From 5cdaefad6adc7e8c33cceac6ea138b072b546489 Mon Sep 17 00:00:00 2001 From: Webster Sheets Date: Wed, 2 Jan 2019 11:59:07 -0500 Subject: [PATCH] Run clang-format over the entire code base. Fix hidden header-inclusion-order dependency errors. Update .clang-format for v7.0.1. --- .clang-format | 2 +- src/Aabb.h | 28 +- src/AmbientSounds.cpp | 165 +- src/AmbientSounds.h | 1 + src/AnimationCurves.h | 13 +- src/Background.cpp | 902 ++++--- src/Background.h | 53 +- src/BaseSphere.cpp | 14 +- src/BaseSphere.h | 18 +- src/Beam.cpp | 84 +- src/Beam.h | 10 +- src/Body.cpp | 87 +- src/Body.h | 40 +- src/ByteRange.h | 19 +- src/CRC32.cpp | 9 +- src/Camera.cpp | 92 +- src/Camera.h | 38 +- src/CameraController.cpp | 63 +- src/CameraController.h | 63 +- src/CargoBody.cpp | 21 +- src/CargoBody.h | 14 +- src/CityOnPlanet.cpp | 157 +- src/CityOnPlanet.h | 19 +- src/CollMesh.h | 28 +- src/Color.cpp | 54 +- src/Color.h | 149 +- src/Cutscene.h | 14 +- src/DateTime.cpp | 101 +- src/DateTime.h | 81 +- src/DeathView.cpp | 8 +- src/DeathView.h | 8 +- src/DeleteEmitter.h | 7 +- src/DynamicBody.cpp | 116 +- src/DynamicBody.h | 24 +- src/Easing.h | 312 ++- src/EnumStrings.cpp | 70 +- src/EnumStrings.h | 8 +- src/FaceParts.cpp | 118 +- src/FaceParts.h | 2 +- src/Factions.cpp | 260 +- src/Factions.h | 127 +- src/FileSourceZip.cpp | 301 +-- src/FileSourceZip.h | 59 +- src/FileSystem.cpp | 115 +- src/FileSystem.h | 95 +- src/FixedGuns.cpp | 73 +- src/FixedGuns.h | 102 +- src/FloatComparison.h | 89 +- src/FontCache.cpp | 8 +- src/FontCache.h | 7 +- src/Frame.cpp | 145 +- src/Frame.h | 40 +- src/GZipFormat.cpp | 141 +- src/GZipFormat.h | 2 +- src/Game.cpp | 256 +- src/Game.h | 70 +- src/GameConfig.cpp | 2 +- src/GameLog.cpp | 7 +- src/GameLog.h | 8 +- src/GasGiant.cpp | 292 +-- src/GasGiant.h | 18 +- src/GasGiantJobs.cpp | 114 +- src/GasGiantJobs.h | 102 +- src/GeoPatch.cpp | 186 +- src/GeoPatch.h | 31 +- src/GeoPatchContext.cpp | 41 +- src/GeoPatchContext.h | 31 +- src/GeoPatchID.cpp | 20 +- src/GeoPatchID.h | 10 +- src/GeoPatchJobs.cpp | 141 +- src/GeoPatchJobs.h | 147 +- src/GeoSphere.cpp | 158 +- src/GeoSphere.h | 38 +- src/HudTrail.cpp | 14 +- src/HudTrail.h | 9 +- src/HyperspaceCloud.cpp | 51 +- src/HyperspaceCloud.h | 5 +- src/IniConfig.cpp | 2 +- src/IniConfig.h | 8 +- src/Input.cpp | 144 +- src/Input.h | 32 +- src/Intro.cpp | 57 +- src/Intro.h | 4 +- src/IterationProxy.h | 14 +- src/JobQueue.cpp | 69 +- src/JobQueue.h | 91 +- src/JsonUtils.cpp | 108 +- src/JsonUtils.h | 56 +- src/KeyBindings.cpp | 1095 ++++----- src/KeyBindings.h | 193 +- src/Lang.cpp | 362 +-- src/Lang.h | 54 +- src/Lua.cpp | 22 +- src/Lua.h | 8 +- src/LuaBody.cpp | 305 +-- src/LuaCargoBody.cpp | 8 +- src/LuaComms.cpp | 4 +- src/LuaConsole.cpp | 286 +-- src/LuaConsole.h | 11 +- src/LuaConstants.h | 2 +- src/LuaDev.cpp | 4 +- src/LuaEngine.cpp | 140 +- src/LuaEngine.h | 2 +- src/LuaEvent.cpp | 95 +- src/LuaEvent.h | 46 +- src/LuaFaction.cpp | 40 +- src/LuaFileSystem.cpp | 37 +- src/LuaFileSystem.h | 2 +- src/LuaFixed.cpp | 12 +- src/LuaFixed.h | 2 +- src/LuaFormat.cpp | 19 +- src/LuaGame.cpp | 179 +- src/LuaHyperspaceCloud.cpp | 33 +- src/LuaInput.cpp | 59 +- src/LuaInput.h | 2 +- src/LuaJson.cpp | 118 +- src/LuaJson.h | 2 +- src/LuaLang.cpp | 9 +- src/LuaManager.cpp | 13 +- src/LuaMatrix.cpp | 26 +- src/LuaMatrix.h | 8 +- src/LuaMissile.cpp | 16 +- src/LuaModelBody.cpp | 9 +- src/LuaMusic.cpp | 8 +- src/LuaNameGen.cpp | 2 +- src/LuaNameGen.h | 3 +- src/LuaObject.cpp | 96 +- src/LuaObject.h | 153 +- src/LuaPiGui.cpp | 919 ++++---- src/LuaPiGui.h | 1 - src/LuaPlanet.cpp | 6 +- src/LuaPlayer.cpp | 112 +- src/LuaPropertiedObject.cpp | 36 +- src/LuaPushPull.h | 113 +- src/LuaRand.cpp | 53 +- src/LuaRef.cpp | 49 +- src/LuaRef.h | 41 +- src/LuaSerializer.cpp | 676 +++--- src/LuaSerializer.h | 2 +- src/LuaServerAgent.cpp | 124 +- src/LuaShip.cpp | 209 +- src/LuaShipDef.cpp | 39 +- src/LuaSpace.cpp | 79 +- src/LuaSpaceStation.cpp | 16 +- src/LuaStar.cpp | 7 +- src/LuaStarSystem.cpp | 94 +- src/LuaSystemBody.cpp | 136 +- src/LuaSystemPath.cpp | 90 +- src/LuaTable.h | 281 ++- src/LuaTimer.cpp | 19 +- src/LuaTimer.h | 2 +- src/LuaUtils.cpp | 224 +- src/LuaUtils.h | 38 +- src/LuaVector.cpp | 8 +- src/LuaVector.h | 12 +- src/MathUtil.cpp | 233 +- src/MathUtil.h | 38 +- src/Missile.cpp | 47 +- src/Missile.h | 15 +- src/ModManager.cpp | 5 +- src/ModelBody.cpp | 94 +- src/ModelBody.h | 28 +- src/ModelCache.cpp | 9 +- src/ModelCache.h | 17 +- src/ModelViewer.cpp | 444 ++-- src/ModelViewer.h | 32 +- src/NavLights.cpp | 89 +- src/NavLights.h | 43 +- src/OS.h | 2 +- src/Object.h | 22 +- src/ObjectViewerView.cpp | 58 +- src/ObjectViewerView.h | 12 +- src/Orbit.cpp | 169 +- src/Orbit.h | 9 +- src/Pi.h | 58 +- src/PiGui.cpp | 321 +-- src/PiGui.h | 65 +- src/Plane.cpp | 9 +- src/Plane.h | 6 +- src/Planet.cpp | 132 +- src/Planet.h | 10 +- src/Player.cpp | 108 +- src/Player.h | 28 +- src/PngWriter.cpp | 8 +- src/Polit.cpp | 94 +- src/Polit.h | 10 +- src/Projectile.cpp | 96 +- src/Projectile.h | 28 +- src/PropertiedObject.h | 3 +- src/PropertyMap.cpp | 4 +- src/PropertyMap.h | 13 +- src/Propulsion.cpp | 151 +- src/Propulsion.h | 192 +- src/Quaternion.h | 175 +- src/Random.h | 47 +- src/RandomColor.cpp | 117 +- src/RandomColor.h | 32 +- src/Range.h | 14 +- src/RefCounted.h | 64 +- src/SDLWrappers.cpp | 2 +- src/SDLWrappers.h | 45 +- src/SectorView.cpp | 418 ++-- src/SectorView.h | 34 +- src/Sensors.cpp | 84 +- src/Sensors.h | 6 +- src/Serializer.cpp | 494 ++-- src/Serializer.h | 21 +- src/ServerAgent.cpp | 15 +- src/ServerAgent.h | 28 +- src/Sfx.cpp | 191 +- src/Sfx.h | 21 +- src/Shields.cpp | 119 +- src/Shields.h | 34 +- src/Ship-AI.cpp | 50 +- src/Ship.cpp | 453 ++-- src/Ship.h | 57 +- src/ShipAICmd.cpp | 647 ++--- src/ShipAICmd.h | 239 +- src/ShipCockpit.cpp | 21 +- src/ShipCockpit.h | 39 +- src/ShipController.cpp | 102 +- src/ShipController.h | 68 +- src/ShipCpanel.cpp | 33 +- src/ShipCpanel.h | 33 +- src/ShipCpanelMultiFuncDisplays.cpp | 268 ++- src/ShipCpanelMultiFuncDisplays.h | 13 +- src/ShipType.cpp | 138 +- src/ShipType.h | 17 +- src/SmartPtr.h | 78 +- src/Sound.cpp | 1176 ++++----- src/Sound.h | 112 +- src/SoundMusic.cpp | 226 +- src/SoundMusic.h | 16 +- src/Space.cpp | 365 ++- src/Space.h | 62 +- src/SpaceStation.cpp | 346 +-- src/SpaceStation.h | 39 +- src/SpaceStationType.cpp | 243 +- src/SpaceStationType.h | 32 +- src/SpeedLines.cpp | 46 +- src/SpeedLines.h | 11 +- src/Sphere.cpp | 7 +- src/Sphere.h | 10 +- src/Star.cpp | 18 +- src/Star.h | 9 +- src/StringF.cpp | 178 +- src/StringF.h | 222 +- src/StringRange.h | 71 +- src/SystemInfoView.cpp | 286 +-- src/SystemInfoView.h | 22 +- src/SystemView.cpp | 407 ++-- src/SystemView.h | 18 +- src/TerrainBody.cpp | 29 +- src/TerrainBody.h | 10 +- src/Tombstone.cpp | 10 +- src/UIView.cpp | 8 +- src/UIView.h | 10 +- src/VideoLink.h | 7 +- src/View.cpp | 25 +- src/collider/BVHTree.cpp | 23 +- src/collider/BVHTree.h | 31 +- src/collider/CollisionContact.h | 14 +- src/collider/CollisionSpace.cpp | 119 +- src/collider/CollisionSpace.h | 32 +- src/collider/Geom.cpp | 42 +- src/collider/Geom.h | 16 +- src/collider/GeomTree.cpp | 139 +- src/collider/GeomTree.h | 8 +- src/collider/Weld.h | 235 +- src/collider/collider.h | 4 +- src/enum_table.h | 10 +- src/fixed.h | 192 +- src/galaxy/CustomSystem.cpp | 210 +- src/galaxy/CustomSystem.h | 88 +- src/galaxy/Economy.cpp | 229 +- src/galaxy/Economy.h | 8 +- src/galaxy/Galaxy.cpp | 59 +- src/galaxy/Galaxy.h | 26 +- src/galaxy/GalaxyCache.cpp | 160 +- src/galaxy/GalaxyCache.h | 86 +- src/galaxy/GalaxyGenerator.cpp | 62 +- src/galaxy/GalaxyGenerator.h | 68 +- src/galaxy/Sector.cpp | 31 +- src/galaxy/Sector.h | 78 +- src/galaxy/SectorGenerator.cpp | 195 +- src/galaxy/SectorGenerator.h | 19 +- src/galaxy/StarSystem.cpp | 1854 ++++++++------- src/galaxy/StarSystem.h | 162 +- src/galaxy/StarSystemGenerator.cpp | 1181 +++++---- src/galaxy/StarSystemGenerator.h | 26 +- src/galaxy/SystemPath.cpp | 44 +- src/galaxy/SystemPath.h | 118 +- src/gameconsts.h | 9 +- src/gameui/BindingCapture.cpp | 184 +- src/gameui/BindingCapture.h | 78 +- src/gameui/Face.cpp | 151 +- src/gameui/Face.h | 54 +- src/gameui/GalaxyMap.cpp | 184 +- src/gameui/GalaxyMap.h | 49 +- src/gameui/GameUI.h | 2 +- src/gameui/LabelOverlay.cpp | 212 +- src/gameui/LabelOverlay.h | 83 +- src/gameui/Lua.cpp | 22 +- src/gameui/Lua.h | 11 +- src/gameui/LuaBindingCapture.cpp | 150 +- src/gameui/LuaFace.cpp | 85 +- src/gameui/LuaGalaxyMap.cpp | 146 +- src/gameui/LuaModelSpinner.cpp | 60 +- src/gameui/ModelSpinner.cpp | 147 +- src/gameui/ModelSpinner.h | 50 +- src/gameui/Panel.cpp | 10 +- src/gameui/Panel.h | 15 +- src/graphics/Drawables.cpp | 1861 +++++++-------- src/graphics/Drawables.h | 374 +-- src/graphics/Frustum.cpp | 254 +- src/graphics/Frustum.h | 58 +- src/graphics/Graphics.cpp | 282 ++- src/graphics/Graphics.h | 15 +- src/graphics/Light.cpp | 32 +- src/graphics/Light.h | 55 +- src/graphics/Material.cpp | 105 +- src/graphics/Material.h | 167 +- src/graphics/RenderState.h | 49 +- src/graphics/RenderTarget.h | 77 +- src/graphics/Renderer.cpp | 81 +- src/graphics/Renderer.h | 377 +-- src/graphics/Stats.cpp | 12 +- src/graphics/Stats.h | 90 +- src/graphics/Texture.h | 197 +- src/graphics/TextureBuilder.cpp | 483 ++-- src/graphics/TextureBuilder.h | 164 +- src/graphics/Types.h | 106 +- src/graphics/VertexArray.cpp | 235 +- src/graphics/VertexArray.h | 88 +- src/graphics/VertexBuffer.cpp | 182 +- src/graphics/VertexBuffer.h | 201 +- src/graphics/dummy/MaterialDummy.h | 10 +- src/graphics/dummy/RenderStateDummy.h | 17 +- src/graphics/dummy/RenderTargetDummy.h | 37 +- src/graphics/dummy/RendererDummy.cpp | 16 +- src/graphics/dummy/RendererDummy.h | 130 +- src/graphics/dummy/TextureDummy.h | 29 +- src/graphics/dummy/VertexBufferDummy.h | 99 +- src/graphics/opengl/BillboardMaterial.cpp | 96 +- src/graphics/opengl/BillboardMaterial.h | 5 +- src/graphics/opengl/FresnelColourMaterial.cpp | 52 +- src/graphics/opengl/FresnelColourMaterial.h | 4 +- src/graphics/opengl/GLDebug.h | 105 +- src/graphics/opengl/GasGiantMaterial.cpp | 289 +-- src/graphics/opengl/GasGiantMaterial.h | 8 +- .../opengl/GenGasGiantColourMaterial.cpp | 247 +- .../opengl/GenGasGiantColourMaterial.h | 4 +- src/graphics/opengl/GeoSphereMaterial.cpp | 438 ++-- src/graphics/opengl/GeoSphereMaterial.h | 9 +- src/graphics/opengl/MaterialGL.cpp | 54 +- src/graphics/opengl/MaterialGL.h | 8 +- src/graphics/opengl/MultiMaterial.cpp | 314 +-- src/graphics/opengl/MultiMaterial.h | 8 +- src/graphics/opengl/Program.cpp | 458 ++-- src/graphics/opengl/Program.h | 10 +- src/graphics/opengl/RenderStateGL.cpp | 121 +- src/graphics/opengl/RenderStateGL.h | 16 +- src/graphics/opengl/RenderTargetGL.cpp | 200 +- src/graphics/opengl/RenderTargetGL.h | 74 +- src/graphics/opengl/RendererGL.cpp | 2100 ++++++++--------- src/graphics/opengl/RendererGL.h | 273 +-- src/graphics/opengl/RingMaterial.cpp | 62 +- src/graphics/opengl/RingMaterial.h | 6 +- src/graphics/opengl/ShieldMaterial.cpp | 132 +- src/graphics/opengl/ShieldMaterial.h | 5 +- src/graphics/opengl/SkyboxMaterial.h | 16 +- src/graphics/opengl/SphereImpostorMaterial.h | 24 +- src/graphics/opengl/StarfieldMaterial.h | 17 +- src/graphics/opengl/TextureGL.cpp | 771 +++--- src/graphics/opengl/TextureGL.h | 16 +- src/graphics/opengl/UIMaterial.cpp | 22 +- src/graphics/opengl/UIMaterial.h | 4 +- src/graphics/opengl/Uniform.cpp | 140 +- src/graphics/opengl/Uniform.h | 18 +- src/graphics/opengl/VertexBufferGL.cpp | 994 ++++---- src/graphics/opengl/VertexBufferGL.h | 119 +- src/graphics/opengl/VtxColorMaterial.cpp | 36 +- src/graphics/opengl/VtxColorMaterial.h | 4 +- src/gui/Gui.cpp | 592 +++-- src/gui/Gui.h | 55 +- src/gui/GuiAdjustment.h | 25 +- src/gui/GuiBox.cpp | 286 +-- src/gui/GuiBox.h | 18 +- src/gui/GuiButton.cpp | 255 +- src/gui/GuiButton.h | 19 +- src/gui/GuiContainer.cpp | 488 ++-- src/gui/GuiContainer.h | 12 +- src/gui/GuiEvents.h | 4 +- src/gui/GuiFixed.cpp | 184 +- src/gui/GuiFixed.h | 8 +- src/gui/GuiISelectable.h | 4 +- src/gui/GuiImage.cpp | 87 +- src/gui/GuiImage.h | 11 +- src/gui/GuiImageButton.cpp | 110 +- src/gui/GuiImageButton.h | 8 +- src/gui/GuiImageRadioButton.cpp | 83 +- src/gui/GuiImageRadioButton.h | 6 +- src/gui/GuiLabel.cpp | 179 +- src/gui/GuiLabel.h | 19 +- src/gui/GuiLabelSet.cpp | 107 +- src/gui/GuiLabelSet.h | 90 +- src/gui/GuiMeterBar.cpp | 94 +- src/gui/GuiMeterBar.h | 9 +- src/gui/GuiMultiStateImageButton.cpp | 212 +- src/gui/GuiMultiStateImageButton.h | 8 +- src/gui/GuiRadioButton.cpp | 85 +- src/gui/GuiRadioButton.h | 8 +- src/gui/GuiRadioGroup.cpp | 39 +- src/gui/GuiRadioGroup.h | 9 +- src/gui/GuiScreen.cpp | 716 +++--- src/gui/GuiScreen.h | 26 +- src/gui/GuiStack.cpp | 150 +- src/gui/GuiStack.h | 8 +- src/gui/GuiTabbed.cpp | 327 ++- src/gui/GuiTabbed.h | 10 +- src/gui/GuiTextEntry.cpp | 424 ++-- src/gui/GuiTextEntry.h | 18 +- src/gui/GuiTextLayout.cpp | 426 ++-- src/gui/GuiTextLayout.h | 63 +- src/gui/GuiTexturedQuad.cpp | 100 +- src/gui/GuiTexturedQuad.h | 46 +- src/gui/GuiToggleButton.cpp | 74 +- src/gui/GuiToggleButton.h | 5 +- src/gui/GuiToolTip.cpp | 162 +- src/gui/GuiToolTip.h | 5 +- src/gui/GuiVScrollBar.cpp | 171 +- src/gui/GuiVScrollBar.h | 14 +- src/gui/GuiVScrollPortal.cpp | 236 +- src/gui/GuiVScrollPortal.h | 6 +- src/gui/GuiWidget.cpp | 336 +-- src/gui/GuiWidget.h | 32 +- src/libs.h | 80 +- src/main.cpp | 273 ++- src/matrix3x3.h | 193 +- src/matrix4x4.h | 484 ++-- src/modelcompiler.cpp | 218 +- src/perlin.cpp | 168 +- src/posix/FileSystemPosix.cpp | 131 +- src/posix/OSPosix.cpp | 181 +- src/savegamedump.cpp | 78 +- src/scenegraph/Animation.cpp | 232 +- src/scenegraph/Animation.h | 46 +- src/scenegraph/AnimationChannel.h | 21 +- src/scenegraph/AnimationKey.h | 49 +- src/scenegraph/BaseLoader.cpp | 12 +- src/scenegraph/BaseLoader.h | 42 +- src/scenegraph/Billboard.cpp | 64 +- src/scenegraph/Billboard.h | 32 +- src/scenegraph/BinaryConverter.cpp | 83 +- src/scenegraph/BinaryConverter.h | 58 +- src/scenegraph/CollisionGeometry.cpp | 171 +- src/scenegraph/CollisionGeometry.h | 68 +- src/scenegraph/CollisionVisitor.cpp | 348 +-- src/scenegraph/CollisionVisitor.h | 59 +- src/scenegraph/ColorMap.cpp | 91 +- src/scenegraph/ColorMap.h | 30 +- src/scenegraph/DumpVisitor.cpp | 180 +- src/scenegraph/DumpVisitor.h | 66 +- src/scenegraph/FindNodeVisitor.cpp | 40 +- src/scenegraph/FindNodeVisitor.h | 36 +- src/scenegraph/Group.cpp | 237 +- src/scenegraph/Group.h | 51 +- src/scenegraph/LOD.cpp | 201 +- src/scenegraph/LOD.h | 34 +- src/scenegraph/Label3D.cpp | 151 +- src/scenegraph/Label3D.h | 36 +- src/scenegraph/Loader.cpp | 1630 +++++++------ src/scenegraph/Loader.h | 78 +- src/scenegraph/LoaderDefinitions.h | 123 +- src/scenegraph/Lua.cpp | 17 +- src/scenegraph/Lua.h | 9 +- src/scenegraph/LuaModel.cpp | 149 +- src/scenegraph/LuaModelSkin.cpp | 176 +- src/scenegraph/MatrixTransform.cpp | 116 +- src/scenegraph/MatrixTransform.h | 42 +- src/scenegraph/Model.cpp | 1223 +++++----- src/scenegraph/Model.h | 265 ++- src/scenegraph/ModelNode.cpp | 62 +- src/scenegraph/ModelNode.h | 30 +- src/scenegraph/ModelSkin.cpp | 264 +-- src/scenegraph/ModelSkin.h | 58 +- src/scenegraph/Node.cpp | 102 +- src/scenegraph/Node.h | 183 +- src/scenegraph/NodeCopyCache.h | 38 +- src/scenegraph/NodeVisitor.cpp | 76 +- src/scenegraph/NodeVisitor.h | 47 +- src/scenegraph/Parser.cpp | 432 ++-- src/scenegraph/Parser.h | 52 +- src/scenegraph/Pattern.cpp | 48 +- src/scenegraph/Pattern.h | 24 +- src/scenegraph/SceneGraph.h | 2 +- src/scenegraph/StaticGeometry.cpp | 656 +++-- src/scenegraph/StaticGeometry.h | 81 +- src/scenegraph/Thruster.cpp | 387 +-- src/scenegraph/Thruster.h | 56 +- src/terrain/Terrain.cpp | 839 +++---- src/terrain/Terrain.h | 47 +- src/terrain/TerrainColorAsteroid.cpp | 16 +- src/terrain/TerrainColorBandedRock.cpp | 6 +- src/terrain/TerrainColorBlack.cpp | 3 +- src/terrain/TerrainColorDeadWithWater.cpp | 12 +- src/terrain/TerrainColorDesert.cpp | 22 +- src/terrain/TerrainColorEarthLike.cpp | 80 +- .../TerrainColorEarthLikeHeightmapped.cpp | 73 +- src/terrain/TerrainColorGGJupiter.cpp | 186 +- src/terrain/TerrainColorGGNeptune.cpp | 30 +- src/terrain/TerrainColorGGNeptune2.cpp | 83 +- src/terrain/TerrainColorGGSaturn.cpp | 32 +- src/terrain/TerrainColorGGSaturn2.cpp | 62 +- src/terrain/TerrainColorGGUranus.cpp | 22 +- src/terrain/TerrainColorIce.cpp | 32 +- src/terrain/TerrainColorMethane.cpp | 12 +- src/terrain/TerrainColorRock.cpp | 113 +- src/terrain/TerrainColorRock2.cpp | 83 +- src/terrain/TerrainColorStarBrownDwarf.cpp | 21 +- src/terrain/TerrainColorStarG.cpp | 33 +- src/terrain/TerrainColorStarK.cpp | 28 +- src/terrain/TerrainColorStarM.cpp | 34 +- src/terrain/TerrainColorStarWhiteDwarf.cpp | 20 +- src/terrain/TerrainColorTFGood.cpp | 110 +- src/terrain/TerrainColorTFPoor.cpp | 81 +- src/terrain/TerrainColorVolcanic.cpp | 24 +- src/terrain/TerrainColorWhite.cpp | 3 +- src/terrain/TerrainFeature.cpp | 818 +++---- src/terrain/TerrainFeature.h | 2 +- src/terrain/TerrainHeightAsteroid.cpp | 13 +- src/terrain/TerrainHeightAsteroid2.cpp | 19 +- src/terrain/TerrainHeightAsteroid3.cpp | 13 +- src/terrain/TerrainHeightAsteroid4.cpp | 23 +- src/terrain/TerrainHeightBarrenRock.cpp | 11 +- src/terrain/TerrainHeightBarrenRock2.cpp | 9 +- src/terrain/TerrainHeightBarrenRock3.cpp | 9 +- src/terrain/TerrainHeightEllipsoid.cpp | 10 +- src/terrain/TerrainHeightFlat.cpp | 3 +- src/terrain/TerrainHeightHillsCraters.cpp | 25 +- src/terrain/TerrainHeightHillsCraters2.cpp | 33 +- src/terrain/TerrainHeightHillsDunes.cpp | 38 +- src/terrain/TerrainHeightHillsNormal.cpp | 42 +- src/terrain/TerrainHeightHillsRidged.cpp | 33 +- src/terrain/TerrainHeightHillsRivers.cpp | 41 +- src/terrain/TerrainHeightMapped.cpp | 117 +- src/terrain/TerrainHeightMapped2.cpp | 62 +- src/terrain/TerrainHeightMountainsCraters.cpp | 31 +- .../TerrainHeightMountainsCraters2.cpp | 45 +- src/terrain/TerrainHeightMountainsNormal.cpp | 144 +- src/terrain/TerrainHeightMountainsRidged.cpp | 69 +- src/terrain/TerrainHeightMountainsRivers.cpp | 136 +- .../TerrainHeightMountainsRiversVolcano.cpp | 237 +- src/terrain/TerrainHeightMountainsVolcano.cpp | 97 +- src/terrain/TerrainHeightRuggedDesert.cpp | 59 +- src/terrain/TerrainHeightRuggedLava.cpp | 85 +- src/terrain/TerrainHeightWaterSolid.cpp | 60 +- .../TerrainHeightWaterSolidCanyons.cpp | 62 +- src/terrain/TerrainNoise.h | 101 +- src/test_DateTime.cpp | 57 +- src/test_FileSystem.cpp | 18 +- src/test_Frame.cpp | 7 +- src/test_Random.cpp | 31 +- src/test_StringF.cpp | 18 +- src/text/DistanceFieldFont.cpp | 302 +-- src/text/DistanceFieldFont.h | 54 +- src/text/FontConfig.cpp | 90 +- src/text/FontConfig.h | 88 +- src/text/TextSupport.cpp | 122 +- src/text/TextSupport.h | 103 +- src/text/TextureFont.cpp | 1166 +++++---- src/text/TextureFont.h | 190 +- src/textstress.cpp | 8 +- src/ui/Align.cpp | 46 +- src/ui/Align.h | 48 +- src/ui/Animation.cpp | 335 ++- src/ui/Animation.h | 160 +- src/ui/Background.cpp | 46 +- src/ui/Background.h | 21 +- src/ui/Box.cpp | 413 ++-- src/ui/Box.h | 103 +- src/ui/Button.cpp | 112 +- src/ui/Button.h | 21 +- src/ui/CellSpec.cpp | 27 +- src/ui/CellSpec.h | 168 +- src/ui/CheckBox.cpp | 92 +- src/ui/CheckBox.h | 36 +- src/ui/ColorBackground.cpp | 24 +- src/ui/ColorBackground.h | 24 +- src/ui/Container.cpp | 312 +-- src/ui/Container.h | 72 +- src/ui/Context.cpp | 457 ++-- src/ui/Context.h | 263 ++- src/ui/DropDown.cpp | 260 +- src/ui/DropDown.h | 70 +- src/ui/Event.cpp | 418 ++-- src/ui/Event.h | 378 +-- src/ui/EventDispatcher.cpp | 429 ++-- src/ui/EventDispatcher.h | 63 +- src/ui/Expand.cpp | 16 +- src/ui/Expand.h | 34 +- src/ui/Gauge.cpp | 175 +- src/ui/Gauge.h | 60 +- src/ui/Gradient.cpp | 69 +- src/ui/Gradient.h | 43 +- src/ui/Grid.cpp | 277 +-- src/ui/Grid.h | 50 +- src/ui/Icon.cpp | 145 +- src/ui/Icon.h | 44 +- src/ui/Image.cpp | 217 +- src/ui/Image.h | 80 +- src/ui/Label.cpp | 142 +- src/ui/Label.h | 54 +- src/ui/Layer.cpp | 42 +- src/ui/Layer.h | 29 +- src/ui/List.cpp | 208 +- src/ui/List.h | 56 +- src/ui/Lua.cpp | 134 +- src/ui/Lua.h | 18 +- src/ui/LuaAlign.cpp | 15 +- src/ui/LuaAnimation.cpp | 53 +- src/ui/LuaBackground.cpp | 15 +- src/ui/LuaBox.cpp | 136 +- src/ui/LuaButton.cpp | 15 +- src/ui/LuaCheckBox.cpp | 62 +- src/ui/LuaColorBackground.cpp | 15 +- src/ui/LuaContainer.cpp | 15 +- src/ui/LuaContext.cpp | 798 ++++--- src/ui/LuaDropDown.cpp | 124 +- src/ui/LuaExpand.cpp | 15 +- src/ui/LuaGauge.cpp | 98 +- src/ui/LuaGradient.cpp | 15 +- src/ui/LuaGrid.cpp | 207 +- src/ui/LuaIcon.cpp | 31 +- src/ui/LuaImage.cpp | 31 +- src/ui/LuaLabel.cpp | 44 +- src/ui/LuaLayer.cpp | 56 +- src/ui/LuaList.cpp | 124 +- src/ui/LuaMargin.cpp | 17 +- src/ui/LuaMultiLineText.cpp | 45 +- src/ui/LuaNumberLabel.cpp | 31 +- src/ui/LuaOverlayStack.cpp | 49 +- src/ui/LuaScroller.cpp | 59 +- src/ui/LuaSignal.h | 320 +-- src/ui/LuaSingle.cpp | 58 +- src/ui/LuaSlider.cpp | 111 +- src/ui/LuaSmallButton.cpp | 17 +- src/ui/LuaTable.cpp | 306 +-- src/ui/LuaTextEntry.cpp | 79 +- src/ui/LuaWidget.cpp | 299 +-- src/ui/Margin.cpp | 87 +- src/ui/Margin.h | 44 +- src/ui/MousePointer.h | 24 +- src/ui/MultiLineText.cpp | 95 +- src/ui/MultiLineText.h | 38 +- src/ui/NumberLabel.cpp | 66 +- src/ui/NumberLabel.h | 56 +- src/ui/OverlayStack.cpp | 48 +- src/ui/OverlayStack.h | 24 +- src/ui/Point.h | 82 +- src/ui/Scroller.cpp | 193 +- src/ui/Scroller.h | 44 +- src/ui/Single.cpp | 88 +- src/ui/Single.h | 30 +- src/ui/Skin.cpp | 392 +-- src/ui/Skin.h | 579 ++--- src/ui/Slider.cpp | 316 ++- src/ui/Slider.h | 123 +- src/ui/SmallButton.cpp | 44 +- src/ui/SmallButton.h | 21 +- src/ui/Table.cpp | 724 +++--- src/ui/Table.h | 220 +- src/ui/TextEntry.cpp | 254 +- src/ui/TextEntry.h | 46 +- src/ui/TextLayout.cpp | 233 +- src/ui/TextLayout.h | 58 +- src/ui/Widget.cpp | 685 +++--- src/ui/Widget.h | 697 +++--- src/ui/WidgetSet.h | 133 +- src/uitest.cpp | 33 +- src/utils.cpp | 232 +- src/utils.h | 103 +- src/vector2.h | 89 +- src/vector3.h | 286 ++- src/win32/FileSystemWin32.cpp | 31 +- src/win32/OSWin32.cpp | 442 ++-- src/win32/TextUtils.cpp | 10 +- src/win32/Win32Setup.h | 18 +- src/win32/WinMath.cpp | 356 ++- src/win32/WinMath.h | 5 +- src/win32/msvc_bug.cpp | 28 +- src/win32/pch.h | 52 +- src/win32/perlintest.cpp | 23 +- 693 files changed, 44448 insertions(+), 41358 deletions(-) diff --git a/.clang-format b/.clang-format index c0b4b5506..4669259ed 100644 --- a/.clang-format +++ b/.clang-format @@ -91,7 +91,7 @@ NamespaceIndentation: All #PenaltyBreakString: 1000 #PenaltyExcessCharacter: 1000000 #PenaltyReturnTypeOnItsOwnLine: 60 -#PointerAlignment: Right +PointerAlignment: Right #RawStringFormats: # - Delimiter: pb # Language: TextProto diff --git a/src/Aabb.h b/src/Aabb.h index e13b4d068..7d5a89469 100644 --- a/src/Aabb.h +++ b/src/Aabb.h @@ -9,21 +9,23 @@ struct Aabb { vector3d min, max; double radius; - Aabb() - : min(DBL_MAX, DBL_MAX, DBL_MAX) - , max(-DBL_MAX, -DBL_MAX, -DBL_MAX) - , radius(0.1) - { } - void Update(const vector3d &p) { + Aabb() : + min(DBL_MAX, DBL_MAX, DBL_MAX), + max(-DBL_MAX, -DBL_MAX, -DBL_MAX), + radius(0.1) + {} + void Update(const vector3d &p) + { if (max.x < p.x) max.x = p.x; if (max.y < p.y) max.y = p.y; if (max.z < p.z) max.z = p.z; if (min.x > p.x) min.x = p.x; if (min.y > p.y) min.y = p.y; if (min.z > p.z) min.z = p.z; - if (p.Dot(p) > radius*radius) radius = p.Length(); + if (p.Dot(p) > radius * radius) radius = p.Length(); } - void Update(float x, float y, float z) { + void Update(float x, float y, float z) + { if (max.x < x) max.x = x; if (max.y < y) max.y = y; if (max.z < z) max.z = z; @@ -32,12 +34,14 @@ struct Aabb { if (min.z > z) min.z = z; } template - bool IsIn (const vector3 &p) const { + bool IsIn(const vector3 &p) const + { return ((p.x >= min.x) && (p.x <= max.x) && - (p.y >= min.y) && (p.y <= max.y) && - (p.z >= min.z) && (p.z <= max.z)); + (p.y >= min.y) && (p.y <= max.y) && + (p.z >= min.z) && (p.z <= max.z)); } - bool Intersects(const Aabb &o) const { + bool Intersects(const Aabb &o) const + { return (min.x < o.max.x) && (max.x > o.min.x) && (min.y < o.max.y) && (max.y > o.min.y) && (min.z < o.max.z) && (max.z > o.min.z); diff --git a/src/AmbientSounds.cpp b/src/AmbientSounds.cpp index eb5966d53..77180bf12 100644 --- a/src/AmbientSounds.cpp +++ b/src/AmbientSounds.cpp @@ -1,26 +1,26 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" -#include "WorldView.h" -#include "Player.h" #include "AmbientSounds.h" #include "Frame.h" +#include "Game.h" +#include "Pi.h" #include "Planet.h" +#include "Player.h" #include "Sound.h" #include "SpaceStation.h" -#include "Game.h" +#include "WorldView.h" +#include "libs.h" enum EAtmosphereNoiseChannels { - eAtmoNoise1=0, + eAtmoNoise1 = 0, eAtmoNoise2, eAtmoNoise3, eAtmoNoise4, eMaxNumAtmosphereSounds }; -static const char* s_airflowTable[eMaxNumAtmosphereSounds] = { +static const char *s_airflowTable[eMaxNumAtmosphereSounds] = { "airflow01", "airflow02", "airflow03", @@ -29,10 +29,10 @@ static const char* s_airflowTable[eMaxNumAtmosphereSounds] = { // start, inverse range static const float s_rangeTable[eMaxNumAtmosphereSounds][2] = { - {0.0f, 1.0f / (1.0f - 0.0f)}, // 1 - {1.0f, 1.0f / (3.0f - 1.0f)}, // 2 - {2.0f, 1.0f / (7.0f - 3.0f)}, // 4 - {4.0f, 1.0f / (15.0f - 7.0f)} // 8 + { 0.0f, 1.0f / (1.0f - 0.0f) }, // 1 + { 1.0f, 1.0f / (3.0f - 1.0f) }, // 2 + { 2.0f, 1.0f / (7.0f - 3.0f) }, // 4 + { 4.0f, 1.0f / (15.0f - 7.0f) } // 8 }; static const Uint32 NUM_SURFACE_LIFE_SOUNDS = 12; @@ -79,22 +79,22 @@ void AmbientSounds::Update() if (Pi::player->GetFlightState() == Ship::DOCKED) { if (s_starNoise.IsPlaying()) { - const float target[2] = {0.0f,0.0f}; - const float dv_dt[2] = {1.0f,1.0f}; + const float target[2] = { 0.0f, 0.0f }; + const float dv_dt[2] = { 1.0f, 1.0f }; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } - for(int i=0; iGetDockedWith()->GetSystemBody()->GetSeed() % NUM_STATION_SOUNDS], - 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); + 0.3f * v_env, 0.3f * v_env, Sound::OP_REPEAT); } } else if (Pi::player->GetFlightState() == Ship::LANDED) { /* Planet surface noise on rough-landing */ if (s_starNoise.IsPlaying()) { - const float target[2] = {0.0f,0.0f}; - const float dv_dt[2] = {1.0f,1.0f}; + const float target[2] = { 0.0f, 0.0f }; + const float dv_dt[2] = { 1.0f, 1.0f }; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } - for(int i=0; iGetLifeAsFixed() > fixed(1,5)) { + if (sbody->GetLifeAsFixed() > fixed(1, 5)) { sample = s_surfaceLifeSounds[sbody->GetSeed() % NUM_SURFACE_LIFE_SOUNDS]; - } - else if (sbody->GetVolatileGasAsFixed() > fixed(1,2)) { + } else if (sbody->GetVolatileGasAsFixed() > fixed(1, 2)) { sample = s_surfaceSounds[sbody->GetSeed() % NUM_SURFACE_DEAD_SOUNDS]; - } - else if (sbody->GetVolatileGasAsFixed() > fixed(1,10)) { + } else if (sbody->GetVolatileGasAsFixed() > fixed(1, 10)) { sample = "Wind"; } if (sample) { - s_planetSurfaceNoise.Play(sample, 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); + s_planetSurfaceNoise.Play(sample, 0.3f * v_env, 0.3f * v_env, Sound::OP_REPEAT); } } - } else if (s_planetSurfaceNoise.IsPlaying()) { - // s_planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing - if (Pi::player->GetFrame()->IsRotFrame()) { - const Body *astro = Pi::player->GetFrame()->GetBody(); - if (astro->IsType(Object::PLANET)) { - const double dist = Pi::player->GetPosition().Length(); - double pressure, density; - static_cast(astro)->GetAtmosphericState(dist, &pressure, &density); - if (pressure < 0.001) { - // Stop playing surface noise once out of the atmosphere - s_planetSurfaceNoise.Stop(); - } - } + } else if (s_planetSurfaceNoise.IsPlaying()) { + // s_planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing + if (Pi::player->GetFrame()->IsRotFrame()) { + const Body *astro = Pi::player->GetFrame()->GetBody(); + if (astro->IsType(Object::PLANET)) { + const double dist = Pi::player->GetPosition().Length(); + double pressure, density; + static_cast(astro)->GetAtmosphericState(dist, &pressure, &density); + if (pressure < 0.001) { + // Stop playing surface noise once out of the atmosphere + s_planetSurfaceNoise.Stop(); + } + } } else if (Pi::game->IsHyperspace()) { s_planetSurfaceNoise.Stop(); } - } else { + } else { if (s_stationNoise.IsPlaying()) { - const float target[2] = {0.0f,0.0f}; - const float dv_dt[2] = {1.0f,1.0f}; + const float target[2] = { 0.0f, 0.0f }; + const float dv_dt[2] = { 1.0f, 1.0f }; s_stationNoise.VolumeAnimate(target, dv_dt); s_stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } @@ -176,8 +174,8 @@ void AmbientSounds::Update() if (astroNoiseSeed != s->GetSeed()) { // change sound! astroNoiseSeed = s->GetSeed(); - const float target[2] = {0.0f,0.0f}; - const float dv_dt[2] = {0.1f,0.1f}; + const float target[2] = { 0.0f, 0.0f }; + const float dv_dt[2] = { 0.1f, 0.1f }; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); // XXX the way Sound::Event works isn't totally obvious. @@ -194,32 +192,31 @@ void AmbientSounds::Update() const char *sample = 0; for (; sbody && !sample; sbody = f->GetSystemBody()) { switch (sbody->GetType()) { - case SystemBody::TYPE_BROWN_DWARF: sample = "Brown_Dwarf_Substellar_Object"; break; - case SystemBody::TYPE_STAR_M: sample = "M_Red_Star"; break; - case SystemBody::TYPE_STAR_K: sample = "K_Star"; break; - case SystemBody::TYPE_WHITE_DWARF: sample = "White_Dwarf_Star"; break; - case SystemBody::TYPE_STAR_G: sample = "G_Star"; break; - case SystemBody::TYPE_STAR_F: sample = "F_Star"; break; - case SystemBody::TYPE_STAR_A: sample = "A_Star"; break; - case SystemBody::TYPE_STAR_B: sample = "B_Hot_Blue_STAR"; break; - case SystemBody::TYPE_STAR_O: sample = "Blue_Super_Giant"; break; - case SystemBody::TYPE_PLANET_GAS_GIANT: { - if (sbody->GetMassAsFixed() > fixed(400,1)) { - sample = "Very_Large_Gas_Giant"; - } else if (sbody->GetMassAsFixed() > fixed(80,1)) { - sample = "Large_Gas_Giant"; - } else if (sbody->GetMassAsFixed() > fixed(20,1)) { - sample = "Medium_Gas_Giant"; - } else { - sample = "Small_Gas_Giant"; - } - } - break; - default: sample = 0; break; + case SystemBody::TYPE_BROWN_DWARF: sample = "Brown_Dwarf_Substellar_Object"; break; + case SystemBody::TYPE_STAR_M: sample = "M_Red_Star"; break; + case SystemBody::TYPE_STAR_K: sample = "K_Star"; break; + case SystemBody::TYPE_WHITE_DWARF: sample = "White_Dwarf_Star"; break; + case SystemBody::TYPE_STAR_G: sample = "G_Star"; break; + case SystemBody::TYPE_STAR_F: sample = "F_Star"; break; + case SystemBody::TYPE_STAR_A: sample = "A_Star"; break; + case SystemBody::TYPE_STAR_B: sample = "B_Hot_Blue_STAR"; break; + case SystemBody::TYPE_STAR_O: sample = "Blue_Super_Giant"; break; + case SystemBody::TYPE_PLANET_GAS_GIANT: { + if (sbody->GetMassAsFixed() > fixed(400, 1)) { + sample = "Very_Large_Gas_Giant"; + } else if (sbody->GetMassAsFixed() > fixed(80, 1)) { + sample = "Large_Gas_Giant"; + } else if (sbody->GetMassAsFixed() > fixed(20, 1)) { + sample = "Medium_Gas_Giant"; + } else { + sample = "Small_Gas_Giant"; + } + } break; + default: sample = 0; break; } if (sample) { s_starNoise.Play(sample, 0.0f, 0.0f, Sound::OP_REPEAT); - s_starNoise.VolumeAnimate(.3f*v_env, .3f*v_env, .05f, .05f); + s_starNoise.VolumeAnimate(.3f * v_env, .3f * v_env, .05f, .05f); } else { // go up orbital hierarchy tree to see if we can find a sound f = f->GetParent(); @@ -232,31 +229,31 @@ void AmbientSounds::Update() if (astro && Pi::player->GetFrame()->IsRotFrame() && (astro->IsType(Object::PLANET))) { double dist = Pi::player->GetPosition().Length(); double pressure, density; - static_cast(astro)->GetAtmosphericState(dist, &pressure, &density); + static_cast(astro)->GetAtmosphericState(dist, &pressure, &density); // maximum volume at around 2km/sec at earth density, pressure const float pressureVolume = float(density * Pi::player->GetVelocity().Length() * 0.0005); //volume = Clamp(volume, 0.0f, 1.0f) * v_env; float volumes[eMaxNumAtmosphereSounds]; - for(int i=0; i - inline void Approach(T & cur, const T target, float frameTime, const T exponentialFactor=10, T linearFactor=1) { + template + inline void Approach(T &cur, const T target, float frameTime, const T exponentialFactor = 10, T linearFactor = 1) + { //static_assert(static_cast(-1) <0); // Assert type is signed - if (frameTime>1) frameTime = 1; // Clamp in case game hangs for a second + if (frameTime > 1) frameTime = 1; // Clamp in case game hangs for a second assert(exponentialFactor >= 0 && linearFactor >= 0); if (is_equal_exact(target, cur)) return; const T delta(target - cur); if (delta < 0) linearFactor = -linearFactor; - cur += (delta*exponentialFactor + linearFactor) * frameTime; + cur += (delta * exponentialFactor + linearFactor) * frameTime; // clamp to target (independent of the direction of motion) const T newDelta(target - cur); - if (newDelta*delta < 0) cur = target; + if (newDelta * delta < 0) cur = target; } -} +} // namespace AnimationCurves #endif diff --git a/src/Background.cpp b/src/Background.cpp index c3f41010a..0f7a7ee54 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -2,29 +2,28 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Background.h" -#include "Frame.h" #include "FileSystem.h" +#include "Frame.h" #include "Game.h" -#include "perlin.h" #include "Pi.h" #include "Player.h" #include "Space.h" +#include "StringF.h" #include "galaxy/StarSystem.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" -#include "graphics/VertexArray.h" #include "graphics/TextureBuilder.h" -#include "StringF.h" +#include "graphics/VertexArray.h" +#include "perlin.h" #include -#include #include +#include using namespace Graphics; -namespace -{ +namespace { static const Uint32 BG_STAR_MAX = 500000; static const Uint32 BG_STAR_MIN = 50000; static RefCountedPtr s_defaultCubeMap; @@ -39,487 +38,478 @@ namespace const char *itemMask = "ub"; Uint32 num_matching = 0; - for (std::vector::const_iterator it = fileList.begin(), itEnd = fileList.end(); it!=itEnd; ++it) { + for (std::vector::const_iterator it = fileList.begin(), itEnd = fileList.end(); it != itEnd; ++it) { if (starts_with((*it).GetName(), itemMask)) { ++num_matching; } } return num_matching; } -} +} // namespace -namespace Background -{ +namespace Background { #pragma pack(push, 4) -struct MilkyWayVert { - vector3f pos; - Color4ub col; -}; + struct MilkyWayVert { + vector3f pos; + Color4ub col; + }; -struct StarVert { - vector3f pos; - Color4ub col; -}; + struct StarVert { + vector3f pos; + Color4ub col; + }; -struct SkyboxVert { - vector3f pos; - vector2f uv; -}; + struct SkyboxVert { + vector3f pos; + vector2f uv; + }; #pragma pack(pop) -void BackgroundElement::SetIntensity(float intensity) -{ - m_material->emissive = Color(intensity * 255, intensity * 255, intensity*255); -} - -UniverseBox::UniverseBox(Graphics::Renderer *renderer) -{ - m_renderer = renderer; - Init(); -} - -UniverseBox::~UniverseBox() -{ -} - -void UniverseBox::Init() -{ - // Load default cubemap - if(!s_defaultCubeMap.Valid()) { - TextureBuilder texture_builder = TextureBuilder::Cube("textures/skybox/default.dds"); - s_defaultCubeMap.Reset( texture_builder.GetOrCreateTexture(m_renderer,std::string("cube")) ); - } - - // Create skybox geometry - std::unique_ptr box(new VertexArray(ATTRIB_POSITION | ATTRIB_UV0, 36)); - const float vp = 1000.0f; - // Top +Y - box->Add(vector3f(-vp, vp, vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, vp, -vp), vector2f(1.0f, 1.0f)); - // Bottom -Y - box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, -vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, -vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, -vp, vp), vector2f(1.0f, 1.0f)); - // Front -Z - box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, -vp, -vp), vector2f(1.0f, 1.0f)); - // Back +Z - box->Add(vector3f( vp, vp, vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f( vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f(-vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f(-vp, -vp, vp), vector2f(1.0f, 1.0f)); - // Right +X - box->Add(vector3f( vp, vp, -vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f( vp, -vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, vp, vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f( vp, -vp, -vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f( vp, -vp, vp), vector2f(1.0f, 1.0f)); - // Left -X - box->Add(vector3f(-vp, vp, vp), vector2f(0.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f(-vp, vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, vp, -vp), vector2f(1.0f, 0.0f)); - box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); - box->Add(vector3f(-vp, -vp, -vp), vector2f(1.0f, 1.0f)); - - Graphics::MaterialDescriptor desc; - desc.effect = EFFECT_SKYBOX; - m_material.Reset(m_renderer->CreateMaterial(desc)); - m_material->texture0 = nullptr; - - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = box->GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - m_vertexBuffer.reset(m_renderer->CreateVertexBuffer(vbd)); - - SkyboxVert* vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); - assert(m_vertexBuffer->GetDesc().stride == sizeof(SkyboxVert)); - for (Uint32 i = 0; i < box->GetNumVerts(); i++) { - vtxPtr[i].pos = box->position[i]; - vtxPtr[i].uv = box->uv0[i]; - } - m_vertexBuffer->Unmap(); - - SetIntensity(1.0f); - - m_numCubemaps = GetNumSkyboxes(); -} - -void UniverseBox::Draw(Graphics::RenderState *rs) -{ - if(m_material->texture0) - m_renderer->DrawBuffer(m_vertexBuffer.get(), rs, m_material.Get()); -} - -void UniverseBox::LoadCubeMap(Random &rand) -{ - if(m_numCubemaps>0) { - const int new_ubox_index = rand.Int32(1, m_numCubemaps); - if(new_ubox_index > 0) { - // Load new one - const std::string os = stringf("textures/skybox/ub%0{d}.dds", (new_ubox_index - 1)); - TextureBuilder texture_builder = TextureBuilder::Cube(os.c_str()); - m_cubemap.Reset( texture_builder.GetOrCreateTexture(m_renderer, std::string("cube")) ); - m_material->texture0 = m_cubemap.Get(); - } - } else { - // use default cubemap - m_cubemap.Reset(); - m_material->texture0 = s_defaultCubeMap.Get(); - } -} - -Starfield::Starfield(Graphics::Renderer *renderer, Random &rand) -{ - m_renderer = renderer; - Init(); - Fill(rand); -} - -void Starfield::Init() -{ - Graphics::MaterialDescriptor desc; - desc.effect = Graphics::EFFECT_STARFIELD; - desc.textures = 1; - desc.vertexColors = true; - m_material.Reset(m_renderer->CreateMaterial(desc)); - m_material->emissive = Color::WHITE; - m_material->texture0 = Graphics::TextureBuilder::Billboard("textures/star_point.png").GetOrCreateTexture(m_renderer, "billboard"); - - Graphics::MaterialDescriptor descStreaks; - descStreaks.effect = Graphics::EFFECT_VTXCOLOR; - descStreaks.vertexColors = true; - m_materialStreaks.Reset(m_renderer->CreateMaterial(descStreaks)); - m_materialStreaks->emissive = Color::WHITE; - - IniConfig cfg; - cfg.Read(FileSystem::gameDataFiles, "configs/Starfield.ini"); - // NB: limit the ranges of all values loaded from the file - m_rMin = Clamp(cfg.Float("rMin", 0.2), 0.2f, 1.0f); - m_rMax = Clamp(cfg.Float("rMax", 0.9), 0.2f, 1.0f); - m_gMin = Clamp(cfg.Float("gMin", 0.2), 0.2f, 1.0f); - m_gMax = Clamp(cfg.Float("gMax", 0.9), 0.2f, 1.0f); - m_bMin = Clamp(cfg.Float("bMin", 0.2), 0.2f, 1.0f); - m_bMax = Clamp(cfg.Float("bMax", 0.9), 0.2f, 1.0f); -} - -void Starfield::Fill(Random &rand) -{ - const Uint32 NUM_BG_STARS = Clamp(Uint32(Pi::GetAmountBackgroundStars() * BG_STAR_MAX), BG_STAR_MIN, BG_STAR_MAX); - m_hyperVtx.reset(new vector3f[BG_STAR_MAX * 3]); - m_hyperCol.reset(new Color[BG_STAR_MAX * 3]); - - // setup the animated stars buffer (streaks in Hyperspace) + void BackgroundElement::SetIntensity(float intensity) { + m_material->emissive = Color(intensity * 255, intensity * 255, intensity * 255); + } + + UniverseBox::UniverseBox(Graphics::Renderer *renderer) + { + m_renderer = renderer; + Init(); + } + + UniverseBox::~UniverseBox() + { + } + + void UniverseBox::Init() + { + // Load default cubemap + if (!s_defaultCubeMap.Valid()) { + TextureBuilder texture_builder = TextureBuilder::Cube("textures/skybox/default.dds"); + s_defaultCubeMap.Reset(texture_builder.GetOrCreateTexture(m_renderer, std::string("cube"))); + } + + // Create skybox geometry + std::unique_ptr box(new VertexArray(ATTRIB_POSITION | ATTRIB_UV0, 36)); + const float vp = 1000.0f; + // Top +Y + box->Add(vector3f(-vp, vp, vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, vp, -vp), vector2f(1.0f, 1.0f)); + // Bottom -Y + box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, -vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, -vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, -vp, vp), vector2f(1.0f, 1.0f)); + // Front -Z + box->Add(vector3f(-vp, vp, -vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, -vp, -vp), vector2f(1.0f, 1.0f)); + // Back +Z + box->Add(vector3f(vp, vp, vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(-vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(-vp, -vp, vp), vector2f(1.0f, 1.0f)); + // Right +X + box->Add(vector3f(vp, vp, -vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(vp, -vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, vp, vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(vp, -vp, -vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(vp, -vp, vp), vector2f(1.0f, 1.0f)); + // Left -X + box->Add(vector3f(-vp, vp, vp), vector2f(0.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(-vp, vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, vp, -vp), vector2f(1.0f, 0.0f)); + box->Add(vector3f(-vp, -vp, vp), vector2f(0.0f, 1.0f)); + box->Add(vector3f(-vp, -vp, -vp), vector2f(1.0f, 1.0f)); + + Graphics::MaterialDescriptor desc; + desc.effect = EFFECT_SKYBOX; + m_material.Reset(m_renderer->CreateMaterial(desc)); + m_material->texture0 = nullptr; + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = box->GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + m_vertexBuffer.reset(m_renderer->CreateVertexBuffer(vbd)); + + SkyboxVert *vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + assert(m_vertexBuffer->GetDesc().stride == sizeof(SkyboxVert)); + for (Uint32 i = 0; i < box->GetNumVerts(); i++) { + vtxPtr[i].pos = box->position[i]; + vtxPtr[i].uv = box->uv0[i]; + } + m_vertexBuffer->Unmap(); + + SetIntensity(1.0f); + + m_numCubemaps = GetNumSkyboxes(); + } + + void UniverseBox::Draw(Graphics::RenderState *rs) + { + if (m_material->texture0) + m_renderer->DrawBuffer(m_vertexBuffer.get(), rs, m_material.Get()); + } + + void UniverseBox::LoadCubeMap(Random &rand) + { + if (m_numCubemaps > 0) { + const int new_ubox_index = rand.Int32(1, m_numCubemaps); + if (new_ubox_index > 0) { + // Load new one + const std::string os = stringf("textures/skybox/ub%0{d}.dds", (new_ubox_index - 1)); + TextureBuilder texture_builder = TextureBuilder::Cube(os.c_str()); + m_cubemap.Reset(texture_builder.GetOrCreateTexture(m_renderer, std::string("cube"))); + m_material->texture0 = m_cubemap.Get(); + } + } else { + // use default cubemap + m_cubemap.Reset(); + m_material->texture0 = s_defaultCubeMap.Get(); + } + } + + Starfield::Starfield(Graphics::Renderer *renderer, Random &rand) + { + m_renderer = renderer; + Init(); + Fill(rand); + } + + void Starfield::Init() + { + Graphics::MaterialDescriptor desc; + desc.effect = Graphics::EFFECT_STARFIELD; + desc.textures = 1; + desc.vertexColors = true; + m_material.Reset(m_renderer->CreateMaterial(desc)); + m_material->emissive = Color::WHITE; + m_material->texture0 = Graphics::TextureBuilder::Billboard("textures/star_point.png").GetOrCreateTexture(m_renderer, "billboard"); + + Graphics::MaterialDescriptor descStreaks; + descStreaks.effect = Graphics::EFFECT_VTXCOLOR; + descStreaks.vertexColors = true; + m_materialStreaks.Reset(m_renderer->CreateMaterial(descStreaks)); + m_materialStreaks->emissive = Color::WHITE; + + IniConfig cfg; + cfg.Read(FileSystem::gameDataFiles, "configs/Starfield.ini"); + // NB: limit the ranges of all values loaded from the file + m_rMin = Clamp(cfg.Float("rMin", 0.2), 0.2f, 1.0f); + m_rMax = Clamp(cfg.Float("rMax", 0.9), 0.2f, 1.0f); + m_gMin = Clamp(cfg.Float("gMin", 0.2), 0.2f, 1.0f); + m_gMax = Clamp(cfg.Float("gMax", 0.9), 0.2f, 1.0f); + m_bMin = Clamp(cfg.Float("bMin", 0.2), 0.2f, 1.0f); + m_bMax = Clamp(cfg.Float("bMax", 0.9), 0.2f, 1.0f); + } + + void Starfield::Fill(Random &rand) + { + const Uint32 NUM_BG_STARS = Clamp(Uint32(Pi::GetAmountBackgroundStars() * BG_STAR_MAX), BG_STAR_MIN, BG_STAR_MAX); + m_hyperVtx.reset(new vector3f[BG_STAR_MAX * 3]); + m_hyperCol.reset(new Color[BG_STAR_MAX * 3]); + + // setup the animated stars buffer (streaks in Hyperspace) + { + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; + vbd.numVertices = NUM_BG_STARS * 2; + m_animBuffer.reset(m_renderer->CreateVertexBuffer(vbd)); + } + + m_pointSprites.reset(new Graphics::Drawables::PointSprites); + + assert(sizeof(StarVert) == 16); + std::unique_ptr stars(new vector3f[NUM_BG_STARS]); + std::unique_ptr colors(new Color[NUM_BG_STARS]); + std::unique_ptr sizes(new float[NUM_BG_STARS]); + //fill the array + Uint32 num = 0; + if (Pi::game != nullptr && Pi::game->GetSpace() != nullptr && Pi::game->GetSpace()->GetStarSystem() != nullptr) { + const SystemPath current = Pi::game->GetSpace()->GetStarSystem()->GetPath(); + + const double size = 1.0; + const Uint8 colScale = size * 255; + const Sint32 visibleRadius = 100; // lyrs + const Sint32 visibleRadiusSqr = (visibleRadius * visibleRadius); + const Sint32 sectorMin = -(visibleRadius / Sector::SIZE); // lyrs_radius / sector_size_in_lyrs + const Sint32 sectorMax = visibleRadius / Sector::SIZE; // lyrs_radius / sector_size_in_lyrs + for (Sint32 x = sectorMin; x < sectorMax; x++) { + for (Sint32 y = sectorMin; y < sectorMax; y++) { + for (Sint32 z = sectorMin; z < sectorMax; z++) { + SystemPath sys(x, y, z); + if (SystemPath::SectorDistanceSqr(sys, current) * Sector::SIZE >= visibleRadiusSqr) + continue; // early out + + // this is fairly expensive + RefCountedPtr sec = Pi::game->GetGalaxy()->GetSector(sys); + + // add as many systems as we can + const size_t numSystems = std::min(sec->m_systems.size(), (size_t)(NUM_BG_STARS - num)); + for (size_t systemIndex = 0; systemIndex < numSystems; systemIndex++) { + const Sector::System *ss = &(sec->m_systems[systemIndex]); + const vector3f distance = Sector::SIZE * vector3f(current.sectorX, current.sectorY, current.sectorZ) - ss->GetFullPosition(); + if (distance.Length() >= visibleRadius) + continue; // too far + + // grab the approximate real colour + Color col = StarSystem::starRealColors[ss->GetStarType(0)]; + col.r = Clamp(col.r, (Uint8)(m_rMin * 255), (Uint8)(m_rMax * 255)); + col.g = Clamp(col.g, (Uint8)(m_gMin * 255), (Uint8)(m_gMax * 255)); + col.b = Clamp(col.b, (Uint8)(m_bMin * 255), (Uint8)(m_bMax * 255)); + //const Color col(Color::PINK); // debug pink + + // copy the data + sizes[num] = size; + stars[num] = distance.Normalized() * 1000.0f; + colors[num] = col; + + //need to keep data around for HS anim - this is stupid + m_hyperVtx[NUM_BG_STARS * 2 + num] = stars[num]; + m_hyperCol[NUM_BG_STARS * 2 + num] = col * 0.8f; + num++; + } + if (num >= NUM_BG_STARS) { + x = sectorMax; + y = sectorMax; + z = sectorMax; + break; + } + } + } + } + } + Output("num = %d\n", num); + + // fill out the remaining target count with generated points + if (num < NUM_BG_STARS) { + for (Uint32 i = num; i < NUM_BG_STARS; i++) { + const double size = rand.Double(0.2, 0.9); + const Uint8 colScale = size * 255; + + const Color col( + rand.Double(m_rMin, m_rMax) * colScale, + rand.Double(m_gMin, m_gMax) * colScale, + rand.Double(m_bMin, m_bMax) * colScale, + 255); + + // this is proper random distribution on a sphere's surface + const float theta = float(rand.Double(0.0, 2.0 * M_PI)); + const float u = float(rand.Double(-1.0, 1.0)); + + sizes[i] = size; + // squeeze the starfield a bit to get more density near horizon using matrix3x3f::Scale + stars[i] = matrix3x3f::Scale(1.0, 0.4, 1.0) * (vector3f(sqrt(1.0f - u * u) * cos(theta), u, sqrt(1.0f - u * u) * sin(theta)).Normalized() * 1000.0f); + colors[i] = col; + + //need to keep data around for HS anim - this is stupid + m_hyperVtx[NUM_BG_STARS * 2 + i] = stars[i]; + m_hyperCol[NUM_BG_STARS * 2 + i] = col; + + num++; + } + } + Output("final num = %d\n", num); + + m_pointSprites->SetData(NUM_BG_STARS, stars.get(), colors.get(), sizes.get(), m_material.Get()); + + Graphics::RenderStateDesc rsd; + rsd.depthTest = false; + rsd.depthWrite = false; + rsd.blendMode = Graphics::BLEND_ALPHA; + m_renderState = m_renderer->CreateRenderState(rsd); + } + + void Starfield::Draw(Graphics::RenderState *rs) + { + // XXX would be nice to get rid of the Pi:: stuff here + if (!Pi::game || Pi::player->GetFlightState() != Ship::HYPERSPACE) { + m_pointSprites->Draw(m_renderer, m_renderState); + } else { + assert(sizeof(StarVert) == 16); + assert(m_animBuffer->GetDesc().stride == sizeof(StarVert)); + auto vtxPtr = m_animBuffer->Map(Graphics::BUFFER_MAP_WRITE); + + // roughly, the multiplier gets smaller as the duration gets larger. + // the time-looking bits in this are completely arbitrary - I figured + // it out by tweaking the numbers until it looked sort of right + const double mult = 0.0015 / (Pi::player->GetHyperspaceDuration() / (60.0 * 60.0 * 24.0 * 7.0)); + + const double hyperspaceProgress = Pi::game->GetHyperspaceProgress(); + + const Sint32 NUM_STARS = m_animBuffer->GetDesc().numVertices / 2; + + const vector3d pz = Pi::player->GetOrient().VectorZ(); //back vector + for (int i = 0; i < NUM_STARS; i++) { + vector3f v = m_hyperVtx[NUM_STARS * 2 + i] + vector3f(pz * hyperspaceProgress * mult); + const Color &c = m_hyperCol[NUM_STARS * 2 + i]; + + vtxPtr[i * 2].pos = m_hyperVtx[i * 2] = m_hyperVtx[NUM_STARS * 2 + i] + v; + vtxPtr[i * 2].col = m_hyperCol[i * 2] = c; + + vtxPtr[i * 2 + 1].pos = m_hyperVtx[i * 2 + 1] = v; + vtxPtr[i * 2 + 1].col = m_hyperCol[i * 2 + 1] = c; + } + m_animBuffer->Unmap(); + m_renderer->DrawBuffer(m_animBuffer.get(), rs, m_materialStreaks.Get(), Graphics::LINE_SINGLE); + } + } + + MilkyWay::MilkyWay(Graphics::Renderer *renderer) + { + m_renderer = renderer; + + //build milky way model in two strips (about 256 verts) + std::unique_ptr bottom(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE)); + std::unique_ptr top(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE)); + + const Color dark(Color::BLANK); + const Color bright(13, 13, 13, 13); + + //bottom + float theta; + for (theta = 0.0; theta < 2.f * float(M_PI); theta += 0.1f) { + bottom->Add( + vector3f(100.0f * sin(theta), float(-40.0 - 30.0 * noise(vector3d(sin(theta), 1.0, cos(theta)))), 100.0f * cos(theta)), + dark); + bottom->Add( + vector3f(100.0f * sin(theta), float(5.0 * noise(vector3d(sin(theta), 0.0, cos(theta)))), 100.0f * cos(theta)), + bright); + } + theta = 2.f * float(M_PI); + bottom->Add( + vector3f(100.0f * sin(theta), float(-40.0 - 30.0 * noise(vector3d(sin(theta), 1.0, cos(theta)))), 100.0f * cos(theta)), + dark); + bottom->Add( + vector3f(100.0f * sin(theta), float(5.0 * noise(vector3d(sin(theta), 0.0, cos(theta)))), 100.0f * cos(theta)), + bright); + //top + for (theta = 0; theta < 2.f * float(M_PI); theta += 0.1f) { + top->Add( + vector3f(100.0f * sin(theta), float(5.0 * noise(vector3d(sin(theta), 0.0, cos(theta)))), 100.0f * cos(theta)), + bright); + top->Add( + vector3f(100.0f * sin(theta), float(40.0 + 30.0 * noise(vector3d(sin(theta), -1.0, cos(theta)))), 100.0f * cos(theta)), + dark); + } + theta = 2.f * float(M_PI); + top->Add( + vector3f(100.0f * sin(theta), float(5.0 * noise(vector3d(sin(theta), 0.0, cos(theta)))), 100.0f * cos(theta)), + bright); + top->Add( + vector3f(100.0f * sin(theta), float(40.0 + 30.0 * noise(vector3d(sin(theta), -1.0, cos(theta)))), 100.0f * cos(theta)), + dark); + + Graphics::MaterialDescriptor desc; + desc.effect = Graphics::EFFECT_STARFIELD; + desc.vertexColors = true; + m_material.Reset(m_renderer->CreateMaterial(desc)); + m_material->emissive = Color::WHITE; + Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; - vbd.numVertices = NUM_BG_STARS*2; - m_animBuffer.reset(m_renderer->CreateVertexBuffer(vbd)); + vbd.numVertices = bottom->GetNumVerts() + top->GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + //two strips in one buffer, but seems to work ok without degenerate triangles + m_vertexBuffer.reset(renderer->CreateVertexBuffer(vbd)); + assert(m_vertexBuffer->GetDesc().stride == sizeof(MilkyWayVert)); + auto vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + for (Uint32 i = 0; i < top->GetNumVerts(); i++) { + vtxPtr->pos = top->position[i]; + vtxPtr->col = top->diffuse[i]; + vtxPtr++; + } + for (Uint32 i = 0; i < bottom->GetNumVerts(); i++) { + vtxPtr->pos = bottom->position[i]; + vtxPtr->col = bottom->diffuse[i]; + vtxPtr++; + } + m_vertexBuffer->Unmap(); } - m_pointSprites.reset( new Graphics::Drawables::PointSprites ); - - assert(sizeof(StarVert) == 16); - std::unique_ptr stars( new vector3f[NUM_BG_STARS] ); - std::unique_ptr colors( new Color[NUM_BG_STARS] ); - std::unique_ptr sizes( new float[NUM_BG_STARS] ); - //fill the array - Uint32 num = 0; - if (Pi::game != nullptr && Pi::game->GetSpace() != nullptr && Pi::game->GetSpace()->GetStarSystem() != nullptr) + void MilkyWay::Draw(Graphics::RenderState *rs) { - const SystemPath current = Pi::game->GetSpace()->GetStarSystem()->GetPath(); - - const double size = 1.0; - const Uint8 colScale = size * 255; - const Sint32 visibleRadius = 100; // lyrs - const Sint32 visibleRadiusSqr = (visibleRadius*visibleRadius); - const Sint32 sectorMin = -(visibleRadius / Sector::SIZE); // lyrs_radius / sector_size_in_lyrs - const Sint32 sectorMax = visibleRadius / Sector::SIZE; // lyrs_radius / sector_size_in_lyrs - for (Sint32 x = sectorMin; x < sectorMax; x++) - { - for (Sint32 y = sectorMin; y < sectorMax; y++) - { - for (Sint32 z = sectorMin; z < sectorMax; z++) - { - SystemPath sys(x, y, z); - if (SystemPath::SectorDistanceSqr(sys, current) * Sector::SIZE >= visibleRadiusSqr) - continue; // early out - - // this is fairly expensive - RefCountedPtr sec = Pi::game->GetGalaxy()->GetSector(sys); - - // add as many systems as we can - const size_t numSystems = std::min(sec->m_systems.size(), (size_t)(NUM_BG_STARS - num)); - for (size_t systemIndex = 0; systemIndex < numSystems; systemIndex++) - { - const Sector::System *ss = &(sec->m_systems[systemIndex]); - const vector3f distance = Sector::SIZE * vector3f(current.sectorX, current.sectorY, current.sectorZ) - ss->GetFullPosition(); - if (distance.Length() >= visibleRadius) - continue; // too far - - // grab the approximate real colour - Color col = StarSystem::starRealColors[ss->GetStarType(0)]; - col.r = Clamp(col.r, (Uint8)(m_rMin * 255), (Uint8)(m_rMax * 255)); - col.g = Clamp(col.g, (Uint8)(m_gMin * 255), (Uint8)(m_gMax * 255)); - col.b = Clamp(col.b, (Uint8)(m_bMin * 255), (Uint8)(m_bMax * 255)); - //const Color col(Color::PINK); // debug pink - - // copy the data - sizes[num] = size; - stars[num] = distance.Normalized() * 1000.0f; - colors[num] = col; - - //need to keep data around for HS anim - this is stupid - m_hyperVtx[NUM_BG_STARS * 2 + num] = stars[num]; - m_hyperCol[NUM_BG_STARS * 2 + num] = col * 0.8f; - num++; - } - if (num >= NUM_BG_STARS) - { - x = sectorMax; - y = sectorMax; - z = sectorMax; - break; - } - } - } - } + assert(m_vertexBuffer); + assert(m_material); + m_renderer->DrawBuffer(m_vertexBuffer.get(), rs, m_material.Get(), Graphics::TRIANGLE_STRIP); } - Output("num = %d\n", num); - // fill out the remaining target count with generated points - if(num < NUM_BG_STARS) + Container::Container(Graphics::Renderer *renderer, Random &rand) : + m_renderer(renderer), + m_milkyWay(renderer), + m_starField(renderer, rand), + m_universeBox(renderer), + m_drawFlags(DRAW_SKYBOX | DRAW_STARS) { - for (Uint32 i = num; i < NUM_BG_STARS; i++) - { - const double size = rand.Double(0.2, 0.9); - const Uint8 colScale = size * 255; - - const Color col( - rand.Double(m_rMin, m_rMax)*colScale, - rand.Double(m_gMin, m_gMax)*colScale, - rand.Double(m_bMin, m_bMax)*colScale, - 255); - - // this is proper random distribution on a sphere's surface - const float theta = float(rand.Double(0.0, 2.0*M_PI)); - const float u = float(rand.Double(-1.0, 1.0)); - - sizes[i] = size; - // squeeze the starfield a bit to get more density near horizon using matrix3x3f::Scale - stars[i] = matrix3x3f::Scale(1.0, 0.4, 1.0) * (vector3f(sqrt(1.0f - u * u) * cos(theta), u, sqrt(1.0f - u * u) * sin(theta)).Normalized() * 1000.0f); - colors[i] = col; - - //need to keep data around for HS anim - this is stupid - m_hyperVtx[NUM_BG_STARS * 2 + i] = stars[i]; - m_hyperCol[NUM_BG_STARS * 2 + i] = col; - - num++; - } + Graphics::RenderStateDesc rsd; + rsd.depthTest = false; + rsd.depthWrite = false; + m_renderState = renderer->CreateRenderState(rsd); + Refresh(rand); } - Output("final num = %d\n", num); - m_pointSprites->SetData(NUM_BG_STARS, stars.get(), colors.get(), sizes.get(), m_material.Get()); - - Graphics::RenderStateDesc rsd; - rsd.depthTest = false; - rsd.depthWrite = false; - rsd.blendMode = Graphics::BLEND_ALPHA; - m_renderState = m_renderer->CreateRenderState(rsd); -} - -void Starfield::Draw(Graphics::RenderState *rs) -{ - // XXX would be nice to get rid of the Pi:: stuff here - if (!Pi::game || Pi::player->GetFlightState() != Ship::HYPERSPACE) { - m_pointSprites->Draw(m_renderer, m_renderState); - } else { - assert(sizeof(StarVert) == 16); - assert(m_animBuffer->GetDesc().stride == sizeof(StarVert)); - auto vtxPtr = m_animBuffer->Map(Graphics::BUFFER_MAP_WRITE); - - // roughly, the multiplier gets smaller as the duration gets larger. - // the time-looking bits in this are completely arbitrary - I figured - // it out by tweaking the numbers until it looked sort of right - const double mult = 0.0015 / (Pi::player->GetHyperspaceDuration() / (60.0*60.0*24.0*7.0)); - - const double hyperspaceProgress = Pi::game->GetHyperspaceProgress(); - - const Sint32 NUM_STARS = m_animBuffer->GetDesc().numVertices / 2; - - const vector3d pz = Pi::player->GetOrient().VectorZ(); //back vector - for (int i=0; iUnmap(); - m_renderer->DrawBuffer(m_animBuffer.get(), rs, m_materialStreaks.Get(), Graphics::LINE_SINGLE); + void Container::Refresh(Random &rand) + { + // always redo starfield, milkyway stays normal for now + m_starField.Fill(rand); + m_universeBox.LoadCubeMap(rand); } -} -MilkyWay::MilkyWay(Graphics::Renderer *renderer) -{ - m_renderer = renderer; - - //build milky way model in two strips (about 256 verts) - std::unique_ptr bottom(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE)); - std::unique_ptr top(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE)); - - const Color dark(Color::BLANK); - const Color bright(13, 13, 13, 13); - - //bottom - float theta; - for (theta=0.0; theta < 2.f*float(M_PI); theta+=0.1f) { - bottom->Add( - vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(vector3d(sin(theta),1.0,cos(theta)))), 100.0f*cos(theta)), - dark); - bottom->Add( - vector3f(100.0f*sin(theta), float(5.0*noise(vector3d(sin(theta),0.0,cos(theta)))), 100.0f*cos(theta)), - bright); - } - theta = 2.f*float(M_PI); - bottom->Add( - vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(vector3d(sin(theta),1.0,cos(theta)))), 100.0f*cos(theta)), - dark); - bottom->Add( - vector3f(100.0f*sin(theta), float(5.0*noise(vector3d(sin(theta),0.0,cos(theta)))), 100.0f*cos(theta)), - bright); - //top - for (theta=0; theta < 2.f*float(M_PI); theta+=0.1f) { - top->Add( - vector3f(100.0f*sin(theta), float(5.0*noise(vector3d(sin(theta),0.0,cos(theta)))), 100.0f*cos(theta)), - bright); - top->Add( - vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(vector3d(sin(theta),-1.0,cos(theta)))), 100.0f*cos(theta)), - dark); - } - theta = 2.f*float(M_PI); - top->Add( - vector3f(100.0f*sin(theta), float(5.0*noise(vector3d(sin(theta),0.0,cos(theta)))), 100.0f*cos(theta)), - bright); - top->Add( - vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(vector3d(sin(theta),-1.0,cos(theta)))), 100.0f*cos(theta)), - dark); - - Graphics::MaterialDescriptor desc; - desc.effect = Graphics::EFFECT_STARFIELD; - desc.vertexColors = true; - m_material.Reset(m_renderer->CreateMaterial(desc)); - m_material->emissive = Color::WHITE; - - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = bottom->GetNumVerts() + top->GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - //two strips in one buffer, but seems to work ok without degenerate triangles - m_vertexBuffer.reset(renderer->CreateVertexBuffer(vbd)); - assert(m_vertexBuffer->GetDesc().stride == sizeof(MilkyWayVert)); - auto vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); - for (Uint32 i = 0; i < top->GetNumVerts(); i++) { - vtxPtr->pos = top->position[i]; - vtxPtr->col = top->diffuse[i]; - vtxPtr++; - } - for (Uint32 i = 0; i < bottom->GetNumVerts(); i++) { - vtxPtr->pos = bottom->position[i]; - vtxPtr->col = bottom->diffuse[i]; - vtxPtr++; - } - m_vertexBuffer->Unmap(); -} - -void MilkyWay::Draw(Graphics::RenderState *rs) -{ - assert(m_vertexBuffer); - assert(m_material); - m_renderer->DrawBuffer(m_vertexBuffer.get(), rs, m_material.Get(), Graphics::TRIANGLE_STRIP); -} - -Container::Container(Graphics::Renderer *renderer, Random &rand) -: m_renderer(renderer) -, m_milkyWay(renderer) -, m_starField(renderer, rand) -, m_universeBox(renderer) -, m_drawFlags( DRAW_SKYBOX | DRAW_STARS ) -{ - Graphics::RenderStateDesc rsd; - rsd.depthTest = false; - rsd.depthWrite = false; - m_renderState = renderer->CreateRenderState(rsd); - Refresh(rand); -} - -void Container::Refresh(Random &rand) -{ - // always redo starfield, milkyway stays normal for now - m_starField.Fill(rand); - m_universeBox.LoadCubeMap(rand); -} - -void Container::Draw(const matrix4x4d &transform) -{ - PROFILE_SCOPED() - m_renderer->SetTransform(transform); - if( DRAW_SKYBOX & m_drawFlags ) { - m_universeBox.Draw(m_renderState); - } - if( DRAW_MILKY & m_drawFlags ) { - m_milkyWay.Draw(m_renderState); - } - if( DRAW_STARS & m_drawFlags ) { + void Container::Draw(const matrix4x4d &transform) + { + PROFILE_SCOPED() m_renderer->SetTransform(transform); - m_starField.Draw(m_renderState); + if (DRAW_SKYBOX & m_drawFlags) { + m_universeBox.Draw(m_renderState); + } + if (DRAW_MILKY & m_drawFlags) { + m_milkyWay.Draw(m_renderState); + } + if (DRAW_STARS & m_drawFlags) { + m_renderer->SetTransform(transform); + m_starField.Draw(m_renderState); + } } -} -void Container::SetIntensity(float intensity) -{ - PROFILE_SCOPED() - intensity = Clamp(intensity, 0.0f, 1.0f); - m_universeBox.SetIntensity(intensity); - m_starField.SetIntensity(intensity); - m_milkyWay.SetIntensity(intensity); -} + void Container::SetIntensity(float intensity) + { + PROFILE_SCOPED() + intensity = Clamp(intensity, 0.0f, 1.0f); + m_universeBox.SetIntensity(intensity); + m_starField.SetIntensity(intensity); + m_milkyWay.SetIntensity(intensity); + } -void Container::SetDrawFlags(const Uint32 flags) -{ - m_drawFlags = flags; -} + void Container::SetDrawFlags(const Uint32 flags) + { + m_drawFlags = flags; + } } //namespace Background diff --git a/src/Background.h b/src/Background.h index 01fbf5c25..73ff19b9b 100644 --- a/src/Background.h +++ b/src/Background.h @@ -4,26 +4,24 @@ #ifndef _BACKGROUND_H #define _BACKGROUND_H -#include "libs.h" +#include "Random.h" #include "galaxy/SystemPath.h" #include "graphics/Drawables.h" -#include "graphics/Texture.h" #include "graphics/RenderState.h" -#include "Random.h" +#include "graphics/Texture.h" +#include "libs.h" namespace Graphics { class Renderer; class Material; -} +} // namespace Graphics /* * Classes to draw background stars and the milky way */ -namespace Background -{ - class BackgroundElement - { +namespace Background { + class BackgroundElement { public: void SetIntensity(float intensity); @@ -40,13 +38,12 @@ namespace Background float m_bMax; }; - class UniverseBox : public BackgroundElement - { + class UniverseBox : public BackgroundElement { public: UniverseBox(Graphics::Renderer *r); ~UniverseBox(); - void Draw(Graphics::RenderState*); + void Draw(Graphics::RenderState *); void LoadCubeMap(Random &rand); private: @@ -58,12 +55,11 @@ namespace Background Uint32 m_numCubemaps; }; - class Starfield : public BackgroundElement - { + class Starfield : public BackgroundElement { public: //does not Fill the starfield Starfield(Graphics::Renderer *r, Random &rand); - void Draw(Graphics::RenderState*); + void Draw(Graphics::RenderState *); //create or recreate the starfield void Fill(Random &rand); @@ -71,38 +67,33 @@ namespace Background void Init(); std::unique_ptr m_pointSprites; - Graphics::RenderState* m_renderState; // NB: we don't own RenderState pointers, just borrow them + Graphics::RenderState *m_renderState; // NB: we don't own RenderState pointers, just borrow them //hyperspace animation vertex data - std::unique_ptr m_hyperVtx;// BG_STAR_MAX * 3 - std::unique_ptr m_hyperCol;// BG_STAR_MAX * 3 + std::unique_ptr m_hyperVtx; // BG_STAR_MAX * 3 + std::unique_ptr m_hyperCol; // BG_STAR_MAX * 3 std::unique_ptr m_animBuffer; }; - class MilkyWay : public BackgroundElement - { + class MilkyWay : public BackgroundElement { public: - MilkyWay(Graphics::Renderer*); - void Draw(Graphics::RenderState*); + MilkyWay(Graphics::Renderer *); + void Draw(Graphics::RenderState *); private: std::unique_ptr m_vertexBuffer; }; - - // contains starfield, milkyway, possibly other Background elements - class Container - { + class Container { public: - enum BackgroundDrawFlags - { - DRAW_STARS = 1<<0, - DRAW_MILKY = 1<<1, - DRAW_SKYBOX = 1<<2 + enum BackgroundDrawFlags { + DRAW_STARS = 1 << 0, + DRAW_MILKY = 1 << 1, + DRAW_SKYBOX = 1 << 2 }; - Container(Graphics::Renderer*, Random &rand); + Container(Graphics::Renderer *, Random &rand); void Draw(const matrix4x4d &transform); void SetIntensity(float intensity); diff --git a/src/BaseSphere.cpp b/src/BaseSphere.cpp index 0e83224a0..4f2f1e760 100644 --- a/src/BaseSphere.cpp +++ b/src/BaseSphere.cpp @@ -1,14 +1,16 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" #include "BaseSphere.h" -#include "GeoSphere.h" #include "GasGiant.h" +#include "GeoSphere.h" +#include "Pi.h" #include "graphics/Material.h" +#include "libs.h" -BaseSphere::BaseSphere(const SystemBody *body) : m_sbody(body), m_terrain(Terrain::InstanceTerrain(body)) {} +BaseSphere::BaseSphere(const SystemBody *body) : + m_sbody(body), + m_terrain(Terrain::InstanceTerrain(body)) {} BaseSphere::~BaseSphere() {} @@ -52,8 +54,8 @@ void BaseSphere::DrawAtmosphereSurface(Graphics::Renderer *renderer, renderer->SetTransform(modelView * matrix4x4d::ScaleMatrix(rad, rad, rad) * invrot); - if(!m_atmos) - m_atmos.reset( new Drawables::Sphere3D(renderer, mat, rs, 4, 1.0f, ATTRIB_POSITION)); + if (!m_atmos) + m_atmos.reset(new Drawables::Sphere3D(renderer, mat, rs, 4, 1.0f, ATTRIB_POSITION)); m_atmos->Draw(renderer); renderer->GetStats().AddToStatCount(Graphics::Stats::STAT_ATMOSPHERES, 1); diff --git a/src/BaseSphere.h b/src/BaseSphere.h index cb64c98a5..bd9957300 100644 --- a/src/BaseSphere.h +++ b/src/BaseSphere.h @@ -6,10 +6,10 @@ #include -#include "vector3.h" #include "Camera.h" #include "galaxy/StarSystem.h" #include "terrain/Terrain.h" +#include "vector3.h" #include @@ -17,7 +17,7 @@ namespace Graphics { class Renderer; class RenderState; class Material; -} +} // namespace Graphics class SystemBody; class BaseSphere { @@ -25,8 +25,8 @@ public: BaseSphere(const SystemBody *body); virtual ~BaseSphere(); - virtual void Update()=0; - virtual void Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, vector3d campos, const float radius, const std::vector &shadows)=0; + virtual void Update() = 0; + virtual void Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, vector3d campos, const float radius, const std::vector &shadows) = 0; virtual double GetHeight(const vector3d &p) const { return 0.0; } @@ -49,14 +49,14 @@ public: Sint32 maxPatchDepth; }; - virtual void Reset()=0; + virtual void Reset() = 0; const SystemBody *GetSystemBody() const { return m_sbody; } - Terrain* GetTerrain() const { return m_terrain.Get(); } + Terrain *GetTerrain() const { return m_terrain.Get(); } - Graphics::RenderState* GetSurfRenderState() const { return m_surfRenderState; } + Graphics::RenderState *GetSurfRenderState() const { return m_surfRenderState; } RefCountedPtr GetSurfaceMaterial() const { return m_surfaceMaterial; } - MaterialParameters& GetMaterialParameters() { return m_materialParameters; } + MaterialParameters &GetMaterialParameters() { return m_materialParameters; } protected: const SystemBody *m_sbody; @@ -64,7 +64,7 @@ protected: // all variables for GetHeight(), GetColor() RefCountedPtr m_terrain; - virtual void SetUpMaterials()=0; + virtual void SetUpMaterials() = 0; Graphics::RenderState *m_surfRenderState; Graphics::RenderState *m_atmosRenderState; diff --git a/src/Beam.cpp b/src/Beam.cpp index c8a706d67..b7c139806 100644 --- a/src/Beam.cpp +++ b/src/Beam.cpp @@ -1,32 +1,30 @@ // Copyright © 2008-2016 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" #include "Beam.h" -#include "Frame.h" -#include "galaxy/StarSystem.h" -#include "Space.h" -#include "GameSaveError.h" -#include "collider/collider.h" #include "CargoBody.h" -#include "Planet.h" -#include "Sfx.h" -#include "Ship.h" -#include "Pi.h" -#include "Player.h" +#include "Frame.h" #include "Game.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "LuaEvent.h" #include "LuaUtils.h" +#include "Pi.h" +#include "Planet.h" +#include "Player.h" +#include "Sfx.h" +#include "Ship.h" +#include "Space.h" +#include "collider/collider.h" +#include "galaxy/StarSystem.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" -#include "graphics/VertexArray.h" #include "graphics/TextureBuilder.h" -#include "JsonUtils.h" +#include "graphics/VertexArray.h" +#include "libs.h" -namespace -{ +namespace { static float lifetime = 0.1f; } @@ -53,8 +51,8 @@ void Beam::BuildModel() const float w = 0.5f; vector3f one(0.f, -w, 0.f); //top left - vector3f two(0.f, w, 0.f); //top right - vector3f three(0.f, w, -1.f); //bottom right + vector3f two(0.f, w, 0.f); //top right + vector3f three(0.f, w, -1.f); //bottom right vector3f four(0.f, -w, -1.f); //bottom left //uv coords @@ -67,7 +65,7 @@ void Beam::BuildModel() s_glowVerts.reset(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0, 240)); //add four intersecting planes to create a volumetric effect - for (int i=0; i < 4; i++) { + for (int i = 0; i < 4; i++) { s_sideVerts->Add(one, topLeft); s_sideVerts->Add(two, topRight); s_sideVerts->Add(three, botRight); @@ -86,7 +84,7 @@ void Beam::BuildModel() static const float gw = 0.5f; float gz = -0.1f; - for (int i=0; i < 40; i++) { + for (int i = 0; i < 40; i++) { s_glowVerts->Add(vector3f(-gw, -gw, gz), topLeft); s_glowVerts->Add(vector3f(-gw, gw, gz), topRight); s_glowVerts->Add(vector3f(gw, gw, gz), botRight); @@ -113,7 +111,8 @@ void Beam::FreeModel() s_glowVerts.reset(); } -Beam::Beam(): Body() +Beam::Beam() : + Body() { if (!s_sideMat) BuildModel(); SetOrient(matrix3x3d::Identity()); @@ -174,10 +173,10 @@ void Beam::UpdateInterpTransform(double alpha) { m_interpOrient = GetOrient(); const vector3d oldPos = GetPosition() - (m_baseVel * Pi::game->GetTimeStep()); - m_interpPos = alpha*GetPosition() + (1.0-alpha)*oldPos; + m_interpPos = alpha * GetPosition() + (1.0 - alpha) * oldPos; } -void Beam::NotifyRemoved(const Body* const removedBody) +void Beam::NotifyRemoved(const Body *const removedBody) { if (m_parent == removedBody) m_parent = nullptr; @@ -199,7 +198,7 @@ float Beam::GetDamage() const double Beam::GetRadius() const { - return sqrt(m_length*m_length); + return sqrt(m_length * m_length); } static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos) @@ -230,8 +229,8 @@ static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, con cargo->SetPosition(pos); const double x = Pi::rng.Double(); vector3d dir = pos.Normalized(); - dir.ArbRotate(vector3d(x, 1-x, 0), Pi::rng.Double()-.5); - cargo->SetVelocity(Pi::rng.Double(100.0,200.0) * dir); + dir.ArbRotate(vector3d(x, 1 - x, 0), Pi::rng.Double() - .5); + cargo->SetVelocity(Pi::rng.Double(100.0, 200.0) * dir); Pi::game->GetSpace()->AddBody(cargo); } @@ -243,21 +242,20 @@ void Beam::StaticUpdate(const float timeStep) return; CollisionContact c; - GetFrame()->GetCollisionSpace()->TraceRay(GetPosition(), m_dir.Normalized(), m_length, &c, static_cast(m_parent)->GetGeom()); + GetFrame()->GetCollisionSpace()->TraceRay(GetPosition(), m_dir.Normalized(), m_length, &c, static_cast(m_parent)->GetGeom()); if (c.userData1) { - Object *o = static_cast(c.userData1); + Object *o = static_cast(c.userData1); if (o->IsType(Object::CITYONPLANET)) { Pi::game->GetSpace()->KillBody(this); - } - else if (o->IsType(Object::BODY)) { - Body *hit = static_cast(o); + } else if (o->IsType(Object::BODY)) { + Body *hit = static_cast(o); if (hit != m_parent) { hit->OnDamage(m_parent, GetDamage(), c); m_active = false; if (hit->IsType(Object::SHIP)) - LuaEvent::Queue("onShipHit", dynamic_cast(hit), dynamic_cast(m_parent)); + LuaEvent::Queue("onShipHit", dynamic_cast(hit), dynamic_cast(m_parent)); } } } @@ -265,7 +263,7 @@ void Beam::StaticUpdate(const float timeStep) if (m_mining) { // need to test for terrain hit if (GetFrame()->GetBody() && GetFrame()->GetBody()->IsType(Object::PLANET)) { - Planet *const planet = static_cast(GetFrame()->GetBody()); + Planet *const planet = static_cast(GetFrame()->GetBody()); const SystemBody *b = planet->GetSystemBody(); vector3d pos = GetPosition(); double terrainHeight = planet->GetTerrainHeight(pos.Normalized()); @@ -273,7 +271,7 @@ void Beam::StaticUpdate(const float timeStep) // hit the fucker if (b->GetType() == SystemBody::TYPE_PLANET_ASTEROID) { vector3d n = GetPosition().Normalized(); - MiningLaserSpawnTastyStuff(planet->GetFrame(), b, n*terrainHeight + 5.0*n); + MiningLaserSpawnTastyStuff(planet->GetFrame(), b, n * terrainHeight + 5.0 * n); SfxManager::Add(this, TYPE_EXPLOSION); } m_active = false; @@ -293,12 +291,20 @@ void Beam::Render(Graphics::Renderer *renderer, const Camera *camera, const vect vector3f v1, v2; matrix4x4f m = matrix4x4f::Identity(); - v1.x = dir.y; v1.y = dir.z; v1.z = dir.x; + v1.x = dir.y; + v1.y = dir.z; + v1.z = dir.x; v2 = v1.Cross(dir).Normalized(); v1 = v2.Cross(dir); - m[0] = v1.x; m[4] = v2.x; m[8] = dir.x; - m[1] = v1.y; m[5] = v2.y; m[9] = dir.y; - m[2] = v1.z; m[6] = v2.z; m[10] = dir.z; + m[0] = v1.x; + m[4] = v2.x; + m[8] = dir.x; + m[1] = v1.y; + m[5] = v2.y; + m[9] = dir.y; + m[2] = v1.z; + m[6] = v2.z; + m[10] = dir.z; m[12] = from.x; m[13] = from.y; @@ -337,7 +343,7 @@ void Beam::Render(Graphics::Renderer *renderer, const Camera *camera, const vect } // static -void Beam::Add(Body *parent, const ProjectileData& prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dir) +void Beam::Add(Body *parent, const ProjectileData &prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dir) { Beam *p = new Beam(); p->m_parent = parent; diff --git a/src/Beam.h b/src/Beam.h index 8eb081241..288b35c75 100644 --- a/src/Beam.h +++ b/src/Beam.h @@ -6,30 +6,30 @@ #ifndef _BEAM_H #define _BEAM_H -#include "libs.h" #include "Body.h" #include "graphics/Material.h" #include "graphics/RenderState.h" +#include "libs.h" class Frame; namespace Graphics { class Renderer; class VertexArray; -} +} // namespace Graphics struct ProjectileData; -class Beam: public Body { +class Beam : public Body { public: OBJDEF(Beam, Body, PROJECTILE); - static void Add(Body *parent, const ProjectileData& prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dir); + static void Add(Body *parent, const ProjectileData &prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dir); Beam(); virtual ~Beam(); virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override final; void TimeStepUpdate(const float timeStep) override final; void StaticUpdate(const float timeStep) override final; - virtual void NotifyRemoved(const Body* const removedBody) override final; + virtual void NotifyRemoved(const Body *const removedBody) override final; virtual void PostLoadFixup(Space *space) override final; virtual void UpdateInterpTransform(double alpha) override final; diff --git a/src/Body.cpp b/src/Body.cpp index bd7efa996..64ac8e326 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -1,35 +1,36 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Body.h" -#include "Frame.h" -#include "Star.h" -#include "Planet.h" #include "CargoBody.h" -#include "SpaceStation.h" -#include "Ship.h" +#include "Frame.h" +#include "Game.h" +#include "GameSaveError.h" +#include "HyperspaceCloud.h" +#include "JsonUtils.h" +#include "LuaEvent.h" +#include "Missile.h" +#include "Pi.h" +#include "Planet.h" #include "Player.h" #include "Projectile.h" -#include "Missile.h" -#include "HyperspaceCloud.h" -#include "Pi.h" +#include "Ship.h" #include "Space.h" -#include "Game.h" -#include "LuaEvent.h" -#include "GameSaveError.h" -#include "JsonUtils.h" +#include "SpaceStation.h" +#include "Star.h" +#include "libs.h" -Body::Body() : PropertiedObject(Lua::manager) - , m_flags(0) - , m_interpPos(0.0) - , m_interpOrient(matrix3x3d::Identity()) - , m_pos(0.0) - , m_orient(matrix3x3d::Identity()) - , m_frame(0) - , m_dead(false) - , m_clipRadius(0.0) - , m_physRadius(0.0) +Body::Body() : + PropertiedObject(Lua::manager), + m_flags(0), + m_interpPos(0.0), + m_interpOrient(matrix3x3d::Identity()), + m_pos(0.0), + m_orient(matrix3x3d::Identity()), + m_frame(0), + m_dead(false), + m_clipRadius(0.0), + m_physRadius(0.0) { Properties().Set("label", m_label); } @@ -70,8 +71,7 @@ void Body::LoadFromJson(const Json &jsonObj, Space *space) m_orient = bodyObj["orient"]; m_physRadius = bodyObj["phys_radius"]; m_clipRadius = bodyObj["clip_radius"]; - } - catch (Json::type_error &) { + } catch (Json::type_error &) { throw SavedGameCorruptException(); } } @@ -106,23 +106,32 @@ Body *Body::FromJson(const Json &jsonObj, Space *space) Object::Type type = Object::Type(jsonObj["body_type"]); switch (type) { case Object::STAR: - b = new Star(); break; + b = new Star(); + break; case Object::PLANET: - b = new Planet(); break; + b = new Planet(); + break; case Object::SPACESTATION: - b = new SpaceStation(); break; + b = new SpaceStation(); + break; case Object::SHIP: - b = new Ship(); break; + b = new Ship(); + break; case Object::PLAYER: - b = new Player(); break; + b = new Player(); + break; case Object::MISSILE: - b = new Missile(); break; + b = new Missile(); + break; case Object::PROJECTILE: - b = new Projectile(); break; + b = new Projectile(); + break; case Object::CARGOBODY: - b = new CargoBody(); break; + b = new CargoBody(); + break; case Object::HYPERSPACECLOUD: - b = new HyperspaceCloud(); break; + b = new HyperspaceCloud(); + break; default: assert(0); } @@ -181,16 +190,16 @@ vector3d Body::GetVelocityRelTo(const Body *relTo) const void Body::OrientOnSurface(double radius, double latitude, double longitude) { - vector3d up = vector3d(cos(latitude)*cos(longitude), sin(latitude)*cos(longitude), sin(longitude)); + vector3d up = vector3d(cos(latitude) * cos(longitude), sin(latitude) * cos(longitude), sin(longitude)); SetPosition(radius * up); - vector3d right = up.Cross(vector3d(0,0,1)).Normalized(); + vector3d right = up.Cross(vector3d(0, 0, 1)).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); } void Body::SwitchToFrame(Frame *newFrame) { - const vector3d vel = GetVelocityRelTo(newFrame); // do this first because it uses position + const vector3d vel = GetVelocityRelTo(newFrame); // do this first because it uses position const vector3d fpos = m_frame->GetPositionRelTo(newFrame); const matrix3x3d forient = m_frame->GetOrientRelTo(newFrame); SetPosition(forient * GetPosition() + fpos); @@ -208,7 +217,7 @@ void Body::UpdateFrame() // falling out of frames if (m_frame->GetRadius() < GetPosition().Length()) { Frame *newFrame = GetFrame()->GetParent(); - if (newFrame) { // don't fall out of root frame + if (newFrame) { // don't fall out of root frame Output("%s leaves frame %s\n", GetLabel().c_str(), GetFrame()->GetLabel().c_str()); SwitchToFrame(newFrame); return; @@ -216,7 +225,7 @@ void Body::UpdateFrame() } // entering into frames - for (Frame* kid : m_frame->GetChildren()) { + for (Frame *kid : m_frame->GetChildren()) { const vector3d pos = GetPositionRelTo(kid); if (pos.Length() >= kid->GetRadius()) continue; SwitchToFrame(kid); diff --git a/src/Body.h b/src/Body.h index 6e91ca989..9656ad8fd 100644 --- a/src/Body.h +++ b/src/Body.h @@ -4,27 +4,29 @@ #ifndef _BODY_H #define _BODY_H -#include "vector3.h" -#include "matrix4x4.h" -#include "Object.h" #include "Frame.h" +#include "Object.h" #include "PropertiedObject.h" +#include "matrix4x4.h" +#include "vector3.h" #include class ObjMesh; class Space; class Camera; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} struct CollisionContact; -class Body: public Object, public PropertiedObject { +class Body : public Object, public PropertiedObject { public: OBJDEF(Body, Object, BODY); Body(); virtual ~Body(); void ToJson(Json &jsonObj, Space *space); static Body *FromJson(const Json &jsonObj, Space *space); - virtual void PostLoadFixup(Space *space) {}; + virtual void PostLoadFixup(Space *space){}; virtual void SetPosition(const vector3d &p) { m_pos = p; } vector3d GetPosition() const { return m_pos; } @@ -37,14 +39,18 @@ public: double GetPhysRadius() const { return m_physRadius; } void SetClipRadius(double r) { m_clipRadius = r; } double GetClipRadius() const { return m_clipRadius; } - virtual double GetMass() const { assert(0); return 0; } + virtual double GetMass() const + { + assert(0); + return 0; + } // return true if to do collision response and apply damage virtual bool OnCollision(Object *o, Uint32 flags, double relVel) { return false; } // Attacker may be null - virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) { return false; } + virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) { return false; } // Override to clear any pointers you hold to the body - virtual void NotifyRemoved(const Body* const removedBody) {} + virtual void NotifyRemoved(const Body *const removedBody) {} // before all bodies have had TimeStepUpdate (their moving step), // StaticUpdate() is called. Good for special collision testing (Projectiles) @@ -56,7 +62,7 @@ public: virtual void SetFrame(Frame *f) { m_frame = f; } Frame *GetFrame() const { return m_frame; } void SwitchToFrame(Frame *newFrame); - void UpdateFrame(); // check for frame switching + void UpdateFrame(); // check for frame switching vector3d GetVelocityRelTo(const Body *) const; vector3d GetVelocityRelTo(const Frame *) const; @@ -88,7 +94,8 @@ public: // should set m_interpolatedTransform to the smoothly interpolated value // (interpolated by 0 <= alpha <=1) between the previous and current physics tick - virtual void UpdateInterpTransform(double alpha) { + virtual void UpdateInterpTransform(double alpha) + { m_interpOrient = GetOrient(); m_interpPos = GetPosition(); } @@ -96,9 +103,9 @@ public: // where to draw targeting indicators - usually equal to GetInterpolatedPositionRelTo virtual vector3d GetTargetIndicatorPosition(const Frame *relTo) const; - enum { FLAG_CAN_MOVE_FRAME = (1<<0), - FLAG_LABEL_HIDDEN = (1<<1), - FLAG_DRAW_LAST = (1<<2) }; // causes the body drawn after other bodies in the z-sort + enum { FLAG_CAN_MOVE_FRAME = (1 << 0), + FLAG_LABEL_HIDDEN = (1 << 1), + FLAG_DRAW_LAST = (1 << 2) }; // causes the body drawn after other bodies in the z-sort protected: virtual void SaveToJson(Json &jsonObj, Space *space); @@ -108,12 +115,13 @@ protected: // Interpolated draw orientation-position vector3d m_interpPos; matrix3x3d m_interpOrient; + private: vector3d m_pos; matrix3x3d m_orient; - Frame *m_frame; // frame of reference + Frame *m_frame; // frame of reference std::string m_label; - bool m_dead; // Checked in destructor to make sure body has been marked dead. + bool m_dead; // Checked in destructor to make sure body has been marked dead. double m_clipRadius; double m_physRadius; }; diff --git a/src/ByteRange.h b/src/ByteRange.h index 6130317a3..1cebf6747 100644 --- a/src/ByteRange.h +++ b/src/ByteRange.h @@ -4,22 +4,25 @@ #ifndef _BYTERANGE_H #define _BYTERANGE_H +#include #include #include #include -#include -struct ByteRange -{ - ByteRange(): begin(0), end(0) {} - ByteRange(const char *begin_, const char *end_) - : begin(begin_), end(end_) +struct ByteRange { + ByteRange() : + begin(0), + end(0) {} + ByteRange(const char *begin_, const char *end_) : + begin(begin_), + end(end_) { assert(begin_ && end_); assert((end_ - begin_) >= 0); } - ByteRange(const char *begin_, size_t size) - : begin(begin_), end(begin_ + size) + ByteRange(const char *begin_, size_t size) : + begin(begin_), + end(begin_ + size) { assert(begin_); } diff --git a/src/CRC32.cpp b/src/CRC32.cpp index 1da01cd18..8a3a5f244 100644 --- a/src/CRC32.cpp +++ b/src/CRC32.cpp @@ -13,17 +13,18 @@ static Uint32 crc32_reflect(Uint32 v, const int bits) Uint32 r = 0; for (int i = 1; i <= bits; i++) { if (v & 1) - r = r | (1<<(bits-i)); + r = r | (1 << (bits - i)); v >>= 1; } return r; } -CRC32::CRC32() : m_checksum(0xffffffff) +CRC32::CRC32() : + m_checksum(0xffffffff) { - if (! s_lookupTableGenerated) { + if (!s_lookupTableGenerated) { for (int i = 0; i <= 0xff; i++) { - s_lookupTable[i] = crc32_reflect(i,8) << 24; + s_lookupTable[i] = crc32_reflect(i, 8) << 24; for (int j = 0; j < 8; j++) s_lookupTable[i] = (s_lookupTable[i] << 1) ^ (s_lookupTable[i] & (1 << 31) ? s_polynomial : 0); s_lookupTable[i] = crc32_reflect(s_lookupTable[i], 32); diff --git a/src/Camera.cpp b/src/Camera.cpp index f96490ebc..3a61648e6 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -3,18 +3,18 @@ #include "Camera.h" #include "Frame.h" -#include "galaxy/StarSystem.h" -#include "Space.h" -#include "Player.h" -#include "Pi.h" -#include "Sfx.h" #include "Game.h" +#include "Pi.h" #include "Planet.h" +#include "Player.h" +#include "Sfx.h" +#include "Space.h" +#include "galaxy/StarSystem.h" #include "graphics/Graphics.h" -#include "graphics/Renderer.h" -#include "graphics/VertexArray.h" #include "graphics/Material.h" +#include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" +#include "graphics/VertexArray.h" #include @@ -60,7 +60,7 @@ void CameraContext::BeginFrame() // make sure old orient and interpolated orient (rendering orient) are not rubbish m_camFrame->ClearMovement(); - m_camFrame->UpdateInterpTransform(1.0); // update root-relative pos/orient + m_camFrame->UpdateInterpTransform(1.0); // update root-relative pos/orient } void CameraContext::EndFrame() @@ -75,11 +75,10 @@ void CameraContext::EndFrame() void CameraContext::ApplyDrawTransforms(Graphics::Renderer *r) { - r->SetPerspectiveProjection(m_fovAng, m_width/m_height, m_zNear, m_zFar); + r->SetPerspectiveProjection(m_fovAng, m_width / m_height, m_zNear, m_zFar); r->SetTransform(matrix4x4f::Identity()); } - Camera::Camera(RefCountedPtr context, Graphics::Renderer *renderer) : m_context(context), m_renderer(renderer) @@ -102,7 +101,7 @@ static void position_system_lights(Frame *camFrame, Frame *frame, std::vectorIsRotFrame() && (body->GetSuperType() == SystemBody::SUPERTYPE_STAR)) { vector3d lpos = frame->GetPositionRelTo(camFrame); const double dist = lpos.Length() / AU; - lpos *= 1.0/dist; // normalize + lpos *= 1.0 / dist; // normalize const Color &col = StarSystem::starRealColors[body->GetType()]; @@ -112,7 +111,7 @@ static void position_system_lights(Frame *camFrame, Frame *frame, std::vectorGetBody(), light)); } - for (Frame* kid : frame->GetChildren()) { + for (Frame *kid : frame->GetChildren()) { position_system_lights(camFrame, kid, lights); } } @@ -123,13 +122,13 @@ void Camera::Update() // evaluate each body and determine if/where/how to draw it m_sortedBodies.clear(); - for (Body* b : Pi::game->GetSpace()->GetBodies()) { + for (Body *b : Pi::game->GetSpace()->GetBodies()) { BodyAttrs attrs; attrs.body = b; attrs.billboard = false; // false by default // determine position and transform for draw -// Frame::GetFrameTransform(b->GetFrame(), camFrame, attrs.viewTransform); // doesn't use interp coords, so breaks in some cases + // Frame::GetFrameTransform(b->GetFrame(), camFrame, attrs.viewTransform); // doesn't use interp coords, so breaks in some cases attrs.viewTransform = b->GetFrame()->GetInterpOrientRelTo(camFrame); attrs.viewTransform.SetTranslate(b->GetFrame()->GetInterpPositionRelTo(camFrame)); attrs.viewCoords = attrs.viewTransform * b->GetInterpPosition(); @@ -159,19 +158,17 @@ void Camera::Update() attrs.billboardSize = std::max(1.0f, pixSize); if (b->IsType(Object::STAR)) { attrs.billboardColor = StarSystem::starRealColors[b->GetSystemBody()->GetType()]; - } - else if (b->IsType(Object::PLANET)) { + } else if (b->IsType(Object::PLANET)) { // XXX this should incorporate some lighting effect // (ie, colour of the illuminating star(s)) attrs.billboardColor = b->GetSystemBody()->GetAlbedo(); - } - else { + } else { attrs.billboardColor = Color::WHITE; } // this should always be the main star in the system - except for the star itself! - if( !m_lightSources.empty() && !b->IsType(Object::STAR) ) { - const Graphics::Light& light = m_lightSources[0].GetLight(); + if (!m_lightSources.empty() && !b->IsType(Object::STAR)) { + const Graphics::Light &light = m_lightSources[0].GetLight(); attrs.billboardColor *= light.GetDiffuse(); // colour the billboard a little with the Starlight } @@ -188,7 +185,7 @@ void Camera::Update() m_sortedBodies.sort(); } -void Camera::Draw(const Body *excludeBody, ShipCockpit* cockpit) +void Camera::Draw(const Body *excludeBody, ShipCockpit *cockpit) { PROFILE_SCOPED() @@ -217,18 +214,16 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit* cockpit) //check if camera is near a planet Body *camParentBody = camFrame->GetParent()->GetBody(); if (camParentBody && camParentBody->IsType(Object::PLANET)) { - Planet *planet = static_cast(camParentBody); + Planet *planet = static_cast(camParentBody); const vector3f relpos(planet->GetInterpPositionRelTo(camFrame)); double altitude(relpos.Length()); double pressure, density; planet->GetAtmosphericState(altitude, &pressure, &density); - if (pressure >= 0.001) - { + if (pressure >= 0.001) { //go through all lights to calculate something resembling light intensity float intensity = 0.f; - const Player* pBody = Pi::game->GetPlayer(); - for( Uint32 i=0; iGetPlayer(); + for (Uint32 i = 0; i < m_lightSources.size(); i++) { // Set up data for eclipses. All bodies are assumed to be spheres. const LightSource &it = m_lightSources[i]; const vector3f lightDir(it.GetLight().GetPosition().Normalized()); @@ -266,8 +261,7 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit* cockpit) m_renderer->SetTransform(matrix4x4d::Identity()); m_billboardMaterial->diffuse = attrs->billboardColor; m_renderer->DrawPointSprites(1, &attrs->billboardPos, SfxManager::additiveAlphaState, m_billboardMaterial.get(), attrs->billboardSize); - } - else + } else attrs->body->Render(m_renderer, this, attrs->viewCoords, attrs->viewTransform); } @@ -279,11 +273,12 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit* cockpit) // Render cockpit // XXX only here because it needs a frame for lighting calc // should really be in WorldView, immediately after camera draw - if(cockpit) + if (cockpit) cockpit->RenderCockpit(m_renderer, this, camFrame); } -void Camera::CalcShadows(const int lightNum, const Body *b, std::vector &shadowsOut) const { +void Camera::CalcShadows(const int lightNum, const Body *b, std::vector &shadowsOut) const +{ // Set up data for eclipses. All bodies are assumed to be spheres. const Body *lightBody = m_lightSources[lightNum].GetBody(); if (!lightBody) @@ -294,19 +289,21 @@ void Camera::CalcShadows(const int lightNum, const Body *b, std::vector const vector3d lightDir = bLightPos.Normalized(); double bRadius; - if (b->IsType(Object::TERRAINBODY)) bRadius = b->GetSystemBody()->GetRadius(); - else bRadius = b->GetPhysRadius(); + if (b->IsType(Object::TERRAINBODY)) + bRadius = b->GetSystemBody()->GetRadius(); + else + bRadius = b->GetPhysRadius(); // Look for eclipsing third bodies: for (const Body *b2 : Pi::game->GetSpace()->GetBodies()) { - if ( b2 == b || b2 == lightBody || !(b2->IsType(Object::PLANET) || b2->IsType(Object::STAR))) + if (b2 == b || b2 == lightBody || !(b2->IsType(Object::PLANET) || b2->IsType(Object::STAR))) continue; double b2Radius = b2->GetSystemBody()->GetRadius(); vector3d b2pos = b2->GetPositionRelTo(b); const double perpDist = lightDir.Dot(b2pos); - if ( perpDist <= 0 || perpDist > bLightPos.Length()) + if (perpDist <= 0 || perpDist > bLightPos.Length()) // b2 isn't between b and lightBody; no eclipse continue; @@ -320,12 +317,12 @@ void Camera::CalcShadows(const int lightNum, const Body *b, std::vector // disc of radius srad centred at projectedCentre-p. To determine the light intensity at p, we // then just need to estimate the proportion of the light disc being occulted. const double srad = b2Radius / bRadius; - const double lrad = (lightRadius/bLightPos.Length())*perpDist / bRadius; + const double lrad = (lightRadius / bLightPos.Length()) * perpDist / bRadius; if (srad / lrad < 0.01) { // any eclipse would have negligible effect - ignore continue; } - const vector3d projectedCentre = ( b2pos - perpDist*lightDir ) / bRadius; + const vector3d projectedCentre = (b2pos - perpDist * lightDir) / bRadius; if (projectedCentre.Length() < 1 + srad + lrad) { // some part of b is (partially) eclipsed Camera::Shadow shadow = { projectedCentre, static_cast(srad), static_cast(lrad) }; @@ -334,7 +331,8 @@ void Camera::CalcShadows(const int lightNum, const Body *b, std::vector } } -float discCovered(const float dist, const float rad) { +float discCovered(const float dist, const float rad) +{ // proportion of unit disc covered by a second disc of radius rad placed // dist from centre of first disc. // @@ -343,10 +341,10 @@ float discCovered(const float dist, const float rad) { // xs = normalised leftwards distance from centre of second disc to intersection. // d = vertical distance to an intersection point // The clampings handle the cases where one disc contains the other. - const float radsq = rad*rad; - const float xl = Clamp((dist*dist + 1.f - radsq) / (2.f*std::max(0.001f,dist)), -1.f, 1.f); - const float xs = Clamp((dist - xl)/std::max(0.001f,rad), -1.f, 1.f); - const float d = sqrt(std::max(0.f, 1.f - xl*xl)); + const float radsq = rad * rad; + const float xl = Clamp((dist * dist + 1.f - radsq) / (2.f * std::max(0.001f, dist)), -1.f, 1.f); + const float xs = Clamp((dist - xl) / std::max(0.001f, rad), -1.f, 1.f); + const float d = sqrt(std::max(0.f, 1.f - xl * xl)); const float th = Clamp(acosf(xl), 0.f, float(M_PI)); const float th2 = Clamp(acosf(xs), 0.f, float(M_PI)); @@ -355,23 +353,25 @@ float discCovered(const float dist, const float rad) { // covered area can be calculated as the sum of segments from the two // discs plus/minus some triangles, and it works out as follows: - return Clamp((th + radsq*th2 - dist*d)/float(M_PI), 0.f, 1.f); + return Clamp((th + radsq * th2 - dist * d) / float(M_PI), 0.f, 1.f); } static std::vector shadows; -float Camera::ShadowedIntensity(const int lightNum, const Body *b) const { +float Camera::ShadowedIntensity(const int lightNum, const Body *b) const +{ shadows.clear(); shadows.reserve(16); CalcShadows(lightNum, b, shadows); float product = 1.0; - for (std::vector::const_iterator it = shadows.begin(), itEnd = shadows.end(); it!=itEnd; ++it) + for (std::vector::const_iterator it = shadows.begin(), itEnd = shadows.end(); it != itEnd; ++it) product *= 1.0 - discCovered(it->centre.Length() / it->lrad, it->srad / it->lrad); return product; } // PrincipalShadows(b,n): returns the n biggest shadows on b in order of size -void Camera::PrincipalShadows(const Body *b, const int n, std::vector &shadowsOut) const { +void Camera::PrincipalShadows(const Body *b, const int n, std::vector &shadowsOut) const +{ shadows.clear(); shadows.reserve(16); for (size_t i = 0; i < 4 && i < m_lightSources.size(); i++) { diff --git a/src/Camera.h b/src/Camera.h index 9b5d59b6e..c95e8b554 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -4,17 +4,19 @@ #ifndef _CAMERA_H #define _CAMERA_H -#include "graphics/Frustum.h" -#include "graphics/Light.h" -#include "RefCounted.h" -#include "vector3.h" -#include "matrix4x4.h" #include "Background.h" #include "Body.h" +#include "RefCounted.h" +#include "graphics/Frustum.h" +#include "graphics/Light.h" +#include "matrix4x4.h" +#include "vector3.h" class Frame; class ShipCockpit; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class CameraContext : public RefCounted { public: @@ -22,11 +24,11 @@ public: CameraContext(float width, float height, float fovAng, float zNear, float zFar); ~CameraContext(); - float GetWidth() const { return m_width; } + float GetWidth() const { return m_width; } float GetHeight() const { return m_height; } float GetFovAng() const { return m_fovAng; } - float GetZNear() const { return m_zNear; } - float GetZFar() const { return m_zFar; } + float GetZNear() const { return m_zNear; } + float GetZFar() const { return m_zFar; } // frame to position the camera relative to void SetFrame(Frame *frame) { m_frame = frame; } @@ -45,7 +47,11 @@ public: void EndFrame(); // valid between BeginFrame and EndFrame - Frame *GetCamFrame() const { assert(m_camFrame); return m_camFrame; } + Frame *GetCamFrame() const + { + assert(m_camFrame); + return m_camFrame; + } // apply projection and modelview transforms to the renderer void ApplyDrawTransforms(Graphics::Renderer *r); @@ -66,7 +72,6 @@ private: Frame *m_camFrame; }; - class Camera { public: Camera(RefCountedPtr context, Graphics::Renderer *renderer); @@ -74,12 +79,14 @@ public: const CameraContext *GetContext() const { return m_context.Get(); } void Update(); - void Draw(const Body *excludeBody = nullptr, ShipCockpit* cockpit = nullptr); + void Draw(const Body *excludeBody = nullptr, ShipCockpit *cockpit = nullptr); // camera-specific light with attached source body class LightSource { public: - LightSource(const Body *b, Graphics::Light &light) : m_body(b), m_light(light) {} + LightSource(const Body *b, Graphics::Light &light) : + m_body(b), + m_light(light) {} const Body *GetBody() const { return m_body; } const Graphics::Light &GetLight() const { return m_light; } @@ -94,7 +101,7 @@ public: float srad; float lrad; - bool operator< (const Shadow& other) const { return srad/lrad < other.srad/other.lrad; } + bool operator<(const Shadow &other) const { return srad / lrad < other.srad / other.lrad; } }; void CalcShadows(const int lightNum, const Body *b, std::vector &shadowsOut) const; @@ -132,7 +139,8 @@ private: Color billboardColor; // for sorting. "should a be drawn before b?" - friend bool operator<(const BodyAttrs &a, const BodyAttrs &b) { + friend bool operator<(const BodyAttrs &a, const BodyAttrs &b) + { // both drawing last; distance order if (a.bodyFlags & Body::FLAG_DRAW_LAST && b.bodyFlags & Body::FLAG_DRAW_LAST) return a.camDist > b.camDist; diff --git a/src/CameraController.cpp b/src/CameraController.cpp index b3420eec2..6d752ef71 100644 --- a/src/CameraController.cpp +++ b/src/CameraController.cpp @@ -2,19 +2,19 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "CameraController.h" -#include "Ship.h" #include "AnimationCurves.h" -#include "Pi.h" #include "Game.h" #include "GameSaveError.h" #include "JsonUtils.h" #include "MathUtil.h" +#include "Pi.h" +#include "Ship.h" CameraController::CameraController(RefCountedPtr camera, const Ship *ship) : -m_camera(camera), -m_ship(ship), -m_pos(0.0), -m_orient(matrix3x3d::Identity()) + m_camera(camera), + m_ship(ship), + m_pos(0.0), + m_orient(matrix3x3d::Identity()) { } @@ -39,9 +39,8 @@ void CameraController::Update() } } - -InternalCameraController::InternalCameraController(RefCountedPtr camera, const Ship *ship) - : MoveableCameraController(camera, ship), +InternalCameraController::InternalCameraController(RefCountedPtr camera, const Ship *ship) : + MoveableCameraController(camera, ship), m_mode(MODE_FRONT), m_rotX(0), m_rotY(0), @@ -56,12 +55,9 @@ static bool FillCameraPosOrient(const SceneGraph::Model *m, const char *tag, vec matrix3x3d fixOrient(matrix3x3d::Identity()); const SceneGraph::MatrixTransform *mt = m->FindTagByName(tag); - if (!mt) - { + if (!mt) { fixOrient = fallbackOrient; - } - else - { + } else { // camera points are have +Z pointing out of the ship, X left, so we // have to rotate 180 about Y to get them to -Z forward, X right like // the rest of the ship. this is not a bug, but rather a convenience to @@ -113,7 +109,8 @@ void InternalCameraController::Update() CameraController::Update(); } -void InternalCameraController::getRots(double &rX, double &rY) { +void InternalCameraController::getRots(double &rX, double &rY) +{ rX = DEG2RAD(m_rotX); rY = DEG2RAD(m_rotY); } @@ -191,18 +188,18 @@ void InternalCameraController::LoadFromJson(const Json &jsonObj) try { Json internalCameraObj = jsonObj["internal"]; SetMode(internalCameraObj["mode"].get()); - } - catch (Json::type_error &) { + } catch (Json::type_error &) { throw SavedGameCorruptException(); } } ExternalCameraController::ExternalCameraController(RefCountedPtr camera, const Ship *ship) : -MoveableCameraController(camera, ship), -m_dist(200), m_distTo(m_dist), -m_rotX(0), -m_rotY(0), -m_extOrient(matrix3x3d::Identity()) + MoveableCameraController(camera, ship), + m_dist(200), + m_distTo(m_dist), + m_rotX(0), + m_rotY(0), + m_extOrient(matrix3x3d::Identity()) { } @@ -307,9 +304,10 @@ void ExternalCameraController::LoadFromJson(const Json &jsonObj) } SiderealCameraController::SiderealCameraController(RefCountedPtr camera, const Ship *ship) : -MoveableCameraController(camera, ship), -m_dist(200), m_distTo(m_dist), -m_sidOrient(matrix3x3d::Identity()) + MoveableCameraController(camera, ship), + m_dist(200), + m_distTo(m_dist), + m_sidOrient(matrix3x3d::Identity()) { } @@ -357,7 +355,7 @@ void SiderealCameraController::ZoomEvent(float amount) void SiderealCameraController::ZoomEventUpdate(float frameTime) { - AnimationCurves::Approach(m_dist, m_distTo, frameTime, 4.0, 50. / std::max(m_distTo, 1e-7)); // std::max() here just avoid dividing by 0. + AnimationCurves::Approach(m_dist, m_distTo, frameTime, 4.0, 50. / std::max(m_distTo, 1e-7)); // std::max() here just avoid dividing by 0. m_dist = std::max(GetShip()->GetClipRadius(), m_dist); } @@ -383,7 +381,7 @@ void SiderealCameraController::Update() { const Ship *ship = GetShip(); - m_sidOrient.Renormalize(); // lots of small rotations + m_sidOrient.Renormalize(); // lots of small rotations matrix3x3d shipOrient = ship->GetInterpOrientRelTo(Pi::game->GetSpace()->GetRootFrame()); SetPosition(shipOrient.Transpose() * m_sidOrient.VectorZ() * m_dist); @@ -417,10 +415,11 @@ void SiderealCameraController::LoadFromJson(const Json &jsonObj) } FlyByCameraController::FlyByCameraController(RefCountedPtr camera, const Ship *ship) : -MoveableCameraController(camera, ship), -m_dist(500), m_distTo(m_dist), -m_roll(0), -m_flybyOrient(matrix3x3d::Identity()) + MoveableCameraController(camera, ship), + m_dist(500), + m_distTo(m_dist), + m_roll(0), + m_flybyOrient(matrix3x3d::Identity()) { } @@ -444,7 +443,7 @@ void FlyByCameraController::ZoomEvent(float amount) void FlyByCameraController::ZoomEventUpdate(float frameTime) { - AnimationCurves::Approach(m_dist, m_distTo, frameTime, 4.0, 50. / std::max(m_distTo, 1e-7)); // std::max() here just avoid dividing by 0. + AnimationCurves::Approach(m_dist, m_distTo, frameTime, 4.0, 50. / std::max(m_distTo, 1e-7)); // std::max() here just avoid dividing by 0. m_dist = std::max(GetShip()->GetClipRadius(), m_dist); } diff --git a/src/CameraController.h b/src/CameraController.h index 241b9b60c..5d3bd7350 100644 --- a/src/CameraController.h +++ b/src/CameraController.h @@ -4,16 +4,15 @@ #ifndef CAMERACONTROLLER_H #define CAMERACONTROLLER_H -#include "vector3.h" -#include "matrix4x4.h" -#include "Lang.h" #include "Camera.h" #include "JsonFwd.h" +#include "Lang.h" +#include "matrix4x4.h" +#include "vector3.h" class Ship; -class CameraController -{ +class CameraController { public: enum Type { //can be used for serialization & identification INTERNAL, @@ -29,8 +28,8 @@ public: virtual Type GetType() const = 0; virtual const char *GetName() const { return ""; } - virtual void SaveToJson(Json &jsonObj) { } - virtual void LoadFromJson(const Json &jsonObj) { } + virtual void SaveToJson(Json &jsonObj) {} + virtual void LoadFromJson(const Json &jsonObj) {} virtual bool IsExternal() const { return false; } // camera position relative to the body @@ -56,23 +55,23 @@ class MoveableCameraController : public CameraController { public: MoveableCameraController(RefCountedPtr camera, const Ship *ship) : CameraController(camera, ship) {} - virtual void Reset() { } + virtual void Reset() {} - virtual void RollLeft(float frameTime) { } - virtual void RollRight(float frameTime) { } - virtual void RotateDown(float frameTime) { } - virtual void RotateLeft(float frameTime) { } - virtual void RotateRight(float frameTime) { } - virtual void RotateUp(float frameTime) { } + virtual void RollLeft(float frameTime) {} + virtual void RollRight(float frameTime) {} + virtual void RotateDown(float frameTime) {} + virtual void RotateLeft(float frameTime) {} + virtual void RotateRight(float frameTime) {} + virtual void RotateUp(float frameTime) {} /// Zooming with this method will interrupt any animation launched by ZoomEvent(). - virtual void ZoomIn(float frameTime) { } + virtual void ZoomIn(float frameTime) {} /// Zooming with this method will interrupt any animation launched by ZoomEvent(). - virtual void ZoomOut(float frameTime) { } + virtual void ZoomOut(float frameTime) {} /// Animated zoom trigger (on each event), primarily designed for mouse wheel. ///\param amount The zoom delta to add or substract (>0: zoom out, <0: zoom in), indirectly controling the zoom animation speed. - virtual void ZoomEvent(float amount) { } + virtual void ZoomEvent(float amount) {} /// Animated zoom update (on each frame), primarily designed for mouse wheel. - virtual void ZoomEventUpdate(float frameTime) { } + virtual void ZoomEventUpdate(float frameTime) {} }; class InternalCameraController : public MoveableCameraController { @@ -88,7 +87,7 @@ public: InternalCameraController(RefCountedPtr camera, const Ship *ship); virtual void Reset(); - virtual void Update(); + virtual void Update(); Type GetType() const { return INTERNAL; } const char *GetName() const { return m_name; } @@ -102,18 +101,24 @@ public: void RotateRight(float frameTime); void RotateUp(float frameTime); - void getRots(double &rotX, double &rotY); + void getRots(double &rotX, double &rotY); - private: +private: Mode m_mode; const char *m_name; - vector3d m_frontPos; matrix3x3d m_frontOrient; - vector3d m_rearPos; matrix3x3d m_rearOrient; - vector3d m_leftPos; matrix3x3d m_leftOrient; - vector3d m_rightPos; matrix3x3d m_rightOrient; - vector3d m_topPos; matrix3x3d m_topOrient; - vector3d m_bottomPos; matrix3x3d m_bottomOrient; + vector3d m_frontPos; + matrix3x3d m_frontOrient; + vector3d m_rearPos; + matrix3x3d m_rearOrient; + vector3d m_leftPos; + matrix3x3d m_leftOrient; + vector3d m_rightPos; + matrix3x3d m_rightOrient; + vector3d m_topPos; + matrix3x3d m_topOrient; + vector3d m_bottomPos; + matrix3x3d m_bottomOrient; double m_rotX; //vertical rot double m_rotY; //horizontal rot @@ -139,7 +144,8 @@ public: void ZoomEventUpdate(float frameTime); void Reset(); bool IsExternal() const { return true; } - void SetRotationAngles(double x, double y) { + void SetRotationAngles(double x, double y) + { m_rotX = x; m_rotY = y; } @@ -156,7 +162,6 @@ private: matrix3x3d m_extOrient; }; - // Much like external camera, but does not turn when the ship turns class SiderealCameraController : public MoveableCameraController { public: diff --git a/src/CargoBody.cpp b/src/CargoBody.cpp index dd6369914..70f7210dc 100644 --- a/src/CargoBody.cpp +++ b/src/CargoBody.cpp @@ -1,18 +1,18 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Ship.h" #include "CargoBody.h" +#include "EnumStrings.h" #include "Game.h" +#include "GameSaveError.h" +#include "LuaTable.h" #include "Pi.h" #include "Sfx.h" +#include "Ship.h" #include "Space.h" -#include "EnumStrings.h" -#include "LuaTable.h" #include "collider/collider.h" -#include "scenegraph/SceneGraph.h" #include "scenegraph/ModelSkin.h" -#include "GameSaveError.h" +#include "scenegraph/SceneGraph.h" void CargoBody::SaveToJson(Json &jsonObj, Space *space) { @@ -69,7 +69,8 @@ void CargoBody::Init() Properties().Set("type", cargoname); } -CargoBody::CargoBody(const LuaRef& cargo, float selfdestructTimer): m_cargo(cargo) +CargoBody::CargoBody(const LuaRef &cargo, float selfdestructTimer) : + m_cargo(cargo) { SetModel("cargo"); Init(); @@ -91,7 +92,7 @@ void CargoBody::TimeStepUpdate(const float timeStep) if (m_hasSelfdestruct) { m_selfdestructTimer -= timeStep; - if (m_selfdestructTimer <= 0){ + if (m_selfdestructTimer <= 0) { Pi::game->GetSpace()->KillBody(this); SfxManager::Add(this, TYPE_EXPLOSION); } @@ -99,9 +100,9 @@ void CargoBody::TimeStepUpdate(const float timeStep) DynamicBody::TimeStepUpdate(timeStep); } -bool CargoBody::OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) +bool CargoBody::OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) { - m_hitpoints -= kgDamage*0.001f; + m_hitpoints -= kgDamage * 0.001f; if (m_hitpoints < 0) { Pi::game->GetSpace()->KillBody(this); SfxManager::Add(this, TYPE_EXPLOSION); @@ -114,7 +115,7 @@ bool CargoBody::OnCollision(Object *b, Uint32 flags, double relVel) // ignore collision if its about to be scooped if (b->IsType(Object::SHIP)) { int cargoscoop_cap = 0; - static_cast(b)->Properties().Get("cargo_scoop_cap", cargoscoop_cap); + static_cast(b)->Properties().Get("cargo_scoop_cap", cargoscoop_cap); if (cargoscoop_cap > 0) return true; } diff --git a/src/CargoBody.h b/src/CargoBody.h index 097f7a297..b868fc9c2 100644 --- a/src/CargoBody.h +++ b/src/CargoBody.h @@ -4,26 +4,30 @@ #ifndef _CARGOBODY_H #define _CARGOBODY_H -#include "libs.h" #include "DynamicBody.h" #include "LuaRef.h" +#include "libs.h" -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} -class CargoBody: public DynamicBody { +class CargoBody : public DynamicBody { public: OBJDEF(CargoBody, DynamicBody, CARGOBODY); - CargoBody(const LuaRef& cargo, float selfdestructTimer=86400.0f); // default to 24 h lifetime + CargoBody(const LuaRef &cargo, float selfdestructTimer = 86400.0f); // default to 24 h lifetime CargoBody() {} LuaRef GetCargoType() const { return m_cargo; } virtual void SetLabel(const std::string &label) override; virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; virtual void TimeStepUpdate(const float timeStep) override; virtual bool OnCollision(Object *o, Uint32 flags, double relVel) override; - virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override; + virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) override; + protected: virtual void SaveToJson(Json &jsonObj, Space *space) override; virtual void LoadFromJson(const Json &jsonObj, Space *space) override; + private: void Init(); LuaRef m_cargo; diff --git a/src/CityOnPlanet.cpp b/src/CityOnPlanet.cpp index da57e5413..f25249bd1 100644 --- a/src/CityOnPlanet.cpp +++ b/src/CityOnPlanet.cpp @@ -1,7 +1,6 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "CityOnPlanet.h" #include "FileSystem.h" #include "Frame.h" @@ -13,21 +12,26 @@ #include "graphics/Frustum.h" #include "graphics/Graphics.h" #include "graphics/Stats.h" +#include "libs.h" #include "scenegraph/Model.h" -#include "scenegraph/SceneGraph.h" #include "scenegraph/ModelSkin.h" +#include "scenegraph/SceneGraph.h" #include static const unsigned int DEFAULT_NUM_BUILDINGS = 1000; -static const double START_SEG_SIZE = CITY_ON_PLANET_RADIUS; -static const double START_SEG_SIZE_NO_ATMO = CITY_ON_PLANET_RADIUS / 5.0f; +static const double START_SEG_SIZE = CITY_ON_PLANET_RADIUS; +static const double START_SEG_SIZE_NO_ATMO = CITY_ON_PLANET_RADIUS / 5.0f; using SceneGraph::Model; CityOnPlanet::citybuildinglist_t CityOnPlanet::s_buildingList = -{ - "city_building", 800, 2000, 0, 0, -}; + { + "city_building", + 800, + 2000, + 0, + 0, + }; CityOnPlanet::cityflavourdef_t CityOnPlanet::cityflavour[CITYFLAVOURS]; @@ -36,30 +40,31 @@ void CityOnPlanet::AddStaticGeomsToCollisionSpace() // reset data structures m_enabledBuildings.clear(); m_buildingCounts.resize(s_buildingList.numBuildings); - for(Uint32 i=0; iAddStaticGeom(m_buildings[i].geom); @@ -76,7 +81,7 @@ void CityOnPlanet::AddStaticGeomsToCollisionSpace() void CityOnPlanet::RemoveStaticGeomsFromCollisionSpace() { m_enabledBuildings.clear(); - for (unsigned int i=0; iRemoveStaticGeom(m_buildings[i].geom); } } @@ -90,9 +95,9 @@ void CityOnPlanet::EnumerateNewBuildings(std::set &filenames) for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, fullpath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { const std::string &name = files.Current().GetName(); if (ends_with_ci(name, ".model")) { - filenames.insert(name.substr(0, name.length()-6)); + filenames.insert(name.substr(0, name.length() - 6)); } else if (ends_with_ci(name, ".sgm")) { - filenames.insert(name.substr(0, name.length()-4)); + filenames.insert(name.substr(0, name.length() - 4)); } } } @@ -100,14 +105,13 @@ void CityOnPlanet::EnumerateNewBuildings(std::set &filenames) //static void CityOnPlanet::LookupBuildingListModels(citybuildinglist_t *list) { - std::vector models; + std::vector models; //get test newmodels - to be replaced with building set definitions { std::set filenames; // set so we get unique names EnumerateNewBuildings(filenames); - for(auto it = filenames.begin(), itEnd = filenames.end(); it != itEnd; ++it) - { + for (auto it = filenames.begin(), itEnd = filenames.end(); it != itEnd; ++it) { // find/load the model Model *model = Pi::modelCache->FindModel(*it); @@ -129,7 +133,7 @@ void CityOnPlanet::LookupBuildingListModels(citybuildinglist_t *list) const Aabb &aabb = list->buildings[i].collMesh->GetAabb(); const double maxx = std::max(fabs(aabb.max.x), fabs(aabb.min.x)); const double maxy = std::max(fabs(aabb.max.z), fabs(aabb.min.z)); - list->buildings[i].xzradius = sqrt(maxx*maxx + maxy*maxy); + list->buildings[i].xzradius = sqrt(maxx * maxx + maxy * maxy); Output(" - %s: %f\n", (*m)->GetName().c_str(), list->buildings[i].xzradius); } Output("End of buildings.\n"); @@ -147,11 +151,12 @@ void CityOnPlanet::Uninit() } // Need a reliable way to sort the models rather than using their address in memory we use their name which should be unique. -bool setcomp (SceneGraph::Model *mlhs, SceneGraph::Model *mrhs) {return mlhs->GetName()GetName();} -bool(*fn_pt)(SceneGraph::Model *mlhs, SceneGraph::Model *mrhs) = setcomp; +bool setcomp(SceneGraph::Model *mlhs, SceneGraph::Model *mrhs) { return mlhs->GetName() < mrhs->GetName(); } +bool (*fn_pt)(SceneGraph::Model *mlhs, SceneGraph::Model *mrhs) = setcomp; struct ModelNameComparator { - bool operator()(SceneGraph::Model* lhs, SceneGraph::Model* rhs) { + bool operator()(SceneGraph::Model *lhs, SceneGraph::Model *rhs) + { return lhs->GetName() < rhs->GetName(); } }; @@ -162,31 +167,31 @@ void CityOnPlanet::SetCityModelPatterns(const SystemPath &path) Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED }; Random rand(_init, 5); - typedef std::set ModelSet; + typedef std::set ModelSet; typedef ModelSet::iterator TSetIter; ModelSet modelSet; { - for (unsigned int j=0; j < s_buildingList.numBuildings; j++) { + for (unsigned int j = 0; j < s_buildingList.numBuildings; j++) { SceneGraph::Model *m = s_buildingList.buildings[j].resolvedModel; modelSet.insert(m); } } SceneGraph::ModelSkin skin; - for (TSetIter it=modelSet.begin(), itEnd=modelSet.end(); it!=itEnd; ++it) { + for (TSetIter it = modelSet.begin(), itEnd = modelSet.end(); it != itEnd; ++it) { SceneGraph::Model *m = (*it); if (!m->SupportsPatterns()) continue; skin.SetRandomColors(rand); skin.Apply(m); - if(m->SupportsPatterns()) - m->SetPattern(rand.Int32(0, m->GetNumPatterns()-1)); + if (m->SupportsPatterns()) + m->SetPattern(rand.Int32(0, m->GetNumPatterns() - 1)); } } CityOnPlanet::~CityOnPlanet() { // frame may be null (already removed from - for (unsigned int i=0; iRemoveStaticGeom(m_buildings[i].geom); delete m_buildings[i].geom; } @@ -206,26 +211,23 @@ CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, const Uint32 s const matrix4x4d &m = station->GetOrient(); const vector3d p = station->GetPosition(); - const vector3d mx = m*vector3d(1,0,0); - const vector3d mz = m*vector3d(0,0,1); + const vector3d mx = m * vector3d(1, 0, 0); + const vector3d mz = m * vector3d(0, 0, 1); Random rand; rand.seed(seed); - + int population = planet->GetSystemBody()->GetPopulation(); int cityradius; - if (planet->GetSystemBody()->HasAtmosphere()) - { + if (planet->GetSystemBody()->HasAtmosphere()) { population *= 1000; cityradius = (population < 200) ? 200 : ((population > START_SEG_SIZE) ? START_SEG_SIZE : population); - } - else - { + } else { population *= 100; cityradius = (population < 250) ? 250 : ((population > START_SEG_SIZE_NO_ATMO) ? START_SEG_SIZE_NO_ATMO : population); } - + citybuildinglist_t *buildings = &s_buildingList; vector3d cent = p; const int cellsize_i = 80; @@ -235,8 +237,8 @@ CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, const Uint32 s static const int gmid = (cityradius / cellsize_i); static const int gsize = gmid * 2; - assert((START_SEG_SIZE/cellsize_i)<100); - assert((START_SEG_SIZE_NO_ATMO/cellsize_i)<100); + assert((START_SEG_SIZE / cellsize_i) < 100); + assert((START_SEG_SIZE_NO_ATMO / cellsize_i) < 100); uint8_t cellgrid[200][200]; std::memset(cellgrid, 0, sizeof(cellgrid)); @@ -247,10 +249,8 @@ CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, const Uint32 s const int z2 = ceil(aabb.max.z / cellsize); // Clear the cells where the station is - for (int x = 0; x <= gsize; x++) - { - for (int z = 0; z <= gsize; z++) - { + for (int x = 0; x <= gsize; x++) { + for (int z = 0; z <= gsize; z++) { const int zz = z - gmid; const int xx = x - gmid; if (zz > z1 && zz < z2 && xx > x1 && xx < x2) @@ -264,54 +264,50 @@ CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, const Uint32 s orientcalc[1] = m * matrix4x4d::RotateYMatrix(M_PI * 0.5 * 1); orientcalc[2] = m * matrix4x4d::RotateYMatrix(M_PI * 0.5 * 2); orientcalc[3] = m * matrix4x4d::RotateYMatrix(M_PI * 0.5 * 3); - - const double maxdist = pow(gmid+0.333, 2); - for (int x = 0; x <= gsize; x++) - { - const double distx = pow((x - gmid),2); - for (int z = 0; z <= gsize; z++) - { - if (cellgrid[x][z] > 0) - { + + const double maxdist = pow(gmid + 0.333, 2); + for (int x = 0; x <= gsize; x++) { + const double distx = pow((x - gmid), 2); + for (int z = 0; z <= gsize; z++) { + if (cellgrid[x][z] > 0) { // This cell has been allocated for something already continue; } - const double distz = pow((z - gmid),2); + const double distz = pow((z - gmid), 2); if ((distz + distx) > maxdist) continue; // fewer and fewer buildings the further from center you get - if ((distx + distz)*(1.0 / maxdist) > rand.Double()) + if ((distx + distz) * (1.0 / maxdist) > rand.Double()) continue; - cent = p + mz*((z - gmid) * cellsize) + mx* ((x - gmid) * cellsize); + cent = p + mz * ((z - gmid) * cellsize) + mx * ((x - gmid) * cellsize); cent = cent.Normalized(); - + const double height = planet->GetTerrainHeight(cent); if ((height - bodyradius) < 0) // don't position below sealevel continue; - + cent = cent * height; // quickly get a random building const citybuilding_t &bt = buildings->buildings[rand.Int32(buildings->numBuildings)]; - const CollMesh* cmesh = bt.collMesh.Get(); // collision mesh - + const CollMesh *cmesh = bt.collMesh.Get(); // collision mesh + // rotate the building to face a random direction const int32_t orient = rand.Int32(4); Geom *geom = new Geom(cmesh->GetGeomTree(), orientcalc[orient], cent, this); - + // add it to the list of buildings to render m_buildings.push_back({ bt.instIndex, float(cmesh->GetRadius()), orient, cent, geom }); } } Aabb buildAABB; - for (std::vector::const_iterator iter=m_buildings.begin(), itEND=m_buildings.end(); iter != itEND; ++iter) - { + for (std::vector::const_iterator iter = m_buildings.begin(), itEND = m_buildings.end(); iter != itEND; ++iter) { buildAABB.Update((*iter).pos - p); } - m_realCentre = buildAABB.min + ((buildAABB.max - buildAABB.min)*0.5); + m_realCentre = buildAABB.min + ((buildAABB.max - buildAABB.min) * 0.5); m_clipRadius = buildAABB.GetRadius(); AddStaticGeomsToCollisionSpace(); } @@ -336,19 +332,19 @@ void CityOnPlanet::Render(Graphics::Renderer *r, const Graphics::Frustum &frustu } rot[0] = viewTransform * rot[0]; - for (int i=1; i<4; i++) { - rot[i] = rot[0] * matrix4x4d::RotateYMatrix(M_PI*0.5*double(i)); + for (int i = 1; i < 4; i++) { + rot[i] = rot[0] * matrix4x4d::RotateYMatrix(M_PI * 0.5 * double(i)); } - for (int i=0; i<4; i++) { - for (int e=0; e<16; e++) { + for (int i = 0; i < 4; i++) { + for (int e = 0; e < 16; e++) { rotf[i][e] = float(rot[i][e]); } } // update any idle animations - for(Uint32 i=0; iSetProgress(fmod(pAnim->GetProgress() + (Pi::game->GetTimeStep() / pAnim->GetDuration()), 1.0)); pAnim->Interpolate(); } @@ -356,16 +352,15 @@ void CityOnPlanet::Render(Graphics::Renderer *r, const Graphics::Frustum &frustu Uint32 uCount = 0; std::vector instCount; - std::vector< std::vector > transform; + std::vector> transform; instCount.resize(s_buildingList.numBuildings); transform.resize(s_buildingList.numBuildings); memset(&instCount[0], 0, sizeof(Uint32) * s_buildingList.numBuildings); - for(Uint32 i=0; i::const_iterator iter=m_enabledBuildings.begin(), itEND=m_enabledBuildings.end(); iter != itEND; ++iter) - { + for (std::vector::const_iterator iter = m_enabledBuildings.begin(), itEND = m_enabledBuildings.end(); iter != itEND; ++iter) { const vector3d pos = viewTransform * (*iter).pos; const vector3f posf(pos); if (!frustum.TestPoint(pos, (*iter).clipRadius)) @@ -376,14 +371,14 @@ void CityOnPlanet::Render(Graphics::Renderer *r, const Graphics::Frustum &frustu // increment the instance count and store the transform instCount[(*iter).instIndex]++; - transform[(*iter).instIndex].push_back( _rot ); + transform[(*iter).instIndex].push_back(_rot); ++uCount; } // render the building models using instancing - for(Uint32 i=0; iRender(transform[i]); } diff --git a/src/CityOnPlanet.h b/src/CityOnPlanet.h index 235ef7853..a7cfe38d9 100644 --- a/src/CityOnPlanet.h +++ b/src/CityOnPlanet.h @@ -4,22 +4,28 @@ #ifndef _CITYONPLANET_H #define _CITYONPLANET_H -#include "libs.h" -#include "Random.h" -#include "Object.h" #include "CollMesh.h" +#include "Object.h" +#include "Random.h" #include "collider/Geom.h" #include "galaxy/StarSystem.h" +#include "libs.h" class Planet; class SpaceStation; class Frame; -namespace Graphics { class Renderer; class Frustum; } -namespace SceneGraph { class Model; class Animation; } +namespace Graphics { + class Renderer; + class Frustum; +} // namespace Graphics +namespace SceneGraph { + class Model; + class Animation; +} // namespace SceneGraph #define CITY_ON_PLANET_RADIUS 5000.0 -class CityOnPlanet: public Object { +class CityOnPlanet : public Object { public: OBJDEF(CityOnPlanet, Object, CITYONPLANET); CityOnPlanet(Planet *planet, SpaceStation *station, const Uint32 seed); @@ -30,6 +36,7 @@ public: static void Init(); static void Uninit(); static void SetCityModelPatterns(const SystemPath &path); + private: void AddStaticGeomsToCollisionSpace(); void RemoveStaticGeomsFromCollisionSpace(); diff --git a/src/CollMesh.h b/src/CollMesh.h index 00f5e2478..844d84f97 100644 --- a/src/CollMesh.h +++ b/src/CollMesh.h @@ -3,20 +3,21 @@ #ifndef _COLLMESH_H #define _COLLMESH_H -#include "RefCounted.h" #include "Aabb.h" -#include "collider/GeomTree.h" +#include "RefCounted.h" #include "Serializer.h" +#include "collider/GeomTree.h" //This simply stores the collision GeomTrees //and AABB. class CollMesh : public RefCounted { public: - CollMesh() - : m_geomTree(0) - , m_totalTris(0) - { } - virtual ~CollMesh() { + CollMesh() : + m_geomTree(0), + m_totalTris(0) + {} + virtual ~CollMesh() + { for (auto it = m_dynGeomTrees.begin(); it != m_dynGeomTrees.end(); ++it) delete *it; delete m_geomTree; @@ -24,19 +25,22 @@ public: inline Aabb &GetAabb() { return m_aabb; } inline double GetRadius() const { return m_aabb.GetRadius(); } - inline void SetRadius(double v) { + inline void SetRadius(double v) + { //0 radius = trouble m_aabb.radius = std::max(v, 0.1); } inline GeomTree *GetGeomTree() const { return m_geomTree; } - inline void SetGeomTree(GeomTree *t) { + inline void SetGeomTree(GeomTree *t) + { assert(t); m_geomTree = t; } - inline const std::vector &GetDynGeomTrees() const { return m_dynGeomTrees; } - inline void AddDynGeomTree(GeomTree *t) { + inline const std::vector &GetDynGeomTrees() const { return m_dynGeomTrees; } + inline void AddDynGeomTree(GeomTree *t) + { assert(t); m_dynGeomTrees.push_back(t); } @@ -51,7 +55,7 @@ public: protected: Aabb m_aabb; GeomTree *m_geomTree; - std::vector m_dynGeomTrees; + std::vector m_dynGeomTrees; unsigned int m_totalTris; }; diff --git a/src/Color.cpp b/src/Color.cpp index 5258770c0..dc9db326e 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -5,33 +5,33 @@ #include "LuaUtils.h" #include -const Color4f Color4f::BLACK = Color4f(0.0f,0.0f,0.0f,1.0f); -const Color4f Color4f::WHITE = Color4f(1.0f,1.0f,1.0f,1.0f); -const Color4f Color4f::RED = Color4f(1.0f,0.0f,0.0f,1.0f); -const Color4f Color4f::GREEN = Color4f(0.0f,1.0f,0.0f,1.0f); -const Color4f Color4f::BLUE = Color4f(0.0f,0.0f,1.0f,1.0f); -const Color4f Color4f::YELLOW = Color4f(1.0f,1.0f,0.0f,1.0f); -const Color4f Color4f::GRAY = Color4f(0.5f,0.5f,0.5f,1.f); +const Color4f Color4f::BLACK = Color4f(0.0f, 0.0f, 0.0f, 1.0f); +const Color4f Color4f::WHITE = Color4f(1.0f, 1.0f, 1.0f, 1.0f); +const Color4f Color4f::RED = Color4f(1.0f, 0.0f, 0.0f, 1.0f); +const Color4f Color4f::GREEN = Color4f(0.0f, 1.0f, 0.0f, 1.0f); +const Color4f Color4f::BLUE = Color4f(0.0f, 0.0f, 1.0f, 1.0f); +const Color4f Color4f::YELLOW = Color4f(1.0f, 1.0f, 0.0f, 1.0f); +const Color4f Color4f::GRAY = Color4f(0.5f, 0.5f, 0.5f, 1.f); const Color4f Color4f::STEELBLUE = Color4f(0.27f, 0.51f, 0.71f, 1.f); const Color4f Color4f::BLANK = Color4f(0.0f, 0.0f, 0.0f, 0.0f); -const Color4ub Color::BLACK = Color(0, 0, 0, 255); -const Color4ub Color::WHITE = Color(255, 255, 255, 255); -const Color4ub Color::RED = Color(255, 0, 0, 255); -const Color4ub Color::GREEN = Color(0, 255, 0, 255); -const Color4ub Color::BLUE = Color(0, 0, 255, 255); -const Color4ub Color::YELLOW = Color(255, 255, 0, 255); -const Color4ub Color::GRAY = Color(128,128,128,255); +const Color4ub Color::BLACK = Color(0, 0, 0, 255); +const Color4ub Color::WHITE = Color(255, 255, 255, 255); +const Color4ub Color::RED = Color(255, 0, 0, 255); +const Color4ub Color::GREEN = Color(0, 255, 0, 255); +const Color4ub Color::BLUE = Color(0, 0, 255, 255); +const Color4ub Color::YELLOW = Color(255, 255, 0, 255); +const Color4ub Color::GRAY = Color(128, 128, 128, 255); const Color4ub Color::STEELBLUE = Color(68, 130, 181, 255); const Color4ub Color::BLANK = Color(0, 0, 0, 0); -const Color4ub Color::PINK = Color(252, 15, 192, 255); // debug pink +const Color4ub Color::PINK = Color(252, 15, 192, 255); // debug pink -const Color3ub Color3ub::BLACK = Color3ub(0, 0, 0); -const Color3ub Color3ub::WHITE = Color3ub(255, 255, 255); -const Color3ub Color3ub::RED = Color3ub(255, 0, 0); -const Color3ub Color3ub::GREEN = Color3ub(0, 255, 0); -const Color3ub Color3ub::BLUE = Color3ub(0, 0, 255); -const Color3ub Color3ub::YELLOW = Color3ub(255, 255, 0); +const Color3ub Color3ub::BLACK = Color3ub(0, 0, 0); +const Color3ub Color3ub::WHITE = Color3ub(255, 255, 255); +const Color3ub Color3ub::RED = Color3ub(255, 0, 0); +const Color3ub Color3ub::GREEN = Color3ub(0, 255, 0); +const Color3ub Color3ub::BLUE = Color3ub(0, 0, 255); +const Color3ub Color3ub::YELLOW = Color3ub(255, 255, 0); const Color3ub Color3ub::STEELBLUE = Color3ub(68, 130, 181); const Color3ub Color3ub::BLANK = Color3ub(0, 0, 0); @@ -80,10 +80,10 @@ Color4f Color4f::FromLuaTable(lua_State *l, int idx) void Color4ub::ToLuaTable(lua_State *l) { lua_newtable(l); - pi_lua_settable(l, "r", 255.0/r); - pi_lua_settable(l, "g", 255.0/g); - pi_lua_settable(l, "b", 255.0/b); - pi_lua_settable(l, "a", 255.0/a); + pi_lua_settable(l, "r", 255.0 / r); + pi_lua_settable(l, "g", 255.0 / g); + pi_lua_settable(l, "b", 255.0 / b); + pi_lua_settable(l, "a", 255.0 / a); } Color4ub Color4ub::FromLuaTable(lua_State *l, int idx) @@ -101,11 +101,11 @@ Color4ub Color4ub::FromLuaTable(lua_State *l, int idx) LUA_DEBUG_END(l, 0); - return Color4ub(r*255, g*255, b*255, a*255); + return Color4ub(r * 255, g * 255, b * 255, a * 255); } Uint8 Color4ub::GetLuminance() const { // these weights are those used for the JPEG luma channel - return (r*299 + g*587 + b*114) / 1000; + return (r * 299 + g * 587 + b * 114) / 1000; } diff --git a/src/Color.h b/src/Color.h index 44d2a76c2..69a8f14fd 100644 --- a/src/Color.h +++ b/src/Color.h @@ -9,15 +9,38 @@ struct lua_State; struct Color4f { - float r,g,b,a; - Color4f() : r(0.f), g(0.f), b(0.f), a(1.f) {} - Color4f(float v_) : r(v_), g(v_), b(v_), a(v_) { } - Color4f(float r_, float g_, float b_): r(r_), g(g_), b(b_), a(1.f) {} - Color4f(float r_, float g_, float b_, float a_): r(r_), g(g_), b(b_), a(a_) {} + float r, g, b, a; + Color4f() : + r(0.f), + g(0.f), + b(0.f), + a(1.f) {} + Color4f(float v_) : + r(v_), + g(v_), + b(v_), + a(v_) {} + Color4f(float r_, float g_, float b_) : + r(r_), + g(g_), + b(b_), + a(1.f) {} + Color4f(float r_, float g_, float b_, float a_) : + r(r_), + g(g_), + b(b_), + a(a_) {} operator float *() { return &r; } operator const float *() const { return &r; } - Color4f &operator*=(const float v) { r*=v; g*=v; b*=v; a*=v; return *this; } - friend Color4f operator*(const Color4f &c, const float v) { return Color4f(c.r*v, c.g*v, c.b*v, c.a*v); } + Color4f &operator*=(const float v) + { + r *= v; + g *= v; + b *= v; + a *= v; + return *this; + } + friend Color4f operator*(const Color4f &c, const float v) { return Color4f(c.r * v, c.g * v, c.b * v, c.a * v); } void ToLuaTable(lua_State *l); static Color4f FromLuaTable(lua_State *l, int idx); @@ -37,31 +60,65 @@ struct Color4f { namespace { static const float s_inv255 = 1.0f / 255.0f; - #define INV255(n) (Uint8(float(n) * s_inv255)) -} +#define INV255(n) (Uint8(float(n) * s_inv255)) +} // namespace struct Color4ub { Uint8 r, g, b, a; - Color4ub(): r(0), g(0), b(0), a(255) {} - Color4ub(Uint8 r_, Uint8 g_, Uint8 b_): r(r_), g(g_), b(b_), a(255) {} - Color4ub(Uint8 r_, Uint8 g_, Uint8 b_, Uint8 a_): r(r_), g(g_), b(b_), a(a_) {} - Color4ub(const Color4f &c): r(Uint8(c.r*255.f)), g(Uint8(c.g*255.f)), b(Uint8(c.b*255.f)), a(Uint8(c.a*255.f)) {} - Color4ub(const Uint32 rgba): r((rgba >> 24) & 0xff), g((rgba >> 16) & 0xff), b((rgba >> 8) & 0xff), a(rgba & 0xff) {} + Color4ub() : + r(0), + g(0), + b(0), + a(255) {} + Color4ub(Uint8 r_, Uint8 g_, Uint8 b_) : + r(r_), + g(g_), + b(b_), + a(255) {} + Color4ub(Uint8 r_, Uint8 g_, Uint8 b_, Uint8 a_) : + r(r_), + g(g_), + b(b_), + a(a_) {} + Color4ub(const Color4f &c) : + r(Uint8(c.r * 255.f)), + g(Uint8(c.g * 255.f)), + b(Uint8(c.b * 255.f)), + a(Uint8(c.a * 255.f)) {} + Color4ub(const Uint32 rgba) : + r((rgba >> 24) & 0xff), + g((rgba >> 16) & 0xff), + b((rgba >> 8) & 0xff), + a(rgba & 0xff) {} - operator unsigned char*() { return &r; } - operator const unsigned char*() const { return &r; } - Color4ub operator+(const Color4ub &c) const { return Color4ub(c.r+r, c.g+g, c.b+b, c.a+a); } - Color4ub &operator*=(const float f) { r=Uint8(r*f); g=Uint8(g*f); b=Uint8(b*f); a=Uint8(a*f); return *this; } - Color4ub &operator*=(const Color4ub &c) { r*=INV255(c.r); g*=INV255(c.g); b*=INV255(c.b); a*=INV255(c.a); return *this; } - Color4ub operator*(const float f) const { return Color4ub(Uint8(f*r), Uint8(f*g), Uint8(f*b), Uint8(f*a)); } - Color4ub operator*(const Color4ub &c) const { return Color4ub(INV255(c.r)*r, INV255(c.g)*g, INV255(c.b)*b, INV255(c.a)*a); } - Color4ub operator/(const float f) const { return Color4ub(Uint8(r/f), Uint8(g/f), Uint8(b/f), Uint8(a/f)); } + operator unsigned char *() { return &r; } + operator const unsigned char *() const { return &r; } + Color4ub operator+(const Color4ub &c) const { return Color4ub(c.r + r, c.g + g, c.b + b, c.a + a); } + Color4ub &operator*=(const float f) + { + r = Uint8(r * f); + g = Uint8(g * f); + b = Uint8(b * f); + a = Uint8(a * f); + return *this; + } + Color4ub &operator*=(const Color4ub &c) + { + r *= INV255(c.r); + g *= INV255(c.g); + b *= INV255(c.b); + a *= INV255(c.a); + return *this; + } + Color4ub operator*(const float f) const { return Color4ub(Uint8(f * r), Uint8(f * g), Uint8(f * b), Uint8(f * a)); } + Color4ub operator*(const Color4ub &c) const { return Color4ub(INV255(c.r) * r, INV255(c.g) * g, INV255(c.b) * b, INV255(c.a) * a); } + Color4ub operator/(const float f) const { return Color4ub(Uint8(r / f), Uint8(g / f), Uint8(b / f), Uint8(a / f)); } - friend bool operator==(const Color4ub& aIn, const Color4ub& bIn) { return ((aIn.r == bIn.r) && (aIn.g == bIn.g) && (aIn.b == bIn.b) && (aIn.a == bIn.a)); } - friend bool operator!=(const Color4ub& aIn, const Color4ub& bIn) { return ((aIn.r != bIn.r) || (aIn.g != bIn.g) || (aIn.b != bIn.b) || (aIn.a != bIn.a)); } + friend bool operator==(const Color4ub &aIn, const Color4ub &bIn) { return ((aIn.r == bIn.r) && (aIn.g == bIn.g) && (aIn.b == bIn.b) && (aIn.a == bIn.a)); } + friend bool operator!=(const Color4ub &aIn, const Color4ub &bIn) { return ((aIn.r != bIn.r) || (aIn.g != bIn.g) || (aIn.b != bIn.b) || (aIn.a != bIn.a)); } - Color4f ToColor4f() const { return Color4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f); } + Color4f ToColor4f() const { return Color4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); } void ToLuaTable(lua_State *l); static Color4ub FromLuaTable(lua_State *l, int idx); @@ -82,20 +139,38 @@ struct Color4ub { struct Color3ub { Uint8 r, g, b; - Color3ub(): r(0), g(0), b(0) {} - Color3ub(Uint8 v_): r(v_), g(v_), b(v_) {} - Color3ub(Uint8 r_, Uint8 g_, Uint8 b_): r(r_), g(g_), b(b_) {} - Color3ub(const Color4f &c): r(Uint8(c.r*255.f)), g(Uint8(c.g*255.f)), b(Uint8(c.b*255.f)) {} + Color3ub() : + r(0), + g(0), + b(0) {} + Color3ub(Uint8 v_) : + r(v_), + g(v_), + b(v_) {} + Color3ub(Uint8 r_, Uint8 g_, Uint8 b_) : + r(r_), + g(g_), + b(b_) {} + Color3ub(const Color4f &c) : + r(Uint8(c.r * 255.f)), + g(Uint8(c.g * 255.f)), + b(Uint8(c.b * 255.f)) {} - operator unsigned char*() { return &r; } - operator const unsigned char*() const { return &r; } - Color3ub &operator*=(const Color3ub &c) { r*=INV255(c.r); g*=INV255(c.g); b*=INV255(c.b); return *this; } - Color3ub operator+(const Color3ub &c) const { return Color3ub(c.r+r, c.g+g, c.b+b); } - Color3ub operator*(const float f) const { return Color3ub(Uint8(f*r), Uint8(f*g), Uint8(f*b)); } - Color3ub operator*(const Color3ub &c) const { return Color3ub(INV255(c.r)*r, INV255(c.g)*g, INV255(c.b)*b); } - Color3ub operator/(const float f) const { return Color3ub(Uint8(r/f), Uint8(g/f), Uint8(b/f)); } + operator unsigned char *() { return &r; } + operator const unsigned char *() const { return &r; } + Color3ub &operator*=(const Color3ub &c) + { + r *= INV255(c.r); + g *= INV255(c.g); + b *= INV255(c.b); + return *this; + } + Color3ub operator+(const Color3ub &c) const { return Color3ub(c.r + r, c.g + g, c.b + b); } + Color3ub operator*(const float f) const { return Color3ub(Uint8(f * r), Uint8(f * g), Uint8(f * b)); } + Color3ub operator*(const Color3ub &c) const { return Color3ub(INV255(c.r) * r, INV255(c.g) * g, INV255(c.b) * b); } + Color3ub operator/(const float f) const { return Color3ub(Uint8(r / f), Uint8(g / f), Uint8(b / f)); } - Color4f ToColor4f() const { return Color4f(r/255.0f, g/255.0f, b/255.0f); } + Color4f ToColor4f() const { return Color4f(r / 255.0f, g / 255.0f, b / 255.0f); } static const Color3ub BLACK; static const Color3ub WHITE; diff --git a/src/Cutscene.h b/src/Cutscene.h index bc8c611c5..2a574d87d 100644 --- a/src/Cutscene.h +++ b/src/Cutscene.h @@ -4,18 +4,20 @@ #ifndef _CUTSCENE_H #define _CUTSCENE_H -#include "libs.h" -#include "graphics/Renderer.h" #include "graphics/Light.h" +#include "graphics/Renderer.h" +#include "libs.h" -namespace SceneGraph { class Model; } +namespace SceneGraph { + class Model; +} class Shields; class Cutscene { public: - Cutscene(Graphics::Renderer *r, int width, int height) - : m_aspectRatio(float(width)/float(height)) - , m_renderer(r) + Cutscene(Graphics::Renderer *r, int width, int height) : + m_aspectRatio(float(width) / float(height)), + m_renderer(r) { } virtual ~Cutscene() {} diff --git a/src/DateTime.cpp b/src/DateTime.cpp index 6de8dfed2..e7b1e4f87 100644 --- a/src/DateTime.cpp +++ b/src/DateTime.cpp @@ -1,18 +1,19 @@ #include "DateTime.h" +#include "libs.h" +#include +#include +#include #include #include -#include -#include -#include -#include "libs.h" static char month_days[2][12] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; -static bool is_leap_year(int year) { +static bool is_leap_year(int year) +{ return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } @@ -35,7 +36,8 @@ enum { // // divmod_euclid provides a division operation that always gives a non-negative remainder template -static std::pair divmod_euclid(const T dividend, const T divisor) { +static std::pair divmod_euclid(const T dividend, const T divisor) +{ T quot = dividend / divisor, rem = dividend % divisor; if (rem < 0) { if (divisor > 0) { @@ -50,11 +52,13 @@ static std::pair divmod_euclid(const T dividend, const T divisor) { } template -static std::pair divmod_trunc(const T a, const T b) { +static std::pair divmod_trunc(const T a, const T b) +{ return std::make_pair(a / b, a % b); } -Time::DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int microsecond) { +Time::DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int microsecond) +{ // minimum year is just a sanity check; the code should work for earlier years assert(year >= 1600 && year <= APPROX_MAX_YEAR); assert(month >= 1 && month <= 12); @@ -66,35 +70,31 @@ Time::DateTime::DateTime(int year, int month, int day, int hour, int minute, int const int yoffset = (year - 2001); // C99 and C++11 specify that integer division truncates toward zero - const int nleap = (yoffset >= 0) - ? (yoffset/400 - yoffset/100 + yoffset/4) - : ((yoffset-399)/400 - (yoffset-99)/100 + (yoffset-3)/4); + const int nleap = (yoffset >= 0) ? (yoffset / 400 - yoffset / 100 + yoffset / 4) : ((yoffset - 399) / 400 - (yoffset - 99) / 100 + (yoffset - 3) / 4); - int days = 365*yoffset + nleap; + int days = 365 * yoffset + nleap; // month offset const bool leap = is_leap_year(year); for (int i = 1; i < month; ++i) { - days += month_days[leap][i-1]; + days += month_days[leap][i - 1]; } // day offset days += (day - 1); // final timestamp - m_timestamp - = days * Time::Day - + hour * Time::Hour - + minute * Time::Minute - + second * Time::Second - + microsecond * Time::Microsecond; + m_timestamp = days * Time::Day + hour * Time::Hour + minute * Time::Minute + second * Time::Second + microsecond * Time::Microsecond; } -Time::DateTime::DateTime(double gameTime) : DateTime(3200,1,1,0,0,0) { +Time::DateTime::DateTime(double gameTime) : + DateTime(3200, 1, 1, 0, 0, 0) +{ *this += Time::TimeDelta(gameTime, Time::Second); } -void Time::DateTime::GetDateParts(int *out_year, int *out_month, int *out_day) const { +void Time::DateTime::GetDateParts(int *out_year, int *out_month, int *out_day) const +{ if (out_year || out_month || out_day) { static_assert(Time::Day > (Sint64(1) << 32), "code below assumes that the 'date' part of a 64-bit timestamp fits in 32 bits"); @@ -106,13 +106,13 @@ void Time::DateTime::GetDateParts(int *out_year, int *out_month, int *out_day) c // computed such that n400 may be negative, but all other values must be positive int n400, n100, n4, n1; - std::tie(n400, days) = divmod_euclid(days, 365*400 + 97); + std::tie(n400, days) = divmod_euclid(days, 365 * 400 + 97); // days must be non-negative after this, so we can use truncating division from here - std::tie(n100, days) = divmod_trunc(days, 365*100 + 24); - std::tie(n4, days) = divmod_trunc(days, 365*4 + 1); + std::tie(n100, days) = divmod_trunc(days, 365 * 100 + 24); + std::tie(n4, days) = divmod_trunc(days, 365 * 4 + 1); std::tie(n1, days) = divmod_trunc(days, 365); - int year = 2001 + 400*n400 + 100*n100 + 4*n4 + n1; + int year = 2001 + 400 * n400 + 100 * n100 + 4 * n4 + n1; int day = days; // the last day in a 400-year or a 4-year cycle are handled incorrectly, @@ -134,30 +134,46 @@ void Time::DateTime::GetDateParts(int *out_year, int *out_month, int *out_day) c assert(month < 12); } - if (out_year) { *out_year = year; } - if (out_month) { *out_month = month + 1; } - if (out_day) { *out_day = day + 1; } + if (out_year) { + *out_year = year; + } + if (out_month) { + *out_month = month + 1; + } + if (out_day) { + *out_day = day + 1; + } } } -void Time::DateTime::GetTimeParts(int *out_hour, int *out_minute, int *out_second, int *out_microsecond) const { +void Time::DateTime::GetTimeParts(int *out_hour, int *out_minute, int *out_second, int *out_microsecond) const +{ if (out_hour || out_minute || out_second || out_microsecond) { const Sint64 tstamp = divmod_euclid(m_timestamp, Sint64(Time::Day)).second; assert(tstamp >= 0); - if (out_microsecond) { *out_microsecond = (tstamp / Time::Microsecond) % 1000000; } + if (out_microsecond) { + *out_microsecond = (tstamp / Time::Microsecond) % 1000000; + } const int seconds = (tstamp / Time::Second); - assert(seconds >= 0 && seconds < 24*60*60); + assert(seconds >= 0 && seconds < 24 * 60 * 60); - if (out_hour) { *out_hour = (seconds / 3600); } - if (out_minute) { *out_minute = (seconds / 60) % 60; } - if (out_second) { *out_second = (seconds / 1) % 60; } + if (out_hour) { + *out_hour = (seconds / 3600); + } + if (out_minute) { + *out_minute = (seconds / 60) % 60; + } + if (out_second) { + *out_second = (seconds / 1) % 60; + } } } -double Time::DateTime::ToGameTime() const { - const Time::DateTime base(3200,1,1, 0,0,0); +double Time::DateTime::ToGameTime() const +{ + const Time::DateTime base(3200, 1, 1, 0, 0, 0); Time::TimeDelta tstamp = (*this - base); if (*this < base) { // adjustment to give correct rounding for GetTotalSeconds() @@ -166,7 +182,8 @@ double Time::DateTime::ToGameTime() const { return double(tstamp.GetTotalSeconds()); } -std::string Time::DateTime::ToDateString() const { +std::string Time::DateTime::ToDateString() const +{ char buf[32]; int year, month, day; GetDateParts(&year, &month, &day); @@ -174,7 +191,8 @@ std::string Time::DateTime::ToDateString() const { return std::string(buf); } -std::string Time::DateTime::ToTimeString() const { +std::string Time::DateTime::ToTimeString() const +{ char buf[16]; int hour, minute, second; GetTimeParts(&hour, &minute, &second); @@ -182,7 +200,8 @@ std::string Time::DateTime::ToTimeString() const { return std::string(buf); } -std::string Time::DateTime::ToStringISO8601() const { +std::string Time::DateTime::ToStringISO8601() const +{ char buf[64]; int year, month, day, hour, minute, second; GetDateParts(&year, &month, &day); diff --git a/src/DateTime.h b/src/DateTime.h index 12898d9cb..7c66dc6e4 100644 --- a/src/DateTime.h +++ b/src/DateTime.h @@ -29,23 +29,25 @@ namespace Time { // and the passage of time. For example, leap seconds are not supported at all. // But... I'm pretty sure we don't need leap seconds for Pioneer. -enum TimeUnit : Sint64 { - Microsecond = 1ll, - Millisecond = 1000ll * Microsecond, - Second = 1000ll * Millisecond, - Minute = 60ll * Second, - Hour = 60ll * Minute, - Day = 24ll * Hour, - Week = 7ll * Day -}; + enum TimeUnit : Sint64 { + Microsecond = 1ll, + Millisecond = 1000ll * Microsecond, + Second = 1000ll * Millisecond, + Minute = 60ll * Second, + Hour = 60ll * Minute, + Day = 24ll * Hour, + Week = 7ll * Day + }; -class TimeDelta; -class DateTime; + class TimeDelta; + class DateTime; -class TimeDelta { + class TimeDelta { public: - TimeDelta(): m_delta(0) {} - explicit TimeDelta(Sint64 t, TimeUnit unit=Second): m_delta(t*unit) {} + TimeDelta() : + m_delta(0) {} + explicit TimeDelta(Sint64 t, TimeUnit unit = Second) : + m_delta(t * unit) {} Sint64 GetTotalWeeks() const { return (m_delta / Week); } Sint64 GetTotalDays() const { return (m_delta / Day); } @@ -55,8 +57,16 @@ class TimeDelta { Sint64 GetTotalMilliseconds() const { return (m_delta / Millisecond); } Sint64 GetTotalMicroseconds() const { return (m_delta / Microsecond); } - TimeDelta &operator+=(const TimeDelta &x) { m_delta += x.m_delta; return *this; } - TimeDelta &operator-=(const TimeDelta &x) { m_delta -= x.m_delta; return *this; } + TimeDelta &operator+=(const TimeDelta &x) + { + m_delta += x.m_delta; + return *this; + } + TimeDelta &operator-=(const TimeDelta &x) + { + m_delta -= x.m_delta; + return *this; + } friend TimeDelta operator+(const TimeDelta &a, const TimeDelta &b) { return TimeDelta(a.m_delta + b.m_delta, TimeUnit(1)); } friend TimeDelta operator-(const TimeDelta &a, const TimeDelta &b) { return TimeDelta(a.m_delta - b.m_delta, TimeUnit(1)); } @@ -66,17 +76,19 @@ class TimeDelta { friend DateTime operator+(const DateTime &a, const TimeDelta &b); friend DateTime operator-(const DateTime &a, const TimeDelta &b); + private: friend class DateTime; Sint64 m_delta; -}; + }; -class DateTime { + class DateTime { public: - DateTime(): m_timestamp(-Sint64(24*60*60) * Sint64(400*365 + 97) * Sint64(Second)) {} + DateTime() : + m_timestamp(-Sint64(24 * 60 * 60) * Sint64(400 * 365 + 97) * Sint64(Second)) {} // month = 1 to 12 // day = 1 to N where N is the number of days in the specified month and year - DateTime(int year, int month, int day, int hour=0, int minute=0, int second=0, int microsecond=0); + DateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int microsecond = 0); DateTime(double gameTime); void GetDateParts(int *year, int *month, int *day) const; @@ -89,15 +101,29 @@ class DateTime { std::string ToStringISO8601() const; friend TimeDelta operator-(const DateTime &a, const DateTime &b) - { return TimeDelta(a.m_timestamp - b.m_timestamp, TimeUnit(1)); } + { + return TimeDelta(a.m_timestamp - b.m_timestamp, TimeUnit(1)); + } friend DateTime operator+(const DateTime &a, const TimeDelta &b) - { return DateTime(a.m_timestamp + b.m_delta); } + { + return DateTime(a.m_timestamp + b.m_delta); + } friend DateTime operator-(const DateTime &a, const TimeDelta &b) - { return DateTime(a.m_timestamp - b.m_delta); } + { + return DateTime(a.m_timestamp - b.m_delta); + } friend DateTime operator+(const TimeDelta &a, const DateTime &b) { return (b + a); } - DateTime &operator+=(const TimeDelta &x) { m_timestamp += x.m_delta; return *this; } - DateTime &operator-=(const TimeDelta &x) { m_timestamp -= x.m_delta; return *this; } + DateTime &operator+=(const TimeDelta &x) + { + m_timestamp += x.m_delta; + return *this; + } + DateTime &operator-=(const TimeDelta &x) + { + m_timestamp -= x.m_delta; + return *this; + } friend bool operator<(const DateTime &a, const DateTime &b) { return (a.m_timestamp < b.m_timestamp); } friend bool operator<=(const DateTime &a, const DateTime &b) { return (a.m_timestamp <= b.m_timestamp); } @@ -109,7 +135,8 @@ class DateTime { Sint64 GetTimestamp() const { return m_timestamp; } private: - explicit DateTime(Sint64 tstamp): m_timestamp(tstamp) {} + explicit DateTime(Sint64 tstamp) : + m_timestamp(tstamp) {} // The timestamp is the number of microseconds since the epoch (2001-01-01T00:00:00Z) // @@ -131,7 +158,7 @@ class DateTime { // // (Incidentally, this is the way all integer timestamps work, at least all the ones I've ever seen) Sint64 m_timestamp; // (units: microseconds; 0 means 2001-01-01T00:00:00Z) -}; + }; } // namespace Time diff --git a/src/DeathView.cpp b/src/DeathView.cpp index 23b746b8c..510f9a257 100644 --- a/src/DeathView.cpp +++ b/src/DeathView.cpp @@ -7,7 +7,9 @@ #include "ShipCpanel.h" #include "graphics/Graphics.h" -DeathView::DeathView(Game* game): View(), m_game(game) +DeathView::DeathView(Game *game) : + View(), + m_game(game) { float size[2]; GetSizeRequested(size); @@ -19,8 +21,8 @@ DeathView::DeathView(Game* game): View(), m_game(game) Pi::renderer->GetNearFarRange(znear, zfar); const float fovY = Pi::config->Float("FOVVertical"); - m_cameraContext.Reset(new CameraContext(Graphics::GetScreenWidth(), Graphics::GetScreenHeight(), fovY, znear, zfar)); - m_camera.reset(new Camera(m_cameraContext, Pi::renderer)); + m_cameraContext.Reset(new CameraContext(Graphics::GetScreenWidth(), Graphics::GetScreenHeight(), fovY, znear, zfar)); + m_camera.reset(new Camera(m_cameraContext, Pi::renderer)); } DeathView::~DeathView() {} diff --git a/src/DeathView.h b/src/DeathView.h index d4caf7bdc..1c76fe8d8 100644 --- a/src/DeathView.h +++ b/src/DeathView.h @@ -4,16 +4,16 @@ #ifndef DEATH_VIEW_H #define DEATH_VIEW_H -#include "libs.h" -#include "View.h" #include "Camera.h" #include "RefCounted.h" +#include "View.h" +#include "libs.h" class Game; class DeathView : public View { public: - DeathView(Game* game); + DeathView(Game *game); virtual ~DeathView(); void Init(); @@ -28,7 +28,7 @@ private: RefCountedPtr m_cameraContext; std::unique_ptr m_camera; float m_cameraDist; - Game* m_game; + Game *m_game; }; #endif diff --git a/src/DeleteEmitter.h b/src/DeleteEmitter.h index 8f06158fc..8673b2d2c 100644 --- a/src/DeleteEmitter.h +++ b/src/DeleteEmitter.h @@ -16,7 +16,8 @@ class DeleteEmitter : public LuaWrappable { public: DeleteEmitter() {} - virtual ~DeleteEmitter() { + virtual ~DeleteEmitter() + { onDelete.emit(); } @@ -26,8 +27,8 @@ public: mutable sigc::signal onDelete; private: - // sigc++ signals cannot be copied, but long-standing design flaw means - // they don't have a private copy constructor. we protect them ourselves + // sigc++ signals cannot be copied, but long-standing design flaw means + // they don't have a private copy constructor. we protect them ourselves DeleteEmitter(const DeleteEmitter &) {} }; diff --git a/src/DynamicBody.cpp b/src/DynamicBody.cpp index 7a745896c..f62c6ee0a 100644 --- a/src/DynamicBody.cpp +++ b/src/DynamicBody.cpp @@ -1,24 +1,24 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "DynamicBody.h" -#include "Space.h" +#include "FixedGuns.h" #include "Frame.h" -#include "Planet.h" -#include "Pi.h" #include "GameSaveError.h" #include "JsonUtils.h" +#include "Pi.h" +#include "Planet.h" #include "Propulsion.h" -#include "FixedGuns.h" +#include "Space.h" +#include "libs.h" static const float KINETIC_ENERGY_MULT = 0.00001f; const double DynamicBody::DEFAULT_DRAG_COEFF = 0.1; // 'smooth sphere' -DynamicBody::DynamicBody() - : ModelBody() - , m_propulsion(nullptr) - , m_fixedGuns(nullptr) +DynamicBody::DynamicBody() : + ModelBody(), + m_propulsion(nullptr), + m_fixedGuns(nullptr) { m_dragCoeff = DEFAULT_DRAG_COEFF; m_flags = Body::FLAG_CAN_MOVE_FRAME; @@ -34,19 +34,21 @@ DynamicBody::DynamicBody() m_isMoving = true; m_atmosForce = vector3d(0.0); m_gravityForce = vector3d(0.0); - m_externalForce = vector3d(0.0); // do external forces calc instead? + m_externalForce = vector3d(0.0); // do external forces calc instead? m_lastForce = vector3d(0.0); m_lastTorque = vector3d(0.0); m_aiMessage = AIError::AIERROR_NONE; m_decelerating = false; - for ( int i=0; i < Feature::MAX_FEATURE; i++ ) m_features[i] = false; + for (int i = 0; i < Feature::MAX_FEATURE; i++) + m_features[i] = false; } -void DynamicBody::AddFeature( Feature f ) { +void DynamicBody::AddFeature(Feature f) +{ m_features[f] = true; - if(f == Feature::PROPULSION && m_propulsion == nullptr) { + if (f == Feature::PROPULSION && m_propulsion == nullptr) { m_propulsion.Reset(new Propulsion()); - } else if(f == Feature::FIXED_GUNS && m_fixedGuns == nullptr) { + } else if (f == Feature::FIXED_GUNS && m_fixedGuns == nullptr) { m_fixedGuns.Reset(new FixedGuns()); } } @@ -115,32 +117,37 @@ void DynamicBody::LoadFromJson(const Json &jsonObj, Space *space) m_aiMessage = AIError::AIERROR_NONE; m_decelerating = false; - for ( int i=0; i < Feature::MAX_FEATURE; i++ ) m_features[i] = false; + for (int i = 0; i < Feature::MAX_FEATURE; i++) + m_features[i] = false; } void DynamicBody::PostLoadFixup(Space *space) { Body::PostLoadFixup(space); m_oldPos = GetPosition(); -// CalcExternalForce(); // too dangerous + // CalcExternalForce(); // too dangerous } -const Propulsion *DynamicBody::GetPropulsion() const { +const Propulsion *DynamicBody::GetPropulsion() const +{ assert(m_propulsion != nullptr); return m_propulsion.Get(); } -Propulsion *DynamicBody::GetPropulsion() { +Propulsion *DynamicBody::GetPropulsion() +{ assert(m_propulsion != nullptr); return m_propulsion.Get(); } -const FixedGuns *DynamicBody::GetFixedGuns() const { +const FixedGuns *DynamicBody::GetFixedGuns() const +{ assert(m_fixedGuns != nullptr); return m_fixedGuns.Get(); } -FixedGuns *DynamicBody::GetFixedGuns() { +FixedGuns *DynamicBody::GetFixedGuns() +{ assert(m_fixedGuns != nullptr); return m_fixedGuns.Get(); } @@ -154,7 +161,7 @@ void DynamicBody::SetMass(double mass) { m_mass = mass; // This is solid sphere mass distribution, my friend - m_angInertia = (2/5.0)*m_mass*m_massRadius*m_massRadius; + m_angInertia = (2 / 5.0) * m_mass * m_massRadius * m_massRadius; } void DynamicBody::SetFrame(Frame *f) @@ -169,53 +176,54 @@ double DynamicBody::CalcAtmosphericForce(double dragCoeff) const Body *body = GetFrame()->GetBody(); if (!body || !GetFrame()->IsRotFrame() || !body->IsType(Object::PLANET)) return 0.0; - Planet *planet = static_cast(body); + Planet *planet = static_cast(body); double dist = GetPosition().Length(); double speed = m_vel.Length(); double pressure, density; planet->GetAtmosphericState(dist, &pressure, &density); - const double radius = GetClipRadius(); // bogus, preserving behaviour + const double radius = GetClipRadius(); // bogus, preserving behaviour const double area = radius; // ^^^ yes that is as stupid as it looks - return 0.5*density*speed*speed*area*dragCoeff; + return 0.5 * density * speed * speed * area * dragCoeff; } void DynamicBody::CalcExternalForce() { // gravity - if (!GetFrame()) return; // no external force if not in a frame + if (!GetFrame()) return; // no external force if not in a frame Body *body = GetFrame()->GetBody(); - if (body && !body->IsType(Object::SPACESTATION)) { // they ought to have mass though... + if (body && !body->IsType(Object::SPACESTATION)) { // they ought to have mass though... vector3d b1b2 = GetPosition(); double m1m2 = GetMass() * body->GetMass(); double invrsqr = 1.0 / b1b2.LengthSqr(); - double force = G*m1m2 * invrsqr; + double force = G * m1m2 * invrsqr; m_externalForce = -b1b2 * sqrt(invrsqr) * force; - } - else m_externalForce = vector3d(0.0); + } else + m_externalForce = vector3d(0.0); m_gravityForce = m_externalForce; // atmospheric drag - if (body && GetFrame()->IsRotFrame() && body->IsType(Object::PLANET)) - { + if (body && GetFrame()->IsRotFrame() && body->IsType(Object::PLANET)) { vector3d dragDir = -m_vel.NormalizedSafe(); - vector3d fDrag = CalcAtmosphericForce(m_dragCoeff)*dragDir; + vector3d fDrag = CalcAtmosphericForce(m_dragCoeff) * dragDir; // make this a bit less daft at high time accel // only allow atmosForce to increase by .1g per frame vector3d f1g = m_atmosForce + dragDir * GetMass(); - if (fDrag.LengthSqr() > f1g.LengthSqr()) m_atmosForce = f1g; - else m_atmosForce = fDrag; + if (fDrag.LengthSqr() > f1g.LengthSqr()) + m_atmosForce = f1g; + else + m_atmosForce = fDrag; m_externalForce += m_atmosForce; - } - else m_atmosForce = vector3d(0.0); + } else + m_atmosForce = vector3d(0.0); // centrifugal and coriolis forces for rotating frames if (GetFrame()->IsRotFrame()) { vector3d angRot(0, GetFrame()->GetAngSpeed(), 0); - m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition())); // centrifugal - m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity()); // coriolis + m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition())); // centrifugal + m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity()); // coriolis } } @@ -238,16 +246,16 @@ void DynamicBody::TimeStepUpdate(const float timeStep) SetPosition(GetPosition() + m_vel * double(timeStep)); -//if (this->IsType(Object::PLAYER)) -//Output("pos = %.1f,%.1f,%.1f, vel = %.1f,%.1f,%.1f, force = %.1f,%.1f,%.1f, external = %.1f,%.1f,%.1f\n", -// pos.x, pos.y, pos.z, m_vel.x, m_vel.y, m_vel.z, m_force.x, m_force.y, m_force.z, -// m_externalForce.x, m_externalForce.y, m_externalForce.z); + //if (this->IsType(Object::PLAYER)) + //Output("pos = %.1f,%.1f,%.1f, vel = %.1f,%.1f,%.1f, force = %.1f,%.1f,%.1f, external = %.1f,%.1f,%.1f\n", + // pos.x, pos.y, pos.z, m_vel.x, m_vel.y, m_vel.z, m_force.x, m_force.y, m_force.z, + // m_externalForce.x, m_externalForce.y, m_externalForce.z); m_lastForce = m_force; m_lastTorque = m_torque; m_force = vector3d(0.0); m_torque = vector3d(0.0); - CalcExternalForce(); // regenerate for new pos/vel + CalcExternalForce(); // regenerate for new pos/vel } else { m_oldAngDisplacement = vector3d(0.0); } @@ -257,15 +265,15 @@ void DynamicBody::TimeStepUpdate(const float timeStep) void DynamicBody::UpdateInterpTransform(double alpha) { - m_interpPos = alpha*GetPosition() + (1.0-alpha)*m_oldPos; + m_interpPos = alpha * GetPosition() + (1.0 - alpha) * m_oldPos; - double len = m_oldAngDisplacement.Length() * (1.0-alpha); + double len = m_oldAngDisplacement.Length() * (1.0 - alpha); if (len > 1e-16) { vector3d axis = m_oldAngDisplacement.Normalized(); - matrix3x3d rot = matrix3x3d::Rotate(-len, axis); // rotate backwards + matrix3x3d rot = matrix3x3d::Rotate(-len, axis); // rotate backwards m_interpOrient = rot * GetOrient(); - } - else m_interpOrient = GetOrient(); + } else + m_interpOrient = GetOrient(); } void DynamicBody::SetMassDistributionFromModel() @@ -273,7 +281,7 @@ void DynamicBody::SetMassDistributionFromModel() CollMesh *m = GetCollMesh(); // XXX totally arbitrarily pick to distribute mass over a half // bounding sphere area - m_massRadius = m->GetRadius()*0.5f; + m_massRadius = m->GetRadius() * 0.5f; SetMass(m_mass); } @@ -317,7 +325,7 @@ bool DynamicBody::OnCollision(Object *o, Uint32 flags, double relVel) double kineticEnergy = 0; if (o->IsType(Object::DYNAMICBODY)) { - kineticEnergy = KINETIC_ENERGY_MULT * static_cast(o)->GetMass() * relVel * relVel; + kineticEnergy = KINETIC_ENERGY_MULT * static_cast(o)->GetMass() * relVel * relVel; } else { kineticEnergy = KINETIC_ENERGY_MULT * m_mass * relVel * relVel; } @@ -325,10 +333,9 @@ bool DynamicBody::OnCollision(Object *o, Uint32 flags, double relVel) // damage (kineticEnergy is being passed as a damage value) is measured in kilograms // ignore damage less than a gram except for cargo, which is very fragile. CollisionContact dummy; - if (this->IsType(Object::CARGOBODY)){ + if (this->IsType(Object::CARGOBODY)) { OnDamage(o, float(kineticEnergy), dummy); - } - else if (kineticEnergy > 1e-3){ + } else if (kineticEnergy > 1e-3) { OnDamage(o, float(kineticEnergy), dummy); } @@ -336,7 +343,8 @@ bool DynamicBody::OnCollision(Object *o, Uint32 flags, double relVel) } // return parameters for orbit of any body, gives both elliptic and hyperbolic trajectories -Orbit DynamicBody::ComputeOrbit() const { +Orbit DynamicBody::ComputeOrbit() const +{ const Frame *frame = this->GetFrame()->GetNonRotFrame(); const double mass = frame->GetSystemBody()->GetMass(); diff --git a/src/DynamicBody.h b/src/DynamicBody.h index b8bf45e9c..d8b46b88d 100644 --- a/src/DynamicBody.h +++ b/src/DynamicBody.h @@ -6,17 +6,18 @@ #include "Body.h" #include "ModelBody.h" -#include "vector3.h" -#include "matrix4x4.h" #include "Orbit.h" +#include "matrix4x4.h" +#include "vector3.h" class Propulsion; class FixedGuns; -class DynamicBody: public ModelBody { +class DynamicBody : public ModelBody { private: friend class Propulsion; friend class FixedGuns; + public: OBJDEF(DynamicBody, ModelBody, DYNAMICBODY); DynamicBody(); @@ -32,7 +33,7 @@ public: void SetMassDistributionFromModel(); void SetMoving(bool isMoving) { m_isMoving = isMoving; } bool IsMoving() const { return m_isMoving; } - virtual double GetMass() const override { return m_mass; } // XXX don't override this + virtual double GetMass() const override { return m_mass; } // XXX don't override this virtual void TimeStepUpdate(const float timeStep) override; double CalcAtmosphericForce(double dragCoeff) const; void CalcExternalForce(); @@ -62,12 +63,17 @@ public: * in line 83) */ enum AIError { // - AIERROR_NONE=0, + AIERROR_NONE = 0, AIERROR_GRAV_TOO_HIGH, AIERROR_REFUSED_PERM, AIERROR_ORBIT_IMPOSSIBLE }; - AIError AIMessage(AIError msg=AIERROR_NONE) { AIError tmp = m_aiMessage; m_aiMessage = msg; return tmp; } + AIError AIMessage(AIError msg = AIERROR_NONE) + { + AIError tmp = m_aiMessage; + m_aiMessage = msg; + return tmp; + } enum Feature { PROPULSION = 0, @@ -75,13 +81,14 @@ public: MAX_FEATURE = 2, }; - bool Have( Feature f ) const { return m_features[f]; }; + bool Have(Feature f) const { return m_features[f]; }; void SetDecelerating(bool decel) { m_decelerating = decel; } const Propulsion *GetPropulsion() const; Propulsion *GetPropulsion(); const FixedGuns *GetFixedGuns() const; FixedGuns *GetFixedGuns(); - void AddFeature( Feature f ); + void AddFeature(Feature f); + protected: virtual void SaveToJson(Json &jsonObj, Space *space) override; virtual void LoadFromJson(const Json &jsonObj, Space *space) override; @@ -91,6 +98,7 @@ protected: bool m_decelerating; AIError m_aiMessage; + private: vector3d m_oldPos; vector3d m_oldAngDisplacement; diff --git a/src/Easing.h b/src/Easing.h index d60c3764e..3e07c2d04 100644 --- a/src/Easing.h +++ b/src/Easing.h @@ -15,146 +15,196 @@ namespace Easing { -// args are: -// t: time point to calculate -// b: value at beginning of range -// c: change over range (ie end-begin) -// d: duration of range + // args are: + // t: time point to calculate + // b: value at beginning of range + // c: change over range (ie end-begin) + // d: duration of range -template struct Function { typedef T (*Type)(T t, T b, T c, T d); }; + template + struct Function { + typedef T (*Type)(T t, T b, T c, T d); + }; + // p(t) = t + namespace Linear { + template + T EaseIn(T t, T b, T c, T d) + { + return c * t / d + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + return c * t / d + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + return c * t / d + b; + } + } // namespace Linear -// p(t) = t -namespace Linear { - template T EaseIn(T t, T b, T c, T d) { - return c*t/d + b; - } - template T EaseOut(T t, T b, T c, T d) { - return c*t/d + b; - } - template T EaseInOut(T t, T b, T c, T d) { - return c*t/d + b; - } -} + // p(t) = t^2 + namespace Quad { + template + T EaseIn(T t, T b, T c, T d) + { + t /= d; + return c * t * t + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + t /= d; + return -c * t * (t - 2) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + t /= d / 2; + if (t < 1) return ((c / 2) * (t * t)) + b; + return -c / 2 * ((t - 1) * (t - 3) - 1) + b; + } + } // namespace Quad -// p(t) = t^2 -namespace Quad { - template T EaseIn(T t, T b, T c, T d) { - t/=d; - return c*t*t + b; - } - template T EaseOut(T t, T b, T c, T d) { - t/=d; - return -c *t*(t-2) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - t/=d/2; - if (t < 1) return ((c/2)*(t*t)) + b; - return -c/2 * ((t-1)*(t-3)-1) + b; - } -} + // p(t) = t^3 + namespace Cubic { + template + T EaseIn(T t, T b, T c, T d) + { + t /= d; + return c * t * t * t + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + t = t / d - 1; + return c * (t * t * t + 1) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + t /= d / 2; + if (t < 1) return c / 2 * t * t * t + b; + t -= 2; + return c / 2 * (t * t * t + 2) + b; + } + } // namespace Cubic -// p(t) = t^3 -namespace Cubic { - template T EaseIn(T t, T b, T c, T d) { - t/=d; - return c*t*t*t + b; - } - template T EaseOut(T t, T b, T c, T d) { - t=t/d-1; - return c*(t*t*t + 1) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - t/=d/2; - if (t < 1) return c/2*t*t*t + b; - t-=2; - return c/2*(t*t*t + 2) + b; - } -} + // p(t) = t^4 + namespace Quart { + template + T EaseIn(T t, T b, T c, T d) + { + t /= d; + return c * t * t * t * t + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + t = t / d - 1; + return -c * (t * t * t * t - 1) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + t /= d / 2; + if (t < 1) return c / 2 * t * t * t * t + b; + t -= 2; + return -c / 2 * (t * t * t * t - 2) + b; + } + } // namespace Quart -// p(t) = t^4 -namespace Quart { - template T EaseIn(T t, T b, T c, T d) { - t/=d; - return c*t*t*t*t + b; - } - template T EaseOut(T t, T b, T c, T d) { - t=t/d-1; - return -c * (t*t*t*t - 1) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - t/=d/2; - if (t < 1) return c/2*t*t*t*t + b; - t-=2; - return -c/2 * (t*t*t*t - 2) + b; - } -} + // p(t) = t^5 + namespace Quint { + template + T EaseIn(T t, T b, T c, T d) + { + t /= d; + return c * t * t * t * t * t + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + t = t / d - 1; + return c * (t * t * t * t * t + 1) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + t /= d / 2; + if (t < 1) return c / 2 * t * t * t * t * t + b; + t -= 2; + return c / 2 * (t * t * t * t * t + 2) + b; + } + } // namespace Quint -// p(t) = t^5 -namespace Quint { - template T EaseIn(T t, T b, T c, T d) { - t/=d; - return c*t*t*t*t*t + b; - } - template T EaseOut(T t, T b, T c, T d) { - t=t/d-1; - return c*(t*t*t*t*t + 1) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - t/=d/2; - if (t < 1) return c/2*t*t*t*t*t + b; - t-=2; - return c/2*(t*t*t*t*t + 2) + b; - } -} + // p(t) = sin(t*pi/2) + namespace Sine { + template + T EaseIn(T t, T b, T c, T d) + { + return -c * cos(t / d * (M_PI / 2)) + c + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + return c * sin(t / d * (M_PI / 2)) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + return -c / 2 * (cos(M_PI * t / d) - 1) + b; + } + } // namespace Sine -// p(t) = sin(t*pi/2) -namespace Sine { - template T EaseIn(T t, T b, T c, T d) { - return -c * cos(t/d * (M_PI/2)) + c + b; - } - template T EaseOut(T t, T b, T c, T d) { - return c * sin(t/d * (M_PI/2)) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - return -c/2 * (cos(M_PI*t/d) - 1) + b; - } -} + // p(t) = 2^(10*(t-1)) + namespace Expo { + template + T EaseIn(T t, T b, T c, T d) + { + return (is_zero_general(t)) ? b : c * pow(2, 10 * (t / d - 1)) + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + return (is_equal_general(t, d)) ? b + c : c * (-pow(2, -10 * t / d) + 1) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + if (is_zero_general(t)) return b; + if (is_equal_general(t, d)) return b + c; + t /= d / 2; + if (t < 1) return c / 2 * pow(2, 10 * (t - 1)) + b; + return c / 2 * (-pow(2, -10 * --t) + 2) + b; + } + } // namespace Expo -// p(t) = 2^(10*(t-1)) -namespace Expo { - template T EaseIn(T t, T b, T c, T d) { - return (is_zero_general(t)) ? b : c * pow(2, 10 * (t/d - 1)) + b; - } - template T EaseOut(T t, T b, T c, T d) { - return (is_equal_general(t,d)) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - if (is_zero_general(t)) return b; - if (is_equal_general(t,d)) return b+c; - t/=d/2; - if (t < 1) return c/2 * pow(2, 10 * (t - 1)) + b; - return c/2 * (-pow(2, -10 * --t) + 2) + b; - } -} + // p(t) = 1-sqrt(1-t^2) + namespace Circ { + template + T EaseIn(T t, T b, T c, T d) + { + t /= d; + return -c * (sqrt(1 - t * t) - 1) + b; + } + template + T EaseOut(T t, T b, T c, T d) + { + t /= d; + return c * (sqrt(1 - (t - 1) * (t - 1))) + b; + } + template + T EaseInOut(T t, T b, T c, T d) + { + t /= d / 2; + if (t < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b; + return c / 2 * (sqrt(1 - (t - 2) * (t - 2)) + 1) + b; + } + } // namespace Circ -// p(t) = 1-sqrt(1-t^2) -namespace Circ { - template T EaseIn(T t, T b, T c, T d) { - t/=d; - return -c * (sqrt(1 - t*t) - 1) + b; - } - template T EaseOut(T t, T b, T c, T d) { - t/=d; - return c * (sqrt(1 - (t-1)*(t-1))) + b; - } - template T EaseInOut(T t, T b, T c, T d) { - t/=d/2; - if (t < 1) return -c/2 * (sqrt(1 - t*t) - 1) + b; - return c/2 * (sqrt(1 - (t-2)*(t-2)) + 1) + b; - } -} - -} +} // namespace Easing #endif diff --git a/src/EnumStrings.cpp b/src/EnumStrings.cpp index 2950b5609..e2835a1ec 100644 --- a/src/EnumStrings.cpp +++ b/src/EnumStrings.cpp @@ -3,53 +3,53 @@ #include "enum_table.h" #include -#include #include +#include namespace EnumStrings { -static std::map< std::string, std::map > enumStrings; -static std::map< std::string, std::map > enumValues; + static std::map> enumStrings; + static std::map> enumValues; -void Init() -{ - for (const EnumTable *table = ENUM_TABLES; table->name; table++) { - std::map &stringMap = enumStrings[table->name]; - std::map &valueMap = enumValues[table->name]; + void Init() + { + for (const EnumTable *table = ENUM_TABLES; table->name; table++) { + std::map &stringMap = enumStrings[table->name]; + std::map &valueMap = enumValues[table->name]; - for (const EnumItem *item = table->first; item->name; item++) { - stringMap.insert(std::make_pair(item->value, item->name)); - valueMap.insert(std::make_pair(item->name, item->value)); + for (const EnumItem *item = table->first; item->name; item++) { + stringMap.insert(std::make_pair(item->value, item->name)); + valueMap.insert(std::make_pair(item->name, item->value)); + } } } -} -const char *GetString(const char *ns, int value) -{ - std::map< std::string, std::map >::const_iterator tableIter = enumStrings.find(ns); - if (tableIter == enumStrings.end()) - return 0; + const char *GetString(const char *ns, int value) + { + std::map>::const_iterator tableIter = enumStrings.find(ns); + if (tableIter == enumStrings.end()) + return 0; - const std::map &table = tableIter->second; - std::map::const_iterator e = table.find(value); - if (e == table.end()) - return 0; + const std::map &table = tableIter->second; + std::map::const_iterator e = table.find(value); + if (e == table.end()) + return 0; - return e->second.c_str(); -} + return e->second.c_str(); + } -int GetValue(const char *ns, const char *name) -{ - std::map< std::string, std::map >::const_iterator tableIter = enumValues.find(ns); - if (tableIter == enumValues.end()) - return -1; + int GetValue(const char *ns, const char *name) + { + std::map>::const_iterator tableIter = enumValues.find(ns); + if (tableIter == enumValues.end()) + return -1; - const std::map &table = tableIter->second; - std::map::const_iterator e = table.find(name); - if (e == table.end()) - return -1; + const std::map &table = tableIter->second; + std::map::const_iterator e = table.find(name); + if (e == table.end()) + return -1; - return e->second; -} + return e->second; + } -} +} // namespace EnumStrings diff --git a/src/EnumStrings.h b/src/EnumStrings.h index fcca2b4f1..a38332445 100644 --- a/src/EnumStrings.h +++ b/src/EnumStrings.h @@ -6,10 +6,10 @@ namespace EnumStrings { -void Init(); -const char *GetString(const char *ns, int value); -int GetValue(const char *ns, const char *name); + void Init(); + const char *GetString(const char *ns, int value); + int GetValue(const char *ns, const char *name); -} +} // namespace EnumStrings #endif diff --git a/src/FaceParts.cpp b/src/FaceParts.cpp index 828a4a022..65473cd4f 100644 --- a/src/FaceParts.cpp +++ b/src/FaceParts.cpp @@ -4,19 +4,19 @@ #include "FaceParts.h" #include "FileSystem.h" #include "SDLWrappers.h" -#include "utils.h" #include "libs.h" +#include "utils.h" namespace { static const int MAX_GENDERS = 6; static const int MAX_RACES = 16; static const int MAX_SPECIES = 10; - static const Uint32 GENDER_SHIFT = 0; - static const Uint32 GENDER_MASK = ((1u << MAX_GENDERS) - 1u) << GENDER_SHIFT; - static const Uint32 RACE_SHIFT = GENDER_SHIFT + MAX_GENDERS; - static const Uint32 RACE_MASK = ((1u << MAX_RACES) - 1u) << RACE_SHIFT; + static const Uint32 GENDER_SHIFT = 0; + static const Uint32 GENDER_MASK = ((1u << MAX_GENDERS) - 1u) << GENDER_SHIFT; + static const Uint32 RACE_SHIFT = GENDER_SHIFT + MAX_GENDERS; + static const Uint32 RACE_MASK = ((1u << MAX_RACES) - 1u) << RACE_SHIFT; static const Uint32 SPECIES_SHIFT = RACE_SHIFT + MAX_RACES; - static const Uint32 SPECIES_MASK = ((1u << MAX_SPECIES) - 1u) << SPECIES_SHIFT; + static const Uint32 SPECIES_MASK = ((1u << MAX_SPECIES) - 1u) << SPECIES_SHIFT; // You can never have too many static_asserts, right? static_assert(((MAX_GENDERS + MAX_RACES + MAX_SPECIES) == 32), "unused bits in the face part selector"); @@ -29,15 +29,20 @@ namespace { Uint32 selector; // a bitmask indicating which species, races and genders can use this part SDLSurfacePtr part; - Part(): selector(0u) {} - Part(const Uint32 sel, SDLSurfacePtr im): selector(sel), part(im) {} + Part() : + selector(0u) {} + Part(const Uint32 sel, SDLSurfacePtr im) : + selector(sel), + part(im) {} }; struct SpeciesInfo { int num_races; int num_genders; - SpeciesInfo(int nraces, int ngenders): num_races(nraces), num_genders(ngenders) {} + SpeciesInfo(int nraces, int ngenders) : + num_races(nraces), + num_genders(ngenders) {} }; class PartDb { @@ -57,25 +62,40 @@ namespace { void Clear(); void Scan(); + private: void ScanSpecies(const std::string &dir, int species_idx); void ScanParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix); void ScanGenderedParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix); }; - static Uint32 _make_selector(int species, int race, int gender) { + static Uint32 _make_selector(int species, int race, int gender) + { assert(species < MAX_SPECIES); assert(race < MAX_RACES); assert(gender < MAX_GENDERS); Uint32 mask = 0u; - if (species < 0) { mask |= SPECIES_MASK; } else { mask |= (1u << (species + SPECIES_SHIFT)); } - if (race < 0) { mask |= RACE_MASK; } else { mask |= (1u << (race + RACE_SHIFT)); } - if (gender < 0) { mask |= GENDER_MASK; } else { mask |= (1u << (gender + GENDER_SHIFT)); } + if (species < 0) { + mask |= SPECIES_MASK; + } else { + mask |= (1u << (species + SPECIES_SHIFT)); + } + if (race < 0) { + mask |= RACE_MASK; + } else { + mask |= (1u << (race + RACE_SHIFT)); + } + if (gender < 0) { + mask |= GENDER_MASK; + } else { + mask |= (1u << (gender + GENDER_SHIFT)); + } return mask; } - static int _count_parts(const std::vector &parts, const Uint32 selector) { + static int _count_parts(const std::vector &parts, const Uint32 selector) + { int count = 0; for (const auto &part : parts) { if ((selector & part.selector) == selector) ++count; @@ -83,10 +103,13 @@ namespace { return count; } - static SDL_Surface *_get_part(const std::vector &parts, const Uint32 selector, int index) { + static SDL_Surface *_get_part(const std::vector &parts, const Uint32 selector, int index) + { for (const auto &part : parts) { if ((selector & part.selector) == selector) { - if (!index) { return part.part.Get(); } + if (!index) { + return part.part.Get(); + } --index; } } @@ -100,7 +123,7 @@ namespace { SDL_Rect destrec = { 0, 0, 0, 0 }; // if the source is the full size, then ignore the offset if ((source->w == FaceParts::FACE_WIDTH) && - (source->h == FaceParts::FACE_HEIGHT)) { + (source->h == FaceParts::FACE_HEIGHT)) { destrec.x = 0; destrec.y = 0; } else { @@ -115,7 +138,8 @@ namespace { namespace fs = FileSystem; -void PartDb::Clear() { +void PartDb::Clear() +{ species.clear(); heads.clear(); eyes.clear(); @@ -129,7 +153,8 @@ void PartDb::Clear() { static const char BACKGROUND_GENERAL_PATH[] = "facegen/backgrounds/general.png"; -void PartDb::Scan() { +void PartDb::Scan() +{ Clear(); background_general = LoadSurfaceFromFile(BACKGROUND_GENERAL_PATH); @@ -151,7 +176,8 @@ void PartDb::Scan() { } } -void PartDb::ScanSpecies(const std::string &basedir, const int species_idx) { +void PartDb::ScanSpecies(const std::string &basedir, const int species_idx) +{ int race_count = 0; const auto flags = fs::FileEnumerator::IncludeDirs | fs::FileEnumerator::ExcludeFiles; for (fs::FileEnumerator dirs(fs::gameDataFiles, basedir, flags); !dirs.Finished(); dirs.Next()) { @@ -183,7 +209,8 @@ void PartDb::ScanSpecies(const std::string &basedir, const int species_idx) { species.push_back(SpeciesInfo(race_count, 2)); // XXX currently we hardcode genders = 2 } -void PartDb::ScanParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix) { +void PartDb::ScanParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix) +{ const Uint32 selector = _make_selector(species_idx, race_idx, -1); for (fs::FileEnumerator files(fs::gameDataFiles, path); !files.Finished(); files.Next()) { const std::string &name = files.Current().GetName(); @@ -198,7 +225,8 @@ void PartDb::ScanParts(std::vector &output, const int species_idx, const i } } -void PartDb::ScanGenderedParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix) { +void PartDb::ScanGenderedParts(std::vector &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix) +{ const int prefix_len = strlen(prefix); for (fs::FileEnumerator files(fs::gameDataFiles, path); !files.Finished(); files.Next()) { const std::string &name = files.Current().GetName(); @@ -243,53 +271,65 @@ void FaceParts::Uninit() s_partdb = nullptr; } -int FaceParts::NumSpecies() { +int FaceParts::NumSpecies() +{ return s_partdb->species.size(); } -int FaceParts::NumGenders(const int speciesIdx) { +int FaceParts::NumGenders(const int speciesIdx) +{ assert(speciesIdx >= 0 && speciesIdx < NumSpecies()); return s_partdb->species[speciesIdx].num_genders; } -int FaceParts::NumRaces(const int speciesIdx) { +int FaceParts::NumRaces(const int speciesIdx) +{ assert(speciesIdx >= 0 && speciesIdx < NumSpecies()); return s_partdb->species[speciesIdx].num_races; } -int FaceParts::NumHeads(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumHeads(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->heads, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumEyes(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumEyes(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->eyes, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumNoses(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumNoses(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->noses, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumMouths(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumMouths(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->mouths, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumHairstyles(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumHairstyles(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->hairstyles, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumClothes(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumClothes(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->clothes, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumAccessories(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumAccessories(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->accessories, _make_selector(speciesIdx, raceIdx, genderIdx)); } -int FaceParts::NumArmour(const int speciesIdx, const int raceIdx, const int genderIdx) { +int FaceParts::NumArmour(const int speciesIdx, const int raceIdx, const int genderIdx) +{ return _count_parts(s_partdb->armour, _make_selector(speciesIdx, raceIdx, genderIdx)); } -static void _pick(Random &rng, int &inout_value, const int limit) { +static void _pick(Random &rng, int &inout_value, const int limit) +{ assert(limit > 0); // we always run the RNG, even if the result is not needed, because that way // the output (index) for a particular component should be fixed for a given seed, @@ -303,7 +343,8 @@ static void _pick(Random &rng, int &inout_value, const int limit) { } } -void FaceParts::PickFaceParts(FaceDescriptor &inout_face, const Uint32 seed) { +void FaceParts::PickFaceParts(FaceDescriptor &inout_face, const Uint32 seed) +{ Random rand(seed); _pick(rand, inout_face.species, NumSpecies()); @@ -320,13 +361,16 @@ void FaceParts::PickFaceParts(FaceDescriptor &inout_face, const Uint32 seed) { const bool has_accessories = (rand.Int32() & 1); _pick(rand, inout_face.accessories, _count_parts(s_partdb->accessories, selector)); - if (!has_accessories) { inout_face.accessories = 0; } + if (!has_accessories) { + inout_face.accessories = 0; + } _pick(rand, inout_face.clothes, _count_parts(s_partdb->clothes, selector)); _pick(rand, inout_face.armour, _count_parts(s_partdb->armour, selector)); } -void FaceParts::BuildFaceImage(SDL_Surface *faceIm, const FaceDescriptor &face, bool armoured) { +void FaceParts::BuildFaceImage(SDL_Surface *faceIm, const FaceDescriptor &face, bool armoured) +{ const Uint32 selector = _make_selector(face.species, face.race, face.gender); _blit_image(faceIm, s_partdb->background_general.Get(), 0, 0); diff --git a/src/FaceParts.h b/src/FaceParts.h index d3b0c5429..5cca9d834 100644 --- a/src/FaceParts.h +++ b/src/FaceParts.h @@ -55,6 +55,6 @@ namespace FaceParts { void PickFaceParts(FaceDescriptor &inout_face, const Uint32 seed); void BuildFaceImage(SDL_Surface *faceIm, const FaceDescriptor &face, bool armoured); -} +} // namespace FaceParts #endif diff --git a/src/Factions.cpp b/src/Factions.cpp index 271db728a..213f96f8e 100644 --- a/src/Factions.cpp +++ b/src/Factions.cpp @@ -2,30 +2,30 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Factions.h" -#include "galaxy/Sector.h" -#include "galaxy/SystemPath.h" #include "galaxy/CustomSystem.h" #include "galaxy/Galaxy.h" +#include "galaxy/Sector.h" +#include "galaxy/SystemPath.h" #include "enum_table.h" +#include "FileSystem.h" #include "GameSaveError.h" +#include "Lang.h" +#include "LuaConstants.h" +#include "LuaFixed.h" #include "LuaUtils.h" #include "LuaVector.h" -#include "LuaFixed.h" -#include "LuaConstants.h" -#include "Polit.h" -#include "FileSystem.h" -#include "Lang.h" #include "Pi.h" -#include +#include "Polit.h" #include #include +#include #include -const Uint32 Faction::BAD_FACTION_IDX = UINT_MAX; -const Color Faction::BAD_FACTION_COLOUR = Color(204,204,204,128); -const float Faction::FACTION_BASE_ALPHA = 0.40f; +const Uint32 Faction::BAD_FACTION_IDX = UINT_MAX; +const Color Faction::BAD_FACTION_COLOUR = Color(204, 204, 204, 128); +const float Faction::FACTION_BASE_ALPHA = 0.40f; const double Faction::FACTION_CURRENT_YEAR = 3200; //#define DUMP_FACTIONS @@ -43,10 +43,11 @@ struct FactionBuilder { static const char LuaFaction_TypeName[] = "Faction"; -static FactionsDatabase* s_activeFactionsDatabase = nullptr; +static FactionsDatabase *s_activeFactionsDatabase = nullptr; -static FactionBuilder *l_fac_check_builder(lua_State *L, int idx) { - FactionBuilder *facbld = static_cast( +static FactionBuilder *l_fac_check_builder(lua_State *L, int idx) +{ + FactionBuilder *facbld = static_cast( luaL_checkudata(L, idx, LuaFaction_TypeName)); assert(facbld->fac); return facbld; @@ -61,10 +62,10 @@ static int l_fac_new(lua_State *L) { const char *name = luaL_checkstring(L, 2); - FactionBuilder *facbld = static_cast(lua_newuserdata(L, sizeof(*facbld))); + FactionBuilder *facbld = static_cast(lua_newuserdata(L, sizeof(*facbld))); facbld->fac = new Faction(s_activeFactionsDatabase->GetGalaxy()); facbld->registered = false; - facbld->skip = false; + facbld->skip = false; luaL_setmetatable(L, LuaFaction_TypeName); facbld->fac->name = name; @@ -73,27 +74,33 @@ static int l_fac_new(lua_State *L) } #define LFAC_FIELD_SETTER_FIXED(luaname, fieldname) \ - static int l_fac_ ## luaname (lua_State *L) { \ + static int l_fac_##luaname(lua_State *L) \ + { \ Faction *fac = l_fac_check(L, 1); \ const fixed *value = LuaFixed::CheckFromLua(L, 2); \ fac->fieldname = *value; \ - lua_settop(L, 1); return 1; \ + lua_settop(L, 1); \ + return 1; \ } -#define LFAC_FIELD_SETTER_FLOAT(luaname, fieldname) \ - static int l_fac_ ## luaname (lua_State *L) { \ - Faction *fac = l_fac_check(L, 1); \ - double value = luaL_checknumber(L, 2); \ - fac->fieldname = value; \ - lua_settop(L, 1); return 1; \ +#define LFAC_FIELD_SETTER_FLOAT(luaname, fieldname) \ + static int l_fac_##luaname(lua_State *L) \ + { \ + Faction *fac = l_fac_check(L, 1); \ + double value = luaL_checknumber(L, 2); \ + fac->fieldname = value; \ + lua_settop(L, 1); \ + return 1; \ } -#define LFAC_FIELD_SETTER_INT(luaname, fieldname) \ - static int l_fac_ ## luaname (lua_State *L) { \ - Faction *fac = l_fac_check(L, 1); \ - int value = luaL_checkinteger(L, 2); \ - fac->fieldname = value; \ - lua_settop(L, 1); return 1; \ +#define LFAC_FIELD_SETTER_INT(luaname, fieldname) \ + static int l_fac_##luaname(lua_State *L) \ + { \ + Faction *fac = l_fac_check(L, 1); \ + int value = luaL_checkinteger(L, 2); \ + fac->fieldname = value; \ + lua_settop(L, 1); \ + return 1; \ } static int l_fac_description_short(lua_State *L) @@ -118,7 +125,7 @@ static int l_fac_govtype_weight(lua_State *L) Faction *fac = l_fac_check(L, 1); const char *typeName = luaL_checkstring(L, 2); const Polit::GovType g = static_cast(LuaConstants::GetConstant(L, "PolitGovType", typeName)); - const Sint32 weight = luaL_checkinteger(L, 3); // signed as we will need to compare with signed out of Random.Int32 + const Sint32 weight = luaL_checkinteger(L, 3); // signed as we will need to compare with signed out of Random.Int32 if (g < Polit::GOV_RAND_MIN || g > Polit::GOV_RAND_MAX) { pi_lua_warn(L, @@ -142,7 +149,7 @@ static int l_fac_govtype_weight(lua_State *L) } // sector(x,y,x) + system index + body index = location in a (custom?) system of homeworld -static int l_fac_homeworld (lua_State *L) +static int l_fac_homeworld(lua_State *L) { FactionBuilder *facbld = l_fac_check_builder(L, 1); Faction *fac = facbld->fac; @@ -158,12 +165,12 @@ static int l_fac_homeworld (lua_State *L) fac->SetBestFitHomeworld(x, y, z, si, bi, +1); if (!fac->homeworld.HasValidSystem()) fac->SetBestFitHomeworld(x, y, z, si, bi, -1); - facbld->skip = !fac->homeworld.HasValidSystem(); // wasn't a valid system + facbld->skip = !fac->homeworld.HasValidSystem(); // wasn't a valid system lua_settop(L, 1); return 1; } -LFAC_FIELD_SETTER_FLOAT(foundingDate, foundingDate) // date faction came into existence +LFAC_FIELD_SETTER_FLOAT(foundingDate, foundingDate) // date faction came into existence LFAC_FIELD_SETTER_FLOAT(expansionRate, expansionRate) // lightyears per year that the volume expands. static int l_fac_military_name(lua_State *L) @@ -199,7 +206,7 @@ static int l_fac_illegal_goods_probability(lua_State *L) Faction *fac = l_fac_check(L, 1); const char *typeName = luaL_checkstring(L, 2); const GalacticEconomy::Commodity e = static_cast( - LuaConstants::GetConstant(L, "CommodityType", typeName)); + LuaConstants::GetConstant(L, "CommodityType", typeName)); const Uint32 probability = luaL_checkunsigned(L, 3); if (probability > 100) { @@ -223,7 +230,7 @@ static int l_fac_colour(lua_State *L) const float g = luaL_checknumber(L, 3); const float b = luaL_checknumber(L, 4); - fac->colour = Color(r*255,g*255,b*255); + fac->colour = Color(r * 255, g * 255, b * 255); lua_settop(L, 1); @@ -242,8 +249,7 @@ static int l_fac_claim(lua_State *L) path.systemIndex = -99; // magic number, claim whole sector - if (lua_gettop(L) > 4) - { + if (lua_gettop(L) > 4) { path.systemIndex = luaL_checkinteger(L, 5); } fac->PushClaim(path); @@ -267,12 +273,12 @@ static void ExportFactionToLua(const Faction *fac, const size_t index) outstr << "local f = Faction:new('" << fac->name << "')" << std::endl; outstr << "\t:description_short('" << fac->description_short << "')" << std::endl; outstr << "\t:description('" << fac->description << "')" << std::endl; - if(fac->hasHomeworld) outstr << "\t:homeworld(" << fac->homeworld.sectorX << "," << fac->homeworld.sectorY << "," << fac->homeworld.sectorZ << "," << fac->homeworld.systemIndex << "," << fac->homeworld.bodyIndex << ")" << std::endl; + if (fac->hasHomeworld) outstr << "\t:homeworld(" << fac->homeworld.sectorX << "," << fac->homeworld.sectorY << "," << fac->homeworld.sectorZ << "," << fac->homeworld.systemIndex << "," << fac->homeworld.bodyIndex << ")" << std::endl; outstr << "\t:foundingDate(" << fac->foundingDate << ")" << std::endl; outstr << "\t:expansionRate(" << fac->expansionRate << ")" << std::endl; - if (!fac->military_name.empty()) outstr << "\t:military_name('" << fac->military_name << "')" << std::endl; - if (!fac->police_name.empty()) outstr << "\t:police_name('" << fac->police_name << "')" << std::endl; - if (!fac->police_ship.empty()) outstr << "\t:police_ship('" << fac->police_ship << "')" << std::endl; + if (!fac->military_name.empty()) outstr << "\t:military_name('" << fac->military_name << "')" << std::endl; + if (!fac->police_name.empty()) outstr << "\t:police_name('" << fac->police_name << "')" << std::endl; + if (!fac->police_ship.empty()) outstr << "\t:police_ship('" << fac->police_ship << "')" << std::endl; outstr << "\t:colour(" << float(fac->colour.r) / 255.f << "," << float(fac->colour.g) / 255.f << "," << float(fac->colour.b) / 255.f << ")" << std::endl; outstr << std::endl; @@ -296,7 +302,8 @@ static void ExportFactionToLua(const Faction *fac, const size_t index) } outstr << std::endl; - outstr << "f:add_to_factions('" << fac->name << "')\n\n" << std::endl; + outstr << "f:add_to_factions('" << fac->name << "')\n\n" + << std::endl; FILE *f = nullptr; FileSystem::FileSourceFS newFS(FileSystem::GetDataDir()); @@ -373,21 +380,21 @@ static int l_fac_gc(lua_State *L) } static luaL_Reg LuaFaction_meta[] = { - { "new", &l_fac_new }, - { "description_short", &l_fac_description_short }, - { "description", &l_fac_description }, - { "govtype_weight", &l_fac_govtype_weight }, - { "homeworld", &l_fac_homeworld }, - { "foundingDate", &l_fac_foundingDate }, - { "expansionRate", &l_fac_expansionRate }, - { "military_name", &l_fac_military_name }, - { "police_name", &l_fac_police_name }, - { "police_ship", &l_fac_police_ship }, + { "new", &l_fac_new }, + { "description_short", &l_fac_description_short }, + { "description", &l_fac_description }, + { "govtype_weight", &l_fac_govtype_weight }, + { "homeworld", &l_fac_homeworld }, + { "foundingDate", &l_fac_foundingDate }, + { "expansionRate", &l_fac_expansionRate }, + { "military_name", &l_fac_military_name }, + { "police_name", &l_fac_police_name }, + { "police_ship", &l_fac_police_ship }, { "illegal_goods_probability", &l_fac_illegal_goods_probability }, - { "colour", &l_fac_colour }, - { "add_to_factions", &l_fac_add_to_factions }, - { "claim", &l_fac_claim }, // claim possession of a starsystem or sector - { "__gc", &l_fac_gc }, + { "colour", &l_fac_colour }, + { "add_to_factions", &l_fac_add_to_factions }, + { "claim", &l_fac_claim }, // claim possession of a starsystem or sector + { "__gc", &l_fac_gc }, { 0, 0 } }; @@ -405,7 +412,6 @@ FactionsDatabase::~FactionsDatabase() } } - static void register_class(lua_State *L, const char *tname, luaL_Reg *meta) { LUA_DEBUG_START(L); @@ -451,12 +457,12 @@ void FactionsDatabase::Init() Output("Number of factions added: " SIZET_FMT "\n", m_factions.size()); ClearHomeSectors(); - m_galaxy->FlushCaches(); // clear caches of anything we used for faction generation + m_galaxy->FlushCaches(); // clear caches of anything we used for faction generation while (!m_missingFactionsMap.empty()) { - const std::string& factionName = m_missingFactionsMap.begin()->first; - std::list& csl = m_missingFactionsMap.begin()->second; + const std::string &factionName = m_missingFactionsMap.begin()->first; + std::list &csl = m_missingFactionsMap.begin()->second; while (!csl.empty()) { - CustomSystem* cs = csl.front(); + CustomSystem *cs = csl.front(); // FIXME: How to signal missing faction? fprintf(stderr, "Custom system %s referenced unknown faction %s\n", cs->name.c_str(), factionName.c_str()); csl.pop_front(); @@ -474,7 +480,7 @@ void FactionsDatabase::PostInit() SetHomeSectors(); #ifdef DUMP_FACTIONS // useful for dumping the factions from an autogenerated script - for (size_t i = 0; iname] = faction; auto it = m_missingFactionsMap.find(faction->name); if (it != m_missingFactionsMap.end()) { - std::list& csl = it->second; - for (CustomSystem* cs : csl) { + std::list &csl = it->second; + for (CustomSystem *cs : csl) { cs->faction = faction; } m_missingFactionsMap.erase(it); @@ -520,17 +526,17 @@ void FactionsDatabase::AddFaction(Faction* faction) m_spatial_index.Add(faction); if (faction->hasHomeworld) m_homesystems.insert(faction->homeworld.SystemOnly()); - faction->idx = m_factions.size()-1; + faction->idx = m_factions.size() - 1; } const Faction *FactionsDatabase::GetFaction(const Uint32 index) const { PROFILE_SCOPED() - assert( index < m_factions.size() ); + assert(index < m_factions.size()); return m_factions[index]; } -const Faction* FactionsDatabase::GetFaction(const std::string& factionName) const +const Faction *FactionsDatabase::GetFaction(const std::string &factionName) const { PROFILE_SCOPED() auto it = m_factions_byName.find(factionName); @@ -553,7 +559,7 @@ bool FactionsDatabase::MayAssignFactions() const return m_may_assign_factions; } -const Faction* FactionsDatabase::GetNearestClaimant(const Sector::System* sys) const +const Faction *FactionsDatabase::GetNearestClaimant(const Sector::System *sys) const { PROFILE_SCOPED() // firstly if this a custom StarSystem it may already have a faction assigned @@ -562,12 +568,11 @@ const Faction* FactionsDatabase::GetNearestClaimant(const Sector::System* sys) c } // if it didn't, or it wasn't a custom StarStystem, then we go ahead and assign it a faction allegiance like normal below... - const Faction* result = &m_no_faction; + const Faction *result = &m_no_faction; double closestFactionDist = HUGE_VAL; - ConstFactionList& candidates = m_spatial_index.CandidateFactions(sys); + ConstFactionList &candidates = m_spatial_index.CandidateFactions(sys); - for (ConstFactionIterator it = candidates.begin(); it != candidates.end(); ++it) - { + for (ConstFactionIterator it = candidates.begin(); it != candidates.end(); ++it) { if ((*it)->IsClaimed(sys->GetPath())) return *it; // this is a very specific claim, no further checks for distance from another factions homeworld is needed. if ((*it)->IsCloserAndContains(closestFactionDist, sys)) @@ -576,7 +581,7 @@ const Faction* FactionsDatabase::GetNearestClaimant(const Sector::System* sys) c return result; } -bool FactionsDatabase::IsHomeSystem(const SystemPath& sysPath) const +bool FactionsDatabase::IsHomeSystem(const SystemPath &sysPath) const { PROFILE_SCOPED() return m_homesystems.find(sysPath.SystemOnly()) != m_homesystems.end(); @@ -590,8 +595,7 @@ bool Faction::IsClaimed(SystemPath path) const SystemPath sector = path; sector.systemIndex = -99; - for (auto clam = m_ownedsystemlist.begin(); clam != m_ownedsystemlist.end(); clam++) - { + for (auto clam = m_ownedsystemlist.begin(); clam != m_ownedsystemlist.end(); clam++) { if (*clam == sector || *clam == path) return true; } @@ -604,7 +608,7 @@ bool Faction::IsClaimed(SystemPath path) const if it is, then the passed distance will also be updated to be the distance from the factions homeworld to the sysPath. */ -const bool Faction::IsCloserAndContains(double& closestFactionDist, const Sector::System* sys) const +const bool Faction::IsCloserAndContains(double &closestFactionDist, const Sector::System *sys) const { PROFILE_SCOPED() /* Treat factions without homeworlds as if they are of effectively infinite radius, @@ -613,21 +617,22 @@ const bool Faction::IsCloserAndContains(double& closestFactionDist, const Sector a better claim. */ float distance = HUGE_VAL; - bool inside = true; + bool inside = true; /* Factions that have a homeworld... */ - if (hasHomeworld) - { + if (hasHomeworld) { /* ...automatically gain the allegiance of worlds within the same sector... */ - if (sys->InSameSector(homeworld)) { distance = 0; } + if (sys->InSameSector(homeworld)) { + distance = 0; + } /* ...otherwise we need to calculate whether the world is inside the the faction border, and how far away it is. */ else { RefCountedPtr homeSec = GetHomeSector(); - const Sector::System* homeSys = &homeSec->m_systems[homeworld.systemIndex]; + const Sector::System *homeSys = &homeSec->m_systems[homeworld.systemIndex]; distance = Sector::System::DistanceBetween(homeSys, sys); - inside = distance < Radius(); + inside = distance < Radius(); } } @@ -637,7 +642,7 @@ const bool Faction::IsCloserAndContains(double& closestFactionDist, const Sector closestFactionDist = distance; return true; - /* otherwise this isn't the faction we were looking for */ + /* otherwise this isn't the faction we were looking for */ } else { return false; } @@ -648,23 +653,23 @@ const Color Faction::AdjustedColour(fixed population, bool inRange) const PROFILE_SCOPED() Color result; // Unexplored: population = -1, Uninhabited: population = 0. - result = population <= 0 ? BAD_FACTION_COLOUR : colour; - result.a = population > 0 ? (FACTION_BASE_ALPHA + (M_E + (logf(population.ToFloat() / 1.25))) / ((2 * M_E) + FACTION_BASE_ALPHA)) * 255 : FACTION_BASE_ALPHA * 255; - result.a = inRange ? 255 : result.a; + result = population <= 0 ? BAD_FACTION_COLOUR : colour; + result.a = population > 0 ? (FACTION_BASE_ALPHA + (M_E + (logf(population.ToFloat() / 1.25))) / ((2 * M_E) + FACTION_BASE_ALPHA)) * 255 : FACTION_BASE_ALPHA * 255; + result.a = inRange ? 255 : result.a; return result; } const Polit::GovType Faction::PickGovType(Random &rand) const { PROFILE_SCOPED() - if( !govtype_weights.empty()) { + if (!govtype_weights.empty()) { // if we roll a number between one and the total weighting... Sint32 roll = rand.Int32(1, govtype_weights_total); Sint32 cumulativeWeight = 0; // ...the first govType with a cumulative weight >= the roll should be our pick GovWeightIterator it = govtype_weights.begin(); - while(roll > (cumulativeWeight + it->second)) { + while (roll > (cumulativeWeight + it->second)) { cumulativeWeight += it->second; ++it; } @@ -688,8 +693,7 @@ void Faction::SetBestFitHomeworld(Sint32 x, Sint32 y, Sint32 z, Sint32 si, Uint3 // or hit the edge of inhabited space Uint32 i = 0; RefCountedPtr sys; - while (si < 0 && (abs(x) != 90 && abs(y) != 90 && abs(z) != 90) - && ( x != 0 && y != 0 && z != 0 )) { + while (si < 0 && (abs(x) != 90 && abs(y) != 90 && abs(z) != 90) && (x != 0 && y != 0 && z != 0)) { SystemPath path(x, y, z); // search for a suitable homeworld in the current sector @@ -705,8 +709,7 @@ void Faction::SetBestFitHomeworld(Sint32 x, Sint32 y, Sint32 z, Sint32 si, Uint3 if (stationCount.find(station->GetParent()->GetPath()) == stationCount.end()) { // new parent stationCount[station->GetParent()->GetPath()] = 1; - } - else { + } else { // increment count stationCount[station->GetParent()->GetPath()]++; } @@ -726,21 +729,38 @@ void Faction::SetBestFitHomeworld(Sint32 x, Sint32 y, Sint32 z, Sint32 si, Uint3 } // set the co-ordinates of the next sector to examine, cycling through x, y and z - if (si < 0 && i%3==0) { if (x >= 0) { x = x + axisChange; } else { x = x - axisChange; }; } - else if (si < 0 && i%3==1) { if (y >= 0) { y = y + axisChange; } else { y = y - axisChange; }; } - else if (si < 0 && i%3==2) { if (z >= 0) { z = z + axisChange; } else { z = z - axisChange; }; } + if (si < 0 && i % 3 == 0) { + if (x >= 0) { + x = x + axisChange; + } else { + x = x - axisChange; + }; + } else if (si < 0 && i % 3 == 1) { + if (y >= 0) { + y = y + axisChange; + } else { + y = y - axisChange; + }; + } else if (si < 0 && i % 3 == 2) { + if (z >= 0) { + z = z + axisChange; + } else { + z = z - axisChange; + }; + } i++; } homeworld = SystemPath(x, y, z, si, bi); } -RefCountedPtr Faction::GetHomeSector() const { +RefCountedPtr Faction::GetHomeSector() const +{ if (!m_homesector) // This will later be replaced by a Sector from the cache m_homesector = m_galaxy->GetSector(homeworld); return m_homesector; } -Faction::Faction(Galaxy* galaxy) : +Faction::Faction(Galaxy *galaxy) : idx(BAD_FACTION_IDX), name(Lang::NO_CENTRAL_GOVERNANCE), hasHomeworld(false), @@ -756,7 +776,7 @@ Faction::Faction(Galaxy* galaxy) : // ------ Factions Spatial Indexing ------ -void FactionsDatabase::Octsapling::Add(const Faction* faction) +void FactionsDatabase::Octsapling::Add(const Faction *faction) { PROFILE_SCOPED() /* The general principle here is to put the faction in every octbox cell that a system @@ -794,30 +814,30 @@ void FactionsDatabase::Octsapling::Add(const Faction* faction) /* put the faction in all the octbox cells needed in a hideously inexact way that will generate duplicates in each cell in many cases */ - octbox[xmin][ymin][zmin].push_back(faction); // 0,0,0 - octbox[xmax][ymin][zmin].push_back(faction); // 1,0,0 - octbox[xmax][ymax][zmin].push_back(faction); // 1,1,0 - octbox[xmax][ymax][zmax].push_back(faction); // 1,1,1 + octbox[xmin][ymin][zmin].push_back(faction); // 0,0,0 + octbox[xmax][ymin][zmin].push_back(faction); // 1,0,0 + octbox[xmax][ymax][zmin].push_back(faction); // 1,1,0 + octbox[xmax][ymax][zmax].push_back(faction); // 1,1,1 - octbox[xmin][ymax][zmin].push_back(faction); // 0,1,0 - octbox[xmin][ymax][zmax].push_back(faction); // 0,1,1 - octbox[xmin][ymin][zmax].push_back(faction); // 0,0,1 - octbox[xmax][ymin][zmax].push_back(faction); // 1,0,1 + octbox[xmin][ymax][zmin].push_back(faction); // 0,1,0 + octbox[xmin][ymax][zmax].push_back(faction); // 0,1,1 + octbox[xmin][ymin][zmax].push_back(faction); // 0,0,1 + octbox[xmax][ymin][zmax].push_back(faction); // 1,0,1 /* prune any duplicates from the octbox cells making things slightly saner */ - PruneDuplicates(0,0,0); - PruneDuplicates(1,0,0); - PruneDuplicates(1,1,0); - PruneDuplicates(1,1,1); + PruneDuplicates(0, 0, 0); + PruneDuplicates(1, 0, 0); + PruneDuplicates(1, 1, 0); + PruneDuplicates(1, 1, 1); - PruneDuplicates(0,1,0); - PruneDuplicates(0,1,1); - PruneDuplicates(0,0,1); - PruneDuplicates(1,0,1); + PruneDuplicates(0, 1, 0); + PruneDuplicates(0, 1, 1); + PruneDuplicates(0, 0, 1); + PruneDuplicates(1, 0, 1); } else { - /* ...other factions, such as ones with no homeworlds, and more annoyingly ones + /* ...other factions, such as ones with no homeworlds, and more annoyingly ones whose homeworlds don't exist yet because they're custom systems have to go in *every* octbox cell */ @@ -836,10 +856,10 @@ void FactionsDatabase::Octsapling::Add(const Faction* faction) void FactionsDatabase::Octsapling::PruneDuplicates(const int bx, const int by, const int bz) { PROFILE_SCOPED() - octbox[bx][by][bz].erase(std::unique( octbox[bx][by][bz].begin(), octbox[bx][by][bz].end() ), octbox[bx][by][bz].end() ); + octbox[bx][by][bz].erase(std::unique(octbox[bx][by][bz].begin(), octbox[bx][by][bz].end()), octbox[bx][by][bz].end()); } -const std::vector& FactionsDatabase::Octsapling::CandidateFactions(const Sector::System* sys) const +const std::vector &FactionsDatabase::Octsapling::CandidateFactions(const Sector::System *sys) const { PROFILE_SCOPED() /* answer the factions that we've put in the same octobox cell as the one the diff --git a/src/Factions.h b/src/Factions.h index ddab5fcc8..49f57a2e1 100644 --- a/src/Factions.h +++ b/src/Factions.h @@ -4,66 +4,67 @@ #ifndef _FACTIONS_H #define _FACTIONS_H -#include "galaxy/Sector.h" -#include "galaxy/Economy.h" -#include "galaxy/StarSystem.h" -#include "Polit.h" -#include "vector3.h" -#include "fixed.h" #include "DeleteEmitter.h" +#include "Polit.h" +#include "fixed.h" +#include "galaxy/Economy.h" +#include "galaxy/Sector.h" +#include "galaxy/StarSystem.h" +#include "vector3.h" #include -#include #include +#include class Galaxy; class CustomSystem; class Faction : public DeleteEmitter { friend class FactionsDatabase; + public: - static const Uint32 BAD_FACTION_IDX; // used by the no faction object to denote it's not a proper faction - static const Color BAD_FACTION_COLOUR; // factionColour to use on failing to find an appropriate faction - static const float FACTION_BASE_ALPHA; // Alpha to use on factionColour of systems with unknown population + static const Uint32 BAD_FACTION_IDX; // used by the no faction object to denote it's not a proper faction + static const Color BAD_FACTION_COLOUR; // factionColour to use on failing to find an appropriate faction + static const float FACTION_BASE_ALPHA; // Alpha to use on factionColour of systems with unknown population - Faction(Galaxy* galaxy); + Faction(Galaxy *galaxy); - Uint32 idx; // faction index - std::string name; // Formal name "Federation", "Empire", "Bob's Rib-shack consortium of delicious worlds (tm)", etc. - std::string description_short; // short description - std::string description; // detailed description describing formation, current status, etc + Uint32 idx; // faction index + std::string name; // Formal name "Federation", "Empire", "Bob's Rib-shack consortium of delicious worlds (tm)", etc. + std::string description_short; // short description + std::string description; // detailed description describing formation, current status, etc // government types with weighting typedef std::pair GovWeight; - typedef std::vector GovWeightVec; - typedef GovWeightVec::const_iterator GovWeightIterator; - GovWeightVec govtype_weights; - Sint32 govtype_weights_total; + typedef std::vector GovWeightVec; + typedef GovWeightVec::const_iterator GovWeightIterator; + GovWeightVec govtype_weights; + Sint32 govtype_weights_total; - bool hasHomeworld; - SystemPath homeworld; // sector(x,y,x) + system index + body index = location in a (custom?) system of homeworld - double foundingDate; // date faction came into existence - double expansionRate; // lightyears per year that the volume expands. - std::string military_name; // "Space Defense Force", "Imperial Will Enforcement Division"... + bool hasHomeworld; + SystemPath homeworld; // sector(x,y,x) + system index + body index = location in a (custom?) system of homeworld + double foundingDate; // date faction came into existence + double expansionRate; // lightyears per year that the volume expands. + std::string military_name; // "Space Defense Force", "Imperial Will Enforcement Division"... //military logo - std::string police_name; // "Police", "Polizia Locale"... - std::string police_ship; // "kanara", "varada"... + std::string police_name; // "Police", "Polizia Locale"... + std::string police_ship; // "kanara", "varada"... //police logo //goods/equipment availability (1-per-economy-type: aka agricultural, industrial, tourist, etc) typedef std::vector ClaimList; - ClaimList m_ownedsystemlist; + ClaimList m_ownedsystemlist; void PushClaim(SystemPath path) { m_ownedsystemlist.push_back(path); } bool IsClaimed(SystemPath) const; // commodity legality typedef std::map CommodityProbMap; - CommodityProbMap commodity_legality; + CommodityProbMap commodity_legality; - Color colour; + Color colour; - const double Radius() const { return (FACTION_CURRENT_YEAR - foundingDate) * expansionRate; }; - const bool IsValid() const { return idx != BAD_FACTION_IDX; }; - const Color AdjustedColour(fixed population, bool inRange) const; + const double Radius() const { return (FACTION_CURRENT_YEAR - foundingDate) * expansionRate; }; + const bool IsValid() const { return idx != BAD_FACTION_IDX; }; + const Color AdjustedColour(fixed population, bool inRange) const; const Polit::GovType PickGovType(Random &rand) const; // set the homeworld to one near the supplied co-ordinates @@ -71,11 +72,11 @@ public: RefCountedPtr GetHomeSector() const; private: - static const double FACTION_CURRENT_YEAR; // used to calculate faction radius + static const double FACTION_CURRENT_YEAR; // used to calculate faction radius - Galaxy* const m_galaxy; // galaxy we are part of - mutable RefCountedPtr m_homesector; // cache of home sector to use in distance calculations - const bool IsCloserAndContains(double& closestFactionDist, const Sector::System* sys) const; + Galaxy *const m_galaxy; // galaxy we are part of + mutable RefCountedPtr m_homesector; // cache of home sector to use in distance calculations + const bool IsCloserAndContains(double &closestFactionDist, const Sector::System *sys) const; }; /* One day it might grow up to become a full tree, on the other hand it might be @@ -85,21 +86,26 @@ private: class FactionsDatabase { public: - FactionsDatabase(Galaxy* galaxy, const std::string& factionDir) : m_galaxy(galaxy), m_factionDirectory(factionDir), m_no_faction(galaxy), m_may_assign_factions(false), m_initialized(false) { } + FactionsDatabase(Galaxy *galaxy, const std::string &factionDir) : + m_galaxy(galaxy), + m_factionDirectory(factionDir), + m_no_faction(galaxy), + m_may_assign_factions(false), + m_initialized(false) {} ~FactionsDatabase(); void Init(); void PostInit(); void ClearCache() { ClearHomeSectors(); } bool IsInitialized() const; - Galaxy* GetGalaxy() const { return m_galaxy; } - void RegisterCustomSystem(CustomSystem *cs, const std::string& factionName); - void AddFaction(Faction* faction); + Galaxy *GetGalaxy() const { return m_galaxy; } + void RegisterCustomSystem(CustomSystem *cs, const std::string &factionName); + void AddFaction(Faction *faction); const Faction *GetFaction(const Uint32 index) const; - const Faction *GetFaction(const std::string& factionName) const; - const Faction *GetNearestClaimant(const Sector::System* sys) const; - bool IsHomeSystem(const SystemPath& sysPath) const; + const Faction *GetFaction(const std::string &factionName) const; + const Faction *GetNearestClaimant(const Sector::System *sys) const; + bool IsHomeSystem(const SystemPath &sysPath) const; const Uint32 GetNumFactions() const; @@ -108,37 +114,36 @@ public: private: class Octsapling { public: - void Add(const Faction* faction); - const std::vector& CandidateFactions(const Sector::System* sys) const; + void Add(const Faction *faction); + const std::vector &CandidateFactions(const Sector::System *sys) const; private: - std::vector octbox[2][2][2]; - static const int BoxIndex(Sint32 sectorIndex) { return sectorIndex < 0 ? 0: 1; }; + std::vector octbox[2][2][2]; + static const int BoxIndex(Sint32 sectorIndex) { return sectorIndex < 0 ? 0 : 1; }; void PruneDuplicates(const int bx, const int by, const int bz); }; - typedef std::vector FactionList; + typedef std::vector FactionList; typedef FactionList::iterator FactionIterator; - typedef const std::vector ConstFactionList; + typedef const std::vector ConstFactionList; typedef ConstFactionList::const_iterator ConstFactionIterator; - typedef std::map FactionMap; - typedef std::set HomeSystemSet; - typedef std::map > MissingFactionsMap; + typedef std::map FactionMap; + typedef std::set HomeSystemSet; + typedef std::map> MissingFactionsMap; void ClearHomeSectors(); void SetHomeSectors(); - Galaxy* const m_galaxy; + Galaxy *const m_galaxy; const std::string m_factionDirectory; - Faction m_no_faction; // instead of answering null, we often want to answer a working faction object for no faction - FactionList m_factions; - FactionMap m_factions_byName; - HomeSystemSet m_homesystems; - Octsapling m_spatial_index; - bool m_may_assign_factions; - bool m_initialized = false; + Faction m_no_faction; // instead of answering null, we often want to answer a working faction object for no faction + FactionList m_factions; + FactionMap m_factions_byName; + HomeSystemSet m_homesystems; + Octsapling m_spatial_index; + bool m_may_assign_factions; + bool m_initialized = false; MissingFactionsMap m_missingFactionsMap; - }; #endif /* _FACTIONS_H */ diff --git a/src/FileSourceZip.cpp b/src/FileSourceZip.cpp index f0052be86..14e944d46 100644 --- a/src/FileSourceZip.cpp +++ b/src/FileSourceZip.cpp @@ -13,173 +13,174 @@ extern "C" { namespace FileSystem { -FileSourceZip::FileSourceZip(FileSourceFS &fs, const std::string &zipPath) : FileSource(zipPath), m_archive(0) -{ - mz_zip_archive *zip = static_cast(std::calloc(1, sizeof(mz_zip_archive))); - FILE *file = fs.OpenReadStream(zipPath); - if (!mz_zip_reader_init_file_stream(zip, file, 0)) { - Output("FileSourceZip: unable to open '%s'\n", zipPath.c_str()); - std::free(zip); - return; - } + FileSourceZip::FileSourceZip(FileSourceFS &fs, const std::string &zipPath) : + FileSource(zipPath), + m_archive(0) + { + mz_zip_archive *zip = static_cast(std::calloc(1, sizeof(mz_zip_archive))); + FILE *file = fs.OpenReadStream(zipPath); + if (!mz_zip_reader_init_file_stream(zip, file, 0)) { + Output("FileSourceZip: unable to open '%s'\n", zipPath.c_str()); + std::free(zip); + return; + } - mz_zip_archive_file_stat zipStat; + mz_zip_archive_file_stat zipStat; - Uint32 numFiles = mz_zip_reader_get_num_files(zip); - for (Uint32 i = 0; i < numFiles; i++) { - if (mz_zip_reader_file_stat(zip, i, &zipStat)) { - bool is_dir = mz_zip_reader_is_file_a_directory(zip, i); - if (!mz_zip_reader_is_file_encrypted(zip, i)) { - std::string fname = zipStat.m_filename; - if ((fname.size() > 1) && (fname[fname.size()-1] == '/')) { - fname.resize(fname.size() - 1); + Uint32 numFiles = mz_zip_reader_get_num_files(zip); + for (Uint32 i = 0; i < numFiles; i++) { + if (mz_zip_reader_file_stat(zip, i, &zipStat)) { + bool is_dir = mz_zip_reader_is_file_a_directory(zip, i); + if (!mz_zip_reader_is_file_encrypted(zip, i)) { + std::string fname = zipStat.m_filename; + if ((fname.size() > 1) && (fname[fname.size() - 1] == '/')) { + fname.resize(fname.size() - 1); + } + AddFile(zipStat.m_filename, FileStat(i, zipStat.m_uncomp_size, MakeFileInfo(fname, is_dir ? FileInfo::FT_DIR : FileInfo::FT_FILE))); } - AddFile(zipStat.m_filename, FileStat(i, zipStat.m_uncomp_size, - MakeFileInfo(fname, is_dir ? FileInfo::FT_DIR : FileInfo::FT_FILE))); } } + + m_archive = static_cast(zip); } - m_archive = static_cast(zip); -} - -FileSourceZip::~FileSourceZip() -{ - if (!m_archive) return; - mz_zip_archive *zip = static_cast(m_archive); - mz_zip_reader_end(zip); -} - -static void SplitPath(const std::string &path, std::vector &output) -{ - static const std::string delim("/"); - - size_t start = 0, end = 0; - while (end != std::string::npos) { - // get to the first non-delim char - start = path.find_first_not_of(delim, end); - - // read the end, no more to do - if (start == std::string::npos) - break; - - // find the end - next delim or end of string - end = path.find_first_of(delim, start); - - // extract the fragment and remember it - output.push_back(path.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); - } -} - -bool FileSourceZip::FindDirectoryAndFile(const std::string &path, const Directory* &dir, std::string &filename) -{ - std::vector fragments; - SplitPath(NormalisePath(path), fragments); - - assert(fragments.size() > 0); - - dir = &m_root; - - if (fragments.size() > 1) { - for (unsigned int i = 0; i < fragments.size()-1; i++) { - std::map::const_iterator it = dir->subdirs.find(fragments[i]); - if (it == dir->subdirs.end()) - return false; - dir = &((*it).second); - } - } - - filename = fragments.back(); - return true; -} - -FileInfo FileSourceZip::Lookup(const std::string &path) -{ - const Directory *dir; - std::string filename; - if (!FindDirectoryAndFile(path, dir, filename)) - return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT); - - std::map::const_iterator i = dir->files.find(filename); - if (i == dir->files.end()) - return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT); - - return (*i).second.info; -} - -RefCountedPtr FileSourceZip::ReadFile(const std::string &path) -{ - if (!m_archive) return RefCountedPtr(); - mz_zip_archive *zip = static_cast(m_archive); - - const Directory *dir; - std::string filename; - if (!FindDirectoryAndFile(path, dir, filename)) - return RefCountedPtr(); - - std::map::const_iterator i = dir->files.find(filename); - if (i == dir->files.end()) - return RefCountedPtr(); - - const FileStat &st = (*i).second; - - char *data = static_cast(std::malloc(st.size)); - if (!mz_zip_reader_extract_to_mem(zip, st.index, data, st.size, 0)) { - Output("FileSourceZip::ReadFile: couldn't extract '%s'\n", path.c_str()); - return RefCountedPtr(); - } - - return RefCountedPtr(new FileDataMalloc(st.info, st.size, data)); -} - -bool FileSourceZip::ReadDirectory(const std::string &path, std::vector &output) -{ - const Directory *dir; - std::string filename; - if (!FindDirectoryAndFile(path, dir, filename)) - return false; - + FileSourceZip::~FileSourceZip() { - std::map::const_iterator i = dir->subdirs.find(filename); - if (i == dir->subdirs.end()) - return false; - dir = &((*i).second); + if (!m_archive) return; + mz_zip_archive *zip = static_cast(m_archive); + mz_zip_reader_end(zip); } - for (std::map::const_iterator i = dir->files.begin(); i != dir->files.end(); ++i) - output.push_back((*i).second.info); + static void SplitPath(const std::string &path, std::vector &output) + { + static const std::string delim("/"); - return true; -} + size_t start = 0, end = 0; + while (end != std::string::npos) { + // get to the first non-delim char + start = path.find_first_not_of(delim, end); -void FileSourceZip::AddFile(const std::string &path, const FileStat &fileStat) -{ - std::vector fragments; - SplitPath(path, fragments); + // read the end, no more to do + if (start == std::string::npos) + break; - assert(fragments.size() > 0); + // find the end - next delim or end of string + end = path.find_first_of(delim, start); - Directory *dir = &m_root; - - if (fragments.size() > 1) { - std::string fullPath; - - for (unsigned int i = 0; i < fragments.size()-1; i++) { - fullPath += ((i > 0) ? "/" : "") + fragments[i]; - - std::map::const_iterator it = dir->files.find(fragments[i]); - if (it == dir->files.end()) - dir->files.insert(std::make_pair(fragments[i], FileStat(Uint32(-1), 0, MakeFileInfo(fullPath, FileInfo::FT_DIR)))); - dir = &(dir->subdirs[fragments[i]]); + // extract the fragment and remember it + output.push_back(path.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); } } - const std::string &filename = fragments.back(); + bool FileSourceZip::FindDirectoryAndFile(const std::string &path, const Directory *&dir, std::string &filename) + { + std::vector fragments; + SplitPath(NormalisePath(path), fragments); - if (fileStat.info.IsDir()) - dir->subdirs.insert(std::make_pair(filename, Directory())); + assert(fragments.size() > 0); - dir->files.insert(std::make_pair(filename, fileStat)); -} + dir = &m_root; -} + if (fragments.size() > 1) { + for (unsigned int i = 0; i < fragments.size() - 1; i++) { + std::map::const_iterator it = dir->subdirs.find(fragments[i]); + if (it == dir->subdirs.end()) + return false; + dir = &((*it).second); + } + } + + filename = fragments.back(); + return true; + } + + FileInfo FileSourceZip::Lookup(const std::string &path) + { + const Directory *dir; + std::string filename; + if (!FindDirectoryAndFile(path, dir, filename)) + return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT); + + std::map::const_iterator i = dir->files.find(filename); + if (i == dir->files.end()) + return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT); + + return (*i).second.info; + } + + RefCountedPtr FileSourceZip::ReadFile(const std::string &path) + { + if (!m_archive) return RefCountedPtr(); + mz_zip_archive *zip = static_cast(m_archive); + + const Directory *dir; + std::string filename; + if (!FindDirectoryAndFile(path, dir, filename)) + return RefCountedPtr(); + + std::map::const_iterator i = dir->files.find(filename); + if (i == dir->files.end()) + return RefCountedPtr(); + + const FileStat &st = (*i).second; + + char *data = static_cast(std::malloc(st.size)); + if (!mz_zip_reader_extract_to_mem(zip, st.index, data, st.size, 0)) { + Output("FileSourceZip::ReadFile: couldn't extract '%s'\n", path.c_str()); + return RefCountedPtr(); + } + + return RefCountedPtr(new FileDataMalloc(st.info, st.size, data)); + } + + bool FileSourceZip::ReadDirectory(const std::string &path, std::vector &output) + { + const Directory *dir; + std::string filename; + if (!FindDirectoryAndFile(path, dir, filename)) + return false; + + { + std::map::const_iterator i = dir->subdirs.find(filename); + if (i == dir->subdirs.end()) + return false; + dir = &((*i).second); + } + + for (std::map::const_iterator i = dir->files.begin(); i != dir->files.end(); ++i) + output.push_back((*i).second.info); + + return true; + } + + void FileSourceZip::AddFile(const std::string &path, const FileStat &fileStat) + { + std::vector fragments; + SplitPath(path, fragments); + + assert(fragments.size() > 0); + + Directory *dir = &m_root; + + if (fragments.size() > 1) { + std::string fullPath; + + for (unsigned int i = 0; i < fragments.size() - 1; i++) { + fullPath += ((i > 0) ? "/" : "") + fragments[i]; + + std::map::const_iterator it = dir->files.find(fragments[i]); + if (it == dir->files.end()) + dir->files.insert(std::make_pair(fragments[i], FileStat(Uint32(-1), 0, MakeFileInfo(fullPath, FileInfo::FT_DIR)))); + dir = &(dir->subdirs[fragments[i]]); + } + } + + const std::string &filename = fragments.back(); + + if (fileStat.info.IsDir()) + dir->subdirs.insert(std::make_pair(filename, Directory())); + + dir->files.insert(std::make_pair(filename, fileStat)); + } + +} // namespace FileSystem diff --git a/src/FileSourceZip.h b/src/FileSourceZip.h index d7714bddb..a2d249c84 100644 --- a/src/FileSourceZip.h +++ b/src/FileSourceZip.h @@ -11,38 +11,41 @@ namespace FileSystem { -class FileSourceZip : public FileSource { -public: - // for now this needs to be FileSourceFS rather than just FileSource, - // because we need a FILE* stream access to the .zip file - FileSourceZip(FileSourceFS &fs, const std::string &zipPath); - virtual ~FileSourceZip(); + class FileSourceZip : public FileSource { + public: + // for now this needs to be FileSourceFS rather than just FileSource, + // because we need a FILE* stream access to the .zip file + FileSourceZip(FileSourceFS &fs, const std::string &zipPath); + virtual ~FileSourceZip(); - virtual FileInfo Lookup(const std::string &path); - virtual RefCountedPtr ReadFile(const std::string &path); - virtual bool ReadDirectory(const std::string &path, std::vector &output); + virtual FileInfo Lookup(const std::string &path); + virtual RefCountedPtr ReadFile(const std::string &path); + virtual bool ReadDirectory(const std::string &path, std::vector &output); -private: - void *m_archive; + private: + void *m_archive; - struct FileStat { - FileStat(Uint32 _index, Uint64 _size, const FileInfo &_info) : index(_index), size(_size), info(_info) {} - const Uint32 index; - const Uint64 size; - const FileInfo info; + struct FileStat { + FileStat(Uint32 _index, Uint64 _size, const FileInfo &_info) : + index(_index), + size(_size), + info(_info) {} + const Uint32 index; + const Uint64 size; + const FileInfo info; + }; + + struct Directory { + std::map subdirs; + std::map files; + }; + + Directory m_root; + + bool FindDirectoryAndFile(const std::string &path, const Directory *&dir, std::string &filename); + void AddFile(const std::string &path, const FileStat &fileStat); }; - struct Directory { - std::map subdirs; - std::map files; - }; - - Directory m_root; - - bool FindDirectoryAndFile(const std::string &path, const Directory* &dir, std::string &filename); - void AddFile(const std::string &path, const FileStat &fileStat); -}; - -} +} // namespace FileSystem #endif diff --git a/src/FileSystem.cpp b/src/FileSystem.cpp index 9bddece81..6a655df4a 100644 --- a/src/FileSystem.cpp +++ b/src/FileSystem.cpp @@ -1,13 +1,13 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "FileSystem.h" #include "StringRange.h" -#include -#include +#include "libs.h" #include +#include #include +#include #include namespace FileSystem { @@ -71,7 +71,9 @@ namespace FileSystem { if (result.size() <= initial_result_length) throw std::invalid_argument(path.ToString()); size_t pos = result.rfind('/'); - if (pos == std::string::npos) { pos = 0; } + if (pos == std::string::npos) { + pos = 0; + } assert(pos >= initial_result_length); result.erase(pos); } else { @@ -80,7 +82,9 @@ namespace FileSystem { result += '/'; result.append(part.begin, part.Size()); } - if (part.end == path.end) { break; } + if (part.end == path.end) { + break; + } assert(*part.end == '/'); part.begin = part.end + 1; part.end = path.end; @@ -105,7 +109,7 @@ namespace FileSystem { else { std::string result(base); result.reserve(result.size() + 1 + path.size()); - if (result[result.size()-1] != '/') + if (result[result.size() - 1] != '/') result += '/'; StringRange rhs(path.c_str(), path.size()); if (path[0] == '/') { @@ -129,14 +133,14 @@ namespace FileSystem { { } - FileInfo::FileInfo(FileSource *source, const std::string &path, FileType type, Time::DateTime modTime): + FileInfo::FileInfo(FileSource *source, const std::string &path, FileType type, Time::DateTime modTime) : m_source(source), m_path(path), m_modTime(modTime), m_dirLen(0), m_type(type) { - assert((m_path.size() <= 1) || (m_path[m_path.size()-1] != '/')); + assert((m_path.size() <= 1) || (m_path[m_path.size() - 1] != '/')); std::size_t slashpos = m_path.rfind('/'); if (slashpos != std::string::npos) { m_dirLen = slashpos + 1; @@ -155,7 +159,8 @@ namespace FileSystem { return MakeFileInfo(path, fileType, Time::DateTime()); } - FileSourceUnion::FileSourceUnion(): FileSource(":union:") {} + FileSourceUnion::FileSourceUnion() : + FileSource(":union:") {} FileSourceUnion::~FileSourceUnion() {} void FileSourceUnion::PrependSource(FileSource *fs) @@ -174,17 +179,19 @@ namespace FileSystem { void FileSourceUnion::RemoveSource(FileSource *fs) { - std::vector::iterator nend = std::remove(m_sources.begin(), m_sources.end(), fs); + std::vector::iterator nend = std::remove(m_sources.begin(), m_sources.end(), fs); m_sources.erase(nend, m_sources.end()); } FileInfo FileSourceUnion::Lookup(const std::string &path) { - for (std::vector::const_iterator - it = m_sources.begin(); it != m_sources.end(); ++it) - { + for (std::vector::const_iterator + it = m_sources.begin(); + it != m_sources.end(); ++it) { FileInfo info = (*it)->Lookup(path); - if (info.Exists()) { return info; } + if (info.Exists()) { + return info; + } } return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT); } @@ -203,11 +210,13 @@ namespace FileSystem { RefCountedPtr FileSourceUnion::ReadFile(const std::string &path) { - for (std::vector::const_iterator - it = m_sources.begin(); it != m_sources.end(); ++it) - { + for (std::vector::const_iterator + it = m_sources.begin(); + it != m_sources.end(); ++it) { RefCountedPtr data = (*it)->ReadFile(path); - if (data) { return data; } + if (data) { + return data; + } } return RefCountedPtr(); } @@ -218,16 +227,19 @@ namespace FileSystem { // in preference to non-directories; otherwise, the FileInfo from the // first vector is selected in preference to the second vector. static void file_union_merge( - std::vector::const_iterator a, std::vector::const_iterator aend, - std::vector::const_iterator b, std::vector::const_iterator bend, - std::vector &output) + std::vector::const_iterator a, std::vector::const_iterator aend, + std::vector::const_iterator b, std::vector::const_iterator bend, + std::vector &output) { while ((a != aend) && (b != bend)) { int order = a->GetPath().compare(b->GetPath()); int which = order; if (which == 0) { - if (b->IsDir() && !a->IsDir()) { which = 1; } - else { which = -1; } + if (b->IsDir() && !a->IsDir()) { + which = 1; + } else { + which = -1; + } } if (which < 0) { output.push_back(*a++); @@ -238,8 +250,12 @@ namespace FileSystem { } } - if (a != aend) { std::copy(a, aend, std::back_inserter(output)); } - if (b != bend) { std::copy(b, bend, std::back_inserter(output)); } + if (a != aend) { + std::copy(a, aend, std::back_inserter(output)); + } + if (b != bend) { + std::copy(b, bend, std::back_inserter(output)); + } } bool FileSourceUnion::ReadDirectory(const std::string &path, std::vector &output) @@ -254,9 +270,9 @@ namespace FileSystem { bool founddir = false; std::vector merged; - for (std::vector::const_iterator - it = m_sources.begin(); it != m_sources.end(); ++it) - { + for (std::vector::const_iterator + it = m_sources.begin(); + it != m_sources.end(); ++it) { std::vector nextfiles; if ((*it)->ReadDirectory(path, nextfiles)) { founddir = true; @@ -278,11 +294,13 @@ namespace FileSystem { return founddir; } - FileEnumerator::FileEnumerator(FileSource &fs, int flags): - m_source(&fs), m_flags(flags) {} + FileEnumerator::FileEnumerator(FileSource &fs, int flags) : + m_source(&fs), + m_flags(flags) {} - FileEnumerator::FileEnumerator(FileSource &fs, const std::string &path, int flags): - m_source(&fs), m_flags(flags) + FileEnumerator::FileEnumerator(FileSource &fs, const std::string &path, int flags) : + m_source(&fs), + m_flags(flags) { AddSearchRoot(path); } @@ -321,20 +339,29 @@ namespace FileSystem { std::vector entries; m_source->ReadDirectory(info.GetPath(), entries); for (std::vector::const_iterator - it = entries.begin(); it != entries.end(); ++it) { + it = entries.begin(); + it != entries.end(); ++it) { switch (it->GetType()) { - case FileInfo::FT_DIR: - if (m_flags & IncludeDirs) { m_queue.push_back(*it); } - if (m_flags & Recurse) { m_dirQueue.push_back(*it); } - break; - case FileInfo::FT_FILE: - if (!(m_flags & ExcludeFiles)) { m_queue.push_back(*it); } - break; - case FileInfo::FT_SPECIAL: - if (m_flags & IncludeSpecials) { m_queue.push_back(*it); } - break; - default: assert(0); break; + case FileInfo::FT_DIR: + if (m_flags & IncludeDirs) { + m_queue.push_back(*it); + } + if (m_flags & Recurse) { + m_dirQueue.push_back(*it); + } + break; + case FileInfo::FT_FILE: + if (!(m_flags & ExcludeFiles)) { + m_queue.push_back(*it); + } + break; + case FileInfo::FT_SPECIAL: + if (m_flags & IncludeSpecials) { + m_queue.push_back(*it); + } + break; + default: assert(0); break; } } } diff --git a/src/FileSystem.h b/src/FileSystem.h index 12d5e9d92..75d282f07 100644 --- a/src/FileSystem.h +++ b/src/FileSystem.h @@ -4,14 +4,14 @@ #ifndef _FILESYSTEM_H #define _FILESYSTEM_H -#include "RefCounted.h" -#include "StringRange.h" #include "ByteRange.h" #include "DateTime.h" -#include -#include +#include "RefCounted.h" +#include "StringRange.h" #include #include +#include +#include /* * Functionality: @@ -63,8 +63,12 @@ namespace FileSystem { class FileInfo { friend class FileSource; + public: - FileInfo(): m_source(0), m_dirLen(0), m_type(FT_NON_EXISTENT) {} + FileInfo() : + m_source(0), + m_dirLen(0), + m_type(FT_NON_EXISTENT) {} enum FileType { // note: order here affects sort-order of FileInfo @@ -95,24 +99,36 @@ namespace FileSystem { RefCountedPtr Read() const; friend bool operator==(const FileInfo &a, const FileInfo &b) - { return (a.m_source == b.m_source && a.m_type == b.m_type && a.m_path == b.m_path); } + { + return (a.m_source == b.m_source && a.m_type == b.m_type && a.m_path == b.m_path); + } friend bool operator!=(const FileInfo &a, const FileInfo &b) - { return (a.m_source != b.m_source || a.m_type != b.m_type || a.m_path != b.m_path); } - friend bool operator< (const FileInfo &a, const FileInfo &b) + { + return (a.m_source != b.m_source || a.m_type != b.m_type || a.m_path != b.m_path); + } + friend bool operator<(const FileInfo &a, const FileInfo &b) { int c = a.m_path.compare(b.m_path); - if (c != 0) { return (c < 0); } - if (a.m_type != b.m_type) { return (a.m_type < b.m_type); } + if (c != 0) { + return (c < 0); + } + if (a.m_type != b.m_type) { + return (a.m_type < b.m_type); + } return (a.m_source < b.m_source); } friend bool operator<=(const FileInfo &a, const FileInfo &b) { int c = a.m_path.compare(b.m_path); - if (c != 0) { return (c < 0); } - if (a.m_type != b.m_type) { return (a.m_type < b.m_type); } + if (c != 0) { + return (c < 0); + } + if (a.m_type != b.m_type) { + return (a.m_type < b.m_type); + } return (a.m_source <= b.m_source); } - friend bool operator> (const FileInfo &a, const FileInfo &b) { return (b < a); } + friend bool operator>(const FileInfo &a, const FileInfo &b) { return (b < a); } friend bool operator>=(const FileInfo &a, const FileInfo &b) { return (b <= a); } private: @@ -132,14 +148,23 @@ namespace FileSystem { const FileInfo &GetInfo() const { return m_info; } size_t GetSize() const { return m_size; } - const char *GetData() const { assert(m_info.IsFile()); return m_data; } + const char *GetData() const + { + assert(m_info.IsFile()); + return m_data; + } StringRange AsStringRange() const { return StringRange(m_data, m_size); } ByteRange AsByteRange() const { return ByteRange(m_data, m_size); } protected: - FileData(const FileInfo &info, size_t size, char *data): - m_info(info), m_data(data), m_size(size) {} - FileData(const FileInfo &info): m_info(info), m_data(0), m_size(0) {} + FileData(const FileInfo &info, size_t size, char *data) : + m_info(info), + m_data(data), + m_size(size) {} + FileData(const FileInfo &info) : + m_info(info), + m_data(0), + m_size(0) {} FileInfo m_info; char *m_data; @@ -148,16 +173,18 @@ namespace FileSystem { class FileDataMalloc : public FileData { public: - FileDataMalloc(const FileInfo &info, size_t size): - FileData(info, size, static_cast(std::malloc(size))) {} - FileDataMalloc(const FileInfo &info, size_t size, char *data): + FileDataMalloc(const FileInfo &info, size_t size) : + FileData(info, size, static_cast(std::malloc(size))) {} + FileDataMalloc(const FileInfo &info, size_t size, char *data) : FileData(info, size, data) {} virtual ~FileDataMalloc() { std::free(m_data); } }; class FileSource { public: - explicit FileSource(const std::string &root, bool trusted = false): m_root(root), m_trusted(trusted) {} + explicit FileSource(const std::string &root, bool trusted = false) : + m_root(root), + m_trusted(trusted) {} virtual ~FileSource() {} const std::string &GetRoot() const { return m_root; } @@ -193,9 +220,9 @@ namespace FileSystem { }; // similar to fopen(path, "rb") - FILE* OpenReadStream(const std::string &path); + FILE *OpenReadStream(const std::string &path); // similar to fopen(path, "wb") - FILE* OpenWriteStream(const std::string &path, int flags = 0); + FILE *OpenWriteStream(const std::string &path, int flags = 0); }; class FileSourceUnion : public FileSource { @@ -216,16 +243,16 @@ namespace FileSystem { virtual bool ReadDirectory(const std::string &path, std::vector &output); private: - std::vector m_sources; + std::vector m_sources; }; class FileEnumerator { public: enum Flags { - IncludeDirs = 1, - IncludeSpecials = 2, - ExcludeFiles = 4, - Recurse = 8 + IncludeDirs = 1, + IncludeSpecials = 2, + ExcludeFiles = 4, + Recurse = 8 }; explicit FileEnumerator(FileSource &fs, int flags = 0); @@ -251,12 +278,18 @@ namespace FileSystem { } // namespace FileSystem inline std::string FileSystem::FileInfo::GetAbsoluteDir() const -{ return JoinPath(m_source->GetRoot(), GetDir()); } +{ + return JoinPath(m_source->GetRoot(), GetDir()); +} inline std::string FileSystem::FileInfo::GetAbsolutePath() const -{ return JoinPath(m_source->GetRoot(), GetPath()); } +{ + return JoinPath(m_source->GetRoot(), GetPath()); +} inline RefCountedPtr FileSystem::FileInfo::Read() const -{ return m_source->ReadFile(m_path); } +{ + return m_source->ReadFile(m_path); +} #endif diff --git a/src/FixedGuns.cpp b/src/FixedGuns.cpp index 2cf46505b..d35815ac1 100644 --- a/src/FixedGuns.cpp +++ b/src/FixedGuns.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "FixedGuns.h" -#include "GameSaveError.h" #include "Beam.h" +#include "GameSaveError.h" #include "StringF.h" FixedGuns::FixedGuns() @@ -34,7 +34,7 @@ bool FixedGuns::IsBeam(const int num) void FixedGuns::Init(DynamicBody *b) { - for (int i=0; iAddFeature( DynamicBody::FIXED_GUNS ); + b->AddFeature(DynamicBody::FIXED_GUNS); } -void FixedGuns::SaveToJson( Json &jsonObj, Space *space ) +void FixedGuns::SaveToJson(Json &jsonObj, Space *space) { Json gunArray = Json::array(); // Create JSON array to contain gun data. - for (int i = 0; i(); assert(Guns::GUNMOUNT_MAX == gunArray.size()); try { - for (unsigned int i = 0; i < Guns::GUNMOUNT_MAX; i++) - { + for (unsigned int i = 0; i < Guns::GUNMOUNT_MAX; i++) { Json gunArrayEl = gunArray[i]; m_is_firing[i] = gunArrayEl["state"]; @@ -90,16 +88,14 @@ void FixedGuns::LoadFromJson( const Json &jsonObj, Space *space ) } }; -void FixedGuns::InitGuns( SceneGraph::Model *m) +void FixedGuns::InitGuns(SceneGraph::Model *m) { - for (int num = 0; num < Guns::GUNMOUNT_MAX; num++) - { + for (int num = 0; num < Guns::GUNMOUNT_MAX; num++) { int found = 0; // probably 4 is fine 99% of the time (X-Wings) m_gun[num].locs.reserve(4); - // 32 is a crazy number... - for (int gun = 0; gun < 32; gun++) - { + // 32 is a crazy number... + for (int gun = 0; gun < 32; gun++) { const std::string tag = stringf("tag_gunmount_%0{d}_multi_%1{d}", num, gun); //"gunmount_0_multi_0"; const SceneGraph::MatrixTransform *mt = m->FindTagByName(tag); if (mt) { @@ -109,9 +105,7 @@ void FixedGuns::InitGuns( SceneGraph::Model *m) loc.pos = vector3d(trans.GetTranslate()); loc.dir = vector3d(trans.GetOrient().VectorZ()); m_gun[num].locs.push_back(loc); - } - else if (found == 0) - { + } else if (found == 0) { // look for legacy "tag_gunmount_0" or "tag_gunmount_1" tags const std::string tag = stringf("tag_gunmount_%0{d}", num); //"gunmount_0"; const SceneGraph::MatrixTransform *mt = m->FindTagByName(tag); @@ -124,17 +118,16 @@ void FixedGuns::InitGuns( SceneGraph::Model *m) m_gun[num].locs.push_back(loc); } break; // definitely no more "gun"s for this "num" if we've come down this path - } - else + } else break; } } } void FixedGuns::MountGun(const int num, const float recharge, const float lifespan, const float damage, const float length, - const float width, const bool mining, const Color& color, const float speed, const bool beam, const float heatrate, const float coolrate ) + const float width, const bool mining, const Color &color, const float speed, const bool beam, const float heatrate, const float coolrate) { - if(num >= Guns::GUNMOUNT_MAX) + if (num >= Guns::GUNMOUNT_MAX) return; // Here we have projectile data MORE recharge time m_is_firing[num] = false; @@ -152,11 +145,11 @@ void FixedGuns::MountGun(const int num, const float recharge, const float lifesp m_gun_present[num] = true; }; -void FixedGuns::UnMountGun( int num ) +void FixedGuns::UnMountGun(int num) { - if(num >= Guns::GUNMOUNT_MAX) + if (num >= Guns::GUNMOUNT_MAX) return; - if(!m_gun_present[num]) + if (!m_gun_present[num]) return; m_is_firing[num] = false; m_gun[num].recharge = 0; @@ -172,13 +165,13 @@ void FixedGuns::UnMountGun( int num ) m_gun_present[num] = false; } -bool FixedGuns::Fire( const int num, Body* b ) +bool FixedGuns::Fire(const int num, Body *b) { if (!m_gun_present[num]) return false; if (!m_is_firing[num]) return false; // Output("Firing gun %i, present\n", num); // Output(" is firing\n"); - if (m_recharge_stat[num]>0) return false; + if (m_recharge_stat[num] > 0) return false; // Output(" recharge stat <= 0\n"); if (m_temperature_stat[num] > 1.0) return false; // Output(" temperature stat <= 1.0\n"); @@ -188,36 +181,32 @@ bool FixedGuns::Fire( const int num, Body* b ) const int maxBarrels = std::min(size_t(m_gun[num].dual ? 2 : 1), m_gun[num].locs.size()); - for (int iBarrel = 0; iBarrel < maxBarrels; iBarrel++) - { + for (int iBarrel = 0; iBarrel < maxBarrels; iBarrel++) { const vector3d dir = (b->GetOrient() * vector3d(m_gun[num].locs[iBarrel].dir)).Normalized(); const vector3d pos = b->GetOrient() * vector3d(m_gun[num].locs[iBarrel].pos) + b->GetPosition(); - if (m_gun[num].projData.beam) - { + if (m_gun[num].projData.beam) { Beam::Add(b, m_gun[num].projData, pos, b->GetVelocity(), dir); - } - else - { + } else { const vector3d dirVel = m_gun[num].projData.speed * dir; Projectile::Add(b, m_gun[num].projData, pos, b->GetVelocity(), dirVel); } } - + return true; }; -void FixedGuns::UpdateGuns( float timeStep ) +void FixedGuns::UpdateGuns(float timeStep) { - for (int i=0; i locs; - float recharge; - float temp_heat_rate; - float temp_cool_rate; - bool dual; - ProjectileData projData; +private: + struct GunData { + struct GunLoc { + vector3d pos; + vector3d dir; }; + std::vector locs; + float recharge; + float temp_heat_rate; + float temp_cool_rate; + bool dual; + ProjectileData projData; + }; - bool m_is_firing[Guns::GUNMOUNT_MAX]; - float m_recharge_stat[Guns::GUNMOUNT_MAX]; - float m_temperature_stat[Guns::GUNMOUNT_MAX]; - //TODO: Make it a vector and rework struct Gun to have bool dir={Forward,Backward} - bool m_gun_present[Guns::GUNMOUNT_MAX]; - GunData m_gun[Guns::GUNMOUNT_MAX]; - float m_cooler_boost; + bool m_is_firing[Guns::GUNMOUNT_MAX]; + float m_recharge_stat[Guns::GUNMOUNT_MAX]; + float m_temperature_stat[Guns::GUNMOUNT_MAX]; + //TODO: Make it a vector and rework struct Gun to have bool dir={Forward,Backward} + bool m_gun_present[Guns::GUNMOUNT_MAX]; + GunData m_gun[Guns::GUNMOUNT_MAX]; + float m_cooler_boost; }; #endif // FIXEDGUNS_H diff --git a/src/FloatComparison.h b/src/FloatComparison.h index dbc404a1d..4bad6c69a 100644 --- a/src/FloatComparison.h +++ b/src/FloatComparison.h @@ -39,33 +39,38 @@ // bool is_nan(float x); // bool is_finite(float x); - // ==================================================================== // in the following code, IEEEFloatTraits::bool_type is used to limit // the application of the functions by SFINAE -template struct IEEEFloatTraits; +template +struct IEEEFloatTraits; // --- float function helpers template inline typename IEEEFloatTraits::float_type float_abs(T x) -{ return (x < T(0)) ? (-x) : x; } +{ + return (x < T(0)) ? (-x) : x; +} template inline typename IEEEFloatTraits::float_type float_max(T x, T y) -{ return (y > x) ? y : x; } +{ + return (y > x) ? y : x; +} template inline typename IEEEFloatTraits::float_type float_max(T x, T y, T z) -{ return float_max(x, float_max(y, z)); } +{ + return float_max(x, float_max(y, z)); +} // --- float property helpers template -inline typename IEEEFloatTraits::bool_type is_nan_bits - (const typename IEEEFloatTraits::uint_type& bits) +inline typename IEEEFloatTraits::bool_type is_nan_bits(const typename IEEEFloatTraits::uint_type &bits) { typedef typename IEEEFloatTraits::uint_type uint_type; const uint_type top = IEEEFloatTraits::TopBit; @@ -79,8 +84,7 @@ inline typename IEEEFloatTraits::bool_type is_nan_bits } template -inline typename IEEEFloatTraits::bool_type is_finite_bits - (const typename IEEEFloatTraits::uint_type& bits) +inline typename IEEEFloatTraits::bool_type is_finite_bits(const typename IEEEFloatTraits::uint_type &bits) { typedef typename IEEEFloatTraits::uint_type uint_type; const uint_type ebits = IEEEFloatTraits::ExponentBits; @@ -90,7 +94,8 @@ inline typename IEEEFloatTraits::bool_type is_finite_bits // --- infinity template -inline typename IEEEFloatTraits::bool_type is_finite(T x) { +inline typename IEEEFloatTraits::bool_type is_finite(T x) +{ #ifdef _MSC_VER return _finite(x); #else @@ -104,7 +109,10 @@ inline typename IEEEFloatTraits::bool_type is_finite(T x) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif -inline bool is_equal_exact(float a, float b) { return (a == b); } +inline bool is_equal_exact(float a, float b) +{ + return (a == b); +} inline bool is_equal_exact(double a, double b) { return (a == b); } inline bool is_zero_exact(float x) { return (x == 0.0f); } @@ -119,36 +127,31 @@ inline bool is_nan(double x) { return (x != x); } // --- relative & absolute error comparisons template -inline typename IEEEFloatTraits::bool_type is_equal_relative - (T a, T b, T tol = IEEEFloatTraits::DefaultRelTolerance()) +inline typename IEEEFloatTraits::bool_type is_equal_relative(T a, T b, T tol = IEEEFloatTraits::DefaultRelTolerance()) { return (float_abs(a - b) <= tol * float_max(float_abs(a), float_abs(b))); } template -inline typename IEEEFloatTraits::bool_type is_equal_absolute - (T a, T b, T tol = IEEEFloatTraits::DefaultAbsTolerance()) +inline typename IEEEFloatTraits::bool_type is_equal_absolute(T a, T b, T tol = IEEEFloatTraits::DefaultAbsTolerance()) { return (float_abs(a - b) <= tol); } template -inline typename IEEEFloatTraits::bool_type is_equal_general - (T a, T b, T rel_tol, T abs_tol) +inline typename IEEEFloatTraits::bool_type is_equal_general(T a, T b, T rel_tol, T abs_tol) { return (float_abs(a - b) <= float_max(abs_tol, rel_tol * float_max(float_abs(a), float_abs(b)))); } template -inline typename IEEEFloatTraits::bool_type is_equal_general - (T a, T b, T tol = IEEEFloatTraits::DefaultTolerance()) +inline typename IEEEFloatTraits::bool_type is_equal_general(T a, T b, T tol = IEEEFloatTraits::DefaultTolerance()) { return (float_abs(a - b) <= tol * float_max(T(1), float_abs(a), float_abs(b))); } template -inline typename IEEEFloatTraits::bool_type is_zero_general - (T x, T tol = IEEEFloatTraits::DefaultRelTolerance()) +inline typename IEEEFloatTraits::bool_type is_zero_general(T x, T tol = IEEEFloatTraits::DefaultRelTolerance()) { return (float_abs(x) <= tol); } @@ -156,7 +159,8 @@ inline typename IEEEFloatTraits::bool_type is_zero_general // --- ulp-based comparisons template -inline typename IEEEFloatTraits::int_type float_ulp_difference(T a, T b) { +inline typename IEEEFloatTraits::int_type float_ulp_difference(T a, T b) +{ typedef typename IEEEFloatTraits::FloatOrInt union_type; union_type afi, bfi; afi.f = a; @@ -171,9 +175,7 @@ inline typename IEEEFloatTraits::int_type float_ulp_difference(T a, T b) { // IEEEFloatTraits::bool_type used for SFINAE template -inline typename IEEEFloatTraits::bool_type is_equal_ulps - (T a, T b, typename IEEEFloatTraits::int_type max_ulps - = IEEEFloatTraits::DefaultUlpTolerance) +inline typename IEEEFloatTraits::bool_type is_equal_ulps(T a, T b, typename IEEEFloatTraits::int_type max_ulps = IEEEFloatTraits::DefaultUlpTolerance) { typedef typename IEEEFloatTraits::FloatOrInt union_type; typedef typename IEEEFloatTraits::int_type int_type; @@ -182,13 +184,12 @@ inline typename IEEEFloatTraits::bool_type is_equal_ulps bfi.f = b; // Infinities aren't close to anything except themselves - if ( (!is_finite_bits(afi.ui) && is_finite_bits(bfi.ui)) - || (is_finite_bits(afi.ui) && !is_finite_bits(bfi.ui))) - return false; + if ((!is_finite_bits(afi.ui) && is_finite_bits(bfi.ui)) || (is_finite_bits(afi.ui) && !is_finite_bits(bfi.ui))) + return false; // IEEE says NaNs are unequal to everything (even themselves) if (is_nan_bits(afi.ui) || is_nan_bits(bfi.ui)) - return false; + return false; // transform from sign-magnitude to two's-complement if (afi.i < 0) afi.ui = (IEEEFloatTraits::TopBit - afi.ui); @@ -205,8 +206,7 @@ template struct IEEEFloatTraits {}; template <> -struct IEEEFloatTraits -{ +struct IEEEFloatTraits { typedef double float_type; typedef bool bool_type; @@ -219,15 +219,11 @@ struct IEEEFloatTraits int_type i; }; - static const uint_type TopBit - = static_cast(1) << (sizeof(double)*8 - 1); - static const uint_type ExponentBits - = (~static_cast(0) << std::numeric_limits::digits) & ~TopBit; - static const uint_type MantissaBits - = ~TopBit & ~ExponentBits; + static const uint_type TopBit = static_cast(1) << (sizeof(double) * 8 - 1); + static const uint_type ExponentBits = (~static_cast(0) << std::numeric_limits::digits) & ~TopBit; + static const uint_type MantissaBits = ~TopBit & ~ExponentBits; - static const int_type DefaultUlpTolerance - = 16; + static const int_type DefaultUlpTolerance = 16; static double DefaultAbsTolerance() { return 1e-12; } static double DefaultRelTolerance() { return 1e-6; } @@ -236,8 +232,7 @@ struct IEEEFloatTraits }; template <> -struct IEEEFloatTraits -{ +struct IEEEFloatTraits { typedef float float_type; typedef bool bool_type; @@ -250,15 +245,11 @@ struct IEEEFloatTraits int_type i; }; - static const uint_type TopBit - = uint_type(1) << (sizeof(float)*8 - 1); - static const uint_type ExponentBits - = (~uint_type(0) << std::numeric_limits::digits) & ~TopBit; - static const uint_type MantissaBits - = ~TopBit & ~ExponentBits; + static const uint_type TopBit = uint_type(1) << (sizeof(float) * 8 - 1); + static const uint_type ExponentBits = (~uint_type(0) << std::numeric_limits::digits) & ~TopBit; + static const uint_type MantissaBits = ~TopBit & ~ExponentBits; - static const int_type DefaultUlpTolerance - = 4; + static const int_type DefaultUlpTolerance = 4; static float DefaultAbsTolerance() { return 1e-6f; } static float DefaultRelTolerance() { return 1e-5f; } diff --git a/src/FontCache.cpp b/src/FontCache.cpp index c308dce79..25501a705 100644 --- a/src/FontCache.cpp +++ b/src/FontCache.cpp @@ -2,14 +2,14 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "FontCache.h" -#include "text/TextureFont.h" #include "FileSystem.h" -#include "gui/GuiScreen.h" #include "Lang.h" +#include "gui/GuiScreen.h" +#include "text/TextureFont.h" RefCountedPtr FontCache::GetTextureFont(const std::string &name) { - std::map< std::string,RefCountedPtr >::iterator i = m_textureFonts.find(name); + std::map>::iterator i = m_textureFonts.find(name); if (i != m_textureFonts.end()) return (*i).second; @@ -18,7 +18,7 @@ RefCountedPtr FontCache::GetTextureFont(const std::string &na const Text::FontConfig config(name, scale[0], scale[1]); RefCountedPtr font(new Text::TextureFont(config, Gui::Screen::GetRenderer())); - m_textureFonts.insert(std::pair< std::string,RefCountedPtr >(name, font)); + m_textureFonts.insert(std::pair>(name, font)); return font; } diff --git a/src/FontCache.h b/src/FontCache.h index 828acf075..d1a7ef32d 100644 --- a/src/FontCache.h +++ b/src/FontCache.h @@ -4,10 +4,10 @@ #ifndef _FONTCACHE_H #define _FONTCACHE_H -#include -#include #include "RefCounted.h" #include "text/TextureFont.h" +#include +#include class FontCache { public: @@ -19,8 +19,7 @@ private: FontCache(const FontCache &); FontCache &operator=(const FontCache &); - std::map< std::string,RefCountedPtr > m_textureFonts; + std::map> m_textureFonts; }; #endif - diff --git a/src/Frame.cpp b/src/Frame.cpp index 8fa223303..286546a06 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -3,14 +3,14 @@ #include "Frame.h" #include "Body.h" +#include "Game.h" +#include "GameSaveError.h" +#include "JsonUtils.h" +#include "Pi.h" +#include "Sfx.h" #include "Space.h" #include "collider/collider.h" -#include "Sfx.h" #include "galaxy/StarSystem.h" -#include "Pi.h" -#include "Game.h" -#include "JsonUtils.h" -#include "GameSaveError.h" #include Frame::Frame() @@ -40,8 +40,7 @@ void Frame::ToJson(Json &frameObj, Frame *f, Space *space) frameObj["index_for_astro_body"] = space->GetIndexForBody(f->m_astroBody); Json childFrameArray = Json::array(); // Create JSON array to contain child frame data. - for (Frame* kid : f->GetChildren()) - { + for (Frame *kid : f->GetChildren()) { Json childFrameArrayEl = Json::object(); // Create JSON object to contain child frame. Frame::ToJson(childFrameArrayEl, kid, space); childFrameArray.push_back(childFrameArrayEl); // Append child frame object to array. @@ -70,7 +69,7 @@ Frame *Frame::FromJson(const Json &frameObj, Space *space, Frame *parent, double f->m_vel = vector3d(0.0); // m_vel is set to zero. if (frameObj.count("child_frames") && frameObj["child_frames"].is_array()) { - Json childFrameArray = frameObj["child_frames"]; + Json childFrameArray = frameObj["child_frames"]; for (unsigned int i = 0; i < childFrameArray.size(); ++i) { f->m_children.push_back(FromJson(childFrameArray[i], space, f, at_time)); } @@ -91,7 +90,7 @@ void Frame::PostUnserializeFixup(Frame *f, Space *space) { f->UpdateRootRelativeVars(); f->m_astroBody = space->GetBodyByIndex(f->m_astroBodyIndex); - for (Frame* kid : f->GetChildren()) + for (Frame *kid : f->GetChildren()) PostUnserializeFixup(kid, space); } @@ -119,15 +118,14 @@ Frame::~Frame() { m_sfx.reset(); delete m_collisionSpace; - for (Frame* kid : m_children) + for (Frame *kid : m_children) delete kid; } void Frame::RemoveChild(Frame *f) { PROFILE_SCOPED() - const std::vector::iterator it - = std::find(m_children.begin(), m_children.end(), f); + const std::vector::iterator it = std::find(m_children.begin(), m_children.end(), f); if (it != m_children.end()) m_children.erase(it); } @@ -138,54 +136,68 @@ void Frame::AddStaticGeom(Geom *g) { m_collisionSpace->AddStaticGeom(g); } void Frame::RemoveStaticGeom(Geom *g) { m_collisionSpace->RemoveStaticGeom(g); } void Frame::SetPlanetGeom(double radius, Body *obj) { - m_collisionSpace->SetSphere(vector3d(0,0,0), radius, static_cast(obj)); + m_collisionSpace->SetSphere(vector3d(0, 0, 0), radius, static_cast(obj)); } // doesn't consider stasis velocity vector3d Frame::GetVelocityRelTo(const Frame *relTo) const { - if (this == relTo) return vector3d(0,0,0); // early-out to avoid unnecessary computation + if (this == relTo) return vector3d(0, 0, 0); // early-out to avoid unnecessary computation vector3d diff = m_rootVel - relTo->m_rootVel; - if (relTo->IsRotFrame()) return diff * relTo->m_rootOrient; - else return diff; + if (relTo->IsRotFrame()) + return diff * relTo->m_rootOrient; + else + return diff; } vector3d Frame::GetPositionRelTo(const Frame *relTo) const { // early-outs for simple cases, required for accuracy in large systems if (this == relTo) return vector3d(0, 0, 0); - if (GetParent() == relTo) return m_pos; // relative to parent - if (relTo->GetParent() == this) { // relative to child - if (!relTo->IsRotFrame()) return -relTo->m_pos; - else return -relTo->m_pos * relTo->m_orient; + if (GetParent() == relTo) return m_pos; // relative to parent + if (relTo->GetParent() == this) { // relative to child + if (!relTo->IsRotFrame()) + return -relTo->m_pos; + else + return -relTo->m_pos * relTo->m_orient; } - if (relTo->GetParent() == GetParent()) { // common parent - if (!relTo->IsRotFrame()) return m_pos - relTo->m_pos; - else return (m_pos - relTo->m_pos) * relTo->m_orient; + if (relTo->GetParent() == GetParent()) { // common parent + if (!relTo->IsRotFrame()) + return m_pos - relTo->m_pos; + else + return (m_pos - relTo->m_pos) * relTo->m_orient; } vector3d diff = m_rootPos - relTo->m_rootPos; - if (relTo->IsRotFrame()) return diff * relTo->m_rootOrient; - else return diff; + if (relTo->IsRotFrame()) + return diff * relTo->m_rootOrient; + else + return diff; } vector3d Frame::GetInterpPositionRelTo(const Frame *relTo) const { // early-outs for simple cases, required for accuracy in large systems - if (this == relTo) return vector3d(0,0,0); - if (GetParent() == relTo) return m_interpPos; // relative to parent - if (relTo->GetParent() == this) { // relative to child - if (!relTo->IsRotFrame()) return -relTo->m_interpPos; - else return -relTo->m_interpPos * relTo->m_interpOrient; + if (this == relTo) return vector3d(0, 0, 0); + if (GetParent() == relTo) return m_interpPos; // relative to parent + if (relTo->GetParent() == this) { // relative to child + if (!relTo->IsRotFrame()) + return -relTo->m_interpPos; + else + return -relTo->m_interpPos * relTo->m_interpOrient; } - if (relTo->GetParent() == GetParent()) { // common parent - if (!relTo->IsRotFrame()) return m_interpPos - relTo->m_interpPos; - else return (m_interpPos - relTo->m_interpPos) * relTo->m_interpOrient; + if (relTo->GetParent() == GetParent()) { // common parent + if (!relTo->IsRotFrame()) + return m_interpPos - relTo->m_interpPos; + else + return (m_interpPos - relTo->m_interpPos) * relTo->m_interpOrient; } vector3d diff = m_rootInterpPos - relTo->m_rootInterpPos; - if (relTo->IsRotFrame()) return diff * relTo->m_rootInterpOrient; - else return diff; + if (relTo->IsRotFrame()) + return diff * relTo->m_rootInterpOrient; + else + return diff; } matrix3x3d Frame::GetOrientRelTo(const Frame *relTo) const @@ -198,7 +210,7 @@ matrix3x3d Frame::GetInterpOrientRelTo(const Frame *relTo) const { if (this == relTo) return matrix3x3d::Identity(); return relTo->m_rootInterpOrient.Transpose() * m_rootInterpOrient; -/* if (IsRotFrame()) { + /* if (IsRotFrame()) { if (relTo->IsRotFrame()) return m_interpOrient * relTo->m_interpOrient.Transpose(); else return m_interpOrient; } @@ -210,23 +222,23 @@ matrix3x3d Frame::GetInterpOrientRelTo(const Frame *relTo) const void Frame::UpdateInterpTransform(double alpha) { PROFILE_SCOPED() - m_interpPos = alpha*m_pos + (1.0-alpha)*m_oldPos; + m_interpPos = alpha * m_pos + (1.0 - alpha) * m_oldPos; - double len = m_oldAngDisplacement * (1.0-alpha); - if (!is_zero_exact(len)) { // very small values are normal here - matrix3x3d rot = matrix3x3d::RotateY(len); // RotateY is backwards + double len = m_oldAngDisplacement * (1.0 - alpha); + if (!is_zero_exact(len)) { // very small values are normal here + matrix3x3d rot = matrix3x3d::RotateY(len); // RotateY is backwards m_interpOrient = m_orient * rot; - } - else m_interpOrient = m_orient; + } else + m_interpOrient = m_orient; - if (!m_parent) ClearMovement(); + if (!m_parent) + ClearMovement(); else { - m_rootInterpPos = m_parent->m_rootInterpOrient * m_interpPos - + m_parent->m_rootInterpPos; + m_rootInterpPos = m_parent->m_rootInterpOrient * m_interpPos + m_parent->m_rootInterpPos; m_rootInterpOrient = m_parent->m_rootInterpOrient * m_interpOrient; } - for (Frame* kid : m_children) + for (Frame *kid : m_children) kid->UpdateInterpTransform(alpha); } @@ -234,7 +246,8 @@ void Frame::GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d & { matrix3x3d forient = fFrom->GetOrientRelTo(fTo); vector3d fpos = fFrom->GetPositionRelTo(fTo); - m = forient; m.SetTranslate(fpos); + m = forient; + m.SetTranslate(fpos); } void Frame::ClearMovement() @@ -255,41 +268,44 @@ void Frame::UpdateOrbitRails(double time, double timestep) // update frame position and velocity if (m_parent && m_sbody && !IsRotFrame()) { m_pos = m_sbody->GetOrbit().OrbitalPosAtTime(time); - vector3d pos2 = m_sbody->GetOrbit().OrbitalPosAtTime(time+timestep); + vector3d pos2 = m_sbody->GetOrbit().OrbitalPosAtTime(time + timestep); m_vel = (pos2 - m_pos) / timestep; } // temporary test thing - else m_pos = m_pos + m_vel * timestep; + else + m_pos = m_pos + m_vel * timestep; // update frame rotation double ang = fmod(m_angSpeed * time, 2.0 * M_PI); - if (!is_zero_exact(ang)) { // frequently used with e^-10 etc - matrix3x3d rot = matrix3x3d::RotateY(-ang); // RotateY is backwards - m_orient = m_initialOrient * rot; // angvel always +y + if (!is_zero_exact(ang)) { // frequently used with e^-10 etc + matrix3x3d rot = matrix3x3d::RotateY(-ang); // RotateY is backwards + m_orient = m_initialOrient * rot; // angvel always +y } - UpdateRootRelativeVars(); // update root-relative pos/vel/orient + UpdateRootRelativeVars(); // update root-relative pos/vel/orient - for (Frame* kid : m_children) + for (Frame *kid : m_children) kid->UpdateOrbitRails(time, timestep); } -void Frame::SetInitialOrient(const matrix3x3d &m, double time) { +void Frame::SetInitialOrient(const matrix3x3d &m, double time) +{ m_initialOrient = m; double ang = fmod(m_angSpeed * time, 2.0 * M_PI); - if (!is_zero_exact(ang)) { // frequently used with e^-10 etc - matrix3x3d rot = matrix3x3d::RotateY(-ang); // RotateY is backwards - m_orient = m_initialOrient * rot; // angvel always +y + if (!is_zero_exact(ang)) { // frequently used with e^-10 etc + matrix3x3d rot = matrix3x3d::RotateY(-ang); // RotateY is backwards + m_orient = m_initialOrient * rot; // angvel always +y } else { m_orient = m_initialOrient; } } -void Frame::SetOrient(const matrix3x3d &m, double time) { +void Frame::SetOrient(const matrix3x3d &m, double time) +{ m_orient = m; double ang = fmod(m_angSpeed * time, 2.0 * M_PI); - if (!is_zero_exact(ang)) { // frequently used with e^-10 etc - matrix3x3d rot = matrix3x3d::RotateY(ang); // RotateY is backwards - m_initialOrient = m_orient * rot; // angvel always +y + if (!is_zero_exact(ang)) { // frequently used with e^-10 etc + matrix3x3d rot = matrix3x3d::RotateY(ang); // RotateY is backwards + m_initialOrient = m_orient * rot; // angvel always +y } else { m_initialOrient = m_orient; } @@ -299,10 +315,9 @@ void Frame::UpdateRootRelativeVars() { // update pos & vel relative to parent frame if (!m_parent) { - m_rootPos = m_rootVel = vector3d(0,0,0); + m_rootPos = m_rootVel = vector3d(0, 0, 0); m_rootOrient = matrix3x3d::Identity(); - } - else { + } else { m_rootPos = m_parent->m_rootOrient * m_pos + m_parent->m_rootPos; m_rootVel = m_parent->m_rootOrient * m_vel + m_parent->m_rootVel; m_rootOrient = m_parent->m_rootOrient * m_orient; diff --git a/src/Frame.h b/src/Frame.h index 42d91aeb2..2f121ac76 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -4,11 +4,11 @@ #ifndef _FRAME_H #define _FRAME_H -#include "libs.h" #include "IterationProxy.h" #include "JsonFwd.h" -#include +#include "libs.h" #include +#include class Body; class CollisionSpace; @@ -21,7 +21,9 @@ class Space; class Frame { public: - enum { FLAG_DEFAULT=(0), FLAG_ROTATING=(1<<1), FLAG_HAS_ROT=(1<<2) }; + enum { FLAG_DEFAULT = (0), + FLAG_ROTATING = (1 << 1), + FLAG_HAS_ROT = (1 << 2) }; Frame(); Frame(Frame *parent, const char *label); @@ -54,7 +56,11 @@ public: const Frame *GetRotFrame() const { return HasRotFrame() ? m_children.front() : this; } Frame *GetRotFrame() { return HasRotFrame() ? m_children.front() : this; } - void SetBodies(SystemBody *s, Body *b) { m_sbody = s; m_astroBody = b; } + void SetBodies(SystemBody *s, Body *b) + { + m_sbody = s; + m_astroBody = b; + } SystemBody *GetSystemBody() const { return m_sbody; } Body *GetBody() const { return m_astroBody; } @@ -62,8 +68,8 @@ public: void RemoveChild(Frame *f); bool HasChildren() const { return !m_children.empty(); } unsigned GetNumChildren() const { return static_cast(m_children.size()); } - IterationProxy > GetChildren() { return MakeIterationProxy(m_children); } - const IterationProxy > GetChildren() const { return MakeIterationProxy(m_children); } + IterationProxy> GetChildren() { return MakeIterationProxy(m_children); } + const IterationProxy> GetChildren() const { return MakeIterationProxy(m_children); } void AddGeom(Geom *); void RemoveGeom(Geom *); @@ -78,7 +84,7 @@ public: // For an object in a rotating frame, relative to non-rotating frames it // must attain this velocity within rotating frame to be stationary. - vector3d GetStasisVelocity(const vector3d &pos) const { return -vector3d(0,m_angSpeed,0).Cross(pos); } + vector3d GetStasisVelocity(const vector3d &pos) const { return -vector3d(0, m_angSpeed, 0).Cross(pos); } vector3d GetPositionRelTo(const Frame *relTo) const; vector3d GetVelocityRelTo(const Frame *relTo) const; @@ -91,16 +97,16 @@ public: static void GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m); - std::unique_ptr m_sfx; // the last survivor. actually m_children is pretty grim too. + std::unique_ptr m_sfx; // the last survivor. actually m_children is pretty grim too. private: void Init(Frame *parent, const char *label, unsigned int flags); void UpdateRootRelativeVars(); - Frame *m_parent; // if parent is null then frame position is absolute - std::vector m_children; // child frames, first may be rotating - SystemBody *m_sbody; // points to SBodies in Pi::current_system - Body *m_astroBody; // if frame contains a star or planet or something + Frame *m_parent; // if parent is null then frame position is absolute + std::vector m_children; // child frames, first may be rotating + SystemBody *m_sbody; // points to SBodies in Pi::current_system + Body *m_astroBody; // if frame contains a star or planet or something vector3d m_pos; vector3d m_oldPos; @@ -109,7 +115,7 @@ private: matrix3x3d m_orient; matrix3x3d m_interpOrient; vector3d m_vel; // note we don't use this to move frame. rather, - // orbital rails determine velocity. + // orbital rails determine velocity. double m_angSpeed; // this however *is* directly applied (for rotating frames) double m_oldAngDisplacement; std::string m_label; @@ -117,11 +123,11 @@ private: int m_flags; CollisionSpace *m_collisionSpace; - vector3d m_rootVel; // velocity, position and orient relative to root frame - vector3d m_rootPos; // updated by UpdateOrbitRails + vector3d m_rootVel; // velocity, position and orient relative to root frame + vector3d m_rootPos; // updated by UpdateOrbitRails matrix3x3d m_rootOrient; - vector3d m_rootInterpPos; // interp position and orient relative to root frame - matrix3x3d m_rootInterpOrient; // updated by UpdateInterpTransform + vector3d m_rootInterpPos; // interp position and orient relative to root frame + matrix3x3d m_rootInterpOrient; // updated by UpdateInterpTransform int m_astroBodyIndex; // deserialisation }; diff --git a/src/GZipFormat.cpp b/src/GZipFormat.cpp index d5c5f644e..8261f208e 100644 --- a/src/GZipFormat.cpp +++ b/src/GZipFormat.cpp @@ -1,7 +1,7 @@ #include "GZipFormat.h" -#include -#include #include +#include +#include extern "C" { #include "miniz/miniz.h" @@ -9,17 +9,17 @@ extern "C" { namespace { enum GZipFlags { - FLAG_TEXT = 1, - FLAG_HCRC = 2, // Header CRC included - FLAG_EXTRA = 4, - FLAG_NAME = 8, + FLAG_TEXT = 1, + FLAG_HCRC = 2, // Header CRC included + FLAG_EXTRA = 4, + FLAG_NAME = 8, FLAG_COMMENT = 16, - FLAGS_ALL = (FLAG_TEXT | FLAG_HCRC | FLAG_EXTRA | FLAG_NAME | FLAG_COMMENT), + FLAGS_ALL = (FLAG_TEXT | FLAG_HCRC | FLAG_EXTRA | FLAG_NAME | FLAG_COMMENT), }; enum GZipCompressionModes { - CM_DEFLATE = 8, // The only one defined in the RFC (and the one we need). + CM_DEFLATE = 8, // The only one defined in the RFC (and the one we need). }; enum GZipHeaderSizes { @@ -28,36 +28,44 @@ namespace { }; // Streaming output function for tdefl_compress_mem_to_output. - static mz_bool PutBytesToString(const void *buf, int len, void *user) { - std::string *out = static_cast(user); - out->append(static_cast(buf), len); + static mz_bool PutBytesToString(const void *buf, int len, void *user) + { + std::string *out = static_cast(user); + out->append(static_cast(buf), len); return MZ_TRUE; } - static uint32_t ReadLE32(const unsigned char *data) { - return - (uint32_t(data[0]) << 0) | - (uint32_t(data[1]) << 8) | + static uint32_t ReadLE32(const unsigned char *data) + { + return (uint32_t(data[0]) << 0) | + (uint32_t(data[1]) << 8) | (uint32_t(data[2]) << 16) | (uint32_t(data[3]) << 24); } - static void WriteLE32(unsigned char *out, uint32_t value) { - out[0] = (value >> 0) & 0xffu; - out[1] = (value >> 8) & 0xffu; + static void WriteLE32(unsigned char *out, uint32_t value) + { + out[0] = (value >> 0) & 0xffu; + out[1] = (value >> 8) & 0xffu; out[2] = (value >> 16) & 0xffu; out[3] = (value >> 24) & 0xffu; } -} +} // namespace -bool gzip::IsGZipFormat(const unsigned char *data, size_t length) { +bool gzip::IsGZipFormat(const unsigned char *data, size_t length) +{ // (This assumes it's possible to provide 0 bytes of compressed data, which is probably not true). - if (length < BASE_HEADER_SIZE + BASE_FOOTER_SIZE) { return false; } - if (data[0] != 0x1fu || data[1] != 0x8bu) { return false; } + if (length < BASE_HEADER_SIZE + BASE_FOOTER_SIZE) { + return false; + } + if (data[0] != 0x1fu || data[1] != 0x8bu) { + return false; + } return true; } -std::string gzip::DecompressDeflateOrGZip(const unsigned char *data, size_t length) { +std::string gzip::DecompressDeflateOrGZip(const unsigned char *data, size_t length) +{ assert(data != nullptr); if (gzip::IsGZipFormat(data, length)) { return gzip::DecompressGZip(data, length); @@ -67,7 +75,8 @@ std::string gzip::DecompressDeflateOrGZip(const unsigned char *data, size_t leng } } -std::string gzip::DecompressGZip(const unsigned char *data, size_t length) { +std::string gzip::DecompressGZip(const unsigned char *data, size_t length) +{ assert(data != nullptr); assert(length >= BASE_HEADER_SIZE + BASE_FOOTER_SIZE); @@ -75,48 +84,64 @@ std::string gzip::DecompressGZip(const unsigned char *data, size_t length) { const unsigned char *at_footer = data + (length - BASE_FOOTER_SIZE); // We only know about DEFLATE. - if (at_header[2] != CM_DEFLATE) { throw gzip::DecompressionFailedException(); } + if (at_header[2] != CM_DEFLATE) { + throw gzip::DecompressionFailedException(); + } int gzip_flags = at_header[3]; // There are not supposed to be any unknown flags! - if (gzip_flags & ~FLAGS_ALL) { throw gzip::DecompressionFailedException(); } + if (gzip_flags & ~FLAGS_ALL) { + throw gzip::DecompressionFailedException(); + } const unsigned char *at_data = at_header + BASE_HEADER_SIZE; assert(at_data <= at_footer); size_t data_length = length - BASE_HEADER_SIZE + BASE_FOOTER_SIZE; if (gzip_flags & FLAG_EXTRA) { - if (data_length < 2) { throw gzip::DecompressionFailedException(); } + if (data_length < 2) { + throw gzip::DecompressionFailedException(); + } size_t xlen = uint8_t(at_data[0]) | (uint8_t(at_data[1]) << 8); - xlen += 2; // Add the two bytes for the length itself. - if (data_length < xlen) { throw gzip::DecompressionFailedException(); } + xlen += 2; // Add the two bytes for the length itself. + if (data_length < xlen) { + throw gzip::DecompressionFailedException(); + } at_data += xlen; assert(at_data <= at_footer); data_length = at_footer - at_data; } if (gzip_flags & FLAG_NAME) { - const unsigned char *name_end = static_cast(std::memchr(at_data, 0, data_length)); - if (!name_end) { throw gzip::DecompressionFailedException(); } - at_data = name_end + 1; // +1 to skip the null terminator. + const unsigned char *name_end = static_cast(std::memchr(at_data, 0, data_length)); + if (!name_end) { + throw gzip::DecompressionFailedException(); + } + at_data = name_end + 1; // +1 to skip the null terminator. assert(at_data <= at_footer); data_length = at_footer - at_data; } if (gzip_flags & FLAG_COMMENT) { - const unsigned char *comment_end = static_cast(std::memchr(at_data, 0, data_length)); - if (!comment_end) { throw gzip::DecompressionFailedException(); } - at_data = comment_end + 1; // +1 to skip the null terminator. + const unsigned char *comment_end = static_cast(std::memchr(at_data, 0, data_length)); + if (!comment_end) { + throw gzip::DecompressionFailedException(); + } + at_data = comment_end + 1; // +1 to skip the null terminator. assert(at_data <= at_footer); data_length = at_footer - at_data; } if (gzip_flags & FLAG_HCRC) { - if (data_length < 2) { throw gzip::DecompressionFailedException(); } + if (data_length < 2) { + throw gzip::DecompressionFailedException(); + } uint32_t true_crc = mz_crc32(MZ_CRC32_INIT, at_header, (at_data - at_header)); - true_crc &= 0xffffu; // Only care about the bottom 16 bits. + true_crc &= 0xffffu; // Only care about the bottom 16 bits. uint32_t file_crc = uint8_t(at_data[0]) | (uint8_t(at_data[1]) << 8); - if (true_crc != file_crc) { throw gzip::DecompressionFailedException(); } + if (true_crc != file_crc) { + throw gzip::DecompressionFailedException(); + } at_data += 2; data_length -= 2; assert(at_data <= at_footer); @@ -125,57 +150,67 @@ std::string gzip::DecompressGZip(const unsigned char *data, size_t length) { std::string out; assert(at_data + data_length == at_footer); - bool inflate_success = tinfl_decompress_mem_to_callback(static_cast(at_data), &data_length, &PutBytesToString, static_cast(&out), 0); - if (!inflate_success) { throw gzip::DecompressionFailedException(); } + bool inflate_success = tinfl_decompress_mem_to_callback(static_cast(at_data), &data_length, &PutBytesToString, static_cast(&out), 0); + if (!inflate_success) { + throw gzip::DecompressionFailedException(); + } - uint32_t true_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(out.data()), out.size()); + uint32_t true_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(out.data()), out.size()); uint32_t crc_from_file = ReadLE32(at_footer + 0); uint32_t size_from_header = ReadLE32(at_footer + 4); - if (true_crc != crc_from_file) { throw gzip::DecompressionFailedException(); } - if (size_from_header != static_cast(out.size())) { throw gzip::DecompressionFailedException(); } + if (true_crc != crc_from_file) { + throw gzip::DecompressionFailedException(); + } + if (size_from_header != static_cast(out.size())) { + throw gzip::DecompressionFailedException(); + } return out; } -std::string gzip::DecompressRawDeflate(const unsigned char *data, size_t length) { +std::string gzip::DecompressRawDeflate(const unsigned char *data, size_t length) +{ assert(data != nullptr); std::string out; size_t in_size = length; - bool success = tinfl_decompress_mem_to_callback(static_cast(data), &in_size, &PutBytesToString, static_cast(&out), 0); - if (!success) { throw gzip::DecompressionFailedException(); } + bool success = tinfl_decompress_mem_to_callback(static_cast(data), &in_size, &PutBytesToString, static_cast(&out), 0); + if (!success) { + throw gzip::DecompressionFailedException(); + } return out; } -std::string gzip::CompressGZip(const std::string &data, const std::string &inner_file_name) { +std::string gzip::CompressGZip(const std::string &data, const std::string &inner_file_name) +{ std::string out; // The base GZip header. const unsigned char header_bytes[10] = { 31, 139, 8, FLAG_HCRC | FLAG_NAME, 0, 0, 0, 0, 0, 255 }; - out.append(reinterpret_cast(header_bytes), sizeof(header_bytes)); + out.append(reinterpret_cast(header_bytes), sizeof(header_bytes)); // Add inner file name, *including* null terminator (c_str() ensures that the data is null terminated). out.append(inner_file_name.c_str(), inner_file_name.size() + 1); // Add 16-bit header-CRC. - uint32_t header_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(out.data()), out.size()); + uint32_t header_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(out.data()), out.size()); const unsigned char crc_buf[2] = { static_cast((header_crc >> 0) & 0xffu), static_cast((header_crc >> 8) & 0xffu), }; - out.append(reinterpret_cast(crc_buf), sizeof(crc_buf)); + out.append(reinterpret_cast(crc_buf), sizeof(crc_buf)); - bool success = tdefl_compress_mem_to_output(data.data(), data.size(), &PutBytesToString, static_cast(&out), TDEFL_DEFAULT_MAX_PROBES); + bool success = tdefl_compress_mem_to_output(data.data(), data.size(), &PutBytesToString, static_cast(&out), TDEFL_DEFAULT_MAX_PROBES); if (!success) { throw gzip::CompressionFailedException(); } unsigned char footer_bytes[8]; - uint32_t data_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(data.data()), data.size()); + uint32_t data_crc = mz_crc32(MZ_CRC32_INIT, reinterpret_cast(data.data()), data.size()); WriteLE32(footer_bytes + 0, data_crc); // GZip specifies that size is written little-endian, modulo 2^32 // (ie, if size is really > 2^32 we just chop off the high bits). WriteLE32(footer_bytes + 4, data.size()); - out.append(reinterpret_cast(footer_bytes), sizeof(footer_bytes)); + out.append(reinterpret_cast(footer_bytes), sizeof(footer_bytes)); return out; } diff --git a/src/GZipFormat.h b/src/GZipFormat.h index ef6821f29..206fd1986 100644 --- a/src/GZipFormat.h +++ b/src/GZipFormat.h @@ -34,6 +34,6 @@ namespace gzip { // If compression fails it throws an exception. // Parameter 'inner_file_name' is the name written in the GZip header as the file name of the compressed block. std::string CompressGZip(const std::string &data, const std::string &inner_file_name); -} +} // namespace gzip #endif diff --git a/src/Game.cpp b/src/Game.cpp index 784548237..6b2f6d6e2 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -2,33 +2,33 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Game.h" -#include "Factions.h" -#include "Space.h" -#include "Player.h" #include "Body.h" -#include "SpaceStation.h" -#include "HyperspaceCloud.h" -#include "Pi.h" -#include "ShipCpanel.h" -#include "Sfx.h" -#include "MathUtil.h" -#include "SectorView.h" -#include "WorldView.h" #include "DeathView.h" -#include "SystemView.h" -#include "SystemInfoView.h" -#include "UIView.h" -#include "LuaEvent.h" -#include "LuaRef.h" -#include "ObjectViewerView.h" +#include "Factions.h" #include "FileSystem.h" #include "GZipFormat.h" +#include "GameSaveError.h" +#include "HyperspaceCloud.h" +#include "LuaEvent.h" +#include "LuaRef.h" +#include "MathUtil.h" +#include "ObjectViewerView.h" +#include "Pi.h" +#include "Player.h" +#include "SectorView.h" +#include "Sfx.h" +#include "ShipCpanel.h" +#include "Space.h" +#include "SpaceStation.h" +#include "SystemInfoView.h" +#include "SystemView.h" +#include "UIView.h" +#include "WorldView.h" +#include "galaxy/GalaxyGenerator.h" #include "graphics/Renderer.h" #include "ui/Context.h" -#include "galaxy/GalaxyGenerator.h" -#include "GameSaveError.h" -static const int s_saveVersion = 85; +static const int s_saveVersion = 85; Game::Game(const SystemPath &path, double time) : m_galaxy(GalaxyGenerator::Create()), @@ -77,11 +77,11 @@ Game::Game(const SystemPath &path, double time) : m_player->SetFrame(b->GetFrame()); if (b->GetType() == Object::SPACESTATION) { - m_player->SetDockedWith(static_cast(b), 0); + m_player->SetDockedWith(static_cast(b), 0); } else { const SystemBody *sbody = b->GetSystemBody(); - m_player->SetPosition(vector3d(0, 1.5*sbody->GetRadius(), 0)); - m_player->SetVelocity(vector3d(0,0,0)); + m_player->SetPosition(vector3d(0, 1.5 * sbody->GetRadius(), 0)); + m_player->SetVelocity(vector3d(0, 0, 0)); } CreateViews(); @@ -119,9 +119,9 @@ Game::~Game() } Game::Game(const Json &jsonObj) : -m_timeAccel(TIMEACCEL_PAUSED), -m_requestedTimeAccel(TIMEACCEL_PAUSED), -m_forceTimeAccel(false) + m_timeAccel(TIMEACCEL_PAUSED), + m_requestedTimeAccel(TIMEACCEL_PAUSED), + m_forceTimeAccel(false) { try { int version = jsonObj["version"]; @@ -154,14 +154,14 @@ m_forceTimeAccel(false) m_space.reset(new Space(this, m_galaxy, jsonObj, m_time)); unsigned int player = jsonObj["player"]; - m_player.reset(static_cast(m_space->GetBodyByIndex(player))); + m_player.reset(static_cast(m_space->GetBodyByIndex(player))); assert(!m_player->IsDead()); // Pioneer does not support necromancy // hyperspace clouds being brought over from the previous system Json hyperspaceCloudArray = jsonObj["hyperspace_clouds"].get(); for (Uint32 i = 0; i < hyperspaceCloudArray.size(); i++) { - m_hyperspaceClouds.push_back(static_cast(Body::FromJson(hyperspaceCloudArray[i], 0))); + m_hyperspaceClouds.push_back(static_cast(Body::FromJson(hyperspaceCloudArray[i], 0))); } } catch (Json::type_error &) { throw SavedGameCorruptException(); @@ -205,8 +205,7 @@ void Game::ToJson(Json &jsonObj) // hyperspace clouds being brought over from the previous system Json hyperspaceCloudArray = Json::array(); // Create JSON array to contain hyperspace cloud data. - for (std::list::const_iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) - { + for (std::list::const_iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) { Json hyperspaceCloudArrayEl = Json::object(); // Create JSON object to contain hyperspace cloud. (*i)->ToJson(hyperspaceCloudArrayEl, m_space.get()); hyperspaceCloudArray.push_back(hyperspaceCloudArrayEl); // Append hyperspace cloud object to array. @@ -268,7 +267,7 @@ void Game::ToJson(Json &jsonObj) void Game::TimeStep(float step) { PROFILE_SCOPED() - m_time += step; // otherwise planets lag time accel changes by a frame + m_time += step; // otherwise planets lag time accel changes by a frame if (m_state == STATE_HYPERSPACE && Pi::game->GetTime() >= m_hyperspaceEndTime) m_time = m_hyperspaceEndTime; @@ -283,8 +282,7 @@ void Game::TimeStep(float step) SwitchToNormalSpace(); m_player->EnterSystem(); RequestTimeAccel(TIMEACCEL_1X); - } - else + } else m_hyperspaceProgress += step; return; } @@ -315,8 +313,8 @@ bool Game::UpdateTimeAccel() // force down to timeaccel 1 during the docking sequence or when just initiating hyperspace else if (m_player->GetFlightState() == Ship::DOCKING || - m_player->GetFlightState() == Ship::JUMPING || - m_player->GetFlightState() == Ship::UNDOCKING) { + m_player->GetFlightState() == Ship::JUMPING || + m_player->GetFlightState() == Ship::UNDOCKING) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); RequestTimeAccel(newTimeAccel); } @@ -330,13 +328,13 @@ bool Game::UpdateTimeAccel() if (!m_forceTimeAccel) { - // if not forced - limit timeaccel to 10x when other ships are close + // if not forced - limit timeaccel to 10x when other ships are close if (m_player->GetAlertState() == Ship::ALERT_SHIP_NEARBY) newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); - // if not forced - check if we aren't too near to objects for timeaccel + // if not forced - check if we aren't too near to objects for timeaccel else { - for (const Body* b : m_space->GetBodies()) { + for (const Body *b : m_space->GetBodies()) { if (b == m_player.get()) continue; if (b->IsType(Object::HYPERSPACECLOUD)) continue; @@ -346,28 +344,28 @@ bool Game::UpdateTimeAccel() if (dist < 1000.0) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1X); - } else if (dist < std::min(rad+0.0001*AU, rad*1.1)) { + } else if (dist < std::min(rad + 0.0001 * AU, rad * 1.1)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); - } else if (dist < std::min(rad+0.001*AU, rad*5.0)) { + } else if (dist < std::min(rad + 0.001 * AU, rad * 5.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_100X); - } else if (dist < std::min(rad+0.01*AU,rad*10.0)) { + } else if (dist < std::min(rad + 0.01 * AU, rad * 10.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1000X); - } else if (dist < std::min(rad+0.1*AU, rad*1000.0)) { + } else if (dist < std::min(rad + 0.1 * AU, rad * 1000.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10000X); } } } - if (!m_player->AIIsActive()) { // don't do this when autopilot is active + if (!m_player->AIIsActive()) { // don't do this when autopilot is active const double locVel = m_player->GetAngVelocity().Length(); const double strictness = 20.0; - if(locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_10X]) { + if (locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_10X]) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1X); - } else if(locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_100X]) { + } else if (locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_100X]) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); - } else if(locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_1000X]) { + } else if (locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_1000X]) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_100X); - } else if(locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_10000X]) { + } else if (locVel > strictness / Game::s_timeAccelRates[TIMEACCEL_10000X]) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1000X); } } @@ -396,7 +394,7 @@ double Game::GetHyperspaceArrivalProbability() const return scale * (1.0 - exp(-fudge * progress)); } -void Game::RemoveHyperspaceCloud(HyperspaceCloud* cloud) +void Game::RemoveHyperspaceCloud(HyperspaceCloud *cloud) { m_hyperspaceClouds.remove(cloud); } @@ -406,17 +404,17 @@ void Game::SwitchToHyperspace() PROFILE_SCOPED() // remember where we came from so we can properly place the player on exit m_hyperspaceSource = m_space->GetStarSystem()->GetPath(); - m_hyperspaceDest = m_player->GetHyperspaceDest(); + m_hyperspaceDest = m_player->GetHyperspaceDest(); // find all the departure clouds, convert them to arrival clouds and store // them for the next system m_hyperspaceClouds.clear(); - for (Body* b : m_space->GetBodies()) { + for (Body *b : m_space->GetBodies()) { if (!b->IsType(Object::HYPERSPACECLOUD)) continue; // only want departure clouds with ships in them - HyperspaceCloud *cloud = static_cast(b); + HyperspaceCloud *cloud = static_cast(b); if (cloud->IsArrival() || cloud->GetShip() == 0) continue; @@ -449,7 +447,7 @@ void Game::SwitchToHyperspace() // create hyperspace :) m_space.reset(new Space(this, m_galaxy, m_space.get())); - m_space->GetBackground()->SetDrawFlags( Background::Container::DRAW_STARS ); + m_space->GetBackground()->SetDrawFlags(Background::Container::DRAW_STARS); // Reset planner Pi::planner->ResetStartTime(); @@ -461,8 +459,8 @@ void Game::SwitchToHyperspace() // put player at the origin. kind of unnecessary since it won't be moving // but at least it gives some consistency - m_player->SetPosition(vector3d(0,0,0)); - m_player->SetVelocity(vector3d(0,0,0)); + m_player->SetPosition(vector3d(0, 0, 0)); + m_player->SetVelocity(vector3d(0, 0, 0)); m_player->SetOrient(matrix3x3d::Identity()); // animation and end time counters @@ -490,7 +488,7 @@ void Game::SwitchToNormalSpace() m_space->AddBody(m_player.get()); // place it - vector3d pos,vel; + vector3d pos, vel; m_space->GetHyperspaceExitParams(m_hyperspaceSource, m_hyperspaceDest, pos, vel); m_player->SetPosition(pos); m_player->SetVelocity(vel); @@ -500,7 +498,7 @@ void Game::SwitchToNormalSpace() vector3d oz = -vel.Normalized(); vector3d ox = MathUtil::OrthogonalDirection(vel); vector3d oy = oz.Cross(ox).Normalized(); - m_player->SetOrient(matrix3x3d::FromVectors(ox,oy,oz)); + m_player->SetOrient(matrix3x3d::FromVectors(ox, oy, oz)); } // place the exit cloud @@ -509,7 +507,7 @@ void Game::SwitchToNormalSpace() cloud->SetPosition(m_player->GetPosition()); m_space->AddBody(cloud); - for (std::list::iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) { + for (std::list::iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) { cloud = *i; cloud->SetFrame(m_space->GetRootFrame()); @@ -522,7 +520,7 @@ void Game::SwitchToNormalSpace() Ship *ship = cloud->EvictShip(); ship->SetFrame(m_space->GetRootFrame()); - ship->SetVelocity(vector3d(0,0,-100.0)); + ship->SetVelocity(vector3d(0, 0, -100.0)); ship->SetOrient(matrix3x3d::Identity()); ship->SetFlightState(Ship::FLYING); @@ -575,7 +573,7 @@ void Game::SwitchToNormalSpace() SystemBody *sbody = m_space->GetStarSystem()->GetBodyByPath(&sdest); if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) { ship->SetFrame(target_body->GetFrame()); - ship->SetPosition(MathUtil::RandomPointOnSphere(1000.0)*1000.0); // somewhere 1000km out + ship->SetPosition(MathUtil::RandomPointOnSphere(1000.0) * 1000.0); // somewhere 1000km out } else { @@ -585,7 +583,7 @@ void Game::SwitchToNormalSpace() target_body = m_space->FindBodyForPath(&path); } - double sdist = sbody->GetRadius()*2.0; + double sdist = sbody->GetRadius() * 2.0; ship->SetFrame(target_body->GetFrame()); ship->SetPosition(MathUtil::RandomPointOnSphere(sdist)); @@ -600,46 +598,46 @@ void Game::SwitchToNormalSpace() } m_hyperspaceClouds.clear(); - m_space->GetBackground()->SetDrawFlags( Background::Container::DRAW_SKYBOX | Background::Container::DRAW_STARS ); + m_space->GetBackground()->SetDrawFlags(Background::Container::DRAW_SKYBOX | Background::Container::DRAW_STARS); m_state = STATE_NORMAL; } const float Game::s_timeAccelRates[] = { - 0.0f, // paused - 1.0f, // 1x - 10.0f, // 10x - 100.0f, // 100x - 1000.0f, // 1000x - 10000.0f, // 10000x - 100000.0f // hyperspace + 0.0f, // paused + 1.0f, // 1x + 10.0f, // 10x + 100.0f, // 100x + 1000.0f, // 1000x + 10000.0f, // 10000x + 100000.0f // hyperspace }; const float Game::s_timeInvAccelRates[] = { - 0.0f, // paused - 1.0f, // 1x - 0.1f, // 10x - 0.01f, // 100x - 0.001f, // 1000x - 0.0001f, // 10000x - 0.00001f // hyperspace + 0.0f, // paused + 1.0f, // 1x + 0.1f, // 10x + 0.01f, // 100x + 0.001f, // 1000x + 0.0001f, // 10000x + 0.00001f // hyperspace }; void Game::SetTimeAccel(TimeAccel t) { // don't want player to spin like mad when hitting time accel if ((t != m_timeAccel) && (t > TIMEACCEL_1X) && - m_player->GetPlayerController()->GetRotationDamping()) { - m_player->SetAngVelocity(vector3d(0,0,0)); - m_player->SetTorque(vector3d(0,0,0)); + m_player->GetPlayerController()->GetRotationDamping()) { + m_player->SetAngVelocity(vector3d(0, 0, 0)); + m_player->SetTorque(vector3d(0, 0, 0)); m_player->SetAngThrusterState(vector3d(0.0)); } // Give all ships a half-step acceleration to stop autopilot overshoot if (t < m_timeAccel) - for (Body* b : m_space->GetBodies()) + for (Body *b : m_space->GetBodies()) if (b->IsType(Object::SHIP)) - (static_cast(b))->TimeAccelAdjust(0.5f * GetTimeStep()); + (static_cast(b))->TimeAccelAdjust(0.5f * GetTimeStep()); bool emitPaused = (t == TIMEACCEL_PAUSED && t != m_timeAccel); bool emitResumed = (m_timeAccel == TIMEACCEL_PAUSED && t != TIMEACCEL_PAUSED); @@ -668,59 +666,59 @@ void Game::RequestTimeAccel(TimeAccel t, bool force) void Game::RequestTimeAccelInc(bool force) { - switch(m_requestedTimeAccel) { - case Game::TIMEACCEL_1X: - m_requestedTimeAccel = Game::TIMEACCEL_10X; - break; - case Game::TIMEACCEL_10X: - m_requestedTimeAccel = Game::TIMEACCEL_100X; - break; - case Game::TIMEACCEL_100X: - m_requestedTimeAccel = Game::TIMEACCEL_1000X; - break; - case Game::TIMEACCEL_1000X: - m_requestedTimeAccel = Game::TIMEACCEL_10000X; - break; - default: - // ignore if paused, hyperspace or 10000X - break; + switch (m_requestedTimeAccel) { + case Game::TIMEACCEL_1X: + m_requestedTimeAccel = Game::TIMEACCEL_10X; + break; + case Game::TIMEACCEL_10X: + m_requestedTimeAccel = Game::TIMEACCEL_100X; + break; + case Game::TIMEACCEL_100X: + m_requestedTimeAccel = Game::TIMEACCEL_1000X; + break; + case Game::TIMEACCEL_1000X: + m_requestedTimeAccel = Game::TIMEACCEL_10000X; + break; + default: + // ignore if paused, hyperspace or 10000X + break; } m_forceTimeAccel = force; } void Game::RequestTimeAccelDec(bool force) { - switch(m_requestedTimeAccel) { - case Game::TIMEACCEL_10X: - m_requestedTimeAccel = Game::TIMEACCEL_1X; - break; - case Game::TIMEACCEL_100X: - m_requestedTimeAccel = Game::TIMEACCEL_10X; - break; - case Game::TIMEACCEL_1000X: - m_requestedTimeAccel = Game::TIMEACCEL_100X; - break; - case Game::TIMEACCEL_10000X: - m_requestedTimeAccel = Game::TIMEACCEL_1000X; - break; - default: - // ignore if paused, hyperspace or 1X - break; + switch (m_requestedTimeAccel) { + case Game::TIMEACCEL_10X: + m_requestedTimeAccel = Game::TIMEACCEL_1X; + break; + case Game::TIMEACCEL_100X: + m_requestedTimeAccel = Game::TIMEACCEL_10X; + break; + case Game::TIMEACCEL_1000X: + m_requestedTimeAccel = Game::TIMEACCEL_100X; + break; + case Game::TIMEACCEL_10000X: + m_requestedTimeAccel = Game::TIMEACCEL_1000X; + break; + default: + // ignore if paused, hyperspace or 1X + break; } m_forceTimeAccel = force; } -Game::Views::Views() - : m_sectorView(nullptr) - , m_galacticView(nullptr) - , m_systemInfoView(nullptr) - , m_systemView(nullptr) - , m_worldView(nullptr) - , m_deathView(nullptr) - , m_spaceStationView(nullptr) - , m_infoView(nullptr) - , m_cpan(nullptr) -{ } +Game::Views::Views() : + m_sectorView(nullptr), + m_galacticView(nullptr), + m_systemInfoView(nullptr), + m_systemView(nullptr), + m_worldView(nullptr), + m_deathView(nullptr), + m_spaceStationView(nullptr), + m_infoView(nullptr), + m_cpan(nullptr) +{} void Game::Views::SetRenderer(Graphics::Renderer *r) { @@ -737,7 +735,7 @@ void Game::Views::SetRenderer(Graphics::Renderer *r) #endif } -void Game::Views::Init(Game* game) +void Game::Views::Init(Game *game) { m_cpan = new ShipCpanel(Pi::renderer, game); m_sectorView = new SectorView(game); @@ -756,7 +754,7 @@ void Game::Views::Init(Game* game) SetRenderer(Pi::renderer); } -void Game::Views::LoadFromJson(const Json &jsonObj, Game* game) +void Game::Views::LoadFromJson(const Json &jsonObj, Game *game) { m_cpan = new ShipCpanel(jsonObj, Pi::renderer, game); m_sectorView = new SectorView(jsonObj, game); @@ -840,7 +838,7 @@ void Game::DestroyViews() void Game::EmitPauseState(bool paused) { - if (paused) { + if (paused) { // Notify UI that time is paused. LuaEvent::Queue("onGamePaused"); } else { @@ -872,11 +870,9 @@ Game *Game::LoadGame(const std::string &filename) try { return new Game(rootNode); - } - catch (Json::type_error) { + } catch (Json::type_error) { throw SavedGameCorruptException(); - } - catch (Json::out_of_range) { + } catch (Json::out_of_range) { throw SavedGameCorruptException(); } } diff --git a/src/Game.h b/src/Game.h index 60877ac69..0b89871d1 100644 --- a/src/Game.h +++ b/src/Game.h @@ -4,13 +4,13 @@ #ifndef _GAME_H #define _GAME_H -#include -#include "libs.h" -#include "gameconsts.h" #include "GameLog.h" +#include "JsonFwd.h" #include "galaxy/Galaxy.h" #include "galaxy/SystemPath.h" -#include "JsonFwd.h" +#include "gameconsts.h" +#include "libs.h" +#include class HyperspaceCloud; class Player; @@ -22,7 +22,8 @@ struct CannotSaveInHyperspace : public CannotSaveCurrentGameState {}; struct CannotSaveDeadPlayer : public CannotSaveCurrentGameState {}; struct InvalidGameStartLocation { std::string error; - InvalidGameStartLocation(const std::string& error_) : error(error_) {} + InvalidGameStartLocation(const std::string &error_) : + error(error_) {} }; class SectorView; @@ -83,9 +84,9 @@ public: double GetHyperspaceDuration() const { return m_hyperspaceDuration; } double GetHyperspaceEndTime() const { return m_hyperspaceEndTime; } double GetHyperspaceArrivalProbability() const; - const SystemPath& GetHyperspaceDest() const { return m_hyperspaceDest; } - const SystemPath& GetHyperspaceSource() const { return m_hyperspaceSource; } - void RemoveHyperspaceCloud(HyperspaceCloud*); + const SystemPath &GetHyperspaceDest() const { return m_hyperspaceDest; } + const SystemPath &GetHyperspaceSource() const { return m_hyperspaceSource; } + void RemoveHyperspaceCloud(HyperspaceCloud *); enum TimeAccel { TIMEACCEL_PAUSED, @@ -95,7 +96,7 @@ public: TIMEACCEL_1000X, TIMEACCEL_10000X, TIMEACCEL_HYPERSPACE - }; + }; void SetTimeAccel(TimeAccel t); void RequestTimeAccel(TimeAccel t, bool force = false); @@ -114,19 +115,22 @@ public: float GetTimeAccelRate() const { return s_timeAccelRates[m_timeAccel]; } float GetInvTimeAccelRate() const { return s_timeInvAccelRates[m_timeAccel]; } - float GetTimeStep() const { return s_timeAccelRates[m_timeAccel]*(1.0f/PHYSICS_HZ); } + float GetTimeStep() const { return s_timeAccelRates[m_timeAccel] * (1.0f / PHYSICS_HZ); } - SectorView* GetSectorView() const { return m_gameViews->m_sectorView; } - UIView* GetGalacticView() const { return m_gameViews->m_galacticView; } - SystemInfoView* GetSystemInfoView() const { return m_gameViews->m_systemInfoView; } - SystemView* GetSystemView() const { return m_gameViews->m_systemView; } - WorldView* GetWorldView() const { return m_gameViews->m_worldView; } - DeathView* GetDeathView() const { return m_gameViews->m_deathView; } - UIView* GetSpaceStationView() const { return m_gameViews->m_spaceStationView; } - UIView* GetInfoView() const { return m_gameViews->m_infoView; } - ShipCpanel* GetCpan() const { return m_gameViews->m_cpan; } + SectorView *GetSectorView() const { return m_gameViews->m_sectorView; } + UIView *GetGalacticView() const { return m_gameViews->m_galacticView; } + SystemInfoView *GetSystemInfoView() const { return m_gameViews->m_systemInfoView; } + SystemView *GetSystemView() const { return m_gameViews->m_systemView; } + WorldView *GetWorldView() const { return m_gameViews->m_worldView; } + DeathView *GetDeathView() const { return m_gameViews->m_deathView; } + UIView *GetSpaceStationView() const { return m_gameViews->m_spaceStationView; } + UIView *GetInfoView() const { return m_gameViews->m_infoView; } + ShipCpanel *GetCpan() const { return m_gameViews->m_cpan; } #if WITH_OBJECTVIEWER - ObjectViewerView* GetObjectViewerView() const { return m_gameViews->m_objectViewerView; } + ObjectViewerView *GetObjectViewerView() const + { + return m_gameViews->m_objectViewerView; + } #endif GameLog *log; @@ -135,23 +139,23 @@ private: class Views { public: Views(); - void Init(Game* game); - void LoadFromJson(const Json &jsonObj, Game* game); + void Init(Game *game); + void LoadFromJson(const Json &jsonObj, Game *game); ~Views(); void SetRenderer(Graphics::Renderer *r); - SectorView* m_sectorView; - UIView* m_galacticView; - SystemInfoView* m_systemInfoView; - SystemView* m_systemView; - WorldView* m_worldView; - DeathView* m_deathView; - UIView* m_spaceStationView; - UIView* m_infoView; - ShipCpanel* m_cpan; + SectorView *m_sectorView; + UIView *m_galacticView; + SystemInfoView *m_systemInfoView; + SystemView *m_systemView; + WorldView *m_worldView; + DeathView *m_deathView; + UIView *m_spaceStationView; + UIView *m_infoView; + ShipCpanel *m_cpan; #if WITH_OBJECTVIEWER - ObjectViewerView* m_objectViewerView; + ObjectViewerView *m_objectViewerView; #endif }; @@ -179,7 +183,7 @@ private: bool m_wantHyperspace; - std::list m_hyperspaceClouds; + std::list m_hyperspaceClouds; SystemPath m_hyperspaceSource; SystemPath m_hyperspaceDest; double m_hyperspaceProgress; diff --git a/src/GameConfig.cpp b/src/GameConfig.cpp index 5b662d097..da39d1dc0 100644 --- a/src/GameConfig.cpp +++ b/src/GameConfig.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GameConfig.h" -#include "KeyBindings.h" #include "FileSystem.h" +#include "KeyBindings.h" GameConfig::GameConfig(const map_string &override_) { diff --git a/src/GameLog.cpp b/src/GameLog.cpp index bcdf70d5f..8efd4c6b4 100644 --- a/src/GameLog.cpp +++ b/src/GameLog.cpp @@ -1,10 +1,10 @@ #include "GameLog.h" +#include "Game.h" +#include "LuaObject.h" +#include "Pi.h" #include "StringF.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "LuaObject.h" -#include "Game.h" -#include "Pi.h" void GameLog::Add(const std::string &msg) { @@ -28,4 +28,3 @@ void GameLog::Add(const std::string &from, const std::string &msg, GameLog::Prio lua_pushnumber(l, priority); lua_call(l, 3, 0); } - diff --git a/src/GameLog.h b/src/GameLog.h index b2734e305..e84c161c4 100644 --- a/src/GameLog.h +++ b/src/GameLog.h @@ -9,16 +9,14 @@ * atm it holds only 6 messages, but do extend */ - class GameLog { public: enum Priority { PRIORITY_NORMAL = 0, - PRIORITY_IMPORTANT = 1, - PRIORITY_ALERT = 2 }; + PRIORITY_IMPORTANT = 1, + PRIORITY_ALERT = 2 }; - void Add(const std::string&); + void Add(const std::string &); void Add(const std::string &from, const std::string &msg, Priority priority); - }; #endif diff --git a/src/GasGiant.cpp b/src/GasGiant.cpp index d9fec94b9..4567c7543 100644 --- a/src/GasGiant.cpp +++ b/src/GasGiant.cpp @@ -1,38 +1,37 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "GasGiant.h" -#include "perlin.h" -#include "Pi.h" -#include "IniConfig.h" #include "FileSystem.h" #include "Game.h" +#include "IniConfig.h" +#include "Pi.h" #include "RefCounted.h" -#include "graphics/Material.h" -#include "graphics/opengl/GenGasGiantColourMaterial.h" -#include "graphics/Renderer.h" #include "graphics/Frustum.h" #include "graphics/Graphics.h" +#include "graphics/Material.h" +#include "graphics/Renderer.h" #include "graphics/Texture.h" #include "graphics/TextureBuilder.h" -#include "graphics/VertexArray.h" #include "graphics/Types.h" +#include "graphics/VertexArray.h" +#include "graphics/opengl/GenGasGiantColourMaterial.h" +#include "libs.h" +#include "perlin.h" #include "vcacheopt/vcacheopt.h" -#include #include +#include RefCountedPtr GasGiant::s_patchContext; -namespace -{ +namespace { static Uint32 s_texture_size_small = 16; static Uint32 s_texture_size_cpu[5]; static Uint32 s_texture_size_gpu[5]; static Uint32 s_noiseOctaves[5]; static float s_initialCPUDelayTime = 60.0f; // (perhaps) 60 seconds seems like a reasonable default static float s_initialGPUDelayTime = 5.0f; // (perhaps) 5 seconds seems like a reasonable default - static std::vector s_allGasGiants; + static std::vector s_allGasGiants; static const std::string GGJupiter("GGJupiter"); static const std::string GGNeptune("GGNeptune"); @@ -46,7 +45,7 @@ namespace static const std::string delim(","); enum dataEntries { - eCPU=0, + eCPU = 0, eGPU, eOCTAVES }; @@ -64,8 +63,7 @@ namespace end = spec.find_first_of(delim, start); // extract the fragment and remember it - switch(i) - { + switch (i) { case eCPU: cpuOut = ceil_pow2(Clamp(atoi(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str()), 64, 4096)); break; @@ -82,83 +80,87 @@ namespace i++; } - return i==4; + return i == 4; } -}; - +}; // namespace class GasPatchContext : public RefCounted { public: - #pragma pack(push, 4) - struct VBOVertex - { +#pragma pack(push, 4) + struct VBOVertex { vector3f pos; vector3f norm; }; - #pragma pack(pop) +#pragma pack(pop) int edgeLen; - inline int IDX_VBO_COUNT_ALL_IDX() const { return ((edgeLen-1)*(edgeLen-1))*2*3; } + inline int IDX_VBO_COUNT_ALL_IDX() const { return ((edgeLen - 1) * (edgeLen - 1)) * 2 * 3; } - inline int NUMVERTICES() const { return edgeLen*edgeLen; } + inline int NUMVERTICES() const { return edgeLen * edgeLen; } double frac; std::unique_ptr indices; RefCountedPtr indexBuffer; - GasPatchContext(const int _edgeLen) : edgeLen(_edgeLen) { + GasPatchContext(const int _edgeLen) : + edgeLen(_edgeLen) + { Init(); } - ~GasPatchContext() { + ~GasPatchContext() + { Cleanup(); } - void Refresh() { + void Refresh() + { Cleanup(); Init(); } - void Cleanup() { + void Cleanup() + { indices.reset(); } int GetIndices(std::vector &pl) { // calculate how many tri's there are - const int tri_count = IDX_VBO_COUNT_ALL_IDX()/3; + const int tri_count = IDX_VBO_COUNT_ALL_IDX() / 3; // pre-allocate enough space pl.reserve(IDX_VBO_COUNT_ALL_IDX()); // add all of the middle indices - for(int i=0; iCreateIndexBuffer(pl_short.size(), Graphics::BUFFER_USAGE_STATIC)); - Uint32* idxPtr = indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + Uint32 *idxPtr = indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); for (Uint32 j = 0; j < pl_short.size(); j++) { idxPtr[j] = pl_short[j]; } @@ -186,7 +188,6 @@ public: } }; - class GasPatch { public: RefCountedPtr ctx; @@ -196,13 +197,19 @@ public: vector3d clipCentroid; double clipRadius; - GasPatch(const RefCountedPtr &_ctx, GasGiant *gs, vector3d v0, vector3d v1, vector3d v2, vector3d v3) - : ctx(_ctx), gasSphere(gs), clipCentroid(((v0+v1+v2+v3) * 0.25).Normalized()), clipRadius(0.0) + GasPatch(const RefCountedPtr &_ctx, GasGiant *gs, vector3d v0, vector3d v1, vector3d v2, vector3d v3) : + ctx(_ctx), + gasSphere(gs), + clipCentroid(((v0 + v1 + v2 + v3) * 0.25).Normalized()), + clipRadius(0.0) { PROFILE_SCOPED() - v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; - for (int i=0; i<4; i++) { - clipRadius = std::max(clipRadius, (v[i]-clipCentroid).Length()); + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + for (int i = 0; i < 4; i++) { + clipRadius = std::max(clipRadius, (v[i] - clipCentroid).Length()); } UpdateVBOs(); @@ -211,30 +218,32 @@ public: ~GasPatch() {} /* in patch surface coords, [0,1] */ - vector3d GetSpherePoint(const double x, const double y) const { - return (v[0] + x*(1.0-y)*(v[1]-v[0]) + x*y*(v[2]-v[0]) + (1.0-x)*y*(v[3]-v[0])).Normalized(); + vector3d GetSpherePoint(const double x, const double y) const + { + return (v[0] + x * (1.0 - y) * (v[1] - v[0]) + x * y * (v[2] - v[0]) + (1.0 - x) * y * (v[3] - v[0])).Normalized(); } - void UpdateVBOs() { + void UpdateVBOs() + { PROFILE_SCOPED() //create buffer and upload data Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.numVertices = ctx->NUMVERTICES(); vbd.usage = Graphics::BUFFER_USAGE_STATIC; m_vertexBuffer.reset(Pi::renderer->CreateVertexBuffer(vbd)); - GasPatchContext::VBOVertex* vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + GasPatchContext::VBOVertex *vtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); assert(m_vertexBuffer->GetDesc().stride == sizeof(GasPatchContext::VBOVertex)); const Sint32 edgeLen = ctx->edgeLen; const double frac = ctx->frac; - for (Sint32 y=0; ypos = vector3f(pSubCentroid); @@ -246,7 +255,8 @@ public: m_vertexBuffer->Unmap(); } - void Render(Graphics::Renderer *renderer, const vector3d &campos, const matrix4x4d &modelView, const Graphics::Frustum &frustum) { + void Render(Graphics::Renderer *renderer, const vector3d &campos, const matrix4x4d &modelView, const Graphics::Frustum &frustum) + { if (!frustum.TestPoint(clipCentroid, clipRadius)) return; @@ -256,7 +266,7 @@ public: const vector3d relpos = clipCentroid - campos; renderer->SetTransform(modelView * matrix4x4d::Translation(relpos)); - Pi::statSceneTris += 2*(ctx->edgeLen-1)*(ctx->edgeLen-1); + Pi::statSceneTris += 2 * (ctx->edgeLen - 1) * (ctx->edgeLen - 1); ++Pi::statNumPatches; renderer->DrawBufferIndexed(m_vertexBuffer.get(), ctx->indexBuffer.Get(), rs, mat.Get()); @@ -264,15 +274,14 @@ public: } }; -Graphics::RenderTarget *GasGiant::s_renderTarget; -Graphics::RenderState *GasGiant::s_quadRenderState; +Graphics::RenderTarget *GasGiant::s_renderTarget; +Graphics::RenderState *GasGiant::s_quadRenderState; // static void GasGiant::UpdateAllGasGiants() { PROFILE_SCOPED() - for(std::vector::iterator i = s_allGasGiants.begin(); i != s_allGasGiants.end(); ++i) - { + for (std::vector::iterator i = s_allGasGiants.begin(); i != s_allGasGiants.end(); ++i) { (*i)->Update(); } } @@ -283,8 +292,7 @@ void GasGiant::OnChangeDetailLevel() s_patchContext.Reset(new GasPatchContext(127)); // reinit the geosphere terrain data - for(std::vector::iterator i = s_allGasGiants.begin(); i != s_allGasGiants.end(); ++i) - { + for (std::vector::iterator i = s_allGasGiants.begin(); i != s_allGasGiants.end(); ++i) { // clearout anything we don't need (*i)->Reset(); @@ -293,19 +301,23 @@ void GasGiant::OnChangeDetailLevel() } } -GasGiant::GasGiant(const SystemBody *body) : BaseSphere(body), - m_hasTempCampos(false), m_tempCampos(0.0), m_hasGpuJobRequest(false), m_timeDelay(s_initialCPUDelayTime) +GasGiant::GasGiant(const SystemBody *body) : + BaseSphere(body), + m_hasTempCampos(false), + m_tempCampos(0.0), + m_hasGpuJobRequest(false), + m_timeDelay(s_initialCPUDelayTime) { s_allGasGiants.push_back(this); - for(int i=0; iGetSeed()+4609837); + Random rng(GetSystemBody()->GetSeed() + 4609837); const bool bEnableGPUJobs = (Pi::config->Int("EnableGPUJobs") == 1); - if(bEnableGPUJobs) + if (bEnableGPUJobs) m_timeDelay = s_initialGPUDelayTime + (rng.Double() * (s_initialGPUDelayTime * 0.5)); //SetUpMaterials is not called until first Render since light count is zero :) @@ -323,14 +335,14 @@ GasGiant::~GasGiant() void GasGiant::Reset() { { - for(int i=0; iOnCancel(); m_hasJobRequest[i] = false; } } - for (int p=0; p::iterator i=s_allGasGiants.begin(), iEnd=s_allGasGiants.end(); i!=iEnd; ++i) { - if( path == (*i)->GetSystemBody()->GetPath() ) { + for (std::vector::iterator i = s_allGasGiants.begin(), iEnd = s_allGasGiants.end(); i != iEnd; ++i) { + if (path == (*i)->GetSystemBody()->GetPath()) { (*i)->AddTextureFaceResult(res); return true; } } // GasGiant not found to return the data to, cancel (which deletes it) instead - if( res ) { + if (res) { res->OnCancel(); delete res; } @@ -364,14 +376,14 @@ bool GasGiant::OnAddTextureFaceResult(const SystemPath &path, GasGiantJobs::STex bool GasGiant::OnAddGPUGenResult(const SystemPath &path, GasGiantJobs::SGPUGenResult *res) { // Find the correct GeoSphere via it's system path, and give it the split result - for(std::vector::iterator i=s_allGasGiants.begin(), iEnd=s_allGasGiants.end(); i!=iEnd; ++i) { - if( path == (*i)->GetSystemBody()->GetPath() ) { + for (std::vector::iterator i = s_allGasGiants.begin(), iEnd = s_allGasGiants.end(); i != iEnd; ++i) { + if (path == (*i)->GetSystemBody()->GetPath()) { (*i)->AddGPUGenResult(res); return true; } } // GasGiant not found to return the data to, cancel (which deletes it) instead - if( res ) { + if (res) { res->OnCancel(); delete res; } @@ -384,7 +396,7 @@ bool GasGiant::OnAddGPUGenResult(const SystemPath &path, GasGiantJobs::SGPUGenRe #include "FileSystem.h" #include "PngWriter.h" #include "graphics/opengl/TextureGL.h" -void textureDump(const char* destFile, const int width, const int height, const Color* buf) +void textureDump(const char *destFile, const int width, const int height, const Color *buf) { const std::string dir = "generated_textures"; FileSystem::userFiles.MakeDirectory(dir); @@ -405,20 +417,20 @@ bool GasGiant::AddTextureFaceResult(GasGiantJobs::STextureFaceResult *res) bool result = false; assert(res); assert(res->face() >= 0 && res->face() < NUM_PATCHES); - m_jobColorBuffers[res->face()].reset( res->data().colors ); + m_jobColorBuffers[res->face()].reset(res->data().colors); m_hasJobRequest[res->face()] = false; const Sint32 uvDims = res->data().uvDims; - assert( uvDims > 0 && uvDims <= 4096 ); + assert(uvDims > 0 && uvDims <= 4096); // tidyup delete res; bool bCreateTexture = true; - for(int i=0; iUpdate(tcd, dataSize, Graphics::TEXTURE_RGBA_8888); #if DUMP_TO_TEXTURE - for (int iFace = 0; iFaceGetName().c_str(), iFace); textureDump(filename, uvDims, uvDims, m_jobColorBuffers[iFace].get()); @@ -447,12 +459,12 @@ bool GasGiant::AddTextureFaceResult(GasGiantJobs::STextureFaceResult *res) #endif // cleanup the temporary color buffer storage - for(int i=0; itexture0 = m_surfaceTexture.Get(); m_surfaceTextureSmall.Reset(); } @@ -468,13 +480,13 @@ bool GasGiant::AddGPUGenResult(GasGiantJobs::SGPUGenResult *res) m_hasGpuJobRequest = false; assert(!m_gpuJob.HasJob()); const Sint32 uvDims = res->data().uvDims; - assert( uvDims > 0 && uvDims <= 4096 ); + assert(uvDims > 0 && uvDims <= 4096); #if DUMP_TO_TEXTURE - for(int iFace=0; iFace buffer(static_cast(malloc(uvDims*uvDims*4))); - Graphics::Texture* pTex = res->data().texture.Get(); - Graphics::TextureGL* pGLTex = static_cast(pTex); + for (int iFace = 0; iFace < NUM_PATCHES; iFace++) { + std::unique_ptr buffer(static_cast(malloc(uvDims * uvDims * 4))); + Graphics::Texture *pTex = res->data().texture.Get(); + Graphics::TextureGL *pGLTex = static_cast(pTex); pGLTex->Bind(); glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get()); pGLTex->Unbind(); @@ -496,7 +508,7 @@ bool GasGiant::AddGPUGenResult(GasGiantJobs::SGPUGenResult *res) m_surfaceTexture->BuildMipmaps(); // change the planet texture for the new higher resolution texture - if( m_surfaceMaterial.Get() ) { + if (m_surfaceMaterial.Get()) { m_surfaceMaterial->texture0 = m_surfaceTexture.Get(); m_surfaceTextureSmall.Reset(); } @@ -506,14 +518,15 @@ bool GasGiant::AddGPUGenResult(GasGiantJobs::SGPUGenResult *res) } // in patch surface coords, [0,1] -inline vector3d GetSpherePointFromCorners(const double x, const double y, const vector3d *corners) { - return (corners[0] + x*(1.0-y)*(corners[1]-corners[0]) + x*y*(corners[2]-corners[0]) + (1.0-x)*y*(corners[3]-corners[0])).Normalized(); +inline vector3d GetSpherePointFromCorners(const double x, const double y, const vector3d *corners) +{ + return (corners[0] + x * (1.0 - y) * (corners[1] - corners[0]) + x * y * (corners[2] - corners[0]) + (1.0 - x) * y * (corners[3] - corners[0])).Normalized(); } void GasGiant::GenerateTexture() { using namespace GasGiantJobs; - for(int i=0; iCreateTexture(texDesc)); const Terrain *pTerrain = GetTerrain(); - const double fracStep = 1.0 / double(s_texture_size_small-1); + const double fracStep = 1.0 / double(s_texture_size_small - 1); Graphics::TextureCubeData tcd; std::unique_ptr bufs[NUM_PATCHES]; - for(int i=0; iGetColor(p, 0.0, p); // convert to ubyte and store - Color* col = colors + (u + (v * s_texture_size_small)); + Color *col = colors + (u + (v * s_texture_size_small)); col[0].r = Uint8(colour.x * 255.0); col[0].g = Uint8(colour.y * 255.0); col[0].b = Uint8(colour.z * 255.0); @@ -570,19 +583,15 @@ void GasGiant::GenerateTexture() } // create small texture - if( !bEnableGPUJobs ) - { - for(int i=0; iGetPath(), i, s_texture_size_cpu[Pi::detail.planets], GetTerrain()); + GasGiantJobs::STextureFaceRequest *ssrd = new GasGiantJobs::STextureFaceRequest(&GetPatchFaces(i, 0), GetSystemBody()->GetPath(), i, s_texture_size_cpu[Pi::detail.planets], GetTerrain()); m_job[i] = Pi::GetAsyncJobQueue()->Queue(new GasGiantJobs::SingleTextureFaceJob(ssrd)); } - } - else - { + } else { // use m_surfaceTexture texture? // create texture const vector2f texSize(1.0f, 1.0f); @@ -597,15 +606,15 @@ void GasGiant::GenerateTexture() Output("Color Fractal name: %s\n", ColorFracName.c_str()); Uint32 GasGiantType = Graphics::OGL::GEN_JUPITER_TEXTURE; - if( ColorFracName == GGSaturn ) { + if (ColorFracName == GGSaturn) { GasGiantType = Graphics::OGL::GEN_SATURN_TEXTURE; - } else if( ColorFracName == GGSaturn2 ) { + } else if (ColorFracName == GGSaturn2) { GasGiantType = Graphics::OGL::GEN_SATURN2_TEXTURE; - } else if( ColorFracName == GGNeptune ) { + } else if (ColorFracName == GGNeptune) { GasGiantType = Graphics::OGL::GEN_NEPTUNE_TEXTURE; - } else if( ColorFracName == GGNeptune2 ) { + } else if (ColorFracName == GGNeptune2) { GasGiantType = Graphics::OGL::GEN_NEPTUNE2_TEXTURE; - } else if( ColorFracName == GGUranus ) { + } else if (ColorFracName == GGUranus) { GasGiantType = Graphics::OGL::GEN_URANUS_TEXTURE; } const Uint32 octaves = (Pi::config->Int("AMD_MESA_HACKS") == 0) ? s_noiseOctaves[Pi::detail.planets] : std::min(5U, s_noiseOctaves[Pi::detail.planets]); @@ -614,11 +623,11 @@ void GasGiant::GenerateTexture() assert(!m_hasGpuJobRequest); assert(!m_gpuJob.HasJob()); - Random rng(GetSystemBody()->GetSeed()+4609837); + Random rng(GetSystemBody()->GetSeed() + 4609837); const std::string parentname = GetSystemBody()->GetParent()->GetName(); const float hueShift = (parentname == "Sol") ? 0.0f : float(((rng.Double() * 2.0) - 1.0) * 0.9); - GasGiantJobs::GenFaceQuad *pQuad = new GasGiantJobs::GenFaceQuad(Pi::renderer, vector2f(s_texture_size_gpu[Pi::detail.planets], s_texture_size_gpu[Pi::detail.planets]), s_quadRenderState, GasGiantType ); + GasGiantJobs::GenFaceQuad *pQuad = new GasGiantJobs::GenFaceQuad(Pi::renderer, vector2f(s_texture_size_gpu[Pi::detail.planets], s_texture_size_gpu[Pi::detail.planets]), s_quadRenderState, GasGiantType); GasGiantJobs::SGPUGenRequest *pGPUReq = new GasGiantJobs::SGPUGenRequest(GetSystemBody()->GetPath(), s_texture_size_gpu[Pi::detail.planets], GetTerrain(), GetSystemBody()->GetRadius(), hueShift, pQuad, m_builtTexture.Get()); m_gpuJob = Pi::GetSyncJobQueue()->Queue(new GasGiantJobs::SingleGPUGenJob(pGPUReq)); @@ -630,13 +639,11 @@ void GasGiant::Update() { PROFILE_SCOPED() // assuming that we haven't already generated the texture from the render call. - if( m_timeDelay > 0.0f ) - { + if (m_timeDelay > 0.0f) { m_timeDelay -= Pi::game->GetTimeStep(); - if( m_timeDelay <= 0.0001f && !m_surfaceTexture.Valid() ) - { + if (m_timeDelay <= 0.0001f && !m_surfaceTexture.Valid()) { // Use the fact that we have a patch as a latch to prevent repeat generation requests. - if( m_patches[0].get() ) + if (m_patches[0].get()) return; BuildFirstPatches(); @@ -648,11 +655,9 @@ void GasGiant::Update() void GasGiant::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, vector3d campos, const float radius, const std::vector &shadows) { PROFILE_SCOPED() - if( !m_surfaceTexture.Valid() ) - { + if (!m_surfaceTexture.Valid()) { // Use the fact that we have a patch as a latch to prevent repeat generation requests. - if( !m_patches[0].get() ) - { + if (!m_patches[0].get()) { BuildFirstPatches(); } } @@ -668,7 +673,7 @@ void GasGiant::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, matrix4x4d proj; matrix4x4ftod(renderer->GetCurrentModelView(), modv); matrix4x4ftod(renderer->GetCurrentProjection(), proj); - Graphics::Frustum frustum( modv, proj ); + Graphics::Frustum frustum(modv, proj); // no frustum test of entire gasSphere, since Space::Render does this // for each body using its GetBoundingRadius() value @@ -694,7 +699,7 @@ void GasGiant::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, // make atmosphere sphere slightly bigger than required so // that the edges of the pixel shader atmosphere jizz doesn't // show ugly polygonal angles - DrawAtmosphereSurface(renderer, trans, campos, m_materialParameters.atmosphere.atmosRadius*1.01, m_atmosRenderState, m_atmosphereMaterial); + DrawAtmosphereSurface(renderer, trans, campos, m_materialParameters.atmosphere.atmosRadius * 1.01, m_atmosRenderState, m_atmosphereMaterial); } } @@ -706,7 +711,7 @@ void GasGiant::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, { // give planet some ambient lighting if the viewer is close to it double camdist = campos.Length(); - camdist = 0.1 / (camdist*camdist); + camdist = 0.1 / (camdist * camdist); // why the fuck is this returning 0.1 when we are sat on the planet?? // JJ: Because campos is relative to a unit-radius planet - 1.0 at the surface // XXX oh well, it is the value we want anyway... @@ -718,7 +723,7 @@ void GasGiant::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, renderer->SetTransform(modelView); - for (int i=0; iRender(renderer, campos, modelView, frustum); } @@ -773,7 +778,7 @@ void GasGiant::SetUpMaterials() void GasGiant::BuildFirstPatches() { PROFILE_SCOPED() - if( s_patchContext.Get() == nullptr ) { + if (s_patchContext.Get() == nullptr) { s_patchContext.Reset(new GasPatchContext(127)); } @@ -802,10 +807,10 @@ void GasGiant::Init() SplitData(cfg.String("texture_size_3"), s_texture_size_cpu[3], s_texture_size_gpu[3], s_noiseOctaves[3]); SplitData(cfg.String("texture_size_4"), s_texture_size_cpu[4], s_texture_size_gpu[4], s_noiseOctaves[4]); - s_initialCPUDelayTime = Clamp(cfg.Float("cpu_delay_time", 60.0f), 0.0f, 120.0f); - s_initialGPUDelayTime = Clamp(cfg.Float("gpu_delay_time", 5.0f), 0.0f, 120.0f); + s_initialCPUDelayTime = Clamp(cfg.Float("cpu_delay_time", 60.0f), 0.0f, 120.0f); + s_initialGPUDelayTime = Clamp(cfg.Float("gpu_delay_time", 5.0f), 0.0f, 120.0f); - if( s_patchContext.Get() == nullptr ) { + if (s_patchContext.Get() == nullptr) { s_patchContext.Reset(new GasPatchContext(127)); } CreateRenderTarget(s_texture_size_gpu[Pi::detail.planets], s_texture_size_gpu[Pi::detail.planets]); @@ -817,7 +822,8 @@ void GasGiant::Uninit() } //static -void GasGiant::CreateRenderTarget(const Uint16 width, const Uint16 height) { +void GasGiant::CreateRenderTarget(const Uint16 width, const Uint16 height) +{ /* @fluffyfreak here's a rendertarget implementation you can use for oculusing and other things. It's pretty simple: - fill out a RenderTargetDesc struct and call Renderer::CreateRenderTarget - pass target to Renderer::SetRenderTarget to start rendering to texture @@ -828,7 +834,7 @@ void GasGiant::CreateRenderTarget(const Uint16 width, const Uint16 height) { In that case, leave the color format to NONE so the initial texture is not created, then use SetColorTexture to attach your own. */ Graphics::RenderStateDesc rsd; - rsd.depthTest = false; + rsd.depthTest = false; rsd.depthWrite = false; rsd.blendMode = Graphics::BLEND_ALPHA; s_quadRenderState = Pi::renderer->CreateRenderState(rsd); @@ -838,8 +844,8 @@ void GasGiant::CreateRenderTarget(const Uint16 width, const Uint16 height) { Graphics::RenderTargetDesc rtDesc( width, height, - Graphics::TEXTURE_NONE, // don't create a texture - Graphics::TEXTURE_NONE, // don't create a depth buffer + Graphics::TEXTURE_NONE, // don't create a texture + Graphics::TEXTURE_NONE, // don't create a depth buffer false); s_renderTarget = Pi::renderer->CreateRenderTarget(rtDesc); } @@ -851,11 +857,13 @@ void GasGiant::SetRenderTargetCubemap(const Uint32 face, Graphics::Texture *pTex } //static -void GasGiant::BeginRenderTarget() { +void GasGiant::BeginRenderTarget() +{ Pi::renderer->SetRenderTarget(s_renderTarget); } //static -void GasGiant::EndRenderTarget() { +void GasGiant::EndRenderTarget() +{ Pi::renderer->SetRenderTarget(nullptr); } diff --git a/src/GasGiant.h b/src/GasGiant.h index 67093f9e4..8b9a1a156 100644 --- a/src/GasGiant.h +++ b/src/GasGiant.h @@ -6,19 +6,21 @@ #include -#include "vector3.h" -#include "Random.h" +#include "BaseSphere.h" #include "Camera.h" +#include "GasGiantJobs.h" +#include "JobQueue.h" +#include "Random.h" #include "graphics/Drawables.h" #include "graphics/Material.h" #include "terrain/Terrain.h" -#include "BaseSphere.h" -#include "JobQueue.h" -#include "GasGiantJobs.h" +#include "vector3.h" #include -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class SystemBody; class GasGiant; class GasPatch; @@ -26,7 +28,7 @@ class GasPatchContext; namespace { class STextureFaceResult; class SGPUGenResult; -} +} // namespace #define NUM_PATCHES 6 @@ -53,7 +55,7 @@ public: static void OnChangeDetailLevel(); static void CreateRenderTarget(const Uint16 width, const Uint16 height); - static void SetRenderTargetCubemap(const Uint32, Graphics::Texture*, const bool unBind = true); + static void SetRenderTargetCubemap(const Uint32, Graphics::Texture *, const bool unBind = true); static void BeginRenderTarget(); static void EndRenderTarget(); diff --git a/src/GasGiantJobs.cpp b/src/GasGiantJobs.cpp index dfc504855..9dd1a054a 100644 --- a/src/GasGiantJobs.cpp +++ b/src/GasGiantJobs.cpp @@ -1,43 +1,46 @@ // Copyright © 2008-2015 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "GasGiant.h" #include "GasGiantJobs.h" -#include "perlin.h" -#include "Pi.h" #include "Game.h" +#include "GasGiant.h" +#include "Pi.h" #include "RefCounted.h" -#include "graphics/Material.h" -#include "graphics/opengl/GenGasGiantColourMaterial.h" -#include "graphics/Renderer.h" #include "graphics/Frustum.h" #include "graphics/Graphics.h" +#include "graphics/Material.h" +#include "graphics/Renderer.h" #include "graphics/Texture.h" #include "graphics/TextureBuilder.h" -#include "graphics/VertexArray.h" #include "graphics/Types.h" +#include "graphics/VertexArray.h" +#include "graphics/opengl/GenGasGiantColourMaterial.h" +#include "libs.h" +#include "perlin.h" #include "vcacheopt/vcacheopt.h" -#include #include +#include -namespace GasGiantJobs -{ +namespace GasGiantJobs { static const vector3d s_patchFaces[NUM_PATCHES][4] = - { - { p5, p1, p4, p8 }, // +x - { p2, p6, p7, p3 }, // -x + { + { p5, p1, p4, p8 }, // +x + { p2, p6, p7, p3 }, // -x - { p2, p1, p5, p6 }, // +y - { p7, p8, p4, p3 }, // -y + { p2, p1, p5, p6 }, // +y + { p7, p8, p4, p3 }, // -y - { p6, p5, p8, p7 }, // +z - NB: these are actually reversed! - { p1, p2, p3, p4 } // -z - }; - const vector3d& GetPatchFaces(const Uint32 patch,const Uint32 face) { return s_patchFaces[patch][face]; } + { p6, p5, p8, p7 }, // +z - NB: these are actually reversed! + { p1, p2, p3, p4 } // -z + }; + const vector3d &GetPatchFaces(const Uint32 patch, const Uint32 face) { return s_patchFaces[patch][face]; } STextureFaceRequest::STextureFaceRequest(const vector3d *v_, const SystemPath &sysPath_, const Sint32 face_, const Sint32 uvDIMs_, Terrain *pTerrain_) : - corners(v_), sysPath(sysPath_), face(face_), uvDIMs(uvDIMs_), pTerrain(pTerrain_) + corners(v_), + sysPath(sysPath_), + face(face_), + uvDIMs(uvDIMs_), + pTerrain(pTerrain_) { colors = new Color[NumTexels()]; } @@ -49,10 +52,10 @@ namespace GasGiantJobs PROFILE_SCOPED() //MsgTimer timey; - assert( corners != nullptr ); - double fracStep = 1.0 / double(UVDims()-1); - for( Sint32 v=0; vGetColor(p, 0.0, p); // convert to ubyte and store - Color* col = colors + (u + (v * UVDims())); + Color *col = colors + (u + (v * UVDims())); col[0].r = Uint8(colour.x * 255.0); col[0].g = Uint8(colour.y * 255.0); col[0].b = Uint8(colour.z * 255.0); @@ -80,7 +83,7 @@ namespace GasGiantJobs SingleTextureFaceJob::~SingleTextureFaceJob() { PROFILE_SCOPED() - if(mpResults) { + if (mpResults) { mpResults->OnCancel(); delete mpResults; mpResults = nullptr; @@ -103,7 +106,7 @@ namespace GasGiantJobs void SingleTextureFaceJob::OnFinish() // runs in primary thread of the context { PROFILE_SCOPED() - GasGiant::OnAddTextureFaceResult( mData->SysPath(), mpResults ); + GasGiant::OnAddTextureFaceResult(mData->SysPath(), mpResults); mpResults = nullptr; } @@ -151,9 +154,9 @@ namespace GasGiantJobs Graphics::VertexArray vertices(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - vertices.Add(vector3f(0.0f, 0.0f, 0.0f), vector2f(0.0f, texSize.y)); - vertices.Add(vector3f(0.0f, size.y, 0.0f), vector2f(0.0f, 0.0f)); - vertices.Add(vector3f(size.x, 0.0f, 0.0f), vector2f(texSize.x, texSize.y)); + vertices.Add(vector3f(0.0f, 0.0f, 0.0f), vector2f(0.0f, texSize.y)); + vertices.Add(vector3f(0.0f, size.y, 0.0f), vector2f(0.0f, 0.0f)); + vertices.Add(vector3f(size.x, 0.0f, 0.0f), vector2f(texSize.x, texSize.y)); vertices.Add(vector3f(size.x, size.y, 0.0f), vector2f(texSize.x, 0.0f)); //Create vtx & index buffers and copy data @@ -168,14 +171,21 @@ namespace GasGiantJobs m_vertexBuffer->Populate(vertices); } - void GenFaceQuad::Draw(Graphics::Renderer *r) { + void GenFaceQuad::Draw(Graphics::Renderer *r) + { PROFILE_SCOPED() r->DrawBuffer(m_vertexBuffer.get(), m_renderState, m_material.get(), Graphics::TRIANGLE_STRIP); } // ******************************************************************************** - SGPUGenRequest::SGPUGenRequest(const SystemPath &sysPath_, const Sint32 uvDIMs_, Terrain *pTerrain_, const float planetRadius_, const float hueAdjust_, GenFaceQuad* pQuad_, Graphics::Texture *pTex_) : - m_texture(pTex_), sysPath(sysPath_), uvDIMs(uvDIMs_), pTerrain(pTerrain_), planetRadius(planetRadius_), hueAdjust(hueAdjust_), pQuad(pQuad_) + SGPUGenRequest::SGPUGenRequest(const SystemPath &sysPath_, const Sint32 uvDIMs_, Terrain *pTerrain_, const float planetRadius_, const float hueAdjust_, GenFaceQuad *pQuad_, Graphics::Texture *pTex_) : + m_texture(pTex_), + sysPath(sysPath_), + uvDIMs(uvDIMs_), + pTerrain(pTerrain_), + planetRadius(planetRadius_), + hueAdjust(hueAdjust_), + pQuad(pQuad_) { PROFILE_SCOPED() assert(m_texture.Valid()); @@ -184,12 +194,12 @@ namespace GasGiantJobs void SGPUGenRequest::SetupMaterialParams(const int face) { PROFILE_SCOPED() - m_specialParams.v = &GetPatchFaces(face,0); + m_specialParams.v = &GetPatchFaces(face, 0); m_specialParams.fracStep = 1.0f / float(uvDIMs); m_specialParams.planetRadius = planetRadius; m_specialParams.time = 0.0f; - for(Uint32 i=0; i<3; i++) { + for (Uint32 i = 0; i < 3; i++) { m_specialParams.frequency[i] = float(pTerrain->GetFracDef(i).frequency); } @@ -199,23 +209,31 @@ namespace GasGiantJobs } // ******************************************************************************** - void SGPUGenResult::addResult(Graphics::Texture *t_, Sint32 uvDims_) { + void SGPUGenResult::addResult(Graphics::Texture *t_, Sint32 uvDims_) + { PROFILE_SCOPED() mData = SGPUGenData(t_, uvDims_); } - void SGPUGenResult::OnCancel() { - if( mData.texture ) { mData.texture.Reset(); } + void SGPUGenResult::OnCancel() + { + if (mData.texture) { + mData.texture.Reset(); + } } - + // ******************************************************************************** // Overloaded JobGPU class to handle generating the mesh for each patch // ******************************************************************************** - SingleGPUGenJob::SingleGPUGenJob(SGPUGenRequest *data) : mData(data), mpResults(nullptr) { /* empty */ } + SingleGPUGenJob::SingleGPUGenJob(SGPUGenRequest *data) : + mData(data), + mpResults(nullptr) + { /* empty */ + } SingleGPUGenJob::~SingleGPUGenJob() { PROFILE_SCOPED() - if(mpResults) { + if (mpResults) { mpResults->OnCancel(); delete mpResults; mpResults = nullptr; @@ -241,14 +259,13 @@ namespace GasGiantJobs } GasGiant::BeginRenderTarget(); - for( Uint32 iFace=0; iFaceTexture()); Pi::renderer->BeginFrame(); // draw to the texture here - mData->SetupMaterialParams( iFace ); + mData->SetupMaterialParams(iFace); mData->Quad()->Draw(Pi::renderer); Pi::renderer->EndFrame(); @@ -266,7 +283,7 @@ namespace GasGiantJobs // add this patches data SGPUGenResult *sr = new SGPUGenResult(); - sr->addResult( mData->Texture(), mData->UVDims() ); + sr->addResult(mData->Texture(), mData->UVDims()); // store the result mpResults = sr; @@ -277,8 +294,7 @@ namespace GasGiantJobs void SingleGPUGenJob::OnFinish() // runs in primary thread of the context { PROFILE_SCOPED() - GasGiant::OnAddGPUGenResult( mData->SysPath(), mpResults ); + GasGiant::OnAddGPUGenResult(mData->SysPath(), mpResults); mpResults = nullptr; } -}; - +}; // namespace GasGiantJobs diff --git a/src/GasGiantJobs.h b/src/GasGiantJobs.h index 7880b0067..f7029d42c 100644 --- a/src/GasGiantJobs.h +++ b/src/GasGiantJobs.h @@ -6,22 +6,21 @@ #include -#include "vector3.h" -#include "Random.h" -#include "Camera.h" -#include "graphics/Drawables.h" -#include "graphics/Material.h" -#include "graphics/opengl/GenGasGiantColourMaterial.h" -#include "graphics/TextureBuilder.h" -#include "terrain/Terrain.h" #include "BaseSphere.h" +#include "Camera.h" #include "GeoSphere.h" #include "JobQueue.h" +#include "Random.h" +#include "graphics/Drawables.h" +#include "graphics/Material.h" +#include "graphics/TextureBuilder.h" +#include "graphics/opengl/GenGasGiantColourMaterial.h" +#include "terrain/Terrain.h" +#include "vector3.h" #include -namespace GasGiantJobs -{ +namespace GasGiantJobs { //#define DUMP_PARAMS 1 // generate root face patches of the cube/sphere @@ -34,7 +33,7 @@ namespace GasGiantJobs static const vector3d p7 = (vector3d(-1, -1, -1)).Normalized(); static const vector3d p8 = (vector3d(1, -1, -1)).Normalized(); - const vector3d& GetPatchFaces(const Uint32 patch,const Uint32 face); + const vector3d &GetPatchFaces(const Uint32 patch, const Uint32 face); class STextureFaceRequest { public: @@ -46,18 +45,19 @@ namespace GasGiantJobs Sint32 Face() const { return face; } inline Sint32 UVDims() const { return uvDIMs; } - Color* Colors() const { return colors; } - const SystemPath& SysPath() const { return sysPath; } + Color *Colors() const { return colors; } + const SystemPath &SysPath() const { return sysPath; } protected: // deliberately prevent copy constructor access STextureFaceRequest(const STextureFaceRequest &r) = delete; - inline Sint32 NumTexels() const { return uvDIMs*uvDIMs; } + inline Sint32 NumTexels() const { return uvDIMs * uvDIMs; } // in patch surface coords, [0,1] - inline vector3d GetSpherePoint(const double x, const double y) const { - return (corners[0] + x*(1.0 - y)*(corners[1] - corners[0]) + x*y*(corners[2] - corners[0]) + (1.0 - x)*y*(corners[3] - corners[0])).Normalized(); + inline vector3d GetSpherePoint(const double x, const double y) const + { + return (corners[0] + x * (1.0 - y) * (corners[1] - corners[0]) + x * y * (corners[2] - corners[0]) + (1.0 - x) * y * (corners[3] - corners[0])).Normalized(); } // these are created with the request and are given to the resulting patches @@ -74,24 +74,34 @@ namespace GasGiantJobs public: struct STextureFaceData { STextureFaceData() {} - STextureFaceData(Color *c_, Sint32 uvDims_) : colors(c_), uvDims(uvDims_) {} - STextureFaceData(const STextureFaceData &r) : colors(r.colors), uvDims(r.uvDims) {} + STextureFaceData(Color *c_, Sint32 uvDims_) : + colors(c_), + uvDims(uvDims_) {} + STextureFaceData(const STextureFaceData &r) : + colors(r.colors), + uvDims(r.uvDims) {} Color *colors; Sint32 uvDims; }; - STextureFaceResult(const int32_t face_) : mFace(face_) {} + STextureFaceResult(const int32_t face_) : + mFace(face_) {} - void addResult(Color *c_, Sint32 uvDims_) { + void addResult(Color *c_, Sint32 uvDims_) + { PROFILE_SCOPED() mData = STextureFaceData(c_, uvDims_); } - inline const STextureFaceData& data() const { return mData; } + inline const STextureFaceData &data() const { return mData; } inline int32_t face() const { return mFace; } - void OnCancel() { - if (mData.colors) { delete[] mData.colors; mData.colors = NULL; } + void OnCancel() + { + if (mData.colors) { + delete[] mData.colors; + mData.colors = NULL; + } } protected: @@ -105,10 +115,13 @@ namespace GasGiantJobs // ******************************************************************************** // Overloaded PureJob class to handle generating the mesh for each patch // ******************************************************************************** - class SingleTextureFaceJob : public Job - { + class SingleTextureFaceJob : public Job { public: - SingleTextureFaceJob(STextureFaceRequest *data) : mData(data), mpResults(nullptr) { /* empty */ } + SingleTextureFaceJob(STextureFaceRequest *data) : + mData(data), + mpResults(nullptr) + { /* empty */ + } virtual ~SingleTextureFaceJob(); virtual void OnRun(); @@ -130,8 +143,13 @@ namespace GasGiantJobs GenFaceQuad(Graphics::Renderer *r, const vector2f &size, Graphics::RenderState *state, const Uint32 GGQuality); virtual void Draw(Graphics::Renderer *r); - void SetMaterial(Graphics::Material *mat) { assert(mat); m_material.reset(mat); } - Graphics::Material* GetMaterial() const { return m_material.get(); } + void SetMaterial(Graphics::Material *mat) + { + assert(mat); + m_material.reset(mat); + } + Graphics::Material *GetMaterial() const { return m_material.get(); } + private: std::unique_ptr m_material; std::unique_ptr m_vertexBuffer; @@ -141,19 +159,19 @@ namespace GasGiantJobs // ******************************************************************************** class SGPUGenRequest { public: - SGPUGenRequest(const SystemPath &sysPath_, const Sint32 uvDIMs_, Terrain *pTerrain_, const float planetRadius_, const float hueAdjust_, GenFaceQuad* pQuad_, Graphics::Texture *pTex_); + SGPUGenRequest(const SystemPath &sysPath_, const Sint32 uvDIMs_, Terrain *pTerrain_, const float planetRadius_, const float hueAdjust_, GenFaceQuad *pQuad_, Graphics::Texture *pTex_); inline Sint32 UVDims() const { return uvDIMs; } - Graphics::Texture* Texture() const { return m_texture.Get(); } - GenFaceQuad* Quad() const { return pQuad; } - const SystemPath& SysPath() const { return sysPath; } + Graphics::Texture *Texture() const { return m_texture.Get(); } + GenFaceQuad *Quad() const { return pQuad; } + const SystemPath &SysPath() const { return sysPath; } void SetupMaterialParams(const int face); protected: // deliberately prevent copy constructor access SGPUGenRequest(const SGPUGenRequest &r) = delete; - inline Sint32 NumTexels() const { return uvDIMs*uvDIMs; } + inline Sint32 NumTexels() const { return uvDIMs * uvDIMs; } // this is created with the request and are given to the resulting patches RefCountedPtr m_texture; @@ -163,7 +181,7 @@ namespace GasGiantJobs Terrain *pTerrain; const float planetRadius; const float hueAdjust; - GenFaceQuad* pQuad; + GenFaceQuad *pQuad; Graphics::GenGasGiantColourMaterialParameters m_specialParams; }; @@ -172,8 +190,12 @@ namespace GasGiantJobs public: struct SGPUGenData { SGPUGenData() {} - SGPUGenData(Graphics::Texture *t_, Sint32 uvDims_) : texture(t_), uvDims(uvDims_) {} - SGPUGenData(const SGPUGenData &r) : texture(r.texture), uvDims(r.uvDims) {} + SGPUGenData(Graphics::Texture *t_, Sint32 uvDims_) : + texture(t_), + uvDims(uvDims_) {} + SGPUGenData(const SGPUGenData &r) : + texture(r.texture), + uvDims(r.uvDims) {} RefCountedPtr texture; Sint32 uvDims; }; @@ -182,7 +204,7 @@ namespace GasGiantJobs void addResult(Graphics::Texture *t_, Sint32 uvDims_); - inline const SGPUGenData& data() const { return mData; } + inline const SGPUGenData &data() const { return mData; } void OnCancel(); @@ -196,8 +218,7 @@ namespace GasGiantJobs // ******************************************************************************** // Overloaded JobGPU class to handle generating the mesh for each patch // ******************************************************************************** - class SingleGPUGenJob : public Job - { + class SingleGPUGenJob : public Job { public: SingleGPUGenJob(SGPUGenRequest *data); virtual ~SingleGPUGenJob(); @@ -214,7 +235,6 @@ namespace GasGiantJobs std::unique_ptr mData; SGPUGenResult *mpResults; }; -}; - +}; // namespace GasGiantJobs #endif /* _GASGIANTJOBS_H */ diff --git a/src/GeoPatch.cpp b/src/GeoPatch.cpp index d1a461f41..fb0548c2a 100644 --- a/src/GeoPatch.cpp +++ b/src/GeoPatch.cpp @@ -1,58 +1,67 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "GeoPatchContext.h" #include "GeoPatch.h" +#include "GeoPatchContext.h" #include "GeoPatchJobs.h" #include "GeoSphere.h" -#include "perlin.h" +#include "MathUtil.h" #include "Pi.h" #include "RefCounted.h" -#include "graphics/Material.h" -#include "graphics/Renderer.h" +#include "Sphere.h" #include "graphics/Frustum.h" #include "graphics/Graphics.h" +#include "graphics/Material.h" +#include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "MathUtil.h" -#include "Sphere.h" +#include "libs.h" +#include "perlin.h" #include "vcacheopt/vcacheopt.h" -#include #include +#include // tri edge lengths static const double GEOPATCH_SUBDIVIDE_AT_CAMDIST = 5.0; GeoPatch::GeoPatch(const RefCountedPtr &ctx_, GeoSphere *gs, const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, - const int depth, const GeoPatchID &ID_) - : ctx(ctx_), v0(v0_), v1(v1_), v2(v2_), v3(v3_), - heights(nullptr), normals(nullptr), colors(nullptr), - parent(nullptr), geosphere(gs), - m_depth(depth), mPatchID(ID_), + const int depth, const GeoPatchID &ID_) : + ctx(ctx_), + v0(v0_), + v1(v1_), + v2(v2_), + v3(v3_), + heights(nullptr), + normals(nullptr), + colors(nullptr), + parent(nullptr), + geosphere(gs), + m_depth(depth), + mPatchID(ID_), mHasJobRequest(false) { - clipCentroid = (v0+v1+v2+v3) * 0.25; + clipCentroid = (v0 + v1 + v2 + v3) * 0.25; centroid = clipCentroid.Normalized(); clipRadius = 0.0; - clipRadius = std::max(clipRadius, (v0-clipCentroid).Length()); - clipRadius = std::max(clipRadius, (v1-clipCentroid).Length()); - clipRadius = std::max(clipRadius, (v2-clipCentroid).Length()); - clipRadius = std::max(clipRadius, (v3-clipCentroid).Length()); + clipRadius = std::max(clipRadius, (v0 - clipCentroid).Length()); + clipRadius = std::max(clipRadius, (v1 - clipCentroid).Length()); + clipRadius = std::max(clipRadius, (v2 - clipCentroid).Length()); + clipRadius = std::max(clipRadius, (v3 - clipCentroid).Length()); double distMult; if (geosphere->GetSystemBody()->GetType() < SystemBody::TYPE_PLANET_ASTEROID) { - distMult = 10.0 / Clamp(depth, 1, 10); - } else { - distMult = 5.0 / Clamp(depth, 1, 5); - } + distMult = 10.0 / Clamp(depth, 1, 10); + } else { + distMult = 5.0 / Clamp(depth, 1, 5); + } m_roughLength = GEOPATCH_SUBDIVIDE_AT_CAMDIST / pow(2.0, depth) * distMult; m_needUpdateVBOs = false; } -GeoPatch::~GeoPatch() { +GeoPatch::~GeoPatch() +{ mHasJobRequest = false; - for (int i=0; iNUMVERTICES(); vbd.usage = Graphics::BUFFER_USAGE_STATIC; m_vertexBuffer.reset(renderer->CreateVertexBuffer(vbd)); - GeoPatchContext::VBOVertex* VBOVtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + GeoPatchContext::VBOVertex *VBOVtxPtr = m_vertexBuffer->Map(Graphics::BUFFER_MAP_WRITE); assert(m_vertexBuffer->GetDesc().stride == sizeof(GeoPatchContext::VBOVertex)); const Sint32 edgeLen = ctx->GetEdgeLen(); @@ -94,8 +103,8 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) // ---------------------------------------------------- // inner loops - for (Sint32 y = 1; ypos = vector3f(p); - ++pHts; // next height + ++pHts; // next height const vector3f norma(pNorm->Normalized()); vtxPtr->norm = norma; @@ -133,13 +142,13 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) // vertical edges // left-edge for (Sint32 y = 1; y < edgeLen - 1; y++) { - const Sint32 x = innerLeft-1; + const Sint32 x = innerLeft - 1; const double xFrac = double(x - 1) * frac; const double yFrac = double(y - 1) * frac; const vector3d p((GetSpherePoint(xFrac, yFrac) * minhScale) - clipCentroid); - GeoPatchContext::VBOVertex* vtxPtr = &VBOVtxPtr[outerLeft + (y*edgeLen)]; - GeoPatchContext::VBOVertex* vtxInr = &VBOVtxPtr[innerLeft + (y*edgeLen)]; + GeoPatchContext::VBOVertex *vtxPtr = &VBOVtxPtr[outerLeft + (y * edgeLen)]; + GeoPatchContext::VBOVertex *vtxInr = &VBOVtxPtr[innerLeft + (y * edgeLen)]; vtxPtr->pos = vector3f(p); vtxPtr->norm = vtxInr->norm; vtxPtr->col = vtxInr->col; @@ -147,13 +156,13 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) } // right-edge for (Sint32 y = 1; y < edgeLen - 1; y++) { - const Sint32 x = innerRight+1; + const Sint32 x = innerRight + 1; const double xFrac = double(x - 1) * frac; const double yFrac = double(y - 1) * frac; const vector3d p((GetSpherePoint(xFrac, yFrac) * minhScale) - clipCentroid); - GeoPatchContext::VBOVertex* vtxPtr = &VBOVtxPtr[outerRight + (y*edgeLen)]; - GeoPatchContext::VBOVertex* vtxInr = &VBOVtxPtr[innerRight + (y*edgeLen)]; + GeoPatchContext::VBOVertex *vtxPtr = &VBOVtxPtr[outerRight + (y * edgeLen)]; + GeoPatchContext::VBOVertex *vtxInr = &VBOVtxPtr[innerRight + (y * edgeLen)]; vtxPtr->pos = vector3f(p); vtxPtr->norm = vtxInr->norm; vtxPtr->col = vtxInr->col; @@ -166,30 +175,28 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) const Sint32 outerBottom = edgeLen - 1; // horizontal edges // top-edge - for (Sint32 x = 1; x < edgeLen - 1; x++) - { - const Sint32 y = innerTop-1; + for (Sint32 x = 1; x < edgeLen - 1; x++) { + const Sint32 y = innerTop - 1; const double xFrac = double(x - 1) * frac; const double yFrac = double(y - 1) * frac; const vector3d p((GetSpherePoint(xFrac, yFrac) * minhScale) - clipCentroid); - GeoPatchContext::VBOVertex* vtxPtr = &VBOVtxPtr[x + (outerTop*edgeLen)]; - GeoPatchContext::VBOVertex* vtxInr = &VBOVtxPtr[x + (innerTop*edgeLen)]; + GeoPatchContext::VBOVertex *vtxPtr = &VBOVtxPtr[x + (outerTop * edgeLen)]; + GeoPatchContext::VBOVertex *vtxInr = &VBOVtxPtr[x + (innerTop * edgeLen)]; vtxPtr->pos = vector3f(p); vtxPtr->norm = vtxInr->norm; vtxPtr->col = vtxInr->col; vtxPtr->uv = vtxInr->uv; } // bottom-edge - for (Sint32 x = 1; x < edgeLen - 1; x++) - { - const Sint32 y = innerBottom+1; + for (Sint32 x = 1; x < edgeLen - 1; x++) { + const Sint32 y = innerBottom + 1; const double xFrac = double(x - 1) * frac; const double yFrac = double(y - 1) * frac; const vector3d p((GetSpherePoint(xFrac, yFrac) * minhScale) - clipCentroid); - GeoPatchContext::VBOVertex* vtxPtr = &VBOVtxPtr[x + (outerBottom * edgeLen)]; - GeoPatchContext::VBOVertex* vtxInr = &VBOVtxPtr[x + (innerBottom * edgeLen)]; + GeoPatchContext::VBOVertex *vtxPtr = &VBOVtxPtr[x + (outerBottom * edgeLen)]; + GeoPatchContext::VBOVertex *vtxInr = &VBOVtxPtr[x + (innerBottom * edgeLen)]; vtxPtr->pos = vector3f(p); vtxPtr->norm = vtxInr->norm; vtxPtr->col = vtxInr->col; @@ -199,26 +206,26 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) // corners { // top left - GeoPatchContext::VBOVertex* tarPtr = &VBOVtxPtr[0]; - GeoPatchContext::VBOVertex* srcPtr = &VBOVtxPtr[1]; + GeoPatchContext::VBOVertex *tarPtr = &VBOVtxPtr[0]; + GeoPatchContext::VBOVertex *srcPtr = &VBOVtxPtr[1]; (*tarPtr) = (*srcPtr); } { // top right - GeoPatchContext::VBOVertex* tarPtr = &VBOVtxPtr[(edgeLen - 1)]; - GeoPatchContext::VBOVertex* srcPtr = &VBOVtxPtr[(edgeLen - 2)]; + GeoPatchContext::VBOVertex *tarPtr = &VBOVtxPtr[(edgeLen - 1)]; + GeoPatchContext::VBOVertex *srcPtr = &VBOVtxPtr[(edgeLen - 2)]; (*tarPtr) = (*srcPtr); } { // bottom left - GeoPatchContext::VBOVertex* tarPtr = &VBOVtxPtr[(edgeLen - 1) * edgeLen]; - GeoPatchContext::VBOVertex* srcPtr = &VBOVtxPtr[(edgeLen - 2) * edgeLen]; + GeoPatchContext::VBOVertex *tarPtr = &VBOVtxPtr[(edgeLen - 1) * edgeLen]; + GeoPatchContext::VBOVertex *srcPtr = &VBOVtxPtr[(edgeLen - 2) * edgeLen]; (*tarPtr) = (*srcPtr); } { // bottom right - GeoPatchContext::VBOVertex* tarPtr = &VBOVtxPtr[(edgeLen - 1) + ((edgeLen - 1) * edgeLen)]; - GeoPatchContext::VBOVertex* srcPtr = &VBOVtxPtr[(edgeLen - 1) + ((edgeLen - 2) * edgeLen)]; + GeoPatchContext::VBOVertex *tarPtr = &VBOVtxPtr[(edgeLen - 1) + ((edgeLen - 1) * edgeLen)]; + GeoPatchContext::VBOVertex *srcPtr = &VBOVtxPtr[(edgeLen - 1) + ((edgeLen - 2) * edgeLen)]; (*tarPtr) = (*srcPtr); } @@ -232,7 +239,7 @@ void GeoPatch::UpdateVBOs(Graphics::Renderer *renderer) #ifdef DEBUG_BOUNDING_SPHERES RefCountedPtr mat(Pi::renderer->CreateMaterial(Graphics::MaterialDescriptor())); - m_boundsphere.reset( new Graphics::Drawables::Sphere3D(Pi::renderer, mat, Pi::renderer->CreateRenderState(Graphics::RenderStateDesc()), 0, clipRadius) ); + m_boundsphere.reset(new Graphics::Drawables::Sphere3D(Pi::renderer, mat, Pi::renderer->CreateRenderState(Graphics::RenderStateDesc()), 0, clipRadius)); #endif } } @@ -254,18 +261,19 @@ void GeoPatch::Render(Graphics::Renderer *renderer, const vector3d &campos, cons const vector3d cenDir(clipCentroid.Normalized()); const double dotProd = camDirNorm.Dot(cenDir); - if( dotProd < 0.25 && (camDir.LengthSqr() > (clipRadius*clipRadius)) ) { + if (dotProd < 0.25 && (camDir.LengthSqr() > (clipRadius * clipRadius))) { SSphere obj; obj.m_centre = clipCentroid; obj.m_radius = clipRadius; - if( !s_sph.HorizonCulling(campos, obj) ) { + if (!s_sph.HorizonCulling(campos, obj)) { return; // nothing below this patch is visible } } if (kids[0]) { - for (int i=0; iRender(renderer, campos, modelView, frustum); + for (int i = 0; i < NUM_KIDS; i++) + kids[i]->Render(renderer, campos, modelView, frustum); } else if (heights) { RefCountedPtr mat = geosphere->GetSurfaceMaterial(); Graphics::RenderState *rs = geosphere->GetSurfRenderState(); @@ -281,7 +289,7 @@ void GeoPatch::Render(Graphics::Renderer *renderer, const vector3d &campos, cons renderer->DrawBufferIndexed(m_vertexBuffer.get(), ctx->GetIndexBuffer(), rs, mat.Get()); #ifdef DEBUG_BOUNDING_SPHERES - if(m_boundsphere.get()) { + if (m_boundsphere.get()) { renderer->SetWireFrameMode(true); m_boundsphere->Draw(renderer); renderer->SetWireFrameMode(false); @@ -294,7 +302,7 @@ void GeoPatch::Render(Graphics::Renderer *renderer, const vector3d &campos, cons void GeoPatch::LODUpdate(const vector3d &campos, const Graphics::Frustum &frustum) { // there should be no LOD update when we have active split requests - if(mHasJobRequest) + if (mHasJobRequest) return; bool canSplit = true; @@ -305,7 +313,7 @@ void GeoPatch::LODUpdate(const vector3d &campos, const Graphics::Frustum &frustu if (parent) { centroidDist = (campos - centroid).Length(); const bool errorSplit = (centroidDist < m_roughLength); - if( !(canSplit && (m_depth < std::min(GEOPATCH_MAX_DEPTH, geosphere->GetMaxDepth())) && errorSplit) ) { + if (!(canSplit && (m_depth < std::min(GEOPATCH_MAX_DEPTH, geosphere->GetMaxDepth())) && errorSplit)) { canSplit = false; } } @@ -322,7 +330,7 @@ void GeoPatch::LODUpdate(const vector3d &campos, const Graphics::Frustum &frustu const vector3d cenDir(clipCentroid.Normalized()); const double dotProd = camDirNorm.Dot(cenDir); - if (dotProd < 0.25 && (camDir.LengthSqr() >(clipRadius*clipRadius))) { + if (dotProd < 0.25 && (camDir.LengthSqr() > (clipRadius * clipRadius))) { SSphere obj; obj.m_centre = clipCentroid; obj.m_radius = clipRadius; @@ -337,22 +345,22 @@ void GeoPatch::LODUpdate(const vector3d &campos, const Graphics::Frustum &frustu mHasJobRequest = true; SQuadSplitRequest *ssrd = new SQuadSplitRequest(v0, v1, v2, v3, centroid.Normalized(), m_depth, - geosphere->GetSystemBody()->GetPath(), mPatchID, ctx->GetEdgeLen()-2, - ctx->GetFrac(), geosphere->GetTerrain()); + geosphere->GetSystemBody()->GetPath(), mPatchID, ctx->GetEdgeLen() - 2, + ctx->GetFrac(), geosphere->GetTerrain()); // add to the GeoSphere to be processed at end of all LODUpdate requests geosphere->AddQuadSplitRequest(centroidDist, ssrd, this); } else { - for (int i=0; iLODUpdate(campos, frustum); } } } else if (canMerge) { - for (int i=0; icanBeMerged(); } - if( canMerge ) { - for (int i=0; iGetSystemBody()->GetPath(), mPatchID, ctx->GetEdgeLen()-2, ctx->GetFrac(), geosphere->GetTerrain()); + geosphere->GetSystemBody()->GetPath(), mPatchID, ctx->GetEdgeLen() - 2, ctx->GetFrac(), geosphere->GetTerrain()); m_job = Pi::GetAsyncJobQueue()->Queue(new SinglePatchJob(ssrd)); } } @@ -373,38 +381,36 @@ void GeoPatch::RequestSinglePatch() void GeoPatch::ReceiveHeightmaps(SQuadSplitResult *psr) { PROFILE_SCOPED() - assert(NULL!=psr); - if (m_depthdepth()) { + assert(NULL != psr); + if (m_depth < psr->depth()) { // this should work because each depth should have a common history - const Uint32 kidIdx = psr->data(0).patchID.GetPatchIdx(m_depth+1); - if( kids[kidIdx] ) { + const Uint32 kidIdx = psr->data(0).patchID.GetPatchIdx(m_depth + 1); + if (kids[kidIdx]) { kids[kidIdx]->ReceiveHeightmaps(psr); } else { psr->OnCancel(); } } else { assert(mHasJobRequest); - const int nD = m_depth+1; - for (int i=0; idata(i); - assert(i==data.patchID.GetPatchIdx(nD)); - assert(0==data.patchID.GetPatchIdx(nD+1)); + const SQuadSplitResult::SSplitResultData &data = psr->data(i); + assert(i == data.patchID.GetPatchIdx(nD)); + assert(0 == data.patchID.GetPatchIdx(nD + 1)); kids[i].reset(new GeoPatch(ctx, geosphere, data.v0, data.v1, data.v2, data.v3, nD, data.patchID)); } kids[0]->parent = kids[1]->parent = kids[2]->parent = kids[3]->parent = this; - for (int i=0; idata(i); + for (int i = 0; i < NUM_KIDS; i++) { + const SQuadSplitResult::SSplitResultData &data = psr->data(i); kids[i]->heights.reset(data.heights); kids[i]->normals.reset(data.normals); kids[i]->colors.reset(data.colors); } - for (int i=0; iNeedToUpdateVBOs(); } mHasJobRequest = false; @@ -418,7 +424,7 @@ void GeoPatch::ReceiveHeightmap(const SSingleSplitResult *psr) assert(nullptr != psr); assert(mHasJobRequest); { - const SSingleSplitResult::SSplitResultData& data = psr->data(); + const SSingleSplitResult::SSplitResultData &data = psr->data(); heights.reset(data.heights); normals.reset(data.normals); colors.reset(data.colors); @@ -429,5 +435,5 @@ void GeoPatch::ReceiveHeightmap(const SSingleSplitResult *psr) void GeoPatch::ReceiveJobHandle(Job::Handle job) { assert(!m_job.HasJob()); - m_job = static_cast(job); + m_job = static_cast(job); } diff --git a/src/GeoPatch.h b/src/GeoPatch.h index 766c622de..696916989 100644 --- a/src/GeoPatch.h +++ b/src/GeoPatch.h @@ -6,20 +6,22 @@ #include -#include "vector3.h" +#include "GeoPatchID.h" +#include "JobQueue.h" #include "Random.h" #include "galaxy/StarSystem.h" #include "graphics/Frustum.h" #include "graphics/Material.h" #include "terrain/Terrain.h" -#include "GeoPatchID.h" -#include "JobQueue.h" +#include "vector3.h" #include // #define DEBUG_BOUNDING_SPHERES -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class SystemBody; class GeoPatchContext; class GeoSphere; @@ -53,21 +55,22 @@ private: std::unique_ptr m_boundsphere; #endif public: - GeoPatch(const RefCountedPtr &_ctx, GeoSphere *gs, const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const int depth, const GeoPatchID &ID_); ~GeoPatch(); - inline void NeedToUpdateVBOs() { + inline void NeedToUpdateVBOs() + { m_needUpdateVBOs = (nullptr != heights); } void UpdateVBOs(Graphics::Renderer *renderer); - int GetChildIdx(const GeoPatch *child) const { - for (int i=0; icanBeMerged(); } } @@ -99,7 +104,7 @@ public: void ReceiveHeightmap(const SSingleSplitResult *psr); void ReceiveJobHandle(Job::Handle job); - inline bool HasHeightData() const { return (heights.get()!=nullptr); } + inline bool HasHeightData() const { return (heights.get() != nullptr); } }; #endif /* _GEOPATCH_H */ diff --git a/src/GeoPatchContext.cpp b/src/GeoPatchContext.cpp index 4388348aa..f6f9690b1 100644 --- a/src/GeoPatchContext.cpp +++ b/src/GeoPatchContext.cpp @@ -1,19 +1,19 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "GeoPatchContext.h" -#include "perlin.h" #include "Pi.h" #include "RefCounted.h" -#include "graphics/Material.h" -#include "graphics/Renderer.h" #include "graphics/Frustum.h" #include "graphics/Graphics.h" +#include "graphics/Material.h" +#include "graphics/Renderer.h" #include "graphics/VertexArray.h" +#include "libs.h" +#include "perlin.h" #include "vcacheopt/vcacheopt.h" -#include #include +#include // static instances int GeoPatchContext::edgeLen = 0; @@ -36,7 +36,7 @@ void GeoPatchContext::GenerateIndices() { // calculate how many tri's there are tri_count = (VBO_COUNT_MID_IDX() / 3); - for (int i = 0; i<4; ++i) { + for (int i = 0; i < 4; ++i) { tri_count += (VBO_COUNT_HI_EDGE() / 3); } @@ -44,30 +44,30 @@ void GeoPatchContext::GenerateIndices() pl_short.reserve(tri_count); // add all of the middle indices - for (int i = 0; iCreateIndexBuffer(pl_short.size(), Graphics::BUFFER_USAGE_STATIC)); - Uint32* idxPtr = indices->Map(Graphics::BUFFER_MAP_WRITE); + Uint32 *idxPtr = indices->Map(Graphics::BUFFER_MAP_WRITE); for (Uint32 j = 0; j < pl_short.size(); j++) { idxPtr[j] = pl_short[j]; } @@ -92,9 +92,8 @@ void GeoPatchContext::GenerateIndices() void GeoPatchContext::Init() { - frac = 1.0 / double(edgeLen-3); - numTris = 2*(edgeLen-1)*(edgeLen-1); + frac = 1.0 / double(edgeLen - 3); + numTris = 2 * (edgeLen - 1) * (edgeLen - 1); GenerateIndices(); } - diff --git a/src/GeoPatchContext.h b/src/GeoPatchContext.h index 1fae94814..26c7ad8d8 100644 --- a/src/GeoPatchContext.h +++ b/src/GeoPatchContext.h @@ -6,20 +6,22 @@ #include -#include "vector3.h" +#include "GeoPatchID.h" #include "Random.h" #include "galaxy/StarSystem.h" #include "graphics/Material.h" #include "graphics/VertexBuffer.h" #include "terrain/Terrain.h" -#include "GeoPatchID.h" +#include "vector3.h" #include // maximumpatch depth -#define GEOPATCH_MAX_DEPTH 15 + (2*Pi::detail.fracmult) //15 +#define GEOPATCH_MAX_DEPTH 15 + (2 * Pi::detail.fracmult) //15 -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class SystemBody; class GeoPatch; class GeoSphere; @@ -31,12 +33,12 @@ private: static double frac; - static inline int VBO_COUNT_HI_EDGE() { return 3*(edgeLen-1); } - static inline int VBO_COUNT_MID_IDX() { return (4*3*(edgeLen-3)) + 2*(edgeLen-3)*(edgeLen-3)*3; } + static inline int VBO_COUNT_HI_EDGE() { return 3 * (edgeLen - 1); } + static inline int VBO_COUNT_MID_IDX() { return (4 * 3 * (edgeLen - 3)) + 2 * (edgeLen - 3) * (edgeLen - 3) * 3; } // ^^ serrated teeth bit ^^^ square inner bit - static inline int IDX_VBO_LO_OFFSET(const int i) { return i*sizeof(Uint32)*3*(edgeLen/2); } - static inline int IDX_VBO_HI_OFFSET(const int i) { return (i*sizeof(Uint32)*VBO_COUNT_HI_EDGE())+IDX_VBO_LO_OFFSET(4); } + static inline int IDX_VBO_LO_OFFSET(const int i) { return i * sizeof(Uint32) * 3 * (edgeLen / 2); } + static inline int IDX_VBO_HI_OFFSET(const int i) { return (i * sizeof(Uint32) * VBO_COUNT_HI_EDGE()) + IDX_VBO_LO_OFFSET(4); } static RefCountedPtr indices; static int prevEdgeLen; @@ -44,28 +46,29 @@ private: static void GenerateIndices(); public: - struct VBOVertex - { + struct VBOVertex { vector3f pos; vector3f norm; Color4ub col; vector2f uv; }; - GeoPatchContext(const int _edgeLen) { + GeoPatchContext(const int _edgeLen) + { edgeLen = _edgeLen + 2; // +2 for the skirt Init(); } - static void Refresh() { + static void Refresh() + { Init(); } static void Init(); - static inline Graphics::IndexBuffer* GetIndexBuffer() { return indices.Get(); } + static inline Graphics::IndexBuffer *GetIndexBuffer() { return indices.Get(); } - static inline int NUMVERTICES() { return edgeLen*edgeLen; } + static inline int NUMVERTICES() { return edgeLen * edgeLen; } static inline int GetEdgeLen() { return edgeLen; } static inline int GetNumTris() { return numTris; } diff --git a/src/GeoPatchID.cpp b/src/GeoPatchID.cpp index 5483a7c3f..c2864d3f6 100644 --- a/src/GeoPatchID.cpp +++ b/src/GeoPatchID.cpp @@ -9,26 +9,26 @@ static const int MAX_PATCH_DEPTH = 30; uint64_t GeoPatchID::NextPatchID(const int depth, const int idx) const { - assert(idx>=0 && idx<4); - assert(depth<=MAX_PATCH_DEPTH); + assert(idx >= 0 && idx < 4); + assert(depth <= MAX_PATCH_DEPTH); const uint64_t idx64 = idx; - const uint64_t shiftDepth64 = depth*2ULL; - assert((mPatchID & (3ULL<> shiftDepth64; - assert(idx64<=uint64_t(-1)); + assert(depth <= MAX_PATCH_DEPTH); + const uint64_t shiftDepth64 = depth * 2ULL; + const uint64_t idx64 = (mPatchID & (3ULL << shiftDepth64)) >> shiftDepth64; + assert(idx64 <= uint64_t(-1)); return int(idx64); } int GeoPatchID::GetPatchFaceIdx() const { const int res = (mPatchID & (7ULL << MAX_SHIFT_DEPTH)) >> MAX_SHIFT_DEPTH; - assert(res>=0 && res<6); + assert(res >= 0 && res < 6); return res; } diff --git a/src/GeoPatchID.h b/src/GeoPatchID.h index c121bd40e..17eaf3125 100644 --- a/src/GeoPatchID.h +++ b/src/GeoPatchID.h @@ -6,13 +6,15 @@ #include -class GeoPatchID -{ +class GeoPatchID { private: uint64_t mPatchID; + public: - GeoPatchID(const uint64_t init) : mPatchID(init) {} - GeoPatchID(const GeoPatchID &init) : mPatchID(init.mPatchID) {} + GeoPatchID(const uint64_t init) : + mPatchID(init) {} + GeoPatchID(const GeoPatchID &init) : + mPatchID(init.mPatchID) {} static const uint64_t MAX_SHIFT_DEPTH = 61; diff --git a/src/GeoPatchJobs.cpp b/src/GeoPatchJobs.cpp index c5df2c9f7..a2e261de5 100644 --- a/src/GeoPatchJobs.cpp +++ b/src/GeoPatchJobs.cpp @@ -1,23 +1,25 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "GeoPatchJobs.h" -#include "GeoSphere.h" #include "GeoPatch.h" -#include "perlin.h" +#include "GeoSphere.h" #include "Pi.h" #include "RefCounted.h" +#include "libs.h" +#include "perlin.h" -inline void setColour(Color3ub &r, const vector3d &v) { - r.r=static_cast(Clamp(v.x*255.0, 0.0, 255.0)); - r.g=static_cast(Clamp(v.y*255.0, 0.0, 255.0)); - r.b=static_cast(Clamp(v.z*255.0, 0.0, 255.0)); +inline void setColour(Color3ub &r, const vector3d &v) +{ + r.r = static_cast(Clamp(v.x * 255.0, 0.0, 255.0)); + r.g = static_cast(Clamp(v.y * 255.0, 0.0, 255.0)); + r.b = static_cast(Clamp(v.z * 255.0, 0.0, 255.0)); } // in patch surface coords, [0,1] -inline vector3d GetSpherePoint(const vector3d &v0, const vector3d &v1, const vector3d &v2, const vector3d &v3, const double x, const double y) { - return (v0 + x*(1.0-y)*(v1-v0) + x*y*(v2-v0) + (1.0-x)*y*(v3-v0)).Normalized(); +inline vector3d GetSpherePoint(const vector3d &v0, const vector3d &v1, const vector3d &v2, const vector3d &v3, const double x, const double y) +{ + return (v0 + x * (1.0 - y) * (v1 - v0) + x * y * (v2 - v0) + (1.0 - x) * y * (v3 - v0)).Normalized(); } // ******************************************************************************** @@ -40,15 +42,15 @@ void SinglePatchJob::GenerateMesh(const SSingleSplitRequest *data) const const double fracStep = data->fracStep; const Terrain *pTerrain = data->pTerrain.Get(); - const int borderedEdgeLen = edgeLen+(BORDER_SIZE*2); - const int numBorderedVerts = borderedEdgeLen*borderedEdgeLen; + const int borderedEdgeLen = edgeLen + (BORDER_SIZE * 2); + const int numBorderedVerts = borderedEdgeLen * borderedEdgeLen; // generate heights plus a 1 unit border double *bhts = data->borderHeights.get(); vector3d *vrts = borderVertexs; - for (int y=-BORDER_SIZE; yGetHeight(p); @@ -64,45 +66,45 @@ void SinglePatchJob::GenerateMesh(const SSingleSplitRequest *data) const vector3f *nrm = normals; double *hts = heights; vrts = borderVertexs; - for (int y=BORDER_SIZE; yGetColor(p, height, n)); - assert(col!=&colors[edgeLen*edgeLen]); + assert(col != &colors[edgeLen * edgeLen]); ++col; } } - assert(hts == &heights[edgeLen*edgeLen]); - assert(nrm == &normals[edgeLen*edgeLen]); - assert(col == &colors[edgeLen*edgeLen]); + assert(hts == &heights[edgeLen * edgeLen]); + assert(nrm == &normals[edgeLen * edgeLen]); + assert(col == &colors[edgeLen * edgeLen]); } // ******************************************************************************** // Overloaded PureJob class to handle generating the mesh for each patch // ******************************************************************************** -void SinglePatchJob::OnFinish() // runs in primary thread of the context +void SinglePatchJob::OnFinish() // runs in primary thread of the context { - GeoSphere::OnAddSingleSplitResult( mData->sysPath, mpResults ); + GeoSphere::OnAddSingleSplitResult(mData->sysPath, mpResults); mpResults = nullptr; BasePatchJob::OnFinish(); } -void SinglePatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! +void SinglePatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! { BasePatchJob::OnRun(); @@ -115,14 +117,14 @@ void SinglePatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! SSingleSplitResult *sr = new SSingleSplitResult(srd.patchID.GetPatchFaceIdx(), srd.depth); sr->addResult(srd.heights, srd.normals, srd.colors, srd.v0, srd.v1, srd.v2, srd.v3, - srd.patchID.NextPatchID(srd.depth+1, 0)); + srd.patchID.NextPatchID(srd.depth + 1, 0)); // store the result mpResults = sr; } SinglePatchJob::~SinglePatchJob() { - if(mpResults) { + if (mpResults) { mpResults->OnCancel(); delete mpResults; mpResults = nullptr; @@ -132,14 +134,14 @@ SinglePatchJob::~SinglePatchJob() // ******************************************************************************** // Overloaded PureJob class to handle generating the mesh for each patch // ******************************************************************************** -void QuadPatchJob::OnFinish() // runs in primary thread of the context +void QuadPatchJob::OnFinish() // runs in primary thread of the context { - GeoSphere::OnAddQuadSplitResult( mData->sysPath, mpResults ); + GeoSphere::OnAddQuadSplitResult(mData->sysPath, mpResults); mpResults = nullptr; BasePatchJob::OnFinish(); } -void QuadPatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! +void QuadPatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! { BasePatchJob::OnRun(); @@ -147,29 +149,28 @@ void QuadPatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! GenerateBorderedData(mData.get()); - const vector3d v01 = (srd.v0+srd.v1).Normalized(); - const vector3d v12 = (srd.v1+srd.v2).Normalized(); - const vector3d v23 = (srd.v2+srd.v3).Normalized(); - const vector3d v30 = (srd.v3+srd.v0).Normalized(); - const vector3d cn = (srd.centroid).Normalized(); + const vector3d v01 = (srd.v0 + srd.v1).Normalized(); + const vector3d v12 = (srd.v1 + srd.v2).Normalized(); + const vector3d v23 = (srd.v2 + srd.v3).Normalized(); + const vector3d v30 = (srd.v3 + srd.v0).Normalized(); + const vector3d cn = (srd.centroid).Normalized(); const vector3d vecs[4][4] = { - {srd.v0, v01, cn, v30}, - {v01, srd.v1, v12, cn}, - {cn, v12, srd.v2, v23}, - {v30, cn, v23, srd.v3} + { srd.v0, v01, cn, v30 }, + { v01, srd.v1, v12, cn }, + { cn, v12, srd.v2, v23 }, + { v30, cn, v23, srd.v3 } }; - const int borderedEdgeLen = (srd.edgeLen*2)+(BORDER_SIZE*2)-1; + const int borderedEdgeLen = (srd.edgeLen * 2) + (BORDER_SIZE * 2) - 1; const int offxy[4][2] = { - {0,0}, - {srd.edgeLen-1,0}, - {srd.edgeLen-1,srd.edgeLen-1}, - {0,srd.edgeLen-1} + { 0, 0 }, + { srd.edgeLen - 1, 0 }, + { srd.edgeLen - 1, srd.edgeLen - 1 }, + { 0, srd.edgeLen - 1 } }; SQuadSplitResult *sr = new SQuadSplitResult(srd.patchID.GetPatchFaceIdx(), srd.depth); - for (int i=0; i<4; i++) - { + for (int i = 0; i < 4; i++) { // fill out the data GenerateSubPatchData(srd.heights[i], srd.normals[i], srd.colors[i], srd.borderHeights.get(), srd.borderVertexs.get(), vecs[i][0], vecs[i][1], vecs[i][2], vecs[i][3], @@ -179,14 +180,14 @@ void QuadPatchJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! // add this patches data sr->addResult(i, srd.heights[i], srd.normals[i], srd.colors[i], vecs[i][0], vecs[i][1], vecs[i][2], vecs[i][3], - srd.patchID.NextPatchID(srd.depth+1, i)); + srd.patchID.NextPatchID(srd.depth + 1, i)); } mpResults = sr; } QuadPatchJob::~QuadPatchJob() { - if(mpResults) { + if (mpResults) { mpResults->OnCancel(); delete mpResults; mpResults = NULL; @@ -196,24 +197,24 @@ QuadPatchJob::~QuadPatchJob() // Generates full-detail vertices, and also non-edge normals and colors void QuadPatchJob::GenerateBorderedData(const SQuadSplitRequest *data) const { - const vector3d &v0 = data->v0; - const vector3d &v1 = data->v1; - const vector3d &v2 = data->v2; - const vector3d &v3 = data->v3; - const int edgeLen = data->edgeLen; - const double fracStep = data->fracStep; + const vector3d &v0 = data->v0; + const vector3d &v1 = data->v1; + const vector3d &v2 = data->v2; + const vector3d &v3 = data->v3; + const int edgeLen = data->edgeLen; + const double fracStep = data->fracStep; const Terrain *pTerrain = data->pTerrain.Get(); const int borderedEdgeLen = (edgeLen * 2) + (BORDER_SIZE * 2) - 1; - const int numBorderedVerts = borderedEdgeLen*borderedEdgeLen; + const int numBorderedVerts = borderedEdgeLen * borderedEdgeLen; // generate heights plus a N=BORDER_SIZE unit border double *bhts = data->borderHeights.get(); vector3d *vrts = data->borderVertexs.get(); - for ( int y = -BORDER_SIZE; y < (borderedEdgeLen - BORDER_SIZE); y++ ) { - const double yfrac = double(y) * (fracStep*0.5); - for ( int x = -BORDER_SIZE; x < (borderedEdgeLen - BORDER_SIZE); x++ ) { - const double xfrac = double(x) * (fracStep*0.5); + for (int y = -BORDER_SIZE; y < (borderedEdgeLen - BORDER_SIZE); y++) { + const double yfrac = double(y) * (fracStep * 0.5); + for (int x = -BORDER_SIZE; x < (borderedEdgeLen - BORDER_SIZE); x++) { + const double xfrac = double(x) * (fracStep * 0.5); const vector3d p = GetSpherePoint(v0, v1, v2, v3, xfrac, yfrac); const double height = pTerrain->GetHeight(p); assert(height >= 0.0f && height <= 1.0f); @@ -245,9 +246,9 @@ void QuadPatchJob::GenerateSubPatchData( double *hts = heights; // step over the small square - for ( int y = 0; y < edgeLen; y++ ) { + for (int y = 0; y < edgeLen; y++) { const int by = (y + BORDER_SIZE) + yoff; - for ( int x = 0; x < edgeLen; x++ ) { + for (int x = 0; x < edgeLen; x++) { const int bx = (x + BORDER_SIZE) + xoff; // height @@ -271,7 +272,7 @@ void QuadPatchJob::GenerateSubPatchData( ++col; } } - assert(hts == &heights[edgeLen*edgeLen]); - assert(nrm == &normals[edgeLen*edgeLen]); - assert(col == &colors[edgeLen*edgeLen]); + assert(hts == &heights[edgeLen * edgeLen]); + assert(nrm == &normals[edgeLen * edgeLen]); + assert(col == &colors[edgeLen * edgeLen]); } diff --git a/src/GeoPatchJobs.h b/src/GeoPatchJobs.h index e65ff7f4e..46a7a8c58 100644 --- a/src/GeoPatchJobs.h +++ b/src/GeoPatchJobs.h @@ -6,12 +6,12 @@ #include -#include "vector3.h" +#include "GeoPatchID.h" +#include "JobQueue.h" #include "Random.h" #include "galaxy/StarSystem.h" #include "terrain/Terrain.h" -#include "GeoPatchID.h" -#include "JobQueue.h" +#include "vector3.h" class GeoSphere; @@ -21,14 +21,22 @@ class SBaseRequest { public: SBaseRequest(const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const vector3d &cn, const uint32_t depth_, const SystemPath &sysPath_, const GeoPatchID &patchID_, const int edgeLen_, const double fracStep_, - Terrain *pTerrain_) - : v0(v0_), v1(v1_), v2(v2_), v3(v3_), centroid(cn), depth(depth_), - sysPath(sysPath_), patchID(patchID_), edgeLen(edgeLen_), fracStep(fracStep_), + Terrain *pTerrain_) : + v0(v0_), + v1(v1_), + v2(v2_), + v3(v3_), + centroid(cn), + depth(depth_), + sysPath(sysPath_), + patchID(patchID_), + edgeLen(edgeLen_), + fracStep(fracStep_), pTerrain(pTerrain_) { } - inline int NUMVERTICES(const int el) const { return el*el; } + inline int NUMVERTICES(const int el) const { return el * el; } const vector3d v0, v1, v2, v3; const vector3d centroid; @@ -48,17 +56,16 @@ class SQuadSplitRequest : public SBaseRequest { public: SQuadSplitRequest(const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const vector3d &cn, const uint32_t depth_, const SystemPath &sysPath_, const GeoPatchID &patchID_, const int edgeLen_, const double fracStep_, - Terrain *pTerrain_) - : SBaseRequest(v0_, v1_, v2_, v3_, cn, depth_, sysPath_, patchID_, edgeLen_, fracStep_, pTerrain_) + Terrain *pTerrain_) : + SBaseRequest(v0_, v1_, v2_, v3_, cn, depth_, sysPath_, patchID_, edgeLen_, fracStep_, pTerrain_) { const int numVerts = NUMVERTICES(edgeLen_); - for( int i=0 ; i<4 ; ++i ) - { + for (int i = 0; i < 4; ++i) { heights[i] = new double[numVerts]; normals[i] = new vector3f[numVerts]; colors[i] = new Color3ub[numVerts]; } - const int numBorderedVerts = NUMVERTICES((edgeLen_*2)+(BORDER_SIZE*2)-1); + const int numBorderedVerts = NUMVERTICES((edgeLen_ * 2) + (BORDER_SIZE * 2) - 1); borderHeights.reset(new double[numBorderedVerts]); borderVertexs.reset(new vector3d[numBorderedVerts]); } @@ -81,15 +88,15 @@ class SSingleSplitRequest : public SBaseRequest { public: SSingleSplitRequest(const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const vector3d &cn, const uint32_t depth_, const SystemPath &sysPath_, const GeoPatchID &patchID_, const int edgeLen_, const double fracStep_, - Terrain *pTerrain_) - : SBaseRequest(v0_, v1_, v2_, v3_, cn, depth_, sysPath_, patchID_, edgeLen_, fracStep_, pTerrain_) + Terrain *pTerrain_) : + SBaseRequest(v0_, v1_, v2_, v3_, cn, depth_, sysPath_, patchID_, edgeLen_, fracStep_, pTerrain_) { const int numVerts = NUMVERTICES(edgeLen_); heights = new double[numVerts]; normals = new vector3f[numVerts]; colors = new Color3ub[numVerts]; - const int numBorderedVerts = NUMVERTICES(edgeLen_+(BORDER_SIZE*2)); + const int numBorderedVerts = NUMVERTICES(edgeLen_ + (BORDER_SIZE * 2)); borderHeights.reset(new double[numBorderedVerts]); borderVertexs.reset(new vector3d[numBorderedVerts]); } @@ -111,12 +118,26 @@ protected: class SBaseSplitResult { public: struct SSplitResultData { - SSplitResultData() : patchID(0) {} + SSplitResultData() : + patchID(0) {} SSplitResultData(double *heights_, vector3f *n_, Color3ub *c_, const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const GeoPatchID &patchID_) : - heights(heights_), normals(n_), colors(c_), v0(v0_), v1(v1_), v2(v2_), v3(v3_), patchID(patchID_) + heights(heights_), + normals(n_), + colors(c_), + v0(v0_), + v1(v1_), + v2(v2_), + v3(v3_), + patchID(patchID_) {} SSplitResultData(const SSplitResultData &r) : - normals(r.normals), colors(r.colors), v0(r.v0), v1(r.v1), v2(r.v2), v3(r.v3), patchID(r.patchID) + normals(r.normals), + colors(r.colors), + v0(r.v0), + v1(r.v1), + v2(r.v2), + v3(r.v3), + patchID(r.patchID) {} double *heights; @@ -126,7 +147,9 @@ public: GeoPatchID patchID; }; - SBaseSplitResult(const int32_t face_, const int32_t depth_) : mFace(face_), mDepth(depth_) {} + SBaseSplitResult(const int32_t face_, const int32_t depth_) : + mFace(face_), + mDepth(depth_) {} virtual ~SBaseSplitResult() {} inline int32_t face() const { return mFace; } @@ -136,7 +159,9 @@ public: protected: // deliberately prevent copy constructor access - SBaseSplitResult(const SBaseSplitResult &r) : mFace(0), mDepth(0) {} + SBaseSplitResult(const SBaseSplitResult &r) : + mFace(0), + mDepth(0) {} const int32_t mFace; const int32_t mDepth; @@ -144,38 +169,51 @@ protected: class SQuadSplitResult : public SBaseSplitResult { static const int NUM_RESULT_DATA = 4; + public: - SQuadSplitResult(const int32_t face_, const int32_t depth_) : SBaseSplitResult(face_, depth_) + SQuadSplitResult(const int32_t face_, const int32_t depth_) : + SBaseSplitResult(face_, depth_) { } void addResult(const int kidIdx, double *h_, vector3f *n_, Color3ub *c_, const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, const GeoPatchID &patchID_) { - assert(kidIdx>=0 && kidIdx= 0 && kidIdx < NUM_RESULT_DATA); mData[kidIdx] = (SSplitResultData(h_, n_, c_, v0_, v1_, v2_, v3_, patchID_)); } - inline const SSplitResultData& data(const int32_t idx) const { return mData[idx]; } + inline const SSplitResultData &data(const int32_t idx) const { return mData[idx]; } virtual void OnCancel() { - for( int i=0; i #include +#include RefCountedPtr GeoSphere::s_patchContext; @@ -40,7 +40,7 @@ static const double gs_targetPatchTriLength(100.0); // { 1, 4, 3, 2 } // }; -static std::vector s_allGeospheres; +static std::vector s_allGeospheres; void GeoSphere::Init() { @@ -49,7 +49,7 @@ void GeoSphere::Init() void GeoSphere::Uninit() { - assert (s_patchContext.Unique()); + assert(s_patchContext.Unique()); s_patchContext.Reset(); } @@ -67,8 +67,7 @@ static void print_info(const SystemBody *sbody, const Terrain *terrain) void GeoSphere::UpdateAllGeoSpheres() { PROFILE_SCOPED() - for(std::vector::iterator i = s_allGeospheres.begin(); i != s_allGeospheres.end(); ++i) - { + for (std::vector::iterator i = s_allGeospheres.begin(); i != s_allGeospheres.end(); ++i) { (*i)->Update(); } } @@ -79,8 +78,7 @@ void GeoSphere::OnChangeDetailLevel() s_patchContext.Reset(new GeoPatchContext(detail_edgeLen[Pi::detail.planets > 4 ? 4 : Pi::detail.planets])); // reinit the geosphere terrain data - for(std::vector::iterator i = s_allGeospheres.begin(); i != s_allGeospheres.end(); ++i) - { + for (std::vector::iterator i = s_allGeospheres.begin(); i != s_allGeospheres.end(); ++i) { // clearout anything we don't need (*i)->Reset(); @@ -94,14 +92,14 @@ void GeoSphere::OnChangeDetailLevel() bool GeoSphere::OnAddQuadSplitResult(const SystemPath &path, SQuadSplitResult *res) { // Find the correct GeoSphere via it's system path, and give it the split result - for(std::vector::iterator i=s_allGeospheres.begin(), iEnd=s_allGeospheres.end(); i!=iEnd; ++i) { - if( path == (*i)->GetSystemBody()->GetPath() ) { + for (std::vector::iterator i = s_allGeospheres.begin(), iEnd = s_allGeospheres.end(); i != iEnd; ++i) { + if (path == (*i)->GetSystemBody()->GetPath()) { (*i)->AddQuadSplitResult(res); return true; } } // GeoSphere not found to return the data to, cancel and delete it instead - if( res ) { + if (res) { res->OnCancel(); delete res; } @@ -112,14 +110,14 @@ bool GeoSphere::OnAddQuadSplitResult(const SystemPath &path, SQuadSplitResult *r bool GeoSphere::OnAddSingleSplitResult(const SystemPath &path, SSingleSplitResult *res) { // Find the correct GeoSphere via it's system path, and give it the split result - for(std::vector::iterator i=s_allGeospheres.begin(), iEnd=s_allGeospheres.end(); i!=iEnd; ++i) { - if( path == (*i)->GetSystemBody()->GetPath() ) { + for (std::vector::iterator i = s_allGeospheres.begin(), iEnd = s_allGeospheres.end(); i != iEnd; ++i) { + if (path == (*i)->GetSystemBody()->GetPath()) { (*i)->AddSingleSplitResult(res); return true; } } // GeoSphere not found to return the data to, cancel and delete it instead - if( res ) { + if (res) { res->OnCancel(); delete res; } @@ -129,9 +127,8 @@ bool GeoSphere::OnAddSingleSplitResult(const SystemPath &path, SSingleSplitResul void GeoSphere::Reset() { { - std::deque::iterator iter = mSingleSplitResults.begin(); - while(iter!=mSingleSplitResults.end()) - { + std::deque::iterator iter = mSingleSplitResults.begin(); + while (iter != mSingleSplitResults.end()) { // finally pass SplitResults SSingleSplitResult *psr = (*iter); assert(psr); @@ -148,9 +145,8 @@ void GeoSphere::Reset() } { - std::deque::iterator iter = mQuadSplitResults.begin(); - while(iter!=mQuadSplitResults.end()) - { + std::deque::iterator iter = mQuadSplitResults.begin(); + while (iter != mQuadSplitResults.end()) { // finally pass SplitResults SQuadSplitResult *psr = (*iter); assert(psr); @@ -166,7 +162,7 @@ void GeoSphere::Reset() mQuadSplitResults.clear(); } - for (int p=0; p::iterator iter = mSingleSplitResults.begin(); - while(iter!=mSingleSplitResults.end()) - { + std::deque::iterator iter = mSingleSplitResults.begin(); + while (iter != mSingleSplitResults.end()) { // finally pass SplitResults SSingleSplitResult *psr = (*iter); assert(psr); const int32_t faceIdx = psr->face(); - if( m_patches[faceIdx] ) { + if (m_patches[faceIdx]) { m_patches[faceIdx]->ReceiveHeightmap(psr); } else { psr->OnCancel(); @@ -251,15 +250,14 @@ void GeoSphere::ProcessSplitResults() // now handle the quad split results { - std::deque::iterator iter = mQuadSplitResults.begin(); - while(iter!=mQuadSplitResults.end()) - { + std::deque::iterator iter = mQuadSplitResults.begin(); + while (iter != mQuadSplitResults.end()) { // finally pass SplitResults SQuadSplitResult *psr = (*iter); assert(psr); const int32_t faceIdx = psr->face(); - if( m_patches[faceIdx] ) { + if (m_patches[faceIdx]) { m_patches[faceIdx]->ReceiveHeightmaps(psr); } else { psr->OnCancel(); @@ -278,20 +276,20 @@ void GeoSphere::ProcessSplitResults() void GeoSphere::BuildFirstPatches() { assert(!m_patches[0]); - if(m_patches[0]) + if (m_patches[0]) return; CalculateMaxPatchDepth(); // generate root face patches of the cube/sphere - static const vector3d p1 = (vector3d( 1, 1, 1)).Normalized(); + static const vector3d p1 = (vector3d(1, 1, 1)).Normalized(); static const vector3d p2 = (vector3d(-1, 1, 1)).Normalized(); - static const vector3d p3 = (vector3d(-1,-1, 1)).Normalized(); - static const vector3d p4 = (vector3d( 1,-1, 1)).Normalized(); - static const vector3d p5 = (vector3d( 1, 1,-1)).Normalized(); - static const vector3d p6 = (vector3d(-1, 1,-1)).Normalized(); - static const vector3d p7 = (vector3d(-1,-1,-1)).Normalized(); - static const vector3d p8 = (vector3d( 1,-1,-1)).Normalized(); + static const vector3d p3 = (vector3d(-1, -1, 1)).Normalized(); + static const vector3d p4 = (vector3d(1, -1, 1)).Normalized(); + static const vector3d p5 = (vector3d(1, 1, -1)).Normalized(); + static const vector3d p6 = (vector3d(-1, 1, -1)).Normalized(); + static const vector3d p7 = (vector3d(-1, -1, -1)).Normalized(); + static const vector3d p8 = (vector3d(1, -1, -1)).Normalized(); const uint64_t maxShiftDepth = GeoPatchID::MAX_SHIFT_DEPTH; @@ -302,7 +300,7 @@ void GeoSphere::BuildFirstPatches() m_patches[4].reset(new GeoPatch(s_patchContext, this, p3, p2, p6, p7, 0, (4ULL << maxShiftDepth))); m_patches[5].reset(new GeoPatch(s_patchContext, this, p8, p7, p6, p5, 0, (5ULL << maxShiftDepth))); - for (int i=0; iRequestSinglePatch(); } @@ -315,7 +313,7 @@ void GeoSphere::CalculateMaxPatchDepth() // calculate length of each edge segment (quad) times 4 due to that being the number around the sphere (1 per side, 4 sides for Root). double edgeMetres = circumference / double(s_patchContext->GetEdgeLen() * 8); // find out what depth we reach the desired resolution - while (edgeMetres>gs_targetPatchTriLength && m_maxDepth gs_targetPatchTriLength && m_maxDepth < GEOPATCH_MAX_DEPTH) { edgeMetres *= 0.5; ++m_maxDepth; } @@ -323,33 +321,30 @@ void GeoSphere::CalculateMaxPatchDepth() void GeoSphere::Update() { - switch(m_initStage) - { + switch (m_initStage) { case eBuildFirstPatches: BuildFirstPatches(); break; - case eRequestedFirstPatches: - { - ProcessSplitResults(); - uint8_t numValidPatches = 0; - for (int i=0; iHasHeightData()) { - ++numValidPatches; - } + case eRequestedFirstPatches: { + ProcessSplitResults(); + uint8_t numValidPatches = 0; + for (int i = 0; i < NUM_PATCHES; i++) { + if (m_patches[i]->HasHeightData()) { + ++numValidPatches; } - m_initStage = (NUM_PATCHES==numValidPatches) ? eReceivedFirstPatches : eRequestedFirstPatches; - } break; - case eReceivedFirstPatches: - { - for (int i=0; iNeedToUpdateVBOs(); - } - m_initStage = eDefaultUpdateState; - } break; + } + m_initStage = (NUM_PATCHES == numValidPatches) ? eReceivedFirstPatches : eRequestedFirstPatches; + } break; + case eReceivedFirstPatches: { + for (int i = 0; i < NUM_PATCHES; i++) { + m_patches[i]->NeedToUpdateVBOs(); + } + m_initStage = eDefaultUpdateState; + } break; case eDefaultUpdateState: - if(m_hasTempCampos) { + if (m_hasTempCampos) { ProcessSplitResults(); - for (int i=0; iLODUpdate(m_tempCampos, m_tempFrustum); } ProcessQuadSplitRequests(); @@ -374,7 +369,7 @@ void GeoSphere::ProcessQuadSplitRequests() }; std::sort(mQuadSplitRequests.begin(), mQuadSplitRequests.end(), RequestDistanceSort()); - for(auto iter : mQuadSplitRequests) { + for (auto iter : mQuadSplitRequests) { SQuadSplitRequest *ssrd = iter.mpRequest; iter.mpRequester->ReceiveJobHandle(Pi::GetAsyncJobQueue()->Queue(new QuadPatchJob(ssrd))); } @@ -388,7 +383,7 @@ void GeoSphere::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView m_tempCampos = campos; m_hasTempCampos = true; - if(m_initStage < eDefaultUpdateState) + if (m_initStage < eDefaultUpdateState) return; matrix4x4d trans = modelView; @@ -398,7 +393,7 @@ void GeoSphere::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView matrix4x4d proj; matrix4x4ftod(renderer->GetCurrentModelView(), modv); matrix4x4ftod(renderer->GetCurrentProjection(), proj); - Graphics::Frustum frustum( modv, proj ); + Graphics::Frustum frustum(modv, proj); m_tempFrustum = frustum; // no frustum test of entire geosphere, since Space::Render does this @@ -428,7 +423,7 @@ void GeoSphere::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView // that the edges of the pixel shader atmosphere jizz doesn't // show ugly polygonal angles DrawAtmosphereSurface(renderer, trans, campos, - m_materialParameters.atmosphere.atmosRadius*1.01, + m_materialParameters.atmosphere.atmosRadius * 1.01, m_atmosRenderState, m_atmosphereMaterial); } } @@ -450,7 +445,7 @@ void GeoSphere::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView else { // give planet some ambient lighting if the viewer is close to it double camdist = campos.Length(); - camdist = 0.1 / (camdist*camdist); + camdist = 0.1 / (camdist * camdist); // why the fuck is this returning 0.1 when we are sat on the planet?? // JJ: Because campos is relative to a unit-radius planet - 1.0 at the surface // XXX oh well, it is the value we want anyway... @@ -462,7 +457,7 @@ void GeoSphere::Render(Graphics::Renderer *renderer, const matrix4x4d &modelView renderer->SetTransform(modelView); - for (int i=0; iRender(renderer, campos, modelView, frustum); } @@ -499,8 +494,7 @@ void GeoSphere::SetUpMaterials() //dim star (emits and receives light) surfDesc.lighting = true; surfDesc.quality &= ~Graphics::HAS_ATMOSPHERE; - } - else if (GetSystemBody()->GetSuperType() == SystemBody::SUPERTYPE_STAR) { + } else if (GetSystemBody()->GetSuperType() == SystemBody::SUPERTYPE_STAR) { //normal star surfDesc.lighting = false; surfDesc.quality &= ~Graphics::HAS_ATMOSPHERE; @@ -509,7 +503,7 @@ void GeoSphere::SetUpMaterials() //planetoid with or without atmosphere const SystemBody::AtmosphereParameters ap(GetSystemBody()->CalcAtmosphereParams()); surfDesc.lighting = true; - if(ap.atmosDensity > 0.0) { + if (ap.atmosDensity > 0.0) { surfDesc.quality |= Graphics::HAS_ATMOSPHERE; } else { surfDesc.quality &= ~Graphics::HAS_ATMOSPHERE; @@ -523,8 +517,8 @@ void GeoSphere::SetUpMaterials() } m_surfaceMaterial.Reset(Pi::renderer->CreateMaterial(surfDesc)); - m_texHi.Reset( Graphics::TextureBuilder::Model("textures/high.dds").GetOrCreateTexture(Pi::renderer, "model") ); - m_texLo.Reset( Graphics::TextureBuilder::Model("textures/low.dds").GetOrCreateTexture(Pi::renderer, "model") ); + m_texHi.Reset(Graphics::TextureBuilder::Model("textures/high.dds").GetOrCreateTexture(Pi::renderer, "model")); + m_texLo.Reset(Graphics::TextureBuilder::Model("textures/low.dds").GetOrCreateTexture(Pi::renderer, "model")); m_surfaceMaterial->texture0 = m_texHi.Get(); m_surfaceMaterial->texture1 = m_texLo.Get(); diff --git a/src/GeoSphere.h b/src/GeoSphere.h index 934f64a2d..2f4a83c07 100644 --- a/src/GeoSphere.h +++ b/src/GeoSphere.h @@ -6,19 +6,21 @@ #include -#include "vector3.h" -#include "Random.h" -#include "Camera.h" -#include "galaxy/StarSystem.h" -#include "graphics/RenderState.h" -#include "graphics/Material.h" -#include "terrain/Terrain.h" -#include "GeoPatchID.h" #include "BaseSphere.h" +#include "Camera.h" +#include "GeoPatchID.h" +#include "Random.h" +#include "galaxy/StarSystem.h" +#include "graphics/Material.h" +#include "graphics/RenderState.h" +#include "terrain/Terrain.h" +#include "vector3.h" #include -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class SystemBody; class GeoPatch; class GeoPatchContext; @@ -36,7 +38,8 @@ public: virtual void Update() override; virtual void Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, vector3d campos, const float radius, const std::vector &shadows) override; - virtual double GetHeight(const vector3d &p) const override final { + virtual double GetHeight(const vector3d &p) const override final + { const double h = m_terrain->GetHeight(p); #ifdef DEBUG // XXX don't remove this. Fix your fractals instead @@ -68,12 +71,13 @@ public: inline Sint32 GetMaxDepth() const { return m_maxDepth; } - void AddQuadSplitRequest(double, SQuadSplitRequest*, GeoPatch*); + void AddQuadSplitRequest(double, SQuadSplitRequest *, GeoPatch *); private: void BuildFirstPatches(); void CalculateMaxPatchDepth(); - inline vector3d GetColor(const vector3d &p, double height, const vector3d &norm) const { + inline vector3d GetColor(const vector3d &p, double height, const vector3d &norm) const + { return m_terrain->GetColor(p, height, norm); } void ProcessQuadSplitRequests(); @@ -81,7 +85,9 @@ private: std::unique_ptr m_patches[6]; struct TDistanceRequest { TDistanceRequest(double dist, SQuadSplitRequest *pRequest, GeoPatch *pRequester) : - mDistance(dist), mpRequest(pRequest), mpRequester(pRequester) {} + mDistance(dist), + mpRequest(pRequest), + mpRequester(pRequester) {} double mDistance; SQuadSplitRequest *mpRequest; GeoPatch *mpRequester; @@ -89,8 +95,8 @@ private: std::deque mQuadSplitRequests; static const uint32_t MAX_SPLIT_OPERATIONS = 128; - std::deque mQuadSplitResults; - std::deque mSingleSplitResults; + std::deque mQuadSplitResults; + std::deque mSingleSplitResults; bool m_hasTempCampos; vector3d m_tempCampos; @@ -104,7 +110,7 @@ private: RefCountedPtr m_texLo; enum EGSInitialisationStage { - eBuildFirstPatches=0, + eBuildFirstPatches = 0, eRequestedFirstPatches, eReceivedFirstPatches, eDefaultUpdateState diff --git a/src/HudTrail.cpp b/src/HudTrail.cpp index 13edab550..3526e5859 100644 --- a/src/HudTrail.cpp +++ b/src/HudTrail.cpp @@ -8,10 +8,10 @@ const float UPDATE_INTERVAL = 0.1f; const Uint16 MAX_POINTS = 100; -HudTrail::HudTrail(Body *b, const Color& c) -: m_body(b) -, m_updateTime(0.f) -, m_color(c) +HudTrail::HudTrail(Body *b, const Color &c) : + m_body(b), + m_updateTime(0.f), + m_color(c) { m_currentFrame = b->GetFrame(); @@ -30,12 +30,12 @@ void HudTrail::Update(float time) m_updateTime = 0.f; const Frame *bodyFrame = m_body->GetFrame(); - if( !m_currentFrame ) { + if (!m_currentFrame) { m_currentFrame = bodyFrame; m_trailPoints.clear(); } - if( bodyFrame==m_currentFrame ) + if (bodyFrame == m_currentFrame) m_trailPoints.push_back(m_body->GetInterpPosition()); } @@ -66,7 +66,7 @@ void HudTrail::Render(Graphics::Renderer *r) float alpha = 1.f; const float decrement = 1.f / m_trailPoints.size(); const Color tcolor = m_color; - for (size_t i = m_trailPoints.size()-1; i > 0; i--) { + for (size_t i = m_trailPoints.size() - 1; i > 0; i--) { tvts.push_back(-vector3f(curpos - m_trailPoints[i])); alpha -= decrement; colors.push_back(tcolor); diff --git a/src/HudTrail.h b/src/HudTrail.h index e8774c95e..f47218b10 100644 --- a/src/HudTrail.h +++ b/src/HudTrail.h @@ -6,15 +6,14 @@ // trail drawn after an object to track motion -#include "libs.h" #include "Body.h" -#include "graphics/Renderer.h" #include "graphics/Drawables.h" +#include "graphics/Renderer.h" +#include "libs.h" -class HudTrail -{ +class HudTrail { public: - HudTrail(Body *b, const Color&); + HudTrail(Body *b, const Color &); void Update(float time); void Render(Graphics::Renderer *r); void Reset(const Frame *newFrame); diff --git a/src/HyperspaceCloud.cpp b/src/HyperspaceCloud.cpp index 2ce21fad8..588b5322a 100644 --- a/src/HyperspaceCloud.cpp +++ b/src/HyperspaceCloud.cpp @@ -2,31 +2,32 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "HyperspaceCloud.h" -#include "libs.h" #include "Game.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "Lang.h" -#include "perlin.h" #include "Pi.h" #include "Player.h" #include "Ship.h" #include "Space.h" #include "graphics/Graphics.h" #include "graphics/Material.h" +#include "graphics/RenderState.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "graphics/RenderState.h" -#include "JsonUtils.h" -#include "GameSaveError.h" +#include "libs.h" +#include "perlin.h" using namespace Graphics; /** How long does a hyperspace cloud last for? 2 Days? */ -#define HYPERCLOUD_DURATION (60.0*60.0*24.0*2.0) +#define HYPERCLOUD_DURATION (60.0 * 60.0 * 24.0 * 2.0) -HyperspaceCloud::HyperspaceCloud(Ship *s, double dueDate, bool isArrival) : m_isBeingKilled(false) +HyperspaceCloud::HyperspaceCloud(Ship *s, double dueDate, bool isArrival) : + m_isBeingKilled(false) { m_flags = Body::FLAG_CAN_MOVE_FRAME | - Body::FLAG_LABEL_HIDDEN; + Body::FLAG_LABEL_HIDDEN; m_ship = s; SetPhysRadius(0.0); SetClipRadius(1200.0); @@ -37,7 +38,8 @@ HyperspaceCloud::HyperspaceCloud(Ship *s, double dueDate, bool isArrival) : m_is InitGraphics(); } -HyperspaceCloud::HyperspaceCloud() : m_isBeingKilled(false) +HyperspaceCloud::HyperspaceCloud() : + m_isBeingKilled(false) { m_ship = 0; SetPhysRadius(0.0); @@ -54,7 +56,7 @@ void HyperspaceCloud::InitGraphics() m_graphic.material.reset(Pi::renderer->CreateMaterial(desc)); Graphics::RenderStateDesc rsd; - rsd.blendMode = BLEND_ALPHA_ONE; + rsd.blendMode = BLEND_ALPHA_ONE; rsd.depthWrite = false; m_graphic.renderState = Pi::renderer->CreateRenderState(rsd); } @@ -80,8 +82,7 @@ void HyperspaceCloud::SaveToJson(Json &jsonObj, Space *space) hyperspaceCloudObj["birth_date"] = m_birthdate; hyperspaceCloudObj["due"] = m_due; hyperspaceCloudObj["is_arrival"] = m_isArrival; - if (m_ship) - { + if (m_ship) { Json shipObj = Json::object(); // Create JSON object to contain ship data. m_ship->ToJson(shipObj, space); hyperspaceCloudObj["ship"] = shipObj; // Add ship object to hyperpace cloud object. @@ -102,10 +103,9 @@ void HyperspaceCloud::LoadFromJson(const Json &jsonObj, Space *space) m_due = hyperspaceCloudObj["due"]; m_isArrival = hyperspaceCloudObj["is_arrival"]; - if (hyperspaceCloudObj["ship"].is_object()) - { + if (hyperspaceCloudObj["ship"].is_object()) { Json shipObj = hyperspaceCloudObj["ship"]; - m_ship = static_cast(Body::FromJson(shipObj, space)); + m_ship = static_cast(Body::FromJson(shipObj, space)); } } catch (Json::type_error &) { throw SavedGameCorruptException(); @@ -120,7 +120,7 @@ void HyperspaceCloud::PostLoadFixup(Space *space) void HyperspaceCloud::TimeStepUpdate(const float timeStep) { - if( m_isBeingKilled ) + if (m_isBeingKilled) return; SetPosition(GetPosition() + m_vel * timeStep); @@ -144,8 +144,7 @@ void HyperspaceCloud::TimeStepUpdate(const float timeStep) } // cloud expiration - if( m_birthdate + HYPERCLOUD_DURATION <= Pi::game->GetTime() ) - { + if (m_birthdate + HYPERCLOUD_DURATION <= Pi::game->GetTime()) { Pi::game->RemoveHyperspaceCloud(this); Pi::game->GetSpace()->KillBody(this); m_isBeingKilled = true; @@ -162,8 +161,8 @@ Ship *HyperspaceCloud::EvictShip() static void make_circle_thing(VertexArray &va, float radius, const Color &colCenter, const Color &colEdge) { va.Add(vector3f(0.f, 0.f, 0.f), colCenter); - for (float ang=0; angGetTimeStep(); - m_interpPos = alpha*GetPosition() + (1.0-alpha)*oldPos; + const vector3d oldPos = GetPosition() - m_vel * Pi::game->GetTimeStep(); + m_interpPos = alpha * GetPosition() + (1.0 - alpha) * oldPos; } void HyperspaceCloud::Render(Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { - if( m_isBeingKilled ) + if (m_isBeingKilled) return; matrix4x4d trans = matrix4x4d::Identity(); @@ -185,17 +184,17 @@ void HyperspaceCloud::Render(Renderer *renderer, const Camera *camera, const vec // face the camera dammit vector3d zaxis = viewCoords.NormalizedSafe(); - vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized(); + vector3d xaxis = vector3d(0, 1, 0).Cross(zaxis).Normalized(); vector3d yaxis = zaxis.Cross(xaxis); matrix4x4d rot = matrix4x4d::MakeRotMatrix(xaxis, yaxis, zaxis).Inverse(); renderer->SetTransform(trans * rot); // precise to the rendered frame (better than PHYSICS_HZ granularity) - const double preciseTime = Pi::game->GetTime() + Pi::GetGameTickAlpha()*Pi::game->GetTimeStep(); + const double preciseTime = Pi::game->GetTime() + Pi::GetGameTickAlpha() * Pi::game->GetTimeStep(); // Flickering gradient circle, departure clouds are red and arrival clouds blue // XXX could just alter the scale instead of recreating the model - const float radius = 1000.0f + 200.0f*float(noise(vector3d(10.0*preciseTime, 0, 0))); + const float radius = 1000.0f + 200.0f * float(noise(vector3d(10.0 * preciseTime, 0, 0))); m_graphic.vertices->Clear(); Color outerColor = m_isArrival ? Color::BLUE : Color::RED; outerColor.a = 0; diff --git a/src/HyperspaceCloud.h b/src/HyperspaceCloud.h index 0b3034e28..b95782266 100644 --- a/src/HyperspaceCloud.h +++ b/src/HyperspaceCloud.h @@ -13,9 +13,9 @@ namespace Graphics { class Renderer; class VertexArray; class RenderState; -} +} // namespace Graphics -class HyperspaceCloud: public Body { +class HyperspaceCloud : public Body { public: OBJDEF(HyperspaceCloud, Body, HYPERSPACECLOUD); HyperspaceCloud(Ship *, double dateDue, bool isArrival); @@ -32,6 +32,7 @@ public: void SetIsArrival(bool isArrival); bool IsArrival() const { return m_isArrival; } virtual void UpdateInterpTransform(double alpha) override; + protected: virtual void SaveToJson(Json &jsonObj, Space *space) override; virtual void LoadFromJson(const Json &jsonObj, Space *space) override; diff --git a/src/IniConfig.cpp b/src/IniConfig.cpp index 781ecf566..3f189c8b7 100644 --- a/src/IniConfig.cpp +++ b/src/IniConfig.cpp @@ -1,10 +1,10 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "IniConfig.h" #include "FileSystem.h" #include "StringRange.h" +#include "libs.h" #include "utils.h" #include #include diff --git a/src/IniConfig.h b/src/IniConfig.h index 05b8baeb9..3cf726bb7 100644 --- a/src/IniConfig.h +++ b/src/IniConfig.h @@ -12,7 +12,7 @@ namespace FileSystem { class FileData; class FileSource; class FileSourceFS; -} +} // namespace FileSystem class IniConfig { public: @@ -38,12 +38,14 @@ public: float Float(const std::string &key, float defval = 0.0f) const { return Float("", key, defval); } std::string String(const std::string &key, const std::string &defval = std::string()) const { return String("", key, defval); } - bool HasSection(const std::string §ion) const { + bool HasSection(const std::string §ion) const + { SectionMapType::const_iterator it = m_map.find(section); return (it != m_map.end()) && (!it->second.empty()); } - bool HasEntry(const std::string §ion, const std::string &key) const { + bool HasEntry(const std::string §ion, const std::string &key) const + { SectionMapType::const_iterator it = m_map.find(section); return (it != m_map.end()) && it->second.count(key); } diff --git a/src/Input.cpp b/src/Input.cpp index 435ec1f59..0d2ce9c08 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -7,22 +7,22 @@ void Input::Init() { - GameConfig *config = Pi::config; + GameConfig *config = Pi::config; - joystickEnabled = (config->Int("EnableJoystick")) ? true : false; + joystickEnabled = (config->Int("EnableJoystick")) ? true : false; mouseYInvert = (config->Int("InvertMouseY")) ? true : false; - InitJoysticks(); + InitJoysticks(); } void Input::InitGame() { - //reset input states + //reset input states keyState.clear(); keyModState = 0; std::fill(mouseButton, mouseButton + COUNTOF(mouseButton), 0); std::fill(mouseMotion, mouseMotion + COUNTOF(mouseMotion), 0); - for (std::map::iterator stick = joysticks.begin(); stick != joysticks.end(); ++stick) { + for (std::map::iterator stick = joysticks.begin(); stick != joysticks.end(); ++stick) { JoystickState &state = stick->second; std::fill(state.buttons.begin(), state.buttons.end(), false); std::fill(state.hats.begin(), state.hats.end(), 0); @@ -30,84 +30,84 @@ void Input::InitGame() } } -KeyBindings::ActionBinding* Input::AddActionBinding(std::string id, BindingGroup* group, KeyBindings::ActionBinding binding) +KeyBindings::ActionBinding *Input::AddActionBinding(std::string id, BindingGroup *group, KeyBindings::ActionBinding binding) { - // TODO: should we throw an error if we attempt to bind over an already-bound action? - group->bindings[id] = BindingGroup::ENTRY_ACTION; + // TODO: should we throw an error if we attempt to bind over an already-bound action? + group->bindings[id] = BindingGroup::ENTRY_ACTION; - // Load from the config - std::string config_str = Pi::config->String(id.c_str()); - if (config_str.length() > 0) binding.SetFromString(config_str); + // Load from the config + std::string config_str = Pi::config->String(id.c_str()); + if (config_str.length() > 0) binding.SetFromString(config_str); - return &(actionBindings[id] = binding); + return &(actionBindings[id] = binding); } -KeyBindings::AxisBinding* Input::AddAxisBinding(std::string id, BindingGroup* group, KeyBindings::AxisBinding binding) +KeyBindings::AxisBinding *Input::AddAxisBinding(std::string id, BindingGroup *group, KeyBindings::AxisBinding binding) { - // TODO: should we throw an error if we attempt to bind over an already-bound axis? - group->bindings[id] = BindingGroup::ENTRY_AXIS; + // TODO: should we throw an error if we attempt to bind over an already-bound axis? + group->bindings[id] = BindingGroup::ENTRY_AXIS; - // Load from the config - std::string config_str = Pi::config->String(id.c_str()); - if (config_str.length() > 0) binding.SetFromString(config_str); + // Load from the config + std::string config_str = Pi::config->String(id.c_str()); + if (config_str.length() > 0) binding.SetFromString(config_str); - return &(axisBindings[id] = binding); + return &(axisBindings[id] = binding); } void Input::HandleSDLEvent(SDL_Event &event) { - switch (event.type) { - case SDL_KEYDOWN: - keyState[event.key.keysym.sym] = true; - keyModState = event.key.keysym.mod; - onKeyPress.emit(&event.key.keysym); - break; - case SDL_KEYUP: - keyState[event.key.keysym.sym] = false; - keyModState = event.key.keysym.mod; - onKeyRelease.emit(&event.key.keysym); - break; - case SDL_MOUSEBUTTONDOWN: - if (event.button.button < COUNTOF(mouseButton)) { - mouseButton[event.button.button] = 1; - onMouseButtonDown.emit(event.button.button, - event.button.x, event.button.y); - } - break; - case SDL_MOUSEBUTTONUP: - if (event.button.button < COUNTOF(mouseButton)) { - mouseButton[event.button.button] = 0; - onMouseButtonUp.emit(event.button.button, - event.button.x, event.button.y); - } - break; - case SDL_MOUSEWHEEL: - onMouseWheel.emit(event.wheel.y > 0); // true = up - break; - case SDL_MOUSEMOTION: - mouseMotion[0] += event.motion.xrel; - mouseMotion[1] += event.motion.yrel; - break; - case SDL_JOYAXISMOTION: - if (!joysticks[event.jaxis.which].joystick) - break; - if (event.jaxis.value == -32768) - joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f; - else - joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f; - break; - case SDL_JOYBUTTONUP: - case SDL_JOYBUTTONDOWN: - if (!joysticks[event.jaxis.which].joystick) - break; - joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0; - break; - case SDL_JOYHATMOTION: - if (!joysticks[event.jaxis.which].joystick) - break; - joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value; - break; - } + switch (event.type) { + case SDL_KEYDOWN: + keyState[event.key.keysym.sym] = true; + keyModState = event.key.keysym.mod; + onKeyPress.emit(&event.key.keysym); + break; + case SDL_KEYUP: + keyState[event.key.keysym.sym] = false; + keyModState = event.key.keysym.mod; + onKeyRelease.emit(&event.key.keysym); + break; + case SDL_MOUSEBUTTONDOWN: + if (event.button.button < COUNTOF(mouseButton)) { + mouseButton[event.button.button] = 1; + onMouseButtonDown.emit(event.button.button, + event.button.x, event.button.y); + } + break; + case SDL_MOUSEBUTTONUP: + if (event.button.button < COUNTOF(mouseButton)) { + mouseButton[event.button.button] = 0; + onMouseButtonUp.emit(event.button.button, + event.button.x, event.button.y); + } + break; + case SDL_MOUSEWHEEL: + onMouseWheel.emit(event.wheel.y > 0); // true = up + break; + case SDL_MOUSEMOTION: + mouseMotion[0] += event.motion.xrel; + mouseMotion[1] += event.motion.yrel; + break; + case SDL_JOYAXISMOTION: + if (!joysticks[event.jaxis.which].joystick) + break; + if (event.jaxis.value == -32768) + joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f; + else + joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f; + break; + case SDL_JOYBUTTONUP: + case SDL_JOYBUTTONDOWN: + if (!joysticks[event.jaxis.which].joystick) + break; + joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0; + break; + case SDL_JOYHATMOTION: + if (!joysticks[event.jaxis.which].joystick) + break; + joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value; + break; + } } void Input::InitJoysticks() @@ -139,7 +139,7 @@ std::string Input::JoystickName(int joystick) std::string Input::JoystickGUIDString(int joystick) { const int guidBufferLen = 33; // as documented by SDL - char guidBuffer[guidBufferLen]; + char guidBuffer[guidBufferLen]; SDL_JoystickGetGUIDString(joysticks[joystick].guid, guidBuffer, guidBufferLen); return std::string(guidBuffer); diff --git a/src/Input.h b/src/Input.h index f910fcca6..ca01c0fd9 100644 --- a/src/Input.h +++ b/src/Input.h @@ -4,14 +4,15 @@ #ifndef INPUT_H #define INPUT_H -#include "utils.h" #include "KeyBindings.h" +#include "utils.h" class Input { // TODO: better decouple these two classes. friend class Pi; + public: - Input() { }; + Input(){}; void Init(); void InitGame(); @@ -27,25 +28,27 @@ public: }; struct BindingPage { - BindingGroup* GetBindingGroup(std::string id) { return &groups[id]; } + BindingGroup *GetBindingGroup(std::string id) { return &groups[id]; } std::map groups; }; - BindingPage* GetBindingPage(std::string id) { return &bindingPages[id]; } + BindingPage *GetBindingPage(std::string id) { return &bindingPages[id]; } std::map GetBindingPages() { return bindingPages; } // Creates a new action binding, copying the provided binding. // The returned binding pointer points to the actual binding. - KeyBindings::ActionBinding* AddActionBinding(std::string id, BindingGroup* group, KeyBindings::ActionBinding binding); - KeyBindings::ActionBinding* GetActionBinding(std::string id) { + KeyBindings::ActionBinding *AddActionBinding(std::string id, BindingGroup *group, KeyBindings::ActionBinding binding); + KeyBindings::ActionBinding *GetActionBinding(std::string id) + { return actionBindings.count(id) ? &actionBindings[id] : nullptr; } // Creates a new axis binding, copying the provided binding. // The returned binding pointer points to the actual binding. - KeyBindings::AxisBinding* AddAxisBinding(std::string id, BindingGroup* group, KeyBindings::AxisBinding binding); - KeyBindings::AxisBinding* GetAxisBinding(std::string id) { + KeyBindings::AxisBinding *AddAxisBinding(std::string id, BindingGroup *group, KeyBindings::AxisBinding binding); + KeyBindings::AxisBinding *GetAxisBinding(std::string id) + { return axisBindings.count(id) ? &axisBindings[id] : nullptr; } @@ -85,12 +88,13 @@ public: int MouseButtonState(int button) { return mouseButton[button]; } void SetMouseButtonState(int button, bool state) { mouseButton[button] = state; } - void GetMouseMotion(int motion[2]) { - memcpy(motion, mouseMotion, sizeof(int)*2); + void GetMouseMotion(int motion[2]) + { + memcpy(motion, mouseMotion, sizeof(int) * 2); } - sigc::signal onKeyPress; - sigc::signal onKeyRelease; + sigc::signal onKeyPress; + sigc::signal onKeyRelease; sigc::signal onMouseButtonUp; sigc::signal onMouseButtonDown; sigc::signal onMouseWheel; @@ -99,14 +103,14 @@ private: void HandleSDLEvent(SDL_Event &ev); void InitJoysticks(); - std::map keyState; + std::map keyState; int keyModState; char mouseButton[6]; int mouseMotion[2]; bool joystickEnabled; bool mouseYInvert; - std::map joysticks; + std::map joysticks; std::map bindingPages; std::map actionBindings; diff --git a/src/Intro.cpp b/src/Intro.cpp index 7389bd035..7baa82a14 100644 --- a/src/Intro.cpp +++ b/src/Intro.cpp @@ -2,24 +2,25 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Intro.h" -#include "Pi.h" -#include "Lang.h" #include "Easing.h" +#include "Lang.h" +#include "Pi.h" +#include "graphics/Graphics.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" -#include "graphics/Graphics.h" -#include "scenegraph/SceneGraph.h" #include "scenegraph/ModelSkin.h" +#include "scenegraph/SceneGraph.h" #include struct PiRngWrapper { - unsigned int operator()(unsigned int n) { + unsigned int operator()(unsigned int n) + { return Pi::rng.Int32(n); } }; -Intro::Intro(Graphics::Renderer *r, int width, int height) -: Cutscene(r, width, height) +Intro::Intro(Graphics::Renderer *r, int width, int height) : + Cutscene(r, width, height) { using Graphics::Light; @@ -38,21 +39,21 @@ Intro::Intro(Graphics::Renderer *r, int width, int height) SceneGraph::Model *model = Pi::FindModel(ShipType::types[i].modelName)->MakeInstance(); model->SetThrust(vector3f(0.f, 0.f, -0.6f), vector3f(0.f)); if (ShipType::types[i].isGlobalColorDefined) model->SetThrusterColor(ShipType::types[i].globalThrusterColor); - for (int j=0; jSetThrusterColor(dir, ShipType::types[i].directionThrusterColor[j]); } const Uint32 numMats = model->GetNumMaterials(); - for( Uint32 m=0; m mat = model->GetMaterialByIndex(m); mat->specialParameter0 = nullptr; } @@ -69,16 +70,16 @@ Intro::Intro(Graphics::Renderer *r, int width, int height) // double-width viewport, centred, then offset 1/6th to centre on the left // 2/3rds of the screen, to the left of the menu - m_spinnerLeft = int(float(w)*-.5f - float(w)/6.f); - m_spinnerWidth = w*2; - m_spinnerRatio = w*2.f/h; + m_spinnerLeft = int(float(w) * -.5f - float(w) / 6.f); + m_spinnerWidth = w * 2; + m_spinnerRatio = w * 2.f / h; m_needReset = true; } Intro::~Intro() { - for (std::vector::iterator i = m_models.begin(); i != m_models.end(); ++i) + for (std::vector::iterator i = m_models.begin(); i != m_models.end(); ++i) delete (*i); } @@ -88,18 +89,18 @@ void Intro::Reset(float _time) if (m_modelIndex == m_models.size()) m_modelIndex = 0; m_skin.SetRandomColors(Pi::rng); m_skin.Apply(m_model); - if(m_model->SupportsPatterns()) - m_model->SetPattern(Pi::rng.Int32(0, m_model->GetNumPatterns()-1)); + if (m_model->SupportsPatterns()) + m_model->SetPattern(Pi::rng.Int32(0, m_model->GetNumPatterns() - 1)); m_zoomBegin = -10000.0f; - m_zoomEnd = -m_model->GetDrawClipRadius()*1.7f; + m_zoomEnd = -m_model->GetDrawClipRadius() * 1.7f; m_dist = m_zoomBegin; m_startTime = _time; m_needReset = false; } // stage end times -static const float ZOOM_IN_END = 2.0f; -static const float WAIT_END = 12.0f; +static const float ZOOM_IN_END = 2.0f; +static const float WAIT_END = 12.0f; static const float ZOOM_OUT_END = 14.0f; void Intro::Draw(float _time) @@ -107,11 +108,11 @@ void Intro::Draw(float _time) if (m_needReset) Reset(_time); - float duration = _time-m_startTime; + float duration = _time - m_startTime; // zoom in if (duration < ZOOM_IN_END) - m_dist = Clamp(Easing::Quad::EaseOut(duration, m_zoomBegin, m_zoomEnd-m_zoomBegin, 2.0f), m_zoomBegin, m_zoomEnd); + m_dist = Clamp(Easing::Quad::EaseOut(duration, m_zoomBegin, m_zoomEnd - m_zoomBegin, 2.0f), m_zoomBegin, m_zoomEnd); // wait else if (duration < WAIT_END) { @@ -120,7 +121,7 @@ void Intro::Draw(float _time) // zoom out else if (duration < ZOOM_OUT_END) - m_dist = Clamp(Easing::Quad::EaseIn(duration-WAIT_END, m_zoomEnd, m_zoomBegin-m_zoomEnd, 2.0f), m_zoomBegin, m_zoomEnd); + m_dist = Clamp(Easing::Quad::EaseIn(duration - WAIT_END, m_zoomEnd, m_zoomBegin - m_zoomEnd, 2.0f), m_zoomBegin, m_zoomEnd); // done else @@ -136,7 +137,7 @@ void Intro::Draw(float _time) // XXX all this stuff will be gone when intro uses a Camera // rotate background by time, and a bit extra Z so it's not so flat - matrix4x4d brot = matrix4x4d::RotateXMatrix(-0.25*_time) * matrix4x4d::RotateZMatrix(0.6); + matrix4x4d brot = matrix4x4d::RotateXMatrix(-0.25 * _time) * matrix4x4d::RotateZMatrix(0.6); m_renderer->ClearDepthBuffer(); m_background->Draw(brot); diff --git a/src/Intro.h b/src/Intro.h index 1db9637e5..641cac08d 100644 --- a/src/Intro.h +++ b/src/Intro.h @@ -4,8 +4,8 @@ #ifndef _INTRO_H #define _INTRO_H -#include "Cutscene.h" #include "Background.h" +#include "Cutscene.h" #include "ShipType.h" #include "scenegraph/ModelSkin.h" @@ -19,7 +19,7 @@ private: void Reset(float time); bool m_needReset; - std::vector m_models; + std::vector m_models; SceneGraph::ModelSkin m_skin; float m_startTime; diff --git a/src/IterationProxy.h b/src/IterationProxy.h index e41426ed1..3517bc166 100644 --- a/src/IterationProxy.h +++ b/src/IterationProxy.h @@ -12,7 +12,8 @@ template class IterationProxy { public: - IterationProxy(Container& container) : m_container(container) { } + IterationProxy(Container &container) : + m_container(container) {} typename Container::iterator begin() { return m_container.begin(); } typename Container::iterator end() { return m_container.end(); } typename Container::const_iterator begin() const { return m_container.begin(); } @@ -21,16 +22,17 @@ public: typename Container::const_iterator cend() { return m_container.cend(); } private: - Container& m_container; + Container &m_container; }; // This specialized version is for containers that provide a random access iterator, we provide an operator[] in this case template class IterationProxy::iterator_category, - std::random_access_iterator_tag>::value>::type> { + std::random_access_iterator_tag>::value>::type> { public: - IterationProxy(Container& container) : m_container(container) { } + IterationProxy(Container &container) : + m_container(container) {} typename Container::iterator begin() { return m_container.begin(); } typename Container::iterator end() { return m_container.end(); } typename Container::const_iterator begin() const { return m_container.begin(); } @@ -42,10 +44,10 @@ public: typename Container::const_reference operator[](int i) const { return *(m_container.begin() + i); } private: - Container& m_container; + Container &m_container; }; template -inline IterationProxy MakeIterationProxy(Container& container) { return IterationProxy(container); } +inline IterationProxy MakeIterationProxy(Container &container) { return IterationProxy(container); } #endif diff --git a/src/JobQueue.cpp b/src/JobQueue.cpp index f92f6a5f7..a0256d5a1 100644 --- a/src/JobQueue.cpp +++ b/src/JobQueue.cpp @@ -19,7 +19,11 @@ Job::~Job() //static unsigned long long Job::Handle::s_nextId(0); -Job::Handle::Handle(Job* job, JobQueue* queue, JobClient* client) : m_id(++s_nextId), m_job(job), m_queue(queue), m_client(client) +Job::Handle::Handle(Job *job, JobQueue *queue, JobClient *client) : + m_id(++s_nextId), + m_job(job), + m_queue(queue), + m_client(client) { assert(!m_job->GetHandle()); m_job->SetHandle(this); @@ -31,7 +35,7 @@ void Job::Handle::Unlink() assert(m_job->GetHandle() == this); m_job->ClearHandle(); } - JobClient* client = m_client; // This Job::Handle may be deleted by the client, so clear it before + JobClient *client = m_client; // This Job::Handle may be deleted by the client, so clear it before m_job = nullptr; m_queue = nullptr; m_client = nullptr; @@ -39,7 +43,11 @@ void Job::Handle::Unlink() client->RemoveJob(this); // This might delete this Job::Handle, so the object must be cleared before } -Job::Handle::Handle(Handle&& other) : m_id(other.m_id), m_job(other.m_job), m_queue(other.m_queue), m_client(other.m_client) +Job::Handle::Handle(Handle &&other) : + m_id(other.m_id), + m_job(other.m_job), + m_queue(other.m_queue), + m_client(other.m_client) { if (m_job) { assert(m_job->GetHandle() == &other); @@ -51,7 +59,7 @@ Job::Handle::Handle(Handle&& other) : m_id(other.m_id), m_job(other.m_job), m_qu other.m_client = nullptr; } -Job::Handle& Job::Handle::operator=(Handle&& other) +Job::Handle &Job::Handle::operator=(Handle &&other) { if (m_job && m_queue) m_queue->Cancel(m_job); @@ -81,12 +89,11 @@ Job::Handle::~Handle() } } - AsyncJobQueue::AsyncJobQueue(Uint32 numRunners) : m_shutdown(false) { // Want to limit this for now to the maximum number of threads defined in the class - numRunners = std::min( numRunners, MAX_THREADS ); + numRunners = std::min(numRunners, MAX_THREADS); m_queueLock = SDL_CreateMutex(); m_queueWaitCond = SDL_CreateCond(); @@ -112,7 +119,7 @@ AsyncJobQueue::~AsyncJobQueue() // else is running one of our functions). Both the flag and the mutex // must be owned by the runner, because we may not exist when it's // checked. - for (std::vector::iterator i = m_runners.begin(); i != m_runners.end(); ++i) { + for (std::vector::iterator i = m_runners.begin(); i != m_runners.end(); ++i) { SDL_LockMutex((*i)->GetQueueDestroyingLock()); (*i)->SetQueueDestroyed(); SDL_UnlockMutex((*i)->GetQueueDestroyingLock()); @@ -120,20 +127,20 @@ AsyncJobQueue::~AsyncJobQueue() const uint32_t numThreads = m_runners.size(); // delete the runners. this will tear down their underlying threads - for (std::vector::iterator i = m_runners.begin(); i != m_runners.end(); ++i) + for (std::vector::iterator i = m_runners.begin(); i != m_runners.end(); ++i) delete (*i); // delete any remaining jobs - for (std::deque::iterator i = m_queue.begin(); i != m_queue.end(); ++i) + for (std::deque::iterator i = m_queue.begin(); i != m_queue.end(); ++i) delete (*i); - for (uint32_t threadIdx=0; threadIdx::iterator i = m_finished[threadIdx].begin(); i != m_finished[threadIdx].end(); ++i) { + for (uint32_t threadIdx = 0; threadIdx < numThreads; threadIdx++) { + for (std::deque::iterator i = m_finished[threadIdx].begin(); i != m_finished[threadIdx].end(); ++i) { delete (*i); } } // only us left now, we can clean up and get out of here - for (uint32_t threadIdx=0; threadIdxcancelled) { + if (!job->cancelled) { job->UnlinkHandle(); job->OnFinish(); finished++; @@ -225,16 +231,17 @@ Uint32 AsyncJobQueue::FinishJobs() return finished; } -void AsyncJobQueue::Cancel(Job *job) { +void AsyncJobQueue::Cancel(Job *job) +{ // lock both queues, so we know that all jobs will stay put SDL_LockMutex(m_queueLock); const uint32_t numRunners = m_runners.size(); - for( uint32_t i=0; i::iterator i = m_queue.begin(); i != m_queue.end(); ++i) { + for (std::deque::iterator i = m_queue.begin(); i != m_queue.end(); ++i) { if (*i == job) { i = m_queue.erase(i); delete job; @@ -244,8 +251,8 @@ void AsyncJobQueue::Cancel(Job *job) { // check the finshed list. if its there then it can't be cancelled, because // its alread finished! we remove it because the caller is saying "I don't care" - for( uint32_t iRunner=0; iRunner::iterator i = m_finished[iRunner].begin(); i != m_finished[iRunner].end(); ++i) { + for (uint32_t iRunner = 0; iRunner < numRunners; ++iRunner) { + for (std::deque::iterator i = m_finished[iRunner].begin(); i != m_finished[iRunner].end(); ++i) { if (*i == job) { i = m_finished[iRunner].erase(i); delete job; @@ -260,7 +267,7 @@ void AsyncJobQueue::Cancel(Job *job) { job->OnCancel(); unlock: - for( uint32_t i=0; i(data); + JobRunner *jr = static_cast(data); jr->Main(); return 0; } @@ -361,13 +368,12 @@ void AsyncJobQueue::JobRunner::SetQueueDestroyed() m_queueDestroyed = true; } - SyncJobQueue::~SyncJobQueue() { // delete any remaining jobs - for (Job* j : m_queue) + for (Job *j : m_queue) delete j; - for (Job* j : m_finished) + for (Job *j : m_finished) delete j; } @@ -389,7 +395,7 @@ Uint32 SyncJobQueue::FinishJobs() m_finished.pop_front(); // if its already been cancelled then its taken care of, so we just forget about it - if(!job->cancelled) { + if (!job->cancelled) { job->UnlinkHandle(); job->OnFinish(); finished++; @@ -400,9 +406,10 @@ Uint32 SyncJobQueue::FinishJobs() return finished; } -void SyncJobQueue::Cancel(Job *job) { +void SyncJobQueue::Cancel(Job *job) +{ // check the waiting list. if its there then it hasn't run yet. just forget about it - for (std::deque::iterator i = m_queue.begin(); i != m_queue.end(); ++i) { + for (std::deque::iterator i = m_queue.begin(); i != m_queue.end(); ++i) { if (*i == job) { i = m_queue.erase(i); delete job; @@ -412,7 +419,7 @@ void SyncJobQueue::Cancel(Job *job) { // check the finshed list. if its there then it can't be cancelled, because // its alread finished! we remove it because the caller is saying "I don't care" - for (std::deque::iterator i = m_finished.begin(); i != m_finished.end(); ++i) { + for (std::deque::iterator i = m_finished.begin(); i != m_finished.end(); ++i) { if (*i == job) { i = m_finished.erase(i); delete job; @@ -434,7 +441,7 @@ Uint32 SyncJobQueue::RunJobs(Uint32 count) if (m_queue.empty()) break; - Job* job = m_queue.front(); + Job *job = m_queue.front(); m_queue.pop_front(); job->OnRun(); executed++; diff --git a/src/JobQueue.h b/src/JobQueue.h index 7d212504e..56a5fe944 100644 --- a/src/JobQueue.h +++ b/src/JobQueue.h @@ -4,12 +4,12 @@ #ifndef JOBQUEUE_H #define JOBQUEUE_H +#include "SDL_thread.h" #include #include -#include #include #include -#include "SDL_thread.h" +#include static const Uint32 MAX_THREADS = 64; @@ -36,41 +36,47 @@ public: // moveable. class Handle { public: - Handle() : m_id(++s_nextId), m_job(nullptr), m_queue(nullptr), m_client(nullptr) { } - Handle(Handle&& other); - Handle& operator=(Handle&& other); + Handle() : + m_id(++s_nextId), + m_job(nullptr), + m_queue(nullptr), + m_client(nullptr) {} + Handle(Handle &&other); + Handle &operator=(Handle &&other); ~Handle(); - Handle(const Handle&) = delete; - Handle& operator=(const Handle&) = delete; + Handle(const Handle &) = delete; + Handle &operator=(const Handle &) = delete; bool HasJob() const { return m_job != nullptr; } - Job* GetJob() const { return m_job; } + Job *GetJob() const { return m_job; } - bool operator<(const Handle& other) const { return m_id < other.m_id; } + bool operator<(const Handle &other) const { return m_id < other.m_id; } private: friend class Job; friend class AsyncJobQueue; friend class SyncJobQueue; - Handle(Job* job, JobQueue* queue, JobClient* client); + Handle(Job *job, JobQueue *queue, JobClient *client); void Unlink(); static unsigned long long s_nextId; unsigned long long m_id; - Job* m_job; - JobQueue* m_queue; - JobClient* m_client; + Job *m_job; + JobQueue *m_queue; + JobClient *m_client; }; public: - Job() : cancelled(false), m_handle(nullptr) {} + Job() : + cancelled(false), + m_handle(nullptr) {} virtual ~Job(); - Job(const Job&) = delete; - Job& operator=(const Job&) = delete; + Job(const Job &) = delete; + Job &operator=(const Job &) = delete; virtual void OnRun() = 0; virtual void OnFinish() = 0; @@ -82,26 +88,25 @@ private: friend class JobRunner; void UnlinkHandle(); - const Handle* GetHandle() const { return m_handle; } - void SetHandle(Handle* handle) { m_handle = handle; } + const Handle *GetHandle() const { return m_handle; } + void SetHandle(Handle *handle) { m_handle = handle; } void ClearHandle() { m_handle = nullptr; } bool cancelled; - Handle* m_handle; + Handle *m_handle; }; - // the queue management class. create one from the main thread, and feed your // jobs do it. it will take care of the rest class JobQueue { public: JobQueue() = default; - JobQueue(const JobQueue&) = delete; - JobQueue& operator=(const JobQueue&) = delete; + JobQueue(const JobQueue &) = delete; + JobQueue &operator=(const JobQueue &) = delete; // numRunners is the number of jobs to run in parallel. right now its the // same as the number of threads, but there's no reason that it has to be - virtual ~JobQueue() { } + virtual ~JobQueue() {} // call from the main thread to add a job to the queue. the job should be // allocated with new. the queue will delete it once its its completed @@ -185,14 +190,14 @@ private: Job *GetJob(); void Finish(Job *job, const uint8_t threadIdx); - std::deque m_queue; + std::deque m_queue; SDL_mutex *m_queueLock; SDL_cond *m_queueWaitCond; - std::deque m_finished[MAX_THREADS]; + std::deque m_finished[MAX_THREADS]; SDL_mutex *m_finishedLock[MAX_THREADS]; - std::vector m_runners; + std::vector m_runners; bool m_shutdown; }; @@ -226,36 +231,46 @@ public: Uint32 RunJobs(Uint32 count = 1); private: - std::deque m_queue; - std::deque m_finished; + std::deque m_queue; + std::deque m_finished; }; class JobClient { public: - virtual void Order(Job* job) = 0; - virtual void RemoveJob(Job::Handle* handle) = 0; + virtual void Order(Job *job) = 0; + virtual void RemoveJob(Job::Handle *handle) = 0; virtual ~JobClient() {} }; class JobSet : public JobClient { public: - JobSet(JobQueue* queue) : m_queue(queue) { } - JobSet(JobSet&& other) : m_queue(other.m_queue), m_jobs(std::move(other.m_jobs)) { other.m_queue = nullptr; } - JobSet& operator=(JobSet&& other) { m_queue = other.m_queue; m_jobs = std::move(other.m_jobs); other.m_queue = nullptr; return *this; } + JobSet(JobQueue *queue) : + m_queue(queue) {} + JobSet(JobSet &&other) : + m_queue(other.m_queue), + m_jobs(std::move(other.m_jobs)) { other.m_queue = nullptr; } + JobSet &operator=(JobSet &&other) + { + m_queue = other.m_queue; + m_jobs = std::move(other.m_jobs); + other.m_queue = nullptr; + return *this; + } - JobSet(const JobSet&) = delete; - JobSet& operator=(const JobSet& other) = delete; + JobSet(const JobSet &) = delete; + JobSet &operator=(const JobSet &other) = delete; - virtual void Order(Job* job) { + virtual void Order(Job *job) + { auto x = m_jobs.insert(m_queue->Queue(job, this)); assert(x.second); } - virtual void RemoveJob(Job::Handle* handle) { m_jobs.erase(*handle); } + virtual void RemoveJob(Job::Handle *handle) { m_jobs.erase(*handle); } bool IsEmpty() const { return m_jobs.empty(); } private: - JobQueue* m_queue; + JobQueue *m_queue; std::set m_jobs; }; diff --git a/src/JsonUtils.cpp b/src/JsonUtils.cpp index 69ad3f5ca..85a2ef770 100644 --- a/src/JsonUtils.cpp +++ b/src/JsonUtils.cpp @@ -5,12 +5,12 @@ #define _USE_MATH_DEFINES #endif -#include #include "JsonUtils.h" -#include "utils.h" -#include "base64/base64.hpp" #include "FileSystem.h" #include "GZipFormat.h" +#include "base64/base64.hpp" +#include "utils.h" +#include extern "C" { #ifdef __GNUC__ @@ -41,10 +41,11 @@ namespace { static const vector3d zeroVector3d(0.0); static const Quaternionf identityQuaternionf(1.0f, 0.0f, 0.0f, 0.0f); static const Quaterniond identityQuaterniond(1.0, 0.0, 0.0, 0.0); -} +} // namespace namespace JsonUtils { - Json LoadJson(RefCountedPtr fd) { + Json LoadJson(RefCountedPtr fd) + { if (!fd) return Json(); Json out; @@ -94,8 +95,10 @@ namespace JsonUtils { Json rootNode; try { // Allow loading files in JSON format as well as CBOR - if (plain_data[0] == '{') return Json::parse(plain_data); - else return Json::from_cbor(plain_data); + if (plain_data[0] == '{') + return Json::parse(plain_data); + else + return Json::from_cbor(plain_data); } catch (Json::parse_error &e) { Output("error in JSON file '%s': %s\n", file->GetInfo().GetPath().c_str(), e.what()); return nullptr; @@ -104,8 +107,7 @@ namespace JsonUtils { return nullptr; } } -} - +} // namespace JsonUtils #define USE_STRING_VERSIONS @@ -167,11 +169,9 @@ void MatrixToJson(Json &jsonObj, const matrix3x3f &mat) Matrix3x3fToStr(mat, str, 512); jsonObj = str; #else - jsonObj = Json::array({ - mat[0], mat[1], mat[2], + jsonObj = Json::array({ mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], - mat[6], mat[7], mat[8] - }); + mat[6], mat[7], mat[8] }); #endif } @@ -184,11 +184,9 @@ void MatrixToJson(Json &jsonObj, const matrix3x3d &mat) Matrix3x3dToStr(mat, str, 512); jsonObj = str; #else - jsonObj = Json::array({ - mat[0], mat[1], mat[2], + jsonObj = Json::array({ mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], - mat[6], mat[7], mat[8] - }); + mat[6], mat[7], mat[8] }); #endif } @@ -202,10 +200,22 @@ void MatrixToJson(Json &jsonObj, const matrix4x4f &mat) jsonObj = str; #else jsonObj = Json::array({ - mat[0], mat[1], mat[2], mat[3], - mat[4], mat[5], mat[6], mat[7], - mat[8], mat[9], mat[10], mat[11], - mat[12], mat[13], mat[14], mat[15], + mat[0], + mat[1], + mat[2], + mat[3], + mat[4], + mat[5], + mat[6], + mat[7], + mat[8], + mat[9], + mat[10], + mat[11], + mat[12], + mat[13], + mat[14], + mat[15], }); #endif } @@ -220,10 +230,22 @@ void MatrixToJson(Json &jsonObj, const matrix4x4d &mat) jsonObj = str; #else jsonObj = Json::array({ - mat[0], mat[1], mat[2], mat[3], - mat[4], mat[5], mat[6], mat[7], - mat[8], mat[9], mat[10], mat[11], - mat[12], mat[13], mat[14], mat[15], + mat[0], + mat[1], + mat[2], + mat[3], + mat[4], + mat[5], + mat[6], + mat[7], + mat[8], + mat[9], + mat[10], + mat[11], + mat[12], + mat[13], + mat[14], + mat[15], }); #endif } @@ -357,24 +379,24 @@ void JsonToMatrix(matrix3x3f *pMat, const Json &jsonObj) void JsonToMatrix(matrix3x3d *pMat, const Json &jsonObj) { PROFILE_SCOPED() - #ifdef USE_STRING_VERSIONS - if (!jsonObj.is_string()) { - *pMat = matrix3x3dIdentity; - return; - } - std::string matStr = jsonObj; - StrToMatrix3x3d(matStr.c_str(), *pMat); - #else - (*pMat)[0] = jsonObj[0]; - (*pMat)[1] = jsonObj[1]; - (*pMat)[2] = jsonObj[2]; - (*pMat)[3] = jsonObj[3]; - (*pMat)[4] = jsonObj[4]; - (*pMat)[5] = jsonObj[5]; - (*pMat)[6] = jsonObj[6]; - (*pMat)[7] = jsonObj[7]; - (*pMat)[8] = jsonObj[8]; - #endif +#ifdef USE_STRING_VERSIONS + if (!jsonObj.is_string()) { + *pMat = matrix3x3dIdentity; + return; + } + std::string matStr = jsonObj; + StrToMatrix3x3d(matStr.c_str(), *pMat); +#else + (*pMat)[0] = jsonObj[0]; + (*pMat)[1] = jsonObj[1]; + (*pMat)[2] = jsonObj[2]; + (*pMat)[3] = jsonObj[3]; + (*pMat)[4] = jsonObj[4]; + (*pMat)[5] = jsonObj[5]; + (*pMat)[6] = jsonObj[6]; + (*pMat)[7] = jsonObj[7]; + (*pMat)[8] = jsonObj[8]; +#endif } void JsonToMatrix(matrix4x4f *pMat, const Json &jsonObj) diff --git a/src/JsonUtils.h b/src/JsonUtils.h index d6e45d58e..0ac38092d 100644 --- a/src/JsonUtils.h +++ b/src/JsonUtils.h @@ -4,30 +4,30 @@ #ifndef _JSON_UTILS_H #define _JSON_UTILS_H +#include "Color.h" #include "Json.h" -#include "vector3.h" #include "Quaternion.h" +#include "RefCounted.h" #include "matrix3x3.h" #include "matrix4x4.h" -#include "Color.h" -#include "RefCounted.h" +#include "vector3.h" namespace FileSystem { - class FileSource; - class FileData; -} + class FileSource; + class FileData; +} // namespace FileSystem namespace JsonUtils { - // Low-level load JSON from a file descriptor. - Json LoadJson(RefCountedPtr fd); - // Load a JSON file from a path and a file source. - Json LoadJsonFile(const std::string &filename, FileSystem::FileSource &source); - // Load a JSON file from the game's data sources, optionally applying all - // files with the the name .patch as Json Merge Patch (RFC 7386) files - Json LoadJsonDataFile(const std::string &filename, bool with_merge = true); - // Loads an optionally-gzipped, optionally-CBOR encoded JSON file from the specified source. - Json LoadJsonSaveFile(const std::string &filename, FileSystem::FileSource &source); -} + // Low-level load JSON from a file descriptor. + Json LoadJson(RefCountedPtr fd); + // Load a JSON file from a path and a file source. + Json LoadJsonFile(const std::string &filename, FileSystem::FileSource &source); + // Load a JSON file from the game's data sources, optionally applying all + // files with the the name .patch as Json Merge Patch (RFC 7386) files + Json LoadJsonDataFile(const std::string &filename, bool with_merge = true); + // Loads an optionally-gzipped, optionally-CBOR encoded JSON file from the specified source. + Json LoadJsonSaveFile(const std::string &filename, FileSystem::FileSource &source); +} // namespace JsonUtils // To-JSON functions. These are called explicitly, and are passed a reference to the object to fill. void VectorToJson(Json &jsonObj, const vector3f &vec); @@ -43,10 +43,14 @@ void ColorToJson(Json &jsonObj, const Color4ub &col); void BinStrToJson(Json &jsonObj, const std::string &str); // Drivers for automatic serialization of custom types. These are implicitly called by assigning to a Json object. -template void to_json(Json &obj, const vector3 &vec) { VectorToJson(obj, vec); } -template void to_json(Json &obj, const Quaternion &vec) { QuaternionToJson(obj, vec); } -template void to_json(Json &obj, const matrix3x3 &mat) { MatrixToJson(obj, mat); } -template void to_json(Json &obj, const matrix4x4 &mat) { MatrixToJson(obj, mat); } +template +void to_json(Json &obj, const vector3 &vec) { VectorToJson(obj, vec); } +template +void to_json(Json &obj, const Quaternion &vec) { QuaternionToJson(obj, vec); } +template +void to_json(Json &obj, const matrix3x3 &mat) { MatrixToJson(obj, mat); } +template +void to_json(Json &obj, const matrix4x4 &mat) { MatrixToJson(obj, mat); } inline void to_json(Json &obj, const Color3ub &col) { ColorToJson(obj, col); } inline void to_json(Json &obj, const Color4ub &col) { ColorToJson(obj, col); } @@ -63,10 +67,14 @@ void JsonToColor(Color3ub *pCol, const Json &jsonObj); void JsonToColor(Color4ub *pCol, const Json &jsonObj); std::string JsonToBinStr(const Json &jsonObj); -template void from_json(const Json &obj, vector3 &vec) { JsonToVector(&vec, obj); } -template void from_json(const Json &obj, Quaternion &vec) { JsonToQuaternion(&vec, obj); } -template void from_json(const Json &obj, matrix3x3 &vec) { JsonToMatrix(&vec, obj); } -template void from_json(const Json &obj, matrix4x4 &vec) { JsonToMatrix(&vec, obj); } +template +void from_json(const Json &obj, vector3 &vec) { JsonToVector(&vec, obj); } +template +void from_json(const Json &obj, Quaternion &vec) { JsonToQuaternion(&vec, obj); } +template +void from_json(const Json &obj, matrix3x3 &vec) { JsonToMatrix(&vec, obj); } +template +void from_json(const Json &obj, matrix4x4 &vec) { JsonToMatrix(&vec, obj); } inline void from_json(const Json &obj, Color3ub &col) { JsonToColor(&col, obj); } inline void from_json(const Json &obj, Color4ub &col) { JsonToColor(&col, obj); } diff --git a/src/KeyBindings.cpp b/src/KeyBindings.cpp index e5d382651..3791e3626 100644 --- a/src/KeyBindings.cpp +++ b/src/KeyBindings.cpp @@ -2,23 +2,28 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "KeyBindings.h" -#include "Pi.h" #include "Lang.h" +#include "Pi.h" #include "StringF.h" -#include #include +#include static bool m_disableBindings = 0; namespace KeyBindings { -#define KEY_BINDING(name,a,b,c,d) ActionBinding name; -#define AXIS_BINDING(name,a,b,c) JoyAxisBinding name; +#define KEY_BINDING(name, a, b, c, d) ActionBinding name; +#define AXIS_BINDING(name, a, b, c) JoyAxisBinding name; #include "KeyBindings.inc.h" // create the BindingPrototype sets for use by the UI -#define BINDING_PAGE(name) const BindingPrototype BINDING_PROTOS_ ## name[] = { -#define BINDING_PAGE_END() {0,0,0,0}}; +#define BINDING_PAGE(name) const BindingPrototype BINDING_PROTOS_##name[] = { +#define BINDING_PAGE_END() \ + { \ + 0, 0, 0, 0 \ + } \ + } \ + ; #define BINDING_GROUP(ui_name) \ { ui_name, 0, 0, 0 }, #define KEY_BINDING(name, config_name, ui_name, def1, def2) \ @@ -27,95 +32,111 @@ namespace KeyBindings { { ui_name, config_name, 0, &KeyBindings::name }, #include "KeyBindings.inc.h" -// static binding object lists for use by the dispatch function -static ActionBinding* const s_KeyBindings[] = { -#define KEY_BINDING(name, a,b,c,d) &KeyBindings::name, + // static binding object lists for use by the dispatch function + static ActionBinding *const s_KeyBindings[] = { +#define KEY_BINDING(name, a, b, c, d) &KeyBindings::name, #include "KeyBindings.inc.h" - 0 -}; + 0 + }; -bool KeyBinding::IsActive() const -{ - if (type == BINDING_DISABLED) { - return false; - } else if (type == KEYBOARD_KEY) { - if (!Pi::input.KeyState(u.keyboard.key)) + bool KeyBinding::IsActive() const + { + if (type == BINDING_DISABLED) { return false; - if (u.keyboard.mod == KMOD_NONE) - return true; - else { - int mod = Pi::input.KeyModState(); - if (mod & KMOD_CTRL) { mod |= KMOD_CTRL; } - if (mod & KMOD_SHIFT) { mod |= KMOD_SHIFT; } - if (mod & KMOD_ALT) { mod |= KMOD_ALT; } - if (mod & KMOD_GUI) { mod |= KMOD_GUI; } - return ((mod & u.keyboard.mod) == u.keyboard.mod); + } else if (type == KEYBOARD_KEY) { + if (!Pi::input.KeyState(u.keyboard.key)) + return false; + if (u.keyboard.mod == KMOD_NONE) + return true; + else { + int mod = Pi::input.KeyModState(); + if (mod & KMOD_CTRL) { + mod |= KMOD_CTRL; + } + if (mod & KMOD_SHIFT) { + mod |= KMOD_SHIFT; + } + if (mod & KMOD_ALT) { + mod |= KMOD_ALT; + } + if (mod & KMOD_GUI) { + mod |= KMOD_GUI; + } + return ((mod & u.keyboard.mod) == u.keyboard.mod); + } + } else if (type == JOYSTICK_BUTTON) { + return Pi::input.JoystickButtonState(u.joystickButton.joystick, u.joystickButton.button) != 0; + } else if (type == JOYSTICK_HAT) { + // SDL_HAT generates diagonal directions by ORing two cardinal directions. + int hatState = Pi::input.JoystickHatState(u.joystickHat.joystick, u.joystickHat.hat); + return (hatState & u.joystickHat.direction) == u.joystickHat.direction; + } else + abort(); + + return false; + } + + bool KeyBinding::Matches(const SDL_Keysym *sym) const + { + int mod = sym->mod; + if (mod & KMOD_CTRL) { + mod |= KMOD_CTRL; } - } else if (type == JOYSTICK_BUTTON) { - return Pi::input.JoystickButtonState(u.joystickButton.joystick, u.joystickButton.button) != 0; - } else if (type == JOYSTICK_HAT) { - // SDL_HAT generates diagonal directions by ORing two cardinal directions. - int hatState = Pi::input.JoystickHatState(u.joystickHat.joystick, u.joystickHat.hat); - return (hatState & u.joystickHat.direction) == u.joystickHat.direction; - } else - abort(); + if (mod & KMOD_SHIFT) { + mod |= KMOD_SHIFT; + } + if (mod & KMOD_ALT) { + mod |= KMOD_ALT; + } + if (mod & KMOD_GUI) { + mod |= KMOD_GUI; + } + return (type == KEYBOARD_KEY) && + (sym->sym == u.keyboard.key) && + ((mod & u.keyboard.mod) == u.keyboard.mod); + } - return false; -} + bool KeyBinding::Matches(const SDL_JoyButtonEvent *joy) const + { + return (type == JOYSTICK_BUTTON) && + (joy->which == u.joystickButton.joystick) && + (joy->button == u.joystickButton.button); + } -bool KeyBinding::Matches(const SDL_Keysym *sym) const { - int mod = sym->mod; - if (mod & KMOD_CTRL) { mod |= KMOD_CTRL; } - if (mod & KMOD_SHIFT) { mod |= KMOD_SHIFT; } - if (mod & KMOD_ALT) { mod |= KMOD_ALT; } - if (mod & KMOD_GUI) { mod |= KMOD_GUI; } - return - (type == KEYBOARD_KEY) && - (sym->sym == u.keyboard.key) && - ((mod & u.keyboard.mod) == u.keyboard.mod); -} + bool KeyBinding::Matches(const SDL_JoyHatEvent *joy) const + { + return (type == JOYSTICK_HAT) && + (joy->which == u.joystickHat.joystick) && + (joy->hat == u.joystickHat.hat) && + (joy->value == u.joystickHat.direction); + } -bool KeyBinding::Matches(const SDL_JoyButtonEvent *joy) const { - return - (type == JOYSTICK_BUTTON) && - (joy->which == u.joystickButton.joystick) && - (joy->button == u.joystickButton.button); -} + std::string KeyBinding::Description() const + { + std::ostringstream oss; -bool KeyBinding::Matches(const SDL_JoyHatEvent *joy) const { - return - (type == JOYSTICK_HAT) && - (joy->which == u.joystickHat.joystick) && - (joy->hat == u.joystickHat.hat) && - (joy->value == u.joystickHat.direction); -} + if (type == BINDING_DISABLED) { + // blank + } else if (type == KEYBOARD_KEY) { + if (u.keyboard.mod & KMOD_SHIFT) oss << Lang::SHIFT << " + "; + if (u.keyboard.mod & KMOD_CTRL) oss << Lang::CTRL << " + "; + if (u.keyboard.mod & KMOD_ALT) oss << Lang::ALT << " + "; + if (u.keyboard.mod & KMOD_GUI) oss << Lang::META << " + "; + oss << SDL_GetKeyName(u.keyboard.key); + } else if (type == JOYSTICK_BUTTON) { + oss << Pi::input.JoystickName(u.joystickButton.joystick); + oss << Lang::BUTTON << int(u.joystickButton.button); + } else if (type == JOYSTICK_HAT) { + oss << Pi::input.JoystickName(u.joystickHat.joystick); + oss << Lang::HAT << int(u.joystickHat.hat); + oss << Lang::DIRECTION << int(u.joystickHat.direction); + } else + assert(0 && "invalid key binding type"); -std::string KeyBinding::Description() const { - std::ostringstream oss; + return oss.str(); + } - if (type == BINDING_DISABLED) { - // blank - } else if (type == KEYBOARD_KEY) { - if (u.keyboard.mod & KMOD_SHIFT) oss << Lang::SHIFT << " + "; - if (u.keyboard.mod & KMOD_CTRL) oss << Lang::CTRL << " + "; - if (u.keyboard.mod & KMOD_ALT) oss << Lang::ALT << " + "; - if (u.keyboard.mod & KMOD_GUI) oss << Lang::META << " + "; - oss << SDL_GetKeyName(u.keyboard.key); - } else if (type == JOYSTICK_BUTTON) { - oss << Pi::input.JoystickName(u.joystickButton.joystick); - oss << Lang::BUTTON << int(u.joystickButton.button); - } else if (type == JOYSTICK_HAT) { - oss << Pi::input.JoystickName(u.joystickHat.joystick); - oss << Lang::HAT << int(u.joystickHat.hat); - oss << Lang::DIRECTION << int(u.joystickHat.direction); - } else - assert(0 && "invalid key binding type"); - - return oss.str(); -} - - -/** + /** * In a C string pointed to by the string pointer pointed to by p, scan for * the character token tok, copying the bytes on the way to bufOut which is at most buflen long. * @@ -124,55 +145,332 @@ std::string KeyBinding::Description() const { * * upon return, the pointer pointed to by p will refer to the character AFTER the tok. */ -static bool ReadToTok(char tok, const char **p, char *bufOut, size_t buflen) { - unsigned int idx; - for (idx = 0; idx < buflen; idx++) { - if (**p == '\0' || **p == tok) { - break; + static bool ReadToTok(char tok, const char **p, char *bufOut, size_t buflen) + { + unsigned int idx; + for (idx = 0; idx < buflen; idx++) { + if (**p == '\0' || **p == tok) { + break; + } + bufOut[idx] = *((*p)++); } - bufOut[idx] = *((*p)++); + // if, after that, we're not pointing at the tok, we must have hit + // the terminal or run out of buffer. + if (**p != tok) { + return false; + } + // otherwise, skip over the tok. + (*p)++; + // if there is sufficient space in the buffer, NUL terminate. + if (idx < buflen) { + bufOut[idx] = '\0'; + } + return true; } - // if, after that, we're not pointing at the tok, we must have hit - // the terminal or run out of buffer. - if (**p != tok) { - return false; - } - // otherwise, skip over the tok. - (*p)++; - // if there is sufficient space in the buffer, NUL terminate. - if (idx < buflen) { - bufOut[idx] = '\0'; - } - return true; -} -/** + /** * Example strings: * Key55 * Joy{uuid}/Button2 * Joy{uuid}/Hat0Dir3 */ -bool KeyBinding::FromString(const char *str, KeyBinding &kb) -{ - const char *digits = "1234567890"; - const char *p = str; + bool KeyBinding::FromString(const char *str, KeyBinding &kb) + { + const char *digits = "1234567890"; + const char *p = str; - if (strcmp(p, "disabled") == 0) { - kb.Clear(); - } else if (strncmp(p, "Key", 3) == 0) { - kb.type = KEYBOARD_KEY; - p += 3; - - kb.u.keyboard.key = SDL_Keycode(atoi(p)); - p += strspn(p, digits); - - if (strncmp(p, "Mod", 3) == 0) { + if (strcmp(p, "disabled") == 0) { + kb.Clear(); + } else if (strncmp(p, "Key", 3) == 0) { + kb.type = KEYBOARD_KEY; p += 3; - kb.u.keyboard.mod = SDL_Keymod(atoi(p)); - } else { - kb.u.keyboard.mod = KMOD_NONE; + + kb.u.keyboard.key = SDL_Keycode(atoi(p)); + p += strspn(p, digits); + + if (strncmp(p, "Mod", 3) == 0) { + p += 3; + kb.u.keyboard.mod = SDL_Keymod(atoi(p)); + } else { + kb.u.keyboard.mod = KMOD_NONE; + } + } else if (strncmp(p, "Joy", 3) == 0) { + p += 3; + + const int JoyUUIDLength = 33; + char joyUUIDBuf[JoyUUIDLength]; + + // read the UUID + if (!ReadToTok('/', &p, joyUUIDBuf, JoyUUIDLength)) { + return false; + } + // force terminate + joyUUIDBuf[JoyUUIDLength - 1] = '\0'; + // now, locate the internal ID. + int joy = Pi::input.JoystickFromGUIDString(joyUUIDBuf); + if (joy == -1) { + return false; + } + if (strncmp(p, "Button", 6) == 0) { + p += 6; + kb.type = JOYSTICK_BUTTON; + kb.u.joystickButton.joystick = joy; + kb.u.joystickButton.button = atoi(p); + } else if (strncmp(p, "Hat", 3) == 0) { + p += 3; + kb.type = JOYSTICK_HAT; + kb.u.joystickHat.joystick = joy; + kb.u.joystickHat.hat = atoi(p); + p += strspn(p, digits); + + if (strncmp(p, "Dir", 3) != 0) + return false; + + p += 3; + kb.u.joystickHat.direction = atoi(p); + } else + return false; } - } else if (strncmp(p, "Joy", 3) == 0) { + + return true; + } + + KeyBinding KeyBinding::FromString(const char *str) + { + KeyBinding kb; + if (!KeyBinding::FromString(str, kb)) + kb.Clear(); + return kb; + } + + std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb) + { + if (kb.type == BINDING_DISABLED) { + oss << "disabled"; + } else if (kb.type == KEYBOARD_KEY) { + oss << "Key" << int(kb.u.keyboard.key); + if (kb.u.keyboard.mod != 0) { + oss << "Mod" << int(kb.u.keyboard.mod); + } + } else if (kb.type == JOYSTICK_BUTTON) { + oss << "Joy" << Pi::input.JoystickGUIDString(kb.u.joystickButton.joystick); + oss << "/Button" << int(kb.u.joystickButton.button); + } else if (kb.type == JOYSTICK_HAT) { + oss << "Joy" << Pi::input.JoystickGUIDString(kb.u.joystickButton.joystick); + oss << "/Hat" << int(kb.u.joystickHat.hat); + oss << "Dir" << int(kb.u.joystickHat.direction); + } else { + assert(0 && "KeyBinding type field is invalid"); + } + return oss; + } + + std::string KeyBinding::ToString() const + { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + KeyBinding KeyBinding::FromKeyMod(SDL_Keycode key, SDL_Keymod mod) + { + KeyBinding kb; + kb.type = KEYBOARD_KEY; + kb.u.keyboard.key = key; + // expand the modifier to cover both left & right variants + int imod = mod; + if (imod & KMOD_CTRL) { + imod |= KMOD_CTRL; + } + if (imod & KMOD_SHIFT) { + imod |= KMOD_SHIFT; + } + if (imod & KMOD_ALT) { + imod |= KMOD_ALT; + } + if (imod & KMOD_GUI) { + imod |= KMOD_GUI; + } + kb.u.keyboard.mod = static_cast(imod); + return kb; + } + + KeyBinding KeyBinding::FromJoystickButton(Uint8 joystick, Uint8 button) + { + KeyBinding kb; + kb.type = JOYSTICK_BUTTON; + kb.u.joystickButton.joystick = joystick; + kb.u.joystickButton.button = button; + return kb; + } + + KeyBinding KeyBinding::FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction) + { + KeyBinding kb; + kb.type = JOYSTICK_HAT; + kb.u.joystickHat.joystick = joystick; + kb.u.joystickHat.hat = hat; + kb.u.joystickHat.direction = direction; + return kb; + } + + void ActionBinding::SetFromString(const char *str) + { + const size_t BUF_SIZE = 64; + const size_t len = strlen(str); + if (len >= BUF_SIZE) { + Output("invalid ActionBinding string\n"); + binding1 = KeyBinding::FromString(str); + binding2.Clear(); + } else { + const char *sep = strchr(str, ','); + if (sep) { + char buf[BUF_SIZE]; + const size_t len1 = sep - str; + const size_t len2 = len - len1 - 1; + memcpy(buf, str, len1); + buf[len1] = '\0'; + binding1 = KeyBinding::FromString(buf); + memcpy(buf, sep + 1, len2); + buf[len2] = '\0'; + binding2 = KeyBinding::FromString(buf); + } else { + binding1 = KeyBinding::FromString(str); + binding2.Clear(); + } + } + } + + std::string ActionBinding::ToString() const + { + std::ostringstream oss; + if (binding1.Enabled() && binding2.Enabled()) { + oss << binding1 << "," << binding2; + } else if (binding1.Enabled()) { + oss << binding1; + } else if (binding2.Enabled()) { + oss << binding2; + } else { + oss << "disabled"; + } + return oss.str(); + } + + bool ActionBinding::IsActive() const + { + return binding1.IsActive() || binding2.IsActive(); + } + + bool ActionBinding::Matches(const SDL_Keysym *sym) const + { + return binding1.Matches(sym) || binding2.Matches(sym); + } + + void ActionBinding::CheckSDLEventAndDispatch(const SDL_Event *event) + { + if (m_disableBindings) return; + switch (event->type) { + case SDL_KEYDOWN: + case SDL_KEYUP: { + if (Matches(&event->key.keysym)) { + if (event->key.state == SDL_PRESSED) + onPress.emit(); + else if (event->key.state == SDL_RELEASED) + onRelease.emit(); + } + break; + } + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: { + if (binding1.Matches(&event->jbutton) || binding2.Matches(&event->jbutton)) { + if (event->jbutton.state == SDL_PRESSED) + onPress.emit(); + else if (event->jbutton.state == SDL_RELEASED) + onRelease.emit(); + } + break; + } + case SDL_JOYHATMOTION: { + if (binding1.Matches(&event->jhat) || binding2.Matches(&event->jhat)) { + onPress.emit(); + // XXX to emit onRelease, we need to have access to the state of the joystick hat prior to this event, + // so that we can detect the case of switching from a direction that matches the binding to some other direction + } + break; + } + default: break; + } + } + + bool JoyAxisBinding::IsActive() const + { + // If the stick is within the deadzone, it's not active. + return fabs(Pi::input.JoystickAxisState(joystick, axis)) > deadzone; + } + + float JoyAxisBinding::GetValue() const + { + if (!Enabled()) return 0.0f; + + const float o_val = Pi::input.JoystickAxisState(joystick, axis); + + // Deadzone with normalisation + float value = fabs(o_val); + if (value < deadzone) { + return 0.0f; + } else { + // subtract deadzone and re-normalise to full range + value = (value - deadzone) / (1.0f - deadzone); + } + + // Apply sensitivity scaling and clamp. + value = fmax(fmin(value * sensitivity, 1.0f), 0.0f); + + value = copysign(value, o_val); + + // Invert as necessary. + return direction == POSITIVE ? value : 0.0f - value; + } + + bool JoyAxisBinding::Matches(const SDL_Event *event) const + { + if (event->type != SDL_JOYAXISMOTION) return false; + return event->jaxis.which == joystick && event->jaxis.axis == axis; + } + + std::string JoyAxisBinding::Description() const + { + if (!Enabled()) return std::string(); + + const char *axis_names[] = { Lang::X, Lang::Y, Lang::Z }; + std::ostringstream ossaxisnum; + ossaxisnum << int(axis); + + return stringf(Lang::JOY_AXIS, + formatarg("sign", direction == KeyBindings::NEGATIVE ? "-" : ""), // no + sign if positive + formatarg("signp", direction == KeyBindings::NEGATIVE ? "-" : "+"), // optional with + sign + formatarg("joynum", joystick), + formatarg("joyname", Pi::input.JoystickName(joystick)), + formatarg("axis", axis >= 0 && axis < 3 ? axis_names[axis] : ossaxisnum.str())); + } + + bool JoyAxisBinding::FromString(const char *str, JoyAxisBinding &ab) + { + if (strcmp(str, "disabled") == 0) { + ab.Clear(); + return true; + } + + const char *p = str; + + if (p[0] == '-') { + ab.direction = NEGATIVE; + p++; + } else + ab.direction = POSITIVE; + + if (strncmp(p, "Joy", 3) != 0) + return false; p += 3; const int JoyUUIDLength = 33; @@ -183,397 +481,130 @@ bool KeyBinding::FromString(const char *str, KeyBinding &kb) return false; } // force terminate - joyUUIDBuf[JoyUUIDLength-1] = '\0'; - // now, locate the internal ID. - int joy = Pi::input.JoystickFromGUIDString(joyUUIDBuf); - if (joy == -1) { + joyUUIDBuf[JoyUUIDLength - 1] = '\0'; + // now, map the GUID to a joystick number + const int joystick = Pi::input.JoystickFromGUIDString(joyUUIDBuf); + if (joystick == -1) { return false; } - if (strncmp(p, "Button", 6) == 0) { - p += 6; - kb.type = JOYSTICK_BUTTON; - kb.u.joystickButton.joystick = joy; - kb.u.joystickButton.button = atoi(p); - } else if (strncmp(p, "Hat", 3) == 0) { - p += 3; - kb.type = JOYSTICK_HAT; - kb.u.joystickHat.joystick = joy; - kb.u.joystickHat.hat = atoi(p); - p += strspn(p, digits); + // found a joystick + assert(joystick < 256); + ab.joystick = Uint8(joystick); - if (strncmp(p, "Dir", 3) != 0) - return false; - - p += 3; - kb.u.joystickHat.direction = atoi(p); - } else + if (strncmp(p, "Axis", 4) != 0) return false; - } - return true; -} + p += 4; + ab.axis = atoi(p); -KeyBinding KeyBinding::FromString(const char *str) { - KeyBinding kb; - if (!KeyBinding::FromString(str, kb)) - kb.Clear(); - return kb; -} + // Skip past the axis integer + if (!(p = strstr(p, "/DZ"))) + return true; // deadzone is optional -std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb) -{ - if (kb.type == BINDING_DISABLED) { - oss << "disabled"; - } else if (kb.type == KEYBOARD_KEY) { - oss << "Key" << int(kb.u.keyboard.key); - if (kb.u.keyboard.mod != 0) { - oss << "Mod" << int(kb.u.keyboard.mod); - } - } else if (kb.type == JOYSTICK_BUTTON) { - oss << "Joy" << Pi::input.JoystickGUIDString(kb.u.joystickButton.joystick); - oss << "/Button" << int(kb.u.joystickButton.button); - } else if (kb.type == JOYSTICK_HAT) { - oss << "Joy" << Pi::input.JoystickGUIDString(kb.u.joystickButton.joystick); - oss << "/Hat" << int(kb.u.joystickHat.hat); - oss << "Dir" << int(kb.u.joystickHat.direction); - } else { - assert(0 && "KeyBinding type field is invalid"); - } - return oss; -} + p += 3; + ab.deadzone = atof(p); -std::string KeyBinding::ToString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); -} + // Skip past the deadzone float + if (!(p = strstr(p, "/E"))) + return true; // sensitivity is optional -KeyBinding KeyBinding::FromKeyMod(SDL_Keycode key, SDL_Keymod mod) -{ - KeyBinding kb; - kb.type = KEYBOARD_KEY; - kb.u.keyboard.key = key; - // expand the modifier to cover both left & right variants - int imod = mod; - if (imod & KMOD_CTRL) { imod |= KMOD_CTRL; } - if (imod & KMOD_SHIFT) { imod |= KMOD_SHIFT; } - if (imod & KMOD_ALT) { imod |= KMOD_ALT; } - if (imod & KMOD_GUI) { imod |= KMOD_GUI; } - kb.u.keyboard.mod = static_cast(imod); - return kb; -} + p += 2; + ab.sensitivity = atof(p); -KeyBinding KeyBinding::FromJoystickButton(Uint8 joystick, Uint8 button) -{ - KeyBinding kb; - kb.type = JOYSTICK_BUTTON; - kb.u.joystickButton.joystick = joystick; - kb.u.joystickButton.button = button; - return kb; -} - -KeyBinding KeyBinding::FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction) -{ - KeyBinding kb; - kb.type = JOYSTICK_HAT; - kb.u.joystickHat.joystick = joystick; - kb.u.joystickHat.hat = hat; - kb.u.joystickHat.direction = direction; - return kb; -} - -void ActionBinding::SetFromString(const char *str) -{ - const size_t BUF_SIZE = 64; - const size_t len = strlen(str); - if (len >= BUF_SIZE) { - Output("invalid ActionBinding string\n"); - binding1 = KeyBinding::FromString(str); - binding2.Clear(); - } else { - const char *sep = strchr(str, ','); - if (sep) { - char buf[BUF_SIZE]; - const size_t len1 = sep - str; - const size_t len2 = len - len1 - 1; - memcpy(buf, str, len1); - buf[len1] = '\0'; - binding1 = KeyBinding::FromString(buf); - memcpy(buf, sep+1, len2); - buf[len2] = '\0'; - binding2 = KeyBinding::FromString(buf); - } else { - binding1 = KeyBinding::FromString(str); - binding2.Clear(); - } - } -} - -std::string ActionBinding::ToString() const -{ - std::ostringstream oss; - if (binding1.Enabled() && binding2.Enabled()) { - oss << binding1 << "," << binding2; - } else if (binding1.Enabled()) { - oss << binding1; - } else if (binding2.Enabled()) { - oss << binding2; - } else { - oss << "disabled"; - } - return oss.str(); -} - -bool ActionBinding::IsActive() const { - return binding1.IsActive() || binding2.IsActive(); -} - -bool ActionBinding::Matches(const SDL_Keysym *sym) const { - return binding1.Matches(sym) || binding2.Matches(sym); -} - -void ActionBinding::CheckSDLEventAndDispatch(const SDL_Event *event) { - if (m_disableBindings) return; - switch (event->type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - { - if (Matches(&event->key.keysym)) { - if (event->key.state == SDL_PRESSED) - onPress.emit(); - else if (event->key.state == SDL_RELEASED) - onRelease.emit(); - } - break; - } - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - { - if (binding1.Matches(&event->jbutton) || binding2.Matches(&event->jbutton)) { - if (event->jbutton.state == SDL_PRESSED) - onPress.emit(); - else if (event->jbutton.state == SDL_RELEASED) - onRelease.emit(); - } - break; - } - case SDL_JOYHATMOTION: - { - if (binding1.Matches(&event->jhat) || binding2.Matches(&event->jhat)) { - onPress.emit(); - // XXX to emit onRelease, we need to have access to the state of the joystick hat prior to this event, - // so that we can detect the case of switching from a direction that matches the binding to some other direction - } - break; - } - default: break; - } -} - -bool JoyAxisBinding::IsActive() const -{ - // If the stick is within the deadzone, it's not active. - return fabs(Pi::input.JoystickAxisState(joystick, axis)) > deadzone; -} - -float JoyAxisBinding::GetValue() const -{ - if (!Enabled()) return 0.0f; - - const float o_val = Pi::input.JoystickAxisState(joystick, axis); - - // Deadzone with normalisation - float value = fabs(o_val); - if (value < deadzone) { - return 0.0f; - } else { - // subtract deadzone and re-normalise to full range - value = (value - deadzone) / (1.0f - deadzone); - } - - // Apply sensitivity scaling and clamp. - value = fmax(fmin(value * sensitivity, 1.0f), 0.0f); - - value = copysign(value, o_val); - - // Invert as necessary. - return direction == POSITIVE ? value : 0.0f - value; -} - -bool JoyAxisBinding::Matches(const SDL_Event *event) const -{ - if (event->type != SDL_JOYAXISMOTION) return false; - return event->jaxis.which == joystick && event->jaxis.axis == axis; -} - -std::string JoyAxisBinding::Description() const { - if (!Enabled()) return std::string(); - - const char *axis_names[] = {Lang::X, Lang::Y, Lang::Z}; - std::ostringstream ossaxisnum; - ossaxisnum << int(axis); - - return stringf(Lang::JOY_AXIS, - formatarg("sign", direction == KeyBindings::NEGATIVE ? "-" : ""), // no + sign if positive - formatarg("signp", direction == KeyBindings::NEGATIVE ? "-" : "+"), // optional with + sign - formatarg("joynum", joystick), - formatarg("joyname", Pi::input.JoystickName(joystick)), - formatarg("axis", axis >= 0 && axis < 3 ? axis_names[axis] : ossaxisnum.str()) - ); -} - -bool JoyAxisBinding::FromString(const char *str, JoyAxisBinding &ab) { - if (strcmp(str, "disabled") == 0) { - ab.Clear(); return true; } - const char *p = str; - - if (p[0] == '-') { - ab.direction = NEGATIVE; - p++; + JoyAxisBinding JoyAxisBinding::FromString(const char *str) + { + JoyAxisBinding ab; + if (!JoyAxisBinding::FromString(str, ab)) + ab.Clear(); + return ab; } - else - ab.direction = POSITIVE; - if (strncmp(p, "Joy", 3) != 0) - return false; - p += 3; + std::string JoyAxisBinding::ToString() const + { + std::ostringstream oss; + if (Enabled()) { + if (direction == NEGATIVE) + oss << '-'; - const int JoyUUIDLength = 33; - char joyUUIDBuf[JoyUUIDLength]; - - // read the UUID - if (!ReadToTok('/', &p, joyUUIDBuf, JoyUUIDLength)) { - return false; + oss << "Joy"; + oss << Pi::input.JoystickGUIDString(joystick); + oss << "/Axis"; + oss << int(axis); + oss << "/DZ" << deadzone; + oss << "/E" << sensitivity; + } else { + oss << "disabled"; + } + return oss.str(); } - // force terminate - joyUUIDBuf[JoyUUIDLength-1] = '\0'; - // now, map the GUID to a joystick number - const int joystick = Pi::input.JoystickFromGUIDString(joyUUIDBuf); - if (joystick == -1) { - return false; + + void AxisBinding::SetFromString(const std::string str) + { + size_t ofs = 0; + size_t nextpos = str.find(','); + if (nextpos == std::string::npos) return; + + if (str.substr(ofs, 8) != "disabled") + axis = JoyAxisBinding::FromString(str.substr(0, nextpos).c_str()); + + ofs = nextpos + 1; + nextpos = str.find(',', ofs); + if (str.substr(ofs, 8) != "disabled") + positive = KeyBinding::FromString(str.substr(ofs, nextpos - ofs).c_str()); + + ofs = nextpos + 1; + if (str.substr(ofs, 8) != "disabled") + negative = KeyBinding::FromString(str.substr(ofs).c_str()); } - // found a joystick - assert(joystick < 256); - ab.joystick = Uint8(joystick); - if (strncmp(p, "Axis", 4) != 0) - return false; - - p += 4; - ab.axis = atoi(p); - - // Skip past the axis integer - if (!(p = strstr(p, "/DZ"))) - return true; // deadzone is optional - - p += 3; - ab.deadzone = atof(p); - - // Skip past the deadzone float - if (!(p = strstr(p, "/E"))) - return true; // sensitivity is optional - - p += 2; - ab.sensitivity = atof(p); - - return true; -} - -JoyAxisBinding JoyAxisBinding::FromString(const char *str) { - JoyAxisBinding ab; - if (!JoyAxisBinding::FromString(str, ab)) - ab.Clear(); - return ab; -} - -std::string JoyAxisBinding::ToString() const { - std::ostringstream oss; - if (Enabled()) { - if (direction == NEGATIVE) - oss << '-'; - - oss << "Joy"; - oss << Pi::input.JoystickGUIDString(joystick); - oss << "/Axis"; - oss << int(axis); - oss << "/DZ" << deadzone; - oss << "/E" << sensitivity; - } else { - oss << "disabled"; + std::string AxisBinding::ToString() const + { + std::ostringstream oss; + oss << axis.ToString() << ','; + oss << positive.ToString() << ','; + oss << negative.ToString(); + return oss.str(); } - return oss.str(); -} -void AxisBinding::SetFromString(const std::string str) -{ - size_t ofs = 0; - size_t nextpos = str.find(','); - if (nextpos == std::string::npos) return; + bool AxisBinding::IsActive() const + { + return axis.IsActive() || positive.IsActive() || negative.IsActive(); + } - if (str.substr(ofs, 8) != "disabled") - axis = JoyAxisBinding::FromString(str.substr(0, nextpos).c_str()); + float AxisBinding::GetValue() const + { + // Holding the positive and negative keys cancel each other out, + float value = 0.0f; + value += positive.IsActive() ? 1.0 : 0.0; + value -= negative.IsActive() ? 1.0 : 0.0; - ofs = nextpos + 1; - nextpos = str.find(',', ofs); - if (str.substr(ofs, 8) != "disabled") - positive = KeyBinding::FromString(str.substr(ofs, nextpos - ofs).c_str()); + // And input on the axis device supercedes both of them. + return axis.IsActive() ? axis.GetValue() : value; + } - ofs = nextpos + 1; - if (str.substr(ofs, 8) != "disabled") - negative = KeyBinding::FromString(str.substr(ofs).c_str()); -} - -std::string AxisBinding::ToString() const -{ - std::ostringstream oss; - oss << axis.ToString() << ','; - oss << positive.ToString() << ','; - oss << negative.ToString(); - return oss.str(); -} - -bool AxisBinding::IsActive() const -{ - return axis.IsActive() || positive.IsActive() || negative.IsActive(); -} - -float AxisBinding::GetValue() const -{ - // Holding the positive and negative keys cancel each other out, - float value = 0.0f; - value += positive.IsActive() ? 1.0 : 0.0; - value -= negative.IsActive() ? 1.0 : 0.0; - - // And input on the axis device supercedes both of them. - return axis.IsActive() ? axis.GetValue() : value; -} - -void AxisBinding::CheckSDLEventAndDispatch(const SDL_Event *event) -{ - if (m_disableBindings) return; - float value = GetValue(); - switch (event->type) { + void AxisBinding::CheckSDLEventAndDispatch(const SDL_Event *event) + { + if (m_disableBindings) return; + float value = GetValue(); + switch (event->type) { case SDL_KEYDOWN: - case SDL_KEYUP: - { + case SDL_KEYUP: { if (positive.Matches(&event->key.keysym) && negative.Matches(&event->key.keysym)) { onAxis.emit(value); } break; } case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - { + case SDL_JOYBUTTONUP: { if (positive.Matches(&event->jbutton) || negative.Matches(&event->jbutton)) { onAxis.emit(value); } break; } - case SDL_JOYHATMOTION: - { + case SDL_JOYHATMOTION: { if (positive.Matches(&event->jhat) || positive.Matches(&event->jhat)) { onAxis.emit(value); // XXX to emit onRelease, we need to have access to the state of the joystick hat prior to this event, @@ -581,16 +612,16 @@ void AxisBinding::CheckSDLEventAndDispatch(const SDL_Event *event) } break; } - case SDL_JOYAXISMOTION: - { + case SDL_JOYAXISMOTION: { if (axis.Matches(event)) onAxis.emit(value); } default: break; + } } -} -void DispatchSDLEvent(const SDL_Event *event) { - switch (event->type) { + void DispatchSDLEvent(const SDL_Event *event) + { + switch (event->type) { case SDL_KEYDOWN: case SDL_KEYUP: case SDL_JOYBUTTONDOWN: @@ -598,67 +629,69 @@ void DispatchSDLEvent(const SDL_Event *event) { case SDL_JOYHATMOTION: break; default: return; - } - - // simplest possible approach here: just check each binding and dispatch if it matches - for (ActionBinding * const *binding = s_KeyBindings; *binding; ++binding) { - (*binding)->CheckSDLEventAndDispatch(event); - } -} - -void InitKeyBinding(ActionBinding &kb, const std::string &bindName, Uint32 defaultKey1, Uint32 defaultKey2) { - std::string keyName = Pi::config->String(bindName.c_str()); - if (keyName.length() == 0) { - if (defaultKey1 && defaultKey2) { - keyName = stringf("Key%0{u},Key%1{u}", defaultKey1, defaultKey2); - } else if (defaultKey1 || defaultKey2) { - Uint32 k = (defaultKey1 | defaultKey2); // only one of them is non-zero, so this gets the non-zero value - keyName = stringf("Key%0{u}", k); } - Pi::config->SetString(bindName.c_str(), keyName.c_str()); + + // simplest possible approach here: just check each binding and dispatch if it matches + for (ActionBinding *const *binding = s_KeyBindings; *binding; ++binding) { + (*binding)->CheckSDLEventAndDispatch(event); + } } - // set the binding from the configured or default value - kb.SetFromString(keyName.c_str()); -} + void InitKeyBinding(ActionBinding &kb, const std::string &bindName, Uint32 defaultKey1, Uint32 defaultKey2) + { + std::string keyName = Pi::config->String(bindName.c_str()); + if (keyName.length() == 0) { + if (defaultKey1 && defaultKey2) { + keyName = stringf("Key%0{u},Key%1{u}", defaultKey1, defaultKey2); + } else if (defaultKey1 || defaultKey2) { + Uint32 k = (defaultKey1 | defaultKey2); // only one of them is non-zero, so this gets the non-zero value + keyName = stringf("Key%0{u}", k); + } + Pi::config->SetString(bindName.c_str(), keyName.c_str()); + } -void InitAxisBinding(JoyAxisBinding &ab, const std::string &bindName, const std::string &defaultAxis) { - std::string axisName = Pi::config->String(bindName.c_str()); - if (axisName.length() == 0) { - axisName = defaultAxis; - Pi::config->SetString(bindName.c_str(), axisName.c_str()); + // set the binding from the configured or default value + kb.SetFromString(keyName.c_str()); } - // set the binding from the configured or default value - if (!JoyAxisBinding::FromString(axisName.c_str(), ab)) { - Output("invalid axis binding '%s' in config file for %s\n", axisName.c_str(), bindName.c_str()); - ab.Clear(); - } -} + void InitAxisBinding(JoyAxisBinding &ab, const std::string &bindName, const std::string &defaultAxis) + { + std::string axisName = Pi::config->String(bindName.c_str()); + if (axisName.length() == 0) { + axisName = defaultAxis; + Pi::config->SetString(bindName.c_str(), axisName.c_str()); + } -void UpdateBindings() -{ + // set the binding from the configured or default value + if (!JoyAxisBinding::FromString(axisName.c_str(), ab)) { + Output("invalid axis binding '%s' in config file for %s\n", axisName.c_str(), bindName.c_str()); + ab.Clear(); + } + } + + void UpdateBindings() + { #define KEY_BINDING(name, config_name, b, default_value_1, default_value_2) \ InitKeyBinding(KeyBindings::name, config_name, default_value_1, default_value_2); #define AXIS_BINDING(name, config_name, b, default_value) \ InitAxisBinding(KeyBindings::name, config_name, default_value); #include "KeyBindings.inc.h" -} + } -void InitBindings() -{ - UpdateBindings(); - Pi::config->Save(); -} + void InitBindings() + { + UpdateBindings(); + Pi::config->Save(); + } -void EnableBindings() -{ - m_disableBindings = 0; -} + void EnableBindings() + { + m_disableBindings = 0; + } -void DisableBindings() -{ - m_disableBindings = 1; -} + void DisableBindings() + { + m_disableBindings = 1; + } -} +} // namespace KeyBindings diff --git a/src/KeyBindings.h b/src/KeyBindings.h index 340b8aa26..27f9e20dc 100644 --- a/src/KeyBindings.h +++ b/src/KeyBindings.h @@ -17,64 +17,68 @@ namespace KeyBindings { }; struct KeyBinding { - public: - // constructors - static bool FromString(const char *str, KeyBinding &binding); - static KeyBinding FromString(const char *str); - static KeyBinding FromKeyMod(SDL_Keycode key, SDL_Keymod mod); - static KeyBinding FromJoystickButton(Uint8 joystick, Uint8 button); - static KeyBinding FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction); + public: + // constructors + static bool FromString(const char *str, KeyBinding &binding); + static KeyBinding FromString(const char *str); + static KeyBinding FromKeyMod(SDL_Keycode key, SDL_Keymod mod); + static KeyBinding FromJoystickButton(Uint8 joystick, Uint8 button); + static KeyBinding FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction); - KeyBinding() : type(BINDING_DISABLED) { - u.keyboard.key = SDLK_UNKNOWN; - u.keyboard.mod = KMOD_NONE; - } - KeyBinding(SDL_Keycode key, SDL_Keymod mod = KMOD_NONE) : type(KEYBOARD_KEY) { - u.keyboard.key = key; - u.keyboard.mod = mod; - } + KeyBinding() : + type(BINDING_DISABLED) + { + u.keyboard.key = SDLK_UNKNOWN; + u.keyboard.mod = KMOD_NONE; + } + KeyBinding(SDL_Keycode key, SDL_Keymod mod = KMOD_NONE) : + type(KEYBOARD_KEY) + { + u.keyboard.key = key; + u.keyboard.mod = mod; + } - std::string ToString() const; // for serialisation - std::string Description() const; // for display to the user + std::string ToString() const; // for serialisation + std::string Description() const; // for display to the user - bool IsActive() const; - bool Matches(const SDL_Keysym *sym) const; - bool Matches(const SDL_JoyButtonEvent *joy) const; - bool Matches(const SDL_JoyHatEvent *joy) const; + bool IsActive() const; + bool Matches(const SDL_Keysym *sym) const; + bool Matches(const SDL_JoyButtonEvent *joy) const; + bool Matches(const SDL_JoyHatEvent *joy) const; - void Clear() { memset(this, 0, sizeof(*this)); } + void Clear() { memset(this, 0, sizeof(*this)); } - bool Enabled() const { return (type != BINDING_DISABLED); } + bool Enabled() const { return (type != BINDING_DISABLED); } - friend std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb); + friend std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb); - private: - Type type; - union { - struct { - SDL_Keycode key; - SDL_Keymod mod; - } keyboard; + private: + Type type; + union { + struct { + SDL_Keycode key; + SDL_Keymod mod; + } keyboard; - struct { - Uint8 joystick; - Uint8 button; - } joystickButton; + struct { + Uint8 joystick; + Uint8 button; + } joystickButton; - struct { - Uint8 joystick; - Uint8 hat; - Uint8 direction; - } joystickHat; + struct { + Uint8 joystick; + Uint8 hat; + Uint8 direction; + } joystickHat; - /* TODO: implement binding mouse buttons. + /* TODO: implement binding mouse buttons. struct { Uint8 button; // TODO: implement binding multiple clicks as their own action. Uint8 clicks; } mouseButton; */ - } u; + } u; }; struct ActionBinding { @@ -84,14 +88,15 @@ namespace KeyBindings { sigc::signal onPress; sigc::signal onRelease; - ActionBinding() { } - ActionBinding(KeyBinding b1, KeyBinding b2 = KeyBinding()) - : binding1(b1), binding2(b2) { } + ActionBinding() {} + ActionBinding(KeyBinding b1, KeyBinding b2 = KeyBinding()) : + binding1(b1), + binding2(b2) {} // This constructor is just a programmer shortcut. ActionBinding(SDL_Keycode k1, SDL_Keycode k2 = SDLK_UNKNOWN) { binding1 = KeyBinding(k1); - if(k2 != SDLK_UNKNOWN) binding2 = KeyBinding(k2); + if (k2 != SDLK_UNKNOWN) binding2 = KeyBinding(k2); } void SetFromString(const char *str); @@ -110,47 +115,58 @@ namespace KeyBindings { }; struct JoyAxisBinding { - public: - JoyAxisBinding() : joystick(JOYSTICK_DISABLED), axis(0), direction(POSITIVE), deadzone(0.0f), sensitivity(1.0f) { } - JoyAxisBinding(Uint8 joystick_, Uint8 axis_, AxisDirection direction_, float deadzone_ = 0.0f, float sensitivity_ = 1.0f) - : joystick(joystick_), axis(axis_), direction(direction_), deadzone(deadzone_), sensitivity(sensitivity_) { } + public: + JoyAxisBinding() : + joystick(JOYSTICK_DISABLED), + axis(0), + direction(POSITIVE), + deadzone(0.0f), + sensitivity(1.0f) {} + JoyAxisBinding(Uint8 joystick_, Uint8 axis_, AxisDirection direction_, float deadzone_ = 0.0f, float sensitivity_ = 1.0f) : + joystick(joystick_), + axis(axis_), + direction(direction_), + deadzone(deadzone_), + sensitivity(sensitivity_) {} - float GetValue() const; - std::string Description() const; + float GetValue() const; + std::string Description() const; - void Clear() { - joystick = JOYSTICK_DISABLED; - axis = 0; - direction = POSITIVE; - deadzone = 0.0f; - sensitivity = 1.0f; - } + void Clear() + { + joystick = JOYSTICK_DISABLED; + axis = 0; + direction = POSITIVE; + deadzone = 0.0f; + sensitivity = 1.0f; + } - bool Enabled() const { return (joystick != JOYSTICK_DISABLED); } + bool Enabled() const { return (joystick != JOYSTICK_DISABLED); } - static bool FromString(const char *str, JoyAxisBinding &binding); - static JoyAxisBinding FromString(const char *str); - std::string ToString() const; + static bool FromString(const char *str, JoyAxisBinding &binding); + static JoyAxisBinding FromString(const char *str); + std::string ToString() const; - bool Matches(const SDL_Event *event) const; - bool IsActive() const; + bool Matches(const SDL_Event *event) const; + bool IsActive() const; - bool IsInverted() { return direction == NEGATIVE; } - AxisDirection GetDirection() { return direction; } - void SetDirection(AxisDirection dir) { direction = dir; } + bool IsInverted() { return direction == NEGATIVE; } + AxisDirection GetDirection() { return direction; } + void SetDirection(AxisDirection dir) { direction = dir; } - float GetDeadzone() { return deadzone; } - void SetDeadzone(float dz) { deadzone = dz; } + float GetDeadzone() { return deadzone; } + void SetDeadzone(float dz) { deadzone = dz; } - float GetSensitivity() { return sensitivity; } - void SetSensitivity(float sens) { sensitivity = sens; } - private: - enum { JOYSTICK_DISABLED = Uint8(-1) }; - Uint8 joystick; - Uint8 axis; - AxisDirection direction; - float deadzone; - float sensitivity; + float GetSensitivity() { return sensitivity; } + void SetSensitivity(float sens) { sensitivity = sens; } + + private: + enum { JOYSTICK_DISABLED = Uint8(-1) }; + Uint8 joystick; + Uint8 axis; + AxisDirection direction; + float deadzone; + float sensitivity; }; struct AxisBinding { @@ -158,12 +174,15 @@ namespace KeyBindings { KeyBinding positive; KeyBinding negative; - AxisBinding() { } - AxisBinding(JoyAxisBinding ax, KeyBinding pos = KeyBinding(), KeyBinding neg = KeyBinding()) - : axis(ax), positive(pos), negative(neg) { } + AxisBinding() {} + AxisBinding(JoyAxisBinding ax, KeyBinding pos = KeyBinding(), KeyBinding neg = KeyBinding()) : + axis(ax), + positive(pos), + negative(neg) {} // This constructor is just a programmer shortcut. - AxisBinding(SDL_Keycode k1, SDL_Keycode k2) - : positive(KeyBinding(k1)), negative(KeyBinding(k2)) { } + AxisBinding(SDL_Keycode k1, SDL_Keycode k2) : + positive(KeyBinding(k1)), + negative(KeyBinding(k2)) {} sigc::signal onAxis; @@ -189,11 +208,11 @@ namespace KeyBindings { void DispatchSDLEvent(const SDL_Event *event); -#define KEY_BINDING(name,a,b,c,d) extern ActionBinding name; -#define AXIS_BINDING(name,a,b,c) extern JoyAxisBinding name; +#define KEY_BINDING(name, a, b, c, d) extern ActionBinding name; +#define AXIS_BINDING(name, a, b, c) extern JoyAxisBinding name; #include "KeyBindings.inc.h" -#define BINDING_PAGE(name) extern const BindingPrototype BINDING_PROTOS_ ## name[]; +#define BINDING_PAGE(name) extern const BindingPrototype BINDING_PROTOS_##name[]; #include "KeyBindings.inc.h" } // namespace KeyBindings diff --git a/src/Lang.cpp b/src/Lang.cpp index 601e2f9f1..0f2a17d75 100644 --- a/src/Lang.cpp +++ b/src/Lang.cpp @@ -1,231 +1,231 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Lang.h" #include "FileSystem.h" -#include "StringRange.h" -#include "utils.h" -#include "text/TextSupport.h" #include "JsonUtils.h" +#include "StringRange.h" +#include "libs.h" +#include "text/TextSupport.h" +#include "utils.h" #include #include namespace Lang { -static bool ident_head(char c) -{ - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'); -} + static bool ident_head(char c) + { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'); + } -static bool ident_tail(char c) -{ - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_'); -} + static bool ident_tail(char c) + { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_'); + } -static bool valid_token(const std::string &token) -{ - if (token.empty()) return false; - if (!ident_head(token[0])) return false; - for (unsigned int i = 1; i < token.size(); i++) - if (!ident_tail(token[i])) return false; - return true; -} - -bool Resource::Load() -{ - if (m_loaded) + static bool valid_token(const std::string &token) + { + if (token.empty()) return false; + if (!ident_head(token[0])) return false; + for (unsigned int i = 1; i < token.size(); i++) + if (!ident_tail(token[i])) return false; return true; - - std::string filename = "lang/" + m_name + "/" + m_langCode + ".json"; - Json data = JsonUtils::LoadJsonDataFile(filename); - if (data.is_null()) { - Output("couldn't read language file '%s'\n", filename.c_str()); - return false; } - for (Json::iterator i = data.begin(); i != data.end(); ++i) { - const std::string token = i.key(); - if (token.empty()) { - Output("%s: found empty token, skipping it\n", filename.c_str()); - continue; - } - if (!valid_token(token)) { - Output("%s: invalid token '%s', skipping it\n", filename.c_str(), token.c_str()); - continue; + bool Resource::Load() + { + if (m_loaded) + return true; + + std::string filename = "lang/" + m_name + "/" + m_langCode + ".json"; + Json data = JsonUtils::LoadJsonDataFile(filename); + if (data.is_null()) { + Output("couldn't read language file '%s'\n", filename.c_str()); + return false; } - Json message = i.value()["message"]; - if (message.is_null()) { - Output("%s: no 'message' key for token '%s', skipping it\n", filename.c_str(), token.c_str()); - continue; - } - - if (!message.is_string()) { - Output("%s: value for token '%s' is not a string, skipping it\n", filename.c_str(), token.c_str()); - continue; - } - - std::string text = message; - if (text.empty()) { - Output("%s: empty value for token '%s', skipping it\n", filename.c_str(), token.c_str()); - continue; - } - - // extracted quoted string - if (text[0] == '"' && text[text.size()-1] == '"') - text = text.substr(1, text.size()-2); - - // adjust for escaped newlines - { - std::string adjustedText; - adjustedText.reserve(text.size()); - - unsigned int ii; - for (ii = 0; ii < text.size()-1; ii++) { - const char *c = &text[ii]; - if (c[0] == '\\' && c[1] == 'n') { - ii++; - adjustedText += '\n'; - } - else - adjustedText += *c; + for (Json::iterator i = data.begin(); i != data.end(); ++i) { + const std::string token = i.key(); + if (token.empty()) { + Output("%s: found empty token, skipping it\n", filename.c_str()); + continue; } - if (ii != text.size()) - adjustedText += text[ii++]; - assert(ii == text.size()); - text = adjustedText; + if (!valid_token(token)) { + Output("%s: invalid token '%s', skipping it\n", filename.c_str(), token.c_str()); + continue; + } + + Json message = i.value()["message"]; + if (message.is_null()) { + Output("%s: no 'message' key for token '%s', skipping it\n", filename.c_str(), token.c_str()); + continue; + } + + if (!message.is_string()) { + Output("%s: value for token '%s' is not a string, skipping it\n", filename.c_str(), token.c_str()); + continue; + } + + std::string text = message; + if (text.empty()) { + Output("%s: empty value for token '%s', skipping it\n", filename.c_str(), token.c_str()); + continue; + } + + // extracted quoted string + if (text[0] == '"' && text[text.size() - 1] == '"') + text = text.substr(1, text.size() - 2); + + // adjust for escaped newlines + { + std::string adjustedText; + adjustedText.reserve(text.size()); + + unsigned int ii; + for (ii = 0; ii < text.size() - 1; ii++) { + const char *c = &text[ii]; + if (c[0] == '\\' && c[1] == 'n') { + ii++; + adjustedText += '\n'; + } else + adjustedText += *c; + } + if (ii != text.size()) + adjustedText += text[ii++]; + assert(ii == text.size()); + text = adjustedText; + } + + m_strings[token] = text; } - m_strings[token] = text; + m_loaded = true; + return true; } - m_loaded = true; - return true; -} - -const std::string &Resource::Get(const std::string &token) const -{ - std::map::const_iterator i = m_strings.find(token); - if (i == m_strings.end()) { - static const std::string empty; - return empty; - } - return (*i).second; -} - -std::vector Resource::GetAvailableLanguages(const std::string &resourceName) -{ - std::vector languages; - - for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "lang/" + resourceName); !files.Finished(); files.Next()) { - assert(files.Current().IsFile()); - const std::string &path = files.Current().GetPath(); - if (ends_with_ci(path, ".json")) { - const std::string name = files.Current().GetName(); - languages.push_back(name.substr(0, name.size() - 5)); + const std::string &Resource::Get(const std::string &token) const + { + std::map::const_iterator i = m_strings.find(token); + if (i == m_strings.end()) { + static const std::string empty; + return empty; } + return (*i).second; } - return languages; -} + std::vector Resource::GetAvailableLanguages(const std::string &resourceName) + { + std::vector languages; + for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "lang/" + resourceName); !files.Finished(); files.Next()) { + assert(files.Current().IsFile()); + const std::string &path = files.Current().GetPath(); + if (ends_with_ci(path, ".json")) { + const std::string name = files.Current().GetName(); + languages.push_back(name.substr(0, name.size() - 5)); + } + } -// XXX we're allocating a KB for each translatable string -// that's... not very nice (though I guess it "doesn't matter" with virtual memory and multi-GB of RAM) -static const int STRING_RECORD_SIZE = 1024; + return languages; + } + + // XXX we're allocating a KB for each translatable string + // that's... not very nice (though I guess it "doesn't matter" with virtual memory and multi-GB of RAM) + static const int STRING_RECORD_SIZE = 1024; #define DECLARE_STRING(x) char x[STRING_RECORD_SIZE]; #include "LangStrings.inc.h" #undef DECLARE_STRING -// -// declaring value type as const char* so that we can give out a const reference to the real -// token map without allowing external code to modify token text -// unfortunately, this means we don't have write access internally either, -// so we have to const_cast<> to initialise the token values. -// this could be avoided by using a custom class for the value type -// (or std::string, but then we'd be changing the way translated text is stored) -typedef std::map token_map; -static token_map s_token_map; + // + // declaring value type as const char* so that we can give out a const reference to the real + // token map without allowing external code to modify token text + // unfortunately, this means we don't have write access internally either, + // so we have to const_cast<> to initialise the token values. + // this could be avoided by using a custom class for the value type + // (or std::string, but then we'd be changing the way translated text is stored) + typedef std::map token_map; + static token_map s_token_map; -static struct init_string_helper_class { - init_string_helper_class() { -#define DECLARE_STRING(x) s_token_map.insert(std::make_pair(#x, Lang::x)); Lang::x[0] = '\0'; + static struct init_string_helper_class { + init_string_helper_class() + { +#define DECLARE_STRING(x) \ + s_token_map.insert(std::make_pair(#x, Lang::x)); \ + Lang::x[0] = '\0'; #include "LangStrings.inc.h" #undef DECLARE_STRING - } -} init_string_helper; - - -static void copy_string(char *buf, const char *str, size_t strsize, size_t bufsize) -{ - size_t sz = std::min(strsize, bufsize-1); - memcpy(buf, str, sz); - buf[sz] = '\0'; -} - -static Resource s_coreResource("core", ""); - -void MakeCore(Resource &res) -{ - assert(res.GetName() == "core"); - - res.Load(); - - for (token_map::iterator i = s_token_map.begin(); i != s_token_map.end(); ++i) { - const std::string &token = i->first; - std::string text = res.Get(token); - - if (text.empty()) { - Output("%s/%s: token '%s' not found\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str()); - text = token; } + } init_string_helper; - if (text.size() > size_t(STRING_RECORD_SIZE)) { - Output("%s/%s: text for token '%s' is too long and will be truncated\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str()); - text.resize(STRING_RECORD_SIZE); - } - - // const_cast so we can set the string, see above - char *record = const_cast(i->second); - copy_string(record, text.c_str(), text.size(), STRING_RECORD_SIZE); + static void copy_string(char *buf, const char *str, size_t strsize, size_t bufsize) + { + size_t sz = std::min(strsize, bufsize - 1); + memcpy(buf, str, sz); + buf[sz] = '\0'; } - s_coreResource = res; -} + static Resource s_coreResource("core", ""); -const Resource &GetCore() -{ - return s_coreResource; -} + void MakeCore(Resource &res) + { + assert(res.GetName() == "core"); -static std::map m_cachedResources; + res.Load(); -Resource GetResource(const std::string &name, const std::string &langCode) -{ - auto key = name + ":" + langCode; + for (token_map::iterator i = s_token_map.begin(); i != s_token_map.end(); ++i) { + const std::string &token = i->first; + std::string text = res.Get(token); - auto i = m_cachedResources.find(key); - if (i != m_cachedResources.end()) - return i->second; + if (text.empty()) { + Output("%s/%s: token '%s' not found\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str()); + text = token; + } - Lang::Resource res = Lang::Resource(name, langCode); - bool loaded = res.Load(); - if (!loaded) { - if (langCode != "en") { - Output("couldn't load language resource %s/%s, trying %s/en\n", name.c_str(), langCode.c_str(), name.c_str()); - res = Lang::Resource(name, "en"); - loaded = res.Load(); - key = name + ":" + "en"; + if (text.size() > size_t(STRING_RECORD_SIZE)) { + Output("%s/%s: text for token '%s' is too long and will be truncated\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str()); + text.resize(STRING_RECORD_SIZE); + } + + // const_cast so we can set the string, see above + char *record = const_cast(i->second); + copy_string(record, text.c_str(), text.size(), STRING_RECORD_SIZE); } - if (!loaded) - Output("couldn't load language resource %s/en\n", name.c_str()); + + s_coreResource = res; } - if (loaded) - m_cachedResources.insert(std::make_pair(key, res)); + const Resource &GetCore() + { + return s_coreResource; + } - return res; -} + static std::map m_cachedResources; + + Resource GetResource(const std::string &name, const std::string &langCode) + { + auto key = name + ":" + langCode; + + auto i = m_cachedResources.find(key); + if (i != m_cachedResources.end()) + return i->second; + + Lang::Resource res = Lang::Resource(name, langCode); + bool loaded = res.Load(); + if (!loaded) { + if (langCode != "en") { + Output("couldn't load language resource %s/%s, trying %s/en\n", name.c_str(), langCode.c_str(), name.c_str()); + res = Lang::Resource(name, "en"); + loaded = res.Load(); + key = name + ":" + "en"; + } + if (!loaded) + Output("couldn't load language resource %s/en\n", name.c_str()); + } + + if (loaded) + m_cachedResources.insert(std::make_pair(key, res)); + + return res; + } } // namespace Lang diff --git a/src/Lang.h b/src/Lang.h index 94275c184..0c9620371 100644 --- a/src/Lang.h +++ b/src/Lang.h @@ -4,52 +4,54 @@ #ifndef _LANG_H #define _LANG_H -#include -#include -#include -#include #include "IterationProxy.h" +#include +#include +#include +#include namespace Lang { -class Resource { -public: - Resource(const std::string &name, const std::string &langCode) : - m_name(name), m_langCode(langCode), m_loaded(false) {} + class Resource { + public: + Resource(const std::string &name, const std::string &langCode) : + m_name(name), + m_langCode(langCode), + m_loaded(false) {} - const std::string &GetName() const { return m_name; } - const std::string &GetLangCode() const { return m_langCode; } + const std::string &GetName() const { return m_name; } + const std::string &GetLangCode() const { return m_langCode; } - bool Load(); + bool Load(); - Uint32 GetNumStrings() const { return static_cast(m_strings.size()); } + Uint32 GetNumStrings() const { return static_cast(m_strings.size()); } - const std::string &Get(const std::string &token) const; + const std::string &Get(const std::string &token) const; - static std::vector GetAvailableLanguages(const std::string &resourceName); + static std::vector GetAvailableLanguages(const std::string &resourceName); - IterationProxy > GetStrings() { return MakeIterationProxy(m_strings); } - const IterationProxy > GetStrings() const { return MakeIterationProxy(m_strings); } + IterationProxy> GetStrings() { return MakeIterationProxy(m_strings); } + const IterationProxy> GetStrings() const { return MakeIterationProxy(m_strings); } -private: - std::string m_name; - std::string m_langCode; + private: + std::string m_name; + std::string m_langCode; - bool m_loaded; + bool m_loaded; - std::map m_strings; -}; + std::map m_strings; + }; // declare all strings #define DECLARE_STRING(x) extern char x[]; #include "LangStrings.inc.h" #undef DECLARE_STRING -void MakeCore(Resource &res); -const Resource &GetCore(); + void MakeCore(Resource &res); + const Resource &GetCore(); -Resource GetResource(const std::string &name, const std::string &langCode); + Resource GetResource(const std::string &name, const std::string &langCode); -} +} // namespace Lang #endif diff --git a/src/Lua.cpp b/src/Lua.cpp index fd8bb5415..84a18ff22 100644 --- a/src/Lua.cpp +++ b/src/Lua.cpp @@ -5,17 +5,17 @@ namespace Lua { -LuaManager *manager = 0; + LuaManager *manager = 0; -void Init() -{ - manager = new LuaManager(); -} + void Init() + { + manager = new LuaManager(); + } -void Uninit() -{ - delete manager; - manager = 0; -} + void Uninit() + { + delete manager; + manager = 0; + } -} +} // namespace Lua diff --git a/src/Lua.h b/src/Lua.h index 11c00f2ba..d51a88d6e 100644 --- a/src/Lua.h +++ b/src/Lua.h @@ -10,11 +10,11 @@ // modelviewer. probably sucks in the long term namespace Lua { -extern LuaManager *manager; + extern LuaManager *manager; -void Init(); -void Uninit(); + void Init(); + void Uninit(); -} +} // namespace Lua #endif diff --git a/src/LuaBody.cpp b/src/LuaBody.cpp index dae5852f1..9fa3969cb 100644 --- a/src/LuaBody.cpp +++ b/src/LuaBody.cpp @@ -1,26 +1,26 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "LuaObject.h" -#include "LuaUtils.h" -#include "LuaConstants.h" -#include "EnumStrings.h" #include "Body.h" -#include "galaxy/StarSystem.h" +#include "EnumStrings.h" #include "Frame.h" -#include "TerrainBody.h" -#include "Pi.h" #include "Game.h" +#include "LuaConstants.h" +#include "LuaObject.h" #include "LuaPiGui.h" +#include "LuaUtils.h" +#include "Pi.h" +#include "TerrainBody.h" +#include "galaxy/StarSystem.h" -#include "ModelBody.h" -#include "Ship.h" -#include "Player.h" -#include "SpaceStation.h" -#include "Planet.h" -#include "Star.h" #include "CargoBody.h" #include "Missile.h" +#include "ModelBody.h" +#include "Planet.h" +#include "Player.h" +#include "Ship.h" +#include "SpaceStation.h" +#include "Star.h" /* * Class: Body @@ -139,89 +139,89 @@ static int l_body_get_velocity_rel_to(lua_State *l) static int l_body_is_moon(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - const SystemBody *sb = body->GetSystemBody(); - if(!sb) { - LuaPush(l, false); - } else { - LuaPush(l, sb->IsMoon()); - } - return 1; + Body *body = LuaObject::CheckFromLua(1); + const SystemBody *sb = body->GetSystemBody(); + if (!sb) { + LuaPush(l, false); + } else { + LuaPush(l, sb->IsMoon()); + } + return 1; } static int l_body_is_missile(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - LuaPush(l, body->GetType() == Object::Type::MISSILE); - return 1; + Body *body = LuaObject::CheckFromLua(1); + LuaPush(l, body->GetType() == Object::Type::MISSILE); + return 1; } static int l_body_is_station(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - LuaPush(l, body->GetType() == Object::Type::SPACESTATION); - return 1; + Body *body = LuaObject::CheckFromLua(1); + LuaPush(l, body->GetType() == Object::Type::SPACESTATION); + return 1; } static int l_body_is_space_station(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - const SystemBody *sb = body->GetSystemBody(); - LuaPush(l, sb ? sb->GetType() == SystemBody::BodyType::TYPE_STARPORT_ORBITAL : false); - return 1; + Body *body = LuaObject::CheckFromLua(1); + const SystemBody *sb = body->GetSystemBody(); + LuaPush(l, sb ? sb->GetType() == SystemBody::BodyType::TYPE_STARPORT_ORBITAL : false); + return 1; } static int l_body_is_ground_station(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - const SystemBody *sb = body->GetSystemBody(); - LuaPush(l, sb ? sb->GetType() == SystemBody::BodyType::TYPE_STARPORT_SURFACE : false); - return 1; + Body *body = LuaObject::CheckFromLua(1); + const SystemBody *sb = body->GetSystemBody(); + LuaPush(l, sb ? sb->GetType() == SystemBody::BodyType::TYPE_STARPORT_SURFACE : false); + return 1; } static int l_body_is_cargo_container(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - LuaPush(l, body->GetType() == Object::Type::CARGOBODY); - return 1; + Body *body = LuaObject::CheckFromLua(1); + LuaPush(l, body->GetType() == Object::Type::CARGOBODY); + return 1; } static int l_body_is_ship(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - LuaPush(l, body->GetType() == Object::Type::SHIP); - return 1; + Body *body = LuaObject::CheckFromLua(1); + LuaPush(l, body->GetType() == Object::Type::SHIP); + return 1; } static int l_body_is_hyperspace_cloud(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - LuaPush(l, body->GetType() == Object::Type::HYPERSPACECLOUD); - return 1; + Body *body = LuaObject::CheckFromLua(1); + LuaPush(l, body->GetType() == Object::Type::HYPERSPACECLOUD); + return 1; } static int l_body_is_planet(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - const SystemBody *sb = body->GetSystemBody(); - if(!sb) { - LuaPush(l, false); - } else { - LuaPush(l, sb->IsPlanet()); - } - return 1; + Body *body = LuaObject::CheckFromLua(1); + const SystemBody *sb = body->GetSystemBody(); + if (!sb) { + LuaPush(l, false); + } else { + LuaPush(l, sb->IsPlanet()); + } + return 1; } static int l_body_get_system_body(lua_State *l) { - Body *body = LuaObject::CheckFromLua(1); - SystemBody *sb = const_cast(body->GetSystemBody()); // TODO: ugly, change this... - if(!sb) { - lua_pushnil(l); - } else { - LuaObject::PushToLua(sb); - } - return 1; + Body *body = LuaObject::CheckFromLua(1); + SystemBody *sb = const_cast(body->GetSystemBody()); // TODO: ugly, change this... + if (!sb) { + lua_pushnil(l); + } else { + LuaObject::PushToLua(sb); + } + return 1; } static int l_body_is_more_important_than(lua_State *l) @@ -234,8 +234,7 @@ static int l_body_is_more_important_than(lua_State *l) // the most important body is shown on the hud and // bodies are sorted by importance in menus - if(body == other) - { + if (body == other) { LuaPush(l, false); return 1; } @@ -257,44 +256,69 @@ static int l_body_is_more_important_than(lua_State *l) // if type is the same, just sort alphabetically // planets are different, because moons are // less important (but don't have their own type) - if(a == b && a != Object::Type::PLANET) result = body->GetLabel() < other->GetLabel(); + if (a == b && a != Object::Type::PLANET) result = body->GetLabel() < other->GetLabel(); // a star is larger than any other object - else if(a == Object::Type::STAR) result = true; + else if (a == Object::Type::STAR) + result = true; // any (non-star) object is smaller than a star - else if(b == Object::Type::STAR) result = false; + else if (b == Object::Type::STAR) + result = false; // a gas giant is larger than anything but a star, // but remember to keep total order in mind: if both are // gas giants, order alphabetically - else if(a_gas_giant) result = !b_gas_giant || body->GetLabel() < other->GetLabel(); + else if (a_gas_giant) + result = !b_gas_giant || body->GetLabel() < other->GetLabel(); // any (non-star, non-gas giant) object is smaller than a gas giant - else if(b_gas_giant) result = false; + else if (b_gas_giant) + result = false; // between two planets or moons, alphabetic - else if(a_planet && b_planet) result = body->GetLabel() < other->GetLabel(); - else if(a_moon && b_moon) result = body->GetLabel() < other->GetLabel(); + else if (a_planet && b_planet) + result = body->GetLabel() < other->GetLabel(); + else if (a_moon && b_moon) + result = body->GetLabel() < other->GetLabel(); // a planet is larger than any non-planet - else if(a_planet) result = true; + else if (a_planet) + result = true; // a non-planet is smaller than any planet - else if(b_planet) result = false; + else if (b_planet) + result = false; // a moon is larger than any non-moon - else if(a_moon) result = true; + else if (a_moon) + result = true; // a non-moon is smaller than any moon - else if(b_moon) result = false; + else if (b_moon) + result = false; // spacestation > city > ship > hyperspace cloud > cargo body > missile > projectile - else if(a == Object::Type::SPACESTATION) result = true; - else if(b == Object::Type::SPACESTATION) result = false; - else if(a == Object::Type::CITYONPLANET) result = true; - else if(b == Object::Type::CITYONPLANET) result = false; - else if(a == Object::Type::SHIP) result = true; - else if(b == Object::Type::SHIP) result = false; - else if(a == Object::Type::HYPERSPACECLOUD) result = true; - else if(b == Object::Type::HYPERSPACECLOUD) result = false; - else if(a == Object::Type::CARGOBODY) result = true; - else if(b == Object::Type::CARGOBODY) result = false; - else if(a == Object::Type::MISSILE) result = true; - else if(b == Object::Type::MISSILE) result = false; - else if(a == Object::Type::PROJECTILE) result = true; - else if(b == Object::Type::PROJECTILE) result = false; - else Error("don't know how to compare %i and %i\n", a, b); + else if (a == Object::Type::SPACESTATION) + result = true; + else if (b == Object::Type::SPACESTATION) + result = false; + else if (a == Object::Type::CITYONPLANET) + result = true; + else if (b == Object::Type::CITYONPLANET) + result = false; + else if (a == Object::Type::SHIP) + result = true; + else if (b == Object::Type::SHIP) + result = false; + else if (a == Object::Type::HYPERSPACECLOUD) + result = true; + else if (b == Object::Type::HYPERSPACECLOUD) + result = false; + else if (a == Object::Type::CARGOBODY) + result = true; + else if (b == Object::Type::CARGOBODY) + result = false; + else if (a == Object::Type::MISSILE) + result = true; + else if (b == Object::Type::MISSILE) + result = false; + else if (a == Object::Type::PROJECTILE) + result = true; + else if (b == Object::Type::PROJECTILE) + result = false; + else + Error("don't know how to compare %i and %i\n", a, b); LuaPush(l, result); return 1; @@ -353,8 +377,8 @@ static int l_body_get_altitude_rel_to(lua_State *l) const Body *other = LuaObject::CheckFromLua(2); vector3d pos = Pi::player->GetPositionRelTo(other); double center_dist = pos.Length(); - if(other && other->IsType(Object::TERRAINBODY)) { - const TerrainBody* terrain = static_cast(other); + if (other && other->IsType(Object::TERRAINBODY)) { + const TerrainBody *terrain = static_cast(other); vector3d surface_pos = pos.Normalized(); double radius = 0.0; if (center_dist <= 3.0 * terrain->GetMaxFeatureRadius()) { @@ -369,7 +393,6 @@ static int l_body_get_altitude_rel_to(lua_State *l) LuaPush(l, center_dist); return 1; } - } /* @@ -604,13 +627,13 @@ static int l_body_get_ground_position(lua_State *l) return 0; vector3d pos = b->GetPosition(); - double latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z)); + double latitude = atan2(pos.y, sqrt(pos.x * pos.x + pos.z * pos.z)); double longitude = atan2(pos.x, pos.z); lua_pushnumber(l, latitude); lua_pushnumber(l, longitude); Body *astro = f->GetBody(); if (astro->IsType(Object::TERRAINBODY)) { - double radius = static_cast(astro)->GetTerrainHeight(pos.Normalized()); + double radius = static_cast(astro)->GetTerrainHeight(pos.Normalized()); double altitude = pos.Length() - radius; lua_pushnumber(l, altitude); } else { @@ -707,14 +730,15 @@ static int l_body_get_projected_screen_position(lua_State *l) return pushOnScreenPositionDirection(l, p); } -static int l_body_get_atmospheric_state(lua_State *l) { +static int l_body_get_atmospheric_state(lua_State *l) +{ Body *b = LuaObject::CheckFromLua(1); // const SystemBody *sb = b->GetSystemBody(); vector3d pos = Pi::player->GetPosition(); double center_dist = pos.Length(); if (b->IsType(Object::PLANET)) { double pressure, density; - static_cast(b)->GetAtmosphericState(center_dist, &pressure, &density); + static_cast(b)->GetAtmosphericState(center_dist, &pressure, &density); lua_pushnumber(l, pressure); lua_pushnumber(l, density); return 2; @@ -738,38 +762,39 @@ static int l_body_get_target_indicator_screen_position(lua_State *l) return pushOnScreenPositionDirection(l, p); } -static bool push_body_to_lua(Body *body) { +static bool push_body_to_lua(Body *body) +{ assert(body); switch (body->GetType()) { case Object::BODY: LuaObject::PushToLua(body); break; case Object::MODELBODY: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::SHIP: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::PLAYER: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::SPACESTATION: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::PLANET: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::STAR: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::CARGOBODY: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::MISSILE: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; case Object::HYPERSPACECLOUD: - LuaObject::PushToLua(dynamic_cast(body)); + LuaObject::PushToLua(dynamic_cast(body)); break; default: return false; @@ -780,14 +805,14 @@ static bool push_body_to_lua(Body *body) { static std::string _body_serializer(LuaWrappable *o) { static char buf[256]; - Body *b = static_cast(o); + Body *b = static_cast(o); snprintf(buf, sizeof(buf), "%u\n", Pi::game->GetSpace()->GetIndexForBody(b)); return std::string(buf); } static bool _body_deserializer(const char *pos, const char **next) { - Uint32 n = strtoul(pos, const_cast(next), 0); + Uint32 n = strtoul(pos, const_cast(next), 0); if (pos == *next) return false; (*next)++; // skip newline @@ -797,7 +822,7 @@ static bool _body_deserializer(const char *pos, const char **next) static void _body_to_json(Json &out, LuaWrappable *o) { - Body *b = static_cast(o); + Body *b = static_cast(o); out = Json(Pi::game->GetSpace()->GetIndexForBody(b)); } @@ -808,45 +833,47 @@ static bool _body_from_json(const Json &obj) return push_body_to_lua(body); } -template <> const char *LuaObject::s_type = "Body"; +template <> +const char *LuaObject::s_type = "Body"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { const char *l_parent = "PropertiedObject"; static luaL_Reg l_methods[] = { - { "IsDynamic", l_body_is_dynamic }, + { "IsDynamic", l_body_is_dynamic }, { "DistanceTo", l_body_distance_to }, { "GetGroundPosition", l_body_get_ground_position }, { "FindNearestTo", l_body_find_nearest_to }, - { "GetVelocityRelTo", l_body_get_velocity_rel_to }, - { "GetPositionRelTo", l_body_get_position_rel_to }, - { "GetAltitudeRelTo", l_body_get_altitude_rel_to }, + { "GetVelocityRelTo", l_body_get_velocity_rel_to }, + { "GetPositionRelTo", l_body_get_position_rel_to }, + { "GetAltitudeRelTo", l_body_get_altitude_rel_to }, { "GetProjectedScreenPosition", l_body_get_projected_screen_position }, { "GetTargetIndicatorScreenPosition", l_body_get_target_indicator_screen_position }, - { "GetPhysicalRadius", l_body_get_phys_radius }, + { "GetPhysicalRadius", l_body_get_phys_radius }, { "GetAtmosphericState", l_body_get_atmospheric_state }, - { "GetLabel", l_body_get_label }, + { "GetLabel", l_body_get_label }, { "IsMoreImportantThan", l_body_is_more_important_than }, - { "IsMoon", l_body_is_moon }, - { "IsPlanet", l_body_is_planet }, - { "IsShip", l_body_is_ship }, - { "IsHyperspaceCloud", l_body_is_hyperspace_cloud }, - { "IsMissile", l_body_is_missile }, - { "IsStation", l_body_is_station }, - { "IsSpaceStation", l_body_is_space_station }, - { "IsGroundStation", l_body_is_ground_station }, - { "IsCargoContainer", l_body_is_cargo_container }, - { "GetSystemBody", l_body_get_system_body }, + { "IsMoon", l_body_is_moon }, + { "IsPlanet", l_body_is_planet }, + { "IsShip", l_body_is_ship }, + { "IsHyperspaceCloud", l_body_is_hyperspace_cloud }, + { "IsMissile", l_body_is_missile }, + { "IsStation", l_body_is_station }, + { "IsSpaceStation", l_body_is_space_station }, + { "IsGroundStation", l_body_is_ground_station }, + { "IsCargoContainer", l_body_is_cargo_container }, + { "GetSystemBody", l_body_get_system_body }, { 0, 0 } }; static luaL_Reg l_attrs[] = { - { "seed", l_body_attr_seed }, - { "path", l_body_attr_path }, - { "type", l_body_attr_type }, - { "superType", l_body_attr_super_type }, - { "frameBody", l_body_attr_frame_body }, + { "seed", l_body_attr_seed }, + { "path", l_body_attr_path }, + { "type", l_body_attr_type }, + { "superType", l_body_attr_super_type }, + { "frameBody", l_body_attr_frame_body }, { "frameRotating", l_body_attr_frame_rotating }, { 0, 0 } }; @@ -858,13 +885,13 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterSerializer(s_type, body_serializers); // we're also the serializer for our subclasses - LuaObjectBase::RegisterSerializer("ModelBody", body_serializers); - LuaObjectBase::RegisterSerializer("Ship", body_serializers); - LuaObjectBase::RegisterSerializer("Player", body_serializers); - LuaObjectBase::RegisterSerializer("SpaceStation", body_serializers); - LuaObjectBase::RegisterSerializer("Planet", body_serializers); - LuaObjectBase::RegisterSerializer("Star", body_serializers); - LuaObjectBase::RegisterSerializer("CargoBody", body_serializers); - LuaObjectBase::RegisterSerializer("Missile", body_serializers); + LuaObjectBase::RegisterSerializer("ModelBody", body_serializers); + LuaObjectBase::RegisterSerializer("Ship", body_serializers); + LuaObjectBase::RegisterSerializer("Player", body_serializers); + LuaObjectBase::RegisterSerializer("SpaceStation", body_serializers); + LuaObjectBase::RegisterSerializer("Planet", body_serializers); + LuaObjectBase::RegisterSerializer("Star", body_serializers); + LuaObjectBase::RegisterSerializer("CargoBody", body_serializers); + LuaObjectBase::RegisterSerializer("Missile", body_serializers); LuaObjectBase::RegisterSerializer("HyperspaceCloud", body_serializers); } diff --git a/src/LuaCargoBody.cpp b/src/LuaCargoBody.cpp index 46bc19a0c..d746bfbfc 100644 --- a/src/LuaCargoBody.cpp +++ b/src/LuaCargoBody.cpp @@ -1,9 +1,9 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "CargoBody.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "CargoBody.h" /* * Class: CargoBody @@ -27,9 +27,11 @@ * experimental */ -template <> const char *LuaObject::s_type = "CargoBody"; +template <> +const char *LuaObject::s_type = "CargoBody"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { const char *l_parent = "ModelBody"; diff --git a/src/LuaComms.cpp b/src/LuaComms.cpp index 461f55f07..d60085e63 100644 --- a/src/LuaComms.cpp +++ b/src/LuaComms.cpp @@ -2,11 +2,11 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaComms.h" +#include "GameLog.h" #include "LuaObject.h" #include "LuaUtils.h" #include "Pi.h" #include "ShipCpanel.h" -#include "GameLog.h" /* * Interface: Comms @@ -104,7 +104,7 @@ void LuaComms::Register() LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "Message", l_comms_message }, + { "Message", l_comms_message }, { "ImportantMessage", l_comms_important_message }, { 0, 0 } }; diff --git a/src/LuaConsole.cpp b/src/LuaConsole.cpp index 8acb8a888..91b7c0308 100644 --- a/src/LuaConsole.cpp +++ b/src/LuaConsole.cpp @@ -2,30 +2,30 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaConsole.h" +#include "FileSystem.h" +#include "KeyBindings.h" #include "LuaManager.h" +#include "LuaUtils.h" #include "Pi.h" +#include "text/TextSupport.h" +#include "text/TextureFont.h" #include "ui/Context.h" #include "ui/Margin.h" -#include "text/TextureFont.h" -#include "text/TextSupport.h" -#include "KeyBindings.h" -#include "FileSystem.h" -#include "LuaUtils.h" +#include #include #include -#include #ifdef REMOTE_LUA_REPL // for networking -#include -#include -#include #include -#include -#include -#include #include +#include #include +#include +#include +#include +#include +#include // end networking #endif @@ -37,12 +37,13 @@ static const char CONSOLE_CHUNK_NAME[] = "[T] console"; static const char CONSOLE_CHUNK_NAME[] = "console"; #endif -LuaConsole::LuaConsole(): +LuaConsole::LuaConsole() : m_active(false), m_precompletionStatement(), m_completionList() #ifdef REMOTE_LUA_REPL - , m_debugSocket(0) + , + m_debugSocket(0) #endif { @@ -52,17 +53,7 @@ LuaConsole::LuaConsole(): m_scroller = Pi::ui->Scroller()->SetInnerWidget(m_output); // temporary until LuaConsole is moved to lua: move up to clear imgui time window - m_container.Reset(Pi::ui->Margin(80, UI::Margin::Direction::BOTTOM)->SetInnerWidget( - Pi::ui->Margin(10)->SetInnerWidget( - Pi::ui->ColorBackground(Color(0,0,0,0xc0))->SetInnerWidget( - Pi::ui->VBox()->PackEnd(UI::WidgetSet( - Pi::ui->Expand()->SetInnerWidget( - m_scroller - ), - m_entry - )) - ) - ))); + m_container.Reset(Pi::ui->Margin(80, UI::Margin::Direction::BOTTOM)->SetInnerWidget(Pi::ui->Margin(10)->SetInnerWidget(Pi::ui->ColorBackground(Color(0, 0, 0, 0xc0))->SetInnerWidget(Pi::ui->VBox()->PackEnd(UI::WidgetSet(Pi::ui->Expand()->SetInnerWidget(m_scroller), m_entry)))))); m_container->SetFont(UI::Widget::FONT_MONO_NORMAL); @@ -86,7 +77,8 @@ void LuaConsole::Toggle() m_active = !m_active; } -static int capture_traceback(lua_State *L) { +static int capture_traceback(lua_State *L) +{ lua_pushstring(L, "\n"); luaL_traceback(L, L, nullptr, 0); lua_concat(L, 3); @@ -94,7 +86,8 @@ static int capture_traceback(lua_State *L) { } // Create the table and leave a copy on the stack for further use -static void init_global_table(lua_State *l) { +static void init_global_table(lua_State *l) +{ LUA_DEBUG_START(l); lua_newtable(l); @@ -109,7 +102,8 @@ static void init_global_table(lua_State *l) { LUA_DEBUG_END(l, 1); } -static int console_autoexec(lua_State* l) { +static int console_autoexec(lua_State *l) +{ LUA_DEBUG_START(l); init_global_table(l); // _ENV @@ -155,10 +149,10 @@ static int console_autoexec(lua_State* l) { LUA_DEBUG_END(l, 0); return 0; - } -void LuaConsole::RegisterAutoexec() { +void LuaConsole::RegisterAutoexec() +{ lua_State *L = Lua::manager->GetLuaState(); LUA_DEBUG_START(L); if (!pi_lua_import(L, "Event")) { @@ -177,89 +171,92 @@ void LuaConsole::RegisterAutoexec() { LuaConsole::~LuaConsole() {} -bool LuaConsole::OnKeyDown(const UI::KeyboardEvent &event) { +bool LuaConsole::OnKeyDown(const UI::KeyboardEvent &event) +{ switch (event.keysym.sym) { - case SDLK_ESCAPE: { - // pressing the ESC key will drop our layer, but we still have to make sure we are marked as not active anymore - m_active = false; - break; - } - case SDLK_UP: - case SDLK_DOWN: { - if (m_historyPosition == -1) { - if (event.keysym.sym == SDLK_UP) { - m_historyPosition = (m_statementHistory.size() - 1); - if (m_historyPosition != -1) { - m_stashedStatement = m_entry->GetText(); - m_entry->SetText(m_statementHistory[m_historyPosition]); - } + case SDLK_ESCAPE: { + // pressing the ESC key will drop our layer, but we still have to make sure we are marked as not active anymore + m_active = false; + break; + } + case SDLK_UP: + case SDLK_DOWN: { + if (m_historyPosition == -1) { + if (event.keysym.sym == SDLK_UP) { + m_historyPosition = (m_statementHistory.size() - 1); + if (m_historyPosition != -1) { + m_stashedStatement = m_entry->GetText(); + m_entry->SetText(m_statementHistory[m_historyPosition]); + } + } + } else { + if (event.keysym.sym == SDLK_DOWN) { + ++m_historyPosition; + if (m_historyPosition >= int(m_statementHistory.size())) { + m_historyPosition = -1; + m_entry->SetText(m_stashedStatement); + m_stashedStatement.clear(); + } else { + m_entry->SetText(m_statementHistory[m_historyPosition]); } } else { - if (event.keysym.sym == SDLK_DOWN) { - ++m_historyPosition; - if (m_historyPosition >= int(m_statementHistory.size())) { - m_historyPosition = -1; - m_entry->SetText(m_stashedStatement); - m_stashedStatement.clear(); - } else { - m_entry->SetText(m_statementHistory[m_historyPosition]); - } - } else { - if (m_historyPosition > 0) { - --m_historyPosition; - m_entry->SetText(m_statementHistory[m_historyPosition]); - } + if (m_historyPosition > 0) { + --m_historyPosition; + m_entry->SetText(m_statementHistory[m_historyPosition]); } } - - return true; } - case SDLK_u: - case SDLK_w: - if (event.keysym.mod & KMOD_CTRL) { - // TextEntry already cleared the input, we must cleanup the history - m_stashedStatement.clear(); - m_historyPosition = -1; - return true; - } - break; + return true; + } - case SDLK_l: - if (event.keysym.mod & KMOD_CTRL) { - m_output->SetText(""); - return true; - } - break; - - case SDLK_TAB: - if (m_completionList.empty()) { - UpdateCompletion(m_entry->GetText()); - } - if (!m_completionList.empty()) { // We still need to test whether it failed or not. - if (event.keysym.mod & KMOD_SHIFT) { - if (m_currentCompletion == 0) - m_currentCompletion = m_completionList.size(); - m_currentCompletion--; - } else { - m_currentCompletion++; - if (m_currentCompletion == m_completionList.size()) - m_currentCompletion = 0; - } - m_entry->SetText(m_precompletionStatement + m_completionList[m_currentCompletion]); - } + case SDLK_u: + case SDLK_w: + if (event.keysym.mod & KMOD_CTRL) { + // TextEntry already cleared the input, we must cleanup the history + m_stashedStatement.clear(); + m_historyPosition = -1; return true; + } + break; + + case SDLK_l: + if (event.keysym.mod & KMOD_CTRL) { + m_output->SetText(""); + return true; + } + break; + + case SDLK_TAB: + if (m_completionList.empty()) { + UpdateCompletion(m_entry->GetText()); + } + if (!m_completionList.empty()) { // We still need to test whether it failed or not. + if (event.keysym.mod & KMOD_SHIFT) { + if (m_currentCompletion == 0) + m_currentCompletion = m_completionList.size(); + m_currentCompletion--; + } else { + m_currentCompletion++; + if (m_currentCompletion == m_completionList.size()) + m_currentCompletion = 0; + } + m_entry->SetText(m_precompletionStatement + m_completionList[m_currentCompletion]); + } + return true; } return false; } -void LuaConsole::OnChange(const std::string &text) { +void LuaConsole::OnChange(const std::string &text) +{ m_completionList.clear(); } -void LuaConsole::OnEnter(const std::string &text) { +void LuaConsole::OnEnter(const std::string &text) +{ if (!text.empty()) ExecOrContinue(text); m_completionList.clear(); @@ -267,7 +264,8 @@ void LuaConsole::OnEnter(const std::string &text) { m_scroller->SetScrollPosition(1.0f); } -void LuaConsole::UpdateCompletion(const std::string & statement) { +void LuaConsole::UpdateCompletion(const std::string &statement) +{ // First, split the statement into chunks. m_completionList.clear(); std::stack chunks; @@ -276,13 +274,13 @@ void LuaConsole::UpdateCompletion(const std::string & statement) { std::string::const_iterator current_end = statement.end(); std::string::const_iterator current_begin = statement.begin(); // To keep record when breaking off the loop. for (std::string::const_reverse_iterator r_str_it = statement.rbegin(); - r_str_it != statement.rend(); ++r_str_it) { - if(Text::is_alphanumunderscore(*r_str_it)) { + r_str_it != statement.rend(); ++r_str_it) { + if (Text::is_alphanumunderscore(*r_str_it)) { expect_symbolname = false; continue; } else if (expect_symbolname) // Wrong syntax. return; - if(*r_str_it != '.' && (!chunks.empty() || *r_str_it != ':')) { // We are out of the expression. + if (*r_str_it != '.' && (!chunks.empty() || *r_str_it != ':')) { // We are out of the expression. current_begin = r_str_it.base(); // Flag the symbol marking the beginning of the expression. break; } @@ -290,8 +288,8 @@ void LuaConsole::UpdateCompletion(const std::string & statement) { expect_symbolname = true; // We hit a separator, there should be a symbol name before it. chunks.push(std::string(r_str_it.base(), current_end)); if (*r_str_it == ':') // If it is a colon, we know chunks is empty so it is incomplete. - method = true; // it must mean that we want to call a method. - current_end = (r_str_it+1).base(); // +1 in order to point on the CURRENT character. + method = true; // it must mean that we want to call a method. + current_end = (r_str_it + 1).base(); // +1 in order to point on the CURRENT character. } if (expect_symbolname) // Again, a symbol was expected when we broke out of the loop. return; @@ -303,7 +301,7 @@ void LuaConsole::UpdateCompletion(const std::string & statement) { return; } - lua_State * l = Lua::manager->GetLuaState(); + lua_State *l = Lua::manager->GetLuaState(); int stackheight = lua_gettop(l); lua_getfield(l, LUA_REGISTRYINDEX, "ConsoleGlobal"); // Loading the tables in which to do the name lookup @@ -315,7 +313,7 @@ void LuaConsole::UpdateCompletion(const std::string & statement) { chunks.pop(); } LuaObjectBase::GetNames(m_completionList, chunks.top(), method); - if(!m_completionList.empty()) { + if (!m_completionList.empty()) { std::sort(m_completionList.begin(), m_completionList.end()); m_completionList.erase(std::unique(m_completionList.begin(), m_completionList.end()), m_completionList.end()); // Add blank completion at the end of the list and point to it. @@ -324,10 +322,11 @@ void LuaConsole::UpdateCompletion(const std::string & statement) { m_precompletionStatement = statement; } - lua_pop(l, lua_gettop(l)-stackheight); // Clean the whole stack. + lua_pop(l, lua_gettop(l) - stackheight); // Clean the whole stack. } -void LuaConsole::AddOutput(const std::string &line) { +void LuaConsole::AddOutput(const std::string &line) +{ std::string actualLine = line + "\n"; m_output->AppendText(actualLine); #ifdef REMOTE_LUA_REPL @@ -335,12 +334,13 @@ void LuaConsole::AddOutput(const std::string &line) { #endif } -void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) { +void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) +{ int result; lua_State *L = Lua::manager->GetLuaState(); // If the statement is an expression, print its final value. - result = luaL_loadbuffer(L, ("return " + stmt).c_str(), stmt.size()+7, CONSOLE_CHUNK_NAME); + result = luaL_loadbuffer(L, ("return " + stmt).c_str(), stmt.size() + 7, CONSOLE_CHUNK_NAME); if (result == LUA_ERRSYNTAX) result = luaL_loadbuffer(L, stmt.c_str(), stmt.size(), CONSOLE_CHUNK_NAME); @@ -387,7 +387,7 @@ void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) { std::getline(stmt_stream, string_buffer); AddOutput("> " + string_buffer); - while(!stmt_stream.eof()) { + while (!stmt_stream.eof()) { std::getline(stmt_stream, string_buffer); AddOutput(" " + string_buffer); } @@ -422,7 +422,7 @@ void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) { // duplicate the tostring function for the call lua_pushvalue(L, -1); - lua_pushvalue(L, top+i); + lua_pushvalue(L, top + i); result = lua_pcall(L, 1, 1, 0); size_t len = 0; @@ -444,7 +444,7 @@ void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) { // update the history list - if (! result) { + if (!result) { // command succeeded... add it to the history unless it's just // an exact repeat of the immediate last command if (m_statementHistory.empty() || (stmt != m_statementHistory.back())) @@ -484,7 +484,8 @@ void LuaConsole::ExecOrContinue(const std::string &stmt, bool repeatStatement) { * * stable */ -static int l_console_addline(lua_State *L) { +static int l_console_addline(lua_State *L) +{ if (Pi::luaConsole) { size_t len; const char *s = luaL_checklstring(L, 1, &len); @@ -493,7 +494,8 @@ static int l_console_addline(lua_State *L) { return 0; } -static int l_console_print(lua_State *L) { +static int l_console_print(lua_State *L) +{ int nargs = lua_gettop(L); LUA_DEBUG_START(L); std::string line; @@ -504,8 +506,12 @@ static int l_console_print(lua_State *L) { lua_call(L, 1, 1); size_t len; const char *str = lua_tolstring(L, -1, &len); - if (!str) { return luaL_error(L, "'tostring' must return a string to 'print'"); } - if (i > 1) { line += '\t'; } + if (!str) { + return luaL_error(L, "'tostring' must return a string to 'print'"); + } + if (i > 1) { + line += '\t'; + } line.append(str, len); lua_pop(L, 1); } @@ -539,7 +545,8 @@ void LuaConsole::Register() } #ifdef REMOTE_LUA_REPL -void LuaConsole::OpenTCPDebugConnection(int portnumber) { +void LuaConsole::OpenTCPDebugConnection(int portnumber) +{ m_debugSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_debugSocket < 0) { Output("Error opening socket"); @@ -549,9 +556,9 @@ void LuaConsole::OpenTCPDebugConnection(int portnumber) { destination.sin_family = AF_INET; destination.sin_port = htons(portnumber); destination.sin_addr.s_addr = INADDR_ANY; // this should be localhost only! - if (bind(m_debugSocket, reinterpret_cast(&destination), sizeof(destination)) < 0) { + if (bind(m_debugSocket, reinterpret_cast(&destination), sizeof(destination)) < 0) { Output("Binding socket failed.\n"); - if(m_debugSocket) { + if (m_debugSocket) { close(m_debugSocket); m_debugSocket = 0; return; @@ -568,12 +575,13 @@ void LuaConsole::OpenTCPDebugConnection(int portnumber) { } } -void LuaConsole::HandleTCPDebugConnections() { +void LuaConsole::HandleTCPDebugConnections() +{ if (m_debugSocket) { fd_set read_fds; FD_ZERO(&read_fds); FD_SET(m_debugSocket, &read_fds); - struct timespec timeout = {0,0}; + struct timespec timeout = { 0, 0 }; int res = pselect(m_debugSocket + 1, &read_fds, NULL, NULL, &timeout, NULL); if (res < 0 && errno != EINTR) { @@ -583,12 +591,13 @@ void LuaConsole::HandleTCPDebugConnections() { HandleNewDebugTCPConnection(m_debugSocket); } } - for(int sock : m_debugConnections) { + for (int sock : m_debugConnections) { HandleDebugTCPConnection(sock); } } -void LuaConsole::HandleNewDebugTCPConnection(int socket) { +void LuaConsole::HandleNewDebugTCPConnection(int socket) +{ int sock = accept(socket, NULL, 0); if (sock < 0) { Output("Error accepting on socket.\n"); @@ -610,25 +619,27 @@ void LuaConsole::HandleNewDebugTCPConnection(int socket) { } // TODO: these should not be here, do we need them generally? Maybe in utils.cpp? -static std::string <rim(std::string & str) +static std::string <rim(std::string &str) { - auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace(ch , std::locale::classic() ) ; } ); - str.erase( str.begin() , it2); + auto it2 = std::find_if(str.begin(), str.end(), [](char ch) { return !std::isspace(ch, std::locale::classic()); }); + str.erase(str.begin(), it2); return str; } -static std::string &rtrim(std::string & str) +static std::string &rtrim(std::string &str) { - auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace(ch , std::locale::classic() ) ; } ); - str.erase( it1.base() , str.end() ); + auto it1 = std::find_if(str.rbegin(), str.rend(), [](char ch) { return !std::isspace(ch, std::locale::classic()); }); + str.erase(it1.base(), str.end()); return str; } -static std::string &trim(std::string &str) { +static std::string &trim(std::string &str) +{ return ltrim(rtrim(str)); } -void LuaConsole::HandleDebugTCPConnection(int sock) { +void LuaConsole::HandleDebugTCPConnection(int sock) +{ char buffer[4097]; int count = read(sock, buffer, 4096); if (count < 0 && errno != EAGAIN) { @@ -644,13 +655,14 @@ void LuaConsole::HandleDebugTCPConnection(int sock) { } } -void LuaConsole::BroadcastToDebuggers(const std::string &message) { - for(int sock : m_debugConnections) { - if(send(sock, message.c_str(), message.size(), MSG_NOSIGNAL) < 0) { - Output("Closing debug socket, error %d.\n", errno); - close(sock); - m_debugConnections.erase(std::remove(m_debugConnections.begin(), m_debugConnections.end(), sock), m_debugConnections.end()); - }; - } +void LuaConsole::BroadcastToDebuggers(const std::string &message) +{ + for (int sock : m_debugConnections) { + if (send(sock, message.c_str(), message.size(), MSG_NOSIGNAL) < 0) { + Output("Closing debug socket, error %d.\n", errno); + close(sock); + m_debugConnections.erase(std::remove(m_debugConnections.begin(), m_debugConnections.end(), sock), m_debugConnections.end()); + }; + } } #endif diff --git a/src/LuaConsole.h b/src/LuaConsole.h index c8bb3a31f..edf195fc8 100644 --- a/src/LuaConsole.h +++ b/src/LuaConsole.h @@ -5,15 +5,15 @@ #define _LUACONSOLE_H #include "LuaManager.h" -#include "ui/Widget.h" #include "RefCounted.h" +#include "ui/Widget.h" #include namespace UI { class TextEntry; class MultiLineText; class Scroller; -} +} // namespace UI class LuaConsole { public: @@ -31,16 +31,17 @@ public: #endif static void Register(); + private: bool OnKeyDown(const UI::KeyboardEvent &event); void OnChange(const std::string &text); void OnEnter(const std::string &text); - void ExecOrContinue(const std::string &stmt, bool repeatStatement=true); + void ExecOrContinue(const std::string &stmt, bool repeatStatement = true); - void OnKeyPressed(const SDL_Keysym*); + void OnKeyPressed(const SDL_Keysym *); void OnTextChanged(); - void UpdateCompletion(const std::string & statement); + void UpdateCompletion(const std::string &statement); void RegisterAutoexec(); #ifdef REMOTE_LUA_REPL diff --git a/src/LuaConstants.h b/src/LuaConstants.h index 871e12378..357024627 100644 --- a/src/LuaConstants.h +++ b/src/LuaConstants.h @@ -13,6 +13,6 @@ namespace LuaConstants { int GetConstant(lua_State *l, const char *ns, const char *name); bool CheckConstant(lua_State *l, const char *ns, const char *name, int *out); bool CheckConstantFromArg(lua_State *m, const char *ns, int idx, int *out); -} +} // namespace LuaConstants #endif diff --git a/src/LuaDev.cpp b/src/LuaDev.cpp index c080c2769..e124be24f 100644 --- a/src/LuaDev.cpp +++ b/src/LuaDev.cpp @@ -2,10 +2,10 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaDev.h" +#include "Game.h" #include "LuaObject.h" #include "Pi.h" #include "WorldView.h" -#include "Game.h" /* * Lua commands used in development & debugging @@ -36,7 +36,7 @@ void LuaDev::Register() LUA_DEBUG_START(l); - static const luaL_Reg methods[]= { + static const luaL_Reg methods[] = { { "SetCameraOffset", l_dev_set_camera_offset }, { 0, 0 } }; diff --git a/src/LuaEngine.cpp b/src/LuaEngine.cpp index ec22f7b45..a8bd9c0f6 100644 --- a/src/LuaEngine.cpp +++ b/src/LuaEngine.cpp @@ -2,29 +2,28 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaEngine.h" -#include "LuaObject.h" -#include "LuaUtils.h" -#include "LuaConstants.h" #include "EnumStrings.h" -#include "Random.h" +#include "FileSystem.h" +#include "FloatComparison.h" +#include "Game.h" +#include "KeyBindings.h" +#include "Lang.h" +#include "LuaConstants.h" +#include "LuaObject.h" +#include "LuaPiGui.h" +#include "LuaUtils.h" #include "OS.h" #include "Pi.h" #include "PiGui.h" -#include "utils.h" -#include "FloatComparison.h" -#include "FileSystem.h" -#include "ui/Context.h" -#include "graphics/Graphics.h" +#include "Player.h" +#include "Random.h" +#include "SectorView.h" #include "Sound.h" #include "SoundMusic.h" -#include "KeyBindings.h" -#include "Lang.h" -#include "Player.h" -#include "Game.h" +#include "graphics/Graphics.h" #include "scenegraph/Model.h" -#include "LuaPiGui.h" -#include "SectorView.h" -#include "LuaPiGui.h" +#include "ui/Context.h" +#include "utils.h" /* * Interface: Engine * @@ -131,8 +130,8 @@ static int l_engine_attr_version(lua_State *l) { std::string version(PIONEER_VERSION); if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")"; - lua_pushlstring(l, version.c_str(), version.size()); - return 1; + lua_pushlstring(l, version.c_str(), version.size()); + return 1; } /* @@ -186,7 +185,7 @@ static int l_engine_get_video_mode_list(lua_State *l) lua_pushinteger(l, modes[i].height); lua_setfield(l, -2, "height"); - lua_rawseti(l, -2, i+1); + lua_rawseti(l, -2, i + 1); } LUA_DEBUG_END(l, 1); @@ -213,7 +212,7 @@ static int l_engine_get_maximum_aa_samples(lua_State *l) { LUA_DEBUG_START(l); - if(Pi::renderer != nullptr) { + if (Pi::renderer != nullptr) { int maxSamples = Pi::renderer->GetMaximumNumberAASamples(); lua_pushinteger(l, maxSamples); } else { @@ -224,8 +223,6 @@ static int l_engine_get_maximum_aa_samples(lua_State *l) return 1; } - - /* * Method: GetVideoResolution * @@ -914,7 +911,8 @@ static int l_engine_set_sector_map_automatic_system_selection(lua_State *l) return 0; } -static int l_engine_sector_map_get_route(lua_State *l) { +static int l_engine_sector_map_get_route(lua_State *l) +{ SectorView *sv = Pi::game->GetSectorView(); std::vector route = sv->GetRoute(); @@ -928,7 +926,8 @@ static int l_engine_sector_map_get_route(lua_State *l) { return 1; } -static int l_engine_sector_map_get_route_size(lua_State *l) { +static int l_engine_sector_map_get_route_size(lua_State *l) +{ SectorView *sv = Pi::game->GetSectorView(); std::vector route = sv->GetRoute(); const int size = route.size(); @@ -952,7 +951,8 @@ static int l_engine_sector_map_auto_route(lua_State *l) return l_engine_sector_map_get_route(l); } -static int l_engine_sector_map_move_route_item_up(lua_State *l) { +static int l_engine_sector_map_move_route_item_up(lua_State *l) +{ SectorView *sv = Pi::game->GetSectorView(); int element = LuaPull(l, 1); @@ -964,7 +964,8 @@ static int l_engine_sector_map_move_route_item_up(lua_State *l) { return 1; } -static int l_engine_sector_map_move_route_item_down(lua_State *l) { +static int l_engine_sector_map_move_route_item_down(lua_State *l) +{ SectorView *sv = Pi::game->GetSectorView(); int element = LuaPull(l, 1); @@ -976,7 +977,8 @@ static int l_engine_sector_map_move_route_item_down(lua_State *l) { return 1; } -static int l_engine_sector_map_remove_route_item(lua_State *l) { +static int l_engine_sector_map_remove_route_item(lua_State *l) +{ SectorView *sv = Pi::game->GetSectorView(); int element = LuaPull(l, 1); @@ -990,10 +992,10 @@ static int l_engine_sector_map_remove_route_item(lua_State *l) { static int l_engine_set_sector_map_selected(lua_State *l) { - SectorView *sv = Pi::game->GetSectorView(); - SystemPath *path = LuaObject::CheckFromLua(1); - sv->SetSelected(*path); - return 0; + SectorView *sv = Pi::game->GetSectorView(); + SystemPath *path = LuaObject::CheckFromLua(1); + sv->SetSelected(*path); + return 0; } static int l_engine_sector_map_goto_sector_path(lua_State *l) @@ -1006,10 +1008,10 @@ static int l_engine_sector_map_goto_sector_path(lua_State *l) static int l_engine_sector_map_goto_system_path(lua_State *l) { - SectorView *sv = Pi::game->GetSectorView(); - SystemPath *path = LuaObject::CheckFromLua(1); - sv->GotoSystem(*path); - return 0; + SectorView *sv = Pi::game->GetSectorView(); + SystemPath *path = LuaObject::CheckFromLua(1); + sv->GotoSystem(*path); + return 0; } static int l_engine_search_nearby_star_systems_by_name(lua_State *l) @@ -1020,7 +1022,7 @@ static int l_engine_search_nearby_star_systems_by_name(lua_State *l) std::vector matches = sv->GetNearbyStarSystemsByName(pattern); int i = 1; lua_newtable(l); - for(const SystemPath &path : matches) { + for (const SystemPath &path : matches) { lua_pushnumber(l, i++); LuaObject::PushToLua(path); lua_settable(l, -3); @@ -1056,10 +1058,10 @@ static int l_engine_get_sector_map_factions(lua_State *l) const std::set hidden = sv->GetHiddenFactions(); lua_newtable(l); // outer table int i = 1; - for(const Faction *f : visible) { + for (const Faction *f : visible) { lua_pushnumber(l, i++); lua_newtable(l); // inner table - LuaObject::PushToLua(const_cast(f)); + LuaObject::PushToLua(const_cast(f)); lua_setfield(l, -2, "faction"); lua_pushboolean(l, hidden.count(f) == 0); lua_setfield(l, -2, "visible"); // inner table @@ -1156,48 +1158,48 @@ void LuaEngine::Register() { "GetModel", l_engine_get_model }, - { "GetSectorMapZoomLevel", l_engine_get_sector_map_zoom_level }, - { "SectorMapZoomIn", l_engine_sector_map_zoom_in }, - { "SectorMapZoomOut", l_engine_sector_map_zoom_out }, - { "GetSectorMapCenterSector", l_engine_get_sector_map_center_sector }, + { "GetSectorMapZoomLevel", l_engine_get_sector_map_zoom_level }, + { "SectorMapZoomIn", l_engine_sector_map_zoom_in }, + { "SectorMapZoomOut", l_engine_sector_map_zoom_out }, + { "GetSectorMapCenterSector", l_engine_get_sector_map_center_sector }, { "GetSectorMapCenterDistance", l_engine_get_sector_map_center_distance }, - { "GetSectorMapCurrentSystemPath", l_engine_get_sector_map_current_system_path }, + { "GetSectorMapCurrentSystemPath", l_engine_get_sector_map_current_system_path }, { "GetSectorMapSelectedSystemPath", l_engine_get_sector_map_selected_system_path }, { "GetSectorMapHyperspaceTargetSystemPath", l_engine_get_sector_map_hyperspace_target_system_path }, - { "SetSectorMapDrawUninhabitedLabels", l_engine_set_sector_map_draw_uninhabited_labels }, - { "SetSectorMapDrawVerticalLines", l_engine_set_sector_map_draw_vertical_lines }, - { "SetSectorMapDrawOutRangeLabels", l_engine_set_sector_map_draw_out_range_labels }, - { "SetSectorMapAutomaticSystemSelection", l_engine_set_sector_map_automatic_system_selection }, - { "SetSectorMapLockHyperspaceTarget", l_engine_set_sector_map_lock_hyperspace_target }, - { "SetSectorMapSelected", l_engine_set_sector_map_selected }, - { "SectorMapGotoSectorPath", l_engine_sector_map_goto_sector_path }, - { "SectorMapGotoSystemPath", l_engine_sector_map_goto_system_path }, - { "GetSectorMapFactions", l_engine_get_sector_map_factions }, - { "SetSectorMapFactionVisible", l_engine_set_sector_map_faction_visible }, - { "SectorMapAutoRoute", l_engine_sector_map_auto_route }, - { "SectorMapGetRoute", l_engine_sector_map_get_route }, - { "SectorMapGetRouteSize", l_engine_sector_map_get_route_size }, - { "SectorMapMoveRouteItemUp", l_engine_sector_map_move_route_item_up }, - { "SectorMapMoveRouteItemDown", l_engine_sector_map_move_route_item_down }, - { "SectorMapRemoveRouteItem", l_engine_sector_map_remove_route_item }, + { "SetSectorMapDrawUninhabitedLabels", l_engine_set_sector_map_draw_uninhabited_labels }, + { "SetSectorMapDrawVerticalLines", l_engine_set_sector_map_draw_vertical_lines }, + { "SetSectorMapDrawOutRangeLabels", l_engine_set_sector_map_draw_out_range_labels }, + { "SetSectorMapAutomaticSystemSelection", l_engine_set_sector_map_automatic_system_selection }, + { "SetSectorMapLockHyperspaceTarget", l_engine_set_sector_map_lock_hyperspace_target }, + { "SetSectorMapSelected", l_engine_set_sector_map_selected }, + { "SectorMapGotoSectorPath", l_engine_sector_map_goto_sector_path }, + { "SectorMapGotoSystemPath", l_engine_sector_map_goto_system_path }, + { "GetSectorMapFactions", l_engine_get_sector_map_factions }, + { "SetSectorMapFactionVisible", l_engine_set_sector_map_faction_visible }, + { "SectorMapAutoRoute", l_engine_sector_map_auto_route }, + { "SectorMapGetRoute", l_engine_sector_map_get_route }, + { "SectorMapGetRouteSize", l_engine_sector_map_get_route_size }, + { "SectorMapMoveRouteItemUp", l_engine_sector_map_move_route_item_up }, + { "SectorMapMoveRouteItemDown", l_engine_sector_map_move_route_item_down }, + { "SectorMapRemoveRouteItem", l_engine_sector_map_remove_route_item }, - {"SectorMapClearRoute", l_engine_sector_map_clear_route }, - {"SectorMapAddToRoute", l_engine_sector_map_add_to_route }, + { "SectorMapClearRoute", l_engine_sector_map_clear_route }, + { "SectorMapAddToRoute", l_engine_sector_map_add_to_route }, - { "SearchNearbyStarSystemsByName", l_engine_search_nearby_star_systems_by_name }, + { "SearchNearbyStarSystemsByName", l_engine_search_nearby_star_systems_by_name }, - { "ShipSpaceToScreenSpace", l_engine_ship_space_to_screen_space }, + { "ShipSpaceToScreenSpace", l_engine_ship_space_to_screen_space }, { "CameraSpaceToScreenSpace", l_engine_camera_space_to_screen_space }, - { "WorldSpaceToScreenSpace", l_engine_world_space_to_screen_space }, - { "WorldSpaceToShipSpace", l_engine_world_space_to_ship_space }, + { "WorldSpaceToScreenSpace", l_engine_world_space_to_screen_space }, + { "WorldSpaceToShipSpace", l_engine_world_space_to_ship_space }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "rand", l_engine_attr_rand }, - { "ticks", l_engine_attr_ticks }, - { "ui", l_engine_attr_ui }, - { "pigui", l_engine_attr_pigui }, + { "rand", l_engine_attr_rand }, + { "ticks", l_engine_attr_ticks }, + { "ui", l_engine_attr_ui }, + { "pigui", l_engine_attr_pigui }, { "version", l_engine_attr_version }, { 0, 0 } }; diff --git a/src/LuaEngine.h b/src/LuaEngine.h index 4374e759f..b8f49fe4e 100644 --- a/src/LuaEngine.h +++ b/src/LuaEngine.h @@ -14,6 +14,6 @@ namespace LuaEngine { DETAIL_HIGH, DETAIL_VERY_HIGH, }; -} +} // namespace LuaEngine #endif diff --git a/src/LuaEvent.cpp b/src/LuaEvent.cpp index 3177cd2c8..11ef0f67f 100644 --- a/src/LuaEvent.cpp +++ b/src/LuaEvent.cpp @@ -1,70 +1,71 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "LuaEvent.h" #include "LuaManager.h" #include "LuaObject.h" #include "LuaUtils.h" +#include "libs.h" namespace LuaEvent { -static bool _get_method_onto_stack(lua_State *l, const char *method) { - LUA_DEBUG_START(l); + static bool _get_method_onto_stack(lua_State *l, const char *method) + { + LUA_DEBUG_START(l); - int top = lua_gettop(l); + int top = lua_gettop(l); - if (!pi_lua_import(l, "Event")) - return false; + if (!pi_lua_import(l, "Event")) + return false; - lua_getfield(l, -1, method); - if (!lua_isfunction(l, -1)) { - lua_pop(l, 2); - LUA_DEBUG_END(l, 0); - return false; + lua_getfield(l, -1, method); + if (!lua_isfunction(l, -1)) { + lua_pop(l, 2); + LUA_DEBUG_END(l, 0); + return false; + } + + lua_insert(l, top + 1); + lua_settop(l, top + 1); + + LUA_DEBUG_END(l, 1); + + return true; } - lua_insert(l, top+1); - lua_settop(l, top+1); + void Clear() + { + lua_State *l = Lua::manager->GetLuaState(); - LUA_DEBUG_END(l, 1); + LUA_DEBUG_START(l); + if (!_get_method_onto_stack(l, "_Clear")) return; + pi_lua_protected_call(l, 0, 0); + LUA_DEBUG_END(l, 0); + } - return true; -} + void Emit() + { + lua_State *l = Lua::manager->GetLuaState(); -void Clear() -{ - lua_State *l = Lua::manager->GetLuaState(); + LUA_DEBUG_START(l); + if (!_get_method_onto_stack(l, "_Emit")) return; + pi_lua_protected_call(l, 0, 0); + LUA_DEBUG_END(l, 0); + } - LUA_DEBUG_START(l); - if (!_get_method_onto_stack(l, "_Clear")) return; - pi_lua_protected_call(l, 0, 0); - LUA_DEBUG_END(l, 0); -} + void Queue(const char *event, const ArgsBase &args) + { + lua_State *l = Lua::manager->GetLuaState(); -void Emit() -{ - lua_State *l = Lua::manager->GetLuaState(); + LUA_DEBUG_START(l); + if (!_get_method_onto_stack(l, "Queue")) return; - LUA_DEBUG_START(l); - if (!_get_method_onto_stack(l, "_Emit")) return; - pi_lua_protected_call(l, 0, 0); - LUA_DEBUG_END(l, 0); -} + int top = lua_gettop(l); + lua_pushstring(l, event); + args.PrepareStack(); + pi_lua_protected_call(l, lua_gettop(l) - top, 0); -void Queue(const char *event, const ArgsBase &args) -{ - lua_State *l = Lua::manager->GetLuaState(); + LUA_DEBUG_END(l, 0); + } - LUA_DEBUG_START(l); - if (!_get_method_onto_stack(l, "Queue")) return; - - int top = lua_gettop(l); - lua_pushstring(l, event); - args.PrepareStack(); - pi_lua_protected_call(l, lua_gettop(l) - top, 0); - - LUA_DEBUG_END(l, 0); -} - -} +} // namespace LuaEvent diff --git a/src/LuaEvent.h b/src/LuaEvent.h index 715f6eb6c..dbe82d9d6 100644 --- a/src/LuaEvent.h +++ b/src/LuaEvent.h @@ -4,9 +4,9 @@ #ifndef _LUAEVENT_H #define _LUAEVENT_H +#include "DeleteEmitter.h" #include "Lua.h" #include "LuaObject.h" -#include "DeleteEmitter.h" #include "Pi.h" namespace LuaEvent { @@ -18,51 +18,59 @@ namespace LuaEvent { virtual void PrepareStack() const = 0; }; - template + template class Args : public ArgsBase { public: - Args(T0 *_arg0, T1 *_arg1) : arg0(_arg0), arg1(_arg1) { } + Args(T0 *_arg0, T1 *_arg1) : + arg0(_arg0), + arg1(_arg1) {} virtual ~Args() {} T0 *arg0; T1 *arg1; - inline void PrepareStack() const { + inline void PrepareStack() const + { LuaObject::PushToLua(arg0); LuaObject::PushToLua(arg1); } }; template - class Args : public ArgsBase { + class Args : public ArgsBase { public: - Args(T0 *_arg0) : arg0(_arg0) { } + Args(T0 *_arg0) : + arg0(_arg0) {} virtual ~Args() {} T0 *arg0; - inline void PrepareStack() const { + inline void PrepareStack() const + { LuaObject::PushToLua(arg0); } }; template - class Args : public ArgsBase { + class Args : public ArgsBase { public: - Args(T0 *_arg0, const char *_arg1) : arg0(_arg0), arg1(_arg1) {} + Args(T0 *_arg0, const char *_arg1) : + arg0(_arg0), + arg1(_arg1) {} virtual ~Args() {} - T0 *arg0; + T0 *arg0; const char *arg1; - inline void PrepareStack() const { + inline void PrepareStack() const + { LuaObject::PushToLua(arg0); lua_pushstring(Lua::manager->GetLuaState(), arg1); } }; template <> - class Args : public ArgsBase { + class Args : public ArgsBase { public: Args() {} virtual ~Args() {} @@ -76,23 +84,27 @@ namespace LuaEvent { void Queue(const char *event, const ArgsBase &args); template - void Queue(const char *event, T0 *arg0, T1 *arg1) { + void Queue(const char *event, T0 *arg0, T1 *arg1) + { Queue(event, Args(arg0, arg1)); } template - void Queue(const char *event, T0 *arg0, const char *arg1) { + void Queue(const char *event, T0 *arg0, const char *arg1) + { Queue(event, Args(arg0, arg1)); } template - void Queue(const char *event, T0 *arg0) { + void Queue(const char *event, T0 *arg0) + { Queue(event, Args(arg0)); } - inline void Queue(const char *event) { + inline void Queue(const char *event) + { Queue(event, Args<>()); } -} +} // namespace LuaEvent #endif diff --git a/src/LuaFaction.cpp b/src/LuaFaction.cpp index e05b15024..669e64d3d 100644 --- a/src/LuaFaction.cpp +++ b/src/LuaFaction.cpp @@ -1,10 +1,10 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "Factions.h" +#include "LuaConstants.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "LuaConstants.h" -#include "Factions.h" /* * Class: Faction @@ -256,8 +256,8 @@ static int l_faction_attr_police_ship(lua_State *l) { Faction *faction = LuaObject::CheckFromLua(1); - if(faction->police_ship.empty()) - faction->police_ship = "sinonatrix_police"; // set default ship + if (faction->police_ship.empty()) + faction->police_ship = "sinonatrix_police"; // set default ship lua_pushlstring(l, faction->police_ship.c_str(), faction->police_ship.size()); return 1; @@ -291,24 +291,26 @@ static int l_faction_attr_colour(lua_State *l) return 1; } -template <> const char *LuaObject::s_type = "Faction"; +template <> +const char *LuaObject::s_type = "Faction"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_attrs[] = { - { "name", l_faction_attr_name }, - { "id", l_faction_attr_id }, - { "descriptionShort", l_faction_attr_description_short }, - { "description", l_faction_attr_description }, - { "hasHomeworld", l_faction_attr_has_homeworld }, - { "homeworld", l_faction_attr_homeworld }, - { "foundingDate", l_faction_attr_founding_date }, - { "expansionRate", l_faction_attr_expansion_rate }, - { "radius", l_faction_attr_radius }, - { "militaryName", l_faction_attr_military_name }, - { "policeName", l_faction_attr_police_name }, - { "policeShip", l_faction_attr_police_ship }, - { "colour", l_faction_attr_colour }, + { "name", l_faction_attr_name }, + { "id", l_faction_attr_id }, + { "descriptionShort", l_faction_attr_description_short }, + { "description", l_faction_attr_description }, + { "hasHomeworld", l_faction_attr_has_homeworld }, + { "homeworld", l_faction_attr_homeworld }, + { "foundingDate", l_faction_attr_founding_date }, + { "expansionRate", l_faction_attr_expansion_rate }, + { "radius", l_faction_attr_radius }, + { "militaryName", l_faction_attr_military_name }, + { "policeName", l_faction_attr_police_name }, + { "policeShip", l_faction_attr_police_ship }, + { "colour", l_faction_attr_colour }, { 0, 0 } }; diff --git a/src/LuaFileSystem.cpp b/src/LuaFileSystem.cpp index 383ec399d..da22f8887 100644 --- a/src/LuaFileSystem.cpp +++ b/src/LuaFileSystem.cpp @@ -2,9 +2,9 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaFileSystem.h" -#include "LuaObject.h" -#include "LuaConstants.h" #include "FileSystem.h" +#include "LuaConstants.h" +#include "LuaObject.h" #include "Pi.h" /* @@ -17,7 +17,8 @@ * will get a Lua error. */ -static void push_date_time(lua_State *l, const Time::DateTime &dt) { +static void push_date_time(lua_State *l, const Time::DateTime &dt) +{ int year, month, day, hour, minute, second; dt.GetDateParts(&year, &month, &day); dt.GetTimeParts(&hour, &minute, &second); @@ -66,17 +67,17 @@ static int l_filesystem_read_dir(lua_State *l) FileSystem::FileSource *fs = nullptr; switch (root) { - case LuaFileSystem::ROOT_USER: - fs = &FileSystem::userFiles; - break; + case LuaFileSystem::ROOT_USER: + fs = &FileSystem::userFiles; + break; - case LuaFileSystem::ROOT_DATA: - fs = &FileSystem::gameDataFiles; - break; + case LuaFileSystem::ROOT_DATA: + fs = &FileSystem::gameDataFiles; + break; - default: - assert(0); // can't happen - return 0; + default: + assert(0); // can't happen + return 0; } assert(fs); @@ -88,8 +89,7 @@ static int l_filesystem_read_dir(lua_State *l) luaL_error(l, "'%s' is not a directory", path.c_str()); return 0; } - } - catch (const std::invalid_argument&) { + } catch (const std::invalid_argument &) { luaL_error(l, "'%s' is not a valid path", path.c_str()); return 0; } @@ -112,9 +112,9 @@ static int l_filesystem_read_dir(lua_State *l) lua_setfield(l, -2, "mtime"); if (info.IsDir()) - lua_rawseti(l, dirsTable, lua_rawlen(l, dirsTable)+1); + lua_rawseti(l, dirsTable, lua_rawlen(l, dirsTable) + 1); else - lua_rawseti(l, filesTable, lua_rawlen(l, filesTable)+1); + lua_rawseti(l, filesTable, lua_rawlen(l, filesTable) + 1); } return 2; @@ -145,8 +145,7 @@ static int l_filesystem_join_path(lua_State *l) path = FileSystem::NormalisePath(path); lua_pushlstring(l, path.c_str(), path.size()); return 1; - } - catch (const std::invalid_argument&) { + } catch (const std::invalid_argument &) { luaL_error(l, "result is not a valid path"); return 0; } @@ -160,7 +159,7 @@ void LuaFileSystem::Register() static const luaL_Reg l_methods[] = { { "ReadDirectory", l_filesystem_read_dir }, - { "JoinPath", l_filesystem_join_path }, + { "JoinPath", l_filesystem_join_path }, { 0, 0 } }; diff --git a/src/LuaFileSystem.h b/src/LuaFileSystem.h index a5cab89df..4255b01b9 100644 --- a/src/LuaFileSystem.h +++ b/src/LuaFileSystem.h @@ -11,6 +11,6 @@ namespace LuaFileSystem { ROOT_USER, ROOT_DATA }; -} +} // namespace LuaFileSystem #endif diff --git a/src/LuaFixed.cpp b/src/LuaFixed.cpp index 623dfd2bc..4514f9167 100644 --- a/src/LuaFixed.cpp +++ b/src/LuaFixed.cpp @@ -1,15 +1,15 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "LuaFixed.h" #include "LuaUtils.h" +#include "libs.h" static int l_fixed_new(lua_State *L) { LUA_DEBUG_START(L); Sint64 num = static_cast(luaL_checknumber(L, 1)); - Sint64 denom = static_cast(luaL_checknumber(L, 2)); // use checknumber for >32-bit precision + Sint64 denom = static_cast(luaL_checknumber(L, 2)); // use checknumber for >32-bit precision if (!denom) return luaL_error(L, "cannot construct a fixed-point value with a zero denominator"); LuaFixed::PushToLua(L, fixed(num, denom)); @@ -97,7 +97,7 @@ static int l_fixed_tonumber(lua_State *L) static int l_fixed_deg2rad(lua_State *L) { const fixed *v = LuaFixed::CheckFromLua(L, 1); - LuaFixed::PushToLua(L, (*v) * fixed(31416,1800000)); + LuaFixed::PushToLua(L, (*v) * fixed(31416, 1800000)); return 1; } @@ -148,7 +148,7 @@ void LuaFixed::Register(lua_State *L) void LuaFixed::PushToLua(lua_State *L, const fixed &v) { LUA_DEBUG_START(L); - fixed *ptr = static_cast(lua_newuserdata(L, sizeof(fixed))); + fixed *ptr = static_cast(lua_newuserdata(L, sizeof(fixed))); *ptr = v; luaL_setmetatable(L, LuaFixed::TypeName); LUA_DEBUG_END(L, 1); @@ -156,10 +156,10 @@ void LuaFixed::PushToLua(lua_State *L, const fixed &v) const fixed *LuaFixed::GetFromLua(lua_State *L, int idx) { - return static_cast(luaL_testudata(L, idx, LuaFixed::TypeName)); + return static_cast(luaL_testudata(L, idx, LuaFixed::TypeName)); } const fixed *LuaFixed::CheckFromLua(lua_State *L, int idx) { - return static_cast(luaL_checkudata(L, idx, LuaFixed::TypeName)); + return static_cast(luaL_checkudata(L, idx, LuaFixed::TypeName)); } diff --git a/src/LuaFixed.h b/src/LuaFixed.h index abb839bf5..cdaceaa6b 100644 --- a/src/LuaFixed.h +++ b/src/LuaFixed.h @@ -16,6 +16,6 @@ namespace LuaFixed { void PushToLua(lua_State *L, const fixed &v); const fixed *GetFromLua(lua_State *L, int idx); const fixed *CheckFromLua(lua_State *L, int idx); -} +} // namespace LuaFixed #endif diff --git a/src/LuaFormat.cpp b/src/LuaFormat.cpp index e719eeea3..afb419dd9 100644 --- a/src/LuaFormat.cpp +++ b/src/LuaFormat.cpp @@ -2,9 +2,9 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaFormat.h" +#include "Lang.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "Lang.h" #include "StringF.h" #include "utils.h" #include @@ -111,12 +111,11 @@ static int l_format_money(lua_State *l) { double t = luaL_checknumber(l, 1); double intpart; - modf(t*100.0, &intpart); - if (lua_isboolean(l, 2)){ + modf(t * 100.0, &intpart); + if (lua_isboolean(l, 2)) { bool show_cents = lua_toboolean(l, 2); lua_pushstring(l, format_money(intpart, show_cents).c_str()); - } - else + } else lua_pushstring(l, format_money(intpart).c_str()); return 1; @@ -152,12 +151,12 @@ void LuaFormat::Register() LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "Date", l_format_date }, - { "Distance", l_format_distance }, - { "Money", l_format_money }, - { "AccelG", l_format_accel_g }, + { "Date", l_format_date }, + { "Distance", l_format_distance }, + { "Money", l_format_money }, + { "AccelG", l_format_accel_g }, { "MassTonnes", l_format_mass_tonnes }, - { "Duration", l_format_duration }, + { "Duration", l_format_duration }, { 0, 0 } }; diff --git a/src/LuaGame.cpp b/src/LuaGame.cpp index 1cf8079f3..50e3e7a97 100644 --- a/src/LuaGame.cpp +++ b/src/LuaGame.cpp @@ -2,25 +2,25 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaGame.h" -#include "LuaObject.h" -#include "LuaUtils.h" -#include "FileSystem.h" -#include "Player.h" -#include "Pi.h" -#include "Game.h" -#include "Lang.h" -#include "StringF.h" -#include "WorldView.h" -#include "DeathView.h" -#include "galaxy/Galaxy.h" #include "DateTime.h" -#include "SectorView.h" -#include "SystemView.h" -#include "SystemInfoView.h" -#include "ShipCpanel.h" -#include "LuaPiGui.h" -#include "GameSaveError.h" +#include "DeathView.h" +#include "FileSystem.h" #include "GZipFormat.h" +#include "Game.h" +#include "GameSaveError.h" +#include "Lang.h" +#include "LuaObject.h" +#include "LuaPiGui.h" +#include "LuaUtils.h" +#include "Pi.h" +#include "Player.h" +#include "SectorView.h" +#include "ShipCpanel.h" +#include "StringF.h" +#include "SystemInfoView.h" +#include "SystemView.h" +#include "WorldView.h" +#include "galaxy/Galaxy.h" /* * Interface: Game @@ -65,14 +65,12 @@ static int l_game_start_game(lua_State *l) const double start_time = luaL_optnumber(l, 2, 0.0); try { Pi::game = new Game(*path, start_time); - } - catch (InvalidGameStartLocation& e) { + } catch (InvalidGameStartLocation &e) { luaL_error(l, "invalid starting location for game: %s", e.error.c_str()); } return 0; } - /* * Function: SaveGameStats * @@ -121,20 +119,16 @@ static int l_game_savegame_stats(lua_State *l) } return 1; - } - catch (CouldNotOpenFileException &e) { + } catch (CouldNotOpenFileException &e) { const std::string message = stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", filename)); lua_pushlstring(l, message.c_str(), message.size()); return lua_error(l); - } - catch (Json::type_error) { + } catch (Json::type_error) { luaL_error(l, Lang::GAME_LOAD_CORRUPT); return 0; - } - catch (Json::out_of_range) { + } catch (Json::out_of_range) { return luaL_error(l, Lang::GAME_LOAD_CORRUPT); - } - catch (SavedGameCorruptException) { + } catch (SavedGameCorruptException) { luaL_error(l, Lang::GAME_LOAD_CORRUPT); return 0; } @@ -171,14 +165,11 @@ static int l_game_load_game(lua_State *l) try { Pi::game = Game::LoadGame(filename); - } - catch (SavedGameCorruptException) { + } catch (SavedGameCorruptException) { luaL_error(l, Lang::GAME_LOAD_CORRUPT); - } - catch (SavedGameWrongVersionException) { + } catch (SavedGameWrongVersionException) { luaL_error(l, Lang::GAME_LOAD_WRONG_VERSION); - } - catch (CouldNotOpenFileException) { + } catch (CouldNotOpenFileException) { const std::string msg = stringf(Lang::GAME_LOAD_CANNOT_OPEN, formatarg("filename", filename)); luaL_error(l, msg.c_str()); } @@ -257,19 +248,15 @@ static int l_game_save_game(lua_State *l) Game::SaveGame(filename, Pi::game); lua_pushlstring(l, path.c_str(), path.size()); return 1; - } - catch (CannotSaveInHyperspace) { + } catch (CannotSaveInHyperspace) { return luaL_error(l, "%s", Lang::CANT_SAVE_IN_HYPERSPACE); - } - catch (CannotSaveDeadPlayer) { + } catch (CannotSaveDeadPlayer) { return luaL_error(l, "%s", Lang::CANT_SAVE_DEAD_PLAYER); - } - catch (CouldNotOpenFileException) { + } catch (CouldNotOpenFileException) { const std::string message = stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path)); lua_pushlstring(l, message.c_str(), message.size()); return lua_error(l); - } - catch (CouldNotWriteToFileException) { + } catch (CouldNotWriteToFileException) { return luaL_error(l, "%s", Lang::GAME_SAVE_CANNOT_WRITE); } } @@ -459,21 +446,21 @@ static int l_game_set_radar_visible(lua_State *l) static int l_game_current_view(lua_State *l) { const View *view = Pi::GetView(); - if(view == Pi::game->GetWorldView()) + if (view == Pi::game->GetWorldView()) LuaPush(l, "world"); - else if(view == Pi::game->GetSpaceStationView()) + else if (view == Pi::game->GetSpaceStationView()) LuaPush(l, "space_station"); - else if(view == Pi::game->GetInfoView()) + else if (view == Pi::game->GetInfoView()) LuaPush(l, "info"); - else if(view == Pi::game->GetSectorView()) + else if (view == Pi::game->GetSectorView()) LuaPush(l, "sector"); - else if(view == Pi::game->GetSystemView()) + else if (view == Pi::game->GetSystemView()) LuaPush(l, "system"); - else if(view == Pi::game->GetSystemInfoView()) + else if (view == Pi::game->GetSystemInfoView()) LuaPush(l, "system_info"); - else if(view == Pi::game->GetDeathView()) + else if (view == Pi::game->GetDeathView()) LuaPush(l, "death"); - else if(view == Pi::game->GetGalacticView()) + else if (view == Pi::game->GetGalacticView()) LuaPush(l, "galaxy"); else lua_pushnil(l); @@ -493,15 +480,16 @@ static int l_game_switch_view(lua_State *l) return 0; } -static void pushTimeAccel(lua_State *l, Game::TimeAccel accel) { - switch(accel) { - case Game::TIMEACCEL_PAUSED: lua_pushstring(l,"paused"); break; - case Game::TIMEACCEL_1X: lua_pushstring(l,"1x"); break; - case Game::TIMEACCEL_10X: lua_pushstring(l,"10x"); break; - case Game::TIMEACCEL_100X: lua_pushstring(l,"100x"); break; - case Game::TIMEACCEL_1000X: lua_pushstring(l,"1000x"); break; - case Game::TIMEACCEL_10000X: lua_pushstring(l,"10000x"); break; - case Game::TIMEACCEL_HYPERSPACE: lua_pushstring(l,"hyperspace"); break; +static void pushTimeAccel(lua_State *l, Game::TimeAccel accel) +{ + switch (accel) { + case Game::TIMEACCEL_PAUSED: lua_pushstring(l, "paused"); break; + case Game::TIMEACCEL_1X: lua_pushstring(l, "1x"); break; + case Game::TIMEACCEL_10X: lua_pushstring(l, "10x"); break; + case Game::TIMEACCEL_100X: lua_pushstring(l, "100x"); break; + case Game::TIMEACCEL_1000X: lua_pushstring(l, "1000x"); break; + case Game::TIMEACCEL_10000X: lua_pushstring(l, "10000x"); break; + case Game::TIMEACCEL_HYPERSPACE: lua_pushstring(l, "hyperspace"); break; default: break; // TODO error } } @@ -525,19 +513,19 @@ static int l_game_set_time_acceleration(lua_State *l) std::string accel = LuaPull(l, 1); bool force = LuaPull(l, 2); Game::TimeAccel a = Game::TIMEACCEL_PAUSED; - if(!accel.compare("paused")) + if (!accel.compare("paused")) a = Game::TIMEACCEL_PAUSED; - else if(!accel.compare("1x")) + else if (!accel.compare("1x")) a = Game::TIMEACCEL_1X; - else if(!accel.compare("10x")) + else if (!accel.compare("10x")) a = Game::TIMEACCEL_10X; - else if(!accel.compare("100x")) + else if (!accel.compare("100x")) a = Game::TIMEACCEL_100X; - else if(!accel.compare("1000x")) + else if (!accel.compare("1000x")) a = Game::TIMEACCEL_1000X; - else if(!accel.compare("10000x")) + else if (!accel.compare("10000x")) a = Game::TIMEACCEL_10000X; - else if(!accel.compare("hyperspace")) + else if (!accel.compare("hyperspace")) a = Game::TIMEACCEL_HYPERSPACE; // else TODO error Pi::game->RequestTimeAccel(a, force); @@ -564,21 +552,21 @@ static int l_game_set_view(lua_State *l) if (!Pi::game) return luaL_error(l, "can't set view when no game is running"); std::string target = luaL_checkstring(l, 1); - if(!target.compare("world")) { + if (!target.compare("world")) { Pi::SetView(Pi::game->GetWorldView()); - } else if(!target.compare("space_station")) { + } else if (!target.compare("space_station")) { Pi::SetView(Pi::game->GetSpaceStationView()); - } else if(!target.compare("info")) { + } else if (!target.compare("info")) { Pi::SetView(Pi::game->GetInfoView()); - } else if(!target.compare("death")) { + } else if (!target.compare("death")) { Pi::SetView(Pi::game->GetDeathView()); - } else if(!target.compare("sector")) { + } else if (!target.compare("sector")) { Pi::SetView(Pi::game->GetSectorView()); - } else if(!target.compare("galaxy")) { + } else if (!target.compare("galaxy")) { Pi::SetView(Pi::game->GetGalacticView()); - } else if(!target.compare("system")) { + } else if (!target.compare("system")) { Pi::SetView(Pi::game->GetSystemView()); - } else if(!target.compare("system_info")) { + } else if (!target.compare("system_info")) { Pi::SetView(Pi::game->GetSystemInfoView()); } else { // TODO else error @@ -588,11 +576,11 @@ static int l_game_set_view(lua_State *l) static int l_game_get_world_cam_type(lua_State *l) { - switch(Pi::game->GetWorldView()->GetCamType()) { + switch (Pi::game->GetWorldView()->GetCamType()) { case WorldView::CAM_INTERNAL: lua_pushstring(l, "internal"); break; case WorldView::CAM_EXTERNAL: lua_pushstring(l, "external"); break; case WorldView::CAM_SIDEREAL: lua_pushstring(l, "sidereal"); break; - case WorldView::CAM_FLYBY: lua_pushstring(l, "flyby"); break; + case WorldView::CAM_FLYBY: lua_pushstring(l, "flyby"); break; default: Output("Unknown world view cam type\n"); break; } return 1; @@ -607,13 +595,13 @@ static int l_game_change_flight_state(lua_State *l) static int l_game_set_world_cam_type(lua_State *l) { std::string cam = luaL_checkstring(l, 1); - if(!cam.compare("internal")) + if (!cam.compare("internal")) Pi::game->GetWorldView()->SetCamType(WorldView::CAM_INTERNAL); - else if(!cam.compare("external")) + else if (!cam.compare("external")) Pi::game->GetWorldView()->SetCamType(WorldView::CAM_EXTERNAL); - else if(!cam.compare("sidereal")) + else if (!cam.compare("sidereal")) Pi::game->GetWorldView()->SetCamType(WorldView::CAM_SIDEREAL); - else if(!cam.compare("flyby")) + else if (!cam.compare("flyby")) Pi::game->GetWorldView()->SetCamType(WorldView::CAM_FLYBY); else { // TODO else error @@ -621,7 +609,8 @@ static int l_game_set_world_cam_type(lua_State *l) return 0; } -static int l_game_get_hyperspace_travelled_percentage(lua_State *l) { +static int l_game_get_hyperspace_travelled_percentage(lua_State *l) +{ LuaPush(l, Pi::game->GetHyperspaceArrivalProbability()); return 1; } @@ -649,28 +638,28 @@ void LuaGame::Register() LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "StartGame", l_game_start_game }, - { "LoadGame", l_game_load_game }, - { "CanLoadGame", l_game_can_load_game }, - { "SaveGame", l_game_save_game }, - { "EndGame", l_game_end_game }, - { "InHyperspace", l_game_in_hyperspace }, - { "SetRadarVisible",l_game_set_radar_visible}, - { "SaveGameStats", l_game_savegame_stats }, + { "StartGame", l_game_start_game }, + { "LoadGame", l_game_load_game }, + { "CanLoadGame", l_game_can_load_game }, + { "SaveGame", l_game_save_game }, + { "EndGame", l_game_end_game }, + { "InHyperspace", l_game_in_hyperspace }, + { "SetRadarVisible", l_game_set_radar_visible }, + { "SaveGameStats", l_game_savegame_stats }, - { "SwitchView", l_game_switch_view }, + { "SwitchView", l_game_switch_view }, { "CurrentView", l_game_current_view }, - { "SetView", l_game_set_view }, + { "SetView", l_game_set_view }, { "GetDateTime", l_game_get_date_time }, { "GetPartsFromDateTime", l_game_get_parts_from_date_time }, - { "SetTimeAcceleration", l_game_set_time_acceleration }, - { "GetTimeAcceleration", l_game_get_time_acceleration }, + { "SetTimeAcceleration", l_game_set_time_acceleration }, + { "GetTimeAcceleration", l_game_get_time_acceleration }, { "GetRequestedTimeAcceleration", l_game_get_requested_time_acceleration }, { "GetHyperspaceTravelledPercentage", l_game_get_hyperspace_travelled_percentage }, { "SetWorldCamType", l_game_set_world_cam_type }, { "GetWorldCamType", l_game_get_world_cam_type }, - { "ChangeFlightState", l_game_change_flight_state }, // deprecated + { "ChangeFlightState", l_game_change_flight_state }, // deprecated { 0, 0 } }; @@ -678,7 +667,7 @@ void LuaGame::Register() static const luaL_Reg l_attrs[] = { { "player", l_game_attr_player }, { "system", l_game_attr_system }, - { "time", l_game_attr_time }, + { "time", l_game_attr_time }, { "paused", l_game_attr_paused }, { 0, 0 } }; diff --git a/src/LuaHyperspaceCloud.cpp b/src/LuaHyperspaceCloud.cpp index ad7a8bf8f..d7ad262ce 100644 --- a/src/LuaHyperspaceCloud.cpp +++ b/src/LuaHyperspaceCloud.cpp @@ -1,15 +1,15 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "EnumStrings.h" +#include "Game.h" +#include "HyperspaceCloud.h" +#include "LuaConstants.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "LuaConstants.h" -#include "HyperspaceCloud.h" #include "Pi.h" -#include "Game.h" -#include "Ship.h" #include "SectorView.h" -#include "EnumStrings.h" +#include "Ship.h" #include "galaxy/Galaxy.h" /* * Class: HyperspaceCloud @@ -17,7 +17,6 @@ * Class representing a hyperspace cloud. Inherits from */ - /* Method: IsArrival * * Return true if this is an arrival cloud. @@ -34,7 +33,6 @@ static int l_hyperspace_cloud_is_arrival(lua_State *l) return 1; } - /* Method: GetShip * * Return the that created this cloud, or nil. @@ -48,14 +46,13 @@ static int l_hyperspace_cloud_get_ship(lua_State *l) { HyperspaceCloud *cloud = LuaObject::CheckFromLua(1); Ship *ship = cloud->GetShip(); - if(ship == nullptr) + if (ship == nullptr) lua_pushnil(l); else LuaPush(l, ship); return 1; } - /* Method: GetDueDate * * Return the date when a ship has entered / will exit this cloud. @@ -67,22 +64,24 @@ static int l_hyperspace_cloud_get_ship(lua_State *l) */ static int l_hyperspace_cloud_get_due_date(lua_State *l) { - HyperspaceCloud *cloud = LuaObject::CheckFromLua(1); - LuaPush(l, cloud->GetDueDate()); - return 1; + HyperspaceCloud *cloud = LuaObject::CheckFromLua(1); + LuaPush(l, cloud->GetDueDate()); + return 1; } -template <> const char *LuaObject::s_type = "HyperspaceCloud"; +template <> +const char *LuaObject::s_type = "HyperspaceCloud"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "Body"; static const luaL_Reg l_methods[] = { - { "IsArrival", l_hyperspace_cloud_is_arrival }, - { "GetShip", l_hyperspace_cloud_get_ship }, + { "IsArrival", l_hyperspace_cloud_is_arrival }, + { "GetShip", l_hyperspace_cloud_get_ship }, { "GetDueDate", l_hyperspace_cloud_get_due_date }, - + { 0, 0 } }; diff --git a/src/LuaInput.cpp b/src/LuaInput.cpp index 8c134d58c..e24e2669a 100644 --- a/src/LuaInput.cpp +++ b/src/LuaInput.cpp @@ -2,11 +2,11 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaInput.h" -#include "LuaUtils.h" -#include "LuaObject.h" -#include "Lang.h" #include "Input.h" #include "KeyBindings.h" +#include "Lang.h" +#include "LuaObject.h" +#include "LuaUtils.h" #include "Pi.h" /* * Interface: Input @@ -113,8 +113,7 @@ static int l_input_get_bindings(lua_State *l) push_key_binding(l, &ab->binding1, "binding1", "bindingDescription1"); push_key_binding(l, &ab->binding2, "binding2", "bindingDescription2"); - } - else { + } else { AxisBinding *ab = Pi::input.GetAxisBinding(type.first); if (!ab) continue; // Should never happen, but include it here for future proofing. setup_binding_table(l, type.first.c_str(), "axis"); @@ -158,7 +157,8 @@ static int l_input_disable_bindings(lua_State *l) return 0; } -static int l_input_set_action_binding(lua_State *l) { +static int l_input_set_action_binding(lua_State *l) +{ const char *binding_id = luaL_checkstring(l, 1); const char *binding_config_1 = lua_tostring(l, 2); const char *binding_config_2 = lua_tostring(l, 3); @@ -182,7 +182,8 @@ static int l_input_set_action_binding(lua_State *l) { return 0; } -static int l_input_set_axis_binding(lua_State *l) { +static int l_input_set_axis_binding(lua_State *l) +{ const char *binding_id = luaL_checkstring(l, 1); const char *binding_config_axis = lua_tostring(l, 2); const char *binding_config_positive = lua_tostring(l, 3); @@ -193,17 +194,20 @@ static int l_input_set_axis_binding(lua_State *l) { if (binding_config_axis) { if (!KeyBindings::JoyAxisBinding::FromString(binding_config_axis, ab)) return luaL_error(l, "invalid axis binding given to Input.SetKeyBinding"); - } else ab.Clear(); + } else + ab.Clear(); KeyBindings::KeyBinding kb1, kb2; if (binding_config_positive) { if (!KeyBindings::KeyBinding::FromString(binding_config_positive, kb1)) return luaL_error(l, "invalid first key binding given to Input.SetKeyBinding"); - } else kb1.Clear(); + } else + kb1.Clear(); if (binding_config_negative) { if (!KeyBindings::KeyBinding::FromString(binding_config_negative, kb2)) return luaL_error(l, "invalid second key binding given to Input.SetKeyBinding"); - } else kb2.Clear(); + } else + kb2.Clear(); binding->axis = ab; binding->positive = kb1; @@ -247,27 +251,28 @@ static int l_input_set_joystick_enabled(lua_State *l) return 0; } -void LuaInput::Register() { - lua_State *l = Lua::manager->GetLuaState(); +void LuaInput::Register() +{ + lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); - static const luaL_Reg l_methods[] = { - { "EnableBindings", l_input_enable_bindings }, - { "DisableBindings", l_input_disable_bindings }, - { "GetBindings", l_input_get_bindings }, - { "SetActionBinding", l_input_set_action_binding }, - { "SetAxisBinding", l_input_set_axis_binding }, - { "GetMouseYInverted", l_input_get_mouse_y_inverted }, - { "SetMouseYInverted", l_input_set_mouse_y_inverted }, - { "GetJoystickEnabled", l_input_get_joystick_enabled }, - { "SetJoystickEnabled", l_input_set_joystick_enabled }, - { NULL, NULL } - }; + static const luaL_Reg l_methods[] = { + { "EnableBindings", l_input_enable_bindings }, + { "DisableBindings", l_input_disable_bindings }, + { "GetBindings", l_input_get_bindings }, + { "SetActionBinding", l_input_set_action_binding }, + { "SetAxisBinding", l_input_set_axis_binding }, + { "GetMouseYInverted", l_input_get_mouse_y_inverted }, + { "SetMouseYInverted", l_input_set_mouse_y_inverted }, + { "GetJoystickEnabled", l_input_get_joystick_enabled }, + { "SetJoystickEnabled", l_input_set_joystick_enabled }, + { NULL, NULL } + }; - static const luaL_Reg l_attrs[] = { - { NULL, NULL } - }; + static const luaL_Reg l_attrs[] = { + { NULL, NULL } + }; lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports"); LuaObjectBase::CreateObject(l_methods, l_attrs, 0); diff --git a/src/LuaInput.h b/src/LuaInput.h index ef5425a7f..d0959f92b 100644 --- a/src/LuaInput.h +++ b/src/LuaInput.h @@ -5,7 +5,7 @@ #define LUAINPUT_H namespace LuaInput { - void Register(); + void Register(); } #endif diff --git a/src/LuaJson.cpp b/src/LuaJson.cpp index 1e9ffc06f..5c56f6ee4 100644 --- a/src/LuaJson.cpp +++ b/src/LuaJson.cpp @@ -2,82 +2,84 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaJson.h" -#include "LuaUtils.h" -#include "LuaObject.h" -#include "JsonUtils.h" #include "FileSystem.h" +#include "JsonUtils.h" +#include "LuaObject.h" +#include "LuaUtils.h" #include "Pi.h" // Do a simple JSON->Lua translation. static void _push_json_to_lua(lua_State *l, Json &obj) { - lua_checkstack(l, 20); + lua_checkstack(l, 20); - switch(obj.type()) { - case Json::value_t::string: { - lua_pushstring(l, obj.get().c_str()); - } break; - case Json::value_t::boolean: { - lua_pushboolean(l, obj.get()); - } break; - case Json::value_t::null: - default: { - lua_pushnil(l); - } break; - case Json::value_t::number_integer: - case Json::value_t::number_unsigned: { - lua_pushinteger(l, obj); - } break; - case Json::value_t::number_float: { - lua_pushnumber(l, obj); - } break; - case Json::value_t::array: { - lua_newtable(l); - size_t size = obj.size(); - lua_pushinteger(l, size); - lua_setfield(l, -2, "n"); - for (size_t idx = 0; idx < size; idx++) { - lua_pushinteger(l, idx); - _push_json_to_lua(l, obj[idx]); - lua_settable(l, -3); - } - } break; - case Json::value_t::object: { - lua_newtable(l); - for (Json::iterator it = obj.begin(); it != obj.end(); it++) { - lua_pushstring(l, it.key().c_str()); - _push_json_to_lua(l, it.value()); - lua_settable(l, -3); - } - } break; - } + switch (obj.type()) { + case Json::value_t::string: { + lua_pushstring(l, obj.get().c_str()); + } break; + case Json::value_t::boolean: { + lua_pushboolean(l, obj.get()); + } break; + case Json::value_t::null: + default: { + lua_pushnil(l); + } break; + case Json::value_t::number_integer: + case Json::value_t::number_unsigned: { + lua_pushinteger(l, obj); + } break; + case Json::value_t::number_float: { + lua_pushnumber(l, obj); + } break; + case Json::value_t::array: { + lua_newtable(l); + size_t size = obj.size(); + lua_pushinteger(l, size); + lua_setfield(l, -2, "n"); + for (size_t idx = 0; idx < size; idx++) { + lua_pushinteger(l, idx); + _push_json_to_lua(l, obj[idx]); + lua_settable(l, -3); + } + } break; + case Json::value_t::object: { + lua_newtable(l); + for (Json::iterator it = obj.begin(); it != obj.end(); it++) { + lua_pushstring(l, it.key().c_str()); + _push_json_to_lua(l, it.value()); + lua_settable(l, -3); + } + } break; + } } -static int l_load_json(lua_State *l) { - std::string filename = luaL_checkstring(l, 1); +static int l_load_json(lua_State *l) +{ + std::string filename = luaL_checkstring(l, 1); - Json data = JsonUtils::LoadJsonDataFile(filename); - if (data.is_null()) - return luaL_error(l, "Error loading JSON file %s.", filename.c_str()); + Json data = JsonUtils::LoadJsonDataFile(filename); + if (data.is_null()) + return luaL_error(l, "Error loading JSON file %s.", filename.c_str()); - _push_json_to_lua(l, data); + _push_json_to_lua(l, data); - return 1; + return 1; } -void LuaJson::Register() { - lua_State *l = Lua::manager->GetLuaState(); +void LuaJson::Register() +{ + lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); - static const luaL_Reg l_methods[] = { - { "LoadJson", l_load_json }, - { NULL, NULL } - }; + static const luaL_Reg l_methods[] = { + { "LoadJson", l_load_json }, + { NULL, NULL } + }; - static const luaL_Reg l_attrs[] = { - { NULL, NULL } - }; + static const luaL_Reg l_attrs[] = { + { NULL, NULL } + }; lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports"); LuaObjectBase::CreateObject(l_methods, l_attrs, 0); diff --git a/src/LuaJson.h b/src/LuaJson.h index a8edf420a..401a35972 100644 --- a/src/LuaJson.h +++ b/src/LuaJson.h @@ -5,7 +5,7 @@ #define PI_LUA_JSON_H namespace LuaJson { - void Register(); + void Register(); } #endif diff --git a/src/LuaLang.cpp b/src/LuaLang.cpp index eafcfd417..5addb9fac 100644 --- a/src/LuaLang.cpp +++ b/src/LuaLang.cpp @@ -2,10 +2,10 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaLang.h" +#include "Lang.h" #include "LuaObject.h" #include "LuaUtils.h" #include "Pi.h" -#include "Lang.h" #include static int _resource_index(lua_State *l) @@ -113,7 +113,8 @@ static int l_lang_get_available_languages(lua_State *l) int i = 1; for (std::vector::const_iterator - it = langs.begin(); it != langs.end(); ++it) { + it = langs.begin(); + it != langs.end(); ++it) { lua_pushlstring(l, it->c_str(), it->size()); lua_rawseti(l, -2, i); @@ -157,9 +158,9 @@ void LuaLang::Register() LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "GetResource", l_lang_get_resource }, + { "GetResource", l_lang_get_resource }, { "GetAvailableLanguages", l_lang_get_available_languages }, - { "SetCurrentLanguage", l_lang_set_current_language }, + { "SetCurrentLanguage", l_lang_set_current_language }, { 0, 0 } }; diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index 5f55e4fe1..ae79fabcb 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -7,7 +7,9 @@ bool instantiated = false; -LuaManager::LuaManager() : m_lua(0) { +LuaManager::LuaManager() : + m_lua(0) +{ if (instantiated) { Output("Can't instantiate more than one LuaManager"); abort(); @@ -20,18 +22,21 @@ LuaManager::LuaManager() : m_lua(0) { instantiated = true; } -LuaManager::~LuaManager() { +LuaManager::~LuaManager() +{ lua_close(m_lua); instantiated = false; } -size_t LuaManager::GetMemoryUsage() const { +size_t LuaManager::GetMemoryUsage() const +{ int kb = lua_gc(m_lua, LUA_GCCOUNT, 0); int b = lua_gc(m_lua, LUA_GCCOUNTB, 0); return (size_t(kb) * 1024) + b; } -void LuaManager::CollectGarbage() { +void LuaManager::CollectGarbage() +{ lua_gc(m_lua, LUA_GCCOLLECT, 0); } diff --git a/src/LuaMatrix.cpp b/src/LuaMatrix.cpp index e9b503623..7244df74f 100644 --- a/src/LuaMatrix.cpp +++ b/src/LuaMatrix.cpp @@ -1,10 +1,10 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "LuaMatrix.h" -#include "LuaVector.h" #include "LuaUtils.h" +#include "LuaVector.h" +#include "libs.h" static int l_matrix_new(lua_State *L) { @@ -27,8 +27,8 @@ static int l_matrix_new(lua_State *L) (*out)[13] = v4.y; (*out)[14] = v4.z; } else if (n == 16) { - for (int i=0; i<16; i++) { - (*out)[i] = luaL_checknumber(L, i+1); + for (int i = 0; i < 16; i++) { + (*out)[i] = luaL_checknumber(L, i + 1); } } else { luaL_error(L, "bad arguments to matrix.new"); @@ -101,7 +101,7 @@ static int l_matrix_print(lua_State *L) } #endif -static int l_matrix_add (lua_State *L) +static int l_matrix_add(lua_State *L) { const matrix4x4f *a = LuaMatrix::CheckFromLua(L, 1); const matrix4x4f *b = LuaMatrix::CheckFromLua(L, 2); @@ -109,7 +109,7 @@ static int l_matrix_add (lua_State *L) return 1; } -static int l_matrix_sub (lua_State *L) +static int l_matrix_sub(lua_State *L) { const matrix4x4f *a = LuaMatrix::CheckFromLua(L, 1); const matrix4x4f *b = LuaMatrix::CheckFromLua(L, 2); @@ -117,16 +117,16 @@ static int l_matrix_sub (lua_State *L) return 1; } -static int l_matrix_unm (lua_State *L) +static int l_matrix_unm(lua_State *L) { const matrix4x4f *m = LuaMatrix::CheckFromLua(L, 1); LuaMatrix::PushToLua(L, -(*m)); return 1; } -static int l_matrix_mul (lua_State *L) +static int l_matrix_mul(lua_State *L) { - if (lua_isnumber(L,1)) { + if (lua_isnumber(L, 1)) { double scale = lua_tonumber(L, 1); const matrix4x4f *m = LuaMatrix::CheckFromLua(L, 2); LuaMatrix::PushToLua(L, scale * *m); @@ -151,7 +151,7 @@ static int l_matrix_mul (lua_State *L) } } -static int l_matrix_div (lua_State *L) +static int l_matrix_div(lua_State *L) { const matrix4x4f *a = LuaMatrix::CheckFromLua(L, 1); double scale = luaL_checknumber(L, 2); @@ -213,17 +213,17 @@ void LuaMatrix::Register(lua_State *L) matrix4x4f *LuaMatrix::PushNewToLua(lua_State *L) { - matrix4x4f *v = static_cast(lua_newuserdata(L, sizeof(matrix4x4f))); + matrix4x4f *v = static_cast(lua_newuserdata(L, sizeof(matrix4x4f))); luaL_setmetatable(L, LuaMatrix::TypeName); return v; } const matrix4x4f *LuaMatrix::GetFromLua(lua_State *L, int idx) { - return static_cast(luaL_testudata(L, idx, LuaMatrix::TypeName)); + return static_cast(luaL_testudata(L, idx, LuaMatrix::TypeName)); } const matrix4x4f *LuaMatrix::CheckFromLua(lua_State *L, int idx) { - return static_cast(luaL_checkudata(L, idx, LuaMatrix::TypeName)); + return static_cast(luaL_checkudata(L, idx, LuaMatrix::TypeName)); } diff --git a/src/LuaMatrix.h b/src/LuaMatrix.h index 1c881e760..aae7de764 100644 --- a/src/LuaMatrix.h +++ b/src/LuaMatrix.h @@ -13,9 +13,13 @@ namespace LuaMatrix { void Register(lua_State *L); matrix4x4f *PushNewToLua(lua_State *L); - inline void PushToLua(lua_State *L, const matrix4x4f &m) { matrix4x4f *v = PushNewToLua(L); *v = m; } + inline void PushToLua(lua_State *L, const matrix4x4f &m) + { + matrix4x4f *v = PushNewToLua(L); + *v = m; + } const matrix4x4f *GetFromLua(lua_State *L, int index); const matrix4x4f *CheckFromLua(lua_State *L, int index); -} +} // namespace LuaMatrix #endif diff --git a/src/LuaMissile.cpp b/src/LuaMissile.cpp index a2952fca2..13d28f84e 100644 --- a/src/LuaMissile.cpp +++ b/src/LuaMissile.cpp @@ -30,7 +30,7 @@ */ static int l_missile_arm(lua_State *l) { - Missile * m = LuaMissile::CheckFromLua(1); + Missile *m = LuaMissile::CheckFromLua(1); m->Arm(); return 0; } @@ -52,7 +52,7 @@ static int l_missile_arm(lua_State *l) */ static int l_missile_disarm(lua_State *l) { - Missile * m = LuaMissile::CheckFromLua(1); + Missile *m = LuaMissile::CheckFromLua(1); m->Disarm(); return 0; } @@ -117,20 +117,22 @@ static int l_missile_ai_kamikaze(lua_State *l) */ static int l_missile_attr_is_armed(lua_State *l) { - Missile * m = LuaMissile::CheckFromLua(1); + Missile *m = LuaMissile::CheckFromLua(1); lua_pushboolean(l, m->IsArmed()); return 1; } -template <> const char *LuaObject::s_type = "Missile"; +template <> +const char *LuaObject::s_type = "Missile"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "ModelBody"; // "DynamicBody"; static const luaL_Reg l_methods[] = { - { "Arm", l_missile_arm }, - { "Disarm", l_missile_disarm }, + { "Arm", l_missile_arm }, + { "Disarm", l_missile_disarm }, { "AIKamikaze", l_missile_ai_kamikaze }, { 0, 0 } }; diff --git a/src/LuaModelBody.cpp b/src/LuaModelBody.cpp index 33964071c..a53fb67f6 100644 --- a/src/LuaModelBody.cpp +++ b/src/LuaModelBody.cpp @@ -13,19 +13,20 @@ class LuaModelBody { public: - static int l_attr_model(lua_State *l) { ModelBody *mb = LuaObject::CheckFromLua(1); LuaObject::PushToLua(mb->GetModel()); return 1; } - }; -template <> const char *LuaObject::s_type = "ModelBody"; +template <> +const char *LuaObject::s_type = "ModelBody"; -template <> void LuaObject::RegisterClass() { +template <> +void LuaObject::RegisterClass() +{ const char *l_parent = "Body"; static luaL_Reg l_attrs[] = { diff --git a/src/LuaMusic.cpp b/src/LuaMusic.cpp index 2b8782655..706524692 100644 --- a/src/LuaMusic.cpp +++ b/src/LuaMusic.cpp @@ -195,8 +195,8 @@ static int l_music_fade_out(lua_State *l) */ static int l_music_get_song_list(lua_State *l) { - using std::vector; using std::string; + using std::vector; const vector vec = Pi::GetMusicPlayer().GetSongList(); lua_newtable(l); int idx = 1; @@ -239,15 +239,15 @@ void LuaMusic::Register() LUA_DEBUG_START(l); - static const luaL_Reg l_methods[]= { + static const luaL_Reg l_methods[] = { { "GetSongName", l_music_get_song }, { "GetSongList", l_music_get_song_list }, { "Play", l_music_play }, - { "Stop", l_music_stop}, + { "Stop", l_music_stop }, { "FadeIn", l_music_fade_in }, { "FadeOut", l_music_fade_out }, { "IsPlaying", l_music_is_playing }, - {0, 0} + { 0, 0 } }; lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports"); diff --git a/src/LuaNameGen.cpp b/src/LuaNameGen.cpp index 93d58a668..2bf5bb14d 100644 --- a/src/LuaNameGen.cpp +++ b/src/LuaNameGen.cpp @@ -3,8 +3,8 @@ #include "LuaNameGen.h" #include "LuaObject.h" -#include "galaxy/StarSystem.h" #include "Random.h" +#include "galaxy/StarSystem.h" static const std::string DEFAULT_FULL_NAME_MALE("Tom Morton"); static const std::string DEFAULT_FULL_NAME_FEMALE("Thomasina Mortonella"); diff --git a/src/LuaNameGen.h b/src/LuaNameGen.h index 49cce458f..f4ffbb144 100644 --- a/src/LuaNameGen.h +++ b/src/LuaNameGen.h @@ -13,7 +13,8 @@ class SystemBody; class LuaNameGen { public: - LuaNameGen(LuaManager *manager): m_luaManager(manager) {} + LuaNameGen(LuaManager *manager) : + m_luaManager(manager) {} std::string FullName(bool isFemale, RefCountedPtr &rng); std::string Surname(RefCountedPtr &rng); diff --git a/src/LuaObject.cpp b/src/LuaObject.cpp index 4ec66cc1d..09da9cd32 100644 --- a/src/LuaObject.cpp +++ b/src/LuaObject.cpp @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "LuaObject.h" +#include "Json.h" #include "LuaUtils.h" #include "PropertiedObject.h" #include "PropertyMap.h" -#include "Json.h" +#include "libs.h" #include #include @@ -94,18 +94,20 @@ // singleton is. This will cause LuaObject to crash during garbage collection static bool instantiated = false; -static std::map< std::string, std::map > *promotions; -static std::map< std::string, SerializerPair > *serializers; +static std::map> *promotions; +static std::map *serializers; -static void _teardown() { +static void _teardown() +{ delete promotions; delete serializers; } -static inline void _instantiate() { +static inline void _instantiate() +{ if (!instantiated) { - promotions = new std::map< std::string, std::map >; - serializers = new std::map< std::string, SerializerPair >; + promotions = new std::map>; + serializers = new std::map; // XXX atexit is not a very nice way to deal with this in C++ atexit(_teardown); @@ -117,7 +119,7 @@ static inline void _instantiate() { int LuaObjectBase::l_exists(lua_State *l) { luaL_checktype(l, 1, LUA_TUSERDATA); - LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); lua_pushboolean(l, lo->GetObject() != 0); return 1; } @@ -150,12 +152,12 @@ int LuaObjectBase::l_unsetprop(lua_State *l) if (lua_isnil(l, -1)) return luaL_error(l, "Object has no property map"); - LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); LuaWrappable *o = lo->GetObject(); if (!o) return luaL_error(l, "Object is no longer valid"); - PropertiedObject *po = dynamic_cast(o); + PropertiedObject *po = dynamic_cast(o); assert(po); po->Properties().PushLuaTable(); @@ -182,12 +184,12 @@ int LuaObjectBase::l_setprop(lua_State *l) if (lua_isnil(l, -1)) return luaL_error(l, "Object has no property map"); - LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); LuaWrappable *o = lo->GetObject(); if (!o) return luaL_error(l, "Object is no longer valid"); - PropertiedObject *po = dynamic_cast(o); + PropertiedObject *po = dynamic_cast(o); assert(po); if (isnum) @@ -201,7 +203,7 @@ int LuaObjectBase::l_setprop(lua_State *l) int LuaObjectBase::l_isa(lua_State *l) { luaL_checktype(l, 1, LUA_TUSERDATA); - LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); if (!lo->GetObject()) return luaL_error(l, "Object is no longer valid"); @@ -212,7 +214,7 @@ int LuaObjectBase::l_isa(lua_State *l) int LuaObjectBase::l_gc(lua_State *l) { luaL_checktype(l, 1, LUA_TUSERDATA); - LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, 1)); Deregister(lo); @@ -240,28 +242,28 @@ static void get_next_method_table(lua_State *l) // get the type from the table lua_pushstring(l, "type"); - lua_rawget(l, -2); // object, metatable, type + lua_rawget(l, -2); // object, metatable, type const std::string type(lua_tostring(l, -1)); - lua_pop(l, 1); // object, metatable - pi_lua_split_table_path(l, type); // object, metatable, "global" table, leaf type name - lua_rawget(l, -2); // object, metatable, "global" table, method table - lua_remove(l, -2); // object, metatable, method table + lua_pop(l, 1); // object, metatable + pi_lua_split_table_path(l, type); // object, metatable, "global" table, leaf type name + lua_rawget(l, -2); // object, metatable, "global" table, method table + lua_remove(l, -2); // object, metatable, method table // see if the metatable has a parent lua_pushstring(l, "parent"); - lua_rawget(l, -3); // object, metatable, method table, parent type + lua_rawget(l, -3); // object, metatable, method table, parent type // it does, lets fetch it if (!lua_isnil(l, -1)) { lua_rawget(l, LUA_REGISTRYINDEX); // object, metatable, method table, parent metatable - lua_replace(l, -3); // object, parent metatable, method table + lua_replace(l, -3); // object, parent metatable, method table LUA_DEBUG_END(l, 1); return; } // no parent - // object, metatable, method table, nil + // object, metatable, method table, nil lua_replace(l, -3); // object, nil, method table LUA_DEBUG_END(l, 1); @@ -286,7 +288,7 @@ static bool get_method_or_attr(lua_State *l) lua_pop(l, 1); // didn't find a method, so now we go looking for an attribute handler - lua_pushstring(l, (std::string("__attribute_")+lua_tostring(l, -1)).c_str()); + lua_pushstring(l, (std::string("__attribute_") + lua_tostring(l, -1)).c_str()); lua_rawget(l, -3); // found something, return it @@ -431,7 +433,7 @@ void LuaObjectBase::GetNames(std::vector &names, const std::string if (typeless) { // Check the metatable indexes lua_pushvalue(l, -1); - while(lua_getmetatable(l, -1)) { + while (lua_getmetatable(l, -1)) { lua_pushstring(l, "__index"); lua_gettable(l, -2); @@ -564,12 +566,12 @@ void LuaObjectBase::CreateClass(const char *type, const char *parent, const luaL // create table, attach methods to it, leave it on the stack lua_newtable(l); - if (methods) luaL_setfuncs(l, methods, 0); + if (methods) luaL_setfuncs(l, methods, 0); // add attributes if (attrs) { for (const luaL_Reg *attr = attrs; attr->name; attr++) { - lua_pushstring(l, (std::string("__attribute_")+attr->name).c_str()); + lua_pushstring(l, (std::string("__attribute_") + attr->name).c_str()); lua_pushcfunction(l, attr->func); lua_rawset(l, -3); } @@ -690,15 +692,14 @@ void LuaObjectBase::Register(LuaObjectBase *lo) bool tried_promote = false; while (have_promotions && !tried_promote) { - std::map< std::string, std::map >::const_iterator base_iter = promotions->find(lo->m_type); + std::map>::const_iterator base_iter = promotions->find(lo->m_type); if (base_iter != promotions->end()) { tried_promote = true; for ( - std::map::const_iterator target_iter = (*base_iter).second.begin(); + std::map::const_iterator target_iter = (*base_iter).second.begin(); target_iter != (*base_iter).second.end(); - ++target_iter) - { + ++target_iter) { if ((*target_iter).second(lo->GetObject())) { lo->m_type = (*target_iter).first.c_str(); tried_promote = false; @@ -706,27 +707,26 @@ void LuaObjectBase::Register(LuaObjectBase *lo) } assert(lo->Isa((*base_iter).first.c_str())); - } - else + } else have_promotions = false; } lua_State *l = Lua::manager->GetLuaState(); - LUA_DEBUG_START(l); // lo userdata + LUA_DEBUG_START(l); // lo userdata - lua_getfield(l, LUA_REGISTRYINDEX, "LuaObjectRegistry"); // lo userdata, registry table + lua_getfield(l, LUA_REGISTRYINDEX, "LuaObjectRegistry"); // lo userdata, registry table assert(lua_istable(l, -1)); - lua_pushlightuserdata(l, lo->GetObject()); // lo userdata, registry table, o lightuserdata - lua_pushvalue(l, -3); // lo userdata, registry table, o lightuserdata, lo userdata - lua_settable(l, -3); // lo userdata, registry table + lua_pushlightuserdata(l, lo->GetObject()); // lo userdata, registry table, o lightuserdata + lua_pushvalue(l, -3); // lo userdata, registry table, o lightuserdata, lo userdata + lua_settable(l, -3); // lo userdata, registry table - lua_pop(l, 1); // lo userdata + lua_pop(l, 1); // lo userdata - luaL_getmetatable(l, lo->m_type); // lo userdata, lo metatable + luaL_getmetatable(l, lo->m_type); // lo userdata, lo metatable - lua_pushvalue(l, -1); // Copy the metatable to begin the search. + lua_pushvalue(l, -1); // Copy the metatable to begin the search. // Now let's go digging around to find a suitable constructor. // Shameless lift from l_dispatch_index @@ -758,19 +758,18 @@ void LuaObjectBase::Register(LuaObjectBase *lo) // // attach properties table if available - PropertiedObject *po = dynamic_cast(lo->GetObject()); + PropertiedObject *po = dynamic_cast(lo->GetObject()); if (po) { po->Properties().PushLuaTable(); lua_setuservalue(l, -4); } - // Call the lua constructor if it ain't nil // We didn't do this when we got it, because one might want to use the nice stuff // such as the properties in the bloody constructor. Setprop, anyone? :) if (lua_isfunction(l, -1)) { - lua_pushvalue(l, -3); // lo userdata, lo mt, cons, lo userdata - lua_call(l, 1, 0); // lo userdata, lo mt + lua_pushvalue(l, -3); // lo userdata, lo mt, cons, lo userdata + lua_call(l, 1, 0); // lo userdata, lo mt lua_pop(l, 1); // Pop the metatable, we're done with it } else { lua_pop(l, 2); // Pop the junk AND the metatable. @@ -808,7 +807,7 @@ LuaWrappable *LuaObjectBase::CheckFromLua(int index, const char *type) lua_State *l = Lua::manager->GetLuaState(); luaL_checktype(l, index, LUA_TUSERDATA); - LuaObjectBase *lo = static_cast(lua_touserdata(l, index)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, index)); LuaWrappable *o = lo->GetObject(); if (!o) { @@ -832,7 +831,7 @@ LuaWrappable *LuaObjectBase::GetFromLua(int index, const char *type) if (lua_type(l, index) != LUA_TUSERDATA) return 0; - LuaObjectBase *lo = static_cast(lua_touserdata(l, index)); + LuaObjectBase *lo = static_cast(lua_touserdata(l, index)); LuaWrappable *o = lo->GetObject(); if (!o) @@ -960,7 +959,8 @@ bool LuaObjectBase::FromJson(const Json &obj) return it->second.from_json(obj["inner"]); } -void *LuaObjectBase::Allocate(size_t n) { +void *LuaObjectBase::Allocate(size_t n) +{ lua_State *l = Lua::manager->GetLuaState(); return lua_newuserdata(l, n); } diff --git a/src/LuaObject.h b/src/LuaObject.h index bd5f52dba..50383ba9e 100644 --- a/src/LuaObject.h +++ b/src/LuaObject.h @@ -4,15 +4,15 @@ #ifndef _LUAOBJECT_H #define _LUAOBJECT_H +#include "DeleteEmitter.h" #include "Lua.h" -#include "LuaRef.h" #include "LuaPushPull.h" +#include "LuaRef.h" #include "LuaUtils.h" #include "LuaWrappable.h" #include "RefCounted.h" -#include "DeleteEmitter.h" -#include #include +#include // // LuaObject provides proxy objects and tracking facilities to safely get @@ -64,7 +64,6 @@ // - Add the new file to the build system // - // type for promotion test callbacks typedef bool (*PromotionTest)(LuaWrappable *o); @@ -84,8 +83,8 @@ struct SerializerPair { {} SerializerPair( - Serializer serialize_, Deserializer deserialize_, - ToJson to_json_, FromJson from_json_): + Serializer serialize_, Deserializer deserialize_, + ToJson to_json_, FromJson from_json_) : serialize(serialize_), deserialize(deserialize_), to_json(to_json_), @@ -98,7 +97,6 @@ struct SerializerPair { FromJson from_json; }; - // wrapper baseclass, and extra bits for getting at certain parts of the // LuaObject layer class LuaObjectBase { @@ -117,7 +115,8 @@ public: protected: // base class constructor, called by the wrapper Push* methods - LuaObjectBase(const char *type) : m_type(type) {}; + LuaObjectBase(const char *type) : + m_type(type){}; virtual ~LuaObjectBase() {} // creates a class in the lua vm with the given name and attaches the @@ -162,11 +161,11 @@ protected: void ToJson(Json &out); static bool FromJson(const Json &obj); - // allocate n bytes from Lua memory and leave it an associated userdata on - // the stack. this is a wrapper around lua_newuserdata + // allocate n bytes from Lua memory and leave it an associated userdata on + // the stack. this is a wrapper around lua_newuserdata static void *Allocate(size_t n); - // get a pointer to the underlying object + // get a pointer to the underlying object virtual LuaWrappable *GetObject() const = 0; const char *GetType() const { return m_type; } @@ -202,68 +201,68 @@ private: // __index metamethod static int l_dispatch_index(lua_State *l); - // determine if the object has a class in its ancestry - bool Isa(const char *base) const; + // determine if the object has a class in its ancestry + bool Isa(const char *base) const; // lua type (ie method/metatable name) const char *m_type; }; - // templated portion of the wrapper baseclass template class LuaObject : public LuaObjectBase { public: - // registers the class with the lua vm static void RegisterClass(); // wrap an object and push it onto the stack. these create a wrapper // object that knows how to deal with the type of object static inline void PushToLua(DeleteEmitter *o); // LuaCoreObject - static inline void PushToLua(RefCounted *o); // LuaSharedObject - static inline void PushToLua(const T &o); // LuaCopyObject + static inline void PushToLua(RefCounted *o); // LuaSharedObject + static inline void PushToLua(const T &o); // LuaCopyObject - template - static inline Ret CallMethod(T* o, const Key &key, const Args &...args); - template - static inline void CallMethod(T* o, const Key &key, const Args &...args) { - CallMethod(o, key, args...); - } + template + static inline Ret CallMethod(T *o, const Key &key, const Args &... args); + template + static inline void CallMethod(T *o, const Key &key, const Args &... args) + { + CallMethod(o, key, args...); + } - template - static inline std::tuple CallMethod(T* o, const Key &key, const Args &...args); + template + static inline std::tuple CallMethod(T *o, const Key &key, const Args &... args); // pull an object off the stack, unwrap and return it // if not found or doesn't match the type, throws a lua exception - static inline T *CheckFromLua(int idx) { + static inline T *CheckFromLua(int idx) + { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundefined-var-template" #endif - return dynamic_cast(LuaObjectBase::CheckFromLua(idx, s_type)); + return dynamic_cast(LuaObjectBase::CheckFromLua(idx, s_type)); #ifdef __clang__ #pragma clang diagnostic pop #endif - } // same but without error checks. returns 0 on failure - static inline T *GetFromLua(int idx) { + static inline T *GetFromLua(int idx) + { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundefined-var-template" #endif - return dynamic_cast(LuaObjectBase::GetFromLua(idx, s_type)); + return dynamic_cast(LuaObjectBase::GetFromLua(idx, s_type)); #ifdef __clang__ #pragma clang diagnostic pop #endif - } // standard cast promotion test for convenience - static inline bool DynamicCastPromotionTest(LuaWrappable *o) { - return dynamic_cast(o); + static inline bool DynamicCastPromotionTest(LuaWrappable *o) + { + return dynamic_cast(o); } protected: @@ -271,7 +270,9 @@ protected: #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundefined-var-template" #endif - LuaObject() : LuaObjectBase(s_type) {} + LuaObject() : + LuaObjectBase(s_type) + {} #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -288,21 +289,26 @@ private: template class LuaCoreObject : public LuaObject { public: - LuaCoreObject(T *o) : m_object(o) { + LuaCoreObject(T *o) : + m_object(o) + { m_deleteConnection = m_object->DeleteEmitter::onDelete.connect(sigc::mem_fun(this, &LuaCoreObject::OnDelete)); } - ~LuaCoreObject() { + ~LuaCoreObject() + { if (m_deleteConnection.connected()) m_deleteConnection.disconnect(); } - LuaWrappable *GetObject() const { + LuaWrappable *GetObject() const + { return m_object; } private: - void OnDelete() { + void OnDelete() + { LuaObjectBase::Deregister(this); m_object = 0; } @@ -311,7 +317,6 @@ private: sigc::connection m_deleteConnection; }; - // wrapper for a "shared" object - one that can comfortably exist in both // environments. usually for long-lived (StarSystem) or standalone (UI // widget) objects @@ -319,9 +324,11 @@ private: template class LuaSharedObject : public LuaObject { public: - LuaSharedObject(T *o) : m_object(o) {} + LuaSharedObject(T *o) : + m_object(o) {} - LuaWrappable *GetObject() const { + LuaWrappable *GetObject() const + { return m_object.Get(); } @@ -329,26 +336,28 @@ private: RefCountedPtr m_object; }; - // wrapper for a "copied" object. a new one is created via the copy // constructor and fully owned by Lua. good for lightweight POD-style objects // (eg SystemPath) template class LuaCopyObject : public LuaObject { public: - LuaCopyObject(const T &o) { + LuaCopyObject(const T &o) + { lua_State *l = Lua::manager->GetLuaState(); m_object = new (LuaObjectBase::Allocate(sizeof(T))) T(o); m_ref = LuaRef(l, -1); lua_pop(l, 1); } - ~LuaCopyObject() { + ~LuaCopyObject() + { m_object->~T(); m_object = 0; } - LuaWrappable *GetObject() const { + LuaWrappable *GetObject() const + { return m_object; } @@ -357,38 +366,44 @@ private: LuaRef m_ref; }; - // push methods, create wrappers if necessary // wrappers are allocated from Lua memory -template inline void LuaObject::PushToLua(DeleteEmitter *o) { +template +inline void LuaObject::PushToLua(DeleteEmitter *o) +{ if (!PushRegistered(o)) - Register(new (LuaObjectBase::Allocate(sizeof(LuaCoreObject))) LuaCoreObject(static_cast(o))); + Register(new (LuaObjectBase::Allocate(sizeof(LuaCoreObject))) LuaCoreObject(static_cast(o))); } -template inline void LuaObject::PushToLua(RefCounted *o) { +template +inline void LuaObject::PushToLua(RefCounted *o) +{ if (!PushRegistered(o)) - Register(new (LuaObjectBase::Allocate(sizeof(LuaSharedObject))) LuaSharedObject(static_cast(o))); + Register(new (LuaObjectBase::Allocate(sizeof(LuaSharedObject))) LuaSharedObject(static_cast(o))); } -template inline void LuaObject::PushToLua(const T &o) { +template +inline void LuaObject::PushToLua(const T &o) +{ Register(new (LuaObjectBase::Allocate(sizeof(LuaCopyObject))) LuaCopyObject(o)); } template -template -inline Ret LuaObject::CallMethod(T* o, const Key &key, const Args &...args) { +template +inline Ret LuaObject::CallMethod(T *o, const Key &key, const Args &... args) +{ lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); Ret return_value; - lua_checkstack(l, sizeof...(args)+5); + lua_checkstack(l, sizeof...(args) + 5); PushToLua(o); pi_lua_generic_push(l, key); lua_gettable(l, -2); lua_pushvalue(l, -2); lua_remove(l, -3); pi_lua_multiple_push(l, args...); - pi_lua_protected_call(l, sizeof...(args)+1, 1); + pi_lua_protected_call(l, sizeof...(args) + 1, 1); pi_lua_generic_pull(l, -1, return_value); lua_pop(l, 1); LUA_DEBUG_END(l, 0); @@ -396,42 +411,50 @@ inline Ret LuaObject::CallMethod(T* o, const Key &key, const Args &...args) { } template -template -inline std::tuple LuaObject::CallMethod(T* o, const Key &key, const Args &...args) { +template +inline std::tuple LuaObject::CallMethod(T *o, const Key &key, const Args &... args) +{ lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); - lua_checkstack(l, sizeof...(args)+5); + lua_checkstack(l, sizeof...(args) + 5); PushToLua(o); pi_lua_generic_push(l, key); lua_gettable(l, -2); lua_pushvalue(l, -2); lua_remove(l, -3); pi_lua_multiple_push(l, args...); - pi_lua_protected_call(l, sizeof...(args)+1, 2+sizeof...(Ret)); - auto ret_values = pi_lua_multiple_pull(l, -2-static_cast(sizeof...(Ret))); - lua_pop(l, 2+static_cast(sizeof...(Ret))); + pi_lua_protected_call(l, sizeof...(args) + 1, 2 + sizeof...(Ret)); + auto ret_values = pi_lua_multiple_pull(l, -2 - static_cast(sizeof...(Ret))); + lua_pop(l, 2 + static_cast(sizeof...(Ret))); LUA_DEBUG_END(l, 0); return ret_values; } // specialise for SystemPath, which needs custom machinery to deduplicate system paths class SystemPath; -template <> void LuaObject::PushToLua(const SystemPath &o); +template <> +void LuaObject::PushToLua(const SystemPath &o); // LuaPushPull stuff. -template void pi_lua_generic_pull(lua_State * l, int index, T* & out) { +template +void pi_lua_generic_pull(lua_State *l, int index, T *&out) +{ assert(l == Lua::manager->GetLuaState()); out = LuaObject::CheckFromLua(index); } -template bool pi_lua_strict_pull(lua_State * l, int index, T* & out) { +template +bool pi_lua_strict_pull(lua_State *l, int index, T *&out) +{ assert(l == Lua::manager->GetLuaState()); out = LuaObject::GetFromLua(index); return out != 0; } -template void pi_lua_generic_push(lua_State * l, T* value) { +template +void pi_lua_generic_push(lua_State *l, T *value) +{ assert(l == Lua::manager->GetLuaState()); if (value) LuaObject::PushToLua(value); diff --git a/src/LuaPiGui.cpp b/src/LuaPiGui.cpp index 8b30752f3..fe6747759 100644 --- a/src/LuaPiGui.cpp +++ b/src/LuaPiGui.cpp @@ -2,30 +2,31 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaPiGui.h" -#include "LuaUtils.h" -#include "LuaConstants.h" -#include "PiGui.h" -#include "WorldView.h" -#include "Pi.h" -#include "Game.h" -#include "graphics/Graphics.h" -#include "Player.h" #include "EnumStrings.h" -#include "SystemInfoView.h" +#include "Game.h" +#include "LuaConstants.h" +#include "LuaUtils.h" +#include "Pi.h" +#include "PiGui.h" +#include "Player.h" #include "Sound.h" +#include "SystemInfoView.h" +#include "WorldView.h" +#include "graphics/Graphics.h" #include "ui/Context.h" // Windows defines RegisterClass as a macro, but we don't need that here. // undef it, to avoid including yet another header that undefs it #undef RegisterClass -template -static Type parse_imgui_flags(lua_State *l, int index, std::map table, std::string name) { +template +static Type parse_imgui_flags(lua_State *l, int index, std::map table, std::string name) +{ LuaTable flags(l, index); Type theflags = Type(0); - for(LuaTable::VecIter iter = flags.Begin(); iter != flags.End(); ++iter) { + for (LuaTable::VecIter iter = flags.Begin(); iter != flags.End(); ++iter) { std::string flag = *iter; - if(table.find(flag) != table.end()) + if (table.find(flag) != table.end()) theflags = static_cast(theflags | table.at(flag)); else Error("Unknown %s %s\n", name.c_str(), flag.c_str()); @@ -34,39 +35,44 @@ static Type parse_imgui_flags(lua_State *l, int index, std::map -static Type parse_imgui_enum(lua_State *l, int index, std::map table, std::string name) { +static Type parse_imgui_enum(lua_State *l, int index, std::map table, std::string name) +{ std::string stylestr = LuaPull(l, index); - if(table.find(stylestr) != table.end()) + if (table.find(stylestr) != table.end()) return table.at(stylestr); else Error("Unknown %s %s\n", name.c_str(), stylestr.c_str()); return static_cast(0); } -void *pi_lua_checklightuserdata(lua_State *l, int index) { - if(lua_islightuserdata(l, index)) +void *pi_lua_checklightuserdata(lua_State *l, int index) +{ + if (lua_islightuserdata(l, index)) return lua_touserdata(l, index); else Error("Expected light user data at index %d, but got %s", index, lua_typename(l, index)); return nullptr; } -void pi_lua_generic_pull(lua_State *l, int index, ImVec2 &vector) { +void pi_lua_generic_pull(lua_State *l, int index, ImVec2 &vector) +{ LuaTable vec(l, index); vector.x = vec.Get("x"); vector.y = vec.Get("y"); } -void pi_lua_generic_pull(lua_State *l, int index, vector3d &vector) { +void pi_lua_generic_pull(lua_State *l, int index, vector3d &vector) +{ LuaTable vec(l, index); vector.x = vec.Get("x"); vector.y = vec.Get("y"); vector.z = vec.Get("z"); } -void pi_lua_generic_pull(lua_State *l, int index, ImColor &color) { +void pi_lua_generic_pull(lua_State *l, int index, ImColor &color) +{ LuaTable c(l, index); - float sc = 1.0f/255.0f; + float sc = 1.0f / 255.0f; color.Value.x = c.Get("r") * sc; color.Value.y = c.Get("g") * sc; color.Value.z = c.Get("b") * sc; @@ -78,7 +84,7 @@ int pushOnScreenPositionDirection(lua_State *l, vector3d position) const int width = Graphics::GetScreenWidth(); const int height = Graphics::GetScreenHeight(); vector3d direction = (position - vector3d(width / 2, height / 2, 0)).Normalized(); - if(vector3d(0,0,0) == position || position.x < 0 || position.y < 0 || position.x > width || position.y > height || position.z > 0) { + if (vector3d(0, 0, 0) == position || position.x < 0 || position.y < 0 || position.x > width || position.y > height || position.z > 0) { LuaPush(l, false); LuaPush(l, vector3d(0, 0, 0)); LuaPush(l, direction * (position.z > 0 ? -1 : 1)); // reverse direction if behind camera @@ -90,19 +96,18 @@ int pushOnScreenPositionDirection(lua_State *l, vector3d position) return 3; } -static std::map imguiSelectableFlagsTable -= { +static std::map imguiSelectableFlagsTable = { { "DontClosePopups", ImGuiSelectableFlags_DontClosePopups }, { "SpanAllColumns", ImGuiSelectableFlags_SpanAllColumns }, { "AllowDoubleClick", ImGuiSelectableFlags_AllowDoubleClick } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiSelectableFlags_ &theflags) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiSelectableFlags_ &theflags) +{ theflags = parse_imgui_flags(l, index, imguiSelectableFlagsTable, "ImGuiSelectableFlags"); } -static std::map imguiTreeNodeFlagsTable -= { +static std::map imguiTreeNodeFlagsTable = { { "Selected", ImGuiTreeNodeFlags_Selected }, { "Framed", ImGuiTreeNodeFlags_Framed }, { "AllowOverlapMode", ImGuiTreeNodeFlags_AllowOverlapMode }, @@ -116,12 +121,12 @@ static std::map imguiTreeNodeFlagsTable { "CollapsingHeader", ImGuiTreeNodeFlags_CollapsingHeader }, }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiTreeNodeFlags_ &theflags) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiTreeNodeFlags_ &theflags) +{ theflags = parse_imgui_flags(l, index, imguiTreeNodeFlagsTable, "ImGuiTreeNodeFlags"); } -static std::map imguiInputTextFlagsTable -= { +static std::map imguiInputTextFlagsTable = { { "CharsDecimal", ImGuiInputTextFlags_CharsDecimal }, { "CharsHexadecimal", ImGuiInputTextFlags_CharsHexadecimal }, { "CharsUppercase", ImGuiInputTextFlags_CharsUppercase }, @@ -140,94 +145,94 @@ static std::map imguiInputTextFlagsTable { "Password", ImGuiInputTextFlags_Password } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiInputTextFlags_ &theflags) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiInputTextFlags_ &theflags) +{ theflags = parse_imgui_flags(l, index, imguiInputTextFlagsTable, "ImGuiInputTextFlagsTable"); } -static std::map imguiSetCondTable -= { +static std::map imguiSetCondTable = { { "Always", ImGuiCond_Always }, { "Once", ImGuiCond_Once }, { "FirstUseEver", ImGuiCond_FirstUseEver }, { "Appearing", ImGuiCond_Appearing } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiCond_ &value) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiCond_ &value) +{ value = parse_imgui_enum(l, index, imguiSetCondTable, "ImGuiCond"); } -static std::map imguiColTable -= { - {"Text", ImGuiCol_Text}, - {"TextDisabled", ImGuiCol_TextDisabled}, - {"WindowBg", ImGuiCol_WindowBg}, - {"ChildWindowBg", ImGuiCol_ChildWindowBg}, - {"PopupBg", ImGuiCol_PopupBg}, - {"Border", ImGuiCol_Border}, - {"BorderShadow", ImGuiCol_BorderShadow}, - {"FrameBg", ImGuiCol_FrameBg}, - {"FrameBgHovered", ImGuiCol_FrameBgHovered}, - {"FrameBgActive", ImGuiCol_FrameBgActive}, - {"TitleBg", ImGuiCol_TitleBg}, - {"TitleBgCollapsed", ImGuiCol_TitleBgCollapsed}, - {"TitleBgActive", ImGuiCol_TitleBgActive}, - {"MenuBarBg", ImGuiCol_MenuBarBg}, - {"ScrollbarBg", ImGuiCol_ScrollbarBg}, - {"ScrollbarGrab", ImGuiCol_ScrollbarGrab}, - {"ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered}, - {"ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive}, - {"CheckMark", ImGuiCol_CheckMark}, - {"SliderGrab", ImGuiCol_SliderGrab}, - {"SliderGrabActive", ImGuiCol_SliderGrabActive}, - {"Button", ImGuiCol_Button}, - {"ButtonHovered", ImGuiCol_ButtonHovered}, - {"ButtonActive", ImGuiCol_ButtonActive}, - {"Header", ImGuiCol_Header}, - {"HeaderHovered", ImGuiCol_HeaderHovered}, - {"HeaderActive", ImGuiCol_HeaderActive}, - {"Column", ImGuiCol_Column}, - {"ColumnHovered", ImGuiCol_ColumnHovered}, - {"ColumnActive", ImGuiCol_ColumnActive}, - {"ResizeGrip", ImGuiCol_ResizeGrip}, - {"ResizeGripHovered", ImGuiCol_ResizeGripHovered}, - {"ResizeGripActive", ImGuiCol_ResizeGripActive}, - {"PlotLines", ImGuiCol_PlotLines}, - {"PlotLinesHovered", ImGuiCol_PlotLinesHovered}, - {"PlotHistogram", ImGuiCol_PlotHistogram}, - {"PlotHistogramHovered", ImGuiCol_PlotHistogramHovered}, - {"TextSelectedBg", ImGuiCol_TextSelectedBg}, - {"ModalWindowDarkening", ImGuiCol_ModalWindowDarkening} +static std::map imguiColTable = { + { "Text", ImGuiCol_Text }, + { "TextDisabled", ImGuiCol_TextDisabled }, + { "WindowBg", ImGuiCol_WindowBg }, + { "ChildWindowBg", ImGuiCol_ChildWindowBg }, + { "PopupBg", ImGuiCol_PopupBg }, + { "Border", ImGuiCol_Border }, + { "BorderShadow", ImGuiCol_BorderShadow }, + { "FrameBg", ImGuiCol_FrameBg }, + { "FrameBgHovered", ImGuiCol_FrameBgHovered }, + { "FrameBgActive", ImGuiCol_FrameBgActive }, + { "TitleBg", ImGuiCol_TitleBg }, + { "TitleBgCollapsed", ImGuiCol_TitleBgCollapsed }, + { "TitleBgActive", ImGuiCol_TitleBgActive }, + { "MenuBarBg", ImGuiCol_MenuBarBg }, + { "ScrollbarBg", ImGuiCol_ScrollbarBg }, + { "ScrollbarGrab", ImGuiCol_ScrollbarGrab }, + { "ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered }, + { "ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive }, + { "CheckMark", ImGuiCol_CheckMark }, + { "SliderGrab", ImGuiCol_SliderGrab }, + { "SliderGrabActive", ImGuiCol_SliderGrabActive }, + { "Button", ImGuiCol_Button }, + { "ButtonHovered", ImGuiCol_ButtonHovered }, + { "ButtonActive", ImGuiCol_ButtonActive }, + { "Header", ImGuiCol_Header }, + { "HeaderHovered", ImGuiCol_HeaderHovered }, + { "HeaderActive", ImGuiCol_HeaderActive }, + { "Column", ImGuiCol_Column }, + { "ColumnHovered", ImGuiCol_ColumnHovered }, + { "ColumnActive", ImGuiCol_ColumnActive }, + { "ResizeGrip", ImGuiCol_ResizeGrip }, + { "ResizeGripHovered", ImGuiCol_ResizeGripHovered }, + { "ResizeGripActive", ImGuiCol_ResizeGripActive }, + { "PlotLines", ImGuiCol_PlotLines }, + { "PlotLinesHovered", ImGuiCol_PlotLinesHovered }, + { "PlotHistogram", ImGuiCol_PlotHistogram }, + { "PlotHistogramHovered", ImGuiCol_PlotHistogramHovered }, + { "TextSelectedBg", ImGuiCol_TextSelectedBg }, + { "ModalWindowDarkening", ImGuiCol_ModalWindowDarkening } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiCol_ &value) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiCol_ &value) +{ value = parse_imgui_enum(l, index, imguiColTable, "ImGuiCol"); } -static std::map imguiStyleVarTable -= { - { "Alpha", ImGuiStyleVar_Alpha}, - { "WindowPadding", ImGuiStyleVar_WindowPadding}, - { "WindowRounding", ImGuiStyleVar_WindowRounding}, - { "WindowBorderSize", ImGuiStyleVar_WindowBorderSize}, - { "WindowMinSize", ImGuiStyleVar_WindowMinSize}, - { "ChildRounding", ImGuiStyleVar_ChildRounding}, - { "ChildBorderSize", ImGuiStyleVar_ChildBorderSize}, - { "FramePadding", ImGuiStyleVar_FramePadding}, - { "FrameRounding", ImGuiStyleVar_FrameRounding}, - { "FrameBorderSize", ImGuiStyleVar_FrameBorderSize}, - { "ItemSpacing", ImGuiStyleVar_ItemSpacing}, - { "ItemInnerSpacing", ImGuiStyleVar_ItemInnerSpacing}, - { "IndentSpacing", ImGuiStyleVar_IndentSpacing}, - { "GrabMinSize", ImGuiStyleVar_GrabMinSize}, - { "ButtonTextAlign", ImGuiStyleVar_ButtonTextAlign} +static std::map imguiStyleVarTable = { + { "Alpha", ImGuiStyleVar_Alpha }, + { "WindowPadding", ImGuiStyleVar_WindowPadding }, + { "WindowRounding", ImGuiStyleVar_WindowRounding }, + { "WindowBorderSize", ImGuiStyleVar_WindowBorderSize }, + { "WindowMinSize", ImGuiStyleVar_WindowMinSize }, + { "ChildRounding", ImGuiStyleVar_ChildRounding }, + { "ChildBorderSize", ImGuiStyleVar_ChildBorderSize }, + { "FramePadding", ImGuiStyleVar_FramePadding }, + { "FrameRounding", ImGuiStyleVar_FrameRounding }, + { "FrameBorderSize", ImGuiStyleVar_FrameBorderSize }, + { "ItemSpacing", ImGuiStyleVar_ItemSpacing }, + { "ItemInnerSpacing", ImGuiStyleVar_ItemInnerSpacing }, + { "IndentSpacing", ImGuiStyleVar_IndentSpacing }, + { "GrabMinSize", ImGuiStyleVar_GrabMinSize }, + { "ButtonTextAlign", ImGuiStyleVar_ButtonTextAlign } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiStyleVar_ &value) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiStyleVar_ &value) +{ value = parse_imgui_enum(l, index, imguiStyleVarTable, "ImGuiStyleVar"); } -static std::map imguiWindowFlagsTable -= { +static std::map imguiWindowFlagsTable = { { "NoTitleBar", ImGuiWindowFlags_NoTitleBar }, { "NoResize", ImGuiWindowFlags_NoResize }, { "NoMove", ImGuiWindowFlags_NoMove }, @@ -246,33 +251,38 @@ static std::map imguiWindowFlagsTable { "AlwaysUseWindowPadding", ImGuiWindowFlags_AlwaysUseWindowPadding } }; -void pi_lua_generic_pull(lua_State *l, int index, ImGuiWindowFlags_ &theflags) { +void pi_lua_generic_pull(lua_State *l, int index, ImGuiWindowFlags_ &theflags) +{ theflags = parse_imgui_flags(l, index, imguiWindowFlagsTable, "ImGuiWindowFlags"); } -static void pi_lua_pushVector(lua_State *l, double x, double y, double z) { +static void pi_lua_pushVector(lua_State *l, double x, double y, double z) +{ const int n = lua_gettop(l); lua_getfield(l, LUA_REGISTRYINDEX, "Imports"); lua_getfield(l, -1, "libs/Vector.lua"); // is there a better way to get at the lua Vector than this? LuaPush(l, x); LuaPush(l, y); LuaPush(l, z); - if(lua_pcall(l, 3, 1, 0) != 0) { + if (lua_pcall(l, 3, 1, 0) != 0) { Error("error running Vector\n"); } lua_remove(l, -2); assert(lua_gettop(l) == n + 1); } -static void pi_lua_generic_push(lua_State *l, const ImVec2 &v) { +static void pi_lua_generic_push(lua_State *l, const ImVec2 &v) +{ pi_lua_pushVector(l, v.x, v.y, 0); } -void pi_lua_generic_push(lua_State *l, const vector3d &v) { +void pi_lua_generic_push(lua_State *l, const vector3d &v) +{ pi_lua_pushVector(l, v.x, v.y, v.z); } -void pi_lua_generic_push(lua_State *l, const vector3f &v) { +void pi_lua_generic_push(lua_State *l, const vector3f &v) +{ pi_lua_pushVector(l, v.x, v.y, v.z); } @@ -294,14 +304,16 @@ void pi_lua_generic_push(lua_State *l, const vector3f &v) { * * stable */ -static int l_pigui_begin(lua_State *l) { +static int l_pigui_begin(lua_State *l) +{ const std::string name = LuaPull(l, 1); ImGuiWindowFlags theflags = LuaPull(l, 2); ImGui::Begin(name.c_str(), nullptr, theflags); return 0; } -static int l_pigui_columns(lua_State *l) { +static int l_pigui_columns(lua_State *l) +{ int columns = LuaPull(l, 1); std::string id = LuaPull(l, 2); bool border = LuaPull(l, 3); @@ -309,14 +321,16 @@ static int l_pigui_columns(lua_State *l) { return 0; } -static int l_pigui_set_column_offset(lua_State *l) { +static int l_pigui_set_column_offset(lua_State *l) +{ int column_index = LuaPull(l, 1); double offset_x = LuaPull(l, 2); ImGui::SetColumnOffset(column_index, offset_x); return 0; } -static int l_pigui_progress_bar(lua_State *l) { +static int l_pigui_progress_bar(lua_State *l) +{ float fraction = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); std::string overlay = LuaPull(l, 3); @@ -324,24 +338,28 @@ static int l_pigui_progress_bar(lua_State *l) { return 0; } -static int l_pigui_next_column(lua_State *l) { +static int l_pigui_next_column(lua_State *l) +{ ImGui::NextColumn(); return 0; } -static int l_pigui_end(lua_State *l) { +static int l_pigui_end(lua_State *l) +{ ImGui::End(); return 0; } -static int l_pigui_pop_clip_rect(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_pop_clip_rect(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); draw_list->PopClipRect(); return 0; } -static int l_pigui_push_clip_rect(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_push_clip_rect(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 min = LuaPull(l, 1); ImVec2 max = LuaPull(l, 2); bool intersect = LuaPull(l, 3); @@ -349,73 +367,80 @@ static int l_pigui_push_clip_rect(lua_State *l) { return 0; } -static int l_pigui_push_clip_rect_full_screen(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_push_clip_rect_full_screen(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); draw_list->PushClipRectFullScreen(); return 0; } -static int l_pigui_set_next_window_pos(lua_State *l) { +static int l_pigui_set_next_window_pos(lua_State *l) +{ ImVec2 pos = LuaPull(l, 1); int cond = LuaPull(l, 2); ImGui::SetNextWindowPos(pos, cond); return 0; } -static int l_pigui_set_next_window_pos_center(lua_State *l) { +static int l_pigui_set_next_window_pos_center(lua_State *l) +{ int cond = LuaPull(l, 1); ImGui::SetNextWindowPosCenter(cond); return 0; } -static int l_pigui_set_next_window_focus(lua_State *l) { +static int l_pigui_set_next_window_focus(lua_State *l) +{ ImGui::SetNextWindowFocus(); return 0; } -static int l_pigui_set_window_focus(lua_State *l) { +static int l_pigui_set_window_focus(lua_State *l) +{ std::string name = LuaPull(l, 1); ImGui::SetWindowFocus(name.c_str()); return 0; } -static int l_pigui_set_next_window_size(lua_State *l) { +static int l_pigui_set_next_window_size(lua_State *l) +{ ImVec2 size = LuaPull(l, 1); int cond = LuaPull(l, 2); ImGui::SetNextWindowSize(size, cond); return 0; } -static int l_pigui_set_next_window_size_constraints(lua_State *l) { +static int l_pigui_set_next_window_size_constraints(lua_State *l) +{ ImVec2 min = LuaPull(l, 1); ImVec2 max = LuaPull(l, 2); ImGui::SetNextWindowSizeConstraints(min, max); return 0; } -static int l_pigui_push_style_color(lua_State *l) { +static int l_pigui_push_style_color(lua_State *l) +{ int style = LuaPull(l, 1); ImColor color = LuaPull(l, 2); ImGui::PushStyleColor(style, static_cast(color)); return 0; } -static int l_pigui_pop_style_color(lua_State *l) { +static int l_pigui_pop_style_color(lua_State *l) +{ int num = LuaPull(l, 1); ImGui::PopStyleColor(num); return 0; } -static int l_pigui_push_style_var(lua_State *l) { +static int l_pigui_push_style_var(lua_State *l) +{ int style = LuaPull(l, 1); - if (lua_isnumber(l, 2)) - { + if (lua_isnumber(l, 2)) { double val = LuaPull(l, 2); ImGui::PushStyleVar(style, val); - } - else if (lua_istable(l, 2)) - { + } else if (lua_istable(l, 2)) { ImVec2 val = LuaPull(l, 2); ImGui::PushStyleVar(style, val); } @@ -423,14 +448,16 @@ static int l_pigui_push_style_var(lua_State *l) { return 0; } -static int l_pigui_pop_style_var(lua_State *l) { +static int l_pigui_pop_style_var(lua_State *l) +{ int num = LuaPull(l, 1); ImGui::PopStyleVar(num); return 0; } -static int l_pigui_add_line(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_line(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImColor col = LuaPull(l, 3); @@ -439,8 +466,9 @@ static int l_pigui_add_line(lua_State *l) { return 0; } -static int l_pigui_add_circle(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_circle(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 center = LuaPull(l, 1); int radius = LuaPull(l, 2); ImColor color = LuaPull(l, 3); @@ -450,8 +478,9 @@ static int l_pigui_add_circle(lua_State *l) { return 0; } -static int l_pigui_add_circle_filled(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_circle_filled(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 center = LuaPull(l, 1); int radius = LuaPull(l, 2); ImColor color = LuaPull(l, 3); @@ -460,8 +489,9 @@ static int l_pigui_add_circle_filled(lua_State *l) { return 0; } -static int l_pigui_path_arc_to(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_path_arc_to(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 center = LuaPull(l, 1); double radius = LuaPull(l, 2); double amin = LuaPull(l, 3); @@ -471,8 +501,9 @@ static int l_pigui_path_arc_to(lua_State *l) { return 0; } -static int l_pigui_path_stroke(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_path_stroke(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImColor color = LuaPull(l, 1); bool closed = LuaPull(l, 2); double thickness = LuaPull(l, 3); @@ -480,7 +511,8 @@ static int l_pigui_path_stroke(lua_State *l) { return 0; } -static int l_pigui_selectable(lua_State *l) { +static int l_pigui_selectable(lua_State *l) +{ std::string label = LuaPull(l, 1); bool selected = LuaPull(l, 2); ImGuiSelectableFlags flags = LuaPull(l, 3); @@ -490,13 +522,15 @@ static int l_pigui_selectable(lua_State *l) { return 1; } -static int l_pigui_text(lua_State *l) { +static int l_pigui_text(lua_State *l) +{ std::string text = LuaPull(l, 1); ImGui::Text("%s", text.c_str()); return 0; } -static int l_pigui_button(lua_State *l) { +static int l_pigui_button(lua_State *l) +{ std::string text = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); bool ret = ImGui::Button(text.c_str(), size); @@ -504,7 +538,8 @@ static int l_pigui_button(lua_State *l) { return 1; } -static int l_pigui_thrust_indicator(lua_State *l) { +static int l_pigui_thrust_indicator(lua_State *l) +{ std::string text = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); vector3d thr = LuaPull(l, 3); @@ -521,7 +556,8 @@ static int l_pigui_thrust_indicator(lua_State *l) { return 0; } -static int l_pigui_low_thrust_button(lua_State *l) { +static int l_pigui_low_thrust_button(lua_State *l) +{ std::string text = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); float level = LuaPull(l, 3); @@ -534,13 +570,15 @@ static int l_pigui_low_thrust_button(lua_State *l) { return 1; } -static int l_pigui_text_wrapped(lua_State *l) { +static int l_pigui_text_wrapped(lua_State *l) +{ std::string text = LuaPull(l, 1); ImGui::TextWrapped("%s", text.c_str()); return 0; } -static int l_pigui_text_colored(lua_State *l) { +static int l_pigui_text_colored(lua_State *l) +{ ImColor col = LuaPull(l, 1); std::string text = LuaPull(l, 2); ImGui::TextColored(col, "%s", text.c_str()); @@ -654,7 +692,7 @@ static int l_pigui_get_axisbinding(lua_State *l) for (auto js : joysticks) { std::vector axes = js.second.axes; for (size_t a = 0; a < axes.size(); a++) { - if (axes[a]>0.25 || axes[a]<-0.25) { + if (axes[a] > 0.25 || axes[a] < -0.25) { binding = "Joy" + Pi::input.JoystickGUIDString(js.first) + "/Axis" + std::to_string(a); break; } @@ -662,8 +700,10 @@ static int l_pigui_get_axisbinding(lua_State *l) if (binding.compare("")) break; } - if (!binding.compare("")) lua_pushnil(l); - else LuaPush(l, binding); + if (!binding.compare("")) + lua_pushnil(l); + else + LuaPush(l, binding); return 1; } @@ -717,33 +757,35 @@ static int l_pigui_get_keybinding(lua_State *l) if (js.second.hats[h]) { int hatDir = js.second.hats[h]; switch (hatDir) { - case SDL_HAT_LEFT: - case SDL_HAT_RIGHT: - case SDL_HAT_UP: - case SDL_HAT_DOWN: - binding = "Joy" + Pi::input.JoystickGUIDString(js.first) + "/Hat" + std::to_string(h) + "Dir" + std::to_string(js.second.hats[h]); - break; - default: - continue; + case SDL_HAT_LEFT: + case SDL_HAT_RIGHT: + case SDL_HAT_UP: + case SDL_HAT_DOWN: + binding = "Joy" + Pi::input.JoystickGUIDString(js.first) + "/Hat" + std::to_string(h) + "Dir" + std::to_string(js.second.hats[h]); + break; + default: + continue; } break; } } if (binding.compare("")) break; } - } - else { + } else { // hard coding is bad, but is instantiating a keybinding every frame worse? binding = "Key" + std::to_string(key); if (mod > 0) binding += "Mod" + std::to_string(mod); } - if (!binding.compare("")) lua_pushnil(l); - else LuaPush(l, binding); + if (!binding.compare("")) + lua_pushnil(l); + else + LuaPush(l, binding); return 1; } -static int l_pigui_add_text(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_text(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 center = LuaPull(l, 1); ImColor color = LuaPull(l, 2); std::string text = LuaPull(l, 3); @@ -751,8 +793,9 @@ static int l_pigui_add_text(lua_State *l) { return 0; } -static int l_pigui_add_triangle(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_triangle(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImVec2 c = LuaPull(l, 3); @@ -762,8 +805,9 @@ static int l_pigui_add_triangle(lua_State *l) { return 0; } -static int l_pigui_add_rect(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_rect(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImColor col = LuaPull(l, 3); @@ -774,8 +818,9 @@ static int l_pigui_add_rect(lua_State *l) { return 0; } -static int l_pigui_add_bezier_curve(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_bezier_curve(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 c0 = LuaPull(l, 2); ImVec2 c1 = LuaPull(l, 3); @@ -787,8 +832,9 @@ static int l_pigui_add_bezier_curve(lua_State *l) { return 0; } -static int l_pigui_add_image(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_image(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImTextureID id = pi_lua_checklightuserdata(l, 1); ImVec2 a = LuaPull(l, 2); ImVec2 b = LuaPull(l, 3); @@ -799,8 +845,9 @@ static int l_pigui_add_image(lua_State *l) { return 0; } -static int l_pigui_add_image_quad(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_image_quad(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImTextureID id = pi_lua_checklightuserdata(l, 1); ImVec2 a = LuaPull(l, 2); ImVec2 b = LuaPull(l, 3); @@ -815,8 +862,9 @@ static int l_pigui_add_image_quad(lua_State *l) { return 0; } -static int l_pigui_add_rect_filled(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_rect_filled(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImColor col = LuaPull(l, 3); @@ -826,8 +874,9 @@ static int l_pigui_add_rect_filled(lua_State *l) { return 0; } -static int l_pigui_add_quad(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_quad(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImVec2 c = LuaPull(l, 3); @@ -838,8 +887,9 @@ static int l_pigui_add_quad(lua_State *l) { return 0; } -static int l_pigui_add_triangle_filled(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_triangle_filled(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 a = LuaPull(l, 1); ImVec2 b = LuaPull(l, 2); ImVec2 c = LuaPull(l, 3); @@ -848,108 +898,126 @@ static int l_pigui_add_triangle_filled(lua_State *l) { return 0; } -static int l_pigui_same_line(lua_State *l) { +static int l_pigui_same_line(lua_State *l) +{ double pos_x = LuaPull(l, 1); double spacing_w = LuaPull(l, 2); ImGui::SameLine(pos_x, spacing_w); return 0; } -static int l_pigui_begin_group(lua_State *l) { +static int l_pigui_begin_group(lua_State *l) +{ ImGui::BeginGroup(); return 0; } -static int l_pigui_end_group(lua_State *l) { +static int l_pigui_end_group(lua_State *l) +{ ImGui::EndGroup(); return 0; } -static int l_pigui_separator(lua_State *l) { +static int l_pigui_separator(lua_State *l) +{ ImGui::Separator(); return 0; } -static int l_pigui_spacing(lua_State *l) { +static int l_pigui_spacing(lua_State *l) +{ ImGui::Spacing(); return 0; } -static int l_pigui_dummy(lua_State *l) { +static int l_pigui_dummy(lua_State *l) +{ ImVec2 size = LuaPull(l, 1); ImGui::Dummy(size); return 0; } -static int l_pigui_begin_popup(lua_State *l) { +static int l_pigui_begin_popup(lua_State *l) +{ std::string id = LuaPull(l, 1); LuaPush(l, ImGui::BeginPopup(id.c_str())); return 1; } -static int l_pigui_open_popup(lua_State *l) { +static int l_pigui_open_popup(lua_State *l) +{ std::string id = LuaPull(l, 1); ImGui::OpenPopup(id.c_str()); return 0; } -static int l_pigui_end_popup(lua_State *l) { +static int l_pigui_end_popup(lua_State *l) +{ ImGui::EndPopup(); return 0; } -static int l_pigui_begin_child(lua_State *l) { +static int l_pigui_begin_child(lua_State *l) +{ std::string id = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); - ImGui::BeginChild(id.c_str(),size); + ImGui::BeginChild(id.c_str(), size); return 0; } -static int l_pigui_end_child(lua_State *l) { +static int l_pigui_end_child(lua_State *l) +{ ImGui::EndChild(); return 0; } -static int l_pigui_is_item_hovered(lua_State *l) { +static int l_pigui_is_item_hovered(lua_State *l) +{ LuaPush(l, ImGui::IsItemHovered()); return 1; } -static int l_pigui_is_item_active(lua_State *l) { +static int l_pigui_is_item_active(lua_State *l) +{ LuaPush(l, ImGui::IsItemActive()); return 1; } -static int l_pigui_is_item_clicked(lua_State *l) { +static int l_pigui_is_item_clicked(lua_State *l) +{ int button = LuaPull(l, 1); LuaPush(l, ImGui::IsItemClicked(button)); return 1; } -static int l_pigui_is_mouse_released(lua_State *l) { +static int l_pigui_is_mouse_released(lua_State *l) +{ int button = LuaPull(l, 1); LuaPush(l, ImGui::IsMouseReleased(button)); return 1; } -static int l_pigui_is_mouse_down(lua_State *l) { +static int l_pigui_is_mouse_down(lua_State *l) +{ int button = LuaPull(l, 1); LuaPush(l, ImGui::IsMouseDown(button)); return 1; } -static int l_pigui_is_mouse_clicked(lua_State *l) { +static int l_pigui_is_mouse_clicked(lua_State *l) +{ int button = LuaPull(l, 1); LuaPush(l, ImGui::IsMouseClicked(button)); return 1; } -static int l_pigui_push_font(lua_State *l) { +static int l_pigui_push_font(lua_State *l) +{ PiGui *pigui = LuaObject::CheckFromLua(1); std::string fontname = LuaPull(l, 2); int size = LuaPull(l, 3); ImFont *font = pigui->GetFont(fontname, size); - if(!font) { + if (!font) { LuaPush(l, false); } else { LuaPush(l, true); @@ -958,37 +1026,43 @@ static int l_pigui_push_font(lua_State *l) { return 1; } -static int l_pigui_pop_font(lua_State *l) { +static int l_pigui_pop_font(lua_State *l) +{ ImGui::PopFont(); return 0; } -static int l_pigui_calc_text_size(lua_State *l) { +static int l_pigui_calc_text_size(lua_State *l) +{ std::string text = LuaPull(l, 1); ImVec2 size = ImGui::CalcTextSize(text.c_str()); pi_lua_generic_push(l, size); return 1; } -static int l_pigui_get_mouse_pos(lua_State *l) { +static int l_pigui_get_mouse_pos(lua_State *l) +{ ImVec2 pos = ImGui::GetMousePos(); pi_lua_generic_push(l, pos); return 1; } -static int l_pigui_get_mouse_wheel(lua_State *l) { +static int l_pigui_get_mouse_wheel(lua_State *l) +{ float wheel = ImGui::GetIO().MouseWheel; LuaPush(l, wheel); return 1; } -static int l_pigui_set_tooltip(lua_State *l) { +static int l_pigui_set_tooltip(lua_State *l) +{ std::string text = LuaPull(l, 1); ImGui::SetTooltip("%s", text.c_str()); return 0; } -static int l_pigui_checkbox(lua_State *l) { +static int l_pigui_checkbox(lua_State *l) +{ std::string label = LuaPull(l, 1); bool checked = LuaPull(l, 2); bool changed = ImGui::Checkbox(label.c_str(), &checked); @@ -997,45 +1071,53 @@ static int l_pigui_checkbox(lua_State *l) { return 2; } -static int l_pigui_push_item_width(lua_State *l) { +static int l_pigui_push_item_width(lua_State *l) +{ double width = LuaPull(l, 1); ImGui::PushItemWidth(width); return 0; } -static int l_pigui_pop_item_width(lua_State *l) { +static int l_pigui_pop_item_width(lua_State *l) +{ ImGui::PopItemWidth(); return 0; } -static int l_pigui_push_id(lua_State *l) { +static int l_pigui_push_id(lua_State *l) +{ std::string id = LuaPull(l, 1); ImGui::PushID(id.c_str()); return 0; } -static int l_pigui_pop_id(lua_State *l) { +static int l_pigui_pop_id(lua_State *l) +{ ImGui::PopID(); return 0; } -static int l_pigui_get_window_pos(lua_State *l) { +static int l_pigui_get_window_pos(lua_State *l) +{ ImVec2 pos = ImGui::GetWindowPos(); pi_lua_generic_push(l, pos); return 1; } -static int l_pigui_get_window_size(lua_State *l) { +static int l_pigui_get_window_size(lua_State *l) +{ pi_lua_generic_push(l, ImGui::GetWindowSize()); return 1; } -static int l_pigui_get_content_region(lua_State *l) { +static int l_pigui_get_content_region(lua_State *l) +{ pi_lua_generic_push(l, ImGui::GetContentRegionAvail()); return 1; } -static int l_pigui_image(lua_State *l) { +static int l_pigui_image(lua_State *l) +{ ImTextureID id = pi_lua_checklightuserdata(l, 1); ImVec2 size = LuaPull(l, 2); ImVec2 uv0 = LuaPull(l, 3); @@ -1045,7 +1127,8 @@ static int l_pigui_image(lua_State *l) { return 0; } -static int l_pigui_image_button(lua_State *l) { +static int l_pigui_image_button(lua_State *l) +{ ImTextureID id = pi_lua_checklightuserdata(l, 1); ImVec2 size = LuaPull(l, 2); ImVec2 uv0 = LuaPull(l, 3); @@ -1058,49 +1141,54 @@ static int l_pigui_image_button(lua_State *l) { return 1; } -static int l_pigui_capture_mouse_from_app(lua_State *l) { +static int l_pigui_capture_mouse_from_app(lua_State *l) +{ bool b = LuaPull(l, 1); ImGui::CaptureMouseFromApp(b); return 0; } -static int l_pigui_get_mouse_clicked_pos(lua_State *l) { +static int l_pigui_get_mouse_clicked_pos(lua_State *l) +{ int n = LuaPull(l, 1); ImVec2 pos = ImGui::GetIO().MouseClickedPos[n]; pi_lua_generic_push(l, pos); return 1; } -std::tuple lua_world_space_to_screen_space(vector3d pos) { +std::tuple lua_world_space_to_screen_space(vector3d pos) +{ WorldView *wv = Pi::game->GetWorldView(); vector3d p = wv->WorldSpaceToScreenSpace(pos); const int width = Graphics::GetScreenWidth(); const int height = Graphics::GetScreenHeight(); vector3d direction = (p - vector3d(width / 2, height / 2, 0)).Normalized(); - if(vector3d(0,0,0) == p || p.x < 0 || p.y < 0 || p.x > width || p.y > height || p.z > 0) { + if (vector3d(0, 0, 0) == p || p.x < 0 || p.y < 0 || p.x > width || p.y > height || p.z > 0) { return std::make_tuple(false, vector3d(0, 0, 0), direction * (p.z > 0 ? -1 : 1)); } else { return std::make_tuple(true, vector3d(p.x, p.y, 0), direction); } } -std::tuple lua_world_space_to_screen_space(Body *body) { +std::tuple lua_world_space_to_screen_space(Body *body) +{ WorldView *wv = Pi::game->GetWorldView(); vector3d p = wv->WorldSpaceToScreenSpace(body); const int width = Graphics::GetScreenWidth(); const int height = Graphics::GetScreenHeight(); vector3d direction = (p - vector3d(width / 2, height / 2, 0)).Normalized(); - if(vector3d(0,0,0) == p || p.x < 0 || p.y < 0 || p.x > width || p.y > height || p.z > 0) { + if (vector3d(0, 0, 0) == p || p.x < 0 || p.y < 0 || p.x > width || p.y > height || p.z > 0) { return std::make_tuple(false, vector3d(0, 0, 0), direction * (p.z > 0 ? -1 : 1)); } else { return std::make_tuple(true, vector3d(p.x, p.y, 0), direction); } } -static int l_pigui_get_projected_bodies(lua_State *l) { +static int l_pigui_get_projected_bodies(lua_State *l) +{ LuaTable result(l); - for (Body* body : Pi::game->GetSpace()->GetBodies()) { - if(body == Pi::game->GetPlayer()) continue; + for (Body *body : Pi::game->GetSpace()->GetBodies()) { + if (body == Pi::game->GetPlayer()) continue; if (body->GetType() == Object::PROJECTILE) continue; LuaTable object(l); @@ -1120,7 +1208,8 @@ static int l_pigui_get_projected_bodies(lua_State *l) { return 1; } -static int l_pigui_get_targets_nearby(lua_State *l) { +static int l_pigui_get_targets_nearby(lua_State *l) +{ int range_max = LuaPull(l, 1); LuaTable result(l); Space::BodyNearList nearby; @@ -1133,15 +1222,13 @@ static int l_pigui_get_targets_nearby(lua_State *l) { float distance = float(position.Length()); vector3d shipSpacePosition = position * Pi::player->GetOrient(); // convert to polar https://en.wikipedia.org/wiki/Spherical_coordinate_system - vector3d polarPosition(// don't calculate X, it is not used + vector3d polarPosition( // don't calculate X, it is not used // sqrt(shipSpacePosition.x*shipSpacePosition.x // + shipSpacePosition.y*shipSpacePosition.y // + shipSpacePosition.z*shipSpacePosition.z) 0, atan2(shipSpacePosition.x, shipSpacePosition.y), - atan2(-shipSpacePosition.z, sqrt(shipSpacePosition.x*shipSpacePosition.x - + shipSpacePosition.y*shipSpacePosition.y)) - ); + atan2(-shipSpacePosition.z, sqrt(shipSpacePosition.x * shipSpacePosition.x + shipSpacePosition.y * shipSpacePosition.y))); // convert to AEP https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection double rho = M_PI / 2 - polarPosition.z; double theta = polarPosition.y; @@ -1160,21 +1247,23 @@ static int l_pigui_get_targets_nearby(lua_State *l) { result.Set(std::to_string(index++), object); lua_pop(l, 1); } - LuaPush(l, result); + LuaPush(l, result); return 1; } -static int l_pigui_disable_mouse_facing(lua_State *l) { +static int l_pigui_disable_mouse_facing(lua_State *l) +{ bool b = LuaPull(l, 1); auto *p = Pi::player->GetPlayerController(); p->SetDisableMouseFacing(b); return 0; } -static int l_pigui_set_mouse_button_state(lua_State *l) { +static int l_pigui_set_mouse_button_state(lua_State *l) +{ int button = LuaPull(l, 1); bool state = LuaPull(l, 2); Pi::input.SetMouseButtonState(button, state); - if(state == false) { + if (state == false) { // new UI caches which widget should receive the mouse up event // after a mouse down. This function exists exactly because the mouse-up event // never gets delivered after imgui uses it. So reset that context as well. @@ -1191,53 +1280,62 @@ static int l_pigui_should_show_labels(lua_State *l) return 1; } -static int l_attr_handlers(lua_State *l) { +static int l_attr_handlers(lua_State *l) +{ PiGui *pigui = LuaObject::CheckFromLua(1); pigui->GetHandlers().PushCopyToStack(); return 1; } -static int l_attr_keys(lua_State *l) { +static int l_attr_keys(lua_State *l) +{ PiGui *pigui = LuaObject::CheckFromLua(1); pigui->GetKeys().PushCopyToStack(); return 1; } -static int l_attr_screen_width(lua_State *l) { +static int l_attr_screen_width(lua_State *l) +{ // PiGui *pigui = LuaObject::CheckFromLua(1); - LuaPush(l,Graphics::GetScreenWidth()); + LuaPush(l, Graphics::GetScreenWidth()); return 1; } -static int l_attr_key_ctrl(lua_State *l) { +static int l_attr_key_ctrl(lua_State *l) +{ LuaPush(l, ImGui::GetIO().KeyCtrl); return 1; } -static int l_attr_key_none(lua_State *l) { +static int l_attr_key_none(lua_State *l) +{ LuaPush(l, !ImGui::GetIO().KeyCtrl & !ImGui::GetIO().KeyShift & !ImGui::GetIO().KeyAlt); return 1; } -static int l_attr_key_shift(lua_State *l) { +static int l_attr_key_shift(lua_State *l) +{ LuaPush(l, ImGui::GetIO().KeyShift); return 1; } -static int l_attr_key_alt(lua_State *l) { +static int l_attr_key_alt(lua_State *l) +{ LuaPush(l, ImGui::GetIO().KeyAlt); return 1; } -static int l_attr_screen_height(lua_State *l) { +static int l_attr_screen_height(lua_State *l) +{ // PiGui *pigui = LuaObject::CheckFromLua(1); - LuaPush(l,Graphics::GetScreenHeight()); + LuaPush(l, Graphics::GetScreenHeight()); return 1; } // TODO: the Combo API was upgraded in IMGUI v1.53. // The Lua API currently uses the old API, and needs to be upgraded. -static int l_pigui_combo(lua_State *l) { +static int l_pigui_combo(lua_State *l) +{ std::string lbl = LuaPull(l, 1); int selected = LuaPull(l, 2); @@ -1255,8 +1353,8 @@ static int l_pigui_combo(lua_State *l) { return 2; } - -static int l_pigui_listbox(lua_State *l) { +static int l_pigui_listbox(lua_State *l) +{ std::string lbl = LuaPull(l, 1); int selected = LuaPull(l, 2); @@ -1275,21 +1373,21 @@ static int l_pigui_listbox(lua_State *l) { return 2; } - -static int l_pigui_radial_menu(lua_State *l) { +static int l_pigui_radial_menu(lua_State *l) +{ ImVec2 center = LuaPull(l, 1); std::string id = LuaPull(l, 2); int mouse_button = LuaPull(l, 3); std::vector tex_ids; - std::vector> uvs; + std::vector> uvs; int i = 0; - while(true) { + while (true) { lua_rawgeti(l, 4, ++i); - if(lua_isnil(l, -1)) { + if (lua_isnil(l, -1)) { lua_pop(l, 1); break; } - if(!lua_istable(l, -1)) { + if (!lua_istable(l, -1)) { Output("element of icons not a table %i\n", i); break; } @@ -1306,13 +1404,13 @@ static int l_pigui_radial_menu(lua_State *l) { lua_pop(l, 1); lua_pop(l, 1); tex_ids.push_back(tid); - uvs.push_back(std::pair(uv0, uv1)); + uvs.push_back(std::pair(uv0, uv1)); } int size = LuaPull(l, 5); std::vector tooltips; LuaTable tts(l, 6); - for(LuaTable::VecIter iter = tts.Begin(); iter != tts.End(); ++iter) { + for (LuaTable::VecIter iter = tts.Begin(); iter != tts.End(); ++iter) { tooltips.push_back(*iter); } int n = PiGui::RadialPopupSelectMenu(center, id, mouse_button, tex_ids, uvs, size, tooltips); @@ -1320,12 +1418,14 @@ static int l_pigui_radial_menu(lua_State *l) { return 1; } -static int l_pigui_should_draw_ui(lua_State *l) { +static int l_pigui_should_draw_ui(lua_State *l) +{ LuaPush(l, Pi::DrawGUI); return 1; } -static int l_pigui_is_mouse_hovering_rect(lua_State *l) { +static int l_pigui_is_mouse_hovering_rect(lua_State *l) +{ ImVec2 r_min = LuaPull(l, 1); ImVec2 r_max = LuaPull(l, 2); bool clip = LuaPull(l, 3); @@ -1333,32 +1433,37 @@ static int l_pigui_is_mouse_hovering_rect(lua_State *l) { return 1; } -static int l_pigui_data_dir_path(lua_State *l) { +static int l_pigui_data_dir_path(lua_State *l) +{ std::string path = FileSystem::GetDataDir(); LuaTable pathComponents(l, 1); - for(LuaTable::VecIter iter = pathComponents.Begin(); iter != pathComponents.End(); ++iter) { + for (LuaTable::VecIter iter = pathComponents.Begin(); iter != pathComponents.End(); ++iter) { path = FileSystem::JoinPath(path, *iter); } LuaPush(l, path); return 1; } -static int l_pigui_is_mouse_hovering_any_window(lua_State *l) { +static int l_pigui_is_mouse_hovering_any_window(lua_State *l) +{ LuaPush(l, ImGui::IsMouseHoveringAnyWindow()); return 1; } -static int l_pigui_is_mouse_hovering_window(lua_State *l) { +static int l_pigui_is_mouse_hovering_window(lua_State *l) +{ LuaPush(l, ImGui::IsMouseHoveringWindow()); return 1; } -static int l_pigui_system_info_view_next_page(lua_State *l) { +static int l_pigui_system_info_view_next_page(lua_State *l) +{ Pi::game->GetSystemInfoView()->NextPage(); return 0; } -static int l_pigui_input_text(lua_State *l) { +static int l_pigui_input_text(lua_State *l) +{ std::string label = LuaPull(l, 1); std::string text = LuaPull(l, 2); int flags = LuaPull(l, 3); @@ -1368,12 +1473,13 @@ static int l_pigui_input_text(lua_State *l) { memset(buffer, 0, 1024); strncpy(buffer, text.c_str(), 1023); bool result = ImGui::InputText(label.c_str(), buffer, 1024, flags); - LuaPush(l, buffer); + LuaPush(l, buffer); LuaPush(l, result); return 2; } -static int l_pigui_play_sfx(lua_State *l) { +static int l_pigui_play_sfx(lua_State *l) +{ std::string name = LuaPull(l, 1); double left = LuaPull(l, 2); double right = LuaPull(l, 3); @@ -1381,20 +1487,22 @@ static int l_pigui_play_sfx(lua_State *l) { return 0; } -static int l_pigui_circular_slider(lua_State *l) { +static int l_pigui_circular_slider(lua_State *l) +{ ImVec2 center = LuaPull(l, 1); float v = LuaPull(l, 2); float v_min = LuaPull(l, 3); float v_max = LuaPull(l, 4); bool res = PiGui::CircularSlider(center, &v, v_min, v_max); - if(res) + if (res) LuaPush(l, v); else lua_pushnil(l); return 1; } -static int l_pigui_slider_int(lua_State *l) { +static int l_pigui_slider_int(lua_State *l) +{ std::string lbl = LuaPull(l, 1); int value = LuaPull(l, 2); int val_min = LuaPull(l, 3); @@ -1406,7 +1514,8 @@ static int l_pigui_slider_int(lua_State *l) { return 1; } -static int l_pigui_vsliderint(lua_State *l) { +static int l_pigui_vsliderint(lua_State *l) +{ std::string lbl = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); @@ -1421,8 +1530,8 @@ static int l_pigui_vsliderint(lua_State *l) { return 1; } - -static int l_pigui_vsliderfloat(lua_State *l) { +static int l_pigui_vsliderfloat(lua_State *l) +{ std::string lbl = LuaPull(l, 1); ImVec2 size = LuaPull(l, 2); @@ -1437,37 +1546,43 @@ static int l_pigui_vsliderfloat(lua_State *l) { return 1; } -static int l_pigui_is_key_released(lua_State *l) { +static int l_pigui_is_key_released(lua_State *l) +{ SDL_Keycode key = LuaPull(l, 1); LuaPush(l, ImGui::IsKeyReleased(SDL_GetScancodeFromKey(key))); return 1; } -static int l_pigui_get_cursor_pos(lua_State *l) { +static int l_pigui_get_cursor_pos(lua_State *l) +{ ImVec2 v = ImGui::GetCursorPos(); LuaPush(l, v); return 1; } -static int l_pigui_get_cursor_screen_pos(lua_State *l) { +static int l_pigui_get_cursor_screen_pos(lua_State *l) +{ ImVec2 v = ImGui::GetCursorScreenPos(); LuaPush(l, v); return 1; } -static int l_pigui_set_cursor_pos(lua_State *l) { +static int l_pigui_set_cursor_pos(lua_State *l) +{ ImVec2 v = LuaPull(l, 1); ImGui::SetCursorPos(v); return 0; } -static int l_pigui_set_cursor_screen_pos(lua_State *l) { +static int l_pigui_set_cursor_screen_pos(lua_State *l) +{ ImVec2 v = LuaPull(l, 1); ImGui::SetCursorScreenPos(v); return 0; } -static int l_pigui_drag_int_4(lua_State *l) { +static int l_pigui_drag_int_4(lua_State *l) +{ std::string label = LuaPull(l, 1); int v[4]; v[0] = LuaPull(l, 2); @@ -1486,16 +1601,17 @@ static int l_pigui_drag_int_4(lua_State *l) { return 5; } -static int l_pigui_add_convex_poly_filled(lua_State *l) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); +static int l_pigui_add_convex_poly_filled(lua_State *l) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); LuaTable pnts(l, 1); ImColor col = LuaPull(l, 2); bool anti_aliased = LuaPull(l, 3); std::vector ps; int i = 0; double x = 0.0, y = 0.0; - for(LuaTable::VecIter iter = pnts.Begin(); iter != pnts.End(); ++iter) { - if(i++ % 2) { + for (LuaTable::VecIter iter = pnts.Begin(); iter != pnts.End(); ++iter) { + if (i++ % 2) { y = *iter; ps.push_back(ImVec2(x, y)); } else @@ -1508,7 +1624,8 @@ static int l_pigui_add_convex_poly_filled(lua_State *l) { return 0; } -static int l_pigui_load_texture_from_svg(lua_State *l) { +static int l_pigui_load_texture_from_svg(lua_State *l) +{ PiGui *pigui = LuaObject::CheckFromLua(1); std::string svg_filename = LuaPull(l, 2); int width = LuaPull(l, 3); @@ -1519,157 +1636,163 @@ static int l_pigui_load_texture_from_svg(lua_State *l) { return 1; } -static int l_pigui_set_scroll_here(lua_State *l) { +static int l_pigui_set_scroll_here(lua_State *l) +{ ImGui::SetScrollHere(); return 0; } -static int l_pigui_pop_text_wrap_pos(lua_State *l) { +static int l_pigui_pop_text_wrap_pos(lua_State *l) +{ ImGui::PopTextWrapPos(); return 0; } -static int l_pigui_collapsing_header(lua_State *l) { +static int l_pigui_collapsing_header(lua_State *l) +{ std::string label = LuaPull(l, 1); ImGuiTreeNodeFlags flags = LuaPull(l, 2); LuaPush(l, ImGui::CollapsingHeader(label.c_str(), flags)); return 1; } -static int l_pigui_push_text_wrap_pos(lua_State *l) { +static int l_pigui_push_text_wrap_pos(lua_State *l) +{ float wrap_pos_x = LuaPull(l, 1); ImGui::PushTextWrapPos(wrap_pos_x); return 0; } -template <> const char *LuaObject::s_type = "PiGui"; +template <> +const char *LuaObject::s_type = "PiGui"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { - { "Begin", l_pigui_begin }, - { "End", l_pigui_end }, + { "Begin", l_pigui_begin }, + { "End", l_pigui_end }, { "PushClipRectFullScreen", l_pigui_push_clip_rect_full_screen }, - { "PopClipRect", l_pigui_pop_clip_rect }, - { "PushClipRect", l_pigui_push_clip_rect }, - { "AddCircle", l_pigui_add_circle }, - { "AddCircleFilled", l_pigui_add_circle_filled }, - { "AddLine", l_pigui_add_line }, - { "AddText", l_pigui_add_text }, - { "AddTriangle", l_pigui_add_triangle }, - { "AddTriangleFilled", l_pigui_add_triangle_filled }, - { "AddQuad", l_pigui_add_quad }, - { "AddRect", l_pigui_add_rect }, - { "AddRectFilled", l_pigui_add_rect_filled }, - { "AddImage", l_pigui_add_image }, - { "AddImageQuad", l_pigui_add_image_quad }, - { "AddBezierCurve", l_pigui_add_bezier_curve }, - { "SetNextWindowPos", l_pigui_set_next_window_pos }, + { "PopClipRect", l_pigui_pop_clip_rect }, + { "PushClipRect", l_pigui_push_clip_rect }, + { "AddCircle", l_pigui_add_circle }, + { "AddCircleFilled", l_pigui_add_circle_filled }, + { "AddLine", l_pigui_add_line }, + { "AddText", l_pigui_add_text }, + { "AddTriangle", l_pigui_add_triangle }, + { "AddTriangleFilled", l_pigui_add_triangle_filled }, + { "AddQuad", l_pigui_add_quad }, + { "AddRect", l_pigui_add_rect }, + { "AddRectFilled", l_pigui_add_rect_filled }, + { "AddImage", l_pigui_add_image }, + { "AddImageQuad", l_pigui_add_image_quad }, + { "AddBezierCurve", l_pigui_add_bezier_curve }, + { "SetNextWindowPos", l_pigui_set_next_window_pos }, { "SetNextWindowPosCenter", l_pigui_set_next_window_pos_center }, - { "SetNextWindowSize", l_pigui_set_next_window_size }, + { "SetNextWindowSize", l_pigui_set_next_window_size }, { "SetNextWindowSizeConstraints", l_pigui_set_next_window_size_constraints }, - { "SetNextWindowFocus", l_pigui_set_next_window_focus }, - { "SetWindowFocus", l_pigui_set_window_focus }, - { "GetKeyBinding", l_pigui_get_keybinding }, - { "GetAxisBinding", l_pigui_get_axisbinding }, + { "SetNextWindowFocus", l_pigui_set_next_window_focus }, + { "SetWindowFocus", l_pigui_set_window_focus }, + { "GetKeyBinding", l_pigui_get_keybinding }, + { "GetAxisBinding", l_pigui_get_axisbinding }, // { "GetHUDMarker", l_pigui_get_hud_marker }, // { "GetVelocity", l_pigui_get_velocity }, - { "PushStyleColor", l_pigui_push_style_color }, - { "PopStyleColor", l_pigui_pop_style_color }, - { "PushStyleVar", l_pigui_push_style_var }, - { "PopStyleVar", l_pigui_pop_style_var }, - { "Columns", l_pigui_columns }, - { "NextColumn", l_pigui_next_column }, - { "SetColumnOffset", l_pigui_set_column_offset }, - { "Text", l_pigui_text }, - { "TextWrapped", l_pigui_text_wrapped }, - { "TextColored", l_pigui_text_colored }, - { "SetScrollHere", l_pigui_set_scroll_here }, - { "Button", l_pigui_button }, - { "Selectable", l_pigui_selectable }, - { "BeginGroup", l_pigui_begin_group }, - { "SetCursorPos", l_pigui_set_cursor_pos }, - { "GetCursorPos", l_pigui_get_cursor_pos }, - { "SetCursorScreenPos", l_pigui_set_cursor_screen_pos }, - { "GetCursorScreenPos", l_pigui_get_cursor_screen_pos }, - { "EndGroup", l_pigui_end_group }, - { "SameLine", l_pigui_same_line }, - { "Separator", l_pigui_separator }, - { "IsItemHovered", l_pigui_is_item_hovered }, - { "IsItemActive", l_pigui_is_item_active }, - { "IsItemClicked", l_pigui_is_item_clicked }, - { "Spacing", l_pigui_spacing }, - { "Dummy", l_pigui_dummy }, - { "BeginChild", l_pigui_begin_child }, - { "EndChild", l_pigui_end_child }, - { "PushFont", l_pigui_push_font }, - { "PopFont", l_pigui_pop_font }, - { "CalcTextSize", l_pigui_calc_text_size }, - { "SetTooltip", l_pigui_set_tooltip }, - { "Checkbox", l_pigui_checkbox }, - { "GetMousePos", l_pigui_get_mouse_pos }, - { "GetMouseWheel", l_pigui_get_mouse_wheel }, - { "PathArcTo", l_pigui_path_arc_to }, - { "PathStroke", l_pigui_path_stroke }, - { "PushItemWidth", l_pigui_push_item_width }, - { "PopItemWidth", l_pigui_pop_item_width }, - { "PushTextWrapPos", l_pigui_push_text_wrap_pos }, - { "PopTextWrapPos", l_pigui_pop_text_wrap_pos }, - { "BeginPopup", l_pigui_begin_popup }, - { "EndPopup", l_pigui_end_popup }, - { "OpenPopup", l_pigui_open_popup }, - { "PushID", l_pigui_push_id }, - { "PopID", l_pigui_pop_id }, - { "IsMouseReleased", l_pigui_is_mouse_released }, - { "IsMouseClicked", l_pigui_is_mouse_clicked }, - { "IsMouseDown", l_pigui_is_mouse_down }, - { "IsMouseHoveringRect", l_pigui_is_mouse_hovering_rect }, - { "IsMouseHoveringAnyWindow", l_pigui_is_mouse_hovering_any_window }, - { "IsMouseHoveringWindow", l_pigui_is_mouse_hovering_window }, - { "Image", l_pigui_image }, - { "ImageButton", l_pigui_image_button }, - { "RadialMenu", l_pigui_radial_menu }, - { "CircularSlider", l_pigui_circular_slider }, - { "SliderInt", l_pigui_slider_int }, - { "VSliderFloat", l_pigui_vsliderfloat }, - { "VSliderInt", l_pigui_vsliderint }, - { "GetMouseClickedPos", l_pigui_get_mouse_clicked_pos }, - { "AddConvexPolyFilled", l_pigui_add_convex_poly_filled }, - { "IsKeyReleased", l_pigui_is_key_released }, - { "DragInt4", l_pigui_drag_int_4 }, - { "GetWindowPos", l_pigui_get_window_pos }, - { "GetWindowSize", l_pigui_get_window_size }, - { "GetContentRegion", l_pigui_get_content_region }, - { "InputText", l_pigui_input_text }, - { "Combo", l_pigui_combo }, - { "ListBox", l_pigui_listbox }, - { "CollapsingHeader", l_pigui_collapsing_header }, - { "CaptureMouseFromApp", l_pigui_capture_mouse_from_app }, - { "ProgressBar", l_pigui_progress_bar }, - { "LoadTextureFromSVG", l_pigui_load_texture_from_svg }, - { "DataDirPath", l_pigui_data_dir_path }, - { "ShouldDrawUI", l_pigui_should_draw_ui }, - { "GetTargetsNearby", l_pigui_get_targets_nearby }, - { "GetProjectedBodies", l_pigui_get_projected_bodies }, - { "ShouldShowLabels", l_pigui_should_show_labels }, + { "PushStyleColor", l_pigui_push_style_color }, + { "PopStyleColor", l_pigui_pop_style_color }, + { "PushStyleVar", l_pigui_push_style_var }, + { "PopStyleVar", l_pigui_pop_style_var }, + { "Columns", l_pigui_columns }, + { "NextColumn", l_pigui_next_column }, + { "SetColumnOffset", l_pigui_set_column_offset }, + { "Text", l_pigui_text }, + { "TextWrapped", l_pigui_text_wrapped }, + { "TextColored", l_pigui_text_colored }, + { "SetScrollHere", l_pigui_set_scroll_here }, + { "Button", l_pigui_button }, + { "Selectable", l_pigui_selectable }, + { "BeginGroup", l_pigui_begin_group }, + { "SetCursorPos", l_pigui_set_cursor_pos }, + { "GetCursorPos", l_pigui_get_cursor_pos }, + { "SetCursorScreenPos", l_pigui_set_cursor_screen_pos }, + { "GetCursorScreenPos", l_pigui_get_cursor_screen_pos }, + { "EndGroup", l_pigui_end_group }, + { "SameLine", l_pigui_same_line }, + { "Separator", l_pigui_separator }, + { "IsItemHovered", l_pigui_is_item_hovered }, + { "IsItemActive", l_pigui_is_item_active }, + { "IsItemClicked", l_pigui_is_item_clicked }, + { "Spacing", l_pigui_spacing }, + { "Dummy", l_pigui_dummy }, + { "BeginChild", l_pigui_begin_child }, + { "EndChild", l_pigui_end_child }, + { "PushFont", l_pigui_push_font }, + { "PopFont", l_pigui_pop_font }, + { "CalcTextSize", l_pigui_calc_text_size }, + { "SetTooltip", l_pigui_set_tooltip }, + { "Checkbox", l_pigui_checkbox }, + { "GetMousePos", l_pigui_get_mouse_pos }, + { "GetMouseWheel", l_pigui_get_mouse_wheel }, + { "PathArcTo", l_pigui_path_arc_to }, + { "PathStroke", l_pigui_path_stroke }, + { "PushItemWidth", l_pigui_push_item_width }, + { "PopItemWidth", l_pigui_pop_item_width }, + { "PushTextWrapPos", l_pigui_push_text_wrap_pos }, + { "PopTextWrapPos", l_pigui_pop_text_wrap_pos }, + { "BeginPopup", l_pigui_begin_popup }, + { "EndPopup", l_pigui_end_popup }, + { "OpenPopup", l_pigui_open_popup }, + { "PushID", l_pigui_push_id }, + { "PopID", l_pigui_pop_id }, + { "IsMouseReleased", l_pigui_is_mouse_released }, + { "IsMouseClicked", l_pigui_is_mouse_clicked }, + { "IsMouseDown", l_pigui_is_mouse_down }, + { "IsMouseHoveringRect", l_pigui_is_mouse_hovering_rect }, + { "IsMouseHoveringAnyWindow", l_pigui_is_mouse_hovering_any_window }, + { "IsMouseHoveringWindow", l_pigui_is_mouse_hovering_window }, + { "Image", l_pigui_image }, + { "ImageButton", l_pigui_image_button }, + { "RadialMenu", l_pigui_radial_menu }, + { "CircularSlider", l_pigui_circular_slider }, + { "SliderInt", l_pigui_slider_int }, + { "VSliderFloat", l_pigui_vsliderfloat }, + { "VSliderInt", l_pigui_vsliderint }, + { "GetMouseClickedPos", l_pigui_get_mouse_clicked_pos }, + { "AddConvexPolyFilled", l_pigui_add_convex_poly_filled }, + { "IsKeyReleased", l_pigui_is_key_released }, + { "DragInt4", l_pigui_drag_int_4 }, + { "GetWindowPos", l_pigui_get_window_pos }, + { "GetWindowSize", l_pigui_get_window_size }, + { "GetContentRegion", l_pigui_get_content_region }, + { "InputText", l_pigui_input_text }, + { "Combo", l_pigui_combo }, + { "ListBox", l_pigui_listbox }, + { "CollapsingHeader", l_pigui_collapsing_header }, + { "CaptureMouseFromApp", l_pigui_capture_mouse_from_app }, + { "ProgressBar", l_pigui_progress_bar }, + { "LoadTextureFromSVG", l_pigui_load_texture_from_svg }, + { "DataDirPath", l_pigui_data_dir_path }, + { "ShouldDrawUI", l_pigui_should_draw_ui }, + { "GetTargetsNearby", l_pigui_get_targets_nearby }, + { "GetProjectedBodies", l_pigui_get_projected_bodies }, + { "ShouldShowLabels", l_pigui_should_show_labels }, { "SystemInfoViewNextPage", l_pigui_system_info_view_next_page }, // deprecated - { "LowThrustButton", l_pigui_low_thrust_button }, - { "ThrustIndicator", l_pigui_thrust_indicator }, - { "PlaySfx", l_pigui_play_sfx }, - { "DisableMouseFacing", l_pigui_disable_mouse_facing }, - { "SetMouseButtonState", l_pigui_set_mouse_button_state }, + { "LowThrustButton", l_pigui_low_thrust_button }, + { "ThrustIndicator", l_pigui_thrust_indicator }, + { "PlaySfx", l_pigui_play_sfx }, + { "DisableMouseFacing", l_pigui_disable_mouse_facing }, + { "SetMouseButtonState", l_pigui_set_mouse_button_state }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "handlers", l_attr_handlers }, - { "screen_width", l_attr_screen_width }, + { "handlers", l_attr_handlers }, + { "screen_width", l_attr_screen_width }, { "screen_height", l_attr_screen_height }, - { "key_ctrl", l_attr_key_ctrl }, - { "key_none", l_attr_key_none }, - { "key_shift", l_attr_key_shift }, - { "key_alt", l_attr_key_alt }, - { "keys", l_attr_keys }, + { "key_ctrl", l_attr_key_ctrl }, + { "key_none", l_attr_key_none }, + { "key_shift", l_attr_key_shift }, + { "key_alt", l_attr_key_alt }, + { "keys", l_attr_keys }, { 0, 0 } }; diff --git a/src/LuaPiGui.h b/src/LuaPiGui.h index 92933729d..a9ec07ccb 100644 --- a/src/LuaPiGui.h +++ b/src/LuaPiGui.h @@ -13,4 +13,3 @@ void pi_lua_generic_pull(lua_State *l, int index, vector3d &vector); int pushOnScreenPositionDirection(lua_State *l, vector3d position); std::tuple lua_world_space_to_screen_space(vector3d pos); #endif - diff --git a/src/LuaPlanet.cpp b/src/LuaPlanet.cpp index 486558885..9e10ab2d2 100644 --- a/src/LuaPlanet.cpp +++ b/src/LuaPlanet.cpp @@ -11,9 +11,11 @@ * Class representing a planet. Inherits from . */ -template <> const char *LuaObject::s_type = "Planet"; +template <> +const char *LuaObject::s_type = "Planet"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { const char *l_parent = "Body"; diff --git a/src/LuaPlayer.cpp b/src/LuaPlayer.cpp index be5837277..f5f98dc60 100644 --- a/src/LuaPlayer.cpp +++ b/src/LuaPlayer.cpp @@ -1,16 +1,16 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "LuaObject.h" -#include "LuaUtils.h" -#include "LuaConstants.h" -#include "Player.h" -#include "Pi.h" -#include "Game.h" -#include "SectorView.h" #include "EnumStrings.h" -#include "galaxy/Galaxy.h" +#include "Game.h" +#include "LuaConstants.h" +#include "LuaObject.h" #include "LuaPiGui.h" +#include "LuaUtils.h" +#include "Pi.h" +#include "Player.h" +#include "SectorView.h" +#include "galaxy/Galaxy.h" /* * Class: Player * @@ -254,7 +254,8 @@ static int l_get_is_mouse_active(lua_State *l) return 1; } -static int l_player_set_flight_control_state(lua_State *l) { +static int l_player_set_flight_control_state(lua_State *l) +{ Player *player = LuaObject::CheckFromLua(1); std::string stateName = LuaPull(l, 2); FlightControlState state = static_cast(EnumStrings::GetValue("ShipControllerFlightControlState", stateName.c_str())); @@ -328,8 +329,8 @@ static int l_get_current_delta_v(lua_State *l) static int l_get_remaining_delta_v(lua_State *l) { Player *player = LuaObject::CheckFromLua(1); - const double fuelmass = 1000*player->GetShipType()->fuelTankMass * player->GetFuel(); - double remaining = player->GetShipType()->effectiveExhaustVelocity * log(player->GetMass()/(player->GetMass()-fuelmass)); + const double fuelmass = 1000 * player->GetShipType()->fuelTankMass * player->GetFuel(); + double remaining = player->GetShipType()->effectiveExhaustVelocity * log(player->GetMass() / (player->GetMass() - fuelmass)); LuaPush(l, remaining); return 1; @@ -355,8 +356,9 @@ static int l_get_remaining_delta_v(lua_State *l) * stable */ -static std::map thrusters_map = { { "forward", THRUSTER_FORWARD }, - { "reverse", THRUSTER_REVERSE } , +static std::map thrusters_map = { + { "forward", THRUSTER_FORWARD }, + { "reverse", THRUSTER_REVERSE }, }; static int l_get_acceleration(lua_State *l) @@ -469,23 +471,23 @@ static int l_get_maneuver_velocity(lua_State *l) static int l_get_heading_pitch_roll(lua_State *l) { - // Player *player = LuaObject::CheckFromLua(1); - std::string type = LuaPull(l, 2); - PlaneType pt = PlaneType::PARENT; - if(!type.compare("system-wide")) { + // Player *player = LuaObject::CheckFromLua(1); + std::string type = LuaPull(l, 2); + PlaneType pt = PlaneType::PARENT; + if (!type.compare("system-wide")) { pt = PlaneType::PARENT; - } else if(!type.compare("planet")) { + } else if (!type.compare("planet")) { pt = PlaneType::ROTATIONAL; - } else { + } else { Output("LuaPlayer: l_get_heading_pitch_roll called with unknown type %s\n", type.c_str()); return 0; } - std::tuple res = Pi::game->GetWorldView()->CalculateHeadingPitchRoll(pt); - LuaPush(l, std::get<0>(res)); - LuaPush(l, std::get<1>(res)); - LuaPush(l, std::get<2>(res)); - return 3; + std::tuple res = Pi::game->GetWorldView()->CalculateHeadingPitchRoll(pt); + LuaPush(l, std::get<0>(res)); + LuaPush(l, std::get<1>(res)); + LuaPush(l, std::get<2>(res)); + return 3; } static int l_set_rotation_damping(lua_State *l) @@ -516,10 +518,10 @@ static int l_get_gps(lua_State *l) vector3d pos = Pi::player->GetPosition(); double center_dist = pos.Length(); auto frame = player->GetFrame(); - if(frame) { + if (frame) { Body *astro = frame->GetBody(); - if(astro && astro->IsType(Object::TERRAINBODY)) { - TerrainBody* terrain = static_cast(astro); + if (astro && astro->IsType(Object::TERRAINBODY)) { + TerrainBody *terrain = static_cast(astro); if (!frame->IsRotFrame()) frame = frame->GetRotFrame(); vector3d surface_pos = pos.Normalized(); @@ -552,7 +554,7 @@ static int l_get_alert_state(lua_State *l) { Player *player = LuaObject::CheckFromLua(1); Ship::AlertState state = player->GetAlertState(); - switch(state) { + switch (state) { case Ship::AlertState::ALERT_NONE: lua_pushnil(l); break; @@ -597,43 +599,45 @@ static int l_player_is_hyperspace_active(lua_State *l) return 1; } -template <> const char *LuaObject::s_type = "Player"; +template <> +const char *LuaObject::s_type = "Player"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "Ship"; static const luaL_Reg l_methods[] = { { "IsPlayer", l_player_is_player }, - { "GetNavTarget", l_get_nav_target }, - { "SetNavTarget", l_set_nav_target }, - { "SetSetSpeedTarget", l_set_set_speed_target }, - { "ChangeSetSpeed", l_change_set_speed }, - { "GetCombatTarget", l_get_combat_target }, - { "SetCombatTarget", l_set_combat_target }, + { "GetNavTarget", l_get_nav_target }, + { "SetNavTarget", l_set_nav_target }, + { "SetSetSpeedTarget", l_set_set_speed_target }, + { "ChangeSetSpeed", l_change_set_speed }, + { "GetCombatTarget", l_get_combat_target }, + { "SetCombatTarget", l_set_combat_target }, { "GetHyperspaceTarget", l_get_hyperspace_target }, { "SetHyperspaceTarget", l_set_hyperspace_target }, - { "GetDistanceToZeroV", l_get_distance_to_zero_v }, + { "GetDistanceToZeroV", l_get_distance_to_zero_v }, { "GetHeadingPitchRoll", l_get_heading_pitch_roll }, - { "GetMaxDeltaV", l_get_max_delta_v }, - { "GetCurrentDeltaV", l_get_current_delta_v }, - { "GetRemainingDeltaV", l_get_remaining_delta_v }, + { "GetMaxDeltaV", l_get_max_delta_v }, + { "GetCurrentDeltaV", l_get_current_delta_v }, + { "GetRemainingDeltaV", l_get_remaining_delta_v }, { "GetManeuverVelocity", l_get_maneuver_velocity }, - { "GetManeuverTime", l_get_maneuver_time }, - { "GetAcceleration", l_get_acceleration }, - { "IsMouseActive", l_get_is_mouse_active }, - { "GetMouseDirection", l_get_mouse_direction }, - { "GetRotationDamping", l_get_rotation_damping }, - { "SetRotationDamping", l_set_rotation_damping }, - { "GetGPS", l_get_gps }, - { "ToggleRotationDamping", l_toggle_rotation_damping }, - { "GetAlertState", l_get_alert_state }, - { "GetLowThrustPower", l_get_low_thrust_power }, - { "SetLowThrustPower", l_set_low_thrust_power }, - { "IsHyperspaceActive", l_player_is_hyperspace_active }, - { "GetHyperspaceCountdown", l_player_get_hyperspace_countdown }, - { "SetFlightControlState", l_player_set_flight_control_state }, + { "GetManeuverTime", l_get_maneuver_time }, + { "GetAcceleration", l_get_acceleration }, + { "IsMouseActive", l_get_is_mouse_active }, + { "GetMouseDirection", l_get_mouse_direction }, + { "GetRotationDamping", l_get_rotation_damping }, + { "SetRotationDamping", l_set_rotation_damping }, + { "GetGPS", l_get_gps }, + { "ToggleRotationDamping", l_toggle_rotation_damping }, + { "GetAlertState", l_get_alert_state }, + { "GetLowThrustPower", l_get_low_thrust_power }, + { "SetLowThrustPower", l_set_low_thrust_power }, + { "IsHyperspaceActive", l_player_is_hyperspace_active }, + { "GetHyperspaceCountdown", l_player_get_hyperspace_countdown }, + { "SetFlightControlState", l_player_set_flight_control_state }, { 0, 0 } }; diff --git a/src/LuaPropertiedObject.cpp b/src/LuaPropertiedObject.cpp index 45250bf5f..c961589f6 100644 --- a/src/LuaPropertiedObject.cpp +++ b/src/LuaPropertiedObject.cpp @@ -16,29 +16,31 @@ * The UI is a big user of this feature, see for details. */ - class PropertyConnection : public LuaWrappable { public: - PropertyConnection(const sigc::connection &conn) : m_connection(conn) {} + PropertyConnection(const sigc::connection &conn) : + m_connection(conn) {} void Disconnect() { m_connection.disconnect(); } + private: sigc::connection m_connection; }; class LuaPropertyConnection { public: - - static int l_disconnect(lua_State *l) { + static int l_disconnect(lua_State *l) + { PropertyConnection *conn = LuaObject::CheckFromLua(1); conn->Disconnect(); return 0; } - }; -template <> const char *LuaObject::s_type = "PropertyConnection"; +template <> +const char *LuaObject::s_type = "PropertyConnection"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { { "Disconnect", LuaPropertyConnection::l_disconnect }, @@ -48,16 +50,13 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::CreateClass(s_type, 0, l_methods, 0, 0); } - - class LuaPropertiedObject { public: - -/* + /* * Group: Methods */ -/* + /* * Method: Connect * * Register a function to be called when the named property changes. @@ -98,7 +97,8 @@ public: * experimental */ - static void _signal_trampoline(PropertyMap &map, const std::string &k, LuaRef ref, lua_State *l) { + static void _signal_trampoline(PropertyMap &map, const std::string &k, LuaRef ref, lua_State *l) + { ref.PushCopyToStack(); lua_pushlstring(l, k.c_str(), k.size()); map.PushLuaTable(); @@ -108,7 +108,8 @@ public: pi_lua_protected_call(l, 2, 0); } - static int l_connect(lua_State *l) { + static int l_connect(lua_State *l) + { PropertiedObject *po = LuaObject::CheckFromLua(1); const std::string propertyName(luaL_checkstring(l, 2)); luaL_checktype(l, 3, LUA_TFUNCTION); @@ -119,12 +120,13 @@ public: LuaObject::PushToLua(PropertyConnection(conn)); return 1; } - }; -template <> const char *LuaObject::s_type = "PropertiedObject"; +template <> +const char *LuaObject::s_type = "PropertiedObject"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { { "Connect", LuaPropertiedObject::l_connect }, diff --git a/src/LuaPushPull.h b/src/LuaPushPull.h index 5bc8aa732..9e0dda5dc 100644 --- a/src/LuaPushPull.h +++ b/src/LuaPushPull.h @@ -10,74 +10,84 @@ #include #include -inline void pi_lua_generic_push(lua_State * l, bool value) { lua_pushboolean(l, value); } -inline void pi_lua_generic_push(lua_State * l, int value) { lua_pushinteger(l, value); } -inline void pi_lua_generic_push(lua_State * l, unsigned int value) { lua_pushinteger(l, value); } -inline void pi_lua_generic_push(lua_State * l, double value) { lua_pushnumber(l, value); } -inline void pi_lua_generic_push(lua_State * l, const char * value) { lua_pushstring(l, value); } -inline void pi_lua_generic_push(lua_State * l, const std::string & value) { +inline void pi_lua_generic_push(lua_State *l, bool value) { lua_pushboolean(l, value); } +inline void pi_lua_generic_push(lua_State *l, int value) { lua_pushinteger(l, value); } +inline void pi_lua_generic_push(lua_State *l, unsigned int value) { lua_pushinteger(l, value); } +inline void pi_lua_generic_push(lua_State *l, double value) { lua_pushnumber(l, value); } +inline void pi_lua_generic_push(lua_State *l, const char *value) { lua_pushstring(l, value); } +inline void pi_lua_generic_push(lua_State *l, const std::string &value) +{ lua_pushlstring(l, value.c_str(), value.size()); } -inline void pi_lua_generic_pull(lua_State * l, int index, bool & out) { out = lua_toboolean(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, int & out) { out = luaL_checkinteger(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, unsigned int & out) { out = luaL_checkunsigned(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, float & out) { out = luaL_checknumber(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, double & out) { out = luaL_checknumber(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, const char * & out) { out = luaL_checkstring(l, index); } -inline void pi_lua_generic_pull(lua_State * l, int index, std::string & out) { +inline void pi_lua_generic_pull(lua_State *l, int index, bool &out) { out = lua_toboolean(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, int &out) { out = luaL_checkinteger(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, unsigned int &out) { out = luaL_checkunsigned(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, float &out) { out = luaL_checknumber(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, double &out) { out = luaL_checknumber(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, const char *&out) { out = luaL_checkstring(l, index); } +inline void pi_lua_generic_pull(lua_State *l, int index, std::string &out) +{ size_t len; const char *buf = luaL_checklstring(l, index, &len); std::string(buf, len).swap(out); } template -inline void LuaPush(lua_State *l, Type value) { +inline void LuaPush(lua_State *l, Type value) +{ pi_lua_generic_push(l, value); } template -inline Type LuaPull(lua_State *l, int index) { +inline Type LuaPull(lua_State *l, int index) +{ Type value; pi_lua_generic_pull(l, index, value); return value; } -inline bool pi_lua_strict_pull(lua_State * l, int index, bool & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, bool &out) +{ if (lua_type(l, index) == LUA_TBOOLEAN) { out = lua_toboolean(l, index); return true; } return false; } -inline bool pi_lua_strict_pull(lua_State * l, int index, int & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, int &out) +{ if (lua_type(l, index) == LUA_TNUMBER) { out = lua_tointeger(l, index); return true; } return false; } -inline bool pi_lua_strict_pull(lua_State * l, int index, float & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, float &out) +{ if (lua_type(l, index) == LUA_TNUMBER) { out = lua_tonumber(l, index); return true; } return false; } -inline bool pi_lua_strict_pull(lua_State * l, int index, double & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, double &out) +{ if (lua_type(l, index) == LUA_TNUMBER) { out = lua_tonumber(l, index); return true; } return false; } -inline bool pi_lua_strict_pull(lua_State * l, int index, const char * & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, const char *&out) +{ if (lua_type(l, index) == LUA_TSTRING) { out = lua_tostring(l, index); return true; } return false; } -inline bool pi_lua_strict_pull(lua_State * l, int index, std::string & out) { +inline bool pi_lua_strict_pull(lua_State *l, int index, std::string &out) +{ if (lua_type(l, index) == LUA_TSTRING) { size_t len; const char *buf = lua_tolstring(l, index, &len); @@ -86,89 +96,98 @@ inline bool pi_lua_strict_pull(lua_State * l, int index, std::string & out) { } return false; } -template -inline void pi_lua_multiple_push(lua_State *l, Types ...args); +template +inline void pi_lua_multiple_push(lua_State *l, Types... args); #if defined(_MSC_VER) // Non-variadic version for MSVC template -inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1) { +inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1) +{ pi_lua_generic_push(l, arg1); } template -inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2) { +inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2) +{ pi_lua_generic_push(l, arg1); pi_lua_generic_push(l, arg2); } template -inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3) { +inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3) +{ pi_lua_generic_push(l, arg1); pi_lua_generic_push(l, arg2); pi_lua_generic_push(l, arg3); } template -inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { +inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) +{ pi_lua_generic_push(l, arg1); pi_lua_generic_push(l, arg2); pi_lua_generic_push(l, arg3); pi_lua_generic_push(l, arg4); } #else // Just use the normal variadic version -template -inline void pi_lua_multiple_push(lua_State *l, Head arg1, Tail ...rest) { +template +inline void pi_lua_multiple_push(lua_State *l, Head arg1, Tail... rest) +{ pi_lua_generic_push(l, arg1); pi_lua_multiple_push(l, rest...); } #endif -inline void pi_lua_multiple_push(lua_State *l) { +inline void pi_lua_multiple_push(lua_State *l) +{ return; } - #if defined(_MSC_VER) template -inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) { +inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) +{ beg = lua_absindex(l, beg); Arg1 arg1; Arg2 arg2; pi_lua_generic_pull(l, beg, arg1); - pi_lua_generic_pull(l, beg+1, arg2); + pi_lua_generic_pull(l, beg + 1, arg2); return std::make_tuple(arg1, arg2); } template -inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) { +inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) +{ beg = lua_absindex(l, beg); Arg1 arg1; Arg2 arg2; Arg3 arg3; pi_lua_generic_pull(l, beg, arg1); - pi_lua_generic_pull(l, beg+1, arg2); - pi_lua_generic_pull(l, beg+2, arg3); + pi_lua_generic_pull(l, beg + 1, arg2); + pi_lua_generic_pull(l, beg + 2, arg3); return std::make_tuple(arg1, arg2, arg3); } template -inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) { +inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) +{ beg = lua_absindex(l, beg); Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; pi_lua_generic_pull(l, beg, arg1); - pi_lua_generic_pull(l, beg+1, arg2); - pi_lua_generic_pull(l, beg+2, arg3); - pi_lua_generic_pull(l, beg+3, arg4); + pi_lua_generic_pull(l, beg + 1, arg2); + pi_lua_generic_pull(l, beg + 2, arg3); + pi_lua_generic_pull(l, beg + 3, arg4); return std::make_tuple(arg1, arg2, arg3, arg4); } #else // The _bogus parameter is used to bring the empty type list case into the template world // to solve name resolution problems. -template -inline std::tuple __helper_pi_lua_multiple_pull(lua_State *l, int beg) { +template +inline std::tuple __helper_pi_lua_multiple_pull(lua_State *l, int beg) +{ beg = lua_absindex(l, beg); - std::tuple rest = __helper_pi_lua_multiple_pull<_bogus, Tail...>(l, beg+1); + std::tuple rest = __helper_pi_lua_multiple_pull<_bogus, Tail...>(l, beg + 1); Head hd; pi_lua_generic_pull(l, beg, hd); std::tuple first(hd); @@ -176,12 +195,14 @@ inline std::tuple __helper_pi_lua_multiple_pull(lua_State *l, int } template -inline std::tuple<> __helper_pi_lua_multiple_pull(lua_State *l, int beg) { +inline std::tuple<> __helper_pi_lua_multiple_pull(lua_State *l, int beg) +{ return std::tuple<>(); } -template -inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) { +template +inline std::tuple pi_lua_multiple_pull(lua_State *l, int beg) +{ return __helper_pi_lua_multiple_pull<0, Types...>(l, beg); } #endif diff --git a/src/LuaRand.cpp b/src/LuaRand.cpp index eb9d27e3a..edece7910 100644 --- a/src/LuaRand.cpp +++ b/src/LuaRand.cpp @@ -43,17 +43,16 @@ static int l_rand_new(lua_State *l) { std::unique_ptr rng(new Random()); switch (lua_type(l, 1)) { - case LUA_TSTRING: - { - size_t sz; - const char *str = lua_tolstring(l, 1, &sz); + case LUA_TSTRING: { + size_t sz; + const char *str = lua_tolstring(l, 1, &sz); - // Note, these are inputs as well as outputs! They must be initialised. - Uint32 hashes[2] = { 0u, 0u }; - lookup3_hashlittle2(str, sz, hashes+0, hashes+1); - rng->seed(hashes, 2); - break; - } + // Note, these are inputs as well as outputs! They must be initialised. + Uint32 hashes[2] = { 0u, 0u }; + lookup3_hashlittle2(str, sz, hashes + 0, hashes + 1); + rng->seed(hashes, 2); + break; + } case LUA_TNUMBER: rng->seed(Uint32(lua_tonumber(l, 1))); break; @@ -105,12 +104,10 @@ static int l_rand_number(lua_State *l) if (lua_isnumber(l, 2) && lua_isnumber(l, 3)) { min = lua_tonumber(l, 2); max = lua_tonumber(l, 3); - } - else if (lua_isnumber(l, 2)) { + } else if (lua_isnumber(l, 2)) { min = 0.0; max = lua_tonumber(l, 2); - } - else { + } else { lua_pushnumber(l, rand->Double()); return 1; } @@ -195,12 +192,10 @@ static int l_rand_normal(lua_State *l) if (lua_isnumber(l, 2) && lua_isnumber(l, 3)) { mean = lua_tonumber(l, 2); stddev = lua_tonumber(l, 3); - } - else if (lua_isnumber(l, 2)) { + } else if (lua_isnumber(l, 2)) { mean = lua_tonumber(l, 2); stddev = 1; - } - else { + } else { lua_pushnumber(l, rand->Normal()); return 1; } @@ -249,14 +244,12 @@ static int l_rand_integer(lua_State *l) if (lua_isnumber(l, 2) && lua_isnumber(l, 3)) { min = lua_tointeger(l, 2); max = lua_tointeger(l, 3); - } - else if (lua_isnumber(l, 2)) { + } else if (lua_isnumber(l, 2)) { min = 0; max = lua_tointeger(l, 2); - } - else { - lua_pushnumber(l, rand->Int32()); - return 1; + } else { + lua_pushnumber(l, rand->Int32()); + return 1; } if (min > max) @@ -266,15 +259,17 @@ static int l_rand_integer(lua_State *l) return 1; } -template <> const char *LuaObject::s_type = "Rand"; +template <> +const char *LuaObject::s_type = "Rand"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { - { "New", l_rand_new }, - { "Number", l_rand_number }, + { "New", l_rand_new }, + { "Number", l_rand_number }, { "Poisson", l_rand_poisson }, - { "Normal", l_rand_normal }, + { "Normal", l_rand_normal }, { "Integer", l_rand_integer }, { 0, 0 } }; diff --git a/src/LuaRef.cpp b/src/LuaRef.cpp index 7900f69df..756862cdd 100644 --- a/src/LuaRef.cpp +++ b/src/LuaRef.cpp @@ -2,17 +2,22 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaRef.h" +#include "GameSaveError.h" #include "Lua.h" #include "Pi.h" -#include "GameSaveError.h" #include -LuaRef::LuaRef(const LuaRef & ref): m_lua(ref.m_lua), m_id(ref.m_id), m_copycount(ref.m_copycount) { +LuaRef::LuaRef(const LuaRef &ref) : + m_lua(ref.m_lua), + m_id(ref.m_id), + m_copycount(ref.m_copycount) +{ if (m_lua && m_id != LUA_NOREF) ++(*m_copycount); } -const LuaRef & LuaRef::operator=(const LuaRef & ref) { +const LuaRef &LuaRef::operator=(const LuaRef &ref) +{ if (&ref == this) return ref; if (m_id != LUA_NOREF && m_lua) { @@ -22,16 +27,18 @@ const LuaRef & LuaRef::operator=(const LuaRef & ref) { m_lua = ref.m_lua; m_id = ref.m_id; m_copycount = ref.m_copycount; - if(m_lua && m_id) + if (m_lua && m_id) ++(*m_copycount); return *this; } -LuaRef::~LuaRef() { - Unref(); +LuaRef::~LuaRef() +{ + Unref(); } -void LuaRef::Unref() { +void LuaRef::Unref() +{ if (m_id != LUA_NOREF && m_lua) { --(*m_copycount); m_id = LUA_NOREF; @@ -39,7 +46,8 @@ void LuaRef::Unref() { } } -bool LuaRef::operator==(const LuaRef & ref) const { +bool LuaRef::operator==(const LuaRef &ref) const +{ if (ref.m_lua != m_lua) return false; if (ref.m_id == m_id) @@ -52,7 +60,8 @@ bool LuaRef::operator==(const LuaRef & ref) const { return return_value; } -void LuaRef::CheckCopyCount() { +void LuaRef::CheckCopyCount() +{ if (*m_copycount <= 0) { delete m_copycount; if (!m_lua) @@ -63,7 +72,10 @@ void LuaRef::CheckCopyCount() { } } -LuaRef::LuaRef(lua_State * l, int index): m_lua(l), m_id(0) { +LuaRef::LuaRef(lua_State *l, int index) : + m_lua(l), + m_id(0) +{ assert(m_lua && index); if (index == LUA_NOREF) { m_copycount = new int(0); @@ -80,8 +92,8 @@ LuaRef::LuaRef(lua_State * l, int index): m_lua(l), m_id(0) { m_copycount = new int(1); } - -void LuaRef::PushCopyToStack() const { +void LuaRef::PushCopyToStack() const +{ assert(m_lua && m_id != LUA_NOREF); PushGlobalToStack(); lua_rawgeti(m_lua, -1, m_id); @@ -95,7 +107,7 @@ void LuaRef::SaveToJson(Json &jsonObj) LUA_DEBUG_START(m_lua); lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiSerializer"); - LuaSerializer *serializer = static_cast(lua_touserdata(m_lua, -1)); + LuaSerializer *serializer = static_cast(lua_touserdata(m_lua, -1)); lua_pop(m_lua, 1); if (!serializer) { @@ -114,12 +126,14 @@ void LuaRef::SaveToJson(Json &jsonObj) void LuaRef::LoadFromJson(const Json &jsonObj) { - if (!m_lua) { m_lua = Lua::manager->GetLuaState(); } + if (!m_lua) { + m_lua = Lua::manager->GetLuaState(); + } LUA_DEBUG_START(m_lua); lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiSerializer"); - LuaSerializer *serializer = static_cast(lua_touserdata(m_lua, -1)); + LuaSerializer *serializer = static_cast(lua_touserdata(m_lua, -1)); lua_pop(m_lua, 1); if (!serializer) { @@ -139,7 +153,7 @@ void LuaRef::LoadFromJson(const Json &jsonObj) // Lua stack: loaded lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiLuaRefLoadTable"); // loaded, reftable lua_pushvalue(m_lua, -2); // loaded, reftable, copy - lua_gettable(m_lua, -2); // loaded, reftable, luaref + lua_gettable(m_lua, -2); // loaded, reftable, luaref // Check whether this table has been referenced before if (lua_isnil(m_lua, -1)) { // If not, mark it as referenced @@ -147,8 +161,7 @@ void LuaRef::LoadFromJson(const Json &jsonObj) lua_pushvalue(m_lua, -3); lua_pushlightuserdata(m_lua, this); lua_settable(m_lua, -4); - } - else { + } else { LuaRef *origin = static_cast(lua_touserdata(m_lua, -1)); *this = *origin; } diff --git a/src/LuaRef.h b/src/LuaRef.h index b87be296e..e81ee9f5b 100644 --- a/src/LuaRef.h +++ b/src/LuaRef.h @@ -4,53 +4,60 @@ #ifndef _LUAREF_H #define _LUAREF_H -#include #include "JsonFwd.h" -#include #include +#include +#include class LuaRef { public: - LuaRef(): m_lua(0), m_id(LUA_NOREF), m_copycount(new int(0)) {} - LuaRef(lua_State * l, int index); - LuaRef(const LuaRef & ref); + LuaRef() : + m_lua(0), + m_id(LUA_NOREF), + m_copycount(new int(0)) {} + LuaRef(lua_State *l, int index); + LuaRef(const LuaRef &ref); ~LuaRef(); - const LuaRef & operator=(const LuaRef & ref); - bool operator==(const LuaRef & ref) const; + const LuaRef &operator=(const LuaRef &ref); + bool operator==(const LuaRef &ref) const; void PushCopyToStack() const; - lua_State * GetLua() const { return m_lua; } + lua_State *GetLua() const { return m_lua; } bool IsValid() const { return m_lua && m_id != LUA_NOREF; } void SaveToJson(Json &jsonObj); void LoadFromJson(const Json &jsonObj); void Unref(); + private: - lua_State * m_lua; + lua_State *m_lua; int m_id; - int * m_copycount; + int *m_copycount; // Does everything we need: get the table, or create it if it doesn't exist. // Yay lua aux lib ! - void PushGlobalToStack() const {luaL_getsubtable(m_lua, LUA_REGISTRYINDEX, "LuaRef");} + void PushGlobalToStack() const { luaL_getsubtable(m_lua, LUA_REGISTRYINDEX, "LuaRef"); } void CheckCopyCount(); }; -inline void pi_lua_generic_push(lua_State *l, const LuaRef &r) { +inline void pi_lua_generic_push(lua_State *l, const LuaRef &r) +{ assert(r.GetLua() == l); r.PushCopyToStack(); } -inline void pi_lua_generic_pull(lua_State *l, int index, LuaRef &r) { - r = LuaRef(l, index); +inline void pi_lua_generic_pull(lua_State *l, int index, LuaRef &r) +{ + r = LuaRef(l, index); } -inline bool pi_lua_strict_pull(lua_State *l, int index, LuaRef &r) { - r = LuaRef(l, index); - return true; +inline bool pi_lua_strict_pull(lua_State *l, int index, LuaRef &r) +{ + r = LuaRef(l, index); + return true; } #endif diff --git a/src/LuaSerializer.cpp b/src/LuaSerializer.cpp index 38b3a4e10..7f94ff55a 100644 --- a/src/LuaSerializer.cpp +++ b/src/LuaSerializer.cpp @@ -2,9 +2,9 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaSerializer.h" -#include "LuaObject.h" #include "GameSaveError.h" #include "JsonUtils.h" +#include "LuaObject.h" // every module can save one object. that will usually be a table. we call // each serializer in turn and capture its return value we build a table like @@ -24,7 +24,6 @@ // for a module that is not currently loaded, we don't lose its data in the // next save - // pickler can handle simple types (boolean, number, string) and will drill // down into tables. it can do userdata assuming the appropriate Lua wrapper // class has registered a serializer and deseriaizer @@ -44,7 +43,6 @@ // oXXXX - object. XXX is type, followed by newline, followed by one // pickled item (typically t[able]) - // on serialize, if an item has a metatable with a "class" attribute, the // "Serialize" function under that namespace will be called with the type. the // data returned will then be serialized as an "object" above. @@ -104,88 +102,88 @@ void LuaSerializer::pickle(lua_State *l, int to_serialize, std::string &out, std } switch (lua_type(l, idx)) { - case LUA_TNIL: - break; + case LUA_TNIL: + break; - case LUA_TNUMBER: { - snprintf(buf, sizeof(buf), "f%g\n", lua_tonumber(l, idx)); - out += buf; - break; + case LUA_TNUMBER: { + snprintf(buf, sizeof(buf), "f%g\n", lua_tonumber(l, idx)); + out += buf; + break; + } + + case LUA_TBOOLEAN: { + snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0); + out += buf; + break; + } + + case LUA_TSTRING: { + size_t len; + const char *str = lua_tolstring(l, idx, &len); + snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", len); + out += buf; + out.append(str, len); + break; + } + + case LUA_TTABLE: { + lua_pushinteger(l, lua_Integer(lua_topointer(l, to_serialize))); // ptr + + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // ptr reftable + lua_pushvalue(l, -2); // ptr reftable ptr + lua_rawget(l, -2); // ptr reftable ??? + + if (!lua_isnil(l, -1)) { + out += "r"; + pickle(l, -3, out, key); + lua_pop(l, 3); // [empty] } - case LUA_TBOOLEAN: { - snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0); - out += buf; - break; - } + else { + out += "t"; - case LUA_TSTRING: { - size_t len; - const char *str = lua_tolstring(l, idx, &len); - snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", len); - out += buf; - out.append(str, len); - break; - } + lua_pushvalue(l, -3); // ptr reftable nil ptr + lua_pushvalue(l, to_serialize); // ptr reftable nil ptr table + lua_rawset(l, -4); // ptr reftable nil + pickle(l, -3, out, key); + lua_pop(l, 3); // [empty] - case LUA_TTABLE: { - lua_pushinteger(l, lua_Integer(lua_topointer(l, to_serialize))); // ptr + lua_pushvalue(l, idx); + lua_pushnil(l); + while (lua_next(l, -2)) { - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // ptr reftable - lua_pushvalue(l, -2); // ptr reftable ptr - lua_rawget(l, -2); // ptr reftable ??? - - if (!lua_isnil(l, -1)) { - out += "r"; - pickle(l, -3, out, key); - lua_pop(l, 3); // [empty] - } - - else { - out += "t"; - - lua_pushvalue(l, -3); // ptr reftable nil ptr - lua_pushvalue(l, to_serialize); // ptr reftable nil ptr table - lua_rawset(l, -4); // ptr reftable nil - pickle(l, -3, out, key); - lua_pop(l, 3); // [empty] - - lua_pushvalue(l, idx); - lua_pushnil(l); - while (lua_next(l, -2)) { - - lua_pushvalue(l, -2); - const char *k = lua_tostring(l, -1); - std::string new_key = key + "." + (k? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">"); - lua_pop(l, 1); - - // Copy the values to pickle, as they might be mutated by the pickling process. - pickle(l, -2, out, new_key); - pickle(l, -1, out, new_key); - lua_pop(l, 1); - } + lua_pushvalue(l, -2); + const char *k = lua_tostring(l, -1); + std::string new_key = key + "." + (k ? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">"); + lua_pop(l, 1); + + // Copy the values to pickle, as they might be mutated by the pickling process. + pickle(l, -2, out, new_key); + pickle(l, -1, out, new_key); lua_pop(l, 1); - out += "n"; } - - break; + lua_pop(l, 1); + out += "n"; } - case LUA_TUSERDATA: { - out += "u"; + break; + } - LuaObjectBase *lo = static_cast(lua_touserdata(l, idx)); - void *o = lo->GetObject(); - if (!o) - Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType()); + case LUA_TUSERDATA: { + out += "u"; - out += lo->Serialize(); - break; - } + LuaObjectBase *lo = static_cast(lua_touserdata(l, idx)); + void *o = lo->GetObject(); + if (!o) + Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType()); - default: - Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx))); - break; + out += lo->Serialize(); + break; + } + + default: + Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx))); + break; } if (idx != lua_absindex(l, to_serialize)) // It means we called a transformation function on the data, so we clean it up. @@ -209,118 +207,118 @@ const char *LuaSerializer::unpickle(lua_State *l, const char *pos) switch (type) { - case 'f': { - char *end; - double f = strtod(pos, &end); - if (pos == end) throw SavedGameCorruptException(); - lua_pushnumber(l, f); - pos = end+1; // skip newline - break; - } + case 'f': { + char *end; + double f = strtod(pos, &end); + if (pos == end) throw SavedGameCorruptException(); + lua_pushnumber(l, f); + pos = end + 1; // skip newline + break; + } - case 'b': { - if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); - lua_pushboolean(l, *pos == '1'); - pos++; - break; - } + case 'b': { + if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); + lua_pushboolean(l, *pos == '1'); + pos++; + break; + } - case 's': { - char *end; - int len = strtol(pos, const_cast(&end), 0); - if (pos == end) throw SavedGameCorruptException(); - end++; // skip newline - lua_pushlstring(l, end, len); - pos = end + len; - break; - } + case 's': { + char *end; + int len = strtol(pos, const_cast(&end), 0); + if (pos == end) throw SavedGameCorruptException(); + end++; // skip newline + lua_pushlstring(l, end, len); + pos = end + len; + break; + } - case 't': { - lua_newtable(l); + case 't': { + lua_newtable(l); - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); + pos = unpickle(l, pos); + lua_pushvalue(l, -3); + lua_rawset(l, -3); + lua_pop(l, 1); + + while (*pos != 'n') { + pos = unpickle(l, pos); pos = unpickle(l, pos); - lua_pushvalue(l, -3); lua_rawset(l, -3); - lua_pop(l, 1); - - while (*pos != 'n') { - pos = unpickle(l, pos); - pos = unpickle(l, pos); - lua_rawset(l, -3); - } - pos++; - - break; } + pos++; - case 'r': { - pos = unpickle(l, pos); + break; + } - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); - lua_pushvalue(l, -2); - lua_rawget(l, -2); + case 'r': { + pos = unpickle(l, pos); - if (lua_isnil(l, -1)) - throw SavedGameCorruptException(); + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); + lua_pushvalue(l, -2); + lua_rawget(l, -2); + + if (lua_isnil(l, -1)) + throw SavedGameCorruptException(); + + lua_insert(l, -3); + lua_pop(l, 2); + + break; + } + + case 'u': { + const char *end; + if (!LuaObjectBase::Deserialize(pos, &end)) + throw SavedGameCorruptException(); + pos = end; + break; + } + + case 'o': { + const char *end = strchr(pos, '\n'); + if (!end) throw SavedGameCorruptException(); + int len = end - pos; + end++; // skip newline + + const char *cl = pos; + + // unpickle the object, and insert it beneath the method table value + pos = unpickle(l, end); + + // If it is a reference, don't run the unserializer. It has either + // already been run, or the data is still building (cyclic + // references will do that to you.) + if (*end != 'r') { + // get PiSerializerClasses[typename] + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses"); + lua_pushlstring(l, cl, len); + lua_gettable(l, -2); + lua_remove(l, -2); + + if (lua_isnil(l, -1)) { + lua_pop(l, 2); + break; + } + + lua_getfield(l, -1, "Unserialize"); + if (lua_isnil(l, -1)) { + lua_pushlstring(l, cl, len); + luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); + } lua_insert(l, -3); - lua_pop(l, 2); + lua_pop(l, 1); - break; + pi_lua_protected_call(l, 1, 1); } - case 'u': { - const char *end; - if (!LuaObjectBase::Deserialize(pos, &end)) - throw SavedGameCorruptException(); - pos = end; - break; - } + break; + } - case 'o': { - const char *end = strchr(pos, '\n'); - if (!end) throw SavedGameCorruptException(); - int len = end - pos; - end++; // skip newline - - const char *cl = pos; - - // unpickle the object, and insert it beneath the method table value - pos = unpickle(l, end); - - // If it is a reference, don't run the unserializer. It has either - // already been run, or the data is still building (cyclic - // references will do that to you.) - if (*end != 'r') { - // get PiSerializerClasses[typename] - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses"); - lua_pushlstring(l, cl, len); - lua_gettable(l, -2); - lua_remove(l, -2); - - if (lua_isnil(l, -1)) { - lua_pop(l, 2); - break; - } - - lua_getfield(l, -1, "Unserialize"); - if (lua_isnil(l, -1)) { - lua_pushlstring(l, cl, len); - luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); - } - - lua_insert(l, -3); - lua_pop(l, 1); - - pi_lua_protected_call(l, 1, 1); - } - - break; - } - - default: - throw SavedGameCorruptException(); + default: + throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); @@ -376,94 +374,94 @@ void LuaSerializer::pickle_json(lua_State *l, int to_serialize, Json &out, const } switch (lua_type(l, idx)) { - case LUA_TNIL: - out = Json(); - break; + case LUA_TNIL: + out = Json(); + break; - case LUA_TBOOLEAN: { - out = Json(static_cast(lua_toboolean(l, idx))); - break; - } + case LUA_TBOOLEAN: { + out = Json(static_cast(lua_toboolean(l, idx))); + break; + } + + case LUA_TSTRING: { + lua_pushvalue(l, idx); + size_t len; + const char *str = lua_tolstring(l, -1, &len); + out = Json(std::string(str, str + len)); + lua_pop(l, 1); + break; + } + + case LUA_TNUMBER: { + out = lua_tonumber(l, idx); + break; + } + + case LUA_TTABLE: { + lua_Integer ptr = lua_Integer(lua_topointer(l, to_serialize)); + lua_pushinteger(l, ptr); // ptr + + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // ptr reftable + lua_pushvalue(l, -2); // ptr reftable ptr + lua_rawget(l, -2); // ptr reftable ??? + + out["ref"] = ptr; + + if (!lua_isnil(l, -1)) { + lua_pop(l, 3); // [empty] + } else { + lua_pushvalue(l, -3); // ptr reftable nil ptr + lua_pushvalue(l, to_serialize); // ptr reftable nil ptr table + lua_rawset(l, -4); // ptr reftable nil + lua_pop(l, 3); // [empty] + + Json inner = Json::array(); - case LUA_TSTRING: { lua_pushvalue(l, idx); - size_t len; - const char *str = lua_tolstring(l, -1, &len); - out = Json(std::string(str, str + len)); - lua_pop(l, 1); - break; - } - - case LUA_TNUMBER: { - out = lua_tonumber(l, idx); - break; - } - - case LUA_TTABLE: { - lua_Integer ptr = lua_Integer(lua_topointer(l, to_serialize)); - lua_pushinteger(l, ptr); // ptr - - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // ptr reftable - lua_pushvalue(l, -2); // ptr reftable ptr - lua_rawget(l, -2); // ptr reftable ??? - - out["ref"] = ptr; - - if (!lua_isnil(l, -1)) { - lua_pop(l, 3); // [empty] - } else { - lua_pushvalue(l, -3); // ptr reftable nil ptr - lua_pushvalue(l, to_serialize); // ptr reftable nil ptr table - lua_rawset(l, -4); // ptr reftable nil - lua_pop(l, 3); // [empty] - - Json inner = Json::array(); - - lua_pushvalue(l, idx); - lua_pushnil(l); - while (lua_next(l, -2)) { - lua_pushvalue(l, -2); - const char *k = lua_tostring(l, -1); - std::string new_key = key + "." + (k? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">"); - lua_pop(l, 1); - - // Copy the values to pickle, as they might be mutated by the pickling process. - Json out_k, out_v; - - pickle_json(l, -2, out_k, new_key); - pickle_json(l, -1, out_v, new_key); - - inner.push_back(out_k); - inner.push_back(out_v); - - lua_pop(l, 1); - } + lua_pushnil(l); + while (lua_next(l, -2)) { + lua_pushvalue(l, -2); + const char *k = lua_tostring(l, -1); + std::string new_key = key + "." + (k ? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">"); lua_pop(l, 1); - out["table"] = Json(inner); + // Copy the values to pickle, as they might be mutated by the pickling process. + Json out_k, out_v; + + pickle_json(l, -2, out_k, new_key); + pickle_json(l, -1, out_v, new_key); + + inner.push_back(out_k); + inner.push_back(out_v); + + lua_pop(l, 1); } + lua_pop(l, 1); - break; + out["table"] = Json(inner); } - case LUA_TUSERDATA: { - LuaObjectBase *lo = static_cast(lua_touserdata(l, idx)); + break; + } - // Check that there is still an object attached. - // There might not be; e.g., this could be a core object which has been deleted where Lua holds a weak reference. - void *o = lo->GetObject(); - if (!o) - Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType()); + case LUA_TUSERDATA: { + LuaObjectBase *lo = static_cast(lua_touserdata(l, idx)); - Json obj = Json::object(); - lo->ToJson(obj); - out["userdata"] = obj; - break; - } + // Check that there is still an object attached. + // There might not be; e.g., this could be a core object which has been deleted where Lua holds a weak reference. + void *o = lo->GetObject(); + if (!o) + Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType()); - default: - Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx))); - break; + Json obj = Json::object(); + lo->ToJson(obj); + out["userdata"] = obj; + break; + } + + default: + Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx))); + break; } if (idx != lua_absindex(l, to_serialize)) // It means we called a transformation function on the data, so we clean it up. @@ -484,110 +482,117 @@ void LuaSerializer::unpickle_json(lua_State *l, const Json &value) luaL_error(l, "The Lua stack couldn't be extended (not enough memory?)"); switch (value.type()) { - case Json::value_t::null: - lua_pushnil(l); - break; - case Json::value_t::number_integer: - case Json::value_t::number_unsigned: - lua_pushinteger(l, value); + case Json::value_t::null: + lua_pushnil(l); + break; + case Json::value_t::number_integer: + case Json::value_t::number_unsigned: + lua_pushinteger(l, value); + LUA_DEBUG_CHECK(l, 1); + break; + case Json::value_t::number_float: + lua_pushnumber(l, value); + LUA_DEBUG_CHECK(l, 1); + break; + case Json::value_t::string: + // FIXME: Should do something to make sure we can unpickle strings that include null bytes. + // However I'm not sure that the JSON library actually supports strings containing nulls which would make it moot. + lua_pushstring(l, value.get().c_str()); + LUA_DEBUG_CHECK(l, 1); + break; + case Json::value_t::boolean: + lua_pushboolean(l, value); + LUA_DEBUG_CHECK(l, 1); + break; + case Json::value_t::array: + // Pickle doesn't emit array type values except as part of another structure. + throw SavedGameCorruptException(); + break; + case Json::value_t::object: + if (value.count("userdata")) { + if (!LuaObjectBase::FromJson(value["userdata"])) { + throw SavedGameCorruptException(); + } LUA_DEBUG_CHECK(l, 1); - break; - case Json::value_t::number_float: - lua_pushnumber(l, value); - LUA_DEBUG_CHECK(l, 1); - break; - case Json::value_t::string: - // FIXME: Should do something to make sure we can unpickle strings that include null bytes. - // However I'm not sure that the JSON library actually supports strings containing nulls which would make it moot. - lua_pushstring(l, value.get().c_str()); - LUA_DEBUG_CHECK(l, 1); - break; - case Json::value_t::boolean: - lua_pushboolean(l, value); - LUA_DEBUG_CHECK(l, 1); - break; - case Json::value_t::array: - // Pickle doesn't emit array type values except as part of another structure. - throw SavedGameCorruptException(); - break; - case Json::value_t::object: - if (value.count("userdata")) { - if (!LuaObjectBase::FromJson(value["userdata"])) { throw SavedGameCorruptException(); } + } else { + // Object, table, or table-reference. + if (value["ref"].is_null()) { + throw SavedGameCorruptException(); + } + + lua_Integer ptr = value["ref"]; + + if (value.count("table")) { + lua_newtable(l); + + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // [t] [refs] + lua_pushinteger(l, ptr); // [t] [refs] [key] + lua_pushvalue(l, -3); // [t] [refs] [key] [t] + lua_rawset(l, -3); // [t] [refs] + lua_pop(l, 1); // [t] + + const Json &inner = value["table"]; + if (inner.size() % 2 != 0) { + throw SavedGameCorruptException(); + } + for (size_t i = 0; i < inner.size(); i += 2) { + unpickle_json(l, inner[i + 0]); + unpickle_json(l, inner[i + 1]); + lua_rawset(l, -3); + } + LUA_DEBUG_CHECK(l, 1); } else { - // Object, table, or table-reference. - if (value["ref"].is_null()) { throw SavedGameCorruptException(); } + // Reference to a previously-pickled table. + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // [refs] + lua_pushinteger(l, ptr); // [refs] [key] + lua_rawget(l, -2); // [refs] [out] - lua_Integer ptr = value["ref"]; + if (lua_isnil(l, -1)) + throw SavedGameCorruptException(); + lua_remove(l, -2); // [out] + + LUA_DEBUG_CHECK(l, 1); + } + + if (value.count("lua_class")) { + const char *cl = value["lua_class"].get_ref().c_str(); + // If this was a full definition (not just a reference) then run the class's unserialiser function. if (value.count("table")) { - lua_newtable(l); - - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // [t] [refs] - lua_pushinteger(l, ptr); // [t] [refs] [key] - lua_pushvalue(l, -3); // [t] [refs] [key] [t] - lua_rawset(l, -3); // [t] [refs] - lua_pop(l, 1); // [t] - - const Json &inner = value["table"]; - if (inner.size() % 2 != 0) { throw SavedGameCorruptException(); } - for (size_t i = 0; i < inner.size(); i += 2) { - unpickle_json(l, inner[i+0]); - unpickle_json(l, inner[i+1]); - lua_rawset(l, -3); - } - - LUA_DEBUG_CHECK(l, 1); - } else { - // Reference to a previously-pickled table. - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // [refs] - lua_pushinteger(l, ptr); // [refs] [key] - lua_rawget(l, -2); // [refs] [out] - - if (lua_isnil(l, -1)) - throw SavedGameCorruptException(); - - lua_remove(l, -2); // [out] - - LUA_DEBUG_CHECK(l, 1); - } - - if (value.count("lua_class")) { - const char *cl = value["lua_class"].get_ref().c_str(); - // If this was a full definition (not just a reference) then run the class's unserialiser function. - if (value.count("table")) { - lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses"); - lua_pushstring(l, cl); - lua_gettable(l, -2); - lua_remove(l, -2); + lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses"); + lua_pushstring(l, cl); + lua_gettable(l, -2); + lua_remove(l, -2); + if (lua_isnil(l, -1)) { + lua_pop(l, 1); + } else { + lua_getfield(l, -1, "Unserialize"); // [t] [klass] [klass.Unserialize] if (lua_isnil(l, -1)) { - lua_pop(l, 1); + luaL_error(l, "No Unserialize method found for class '%s'\n", cl); } else { - lua_getfield(l, -1, "Unserialize"); // [t] [klass] [klass.Unserialize] - if (lua_isnil(l, -1)) { - luaL_error(l, "No Unserialize method found for class '%s'\n", cl); - } else { - lua_insert(l, -3); // [klass.Unserialize] [t] [klass] - lua_pop(l, 1); // [klass.Unserialize] [t] + lua_insert(l, -3); // [klass.Unserialize] [t] [klass] + lua_pop(l, 1); // [klass.Unserialize] [t] - pi_lua_protected_call(l, 1, 1); - } + pi_lua_protected_call(l, 1, 1); } } - LUA_DEBUG_CHECK(l, 1); } + LUA_DEBUG_CHECK(l, 1); } - break; + } + break; - default: - throw SavedGameCorruptException(); + default: + throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); } -void LuaSerializer::InitTableRefs() { +void LuaSerializer::InitTableRefs() +{ lua_State *l = Lua::manager->GetLuaState(); lua_pushlightuserdata(l, this); @@ -600,7 +605,8 @@ void LuaSerializer::InitTableRefs() { lua_setfield(l, LUA_REGISTRYINDEX, "PiLuaRefLoadTable"); } -void LuaSerializer::UninitTableRefs() { +void LuaSerializer::UninitTableRefs() +{ lua_State *l = Lua::manager->GetLuaState(); lua_pushnil(l); @@ -662,7 +668,9 @@ void LuaSerializer::FromJson(const Json &jsonObj) if (jsonObj.count("lua_modules_json")) { const Json &value = jsonObj["lua_modules_json"]; - if (!value.is_object()) { throw SavedGameCorruptException(); } + if (!value.is_object()) { + throw SavedGameCorruptException(); + } unpickle_json(l, value); } else if (jsonObj.count("lua_modules")) { std::string pickled = JsonToBinStr(jsonObj["lua_modules"]); @@ -773,16 +781,18 @@ int LuaSerializer::l_register_class(lua_State *l) return 0; } -template <> const char *LuaObject::s_type = "Serializer"; +template <> +const char *LuaObject::s_type = "Serializer"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "Register", LuaSerializer::l_register }, + { "Register", LuaSerializer::l_register }, { "RegisterClass", LuaSerializer::l_register_class }, { 0, 0 } }; diff --git a/src/LuaSerializer.h b/src/LuaSerializer.h index c9a8592ff..fdac52b4f 100644 --- a/src/LuaSerializer.h +++ b/src/LuaSerializer.h @@ -4,10 +4,10 @@ #ifndef _LUASERIALIZER_H #define _LUASERIALIZER_H +#include "DeleteEmitter.h" #include "LuaManager.h" #include "LuaObject.h" #include "LuaRef.h" -#include "DeleteEmitter.h" class LuaSerializer : public DeleteEmitter { friend class LuaObject; diff --git a/src/LuaServerAgent.cpp b/src/LuaServerAgent.cpp index 210c3b4a9..84f4e007b 100644 --- a/src/LuaServerAgent.cpp +++ b/src/LuaServerAgent.cpp @@ -6,8 +6,8 @@ #include "LuaServerAgent.h" #include "LuaObject.h" #include "LuaRef.h" -#include "ServerAgent.h" #include "Pi.h" +#include "ServerAgent.h" #include /* @@ -26,7 +26,7 @@ struct CallbackPair { lua(l), successCallback(l, successIndex), failCallback(l, failIndex) - {} + {} lua_State *lua; LuaRef successCallback; LuaRef failCallback; @@ -37,38 +37,38 @@ static Json _lua_to_json(lua_State *l, int idx) int data = lua_absindex(l, idx); switch (lua_type(l, data)) { - case LUA_TNIL: - return Json(); + case LUA_TNIL: + return Json(); - case LUA_TNUMBER: - return Json(lua_tonumber(l, data)); + case LUA_TNUMBER: + return Json(lua_tonumber(l, data)); - case LUA_TBOOLEAN: - return Json(lua_toboolean(l, data)); + case LUA_TBOOLEAN: + return Json(lua_toboolean(l, data)); - case LUA_TSTRING: - return Json(lua_tostring(l, data)); + case LUA_TSTRING: + return Json(lua_tostring(l, data)); - case LUA_TTABLE: { + case LUA_TTABLE: { - // XXX handle arrays + // XXX handle arrays - Json object(Json::objectValue); + Json object(Json::objectValue); - lua_pushnil(l); - while (lua_next(l, data)) { - const std::string key(luaL_checkstring(l, -2)); - Json value(_lua_to_json(l, -1)); - object[key] = value; - lua_pop(l, 1); - } - - return object; + lua_pushnil(l); + while (lua_next(l, data)) { + const std::string key(luaL_checkstring(l, -2)); + Json value(_lua_to_json(l, -1)); + object[key] = value; + lua_pop(l, 1); } - default: - luaL_error(l, "can't convert Lua type %s to JSON", lua_typename(l, lua_type(l, idx))); - return Json(); + return object; + } + + default: + luaL_error(l, "can't convert Lua type %s to JSON", lua_typename(l, lua_type(l, idx))); + return Json(); } // shouldn't get here @@ -82,46 +82,46 @@ static void _json_to_lua(lua_State *l, const Json &data) LUA_DEBUG_START(l); switch (data.type()) { - case Json::nullValue: - lua_pushnil(l); - break; + case Json::nullValue: + lua_pushnil(l); + break; - case Json::intValue: - case Json::uintValue: - case Json::realValue: - lua_pushnumber(l, data.asDouble()); - break; + case Json::intValue: + case Json::uintValue: + case Json::realValue: + lua_pushnumber(l, data.asDouble()); + break; - case Json::stringValue: { - const std::string &str(data.asString()); - lua_pushlstring(l, str.c_str(), str.size()); - break; + case Json::stringValue: { + const std::string &str(data.asString()); + lua_pushlstring(l, str.c_str(), str.size()); + break; + } + + case Json::booleanValue: + lua_pushboolean(l, data.asBool()); + break; + + case Json::arrayValue: { + lua_newtable(l); + for (int i = 0; i < int(data.size()); i++) { + lua_pushinteger(l, i + 1); + _json_to_lua(l, data[i]); + lua_rawset(l, -3); } + break; + } - case Json::booleanValue: - lua_pushboolean(l, data.asBool()); - break; - - case Json::arrayValue: { - lua_newtable(l); - for (int i = 0; i < int(data.size()); i++) { - lua_pushinteger(l, i+1); - _json_to_lua(l, data[i]); - lua_rawset(l, -3); - } - break; - } - - case Json::objectValue: { - lua_newtable(l); - for (Json::const_iterator i = data.begin(); i != data.end(); ++i) { - const std::string &key(i.key().asString()); - lua_pushlstring(l, key.c_str(), key.size()); - _json_to_lua(l, *i); - lua_rawset(l, -3); - } - break; + case Json::objectValue: { + lua_newtable(l); + for (Json::const_iterator i = data.begin(); i != data.end(); ++i) { + const std::string &key(i.key().asString()); + lua_pushlstring(l, key.c_str(), key.size()); + _json_to_lua(l, *i); + lua_rawset(l, -3); } + break; + } } LUA_DEBUG_END(l, 1); @@ -129,7 +129,7 @@ static void _json_to_lua(lua_State *l, const Json &data) static void _success_callback(const Json &data, void *userdata) { - CallbackPair *cp = reinterpret_cast(userdata); + CallbackPair *cp = reinterpret_cast(userdata); if (!cp->successCallback.IsValid()) return; cp->successCallback.PushCopyToStack(); @@ -142,7 +142,7 @@ static void _success_callback(const Json &data, void *userdata) static void _fail_callback(const std::string &error, void *userdata) { - CallbackPair *cp = reinterpret_cast(userdata); + CallbackPair *cp = reinterpret_cast(userdata); if (!cp->failCallback.IsValid()) return; cp->failCallback.PushCopyToStack(); diff --git a/src/LuaShip.cpp b/src/LuaShip.cpp index 6b9e7d97f..d648f78fe 100644 --- a/src/LuaShip.cpp +++ b/src/LuaShip.cpp @@ -1,23 +1,23 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "EnumStrings.h" +#include "LuaConstants.h" +#include "LuaMissile.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "LuaConstants.h" #include "LuaVector.h" -#include "EnumStrings.h" -#include "Ship.h" #include "Missile.h" -#include "LuaMissile.h" -#include "SpaceStation.h" +#include "Ship.h" #include "ShipType.h" +#include "SpaceStation.h" // #include "Sfx.h" -#include "Sound.h" -#include "Space.h" +#include "Game.h" +#include "HyperspaceCloud.h" #include "Pi.h" #include "Player.h" -#include "HyperspaceCloud.h" -#include "Game.h" +#include "Sound.h" +#include "Space.h" /* * Class: Ship @@ -89,7 +89,7 @@ static int l_ship_set_type(lua_State *l) Ship *s = LuaObject::CheckFromLua(1); const char *type = luaL_checkstring(l, 2); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); s->SetShipType(type); @@ -181,8 +181,8 @@ static int l_ship_set_hull_percent(lua_State *l) percent = float(luaL_checknumber(l, 2)); if (percent < 0.0f || percent > 100.0f) { pi_lua_warn(l, - "argument out of range: Ship{%s}:SetHullPercent(%g)", - s->GetLabel().c_str(), percent); + "argument out of range: Ship{%s}:SetHullPercent(%g)", + s->GetLabel().c_str(), percent); } } @@ -228,12 +228,12 @@ static int l_ship_set_fuel_percent(lua_State *l) percent = luaL_checknumber(l, 2); if (percent < 0.0 || percent > 100.0) { pi_lua_warn(l, - "argument out of range: Ship{%s}:SetFuelPercent(%g)", - s->GetLabel().c_str(), percent); + "argument out of range: Ship{%s}:SetFuelPercent(%g)", + s->GetLabel().c_str(), percent); } } - s->SetFuel(percent/100.0); + s->SetFuel(percent / 100.0); // This is required for the fuel to properly update when the game is paused. // Without this we can sell fuel indefinitely, or buy fuel without receiving // anything. This is a workaround - the proper fix is to prevent interactions @@ -352,8 +352,8 @@ static int l_ship_set_pattern(lua_State *l) Ship *s = LuaObject::CheckFromLua(1); unsigned int num = lua_tointeger(l, 2); SceneGraph::Model *model = s->GetModel(); - if(model && model->SupportsPatterns()) { - if (num > model->GetNumPatterns()-1) + if (model && model->SupportsPatterns()) { + if (num > model->GetNumPatterns() - 1) return luaL_error(l, "This pattern does not exist for this ship"); s->SetPattern(num); @@ -456,19 +456,19 @@ static int l_ship_set_ship_name(lua_State *l) * * experimental */ -static int l_ship_spawn_cargo(lua_State *l) { +static int l_ship_spawn_cargo(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); if (!lua_istable(l, 2)) { lua_pushboolean(l, false); } - CargoBody * c_body; + CargoBody *c_body; - if (lua_gettop(l) >= 3){ + if (lua_gettop(l) >= 3) { float lifeTime = lua_tonumber(l, 3); c_body = new CargoBody(LuaRef(l, 2), lifeTime); - } - else + } else c_body = new CargoBody(LuaRef(l, 2)); lua_pushboolean(l, s->SpawnCargo(c_body)); @@ -504,9 +504,10 @@ static int l_ship_get_docked_with(lua_State *l) return 1; } -static int l_ship_request_docking_clearance(lua_State *l) { +static int l_ship_request_docking_clearance(lua_State *l) +{ Ship *player = LuaObject::CheckFromLua(1); - SpaceStation *s = static_cast(LuaObject::CheckFromLua(2)); + SpaceStation *s = static_cast(LuaObject::CheckFromLua(2)); std::string msg; s->GetDockingClearance(player, msg); lua_pushstring(l, msg.c_str()); @@ -545,7 +546,6 @@ static int l_ship_undock(lua_State *l) return 1; } - /* Method: BlastOff * * Blast off if landed on a surface. @@ -554,7 +554,7 @@ static int l_ship_undock(lua_State *l) static int l_ship_blast_off(lua_State *l) { Ship *s = LuaObject::CheckFromLua(1); - if(!s->IsLanded()) + if (!s->IsLanded()) luaL_error(l, "Can't blast off if not already landed"); s->Blastoff(); return 0; @@ -595,13 +595,13 @@ static int l_ship_spawn_missile(lua_State *l) ShipType::Id missile_type(luaL_checkstring(l, 2)); if (missile_type != ShipType::MISSILE_UNGUIDED && - missile_type != ShipType::MISSILE_GUIDED && - missile_type != ShipType::MISSILE_SMART && - missile_type != ShipType::MISSILE_NAVAL) + missile_type != ShipType::MISSILE_GUIDED && + missile_type != ShipType::MISSILE_SMART && + missile_type != ShipType::MISSILE_NAVAL) luaL_error(l, "Ship type '%s' is not a valid missile type", lua_tostring(l, 2)); - int power = (lua_isnone(l, 3))? -1 : lua_tointeger(l, 3); + int power = (lua_isnone(l, 3)) ? -1 : lua_tointeger(l, 3); - Missile * missile = s->SpawnMissile(missile_type, power); + Missile *missile = s->SpawnMissile(missile_type, power); if (missile) LuaObject::PushToLua(missile); else @@ -642,17 +642,15 @@ static int l_ship_use_ecm(lua_State *l) float recharge; - if(result == Ship::ECMResult::ECM_ACTIVATED) { + if (result == Ship::ECMResult::ECM_ACTIVATED) { recharge = s->GetECMRechargeRemain(); lua_pushboolean(l, true); lua_pushnumber(l, recharge); - } - else if(result == Ship::ECMResult::ECM_RECHARGING) { + } else if (result == Ship::ECMResult::ECM_RECHARGING) { recharge = s->GetECMRechargeRemain(); lua_pushboolean(l, false); lua_pushnumber(l, recharge); - } - else if(result == Ship::ECMResult::ECM_NOT_INSTALLED) { + } else if (result == Ship::ECMResult::ECM_NOT_INSTALLED) { lua_pushboolean(l, false); lua_pushnil(l); } @@ -808,7 +806,6 @@ static int l_ship_set_invulnerable(lua_State *l) return 0; } - /* Method: GetWheelState * * Return the current state of the landing gear. @@ -819,14 +816,13 @@ static int l_ship_set_invulnerable(lua_State *l) * and a value in between if it is moving. * */ -static int l_ship_get_wheel_state(lua_State *l) { +static int l_ship_get_wheel_state(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); lua_pushnumber(l, s->GetWheelState()); return 1; } - - /* Method: GetFlightState * * Return the current flight state of a ship as a string. @@ -843,13 +839,13 @@ static int l_ship_get_wheel_state(lua_State *l) { * - HYPERSPACE * */ -static int l_ship_get_flight_state(lua_State *l) { +static int l_ship_get_flight_state(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); LuaPush(l, EnumStrings::GetString("ShipFlightState", s->GetFlightState())); return 1; } - /* Method: GetFlightControlState * * Return the current flight control state. @@ -871,13 +867,13 @@ static int l_ship_get_flight_state(lua_State *l) { * - CONTROL_AUTOPILOT * */ -static int l_ship_get_flight_control_state(lua_State *l) { +static int l_ship_get_flight_control_state(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); LuaPush(l, EnumStrings::GetString("ShipControllerFlightControlState", s->GetController()->GetFlightControlState())); return 1; } - /* Method: GetSetSpeed * * Return the current SetSpeed speed in m/s. @@ -889,16 +885,16 @@ static int l_ship_get_flight_control_state(lua_State *l) { * the current SetSpeed speed in m/s or nil if not in fix speed mode. * */ -static int l_ship_get_set_speed(lua_State *l) { +static int l_ship_get_set_speed(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); - if(s->GetController()->GetFlightControlState() == CONTROL_FIXSPEED) + if (s->GetController()->GetFlightControlState() == CONTROL_FIXSPEED) LuaPush(l, s->GetController()->GetSetSpeed()); else lua_pushnil(l); return 1; } - /* Method: GetSetSpeedTarget * * Return the current SetSpeed target of the ship. @@ -908,22 +904,22 @@ static int l_ship_get_set_speed(lua_State *l) { * The of the current SetSpeed target or nil. * */ -static int l_ship_get_set_speed_target(lua_State *l) { +static int l_ship_get_set_speed_target(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); Body *t = s->GetController()->GetSetSpeedTarget(); - if(s->GetType() == Object::Type::PLAYER && t == nullptr) { + if (s->GetType() == Object::Type::PLAYER && t == nullptr) { Frame *f = s->GetFrame(); - if(f) + if (f) t = f->GetBody(); } - if(t) + if (t) LuaObject::PushToLua(t); else lua_pushnil(l); return 1; } - /* Method: ToggleWheelState * * If the landing gear of the ship is up, start lowering it, and vice versa. @@ -931,7 +927,8 @@ static int l_ship_get_set_speed_target(lua_State *l) { * > ship:ToggleWheelState() * */ -static int l_ship_toggle_wheel_state(lua_State *l) { +static int l_ship_toggle_wheel_state(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); s->SetWheelState(is_equal_exact(s->GetWheelState(), 0.0f)); return 0; @@ -963,7 +960,6 @@ static int l_ship_get_velocity(lua_State *l) return 1; } - /* Method: GetStats * * Return some ship stats. @@ -983,7 +979,8 @@ static int l_ship_get_velocity(lua_State *l) * - fuelTankMassLeft * */ -static int l_ship_get_stats(lua_State *l) { +static int l_ship_get_stats(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); LuaTable t(l); const shipstats_t &stats = s->GetStats(); @@ -1026,7 +1023,6 @@ static int l_ship_get_position(lua_State *l) return 1; } - /* Method: GetHullTemperature * * Return the current hull temperature (0.0 - 1.0). @@ -1036,13 +1032,13 @@ static int l_ship_get_position(lua_State *l) * the hull temperature (0.0 - 1.0) * */ -static int l_ship_get_hull_temperature(lua_State *l) { +static int l_ship_get_hull_temperature(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); LuaPush(l, s->GetHullTemperature()); return 1; } - /* Method: GetGunTemperature * * Get a gun's temperature (0.0 - 1.0). @@ -1056,14 +1052,14 @@ static int l_ship_get_hull_temperature(lua_State *l) { * the gun's current temperature (0.0 - 1.0) * */ -static int l_ship_get_gun_temperature(lua_State *l) { +static int l_ship_get_gun_temperature(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); int gun = luaL_checkinteger(l, 2); LuaPush(l, s->GetGunTemperature(gun)); return 1; } - /* Method: GetHullPercent * * Return the current percentage of hull left (0.0 - 1.0). @@ -1073,13 +1069,13 @@ static int l_ship_get_gun_temperature(lua_State *l) { * the current hull (0.0 - 1.0) * */ -static int l_ship_get_hull_percent(lua_State *l) { +static int l_ship_get_hull_percent(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); LuaPush(l, s->GetPercentHull()); return 1; } - /* Method: GetShieldPercent * * Return the current percentage of shield left (0.0 - 1.0) or nil if no shield. @@ -1089,17 +1085,17 @@ static int l_ship_get_hull_percent(lua_State *l) { * the current shield (0.0 - 1.0) or nil * */ -static int l_ship_get_shields_percent(lua_State *l) { +static int l_ship_get_shields_percent(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); double shields = s->GetPercentShields(); - if(s->GetStats().shield_mass <= 0) + if (s->GetStats().shield_mass <= 0) lua_pushnil(l); else lua_pushnumber(l, shields); return 1; } - /* Method: IsDocked * * Return true if the ship is docked. @@ -1109,7 +1105,8 @@ static int l_ship_get_shields_percent(lua_State *l) { * true if the ship is docked * */ -static int l_ship_is_docked(lua_State *l) { +static int l_ship_is_docked(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); lua_pushboolean(l, s->IsDocked()); return 1; @@ -1124,13 +1121,13 @@ static int l_ship_is_docked(lua_State *l) { * true if the ship is landed * */ -static int l_ship_is_landed(lua_State *l) { +static int l_ship_is_landed(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); lua_pushboolean(l, s->IsLanded()); return 1; } - /* Method: GetHyperspaceCountdown * * Return the current hyperspace countdown in seconds. @@ -1147,7 +1144,6 @@ static int l_ship_get_hyperspace_countdown(lua_State *l) return 1; } - /* Method: GetHyperspaceDestination * * Return the current hyperspace destination. @@ -1168,7 +1164,6 @@ static int l_ship_get_hyperspace_destination(lua_State *l) return 2; } - /* Method: IsHyperspaceActive * * Return true if a hyperspace countdown is currently running. @@ -1185,7 +1180,6 @@ static int l_ship_is_hyperspace_active(lua_State *l) return 1; } - /* Method: GetThrusterState * * Return the state of the directional thrusters. @@ -1451,10 +1445,11 @@ static int l_ship_ai_enter_high_orbit(lua_State *l) return 0; } -static int l_ship_get_current_ai_command(lua_State *l) { +static int l_ship_get_current_ai_command(lua_State *l) +{ Ship *s = LuaObject::CheckFromLua(1); const AICommand *cmd = s->GetAICommand(); - if(cmd != nullptr) { + if (cmd != nullptr) { LuaPush(l, EnumStrings::GetString("ShipAICmdName", cmd->GetType())); return 1; } else { @@ -1516,9 +1511,11 @@ static int l_ship_update_equip_stats(lua_State *l) return 0; } -template <> const char *LuaObject::s_type = "Ship"; +template <> +const char *LuaObject::s_type = "Ship"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "ModelBody"; @@ -1531,11 +1528,11 @@ template <> void LuaObject::RegisterClass() { "SetHullPercent", l_ship_set_hull_percent }, { "SetFuelPercent", l_ship_set_fuel_percent }, - { "GetSkin", l_ship_get_skin }, - { "SetSkin", l_ship_set_skin }, + { "GetSkin", l_ship_get_skin }, + { "SetSkin", l_ship_set_skin }, { "SetPattern", l_ship_set_pattern }, - { "SetLabel", l_ship_set_label }, - { "SetShipName", l_ship_set_ship_name }, + { "SetLabel", l_ship_set_label }, + { "SetShipName", l_ship_set_ship_name }, { "GetHyperspaceDestination", l_ship_get_hyperspace_destination }, @@ -1543,27 +1540,27 @@ template <> void LuaObject::RegisterClass() { "SpawnMissile", l_ship_spawn_missile }, - { "UseECM", l_ship_use_ecm }, + { "UseECM", l_ship_use_ecm }, { "IsECMReady", l_ship_is_ecm_ready }, { "GetDockedWith", l_ship_get_docked_with }, { "RequestDockingClearance", l_ship_request_docking_clearance }, - { "Undock", l_ship_undock }, - { "BlastOff", l_ship_blast_off }, + { "Undock", l_ship_undock }, + { "BlastOff", l_ship_blast_off }, { "Explode", l_ship_explode }, - { "AIKill", l_ship_ai_kill }, - { "AIKamikaze", l_ship_ai_kamikaze }, - { "AIFlyTo", l_ship_ai_fly_to }, - { "AIDockWith", l_ship_ai_dock_with }, - { "AIEnterLowOrbit", l_ship_ai_enter_low_orbit }, + { "AIKill", l_ship_ai_kill }, + { "AIKamikaze", l_ship_ai_kamikaze }, + { "AIFlyTo", l_ship_ai_fly_to }, + { "AIDockWith", l_ship_ai_dock_with }, + { "AIEnterLowOrbit", l_ship_ai_enter_low_orbit }, { "AIEnterMediumOrbit", l_ship_ai_enter_medium_orbit }, - { "AIEnterHighOrbit", l_ship_ai_enter_high_orbit }, - { "CancelAI", l_ship_cancel_ai }, + { "AIEnterHighOrbit", l_ship_ai_enter_high_orbit }, + { "CancelAI", l_ship_cancel_ai }, - { "InitiateHyperjumpTo", l_ship_initiate_hyperjump_to }, - { "AbortHyperjump", l_ship_abort_hyperjump }, + { "InitiateHyperjumpTo", l_ship_initiate_hyperjump_to }, + { "AbortHyperjump", l_ship_abort_hyperjump }, { "GetInvulnerable", l_ship_get_invulnerable }, { "SetInvulnerable", l_ship_set_invulnerable }, @@ -1571,29 +1568,29 @@ template <> void LuaObject::RegisterClass() { "UpdateEquipStats", l_ship_update_equip_stats }, { "GetVelocity", l_ship_get_velocity }, - { "GetPosition", l_ship_get_position }, - { "GetThrusterState", l_ship_get_thruster_state }, + { "GetPosition", l_ship_get_position }, + { "GetThrusterState", l_ship_get_thruster_state }, - { "IsDocked", l_ship_is_docked }, - { "IsLanded", l_ship_is_landed }, + { "IsDocked", l_ship_is_docked }, + { "IsLanded", l_ship_is_landed }, - { "GetWheelState", l_ship_get_wheel_state }, - { "ToggleWheelState", l_ship_toggle_wheel_state }, - { "GetFlightState", l_ship_get_flight_state }, - { "GetSetSpeed", l_ship_get_set_speed }, + { "GetWheelState", l_ship_get_wheel_state }, + { "ToggleWheelState", l_ship_toggle_wheel_state }, + { "GetFlightState", l_ship_get_flight_state }, + { "GetSetSpeed", l_ship_get_set_speed }, { "GetSetSpeedTarget", l_ship_get_set_speed_target }, - { "GetStats", l_ship_get_stats }, + { "GetStats", l_ship_get_stats }, { "GetHyperspaceCountdown", l_ship_get_hyperspace_countdown }, - { "IsHyperspaceActive", l_ship_is_hyperspace_active }, + { "IsHyperspaceActive", l_ship_is_hyperspace_active }, { "GetHullTemperature", l_ship_get_hull_temperature }, - { "GetGunTemperature", l_ship_get_gun_temperature }, - { "GetHullPercent", l_ship_get_hull_percent }, - { "GetShieldsPercent", l_ship_get_shields_percent }, + { "GetGunTemperature", l_ship_get_gun_temperature }, + { "GetHullPercent", l_ship_get_hull_percent }, + { "GetShieldsPercent", l_ship_get_shields_percent }, - { "GetFlightControlState", l_ship_get_flight_control_state }, - { "GetCurrentAICommand", l_ship_get_current_ai_command }, + { "GetFlightControlState", l_ship_get_flight_control_state }, + { "GetCurrentAICommand", l_ship_get_current_ai_command }, { 0, 0 } }; diff --git a/src/LuaShipDef.cpp b/src/LuaShipDef.cpp index 4de06b820..5acb619b9 100644 --- a/src/LuaShipDef.cpp +++ b/src/LuaShipDef.cpp @@ -1,10 +1,10 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Lua.h" #include "LuaShipDef.h" -#include "LuaUtils.h" #include "EnumStrings.h" +#include "Lua.h" +#include "LuaUtils.h" #include "ShipType.h" /* @@ -228,28 +228,27 @@ void LuaShipDef::Register() lua_newtable(l); - for (auto iter : ShipType::types) - { + for (auto iter : ShipType::types) { const ShipType &st = iter.second; lua_newtable(l); - pi_lua_settable(l, "id", iter.first.c_str()); - pi_lua_settable(l, "name", st.name.c_str()); - pi_lua_settable(l, "shipClass", st.shipClass.c_str()); - pi_lua_settable(l, "manufacturer", st.manufacturer.c_str()); - pi_lua_settable(l, "modelName", st.modelName.c_str()); - pi_lua_settable(l, "cockpitName", st.cockpitName.c_str()); - pi_lua_settable(l, "tag", EnumStrings::GetString("ShipTypeTag", st.tag)); - pi_lua_settable(l, "angularThrust", st.angThrust); - pi_lua_settable(l, "capacity", st.capacity); - pi_lua_settable(l, "hullMass", st.hullMass); - pi_lua_settable(l, "fuelTankMass", st.fuelTankMass); - pi_lua_settable(l, "basePrice", st.baseprice); - pi_lua_settable(l, "minCrew", st.minCrew); - pi_lua_settable(l, "maxCrew", st.maxCrew); - pi_lua_settable(l, "hyperdriveClass", st.hyperdriveClass); + pi_lua_settable(l, "id", iter.first.c_str()); + pi_lua_settable(l, "name", st.name.c_str()); + pi_lua_settable(l, "shipClass", st.shipClass.c_str()); + pi_lua_settable(l, "manufacturer", st.manufacturer.c_str()); + pi_lua_settable(l, "modelName", st.modelName.c_str()); + pi_lua_settable(l, "cockpitName", st.cockpitName.c_str()); + pi_lua_settable(l, "tag", EnumStrings::GetString("ShipTypeTag", st.tag)); + pi_lua_settable(l, "angularThrust", st.angThrust); + pi_lua_settable(l, "capacity", st.capacity); + pi_lua_settable(l, "hullMass", st.hullMass); + pi_lua_settable(l, "fuelTankMass", st.fuelTankMass); + pi_lua_settable(l, "basePrice", st.baseprice); + pi_lua_settable(l, "minCrew", st.minCrew); + pi_lua_settable(l, "maxCrew", st.maxCrew); + pi_lua_settable(l, "hyperdriveClass", st.hyperdriveClass); pi_lua_settable(l, "effectiveExhaustVelocity", st.effectiveExhaustVelocity); - pi_lua_settable(l, "thrusterFuelUse", st.GetFuelUseRate()); + pi_lua_settable(l, "thrusterFuelUse", st.GetFuelUseRate()); lua_newtable(l); for (int t = Thruster::THRUSTER_REVERSE; t < Thruster::THRUSTER_MAX; t++) diff --git a/src/LuaSpace.cpp b/src/LuaSpace.cpp index 492f49475..1f380fde9 100644 --- a/src/LuaSpace.cpp +++ b/src/LuaSpace.cpp @@ -1,20 +1,20 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "LuaObject.h" #include "LuaSpace.h" +#include "Frame.h" +#include "Game.h" +#include "HyperspaceCloud.h" #include "LuaManager.h" +#include "LuaObject.h" #include "LuaUtils.h" #include "LuaVector.h" -#include "Space.h" -#include "Ship.h" -#include "HyperspaceCloud.h" -#include "Pi.h" -#include "SpaceStation.h" -#include "Player.h" -#include "Game.h" #include "MathUtil.h" -#include "Frame.h" +#include "Pi.h" +#include "Player.h" +#include "Ship.h" +#include "Space.h" +#include "SpaceStation.h" /* * Interface: Space @@ -22,7 +22,7 @@ * Various functions to create and find objects in the current physics space. */ -static void _unpack_hyperspace_args(lua_State *l, int index, SystemPath* &path, double &due) +static void _unpack_hyperspace_args(lua_State *l, int index, SystemPath *&path, double &due) { if (lua_isnone(l, index)) return; @@ -115,7 +115,7 @@ static int l_space_spawn_ship(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); float min_dist = luaL_checknumber(l, 2); @@ -133,12 +133,12 @@ static int l_space_spawn_ship(lua_State *l) // XXX protect against spawning inside the body thing->SetFrame(Pi::game->GetSpace()->GetRootFrame()); if (!path) - thing->SetPosition(MathUtil::RandomPointOnSphere(min_dist, max_dist)*AU); + thing->SetPosition(MathUtil::RandomPointOnSphere(min_dist, max_dist) * AU); else // XXX broken. this is ignoring min_dist & max_dist. otoh, what's the // correct behaviour given there's now a fixed hyperspace exit point? thing->SetPosition(Pi::game->GetSpace()->GetHyperspaceExitPoint(*path)); - thing->SetVelocity(vector3d(0,0,0)); + thing->SetVelocity(vector3d(0, 0, 0)); Pi::game->GetSpace()->AddBody(thing); LuaObject::PushToLua(ship); @@ -203,7 +203,7 @@ static int l_space_spawn_ship_near(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Body *nearbody = LuaObject::CheckFromLua(2); @@ -224,8 +224,8 @@ static int l_space_spawn_ship_near(lua_State *l) Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body - Frame * newframe = nearbody->GetFrame(); - const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist)* 1000.0) + nearbody->GetPosition(); + Frame *newframe = nearbody->GetFrame(); + const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist) * 1000.0) + nearbody->GetPosition(); // If the frame is rotating and the chosen position is too far, use non-rotating parent. // Otherwise the ship will be given a massive initial velocity when it's bumped out of the @@ -235,7 +235,8 @@ static int l_space_spawn_ship_near(lua_State *l) newframe = newframe->GetParent(); } - thing->SetFrame(newframe);; + thing->SetFrame(newframe); + ; thing->SetPosition(newPosition); thing->SetVelocity(newVelocity); Pi::game->GetSpace()->AddBody(thing); @@ -281,7 +282,7 @@ static int l_space_spawn_ship_docked(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); SpaceStation *station = LuaObject::CheckFromLua(2); @@ -289,8 +290,8 @@ static int l_space_spawn_ship_docked(lua_State *l) Ship *ship = new Ship(type); assert(ship); - int port = station->GetFreeDockingPort(ship); // pass in the ship to get a port we fit into - if(port < 0) { + int port = station->GetFreeDockingPort(ship); // pass in the ship to get a port we fit into + if (port < 0) { delete ship; return 0; } @@ -344,7 +345,7 @@ static int l_space_spawn_ship_parked(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); SpaceStation *station = LuaObject::CheckFromLua(2); @@ -356,15 +357,15 @@ static int l_space_spawn_ship_parked(lua_State *l) Ship *ship = new Ship(type); assert(ship); - const double parkDist = station->GetStationType()->ParkingDistance() - ship->GetPhysRadius(); // park inside parking radius - const double parkOffset = (0.5 * station->GetStationType()->ParkingGapSize()) + ship->GetPhysRadius(); // but outside the docking gap + const double parkDist = station->GetStationType()->ParkingDistance() - ship->GetPhysRadius(); // park inside parking radius + const double parkOffset = (0.5 * station->GetStationType()->ParkingGapSize()) + ship->GetPhysRadius(); // but outside the docking gap double xpos = (slot == 0 || slot == 3) ? -parkOffset : parkOffset; double zpos = (slot == 0 || slot == 1) ? -parkOffset : parkOffset; const vector3d parkPos = station->GetPosition() + station->GetOrient() * vector3d(xpos, parkDist, zpos); // orbital stations have Y as axis of rotation - const matrix3x3d rot = matrix3x3d::RotateX(M_PI/2) * station->GetOrient(); + const matrix3x3d rot = matrix3x3d::RotateX(M_PI / 2) * station->GetOrient(); ship->SetFrame(station->GetFrame()); ship->SetVelocity(vector3d(0.0)); @@ -425,7 +426,7 @@ static int l_space_spawn_ship_landed(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Planet *planet = LuaObject::CheckFromLua(2); @@ -490,7 +491,7 @@ static int l_space_spawn_ship_landed_near(lua_State *l) LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); - if (! ShipType::Get(type)) + if (!ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Body *nearbody = LuaObject::CheckFromLua(2); @@ -503,7 +504,7 @@ static int l_space_spawn_ship_landed_near(lua_State *l) assert(ship); // XXX protect against spawning inside the body - Frame * newframe = nearbody->GetFrame()->GetRotFrame(); + Frame *newframe = nearbody->GetFrame()->GetRotFrame(); if (!newframe->IsRotFrame()) luaL_error(l, "Body must be in rotating frame"); SystemBody *sbody = newframe->GetSystemBody(); @@ -521,19 +522,19 @@ static int l_space_spawn_ship_landed_near(lua_State *l) // The second vector is just the cross product of the up-vector and out first vector. if (up.x <= up.y && up.x <= up.z) { x = vector3d(0.0, up.z, -up.y).Normalized(); - y = vector3d(-up.y*up.y - up.z*up.z, up.x*up.y, up.x*up.z).Normalized(); + y = vector3d(-up.y * up.y - up.z * up.z, up.x * up.y, up.x * up.z).Normalized(); } else if (up.y <= up.x && up.y <= up.z) { x = vector3d(-up.z, 0.0, up.x).Normalized(); - y = vector3d(up.x*up.y, -up.x*up.x - up.z*up.z, up.y*up.z).Normalized(); + y = vector3d(up.x * up.y, -up.x * up.x - up.z * up.z, up.y * up.z).Normalized(); } else { x = vector3d(up.y, -up.x, 0.0).Normalized(); - y = vector3d(up.x*up.z, up.y*up.z, -up.x*up.x - up.y*up.y).Normalized(); + y = vector3d(up.x * up.z, up.y * up.z, -up.x * up.x - up.y * up.y).Normalized(); } - Planet *planet = static_cast(newframe->GetBody()); + Planet *planet = static_cast(newframe->GetBody()); const double radius = planet->GetSystemBody()->GetRadius(); const vector3d planar = MathUtil::RandomPointInCircle(min_dist * 1000.0, max_dist * 1000.0); vector3d pos = (radius * up + x * planar.x + y * planar.y).Normalized(); - float latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z)); + float latitude = atan2(pos.y, sqrt(pos.x * pos.x + pos.z * pos.z)); float longitude = atan2(pos.x, pos.z); Pi::game->GetSpace()->AddBody(ship); @@ -642,12 +643,12 @@ static int l_space_get_bodies(lua_State *l) lua_newtable(l); - for (Body* b : Pi::game->GetSpace()->GetBodies()) { + for (Body *b : Pi::game->GetSpace()->GetBodies()) { if (filter) { lua_pushvalue(l, 1); LuaObject::PushToLua(b); if (int ret = lua_pcall(l, 1, 1, 0)) { - const char *errmsg( "Unknown error" ); + const char *errmsg("Unknown error"); if (ret == LUA_ERRRUN) errmsg = lua_tostring(l, -1); else if (ret == LUA_ERRMEM) @@ -663,10 +664,10 @@ static int l_space_get_bodies(lua_State *l) lua_pop(l, 1); } - lua_pushinteger(l, lua_rawlen(l, -1)+1); + lua_pushinteger(l, lua_rawlen(l, -1) + 1); LuaObject::PushToLua(b); lua_rawset(l, -3); - } + } LUA_DEBUG_END(l, 1); @@ -696,14 +697,14 @@ void LuaSpace::Register() LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "SpawnShip", l_space_spawn_ship }, - { "SpawnShipNear", l_space_spawn_ship_near }, + { "SpawnShip", l_space_spawn_ship }, + { "SpawnShipNear", l_space_spawn_ship_near }, { "SpawnShipDocked", l_space_spawn_ship_docked }, { "SpawnShipParked", l_space_spawn_ship_parked }, { "SpawnShipLanded", l_space_spawn_ship_landed }, { "SpawnShipLandedNear", l_space_spawn_ship_landed_near }, - { "GetBody", l_space_get_body }, + { "GetBody", l_space_get_body }, { "GetBodies", l_space_get_bodies }, { 0, 0 } }; diff --git a/src/LuaSpaceStation.cpp b/src/LuaSpaceStation.cpp index 9329af5ec..a9ade4789 100644 --- a/src/LuaSpaceStation.cpp +++ b/src/LuaSpaceStation.cpp @@ -1,10 +1,10 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "LuaConstants.h" #include "LuaObject.h" #include "LuaUtils.h" #include "SpaceStation.h" -#include "LuaConstants.h" /* * Class: SpaceStation @@ -47,7 +47,7 @@ static int l_spacestation_get_ground_position(lua_State *l) return 0; vector3d pos = s->GetPosition(); - double latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z)); + double latitude = atan2(pos.y, sqrt(pos.x * pos.x + pos.z * pos.z)); double longitude = atan2(pos.x, pos.z); lua_pushnumber(l, latitude); lua_pushnumber(l, longitude); @@ -114,22 +114,24 @@ static int l_spacestation_attr_is_ground_station(lua_State *l) return 1; } -template <> const char *LuaObject::s_type = "SpaceStation"; +template <> +const char *LuaObject::s_type = "SpaceStation"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { const char *l_parent = "ModelBody"; static const luaL_Reg l_methods[] = { - { "GetGroundPosition", l_spacestation_get_ground_position }, + { "GetGroundPosition", l_spacestation_get_ground_position }, { 0, 0 } }; static luaL_Reg l_attrs[] = { - { "numDocks", l_spacestation_attr_num_docks }, + { "numDocks", l_spacestation_attr_num_docks }, { "isGroundStation", l_spacestation_attr_is_ground_station }, - { "numShipsDocked", l_spacestation_attr_num_ships_docked }, + { "numShipsDocked", l_spacestation_attr_num_ships_docked }, { 0, 0 } }; diff --git a/src/LuaStar.cpp b/src/LuaStar.cpp index 12d404eb0..9a73b46e1 100644 --- a/src/LuaStar.cpp +++ b/src/LuaStar.cpp @@ -10,9 +10,12 @@ * Class representing a star. Inherits from . */ -template <> const char *LuaObject::s_type = "Star"; +template <> +const char *LuaObject::s_type = "Star"; -template <> void LuaObject::RegisterClass() { +template <> +void LuaObject::RegisterClass() +{ const char *l_parent = "Body"; LuaObjectBase::CreateClass(s_type, l_parent, 0, 0, 0); diff --git a/src/LuaStarSystem.cpp b/src/LuaStarSystem.cpp index 01756a890..b62b62b0a 100644 --- a/src/LuaStarSystem.cpp +++ b/src/LuaStarSystem.cpp @@ -1,26 +1,25 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "LuaObject.h" -#include "LuaConstants.h" -#include "LuaTable.h" -#include "LuaUtils.h" #include "EnumStrings.h" -#include "LuaUtils.h" -#include "galaxy/StarSystem.h" -#include "galaxy/Economy.h" -#include "Pi.h" -#include "Game.h" -#include "Space.h" -#include "Star.h" -#include "Planet.h" -#include "SpaceStation.h" -#include "galaxy/Galaxy.h" -#include "galaxy/Sector.h" -#include "galaxy/GalaxyCache.h" #include "Factions.h" #include "FileSystem.h" +#include "Game.h" #include "GameSaveError.h" +#include "LuaConstants.h" +#include "LuaObject.h" +#include "LuaTable.h" +#include "LuaUtils.h" +#include "Pi.h" +#include "Planet.h" +#include "Space.h" +#include "SpaceStation.h" +#include "Star.h" +#include "galaxy/Economy.h" +#include "galaxy/Galaxy.h" +#include "galaxy/GalaxyCache.h" +#include "galaxy/Sector.h" +#include "galaxy/StarSystem.h" /* * Class: StarSystem @@ -66,9 +65,8 @@ static int l_starsystem_get_station_paths(lua_State *l) lua_newtable(l); - for (const SystemBody *station : s->GetSpaceStations()) - { - lua_pushinteger(l, lua_rawlen(l, -1)+1); + for (const SystemBody *station : s->GetSpaceStations()) { + lua_pushinteger(l, lua_rawlen(l, -1) + 1); LuaObject::PushToLua(&station->GetPath()); lua_rawset(l, -3); } @@ -106,9 +104,8 @@ static int l_starsystem_get_body_paths(lua_State *l) lua_newtable(l); - for (RefCountedPtr sb : s->GetBodies()) - { - lua_pushinteger(l, lua_rawlen(l, -1)+1); + for (RefCountedPtr sb : s->GetBodies()) { + lua_pushinteger(l, lua_rawlen(l, -1) + 1); LuaObject::PushToLua(&sb->GetPath()); lua_rawset(l, -3); } @@ -267,11 +264,11 @@ static int l_starsystem_get_nearby_systems(lua_State *l) const Uint32 here_idx = here.systemIndex; RefCountedPtr here_sec = s->m_galaxy->GetSector(here); - const int diff_sec = int(ceil(dist_ly/Sector::SIZE)); + const int diff_sec = int(ceil(dist_ly / Sector::SIZE)); - for (int x = here_x-diff_sec; x <= here_x+diff_sec; x++) { - for (int y = here_y-diff_sec; y <= here_y+diff_sec; y++) { - for (int z = here_z-diff_sec; z <= here_z+diff_sec; z++) { + for (int x = here_x - diff_sec; x <= here_x + diff_sec; x++) { + for (int y = here_y - diff_sec; y <= here_y + diff_sec; y++) { + for (int z = here_z - diff_sec; z <= here_z + diff_sec; z++) { RefCountedPtr sec = s->m_galaxy->GetSector(SystemPath(x, y, z)); for (unsigned int idx = 0; idx < sec->m_systems.size(); idx++) { @@ -293,7 +290,7 @@ static int l_starsystem_get_nearby_systems(lua_State *l) lua_pop(l, 1); } - lua_pushinteger(l, lua_rawlen(l, -1)+1); + lua_pushinteger(l, lua_rawlen(l, -1) + 1); LuaObject::PushToLua(sys.Get()); lua_rawset(l, -3); } @@ -311,7 +308,7 @@ static int l_starsystem_get_stars(lua_State *l) const StarSystem *s = LuaObject::CheckFromLua(1); lua_newtable(l); int i = 1; - for(SystemBody *star : s->GetStars()) { + for (SystemBody *star : s->GetStars()) { lua_pushnumber(l, i++); LuaObject::PushToLua(star); lua_settable(l, -3); @@ -360,13 +357,10 @@ static int l_starsystem_distance_to(lua_State *l) RefCountedPtr sec2 = s->m_galaxy->GetSector(*loc2); // this only works if the SystemPath is valid - if (loc1->HasValidSystem() && loc2->HasValidSystem()) - { + if (loc1->HasValidSystem() && loc2->HasValidSystem()) { double dist = Sector::DistanceBetween(sec1, loc1->systemIndex, sec2, loc2->systemIndex); lua_pushnumber(l, dist); - } - else - { + } else { lua_pushnumber(l, FLT_MAX); return luaL_error(l, "Cannot compare non-systemPaths"); } @@ -404,7 +398,7 @@ static int l_starsystem_export_to_lua(lua_State *l) try { const std::string filename(EXPORTED_SYSTEMS_DIR_NAME + "/" + FileSystem::SanitiseFileName(s->GetName()) + ".lua"); const std::string finalPath = FileSystem::NormalisePath( - FileSystem::JoinPathBelow(FileSystem::GetUserDir(), filename)); + FileSystem::JoinPathBelow(FileSystem::GetUserDir(), filename)); s->ExportToLua(finalPath.c_str()); } catch (std::invalid_argument &) { return luaL_error(l, "could not export system -- name forms an invalid path"); @@ -447,7 +441,7 @@ static int l_starsystem_explore(lua_State *l) s->ExploreSystem(time); - LUA_DEBUG_END(l,0); + LUA_DEBUG_END(l, 0); return 0; } @@ -479,7 +473,7 @@ static int l_starsystem_attr_other_names(lua_State *l) StarSystem *s = LuaObject::CheckFromLua(1); LuaTable names(l); int i = 1; - for(std::string n : s->GetOtherNames()) { + for (std::string n : s->GetOtherNames()) { LuaPush(l, i++); LuaPush(l, n); lua_settable(l, -3); @@ -570,7 +564,7 @@ static int l_starsystem_attr_faction(lua_State *l) PROFILE_SCOPED() StarSystem *s = LuaObject::CheckFromLua(1); if (s->GetFaction()->IsValid()) { - LuaObject::PushToLua(const_cast(s->GetFaction())); // XXX const-correctness violation + LuaObject::PushToLua(const_cast(s->GetFaction())); // XXX const-correctness violation return 1; } else { return 0; @@ -594,9 +588,9 @@ static int l_starsystem_attr_root_system_body(lua_State *l) static int l_starsystem_attr_short_description(lua_State *l) { - StarSystem *s = LuaObject::CheckFromLua(1); - LuaPush(l, s->GetShortDescription()); - return 1; + StarSystem *s = LuaObject::CheckFromLua(1); + LuaPush(l, s->GetShortDescription()); + return 1; } /* @@ -643,9 +637,11 @@ static int l_starsystem_attr_explored(lua_State *l) return 1; } -template <> const char *LuaObject::s_type = "StarSystem"; +template <> +const char *LuaObject::s_type = "StarSystem"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { { "GetStationPaths", l_starsystem_get_station_paths }, @@ -653,7 +649,7 @@ template <> void LuaObject::RegisterClass() { "GetStars", l_starsystem_get_stars }, { "GetCommodityBasePriceAlterations", l_starsystem_get_commodity_base_price_alterations }, - { "IsCommodityLegal", l_starsystem_is_commodity_legal }, + { "IsCommodityLegal", l_starsystem_is_commodity_legal }, { "GetNearbySystems", l_starsystem_get_nearby_systems }, @@ -672,12 +668,12 @@ template <> void LuaObject::RegisterClass() { "path", l_starsystem_attr_path }, { "lawlessness", l_starsystem_attr_lawlessness }, - { "population", l_starsystem_attr_population }, - { "faction", l_starsystem_attr_faction }, - { "govtype", l_starsystem_attr_govtype }, - { "explored", l_starsystem_attr_explored }, - { "numberOfStars", l_starsystem_attr_number_of_stars }, - { "rootSystemBody", l_starsystem_attr_root_system_body }, + { "population", l_starsystem_attr_population }, + { "faction", l_starsystem_attr_faction }, + { "govtype", l_starsystem_attr_govtype }, + { "explored", l_starsystem_attr_explored }, + { "numberOfStars", l_starsystem_attr_number_of_stars }, + { "rootSystemBody", l_starsystem_attr_root_system_body }, { "shortDescription", l_starsystem_attr_short_description }, { 0, 0 } }; diff --git a/src/LuaSystemBody.cpp b/src/LuaSystemBody.cpp index d32e6d38e..1b657e2fe 100644 --- a/src/LuaSystemBody.cpp +++ b/src/LuaSystemBody.cpp @@ -1,13 +1,13 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "EnumStrings.h" +#include "Game.h" #include "LuaObject.h" #include "LuaUtils.h" -#include "EnumStrings.h" #include "Pi.h" #include "galaxy/Galaxy.h" #include "galaxy/StarSystem.h" -#include "Game.h" /* * Class: SystemBody @@ -252,7 +252,7 @@ static int l_sbody_attr_gravity(lua_State *l) static int l_sbody_attr_periapsis(lua_State *l) { SystemBody *sbody = LuaObject::CheckFromLua(1); - lua_pushnumber(l, sbody->GetOrbMin()*AU); + lua_pushnumber(l, sbody->GetOrbMin() * AU); return 1; } @@ -272,11 +272,10 @@ static int l_sbody_attr_periapsis(lua_State *l) static int l_sbody_attr_apoapsis(lua_State *l) { SystemBody *sbody = LuaObject::CheckFromLua(1); - lua_pushnumber(l, sbody->GetOrbMax()*AU); + lua_pushnumber(l, sbody->GetOrbMax() * AU); return 1; } - /* * Attribute: orbitPeriod * @@ -293,11 +292,10 @@ static int l_sbody_attr_apoapsis(lua_State *l) static int l_sbody_attr_orbital_period(lua_State *l) { SystemBody *sbody = LuaObject::CheckFromLua(1); - lua_pushnumber(l, sbody->GetOrbit().Period() / float(60*60*24)); + lua_pushnumber(l, sbody->GetOrbit().Period() / float(60 * 60 * 24)); return 1; } - /* * Attribute: rotationPeriod * @@ -334,7 +332,7 @@ static int l_sbody_attr_rotation_period(lua_State *l) static int l_sbody_attr_semi_major_axis(lua_State *l) { SystemBody *sbody = LuaObject::CheckFromLua(1); - lua_pushnumber(l, sbody->GetSemiMajorAxis()*AU); + lua_pushnumber(l, sbody->GetSemiMajorAxis() * AU); return 1; } @@ -561,7 +559,7 @@ static int l_sbody_attr_life(lua_State *l) static int l_sbody_attr_has_rings(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); + SystemBody *sbody = LuaObject::CheckFromLua(1); lua_pushboolean(l, sbody->HasRings()); return 1; } @@ -582,7 +580,7 @@ static int l_sbody_attr_has_rings(lua_State *l) static int l_sbody_attr_has_atmosphere(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); + SystemBody *sbody = LuaObject::CheckFromLua(1); lua_pushboolean(l, sbody->HasAtmosphere()); return 1; } @@ -603,95 +601,97 @@ static int l_sbody_attr_has_atmosphere(lua_State *l) static int l_sbody_attr_is_scoopable(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); + SystemBody *sbody = LuaObject::CheckFromLua(1); lua_pushboolean(l, sbody->IsScoopable()); return 1; } static int l_sbody_attr_path(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); + SystemBody *sbody = LuaObject::CheckFromLua(1); LuaObject::PushToLua(sbody->GetPath()); return 1; } static int l_sbody_attr_astro_description(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); + SystemBody *sbody = LuaObject::CheckFromLua(1); LuaPush(l, sbody->GetAstroDescription()); return 1; } static int l_sbody_attr_body(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); - if(Pi::game) { - Space *space = Pi::game->GetSpace(); - if(space) { - const SystemPath &path = sbody->GetPath(); - Body *body = space->FindBodyForPath(&path); - if(body) { - LuaObject::PushToLua(body); - } else { + SystemBody *sbody = LuaObject::CheckFromLua(1); + if (Pi::game) { + Space *space = Pi::game->GetSpace(); + if (space) { + const SystemPath &path = sbody->GetPath(); + Body *body = space->FindBodyForPath(&path); + if (body) { + LuaObject::PushToLua(body); + } else { + lua_pushnil(l); + } + } + } else { lua_pushnil(l); - } } - } else { - lua_pushnil(l); - } - return 1; + return 1; } static int l_sbody_attr_children(lua_State *l) { - SystemBody * sbody = LuaObject::CheckFromLua(1); - LuaTable children(l); - int i = 1; - for (auto child : sbody->GetChildren()) { - LuaPush(l, i++); - LuaObject::PushToLua(child); - lua_settable(l, -3); - } - return 1; + SystemBody *sbody = LuaObject::CheckFromLua(1); + LuaTable children(l); + int i = 1; + for (auto child : sbody->GetChildren()) { + LuaPush(l, i++); + LuaObject::PushToLua(child); + lua_settable(l, -3); + } + return 1; } -template <> const char *LuaObject::s_type = "SystemBody"; +template <> +const char *LuaObject::s_type = "SystemBody"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_attrs[] = { - { "index", l_sbody_attr_index }, - { "name", l_sbody_attr_name }, - { "type", l_sbody_attr_type }, - { "superType", l_sbody_attr_super_type }, - { "seed", l_sbody_attr_seed }, - { "parent", l_sbody_attr_parent }, - { "population", l_sbody_attr_population }, - { "radius", l_sbody_attr_radius }, - { "mass", l_sbody_attr_mass }, - { "gravity", l_sbody_attr_gravity }, - { "periapsis", l_sbody_attr_periapsis }, - { "apoapsis", l_sbody_attr_apoapsis }, - { "orbitPeriod", l_sbody_attr_orbital_period }, + { "index", l_sbody_attr_index }, + { "name", l_sbody_attr_name }, + { "type", l_sbody_attr_type }, + { "superType", l_sbody_attr_super_type }, + { "seed", l_sbody_attr_seed }, + { "parent", l_sbody_attr_parent }, + { "population", l_sbody_attr_population }, + { "radius", l_sbody_attr_radius }, + { "mass", l_sbody_attr_mass }, + { "gravity", l_sbody_attr_gravity }, + { "periapsis", l_sbody_attr_periapsis }, + { "apoapsis", l_sbody_attr_apoapsis }, + { "orbitPeriod", l_sbody_attr_orbital_period }, { "rotationPeriod", l_sbody_attr_rotation_period }, - { "semiMajorAxis", l_sbody_attr_semi_major_axis }, - { "eccentricity", l_sbody_attr_eccentricty }, - { "axialTilt", l_sbody_attr_axial_tilt }, - { "averageTemp", l_sbody_attr_average_temp }, - { "metallicity", l_sbody_attr_metallicity }, - { "volatileGas", l_sbody_attr_volatileGas }, - { "atmosOxidizing", l_sbody_attr_atmosOxidizing }, - { "volatileLiquid", l_sbody_attr_volatileLiquid }, - { "volatileIces", l_sbody_attr_volatileIces }, - { "volcanicity", l_sbody_attr_volcanicity }, - { "life", l_sbody_attr_life }, - { "hasRings", l_sbody_attr_has_rings }, - { "hasAtmosphere", l_sbody_attr_has_atmosphere }, - { "isScoopable", l_sbody_attr_is_scoopable }, + { "semiMajorAxis", l_sbody_attr_semi_major_axis }, + { "eccentricity", l_sbody_attr_eccentricty }, + { "axialTilt", l_sbody_attr_axial_tilt }, + { "averageTemp", l_sbody_attr_average_temp }, + { "metallicity", l_sbody_attr_metallicity }, + { "volatileGas", l_sbody_attr_volatileGas }, + { "atmosOxidizing", l_sbody_attr_atmosOxidizing }, + { "volatileLiquid", l_sbody_attr_volatileLiquid }, + { "volatileIces", l_sbody_attr_volatileIces }, + { "volcanicity", l_sbody_attr_volcanicity }, + { "life", l_sbody_attr_life }, + { "hasRings", l_sbody_attr_has_rings }, + { "hasAtmosphere", l_sbody_attr_has_atmosphere }, + { "isScoopable", l_sbody_attr_is_scoopable }, { "astroDescription", l_sbody_attr_astro_description }, - { "path", l_sbody_attr_path }, - { "body", l_sbody_attr_body }, - { "children", l_sbody_attr_children }, + { "path", l_sbody_attr_path }, + { "body", l_sbody_attr_body }, + { "children", l_sbody_attr_children }, { 0, 0 } }; diff --git a/src/LuaSystemPath.cpp b/src/LuaSystemPath.cpp index 5209bfda4..09bae2fe5 100644 --- a/src/LuaSystemPath.cpp +++ b/src/LuaSystemPath.cpp @@ -1,15 +1,15 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "Game.h" #include "LuaObject.h" #include "LuaUtils.h" #include "Pi.h" -#include "Game.h" #include "galaxy/Galaxy.h" -#include "galaxy/SystemPath.h" -#include "galaxy/StarSystem.h" -#include "galaxy/Sector.h" #include "galaxy/GalaxyCache.h" +#include "galaxy/Sector.h" +#include "galaxy/StarSystem.h" +#include "galaxy/SystemPath.h" /* * Class: SystemPath @@ -33,7 +33,9 @@ * same system without reference to their body indexes, use . */ -template <> void LuaObject::PushToLua(const SystemPath &o) { +template <> +void LuaObject::PushToLua(const SystemPath &o) +{ lua_State *l = Lua::manager->GetLuaState(); // get the system path object cache @@ -228,7 +230,9 @@ static int l_sbodypath_system_only(lua_State *l) SystemPath *path = LuaObject::CheckFromLua(1); if (!path->HasValidSystem()) return luaL_error(l, "SystemPath:SystemOnly() self argument does not refer to a system"); - if (path->IsSystemPath()) { return 1; } + if (path->IsSystemPath()) { + return 1; + } const SystemPath sysOnly(path->SystemOnly()); LuaObject::PushToLua(sysOnly); return 1; @@ -256,7 +260,9 @@ static int l_sbodypath_system_only(lua_State *l) static int l_sbodypath_sector_only(lua_State *l) { SystemPath *path = LuaObject::CheckFromLua(1); - if (path->IsSectorPath()) { return 1; } + if (path->IsSectorPath()) { + return 1; + } LuaObject::PushToLua(path->SectorOnly()); return 1; } @@ -432,14 +438,11 @@ static int l_sbodypath_is_system_path(lua_State *l) static int l_sbodypath_parse_string(lua_State *l) { std::string path = LuaPull(l, 1); - try - { + try { SystemPath syspath = SystemPath::Parse(path.c_str()); LuaObject::PushToLua(syspath.SectorOnly()); return 1; - } - catch (const SystemPath::ParseFailure&) - { + } catch (const SystemPath::ParseFailure &) { return 0; } return 0; @@ -577,7 +580,7 @@ static std::string _systempath_serializer(LuaWrappable *o) { static char buf[256]; - SystemPath *sbp = static_cast(o); + SystemPath *sbp = static_cast(o); snprintf(buf, sizeof(buf), "%d\n%d\n%d\n%u\n%u\n", sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex); @@ -588,25 +591,25 @@ static bool _systempath_deserializer(const char *pos, const char **next) { const char *end; - Sint32 sectorX = strtol(pos, const_cast(&end), 0); + Sint32 sectorX = strtol(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline - Sint32 sectorY = strtol(pos, const_cast(&end), 0); + Sint32 sectorY = strtol(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline - Sint32 sectorZ = strtol(pos, const_cast(&end), 0); + Sint32 sectorZ = strtol(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline - Uint32 systemNum = strtoul(pos, const_cast(&end), 0); + Uint32 systemNum = strtoul(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline - Uint32 sbodyId = strtoul(pos, const_cast(&end), 0); + Uint32 sbodyId = strtoul(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline const SystemPath sbp(sectorX, sectorY, sectorZ, systemNum, sbodyId); LuaObject::PushToLua(sbp); @@ -618,7 +621,7 @@ static bool _systempath_deserializer(const char *pos, const char **next) static void _systempath_to_json(Json &out, LuaWrappable *o) { - SystemPath *p = static_cast(o); + SystemPath *p = static_cast(o); out = Json::array(); out[0] = Json(p->sectorX); out[1] = Json(p->sectorY); @@ -631,22 +634,32 @@ static bool _systempath_from_json(const Json &obj) { if (!obj.is_array()) return false; if (obj.size() < 3 || obj.size() > 5) return false; - for (size_t i = 0; i < obj.size(); ++i) { if (!obj[i].is_number_integer()) { return false; } } + for (size_t i = 0; i < obj.size(); ++i) { + if (!obj[i].is_number_integer()) { + return false; + } + } SystemPath p; p.sectorX = obj[0]; p.sectorY = obj[1]; p.sectorZ = obj[2]; - if (obj.size() >= 4) { p.systemIndex = obj[3]; } - if (obj.size() >= 5) { p.bodyIndex = obj[4]; } + if (obj.size() >= 4) { + p.systemIndex = obj[3]; + } + if (obj.size() >= 5) { + p.bodyIndex = obj[4]; + } LuaObject::PushToLua(p); return true; } -template <> const char *LuaObject::s_type = "SystemPath"; +template <> +const char *LuaObject::s_type = "SystemPath"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { { "New", l_sbodypath_new }, @@ -661,19 +674,19 @@ template <> void LuaObject::RegisterClass() { "GetStarSystem", l_sbodypath_get_star_system }, { "GetSystemBody", l_sbodypath_get_system_body }, - { "IsSystemPath", l_sbodypath_is_system_path }, - { "IsSectorPath", l_sbodypath_is_sector_path }, - { "IsBodyPath", l_sbodypath_is_body_path }, - { "ParseString", l_sbodypath_parse_string}, + { "IsSystemPath", l_sbodypath_is_system_path }, + { "IsSectorPath", l_sbodypath_is_sector_path }, + { "IsBodyPath", l_sbodypath_is_body_path }, + { "ParseString", l_sbodypath_parse_string }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "sectorX", l_sbodypath_attr_sector_x }, - { "sectorY", l_sbodypath_attr_sector_y }, - { "sectorZ", l_sbodypath_attr_sector_z }, + { "sectorX", l_sbodypath_attr_sector_x }, + { "sectorY", l_sbodypath_attr_sector_y }, + { "sectorZ", l_sbodypath_attr_sector_z }, { "systemIndex", l_sbodypath_attr_system_index }, - { "bodyIndex", l_sbodypath_attr_body_index }, + { "bodyIndex", l_sbodypath_attr_body_index }, { 0, 0 } }; @@ -683,6 +696,5 @@ template <> void LuaObject::RegisterClass() }; LuaObjectBase::CreateClass(s_type, 0, l_methods, l_attrs, l_meta); - LuaObjectBase::RegisterSerializer(s_type, SerializerPair( - _systempath_serializer, _systempath_deserializer, _systempath_to_json, _systempath_from_json)); + LuaObjectBase::RegisterSerializer(s_type, SerializerPair(_systempath_serializer, _systempath_deserializer, _systempath_to_json, _systempath_from_json)); } diff --git a/src/LuaTable.h b/src/LuaTable.h index d0b58c5fb..9c43bbe02 100644 --- a/src/LuaTable.h +++ b/src/LuaTable.h @@ -9,8 +9,8 @@ #include -#include "LuaRef.h" #include "LuaPushPull.h" +#include "LuaRef.h" #include "LuaUtils.h" /* @@ -97,52 +97,75 @@ class LuaTable { public: // For now, every lua_State * can only be NULL or Pi::LuaManager->GetLuaState(); - LuaTable(const LuaTable & ref): m_lua(ref.m_lua), m_index(ref.m_index) {} // Copy constructor. - LuaTable(lua_State * l, int index): m_lua(l), m_index(lua_absindex(l, index)) {assert(lua_istable(m_lua, m_index));} - explicit LuaTable(lua_State * l): m_lua(l) { + LuaTable(const LuaTable &ref) : + m_lua(ref.m_lua), + m_index(ref.m_index) {} // Copy constructor. + LuaTable(lua_State *l, int index) : + m_lua(l), + m_index(lua_absindex(l, index)) { assert(lua_istable(m_lua, m_index)); } + explicit LuaTable(lua_State *l) : + m_lua(l) + { lua_newtable(m_lua); m_index = lua_gettop(l); } ~LuaTable() {} - const LuaTable & operator=(const LuaTable & ref) { m_lua = ref.m_lua; m_index = ref.m_index; return *this;} - template LuaTable PushValueToStack(const Key & key) const; - template Value Get(const Key & key) const; - template LuaTable Sub(const Key & key) const; // Does not clean up the stack. - template Value Get(const Key & key, Value default_value) const; - template LuaTable Set(const Key & key, const Value & value) const; + const LuaTable &operator=(const LuaTable &ref) + { + m_lua = ref.m_lua; + m_index = ref.m_index; + return *this; + } + template + LuaTable PushValueToStack(const Key &key) const; + template + Value Get(const Key &key) const; + template + LuaTable Sub(const Key &key) const; // Does not clean up the stack. + template + Value Get(const Key &key, Value default_value) const; + template + LuaTable Set(const Key &key, const Value &value) const; - template - Ret Call(const Key & key, const Args &... args) const; - template - void Call(const Key & key, const Args &... args) const { + template + Ret Call(const Key &key, const Args &... args) const; + template + void Call(const Key &key, const Args &... args) const + { Call(key, args...); } - template - std::tuple Call(const Key & key, const Args &... args) const; + template + std::tuple Call(const Key &key, const Args &... args) const; - template - void CallMethod(const Key & key, const Args &... args) const { + template + void CallMethod(const Key &key, const Args &... args) const + { Call(key, *this, args...); } - template - Ret CallMethod(const Key & key, const Args &... args) const { + template + Ret CallMethod(const Key &key, const Args &... args) const + { return Call(key, *this, args...); } - template - std::tuple CallMethod(const Key & key, const Args &... args) const { + template + std::tuple CallMethod(const Key &key, const Args &... args) const + { return Call(key, *this, args...); } - template LuaTable LoadMap(PairIterator beg, PairIterator end) const; - template LuaTable LoadVector(ValueIterator beg, ValueIterator end) const; + template + LuaTable LoadMap(PairIterator beg, PairIterator end) const; + template + LuaTable LoadVector(ValueIterator beg, ValueIterator end) const; - template std::map GetMap() const; + template + std::map GetMap() const; - lua_State * GetLua() const { return m_lua; } + lua_State *GetLua() const { return m_lua; } int GetIndex() const { return m_index; } - size_t Size() const {return lua_rawlen(m_lua, m_index);} + size_t Size() const { return lua_rawlen(m_lua, m_index); } /* VecIter, as in VectorIterator (only shorter to type :-) * @@ -153,79 +176,146 @@ public: * For all other values, occasional operations on the stack may occur but it should * not leak anything. */ - template class VecIter : public std::iterator { - public: - VecIter() : m_table(0), m_currentIndex(0), m_cache(), m_dirtyCache(true) {} - ~VecIter() {} - VecIter(LuaTable * t, int currentIndex): m_table(t), m_currentIndex(currentIndex), m_cache(), m_dirtyCache(true) {} - VecIter(const VecIter & copy): m_table(copy.m_table), m_currentIndex(copy.m_currentIndex), m_cache(), m_dirtyCache(true) {} - void operator=(const VecIter & copy) { CleanCache(); m_table = copy.m_table; m_currentIndex = copy.m_currentIndex;} + template + class VecIter : public std::iterator { + public: + VecIter() : + m_table(0), + m_currentIndex(0), + m_cache(), + m_dirtyCache(true) {} + ~VecIter() {} + VecIter(LuaTable *t, int currentIndex) : + m_table(t), + m_currentIndex(currentIndex), + m_cache(), + m_dirtyCache(true) {} + VecIter(const VecIter ©) : + m_table(copy.m_table), + m_currentIndex(copy.m_currentIndex), + m_cache(), + m_dirtyCache(true) {} + void operator=(const VecIter ©) + { + CleanCache(); + m_table = copy.m_table; + m_currentIndex = copy.m_currentIndex; + } - VecIter operator++() { if (m_table) {CleanCache(); ++m_currentIndex;} return *this; } - VecIter operator++(int) { VecIter copy(*this); if (m_table) {CleanCache(); ++m_currentIndex;} return copy;} - VecIter operator--() { if (m_table) --m_currentIndex; return *this; } - VecIter operator--(int) { VecIter copy(*this); if (m_table) --m_currentIndex; return copy;} - - bool operator==(const VecIter & other) const {return (m_table == other.m_table && m_currentIndex == other.m_currentIndex);} - bool operator!=(const VecIter & other) const {return (m_table != other.m_table || m_currentIndex != other.m_currentIndex);} - Value operator*() { LoadCache(); return m_cache;} - const Value * operator->() { LoadCache(); return &m_cache;} - private: - void CleanCache() { m_dirtyCache = true; } - void LoadCache() { - if (m_dirtyCache) { - m_cache = m_table->Get(m_currentIndex); - m_dirtyCache = false; - } + VecIter operator++() + { + if (m_table) { + CleanCache(); + ++m_currentIndex; } - LuaTable * m_table; - int m_currentIndex; - Value m_cache; - bool m_dirtyCache; + return *this; + } + VecIter operator++(int) + { + VecIter copy(*this); + if (m_table) { + CleanCache(); + ++m_currentIndex; + } + return copy; + } + VecIter operator--() + { + if (m_table) --m_currentIndex; + return *this; + } + VecIter operator--(int) + { + VecIter copy(*this); + if (m_table) --m_currentIndex; + return copy; + } + + bool operator==(const VecIter &other) const { return (m_table == other.m_table && m_currentIndex == other.m_currentIndex); } + bool operator!=(const VecIter &other) const { return (m_table != other.m_table || m_currentIndex != other.m_currentIndex); } + Value operator*() + { + LoadCache(); + return m_cache; + } + const Value *operator->() + { + LoadCache(); + return &m_cache; + } + + private: + void CleanCache() { m_dirtyCache = true; } + void LoadCache() + { + if (m_dirtyCache) { + m_cache = m_table->Get(m_currentIndex); + m_dirtyCache = false; + } + } + LuaTable *m_table; + int m_currentIndex; + Value m_cache; + bool m_dirtyCache; }; - template VecIter Begin() {return VecIter(this, 1);} - template VecIter End() {return VecIter(this, Size()+1);} + template + VecIter Begin() { return VecIter(this, 1); } + template + VecIter End() { return VecIter(this, Size() + 1); } protected: - LuaTable(): m_lua(0), m_index(0) {} //Protected : invalid tables shouldn't be out there. - lua_State * m_lua; + LuaTable() : + m_lua(0), + m_index(0) {} //Protected : invalid tables shouldn't be out there. + lua_State *m_lua; int m_index; - }; -class ScopedTable: public LuaTable { +class ScopedTable : public LuaTable { public: - ScopedTable(const LuaTable &t): LuaTable(t) { + ScopedTable(const LuaTable &t) : + LuaTable(t) + { if (m_lua) { lua_pushvalue(m_lua, m_index); m_index = lua_gettop(m_lua); } } - ScopedTable(lua_State* l): LuaTable(l) {} - ScopedTable(const LuaRef & r): LuaTable() { + ScopedTable(lua_State *l) : + LuaTable(l) {} + ScopedTable(const LuaRef &r) : + LuaTable() + { r.PushCopyToStack(); m_lua = r.GetLua(); m_index = lua_gettop(m_lua); } - ~ScopedTable() { + ~ScopedTable() + { if (m_lua && !lua_isnone(m_lua, m_index) && lua_istable(m_lua, m_index)) lua_remove(m_lua, m_index); } }; -template LuaTable LuaTable::PushValueToStack(const Key & key) const { +template +LuaTable LuaTable::PushValueToStack(const Key &key) const +{ pi_lua_generic_push(m_lua, key); lua_gettable(m_lua, m_index); return *this; } -template LuaTable LuaTable::Sub(const Key & key) const { +template +LuaTable LuaTable::Sub(const Key &key) const +{ PushValueToStack(key); return (lua_istable(m_lua, -1)) ? LuaTable(m_lua, -1) : LuaTable(); } -template Value LuaTable::Get(const Key & key) const { +template +Value LuaTable::Get(const Key &key) const +{ Value return_value; PushValueToStack(key); pi_lua_generic_pull(m_lua, -1, return_value); @@ -233,7 +323,9 @@ template Value LuaTable::Get(const Key & key) const { return return_value; } -template Value LuaTable::Get(const Key & key, Value default_value) const { +template +Value LuaTable::Get(const Key &key, Value default_value) const +{ PushValueToStack(key); if (!(lua_isnil(m_lua, -1))) pi_lua_generic_pull(m_lua, -1, default_value); @@ -241,18 +333,22 @@ template Value LuaTable::Get(const Key & key, Value def return default_value; } -template LuaTable LuaTable::Set(const Key & key, const Value & value) const { +template +LuaTable LuaTable::Set(const Key &key, const Value &value) const +{ pi_lua_generic_push(m_lua, key); pi_lua_generic_push(m_lua, value); lua_settable(m_lua, m_index); return *this; } -template std::map LuaTable::GetMap() const { +template +std::map LuaTable::GetMap() const +{ LUA_DEBUG_START(m_lua); std::map ret; lua_pushnil(m_lua); - while(lua_next(m_lua, m_index)) { + while (lua_next(m_lua, m_index)) { Key k; Value v; if (pi_lua_strict_pull(m_lua, -2, k) && pi_lua_strict_pull(m_lua, -1, v)) { @@ -266,27 +362,32 @@ template std::map LuaTable::GetMap() const return ret; } -template LuaTable LuaTable::LoadMap(PairIterator beg, PairIterator end) const { - for (PairIterator it = beg; it != end ; ++it) +template +LuaTable LuaTable::LoadMap(PairIterator beg, PairIterator end) const +{ + for (PairIterator it = beg; it != end; ++it) Set(it->first, it->second); return *this; } -template LuaTable LuaTable::LoadVector(ValueIterator beg, ValueIterator end) const { +template +LuaTable LuaTable::LoadVector(ValueIterator beg, ValueIterator end) const +{ lua_len(m_lua, m_index); int i = lua_tointeger(m_lua, -1) + 1; lua_pop(m_lua, 1); - for (ValueIterator it = beg; it != end ; ++it, ++i) + for (ValueIterator it = beg; it != end; ++it, ++i) Set(i, *it); return *this; } -template -Ret LuaTable::Call(const Key & key, const Args &... args) const { +template +Ret LuaTable::Call(const Key &key, const Args &... args) const +{ LUA_DEBUG_START(m_lua); Ret return_value; - lua_checkstack(m_lua, sizeof...(args)+3); + lua_checkstack(m_lua, sizeof...(args) + 3); PushValueToStack(key); pi_lua_multiple_push(m_lua, args...); pi_lua_protected_call(m_lua, sizeof...(args), 1); @@ -296,33 +397,39 @@ Ret LuaTable::Call(const Key & key, const Args &... args) const { return return_value; } -template -std::tuple LuaTable::Call(const Key & key, const Args &... args) const { +template +std::tuple LuaTable::Call(const Key &key, const Args &... args) const +{ LUA_DEBUG_START(m_lua); - lua_checkstack(m_lua, sizeof...(args)+3); + lua_checkstack(m_lua, sizeof...(args) + 3); PushValueToStack(key); pi_lua_multiple_push(m_lua, args...); - pi_lua_protected_call(m_lua, sizeof...(args), sizeof...(Ret)+2); - auto return_values = pi_lua_multiple_pull(m_lua, -static_cast(sizeof...(Ret))-2); - lua_pop(m_lua, static_cast(sizeof...(Ret))+2); + pi_lua_protected_call(m_lua, sizeof...(args), sizeof...(Ret) + 2); + auto return_values = pi_lua_multiple_pull(m_lua, -static_cast(sizeof...(Ret)) - 2); + lua_pop(m_lua, static_cast(sizeof...(Ret)) + 2); LUA_DEBUG_END(m_lua, 0); return return_values; } -template <> inline void LuaTable::VecIter::LoadCache() { +template <> +inline void LuaTable::VecIter::LoadCache() +{ if (m_dirtyCache) { m_cache = m_table->Sub(m_currentIndex); m_dirtyCache = false; } } -template <> inline void LuaTable::VecIter::CleanCache() { +template <> +inline void LuaTable::VecIter::CleanCache() +{ if (!m_dirtyCache && m_cache.GetLua()) { lua_remove(m_cache.GetLua(), m_cache.GetIndex()); } m_dirtyCache = true; } -inline void pi_lua_generic_push(lua_State* l, const LuaTable & value) { +inline void pi_lua_generic_push(lua_State *l, const LuaTable &value) +{ lua_pushvalue(l, value.GetIndex()); } #endif diff --git a/src/LuaTimer.cpp b/src/LuaTimer.cpp index ad69751a9..52e63f832 100644 --- a/src/LuaTimer.cpp +++ b/src/LuaTimer.cpp @@ -2,16 +2,16 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaTimer.h" -#include "LuaUtils.h" #include "Game.h" +#include "LuaUtils.h" #include "Pi.h" void LuaTimer::RemoveAll() { - lua_State *l = Lua::manager->GetLuaState(); + lua_State *l = Lua::manager->GetLuaState(); - lua_pushnil(l); - lua_setfield(l, LUA_REGISTRYINDEX, "PiTimerCallbacks"); + lua_pushnil(l); + lua_setfield(l, LUA_REGISTRYINDEX, "PiTimerCallbacks"); } void LuaTimer::Tick() @@ -52,8 +52,7 @@ void LuaTimer::Tick() lua_pushvalue(l, -2); lua_pushnil(l); lua_settable(l, -5); - } - else { + } else { double every = lua_tonumber(l, -1); lua_pop(l, 1); @@ -248,16 +247,18 @@ static int l_timer_call_every(lua_State *l) return 0; } -template <> const char *LuaObject::s_type = "Timer"; +template <> +const char *LuaObject::s_type = "Timer"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { - { "CallAt", l_timer_call_at }, + { "CallAt", l_timer_call_at }, { "CallEvery", l_timer_call_every }, { 0, 0 } }; diff --git a/src/LuaTimer.h b/src/LuaTimer.h index 75bf237c6..193f4f3da 100644 --- a/src/LuaTimer.h +++ b/src/LuaTimer.h @@ -4,8 +4,8 @@ #ifndef _LUATIMER_H #define _LUATIMER_H -#include "LuaManager.h" #include "DeleteEmitter.h" +#include "LuaManager.h" class LuaTimer : public DeleteEmitter { public: diff --git a/src/LuaUtils.cpp b/src/LuaUtils.cpp index c56b4d5e5..09ef0a3b5 100644 --- a/src/LuaUtils.cpp +++ b/src/LuaUtils.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LuaUtils.h" -#include "libs.h" #include "FileSystem.h" +#include "libs.h" extern "C" { #include "jenkins/lookup3.h" @@ -55,28 +55,26 @@ static int l_hash_random(lua_State *L) luaL_checkany(L, 1); switch (lua_type(L, 1)) { - case LUA_TSTRING: - { - size_t sz; - const char *str = lua_tolstring(L, 1, &sz); - // jenkins/lookup3 - lookup3_hashlittle2(str, sz, &hashA, &hashB); - break; - } - case LUA_TNUMBER: - { - double n = lua_tonumber(L, 1); - assert(!is_nan(n)); - // jenkins/lookup3 - // There are assumptions here that 'double' has the same in-memory - // representation on all platforms we care about. Also since we're - // taking a number as input, the source of that number (Lua code) - // needs to compute it in a way that gives the same result on all - // platforms, which may be tricky in some cases. - lookup3_hashlittle2(&n, sizeof(n), &hashA, &hashB); - break; - } - default: return luaL_error(L, "expected a string or a number for argument 1"); + case LUA_TSTRING: { + size_t sz; + const char *str = lua_tolstring(L, 1, &sz); + // jenkins/lookup3 + lookup3_hashlittle2(str, sz, &hashA, &hashB); + break; + } + case LUA_TNUMBER: { + double n = lua_tonumber(L, 1); + assert(!is_nan(n)); + // jenkins/lookup3 + // There are assumptions here that 'double' has the same in-memory + // representation on all platforms we care about. Also since we're + // taking a number as input, the source of that number (Lua code) + // needs to compute it in a way that gives the same result on all + // platforms, which may be tricky in some cases. + lookup3_hashlittle2(&n, sizeof(n), &hashA, &hashB); + break; + } + default: return luaL_error(L, "expected a string or a number for argument 1"); } if (numargs == 1) { @@ -98,13 +96,19 @@ static int l_hash_random(lua_State *L) Sint64 m = Sint64(lua_tonumber(L, 2)); Sint64 n = Sint64(lua_tonumber(L, 3)); - if (m > n) { return luaL_error(L, "arguments invalid (m > n not allowed)"); } + if (m > n) { + return luaL_error(L, "arguments invalid (m > n not allowed)"); + } // Restrict to 32-bit output. This is a bit weird because we allow both signed and unsigned. if (m < 0) { - if (m < INT32_MIN || n > INT32_MAX) { return luaL_error(L, "arguments out of range for signed 32-bit int"); } + if (m < INT32_MIN || n > INT32_MAX) { + return luaL_error(L, "arguments out of range for signed 32-bit int"); + } } else { - if (n > UINT32_MAX) { return luaL_error(L, "arguments out of range for unsigned 32-bit int"); } + if (n > UINT32_MAX) { + return luaL_error(L, "arguments out of range for unsigned 32-bit int"); + } } Uint64 range = n - m + 1; @@ -141,7 +145,7 @@ static int l_trim(lua_State *l) size_t len; const char *str = luaL_checklstring(l, 1, &len); - if (len == 0 || (!isspace(str[0]) && !isspace(str[len-1]))) { + if (len == 0 || (!isspace(str[0]) && !isspace(str[len - 1]))) { // empty string, or the string beings & ends with non-whitespace // just return the same value lua_pushvalue(l, 1); @@ -149,8 +153,14 @@ static int l_trim(lua_State *l) } else { const char *first = str; const char *last = str + (len - 1); - while (len && isspace(*first)) { ++first; --len; } - while (len && isspace(*last)) { --last; --len; } + while (len && isspace(*first)) { + ++first; + --len; + } + while (len && isspace(*last)) { + --last; + --len; + } lua_pushlstring(l, first, len); return 1; } @@ -195,24 +205,23 @@ static bool _import_core(lua_State *L, const std::string &importName) #undef DEBUG_IMPORT #ifdef DEBUG_IMPORT - #define DEBUG_PRINTF Output - #define DEBUG_INDENTED_PRINTF IndentedOutput - #define DEBUG_INDENT_INCREASE IndentIncrease - #define DEBUG_INDENT_DECREASE IndentDecrease +#define DEBUG_PRINTF Output +#define DEBUG_INDENTED_PRINTF IndentedOutput +#define DEBUG_INDENT_INCREASE IndentIncrease +#define DEBUG_INDENT_DECREASE IndentDecrease #else - #define DEBUG_PRINTF(...) - #define DEBUG_INDENTED_PRINTF(...) - #define DEBUG_INDENT_INCREASE(...) - #define DEBUG_INDENT_DECREASE(...) +#define DEBUG_PRINTF(...) +#define DEBUG_INDENTED_PRINTF(...) +#define DEBUG_INDENT_INCREASE(...) +#define DEBUG_INDENT_DECREASE(...) #endif // simple struct to pass data between functions -struct ImportInfo -{ - const std::string& importName; // original name argument from "import(importName)" - std::string& fileName; // name of the existing file - const bool& isFullName; // if true import will no try to load relative to the importDirectories - std::vector& importDirectories; // contans list of paths where file can be imported +struct ImportInfo { + const std::string &importName; // original name argument from "import(importName)" + std::string &fileName; // name of the existing file + const bool &isFullName; // if true import will no try to load relative to the importDirectories + std::vector &importDirectories; // contans list of paths where file can be imported }; /** @@ -228,8 +237,7 @@ static std::string get_caller(lua_State *L) lua_Debug ar; // if have stack and caller in the stack - if (lua_getstack(L, 1, &ar) && lua_getinfo(L, "S", &ar) && ar.source) - { + if (lua_getstack(L, 1, &ar) && lua_getinfo(L, "S", &ar) && ar.source) { int start = 0; int end = strlen(ar.source); @@ -255,7 +263,7 @@ static std::string get_caller(lua_State *L) * Requires a existing table in the stack at index -1. * Returns true if field exists and not nil, puts value to lua stack. */ -static bool get_cached(lua_State *L, const std::string& name) +static bool get_cached(lua_State *L, const std::string &name) { LUA_DEBUG_START(L); assert(lua_istable(L, -1)); @@ -278,7 +286,8 @@ static bool get_cached(lua_State *L, const std::string& name) in the form `module/submodule/abc`. */ #include -static std::string table_path_to_file_name(const std::string &path) { +static std::string table_path_to_file_name(const std::string &path) +{ const char separator = '.'; std::string out = path; @@ -295,7 +304,7 @@ static std::string table_path_to_file_name(const std::string &path) { * Require a existing cache table in the stack at index -1. * Returns true if field not nil (exists), puts value to lua stack. */ -static bool import_from_cache(lua_State *L, const ImportInfo& importInfo) +static bool import_from_cache(lua_State *L, const ImportInfo &importInfo) { LUA_DEBUG_START(L); assert(lua_istable(L, -1)); @@ -312,19 +321,17 @@ static bool import_from_cache(lua_State *L, const ImportInfo& importInfo) // check original name, with lua extension and relative by dirs by same rule // if isFullName is true, loop pass once and check only original importName - for (size_t i = 0; i < dirsToCheck; i++) - { + for (size_t i = 0; i < dirsToCheck; i++) { std::string cacheName = realName; if (i > 0) cacheName = FileSystem::NormalisePath( - // normalize for relative paths as "../target" - FileSystem::JoinPath(importInfo.importDirectories[i - 1], realName)); + // normalize for relative paths as "../target" + FileSystem::JoinPath(importInfo.importDirectories[i - 1], realName)); // check original name isImported = get_cached(L, cacheName); // check name with extension - if (!isImported && !importInfo.isFullName) - { + if (!isImported && !importInfo.isFullName) { isImported = get_cached(L, cacheName + ".lua"); if (isImported) cacheName += ".lua"; } @@ -334,8 +341,7 @@ static bool import_from_cache(lua_State *L, const ImportInfo& importInfo) isImported = get_cached(L, cacheName); } - if (isImported) - { + if (isImported) { DEBUG_PRINTF(" found cached %s\n", cacheName.c_str()); break; } @@ -352,15 +358,14 @@ static bool import_from_cache(lua_State *L, const ImportInfo& importInfo) * Tries to load file. * Returns true if file exists and puts return of dofile to stack. */ -static bool load_file(lua_State *L, const std::string& name) +static bool load_file(lua_State *L, const std::string &name) { LUA_DEBUG_START(L); RefCountedPtr fileData = FileSystem::gameDataFiles.ReadFile(name); // if file exists - if (fileData) - { + if (fileData) { DEBUG_PRINTF(" loading %s...\n", name.c_str()); pi_lua_dofile(L, *fileData, 1); } @@ -374,7 +379,7 @@ static bool load_file(lua_State *L, const std::string& name) * If file found returns true, puts return of dofile to stack, no matter nil it or value. * If import was successful, changes fileName in the importInfo to the filename that was found. */ -static bool import_from_file(lua_State *L, ImportInfo& importInfo) +static bool import_from_file(lua_State *L, ImportInfo &importInfo) { LUA_DEBUG_START(L); DEBUG_INDENTED_PRINTF("import [%s]: trying to load a file...", importInfo.importName.c_str()); @@ -390,18 +395,16 @@ static bool import_from_file(lua_State *L, ImportInfo& importInfo) // load file with original name, with lua extension and relative by dirs by same rule // if isFullName is true, loop pass once and check only original importName - for (size_t i = 0; i < dirsToCheck; i++) - { + for (size_t i = 0; i < dirsToCheck; i++) { std::string fileName = realName; if (i > 0) fileName = FileSystem::NormalisePath( // normalize for relative paths as "../target" - FileSystem::JoinPath(importInfo.importDirectories[i - 1], realName)); + FileSystem::JoinPath(importInfo.importDirectories[i - 1], realName)); // check original name isImported = load_file(L, fileName); // check name with extension - if (!isImported && !importInfo.isFullName) - { + if (!isImported && !importInfo.isFullName) { isImported = load_file(L, fileName + ".lua"); if (isImported) fileName += ".lua"; } @@ -411,8 +414,7 @@ static bool import_from_file(lua_State *L, ImportInfo& importInfo) isImported = load_file(L, fileName); } - if (isImported) - { + if (isImported) { DEBUG_INDENTED_PRINTF("import [%s]: file %s loaded\n", importInfo.importName.c_str(), fileName.c_str()); importInfo.fileName = fileName; break; @@ -430,7 +432,7 @@ static bool import_from_file(lua_State *L, ImportInfo& importInfo) * Tries to import from core. * Returns true if imported, puts value to the stack. */ -static bool import_from_core(lua_State *L, const ImportInfo& importInfo) +static bool import_from_core(lua_State *L, const ImportInfo &importInfo) { LUA_DEBUG_START(L); DEBUG_INDENTED_PRINTF("import [%s]: trying core import...", importInfo.importName.c_str()); @@ -449,26 +451,23 @@ static bool import_from_core(lua_State *L, const ImportInfo& importInfo) /** * Saves value with index -1 to table with index -2 */ -static void save_to_cache(lua_State *L, const ImportInfo& importInfo) +static void save_to_cache(lua_State *L, const ImportInfo &importInfo) { LUA_DEBUG_START(L); DEBUG_INDENTED_PRINTF("import [%s]: entering into cache...", importInfo.importName.c_str()); // cache if got not nil - if (!lua_isnil(L, -1)) - { + if (!lua_isnil(L, -1)) { lua_pushvalue(L, -1); lua_setfield(L, -3, importInfo.fileName.c_str()); DEBUG_PRINTF(" saved with name %s\n", importInfo.fileName.c_str()); - } - else + } else DEBUG_PRINTF(" aborted because imported module returned nil\n"); LUA_DEBUG_END(L, 0); // function does not change the stack } - /** * Imports from file or loads from cache lua module. * Also tries to import from core. @@ -477,21 +476,20 @@ static void save_to_cache(lua_State *L, const ImportInfo& importInfo) * If isFullName disabled tries to check with .lua extension and also * relative by importDirectories. Else checks only by importName. */ -static bool _import(lua_State *L, const std::string& importName, bool isFullName = false) +static bool _import(lua_State *L, const std::string &importName, bool isFullName = false) { LUA_DEBUG_START(L); bool isImported = false; std::string fileName; - const std::string& caller = get_caller(L); + const std::string &caller = get_caller(L); std::string callerDirectory; if (!caller.empty()) callerDirectory = caller.substr(0, caller.find_last_of('/')); - std::vector importDirectories - { + std::vector importDirectories{ "libs" }; @@ -508,15 +506,12 @@ static bool _import(lua_State *L, const std::string& importName, bool isFullName importInfo.importName.c_str(), caller.empty() ? "core" : caller.c_str()); // add caller directory to import directories if exists - if (!isFullName && !callerDirectory.empty()) - { + if (!isFullName && !callerDirectory.empty()) { bool directoryExists = false; // check if caller not exists in import directory - for (auto it = importInfo.importDirectories.begin(); it != importInfo.importDirectories.end(); ++it) - { - if (*it == callerDirectory) - { + for (auto it = importInfo.importDirectories.begin(); it != importInfo.importDirectories.end(); ++it) { + if (*it == callerDirectory) { directoryExists = true; break; } @@ -555,21 +550,16 @@ static bool _import(lua_State *L, const std::string& importName, bool isFullName // generate error messages DEBUG_INDENTED_PRINTF("import [%s]: generating error messages...", importInfo.importName.c_str()); - if (isImported) - { + if (isImported) { // usually happens when file not returns nothing or nil - if (lua_isnil(L, -1)) - { + if (lua_isnil(L, -1)) { lua_pop(L, 1); DEBUG_PRINTF(" got error: %s did not return anything\n", importInfo.fileName.c_str()); lua_pushfstring(L, "import [%s]: %s did not return anything", importInfo.importName.c_str(), importInfo.fileName.c_str()); isImported = false; - } - else + } else DEBUG_PRINTF(" no errors\n"); - } - else - { + } else { // if just not imported DEBUG_PRINTF(" got error: not found\n"); lua_pushfstring(L, "import [%s]: not found", importInfo.importName.c_str()); @@ -582,7 +572,6 @@ static bool _import(lua_State *L, const std::string& importName, bool isFullName return isImported; } - static int l_d_null_userdata(lua_State *L) { lua_pushlightuserdata(L, nullptr); @@ -599,9 +588,9 @@ static int l_base_import(lua_State *L) bool pi_lua_import(lua_State *L, const std::string &importName, bool isFullName) { if (!_import(L, importName, isFullName)) { - #ifndef DEBUG_IMPORT // already have extended info +#ifndef DEBUG_IMPORT // already have extended info Output("%s\n", lua_tostring(L, -1)); - #endif +#endif lua_pop(L, 1); return false; } @@ -614,14 +603,12 @@ void pi_lua_import_recursive(lua_State *L, const std::string &basepath) DEBUG_INDENTED_PRINTF("import recursive [%s]: started\n", basepath.c_str()); DEBUG_INDENT_INCREASE(); - for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, basepath, FileSystem::FileEnumerator::IncludeDirs); !files.Finished(); files.Next()) - { + for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, basepath, FileSystem::FileEnumerator::IncludeDirs); !files.Finished(); files.Next()) { const FileSystem::FileInfo &info = files.Current(); const std::string &fpath = info.GetPath(); if (info.IsDir()) { pi_lua_import_recursive(L, fpath); - } - else { + } else { assert(info.IsFile()); if (ends_with_ci(fpath, ".lua")) { if (pi_lua_import(L, fpath, true)) @@ -716,7 +703,6 @@ void pi_lua_open_standard_base(lua_State *L) lua_pushnil(L); lua_setglobal(L, "loadstring"); - // import table and function lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "Imports"); @@ -866,7 +852,8 @@ int pi_lua_panic(lua_State *L) RETURN_ZERO_NONGNU_ONLY; } -void pi_lua_protected_call(lua_State* L, int nargs, int nresults) { +void pi_lua_protected_call(lua_State *L, int nargs, int nresults) +{ int handleridx = lua_gettop(L) - nargs; lua_pushcfunction(L, &l_handle_error); lua_insert(L, handleridx); @@ -918,21 +905,23 @@ static void pi_lua_dofile(lua_State *l, const FileSystem::FileData &code, int nr int ret = lua_pcall(l, 0, nret, panicidx); if (ret) { const char *emsg = lua_tostring(l, -1); - if (emsg) { Output("lua error: %s\n", emsg); } + if (emsg) { + Output("lua error: %s\n", emsg); + } switch (ret) { - case LUA_ERRRUN: - Output("Lua runtime error in pi_lua_dofile('%s')\n", - code.GetInfo().GetAbsolutePath().c_str()); - break; - case LUA_ERRMEM: - Output("Memory allocation error in Lua pi_lua_dofile('%s')\n", - code.GetInfo().GetAbsolutePath().c_str()); - break; - case LUA_ERRERR: - Output("Error running error handler in pi_lua_dofile('%s')\n", - code.GetInfo().GetAbsolutePath().c_str()); - break; - default: abort(); + case LUA_ERRRUN: + Output("Lua runtime error in pi_lua_dofile('%s')\n", + code.GetInfo().GetAbsolutePath().c_str()); + break; + case LUA_ERRMEM: + Output("Memory allocation error in Lua pi_lua_dofile('%s')\n", + code.GetInfo().GetAbsolutePath().c_str()); + break; + case LUA_ERRERR: + Output("Error running error handler in pi_lua_dofile('%s')\n", + code.GetInfo().GetAbsolutePath().c_str()); + break; + default: abort(); } lua_pop(l, 1); } @@ -961,8 +950,7 @@ void pi_lua_dofile_recursive(lua_State *l, const std::string &basepath) { LUA_DEBUG_START(l); - for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, basepath, FileSystem::FileEnumerator::IncludeDirs); !files.Finished(); files.Next()) - { + for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, basepath, FileSystem::FileEnumerator::IncludeDirs); !files.Finished(); files.Next()) { const FileSystem::FileInfo &info = files.Current(); const std::string &fpath = info.GetPath(); if (info.IsDir()) { diff --git a/src/LuaUtils.h b/src/LuaUtils.h index 4b5116217..4217bfbeb 100644 --- a/src/LuaUtils.h +++ b/src/LuaUtils.h @@ -4,11 +4,13 @@ #ifndef _LUAUTILS_H #define _LUAUTILS_H -#include -#include #include "utils.h" +#include +#include -namespace FileSystem { class FileData; } +namespace FileSystem { + class FileData; +} inline void pi_lua_settable(lua_State *l, const char *key, bool value) { @@ -69,33 +71,33 @@ void pi_lua_readonly_table_original(lua_State *l, int index); bool pi_lua_import(lua_State *l, const std::string &importName, bool isFullName = false); void pi_lua_import_recursive(lua_State *L, const std::string &basepath); -int pi_lua_panic(lua_State *l) __attribute((noreturn)); -void pi_lua_protected_call(lua_State* state, int nargs, int nresults); +int pi_lua_panic(lua_State *l) __attribute((noreturn)); +void pi_lua_protected_call(lua_State *state, int nargs, int nresults); int pi_lua_loadfile(lua_State *l, const FileSystem::FileData &code); void pi_lua_dofile(lua_State *l, const std::string &path); void pi_lua_dofile_recursive(lua_State *l, const std::string &basepath); -void pi_lua_warn(lua_State *l, const char *format, ...) __attribute((format(printf,2,3))); +void pi_lua_warn(lua_State *l, const char *format, ...) __attribute((format(printf, 2, 3))); bool pi_lua_split_table_path(lua_State *l, const std::string &path); int secure_trampoline(lua_State *l); #ifdef DEBUG -# define LUA_DEBUG_START(luaptr) const int __luaStartStackDepth = lua_gettop(luaptr) -# define LUA_DEBUG_END(luaptr, expectedStackDiff) \ - do { \ - const int __luaEndStackDepth = lua_gettop(luaptr); \ - if ( __luaEndStackDepth-expectedStackDiff != __luaStartStackDepth) { \ - Error("%s:%d: lua stack difference is %d, expected %d", \ - __FILE__, __LINE__, __luaEndStackDepth-__luaStartStackDepth, expectedStackDiff); \ - } \ +#define LUA_DEBUG_START(luaptr) const int __luaStartStackDepth = lua_gettop(luaptr) +#define LUA_DEBUG_END(luaptr, expectedStackDiff) \ + do { \ + const int __luaEndStackDepth = lua_gettop(luaptr); \ + if (__luaEndStackDepth - expectedStackDiff != __luaStartStackDepth) { \ + Error("%s:%d: lua stack difference is %d, expected %d", \ + __FILE__, __LINE__, __luaEndStackDepth - __luaStartStackDepth, expectedStackDiff); \ + } \ } while (0) -# define LUA_DEBUG_CHECK(luaptr, expectedStackDiff) LUA_DEBUG_END(luaptr, expectedStackDiff) +#define LUA_DEBUG_CHECK(luaptr, expectedStackDiff) LUA_DEBUG_END(luaptr, expectedStackDiff) #else -# define LUA_DEBUG_START(luaptr) -# define LUA_DEBUG_END(luaptr, expectedStackDiff) -# define LUA_DEBUG_CHECK(luaptr, expectedStackDiff) +#define LUA_DEBUG_START(luaptr) +#define LUA_DEBUG_END(luaptr, expectedStackDiff) +#define LUA_DEBUG_CHECK(luaptr, expectedStackDiff) #endif #endif diff --git a/src/LuaVector.cpp b/src/LuaVector.cpp index a4b9b77db..e113e469f 100644 --- a/src/LuaVector.cpp +++ b/src/LuaVector.cpp @@ -1,9 +1,9 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "LuaVector.h" #include "LuaUtils.h" +#include "libs.h" static int l_vector_new(lua_State *L) { @@ -200,17 +200,17 @@ void LuaVector::Register(lua_State *L) vector3d *LuaVector::PushNewToLua(lua_State *L) { - vector3d *ptr = static_cast(lua_newuserdata(L, sizeof(vector3d))); + vector3d *ptr = static_cast(lua_newuserdata(L, sizeof(vector3d))); luaL_setmetatable(L, LuaVector::TypeName); return ptr; } const vector3d *LuaVector::GetFromLua(lua_State *L, int idx) { - return static_cast(luaL_testudata(L, idx, LuaVector::TypeName)); + return static_cast(luaL_testudata(L, idx, LuaVector::TypeName)); } const vector3d *LuaVector::CheckFromLua(lua_State *L, int idx) { - return static_cast(luaL_checkudata(L, idx, LuaVector::TypeName)); + return static_cast(luaL_checkudata(L, idx, LuaVector::TypeName)); } diff --git a/src/LuaVector.h b/src/LuaVector.h index 074708ea7..6bfdf2f2c 100644 --- a/src/LuaVector.h +++ b/src/LuaVector.h @@ -20,16 +20,18 @@ namespace LuaVector { inline void PushToLuaF(lua_State *L, const vector3f &v) { PushToLua(L, vector3d(v)); } inline vector3f CheckFromLuaF(lua_State *L, int idx) { return vector3f(*CheckFromLua(L, idx)); } -} +} // namespace LuaVector -inline void pi_lua_generic_push(lua_State * l, const vector3d & value) { LuaVector::PushToLua(l, value); } +inline void pi_lua_generic_push(lua_State *l, const vector3d &value) { LuaVector::PushToLua(l, value); } -inline void pi_lua_generic_pull(lua_State * l, int index, vector3d& out) { +inline void pi_lua_generic_pull(lua_State *l, int index, vector3d &out) +{ out = *LuaVector::CheckFromLua(l, index); } -inline bool pi_lua_strict_pull(lua_State * l, int index, vector3d & out) { - const vector3d* tmp = LuaVector::GetFromLua(l, index); +inline bool pi_lua_strict_pull(lua_State *l, int index, vector3d &out) +{ + const vector3d *tmp = LuaVector::GetFromLua(l, index); if (tmp) { out = *tmp; return true; diff --git a/src/MathUtil.cpp b/src/MathUtil.cpp index 2ee94feb3..ff4d3f169 100644 --- a/src/MathUtil.cpp +++ b/src/MathUtil.cpp @@ -6,39 +6,46 @@ namespace MathUtil { - vector3d RandomPointOnSphere(double minRadius,double maxRadius) + vector3d RandomPointOnSphere(double minRadius, double maxRadius) { // see http://mathworld.wolfram.com/SpherePointPicking.html // or a Google search for further information - const double dist = Pi::rng.Double(minRadius,maxRadius); - const double z = Pi::rng.Double_closed(-1.0,1.0); - const double theta = Pi::rng.Double(2.0*M_PI); - const double r = sqrt(1.0 - z*z) * dist; - return vector3d(r*cos(theta),r*sin(theta),z*dist); + const double dist = Pi::rng.Double(minRadius, maxRadius); + const double z = Pi::rng.Double_closed(-1.0, 1.0); + const double theta = Pi::rng.Double(2.0 * M_PI); + const double r = sqrt(1.0 - z * z) * dist; + return vector3d(r * cos(theta), r * sin(theta), z * dist); } - vector3d RandomPointInCircle(double minRadius,double maxRadius) + vector3d RandomPointInCircle(double minRadius, double maxRadius) { // m: minRadius, M: maxRadius, r: random radius // PDF(r) = 2/(M^2 - m^2) * r for m <= r < M // CDF(r) = 1/(M^2 - m^2) * (r^2 - m^2) // per inversion method (http://en.wikipedia.org/wiki/Inversion_method): CDF(r) := Uniform{0..1} // r = sqrt(Uniform{0..1} * (M^2 - m^2) + m^2) = sqrt(Uniform{m^2..M^2}) - const double r = sqrt(Pi::rng.Double(minRadius*minRadius,maxRadius*maxRadius)); - const double phi = Pi::rng.Double(2.0*M_PI); - return vector3d(r*cos(phi),r*sin(phi),0.0); + const double r = sqrt(Pi::rng.Double(minRadius * minRadius, maxRadius * maxRadius)); + const double phi = Pi::rng.Double(2.0 * M_PI); + return vector3d(r * cos(phi), r * sin(phi), 0.0); } // matrix4x4f utility functions - matrix4x4f Inverse(const matrix4x4f &cell) { + matrix4x4f Inverse(const matrix4x4f &cell) + { matrix4x4f m; // this only works for matrices containing only rotation and transform - m[0] = cell[0]; m[1] = cell[4]; m[2] = cell[8]; - m[4] = cell[1]; m[5] = cell[5]; m[6] = cell[9]; - m[8] = cell[2]; m[9] = cell[6]; m[10] = cell[10]; - m[12] = -(cell[0]*cell[12] + cell[1]*cell[13] + cell[2]*cell[14]); - m[13] = -(cell[4]*cell[12] + cell[5]*cell[13] + cell[6]*cell[14]); - m[14] = -(cell[8]*cell[12] + cell[9]*cell[13] + cell[10]*cell[14]); + m[0] = cell[0]; + m[1] = cell[4]; + m[2] = cell[8]; + m[4] = cell[1]; + m[5] = cell[5]; + m[6] = cell[9]; + m[8] = cell[2]; + m[9] = cell[6]; + m[10] = cell[10]; + m[12] = -(cell[0] * cell[12] + cell[1] * cell[13] + cell[2] * cell[14]); + m[13] = -(cell[4] * cell[12] + cell[5] * cell[13] + cell[6] * cell[14]); + m[14] = -(cell[8] * cell[12] + cell[9] * cell[13] + cell[10] * cell[14]); m[3] = m[7] = m[11] = 0; m[15] = 1.0f; @@ -48,87 +55,87 @@ namespace MathUtil { { matrix4x4f inv; - inv[0] = cell[5] * cell[10] * cell[15] - - cell[5] * cell[11] * cell[14] - - cell[9] * cell[6] * cell[15] + - cell[9] * cell[7] * cell[14] + - cell[13] * cell[6] * cell[11] - - cell[13] * cell[7] * cell[10]; + inv[0] = cell[5] * cell[10] * cell[15] - + cell[5] * cell[11] * cell[14] - + cell[9] * cell[6] * cell[15] + + cell[9] * cell[7] * cell[14] + + cell[13] * cell[6] * cell[11] - + cell[13] * cell[7] * cell[10]; - inv[4] = -cell[4] * cell[10] * cell[15] + - cell[4] * cell[11] * cell[14] + - cell[8] * cell[6] * cell[15] - - cell[8] * cell[7] * cell[14] - - cell[12] * cell[6] * cell[11] + - cell[12] * cell[7] * cell[10]; + inv[4] = -cell[4] * cell[10] * cell[15] + + cell[4] * cell[11] * cell[14] + + cell[8] * cell[6] * cell[15] - + cell[8] * cell[7] * cell[14] - + cell[12] * cell[6] * cell[11] + + cell[12] * cell[7] * cell[10]; - inv[8] = cell[4] * cell[9] * cell[15] - - cell[4] * cell[11] * cell[13] - - cell[8] * cell[5] * cell[15] + - cell[8] * cell[7] * cell[13] + + inv[8] = cell[4] * cell[9] * cell[15] - + cell[4] * cell[11] * cell[13] - + cell[8] * cell[5] * cell[15] + + cell[8] * cell[7] * cell[13] + cell[12] * cell[5] * cell[11] - cell[12] * cell[7] * cell[9]; - inv[12] = -cell[4] * cell[9] * cell[14] + - cell[4] * cell[10] * cell[13] + - cell[8] * cell[5] * cell[14] - - cell[8] * cell[6] * cell[13] - + inv[12] = -cell[4] * cell[9] * cell[14] + + cell[4] * cell[10] * cell[13] + + cell[8] * cell[5] * cell[14] - + cell[8] * cell[6] * cell[13] - cell[12] * cell[5] * cell[10] + cell[12] * cell[6] * cell[9]; - inv[1] = -cell[1] * cell[10] * cell[15] + - cell[1] * cell[11] * cell[14] + - cell[9] * cell[2] * cell[15] - - cell[9] * cell[3] * cell[14] - + inv[1] = -cell[1] * cell[10] * cell[15] + + cell[1] * cell[11] * cell[14] + + cell[9] * cell[2] * cell[15] - + cell[9] * cell[3] * cell[14] - cell[13] * cell[2] * cell[11] + cell[13] * cell[3] * cell[10]; - inv[5] = cell[0] * cell[10] * cell[15] - - cell[0] * cell[11] * cell[14] - - cell[8] * cell[2] * cell[15] + - cell[8] * cell[3] * cell[14] + + inv[5] = cell[0] * cell[10] * cell[15] - + cell[0] * cell[11] * cell[14] - + cell[8] * cell[2] * cell[15] + + cell[8] * cell[3] * cell[14] + cell[12] * cell[2] * cell[11] - cell[12] * cell[3] * cell[10]; - inv[9] = -cell[0] * cell[9] * cell[15] + - cell[0] * cell[11] * cell[13] + - cell[8] * cell[1] * cell[15] - - cell[8] * cell[3] * cell[13] - + inv[9] = -cell[0] * cell[9] * cell[15] + + cell[0] * cell[11] * cell[13] + + cell[8] * cell[1] * cell[15] - + cell[8] * cell[3] * cell[13] - cell[12] * cell[1] * cell[11] + cell[12] * cell[3] * cell[9]; - inv[13] = cell[0] * cell[9] * cell[14] - - cell[0] * cell[10] * cell[13] - - cell[8] * cell[1] * cell[14] + - cell[8] * cell[2] * cell[13] + + inv[13] = cell[0] * cell[9] * cell[14] - + cell[0] * cell[10] * cell[13] - + cell[8] * cell[1] * cell[14] + + cell[8] * cell[2] * cell[13] + cell[12] * cell[1] * cell[10] - cell[12] * cell[2] * cell[9]; - inv[2] = cell[1] * cell[6] * cell[15] - - cell[1] * cell[7] * cell[14] - - cell[5] * cell[2] * cell[15] + - cell[5] * cell[3] * cell[14] + + inv[2] = cell[1] * cell[6] * cell[15] - + cell[1] * cell[7] * cell[14] - + cell[5] * cell[2] * cell[15] + + cell[5] * cell[3] * cell[14] + cell[13] * cell[2] * cell[7] - cell[13] * cell[3] * cell[6]; - inv[6] = -cell[0] * cell[6] * cell[15] + - cell[0] * cell[7] * cell[14] + - cell[4] * cell[2] * cell[15] - - cell[4] * cell[3] * cell[14] - + inv[6] = -cell[0] * cell[6] * cell[15] + + cell[0] * cell[7] * cell[14] + + cell[4] * cell[2] * cell[15] - + cell[4] * cell[3] * cell[14] - cell[12] * cell[2] * cell[7] + cell[12] * cell[3] * cell[6]; - inv[10] = cell[0] * cell[5] * cell[15] - - cell[0] * cell[7] * cell[13] - - cell[4] * cell[1] * cell[15] + - cell[4] * cell[3] * cell[13] + + inv[10] = cell[0] * cell[5] * cell[15] - + cell[0] * cell[7] * cell[13] - + cell[4] * cell[1] * cell[15] + + cell[4] * cell[3] * cell[13] + cell[12] * cell[1] * cell[7] - cell[12] * cell[3] * cell[5]; - inv[14] = -cell[0] * cell[5] * cell[14] + - cell[0] * cell[6] * cell[13] + - cell[4] * cell[1] * cell[14] - - cell[4] * cell[2] * cell[13] - + inv[14] = -cell[0] * cell[5] * cell[14] + + cell[0] * cell[6] * cell[13] + + cell[4] * cell[1] * cell[14] - + cell[4] * cell[2] * cell[13] - cell[12] * cell[1] * cell[6] + cell[12] * cell[2] * cell[5]; @@ -162,13 +169,13 @@ namespace MathUtil { float det = cell[0] * inv[0] + cell[1] * inv[4] + cell[2] * inv[8] + cell[3] * inv[12]; - if(is_equal_exact(det, 0.0f)) + if (is_equal_exact(det, 0.0f)) return matrix4x4f::Identity(); det = 1.0f / det; matrix4x4f m; - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) m[i] = inv[i] * det; return m; @@ -176,10 +183,22 @@ namespace MathUtil { matrix4x4f Transpose(const matrix4x4f &cell) { matrix4x4f m; - m[0] = cell[0]; m[1] = cell[4]; m[2] = cell[8]; m[3] = cell[12]; - m[4] = cell[1]; m[5] = cell[5]; m[6] = cell[9]; m[7] = cell[13]; - m[8] = cell[2]; m[9] = cell[6]; m[10] = cell[10]; m[11] = cell[14]; - m[12] = cell[3]; m[13] = cell[7]; m[14] = cell[11]; m[15] = cell[15]; + m[0] = cell[0]; + m[1] = cell[4]; + m[2] = cell[8]; + m[3] = cell[12]; + m[4] = cell[1]; + m[5] = cell[5]; + m[6] = cell[9]; + m[7] = cell[13]; + m[8] = cell[2]; + m[9] = cell[6]; + m[10] = cell[10]; + m[11] = cell[14]; + m[12] = cell[3]; + m[13] = cell[7]; + m[14] = cell[11]; + m[15] = cell[15]; return m; } @@ -187,23 +206,29 @@ namespace MathUtil { matrix3x3f Transpose(const matrix3x3f &cell) { matrix3x3f m; - m[0] = cell[0]; m[1] = cell[3]; m[2] = cell[6]; - m[3] = cell[1]; m[4] = cell[4]; m[5] = cell[7]; - m[6] = cell[2]; m[7] = cell[5]; m[8] = cell[8]; + m[0] = cell[0]; + m[1] = cell[3]; + m[2] = cell[6]; + m[3] = cell[1]; + m[4] = cell[4]; + m[5] = cell[7]; + m[6] = cell[2]; + m[7] = cell[5]; + m[8] = cell[8]; return m; } matrix3x3f Inverse(const matrix3x3f &cell) { - // computes the inverse of a matrix m - #define cell2d(x,y) cell[((y*3) + x)] +// computes the inverse of a matrix m +#define cell2d(x, y) cell[((y * 3) + x)] const float det = cell2d(0, 0) * (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) - - cell2d(0, 1) * (cell2d(1, 0) * cell2d(2, 2) - cell2d(1, 2) * cell2d(2, 0)) + - cell2d(0, 2) * (cell2d(1, 0) * cell2d(2, 1) - cell2d(1, 1) * cell2d(2, 0)); + cell2d(0, 1) * (cell2d(1, 0) * cell2d(2, 2) - cell2d(1, 2) * cell2d(2, 0)) + + cell2d(0, 2) * (cell2d(1, 0) * cell2d(2, 1) - cell2d(1, 1) * cell2d(2, 0)); const float invdet = 1.0f / det; matrix3x3f minv; // inverse of matrix m - #define idx2d(x,y) ((y*3) + x) +#define idx2d(x, y) ((y * 3) + x) minv[idx2d(0, 0)] = (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) * invdet; minv[idx2d(0, 1)] = (cell2d(0, 2) * cell2d(2, 1) - cell2d(0, 1) * cell2d(2, 2)) * invdet; minv[idx2d(0, 2)] = (cell2d(0, 1) * cell2d(1, 2) - cell2d(0, 2) * cell2d(1, 1)) * invdet; @@ -218,12 +243,12 @@ namespace MathUtil { // basic distince from a line segment as described here: // http://paulbourke.net/geometry/pointline/ - float DistanceFromLineSegment(const vector3f& start, const vector3f& end, const vector3f& pos, bool& isWithinLineSegment) + float DistanceFromLineSegment(const vector3f &start, const vector3f &end, const vector3f &pos, bool &isWithinLineSegment) { - const float magnitude = (end-start).Length(); - float t = Dot((pos - start), (end - start)) / (magnitude * magnitude) ; + const float magnitude = (end - start).Length(); + float t = Dot((pos - start), (end - start)) / (magnitude * magnitude); - if( t<0.0f || t>1.0f ) { + if (t < 0.0f || t > 1.0f) { t = (t < 0.0f) ? 0.0f : t; t = (t > 1.0f) ? 1.0f : t; isWithinLineSegment = false; @@ -231,22 +256,22 @@ namespace MathUtil { isWithinLineSegment = true; } // convert the time t to a vector to use in intersection calculation - vector3f tv(t,t,t); + vector3f tv(t, t, t); vector3f intersect(start + tv * (end - start)); - return (intersect-pos).Length(); + return (intersect - pos).Length(); } - float DistanceFromLine(const vector3f& start, const vector3f& end, const vector3f& pos) + float DistanceFromLine(const vector3f &start, const vector3f &end, const vector3f &pos) { - const float magnitude = (end-start).Length(); - const float t = Dot((pos - start), (end - start)) / (magnitude * magnitude) ; + const float magnitude = (end - start).Length(); + const float t = Dot((pos - start), (end - start)) / (magnitude * magnitude); // convert the time t to a vector to use in intersection calculation - vector3f tv(t,t,t); + vector3f tv(t, t, t); vector3f intersect(start + tv * (end - start)); - return (intersect-pos).Length(); + return (intersect - pos).Length(); } #ifdef TEST_MATHUTIL @@ -279,22 +304,22 @@ namespace MathUtil { }; static const bool RES[TotalNum] = { false, // no - true,// yes - false,// no - false// no + true, // yes + false, // no + false // no }; static const bool RESLINE[TotalNum] = { true, // no - true,// yes - false,// no - true// no + true, // yes + false, // no + true // no }; // Just working with a fixed distance. static const float triggerSoundDistance = 6.0f; // Iterate through the generated data and see which ones pass close enough to trigger the sound bool success = true; - for( int i=0; i - inline T mix(const T& v1, const T& v2, const F t){ - return t*v2 + (F(1.0)-t)*v1; + template + inline T mix(const T &v1, const T &v2, const F t) + { + return t * v2 + (F(1.0) - t) * v1; } - inline float Dot(const vector3f &a, const vector3f &b) { return a.x*b.x + a.y*b.y + a.z*b.z; } + inline float Dot(const vector3f &a, const vector3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } // unit vector orthogonal to given vector - template - vector3 OrthogonalDirection(const vector3& a) + template + vector3 OrthogonalDirection(const vector3 &a) { vector3 b; - if(std::abs(a.x)>std::abs(a.y)) { - if(std::abs(a.y)>std::abs(a.z)) - b = vector3(-a.y,a.x,0); + if (std::abs(a.x) > std::abs(a.y)) { + if (std::abs(a.y) > std::abs(a.z)) + b = vector3(-a.y, a.x, 0); else - b = vector3(a.z,0,-a.x); - } - else { - if(std::abs(a.x)>std::abs(a.z)) - b = vector3(-a.y,a.x,0); + b = vector3(a.z, 0, -a.x); + } else { + if (std::abs(a.x) > std::abs(a.z)) + b = vector3(-a.y, a.x, 0); else - b = vector3(0,-a.z,a.y); + b = vector3(0, -a.z, a.y); } return b.Normalized(); } @@ -56,8 +56,8 @@ namespace MathUtil { matrix3x3f Transpose(const matrix3x3f &); // distance from a line segment: - float DistanceFromLineSegment(const vector3f& start, const vector3f& end, const vector3f& pos, bool& isWithinLineSegment); - float DistanceFromLine(const vector3f& start, const vector3f& end, const vector3f& pos); + float DistanceFromLineSegment(const vector3f &start, const vector3f &end, const vector3f &pos, bool &isWithinLineSegment); + float DistanceFromLine(const vector3f &start, const vector3f &end, const vector3f &pos); inline static matrix3x3d LookAt(const vector3d eye, const vector3d target, const vector3d up) { @@ -72,6 +72,6 @@ namespace MathUtil { #ifdef TEST_MATHUTIL bool TestDistanceFromLine(); #endif -} +} // namespace MathUtil #endif diff --git a/src/Missile.cpp b/src/Missile.cpp index f02b04cc7..f6990c40c 100644 --- a/src/Missile.cpp +++ b/src/Missile.cpp @@ -2,17 +2,17 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Missile.h" -#include "Space.h" +#include "Game.h" +#include "Lang.h" +#include "LuaEvent.h" +#include "Pi.h" #include "Sfx.h" #include "ShipType.h" -#include "Lang.h" -#include "Pi.h" -#include "Game.h" -#include "LuaEvent.h" +#include "Space.h" -Missile::Missile(const ShipType::Id &shipId, Body *owner, int power)//: Ship(shipId) +Missile::Missile(const ShipType::Id &shipId, Body *owner, int power) //: Ship(shipId) { - AddFeature( Feature::PROPULSION ); // add component propulsion + AddFeature(Feature::PROPULSION); // add component propulsion if (power < 0) { m_power = 0; if (shipId == ShipType::MISSILE_GUIDED) m_power = 1; @@ -24,7 +24,7 @@ Missile::Missile(const ShipType::Id &shipId, Body *owner, int power)//: Ship(shi m_owner = owner; m_type = &ShipType::types[shipId]; - SetMass(m_type->hullMass*1000); + SetMass(m_type->hullMass * 1000); SetModel(m_type->modelName.c_str()); SetMassDistributionFromModel(); @@ -40,8 +40,7 @@ Missile::Missile(const ShipType::Id &shipId, Body *owner, int power)//: Ship(shi m_aiMessage = AIERROR_NONE; m_decelerating = false; - GetPropulsion()->Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust ); - + GetPropulsion()->Init(this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust); } Missile::~Missile() @@ -95,8 +94,7 @@ void Missile::LoadFromJson(const Json &jsonObj, Space *space) throw SavedGameCorruptException(); } - GetPropulsion()->Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust ); - + GetPropulsion()->Init(this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust); } void Missile::PostLoadFixup(Space *space) @@ -113,18 +111,17 @@ void Missile::StaticUpdate(const float timeStep) if (!m_curAICmd) { GetPropulsion()->ClearLinThrusterState(); GetPropulsion()->ClearAngThrusterState(); - } - else if (m_curAICmd->TimeStepUpdate()) { + } else if (m_curAICmd->TimeStepUpdate()) { delete m_curAICmd; m_curAICmd = nullptr; } //Add smoke trails for missiles on thruster state static double s_timeAccum = 0.0; s_timeAccum += timeStep; - if (!is_equal_exact(GetPropulsion()->GetLinThrusterState().LengthSqr(), 0.0) && (s_timeAccum > 4 || 0.1*Pi::rng.Double() < timeStep)) { + if (!is_equal_exact(GetPropulsion()->GetLinThrusterState().LengthSqr(), 0.0) && (s_timeAccum > 4 || 0.1 * Pi::rng.Double() < timeStep)) { s_timeAccum = 0.0; - const vector3d pos = GetOrient() * vector3d(0, 0 , 5); - const float speed = std::min(10.0*GetVelocity().Length()*std::max(1.0,fabs(GetPropulsion()->GetLinThrusterState().z)),100.0); + const vector3d pos = GetOrient() * vector3d(0, 0, 5); + const float speed = std::min(10.0 * GetVelocity().Length() * std::max(1.0, fabs(GetPropulsion()->GetLinThrusterState().z)), 100.0); SfxManager::AddThrustSmoke(this, speed, pos); } } @@ -132,9 +129,9 @@ void Missile::StaticUpdate(const float timeStep) void Missile::TimeStepUpdate(const float timeStep) { - const vector3d thrust=GetPropulsion()->GetActualLinThrust(); - AddRelForce( thrust ); - AddRelTorque( GetPropulsion()->GetActualAngThrust() ); + const vector3d thrust = GetPropulsion()->GetActualLinThrust(); + AddRelForce(thrust); + AddRelTorque(GetPropulsion()->GetActualAngThrust()); DynamicBody::TimeStepUpdate(timeStep); GetPropulsion()->UpdateFuel(timeStep); @@ -164,7 +161,7 @@ bool Missile::OnCollision(Object *o, Uint32 flags, double relVel) return true; } -bool Missile::OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) +bool Missile::OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) { if (!IsDead()) { Explode(); @@ -189,14 +186,14 @@ void Missile::Explode() // linear damage decay with distance (*i)->OnDamage(m_owner, kgDamage * (damageRadius - dist) / damageRadius, dummy); if ((*i)->IsType(Object::SHIP)) - LuaEvent::Queue("onShipHit", dynamic_cast(*i), m_owner); + LuaEvent::Queue("onShipHit", dynamic_cast(*i), m_owner); } } SfxManager::Add(this, TYPE_EXPLOSION); } -void Missile::NotifyRemoved(const Body* const removedBody) +void Missile::NotifyRemoved(const Body *const removedBody) { if (m_curAICmd) m_curAICmd->OnDeleted(removedBody); if (m_owner == removedBody) { @@ -221,14 +218,14 @@ void Missile::Render(Graphics::Renderer *renderer, const Camera *camera, const v { if (IsDead()) return; - GetPropulsion()->Render( renderer, camera, viewCoords, viewTransform ); + GetPropulsion()->Render(renderer, camera, viewCoords, viewTransform); RenderModel(renderer, camera, viewCoords, viewTransform); } void Missile::AIKamikaze(Body *target) { //AIClearInstructions(); - if (m_curAICmd!=0) + if (m_curAICmd != 0) delete m_curAICmd; m_curAICmd = new AICmdKamikaze(this, target); } diff --git a/src/Missile.h b/src/Missile.h index 1fae41f14..546a70c75 100644 --- a/src/Missile.h +++ b/src/Missile.h @@ -4,27 +4,27 @@ #ifndef _MISSILE_H #define _MISSILE_H -#include -#include "libs.h" #include "DynamicBody.h" #include "ShipAICmd.h" +#include "libs.h" +#include -class Missile: public DynamicBody { +class Missile : public DynamicBody { public: OBJDEF(Missile, DynamicBody, MISSILE); - Missile(const ShipType::Id &type, Body *owner, int power=-1); + Missile(const ShipType::Id &type, Body *owner, int power = -1); Missile() {} virtual ~Missile(); void StaticUpdate(const float timeStep) override; void TimeStepUpdate(const float timeStep) override; virtual bool OnCollision(Object *o, Uint32 flags, double relVel) override; - virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override; - virtual void NotifyRemoved(const Body* const removedBody) override; + virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) override; + virtual void NotifyRemoved(const Body *const removedBody) override; virtual void PostLoadFixup(Space *space) override; virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; void ECMAttack(int power_val); Body *GetOwner() const { return m_owner; } - bool IsArmed() const {return m_armed;} + bool IsArmed() const { return m_armed; } void Arm(); void Disarm(); void AIKamikaze(Body *target); @@ -32,6 +32,7 @@ public: protected: virtual void SaveToJson(Json &jsonObj, Space *space) override; virtual void LoadFromJson(const Json &jsonObj, Space *space) override; + private: void Explode(); AICommand *m_curAICmd; diff --git a/src/ModManager.cpp b/src/ModManager.cpp index 7ffdf986e..4224867a3 100644 --- a/src/ModManager.cpp +++ b/src/ModManager.cpp @@ -2,11 +2,12 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ModManager.h" -#include "FileSystem.h" #include "FileSourceZip.h" +#include "FileSystem.h" #include "utils.h" -void ModManager::Init() { +void ModManager::Init() +{ FileSystem::userFiles.MakeDirectory("mods"); for (FileSystem::FileEnumerator files(FileSystem::userFiles, "mods", 0); !files.Finished(); files.Next()) { diff --git a/src/ModelBody.cpp b/src/ModelBody.cpp index cf01e4ed3..dbf37f74a 100644 --- a/src/ModelBody.cpp +++ b/src/ModelBody.cpp @@ -1,26 +1,26 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "ModelBody.h" +#include "Camera.h" #include "Frame.h" #include "Game.h" +#include "GameSaveError.h" #include "ModelCache.h" #include "Pi.h" +#include "Planet.h" #include "Space.h" #include "WorldView.h" -#include "Camera.h" -#include "Planet.h" #include "collider/collider.h" #include "graphics/Renderer.h" -#include "scenegraph/SceneGraph.h" -#include "scenegraph/NodeVisitor.h" +#include "libs.h" #include "scenegraph/CollisionGeometry.h" -#include "GameSaveError.h" +#include "scenegraph/NodeVisitor.h" +#include "scenegraph/SceneGraph.h" class DynGeomFinder : public SceneGraph::NodeVisitor { public: - std::vector results; + std::vector results; virtual void ApplyCollisionGeometry(SceneGraph::CollisionGeometry &cg) { @@ -61,11 +61,11 @@ public: } }; -ModelBody::ModelBody() -: m_isStatic(false) -, m_colliding(true) -, m_geom(0) -, m_model(0) +ModelBody::ModelBody() : + m_isStatic(false), + m_colliding(true), + m_geom(0), + m_model(0) { } @@ -119,8 +119,7 @@ void ModelBody::SetStatic(bool isStatic) if (m_isStatic) { GetFrame()->RemoveGeom(m_geom); GetFrame()->AddStaticGeom(m_geom); - } - else { + } else { GetFrame()->RemoveStaticGeom(m_geom); GetFrame()->AddGeom(m_geom); } @@ -129,8 +128,10 @@ void ModelBody::SetStatic(bool isStatic) void ModelBody::SetColliding(bool colliding) { m_colliding = colliding; - if(colliding) m_geom->Enable(); - else m_geom->Disable(); + if (colliding) + m_geom->Enable(); + else + m_geom->Disable(); } void ModelBody::RebuildCollisionMesh() @@ -141,7 +142,7 @@ void ModelBody::RebuildCollisionMesh() } m_collMesh = m_model->GetCollisionMesh(); - double maxRadius= m_collMesh->GetAabb().GetRadius(); + double maxRadius = m_collMesh->GetAabb().GetRadius(); //static geom m_geom = new Geom(m_collMesh->GetGeomTree(), GetOrient(), GetPosition(), this); @@ -228,7 +229,7 @@ void ModelBody::AddGeomsToFrame(Frame *f) m_geom->SetGroup(group); - if(m_isStatic) { + if (m_isStatic) { f->AddStaticGeom(m_geom); } else { f->AddGeom(m_geom); @@ -242,7 +243,7 @@ void ModelBody::AddGeomsToFrame(Frame *f) void ModelBody::RemoveGeomsFromFrame(Frame *f) { - if(m_isStatic) { + if (m_isStatic) { GetFrame()->RemoveStaticGeom(m_geom); } else { GetFrame()->RemoveGeom(m_geom); @@ -292,10 +293,10 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came ambient = minAmbient; direct = 1.0; Body *astro = GetFrame()->GetBody(); - if ( ! (astro && astro->IsType(Object::PLANET)) ) + if (!(astro && astro->IsType(Object::PLANET))) return; - Planet *planet = static_cast(astro); + Planet *planet = static_cast(astro); // position relative to the rotating frame of the planet vector3d upDir = GetInterpPositionRelTo(planet->GetFrame()); @@ -310,7 +311,7 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came planet->GetSystemBody()->GetAtmosphereFlavor(&cl, &surfaceDensity); // approximate optical thickness fraction as fraction of density remaining relative to earths - double opticalThicknessFraction = density/EARTH_ATMOSPHERE_SURFACE_DENSITY; + double opticalThicknessFraction = density / EARTH_ATMOSPHERE_SURFACE_DENSITY; // tweak optical thickness curve - lower exponent ==> higher altitude before ambient level drops // Commenting this out, since it leads to a sharp transition at @@ -325,11 +326,11 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came double light_clamped = 0.0; const std::vector &lightSources = camera->GetLightSources(); - for(std::vector::const_iterator l = lightSources.begin(); - l != lightSources.end(); ++l) { + for (std::vector::const_iterator l = lightSources.begin(); + l != lightSources.end(); ++l) { double sunAngle; // calculate the extent the sun is towards zenith - if (l->GetBody()){ + if (l->GetBody()) { // relative to the rotating frame of the planet const vector3d lightDir = (l->GetBody()->GetInterpPositionRelTo(planet->GetFrame()).Normalized()); sunAngle = lightDir.Dot(upDir); @@ -338,20 +339,20 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came sunAngle = 1.0; } - const double critAngle = -sqrt(dist*dist-planetRadius*planetRadius)/dist; + const double critAngle = -sqrt(dist * dist - planetRadius * planetRadius) / dist; //0 to 1 as sunangle goes from critAngle to 1.0 - double sunAngle2 = (Clamp(sunAngle, critAngle, 1.0)-critAngle)/(1.0-critAngle); + double sunAngle2 = (Clamp(sunAngle, critAngle, 1.0) - critAngle) / (1.0 - critAngle); // angle at which light begins to fade on Earth const double surfaceStartAngle = 0.3; // angle at which sun set completes, which should be after sun has dipped below the horizon on Earth const double surfaceEndAngle = -0.18; - const double start = std::min((surfaceStartAngle*opticalThicknessFraction),1.0); - const double end = std::max((surfaceEndAngle*opticalThicknessFraction),-0.2); + const double start = std::min((surfaceStartAngle * opticalThicknessFraction), 1.0); + const double end = std::max((surfaceEndAngle * opticalThicknessFraction), -0.2); - sunAngle = (Clamp(sunAngle-critAngle, end, start)-end)/(start-end); + sunAngle = (Clamp(sunAngle - critAngle, end, start) - end) / (start - end); light += sunAngle; light_clamped += sunAngle2; @@ -361,17 +362,17 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came light /= lightSources.size(); // brightness depends on optical depth and intensity of light from all the stars - direct = 1.0 - Clamp((1.0 - light),0.0,1.0) * Clamp(opticalThicknessFraction,0.0,1.0); + direct = 1.0 - Clamp((1.0 - light), 0.0, 1.0) * Clamp(opticalThicknessFraction, 0.0, 1.0); // ambient light fraction // alter ratio between directly and ambiently lit portions towards ambiently lit as sun sets - const double fraction = ( 0.2 + 0.8 * (1.0-light_clamped) ) * Clamp(opticalThicknessFraction,0.0,1.0); + const double fraction = (0.2 + 0.8 * (1.0 - light_clamped)) * Clamp(opticalThicknessFraction, 0.0, 1.0); // fraction of light left over to be lit directly - direct = (1.0-fraction)*direct; + direct = (1.0 - fraction) * direct; // scale ambient by amount of light - ambient = fraction*(Clamp((light),0.0,1.0))*0.25; + ambient = fraction * (Clamp((light), 0.0, 1.0)) * 0.25; ambient = std::max(minAmbient, ambient); } @@ -379,14 +380,15 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came // setLighting: set renderer lights according to current position and sun // positions. Original lighting is passed back in oldLights, oldAmbient, and // should be reset after rendering with ModelBody::ResetLighting. -void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::vector &oldLights, Color &oldAmbient) { +void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::vector &oldLights, Color &oldAmbient) +{ std::vector newLights; double ambient, direct; CalcLighting(ambient, direct, camera); const std::vector &lightSources = camera->GetLightSources(); newLights.reserve(lightSources.size()); oldLights.reserve(lightSources.size()); - for(size_t i = 0; i < lightSources.size(); i++) { + for (size_t i = 0; i < lightSources.size(); i++) { Graphics::Light light(lightSources[i].GetLight()); oldLights.push_back(light); @@ -395,12 +397,12 @@ void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::ve Color c = light.GetDiffuse(); Color cs = light.GetSpecular(); - c.r*=float(intensity); - c.g*=float(intensity); - c.b*=float(intensity); - cs.r*=float(intensity); - cs.g*=float(intensity); - cs.b*=float(intensity); + c.r *= float(intensity); + c.g *= float(intensity); + c.b *= float(intensity); + cs.r *= float(intensity); + cs.g *= float(intensity); + cs.b *= float(intensity); light.SetDiffuse(c); light.SetSpecular(cs); @@ -413,11 +415,12 @@ void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::ve } oldAmbient = r->GetAmbientColor(); - r->SetAmbientColor(Color(ambient*255, ambient * 255, ambient * 255)); + r->SetAmbientColor(Color(ambient * 255, ambient * 255, ambient * 255)); r->SetLights(newLights.size(), &newLights[0]); } -void ModelBody::ResetLighting(Graphics::Renderer *r, const std::vector &oldLights, const Color &oldAmbient) { +void ModelBody::ResetLighting(Graphics::Renderer *r, const std::vector &oldLights, const Color &oldAmbient) +{ // restore old lights if (!oldLights.empty()) r->SetLights(oldLights.size(), &oldLights[0]); @@ -437,7 +440,8 @@ void ModelBody::RenderModel(Graphics::Renderer *r, const Camera *camera, const v //double to float matrix matrix4x4f trans; - for (int i=0; i<12; i++) trans[i] = float(t[i]); + for (int i = 0; i < 12; i++) + trans[i] = float(t[i]); trans[12] = viewCoords.x; trans[13] = viewCoords.y; trans[14] = viewCoords.z; diff --git a/src/ModelBody.h b/src/ModelBody.h index 315a74a91..078bd6fb3 100644 --- a/src/ModelBody.h +++ b/src/ModelBody.h @@ -4,17 +4,23 @@ #ifndef _MODELBODY_H #define _MODELBODY_H -#include "libs.h" #include "Body.h" #include "CollMesh.h" #include "Shields.h" +#include "libs.h" class Geom; class Camera; -namespace Graphics { class Renderer; class Light; } -namespace SceneGraph { class Model; class Animation; } +namespace Graphics { + class Renderer; + class Light; +} // namespace Graphics +namespace SceneGraph { + class Model; + class Animation; +} // namespace SceneGraph -class ModelBody: public Body { +class ModelBody : public Body { public: OBJDEF(ModelBody, Body, MODELBODY); ModelBody(); @@ -31,11 +37,11 @@ public: const Aabb &GetAabb() const { return m_collMesh->GetAabb(); } SceneGraph::Model *GetModel() const { return m_model; } CollMesh *GetCollMesh() { return m_collMesh.Get(); } - Geom* GetGeom() const { return m_geom; } + Geom *GetGeom() const { return m_geom; } void SetModel(const char *modelName); - void RenderModel(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform, const bool setLighting=true); + void RenderModel(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform, const bool setLighting = true); virtual void TimeStepUpdate(const float timeStep) override; @@ -46,14 +52,14 @@ protected: void SetLighting(Graphics::Renderer *r, const Camera *camera, std::vector &oldLights, Color &oldAmbient); void ResetLighting(Graphics::Renderer *r, const std::vector &oldLights, const Color &oldAmbient); - Shields* GetShields() const { return m_shields.get(); } + Shields *GetShields() const { return m_shields.get(); } private: void RebuildCollisionMesh(); void DeleteGeoms(); - void AddGeomsToFrame(Frame*); - void RemoveGeomsFromFrame(Frame*); - void MoveGeoms(const matrix4x4d&, const vector3d&); + void AddGeomsToFrame(Frame *); + void RemoveGeomsFromFrame(Frame *); + void MoveGeoms(const matrix4x4d &, const vector3d &); void CalcLighting(double &ambient, double &direct, const Camera *camera); @@ -63,7 +69,7 @@ private: Geom *m_geom; //static geom std::string m_modelName; SceneGraph::Model *m_model; - std::vector m_dynGeoms; + std::vector m_dynGeoms; SceneGraph::Animation *m_idleAnimation; std::unique_ptr m_shields; }; diff --git a/src/ModelCache.cpp b/src/ModelCache.cpp index 80efec738..6cdd372c2 100644 --- a/src/ModelCache.cpp +++ b/src/ModelCache.cpp @@ -2,13 +2,12 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ModelCache.h" -#include "scenegraph/SceneGraph.h" #include "Shields.h" +#include "scenegraph/SceneGraph.h" -ModelCache::ModelCache(Graphics::Renderer *r) -: m_renderer(r) +ModelCache::ModelCache(Graphics::Renderer *r) : + m_renderer(r) { - } ModelCache::~ModelCache() @@ -36,7 +35,7 @@ SceneGraph::Model *ModelCache::FindModel(const std::string &name) void ModelCache::Flush() { - for(ModelMap::iterator it = m_models.begin(); it != m_models.end(); ++it) { + for (ModelMap::iterator it = m_models.begin(); it != m_models.end(); ++it) { delete it->second; } m_models.clear(); diff --git a/src/ModelCache.h b/src/ModelCache.h index a868d4440..5da03ed2b 100644 --- a/src/ModelCache.h +++ b/src/ModelCache.h @@ -10,21 +10,26 @@ #include "libs.h" #include -namespace Graphics { class Renderer; } -namespace SceneGraph { class Model; } +namespace Graphics { + class Renderer; +} +namespace SceneGraph { + class Model; +} class ModelCache { public: struct ModelNotFoundException : public std::runtime_error { - ModelNotFoundException() : std::runtime_error("Could not find model") { } + ModelNotFoundException() : + std::runtime_error("Could not find model") {} }; - ModelCache(Graphics::Renderer*); + ModelCache(Graphics::Renderer *); ~ModelCache(); - SceneGraph::Model *FindModel(const std::string&); + SceneGraph::Model *FindModel(const std::string &); void Flush(); private: - typedef std::map ModelMap; + typedef std::map ModelMap; ModelMap m_models; Graphics::Renderer *m_renderer; }; diff --git a/src/ModelViewer.cpp b/src/ModelViewer.cpp index 46c03c25d..92b4af084 100644 --- a/src/ModelViewer.cpp +++ b/src/ModelViewer.cpp @@ -3,46 +3,47 @@ #include "ModelViewer.h" #include "FileSystem.h" -#include "graphics/opengl/RendererGL.h" -#include "graphics/Graphics.h" -#include "graphics/Light.h" -#include "graphics/TextureBuilder.h" -#include "graphics/Drawables.h" -#include "graphics/VertexArray.h" -#include "scenegraph/DumpVisitor.h" -#include "scenegraph/FindNodeVisitor.h" -#include "scenegraph/BinaryConverter.h" -#include "scenegraph/ModelSkin.h" +#include "GameSaveError.h" +#include "ModManager.h" #include "OS.h" #include "Pi.h" #include "StringF.h" -#include "ModManager.h" -#include "GameSaveError.h" +#include "graphics/Drawables.h" +#include "graphics/Graphics.h" +#include "graphics/Light.h" +#include "graphics/TextureBuilder.h" +#include "graphics/VertexArray.h" +#include "graphics/opengl/RendererGL.h" +#include "scenegraph/BinaryConverter.h" +#include "scenegraph/DumpVisitor.h" +#include "scenegraph/FindNodeVisitor.h" +#include "scenegraph/ModelSkin.h" #include //default options -ModelViewer::Options::Options() -: attachGuns(false) -, showTags(false) -, showDockingLocators(false) -, showCollMesh(false) -, showAabb(false) -, showShields(false) -, showGrid(false) -, showLandingPad(false) -, showUI(true) -, wireframe(false) -, mouselookEnabled(false) -, gridInterval(10.f) -, lightPreset(0) -, orthoView(false) +ModelViewer::Options::Options() : + attachGuns(false), + showTags(false), + showDockingLocators(false), + showCollMesh(false), + showAabb(false), + showShields(false), + showGrid(false), + showLandingPad(false), + showUI(true), + wireframe(false), + mouselookEnabled(false), + gridInterval(10.f), + lightPreset(0), + orthoView(false) { } //some utility functions namespace { //azimuth/elevation in degrees to a dir vector - vector3f az_el_to_dir(float yaw, float pitch) { + vector3f az_el_to_dir(float yaw, float pitch) + { //0,0 points to "right" (1,0,0) vector3f v; v.x = cos(DEG2RAD(yaw)) * cos(DEG2RAD(pitch)); @@ -52,31 +53,33 @@ namespace { } //extract color from RGB sliders - Color get_slider_color(UI::Slider *r, UI::Slider *g, UI::Slider *b) { + Color get_slider_color(UI::Slider *r, UI::Slider *g, UI::Slider *b) + { return Color(r->GetValue() * 255.f, g->GetValue() * 255.f, b->GetValue() * 255.f); } - float get_thrust(const UI::Slider *s) { + float get_thrust(const UI::Slider *s) + { return 1.f - (2.f * s->GetValue()); } //add a horizontal button/label pair to a box - void add_pair(UI::Context *c, UI::Box *box, UI::Widget *widget, const std::string &label) { - box->PackEnd(c->HBox(5)->PackEnd(UI::WidgetSet( widget, c->Label(label) ))); + void add_pair(UI::Context *c, UI::Box *box, UI::Widget *widget, const std::string &label) + { + box->PackEnd(c->HBox(5)->PackEnd(UI::WidgetSet(widget, c->Label(label)))); } void collect_decals(std::vector &list) { const std::string basepath("textures/decals"); FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; - for (FileSystem::FileEnumerator files(fileSource, basepath); !files.Finished(); files.Next()) - { + for (FileSystem::FileEnumerator files(fileSource, basepath); !files.Finished(); files.Next()) { const FileSystem::FileInfo &info = files.Current(); const std::string &fpath = info.GetPath(); //check it's the expected type if (info.IsFile() && ends_with_ci(fpath, ".dds")) { - list.push_back(info.GetName().substr(0, info.GetName().size()-4)); + list.push_back(info.GetName().substr(0, info.GetName().size() - 4)); } } } @@ -85,23 +88,25 @@ namespace { { return base_distance * powf(2.0f, zoom); } -} +} // namespace -ModelViewer::ModelViewer(Graphics::Renderer *r, LuaManager *lm) -: m_done(false) -, m_screenshotQueued(false) -, m_shieldIsHit(false) -, m_settingColourSliders(false) -, m_shieldHitPan(-1.48f) -, m_frameTime(0.0) -, m_renderer(r) -, m_decalTexture(0) -, m_rotX(0), m_rotY(0), m_zoom(0) -, m_baseDistance(100.0f) -, m_rng(time(0)) -, m_currentAnimation(0) -, m_model(0) -, m_modelName("") +ModelViewer::ModelViewer(Graphics::Renderer *r, LuaManager *lm) : + m_done(false), + m_screenshotQueued(false), + m_shieldIsHit(false), + m_settingColourSliders(false), + m_shieldHitPan(-1.48f), + m_frameTime(0.0), + m_renderer(r), + m_decalTexture(0), + m_rotX(0), + m_rotY(0), + m_zoom(0), + m_baseDistance(100.0f), + m_rng(time(0)), + m_currentAnimation(0), + m_model(0), + m_modelName("") { OS::RedirectStdio(); m_ui.Reset(new UI::Context(lm, r, Graphics::GetScreenWidth(), Graphics::GetScreenHeight())); @@ -111,7 +116,7 @@ ModelViewer::ModelViewer(Graphics::Renderer *r, LuaManager *lm) m_log->SetFont(UI::Widget::FONT_SMALLEST); m_logScroller.Reset(m_ui->Scroller()); - m_logScroller->SetInnerWidget(m_ui->ColorBackground(Color(0x0,0x0,0x0,0x40))->SetInnerWidget(m_log)); + m_logScroller->SetInnerWidget(m_ui->ColorBackground(Color(0x0, 0x0, 0x0, 0x40))->SetInnerWidget(m_log)); std::fill(m_mouseButton, m_mouseButton + COUNTOF(m_mouseButton), false); std::fill(m_mouseMotion, m_mouseMotion + 2, 0); @@ -231,17 +236,14 @@ bool ModelViewer::OnToggleGrid(UI::Widget *) if (!m_options.showGrid) { m_options.showGrid = true; m_options.gridInterval = 1.0f; - } - else { - m_options.gridInterval = powf(10, ceilf(log10f(m_options.gridInterval))+1); + } else { + m_options.gridInterval = powf(10, ceilf(log10f(m_options.gridInterval)) + 1); if (m_options.gridInterval >= 10000.0f) { m_options.showGrid = false; m_options.gridInterval = 0.0f; } } - AddLog(m_options.showGrid - ? stringf("Grid: %0{d}", int(m_options.gridInterval)) - : "Grid: off"); + AddLog(m_options.showGrid ? stringf("Grid: %0{d}", int(m_options.gridInterval)) : "Grid: off"); return m_options.showGrid; } @@ -276,7 +278,7 @@ bool ModelViewer::OnToggleGuns(UI::CheckBox *w) return true; } -bool ModelViewer::OnRandomColor(UI::Widget*) +bool ModelViewer::OnRandomColor(UI::Widget *) { if (!m_model || !m_model->SupportsPatterns()) return false; @@ -287,11 +289,11 @@ bool ModelViewer::OnRandomColor(UI::Widget*) // We need this flag setting so that we don't override what we're changing in OnModelColorsChanged m_settingColourSliders = true; const std::vector &colors = skin.GetColors(); - for(unsigned int i=0; i<3; i++) { - for(unsigned int j=0; j<3; j++) { + for (unsigned int i = 0; i < 3; i++) { + for (unsigned int j = 0; j < 3; j++) { // use ToColor4f to get the colours in 0..1 range required - if( colorSliders[(i*3)+j] ) - colorSliders[(i*3)+j]->SetValue(colors[i].ToColor4f()[j]); + if (colorSliders[(i * 3) + j]) + colorSliders[(i * 3) + j]->SetValue(colors[i].ToColor4f()[j]); } } m_settingColourSliders = false; @@ -310,7 +312,7 @@ void ModelViewer::UpdateShield() } } -bool ModelViewer::OnHitIt(UI::Widget*) +bool ModelViewer::OnHitIt(UI::Widget *) { HitImpl(); return true; @@ -318,20 +320,20 @@ bool ModelViewer::OnHitIt(UI::Widget*) void ModelViewer::HitImpl() { - if(m_model) { + if (m_model) { assert(m_shields.get()); // pick a point on the shield to serve as the point of impact. - SceneGraph::StaticGeometry* sg = m_shields->GetFirstShieldMesh(); - if(sg) { + SceneGraph::StaticGeometry *sg = m_shields->GetFirstShieldMesh(); + if (sg) { SceneGraph::StaticGeometry::Mesh &mesh = sg->GetMeshAt(0); // Please don't do this in game, no speed guarantee const Uint32 posOffs = mesh.vertexBuffer->GetDesc().GetOffset(Graphics::ATTRIB_POSITION); - const Uint32 stride = mesh.vertexBuffer->GetDesc().stride; + const Uint32 stride = mesh.vertexBuffer->GetDesc().stride; const Uint32 vtxIdx = m_rng.Int32() % mesh.vertexBuffer->GetSize(); const Uint8 *vtxPtr = mesh.vertexBuffer->Map(Graphics::BUFFER_MAP_READ); - const vector3f pos = *reinterpret_cast(vtxPtr + vtxIdx * stride + posOffs); + const vector3f pos = *reinterpret_cast(vtxPtr + vtxIdx * stride + posOffs); mesh.vertexBuffer->Unmap(); m_shields->AddHit(vector3d(pos)); } @@ -342,7 +344,7 @@ void ModelViewer::HitImpl() void ModelViewer::AddLog(const std::string &line) { - m_log->AppendText(line+"\n"); + m_log->AppendText(line + "\n"); m_logScroller->SetScrollPosition(1.0f); Output("%s\n", line.c_str()); } @@ -359,33 +361,39 @@ void ModelViewer::ChangeCameraPreset(SDL_Keycode key, SDL_Keymod mod) const bool invert = mod & KMOD_CTRL; - switch (key) - { - case SDLK_KP_7: case SDLK_u: + switch (key) { + case SDLK_KP_7: + case SDLK_u: m_rotX = invert ? -90.f : 90.f; m_rotY = 0.f; AddLog(invert ? "Bottom view" : "Top view"); break; - case SDLK_KP_3: case SDLK_PERIOD: + case SDLK_KP_3: + case SDLK_PERIOD: m_rotX = 0.f; m_rotY = invert ? -90.f : 90.f; AddLog(invert ? "Right view" : "Left view"); break; - case SDLK_KP_1: case SDLK_m: + case SDLK_KP_1: + case SDLK_m: m_rotX = 0.f; m_rotY = invert ? 0.f : 180.f; AddLog(invert ? "Rear view" : "Front view"); break; - case SDLK_KP_4: case SDLK_j: + case SDLK_KP_4: + case SDLK_j: m_rotY += 15.f; break; - case SDLK_KP_6: case SDLK_l: + case SDLK_KP_6: + case SDLK_l: m_rotY -= 15.f; break; - case SDLK_KP_2: case SDLK_COMMA: + case SDLK_KP_2: + case SDLK_COMMA: m_rotX += 15.f; break; - case SDLK_KP_8: case SDLK_i: + case SDLK_KP_8: + case SDLK_i: m_rotX -= 15.f; break; default: @@ -415,7 +423,8 @@ void ModelViewer::ClearLog() void ModelViewer::ClearModel() { - delete m_model; m_model = 0; + delete m_model; + m_model = 0; m_gunModel.reset(); m_scaleModel.reset(); @@ -446,8 +455,7 @@ void ModelViewer::DrawBackground() m_renderer->SetOrthographicProjection(0.f, 1.f, 0.f, 1.f, -1.f, 1.f); m_renderer->SetTransform(matrix4x4f::Identity()); - if(!m_bgBuffer.Valid()) - { + if (!m_bgBuffer.Valid()) { const Color top = Color::BLACK; const Color bottom = Color(77, 77, 77); Graphics::VertexArray bgArr(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, 6); @@ -461,15 +469,15 @@ void ModelViewer::DrawBackground() bgArr.Add(vector3f(0.f, 1.f, 0.f), top); Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; vbd.numVertices = 6; vbd.usage = Graphics::BUFFER_USAGE_STATIC; // VertexBuffer - m_bgBuffer.Reset( m_renderer->CreateVertexBuffer(vbd) ); + m_bgBuffer.Reset(m_renderer->CreateVertexBuffer(vbd)); m_bgBuffer->Populate(bgArr); } @@ -483,26 +491,26 @@ void ModelViewer::DrawGrid(const matrix4x4f &trans, float radius) const float dist = zoom_distance(m_baseDistance, m_zoom); - const float max = std::min(powf(10, ceilf(log10f(dist))), ceilf(radius/m_options.gridInterval)*m_options.gridInterval); + const float max = std::min(powf(10, ceilf(log10f(dist))), ceilf(radius / m_options.gridInterval) * m_options.gridInterval); static std::vector points; points.clear(); for (float x = -max; x <= max; x += m_options.gridInterval) { - points.push_back(vector3f(x,0,-max)); - points.push_back(vector3f(x,0,max)); - points.push_back(vector3f(0,x,-max)); - points.push_back(vector3f(0,x,max)); + points.push_back(vector3f(x, 0, -max)); + points.push_back(vector3f(x, 0, max)); + points.push_back(vector3f(0, x, -max)); + points.push_back(vector3f(0, x, max)); - points.push_back(vector3f(x,-max,0)); - points.push_back(vector3f(x,max,0)); - points.push_back(vector3f(0,-max,x)); - points.push_back(vector3f(0,max,x)); + points.push_back(vector3f(x, -max, 0)); + points.push_back(vector3f(x, max, 0)); + points.push_back(vector3f(0, -max, x)); + points.push_back(vector3f(0, max, x)); - points.push_back(vector3f(-max,x,0)); - points.push_back(vector3f(max,x,0)); - points.push_back(vector3f(-max,0,x)); - points.push_back(vector3f(max,0,x)); + points.push_back(vector3f(-max, x, 0)); + points.push_back(vector3f(max, x, 0)); + points.push_back(vector3f(-max, 0, x)); + points.push_back(vector3f(max, 0, x)); } m_renderer->SetTransform(trans); @@ -521,12 +529,11 @@ void ModelViewer::DrawModel(const matrix4x4f &mv) m_model->UpdateAnimations(); m_model->SetDebugFlags( - (m_options.showAabb ? SceneGraph::Model::DEBUG_BBOX : 0x0) | - (m_options.showCollMesh ? SceneGraph::Model::DEBUG_COLLMESH : 0x0) | - (m_options.showTags ? SceneGraph::Model::DEBUG_TAGS : 0x0) | - (m_options.showDockingLocators ? SceneGraph::Model::DEBUG_DOCKING : 0x0) | - (m_options.wireframe ? SceneGraph::Model::DEBUG_WIREFRAME : 0x0) - ); + (m_options.showAabb ? SceneGraph::Model::DEBUG_BBOX : 0x0) | + (m_options.showCollMesh ? SceneGraph::Model::DEBUG_COLLMESH : 0x0) | + (m_options.showTags ? SceneGraph::Model::DEBUG_TAGS : 0x0) | + (m_options.showDockingLocators ? SceneGraph::Model::DEBUG_DOCKING : 0x0) | + (m_options.wireframe ? SceneGraph::Model::DEBUG_WIREFRAME : 0x0)); m_model->Render(mv); m_navLights->Render(m_renderer); @@ -535,8 +542,7 @@ void ModelViewer::DrawModel(const matrix4x4f &mv) void ModelViewer::MainLoop() { double lastTime = SDL_GetTicks() * 0.001; - while (!m_done) - { + while (!m_done) { const double ticks = SDL_GetTicks() * 0.001; m_frameTime = (ticks - lastTime); lastTime = ticks; @@ -567,25 +573,25 @@ void ModelViewer::MainLoop() // setup rendering if (!m_options.orthoView) { - m_renderer->SetPerspectiveProjection(85, Graphics::GetScreenWidth()/float(Graphics::GetScreenHeight()), 0.1f, 100000.f); + m_renderer->SetPerspectiveProjection(85, Graphics::GetScreenWidth() / float(Graphics::GetScreenHeight()), 0.1f, 100000.f); } else { - /* TODO: Zoom in ortho mode seems don't work as in perspective mode, + /* TODO: Zoom in ortho mode seems don't work as in perspective mode, / I change "screen dimensions" to avoid the problem. / However the zoom needs more care */ - if (m_zoom<=0.0) m_zoom = 0.01; - float screenW = Graphics::GetScreenWidth()*m_zoom/10; - float screenH = Graphics::GetScreenHeight()*m_zoom/10; - matrix4x4f orthoMat = matrix4x4f::OrthoFrustum(-screenW,screenW, -screenH, screenH, 0.1f, 100000.0f); - orthoMat.ClearToRotOnly(); - m_renderer->SetProjection(orthoMat); + if (m_zoom <= 0.0) m_zoom = 0.01; + float screenW = Graphics::GetScreenWidth() * m_zoom / 10; + float screenH = Graphics::GetScreenHeight() * m_zoom / 10; + matrix4x4f orthoMat = matrix4x4f::OrthoFrustum(-screenW, screenW, -screenH, screenH, 0.1f, 100000.0f); + orthoMat.ClearToRotOnly(); + m_renderer->SetProjection(orthoMat); } m_renderer->SetTransform(matrix4x4f::Identity()); // calc camera info matrix4x4f mv; - float zd=0; + float zd = 0; if (m_options.mouselookEnabled) { mv = m_viewRot.Transpose() * matrix4x4f::Translation(-m_viewPos); } else { @@ -593,8 +599,10 @@ void ModelViewer::MainLoop() matrix4x4f rot = matrix4x4f::Identity(); rot.RotateX(DEG2RAD(-m_rotX)); rot.RotateY(DEG2RAD(-m_rotY)); - if (m_options.orthoView) zd = -m_baseDistance; - else zd = -zoom_distance(m_baseDistance, m_zoom); + if (m_options.orthoView) + zd = -m_baseDistance; + else + zd = -zoom_distance(m_baseDistance, m_zoom); mv = matrix4x4f::Translation(0.0f, 0.0f, zd) * rot; } @@ -625,7 +633,7 @@ void ModelViewer::MainLoop() m_renderer->SwapBuffers(); // if we've requested a different model then switch too it - if(!m_requestedModelName.empty()) { + if (!m_requestedModelName.empty()) { SetModel(m_requestedModelName); m_requestedModelName.clear(); ResetCamera(); @@ -639,8 +647,8 @@ void ModelViewer::OnAnimChanged(unsigned int, const std::string &name) // Find the animation matching the name (could also store the anims in a map // when the animationSelector is filled) if (!name.empty()) { - const std::vector &anims = m_model->GetAnimations(); - for (std::vector::const_iterator anim = anims.begin(); anim != anims.end(); ++anim) { + const std::vector &anims = m_model->GetAnimations(); + for (std::vector::const_iterator anim = anims.begin(); anim != anims.end(); ++anim) { if ((*anim)->GetName() == name) m_currentAnimation = (*anim); } @@ -670,7 +678,7 @@ void ModelViewer::OnDecalChanged(unsigned int index, const std::string &texname) m_model->SetDecalTexture(m_decalTexture, 3); } -void ModelViewer::OnLightPresetChanged(unsigned int index, const std::string&) +void ModelViewer::OnLightPresetChanged(unsigned int index, const std::string &) { m_options.lightPreset = std::min(index, 3); } @@ -735,8 +743,7 @@ void ModelViewer::PollEvents() if (m_options.showUI && m_ui->DispatchSDLEvent(event)) continue; - switch (event.type) - { + switch (event.type) { case SDL_QUIT: m_done = true; break; @@ -755,8 +762,7 @@ void ModelViewer::PollEvents() if (event.wheel.y < 0) m_mouseWheelDown = true; break; case SDL_KEYDOWN: - switch (event.key.keysym.sym) - { + switch (event.key.keysym.sym) { case SDLK_ESCAPE: if (m_model) { ClearModel(); @@ -782,9 +788,9 @@ void ModelViewer::PollEvents() case SDLK_g: OnToggleGrid(0); break; - case SDLK_o: - m_options.orthoView = !m_options.orthoView; - break; + case SDLK_o: + m_options.orthoView = !m_options.orthoView; + break; case SDLK_z: m_options.wireframe = !m_options.wireframe; break; @@ -798,13 +804,20 @@ void ModelViewer::PollEvents() if (event.key.keysym.mod & KMOD_SHIFT) m_renderer->ReloadShaders(); break; - case SDLK_KP_1: case SDLK_m: - case SDLK_KP_2: case SDLK_COMMA: - case SDLK_KP_3: case SDLK_PERIOD: - case SDLK_KP_4: case SDLK_j: - case SDLK_KP_6: case SDLK_l: - case SDLK_KP_7: case SDLK_u: - case SDLK_KP_8: case SDLK_i: + case SDLK_KP_1: + case SDLK_m: + case SDLK_KP_2: + case SDLK_COMMA: + case SDLK_KP_3: + case SDLK_PERIOD: + case SDLK_KP_4: + case SDLK_j: + case SDLK_KP_6: + case SDLK_l: + case SDLK_KP_7: + case SDLK_u: + case SDLK_KP_8: + case SDLK_i: ChangeCameraPreset(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod)); break; case SDLK_p: //landing pad test @@ -812,7 +825,7 @@ void ModelViewer::PollEvents() AddLog(stringf("Scale/landing pad test %0", m_options.showLandingPad ? "on" : "off")); break; case SDLK_r: //random colors, eastereggish - for(unsigned int i=0; i<3*3; i++) { + for (unsigned int i = 0; i < 3 * 3; i++) { if (colorSliders[i]) colorSliders[i]->SetValue(m_rng.Double()); } @@ -835,15 +848,14 @@ static void collect_models(std::vector &list) { const std::string basepath("models"); FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; - for (FileSystem::FileEnumerator files(fileSource, basepath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) - { + for (FileSystem::FileEnumerator files(fileSource, basepath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { const FileSystem::FileInfo &info = files.Current(); const std::string &fpath = info.GetPath(); //check it's the expected type if (info.IsFile()) { if (ends_with_ci(fpath, ".model")) - list.push_back(info.GetName().substr(0, info.GetName().size()-6)); + list.push_back(info.GetName().substr(0, info.GetName().size() - 6)); else if (ends_with_ci(fpath, ".sgm")) list.push_back(info.GetName()); } @@ -857,7 +869,7 @@ void ModelViewer::PopulateFilePicker() std::vector models; collect_models(models); - for (const auto& it : models) + for (const auto &it : models) m_fileList->AddOption(it); } @@ -872,7 +884,7 @@ void ModelViewer::ResetThrusters() { if (thrustSliders[0] == 0) return; - for (unsigned int i=0; i<6; i++) { + for (unsigned int i = 0; i < 6; i++) { thrustSliders[i]->SetValue(0.5f); } } @@ -911,9 +923,9 @@ void ModelViewer::SaveModelToBinary() SceneGraph::BinaryConverter bc(m_renderer); bc.Save(m_modelName, model.get()); AddLog("Saved binary model file"); - } catch (const CouldNotOpenFileException&) { + } catch (const CouldNotOpenFileException &) { AddLog("Could not open file or directory for writing"); - } catch (const CouldNotWriteToFileException&) { + } catch (const CouldNotWriteToFileException &) { AddLog("Error while writing to file"); } } @@ -930,7 +942,7 @@ void ModelViewer::SetModel(const std::string &filename) try { if (ends_with_ci(filename, ".sgm")) { //binary loader expects extension-less name. Might want to change this. - m_modelName = filename.substr(0, filename.size()-4); + m_modelName = filename.substr(0, filename.size() - 4); SceneGraph::BinaryConverter bc(m_renderer); m_model = bc.Load(m_modelName); } else { @@ -940,8 +952,7 @@ void ModelViewer::SetModel(const std::string &filename) //dump warnings for (std::vector::const_iterator it = loader.GetLogMessages().begin(); - it != loader.GetLogMessages().end(); ++it) - { + it != loader.GetLogMessages().end(); ++it) { AddLog(*it); Output("%s\n", (*it).c_str()); } @@ -994,21 +1005,16 @@ void ModelViewer::SetupFilePicker() PopulateFilePicker(); UI::Widget *fp = - c->Grid(UI::CellSpec(1,3,1), UI::CellSpec(1,3,1)) - ->SetCell(1,1, - c->VBox(10) - ->PackEnd(c->Label("Select a model")) - ->PackEnd(c->Expand(UI::Expand::BOTH)->SetInnerWidget(c->Scroller()->SetInnerWidget(m_fileList))) - ->PackEnd(c->Grid(2,1)->SetRow(0, UI::WidgetSet( - c->Align(UI::Align::LEFT)->SetInnerWidget(loadButton), - c->Align(UI::Align::RIGHT)->SetInnerWidget(quitButton) - ))) - ); + c->Grid(UI::CellSpec(1, 3, 1), UI::CellSpec(1, 3, 1)) + ->SetCell(1, 1, + c->VBox(10) + ->PackEnd(c->Label("Select a model")) + ->PackEnd(c->Expand(UI::Expand::BOTH)->SetInnerWidget(c->Scroller()->SetInnerWidget(m_fileList))) + ->PackEnd(c->Grid(2, 1)->SetRow(0, UI::WidgetSet(c->Align(UI::Align::LEFT)->SetInnerWidget(loadButton), c->Align(UI::Align::RIGHT)->SetInnerWidget(quitButton))))); m_logScroller->Layout(); //issues without this - c->GetTopLayer()->SetInnerWidget(c->Grid(2,1) - ->SetRow(0, UI::WidgetSet(fp, m_logScroller.Get())) - ); + c->GetTopLayer()->SetInnerWidget(c->Grid(2, 1) + ->SetRow(0, UI::WidgetSet(fp, m_logScroller.Get()))); c->Layout(); m_logScroller->SetScrollPosition(1.f); @@ -1022,9 +1028,9 @@ void ModelViewer::SetupUI() UI::Context *c = m_ui.Get(); c->SetFont(UI::Widget::FONT_XSMALL); - for (unsigned int i=0; i<9; i++) + for (unsigned int i = 0; i < 9; i++) colorSliders[i] = 0; - for (unsigned int i=0; i<6; i++) + for (unsigned int i = 0; i < 6; i++) thrustSliders[i] = 0; animSlider = 0; @@ -1043,21 +1049,19 @@ void ModelViewer::SetupUI() UI::CheckBox *showShieldsCheck = nullptr; UI::CheckBox *gunsCheck = nullptr; - UI::VBox* outerBox = c->VBox(); + UI::VBox *outerBox = c->VBox(); - UI::VBox* mainBox = c->VBox(5); - UI::VBox* bottomBox = c->VBox(5); + UI::VBox *mainBox = c->VBox(5); + UI::VBox *bottomBox = c->VBox(5); - UI::HBox* sliderBox = c->HBox(); + UI::HBox *sliderBox = c->HBox(); bottomBox->PackEnd(sliderBox); outerBox->PackEnd(UI::WidgetSet( - c->Expand()->SetInnerWidget(c->Grid(UI::CellSpec(0.30f,0.8f,0.35f),1) - ->SetColumn(0, mainBox) - ->SetColumn(2, m_logScroller.Get()) - ), - bottomBox - )); + c->Expand()->SetInnerWidget(c->Grid(UI::CellSpec(0.30f, 0.8f, 0.35f), 1) + ->SetColumn(0, mainBox) + ->SetColumn(2, m_logScroller.Get())), + bottomBox)); c->GetTopLayer()->SetInnerWidget(c->Margin(spacing)->SetInnerWidget(outerBox)); @@ -1075,43 +1079,25 @@ void ModelViewer::SetupUI() add_pair(c, mainBox, toggleGridButton = c->SmallButton(), "Grid mode"); add_pair(c, mainBox, collMeshCheck = c->CheckBox(), "Collision mesh"); // not everything has a shield - if( m_shields.get() && m_shields->GetFirstShieldMesh() ) { + if (m_shields.get() && m_shields->GetFirstShieldMesh()) { add_pair(c, mainBox, showShieldsCheck = c->CheckBox(), "Show Shields"); add_pair(c, mainBox, hitItButton = c->SmallButton(), "Hit it!"); hitItButton->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnHitIt), hitItButton)); } - add_pair(c, mainBox, randomColours = c->SmallButton(), "Random Colours"); randomColours->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnRandomColor), randomColours)); - //pattern selector if (m_model->SupportsPatterns()) { mainBox->PackEnd(c->Label("Pattern:")); mainBox->PackEnd(patternSelector = c->DropDown()->AddOption("Default")); sliderBox->PackEnd( - c->Grid(3,4) - ->SetColumn(0, UI::WidgetSet( - c->Label("Color 1"), - c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[0] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[1] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[2] = c->HSlider()) - )) - ->SetColumn(1, UI::WidgetSet( - c->Label("Color 2"), - c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[3] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[4] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[5] = c->HSlider()) - )) - ->SetColumn(2, UI::WidgetSet( - c->Label("Color 3"), - c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[6] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[7] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[8] = c->HSlider()) - )) - ); + c->Grid(3, 4) + ->SetColumn(0, UI::WidgetSet(c->Label("Color 1"), c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[0] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[1] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[2] = c->HSlider()))) + ->SetColumn(1, UI::WidgetSet(c->Label("Color 2"), c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[3] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[4] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[5] = c->HSlider()))) + ->SetColumn(2, UI::WidgetSet(c->Label("Color 3"), c->HBox(spacing)->PackEnd(c->Label("R"))->PackEnd(colorSliders[6] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("G"))->PackEnd(colorSliders[7] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("B"))->PackEnd(colorSliders[8] = c->HSlider())))); //connect slider signals, set initial values (RGB) const float values[] = { @@ -1119,7 +1105,7 @@ void ModelViewer::SetupUI() 0.f, 1.f, 0.f, 0.f, 0.f, 1.f }; - for(unsigned int i=0; i<3*3; i++) { + for (unsigned int i = 0; i < 3 * 3; i++) { colorSliders[i]->SetValue(values[i]); colorSliders[i]->onValueChanged.connect(sigc::mem_fun(*this, &ModelViewer::OnModelColorsChanged)); } @@ -1153,10 +1139,10 @@ void ModelViewer::SetupUI() mainBox->PackEnd(c->Label("Lights:")); mainBox->PackEnd( lightSelector = c->DropDown() - ->AddOption("1 Front white") - ->AddOption("2 Two-point") - ->AddOption("3 Backlight") - //->AddOption("4 Nuts") + ->AddOption("1 Front white") + ->AddOption("2 Two-point") + ->AddOption("3 Backlight") + //->AddOption("4 Nuts") ); lightSelector->SetSelectedOption("1 Front white"); m_options.lightPreset = 0; @@ -1198,23 +1184,14 @@ void ModelViewer::SetupUI() } if (supportsThrusters) { sliderBox->PackStart( - c->Grid(2,4) + c->Grid(2, 4) ->SetColumn(0, UI::WidgetSet( - // Column 1, Linear thrust sliders - c->Label("Linear"), - c->HBox(spacing)->PackEnd(c->Label("X"))->PackEnd(thrustSliders[0] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("Y"))->PackEnd(thrustSliders[1] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("Z"))->PackEnd(thrustSliders[2] = c->HSlider()) - )) + // Column 1, Linear thrust sliders + c->Label("Linear"), c->HBox(spacing)->PackEnd(c->Label("X"))->PackEnd(thrustSliders[0] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("Y"))->PackEnd(thrustSliders[1] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("Z"))->PackEnd(thrustSliders[2] = c->HSlider()))) ->SetColumn(1, UI::WidgetSet( - //Column 2, Angular thrust sliders - c->Label("Angular"), - c->HBox(spacing)->PackEnd(c->Label("Pitch"))->PackEnd(thrustSliders[3] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("Yaw"))->PackEnd(thrustSliders[4] = c->HSlider()), - c->HBox(spacing)->PackEnd(c->Label("Roll"))->PackEnd(thrustSliders[5] = c->HSlider()) - )) - ); - for(unsigned int i=0; i<2*3; i++) { + //Column 2, Angular thrust sliders + c->Label("Angular"), c->HBox(spacing)->PackEnd(c->Label("Pitch"))->PackEnd(thrustSliders[3] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("Yaw"))->PackEnd(thrustSliders[4] = c->HSlider()), c->HBox(spacing)->PackEnd(c->Label("Roll"))->PackEnd(thrustSliders[5] = c->HSlider())))); + for (unsigned int i = 0; i < 2 * 3; i++) { thrustSliders[i]->SetValue(0.5f); thrustSliders[i]->onValueChanged.connect(sigc::mem_fun(*this, &ModelViewer::OnThrustChanged)); } @@ -1225,7 +1202,9 @@ void ModelViewer::SetupUI() //event handlers collMeshCheck->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnToggleCollMesh), collMeshCheck)); - if( m_shields.get() && showShieldsCheck ) { showShieldsCheck->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnToggleShowShields), showShieldsCheck)); } + if (m_shields.get() && showShieldsCheck) { + showShieldsCheck->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnToggleShowShields), showShieldsCheck)); + } gunsCheck->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnToggleGuns), gunsCheck)); lightSelector->onOptionSelected.connect(sigc::mem_fun(*this, &ModelViewer::OnLightPresetChanged)); toggleGridButton->onClick.connect(sigc::bind(sigc::mem_fun(*this, &ModelViewer::OnToggleGrid), toggleGridButton)); @@ -1235,8 +1214,8 @@ void ModelViewer::UpdateAnimList() { animSelector->Clear(); if (m_model) { - const std::vector &anims = m_model->GetAnimations(); - for(unsigned int i=0; i &anims = m_model->GetAnimations(); + for (unsigned int i = 0; i < anims.size(); i++) { animSelector->AddOption(anims[i]->GetName()); } if (anims.size()) @@ -1257,8 +1236,7 @@ void ModelViewer::UpdateCamera() zoomRate *= 8.0f; moveRate *= 4.0f; rotateRate *= 4.0f; - } - else if (m_keyStates[SDLK_RSHIFT]) { + } else if (m_keyStates[SDLK_RSHIFT]) { zoomRate *= 3.0f; moveRate *= 2.0f; rotateRate *= 2.0f; @@ -1268,8 +1246,8 @@ void ModelViewer::UpdateCamera() const float degrees_per_pixel = 0.2f; if (!m_mouseButton[SDL_BUTTON_RIGHT]) { // yaw and pitch - const float rot_y = degrees_per_pixel*m_mouseMotion[0]; - const float rot_x = degrees_per_pixel*m_mouseMotion[1]; + const float rot_y = degrees_per_pixel * m_mouseMotion[0]; + const float rot_x = degrees_per_pixel * m_mouseMotion[1]; const matrix3x3f rot = matrix3x3f::RotateX(DEG2RAD(rot_x)) * matrix3x3f::RotateY(DEG2RAD(rot_y)); @@ -1308,8 +1286,8 @@ void ModelViewer::UpdateCamera() //mouse rotate when right button held if (m_mouseButton[SDL_BUTTON_RIGHT]) { - m_rotY += 0.2f*m_mouseMotion[0]; - m_rotX += 0.2f*m_mouseMotion[1]; + m_rotY += 0.2f * m_mouseMotion[0]; + m_rotX += 0.2f * m_mouseMotion[1]; } } } @@ -1319,21 +1297,21 @@ void ModelViewer::UpdateLights() using Graphics::Light; std::vector lights; - switch(m_options.lightPreset) { + switch (m_options.lightPreset) { case 0: //Front white - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(90,0), Color::WHITE, Color::WHITE)); - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(0,-90), Color(13, 13, 26), Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(90, 0), Color::WHITE, Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(0, -90), Color(13, 13, 26), Color::WHITE)); break; case 1: //Two-point - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(120,0), Color(230, 204, 204), Color::WHITE)); - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(-30,-90), Color(178, 128, 0), Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(120, 0), Color(230, 204, 204), Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(-30, -90), Color(178, 128, 0), Color::WHITE)); break; case 2: //Backlight - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(-75,20), Color::WHITE, Color::WHITE)); - lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(0,-90), Color(13, 13, 26), Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(-75, 20), Color::WHITE, Color::WHITE)); + lights.push_back(Light(Light::LIGHT_DIRECTIONAL, az_el_to_dir(0, -90), Color(13, 13, 26), Color::WHITE)); break; case 3: //4 lights @@ -1353,7 +1331,7 @@ void ModelViewer::UpdatePatternList() if (m_model) { const SceneGraph::PatternContainer &pats = m_model->GetPatterns(); - for(unsigned int i=0; iAddOption(pats[i].name); } if (pats.size() > 0) diff --git a/src/ModelViewer.h b/src/ModelViewer.h index 12b541e42..dfaa96e50 100644 --- a/src/ModelViewer.h +++ b/src/ModelViewer.h @@ -3,13 +3,13 @@ #ifndef MODELVIEWER_H #define MODELVIEWER_H -#include "libs.h" #include "LuaManager.h" #include "NavLights.h" #include "Shields.h" +#include "graphics/Drawables.h" #include "graphics/Renderer.h" #include "graphics/Texture.h" -#include "graphics/Drawables.h" +#include "libs.h" #include "scenegraph/SceneGraph.h" #include "ui/Context.h" @@ -21,16 +21,16 @@ public: static void Run(const std::string &modelName); private: - bool OnPickModel(UI::List*); + bool OnPickModel(UI::List *); bool OnQuit(); - bool OnReloadModel(UI::Widget*); - bool OnToggleCollMesh(UI::CheckBox*); - bool OnToggleShowShields(UI::CheckBox*); - bool OnToggleGrid(UI::Widget*); - bool OnToggleGuns(UI::CheckBox*); - bool OnRandomColor(UI::Widget*); + bool OnReloadModel(UI::Widget *); + bool OnToggleCollMesh(UI::CheckBox *); + bool OnToggleShowShields(UI::CheckBox *); + bool OnToggleGrid(UI::Widget *); + bool OnToggleGuns(UI::CheckBox *); + bool OnRandomColor(UI::Widget *); void UpdateShield(); - bool OnHitIt(UI::Widget*); + bool OnHitIt(UI::Widget *); void HitImpl(); void AddLog(const std::string &line); void ChangeCameraPreset(SDL_Keycode, SDL_Keymod); @@ -42,12 +42,12 @@ private: void DrawGrid(const matrix4x4f &trans, float radius); void DrawModel(const matrix4x4f &mv); void MainLoop(); - void OnAnimChanged(unsigned int, const std::string&); + void OnAnimChanged(unsigned int, const std::string &); void OnAnimSliderChanged(float); - void OnDecalChanged(unsigned int, const std::string&); + void OnDecalChanged(unsigned int, const std::string &); void OnLightPresetChanged(unsigned int index, const std::string &); void OnModelColorsChanged(float); - void OnPatternChanged(unsigned int, const std::string&); + void OnPatternChanged(unsigned int, const std::string &); void OnThrustChanged(float); void PollEvents(); void PopulateFilePicker(); @@ -55,7 +55,7 @@ private: void ResetThrusters(); void Screenshot(); void SaveModelToBinary(); - void SetModel(const std::string& name); + void SetModel(const std::string &name); void SetupFilePicker(); void SetupUI(); void UpdateAnimList(); @@ -111,7 +111,7 @@ private: //undecided on this input stuff //updating the states of all inputs during PollEvents - std::map m_keyStates; + std::map m_keyStates; bool m_mouseButton[SDL_BUTTON_RIGHT + 1]; //buttons start at 1 int m_mouseMotion[2]; bool m_mouseWheelUp, m_mouseWheelDown; @@ -128,7 +128,7 @@ private: UI::Slider *animSlider; UI::Label *animValue; UI::Slider *colorSliders[9]; - UI::Slider *thrustSliders[2*3]; //thruster sliders 2*xyz (linear & angular) + UI::Slider *thrustSliders[2 * 3]; //thruster sliders 2*xyz (linear & angular) sigc::signal onModelChanged; diff --git a/src/NavLights.cpp b/src/NavLights.cpp index e45b68abb..9c5cac5f5 100644 --- a/src/NavLights.cpp +++ b/src/NavLights.cpp @@ -2,12 +2,12 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "NavLights.h" +#include "FileSystem.h" +#include "GameSaveError.h" +#include "IniConfig.h" #include "graphics/TextureBuilder.h" #include "scenegraph/FindNodeVisitor.h" #include "scenegraph/SceneGraph.h" -#include "IniConfig.h" -#include "FileSystem.h" -#include "GameSaveError.h" #include "utils.h" const float BILLBOARD_SIZE = 2.5f; @@ -16,11 +16,11 @@ static RefCountedPtr texHalos4x4; static RefCountedPtr matHalos4x4; static bool g_initted = false; -static vector2f m_lightColorsUVoffsets[(NavLights::NAVLIGHT_YELLOW+1)] = { - vector2f(0.0f,0.0f), - vector2f(0.5f,0.0f), - vector2f(0.0f,0.5f), - vector2f(0.5f,0.5f) +static vector2f m_lightColorsUVoffsets[(NavLights::NAVLIGHT_YELLOW + 1)] = { + vector2f(0.0f, 0.0f), + vector2f(0.5f, 0.0f), + vector2f(0.0f, 0.5f), + vector2f(0.5f, 0.5f) }; typedef std::vector::iterator LightIterator; @@ -36,11 +36,11 @@ static inline vector2f LoadLightColorUVoffset(const std::string &spec) return vector2f(v[0], v[1]); } -NavLights::LightBulb::LightBulb(Uint8 _group, Uint8 _mask, Uint8 _color, SceneGraph::Billboard *_bb) -: group(_group) -, mask(_mask) -, color(_color) -, billboard(_bb) +NavLights::LightBulb::LightBulb(Uint8 _group, Uint8 _mask, Uint8 _color, SceneGraph::Billboard *_bb) : + group(_group), + mask(_mask), + color(_color), + billboard(_bb) { } @@ -57,9 +57,9 @@ void NavLights::Init(Graphics::Renderer *renderer) // load cfg.Read(FileSystem::gameDataFiles, "textures/NavLights.ini"); - m_lightColorsUVoffsets[NAVLIGHT_RED ] = LoadLightColorUVoffset(cfg.String("LeftOrOccupiedUVOffset")); - m_lightColorsUVoffsets[NAVLIGHT_GREEN ] = LoadLightColorUVoffset(cfg.String("RightOrFreeUVOffset")); - m_lightColorsUVoffsets[NAVLIGHT_BLUE ] = LoadLightColorUVoffset(cfg.String("StaticUVOffset")); + m_lightColorsUVoffsets[NAVLIGHT_RED] = LoadLightColorUVoffset(cfg.String("LeftOrOccupiedUVOffset")); + m_lightColorsUVoffsets[NAVLIGHT_GREEN] = LoadLightColorUVoffset(cfg.String("RightOrFreeUVOffset")); + m_lightColorsUVoffsets[NAVLIGHT_BLUE] = LoadLightColorUVoffset(cfg.String("StaticUVOffset")); m_lightColorsUVoffsets[NAVLIGHT_YELLOW] = LoadLightColorUVoffset(cfg.String("DockingUVOffset")); g_initted = true; @@ -72,54 +72,53 @@ void NavLights::Uninit() g_initted = false; } -NavLights::NavLights(SceneGraph::Model *model, float period) -: m_time(0.f) -, m_period(period) -, m_enabled(false) -, m_billboardTris(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL) -, m_billboardRS(nullptr) +NavLights::NavLights(SceneGraph::Model *model, float period) : + m_time(0.f), + m_period(period), + m_enabled(false), + m_billboardTris(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL), + m_billboardRS(nullptr) { PROFILE_SCOPED(); assert(g_initted); Graphics::Renderer *renderer = model->GetRenderer(); - using SceneGraph::Node; - using SceneGraph::MatrixTransform; using SceneGraph::Billboard; + using SceneGraph::MatrixTransform; + using SceneGraph::Node; //This will find all matrix transforms meant for navlights. SceneGraph::FindNodeVisitor lightFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_STARTSWITH, "navlight_"); model->GetRoot()->Accept(lightFinder); - const std::vector &results = lightFinder.GetResults(); + const std::vector &results = lightFinder.GetResults(); //attach light billboards - for (unsigned int i=0; i < results.size(); i++) - { - MatrixTransform *mt = dynamic_cast(results.at(i)); + for (unsigned int i = 0; i < results.size(); i++) { + MatrixTransform *mt = dynamic_cast(results.at(i)); assert(mt); Billboard *bblight = new Billboard(m_billboardTris, renderer, BILLBOARD_SIZE); Uint32 group = 0; - Uint8 mask = 0xff; //always on + Uint8 mask = 0xff; //always on Uint8 color = NAVLIGHT_BLUE; if (mt->GetName().substr(9, 3) == "red") { - mask = 0x0f; + mask = 0x0f; color = NAVLIGHT_RED; } else if (mt->GetName().substr(9, 5) == "green") { - mask = 0xf0; + mask = 0xf0; color = NAVLIGHT_GREEN; } else if (mt->GetName().substr(9, 3) == "pad") { //group by pad number // due to this problem: http://stackoverflow.com/questions/15825254/why-is-scanfhhu-char-overwriting-other-variables-when-they-are-local // where MSVC is still using a C89 compiler the format identifer %hhu is not recognised. Therefore I've switched to Uint32 for group. PiVerify(1 == sscanf(mt->GetName().c_str(), "navlight_pad%u", &group)); - mask = 0xf0; + mask = 0xf0; } bblight->SetColorUVoffset(get_color(color)); GroupLightsVecIter glit = std::find_if(m_groupLights.begin(), m_groupLights.end(), GroupMatch(group)); - if(glit == m_groupLights.end()) { + if (glit == m_groupLights.end()) { // didn't find group, create a new one m_groupLights.push_back(TGroupLights(group)); // now use it @@ -163,7 +162,7 @@ void NavLights::Update(float time) { PROFILE_SCOPED(); if (!m_enabled) { - for(auto glit : m_groupLights) + for (auto glit : m_groupLights) for (LightIterator it = glit.m_lights.begin(), itEnd = glit.m_lights.end(); it != itEnd; ++it) it->billboard->SetNodeMask(0x0); return; @@ -174,7 +173,7 @@ void NavLights::Update(float time) const int phase((fmod(m_time, m_period) / m_period) * 8); const Uint8 mask = 1 << phase; - for(auto glit : m_groupLights) { + for (auto glit : m_groupLights) { for (LightIterator it = glit.m_lights.begin(), itEnd = glit.m_lights.end(); it != itEnd; ++it) { if (it->mask & mask) it->billboard->SetNodeMask(SceneGraph::NODE_TRANSPARENT); @@ -186,7 +185,7 @@ void NavLights::Update(float time) void NavLights::Render(Graphics::Renderer *renderer) { - if(!m_billboardRS) { + if (!m_billboardRS) { Graphics::MaterialDescriptor desc; desc.effect = Graphics::EFFECT_BILLBOARD_ATLAS; desc.textures = 1; @@ -203,23 +202,21 @@ void NavLights::Render(Graphics::Renderer *renderer) const bool isVBValid = m_billboardVB.Valid(); const bool hasVerts = !m_billboardTris.IsEmpty(); const bool isVertCountEnough = isVBValid && (m_billboardTris.GetNumVerts() <= m_billboardVB->GetCapacity()); - if( hasVerts && (!isVBValid || !isVertCountEnough) ) - { + if (hasVerts && (!isVBValid || !isVertCountEnough)) { //create buffer // NB - we're (ab)using the normal type to hold (uv coordinate offset value + point size) Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.numVertices = m_billboardTris.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame - m_billboardVB.Reset( renderer->CreateVertexBuffer(vbd) ); + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + m_billboardVB.Reset(renderer->CreateVertexBuffer(vbd)); } - if(m_billboardVB.Valid()) - { - if(hasVerts) { + if (m_billboardVB.Valid()) { + if (hasVerts) { m_billboardVB->Populate(m_billboardTris); renderer->SetTransform(matrix4x4f::Identity()); renderer->DrawBuffer(m_billboardVB.Get(), m_billboardRS, matHalos4x4.Get(), Graphics::POINTS); @@ -233,7 +230,7 @@ void NavLights::SetColor(unsigned int group, LightColor c) { PROFILE_SCOPED(); GroupLightsVecIter glit = std::find_if(m_groupLights.begin(), m_groupLights.end(), GroupMatch(group)); - if(glit != m_groupLights.end()) { + if (glit != m_groupLights.end()) { for (LightIterator it = glit->m_lights.begin(), itEnd = glit->m_lights.end(); it != itEnd; ++it) { if (it->group != group || it->color == c) continue; it->billboard->SetColorUVoffset(get_color(c)); diff --git a/src/NavLights.h b/src/NavLights.h index fb6f51b71..3b404a0c5 100644 --- a/src/NavLights.h +++ b/src/NavLights.h @@ -6,27 +6,30 @@ /* * Blinking navigation lights for ships and stations */ -#include "libs.h" #include "JsonFwd.h" #include "graphics/RenderState.h" #include "graphics/VertexArray.h" #include "graphics/VertexBuffer.h" +#include "libs.h" -namespace Graphics { class Renderer; } -namespace SceneGraph { class Model; class Billboard; } +namespace Graphics { + class Renderer; +} +namespace SceneGraph { + class Model; + class Billboard; +} // namespace SceneGraph -class NavLights -{ +class NavLights { public: enum LightColor { - NAVLIGHT_RED = 0, - NAVLIGHT_GREEN = 1, - NAVLIGHT_BLUE = 2, + NAVLIGHT_RED = 0, + NAVLIGHT_GREEN = 1, + NAVLIGHT_BLUE = 2, NAVLIGHT_YELLOW = 3 }; - struct LightBulb - { + struct LightBulb { LightBulb(Uint8 group, Uint8 mask, Uint8 color, SceneGraph::Billboard *bb); Uint8 group; Uint8 mask; //bitmask: 00001111 light on half the period, 11111111 light on the entire period etc... @@ -34,7 +37,7 @@ public: SceneGraph::Billboard *billboard; }; - NavLights(SceneGraph::Model*, float period = 2.f); + NavLights(SceneGraph::Model *, float period = 2.f); virtual ~NavLights(); virtual void SaveToJson(Json &jsonObj); virtual void LoadFromJson(const Json &jsonObj); @@ -44,26 +47,30 @@ public: void Render(Graphics::Renderer *renderer); void SetColor(unsigned int group, LightColor); - static void Init(Graphics::Renderer*); + static void Init(Graphics::Renderer *); static void Uninit(); protected: - class TGroupLights { public: - TGroupLights(Uint32 g) : m_group(g) {} + TGroupLights(Uint32 g) : + m_group(g) {} const Uint32 m_group; std::vector m_lights; + private: - TGroupLights() : m_group(0xFFFFFFFF) {} + TGroupLights() : + m_group(0xFFFFFFFF) {} }; // for use with std::find_if - class GroupMatch{ + class GroupMatch { const Uint32 group; + public: - GroupMatch(const Uint32 g): group(g) {} - bool operator() (const TGroupLights& myValue) + GroupMatch(const Uint32 g) : + group(g) {} + bool operator()(const TGroupLights &myValue) { return (group == myValue.m_group); } diff --git a/src/OS.h b/src/OS.h index 0cf286a30..ebd61784f 100644 --- a/src/OS.h +++ b/src/OS.h @@ -40,6 +40,6 @@ namespace OS { // Open the Explorer/Finder/etc bool SupportsFolderBrowser(); void OpenUserFolderBrowser(); -} +} // namespace OS #endif diff --git a/src/Object.h b/src/Object.h index f99df3c60..4055a945f 100644 --- a/src/Object.h +++ b/src/Object.h @@ -11,28 +11,32 @@ class Object : public DeleteEmitter { public: // only creating enum strings for types that are exposed to Lua enum Type { // - OBJECT, // + OBJECT, // BODY, MODELBODY, - DYNAMICBODY, // + DYNAMICBODY, // SHIP, PLAYER, SPACESTATION, - TERRAINBODY, // + TERRAINBODY, // PLANET, STAR, CARGOBODY, - CITYONPLANET, // - PROJECTILE, // + CITYONPLANET, // + PROJECTILE, // MISSILE, HYPERSPACECLOUD // }; virtual Type GetType() const { return OBJECT; } virtual bool IsType(Type c) const { return GetType() == c; } }; -#define OBJDEF(__thisClass,__parentClass,__TYPE) \ +#define OBJDEF(__thisClass, __parentClass, __TYPE) \ virtual Object::Type GetType() const override { return Object::__TYPE; } \ - virtual bool IsType(Type c) const override { \ - if (__thisClass::GetType() == (c)) return true; \ - else return __parentClass::IsType(c); } + virtual bool IsType(Type c) const override \ + { \ + if (__thisClass::GetType() == (c)) \ + return true; \ + else \ + return __parentClass::IsType(c); \ + } #endif /* _OBJECT_H */ diff --git a/src/ObjectViewerView.cpp b/src/ObjectViewerView.cpp index dd6fb1673..fc8653228 100644 --- a/src/ObjectViewerView.cpp +++ b/src/ObjectViewerView.cpp @@ -2,21 +2,22 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ObjectViewerView.h" -#include "WorldView.h" -#include "Pi.h" #include "Frame.h" +#include "Pi.h" +#include "Planet.h" #include "Player.h" #include "Space.h" -#include "terrain/Terrain.h" -#include "Planet.h" +#include "StringF.h" +#include "WorldView.h" #include "graphics/Light.h" #include "graphics/Renderer.h" -#include "StringF.h" +#include "terrain/Terrain.h" #include #if WITH_OBJECTVIEWER -ObjectViewerView::ObjectViewerView(): UIView() +ObjectViewerView::ObjectViewerView() : + UIView() { SetTransparency(true); viewingDist = 1000.0f; @@ -32,15 +33,15 @@ ObjectViewerView::ObjectViewerView(): UIView() Pi::renderer->GetNearFarRange(znear, zfar); const float fovY = Pi::config->Float("FOVVertical"); - m_cameraContext.Reset(new CameraContext(Graphics::GetScreenWidth(), Graphics::GetScreenHeight(), fovY, znear, zfar)); - m_camera.reset(new Camera(m_cameraContext, Pi::renderer)); + m_cameraContext.Reset(new CameraContext(Graphics::GetScreenWidth(), Graphics::GetScreenHeight(), fovY, znear, zfar)); + m_camera.reset(new Camera(m_cameraContext, Pi::renderer)); m_cameraContext->SetFrame(Pi::player->GetFrame()); m_cameraContext->SetPosition(Pi::player->GetInterpPosition() + vector3d(0, 0, viewingDist)); m_cameraContext->SetOrient(matrix3x3d::Identity()); m_infoLabel = new Gui::Label(""); - Add(m_infoLabel, 2, Gui::Screen::GetHeight()-66-Gui::Screen::GetFontHeight()); + Add(m_infoLabel, 2, Gui::Screen::GetHeight() - 66 - Gui::Screen::GetFontHeight()); m_vbox = new Gui::VBox(); Add(m_vbox, 580, 2); @@ -118,8 +119,8 @@ void ObjectViewerView::Draw3D() if (btnState) { int m[2]; Pi::input.GetMouseMotion(m); - m_camRot = matrix4x4d::RotateXMatrix(-0.002*m[1]) * - matrix4x4d::RotateYMatrix(-0.002*m[0]) * m_camRot; + m_camRot = matrix4x4d::RotateXMatrix(-0.002 * m[1]) * + matrix4x4d::RotateYMatrix(-0.002 * m[0]) * m_camRot; m_cameraContext->SetPosition(Pi::player->GetInterpPosition() + vector3d(0, 0, viewingDist)); m_cameraContext->BeginFrame(); m_camera->Update(); @@ -134,7 +135,7 @@ void ObjectViewerView::Draw3D() } m_renderer->SetLights(1, &light); - body->Render(m_renderer, m_camera.get(), vector3d(0,0,-viewingDist), m_camRot); + body->Render(m_renderer, m_camera.get(), vector3d(0, 0, -viewingDist), m_camRot); } UIView::Draw3D(); @@ -157,13 +158,13 @@ void ObjectViewerView::Update() char buf[128]; Body *body = Pi::player->GetNavTarget(); - if(body && (body != lastTarget)) { + if (body && (body != lastTarget)) { // Reset view distance for new target. viewingDist = body->GetClipRadius() * 2.0f; lastTarget = body; if (body->IsType(Object::TERRAINBODY)) { - TerrainBody *tbody = static_cast(body); + TerrainBody *tbody = static_cast(body); const SystemBody *sbody = tbody->GetSystemBody(); m_sbodyVolatileGas->SetText(stringf("%0{f.3}", sbody->GetVolatileGas())); m_sbodyVolatileLiquid->SetText(stringf("%0{f.3}", sbody->GetVolatileLiquid())); @@ -178,12 +179,11 @@ void ObjectViewerView::Update() } std::ostringstream pathStr; - if(body) - { + if (body) { // fill in pathStr from sp values and sys->GetName() static const std::string comma(", "); const SystemBody *psb = body->GetSystemBody(); - if(psb) { + if (psb) { const SystemPath sp = psb->GetPath(); pathStr << body->GetSystemBody()->GetName() << " (" << sp.sectorX << comma << sp.sectorY << comma << sp.sectorZ << comma << sp.systemIndex << comma << sp.bodyIndex << ")"; } else { @@ -196,29 +196,31 @@ void ObjectViewerView::Update() pathStr.str().c_str()); m_infoLabel->SetText(buf); - if (body && body->IsType(Object::TERRAINBODY)) m_vbox->ShowAll(); - else m_vbox->HideAll(); + if (body && body->IsType(Object::TERRAINBODY)) + m_vbox->ShowAll(); + else + m_vbox->HideAll(); UIView::Update(); } void ObjectViewerView::OnChangeTerrain() { - const fixed volatileGas = fixed(65536.0*atof(m_sbodyVolatileGas->GetText().c_str()), 65536); - const fixed volatileLiquid = fixed(65536.0*atof(m_sbodyVolatileLiquid->GetText().c_str()), 65536); - const fixed volatileIces = fixed(65536.0*atof(m_sbodyVolatileIces->GetText().c_str()), 65536); - const fixed life = fixed(65536.0*atof(m_sbodyLife->GetText().c_str()), 65536); - const fixed volcanicity = fixed(65536.0*atof(m_sbodyVolcanicity->GetText().c_str()), 65536); - const fixed metallicity = fixed(65536.0*atof(m_sbodyMetallicity->GetText().c_str()), 65536); - const fixed mass = fixed(65536.0*atof(m_sbodyMass->GetText().c_str()), 65536); - const fixed radius = fixed(65536.0*atof(m_sbodyRadius->GetText().c_str()), 65536); + const fixed volatileGas = fixed(65536.0 * atof(m_sbodyVolatileGas->GetText().c_str()), 65536); + const fixed volatileLiquid = fixed(65536.0 * atof(m_sbodyVolatileLiquid->GetText().c_str()), 65536); + const fixed volatileIces = fixed(65536.0 * atof(m_sbodyVolatileIces->GetText().c_str()), 65536); + const fixed life = fixed(65536.0 * atof(m_sbodyLife->GetText().c_str()), 65536); + const fixed volcanicity = fixed(65536.0 * atof(m_sbodyVolcanicity->GetText().c_str()), 65536); + const fixed metallicity = fixed(65536.0 * atof(m_sbodyMetallicity->GetText().c_str()), 65536); + const fixed mass = fixed(65536.0 * atof(m_sbodyMass->GetText().c_str()), 65536); + const fixed radius = fixed(65536.0 * atof(m_sbodyRadius->GetText().c_str()), 65536); // XXX this is horrendous, but probably safe for the moment. all bodies, // terrain, whatever else holds a const pointer to the same toplevel // sbody. one day objectviewer should be far more contained and not // actually modify the space Body *body = Pi::player->GetNavTarget(); - SystemBody *sbody = const_cast(body->GetSystemBody()); + SystemBody *sbody = const_cast(body->GetSystemBody()); sbody->m_seed = atoi(m_sbodySeed->GetText().c_str()); sbody->m_radius = radius; diff --git a/src/ObjectViewerView.h b/src/ObjectViewerView.h index 4cadb280e..25950c814 100644 --- a/src/ObjectViewerView.h +++ b/src/ObjectViewerView.h @@ -4,27 +4,29 @@ #ifndef _OBJECTVIEWERVIEW_H #define _OBJECTVIEWERVIEW_H -#include "libs.h" -#include "gui/Gui.h" -#include "UIView.h" #include "Camera.h" +#include "UIView.h" +#include "gui/Gui.h" +#include "libs.h" #if WITH_OBJECTVIEWER class Body; -class ObjectViewerView: public UIView { +class ObjectViewerView : public UIView { public: ObjectViewerView(); virtual void Update(); virtual void Draw3D(); + protected: virtual void OnSwitchTo(); + private: float viewingDist; Gui::Label *m_infoLabel; Gui::VBox *m_vbox; - const Body* lastTarget; + const Body *lastTarget; matrix4x4d m_camRot; RefCountedPtr m_cameraContext; diff --git a/src/Orbit.cpp b/src/Orbit.cpp index dd67ac273..bf0536871 100644 --- a/src/Orbit.cpp +++ b/src/Orbit.cpp @@ -2,16 +2,16 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Orbit.h" -#include "libs.h" #include "gameconsts.h" +#include "libs.h" #ifdef _MSC_VER - #include "win32/WinMath.h" +#include "win32/WinMath.h" #endif double Orbit::OrbitalPeriod(double semiMajorAxis, double centralMass) { - return 2.0*M_PI*sqrt((semiMajorAxis*semiMajorAxis*semiMajorAxis)/(G*centralMass)); + return 2.0 * M_PI * sqrt((semiMajorAxis * semiMajorAxis * semiMajorAxis) / (G * centralMass)); } double Orbit::OrbitalPeriodTwoBody(double semiMajorAxis, double totalMass, double bodyMass) @@ -37,46 +37,51 @@ double Orbit::OrbitalPeriodTwoBody(double semiMajorAxis, double totalMass, doubl const double r1 = semiMajorAxis; const double m2 = (totalMass - bodyMass); const double a = r1 * totalMass / m2; - const double a3 = a*a*a; + const double a3 = a * a * a; return 2.0 * M_PI * sqrt(a3 / (G * totalMass)); } -static double calc_velocity_area_per_sec(double semiMajorAxis, double centralMass, double eccentricity) { +static double calc_velocity_area_per_sec(double semiMajorAxis, double centralMass, double eccentricity) +{ const double a2 = semiMajorAxis * semiMajorAxis; const double e2 = eccentricity * eccentricity; return M_PI * a2 * sqrt((eccentricity < 1.0) ? (1 - e2) : (e2 - 1.0)) / Orbit::OrbitalPeriod(semiMajorAxis, centralMass); } -static double calc_velocity_area_per_sec_gravpoint(double semiMajorAxis, double totalMass, double bodyMass, double eccentricity) { +static double calc_velocity_area_per_sec_gravpoint(double semiMajorAxis, double totalMass, double bodyMass, double eccentricity) +{ const double a2 = semiMajorAxis * semiMajorAxis; const double e2 = eccentricity * eccentricity; return M_PI * a2 * sqrt((eccentricity < 1.0) ? (1 - e2) : (e2 - 1.0)) / Orbit::OrbitalPeriodTwoBody(semiMajorAxis, totalMass, bodyMass); } -static void calc_position_from_mean_anomaly(const double M, const double e, const double a, double &cos_v, double &sin_v, double *r) { +static void calc_position_from_mean_anomaly(const double M, const double e, const double a, double &cos_v, double &sin_v, double *r) +{ // M is mean anomaly // e is eccentricity // a is semi-major axis cos_v = 0.0; sin_v = 0.0; - if (r) { *r = 0.0; } + if (r) { + *r = 0.0; + } if (e < 1.0) { // elliptic orbit // eccentric anomaly // NR method to solve for E: M = E-e*sin(E) {Kepler's equation} double E = M; - for (int iter=5; iter > 0; --iter) { - E = E - (E-e*(sin(E))-M) / (1.0 - e*cos(E)); + for (int iter = 5; iter > 0; --iter) { + E = E - (E - e * (sin(E)) - M) / (1.0 - e * cos(E)); } // true anomaly (angle of orbit position) - cos_v = (cos(E) - e) / (1.0 - e*cos(E)); - sin_v = (sqrt(1.0-e*e)*sin(E))/ (1.0 - e*cos(E)); + cos_v = (cos(E) - e) / (1.0 - e * cos(E)); + sin_v = (sqrt(1.0 - e * e) * sin(E)) / (1.0 - e * cos(E)); // heliocentric distance if (r) { - *r = a * (1.0 - e*cos(E)); + *r = a * (1.0 - e * cos(E)); } } else { // parabolic or hyperbolic orbit @@ -84,50 +89,53 @@ static void calc_position_from_mean_anomaly(const double M, const double e, cons // NR method to solve for E: M = E-sinh(E) // sinh E and cosh E are solved directly, because of inherent numerical instability of tanh(k arctanh x) double sh = 2.0; - for (int iter=5; iter > 0; --iter) { - sh = sh - (M + e*sh - asinh(sh))/(e - 1/sqrt(1 + (sh*sh))); + for (int iter = 5; iter > 0; --iter) { + sh = sh - (M + e * sh - asinh(sh)) / (e - 1 / sqrt(1 + (sh * sh))); } - double ch = sqrt(1 + sh*sh); + double ch = sqrt(1 + sh * sh); // true anomaly (angle of orbit position) - cos_v = (ch - e) / (1.0 - e*ch); - sin_v = (sqrt(e*e-1.0)*sh)/ (e*ch - 1.0); + cos_v = (ch - e) / (1.0 - e * ch); + sin_v = (sqrt(e * e - 1.0) * sh) / (e * ch - 1.0); if (r) { // heliocentric distance - *r = a * (e*ch - 1.0); + *r = a * (e * ch - 1.0); } } } -double Orbit::TrueAnomalyFromMeanAnomaly(double MeanAnomaly) const { +double Orbit::TrueAnomalyFromMeanAnomaly(double MeanAnomaly) const +{ double cos_v, sin_v; calc_position_from_mean_anomaly(MeanAnomaly, m_eccentricity, m_semiMajorAxis, cos_v, sin_v, 0); return atan2(sin_v, cos_v); } -double Orbit::MeanAnomalyFromTrueAnomaly(double trueAnomaly) const { +double Orbit::MeanAnomalyFromTrueAnomaly(double trueAnomaly) const +{ double M_t0; const double e = m_eccentricity; if (e < 1.0) { - M_t0 = 2.0*atan(tan(trueAnomaly/2.0)*sqrt((1.0-e)/(1.0+e))); - M_t0 = M_t0 - e*sin(M_t0); + M_t0 = 2.0 * atan(tan(trueAnomaly / 2.0) * sqrt((1.0 - e) / (1.0 + e))); + M_t0 = M_t0 - e * sin(M_t0); } else { // For hyperbolic trajectories, mean anomaly has opposite sign to true anomaly, therefore trajectories which go forward // in time decrease their true anomaly. Yes, it is confusing. - M_t0 = 2.0*atanh(tan(trueAnomaly/2.0)*sqrt((e-1.0)/(1.0+e))); - M_t0 = M_t0 - e*sinh(M_t0); + M_t0 = 2.0 * atanh(tan(trueAnomaly / 2.0) * sqrt((e - 1.0) / (1.0 + e))); + M_t0 = M_t0 - e * sinh(M_t0); } return M_t0; } -double Orbit::MeanAnomalyAtTime(double time) const { +double Orbit::MeanAnomalyAtTime(double time) const +{ const double e = m_eccentricity; if (e < 1.0) { // elliptic orbit - return 2.0*M_PI*time / Period() + m_orbitalPhaseAtStart; + return 2.0 * M_PI * time / Period() + m_orbitalPhaseAtStart; } else { - return -2.0*time * m_velocityAreaPerSecond / (m_semiMajorAxis * m_semiMajorAxis * sqrt(e*e-1)) + m_orbitalPhaseAtStart; + return -2.0 * time * m_velocityAreaPerSecond / (m_semiMajorAxis * m_semiMajorAxis * sqrt(e * e - 1)) + m_orbitalPhaseAtStart; } } @@ -135,10 +143,10 @@ vector3d Orbit::OrbitalPosAtTime(double t) const { double cos_v, sin_v, r; calc_position_from_mean_anomaly(MeanAnomalyAtTime(t), m_eccentricity, m_semiMajorAxis, cos_v, sin_v, &r); - return m_orient * vector3d(-cos_v*r, sin_v*r, 0); + return m_orient * vector3d(-cos_v * r, sin_v * r, 0); } -double Orbit::OrbitalTimeAtPos(const vector3d& pos, double centralMass) const +double Orbit::OrbitalTimeAtPos(const vector3d &pos, double centralMass) const { double c = m_eccentricity * m_semiMajorAxis; matrix3x3d matrixInv = m_orient.Inverse(); @@ -150,36 +158,31 @@ double Orbit::OrbitalTimeAtPos(const vector3d& pos, double centralMass) const double cos_E = (cos_v + m_eccentricity) / (1. + m_eccentricity * cos_v); double E; double meanAnomaly; - if(m_eccentricity <= 1.) - { + if (m_eccentricity <= 1.) { E = std::acos(cos_E); - if(sin_v < 0) + if (sin_v < 0) E *= -1.; meanAnomaly = E - m_eccentricity * std::sin(E); - } - else - { + } else { E = std::acosh(cos_E); - if(sin_v < 0) + if (sin_v < 0) E *= -1.; meanAnomaly = E - m_eccentricity * std::sinh(E); } - if(m_eccentricity <= 1.) - { + if (m_eccentricity <= 1.) { meanAnomaly -= m_orbitalPhaseAtStart; - while(meanAnomaly < 0) + while (meanAnomaly < 0) meanAnomaly += 2. * M_PI; - } - else if(meanAnomaly < 0.) + } else if (meanAnomaly < 0.) meanAnomaly += m_orbitalPhaseAtStart; - if(m_eccentricity <= 1.) + if (m_eccentricity <= 1.) return meanAnomaly * Period() / (2. * M_PI); - else if(meanAnomaly < 0.) + else if (meanAnomaly < 0.) return -meanAnomaly * std::sqrt(std::pow(m_semiMajorAxis, 3) / (G * centralMass)); else - return - std::fabs(meanAnomaly + m_orbitalPhaseAtStart) * std::sqrt(std::pow(m_semiMajorAxis, 3) / (G * centralMass)); + return -std::fabs(meanAnomaly + m_orbitalPhaseAtStart) * std::sqrt(std::pow(m_semiMajorAxis, 3) / (G * centralMass)); } vector3d Orbit::OrbitalVelocityAtTime(double totalMass, double t) const @@ -189,7 +192,7 @@ vector3d Orbit::OrbitalVelocityAtTime(double totalMass, double t) const double mi = G * totalMass; double p; - if(m_eccentricity <= 1.) + if (m_eccentricity <= 1.) p = (1. - m_eccentricity * m_eccentricity) * m_semiMajorAxis; else p = (m_eccentricity * m_eccentricity - 1.) * m_semiMajorAxis; @@ -205,52 +208,54 @@ vector3d Orbit::OrbitalVelocityAtTime(double totalMass, double t) const vector3d Orbit::EvenSpacedPosTrajectory(double t, double timeOffset) const { const double e = m_eccentricity; - double v = 2*M_PI*t + TrueAnomalyFromMeanAnomaly(MeanAnomalyAtTime(timeOffset)); + double v = 2 * M_PI * t + TrueAnomalyFromMeanAnomaly(MeanAnomalyAtTime(timeOffset)); double r; if (e < 1.0) { - r = m_semiMajorAxis * (1 - e*e) / (1 + e*cos(v)); + r = m_semiMajorAxis * (1 - e * e) / (1 + e * cos(v)); } else { - r = m_semiMajorAxis * (e*e - 1) / (1 + e*cos(v)); + r = m_semiMajorAxis * (e * e - 1) / (1 + e * cos(v)); // planet is in infinity - const double ac = acos(-1/e); + const double ac = acos(-1 / e); if (v <= -ac) { v = -ac + 0.0001; - r = 100.0 * AU; + r = 100.0 * AU; } if (v >= ac) { v = ac - 0.0001; - r = 100.0 * AU; + r = 100.0 * AU; } - } - return m_orient * vector3d(-cos(v)*r, sin(v)*r, 0); + return m_orient * vector3d(-cos(v) * r, sin(v) * r, 0); } -double Orbit::Period() const { - if(m_eccentricity < 1 && m_eccentricity >= 0) { - return M_PI * m_semiMajorAxis * m_semiMajorAxis * sqrt(1 - m_eccentricity * m_eccentricity)/ m_velocityAreaPerSecond; +double Orbit::Period() const +{ + if (m_eccentricity < 1 && m_eccentricity >= 0) { + return M_PI * m_semiMajorAxis * m_semiMajorAxis * sqrt(1 - m_eccentricity * m_eccentricity) / m_velocityAreaPerSecond; } else { // hyperbola.. period makes no sense, should not be used assert(0); return 0; } } -vector3d Orbit::Apogeum() const { - if(m_eccentricity < 1) { - return m_semiMajorAxis * (1 + m_eccentricity) * (m_orient * vector3d(1,0,0)); +vector3d Orbit::Apogeum() const +{ + if (m_eccentricity < 1) { + return m_semiMajorAxis * (1 + m_eccentricity) * (m_orient * vector3d(1, 0, 0)); } else { - return vector3d(0,0,0); + return vector3d(0, 0, 0); } } -vector3d Orbit::Perigeum() const { - if(m_eccentricity < 1) { - return m_semiMajorAxis * (1 - m_eccentricity) * (m_orient * vector3d(-1,0,0)); +vector3d Orbit::Perigeum() const +{ + if (m_eccentricity < 1) { + return m_semiMajorAxis * (1 - m_eccentricity) * (m_orient * vector3d(-1, 0, 0)); } else { - return m_semiMajorAxis * (m_eccentricity - 1) * (m_orient * vector3d(-1,0,0)); + return m_semiMajorAxis * (m_eccentricity - 1) * (m_orient * vector3d(-1, 0, 0)); } } @@ -284,19 +289,19 @@ Orbit Orbit::FromBodyState(const vector3d &pos, const vector3d &vel, double cent const double LL = ang.Length(); // total energy - const double EE = vel.LengthSqr()/2.0 - u/r_now; + const double EE = vel.LengthSqr() / 2.0 - u / r_now; - if (is_zero_general(centralMass) || is_zero_general(r_now) || is_zero_general(v_now) || is_zero_general(EE) || (ang.z*ang.z/LLSqr > 1.0)) { + if (is_zero_general(centralMass) || is_zero_general(r_now) || is_zero_general(v_now) || is_zero_general(EE) || (ang.z * ang.z / LLSqr > 1.0)) { ret.m_eccentricity = 0.0; ret.m_semiMajorAxis = 0.0; ret.m_velocityAreaPerSecond = 0.0; ret.m_orbitalPhaseAtStart = 0.0; - ret.m_orient = matrix3x3d::Identity(); + ret.m_orient = matrix3x3d::Identity(); return ret; } // http://en.wikipedia.org/wiki/Orbital_eccentricity - ret.m_eccentricity = 1 + 2*EE*LLSqr/(u*u); + ret.m_eccentricity = 1 + 2 * EE * LLSqr / (u * u); if (ret.m_eccentricity < 0.0) ret.m_eccentricity = 0.0; ret.m_eccentricity = sqrt(ret.m_eccentricity); @@ -305,17 +310,17 @@ Orbit Orbit::FromBodyState(const vector3d &pos, const vector3d &vel, double cent // M G (e - 1) / 2 EE, always positive (EE and (e-1) change sign // M G / 2 EE, // which is a (http://en.wikipedia.org/wiki/Semi-major_axis); a of hyperbola is taken as positive here - ret.m_semiMajorAxis = 2*EE*LLSqr + u*u; - if (ret.m_semiMajorAxis < 0) ret.m_semiMajorAxis = 0; - ret.m_semiMajorAxis = (sqrt(ret.m_semiMajorAxis ) - u) / (2*EE); - ret.m_semiMajorAxis = ret.m_semiMajorAxis/fabs(1.0-ret.m_eccentricity); + ret.m_semiMajorAxis = 2 * EE * LLSqr + u * u; + if (ret.m_semiMajorAxis < 0) ret.m_semiMajorAxis = 0; + ret.m_semiMajorAxis = (sqrt(ret.m_semiMajorAxis) - u) / (2 * EE); + ret.m_semiMajorAxis = ret.m_semiMajorAxis / fabs(1.0 - ret.m_eccentricity); // The formulas for rotation matrix were derived based on following assumptions: // 1. Trajectory follows Kepler's law and vector {-r cos(v), -r sin(v), 0}, r(t) and v(t) are parameters. // 2. Correct transformation must transform {0,0,LL} to ang and {-r_now cos(orbitalPhaseAtStart), -r_now sin(orbitalPhaseAtStart), 0} to pos. // 3. orbitalPhaseAtStart (=offset) is calculated from r = a ((e^2 - 1)/(1 + e cos(v) )) - const double angle1 = acos(Clamp(ang.z/LL ,-1 + 1e-6,1 - 1e-6)) * (ang.x > 0 ? -1 : 1); - const double angle2 = asin(Clamp(ang.y / (LL * sqrt(1.0 - ang.z*ang.z / LLSqr)), -1 + 1e-6, 1 - 1e-6) ) * (ang.x > 0 ? -1 : 1); + const double angle1 = acos(Clamp(ang.z / LL, -1 + 1e-6, 1 - 1e-6)) * (ang.x > 0 ? -1 : 1); + const double angle2 = asin(Clamp(ang.y / (LL * sqrt(1.0 - ang.z * ang.z / LLSqr)), -1 + 1e-6, 1 - 1e-6)) * (ang.x > 0 ? -1 : 1); // There are two possible solutions of the equation and the only way how to find the correct one // I know about is to try both and check if the position is transformed correctly. We minimize the difference @@ -326,20 +331,20 @@ Orbit Orbit::FromBodyState(const vector3d &pos, const vector3d &vel, double cent matrix3x3d mat; if (ret.m_eccentricity < 1) { - off = ret.m_semiMajorAxis*(1 - ret.m_eccentricity*ret.m_eccentricity) - r_now; + off = ret.m_semiMajorAxis * (1 - ret.m_eccentricity * ret.m_eccentricity) - r_now; } else { - off = ret.m_semiMajorAxis*(-1 + ret.m_eccentricity*ret.m_eccentricity) - r_now; + off = ret.m_semiMajorAxis * (-1 + ret.m_eccentricity * ret.m_eccentricity) - r_now; } // correct sign of offset is given by sign pos.Dot(vel) (heading towards apohelion or perihelion?] - off = Clamp(off/(r_now * ret.m_eccentricity), -1 + 1e-6,1 - 1e-6); - off = -pos.Dot(vel)/fabs(pos.Dot(vel))*acos(off); + off = Clamp(off / (r_now * ret.m_eccentricity), -1 + 1e-6, 1 - 1e-6); + off = -pos.Dot(vel) / fabs(pos.Dot(vel)) * acos(off); - ccc = acos(-pos.z/r_now/sin(angle1)) * i; + ccc = acos(-pos.z / r_now / sin(angle1)) * i; mat = matrix3x3d::RotateZ(angle2) * matrix3x3d::RotateY(angle1) * matrix3x3d::RotateZ(ccc - off); - if (((mat*vector3d(-r_now*cos(off),r_now*sin(off),0)) - pos).Length() < value) { - value = ((mat*vector3d(-r_now*cos(off),r_now*sin(off),0)) - pos).Length(); + if (((mat * vector3d(-r_now * cos(off), r_now * sin(off), 0)) - pos).Length() < value) { + value = ((mat * vector3d(-r_now * cos(off), r_now * sin(off), 0)) - pos).Length(); cc = ccc; offset = off; } diff --git a/src/Orbit.h b/src/Orbit.h index 6f2fdf960..af9e6c9b6 100644 --- a/src/Orbit.h +++ b/src/Orbit.h @@ -5,8 +5,8 @@ #define ORBIT_H #include "libs.h" -#include "vector3.h" #include "matrix3x3.h" +#include "vector3.h" class Orbit { public: @@ -17,7 +17,7 @@ public: // note: the resulting Orbit is at the given position at t=0 static Orbit FromBodyState(const vector3d &position, const vector3d &velocity, double central_mass); - Orbit(): + Orbit() : m_eccentricity(0.0), m_semiMajorAxis(0.0), m_orbitalPhaseAtStart(0.0), @@ -27,7 +27,8 @@ public: void SetShapeAroundBarycentre(double semiMajorAxis, double totalMass, double bodyMass, double eccentricity); void SetShapeAroundPrimary(double semiMajorAxis, double totalMass, double eccentricity); - void SetPlane(const matrix3x3d &orient) { + void SetPlane(const matrix3x3d &orient) + { m_orient = orient; assert(!std::isnan(m_orient[0]) && !std::isnan(m_orient[1]) && !std::isnan(m_orient[2])); assert(!std::isnan(m_orient[3]) && !std::isnan(m_orient[4]) && !std::isnan(m_orient[5])); @@ -36,7 +37,7 @@ public: void SetPhase(double orbitalPhaseAtStart) { m_orbitalPhaseAtStart = orbitalPhaseAtStart; } vector3d OrbitalPosAtTime(double t) const; - double OrbitalTimeAtPos(const vector3d& pos, double centralMass) const; + double OrbitalTimeAtPos(const vector3d &pos, double centralMass) const; vector3d OrbitalVelocityAtTime(double totalMass, double t) const; // 0.0 <= t <= 1.0. Not for finding orbital pos diff --git a/src/Pi.h b/src/Pi.h index ff1d5e9d0..a66c5d9f9 100644 --- a/src/Pi.h +++ b/src/Pi.h @@ -4,18 +4,18 @@ #ifndef _PI_H #define _PI_H -#include "utils.h" -#include "gui/Gui.h" -#include "Input.h" -#include "Random.h" -#include "gameconsts.h" +#include "CargoBody.h" #include "GameConfig.h" +#include "Input.h" +#include "JobQueue.h" #include "LuaSerializer.h" #include "LuaTimer.h" -#include "CargoBody.h" +#include "Random.h" #include "Space.h" -#include "JobQueue.h" #include "galaxy/Galaxy.h" +#include "gameconsts.h" +#include "gui/Gui.h" +#include "utils.h" #include #include #include @@ -36,10 +36,18 @@ class SDLGraphics; #if ENABLE_SERVER_AGENT class ServerAgent; #endif -namespace Graphics { class Renderer; } -namespace SceneGraph { class Model; } -namespace Sound { class MusicPlayer; } -namespace UI { class Context; } +namespace Graphics { + class Renderer; +} +namespace SceneGraph { + class Model; +} +namespace Sound { + class MusicPlayer; +} +namespace UI { + class Context; +} #if WITH_OBJECTVIEWER class ObjectViewerView; @@ -47,7 +55,11 @@ class ObjectViewerView; class DetailLevel { public: - DetailLevel() : planets(0), textures(0), fracmult(0), cities(0) {} + DetailLevel() : + planets(0), + textures(0), + fracmult(0), + cities(0) {} int planets; int textures; int fracmult; @@ -59,7 +71,7 @@ class Game; class Pi { public: - static void Init(const std::map &options, bool no_gui = false); + static void Init(const std::map &options, bool no_gui = false); static void InitGame(); static void StartGame(); static void RequestEndGame(); // request that the game is ended as soon as safely possible @@ -84,13 +96,13 @@ public: static void SetMouseGrab(bool on); static bool DoingMouseGrab() { return doingMouseGrab; } - // Get the default speed modifier to apply to movement (scrolling, zooming...), depending on the "shift" keys. + // Get the default speed modifier to apply to movement (scrolling, zooming...), depending on the "shift" keys. // This is a default value only, centralized here to promote uniform user expericience. static float GetMoveSpeedShiftModifier(); static void BoinkNoise(); static std::string GetSaveDir(); - static SceneGraph::Model *FindModel(const std::string&, bool allowPlaceholder = true); + static SceneGraph::Model *FindModel(const std::string &, bool allowPlaceholder = true); static void CreateRenderTarget(const Uint16 width, const Uint16 height); static void DrawRenderTarget(); @@ -122,9 +134,14 @@ public: static void SetView(View *v); static View *GetView() { return currentView; } - static void SetAmountBackgroundStars(const float pc) { amountOfBackgroundStarsDisplayed = Clamp(pc, 0.01f, 1.0f); bRefreshBackgroundStars = true; } + static void SetAmountBackgroundStars(const float pc) + { + amountOfBackgroundStarsDisplayed = Clamp(pc, 0.01f, 1.0f); + bRefreshBackgroundStars = true; + } static float GetAmountBackgroundStars() { return amountOfBackgroundStarsDisplayed; } - static bool MustRefreshBackgroundClearFlag() { + static bool MustRefreshBackgroundClearFlag() + { const bool bRet = bRefreshBackgroundStars; bRefreshBackgroundStars = false; return bRet; @@ -154,15 +171,14 @@ public: static DetailLevel detail; static GameConfig *config; - static JobQueue *GetAsyncJobQueue() { return asyncJobQueue.get();} - static JobQueue *GetSyncJobQueue() { return syncJobQueue.get();} + static JobQueue *GetAsyncJobQueue() { return asyncJobQueue.get(); } + static JobQueue *GetSyncJobQueue() { return syncJobQueue.get(); } static bool DrawGUI; private: // msgs/requests that can be posted which the game processes at the end of a game loop in HandleRequests - enum InternalRequests - { + enum InternalRequests { END_GAME = 0, QUIT_GAME, }; diff --git a/src/PiGui.cpp b/src/PiGui.cpp index 1466b8895..ece85849b 100644 --- a/src/PiGui.cpp +++ b/src/PiGui.cpp @@ -1,9 +1,9 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "PiGui.h" #include "Pi.h" #include "graphics/opengl/TextureGL.h" // nasty, usage of GL is implementation specific -#include "PiGui.h" // Use GLEW instead of GL3W. #define IMGUI_IMPL_OPENGL_LOADER_GLEW 1 #include "imgui/examples/imgui_impl_opengl3.h" @@ -12,46 +12,47 @@ #define IMGUI_DEFINE_MATH_OPERATORS true #include "imgui/imgui_internal.h" +#include #include #include -#include #define NANOSVG_IMPLEMENTATION #include "nanosvg/nanosvg.h" #define NANOSVGRAST_IMPLEMENTATION #include "nanosvg/nanosvgrast.h" +std::vector PiGui::m_svg_textures; -std::vector PiGui::m_svg_textures; - -static int to_keycode(int key) { +static int to_keycode(int key) +{ /*if(key & SDLK_SCANCODE_MASK) { return (key & ~SDLK_SCANCODE_MASK) | 0x100; }*/ return key; } -static std::vector> keycodes -= { {"left", to_keycode(SDLK_LEFT) }, - {"right", to_keycode(SDLK_RIGHT)}, - {"up", to_keycode(SDLK_UP)}, - {"down", to_keycode(SDLK_DOWN)}, - {"escape", to_keycode(SDLK_ESCAPE)}, - {"f1", to_keycode(SDLK_F1)}, - {"f2", to_keycode(SDLK_F2)}, - {"f3", to_keycode(SDLK_F3)}, - {"f4", to_keycode(SDLK_F4)}, - {"f5", to_keycode(SDLK_F5)}, - {"f6", to_keycode(SDLK_F6)}, - {"f7", to_keycode(SDLK_F7)}, - {"f8", to_keycode(SDLK_F8)}, - {"f9", to_keycode(SDLK_F9)}, - {"f10", to_keycode(SDLK_F10)}, - {"f11", to_keycode(SDLK_F11)}, - {"f12", to_keycode(SDLK_F12)}, - {"tab", to_keycode(SDLK_TAB)}, +static std::vector> keycodes = { + { "left", to_keycode(SDLK_LEFT) }, + { "right", to_keycode(SDLK_RIGHT) }, + { "up", to_keycode(SDLK_UP) }, + { "down", to_keycode(SDLK_DOWN) }, + { "escape", to_keycode(SDLK_ESCAPE) }, + { "f1", to_keycode(SDLK_F1) }, + { "f2", to_keycode(SDLK_F2) }, + { "f3", to_keycode(SDLK_F3) }, + { "f4", to_keycode(SDLK_F4) }, + { "f5", to_keycode(SDLK_F5) }, + { "f6", to_keycode(SDLK_F6) }, + { "f7", to_keycode(SDLK_F7) }, + { "f8", to_keycode(SDLK_F8) }, + { "f9", to_keycode(SDLK_F9) }, + { "f10", to_keycode(SDLK_F10) }, + { "f11", to_keycode(SDLK_F11) }, + { "f12", to_keycode(SDLK_F12) }, + { "tab", to_keycode(SDLK_TAB) }, }; -ImTextureID PiGui::RenderSVG(std::string svgFilename, int width, int height) { +ImTextureID PiGui::RenderSVG(std::string svgFilename, int width, int height) +{ Output("nanosvg: %s %dx%d\n", svgFilename.c_str(), width, height); // // re-use existing texture if already loaded @@ -67,7 +68,7 @@ ImTextureID PiGui::RenderSVG(std::string svgFilename, int width, int height) { NSVGimage *image = NULL; NSVGrasterizer *rast = NULL; - unsigned char* img = NULL; + unsigned char *img = NULL; int w; // size of each icon // int size = 64; @@ -77,7 +78,7 @@ ImTextureID PiGui::RenderSVG(std::string svgFilename, int width, int height) { // 16 rows // int H = 16*size; int H = height; - img = static_cast(malloc(W*H*4)); + img = static_cast(malloc(W * H * 4)); memset(img, 0, W * H * 4); image = nsvgParseFromFile(svgFilename.c_str(), "px", 96.0f); if (image == NULL) { @@ -94,19 +95,20 @@ ImTextureID PiGui::RenderSVG(std::string svgFilename, int width, int height) { Error("Could not alloc image buffer.\n"); } { - float scale = double(W)/w; + float scale = double(W) / w; float tx = 0; float ty = 0; - nsvgRasterize(rast, image, tx, ty, scale, img, W, H, W*4); + nsvgRasterize(rast, image, tx, ty, scale, img, W, H, W * 4); } nsvgDeleteRasterizer(rast); nsvgDelete(image); return makeTexture(img, W, H); } -ImFont *PiGui::GetFont(const std::string &name, int size) { +ImFont *PiGui::GetFont(const std::string &name, int size) +{ auto iter = m_fonts.find(std::make_pair(name, size)); - if(iter != m_fonts.end()) + if (iter != m_fonts.end()) return iter->second; // Output("GetFont: adding font %s at %i on demand\n", name.c_str(), size); ImFont *font = AddFont(name, size); @@ -114,21 +116,22 @@ ImFont *PiGui::GetFont(const std::string &name, int size) { return font; } -void PiGui::AddGlyph(ImFont *font, unsigned short glyph) { +void PiGui::AddGlyph(ImFont *font, unsigned short glyph) +{ // range glyph..glyph auto iter = m_im_fonts.find(font); - if(iter == m_im_fonts.end()) { + if (iter == m_im_fonts.end()) { Error("Cannot find font instance for ImFont %p\n", font); assert(false); } auto pifont_iter = m_pi_fonts.find(iter->second); - if(pifont_iter == m_pi_fonts.end()) { + if (pifont_iter == m_pi_fonts.end()) { Error("No registered PiFont for name %s size %i\n", iter->second.first.c_str(), iter->second.second); assert(false); } PiFont &pifont = pifont_iter->second; - for(PiFace &face : pifont.faces()) { - if(face.containsGlyph(glyph)) { + for (PiFace &face : pifont.faces()) { + if (face.containsGlyph(glyph)) { face.addGlyph(glyph); m_should_bake_fonts = true; return; @@ -137,14 +140,15 @@ void PiGui::AddGlyph(ImFont *font, unsigned short glyph) { Error("No face in font %s handles glyph %i\n", pifont.name().c_str(), glyph); } -ImFont *PiGui::AddFont(const std::string &name, int size) { +ImFont *PiGui::AddFont(const std::string &name, int size) +{ auto iter = m_font_definitions.find(name); - if(iter == m_font_definitions.end()) { + if (iter == m_font_definitions.end()) { Error("No font definition with name %s\n", name.c_str()); assert(false); } - auto existing = m_fonts.find(std::make_pair(name,size)); - if(existing != m_fonts.end()) { + auto existing = m_fonts.find(std::make_pair(name, size)); + if (existing != m_fonts.end()) { Error("Font %s already exists at size %i\n", name.c_str(), size); assert(false); } @@ -152,14 +156,15 @@ ImFont *PiGui::AddFont(const std::string &name, int size) { PiFont &pifont = iter->second; pifont.setPixelsize(size); pifont.faces().back().addGlyph(0x20); // only add space - m_pi_fonts[std::make_pair(name,size)] = pifont; + m_pi_fonts[std::make_pair(name, size)] = pifont; m_should_bake_fonts = true; - return m_fonts[std::make_pair(name,size)]; + return m_fonts[std::make_pair(name, size)]; } -void PiGui::RefreshFontsTexture() { +void PiGui::RefreshFontsTexture() +{ // TODO: fix this, do the right thing, don't just re-create *everything* :) ImGui::GetIO().Fonts->Build(); ImGui_ImplOpenGL3_CreateDeviceObjects(); @@ -167,10 +172,11 @@ void PiGui::RefreshFontsTexture() { void PiDefaultStyle(ImGuiStyle &style) { - style.WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. + style.WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. } -void PiGui::Init(SDL_Window *window) { +void PiGui::Init(SDL_Window *window) +{ m_handlers.Unref(); lua_State *l = Lua::manager->GetLuaState(); @@ -180,7 +186,7 @@ void PiGui::Init(SDL_Window *window) { lua_newtable(l); m_keys = LuaRef(l, -1); LuaTable keys(l, -1); - for(auto p : keycodes) { + for (auto p : keycodes) { keys.Set(p.first, p.second); } @@ -191,8 +197,7 @@ void PiGui::Init(SDL_Window *window) { // unused, but that is slated to change very soon. // We will need to fill this with a valid pointer to the OpenGL context. ImGui_ImplSDL2_InitForOpenGL(window, NULL); - switch(Pi::renderer->GetRendererType()) - { + switch (Pi::renderer->GetRendererType()) { default: case Graphics::RENDERER_DUMMY: Error("RENDERER_DUMMY is not a valid renderer, aborting."); @@ -215,10 +220,9 @@ void PiGui::Init(SDL_Window *window) { char *ioIniFilename = new char[imguiIni.size() + 1]; std::strncpy(ioIniFilename, imguiIni.c_str(), imguiIni.size() + 1); io.IniFilename = ioIniFilename; - } -int PiGui::RadialPopupSelectMenu(const ImVec2& center, std::string popup_id, int mouse_button, std::vector tex_ids, std::vector> uvs, unsigned int size, std::vector tooltips) +int PiGui::RadialPopupSelectMenu(const ImVec2 ¢er, std::string popup_id, int mouse_button, std::vector tex_ids, std::vector> uvs, unsigned int size, std::vector tooltips) { // return: // 0 - n for item selected @@ -229,35 +233,35 @@ int PiGui::RadialPopupSelectMenu(const ImVec2& center, std::string popup_id, int // FIXME: Missing a call to query if Popup is open so we can move the PushStyleColor inside the BeginPopupBlock (e.g. IsPopupOpen() in imgui.cpp) // FIXME: Our PathFill function only handle convex polygons, so we can't have items spanning an arc too large else inner concave edge artifact is too visible, hence the ImMax(7,items_count) - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0,0,0,0)); - ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0,0,0,0)); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0,0,0,0)); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); if (ImGui::BeginPopup(popup_id.c_str())) { ret = -1; const ImVec2 drag_delta = ImVec2(ImGui::GetIO().MousePos.x - center.x, ImGui::GetIO().MousePos.y - center.y); - const float drag_dist2 = drag_delta.x*drag_delta.x + drag_delta.y*drag_delta.y; + const float drag_dist2 = drag_delta.x * drag_delta.x + drag_delta.y * drag_delta.y; - const ImGuiStyle& style = ImGui::GetStyle(); + const ImGuiStyle &style = ImGui::GetStyle(); const float RADIUS_MIN = 20.0f; const float RADIUS_MAX = 90.0f; const float RADIUS_INTERACT_MIN = 20.0f; const int ITEMS_MIN = 4; const float border_inout = 12.0f; const float border_thickness = 4.0f; - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImDrawList *draw_list = ImGui::GetWindowDrawList(); draw_list->PushClipRectFullScreen(); - draw_list->PathArcTo(center, (RADIUS_MIN + RADIUS_MAX)*0.5f, 0.0f, IM_PI*2.0f*0.99f, 64); // FIXME: 0.99f look like full arc with closed thick stroke has a bug now - draw_list->PathStroke(ImColor(18,44,67,210), true, RADIUS_MAX - RADIUS_MIN); + draw_list->PathArcTo(center, (RADIUS_MIN + RADIUS_MAX) * 0.5f, 0.0f, IM_PI * 2.0f * 0.99f, 64); // FIXME: 0.99f look like full arc with closed thick stroke has a bug now + draw_list->PathStroke(ImColor(18, 44, 67, 210), true, RADIUS_MAX - RADIUS_MIN); - const float item_arc_span = 2*IM_PI / ImMax(ITEMS_MIN, tex_ids.size()); + const float item_arc_span = 2 * IM_PI / ImMax(ITEMS_MIN, tex_ids.size()); float drag_angle = atan2f(drag_delta.y, drag_delta.x); - if (drag_angle < -0.5f*item_arc_span) - drag_angle += 2.0f*IM_PI; + if (drag_angle < -0.5f * item_arc_span) + drag_angle += 2.0f * IM_PI; int item_hovered = -1; int item_n = 0; - for(ImTextureID tex_id : tex_ids) { - const char* tooltip = tooltips.at(item_n).c_str(); + for (ImTextureID tex_id : tex_ids) { + const char *tooltip = tooltips.at(item_n).c_str(); const float inner_spacing = style.ItemInnerSpacing.x / RADIUS_MIN / 2; const float item_inner_ang_min = item_arc_span * (item_n - 0.5f + inner_spacing); const float item_inner_ang_max = item_arc_span * (item_n + 0.5f - inner_spacing); @@ -265,33 +269,33 @@ int PiGui::RadialPopupSelectMenu(const ImVec2& center, std::string popup_id, int const float item_outer_ang_max = item_arc_span * (item_n + 0.5f - inner_spacing * (RADIUS_MIN / RADIUS_MAX)); bool hovered = false; - if (drag_dist2 >= RADIUS_INTERACT_MIN*RADIUS_INTERACT_MIN) { + if (drag_dist2 >= RADIUS_INTERACT_MIN * RADIUS_INTERACT_MIN) { if (drag_angle >= item_inner_ang_min && drag_angle < item_inner_ang_max) hovered = true; } bool selected = false; - int arc_segments = static_cast((64 * item_arc_span / (2*IM_PI))) + 1; + int arc_segments = static_cast((64 * item_arc_span / (2 * IM_PI))) + 1; draw_list->PathArcTo(center, RADIUS_MAX - border_inout, item_outer_ang_min, item_outer_ang_max, arc_segments); draw_list->PathArcTo(center, RADIUS_MIN + border_inout, item_inner_ang_max, item_inner_ang_min, arc_segments); - draw_list->PathFillConvex(hovered ? ImColor(102,147,189) : selected ? ImColor(48,81,111) : ImColor(48,81,111)); - if(hovered) { + draw_list->PathFillConvex(hovered ? ImColor(102, 147, 189) : selected ? ImColor(48, 81, 111) : ImColor(48, 81, 111)); + if (hovered) { // draw outer / inner extra segments draw_list->PathArcTo(center, RADIUS_MAX - border_thickness, item_outer_ang_min, item_outer_ang_max, arc_segments); - draw_list->PathStroke(ImColor(102,147,189), false, border_thickness); + draw_list->PathStroke(ImColor(102, 147, 189), false, border_thickness); draw_list->PathArcTo(center, RADIUS_MIN + border_thickness, item_outer_ang_min, item_outer_ang_max, arc_segments); - draw_list->PathStroke(ImColor(102,147,189), false, border_thickness); + draw_list->PathStroke(ImColor(102, 147, 189), false, border_thickness); } ImVec2 text_size = ImVec2(size, size); ImVec2 text_pos = ImVec2( - center.x + cosf((item_inner_ang_min + item_inner_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.x * 0.5f, - center.y + sinf((item_inner_ang_min + item_inner_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.y * 0.5f); - draw_list->AddImage(tex_id, text_pos, ImVec2(text_pos.x+size,text_pos.y+size), uvs[item_n].first, uvs[item_n].second); ImGui::SameLine(); + center.x + cosf((item_inner_ang_min + item_inner_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.x * 0.5f, + center.y + sinf((item_inner_ang_min + item_inner_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.y * 0.5f); + draw_list->AddImage(tex_id, text_pos, ImVec2(text_pos.x + size, text_pos.y + size), uvs[item_n].first, uvs[item_n].second); + ImGui::SameLine(); if (hovered) { item_hovered = item_n; ImGui::SetTooltip("%s", tooltip); - } item_n++; } @@ -299,26 +303,27 @@ int PiGui::RadialPopupSelectMenu(const ImVec2& center, std::string popup_id, int if (ImGui::IsMouseReleased(mouse_button)) { ImGui::CloseCurrentPopup(); - if(item_hovered == -1) + if (item_hovered == -1) ret = -2; else ret = item_hovered; } ImGui::EndPopup(); } else { - // Output("WARNING: RadialPopupSelectMenu BeginPopup failed: %s\n", popup_id.c_str()); + // Output("WARNING: RadialPopupSelectMenu BeginPopup failed: %s\n", popup_id.c_str()); } ImGui::PopStyleColor(3); return ret; } -bool PiGui::CircularSlider(const ImVec2 ¢er, float *v, float v_min, float v_max) { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - ImGuiWindow* window = ImGui::GetCurrentWindow(); +bool PiGui::CircularSlider(const ImVec2 ¢er, float *v, float v_min, float v_max) +{ + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + ImGuiWindow *window = ImGui::GetCurrentWindow(); const ImGuiID id = window->GetID("circularslider"); draw_list->AddCircle(center, 17, ImColor(100, 100, 100), 128, 12.0); draw_list->PathArcTo(center, 17, 0, M_PI * 2.0 * (*v - v_min) / (v_max - v_min), 64); - draw_list->PathStroke(ImColor(200,200,200), false, 12.0); + draw_list->PathStroke(ImColor(200, 200, 200), false, 12.0); ImRect grab_bb; return ImGui::SliderBehavior(ImRect(center.x - 17, center.y - 17, center.x + 17, center.y + 17), id, ImGuiDataType_Float, v, &v_min, &v_max, "%.4f", 1.0, ImGuiSliderFlags_None, &grab_bb); @@ -346,24 +351,26 @@ void *PiGui::makeTexture(unsigned char *pixels, int width, int height) // Update it with the actual pixels, this is a two step process due to legacy code pTex->Update(pixels, dataSize, Graphics::TEXTURE_RGBA_8888); // nasty bit as I invoke the TextureGL - Graphics::OGL::TextureGL *pGLTex = reinterpret_cast(pTex); + Graphics::OGL::TextureGL *pGLTex = reinterpret_cast(pTex); Uint32 result = pGLTex->GetTextureID(); - m_svg_textures.push_back( pTex ); // store for cleanup later - return reinterpret_cast(result); + m_svg_textures.push_back(pTex); // store for cleanup later + return reinterpret_cast(result); } -void PiGui::EndFrame() { +void PiGui::EndFrame() +{ ImGui::EndFrame(); } -void PiGui::NewFrame(SDL_Window *window) { +void PiGui::NewFrame(SDL_Window *window) +{ // Ask ImGui to hide OS cursor if GUI is not being drawn: // it will do this if MouseDrawCursor is true. After the frame // is created, we set the actual cursor draw state. if (!Pi::DrawGUI) { ImGui::GetIO().MouseDrawCursor = true; } - switch(Pi::renderer->GetRendererType()) { + switch (Pi::renderer->GetRendererType()) { default: case Graphics::RENDERER_DUMMY: Error("RENDERER_DUMMY is not a valid renderer, aborting."); @@ -386,9 +393,10 @@ void PiGui::NewFrame(SDL_Window *window) { } #endif } -void PiGui::Render(double delta, std::string handler) { +void PiGui::Render(double delta, std::string handler) +{ ScopedTable t(m_handlers); - if(t.Get(handler)) { + if (t.Get(handler)) { t.Call(handler, delta); Pi::renderer->CheckRenderErrors(__FUNCTION__, __LINE__); } @@ -397,12 +405,12 @@ void PiGui::Render(double delta, std::string handler) { EndFrame(); // Iterate through our fonts and check if IMGUI wants a character we don't have. - for(auto &iter : m_fonts) { + for (auto &iter : m_fonts) { ImFont *font = iter.second; // font might be nullptr, if it wasn't baked yet - if(font && font->AreGlyphsMissing()) { + if (font && font->AreGlyphsMissing()) { // Output("%s %i is missing glyphs.\n", iter.first.first.c_str(), iter.first.second); - for(auto &glyph : font->MissingGlyphs()) { + for (auto &glyph : font->MissingGlyphs()) { AddGlyph(font, glyph); } font->ResetMissingGlyphs(); @@ -410,15 +418,16 @@ void PiGui::Render(double delta, std::string handler) { } // Bake fonts *after* a frame is done, so the font atlas is not needed any longer - if(m_should_bake_fonts) { + if (m_should_bake_fonts) { BakeFonts(); } } -void PiGui::RenderImGui() { +void PiGui::RenderImGui() +{ ImGui::Render(); - switch(Pi::renderer->GetRendererType()) { + switch (Pi::renderer->GetRendererType()) { default: case Graphics::RENDERER_DUMMY: return; @@ -428,7 +437,8 @@ void PiGui::RenderImGui() { } } -void PiGui::ClearFonts() { +void PiGui::ClearFonts() +{ ImGuiIO &io = ImGui::GetIO(); // TODO: should also release all glyph_ranges... m_fonts.clear(); @@ -436,31 +446,33 @@ void PiGui::ClearFonts() { io.Fonts->Clear(); } -void PiGui::BakeFont(PiFont &font) { +void PiGui::BakeFont(PiFont &font) +{ ImGuiIO &io = ImGui::GetIO(); ImFont *imfont = nullptr; - for(PiFace &face : font.faces()) { + for (PiFace &face : font.faces()) { ImFontConfig config; config.MergeMode = true; float size = font.pixelsize() * face.sizefactor(); const std::string path = FileSystem::JoinPath(FileSystem::JoinPath(FileSystem::GetDataDir(), "fonts"), face.ttfname()); // Output("- baking face %s at size %f\n", path.c_str(), size); face.sortUsedRanges(); - if(face.used_ranges().size() > 0) { + if (face.used_ranges().size() > 0) { face.m_imgui_ranges.clear(); ImFontAtlas::GlyphRangesBuilder gb; // Always include the default range gb.AddRanges(io.Fonts->GetGlyphRangesDefault()); ImWchar gr[3] = { 0, 0, 0 }; - for(auto &range : face.used_ranges()) { + for (auto &range : face.used_ranges()) { // Output("Used range: %x - %x", range.first, range.second); - gr[0] = range.first; gr[1] = range.second; + gr[0] = range.first; + gr[1] = range.second; gb.AddRanges(gr); } gb.BuildRanges(&face.m_imgui_ranges); ImFont *f = io.Fonts->AddFontFromFileTTF(path.c_str(), size, imfont == nullptr ? nullptr : &config, face.m_imgui_ranges.Data); assert(f); - if(imfont != nullptr) + if (imfont != nullptr) assert(f == imfont); imfont = f; } @@ -468,18 +480,19 @@ void PiGui::BakeFont(PiFont &font) { m_im_fonts[imfont] = std::make_pair(font.name(), font.pixelsize()); // Output("setting %s %i to %p\n", font.name(), font.pixelsize(), imfont); m_fonts[std::make_pair(font.name(), font.pixelsize())] = imfont; - if(imfont->AreGlyphsMissing()) { + if (imfont->AreGlyphsMissing()) { Output("WARNING: glyphs missing in shiny new font\n"); } imfont->ResetMissingGlyphs(); } -void PiGui::BakeFonts() { +void PiGui::BakeFonts() +{ // Output("Baking fonts\n"); m_should_bake_fonts = false; - if(m_pi_fonts.size() == 0) { + if (m_pi_fonts.size() == 0) { // Output("No fonts to bake.\n"); return; } @@ -489,9 +502,9 @@ void PiGui::BakeFonts() { // first bake tooltip/default font BakeFont(m_pi_fonts[std::make_pair("pionillium", 14)]); - for(auto &iter : m_pi_fonts) { + for (auto &iter : m_pi_fonts) { // don't bake tooltip/default font again - if(!(iter.first.first == "pionillium" && iter.first.second == 14)) + if (!(iter.first.first == "pionillium" && iter.first.second == 14)) BakeFont(iter.second); // Output("Fonts registered: %i\n", io.Fonts->Fonts.Size); } @@ -499,10 +512,11 @@ void PiGui::BakeFonts() { RefreshFontsTexture(); } -static void drawThrust(ImDrawList* draw_list, const ImVec2 ¢er, const ImVec2 &up, float value, const ImColor &fg, const ImColor &bg) { +static void drawThrust(ImDrawList *draw_list, const ImVec2 ¢er, const ImVec2 &up, float value, const ImColor &fg, const ImColor &bg) +{ float factor = 0.1; // how much to offset from center const ImVec2 step(up.x * 0.5, up.y * 0.5); - const ImVec2 left(-step.y * (1.0-factor), step.x * (1.0-factor)); + const ImVec2 left(-step.y * (1.0 - factor), step.x * (1.0 - factor)); const ImVec2 u(up.x * (1.0 - factor), up.y * (1.0 - factor)); const ImVec2 c(center + ImVec2(u.x * factor, u.y * factor)); const ImVec2 right(-left.x, -left.y); @@ -516,19 +530,19 @@ static void drawThrust(ImDrawList* draw_list, const ImVec2 ¢er, const ImVec2 const ImVec2 maximum(fmax(bb_upperleft.x, bb_lowerright.x), fmax(bb_upperleft.y, bb_lowerright.y)); ImVec2 points[] = { c, leftmiddle, lefttop, righttop, rightmiddle }; draw_list->AddConvexPolyFilled(points, 5, bg); - draw_list->PushClipRect(minimum - ImVec2(1,1), maximum + ImVec2(1,1)); + draw_list->PushClipRect(minimum - ImVec2(1, 1), maximum + ImVec2(1, 1)); draw_list->AddConvexPolyFilled(points, 5, fg); draw_list->PopClipRect(); } -void PiGui::ThrustIndicator(const std::string &id_string, const ImVec2& size_arg, const ImVec4& thrust, const ImVec4& velocity, const ImVec4 &bg_col, int frame_padding, ImColor vel_fg, ImColor vel_bg, ImColor thrust_fg, ImColor thrust_bg) +void PiGui::ThrustIndicator(const std::string &id_string, const ImVec2 &size_arg, const ImVec4 &thrust, const ImVec4 &velocity, const ImVec4 &bg_col, int frame_padding, ImColor vel_fg, ImColor vel_bg, ImColor thrust_fg, ImColor thrust_bg) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow *window = ImGui::GetCurrentWindow(); if (window->SkipItems) return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext &g = *GImGui; + const ImGuiStyle &style = g.Style; const ImGuiID id = window->GetID(id_string.c_str()); ImVec2 pos = window->DC.CursorPos; @@ -537,7 +551,7 @@ void PiGui::ThrustIndicator(const std::string &id_string, const ImVec2& size_arg ImVec2 size = ImGui::CalcItemSize(size_arg, style.FramePadding.x * 2.0f, style.FramePadding.y * 2.0f); const ImVec2 padding = (frame_padding >= 0) ? ImVec2(static_cast(frame_padding), static_cast(frame_padding)) : style.FramePadding; - const ImRect bb(pos, pos + size + padding*2); + const ImRect bb(pos, pos + size + padding * 2); const ImRect inner_bb(pos + padding, pos + padding + size); ImGui::ItemSize(bb, style.FramePadding.y); @@ -547,21 +561,21 @@ void PiGui::ThrustIndicator(const std::string &id_string, const ImVec2& size_arg // Render const ImU32 col = ImGui::GetColorU32(static_cast(ImGuiCol_Button)); ImGui::RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImDrawList *draw_list = ImGui::GetWindowDrawList(); if (bg_col.w > 0.0f) draw_list->AddRectFilled(inner_bb.Min, inner_bb.Max, ImGui::GetColorU32(bg_col)); const ImVec2 leftupper = inner_bb.Min; const ImVec2 rightlower = inner_bb.Max; const ImVec2 rightcenter((rightlower.x - leftupper.x) * 0.8 + leftupper.x, (rightlower.y + leftupper.y) / 2); const ImVec2 leftcenter((rightlower.x - leftupper.x) * 0.35 + leftupper.x, (rightlower.y + leftupper.y) / 2); - const ImVec2 up(0, - abs(leftupper.y - rightlower.y) * 0.4); + const ImVec2 up(0, -abs(leftupper.y - rightlower.y) * 0.4); const ImVec2 left(-up.y, up.x); - float thrust_fwd = fmax( thrust.z, 0); - float thrust_bwd = fmax(-thrust.z, 0); - float thrust_left = fmax(-thrust.x, 0); - float thrust_right = fmax( thrust.x, 0); - float thrust_up = fmax(-thrust.y, 0); - float thrust_down = fmax( thrust.y, 0); + float thrust_fwd = fmax(thrust.z, 0); + float thrust_bwd = fmax(-thrust.z, 0); + float thrust_left = fmax(-thrust.x, 0); + float thrust_right = fmax(thrust.x, 0); + float thrust_up = fmax(-thrust.y, 0); + float thrust_down = fmax(thrust.y, 0); // actual thrust drawThrust(draw_list, rightcenter, up, thrust_fwd, thrust_fg, thrust_bg); drawThrust(draw_list, rightcenter, ImVec2(-up.x, -up.y), thrust_bwd, thrust_fg, thrust_bg); @@ -583,15 +597,15 @@ void PiGui::ThrustIndicator(const std::string &id_string, const ImVec2& size_arg // CloseCurrentPopup(); } -bool PiGui::LowThrustButton(const char* id_string, const ImVec2& size_arg, int thrust_level, const ImVec4 &bg_col, int frame_padding, ImColor gauge_fg, ImColor gauge_bg) +bool PiGui::LowThrustButton(const char *id_string, const ImVec2 &size_arg, int thrust_level, const ImVec4 &bg_col, int frame_padding, ImColor gauge_fg, ImColor gauge_bg) { std::string label = std::to_string(thrust_level); - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow *window = ImGui::GetCurrentWindow(); if (window->SkipItems) return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext &g = *GImGui; + const ImGuiStyle &style = g.Style; const ImGuiID id = window->GetID(id_string); const ImVec2 label_size = ImGui::CalcTextSize(label.c_str(), NULL, true); @@ -601,7 +615,7 @@ bool PiGui::LowThrustButton(const char* id_string, const ImVec2& size_arg, int t ImVec2 size = ImGui::CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); const ImVec2 padding = (frame_padding >= 0) ? ImVec2(static_cast(frame_padding), static_cast(frame_padding)) : style.FramePadding; - const ImRect bb(pos, pos + size + padding*2); + const ImRect bb(pos, pos + size + padding * 2); const ImRect inner_bb(pos + padding, pos + padding + size); ImGui::ItemSize(bb, style.FramePadding.y); @@ -618,14 +632,14 @@ bool PiGui::LowThrustButton(const char* id_string, const ImVec2& size_arg, int t const ImVec2 center = (inner_bb.Min + inner_bb.Max) / 2; float radius = (inner_bb.Max.x - inner_bb.Min.x) * 0.4; float thickness = 4; - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImDrawList *draw_list = ImGui::GetWindowDrawList(); if (bg_col.w > 0.0f) draw_list->AddRectFilled(inner_bb.Min, inner_bb.Max, ImGui::GetColorU32(bg_col)); draw_list->PathArcTo(center, radius, 0, IM_PI * 2, 16); draw_list->PathStroke(gauge_bg, false, thickness); - draw_list->PathArcTo(center, radius, IM_PI, IM_PI + IM_PI * 2 * (thrust_level / 100.0) , 16); + draw_list->PathArcTo(center, radius, IM_PI, IM_PI + IM_PI * 2 * (thrust_level / 100.0), 16); draw_list->PathStroke(gauge_fg, false, thickness); ImGui::RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label.c_str(), NULL, &label_size, style.ButtonTextAlign, &bb); @@ -636,12 +650,13 @@ bool PiGui::LowThrustButton(const char* id_string, const ImVec2& size_arg, int t return pressed; } -void PiGui::Cleanup() { - for(auto tex : m_svg_textures) { +void PiGui::Cleanup() +{ + for (auto tex : m_svg_textures) { delete tex; } - switch(Pi::renderer->GetRendererType()) { + switch (Pi::renderer->GetRendererType()) { default: case Graphics::RENDERER_DUMMY: return; @@ -654,23 +669,18 @@ void PiGui::Cleanup() { ImGui::DestroyContext(); } -PiGui::PiGui() : m_should_bake_fonts(true) +PiGui::PiGui() : + m_should_bake_fonts(true) { PiFont uiheading("orbiteer", { - PiFace("DejaVuSans.ttf", /*18.0/20.0*/ 1.2, {{0x400, 0x4ff}, {0x500, 0x527}}), - PiFace("wqy-microhei.ttc", 1.0, {{0x4e00, 0x9fff},{0x3400,0x4dff}}), - PiFace("Orbiteer-Bold.ttf", 1.0, {{0, 0xffff}}) // imgui only supports 0xffff, not 0x10ffff - }); - PiFont guifont("pionillium", { - PiFace("DejaVuSans.ttf", 13.0/14.0, {{0x400, 0x4ff}, {0x500, 0x527}}), - PiFace("wqy-microhei.ttc", 1.0, {{0x4e00, 0x9fff},{0x3400,0x4dff}}), - PiFace("PionilliumText22L-Medium.ttf", 1.0, {{0, 0xffff}}) - }); + PiFace("DejaVuSans.ttf", /*18.0/20.0*/ 1.2, { { 0x400, 0x4ff }, { 0x500, 0x527 } }), PiFace("wqy-microhei.ttc", 1.0, { { 0x4e00, 0x9fff }, { 0x3400, 0x4dff } }), PiFace("Orbiteer-Bold.ttf", 1.0, { { 0, 0xffff } }) // imgui only supports 0xffff, not 0x10ffff + }); + PiFont guifont("pionillium", { PiFace("DejaVuSans.ttf", 13.0 / 14.0, { { 0x400, 0x4ff }, { 0x500, 0x527 } }), PiFace("wqy-microhei.ttc", 1.0, { { 0x4e00, 0x9fff }, { 0x3400, 0x4dff } }), PiFace("PionilliumText22L-Medium.ttf", 1.0, { { 0, 0xffff } }) }); AddFontDefinition(uiheading); AddFontDefinition(guifont); // Output("Fonts:\n"); - for(auto entry : m_font_definitions) { + for (auto entry : m_font_definitions) { // Output(" entry %s:\n", entry.first.c_str()); entry.second.describe(); } @@ -679,18 +689,20 @@ PiGui::PiGui() : m_should_bake_fonts(true) GetFont("pionillium", 14); }; -const bool PiFace::containsGlyph(unsigned short glyph) const { - for(auto range : m_ranges) { - if(range.first <= glyph && glyph <= range.second) +const bool PiFace::containsGlyph(unsigned short glyph) const +{ + for (auto range : m_ranges) { + if (range.first <= glyph && glyph <= range.second) return true; } return false; } -void PiFace::addGlyph(unsigned short glyph) { +void PiFace::addGlyph(unsigned short glyph) +{ // Output("- PiFace %s adding glyph 0x%x\n", ttfname().c_str(), glyph); - for(auto &range : m_used_ranges) { - if(range.first <= glyph && glyph <= range.second) { + for (auto &range : m_used_ranges) { + if (range.first <= glyph && glyph <= range.second) { // Output(" - already added, not adding again\n"); return; } @@ -699,19 +711,20 @@ void PiFace::addGlyph(unsigned short glyph) { m_used_ranges.push_back(std::make_pair(glyph, glyph)); } -void PiFace::sortUsedRanges() const { +void PiFace::sortUsedRanges() const +{ // sort by ascending lower end of range std::sort(m_used_ranges.begin(), m_used_ranges.end(), [](const std::pair &a, const std::pair &b) { return a.first < b.first; }); // merge adjacent ranges std::vector> merged; - std::pair current(0xffff,0xffff); - for(auto &range : m_used_ranges) { + std::pair current(0xffff, 0xffff); + for (auto &range : m_used_ranges) { // Output("> checking 0x%x-0x%x\n", range.first, range.second); - if(current.first == 0xffff && current.second == 0xffff) + if (current.first == 0xffff && current.second == 0xffff) current = range; else { // if only a few are missing in range, just merge nontheless. +5 is 4 missing - if(current.second + 5 >= range.first) { // (current.second + 1 == range.first) + if (current.second + 5 >= range.first) { // (current.second + 1 == range.first) // Output("> merging 0x%x-0x%x and 0x%x-0x%x\n", current.first, current.second, range.first, range.second); current.second = range.second; } else { @@ -721,7 +734,7 @@ void PiFace::sortUsedRanges() const { } } } - if(current.first != 0xffff && current.second != 0xffff) + if (current.first != 0xffff && current.second != 0xffff) merged.push_back(current); m_used_ranges.assign(merged.begin(), merged.end()); } diff --git a/src/PiGui.h b/src/PiGui.h index 38798ae1f..649ed338c 100644 --- a/src/PiGui.h +++ b/src/PiGui.h @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "RefCounted.h" -#include "graphics/opengl/RendererGL.h" +#include "FileSystem.h" #include "Lua.h" #include "LuaRef.h" #include "LuaTable.h" -#include "FileSystem.h" +#include "RefCounted.h" +#include "graphics/opengl/RendererGL.h" #include "imgui/imgui.h" class PiFace { @@ -16,9 +16,15 @@ class PiFace { std::vector> m_ranges; mutable std::vector> m_used_ranges; ImVector m_imgui_ranges; + public: - PiFace(const std::string &ttfname, float sizefactor) : m_ttfname(ttfname), m_sizefactor(sizefactor) {} - PiFace(const std::string &ttfname, float sizefactor, const std::vector> &ranges) : m_ttfname(ttfname), m_sizefactor(sizefactor), m_ranges(ranges) {} + PiFace(const std::string &ttfname, float sizefactor) : + m_ttfname(ttfname), + m_sizefactor(sizefactor) {} + PiFace(const std::string &ttfname, float sizefactor, const std::vector> &ranges) : + m_ttfname(ttfname), + m_sizefactor(sizefactor), + m_ranges(ranges) {} const std::string &ttfname() const { return m_ttfname; } const float sizefactor() const { return m_sizefactor; } const std::vector> &ranges() const { return m_ranges; } @@ -32,40 +38,47 @@ class PiFont { std::string m_name; std::vector m_faces; int m_pixelsize; + public: - PiFont(const std::string &name) : m_name(name) {} - PiFont(const std::string &name, const std::vector &faces) : m_name(name), m_faces(faces) {} - PiFont(const PiFont &other) : m_name(other.name()), m_faces(other.faces()) {} - PiFont() : m_name("unknown") {} + PiFont(const std::string &name) : + m_name(name) {} + PiFont(const std::string &name, const std::vector &faces) : + m_name(name), + m_faces(faces) {} + PiFont(const PiFont &other) : + m_name(other.name()), + m_faces(other.faces()) {} + PiFont() : + m_name("unknown") {} const std::vector &faces() const { return m_faces; } std::vector &faces() { return m_faces; } const std::string &name() const { return m_name; } int pixelsize() const { return m_pixelsize; } void setPixelsize(int pixelsize) { m_pixelsize = pixelsize; } - void describe() const { + void describe() const + { Output("font %s:\n", name().c_str()); - for(const PiFace &face : faces()) { + for (const PiFace &face : faces()) { Output("- %s %f\n", face.ttfname().c_str(), face.sizefactor()); } } }; - /* Class to wrap ImGui. */ class PiGui : public RefCounted { - std::map, ImFont*> m_fonts; - std::map> m_im_fonts; - std::map, PiFont> m_pi_fonts; + std::map, ImFont *> m_fonts; + std::map> m_im_fonts; + std::map, PiFont> m_pi_fonts; bool m_should_bake_fonts; - std::map m_font_definitions; + std::map m_font_definitions; void BakeFonts(); void BakeFont(PiFont &font); void AddFontDefinition(const PiFont &font) { m_font_definitions[font.name()] = font; } void ClearFonts(); -public: +public: PiGui(); LuaRef GetHandlers() const { return m_handlers; } @@ -78,7 +91,8 @@ public: ImFont *GetFont(const std::string &name, int size); - void Uninit() { + void Uninit() + { Cleanup(); m_handlers.Unref(); m_keys.Unref(); @@ -101,22 +115,25 @@ public: static void *makeTexture(unsigned char *pixels, int width, int height); - static bool WantCaptureMouse() { + static bool WantCaptureMouse() + { return ImGui::GetIO().WantCaptureMouse; } - static bool WantCaptureKeyboard() { + static bool WantCaptureKeyboard() + { return ImGui::GetIO().WantCaptureKeyboard; } - static int RadialPopupSelectMenu(const ImVec2& center, std::string popup_id, int mouse_button, std::vector tex_ids, std::vector> uvs, unsigned int size, std::vector tooltips); + static int RadialPopupSelectMenu(const ImVec2 ¢er, std::string popup_id, int mouse_button, std::vector tex_ids, std::vector> uvs, unsigned int size, std::vector tooltips); static bool CircularSlider(const ImVec2 ¢er, float *v, float v_min, float v_max); void Cleanup(); - static bool LowThrustButton(const char* label, const ImVec2& size_arg, int thrust_level, const ImVec4 &bg_col, int frame_padding, ImColor gauge_fg, ImColor gauge_bg); + static bool LowThrustButton(const char *label, const ImVec2 &size_arg, int thrust_level, const ImVec4 &bg_col, int frame_padding, ImColor gauge_fg, ImColor gauge_bg); + + static void ThrustIndicator(const std::string &id_string, const ImVec2 &size, const ImVec4 &thrust, const ImVec4 &velocity, const ImVec4 &bg_col, int frame_padding, ImColor vel_fg, ImColor vel_bg, ImColor thrust_fg, ImColor thrust_bg); - static void ThrustIndicator(const std::string &id_string, const ImVec2& size, const ImVec4& thrust, const ImVec4& velocity, const ImVec4 &bg_col, int frame_padding, ImColor vel_fg, ImColor vel_bg, ImColor thrust_fg, ImColor thrust_bg); private: LuaRef m_handlers; LuaRef m_keys; - static std::vector m_svg_textures; + static std::vector m_svg_textures; }; diff --git a/src/Plane.cpp b/src/Plane.cpp index 093c1cafa..5cc19ef4a 100644 --- a/src/Plane.cpp +++ b/src/Plane.cpp @@ -1,14 +1,15 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Plane.h" +#include "libs.h" -double SPlane::DistanceToPoint(const vector3d &p) const { - return a*p.x + b*p.y + c*p.z + d; +double SPlane::DistanceToPoint(const vector3d &p) const +{ + return a * p.x + b * p.y + c * p.z + d; } -SPlane::SPlane(const vector3d& N, const vector3d &P) +SPlane::SPlane(const vector3d &N, const vector3d &P) { const vector3d NormalizedNormal = N.Normalized(); a = NormalizedNormal.x; diff --git a/src/Plane.h b/src/Plane.h index 7f5751045..63fc56dd2 100644 --- a/src/Plane.h +++ b/src/Plane.h @@ -13,8 +13,10 @@ struct SPlane { double a, b, c, d; double DistanceToPoint(const vector3d &p) const; - SPlane() {/*default empty for Frustum*/} - SPlane(const vector3d& N, const vector3d &P); + SPlane() + { /*default empty for Frustum*/ + } + SPlane(const vector3d &N, const vector3d &P); }; #endif /* _GEOPATCH_H */ diff --git a/src/Planet.cpp b/src/Planet.cpp index e79b03a15..1903011b9 100644 --- a/src/Planet.cpp +++ b/src/Planet.cpp @@ -2,39 +2,37 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Planet.h" +#include "Color.h" +#include "GeoSphere.h" #include "Pi.h" #include "WorldView.h" -#include "GeoSphere.h" -#include "perlin.h" -#include "graphics/Material.h" -#include "graphics/Renderer.h" -#include "graphics/RenderState.h" #include "graphics/Graphics.h" +#include "graphics/Material.h" +#include "graphics/RenderState.h" +#include "graphics/Renderer.h" #include "graphics/Texture.h" #include "graphics/VertexArray.h" -#include "Color.h" +#include "perlin.h" #ifdef _MSC_VER - #include "win32/WinMath.h" +#include "win32/WinMath.h" #endif // _MSC_VER using namespace Graphics; -static const Graphics::AttributeSet RING_VERTEX_ATTRIBS - = Graphics::ATTRIB_POSITION - | Graphics::ATTRIB_UV0; +static const Graphics::AttributeSet RING_VERTEX_ATTRIBS = Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0; -Planet::Planet() - : TerrainBody() - , m_ringVertices(RING_VERTEX_ATTRIBS) - , m_ringState(nullptr) +Planet::Planet() : + TerrainBody(), + m_ringVertices(RING_VERTEX_ATTRIBS), + m_ringState(nullptr) { } -Planet::Planet(SystemBody *sbody) - : TerrainBody(sbody) - , m_ringVertices(RING_VERTEX_ATTRIBS) - , m_ringState(nullptr) +Planet::Planet(SystemBody *sbody) : + TerrainBody(sbody), + m_ringVertices(RING_VERTEX_ATTRIBS), + m_ringState(nullptr) { InitParams(sbody); } @@ -53,10 +51,10 @@ void Planet::InitParams(const SystemBody *sbody) double specificHeatCp; double gasMolarMass; if (sbody->GetSuperType() == SystemBody::SUPERTYPE_GAS_GIANT) { - specificHeatCp=12950.0; // constant pressure specific heat, for a combination of hydrogen and helium + specificHeatCp = 12950.0; // constant pressure specific heat, for a combination of hydrogen and helium gasMolarMass = 0.0023139903; } else { - specificHeatCp=1000.5;// constant pressure specific heat, for the combination of gasses that make up air + specificHeatCp = 1000.5; // constant pressure specific heat, for the combination of gasses that make up air // XXX using earth's molar mass of air... gasMolarMass = 0.02897; } @@ -64,29 +62,31 @@ void Planet::InitParams(const SystemBody *sbody) const double PA_2_ATMOS = 1.0 / 101325.0; // surface gravity = -G*M/planet radius^2 - m_surfaceGravity_g = -G*sbody->GetMass()/(sbody->GetRadius()*sbody->GetRadius()); - const double lapseRate_L = -m_surfaceGravity_g/specificHeatCp; // negative deg/m + m_surfaceGravity_g = -G * sbody->GetMass() / (sbody->GetRadius() * sbody->GetRadius()); + const double lapseRate_L = -m_surfaceGravity_g / specificHeatCp; // negative deg/m const double surfaceTemperature_T0 = sbody->GetAverageTemp(); //K - double surfaceDensity, h; Color c; - sbody->GetAtmosphereFlavor(&c, &surfaceDensity);// kg / m^3 - surfaceDensity/=gasMolarMass; // convert to moles/m^3 + double surfaceDensity, h; + Color c; + sbody->GetAtmosphereFlavor(&c, &surfaceDensity); // kg / m^3 + surfaceDensity /= gasMolarMass; // convert to moles/m^3 //P = density*R*T=(n/V)*R*T - const double surfaceP_p0 = PA_2_ATMOS*((surfaceDensity)*GAS_CONSTANT*surfaceTemperature_T0); // in atmospheres - if (surfaceP_p0 < 0.002) h = 0; + const double surfaceP_p0 = PA_2_ATMOS * ((surfaceDensity)*GAS_CONSTANT * surfaceTemperature_T0); // in atmospheres + if (surfaceP_p0 < 0.002) + h = 0; else { //*outPressure = p0*(1-l*h/T0)^(g*M/(R*L); // want height for pressure 0.001 atm: // h = (1 - exp(RL/gM * log(P/p0))) * T0 / l - double RLdivgM = (GAS_CONSTANT*lapseRate_L)/(-m_surfaceGravity_g*gasMolarMass); - h = (1.0 - exp(RLdivgM * log(0.001/surfaceP_p0))) * surfaceTemperature_T0 / lapseRate_L; -// double h2 = (1.0 - pow(0.001/surfaceP_p0, RLdivgM)) * surfaceTemperature_T0 / lapseRate_L; -// double P = surfaceP_p0*pow((1.0-lapseRate_L*h/surfaceTemperature_T0),1/RLdivgM); + double RLdivgM = (GAS_CONSTANT * lapseRate_L) / (-m_surfaceGravity_g * gasMolarMass); + h = (1.0 - exp(RLdivgM * log(0.001 / surfaceP_p0))) * surfaceTemperature_T0 / lapseRate_L; + // double h2 = (1.0 - pow(0.001/surfaceP_p0, RLdivgM)) * surfaceTemperature_T0 / lapseRate_L; + // double P = surfaceP_p0*pow((1.0-lapseRate_L*h/surfaceTemperature_T0),1/RLdivgM); } m_atmosphereRadius = h + sbody->GetRadius(); - SetPhysRadius(std::max(m_atmosphereRadius, GetMaxFeatureRadius()+1000)); + SetPhysRadius(std::max(m_atmosphereRadius, GetMaxFeatureRadius() + 1000)); // NB: Below abandoned due to docking problems with low altitude orbiting space stations // SetPhysRadius(std::max(m_atmosphereRadius, std::max(GetMaxFeatureRadius() * 2.0 + 2000, sbody->GetRadius() * 1.05))); if (sbody->HasRings()) { @@ -119,17 +119,21 @@ void Planet::GetAtmosphericState(double dist, double *outPressure, double *outDe // This model has no atmosphere beyond the adiabetic limit // Note: some code duplicated in InitParams(). Check if changing. - if (dist >= m_atmosphereRadius) {*outDensity = 0.0; *outPressure = 0.0; return;} + if (dist >= m_atmosphereRadius) { + *outDensity = 0.0; + *outPressure = 0.0; + return; + } double surfaceDensity; double specificHeatCp; double gasMolarMass; const SystemBody *sbody = this->GetSystemBody(); if (sbody->GetSuperType() == SystemBody::SUPERTYPE_GAS_GIANT) { - specificHeatCp=12950.0; // constant pressure specific heat, for a combination of hydrogen and helium + specificHeatCp = 12950.0; // constant pressure specific heat, for a combination of hydrogen and helium gasMolarMass = 0.0023139903; } else { - specificHeatCp=1000.5;// constant pressure specific heat, for the combination of gasses that make up air + specificHeatCp = 1000.5; // constant pressure specific heat, for the combination of gasses that make up air // XXX using earth's molar mass of air... gasMolarMass = 0.02897; } @@ -139,29 +143,33 @@ void Planet::GetAtmosphericState(double dist, double *outPressure, double *outDe // lapse rate http://en.wikipedia.org/wiki/Adiabatic_lapse_rate#Dry_adiabatic_lapse_rate // the wet adiabatic rate can be used when cloud layers are incorporated // fairly accurate in the troposphere - const double lapseRate_L = -m_surfaceGravity_g/specificHeatCp; // negative deg/m + const double lapseRate_L = -m_surfaceGravity_g / specificHeatCp; // negative deg/m - const double height_h = (dist-sbody->GetRadius()); // height in m + const double height_h = (dist - sbody->GetRadius()); // height in m const double surfaceTemperature_T0 = sbody->GetAverageTemp(); //K Color c; - sbody->GetAtmosphereFlavor(&c, &surfaceDensity);// kg / m^3 + sbody->GetAtmosphereFlavor(&c, &surfaceDensity); // kg / m^3 // convert to moles/m^3 - surfaceDensity/=gasMolarMass; + surfaceDensity /= gasMolarMass; //P = density*R*T=(n/V)*R*T - const double surfaceP_p0 = PA_2_ATMOS*((surfaceDensity)*GAS_CONSTANT*surfaceTemperature_T0); // in atmospheres + const double surfaceP_p0 = PA_2_ATMOS * ((surfaceDensity)*GAS_CONSTANT * surfaceTemperature_T0); // in atmospheres // height below zero should not occur - if (height_h < 0.0) { *outPressure = surfaceP_p0; *outDensity = surfaceDensity*gasMolarMass; return; } + if (height_h < 0.0) { + *outPressure = surfaceP_p0; + *outDensity = surfaceDensity * gasMolarMass; + return; + } //*outPressure = p0*(1-l*h/T0)^(g*M/(R*L); - *outPressure = surfaceP_p0*pow((1-lapseRate_L*height_h/surfaceTemperature_T0),(-m_surfaceGravity_g*gasMolarMass/(GAS_CONSTANT*lapseRate_L)));// in ATM since p0 was in ATM + *outPressure = surfaceP_p0 * pow((1 - lapseRate_L * height_h / surfaceTemperature_T0), (-m_surfaceGravity_g * gasMolarMass / (GAS_CONSTANT * lapseRate_L))); // in ATM since p0 was in ATM // ^^g used is abs(g) // temperature at height - double temp = surfaceTemperature_T0+lapseRate_L*height_h; + double temp = surfaceTemperature_T0 + lapseRate_L * height_h; - *outDensity = (*outPressure/(PA_2_ATMOS*GAS_CONSTANT*temp))*gasMolarMass; + *outDensity = (*outPressure / (PA_2_ATMOS * GAS_CONSTANT * temp)) * gasMolarMass; } void Planet::GenerateRings(Graphics::Renderer *renderer) @@ -175,11 +183,11 @@ void Planet::GenerateRings(Graphics::Renderer *renderer) const float outer = sbody->GetRings().maxRadius.ToFloat(); int segments = 200; for (int i = 0; i <= segments; ++i) { - const float a = (2.0f*float(M_PI)) * (float(i) / float(segments)); + const float a = (2.0f * float(M_PI)) * (float(i) / float(segments)); const float ca = cosf(a); const float sa = sinf(a); - m_ringVertices.Add(vector3f(inner*sa, 0.0f, inner*ca), vector2f(float(i), 0.0f)); - m_ringVertices.Add(vector3f(outer*sa, 0.0f, outer*ca), vector2f(float(i), 1.0f)); + m_ringVertices.Add(vector3f(inner * sa, 0.0f, inner * ca), vector2f(float(i), 0.0f)); + m_ringVertices.Add(vector3f(outer * sa, 0.0f, outer * ca), vector2f(float(i), 1.0f)); } // generate the ring texture @@ -189,27 +197,27 @@ void Planet::GenerateRings(Graphics::Renderer *renderer) const int RING_TEXTURE_WIDTH = 4; const int RING_TEXTURE_LENGTH = 256; std::unique_ptr buf( - static_cast(malloc(RING_TEXTURE_WIDTH * RING_TEXTURE_LENGTH * 4))); + static_cast(malloc(RING_TEXTURE_WIDTH * RING_TEXTURE_LENGTH * 4))); - const float ringScale = (outer-inner)*sbody->GetRadius() / 1.5e7f; + const float ringScale = (outer - inner) * sbody->GetRadius() / 1.5e7f; - Random rng(GetSystemBody()->GetSeed()+4609837); + Random rng(GetSystemBody()->GetSeed() + 4609837); Color baseCol = sbody->GetRings().baseColor; double noiseOffset = 2048.0 * rng.Double(); for (int i = 0; i < RING_TEXTURE_LENGTH; ++i) { const float alpha = (float(i) / float(RING_TEXTURE_LENGTH)) * ringScale; const float n = 0.25 + - 0.60 * noise(vector3d( 5.0 * alpha, noiseOffset, 0.0)) + + 0.60 * noise(vector3d(5.0 * alpha, noiseOffset, 0.0)) + 0.15 * noise(vector3d(10.0 * alpha, noiseOffset, 0.0)); - const float LOG_SCALE = 1.0f/sqrtf(sqrtf(log1p(1.0f))); - const float v = LOG_SCALE*sqrtf(sqrtf(log1p(n))); + const float LOG_SCALE = 1.0f / sqrtf(sqrtf(log1p(1.0f))); + const float v = LOG_SCALE * sqrtf(sqrtf(log1p(n))); Color color; - color.r = v*baseCol.r; - color.g = v*baseCol.g; - color.b = v*baseCol.b; - color.a = ((v*0.25f)+0.75f)*baseCol.a; + color.r = v * baseCol.r; + color.g = v * baseCol.g; + color.b = v * baseCol.b; + color.a = ((v * 0.25f) + 0.75f) * baseCol.a; Color *row = buf.get() + i * RING_TEXTURE_WIDTH; for (int j = 0; j < RING_TEXTURE_WIDTH; ++j) { @@ -228,12 +236,12 @@ void Planet::GenerateRings(Graphics::Renderer *renderer) const vector2f texSize(RING_TEXTURE_WIDTH, RING_TEXTURE_LENGTH); const Graphics::TextureDescriptor texDesc( - Graphics::TEXTURE_RGBA_8888, texSize, Graphics::LINEAR_REPEAT, true, true, true, 0, Graphics::TEXTURE_2D); + Graphics::TEXTURE_RGBA_8888, texSize, Graphics::LINEAR_REPEAT, true, true, true, 0, Graphics::TEXTURE_2D); m_ringTexture.Reset(renderer->CreateTexture(texDesc)); m_ringTexture->Update( - static_cast(buf.get()), texSize, - Graphics::TEXTURE_RGBA_8888); + static_cast(buf.get()), texSize, + Graphics::TEXTURE_RGBA_8888); Graphics::MaterialDescriptor desc; desc.effect = Graphics::EFFECT_PLANETRING; @@ -261,5 +269,7 @@ void Planet::DrawGasGiantRings(Renderer *renderer, const matrix4x4d &modelView) void Planet::SubRender(Renderer *r, const matrix4x4d &viewTran, const vector3d &camPos) { - if (GetSystemBody()->HasRings()) { DrawGasGiantRings(r, viewTran); } + if (GetSystemBody()->HasRings()) { + DrawGasGiantRings(r, viewTran); + } } diff --git a/src/Planet.h b/src/Planet.h index e7eaf6d39..f1b8e5517 100644 --- a/src/Planet.h +++ b/src/Planet.h @@ -4,21 +4,21 @@ #ifndef _PLANET_H #define _PLANET_H +#include "SmartPtr.h" #include "TerrainBody.h" #include "graphics/VertexArray.h" -#include "SmartPtr.h" namespace Graphics { class Renderer; class RenderState; class Texture; class Material; -} +} // namespace Graphics -class Planet: public TerrainBody { +class Planet : public TerrainBody { public: OBJDEF(Planet, TerrainBody, PLANET); - Planet(SystemBody*); + Planet(SystemBody *); Planet(); virtual void SubRender(Graphics::Renderer *r, const matrix4x4d &viewTran, const vector3d &camPos) override; @@ -34,7 +34,7 @@ protected: virtual void LoadFromJson(const Json &jsonObj, Space *space) override; private: - void InitParams(const SystemBody*); + void InitParams(const SystemBody *); void GenerateRings(Graphics::Renderer *renderer); void DrawGasGiantRings(Graphics::Renderer *r, const matrix4x4d &modelView); diff --git a/src/Player.cpp b/src/Player.cpp index 326587b3f..e3c0fad12 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -11,21 +11,23 @@ #include "ShipCpanel.h" #include "Sound.h" #include "SpaceStation.h" -#include "WorldView.h" #include "StringF.h" #include "SystemView.h" // for the transfer planner +#include "WorldView.h" //Some player specific sounds static Sound::Event s_soundUndercarriage; static Sound::Event s_soundHyperdrive; -static int onEquipChangeListener(lua_State *l) { +static int onEquipChangeListener(lua_State *l) +{ Player *p = LuaObject::GetFromLua(lua_upvalueindex(1)); p->onChangeEquipment.emit(); return 0; } -static void registerEquipChangeListener(Player *player) { +static void registerEquipChangeListener(Player *player) +{ lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); @@ -38,14 +40,16 @@ static void registerEquipChangeListener(Player *player) { LUA_DEBUG_END(l, 0); } -Player::Player(const ShipType::Id &shipId): Ship(shipId) +Player::Player(const ShipType::Id &shipId) : + Ship(shipId) { SetController(new PlayerShipController()); InitCockpit(); registerEquipChangeListener(this); } -void Player::SetShipType(const ShipType::Id &shipId) { +void Player::SetShipType(const ShipType::Id &shipId) +{ Ship::SetShipType(shipId); registerEquipChangeListener(this); InitCockpit(); @@ -96,9 +100,8 @@ bool Player::DoCrushDamage(float kgDamage) { bool r = Ship::DoCrushDamage(kgDamage); // Don't fire audio on EVERY iteration (aka every 16ms, or 60fps), only when exceeds a value randomly - const float dam = kgDamage*0.01f; - if (Pi::rng.Double() < dam) - { + const float dam = kgDamage * 0.01f; + if (Pi::rng.Double() < dam) { if (!IsDead() && (GetPercentHull() < 25.0f)) { Sound::BodyMakeNoise(this, "warning", .5f); } @@ -111,7 +114,7 @@ bool Player::DoCrushDamage(float kgDamage) } //XXX perhaps remove this, the sound is very annoying -bool Player::OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) +bool Player::OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) { bool r = Ship::OnDamage(attacker, kgDamage, contactData); if (!IsDead() && (GetPercentHull() < 25.0f)) { @@ -137,9 +140,9 @@ bool Player::SetWheelState(bool down) } //XXX all ships should make this sound -Missile * Player::SpawnMissile(ShipType::Id missile_type, int power) +Missile *Player::SpawnMissile(ShipType::Id missile_type, int power) { - Missile * m = Ship::SpawnMissile(missile_type, power); + Missile *m = Ship::SpawnMissile(missile_type, power); if (m) Sound::PlaySfx("Missile_launch", 1.0f, 1.0f, 0); return m; @@ -151,29 +154,29 @@ void Player::SetAlertState(Ship::AlertState as) Ship::AlertState prev = GetAlertState(); switch (as) { - case ALERT_NONE: - if (prev != ALERT_NONE) - Pi::game->log->Add(Lang::ALERT_CANCELLED); - break; + case ALERT_NONE: + if (prev != ALERT_NONE) + Pi::game->log->Add(Lang::ALERT_CANCELLED); + break; - case ALERT_SHIP_NEARBY: - if (prev == ALERT_NONE) - Pi::game->log->Add(Lang::SHIP_DETECTED_NEARBY); - else - Pi::game->log->Add(Lang::DOWNGRADING_ALERT_STATUS); - Sound::PlaySfx("OK"); - break; + case ALERT_SHIP_NEARBY: + if (prev == ALERT_NONE) + Pi::game->log->Add(Lang::SHIP_DETECTED_NEARBY); + else + Pi::game->log->Add(Lang::DOWNGRADING_ALERT_STATUS); + Sound::PlaySfx("OK"); + break; - case ALERT_SHIP_FIRING: - Pi::game->log->Add(Lang::LASER_FIRE_DETECTED); - Sound::PlaySfx("warning", 0.2f, 0.2f, 0); - break; + case ALERT_SHIP_FIRING: + Pi::game->log->Add(Lang::LASER_FIRE_DETECTED); + Sound::PlaySfx("warning", 0.2f, 0.2f, 0); + break; } Ship::SetAlertState(as); } -void Player::NotifyRemoved(const Body* const removedBody) +void Player::NotifyRemoved(const Body *const removedBody) { if (GetNavTarget() == removedBody) SetNavTarget(0); @@ -182,7 +185,7 @@ void Player::NotifyRemoved(const Body* const removedBody) SetCombatTarget(0); if (!GetNavTarget() && removedBody->IsType(Object::SHIP)) - SetNavTarget(static_cast(removedBody)->GetHyperspaceCloud()); + SetNavTarget(static_cast(removedBody)->GetHyperspaceCloud()); } Ship::NotifyRemoved(removedBody); @@ -210,51 +213,52 @@ void Player::OnEnterSystem() //temporary targeting stuff PlayerShipController *Player::GetPlayerController() const { - return static_cast(GetController()); + return static_cast(GetController()); } Body *Player::GetCombatTarget() const { - return static_cast(m_controller)->GetCombatTarget(); + return static_cast(m_controller)->GetCombatTarget(); } Body *Player::GetNavTarget() const { - return static_cast(m_controller)->GetNavTarget(); + return static_cast(m_controller)->GetNavTarget(); } Body *Player::GetSetSpeedTarget() const { - return static_cast(m_controller)->GetSetSpeedTarget(); + return static_cast(m_controller)->GetSetSpeedTarget(); } -void Player::SetCombatTarget(Body* const target, bool setSpeedTo) +void Player::SetCombatTarget(Body *const target, bool setSpeedTo) { - static_cast(m_controller)->SetCombatTarget(target, setSpeedTo); + static_cast(m_controller)->SetCombatTarget(target, setSpeedTo); Pi::onPlayerChangeTarget.emit(); } -void Player::SetNavTarget(Body* const target, bool setSpeedTo) +void Player::SetNavTarget(Body *const target, bool setSpeedTo) { - static_cast(m_controller)->SetNavTarget(target, setSpeedTo); + static_cast(m_controller)->SetNavTarget(target, setSpeedTo); Pi::onPlayerChangeTarget.emit(); } -void Player::SetSetSpeedTarget(Body* const target) +void Player::SetSetSpeedTarget(Body *const target) { - static_cast(m_controller)->SetSetSpeedTarget(target); + static_cast(m_controller)->SetSetSpeedTarget(target); // TODO: not sure, do we actually need this? we are only changing the set speed target Pi::onPlayerChangeTarget.emit(); } void Player::ChangeSetSpeed(double delta) { - static_cast(m_controller)->ChangeSetSpeed(delta); + static_cast(m_controller)->ChangeSetSpeed(delta); } //temporary targeting stuff ends -Ship::HyperjumpStatus Player::InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks) { +Ship::HyperjumpStatus Player::InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks) +{ HyperjumpStatus status = Ship::InitiateHyperjumpTo(dest, warmup_time, duration, sounds, checks); if (status == HYPERJUMP_OK) @@ -285,29 +289,31 @@ void Player::StaticUpdate(const float timeStep) m_cockpit->Update(this, timeStep); } -int Player::GetManeuverTime() const { - if(Pi::planner->GetOffsetVel().ExactlyEqual(vector3d(0,0,0))) { +int Player::GetManeuverTime() const +{ + if (Pi::planner->GetOffsetVel().ExactlyEqual(vector3d(0, 0, 0))) { return 0; } return Pi::planner->GetStartTime(); } -vector3d Player::GetManeuverVelocity() const { - const Frame* frame = GetFrame(); - if(frame->IsRotFrame()) +vector3d Player::GetManeuverVelocity() const +{ + const Frame *frame = GetFrame(); + if (frame->IsRotFrame()) frame = frame->GetNonRotFrame(); - const SystemBody* systemBody = frame->GetSystemBody(); + const SystemBody *systemBody = frame->GetSystemBody(); - if(Pi::planner->GetOffsetVel().ExactlyEqual(vector3d(0,0,0))) { - return vector3d(0,0,0); - } else if(systemBody) { + if (Pi::planner->GetOffsetVel().ExactlyEqual(vector3d(0, 0, 0))) { + return vector3d(0, 0, 0); + } else if (systemBody) { Orbit playerOrbit = ComputeOrbit(); - if(!is_zero_exact(playerOrbit.GetSemiMajorAxis())) { + if (!is_zero_exact(playerOrbit.GetSemiMajorAxis())) { double mass = systemBody->GetMass(); // XXX The best solution would be to store the mass(es) on Orbit const vector3d velocity = (Pi::planner->GetVel() - playerOrbit.OrbitalVelocityAtTime(mass, playerOrbit.OrbitalTimeAtPos(Pi::planner->GetPosition(), mass))); return velocity; } } - return vector3d(0,0,0); + return vector3d(0, 0, 0); } diff --git a/src/Player.h b/src/Player.h index 7b64ab1a8..2736f2a57 100644 --- a/src/Player.h +++ b/src/Player.h @@ -4,28 +4,30 @@ #ifndef _PLAYER_H #define _PLAYER_H -#include "libs.h" -#include #include "HyperspaceCloud.h" #include "Ship.h" -#include "ShipController.h" #include "ShipCockpit.h" +#include "ShipController.h" #include "galaxy/StarSystem.h" +#include "libs.h" +#include -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} -class Player: public Ship { +class Player : public Ship { public: OBJDEF(Player, Ship, PLAYER); Player(const ShipType::Id &shipId); - Player() {}; //default constructor used before Load + Player(){}; //default constructor used before Load virtual void SetDockedWith(SpaceStation *, int port) override; virtual bool DoCrushDamage(float kgDamage) override final; // overloaded to add "crush" audio - virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override; + virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) override; virtual bool SetWheelState(bool down) override; // returns success of state change, NOT state itself - virtual Missile * SpawnMissile(ShipType::Id missile_type, int power=-1) override; + virtual Missile *SpawnMissile(ShipType::Id missile_type, int power = -1) override; virtual void SetAlertState(Ship::AlertState as) override; - virtual void NotifyRemoved(const Body* const removedBody) override; + virtual void NotifyRemoved(const Body *const removedBody) override; virtual void SetShipType(const ShipType::Id &shipId) override; @@ -34,9 +36,9 @@ public: Body *GetCombatTarget() const; Body *GetNavTarget() const; Body *GetSetSpeedTarget() const; - void SetCombatTarget(Body* const target, bool setSpeedTo = false); - void SetNavTarget(Body* const target, bool setSpeedTo = false); - void SetSetSpeedTarget(Body* const target); + void SetCombatTarget(Body *const target, bool setSpeedTo = false); + void SetNavTarget(Body *const target, bool setSpeedTo = false); + void SetSetSpeedTarget(Body *const target); void ChangeSetSpeed(double delta); virtual Ship::HyperjumpStatus InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks) override; @@ -44,7 +46,7 @@ public: // XXX cockpit is here for now because it has a physics component void InitCockpit(); - ShipCockpit* GetCockpit() const {return m_cockpit.get();} + ShipCockpit *GetCockpit() const { return m_cockpit.get(); } void OnCockpitActivated(); virtual void StaticUpdate(const float timeStep) override; diff --git a/src/PngWriter.cpp b/src/PngWriter.cpp index 7ac862730..76bfb0e6b 100644 --- a/src/PngWriter.cpp +++ b/src/PngWriter.cpp @@ -30,13 +30,11 @@ void write_png(FileSystem::FileSourceFS &fs, const std::string &path, const Uint int srcy = height - 1; for (int y = 0; y < height; y++) { - for (int x = 0; x < stride; x++) - { + for (int x = 0; x < stride; x++) { const int src_index = (srcy * stride) + x; const int dst_index = (y * stride) + x; - for (int channel = 0; channel < bytes_per_pixel; channel++) - { - (static_cast(surface->pixels))[dst_index + channel] = bytes[src_index + channel]; + for (int channel = 0; channel < bytes_per_pixel; channel++) { + (static_cast(surface->pixels))[dst_index + channel] = bytes[src_index + channel]; } } srcy--; diff --git a/src/Polit.cpp b/src/Polit.cpp index 4a2348932..6a7c6937a 100644 --- a/src/Polit.cpp +++ b/src/Polit.cpp @@ -1,64 +1,64 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" #include "Polit.h" -#include "galaxy/Galaxy.h" -#include "galaxy/StarSystem.h" -#include "galaxy/Sector.h" -#include "galaxy/Economy.h" #include "Factions.h" -#include "Space.h" +#include "Game.h" +#include "Lang.h" +#include "Pi.h" #include "Ship.h" #include "ShipCpanel.h" +#include "Space.h" #include "SpaceStation.h" -#include "Lang.h" #include "StringF.h" -#include "Game.h" +#include "galaxy/Economy.h" +#include "galaxy/Galaxy.h" +#include "galaxy/Sector.h" +#include "galaxy/StarSystem.h" +#include "libs.h" namespace Polit { + const char *s_econDesc[ECON_MAX] = { + Lang::NO_ESTABLISHED_ORDER, + Lang::HARD_CAPITALIST, + Lang::CAPITALIST, + Lang::MIXED_ECONOMY, + Lang::PLANNED_ECONOMY + }; -const char *s_econDesc[ECON_MAX] = { - Lang::NO_ESTABLISHED_ORDER, - Lang::HARD_CAPITALIST, - Lang::CAPITALIST, - Lang::MIXED_ECONOMY, - Lang::PLANNED_ECONOMY -}; + struct politDesc_t { + const char *description; + int rarity; + PolitEcon econ; + fixed baseLawlessness; + }; + static politDesc_t s_govDesc[GOV_MAX] = { + { "", 0, ECON_NONE, fixed(1, 1) }, + { Lang::NO_CENTRAL_GOVERNANCE, 0, ECON_NONE, fixed(1, 1) }, + { Lang::EARTH_FEDERATION_COLONIAL_RULE, 2, ECON_CAPITALIST, fixed(3, 10) }, + { Lang::EARTH_FEDERATION_DEMOCRACY, 3, ECON_CAPITALIST, fixed(15, 100) }, + { Lang::IMPERIAL_RULE, 3, ECON_PLANNED, fixed(15, 100) }, + { Lang::LIBERAL_DEMOCRACY, 2, ECON_CAPITALIST, fixed(25, 100) }, + { Lang::SOCIAL_DEMOCRACY, 2, ECON_MIXED, fixed(20, 100) }, + { Lang::LIBERAL_DEMOCRACY, 2, ECON_CAPITALIST, fixed(25, 100) }, + { Lang::CORPORATE_SYSTEM, 2, ECON_CAPITALIST, fixed(40, 100) }, + { Lang::SOCIAL_DEMOCRACY, 2, ECON_MIXED, fixed(25, 100) }, + { Lang::MILITARY_DICTATORSHIP, 5, ECON_CAPITALIST, fixed(40, 100) }, + { Lang::MILITARY_DICTATORSHIP, 6, ECON_CAPITALIST, fixed(25, 100) }, + { Lang::MILITARY_DICTATORSHIP, 6, ECON_MIXED, fixed(25, 100) }, + { Lang::MILITARY_DICTATORSHIP, 5, ECON_MIXED, fixed(40, 100) }, + { Lang::COMMUNIST, 10, ECON_PLANNED, fixed(25, 100) }, + { Lang::PLUTOCRATIC_DICTATORSHIP, 4, ECON_VERY_CAPITALIST, fixed(45, 100) }, + { Lang::VIOLENT_ANARCHY, 2, ECON_NONE, fixed(90, 100) }, + }; -struct politDesc_t { - const char *description; - int rarity; - PolitEcon econ; - fixed baseLawlessness; -}; -static politDesc_t s_govDesc[GOV_MAX] = { - { "", 0, ECON_NONE, fixed(1,1) }, - { Lang::NO_CENTRAL_GOVERNANCE, 0, ECON_NONE, fixed(1,1) }, - { Lang::EARTH_FEDERATION_COLONIAL_RULE, 2, ECON_CAPITALIST, fixed(3,10) }, - { Lang::EARTH_FEDERATION_DEMOCRACY, 3, ECON_CAPITALIST, fixed(15,100) }, - { Lang::IMPERIAL_RULE, 3, ECON_PLANNED, fixed(15,100) }, - { Lang::LIBERAL_DEMOCRACY, 2, ECON_CAPITALIST, fixed(25,100) }, - { Lang::SOCIAL_DEMOCRACY, 2, ECON_MIXED, fixed(20,100) }, - { Lang::LIBERAL_DEMOCRACY, 2, ECON_CAPITALIST, fixed(25,100) }, - { Lang::CORPORATE_SYSTEM, 2, ECON_CAPITALIST, fixed(40,100) }, - { Lang::SOCIAL_DEMOCRACY, 2, ECON_MIXED, fixed(25,100) }, - { Lang::MILITARY_DICTATORSHIP, 5, ECON_CAPITALIST, fixed(40,100) }, - { Lang::MILITARY_DICTATORSHIP, 6, ECON_CAPITALIST, fixed(25,100) }, - { Lang::MILITARY_DICTATORSHIP, 6, ECON_MIXED, fixed(25,100) }, - { Lang::MILITARY_DICTATORSHIP, 5, ECON_MIXED, fixed(40,100) }, - { Lang::COMMUNIST, 10, ECON_PLANNED, fixed(25,100) }, - { Lang::PLUTOCRATIC_DICTATORSHIP, 4, ECON_VERY_CAPITALIST, fixed(45,100) }, - { Lang::VIOLENT_ANARCHY, 2, ECON_NONE, fixed(90,100) }, -}; + fixed GetBaseLawlessness(GovType gov) + { + return s_govDesc[gov].baseLawlessness; + } -fixed GetBaseLawlessness(GovType gov) { - return s_govDesc[gov].baseLawlessness; -} - -} +} // namespace Polit const char *SysPolit::GetGovernmentDesc() const { @@ -67,5 +67,5 @@ const char *SysPolit::GetGovernmentDesc() const const char *SysPolit::GetEconomicDesc() const { - return Polit::s_econDesc[ Polit::s_govDesc[govType].econ ]; + return Polit::s_econDesc[Polit::s_govDesc[govType].econ]; } diff --git a/src/Polit.h b/src/Polit.h index c5dc10794..f9fff7de8 100644 --- a/src/Polit.h +++ b/src/Polit.h @@ -4,6 +4,7 @@ #ifndef _POLIT_H #define _POLIT_H +#include "fixed.h" #include "galaxy/Economy.h" class Galaxy; @@ -40,16 +41,17 @@ namespace Polit { GOV_PLUTOCRATIC, GOV_DISORDER, GOV_MAX, // - GOV_RAND_MIN = GOV_NONE+1, // - GOV_RAND_MAX = GOV_MAX-1, // + GOV_RAND_MIN = GOV_NONE + 1, // + GOV_RAND_MAX = GOV_MAX - 1, // }; fixed GetBaseLawlessness(GovType gov); -} +} // namespace Polit class SysPolit { public: - SysPolit() : govType(Polit::GOV_INVALID) { } + SysPolit() : + govType(Polit::GOV_INVALID) {} const char *GetGovernmentDesc() const; const char *GetEconomicDesc() const; diff --git a/src/Projectile.cpp b/src/Projectile.cpp index 08e3e4c0c..2b7254cf7 100644 --- a/src/Projectile.cpp +++ b/src/Projectile.cpp @@ -1,29 +1,28 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" #include "Projectile.h" -#include "Frame.h" -#include "galaxy/StarSystem.h" -#include "Space.h" -#include "collider/collider.h" #include "CargoBody.h" -#include "Planet.h" -#include "Sfx.h" -#include "Ship.h" -#include "Pi.h" +#include "Frame.h" #include "Game.h" -#include "Player.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "LuaEvent.h" #include "LuaUtils.h" +#include "Pi.h" +#include "Planet.h" +#include "Player.h" +#include "Sfx.h" +#include "Ship.h" +#include "Space.h" +#include "collider/collider.h" +#include "galaxy/StarSystem.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" -#include "graphics/VertexArray.h" #include "graphics/TextureBuilder.h" -#include "JsonUtils.h" -#include "GameSaveError.h" +#include "graphics/VertexArray.h" +#include "libs.h" std::unique_ptr Projectile::s_sideVerts; std::unique_ptr Projectile::s_glowVerts; @@ -48,8 +47,8 @@ void Projectile::BuildModel() const float w = 0.5f; vector3f one(0.f, -w, 0.f); //top left - vector3f two(0.f, w, 0.f); //top right - vector3f three(0.f, w, -1.f); //bottom right + vector3f two(0.f, w, 0.f); //top right + vector3f three(0.f, w, -1.f); //bottom right vector3f four(0.f, -w, -1.f); //bottom left //uv coords @@ -62,7 +61,7 @@ void Projectile::BuildModel() s_glowVerts.reset(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0)); //add four intersecting planes to create a volumetric effect - for (int i=0; i < 4; i++) { + for (int i = 0; i < 4; i++) { s_sideVerts->Add(one, topLeft); s_sideVerts->Add(two, topRight); s_sideVerts->Add(three, botRight); @@ -81,7 +80,7 @@ void Projectile::BuildModel() float gw = 0.5f; float gz = -0.1f; - for (int i=0; i < 4; i++) { + for (int i = 0; i < 4; i++) { s_glowVerts->Add(vector3f(-gw, -gw, gz), topLeft); s_glowVerts->Add(vector3f(-gw, gw, gz), topRight); s_glowVerts->Add(vector3f(gw, gw, gz), botRight); @@ -109,7 +108,8 @@ void Projectile::FreeModel() s_glowVerts.reset(); } -Projectile::Projectile(): Body() +Projectile::Projectile() : + Body() { if (!s_sideMat) BuildModel(); SetOrient(matrix3x3d::Identity()); @@ -178,11 +178,11 @@ void Projectile::PostLoadFixup(Space *space) void Projectile::UpdateInterpTransform(double alpha) { m_interpOrient = GetOrient(); - const vector3d oldPos = GetPosition() - (m_baseVel+m_dirVel)*Pi::game->GetTimeStep(); - m_interpPos = alpha*GetPosition() + (1.0-alpha)*oldPos; + const vector3d oldPos = GetPosition() - (m_baseVel + m_dirVel) * Pi::game->GetTimeStep(); + m_interpPos = alpha * GetPosition() + (1.0 - alpha) * oldPos; } -void Projectile::NotifyRemoved(const Body* const removedBody) +void Projectile::NotifyRemoved(const Body *const removedBody) { if (m_parent == removedBody) m_parent = 0; } @@ -190,21 +190,21 @@ void Projectile::NotifyRemoved(const Body* const removedBody) void Projectile::TimeStepUpdate(const float timeStep) { m_age += timeStep; - SetPosition(GetPosition() + (m_baseVel+m_dirVel) * double(timeStep)); + SetPosition(GetPosition() + (m_baseVel + m_dirVel) * double(timeStep)); if (m_age > m_lifespan) Pi::game->GetSpace()->KillBody(this); } /* In hull kg */ float Projectile::GetDamage() const { - return m_baseDam * sqrt((m_lifespan - m_age)/m_lifespan); + return m_baseDam * sqrt((m_lifespan - m_age) / m_lifespan); // TEST -// return 0.01f; + // return 0.01f; } double Projectile::GetRadius() const { - return sqrt(m_length*m_length + m_width*m_width); + return sqrt(m_length * m_length + m_width * m_width); } static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos) @@ -235,8 +235,8 @@ static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, con cargo->SetPosition(pos); const double x = Pi::rng.Double(); vector3d dir = pos.Normalized(); - dir.ArbRotate(vector3d(x, 1-x, 0), Pi::rng.Double()-.5); - cargo->SetVelocity(Pi::rng.Double(100.0,200.0) * dir); + dir.ArbRotate(vector3d(x, 1 - x, 0), Pi::rng.Double() - .5); + cargo->SetVelocity(Pi::rng.Double(100.0, 200.0) * dir); Pi::game->GetSpace()->AddBody(cargo); } @@ -249,37 +249,33 @@ void Projectile::StaticUpdate(const float timeStep) GetFrame()->GetCollisionSpace()->TraceRay(GetPosition(), vel.Normalized(), vel.Length(), &c); if (c.userData1) { - Object *o = static_cast(c.userData1); + Object *o = static_cast(c.userData1); if (o->IsType(Object::CITYONPLANET)) { Pi::game->GetSpace()->KillBody(this); - } - else if (o->IsType(Object::BODY)) { - Body *hit = static_cast(o); + } else if (o->IsType(Object::BODY)) { + Body *hit = static_cast(o); if (hit != m_parent) { hit->OnDamage(m_parent, GetDamage(), c); Pi::game->GetSpace()->KillBody(this); if (hit->IsType(Object::SHIP)) - LuaEvent::Queue("onShipHit", dynamic_cast(hit), dynamic_cast(m_parent)); + LuaEvent::Queue("onShipHit", dynamic_cast(hit), dynamic_cast(m_parent)); } } } if (m_mining) // mining lasers can break off chunks of terrain { // need to test for terrain hit - Planet *const planet = static_cast(GetFrame()->GetBody()); // cache the value even for the if statement - if (planet && planet->IsType(Object::PLANET)) - { + Planet *const planet = static_cast(GetFrame()->GetBody()); // cache the value even for the if statement + if (planet && planet->IsType(Object::PLANET)) { vector3d pos = GetPosition(); double terrainHeight = planet->GetTerrainHeight(pos.Normalized()); - if (terrainHeight > pos.Length()) - { + if (terrainHeight > pos.Length()) { const SystemBody *b = planet->GetSystemBody(); // hit the fucker - if (b->GetType() == SystemBody::TYPE_PLANET_ASTEROID) - { + if (b->GetType() == SystemBody::TYPE_PLANET_ASTEROID) { vector3d n = GetPosition().Normalized(); - MiningLaserSpawnTastyStuff(planet->GetFrame(), b, n*terrainHeight + 5.0*n); + MiningLaserSpawnTastyStuff(planet->GetFrame(), b, n * terrainHeight + 5.0 * n); SfxManager::Add(this, TYPE_EXPLOSION); } Pi::game->GetSpace()->KillBody(this); @@ -299,12 +295,20 @@ void Projectile::Render(Graphics::Renderer *renderer, const Camera *camera, cons vector3f v1, v2; matrix4x4f m = matrix4x4f::Identity(); - v1.x = dir.y; v1.y = dir.z; v1.z = dir.x; + v1.x = dir.y; + v1.y = dir.z; + v1.z = dir.x; v2 = v1.Cross(dir).Normalized(); v1 = v2.Cross(dir); - m[0] = v1.x; m[4] = v2.x; m[8] = dir.x; - m[1] = v1.y; m[5] = v2.y; m[9] = dir.y; - m[2] = v1.z; m[6] = v2.z; m[10] = dir.z; + m[0] = v1.x; + m[4] = v2.x; + m[8] = dir.x; + m[1] = v1.y; + m[5] = v2.y; + m[9] = dir.y; + m[2] = v1.z; + m[6] = v2.z; + m[10] = dir.z; m[12] = from.x; m[13] = from.y; @@ -321,7 +325,7 @@ void Projectile::Render(Graphics::Renderer *renderer, const Camera *camera, cons Color color = m_color; // fade them out as they age so they don't suddenly disappear // this matches the damage fall-off calculation - const float base_alpha = sqrt(1.0f - m_age/m_lifespan); + const float base_alpha = sqrt(1.0f - m_age / m_lifespan); // fade out side quads when viewing nearly edge on vector3f view_dir = vector3f(viewCoords).Normalized(); color.a = (base_alpha * (1.f - powf(fabs(dir.Dot(view_dir)), length))) * 255; diff --git a/src/Projectile.h b/src/Projectile.h index 8515ebec9..0c94504bf 100644 --- a/src/Projectile.h +++ b/src/Projectile.h @@ -4,13 +4,21 @@ #ifndef _PROJECTILE_H #define _PROJECTILE_H -#include "libs.h" #include "Body.h" #include "graphics/Material.h" #include "graphics/RenderState.h" +#include "libs.h" struct ProjectileData { - ProjectileData() : lifespan(0.0f), damage(0.0f), length(0.0f), width(0.0f), speed(0.0f), color(Color::WHITE), mining(false), beam(false) {} + ProjectileData() : + lifespan(0.0f), + damage(0.0f), + length(0.0f), + width(0.0f), + speed(0.0f), + color(Color::WHITE), + mining(false), + beam(false) {} float lifespan; float damage; float length; @@ -21,28 +29,28 @@ struct ProjectileData { bool beam; }; - class Frame; namespace Graphics { class Renderer; class VertexArray; -} +} // namespace Graphics -class Projectile: public Body { +class Projectile : public Body { public: OBJDEF(Projectile, Body, PROJECTILE); - static void Add(Body *parent, float lifespan, float dam, float length, float width, bool mining, const Color& color, const vector3d &pos, const vector3d &baseVel, const vector3d &dirVel); - static void Add(Body *parent, const ProjectileData& prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dirVel ) { - Add( parent, prData.lifespan, prData.damage, prData.length, prData.width, prData.mining, prData.color, pos, baseVel, dirVel ); + static void Add(Body *parent, float lifespan, float dam, float length, float width, bool mining, const Color &color, const vector3d &pos, const vector3d &baseVel, const vector3d &dirVel); + static void Add(Body *parent, const ProjectileData &prData, const vector3d &pos, const vector3d &baseVel, const vector3d &dirVel) + { + Add(parent, prData.lifespan, prData.damage, prData.length, prData.width, prData.mining, prData.color, pos, baseVel, dirVel); } Projectile(); virtual ~Projectile(); - virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override final; + virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override final; void TimeStepUpdate(const float timeStep) override final; void StaticUpdate(const float timeStep) override final; - virtual void NotifyRemoved(const Body* const removedBody) override final; + virtual void NotifyRemoved(const Body *const removedBody) override final; virtual void UpdateInterpTransform(double alpha) override final; virtual void PostLoadFixup(Space *space) override final; diff --git a/src/PropertiedObject.h b/src/PropertiedObject.h index 24496bc0c..426966498 100644 --- a/src/PropertiedObject.h +++ b/src/PropertiedObject.h @@ -14,7 +14,8 @@ public: const PropertyMap &Properties() const { return m_properties; } protected: - PropertiedObject(LuaManager *lua) : m_properties(lua) {} + PropertiedObject(LuaManager *lua) : + m_properties(lua) {} private: PropertyMap m_properties; diff --git a/src/PropertyMap.cpp b/src/PropertyMap.cpp index 450439e7d..b08e6ec45 100644 --- a/src/PropertyMap.cpp +++ b/src/PropertyMap.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "PropertyMap.h" -#include "LuaUtils.h" #include "LuaSerializer.h" +#include "LuaUtils.h" PropertyMap::PropertyMap(LuaManager *lua) { @@ -17,7 +17,7 @@ PropertyMap::PropertyMap(LuaManager *lua) void PropertyMap::SendSignal(const std::string &k) { - std::map< std::string,sigc::signal >::iterator i = m_signals.find(k); + std::map>::iterator i = m_signals.find(k); if (i == m_signals.end()) return; diff --git a/src/PropertyMap.h b/src/PropertyMap.h index 435376fc4..0528522c2 100644 --- a/src/PropertyMap.h +++ b/src/PropertyMap.h @@ -15,18 +15,23 @@ class PropertyMap { public: PropertyMap(LuaManager *lua); - template void Set(const std::string &k, const Value &v) { + template + void Set(const std::string &k, const Value &v) + { ScopedTable(m_table).Set(k, v); SendSignal(k); } - template void Get(const std::string &k, Value &v) const { + template + void Get(const std::string &k, Value &v) const + { v = ScopedTable(m_table).Get(k, v); } void PushLuaTable(); - sigc::connection Connect(const std::string &k, const sigc::slot &fn) { + sigc::connection Connect(const std::string &k, const sigc::slot &fn) + { return m_signals[k].connect(fn); } @@ -37,7 +42,7 @@ private: LuaRef m_table; void SendSignal(const std::string &k); - std::map< std::string,sigc::signal > m_signals; + std::map> m_signals; }; #endif diff --git a/src/Propulsion.cpp b/src/Propulsion.cpp index 687db82c7..0bc05f5ef 100644 --- a/src/Propulsion.cpp +++ b/src/Propulsion.cpp @@ -2,11 +2,11 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Propulsion.h" -#include "Pi.h" #include "Game.h" -#include "Object.h" // <- here only for comment in AIFaceDirection (line 320) -#include "KeyBindings.h" // <- same here #include "GameSaveError.h" +#include "KeyBindings.h" // <- same here +#include "Object.h" // <- here only for comment in AIFaceDirection (line 320) +#include "Pi.h" void Propulsion::SaveToJson(Json &jsonObj, Space *space) { @@ -39,50 +39,52 @@ void Propulsion::LoadFromJson(const Json &jsonObj, Space *space) Propulsion::Propulsion() { m_fuelTankMass = 1; - for (int i=0; i< Thruster::THRUSTER_MAX; i++) m_linThrust[i] = 0.0; - for (int i=0; i< Thruster::THRUSTER_MAX; i++) m_linAccelerationCap[i] = INFINITY; + for (int i = 0; i < Thruster::THRUSTER_MAX; i++) + m_linThrust[i] = 0.0; + for (int i = 0; i < Thruster::THRUSTER_MAX; i++) + m_linAccelerationCap[i] = INFINITY; m_angThrust = 0.0; m_effectiveExhaustVelocity = 100000.0; - m_thrusterFuel= 0.0; //0.0-1.0, remaining fuel - m_reserveFuel= 0.0; + m_thrusterFuel = 0.0; //0.0-1.0, remaining fuel + m_reserveFuel = 0.0; m_fuelStateChange = false; - m_linThrusters = vector3d(0,0,0); - m_angThrusters = vector3d(0,0,0); + m_linThrusters = vector3d(0, 0, 0); + m_angThrusters = vector3d(0, 0, 0); m_smodel = nullptr; m_dBody = nullptr; - } void Propulsion::Init(DynamicBody *b, SceneGraph::Model *m, const int tank_mass, const double effExVel, const float lin_Thrust[], const float ang_Thrust) { m_fuelTankMass = tank_mass; m_effectiveExhaustVelocity = effExVel; - for (int i=0; i(m_dBody->GetMass()); return std::min( m_linThrust[thruster], - m_linAccelerationCap[thruster] * mass - ); + m_linAccelerationCap[thruster] * mass); } vector3d Propulsion::GetThrust(const vector3d &dir) const { vector3d maxThrust; - maxThrust.x = (dir.x > 0) ? GetThrust(THRUSTER_RIGHT) : GetThrust(THRUSTER_LEFT); - maxThrust.y = (dir.y > 0) ? GetThrust(THRUSTER_UP) : GetThrust(THRUSTER_DOWN); + maxThrust.x = (dir.x > 0) ? GetThrust(THRUSTER_RIGHT) : GetThrust(THRUSTER_LEFT); + maxThrust.y = (dir.y > 0) ? GetThrust(THRUSTER_UP) : GetThrust(THRUSTER_DOWN); maxThrust.z = (dir.z > 0) ? GetThrust(THRUSTER_REVERSE) : GetThrust(THRUSTER_FORWARD); return maxThrust; @@ -184,8 +184,8 @@ vector3d Propulsion::GetThrustUncapped(const vector3d &dir) const { vector3d maxThrust; - maxThrust.x = (dir.x > 0) ? m_linThrust[THRUSTER_RIGHT] : m_linThrust[THRUSTER_LEFT]; - maxThrust.y = (dir.y > 0) ? m_linThrust[THRUSTER_UP] : m_linThrust[THRUSTER_DOWN]; + maxThrust.x = (dir.x > 0) ? m_linThrust[THRUSTER_RIGHT] : m_linThrust[THRUSTER_LEFT]; + maxThrust.y = (dir.y > 0) ? m_linThrust[THRUSTER_UP] : m_linThrust[THRUSTER_DOWN]; maxThrust.z = (dir.z > 0) ? m_linThrust[THRUSTER_REVERSE] : m_linThrust[THRUSTER_FORWARD]; return maxThrust; @@ -194,7 +194,7 @@ vector3d Propulsion::GetThrustUncapped(const vector3d &dir) const float Propulsion::GetFuelUseRate() { const float denominator = m_fuelTankMass * m_effectiveExhaustVelocity * 10; - return denominator > 0 ? m_linThrust[THRUSTER_FORWARD]/denominator : 1e9; + return denominator > 0 ? m_linThrust[THRUSTER_FORWARD] / denominator : 1e9; } void Propulsion::UpdateFuel(const float timeStep) @@ -205,8 +205,10 @@ void Propulsion::UpdateFuel(const float timeStep) m_thrusterFuel -= timeStep * (totalThrust * fuelUseRate); FuelState currentState = GetFuelState(); - if (currentState != lastState) m_fuelStateChange = true; - else m_fuelStateChange = false; + if (currentState != lastState) + m_fuelStateChange = true; + else + m_fuelStateChange = false; } // returns speed that can be reached using fuel minus reserve according to the Tsiolkovsky equation @@ -215,9 +217,9 @@ double Propulsion::GetSpeedReachedWithFuel() const const double mass = m_dBody->GetMass(); // Why is the fuel mass multiplied by 1000 and the fuel use rate divided by 1000? // (see Propulsion::UpdateFuel and Propulsion::GetFuelUseRate) - const double fuelmass = 1000 * m_fuelTankMass * ( m_thrusterFuel - m_reserveFuel ); + const double fuelmass = 1000 * m_fuelTankMass * (m_thrusterFuel - m_reserveFuel); if (fuelmass < 0) return 0.0; - return m_effectiveExhaustVelocity * log( mass/( mass-fuelmass )); + return m_effectiveExhaustVelocity * log(mass / (mass - fuelmass)); } void Propulsion::Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) @@ -227,7 +229,7 @@ void Propulsion::Render(Graphics::Renderer *r, const Camera *camera, const vecto * thruster and so on)... this code is :-/ */ //angthrust negated, for some reason - if (m_smodel != nullptr ) m_smodel->SetThrust(vector3f( GetLinThrusterState() ), -vector3f( GetAngThrusterState() )); + if (m_smodel != nullptr) m_smodel->SetThrust(vector3f(GetLinThrusterState()), -vector3f(GetAngThrusterState())); } void Propulsion::AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double softness) @@ -237,7 +239,7 @@ void Propulsion::AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double vector3d angVel = desiredAngVel - m_dBody->GetAngVelocity() * m_dBody->GetOrient(); vector3d thrust; - for (int axis=0; axis<3; axis++) { + for (int axis = 0; axis < 3; axis++) { if (angAccel * softTimeStep >= fabs(angVel[axis])) { thrust[axis] = angVel[axis] / (softTimeStep * angAccel); } else { @@ -287,13 +289,19 @@ void Propulsion::AIAccelToModelRelativeVelocity(const vector3d &v) double calc_ivel(double dist, double vel, double acc) { bool inv = false; - if (dist < 0) { dist = -dist; vel = -vel; inv = true; } - double ivel = 0.9 * sqrt(vel*vel + 2.0 * acc * dist); // fudge hardly necessary + if (dist < 0) { + dist = -dist; + vel = -vel; + inv = true; + } + double ivel = 0.9 * sqrt(vel * vel + 2.0 * acc * dist); // fudge hardly necessary double endvel = ivel - (acc * Pi::game->GetTimeStep()); - if (endvel <= 0.0) ivel = dist / Pi::game->GetTimeStep(); // last frame discrete correction - else ivel = (ivel + endvel) * 0.5; // discrete overshoot correction -// else ivel = endvel + 0.5*acc/PHYSICS_HZ; // unknown next timestep discrete overshoot correction + if (endvel <= 0.0) + ivel = dist / Pi::game->GetTimeStep(); // last frame discrete correction + else + ivel = (ivel + endvel) * 0.5; // discrete overshoot correction + // else ivel = endvel + 0.5*acc/PHYSICS_HZ; // unknown next timestep discrete overshoot correction return (inv) ? -ivel : ivel; } @@ -301,11 +309,13 @@ double calc_ivel(double dist, double vel, double acc) // version for all-positive values double calc_ivel_pos(double dist, double vel, double acc) { - double ivel = 0.9 * sqrt(vel*vel + 2.0 * acc * dist); // fudge hardly necessary + double ivel = 0.9 * sqrt(vel * vel + 2.0 * acc * dist); // fudge hardly necessary double endvel = ivel - (acc * Pi::game->GetTimeStep()); - if (endvel <= 0.0) ivel = dist / Pi::game->GetTimeStep(); // last frame discrete correction - else ivel = (ivel + endvel) * 0.5; // discrete overshoot correction + if (endvel <= 0.0) + ivel = dist / Pi::game->GetTimeStep(); // last frame discrete correction + else + ivel = (ivel + endvel) * 0.5; // discrete overshoot correction return ivel; } @@ -329,10 +339,10 @@ bool Propulsion::AIChangeVelBy(const vector3d &diffvel) vector3d maxThrust = GetThrust(diffvel2); vector3d maxFrameAccel = maxThrust * (Pi::game->GetTimeStep() / m_dBody->GetMass()); vector3d thrust(diffvel2.x / maxFrameAccel.x, - diffvel2.y / maxFrameAccel.y, - diffvel2.z / maxFrameAccel.z); + diffvel2.y / maxFrameAccel.y, + diffvel2.z / maxFrameAccel.z); SetLinThrusterState(thrust); // use clamping - if (thrust.x*thrust.x > 1.0 || thrust.y*thrust.y > 1.0 || thrust.z*thrust.z > 1.0) return false; + if (thrust.x * thrust.x > 1.0 || thrust.y * thrust.y > 1.0 || thrust.z * thrust.z > 1.0) return false; return true; } @@ -343,7 +353,9 @@ vector3d Propulsion::AIChangeVelDir(const vector3d &reqdiffvel) vector3d maxthrust = GetThrust(reqdiffvel); maxthrust += m_dBody->GetExternalForce() * m_dBody->GetOrient(); vector3d maxFA = maxthrust * (Pi::game->GetTimeStep() / m_dBody->GetMass()); - maxFA.x = fabs(maxFA.x); maxFA.y = fabs(maxFA.y); maxFA.z = fabs(maxFA.z); + maxFA.x = fabs(maxFA.x); + maxFA.y = fabs(maxFA.y); + maxFA.z = fabs(maxFA.z); // crunch diffvel by relative thruster power to get acceleration in right direction vector3d diffvel = reqdiffvel; @@ -351,8 +363,8 @@ vector3d Propulsion::AIChangeVelDir(const vector3d &reqdiffvel) if (fabs(diffvel.y) > maxFA.y) diffvel *= maxFA.y / fabs(diffvel.y); if (fabs(diffvel.z) > maxFA.z) diffvel *= maxFA.z / fabs(diffvel.z); - AIChangeVelBy(diffvel); // should always return true because it's already capped? - return m_dBody->GetOrient() * (reqdiffvel - diffvel); // should be remaining diffvel to correct + AIChangeVelBy(diffvel); // should always return true because it's already capped? + return m_dBody->GetOrient() * (reqdiffvel - diffvel); // should be remaining diffvel to correct } // Input in object space @@ -361,30 +373,30 @@ void Propulsion::AIMatchAngVelObjSpace(const vector3d &angvel) double maxAccel = m_angThrust / m_dBody->GetAngularInertia(); double invFrameAccel = 1.0 / (maxAccel * Pi::game->GetTimeStep()); - vector3d diff = angvel - m_dBody->GetAngVelocity() * m_dBody->GetOrient(); // find diff between current & desired angvel + vector3d diff = angvel - m_dBody->GetAngVelocity() * m_dBody->GetOrient(); // find diff between current & desired angvel SetAngThrusterState(diff * invFrameAccel); } // get updir as close as possible just using roll thrusters double Propulsion::AIFaceUpdir(const vector3d &updir, double av) { - double maxAccel = m_angThrust / m_dBody->GetAngularInertia(); // should probably be in stats anyway + double maxAccel = m_angThrust / m_dBody->GetAngularInertia(); // should probably be in stats anyway double frameAccel = maxAccel * Pi::game->GetTimeStep(); - vector3d uphead = updir * m_dBody->GetOrient(); // create desired object-space updir - if (uphead.z > 0.99999) return 0; // bail out if facing updir - uphead.z = 0; uphead = uphead.Normalized(); // only care about roll axis + vector3d uphead = updir * m_dBody->GetOrient(); // create desired object-space updir + if (uphead.z > 0.99999) return 0; // bail out if facing updir + uphead.z = 0; + uphead = uphead.Normalized(); // only care about roll axis double ang = 0.0, dav = 0.0; - if (uphead.y < 0.99999999) - { - ang = acos(Clamp(uphead.y, -1.0, 1.0)); // scalar angle from head to curhead - double iangvel = av + calc_ivel_pos(ang, 0.0, maxAccel); // ideal angvel at current time + if (uphead.y < 0.99999999) { + ang = acos(Clamp(uphead.y, -1.0, 1.0)); // scalar angle from head to curhead + double iangvel = av + calc_ivel_pos(ang, 0.0, maxAccel); // ideal angvel at current time dav = uphead.x > 0 ? -iangvel : iangvel; } - double cav = (m_dBody->GetAngVelocity() * m_dBody->GetOrient()).z; // current obj-rel angvel - double diff = (dav - cav) / frameAccel; // find diff between current & desired angvel + double cav = (m_dBody->GetAngVelocity() * m_dBody->GetOrient()).z; // current obj-rel angvel + double diff = (dav - cav) / frameAccel; // find diff between current & desired angvel SetAngThrusterState(2, diff); return ang; @@ -397,26 +409,25 @@ double Propulsion::AIFaceUpdir(const vector3d &updir, double av) // returns angle to target double Propulsion::AIFaceDirection(const vector3d &dir, double av) { - double maxAccel = m_angThrust / m_dBody->GetAngularInertia(); // should probably be in stats anyway + double maxAccel = m_angThrust / m_dBody->GetAngularInertia(); // should probably be in stats anyway - vector3d head = (dir * m_dBody->GetOrient()).Normalized(); // create desired object-space heading - vector3d dav(0.0, 0.0, 0.0); // desired angular velocity + vector3d head = (dir * m_dBody->GetOrient()).Normalized(); // create desired object-space heading + vector3d dav(0.0, 0.0, 0.0); // desired angular velocity double ang = 0.0; - if (head.z > -0.99999999) - { - ang = acos (Clamp(-head.z, -1.0, 1.0)); // scalar angle from head to curhead - double iangvel = av + calc_ivel_pos(ang, 0.0, maxAccel); // ideal angvel at current time + if (head.z > -0.99999999) { + ang = acos(Clamp(-head.z, -1.0, 1.0)); // scalar angle from head to curhead + double iangvel = av + calc_ivel_pos(ang, 0.0, maxAccel); // ideal angvel at current time // Normalize (head.x, head.y) to give desired angvel direction if (head.z > 0.999999) head.x = 1.0; - double head2dnorm = 1.0 / sqrt(head.x*head.x + head.y*head.y); // NAN fix shouldn't be necessary if inputs are normalized + double head2dnorm = 1.0 / sqrt(head.x * head.x + head.y * head.y); // NAN fix shouldn't be necessary if inputs are normalized dav.x = head.y * head2dnorm * iangvel; dav.y = -head.x * head2dnorm * iangvel; } - const vector3d cav = m_dBody->GetAngVelocity() * m_dBody->GetOrient(); // current obj-rel angvel + const vector3d cav = m_dBody->GetAngVelocity() * m_dBody->GetOrient(); // current obj-rel angvel const double frameAccel = maxAccel * Pi::game->GetTimeStep(); - vector3d diff = is_zero_exact(frameAccel) ? vector3d(0.0) : (dav - cav) / frameAccel; // find diff between current & desired angvel + vector3d diff = is_zero_exact(frameAccel) ? vector3d(0.0) : (dav - cav) / frameAccel; // find diff between current & desired angvel // If the player is pressing a roll key, don't override roll. // XXX this really shouldn't be here. a better way would be to have a @@ -431,7 +442,7 @@ double Propulsion::AIFaceDirection(const vector3d &dir, double av) } // returns direction in ship's frame from this ship to target lead position -vector3d Propulsion::AIGetLeadDir(const Body *target, const vector3d& targaccel, double projspeed) +vector3d Propulsion::AIGetLeadDir(const Body *target, const vector3d &targaccel, double projspeed) { assert(target); const vector3d targpos = target->GetPositionRelTo(m_dBody); @@ -439,14 +450,14 @@ vector3d Propulsion::AIGetLeadDir(const Body *target, const vector3d& targaccel, // todo: should adjust targpos for gunmount offset vector3d leadpos; // avoid a divide-by-zero floating point exception (very nearly zero is ok) - if( !is_zero_exact(projspeed) ) { + if (!is_zero_exact(projspeed)) { // first attempt double projtime = targpos.Length() / projspeed; - leadpos = targpos + targvel*projtime + 0.5*targaccel*projtime*projtime; + leadpos = targpos + targvel * projtime + 0.5 * targaccel * projtime * projtime; // second pass projtime = leadpos.Length() / projspeed; - leadpos = targpos + targvel*projtime + 0.5*targaccel*projtime*projtime; + leadpos = targpos + targvel * projtime + 0.5 * targaccel * projtime * projtime; } else { // default leadpos = targpos; diff --git a/src/Propulsion.h b/src/Propulsion.h index 139aaa627..0ebfb08a9 100644 --- a/src/Propulsion.h +++ b/src/Propulsion.h @@ -4,13 +4,13 @@ #ifndef PROPULSION_H #define PROPULSION_H -#include "vector3.h" -#include "libs.h" -#include "Space.h" #include "Camera.h" -#include "JsonUtils.h" -#include "scenegraph/Model.h" #include "DynamicBody.h" +#include "JsonUtils.h" +#include "Space.h" +#include "libs.h" +#include "scenegraph/Model.h" +#include "vector3.h" enum Thruster { // THRUSTER_REVERSE, @@ -22,120 +22,118 @@ enum Thruster { // }; -class Propulsion : public RefCounted -{ - public: - // Inits: - Propulsion(); - virtual ~Propulsion() {}; - // Acceleration cap is infinite - void Init(DynamicBody *b, SceneGraph::Model *m, const int tank_mass, const double effExVel, const float lin_Thrust[], const float ang_Thrust); - void Init(DynamicBody *b, SceneGraph::Model *m, const int tank_mass, const double effExVel, const float lin_Thrust[], const float ang_Thrust, const float lin_AccelerationCap[]); +class Propulsion : public RefCounted { +public: + // Inits: + Propulsion(); + virtual ~Propulsion(){}; + // Acceleration cap is infinite + void Init(DynamicBody *b, SceneGraph::Model *m, const int tank_mass, const double effExVel, const float lin_Thrust[], const float ang_Thrust); + void Init(DynamicBody *b, SceneGraph::Model *m, const int tank_mass, const double effExVel, const float lin_Thrust[], const float ang_Thrust, const float lin_AccelerationCap[]); - virtual void SaveToJson(Json &jsonObj, Space *space); - virtual void LoadFromJson(const Json &jsonObj, Space *space); + virtual void SaveToJson(Json &jsonObj, Space *space); + virtual void LoadFromJson(const Json &jsonObj, Space *space); - // Bonus: - void SetThrustPowerMult(double p, const float lin_Thrust[], const float ang_Thrust); - void SetAccelerationCapMult(double p, const float lin_AccelerationCap[]); + // Bonus: + void SetThrustPowerMult(double p, const float lin_Thrust[], const float ang_Thrust); + void SetAccelerationCapMult(double p, const float lin_AccelerationCap[]); - // Thrust and thruster functions - // Everything's capped unless specified otherwise. - double GetThrust(Thruster thruster) const; // Maximum thrust possible within acceleration cap - vector3d GetThrust(const vector3d &dir) const; - inline double GetThrustFwd() const { return GetThrust(THRUSTER_FORWARD); } - inline double GetThrustRev() const { return GetThrust(THRUSTER_REVERSE); } - inline double GetThrustUp() const { return GetThrust(THRUSTER_UP); } - double GetThrustMin() const; + // Thrust and thruster functions + // Everything's capped unless specified otherwise. + double GetThrust(Thruster thruster) const; // Maximum thrust possible within acceleration cap + vector3d GetThrust(const vector3d &dir) const; + inline double GetThrustFwd() const { return GetThrust(THRUSTER_FORWARD); } + inline double GetThrustRev() const { return GetThrust(THRUSTER_REVERSE); } + inline double GetThrustUp() const { return GetThrust(THRUSTER_UP); } + double GetThrustMin() const; - vector3d GetThrustUncapped(const vector3d &dir) const; + vector3d GetThrustUncapped(const vector3d &dir) const; - inline double GetAccel(Thruster thruster) const { return GetThrust(thruster) / m_dBody->GetMass(); } - inline double GetAccelFwd() const { return GetAccel(THRUSTER_FORWARD); } //GetThrustFwd() / m_dBody->GetMass(); } - inline double GetAccelRev() const { return GetAccel(THRUSTER_REVERSE); } //GetThrustRev() / m_dBody->GetMass(); } - inline double GetAccelUp() const { return GetAccel(THRUSTER_UP); } //GetThrustUp() / m_dBody->GetMass(); } - inline double GetAccelMin() const { return GetThrustMin() / m_dBody->GetMass(); } + inline double GetAccel(Thruster thruster) const { return GetThrust(thruster) / m_dBody->GetMass(); } + inline double GetAccelFwd() const { return GetAccel(THRUSTER_FORWARD); } //GetThrustFwd() / m_dBody->GetMass(); } + inline double GetAccelRev() const { return GetAccel(THRUSTER_REVERSE); } //GetThrustRev() / m_dBody->GetMass(); } + inline double GetAccelUp() const { return GetAccel(THRUSTER_UP); } //GetThrustUp() / m_dBody->GetMass(); } + inline double GetAccelMin() const { return GetThrustMin() / m_dBody->GetMass(); } - // Clamp thruster levels and scale them down so that a level of 1 - // corresponds to the thrust from GetThrust(). - double ClampLinThrusterState(int axis, double level) const; - vector3d ClampLinThrusterState(const vector3d &levels) const; + // Clamp thruster levels and scale them down so that a level of 1 + // corresponds to the thrust from GetThrust(). + double ClampLinThrusterState(int axis, double level) const; + vector3d ClampLinThrusterState(const vector3d &levels) const; - // A level of 1 corresponds to the thrust from GetThrust(). - void SetLinThrusterState(int axis, double level); - void SetLinThrusterState(const vector3d &levels); + // A level of 1 corresponds to the thrust from GetThrust(). + void SetLinThrusterState(int axis, double level); + void SetLinThrusterState(const vector3d &levels); - inline void SetAngThrusterState(int axis, double level) { m_angThrusters[axis] = Clamp(level, -1.0, 1.0); } - void SetAngThrusterState(const vector3d &levels); + inline void SetAngThrusterState(int axis, double level) { m_angThrusters[axis] = Clamp(level, -1.0, 1.0); } + void SetAngThrusterState(const vector3d &levels); - inline vector3d GetLinThrusterState() const { return m_linThrusters; }; - inline vector3d GetAngThrusterState() const { return m_angThrusters; } + inline vector3d GetLinThrusterState() const { return m_linThrusters; }; + inline vector3d GetAngThrusterState() const { return m_angThrusters; } - inline void ClearLinThrusterState() { m_linThrusters = vector3d(0,0,0); } - inline void ClearAngThrusterState() { m_angThrusters = vector3d(0,0,0); } + inline void ClearLinThrusterState() { m_linThrusters = vector3d(0, 0, 0); } + inline void ClearAngThrusterState() { m_angThrusters = vector3d(0, 0, 0); } - inline vector3d GetActualLinThrust() const { return m_linThrusters * GetThrustUncapped(m_linThrusters); } - inline vector3d GetActualAngThrust() const { return m_angThrusters * m_angThrust; } + inline vector3d GetActualLinThrust() const { return m_linThrusters * GetThrustUncapped(m_linThrusters); } + inline vector3d GetActualAngThrust() const { return m_angThrusters * m_angThrust; } - // Fuel - enum FuelState { // - FUEL_OK, - FUEL_WARNING, - FUEL_EMPTY, - }; + // Fuel + enum FuelState { // + FUEL_OK, + FUEL_WARNING, + FUEL_EMPTY, + }; - inline FuelState GetFuelState() const { return (m_thrusterFuel > 0.05f) ? FUEL_OK : (m_thrusterFuel > 0.0f) ? FUEL_WARNING : FUEL_EMPTY; } - // fuel left, 0.0-1.0 - inline double GetFuel() const { return m_thrusterFuel; } - inline double GetFuelReserve() const { return m_reserveFuel; } - inline void SetFuel(const double f) { m_thrusterFuel = Clamp(f, 0.0, 1.0 ); } - inline void SetFuelReserve(const double f) { m_reserveFuel = Clamp(f, 0.0, 1.0 ); } - float GetFuelUseRate(); - // available delta-V given the ship's current fuel minus reserve according to the Tsiolkovsky equation - double GetSpeedReachedWithFuel() const; - /* TODO: These are needed to avoid savegamebumps: + inline FuelState GetFuelState() const { return (m_thrusterFuel > 0.05f) ? FUEL_OK : (m_thrusterFuel > 0.0f) ? FUEL_WARNING : FUEL_EMPTY; } + // fuel left, 0.0-1.0 + inline double GetFuel() const { return m_thrusterFuel; } + inline double GetFuelReserve() const { return m_reserveFuel; } + inline void SetFuel(const double f) { m_thrusterFuel = Clamp(f, 0.0, 1.0); } + inline void SetFuelReserve(const double f) { m_reserveFuel = Clamp(f, 0.0, 1.0); } + float GetFuelUseRate(); + // available delta-V given the ship's current fuel minus reserve according to the Tsiolkovsky equation + double GetSpeedReachedWithFuel() const; + /* TODO: These are needed to avoid savegamebumps: * are used to pass things to/from shipStats; * may be better if you not expose these fields */ - inline float FuelTankMassLeft() { return m_fuelTankMass * m_thrusterFuel; } - inline void SetFuelTankMass( int fTank ) { m_fuelTankMass = fTank; } - void UpdateFuel(const float timeStep); - inline bool IsFuelStateChanged() { return m_fuelStateChange; } + inline float FuelTankMassLeft() { return m_fuelTankMass * m_thrusterFuel; } + inline void SetFuelTankMass(int fTank) { m_fuelTankMass = fTank; } + void UpdateFuel(const float timeStep); + inline bool IsFuelStateChanged() { return m_fuelStateChange; } - void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform); + void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform); - // AI on Propulsion - void AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double softness); - void AIModelCoordsMatchSpeedRelTo(const vector3d &v, const DynamicBody *other); - void AIAccelToModelRelativeVelocity(const vector3d &v); + // AI on Propulsion + void AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double softness); + void AIModelCoordsMatchSpeedRelTo(const vector3d &v, const DynamicBody *other); + void AIAccelToModelRelativeVelocity(const vector3d &v); - bool AIMatchVel(const vector3d &vel); - bool AIChangeVelBy(const vector3d &diffvel); // acts in object space - vector3d AIChangeVelDir(const vector3d &diffvel); // object space, maintain direction - void AIMatchAngVelObjSpace(const vector3d &angvel); - double AIFaceUpdir(const vector3d &updir, double av=0); - double AIFaceDirection(const vector3d &dir, double av=0); - vector3d AIGetLeadDir(const Body *target, const vector3d& targaccel, double projspeed); + bool AIMatchVel(const vector3d &vel); + bool AIChangeVelBy(const vector3d &diffvel); // acts in object space + vector3d AIChangeVelDir(const vector3d &diffvel); // object space, maintain direction + void AIMatchAngVelObjSpace(const vector3d &angvel); + double AIFaceUpdir(const vector3d &updir, double av = 0); + double AIFaceDirection(const vector3d &dir, double av = 0); + vector3d AIGetLeadDir(const Body *target, const vector3d &targaccel, double projspeed); - private: - // Thrust and thrusters - float m_linThrust[THRUSTER_MAX]; - float m_angThrust; - vector3d m_linThrusters; // 0.0-1.0, thruster levels - vector3d m_angThrusters; // 0.0-1.0 - // Used to calculate max linear thrust by limiting the thruster levels - float m_linAccelerationCap[THRUSTER_MAX]; +private: + // Thrust and thrusters + float m_linThrust[THRUSTER_MAX]; + float m_angThrust; + vector3d m_linThrusters; // 0.0-1.0, thruster levels + vector3d m_angThrusters; // 0.0-1.0 + // Used to calculate max linear thrust by limiting the thruster levels + float m_linAccelerationCap[THRUSTER_MAX]; - // Fuel - int m_fuelTankMass; - double m_thrusterFuel; // 0.0-1.0, remaining fuel - double m_reserveFuel; // 0.0-1.0, fuel not to touch for the current AI program - double m_effectiveExhaustVelocity; - bool m_fuelStateChange; - - const DynamicBody *m_dBody; - SceneGraph::Model *m_smodel; + // Fuel + int m_fuelTankMass; + double m_thrusterFuel; // 0.0-1.0, remaining fuel + double m_reserveFuel; // 0.0-1.0, fuel not to touch for the current AI program + double m_effectiveExhaustVelocity; + bool m_fuelStateChange; + const DynamicBody *m_dBody; + SceneGraph::Model *m_smodel; }; #endif // PROPULSION_H diff --git a/src/Quaternion.h b/src/Quaternion.h index f80e9e50d..8615f9fb7 100644 --- a/src/Quaternion.h +++ b/src/Quaternion.h @@ -4,14 +4,14 @@ #ifndef _QUATERNION_H #define _QUATERNION_H -#include -#include "vector3.h" #include "matrix4x4.h" +#include "vector3.h" +#include template class Quaternion { public: - T w,x,y,z; + T w, x, y, z; // Constructor definitions are outside class declaration to enforce that // only float and double versions are possible. @@ -19,13 +19,14 @@ public: Quaternion(T w, T x, T y, T z); // from angle and axis Quaternion(T ang, vector3 axis); - Quaternion(const Quaternion &o); + Quaternion(const Quaternion &o); Quaternion(const Quaternion &o); - void GetAxisAngle(T &angle, vector3 &axis) const { + void GetAxisAngle(T &angle, vector3 &axis) const + { if (w > 1.0) *this = Normalized(); // if w>1 acos and sqrt will produce errors, this cant happen if quaternion is normalised angle = 2.0 * acos(w); - double s = sqrt(1.0-w*w); // assuming quaternion normalised then w is less than 1, so term always positive. + double s = sqrt(1.0 - w * w); // assuming quaternion normalised then w is less than 1, so term always positive. if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt // if s close to zero then direction of axis not important axis.x = x; // if it is important that axis is normalised then replace with x=1; y=z=0; @@ -38,7 +39,8 @@ public: } } // conjugate (inverse) - friend Quaternion operator~ (const Quaternion &a) { + friend Quaternion operator~(const Quaternion &a) + { Quaternion r; r.w = a.w; r.x = -a.x; @@ -46,48 +48,54 @@ public: r.z = -a.z; return r; } - friend Quaternion operator* (const Quaternion &a, const Quaternion &b) { + friend Quaternion operator*(const Quaternion &a, const Quaternion &b) + { Quaternion r; - r.w = a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z; - r.x = a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y; - r.y = a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x; - r.z = a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w; + r.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z; + r.x = a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y; + r.y = a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x; + r.z = a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w; return r; } - friend Quaternion operator* (const T s, const Quaternion &a) { return a*s; } - friend Quaternion operator* (const Quaternion &a, const T s) { + friend Quaternion operator*(const T s, const Quaternion &a) { return a * s; } + friend Quaternion operator*(const Quaternion &a, const T s) + { Quaternion r; - r.w = a.w*s; - r.x = a.x*s; - r.y = a.y*s; - r.z = a.z*s; + r.w = a.w * s; + r.x = a.x * s; + r.y = a.y * s; + r.z = a.z * s; return r; } - friend Quaternion operator+ (const Quaternion &a, const Quaternion &b) { + friend Quaternion operator+(const Quaternion &a, const Quaternion &b) + { Quaternion r; - r.w = a.w+b.w; - r.x = a.x+b.x; - r.y = a.y+b.y; - r.z = a.z+b.z; + r.w = a.w + b.w; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; return r; } - friend Quaternion operator- (const Quaternion &a, const Quaternion &b) { + friend Quaternion operator-(const Quaternion &a, const Quaternion &b) + { Quaternion r; - r.w = a.w-b.w; - r.x = a.x-b.x; - r.y = a.y-b.y; - r.z = a.z-b.z; + r.w = a.w - b.w; + r.x = a.x - b.x; + r.y = a.y - b.y; + r.z = a.z - b.z; return r; } - Quaternion Normalized() const { - T l = 1.0 / sqrt (w*w + x*x + y*y + z*z); - return Quaternion(w*l, x*l, y*l, z*l); + Quaternion Normalized() const + { + T l = 1.0 / sqrt(w * w + x * x + y * y + z * z); + return Quaternion(w * l, x * l, y * l, z * l); } - static T Dot (const Quaternion &a, const Quaternion &b) { return a.w*b.w + a.x*b.x + a.y*b.y + a.z*b.z; } + static T Dot(const Quaternion &a, const Quaternion &b) { return a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z; } template - static Quaternion FromMatrix3x3(const matrix3x3 &m) { + static Quaternion FromMatrix3x3(const matrix3x3 &m) + { Quaternion r; if (m[0] + m[4] + m[8] > 0.0f) { U t = m[0] + m[4] + m[8] + 1.0; @@ -122,7 +130,8 @@ public: } template - matrix3x3 ToMatrix3x3() const { + matrix3x3 ToMatrix3x3() const + { matrix3x3 m; U xx = x * x; U xy = x * y; @@ -137,36 +146,38 @@ public: U zw = z * w; m[0] = 1.0 - 2.0 * (yy + zz); - m[1] = 2.0 * (xy - zw); - m[2] = 2.0 * (xz + yw); + m[1] = 2.0 * (xy - zw); + m[2] = 2.0 * (xz + yw); - m[3] = 2.0 * (xy + zw); + m[3] = 2.0 * (xy + zw); m[4] = 1.0 - 2.0 * (xx + zz); - m[5] = 2.0 * (yz - xw); + m[5] = 2.0 * (yz - xw); - m[6] = 2.0 * (xz - yw); - m[7] = 2.0 * (yz + xw); + m[6] = 2.0 * (xz - yw); + m[7] = 2.0 * (yz + xw); m[8] = 1.0 - 2.0 * (xx + yy); return m; } /* normalized linear interpolation between 2 quaternions */ - static Quaternion Nlerp(const Quaternion &a, const Quaternion &b, T t) { + static Quaternion Nlerp(const Quaternion &a, const Quaternion &b, T t) + { //printf("a: %f,%f,%f,%f\n", a.x, a.y, a.z, a.w); //printf("b: %f,%f,%f,%f\n", b.x, b.y, b.z, b.w); - return (a + t*(b-a)).Normalized(); + return (a + t * (b - a)).Normalized(); } // spherical linear interpolation between two quaternions // taken from assimp via #2514 - static Quaternion Slerp(const Quaternion &a, const Quaternion &b, T t) { + static Quaternion Slerp(const Quaternion &a, const Quaternion &b, T t) + { // calc cosine theta T cosom = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; // adjust signs (if necessary) Quaternion end = b; - if(cosom < T(0.0)) { + if (cosom < T(0.0)) { cosom = -cosom; - end.x = -end.x; // Reverse all signs + end.x = -end.x; // Reverse all signs end.y = -end.y; end.z = -end.z; end.w = -end.w; @@ -174,15 +185,14 @@ public: // Calculate coefficients T sclp, sclq; - if( (T(1.0) - cosom) > T(0.0001)) { // 0.0001 -> some epsillon + if ((T(1.0) - cosom) > T(0.0001)) { // 0.0001 -> some epsillon // Standard case (slerp) T omega, sinom; omega = acos(cosom); // extract theta from dot product's cos theta sinom = sin(omega); - sclp = sin((T(1.0) - t) * omega) / sinom; - sclq = sin(t * omega) / sinom; - } - else { + sclp = sin((T(1.0) - t) * omega) / sinom; + sclq = sin(t * omega) / sinom; + } else { // Very close, do linear interp (because it's faster) sclp = T(1.0) - t; sclq = t; @@ -192,8 +202,7 @@ public: sclp * a.w + sclq * end.w, sclp * a.x + sclq * end.x, sclp * a.y + sclq * end.y, - sclp * a.z + sclq * end.z - ); + sclp * a.z + sclq * end.z); } //void Print() const { @@ -201,21 +210,37 @@ public: //} }; -template<> inline Quaternion::Quaternion() {} -template<> inline Quaternion::Quaternion() {} -template<> inline Quaternion::Quaternion(float w_, float x_, float y_, float z_): w(w_), x(x_), y(y_), z(z_) {} -template<> inline Quaternion::Quaternion(double w_, double x_, double y_, double z_): w(w_), x(x_), y(y_), z(z_) {} +template <> +inline Quaternion::Quaternion() {} +template <> +inline Quaternion::Quaternion() {} +template <> +inline Quaternion::Quaternion(float w_, float x_, float y_, float z_) : + w(w_), + x(x_), + y(y_), + z(z_) {} +template <> +inline Quaternion::Quaternion(double w_, double x_, double y_, double z_) : + w(w_), + x(x_), + y(y_), + z(z_) {} -template<> inline Quaternion::Quaternion(float ang, vector3 axis) { - const float halfAng = ang*0.5f; +template <> +inline Quaternion::Quaternion(float ang, vector3 axis) +{ + const float halfAng = ang * 0.5f; const float sinHalfAng = sin(halfAng); w = cos(halfAng); x = axis.x * sinHalfAng; y = axis.y * sinHalfAng; z = axis.z * sinHalfAng; } -template<> inline Quaternion::Quaternion(double ang, vector3 axis) { - const double halfAng = ang*0.5; +template <> +inline Quaternion::Quaternion(double ang, vector3 axis) +{ + const double halfAng = ang * 0.5; const double sinHalfAng = sin(halfAng); w = cos(halfAng); x = axis.x * sinHalfAng; @@ -223,12 +248,32 @@ template<> inline Quaternion::Quaternion(double ang, vector3 axi z = axis.z * sinHalfAng; } -template<> inline Quaternion::Quaternion(const Quaternion &o): w(o.w), x(o.x), y(o.y), z(o.z) {} -template<> inline Quaternion::Quaternion(const Quaternion &o): w(float(o.w)), x(float(o.x)), y(float(o.y)), z(float(o.z)) {} -template<> inline Quaternion::Quaternion(const Quaternion &o): w(o.w), x(o.x), y(o.y), z(o.z) {} -template<> inline Quaternion::Quaternion(const Quaternion &o): w(o.w), x(o.x), y(o.y), z(o.z) {} +template <> +inline Quaternion::Quaternion(const Quaternion &o) : + w(o.w), + x(o.x), + y(o.y), + z(o.z) {} +template <> +inline Quaternion::Quaternion(const Quaternion &o) : + w(float(o.w)), + x(float(o.x)), + y(float(o.y)), + z(float(o.z)) {} +template <> +inline Quaternion::Quaternion(const Quaternion &o) : + w(o.w), + x(o.x), + y(o.y), + z(o.z) {} +template <> +inline Quaternion::Quaternion(const Quaternion &o) : + w(o.w), + x(o.x), + y(o.y), + z(o.z) {} -typedef Quaternion Quaternionf; +typedef Quaternion Quaternionf; typedef Quaternion Quaterniond; #endif /* _QUATERNION_H */ diff --git a/src/Random.h b/src/Random.h index e030dc81b..96ec6ba45 100644 --- a/src/Random.h +++ b/src/Random.h @@ -13,8 +13,8 @@ #include #include -#include "fixed.h" #include "RefCounted.h" +#include "fixed.h" extern "C" { #include "jenkins/lookup3.h" @@ -24,8 +24,7 @@ extern "C" { #include "pcg-cpp/pcg_random.hpp" // A deterministic random number generator -class Random : public RefCounted -{ +class Random : public RefCounted { pcg32 mPCG; // For storing second rand from Normal @@ -33,7 +32,6 @@ class Random : public RefCounted double z1; public: - // // Constructors // @@ -45,16 +43,16 @@ public: } // Construct a new generator given an array of 32-bit seeds. - Random(const Uint32* const seeds, size_t length) + Random(const Uint32 *const seeds, size_t length) { seed(seeds, length); } // Construct a new random generator from an array of 64-bit // seeds. - Random(const Uint64* const seeds, size_t length) + Random(const Uint64 *const seeds, size_t length) { - seed(reinterpret_cast(seeds), length * 2); + seed(reinterpret_cast(seeds), length * 2); } // @@ -62,7 +60,7 @@ public: // // Seed the RNG using the hash of the given array of seeds. - void seed(const Uint32* const seeds, size_t length) + void seed(const Uint32 *const seeds, size_t length) { const Uint32 hash = lookup3_hashword(seeds, length, 0); mPCG.seed(hash); @@ -70,9 +68,9 @@ public: } // Seed using an array of 64-bit integers - void seed(const Uint64* const seeds, size_t length) + void seed(const Uint64 *const seeds, size_t length) { - seed(reinterpret_cast(seeds), length * 2); + seed(reinterpret_cast(seeds), length * 2); } // Seed using a single 32-bit integer @@ -145,14 +143,14 @@ public: // Pick a number in the half-open interval [0, limit) inline double Double(double limit) { - return limit*Double(); + return limit * Double(); } // Pick a number between 0 and max inclusive // interval [0, max] inline double Double_closed(double max) { - return max*Double_closed(); + return max * Double_closed(); } // Pick a number between min and max inclusive @@ -189,26 +187,23 @@ public: //https://en.wikipedia.org/wiki/Box-Muller_transform#Polar_form double u, v, s, z0; - if (cached) - { + if (cached) { z0 = z1; cached = false; - } - else - { - do{ + } else { + do { u = Double_closed(-1, 1); v = Double_closed(-1, 1); - s = u*u + v*v; - }while (s >= 1.0); + s = u * u + v * v; + } while (s >= 1.0); - s = sqrt((-2.0 * log(s))/s); + s = sqrt((-2.0 * log(s)) / s); z0 = u * s; z1 = v * s; cached = true; } - return mean + z0 * stddev; + return mean + z0 * stddev; } inline int Poisson(const double lambda) @@ -216,8 +211,7 @@ public: int k = 0; double p = Double(); const double target = exp(-lambda); - while (p > target) - { + while (p > target) { k += 1; p *= Double(); } @@ -240,9 +234,10 @@ public: } const pcg32 &GetPCG() const { return mPCG; } + private: - Random(const Random&); // copy constructor not defined - void operator=(const Random&); // assignment operator not defined + Random(const Random &); // copy constructor not defined + void operator=(const Random &); // assignment operator not defined }; #endif // RAND_H diff --git a/src/RandomColor.cpp b/src/RandomColor.cpp index 54bdd84e0..60cb7f8f4 100644 --- a/src/RandomColor.cpp +++ b/src/RandomColor.cpp @@ -3,11 +3,10 @@ #include "RandomColor.h" #include "libs.h" -#include #include "utils.h" +#include -namespace RandomColorGenerator -{ +namespace RandomColorGenerator { //static std::map RandomColor::ColorDictionary; static Random *pRNG = nullptr; @@ -49,8 +48,7 @@ namespace RandomColorGenerator pRNG = &rand; std::vector ret; ret.resize(count); - for ( int i = 0; i < count; i++ ) - { + for (int i = 0; i < count; i++) { ret[i] = GetColor(scheme, luminosity); } pRNG = nullptr; @@ -65,7 +63,7 @@ namespace RandomColorGenerator // Instead of storing red as two separate ranges, // we group them, using negative numbers - if ( hue < 0 ) hue = 360 + hue; + if (hue < 0) hue = 360 + hue; return hue; } @@ -73,13 +71,11 @@ namespace RandomColorGenerator //static int RandomColor::PickSaturation(int hue, Luminosity luminosity, ColorScheme scheme) { - if ( luminosity == Luminosity::LUMINOSITY_RANDOM ) - { + if (luminosity == Luminosity::LUMINOSITY_RANDOM) { return RandomWithin(0, 100); } - if ( scheme == ColorScheme::SCHEME_MONOCHROME ) - { + if (scheme == ColorScheme::SCHEME_MONOCHROME) { return 0; } @@ -88,8 +84,7 @@ namespace RandomColorGenerator int sMin = saturationRange.Lower; int sMax = saturationRange.Upper; - switch ( luminosity ) - { + switch (luminosity) { case Luminosity::LUMINOSITY_BRIGHT: sMin = 55; break; @@ -116,8 +111,7 @@ namespace RandomColorGenerator auto bMin = GetMinimumBrightness(H, S); auto bMax = 100; - switch ( luminosity ) - { + switch (luminosity) { case Luminosity::LUMINOSITY_DARK: bMax = bMin + 20; break; @@ -144,16 +138,14 @@ namespace RandomColorGenerator { auto lowerBounds = GetColorInfo(H).LowerBounds; - for ( size_t i = 0; i < std::min(lowerBounds.size(), lowerBounds.size() - 1U); i++ ) - { + for (size_t i = 0; i < std::min(lowerBounds.size(), lowerBounds.size() - 1U); i++) { auto s1 = lowerBounds[i].x; auto v1 = lowerBounds[i].y; auto s2 = lowerBounds[i + 1].x; auto v2 = lowerBounds[i + 1].y; - if ( S >= s1 && S <= s2 ) - { + if (S >= s1 && S <= s2) { auto m = (v2 - v1) / (s2 - s1); auto b = v1 - m * s1; @@ -168,8 +160,7 @@ namespace RandomColorGenerator Range RandomColor::GetHueRange(ColorScheme colorInput) { std::map::iterator out = ColorDictionary.find(colorInput); - if ( out != ColorDictionary.end() ) - { + if (out != ColorDictionary.end()) { return out->second.HueRange; } @@ -180,13 +171,12 @@ namespace RandomColorGenerator RandomColor::DefinedColor RandomColor::GetColorInfo(int hue) { // Maps red colors to make picking hue easier - if ( hue >= 334 && hue <= 360 ) - { + if (hue >= 334 && hue <= 360) { hue -= 360; } - for ( auto c : ColorDictionary ) { - if ( hue >= c.second.HueRange[0] && hue <= c.second.HueRange[1] ) { + for (auto c : ColorDictionary) { + if (hue >= c.second.HueRange[0] && hue <= c.second.HueRange[1]) { return c.second; } } @@ -216,7 +206,7 @@ namespace RandomColorGenerator DefinedColor defCol; defCol.HueRange = Range(hueRange.x, hueRange.y); - for ( size_t lb = 0; lb < lbCount; lb++ ) { + for (size_t lb = 0; lb < lbCount; lb++) { defCol.LowerBounds.push_back(lowerBounds[lb]); } defCol.SaturationRange = Range(sMin, sMax); @@ -233,64 +223,56 @@ namespace RandomColorGenerator ColorScheme::SCHEME_MONOCHROME, Point(0, 360), mono, - COUNTOF(mono) - ); + COUNTOF(mono)); Point red[] = { { 20, 100 }, { 30, 92 }, { 40, 89 }, { 50, 85 }, { 60, 78 }, { 70, 70 }, { 80, 60 }, { 90, 55 }, { 100, 50 } }; DefineColor( ColorScheme::SCHEME_RED, Point(-26, 18), red, - COUNTOF(red) - ); + COUNTOF(red)); Point orange[] = { { 20, 100 }, { 30, 93 }, { 40, 88 }, { 50, 86 }, { 60, 85 }, { 70, 70 }, { 100, 70 } }; DefineColor( ColorScheme::SCHEME_ORANGE, Point(19, 46), orange, - COUNTOF(orange) - ); + COUNTOF(orange)); Point yellow[] = { { 25, 100 }, { 40, 94 }, { 50, 89 }, { 60, 86 }, { 70, 84 }, { 80, 82 }, { 90, 80 }, { 100, 75 } }; DefineColor( ColorScheme::SCHEME_YELLOW, Point(47, 62), yellow, - COUNTOF(yellow) - ); + COUNTOF(yellow)); Point green[] = { { 30, 100 }, { 40, 90 }, { 50, 85 }, { 60, 81 }, { 70, 74 }, { 80, 64 }, { 90, 50 }, { 100, 40 } }; DefineColor( ColorScheme::SCHEME_GREEN, Point(63, 178), green, - COUNTOF(green) - ); + COUNTOF(green)); Point blue[] = { { 20, 100 }, { 30, 86 }, { 40, 80 }, { 50, 74 }, { 60, 60 }, { 70, 52 }, { 80, 44 }, { 90, 39 }, { 100, 35 } }; DefineColor( ColorScheme::SCHEME_BLUE, Point(179, 257), blue, - COUNTOF(blue) - ); + COUNTOF(blue)); Point purple[] = { { 20, 100 }, { 30, 87 }, { 40, 79 }, { 50, 70 }, { 60, 65 }, { 70, 59 }, { 80, 52 }, { 90, 45 }, { 100, 42 } }; DefineColor( ColorScheme::SCHEME_PURPLE, Point(258, 282), purple, - COUNTOF(purple) - ); + COUNTOF(purple)); Point pink[] = { { 20, 100 }, { 30, 90 }, { 40, 86 }, { 60, 84 }, { 80, 80 }, { 90, 75 }, { 100, 73 } }; DefineColor( ColorScheme::SCHEME_PINK, Point(283, 334), pink, - COUNTOF(pink) - ); + COUNTOF(pink)); } /// Converts hue, saturation, and lightness to a color. @@ -300,12 +282,10 @@ namespace RandomColorGenerator // this doesn't work for the values of 0 and 360 // here's the hacky fix auto h = double(hue); - if ( is_equal_exact(h, 0.0) ) - { + if (is_equal_exact(h, 0.0)) { h = 1.0; } - if ( is_equal_exact(h, 360.0) ) - { + if (is_equal_exact(h, 360.0)) { h = 359.0; } @@ -323,20 +303,43 @@ namespace RandomColorGenerator auto g = 256.0; auto b = 256.0; - switch ( hInt ) - { - case 0: r = v; g = t; b = p; break; - case 1: r = q; g = v; b = p; break; - case 2: r = p; g = v; b = t; break; - case 3: r = p; g = q; b = v; break; - case 4: r = t; g = p; b = v; break; - case 5: r = v; g = p; b = q; break; + switch (hInt) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; } auto c = Color(static_cast(floor(r * 255.0)), - static_cast(floor(g * 255.0)), - static_cast(floor(b * 255.0)), - 255); + static_cast(floor(g * 255.0)), + static_cast(floor(b * 255.0)), + 255); return c; } -}; +}; // namespace RandomColorGenerator diff --git a/src/RandomColor.h b/src/RandomColor.h index fe138fed9..b9f4c66f9 100644 --- a/src/RandomColor.h +++ b/src/RandomColor.h @@ -41,17 +41,15 @@ // around the same time a coworker was creating an ad hoc visualization app. As we watched the data appear on screen, we had to squint as some of the colors // were very difficult to make out against the background. This should make things easier to see and will hopefully help others as well. -#include "Range.h" -#include "Random.h" #include "Color.h" +#include "Random.h" +#include "Range.h" -#include #include +#include -namespace RandomColorGenerator -{ - enum ColorScheme - { +namespace RandomColorGenerator { + enum ColorScheme { // Select randomly from among the other color schemes. SCHEME_RANDOM = 0, // Generates only grayscale colors. @@ -72,8 +70,7 @@ namespace RandomColorGenerator SCHEME_PINK }; - enum Luminosity - { + enum Luminosity { // Select randomly from among the other luminosities. LUMINOSITY_RANDOM = 0, // Generate dark colors. @@ -86,17 +83,19 @@ namespace RandomColorGenerator class Point { public: - Point() : x(0), y(0) {} - Point(int nx, int ny) : x(nx), y(ny) {} + Point() : + x(0), + y(0) {} + Point(int nx, int ny) : + x(nx), + y(ny) {} int x, y; }; // Generates random numbers. - class RandomColor - { + class RandomColor { private: - class DefinedColor - { + class DefinedColor { public: DefinedColor() {} Range HueRange; @@ -145,7 +144,6 @@ namespace RandomColorGenerator // Converts hue, saturation, and lightness to a color. static Color HsvToColor(int hue, int saturation, double value); }; -}; - +}; // namespace RandomColorGenerator #endif // _RANDOM_COLOR_H_ diff --git a/src/Range.h b/src/Range.h index d104704db..b5cf10870 100644 --- a/src/Range.h +++ b/src/Range.h @@ -37,17 +37,19 @@ namespace RandomColorGenerator { int Upper; Range() {} - Range(int lower, int upper) - { + Range(int lower, int upper) + { Lower = lower; Upper = upper; - } + } - // Gets the lower range for an index of 0 and the upper for an index of 1. + // Gets the lower range for an index of 0 and the upper for an index of 1. const int &operator[](const size_t index) const { - if(index==0) return Lower; - else return Upper; + if (index == 0) + return Lower; + else + return Upper; } }; } // namespace RandomColorGenerator diff --git a/src/RefCounted.h b/src/RefCounted.h index de6408078..341395de8 100644 --- a/src/RefCounted.h +++ b/src/RefCounted.h @@ -4,25 +4,30 @@ #ifndef _REFCOUNTED_H #define _REFCOUNTED_H -#include -#include "SmartPtr.h" #include "LuaWrappable.h" +#include "SmartPtr.h" +#include class RefCounted : public LuaWrappable { public: - RefCounted() : m_refCount(0) {} + RefCounted() : + m_refCount(0) {} virtual ~RefCounted() {} inline void IncRefCount() const { ++m_refCount; } - inline void DecRefCount() const { assert(m_refCount > 0); if (! --m_refCount) delete this; } + inline void DecRefCount() const + { + assert(m_refCount > 0); + if (!--m_refCount) delete this; + } inline int GetRefCount() const { return m_refCount; } private: // vs2012 doesn't support the `= delete` syntax - RefCounted(const RefCounted&); - RefCounted(const RefCounted&&); - RefCounted& operator=(const RefCounted&); - RefCounted& operator=(const RefCounted&&); + RefCounted(const RefCounted &); + RefCounted(const RefCounted &&); + RefCounted &operator=(const RefCounted &); + RefCounted &operator=(const RefCounted &&); mutable std::atomic m_refCount; // We model logical constness, so refcount is changeable even for const objects }; @@ -31,34 +36,57 @@ template class RefCountedPtr : public SmartPtrBase, T> { typedef RefCountedPtr this_type; typedef SmartPtrBase base_type; + public: RefCountedPtr() {} - explicit RefCountedPtr(T *p): base_type(p) - { if (this->m_ptr) this->m_ptr->IncRefCount(); } + explicit RefCountedPtr(T *p) : + base_type(p) + { + if (this->m_ptr) this->m_ptr->IncRefCount(); + } // Note: This is still needed, the compiler would generate a default copy constructor despite the templated version - RefCountedPtr(const this_type& b): base_type(b.Get()) - { if (this->m_ptr) this->m_ptr->IncRefCount(); } + RefCountedPtr(const this_type &b) : + base_type(b.Get()) + { + if (this->m_ptr) this->m_ptr->IncRefCount(); + } // Generalized copy constructor, allowing copy for compatible pointer types (e.g. RefCountedPtr) template - RefCountedPtr(const RefCountedPtr& b): base_type(b.Get()) - { if (this->m_ptr) this->m_ptr->IncRefCount(); } + RefCountedPtr(const RefCountedPtr &b) : + base_type(b.Get()) + { + if (this->m_ptr) this->m_ptr->IncRefCount(); + } - ~RefCountedPtr() { + ~RefCountedPtr() + { T *p = this->Release(); if (p) p->DecRefCount(); } // Note: This is still needed, the compiler would generate a default assignment operator despite the templated version - this_type &operator=(const this_type &b) { this->Reset(b.Get()); return *this; } + this_type &operator=(const this_type &b) + { + this->Reset(b.Get()); + return *this; + } // Generalized assignment operator allowing assignment for compatible pointer types (e.g. RefCountedPtr) template - this_type &operator=(const RefCountedPtr& b) { this->Reset(b.Get()); return *this; } + this_type &operator=(const RefCountedPtr &b) + { + this->Reset(b.Get()); + return *this; + } - bool Unique() const { assert(this->m_ptr); return (this->m_ptr->GetRefCount() == 1); } + bool Unique() const + { + assert(this->m_ptr); + return (this->m_ptr->GetRefCount() == 1); + } }; #endif diff --git a/src/SDLWrappers.cpp b/src/SDLWrappers.cpp index 3664a8c55..238193fbf 100644 --- a/src/SDLWrappers.cpp +++ b/src/SDLWrappers.cpp @@ -1,9 +1,9 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "SDLWrappers.h" #include "FileSystem.h" +#include "libs.h" #include "utils.h" SDLSurfacePtr LoadSurfaceFromFile(const std::string &fname, FileSystem::FileSource &source) diff --git a/src/SDLWrappers.h b/src/SDLWrappers.h index 4efb83603..a147cc802 100644 --- a/src/SDLWrappers.h +++ b/src/SDLWrappers.h @@ -6,29 +6,56 @@ #include "SmartPtr.h" #include +#include -namespace FileSystem { class FileSource; } +namespace FileSystem { + class FileSource; +} struct SDL_Surface; class SDLSurfacePtr : public SmartPtrBase { typedef SmartPtrBase base_type; + private: - explicit SDLSurfacePtr(SDL_Surface *p): base_type(p) {} + explicit SDLSurfacePtr(SDL_Surface *p) : + base_type(p) {} + public: static SDLSurfacePtr WrapNew(SDL_Surface *p) { return SDLSurfacePtr(p); } - static SDLSurfacePtr WrapCopy(SDL_Surface *p) { if (p) { p->refcount += 1; } return SDLSurfacePtr(p); } + static SDLSurfacePtr WrapCopy(SDL_Surface *p) + { + if (p) { + p->refcount += 1; + } + return SDLSurfacePtr(p); + } SDLSurfacePtr() {} - SDLSurfacePtr(const SDLSurfacePtr& b): base_type(b.Get()) - { if (this->m_ptr) this->m_ptr->refcount += 1; } -// ~SDLSurfacePtr() { SDL_FreeSurface(this->Release()); } + SDLSurfacePtr(const SDLSurfacePtr &b) : + base_type(b.Get()) + { + if (this->m_ptr) this->m_ptr->refcount += 1; + } + // ~SDLSurfacePtr() { SDL_FreeSurface(this->Release()); } // workaround for SDL 2.0.6 FreeSurface bug - ~SDLSurfacePtr() { SDL_Surface *p = this->Release(); if (p && --p->refcount <= 0) SDL_FreeSurface(p); } + ~SDLSurfacePtr() + { + SDL_Surface *p = this->Release(); + if (p && --p->refcount <= 0) SDL_FreeSurface(p); + } - SDLSurfacePtr &operator=(const SDLSurfacePtr &b) { SDLSurfacePtr(b).Swap(*this); return *this; } + SDLSurfacePtr &operator=(const SDLSurfacePtr &b) + { + SDLSurfacePtr(b).Swap(*this); + return *this; + } - bool Unique() const { assert(this->m_ptr); return (this->m_ptr->refcount == 1); } + bool Unique() const + { + assert(this->m_ptr); + return (this->m_ptr->refcount == 1); + } }; SDLSurfacePtr LoadSurfaceFromFile(const std::string &fname, FileSystem::FileSource &source); diff --git a/src/SectorView.cpp b/src/SectorView.cpp index 73f786080..d593590cd 100644 --- a/src/SectorView.cpp +++ b/src/SectorView.cpp @@ -1,52 +1,54 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" +#include "SectorView.h" #include "Factions.h" #include "Game.h" +#include "GameSaveError.h" +#include "KeyBindings.h" #include "Lang.h" #include "LuaConstants.h" #include "MathUtil.h" #include "Pi.h" #include "Player.h" -#include "SectorView.h" #include "ShipCpanel.h" #include "StringF.h" #include "SystemInfoView.h" #include "galaxy/Galaxy.h" -#include "galaxy/Sector.h" #include "galaxy/GalaxyCache.h" +#include "galaxy/Sector.h" #include "galaxy/StarSystem.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" #include "gui/Gui.h" -#include "KeyBindings.h" -#include "GameSaveError.h" +#include "libs.h" +#include #include #include #include -#include using namespace Graphics; static const int DRAW_RAD = 5; -#define INNER_RADIUS (Sector::SIZE*1.5f) -#define OUTER_RADIUS (Sector::SIZE*float(DRAW_RAD)) +#define INNER_RADIUS (Sector::SIZE * 1.5f) +#define OUTER_RADIUS (Sector::SIZE * float(DRAW_RAD)) static const float FAR_THRESHOLD = 7.5f; -static const float FAR_LIMIT = 36.f; -static const float FAR_MAX = 46.f; +static const float FAR_LIMIT = 36.f; +static const float FAR_MAX = 46.f; enum DetailSelection { - DETAILBOX_NONE = 0, - DETAILBOX_INFO = 1, + DETAILBOX_NONE = 0, + DETAILBOX_INFO = 1, DETAILBOX_FACTION = 2 }; static const float ZOOM_SPEED = 15; -static const float WHEEL_SENSITIVITY = .03f; // Should be a variable in user settings. +static const float WHEEL_SENSITIVITY = .03f; // Should be a variable in user settings. -SectorView::SectorView(Game* game) : UIView(), m_galaxy(game->GetGalaxy()) +SectorView::SectorView(Game *game) : + UIView(), + m_galaxy(game->GetGalaxy()) { InitDefaults(); @@ -69,15 +71,17 @@ SectorView::SectorView(Game* game) : UIView(), m_galaxy(game->GetGalaxy()) GotoSystem(m_current); m_pos = m_posMovingTo; - m_matchTargetToSelection = true; + m_matchTargetToSelection = true; m_automaticSystemSelection = true; - m_detailBoxVisible = DETAILBOX_INFO; - m_toggledFaction = false; + m_detailBoxVisible = DETAILBOX_INFO; + m_toggledFaction = false; InitObject(); } -SectorView::SectorView(const Json &jsonObj, Game* game) : UIView(), m_galaxy(game->GetGalaxy()) +SectorView::SectorView(const Json &jsonObj, Game *game) : + UIView(), + m_galaxy(game->GetGalaxy()) { InitDefaults(); @@ -138,11 +142,11 @@ void SectorView::InitObject() m_lineVerts.reset(new Graphics::VertexArray(Graphics::ATTRIB_POSITION, 500)); m_secLineVerts.reset(new Graphics::VertexArray(Graphics::ATTRIB_POSITION, 500)); m_starVerts.reset(new Graphics::VertexArray( - Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0, 500)); + Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0, 500)); Gui::Screen::PushFont("OverlayFont"); m_clickableLabels = new Gui::LabelSet(); - m_clickableLabels->SetLabelColor(Color(178,178,178,191)); + m_clickableLabels->SetLabelColor(Color(178, 178, 178, 191)); Add(m_clickableLabels, 0, 0); Gui::Screen::PopFont(); @@ -205,8 +209,7 @@ void SectorView::SaveToJson(Json &jsonObj) jsonObj["sector_view"] = sectorViewObj; // Add sector view object to supplied object. } - -#define FFRAC(_x) ((_x)-floor(_x)) +#define FFRAC(_x) ((_x)-floor(_x)) void SectorView::Draw3D() { @@ -217,8 +220,10 @@ void SectorView::Draw3D() m_clickableLabels->Clear(); m_starVerts->Clear(); - if (m_zoomClamped <= FAR_THRESHOLD) m_renderer->SetPerspectiveProjection(40.f, m_renderer->GetDisplayAspect(), 1.f, 300.f); - else m_renderer->SetPerspectiveProjection(40.f, m_renderer->GetDisplayAspect(), 1.f, 600.f); + if (m_zoomClamped <= FAR_THRESHOLD) + m_renderer->SetPerspectiveProjection(40.f, m_renderer->GetDisplayAspect(), 1.f, 300.f); + else + m_renderer->SetPerspectiveProjection(40.f, m_renderer->GetDisplayAspect(), 1.f, 600.f); matrix4x4f modelview = matrix4x4f::Identity(); @@ -227,16 +232,15 @@ void SectorView::Draw3D() Graphics::Renderer::MatrixTicket ticket(m_renderer, Graphics::MatrixMode::MODELVIEW); // units are lightyears, my friend - modelview.Translate(0.f, 0.f, -10.f-10.f*m_zoom); // not zoomClamped, let us zoom out a bit beyond what we're drawing + modelview.Translate(0.f, 0.f, -10.f - 10.f * m_zoom); // not zoomClamped, let us zoom out a bit beyond what we're drawing modelview.Rotate(DEG2RAD(m_rotX), 1.f, 0.f, 0.f); modelview.Rotate(DEG2RAD(m_rotZ), 0.f, 0.f, 1.f); - modelview.Translate(-FFRAC(m_pos.x)*Sector::SIZE, -FFRAC(m_pos.y)*Sector::SIZE, -FFRAC(m_pos.z)*Sector::SIZE); + modelview.Translate(-FFRAC(m_pos.x) * Sector::SIZE, -FFRAC(m_pos.y) * Sector::SIZE, -FFRAC(m_pos.z) * Sector::SIZE); m_renderer->SetTransform(modelview); RefCountedPtr playerSec = GetCached(m_current); const vector3f playerPos = Sector::SIZE * vector3f(float(m_current.sectorX), float(m_current.sectorY), float(m_current.sectorZ)) + playerSec->m_systems[m_current.systemIndex].GetPosition(); - if (m_zoomClamped <= FAR_THRESHOLD) DrawNearSectors(modelview); else @@ -249,22 +253,22 @@ void SectorView::Draw3D() m_renderer->DrawTriangles(m_starVerts.get(), m_solidState, m_starMaterial.Get()); //draw sector legs in one go - if(!m_lineVerts->IsEmpty()) { + if (!m_lineVerts->IsEmpty()) { m_lines.SetData(m_lineVerts->GetNumVerts(), &m_lineVerts->position[0], &m_lineVerts->diffuse[0]); m_lines.Draw(m_renderer, m_alphaBlendState); } if (!m_secLineVerts->IsEmpty()) { - m_sectorlines.SetData( m_secLineVerts->GetNumVerts(), &m_secLineVerts->position[0], &m_secLineVerts->diffuse[0]); + m_sectorlines.SetData(m_secLineVerts->GetNumVerts(), &m_secLineVerts->position[0], &m_secLineVerts->diffuse[0]); m_sectorlines.Draw(m_renderer, m_alphaBlendState); } // not quite the same as modelview matrix4x4f trans = matrix4x4f::Identity(); - trans.Translate(0.f, 0.f, -10.f - 10.f*m_zoom); + trans.Translate(0.f, 0.f, -10.f - 10.f * m_zoom); trans.Rotate(DEG2RAD(m_rotX), 1.f, 0.f, 0.f); trans.Rotate(DEG2RAD(m_rotZ), 0.f, 0.f, 1.f); - trans.Translate(-(m_pos.x)*Sector::SIZE, -(m_pos.y)*Sector::SIZE, -(m_pos.z)*Sector::SIZE); + trans.Translate(-(m_pos.x) * Sector::SIZE, -(m_pos.y) * Sector::SIZE, -(m_pos.z) * Sector::SIZE); DrawRouteLines(playerPos, trans); @@ -308,9 +312,9 @@ void SectorView::GotoSystem(const SystemPath &path) { RefCountedPtr ps = GetCached(path); const vector3f &p = ps->m_systems[path.systemIndex].GetPosition(); - m_posMovingTo.x = path.sectorX + p.x/Sector::SIZE; - m_posMovingTo.y = path.sectorY + p.y/Sector::SIZE; - m_posMovingTo.z = path.sectorZ + p.z/Sector::SIZE; + m_posMovingTo.x = path.sectorX + p.x / Sector::SIZE; + m_posMovingTo.y = path.sectorY + p.y / Sector::SIZE; + m_posMovingTo.z = path.sectorZ + p.z / Sector::SIZE; // for performance don't animate the travel if we're Far Zoomed if (m_zoomClamped > FAR_THRESHOLD) { @@ -351,7 +355,7 @@ void SectorView::OnClickSystem(const SystemPath &path) if (i >= system->GetNumStars() - 1) SetSelected(system->GetStars()[0]->GetPath()); else - SetSelected(system->GetStars()[i+1]->GetPath()); + SetSelected(system->GetStars()[i + 1]->GetPath()); } else { SetSelected(system->GetStars()[0]->GetPath()); } @@ -368,15 +372,13 @@ void SectorView::OnClickSystem(const SystemPath &path) void SectorView::PutSystemLabels(RefCountedPtr sec, const vector3f &origin, int drawRadius) { PROFILE_SCOPED() - Uint32 sysIdx = 0; - for (std::vector::iterator sys = sec->m_systems.begin(); sys !=sec->m_systems.end(); ++sys, ++sysIdx) { + Uint32 sysIdx = 0; + for (std::vector::iterator sys = sec->m_systems.begin(); sys != sec->m_systems.end(); ++sys, ++sysIdx) { // skip the system if it doesn't fall within the sphere we're viewing. - if ((m_pos*Sector::SIZE - (*sys).GetFullPosition()).Length() > drawRadius) continue; + if ((m_pos * Sector::SIZE - (*sys).GetFullPosition()).Length() > drawRadius) continue; // if the system is the current system or target we can't skip it - bool can_skip = !sys->IsSameSystem(m_selected) - && !sys->IsSameSystem(m_hyperspaceTarget) - && !sys->IsSameSystem(m_current); + bool can_skip = !sys->IsSameSystem(m_selected) && !sys->IsSameSystem(m_hyperspaceTarget) && !sys->IsSameSystem(m_current); // skip the system if it belongs to a Faction we've toggled off and we can skip it if (m_hiddenFactions.find(sys->GetFaction()) != m_hiddenFactions.end() && can_skip) continue; @@ -391,7 +393,7 @@ void SectorView::PutSystemLabels(RefCountedPtr sec, const vector3f &orig vector3d screenPos; if (Gui::Screen::Project(systemPos, screenPos)) { // reject back-projected labels - if(screenPos.z > 1.0f) + if (screenPos.z > 1.0f) continue; // work out the colour @@ -402,7 +404,7 @@ void SectorView::PutSystemLabels(RefCountedPtr sec, const vector3f &orig // label text std::string text = ""; - if(((inRange || m_drawOutRangeLabels) && (sys->GetPopulation() > 0 || m_drawUninhabitedLabels)) || !can_skip) + if (((inRange || m_drawOutRangeLabels) && (sys->GetPopulation() > 0 || m_drawUninhabitedLabels)) || !can_skip) text = sys->GetName(); // setup the label; @@ -415,7 +417,7 @@ void SectorView::PutFactionLabels(const vector3f &origin) { PROFILE_SCOPED() - m_renderer->SetDepthRange(0,1); + m_renderer->SetDepthRange(0, 1); Gui::Screen::EnterOrtho(); if (!m_material) @@ -428,15 +430,15 @@ void SectorView::PutFactionLabels(const vector3f &origin) if ((*it)->hasHomeworld && m_hiddenFactions.find((*it)) == m_hiddenFactions.end()) { Sector::System sys = GetCached((*it)->homeworld)->m_systems[(*it)->homeworld.systemIndex]; - if ((m_pos*Sector::SIZE - sys.GetFullPosition()).Length() > (m_zoomClamped/FAR_THRESHOLD )*OUTER_RADIUS) continue; + if ((m_pos * Sector::SIZE - sys.GetFullPosition()).Length() > (m_zoomClamped / FAR_THRESHOLD) * OUTER_RADIUS) continue; vector3d pos; if (Gui::Screen::Project(vector3d(sys.GetFullPosition() - origin), pos)) { - std::string labelText = sys.GetName() + "\n" + (*it)->name; - Color labelColor = (*it)->colour; + std::string labelText = sys.GetName() + "\n" + (*it)->name; + Color labelColor = (*it)->colour; float labelHeight = 0; - float labelWidth = 0; + float labelWidth = 0; Gui::Screen::MeasureString(labelText, labelWidth, labelHeight); @@ -470,7 +472,7 @@ void SectorView::PutFactionLabels(const vector3f &origin) m_renderer->DrawTriangles(&surface, renderState, m_material.Get(), Graphics::TRIANGLE_STRIP); if (labelColor.GetLuminance() > 204) - labelColor.a = 204; // luminance is sometimes a bit overly + labelColor.a = 204; // luminance is sometimes a bit overly m_clickableLabels->Add(labelText, sigc::bind(sigc::mem_fun(this, &SectorView::OnClickSystem), (*it)->homeworld), pos.x + MARGINLEFT, pos.y - (halfheight / 2.0) - 1.f, labelColor); } } @@ -484,42 +486,43 @@ void SectorView::AddStarBillboard(const matrix4x4f &trans, const vector3f &pos, const vector3f offset = trans * pos; - const vector3f rotv1 = rot * vector3f(size/2.f, -size/2.f, 0.0f); - const vector3f rotv2 = rot * vector3f(size/2.f, size/2.f, 0.0f); + const vector3f rotv1 = rot * vector3f(size / 2.f, -size / 2.f, 0.0f); + const vector3f rotv2 = rot * vector3f(size / 2.f, size / 2.f, 0.0f); Graphics::VertexArray &va = *m_starVerts; - va.Add(offset-rotv1, col, vector2f(0.f, 0.f)); //top left - va.Add(offset-rotv2, col, vector2f(0.f, 1.f)); //bottom left - va.Add(offset+rotv2, col, vector2f(1.f, 0.f)); //top right + va.Add(offset - rotv1, col, vector2f(0.f, 0.f)); //top left + va.Add(offset - rotv2, col, vector2f(0.f, 1.f)); //bottom left + va.Add(offset + rotv2, col, vector2f(1.f, 0.f)); //top right - va.Add(offset+rotv2, col, vector2f(1.f, 0.f)); //top right - va.Add(offset-rotv2, col, vector2f(0.f, 1.f)); //bottom left - va.Add(offset+rotv1, col, vector2f(1.f, 1.f)); //bottom right + va.Add(offset + rotv2, col, vector2f(1.f, 0.f)); //top right + va.Add(offset - rotv2, col, vector2f(0.f, 1.f)); //bottom left + va.Add(offset + rotv1, col, vector2f(1.f, 1.f)); //bottom right } -void SectorView::OnToggleFaction(Gui::ToggleButton* button, bool pressed, const Faction* faction) +void SectorView::OnToggleFaction(Gui::ToggleButton *button, bool pressed, const Faction *faction) { // hide or show the faction's systems depending on whether the button is pressed - if (pressed) m_hiddenFactions.erase(faction); - else m_hiddenFactions.insert(faction); + if (pressed) + m_hiddenFactions.erase(faction); + else + m_hiddenFactions.insert(faction); m_toggledFaction = true; } -void SectorView::DrawNearSectors(const matrix4x4f& modelview) +void SectorView::DrawNearSectors(const matrix4x4f &modelview) { PROFILE_SCOPED() - m_visibleFactions.clear(); + m_visibleFactions.clear(); RefCountedPtr playerSec = GetCached(m_current); const vector3f playerPos = Sector::SIZE * vector3f(float(m_current.sectorX), float(m_current.sectorY), float(m_current.sectorZ)) + playerSec->m_systems[m_current.systemIndex].GetPosition(); - for (int sx = -DRAW_RAD; sx <= DRAW_RAD; sx++) { for (int sy = -DRAW_RAD; sy <= DRAW_RAD; sy++) { for (int sz = -DRAW_RAD; sz <= DRAW_RAD; sz++) { - DrawNearSector(int(floorf(m_pos.x))+sx, int(floorf(m_pos.y))+sy, int(floorf(m_pos.z))+sz, playerPos, - modelview * matrix4x4f::Translation(Sector::SIZE*sx, Sector::SIZE*sy, Sector::SIZE*sz)); + DrawNearSector(int(floorf(m_pos.x)) + sx, int(floorf(m_pos.y)) + sy, int(floorf(m_pos.z)) + sz, playerPos, + modelview * matrix4x4f::Translation(Sector::SIZE * sx, Sector::SIZE * sy, Sector::SIZE * sz)); } } } @@ -528,7 +531,7 @@ void SectorView::DrawNearSectors(const matrix4x4f& modelview) const vector3f secOrigin = vector3f(int(floorf(m_pos.x)), int(floorf(m_pos.y)), int(floorf(m_pos.z))); m_renderer->SetTransform(modelview); - m_renderer->SetDepthRange(0,1); + m_renderer->SetDepthRange(0, 1); Gui::Screen::EnterOrtho(); for (int sx = -DRAW_RAD; sx <= DRAW_RAD; sx++) { for (int sy = -DRAW_RAD; sy <= DRAW_RAD; sy++) { @@ -540,7 +543,8 @@ void SectorView::DrawNearSectors(const matrix4x4f& modelview) Gui::Screen::LeaveOrtho(); } -bool SectorView::MoveRouteItemUp(const std::vector::size_type element) { +bool SectorView::MoveRouteItemUp(const std::vector::size_type element) +{ if (element <= 0 || element >= m_route.size()) return false; std::swap(m_route[element - 1], m_route[element]); @@ -548,7 +552,8 @@ bool SectorView::MoveRouteItemUp(const std::vector::size_type elemen return true; } -bool SectorView::MoveRouteItemDown(const std::vector::size_type element) { +bool SectorView::MoveRouteItemDown(const std::vector::size_type element) +{ if (element < 0 || element >= m_route.size() - 1) return false; std::swap(m_route[element + 1], m_route[element]); @@ -561,7 +566,8 @@ void SectorView::AddToRoute(const SystemPath &path) m_route.push_back(path); } -bool SectorView::RemoveRouteItem(const std::vector::size_type element) { +bool SectorView::RemoveRouteItem(const std::vector::size_type element) +{ if (element >= 0 && element < m_route.size()) { m_route.erase(m_route.begin() + element); return true; @@ -596,9 +602,9 @@ void SectorView::AutoRoute(const SystemPath &start, const SystemPath &target, st std::vector nodes; nodes.push_back(start); - const Sint32 minX = std::min(start.sectorX, target.sectorX)-2, maxX = std::max(start.sectorX, target.sectorX)+2; - const Sint32 minY = std::min(start.sectorY, target.sectorY)-2, maxY = std::max(start.sectorY, target.sectorY)+2; - const Sint32 minZ = std::min(start.sectorZ, target.sectorZ)-2, maxZ = std::max(start.sectorZ, target.sectorZ)+2; + const Sint32 minX = std::min(start.sectorX, target.sectorX) - 2, maxX = std::max(start.sectorX, target.sectorX) + 2; + const Sint32 minY = std::min(start.sectorY, target.sectorY) - 2, maxY = std::max(start.sectorY, target.sectorY) + 2; + const Sint32 minZ = std::min(start.sectorZ, target.sectorZ) - 2, maxZ = std::max(start.sectorZ, target.sectorZ) + 2; const vector3f start_pos = start_sec->m_systems[start.systemIndex].GetFullPosition(); const vector3f target_pos = target_sec->m_systems[target.systemIndex].GetFullPosition(); @@ -617,8 +623,7 @@ void SectorView::AutoRoute(const SystemPath &start, const SystemPath &target, st if (Sector::DistanceBetween(start_sec, start.systemIndex, sec, sec->m_systems[s].idx) <= dist * 1.10 && Sector::DistanceBetween(target_sec, target.systemIndex, sec, sec->m_systems[s].idx) <= dist * 1.10 && - lineDist<(Sector::SIZE*3)) - { + lineDist < (Sector::SIZE * 3)) { nodes.push_back(sec->m_systems[s].GetPath()); } } @@ -665,7 +670,7 @@ void SectorView::AutoRoute(const SystemPath &start, const SystemPath &target, st for (auto it : unvisited) { const SystemPath &v = nodes[it]; // everything is a neighbor isn't quite true as the ship has a max_range for each jump! - if ((SystemPath::SectorDistance(closest, v)*Sector::SIZE) > max_range) { + if ((SystemPath::SectorDistance(closest, v) * Sector::SIZE) > max_range) { ++totalSkipped; continue; } @@ -716,16 +721,16 @@ void SectorView::DrawRouteLines(const vector3f &playerAbsPos, const matrix4x4f & { for (std::vector::size_type i = 0; i < m_route.size(); ++i) { RefCountedPtr jumpSec = m_galaxy->GetSector(m_route[i]); - const Sector::System& jumpSecSys = jumpSec->m_systems[m_route[i].systemIndex]; - const vector3f jumpAbsPos = Sector::SIZE*vector3f(float(jumpSec->sx), float(jumpSec->sy), float(jumpSec->sz)) + jumpSecSys.GetPosition(); + const Sector::System &jumpSecSys = jumpSec->m_systems[m_route[i].systemIndex]; + const vector3f jumpAbsPos = Sector::SIZE * vector3f(float(jumpSec->sx), float(jumpSec->sy), float(jumpSec->sz)) + jumpSecSys.GetPosition(); vector3f startPos; if (i == 0) { startPos = playerAbsPos; } else { - RefCountedPtr prevSec = m_galaxy->GetSector(m_route[i-1]); - const Sector::System& prevSecSys = prevSec->m_systems[m_route[i-1].systemIndex]; - const vector3f prevAbsPos = Sector::SIZE*vector3f(float(prevSec->sx), float(prevSec->sy), float(prevSec->sz)) + prevSecSys.GetPosition(); + RefCountedPtr prevSec = m_galaxy->GetSector(m_route[i - 1]); + const Sector::System &prevSecSys = prevSec->m_systems[m_route[i - 1].systemIndex]; + const vector3f prevAbsPos = Sector::SIZE * vector3f(float(prevSec->sx), float(prevSec->sy), float(prevSec->sz)) + prevSecSys.GetPosition(); startPos = prevAbsPos; } std::unique_ptr verts; @@ -736,21 +741,21 @@ void SectorView::DrawRouteLines(const vector3f &playerAbsPos, const matrix4x4f & verts->position.reserve(2); verts->diffuse.reserve(2); - verts->Add(trans* startPos, Color(20, 20, 0, 127)); - verts->Add(trans* jumpAbsPos, Color(255, 255, 0, 255)); + verts->Add(trans * startPos, Color(20, 20, 0, 127)); + verts->Add(trans * jumpAbsPos, Color(255, 255, 0, 255)); lines.SetData(verts->GetNumVerts(), &verts->position[0], &verts->diffuse[0]); lines.Draw(m_renderer, m_alphaBlendState); } } -void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const vector3f &playerAbsPos,const matrix4x4f &trans) +void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const vector3f &playerAbsPos, const matrix4x4f &trans) { PROFILE_SCOPED() - m_renderer->SetTransform(trans); + m_renderer->SetTransform(trans); RefCountedPtr ps = GetCached(SystemPath(sx, sy, sz)); - const int cz = int(floor(m_pos.z+0.5f)); + const int cz = int(floor(m_pos.z + 0.5f)); if (cz == sz) { static const Color darkgreen(0, 51, 0, 255); @@ -766,13 +771,13 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const m_secLineVerts->position.reserve(newNum); m_secLineVerts->diffuse.reserve(newNum); - m_secLineVerts->Add(vts[0], darkgreen); // line segment 1 + m_secLineVerts->Add(vts[0], darkgreen); // line segment 1 m_secLineVerts->Add(vts[1], darkgreen); - m_secLineVerts->Add(vts[1], darkgreen); // line segment 2 + m_secLineVerts->Add(vts[1], darkgreen); // line segment 2 m_secLineVerts->Add(vts[2], darkgreen); - m_secLineVerts->Add(vts[2], darkgreen); // line segment 3 + m_secLineVerts->Add(vts[2], darkgreen); // line segment 3 m_secLineVerts->Add(vts[3], darkgreen); - m_secLineVerts->Add(vts[3], darkgreen); // line segment 4 + m_secLineVerts->Add(vts[3], darkgreen); // line segment 4 m_secLineVerts->Add(vts[0], darkgreen); } @@ -783,8 +788,8 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const Uint32 sysIdx = 0; for (std::vector::iterator i = ps->m_systems.begin(); i != ps->m_systems.end(); ++i, ++sysIdx) { // calculate where the system is in relation the centre of the view... - const vector3f sysAbsPos = Sector::SIZE*vector3f(float(sx), float(sy), float(sz)) + i->GetPosition(); - const vector3f toCentreOfView = m_pos*Sector::SIZE - sysAbsPos; + const vector3f sysAbsPos = Sector::SIZE * vector3f(float(sx), float(sy), float(sz)) + i->GetPosition(); + const vector3f toCentreOfView = m_pos * Sector::SIZE - sysAbsPos; // ...and skip the system if it doesn't fall within the sphere we're viewing. if (toCentreOfView.Length() > OUTER_RADIUS) continue; @@ -792,9 +797,7 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const const bool bIsCurrentSystem = i->IsSameSystem(m_current); // if the system is the current system or target we can't skip it - bool can_skip = !i->IsSameSystem(m_selected) - && !i->IsSameSystem(m_hyperspaceTarget) - && !bIsCurrentSystem; + bool can_skip = !i->IsSameSystem(m_selected) && !i->IsSameSystem(m_hyperspaceTarget) && !bIsCurrentSystem; // if the system belongs to a faction we've chosen to temporarily hide // then skip it if we can @@ -809,21 +812,20 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const // don't worry about looking for inhabited systems if they're // unexplored (same calculation as in StarSystem.cpp) or we've // already retrieved their population. - if (i->GetPopulation() < 0 && isqrt(1 + sx*sx + sy*sy + sz*sz) <= 90) { + if (i->GetPopulation() < 0 && isqrt(1 + sx * sx + sy * sy + sz * sz) <= 90) { // only do this once we've pretty much stopped moving. vector3f diff = vector3f( - fabs(m_posMovingTo.x - m_pos.x), - fabs(m_posMovingTo.y - m_pos.y), - fabs(m_posMovingTo.z - m_pos.z)); + fabs(m_posMovingTo.x - m_pos.x), + fabs(m_posMovingTo.y - m_pos.y), + fabs(m_posMovingTo.z - m_pos.z)); // Ideally, since this takes so f'ing long, it wants to be done as a threaded job but haven't written that yet. - if( (diff.x < 0.001f && diff.y < 0.001f && diff.z < 0.001f) ) { + if ((diff.x < 0.001f && diff.y < 0.001f && diff.z < 0.001f)) { SystemPath current = SystemPath(sx, sy, sz, sysIdx); RefCountedPtr pSS = m_galaxy->GetStarSystem(current); i->SetPopulation(pSS->GetTotalPop()); } - } matrix4x4f systrans = trans * matrix4x4f::Translation(i->GetPosition().x, i->GetPosition().y, i->GetPosition().z); @@ -838,9 +840,9 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const // draw system "leg" float z = -i->GetPosition().z; if (sz <= cz) - z = z+abs(cz-sz)*Sector::SIZE; + z = z + abs(cz - sz) * Sector::SIZE; else - z = z-abs(cz-sz)*Sector::SIZE; + z = z - abs(cz - sz) * Sector::SIZE; m_lineVerts->Add(systrans * vector3f(0.f, 0.f, z), light); m_lineVerts->Add(systrans * vector3f(0.f, 0.f, z * 0.5f), dark); m_lineVerts->Add(systrans * vector3f(0.f, 0.f, z * 0.5f), dark); @@ -863,8 +865,7 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const if (m_selected != m_hyperspaceTarget) { RefCountedPtr hyperSec = GetCached(m_hyperspaceTarget); const vector3f hyperAbsPos = - Sector::SIZE*vector3f(m_hyperspaceTarget.sectorX, m_hyperspaceTarget.sectorY, m_hyperspaceTarget.sectorZ) - + hyperSec->m_systems[m_hyperspaceTarget.systemIndex].GetPosition(); + Sector::SIZE * vector3f(m_hyperspaceTarget.sectorX, m_hyperspaceTarget.sectorY, m_hyperspaceTarget.sectorZ) + hyperSec->m_systems[m_hyperspaceTarget.systemIndex].GetPosition(); if (m_selected != m_current) { m_secondLine.SetStart(vector3f(0.f, 0.f, 0.f)); m_secondLine.SetEnd(hyperAbsPos - sysAbsPos); @@ -892,26 +893,26 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const // player location indicator if (m_inSystem && bIsCurrentSystem) { - m_renderer->SetDepthRange(0.2,1.0); + m_renderer->SetDepthRange(0.2, 1.0); m_disk->SetColor(Color(0, 0, 204)); m_renderer->SetTransform(systrans * matrix4x4f::ScaleMatrix(3.f)); m_disk->Draw(m_renderer); } // selected indicator if (bIsCurrentSystem) { - m_renderer->SetDepthRange(0.1,1.0); + m_renderer->SetDepthRange(0.1, 1.0); m_disk->SetColor(Color(0, 204, 0)); m_renderer->SetTransform(systrans * matrix4x4f::ScaleMatrix(2.f)); m_disk->Draw(m_renderer); } // hyperspace target indicator (if different from selection) if (i->IsSameSystem(m_hyperspaceTarget) && m_hyperspaceTarget != m_selected && (!m_inSystem || m_hyperspaceTarget != m_current)) { - m_renderer->SetDepthRange(0.1,1.0); + m_renderer->SetDepthRange(0.1, 1.0); m_disk->SetColor(Color(77, 77, 77)); m_renderer->SetTransform(systrans * matrix4x4f::ScaleMatrix(2.f)); m_disk->Draw(m_renderer); } - if(bIsCurrentSystem && m_jumpSphere && m_playerHyperspaceRange>0.0f) { + if (bIsCurrentSystem && m_jumpSphere && m_playerHyperspaceRange > 0.0f) { const matrix4x4f sphTrans = trans * matrix4x4f::Translation(i->GetPosition().x, i->GetPosition().y, i->GetPosition().z); m_renderer->SetTransform(sphTrans * matrix4x4f::ScaleMatrix(m_playerHyperspaceRange)); m_jumpSphere->Draw(m_renderer); @@ -919,32 +920,32 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const } } -void SectorView::DrawFarSectors(const matrix4x4f& modelview) +void SectorView::DrawFarSectors(const matrix4x4f &modelview) { PROFILE_SCOPED() - int buildRadius = ceilf((m_zoomClamped/FAR_THRESHOLD) * 3); + int buildRadius = ceilf((m_zoomClamped / FAR_THRESHOLD) * 3); if (buildRadius <= DRAW_RAD) buildRadius = DRAW_RAD; const vector3f secOrigin = vector3f(int(floorf(m_pos.x)), int(floorf(m_pos.y)), int(floorf(m_pos.z))); // build vertex and colour arrays for all the stars we want to see, if we don't already have them if (m_toggledFaction || buildRadius != m_radiusFar || !secOrigin.ExactlyEqual(m_secPosFar)) { - m_farstars .clear(); - m_farstarsColor .clear(); + m_farstars.clear(); + m_farstarsColor.clear(); m_visibleFactions.clear(); - for (int sx = secOrigin.x-buildRadius; sx <= secOrigin.x+buildRadius; sx++) { - for (int sy = secOrigin.y-buildRadius; sy <= secOrigin.y+buildRadius; sy++) { - for (int sz = secOrigin.z-buildRadius; sz <= secOrigin.z+buildRadius; sz++) { - if ((vector3f(sx,sy,sz) - secOrigin).Length() <= buildRadius){ + for (int sx = secOrigin.x - buildRadius; sx <= secOrigin.x + buildRadius; sx++) { + for (int sy = secOrigin.y - buildRadius; sy <= secOrigin.y + buildRadius; sy++) { + for (int sz = secOrigin.z - buildRadius; sz <= secOrigin.z + buildRadius; sz++) { + if ((vector3f(sx, sy, sz) - secOrigin).Length() <= buildRadius) { BuildFarSector(GetCached(SystemPath(sx, sy, sz)), Sector::SIZE * secOrigin, m_farstars, m_farstarsColor); } } } } - m_secPosFar = secOrigin; - m_radiusFar = buildRadius; + m_secPosFar = secOrigin; + m_radiusFar = buildRadius; m_toggledFaction = false; } @@ -961,22 +962,20 @@ void SectorView::DrawFarSectors(const matrix4x4f& modelview) void SectorView::BuildFarSector(RefCountedPtr sec, const vector3f &origin, std::vector &points, std::vector &colors) { PROFILE_SCOPED() - Color starColor; + Color starColor; for (std::vector::iterator i = sec->m_systems.begin(); i != sec->m_systems.end(); ++i) { // skip the system if it doesn't fall within the sphere we're viewing. - if ((m_pos*Sector::SIZE - (*i).GetFullPosition()).Length() > (m_zoomClamped/FAR_THRESHOLD )*OUTER_RADIUS) continue; + if ((m_pos * Sector::SIZE - (*i).GetFullPosition()).Length() > (m_zoomClamped / FAR_THRESHOLD) * OUTER_RADIUS) continue; - if (!i->IsExplored()) - { + if (!i->IsExplored()) { points.push_back((*i).GetFullPosition() - origin); - colors.push_back({ 100,100,100,155 }); // flat gray for unexplored systems + colors.push_back({ 100, 100, 100, 155 }); // flat gray for unexplored systems continue; } // if the system belongs to a faction we've chosen to hide also skip it, if it's not selectd in some way m_visibleFactions.insert(i->GetFaction()); - if (m_hiddenFactions.find(i->GetFaction()) != m_hiddenFactions.end() - && !i->IsSameSystem(m_selected) && !i->IsSameSystem(m_hyperspaceTarget) && !i->IsSameSystem(m_current)) continue; + if (m_hiddenFactions.find(i->GetFaction()) != m_hiddenFactions.end() && !i->IsSameSystem(m_selected) && !i->IsSameSystem(m_hyperspaceTarget) && !i->IsSameSystem(m_current)) continue; // otherwise add the system's position (origin must be m_pos's *sector* or we get judder) // and faction color to the list to draw @@ -1043,8 +1042,10 @@ void SectorView::OnKeyPressed(SDL_Keysym *keysym) // reset rotation and zoom if (reset_view || KeyBindings::mapViewReset.Matches(keysym)) { - while (m_rotZ < -180.0f) m_rotZ += 360.0f; - while (m_rotZ > 180.0f) m_rotZ -= 360.0f; + while (m_rotZ < -180.0f) + m_rotZ += 360.0f; + while (m_rotZ > 180.0f) + m_rotZ -= 360.0f; m_rotXMovingTo = m_rotXDefault; m_rotZMovingTo = m_rotZDefault; m_zoomMovingTo = m_zoomDefault; @@ -1059,8 +1060,7 @@ void SectorView::Update() if (Pi::game->IsNormalSpace()) { m_inSystem = true; m_current = Pi::game->GetSpace()->GetStarSystem()->GetPath(); - } - else { + } else { m_inSystem = false; m_current = Pi::player->GetHyperspaceDest(); } @@ -1075,7 +1075,7 @@ void SectorView::Update() // XXX ugly hack checking for Lua console here if (!Pi::IsConsoleActive()) { const float moveSpeed = Pi::GetMoveSpeedShiftModifier(); - float move = moveSpeed*frameTime; + float move = moveSpeed * frameTime; vector3f shift(0.0f); if (KeyBindings::mapViewShiftLeft.IsActive()) shift.x -= move; if (KeyBindings::mapViewShiftRight.IsActive()) shift.x += move; @@ -1101,34 +1101,41 @@ void SectorView::Update() int motion[2]; Pi::input.GetMouseMotion(motion); - m_rotXMovingTo += 0.2f*float(motion[1]); - m_rotZMovingTo += 0.2f*float(motion[0]); + m_rotXMovingTo += 0.2f * float(motion[1]); + m_rotZMovingTo += 0.2f * float(motion[0]); } m_rotXMovingTo = Clamp(m_rotXMovingTo, -170.0f, -10.0f); { vector3f diffPos = m_posMovingTo - m_pos; - vector3f travelPos = diffPos * 10.0f*frameTime; - if (travelPos.Length() > diffPos.Length()) m_pos = m_posMovingTo; - else m_pos = m_pos + travelPos; + vector3f travelPos = diffPos * 10.0f * frameTime; + if (travelPos.Length() > diffPos.Length()) + m_pos = m_posMovingTo; + else + m_pos = m_pos + travelPos; float diffX = m_rotXMovingTo - m_rotX; - float travelX = diffX * 10.0f*frameTime; - if (fabs(travelX) > fabs(diffX)) m_rotX = m_rotXMovingTo; - else m_rotX = m_rotX + travelX; + float travelX = diffX * 10.0f * frameTime; + if (fabs(travelX) > fabs(diffX)) + m_rotX = m_rotXMovingTo; + else + m_rotX = m_rotX + travelX; float diffZ = m_rotZMovingTo - m_rotZ; - float travelZ = diffZ * 10.0f*frameTime; - if (fabs(travelZ) > fabs(diffZ)) m_rotZ = m_rotZMovingTo; - else m_rotZ = m_rotZ + travelZ; + float travelZ = diffZ * 10.0f * frameTime; + if (fabs(travelZ) > fabs(diffZ)) + m_rotZ = m_rotZMovingTo; + else + m_rotZ = m_rotZ + travelZ; float diffZoom = m_zoomMovingTo - m_zoom; - float travelZoom = diffZoom * ZOOM_SPEED*frameTime; - if (fabs(travelZoom) > fabs(diffZoom)) m_zoom = m_zoomMovingTo; - else m_zoom = m_zoom + travelZoom; + float travelZoom = diffZoom * ZOOM_SPEED * frameTime; + if (fabs(travelZoom) > fabs(diffZoom)) + m_zoom = m_zoomMovingTo; + else + m_zoom = m_zoom + travelZoom; m_zoomClamped = Clamp(m_zoom, 1.f, FAR_LIMIT); - } if (m_automaticSystemSelection) { @@ -1136,17 +1143,17 @@ void SectorView::Update() RefCountedPtr ps = GetCached(new_selected); if (ps->m_systems.size()) { - float px = FFRAC(m_pos.x)*Sector::SIZE; - float py = FFRAC(m_pos.y)*Sector::SIZE; - float pz = FFRAC(m_pos.z)*Sector::SIZE; + float px = FFRAC(m_pos.x) * Sector::SIZE; + float py = FFRAC(m_pos.y) * Sector::SIZE; + float pz = FFRAC(m_pos.z) * Sector::SIZE; float min_dist = FLT_MAX; - for (unsigned int i=0; im_systems.size(); i++) { + for (unsigned int i = 0; i < ps->m_systems.size(); i++) { Sector::System *ss = &ps->m_systems[i]; float dx = px - ss->GetPosition().x; float dy = py - ss->GetPosition().y; float dz = pz - ss->GetPosition().z; - float dist = sqrtf(dx*dx + dy*dy + dz*dz); + float dist = sqrtf(dx * dx + dy * dy + dz * dz); if (dist < min_dist) { min_dist = dist; new_selected.systemIndex = i; @@ -1164,21 +1171,20 @@ void SectorView::Update() m_playerHyperspaceRange = LuaObject::CallMethod(Pi::player, "GetHyperspaceRange"); - if(!m_jumpSphere) - { - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthTest = false; - rsd.depthWrite = false; - rsd.cullMode = Graphics::CULL_NONE; - m_jumpSphereState = m_renderer->CreateRenderState(rsd); + if (!m_jumpSphere) { + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthTest = false; + rsd.depthWrite = false; + rsd.cullMode = Graphics::CULL_NONE; + m_jumpSphereState = m_renderer->CreateRenderState(rsd); - Graphics::MaterialDescriptor matdesc; - matdesc.effect = EFFECT_FRESNEL_SPHERE; - m_fresnelMat.Reset(m_renderer->CreateMaterial(matdesc)); - m_fresnelMat->diffuse = Color::WHITE; - m_jumpSphere.reset( new Graphics::Drawables::Sphere3D(m_renderer, m_fresnelMat, m_jumpSphereState, 4, 1.0f) ); - } + Graphics::MaterialDescriptor matdesc; + matdesc.effect = EFFECT_FRESNEL_SPHERE; + m_fresnelMat.Reset(m_renderer->CreateMaterial(matdesc)); + m_fresnelMat->diffuse = Color::WHITE; + m_jumpSphere.reset(new Graphics::Drawables::Sphere3D(m_renderer, m_fresnelMat, m_jumpSphereState, 4, 1.0f)); + } UIView::Update(); } @@ -1201,27 +1207,25 @@ void SectorView::MouseWheel(bool up) void SectorView::ShrinkCache() { PROFILE_SCOPED() - // we're going to use these to determine if our sectors are within the range that we'll ever render - const int drawRadius = (m_zoomClamped <= FAR_THRESHOLD) ? DRAW_RAD : ceilf((m_zoomClamped/FAR_THRESHOLD) * DRAW_RAD); + // we're going to use these to determine if our sectors are within the range that we'll ever render + const int drawRadius = (m_zoomClamped <= FAR_THRESHOLD) ? DRAW_RAD : ceilf((m_zoomClamped / FAR_THRESHOLD) * DRAW_RAD); - const int xmin = int(floorf(m_pos.x))-drawRadius; - const int xmax = int(floorf(m_pos.x))+drawRadius; - const int ymin = int(floorf(m_pos.y))-drawRadius; - const int ymax = int(floorf(m_pos.y))+drawRadius; - const int zmin = int(floorf(m_pos.z))-drawRadius; - const int zmax = int(floorf(m_pos.z))+drawRadius; + const int xmin = int(floorf(m_pos.x)) - drawRadius; + const int xmax = int(floorf(m_pos.x)) + drawRadius; + const int ymin = int(floorf(m_pos.y)) - drawRadius; + const int ymax = int(floorf(m_pos.y)) + drawRadius; + const int zmin = int(floorf(m_pos.z)) - drawRadius; + const int zmax = int(floorf(m_pos.z)) + drawRadius; // XXX don't clear the current/selected/target sectors - if (xmin != m_cacheXMin || xmax != m_cacheXMax - || ymin != m_cacheYMin || ymax != m_cacheYMax - || zmin != m_cacheZMin || zmax != m_cacheZMax) { + if (xmin != m_cacheXMin || xmax != m_cacheXMax || ymin != m_cacheYMin || ymax != m_cacheYMax || zmin != m_cacheZMin || zmax != m_cacheZMax) { auto iter = m_sectorCache->Begin(); - while (iter != m_sectorCache->End()) { + while (iter != m_sectorCache->End()) { RefCountedPtr s = iter->second; //check_point_in_box - if (!s->WithinBox( xmin, xmax, ymin, ymax, zmin, zmax )) { - m_sectorCache->Erase( iter++ ); + if (!s->WithinBox(xmin, xmax, ymin, ymax, zmin, zmax)) { + m_sectorCache->Erase(iter++); } else { iter++; } @@ -1236,41 +1240,47 @@ void SectorView::ShrinkCache() } } -double SectorView::GetZoomLevel() const { - return ((m_zoomClamped/FAR_THRESHOLD )*(OUTER_RADIUS)) + 0.5 * Sector::SIZE; +double SectorView::GetZoomLevel() const +{ + return ((m_zoomClamped / FAR_THRESHOLD) * (OUTER_RADIUS)) + 0.5 * Sector::SIZE; } -void SectorView::ZoomIn() { +void SectorView::ZoomIn() +{ const float frameTime = Pi::GetFrameTime(); const float moveSpeed = Pi::GetMoveSpeedShiftModifier(); - float move = moveSpeed*frameTime; + float move = moveSpeed * frameTime; m_zoomMovingTo -= move; m_zoomMovingTo = Clamp(m_zoomMovingTo, 0.1f, FAR_MAX); } -void SectorView::ZoomOut() { +void SectorView::ZoomOut() +{ const float frameTime = Pi::GetFrameTime(); const float moveSpeed = Pi::GetMoveSpeedShiftModifier(); - float move = moveSpeed*frameTime; + float move = moveSpeed * frameTime; m_zoomMovingTo += move; m_zoomMovingTo = Clamp(m_zoomMovingTo, 0.1f, FAR_MAX); } -vector3f SectorView::GetCenterSector() { +vector3f SectorView::GetCenterSector() +{ return m_pos; } -double SectorView::GetCenterDistance() { +double SectorView::GetCenterDistance() +{ if (m_inSystem) { - vector3f dv = vector3f(floorf(m_pos.x)-m_current.sectorX, floorf(m_pos.y)-m_current.sectorY, floorf(m_pos.z)-m_current.sectorZ) * Sector::SIZE; + vector3f dv = vector3f(floorf(m_pos.x) - m_current.sectorX, floorf(m_pos.y) - m_current.sectorY, floorf(m_pos.z) - m_current.sectorZ) * Sector::SIZE; return dv.Length(); } else { return 0.0; } } -void SectorView::LockHyperspaceTarget(bool lock) { - if(lock) { +void SectorView::LockHyperspaceTarget(bool lock) +{ + if (lock) { SetHyperspaceTarget(GetSelected()); } else { FloatHyperspaceTarget(); @@ -1279,28 +1289,28 @@ void SectorView::LockHyperspaceTarget(bool lock) { std::vector SectorView::GetNearbyStarSystemsByName(std::string pattern) { std::vector result; - for(auto i = m_sectorCache->Begin(); i != m_sectorCache->End(); ++i) { - for (unsigned int systemIndex = 0; systemIndex < (*i).second->m_systems.size(); systemIndex++) - { - const Sector::System *ss = &((*i).second->m_systems[systemIndex]); + for (auto i = m_sectorCache->Begin(); i != m_sectorCache->End(); ++i) { + for (unsigned int systemIndex = 0; systemIndex < (*i).second->m_systems.size(); systemIndex++) { + const Sector::System *ss = &((*i).second->m_systems[systemIndex]); - // compare with the start of the current system - if (strncasecmp(pattern.c_str(), ss->GetName().c_str(), pattern.size()) == 0 - // look for the pattern term somewhere within the current system - || pi_strcasestr(ss->GetName().c_str(), pattern.c_str())) - { - SystemPath match((*i).first); - match.systemIndex = systemIndex; - result.push_back(match); - } + // compare with the start of the current system + if (strncasecmp(pattern.c_str(), ss->GetName().c_str(), pattern.size()) == 0 + // look for the pattern term somewhere within the current system + || pi_strcasestr(ss->GetName().c_str(), pattern.c_str())) { + SystemPath match((*i).first); + match.systemIndex = systemIndex; + result.push_back(match); } + } } return result; } void SectorView::SetFactionVisible(const Faction *faction, bool visible) { - if (visible) m_hiddenFactions.erase(faction); - else m_hiddenFactions.insert(faction); + if (visible) + m_hiddenFactions.erase(faction); + else + m_hiddenFactions.insert(faction); m_toggledFaction = true; } diff --git a/src/SectorView.h b/src/SectorView.h index 467c302b5..42f27b881 100644 --- a/src/SectorView.h +++ b/src/SectorView.h @@ -4,26 +4,25 @@ #ifndef _SECTORVIEW_H #define _SECTORVIEW_H -#include "libs.h" -#include "gui/Gui.h" #include "UIView.h" -#include -#include -#include #include "View.h" #include "galaxy/Sector.h" #include "galaxy/SystemPath.h" #include "graphics/Drawables.h" #include "graphics/RenderState.h" +#include "gui/Gui.h" +#include "libs.h" #include +#include +#include class Game; class Galaxy; -class SectorView: public UIView { +class SectorView : public UIView { public: - SectorView(Game* game); - SectorView(const Json &jsonObj, Game* game); + SectorView(Game *game); + SectorView(const Json &jsonObj, Game *game); virtual ~SectorView(); virtual void Update(); @@ -72,7 +71,6 @@ public: void AutoRoute(const SystemPath &start, const SystemPath &target, std::vector &outRoute) const; void SetDrawRouteLines(bool value) { m_drawRouteLines = value; } - protected: virtual void OnSwitchTo(); @@ -96,18 +94,18 @@ private: Gui::Label *shortDesc; }; - void DrawNearSectors(const matrix4x4f& modelview); + void DrawNearSectors(const matrix4x4f &modelview); void DrawNearSector(const int sx, const int sy, const int sz, const vector3f &playerAbsPos, const matrix4x4f &trans); void PutSystemLabels(RefCountedPtr sec, const vector3f &origin, int drawRadius); - void DrawFarSectors(const matrix4x4f& modelview); + void DrawFarSectors(const matrix4x4f &modelview); void BuildFarSector(RefCountedPtr sec, const vector3f &origin, std::vector &points, std::vector &colors); void PutFactionLabels(const vector3f &secPos); void AddStarBillboard(const matrix4x4f &modelview, const vector3f &pos, const Color &col, float size); void OnClickSystem(const SystemPath &path); - RefCountedPtr GetCached(const SystemPath& loc) { return m_sectorCache->GetCached(loc); } + RefCountedPtr GetCached(const SystemPath &loc) { return m_sectorCache->GetCached(loc); } void ShrinkCache(); void MouseWheel(bool up); @@ -144,12 +142,12 @@ private: Gui::LabelSet *m_clickableLabels; - std::set m_visibleFactions; - std::set m_hiddenFactions; + std::set m_visibleFactions; + std::set m_hiddenFactions; Uint8 m_detailBoxVisible; - void OnToggleFaction(Gui::ToggleButton* button, bool pressed, const Faction* faction); + void OnToggleFaction(Gui::ToggleButton *button, bool pressed, const Faction *faction); sigc::connection m_onMouseWheelCon; sigc::connection m_onKeyPressConnection; @@ -174,11 +172,11 @@ private: RefCountedPtr m_starMaterial; std::vector m_farstars; - std::vector m_farstarsColor; + std::vector m_farstarsColor; vector3f m_secPosFar; - int m_radiusFar; - bool m_toggledFaction; + int m_radiusFar; + bool m_toggledFaction; int m_cacheXMin; int m_cacheXMax; diff --git a/src/Sensors.cpp b/src/Sensors.cpp index 98cd14c24..792ab5ca4 100644 --- a/src/Sensors.cpp +++ b/src/Sensors.cpp @@ -4,43 +4,45 @@ #include "Sensors.h" #include "Body.h" #include "Game.h" +#include "HudTrail.h" #include "Pi.h" +#include "Player.h" #include "Ship.h" #include "Space.h" -#include "Player.h" -#include "HudTrail.h" -Sensors::RadarContact::RadarContact() -: body(0) -, trail(0) -, distance(0.0) -, iff(IFF_UNKNOWN) -, fresh(true) { +Sensors::RadarContact::RadarContact() : + body(0), + trail(0), + distance(0.0), + iff(IFF_UNKNOWN), + fresh(true) +{ } -Sensors::RadarContact::RadarContact(Body *b) -: body(b) -, trail(0) -, distance(0.0) -, iff(IFF_UNKNOWN) -, fresh(true) { +Sensors::RadarContact::RadarContact(Body *b) : + body(b), + trail(0), + distance(0.0), + iff(IFF_UNKNOWN), + fresh(true) +{ } -Sensors::RadarContact::~RadarContact() { +Sensors::RadarContact::~RadarContact() +{ body = 0; delete trail; } Color Sensors::IFFColor(IFF iff) { - switch (iff) - { - case IFF_NEUTRAL: return Color::BLUE; - case IFF_ALLY: return Color::GREEN; - case IFF_HOSTILE: return Color::RED; - case IFF_UNKNOWN: - default: - return Color::GRAY; + switch (iff) { + case IFF_NEUTRAL: return Color::BLUE; + case IFF_ALLY: return Color::GREEN; + case IFF_HOSTILE: return Color::RED; + case IFF_UNKNOWN: + default: + return Color::GRAY; } } @@ -68,7 +70,7 @@ bool Sensors::ChooseTarget(TargetingCriteria crit) //if (it->iff != IFF_HOSTILE) continue; //should move the target to ship after all (from PlayerShipController) //targeting inputs stay in PSC - static_cast(m_owner)->SetCombatTarget(it->body); + static_cast(m_owner)->SetCombatTarget(it->body); found = true; break; } @@ -77,14 +79,16 @@ bool Sensors::ChooseTarget(TargetingCriteria crit) return found; } -Sensors::IFF Sensors::CheckIFF(Body* other) +Sensors::IFF Sensors::CheckIFF(Body *other) { PROFILE_SCOPED(); //complicated relationship check goes here if (other->IsType(Object::SHIP)) { Uint8 rel = m_owner->GetRelations(other); - if (rel == 0) return IFF_HOSTILE; - else if (rel == 100) return IFF_ALLY; + if (rel == 0) + return IFF_HOSTILE; + else if (rel == 100) + return IFF_ALLY; return IFF_NEUTRAL; } else { return IFF_UNKNOWN; @@ -130,8 +134,8 @@ void Sensors::Update(float time) if (!it->fresh) { m_radarContacts.erase(it++); } else { - const Ship* ship =dynamic_cast(it->body); - if (ship && Ship::FLYING==ship->GetFlightState()) { + const Ship *ship = dynamic_cast(it->body); + if (ship && Ship::FLYING == ship->GetFlightState()) { it->distance = m_owner->GetPositionRelTo(it->body).Length(); it->trail->Update(time); } else { @@ -146,8 +150,7 @@ void Sensors::Update(float time) void Sensors::UpdateIFF(Body *b) { PROFILE_SCOPED(); - for (auto it = m_radarContacts.begin(); it != m_radarContacts.end(); ++it) - { + for (auto it = m_radarContacts.begin(); it != m_radarContacts.end(); ++it) { if (it->body == b) { it->iff = CheckIFF(b); it->trail->SetColor(IFFColor(it->iff)); @@ -167,16 +170,15 @@ void Sensors::PopulateStaticContacts() PROFILE_SCOPED(); m_staticContacts.clear(); - for (Body* b : Pi::game->GetSpace()->GetBodies()) { - switch (b->GetType()) - { - case Object::STAR: - case Object::PLANET: - case Object::CITYONPLANET: - case Object::SPACESTATION: - break; - default: - continue; + for (Body *b : Pi::game->GetSpace()->GetBodies()) { + switch (b->GetType()) { + case Object::STAR: + case Object::PLANET: + case Object::CITYONPLANET: + case Object::SPACESTATION: + break; + default: + continue; } m_staticContacts.push_back(RadarContact(b)); RadarContact &rc = m_staticContacts.back(); diff --git a/src/Sensors.h b/src/Sensors.h index 36c9acf05..e4e519d3f 100644 --- a/src/Sensors.h +++ b/src/Sensors.h @@ -11,8 +11,8 @@ * - don't run radar sweep every frame (more of an optimization than simulation) * - allow "pinned" radar contacts (visible at all ranges, for missions) */ -#include "libs.h" #include "Body.h" +#include "libs.h" class Body; class HudTrail; @@ -36,7 +36,7 @@ public: RadarContact(Body *); ~RadarContact(); Body *body; - HudTrail* trail; + HudTrail *trail; double distance; IFF iff; bool fresh; @@ -53,7 +53,7 @@ public: const ContactList &GetContacts() { return m_radarContacts; } const ContactList &GetStaticContacts() { return m_staticContacts; } void Update(float time); - void UpdateIFF(Body*); + void UpdateIFF(Body *); void ResetTrails(); private: diff --git a/src/Serializer.cpp b/src/Serializer.cpp index b4b1f3316..c7bc3a0d4 100644 --- a/src/Serializer.cpp +++ b/src/Serializer.cpp @@ -6,270 +6,278 @@ namespace Serializer { -const std::string &Writer::GetData() { return m_str; } -void Writer::Byte(Uint8 x) { - m_str.push_back(char(x)); -} -void Writer::Bool(bool x) { - Byte(Uint8(x)); -} -void Writer::Int16(Uint16 x) { - m_str.push_back(char(x&0xff)); - m_str.push_back(char((x>>8)&0xff)); -} -void Writer::Int32(Uint32 x) { - m_str.push_back(char(x&0xff)); - m_str.push_back(char((x>>8)&0xff)); - m_str.push_back(char((x>>16)&0xff)); - m_str.push_back(char((x>>24)&0xff)); -} -void Writer::Int64(Uint64 x) { - m_str.push_back(char(x&0xff)); - m_str.push_back(char((x>>8)&0xff)); - m_str.push_back(char((x>>16)&0xff)); - m_str.push_back(char((x>>24)&0xff)); - m_str.push_back(char((x>>32)&0xff)); - m_str.push_back(char((x>>40)&0xff)); - m_str.push_back(char((x>>48)&0xff)); - m_str.push_back(char((x>>56)&0xff)); -} -void Writer::Float(float f) { - // not portable across architectures? - unsigned int i; - union { - unsigned char c[sizeof (float)]; - float f; - } p; - p.f = f; - - for (i=0; i> 8) & 0xff)); } + void Writer::Int32(Uint32 x) + { + m_str.push_back(char(x & 0xff)); + m_str.push_back(char((x >> 8) & 0xff)); + m_str.push_back(char((x >> 16) & 0xff)); + m_str.push_back(char((x >> 24) & 0xff)); + } + void Writer::Int64(Uint64 x) + { + m_str.push_back(char(x & 0xff)); + m_str.push_back(char((x >> 8) & 0xff)); + m_str.push_back(char((x >> 16) & 0xff)); + m_str.push_back(char((x >> 24) & 0xff)); + m_str.push_back(char((x >> 32) & 0xff)); + m_str.push_back(char((x >> 40) & 0xff)); + m_str.push_back(char((x >> 48) & 0xff)); + m_str.push_back(char((x >> 56) & 0xff)); + } + void Writer::Float(float f) + { + // not portable across architectures? + unsigned int i; + union { + unsigned char c[sizeof(float)]; + float f; + } p; + p.f = f; - Int32(strlen(s)+1); + for (i = 0; i < sizeof(float); i++) { + Byte(p.c[i]); + } + } + void Writer::Double(double f) + { + // not portable across architectures + unsigned int i; + union { + unsigned char c[sizeof(double)]; + double f; + } p; + p.f = f; - while (*s) { + for (i = 0; i < sizeof(double); i++) { + Byte(p.c[i]); + } + } + /* First byte is string length, including null terminator */ + void Writer::String(const char *s) + { + /* We shouldn't fail on null strings */ + if (!s) { + Int32(0); + return; + } + + Int32(strlen(s) + 1); + + while (*s) { + Byte(*s); + s++; + } Byte(*s); - s++; } - Byte(*s); -} -void Writer::String(const std::string &s) -{ - Int32(s.size()+1); + void Writer::String(const std::string &s) + { + Int32(s.size() + 1); - for(size_t i=0; i= 0 && size_t(pos) <= m_data.Size()); - m_at = m_data.begin + pos; -} + bool Reader::AtEnd() { return (m_at == m_data.end); } + void Reader::Seek(int pos) + { + assert(pos >= 0 && size_t(pos) <= m_data.Size()); + m_at = m_data.begin + pos; + } -Uint8 Reader::Byte() -{ + Uint8 Reader::Byte() + { #ifdef DEBUG - assert(!AtEnd()); + assert(!AtEnd()); #endif /* DEBUG */ - return Uint8(*m_at++); -} - -bool Reader::Bool() -{ - return Byte() != 0; -} - -Uint16 Reader::Int16() -{ - int t1, t2; - t2 = Byte(); - t1 = Byte(); - return ((t1 << 8) | t2); -} -Uint32 Reader::Int32(void) -{ - int t1, t2, t3, t4; - t4 = Byte(); - t3 = Byte(); - t2 = Byte(); - t1 = Byte(); - return ((t1 << 24) | (t2 << 16) | (t3 << 8) | t4); -} -Uint64 Reader::Int64(void) -{ - Uint64 t1, t2, t3, t4, t5, t6, t7, t8; - t8 = Byte(); - t7 = Byte(); - t6 = Byte(); - t5 = Byte(); - t4 = Byte(); - t3 = Byte(); - t2 = Byte(); - t1 = Byte(); - return ((t1<<56) | (t2<<48) | (t3<<40) | (t4<<32) | (t5 << 24) | (t6 << 16) | (t7 << 8) | t8); -} - -float Reader::Float () -{ - unsigned int i; - union { - unsigned char c[sizeof (float)]; - float f; - } p; - - for (i=0; i (m_data.end - m_at)) { - // XXX error condition -- exception? some kind of error state on the Reader? - assert(0 && "Serializer:Reader stream is truncated"); - size = (m_data.end - m_at); + return Uint8(*m_at++); } - assert(size > 0); - assert(size <= (m_data.end - m_at)); - ByteRange range = ByteRange(m_at, m_at + (size - 1)); // -1 to exclude the null terminator - m_at += size; - assert(m_at <= m_data.end); - return range; -} - -std::string Reader::String() -{ - ByteRange range = Blob(); - return std::string(range.begin, range.Size()); -} - -vector3f Reader::Vector3f() -{ - vector3f v; - v.x = Float(); - v.y = Float(); - v.z = Float(); - return v; -} - -vector3d Reader::Vector3d() -{ - vector3d v; - v.x = Double(); - v.y = Double(); - v.z = Double(); - return v; -} - -Quaternionf Reader::RdQuaternionf() -{ - Quaternionf q; - q.w = Float(); - q.x = Float(); - q.y = Float(); - q.z = Float(); - return q; -} - -Color Reader::Color4UB() -{ - Color c; - c.r = Byte(); - c.g = Byte(); - c.b = Byte(); - c.a = Byte(); - return c; -} - -Reader Reader::RdSection(const std::string §ion_label_expected) { - if (section_label_expected != String()) { - throw SavedGameCorruptException(); + bool Reader::Bool() + { + return Byte() != 0; + } + + Uint16 Reader::Int16() + { + int t1, t2; + t2 = Byte(); + t1 = Byte(); + return ((t1 << 8) | t2); + } + Uint32 Reader::Int32(void) + { + int t1, t2, t3, t4; + t4 = Byte(); + t3 = Byte(); + t2 = Byte(); + t1 = Byte(); + return ((t1 << 24) | (t2 << 16) | (t3 << 8) | t4); + } + Uint64 Reader::Int64(void) + { + Uint64 t1, t2, t3, t4, t5, t6, t7, t8; + t8 = Byte(); + t7 = Byte(); + t6 = Byte(); + t5 = Byte(); + t4 = Byte(); + t3 = Byte(); + t2 = Byte(); + t1 = Byte(); + return ((t1 << 56) | (t2 << 48) | (t3 << 40) | (t4 << 32) | (t5 << 24) | (t6 << 16) | (t7 << 8) | t8); + } + + float Reader::Float() + { + unsigned int i; + union { + unsigned char c[sizeof(float)]; + float f; + } p; + + for (i = 0; i < sizeof(float); i++) { + p.c[i] = Byte(); + } + return p.f; + } + + double Reader::Double() + { + unsigned int i; + union { + unsigned char c[sizeof(double)]; + double f; + } p; + + for (i = 0; i < sizeof(double); i++) { + p.c[i] = Byte(); + } + return p.f; + } + + ByteRange Reader::Blob() + { + int size = Int32(); + if (size == 0) return ByteRange(); + + if (size > (m_data.end - m_at)) { + // XXX error condition -- exception? some kind of error state on the Reader? + assert(0 && "Serializer:Reader stream is truncated"); + size = (m_data.end - m_at); + } + + assert(size > 0); + assert(size <= (m_data.end - m_at)); + ByteRange range = ByteRange(m_at, m_at + (size - 1)); // -1 to exclude the null terminator + m_at += size; + assert(m_at <= m_data.end); + return range; + } + + std::string Reader::String() + { + ByteRange range = Blob(); + return std::string(range.begin, range.Size()); + } + + vector3f Reader::Vector3f() + { + vector3f v; + v.x = Float(); + v.y = Float(); + v.z = Float(); + return v; + } + + vector3d Reader::Vector3d() + { + vector3d v; + v.x = Double(); + v.y = Double(); + v.z = Double(); + return v; + } + + Quaternionf Reader::RdQuaternionf() + { + Quaternionf q; + q.w = Float(); + q.x = Float(); + q.y = Float(); + q.z = Float(); + return q; + } + + Color Reader::Color4UB() + { + Color c; + c.r = Byte(); + c.g = Byte(); + c.b = Byte(); + c.a = Byte(); + return c; + } + + Reader Reader::RdSection(const std::string §ion_label_expected) + { + if (section_label_expected != String()) { + throw SavedGameCorruptException(); + } + Reader section = Reader(Blob()); + section.SetStreamVersion(StreamVersion()); + return section; } - Reader section = Reader(Blob()); - section.SetStreamVersion(StreamVersion()); - return section; -} } /* end namespace Serializer */ diff --git a/src/Serializer.h b/src/Serializer.h index 19a564f67..49d0a0d86 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -4,11 +4,11 @@ #ifndef _SERIALIZE_H #define _SERIALIZE_H -#include #include "ByteRange.h" #include "Color.h" #include "Quaternion.h" #include "vector3.h" +#include namespace Serializer { @@ -23,13 +23,14 @@ namespace Serializer { void Int64(Uint64 x); void Float(float f); void Double(double f); - void String(const char* s); + void String(const char *s); void String(const std::string &s); void Vector3f(vector3f vec); void Vector3d(vector3d vec); void WrQuaternionf(const Quaternionf &q); - void Color4UB(const Color&); - void WrSection(const std::string §ion_label, const std::string §ion_data) { + void Color4UB(const Color &); + void WrSection(const std::string §ion_label, const std::string §ion_data) + { String(section_label); String(section_data); } @@ -38,13 +39,16 @@ namespace Serializer { void Auto(Sint64 x) { Int64(x); } void Auto(float x) { Float(x); } void Auto(double x) { Double(x); } + private: std::string m_str; }; class Reader { public: - Reader(): m_at(nullptr), m_streamVersion(-1) {} + Reader() : + m_at(nullptr), + m_streamVersion(-1) {} explicit Reader(const ByteRange &data); bool AtEnd(); @@ -54,8 +58,8 @@ namespace Serializer { Uint16 Int16(); Uint32 Int32(); Uint64 Int64(); - float Float (); - double Double (); + float Float(); + double Double(); std::string String(); ByteRange Blob(); vector3f Vector3f(); @@ -77,7 +81,6 @@ namespace Serializer { int m_streamVersion; }; - -} +} // namespace Serializer #endif /* _SERIALIZE_H */ diff --git a/src/ServerAgent.cpp b/src/ServerAgent.cpp index 72e7c51d0..59784bbad 100644 --- a/src/ServerAgent.cpp +++ b/src/ServerAgent.cpp @@ -29,7 +29,6 @@ void NullServerAgent::ProcessResponses() } } - bool HTTPServerAgent::s_initialised = false; HTTPServerAgent::HTTPServerAgent(const std::string &endpoint) : @@ -121,7 +120,7 @@ void HTTPServerAgent::ProcessResponses() int HTTPServerAgent::ThreadEntry(void *data) { - reinterpret_cast(data)->ThreadMain(); + reinterpret_cast(data)->ThreadMain(); return 0; } @@ -159,7 +158,7 @@ void HTTPServerAgent::ThreadMain() Response resp(req.onSuccess, req.onFail, req.userdata); - curl_easy_setopt(m_curl, CURLOPT_URL, std::string(m_endpoint+"/"+req.method).c_str()); + curl_easy_setopt(m_curl, CURLOPT_URL, std::string(m_endpoint + "/" + req.method).c_str()); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE, req.buffer.size()); curl_easy_setopt(m_curl, CURLOPT_READDATA, &req); curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &resp); @@ -193,8 +192,8 @@ void HTTPServerAgent::ThreadMain() size_t HTTPServerAgent::FillRequestBuffer(char *ptr, size_t size, size_t nmemb, void *userdata) { - HTTPServerAgent::Request *req = reinterpret_cast(userdata); - size_t amount = std::max(size*nmemb, req->buffer.size()); + HTTPServerAgent::Request *req = reinterpret_cast(userdata); + size_t amount = std::max(size * nmemb, req->buffer.size()); memcpy(ptr, req->buffer.data(), amount); req->buffer.erase(0, amount); return amount; @@ -202,9 +201,9 @@ size_t HTTPServerAgent::FillRequestBuffer(char *ptr, size_t size, size_t nmemb, size_t HTTPServerAgent::FillResponseBuffer(char *ptr, size_t size, size_t nmemb, void *userdata) { - HTTPServerAgent::Response *resp = reinterpret_cast(userdata); - resp->buffer.append(ptr, size*nmemb); - return size*nmemb; + HTTPServerAgent::Response *resp = reinterpret_cast(userdata); + resp->buffer.append(ptr, size * nmemb); + return size * nmemb; } const std::string &HTTPServerAgent::UserAgent() diff --git a/src/ServerAgent.h b/src/ServerAgent.h index c8377ac2c..4b9c58c33 100644 --- a/src/ServerAgent.h +++ b/src/ServerAgent.h @@ -6,17 +6,17 @@ #define SERVERAGENT_H #include "libs.h" +#include +#include #include #include -#include -#include class ServerAgent { public: virtual ~ServerAgent() {} - typedef sigc::slot SuccessCallback; - typedef sigc::slot FailCallback; + typedef sigc::slot SuccessCallback; + typedef sigc::slot FailCallback; virtual void Call(const std::string &method, const Json &data, SuccessCallback onSuccess, FailCallback onFail, void *userdata) = 0; @@ -27,7 +27,6 @@ protected: static void IgnoreFailCallback(const std::string &error) {} }; - class NullServerAgent : public ServerAgent { public: virtual void Call(const std::string &method, const Json &data, ServerAgent::SuccessCallback onSuccess = sigc::ptr_fun(&ServerAgent::IgnoreSuccessCallback), ServerAgent::FailCallback onFail = sigc::ptr_fun(&ServerAgent::IgnoreFailCallback), void *userdata = 0); @@ -35,11 +34,11 @@ public: virtual void ProcessResponses(); private: - struct Response { Response(FailCallback _onFail, void *_userdata) : - onFail(_onFail), userdata(_userdata) - {} + onFail(_onFail), + userdata(_userdata) + {} FailCallback onFail; void *userdata; @@ -48,7 +47,6 @@ private: std::queue m_queue; }; - class HTTPServerAgent : public ServerAgent { public: HTTPServerAgent(const std::string &endpoint); @@ -59,10 +57,13 @@ public: virtual void ProcessResponses(); private: - struct Request { Request(const std::string &_method, const Json &_data, SuccessCallback _onSuccess, FailCallback _onFail, void *_userdata) : - method(_method), data(_data), onSuccess(_onSuccess), onFail(_onFail), userdata(_userdata) {} + method(_method), + data(_data), + onSuccess(_onSuccess), + onFail(_onFail), + userdata(_userdata) {} const std::string method; const Json data; @@ -77,7 +78,10 @@ private: struct Response { Response(SuccessCallback _onSuccess, FailCallback _onFail, void *_userdata) : - success(false), onSuccess(_onSuccess), onFail(_onFail), userdata(_userdata) {} + success(false), + onSuccess(_onSuccess), + onFail(_onFail), + userdata(_userdata) {} bool success; diff --git a/src/Sfx.cpp b/src/Sfx.cpp index 94166fbf5..dcbeb0f76 100644 --- a/src/Sfx.cpp +++ b/src/Sfx.cpp @@ -2,22 +2,22 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Sfx.h" -#include "Frame.h" -#include "galaxy/StarSystem.h" -#include "libs.h" -#include "Pi.h" -#include "IniConfig.h" #include "FileSystem.h" +#include "Frame.h" +#include "GameSaveError.h" +#include "IniConfig.h" +#include "JsonUtils.h" +#include "Pi.h" #include "Ship.h" #include "Space.h" #include "StringF.h" +#include "galaxy/StarSystem.h" #include "graphics/Drawables.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" -#include "JsonUtils.h" -#include "GameSaveError.h" +#include "libs.h" using namespace Graphics; @@ -29,7 +29,7 @@ namespace { const float pixrad = Clamp(Graphics::GetScreenHeight() / trans.Length(), 0.1f, 50.0f); return (size * Graphics::GetFovFactor()) * pixrad; } -}; +}; // namespace std::unique_ptr SfxManager::damageParticle; std::unique_ptr SfxManager::ecmParticle; @@ -40,17 +40,27 @@ Graphics::RenderState *SfxManager::additiveAlphaState = nullptr; Graphics::RenderState *SfxManager::alphaOneState = nullptr; SfxManager::MaterialData SfxManager::m_materialData[TYPE_NONE]; -Sfx::Sfx() : m_speed(200.0f), m_type(TYPE_NONE) +Sfx::Sfx() : + m_speed(200.0f), + m_type(TYPE_NONE) { } Sfx::Sfx(const vector3d &pos, const vector3d &vel, const float speed, const SFX_TYPE type) : - m_pos(pos), m_vel(vel), m_age(0.0f), m_speed(speed), m_type(type) + m_pos(pos), + m_vel(vel), + m_age(0.0f), + m_speed(speed), + m_type(type) { } Sfx::Sfx(const Sfx &b) : - m_pos(b.m_pos), m_vel(b.m_vel), m_age(b.m_age), m_speed(b.m_speed), m_type(b.m_type) + m_pos(b.m_pos), + m_vel(b.m_vel), + m_age(b.m_age), + m_speed(b.m_speed), + m_type(b.m_type) { } @@ -92,28 +102,33 @@ void Sfx::TimeStepUpdate(const float timeStep) m_pos += m_vel * double(timeStep); switch (m_type) { - case TYPE_EXPLOSION: if (m_age > 3.2) m_type = TYPE_NONE; break; - case TYPE_DAMAGE: if (m_age > 2.0) m_type = TYPE_NONE; break; - case TYPE_SMOKE: if (m_age > 8.0) m_type = TYPE_NONE; break; - case TYPE_NONE: break; + case TYPE_EXPLOSION: + if (m_age > 3.2) m_type = TYPE_NONE; + break; + case TYPE_DAMAGE: + if (m_age > 2.0) m_type = TYPE_NONE; + break; + case TYPE_SMOKE: + if (m_age > 8.0) m_type = TYPE_NONE; + break; + case TYPE_NONE: break; } } float Sfx::AgeBlend() const { switch (m_type) { - case TYPE_EXPLOSION: return (3.2 - m_age) / 3.2; - case TYPE_DAMAGE: return (2.0 - m_age) / 2.0; - case TYPE_SMOKE: return (8.0 - m_age) / 8.0; - case TYPE_NONE: return 0.0f; + case TYPE_EXPLOSION: return (3.2 - m_age) / 3.2; + case TYPE_DAMAGE: return (2.0 - m_age) / 2.0; + case TYPE_SMOKE: return (8.0 - m_age) / 8.0; + case TYPE_NONE: return 0.0f; } return 0.0f; } SfxManager::SfxManager() { - for(size_t t=0; tm_sfx) - { - for(size_t t=TYPE_EXPLOSION; tm_sfx->GetNumberInstances(SFX_TYPE(t)); i++) - { + if (f->m_sfx) { + for (size_t t = TYPE_EXPLOSION; t < TYPE_NONE; t++) { + for (size_t i = 0; i < f->m_sfx->GetNumberInstances(SFX_TYPE(t)); i++) { Sfx &inst(f->m_sfx->GetInstanceByIndex(SFX_TYPE(t), i)); - if (inst.m_type != TYPE_NONE) - { + if (inst.m_type != TYPE_NONE) { Json sfxArrayEl({}); // Create JSON object to contain sfx element. inst.SaveToJson(sfxArrayEl); sfxArray.push_back(sfxArrayEl); // Append sfx object to array. @@ -147,9 +158,9 @@ void SfxManager::FromJson(const Json &jsonObj, Frame *f) Json sfxArray = jsonObj["sfx_array"].get(); if (sfxArray.size()) f->m_sfx.reset(new SfxManager); - for (unsigned int i = 0; i < sfxArray.size(); ++i) - { - Sfx inst; inst.LoadFromJson(sfxArray[i]); + for (unsigned int i = 0; i < sfxArray.size(); ++i) { + Sfx inst; + inst.LoadFromJson(sfxArray[i]); f->m_sfx->AddInstance(inst); } } @@ -165,10 +176,10 @@ SfxManager *SfxManager::AllocSfxInFrame(Frame *f) void SfxManager::Add(const Body *b, SFX_TYPE t) { - assert(t!=TYPE_NONE); + assert(t != TYPE_NONE); SfxManager *sfxman = AllocSfxInFrame(b->GetFrame()); if (!sfxman) return; - vector3d vel(b->GetVelocity() + 200.0*vector3d(Pi::rng.Double()-0.5,Pi::rng.Double()-0.5,Pi::rng.Double()-0.5)); + vector3d vel(b->GetVelocity() + 200.0 * vector3d(Pi::rng.Double() - 0.5, Pi::rng.Double() - 0.5, Pi::rng.Double() - 0.5)); Sfx sfx(b->GetPosition(), vel, 200, t); sfxman->AddInstance(sfx); } @@ -180,8 +191,8 @@ void SfxManager::AddExplosion(Body *b) float speed = 200.0f; if (b->IsType(Object::SHIP)) { - Ship *s = static_cast(b); - speed = s->GetAabb().radius*8.0; + Ship *s = static_cast(b); + speed = s->GetAabb().radius * 8.0; } Sfx sfx(b->GetPosition(), b->GetVelocity(), speed, TYPE_EXPLOSION); sfxman->AddInstance(sfx); @@ -192,7 +203,7 @@ void SfxManager::AddThrustSmoke(const Body *b, const float speed, const vector3d SfxManager *sfxman = AllocSfxInFrame(b->GetFrame()); if (!sfxman) return; - Sfx sfx(b->GetPosition()+adjustpos, vector3d(0,0,0), speed, TYPE_SMOKE); + Sfx sfx(b->GetPosition() + adjustpos, vector3d(0, 0, 0), speed, TYPE_SMOKE); sfxman->AddInstance(sfx); } @@ -200,10 +211,8 @@ void SfxManager::TimeStepAll(const float timeStep, Frame *f) { PROFILE_SCOPED() if (f->m_sfx) { - for(size_t t=TYPE_EXPLOSION; tm_sfx->GetNumberInstances(SFX_TYPE(t)); i++) - { + for (size_t t = TYPE_EXPLOSION; t < TYPE_NONE; t++) { + for (size_t i = 0; i < f->m_sfx->GetNumberInstances(SFX_TYPE(t)); i++) { Sfx &inst(f->m_sfx->GetInstanceByIndex(SFX_TYPE(t), i)); inst.TimeStepUpdate(timeStep); } @@ -211,25 +220,22 @@ void SfxManager::TimeStepAll(const float timeStep, Frame *f) f->m_sfx->Cleanup(); } - for (Frame* kid : f->GetChildren()) { + for (Frame *kid : f->GetChildren()) { TimeStepAll(timeStep, kid); } } void SfxManager::Cleanup() { - for(size_t t=TYPE_EXPLOSION; t=0; i--) - { + for (Sint64 i = Sint64(numInstances - 1); i >= 0; i--) { Sfx &inst(GetInstanceByIndex(SFX_TYPE(t), i)); - if (inst.m_type == TYPE_NONE) - { - m_instances[t].erase(m_instances[t].begin()+i); + if (inst.m_type == TYPE_NONE) { + m_instances[t].erase(m_instances[t].begin() + i); } } } @@ -242,19 +248,20 @@ void SfxManager::RenderAll(Renderer *renderer, Frame *f, const Frame *camFrame) matrix4x4d ftran; Frame::GetFrameTransform(f, camFrame, ftran); - for(size_t t=TYPE_EXPLOSION; tm_sfx->GetNumberInstances(SFX_TYPE(t)); - if(!numInstances) + if (!numInstances) continue; Graphics::RenderState *rs = nullptr; Graphics::Material *material = nullptr; - std::vector positions; positions.reserve(numInstances); - std::vector offsets; offsets.reserve(numInstances); - std::vector sizes; sizes.reserve(numInstances); - for (size_t i = 0; i < numInstances; i++) - { + std::vector positions; + positions.reserve(numInstances); + std::vector offsets; + offsets.reserve(numInstances); + std::vector sizes; + sizes.reserve(numInstances); + for (size_t i = 0; i < numInstances; i++) { Sfx &inst(f->m_sfx->GetInstanceByIndex(SFX_TYPE(t), i)); assert(inst.m_type == t); @@ -264,25 +271,24 @@ void SfxManager::RenderAll(Renderer *renderer, Frame *f, const Frame *camFrame) float speed = 0.0f; const vector2f offset(CalculateOffset(SFX_TYPE(t), inst)); - switch (t) - { - case TYPE_NONE: assert(false); break; - case TYPE_EXPLOSION: { - speed = SizeToPixels(pos, inst.m_speed); - rs = SfxManager::alphaState; - material = explosionParticle.get(); - break; - } - case TYPE_DAMAGE: - speed = SizeToPixels(pos, 20.f); - rs = SfxManager::additiveAlphaState; - material = damageParticle.get(); - break; - case TYPE_SMOKE: - speed = Clamp(SizeToPixels(pos, (inst.m_speed*inst.m_age)), 0.1f, 50.0f); - rs = SfxManager::alphaState; - material = smokeParticle.get(); - break; + switch (t) { + case TYPE_NONE: assert(false); break; + case TYPE_EXPLOSION: { + speed = SizeToPixels(pos, inst.m_speed); + rs = SfxManager::alphaState; + material = explosionParticle.get(); + break; + } + case TYPE_DAMAGE: + speed = SizeToPixels(pos, 20.f); + rs = SfxManager::additiveAlphaState; + material = damageParticle.get(); + break; + case TYPE_SMOKE: + speed = Clamp(SizeToPixels(pos, (inst.m_speed * inst.m_age)), 0.1f, 50.0f); + rs = SfxManager::alphaState; + material = smokeParticle.get(); + break; } sizes.push_back(speed); offsets.push_back(offset); @@ -292,18 +298,18 @@ void SfxManager::RenderAll(Renderer *renderer, Frame *f, const Frame *camFrame) } } - for (Frame* kid : f->GetChildren()) { + for (Frame *kid : f->GetChildren()) { RenderAll(renderer, kid, camFrame); } } vector2f SfxManager::CalculateOffset(const enum SFX_TYPE type, const Sfx &inst) { - if(m_materialData[type].effect == Graphics::EFFECT_BILLBOARD_ATLAS) { - const int spriteframe = inst.AgeBlend() * (m_materialData[type].num_textures-1); + if (m_materialData[type].effect == Graphics::EFFECT_BILLBOARD_ATLAS) { + const int spriteframe = inst.AgeBlend() * (m_materialData[type].num_textures - 1); const Sint32 numImgsWide = m_materialData[type].num_imgs_wide; - const int u = (spriteframe % numImgsWide); // % is the "modulo operator", the remainder of i / width; - const int v = (spriteframe / numImgsWide); // where "/" is an integer division + const int u = (spriteframe % numImgsWide); // % is the "modulo operator", the remainder of i / width; + const int v = (spriteframe / numImgsWide); // where "/" is an integer division return vector2f( float(u) / float(numImgsWide), float(v) / float(numImgsWide)); @@ -316,7 +322,7 @@ bool SfxManager::SplitMaterialData(const std::string &spec, MaterialData &output static const std::string delim(","); enum dataEntries { - eEFFECT=0, + eEFFECT = 0, eNUM_IMGS_WIDE, eNUM_TEXTURES, eCOORD_DOWNSCALE @@ -335,8 +341,7 @@ bool SfxManager::SplitMaterialData(const std::string &spec, MaterialData &output end = spec.find_first_of(delim, start); // extract the fragment and remember it - switch(i) - { + switch (i) { case eEFFECT: output.effect = (spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start) == "billboard") ? Graphics::EFFECT_BILLBOARD : Graphics::EFFECT_BILLBOARD_ATLAS; break; @@ -355,7 +360,7 @@ bool SfxManager::SplitMaterialData(const std::string &spec, MaterialData &output } output.coord_downscale = 1.0f / float(output.num_imgs_wide); - return i==eCOORD_DOWNSCALE; + return i == eCOORD_DOWNSCALE; } void SfxManager::Init(Graphics::Renderer *r) @@ -390,7 +395,7 @@ void SfxManager::Init(Graphics::Renderer *r) // ECM effect is different, not managed by Sfx at all, should it be factored out? desc.effect = Graphics::EFFECT_BILLBOARD; - ecmParticle.reset( r->CreateMaterial(desc) ); + ecmParticle.reset(r->CreateMaterial(desc)); ecmParticle->texture0 = Graphics::TextureBuilder::Billboard("textures/ecm.png").GetOrCreateTexture(r, "billboard"); // load material definition data @@ -399,21 +404,21 @@ void SfxManager::Init(Graphics::Renderer *r) SplitMaterialData(cfg.String("smokePacking"), m_materialData[TYPE_SMOKE]); desc.effect = m_materialData[TYPE_DAMAGE].effect; - damageParticle.reset( r->CreateMaterial(desc) ); + damageParticle.reset(r->CreateMaterial(desc)); damageParticle->texture0 = Graphics::TextureBuilder::Billboard(cfg.String("damageFile")).GetOrCreateTexture(r, "billboard"); - if(desc.effect==Graphics::EFFECT_BILLBOARD_ATLAS) + if (desc.effect == Graphics::EFFECT_BILLBOARD_ATLAS) damageParticle->specialParameter0 = &m_materialData[TYPE_DAMAGE].coord_downscale; desc.effect = m_materialData[TYPE_SMOKE].effect; - smokeParticle.reset( r->CreateMaterial(desc) ); + smokeParticle.reset(r->CreateMaterial(desc)); smokeParticle->texture0 = Graphics::TextureBuilder::Billboard(cfg.String("smokeFile")).GetOrCreateTexture(r, "billboard"); - if(desc.effect==Graphics::EFFECT_BILLBOARD_ATLAS) + if (desc.effect == Graphics::EFFECT_BILLBOARD_ATLAS) smokeParticle->specialParameter0 = &m_materialData[TYPE_SMOKE].coord_downscale; desc.effect = m_materialData[TYPE_EXPLOSION].effect; - explosionParticle.reset( r->CreateMaterial(desc) ); + explosionParticle.reset(r->CreateMaterial(desc)); explosionParticle->texture0 = Graphics::TextureBuilder::Billboard(cfg.String("explosionFile")).GetOrCreateTexture(r, "billboard"); - if(desc.effect==Graphics::EFFECT_BILLBOARD_ATLAS) + if (desc.effect == Graphics::EFFECT_BILLBOARD_ATLAS) explosionParticle->specialParameter0 = &m_materialData[TYPE_EXPLOSION].coord_downscale; } diff --git a/src/Sfx.h b/src/Sfx.h index a9b48c6d0..19f748239 100644 --- a/src/Sfx.h +++ b/src/Sfx.h @@ -13,17 +13,19 @@ namespace Graphics { class Renderer; } -enum SFX_TYPE { TYPE_EXPLOSION=1, TYPE_DAMAGE, TYPE_SMOKE, TYPE_NONE }; +enum SFX_TYPE { TYPE_EXPLOSION = 1, + TYPE_DAMAGE, + TYPE_SMOKE, + TYPE_NONE }; class Sfx { public: - friend class SfxManager; Sfx(); Sfx(const vector3d &pos, const vector3d &vel, const float speed, const SFX_TYPE type); - Sfx(const Sfx&); + Sfx(const Sfx &); void SetPosition(const vector3d &p); - const vector3d& GetPosition() const { return m_pos; } + const vector3d &GetPosition() const { return m_pos; } float AgeBlend() const; @@ -39,7 +41,6 @@ private: enum SFX_TYPE m_type; }; - class SfxManager { public: friend class Sfx; @@ -66,14 +67,18 @@ public: SfxManager(); size_t GetNumberInstances(const SFX_TYPE t) const { return m_instances[t].size(); } - Sfx& GetInstanceByIndex(const SFX_TYPE t, const size_t i) { return m_instances[t][i]; } + Sfx &GetInstanceByIndex(const SFX_TYPE t, const size_t i) { return m_instances[t][i]; } void AddInstance(Sfx &inst) { return m_instances[inst.m_type].push_back(inst); } void Cleanup(); private: // types struct MaterialData { - MaterialData() : effect(Graphics::EFFECT_BILLBOARD), num_textures(1), num_imgs_wide(1), coord_downscale(1.0f) {} + MaterialData() : + effect(Graphics::EFFECT_BILLBOARD), + num_textures(1), + num_imgs_wide(1), + coord_downscale(1.0f) {} Graphics::EffectType effect; Uint32 num_textures; int num_imgs_wide; @@ -82,7 +87,7 @@ private: // methods static SfxManager *AllocSfxInFrame(Frame *f); - static vector2f CalculateOffset(const enum SFX_TYPE, const Sfx&); + static vector2f CalculateOffset(const enum SFX_TYPE, const Sfx &); static bool SplitMaterialData(const std::string &spec, MaterialData &output); // static members diff --git a/src/Shields.cpp b/src/Shields.cpp index 6d369559f..2f377d170 100644 --- a/src/Shields.cpp +++ b/src/Shields.cpp @@ -2,14 +2,14 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Shields.h" +#include "GameSaveError.h" +#include "JsonUtils.h" +#include "Pi.h" +#include "Ship.h" #include "graphics/TextureBuilder.h" +#include "scenegraph/CollisionGeometry.h" #include "scenegraph/FindNodeVisitor.h" #include "scenegraph/SceneGraph.h" -#include "scenegraph/CollisionGeometry.h" -#include "Ship.h" -#include "Pi.h" -#include "JsonUtils.h" -#include "GameSaveError.h" #include namespace { @@ -22,19 +22,20 @@ namespace { { return s_matShield; } -} +} // namespace //used to find the accumulated transform of a MatrixTransform class MatrixAccumVisitor : public SceneGraph::NodeVisitor { public: - MatrixAccumVisitor(const std::string &name_) - : outMat(matrix4x4f::Identity()) - , m_accumMat(matrix4x4f::Identity()) - , m_name(name_) + MatrixAccumVisitor(const std::string &name_) : + outMat(matrix4x4f::Identity()), + m_accumMat(matrix4x4f::Identity()), + m_name(name_) { } - virtual void ApplyMatrixTransform(SceneGraph::MatrixTransform &mt) override { + virtual void ApplyMatrixTransform(SceneGraph::MatrixTransform &mt) override + { if (mt.GetName() == m_name) { outMat = m_accumMat * mt.GetTransform(); } else { @@ -57,13 +58,17 @@ typedef std::vector::iterator ShieldIterator; //static bool Shields::s_initialised = false; -Shields::Shield::Shield(const Color3ub &_colour, const matrix4x4f &matrix, SceneGraph::StaticGeometry *_sg) - : m_colour(_colour), m_matrix(matrix), m_mesh(_sg) -{ } +Shields::Shield::Shield(const Color3ub &_colour, const matrix4x4f &matrix, SceneGraph::StaticGeometry *_sg) : + m_colour(_colour), + m_matrix(matrix), + m_mesh(_sg) +{} -Shields::Hits::Hits(const vector3d& _pos, const Uint32 _start, const Uint32 _end) - : pos(_pos), start(_start), end(_end) -{ } +Shields::Hits::Hits(const vector3d &_pos, const Uint32 _start, const Uint32 _end) : + pos(_pos), + start(_start), + end(_end) +{} void Shields::Init(Graphics::Renderer *renderer) { @@ -81,41 +86,39 @@ void Shields::Init(Graphics::Renderer *renderer) s_initialised = true; } -void Shields::ReparentShieldNodes(SceneGraph::Model* model) +void Shields::ReparentShieldNodes(SceneGraph::Model *model) { assert(s_initialised); Graphics::Renderer *renderer = model->GetRenderer(); - using SceneGraph::Node; using SceneGraph::Group; using SceneGraph::MatrixTransform; + using SceneGraph::Node; using SceneGraph::StaticGeometry; //This will find all matrix transforms meant for navlights. SceneGraph::FindNodeVisitor shieldFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_ENDSWITH, "_shield"); model->GetRoot()->Accept(shieldFinder); - const std::vector &results = shieldFinder.GetResults(); + const std::vector &results = shieldFinder.GetResults(); //Move shield geometry to same level as the LODs for (unsigned int i = 0; i < results.size(); i++) { - MatrixTransform *mt = dynamic_cast(results.at(i)); + MatrixTransform *mt = dynamic_cast(results.at(i)); assert(mt); const Uint32 NumChildren = mt->GetNumChildren(); - if (NumChildren>0) - { + if (NumChildren > 0) { // Group to contain all of the shields we might find Group *shieldGroup = new Group(renderer); shieldGroup->SetName(s_shieldGroupName); // go through all of this MatrixTransforms children to extract all of the shield meshes for (Uint32 iChild = 0; iChild < NumChildren; ++iChild) { - Node* node = mt->GetChildAt(iChild); + Node *node = mt->GetChildAt(iChild); assert(node); - if (node) - { - RefCountedPtr sg(dynamic_cast(node)); + if (node) { + RefCountedPtr sg(dynamic_cast(node)); assert(sg.Valid()); sg->SetNodeMask(SceneGraph::NODE_TRANSPARENT); @@ -168,32 +171,30 @@ void Shields::Uninit() s_initialised = false; } -Shields::Shields(SceneGraph::Model *model) - : m_enabled(false) +Shields::Shields(SceneGraph::Model *model) : + m_enabled(false) { assert(s_initialised); - using SceneGraph::Node; - using SceneGraph::MatrixTransform; - using SceneGraph::StaticGeometry; using SceneGraph::CollisionGeometry; + using SceneGraph::MatrixTransform; + using SceneGraph::Node; + using SceneGraph::StaticGeometry; //This will find all matrix transforms meant for shields. SceneGraph::FindNodeVisitor shieldFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_ENDSWITH, s_matrixTransformName); model->GetRoot()->Accept(shieldFinder); - const std::vector &results = shieldFinder.GetResults(); + const std::vector &results = shieldFinder.GetResults(); //Store pointer to the shields for later. - for (unsigned int i=0; i < results.size(); i++) { - MatrixTransform *mt = dynamic_cast(results.at(i)); + for (unsigned int i = 0; i < results.size(); i++) { + MatrixTransform *mt = dynamic_cast(results.at(i)); assert(mt); - - for(Uint32 iChild=0 ; iChildGetNumChildren() ; ++iChild) { - Node* node = mt->GetChildAt(iChild); - if (node) - { - RefCountedPtr sg(dynamic_cast(node)); + for (Uint32 iChild = 0; iChild < mt->GetNumChildren(); ++iChild) { + Node *node = mt->GetChildAt(iChild); + if (node) { + RefCountedPtr sg(dynamic_cast(node)); assert(sg.Valid()); sg->SetNodeMask(SceneGraph::NODE_TRANSPARENT); @@ -226,8 +227,7 @@ void Shields::SaveToJson(Json &jsonObj) shieldsObj["num_shields"] = m_shields.size(); Json shieldArray = Json::array(); // Create JSON array to contain shield data. - for (ShieldIterator it = m_shields.begin(); it != m_shields.end(); ++it) - { + for (ShieldIterator it = m_shields.begin(); it != m_shields.end(); ++it) { Json shieldArrayEl({}); // Create JSON object to contain shield. shieldArrayEl["color"] = it->m_colour; shieldArrayEl["mesh_name"] = it->m_mesh->GetName(); @@ -248,13 +248,10 @@ void Shields::LoadFromJson(const Json &jsonObj) Json shieldArray = shieldsObj["shield_array"].get(); - for (unsigned int i = 0; i < shieldArray.size(); ++i) - { + for (unsigned int i = 0; i < shieldArray.size(); ++i) { Json shieldArrayEl = shieldArray[i]; - for (ShieldIterator it = m_shields.begin(); it != m_shields.end(); ++it) - { - if (shieldArrayEl["mesh_name"] == it->m_mesh->GetName()) - { + for (ShieldIterator it = m_shields.begin(); it != m_shields.end(); ++it) { + if (shieldArrayEl["mesh_name"] == it->m_mesh->GetName()) { it->m_colour = shieldArrayEl["color"]; break; } @@ -271,9 +268,9 @@ void Shields::Update(const float coolDown, const float shieldStrength) const Uint32 tickTime = SDL_GetTicks(); { HitIterator it = m_hits.begin(); - while(it != m_hits.end()) { - if (tickTime > it->end ) { - it = m_hits.erase( it ); + while (it != m_hits.end()) { + if (tickTime > it->end) { + it = m_hits.erase(it); } else { ++it; } @@ -288,20 +285,20 @@ void Shields::Update(const float coolDown, const float shieldStrength) } // setup the render params - if (shieldStrength>0.0f) { + if (shieldStrength > 0.0f) { s_renderParams.strength = shieldStrength; s_renderParams.coolDown = coolDown; Uint32 numHits = m_hits.size(); - for (Uint32 i = 0; i0.0f) { + if (shieldStrength > 0.0f) { it->m_mesh->SetNodeMask(SceneGraph::NODE_TRANSPARENT); GetGlobalShieldMaterial()->specialParameter0 = &s_renderParams; @@ -327,16 +324,16 @@ void Shields::SetColor(const Color3ub &inCol) } } -void Shields::AddHit(const vector3d& hitPos) +void Shields::AddHit(const vector3d &hitPos) { Uint32 tickTime = SDL_GetTicks(); - m_hits.push_back( Hits(hitPos, tickTime, tickTime+1000) ); + m_hits.push_back(Hits(hitPos, tickTime, tickTime + 1000)); } -SceneGraph::StaticGeometry* Shields::GetFirstShieldMesh() +SceneGraph::StaticGeometry *Shields::GetFirstShieldMesh() { for (ShieldIterator it = m_shields.begin(); it != m_shields.end(); ++it) { - if( it->m_mesh ) { + if (it->m_mesh) { return it->m_mesh.Get(); } } diff --git a/src/Shields.h b/src/Shields.h index c52cebc85..e10510175 100644 --- a/src/Shields.h +++ b/src/Shields.h @@ -6,12 +6,17 @@ /* * Mesh shields for ships and other objects. */ -#include "libs.h" #include "JsonFwd.h" +#include "libs.h" #include -namespace Graphics { class Renderer; } -namespace SceneGraph { class Model; class StaticGeometry; } +namespace Graphics { + class Renderer; +} +namespace SceneGraph { + class Model; + class StaticGeometry; +} // namespace SceneGraph struct ShieldRenderParameters { static const Uint32 MAX_SHIELD_HITS = 5; // Also defined in ShieldMaterial.h @@ -22,37 +27,34 @@ struct ShieldRenderParameters { Sint32 numHits; }; -class Shields -{ +class Shields { public: - struct Shield - { + struct Shield { Shield(const Color3ub &color, const matrix4x4f &matrix, SceneGraph::StaticGeometry *sg); Color3ub m_colour; // I'm English, so it's "colour" ;) matrix4x4f m_matrix; RefCountedPtr m_mesh; }; - Shields(SceneGraph::Model*); + Shields(SceneGraph::Model *); virtual ~Shields(); virtual void SaveToJson(Json &jsonObj); virtual void LoadFromJson(const Json &jsonObj); void SetEnabled(const bool on) { m_enabled = on; } void Update(const float coolDown, const float shieldStrength); - void SetColor(const Color3ub&); - void AddHit(const vector3d& hitPos); + void SetColor(const Color3ub &); + void AddHit(const vector3d &hitPos); - static void Init(Graphics::Renderer*); - static void ReparentShieldNodes(SceneGraph::Model*); + static void Init(Graphics::Renderer *); + static void ReparentShieldNodes(SceneGraph::Model *); static void Uninit(); - SceneGraph::StaticGeometry* GetFirstShieldMesh(); + SceneGraph::StaticGeometry *GetFirstShieldMesh(); protected: - struct Hits - { - Hits(const vector3d& _pos, const Uint32 _start, const Uint32 _end); + struct Hits { + Hits(const vector3d &_pos, const Uint32 _start, const Uint32 _end); vector3d pos; Uint32 start; Uint32 end; diff --git a/src/Ship-AI.cpp b/src/Ship-AI.cpp index 7a3c6ee48..09bc43653 100644 --- a/src/Ship-AI.cpp +++ b/src/Ship-AI.cpp @@ -1,20 +1,20 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Ship.h" -#include "Propulsion.h" -#include "ShipAICmd.h" -#include "Pi.h" -#include "Player.h" -#include "perlin.h" +#include "EnumStrings.h" #include "Frame.h" -#include "Planet.h" -#include "SpaceStation.h" -#include "Space.h" #include "LuaConstants.h" #include "LuaEvent.h" -#include "EnumStrings.h" +#include "Pi.h" +#include "Planet.h" +#include "Player.h" +#include "Propulsion.h" +#include "Ship.h" +#include "ShipAICmd.h" +#include "Space.h" +#include "SpaceStation.h" +#include "libs.h" +#include "perlin.h" // returns true if command is complete bool Ship::AITimeStep(float timeStep) @@ -28,33 +28,35 @@ bool Ship::AITimeStep(float timeStep) // just in case the AI left it on ClearThrusterState(); - for (int i=0; iTimeStepUpdate()) { AIClearInstructions(); -// ClearThrusterState(); // otherwise it does one timestep at 10k and gravity is fatal + // ClearThrusterState(); // otherwise it does one timestep at 10k and gravity is fatal LuaEvent::Queue("onAICompleted", this, EnumStrings::GetString("ShipAIError", AIMessage())); return true; - } - else return false; + } else + return false; } void Ship::AIClearInstructions() { if (!m_curAICmd) return; - delete m_curAICmd; // rely on destructor to kill children + delete m_curAICmd; // rely on destructor to kill children m_curAICmd = 0; - m_decelerating = false; // don't adjust unless AI is running + m_decelerating = false; // don't adjust unless AI is running } void Ship::AIGetStatusText(char *str) { - if (!m_curAICmd) strcpy(str, "AI inactive"); - else m_curAICmd->GetStatusText(str); + if (!m_curAICmd) + strcpy(str, "AI inactive"); + else + m_curAICmd->GetStatusText(str); } void Ship::AIKamikaze(Body *target) @@ -84,11 +86,11 @@ void Ship::AIFlyTo(Body *target) AIClearInstructions(); SetFuelReserve((GetFuel() < 0.5) ? GetFuel() / 2 : 0.25); - if (target->IsType(Object::SHIP)) { // test code + if (target->IsType(Object::SHIP)) { // test code vector3d posoff(-1000.0, 0.0, 1000.0); - m_curAICmd = new AICmdFormation(this, static_cast(target), posoff); - } - else m_curAICmd = new AICmdFlyTo(this, target); + m_curAICmd = new AICmdFormation(this, static_cast(target), posoff); + } else + m_curAICmd = new AICmdFlyTo(this, target); } void Ship::AIDock(SpaceStation *target) diff --git a/src/Ship.cpp b/src/Ship.cpp index fec6e2082..9f599a568 100644 --- a/src/Ship.cpp +++ b/src/Ship.cpp @@ -2,31 +2,31 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Ship.h" +#include "Beam.h" #include "CityOnPlanet.h" -#include "Lang.h" #include "EnumStrings.h" +#include "Frame.h" +#include "HyperspaceCloud.h" +#include "Lang.h" #include "LuaEvent.h" #include "LuaUtils.h" #include "Missile.h" #include "Player.h" #include "Projectile.h" -#include "Beam.h" +#include "Sfx.h" #include "ShipAICmd.h" #include "ShipController.h" -#include "Sfx.h" -#include "galaxy/Galaxy.h" -#include "galaxy/Sector.h" -#include "galaxy/GalaxyCache.h" -#include "Frame.h" +#include "StringF.h" #include "WorldView.h" -#include "HyperspaceCloud.h" +#include "collider/collider.h" +#include "galaxy/Galaxy.h" +#include "galaxy/GalaxyCache.h" +#include "galaxy/Sector.h" #include "graphics/Drawables.h" #include "graphics/Graphics.h" #include "graphics/Material.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" -#include "collider/collider.h" -#include "StringF.h" #include @@ -60,7 +60,7 @@ void Ship::SaveToJson(Json &jsonObj, Space *space) shipObj["hyperspace_abort_sound"] = m_hyperspace.sounds.abort_sound; shipObj["hyperspace_jump_sound"] = m_hyperspace.sounds.jump_sound; - GetFixedGuns()->SaveToJson( shipObj, space ); + GetFixedGuns()->SaveToJson(shipObj, space); shipObj["ecm_recharge"] = m_ecmRecharge; shipObj["ship_type_id"] = m_type->id; @@ -84,11 +84,11 @@ void Ship::SaveToJson(Json &jsonObj, Space *space) void Ship::LoadFromJson(const Json &jsonObj, Space *space) { - AddFeature( Feature::PROPULSION ); // add component propulsion + AddFeature(Feature::PROPULSION); // add component propulsion DynamicBody::LoadFromJson(jsonObj, space); - AddFeature( Feature::PROPULSION ); // add component propulsion - AddFeature( Feature::FIXED_GUNS ); // add component fixed guns + AddFeature(Feature::PROPULSION); // add component propulsion + AddFeature(Feature::FIXED_GUNS); // add component fixed guns try { Json shipObj = jsonObj["ship"]; @@ -96,7 +96,7 @@ void Ship::LoadFromJson(const Json &jsonObj, Space *space) GetPropulsion()->LoadFromJson(shipObj, space); SetShipId(shipObj["ship_type_id"]); // XXX handle missing thirdparty ship - GetPropulsion()->SetFuelTankMass( GetShipType()->fuelTankMass ); + GetPropulsion()->SetFuelTankMass(GetShipType()->fuelTankMass); m_stats.fuel_tank_mass_left = GetPropulsion()->FuelTankMassLeft(); m_skin.LoadFromJson(shipObj); @@ -108,9 +108,9 @@ void Ship::LoadFromJson(const Json &jsonObj, Space *space) m_testLanded = shipObj["test_landed"]; m_flightState = shipObj["flight_state"]; - m_lastAlertUpdate = 0.0; // alertstate check cache timer - m_shipNear = false; // alertstate check cache value - m_shipFiring = false; // alertstate check cache value + m_lastAlertUpdate = 0.0; // alertstate check cache timer + m_shipNear = false; // alertstate check cache value + m_shipFiring = false; // alertstate check cache value m_alertState = shipObj["alert_state"]; Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState)); @@ -125,7 +125,7 @@ void Ship::LoadFromJson(const Json &jsonObj, Space *space) m_hyperspace.sounds.abort_sound = shipObj.value("hyperspace_abort_sound", ""); m_hyperspace.sounds.jump_sound = shipObj.value("hyperspace_jump_sound", ""); - GetFixedGuns()->LoadFromJson( shipObj, space ); + GetFixedGuns()->LoadFromJson(shipObj, space); m_ecmRecharge = shipObj["ecm_recharge"]; SetShipId(shipObj["ship_type_id"]); // XXX handle missing thirdparty ship @@ -170,14 +170,15 @@ void Ship::LoadFromJson(const Json &jsonObj, Space *space) } } -void Ship::InitEquipSet() { - lua_State * l = Lua::manager->GetLuaState(); - PropertyMap & p = Properties(); +void Ship::InitEquipSet() +{ + lua_State *l = Lua::manager->GetLuaState(); + PropertyMap &p = Properties(); LUA_DEBUG_START(l); pi_lua_import(l, "EquipSet"); LuaTable es_class(l, -1); LuaTable slots = LuaTable(l).LoadMap(GetShipType()->slots.begin(), GetShipType()->slots.end()); - m_equipSet = es_class.Call("New", slots); + m_equipSet = es_class.Call("New", slots); p.Set("equipSet", ScopedTable(m_equipSet)); UpdateEquipStats(); { @@ -196,7 +197,7 @@ void Ship::InitMaterials() SceneGraph::Model *pModel = GetModel(); assert(pModel); const Uint32 numMats = pModel->GetNumMaterials(); - for( Uint32 m=0; m mat = pModel->GetMaterialByIndex(m); mat->heatGradient = Graphics::TextureBuilder::Decal("textures/heat_gradient.dds").GetOrCreateTexture(Pi::renderer, "model"); mat->specialParameter0 = &s_heatGradientParams; @@ -226,24 +227,24 @@ void Ship::Init() p.Set("fuelMassLeft", m_stats.fuel_tank_mass_left); // Init of Propulsion: - GetPropulsion()->Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust, m_type->linAccelerationCap ); + GetPropulsion()->Init(this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust, m_type->linAccelerationCap); p.Set("shipName", m_shipName); - m_hyperspace.now = false; // TODO: move this on next savegame change, maybe + m_hyperspace.now = false; // TODO: move this on next savegame change, maybe m_hyperspaceCloud = 0; m_landingGearAnimation = GetModel()->FindAnimation("gear_down"); - GetFixedGuns()->InitGuns( GetModel()); + GetFixedGuns()->InitGuns(GetModel()); // If we've got the tag_landing set then use it for an offset // otherwise use zero so that it will dock but look clearly incorrect const SceneGraph::MatrixTransform *mt = GetModel()->FindTagByName("tag_landing"); - if( mt ) { + if (mt) { m_landingMinOffset = mt->GetTransform().GetTranslate().y; } else { - m_landingMinOffset = 0.0; // GetAabb().min.y; + m_landingMinOffset = 0.0; // GetAabb().min.y; } InitMaterials(); @@ -252,22 +253,23 @@ void Ship::Init() void Ship::PostLoadFixup(Space *space) { DynamicBody::PostLoadFixup(space); - m_dockedWith = static_cast(space->GetBodyByIndex(m_dockedWithIndex)); + m_dockedWith = static_cast(space->GetBodyByIndex(m_dockedWithIndex)); if (m_curAICmd) m_curAICmd->PostLoadFixup(space); m_controller->PostLoadFixup(space); } -Ship::Ship(const ShipType::Id &shipId): DynamicBody(), +Ship::Ship(const ShipType::Id &shipId) : + DynamicBody(), m_controller(0), - m_flightState(FLYING), - m_alertState(ALERT_NONE), + m_flightState(FLYING), + m_alertState(ALERT_NONE), m_landingGearAnimation(nullptr) { /* THIS CODE DOES NOT RUN WHEN LOADING SAVEGAMES!! */ - AddFeature( Feature::PROPULSION ); // add component propulsion - AddFeature( Feature::FIXED_GUNS ); // add component fixed guns + AddFeature(Feature::PROPULSION); // add component propulsion + AddFeature(Feature::FIXED_GUNS); // add component fixed guns Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState)); Properties().Set("alertStatus", EnumStrings::GetString("ShipAlertStatus", m_alertState)); @@ -302,16 +304,16 @@ Ship::Ship(const ShipType::Id &shipId): DynamicBody(), SetModel(m_type->modelName.c_str()); // Setting thrusters colors if (m_type->isGlobalColorDefined) GetModel()->SetThrusterColor(m_type->globalThrusterColor); - for (int i=0; iisDirectionColorDefined[i]) continue; vector3f dir; switch (i) { - case THRUSTER_FORWARD: dir = vector3f(0.0, 0.0, 1.0); break; - case THRUSTER_REVERSE: dir = vector3f(0.0, 0.0, -1.0); break; - case THRUSTER_LEFT: dir = vector3f(1.0, 0.0, 0.0); break; - case THRUSTER_RIGHT: dir = vector3f(-1.0, 0.0, 0.0); break; - case THRUSTER_UP: dir = vector3f(1.0, 0.0, 0.0); break; - case THRUSTER_DOWN: dir = vector3f(-1.0, 0.0, 0.0); break; + case THRUSTER_FORWARD: dir = vector3f(0.0, 0.0, 1.0); break; + case THRUSTER_REVERSE: dir = vector3f(0.0, 0.0, -1.0); break; + case THRUSTER_LEFT: dir = vector3f(1.0, 0.0, 0.0); break; + case THRUSTER_RIGHT: dir = vector3f(-1.0, 0.0, 0.0); break; + case THRUSTER_UP: dir = vector3f(1.0, 0.0, 0.0); break; + case THRUSTER_DOWN: dir = vector3f(-1.0, 0.0, 0.0); break; } GetModel()->SetThrusterColor(dir, m_type->directionThrusterColor[i]); } @@ -319,8 +321,8 @@ Ship::Ship(const ShipType::Id &shipId): DynamicBody(), m_skin.SetRandomColors(Pi::rng); m_skin.SetDecal(m_type->manufacturer); m_skin.Apply(GetModel()); - if(GetModel()->SupportsPatterns()) - GetModel()->SetPattern(Pi::rng.Int32(0, GetModel()->GetNumPatterns()-1)); + if (GetModel()->SupportsPatterns()) + GetModel()->SetPattern(Pi::rng.Int32(0, GetModel()->GetNumPatterns() - 1)); Init(); SetController(new ShipController()); @@ -347,8 +349,10 @@ float Ship::GetPercentHull() const float Ship::GetPercentShields() const { - if (m_stats.shield_mass <= 0) return 100.0f; - else return 100.0f * (m_stats.shield_mass_left / m_stats.shield_mass); + if (m_stats.shield_mass <= 0) + return 100.0f; + else + return 100.0f * (m_stats.shield_mass_left / m_stats.shield_mass); } void Ship::SetPercentHull(float p) @@ -360,10 +364,10 @@ void Ship::SetPercentHull(float p) void Ship::UpdateMass() { - SetMass((m_stats.static_mass + GetPropulsion()->FuelTankMassLeft() )*1000); + SetMass((m_stats.static_mass + GetPropulsion()->FuelTankMassLeft()) * 1000); } -bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) +bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) { if (m_invulnerable) { Sound::BodyMakeNoise(this, "Hull_hit_Small", 0.5f); @@ -371,7 +375,7 @@ bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact& co } if (!IsDead()) { - float dam = kgDamage*0.001f; + float dam = kgDamage * 0.001f; if (m_stats.shield_mass_left > 0.0f) { if (m_stats.shield_mass_left > dam) { m_stats.shield_mass_left -= dam; @@ -386,7 +390,7 @@ bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact& co m_shieldCooldown = DEFAULT_SHIELD_COOLDOWN_TIME; // transform the collision location into the models local space (from world space) and add it as a hit. matrix4x4d mtx = GetOrient(); - mtx.SetTranslate( GetPosition() ); + mtx.SetTranslate(GetPosition()); const matrix4x4d invmtx = mtx.Inverse(); const vector3d localPos = invmtx * contactData.pos; GetShields()->AddHit(localPos); @@ -397,9 +401,9 @@ bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact& co if (m_stats.hull_mass_left < 0) { if (attacker) { if (attacker->IsType(Object::BODY)) - LuaEvent::Queue("onShipDestroyed", this, dynamic_cast(attacker)); + LuaEvent::Queue("onShipDestroyed", this, dynamic_cast(attacker)); else if (attacker->IsType(Object::CITYONPLANET)) - LuaEvent::Queue("onShipDestroyed", this, dynamic_cast(attacker)->GetPlanet()); + LuaEvent::Queue("onShipDestroyed", this, dynamic_cast(attacker)->GetPlanet()); } Explode(); @@ -430,10 +434,10 @@ bool Ship::OnCollision(Object *b, Uint32 flags, double relVel) // hitting cargo scoop surface shouldn't do damage int cargoscoop_cap = 0; Properties().Get("cargo_scoop_cap", cargoscoop_cap); - if (cargoscoop_cap > 0 && b->IsType(Object::CARGOBODY) && !dynamic_cast(b)->IsDead()) { - LuaRef item = dynamic_cast(b)->GetCargoType(); + if (cargoscoop_cap > 0 && b->IsType(Object::CARGOBODY) && !dynamic_cast(b)->IsDead()) { + LuaRef item = dynamic_cast(b)->GetCargoType(); if (LuaObject::CallMethod(this, "AddEquip", item) > 0) { // try to add it to the ship cargo. - Pi::game->GetSpace()->KillBody(dynamic_cast(b)); + Pi::game->GetSpace()->KillBody(dynamic_cast(b)); if (this->IsType(Object::PLAYER)) Pi::game->log->Add(stringf(Lang::CARGO_SCOOP_ACTIVE_1_TONNE_X_COLLECTED, formatarg("item", ScopedTable(item).CallMethod("GetName")))); // XXX SfxManager::Add(this, TYPE_SCOOP); @@ -446,7 +450,8 @@ bool Ship::OnCollision(Object *b, Uint32 flags, double relVel) if (b->IsType(Object::PLANET)) { // geoms still enabled when landed - if (m_flightState != FLYING) return false; + if (m_flightState != FLYING) + return false; else { if (GetVelocity().Length() < MAX_LANDING_SPEED) { m_testLanded = true; @@ -461,10 +466,9 @@ bool Ship::OnCollision(Object *b, Uint32 flags, double relVel) b->IsType(Object::SPACESTATION) || b->IsType(Object::PLANET) || b->IsType(Object::STAR) || - b->IsType(Object::CARGOBODY)) - { + b->IsType(Object::CARGOBODY)) { LuaEvent::Queue("onShipCollided", this, - b->IsType(Object::CITYONPLANET) ? dynamic_cast(b)->GetPlanet() : dynamic_cast(b)); + b->IsType(Object::CITYONPLANET) ? dynamic_cast(b)->GetPlanet() : dynamic_cast(b)); } return DynamicBody::OnCollision(b, flags, relVel); @@ -490,7 +494,7 @@ bool Ship::DoCrushDamage(float kgDamage) } if (!IsDead()) { - float dam = kgDamage*0.01f; + float dam = kgDamage * 0.01f; if (m_stats.shield_mass_left > 0.0f) { if (m_stats.shield_mass_left > dam) { m_stats.shield_mass_left -= dam; @@ -504,7 +508,8 @@ bool Ship::DoCrushDamage(float kgDamage) m_shieldCooldown = DEFAULT_SHIELD_COOLDOWN_TIME; // create a collision location in the models local space and add it as a hit. - Random rnd; rnd.seed(time(0)); + Random rnd; + rnd.seed(time(0)); const vector3d randPos( rnd.Double() * 2.0 - 1.0, rnd.Double() * 2.0 - 1.0, @@ -561,13 +566,14 @@ void Ship::UpdateEquipStats() p.Set("maxHyperspaceRange", m_stats.hyperspace_range_max); } -void Ship::UpdateLuaStats() { +void Ship::UpdateLuaStats() +{ // This code cannot be in UpdateEquipStats itself because *Equip* needs to be // called in Init(), which is itself called in the constructor, but we absolutely // cannot use LuaObject::* in a constructor, or else we'd fix the type of the // object to Ship forever, even though it could very well be a Player. UpdateEquipStats(); - PropertyMap& p = Properties(); + PropertyMap &p = Properties(); m_stats.hyperspace_range = m_stats.hyperspace_range_max = 0; int hyperclass = 0; p.Get("hyperclass_cap", hyperclass); @@ -581,16 +587,17 @@ void Ship::UpdateLuaStats() { p.Set("maxHyperspaceRange", m_stats.hyperspace_range_max); } -void Ship::UpdateGunsStats() { +void Ship::UpdateGunsStats() +{ float cooler = 1.0f; Properties().Get("laser_cooler_cap", cooler); - GetFixedGuns()->SetCoolingBoost( cooler ); + GetFixedGuns()->SetCoolingBoost(cooler); - for (int num=0; num < 2; num++) { - std::string prefix(num?"laser_rear_":"laser_front_"); + for (int num = 0; num < 2; num++) { + std::string prefix(num ? "laser_rear_" : "laser_front_"); int damage = 0; - Properties().Get(prefix+"damage", damage); + Properties().Get(prefix + "damage", damage); if (!damage) { GetFixedGuns()->UnMountGun(num); } else { @@ -598,24 +605,26 @@ void Ship::UpdateGunsStats() { LuaTable prop(Lua::manager->GetLuaState(), -1); const Color c( - prop.Get(prefix+"rgba_r"), - prop.Get(prefix+"rgba_g"), - prop.Get(prefix+"rgba_b"), - prop.Get(prefix+"rgba_a")); + prop.Get(prefix + "rgba_r"), + prop.Get(prefix + "rgba_g"), + prop.Get(prefix + "rgba_b"), + prop.Get(prefix + "rgba_a")); const float heatrate = prop.Get(prefix + "heatrate", 0.01f); const float coolrate = prop.Get(prefix + "coolrate", 0.01f); - const float lifespan = prop.Get(prefix+"lifespan"); - const float width = prop.Get(prefix+"width"); - const float length = prop.Get(prefix+"length"); - const bool mining = prop.Get(prefix+"mining"); - const float speed = prop.Get(prefix+"speed"); - const float recharge = prop.Get(prefix+"rechargeTime"); - const bool beam = prop.Get(prefix+"beam"); + const float lifespan = prop.Get(prefix + "lifespan"); + const float width = prop.Get(prefix + "width"); + const float length = prop.Get(prefix + "length"); + const bool mining = prop.Get(prefix + "mining"); + const float speed = prop.Get(prefix + "speed"); + const float recharge = prop.Get(prefix + "rechargeTime"); + const bool beam = prop.Get(prefix + "beam"); - GetFixedGuns()->MountGun( num, recharge, lifespan, damage, length, width, mining, c, speed, beam, heatrate, coolrate); + GetFixedGuns()->MountGun(num, recharge, lifespan, damage, length, width, mining, c, speed, beam, heatrate, coolrate); - if (prop.Get(prefix+"dual")) GetFixedGuns()->IsDual( num, true ); - else GetFixedGuns()->IsDual( num, false ); + if (prop.Get(prefix + "dual")) + GetFixedGuns()->IsDual(num, true); + else + GetFixedGuns()->IsDual(num, false); lua_pop(prop.GetLua(), 1); } } @@ -629,7 +638,8 @@ void Ship::UpdateFuelStats() UpdateMass(); } -Ship::HyperjumpStatus Ship::CheckHyperjumpCapability() const { +Ship::HyperjumpStatus Ship::CheckHyperjumpCapability() const +{ if (GetFlightState() == HYPERSPACE) return HYPERJUMP_DRIVE_ACTIVE; @@ -639,7 +649,8 @@ Ship::HyperjumpStatus Ship::CheckHyperjumpCapability() const { return HYPERJUMP_OK; } -Ship::HyperjumpStatus Ship::InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks) { +Ship::HyperjumpStatus Ship::InitiateHyperjumpTo(const SystemPath &dest, int warmup_time, double duration, const HyperdriveSoundsTable &sounds, LuaRef checks) +{ if (!dest.HasValidSystem() || GetFlightState() != FLYING || warmup_time < 1) return HYPERJUMP_SAFETY_LOCKOUT; StarSystem *s = Pi::game->GetSpace()->GetStarSystem().Get(); @@ -656,7 +667,8 @@ Ship::HyperjumpStatus Ship::InitiateHyperjumpTo(const SystemPath &dest, int warm return Ship::HYPERJUMP_OK; } -void Ship::AbortHyperjump() { +void Ship::AbortHyperjump() +{ m_hyperspace.countdown = 0; m_hyperspace.now = false; m_hyperspace.duration = 0; @@ -693,16 +705,17 @@ Ship::ECMResult Ship::UseECM() if (dist < ECM_RADIUS) { // increasing chance of destroying it with proximity if (Pi::rng.Double() > (dist / ECM_RADIUS)) { - static_cast(*i)->ECMAttack(ecm_power_cap); + static_cast(*i)->ECMAttack(ecm_power_cap); } } } return ECM_ACTIVATED; - } - else return ECM_NOT_INSTALLED; + } else + return ECM_NOT_INSTALLED; } -Missile * Ship::SpawnMissile(ShipType::Id missile_type, int power) { +Missile *Ship::SpawnMissile(ShipType::Id missile_type, int power) +{ if (GetFlightState() != FLYING) return 0; @@ -711,8 +724,8 @@ Missile * Ship::SpawnMissile(ShipType::Id missile_type, int power) { missile->SetFrame(GetFrame()); const vector3d pos = GetOrient() * vector3d(0, GetAabb().min.y - 10, GetAabb().min.z); const vector3d vel = -40.0 * GetOrient().VectorZ(); - missile->SetPosition(GetPosition()+pos); - missile->SetVelocity(GetVelocity()+vel); + missile->SetPosition(GetPosition() + pos); + missile->SetVelocity(GetVelocity() + vel); Pi::game->GetSpace()->AddBody(missile); return missile; } @@ -745,16 +758,43 @@ void Ship::SetFlightState(Ship::FlightState newState) m_flightState = newState; Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState)); - switch (m_flightState) - { - case FLYING: SetMoving(true); SetColliding(true); SetStatic(false); break; - case DOCKING: SetMoving(false); SetColliding(false); SetStatic(false); break; - case UNDOCKING: SetMoving(false); SetColliding(false); SetStatic(false); break; -// TODO: set collision index? dynamic stations... use landed for open-air? - case DOCKED: SetMoving(false); SetColliding(false); SetStatic(false); break; - case LANDED: SetMoving(false); SetColliding(true); SetStatic(true); break; - case JUMPING: SetMoving(true); SetColliding(false); SetStatic(false); break; - case HYPERSPACE: SetMoving(false); SetColliding(false); SetStatic(false); break; + switch (m_flightState) { + case FLYING: + SetMoving(true); + SetColliding(true); + SetStatic(false); + break; + case DOCKING: + SetMoving(false); + SetColliding(false); + SetStatic(false); + break; + case UNDOCKING: + SetMoving(false); + SetColliding(false); + SetStatic(false); + break; + // TODO: set collision index? dynamic stations... use landed for open-air? + case DOCKED: + SetMoving(false); + SetColliding(false); + SetStatic(false); + break; + case LANDED: + SetMoving(false); + SetColliding(true); + SetStatic(true); + break; + case JUMPING: + SetMoving(true); + SetColliding(false); + SetStatic(false); + break; + case HYPERSPACE: + SetMoving(false); + SetColliding(false); + SetStatic(false); + break; } } @@ -764,13 +804,13 @@ void Ship::Blastoff() vector3d up = GetPosition().Normalized(); assert(GetFrame()->GetBody()->IsType(Object::PLANET)); - const double planetRadius = 2.0 + static_cast(GetFrame()->GetBody())->GetTerrainHeight(up); + const double planetRadius = 2.0 + static_cast(GetFrame()->GetBody())->GetTerrainHeight(up); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetFlightState(FLYING); - SetPosition(up*planetRadius - GetAabb().min.y*up); - SetThrusterState(1, 1.0); // thrust upwards + SetPosition(up * planetRadius - GetAabb().min.y * up); + SetThrusterState(1, 1.0); // thrust upwards LuaEvent::Queue("onShipTakeOff", this, GetFrame()->GetBody()); } @@ -783,7 +823,7 @@ void Ship::TestLanded() if (GetFrame()->GetBody()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); - const double planetRadius = static_cast(GetFrame()->GetBody())->GetTerrainHeight(up); + const double planetRadius = static_cast(GetFrame()->GetBody())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // check player is sortof sensibly oriented for landing @@ -811,12 +851,12 @@ void Ship::SetLandedOn(Planet *p, float latitude, float longitude) { m_wheelTransition = 0; m_wheelState = 1.0f; - Frame* f = p->GetFrame()->GetRotFrame(); + Frame *f = p->GetFrame()->GetRotFrame(); SetFrame(f); - vector3d up = vector3d(cos(latitude)*sin(longitude), sin(latitude), cos(latitude)*cos(longitude)); + vector3d up = vector3d(cos(latitude) * sin(longitude), sin(latitude), cos(latitude) * cos(longitude)); const double planetRadius = p->GetTerrainHeight(up); SetPosition(up * (planetRadius - GetAabb().min.y)); - vector3d right = up.Cross(vector3d(0,0,1)).Normalized(); + vector3d right = up.Cross(vector3d(0, 0, 1)).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); @@ -837,9 +877,9 @@ void Ship::TimeStepUpdate(const float timeStep) // If docked, station is responsible for updating position/orient of ship // but we call this crap anyway and hope it doesn't do anything bad - const vector3d thrust=GetPropulsion()->GetActualLinThrust(); - AddRelForce( thrust ); - AddRelTorque( GetPropulsion()->GetActualAngThrust() ); + const vector3d thrust = GetPropulsion()->GetActualLinThrust(); + AddRelForce(thrust); + AddRelTorque(GetPropulsion()->GetActualAngThrust()); if (m_landingGearAnimation) m_landingGearAnimation->SetProgress(m_wheelState); @@ -847,7 +887,7 @@ void Ship::TimeStepUpdate(const float timeStep) DynamicBody::TimeStepUpdate(timeStep); // fuel use decreases mass, so do this as the last thing in the frame - UpdateFuel( timeStep ); + UpdateFuel(timeStep); m_navLights->SetEnabled(m_wheelState > 0.01f); m_navLights->Update(timeStep); @@ -864,13 +904,14 @@ void Ship::DoThrusterSounds() const float v_env = (Pi::game->GetWorldView()->GetCameraController()->IsExternal() ? 1.0f : 0.5f) * Sound::GetSfxVolume(); static Sound::Event sndev; float volBoth = 0.0f; - volBoth += 0.5f*fabs(GetPropulsion()->GetLinThrusterState().y); - volBoth += 0.5f*fabs(GetPropulsion()->GetLinThrusterState().z); + volBoth += 0.5f * fabs(GetPropulsion()->GetLinThrusterState().y); + volBoth += 0.5f * fabs(GetPropulsion()->GetLinThrusterState().z); float targetVol[2] = { volBoth, volBoth }; if (GetPropulsion()->GetLinThrusterState().x > 0.0) - targetVol[0] += 0.5f*float(GetPropulsion()->GetLinThrusterState().x); - else targetVol[1] += -0.5f*float(GetPropulsion()->GetLinThrusterState().x); + targetVol[0] += 0.5f * float(GetPropulsion()->GetLinThrusterState().x); + else + targetVol[1] += -0.5f * float(GetPropulsion()->GetLinThrusterState().x); targetVol[0] = v_env * Clamp(targetVol[0], 0.0f, 1.0f); targetVol[1] = v_env * Clamp(targetVol[1], 0.0f, 1.0f); @@ -946,15 +987,13 @@ void Ship::UpdateAlertState() // sanity check: m_lastAlertUpdate should not be in the future. // reset and re-check if it is. - if (m_lastAlertUpdate > Pi::game->GetTime()) - { + if (m_lastAlertUpdate > Pi::game->GetTime()) { m_lastAlertUpdate = 0; m_shipNear = false; m_shipFiring = false; } - if (m_lastAlertUpdate + 1.0 <= Pi::game->GetTime()) - { + if (m_lastAlertUpdate + 1.0 <= Pi::game->GetTime()) { // time to update the list again, once per second should suffice m_lastAlertUpdate = Pi::game->GetTime(); @@ -964,19 +1003,18 @@ void Ship::UpdateAlertState() Pi::game->GetSpace()->GetBodiesMaybeNear(this, ALERT_DISTANCE, m_nearbyBodies); // handle the results - for (auto i : m_nearbyBodies) - { + for (auto i : m_nearbyBodies) { if ((i) == this) continue; if (!(i)->IsType(Object::SHIP) || (i)->IsType(Object::MISSILE)) continue; // TODO: Here there were a const on Ship*, now it cannot remain because of ship->firing and so, this open a breach... // A solution is to put a member on ship: true if is firing, false if is not - Ship *ship = static_cast< Ship*>(i); + Ship *ship = static_cast(i); if (ship->GetShipType()->tag == ShipType::TAG_STATIC_SHIP) continue; if (ship->GetFlightState() == LANDED || ship->GetFlightState() == DOCKED) continue; - if (GetPositionRelTo(ship).LengthSqr() < ALERT_DISTANCE*ALERT_DISTANCE) { + if (GetPositionRelTo(ship).LengthSqr() < ALERT_DISTANCE * ALERT_DISTANCE) { ship_is_near = true; Uint32 gunstate = ship->GetFixedGuns()->IsFiring(); @@ -990,65 +1028,60 @@ void Ship::UpdateAlertState() // store m_shipNear = ship_is_near; m_shipFiring = ship_is_firing; - } - else - { + } else { ship_is_near = m_shipNear; ship_is_firing = m_shipFiring; } bool changed = false; switch (m_alertState) { - case ALERT_NONE: - if (ship_is_near) { - SetAlertState(ALERT_SHIP_NEARBY); - changed = true; - } - if (ship_is_firing) { - m_lastFiringAlert = Pi::game->GetTime(); - SetAlertState(ALERT_SHIP_FIRING); - changed = true; - } - break; + case ALERT_NONE: + if (ship_is_near) { + SetAlertState(ALERT_SHIP_NEARBY); + changed = true; + } + if (ship_is_firing) { + m_lastFiringAlert = Pi::game->GetTime(); + SetAlertState(ALERT_SHIP_FIRING); + changed = true; + } + break; - case ALERT_SHIP_NEARBY: - if (!ship_is_near) { - SetAlertState(ALERT_NONE); - changed = true; - } - else if (ship_is_firing) { - m_lastFiringAlert = Pi::game->GetTime(); - SetAlertState(ALERT_SHIP_FIRING); - changed = true; - } - break; + case ALERT_SHIP_NEARBY: + if (!ship_is_near) { + SetAlertState(ALERT_NONE); + changed = true; + } else if (ship_is_firing) { + m_lastFiringAlert = Pi::game->GetTime(); + SetAlertState(ALERT_SHIP_FIRING); + changed = true; + } + break; - case ALERT_SHIP_FIRING: - if (!ship_is_near) { - SetAlertState(ALERT_NONE); - changed = true; - } - else if (ship_is_firing) { - m_lastFiringAlert = Pi::game->GetTime(); - } - else if (m_lastFiringAlert + 60.0 <= Pi::game->GetTime()) { - SetAlertState(ALERT_SHIP_NEARBY); - changed = true; - } - break; + case ALERT_SHIP_FIRING: + if (!ship_is_near) { + SetAlertState(ALERT_NONE); + changed = true; + } else if (ship_is_firing) { + m_lastFiringAlert = Pi::game->GetTime(); + } else if (m_lastFiringAlert + 60.0 <= Pi::game->GetTime()) { + SetAlertState(ALERT_SHIP_NEARBY); + changed = true; + } + break; } if (changed) LuaEvent::Queue("onShipAlertChanged", this, EnumStrings::GetString("ShipAlertStatus", GetAlertState())); } -void Ship::UpdateFuel(const float timeStep ) +void Ship::UpdateFuel(const float timeStep) { - GetPropulsion()->UpdateFuel( timeStep ); + GetPropulsion()->UpdateFuel(timeStep); UpdateFuelStats(); - Properties().Set("fuel", GetFuel()*100); // XXX to match SetFuelPercent + Properties().Set("fuel", GetFuel() * 100); // XXX to match SetFuelPercent - if ( GetPropulsion()->IsFuelStateChanged() ) + if (GetPropulsion()->IsFuelStateChanged()) LuaEvent::Queue("onShipFuelChanged", this, EnumStrings::GetString("ShipFuelStatus", GetPropulsion()->GetFuelState())); } @@ -1064,11 +1097,10 @@ void Ship::StaticUpdate(const float timeStep) if (GetHullTemperature() > 1.0) Explode(); - if (m_flightState == FLYING) { Body *astro = GetFrame()->GetBody(); if (astro && astro->IsType(Object::PLANET)) { - Planet *p = static_cast(astro); + Planet *p = static_cast(astro); double dist = GetPosition().Length(); double pressure, density; p->GetAtmosphericState(dist, &pressure, &density); @@ -1091,7 +1123,7 @@ void Ship::StaticUpdate(const float timeStep) if (m_flightState == FLYING && capacity > 0) { Body *astro = GetFrame()->GetBody(); if (astro && astro->IsType(Object::PLANET)) { - Planet *p = static_cast(astro); + Planet *p = static_cast(astro); if (p->GetSystemBody()->IsScoopable()) { const double dist = GetPosition().Length(); double pressure, density; @@ -1111,7 +1143,7 @@ void Ship::StaticUpdate(const float timeStep) UpdateEquipStats(); if (this->IsType(Object::PLAYER)) { Pi::game->log->Add(stringf(Lang::FUEL_SCOOP_ACTIVE_N_TONNES_H_COLLECTED, - formatarg("quantity", LuaObject::CallMethod(this, "CountEquip", hydrogen)))); + formatarg("quantity", LuaObject::CallMethod(this, "CountEquip", hydrogen)))); } lua_pop(l, 3); } @@ -1128,7 +1160,7 @@ void Ship::StaticUpdate(const float timeStep) // temperature regulation and breathable atmosphere // kill stuff roughly every 5 seconds - if ((!m_dockedWith) && (5.0*Pi::rng.Double() < timeStep)) { + if ((!m_dockedWith) && (5.0 * Pi::rng.Double() < timeStep)) { std::string t(Pi::rng.Int32(2) ? "live_animals" : "slaves"); lua_State *l = Lua::manager->GetLuaState(); @@ -1140,8 +1172,7 @@ void Ship::StaticUpdate(const float timeStep) Pi::game->log->Add(Lang::CARGO_BAY_LIFE_SUPPORT_LOST); } lua_pop(l, 4); - } - else + } else lua_pop(l, 3); } } @@ -1154,40 +1185,30 @@ void Ship::StaticUpdate(const float timeStep) // lasers FixedGuns *fg = GetFixedGuns(); - fg->UpdateGuns( timeStep ); - for (int i = 0; i < 2; i++) - { - if (fg->Fire(i, this)) - { - if (fg->IsBeam(i)) - { + fg->UpdateGuns(timeStep); + for (int i = 0; i < 2; i++) { + if (fg->Fire(i, this)) { + if (fg->IsBeam(i)) { float vl, vr; Sound::CalculateStereo(this, 1.0f, &vl, &vr); m_beamLaser[i].Play("Beam_laser", vl, vr, Sound::OP_REPEAT); - } - else - { + } else { Sound::BodyMakeNoise(this, "Pulse_Laser", 1.0f); } LuaEvent::Queue("onShipFiring", this); } - if (fg->IsBeam(i)) - { - if (fg->IsFiring(i)) - { + if (fg->IsBeam(i)) { + if (fg->IsFiring(i)) { float vl, vr; Sound::CalculateStereo(this, 1.0f, &vl, &vr); if (!m_beamLaser[i].IsPlaying()) { m_beamLaser[i].Play("Beam_laser", vl, vr, Sound::OP_REPEAT); - } - else { + } else { // update volume m_beamLaser[i].SetVolume(vl, vr); } - } - else if (!fg->IsFiring(i) && m_beamLaser[i].IsPlaying()) - { + } else if (!fg->IsFiring(i) && m_beamLaser[i].IsPlaying()) { m_beamLaser[i].Stop(); } } @@ -1212,7 +1233,7 @@ void Ship::StaticUpdate(const float timeStep) } if (m_wheelTransition) { - m_wheelState += m_wheelTransition*0.3f*timeStep; + m_wheelState += m_wheelTransition * 0.3f * timeStep; m_wheelState = Clamp(m_wheelState, 0.0f, 1.0f); if (is_equal_exact(m_wheelState, 0.0f) || is_equal_exact(m_wheelState, 1.0f)) m_wheelTransition = 0; @@ -1223,7 +1244,7 @@ void Ship::StaticUpdate(const float timeStep) capacity = 0; Properties().Get("hull_autorepair_cap", capacity); if (capacity) { - m_stats.hull_mass_left = std::min(m_stats.hull_mass_left + 0.1f*timeStep, float(m_type->hullMass)); + m_stats.hull_mass_left = std::min(m_stats.hull_mass_left + 0.1f * timeStep, float(m_type->hullMass)); Properties().Set("hullMassLeft", m_stats.hull_mass_left); Properties().Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass))); } @@ -1240,7 +1261,7 @@ void Ship::StaticUpdate(const float timeStep) if (m_hyperspace.countdown > 0.0f) { // Check the Lua function bool abort = false; - lua_State * l = m_hyperspace.checks.GetLua(); + lua_State *l = m_hyperspace.checks.GetLua(); if (l) { m_hyperspace.checks.PushCopyToStack(); if (lua_isfunction(l, -1)) { @@ -1268,10 +1289,9 @@ void Ship::StaticUpdate(const float timeStep) } } } - } -void Ship::NotifyRemoved(const Body* const removedBody) +void Ship::NotifyRemoved(const Body *const removedBody) { if (m_curAICmd) m_curAICmd->OnDeleted(removedBody); } @@ -1301,7 +1321,7 @@ void Ship::SetGunState(int idx, int state) if (m_flightState != FLYING) return; - GetFixedGuns()->SetGunFiringState( idx, state ); + GetFixedGuns()->SetGunFiringState(idx, state); } bool Ship::SetWheelState(bool down) @@ -1318,18 +1338,18 @@ void Ship::Render(Graphics::Renderer *renderer, const Camera *camera, const vect { if (IsDead()) return; - GetPropulsion()->Render( renderer, camera, viewCoords, viewTransform ); + GetPropulsion()->Render(renderer, camera, viewCoords, viewTransform); matrix3x3f mt; matrix3x3dtof(viewTransform.Inverse().GetOrient(), mt); s_heatGradientParams.heatingMatrix = mt; s_heatGradientParams.heatingNormal = vector3f(GetVelocity().Normalized()); - s_heatGradientParams.heatingAmount = Clamp(GetHullTemperature(),0.0,1.0); + s_heatGradientParams.heatingAmount = Clamp(GetHullTemperature(), 0.0, 1.0); // This has to be done per-model with a shield and just before it's rendered const bool shieldsVisible = m_shieldCooldown > 0.01f && m_stats.shield_mass_left > (m_stats.shield_mass / 100.0f); GetShields()->SetEnabled(shieldsVisible); - GetShields()->Update(m_shieldCooldown, 0.01f*GetPercentShields()); + GetShields()->Update(m_shieldCooldown, 0.01f * GetPercentShields()); //strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText)); RenderModel(renderer, camera, viewCoords, viewTransform); @@ -1339,13 +1359,13 @@ void Ship::Render(Graphics::Renderer *renderer, const Camera *camera, const vect if (m_ecmRecharge > 0.0f) { // ECM effect: a cloud of particles for a sparkly effect vector3f v[100]; - for (int i=0; i<100; i++) { - const double r1 = Pi::rng.Double()-0.5; - const double r2 = Pi::rng.Double()-0.5; - const double r3 = Pi::rng.Double()-0.5; - v[i] = vector3f(GetPhysRadius()*vector3d(r1, r2, r3).NormalizedSafe()); + for (int i = 0; i < 100; i++) { + const double r1 = Pi::rng.Double() - 0.5; + const double r2 = Pi::rng.Double() - 0.5; + const double r3 = Pi::rng.Double() - 0.5; + v[i] = vector3f(GetPhysRadius() * vector3d(r1, r2, r3).NormalizedSafe()); } - Color c(128,128,255,255); + Color c(128, 128, 255, 255); float totalRechargeTime = GetECMRechargeTime(); if (totalRechargeTime >= 0.0f) { c.a = (m_ecmRecharge / totalRechargeTime) * 255; @@ -1354,7 +1374,8 @@ void Ship::Render(Graphics::Renderer *renderer, const Camera *camera, const vect SfxManager::ecmParticle->diffuse = c; matrix4x4f t; - for (int i=0; i<12; i++) t[i] = float(viewTransform[i]); + for (int i = 0; i < 12; i++) + t[i] = float(viewTransform[i]); t[12] = viewCoords.x; t[13] = viewCoords.y; t[14] = viewCoords.z; @@ -1365,18 +1386,19 @@ void Ship::Render(Graphics::Renderer *renderer, const Camera *camera, const vect } } -bool Ship::SpawnCargo(CargoBody * c_body) const +bool Ship::SpawnCargo(CargoBody *c_body) const { if (m_flightState != FLYING) return false; vector3d pos = GetOrient() * vector3d(0, GetAabb().min.y - 5, 0); c_body->SetFrame(GetFrame()); c_body->SetPosition(GetPosition() + pos); - c_body->SetVelocity(GetVelocity() + GetOrient()*vector3d(0, -10, 0)); + c_body->SetVelocity(GetVelocity() + GetOrient() * vector3d(0, -10, 0)); Pi::game->GetSpace()->AddBody(c_body); return true; } -void Ship::EnterHyperspace() { +void Ship::EnterHyperspace() +{ assert(GetFlightState() != Ship::HYPERSPACE); // Is it still a good idea, with the onLeaveSystem moved elsewhere? @@ -1396,7 +1418,8 @@ void Ship::EnterHyperspace() { OnEnterHyperspace(); } -void Ship::OnEnterHyperspace() { +void Ship::OnEnterHyperspace() +{ Sound::BodyMakeNoise(this, m_hyperspace.sounds.jump_sound.c_str(), 1.f); m_hyperspaceCloud = new HyperspaceCloud(this, Pi::game->GetTime() + m_hyperspace.duration, false); m_hyperspaceCloud->SetFrame(GetFrame()); @@ -1408,7 +1431,8 @@ void Ship::OnEnterHyperspace() { space->AddBody(m_hyperspaceCloud); } -void Ship::EnterSystem() { +void Ship::EnterSystem() +{ PROFILE_SCOPED() assert(GetFlightState() == Ship::HYPERSPACE); @@ -1420,7 +1444,8 @@ void Ship::EnterSystem() { LuaEvent::Queue("onEnterSystem", this); } -void Ship::OnEnterSystem() { +void Ship::OnEnterSystem() +{ m_hyperspaceCloud = 0; } diff --git a/src/Ship.h b/src/Ship.h index ec107fe8f..921145f33 100644 --- a/src/Ship.h +++ b/src/Ship.h @@ -4,24 +4,24 @@ #ifndef _SHIP_H #define _SHIP_H -#include "libs.h" #include "Camera.h" #include "DynamicBody.h" -#include "galaxy/SystemPath.h" +#include "LuaTable.h" #include "NavLights.h" #include "Planet.h" #include "Sensors.h" #include "ShipType.h" -#include "Space.h" -#include "scenegraph/SceneGraph.h" -#include "scenegraph/ModelSkin.h" #include "Sound.h" -#include "LuaTable.h" +#include "Space.h" +#include "galaxy/SystemPath.h" +#include "libs.h" +#include "scenegraph/ModelSkin.h" +#include "scenegraph/SceneGraph.h" #include #include -#include "Propulsion.h" #include "FixedGuns.h" +#include "Propulsion.h" class SpaceStation; class HyperspaceCloud; @@ -29,7 +29,9 @@ class AICommand; class ShipController; class CargoBody; class Missile; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} struct HeatGradientParameters_t { matrix3x3f heatingMatrix; @@ -56,9 +58,10 @@ struct HyperdriveSoundsTable { std::string abort_sound; }; -class Ship: public DynamicBody { +class Ship : public DynamicBody { friend class ShipController; //only controllers need access to AITimeStep friend class PlayerShipController; + public: OBJDEF(Ship, DynamicBody, SHIP); Ship(const ShipType::Id &shipId); @@ -81,7 +84,8 @@ public: virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; - inline void ClearThrusterState() { + inline void ClearThrusterState() + { ClearAngThrusterState(); if (m_launchLockTimeout <= 0.0f) ClearLinThrusterState(); } @@ -106,17 +110,17 @@ public: bool IsDecelerating() const { return m_decelerating; } - virtual void NotifyRemoved(const Body* const removedBody) override; + virtual void NotifyRemoved(const Body *const removedBody) override; virtual bool OnCollision(Object *o, Uint32 flags, double relVel) override; - virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override; + virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact &contactData) override; enum FlightState { // - FLYING, // open flight (includes autopilot) - DOCKING, // in docking animation - UNDOCKING, // in docking animation - DOCKED, // docked with station - LANDED, // rough landed (not docked) - JUMPING, // between space and hyperspace ;) + FLYING, // open flight (includes autopilot) + DOCKING, // in docking animation + UNDOCKING, // in docking animation + DOCKED, // docked with station + LANDED, // rough landed (not docked) + JUMPING, // between space and hyperspace ;) HYPERSPACE, // in hyperspace }; @@ -124,7 +128,7 @@ public: void SetFlightState(FlightState s); float GetWheelState() const { return m_wheelState; } int GetWheelTransition() const { return m_wheelTransition; } - bool SpawnCargo(CargoBody * c_body) const; + bool SpawnCargo(CargoBody *c_body) const; LuaRef GetEquipSet() const { return m_equipSet; } @@ -165,7 +169,7 @@ public: ECMResult UseECM(); - virtual Missile * SpawnMissile(ShipType::Id missile_type, int power=-1); + virtual Missile *SpawnMissile(ShipType::Id missile_type, int power = -1); enum AlertState { // ALERT_NONE, @@ -186,7 +190,7 @@ public: void AIOrbit(Body *target, double alt); // Note: defined in Ship-AI.cpp void AIHoldPosition(); // Note: defined in Ship-AI.cpp - void AIBodyDeleted(const Body* const body) {}; // Note: defined in Ship-AI.cpp // todo: signals + void AIBodyDeleted(const Body *const body){}; // Note: defined in Ship-AI.cpp // todo: signals const AICommand *GetAICommand() const { return m_curAICmd; } @@ -211,7 +215,7 @@ public: HyperspaceCloud *GetHyperspaceCloud() const { return m_hyperspaceCloud; } - sigc::signal onDock; // JJ: check what these are for + sigc::signal onDock; // JJ: check what these are for sigc::signal onUndock; sigc::signal onLanded; @@ -298,7 +302,7 @@ private: AICommand *m_curAICmd; - double m_landingMinOffset; // offset from the centre of the ship used during docking + double m_landingMinOffset; // offset from the centre of the ship used during docking int m_dockedWithIndex; // deserialisation @@ -308,9 +312,10 @@ private: static HeatGradientParameters_t s_heatGradientParams; std::unique_ptr m_sensors; - std::unordered_map m_relationsMap; + std::unordered_map m_relationsMap; std::string m_shipName; + public: void ClearAngThrusterState() { GetPropulsion()->ClearAngThrusterState(); } void ClearLinThrusterState() { GetPropulsion()->ClearLinThrusterState(); } @@ -322,12 +327,10 @@ public: void SetFuelReserve(const double f) { GetPropulsion()->SetFuelReserve(f); } bool AIMatchVel(const vector3d &vel) { return GetPropulsion()->AIMatchVel(vel); } - double AIFaceDirection(const vector3d &dir, double av=0) { return GetPropulsion()->AIFaceDirection(dir, av); } + double AIFaceDirection(const vector3d &dir, double av = 0) { return GetPropulsion()->AIFaceDirection(dir, av); } void AIMatchAngVelObjSpace(const vector3d &angvel) { return GetPropulsion()->AIMatchAngVelObjSpace(angvel); } void SetThrusterState(int axis, double level) { return GetPropulsion()->SetLinThrusterState(axis, level); } void AIModelCoordsMatchAngVel(const vector3d &desiredAngVel, double softness) { return GetPropulsion()->AIModelCoordsMatchAngVel(desiredAngVel, softness); } }; - - #endif /* _SHIP_H */ diff --git a/src/ShipAICmd.cpp b/src/ShipAICmd.cpp index dccf664c1..bfd20aa26 100644 --- a/src/ShipAICmd.cpp +++ b/src/ShipAICmd.cpp @@ -1,17 +1,16 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Ship.h" #include "ShipAICmd.h" -#include "Pi.h" -#include "Player.h" -#include "perlin.h" #include "Frame.h" +#include "Pi.h" #include "Planet.h" -#include "SpaceStation.h" +#include "Player.h" +#include "Ship.h" #include "Space.h" - +#include "SpaceStation.h" +#include "libs.h" +#include "perlin.h" static const double VICINITY_MIN = 15000.0; static const double VICINITY_MUL = 4.0; @@ -26,14 +25,15 @@ AICommand *AICommand::LoadFromJson(const Json &jsonObj) Json commonAiCommandObj = aiCommandObj["common_ai_command"]; CmdName name = CmdName(commonAiCommandObj["command_name"]); switch (name) { - case CMD_NONE: default: return 0; // No longer need CMD_NONE (see AICommand::SaveToJson notes). - case CMD_DOCK: return new AICmdDock(aiCommandObj); - case CMD_FLYTO: return new AICmdFlyTo(aiCommandObj); - case CMD_FLYAROUND: return new AICmdFlyAround(aiCommandObj); - case CMD_KILL: return new AICmdKill(aiCommandObj); - case CMD_KAMIKAZE: return new AICmdKamikaze(aiCommandObj); - case CMD_HOLDPOSITION: return new AICmdHoldPosition(aiCommandObj); - case CMD_FORMATION: return new AICmdFormation(aiCommandObj); + case CMD_NONE: + default: return 0; // No longer need CMD_NONE (see AICommand::SaveToJson notes). + case CMD_DOCK: return new AICmdDock(aiCommandObj); + case CMD_FLYTO: return new AICmdFlyTo(aiCommandObj); + case CMD_FLYAROUND: return new AICmdFlyAround(aiCommandObj); + case CMD_KILL: return new AICmdKill(aiCommandObj); + case CMD_KAMIKAZE: return new AICmdKamikaze(aiCommandObj); + case CMD_HOLDPOSITION: return new AICmdHoldPosition(aiCommandObj); + case CMD_FORMATION: return new AICmdFormation(aiCommandObj); } } catch (Json::type_error &) { throw SavedGameCorruptException(); @@ -58,7 +58,8 @@ void AICommand::SaveToJson(Json &jsonObj) jsonObj["common_ai_command"] = commonAiCommandObj; // Add common ai command object to supplied object. } -AICommand::AICommand(const Json &jsonObj, CmdName name) : m_cmdName(name) +AICommand::AICommand(const Json &jsonObj, CmdName name) : + m_cmdName(name) { try { Json commonAiCommandObj = jsonObj["common_ai_command"]; @@ -80,11 +81,11 @@ void AICommand::PostLoadFixup(Space *space) bool AICommand::ProcessChild() { - if (!m_child) return true; // no child present + if (!m_child) return true; // no child present m_child->m_is_flyto = false; - if (!m_child->TimeStepUpdate()) return false; // child still active + if (!m_child->TimeStepUpdate()) return false; // child still active m_child.reset(); - return true; // child finished + return true; // child finished } /* @@ -221,12 +222,15 @@ static void LaunchShip(Ship *ship) ship->Undock(); } -AICmdKamikaze::AICmdKamikaze(const Json &jsonObj) : AICommand(jsonObj, CMD_KAMIKAZE) { +AICmdKamikaze::AICmdKamikaze(const Json &jsonObj) : + AICommand(jsonObj, CMD_KAMIKAZE) +{ if (!jsonObj.count("index_for_target")) throw SavedGameCorruptException(); m_targetIndex = jsonObj["index_for_target"]; } -void AICmdKamikaze::SaveToJson(Json &jsonObj) { +void AICmdKamikaze::SaveToJson(Json &jsonObj) +{ Space *space = Pi::game->GetSpace(); Json aiCommandObj({}); // Create JSON object to contain ai command data. AICommand::SaveToJson(aiCommandObj); @@ -240,13 +244,17 @@ bool AICmdKamikaze::TimeStepUpdate() if (m_dBody->IsType(Object::SHIP)) { // "Standard" checks for a ship... - Ship *ship = static_cast(m_dBody); - assert(ship!=nullptr); + Ship *ship = static_cast(m_dBody); + assert(ship != nullptr); if (ship->GetFlightState() == Ship::JUMPING) return false; - if (ship->GetFlightState() == Ship::FLYING) ship->SetWheelState(false); - else { LaunchShip(ship); return false; } + if (ship->GetFlightState() == Ship::FLYING) + ship->SetWheelState(false); + else { + LaunchShip(ship); + return false; + } - ship->SetGunState(0,0); + ship->SetGunState(0, 0); } else { // Missile, for now ;-) @@ -260,16 +268,16 @@ bool AICmdKamikaze::TimeStepUpdate() // too much if we miss the target. // Aim to collide at a speed which would take us 4s to reverse. - const double aimCollisionSpeed = m_prop->GetAccelFwd()*2; + const double aimCollisionSpeed = m_prop->GetAccelFwd() * 2; // Aim to use 1/4 of our acceleration for braking while closing // distance, leaving the rest for course adjustment. - const double brake = m_prop->GetAccelFwd()/4; + const double brake = m_prop->GetAccelFwd() / 4; const double aimRelSpeed = - sqrt(aimCollisionSpeed*aimCollisionSpeed + 2*dist*brake); + sqrt(aimCollisionSpeed * aimCollisionSpeed + 2 * dist * brake); - const vector3d aimVel = aimRelSpeed*targetDir + m_target->GetVelocityRelTo(m_dBody->GetFrame()); + const vector3d aimVel = aimRelSpeed * targetDir + m_target->GetVelocityRelTo(m_dBody->GetFrame()); const vector3d accelDir = (aimVel - m_dBody->GetVelocity()).NormalizedSafe(); m_prop->ClearLinThrusterState(); @@ -281,11 +289,14 @@ bool AICmdKamikaze::TimeStepUpdate() return false; } -AICmdKill::AICmdKill(const Json &jsonObj) : AICommand(jsonObj, CMD_KILL) { +AICmdKill::AICmdKill(const Json &jsonObj) : + AICommand(jsonObj, CMD_KILL) +{ m_targetIndex = jsonObj["index_for_target"]; } -void AICmdKill::SaveToJson(Json &jsonObj) { +void AICmdKill::SaveToJson(Json &jsonObj) +{ Space *space = Pi::game->GetSpace(); Json aiCommandObj({}); // Create JSON object to contain ai command data. AICommand::SaveToJson(aiCommandObj); @@ -296,11 +307,15 @@ void AICmdKill::SaveToJson(Json &jsonObj) { bool AICmdKill::TimeStepUpdate() { if (m_dBody->IsType(Object::SHIP)) { - Ship *ship = static_cast(m_dBody); - assert(ship!=nullptr); + Ship *ship = static_cast(m_dBody); + assert(ship != nullptr); if (ship->GetFlightState() == Ship::JUMPING) return false; - if (ship->GetFlightState() == Ship::FLYING) ship->SetWheelState(false); - else { LaunchShip(ship); return false; } + if (ship->GetFlightState() == Ship::FLYING) + ship->SetWheelState(false); + else { + LaunchShip(ship); + return false; + } } else { // Maybe be a drone ;-) return false; @@ -316,96 +331,92 @@ bool AICmdKill::TimeStepUpdate() vector3d heading = -rot.VectorZ(); // Accel will be wrong for a frame on timestep changes, but it doesn't matter vector3d targaccel = (m_target->GetVelocity() - m_lastVel) / Pi::game->GetTimeStep(); - m_lastVel = m_target->GetVelocity(); // may need next frame + m_lastVel = m_target->GetVelocity(); // may need next frame vector3d leaddir = m_prop->AIGetLeadDir(m_target, targaccel, m_fguns->GetProjSpeed(0)); - if (targpos.Length() >= VICINITY_MIN+1000.0) { // if really far from target, intercept -// Output("%s started AUTOPILOT\n", m_ship->GetLabel().c_str()); + if (targpos.Length() >= VICINITY_MIN + 1000.0) { // if really far from target, intercept + // Output("%s started AUTOPILOT\n", m_ship->GetLabel().c_str()); m_child.reset(new AICmdFlyTo(m_dBody, m_target)); - ProcessChild(); return false; + ProcessChild(); + return false; } // turn towards target lead direction, add inaccuracy // trigger recheck when angular velocity reaches zero or after certain time - if (m_leadTime < Pi::game->GetTime()) - { - double skillShoot = 0.5; // todo: should come from AI stats + if (m_leadTime < Pi::game->GetTime()) { + double skillShoot = 0.5; // todo: should come from AI stats double headdiff = (leaddir - heading).Length(); double leaddiff = (leaddir - targdir).Length(); - m_leadTime = Pi::game->GetTime() + headdiff + (1.0*Pi::rng.Double()*skillShoot); + m_leadTime = Pi::game->GetTime() + headdiff + (1.0 * Pi::rng.Double() * skillShoot); // lead inaccuracy based on diff between heading and leaddir - vector3d r(Pi::rng.Double()-0.5, Pi::rng.Double()-0.5, Pi::rng.Double()-0.5); - vector3d newoffset = r * (0.02 + 2.0*leaddiff + 2.0*headdiff)*Pi::rng.Double()*skillShoot; - m_leadOffset = (heading - leaddir); // should be already... + vector3d r(Pi::rng.Double() - 0.5, Pi::rng.Double() - 0.5, Pi::rng.Double() - 0.5); + vector3d newoffset = r * (0.02 + 2.0 * leaddiff + 2.0 * headdiff) * Pi::rng.Double() * skillShoot; + m_leadOffset = (heading - leaddir); // should be already... m_leadDrift = (newoffset - m_leadOffset) / (m_leadTime - Pi::game->GetTime()); // Shoot only when close to target double vissize = 1.3 * m_dBody->GetPhysRadius() / targpos.Length(); - vissize += (0.05 + 0.5*leaddiff)*Pi::rng.Double()*skillShoot; - if (vissize > headdiff) m_fguns->SetGunFiringState(0,1); - else m_fguns->SetGunFiringState(0,0); + vissize += (0.05 + 0.5 * leaddiff) * Pi::rng.Double() * skillShoot; + if (vissize > headdiff) + m_fguns->SetGunFiringState(0, 1); + else + m_fguns->SetGunFiringState(0, 0); float max_fire_dist = m_fguns->GetGunRange(0); if (max_fire_dist > 4000) max_fire_dist = 4000; max_fire_dist *= max_fire_dist; - if (targpos.LengthSqr() > max_fire_dist) m_fguns->SetGunFiringState(0,0); // temp + if (targpos.LengthSqr() > max_fire_dist) m_fguns->SetGunFiringState(0, 0); // temp } m_leadOffset += m_leadDrift * Pi::game->GetTimeStep(); - double leadAV = (leaddir-targdir).Dot((leaddir-heading).NormalizedSafe()); // leaddir angvel + double leadAV = (leaddir - targdir).Dot((leaddir - heading).NormalizedSafe()); // leaddir angvel m_prop->AIFaceDirection((leaddir + m_leadOffset).Normalized(), leadAV); - - vector3d evadethrust(0,0,0); - if (m_evadeTime < Pi::game->GetTime()) // evasion time! + vector3d evadethrust(0, 0, 0); + if (m_evadeTime < Pi::game->GetTime()) // evasion time! { - double skillEvade = 0.5; // todo: should come from AI stats - m_evadeTime = Pi::game->GetTime() + Pi::rng.Double(3.0,10.0) * skillEvade; - if (heading.Dot(targdir) < 0.7) skillEvade += 0.5; // not in view - skillEvade += Pi::rng.Double(-0.5,0.5); + double skillEvade = 0.5; // todo: should come from AI stats + m_evadeTime = Pi::game->GetTime() + Pi::rng.Double(3.0, 10.0) * skillEvade; + if (heading.Dot(targdir) < 0.7) skillEvade += 0.5; // not in view + skillEvade += Pi::rng.Double(-0.5, 0.5); - vector3d targhead = -m_target->GetOrient().VectorZ() * rot; // obj space + vector3d targhead = -m_target->GetOrient().VectorZ() * rot; // obj space vector3d targav = m_target->GetAngVelocity(); - if (skillEvade < 1.6 && targhead.z < 0.0) { // smart chase - vector3d objvel = targvel * rot; // obj space targvel - if ((objvel.x*objvel.x + objvel.y*objvel.y) < 10000) { + if (skillEvade < 1.6 && targhead.z < 0.0) { // smart chase + vector3d objvel = targvel * rot; // obj space targvel + if ((objvel.x * objvel.x + objvel.y * objvel.y) < 10000) { evadethrust.x = objvel.x > 0.0 ? 1.0 : -1.0; evadethrust.y = objvel.y > 0.0 ? 1.0 : -1.0; } - } - else - { - skillEvade += targpos.Length() / 2000; // 0.25 per 500m + } else { + skillEvade += targpos.Length() / 2000; // 0.25 per 500m - if (skillEvade < 1.0 && targav.Length() < 0.05) { // smart evade, assumes facing + if (skillEvade < 1.0 && targav.Length() < 0.05) { // smart evade, assumes facing evadethrust.x = targhead.x < 0.0 ? 1.0 : -1.0; evadethrust.y = targhead.y < 0.0 ? 1.0 : -1.0; - } - else if (skillEvade < 1.3) { // random two-thruster evade - evadethrust.x = (Pi::rng.Int32()&8) ? 1.0 : -1.0; - evadethrust.y = (Pi::rng.Int32()&4) ? 1.0 : -1.0; - } - else if (skillEvade < 1.6) { // one thruster only - if (Pi::rng.Int32()&8) - evadethrust.x = (Pi::rng.Int32()&4) ? 1.0 : -1.0; - else evadethrust.y = (Pi::rng.Int32()&4) ? 1.0 : -1.0; + } else if (skillEvade < 1.3) { // random two-thruster evade + evadethrust.x = (Pi::rng.Int32() & 8) ? 1.0 : -1.0; + evadethrust.y = (Pi::rng.Int32() & 4) ? 1.0 : -1.0; + } else if (skillEvade < 1.6) { // one thruster only + if (Pi::rng.Int32() & 8) + evadethrust.x = (Pi::rng.Int32() & 4) ? 1.0 : -1.0; + else + evadethrust.y = (Pi::rng.Int32() & 4) ? 1.0 : -1.0; } // else no evade thrust } - } - else evadethrust = m_prop->GetLinThrusterState(); - + } else + evadethrust = m_prop->GetLinThrusterState(); // todo: some logic behind desired range? pass from higher level - if (m_closeTime < Pi::game->GetTime()) - { + if (m_closeTime < Pi::game->GetTime()) { double skillEvade = 0.5; - if (heading.Dot(targdir) < 0.7) skillEvade += 0.5; // not in view + if (heading.Dot(targdir) < 0.7) skillEvade += 0.5; // not in view - m_closeTime = Pi::game->GetTime() + skillEvade * Pi::rng.Double(1.0,5.0); + m_closeTime = Pi::game->GetTime() + skillEvade * Pi::rng.Double(1.0, 5.0); double reqdist = 500.0 + skillEvade * Pi::rng.Double(-500.0, 250); double dist = targpos.Length(), ispeed; @@ -413,14 +424,20 @@ bool AICmdKill::TimeStepUpdate() rearaccel += targaccel.Dot(targdir); // v = sqrt(2as), positive => towards double as2 = 2.0 * rearaccel * (dist - reqdist); - if (as2 > 0) ispeed = sqrt(as2); else ispeed = -sqrt(-as2); + if (as2 > 0) + ispeed = sqrt(as2); + else + ispeed = -sqrt(-as2); double vdiff = ispeed + targvel.Dot(targdir); - if (skillEvade + Pi::rng.Double() > 1.5) evadethrust.z = 0.0; - else if (vdiff*vdiff < 400.0) evadethrust.z = 0.0; - else evadethrust.z = (vdiff > 0.0) ? -1.0 : 1.0; - } - else evadethrust.z = m_prop->GetLinThrusterState().z; + if (skillEvade + Pi::rng.Double() > 1.5) + evadethrust.z = 0.0; + else if (vdiff * vdiff < 400.0) + evadethrust.z = 0.0; + else + evadethrust.z = (vdiff > 0.0) ? -1.0 : 1.0; + } else + evadethrust.z = m_prop->GetLinThrusterState().z; m_prop->SetLinThrusterState(evadethrust); return false; @@ -435,7 +452,6 @@ bool AICmdKill::TimeStepUpdate() // ok, can't really decide what's best. // best: evade from heading if low velocity, otherwise evade in direction of angvel - // first need to consider whether danger is sufficiently high to prioritise evasion // back to the threat metrics thing @@ -454,7 +470,6 @@ bool AICmdKill::TimeStepUpdate() // hmm. could consider heading strictly, like watching laser bolts. - // vector3d targld = m_target->AIGetLeadDir(m_ship, vector3d(0,0,0), 0); // (-targpos).Normalized().Dot(targld); // compare against target's actual heading and this ship's current velocity @@ -471,18 +486,12 @@ bool AICmdKill::TimeStepUpdate() // 1. closer range, closing velocity => worth doing a flypast - - - - // need fuzzy range-maintenance // every time period, hit forward or reverse thruster or neither // actually just use real one except only occasionally and with randomised distances // - - /* bool AICmdKill::TimeStepUpdate() { @@ -581,16 +590,18 @@ bool AICmdKill::TimeStepUpdate() static double MaxFeatureRad(Body *body) { - if(!body) return 0.0; - else return body->GetPhysRadius(); + if (!body) + return 0.0; + else + return body->GetPhysRadius(); } static double MaxEffectRad(Body *body, Propulsion *prop) { - if(!body) return 0.0; - if(!body->IsType(Object::TERRAINBODY)) { + if (!body) return 0.0; + if (!body->IsType(Object::TERRAINBODY)) { if (!body->IsType(Object::SPACESTATION)) return body->GetPhysRadius() + 1000.0; - return static_cast(body)->GetStationType()->ParkingDistance() + 1000.0; + return static_cast(body)->GetStationType()->ParkingDistance() + 1000.0; } return std::max(body->GetPhysRadius(), sqrt(G * body->GetMass() / prop->GetAccelUp())); } @@ -615,10 +626,10 @@ static vector3d GetVelInFrame(Frame *frame, Frame *target, const vector3d &offse { vector3d vel = vector3d(0.0); if (target != frame && target->IsRotFrame()) { -// double ang = Pi::game->GetTimeStep() * target->GetAngSpeed(); -// vector3d newpos = offset * matrix3x3d::RotateYMatrix(ang); -// vel = (newpos - offset) / Pi::game->GetTimeStep(); - vel = -target->GetStasisVelocity(offset); // stasis velocity not accurate enough + // double ang = Pi::game->GetTimeStep() * target->GetAngSpeed(); + // vector3d newpos = offset * matrix3x3d::RotateYMatrix(ang); + // vel = (newpos - offset) / Pi::game->GetTimeStep(); + vel = -target->GetStasisVelocity(offset); // stasis velocity not accurate enough } return target->GetOrientRelTo(frame) * vel + target->GetVelocityRelTo(frame); } @@ -632,9 +643,12 @@ static vector3d GenerateTangent(DynamicBody *dBody, Frame *targframe, const vect vector3d spos = dBody->GetPositionRelTo(targframe); vector3d targ = GetPosInFrame(targframe, dBody->GetFrame(), shiptarg); double a = spos.Length(), b = alt; - if (b*1.02 > a) { spos *= b*1.02/a; a = b*1.02; } // fudge if ship gets under radius - double c = sqrt(a*a - b*b); - return (spos*b*b)/(a*a) + spos.Cross(targ).Cross(spos).Normalized()*b*c/a; + if (b * 1.02 > a) { + spos *= b * 1.02 / a; + a = b * 1.02; + } // fudge if ship gets under radius + double c = sqrt(a * a - b * b); + return (spos * b * b) / (a * a) + spos.Cross(targ).Cross(spos).Normalized() * b * c / a; } // check whether ship is at risk of colliding with frame body on current path @@ -648,7 +662,7 @@ static int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pa { if (!dBody->Have(DynamicBody::PROPULSION)) return 0; Propulsion *prop = dBody->GetPropulsion(); - assert(prop!=nullptr); + assert(prop != nullptr); // ship is in obstructor's frame anyway, so is tpos if (pathdist < 100.0) return 0; Body *body = dBody->GetFrame()->GetBody(); @@ -659,38 +673,45 @@ static int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pa // if target inside, check if direct entry is safe (30 degree) if (tlen < r) { - double af = (tlen > fr) ? 0.5 * (1 - (tlen-fr) / (r-fr)) : 0.5; - if (pathdir.Dot(tpos) > -af*tlen) - if (slen < fr) return 1; else return 3; - else return 0; + double af = (tlen > fr) ? 0.5 * (1 - (tlen - fr) / (r - fr)) : 0.5; + if (pathdir.Dot(tpos) > -af * tlen) + if (slen < fr) + return 1; + else + return 3; + else + return 0; } // if ship inside, check for max feature height and direct escape (30 degree) if (slen < r) { if (slen < fr) return 1; - double af = (slen > fr) ? 0.5 * (1 - (slen-fr) / (r-fr)) : 0.5; - if (pathdir.Dot(spos) < af*slen) return 2; else return 0; + double af = (slen > fr) ? 0.5 * (1 - (slen - fr) / (r - fr)) : 0.5; + if (pathdir.Dot(spos) < af * slen) + return 2; + else + return 0; } // now for the intercept calc // find closest point to obstructor double tanlen = -spos.Dot(pathdir); - if (tanlen < 0 || tanlen > pathdist) return 0; // closest point outside path + if (tanlen < 0 || tanlen > pathdist) return 0; // closest point outside path - vector3d perpdir = (tanlen*pathdir + spos).Normalized(); + vector3d perpdir = (tanlen * pathdir + spos).Normalized(); double perpspeed = dBody->GetVelocity().Dot(perpdir); double parspeed = dBody->GetVelocity().Dot(pathdir); - if (parspeed < 0) parspeed = 0; // shouldn't break any important case - if (perpspeed > 0) perpspeed = 0; // prevent attempts to speculatively fly through planets + if (parspeed < 0) parspeed = 0; // shouldn't break any important case + if (perpspeed > 0) perpspeed = 0; // prevent attempts to speculatively fly through planets // find time that dBody will pass through that point // get velocity as if accelerating from start or end, pick smallest - double ivelsqr = endvel*endvel + 2*prop->GetAccelFwd()*(pathdist-tanlen); // could put endvel in here - double fvelsqr = parspeed*parspeed + 2*prop->GetAccelFwd()*tanlen; + double ivelsqr = endvel * endvel + 2 * prop->GetAccelFwd() * (pathdist - tanlen); // could put endvel in here + double fvelsqr = parspeed * parspeed + 2 * prop->GetAccelFwd() * tanlen; double tanspeed = sqrt(ivelsqr < fvelsqr ? ivelsqr : fvelsqr); - double time = tanlen / (0.5 * (parspeed + tanspeed)); // actually correct? + double time = tanlen / (0.5 * (parspeed + tanspeed)); // actually correct? - double dist = spos.Dot(perpdir) + perpspeed*time; // spos.perpdir should be positive + double dist = spos.Dot(perpdir) + perpspeed * time; // spos.perpdir should be positive if (dist < r) return 4; return 0; } @@ -701,29 +722,28 @@ static bool ParentSafetyAdjust(DynamicBody *dBody, Frame *targframe, vector3d &t { Body *body = 0; Frame *frame = targframe->GetNonRotFrame(); - while (frame) - { - if (dBody->GetFrame()->GetNonRotFrame() == frame) break; // ship in frame, stop - if (frame->GetBody()) body = frame->GetBody(); // ignore grav points? + while (frame) { + if (dBody->GetFrame()->GetNonRotFrame() == frame) break; // ship in frame, stop + if (frame->GetBody()) body = frame->GetBody(); // ignore grav points? double sdist = dBody->GetPositionRelTo(frame).Length(); - if (sdist < frame->GetRadius()) break; // ship inside frame, stop + if (sdist < frame->GetRadius()) break; // ship inside frame, stop // we should always be inside the root frame, so if we're not inside 'frame' // then it must not be the root frame (ie, it must have a parent) assert(frame->GetParent()); - frame = frame->GetParent()->GetNonRotFrame(); // check next frame down + frame = frame->GetParent()->GetNonRotFrame(); // check next frame down } if (!body) return false; // aim for zero velocity at surface of that body // still along path to target Propulsion *prop = dBody->GetPropulsion(); - if (prop==nullptr) return false; + if (prop == nullptr) return false; vector3d targpos2 = targpos - dBody->GetPosition(); double targdist = targpos2.Length(); - double bodydist = body->GetPositionRelTo(dBody).Length() - MaxEffectRad(body, prop)*1.5; + double bodydist = body->GetPositionRelTo(dBody).Length() - MaxEffectRad(body, prop) * 1.5; if (targdist < bodydist) return false; targpos -= (targdist - bodydist) * targpos2 / targdist; targvel = body->GetVelocityRelTo(dBody->GetFrame()); @@ -737,35 +757,44 @@ static bool CheckSuicide(DynamicBody *dBody, const vector3d &tandir) Body *body = dBody->GetFrame()->GetBody(); if (dBody->Have(DynamicBody::PROPULSION)) return false; Propulsion *prop = dBody->GetPropulsion(); - assert(prop!=nullptr); + assert(prop != nullptr); if (!body || !body->IsType(Object::TERRAINBODY)) return false; - double vel = dBody->GetVelocity().Dot(tandir); // vel towards is negative + double vel = dBody->GetVelocity().Dot(tandir); // vel towards is negative double dist = dBody->GetPosition().Length() - MaxFeatureRad(body); - if (vel < -1.0 && vel*vel > 2.0*prop->GetAccelMin()*dist) + if (vel < -1.0 && vel * vel > 2.0 * prop->GetAccelMin() * dist) return true; return false; } - extern double calc_ivel(double dist, double vel, double acc); // Fly to vicinity of body -AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Body *target) : AICommand(dBody, CMD_FLYTO) +AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Body *target) : + AICommand(dBody, CMD_FLYTO) { m_prop.Reset(dBody->GetPropulsion()); - assert(m_prop!=nullptr); - m_frame = 0; m_state = -6; m_lockhead = true; m_endvel = 0; m_tangent = false; + assert(m_prop != nullptr); + m_frame = 0; + m_state = -6; + m_lockhead = true; + m_endvel = 0; + m_tangent = false; m_is_flyto = true; - if (!target->IsType(Object::TERRAINBODY)) m_dist = VICINITY_MIN; - else m_dist = VICINITY_MUL*MaxEffectRad(target, m_prop.Get()); + if (!target->IsType(Object::TERRAINBODY)) + m_dist = VICINITY_MIN; + else + m_dist = VICINITY_MUL * MaxEffectRad(target, m_prop.Get()); - if (target->IsType(Object::SPACESTATION) && static_cast(target)->IsGroundStation()) { + if (target->IsType(Object::SPACESTATION) && static_cast(target)->IsGroundStation()) { m_posoff = target->GetPosition() + 15000.0 * target->GetOrient().VectorY(); -// m_posoff += 500.0 * target->GetOrient().VectorX(); - m_targframe = target->GetFrame(); m_target = 0; + // m_posoff += 500.0 * target->GetOrient().VectorX(); + m_targframe = target->GetFrame(); + m_target = 0; + } else { + m_target = target; + m_targframe = 0; } - else { m_target = target; m_targframe = 0; } if (dBody->GetPositionRelTo(target).Length() <= 15000.0) m_targframe = 0; } @@ -783,10 +812,12 @@ AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Frame *targframe, const vector3d &pos m_frame(nullptr) { m_prop.Reset(dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } -AICmdFlyTo::AICmdFlyTo(const Json &jsonObj) : AICommand(jsonObj, CMD_FLYTO) { +AICmdFlyTo::AICmdFlyTo(const Json &jsonObj) : + AICommand(jsonObj, CMD_FLYTO) +{ try { m_targetIndex = jsonObj["index_for_target"]; m_dist = jsonObj["dist"]; @@ -800,8 +831,11 @@ AICmdFlyTo::AICmdFlyTo(const Json &jsonObj) : AICommand(jsonObj, CMD_FLYTO) { } } -void AICmdFlyTo::SaveToJson(Json &jsonObj) { - if (m_child) { m_child.reset(); } +void AICmdFlyTo::SaveToJson(Json &jsonObj) +{ + if (m_child) { + m_child.reset(); + } Json aiCommandObj({}); // Create JSON object to contain ai command data. AICommand::SaveToJson(aiCommandObj); aiCommandObj["index_for_target"] = Pi::game->GetSpace()->GetIndexForBody(m_target); @@ -821,17 +855,21 @@ bool AICmdFlyTo::TimeStepUpdate() * it is better to split them in a module */ if (m_dBody->IsType(Object::SHIP)) { - Ship *ship = static_cast(m_dBody); - assert(ship!=nullptr); + Ship *ship = static_cast(m_dBody); + assert(ship != nullptr); if (ship->GetFlightState() == Ship::JUMPING) return false; // sort out gear, launching - if (ship->GetFlightState() == Ship::FLYING) ship->SetWheelState(false); - else { LaunchShip(ship); return false; } + if (ship->GetFlightState() == Ship::FLYING) + ship->SetWheelState(false); + else { + LaunchShip(ship); + return false; + } } else { // may be an exploration probe ;-) return false; } - if (!m_target && !m_targframe) return true; // deleted object + if (!m_target && !m_targframe) return true; // deleted object // generate base target pos (with vicinity adjustment) & vel double timestep = Pi::game->GetTimeStep(); @@ -852,43 +890,46 @@ bool AICmdFlyTo::TimeStepUpdate() double targdist = relpos.Length(); #ifdef DEBUG_AUTOPILOT -if (m_ship->IsType(Object::PLAYER)) -Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", - targdist, relvel.Length(), m_ship->GetLinThrusterState().z, m_state); + if (m_ship->IsType(Object::PLAYER)) + Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", + targdist, relvel.Length(), m_ship->GetLinThrusterState().z, m_state); #endif // frame switch stuff - clear children/collision state if (m_frame != m_dBody->GetFrame()) { - if (m_child) { m_child.reset(); } - if (m_tangent && m_frame) return true; // regen tangent on frame switch - m_reldir = reldir; // for +vel termination condition + if (m_child) { + m_child.reset(); + } + if (m_tangent && m_frame) return true; // regen tangent on frame switch + m_reldir = reldir; // for +vel termination condition m_frame = m_dBody->GetFrame(); } -// TODO: collision needs to be processed according to vdiff, not reldir? + // TODO: collision needs to be processed according to vdiff, not reldir? Body *body = m_frame->GetBody(); double erad = MaxEffectRad(body, m_prop.Get()); - if ((m_target && body != m_target) - || (m_targframe && (!m_tangent || body != m_targframe->GetBody()))) - { + if ((m_target && body != m_target) || (m_targframe && (!m_tangent || body != m_targframe->GetBody()))) { int coll = CheckCollision(m_dBody, reldir, targdist, targpos, m_endvel, erad); - if (coll == 0) { // no collision - if (m_child) { m_child.reset(); } - } - else if (coll == 1) { // below feature height, target not below + if (coll == 0) { // no collision + if (m_child) { + m_child.reset(); + } + } else if (coll == 1) { // below feature height, target not below double ang = m_prop->AIFaceDirection(m_dBody->GetPosition()); m_prop->AIMatchVel(ang < 0.05 ? 1000.0 * m_dBody->GetPosition().Normalized() : vector3d(0.0)); - } - else { // same thing for 2/3/4 - if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, m_frame->GetBody(), erad*1.05, 0.0)); - static_cast(m_child.get())->SetTargPos(targpos); + } else { // same thing for 2/3/4 + if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, m_frame->GetBody(), erad * 1.05, 0.0)); + static_cast(m_child.get())->SetTargPos(targpos); ProcessChild(); } - if (coll) { m_state = -coll; return false; } + if (coll) { + m_state = -coll; + return false; + } } - if (m_state < 0 && m_state > -6 && m_tangent) return true; // bail out - if (m_state < 0) m_state = targdist > 10000000.0 ? 1 : 0; // still lame + if (m_state < 0 && m_state > -6 && m_tangent) return true; // bail out + if (m_state < 0) m_state = targdist > 10000000.0 ? 1 : 0; // still lame double maxdecel = m_state ? m_prop->GetAccelFwd() : m_prop->GetAccelRev(); double gravdir = -reldir.Dot(m_dBody->GetPosition().Normalized()); @@ -901,7 +942,7 @@ Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", // target ship acceleration adjustment if (m_target && m_target->IsType(Object::SHIP)) { - Ship *targship = static_cast(m_target); + Ship *targship = static_cast(m_target); matrix3x3d orient = m_target->GetFrame()->GetOrientRelTo(m_frame); vector3d targaccel = orient * targship->GetLastForce() / m_target->GetMass(); // fudge: targets accelerating towards you are usually going to flip @@ -909,25 +950,26 @@ Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", relvel += targaccel * timestep; maxdecel += targaccel.Dot(reldir); // if we have margin lower than 10%, fly as if 10% anyway - maxdecel = std::max(maxdecel, 0.1*m_prop->GetAccelFwd()); + maxdecel = std::max(maxdecel, 0.1 * m_prop->GetAccelFwd()); } const double curspeed = -relvel.Dot(reldir); - const double tt = (bZeroDecel) ? timestep : std::max( sqrt(2.0*targdist / maxdecel), timestep ); + const double tt = (bZeroDecel) ? timestep : std::max(sqrt(2.0 * targdist / maxdecel), timestep); const vector3d perpvel = relvel + reldir * curspeed; double perpspeed = perpvel.Length(); - const vector3d perpdir = (perpspeed > 1e-30) ? perpvel / perpspeed : vector3d(0,0,1); + const vector3d perpdir = (perpspeed > 1e-30) ? perpvel / perpspeed : vector3d(0, 0, 1); - double sidefactor = perpspeed / (tt*0.5); - if (curspeed > (tt+timestep)*maxdecel || maxdecel < sidefactor) { + double sidefactor = perpspeed / (tt * 0.5); + if (curspeed > (tt + timestep) * maxdecel || maxdecel < sidefactor) { m_prop->AIFaceDirection(relvel); m_prop->AIMatchVel(targvel); - m_state = -5; return false; - } - else maxdecel = sqrt(maxdecel*maxdecel - sidefactor*sidefactor); + m_state = -5; + return false; + } else + maxdecel = sqrt(maxdecel * maxdecel - sidefactor * sidefactor); // ignore targvel if we could clear with side thrusters in a fraction of minimum time -// if (perpspeed < tt*0.01*m_ship->GetAccelMin()) perpspeed = 0; + // if (perpspeed < tt*0.01*m_ship->GetAccelMin()) perpspeed = 0; // calculate target speed double ispeed = (maxdecel < 1e-10) ? 0.0 : calc_ivel(targdist, m_endvel, maxdecel); @@ -936,37 +978,39 @@ Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", double fuelspeed = m_prop->GetSpeedReachedWithFuel(); if (m_target && m_target->IsType(Object::SHIP)) fuelspeed -= m_dBody->GetVelocityRelTo(Pi::game->GetSpace()->GetRootFrame()).Length(); - if (ispeed > curspeed && curspeed > 0.9*fuelspeed) ispeed = curspeed; + if (ispeed > curspeed && curspeed > 0.9 * fuelspeed) ispeed = curspeed; // Don't exit a frame faster than some fraction of radius -// double maxframespeed = 0.2 * m_frame->GetRadius() / timestep; -// if (m_frame->GetParent() && ispeed > maxframespeed) ispeed = maxframespeed; + // double maxframespeed = 0.2 * m_frame->GetRadius() / timestep; + // if (m_frame->GetParent() && ispeed > maxframespeed) ispeed = maxframespeed; // cap perpspeed according to what's needed now - perpspeed = std::min(perpspeed, 2.0*sidefactor*timestep); + perpspeed = std::min(perpspeed, 2.0 * sidefactor * timestep); // cap sdiff by thrust... double sdiff = ispeed - curspeed; double linaccel = sdiff < 0 ? - std::max(sdiff, -m_prop->GetAccelFwd()*timestep) : - std::min(sdiff, m_prop->GetAccelFwd()*timestep); + std::max(sdiff, -m_prop->GetAccelFwd() * timestep) : + std::min(sdiff, m_prop->GetAccelFwd() * timestep); // linear thrust application, decel check - vector3d vdiff = linaccel*reldir + perpspeed*perpdir; + vector3d vdiff = linaccel * reldir + perpspeed * perpdir; bool decel = sdiff <= 0; // TODO: what is "SetDecelerating"??? => needs to be moved m_dBody->SetDecelerating(decel); - if (decel) m_prop->AIChangeVelBy(vdiff * m_dBody->GetOrient()); - else m_prop->AIChangeVelDir(vdiff * m_dBody->GetOrient()); + if (decel) + m_prop->AIChangeVelBy(vdiff * m_dBody->GetOrient()); + else + m_prop->AIChangeVelDir(vdiff * m_dBody->GetOrient()); // work out which way to head vector3d head = reldir; - if (!m_state && sdiff < -1.2*maxdecel*timestep) m_state = 1; + if (!m_state && sdiff < -1.2 * maxdecel * timestep) m_state = 1; // if we're not coasting due to fuel constraints, and we're in the deceleration phase // then flip the ship so we can use our main thrusters to decelerate - if (m_state && !is_zero_exact(sdiff) && sdiff < maxdecel*timestep*60) head = -head; + if (m_state && !is_zero_exact(sdiff) && sdiff < maxdecel * timestep * 60) head = -head; if (!m_state && decel) sidefactor = -sidefactor; - head = head*maxdecel + perpdir*sidefactor; + head = head * maxdecel + perpdir * sidefactor; // face appropriate direction if (m_state >= 3) { @@ -983,37 +1027,43 @@ Output("Autopilot dist = %.1f, speed = %.1f, zthrust = %.2f, state = %i\n", } m_prop->AIMatchAngVelObjSpace(vector3d(0.0)); return true; - } - else m_prop->AIFaceDirection(head); - if (body && body->IsType(Object::PLANET) && m_dBody->GetPosition().LengthSqr() < 2*erad*erad) - m_prop->AIFaceUpdir(m_dBody->GetPosition()); // turn bottom thruster towards planet + } else + m_prop->AIFaceDirection(head); + if (body && body->IsType(Object::PLANET) && m_dBody->GetPosition().LengthSqr() < 2 * erad * erad) + m_prop->AIFaceUpdir(m_dBody->GetPosition()); // turn bottom thruster towards planet // termination conditions: check - if (m_state >= 3) return true; // finished last adjustment, hopefully - if (m_endvel > 0.0) { if (reldir.Dot(m_reldir) < 0.9) return true; } - else if (targdist < 0.5*m_prop->GetAccelMin()*timestep*timestep) m_state = 3; + if (m_state >= 3) return true; // finished last adjustment, hopefully + if (m_endvel > 0.0) { + if (reldir.Dot(m_reldir) < 0.9) return true; + } else if (targdist < 0.5 * m_prop->GetAccelMin() * timestep * timestep) + m_state = 3; return false; } -AICmdDock::AICmdDock(DynamicBody *dBody, SpaceStation *target) : AICommand(dBody, CMD_DOCK), - m_target(target), m_state(eDockGetDataStart) +AICmdDock::AICmdDock(DynamicBody *dBody, SpaceStation *target) : + AICommand(dBody, CMD_DOCK), + m_target(target), + m_state(eDockGetDataStart) { Ship *ship = nullptr; if (!dBody->IsType(Object::SHIP)) return; - ship = static_cast(dBody); - assert(ship!=nullptr); + ship = static_cast(dBody); + assert(ship != nullptr); m_prop.Reset(ship->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); double grav = GetGravityAtPos(m_target->GetFrame(), m_target->GetPosition()); if (m_prop->GetAccelUp() < grav) { m_dBody->AIMessage(Ship::AIERROR_GRAV_TOO_HIGH); - m_target = 0; // bail out on next timestep call + m_target = 0; // bail out on next timestep call } } -AICmdDock::AICmdDock(const Json &jsonObj) : AICommand(jsonObj, CMD_DOCK) { +AICmdDock::AICmdDock(const Json &jsonObj) : + AICommand(jsonObj, CMD_DOCK) +{ try { m_targetIndex = jsonObj["index_for_target"]; m_dockpos = jsonObj["dock_pos"]; @@ -1025,7 +1075,8 @@ AICmdDock::AICmdDock(const Json &jsonObj) : AICommand(jsonObj, CMD_DOCK) { } } -void AICmdDock::SaveToJson(Json &jsonObj) { +void AICmdDock::SaveToJson(Json &jsonObj) +{ Space *space = Pi::game->GetSpace(); Json aiCommandObj({}); // Create JSON object to contain ai command data. AICommand::SaveToJson(aiCommandObj); @@ -1050,8 +1101,8 @@ bool AICmdDock::TimeStepUpdate() if (!m_target) return true; if (!m_dBody->IsType(Object::SHIP)) return false; - ship = static_cast(m_dBody); - assert(ship!=nullptr); + ship = static_cast(m_dBody); + assert(ship != nullptr); // finished moving into dock start pos (done by child FlyTo command) if (m_state == eDockFlyToStart) IncrementState(); @@ -1080,7 +1131,8 @@ bool AICmdDock::TimeStepUpdate() double targdist = m_target->GetPositionRelTo(ship).Length(); if (targdist > 16000.0) { m_child.reset(new AICmdFlyTo(m_dBody, m_target)); - ProcessChild(); return false; + ProcessChild(); + return false; } int port = m_target->GetMyDockingPort(ship); @@ -1095,19 +1147,16 @@ bool AICmdDock::TimeStepUpdate() } // state 0,2: Get docking data - if (m_state == eDockGetDataStart - || m_state == eDockGetDataEnd - || m_state == eDockingComplete) - { + if (m_state == eDockGetDataStart || m_state == eDockGetDataEnd || m_state == eDockingComplete) { const SpaceStationType *type = m_target->GetStationType(); SpaceStationType::positionOrient_t dockpos; - type->GetShipApproachWaypoints(port, (m_state==0)?1:2, dockpos); + type->GetShipApproachWaypoints(port, (m_state == 0) ? 1 : 2, dockpos); if (m_state != eDockGetDataEnd) { m_dockpos = dockpos.pos; } m_dockdir = dockpos.zaxis.Normalized(); - m_dockupdir = dockpos.yaxis.Normalized(); // don't trust these enough + m_dockupdir = dockpos.yaxis.Normalized(); // don't trust these enough if (type->IsOrbitalStation()) { m_dockupdir = -m_dockupdir; } else if (m_state == eDockingComplete) { @@ -1121,9 +1170,10 @@ bool AICmdDock::TimeStepUpdate() // should have m_dockpos in target frame, dirs relative to target orient } - if (m_state == eDockFlyToStart) { // fly to first docking waypoint + if (m_state == eDockFlyToStart) { // fly to first docking waypoint m_child.reset(new AICmdFlyTo(m_dBody, m_target->GetFrame(), m_dockpos, 0.0, false)); - ProcessChild(); return false; + ProcessChild(); + return false; } // second docking waypoint @@ -1135,7 +1185,7 @@ bool AICmdDock::TimeStepUpdate() const double maxdecel = m_prop->GetAccelUp() - GetGravityAtPos(m_target->GetFrame(), m_dockpos); const double ispeed = calc_ivel(relpos.Length(), 0.0, maxdecel); - const vector3d vdiff = ispeed*reldir - relvel; + const vector3d vdiff = ispeed * reldir - relvel; m_prop->AIChangeVelDir(vdiff * m_dBody->GetOrient()); if (vdiff.Dot(reldir) < 0) { m_dBody->SetDecelerating(true); @@ -1163,8 +1213,8 @@ bool AICmdDock::TimeStepUpdate() } #ifdef DEBUG_AUTOPILOT -Output("AICmdDock dist = %.1f, speed = %.1f, ythrust = %.2f, state = %i\n", - targdist, relvel.Length(), m_ship->GetLinThrusterState().y, m_state); + Output("AICmdDock dist = %.1f, speed = %.1f, ythrust = %.2f, state = %i\n", + targdist, relvel.Length(), m_ship->GetLinThrusterState().y, m_state); #endif return false; @@ -1173,7 +1223,7 @@ Output("AICmdDock dist = %.1f, speed = %.1f, ythrust = %.2f, state = %i\n", bool AICmdHoldPosition::TimeStepUpdate() { // XXX perhaps try harder to move back to the original position - m_prop->AIMatchVel(vector3d(0,0,0)); + m_prop->AIMatchVel(vector3d(0, 0, 0)); return false; } @@ -1181,7 +1231,10 @@ void AICmdFlyAround::Setup(Body *obstructor, double alt, double vel, int mode) { assert(!std::isnan(alt)); assert(!std::isnan(vel)); - m_obstructor = obstructor; m_alt = alt; m_vel = vel; m_targmode = mode; + m_obstructor = obstructor; + m_alt = alt; + m_vel = vel; + m_targmode = mode; // push out of effect radius (gravity safety & station parking zones) alt = std::max(alt, MaxEffectRad(obstructor, m_prop.Get())); @@ -1193,14 +1246,14 @@ void AICmdFlyAround::Setup(Body *obstructor, double alt, double vel, int mode) // generate suitable velocity if none provided double minacc = (mode == 2) ? 0 : m_prop->GetAccelMin(); double mass = obstructor->IsType(Object::TERRAINBODY) ? obstructor->GetMass() : 0; - if (vel < 1e-30) m_vel = sqrt(m_alt*0.8*minacc + mass*G/m_alt); + if (vel < 1e-30) m_vel = sqrt(m_alt * 0.8 * minacc + mass * G / m_alt); } -AICmdFlyAround::AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double relalt, int mode) - : AICommand (dBody, CMD_FLYAROUND) +AICmdFlyAround::AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double relalt, int mode) : + AICommand(dBody, CMD_FLYAROUND) { m_prop.Reset(dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); assert(!std::isnan(relalt)); double alt = relalt * obstructor->GetPhysRadius(); @@ -1208,17 +1261,19 @@ AICmdFlyAround::AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double rela Setup(obstructor, alt, 0.0, mode); } -AICmdFlyAround::AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double alt, double vel, int mode) - : AICommand (dBody, CMD_FLYAROUND) +AICmdFlyAround::AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double alt, double vel, int mode) : + AICommand(dBody, CMD_FLYAROUND) { m_prop.Reset(dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); assert(!std::isnan(alt)); Setup(obstructor, alt, vel, mode); } -AICmdFlyAround::AICmdFlyAround(const Json &jsonObj) : AICommand(jsonObj, CMD_FLYAROUND) { +AICmdFlyAround::AICmdFlyAround(const Json &jsonObj) : + AICommand(jsonObj, CMD_FLYAROUND) +{ try { m_obstructorIndex = jsonObj["index_for_obstructor"]; m_vel = jsonObj["vel"]; @@ -1229,27 +1284,30 @@ AICmdFlyAround::AICmdFlyAround(const Json &jsonObj) : AICommand(jsonObj, CMD_FLY } } -void AICmdFlyAround::SaveToJson(Json &jsonObj) { - if (m_child) { m_child.reset(); } - Json aiCommandObj({}); // Create JSON object to contain ai command data. - AICommand::SaveToJson(aiCommandObj); - aiCommandObj["index_for_obstructor"] = Pi::game->GetSpace()->GetIndexForBody(m_obstructor); - aiCommandObj["vel"] = m_vel; - aiCommandObj["alt"] = m_alt; - aiCommandObj["targ_mode"] = m_targmode; - jsonObj["ai_command"] = aiCommandObj; // Add ai command object to supplied object. +void AICmdFlyAround::SaveToJson(Json &jsonObj) +{ + if (m_child) { + m_child.reset(); + } + Json aiCommandObj({}); // Create JSON object to contain ai command data. + AICommand::SaveToJson(aiCommandObj); + aiCommandObj["index_for_obstructor"] = Pi::game->GetSpace()->GetIndexForBody(m_obstructor); + aiCommandObj["vel"] = m_vel; + aiCommandObj["alt"] = m_alt; + aiCommandObj["targ_mode"] = m_targmode; + jsonObj["ai_command"] = aiCommandObj; // Add ai command object to supplied object. } double AICmdFlyAround::MaxVel(double targdist, double targalt) { Propulsion *prop = m_dBody->GetPropulsion(); - assert(prop!=0); + assert(prop != 0); if (targalt > m_alt) return m_vel; double t = sqrt(2.0 * targdist / prop->GetAccelFwd()); - double vmaxprox = prop->GetAccelMin()*t; // limit by target proximity - double vmaxstep = std::max(m_alt*0.05, m_alt-targalt); - vmaxstep /= Pi::game->GetTimeStep(); // limit by distance covered per timestep + double vmaxprox = prop->GetAccelMin() * t; // limit by target proximity + double vmaxstep = std::max(m_alt * 0.05, m_alt - targalt); + vmaxstep /= Pi::game->GetTimeStep(); // limit by distance covered per timestep return std::min(m_vel, std::min(vmaxprox, vmaxstep)); } @@ -1257,21 +1315,26 @@ bool AICmdFlyAround::TimeStepUpdate() { if (m_dBody->IsType(Object::SHIP)) { Ship *ship = nullptr; - ship = static_cast(m_dBody); - assert(ship!=0); + ship = static_cast(m_dBody); + assert(ship != 0); if (ship->GetFlightState() == Ship::JUMPING) return false; if (!ProcessChild()) return false; // Not necessary unless it's a tier 1 AI - if (ship->GetFlightState() == Ship::FLYING) ship->SetWheelState(false); - else { LaunchShip(ship); return false; } + if (ship->GetFlightState() == Ship::FLYING) + ship->SetWheelState(false); + else { + LaunchShip(ship); + return false; + } - } else;// return false; + } else + ; // return false; double timestep = Pi::game->GetTimeStep(); vector3d targpos = (!m_targmode) ? m_targpos : - m_dBody->GetVelocity().NormalizedSafe()*m_dBody->GetPosition().LengthSqr(); + m_dBody->GetVelocity().NormalizedSafe() * m_dBody->GetPosition().LengthSqr(); vector3d obspos = m_obstructor->GetPositionRelTo(m_dBody); double obsdist = obspos.Length(); vector3d obsdir = obspos / obsdist; @@ -1279,22 +1342,26 @@ bool AICmdFlyAround::TimeStepUpdate() // frame body suicide check, response if (CheckSuicide(m_dBody, -obsdir)) { - m_prop->AIFaceDirection(m_dBody->GetPosition()); // face away from planet - m_prop->AIMatchVel(vector3d(0.0)); return false; + m_prop->AIFaceDirection(m_dBody->GetPosition()); // face away from planet + m_prop->AIMatchVel(vector3d(0.0)); + return false; } // if too far away, fly to tangent - if (obsdist > 1.1*m_alt) - { + if (obsdist > 1.1 * m_alt) { double v; Frame *obsframe = m_obstructor->GetFrame()->GetNonRotFrame(); vector3d tangent = GenerateTangent(m_dBody, obsframe, targpos, m_alt); vector3d tpos_obs = GetPosInFrame(obsframe, m_dBody->GetFrame(), targpos); - if (m_targmode) v = m_vel; - else if (relpos.LengthSqr() < obsdist + tpos_obs.LengthSqr()) v = 0.0; - else v = MaxVel((tpos_obs-tangent).Length(), tpos_obs.Length()); + if (m_targmode) + v = m_vel; + else if (relpos.LengthSqr() < obsdist + tpos_obs.LengthSqr()) + v = 0.0; + else + v = MaxVel((tpos_obs - tangent).Length(), tpos_obs.Length()); m_child.reset(new AICmdFlyTo(m_dBody, obsframe, tangent, v, true)); - ProcessChild(); return false; + ProcessChild(); + return false; } // limit m_vel by target proximity & distance covered per frame @@ -1312,7 +1379,7 @@ bool AICmdFlyAround::TimeStepUpdate() } // calculate target velocity - double alt = (tanvel * timestep + obspos).Length(); // unnecessary? + double alt = (tanvel * timestep + obspos).Length(); // unnecessary? double ivel = calc_ivel(alt - m_alt, 0.0, m_prop->GetAccelMin()); vector3d finalvel = tanvel + ivel * obsdir; @@ -1320,14 +1387,17 @@ bool AICmdFlyAround::TimeStepUpdate() m_prop->AIFaceDirection(fwddir); m_prop->AIFaceUpdir(-obsdir); -// vector3d newhead = GenerateTangent(m_ship, m_obstructor->GetFrame(), fwddir); -// newhead = GetPosInFrame(m_ship->GetFrame(), m_obstructor->GetFrame(), newhead); -// m_ship->AIFaceDirection(newhead-m_ship->GetPosition()); + // vector3d newhead = GenerateTangent(m_ship, m_obstructor->GetFrame(), fwddir); + // newhead = GetPosInFrame(m_ship->GetFrame(), m_obstructor->GetFrame(), newhead); + // m_ship->AIFaceDirection(newhead-m_ship->GetPosition()); // termination condition for orbits vector3d thrust = m_prop->GetLinThrusterState(); if (m_targmode >= 2 && thrust.LengthSqr() < 0.01) m_targmode++; - if (m_targmode == 4) { m_prop->SetLinThrusterState(vector3d(0.0)); return true; } + if (m_targmode == 4) { + m_prop->SetLinThrusterState(vector3d(0.0)); + return true; + } return false; } @@ -1337,10 +1407,12 @@ AICmdFormation::AICmdFormation(DynamicBody *dBody, DynamicBody *target, const ve m_posoff(posoff) { m_prop.Reset(dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } -AICmdFormation::AICmdFormation(const Json &jsonObj) : AICommand(jsonObj, CMD_FORMATION) { +AICmdFormation::AICmdFormation(const Json &jsonObj) : + AICommand(jsonObj, CMD_FORMATION) +{ try { m_targetIndex = jsonObj["index_for_target"]; m_posoff = jsonObj["pos_off"]; @@ -1349,8 +1421,11 @@ AICmdFormation::AICmdFormation(const Json &jsonObj) : AICommand(jsonObj, CMD_FOR } } -void AICmdFormation::SaveToJson(Json &jsonObj) { - if (m_child) { m_child.reset(); } +void AICmdFormation::SaveToJson(Json &jsonObj) +{ + if (m_child) { + m_child.reset(); + } Json aiCommandObj({}); // Create JSON object to contain ai command data. AICommand::SaveToJson(aiCommandObj); aiCommandObj["index_for_target"] = Pi::game->GetSpace()->GetIndexForBody(m_target); @@ -1361,29 +1436,33 @@ void AICmdFormation::SaveToJson(Json &jsonObj) { bool AICmdFormation::TimeStepUpdate() { if (m_dBody->IsType(Object::SHIP)) { - Ship *ship = static_cast(m_dBody); - assert(ship!=0); + Ship *ship = static_cast(m_dBody); + assert(ship != 0); if (ship->GetFlightState() == Ship::JUMPING) return false; - if (ship->GetFlightState() == Ship::FLYING) ship->SetWheelState(false); - else { LaunchShip(ship); return false; } + if (ship->GetFlightState() == Ship::FLYING) + ship->SetWheelState(false); + else { + LaunchShip(ship); + return false; + } } if (!m_target) return true; - if (!ProcessChild()) return false; // In case we're doing an intercept - + if (!ProcessChild()) return false; // In case we're doing an intercept // if too far away, do an intercept first // TODO: adjust distance cap by timestep so we don't bounce? if (m_target->GetPositionRelTo(m_dBody).Length() > 30000.0) { m_child.reset(new AICmdFlyTo(m_dBody, m_target)); - ProcessChild(); return false; + ProcessChild(); + return false; } matrix3x3d torient = m_target->GetOrientRelTo(m_dBody->GetFrame()); vector3d relpos = m_target->GetPositionRelTo(m_dBody) + torient * m_posoff; vector3d relvel = -m_target->GetVelocityRelTo(m_dBody); double targdist = relpos.Length(); - vector3d reldir = (targdist < 1e-16) ? vector3d(1,0,0) : relpos/targdist; + vector3d reldir = (targdist < 1e-16) ? vector3d(1, 0, 0) : relpos / targdist; // adjust for target acceleration matrix3x3d forient = m_target->GetFrame()->GetOrientRelTo(m_dBody->GetFrame()); @@ -1394,15 +1473,15 @@ bool AICmdFormation::TimeStepUpdate() // linear thrust double ispeed = calc_ivel(targdist, 0.0, maxdecel); - vector3d vdiff = ispeed*reldir - relvel; + vector3d vdiff = ispeed * reldir - relvel; m_prop->AIChangeVelDir(vdiff * m_dBody->GetOrient()); if (m_target->IsType(Object::SHIP)) { - Ship *target_ship = static_cast(m_target); + Ship *target_ship = static_cast(m_target); if (target_ship->IsDecelerating()) m_dBody->SetDecelerating(true); } else { m_dBody->SetDecelerating(false); } m_prop->AIFaceDirection(-torient.VectorZ()); - return false; // never self-terminates + return false; // never self-terminates } diff --git a/src/ShipAICmd.h b/src/ShipAICmd.h index e33c17a01..e9a1d96be 100644 --- a/src/ShipAICmd.h +++ b/src/ShipAICmd.h @@ -4,12 +4,12 @@ #ifndef _SHIPAICMD_H #define _SHIPAICMD_H +#include "Game.h" +#include "GameSaveError.h" +#include "JsonFwd.h" +#include "Pi.h" #include "Ship.h" #include "SpaceStation.h" -#include "Pi.h" -#include "Game.h" -#include "JsonFwd.h" -#include "GameSaveError.h" #include "libs.h" class AICommand { @@ -26,17 +26,22 @@ public: CMD_FORMATION }; - AICommand(DynamicBody *dBody, CmdName name): - m_dBody(dBody), m_cmdName(name) { + AICommand(DynamicBody *dBody, CmdName name) : + m_dBody(dBody), + m_cmdName(name) + { m_dBody->AIMessage(DynamicBody::AIERROR_NONE); } virtual ~AICommand() {} virtual bool TimeStepUpdate() = 0; - bool ProcessChild(); // returns false if child is active - virtual void GetStatusText(char *str) { - if (m_child) m_child->GetStatusText(str); - else strcpy(str, "AI state unknown"); + bool ProcessChild(); // returns false if child is active + virtual void GetStatusText(char *str) + { + if (m_child) + m_child->GetStatusText(str); + else + strcpy(str, "AI state unknown"); } // Serialisation functions @@ -46,9 +51,13 @@ public: virtual void PostLoadFixup(Space *space); // Signal functions - virtual void OnDeleted(const Body *body) { if (m_child) m_child->OnDeleted(body); } + virtual void OnDeleted(const Body *body) + { + if (m_child) m_child->OnDeleted(body); + } CmdName GetType() const { return m_cmdName; } + protected: DynamicBody *m_dBody; RefCountedPtr m_prop; @@ -66,48 +75,55 @@ public: virtual bool TimeStepUpdate(); AICmdDock(DynamicBody *dBody, SpaceStation *target); - virtual void GetStatusText(char *str) { - if (m_child) m_child->GetStatusText(str); - else snprintf(str, 255, "Dock: target %s, state %i", m_target->GetLabel().c_str(), m_state); + virtual void GetStatusText(char *str) + { + if (m_child) + m_child->GetStatusText(str); + else + snprintf(str, 255, "Dock: target %s, state %i", m_target->GetLabel().c_str(), m_state); } virtual void SaveToJson(Json &jsonObj); AICmdDock(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); m_target = static_cast(space->GetBodyByIndex(m_targetIndex)); // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { AICommand::OnDeleted(body); if (static_cast(m_target) == body) m_target = 0; } + private: enum EDockingStates { - eDockGetDataStart = 0, // 0: get data for docking start pos - eDockFlyToStart = 1, // 1: Fly to docking start pos - eDockGetDataEnd = 2, // 2: get data for docking end pos - eDockFlyToEnd = 3, // 3: Fly to docking end pos + eDockGetDataStart = 0, // 0: get data for docking start pos + eDockFlyToStart = 1, // 1: Fly to docking start pos + eDockGetDataEnd = 2, // 2: get data for docking end pos + eDockFlyToEnd = 3, // 3: Fly to docking end pos eDockingComplete = 4, eInvalidDockingStage = 5 }; SpaceStation *m_target; - vector3d m_dockpos; // offset in target's frame + vector3d m_dockpos; // offset in target's frame vector3d m_dockdir; vector3d m_dockupdir; - EDockingStates m_state; // see TimeStepUpdate() - int m_targetIndex; // used during deserialisation + EDockingStates m_state; // see TimeStepUpdate() + int m_targetIndex; // used during deserialisation - void IncrementState() { - switch(m_state) { - case eDockGetDataStart: m_state = eDockFlyToStart; break; - case eDockFlyToStart: m_state = eDockGetDataEnd; break; - case eDockGetDataEnd: m_state = eDockFlyToEnd; break; - case eDockFlyToEnd: m_state = eDockingComplete; break; - case eDockingComplete: m_state = eInvalidDockingStage; break; - case eInvalidDockingStage: break; + void IncrementState() + { + switch (m_state) { + case eDockGetDataStart: m_state = eDockFlyToStart; break; + case eDockFlyToStart: m_state = eDockGetDataEnd; break; + case eDockGetDataEnd: m_state = eDockFlyToEnd; break; + case eDockFlyToEnd: m_state = eDockingComplete; break; + case eDockingComplete: m_state = eInvalidDockingStage; break; + case eInvalidDockingStage: break; } } }; @@ -118,104 +134,123 @@ public: AICmdFlyTo(DynamicBody *dBody, Frame *targframe, const vector3d &posoff, double endvel, bool tangent); AICmdFlyTo(DynamicBody *dBody, Body *target); - virtual void GetStatusText(char *str) { - if (m_child) m_child->GetStatusText(str); - else if (m_target) snprintf(str, 255, "Intercept: %s, dist %.1fkm, state %i", - m_target->GetLabel().c_str(), m_dist, m_state); - else snprintf(str, 255, "FlyTo: %s, dist %.1fkm, endvel %.1fkm/s, state %i", - m_targframe->GetLabel().c_str(), m_posoff.Length()/1000.0, m_endvel/1000.0, m_state); + virtual void GetStatusText(char *str) + { + if (m_child) + m_child->GetStatusText(str); + else if (m_target) + snprintf(str, 255, "Intercept: %s, dist %.1fkm, state %i", + m_target->GetLabel().c_str(), m_dist, m_state); + else + snprintf(str, 255, "FlyTo: %s, dist %.1fkm, endvel %.1fkm/s, state %i", + m_targframe->GetLabel().c_str(), m_posoff.Length() / 1000.0, m_endvel / 1000.0, m_state); } virtual void SaveToJson(Json &jsonObj); AICmdFlyTo(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); m_target = space->GetBodyByIndex(m_targetIndex); m_targframe = space->GetFrameByIndex(m_targframeIndex); m_lockhead = true; // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { AICommand::OnDeleted(body); if (m_target == body) m_target = 0; } private: - Body *m_target; // target for vicinity. Either this or targframe is 0 - double m_dist; // vicinity distance - Frame *m_targframe; // target frame for waypoint - vector3d m_posoff; // offset in target frame - double m_endvel; // target speed in direction of motion at end of path, positive only - bool m_tangent; // true if path is to a tangent of the target frame's body + Body *m_target; // target for vicinity. Either this or targframe is 0 + double m_dist; // vicinity distance + Frame *m_targframe; // target frame for waypoint + vector3d m_posoff; // offset in target frame + double m_endvel; // target speed in direction of motion at end of path, positive only + bool m_tangent; // true if path is to a tangent of the target frame's body int m_state; bool m_lockhead; - int m_targetIndex, m_targframeIndex; // used during deserialisation - vector3d m_reldir; // target direction relative to ship at last frame change - Frame *m_frame; // last frame of ship + int m_targetIndex, m_targframeIndex; // used during deserialisation + vector3d m_reldir; // target direction relative to ship at last frame change + Frame *m_frame; // last frame of ship }; class AICmdFlyAround : public AICommand { public: virtual bool TimeStepUpdate(); - AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double relalt, int mode=2); - AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double alt, double vel, int mode=1); + AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double relalt, int mode = 2); + AICmdFlyAround(DynamicBody *dBody, Body *obstructor, double alt, double vel, int mode = 1); - virtual void GetStatusText(char *str) { - if (m_child) m_child->GetStatusText(str); - else snprintf(str, 255, "FlyAround: alt %.1fkm, vel %.1fkm/s, mode %i", - m_alt/1000.0, m_vel/1000.0, m_targmode); + virtual void GetStatusText(char *str) + { + if (m_child) + m_child->GetStatusText(str); + else + snprintf(str, 255, "FlyAround: alt %.1fkm, vel %.1fkm/s, mode %i", + m_alt / 1000.0, m_vel / 1000.0, m_targmode); } virtual void SaveToJson(Json &jsonObj); AICmdFlyAround(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); m_obstructor = space->GetBodyByIndex(m_obstructorIndex); // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { AICommand::OnDeleted(body); // check against obstructor? } - void SetTargPos(const vector3d &targpos) { m_targpos = targpos; m_targmode = 0; } + void SetTargPos(const vector3d &targpos) + { + m_targpos = targpos; + m_targmode = 0; + } protected: void Setup(Body *obstructor, double alt, double vel, int mode); double MaxVel(double targdist, double targalt); private: - Body *m_obstructor; // body to fly around - int m_obstructorIndex; // deserialisation + Body *m_obstructor; // body to fly around + int m_obstructorIndex; // deserialisation double m_alt, m_vel; - int m_targmode; // 0 targpos termination, 1 infinite, 2+ orbital termination - vector3d m_targpos; // target position in ship space + int m_targmode; // 0 targpos termination, 1 infinite, 2+ orbital termination + vector3d m_targpos; // target position in ship space }; class AICmdKill : public AICommand { public: virtual bool TimeStepUpdate(); - AICmdKill(DynamicBody *dBody, Ship *target) : AICommand (dBody, CMD_KILL) { + AICmdKill(DynamicBody *dBody, Ship *target) : + AICommand(dBody, CMD_KILL) + { m_target = target; m_leadTime = m_evadeTime = m_closeTime = 0.0; m_lastVel = m_target->GetVelocity(); m_prop.Reset(m_dBody->GetPropulsion()); m_fguns.Reset(m_dBody->GetFixedGuns()); - assert(m_prop!=nullptr); - assert(m_fguns!=nullptr); + assert(m_prop != nullptr); + assert(m_fguns != nullptr); } - ~AICmdKill() { - if(m_fguns) m_fguns->SetGunFiringState(0,0); + ~AICmdKill() + { + if (m_fguns) m_fguns->SetGunFiringState(0, 0); } // don't actually need to save all this crap virtual void SaveToJson(Json &jsonObj); AICmdKill(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); m_target = static_cast(space->GetBodyByIndex(m_targetIndex)); m_leadTime = m_evadeTime = m_closeTime = 0.0; @@ -223,11 +258,12 @@ public: // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); m_fguns.Reset(m_dBody->GetFixedGuns()); - assert(m_prop!=nullptr); - assert(m_fguns!=nullptr); + assert(m_prop != nullptr); + assert(m_fguns != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { if (static_cast(m_target) == body) m_target = 0; AICommand::OnDeleted(body); } @@ -236,49 +272,57 @@ private: Ship *m_target; double m_leadTime, m_evadeTime, m_closeTime; vector3d m_leadOffset, m_leadDrift, m_lastVel; - int m_targetIndex; // used during deserialisation + int m_targetIndex; // used during deserialisation }; class AICmdKamikaze : public AICommand { public: virtual bool TimeStepUpdate(); - AICmdKamikaze(DynamicBody *dBody, Body *target) : AICommand(dBody, CMD_KAMIKAZE) { + AICmdKamikaze(DynamicBody *dBody, Body *target) : + AICommand(dBody, CMD_KAMIKAZE) + { m_target = target; m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } virtual void SaveToJson(Json &jsonObj); AICmdKamikaze(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); m_target = space->GetBodyByIndex(m_targetIndex); // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { if (static_cast(m_target) == body) m_target = 0; AICommand::OnDeleted(body); } private: Body *m_target; - int m_targetIndex; // used during deserialisation + int m_targetIndex; // used during deserialisation }; class AICmdHoldPosition : public AICommand { public: virtual bool TimeStepUpdate(); - AICmdHoldPosition(DynamicBody *dBody) : AICommand(dBody, CMD_HOLDPOSITION) { + AICmdHoldPosition(DynamicBody *dBody) : + AICommand(dBody, CMD_HOLDPOSITION) + { m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - AICmdHoldPosition(const Json &jsonObj) : AICommand(jsonObj, CMD_HOLDPOSITION) { + AICmdHoldPosition(const Json &jsonObj) : + AICommand(jsonObj, CMD_HOLDPOSITION) + { // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } }; @@ -287,30 +331,35 @@ public: virtual bool TimeStepUpdate(); AICmdFormation(DynamicBody *dBody, DynamicBody *target, const vector3d &posoff); - virtual void GetStatusText(char *str) { - if (m_child) m_child->GetStatusText(str); - else snprintf(str, 255, "Formation: %s, dist %.1fkm", - m_target->GetLabel().c_str(), m_posoff.Length()/1000.0); + virtual void GetStatusText(char *str) + { + if (m_child) + m_child->GetStatusText(str); + else + snprintf(str, 255, "Formation: %s, dist %.1fkm", + m_target->GetLabel().c_str(), m_posoff.Length() / 1000.0); } virtual void SaveToJson(Json &jsonObj); AICmdFormation(const Json &jsonObj); - virtual void PostLoadFixup(Space *space) { + virtual void PostLoadFixup(Space *space) + { AICommand::PostLoadFixup(space); - m_target = static_cast(space->GetBodyByIndex(m_targetIndex)); + m_target = static_cast(space->GetBodyByIndex(m_targetIndex)); // Ensure needed sub-system: m_prop.Reset(m_dBody->GetPropulsion()); - assert(m_prop!=nullptr); + assert(m_prop != nullptr); } - virtual void OnDeleted(const Body *body) { + virtual void OnDeleted(const Body *body) + { if (static_cast(m_target) == body) m_target = 0; AICommand::OnDeleted(body); } private: - DynamicBody *m_target; // target frame for waypoint - vector3d m_posoff; // offset in target frame + DynamicBody *m_target; // target frame for waypoint + vector3d m_posoff; // offset in target frame - int m_targetIndex; // used during deserialisation + int m_targetIndex; // used during deserialisation }; #endif /* _SHIPAICMD_H */ diff --git a/src/ShipCockpit.cpp b/src/ShipCockpit.cpp index fa89d2d8c..37a1c2fdb 100644 --- a/src/ShipCockpit.cpp +++ b/src/ShipCockpit.cpp @@ -2,12 +2,12 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ShipCockpit.h" -#include "ShipType.h" +#include "CameraController.h" +#include "Easing.h" +#include "Game.h" #include "Pi.h" #include "Player.h" -#include "Easing.h" -#include "CameraController.h" -#include "Game.h" +#include "ShipType.h" #include "WorldView.h" ShipCockpit::ShipCockpit(const std::string &modelName) : @@ -32,7 +32,6 @@ ShipCockpit::ShipCockpit(const std::string &modelName) : ShipCockpit::~ShipCockpit() { - } void ShipCockpit::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) @@ -41,8 +40,9 @@ void ShipCockpit::Render(Graphics::Renderer *renderer, const Camera *camera, con RenderModel(renderer, camera, viewCoords, viewTransform); } -inline void ShipCockpit::resetInternalCameraController() { - m_icc = static_cast(Pi::game->GetWorldView()->GetCameraController()); +inline void ShipCockpit::resetInternalCameraController() +{ + m_icc = static_cast(Pi::game->GetWorldView()->GetCameraController()); } void ShipCockpit::Update(const Player *player, float timeStep) @@ -69,7 +69,7 @@ void ShipCockpit::Update(const Player *player, float timeStep) //---------------------------------------- Acceleration float cur_vel = CalculateSignedForwardVelocity(-cur_dir, player->GetVelocity()); // Forward is -Z float gforce = Clamp(floorf(((fabs(cur_vel) - m_shipVel) / timeStep) / 9.8f), -COCKPIT_MAX_GFORCE, COCKPIT_MAX_GFORCE); - if (fabs(cur_vel) > 500000.0f || // Limit gforce measurement so we don't get astronomical fluctuations + if (fabs(cur_vel) > 500000.0f || // Limit gforce measurement so we don't get astronomical fluctuations fabs(gforce - m_gForce) > 100.0) { // Smooth out gforce one frame spikes, sometimes happens when hitting max speed due to the thrust limiters gforce = 0.0f; } @@ -180,7 +180,7 @@ void ShipCockpit::Update(const Player *player, float timeStep) } } -void ShipCockpit::RenderCockpit(Graphics::Renderer* renderer, const Camera* camera, Frame* frame) +void ShipCockpit::RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, Frame *frame) { PROFILE_SCOPED() renderer->ClearDepthBuffer(); @@ -199,7 +199,8 @@ void ShipCockpit::OnActivated(const Player *player) m_shipVel = CalculateSignedForwardVelocity(-m_shipDir, player->GetVelocity()); } -float ShipCockpit::CalculateSignedForwardVelocity(const vector3d &normalized_forward, const vector3d &velocity) { +float ShipCockpit::CalculateSignedForwardVelocity(const vector3d &normalized_forward, const vector3d &velocity) +{ float velz_cos = velocity.Dot(normalized_forward); return (velz_cos * normalized_forward).Length() * (velz_cos < 0.0 ? -1.0 : 1.0); } diff --git a/src/ShipCockpit.h b/src/ShipCockpit.h index d85e46ee7..706019ad9 100644 --- a/src/ShipCockpit.h +++ b/src/ShipCockpit.h @@ -4,11 +4,11 @@ #ifndef _SHIP_COCKPIT_H_ #define _SHIP_COCKPIT_H_ -#include "libs.h" -#include "ModelBody.h" -#include "scenegraph/Model.h" #include "CameraController.h" +#include "ModelBody.h" #include "WorldView.h" +#include "libs.h" +#include "scenegraph/Model.h" static const float COCKPIT_LAG_MAX_ANGLE = 7.5f; static const float COCKPIT_ROTATION_INTERP_MULTIPLIER = 5.0f; @@ -18,8 +18,7 @@ static const float COCKPIT_ACCEL_OFFSET = 0.075f; class Player; -class ShipCockpit : public ModelBody -{ +class ShipCockpit : public ModelBody { public: explicit ShipCockpit(const std::string &modelName); virtual ~ShipCockpit(); @@ -27,7 +26,7 @@ public: virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; void Update(const Player *player, float timeStep); - void RenderCockpit(Graphics::Renderer* renderer, const Camera* camera, Frame* frame); + void RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, Frame *frame); void OnActivated(const Player *player); void resetInternalCameraController(void); @@ -35,20 +34,20 @@ protected: float CalculateSignedForwardVelocity(const vector3d &forward, const vector3d &velocity); private: - ShipCockpit(const ShipCockpit&) = delete; - ShipCockpit& operator=(const ShipCockpit&) = delete; + ShipCockpit(const ShipCockpit &) = delete; + ShipCockpit &operator=(const ShipCockpit &) = delete; - vector3d m_shipDir; // current ship direction - vector3d m_shipYaw; // current ship yaw vector - vector3d m_dir; // cockpit direction - vector3d m_yaw; // cockpit yaw vector - float m_rotInterp; // for rotation interpolation - float m_transInterp; // for translation interpolation - float m_gForce; // current ship gforce - float m_offset; // current ship offset due to acceleration effect - float m_shipVel; // current ship velocity - vector3d m_translate; // cockpit translation - matrix4x4d m_transform; // cockpit transformation - InternalCameraController* m_icc; + vector3d m_shipDir; // current ship direction + vector3d m_shipYaw; // current ship yaw vector + vector3d m_dir; // cockpit direction + vector3d m_yaw; // cockpit yaw vector + float m_rotInterp; // for rotation interpolation + float m_transInterp; // for translation interpolation + float m_gForce; // current ship gforce + float m_offset; // current ship offset due to acceleration effect + float m_shipVel; // current ship velocity + vector3d m_translate; // cockpit translation + matrix4x4d m_transform; // cockpit transformation + InternalCameraController *m_icc; }; #endif diff --git a/src/ShipController.cpp b/src/ShipController.cpp index ef8c737a7..b1d4f5d6f 100644 --- a/src/ShipController.cpp +++ b/src/ShipController.cpp @@ -4,14 +4,14 @@ #include "ShipController.h" #include "Frame.h" #include "Game.h" +#include "GameSaveError.h" #include "KeyBindings.h" +#include "OS.h" #include "Pi.h" #include "Player.h" #include "Ship.h" #include "Space.h" #include "WorldView.h" -#include "OS.h" -#include "GameSaveError.h" void ShipController::StaticUpdate(float timeStep) { @@ -44,15 +44,14 @@ PlayerShipController::PlayerShipController() : if (!InputBindings.primaryFire) { Error("PlayerShipController was not properly initialized!\n" - "You must call PlayerShipController::RegisterInputBindings before initializing a PlayerShipController"); + "You must call PlayerShipController::RegisterInputBindings before initializing a PlayerShipController"); } m_connRotationDampingToggleKey = InputBindings.toggleRotationDamping->onPress.connect( sigc::mem_fun(this, &PlayerShipController::ToggleRotationDamping)); m_fireMissileKey = InputBindings.secondaryFire->onPress.connect( - sigc::mem_fun(this, &PlayerShipController::FireMissile)); - + sigc::mem_fun(this, &PlayerShipController::FireMissile)); } PlayerShipController::InputBinding PlayerShipController::InputBindings; @@ -138,18 +137,18 @@ void PlayerShipController::StaticUpdate(const float timeStep) matrix4x4d m; int mouseMotion[2]; - SDL_GetRelativeMouseState (mouseMotion+0, mouseMotion+1); // call to flush + SDL_GetRelativeMouseState(mouseMotion + 0, mouseMotion + 1); // call to flush // external camera mouselook if (Pi::input.MouseButtonState(SDL_BUTTON_MIDDLE)) { - MoveableCameraController *mcc = static_cast(Pi::game->GetWorldView()->GetCameraController()); - const double accel = 0.01; // XXX configurable? - mcc->RotateLeft(mouseMotion[0] * accel); - mcc->RotateUp( mouseMotion[1] * accel); - // only mouselook if the player presses both mmb and rmb - mouseMotion[0] = 0; - mouseMotion[1] = 0; - } + MoveableCameraController *mcc = static_cast(Pi::game->GetWorldView()->GetCameraController()); + const double accel = 0.01; // XXX configurable? + mcc->RotateLeft(mouseMotion[0] * accel); + mcc->RotateUp(mouseMotion[1] * accel); + // only mouselook if the player presses both mmb and rmb + mouseMotion[0] = 0; + mouseMotion[1] = 0; + } if (m_ship->GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { @@ -196,17 +195,19 @@ void PlayerShipController::StaticUpdate(const float timeStep) case CONTROL_AUTOPILOT: if (m_ship->AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); -// AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... - // actually this breaks last timestep slightly in non-relative target cases + // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... + // actually this breaks last timestep slightly in non-relative target cases m_ship->AIMatchAngVelObjSpace(vector3d(0.0)); - if (m_ship->GetFrame()->IsRotFrame()) SetFlightControlState(CONTROL_FIXSPEED); - else SetFlightControlState(CONTROL_MANUAL); + if (m_ship->GetFrame()->IsRotFrame()) + SetFlightControlState(CONTROL_FIXSPEED); + else + SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; default: assert(0); break; } - } - else SetFlightControlState(CONTROL_MANUAL); + } else + SetFlightControlState(CONTROL_MANUAL); //call autopilot AI, if active (also applies to set speed and heading lock modes) OS::EnableFPE(); @@ -216,11 +217,7 @@ void PlayerShipController::StaticUpdate(const float timeStep) void PlayerShipController::CheckControlsLock() { - m_controlsLocked = (Pi::game->IsPaused()) - || Pi::player->IsDead() - || (m_ship->GetFlightState() != Ship::FLYING) - || Pi::IsConsoleActive() - || (Pi::GetView() != Pi::game->GetWorldView()); //to prevent moving the ship in starmap etc. + m_controlsLocked = (Pi::game->IsPaused()) || Pi::player->IsDead() || (m_ship->GetFlightState() != Ship::FLYING) || Pi::IsConsoleActive() || (Pi::GetView() != Pi::game->GetWorldView()); //to prevent moving the ship in starmap etc. } vector3d PlayerShipController::GetMouseDir() const @@ -232,7 +229,7 @@ vector3d PlayerShipController::GetMouseDir() const // mouse wraparound control function static double clipmouse(double cur, double inp) { - if (cur*cur > 0.7 && cur*inp > 0) return 0.0; + if (cur * cur > 0.7 && cur * inp > 0) return 0.0; if (inp > 0.2) return 0.2; if (inp < -0.2) return -0.2; return inp; @@ -247,8 +244,8 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r // if flying { m_ship->ClearThrusterState(); - m_ship->SetGunState(0,0); - m_ship->SetGunState(1,0); + m_ship->SetGunState(0, 0); + m_ship->SetGunState(1, 0); // vector3d wantAngVel(0.0); double angThrustSoftness = 10.0; @@ -256,8 +253,7 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r const float linearThrustPower = (InputBindings.thrustLowPower->IsActive() ? m_lowThrustPower : 1.0f); // have to use this function. SDL mouse position event is bugged in windows - if (Pi::input.MouseButtonState(SDL_BUTTON_RIGHT)) - { + if (Pi::input.MouseButtonState(SDL_BUTTON_RIGHT)) { // use ship rotation relative to system, unchanged by frame transitions matrix3x3d rot = m_ship->GetOrientRelTo(m_ship->GetFrame()->GetNonRotFrame()); if (!m_mouseActive && !m_disableMouseFacing) { @@ -281,12 +277,12 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r double mody = clipmouse(objDir.y, m_mouseY); m_mouseY -= mody; - if(!is_zero_general(modx) || !is_zero_general(mody)) { + if (!is_zero_general(modx) || !is_zero_general(mody)) { matrix3x3d mrot = matrix3x3d::RotateY(modx) * matrix3x3d::RotateX(mody); m_mouseDir = (rot * (mrot * objDir)).Normalized(); } - } - else m_mouseActive = false; + } else + m_mouseActive = false; if (m_flightControlState == CONTROL_FIXSPEED) { double oldSpeed = m_setSpeed; @@ -298,15 +294,15 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r if (!stickySpeedKey) { if (InputBindings.increaseSpeed->IsActive()) { - m_setSpeed += std::max(fabs(m_setSpeed)*0.05, 1.0); - if ( m_setSpeed > 300000000 ) m_setSpeed = 300000000; + m_setSpeed += std::max(fabs(m_setSpeed) * 0.05, 1.0); + if (m_setSpeed > 300000000) m_setSpeed = 300000000; } if (InputBindings.decreaseSpeed->IsActive()) { - m_setSpeed -= std::max(fabs(m_setSpeed)*0.05, 1.0); - if ( m_setSpeed < -300000000 ) m_setSpeed = -300000000; + m_setSpeed -= std::max(fabs(m_setSpeed) * 0.05, 1.0); + if (m_setSpeed < -300000000) m_setSpeed = -300000000; } - if ( ((oldSpeed < 0.0) && (m_setSpeed >= 0.0)) || - ((oldSpeed > 0.0) && (m_setSpeed <= 0.0)) ) { + if (((oldSpeed < 0.0) && (m_setSpeed >= 0.0)) || + ((oldSpeed > 0.0) && (m_setSpeed <= 0.0))) { // flipped from going forward to backwards. make the speed 'stick' at zero // until the player lets go of the key and presses it again stickySpeedKey = true; @@ -323,8 +319,8 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r m_ship->SetThrusterState(0, -linearThrustPower * InputBindings.thrustLeft->GetValue()); if (InputBindings.primaryFire->IsActive() || (Pi::input.MouseButtonState(SDL_BUTTON_LEFT) && Pi::input.MouseButtonState(SDL_BUTTON_RIGHT))) { - //XXX worldview? madness, ask from ship instead - m_ship->SetGunState(Pi::game->GetWorldView()->GetActiveWeapon(), 1); + //XXX worldview? madness, ask from ship instead + m_ship->SetGunState(Pi::game->GetWorldView()->GetActiveWeapon(), 1); } vector3d wantAngVel = vector3d( @@ -338,8 +334,8 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r angThrustSoftness = 50.0; if (wantAngVel.Length() >= 0.001 || force_rotation_damping || m_rotationDamping) { - if (Pi::game->GetTimeAccel()!=Game::TIMEACCEL_1X) { - for (int axis=0; axis<3; axis++) + if (Pi::game->GetTimeAccel() != Game::TIMEACCEL_1X) { + for (int axis = 0; axis < 3; axis++) wantAngVel[axis] = wantAngVel[axis] * Pi::game->GetInvTimeAccelRate(); } @@ -352,20 +348,12 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r bool PlayerShipController::IsAnyAngularThrusterKeyDown() { - return !Pi::IsConsoleActive() && ( - InputBindings.pitch->IsActive() || - InputBindings.yaw->IsActive() || - InputBindings.roll->IsActive() - ); + return !Pi::IsConsoleActive() && (InputBindings.pitch->IsActive() || InputBindings.yaw->IsActive() || InputBindings.roll->IsActive()); } bool PlayerShipController::IsAnyLinearThrusterKeyDown() { - return !Pi::IsConsoleActive() && ( - InputBindings.thrustForward->IsActive() || - InputBindings.thrustLeft->IsActive() || - InputBindings.thrustUp->IsActive() - ); + return !Pi::IsConsoleActive() && (InputBindings.thrustForward->IsActive() || InputBindings.thrustLeft->IsActive() || InputBindings.thrustUp->IsActive()); } void PlayerShipController::SetFlightControlState(FlightControlState s) @@ -414,7 +402,7 @@ void PlayerShipController::FireMissile() { if (!Pi::player->GetCombatTarget()) return; - LuaObject::CallMethod(Pi::player, "FireMissileAt", "any", static_cast(Pi::player->GetCombatTarget())); + LuaObject::CallMethod(Pi::player, "FireMissileAt", "any", static_cast(Pi::player->GetCombatTarget())); } Body *PlayerShipController::GetCombatTarget() const @@ -432,7 +420,7 @@ Body *PlayerShipController::GetSetSpeedTarget() const return m_setSpeedTarget; } -void PlayerShipController::SetCombatTarget(Body* const target, bool setSpeedTo) +void PlayerShipController::SetCombatTarget(Body *const target, bool setSpeedTo) { if (setSpeedTo) m_setSpeedTarget = target; @@ -441,7 +429,7 @@ void PlayerShipController::SetCombatTarget(Body* const target, bool setSpeedTo) m_combatTarget = target; } -void PlayerShipController::SetNavTarget(Body* const target, bool setSpeedTo) +void PlayerShipController::SetNavTarget(Body *const target, bool setSpeedTo) { if (setSpeedTo) m_setSpeedTarget = target; @@ -450,7 +438,7 @@ void PlayerShipController::SetNavTarget(Body* const target, bool setSpeedTo) m_navTarget = target; } -void PlayerShipController::SetSetSpeedTarget(Body* const target) +void PlayerShipController::SetSetSpeedTarget(Body *const target) { m_setSpeedTarget = target; } diff --git a/src/ShipController.h b/src/ShipController.h index b72988687..0ef163e98 100644 --- a/src/ShipController.h +++ b/src/ShipController.h @@ -7,13 +7,13 @@ * Ship movement controller class * Controls thrusters, autopilot according to player input or AI */ -#include "libs.h" #include "JsonFwd.h" +#include "libs.h" namespace KeyBindings { struct ActionBinding; struct AxisBinding; -} +} // namespace KeyBindings class Body; class Ship; @@ -35,32 +35,30 @@ enum FlightControlState { // onRotationDampingChanged; @@ -106,38 +104,38 @@ private: typedef KeyBindings::ActionBinding ActionBinding; // Weapons - ActionBinding* targetObject; - ActionBinding* primaryFire; - ActionBinding* secondaryFire; + ActionBinding *targetObject; + ActionBinding *primaryFire; + ActionBinding *secondaryFire; // Flight - AxisBinding* pitch; - AxisBinding* yaw; - AxisBinding* roll; - ActionBinding* killRot; + AxisBinding *pitch; + AxisBinding *yaw; + AxisBinding *roll; + ActionBinding *killRot; // Manual Control - AxisBinding* thrustForward; - AxisBinding* thrustUp; - AxisBinding* thrustLeft; - ActionBinding* thrustLowPower; + AxisBinding *thrustForward; + AxisBinding *thrustUp; + AxisBinding *thrustLeft; + ActionBinding *thrustLowPower; // Speed Control - ActionBinding* increaseSpeed; - ActionBinding* decreaseSpeed; - AxisBinding* throttleAxis; + ActionBinding *increaseSpeed; + ActionBinding *decreaseSpeed; + AxisBinding *throttleAxis; // Miscellaneous - ActionBinding* toggleRotationDamping; + ActionBinding *toggleRotationDamping; } InputBindings; bool IsAnyAngularThrusterKeyDown(); bool IsAnyLinearThrusterKeyDown(); //do a variety of checks to see if input is allowed void CheckControlsLock(); - Body* m_combatTarget; - Body* m_navTarget; - Body* m_setSpeedTarget; + Body *m_combatTarget; + Body *m_navTarget; + Body *m_setSpeedTarget; bool m_controlsLocked; bool m_invertMouse; // used for rear view, *not* for invert Y-axis option (which is Pi::input.IsMouseYInvert) bool m_mouseActive; diff --git a/src/ShipCpanel.cpp b/src/ShipCpanel.cpp index 18c9164f2..32a0a5728 100644 --- a/src/ShipCpanel.cpp +++ b/src/ShipCpanel.cpp @@ -1,25 +1,27 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" #include "ShipCpanel.h" -#include "Player.h" -#include "WorldView.h" -#include "SpaceStation.h" -#include "ShipCpanelMultiFuncDisplays.h" -#include "SectorView.h" -#include "SystemView.h" -#include "SystemInfoView.h" -#include "UIView.h" -#include "Lang.h" #include "Game.h" #include "GameSaveError.h" +#include "Lang.h" +#include "Pi.h" +#include "Player.h" +#include "SectorView.h" +#include "ShipCpanelMultiFuncDisplays.h" +#include "SpaceStation.h" +#include "SystemInfoView.h" +#include "SystemView.h" +#include "UIView.h" +#include "WorldView.h" +#include "libs.h" // XXX duplicated in WorldView. should probably be a theme variable -static const Color s_hudTextColor(0,255,0,204); +static const Color s_hudTextColor(0, 255, 0, 204); -ShipCpanel::ShipCpanel(Graphics::Renderer *r, Game* game): Gui::Fixed(float(Gui::Screen::GetWidth()), 80), m_game(game) +ShipCpanel::ShipCpanel(Graphics::Renderer *r, Game *game) : + Gui::Fixed(float(Gui::Screen::GetWidth()), 80), + m_game(game) { m_radar = new RadarWidget(r); @@ -29,8 +31,9 @@ ShipCpanel::ShipCpanel(Graphics::Renderer *r, Game* game): Gui::Fixed(float(Gui: m_radar->ShowAll(); } -ShipCpanel::ShipCpanel(const Json &jsonObj, Graphics::Renderer *r, Game* game) : Gui::Fixed(float(Gui::Screen::GetWidth()), 80), -m_game(game) +ShipCpanel::ShipCpanel(const Json &jsonObj, Graphics::Renderer *r, Game *game) : + Gui::Fixed(float(Gui::Screen::GetWidth()), 80), + m_game(game) { if (jsonObj["ship_c_panel"].is_null()) throw SavedGameCorruptException(); Json shipCPanelObj = jsonObj["ship_c_panel"]; diff --git a/src/ShipCpanel.h b/src/ShipCpanel.h index d88ec9ead..620a0aeef 100644 --- a/src/ShipCpanel.h +++ b/src/ShipCpanel.h @@ -4,21 +4,23 @@ #ifndef _SHIPCPANEL_H #define _SHIPCPANEL_H -#include "libs.h" -#include "gui/Gui.h" -#include "ShipCpanelMultiFuncDisplays.h" -#include "Ship.h" #include "Game.h" +#include "Ship.h" +#include "ShipCpanelMultiFuncDisplays.h" #include "WorldView.h" +#include "gui/Gui.h" +#include "libs.h" class Body; class SpaceStation; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} -class ShipCpanel: public Gui::Fixed { +class ShipCpanel : public Gui::Fixed { public: - ShipCpanel(Graphics::Renderer *r, Game* game); - ShipCpanel(const Json &jsonObj, Graphics::Renderer *r, Game* game); + ShipCpanel(Graphics::Renderer *r, Game *game); + ShipCpanel(const Json &jsonObj, Graphics::Renderer *r, Game *game); virtual ~ShipCpanel(); virtual void Draw(); void Update(); @@ -27,17 +29,26 @@ public: void SaveToJson(Json &jsonObj); - void SetRadarVisible(bool visible) { if(visible) m_radar->Show(); else m_radar->Hide(); } + void SetRadarVisible(bool visible) + { + if (visible) + m_radar->Show(); + else + m_radar->Hide(); + } private: void InitObject(); - enum MapView { MAP_SECTOR, MAP_SYSTEM, MAP_INFO, MAP_GALACTIC }; + enum MapView { MAP_SECTOR, + MAP_SYSTEM, + MAP_INFO, + MAP_GALACTIC }; // Handler for radar view / equipment view toggle button void OnClickRadarEquip(Gui::MultiStateImageButton *b); - Game* m_game; + Game *m_game; RadarWidget *m_radar; }; diff --git a/src/ShipCpanelMultiFuncDisplays.cpp b/src/ShipCpanelMultiFuncDisplays.cpp index 7e28f6887..0d724da9c 100644 --- a/src/ShipCpanelMultiFuncDisplays.cpp +++ b/src/ShipCpanelMultiFuncDisplays.cpp @@ -2,12 +2,11 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ShipCpanelMultiFuncDisplays.h" -#include "galaxy/Sector.h" #include "Game.h" +#include "GameSaveError.h" #include "HyperspaceCloud.h" #include "KeyBindings.h" #include "Lang.h" -#include "libs.h" #include "LuaConstants.h" #include "LuaTable.h" #include "Missile.h" @@ -17,30 +16,31 @@ #include "Sound.h" #include "Space.h" #include "StringF.h" +#include "galaxy/Sector.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "GameSaveError.h" +#include "libs.h" using namespace Graphics; static const float RADAR_RANGE_MAX = 100000.0f; static const float RADAR_RANGE_MIN = 1000.0f; -static const float RADAR_SCALE = 0.00001f; +static const float RADAR_SCALE = 0.00001f; //static const float RADAR_YSHRINK = 0.95f; //static const float RADAR_XSHRINK = 4.0f; -static const float A_BIT = 1.1f; +static const float A_BIT = 1.1f; static const unsigned int RADAR_STEPS = 100; // XXX target colours should be unified throughout the game -static const Color radarNavTargetColour = Color( 0, 255, 0 ); -static const Color radarCombatTargetColour = Color( 255, 0, 0 ); -static const Color radarStationColour = Color( 255, 255, 255 ); -static const Color radarShipColour = Color( 243, 237, 29 ); -static const Color radarMissileColour = Color( 240, 38, 50 ); -static const Color radarPlayerMissileColour = Color( 243, 237, 29 ); -static const Color radarCargoColour = Color( 166, 166, 166 ); -static const Color radarCloudColour = Color( 128, 128, 255 ); +static const Color radarNavTargetColour = Color(0, 255, 0); +static const Color radarCombatTargetColour = Color(255, 0, 0); +static const Color radarStationColour = Color(255, 255, 255); +static const Color radarShipColour = Color(243, 237, 29); +static const Color radarMissileColour = Color(240, 38, 50); +static const Color radarPlayerMissileColour = Color(243, 237, 29); +static const Color radarCargoColour = Color(166, 166, 166); +static const Color radarCloudColour = Color(128, 128, 255); RadarWidget::RadarWidget(Graphics::Renderer *r) : m_renderer(r) @@ -52,7 +52,7 @@ RadarWidget::RadarWidget(Graphics::Renderer *r) : } RadarWidget::RadarWidget(Graphics::Renderer *r, const Json &jsonObj) : -m_renderer(r) + m_renderer(r) { try { // Radar used to be called "scanner" for Frontier-reasons @@ -74,7 +74,7 @@ void RadarWidget::InitObject() InitScaling(); m_toggleScanModeConnection = KeyBindings::toggleScanMode.onPress.connect(sigc::mem_fun(this, &RadarWidget::ToggleMode)); - m_lastRange = RADAR_RANGE_MAX * 100.0f; // force regen + m_lastRange = RADAR_RANGE_MAX * 100.0f; // force regen GenerateBaseGeometry(); @@ -102,8 +102,10 @@ void RadarWidget::GetSizeRequested(float size[2]) void RadarWidget::ToggleMode() { if (IsVisible() && Pi::game->GetTimeAccel() != Game::TIMEACCEL_PAUSED) { - if (m_mode == RADAR_MODE_AUTO) m_mode = RADAR_MODE_MANUAL; - else m_mode = RADAR_MODE_AUTO; + if (m_mode == RADAR_MODE_AUTO) + m_mode = RADAR_MODE_MANUAL; + else + m_mode = RADAR_MODE_AUTO; } } @@ -123,7 +125,7 @@ void RadarWidget::Draw() SetScissor(true); - float rangediff = fabs(m_lastRange-m_currentRange); + float rangediff = fabs(m_lastRange - m_currentRange); if (rangediff > 200.0 || rangediff / m_currentRange > 0.01) { GenerateRingsAndSpokes(); m_lastRange = m_currentRange; @@ -160,7 +162,8 @@ void RadarWidget::Draw() SetScissor(false); } -void RadarWidget::InitScaling(void) { +void RadarWidget::InitScaling(void) +{ RADAR_XSHRINK = 4.0f; RADAR_YSHRINK = 0.95f; } @@ -178,7 +181,11 @@ void RadarWidget::Update() } // range priority is combat target > ship/missile > nav target > other - enum { RANGE_MAX, RANGE_FAR_OTHER, RANGE_NAV, RANGE_FAR_SHIP, RANGE_COMBAT } range_type = RANGE_MAX; + enum { RANGE_MAX, + RANGE_FAR_OTHER, + RANGE_NAV, + RANGE_FAR_SHIP, + RANGE_COMBAT } range_type = RANGE_MAX; float combat_dist = 0, far_ship_dist = 0, nav_dist = 0, far_other_dist = 0; // collect the bodies to be displayed, and if AUTO, distances @@ -196,55 +203,53 @@ void RadarWidget::Update() switch ((*i)->GetType()) { - case Object::MISSILE: - // player's own missiles are ignored for range calc but still shown - if (static_cast(*i)->GetOwner() == Pi::player) { - c.isSpecial = true; - break; - } - - // else fall through - - case Object::SHIP: { - const Ship *s = static_cast(*i); - if (s->GetFlightState() != Ship::FLYING && s->GetFlightState() != Ship::LANDED) - continue; - - if ((*i) == Pi::player->GetCombatTarget()) c.isSpecial = true; - - if (m_mode == RADAR_MODE_AUTO && range_type != RANGE_COMBAT) { - if (c.isSpecial == true) { - combat_dist = dist; - range_type = RANGE_COMBAT; - } - else if (dist > far_ship_dist) { - far_ship_dist = dist; - range_type = RANGE_FAR_SHIP; - } - } + case Object::MISSILE: + // player's own missiles are ignored for range calc but still shown + if (static_cast(*i)->GetOwner() == Pi::player) { + c.isSpecial = true; break; } - case Object::SPACESTATION: - case Object::CARGOBODY: - case Object::HYPERSPACECLOUD: + // else fall through - if ((*i) == Pi::player->GetNavTarget()) c.isSpecial = true; - - if (m_mode == RADAR_MODE_AUTO && range_type < RANGE_NAV) { - if (c.isSpecial == true) { - nav_dist = dist; - range_type = RANGE_NAV; - } - else if (dist > far_other_dist) { - far_other_dist = dist; - range_type = RANGE_FAR_OTHER; - } - } - break; - - default: + case Object::SHIP: { + const Ship *s = static_cast(*i); + if (s->GetFlightState() != Ship::FLYING && s->GetFlightState() != Ship::LANDED) continue; + + if ((*i) == Pi::player->GetCombatTarget()) c.isSpecial = true; + + if (m_mode == RADAR_MODE_AUTO && range_type != RANGE_COMBAT) { + if (c.isSpecial == true) { + combat_dist = dist; + range_type = RANGE_COMBAT; + } else if (dist > far_ship_dist) { + far_ship_dist = dist; + range_type = RANGE_FAR_SHIP; + } + } + break; + } + + case Object::SPACESTATION: + case Object::CARGOBODY: + case Object::HYPERSPACECLOUD: + + if ((*i) == Pi::player->GetNavTarget()) c.isSpecial = true; + + if (m_mode == RADAR_MODE_AUTO && range_type < RANGE_NAV) { + if (c.isSpecial == true) { + nav_dist = dist; + range_type = RANGE_NAV; + } else if (dist > far_other_dist) { + far_other_dist = dist; + range_type = RANGE_FAR_OTHER; + } + } + break; + + default: + continue; } m_contacts.push_back(c); @@ -254,38 +259,35 @@ void RadarWidget::Update() if (m_mode == RADAR_MODE_AUTO) { m_manualRange = m_targetRange; m_mode = RADAR_MODE_MANUAL; - } - else + } else m_manualRange = m_currentRange; m_manualRange = Clamp(m_manualRange * 1.05f, RADAR_RANGE_MIN, RADAR_RANGE_MAX); - } - else if (KeyBindings::decreaseScanRange.IsActive()) { + } else if (KeyBindings::decreaseScanRange.IsActive()) { if (m_mode == RADAR_MODE_AUTO) { m_manualRange = m_targetRange; m_mode = RADAR_MODE_MANUAL; - } - else + } else m_manualRange = m_currentRange; m_manualRange = Clamp(m_manualRange * 0.95f, RADAR_RANGE_MIN, RADAR_RANGE_MAX); } if (m_mode == RADAR_MODE_AUTO) { switch (range_type) { - case RANGE_COMBAT: - m_targetRange = Clamp(combat_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); - break; - case RANGE_FAR_SHIP: - m_targetRange = Clamp(far_ship_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); - break; - case RANGE_NAV: - m_targetRange = Clamp(nav_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); - break; - case RANGE_FAR_OTHER: - m_targetRange = Clamp(far_other_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); - break; - default: - m_targetRange = RADAR_RANGE_MAX; - break; + case RANGE_COMBAT: + m_targetRange = Clamp(combat_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); + break; + case RANGE_FAR_SHIP: + m_targetRange = Clamp(far_ship_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); + break; + case RANGE_NAV: + m_targetRange = Clamp(nav_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); + break; + case RANGE_FAR_OTHER: + m_targetRange = Clamp(far_other_dist * A_BIT, RADAR_RANGE_MIN, RADAR_RANGE_MAX); + break; + default: + m_targetRange = RADAR_RANGE_MAX; + break; } } @@ -295,7 +297,7 @@ void RadarWidget::Update() void RadarWidget::DrawBlobs(bool below) { - assert( !m_contacts.empty() ); + assert(!m_contacts.empty()); static const Uint32 MAX_CONTACTS(100); std::vector blobs; @@ -312,43 +314,43 @@ void RadarWidget::DrawBlobs(bool below) const Color *color = 0; switch (i->type) { - case Object::SHIP: - if (i->isSpecial) - color = &radarCombatTargetColour; - else - color = &radarShipColour; - break; + case Object::SHIP: + if (i->isSpecial) + color = &radarCombatTargetColour; + else + color = &radarShipColour; + break; - case Object::MISSILE: - if (i->isSpecial) - color = &radarPlayerMissileColour; - else - color = &radarMissileColour; - break; + case Object::MISSILE: + if (i->isSpecial) + color = &radarPlayerMissileColour; + else + color = &radarMissileColour; + break; - case Object::SPACESTATION: - if (i->isSpecial) - color = &radarNavTargetColour; - else - color = &radarStationColour; - break; + case Object::SPACESTATION: + if (i->isSpecial) + color = &radarNavTargetColour; + else + color = &radarStationColour; + break; - case Object::CARGOBODY: - if (i->isSpecial) - color = &radarNavTargetColour; - else - color = &radarCargoColour; - break; + case Object::CARGOBODY: + if (i->isSpecial) + color = &radarNavTargetColour; + else + color = &radarCargoColour; + break; - case Object::HYPERSPACECLOUD: - if (i->isSpecial) - color = &radarNavTargetColour; - else - color = &radarCloudColour; - break; + case Object::HYPERSPACECLOUD: + if (i->isSpecial) + color = &radarNavTargetColour; + else + color = &radarCloudColour; + break; - default: - continue; + default: + continue; } vector3d pos = i->pos * Pi::player->GetOrient(); @@ -374,7 +376,7 @@ void RadarWidget::DrawBlobs(bool below) blobcolors.push_back(*color); } - if( !vts.empty() ) { + if (!vts.empty()) { m_contactLines.SetData(vts.size(), &vts[0], &colors[0]); m_contactLines.Draw(m_renderer, m_renderState); @@ -394,7 +396,8 @@ void RadarWidget::GenerateBaseGeometry() float a = step; for (unsigned int i = 1; i < RADAR_STEPS; i++, a += step) { vector3f v = vector3f(sin(a), RADAR_YSHRINK * cos(a), 0.0f); - m_circle.push_back(v); m_circle.push_back(v); + m_circle.push_back(v); + m_circle.push_back(v); } m_circle.push_back(vector3f(0.0f, RADAR_YSHRINK, 0.0f)); @@ -413,18 +416,21 @@ void RadarWidget::GenerateRingsAndSpokes() m_vts.clear(); // inner circle - for (int i=0; i= 1.0f) break; - for (int i=0; i m_currentRange) - m_currentRange = Clamp(m_currentRange + (m_currentRange*step), RADAR_RANGE_MIN, m_targetRange); + m_currentRange = Clamp(m_currentRange + (m_currentRange * step), RADAR_RANGE_MIN, m_targetRange); m_scale = RADAR_SCALE * (RADAR_RANGE_MAX / m_currentRange); } diff --git a/src/ShipCpanelMultiFuncDisplays.h b/src/ShipCpanelMultiFuncDisplays.h index d4e88640e..a458afc3f 100644 --- a/src/ShipCpanelMultiFuncDisplays.h +++ b/src/ShipCpanelMultiFuncDisplays.h @@ -4,12 +4,14 @@ #ifndef _SHIPCPANELMULTIFUNCDISPLAYS_H #define _SHIPCPANELMULTIFUNCDISPLAYS_H -#include "gui/Gui.h" -#include "Object.h" #include "JsonFwd.h" +#include "Object.h" +#include "gui/Gui.h" class Body; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} enum multifuncfunc_t { MFUNC_RADAR, @@ -24,7 +26,7 @@ public: virtual void Update() = 0; }; -class RadarWidget: public IMultiFunc, public Gui::Widget { +class RadarWidget : public IMultiFunc, public Gui::Widget { public: RadarWidget(Graphics::Renderer *r); RadarWidget(Graphics::Renderer *r, const Json &jsonObj); @@ -58,7 +60,8 @@ private: Graphics::Drawables::Lines m_contactLines; Graphics::Drawables::Points m_contactBlobs; - enum RadarMode { RADAR_MODE_AUTO, RADAR_MODE_MANUAL }; + enum RadarMode { RADAR_MODE_AUTO, + RADAR_MODE_MANUAL }; RadarMode m_mode; float m_currentRange, m_manualRange, m_targetRange; diff --git a/src/ShipType.cpp b/src/ShipType.cpp index 863db2515..2eb111c9b 100644 --- a/src/ShipType.cpp +++ b/src/ShipType.cpp @@ -5,15 +5,15 @@ #include "ShipType.h" #if ALLOW_LUA_SHIP_DEF -#include "LuaVector.h" -#include "LuaUtils.h" -#include "LuaTable.h" #include "LuaConstants.h" +#include "LuaTable.h" +#include "LuaUtils.h" +#include "LuaVector.h" #endif #include "FileSystem.h" -#include "utils.h" -#include "Lang.h" #include "Json.h" +#include "Lang.h" +#include "utils.h" #include // TODO: Fix the horrible control flow that makes this exception type necessary. @@ -24,22 +24,23 @@ std::vector ShipType::player_ships; std::vector ShipType::static_ships; std::vector ShipType::missile_ships; -const std::string ShipType::POLICE = "kanara"; -const std::string ShipType::MISSILE_GUIDED = "missile_guided"; -const std::string ShipType::MISSILE_NAVAL = "missile_naval"; -const std::string ShipType::MISSILE_SMART = "missile_smart"; -const std::string ShipType::MISSILE_UNGUIDED = "missile_unguided"; +const std::string ShipType::POLICE = "kanara"; +const std::string ShipType::MISSILE_GUIDED = "missile_guided"; +const std::string ShipType::MISSILE_NAVAL = "missile_naval"; +const std::string ShipType::MISSILE_SMART = "missile_smart"; +const std::string ShipType::MISSILE_UNGUIDED = "missile_unguided"; float ShipType::GetFuelUseRate() const { const float denominator = fuelTankMass * effectiveExhaustVelocity * 10; - return denominator > 0 ? linThrust[THRUSTER_FORWARD]/denominator : 1e9; + return denominator > 0 ? linThrust[THRUSTER_FORWARD] / denominator : 1e9; } // returns velocity of engine exhausts in m/s -static double GetEffectiveExhaustVelocity(double fuelTankMass, double thrusterFuelUse, double forwardThrust) { +static double GetEffectiveExhaustVelocity(double fuelTankMass, double thrusterFuelUse, double forwardThrust) +{ double denominator = fuelTankMass * thrusterFuelUse * 10; - return fabs(denominator > 0 ? forwardThrust/denominator : 1e9); + return fabs(denominator > 0 ? forwardThrust / denominator : 1e9); } static bool ShipIsUnbuyable(const std::string &id) @@ -60,11 +61,11 @@ ShipType::ShipType(const Id &_id, const std::string &path) // determine what kind (tag) of ship this is. const std::string tagStr = data.value("tag", ""); - if( tagStr.empty() || strcasecmp(tagStr.c_str(), "ship")==0 ) { + if (tagStr.empty() || strcasecmp(tagStr.c_str(), "ship") == 0) { tag = TAG_SHIP; - } else if( strcasecmp(tagStr.c_str(), "static")==0 ) { + } else if (strcasecmp(tagStr.c_str(), "static") == 0) { tag = TAG_STATIC_SHIP; - } else if( strcasecmp(tagStr.c_str(), "missile")==0 ) { + } else if (strcasecmp(tagStr.c_str(), "missile") == 0) { tag = TAG_MISSILE; } @@ -93,9 +94,9 @@ ShipType::ShipType(const Id &_id, const std::string &path) // Parse global thrusters color bool error = false; int parse = 0; - for( Json::iterator thruster_color = data["thruster_global_color"].begin() ; thruster_color != data["thruster_global_color"].end() ; ++thruster_color ) { + for (Json::iterator thruster_color = data["thruster_global_color"].begin(); thruster_color != data["thruster_global_color"].end(); ++thruster_color) { const std::string colorchannel = thruster_color.key(); - if (colorchannel.length()!=1) { + if (colorchannel.length() != 1) { error = true; break; } @@ -117,49 +118,51 @@ ShipType::ShipType(const Id &_id, const std::string &path) break; } } - if (error==true) { + if (error == true) { Output("In file \"%s.json\" global thrusters custom color must be \"r\",\"g\" and \"b\"\n", modelName.c_str()); throw ShipTypeLoadError(); - } else if (parse>0 && parse<3) { + } else if (parse > 0 && parse < 3) { Output("In file \"%s.json\" global thrusters custom color is malformed\n", modelName.c_str()); throw ShipTypeLoadError(); - } else if (parse==3) { + } else if (parse == 3) { globalThrusterColor.a = 255; isGlobalColorDefined = true; } // Parse direction thrusters color - for (int i=0; isecond = Clamp(it->second, 0, 1); } } @@ -201,14 +204,14 @@ ShipType::ShipType(const Id &_id, const std::string &path) effectiveExhaustVelocity = data.value("effective_exhaust_velocity", -1.0f); const float thruster_fuel_use = data.value("thruster_fuel_use", -1.0f); - if(effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) { + if (effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) { // default value of v_c is used effectiveExhaustVelocity = 55000000; - } else if(effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) { + } else if (effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) { // v_c undefined and thruster fuel use defined -- use it! effectiveExhaustVelocity = GetEffectiveExhaustVelocity(fuelTankMass, thruster_fuel_use, linThrust[Thruster::THRUSTER_FORWARD]); } else { - if(thruster_fuel_use >= 0) { + if (thruster_fuel_use >= 0) { Output("Warning: Both thruster_fuel_use and effective_exhaust_velocity defined for %s, using effective_exhaust_velocity.\n", modelName.c_str()); } } @@ -296,10 +299,12 @@ int _define_ship(lua_State *L, ShipType::Tag tag, std::vector *lis { const auto it = s.slots.find("engine"); - if (it != s.slots.end()) { it->second = Clamp(it->second, 0, 1); } + if (it != s.slots.end()) { + it->second = Clamp(it->second, 0, 1); + } } - for( auto slot : s.slots ) { + for (auto slot : s.slots) { data["slots"][slot.first] = slot.second; } @@ -311,14 +316,14 @@ int _define_ship(lua_State *L, ShipType::Tag tag, std::vector *lis data["effective_exhaust_velocity"] = s.effectiveExhaustVelocity; data["thruster_fuel_use"] = thruster_fuel_use; - if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) { + if (s.effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) { // default value of v_c is used s.effectiveExhaustVelocity = 55000000; - } else if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) { + } else if (s.effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) { // v_c undefined and thruster fuel use defined -- use it! s.effectiveExhaustVelocity = GetEffectiveExhaustVelocity(s.fuelTankMass, thruster_fuel_use, s.linThrust[ShipType::THRUSTER_FORWARD]); } else { - if(thruster_fuel_use >= 0) + if (thruster_fuel_use >= 0) Output("Warning: Both thruster_fuel_use and effective_exhaust_velocity defined for %s, using effective_exhaust_velocity.\n", s.modelName.c_str()); } @@ -335,7 +340,7 @@ int _define_ship(lua_State *L, ShipType::Tag tag, std::vector *lis data["hyperdrive_class"] = s.hyperdriveClass; Json::StyledWriter writer; - const std::string saveMe = writer.write( data ); + const std::string saveMe = writer.write(data); const std::string path("ships/" + s_currentShipFile + ".json"); FileSystem::FileSourceFS newFS(FileSystem::GetDataDir()); @@ -360,7 +365,7 @@ int _define_ship(lua_State *L, ShipType::Tag tag, std::vector *lis if (s.minCrew < 1 || s.maxCrew < 1 || s.minCrew > s.maxCrew) return luaL_error(L, "Invalid values for min_crew and max_crew"); - const std::string& id = s_currentShipFile; + const std::string &id = s_currentShipFile; typedef std::map::iterator iter; std::pair result = ShipType::types.insert(std::make_pair(id, s)); if (result.second) @@ -400,16 +405,18 @@ void ShipType::Init() for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse); !files.Finished(); files.Next()) { const fs::FileInfo &info = files.Current(); if (ends_with_ci(info.GetPath(), ".json")) { - const std::string id(info.GetName().substr(0, info.GetName().size()-5)); + const std::string id(info.GetName().substr(0, info.GetName().size() - 5)); try { ShipType st = ShipType(id, info.GetPath()); types.insert(std::make_pair(st.id, st)); // assign the names to the various lists - switch( st.tag ) { - case TAG_SHIP: player_ships.push_back(id); break; - case TAG_STATIC_SHIP: static_ships.push_back(id); break; - case TAG_MISSILE: missile_ships.push_back(id); break; + switch (st.tag) { + case TAG_SHIP: player_ships.push_back(id); break; + case TAG_STATIC_SHIP: static_ships.push_back(id); break; + case TAG_MISSILE: + missile_ships.push_back(id); + break; break; case TAG_NONE: default: @@ -459,8 +466,7 @@ void ShipType::Init() if (ends_with_ci(info.GetPath(), ".lua")) { const std::string name = info.GetName(); s_currentShipFile = name.substr(0, name.size() - 4); - if (ShipType::types.find(s_currentShipFile) == ShipType::types.end()) - { + if (ShipType::types.find(s_currentShipFile) == ShipType::types.end()) { pi_lua_dofile(l, info.GetPath()); s_currentShipFile.clear(); } diff --git a/src/ShipType.h b/src/ShipType.h index b2a16f629..3138afe81 100644 --- a/src/ShipType.h +++ b/src/ShipType.h @@ -4,13 +4,13 @@ #ifndef _SHIPTYPE_H #define _SHIPTYPE_H +#include "FixedGuns.h" +#include "Propulsion.h" #include "libs.h" #include "vector3.h" -#include #include #include -#include "Propulsion.h" -#include "FixedGuns.h" +#include struct ShipType { enum DualLaserOrientation { // @@ -26,7 +26,7 @@ struct ShipType { }; typedef std::string Id; - ShipType() {}; + ShipType(){}; ShipType(const Id &id, const std::string &path); //////// @@ -76,10 +76,13 @@ struct ShipType { static std::vector missile_ships; static void Init(); - static const ShipType *Get(const char *name) { + static const ShipType *Get(const char *name) + { std::map::iterator t = types.find(name); - if (t == types.end()) return 0; - else return &(*t).second; + if (t == types.end()) + return 0; + else + return &(*t).second; } }; diff --git a/src/SmartPtr.h b/src/SmartPtr.h index a8a2bc4dc..9f745b425 100644 --- a/src/SmartPtr.h +++ b/src/SmartPtr.h @@ -4,28 +4,36 @@ #ifndef _SMARTPTR_H #define _SMARTPTR_H -#include // for ptrdiff_t #include +#include // for ptrdiff_t #include // for free() #ifdef __GNUC__ -#define WARN_UNUSED_RESULT(ret,decl) ret decl __attribute__ ((warn_unused_result)) +#define WARN_UNUSED_RESULT(ret, decl) ret decl __attribute__((warn_unused_result)) #else -#define WARN_UNUSED_RESULT(ret,decl) ret decl +#define WARN_UNUSED_RESULT(ret, decl) ret decl #endif template class SmartPtrBase { typedef SmartPtrBase this_type; - typedef T* this_type::*safe_bool; + typedef T *this_type::*safe_bool; public: // copy & swap idiom // see http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom - void Reset(T *p = 0) { Derived(p).Swap(*static_cast(this)); } + void Reset(T *p = 0) { Derived(p).Swap(*static_cast(this)); } - T &operator*() const { assert(m_ptr); return *m_ptr; } - T *operator->() const { assert(m_ptr); return m_ptr; } + T &operator*() const + { + assert(m_ptr); + return *m_ptr; + } + T *operator->() const + { + assert(m_ptr); + return m_ptr; + } T *Get() const { return m_ptr; } bool Valid() const { return (m_ptr != 0); } @@ -35,7 +43,8 @@ public: friend void swap(this_type &a, this_type &b) { a.Swap(b); } - void Swap(this_type &b) { + void Swap(this_type &b) + { T *p = m_ptr; m_ptr = b.m_ptr; b.m_ptr = p; @@ -47,50 +56,63 @@ public: // comparisons that are written to work on any pair friend bool operator==(const this_type &a, const T *b) { return (a.Get() == b); } friend bool operator!=(const this_type &a, const T *b) { return (a.Get() != b); } - friend bool operator< (const this_type &a, const T *b) { return (a.Get() < b); } + friend bool operator<(const this_type &a, const T *b) { return (a.Get() < b); } friend bool operator<=(const this_type &a, const T *b) { return (a.Get() <= b); } - friend bool operator> (const this_type &a, const T *b) { return (a.Get() > b); } + friend bool operator>(const this_type &a, const T *b) { return (a.Get() > b); } friend bool operator>=(const this_type &a, const T *b) { return (a.Get() >= b); } friend bool operator==(const T *a, const this_type &b) { return (a == b.Get()); } friend bool operator!=(const T *a, const this_type &b) { return (a != b.Get()); } - friend bool operator< (const T *a, const this_type &b) { return (a < b.Get()); } + friend bool operator<(const T *a, const this_type &b) { return (a < b.Get()); } friend bool operator<=(const T *a, const this_type &b) { return (a <= b.Get()); } - friend bool operator> (const T *a, const this_type &b) { return (a > b.Get()); } + friend bool operator>(const T *a, const this_type &b) { return (a > b.Get()); } friend bool operator>=(const T *a, const this_type &b) { return (a >= b.Get()); } protected: - SmartPtrBase(): m_ptr(0) {} - explicit SmartPtrBase(T *p): m_ptr(p) {} + SmartPtrBase() : + m_ptr(0) {} + explicit SmartPtrBase(T *p) : + m_ptr(p) {} // Release() doesn't make sense for all smart pointer types // (e.g., RefCountedPtr can't Release, it can only Reset) - WARN_UNUSED_RESULT(T*,Release()) { T *p = m_ptr; m_ptr = 0; return p; } + WARN_UNUSED_RESULT(T *, Release()) + { + T *p = m_ptr; + m_ptr = 0; + return p; + } T *m_ptr; }; -#define DEF_SMARTPTR_COMPARISON(op) \ - template \ - inline bool operator op(const SmartPtrBase &a, const SmartPtrBase &b) \ - { return (a.Get() op b.Get()); } \ - template \ - inline bool operator op(const SmartPtrBase &a, const T2 *b) \ - { return (a.Get() op b); } \ - template \ - inline bool operator op(const T1 *a, const SmartPtrBase &b) \ - { return (a op b.Get()); } +#define DEF_SMARTPTR_COMPARISON(op) \ + template \ + inline bool operator op(const SmartPtrBase &a, const SmartPtrBase &b) \ + { \ + return (a.Get() op b.Get()); \ + } \ + template \ + inline bool operator op(const SmartPtrBase &a, const T2 *b) \ + { \ + return (a.Get() op b); \ + } \ + template \ + inline bool operator op(const T1 *a, const SmartPtrBase &b) \ + { \ + return (a op b.Get()); \ + } DEF_SMARTPTR_COMPARISON(==) DEF_SMARTPTR_COMPARISON(!=) -DEF_SMARTPTR_COMPARISON(< ) +DEF_SMARTPTR_COMPARISON(<) DEF_SMARTPTR_COMPARISON(<=) -DEF_SMARTPTR_COMPARISON(> ) +DEF_SMARTPTR_COMPARISON(>) DEF_SMARTPTR_COMPARISON(>=) #undef DEF_SMARTPTR_COMPARISON // a deleter type for use with std::unique_ptr struct FreeDeleter { - void operator()(void* p) { std::free(p); } + void operator()(void *p) { std::free(p); } }; #endif diff --git a/src/Sound.cpp b/src/Sound.cpp index de449cd2e..847ae7905 100644 --- a/src/Sound.cpp +++ b/src/Sound.cpp @@ -5,655 +5,669 @@ * Sound, dude */ -#include -#include -#include -#include -#include -#include -#include #include "Sound.h" #include "Body.h" +#include "FileSystem.h" #include "Pi.h" #include "Player.h" -#include "FileSystem.h" +#include +#include +#include +#include +#include +#include +#include namespace Sound { -static const unsigned int FREQ = 44100; -static const unsigned int BUF_SIZE = 4096; -static const unsigned int MAX_WAVSTREAMS = 10; //first two are for music -static const double STREAM_IF_LONGER_THAN = 10.0; + static const unsigned int FREQ = 44100; + static const unsigned int BUF_SIZE = 4096; + static const unsigned int MAX_WAVSTREAMS = 10; //first two are for music + static const double STREAM_IF_LONGER_THAN = 10.0; -class OggFileDataStream { -public: - static const ov_callbacks CALLBACKS; + class OggFileDataStream { + public: + static const ov_callbacks CALLBACKS; - OggFileDataStream(): m_cursor(nullptr) {} - explicit OggFileDataStream(const RefCountedPtr &data): - m_data(data), m_cursor(data->GetData()) { assert(data); } + OggFileDataStream() : + m_cursor(nullptr) {} + explicit OggFileDataStream(const RefCountedPtr &data) : + m_data(data), + m_cursor(data->GetData()) { assert(data); } - void Reset() - { - m_data.Reset(); - m_cursor = nullptr; - } + void Reset() + { + m_data.Reset(); + m_cursor = nullptr; + } - void Reset(const RefCountedPtr &data) - { - assert(data); - m_data = data; - m_cursor = m_data->GetData(); - } + void Reset(const RefCountedPtr &data) + { + assert(data); + m_data = data; + m_cursor = m_data->GetData(); + } - size_t read(char *buf, size_t sz, int n) - { - assert(n >= 0); - ptrdiff_t offset = tell(); - // clamp to available data - n = std::min(n, int((m_data->GetSize() - offset) / sz)); - size_t fullsize = sz * n; - assert(offset + fullsize <= m_data->GetSize()); - memcpy(buf, m_cursor, fullsize); - m_cursor += fullsize; - return n; - } + size_t read(char *buf, size_t sz, int n) + { + assert(n >= 0); + ptrdiff_t offset = tell(); + // clamp to available data + n = std::min(n, int((m_data->GetSize() - offset) / sz)); + size_t fullsize = sz * n; + assert(offset + fullsize <= m_data->GetSize()); + memcpy(buf, m_cursor, fullsize); + m_cursor += fullsize; + return n; + } - int seek(ogg_int64_t offset, int whence) - { - switch (whence) { + int seek(ogg_int64_t offset, int whence) + { + switch (whence) { case SEEK_SET: m_cursor = m_data->GetData() + offset; break; case SEEK_END: m_cursor = m_data->GetData() + (m_data->GetSize() + offset); break; case SEEK_CUR: m_cursor += offset; break; default: return -1; - } - return 0; - } - - long tell() - { - assert(m_data && m_cursor); - return long(m_cursor - m_data->GetData()); - } - - int close() - { - if (m_data) { - m_data.Reset(); - m_cursor = nullptr; + } return 0; + } + + long tell() + { + assert(m_data && m_cursor); + return long(m_cursor - m_data->GetData()); + } + + int close() + { + if (m_data) { + m_data.Reset(); + m_cursor = nullptr; + return 0; + } else { + return -1; + } + } + + private: + static size_t ov_callback_read(void *buf, size_t sz, size_t n, void *stream) + { + return reinterpret_cast(stream)->read(reinterpret_cast(buf), sz, n); + } + static int ov_callback_seek(void *stream, ogg_int64_t offset, int whence) + { + return reinterpret_cast(stream)->seek(offset, whence); + } + static long ov_callback_tell(void *stream) + { + return reinterpret_cast(stream)->tell(); + } + static int ov_callback_close(void *stream) + { + return reinterpret_cast(stream)->close(); + } + + RefCountedPtr m_data; + const char *m_cursor; + }; + + const ov_callbacks OggFileDataStream::CALLBACKS = { + &OggFileDataStream::ov_callback_read, + &OggFileDataStream::ov_callback_seek, + &OggFileDataStream::ov_callback_close, + &OggFileDataStream::ov_callback_tell + }; + + static float m_masterVol = 1.0f; + static float m_sfxVol = 1.0f; + + void SetMasterVolume(const float vol) + { + m_masterVol = vol; + } + + float GetMasterVolume() + { + return m_masterVol; + } + + void SetSfxVolume(const float vol) + { + m_sfxVol = vol; + } + + float GetSfxVolume() + { + return m_sfxVol; + } + + void CalculateStereo(const Body *b, float vol, float *volLeftOut, float *volRightOut) + { + vector3d pos(0.0); + + if (b != Pi::player) { + pos = b->GetPositionRelTo(Pi::player); + pos = pos * Pi::player->GetOrient(); + } + + const float len = pos.Length(); + if (!is_zero_general(len)) { + vol = vol / (0.002 * len); + double dot = pos.Normalized().x * vol; + + (*volLeftOut) = vol * (2.0f - (1.0 + dot)); + (*volRightOut) = vol * (1.0 + dot); } else { - return -1; + (*volLeftOut) = (*volRightOut) = vol; + } + (*volLeftOut) = Clamp((*volLeftOut), 0.0f, 1.0f); + (*volRightOut) = Clamp((*volRightOut), 0.0f, 1.0f); + } + + eventid BodyMakeNoise(const Body *b, const char *sfx, float vol) + { + float vl, vr; + CalculateStereo(b, vol, &vl, &vr); + return Sound::PlaySfx(sfx, vl, vr, 0); + } + + struct SoundEvent { + const Sample *sample; + OggVorbis_File *oggv; // if sample->buf = 0 then stream this + OggFileDataStream ogg_data_stream; + Uint32 buf_pos; + float volume[2]; // left and right channels + eventid identifier; + Uint32 op; + + float targetVolume[2]; + float rateOfChange[2]; // per sample + bool ascend[2]; + }; + + static std::map sfx_samples; + struct SoundEvent wavstream[MAX_WAVSTREAMS]; + + static Sample *GetSample(const char *filename) + { + if (sfx_samples.find(filename) != sfx_samples.end()) { + return &sfx_samples[filename]; + } else { + //SilentWarning("Unknown sound sample: %s", filename); + return 0; } } -private: - static size_t ov_callback_read(void *buf, size_t sz, size_t n, void *stream) - { return reinterpret_cast(stream)->read(reinterpret_cast(buf), sz, n); } - static int ov_callback_seek(void *stream, ogg_int64_t offset, int whence) - { return reinterpret_cast(stream)->seek(offset, whence); } - static long ov_callback_tell(void *stream) - { return reinterpret_cast(stream)->tell(); } - static int ov_callback_close(void *stream) - { return reinterpret_cast(stream)->close(); } - - RefCountedPtr m_data; - const char *m_cursor; -}; - -const ov_callbacks OggFileDataStream::CALLBACKS = { - &OggFileDataStream::ov_callback_read, - &OggFileDataStream::ov_callback_seek, - &OggFileDataStream::ov_callback_close, - &OggFileDataStream::ov_callback_tell -}; - -static float m_masterVol = 1.0f; -static float m_sfxVol = 1.0f; - -void SetMasterVolume(const float vol) -{ - m_masterVol = vol; -} - -float GetMasterVolume() -{ - return m_masterVol; -} - -void SetSfxVolume(const float vol) -{ - m_sfxVol = vol; -} - -float GetSfxVolume() -{ - return m_sfxVol; -} - -void CalculateStereo(const Body *b, float vol, float *volLeftOut, float *volRightOut) -{ - vector3d pos(0.0); - - if (b != Pi::player) { - pos = b->GetPositionRelTo(Pi::player); - pos = pos * Pi::player->GetOrient(); + static SoundEvent *GetEvent(eventid id) + { + for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { + if (wavstream[i].sample && (wavstream[i].identifier == id)) + return &wavstream[i]; + } + return nullptr; } - const float len = pos.Length(); - if (!is_zero_general(len)) { - vol = vol / (0.002*len); - double dot = pos.Normalized().x * vol; - - (*volLeftOut) = vol * (2.0f - (1.0 + dot)); - (*volRightOut) = vol * (1.0 + dot); + bool SetOp(eventid id, Op op) + { + if (id == 0) return false; + bool ret = false; + SDL_LockAudio(); + SoundEvent *se = GetEvent(id); + if (se) { + se->op = op; + ret = true; + } + SDL_UnlockAudio(); + return ret; } - else { - (*volLeftOut) = (*volRightOut) = vol; + + static void DestroyEvent(SoundEvent *ev) + { + if (ev->oggv) { + // streaming ogg + ov_clear(ev->oggv); + delete ev->oggv; + ev->oggv = 0; + ev->ogg_data_stream.Reset(); + } + ev->sample = nullptr; } - (*volLeftOut) = Clamp((*volLeftOut), 0.0f, 1.0f); - (*volRightOut) = Clamp((*volRightOut), 0.0f, 1.0f); -} -eventid BodyMakeNoise(const Body *b, const char *sfx, float vol) -{ - float vl, vr; - CalculateStereo(b, vol, &vl, &vr); - return Sound::PlaySfx(sfx, vl, vr, 0); -} - -struct SoundEvent { - const Sample *sample; - OggVorbis_File *oggv; // if sample->buf = 0 then stream this - OggFileDataStream ogg_data_stream; - Uint32 buf_pos; - float volume[2]; // left and right channels - eventid identifier; - Uint32 op; - - float targetVolume[2]; - float rateOfChange[2]; // per sample - bool ascend[2]; -}; - -static std::map sfx_samples; -struct SoundEvent wavstream[MAX_WAVSTREAMS]; - -static Sample *GetSample(const char *filename) -{ - if (sfx_samples.find(filename) != sfx_samples.end()) { - return &sfx_samples[filename]; - } else { - //SilentWarning("Unknown sound sample: %s", filename); - return 0; - } -} - -static SoundEvent *GetEvent(eventid id) -{ - for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { - if (wavstream[i].sample && (wavstream[i].identifier == id)) - return &wavstream[i]; - } - return nullptr; -} - -bool SetOp(eventid id, Op op) -{ - if (id == 0) return false; - bool ret = false; - SDL_LockAudio(); - SoundEvent *se = GetEvent(id); - if (se) { - se->op = op; - ret = true; - } - SDL_UnlockAudio(); - return ret; -} - -static void DestroyEvent(SoundEvent *ev) -{ - if (ev->oggv) { - // streaming ogg - ov_clear(ev->oggv); - delete ev->oggv; - ev->oggv = 0; - ev->ogg_data_stream.Reset(); - } - ev->sample = nullptr; -} - -/* + /* * Volume should be 0-65535 */ -static Uint32 identifier = 1; -eventid PlaySfx (const char *fx, const float volume_left, const float volume_right, const Op op) -{ - SDL_LockAudio(); - unsigned int idx; - Uint32 age; - /* find free wavstream (first two reserved for music) */ - for (idx = 2; idx < MAX_WAVSTREAMS; idx++) { - if (!wavstream[idx].sample) break; - } - if (idx == MAX_WAVSTREAMS) { - /* otherwise overwrite oldest one */ - age = 0; idx = 0; - for (unsigned int i = 2; i < MAX_WAVSTREAMS; i++) { - if ((i==0) || (wavstream[i].buf_pos > age)) { - idx = i; - age = wavstream[i].buf_pos; - } + static Uint32 identifier = 1; + eventid PlaySfx(const char *fx, const float volume_left, const float volume_right, const Op op) + { + SDL_LockAudio(); + unsigned int idx; + Uint32 age; + /* find free wavstream (first two reserved for music) */ + for (idx = 2; idx < MAX_WAVSTREAMS; idx++) { + if (!wavstream[idx].sample) break; } - DestroyEvent(&wavstream[idx]); + if (idx == MAX_WAVSTREAMS) { + /* otherwise overwrite oldest one */ + age = 0; + idx = 0; + for (unsigned int i = 2; i < MAX_WAVSTREAMS; i++) { + if ((i == 0) || (wavstream[i].buf_pos > age)) { + idx = i; + age = wavstream[i].buf_pos; + } + } + DestroyEvent(&wavstream[idx]); + } + wavstream[idx].sample = GetSample(fx); + wavstream[idx].oggv = 0; + wavstream[idx].buf_pos = 0; + wavstream[idx].volume[0] = volume_left * GetSfxVolume(); + wavstream[idx].volume[1] = volume_right * GetSfxVolume(); + wavstream[idx].op = op; + wavstream[idx].identifier = identifier; + wavstream[idx].targetVolume[0] = volume_left * GetSfxVolume(); + wavstream[idx].targetVolume[1] = volume_right * GetSfxVolume(); + wavstream[idx].rateOfChange[0] = wavstream[idx].rateOfChange[1] = 0.0f; + SDL_UnlockAudio(); + return identifier++; } - wavstream[idx].sample = GetSample(fx); - wavstream[idx].oggv = 0; - wavstream[idx].buf_pos = 0; - wavstream[idx].volume[0] = volume_left * GetSfxVolume(); - wavstream[idx].volume[1] = volume_right * GetSfxVolume(); - wavstream[idx].op = op; - wavstream[idx].identifier = identifier; - wavstream[idx].targetVolume[0] = volume_left * GetSfxVolume(); - wavstream[idx].targetVolume[1] = volume_right * GetSfxVolume(); - wavstream[idx].rateOfChange[0] = wavstream[idx].rateOfChange[1] = 0.0f; - SDL_UnlockAudio(); - return identifier++; -} -//unlike PlaySfx, we want uninterrupted play and do not care about age -//alternate between two streams for crossfade -static int nextMusicStream = 0; -eventid PlayMusic(const char *fx, const float volume_left, const float volume_right, const Op op) -{ - const int idx = nextMusicStream; - nextMusicStream ^= 1; - SDL_LockAudio(); - if (wavstream[idx].sample) - DestroyEvent(&wavstream[idx]); - wavstream[idx].sample = GetSample(fx); - wavstream[idx].oggv = nullptr; - wavstream[idx].buf_pos = 0; - wavstream[idx].volume[0] = volume_left; - wavstream[idx].volume[1] = volume_right; - wavstream[idx].op = op; - wavstream[idx].identifier = identifier; - wavstream[idx].targetVolume[0] = volume_left; //already scaled in MusicPlayer - wavstream[idx].targetVolume[1] = volume_right; - wavstream[idx].rateOfChange[0] = wavstream[idx].rateOfChange[1] = 0.0f; - SDL_UnlockAudio(); - return identifier++; -} + //unlike PlaySfx, we want uninterrupted play and do not care about age + //alternate between two streams for crossfade + static int nextMusicStream = 0; + eventid PlayMusic(const char *fx, const float volume_left, const float volume_right, const Op op) + { + const int idx = nextMusicStream; + nextMusicStream ^= 1; + SDL_LockAudio(); + if (wavstream[idx].sample) + DestroyEvent(&wavstream[idx]); + wavstream[idx].sample = GetSample(fx); + wavstream[idx].oggv = nullptr; + wavstream[idx].buf_pos = 0; + wavstream[idx].volume[0] = volume_left; + wavstream[idx].volume[1] = volume_right; + wavstream[idx].op = op; + wavstream[idx].identifier = identifier; + wavstream[idx].targetVolume[0] = volume_left; //already scaled in MusicPlayer + wavstream[idx].targetVolume[1] = volume_right; + wavstream[idx].rateOfChange[0] = wavstream[idx].rateOfChange[1] = 0.0f; + SDL_UnlockAudio(); + return identifier++; + } -/* + /* * len is the number of floats to put in buffer, NOT full samples (a sample would be 2 floats since stereo) */ -template -static void fill_audio_1stream(float *buffer, int len, int stream_num) -{ - // inbuf will be smaller for mono and for 22050hz samples - Sint16 *inbuf = static_cast(alloca(len*T_channels / T_upsample)); - // hm pity to put this here ^^ since not used by ev.sample->buf case - SoundEvent &ev = wavstream[stream_num]; - int inbuf_pos = 0; - int pos = 0; - while ((pos < len) && ev.sample) { - if (ev.sample->buf) { - // already decoded - inbuf = reinterpret_cast(ev.sample->buf); - inbuf_pos = ev.buf_pos; - } else { - // stream ogg vorbis - // ogg vorbis streaming - if (!ev.oggv) { - // open file to start streaming - ev.oggv = new OggVorbis_File; - RefCountedPtr oggdata = FileSystem::gameDataFiles.ReadFile(ev.sample->path); - if (!oggdata) { - Output("Could not open '%s'", ev.sample->path.c_str()); - ev.sample = nullptr; - return; + template + static void fill_audio_1stream(float *buffer, int len, int stream_num) + { + // inbuf will be smaller for mono and for 22050hz samples + Sint16 *inbuf = static_cast(alloca(len * T_channels / T_upsample)); + // hm pity to put this here ^^ since not used by ev.sample->buf case + SoundEvent &ev = wavstream[stream_num]; + int inbuf_pos = 0; + int pos = 0; + while ((pos < len) && ev.sample) { + if (ev.sample->buf) { + // already decoded + inbuf = reinterpret_cast(ev.sample->buf); + inbuf_pos = ev.buf_pos; + } else { + // stream ogg vorbis + // ogg vorbis streaming + if (!ev.oggv) { + // open file to start streaming + ev.oggv = new OggVorbis_File; + RefCountedPtr oggdata = FileSystem::gameDataFiles.ReadFile(ev.sample->path); + if (!oggdata) { + Output("Could not open '%s'", ev.sample->path.c_str()); + ev.sample = nullptr; + return; + } + ev.ogg_data_stream.Reset(oggdata); + oggdata.Reset(); + if (ov_open_callbacks(&ev.ogg_data_stream, ev.oggv, 0, 0, OggFileDataStream::CALLBACKS) < 0) { + Output("Vorbis could not understand '%s'", ev.sample->path.c_str()); + ev.sample = nullptr; + return; + } } - ev.ogg_data_stream.Reset(oggdata); - oggdata.Reset(); - if (ov_open_callbacks(&ev.ogg_data_stream, ev.oggv, 0, 0, OggFileDataStream::CALLBACKS) < 0) { - Output("Vorbis could not understand '%s'", ev.sample->path.c_str()); - ev.sample = nullptr; - return; + int i = 0; + // (len-pos) = num floats the destination buffer wants. + // if we are stereo then to fill this we need (len-pos)*2 bytes + // if we are mono we want (len-pos) bytes + int wanted_bytes = (len - pos) * T_channels / T_upsample; + for (;;) { + int music_section; + if (wanted_bytes == 0) break; + int amt = ov_read(ev.oggv, reinterpret_cast(inbuf) + i, + wanted_bytes, 0, 2, 1, &music_section); + i += amt; + wanted_bytes -= amt; + if (amt == 0) break; } } - int i=0; - // (len-pos) = num floats the destination buffer wants. - // if we are stereo then to fill this we need (len-pos)*2 bytes - // if we are mono we want (len-pos) bytes - int wanted_bytes = (len-pos)*T_channels / T_upsample; + + while (pos < len) { + /* Volume animations */ + for (int chan = 0; chan < 2; chan++) { + if (ev.ascend[chan]) { + ev.volume[chan] = std::min(ev.volume[chan] + ev.rateOfChange[chan], ev.targetVolume[chan]); + } else { + ev.volume[chan] = std::max(ev.volume[chan] - ev.rateOfChange[chan], ev.targetVolume[chan]); + } + } + + float s0, s1; + + if (T_channels == 1) { + s0 = float(inbuf[inbuf_pos++]); + s1 = ev.volume[1] * s0; + s0 = ev.volume[0] * s0; + ev.buf_pos += 1; + } else /* stereo */ { + s0 = ev.volume[0] * float(inbuf[inbuf_pos++]); + s1 = ev.volume[1] * float(inbuf[inbuf_pos++]); + ev.buf_pos += 2; + } + + if (T_upsample == 1) { + buffer[pos] += s0; + buffer[pos + 1] += s1; + pos += 2; + } else { + buffer[pos] += s0; + buffer[pos + 1] += s1; + buffer[pos + 2] += s0; + buffer[pos + 3] += s1; + pos += 4; + } + + /* Repeat or end? */ + if (ev.buf_pos >= ev.sample->buf_len) { + ev.buf_pos = 0; + inbuf_pos = 0; + if (!(ev.op & OP_REPEAT)) { + DestroyEvent(&ev); + break; + } + if (ev.oggv) { + // streaming ogg + ov_pcm_seek(ev.oggv, 0); + // repeat outer loop to decode some + // more vorbis from the start of the stream + break; + } + } + } + } + } + + static void fill_audio(void *udata, Uint8 *dsp_buf, int len) + { + const int len_in_floats = len >> 1; + float *tmpbuf = static_cast(alloca(sizeof(float) * len_in_floats)); // len is in chars not samples + memset(static_cast(tmpbuf), 0, sizeof(float) * len_in_floats); + + for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { + if (!wavstream[i].sample) continue; + + wavstream[i].ascend[0] = (wavstream[i].targetVolume[0] > wavstream[i].volume[0]); + wavstream[i].ascend[1] = (wavstream[i].targetVolume[1] > wavstream[i].volume[1]); + + if (wavstream[i].op & OP_STOP_AT_TARGET_VOLUME) { + if (wavstream[i].ascend[0] && wavstream[i].ascend[1]) { + if ((wavstream[i].targetVolume[0] <= wavstream[i].volume[0]) && + (wavstream[i].targetVolume[1] <= wavstream[i].volume[1])) { + DestroyEvent(&wavstream[i]); + continue; + } + } else { + if ((wavstream[i].targetVolume[0] >= wavstream[i].volume[0]) && + (wavstream[i].targetVolume[1] >= wavstream[i].volume[1])) { + DestroyEvent(&wavstream[i]); + continue; + } + } + } + + if (wavstream[i].sample->channels == 1) { + if (wavstream[i].sample->upsample == 1) { + fill_audio_1stream<1, 1>(tmpbuf, len_in_floats, i); + } else { + fill_audio_1stream<1, 2>(tmpbuf, len_in_floats, i); + } + } else { + if (wavstream[i].sample->upsample == 1) { + fill_audio_1stream<2, 1>(tmpbuf, len_in_floats, i); + } else { + fill_audio_1stream<2, 2>(tmpbuf, len_in_floats, i); + } + } + } + + /* Convert float sample buffer to Sint16 samples the hardware likes */ + for (int pos = 0; pos < len_in_floats; pos++) { + const float val = m_masterVol * tmpbuf[pos]; + (reinterpret_cast(dsp_buf))[pos] = Sint16(Clamp(val, -32768.0f, 32767.0f)); + } + } + + void DestroyAllEvents() + { + /* silence any sound events */ + SDL_LockAudio(); + for (unsigned int idx = 0; idx < MAX_WAVSTREAMS; idx++) { + DestroyEvent(&wavstream[idx]); + } + SDL_UnlockAudio(); + } + + static void load_sound(const std::string &basename, const std::string &path, bool is_music) + { + if (!ends_with_ci(basename, ".ogg")) return; + + Sample sample; + OggVorbis_File oggv; + + RefCountedPtr oggdata = FileSystem::gameDataFiles.ReadFile(path); + if (!oggdata) { + Error("Could not read '%s'", path.c_str()); + } + OggFileDataStream datastream(oggdata); + oggdata.Reset(); + if (ov_open_callbacks(&datastream, &oggv, 0, 0, OggFileDataStream::CALLBACKS) < 0) { + Error("Vorbis could not understand '%s'", path.c_str()); + } + struct vorbis_info *info; + info = ov_info(&oggv, -1); + + if ((static_cast(info->rate) != FREQ) && (static_cast(info->rate) != (FREQ >> 1))) { + Error("Vorbis file %s is not %dHz or %dHz. Bad!", path.c_str(), FREQ, FREQ >> 1); + } + if ((info->channels < 1) || (info->channels > 2)) { + Error("Vorbis file %s is not mono or stereo. Bad!", path.c_str()); + } + + int resample_multiplier = ((info->rate == (FREQ >> 1)) ? 2 : 1); + const Sint64 num_samples = ov_pcm_total(&oggv, -1); + // since samples are 16 bits we have: + + sample.buf = 0; + sample.buf_len = num_samples * info->channels; + sample.channels = info->channels; + sample.upsample = resample_multiplier; + sample.path = path; + + const float seconds = num_samples / float(info->rate); + //Output("%f seconds\n", seconds); + + // immediately decode and store as raw sample if short enough + if (seconds < STREAM_IF_LONGER_THAN) { + sample.buf = new Uint16[sample.buf_len]; + + int i = 0; for (;;) { int music_section; - if (wanted_bytes == 0) break; - int amt = ov_read(ev.oggv, reinterpret_cast(inbuf) + i, - wanted_bytes, 0, 2, 1, &music_section); + int amt = ov_read(&oggv, reinterpret_cast(sample.buf) + i, + 2 * sample.buf_len - i, 0, 2, 1, &music_section); i += amt; - wanted_bytes -= amt; if (amt == 0) break; } } - while (pos < len) { - /* Volume animations */ - for (int chan=0; chan<2; chan++) { - if (ev.ascend[chan]) { - ev.volume[chan] = std::min(ev.volume[chan] + ev.rateOfChange[chan], ev.targetVolume[chan]); - } else { - ev.volume[chan] = std::max(ev.volume[chan] - ev.rateOfChange[chan], ev.targetVolume[chan]); - } - } - - float s0, s1; - - if (T_channels == 1) { - s0 = float(inbuf[inbuf_pos++]); - s1 = ev.volume[1] * s0; - s0 = ev.volume[0] * s0; - ev.buf_pos += 1; - } else /* stereo */ { - s0 = ev.volume[0] * float(inbuf[inbuf_pos++]); - s1 = ev.volume[1] * float(inbuf[inbuf_pos++]); - ev.buf_pos += 2; - } - - if (T_upsample == 1) { - buffer[pos] += s0; - buffer[pos+1] += s1; - pos += 2; - } else { - buffer[pos] += s0; - buffer[pos+1] += s1; - buffer[pos+2] += s0; - buffer[pos+3] += s1; - pos += 4; - } - - /* Repeat or end? */ - if (ev.buf_pos >= ev.sample->buf_len) { - ev.buf_pos = 0; - inbuf_pos = 0; - if (!(ev.op & OP_REPEAT)) { - DestroyEvent(&ev); - break; - } - if (ev.oggv) { - // streaming ogg - ov_pcm_seek(ev.oggv, 0); - // repeat outer loop to decode some - // more vorbis from the start of the stream - break; - } - } - } - } -} - -static void fill_audio(void *udata, Uint8 *dsp_buf, int len) -{ - const int len_in_floats = len>>1; - float *tmpbuf = static_cast(alloca(sizeof(float)*len_in_floats)); // len is in chars not samples - memset(static_cast(tmpbuf), 0, sizeof(float)*len_in_floats); - - for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { - if (!wavstream[i].sample) continue; - - wavstream[i].ascend[0] = (wavstream[i].targetVolume[0] > wavstream[i].volume[0]); - wavstream[i].ascend[1] = (wavstream[i].targetVolume[1] > wavstream[i].volume[1]); - - if (wavstream[i].op & OP_STOP_AT_TARGET_VOLUME) { - if (wavstream[i].ascend[0] && wavstream[i].ascend[1]) { - if ((wavstream[i].targetVolume[0] <= wavstream[i].volume[0]) && - (wavstream[i].targetVolume[1] <= wavstream[i].volume[1])) { - DestroyEvent(&wavstream[i]); - continue; - } - } else { - if ((wavstream[i].targetVolume[0] >= wavstream[i].volume[0]) && - (wavstream[i].targetVolume[1] >= wavstream[i].volume[1])) { - DestroyEvent(&wavstream[i]); - continue; - } - } - } - - if (wavstream[i].sample->channels == 1) { - if (wavstream[i].sample->upsample == 1) { - fill_audio_1stream<1,1>(tmpbuf, len_in_floats, i); - } else { - fill_audio_1stream<1,2>(tmpbuf, len_in_floats, i); - } + if (is_music) { + sample.isMusic = true; + // music keyed by pathname minus (datapath)/music/ and extension + sfx_samples[path.substr(0, path.size() - 4)] = sample; } else { - if (wavstream[i].sample->upsample == 1) { - fill_audio_1stream<2,1>(tmpbuf, len_in_floats, i); - } else { - fill_audio_1stream<2,2>(tmpbuf, len_in_floats, i); + sample.isMusic = false; + // sfx keyed by basename minus the .ogg + sfx_samples[basename.substr(0, basename.size() - 4)] = sample; + } + + ov_clear(&oggv); + } + + bool Init() + { + static bool isInitted = false; + + if (!isInitted) { + isInitted = true; + SDL_AudioSpec wanted; + + if (SDL_Init(SDL_INIT_AUDIO) == -1) { + Output("Count not initialise SDL: %s.\n", SDL_GetError()); + return false; + } + + wanted.freq = FREQ; + wanted.channels = 2; + wanted.format = AUDIO_S16; + wanted.samples = BUF_SIZE; + wanted.callback = fill_audio; + wanted.userdata = 0; + + if (SDL_OpenAudio(&wanted, 0) < 0) { + Output("Could not open audio: %s\n", SDL_GetError()); + return false; + } + + // load all the wretched effects + for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "sounds", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { + const FileSystem::FileInfo &info = files.Current(); + assert(info.IsFile()); + load_sound(info.GetName(), info.GetPath(), false); + } + + //I'd rather do this in MusicPlayer and store in a different map too, this will do for now + for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "music", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { + const FileSystem::FileInfo &info = files.Current(); + assert(info.IsFile()); + load_sound(info.GetName(), info.GetPath(), true); } } + + /* silence any sound events */ + DestroyAllEvents(); + + return true; } - /* Convert float sample buffer to Sint16 samples the hardware likes */ - for (int pos=0; pos(dsp_buf))[pos] = Sint16(Clamp(val, -32768.0f, 32767.0f)); - } -} - -void DestroyAllEvents() -{ - /* silence any sound events */ - SDL_LockAudio(); - for (unsigned int idx = 0; idx < MAX_WAVSTREAMS; idx++) { - DestroyEvent(&wavstream[idx]); - } - SDL_UnlockAudio(); -} - -static void load_sound(const std::string &basename, const std::string &path, bool is_music) -{ - if (!ends_with_ci(basename, ".ogg")) return; - - Sample sample; - OggVorbis_File oggv; - - RefCountedPtr oggdata = FileSystem::gameDataFiles.ReadFile(path); - if (!oggdata) { - Error("Could not read '%s'", path.c_str()); - } - OggFileDataStream datastream(oggdata); - oggdata.Reset(); - if (ov_open_callbacks(&datastream, &oggv, 0, 0, OggFileDataStream::CALLBACKS) < 0) { - Error("Vorbis could not understand '%s'", path.c_str()); - } - struct vorbis_info *info; - info = ov_info(&oggv, -1); - - if ((static_cast(info->rate) != FREQ) && (static_cast(info->rate) != (FREQ>>1))) { - Error("Vorbis file %s is not %dHz or %dHz. Bad!", path.c_str(), FREQ, FREQ>>1); - } - if ((info->channels < 1) || (info->channels > 2)) { - Error("Vorbis file %s is not mono or stereo. Bad!", path.c_str()); + void Uninit() + { + DestroyAllEvents(); + std::map::iterator i; + for (i = sfx_samples.begin(); i != sfx_samples.end(); ++i) + delete[](*i).second.buf; + SDL_CloseAudio(); } - int resample_multiplier = ((info->rate == (FREQ>>1)) ? 2 : 1); - const Sint64 num_samples = ov_pcm_total(&oggv, -1); - // since samples are 16 bits we have: - - sample.buf = 0; - sample.buf_len = num_samples * info->channels; - sample.channels = info->channels; - sample.upsample = resample_multiplier; - sample.path = path; - - const float seconds = num_samples/float(info->rate); - //Output("%f seconds\n", seconds); - - // immediately decode and store as raw sample if short enough - if (seconds < STREAM_IF_LONGER_THAN) { - sample.buf = new Uint16[sample.buf_len]; - - int i=0; - for (;;) { - int music_section; - int amt = ov_read(&oggv, reinterpret_cast(sample.buf) + i, - 2*sample.buf_len - i, 0, 2, 1, &music_section); - i += amt; - if (amt == 0) break; - } + void Pause(int on) + { + SDL_PauseAudio(on); } - if (is_music) { - sample.isMusic = true; - // music keyed by pathname minus (datapath)/music/ and extension - sfx_samples[path.substr(0, path.size() - 4)] = sample; - } else { - sample.isMusic = false; - // sfx keyed by basename minus the .ogg - sfx_samples[basename.substr(0, basename.size()-4)] = sample; + void Event::Play(const char *fx, float volume_left, float volume_right, Op op) + { + Stop(); + eid = PlaySfx(fx, volume_left, volume_right, op); } - ov_clear(&oggv); -} - -bool Init () -{ - static bool isInitted = false; - - if (!isInitted) { - isInitted = true; - SDL_AudioSpec wanted; - - if (SDL_Init (SDL_INIT_AUDIO) == -1) { - Output("Count not initialise SDL: %s.\n", SDL_GetError ()); + bool Event::Stop() + { + if (eid) { + SDL_LockAudio(); + SoundEvent *s = GetEvent(eid); + if (s) { + DestroyEvent(s); + } + SDL_UnlockAudio(); + return s != nullptr; + } else { return false; } - - wanted.freq = FREQ; - wanted.channels = 2; - wanted.format = AUDIO_S16; - wanted.samples = BUF_SIZE; - wanted.callback = fill_audio; - wanted.userdata = 0; - - if (SDL_OpenAudio (&wanted, 0) < 0) { - Output("Could not open audio: %s\n", SDL_GetError ()); - return false; - } - - // load all the wretched effects - for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "sounds", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { - const FileSystem::FileInfo &info = files.Current(); - assert(info.IsFile()); - load_sound(info.GetName(), info.GetPath(), false); - } - - //I'd rather do this in MusicPlayer and store in a different map too, this will do for now - for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "music", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { - const FileSystem::FileInfo &info = files.Current(); - assert(info.IsFile()); - load_sound(info.GetName(), info.GetPath(), true); - } } - /* silence any sound events */ - DestroyAllEvents(); + bool Event::IsPlaying() const + { + if (eid == 0) + return false; + else + return GetEvent(eid) != nullptr; + } - return true; -} - -void Uninit () -{ - DestroyAllEvents(); - std::map::iterator i; - for (i=sfx_samples.begin(); i!=sfx_samples.end(); ++i) delete[] (*i).second.buf; - SDL_CloseAudio (); -} - -void Pause (int on) -{ - SDL_PauseAudio (on); -} - -void Event::Play(const char *fx, float volume_left, float volume_right, Op op) -{ - Stop(); - eid = PlaySfx(fx, volume_left, volume_right, op); -} - -bool Event::Stop() -{ - if (eid) { + bool Event::SetOp(Op op) + { + if (eid == 0) return false; + bool ret = false; SDL_LockAudio(); - SoundEvent *s = GetEvent(eid); - if (s) { - DestroyEvent(s); + SoundEvent *se = GetEvent(eid); + if (se) { + se->op = op; + ret = true; } SDL_UnlockAudio(); - return s != nullptr; - } else { - return false; + return ret; } -} -bool Event::IsPlaying() const -{ - if (eid == 0) return false; - else return GetEvent(eid) != nullptr; -} - -bool Event::SetOp(Op op) { - if (eid == 0) return false; - bool ret = false; - SDL_LockAudio(); - SoundEvent *se = GetEvent(eid); - if (se) { - se->op = op; - ret = true; - } - SDL_UnlockAudio(); - return ret; -} - -bool Event::VolumeAnimate(const float targetVol1, const float targetVol2, const float dv_dt1, const float dv_dt2) -{ - SDL_LockAudio(); - SoundEvent *ev = GetEvent(eid); - if (ev) { - ev->targetVolume[0] = targetVol1; - ev->targetVolume[1] = targetVol2; - ev->rateOfChange[0] = dv_dt1 / float(FREQ); - ev->rateOfChange[1] = dv_dt2 / float(FREQ); - } - SDL_UnlockAudio(); - return (ev != nullptr); -} - -bool Event::SetVolume(const float vol_left, const float vol_right) -{ - SDL_LockAudio(); - bool status = false; - for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { - if (wavstream[i].sample && (wavstream[i].identifier == eid)) { - wavstream[i].volume[0] = vol_left; - wavstream[i].volume[1] = vol_right; - wavstream[i].targetVolume[0] = vol_left; - wavstream[i].targetVolume[1] = vol_right; - status = true; - break; + bool Event::VolumeAnimate(const float targetVol1, const float targetVol2, const float dv_dt1, const float dv_dt2) + { + SDL_LockAudio(); + SoundEvent *ev = GetEvent(eid); + if (ev) { + ev->targetVolume[0] = targetVol1; + ev->targetVolume[1] = targetVol2; + ev->rateOfChange[0] = dv_dt1 / float(FREQ); + ev->rateOfChange[1] = dv_dt2 / float(FREQ); } + SDL_UnlockAudio(); + return (ev != nullptr); } - SDL_UnlockAudio(); - return status; -} -const std::map & GetSamples() -{ - return sfx_samples; -} + bool Event::SetVolume(const float vol_left, const float vol_right) + { + SDL_LockAudio(); + bool status = false; + for (unsigned int i = 0; i < MAX_WAVSTREAMS; i++) { + if (wavstream[i].sample && (wavstream[i].identifier == eid)) { + wavstream[i].volume[0] = vol_left; + wavstream[i].volume[1] = vol_right; + wavstream[i].targetVolume[0] = vol_left; + wavstream[i].targetVolume[1] = vol_right; + status = true; + break; + } + } + SDL_UnlockAudio(); + return status; + } + + const std::map &GetSamples() + { + return sfx_samples; + } } /* namespace Sound */ diff --git a/src/Sound.h b/src/Sound.h index e485183c4..505f84f7e 100644 --- a/src/Sound.h +++ b/src/Sound.h @@ -1,76 +1,80 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt - #ifndef __OGGMIX_H #define __OGGMIX_H -#include +#include #include +#include class Body; namespace Sound { -enum { - OP_REPEAT = (1<<0), - OP_STOP_AT_TARGET_VOLUME = (1<<1) -}; -typedef Uint32 Op; + enum { + OP_REPEAT = (1 << 0), + OP_STOP_AT_TARGET_VOLUME = (1 << 1) + }; + typedef Uint32 Op; -struct Sample { - Uint16 *buf; - Uint32 buf_len; - Uint32 channels; - int upsample; // 1 = 44100, 2=22050 - /* if buf is null, this will be path to an ogg we must stream */ - std::string path; - bool isMusic; -}; + struct Sample { + Uint16 *buf; + Uint32 buf_len; + Uint32 channels; + int upsample; // 1 = 44100, 2=22050 + /* if buf is null, this will be path to an ogg we must stream */ + std::string path; + bool isMusic; + }; -class Event { -public: - Event(): eid(0) {} - Event(Uint32 id): eid(id) {} - virtual void Play(const char *fx, const float volume_left, const float volume_right, Op op); - void Play(const char *fx) { Play(fx, 1.0f, 1.0f, 0); } - bool Stop(); - bool IsPlaying() const; - Uint32 EventId() { return eid; } - bool SetOp(Op op); - bool VolumeAnimate(const float targetVol1, const float targetVol2, const float dv_dt1, const float dv_dt2); - bool VolumeAnimate(const float targetVols[2], const float dv_dt[2]) { - return VolumeAnimate(targetVols[0], targetVols[1], + class Event { + public: + Event() : + eid(0) {} + Event(Uint32 id) : + eid(id) {} + virtual void Play(const char *fx, const float volume_left, const float volume_right, Op op); + void Play(const char *fx) { Play(fx, 1.0f, 1.0f, 0); } + bool Stop(); + bool IsPlaying() const; + Uint32 EventId() { return eid; } + bool SetOp(Op op); + bool VolumeAnimate(const float targetVol1, const float targetVol2, const float dv_dt1, const float dv_dt2); + bool VolumeAnimate(const float targetVols[2], const float dv_dt[2]) + { + return VolumeAnimate(targetVols[0], targetVols[1], dv_dt[0], dv_dt[1]); - } - bool SetVolume(const float vol_left, const float vol_right); - bool SetVolume(const float vol) { - return SetVolume(vol, vol); - } -protected: - Uint32 eid; -}; -typedef Uint32 eventid; + } + bool SetVolume(const float vol_left, const float vol_right); + bool SetVolume(const float vol) + { + return SetVolume(vol, vol); + } -bool Init (); -void Uninit (); -/** + protected: + Uint32 eid; + }; + typedef Uint32 eventid; + + bool Init(); + void Uninit(); + /** * Silence all active sound events. */ -void DestroyAllEvents(); -void Pause (int on); -eventid PlaySfx (const char *fx, const float volume_left, const float volume_right, const Op op); -eventid PlayMusic (const char *fx, const float volume_left, const float volume_right, const Op op); -inline static eventid PlaySfx (const char *fx) { return PlaySfx(fx, 1.0f, 1.0f, 0); } -void CalculateStereo(const Body *b, float vol, float *volLeftOut, float *volRightOut); -eventid BodyMakeNoise(const Body *b, const char *fx, float vol); -void SetMasterVolume(const float vol); -float GetMasterVolume(); -void SetSfxVolume(const float vol); -float GetSfxVolume(); -const std::map & GetSamples(); + void DestroyAllEvents(); + void Pause(int on); + eventid PlaySfx(const char *fx, const float volume_left, const float volume_right, const Op op); + eventid PlayMusic(const char *fx, const float volume_left, const float volume_right, const Op op); + inline static eventid PlaySfx(const char *fx) { return PlaySfx(fx, 1.0f, 1.0f, 0); } + void CalculateStereo(const Body *b, float vol, float *volLeftOut, float *volRightOut); + eventid BodyMakeNoise(const Body *b, const char *fx, float vol); + void SetMasterVolume(const float vol); + float GetMasterVolume(); + void SetSfxVolume(const float vol); + float GetSfxVolume(); + const std::map &GetSamples(); } /* namespace Sound */ #endif /* __OGGMIX_H */ - diff --git a/src/SoundMusic.cpp b/src/SoundMusic.cpp index 261f2c314..bae104ad9 100644 --- a/src/SoundMusic.cpp +++ b/src/SoundMusic.cpp @@ -2,136 +2,136 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "SoundMusic.h" -#include "libs.h" //for clamp -#include "Pi.h" #include "LuaEvent.h" +#include "Pi.h" +#include "libs.h" //for clamp #include namespace Sound { -MusicEvent::MusicEvent() : Event() { } + MusicEvent::MusicEvent() : + Event() {} -MusicEvent::MusicEvent(Uint32 id) : Event(id) { } + MusicEvent::MusicEvent(Uint32 id) : + Event(id) {} -MusicEvent::~MusicEvent() { } + MusicEvent::~MusicEvent() {} -void MusicEvent::Play(const char *fx, const float volume_left, const float volume_right, Op op) -{ - Stop(); - eid = PlayMusic(fx, volume_left, volume_right, op); -} - -MusicPlayer::MusicPlayer() : - m_volume(0.8f), - m_playing(false), - m_eventOnePlaying(false), - m_currentSongName(""), - m_enabled(true) -{ - -} - -MusicPlayer::~MusicPlayer() -{ - -} - -float MusicPlayer::GetVolume() const -{ - return m_volume; -} - -void MusicPlayer::SetVolume(const float vol) -{ - m_volume = Clamp(vol, 0.f, 1.f); - //the other song might be fading out so don't set its volume - if (m_eventOnePlaying && m_eventOne.IsPlaying()) - m_eventOne.SetVolume(m_volume); - else if (m_eventTwo.IsPlaying()) - m_eventTwo.SetVolume(m_volume); -} - -void MusicPlayer::Play(const std::string& name, const bool repeat /* = false */ , const float fadeDelta /* = 1.f */ ) -{ - if (!m_enabled) return; - Sound::Op op = 0; - if (repeat) - op |= Sound::OP_REPEAT; - if (m_eventOnePlaying) { - m_eventOne.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); - m_eventOne.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); - m_eventTwo.Play(name.c_str(), 0.f, 0.f, op); - m_eventTwo.VolumeAnimate(m_volume, m_volume, fadeDelta, fadeDelta); - m_eventOnePlaying = false; - } else { - m_eventTwo.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); - m_eventTwo.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); - m_eventOne.Play(name.c_str(), 0.f, 0.f, op); - m_eventOne.VolumeAnimate(m_volume, m_volume, fadeDelta, fadeDelta); - m_eventOnePlaying = true; + void MusicEvent::Play(const char *fx, const float volume_left, const float volume_right, Op op) + { + Stop(); + eid = PlayMusic(fx, volume_left, volume_right, op); } - m_playing = true; - m_currentSongName = name; -} -void MusicPlayer::Stop() -{ - m_eventOne.Stop(); - m_eventTwo.Stop(); - m_playing = false; -} - -void MusicPlayer::FadeOut(const float fadeDelta) -{ - if (m_eventOnePlaying) {//2 might be already fading out - m_eventOne.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); - m_eventOne.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); - } else { // 1 might be already fading out - m_eventTwo.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); - m_eventTwo.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); + MusicPlayer::MusicPlayer() : + m_volume(0.8f), + m_playing(false), + m_eventOnePlaying(false), + m_currentSongName(""), + m_enabled(true) + { } -} -void MusicPlayer::Update() -{ - PROFILE_SCOPED() - if (m_playing) { //expecting report - if ((m_eventOnePlaying && !m_eventOne.IsPlaying()) || (!m_eventOnePlaying && !m_eventTwo.IsPlaying())) { - m_playing = false; - LuaEvent::Queue("onSongFinished"); + MusicPlayer::~MusicPlayer() + { + } + + float MusicPlayer::GetVolume() const + { + return m_volume; + } + + void MusicPlayer::SetVolume(const float vol) + { + m_volume = Clamp(vol, 0.f, 1.f); + //the other song might be fading out so don't set its volume + if (m_eventOnePlaying && m_eventOne.IsPlaying()) + m_eventOne.SetVolume(m_volume); + else if (m_eventTwo.IsPlaying()) + m_eventTwo.SetVolume(m_volume); + } + + void MusicPlayer::Play(const std::string &name, const bool repeat /* = false */, const float fadeDelta /* = 1.f */) + { + if (!m_enabled) return; + Sound::Op op = 0; + if (repeat) + op |= Sound::OP_REPEAT; + if (m_eventOnePlaying) { + m_eventOne.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); + m_eventOne.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); + m_eventTwo.Play(name.c_str(), 0.f, 0.f, op); + m_eventTwo.VolumeAnimate(m_volume, m_volume, fadeDelta, fadeDelta); + m_eventOnePlaying = false; + } else { + m_eventTwo.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); + m_eventTwo.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); + m_eventOne.Play(name.c_str(), 0.f, 0.f, op); + m_eventOne.VolumeAnimate(m_volume, m_volume, fadeDelta, fadeDelta); + m_eventOnePlaying = true; + } + m_playing = true; + m_currentSongName = name; + } + + void MusicPlayer::Stop() + { + m_eventOne.Stop(); + m_eventTwo.Stop(); + m_playing = false; + } + + void MusicPlayer::FadeOut(const float fadeDelta) + { + if (m_eventOnePlaying) { //2 might be already fading out + m_eventOne.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); + m_eventOne.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); + } else { // 1 might be already fading out + m_eventTwo.SetOp(Sound::OP_STOP_AT_TARGET_VOLUME); + m_eventTwo.VolumeAnimate(0.f, 0.f, fadeDelta, fadeDelta); } } -} -const std::string MusicPlayer::GetCurrentSongName() const -{ - return m_currentSongName; -} - -const std::vector MusicPlayer::GetSongList() const -{ - using std::string; - using std::pair; - std::vector songs; - const std::map samples = Sound::GetSamples(); - for (std::map::const_iterator it = samples.begin(); - it != samples.end(); ++it) { - if (it->second.isMusic) - songs.push_back(it->first.c_str()); + void MusicPlayer::Update() + { + PROFILE_SCOPED() + if (m_playing) { //expecting report + if ((m_eventOnePlaying && !m_eventOne.IsPlaying()) || (!m_eventOnePlaying && !m_eventTwo.IsPlaying())) { + m_playing = false; + LuaEvent::Queue("onSongFinished"); + } + } } - return songs; -} + const std::string MusicPlayer::GetCurrentSongName() const + { + return m_currentSongName; + } -bool MusicPlayer::IsPlaying() const -{ - return (m_eventOne.IsPlaying() || m_eventTwo.IsPlaying()); -} + const std::vector MusicPlayer::GetSongList() const + { + using std::pair; + using std::string; + std::vector songs; + const std::map samples = Sound::GetSamples(); + for (std::map::const_iterator it = samples.begin(); + it != samples.end(); ++it) { + if (it->second.isMusic) + songs.push_back(it->first.c_str()); + } -void MusicPlayer::SetEnabled(const bool en) -{ - m_enabled = en; - if (!en && IsPlaying()) Stop(); -} + return songs; + } -} /* namespace sound */ + bool MusicPlayer::IsPlaying() const + { + return (m_eventOne.IsPlaying() || m_eventTwo.IsPlaying()); + } + + void MusicPlayer::SetEnabled(const bool en) + { + m_enabled = en; + if (!en && IsPlaying()) Stop(); + } + +} // namespace Sound diff --git a/src/SoundMusic.h b/src/SoundMusic.h index 4db101285..813932545 100644 --- a/src/SoundMusic.h +++ b/src/SoundMusic.h @@ -4,15 +4,13 @@ #ifndef _MUSIC_H #define _MUSIC_H -#include #include "Sound.h" +#include #include #include -namespace Sound -{ - class MusicEvent : public Event - { +namespace Sound { + class MusicEvent : public Event { public: MusicEvent(); MusicEvent(Uint32 id); @@ -20,14 +18,13 @@ namespace Sound virtual void Play(const char *fx, const float volume_left, const float volume_right, Op op); }; - class MusicPlayer - { + class MusicPlayer { public: MusicPlayer(); ~MusicPlayer(); float GetVolume() const; void SetVolume(const float); - void Play(const std::string&, const bool repeat = false, const float fadeDelta = 1.f); + void Play(const std::string &, const bool repeat = false, const float fadeDelta = 1.f); void Stop(); void FadeOut(const float fadeDelta); void Update(); @@ -35,6 +32,7 @@ namespace Sound const std::vector GetSongList() const; bool IsPlaying() const; void SetEnabled(bool); + private: float m_volume; //two streams for crossfade @@ -45,6 +43,6 @@ namespace Sound std::string m_currentSongName; bool m_enabled; }; -} +} // namespace Sound #endif diff --git a/src/Space.cpp b/src/Space.cpp index 70cbfa520..3456bd6d4 100644 --- a/src/Space.cpp +++ b/src/Space.cpp @@ -1,30 +1,30 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Space.h" #include "Body.h" -#include "Frame.h" -#include "Star.h" -#include "Planet.h" #include "CityOnPlanet.h" -#include -#include +#include "Frame.h" +#include "Game.h" +#include "HyperspaceCloud.h" +#include "Lang.h" +#include "LuaEvent.h" +#include "MathUtil.h" +#include "Missile.h" #include "Pi.h" +#include "Planet.h" #include "Player.h" +#include "SectorView.h" +#include "SpaceStation.h" +#include "Star.h" +#include "WorldView.h" +#include "collider/collider.h" #include "galaxy/Galaxy.h" #include "galaxy/StarSystem.h" -#include "SpaceStation.h" -#include "collider/collider.h" -#include "Missile.h" -#include "HyperspaceCloud.h" #include "graphics/Graphics.h" -#include "WorldView.h" -#include "SectorView.h" -#include "Lang.h" -#include "Game.h" -#include "MathUtil.h" -#include "LuaEvent.h" +#include "libs.h" +#include +#include //#define DEBUG_CACHE @@ -32,7 +32,7 @@ void Space::BodyNearFinder::Prepare() { m_bodyDist.clear(); - for (Body* b : m_space->GetBodies()) + for (Body *b : m_space->GetBodies()) m_bodyDist.push_back(BodyDist(b, b->GetPositionRelTo(m_space->GetRootFrame()).Length())); std::sort(m_bodyDist.begin(), m_bodyDist.end()); @@ -49,8 +49,8 @@ void Space::BodyNearFinder::GetBodiesMaybeNear(const vector3d &pos, double dist, const double len = pos.Length(); - std::vector::const_iterator min = std::lower_bound(m_bodyDist.begin(), m_bodyDist.end(), len-dist); - std::vector::const_iterator max = std::upper_bound(min, m_bodyDist.end(), len+dist); + std::vector::const_iterator min = std::lower_bound(m_bodyDist.begin(), m_bodyDist.end(), len - dist); + std::vector::const_iterator max = std::upper_bound(min, m_bodyDist.end(), len + dist); while (min != max) { bodies.push_back((*min).body); @@ -58,15 +58,16 @@ void Space::BodyNearFinder::GetBodiesMaybeNear(const vector3d &pos, double dist, } } -Space::Space(Game *game, RefCountedPtr galaxy, Space* oldSpace) - : m_starSystemCache(oldSpace ? oldSpace->m_starSystemCache : galaxy->NewStarSystemSlaveCache()) - , m_game(game) - , m_frameIndexValid(false) - , m_bodyIndexValid(false) - , m_sbodyIndexValid(false) - , m_bodyNearFinder(this) +Space::Space(Game *game, RefCountedPtr galaxy, Space *oldSpace) : + m_starSystemCache(oldSpace ? oldSpace->m_starSystemCache : galaxy->NewStarSystemSlaveCache()), + m_game(game), + m_frameIndexValid(false), + m_bodyIndexValid(false), + m_sbodyIndexValid(false), + m_bodyNearFinder(this) #ifndef NDEBUG - , m_processingFinalizationQueue(false) + , + m_processingFinalizationQueue(false) #endif { m_background.reset(new Background::Container(Pi::renderer, Pi::rng)); @@ -77,16 +78,17 @@ Space::Space(Game *game, RefCountedPtr galaxy, Space* oldSpace) GenSectorCache(galaxy, &game->GetHyperspaceDest()); } -Space::Space(Game *game, RefCountedPtr galaxy, const SystemPath &path, Space* oldSpace) - : m_starSystemCache(oldSpace ? oldSpace->m_starSystemCache : galaxy->NewStarSystemSlaveCache()) - , m_starSystem(galaxy->GetStarSystem(path)) - , m_game(game) - , m_frameIndexValid(false) - , m_bodyIndexValid(false) - , m_sbodyIndexValid(false) - , m_bodyNearFinder(this) +Space::Space(Game *game, RefCountedPtr galaxy, const SystemPath &path, Space *oldSpace) : + m_starSystemCache(oldSpace ? oldSpace->m_starSystemCache : galaxy->NewStarSystemSlaveCache()), + m_starSystem(galaxy->GetStarSystem(path)), + m_game(game), + m_frameIndexValid(false), + m_bodyIndexValid(false), + m_sbodyIndexValid(false), + m_bodyNearFinder(this) #ifndef NDEBUG - , m_processingFinalizationQueue(false) + , + m_processingFinalizationQueue(false) #endif { Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED }; @@ -108,15 +110,16 @@ Space::Space(Game *game, RefCountedPtr galaxy, const SystemPath &path, S //DebugDumpFrames(); } -Space::Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, double at_time) - : m_starSystemCache(galaxy->NewStarSystemSlaveCache()) - , m_game(game) - , m_frameIndexValid(false) - , m_bodyIndexValid(false) - , m_sbodyIndexValid(false) - , m_bodyNearFinder(this) +Space::Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, double at_time) : + m_starSystemCache(galaxy->NewStarSystemSlaveCache()), + m_game(game), + m_frameIndexValid(false), + m_bodyIndexValid(false), + m_sbodyIndexValid(false), + m_bodyNearFinder(this) #ifndef NDEBUG - , m_processingFinalizationQueue(false) + , + m_processingFinalizationQueue(false) #endif { Json spaceObj = jsonObj["space"]; @@ -139,7 +142,7 @@ Space::Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, doub try { Json bodyArray = spaceObj["bodies"].get(); for (Uint32 i = 0; i < bodyArray.size(); i++) - m_bodies.push_back(Body::FromJson(bodyArray[i], this)); + m_bodies.push_back(Body::FromJson(bodyArray[i], this)); } catch (Json::type_error &) { throw SavedGameCorruptException(); } @@ -147,8 +150,8 @@ Space::Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, doub RebuildBodyIndex(); Frame::PostUnserializeFixup(m_rootFrame.get(), this); - for (Body* b : m_bodies) - b->PostLoadFixup(this); + for (Body *b : m_bodies) + b->PostLoadFixup(this); GenSectorCache(galaxy, &path); } @@ -156,7 +159,7 @@ Space::Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, doub Space::~Space() { UpdateBodies(); // make sure anything waiting to be removed gets removed before we go and kill everything else - for (std::list::iterator i = m_bodies.begin(); i != m_bodies.end(); ++i) + for (std::list::iterator i = m_bodies.begin(); i != m_bodies.end(); ++i) KillBody(*i); UpdateBodies(); } @@ -185,8 +188,7 @@ void Space::ToJson(Json &jsonObj) spaceObj["frame"] = frameObj; Json bodyArray = Json::array(); // Create JSON array to contain body data. - for (Body* b : m_bodies) - { + for (Body *b : m_bodies) { Json bodyArrayEl({}); // Create JSON object to contain body. b->ToJson(bodyArrayEl, this); bodyArray.push_back(bodyArrayEl); // Append body object to array. @@ -248,7 +250,7 @@ void Space::AddFrameToIndex(Frame *frame) { assert(frame); m_frameIndex.push_back(frame); - for (Frame* kid : frame->GetChildren()) + for (Frame *kid : frame->GetChildren()) AddFrameToIndex(kid); } @@ -276,13 +278,13 @@ void Space::RebuildBodyIndex() m_bodyIndex.clear(); m_bodyIndex.push_back(0); - for (Body* b : m_bodies) { + for (Body *b : m_bodies) { m_bodyIndex.push_back(b); // also index ships inside clouds // XXX we should not have to know about this. move indexing grunt work // down into the bodies? if (b->IsType(Object::HYPERSPACECLOUD)) { - Ship *s = static_cast(b)->GetShip(); + Ship *s = static_cast(b)->GetShip(); if (s) m_bodyIndex.push_back(s); } } @@ -316,7 +318,7 @@ void Space::RemoveBody(Body *b) m_removeBodies.push_back(b); } -void Space::KillBody(Body* b) +void Space::KillBody(Body *b) { #ifndef NDEBUG assert(!m_processingFinalizationQueue); @@ -336,7 +338,7 @@ void Space::KillBody(Body* b) } void Space::GetHyperspaceExitParams(const SystemPath &source, const SystemPath &dest, - vector3d &pos, vector3d &vel) const + vector3d &pos, vector3d &vel) const { assert(m_starSystem); assert(source.IsSystemPath()); @@ -357,13 +359,13 @@ void Space::GetHyperspaceExitParams(const SystemPath &source, const SystemPath & assert(dest.bodyIndex < m_starSystem->GetNumBodies()); primary = FindBodyForPath(&dest); while (primary && primary->GetSystemBody()->GetSuperType() != SystemBody::SUPERTYPE_STAR) { - SystemBody* parent = primary->GetSystemBody()->GetParent(); + SystemBody *parent = primary->GetSystemBody()->GetParent(); primary = parent ? FindBodyForPath(&parent->GetPath()) : 0; } } if (!primary) { // find the first non-gravpoint. should be the primary star - for (Body* b : GetBodies()) + for (Body *b : GetBodies()) if (b->GetSystemBody()->GetType() != SystemBody::TYPE_GRAVPOINT) { primary = b; break; @@ -372,13 +374,13 @@ void Space::GetHyperspaceExitParams(const SystemPath &source, const SystemPath & assert(primary); // calculate distance to primary body relative to body's mass and radius - const double max_orbit_vel=100e3; - double dist = G*primary->GetSystemBody()->GetMass() / - (max_orbit_vel*max_orbit_vel); - dist = std::max(dist, primary->GetSystemBody()->GetRadius()*10); + const double max_orbit_vel = 100e3; + double dist = G * primary->GetSystemBody()->GetMass() / + (max_orbit_vel * max_orbit_vel); + dist = std::max(dist, primary->GetSystemBody()->GetRadius() * 10); // ensure an absolut minimum distance - dist = std::max(dist, 0.2*AU); + dist = std::max(dist, 0.2 * AU); // point velocity vector along the line from source to dest, // make exit position perpendicular to it, @@ -386,13 +388,13 @@ void Space::GetHyperspaceExitParams(const SystemPath &source, const SystemPath & // set velocity for (almost) circular orbit vel = (destPos - sourcePos).Normalized(); { - vector3d a{MathUtil::OrthogonalDirection(vel)}; - vector3d b{vel.Cross(a)}; - vector3d p{MathUtil::RandomPointOnCircle(1.)}; - pos = p.x*a + p.y*b; + vector3d a{ MathUtil::OrthogonalDirection(vel) }; + vector3d b{ vel.Cross(a) }; + vector3d p{ MathUtil::RandomPointOnCircle(1.) }; + pos = p.x * a + p.y * b; } - pos *= dist*Pi::rng.Double(0.95,1.2); - vel *= sqrt(G*primary->GetSystemBody()->GetMass()/dist); + pos *= dist * Pi::rng.Double(0.95, 1.2); + vel *= sqrt(G * primary->GetSystemBody()->GetMass() / dist); assert(pos.Length() > primary->GetSystemBody()->GetRadius()); pos += primary->GetPositionRelTo(GetRootFrame()); @@ -402,7 +404,7 @@ Body *Space::FindNearestTo(const Body *b, Object::Type t) const { Body *nearest = 0; double dist = FLT_MAX; - for (std::list::const_iterator i = m_bodies.begin(); i != m_bodies.end(); ++i) { + for (std::list::const_iterator i = m_bodies.begin(); i != m_bodies.end(); ++i) { if ((*i)->IsDead()) continue; if ((*i)->IsType(t)) { double d = (*i)->GetPositionRelTo(b).Length(); @@ -422,7 +424,7 @@ Body *Space::FindBodyForPath(const SystemPath *path) const if (!body) return 0; - for (Body* b : m_bodies) { + for (Body *b : m_bodies) { if (b->GetSystemBody() == body) return b; } return 0; @@ -430,9 +432,10 @@ Body *Space::FindBodyForPath(const SystemPath *path) const static Frame *find_frame_with_sbody(Frame *f, const SystemBody *b) { - if (f->GetSystemBody() == b) return f; + if (f->GetSystemBody() == b) + return f; else { - for (Frame* kid : f->GetChildren()) { + for (Frame *kid : f->GetChildren()) { Frame *found = find_frame_with_sbody(kid, b); if (found) return found; } @@ -451,7 +454,7 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet // suggested position rot = sbody->GetOrbit().GetPlane(); - pos = rot * vector3d(0,1,0); + pos = rot * vector3d(0, 1, 0); // Check if height varies too much around the starport center // by sampling 6 points around it. try upto 100 new positions randomly until a match is found @@ -470,9 +473,9 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet // points must stay within max height variation to be accepted // 1. delta should be chosen such that it a distance from the starport center that encloses landing pads for the largest starport // 2. maxSlope should be set so maxHeightVariation is less than the height of the landing pads - const double delta = 20.0/radius; // in radii + const double delta = 20.0 / radius; // in radii const double maxSlope = 0.2; // 0.0 to 1.0 - const double maxHeightVariation = maxSlope*delta*radius; // in m + const double maxHeightVariation = maxSlope * delta * radius; // in m matrix3x3d rot_ = rot; vector3d pos_ = pos; @@ -487,8 +490,7 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet Random r(sbody->GetSeed()); - for (int tries = 0; tries < 200; tries++) - { + for (int tries = 0; tries < 200; tries++) { variationWithinLimits = true; const double height = planet->GetTerrainHeight(pos_) - radius; // in m @@ -497,18 +499,18 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet // GetHeight gives a varying height field in 3 dimensions. // Given it's smoothly varying it's fine to sample it in arbitary directions to get an idea of how sharply it varies double v[6]; - v[0] = fabs(planet->GetTerrainHeight(vector3d(pos_.x+delta, pos_.y, pos_.z))-radius-height); - v[1] = fabs(planet->GetTerrainHeight(vector3d(pos_.x-delta, pos_.y, pos_.z))-radius-height); - v[2] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y, pos_.z+delta))-radius-height); - v[3] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y, pos_.z-delta))-radius-height); - v[4] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y+delta, pos_.z))-radius-height); - v[5] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y-delta, pos_.z))-radius-height); + v[0] = fabs(planet->GetTerrainHeight(vector3d(pos_.x + delta, pos_.y, pos_.z)) - radius - height); + v[1] = fabs(planet->GetTerrainHeight(vector3d(pos_.x - delta, pos_.y, pos_.z)) - radius - height); + v[2] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y, pos_.z + delta)) - radius - height); + v[3] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y, pos_.z - delta)) - radius - height); + v[4] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y + delta, pos_.z)) - radius - height); + v[5] = fabs(planet->GetTerrainHeight(vector3d(pos_.x, pos_.y - delta, pos_.z)) - radius - height); // break if variation for all points is within limits double variationMax = 0.0; for (int i = 0; i < 6; i++) { variationWithinLimits = variationWithinLimits && (v[i] < maxHeightVariation); - variationMax = (v[i] > variationMax)? v[i]:variationMax; + variationMax = (v[i] > variationMax) ? v[i] : variationMax; } // check if underwater @@ -518,16 +520,15 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet // sbody->name.c_str(), tries, (variationWithinLimits && !starportUnderwater), bestVariation, variationMax, maxHeightVariation, starportUnderwater); bool tooCloseToOther = false; - for (vector3d oldPos : prevPositions) - { + for (vector3d oldPos : prevPositions) { // is the distance between points less than the delta distance? - if ((pos_ - oldPos).LengthSqr() < (delta*delta)) { + if ((pos_ - oldPos).LengthSqr() < (delta * delta)) { tooCloseToOther = true; // then we're too close so try again break; } } - if (tries == 0) { + if (tries == 0) { isInitiallyUnderwater = starportUnderwater; initialVariationTooHigh = !variationWithinLimits; } @@ -543,12 +544,10 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet // try new random position const double r3 = r.Double(); - const double r2 = r.Double(); // function parameter evaluation order is implementation-dependent - const double r1 = r.Double(); // can't put two rands in the same expression - rot_ = matrix3x3d::RotateZ(2.0*M_PI*r1) - * matrix3x3d::RotateY(2.0*M_PI*r2) - * matrix3x3d::RotateX(2.0*M_PI*r3); - pos_ = rot_ * vector3d(0,1,0); + const double r2 = r.Double(); // function parameter evaluation order is implementation-dependent + const double r1 = r.Double(); // can't put two rands in the same expression + rot_ = matrix3x3d::RotateZ(2.0 * M_PI * r1) * matrix3x3d::RotateY(2.0 * M_PI * r2) * matrix3x3d::RotateX(2.0 * M_PI * r3); + pos_ = rot_ * vector3d(0, 1, 0); } if (isInitiallyUnderwater || (isRelocatableIfBuried && initialVariationTooHigh)) { @@ -585,17 +584,17 @@ static Frame *MakeFrameFor(const double at_time, SystemBody *sbody, Body *b, Fra if (sbody->GetType() == SystemBody::TYPE_GRAVPOINT) { Frame *orbFrame = new Frame(f, sbody->GetName().c_str()); orbFrame->SetBodies(sbody, b); - orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1); + orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance() * 1.1); return orbFrame; } SystemBody::BodySuperType supertype = sbody->GetSuperType(); if ((supertype == SystemBody::SUPERTYPE_GAS_GIANT) || - (supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) { + (supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) { // for planets we want an non-rotating frame for a few radii // and a rotating frame with no radius to contain attached objects - double frameRadius = std::max(4.0*sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance()*1.05); + double frameRadius = std::max(4.0 * sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance() * 1.05); Frame *orbFrame = new Frame(f, sbody->GetName().c_str(), Frame::FLAG_HAS_ROT); orbFrame->SetBodies(sbody, b); orbFrame->SetRadius(frameRadius); @@ -611,7 +610,7 @@ static Frame *MakeFrameFor(const double at_time, SystemBody *sbody, Body *b, Fra rotFrame->SetRadius(b->GetPhysRadius()); matrix3x3d rotMatrix = matrix3x3d::RotateX(sbody->GetAxialTilt()); - double angSpeed = 2.0*M_PI/sbody->GetRotationPeriod(); + double angSpeed = 2.0 * M_PI / sbody->GetRotationPeriod(); rotFrame->SetAngSpeed(angSpeed); if (sbody->HasRotationPhase()) @@ -620,28 +619,26 @@ static Frame *MakeFrameFor(const double at_time, SystemBody *sbody, Body *b, Fra b->SetFrame(rotFrame); return orbFrame; - } - else if (supertype == SystemBody::SUPERTYPE_STAR) { + } else if (supertype == SystemBody::SUPERTYPE_STAR) { // stars want a single small non-rotating frame // bigger than it's furtherest orbiting body. // if there are no orbiting bodies use a frame of several radii. Frame *orbFrame = new Frame(f, sbody->GetName().c_str()); orbFrame->SetBodies(sbody, b); - double frameRadius = std::max(10.0*sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance()*1.1); + double frameRadius = std::max(10.0 * sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance() * 1.1); // Respect the frame of other stars in the multi-star system. We still make sure that the frame ends outside // the body. For a minimum separation of 1.236 radii, nothing will overlap (see StarSystem::StarSystem()). if (sbody->GetParent() && frameRadius > AU * 0.11 * sbody->GetOrbMin()) - frameRadius = std::max(1.1*sbody->GetRadius(), AU * 0.11 * sbody->GetOrbMin()); + frameRadius = std::max(1.1 * sbody->GetRadius(), AU * 0.11 * sbody->GetOrbMin()); orbFrame->SetRadius(frameRadius); b->SetFrame(orbFrame); return orbFrame; - } - else if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) { + } else if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) { // space stations want non-rotating frame to some distance Frame *orbFrame = new Frame(f, sbody->GetName().c_str()); orbFrame->SetBodies(sbody, b); -// orbFrame->SetRadius(10*sbody->GetRadius()); - orbFrame->SetRadius(20000.0); // 4x standard parking radius + // orbFrame->SetRadius(10*sbody->GetRadius()); + orbFrame->SetRadius(20000.0); // 4x standard parking radius b->SetFrame(orbFrame); return orbFrame; @@ -655,7 +652,7 @@ static Frame *MakeFrameFor(const double at_time, SystemBody *sbody, Body *b, Fra assert(rotFrame->GetBody()->IsType(Object::PLANET)); matrix3x3d rot; vector3d pos; - Planet *planet = static_cast(rotFrame->GetBody()); + Planet *planet = static_cast(rotFrame->GetBody()); RelocateStarportIfNecessary(sbody, rotFrame, planet, pos, rot, prevPositions); sbody->SetOrbitPlane(rot); b->SetPosition(pos * planet->GetTerrainHeight(pos)); @@ -681,15 +678,16 @@ public: const float dist_b = vector3f(here.sectorX - b.sectorX, here.sectorY - b.sectorY, here.sectorZ - b.sectorZ).LengthSqr(); return dist_a < dist_b; } - SectorDistanceSort( const SystemPath* centre ) - : here(centre) + SectorDistanceSort(const SystemPath *centre) : + here(centre) {} + private: SectorDistanceSort() {} SystemPath here; }; -void Space::GenSectorCache(RefCountedPtr galaxy, const SystemPath* here) +void Space::GenSectorCache(RefCountedPtr galaxy, const SystemPath *here) { PROFILE_SCOPED() @@ -705,9 +703,9 @@ void Space::GenSectorCache(RefCountedPtr galaxy, const SystemPath* here) SectorCache::PathVector paths; // build all of the possible paths we'll need to build sectors for - for (int x = here_x-sectorRadius; x <= here_x+sectorRadius; x++) { - for (int y = here_y-sectorRadius; y <= here_y+sectorRadius; y++) { - for (int z = here_z-sectorRadius; z <= here_z+sectorRadius; z++) { + for (int x = here_x - sectorRadius; x <= here_x + sectorRadius; x++) { + for (int y = here_y - sectorRadius; y <= here_y + sectorRadius; y++) { + for (int z = here_z - sectorRadius; z <= here_z + sectorRadius; z++) { SystemPath path(x, y, z); paths.push_back(path); } @@ -717,15 +715,16 @@ void Space::GenSectorCache(RefCountedPtr galaxy, const SystemPath* here) SectorDistanceSort SDS(here); std::sort(paths.begin(), paths.end(), SDS); m_sectorCache = galaxy->NewSectorSlaveCache(); - const SystemPath& center(*here); - m_sectorCache->FillCache(paths, [this,center]() { UpdateStarSystemCache(¢er); }); + const SystemPath ¢er(*here); + m_sectorCache->FillCache(paths, [this, center]() { UpdateStarSystemCache(¢er); }); } -static bool WithinBox(const SystemPath &here, const int Xmin, const int Xmax, const int Ymin, const int Ymax, const int Zmin, const int Zmax) { +static bool WithinBox(const SystemPath &here, const int Xmin, const int Xmax, const int Ymin, const int Ymax, const int Zmin, const int Zmax) +{ PROFILE_SCOPED() - if(here.sectorX >= Xmin && here.sectorX <= Xmax) { - if(here.sectorY >= Ymin && here.sectorY <= Ymax) { - if(here.sectorZ >= Zmin && here.sectorZ <= Zmax) { + if (here.sectorX >= Xmin && here.sectorX <= Xmax) { + if (here.sectorY >= Ymin && here.sectorY <= Ymax) { + if (here.sectorZ >= Zmin && here.sectorZ <= Zmax) { return true; } } @@ -733,7 +732,7 @@ static bool WithinBox(const SystemPath &here, const int Xmin, const int Xmax, co return false; } -void Space::UpdateStarSystemCache(const SystemPath* here) +void Space::UpdateStarSystemCache(const SystemPath *here) { PROFILE_SCOPED() @@ -748,42 +747,42 @@ void Space::UpdateStarSystemCache(const SystemPath* here) const int here_z = here->sectorZ; // we're going to use these to determine if our StarSystems are within a range that we'll keep for later use - static const int survivorRadius = sectorRadius*3; + static const int survivorRadius = sectorRadius * 3; // min/max box limits - const int xmin = here->sectorX-survivorRadius; - const int xmax = here->sectorX+survivorRadius; - const int ymin = here->sectorY-survivorRadius; - const int ymax = here->sectorY+survivorRadius; - const int zmin = here->sectorZ-survivorRadius; - const int zmax = here->sectorZ+survivorRadius; + const int xmin = here->sectorX - survivorRadius; + const int xmax = here->sectorX + survivorRadius; + const int ymin = here->sectorY - survivorRadius; + const int ymax = here->sectorY + survivorRadius; + const int zmin = here->sectorZ - survivorRadius; + const int zmax = here->sectorZ + survivorRadius; -# ifdef DEBUG_CACHE - unsigned removed = 0; -# endif +#ifdef DEBUG_CACHE + unsigned removed = 0; +#endif StarSystemCache::CacheMap::const_iterator i = m_starSystemCache->Begin(); while (i != m_starSystemCache->End()) { if (!WithinBox(i->second->GetPath(), xmin, xmax, ymin, ymax, zmin, zmax)) { m_starSystemCache->Erase(i++); -# ifdef DEBUG_CACHE - ++removed; -# endif +#ifdef DEBUG_CACHE + ++removed; +#endif } else ++i; } -# ifdef DEBUG_CACHE - Output("%s: Erased %u entries.\n", StarSystemCache::CACHE_NAME.c_str(), removed); -# endif +#ifdef DEBUG_CACHE + Output("%s: Erased %u entries.\n", StarSystemCache::CACHE_NAME.c_str(), removed); +#endif SectorCache::PathVector paths; // build all of the possible paths we'll need to build star systems for - for (int x = here_x-sectorRadius; x <= here_x+sectorRadius; x++) { - for (int y = here_y-sectorRadius; y <= here_y+sectorRadius; y++) { - for (int z = here_z-sectorRadius; z <= here_z+sectorRadius; z++) { + for (int x = here_x - sectorRadius; x <= here_x + sectorRadius; x++) { + for (int y = here_y - sectorRadius; y <= here_y + sectorRadius; y++) { + for (int z = here_z - sectorRadius; z <= here_z + sectorRadius; z++) { SystemPath path(x, y, z); RefCountedPtr sec(m_sectorCache->GetIfCached(path)); assert(sec); - for (const Sector::System& ss : sec->m_systems) + for (const Sector::System &ss : sec->m_systems) paths.push_back(SystemPath(ss.sx, ss.sy, ss.sz, ss.idx)); } } @@ -800,7 +799,7 @@ void Space::GenBody(const double at_time, SystemBody *sbody, Frame *f, std::vect Star *star = new Star(sbody); b = star; } else if ((sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) || - (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE)) { + (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE)) { SpaceStation *ss = new SpaceStation(sbody); b = ss; } else { @@ -810,20 +809,20 @@ void Space::GenBody(const double at_time, SystemBody *sbody, Frame *f, std::vect posAccum.clear(); } b->SetLabel(sbody->GetName().c_str()); - b->SetPosition(vector3d(0,0,0)); + b->SetPosition(vector3d(0, 0, 0)); AddBody(b); } f = MakeFrameFor(at_time, sbody, b, f, posAccum); - for (SystemBody* kid : sbody->GetChildren()) { + for (SystemBody *kid : sbody->GetChildren()) { GenBody(at_time, kid, f, posAccum); } } static bool OnCollision(Object *o1, Object *o2, CollisionContact *c, double relativeVel) { - Body *pb1 = static_cast(o1); - Body *pb2 = static_cast(o2); + Body *pb1 = static_cast(o1); + Body *pb2 = static_cast(o2); /* Not always a Body (could be CityOnPlanet, which is a nasty exception I should eradicate) */ if (o1->IsType(Object::BODY)) { if (pb1 && !pb1->OnCollision(o2, c->geomFlag, relativeVel)) return false; @@ -838,8 +837,8 @@ static void hitCallback(CollisionContact *c) { //Output("OUCH! %x (depth %f)\n", SDL_GetTicks(), c->depth); - Object *po1 = static_cast(c->userData1); - Object *po2 = static_cast(c->userData2); + Object *po1 = static_cast(c->userData1); + Object *po2 = static_cast(c->userData2); const bool po1_isDynBody = po1->IsType(Object::DYNAMICBODY); const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY); @@ -847,8 +846,8 @@ static void hitCallback(CollisionContact *c) assert(po1_isDynBody || po2_isDynBody); if (po1_isDynBody && po2_isDynBody) { - DynamicBody *b1 = static_cast(po1); - DynamicBody *b2 = static_cast(po2); + DynamicBody *b1 = static_cast(po1); + DynamicBody *b2 = static_cast(po2); const vector3d linVel1 = b1->GetVelocity(); const vector3d linVel2 = b2->GetVelocity(); const vector3d angVel1 = b1->GetAngVelocity(); @@ -856,7 +855,7 @@ static void hitCallback(CollisionContact *c) const double coeff_rest = 0.5; // step back -// mover->UndoTimestep(); + // mover->UndoTimestep(); const double invMass1 = 1.0 / b1->GetMass(); const double invMass2 = 1.0 / b2->GetMass(); @@ -873,26 +872,26 @@ static void hitCallback(CollisionContact *c) const double numerator = -(1.0 + coeff_rest) * relVel; const double term1 = invMass1; const double term2 = invMass2; - const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert1).Cross(hitPos1)); - const double term4 = c->normal.Dot((hitPos2.Cross(c->normal)*invAngInert2).Cross(hitPos2)); + const double term3 = c->normal.Dot((hitPos1.Cross(c->normal) * invAngInert1).Cross(hitPos1)); + const double term4 = c->normal.Dot((hitPos2.Cross(c->normal) * invAngInert2).Cross(hitPos2)); const double j = numerator / (term1 + term2 + term3 + term4); const vector3d force = j * c->normal; - b1->SetVelocity(linVel1 + force*invMass1); - b1->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert1); - b2->SetVelocity(linVel2 - force*invMass2); - b2->SetAngVelocity(angVel2 - hitPos2.Cross(force)*invAngInert2); + b1->SetVelocity(linVel1 + force * invMass1); + b1->SetAngVelocity(angVel1 + hitPos1.Cross(force) * invAngInert1); + b2->SetVelocity(linVel2 - force * invMass2); + b2->SetAngVelocity(angVel2 - hitPos2.Cross(force) * invAngInert2); } else { // one body is static vector3d hitNormal; DynamicBody *mover; if (po1_isDynBody) { - mover = static_cast(po1); + mover = static_cast(po1); hitNormal = c->normal; } else { - mover = static_cast(po2); + mover = static_cast(po2); hitNormal = -c->normal; } @@ -901,7 +900,7 @@ static void hitCallback(CollisionContact *c) const vector3d angVel1 = mover->GetAngVelocity(); // step back -// mover->UndoTimestep(); + // mover->UndoTimestep(); const double invMass1 = 1.0 / mover->GetMass(); const vector3d hitPos1 = c->pos - mover->GetPosition(); @@ -913,13 +912,13 @@ static void hitCallback(CollisionContact *c) const double invAngInert = 1.0 / mover->GetAngularInertia(); const double numerator = -(1.0 + coeff_rest) * relVel; const double term1 = invMass1; - const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert).Cross(hitPos1)); + const double term3 = c->normal.Dot((hitPos1.Cross(c->normal) * invAngInert).Cross(hitPos1)); const double j = numerator / (term1 + term3); const vector3d force = j * c->normal; - mover->SetVelocity(linVel1 + force*invMass1); - mover->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert); + mover->SetVelocity(linVel1 + force * invMass1); + mover->SetAngVelocity(angVel1 + hitPos1.Cross(force) * invAngInert); } } @@ -927,17 +926,17 @@ static void hitCallback(CollisionContact *c) static void CollideWithTerrain(Body *body) { if (!body->IsType(Object::DYNAMICBODY)) return; - DynamicBody *dynBody = static_cast(body); + DynamicBody *dynBody = static_cast(body); if (!dynBody->IsMoving()) return; Frame *f = body->GetFrame(); if (!f || !f->GetBody() || f != f->GetBody()->GetFrame()) return; if (!f->GetBody()->IsType(Object::TERRAINBODY)) return; - TerrainBody *terrain = static_cast(f->GetBody()); + TerrainBody *terrain = static_cast(f->GetBody()); const Aabb &aabb = dynBody->GetAabb(); double altitude = body->GetPosition().Length() + aabb.min.y; - if (altitude >= (terrain->GetMaxFeatureRadius()*2.0)) return; + if (altitude >= (terrain->GetMaxFeatureRadius() * 2.0)) return; double terrHeight = terrain->GetTerrainHeight(body->GetPosition().Normalized()); if (altitude >= terrHeight) return; @@ -946,15 +945,15 @@ static void CollideWithTerrain(Body *body) c.pos = body->GetPosition(); c.normal = c.pos.Normalized(); c.depth = terrHeight - altitude; - c.userData1 = static_cast(body); - c.userData2 = static_cast(f->GetBody()); + c.userData1 = static_cast(body); + c.userData2 = static_cast(f->GetBody()); hitCallback(&c); } void Space::CollideFrame(Frame *f) { f->GetCollisionSpace()->Collide(&hitCallback); - for (Frame* kid : f->GetChildren()) + for (Frame *kid : f->GetChildren()) CollideFrame(kid); } @@ -962,27 +961,27 @@ void Space::TimeStep(float step) { PROFILE_SCOPED() - if( Pi::MustRefreshBackgroundClearFlag() ) + if (Pi::MustRefreshBackgroundClearFlag()) RefreshBackground(); m_frameIndexValid = m_bodyIndexValid = m_sbodyIndexValid = false; // XXX does not need to be done this often CollideFrame(m_rootFrame.get()); - for (Body* b : m_bodies) + for (Body *b : m_bodies) CollideWithTerrain(b); // update frames of reference - for (Body* b : m_bodies) + for (Body *b : m_bodies) b->UpdateFrame(); // AI acts here, then move all bodies and frames - for (Body* b : m_bodies) + for (Body *b : m_bodies) b->StaticUpdate(step); m_rootFrame->UpdateOrbitRails(m_game->GetTime(), m_game->GetTimeStep()); - for (Body* b : m_bodies) + for (Body *b : m_bodies) b->TimeStepUpdate(step); LuaEvent::Emit(); @@ -999,16 +998,16 @@ void Space::UpdateBodies() m_processingFinalizationQueue = true; #endif - for (Body* rmb : m_removeBodies) { + for (Body *rmb : m_removeBodies) { rmb->SetFrame(0); - for (Body* b : m_bodies) + for (Body *b : m_bodies) b->NotifyRemoved(rmb); m_bodies.remove(rmb); } m_removeBodies.clear(); - for (Body* killb : m_killBodies) { - for (Body* b : m_bodies) + for (Body *killb : m_killBodies) { + for (Body *b : m_bodies) b->NotifyRemoved(killb); m_bodies.remove(killb); delete killb; @@ -1024,18 +1023,18 @@ static char space[256]; static void DebugDumpFrame(Frame *f, unsigned int indent) { - Output("%.*s%p (%s)", indent, space, static_cast(f), f->GetLabel().c_str()); + Output("%.*s%p (%s)", indent, space, static_cast(f), f->GetLabel().c_str()); if (f->GetParent()) - Output(" parent %p (%s)", static_cast(f->GetParent()), f->GetParent()->GetLabel().c_str()); + Output(" parent %p (%s)", static_cast(f->GetParent()), f->GetParent()->GetLabel().c_str()); if (f->GetBody()) - Output(" body %p (%s)", static_cast(f->GetBody()), f->GetBody()->GetLabel().c_str()); + Output(" body %p (%s)", static_cast(f->GetBody()), f->GetBody()->GetLabel().c_str()); if (Body *b = f->GetBody()) - Output(" bodyFor %p (%s)", static_cast(b), b->GetLabel().c_str()); + Output(" bodyFor %p (%s)", static_cast(b), b->GetLabel().c_str()); Output(" distance %f radius %f", f->GetPosition().Length(), f->GetRadius()); Output("%s\n", f->IsRotFrame() ? " [rotating]" : ""); - for (Frame* kid : f->GetChildren()) - DebugDumpFrame(kid, indent+2); + for (Frame *kid : f->GetChildren()) + DebugDumpFrame(kid, indent + 2); } void Space::DebugDumpFrames() diff --git a/src/Space.h b/src/Space.h index ffc478352..26cae1657 100644 --- a/src/Space.h +++ b/src/Space.h @@ -4,14 +4,14 @@ #ifndef _SPACE_H #define _SPACE_H -#include +#include "Background.h" +#include "IterationProxy.h" #include "Object.h" -#include "vector3.h" #include "RefCounted.h" #include "galaxy/GalaxyCache.h" #include "galaxy/StarSystem.h" -#include "Background.h" -#include "IterationProxy.h" +#include "vector3.h" +#include class Body; class Frame; @@ -22,10 +22,10 @@ class Game; class Space { public: // empty space (eg for hyperspace) - Space(Game *game, RefCountedPtr galaxy, Space* oldSpace = nullptr); + Space(Game *game, RefCountedPtr galaxy, Space *oldSpace = nullptr); // initalise with system bodies - Space(Game *game, RefCountedPtr galaxy, const SystemPath &path, Space* oldSpace = nullptr); + Space(Game *game, RefCountedPtr galaxy, const SystemPath &path, Space *oldSpace = nullptr); // initialise from save file Space(Game *game, RefCountedPtr galaxy, const Json &jsonObj, double at_time); @@ -38,7 +38,7 @@ public: // construction/ToJson(), invalidated by TimeStep(). they will assert // if called while invalid Frame *GetFrameByIndex(Uint32 idx) const; - Body *GetBodyByIndex(Uint32 idx) const; + Body *GetBodyByIndex(Uint32 idx) const; SystemBody *GetSystemBodyByIndex(Uint32 idx) const; Uint32 GetIndexForFrame(const Frame *frame) const; Uint32 GetIndexForBody(const Body *body) const; @@ -55,13 +55,15 @@ public: void TimeStep(float step); void GetHyperspaceExitParams(const SystemPath &source, const SystemPath &dest, - vector3d &pos, vector3d &vel) const; - vector3d GetHyperspaceExitPoint(const SystemPath &source, const SystemPath &dest) const { - vector3d pos,vel; + vector3d &pos, vector3d &vel) const; + vector3d GetHyperspaceExitPoint(const SystemPath &source, const SystemPath &dest) const + { + vector3d pos, vel; GetHyperspaceExitParams(source, dest, pos, vel); return pos; } - vector3d GetHyperspaceExitPoint(const SystemPath &source) const { + vector3d GetHyperspaceExitPoint(const SystemPath &source) const + { return GetHyperspaceExitPoint(source, m_starSystem->GetPath()); } @@ -69,26 +71,27 @@ public: Body *FindBodyForPath(const SystemPath *path) const; Uint32 GetNumBodies() const { return static_cast(m_bodies.size()); } - IterationProxy > GetBodies() { return MakeIterationProxy(m_bodies); } - const IterationProxy > GetBodies() const { return MakeIterationProxy(m_bodies); } + IterationProxy> GetBodies() { return MakeIterationProxy(m_bodies); } + const IterationProxy> GetBodies() const { return MakeIterationProxy(m_bodies); } Background::Container *GetBackground() { return m_background.get(); } void RefreshBackground(); // body finder delegates - typedef std::vector BodyNearList; + typedef std::vector BodyNearList; typedef BodyNearList::iterator BodyNearIterator; - void GetBodiesMaybeNear(const Body *b, double dist, BodyNearList &bodies) const { + void GetBodiesMaybeNear(const Body *b, double dist, BodyNearList &bodies) const + { m_bodyNearFinder.GetBodiesMaybeNear(b, dist, bodies); } - void GetBodiesMaybeNear(const vector3d &pos, double dist, BodyNearList &bodies) const { + void GetBodiesMaybeNear(const vector3d &pos, double dist, BodyNearList &bodies) const + { m_bodyNearFinder.GetBodiesMaybeNear(pos, dist, bodies); } - private: - void GenSectorCache(RefCountedPtr galaxy, const SystemPath* here); - void UpdateStarSystemCache(const SystemPath* here); + void GenSectorCache(RefCountedPtr galaxy, const SystemPath *here); + void UpdateStarSystemCache(const SystemPath *here); void GenBody(const double at_time, SystemBody *b, Frame *f, std::vector &posAccum); // make sure SystemBody* is in Pi::currentSystem Frame *GetFrameWithSystemBody(const SystemBody *b) const; @@ -107,11 +110,11 @@ private: Game *m_game; // all the bodies we know about - std::list m_bodies; + std::list m_bodies; // bodies that were removed/killed this timestep and need pruning at the end - std::list m_removeBodies; - std::list m_killBodies; + std::list m_removeBodies; + std::list m_killBodies; void RebuildFrameIndex(); void RebuildBodyIndex(); @@ -121,9 +124,9 @@ private: void AddSystemBodyToIndex(SystemBody *sbody); bool m_frameIndexValid, m_bodyIndexValid, m_sbodyIndexValid; - std::vector m_frameIndex; - std::vector m_bodyIndex; - std::vector m_sbodyIndex; + std::vector m_frameIndex; + std::vector m_bodyIndex; + std::vector m_sbodyIndex; //background (elements that are infinitely far away, //e.g. starfield and milky way) @@ -131,7 +134,8 @@ private: class BodyNearFinder { public: - BodyNearFinder(const Space *space) : m_space(space) {} + BodyNearFinder(const Space *space) : + m_space(space) {} void Prepare(); void GetBodiesMaybeNear(const Body *b, double dist, BodyNearList &bodies) const; @@ -139,8 +143,10 @@ private: private: struct BodyDist { - BodyDist(Body *_body, double _dist) : body(_body), dist(_dist) {} - Body *body; + BodyDist(Body *_body, double _dist) : + body(_body), + dist(_dist) {} + Body *body; double dist; bool operator<(const BodyDist &a) const { return dist < a.dist; } diff --git a/src/SpaceStation.cpp b/src/SpaceStation.cpp index c9998b692..ed2ed30fc 100644 --- a/src/SpaceStation.cpp +++ b/src/SpaceStation.cpp @@ -6,7 +6,8 @@ #include "FileSystem.h" #include "Frame.h" #include "Game.h" -#include "gameconsts.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "Lang.h" #include "LuaEvent.h" #include "LuaVector.h" @@ -15,14 +16,13 @@ #include "Player.h" #include "Polit.h" #include "Ship.h" +#include "ShipCpanel.h" #include "Space.h" #include "StringF.h" -#include "ShipCpanel.h" #include "galaxy/StarSystem.h" +#include "gameconsts.h" #include "graphics/Graphics.h" #include "scenegraph/ModelSkin.h" -#include "JsonUtils.h" -#include "GameSaveError.h" #include void SpaceStation::Init() @@ -37,12 +37,10 @@ void SpaceStation::SaveToJson(Json &jsonObj, Space *space) Json spaceStationObj({}); // Create JSON object to contain space station data. Json shipDockingArray = Json::array(); // Create JSON array to contain ship docking data. - for (Uint32 i = 0; iGetIndexForBody(m_shipDocking[i].ship); - if (bodyIndex != 0) - { + if (bodyIndex != 0) { shipDockingArrayEl["index_for_body"] = bodyIndex; shipDockingArrayEl["stage"] = m_shipDocking[i].stage; shipDockingArrayEl["stage_pos"] = m_shipDocking[i].stagePos; // stagePos is a double but was saved as a float in pre-JSON system for some reason (saved as double here). @@ -55,11 +53,10 @@ void SpaceStation::SaveToJson(Json &jsonObj, Space *space) // store each of the port details and bay IDs Json portArray = Json::array(); // Create JSON array to contain port data. - for (Uint32 i = 0; i < m_ports.size(); i++) - { + for (Uint32 i = 0; i < m_ports.size(); i++) { Json portArrayEl({}); // Create JSON object to contain port. - if(m_ports[i].inUse) + if (m_ports[i].inUse) portArrayEl["in_use"] = m_ports[i].inUse; portArray.push_back(portArrayEl); // Append port object to array. @@ -88,29 +85,27 @@ void SpaceStation::LoadFromJson(const Json &jsonObj, Space *space) Json shipDockingArray = spaceStationObj["ship_docking"].get(); m_shipDocking.reserve(shipDockingArray.size()); - for (Uint32 i = 0; i < shipDockingArray.size(); i++) - { + for (Uint32 i = 0; i < shipDockingArray.size(); i++) { m_shipDocking.push_back(shipDocking_t()); shipDocking_t &sd = m_shipDocking.back(); Json shipDockingArrayEl = shipDockingArray[i]; - if(shipDockingArrayEl.count("index_for_body")) + if (shipDockingArrayEl.count("index_for_body")) sd.shipIndex = shipDockingArrayEl["index_for_body"]; - if(shipDockingArrayEl.count("stage")) + if (shipDockingArrayEl.count("stage")) sd.stage = shipDockingArrayEl["stage"]; - if(shipDockingArrayEl.count("stage_pos")) + if (shipDockingArrayEl.count("stage_pos")) sd.stagePos = shipDockingArrayEl["stage_pos"]; // For some reason stagePos was saved as a float in pre-JSON system (saved & loaded as double here). - if(shipDockingArrayEl.count("from_pos")) + if (shipDockingArrayEl.count("from_pos")) sd.fromPos = shipDockingArrayEl["from_pos"]; - if(shipDockingArrayEl.count("from_rot")) + if (shipDockingArrayEl.count("from_rot")) sd.fromRot = shipDockingArrayEl["from_rot"]; } // retrieve each of the port details and bay IDs Json portArray = spaceStationObj["ports"].get(); m_ports.reserve(portArray.size()); - for (Uint32 i = 0; i < portArray.size(); i++) - { + for (Uint32 i = 0; i < portArray.size(); i++) { m_ports.push_back(SpaceStationType::SPort()); SpaceStationType::SPort &port = m_ports.back(); @@ -135,12 +130,14 @@ void SpaceStation::LoadFromJson(const Json &jsonObj, Space *space) void SpaceStation::PostLoadFixup(Space *space) { ModelBody::PostLoadFixup(space); - for (Uint32 i=0; i(space->GetBodyByIndex(m_shipDocking[i].shipIndex)); + for (Uint32 i = 0; i < m_shipDocking.size(); i++) { + m_shipDocking[i].ship = static_cast(space->GetBodyByIndex(m_shipDocking[i].shipIndex)); } } -SpaceStation::SpaceStation(const SystemBody *sbody): ModelBody(), m_type(nullptr) +SpaceStation::SpaceStation(const SystemBody *sbody) : + ModelBody(), + m_type(nullptr) { m_sbody = sbody; @@ -154,21 +151,22 @@ SpaceStation::SpaceStation(const SystemBody *sbody): ModelBody(), m_type(nullptr void SpaceStation::InitStation() { m_adjacentCity = 0; - for(int i=0; iGetSeed()); const bool ground = m_sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL ? false : true; const std::string &space_station_type = m_sbody->GetSpaceStationType(); - if(space_station_type != "") { + if (space_station_type != "") { m_type = SpaceStationType::FindByName(space_station_type); - if(m_type == nullptr) + if (m_type == nullptr) Output("WARNING: SpaceStation::InitStation wants to initialize a custom station of type %s, but no station type with that id has been found.\n", space_station_type.c_str()); } - if(m_type == nullptr) + if (m_type == nullptr) m_type = SpaceStationType::RandomStationType(rand, ground); - if(m_shipDocking.empty()) { + if (m_shipDocking.empty()) { m_shipDocking.reserve(m_type->NumDockingPorts()); - for (unsigned int i=0; iNumDockingPorts(); i++) { + for (unsigned int i = 0; i < m_type->NumDockingPorts(); i++) { m_shipDocking.push_back(shipDocking_t()); } // only (re)set these if we've not come from the ::Load method @@ -177,25 +175,21 @@ void SpaceStation::InitStation() assert(m_shipDocking.size() == m_type->NumDockingPorts()); // This SpaceStation's bay ports are an instance of... - if (m_ports.size() != m_type->Ports().size()) - { + if (m_ports.size() != m_type->Ports().size()) { m_ports = m_type->Ports(); - } - else - { + } else { // since we might have loaded from JSON we've got a little bit of useful info in m_ports already // backup the current data auto backup = m_ports; // clear it all to default m_ports = m_type->Ports(); // now restore the "inUse" variable only since it's the only bit that might have changed - for (int p=0;pSetEnabled(true); - if (ground) SetClipRadius(CITY_ON_PLANET_RADIUS); // overrides setmodel + if (ground) SetClipRadius(CITY_ON_PLANET_RADIUS); // overrides setmodel m_doorAnimation = model->FindAnimation("doors"); @@ -217,7 +211,7 @@ void SpaceStation::InitStation() skin.SetRandomColors(rand); skin.Apply(model); if (model->SupportsPatterns()) { - model->SetPattern(rand.Int32(0, model->GetNumPatterns()-1)); + model->SetPattern(rand.Int32(0, model->GetNumPatterns() - 1)); } } @@ -226,9 +220,9 @@ SpaceStation::~SpaceStation() if (m_adjacentCity) delete m_adjacentCity; } -void SpaceStation::NotifyRemoved(const Body* const removedBody) +void SpaceStation::NotifyRemoved(const Body *const removedBody) { - for (Uint32 i=0; iNumDockingPorts(); i++) { + for (unsigned int i = 0; i < m_type->NumDockingPorts(); i++) { if (m_shipDocking[i].ship == nullptr) { // size-of-ship vs size-of-bay check const SpaceStationType::SPort *const pPort = m_type->FindPortByBay(i); - if( !pPort ) continue; + if (!pPort) continue; const Aabb &bbox = s->GetAabb(); const double bboxRad = bbox.GetRadius(); - if( pPort->minShipSize < bboxRad && bboxRad < pPort->maxShipSize ) { + if (pPort->minShipSize < bboxRad && bboxRad < pPort->maxShipSize) { return i; } } @@ -277,7 +271,7 @@ void SpaceStation::SetDocked(Ship *ship, const int port) { assert(m_shipDocking.size() > Uint32(port)); m_shipDocking[port].ship = ship; - m_shipDocking[port].stage = m_type->NumDockingStages()+3; + m_shipDocking[port].stage = m_type->NumDockingStages() + 3; // have to do this crap again in case it was called directly (Ship::SetDockWith()) ship->SetFlightState(Ship::DOCKED); @@ -288,7 +282,7 @@ void SpaceStation::SetDocked(Ship *ship, const int port) void SpaceStation::SwapDockedShipsPort(const int oldPort, const int newPort) { - if( oldPort == newPort ) + if (oldPort == newPort) return; // set new location @@ -303,8 +297,8 @@ void SpaceStation::SwapDockedShipsPort(const int oldPort, const int newPort) bool SpaceStation::LaunchShip(Ship *ship, const int port) { shipDocking_t &sd = m_shipDocking[port]; - if (sd.stage < 0) return true; // already launching - if (IsPortLocked(port)) return false; // another ship docking + if (sd.stage < 0) return true; // already launching + if (IsPortLocked(port)) return false; // another ship docking LockPort(port, true); sd.ship = ship; @@ -315,7 +309,7 @@ bool SpaceStation::LaunchShip(Ship *ship, const int port) const vector3d up = ship->GetOrient().VectorY().Normalized() * ship->GetLandingPosOffset(); - sd.fromPos = (ship->GetPosition() - GetPosition() + up) * GetOrient(); // station space + sd.fromPos = (ship->GetPosition() - GetPosition() + up) * GetOrient(); // station space sd.fromRot = Quaterniond::FromMatrix3x3(GetOrient().Transpose() * ship->GetOrient()); ship->SetFlightState(Ship::UNDOCKING); @@ -326,23 +320,23 @@ bool SpaceStation::LaunchShip(Ship *ship, const int port) bool SpaceStation::GetDockingClearance(Ship *s, std::string &outMsg) { assert(m_shipDocking.size() == m_type->NumDockingPorts()); - for (Uint32 i=0; i 0); // grant docking only if the ship is not already docked/undocking } } const Aabb &bbox = s->GetAabb(); - const float bboxRad = vector2f( float(bbox.max.x), float(bbox.max.z)).Length(); + const float bboxRad = vector2f(float(bbox.max.x), float(bbox.max.z)).Length(); - for (Uint32 i=0; iFindPortByBay(i); - if( !pPort ) continue; + if (!pPort) continue; // distance-to-station check const double shipDist = s->GetPositionRelTo(this).Length(); @@ -352,15 +346,15 @@ bool SpaceStation::GetDockingClearance(Ship *s, std::string &outMsg) return false; } - if( pPort->minShipSize < bboxRad && bboxRad < pPort->maxShipSize ) { + if (pPort->minShipSize < bboxRad && bboxRad < pPort->maxShipSize) { shipDocking_t &sd = m_shipDocking[i]; sd.ship = s; sd.stage = 1; sd.stagePos = 0; // Note: maxOffset is squared - sd.maxOffset = std::max((pPort->maxShipSize/2 - bboxRad), float(pPort->maxShipSize/5.0) ); + sd.maxOffset = std::max((pPort->maxShipSize / 2 - bboxRad), float(pPort->maxShipSize / 5.0)); sd.maxOffset *= sd.maxOffset; - outMsg = stringf(Lang::CLEARANCE_GRANTED_BAY_N, formatarg("bay", i+1)); + outMsg = stringf(Lang::CLEARANCE_GRANTED_BAY_N, formatarg("bay", i + 1)); return true; } } @@ -371,37 +365,41 @@ bool SpaceStation::GetDockingClearance(Ship *s, std::string &outMsg) bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) { if ((flags & 0x10) && (b->IsType(Object::SHIP))) { - Ship *s = static_cast(b); + Ship *s = static_cast(b); int port = -1; - for (Uint32 i=0; iGetDockAnimPositionOrient(port, m_type->NumDockingStages(), 1.0f, vector3d(0.0), dport, s)); - vector3d dockingNormal = GetOrient()*dport.yaxis; + vector3d dockingNormal = GetOrient() * dport.yaxis; const double dot = s->GetOrient().VectorY().Dot(dockingNormal); - if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return DoShipDamage(s, flags, relVel); // <0.99 harsh? + if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return DoShipDamage(s, flags, relVel); // <0.99 harsh? // check speed if (s->GetVelocity().Length() > MAX_LANDING_SPEED) return DoShipDamage(s, flags, relVel); // check if you're near your pad - float dist = (s->GetPosition() - GetPosition() - GetOrient()*dport.pos).LengthSqr(); + float dist = (s->GetPosition() - GetPosition() - GetOrient() * dport.pos).LengthSqr(); // docking allowed only if inside a circle 70% greater than pad itself (*1.7) - float maxDist = static_cast(m_type->FindPortByBay(port)->maxShipSize/2)*1.7; - if (dist > (maxDist*maxDist)) return DoShipDamage(s, flags, relVel); + float maxDist = static_cast(m_type->FindPortByBay(port)->maxShipSize / 2) * 1.7; + if (dist > (maxDist * maxDist)) return DoShipDamage(s, flags, relVel); } // why stage 2? Because stage 1 is permission to dock @@ -414,7 +412,7 @@ bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) sd.ship = s; sd.stage = 2; sd.stagePos = 0; - sd.fromPos = (s->GetPosition() - GetPosition()) * GetOrient(); // station space + sd.fromPos = (s->GetPosition() - GetPosition()) * GetOrient(); // station space sd.fromRot = Quaterniond::FromMatrix3x3(GetOrient().Transpose() * s->GetOrient()); LockPort(port, true); @@ -423,7 +421,7 @@ bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) s->SetAngVelocity(vector3d(0.0)); s->ClearThrusterState(); } else { - s->SetDockedWith(this, port); // bounces back to SS::SetDocked() + s->SetDockedWith(this, port); // bounces back to SS::SetDocked() LuaEvent::Queue("onShipDocked", s, this); } // If this is reached, then you have permission @@ -434,8 +432,9 @@ bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) } } -bool SpaceStation::DoShipDamage(Ship* s, Uint32 flags, double relVel) { - if (s==nullptr) return false; +bool SpaceStation::DoShipDamage(Ship *s, Uint32 flags, double relVel) +{ + if (s == nullptr) return false; s->DynamicBody::OnCollision(this, flags, relVel); return true; } @@ -457,65 +456,65 @@ bool SpaceStation::DoShipDamage(Ship* s, Uint32 flags, double relVel) { void SpaceStation::DockingUpdate(const double timeStep) { vector3d p1, p2, zaxis; - for (Uint32 i=0; i m_type->NumDockingStages()) { int extraStage = dt.stage - m_type->NumDockingStages(); SpaceStationType::positionOrient_t dport; float dist = 0.0; - switch ( extraStage ) { - case 1: // Level ship & Reposition eval - // PS: This is to avoid to float around if dock - // at high time steps on an orbital - if (!IsGroundStation()) { - dt.fromPos = vector3d(0.0); //No offset - dt.fromRot = Quaterniond(1.0,0.0,0.0,0.0); //Identity (no rotation) - dt.stage += 2; - continue; - } - if ( !LevelShip(dt.ship, i, timeStep) ) continue; - PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->NumDockingStages(), 1.0f, dt.fromPos, dport, dt.ship)); - dist = (dt.ship->GetPosition() - GetPosition() - GetOrient()*dport.pos).LengthSqr(); - if (dist > dt.maxOffset) { - // Reposition needed - dt.fromPos = dt.ship->GetPosition(); - matrix3x3d padOrient = matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis); - dt.fromRot = Quaterniond::FromMatrix3x3((GetOrient()*padOrient).Transpose() * dt.ship->GetOrient()); - dt.stage++; - dt.stagePos = 0.0; - } else { - // Save ship position - dt.fromPos = (dt.ship->GetPosition() - GetPosition() - GetOrient()*dport.pos)*GetOrient(); - matrix3x3d padOrient = matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis); - dt.fromRot = Quaterniond::FromMatrix3x3((GetOrient()*padOrient).Transpose() * dt.ship->GetOrient()); - dt.stage += 2; - } + switch (extraStage) { + case 1: // Level ship & Reposition eval + // PS: This is to avoid to float around if dock + // at high time steps on an orbital + if (!IsGroundStation()) { + dt.fromPos = vector3d(0.0); //No offset + dt.fromRot = Quaterniond(1.0, 0.0, 0.0, 0.0); //Identity (no rotation) + dt.stage += 2; continue; - case 2: // Reposition stage - dt.stagePos += timeStep / 2.0; - if ( dt.stagePos >= 1.0 ) { - dt.stage++; - dt.fromPos = vector3d(0.0); //No offset - dt.fromRot = Quaterniond(1.0,0.0,0.0,0.0); //Identity (no rotation) - } - continue; - case 3: // Just docked - dt.ship->SetDockedWith(this, i); - LuaEvent::Queue("onShipDocked", dt.ship, this); - if (dt.fromPos.LengthSqr()>0.5) LuaEvent::Queue("onShipBadDocked", dt.ship, this); - LockPort(i, false); - m_doorAnimationStep = -0.3; // close door + } + if (!LevelShip(dt.ship, i, timeStep)) continue; + PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->NumDockingStages(), 1.0f, dt.fromPos, dport, dt.ship)); + dist = (dt.ship->GetPosition() - GetPosition() - GetOrient() * dport.pos).LengthSqr(); + if (dist > dt.maxOffset) { + // Reposition needed + dt.fromPos = dt.ship->GetPosition(); + matrix3x3d padOrient = matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis); + dt.fromRot = Quaterniond::FromMatrix3x3((GetOrient() * padOrient).Transpose() * dt.ship->GetOrient()); dt.stage++; - continue; - case 4: // Docked - default: continue; + dt.stagePos = 0.0; + } else { + // Save ship position + dt.fromPos = (dt.ship->GetPosition() - GetPosition() - GetOrient() * dport.pos) * GetOrient(); + matrix3x3d padOrient = matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis); + dt.fromRot = Quaterniond::FromMatrix3x3((GetOrient() * padOrient).Transpose() * dt.ship->GetOrient()); + dt.stage += 2; + } + continue; + case 2: // Reposition stage + dt.stagePos += timeStep / 2.0; + if (dt.stagePos >= 1.0) { + dt.stage++; + dt.fromPos = vector3d(0.0); //No offset + dt.fromRot = Quaterniond(1.0, 0.0, 0.0, 0.0); //Identity (no rotation) + } + continue; + case 3: // Just docked + dt.ship->SetDockedWith(this, i); + LuaEvent::Queue("onShipDocked", dt.ship, this); + if (dt.fromPos.LengthSqr() > 0.5) LuaEvent::Queue("onShipBadDocked", dt.ship, this); + LockPort(i, false); + m_doorAnimationStep = -0.3; // close door + dt.stage++; + continue; + case 4: // Docked + default: continue; } } double stageDuration = (dt.stage > 0 ? - m_type->GetDockAnimStageDuration(dt.stage-1) : - m_type->GetUndockAnimStageDuration(abs(dt.stage)-1)); + m_type->GetDockAnimStageDuration(dt.stage - 1) : + m_type->GetUndockAnimStageDuration(abs(dt.stage) - 1)); dt.stagePos += timeStep / stageDuration; if (dt.stage == 1) { @@ -543,8 +542,10 @@ void SpaceStation::DockingUpdate(const double timeStep) // transition between docking stages dt.stagePos = 0; - if (dt.stage >= 0) dt.stage++; - else dt.stage--; + if (dt.stage >= 0) + dt.stage++; + else + dt.stage--; } if (dt.stage < -m_type->ShipLaunchStage() && dt.ship->GetFlightState() != Ship::FLYING) { @@ -552,9 +553,9 @@ void SpaceStation::DockingUpdate(const double timeStep) dt.ship->SetFlightState(Ship::FLYING); dt.ship->SetAngVelocity(GetAngVelocity()); if (m_type->IsSurfaceStation()) { - dt.ship->SetThrusterState(1, 1.0); // up + dt.ship->SetThrusterState(1, 1.0); // up } else { - dt.ship->SetThrusterState(2, -1.0); // forward + dt.ship->SetThrusterState(2, -1.0); // forward } LuaEvent::Queue("onShipUndocked", dt.ship, this); } @@ -569,7 +570,7 @@ void SpaceStation::DockingUpdate(const double timeStep) } } - m_doorAnimationState = Clamp(m_doorAnimationState + m_doorAnimationStep*timeStep, 0.0, 1.0); + m_doorAnimationState = Clamp(m_doorAnimationState + m_doorAnimationStep * timeStep, 0.0, 1.0); if (m_doorAnimation) m_doorAnimation->SetProgress(m_doorAnimationState); } @@ -580,30 +581,32 @@ bool SpaceStation::LevelShip(Ship *ship, int port, const float timeStep) const SpaceStationType::positionOrient_t dport; PiVerify(m_type->GetDockAnimPositionOrient(port, dt.stage, dt.stagePos, dt.fromPos, dport, ship)); matrix3x3d shipOrient = ship->GetOrient(); - vector3d dockingNormal = GetOrient()*dport.yaxis; + vector3d dockingNormal = GetOrient() * dport.yaxis; const vector3d &shipPos = ship->GetPosition(); - vector3d dist = (shipPos - GetPosition())*GetOrient() - dport.pos; + vector3d dist = (shipPos - GetPosition()) * GetOrient() - dport.pos; - double cosUp = dockingNormal.Dot( shipOrient.VectorY() ); + double cosUp = dockingNormal.Dot(shipOrient.VectorY()); ship->ClearThrusterState(); - if (cosUp < 0.999999 ) { + if (cosUp < 0.999999) { // need level ship double angle; - if ( cosUp < 0.985 ) angle = -0.8*timeStep; - else angle = -acos( cosUp ); - vector3d rotAxis = dockingNormal.Cross( shipOrient.VectorY() ); + if (cosUp < 0.985) + angle = -0.8 * timeStep; + else + angle = -acos(cosUp); + vector3d rotAxis = dockingNormal.Cross(shipOrient.VectorY()); rotAxis = rotAxis.NormalizedSafe(); - shipOrient = matrix3x3d::Rotate( angle, rotAxis) * shipOrient; - ship->SetOrient( shipOrient ); + shipOrient = matrix3x3d::Rotate(angle, rotAxis) * shipOrient; + ship->SetOrient(shipOrient); } - if ( fabs(dist.y) > 0.01) { + if (fabs(dist.y) > 0.01) { vector3d inc(0.0, -dist.y, 0.0); - inc = GetOrient()*inc; - ship->SetPosition( shipPos + inc ); + inc = GetOrient() * inc; + ship->SetPosition(shipPos + inc); } - return (cosUp>=0.999999) && (fabs(dist.y)<0.01); + return (cosUp >= 0.999999) && (fabs(dist.y) < 0.01); } void SpaceStation::PositionDockingShip(Ship *ship, int port) const @@ -611,17 +614,17 @@ void SpaceStation::PositionDockingShip(Ship *ship, int port) const const shipDocking_t &dt = m_shipDocking[port]; SpaceStationType::positionOrient_t dport; PiVerify(m_type->GetDockAnimPositionOrient(port, dt.stage, dt.stagePos, dt.fromPos, dport, ship)); - if ( dt.stage > m_type->NumDockingStages() ) { - if (dt.stage == m_type->NumDockingStages()+1) { + if (dt.stage > m_type->NumDockingStages()) { + if (dt.stage == m_type->NumDockingStages() + 1) { // Leveling return; - } else if (dt.stage == m_type->NumDockingStages()+2) { + } else if (dt.stage == m_type->NumDockingStages() + 2) { // Repositioning - vector3d wantPos = GetPosition() + GetOrient()*dport.pos; - ship->SetPosition(dt.fromPos - (dt.fromPos - wantPos)*dt.stagePos); + vector3d wantPos = GetPosition() + GetOrient() * dport.pos; + ship->SetPosition(dt.fromPos - (dt.fromPos - wantPos) * dt.stagePos); } } else { - ship->SetPosition(GetPosition() + GetOrient()*dport.pos); + ship->SetPosition(GetPosition() + GetOrient() * dport.pos); } matrix3x3d wantRot = matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis); // use quaternion spherical linear interpolation to do @@ -639,12 +642,12 @@ void SpaceStation::PositionDockedShip(Ship *ship, int port) const PiVerify(m_type->GetDockAnimPositionOrient(port, dt.stage, dt.stagePos, dt.fromPos, dport, ship)); assert(dt.ship == ship); - ship->SetPosition(GetPosition() + GetOrient()*(dport.pos + dt.fromPos)); + ship->SetPosition(GetPosition() + GetOrient() * (dport.pos + dt.fromPos)); // Note: ship bounding box is used to generate dport.pos Quaterniond dportQ = Quaterniond::FromMatrix3x3(matrix3x3d::FromVectors(dport.xaxis, dport.yaxis, dport.zaxis)); - dportQ = dportQ*dt.fromRot; + dportQ = dportQ * dt.fromRot; matrix3x3d shipRot = dportQ.ToMatrix3x3(); - ship->SetOrient(GetOrient()*shipRot); + ship->SetOrient(GetOrient() * shipRot); } void SpaceStation::StaticUpdate(const float timeStep) @@ -658,31 +661,30 @@ void SpaceStation::TimeStepUpdate(const float timeStep) // rotate the thing double len = m_type->AngVel() * timeStep; if (!is_zero_exact(len)) { - matrix3x3d r = matrix3x3d::RotateY(-len); // RotateY is backwards + matrix3x3d r = matrix3x3d::RotateY(-len); // RotateY is backwards SetOrient(r * GetOrient()); } m_oldAngDisplacement = len; // reposition the ships that are docked or docking here - for (unsigned int i=0; iNumDockingPorts(); i++) { + for (unsigned int i = 0; i < m_type->NumDockingPorts(); i++) { const shipDocking_t &dt = m_shipDocking[i]; if (!dt.ship) { //free - m_navLights->SetColor(i+1, NavLights::NAVLIGHT_GREEN); + m_navLights->SetColor(i + 1, NavLights::NAVLIGHT_GREEN); continue; } - if (dt.stage == 1) {//reserved - m_navLights->SetColor(i+1, NavLights::NAVLIGHT_YELLOW); + if (dt.stage == 1) { //reserved + m_navLights->SetColor(i + 1, NavLights::NAVLIGHT_YELLOW); continue; } if (dt.ship->GetFlightState() == Ship::DOCKED) { PositionDockedShip(dt.ship, i); continue; } - if (dt.ship->GetFlightState() != Ship::DOCKING - && dt.ship->GetFlightState() != Ship::UNDOCKING) + if (dt.ship->GetFlightState() != Ship::DOCKING && dt.ship->GetFlightState() != Ship::UNDOCKING) continue; PositionDockingShip(dt.ship, i); - m_navLights->SetColor(i+1, NavLights::NAVLIGHT_RED); //docked + m_navLights->SetColor(i + 1, NavLights::NAVLIGHT_RED); //docked } ModelBody::TimeStepUpdate(timeStep); @@ -690,12 +692,12 @@ void SpaceStation::TimeStepUpdate(const float timeStep) void SpaceStation::UpdateInterpTransform(double alpha) { - double len = m_oldAngDisplacement * (1.0-alpha); + double len = m_oldAngDisplacement * (1.0 - alpha); if (!is_zero_exact(len)) { - matrix3x3d rot = matrix3x3d::RotateY(len); // RotateY is backwards + matrix3x3d rot = matrix3x3d::RotateY(len); // RotateY is backwards m_interpOrient = rot * GetOrient(); - } - else m_interpOrient = GetOrient(); + } else + m_interpOrient = GetOrient(); m_interpPos = GetPosition(); } @@ -731,7 +733,7 @@ void SpaceStation::Render(Graphics::Renderer *r, const Camera *camera, const vec SetLighting(r, camera, oldLights, oldAmbient); if (!m_adjacentCity) { - m_adjacentCity = new CityOnPlanet(static_cast(b), this, m_sbody->GetSeed()); + m_adjacentCity = new CityOnPlanet(static_cast(b), this, m_sbody->GetSeed()); } m_adjacentCity->Render(r, camera->GetContext()->GetFrustum(), this, viewCoords, viewTransform); @@ -754,13 +756,13 @@ void SpaceStation::SetLabel(const std::string &label) // find an empty position for a static ship and mark it as used. these aren't // saved and are only needed to help modules place bulk ships. this isn't a // great place for this, but its gotta be tracked somewhere -bool SpaceStation::AllocateStaticSlot(int& slot) +bool SpaceStation::AllocateStaticSlot(int &slot) { // no slots at ground stations if (IsGroundStation()) return false; - for (int i=0; i= m_type->NumDockingPorts()) break; if ((m_shipDocking[i].ship == Pi::player) && (m_shipDocking[i].stage > 0) && (m_shipDocking[i].stage != m_type->NumDockingStages() + 1)) { // last part is "not currently docked" SpaceStationType::positionOrient_t dport; - if (!m_type->GetShipApproachWaypoints(i, m_shipDocking[i].stage+1, dport)) + if (!m_type->GetShipApproachWaypoints(i, m_shipDocking[i].stage + 1, dport)) PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->NumDockingStages(), - 1.0f, vector3d(0.0), dport, m_shipDocking[i].ship)); + 1.0f, vector3d(0.0), dport, m_shipDocking[i].ship)); vector3d v = GetInterpPositionRelTo(relTo); return v + GetInterpOrientRelTo(relTo) * dport.pos; @@ -793,9 +795,9 @@ vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const bool SpaceStation::IsPortLocked(const int bay) const { - for (auto &bayIter : m_ports ) { - for ( auto &idIter : bayIter.bayIDs ) { - if (idIter.first==bay) { + for (auto &bayIter : m_ports) { + for (auto &idIter : bayIter.bayIDs) { + if (idIter.first == bay) { return bayIter.inUse; } } @@ -806,9 +808,9 @@ bool SpaceStation::IsPortLocked(const int bay) const void SpaceStation::LockPort(const int bay, const bool lockIt) { - for (auto &bayIter : m_ports ) { - for ( auto &idIter : bayIter.bayIDs ) { - if (idIter.first==bay) { + for (auto &bayIter : m_ports) { + for (auto &idIter : bayIter.bayIDs) { + if (idIter.first == bay) { bayIter.inUse = lockIt; return; } diff --git a/src/SpaceStation.h b/src/SpaceStation.h index 600b174bd..b45982cef 100644 --- a/src/SpaceStation.h +++ b/src/SpaceStation.h @@ -4,15 +4,15 @@ #ifndef _SPACESTATION_H #define _SPACESTATION_H -#include "libs.h" #include "Camera.h" #include "ModelBody.h" #include "NavLights.h" #include "Quaternion.h" #include "ShipType.h" #include "SpaceStationType.h" +#include "libs.h" -#define MAX_DOCKING_PORTS 240 //256-(0x10), 0x10 is used because the collision surfaces use it as an identifying flag +#define MAX_DOCKING_PORTS 240 //256-(0x10), 0x10 is used because the collision surfaces use it as an identifying flag class CityOnPlanet; class CollMeshSet; @@ -20,28 +20,33 @@ class Planet; class Ship; class SpaceStation; class SystemBody; -namespace Graphics { class Renderer; } -namespace SceneGraph { class Animation; } +namespace Graphics { + class Renderer; +} +namespace SceneGraph { + class Animation; +} -class SpaceStation: public ModelBody { +class SpaceStation : public ModelBody { public: OBJDEF(SpaceStation, ModelBody, SPACESTATION); static void Init(); // Should point to SystemBody in Pi::currentSystem SpaceStation(const SystemBody *); - SpaceStation() : m_type(nullptr) {} + SpaceStation() : + m_type(nullptr) {} virtual ~SpaceStation(); - virtual vector3d GetAngVelocity() const { return vector3d(0,m_type->AngVel(),0); } + virtual vector3d GetAngVelocity() const { return vector3d(0, m_type->AngVel(), 0); } virtual bool OnCollision(Object *b, Uint32 flags, double relVel) override; - bool DoShipDamage(Ship* s, Uint32 flags, double relVel); + bool DoShipDamage(Ship *s, Uint32 flags, double relVel); virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; virtual void StaticUpdate(const float timeStep) override; virtual void TimeStepUpdate(const float timeStep) override; virtual const SystemBody *GetSystemBody() const override { return m_sbody; } virtual void PostLoadFixup(Space *space) override; - virtual void NotifyRemoved(const Body* const removedBody) override; + virtual void NotifyRemoved(const Body *const removedBody) override; virtual void SetLabel(const std::string &label) override; @@ -60,7 +65,7 @@ public: const SpaceStationType *GetStationType() const { return m_type; } bool IsGroundStation() const; - bool AllocateStaticSlot(int& slot); + bool AllocateStaticSlot(int &slot); // use docking bay position, if player has been granted permission virtual vector3d GetTargetIndicatorPosition(const Frame *relTo) const override; @@ -91,9 +96,13 @@ private: * Stage -1 to -m_type->numUndockStages is undocking animation */ struct shipDocking_t { - shipDocking_t(): - ship(0), shipIndex(0), stage(0), stagePos(0), - fromPos(0.0), fromRot(1.0, 0.0, 0.0, 0.0), + shipDocking_t() : + ship(0), + shipIndex(0), + stage(0), + stagePos(0), + fromPos(0.0), + fromRot(1.0, 0.0, 0.0, 0.0), maxOffset(0) {} @@ -105,8 +114,8 @@ private: Quaterniond fromRot; double maxOffset; }; - typedef std::vector::const_iterator constShipDockingIter; - typedef std::vector::iterator shipDockingIter; + typedef std::vector::const_iterator constShipDockingIter; + typedef std::vector::iterator shipDockingIter; std::vector m_shipDocking; SpaceStationType::TPorts m_ports; diff --git a/src/SpaceStationType.cpp b/src/SpaceStationType.cpp index c719f45e5..4e3290ebc 100644 --- a/src/SpaceStationType.cpp +++ b/src/SpaceStationType.cpp @@ -3,13 +3,13 @@ #include "SpaceStationType.h" #include "FileSystem.h" -#include "Pi.h" +#include "Json.h" #include "MathUtil.h" +#include "OS.h" +#include "Pi.h" #include "Ship.h" #include "StringF.h" #include "scenegraph/Model.h" -#include "OS.h" -#include "Json.h" #include @@ -19,18 +19,18 @@ struct StationTypeLoadError {}; std::vector SpaceStationType::surfaceTypes; std::vector SpaceStationType::orbitalTypes; -SpaceStationType::SpaceStationType(const std::string &id_, const std::string &path_) - : id(id_) - , model(0) - , modelName("") - , angVel(0.f) - , dockMethod(SURFACE) - , numDockingPorts(0) - , numDockingStages(0) - , numUndockStages(0) - , shipLaunchStage(3) - , parkingDistance(0) - , parkingGapSize(0) +SpaceStationType::SpaceStationType(const std::string &id_, const std::string &path_) : + id(id_), + model(0), + modelName(""), + angVel(0.f), + dockMethod(SURFACE), + numDockingPorts(0), + numDockingStages(0), + numUndockStages(0), + shipLaunchStage(3), + parkingDistance(0), + parkingGapSize(0) { Json data = JsonUtils::LoadJsonDataFile(path_); if (data.is_null()) { @@ -78,7 +78,7 @@ void SpaceStationType::OnSetupComplete() // This mostly means offsetting from one locator to create the next in the sequence. // ground stations have a "special-fucking-case" 0 stage launch process - shipLaunchStage = ((SURFACE==dockMethod) ? 0 : 3); + shipLaunchStage = ((SURFACE == dockMethod) ? 0 : 3); // gather the tags SceneGraph::Model::TVecMT entrance_mts; @@ -91,31 +91,29 @@ void SpaceStationType::OnSetupComplete() Output("%s has:\n %lu entrances,\n %lu pads,\n %lu exits\n", modelName.c_str(), entrance_mts.size(), locator_mts.size(), exit_mts.size()); // Add the partially initialised ports - for (auto apprIter : entrance_mts) - { + for (auto apprIter : entrance_mts) { int portId; PiVerify(1 == sscanf(apprIter->GetName().c_str(), "entrance_port%d", &portId)); - PiVerify(portId>0); + PiVerify(portId > 0); SPort new_port; new_port.portId = portId; new_port.name = apprIter->GetName(); - if(SURFACE==dockMethod) { + if (SURFACE == dockMethod) { const vector3f offDir = apprIter->GetTransform().Up().Normalized(); new_port.m_approach[1] = apprIter->GetTransform(); - new_port.m_approach[1].SetTranslate( apprIter->GetTransform().GetTranslate() + (offDir * 500.0f) ); + new_port.m_approach[1].SetTranslate(apprIter->GetTransform().GetTranslate() + (offDir * 500.0f)); } else { const vector3f offDir = -apprIter->GetTransform().Back().Normalized(); new_port.m_approach[1] = apprIter->GetTransform(); - new_port.m_approach[1].SetTranslate( apprIter->GetTransform().GetTranslate() + (offDir * 1500.0f) ); + new_port.m_approach[1].SetTranslate(apprIter->GetTransform().GetTranslate() + (offDir * 1500.0f)); } new_port.m_approach[2] = apprIter->GetTransform(); - m_ports.push_back( new_port ); + m_ports.push_back(new_port); } - int bay=0; - for (auto locIter : locator_mts) - { + int bay = 0; + for (auto locIter : locator_mts) { int bayStr, portId; int minSize, maxSize; char padname[8]; @@ -125,17 +123,17 @@ void SpaceStationType::OnSetupComplete() // eg:loc_A001_p01_s0_500_b01 PiVerify(5 == sscanf(locIter->GetName().c_str(), "loc_%4s_p%d_s%d_%d_b%d", &padname[0], &portId, &minSize, &maxSize, &bayStr)); - PiVerify(bay>0 && portId>0); + PiVerify(bay > 0 && portId > 0); // find the port and setup the rest of it's information bool bFoundPort = false; matrix4x4f approach1(0.0); matrix4x4f approach2(0.0); - for(auto &rPort : m_ports) { - if(rPort.portId == portId) { - rPort.minShipSize = std::min(minSize,rPort.minShipSize); - rPort.maxShipSize = std::max(maxSize,rPort.maxShipSize); - rPort.bayIDs.push_back( std::make_pair(bay-1, padname) ); + for (auto &rPort : m_ports) { + if (rPort.portId == portId) { + rPort.minShipSize = std::min(minSize, rPort.minShipSize); + rPort.maxShipSize = std::max(maxSize, rPort.maxShipSize); + rPort.bayIDs.push_back(std::make_pair(bay - 1, padname)); bFoundPort = true; approach1 = rPort.m_approach[1]; approach2 = rPort.m_approach[2]; @@ -145,33 +143,29 @@ void SpaceStationType::OnSetupComplete() assert(bFoundPort); // now build the docking/leaving waypoints - if( SURFACE == dockMethod ) - { + if (SURFACE == dockMethod) { // ground stations don't have leaving waypoints. m_portPaths[bay].m_docking[2] = locTransform; // final (docked) numDockingStages = 2; numUndockStages = 1; - } - else - { - struct TPointLine - { + } else { + struct TPointLine { // for reference: http://paulbourke.net/geometry/pointlineplane/ - static bool ClosestPointOnLine( const vector3f &Point, const vector3f &LineStart, const vector3f &LineEnd, vector3f &Intersection ) + static bool ClosestPointOnLine(const vector3f &Point, const vector3f &LineStart, const vector3f &LineEnd, vector3f &Intersection) { - const float LineMag = ( LineStart - LineEnd ).Length(); + const float LineMag = (LineStart - LineEnd).Length(); - const float U = ( ( ( Point.x - LineStart.x ) * ( LineEnd.x - LineStart.x ) ) + - ( ( Point.y - LineStart.y ) * ( LineEnd.y - LineStart.y ) ) + - ( ( Point.z - LineStart.z ) * ( LineEnd.z - LineStart.z ) ) ) / - ( LineMag * LineMag ); + const float U = (((Point.x - LineStart.x) * (LineEnd.x - LineStart.x)) + + ((Point.y - LineStart.y) * (LineEnd.y - LineStart.y)) + + ((Point.z - LineStart.z) * (LineEnd.z - LineStart.z))) / + (LineMag * LineMag); - if( U < 0.0f || U > 1.0f ) - return false; // closest point does not fall within the line segment + if (U < 0.0f || U > 1.0f) + return false; // closest point does not fall within the line segment - Intersection.x = LineStart.x + U * ( LineEnd.x - LineStart.x ); - Intersection.y = LineStart.y + U * ( LineEnd.y - LineStart.y ); - Intersection.z = LineStart.z + U * ( LineEnd.z - LineStart.z ); + Intersection.x = LineStart.x + U * (LineEnd.x - LineStart.x); + Intersection.y = LineStart.y + U * (LineEnd.y - LineStart.y); + Intersection.z = LineStart.z + U * (LineEnd.z - LineStart.z); return true; } @@ -180,7 +174,7 @@ void SpaceStationType::OnSetupComplete() // create the docking locators // start m_portPaths[bay].m_docking[2] = approach2; - m_portPaths[bay].m_docking[2].SetRotationOnly( locTransform.GetOrient() ); + m_portPaths[bay].m_docking[2].SetRotationOnly(locTransform.GetOrient()); // above the pad vector3f intersectionPos(0.0f); const vector3f approach1Pos = approach1.GetTranslate(); @@ -188,44 +182,39 @@ void SpaceStationType::OnSetupComplete() { const vector3f p0 = locTransform.GetTranslate(); // plane position const vector3f l = (approach2Pos - approach1Pos).Normalized(); // ray direction - const vector3f l0 = approach1Pos + (l*10000.0f); + const vector3f l0 = approach1Pos + (l * 10000.0f); - if(!TPointLine::ClosestPointOnLine(p0, approach1Pos, l0, intersectionPos)) { + if (!TPointLine::ClosestPointOnLine(p0, approach1Pos, l0, intersectionPos)) { Output("No point found on line segment"); } } m_portPaths[bay].m_docking[3] = locTransform; - m_portPaths[bay].m_docking[3].SetTranslate( intersectionPos ); + m_portPaths[bay].m_docking[3].SetTranslate(intersectionPos); // final (docked) m_portPaths[bay].m_docking[4] = locTransform; numDockingStages = 4; // leaving locators ... matrix4x4f orient = locTransform.GetOrient(), EndOrient; - if( exit_mts.empty() ) - { + if (exit_mts.empty()) { // leaving locators need to face in the opposite direction const matrix4x4f rot = matrix3x3f::Rotate(DEG2RAD(180.0f), orient.Back()); orient = orient * rot; - orient.SetTranslate( locTransform.GetTranslate() ); + orient.SetTranslate(locTransform.GetTranslate()); EndOrient = approach2; EndOrient.SetRotationOnly(orient); - } - else - { + } else { // leaving locators, use whatever orientation they have - orient.SetTranslate( locTransform.GetTranslate() ); + orient.SetTranslate(locTransform.GetTranslate()); int exitport = 0; - for( auto &exitIt : exit_mts ) { - PiVerify(1 == sscanf( exitIt->GetName().c_str(), "exit_port%d", &exitport )); - if( exitport == portId ) - { + for (auto &exitIt : exit_mts) { + PiVerify(1 == sscanf(exitIt->GetName().c_str(), "exit_port%d", &exitport)); + if (exitport == portId) { EndOrient = exitIt->GetTransform(); break; } } - if( exitport == 0 ) - { + if (exitport == 0) { EndOrient = approach2; } } @@ -233,7 +222,7 @@ void SpaceStationType::OnSetupComplete() // create the leaving locators m_portPaths[bay].m_leaving[1] = locTransform; // start - maintain the same orientation and position as when docked. m_portPaths[bay].m_leaving[2] = orient; // above the pad - reorient... - m_portPaths[bay].m_leaving[2].SetTranslate( intersectionPos ); // ...and translate to new position + m_portPaths[bay].m_leaving[2].SetTranslate(intersectionPos); // ...and translate to new position m_portPaths[bay].m_leaving[3] = EndOrient; // end (on manual after here) numUndockStages = 3; } @@ -247,41 +236,39 @@ void SpaceStationType::OnSetupComplete() assert(numUndockStages > 0); // insanity - for (PortPathMap::const_iterator pIt = m_portPaths.begin(), pItEnd = m_portPaths.end(); pIt!=pItEnd; ++pIt) - { - if (Uint32(numDockingStages-1) < pIt->second.m_docking.size()) { + for (PortPathMap::const_iterator pIt = m_portPaths.begin(), pItEnd = m_portPaths.end(); pIt != pItEnd; ++pIt) { + if (Uint32(numDockingStages - 1) < pIt->second.m_docking.size()) { Error( "(%s): numDockingStages (%d) vs number of docking stages (" SIZET_FMT ")\n" "Must have at least the same number of entries as the number of docking stages " "PLUS the docking timeout at the start of the array.", - modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size()); + modelName.c_str(), (numDockingStages - 1), pIt->second.m_docking.size()); - } else if (Uint32(numDockingStages-1) != pIt->second.m_docking.size()) { + } else if (Uint32(numDockingStages - 1) != pIt->second.m_docking.size()) { Warning( "(%s): numDockingStages (%d) vs number of docking stages (" SIZET_FMT ")\n", - modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size()); + modelName.c_str(), (numDockingStages - 1), pIt->second.m_docking.size()); } - if (0!=pIt->second.m_leaving.size() && Uint32(numUndockStages) < pIt->second.m_leaving.size()) { + if (0 != pIt->second.m_leaving.size() && Uint32(numUndockStages) < pIt->second.m_leaving.size()) { Error( "(%s): numUndockStages (%d) vs number of leaving stages (" SIZET_FMT ")\n" "Must have at least the same number of entries as the number of leaving stages.", - modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size()); + modelName.c_str(), (numDockingStages - 1), pIt->second.m_docking.size()); - } else if(0!=pIt->second.m_leaving.size() && Uint32(numUndockStages) != pIt->second.m_leaving.size()) { + } else if (0 != pIt->second.m_leaving.size() && Uint32(numUndockStages) != pIt->second.m_leaving.size()) { Warning( "(%s): numUndockStages (%d) vs number of leaving stages (" SIZET_FMT ")\n", modelName.c_str(), numUndockStages, pIt->second.m_leaving.size()); } - } } -const SpaceStationType::SPort* SpaceStationType::FindPortByBay(const int zeroBaseBayID) const +const SpaceStationType::SPort *SpaceStationType::FindPortByBay(const int zeroBaseBayID) const { - for (TPorts::const_iterator bayIter = m_ports.begin(), grpEnd=m_ports.end(); bayIter!=grpEnd ; ++bayIter ) { - for (auto idIter : (*bayIter).bayIDs ) { - if (idIter.first==zeroBaseBayID) { + for (TPorts::const_iterator bayIter = m_ports.begin(), grpEnd = m_ports.end(); bayIter != grpEnd; ++bayIter) { + for (auto idIter : (*bayIter).bayIDs) { + if (idIter.first == zeroBaseBayID) { return &(*bayIter); } } @@ -290,11 +277,11 @@ const SpaceStationType::SPort* SpaceStationType::FindPortByBay(const int zeroBas return 0; } -SpaceStationType::SPort* SpaceStationType::GetPortByBay(const int zeroBaseBayID) +SpaceStationType::SPort *SpaceStationType::GetPortByBay(const int zeroBaseBayID) { - for (TPorts::iterator bayIter = m_ports.begin(), grpEnd=m_ports.end(); bayIter!=grpEnd ; ++bayIter ) { - for (auto idIter : (*bayIter).bayIDs ) { - if (idIter.first==zeroBaseBayID) { + for (TPorts::iterator bayIter = m_ports.begin(), grpEnd = m_ports.end(); bayIter != grpEnd; ++bayIter) { + for (auto idIter : (*bayIter).bayIDs) { + if (idIter.first == zeroBaseBayID) { return &(*bayIter); } } @@ -307,18 +294,18 @@ bool SpaceStationType::GetShipApproachWaypoints(const unsigned int port, const i { bool gotOrient = false; - const SPort* pPort = FindPortByBay(port); - if (pPort && stage>0) { + const SPort *pPort = FindPortByBay(port); + if (pPort && stage > 0) { TMapBayIDMat::const_iterator stageDataIt = pPort->m_approach.find(stage); if (stageDataIt != pPort->m_approach.end()) { const matrix4x4f &mt = pPort->m_approach.at(stage); - outPosOrient.pos = vector3d(mt.GetTranslate()); - outPosOrient.xaxis = vector3d(mt.GetOrient().VectorX()); - outPosOrient.yaxis = vector3d(mt.GetOrient().VectorY()); - outPosOrient.zaxis = vector3d(mt.GetOrient().VectorZ()); - outPosOrient.xaxis = outPosOrient.xaxis.Normalized(); - outPosOrient.yaxis = outPosOrient.yaxis.Normalized(); - outPosOrient.zaxis = outPosOrient.zaxis.Normalized(); + outPosOrient.pos = vector3d(mt.GetTranslate()); + outPosOrient.xaxis = vector3d(mt.GetOrient().VectorX()); + outPosOrient.yaxis = vector3d(mt.GetOrient().VectorY()); + outPosOrient.zaxis = vector3d(mt.GetOrient().VectorZ()); + outPosOrient.xaxis = outPosOrient.xaxis.Normalized(); + outPosOrient.yaxis = outPosOrient.yaxis.Normalized(); + outPosOrient.zaxis = outPosOrient.zaxis.Normalized(); gotOrient = true; } } @@ -327,37 +314,36 @@ bool SpaceStationType::GetShipApproachWaypoints(const unsigned int port, const i double SpaceStationType::GetDockAnimStageDuration(const int stage) const { - return (stage==0) ? 300.0 : ((SURFACE==dockMethod) ? 0.0 : 3.0); + return (stage == 0) ? 300.0 : ((SURFACE == dockMethod) ? 0.0 : 3.0); } double SpaceStationType::GetUndockAnimStageDuration(const int stage) const { - return ((SURFACE==dockMethod) ? 0.0 : 5.0); + return ((SURFACE == dockMethod) ? 0.0 : 5.0); } static bool GetPosOrient(const SpaceStationType::TMapBayIDMat &bayMap, const int stage, const double t, const vector3d &from, - SpaceStationType::positionOrient_t &outPosOrient) + SpaceStationType::positionOrient_t &outPosOrient) { bool gotOrient = false; vector3d toPos; - const SpaceStationType::TMapBayIDMat::const_iterator stageDataIt = bayMap.find( stage ); + const SpaceStationType::TMapBayIDMat::const_iterator stageDataIt = bayMap.find(stage); const bool bHasStageData = (stageDataIt != bayMap.end()); assert(bHasStageData); if (bHasStageData) { const matrix4x4f &mt = stageDataIt->second; - outPosOrient.xaxis = vector3d(mt.GetOrient().VectorX()).Normalized(); - outPosOrient.yaxis = vector3d(mt.GetOrient().VectorY()).Normalized(); - outPosOrient.zaxis = vector3d(mt.GetOrient().VectorZ()).Normalized(); - toPos = vector3d(mt.GetTranslate()); + outPosOrient.xaxis = vector3d(mt.GetOrient().VectorX()).Normalized(); + outPosOrient.yaxis = vector3d(mt.GetOrient().VectorY()).Normalized(); + outPosOrient.zaxis = vector3d(mt.GetOrient().VectorZ()).Normalized(); + toPos = vector3d(mt.GetTranslate()); gotOrient = true; } - if (gotOrient) - { - vector3d pos = MathUtil::mix(from, toPos, t); - outPosOrient.pos = pos; + if (gotOrient) { + vector3d pos = MathUtil::mix(from, toPos, t); + outPosOrient.pos = pos; } return gotOrient; @@ -370,20 +356,26 @@ static bool GetPosOrient(const SpaceStationType::TMapBayIDMat &bayMap, const int bool SpaceStationType::GetDockAnimPositionOrient(const unsigned int port, int stage, double t, const vector3d &from, positionOrient_t &outPosOrient, const Ship *ship) const { assert(ship); - if (stage < -shipLaunchStage) { stage = -shipLaunchStage; t = 1.0; } - if (stage > numDockingStages || !stage) { stage = numDockingStages; t = 1.0; } + if (stage < -shipLaunchStage) { + stage = -shipLaunchStage; + t = 1.0; + } + if (stage > numDockingStages || !stage) { + stage = numDockingStages; + t = 1.0; + } // note case for stageless launch (shipLaunchStage==0) bool gotOrient = false; - assert(port<=m_portPaths.size()); - const PortPath &rPortPath = m_portPaths.at(port+1); - if (stage<0) { - const int leavingStage = (-1*stage); + assert(port <= m_portPaths.size()); + const PortPath &rPortPath = m_portPaths.at(port + 1); + if (stage < 0) { + const int leavingStage = (-1 * stage); gotOrient = GetPosOrient(rPortPath.m_leaving, leavingStage, t, from, outPosOrient); const vector3d up = outPosOrient.yaxis.Normalized() * ship->GetLandingPosOffset(); outPosOrient.pos = outPosOrient.pos - up; - } else if (stage>0) { + } else if (stage > 0) { gotOrient = GetPosOrient(rPortPath.m_docking, stage, t, from, outPosOrient); const vector3d up = outPosOrient.yaxis.Normalized() * ship->GetLandingPosOffset(); outPosOrient.pos = outPosOrient.pos - up; @@ -405,12 +397,12 @@ void SpaceStationType::Init() for (fs::FileEnumerator files(fs::gameDataFiles, "stations", 0); !files.Finished(); files.Next()) { const fs::FileInfo &info = files.Current(); if (ends_with_ci(info.GetPath(), ".json")) { - const std::string id(info.GetName().substr(0, info.GetName().size()-5)); + const std::string id(info.GetName().substr(0, info.GetName().size() - 5)); try { SpaceStationType st = SpaceStationType(id, info.GetPath()); switch (st.dockMethod) { - case SURFACE: surfaceTypes.push_back(st); break; - case ORBITAL: orbitalTypes.push_back(st); break; + case SURFACE: surfaceTypes.push_back(st); break; + case ORBITAL: orbitalTypes.push_back(st); break; } } catch (StationTypeLoadError) { // TODO: Actual error handling would be nice. @@ -421,22 +413,23 @@ void SpaceStationType::Init() } /*static*/ -const SpaceStationType* SpaceStationType::RandomStationType(Random &random, const bool bIsGround) +const SpaceStationType *SpaceStationType::RandomStationType(Random &random, const bool bIsGround) { if (bIsGround) { - return &surfaceTypes[ random.Int32(SpaceStationType::surfaceTypes.size()) ]; + return &surfaceTypes[random.Int32(SpaceStationType::surfaceTypes.size())]; } - return &orbitalTypes[ random.Int32(SpaceStationType::orbitalTypes.size()) ]; + return &orbitalTypes[random.Int32(SpaceStationType::orbitalTypes.size())]; } /*static*/ -const SpaceStationType *SpaceStationType::FindByName(const std::string &name) { - for(auto &sst : surfaceTypes) - if(sst.id == name) +const SpaceStationType *SpaceStationType::FindByName(const std::string &name) +{ + for (auto &sst : surfaceTypes) + if (sst.id == name) return &sst; - for(auto &sst : orbitalTypes) - if(sst.id == name) + for (auto &sst : orbitalTypes) + if (sst.id == name) return &sst; return nullptr; } diff --git a/src/SpaceStationType.h b/src/SpaceStationType.h index 79685d243..9ffe5fb9a 100644 --- a/src/SpaceStationType.h +++ b/src/SpaceStationType.h @@ -9,13 +9,14 @@ //Space station definition, loaded from data/stations class Ship; -namespace SceneGraph { class Model; } +namespace SceneGraph { + class Model; +} class SpaceStationType { public: typedef std::map TMapBayIDMat; - struct PortPath - { + struct PortPath { TMapBayIDMat m_docking; TMapBayIDMat m_leaving; }; @@ -23,11 +24,15 @@ public: struct SPort { static const int BAD_PORT_ID = -1; - SPort() : portId(BAD_PORT_ID), minShipSize(5000), maxShipSize(-1), inUse(false) {} + SPort() : + portId(BAD_PORT_ID), + minShipSize(5000), + maxShipSize(-1), + inUse(false) {} int portId; int minShipSize, maxShipSize; bool inUse; - std::vector > bayIDs; + std::vector> bayIDs; std::string name; TMapBayIDMat m_approach; }; @@ -45,7 +50,8 @@ private: SceneGraph::Model *model; std::string modelName; float angVel; - enum DOCKMETHOD { SURFACE, ORBITAL } dockMethod; + enum DOCKMETHOD { SURFACE, + ORBITAL } dockMethod; unsigned int numDockingPorts; int numDockingStages; int numUndockStages; @@ -63,8 +69,8 @@ public: SpaceStationType(const std::string &id, const std::string &path); void OnSetupComplete(); - const SPort* FindPortByBay(const int zeroBaseBayID) const; - SPort* GetPortByBay(const int zeroBaseBayID); + const SPort *FindPortByBay(const int zeroBaseBayID) const; + SPort *GetPortByBay(const int zeroBaseBayID); double GetDockAnimStageDuration(const int stage) const; double GetUndockAnimStageDuration(const int stage) const; @@ -77,21 +83,21 @@ public: * ship has been released and is under player control again */ bool GetDockAnimPositionOrient(const unsigned int port, int stage, double t, const vector3d &from, positionOrient_t &outPosOrient, const Ship *ship) const; - const std::string& ModelName() const { return modelName; } + const std::string &ModelName() const { return modelName; } float AngVel() const { return angVel; } - bool IsSurfaceStation() const { return (SURFACE==dockMethod); } - bool IsOrbitalStation() const { return (ORBITAL==dockMethod); } + bool IsSurfaceStation() const { return (SURFACE == dockMethod); } + bool IsOrbitalStation() const { return (ORBITAL == dockMethod); } unsigned int NumDockingPorts() const { return numDockingPorts; } int NumDockingStages() const { return numDockingStages; } int NumUndockStages() const { return numUndockStages; } int ShipLaunchStage() const { return shipLaunchStage; } float ParkingDistance() const { return parkingDistance; } float ParkingGapSize() const { return parkingGapSize; } - const TPorts& Ports() const { return m_ports; } + const TPorts &Ports() const { return m_ports; } static void Init(); - static const SpaceStationType* RandomStationType(Random &random, const bool bIsGround); + static const SpaceStationType *RandomStationType(Random &random, const bool bIsGround); static const SpaceStationType *FindByName(const std::string &name); }; diff --git a/src/SpeedLines.cpp b/src/SpeedLines.cpp index 479528008..b73c6e61a 100644 --- a/src/SpeedLines.cpp +++ b/src/SpeedLines.cpp @@ -2,22 +2,22 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "SpeedLines.h" +#include "FileSystem.h" +#include "IniConfig.h" +#include "Pi.h" #include "Ship.h" #include "graphics/RenderState.h" -#include "Pi.h" -#include "IniConfig.h" -#include "FileSystem.h" // default values -float SpeedLines::BOUNDS = 2000.f; -int SpeedLines::DEPTH = 9; -float SpeedLines::SPACING = 750.f; -float SpeedLines::MAX_VEL = 100.f; +float SpeedLines::BOUNDS = 2000.f; +int SpeedLines::DEPTH = 9; +float SpeedLines::SPACING = 750.f; +float SpeedLines::MAX_VEL = 100.f; -SpeedLines::SpeedLines(Ship *s) -: m_ship(s) -, m_visible(false) -, m_dir(0.f) +SpeedLines::SpeedLines(Ship *s) : + m_ship(s), + m_visible(false), + m_dir(0.f) { PROFILE_SCOPED(); @@ -25,9 +25,9 @@ SpeedLines::SpeedLines(Ship *s) SpeedLines::Init(); m_points.reserve(DEPTH * DEPTH * DEPTH); - for (int x = -DEPTH/2; x < DEPTH/2; x++) { - for (int y = -DEPTH/2; y < DEPTH/2; y++) { - for (int z = -DEPTH/2; z < DEPTH/2; z++) { + for (int x = -DEPTH / 2; x < DEPTH / 2; x++) { + for (int y = -DEPTH / 2; y < DEPTH / 2; y++) { + for (int z = -DEPTH / 2; z < DEPTH / 2; z++) { m_points.push_back(vector3f(x * SPACING, y * SPACING, z * SPACING)); } } @@ -35,7 +35,7 @@ SpeedLines::SpeedLines(Ship *s) const Uint32 doubleNumPoints = static_cast(m_points.size()) * 2; m_varray.reset(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, doubleNumPoints)); - for( Uint32 i = 0; i < doubleNumPoints; i++ ) + for (Uint32 i = 0; i < doubleNumPoints; i++) m_varray->Add(vector3f(0.0f), Color::BLACK); Graphics::RenderStateDesc rsd; @@ -43,7 +43,7 @@ SpeedLines::SpeedLines(Ship *s) rsd.depthWrite = false; m_renderState = Pi::renderer->CreateRenderState(rsd); - CreateVertexBuffer( Pi::renderer, doubleNumPoints ); + CreateVertexBuffer(Pi::renderer, doubleNumPoints); } void SpeedLines::Update(float time) @@ -117,15 +117,15 @@ void SpeedLines::Render(Graphics::Renderer *r) //distance fade Color col(Color::GRAY); for (auto it = m_points.begin(); it != m_points.end(); ++it) { - col.a = Clamp((1.f - it->Length() / BOUNDS),0.f,1.f) * 255; + col.a = Clamp((1.f - it->Length() / BOUNDS), 0.f, 1.f) * 255; m_varray->Set(vtx, *it - dir, col); - m_varray->Set(vtx+1,*it + dir, col); + m_varray->Set(vtx + 1, *it + dir, col); vtx += 2; } - m_vbuffer->Populate( *m_varray ); + m_vbuffer->Populate(*m_varray); r->SetTransform(m_transform); r->DrawBuffer(m_vbuffer.get(), m_renderState, m_material.Get(), Graphics::LINE_SINGLE); @@ -154,8 +154,8 @@ void SpeedLines::Init() cfg.Read(FileSystem::gameDataFiles, "configs/SpeedLines.ini"); // NB: limit the ranges of all values loaded from the file - BOUNDS = Clamp(cfg.Float("bounds", 2000.0f), 100.0f, 4000.0f); - DEPTH = Clamp(cfg.Int("depth", 9), 1, 32); - SPACING = Clamp(cfg.Float("spacing", 750.0f), 250.0f, 2000.0f); - MAX_VEL = Clamp(cfg.Float("max_vel", 100.0f), 50.0f, 200.0f); + BOUNDS = Clamp(cfg.Float("bounds", 2000.0f), 100.0f, 4000.0f); + DEPTH = Clamp(cfg.Int("depth", 9), 1, 32); + SPACING = Clamp(cfg.Float("spacing", 750.0f), 250.0f, 2000.0f); + MAX_VEL = Clamp(cfg.Float("max_vel", 100.0f), 50.0f, 200.0f); } diff --git a/src/SpeedLines.h b/src/SpeedLines.h index cc729b886..325a6e16b 100644 --- a/src/SpeedLines.h +++ b/src/SpeedLines.h @@ -6,18 +6,17 @@ // virtual space dust to give a sense of movement -#include "libs.h" #include "graphics/Renderer.h" +#include "libs.h" class Ship; -class SpeedLines -{ +class SpeedLines { public: - SpeedLines(Ship*); + SpeedLines(Ship *); void Update(float time); - void Render(Graphics::Renderer*); + void Render(Graphics::Renderer *); void SetTransform(const matrix4x4d &t) { m_transform = t; } @@ -26,7 +25,7 @@ public: private: static void Init(); static float BOUNDS; - static int DEPTH; + static int DEPTH; static float SPACING; static float MAX_VEL; diff --git a/src/Sphere.cpp b/src/Sphere.cpp index e2e1480b9..a9d75f5fd 100644 --- a/src/Sphere.cpp +++ b/src/Sphere.cpp @@ -1,8 +1,8 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Sphere.h" +#include "libs.h" #include "Plane.h" @@ -17,7 +17,7 @@ /// @return true if the object's bounding sphere is visible from the viewpoint, false if the /// sphere is in the shadow cone AND not in front of the capping plane. /// -bool SSphere::HorizonCulling(const vector3d& view, const SSphere& obj) const +bool SSphere::HorizonCulling(const vector3d &view, const SSphere &obj) const { vector3d O1C = m_centre - view; vector3d O2C = obj.m_centre - view; @@ -36,8 +36,7 @@ bool SSphere::HorizonCulling(const vector3d& view, const SSphere& obj) const const double K1 = R1 * iD1; const double K2 = R2 * iD2; bool status = true; - if ( K > K1 * K2 ) - { + if (K > K1 * K2) { status = (-2.0 * K * K1 * K2 + K1 * K1 + K2 * K2) < (1.0 - K * K); } diff --git a/src/Sphere.h b/src/Sphere.h index 237ac8b14..c40ff3ed7 100644 --- a/src/Sphere.h +++ b/src/Sphere.h @@ -11,13 +11,17 @@ #include "vector3.h" struct SSphere { - SSphere() : m_centre(vector3d(0.0)), m_radius(1.0) {} - SSphere(const double rad) : m_centre(vector3d(0.0)), m_radius(rad) {} + SSphere() : + m_centre(vector3d(0.0)), + m_radius(1.0) {} + SSphere(const double rad) : + m_centre(vector3d(0.0)), + m_radius(rad) {} vector3d m_centre; double m_radius; // Adapted from Ysaneya here: http://www.gamedev.net/blog/73/entry-1666972-horizon-culling/ - bool HorizonCulling(const vector3d& view, const SSphere& obj) const; + bool HorizonCulling(const vector3d &view, const SSphere &obj) const; }; #endif /* _SPHERE_H */ diff --git a/src/Star.cpp b/src/Star.cpp index 6e014e322..2d5cb2965 100644 --- a/src/Star.cpp +++ b/src/Star.cpp @@ -2,27 +2,29 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Star.h" +#include "Pi.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" #include "gui/Gui.h" -#include "Pi.h" #include using namespace Graphics; -Star::Star() : TerrainBody() +Star::Star() : + TerrainBody() { } -Star::Star(SystemBody *sbody): TerrainBody(sbody) +Star::Star(SystemBody *sbody) : + TerrainBody(sbody) { InitStar(); } void Star::LoadFromJson(const Json &jsonObj, Space *space) { - TerrainBody::LoadFromJson(jsonObj, space); // to get sbody + TerrainBody::LoadFromJson(jsonObj, space); // to get sbody InitStar(); } @@ -53,7 +55,7 @@ void Star::Render(Graphics::Renderer *renderer, const Camera *camera, const vect while (len > 1000.0f) { rad *= 0.25; - fpos = 0.25*fpos; + fpos = 0.25 * fpos; len *= 0.25; } @@ -62,7 +64,7 @@ void Star::Render(Graphics::Renderer *renderer, const Camera *camera, const vect // face the camera dammit vector3d zaxis = viewCoords.NormalizedSafe(); - vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized(); + vector3d xaxis = vector3d(0, 1, 0).Cross(zaxis).Normalized(); vector3d yaxis = zaxis.Cross(xaxis); matrix4x4d rot = matrix4x4d::MakeRotMatrix(xaxis, yaxis, zaxis).Inverse(); @@ -76,8 +78,8 @@ void Star::Render(Graphics::Renderer *renderer, const Camera *camera, const vect const Color dark(Color::BLANK); va.Add(vector3f(0.f), bright); - for (float ang=0; ang<2*M_PI; ang+=0.26183+rand.Double(0,0.4)) { - va.Add(vector3f(rad*sin(ang), rad*cos(ang), 0), dark); + for (float ang = 0; ang < 2 * M_PI; ang += 0.26183 + rand.Double(0, 0.4)) { + va.Add(vector3f(rad * sin(ang), rad * cos(ang), 0), dark); } va.Add(vector3f(0.f, rad, 0.f), dark); diff --git a/src/Star.h b/src/Star.h index baee6ca6e..a7503aa13 100644 --- a/src/Star.h +++ b/src/Star.h @@ -7,16 +7,19 @@ #include "TerrainBody.h" #include "graphics/RenderState.h" -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} -class Star: public TerrainBody { +class Star : public TerrainBody { public: OBJDEF(Star, TerrainBody, STAR); Star(SystemBody *sbody); Star(); - virtual ~Star() {}; + virtual ~Star(){}; virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override; + protected: void InitStar(); virtual void LoadFromJson(const Json &jsonObj, Space *space) override; diff --git a/src/StringF.cpp b/src/StringF.cpp index 7b42ae268..ac6cb8a63 100644 --- a/src/StringF.cpp +++ b/src/StringF.cpp @@ -6,57 +6,68 @@ #include #include -#include #include #include +#include // --------------------------------------------------------------------------- // ## FormatSpec -FormatSpec::FormatSpec(): format("") { +FormatSpec::FormatSpec() : + format("") +{ for (int i = 0; i <= MAX_PARAMS; ++i) params[i] = 0; } -FormatSpec::FormatSpec(const char* format_): format(format_) { +FormatSpec::FormatSpec(const char *format_) : + format(format_) +{ assert(format_); parseFormat(strlen(format)); } -FormatSpec::FormatSpec(const char* format_, int formatlen_): format(format_) { +FormatSpec::FormatSpec(const char *format_, int formatlen_) : + format(format_) +{ assert(format_ && (formatlen_ >= 0)); parseFormat(formatlen_); } -bool FormatSpec::empty() const { +bool FormatSpec::empty() const +{ return (params[MAX_PARAMS] == 0); } -bool FormatSpec::specifierIs(const char* specifier) const { +bool FormatSpec::specifierIs(const char *specifier) const +{ int len = params[0]; - if (len && (format[len-1] == ':')) + if (len && (format[len - 1] == ':')) --len; return (strncmp(specifier, format, len) == 0); } -int FormatSpec::paramCount() const { +int FormatSpec::paramCount() const +{ int i = 0; - while ((i < MAX_PARAMS) && (params[i] < params[i+1])) + while ((i < MAX_PARAMS) && (params[i] < params[i + 1])) ++i; return i; } -std::string FormatSpec::param(int idx) const { +std::string FormatSpec::param(int idx) const +{ const char *beg, *end; paramPtr(idx, beg, end); std::string str; str.reserve(end - beg); - const char* c = beg; + const char *c = beg; while (c != end) { // scan to the next escape character or the end of the segment - while ((c != end) && (*c != '\\')) ++c; + while ((c != end) && (*c != '\\')) + ++c; // append this run of unescaped characters str.append(beg, (c - beg)); // if we're not at the end, we must have hit a backslash @@ -75,29 +86,32 @@ std::string FormatSpec::param(int idx) const { return str; } -void FormatSpec::paramPtr(int idx, const char*& begin, const char*& end) const { +void FormatSpec::paramPtr(int idx, const char *&begin, const char *&end) const +{ assert(idx >= 0 && idx < MAX_PARAMS); - begin = &format[ params[idx] ]; - end = &format[ params[idx+1] ]; + begin = &format[params[idx]]; + end = &format[params[idx + 1]]; // if it's not the last parameter, then we need to shift end back one, // to account for the '|' character that separates parameters // note: the last character of a parameter may legitimately be a '|', e.g. // in %foo{bar:qux\|} // param 0 (before escape processing) is exactly ``qux\|'' - if ((idx+1 < MAX_PARAMS) && (params[idx+2] > params[idx+1])) + if ((idx + 1 < MAX_PARAMS) && (params[idx + 2] > params[idx + 1])) --end; } -void FormatSpec::parseFormat(int length) { +void FormatSpec::parseFormat(int length) +{ // length limit due to the type used for the params[] array assert((length >= 0) && (length <= USHRT_MAX)); assert(format); // format should already have been set - const char* c = format; - const char* end = &format[length]; + const char *c = format; + const char *end = &format[length]; // scan the specifier - while ((c != end) && isalpha(*c)) ++c; + while ((c != end) && isalpha(*c)) + ++c; // skip the optional ':' separating the specifier and the first parameter if (*c == ':') ++c; @@ -128,47 +142,58 @@ struct PrintfSpec { enum Flags { AlignLeft = 1 << 0, // corresponds with '-' flag ForceSign = 1 << 1, // corresponds with '+' flag - PadSign = 1 << 2, // corresponds with ' ' flag - PadZero = 1 << 3, // corresponds with '0' flag - ShowType = 1 << 4 // corresponds with '#' flag + PadSign = 1 << 2, // corresponds with ' ' flag + PadZero = 1 << 3, // corresponds with '0' flag + ShowType = 1 << 4 // corresponds with '#' flag }; int width; int precision; int flags; - PrintfSpec(): width(-1), precision(-1), flags(0) {} + PrintfSpec() : + width(-1), + precision(-1), + flags(0) {} }; -static const char* parse_printfspec(PrintfSpec& spec, const char* fmt, const char* end = 0) { - const char* c = fmt; -//at_flags: +static const char *parse_printfspec(PrintfSpec &spec, const char *fmt, const char *end = 0) +{ + const char *c = fmt; + //at_flags: while ((c != end) && *c) { // skip backslash if (*c == '\\') ++c; if (c == end) return c; int addflag = 0; switch (*c) { - // printf flags - case '-': addflag = PrintfSpec::AlignLeft; break; - case '+': addflag = PrintfSpec::ForceSign; break; - case ' ': addflag = PrintfSpec::PadSign; break; - case '0': addflag = PrintfSpec::PadZero; break; - case '#': addflag = PrintfSpec::ShowType; break; + // printf flags + case '-': addflag = PrintfSpec::AlignLeft; break; + case '+': addflag = PrintfSpec::ForceSign; break; + case ' ': addflag = PrintfSpec::PadSign; break; + case '0': addflag = PrintfSpec::PadZero; break; + case '#': addflag = PrintfSpec::ShowType; break; - // valid characters for the width specifier - case '*': - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - goto at_width; + // valid characters for the width specifier + case '*': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + goto at_width; - // valid characters for the precision specifier - case '.': - goto at_precision; + // valid characters for the precision specifier + case '.': + goto at_precision; - // unknown char - default: - return c; + // unknown char + default: + return c; } if (addflag && !(spec.flags & addflag)) { spec.flags |= addflag; @@ -208,7 +233,8 @@ at_precision: return c; } -void init_iosflags(std::ostream& ss, const PrintfSpec& spec) { +void init_iosflags(std::ostream &ss, const PrintfSpec &spec) +{ if (spec.width != -1) ss.width(spec.width); if (spec.precision != -1) @@ -240,11 +266,12 @@ void init_iosflags(std::ostream& ss, const PrintfSpec& spec) { if (spec.precision != -1) { ss << '.' << spec.precision; } */ -std::string to_string(int64_t value, const FormatSpec& fmt) { +std::string to_string(int64_t value, const FormatSpec &fmt) +{ std::ostringstream ss; PrintfSpec spec; - if (! fmt.empty()) { + if (!fmt.empty()) { if (fmt.specifierIs("d") || fmt.specifierIs("i")) { ss.setf(std::ios::dec, std::ios::basefield); } else @@ -270,11 +297,12 @@ std::string to_string(int64_t value, const FormatSpec& fmt) { return ss.str(); } -std::string to_string(uint64_t value, const FormatSpec& fmt) { +std::string to_string(uint64_t value, const FormatSpec &fmt) +{ std::ostringstream ss; PrintfSpec spec; - if (! fmt.empty()) { + if (!fmt.empty()) { if (fmt.specifierIs("u")) { ss.setf(std::ios::dec, std::ios::basefield); } else if (fmt.specifierIs("x")) { @@ -307,11 +335,12 @@ std::string to_string(uint64_t value, const FormatSpec& fmt) { return ss.str(); } -std::string to_string(double value, const FormatSpec& fmt) { +std::string to_string(double value, const FormatSpec &fmt) +{ std::ostringstream ss; PrintfSpec spec; - if (! fmt.empty()) { + if (!fmt.empty()) { if (fmt.specifierIs("f")) { ss.setf(std::ios::fixed, std::ios::floatfield); } else if (fmt.specifierIs("g")) { @@ -341,7 +370,8 @@ std::string to_string(double value, const FormatSpec& fmt) { return ss.str(); } -std::string to_string(const char* value, const FormatSpec& fmt) { +std::string to_string(const char *value, const FormatSpec &fmt) +{ if (fmt.empty()) { return std::string(value); } else { @@ -349,7 +379,8 @@ std::string to_string(const char* value, const FormatSpec& fmt) { } } -std::string to_string(const std::string& value, const FormatSpec& fmt) { +std::string to_string(const std::string &value, const FormatSpec &fmt) +{ if (fmt.empty()) { return value; } else { @@ -365,10 +396,11 @@ std::string to_string(const std::string& value, const FormatSpec& fmt) { // return c; // } -static inline const char* scan_int(const char* fmt, int& value) { +static inline const char *scan_int(const char *fmt, int &value) +{ value = 0; const char *c = fmt; - while (*c>=0 && isdigit(*c)) { + while (*c >= 0 && isdigit(*c)) { value *= 10; value += (*c - '0'); ++c; @@ -376,17 +408,20 @@ static inline const char* scan_int(const char* fmt, int& value) { return c; } -static inline const char* scan_ident(const char* fmt) { +static inline const char *scan_ident(const char *fmt) +{ const char *c = fmt; if (isalpha(*c) || (*c == '_')) { ++c; - while (isalnum(*c) || (*c == '_')) ++c; + while (isalnum(*c) || (*c == '_')) + ++c; } return c; } -static inline const char* scan_bracetext(const char* fmt) { - const char* c = fmt; +static inline const char *scan_bracetext(const char *fmt) +{ + const char *c = fmt; while (*c && (*c != '}')) { if (*c == '\\') { ++c; @@ -397,11 +432,13 @@ static inline const char* scan_bracetext(const char* fmt) { return c; } -std::string string_format(const char* fmt, int numargs, FormatArg const * const args[]) { +std::string string_format(const char *fmt, int numargs, FormatArg const *const args[]) +{ std::string out; const char *c = fmt; while (*c) { - while (*c && *c != '%') ++c; + while (*c && *c != '%') + ++c; if (c != fmt) out.append(fmt, c - fmt); fmt = c; @@ -412,8 +449,8 @@ std::string string_format(const char* fmt, int numargs, FormatArg const * const ++c; } else { int argid = -1; - const char* identBegin = c; - const char* identEnd = c; + const char *identBegin = c; + const char *identEnd = c; // parse and match reference if (isdigit(*c)) { @@ -421,7 +458,8 @@ std::string string_format(const char* fmt, int numargs, FormatArg const * const } else { if (*c == '{') { identBegin = ++c; - while (*c && (*c != '}')) ++c; + while (*c && (*c != '}')) + ++c; identEnd = c; if (*c == '}') ++c; @@ -443,9 +481,7 @@ std::string string_format(const char* fmt, int numargs, FormatArg const * const for (int i = 0; i < numargs; ++i) { size_t identLen = (identEnd - identBegin); - if (args[i]->name - && (strncmp(args[i]->name, identBegin, identLen) == 0) - && (args[i]->name[identLen] == '\0')) { + if (args[i]->name && (strncmp(args[i]->name, identBegin, identLen) == 0) && (args[i]->name[identLen] == '\0')) { argid = i; break; } @@ -453,9 +489,9 @@ std::string string_format(const char* fmt, int numargs, FormatArg const * const } if (argid >= 0 && argid < numargs) { - const FormatArg& arg = *args[argid]; - const char* fmtBegin = 0; - const char* fmtEnd = 0; + const FormatArg &arg = *args[argid]; + const char *fmtBegin = 0; + const char *fmtEnd = 0; // scan format specifier, if provided if (*c == '{') { ++c; @@ -494,7 +530,7 @@ std::string string_format(const char* fmt, int numargs, FormatArg const * const goto bad_reference; } -bad_reference: + bad_reference: fmt = c; } } diff --git a/src/StringF.h b/src/StringF.h index 3caa88c5d..9b77b1d69 100644 --- a/src/StringF.h +++ b/src/StringF.h @@ -5,8 +5,8 @@ #define _STRINGF_H #include "libs.h" -#include #include +#include // provides (for integer types, floating point types, const char* and std::string): // @@ -92,78 +92,83 @@ class FormatSpec { public: FormatSpec(); - FormatSpec(const char* format); - FormatSpec(const char* format, int formatlen); + FormatSpec(const char *format); + FormatSpec(const char *format, int formatlen); bool empty() const; // access to components of the formatspec - bool specifierIs(const char* specifier) const; + bool specifierIs(const char *specifier) const; int paramCount() const; std::string param(int idx) const; - void paramPtr(int idx, const char*& begin, const char*& end) const; + void paramPtr(int idx, const char *&begin, const char *&end) const; private: static const int MAX_PARAMS = 3; void parseFormat(int length); - const char * const format; + const char *const format; // each entry in the params array specifies the index within format[] // of the first byte in the parameter - uint16_t params[MAX_PARAMS+1]; + uint16_t params[MAX_PARAMS + 1]; }; -std::string to_string(int8_t value, const FormatSpec& fmt); -std::string to_string(int16_t value, const FormatSpec& fmt); -std::string to_string(int32_t value, const FormatSpec& fmt); -std::string to_string(int64_t value, const FormatSpec& fmt); -std::string to_string(uint8_t value, const FormatSpec& fmt); -std::string to_string(uint16_t value, const FormatSpec& fmt); -std::string to_string(uint32_t value, const FormatSpec& fmt); -std::string to_string(uint64_t value, const FormatSpec& fmt); -std::string to_string(float value, const FormatSpec& fmt); -std::string to_string(double value, const FormatSpec& fmt); -std::string to_string(fixed value, const FormatSpec& fmt); -std::string to_string(const char* value, const FormatSpec& fmt); -std::string to_string(const std::string& value, const FormatSpec& fmt); +std::string to_string(int8_t value, const FormatSpec &fmt); +std::string to_string(int16_t value, const FormatSpec &fmt); +std::string to_string(int32_t value, const FormatSpec &fmt); +std::string to_string(int64_t value, const FormatSpec &fmt); +std::string to_string(uint8_t value, const FormatSpec &fmt); +std::string to_string(uint16_t value, const FormatSpec &fmt); +std::string to_string(uint32_t value, const FormatSpec &fmt); +std::string to_string(uint64_t value, const FormatSpec &fmt); +std::string to_string(float value, const FormatSpec &fmt); +std::string to_string(double value, const FormatSpec &fmt); +std::string to_string(fixed value, const FormatSpec &fmt); +std::string to_string(const char *value, const FormatSpec &fmt); +std::string to_string(const std::string &value, const FormatSpec &fmt); -inline std::string to_string(int8_t value, const FormatSpec& fmt) { return to_string(int64_t(value), fmt); } -inline std::string to_string(int16_t value, const FormatSpec& fmt) { return to_string(int64_t(value), fmt); } -inline std::string to_string(int32_t value, const FormatSpec& fmt) { return to_string(int64_t(value), fmt); } -inline std::string to_string(uint8_t value, const FormatSpec& fmt) { return to_string(uint64_t(value), fmt); } -inline std::string to_string(uint16_t value, const FormatSpec& fmt) { return to_string(uint64_t(value), fmt); } -inline std::string to_string(uint32_t value, const FormatSpec& fmt) { return to_string(uint64_t(value), fmt); } +inline std::string to_string(int8_t value, const FormatSpec &fmt) { return to_string(int64_t(value), fmt); } +inline std::string to_string(int16_t value, const FormatSpec &fmt) { return to_string(int64_t(value), fmt); } +inline std::string to_string(int32_t value, const FormatSpec &fmt) { return to_string(int64_t(value), fmt); } +inline std::string to_string(uint8_t value, const FormatSpec &fmt) { return to_string(uint64_t(value), fmt); } +inline std::string to_string(uint16_t value, const FormatSpec &fmt) { return to_string(uint64_t(value), fmt); } +inline std::string to_string(uint32_t value, const FormatSpec &fmt) { return to_string(uint64_t(value), fmt); } -inline std::string to_string(float value, const FormatSpec& fmt) { return to_string(double(value), fmt); } +inline std::string to_string(float value, const FormatSpec &fmt) { return to_string(double(value), fmt); } -inline std::string to_string(fixed value, const FormatSpec& fmt) { +inline std::string to_string(fixed value, const FormatSpec &fmt) +{ return to_string(value.ToDouble(), fmt); } template -inline std::string to_string(const T& value) { +inline std::string to_string(const T &value) +{ return to_string(value, FormatSpec()); } class FormatArg { public: - explicit FormatArg(const char* name_ = 0, const char* defaultformat_ = 0): - name(name_), defaultformat(defaultformat_) {} + explicit FormatArg(const char *name_ = 0, const char *defaultformat_ = 0) : + name(name_), + defaultformat(defaultformat_) {} - char const * const name; - char const * const defaultformat; + char const *const name; + char const *const defaultformat; - virtual std::string format(const FormatSpec& spec) const = 0; + virtual std::string format(const FormatSpec &spec) const = 0; }; template class FormatArgT : public FormatArg { public: - FormatArgT(const char* name_, const T& value_, const char* defaultformat_): - FormatArg(name_, defaultformat_), value(value_) {} + FormatArgT(const char *name_, const T &value_, const char *defaultformat_) : + FormatArg(name_, defaultformat_), + value(value_) {} - virtual std::string format(const FormatSpec& spec) const { + virtual std::string format(const FormatSpec &spec) const + { return to_string(value, spec); } @@ -173,30 +178,42 @@ private: // --------------------------------------------------------------------------- -template struct FormatArgWrapper; +template +struct FormatArgWrapper; -template struct FormatArgWrapper { +template +struct FormatArgWrapper { typedef FormatArgT type; - static type wrap(const T& arg, const char* name = 0, const char* defaultformat = 0) - { return FormatArgT(name, arg, defaultformat); } + static type wrap(const T &arg, const char *name = 0, const char *defaultformat = 0) + { + return FormatArgT(name, arg, defaultformat); + } }; -template struct FormatArgWrapper { - typedef FormatArgT type; - static type wrap(const char (&arg)[N], const char* name = 0, const char* defaultformat = 0) - { return FormatArgT(name, arg, defaultformat); } +template +struct FormatArgWrapper { + typedef FormatArgT type; + static type wrap(const char (&arg)[N], const char *name = 0, const char *defaultformat = 0) + { + return FormatArgT(name, arg, defaultformat); + } }; -template <> struct FormatArgWrapper { - typedef FormatArgT type; - static type wrap(const char *arg, const char* name = 0, const char* defaultformat = 0) - { return FormatArgT(name, arg, defaultformat); } +template <> +struct FormatArgWrapper { + typedef FormatArgT type; + static type wrap(const char *arg, const char *name = 0, const char *defaultformat = 0) + { + return FormatArgT(name, arg, defaultformat); + } }; -template <> struct FormatArgWrapper { +template <> +struct FormatArgWrapper { typedef FormatArg type; - static const type& wrap(const FormatArg& arg) { return arg; } + static const type &wrap(const FormatArg &arg) { return arg; } }; -template struct FormatArgWrapper< FormatArgT > { +template +struct FormatArgWrapper> { typedef FormatArgT type; - static const type& wrap(const FormatArgT& arg) { return arg; } + static const type &wrap(const FormatArgT &arg) { return arg; } }; // --------------------------------------------------------------------------- @@ -211,89 +228,98 @@ FormatArgT formatarg(const char* name, const char* value) { template inline typename FormatArgWrapper::type -formatarg(const char* name, const T& value, const char* defaultformat = 0) { +formatarg(const char *name, const T &value, const char *defaultformat = 0) +{ return FormatArgWrapper::wrap(value, name, defaultformat); } // underlying formatting function -std::string string_format(const char* fmt, int numargs, FormatArg const * const args[]); +std::string string_format(const char *fmt, int numargs, FormatArg const *const args[]); // --------------------------------------------------------------------------- // ---- stringf(format, args...) for 0 to 7 arguments ---- -inline std::string stringf(const char* fmt) { +inline std::string stringf(const char *fmt) +{ return string_format(fmt, 0, 0); } template -inline std::string stringf(const char* fmt, const T0& p0) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - FormatArg const * const args[] = { &arg0 }; +inline std::string stringf(const char *fmt, const T0 &p0) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + FormatArg const *const args[] = { &arg0 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - FormatArg const * const args[] = { &arg0, &arg1 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + FormatArg const *const args[] = { &arg0, &arg1 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1, const T2& p2) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - const typename FormatArgWrapper::type& arg2 = FormatArgWrapper::wrap(p2); - FormatArg const * const args[] = { &arg0, &arg1, &arg2 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1, const T2 &p2) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + const typename FormatArgWrapper::type &arg2 = FormatArgWrapper::wrap(p2); + FormatArg const *const args[] = { &arg0, &arg1, &arg2 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1, const T2& p2, const T3& p3) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - const typename FormatArgWrapper::type& arg2 = FormatArgWrapper::wrap(p2); - const typename FormatArgWrapper::type& arg3 = FormatArgWrapper::wrap(p3); - FormatArg const * const args[] = { &arg0, &arg1, &arg2, &arg3 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1, const T2 &p2, const T3 &p3) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + const typename FormatArgWrapper::type &arg2 = FormatArgWrapper::wrap(p2); + const typename FormatArgWrapper::type &arg3 = FormatArgWrapper::wrap(p3); + FormatArg const *const args[] = { &arg0, &arg1, &arg2, &arg3 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - const typename FormatArgWrapper::type& arg2 = FormatArgWrapper::wrap(p2); - const typename FormatArgWrapper::type& arg3 = FormatArgWrapper::wrap(p3); - const typename FormatArgWrapper::type& arg4 = FormatArgWrapper::wrap(p4); - FormatArg const * const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1, const T2 &p2, const T3 &p3, const T4 &p4) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + const typename FormatArgWrapper::type &arg2 = FormatArgWrapper::wrap(p2); + const typename FormatArgWrapper::type &arg3 = FormatArgWrapper::wrap(p3); + const typename FormatArgWrapper::type &arg4 = FormatArgWrapper::wrap(p4); + FormatArg const *const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - const typename FormatArgWrapper::type& arg2 = FormatArgWrapper::wrap(p2); - const typename FormatArgWrapper::type& arg3 = FormatArgWrapper::wrap(p3); - const typename FormatArgWrapper::type& arg4 = FormatArgWrapper::wrap(p4); - const typename FormatArgWrapper::type& arg5 = FormatArgWrapper::wrap(p5); - FormatArg const * const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1, const T2 &p2, const T3 &p3, const T4 &p4, const T5 &p5) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + const typename FormatArgWrapper::type &arg2 = FormatArgWrapper::wrap(p2); + const typename FormatArgWrapper::type &arg3 = FormatArgWrapper::wrap(p3); + const typename FormatArgWrapper::type &arg4 = FormatArgWrapper::wrap(p4); + const typename FormatArgWrapper::type &arg5 = FormatArgWrapper::wrap(p5); + FormatArg const *const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5 }; return string_format(fmt, COUNTOF(args), args); } template -inline std::string stringf(const char* fmt, const T0& p0, const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6) { - const typename FormatArgWrapper::type& arg0 = FormatArgWrapper::wrap(p0); - const typename FormatArgWrapper::type& arg1 = FormatArgWrapper::wrap(p1); - const typename FormatArgWrapper::type& arg2 = FormatArgWrapper::wrap(p2); - const typename FormatArgWrapper::type& arg3 = FormatArgWrapper::wrap(p3); - const typename FormatArgWrapper::type& arg4 = FormatArgWrapper::wrap(p4); - const typename FormatArgWrapper::type& arg5 = FormatArgWrapper::wrap(p5); - const typename FormatArgWrapper::type& arg6 = FormatArgWrapper::wrap(p6); - FormatArg const * const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 }; +inline std::string stringf(const char *fmt, const T0 &p0, const T1 &p1, const T2 &p2, const T3 &p3, const T4 &p4, const T5 &p5, const T6 &p6) +{ + const typename FormatArgWrapper::type &arg0 = FormatArgWrapper::wrap(p0); + const typename FormatArgWrapper::type &arg1 = FormatArgWrapper::wrap(p1); + const typename FormatArgWrapper::type &arg2 = FormatArgWrapper::wrap(p2); + const typename FormatArgWrapper::type &arg3 = FormatArgWrapper::wrap(p3); + const typename FormatArgWrapper::type &arg4 = FormatArgWrapper::wrap(p4); + const typename FormatArgWrapper::type &arg5 = FormatArgWrapper::wrap(p5); + const typename FormatArgWrapper::type &arg6 = FormatArgWrapper::wrap(p6); + FormatArg const *const args[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 }; return string_format(fmt, COUNTOF(args), args); } diff --git a/src/StringRange.h b/src/StringRange.h index 50c9d94b0..f07f6cbfb 100644 --- a/src/StringRange.h +++ b/src/StringRange.h @@ -4,21 +4,24 @@ #ifndef _STRINGRANGE_H #define _STRINGRANGE_H -#include #include #include +#include -struct StringRange -{ - StringRange(): begin(0), end(0) {} - StringRange(const char *begin_, const char *end_) - : begin(begin_), end(end_) +struct StringRange { + StringRange() : + begin(0), + end(0) {} + StringRange(const char *begin_, const char *end_) : + begin(begin_), + end(end_) { assert(begin_ && end_); assert((end_ - begin_) >= 0); } - StringRange(const char *begin_, size_t size) - : begin(begin_), end(begin_ + size) + StringRange(const char *begin_, size_t size) : + begin(begin_), + end(begin_ + size) { assert(begin_); } @@ -39,15 +42,15 @@ struct StringRange friend bool operator!=(const StringRange &a, const char *b) { return (a.Compare(b) != 0); } friend bool operator<=(const StringRange &a, const char *b) { return (a.Compare(b) <= 0); } friend bool operator>=(const StringRange &a, const char *b) { return (a.Compare(b) >= 0); } - friend bool operator< (const StringRange &a, const char *b) { return (a.Compare(b) < 0); } - friend bool operator> (const StringRange &a, const char *b) { return (a.Compare(b) > 0); } + friend bool operator<(const StringRange &a, const char *b) { return (a.Compare(b) < 0); } + friend bool operator>(const StringRange &a, const char *b) { return (a.Compare(b) > 0); } friend bool operator==(const char *a, const StringRange &b) { return (b.Compare(a) == 0); } friend bool operator!=(const char *a, const StringRange &b) { return (b.Compare(a) != 0); } friend bool operator<=(const char *a, const StringRange &b) { return (b.Compare(a) >= 0); } friend bool operator>=(const char *a, const StringRange &b) { return (b.Compare(a) <= 0); } - friend bool operator< (const char *a, const StringRange &b) { return (b.Compare(a) > 0); } - friend bool operator> (const char *a, const StringRange &b) { return (b.Compare(a) < 0); } + friend bool operator<(const char *a, const StringRange &b) { return (b.Compare(a) > 0); } + friend bool operator>(const char *a, const StringRange &b) { return (b.Compare(a) < 0); } const char *FindChar(char c) const; const char *RFindChar(char c) const; @@ -66,8 +69,10 @@ struct StringRange StringRange StripSpace() const; StringRange ReadLine(); + private: - static bool is_space(char c) { + static bool is_space(char c) + { // MSVC's isspace() apparently asserts if you give it non-ASCII chars // (maybe changing locale would help) return (c == ' ') || (c == '\t') || (c == '\v') || (c == '\r') || (c == '\n'); @@ -84,45 +89,59 @@ inline StringRange StringRange::ReadLine() inline int StringRange::Compare(const char *b) const { const char *a = begin; - while (a != end && *b && *a == *b) { ++a; ++b; } - if (a != end && *b) { return (*a < *b ? -1 : 1); } - if (a != end) { return 1; } - if (*b) { return -1; } + while (a != end && *b && *a == *b) { + ++a; + ++b; + } + if (a != end && *b) { + return (*a < *b ? -1 : 1); + } + if (a != end) { + return 1; + } + if (*b) { + return -1; + } return 0; } inline const char *StringRange::FindChar(char c) const { const char *x = begin, *y = end; - while ((x != y) && (*x != c)) ++x; + while ((x != y) && (*x != c)) + ++x; return x; } inline const char *StringRange::RFindChar(char c) const { const char *x = begin, *y = end; - while ((x != y) && (*--y != c)) {} + while ((x != y) && (*--y != c)) { + } return y; } inline const char *StringRange::FindSpace() const { const char *x = begin, *y = end; - while ((x != y) && !isspace(*x)) ++x; + while ((x != y) && !isspace(*x)) + ++x; return x; } inline const char *StringRange::RFindSpace() const { const char *x = begin, *y = end; - while ((x != y) && !isspace(*--y)) {} + while ((x != y) && !isspace(*--y)) { + } return y; } inline const char *StringRange::FindNewline() const { const char *x = begin, *y = end; - while ((x != y) && (*x != '\r') && (*x != '\n')) ++x; + while ((x != y) && (*x != '\r') && (*x != '\n')) + ++x; return x; } @@ -137,21 +156,23 @@ inline const char *StringRange::FindNextLine() const inline const char *StringRange::FindNonSpace() const { const char *x = begin, *y = end; - while ((x != y) && is_space(*x)) ++x; + while ((x != y) && is_space(*x)) + ++x; return x; } inline const char *StringRange::RFindNonSpace() const { const char *x = begin, *y = end; - while ((x != y) && is_space(*--y)) {} + while ((x != y) && is_space(*--y)) { + } return (y == end ? y : y + 1); } inline StringRange StringRange::StripUTF8BOM() const { if (Size() >= 3 && begin[0] == '\xEF' && begin[1] == '\xBB' && begin[2] == '\xBF') - return StringRange(begin+3, end); + return StringRange(begin + 3, end); else return *this; } diff --git a/src/SystemInfoView.cpp b/src/SystemInfoView.cpp index 5644bcae7..9f4662e5c 100644 --- a/src/SystemInfoView.cpp +++ b/src/SystemInfoView.cpp @@ -1,25 +1,27 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Pi.h" -#include "galaxy/Galaxy.h" -#include "galaxy/Sector.h" -#include "SectorView.h" #include "SystemInfoView.h" -#include "ShipCpanel.h" +#include "Factions.h" +#include "Game.h" +#include "Lang.h" +#include "Pi.h" #include "Player.h" #include "Polit.h" +#include "SectorView.h" +#include "ShipCpanel.h" #include "Space.h" -#include "galaxy/SystemPath.h" -#include "Lang.h" #include "StringF.h" -#include "Game.h" -#include "graphics/Renderer.h" +#include "galaxy/Galaxy.h" +#include "galaxy/Sector.h" +#include "galaxy/SystemPath.h" #include "graphics/Drawables.h" -#include "Factions.h" +#include "graphics/Renderer.h" #include -SystemInfoView::SystemInfoView(Game* game) : UIView(), m_game(game) +SystemInfoView::SystemInfoView(Game *game) : + UIView(), + m_game(game) { SetTransparency(true); m_refresh = REFRESH_NONE; @@ -46,8 +48,8 @@ void SystemInfoView::OnBodySelected(SystemBody *b) } } else { if (isCurrentSystem) { - Body* body = m_game->GetSpace()->FindBodyForPath(&path); - if(body != 0) + Body *body = m_game->GetSpace()->FindBodyForPath(&path); + if (body != 0) Pi::player->SetNavTarget(body); } else if (b->GetSuperType() == SystemBody::SUPERTYPE_STAR) { // We allow hyperjump to any star of the system m_game->GetSectorView()->SetSelected(path); @@ -70,29 +72,27 @@ void SystemInfoView::OnBodyViewed(SystemBody *b) outer->Add(col1, 0, 0); outer->Add(col2, 300, 0); -#define _add_label_and_value(label, value) { \ - Gui::Label *l = (new Gui::Label(label))->Color(255,255,0); \ - col1->PackEnd(l); \ - l = (new Gui::Label(value))->Color(255,255,0); \ - col2->PackEnd(l); \ -} +#define _add_label_and_value(label, value) \ + { \ + Gui::Label *l = (new Gui::Label(label))->Color(255, 255, 0); \ + col1->PackEnd(l); \ + l = (new Gui::Label(value))->Color(255, 255, 0); \ + col2->PackEnd(l); \ + } bool multiple = (b->GetSuperType() == SystemBody::SUPERTYPE_STAR && - b->GetParent() && b->GetParent()->GetType() == SystemBody::TYPE_GRAVPOINT && b->GetParent()->GetParent()); + b->GetParent() && b->GetParent()->GetType() == SystemBody::TYPE_GRAVPOINT && b->GetParent()->GetParent()); { Gui::Label *l = new Gui::Label(b->GetName() + ": " + b->GetAstroDescription() + - (multiple ? (std::string(" (")+b->GetParent()->GetName() + ")") : "")); - l->Color(255,255,0); + (multiple ? (std::string(" (") + b->GetParent()->GetName() + ")") : "")); + l->Color(255, 255, 0); m_infoBox->PackStart(l); } if (b->GetType() != SystemBody::TYPE_STARPORT_ORBITAL) { - _add_label_and_value(Lang::MASS, stringf(Lang::N_WHATEVER_MASSES, formatarg("mass", b->GetMassAsFixed().ToDouble()), - formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH)))); + _add_label_and_value(Lang::MASS, stringf(Lang::N_WHATEVER_MASSES, formatarg("mass", b->GetMassAsFixed().ToDouble()), formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH)))); - _add_label_and_value(Lang::RADIUS, stringf(Lang::N_WHATEVER_RADII, formatarg("radius", b->GetRadiusAsFixed().ToDouble()), - formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH)), - formatarg("radkm", b->GetRadius() / 1000.0))); + _add_label_and_value(Lang::RADIUS, stringf(Lang::N_WHATEVER_RADII, formatarg("radius", b->GetRadiusAsFixed().ToDouble()), formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH)), formatarg("radkm", b->GetRadius() / 1000.0))); } if (b->GetSuperType() == SystemBody::SUPERTYPE_STAR) { @@ -100,42 +100,38 @@ void SystemInfoView::OnBodyViewed(SystemBody *b) } if (b->GetType() != SystemBody::TYPE_STARPORT_ORBITAL) { - _add_label_and_value(Lang::SURFACE_TEMPERATURE, stringf(Lang::N_CELSIUS, formatarg("temperature", b->GetAverageTemp()-273))); + _add_label_and_value(Lang::SURFACE_TEMPERATURE, stringf(Lang::N_CELSIUS, formatarg("temperature", b->GetAverageTemp() - 273))); static const auto earthG = G * EARTH_MASS / (EARTH_RADIUS * EARTH_RADIUS); const auto surfAccel = b->CalcSurfaceGravity(); _add_label_and_value(Lang::SURFACE_GRAVITY, stringf("%0{f.3} m/s^2 (%1{f.3} g)", surfAccel, surfAccel / earthG)); } if (b->GetParent()) { - float days = float(b->GetOrbit().Period()) / float(60*60*24); + float days = float(b->GetOrbit().Period()) / float(60 * 60 * 24); if (days > 1000) { - data = stringf(Lang::N_YEARS, formatarg("years", days/365)); + data = stringf(Lang::N_YEARS, formatarg("years", days / 365)); } else { - data = stringf(Lang::N_DAYS, formatarg("days", b->GetOrbit().Period() / (60*60*24))); + data = stringf(Lang::N_DAYS, formatarg("days", b->GetOrbit().Period() / (60 * 60 * 24))); } if (multiple) { - float pdays = float(b->GetParent()->GetOrbit().Period()) /float(60*60*24); - data += " (" + (pdays > 1000 ? stringf(Lang::N_YEARS, formatarg("years", pdays/365)) - : stringf(Lang::N_DAYS, formatarg("days", b->GetParent()->GetOrbit().Period() / (60*60*24)))) + ")"; + float pdays = float(b->GetParent()->GetOrbit().Period()) / float(60 * 60 * 24); + data += " (" + (pdays > 1000 ? stringf(Lang::N_YEARS, formatarg("years", pdays / 365)) : stringf(Lang::N_DAYS, formatarg("days", b->GetParent()->GetOrbit().Period() / (60 * 60 * 24)))) + ")"; } _add_label_and_value(Lang::ORBITAL_PERIOD, data); - _add_label_and_value(Lang::PERIAPSIS_DISTANCE, format_distance(b->GetOrbMin()*AU, 3) + - (multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMin()*AU, 3)+ ")") : "")); - _add_label_and_value(Lang::APOAPSIS_DISTANCE, format_distance(b->GetOrbMax()*AU, 3) + - (multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMax()*AU, 3)+ ")") : "")); - _add_label_and_value(Lang::ECCENTRICITY, stringf("%0{f.2}", b->GetOrbit().GetEccentricity()) + - (multiple ? (std::string(" (") + stringf("%0{f.2}", b->GetParent()->GetOrbit().GetEccentricity()) + ")") : "")); + _add_label_and_value(Lang::PERIAPSIS_DISTANCE, format_distance(b->GetOrbMin() * AU, 3) + (multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMin() * AU, 3) + ")") : "")); + _add_label_and_value(Lang::APOAPSIS_DISTANCE, format_distance(b->GetOrbMax() * AU, 3) + (multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMax() * AU, 3) + ")") : "")); + _add_label_and_value(Lang::ECCENTRICITY, stringf("%0{f.2}", b->GetOrbit().GetEccentricity()) + (multiple ? (std::string(" (") + stringf("%0{f.2}", b->GetParent()->GetOrbit().GetEccentricity()) + ")") : "")); if (b->GetType() != SystemBody::TYPE_STARPORT_ORBITAL) { - _add_label_and_value(Lang::AXIAL_TILT, stringf(Lang::N_DEGREES, formatarg("angle", b->GetAxialTilt() * (180.0/M_PI)))); + _add_label_and_value(Lang::AXIAL_TILT, stringf(Lang::N_DEGREES, formatarg("angle", b->GetAxialTilt() * (180.0 / M_PI)))); if (b->IsRotating()) { _add_label_and_value( - std::string(Lang::DAY_LENGTH)+std::string(Lang::ROTATIONAL_PERIOD), + std::string(Lang::DAY_LENGTH) + std::string(Lang::ROTATIONAL_PERIOD), stringf(Lang::N_EARTH_DAYS, formatarg("days", b->GetRotationPeriodInDays()))); } } int numSurfaceStarports = 0; std::string nameList; - for (const SystemBody* kid : b->GetChildren()) { + for (const SystemBody *kid : b->GetChildren()) { if (kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { nameList += (numSurfaceStarports ? ", " : "") + kid->GetName(); numSurfaceStarports++; @@ -153,7 +149,7 @@ void SystemInfoView::OnBodyViewed(SystemBody *b) void SystemInfoView::UpdateEconomyTab() { /* Economy info page */ - StarSystem *s = m_system.Get(); // selected system + StarSystem *s = m_system.Get(); // selected system /* imports and exports */ const RefCountedPtr hs = m_game->GetSpace()->GetStarSystem(); @@ -163,31 +159,31 @@ void SystemInfoView::UpdateEconomyTab() Pi::player->Properties().Get("trade_computer_cap", trade_computer); // we might be here because we changed equipment, update that as well: - m_hasTradeComputer = bool (trade_computer); + m_hasTradeComputer = bool(trade_computer); // If current system is defined and not equal to selected we will compare them const bool compareSelectedWithCurrent = (hs && !m_system->GetPath().IsSameSystem(hs->GetPath()) && trade_computer > 0); - const std::string meh = "#999"; - const std::string ok = "#fff"; - const std::string good = "#7c7"; - const std::string awesome = "#7f7"; - const std::string illegal = "#744"; + const std::string meh = "#999"; + const std::string ok = "#fff"; + const std::string good = "#7c7"; + const std::string awesome = "#7f7"; + const std::string illegal = "#744"; - if (compareSelectedWithCurrent){ + if (compareSelectedWithCurrent) { // different system selected const std::string COMM_COMP = stringf(Lang::COMMODITY_TRADE_ANALYSIS_COMPARE, - formatarg("selected_system", m_system->GetName().c_str()), - formatarg("current_system", hs->GetName().c_str())); + formatarg("selected_system", m_system->GetName().c_str()), + formatarg("current_system", hs->GetName().c_str())); m_commodityTradeLabel->SetText(COMM_COMP.c_str()); } else { // same system as current selected const std::string COMM_SELF = stringf(Lang::COMMODITY_TRADE_ANALYSIS_SELF, - formatarg("system", m_system->GetName().c_str())); + formatarg("system", m_system->GetName().c_str())); m_commodityTradeLabel->SetText(COMM_SELF.c_str()); } @@ -195,23 +191,22 @@ void SystemInfoView::UpdateEconomyTab() const int rowsep = 18; // lambda function to build each colum for MAJOR/MINOR IMPORT/EXPORT - auto f = [&](std::function isInList, - std::function isInInterval, std::string colorInInterval, std::string toolTipInInterval, - std::function isOther, std::string colorOther, std::string toolTipOther, - Gui::Fixed *m_econMType, std::string tradeType){ + auto f = [&](std::function isInList, + std::function isInInterval, std::string colorInInterval, std::string toolTipInInterval, + std::function isOther, std::string colorOther, std::string toolTipOther, + Gui::Fixed *m_econMType, std::string tradeType) { int num = 0; m_econMType->DeleteAllChildren(); - m_econMType->Add(new Gui::Label(std::string("#ff0")+tradeType), + m_econMType->Add(new Gui::Label(std::string("#ff0") + tradeType), 0, num++ * rowsep); - for (int i=1; i< GalacticEconomy::COMMODITY_COUNT; i++){ - if (isInList(s->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i))) - && s->IsCommodityLegal(GalacticEconomy::Commodity(i))) { - std::string extra = meh; // default color - std::string tooltip = ""; // no tooltip for default + for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { + if (isInList(s->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i))) && s->IsCommodityLegal(GalacticEconomy::Commodity(i))) { + std::string extra = meh; // default color + std::string tooltip = ""; // no tooltip for default if (compareSelectedWithCurrent) { if (isInInterval(hs->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i)))) { - extra = colorInInterval; // change color + extra = colorInInterval; // change color tooltip = toolTipInInterval; // describe trade status in current system } else if (isOther(hs->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i)))) { extra = colorOther; @@ -222,7 +217,7 @@ void SystemInfoView::UpdateEconomyTab() tooltip = std::string(Lang::ILLEGAL_CURRENT_SYSTEM); } } - Gui::Label *label = new Gui::Label(extra+GalacticEconomy::COMMODITY_DATA[i].name); + Gui::Label *label = new Gui::Label(extra + GalacticEconomy::COMMODITY_DATA[i].name); label->SetToolTip(tooltip); m_econMType->Add(label, 5, num++ * rowsep); } @@ -234,33 +229,33 @@ void SystemInfoView::UpdateEconomyTab() }; // sm = selected system price modifier, csp = current system price modifier - f([](int sm) {return sm > 10;}, - [](int cm) {return -10 <= cm && cm < -2;}, good, Lang::MINOR_EXPORT_CURRENT_SYSTEM, - [](int cm) {return cm < -10;}, awesome, Lang::MAJOR_EXPORT_CURRENT_SYSTEM, - m_econMajImport, Lang::MAJOR_IMPORTS); + f([](int sm) { return sm > 10; }, + [](int cm) { return -10 <= cm && cm < -2; }, good, Lang::MINOR_EXPORT_CURRENT_SYSTEM, + [](int cm) { return cm < -10; }, awesome, Lang::MAJOR_EXPORT_CURRENT_SYSTEM, + m_econMajImport, Lang::MAJOR_IMPORTS); - f([](int sm) {return 2 < sm && sm <= 10;}, - [](int cm) {return -10 <= cm && cm < -2;}, ok, Lang::MINOR_EXPORT_CURRENT_SYSTEM, - [](int cm) {return cm < -10;}, good, Lang::MAJOR_EXPORT_CURRENT_SYSTEM, - m_econMinImport, Lang::MINOR_IMPORTS); + f([](int sm) { return 2 < sm && sm <= 10; }, + [](int cm) { return -10 <= cm && cm < -2; }, ok, Lang::MINOR_EXPORT_CURRENT_SYSTEM, + [](int cm) { return cm < -10; }, good, Lang::MAJOR_EXPORT_CURRENT_SYSTEM, + m_econMinImport, Lang::MINOR_IMPORTS); - f([](int sm) {return sm < -10;}, - [](int cm) {return 2 < cm && cm <= 10;}, good, Lang::MINOR_IMPORT_CURRENT_SYSTEM, - [](int cm) {return 10 < cm;}, awesome, Lang::MAJOR_IMPORT_CURRENT_SYSTEM, - m_econMajExport, Lang::MAJOR_EXPORTS); + f([](int sm) { return sm < -10; }, + [](int cm) { return 2 < cm && cm <= 10; }, good, Lang::MINOR_IMPORT_CURRENT_SYSTEM, + [](int cm) { return 10 < cm; }, awesome, Lang::MAJOR_IMPORT_CURRENT_SYSTEM, + m_econMajExport, Lang::MAJOR_EXPORTS); - f([](int sm) {return -10 <= sm && sm < -2;}, - [](int cm) {return 2 < cm && cm <= 10;}, ok, Lang::MINOR_IMPORT_CURRENT_SYSTEM, - [](int cm) {return 10 < cm;}, good, Lang::MAJOR_IMPORT_CURRENT_SYSTEM, - m_econMinExport, Lang::MINOR_EXPORTS); + f([](int sm) { return -10 <= sm && sm < -2; }, + [](int cm) { return 2 < cm && cm <= 10; }, ok, Lang::MINOR_IMPORT_CURRENT_SYSTEM, + [](int cm) { return 10 < cm; }, good, Lang::MAJOR_IMPORT_CURRENT_SYSTEM, + m_econMinExport, Lang::MINOR_EXPORTS); // ILLEGAL GOODS int num = 0; m_econIllegal->DeleteAllChildren(); m_econIllegal->Add(new Gui::Label( - std::string("#f55")+std::string(Lang::ILLEGAL_GOODS)), + std::string("#f55") + std::string(Lang::ILLEGAL_GOODS)), 0, num++ * rowsep); - for (int i=1; iIsCommodityLegal(GalacticEconomy::Commodity(i))) { std::string extra = illegal; std::string tooltip = ""; @@ -269,7 +264,7 @@ void SystemInfoView::UpdateEconomyTab() extra = meh; tooltip = std::string(Lang::LEGAL_CURRENT_SYSTEM); } - Gui::Label *label = new Gui::Label(extra+GalacticEconomy::COMMODITY_DATA[i].name); + Gui::Label *label = new Gui::Label(extra + GalacticEconomy::COMMODITY_DATA[i].name); label->SetToolTip(tooltip); m_econIllegal->Add(label, 5, num++ * rowsep); } @@ -297,21 +292,21 @@ void SystemInfoView::PutBodies(SystemBody *body, Gui::Fixed *container, int dir, if (body->GetType() != SystemBody::TYPE_GRAVPOINT) { BodyIcon *ib = new BodyIcon(body->GetIcon(), m_renderer); if (body->GetSuperType() == SystemBody::SUPERTYPE_ROCKY_PLANET) { - for (const SystemBody* kid : body->GetChildren()) { + for (const SystemBody *kid : body->GetChildren()) { if (kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { ib->SetHasStarport(); break; } } } - m_bodyIcons.push_back(std::pair(body->GetPath().bodyIndex, ib)); + m_bodyIcons.push_back(std::pair(body->GetPath().bodyIndex, ib)); ib->GetSize(size); if (prevSize < 0) prevSize = size[!dir]; ib->onSelect.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), body)); ib->onMouseEnter.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodyViewed), body)); ib->onMouseLeave.connect(sigc::mem_fun(this, &SystemInfoView::OnSwitchTo)); - myPos[0] += (dir ? prevSize*0.5 - size[0]*0.5 : 0); - myPos[1] += (!dir ? prevSize*0.5 - size[1]*0.5 : 0); + myPos[0] += (dir ? prevSize * 0.5 - size[0] * 0.5 : 0); + myPos[1] += (!dir ? prevSize * 0.5 - size[1] * 0.5 : 0); container->Add(ib, myPos[0], myPos[1]); if (body->GetSuperType() != SystemBody::SUPERTYPE_STARPORT) majorBodies++; @@ -325,7 +320,7 @@ void SystemInfoView::PutBodies(SystemBody *body, Gui::Fixed *container, int dir, } float prevSizeForKids = size[!dir]; - for (SystemBody* kid : body->GetChildren()) { + for (SystemBody *kid : body->GetChildren()) { PutBodies(kid, container, dir, myPos, majorBodies, starports, onSurface, prevSizeForKids); } } @@ -350,7 +345,7 @@ void SystemInfoView::SystemChanged(const SystemPath &path) m_system = m_game->GetGalaxy()->GetStarSystem(path); m_unexplored = m_system->GetUnexplored(); - m_sbodyInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight()-100)); + m_sbodyInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight() - 100)); if (m_system->GetUnexplored()) { Add(m_sbodyInfoTab, 0, 0); @@ -358,7 +353,7 @@ void SystemInfoView::SystemChanged(const SystemPath &path) std::string _info = Lang::UNEXPLORED_SYSTEM_STAR_INFO_ONLY; - Gui::Label *l = (new Gui::Label(_info))->Color(255,255,0); + Gui::Label *l = (new Gui::Label(_info))->Color(255, 255, 0); m_sbodyInfoTab->Add(l, 35, 300); m_selectedBodyPath = SystemPath(); @@ -366,7 +361,7 @@ void SystemInfoView::SystemChanged(const SystemPath &path) return; } - m_econInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight()-100)); + m_econInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight() - 100)); Gui::Fixed *demographicsTab = new Gui::Fixed(); m_tabs = new Gui::Tabbed(); @@ -418,7 +413,7 @@ void SystemInfoView::SystemChanged(const SystemPath &path) Gui::VScrollPortal *portal = new Gui::VScrollPortal(730); scroll->SetAdjustment(&portal->vscrollAdjust); - Gui::Label *l = (new Gui::Label(_info))->Color(255,255,0); + Gui::Label *l = (new Gui::Label(_info))->Color(255, 255, 0); m_infoBox->PackStart(l); portal->Add(m_infoBox); scrollBox->PackStart(scroll); @@ -470,31 +465,36 @@ void SystemInfoView::SystemChanged(const SystemPath &path) const float YSEP = Gui::Screen::GetFontHeight() * 1.2f; - col1->Add((new Gui::Label(Lang::SYSTEM_TYPE))->Color(255,255,0), 0, 0); + col1->Add((new Gui::Label(Lang::SYSTEM_TYPE))->Color(255, 255, 0), 0, 0); col2->Add(new Gui::Label(m_system->GetShortDescription()), 0, 0); - col1->Add((new Gui::Label(Lang::GOVERNMENT_TYPE))->Color(255,255,0), 0, 2*YSEP); - col2->Add(new Gui::Label(m_system->GetSysPolit().GetGovernmentDesc()), 0, 2*YSEP); + col1->Add((new Gui::Label(Lang::GOVERNMENT_TYPE))->Color(255, 255, 0), 0, 2 * YSEP); + col2->Add(new Gui::Label(m_system->GetSysPolit().GetGovernmentDesc()), 0, 2 * YSEP); - col1->Add((new Gui::Label(Lang::ECONOMY_TYPE))->Color(255,255,0), 0, 3*YSEP); - col2->Add(new Gui::Label(m_system->GetSysPolit().GetEconomicDesc()), 0, 3*YSEP); + col1->Add((new Gui::Label(Lang::ECONOMY_TYPE))->Color(255, 255, 0), 0, 3 * YSEP); + col2->Add(new Gui::Label(m_system->GetSysPolit().GetEconomicDesc()), 0, 3 * YSEP); - col1->Add((new Gui::Label(Lang::ALLEGIANCE))->Color(255,255,0), 0, 4*YSEP); - col2->Add(new Gui::Label(m_system->GetFaction()->name.c_str()), 0, 4*YSEP); - col1->Add((new Gui::Label(Lang::POPULATION))->Color(255,255,0), 0, 5*YSEP); + col1->Add((new Gui::Label(Lang::ALLEGIANCE))->Color(255, 255, 0), 0, 4 * YSEP); + col2->Add(new Gui::Label(m_system->GetFaction()->name.c_str()), 0, 4 * YSEP); + col1->Add((new Gui::Label(Lang::POPULATION))->Color(255, 255, 0), 0, 5 * YSEP); std::string popmsg; fixed pop = m_system->GetTotalPop(); - if (pop >= fixed(1,1)) { popmsg = stringf(Lang::OVER_N_BILLION, formatarg("population", pop.ToInt32())); } - else if (pop >= fixed(1,1000)) { popmsg = stringf(Lang::OVER_N_MILLION, formatarg("population", (pop*1000).ToInt32())); } - else if (pop != fixed(0)) { popmsg = Lang::A_FEW_THOUSAND; } - else { popmsg = Lang::NO_REGISTERED_INHABITANTS; } - col2->Add(new Gui::Label(popmsg), 0, 5*YSEP); + if (pop >= fixed(1, 1)) { + popmsg = stringf(Lang::OVER_N_BILLION, formatarg("population", pop.ToInt32())); + } else if (pop >= fixed(1, 1000)) { + popmsg = stringf(Lang::OVER_N_MILLION, formatarg("population", (pop * 1000).ToInt32())); + } else if (pop != fixed(0)) { + popmsg = Lang::A_FEW_THOUSAND; + } else { + popmsg = Lang::NO_REGISTERED_INHABITANTS; + } + col2->Add(new Gui::Label(popmsg), 0, 5 * YSEP); - col1->Add((new Gui::Label(Lang::SECTOR_COORDINATES))->Color(255,255,0), 0, 6*YSEP); - col2->Add(new Gui::Label(stringf("%0{d}, %1{d}, %2{d}", path.sectorX, path.sectorY, path.sectorZ)), 0, 6*YSEP); + col1->Add((new Gui::Label(Lang::SECTOR_COORDINATES))->Color(255, 255, 0), 0, 6 * YSEP); + col2->Add(new Gui::Label(stringf("%0{d}, %1{d}, %2{d}", path.sectorX, path.sectorY, path.sectorZ)), 0, 6 * YSEP); - col1->Add((new Gui::Label(Lang::SYSTEM_NUMBER))->Color(255,255,0), 0, 7*YSEP); - col2->Add(new Gui::Label(stringf("%0", path.systemIndex)), 0, 7*YSEP); + col1->Add((new Gui::Label(Lang::SYSTEM_NUMBER))->Color(255, 255, 0), 0, 7 * YSEP); + col2->Add(new Gui::Label(stringf("%0", path.systemIndex)), 0, 7 * YSEP); } UpdateIconSelections(); @@ -510,9 +510,9 @@ void SystemInfoView::Draw3D() UIView::Draw3D(); } -static bool IsShownInInfoView(const SystemBody* sb) +static bool IsShownInInfoView(const SystemBody *sb) { - if(!sb) return false; // sanity check + if (!sb) return false; // sanity check SystemBody::BodySuperType superType = sb->GetSuperType(); return superType == SystemBody::SUPERTYPE_STAR || superType == SystemBody::SUPERTYPE_GAS_GIANT || superType == SystemBody::SUPERTYPE_ROCKY_PLANET || @@ -530,7 +530,7 @@ SystemInfoView::RefreshType SystemInfoView::NeedsRefresh() // If we changed equipment since last refresh int trade_computer = 0; Pi::player->Properties().Get("trade_computer_cap", trade_computer); - if (m_hasTradeComputer != (trade_computer!=0)) + if (m_hasTradeComputer != (trade_computer != 0)) return REFRESH_ALL; if (m_system->GetUnexplored()) @@ -547,11 +547,11 @@ SystemInfoView::RefreshType SystemInfoView::NeedsRefresh() // No body was selected if (m_game->GetSectorView()->GetSelected().IsBodyPath()) return REFRESH_SELECTED_BODY; // but now we want one, this can only be a star, - // so no check for IsShownInInfoView() needed + // so no check for IsShownInInfoView() needed } } else { Body *navTarget = Pi::player->GetNavTarget(); - if (navTarget && (navTarget->GetSystemBody()!=nullptr) && IsShownInInfoView(navTarget->GetSystemBody())) { + if (navTarget && (navTarget->GetSystemBody() != nullptr) && IsShownInInfoView(navTarget->GetSystemBody())) { // Navigation target is something we show in the info view if (navTarget->GetSystemBody()->GetPath() != m_selectedBodyPath) return REFRESH_SELECTED_BODY; // and wasn't selected, yet @@ -568,21 +568,21 @@ SystemInfoView::RefreshType SystemInfoView::NeedsRefresh() void SystemInfoView::Update() { switch (m_refresh) { - case REFRESH_ALL: - SystemChanged(m_game->GetSectorView()->GetSelected()); - m_refresh = REFRESH_NONE; - assert(NeedsRefresh() == REFRESH_NONE); - break; - case REFRESH_SELECTED_BODY: - UpdateIconSelections(); - UpdateEconomyTab(); //update price analysis after hyper jump - m_refresh = REFRESH_NONE; - assert(NeedsRefresh() == REFRESH_NONE); - break; - case REFRESH_NONE: - break; + case REFRESH_ALL: + SystemChanged(m_game->GetSectorView()->GetSelected()); + m_refresh = REFRESH_NONE; + assert(NeedsRefresh() == REFRESH_NONE); + break; + case REFRESH_SELECTED_BODY: + UpdateIconSelections(); + UpdateEconomyTab(); //update price analysis after hyper jump + m_refresh = REFRESH_NONE; + assert(NeedsRefresh() == REFRESH_NONE); + break; + case REFRESH_NONE: + break; } - UIView::Update(); + UIView::Update(); } void SystemInfoView::OnSwitchTo() @@ -592,7 +592,7 @@ void SystemInfoView::OnSwitchTo() if (needsRefresh != REFRESH_NONE) m_refresh = needsRefresh; } - UIView::OnSwitchTo(); + UIView::OnSwitchTo(); } void SystemInfoView::NextPage() @@ -605,19 +605,19 @@ void SystemInfoView::UpdateIconSelections() { m_selectedBodyPath = SystemPath(); - for (auto& bodyIcon : m_bodyIcons) { + for (auto &bodyIcon : m_bodyIcons) { bodyIcon.second->SetSelected(false); RefCountedPtr currentSys = m_game->GetSpace()->GetStarSystem(); if (currentSys && currentSys->GetPath() == m_system->GetPath()) { //navtarget can be only set in current system - Body* navtarget = Pi::player->GetNavTarget(); - if ( navtarget && - (navtarget->IsType(Body::STAR) || - navtarget->IsType(Body::PLANET) || - navtarget->IsType(Body::SPACESTATION))) { - const SystemPath& navpath = navtarget->GetSystemBody()->GetPath(); + Body *navtarget = Pi::player->GetNavTarget(); + if (navtarget && + (navtarget->IsType(Body::STAR) || + navtarget->IsType(Body::PLANET) || + navtarget->IsType(Body::SPACESTATION))) { + const SystemPath &navpath = navtarget->GetSystemBody()->GetPath(); if (bodyIcon.first == navpath.bodyIndex) { bodyIcon.second->SetSelectColor(Color(0, 255, 0, 255)); bodyIcon.second->SetSelected(true); @@ -637,11 +637,11 @@ void SystemInfoView::UpdateIconSelections() } } -SystemInfoView::BodyIcon::BodyIcon(const char *img, Graphics::Renderer *r) - : Gui::ImageRadioButton(0, img, img) - , m_renderer(r) - , m_hasStarport(false) - , m_selectColor(0, 255, 0, 255) +SystemInfoView::BodyIcon::BodyIcon(const char *img, Graphics::Renderer *r) : + Gui::ImageRadioButton(0, img, img), + m_renderer(r), + m_hasStarport(false), + m_selectColor(0, 255, 0, 255) { //no blending Graphics::RenderStateDesc rsd; diff --git a/src/SystemInfoView.h b/src/SystemInfoView.h index 67b8fec47..5c708aacd 100644 --- a/src/SystemInfoView.h +++ b/src/SystemInfoView.h @@ -4,8 +4,9 @@ #ifndef _SYSTEMINFOVIEW_H #define _SYSTEMINFOVIEW_H -#include "libs.h" +#include "galaxy/SystemPath.h" #include "gui/Gui.h" +#include "libs.h" #include "UIView.h" #include @@ -13,25 +14,30 @@ class Game; class StarSystem; class SystemBody; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} -class SystemInfoView: public UIView { +class SystemInfoView : public UIView { public: - SystemInfoView(Game* game); + SystemInfoView(Game *game); virtual void Update(); virtual void Draw3D(); void NextPage(); + protected: virtual void OnSwitchTo(); + private: class BodyIcon : public Gui::ImageRadioButton { public: - BodyIcon(const char* img, Graphics::Renderer*); + BodyIcon(const char *img, Graphics::Renderer *); virtual void Draw(); virtual void OnActivate(); bool HasStarport() { return m_hasStarport; } void SetHasStarport() { m_hasStarport = true; } - void SetSelectColor(const Color& color) { m_selectColor = color; } + void SetSelectColor(const Color &color) { m_selectColor = color; } + private: Graphics::Renderer *m_renderer; Graphics::RenderState *m_renderState; @@ -56,7 +62,7 @@ private: void PutBodies(SystemBody *body, Gui::Fixed *container, int dir, float pos[2], int &majorBodies, int &starports, int &onSurface, float &prevSize); void UpdateIconSelections(); - Game* m_game; + Game *m_game; Gui::VBox *m_infoBox; Gui::Fixed *m_econInfo; @@ -71,7 +77,7 @@ private: SystemPath m_selectedBodyPath; RefreshType m_refresh; //map is not enough to associate icons as each tab has their own. First element is the body index of SystemPath (names are not unique) - std::vector > m_bodyIcons; + std::vector> m_bodyIcons; bool m_unexplored; bool m_hasTradeComputer; }; diff --git a/src/SystemView.cpp b/src/SystemView.cpp index 2c8eb9c3e..b27a90965 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -2,37 +2,38 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "SystemView.h" -#include "Pi.h" -#include "SectorView.h" -#include "galaxy/Galaxy.h" -#include "galaxy/StarSystem.h" -#include "Lang.h" -#include "StringF.h" -#include "Space.h" -#include "Player.h" +#include "AnimationCurves.h" #include "FloatComparison.h" #include "Game.h" -#include "AnimationCurves.h" +#include "Lang.h" #include "MathUtil.h" +#include "Pi.h" +#include "Player.h" +#include "SectorView.h" +#include "Space.h" +#include "StringF.h" +#include "galaxy/Galaxy.h" +#include "galaxy/StarSystem.h" #include "graphics/Material.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" -#include #include +#include using namespace Graphics; const double SystemView::PICK_OBJECT_RECT_SIZE = 12.0; const Uint16 SystemView::N_VERTICES_MAX = 100; -static const float MIN_ZOOM = 1e-30f; // Just to avoid having 0 +static const float MIN_ZOOM = 1e-30f; // Just to avoid having 0 static const float MAX_ZOOM = 1e30f; static const float ZOOM_IN_SPEED = 2; -static const float ZOOM_OUT_SPEED = 1.f/ZOOM_IN_SPEED; -static const float WHEEL_SENSITIVITY = .1f; // Should be a variable in user settings. +static const float ZOOM_OUT_SPEED = 1.f / ZOOM_IN_SPEED; +static const float WHEEL_SENSITIVITY = .1f; // Should be a variable in user settings. static const double DEFAULT_VIEW_DISTANCE = 10.0; TransferPlanner::TransferPlanner() : - m_position(0., 0., 0.), m_velocity(0., 0., 0.) + m_position(0., 0., 0.), + m_velocity(0., 0., 0.) { m_dvPrograde = 0.0; m_dvNormal = 0.0; @@ -43,52 +44,51 @@ TransferPlanner::TransferPlanner() : vector3d TransferPlanner::GetVel() const { return m_velocity + GetOffsetVel(); } -vector3d TransferPlanner::GetOffsetVel() const { - if(m_position.ExactlyEqual(vector3d(0., 0., 0.))) +vector3d TransferPlanner::GetOffsetVel() const +{ + if (m_position.ExactlyEqual(vector3d(0., 0., 0.))) return vector3d(0., 0., 0.); const vector3d pNormal = m_position.Cross(m_velocity); return m_dvPrograde * m_velocity.Normalized() + - m_dvNormal * pNormal.Normalized() + - m_dvRadial * m_position.Normalized(); + m_dvNormal * pNormal.Normalized() + + m_dvRadial * m_position.Normalized(); } -void TransferPlanner::AddStartTime(double timeStep) { - if(std::fabs(m_startTime) < 1.) +void TransferPlanner::AddStartTime(double timeStep) +{ + if (std::fabs(m_startTime) < 1.) m_startTime = Pi::game->GetTime(); m_startTime += m_factor * timeStep; double deltaT = m_startTime - Pi::game->GetTime(); - if(deltaT > 0.) - { + if (deltaT > 0.) { Frame *frame = Pi::player->GetFrame()->GetNonRotFrame(); Orbit playerOrbit = Orbit::FromBodyState(Pi::player->GetPositionRelTo(frame), Pi::player->GetVelocityRelTo(frame), frame->GetSystemBody()->GetMass()); m_position = playerOrbit.OrbitalPosAtTime(deltaT); m_velocity = playerOrbit.OrbitalVelocityAtTime(frame->GetSystemBody()->GetMass(), deltaT); - } - else + } else ResetStartTime(); } -void TransferPlanner::ResetStartTime() { +void TransferPlanner::ResetStartTime() +{ m_startTime = 0; Frame *frame = Pi::player->GetFrame(); - if(!frame || GetOffsetVel().ExactlyEqual(vector3d(0., 0. , 0.))) - { + if (!frame || GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) { m_position = vector3d(0., 0., 0.); - m_velocity = vector3d(0. , 0., 0.); - } - else - { + m_velocity = vector3d(0., 0., 0.); + } else { frame = frame->GetNonRotFrame(); m_position = Pi::player->GetPositionRelTo(frame); m_velocity = Pi::player->GetVelocityRelTo(frame); } } -double TransferPlanner::GetStartTime() const { +double TransferPlanner::GetStartTime() const +{ return m_startTime; } @@ -97,24 +97,25 @@ static std::string formatTime(double t) std::stringstream formattedTime; formattedTime << std::setprecision(1) << std::fixed; double absT = fabs(t); - if(absT < 60.) + if (absT < 60.) formattedTime << t << "s"; - else if(absT < 3600) + else if (absT < 3600) formattedTime << t / 60. << "m"; - else if(absT < 86400) + else if (absT < 86400) formattedTime << t / 3600. << "h"; - else if(absT < 31536000) + else if (absT < 31536000) formattedTime << t / 86400. << "d"; else formattedTime << t / 31536000. << "y"; return formattedTime.str(); } -std::string TransferPlanner::printDeltaTime() { +std::string TransferPlanner::printDeltaTime() +{ std::stringstream out; out << std::setw(9); double deltaT = m_startTime - Pi::game->GetTime(); - if(std::fabs(m_startTime) < 1.) + if (std::fabs(m_startTime) < 1.) out << Lang::NOW; else out << formatTime(deltaT); @@ -122,9 +123,9 @@ std::string TransferPlanner::printDeltaTime() { return out.str(); } -void TransferPlanner::AddDv(BurnDirection d, double dv) { - if(m_position.ExactlyEqual(vector3d(0., 0., 0.))) - { +void TransferPlanner::AddDv(BurnDirection d, double dv) +{ + if (m_position.ExactlyEqual(vector3d(0., 0., 0.))) { Frame *frame = Pi::player->GetFrame()->GetNonRotFrame(); m_position = Pi::player->GetPositionRelTo(frame); m_velocity = Pi::player->GetVelocityRelTo(frame); @@ -133,65 +134,70 @@ void TransferPlanner::AddDv(BurnDirection d, double dv) { switch (d) { case PROGRADE: m_dvPrograde += m_factor * dv; break; - case NORMAL: m_dvNormal += m_factor * dv; break; - case RADIAL: m_dvRadial += m_factor * dv; break; + case NORMAL: m_dvNormal += m_factor * dv; break; + case RADIAL: m_dvRadial += m_factor * dv; break; } } -void TransferPlanner::ResetDv(BurnDirection d) { +void TransferPlanner::ResetDv(BurnDirection d) +{ switch (d) { case PROGRADE: m_dvPrograde = 0; break; - case NORMAL: m_dvNormal = 0; break; - case RADIAL: m_dvRadial = 0; break; + case NORMAL: m_dvNormal = 0; break; + case RADIAL: m_dvRadial = 0; break; } - if(std::fabs(m_startTime) < 1. && - GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) - { + if (std::fabs(m_startTime) < 1. && + GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) { m_position = vector3d(0., 0., 0.); m_velocity = vector3d(0., 0., 0.); m_startTime = 0.; } } -void TransferPlanner::ResetDv() { - m_dvPrograde = 0; - m_dvNormal = 0; - m_dvRadial = 0; +void TransferPlanner::ResetDv() +{ + m_dvPrograde = 0; + m_dvNormal = 0; + m_dvRadial = 0; - if(std::fabs(m_startTime) < 1.) { + if (std::fabs(m_startTime) < 1.) { m_position = vector3d(0., 0., 0.); m_velocity = vector3d(0., 0., 0.); m_startTime = 0.; - } + } } -std::string TransferPlanner::printDv(BurnDirection d) { +std::string TransferPlanner::printDv(BurnDirection d) +{ double dv = 0; char buf[10]; - switch(d) { + switch (d) { case PROGRADE: dv = m_dvPrograde; break; - case NORMAL: dv = m_dvNormal; break; - case RADIAL: dv = m_dvRadial; break; + case NORMAL: dv = m_dvNormal; break; + case RADIAL: dv = m_dvRadial; break; } snprintf(buf, sizeof(buf), "%6.0fm/s", dv); return std::string(buf); } -void TransferPlanner::IncreaseFactor(void) { - if(m_factor > 1000) return; +void TransferPlanner::IncreaseFactor(void) +{ + if (m_factor > 1000) return; m_factor *= m_factorFactor; } void TransferPlanner::ResetFactor(void) { m_factor = 1; } -void TransferPlanner::DecreaseFactor(void) { - if(m_factor < 0.0002) return; +void TransferPlanner::DecreaseFactor(void) +{ + if (m_factor < 0.0002) return; m_factor /= m_factorFactor; } -std::string TransferPlanner::printFactor(void) { +std::string TransferPlanner::printFactor(void) +{ char buf[16]; snprintf(buf, sizeof(buf), "%8gx", 10 * m_factor); return std::string(buf); @@ -199,9 +205,11 @@ std::string TransferPlanner::printFactor(void) { vector3d TransferPlanner::GetPosition() const { return m_position; } -void TransferPlanner::SetPosition(const vector3d& position) { m_position = position; } +void TransferPlanner::SetPosition(const vector3d &position) { m_position = position; } -SystemView::SystemView(Game* game) : UIView(), m_game(game) +SystemView::SystemView(Game *game) : + UIView(), + m_game(game) { SetTransparency(true); @@ -215,12 +223,12 @@ SystemView::SystemView(Game* game) : UIView(), m_game(game) m_objectLabels = new Gui::LabelSet(); Add(m_objectLabels, 0, 0); m_shipLabels = new Gui::LabelSet(); - m_shipLabels->SetLabelColor(Color(255,155,0,200)); + m_shipLabels->SetLabelColor(Color(255, 155, 0, 200)); Add(m_shipLabels, 0, 0); Gui::Screen::PopFont(); m_timePoint = (new Gui::Label(""))->Color(178, 178, 178); - Add(m_timePoint, 2, Gui::Screen::GetHeight()-Gui::Screen::GetFontHeight()-66); + Add(m_timePoint, 2, Gui::Screen::GetHeight() - Gui::Screen::GetFontHeight() - 66); m_infoLabel = (new Gui::Label(""))->Color(178, 178, 178); Add(m_infoLabel, 2, 0); @@ -246,9 +254,9 @@ SystemView::SystemView(Game* game) : UIView(), m_game(game) // Add the 3 Lagrange button stations m_toggleL4L5Button = new Gui::MultiStateImageButton(); - m_toggleL4L5Button->AddState(LAG_ICON, "icons/toggle_lag_icon.png"); - m_toggleL4L5Button->AddState(LAG_ICONTEXT, "icons/toggle_lag_icon_text.png"); - m_toggleL4L5Button->AddState(LAG_OFF, "icons/toggle_lag_off.png"); + m_toggleL4L5Button->AddState(LAG_ICON, "icons/toggle_lag_icon.png"); + m_toggleL4L5Button->AddState(LAG_ICONTEXT, "icons/toggle_lag_icon_text.png"); + m_toggleL4L5Button->AddState(LAG_OFF, "icons/toggle_lag_off.png"); m_toggleL4L5Button->SetToolTip(Lang::L4L5_DISPLAY_MODE_TOGGLE); m_toggleL4L5Button->SetRenderDimensions(30, 22); m_toggleL4L5Button->onClick.connect(sigc::mem_fun(this, &SystemView::OnToggleL4L5ButtonClick)); @@ -406,8 +414,8 @@ SystemView::SystemView(Game* game) : UIView(), m_game(game) m_showL4L5 = LAG_OFF; m_planner = Pi::planner; - m_orbitVts.reset( new vector3f[N_VERTICES_MAX] ); - m_orbitColors.reset( new Color[N_VERTICES_MAX] ); + m_orbitVts.reset(new vector3f[N_VERTICES_MAX]); + m_orbitColors.reset(new Color[N_VERTICES_MAX]); } SystemView::~SystemView() @@ -423,23 +431,42 @@ void SystemView::OnClickAccel(float step) } void SystemView::OnIncreaseFactorButtonClick(void) { m_planner->IncreaseFactor(); } -void SystemView::OnResetFactorButtonClick(void) { m_planner->ResetFactor(); } +void SystemView::OnResetFactorButtonClick(void) { m_planner->ResetFactor(); } void SystemView::OnDecreaseFactorButtonClick(void) { m_planner->DecreaseFactor(); } -void SystemView::OnToggleShipsButtonClick(void) { - switch(m_shipDrawing) { - case OFF: m_shipDrawing = BOXES; RefreshShips(); break; - case BOXES: m_shipDrawing = ORBITS; RefreshShips(); break; - case ORBITS: m_shipDrawing = OFF; m_shipLabels->Clear(); break; +void SystemView::OnToggleShipsButtonClick(void) +{ + switch (m_shipDrawing) { + case OFF: + m_shipDrawing = BOXES; + RefreshShips(); + break; + case BOXES: + m_shipDrawing = ORBITS; + RefreshShips(); + break; + case ORBITS: + m_shipDrawing = OFF; + m_shipLabels->Clear(); + break; } } -void SystemView::OnToggleL4L5ButtonClick(Gui::MultiStateImageButton *b) { - switch (m_showL4L5) - { - case LAG_OFF: m_showL4L5 = LAG_ICON; m_toggleL4L5Button->SetActiveState(LAG_ICON); break; - case LAG_ICON: m_showL4L5 = LAG_ICONTEXT; m_toggleL4L5Button->SetActiveState(LAG_ICONTEXT); break; - case LAG_ICONTEXT: m_showL4L5 = LAG_OFF; m_toggleL4L5Button->SetActiveState(LAG_OFF); break; +void SystemView::OnToggleL4L5ButtonClick(Gui::MultiStateImageButton *b) +{ + switch (m_showL4L5) { + case LAG_OFF: + m_showL4L5 = LAG_ICON; + m_toggleL4L5Button->SetActiveState(LAG_ICON); + break; + case LAG_ICON: + m_showL4L5 = LAG_ICONTEXT; + m_toggleL4L5Button->SetActiveState(LAG_ICONTEXT); + break; + case LAG_ICONTEXT: + m_showL4L5 = LAG_OFF; + m_toggleL4L5Button->SetActiveState(LAG_OFF); + break; } } @@ -455,7 +482,7 @@ void SystemView::ResetViewpoint() m_rot_x = 50; m_rot_z_to = m_rot_z; m_rot_x_to = m_rot_x; - m_zoom = 1.0f/float(AU); + m_zoom = 1.0f / float(AU); m_zoomTo = m_zoom; m_timeStep = 1.0f; m_time = m_game->GetTime(); @@ -468,8 +495,7 @@ void SystemView::PutOrbit(const Orbit *orbit, const vector3d &offset, const Colo for (unsigned short i = 0; i < N_VERTICES_MAX; ++i) { const double t = double(i) / double(N_VERTICES_MAX); const vector3d pos = orbit->EvenSpacedPosTrajectory(t); - if (pos.Length() < planetRadius) - { + if (pos.Length() < planetRadius) { maxT = t; break; } @@ -482,7 +508,7 @@ void SystemView::PutOrbit(const Orbit *orbit, const vector3d &offset, const Colo const double tMinust0 = m_time - m_game->GetTime(); for (unsigned short i = 0; i < N_VERTICES_MAX; ++i) { const double t = double(i) / double(N_VERTICES_MAX) * maxT; - if(fadingColors == 0 && t >= startTrailPercent * maxT) + if (fadingColors == 0 && t >= startTrailPercent * maxT) fadingColors = i; const vector3d pos = orbit->EvenSpacedPosTrajectory(t, tMinust0); m_orbitVts[i] = vector3f(offset + pos * double(m_zoom)); @@ -495,8 +521,7 @@ void SystemView::PutOrbit(const Orbit *orbit, const vector3d &offset, const Colo std::fill_n(m_orbitColors.get(), num_vertices, fadedColor); const Uint16 trailLength = num_vertices - fadingColors; - for (Uint16 currentColor = 0; currentColor < trailLength; ++currentColor) - { + for (Uint16 currentColor = 0; currentColor < trailLength; ++currentColor) { float scalingParameter = fadedColorParameter + static_cast(currentColor) / trailLength * (1.f - fadedColorParameter); m_orbitColors[currentColor + fadingColors] = color * scalingParameter; } @@ -514,18 +539,17 @@ void SystemView::PutOrbit(const Orbit *orbit, const vector3d &offset, const Colo Gui::Screen::EnterOrtho(); vector3d pos; - if(Gui::Screen::Project(offset + orbit->Perigeum() * double(m_zoom), pos)) - m_periapsisIcon->Draw(Pi::renderer, vector2f(pos.x-3, pos.y-5), vector2f(6,10), color); - if(Gui::Screen::Project(offset + orbit->Apogeum() * double(m_zoom), pos)) - m_apoapsisIcon->Draw(Pi::renderer, vector2f(pos.x-3, pos.y-5), vector2f(6,10), color); + if (Gui::Screen::Project(offset + orbit->Perigeum() * double(m_zoom), pos)) + m_periapsisIcon->Draw(Pi::renderer, vector2f(pos.x - 3, pos.y - 5), vector2f(6, 10), color); + if (Gui::Screen::Project(offset + orbit->Apogeum() * double(m_zoom), pos)) + m_apoapsisIcon->Draw(Pi::renderer, vector2f(pos.x - 3, pos.y - 5), vector2f(6, 10), color); - if (showLagrange && m_showL4L5!=LAG_OFF) - { + if (showLagrange && m_showL4L5 != LAG_OFF) { const Color LPointColor(0x00d6e2ff); const vector3d posL4 = orbit->EvenSpacedPosTrajectory((1.0 / 360.0) * 60.0, tMinust0); if (Gui::Screen::Project(offset + posL4 * double(m_zoom), pos)) { m_l4Icon->Draw(Pi::renderer, vector2f(pos.x - 2, pos.y - 2), vector2f(4, 4), LPointColor); - if(m_showL4L5==LAG_ICONTEXT) + if (m_showL4L5 == LAG_ICONTEXT) m_objectLabels->Add(std::string("L4"), sigc::mem_fun(this, &SystemView::OnClickLagrange), pos.x, pos.y); } @@ -547,7 +571,7 @@ void SystemView::OnClickObject(const SystemBody *b) desc += std::string(Lang::NAME_OBJECT); desc += ":\n"; - data += b->GetName()+"\n"; + data += b->GetName() + "\n"; desc += std::string(Lang::DAY_LENGTH); desc += std::string(Lang::ROTATIONAL_PERIOD); @@ -556,16 +580,16 @@ void SystemView::OnClickObject(const SystemBody *b) desc += std::string(Lang::RADIUS); desc += ":\n"; - data += format_distance(b->GetRadius())+"\n"; + data += format_distance(b->GetRadius()) + "\n"; if (b->GetParent()) { desc += std::string(Lang::SEMI_MAJOR_AXIS); - desc += ":\n"; - data += format_distance(b->GetOrbit().GetSemiMajorAxis())+"\n"; + desc += ":\n"; + data += format_distance(b->GetOrbit().GetSemiMajorAxis()) + "\n"; desc += std::string(Lang::ORBITAL_PERIOD); - desc += ":\n"; - data += stringf(Lang::N_DAYS, formatarg("days", b->GetOrbit().Period() / (24*60*60))) + "\n"; + desc += ":\n"; + data += stringf(Lang::N_DAYS, formatarg("days", b->GetOrbit().Period() / (24 * 60 * 60))) + "\n"; } m_infoLabel->SetText(desc); m_infoText->SetText(data); @@ -573,14 +597,13 @@ void SystemView::OnClickObject(const SystemBody *b) // click on object (in same system) sets/unsets it as nav target SystemPath path = m_system->GetPathOf(b); if (m_game->GetSpace()->GetStarSystem()->GetPath() == m_system->GetPath()) { - Body* body = m_game->GetSpace()->FindBodyForPath(&path); + Body *body = m_game->GetSpace()->FindBodyForPath(&path); if (body != 0) { - if(Pi::player->GetNavTarget() == body) { + if (Pi::player->GetNavTarget() == body) { Pi::player->SetNavTarget(body); Pi::player->SetNavTarget(0); m_game->log->Add(Lang::UNSET_NAVTARGET); - } - else { + } else { Pi::player->SetNavTarget(body); m_game->log->Add(Lang::SET_NAVTARGET_TO + body->GetLabel()); } @@ -590,7 +613,6 @@ void SystemView::OnClickObject(const SystemBody *b) void SystemView::OnClickLagrange() { - } void SystemView::PutLabel(const SystemBody *b, const vector3d &offset) @@ -606,7 +628,8 @@ void SystemView::PutLabel(const SystemBody *b, const vector3d &offset) Gui::Screen::LeaveOrtho(); } -void SystemView::LabelShip(Ship *s, const vector3d &offset) { +void SystemView::LabelShip(Ship *s, const vector3d &offset) +{ Gui::Screen::EnterOrtho(); vector3d pos; @@ -617,12 +640,16 @@ void SystemView::LabelShip(Ship *s, const vector3d &offset) { Gui::Screen::LeaveOrtho(); } -void SystemView::OnClickShip(Ship *s) { - if(!s) { printf("clicked on ship label but ship wasn't there\n"); return; } - if(Pi::player->GetNavTarget() == s) { //un-select ship if already selected +void SystemView::OnClickShip(Ship *s) +{ + if (!s) { + printf("clicked on ship label but ship wasn't there\n"); + return; + } + if (Pi::player->GetNavTarget() == s) { //un-select ship if already selected Pi::player->SetNavTarget(0); // remove current m_game->log->Add(Lang::UNSET_NAVTARGET); - m_infoLabel->SetText(""); // remove lingering text + m_infoLabel->SetText(""); // remove lingering text m_infoText->SetText(""); } else { Pi::player->SetNavTarget(s); @@ -636,13 +663,13 @@ void SystemView::OnClickShip(Ship *s) { // ...if we have advanced target scanner equipment, show some extra info on selected ship int prop_var = 0; Pi::player->Properties().Get("target_scanner_level_cap", prop_var); - if (prop_var > 1) { // advanced target scanner + if (prop_var > 1) { // advanced target scanner const shipstats_t &stats = s->GetStats(); text += s->GetShipType()->name; text += "\n"; - lua_State * l = Lua::manager->GetLuaState(); + lua_State *l = Lua::manager->GetLuaState(); int clean_stack = lua_gettop(l); LuaObject::CallMethod(s, "GetEquip", "engine").PushCopyToStack(); @@ -662,8 +689,7 @@ void SystemView::OnClickShip(Ship *s) { } m_infoLabel->SetText(text); - m_infoText->SetText(""); // clear lingering info from body being selected - + m_infoText->SetText(""); // clear lingering info from body being selected } } @@ -672,10 +698,8 @@ void SystemView::PutBody(const SystemBody *b, const vector3d &offset, const matr if (b->GetType() == SystemBody::TYPE_STARPORT_SURFACE) return; - if (b->GetType() != SystemBody::TYPE_GRAVPOINT) - { - if (!m_bodyIcon) - { + if (b->GetType() != SystemBody::TYPE_GRAVPOINT) { + if (!m_bodyIcon) { Graphics::RenderStateDesc rsd; auto solidState = m_renderer->CreateRenderState(rsd); m_bodyIcon.reset(new Graphics::Drawables::Disk(m_renderer, solidState, Color::WHITE, 1.0f)); @@ -699,45 +723,39 @@ void SystemView::PutBody(const SystemBody *b, const vector3d &offset, const matr } Frame *frame = Pi::player->GetFrame(); - if(frame->IsRotFrame()) + if (frame->IsRotFrame()) frame = frame->GetNonRotFrame(); // display the players orbit(?) - if(frame->GetSystemBody() == b && frame->GetSystemBody()->GetMass() > 0) - { + if (frame->GetSystemBody() == b && frame->GetSystemBody()->GetMass() > 0) { const double t0 = m_game->GetTime(); Orbit playerOrbit = Pi::player->ComputeOrbit(); PutOrbit(&playerOrbit, offset, Color::RED, b->GetRadius()); const double plannerStartTime = m_planner->GetStartTime(); - if(!m_planner->GetPosition().ExactlyEqual(vector3d(0,0,0))) - { + if (!m_planner->GetPosition().ExactlyEqual(vector3d(0, 0, 0))) { Orbit plannedOrbit = Orbit::FromBodyState(m_planner->GetPosition(), - m_planner->GetVel(), - frame->GetSystemBody()->GetMass()); + m_planner->GetVel(), + frame->GetSystemBody()->GetMass()); PutOrbit(&plannedOrbit, offset, Color::STEELBLUE, b->GetRadius()); - if(std::fabs(m_time - t0) > 1. && (m_time - plannerStartTime) > 0.) + if (std::fabs(m_time - t0) > 1. && (m_time - plannerStartTime) > 0.) PutSelectionBox(offset + plannedOrbit.OrbitalPosAtTime(m_time - plannerStartTime) * static_cast(m_zoom), Color::STEELBLUE); else PutSelectionBox(offset + m_planner->GetPosition() * static_cast(m_zoom), Color::STEELBLUE); - } - PutSelectionBox(offset + playerOrbit.OrbitalPosAtTime(m_time - t0)* double(m_zoom), Color::RED); + PutSelectionBox(offset + playerOrbit.OrbitalPosAtTime(m_time - t0) * double(m_zoom), Color::RED); } // display all child bodies and their orbits - if (b->HasChildren()) - { - for(const SystemBody* kid : b->GetChildren()) - { + if (b->HasChildren()) { + for (const SystemBody *kid : b->GetChildren()) { if (is_zero_general(kid->GetOrbit().GetSemiMajorAxis())) continue; const double axisZoom = kid->GetOrbit().GetSemiMajorAxis() * m_zoom; - if (axisZoom < DEFAULT_VIEW_DISTANCE) - { + if (axisZoom < DEFAULT_VIEW_DISTANCE) { const SystemBody::BodySuperType bst = kid->GetSuperType(); const bool showLagrange = (bst == SystemBody::SUPERTYPE_ROCKY_PLANET || bst == SystemBody::SUPERTYPE_GAS_GIANT); PutOrbit(&(kid->GetOrbit()), offset, Color::GREEN, 0.0, showLagrange); @@ -780,12 +798,12 @@ void SystemView::PutSelectionBox(const vector3d &worldPos, const Color &col) const float y1 = float(screenPos.y - SystemView::PICK_OBJECT_RECT_SIZE * 0.5); const float y2 = float(y1 + SystemView::PICK_OBJECT_RECT_SIZE); - const vector3f verts[4] = { - vector3f(x1, y1, 0.f), - vector3f(x2, y1, 0.f), - vector3f(x2, y2, 0.f), - vector3f(x1, y2, 0.f) - }; + const vector3f verts[4] = { + vector3f(x1, y1, 0.f), + vector3f(x2, y1, 0.f), + vector3f(x2, y2, 0.f), + vector3f(x1, y2, 0.f) + }; m_selectBox.SetData(4, &verts[0], col); m_selectBox.Draw(m_renderer, m_lineState, Graphics::LINE_LOOP); } @@ -817,11 +835,10 @@ void SystemView::Draw3D() if (m_realtime) { m_time = m_game->GetTime(); + } else { + m_time += m_timeStep * Pi::GetFrameTime(); } - else { - m_time += m_timeStep*Pi::GetFrameTime(); - } - std::string t = Lang::TIME_POINT+format_date(m_time); + std::string t = Lang::TIME_POINT + format_date(m_time); m_timePoint->SetText(t); if (!m_system) { @@ -830,12 +847,12 @@ void SystemView::Draw3D() } matrix4x4f trans = matrix4x4f::Identity(); - trans.Translate(0,0,-DEFAULT_VIEW_DISTANCE); - trans.Rotate( DEG2RAD(m_rot_x), 1, 0, 0); + trans.Translate(0, 0, -DEFAULT_VIEW_DISTANCE); + trans.Rotate(DEG2RAD(m_rot_x), 1, 0, 0); trans.Rotate(-DEG2RAD(m_rot_z), 0, 0, 1); m_renderer->SetTransform(trans); - vector3d pos(0,0,0); + vector3d pos(0, 0, 0); if (m_selectedObject) GetTransformTo(m_selectedObject, pos); // glLineWidth(2); @@ -855,7 +872,7 @@ void SystemView::Draw3D() } // glLineWidth(1); - if(m_shipDrawing != OFF) { + if (m_shipDrawing != OFF) { RefreshShips(); DrawShips(m_time - m_game->GetTime(), pos); } @@ -870,31 +887,54 @@ void SystemView::Update() if (!Pi::IsConsoleActive()) { if (Pi::input.KeyState(SDLK_EQUALS) || m_zoomInButton->IsPressed()) - m_zoomTo *= pow(ZOOM_IN_SPEED * Pi::GetMoveSpeedShiftModifier(), ft); + m_zoomTo *= pow(ZOOM_IN_SPEED * Pi::GetMoveSpeedShiftModifier(), ft); if (Pi::input.KeyState(SDLK_MINUS) || m_zoomOutButton->IsPressed()) - m_zoomTo *= pow(ZOOM_OUT_SPEED / Pi::GetMoveSpeedShiftModifier(), ft); + m_zoomTo *= pow(ZOOM_OUT_SPEED / Pi::GetMoveSpeedShiftModifier(), ft); // transfer planner buttons - if (m_plannerIncreaseStartTimeButton->IsPressed()) { m_planner->AddStartTime( 10.); } - if (m_plannerDecreaseStartTimeButton->IsPressed()) { m_planner->AddStartTime(-10.); } - if (m_plannerAddProgradeVelButton->IsPressed()) { m_planner->AddDv(PROGRADE, 10.0); } - if (m_plannerAddRetrogradeVelButton->IsPressed()) { m_planner->AddDv(PROGRADE, -10.0); } - if (m_plannerAddNormalVelButton->IsPressed()) { m_planner->AddDv(NORMAL, 10.0); } - if (m_plannerAddAntiNormalVelButton->IsPressed()) { m_planner->AddDv(NORMAL, -10.0); } - if (m_plannerAddRadiallyInVelButton->IsPressed()) { m_planner->AddDv(RADIAL, 10.0); } - if (m_plannerAddRadiallyOutVelButton->IsPressed()) { m_planner->AddDv(RADIAL, -10.0); } - if (m_plannerResetStartTimeButton->IsPressed()) { m_planner->ResetStartTime(); } - if (m_plannerZeroProgradeVelButton->IsPressed()) { m_planner->ResetDv(PROGRADE); } - if (m_plannerZeroNormalVelButton->IsPressed()) { m_planner->ResetDv(NORMAL); } - if (m_plannerZeroRadialVelButton->IsPressed()) { m_planner->ResetDv(RADIAL); } + if (m_plannerIncreaseStartTimeButton->IsPressed()) { + m_planner->AddStartTime(10.); + } + if (m_plannerDecreaseStartTimeButton->IsPressed()) { + m_planner->AddStartTime(-10.); + } + if (m_plannerAddProgradeVelButton->IsPressed()) { + m_planner->AddDv(PROGRADE, 10.0); + } + if (m_plannerAddRetrogradeVelButton->IsPressed()) { + m_planner->AddDv(PROGRADE, -10.0); + } + if (m_plannerAddNormalVelButton->IsPressed()) { + m_planner->AddDv(NORMAL, 10.0); + } + if (m_plannerAddAntiNormalVelButton->IsPressed()) { + m_planner->AddDv(NORMAL, -10.0); + } + if (m_plannerAddRadiallyInVelButton->IsPressed()) { + m_planner->AddDv(RADIAL, 10.0); + } + if (m_plannerAddRadiallyOutVelButton->IsPressed()) { + m_planner->AddDv(RADIAL, -10.0); + } + if (m_plannerResetStartTimeButton->IsPressed()) { + m_planner->ResetStartTime(); + } + if (m_plannerZeroProgradeVelButton->IsPressed()) { + m_planner->ResetDv(PROGRADE); + } + if (m_plannerZeroNormalVelButton->IsPressed()) { + m_planner->ResetDv(NORMAL); + } + if (m_plannerZeroRadialVelButton->IsPressed()) { + m_planner->ResetDv(RADIAL); + } m_plannerFactorText->SetText(m_planner->printFactor()); m_plannerStartTimeText->SetText(m_planner->printDeltaTime()); m_plannerProgradeDvText->SetText(m_planner->printDv(PROGRADE)); m_plannerNormalDvText->SetText(m_planner->printDv(NORMAL)); m_plannerRadialDvText->SetText(m_planner->printDv(RADIAL)); - } // TODO: add "true" lower/upper bounds to m_zoomTo / m_zoom m_zoomTo = Clamp(m_zoomTo, MIN_ZOOM, MAX_ZOOM); @@ -909,8 +949,8 @@ void SystemView::Update() if (Pi::input.MouseButtonState(SDL_BUTTON_RIGHT)) { int motion[2]; Pi::input.GetMouseMotion(motion); - m_rot_x_to += motion[1]*20*ft; - m_rot_z_to += motion[0]*20*ft; + m_rot_x_to += motion[1] * 20 * ft; + m_rot_z_to += motion[0] * 20 * ft; } UIView::Update(); @@ -920,46 +960,49 @@ void SystemView::MouseWheel(bool up) { if (this == Pi::GetView()) { if (!up) - m_zoomTo *= ((ZOOM_OUT_SPEED-1) * WHEEL_SENSITIVITY+1) / Pi::GetMoveSpeedShiftModifier(); + m_zoomTo *= ((ZOOM_OUT_SPEED - 1) * WHEEL_SENSITIVITY + 1) / Pi::GetMoveSpeedShiftModifier(); else - m_zoomTo *= ((ZOOM_IN_SPEED-1) * WHEEL_SENSITIVITY+1) * Pi::GetMoveSpeedShiftModifier(); + m_zoomTo *= ((ZOOM_IN_SPEED - 1) * WHEEL_SENSITIVITY + 1) * Pi::GetMoveSpeedShiftModifier(); } } -void SystemView::RefreshShips(void) { +void SystemView::RefreshShips(void) +{ m_contacts.clear(); - if(!m_game->GetSpace()->GetStarSystem()->GetPath().IsSameSystem(m_game->GetSectorView()->GetSelected())) + if (!m_game->GetSpace()->GetStarSystem()->GetPath().IsSameSystem(m_game->GetSectorView()->GetSelected())) return; auto bs = m_game->GetSpace()->GetBodies(); - for(auto s = bs.begin(); s != bs.end(); s++) { - if((*s) != Pi::player && - (*s)->GetType() == Object::SHIP) { + for (auto s = bs.begin(); s != bs.end(); s++) { + if ((*s) != Pi::player && + (*s)->GetType() == Object::SHIP) { - const auto c = static_cast(*s); + const auto c = static_cast(*s); m_contacts.push_back(std::make_pair(c, c->ComputeOrbit())); } } } -void SystemView::DrawShips(const double t, const vector3d &offset) { +void SystemView::DrawShips(const double t, const vector3d &offset) +{ m_shipLabels->Clear(); - for(auto s = m_contacts.begin(); s != m_contacts.end(); s++) { + for (auto s = m_contacts.begin(); s != m_contacts.end(); s++) { vector3d pos = offset; if ((*s).first->GetFlightState() != Ship::FlightState::FLYING) { Frame *frame = Pi::game->GetSpace()->GetRootFrame(); - pos += (*s).first->GetPositionRelTo(frame) * double(m_zoom);; + pos += (*s).first->GetPositionRelTo(frame) * double(m_zoom); + ; } else { Frame *frame = (*s).first->GetFrame(); vector3d bpos = vector3d(0., 0., 0.); if (frame != Pi::game->GetSpace()->GetRootFrame()) - bpos += frame->GetPositionRelTo(Pi::game->GetSpace()->GetRootFrame()); + bpos += frame->GetPositionRelTo(Pi::game->GetSpace()->GetRootFrame()); pos += (bpos + (*s).second.OrbitalPosAtTime(t)) * double(m_zoom); } const bool isNavTarget = Pi::player->GetNavTarget() == (*s).first; PutSelectionBox(pos, isNavTarget ? Color::GREEN : Color::BLUE); LabelShip((*s).first, pos); - if(m_shipDrawing == ORBITS && (*s).first->GetFlightState() == Ship::FlightState::FLYING) + if (m_shipDrawing == ORBITS && (*s).first->GetFlightState() == Ship::FlightState::FLYING) PutOrbit(&(*s).second, offset, isNavTarget ? Color::GREEN : Color::BLUE, 0); } } diff --git a/src/SystemView.h b/src/SystemView.h index a454d2422..baceae2aa 100644 --- a/src/SystemView.h +++ b/src/SystemView.h @@ -4,10 +4,10 @@ #ifndef _SYSTEMVIEW_H #define _SYSTEMVIEW_H -#include "libs.h" -#include "gui/Gui.h" #include "UIView.h" #include "graphics/Drawables.h" +#include "gui/Gui.h" +#include "libs.h" class StarSystem; class SystemBody; @@ -40,7 +40,7 @@ public: vector3d GetOffsetVel() const; vector3d GetPosition() const; double GetStartTime() const; - void SetPosition(const vector3d& position); + void SetPosition(const vector3d &position); void IncreaseFactor(), ResetFactor(), DecreaseFactor(); void AddStartTime(double timeStep); void ResetStartTime(); @@ -50,23 +50,25 @@ public: std::string printDeltaTime(); std::string printDv(BurnDirection d); std::string printFactor(); + private: double m_dvPrograde; double m_dvNormal; double m_dvRadial; - double m_factor; // dv multiplier + double m_factor; // dv multiplier const double m_factorFactor = 5.0; // m_factor multiplier vector3d m_position; vector3d m_velocity; double m_startTime; }; -class SystemView: public UIView { +class SystemView : public UIView { public: - SystemView(Game* game); + SystemView(Game *game); virtual ~SystemView(); virtual void Update(); virtual void Draw3D(); + private: static const double PICK_OBJECT_RECT_SIZE; static const Uint16 N_VERTICES_MAX; @@ -91,13 +93,13 @@ private: void LabelShip(Ship *s, const vector3d &offset); void OnClickShip(Ship *s); - Game* m_game; + Game *m_game; RefCountedPtr m_system; const SystemBody *m_selectedObject; bool m_unexplored; ShowLagrange m_showL4L5; TransferPlanner *m_planner; - std::list> m_contacts; + std::list> m_contacts; Gui::LabelSet *m_shipLabels; ShipDrawing m_shipDrawing; float m_rot_x, m_rot_z; diff --git a/src/TerrainBody.cpp b/src/TerrainBody.cpp index 32bb5833d..482ff5d6f 100644 --- a/src/TerrainBody.cpp +++ b/src/TerrainBody.cpp @@ -2,15 +2,15 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "TerrainBody.h" +#include "Frame.h" +#include "Game.h" +#include "GameSaveError.h" #include "GasGiant.h" #include "GeoSphere.h" #include "Pi.h" #include "WorldView.h" -#include "Frame.h" -#include "Game.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" -#include "GameSaveError.h" TerrainBody::TerrainBody(SystemBody *sbody) : Body(), @@ -37,7 +37,7 @@ void TerrainBody::InitTerrainBody() assert(m_sbody); m_mass = m_sbody->GetMass(); if (!m_baseSphere) { - if ( SystemBody::SUPERTYPE_GAS_GIANT==m_sbody->GetSuperType() ) { + if (SystemBody::SUPERTYPE_GAS_GIANT == m_sbody->GetSuperType()) { m_baseSphere.reset(new GasGiant(m_sbody)); } else { m_baseSphere.reset(new GeoSphere(m_sbody)); @@ -84,21 +84,20 @@ void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, con //stars very far away are downscaled, because they cannot be //accurately drawn using actual distances int shrink = 0; - if (m_sbody->GetSuperType() == SystemBody::SUPERTYPE_STAR) - { + if (m_sbody->GetSuperType() == SystemBody::SUPERTYPE_STAR) { double len = fpos.Length(); double dist_to_horizon; for (;;) { if (len < rad) // player inside radius case break; - dist_to_horizon = sqrt(len*len - rad * rad); + dist_to_horizon = sqrt(len * len - rad * rad); - if (dist_to_horizon < zfar*0.5) + if (dist_to_horizon < zfar * 0.5) break; rad *= 0.25; - fpos = 0.25*fpos; + fpos = 0.25 * fpos; len *= 0.25; ++shrink; } @@ -108,12 +107,12 @@ void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, con ftran.ClearToRotOnly(); campos = ftran.Inverse() * campos; - campos = campos * (1.0/rad); // position of camera relative to planet "model" + campos = campos * (1.0 / rad); // position of camera relative to planet "model" std::vector shadows; - if( camera ) { + if (camera) { camera->PrincipalShadows(this, 3, shadows); - for (std::vector::iterator it = shadows.begin(), itEnd=shadows.end(); it!=itEnd; ++it) { + for (std::vector::iterator it = shadows.begin(), itEnd = shadows.end(); it != itEnd; ++it) { it->centre = ftran * it->centre; } } @@ -155,8 +154,10 @@ double TerrainBody::GetTerrainHeight(const vector3d &pos_) const bool TerrainBody::IsSuperType(SystemBody::BodySuperType t) const { - if (!m_sbody) return false; - else return m_sbody->GetSuperType() == t; + if (!m_sbody) + return false; + else + return m_sbody->GetSuperType() == t; } //static diff --git a/src/TerrainBody.h b/src/TerrainBody.h index 95cd75600..a1b8757cc 100644 --- a/src/TerrainBody.h +++ b/src/TerrainBody.h @@ -4,13 +4,15 @@ #ifndef _TERRAINBODY_H #define _TERRAINBODY_H -#include "Body.h" -#include "galaxy/StarSystem.h" #include "BaseSphere.h" +#include "Body.h" #include "Camera.h" +#include "galaxy/StarSystem.h" class Frame; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} class TerrainBody : public Body { public: @@ -32,7 +34,7 @@ public: static void OnChangeDetailLevel(); protected: - TerrainBody(SystemBody*); + TerrainBody(SystemBody *); TerrainBody(); virtual ~TerrainBody(); diff --git a/src/Tombstone.cpp b/src/Tombstone.cpp index d14b243aa..1ccb02719 100644 --- a/src/Tombstone.cpp +++ b/src/Tombstone.cpp @@ -7,8 +7,8 @@ #include "graphics/Renderer.h" #include "scenegraph/SceneGraph.h" -Tombstone::Tombstone(Graphics::Renderer *r, int width, int height) -: Cutscene(r, width, height) +Tombstone::Tombstone(Graphics::Renderer *r, int width, int height) : + Cutscene(r, width, height) { m_ambientColor = Color(13, 13, 26, 255); @@ -18,7 +18,7 @@ Tombstone::Tombstone(Graphics::Renderer *r, int width, int height) m_model = Pi::FindModel("tombstone"); m_model->SetLabel(Lang::TOMBSTONE_EPITAPH); const Uint32 numMats = m_model->GetNumMaterials(); - for( Uint32 m=0; m mat = m_model->GetMaterialByIndex(m); mat->specialParameter0 = nullptr; } @@ -35,7 +35,7 @@ void Tombstone::Draw(float _time) m_renderer->SetAmbientColor(m_ambientColor); m_renderer->SetLights(m_lights.size(), &m_lights[0]); - matrix4x4f rot = matrix4x4f::RotateYMatrix(_time*2); - rot[14] = -std::max(150.0f - 30.0f*_time, 30.0f); + matrix4x4f rot = matrix4x4f::RotateYMatrix(_time * 2); + rot[14] = -std::max(150.0f - 30.0f * _time, 30.0f); m_model->Render(rot); } diff --git a/src/UIView.cpp b/src/UIView.cpp index 4fcd65497..0de4d43b6 100644 --- a/src/UIView.cpp +++ b/src/UIView.cpp @@ -3,8 +3,8 @@ #include "UIView.h" #include "Pi.h" -#include "ui/Context.h" #include "gameui/Panel.h" +#include "ui/Context.h" void UIView::OnSwitchTo() { @@ -24,12 +24,14 @@ void UIView::OnSwitchFrom() Pi::ui->Layout(); // UI does important things on layout, like updating keyboard shortcuts } -void UIView::BuildUI(UI::Single *container) { +void UIView::BuildUI(UI::Single *container) +{ UI::Widget *w = BuildTemplateUI(); if (w) container->SetInnerWidget(w); } -UI::Widget *UIView::BuildTemplateUI() { +UI::Widget *UIView::BuildTemplateUI() +{ if (m_templateName) return Pi::ui->CallTemplate(m_templateName); else diff --git a/src/UIView.h b/src/UIView.h index 4b68f918e..eeeac8462 100644 --- a/src/UIView.h +++ b/src/UIView.h @@ -9,18 +9,20 @@ namespace UI { class Widget; class Single; -} +} // namespace UI // wrapper to allow new UI to be switched to by the existing view system // remove this once all existing views are ported to the new UI class UIView : public View { public: - UIView(const char *templateName) : m_templateName(templateName) {} - UIView() : m_templateName(0) {} + UIView(const char *templateName) : + m_templateName(templateName) {} + UIView() : + m_templateName(0) {} virtual void Update() {} virtual void Draw3D() {} - const char* GetTemplateName() { return m_templateName; } + const char *GetTemplateName() { return m_templateName; } protected: virtual void BuildUI(UI::Single *container); diff --git a/src/VideoLink.h b/src/VideoLink.h index 07c02e531..4b4d1cd5a 100644 --- a/src/VideoLink.h +++ b/src/VideoLink.h @@ -8,9 +8,12 @@ class VideoLink : public Gui::Widget { public: - VideoLink(float w, float h) : m_width(w), m_height(h) {} + VideoLink(float w, float h) : + m_width(w), + m_height(h) {} - virtual void GetSizeRequested(float size[2]) { + virtual void GetSizeRequested(float size[2]) + { size[0] = m_width; size[1] = m_height; } diff --git a/src/View.cpp b/src/View.cpp index 49b41a945..a21f5aabe 100644 --- a/src/View.cpp +++ b/src/View.cpp @@ -5,11 +5,13 @@ #include "Pi.h" #include "ShipCpanel.h" -ShipCpanel* View::s_cpan = nullptr; +ShipCpanel *View::s_cpan = nullptr; -View::View(): Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight()-64)) { +View::View() : + Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight() - 64)) +{ m_rightButtonBar = new Gui::Fixed(128, 26); - m_rightButtonBar->SetBgColor(Color(160,160,160,255)); + m_rightButtonBar->SetBgColor(Color(160, 160, 160, 255)); m_rightRegion2 = new Gui::Fixed(126, 17); m_rightRegion2->SetTransparency(true); @@ -18,7 +20,8 @@ View::View(): Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetH m_rightRegion1->SetTransparency(true); } -View::~View() { +View::~View() +{ Gui::Screen::RemoveBaseWidget(m_rightButtonBar); Gui::Screen::RemoveBaseWidget(m_rightRegion2); Gui::Screen::RemoveBaseWidget(m_rightRegion1); @@ -29,7 +32,8 @@ View::~View() { delete m_rightRegion1; } -void View::Attach() { +void View::Attach() +{ OnSwitchTo(); const float w = float(Gui::Screen::GetWidth()); @@ -38,10 +42,10 @@ void View::Attach() { Gui::Screen::AddBaseWidget(this, 0, 0); if (s_cpan) { - Gui::Screen::AddBaseWidget(s_cpan, 0, h-80); - Gui::Screen::AddBaseWidget(m_rightButtonBar, w-128, h-26); - Gui::Screen::AddBaseWidget(m_rightRegion2, w-128, h-68); - Gui::Screen::AddBaseWidget(m_rightRegion1, w-123, h-62); + Gui::Screen::AddBaseWidget(s_cpan, 0, h - 80); + Gui::Screen::AddBaseWidget(m_rightButtonBar, w - 128, h - 26); + Gui::Screen::AddBaseWidget(m_rightRegion2, w - 128, h - 68); + Gui::Screen::AddBaseWidget(m_rightRegion1, w - 123, h - 62); m_rightButtonBar->ShowAll(); m_rightRegion2->ShowAll(); @@ -51,7 +55,8 @@ void View::Attach() { ShowAll(); } -void View::Detach() { +void View::Detach() +{ Gui::Screen::RemoveBaseWidget(m_rightButtonBar); Gui::Screen::RemoveBaseWidget(m_rightRegion2); Gui::Screen::RemoveBaseWidget(m_rightRegion1); diff --git a/src/collider/BVHTree.cpp b/src/collider/BVHTree.cpp index 25fcdeb28..fa491fcb4 100644 --- a/src/collider/BVHTree.cpp +++ b/src/collider/BVHTree.cpp @@ -3,8 +3,8 @@ #include "BVHTree.h" #include "../buildopts.h" -#include #include +#include const int MAX_SPLITPOS_RETRIES = 15; @@ -15,15 +15,16 @@ BVHTree::BVHTree(int numObjs, const objPtr_t *objPtrs, const Aabb *objAabbs) timer.Start(); std::vector activeObjIdxs(numObjs); - for (int i=0; i3) Output("fat node %d\n", objs.size()); // copy tri indices to the stinking flat array - for (int i=numTris-1; i>=0; i--) { + for (int i = numTris - 1; i >= 0; i--) { m_objPtrAlloc[m_objPtrAllocPos++] = objPtrs[objs[i]]; } } void BVHTree::BuildNode(BVHNode *node, - const objPtr_t *objPtrs, - const Aabb *objAabbs, - std::vector &activeObjIdx) + const objPtr_t *objPtrs, + const Aabb *objAabbs, + std::vector &activeObjIdx) { const int numTris = activeObjIdx.size(); if (numTris <= 0) Error("BuildNode called with no elements in activeObjIndex."); @@ -70,7 +71,7 @@ void BVHTree::BuildNode(BVHNode *node, aabb.min = vector3d(FLT_MAX, FLT_MAX, FLT_MAX); aabb.max = vector3d(-FLT_MAX, -FLT_MAX, -FLT_MAX); - for (int i=0; i -#include -#include "../vector3.h" #include "../Aabb.h" #include "../utils.h" +#include "../vector3.h" +#include +#include struct BVHNode { Aabb aabb; @@ -20,11 +20,15 @@ struct BVHNode { BVHNode *kids[2]; - BVHNode() : numTris(0), triIndicesStart(nullptr) { + BVHNode() : + numTris(0), + triIndicesStart(nullptr) + { kids[0] = nullptr; kids[1] = nullptr; } - bool IsLeaf() const { + bool IsLeaf() const + { return triIndicesStart != nullptr; } }; @@ -33,18 +37,21 @@ class BVHTree { public: typedef int objPtr_t; BVHTree(const int numObjs, const objPtr_t *objPtrs, const Aabb *objAabbs); - ~BVHTree() { - delete [] m_objPtrAlloc; - delete [] m_bvhNodes; + ~BVHTree() + { + delete[] m_objPtrAlloc; + delete[] m_bvhNodes; } BVHNode *GetRoot() { return m_root; } + private: void BuildNode(BVHNode *node, - const objPtr_t *objPtrs, - const Aabb *objAabbs, - std::vector &activeObjIdxs); + const objPtr_t *objPtrs, + const Aabb *objAabbs, + std::vector &activeObjIdxs); void MakeLeaf(BVHNode *node, const objPtr_t *objPtrs, std::vector &objs); - BVHNode *AllocNode() { + BVHNode *AllocNode() + { if (m_nodeAllocPos >= m_nodeAllocMax) Error("Out of space in m_bvhNodes."); return &m_bvhNodes[m_nodeAllocPos++]; } diff --git a/src/collider/CollisionContact.h b/src/collider/CollisionContact.h index b0df7d4fe..6e911d530 100644 --- a/src/collider/CollisionContact.h +++ b/src/collider/CollisionContact.h @@ -4,6 +4,8 @@ #ifndef _COLLISION_CONTACT_H #define _COLLISION_CONTACT_H +#include "vector3.h" + struct CollisionContact { /* position and normal are in world (or rather, CollisionSpace) coordinates */ vector3d pos; @@ -13,8 +15,16 @@ struct CollisionContact { int triIdx; void *userData1, *userData2; int geomFlag; -// bool vsStatic; // true => object 2 was in static, else dynamic - CollisionContact() : depth(0), dist(0), triIdx(-1), userData1(nullptr), userData2(nullptr), geomFlag(0) { /*empty*/ } + // bool vsStatic; // true => object 2 was in static, else dynamic + CollisionContact() : + depth(0), + dist(0), + triIdx(-1), + userData1(nullptr), + userData2(nullptr), + geomFlag(0) + { /*empty*/ + } }; #endif /* _COLLISION_CONTACT_H */ diff --git a/src/collider/CollisionSpace.cpp b/src/collider/CollisionSpace.cpp index b51fd6c9c..ea8dd4492 100644 --- a/src/collider/CollisionSpace.cpp +++ b/src/collider/CollisionSpace.cpp @@ -2,9 +2,9 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "CollisionSpace.h" +#include "../libs.h" #include "Geom.h" #include "GeomTree.h" -#include "../libs.h" /* volnode!!!!!!!!!!! */ struct BvhNode { @@ -17,7 +17,8 @@ struct BvhNode { BvhNode *kids[2]; - BvhNode() { + BvhNode() + { kids[0] = 0; geomStart = 0; } @@ -26,24 +27,23 @@ struct BvhNode { { PROFILE_SCOPED() double - l1 = (aabb.min.x - start.x) * invDir.x, - l2 = (aabb.max.x - start.x) * invDir.x, - lmin = std::min(l1,l2), - lmax = std::max(l1,l2); + l1 = (aabb.min.x - start.x) * invDir.x, + l2 = (aabb.max.x - start.x) * invDir.x, + lmin = std::min(l1, l2), + lmax = std::max(l1, l2); - l1 = (aabb.min.y - start.y) * invDir.y; - l2 = (aabb.max.y - start.y) * invDir.y; - lmin = std::max(std::min(l1,l2), lmin); - lmax = std::min(std::max(l1,l2), lmax); + l1 = (aabb.min.y - start.y) * invDir.y; + l2 = (aabb.max.y - start.y) * invDir.y; + lmin = std::max(std::min(l1, l2), lmin); + lmax = std::min(std::max(l1, l2), lmax); - l1 = (aabb.min.z - start.z) * invDir.z; - l2 = (aabb.max.z - start.z) * invDir.z; - lmin = std::max(std::min(l1,l2), lmin); - lmax = std::min(std::max(l1,l2), lmax); + l1 = (aabb.min.z - start.z) * invDir.z; + l2 = (aabb.max.z - start.z) * invDir.z; + lmin = std::max(std::min(l1, l2), lmin); + lmax = std::min(std::max(l1, l2), lmax); return ((lmax >= 0.f) & (lmax >= lmin) & (lmin < isect->dist)); } - }; /* @@ -58,23 +58,25 @@ public: int m_nodesAllocPos; int m_nodesAllocMax; - BvhNode *AllocNode() { + BvhNode *AllocNode() + { assert(m_nodesAllocPos < m_nodesAllocMax); return &m_nodesAlloc[m_nodesAllocPos++]; } - BvhTree(const std::list &geoms); - ~BvhTree() { - if (m_geoms) delete [] m_geoms; - if (m_nodesAlloc) delete [] m_nodesAlloc; + BvhTree(const std::list &geoms); + ~BvhTree() + { + if (m_geoms) delete[] m_geoms; + if (m_nodesAlloc) delete[] m_nodesAlloc; } - void CollideGeom(Geom *, const Aabb &, int minMailboxValue, void (*callback)(CollisionContact*)); + void CollideGeom(Geom *, const Aabb &, int minMailboxValue, void (*callback)(CollisionContact *)); private: - void BuildNode(BvhNode *node, const std::list &a_geoms, int &outGeomPos); + void BuildNode(BvhNode *node, const std::list &a_geoms, int &outGeomPos); }; -BvhTree::BvhTree(const std::list &geoms) +BvhTree::BvhTree(const std::list &geoms) { PROFILE_SCOPED() m_geoms = 0; @@ -84,17 +86,17 @@ BvhTree::BvhTree(const std::list &geoms) m_root = 0; return; } - m_geoms = new Geom*[numGeoms]; + m_geoms = new Geom *[numGeoms]; int geomPos = 0; m_nodesAllocPos = 0; - m_nodesAllocMax = numGeoms*2; + m_nodesAllocMax = numGeoms * 2; m_nodesAlloc = new BvhNode[m_nodesAllocMax]; m_root = AllocNode(); BuildNode(m_root, geoms, geomPos); assert(geomPos == numGeoms); } -void BvhTree::CollideGeom(Geom *g, const Aabb &geomAabb, int minMailboxValue, void (*callback)(CollisionContact*)) +void BvhTree::CollideGeom(Geom *g, const Aabb &geomAabb, int minMailboxValue, void (*callback)(CollisionContact *)) { PROFILE_SCOPED() if (!m_root) return; @@ -110,7 +112,7 @@ void BvhTree::CollideGeom(Geom *g, const Aabb &geomAabb, int minMailboxValue, vo for (;;) { if (geomAabb.Intersects(node->aabb)) { if (node->geomStart) { - for (int i=0; inumGeoms; i++) { + for (int i = 0; i < node->numGeoms; i++) { Geom *g2 = node->geomStart[i]; if (!g2->IsEnabled()) continue; if (g2->GetMailboxIndex() < minMailboxValue) continue; @@ -118,12 +120,11 @@ void BvhTree::CollideGeom(Geom *g, const Aabb &geomAabb, int minMailboxValue, vo if (g->GetGroup() && g2->GetGroup() == g->GetGroup()) continue; double radius2 = g2->GetGeomTree()->GetRadius(); vector3d pos2 = g2->GetPosition(); - if ((pos-pos2).Length() <= (radius + radius2)) { + if ((pos - pos2).Length() <= (radius + radius2)) { g->Collide(g2, callback); } } - } - else if (node->kids[0]) { + } else if (node->kids[0]) { stack[++stackPos] = node->kids[0]; node = node->kids[1]; continue; @@ -135,7 +136,7 @@ void BvhTree::CollideGeom(Geom *g, const Aabb &geomAabb, int minMailboxValue, vo } } -void BvhTree::BuildNode(BvhNode *node, const std::list &a_geoms, int &outGeomPos) +void BvhTree::BuildNode(BvhNode *node, const std::list &a_geoms, int &outGeomPos) { PROFILE_SCOPED() const int numGeoms = a_geoms.size(); @@ -146,26 +147,29 @@ void BvhTree::BuildNode(BvhNode *node, const std::list &a_geoms, int &out aabb.min = vector3d(FLT_MAX, FLT_MAX, FLT_MAX); aabb.max = vector3d(-FLT_MAX, -FLT_MAX, -FLT_MAX); - for (std::list::const_iterator i = a_geoms.begin(); - i != a_geoms.end(); ++i) { + for (std::list::const_iterator i = a_geoms.begin(); + i != a_geoms.end(); ++i) { vector3d p = (*i)->GetPosition(); double rad = (*i)->GetGeomTree()->GetRadius(); - aabb.Update(p + vector3d(rad,rad,rad)); - aabb.Update(p - vector3d(rad,rad,rad)); + aabb.Update(p + vector3d(rad, rad, rad)); + aabb.Update(p - vector3d(rad, rad, rad)); } // divide by longest axis int axis; const vector3d axislen = aabb.max - aabb.min; - if ((axislen.x > axislen.y) && (axislen.x > axislen.z)) axis = 0; - else if (axislen.y > axislen.z) axis = 1; - else axis = 2; - const double pivot = 0.5*(aabb.max[axis] + aabb.min[axis]); + if ((axislen.x > axislen.y) && (axislen.x > axislen.z)) + axis = 0; + else if (axislen.y > axislen.z) + axis = 1; + else + axis = 2; + const double pivot = 0.5 * (aabb.max[axis] + aabb.min[axis]); - std::list side[2]; + std::list side[2]; - for (std::list::const_iterator i = a_geoms.begin(); - i != a_geoms.end(); ++i) { + for (std::list::const_iterator i = a_geoms.begin(); + i != a_geoms.end(); ++i) { if ((*i)->GetPosition()[axis] < pivot) { side[0].push_back(*i); } else { @@ -181,8 +185,8 @@ void BvhTree::BuildNode(BvhNode *node, const std::list &a_geoms, int &out node->geomStart = &m_geoms[outGeomPos]; // copy geoms to the stinking flat array - for (std::list::const_iterator i = a_geoms.begin(); - i != a_geoms.end(); ++i) { + for (std::list::const_iterator i = a_geoms.begin(); + i != a_geoms.end(); ++i) { m_geoms[outGeomPos++] = *i; } } else { @@ -249,7 +253,7 @@ void CollisionSpace::CollideRaySphere(const vector3d &start, const vector3d &dir /* Collide with lovely sphere! */ const vector3d v = start - sphere.pos; const double b = -v.Dot(dir); - double det = (b * b) - v.LengthSqr() + (sphere.radius*sphere.radius); + double det = (b * b) - v.LengthSqr() + (sphere.radius * sphere.radius); if (det > 0) { det = sqrt(det); const double i1 = b - det; @@ -276,14 +280,14 @@ void CollisionSpace::CollideRaySphere(const vector3d &start, const vector3d &dir void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, double len, CollisionContact *c, const Geom *ignore /*= nullptr*/) { PROFILE_SCOPED() - vector3d invDir(1.0/dir.x, 1.0/dir.y, 1.0/dir.z); + vector3d invDir(1.0 / dir.x, 1.0 / dir.y, 1.0 / dir.z); c->dist = len; BvhNode *vn_stack[16]; BvhNode *node = m_staticObjectTree->m_root; int stackPos = -1; - for (;node;) { + for (; node;) { // do we hit it? { isect_t isect; @@ -295,7 +299,7 @@ void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, double if (node->geomStart) { // it is a leaf node // collide with all geoms - for (int i=0; inumGeoms; i++) { + for (int i = 0; i < node->numGeoms; i++) { Geom *g = node->geomStart[i]; const matrix4x4d &invTrans = g->GetInvTransform(); @@ -309,7 +313,7 @@ void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, double isect.triIdx = -1; g->GetGeomTree()->TraceRay(modelStart, modelDir, &isect); if (isect.triIdx != -1) { - c->pos = start + dir*double(isect.dist); + c->pos = start + dir * double(isect.dist); vector3f n = g->GetGeomTree()->GetTriNormal(isect.triIdx); c->normal = vector3d(n.x, n.y, n.z); @@ -328,12 +332,12 @@ void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, double node = node->kids[1]; continue; } -pop_jizz: + pop_jizz: if (stackPos < 0) break; node = vn_stack[stackPos--]; } - for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) { + for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) { if ((*i) == ignore) continue; if ((*i)->IsEnabled()) { const matrix4x4d &invTrans = (*i)->GetInvTransform(); @@ -347,7 +351,7 @@ pop_jizz: isect.triIdx = -1; (*i)->GetGeomTree()->TraceRay(modelStart, modelDir, &isect); if (isect.triIdx != -1) { - c->pos = start + dir*double(isect.dist); + c->pos = start + dir * double(isect.dist); vector3f n = (*i)->GetGeomTree()->GetTriNormal(isect.triIdx); c->normal = vector3d(n.x, n.y, n.z); @@ -368,7 +372,7 @@ pop_jizz: isect.triIdx = -1; CollideRaySphere(start, dir, &isect); if (isect.triIdx != -1) { - c->pos = start + dir*double(isect.dist); + c->pos = start + dir * double(isect.dist); c->normal = vector3d(0.0); c->depth = len - isect.dist; c->triIdx = -1; @@ -382,7 +386,7 @@ pop_jizz: /* * Do not collide objects with mailbox value < minMailboxValue */ -void CollisionSpace::CollideGeoms(Geom *a, int minMailboxValue, void (*callback)(CollisionContact*)) +void CollisionSpace::CollideGeoms(Geom *a, int minMailboxValue, void (*callback)(CollisionContact *)) { PROFILE_SCOPED() if (!a->IsEnabled()) return; @@ -400,7 +404,6 @@ void CollisionSpace::CollideGeoms(Geom *a, int minMailboxValue, void (*callback) if (sphere.radius > 0.0) { a->CollideSphere(sphere, callback); } - } void CollisionSpace::RebuildObjectTrees() @@ -416,20 +419,20 @@ void CollisionSpace::RebuildObjectTrees() m_needStaticGeomRebuild = false; } -void CollisionSpace::Collide(void (*callback)(CollisionContact*)) +void CollisionSpace::Collide(void (*callback)(CollisionContact *)) { PROFILE_SCOPED() RebuildObjectTrees(); int mailboxMin = 0; - for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) { + for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) { (*i)->SetMailboxIndex(mailboxMin++); } /* This mailbox nonsense is so: after collision(a,b), we will not * attempt collision(b,a) */ mailboxMin = 1; - for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i, mailboxMin++) { + for (std::list::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i, mailboxMin++) { CollideGeoms(*i, mailboxMin, callback); } } diff --git a/src/collider/CollisionSpace.h b/src/collider/CollisionSpace.h index 13ad3f52e..56d673478 100644 --- a/src/collider/CollisionSpace.h +++ b/src/collider/CollisionSpace.h @@ -4,8 +4,8 @@ #ifndef _COLLISION_SPACE #define _COLLISION_SPACE -#include #include "../vector3.h" +#include class Geom; struct isect_t; @@ -26,14 +26,17 @@ class CollisionSpace { public: CollisionSpace(); ~CollisionSpace(); - void AddGeom(Geom*); - void RemoveGeom(Geom*); - void AddStaticGeom(Geom*); - void RemoveStaticGeom(Geom*); + void AddGeom(Geom *); + void RemoveGeom(Geom *); + void AddStaticGeom(Geom *); + void RemoveStaticGeom(Geom *); void TraceRay(const vector3d &start, const vector3d &dir, double len, CollisionContact *c, const Geom *ignore = nullptr); - void Collide(void (*callback)(CollisionContact*)); - void SetSphere(const vector3d &pos, double radius, void *user_data) { - sphere.pos = pos; sphere.radius = radius; sphere.userData = user_data; + void Collide(void (*callback)(CollisionContact *)); + void SetSphere(const vector3d &pos, double radius, void *user_data) + { + sphere.pos = pos; + sphere.radius = radius; + sphere.userData = user_data; } void FlagRebuildObjectTrees() { m_needStaticGeomRebuild = true; } void RebuildObjectTrees(); @@ -42,12 +45,17 @@ public: // should be used for geoms that are part of the same body // could also be used for autopiloted groups and LRCs near stations // zero means ungrouped. assumes that wraparound => no old crap left - static int GetGroupHandle() { if(!s_nextHandle) s_nextHandle++; return s_nextHandle++; } + static int GetGroupHandle() + { + if (!s_nextHandle) s_nextHandle++; + return s_nextHandle++; + } + private: - void CollideGeoms(Geom *a, int minMailboxValue, void (*callback)(CollisionContact*)); + void CollideGeoms(Geom *a, int minMailboxValue, void (*callback)(CollisionContact *)); void CollideRaySphere(const vector3d &start, const vector3d &dir, isect_t *isect); - std::list m_geoms; - std::list m_staticGeoms; + std::list m_geoms; + std::list m_staticGeoms; bool m_needStaticGeomRebuild; BvhTree *m_staticObjectTree; BvhTree *m_dynamicObjectTree; diff --git a/src/collider/Geom.cpp b/src/collider/Geom.cpp index 6634e2ee5..ab3427ed8 100644 --- a/src/collider/Geom.cpp +++ b/src/collider/Geom.cpp @@ -1,11 +1,11 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include #include "Geom.h" +#include "BVHTree.h" #include "GeomTree.h" #include "collider.h" -#include "BVHTree.h" +#include static const unsigned int MAX_CONTACTS = 8; @@ -47,7 +47,7 @@ void Geom::MoveTo(const matrix4x4d &m, const vector3d &pos) m_invOrient = m_orient.Inverse(); } -void Geom::CollideSphere(Sphere &sphere, void (*callback)(CollisionContact*)) const +void Geom::CollideSphere(Sphere &sphere, void (*callback)(CollisionContact *)) const { PROFILE_SCOPED() /* if the geom is actually within the sphere, create a contact so @@ -57,7 +57,7 @@ void Geom::CollideSphere(Sphere &sphere, void (*callback)(CollisionContact*)) co const double len = v.Length(); if (len < sphere.radius) { contact.pos = GetPosition(); - contact.normal = (1.0/len)*v; + contact.normal = (1.0 / len) * v; contact.depth = sphere.radius - len; contact.triIdx = 0; contact.userData1 = this->m_data; @@ -72,7 +72,7 @@ void Geom::CollideSphere(Sphere &sphere, void (*callback)(CollisionContact*)) co * This geom has moved, causing a possible collision with geom b. * Collide meshes to see. */ -void Geom::Collide(Geom *b, void (*callback)(CollisionContact*)) const +void Geom::Collide(Geom *b, void (*callback)(CollisionContact *)) const { PROFILE_SCOPED() int max_contacts = MAX_CONTACTS; @@ -88,9 +88,9 @@ void Geom::Collide(Geom *b, void (*callback)(CollisionContact*)) const b->CollideEdgesWithTrisOf(max_contacts, this, transTo, callback); } -// t = SDL_GetTicks() - t; -// int numEdges = GetGeomTree()->GetNumEdges() + b->GetGeomTree()->GetNumEdges(); -// Output("%d 'rays' in %dms (%f rps)\n", numEdges, t, 1000.0*numEdges / (double)t); + // t = SDL_GetTicks() - t; + // int numEdges = GetGeomTree()->GetNumEdges() + b->GetGeomTree()->GetNumEdges(); + // Output("%d 'rays' in %dms (%f rps)\n", numEdges, t, 1000.0*numEdges / (double)t); } static bool rotatedAabbIsectsNormalOne(Aabb &a, const matrix4x4d &transA, Aabb &b) @@ -107,7 +107,8 @@ static bool rotatedAabbIsectsNormalOne(Aabb &a, const matrix4x4d &transA, Aabb & p[6] = transA * vector3d(a.max.x, a.max.y, a.min.z); p[7] = transA * vector3d(a.max.x, a.max.y, a.max.z); arot.min = arot.max = p[0]; - for (int i=1; i<8; i++) arot.Update(p[i]); + for (int i = 1; i < 8; i++) + arot.Update(p[i]); return b.Intersects(arot); } @@ -115,7 +116,7 @@ static bool rotatedAabbIsectsNormalOne(Aabb &a, const matrix4x4d &transA, Aabb & * Intersect this Geom's edge BVH tree with geom b's triangle BVH tree. * Generate collision contacts. */ -void Geom::CollideEdgesWithTrisOf(int &maxContacts, const Geom *b, const matrix4x4d &transTo, void (*callback)(CollisionContact*)) const +void Geom::CollideEdgesWithTrisOf(int &maxContacts, const Geom *b, const matrix4x4d &transTo, void (*callback)(CollisionContact *)) const { PROFILE_SCOPED() struct stackobj { @@ -177,7 +178,7 @@ void Geom::CollideEdgesWithTrisOf(int &maxContacts, const Geom *b, const matrix4 * BVH of another geom (b), starting from btriNode. */ void Geom::CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const matrix4x4d &transToB, - const Geom *b, const BVHNode *btriNode, void (*callback)(CollisionContact*)) const + const Geom *b, const BVHNode *btriNode, void (*callback)(CollisionContact *)) const { PROFILE_SCOPED() if (maxContacts <= 0) return; @@ -187,28 +188,28 @@ void Geom::CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const mat vector3f dir; isect_t isect; const std::vector &rVertices = GetGeomTree()->GetVertices(); - for (int i=0; inumTris; i++) { - const int vtxNum = edges[ edgeNode->triIndicesStart[i] ].v1i; + for (int i = 0; i < edgeNode->numTris; i++) { + const int vtxNum = edges[edgeNode->triIndicesStart[i]].v1i; const vector3d v1 = transToB * vector3d(rVertices[vtxNum]); const vector3f _from(float(v1.x), float(v1.y), float(v1.z)); vector3d _dir( - double(edges[ edgeNode->triIndicesStart[i] ].dir.x), - double(edges[ edgeNode->triIndicesStart[i] ].dir.y), - double(edges[ edgeNode->triIndicesStart[i] ].dir.z)); + double(edges[edgeNode->triIndicesStart[i]].dir.x), + double(edges[edgeNode->triIndicesStart[i]].dir.y), + double(edges[edgeNode->triIndicesStart[i]].dir.z)); _dir = transToB.ApplyRotationOnly(_dir); dir = vector3f(&_dir.x); - isect.dist = edges[ edgeNode->triIndicesStart[i] ].len; + isect.dist = edges[edgeNode->triIndicesStart[i]].len; isect.triIdx = -1; b->GetGeomTree()->TraceRay(btriNode, _from, dir, &isect); if (isect.triIdx == -1) continue; numContacts++; - const double depth = edges[ edgeNode->triIndicesStart[i] ].len - isect.dist; + const double depth = edges[edgeNode->triIndicesStart[i]].len - isect.dist; // in world coords CollisionContact contact; - contact.pos = b->GetTransform() * (v1 + vector3d(&dir.x)*double(isect.dist)); + contact.pos = b->GetTransform() * (v1 + vector3d(&dir.x) * double(isect.dist)); vector3f n = b->m_geomtree->GetTriNormal(isect.triIdx); contact.normal = vector3d(n.x, n.y, n.z); contact.normal = b->GetTransform().ApplyRotationOnly(contact.normal); @@ -220,7 +221,7 @@ void Geom::CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const mat contact.userData2 = b->m_data; // contact geomFlag is bitwise OR of triangle's and edge's flags contact.geomFlag = b->m_geomtree->GetTriFlag(isect.triIdx) | - edges[ edgeNode->triIndicesStart[i] ].triFlag; + edges[edgeNode->triIndicesStart[i]].triFlag; callback(&contact); if (--maxContacts <= 0) return; } @@ -229,4 +230,3 @@ void Geom::CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const mat CollideEdgesTris(maxContacts, edgeNode->kids[1], transToB, b, btriNode, callback); } } - diff --git a/src/collider/Geom.h b/src/collider/Geom.h index 267815c8e..d34d796cf 100644 --- a/src/collider/Geom.h +++ b/src/collider/Geom.h @@ -21,14 +21,14 @@ public: inline const matrix4x4d &GetInvTransform() const { return m_invOrient; } inline const matrix4x4d &GetTransform() const { return m_orient; } //matrix4x4d GetRotation() const; - inline const vector3d& GetPosition() const { return m_pos; } + inline const vector3d &GetPosition() const { return m_pos; } inline void Enable() { m_active = true; } inline void Disable() { m_active = false; } inline bool IsEnabled() const { return m_active; } - inline const GeomTree* GetGeomTree() const { return m_geomtree; } - void Collide(Geom *b, void (*callback)(CollisionContact*)) const; - void CollideSphere(Sphere &sphere, void (*callback)(CollisionContact*)) const; - inline void* GetUserData() const { return m_data; } + inline const GeomTree *GetGeomTree() const { return m_geomtree; } + void Collide(Geom *b, void (*callback)(CollisionContact *)) const; + void CollideSphere(Sphere &sphere, void (*callback)(CollisionContact *)) const; + inline void *GetUserData() const { return m_data; } inline void SetMailboxIndex(int idx) { m_mailboxIndex = idx; } inline int GetMailboxIndex() const { return m_mailboxIndex; } inline void SetGroup(int g) { m_group = g; } @@ -37,10 +37,10 @@ public: matrix4x4d m_animTransform; private: - void CollideEdgesWithTrisOf(int &maxContacts, const Geom *b, const matrix4x4d &transTo, void (*callback)(CollisionContact*)) const; + void CollideEdgesWithTrisOf(int &maxContacts, const Geom *b, const matrix4x4d &transTo, void (*callback)(CollisionContact *)) const; void CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const matrix4x4d &transToB, - const Geom *b, const BVHNode *btriNode, void (*callback)(CollisionContact*)) const; - + const Geom *b, const BVHNode *btriNode, void (*callback)(CollisionContact *)) const; + // double-buffer position so we can keep previous position matrix4x4d m_orient, m_invOrient; vector3d m_pos; diff --git a/src/collider/GeomTree.cpp b/src/collider/GeomTree.cpp index 11c676cdd..7f833d745 100644 --- a/src/collider/GeomTree.cpp +++ b/src/collider/GeomTree.cpp @@ -1,8 +1,8 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "../libs.h" #include "GeomTree.h" +#include "../libs.h" #include "BVHTree.h" #include "Weld.h" @@ -10,10 +10,10 @@ GeomTree::~GeomTree() { } -GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector &vertices, const Uint32 *indices, const Uint32 *triflags) -: m_numVertices(numVerts) -, m_numTris(numTris) -, m_vertices(vertices) +GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector &vertices, const Uint32 *indices, const Uint32 *triflags) : + m_numVertices(numVerts), + m_numTris(numTris), + m_vertices(vertices) { PROFILE_SCOPED() assert(static_cast(vertices.size()) == m_numVertices); @@ -31,22 +31,23 @@ GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector activeTris; activeTris.reserve(numTris); - for (int i=0; i, int > EdgeType; + typedef std::map, int> EdgeType; EdgeType edges; -#define ADD_EDGE(_i1,_i2,_triflag) \ - if ((_i1) < (_i2)) edges[std::pair(_i1,_i2)] = _triflag; \ - else if ((_i1) > (_i2)) edges[std::pair(_i2,_i1)] = _triflag; +#define ADD_EDGE(_i1, _i2, _triflag) \ + if ((_i1) < (_i2)) \ + edges[std::pair(_i1, _i2)] = _triflag; \ + else if ((_i1) > (_i2)) \ + edges[std::pair(_i2, _i1)] = _triflag; // eliminate duplicate vertices { @@ -59,23 +60,21 @@ GeomTree::GeomTree(const int numVerts, const int numTris, const std::vectorm_radius) m_radius = rad; + for (int j = 0; j < 3; j++) { + const double rad = v[j].x * v[j].x + v[j].y * v[j].y + v[j].z * v[j].z; + if (rad > m_radius) m_radius = rad; } } m_radius = sqrt(m_radius); { Aabb *aabbs = new Aabb[activeTris.size()]; - for (Uint32 i = 0; i < activeTris.size(); i++) - { + for (Uint32 i = 0; i < activeTris.size(); i++) { const vector3d v1 = vector3d(m_vertices[m_indices[activeTris[i] + 0]]); const vector3d v2 = vector3d(m_vertices[m_indices[activeTris[i] + 1]]); const vector3d v3 = vector3d(m_vertices[m_indices[activeTris[i] + 2]]); @@ -114,23 +112,22 @@ GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector &vtx = (*i).first; const int triflag = (*i).second; const vector3f &v1 = m_vertices[vtx.first]; const vector3f &v2 = m_vertices[vtx.second]; - vector3f dir = (v2-v1); + vector3f dir = (v2 - v1); const float len = dir.Length(); - dir *= 1.0f/len; + dir *= 1.0f / len; m_edges[pos].v1i = vtx.first; m_edges[pos].v2i = vtx.second; @@ -145,7 +142,7 @@ GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector activeTris; activeTris.reserve(m_numTris); - for (int i = 0; iaabb.min.x - start.x) * invDir.x, - l2 = (n->aabb.max.x - start.x) * invDir.x, - lmin = std::min(l1,l2), - lmax = std::max(l1,l2); + l1 = (n->aabb.min.x - start.x) * invDir.x, + l2 = (n->aabb.max.x - start.x) * invDir.x, + lmin = std::min(l1, l2), + lmax = std::max(l1, l2); - l1 = (n->aabb.min.y - start.y) * invDir.y; - l2 = (n->aabb.max.y - start.y) * invDir.y; - lmin = std::max(std::min(l1,l2), lmin); - lmax = std::min(std::max(l1,l2), lmax); + l1 = (n->aabb.min.y - start.y) * invDir.y; + l2 = (n->aabb.max.y - start.y) * invDir.y; + lmin = std::max(std::min(l1, l2), lmin); + lmax = std::min(std::max(l1, l2), lmax); - l1 = (n->aabb.min.z - start.z) * invDir.z; - l2 = (n->aabb.max.z - start.z) * invDir.z; - lmin = std::max(std::min(l1,l2), lmin); - lmax = std::min(std::max(l1,l2), lmax); + l1 = (n->aabb.min.z - start.z) * invDir.z; + l2 = (n->aabb.max.z - start.z) * invDir.z; + lmin = std::max(std::min(l1, l2), lmin); + lmax = std::min(std::max(l1, l2), lmax); return ((lmax >= 0.f) & (lmax >= lmin) & (lmin < isect->dist)); } @@ -271,10 +266,10 @@ void GeomTree::TraceRay(const BVHNode *currnode, const vector3f &a_origin, const currnode = currnode->kids[0]; } // triangle intersection jizz - for (int i=0; inumTris; i++) { + for (int i = 0; i < currnode->numTris; i++) { RayTriIntersect(1, a_origin, &a_dir, currnode->triIndicesStart[i], isect); } -pop_bstack: + pop_bstack: if (stackpos < 0) break; currnode = stack[stackpos]; stackpos--; @@ -284,28 +279,28 @@ pop_bstack: void GeomTree::RayTriIntersect(int numRays, const vector3f &origin, const vector3f *dirs, int triIdx, isect_t *isects) const { PROFILE_SCOPED() - const vector3f a(m_vertices[m_indices[triIdx+0]]); - const vector3f b(m_vertices[m_indices[triIdx+1]]); - const vector3f c(m_vertices[m_indices[triIdx+2]]); + const vector3f a(m_vertices[m_indices[triIdx + 0]]); + const vector3f b(m_vertices[m_indices[triIdx + 1]]); + const vector3f c(m_vertices[m_indices[triIdx + 2]]); - const vector3f n = (c-a).Cross(b-a); - const float nominator = n.Dot(a-origin); + const vector3f n = (c - a).Cross(b - a); + const float nominator = n.Dot(a - origin); - const vector3f v0_cross((c-origin).Cross(b-origin)); - const vector3f v1_cross((b-origin).Cross(a-origin)); - const vector3f v2_cross((a-origin).Cross(c-origin)); + const vector3f v0_cross((c - origin).Cross(b - origin)); + const vector3f v1_cross((b - origin).Cross(a - origin)); + const vector3f v2_cross((a - origin).Cross(c - origin)); - for (int i=0; i 0) && (v1d > 0) && (v2d > 0)) || - ((v0d < 0) && (v1d < 0) && (v2d < 0)) ) { + if (((v0d > 0) && (v1d > 0) && (v2d > 0)) || + ((v0d < 0) && (v1d < 0) && (v2d < 0))) { const float dist = nominator / dirs[i].Dot(n); if ((dist > 0) && (dist < isects[i].dist)) { isects[i].dist = dist; - isects[i].triIdx = triIdx/3; + isects[i].triIdx = triIdx / 3; } } } @@ -314,11 +309,11 @@ void GeomTree::RayTriIntersect(int numRays, const vector3f &origin, const vector vector3f GeomTree::GetTriNormal(int triIdx) const { PROFILE_SCOPED() - const vector3f a(m_vertices[m_indices[3*triIdx+0]]); - const vector3f b(m_vertices[m_indices[3*triIdx+1]]); - const vector3f c(m_vertices[m_indices[3*triIdx+2]]); + const vector3f a(m_vertices[m_indices[3 * triIdx + 0]]); + const vector3f b(m_vertices[m_indices[3 * triIdx + 1]]); + const vector3f c(m_vertices[m_indices[3 * triIdx + 2]]); - return (b-a).Cross(c-a).Normalized(); + return (b - a).Cross(c - a).Normalized(); } void GeomTree::Save(Serializer::Writer &wr) const diff --git a/src/collider/GeomTree.h b/src/collider/GeomTree.h index a4650788b..fb87f58a3 100644 --- a/src/collider/GeomTree.h +++ b/src/collider/GeomTree.h @@ -4,9 +4,9 @@ #ifndef _GEOMTREE_H #define _GEOMTREE_H -#include "libs.h" #include "CollisionContact.h" #include "Serializer.h" +#include "libs.h" struct isect_t { // triIdx = -1 if no intersection @@ -62,10 +62,10 @@ public: const Edge *GetEdges() const { return &m_edges[0]; } int GetNumEdges() const { return m_numEdges; } - BVHTree* GetTriTree() const { return m_triTree.get(); } - BVHTree* GetEdgeTree() const { return m_edgeTree.get(); } + BVHTree *GetTriTree() const { return m_triTree.get(); } + BVHTree *GetEdgeTree() const { return m_edgeTree.get(); } - const std::vector& GetVertices() const { return m_vertices; } + const std::vector &GetVertices() const { return m_vertices; } const Uint32 *GetIndices() const { return &m_indices[0]; } const Uint32 *GetTriFlags() const { return &m_triFlags[0]; } int GetNumVertices() const { return m_numVertices; } diff --git a/src/collider/Weld.h b/src/collider/Weld.h index 001b3109c..a8d331ebc 100644 --- a/src/collider/Weld.h +++ b/src/collider/Weld.h @@ -7,142 +7,137 @@ // Weld function to remove array duplicates in linear time using hashing. -namespace nv -{ +namespace nv { -template struct Equal -{ - bool operator()(const T & a, const T & b) const - { - return a == b; - } -}; + template + struct Equal { + bool operator()(const T &a, const T &b) const + { + return a == b; + } + }; /// Null index. @@ Move this somewhere else... This could have collisions with other definitions! #define NIL Uint32(~0) -template struct hash -{ - inline Uint32 sdbm_hash(const void * data_in, Uint32 size, Uint32 h = 5381) - { - const Uint8 * data = static_cast(data_in); - Uint32 i = 0; - while (i < size) { - h = (h << 16) + (h << 6) - h + static_cast(data[i++]); + template + struct hash { + inline Uint32 sdbm_hash(const void *data_in, Uint32 size, Uint32 h = 5381) + { + const Uint8 *data = static_cast(data_in); + Uint32 i = 0; + while (i < size) { + h = (h << 16) + (h << 6) - h + static_cast(data[i++]); + } + return h; } - return h; - } - Uint32 operator()(const Key & k) { - return sdbm_hash(&k, sizeof(Key)); - } -}; -template <> struct hash -{ - Uint32 operator()(int x) const { return x; } -}; -template <> struct hash -{ - Uint32 operator()(Uint32 x) const { return x; } -}; + Uint32 operator()(const Key &k) + { + return sdbm_hash(&k, sizeof(Key)); + } + }; + template <> + struct hash { + Uint32 operator()(int x) const { return x; } + }; + template <> + struct hash { + Uint32 operator()(Uint32 x) const { return x; } + }; -/** Return the next power of two. + /** Return the next power of two. * @see http://graphics.stanford.edu/~seander/bithacks.html * @warning Behaviour for 0 is undefined. * @note isPowerOfTwo(x) == true -> nextPowerOfTwo(x) == x * @note nextPowerOfTwo(x) = 2 << log2(x-1) */ -inline Uint32 nextPowerOfTwo( Uint32 x ) -{ - assert( x != 0 ); -#if 1 // On modern CPUs this is supposed to be as fast as using the bsr instruction. - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return x+1; -#else - Uint32 p = 1; - while( x > p ) { - p += p; - } - return p; -#endif -} - -/// Return true if @a n is a power of two. -inline bool isPowerOfTwo( Uint32 n ) -{ - return (n & (n-1)) == 0; -} - - -/// Generic welding routine. This function welds the elements of the array p -/// and returns the cross references in the xrefs array. To compare the elements -/// it uses the given hash and equal functors. -/// -/// This code is based on the ideas of Ville Miettinen and Pierre Terdiman. -template , class E=Equal > -struct Weld -{ - // xrefs maps old elements to new elements - Uint32 operator()(std::vector & p, std::vector & xrefs) + inline Uint32 nextPowerOfTwo(Uint32 x) { - const Uint32 N = p.size(); // # of input vertices. - Uint32 outputCount = 0; // # of output vertices - Uint32 hashSize = nextPowerOfTwo(N); // size of the hash table - Uint32 * hashTable = new Uint32[hashSize + N]; // hash table + linked list - Uint32 * next = hashTable + hashSize; // use bottom part as linked list - - xrefs.resize(N); - memset( hashTable, NIL, (hashSize + N)*sizeof(Uint32) ); // init hash table (NIL = 0xFFFFFFFF so memset works) - - H hash; - E equal; - for (Uint32 i = 0; i < N; i++) - { - const T & e = p[i]; - const Uint32 hashValue = hash(e) & (hashSize-1); - //const Uint32 hashValue = CodeSupHash(e) & (hashSize-1); - Uint32 offset = hashTable[hashValue]; - - // traverse linked list - while( offset != NIL && !equal(p[offset], e) ) - { - offset = next[offset]; - } - - xrefs[i] = offset; - - // no match found - copy vertex & add to hash - if( offset == NIL ) - { - // save xref - xrefs[i] = outputCount; - - // copy element - p[outputCount] = e; - - // link to hash table - next[outputCount] = hashTable[hashValue]; - - // update hash heads and increase output counter - hashTable[hashValue] = outputCount++; - } + assert(x != 0); +#if 1 // On modern CPUs this is supposed to be as fast as using the bsr instruction. + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return x + 1; +#else + Uint32 p = 1; + while (x > p) { + p += p; } - - // cleanup - delete [] hashTable; - - p.resize(outputCount); - - // number of output vertices - return outputCount; + return p; +#endif } -}; -} // nv namespace + /// Return true if @a n is a power of two. + inline bool isPowerOfTwo(Uint32 n) + { + return (n & (n - 1)) == 0; + } + + /// Generic welding routine. This function welds the elements of the array p + /// and returns the cross references in the xrefs array. To compare the elements + /// it uses the given hash and equal functors. + /// + /// This code is based on the ideas of Ville Miettinen and Pierre Terdiman. + template , class E = Equal> + struct Weld { + // xrefs maps old elements to new elements + Uint32 operator()(std::vector &p, std::vector &xrefs) + { + const Uint32 N = p.size(); // # of input vertices. + Uint32 outputCount = 0; // # of output vertices + Uint32 hashSize = nextPowerOfTwo(N); // size of the hash table + Uint32 *hashTable = new Uint32[hashSize + N]; // hash table + linked list + Uint32 *next = hashTable + hashSize; // use bottom part as linked list + + xrefs.resize(N); + memset(hashTable, NIL, (hashSize + N) * sizeof(Uint32)); // init hash table (NIL = 0xFFFFFFFF so memset works) + + H hash; + E equal; + for (Uint32 i = 0; i < N; i++) { + const T &e = p[i]; + const Uint32 hashValue = hash(e) & (hashSize - 1); + //const Uint32 hashValue = CodeSupHash(e) & (hashSize-1); + Uint32 offset = hashTable[hashValue]; + + // traverse linked list + while (offset != NIL && !equal(p[offset], e)) { + offset = next[offset]; + } + + xrefs[i] = offset; + + // no match found - copy vertex & add to hash + if (offset == NIL) { + // save xref + xrefs[i] = outputCount; + + // copy element + p[outputCount] = e; + + // link to hash table + next[outputCount] = hashTable[hashValue]; + + // update hash heads and increase output counter + hashTable[hashValue] = outputCount++; + } + } + + // cleanup + delete[] hashTable; + + p.resize(outputCount); + + // number of output vertices + return outputCount; + } + }; + +} // namespace nv #endif // NV_MESH_WELD_H diff --git a/src/collider/collider.h b/src/collider/collider.h index 270898ea8..e5a0ecaee 100644 --- a/src/collider/collider.h +++ b/src/collider/collider.h @@ -5,9 +5,9 @@ #define _COLLISION_H #include "../vector3.h" -#include "GeomTree.h" +#include "CollisionContact.h" #include "CollisionSpace.h" #include "Geom.h" -#include "CollisionContact.h" +#include "GeomTree.h" #endif /* _COLLISION_H */ diff --git a/src/enum_table.h b/src/enum_table.h index d48625fc2..8cf9e3c01 100644 --- a/src/enum_table.h +++ b/src/enum_table.h @@ -7,8 +7,14 @@ /* THIS FILE IS AUTO-GENERATED, CHANGES WILL BE OVERWRITTEN */ /* enum table generated by scan_enums.py */ -struct EnumItem { const char *name; int value; }; -struct EnumTable { const char *name; const EnumItem *first; }; +struct EnumItem { + const char *name; + int value; +}; +struct EnumTable { + const char *name; + const EnumItem *first; +}; extern const struct EnumItem ENUM_ShipAIError[]; extern const struct EnumItem ENUM_DetailLevel[]; diff --git a/src/fixed.h b/src/fixed.h index 8155eebb9..6e375dff7 100644 --- a/src/fixed.h +++ b/src/fixed.h @@ -11,54 +11,98 @@ template class fixedf { public: static const int FRAC = FRAC_BITS; - static const Uint64 MASK = (Uint64(1UL)< -// fixedf(fixedf f) { *this = f; } - fixedf(Sint64 raw): v(raw) {} - fixedf(Sint64 num, Sint64 denom): v((num< + // fixedf(fixedf f) { *this = f; } + fixedf(Sint64 raw) : + v(raw) {} + fixedf(Sint64 num, Sint64 denom) : + v((num << FRAC) / denom) {} // ^^ this is fucking shit fixedf Abs() const { return fixedf(v >= 0 ? v : -v); } - friend fixedf operator+(const fixedf &a, const Sint64 b) { return a+fixedf(b<=(const fixedf &a, const Sint64 b) { return a >= fixedf(b<=(const Sint64 a, const fixedf &b) { return b >= fixedf(a<(const fixedf &a, const Sint64 b) { return a > fixedf(b<(const Sint64 a, const fixedf &b) { return b > fixedf(a<=(const fixedf &a, const Sint64 b) { return a >= fixedf(b << FRAC); } + friend bool operator>=(const Sint64 a, const fixedf &b) { return b >= fixedf(a << FRAC); } + friend bool operator<=(const fixedf &a, const Sint64 b) { return a <= fixedf(b << FRAC); } + friend bool operator<=(const Sint64 a, const fixedf &b) { return b <= fixedf(a << FRAC); } + friend bool operator>(const fixedf &a, const Sint64 b) { return a > fixedf(b << FRAC); } + friend bool operator>(const Sint64 a, const fixedf &b) { return b > fixedf(a << FRAC); } + friend bool operator<(const fixedf &a, const Sint64 b) { return a < fixedf(b << FRAC); } + friend bool operator<(const Sint64 a, const fixedf &b) { return b < fixedf(a << FRAC); } friend fixedf operator>>(const fixedf &a, const int b) { return fixedf(a.v >> b); } friend fixedf operator<<(const fixedf &a, const int b) { return fixedf(a.v << b); } - fixedf &operator*=(const fixedf &a) { (*this) = (*this)*a; return (*this); } - fixedf &operator*=(const Sint64 a) { (*this) = (*this)*a; return (*this); } - fixedf &operator/=(const fixedf &a) { (*this) = (*this)/a; return (*this); } - fixedf &operator/=(const Sint64 a) { (*this) = (*this)/a; return (*this); } - fixedf &operator+=(const fixedf &a) { (*this) = (*this)+a; return (*this); } - fixedf &operator+=(const Sint64 a) { (*this) = (*this)+a; return (*this); } - fixedf &operator-=(const fixedf &a) { (*this) = (*this)-a; return (*this); } - fixedf &operator-=(const Sint64 a) { (*this) = (*this)-a; return (*this); } - fixedf &operator>>=(const int a) { v >>= a; return (*this); } - fixedf &operator<<=(const int a) { v <<= a; return (*this); } + fixedf &operator*=(const fixedf &a) + { + (*this) = (*this) * a; + return (*this); + } + fixedf &operator*=(const Sint64 a) + { + (*this) = (*this) * a; + return (*this); + } + fixedf &operator/=(const fixedf &a) + { + (*this) = (*this) / a; + return (*this); + } + fixedf &operator/=(const Sint64 a) + { + (*this) = (*this) / a; + return (*this); + } + fixedf &operator+=(const fixedf &a) + { + (*this) = (*this) + a; + return (*this); + } + fixedf &operator+=(const Sint64 a) + { + (*this) = (*this) + a; + return (*this); + } + fixedf &operator-=(const fixedf &a) + { + (*this) = (*this) - a; + return (*this); + } + fixedf &operator-=(const Sint64 a) + { + (*this) = (*this) - a; + return (*this); + } + fixedf &operator>>=(const int a) + { + v >>= a; + return (*this); + } + fixedf &operator<<=(const int a) + { + v <<= a; + return (*this); + } friend fixedf operator-(const fixedf &a) { return fixedf(-a.v); } - friend fixedf operator+(const fixedf &a, const fixedf &b) { return fixedf(a.v+b.v); } - friend fixedf operator-(const fixedf &a, const fixedf &b) { return fixedf(a.v-b.v); } - friend fixedf operator*(const fixedf &a, const fixedf &b) { + friend fixedf operator+(const fixedf &a, const fixedf &b) { return fixedf(a.v + b.v); } + friend fixedf operator-(const fixedf &a, const fixedf &b) { return fixedf(a.v - b.v); } + friend fixedf operator*(const fixedf &a, const fixedf &b) + { // 64*64 = (128bit>>FRAC) & ((1<<64)-1) //return fixedf(a.v*b.v >> FRAC); Sint64 hi = 0; @@ -84,45 +128,47 @@ public: } Uint64 x; // a0 * b; - lo = a0*b0; oldlo = lo; - x = a0*b1; - lo += x<<32; + lo = a0 * b0; + oldlo = lo; + x = a0 * b1; + lo += x << 32; if (lo < oldlo) hi++; oldlo = lo; - hi += (x>>32); + hi += (x >> 32); // a1 * b; - x = a1*b0; - lo += x<<32; + x = a1 * b0; + lo += x << 32; if (lo < oldlo) hi++; oldlo = lo; - hi += x>>32; + hi += x >> 32; - hi += a1*b1; - Sint64 out = (lo>>FRAC) + ((hi&MASK)<<(64-FRAC)); + hi += a1 * b1; + Sint64 out = (lo >> FRAC) + ((hi & MASK) << (64 - FRAC)); return isneg ? -out : out; } - friend fixedf operator/(const fixedf &a, const fixedf &b) { + friend fixedf operator/(const fixedf &a, const fixedf &b) + { // 128-bit divided by 64-bit, to make sure high bits are not lost - Sint64 quotient_hi = a.v>>(64-FRAC); - Uint64 quotient_lo = a.v<> (64 - FRAC); + Uint64 quotient_lo = a.v << FRAC; Sint64 d = b.v; int isneg = 0; - Sint64 remainder=0; + Sint64 remainder = 0; if (d < 0) { d = -d; isneg = 1; } - for (int i=0; i<128; i++) { - Uint64 sbit = (Uint64(1)<<63) & quotient_hi; + for (int i = 0; i < 128; i++) { + Uint64 sbit = (Uint64(1) << 63) & quotient_hi; remainder <<= 1; if (sbit) remainder |= 1; // shift quotient left 1 { quotient_hi <<= 1; - if (quotient_lo & (Uint64(1)<<63)) quotient_hi |= 1; + if (quotient_lo & (Uint64(1) << 63)) quotient_hi |= 1; quotient_lo <<= 1; } if (remainder >= d) { @@ -140,30 +186,35 @@ public: friend bool operator<=(const fixedf &a, const fixedf &b) { return a.v <= b.v; } /* implicit operator float() bad */ - int ToInt32() const { return int(v>>FRAC); } - Sint64 ToInt64() const { return v>>FRAC; } - float ToFloat() const { return v/float(Sint64(1)<> FRAC); } + Sint64 ToInt64() const { return v >> FRAC; } + float ToFloat() const { return v / float(Sint64(1) << FRAC); } + double ToDouble() const { return v / double(Sint64(1) << FRAC); } - static fixedf FromDouble(const double val) { return fixedf(Sint64(((val) * double(Sint64(1)< - operator fixedf() const { + operator fixedf() const + { int shift = NEW_FRAC_BITS - FRAC_BITS; - if (shift > 0) return fixedf(v<(v>>(-shift)); + if (shift > 0) + return fixedf(v << shift); + else + return fixedf(v >> (-shift)); } - static fixedf SqrtOf(const fixedf &a) { + static fixedf SqrtOf(const fixedf &a) + { /* only works on even-numbered fractional bits */ assert(!(FRAC & 1)); Uint64 root, remHi, remLo, testDiv, count; root = 0; remHi = 0; remLo = a.v; - count = 32+(FRAC>>1)-1; + count = 32 + (FRAC >> 1) - 1; do { - remHi = (remHi<<2) | (remLo>>62); remLo <<= 2; + remHi = (remHi << 2) | (remLo >> 62); + remLo <<= 2; root <<= 1; testDiv = (root << 1) + 1; if (remHi >= testDiv) { @@ -172,18 +223,19 @@ public: } } while (count-- != 0); - return(fixedf(root)); + return (fixedf(root)); } - static fixedf CubeRootOf(const fixedf &a) { + static fixedf CubeRootOf(const fixedf &a) + { /* NR method. XXX very bad initial estimate (we get there in * the end... XXX */ fixedf x = a; - for (int i=0; i<48; i++) x = fixedf(1,3) * ((a / (x*x)) + 2*x); + for (int i = 0; i < 48; i++) + x = fixedf(1, 3) * ((a / (x * x)) + 2 * x); return x; } - Sint64 v; }; diff --git a/src/galaxy/CustomSystem.cpp b/src/galaxy/CustomSystem.cpp index 8b3aaa99c..b862c8d80 100644 --- a/src/galaxy/CustomSystem.cpp +++ b/src/galaxy/CustomSystem.cpp @@ -5,27 +5,28 @@ #include "Galaxy.h" #include "SystemPath.h" -#include "LuaUtils.h" -#include "LuaVector.h" -#include "LuaFixed.h" -#include "LuaConstants.h" -#include "Pi.h" -#include "Polit.h" #include "Factions.h" #include "FileSystem.h" +#include "LuaConstants.h" +#include "LuaFixed.h" +#include "LuaUtils.h" +#include "LuaVector.h" +#include "Pi.h" +#include "Polit.h" #include const CustomSystemsDatabase::SystemList CustomSystemsDatabase::s_emptySystemList; // see: Null Object pattern -static CustomSystemsDatabase* s_activeCustomSystemsDatabase = nullptr; +static CustomSystemsDatabase *s_activeCustomSystemsDatabase = nullptr; // ------- CustomSystemBody -------- static const char LuaCustomSystemBody_TypeName[] = "CustomSystemBody"; -static CustomSystemBody **l_csb_check_ptr(lua_State *L, int idx) { - CustomSystemBody **csbptr = static_cast( - luaL_checkudata(L, idx, LuaCustomSystemBody_TypeName)); +static CustomSystemBody **l_csb_check_ptr(lua_State *L, int idx) +{ + CustomSystemBody **csbptr = static_cast( + luaL_checkudata(L, idx, LuaCustomSystemBody_TypeName)); if (!(*csbptr)) { abort(); luaL_argerror(L, idx, "invalid body (this body has already been used)"); @@ -34,7 +35,9 @@ static CustomSystemBody **l_csb_check_ptr(lua_State *L, int idx) { } static CustomSystemBody *l_csb_check(lua_State *L, int idx) -{ return *l_csb_check_ptr(L, idx); } +{ + return *l_csb_check_ptr(L, idx); +} static int l_csb_new(lua_State *L) { @@ -45,8 +48,8 @@ static int l_csb_new(lua_State *L) return luaL_error(L, "body '%s' does not have a valid type", name); } - CustomSystemBody **csbptr = static_cast( - lua_newuserdata(L, sizeof(CustomSystemBody*))); + CustomSystemBody **csbptr = static_cast( + lua_newuserdata(L, sizeof(CustomSystemBody *))); *csbptr = new CustomSystemBody; luaL_setmetatable(L, LuaCustomSystemBody_TypeName); @@ -61,68 +64,75 @@ static double *getDoubleOrFixed(lua_State *L, int which) static double mixvalue; const char *s = luaL_typename(L, which); - if (strcmp(s, "userdata") == 0) - { + if (strcmp(s, "userdata") == 0) { const fixed *mix = LuaFixed::CheckFromLua(L, which); mixvalue = mix->ToDouble(); - return(&mixvalue); - } - else if (strcmp(s, "number") == 0) - { + return (&mixvalue); + } else if (strcmp(s, "number") == 0) { mixvalue = luaL_checknumber(L, which); - return(&mixvalue); + return (&mixvalue); } return nullptr; } // Used when the value MUST not be NEGATIVE but can be Zero, for life, etc -#define CSB_FIELD_SETTER_FIXED(luaname, fieldname) \ - static int l_csb_ ## luaname (lua_State *L) { \ - CustomSystemBody *csb = l_csb_check(L, 1); \ - double *value = getDoubleOrFixed(L, 2); \ - if (value == nullptr) \ - return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); \ - if (*value < 0.0) \ +#define CSB_FIELD_SETTER_FIXED(luaname, fieldname) \ + static int l_csb_##luaname(lua_State *L) \ + { \ + CustomSystemBody *csb = l_csb_check(L, 1); \ + double *value = getDoubleOrFixed(L, 2); \ + if (value == nullptr) \ + return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); \ + if (*value < 0.0) \ Output("Error: Custom system definition: Value cannot be negative (%lf) for %s : %s\n", *value, csb->name.c_str(), #luaname); \ - csb->fieldname = fixed::FromDouble(*value); \ - lua_settop(L, 1); return 1; \ + csb->fieldname = fixed::FromDouble(*value); \ + lua_settop(L, 1); \ + return 1; \ } // Used when the value MUST be greater than Zero, for Mass or Radius for example -#define CSB_FIELD_SETTER_FIXED_POSITIVE(luaname, fieldname) \ - static int l_csb_ ## luaname (lua_State *L) { \ - CustomSystemBody *csb = l_csb_check(L, 1); \ - double *value = getDoubleOrFixed(L, 2); \ - if (value == nullptr) \ - return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); \ - if (*value <= 0.0) \ - Output("Error: Custom system definition: Value cannot be negative/zero (%lf) for %s : %s\n", *value, csb->name.c_str(), #luaname);\ - csb->fieldname = fixed::FromDouble(*value); \ - lua_settop(L, 1); return 1; \ +#define CSB_FIELD_SETTER_FIXED_POSITIVE(luaname, fieldname) \ + static int l_csb_##luaname(lua_State *L) \ + { \ + CustomSystemBody *csb = l_csb_check(L, 1); \ + double *value = getDoubleOrFixed(L, 2); \ + if (value == nullptr) \ + return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); \ + if (*value <= 0.0) \ + Output("Error: Custom system definition: Value cannot be negative/zero (%lf) for %s : %s\n", *value, csb->name.c_str(), #luaname); \ + csb->fieldname = fixed::FromDouble(*value); \ + lua_settop(L, 1); \ + return 1; \ } -#define CSB_FIELD_SETTER_REAL(luaname, fieldname) \ - static int l_csb_ ## luaname (lua_State *L) { \ - CustomSystemBody *csb = l_csb_check(L, 1); \ - double value = luaL_checknumber(L, 2); \ - csb->fieldname = value; \ - lua_settop(L, 1); return 1; \ +#define CSB_FIELD_SETTER_REAL(luaname, fieldname) \ + static int l_csb_##luaname(lua_State *L) \ + { \ + CustomSystemBody *csb = l_csb_check(L, 1); \ + double value = luaL_checknumber(L, 2); \ + csb->fieldname = value; \ + lua_settop(L, 1); \ + return 1; \ } -#define CSB_FIELD_SETTER_INT(luaname, fieldname) \ - static int l_csb_ ## luaname (lua_State *L) { \ - CustomSystemBody *csb = l_csb_check(L, 1); \ - int value = luaL_checkinteger(L, 2); \ - csb->fieldname = value; \ - lua_settop(L, 1); return 1; \ +#define CSB_FIELD_SETTER_INT(luaname, fieldname) \ + static int l_csb_##luaname(lua_State *L) \ + { \ + CustomSystemBody *csb = l_csb_check(L, 1); \ + int value = luaL_checkinteger(L, 2); \ + csb->fieldname = value; \ + lua_settop(L, 1); \ + return 1; \ } -#define CSB_FIELD_SETTER_STRING(luaname, fieldname) \ - static int l_csb_ ## luaname (lua_State *L) { \ - CustomSystemBody *csb = l_csb_check(L, 1); \ - std::string value = luaL_checkstring(L, 2); \ - csb->fieldname = value; \ - lua_settop(L, 1); return 1; \ +#define CSB_FIELD_SETTER_STRING(luaname, fieldname) \ + static int l_csb_##luaname(lua_State *L) \ + { \ + CustomSystemBody *csb = l_csb_check(L, 1); \ + std::string value = luaL_checkstring(L, 2); \ + csb->fieldname = value; \ + lua_settop(L, 1); \ + return 1; \ } CSB_FIELD_SETTER_FIXED_POSITIVE(radius, radius) @@ -152,7 +162,7 @@ static int l_csb_radius_km(lua_State *L) CustomSystemBody *csb = l_csb_check(L, 1); double value = luaL_checknumber(L, 2); // earth mean radiusMean radius = 6371.0 km (source: wikipedia) - csb->radius = (value/6371.0); + csb->radius = (value / 6371.0); lua_settop(L, 1); return 1; } @@ -184,7 +194,7 @@ static int l_csb_orbital_phase_at_start(lua_State *L) double *value = getDoubleOrFixed(L, 2); if (value == nullptr) return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); - if ((*value < 0.0) || (*value > double(2.0*M_PI))) + if ((*value < 0.0) || (*value > double(2.0 * M_PI))) return luaL_error(L, "Error: Custom system definition: Orbital phase at game start must be between 0 and 2 PI radians (including 0 but not 2 PI)."); csb->orbitalPhaseAtStart = fixed::FromDouble(*value); lua_settop(L, 1); @@ -197,7 +207,7 @@ static int l_csb_rotational_phase_at_start(lua_State *L) double *value = getDoubleOrFixed(L, 2); if (value == nullptr) return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); - if ((*value < 0.0) || (*value > double(2.0*M_PI))) + if ((*value < 0.0) || (*value > double(2.0 * M_PI))) return luaL_error(L, "Error: Custom system definition: Rotational phase at start must be between 0 and 2 PI radians (including 0 but not 2 PI).\n The rotational phase is the phase of the body's spin about it's axis at game start."); csb->rotationalPhaseAtStart = fixed::FromDouble(*value); lua_settop(L, 1); @@ -209,7 +219,9 @@ static int l_csb_height_map(lua_State *L) CustomSystemBody *csb = l_csb_check(L, 1); const char *fname = luaL_checkstring(L, 2); int fractal = luaL_checkinteger(L, 3); - if (fractal >= 2) { return luaL_error(L, "invalid terrain fractal type"); } + if (fractal >= 2) { + return luaL_error(L, "invalid terrain fractal type"); + } csb->heightMapFilename = FileSystem::JoinPathBelow("heightmaps", fname); csb->heightMapFractal = fractal; @@ -254,8 +266,8 @@ static int l_csb_rings(lua_State *L) static int l_csb_gc(lua_State *L) { - CustomSystemBody **csbptr = static_cast( - luaL_checkudata(L, 1, LuaCustomSystemBody_TypeName)); + CustomSystemBody **csbptr = static_cast( + luaL_checkudata(L, 1, LuaCustomSystemBody_TypeName)); delete *csbptr; // does nothing if *csbptr is null *csbptr = 0; return 0; @@ -268,10 +280,14 @@ static int l_csb_aspect_ratio(lua_State *L) if (value == nullptr) return luaL_error(L, "Bad datatype. Expected fixed or float, got %s", luaL_typename(L, 2)); csb->aspectRatio = fixed::FromDouble(*value); - if (csb->aspectRatio < fixed(1,1) ) { return luaL_error( - L, "Error: Custom system definition: Equatorial to Polar radius ratio cannot be less than 1."); } - if (csb->aspectRatio > fixed(10000,1) ) { return luaL_error( - L, "Error: Custom system definition: Equatorial to Polar radius ratio cannot be greater than 10000.0."); } + if (csb->aspectRatio < fixed(1, 1)) { + return luaL_error( + L, "Error: Custom system definition: Equatorial to Polar radius ratio cannot be less than 1."); + } + if (csb->aspectRatio > fixed(10000, 1)) { + return luaL_error( + L, "Error: Custom system definition: Equatorial to Polar radius ratio cannot be greater than 10000.0."); + } lua_settop(L, 1); return 1; } @@ -313,9 +329,10 @@ static luaL_Reg LuaCustomSystemBody_meta[] = { static const char LuaCustomSystem_TypeName[] = "CustomSystem"; -static CustomSystem **l_csys_check_ptr(lua_State *L, int idx) { - CustomSystem **csptr = static_cast( - luaL_checkudata(L, idx, LuaCustomSystem_TypeName)); +static CustomSystem **l_csys_check_ptr(lua_State *L, int idx) +{ + CustomSystem **csptr = static_cast( + luaL_checkudata(L, idx, LuaCustomSystem_TypeName)); if (!(*csptr)) { abort(); luaL_error(L, "invalid system (this system has already been used)"); @@ -324,7 +341,9 @@ static CustomSystem **l_csys_check_ptr(lua_State *L, int idx) { } static CustomSystem *l_csys_check(lua_State *L, int idx) -{ return *l_csys_check_ptr(L, idx); } +{ + return *l_csys_check_ptr(L, idx); +} static unsigned interpret_star_types(int *starTypes, lua_State *L, int idx) { @@ -337,13 +356,12 @@ static unsigned interpret_star_types(int *starTypes, lua_State *L, int idx) lua_rawgeti(L, -1, i + 1); if (lua_type(L, -1) == LUA_TSTRING) { ty = LuaConstants::GetConstantFromArg(L, "BodyType", -1); - if ((ty < SystemBody::TYPE_STAR_MIN || ty > SystemBody::TYPE_STAR_MAX) - && ty != SystemBody::TYPE_GRAVPOINT) { - luaL_error(L, "system star %d does not have a valid star type", i+1); + if ((ty < SystemBody::TYPE_STAR_MIN || ty > SystemBody::TYPE_STAR_MAX) && ty != SystemBody::TYPE_GRAVPOINT) { + luaL_error(L, "system star %d does not have a valid star type", i + 1); // unreachable (longjmp in luaL_error) } } else if (!lua_isnil(L, -1)) { - luaL_error(L, "system star %d is not a string constant", i+1); + luaL_error(L, "system star %d is not a string constant", i + 1); } lua_pop(L, 1); LUA_DEBUG_CHECK(L, 1); @@ -362,8 +380,8 @@ static int l_csys_new(lua_State *L) int starTypes[4]; unsigned numStars = interpret_star_types(starTypes, L, 3); - CustomSystem **csptr = static_cast( - lua_newuserdata(L, sizeof(CustomSystem*))); + CustomSystem **csptr = static_cast( + lua_newuserdata(L, sizeof(CustomSystem *))); *csptr = new CustomSystem; luaL_setmetatable(L, LuaCustomSystem_TypeName); @@ -432,10 +450,10 @@ static int l_csys_other_names(lua_State *L) { CustomSystem *cs = l_csys_check(L, 1); std::vector other_names; - if(lua_istable(L, 2)) { + if (lua_istable(L, 2)) { lua_pushnil(L); - while(lua_next(L, -2) != 0) { - if(lua_isstring(L, -2)) { + while (lua_next(L, -2) != 0) { + if (lua_isstring(L, -2)) { std::string n(lua_tostring(L, -1)); other_names.push_back(n); } @@ -489,7 +507,7 @@ static void _add_children_to_sbody(lua_State *L, CustomSystemBody *sbody) // then there are any number of sub-tables containing direct children while (true) { - lua_rawgeti(L, -1, i+1); + lua_rawgeti(L, -1, i + 1); LUA_DEBUG_CHECK(L, 1); if (!lua_istable(L, -1)) break; _add_children_to_sbody(L, kid); @@ -508,14 +526,14 @@ static void _add_children_to_sbody(lua_State *L, CustomSystemBody *sbody) LUA_DEBUG_END(L, 0); } -static unsigned count_stars(CustomSystemBody* csb) +static unsigned count_stars(CustomSystemBody *csb) { if (!csb) return 0; unsigned count = 0; if (csb->type >= SystemBody::TYPE_STAR_MIN && csb->type <= SystemBody::TYPE_STAR_MAX) ++count; - for (CustomSystemBody* child : csb->children) + for (CustomSystemBody *child : csb->children) count += count_stars(child); return count; } @@ -527,8 +545,7 @@ static int l_csys_bodies(lua_State *L) int primary_type = (*primary_ptr)->type; luaL_checktype(L, 3, LUA_TTABLE); - if ((primary_type < SystemBody::TYPE_STAR_MIN || primary_type > SystemBody::TYPE_STAR_MAX) - && primary_type != SystemBody::TYPE_GRAVPOINT) + if ((primary_type < SystemBody::TYPE_STAR_MIN || primary_type > SystemBody::TYPE_STAR_MAX) && primary_type != SystemBody::TYPE_GRAVPOINT) return luaL_error(L, "first body does not have a valid star type"); if (primary_type != cs->primaryType[0] && primary_type != SystemBody::TYPE_GRAVPOINT) return luaL_error(L, "first body type does not match the system's primary star type"); @@ -574,8 +591,8 @@ static int l_csys_add_to_sector(lua_State *L) static int l_csys_gc(lua_State *L) { - CustomSystem **csptr = static_cast( - luaL_checkudata(L, 1, LuaCustomSystem_TypeName)); + CustomSystem **csptr = static_cast( + luaL_checkudata(L, 1, LuaCustomSystem_TypeName)); delete *csptr; *csptr = 0; return 0; @@ -664,7 +681,8 @@ CustomSystemsDatabase::~CustomSystemsDatabase() { for (SectorMap::iterator secIt = m_sectorMap.begin(); secIt != m_sectorMap.end(); ++secIt) { for (CustomSystemsDatabase::SystemList::iterator - sysIt = secIt->second.begin(); sysIt != secIt->second.end(); ++sysIt) { + sysIt = secIt->second.begin(); + sysIt != secIt->second.end(); ++sysIt) { delete *sysIt; } } @@ -673,18 +691,17 @@ CustomSystemsDatabase::~CustomSystemsDatabase() const CustomSystemsDatabase::SystemList &CustomSystemsDatabase::GetCustomSystemsForSector(int x, int y, int z) const { - SystemPath path(x,y,z); + SystemPath path(x, y, z); SectorMap::const_iterator it = m_sectorMap.find(path); return (it != m_sectorMap.end()) ? it->second : s_emptySystemList; } -void CustomSystemsDatabase::AddCustomSystem(const SystemPath& path, CustomSystem* csys) +void CustomSystemsDatabase::AddCustomSystem(const SystemPath &path, CustomSystem *csys) { m_sectorMap[path].push_back(csys); - } -CustomSystem::CustomSystem(): +CustomSystem::CustomSystem() : sBody(0), numStars(0), seed(0), @@ -702,8 +719,8 @@ CustomSystem::~CustomSystem() delete sBody; } -CustomSystemBody::CustomSystemBody(): - aspectRatio(fixed(1,1)), +CustomSystemBody::CustomSystemBody() : + aspectRatio(fixed(1, 1)), averageTemp(1), want_rand_offset(true), latitude(0.0), @@ -717,8 +734,9 @@ CustomSystemBody::CustomSystemBody(): CustomSystemBody::~CustomSystemBody() { - for (std::vector::iterator - it = children.begin(); it != children.end(); ++it) { + for (std::vector::iterator + it = children.begin(); + it != children.end(); ++it) { delete (*it); } } diff --git a/src/galaxy/CustomSystem.h b/src/galaxy/CustomSystem.h index a3e5b9038..8e49444a7 100644 --- a/src/galaxy/CustomSystem.h +++ b/src/galaxy/CustomSystem.h @@ -4,11 +4,11 @@ #ifndef _CUSTOMSYSTEM_H #define _CUSTOMSYSTEM_H -#include "galaxy/StarSystem.h" -#include "Polit.h" -#include "vector3.h" -#include "fixed.h" #include "Color.h" +#include "Polit.h" +#include "fixed.h" +#include "galaxy/StarSystem.h" +#include "vector3.h" class Faction; class Galaxy; @@ -18,25 +18,25 @@ public: CustomSystemBody(); ~CustomSystemBody(); - std::string name; - SystemBody::BodyType type; - fixed radius; // in earth radii for planets, sol radii for stars (equatorial radius) - fixed aspectRatio; // the ratio between equatorial radius and polar radius for bodies flattened due to equatorial bulge (1.0 to infinity) - fixed mass; // earth masses or sol masses - int averageTemp; // kelvin - fixed semiMajorAxis; // in AUs - fixed eccentricity; - fixed orbitalOffset; - fixed orbitalPhaseAtStart; // mean anomaly at start 0 to 2 pi - bool want_rand_offset; + std::string name; + SystemBody::BodyType type; + fixed radius; // in earth radii for planets, sol radii for stars (equatorial radius) + fixed aspectRatio; // the ratio between equatorial radius and polar radius for bodies flattened due to equatorial bulge (1.0 to infinity) + fixed mass; // earth masses or sol masses + int averageTemp; // kelvin + fixed semiMajorAxis; // in AUs + fixed eccentricity; + fixed orbitalOffset; + fixed orbitalPhaseAtStart; // mean anomaly at start 0 to 2 pi + bool want_rand_offset; // for orbiting things, latitude = inclination - float latitude, longitude; // radians - fixed rotationPeriod; // in days - fixed rotationalPhaseAtStart; // 0 to 2 pi - fixed axialTilt; // in radians - std::string heightMapFilename; - int heightMapFractal; - std::vector children; + float latitude, longitude; // radians + fixed rotationPeriod; // in days + fixed rotationalPhaseAtStart; // 0 to 2 pi + fixed axialTilt; // in radians + std::string heightMapFilename; + int heightMapFractal; + std::vector children; /* composition */ fixed metallicity; // (crust) 0.0 = light (Al, SiO2, etc), 1.0 = heavy (Fe, heavy metals) @@ -60,7 +60,7 @@ public: Color ringColor; Uint32 seed; - bool want_rand_seed; + bool want_rand_seed; std::string spaceStationType; }; @@ -70,43 +70,45 @@ public: CustomSystem(); ~CustomSystem(); - std::string name; + std::string name; std::vector other_names; - CustomSystemBody* sBody; - SystemBody::BodyType primaryType[4]; - unsigned numStars; - int sectorX, sectorY, sectorZ; - vector3f pos; - Uint32 seed; - bool want_rand_explored; - bool explored; - const Faction* faction; - Polit::GovType govType; - bool want_rand_lawlessness; - fixed lawlessness; // 0.0 = lawful, 1.0 = totally lawless - std::string shortDesc; - std::string longDesc; + CustomSystemBody *sBody; + SystemBody::BodyType primaryType[4]; + unsigned numStars; + int sectorX, sectorY, sectorZ; + vector3f pos; + Uint32 seed; + bool want_rand_explored; + bool explored; + const Faction *faction; + Polit::GovType govType; + bool want_rand_lawlessness; + fixed lawlessness; // 0.0 = lawful, 1.0 = totally lawless + std::string shortDesc; + std::string longDesc; bool IsRandom() const { return !sBody; } }; class CustomSystemsDatabase { public: - CustomSystemsDatabase(Galaxy* galaxy, const std::string& customSysDir) : m_galaxy(galaxy), m_customSysDirectory(customSysDir) { } + CustomSystemsDatabase(Galaxy *galaxy, const std::string &customSysDir) : + m_galaxy(galaxy), + m_customSysDirectory(customSysDir) {} ~CustomSystemsDatabase(); void Init(); - typedef std::vector SystemList; + typedef std::vector SystemList; // XXX this is not as const-safe as it should be const SystemList &GetCustomSystemsForSector(int sectorX, int sectorY, int sectorZ) const; - void AddCustomSystem(const SystemPath& path, CustomSystem* csys); - Galaxy* GetGalaxy() const { return m_galaxy; } + void AddCustomSystem(const SystemPath &path, CustomSystem *csys); + Galaxy *GetGalaxy() const { return m_galaxy; } private: typedef std::map SectorMap; - Galaxy* const m_galaxy; + Galaxy *const m_galaxy; const std::string m_customSysDirectory; SectorMap m_sectorMap; static const CustomSystemsDatabase::SystemList s_emptySystemList; // see: Null Object pattern diff --git a/src/galaxy/Economy.cpp b/src/galaxy/Economy.cpp index 89b1ff139..af9c9f3e2 100644 --- a/src/galaxy/Economy.cpp +++ b/src/galaxy/Economy.cpp @@ -6,136 +6,103 @@ namespace GalacticEconomy { -const CommodityInfo COMMODITY_DATA[COMMODITY_COUNT] = { - { - Lang::COMMODITY_NONE, - {}, - 0 - },{ - Lang::HYDROGEN, - {}, - ECON_MINING - },{ - Lang::LIQUID_OXYGEN, - { Commodity::WATER, Commodity::INDUSTRIAL_MACHINERY }, - ECON_MINING - },{ - Lang::METAL_ORE, - { Commodity::MINING_MACHINERY }, - ECON_MINING - },{ - Lang::CARBON_ORE, - { Commodity::MINING_MACHINERY }, - ECON_MINING - },{ - Lang::METAL_ALLOYS, - { Commodity::METAL_ORE, Commodity::INDUSTRIAL_MACHINERY }, - ECON_INDUSTRY - },{ - Lang::PLASTICS, - { Commodity::CARBON_ORE, Commodity::INDUSTRIAL_MACHINERY }, - ECON_INDUSTRY - },{ - Lang::FRUIT_AND_VEG, - { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, - ECON_AGRICULTURE - },{ - Lang::ANIMAL_MEAT, - { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, - ECON_AGRICULTURE - },{ - Lang::LIVE_ANIMALS, - { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, - ECON_AGRICULTURE - },{ - Lang::LIQUOR, - { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, - ECON_AGRICULTURE - },{ - Lang::GRAIN, - { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, - ECON_AGRICULTURE - },{ - Lang::TEXTILES, - { Commodity::PLASTICS }, - ECON_INDUSTRY - },{ - Lang::FERTILIZER, - { Commodity::CARBON_ORE }, - ECON_INDUSTRY - },{ - Lang::WATER, - { Commodity::MINING_MACHINERY }, - ECON_MINING - },{ - Lang::MEDICINES, - { Commodity::COMPUTERS, Commodity::CARBON_ORE }, - ECON_INDUSTRY - },{ - Lang::CONSUMER_GOODS, - { Commodity::PLASTICS, Commodity::TEXTILES }, - ECON_INDUSTRY - },{ - Lang::COMPUTERS, - { Commodity::PRECIOUS_METALS, Commodity::INDUSTRIAL_MACHINERY }, - ECON_INDUSTRY - },{ - Lang::ROBOTS, - { Commodity::PLASTICS, Commodity::COMPUTERS }, - ECON_INDUSTRY - },{ - Lang::PRECIOUS_METALS, - { Commodity::MINING_MACHINERY }, - ECON_MINING - },{ - Lang::INDUSTRIAL_MACHINERY, - { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, - ECON_INDUSTRY - },{ - Lang::FARM_MACHINERY, - { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, - ECON_INDUSTRY - },{ - Lang::MINING_MACHINERY, - { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, - ECON_INDUSTRY - },{ - Lang::AIR_PROCESSORS, - { Commodity::PLASTICS, Commodity::INDUSTRIAL_MACHINERY }, - ECON_INDUSTRY - },{ - Lang::SLAVES, - {}, - ECON_AGRICULTURE - },{ - Lang::HAND_WEAPONS, - { Commodity::COMPUTERS }, - ECON_INDUSTRY - },{ - Lang::BATTLE_WEAPONS, - { Commodity::INDUSTRIAL_MACHINERY, Commodity::METAL_ALLOYS }, - ECON_INDUSTRY - },{ - Lang::NERVE_GAS, - {}, - ECON_INDUSTRY - },{ - Lang::NARCOTICS, - {}, - ECON_INDUSTRY - },{ - Lang::MILITARY_FUEL, - { Commodity::HYDROGEN }, - ECON_INDUSTRY - },{ - Lang::RUBBISH, - {}, - ECON_INDUSTRY - },{ - Lang::RADIOACTIVES, - {}, - ECON_INDUSTRY - } -}; + const CommodityInfo COMMODITY_DATA[COMMODITY_COUNT] = { + { Lang::COMMODITY_NONE, + {}, + 0 }, + { Lang::HYDROGEN, + {}, + ECON_MINING }, + { Lang::LIQUID_OXYGEN, + { Commodity::WATER, Commodity::INDUSTRIAL_MACHINERY }, + ECON_MINING }, + { Lang::METAL_ORE, + { Commodity::MINING_MACHINERY }, + ECON_MINING }, + { Lang::CARBON_ORE, + { Commodity::MINING_MACHINERY }, + ECON_MINING }, + { Lang::METAL_ALLOYS, + { Commodity::METAL_ORE, Commodity::INDUSTRIAL_MACHINERY }, + ECON_INDUSTRY }, + { Lang::PLASTICS, + { Commodity::CARBON_ORE, Commodity::INDUSTRIAL_MACHINERY }, + ECON_INDUSTRY }, + { Lang::FRUIT_AND_VEG, + { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, + ECON_AGRICULTURE }, + { Lang::ANIMAL_MEAT, + { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, + ECON_AGRICULTURE }, + { Lang::LIVE_ANIMALS, + { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, + ECON_AGRICULTURE }, + { Lang::LIQUOR, + { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, + ECON_AGRICULTURE }, + { Lang::GRAIN, + { Commodity::FARM_MACHINERY, Commodity::FERTILIZER }, + ECON_AGRICULTURE }, + { Lang::TEXTILES, + { Commodity::PLASTICS }, + ECON_INDUSTRY }, + { Lang::FERTILIZER, + { Commodity::CARBON_ORE }, + ECON_INDUSTRY }, + { Lang::WATER, + { Commodity::MINING_MACHINERY }, + ECON_MINING }, + { Lang::MEDICINES, + { Commodity::COMPUTERS, Commodity::CARBON_ORE }, + ECON_INDUSTRY }, + { Lang::CONSUMER_GOODS, + { Commodity::PLASTICS, Commodity::TEXTILES }, + ECON_INDUSTRY }, + { Lang::COMPUTERS, + { Commodity::PRECIOUS_METALS, Commodity::INDUSTRIAL_MACHINERY }, + ECON_INDUSTRY }, + { Lang::ROBOTS, + { Commodity::PLASTICS, Commodity::COMPUTERS }, + ECON_INDUSTRY }, + { Lang::PRECIOUS_METALS, + { Commodity::MINING_MACHINERY }, + ECON_MINING }, + { Lang::INDUSTRIAL_MACHINERY, + { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, + ECON_INDUSTRY }, + { Lang::FARM_MACHINERY, + { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, + ECON_INDUSTRY }, + { Lang::MINING_MACHINERY, + { Commodity::METAL_ALLOYS, Commodity::ROBOTS }, + ECON_INDUSTRY }, + { Lang::AIR_PROCESSORS, + { Commodity::PLASTICS, Commodity::INDUSTRIAL_MACHINERY }, + ECON_INDUSTRY }, + { Lang::SLAVES, + {}, + ECON_AGRICULTURE }, + { Lang::HAND_WEAPONS, + { Commodity::COMPUTERS }, + ECON_INDUSTRY }, + { Lang::BATTLE_WEAPONS, + { Commodity::INDUSTRIAL_MACHINERY, Commodity::METAL_ALLOYS }, + ECON_INDUSTRY }, + { Lang::NERVE_GAS, + {}, + ECON_INDUSTRY }, + { Lang::NARCOTICS, + {}, + ECON_INDUSTRY }, + { Lang::MILITARY_FUEL, + { Commodity::HYDROGEN }, + ECON_INDUSTRY }, + { Lang::RUBBISH, + {}, + ECON_INDUSTRY }, + { Lang::RADIOACTIVES, + {}, + ECON_INDUSTRY } + }; } // namespace GalacticEconomy diff --git a/src/galaxy/Economy.h b/src/galaxy/Economy.h index b1e364347..62dcbdfbc 100644 --- a/src/galaxy/Economy.h +++ b/src/galaxy/Economy.h @@ -6,9 +6,9 @@ namespace GalacticEconomy { enum EconType { // - ECON_MINING = 1<<0, - ECON_AGRICULTURE = 1<<1, - ECON_INDUSTRY = 1<<2 + ECON_MINING = 1 << 0, + ECON_AGRICULTURE = 1 << 1, + ECON_INDUSTRY = 1 << 2 }; enum class Commodity { // @@ -62,6 +62,6 @@ namespace GalacticEconomy { }; extern const CommodityInfo COMMODITY_DATA[]; -} +} // namespace GalacticEconomy #endif diff --git a/src/galaxy/Galaxy.cpp b/src/galaxy/Galaxy.cpp index 84cf86ffa..07d6a397b 100644 --- a/src/galaxy/Galaxy.cpp +++ b/src/galaxy/Galaxy.cpp @@ -1,20 +1,26 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt +#include "Galaxy.h" +#include "FileSystem.h" +#include "GalaxyGenerator.h" +#include "GameSaveError.h" +#include "Pi.h" +#include "Sector.h" #include "libs.h" #include "utils.h" -#include "Galaxy.h" -#include "GalaxyGenerator.h" -#include "Sector.h" -#include "Pi.h" -#include "FileSystem.h" -#include "GameSaveError.h" Galaxy::Galaxy(RefCountedPtr galaxyGenerator, float radius, float sol_offset_x, float sol_offset_y, - const std::string& factionsDir, const std::string& customSysDir) - : GALAXY_RADIUS(radius), SOL_OFFSET_X(sol_offset_x), SOL_OFFSET_Y(sol_offset_y), - m_initialized(false), m_galaxyGenerator(galaxyGenerator), m_sectorCache(this), - m_starSystemCache(this), m_factions(this, factionsDir), m_customSystems(this, customSysDir) + const std::string &factionsDir, const std::string &customSysDir) : + GALAXY_RADIUS(radius), + SOL_OFFSET_X(sol_offset_x), + SOL_OFFSET_Y(sol_offset_y), + m_initialized(false), + m_galaxyGenerator(galaxyGenerator), + m_sectorCache(this), + m_starSystemCache(this), + m_factions(this, factionsDir), + m_customSystems(this, customSysDir) { } @@ -78,7 +84,7 @@ void Galaxy::FlushCaches() assert(m_sectorCache.IsEmpty()); } -void Galaxy::Dump(FILE* file, Sint32 centerX, Sint32 centerY, Sint32 centerZ, Sint32 radius) +void Galaxy::Dump(FILE *file, Sint32 centerX, Sint32 centerY, Sint32 centerZ, Sint32 radius) { for (Sint32 sx = centerX - radius; sx <= centerX + radius; ++sx) { for (Sint32 sy = centerY - radius; sy <= centerY + radius; ++sy) { @@ -96,7 +102,7 @@ RefCountedPtr Galaxy::GetGenerator() const return m_galaxyGenerator; } -const std::string& Galaxy::GetGeneratorName() const +const std::string &Galaxy::GetGeneratorName() const { return m_galaxyGenerator->GetName(); } @@ -106,10 +112,11 @@ int Galaxy::GetGeneratorVersion() const return m_galaxyGenerator->GetVersion(); } -DensityMapGalaxy::DensityMapGalaxy(RefCountedPtr galaxyGenerator, const std::string& mapfile, - float radius, float sol_offset_x, float sol_offset_y, const std::string& factionsDir, const std::string& customSysDir) - : Galaxy(galaxyGenerator, radius, sol_offset_x, sol_offset_y, factionsDir, customSysDir), - m_mapWidth(0), m_mapHeight(0) +DensityMapGalaxy::DensityMapGalaxy(RefCountedPtr galaxyGenerator, const std::string &mapfile, + float radius, float sol_offset_x, float sol_offset_y, const std::string &factionsDir, const std::string &customSysDir) : + Galaxy(galaxyGenerator, radius, sol_offset_x, sol_offset_y, factionsDir, customSysDir), + m_mapWidth(0), + m_mapHeight(0) { RefCountedPtr filedata = FileSystem::gameDataFiles.ReadFile(mapfile); if (!filedata) { @@ -124,22 +131,22 @@ DensityMapGalaxy::DensityMapGalaxy(RefCountedPtr galaxyGenerato // now that we have our raw image loaded // allocate the space for our processed representation - m_galaxyMap.reset( new float[(galaxyImg->w * galaxyImg->h)] ); + m_galaxyMap.reset(new float[(galaxyImg->w * galaxyImg->h)]); // lock the image once so we can read from it SDL_LockSurface(galaxyImg); // setup our map dimensions for later m_mapWidth = galaxyImg->w; m_mapHeight = galaxyImg->h; // copy every pixel value from the red channel (image is greyscale, channel is irrelevant) - for( int x=0; xw; x++ ) { - for( int y=0; yh; y++ ) { - const float val = float(static_cast(galaxyImg->pixels)[x + y*galaxyImg->pitch]); - m_galaxyMap.get()[x + y*m_mapWidth] = val; + for (int x = 0; x < galaxyImg->w; x++) { + for (int y = 0; y < galaxyImg->h; y++) { + const float val = float(static_cast(galaxyImg->pixels)[x + y * galaxyImg->pitch]); + m_galaxyMap.get()[x + y * m_mapWidth] = val; } } // unlock the surface and then release it SDL_UnlockSurface(galaxyImg); - if(galaxyImg) + if (galaxyImg) SDL_FreeSurface(galaxyImg); } @@ -147,16 +154,16 @@ static const float one_over_256(1.0f / 256.0f); Uint8 DensityMapGalaxy::GetSectorDensity(const int sx, const int sy, const int sz) const { // -1.0 to 1.0 then limited to 0.0 to 1.0 - const float offset_x = (((sx*Sector::SIZE + SOL_OFFSET_X)/GALAXY_RADIUS) + 1.0f)*0.5f; - const float offset_y = (((-sy*Sector::SIZE + SOL_OFFSET_Y)/GALAXY_RADIUS) + 1.0f)*0.5f; + const float offset_x = (((sx * Sector::SIZE + SOL_OFFSET_X) / GALAXY_RADIUS) + 1.0f) * 0.5f; + const float offset_y = (((-sy * Sector::SIZE + SOL_OFFSET_Y) / GALAXY_RADIUS) + 1.0f) * 0.5f; const int x = int(floor(offset_x * (m_mapWidth - 1))); const int y = int(floor(offset_y * (m_mapHeight - 1))); - float val = m_galaxyMap.get()[x + y*m_mapWidth]; + float val = m_galaxyMap.get()[x + y * m_mapWidth]; // crappy unrealistic but currently adequate density dropoff with sector z - val = val * (256.0f - std::min(float(abs(sz)),256.0f)) * one_over_256; + val = val * (256.0f - std::min(float(abs(sz)), 256.0f)) * one_over_256; // reduce density somewhat to match real (gliese) density val *= 0.5f; diff --git a/src/galaxy/Galaxy.h b/src/galaxy/Galaxy.h index cee9bb019..c84c49cce 100644 --- a/src/galaxy/Galaxy.h +++ b/src/galaxy/Galaxy.h @@ -4,12 +4,12 @@ #ifndef _GALAXY_H #define _GALAXY_H -#include -#include "RefCounted.h" -#include "Factions.h" #include "CustomSystem.h" +#include "Factions.h" #include "GalaxyCache.h" #include "Json.h" +#include "RefCounted.h" +#include struct SDL_Surface; class GalaxyGenerator; @@ -18,7 +18,7 @@ class Galaxy : public RefCounted { protected: friend class GalaxyGenerator; Galaxy(RefCountedPtr galaxyGenerator, float radius, float sol_offset_x, float sol_offset_y, - const std::string& factionsDir, const std::string& customSysDir); + const std::string &factionsDir, const std::string &customSysDir); void SetGalaxyGenerator(RefCountedPtr galaxyGenerator); virtual void Init(); @@ -36,21 +36,21 @@ public: bool IsInitialized() const { return m_initialized; } /* 0 - 255 */ virtual Uint8 GetSectorDensity(const int sx, const int sy, const int sz) const = 0; - FactionsDatabase* GetFactions() { return &m_factions; } // XXX const correctness - CustomSystemsDatabase* GetCustomSystems() { return &m_customSystems; } // XXX const correctness + FactionsDatabase *GetFactions() { return &m_factions; } // XXX const correctness + CustomSystemsDatabase *GetCustomSystems() { return &m_customSystems; } // XXX const correctness - RefCountedPtr GetSector(const SystemPath& path) { return m_sectorCache.GetCached(path); } - RefCountedPtr GetMutableSector(const SystemPath& path) { return m_sectorCache.GetCached(path); } + RefCountedPtr GetSector(const SystemPath &path) { return m_sectorCache.GetCached(path); } + RefCountedPtr GetMutableSector(const SystemPath &path) { return m_sectorCache.GetCached(path); } RefCountedPtr NewSectorSlaveCache() { return m_sectorCache.NewSlaveCache(); } - RefCountedPtr GetStarSystem(const SystemPath& path) { return m_starSystemCache.GetCached(path); } + RefCountedPtr GetStarSystem(const SystemPath &path) { return m_starSystemCache.GetCached(path); } RefCountedPtr NewStarSystemSlaveCache() { return m_starSystemCache.NewSlaveCache(); } void FlushCaches(); - void Dump(FILE* file, Sint32 centerX, Sint32 centerY, Sint32 centerZ, Sint32 radius); + void Dump(FILE *file, Sint32 centerX, Sint32 centerY, Sint32 centerZ, Sint32 radius); RefCountedPtr GetGenerator() const; - const std::string& GetGeneratorName() const; + const std::string &GetGeneratorName() const; int GetGeneratorVersion() const; private: @@ -65,8 +65,8 @@ private: class DensityMapGalaxy : public Galaxy { private: friend class GalaxyGenerator; - DensityMapGalaxy(RefCountedPtr galaxyGenerator, const std::string& mapfile, - float radius, float sol_offset_x, float sol_offset_y, const std::string& factionsDir, const std::string& customSysDir); + DensityMapGalaxy(RefCountedPtr galaxyGenerator, const std::string &mapfile, + float radius, float sol_offset_x, float sol_offset_y, const std::string &factionsDir, const std::string &customSysDir); public: virtual Uint8 GetSectorDensity(const int sx, const int sy, const int sz) const; diff --git a/src/galaxy/GalaxyCache.cpp b/src/galaxy/GalaxyCache.cpp index d1db027f3..2fe1c3e9f 100644 --- a/src/galaxy/GalaxyCache.cpp +++ b/src/galaxy/GalaxyCache.cpp @@ -1,34 +1,34 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include -#include "libs.h" -#include "Factions.h" -#include "Pi.h" -#include "Game.h" #include "galaxy/GalaxyCache.h" -#include "galaxy/GalaxyGenerator.h" +#include "Factions.h" +#include "Game.h" +#include "Pi.h" #include "galaxy/Galaxy.h" +#include "galaxy/GalaxyGenerator.h" #include "galaxy/Sector.h" #include "galaxy/StarSystem.h" +#include "libs.h" +#include //#define DEBUG_CACHE //virtual template -GalaxyObjectCache::~GalaxyObjectCache() +GalaxyObjectCache::~GalaxyObjectCache() { - for (Slave* s : m_slaves) + for (Slave *s : m_slaves) s->MasterDeleted(); assert(m_attic.empty()); // otherwise the objects will deregister at a cache that no longer exists } template -void GalaxyObjectCache::AddToCache(std::vector >& objects) +void GalaxyObjectCache::AddToCache(std::vector> &objects) { for (auto it = objects.begin(), itEnd = objects.end(); it != itEnd; ++it) { - auto inserted = m_attic.insert( std::make_pair(it->Get()->GetPath(), it->Get()) ); + auto inserted = m_attic.insert(std::make_pair(it->Get()->GetPath(), it->Get())); if (!inserted.second) { it->Reset(inserted.first->second); } else { @@ -38,7 +38,7 @@ void GalaxyObjectCache::AddToCache(std::vector >& o } template -RefCountedPtr GalaxyObjectCache::GetIfCached(const SystemPath& path) +RefCountedPtr GalaxyObjectCache::GetIfCached(const SystemPath &path) { PROFILE_SCOPED() @@ -52,15 +52,15 @@ RefCountedPtr GalaxyObjectCache::GetIfCached(const SystemPath& pa } template -RefCountedPtr GalaxyObjectCache::GetCached(const SystemPath& path) +RefCountedPtr GalaxyObjectCache::GetCached(const SystemPath &path) { PROFILE_SCOPED() RefCountedPtr s = this->GetIfCached(path); if (!s) { ++m_cacheMisses; - s = m_galaxy->GetGenerator()->Generate>(RefCountedPtr(m_galaxy), path, this); - m_attic.insert( std::make_pair(path, s.Get())); + s = m_galaxy->GetGenerator()->Generate>(RefCountedPtr(m_galaxy), path, this); + m_attic.insert(std::make_pair(path, s.Get())); } else { ++m_cacheHits; } @@ -68,7 +68,7 @@ RefCountedPtr GalaxyObjectCache::GetCached(const SystemPath& path } template -bool GalaxyObjectCache::HasCached(const SystemPath& path) const +bool GalaxyObjectCache::HasCached(const SystemPath &path) const { PROFILE_SCOPED() @@ -76,20 +76,20 @@ bool GalaxyObjectCache::HasCached(const SystemPath& path) const } template -void GalaxyObjectCache::RemoveFromAttic(const SystemPath& path) +void GalaxyObjectCache::RemoveFromAttic(const SystemPath &path) { m_attic.erase(path); } template -void GalaxyObjectCache::ClearCache() +void GalaxyObjectCache::ClearCache() { for (auto it = m_slaves.begin(), itEnd = m_slaves.end(); it != itEnd; ++it) (*it)->ClearCache(); } template -void GalaxyObjectCache::OutputCacheStatistics(bool reset) +void GalaxyObjectCache::OutputCacheStatistics(bool reset) { Output("%s: misses: %llu, slave hits: %llu, master hits: %llu\n", CACHE_NAME.c_str(), m_cacheMisses, m_cacheHitsSlave, m_cacheHits); if (reset) @@ -97,26 +97,28 @@ void GalaxyObjectCache::OutputCacheStatistics(bool reset) } template -RefCountedPtr::Slave> GalaxyObjectCache::NewSlaveCache() +RefCountedPtr::Slave> GalaxyObjectCache::NewSlaveCache() { return RefCountedPtr(new Slave(this, RefCountedPtr(m_galaxy), Pi::GetAsyncJobQueue())); } template -GalaxyObjectCache::Slave::Slave(GalaxyObjectCache* master, RefCountedPtr galaxy, JobQueue* jobQueue) - : m_master(master), m_galaxy(galaxy), m_jobs(Pi::GetAsyncJobQueue()) +GalaxyObjectCache::Slave::Slave(GalaxyObjectCache *master, RefCountedPtr galaxy, JobQueue *jobQueue) : + m_master(master), + m_galaxy(galaxy), + m_jobs(Pi::GetAsyncJobQueue()) { m_master->m_slaves.insert(this); } template -void GalaxyObjectCache::Slave::MasterDeleted() +void GalaxyObjectCache::Slave::MasterDeleted() { m_master = nullptr; } template -RefCountedPtr GalaxyObjectCache::Slave::GetIfCached(const SystemPath& path) +RefCountedPtr GalaxyObjectCache::Slave::GetIfCached(const SystemPath &path) { PROFILE_SCOPED() @@ -127,7 +129,7 @@ RefCountedPtr GalaxyObjectCache::Slave::GetIfCached(const SystemP } template -RefCountedPtr GalaxyObjectCache::Slave::GetCached(const SystemPath& path) +RefCountedPtr GalaxyObjectCache::Slave::GetCached(const SystemPath &path) { PROFILE_SCOPED() @@ -139,7 +141,7 @@ RefCountedPtr GalaxyObjectCache::Slave::GetCached(const SystemPat } if (m_master) { - auto inserted = m_cache.insert( std::make_pair(path, m_master->GetCached(path)) ); + auto inserted = m_cache.insert(std::make_pair(path, m_master->GetCached(path))); return inserted.first->second; } else { return RefCountedPtr(); @@ -147,85 +149,85 @@ RefCountedPtr GalaxyObjectCache::Slave::GetCached(const SystemPat } template -void GalaxyObjectCache::Slave::Erase(const SystemPath& path) { m_cache.erase(path); } +void GalaxyObjectCache::Slave::Erase(const SystemPath &path) { m_cache.erase(path); } template -void GalaxyObjectCache::Slave::Erase(const typename CacheMap::const_iterator& it) { m_cache.erase(it); } +void GalaxyObjectCache::Slave::Erase(const typename CacheMap::const_iterator &it) { m_cache.erase(it); } template -void GalaxyObjectCache::Slave::ClearCache() { m_cache.clear(); } +void GalaxyObjectCache::Slave::ClearCache() { m_cache.clear(); } template -GalaxyObjectCache::Slave::~Slave() +GalaxyObjectCache::Slave::~Slave() { -# ifdef DEBUG_CACHE - unsigned unique = 0; - for (auto it = m_cache.begin(); it != m_cache.end(); ++it) - if (it->second->GetRefCount() == 1) - unique++; - Output("%s: Discarding slave cache with " SIZET_FMT " entries (%u to be removed)\n", CACHE_NAME.c_str(), m_cache.size(), unique); -# endif +#ifdef DEBUG_CACHE + unsigned unique = 0; + for (auto it = m_cache.begin(); it != m_cache.end(); ++it) + if (it->second->GetRefCount() == 1) + unique++; + Output("%s: Discarding slave cache with " SIZET_FMT " entries (%u to be removed)\n", CACHE_NAME.c_str(), m_cache.size(), unique); +#endif if (m_master) m_master->m_slaves.erase(this); } template -void GalaxyObjectCache::Slave::AddToCache(std::vector >& objects) +void GalaxyObjectCache::Slave::AddToCache(std::vector> &objects) { if (m_master) { m_master->AddToCache(objects); // This modifies the vector to the sectors already in the master cache for (auto it = objects.begin(), itEnd = objects.end(); it != itEnd; ++it) { - m_cache.insert( std::make_pair(it->Get()->GetPath(), *it) ); + m_cache.insert(std::make_pair(it->Get()->GetPath(), *it)); } } } template -void GalaxyObjectCache::Slave::FillCache(const typename GalaxyObjectCache::PathVector& paths, - typename GalaxyObjectCache::CacheFilledCallback callback) +void GalaxyObjectCache::Slave::FillCache(const typename GalaxyObjectCache::PathVector &paths, + typename GalaxyObjectCache::CacheFilledCallback callback) { // allocate some space for what we're about to chunk up - std::vector > vec_paths; - vec_paths.reserve(paths.size()/CACHE_JOB_SIZE + 1); + std::vector> vec_paths; + vec_paths.reserve(paths.size() / CACHE_JOB_SIZE + 1); std::unique_ptr current_paths; -# ifdef DEBUG_CACHE - size_t alreadyCached = m_cache.size(); - unsigned masterCached = 0; - unsigned toBeCreated = 0; -# endif +#ifdef DEBUG_CACHE + size_t alreadyCached = m_cache.size(); + unsigned masterCached = 0; + unsigned toBeCreated = 0; +#endif // chop the paths into groups of CACHE_JOB_SIZE for (auto it = paths.begin(), itEnd = paths.end(); it != itEnd; ++it) { RefCountedPtr s = m_master->GetIfCached(*it); if (s) { m_cache[*it] = s; -# ifdef DEBUG_CACHE - ++masterCached; -# endif +#ifdef DEBUG_CACHE + ++masterCached; +#endif } else { if (!current_paths) { current_paths.reset(new PathVector); current_paths->reserve(CACHE_JOB_SIZE); } current_paths->push_back(*it); - if( current_paths->size() >= CACHE_JOB_SIZE ) { - vec_paths.push_back( std::move(current_paths) ); + if (current_paths->size() >= CACHE_JOB_SIZE) { + vec_paths.push_back(std::move(current_paths)); } -# ifdef DEBUG_CACHE - ++toBeCreated; -# endif +#ifdef DEBUG_CACHE + ++toBeCreated; +#endif } } // catch the last loop in case it's got some entries (could be less than the spread width) if (current_paths) { - vec_paths.push_back( std::move(current_paths) ); + vec_paths.push_back(std::move(current_paths)); } -# ifdef DEBUG_CACHE - Output("%s: FillCache: " SIZET_FMT " cached, %u in master cache, %u to be created, will use " SIZET_FMT " jobs\n", CACHE_NAME.c_str(), - alreadyCached, masterCached, toBeCreated, vec_paths.size()); -# endif +#ifdef DEBUG_CACHE + Output("%s: FillCache: " SIZET_FMT " cached, %u in master cache, %u to be created, will use " SIZET_FMT " jobs\n", CACHE_NAME.c_str(), + alreadyCached, masterCached, toBeCreated, vec_paths.size()); +#endif if (vec_paths.empty()) { if (callback) @@ -233,31 +235,35 @@ void GalaxyObjectCache::Slave::FillCache(const typename GalaxyObject } else { // now add the batched jobs for (auto it = vec_paths.begin(), itEnd = vec_paths.end(); it != itEnd; ++it) - m_jobs.Order(new GalaxyObjectCache::CacheJob(std::move(*it), this, m_galaxy, callback)); + m_jobs.Order(new GalaxyObjectCache::CacheJob(std::move(*it), this, m_galaxy, callback)); } } - template -GalaxyObjectCache::CacheJob::CacheJob(std::unique_ptr > path, - typename GalaxyObjectCache::Slave* slaveCache, RefCountedPtr galaxy, - typename GalaxyObjectCache::CacheFilledCallback callback) - : Job(), m_paths(std::move(path)), m_slaveCache(slaveCache), m_galaxy(galaxy), m_galaxyGenerator(galaxy->GetGenerator()), m_callback(callback) +GalaxyObjectCache::CacheJob::CacheJob(std::unique_ptr> path, + typename GalaxyObjectCache::Slave *slaveCache, RefCountedPtr galaxy, + typename GalaxyObjectCache::CacheFilledCallback callback) : + Job(), + m_paths(std::move(path)), + m_slaveCache(slaveCache), + m_galaxy(galaxy), + m_galaxyGenerator(galaxy->GetGenerator()), + m_callback(callback) { m_objects.reserve(m_paths->size()); } //virtual template -void GalaxyObjectCache::CacheJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! +void GalaxyObjectCache::CacheJob::OnRun() // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! { for (auto it = m_paths->begin(), itEnd = m_paths->end(); it != itEnd; ++it) - m_objects.push_back(m_galaxyGenerator->Generate>(m_galaxy, *it, nullptr)); + m_objects.push_back(m_galaxyGenerator->Generate>(m_galaxy, *it, nullptr)); } //virtual template -void GalaxyObjectCache::CacheJob::OnFinish() // runs in primary thread of the context +void GalaxyObjectCache::CacheJob::OnFinish() // runs in primary thread of the context { m_slaveCache->AddToCache(m_objects); if (m_slaveCache->m_jobs.IsEmpty() && m_callback) @@ -266,19 +272,23 @@ void GalaxyObjectCache::CacheJob::OnFinish() // runs in primary thr /****** SectorCache ******/ -template <> const std::string GalaxyObjectCache::CACHE_NAME("SectorCache"); +template <> +const std::string GalaxyObjectCache::CACHE_NAME("SectorCache"); -template class GalaxyObjectCache; +template class GalaxyObjectCache; /****** StarSystemCache ******/ template <> -GalaxyObjectCache::Slave::Slave(GalaxyObjectCache* master, RefCountedPtr galaxy, JobQueue* jobQueue) - : m_master(master), m_galaxy(galaxy), m_jobs(Pi::GetSyncJobQueue()) +GalaxyObjectCache::Slave::Slave(GalaxyObjectCache *master, RefCountedPtr galaxy, JobQueue *jobQueue) : + m_master(master), + m_galaxy(galaxy), + m_jobs(Pi::GetSyncJobQueue()) { m_master->m_slaves.insert(this); } -template <> const std::string GalaxyObjectCache::CACHE_NAME("StarSystemCache"); +template <> +const std::string GalaxyObjectCache::CACHE_NAME("StarSystemCache"); -template class GalaxyObjectCache; +template class GalaxyObjectCache; diff --git a/src/galaxy/GalaxyCache.h b/src/galaxy/GalaxyCache.h index c913db9e9..91e5289a4 100644 --- a/src/galaxy/GalaxyCache.h +++ b/src/galaxy/GalaxyCache.h @@ -4,16 +4,16 @@ #ifndef SECTORCACHE_H #define SECTORCACHE_H -#include -#include -#include -#include -#include -#include "libs.h" -#include "galaxy/SystemPath.h" -#include "graphics/Drawables.h" #include "JobQueue.h" #include "RefCounted.h" +#include "galaxy/SystemPath.h" +#include "graphics/Drawables.h" +#include "libs.h" +#include +#include +#include +#include +#include class GalaxyGenerator; class Galaxy; @@ -21,49 +21,55 @@ class Galaxy; template class GalaxyObjectCache { friend T; + public: static const std::string CACHE_NAME; - GalaxyObjectCache(Galaxy* galaxy) : m_galaxy(galaxy), m_cacheHits(0), m_cacheHitsSlave(0), m_cacheMisses(0) { } + GalaxyObjectCache(Galaxy *galaxy) : + m_galaxy(galaxy), + m_cacheHits(0), + m_cacheHitsSlave(0), + m_cacheMisses(0) {} ~GalaxyObjectCache(); - RefCountedPtr GetCached(const SystemPath& path); - RefCountedPtr GetIfCached(const SystemPath& path); + RefCountedPtr GetCached(const SystemPath &path); + RefCountedPtr GetIfCached(const SystemPath &path); - void ClearCache(); // Completely clear slave caches + void ClearCache(); // Completely clear slave caches bool IsEmpty() { return m_attic.empty(); } void OutputCacheStatistics(bool reset = true); typedef std::vector PathVector; - typedef std::map,CompareT> CacheMap; - typedef std::map AtticMap; + typedef std::map, CompareT> CacheMap; + typedef std::map AtticMap; typedef std::function CacheFilledCallback; class Slave : public RefCounted { - friend class GalaxyObjectCache; + friend class GalaxyObjectCache; + public: - RefCountedPtr GetCached(const SystemPath& path); - RefCountedPtr GetIfCached(const SystemPath& path); + RefCountedPtr GetCached(const SystemPath &path); + RefCountedPtr GetIfCached(const SystemPath &path); typename CacheMap::const_iterator Begin() const { return m_cache.begin(); } typename CacheMap::const_iterator End() const { return m_cache.end(); } - void FillCache(const PathVector& paths, CacheFilledCallback callback = CacheFilledCallback()); - void Erase(const SystemPath& path); - void Erase(const typename CacheMap::const_iterator& it); + void FillCache(const PathVector &paths, CacheFilledCallback callback = CacheFilledCallback()); + void Erase(const SystemPath &path); + void Erase(const typename CacheMap::const_iterator &it); void ClearCache(); bool IsEmpty() { return m_cache.empty(); } ~Slave(); private: - GalaxyObjectCache* m_master; + GalaxyObjectCache *m_master; RefCountedPtr m_galaxy; CacheMap m_cache; JobSet m_jobs; - Slave(GalaxyObjectCache* master, RefCountedPtr galaxy, JobQueue* jobQueue); + Slave(GalaxyObjectCache *master, RefCountedPtr galaxy, JobQueue *jobQueue); void MasterDeleted(); - void AddToCache(std::vector >& objects); + void AddToCache(std::vector> &objects); }; RefCountedPtr NewSlaveCache(); @@ -71,36 +77,35 @@ public: private: static const unsigned CACHE_JOB_SIZE = 100; - void AddToCache(std::vector >& objects); - bool HasCached(const SystemPath& path) const; - void RemoveFromAttic(const SystemPath& path); + void AddToCache(std::vector> &objects); + bool HasCached(const SystemPath &path) const; + void RemoveFromAttic(const SystemPath &path); // ******************************************************************************** // Overloaded Job class to handle generating a collection of sectors // ******************************************************************************** - class CacheJob : public Job - { + class CacheJob : public Job { public: - CacheJob(std::unique_ptr > path, Slave* slaveCache, RefCountedPtr galaxy, CacheFilledCallback callback = CacheFilledCallback()); + CacheJob(std::unique_ptr> path, Slave *slaveCache, RefCountedPtr galaxy, CacheFilledCallback callback = CacheFilledCallback()); - virtual void OnRun(); // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! - virtual void OnFinish(); // runs in primary thread of the context - virtual void OnCancel() {} // runs in primary thread of the context + virtual void OnRun(); // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! + virtual void OnFinish(); // runs in primary thread of the context + virtual void OnCancel() {} // runs in primary thread of the context protected: - std::unique_ptr > m_paths; - std::vector > m_objects; - Slave* m_slaveCache; + std::unique_ptr> m_paths; + std::vector> m_objects; + Slave *m_slaveCache; RefCountedPtr m_galaxy; RefCountedPtr m_galaxyGenerator; CacheFilledCallback m_callback; }; - Galaxy* m_galaxy; - std::set m_slaves; - AtticMap m_attic; // Those contains non-refcounted pointers which are kept alive by RefCountedPtrs in slave caches - // or elsewhere. The Sector destructor ensures that it is removed from here. - // This ensures, that there is only ever one object for each Sector. + Galaxy *m_galaxy; + std::set m_slaves; + AtticMap m_attic; // Those contains non-refcounted pointers which are kept alive by RefCountedPtrs in slave caches + // or elsewhere. The Sector destructor ensures that it is removed from here. + // This ensures, that there is only ever one object for each Sector. unsigned long long m_cacheHits; unsigned long long m_cacheHitsSlave; @@ -110,7 +115,6 @@ private: class Sector; typedef GalaxyObjectCache SectorCache; - class StarSystem; typedef GalaxyObjectCache StarSystemCache; diff --git a/src/galaxy/GalaxyGenerator.cpp b/src/galaxy/GalaxyGenerator.cpp index 23e766d76..bb68358de 100644 --- a/src/galaxy/GalaxyGenerator.cpp +++ b/src/galaxy/GalaxyGenerator.cpp @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Pi.h" -#include "galaxy/Galaxy.h" #include "GalaxyGenerator.h" -#include "SectorGenerator.h" -#include "galaxy/StarSystemGenerator.h" #include "GameSaveError.h" +#include "Pi.h" +#include "SectorGenerator.h" +#include "galaxy/Galaxy.h" +#include "galaxy/StarSystemGenerator.h" static const GalaxyGenerator::Version LAST_VERSION_LEGACY = 1; @@ -15,7 +15,7 @@ GalaxyGenerator::Version GalaxyGenerator::s_defaultVersion = LAST_VERSION_LEGACY RefCountedPtr GalaxyGenerator::s_galaxy; //static -void GalaxyGenerator::Init(const std::string& name, Version version) +void GalaxyGenerator::Init(const std::string &name, Version version) { s_defaultGenerator = name; s_defaultVersion = (version == LAST_VERSION) ? GetLastVersion(name) : version; @@ -30,7 +30,7 @@ void GalaxyGenerator::Uninit() } //static -GalaxyGenerator::Version GalaxyGenerator::GetLastVersion(const std::string& name) +GalaxyGenerator::Version GalaxyGenerator::GetLastVersion(const std::string &name) { if (name == "legacy") return LAST_VERSION_LEGACY; @@ -39,7 +39,7 @@ GalaxyGenerator::Version GalaxyGenerator::GetLastVersion(const std::string& name } // static -RefCountedPtr GalaxyGenerator::Create(const std::string& name, Version version) +RefCountedPtr GalaxyGenerator::Create(const std::string &name, Version version) { if (version == LAST_VERSION) version = GetLastVersion(name); @@ -49,13 +49,13 @@ RefCountedPtr GalaxyGenerator::Create(const std::string& name, Version v Output("Creating new galaxy generator '%s' version %d\n", name.c_str(), version); if (version == 0 || version == 1) { galgen.Reset((new GalaxyGenerator(name, version)) - ->AddSectorStage(new SectorCustomSystemsGenerator(CustomSystem::CUSTOM_ONLY_RADIUS)) - ->AddSectorStage(new SectorRandomSystemsGenerator) - ->AddSectorStage(new SectorPersistenceGenerator(version)) - ->AddStarSystemStage(new StarSystemFromSectorGenerator) - ->AddStarSystemStage(new StarSystemCustomGenerator) - ->AddStarSystemStage(new StarSystemRandomGenerator) - ->AddStarSystemStage(new PopulateStarSystemGenerator)); + ->AddSectorStage(new SectorCustomSystemsGenerator(CustomSystem::CUSTOM_ONLY_RADIUS)) + ->AddSectorStage(new SectorRandomSystemsGenerator) + ->AddSectorStage(new SectorPersistenceGenerator(version)) + ->AddStarSystemStage(new StarSystemFromSectorGenerator) + ->AddStarSystemStage(new StarSystemCustomGenerator) + ->AddStarSystemStage(new StarSystemRandomGenerator) + ->AddStarSystemStage(new PopulateStarSystemGenerator)); } } @@ -63,8 +63,8 @@ RefCountedPtr GalaxyGenerator::Create(const std::string& name, Version v if (s_galaxy && galgen->m_name == s_galaxy->GetGeneratorName() && galgen->m_version == s_galaxy->GetGeneratorVersion()) { Output("Clearing and re-using previous Galaxy object\n"); s_galaxy->SetGalaxyGenerator(galgen); - s_galaxy->FlushCaches(); - return s_galaxy; + s_galaxy->FlushCaches(); + return s_galaxy; } assert(name == "legacy"); // Once whe have have more, this will become an if switch @@ -108,15 +108,13 @@ void GalaxyGenerator::ToJson(Json &jsonObj, RefCountedPtr galaxy) galaxyGenObj["version"] = m_version; Json sectorStageArray = Json::array(); // Create JSON array to contain sector stage data. - for (SectorGeneratorStage* secgen : m_sectorStage) - { + for (SectorGeneratorStage *secgen : m_sectorStage) { Json sectorStageArrayEl({}); // Create JSON object to contain sector stage element. secgen->ToJson(sectorStageArrayEl, galaxy); sectorStageArray.push_back(sectorStageArrayEl); // Append sector stage object to array. } Json starSystemStageArray = Json::array(); // Create JSON array to contain system stage data. - for (StarSystemGeneratorStage* sysgen : m_starSystemStage) - { + for (StarSystemGeneratorStage *sysgen : m_starSystemStage) { Json starSystemStageArrayEl({}); // Create JSON object to contain system stage element. sysgen->ToJson(starSystemStageArrayEl, galaxy); starSystemStageArray.push_back(starSystemStageArrayEl); // Append system stage object to array. @@ -134,11 +132,11 @@ void GalaxyGenerator::FromJson(const Json &jsonObj, RefCountedPtr galaxy Json starSystemStageArray = jsonObj["star_system_stage"].get(); unsigned int arrayIndex = 0; - for (SectorGeneratorStage* secgen : m_sectorStage) - secgen->FromJson(sectorStageArray[arrayIndex++], galaxy); + for (SectorGeneratorStage *secgen : m_sectorStage) + secgen->FromJson(sectorStageArray[arrayIndex++], galaxy); arrayIndex = 0; - for (StarSystemGeneratorStage* sysgen : m_starSystemStage) - sysgen->FromJson(starSystemStageArray[arrayIndex++], galaxy); + for (StarSystemGeneratorStage *sysgen : m_starSystemStage) + sysgen->FromJson(starSystemStageArray[arrayIndex++], galaxy); } catch (Json::type_error &) { throw SavedGameCorruptException(); } @@ -146,39 +144,39 @@ void GalaxyGenerator::FromJson(const Json &jsonObj, RefCountedPtr galaxy GalaxyGenerator::~GalaxyGenerator() { - for (SectorGeneratorStage* secgen : m_sectorStage) + for (SectorGeneratorStage *secgen : m_sectorStage) delete secgen; - for (StarSystemGeneratorStage* sysgen : m_starSystemStage) + for (StarSystemGeneratorStage *sysgen : m_starSystemStage) delete sysgen; } -GalaxyGenerator* GalaxyGenerator::AddSectorStage(SectorGeneratorStage* sectorGenerator) +GalaxyGenerator *GalaxyGenerator::AddSectorStage(SectorGeneratorStage *sectorGenerator) { auto it = m_sectorStage.insert(m_sectorStage.end(), sectorGenerator); (*it)->AssignToGalaxyGenerator(this); return this; } -GalaxyGenerator* GalaxyGenerator::AddStarSystemStage(StarSystemGeneratorStage* starSystemGenerator) +GalaxyGenerator *GalaxyGenerator::AddStarSystemStage(StarSystemGeneratorStage *starSystemGenerator) { auto it = m_starSystemStage.insert(m_starSystemStage.end(), starSystemGenerator); (*it)->AssignToGalaxyGenerator(this); return this; } -RefCountedPtr GalaxyGenerator::GenerateSector(RefCountedPtr galaxy, const SystemPath& path, SectorCache* cache) +RefCountedPtr GalaxyGenerator::GenerateSector(RefCountedPtr galaxy, const SystemPath &path, SectorCache *cache) { const Uint32 _init[4] = { Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED }; Random rng(_init, 4); SectorConfig config; RefCountedPtr sector(new Sector(galaxy, path, cache)); - for (SectorGeneratorStage* secgen : m_sectorStage) + for (SectorGeneratorStage *secgen : m_sectorStage) if (!secgen->Apply(rng, galaxy, sector, &config)) break; return sector; } -RefCountedPtr GalaxyGenerator::GenerateStarSystem(RefCountedPtr galaxy, const SystemPath& path, StarSystemCache* cache) +RefCountedPtr GalaxyGenerator::GenerateStarSystem(RefCountedPtr galaxy, const SystemPath &path, StarSystemCache *cache) { RefCountedPtr sec = galaxy->GetSector(path); assert(path.systemIndex >= 0 && path.systemIndex < sec->m_systems.size()); @@ -188,7 +186,7 @@ RefCountedPtr GalaxyGenerator::GenerateStarSystem(RefCountedPtr system(new StarSystem::GeneratorAPI(path, galaxy, cache, rng)); - for (StarSystemGeneratorStage* sysgen : m_starSystemStage) + for (StarSystemGeneratorStage *sysgen : m_starSystemStage) if (!sysgen->Apply(rng, galaxy, system, &config)) break; return system; diff --git a/src/galaxy/GalaxyGenerator.h b/src/galaxy/GalaxyGenerator.h index 8513ccc39..1d689c432 100644 --- a/src/galaxy/GalaxyGenerator.h +++ b/src/galaxy/GalaxyGenerator.h @@ -4,12 +4,12 @@ #ifndef GALAXYGENERATOR_H #define GALAXYGENERATOR_H -#include -#include #include "RefCounted.h" #include "Sector.h" #include "StarSystem.h" #include "SystemPath.h" +#include +#include class SectorGeneratorStage; class StarSystemGeneratorStage; @@ -19,22 +19,23 @@ public: typedef int Version; static const Version LAST_VERSION = -1; - static void Init(const std::string& name = std::string("legacy"), Version version = LAST_VERSION); - static void Uninit(); + static void Init(const std::string &name = std::string("legacy"), Version version = LAST_VERSION); + static void Uninit(); - static RefCountedPtr Create(const std::string& name, Version version = LAST_VERSION); - static RefCountedPtr Create() { + static RefCountedPtr Create(const std::string &name, Version version = LAST_VERSION); + static RefCountedPtr Create() + { return Create(s_defaultGenerator, s_defaultVersion); } static RefCountedPtr CreateFromJson(const Json &jsonObj); static std::string GetDefaultGeneratorName() { return s_defaultGenerator; } static Version GetDefaultGeneratorVersion() { return s_defaultVersion; } - static Version GetLastVersion(const std::string& name); + static Version GetLastVersion(const std::string &name); virtual ~GalaxyGenerator(); - const std::string& GetName() const { return m_name; } + const std::string &GetName() const { return m_name; } Version GetVersion() const { return m_version; } bool IsDefault() const { return m_name == s_defaultGenerator && m_version == s_defaultVersion; } @@ -44,34 +45,38 @@ public: // Templated for the template cache class. template - RefCountedPtr Generate(RefCountedPtr galaxy, const SystemPath& path, Cache* cache); + RefCountedPtr Generate(RefCountedPtr galaxy, const SystemPath &path, Cache *cache); - GalaxyGenerator* AddSectorStage(SectorGeneratorStage* sectorGenerator); - GalaxyGenerator* AddStarSystemStage(StarSystemGeneratorStage* starSystemGenerator); + GalaxyGenerator *AddSectorStage(SectorGeneratorStage *sectorGenerator); + GalaxyGenerator *AddStarSystemStage(StarSystemGeneratorStage *starSystemGenerator); struct SectorConfig { bool isCustomOnly; - SectorConfig() : isCustomOnly(false) { } + SectorConfig() : + isCustomOnly(false) {} }; struct StarSystemConfig { bool isCustomOnly; - StarSystemConfig() : isCustomOnly(false) { } + StarSystemConfig() : + isCustomOnly(false) {} }; private: - GalaxyGenerator(const std::string& name, Version version = LAST_VERSION) : m_name(name), m_version(version) { } + GalaxyGenerator(const std::string &name, Version version = LAST_VERSION) : + m_name(name), + m_version(version) {} - virtual RefCountedPtr GenerateSector(RefCountedPtr galaxy, const SystemPath& path, SectorCache* cache); - virtual RefCountedPtr GenerateStarSystem(RefCountedPtr galaxy, const SystemPath& path, StarSystemCache* cache); + virtual RefCountedPtr GenerateSector(RefCountedPtr galaxy, const SystemPath &path, SectorCache *cache); + virtual RefCountedPtr GenerateStarSystem(RefCountedPtr galaxy, const SystemPath &path, StarSystemCache *cache); const std::string m_name; const Version m_version; - std::list m_sectorStage; - std::list m_starSystemStage; + std::list m_sectorStage; + std::list m_starSystemStage; static RefCountedPtr s_galaxy; static std::string s_defaultGenerator; @@ -79,43 +84,46 @@ private: }; template <> -inline RefCountedPtr GalaxyGenerator::Generate(RefCountedPtr galaxy, const SystemPath& path, SectorCache* cache) { +inline RefCountedPtr GalaxyGenerator::Generate(RefCountedPtr galaxy, const SystemPath &path, SectorCache *cache) +{ return GenerateSector(galaxy, path, cache); } template <> -inline RefCountedPtr GalaxyGenerator::Generate(RefCountedPtr galaxy, const SystemPath& path, StarSystemCache* cache) { +inline RefCountedPtr GalaxyGenerator::Generate(RefCountedPtr galaxy, const SystemPath &path, StarSystemCache *cache) +{ return GenerateStarSystem(galaxy, path, cache); } class GalaxyGeneratorStage { public: - virtual ~GalaxyGeneratorStage() { } + virtual ~GalaxyGeneratorStage() {} - virtual void ToJson(Json &jsonObj, RefCountedPtr galaxy) { } - virtual void FromJson(const Json &jsonObj, RefCountedPtr galaxy) { } + virtual void ToJson(Json &jsonObj, RefCountedPtr galaxy) {} + virtual void FromJson(const Json &jsonObj, RefCountedPtr galaxy) {} protected: - GalaxyGeneratorStage() : m_galaxyGenerator(nullptr) { } + GalaxyGeneratorStage() : + m_galaxyGenerator(nullptr) {} friend class GalaxyGenerator; - void AssignToGalaxyGenerator(GalaxyGenerator* galaxyGenerator) { m_galaxyGenerator = galaxyGenerator; } + void AssignToGalaxyGenerator(GalaxyGenerator *galaxyGenerator) { m_galaxyGenerator = galaxyGenerator; } - GalaxyGenerator* m_galaxyGenerator; + GalaxyGenerator *m_galaxyGenerator; }; class SectorGeneratorStage : public GalaxyGeneratorStage { public: - virtual ~SectorGeneratorStage() { } + virtual ~SectorGeneratorStage() {} - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config) = 0; + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config) = 0; }; class StarSystemGeneratorStage : public GalaxyGeneratorStage { public: - virtual ~StarSystemGeneratorStage() { } + virtual ~StarSystemGeneratorStage() {} - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config) = 0; + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config) = 0; }; #endif diff --git a/src/galaxy/Sector.cpp b/src/galaxy/Sector.cpp index 5f10704fd..982cbc67e 100644 --- a/src/galaxy/Sector.cpp +++ b/src/galaxy/Sector.cpp @@ -2,21 +2,25 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Sector.h" -#include "StarSystem.h" #include "CustomSystem.h" #include "Galaxy.h" +#include "StarSystem.h" +#include "EnumStrings.h" #include "Factions.h" #include "Pi.h" #include "utils.h" -#include "EnumStrings.h" const float Sector::SIZE = 8.f; //////////////////////// Sector -Sector::Sector(RefCountedPtr galaxy, const SystemPath& path, SectorCache* cache) - : sx(path.sectorX), sy(path.sectorY), sz(path.sectorZ), m_galaxy(galaxy), m_cache(cache) { } +Sector::Sector(RefCountedPtr galaxy, const SystemPath &path, SectorCache *cache) : + sx(path.sectorX), + sy(path.sectorY), + sz(path.sectorZ), + m_galaxy(galaxy), + m_cache(cache) {} Sector::~Sector() { @@ -28,15 +32,16 @@ float Sector::DistanceBetween(RefCountedPtr a, int sysIdxA, RefCou { PROFILE_SCOPED() vector3f dv = a->m_systems[sysIdxA].GetPosition() - b->m_systems[sysIdxB].GetPosition(); - dv += Sector::SIZE*vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz)); + dv += Sector::SIZE * vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz)); return dv.Length(); } -bool Sector::WithinBox(const int Xmin, const int Xmax, const int Ymin, const int Ymax, const int Zmin, const int Zmax) const { +bool Sector::WithinBox(const int Xmin, const int Xmax, const int Ymin, const int Ymax, const int Zmin, const int Zmax) const +{ PROFILE_SCOPED() - if(sx >= Xmin && sx <= Xmax) { - if(sy >= Ymin && sy <= Ymax) { - if(sz >= Zmin && sz <= Zmax) { + if (sx >= Xmin && sx <= Xmax) { + if (sy >= Ymin && sy <= Ymax) { + if (sz >= Zmin && sz <= Zmax) { return true; } } @@ -64,11 +69,11 @@ void Sector::System::SetExplored(StarSystem::ExplorationState e, double time) } } -void Sector::Dump(FILE* file, const char* indent) const +void Sector::Dump(FILE *file, const char *indent) const { fprintf(file, "Sector(%d,%d,%d) {\n", sx, sy, sz); fprintf(file, "\t" SIZET_FMT " systems\n", m_systems.size()); - for (const Sector::System& sys : m_systems) { + for (const Sector::System &sys : m_systems) { assert(sx == sys.sx && sy == sys.sy && sz == sys.sz); assert(sys.idx >= 0); fprintf(file, "\tSystem(%d,%d,%d,%u) {\n", sys.sx, sys.sy, sys.sz, sys.idx); @@ -98,11 +103,11 @@ void Sector::Dump(FILE* file, const char* indent) const fprintf(file, "}\n\n"); } -float Sector::System::DistanceBetween(const System* a, const System* b) +float Sector::System::DistanceBetween(const System *a, const System *b) { PROFILE_SCOPED() vector3f dv = a->GetPosition() - b->GetPosition(); - dv += Sector::SIZE*vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz)); + dv += Sector::SIZE * vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz)); return dv.Length(); } diff --git a/src/galaxy/Sector.h b/src/galaxy/Sector.h index f958f1ea2..4930ae33e 100644 --- a/src/galaxy/Sector.h +++ b/src/galaxy/Sector.h @@ -4,12 +4,12 @@ #ifndef _SECTOR_H #define _SECTOR_H -#include "libs.h" -#include "galaxy/SystemPath.h" -#include "galaxy/StarSystem.h" -#include "galaxy/CustomSystem.h" #include "GalaxyCache.h" #include "RefCounted.h" +#include "galaxy/CustomSystem.h" +#include "galaxy/StarSystem.h" +#include "galaxy/SystemPath.h" +#include "libs.h" #include #include @@ -36,23 +36,41 @@ public: class System { public: - System(Sector* sector, int x, int y, int z, Uint32 si) : sx(x), sy(y), sz(z), idx(si), m_sector(sector), - m_numStars(0), m_seed(0), m_customSys(nullptr), m_faction(nullptr), m_population(-1), - m_explored(StarSystem::eUNEXPLORED), m_exploredTime(0.0) {} + System(Sector *sector, int x, int y, int z, Uint32 si) : + sx(x), + sy(y), + sz(z), + idx(si), + m_sector(sector), + m_numStars(0), + m_seed(0), + m_customSys(nullptr), + m_faction(nullptr), + m_population(-1), + m_explored(StarSystem::eUNEXPLORED), + m_exploredTime(0.0) {} - static float DistanceBetween(const System* a, const System* b); + static float DistanceBetween(const System *a, const System *b); // Check that we've had our habitation status set - const std::string& GetName() const { return m_name; } - const std::vector& GetOtherNames() const { return m_other_names; } - const vector3f& GetPosition() const { return m_pos; } - vector3f GetFullPosition() const { return Sector::SIZE*vector3f(float(sx), float(sy), float(sz)) + m_pos; }; + const std::string &GetName() const { return m_name; } + const std::vector &GetOtherNames() const { return m_other_names; } + const vector3f &GetPosition() const { return m_pos; } + vector3f GetFullPosition() const { return Sector::SIZE * vector3f(float(sx), float(sy), float(sz)) + m_pos; }; unsigned GetNumStars() const { return m_numStars; } - SystemBody::BodyType GetStarType(unsigned i) const { assert(i < m_numStars); return m_starType[i]; } + SystemBody::BodyType GetStarType(unsigned i) const + { + assert(i < m_numStars); + return m_starType[i]; + } Uint32 GetSeed() const { return m_seed; } - const CustomSystem* GetCustomSystem() const { return m_customSys; } - const Faction* GetFaction() const { if (!m_faction) AssignFaction(); return m_faction; } + const CustomSystem *GetCustomSystem() const { return m_customSys; } + const Faction *GetFaction() const + { + if (!m_faction) AssignFaction(); + return m_faction; + } fixed GetPopulation() const { return m_population; } void SetPopulation(fixed pop) { m_population = pop; } StarSystem::ExplorationState GetExplored() const { return m_explored; } @@ -60,10 +78,12 @@ public: bool IsExplored() const { return m_explored != StarSystem::eUNEXPLORED; } void SetExplored(StarSystem::ExplorationState e, double time); - bool IsSameSystem(const SystemPath &b) const { + bool IsSameSystem(const SystemPath &b) const + { return sx == b.sectorX && sy == b.sectorY && sz == b.sectorZ && idx == b.systemIndex; } - bool InSameSector(const SystemPath &b) const { + bool InSameSector(const SystemPath &b) const + { return sx == b.sectorX && sy == b.sectorY && sz == b.sectorZ; } SystemPath GetPath() const { return SystemPath(sx, sy, sz, idx); } @@ -79,15 +99,15 @@ public: void AssignFaction() const; - Sector* m_sector; + Sector *m_sector; std::string m_name; std::vector m_other_names; vector3f m_pos; unsigned m_numStars; SystemBody::BodyType m_starType[4]; Uint32 m_seed; - const CustomSystem* m_customSys; - mutable const Faction* m_faction; // mutable because we only calculate on demand + const CustomSystem *m_customSys; + mutable const Faction *m_faction; // mutable because we only calculate on demand fixed m_population; StarSystem::ExplorationState m_explored; double m_exploredTime; @@ -95,20 +115,24 @@ public: std::vector m_systems; const int sx, sy, sz; - void Dump(FILE* file, const char* indent = "") const; + void Dump(FILE *file, const char *indent = "") const; - sigc::signal onSetExplorationState; + sigc::signal onSetExplorationState; private: - Sector(const Sector&); // non-copyable - Sector& operator=(const Sector&); // non-assignable + Sector(const Sector &); // non-copyable + Sector &operator=(const Sector &); // non-assignable RefCountedPtr m_galaxy; - SectorCache* m_cache; + SectorCache *m_cache; // Only SectorCache(Job) are allowed to create sectors - Sector(RefCountedPtr galaxy, const SystemPath& path, SectorCache* cache); - void SetCache(SectorCache* cache) { assert(!m_cache); m_cache = cache; } + Sector(RefCountedPtr galaxy, const SystemPath &path, SectorCache *cache); + void SetCache(SectorCache *cache) + { + assert(!m_cache); + m_cache = cache; + } // sets appropriate factions for all systems in the sector }; diff --git a/src/galaxy/SectorGenerator.cpp b/src/galaxy/SectorGenerator.cpp index 1a8ec2a24..9b796d6f4 100644 --- a/src/galaxy/SectorGenerator.cpp +++ b/src/galaxy/SectorGenerator.cpp @@ -1,45 +1,45 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Pi.h" -#include "DateTime.h" #include "SectorGenerator.h" #include "CustomSystem.h" -#include "Galaxy.h" +#include "DateTime.h" #include "Factions.h" +#include "Galaxy.h" #include "GameSaveError.h" +#include "Pi.h" -#define Square(x) ((x)*(x)) +#define Square(x) ((x) * (x)) static const unsigned int SYS_NAME_FRAGS = 32; static const char *sys_names[SYS_NAME_FRAGS] = -{ "en", "la", "can", "be", "and", "phi", "eth", "ol", "ve", "ho", "a", - "lia", "an", "ar", "ur", "mi", "in", "ti", "qu", "so", "ed", "ess", - "ex", "io", "ce", "ze", "fa", "ay", "wa", "da", "ack", "gre" }; + { "en", "la", "can", "be", "and", "phi", "eth", "ol", "ve", "ho", "a", + "lia", "an", "ar", "ur", "mi", "in", "ti", "qu", "so", "ed", "ess", + "ex", "io", "ce", "ze", "fa", "ay", "wa", "da", "ack", "gre" }; -bool SectorCustomSystemsGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config) +bool SectorCustomSystemsGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config) { const int sx = sector->sx; const int sy = sector->sy; const int sz = sector->sz; - const Sint64 dist = (1 + sx*sx + sy*sy + sz*sz); + const Sint64 dist = (1 + sx * sx + sy * sy + sz * sz); - if ((sx >= -m_customOnlyRadius) && (sx <= m_customOnlyRadius-1) && - (sy >= -m_customOnlyRadius) && (sy <= m_customOnlyRadius-1) && - (sz >= -m_customOnlyRadius) && (sz <= m_customOnlyRadius-1)) + if ((sx >= -m_customOnlyRadius) && (sx <= m_customOnlyRadius - 1) && + (sy >= -m_customOnlyRadius) && (sy <= m_customOnlyRadius - 1) && + (sz >= -m_customOnlyRadius) && (sz <= m_customOnlyRadius - 1)) config->isCustomOnly = true; - const std::vector &systems = galaxy->GetCustomSystems()->GetCustomSystemsForSector(sx, sy, sz); + const std::vector &systems = galaxy->GetCustomSystems()->GetCustomSystemsForSector(sx, sy, sz); if (systems.size() == 0) return true; Uint32 sysIdx = 0; - for (std::vector::const_iterator it = systems.begin(); it != systems.end(); ++it, ++sysIdx) { + for (std::vector::const_iterator it = systems.begin(); it != systems.end(); ++it, ++sysIdx) { const CustomSystem *cs = *it; Sector::System s(sector.Get(), sx, sy, sz, sysIdx); - s.m_pos = Sector::SIZE*cs->pos; + s.m_pos = Sector::SIZE * cs->pos; s.m_name = cs->name; s.m_other_names = cs->other_names; - for (s.m_numStars=0; s.m_numStarsnumStars; s.m_numStars++) { + for (s.m_numStars = 0; s.m_numStars < cs->numStars; s.m_numStars++) { if (cs->primaryType[s.m_numStars] == 0) break; s.m_starType[s.m_numStars] = cs->primaryType[s.m_numStars]; } @@ -51,7 +51,7 @@ bool SectorCustomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala * ~500ly - ~700ly (65-90 sectors): gradual * ~700ly+: unexplored */ - if (((dist <= Square(90)) && ( dist <= Square(65) || rng.Int32(dist) <= Square(40))) || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, sysIdx))) + if (((dist <= Square(90)) && (dist <= Square(65) || rng.Int32(dist) <= Square(40))) || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, sysIdx))) s.m_explored = StarSystem::eEXPLORED_AT_START; else s.m_explored = StarSystem::eUNEXPLORED; @@ -66,71 +66,71 @@ bool SectorCustomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala return true; } -const std::string SectorRandomSystemsGenerator::GenName(RefCountedPtr galaxy, const Sector& sec, Sector::System &sys, int si, Random &rng) +const std::string SectorRandomSystemsGenerator::GenName(RefCountedPtr galaxy, const Sector &sec, Sector::System &sys, int si, Random &rng) { std::string name; const int sx = sec.sx; const int sy = sec.sy; const int sz = sec.sz; - const int dist = std::max(std::max(abs(sx),abs(sy)),abs(sz)); + const int dist = std::max(std::max(abs(sx), abs(sy)), abs(sz)); int chance = 100; switch (sys.m_starType[0]) { - case SystemBody::TYPE_STAR_O: - case SystemBody::TYPE_STAR_B: break; - case SystemBody::TYPE_STAR_A: chance += dist; break; - case SystemBody::TYPE_STAR_F: chance += 2*dist; break; - case SystemBody::TYPE_STAR_G: chance += 4*dist; break; - case SystemBody::TYPE_STAR_K: chance += 8*dist; break; - case SystemBody::TYPE_STAR_O_GIANT: - case SystemBody::TYPE_STAR_B_GIANT: chance = 50; break; - case SystemBody::TYPE_STAR_A_GIANT: chance = int(0.2*dist); break; - case SystemBody::TYPE_STAR_F_GIANT: chance = int(0.4*dist); break; - case SystemBody::TYPE_STAR_G_GIANT: chance = int(0.5*dist); break; - case SystemBody::TYPE_STAR_K_GIANT: - case SystemBody::TYPE_STAR_M_GIANT: chance = dist; break; - case SystemBody::TYPE_STAR_O_SUPER_GIANT: - case SystemBody::TYPE_STAR_B_SUPER_GIANT: chance = 10; break; - case SystemBody::TYPE_STAR_A_SUPER_GIANT: - case SystemBody::TYPE_STAR_F_SUPER_GIANT: - case SystemBody::TYPE_STAR_G_SUPER_GIANT: - case SystemBody::TYPE_STAR_K_SUPER_GIANT: chance = 15; break; - case SystemBody::TYPE_STAR_M_SUPER_GIANT: chance = 20; break; - case SystemBody::TYPE_STAR_O_HYPER_GIANT: - case SystemBody::TYPE_STAR_B_HYPER_GIANT: - case SystemBody::TYPE_STAR_A_HYPER_GIANT: - case SystemBody::TYPE_STAR_F_HYPER_GIANT: - case SystemBody::TYPE_STAR_G_HYPER_GIANT: - case SystemBody::TYPE_STAR_K_HYPER_GIANT: - case SystemBody::TYPE_STAR_M_HYPER_GIANT: chance = 1; break; //Should give a nice name almost all the time - default: chance += 16*dist; break; + case SystemBody::TYPE_STAR_O: + case SystemBody::TYPE_STAR_B: break; + case SystemBody::TYPE_STAR_A: chance += dist; break; + case SystemBody::TYPE_STAR_F: chance += 2 * dist; break; + case SystemBody::TYPE_STAR_G: chance += 4 * dist; break; + case SystemBody::TYPE_STAR_K: chance += 8 * dist; break; + case SystemBody::TYPE_STAR_O_GIANT: + case SystemBody::TYPE_STAR_B_GIANT: chance = 50; break; + case SystemBody::TYPE_STAR_A_GIANT: chance = int(0.2 * dist); break; + case SystemBody::TYPE_STAR_F_GIANT: chance = int(0.4 * dist); break; + case SystemBody::TYPE_STAR_G_GIANT: chance = int(0.5 * dist); break; + case SystemBody::TYPE_STAR_K_GIANT: + case SystemBody::TYPE_STAR_M_GIANT: chance = dist; break; + case SystemBody::TYPE_STAR_O_SUPER_GIANT: + case SystemBody::TYPE_STAR_B_SUPER_GIANT: chance = 10; break; + case SystemBody::TYPE_STAR_A_SUPER_GIANT: + case SystemBody::TYPE_STAR_F_SUPER_GIANT: + case SystemBody::TYPE_STAR_G_SUPER_GIANT: + case SystemBody::TYPE_STAR_K_SUPER_GIANT: chance = 15; break; + case SystemBody::TYPE_STAR_M_SUPER_GIANT: chance = 20; break; + case SystemBody::TYPE_STAR_O_HYPER_GIANT: + case SystemBody::TYPE_STAR_B_HYPER_GIANT: + case SystemBody::TYPE_STAR_A_HYPER_GIANT: + case SystemBody::TYPE_STAR_F_HYPER_GIANT: + case SystemBody::TYPE_STAR_G_HYPER_GIANT: + case SystemBody::TYPE_STAR_K_HYPER_GIANT: + case SystemBody::TYPE_STAR_M_HYPER_GIANT: chance = 1; break; //Should give a nice name almost all the time + default: chance += 16 * dist; break; } Uint32 weight = rng.Int32(chance); if (weight < 500 || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, si))) { /* well done. you get a real name */ - int len = rng.Int32(2,3); - for (int i=0; i Morton Jordan Bennett Norris + snprintf(buf, sizeof(buf), "MJBN %d%+d%+d", rng.Int32(10, 999), sx, sy); // MJBN -> Morton Jordan Bennett Norris return buf; } else if (weight < 1200) { char buf[128]; - snprintf(buf, sizeof(buf), "SC %d%+d%+d", rng.Int32(1000,9999),sx,sy); + snprintf(buf, sizeof(buf), "SC %d%+d%+d", rng.Int32(1000, 9999), sx, sy); return buf; } else { char buf[128]; - snprintf(buf, sizeof(buf), "DSC %d%+d%+d", rng.Int32(1000,9999),sx,sy); + snprintf(buf, sizeof(buf), "DSC %d%+d%+d", rng.Int32(1000, 9999), sx, sy); return buf; } } -bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config) +bool SectorRandomSystemsGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config) { /* Always place random systems outside the core custom-only region */ if (config->isCustomOnly) @@ -140,24 +140,32 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala const int sy = sector->sy; const int sz = sector->sz; const int customCount = static_cast(sector->m_systems.size()); - const Sint64 dist = (1 + sx*sx + sy*sy + sz*sz); + const Sint64 dist = (1 + sx * sx + sy * sy + sz * sz); const Sint64 freq = (1 + sx * sx + sy * sy); - const int numSystems = (rng.Int32(4,20) * galaxy->GetSectorDensity(sx, sy, sz)) >> 8; + const int numSystems = (rng.Int32(4, 20) * galaxy->GetSectorDensity(sx, sy, sz)) >> 8; sector->m_systems.reserve(numSystems); - for (int i=0; i gala * ~500ly - ~700ly (65-90 sectors): gradual * ~700ly+: unexplored */ - if (((dist <= Square(90)) && ( dist <= Square(65) || rng.Int32(dist) <= Square(40))) || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, customCount + i))) + if (((dist <= Square(90)) && (dist <= Square(65) || rng.Int32(dist) <= Square(40))) || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, customCount + i))) s.m_explored = StarSystem::eEXPLORED_AT_START; else s.m_explored = StarSystem::eUNEXPLORED; // Frequencies are low enough that we probably don't need this anymore. - if (freq > Square(10)) - { + if (freq > Square(10)) { const Uint32 weight = rng.Int32(1000000); if (weight < 1) { - s.m_starType[0] = SystemBody::TYPE_STAR_IM_BH; // These frequencies are made up + s.m_starType[0] = SystemBody::TYPE_STAR_IM_BH; // These frequencies are made up } else if (weight < 3) { s.m_starType[0] = SystemBody::TYPE_STAR_S_BH; } else if (weight < 5) { @@ -231,7 +238,7 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala } else if (weight < 700) { s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; } else if (weight < 800) { - s.m_starType[0] = SystemBody::TYPE_STAR_O; // should be 1 but that is boring + s.m_starType[0] = SystemBody::TYPE_STAR_O; // should be 1 but that is boring } else if (weight < 2000) { // weight < 1300 / 20500 s.m_starType[0] = SystemBody::TYPE_STAR_B; } else if (weight < 8000) { // weight < 7300 @@ -244,7 +251,7 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala s.m_starType[0] = SystemBody::TYPE_STAR_K; } else if (weight < 250000) { // weight < 250000 s.m_starType[0] = SystemBody::TYPE_WHITE_DWARF; - } else if (weight < 900000) { //weight < 900000 + } else if (weight < 900000) { //weight < 900000 s.m_starType[0] = SystemBody::TYPE_STAR_M; } else { s.m_starType[0] = SystemBody::TYPE_BROWN_DWARF; @@ -281,10 +288,9 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala } } - if ((s.m_starType[0] <= SystemBody::TYPE_STAR_A) && (rng.Int32(10)==0)) { + if ((s.m_starType[0] <= SystemBody::TYPE_STAR_A) && (rng.Int32(10) == 0)) { // make primary a giant. never more than one giant in a system - if (freq > Square(10)) - { + if (freq > Square(10)) { const Uint32 weight = rng.Int32(1000); if (weight >= 999) { s.m_starType[0] = SystemBody::TYPE_STAR_B_HYPER_GIANT; @@ -311,13 +317,15 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala } else { s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; } - } else if (freq > Square(5)) s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; - else s.m_starType[0] = SystemBody::TYPE_STAR_M; + } else if (freq > Square(5)) + s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; + else + s.m_starType[0] = SystemBody::TYPE_STAR_M; //Output("%d: %d%\n", sx, sy); } - s.m_name = GenName(galaxy, *sector, s, customCount + i, rng); + s.m_name = GenName(galaxy, *sector, s, customCount + i, rng); //Output("%s: \n", s.m_name.c_str()); sector->m_systems.push_back(s); @@ -325,8 +333,7 @@ bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr gala return true; } - -void SectorPersistenceGenerator::SetExplored(Sector::System* sys, StarSystem::ExplorationState e, double time) +void SectorPersistenceGenerator::SetExplored(Sector::System *sys, StarSystem::ExplorationState e, double time) { if (e == StarSystem::eUNEXPLORED) { m_exploredSystems.erase(sys->GetPath()); @@ -334,7 +341,7 @@ void SectorPersistenceGenerator::SetExplored(Sector::System* sys, StarSystem::Ex m_exploredSystems[sys->GetPath()] = 0; } else { assert(e == StarSystem::eEXPLORED_BY_PLAYER); - Time::DateTime dt = Time::DateTime(3200,1,1,0,0,0) + Time::TimeDelta(time, Time::Second); + Time::DateTime dt = Time::DateTime(3200, 1, 1, 0, 0, 0) + Time::TimeDelta(time, Time::Second); int year, month, day; dt.GetDateParts(&year, &month, &day); Sint32 date = day | month << 5 | year << 9; @@ -342,10 +349,10 @@ void SectorPersistenceGenerator::SetExplored(Sector::System* sys, StarSystem::Ex } } -bool SectorPersistenceGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config) +bool SectorPersistenceGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config) { if (galaxy->IsInitialized()) { - for (Sector::System& secsys : sector->m_systems) { + for (Sector::System &secsys : sector->m_systems) { const auto iter = m_exploredSystems.find(SystemPath(secsys.sx, secsys.sy, secsys.sz, secsys.idx)); if (iter != m_exploredSystems.end()) { Sint32 date = iter->second; @@ -370,21 +377,23 @@ bool SectorPersistenceGenerator::Apply(Random& rng, RefCountedPtr galaxy void SectorPersistenceGenerator::FromJson(const Json &jsonObj, RefCountedPtr galaxy) { m_exploredSystems.clear(); - if (m_version < 1) { return; } + if (m_version < 1) { + return; + } // The layout of this data is really weird for historical reasons. // It used to be stored by a general System-information container type called PersistSystemData<>. - try { - Json dictArray = jsonObj["dict"].get(); - for (unsigned int arrayIndex = 0; arrayIndex < dictArray.size(); ++arrayIndex) { - const Json &dictArrayEl = dictArray[arrayIndex]; - SystemPath path = SystemPath::FromJson(dictArrayEl); - StrToAuto(&m_exploredSystems[path], dictArrayEl["value"]); - } - } catch (Json::type_error &) { - throw SavedGameCorruptException(); - } + try { + Json dictArray = jsonObj["dict"].get(); + for (unsigned int arrayIndex = 0; arrayIndex < dictArray.size(); ++arrayIndex) { + const Json &dictArrayEl = dictArray[arrayIndex]; + SystemPath path = SystemPath::FromJson(dictArrayEl); + StrToAuto(&m_exploredSystems[path], dictArrayEl["value"]); + } + } catch (Json::type_error &) { + throw SavedGameCorruptException(); + } } void SectorPersistenceGenerator::ToJson(Json &jsonObj, RefCountedPtr galaxy) diff --git a/src/galaxy/SectorGenerator.h b/src/galaxy/SectorGenerator.h index 6f1b8895c..35f6620d2 100644 --- a/src/galaxy/SectorGenerator.h +++ b/src/galaxy/SectorGenerator.h @@ -4,16 +4,17 @@ #ifndef SECTORGENERATOR_H #define SECTORGENERATOR_H +#include "GalaxyGenerator.h" #include "Random.h" #include "RefCounted.h" #include "Sector.h" -#include "GalaxyGenerator.h" #include "StarSystem.h" class SectorCustomSystemsGenerator : public SectorGeneratorStage { public: - SectorCustomSystemsGenerator(int customOnlyRadius) : m_customOnlyRadius(customOnlyRadius) { } - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config); + SectorCustomSystemsGenerator(int customOnlyRadius) : + m_customOnlyRadius(customOnlyRadius) {} + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config); private: int m_customOnlyRadius; @@ -21,20 +22,22 @@ private: class SectorRandomSystemsGenerator : public SectorGeneratorStage { public: - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config); + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config); + private: - const std::string GenName(RefCountedPtr galaxy, const Sector& sec, Sector::System &sys, int si, Random &rand); + const std::string GenName(RefCountedPtr galaxy, const Sector &sec, Sector::System &sys, int si, Random &rand); }; class SectorPersistenceGenerator : public SectorGeneratorStage { public: - SectorPersistenceGenerator(GalaxyGenerator::Version version) : m_version(version) { } - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig* config); + SectorPersistenceGenerator(GalaxyGenerator::Version version) : + m_version(version) {} + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr sector, GalaxyGenerator::SectorConfig *config); virtual void FromJson(const Json &jsonObj, RefCountedPtr galaxy); virtual void ToJson(Json &jsonObj, RefCountedPtr galaxy); private: - void SetExplored(Sector::System* sys, StarSystem::ExplorationState e, double time); + void SetExplored(Sector::System *sys, StarSystem::ExplorationState e, double time); const GalaxyGenerator::Version m_version; diff --git a/src/galaxy/StarSystem.cpp b/src/galaxy/StarSystem.cpp index ea9774038..df9dfcd0f 100644 --- a/src/galaxy/StarSystem.cpp +++ b/src/galaxy/StarSystem.cpp @@ -2,690 +2,709 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "StarSystem.h" -#include "Sector.h" +#include "Factions.h" #include "Galaxy.h" #include "GalaxyCache.h" #include "GalaxyGenerator.h" -#include "Factions.h" +#include "Sector.h" -#include "Pi.h" -#include "LuaEvent.h" -#include "enum_table.h" -#include "utils.h" -#include "Orbit.h" -#include "Lang.h" -#include "StringF.h" #include "EnumStrings.h" #include "GameSaveError.h" +#include "Lang.h" +#include "LuaEvent.h" +#include "Orbit.h" +#include "Pi.h" +#include "StringF.h" +#include "enum_table.h" +#include "utils.h" #include +#include #include #include -#include //#define DEBUG_DUMP -namespace -{ - bool InvalidSystemNameChar (char c) - { - return !( - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9')); - } -} +namespace { + bool InvalidSystemNameChar(char c) + { + return !( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9')); + } +} // namespace // indexed by enum type turd const Color StarSystem::starColors[] = { - { 0, 0, 0 }, // gravpoint - { 128, 0, 0 }, // brown dwarf - { 102, 102, 204 }, // white dwarf - { 255, 51, 0 }, // M - { 255, 153, 26 }, // K - { 255, 255, 102 }, // G - { 255, 255, 204 }, // F - { 255, 255, 255 }, // A - { 178, 178, 255 }, // B - { 255, 178, 255 }, // O - { 255, 51, 0 }, // M Giant - { 255, 153, 26 }, // K Giant - { 255, 255, 102 }, // G Giant - { 255, 255, 204 }, // F Giant - { 255, 255, 255 }, // A Giant - { 178, 178, 255 }, // B Giant - { 255, 178, 255 }, // O Giant - { 255, 51, 0 }, // M Super Giant - { 255, 153, 26 }, // K Super Giant - { 255, 255, 102 }, // G Super Giant - { 255, 255, 204 }, // F Super Giant - { 255, 255, 255 }, // A Super Giant - { 178, 178, 255 }, // B Super Giant - { 255, 178, 255 }, // O Super Giant - { 255, 51, 0 }, // M Hyper Giant - { 255, 153, 26 }, // K Hyper Giant - { 255, 255, 102 }, // G Hyper Giant - { 255, 255, 204 }, // F Hyper Giant - { 255, 255, 255 }, // A Hyper Giant - { 178, 178, 255 }, // B Hyper Giant - { 255, 178, 255 }, // O Hyper Giant - { 255, 51, 0 }, // Red/M Wolf Rayet Star - { 178, 178, 255 }, // Blue/B Wolf Rayet Star - { 255, 178, 255 }, // Purple-Blue/O Wolf Rayet Star - { 76, 178, 76 }, // Stellar Blackhole - { 51, 230, 51 }, // Intermediate mass Black-hole - { 0, 255, 0 } // Super massive black hole + { 0, 0, 0 }, // gravpoint + { 128, 0, 0 }, // brown dwarf + { 102, 102, 204 }, // white dwarf + { 255, 51, 0 }, // M + { 255, 153, 26 }, // K + { 255, 255, 102 }, // G + { 255, 255, 204 }, // F + { 255, 255, 255 }, // A + { 178, 178, 255 }, // B + { 255, 178, 255 }, // O + { 255, 51, 0 }, // M Giant + { 255, 153, 26 }, // K Giant + { 255, 255, 102 }, // G Giant + { 255, 255, 204 }, // F Giant + { 255, 255, 255 }, // A Giant + { 178, 178, 255 }, // B Giant + { 255, 178, 255 }, // O Giant + { 255, 51, 0 }, // M Super Giant + { 255, 153, 26 }, // K Super Giant + { 255, 255, 102 }, // G Super Giant + { 255, 255, 204 }, // F Super Giant + { 255, 255, 255 }, // A Super Giant + { 178, 178, 255 }, // B Super Giant + { 255, 178, 255 }, // O Super Giant + { 255, 51, 0 }, // M Hyper Giant + { 255, 153, 26 }, // K Hyper Giant + { 255, 255, 102 }, // G Hyper Giant + { 255, 255, 204 }, // F Hyper Giant + { 255, 255, 255 }, // A Hyper Giant + { 178, 178, 255 }, // B Hyper Giant + { 255, 178, 255 }, // O Hyper Giant + { 255, 51, 0 }, // Red/M Wolf Rayet Star + { 178, 178, 255 }, // Blue/B Wolf Rayet Star + { 255, 178, 255 }, // Purple-Blue/O Wolf Rayet Star + { 76, 178, 76 }, // Stellar Blackhole + { 51, 230, 51 }, // Intermediate mass Black-hole + { 0, 255, 0 } // Super massive black hole }; // indexed by enum type turd const Color StarSystem::starRealColors[] = { - { 0, 0, 0 }, // gravpoint - { 128, 0, 0 }, // brown dwarf - { 255, 255, 255 }, // white dwarf - { 255, 128, 51 }, // M - { 255, 255, 102 }, // K - { 255, 255, 242 }, // G - { 255, 255, 255 }, // F - { 255, 255, 255 }, // A - { 204, 204, 255 }, // B - { 255, 204, 255 }, // O - { 255, 128, 51 }, // M Giant - { 255, 255, 102 }, // K Giant - { 255, 255, 242 }, // G Giant - { 255, 255, 255 }, // F Giant - { 255, 255, 255 }, // A Giant - { 204, 204, 255 }, // B Giant - { 255, 204, 255 }, // O Giant - { 255, 128, 51 }, // M Super Giant - { 255, 255, 102 }, // K Super Giant - { 255, 255, 242 }, // G Super Giant - { 255, 255, 255 }, // F Super Giant - { 255, 255, 255 }, // A Super Giant - { 204, 204, 255 }, // B Super Giant - { 255, 204, 255 }, // O Super Giant - { 255, 128, 51 }, // M Hyper Giant - { 255, 255, 102 }, // K Hyper Giant - { 255, 255, 242 }, // G Hyper Giant - { 255, 255, 255 }, // F Hyper Giant - { 255, 255, 255 }, // A Hyper Giant - { 204, 204, 255 }, // B Hyper Giant - { 255, 204, 255 }, // O Hyper Giant - { 255, 153, 153 }, // M WF - { 204, 204, 255 }, // B WF - { 255, 204, 255 }, // O WF - { 22, 0, 24 }, // small Black hole - { 16, 0, 20 }, // med BH - { 10, 0, 16 } // massive BH + { 0, 0, 0 }, // gravpoint + { 128, 0, 0 }, // brown dwarf + { 255, 255, 255 }, // white dwarf + { 255, 128, 51 }, // M + { 255, 255, 102 }, // K + { 255, 255, 242 }, // G + { 255, 255, 255 }, // F + { 255, 255, 255 }, // A + { 204, 204, 255 }, // B + { 255, 204, 255 }, // O + { 255, 128, 51 }, // M Giant + { 255, 255, 102 }, // K Giant + { 255, 255, 242 }, // G Giant + { 255, 255, 255 }, // F Giant + { 255, 255, 255 }, // A Giant + { 204, 204, 255 }, // B Giant + { 255, 204, 255 }, // O Giant + { 255, 128, 51 }, // M Super Giant + { 255, 255, 102 }, // K Super Giant + { 255, 255, 242 }, // G Super Giant + { 255, 255, 255 }, // F Super Giant + { 255, 255, 255 }, // A Super Giant + { 204, 204, 255 }, // B Super Giant + { 255, 204, 255 }, // O Super Giant + { 255, 128, 51 }, // M Hyper Giant + { 255, 255, 102 }, // K Hyper Giant + { 255, 255, 242 }, // G Hyper Giant + { 255, 255, 255 }, // F Hyper Giant + { 255, 255, 255 }, // A Hyper Giant + { 204, 204, 255 }, // B Hyper Giant + { 255, 204, 255 }, // O Hyper Giant + { 255, 153, 153 }, // M WF + { 204, 204, 255 }, // B WF + { 255, 204, 255 }, // O WF + { 22, 0, 24 }, // small Black hole + { 16, 0, 20 }, // med BH + { 10, 0, 16 } // massive BH }; const double StarSystem::starLuminosities[] = { - 0, - 0.0003, // brown dwarf - 0.1, // white dwarf - 0.08, // M0 - 0.38, // K0 - 1.2, // G0 - 5.1, // F0 - 24.0, // A0 - 100.0, // B0 - 200.0, // O5 - 1000.0, // M0 Giant - 2000.0, // K0 Giant - 4000.0, // G0 Giant - 6000.0, // F0 Giant - 8000.0, // A0 Giant - 9000.0, // B0 Giant - 12000.0, // O5 Giant - 12000.0, // M0 Super Giant - 14000.0, // K0 Super Giant - 18000.0, // G0 Super Giant - 24000.0, // F0 Super Giant - 30000.0, // A0 Super Giant - 50000.0, // B0 Super Giant - 100000.0, // O5 Super Giant - 125000.0, // M0 Hyper Giant - 150000.0, // K0 Hyper Giant - 175000.0, // G0 Hyper Giant - 200000.0, // F0 Hyper Giant - 200000.0, // A0 Hyper Giant - 200000.0, // B0 Hyper Giant - 200000.0, // O5 Hyper Giant - 50000.0, // M WF - 100000.0, // B WF - 200000.0, // O WF - 0.0003, // Stellar Black hole - 0.00003, // IM Black hole - 0.000003, // Supermassive Black hole + 0, + 0.0003, // brown dwarf + 0.1, // white dwarf + 0.08, // M0 + 0.38, // K0 + 1.2, // G0 + 5.1, // F0 + 24.0, // A0 + 100.0, // B0 + 200.0, // O5 + 1000.0, // M0 Giant + 2000.0, // K0 Giant + 4000.0, // G0 Giant + 6000.0, // F0 Giant + 8000.0, // A0 Giant + 9000.0, // B0 Giant + 12000.0, // O5 Giant + 12000.0, // M0 Super Giant + 14000.0, // K0 Super Giant + 18000.0, // G0 Super Giant + 24000.0, // F0 Super Giant + 30000.0, // A0 Super Giant + 50000.0, // B0 Super Giant + 100000.0, // O5 Super Giant + 125000.0, // M0 Hyper Giant + 150000.0, // K0 Hyper Giant + 175000.0, // G0 Hyper Giant + 200000.0, // F0 Hyper Giant + 200000.0, // A0 Hyper Giant + 200000.0, // B0 Hyper Giant + 200000.0, // O5 Hyper Giant + 50000.0, // M WF + 100000.0, // B WF + 200000.0, // O WF + 0.0003, // Stellar Black hole + 0.00003, // IM Black hole + 0.000003, // Supermassive Black hole }; -const float StarSystem::starScale[] = { // Used in sector view - 0, - 0.6f, // brown dwarf - 0.5f, // white dwarf - 0.7f, // M - 0.8f, // K - 0.8f, // G - 0.9f, // F - 1.0f, // A - 1.1f, // B - 1.1f, // O - 1.3f, // M Giant - 1.2f, // K G - 1.2f, // G G - 1.2f, // F G - 1.1f, // A G - 1.1f, // B G - 1.2f, // O G - 1.8f, // M Super Giant - 1.6f, // K SG - 1.5f, // G SG - 1.5f, // F SG - 1.4f, // A SG - 1.3f, // B SG - 1.3f, // O SG - 2.5f, // M Hyper Giant - 2.2f, // K HG - 2.2f, // G HG - 2.1f, // F HG - 2.1f, // A HG - 2.0f, // B HG - 1.9f, // O HG - 1.1f, // M WF - 1.3f, // B WF - 1.6f, // O WF - 1.0f, // Black hole - 2.5f, // Intermediate-mass blackhole - 4.0f // Supermassive blackhole +const float StarSystem::starScale[] = { + // Used in sector view + 0, + 0.6f, // brown dwarf + 0.5f, // white dwarf + 0.7f, // M + 0.8f, // K + 0.8f, // G + 0.9f, // F + 1.0f, // A + 1.1f, // B + 1.1f, // O + 1.3f, // M Giant + 1.2f, // K G + 1.2f, // G G + 1.2f, // F G + 1.1f, // A G + 1.1f, // B G + 1.2f, // O G + 1.8f, // M Super Giant + 1.6f, // K SG + 1.5f, // G SG + 1.5f, // F SG + 1.4f, // A SG + 1.3f, // B SG + 1.3f, // O SG + 2.5f, // M Hyper Giant + 2.2f, // K HG + 2.2f, // G HG + 2.1f, // F HG + 2.1f, // A HG + 2.0f, // B HG + 1.9f, // O HG + 1.1f, // M WF + 1.3f, // B WF + 1.6f, // O WF + 1.0f, // Black hole + 2.5f, // Intermediate-mass blackhole + 4.0f // Supermassive blackhole }; SystemBody::BodySuperType SystemBody::GetSuperType() const { - PROFILE_SCOPED() - switch (m_type) { - case TYPE_BROWN_DWARF: - case TYPE_WHITE_DWARF: - case TYPE_STAR_M: - case TYPE_STAR_K: - case TYPE_STAR_G: - case TYPE_STAR_F: - case TYPE_STAR_A: - case TYPE_STAR_B: - case TYPE_STAR_O: - case TYPE_STAR_M_GIANT: - case TYPE_STAR_K_GIANT: - case TYPE_STAR_G_GIANT: - case TYPE_STAR_F_GIANT: - case TYPE_STAR_A_GIANT: - case TYPE_STAR_B_GIANT: - case TYPE_STAR_O_GIANT: - case TYPE_STAR_M_SUPER_GIANT: - case TYPE_STAR_K_SUPER_GIANT: - case TYPE_STAR_G_SUPER_GIANT: - case TYPE_STAR_F_SUPER_GIANT: - case TYPE_STAR_A_SUPER_GIANT: - case TYPE_STAR_B_SUPER_GIANT: - case TYPE_STAR_O_SUPER_GIANT: - case TYPE_STAR_M_HYPER_GIANT: - case TYPE_STAR_K_HYPER_GIANT: - case TYPE_STAR_G_HYPER_GIANT: - case TYPE_STAR_F_HYPER_GIANT: - case TYPE_STAR_A_HYPER_GIANT: - case TYPE_STAR_B_HYPER_GIANT: - case TYPE_STAR_O_HYPER_GIANT: - case TYPE_STAR_M_WF: - case TYPE_STAR_B_WF: - case TYPE_STAR_O_WF: - case TYPE_STAR_S_BH: - case TYPE_STAR_IM_BH: - case TYPE_STAR_SM_BH: - return SUPERTYPE_STAR; - case TYPE_PLANET_GAS_GIANT: - return SUPERTYPE_GAS_GIANT; - case TYPE_PLANET_ASTEROID: - case TYPE_PLANET_TERRESTRIAL: - return SUPERTYPE_ROCKY_PLANET; - case TYPE_STARPORT_ORBITAL: - case TYPE_STARPORT_SURFACE: - return SUPERTYPE_STARPORT; - case TYPE_GRAVPOINT: - return SUPERTYPE_NONE; - default: - Output("Warning: Invalid SuperBody Type found.\n"); - return SUPERTYPE_NONE; - } + PROFILE_SCOPED() + switch (m_type) { + case TYPE_BROWN_DWARF: + case TYPE_WHITE_DWARF: + case TYPE_STAR_M: + case TYPE_STAR_K: + case TYPE_STAR_G: + case TYPE_STAR_F: + case TYPE_STAR_A: + case TYPE_STAR_B: + case TYPE_STAR_O: + case TYPE_STAR_M_GIANT: + case TYPE_STAR_K_GIANT: + case TYPE_STAR_G_GIANT: + case TYPE_STAR_F_GIANT: + case TYPE_STAR_A_GIANT: + case TYPE_STAR_B_GIANT: + case TYPE_STAR_O_GIANT: + case TYPE_STAR_M_SUPER_GIANT: + case TYPE_STAR_K_SUPER_GIANT: + case TYPE_STAR_G_SUPER_GIANT: + case TYPE_STAR_F_SUPER_GIANT: + case TYPE_STAR_A_SUPER_GIANT: + case TYPE_STAR_B_SUPER_GIANT: + case TYPE_STAR_O_SUPER_GIANT: + case TYPE_STAR_M_HYPER_GIANT: + case TYPE_STAR_K_HYPER_GIANT: + case TYPE_STAR_G_HYPER_GIANT: + case TYPE_STAR_F_HYPER_GIANT: + case TYPE_STAR_A_HYPER_GIANT: + case TYPE_STAR_B_HYPER_GIANT: + case TYPE_STAR_O_HYPER_GIANT: + case TYPE_STAR_M_WF: + case TYPE_STAR_B_WF: + case TYPE_STAR_O_WF: + case TYPE_STAR_S_BH: + case TYPE_STAR_IM_BH: + case TYPE_STAR_SM_BH: + return SUPERTYPE_STAR; + case TYPE_PLANET_GAS_GIANT: + return SUPERTYPE_GAS_GIANT; + case TYPE_PLANET_ASTEROID: + case TYPE_PLANET_TERRESTRIAL: + return SUPERTYPE_ROCKY_PLANET; + case TYPE_STARPORT_ORBITAL: + case TYPE_STARPORT_SURFACE: + return SUPERTYPE_STARPORT; + case TYPE_GRAVPOINT: + return SUPERTYPE_NONE; + default: + Output("Warning: Invalid SuperBody Type found.\n"); + return SUPERTYPE_NONE; + } } std::string SystemBody::GetAstroDescription() const { - PROFILE_SCOPED() - switch (m_type) - { - case TYPE_BROWN_DWARF: return Lang::BROWN_DWARF; - case TYPE_WHITE_DWARF: return Lang::WHITE_DWARF; - case TYPE_STAR_M: return Lang::STAR_M; - case TYPE_STAR_K: return Lang::STAR_K; - case TYPE_STAR_G: return Lang::STAR_G; - case TYPE_STAR_F: return Lang::STAR_F; - case TYPE_STAR_A: return Lang::STAR_A; - case TYPE_STAR_B: return Lang::STAR_B; - case TYPE_STAR_O: return Lang::STAR_O; - case TYPE_STAR_M_GIANT: return Lang::STAR_M_GIANT; - case TYPE_STAR_K_GIANT: return Lang::STAR_K_GIANT; - case TYPE_STAR_G_GIANT: return Lang::STAR_G_GIANT; - case TYPE_STAR_F_GIANT: return Lang::STAR_AF_GIANT; - case TYPE_STAR_A_GIANT: return Lang::STAR_AF_GIANT; - case TYPE_STAR_B_GIANT: return Lang::STAR_B_GIANT; - case TYPE_STAR_O_GIANT: return Lang::STAR_O_GIANT; - case TYPE_STAR_M_SUPER_GIANT: return Lang::STAR_M_SUPER_GIANT; - case TYPE_STAR_K_SUPER_GIANT: return Lang::STAR_K_SUPER_GIANT; - case TYPE_STAR_G_SUPER_GIANT: return Lang::STAR_G_SUPER_GIANT; - case TYPE_STAR_F_SUPER_GIANT: return Lang::STAR_AF_SUPER_GIANT; - case TYPE_STAR_A_SUPER_GIANT: return Lang::STAR_AF_SUPER_GIANT; - case TYPE_STAR_B_SUPER_GIANT: return Lang::STAR_B_SUPER_GIANT; - case TYPE_STAR_O_SUPER_GIANT: return Lang::STAR_O_SUPER_GIANT; - case TYPE_STAR_M_HYPER_GIANT: return Lang::STAR_M_HYPER_GIANT; - case TYPE_STAR_K_HYPER_GIANT: return Lang::STAR_K_HYPER_GIANT; - case TYPE_STAR_G_HYPER_GIANT: return Lang::STAR_G_HYPER_GIANT; - case TYPE_STAR_F_HYPER_GIANT: return Lang::STAR_AF_HYPER_GIANT; - case TYPE_STAR_A_HYPER_GIANT: return Lang::STAR_AF_HYPER_GIANT; - case TYPE_STAR_B_HYPER_GIANT: return Lang::STAR_B_HYPER_GIANT; - case TYPE_STAR_O_HYPER_GIANT: return Lang::STAR_O_HYPER_GIANT; - case TYPE_STAR_M_WF: return Lang::STAR_M_WF; - case TYPE_STAR_B_WF: return Lang::STAR_B_WF; - case TYPE_STAR_O_WF: return Lang::STAR_O_WF; - case TYPE_STAR_S_BH: return Lang::STAR_S_BH; - case TYPE_STAR_IM_BH: return Lang::STAR_IM_BH; - case TYPE_STAR_SM_BH: return Lang::STAR_SM_BH; - case TYPE_PLANET_GAS_GIANT: - if (m_mass > 800) return Lang::VERY_LARGE_GAS_GIANT; - if (m_mass > 300) return Lang::LARGE_GAS_GIANT; - if (m_mass > 80) return Lang::MEDIUM_GAS_GIANT; - else return Lang::SMALL_GAS_GIANT; - case TYPE_PLANET_ASTEROID: return Lang::ASTEROID; - case TYPE_PLANET_TERRESTRIAL: - { - std::string s; - if (m_mass > fixed(2,1)) - s = Lang::MASSIVE; - else if (m_mass > fixed(3,2)) - s = Lang::LARGE; - else if (m_mass < fixed(1,10)) - s = Lang::TINY; - else if (m_mass < fixed(1,5)) - s = Lang::SMALL; + PROFILE_SCOPED() + switch (m_type) { + case TYPE_BROWN_DWARF: return Lang::BROWN_DWARF; + case TYPE_WHITE_DWARF: return Lang::WHITE_DWARF; + case TYPE_STAR_M: return Lang::STAR_M; + case TYPE_STAR_K: return Lang::STAR_K; + case TYPE_STAR_G: return Lang::STAR_G; + case TYPE_STAR_F: return Lang::STAR_F; + case TYPE_STAR_A: return Lang::STAR_A; + case TYPE_STAR_B: return Lang::STAR_B; + case TYPE_STAR_O: return Lang::STAR_O; + case TYPE_STAR_M_GIANT: return Lang::STAR_M_GIANT; + case TYPE_STAR_K_GIANT: return Lang::STAR_K_GIANT; + case TYPE_STAR_G_GIANT: return Lang::STAR_G_GIANT; + case TYPE_STAR_F_GIANT: return Lang::STAR_AF_GIANT; + case TYPE_STAR_A_GIANT: return Lang::STAR_AF_GIANT; + case TYPE_STAR_B_GIANT: return Lang::STAR_B_GIANT; + case TYPE_STAR_O_GIANT: return Lang::STAR_O_GIANT; + case TYPE_STAR_M_SUPER_GIANT: return Lang::STAR_M_SUPER_GIANT; + case TYPE_STAR_K_SUPER_GIANT: return Lang::STAR_K_SUPER_GIANT; + case TYPE_STAR_G_SUPER_GIANT: return Lang::STAR_G_SUPER_GIANT; + case TYPE_STAR_F_SUPER_GIANT: return Lang::STAR_AF_SUPER_GIANT; + case TYPE_STAR_A_SUPER_GIANT: return Lang::STAR_AF_SUPER_GIANT; + case TYPE_STAR_B_SUPER_GIANT: return Lang::STAR_B_SUPER_GIANT; + case TYPE_STAR_O_SUPER_GIANT: return Lang::STAR_O_SUPER_GIANT; + case TYPE_STAR_M_HYPER_GIANT: return Lang::STAR_M_HYPER_GIANT; + case TYPE_STAR_K_HYPER_GIANT: return Lang::STAR_K_HYPER_GIANT; + case TYPE_STAR_G_HYPER_GIANT: return Lang::STAR_G_HYPER_GIANT; + case TYPE_STAR_F_HYPER_GIANT: return Lang::STAR_AF_HYPER_GIANT; + case TYPE_STAR_A_HYPER_GIANT: return Lang::STAR_AF_HYPER_GIANT; + case TYPE_STAR_B_HYPER_GIANT: return Lang::STAR_B_HYPER_GIANT; + case TYPE_STAR_O_HYPER_GIANT: return Lang::STAR_O_HYPER_GIANT; + case TYPE_STAR_M_WF: return Lang::STAR_M_WF; + case TYPE_STAR_B_WF: return Lang::STAR_B_WF; + case TYPE_STAR_O_WF: return Lang::STAR_O_WF; + case TYPE_STAR_S_BH: return Lang::STAR_S_BH; + case TYPE_STAR_IM_BH: return Lang::STAR_IM_BH; + case TYPE_STAR_SM_BH: return Lang::STAR_SM_BH; + case TYPE_PLANET_GAS_GIANT: + if (m_mass > 800) return Lang::VERY_LARGE_GAS_GIANT; + if (m_mass > 300) return Lang::LARGE_GAS_GIANT; + if (m_mass > 80) + return Lang::MEDIUM_GAS_GIANT; + else + return Lang::SMALL_GAS_GIANT; + case TYPE_PLANET_ASTEROID: return Lang::ASTEROID; + case TYPE_PLANET_TERRESTRIAL: { + std::string s; + if (m_mass > fixed(2, 1)) + s = Lang::MASSIVE; + else if (m_mass > fixed(3, 2)) + s = Lang::LARGE; + else if (m_mass < fixed(1, 10)) + s = Lang::TINY; + else if (m_mass < fixed(1, 5)) + s = Lang::SMALL; - if (m_volcanicity > fixed(7,10)) - { - if (s.size()) - s += Lang::COMMA_HIGHLY_VOLCANIC; - else - s = Lang::HIGHLY_VOLCANIC; - } + if (m_volcanicity > fixed(7, 10)) { + if (s.size()) + s += Lang::COMMA_HIGHLY_VOLCANIC; + else + s = Lang::HIGHLY_VOLCANIC; + } - // m_averageTemp <-- in degrees Kelvin. -273 for Celsius. - // ^--- is not in fixed() format, but rather plain integer + // m_averageTemp <-- in degrees Kelvin. -273 for Celsius. + // ^--- is not in fixed() format, but rather plain integer - if (m_volatileIces + m_volatileLiquid > fixed(4,5)) - { - if (m_volatileIces > m_volatileLiquid) - { - s += (m_averageTemp < 273) ? Lang::ICE_WORLD : Lang::ROCKY_PLANET; - } - else - { - s += (m_averageTemp < 273) ? Lang::ICE_WORLD : Lang::OCEANICWORLD; - } - // what is a waterworld with temperature above 100C? possible? - } - else if (m_volatileLiquid > fixed(2,5)) - { - s += (m_averageTemp > 273) ? Lang::PLANET_CONTAINING_LIQUID_WATER : Lang::PLANET_WITH_SOME_ICE; - } - else - { - s += (m_volatileLiquid > fixed(1,5)) ? Lang::ROCKY_PLANET_CONTAINING_COME_LIQUIDS : Lang::ROCKY_PLANET; - } + if (m_volatileIces + m_volatileLiquid > fixed(4, 5)) { + if (m_volatileIces > m_volatileLiquid) { + s += (m_averageTemp < 273) ? Lang::ICE_WORLD : Lang::ROCKY_PLANET; + } else { + s += (m_averageTemp < 273) ? Lang::ICE_WORLD : Lang::OCEANICWORLD; + } + // what is a waterworld with temperature above 100C? possible? + } else if (m_volatileLiquid > fixed(2, 5)) { + s += (m_averageTemp > 273) ? Lang::PLANET_CONTAINING_LIQUID_WATER : Lang::PLANET_WITH_SOME_ICE; + } else { + s += (m_volatileLiquid > fixed(1, 5)) ? Lang::ROCKY_PLANET_CONTAINING_COME_LIQUIDS : Lang::ROCKY_PLANET; + } - if (m_volatileGas < fixed(1,100)) - { - s += Lang::WITH_NO_SIGNIFICANT_ATMOSPHERE; - } - else - { - std::string thickness; - if (m_volatileGas < fixed(1,10)) - thickness = Lang::TENUOUS; - else if (m_volatileGas < fixed(1,5)) - thickness = Lang::THIN; - else if (m_volatileGas < fixed(2,1)) // normal atmosphere - {} - else if (m_volatileGas < fixed(4,1)) - thickness = Lang::THICK; - else - thickness = Lang::VERY_DENSE; + if (m_volatileGas < fixed(1, 100)) { + s += Lang::WITH_NO_SIGNIFICANT_ATMOSPHERE; + } else { + std::string thickness; + if (m_volatileGas < fixed(1, 10)) + thickness = Lang::TENUOUS; + else if (m_volatileGas < fixed(1, 5)) + thickness = Lang::THIN; + else if (m_volatileGas < fixed(2, 1)) // normal atmosphere + { + } else if (m_volatileGas < fixed(4, 1)) + thickness = Lang::THICK; + else + thickness = Lang::VERY_DENSE; - if (m_atmosOxidizing > fixed(95,100)) { - s += Lang::WITH_A+thickness+Lang::O2_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(7,10)) { - s += Lang::WITH_A+thickness+Lang::CO2_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(65,100)) { - s += Lang::WITH_A+thickness+Lang::CO_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(55,100)) { - s += Lang::WITH_A+thickness+Lang::CH4_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(3,10)) { - s += Lang::WITH_A+thickness+Lang::H_ATMOSPHERE; // IsScoopable depends on these if/then/else values fixed(3,10) -> fixed(55,100) == hydrogen - } else if (m_atmosOxidizing > fixed(2,10)) { - s += Lang::WITH_A+thickness+Lang::HE_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(15,100)) { - s += Lang::WITH_A+thickness+Lang::AR_ATMOSPHERE; - } else if (m_atmosOxidizing > fixed(1,10)) { - s += Lang::WITH_A+thickness+Lang::S_ATMOSPHERE; - } else { - s += Lang::WITH_A+thickness+Lang::N_ATMOSPHERE; - } - } + if (m_atmosOxidizing > fixed(95, 100)) { + s += Lang::WITH_A + thickness + Lang::O2_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(7, 10)) { + s += Lang::WITH_A + thickness + Lang::CO2_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(65, 100)) { + s += Lang::WITH_A + thickness + Lang::CO_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(55, 100)) { + s += Lang::WITH_A + thickness + Lang::CH4_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(3, 10)) { + s += Lang::WITH_A + thickness + Lang::H_ATMOSPHERE; // IsScoopable depends on these if/then/else values fixed(3,10) -> fixed(55,100) == hydrogen + } else if (m_atmosOxidizing > fixed(2, 10)) { + s += Lang::WITH_A + thickness + Lang::HE_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(15, 100)) { + s += Lang::WITH_A + thickness + Lang::AR_ATMOSPHERE; + } else if (m_atmosOxidizing > fixed(1, 10)) { + s += Lang::WITH_A + thickness + Lang::S_ATMOSPHERE; + } else { + s += Lang::WITH_A + thickness + Lang::N_ATMOSPHERE; + } + } - if (m_life > fixed(1,2)) { - s += Lang::AND_HIGHLY_COMPLEX_ECOSYSTEM; - } else if (m_life > fixed(1,10)) { - s += Lang::AND_INDIGENOUS_PLANT_LIFE; - } else if (m_life > fixed()) { - s += Lang::AND_INDIGENOUS_MICROBIAL_LIFE; - } else { - s += "."; - } + if (m_life > fixed(1, 2)) { + s += Lang::AND_HIGHLY_COMPLEX_ECOSYSTEM; + } else if (m_life > fixed(1, 10)) { + s += Lang::AND_INDIGENOUS_PLANT_LIFE; + } else if (m_life > fixed()) { + s += Lang::AND_INDIGENOUS_MICROBIAL_LIFE; + } else { + s += "."; + } - return s; - } - case TYPE_STARPORT_ORBITAL: - return Lang::ORBITAL_STARPORT; - case TYPE_STARPORT_SURFACE: - return Lang::STARPORT; - case TYPE_GRAVPOINT: - default: - Output("Warning: Invalid Astro Body Description found.\n"); - return Lang::UNKNOWN; - } + return s; + } + case TYPE_STARPORT_ORBITAL: + return Lang::ORBITAL_STARPORT; + case TYPE_STARPORT_SURFACE: + return Lang::STARPORT; + case TYPE_GRAVPOINT: + default: + Output("Warning: Invalid Astro Body Description found.\n"); + return Lang::UNKNOWN; + } } const char *SystemBody::GetIcon() const { - PROFILE_SCOPED() - switch (m_type) { - case TYPE_BROWN_DWARF: return "icons/object_brown_dwarf.png"; - case TYPE_WHITE_DWARF: return "icons/object_white_dwarf.png"; - case TYPE_STAR_M: return "icons/object_star_m.png"; - case TYPE_STAR_K: return "icons/object_star_k.png"; - case TYPE_STAR_G: return "icons/object_star_g.png"; - case TYPE_STAR_F: return "icons/object_star_f.png"; - case TYPE_STAR_A: return "icons/object_star_a.png"; - case TYPE_STAR_B: return "icons/object_star_b.png"; - case TYPE_STAR_O: return "icons/object_star_b.png"; //shares B graphic for now - case TYPE_STAR_M_GIANT: return "icons/object_star_m_giant.png"; - case TYPE_STAR_K_GIANT: return "icons/object_star_k_giant.png"; - case TYPE_STAR_G_GIANT: return "icons/object_star_g_giant.png"; - case TYPE_STAR_F_GIANT: return "icons/object_star_f_giant.png"; - case TYPE_STAR_A_GIANT: return "icons/object_star_a_giant.png"; - case TYPE_STAR_B_GIANT: return "icons/object_star_b_giant.png"; - case TYPE_STAR_O_GIANT: return "icons/object_star_o.png"; // uses old O type graphic - case TYPE_STAR_M_SUPER_GIANT: return "icons/object_star_m_super_giant.png"; - case TYPE_STAR_K_SUPER_GIANT: return "icons/object_star_k_super_giant.png"; - case TYPE_STAR_G_SUPER_GIANT: return "icons/object_star_g_super_giant.png"; - case TYPE_STAR_F_SUPER_GIANT: return "icons/object_star_g_super_giant.png"; //shares G graphic for now - case TYPE_STAR_A_SUPER_GIANT: return "icons/object_star_a_super_giant.png"; - case TYPE_STAR_B_SUPER_GIANT: return "icons/object_star_b_super_giant.png"; - case TYPE_STAR_O_SUPER_GIANT: return "icons/object_star_b_super_giant.png";// uses B type graphic for now - case TYPE_STAR_M_HYPER_GIANT: return "icons/object_star_m_hyper_giant.png"; - case TYPE_STAR_K_HYPER_GIANT: return "icons/object_star_k_hyper_giant.png"; - case TYPE_STAR_G_HYPER_GIANT: return "icons/object_star_g_hyper_giant.png"; - case TYPE_STAR_F_HYPER_GIANT: return "icons/object_star_f_hyper_giant.png"; - case TYPE_STAR_A_HYPER_GIANT: return "icons/object_star_a_hyper_giant.png"; - case TYPE_STAR_B_HYPER_GIANT: return "icons/object_star_b_hyper_giant.png"; - case TYPE_STAR_O_HYPER_GIANT: return "icons/object_star_b_hyper_giant.png";// uses B type graphic for now - case TYPE_STAR_M_WF: return "icons/object_star_m_wf.png"; - case TYPE_STAR_B_WF: return "icons/object_star_b_wf.png"; - case TYPE_STAR_O_WF: return "icons/object_star_o_wf.png"; - case TYPE_STAR_S_BH: return "icons/object_star_bh.png"; - case TYPE_STAR_IM_BH: return "icons/object_star_smbh.png"; - case TYPE_STAR_SM_BH: return "icons/object_star_smbh.png"; - case TYPE_PLANET_GAS_GIANT: - if (m_mass > 800) { - if (m_averageTemp > 1000) return "icons/object_planet_large_gas_giant_hot.png"; - else return "icons/object_planet_large_gas_giant.png"; - } - if (m_mass > 300) { - if (m_averageTemp > 1000) return "icons/object_planet_large_gas_giant_hot.png"; - else return "icons/object_planet_large_gas_giant.png"; - } - if (m_mass > 80) { - if (m_averageTemp > 1000) return "icons/object_planet_medium_gas_giant_hot.png"; - else return "icons/object_planet_medium_gas_giant.png"; - } - else { - if (m_averageTemp > 1000) return "icons/object_planet_small_gas_giant_hot.png"; - else return "icons/object_planet_small_gas_giant.png"; - } - case TYPE_PLANET_ASTEROID: - return "icons/object_planet_asteroid.png"; - case TYPE_PLANET_TERRESTRIAL: - if (m_volatileLiquid > fixed(7,10)) { - if (m_averageTemp > 250) return "icons/object_planet_water.png"; - else return "icons/object_planet_ice.png"; - } - if ((m_life > fixed(9,10)) && - (m_volatileGas > fixed(6,10))) return "icons/object_planet_life.png"; - if ((m_life > fixed(8,10)) && - (m_volatileGas > fixed(5,10))) return "icons/object_planet_life6.png"; - if ((m_life > fixed(7,10)) && - (m_volatileGas > fixed(45,100))) return "icons/object_planet_life7.png"; - if ((m_life > fixed(6,10)) && - (m_volatileGas > fixed(4,10))) return "icons/object_planet_life8.png"; - if ((m_life > fixed(5,10)) && - (m_volatileGas > fixed(3,10))) return "icons/object_planet_life4.png"; - if ((m_life > fixed(4,10)) && - (m_volatileGas > fixed(2,10))) return "icons/object_planet_life5.png"; - if ((m_life > fixed(1,10)) && - (m_volatileGas > fixed(2,10))) return "icons/object_planet_life2.png"; - if (m_life > fixed(1,10)) return "icons/object_planet_life3.png"; - if (m_mass < fixed(1,100)) return "icons/object_planet_dwarf.png"; - if (m_mass < fixed(1,10)) return "icons/object_planet_small.png"; - if ((m_volatileLiquid < fixed(1,10)) && - (m_volatileGas > fixed(1,5))) return "icons/object_planet_desert.png"; + PROFILE_SCOPED() + switch (m_type) { + case TYPE_BROWN_DWARF: return "icons/object_brown_dwarf.png"; + case TYPE_WHITE_DWARF: return "icons/object_white_dwarf.png"; + case TYPE_STAR_M: return "icons/object_star_m.png"; + case TYPE_STAR_K: return "icons/object_star_k.png"; + case TYPE_STAR_G: return "icons/object_star_g.png"; + case TYPE_STAR_F: return "icons/object_star_f.png"; + case TYPE_STAR_A: return "icons/object_star_a.png"; + case TYPE_STAR_B: return "icons/object_star_b.png"; + case TYPE_STAR_O: return "icons/object_star_b.png"; //shares B graphic for now + case TYPE_STAR_M_GIANT: return "icons/object_star_m_giant.png"; + case TYPE_STAR_K_GIANT: return "icons/object_star_k_giant.png"; + case TYPE_STAR_G_GIANT: return "icons/object_star_g_giant.png"; + case TYPE_STAR_F_GIANT: return "icons/object_star_f_giant.png"; + case TYPE_STAR_A_GIANT: return "icons/object_star_a_giant.png"; + case TYPE_STAR_B_GIANT: return "icons/object_star_b_giant.png"; + case TYPE_STAR_O_GIANT: return "icons/object_star_o.png"; // uses old O type graphic + case TYPE_STAR_M_SUPER_GIANT: return "icons/object_star_m_super_giant.png"; + case TYPE_STAR_K_SUPER_GIANT: return "icons/object_star_k_super_giant.png"; + case TYPE_STAR_G_SUPER_GIANT: return "icons/object_star_g_super_giant.png"; + case TYPE_STAR_F_SUPER_GIANT: return "icons/object_star_g_super_giant.png"; //shares G graphic for now + case TYPE_STAR_A_SUPER_GIANT: return "icons/object_star_a_super_giant.png"; + case TYPE_STAR_B_SUPER_GIANT: return "icons/object_star_b_super_giant.png"; + case TYPE_STAR_O_SUPER_GIANT: return "icons/object_star_b_super_giant.png"; // uses B type graphic for now + case TYPE_STAR_M_HYPER_GIANT: return "icons/object_star_m_hyper_giant.png"; + case TYPE_STAR_K_HYPER_GIANT: return "icons/object_star_k_hyper_giant.png"; + case TYPE_STAR_G_HYPER_GIANT: return "icons/object_star_g_hyper_giant.png"; + case TYPE_STAR_F_HYPER_GIANT: return "icons/object_star_f_hyper_giant.png"; + case TYPE_STAR_A_HYPER_GIANT: return "icons/object_star_a_hyper_giant.png"; + case TYPE_STAR_B_HYPER_GIANT: return "icons/object_star_b_hyper_giant.png"; + case TYPE_STAR_O_HYPER_GIANT: return "icons/object_star_b_hyper_giant.png"; // uses B type graphic for now + case TYPE_STAR_M_WF: return "icons/object_star_m_wf.png"; + case TYPE_STAR_B_WF: return "icons/object_star_b_wf.png"; + case TYPE_STAR_O_WF: return "icons/object_star_o_wf.png"; + case TYPE_STAR_S_BH: return "icons/object_star_bh.png"; + case TYPE_STAR_IM_BH: return "icons/object_star_smbh.png"; + case TYPE_STAR_SM_BH: return "icons/object_star_smbh.png"; + case TYPE_PLANET_GAS_GIANT: + if (m_mass > 800) { + if (m_averageTemp > 1000) + return "icons/object_planet_large_gas_giant_hot.png"; + else + return "icons/object_planet_large_gas_giant.png"; + } + if (m_mass > 300) { + if (m_averageTemp > 1000) + return "icons/object_planet_large_gas_giant_hot.png"; + else + return "icons/object_planet_large_gas_giant.png"; + } + if (m_mass > 80) { + if (m_averageTemp > 1000) + return "icons/object_planet_medium_gas_giant_hot.png"; + else + return "icons/object_planet_medium_gas_giant.png"; + } else { + if (m_averageTemp > 1000) + return "icons/object_planet_small_gas_giant_hot.png"; + else + return "icons/object_planet_small_gas_giant.png"; + } + case TYPE_PLANET_ASTEROID: + return "icons/object_planet_asteroid.png"; + case TYPE_PLANET_TERRESTRIAL: + if (m_volatileLiquid > fixed(7, 10)) { + if (m_averageTemp > 250) + return "icons/object_planet_water.png"; + else + return "icons/object_planet_ice.png"; + } + if ((m_life > fixed(9, 10)) && + (m_volatileGas > fixed(6, 10))) return "icons/object_planet_life.png"; + if ((m_life > fixed(8, 10)) && + (m_volatileGas > fixed(5, 10))) return "icons/object_planet_life6.png"; + if ((m_life > fixed(7, 10)) && + (m_volatileGas > fixed(45, 100))) return "icons/object_planet_life7.png"; + if ((m_life > fixed(6, 10)) && + (m_volatileGas > fixed(4, 10))) return "icons/object_planet_life8.png"; + if ((m_life > fixed(5, 10)) && + (m_volatileGas > fixed(3, 10))) return "icons/object_planet_life4.png"; + if ((m_life > fixed(4, 10)) && + (m_volatileGas > fixed(2, 10))) return "icons/object_planet_life5.png"; + if ((m_life > fixed(1, 10)) && + (m_volatileGas > fixed(2, 10))) return "icons/object_planet_life2.png"; + if (m_life > fixed(1, 10)) return "icons/object_planet_life3.png"; + if (m_mass < fixed(1, 100)) return "icons/object_planet_dwarf.png"; + if (m_mass < fixed(1, 10)) return "icons/object_planet_small.png"; + if ((m_volatileLiquid < fixed(1, 10)) && + (m_volatileGas > fixed(1, 5))) return "icons/object_planet_desert.png"; - if (m_volatileIces + m_volatileLiquid > fixed(3,5)) { - if (m_volatileIces > m_volatileLiquid) { - if (m_averageTemp < 250) return "icons/object_planet_ice.png"; - } else { - if (m_averageTemp > 250) { - return "icons/object_planet_water.png"; - } else return "icons/object_planet_ice.png"; - } - } + if (m_volatileIces + m_volatileLiquid > fixed(3, 5)) { + if (m_volatileIces > m_volatileLiquid) { + if (m_averageTemp < 250) return "icons/object_planet_ice.png"; + } else { + if (m_averageTemp > 250) { + return "icons/object_planet_water.png"; + } else + return "icons/object_planet_ice.png"; + } + } - if (m_volatileGas > fixed(1,2)) { - if (m_atmosOxidizing < fixed(1,2)) { - if (m_averageTemp > 300) return "icons/object_planet_methane3.png"; - else if (m_averageTemp > 250) return "icons/object_planet_methane2.png"; - else return "icons/object_planet_methane.png"; - } else { - if (m_averageTemp > 300) return "icons/object_planet_co2_2.png"; - else if (m_averageTemp > 250) { - if ((m_volatileLiquid > fixed(3,10)) && (m_volatileGas > fixed(2,10))) - return "icons/object_planet_co2_4.png"; - else return "icons/object_planet_co2_3.png"; - } else return "icons/object_planet_co2.png"; - } - } + if (m_volatileGas > fixed(1, 2)) { + if (m_atmosOxidizing < fixed(1, 2)) { + if (m_averageTemp > 300) + return "icons/object_planet_methane3.png"; + else if (m_averageTemp > 250) + return "icons/object_planet_methane2.png"; + else + return "icons/object_planet_methane.png"; + } else { + if (m_averageTemp > 300) + return "icons/object_planet_co2_2.png"; + else if (m_averageTemp > 250) { + if ((m_volatileLiquid > fixed(3, 10)) && (m_volatileGas > fixed(2, 10))) + return "icons/object_planet_co2_4.png"; + else + return "icons/object_planet_co2_3.png"; + } else + return "icons/object_planet_co2.png"; + } + } - if ((m_volatileLiquid > fixed(1,10)) && - (m_volatileGas < fixed(1,10))) return "icons/object_planet_ice.png"; - if (m_volcanicity > fixed(7,10)) return "icons/object_planet_volcanic.png"; - return "icons/object_planet_small.png"; - /* + if ((m_volatileLiquid > fixed(1, 10)) && + (m_volatileGas < fixed(1, 10))) return "icons/object_planet_ice.png"; + if (m_volcanicity > fixed(7, 10)) return "icons/object_planet_volcanic.png"; + return "icons/object_planet_small.png"; + /* "icons/object_planet_water_n1.png" "icons/object_planet_life3.png" "icons/object_planet_life2.png" */ - case TYPE_STARPORT_ORBITAL: - return "icons/object_orbital_starport.png"; - case TYPE_GRAVPOINT: - case TYPE_STARPORT_SURFACE: - default: - Output("Warning: Invalid body icon.\n"); - return 0; - } + case TYPE_STARPORT_ORBITAL: + return "icons/object_orbital_starport.png"; + case TYPE_GRAVPOINT: + case TYPE_STARPORT_SURFACE: + default: + Output("Warning: Invalid body icon.\n"); + return 0; + } } -bool SystemBody::IsPlanet() const { - BodySuperType st = GetSuperType(); - if(st != BodySuperType::SUPERTYPE_ROCKY_PLANET && st != BodySuperType::SUPERTYPE_GAS_GIANT) - return false; - SystemBody *p = GetParent(); - if(p != nullptr && p->GetSuperType() == BodySuperType::SUPERTYPE_STAR) { - return true; - } else { - return false; - } +bool SystemBody::IsPlanet() const +{ + BodySuperType st = GetSuperType(); + if (st != BodySuperType::SUPERTYPE_ROCKY_PLANET && st != BodySuperType::SUPERTYPE_GAS_GIANT) + return false; + SystemBody *p = GetParent(); + if (p != nullptr && p->GetSuperType() == BodySuperType::SUPERTYPE_STAR) { + return true; + } else { + return false; + } } double SystemBody::GetMaxChildOrbitalDistance() const { - PROFILE_SCOPED() - double max = 0; - for (unsigned int i=0; im_orbMax.ToDouble() > max) { - max = m_children[i]->m_orbMax.ToDouble(); - } - } - return AU * max; + PROFILE_SCOPED() + double max = 0; + for (unsigned int i = 0; i < m_children.size(); i++) { + if (m_children[i]->m_orbMax.ToDouble() > max) { + max = m_children[i]->m_orbMax.ToDouble(); + } + } + return AU * max; } -bool SystemBody::IsCoOrbitalWith(const SystemBody* other) const +bool SystemBody::IsCoOrbitalWith(const SystemBody *other) const { - if(m_parent && m_parent->GetType()==SystemBody::TYPE_GRAVPOINT - && ((m_parent->m_children[0] == this && m_parent->m_children[1] == other) - || (m_parent->m_children[1] == this && m_parent->m_children[0] == other))) - return true; - return false; + if (m_parent && m_parent->GetType() == SystemBody::TYPE_GRAVPOINT && ((m_parent->m_children[0] == this && m_parent->m_children[1] == other) || (m_parent->m_children[1] == this && m_parent->m_children[0] == other))) + return true; + return false; } bool SystemBody::IsCoOrbital() const { - if(m_parent && m_parent->GetType()==SystemBody::TYPE_GRAVPOINT && (m_parent->m_children[0] == this || m_parent->m_children[1] == this)) - return true; - return false; + if (m_parent && m_parent->GetType() == SystemBody::TYPE_GRAVPOINT && (m_parent->m_children[0] == this || m_parent->m_children[1] == this)) + return true; + return false; } double SystemBody::CalcSurfaceGravity() const { - PROFILE_SCOPED() - double r = GetRadius(); - if (r > 0.0) { - return G * GetMass() / pow(r, 2); - } else { - return 0.0; - } + PROFILE_SCOPED() + double r = GetRadius(); + if (r > 0.0) { + return G * GetMass() / pow(r, 2); + } else { + return 0.0; + } } SystemBody *StarSystem::GetBodyByPath(const SystemPath &path) const { - PROFILE_SCOPED() - assert(m_path.IsSameSystem(path)); - assert(path.IsBodyPath()); - assert(path.bodyIndex < m_bodies.size()); + PROFILE_SCOPED() + assert(m_path.IsSameSystem(path)); + assert(path.IsBodyPath()); + assert(path.bodyIndex < m_bodies.size()); - return m_bodies[path.bodyIndex].Get(); + return m_bodies[path.bodyIndex].Get(); } SystemPath StarSystem::GetPathOf(const SystemBody *sbody) const { - return sbody->GetPath(); + return sbody->GetPath(); } -SystemBody::SystemBody(const SystemPath& path, StarSystem *system) : m_parent(nullptr), m_path(path), m_seed(0), m_aspectRatio(1,1), m_orbMin(0), - m_orbMax(0), m_rotationalPhaseAtStart(0), m_semiMajorAxis(0), m_eccentricity(0), m_orbitalOffset(0), m_axialTilt(0), - m_inclination(0), m_averageTemp(0), m_type(TYPE_GRAVPOINT), m_isCustomBody(false), m_heightMapFractal(0), m_atmosDensity(0.0), m_system(system) +SystemBody::SystemBody(const SystemPath &path, StarSystem *system) : + m_parent(nullptr), + m_path(path), + m_seed(0), + m_aspectRatio(1, 1), + m_orbMin(0), + m_orbMax(0), + m_rotationalPhaseAtStart(0), + m_semiMajorAxis(0), + m_eccentricity(0), + m_orbitalOffset(0), + m_axialTilt(0), + m_inclination(0), + m_averageTemp(0), + m_type(TYPE_GRAVPOINT), + m_isCustomBody(false), + m_heightMapFractal(0), + m_atmosDensity(0.0), + m_system(system) { } bool SystemBody::HasAtmosphere() const { - PROFILE_SCOPED() - return (m_volatileGas > fixed(1,100)); + PROFILE_SCOPED() + return (m_volatileGas > fixed(1, 100)); } bool SystemBody::IsScoopable() const { - PROFILE_SCOPED() + PROFILE_SCOPED() - if (GetSuperType() == SUPERTYPE_GAS_GIANT) - return true; - if ((m_type == TYPE_PLANET_TERRESTRIAL) && - m_volatileGas > fixed(1, 100) && - m_atmosOxidizing > fixed(3, 10) && - m_atmosOxidizing <= fixed(55, 100)) - return true; - return false; + if (GetSuperType() == SUPERTYPE_GAS_GIANT) + return true; + if ((m_type == TYPE_PLANET_TERRESTRIAL) && + m_volatileGas > fixed(1, 100) && + m_atmosOxidizing > fixed(3, 10) && + m_atmosOxidizing <= fixed(55, 100)) + return true; + return false; } // Calculate parameters used in the atmospheric model for shaders SystemBody::AtmosphereParameters SystemBody::CalcAtmosphereParams() const { - PROFILE_SCOPED() - AtmosphereParameters params; + PROFILE_SCOPED() + AtmosphereParameters params; - double atmosDensity; + double atmosDensity; - GetAtmosphereFlavor(¶ms.atmosCol, &atmosDensity); - // adjust global atmosphere opacity - atmosDensity *= 1e-5; + GetAtmosphereFlavor(¶ms.atmosCol, &atmosDensity); + // adjust global atmosphere opacity + atmosDensity *= 1e-5; - params.atmosDensity = static_cast(atmosDensity); + params.atmosDensity = static_cast(atmosDensity); - // Calculate parameters used in the atmospheric model for shaders - // Isothermal atmospheric model - // See http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation - // This model features an exponential decrease in pressure and density with altitude. - // The scale height is 1/the exponential coefficient. + // Calculate parameters used in the atmospheric model for shaders + // Isothermal atmospheric model + // See http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation + // This model features an exponential decrease in pressure and density with altitude. + // The scale height is 1/the exponential coefficient. - // The equation for pressure is: - // Pressure at height h = Pressure surface * e^((-Mg/RT)*h) + // The equation for pressure is: + // Pressure at height h = Pressure surface * e^((-Mg/RT)*h) - // calculate (inverse) atmosphere scale height - // The formula for scale height is: - // h = RT / Mg - // h is height above the surface in meters - // R is the universal gas constant - // T is the surface temperature in Kelvin - // g is the gravity in m/s^2 - // M is the molar mass of air in kg/mol + // calculate (inverse) atmosphere scale height + // The formula for scale height is: + // h = RT / Mg + // h is height above the surface in meters + // R is the universal gas constant + // T is the surface temperature in Kelvin + // g is the gravity in m/s^2 + // M is the molar mass of air in kg/mol - // calculate gravity - // radius of the planet - const double radiusPlanet_in_m = (m_radius.ToDouble()*EARTH_RADIUS); - const double massPlanet_in_kg = (m_mass.ToDouble()*EARTH_MASS); - const double g = G*massPlanet_in_kg/(radiusPlanet_in_m*radiusPlanet_in_m); + // calculate gravity + // radius of the planet + const double radiusPlanet_in_m = (m_radius.ToDouble() * EARTH_RADIUS); + const double massPlanet_in_kg = (m_mass.ToDouble() * EARTH_MASS); + const double g = G * massPlanet_in_kg / (radiusPlanet_in_m * radiusPlanet_in_m); - double T = static_cast(m_averageTemp); + double T = static_cast(m_averageTemp); - // XXX hack to avoid issues with sysgen giving 0 temps - // temporary as part of sysgen needs to be rewritten before the proper fix can be used - if (T < 1) - T = 165; + // XXX hack to avoid issues with sysgen giving 0 temps + // temporary as part of sysgen needs to be rewritten before the proper fix can be used + if (T < 1) + T = 165; - // We have two kinds of atmosphere: Earth-like and gas giant (hydrogen/helium) - const double M = m_type == TYPE_PLANET_GAS_GIANT ? 0.0023139903 : 0.02897f; // in kg/mol + // We have two kinds of atmosphere: Earth-like and gas giant (hydrogen/helium) + const double M = m_type == TYPE_PLANET_GAS_GIANT ? 0.0023139903 : 0.02897f; // in kg/mol - float atmosScaleHeight = static_cast(GAS_CONSTANT_R*T/(M*g)); + float atmosScaleHeight = static_cast(GAS_CONSTANT_R * T / (M * g)); - // min of 2.0 corresponds to a scale height of 1/20 of the planet's radius, - params.atmosInvScaleHeight = std::max(20.0f, static_cast(GetRadius() / atmosScaleHeight)); - // integrate atmospheric density between surface and this radius. this is 10x the scale - // height, which should be a height at which the atmospheric density is negligible - params.atmosRadius = 1.0f + static_cast(10.0f * atmosScaleHeight) / GetRadius(); + // min of 2.0 corresponds to a scale height of 1/20 of the planet's radius, + params.atmosInvScaleHeight = std::max(20.0f, static_cast(GetRadius() / atmosScaleHeight)); + // integrate atmospheric density between surface and this radius. this is 10x the scale + // height, which should be a height at which the atmospheric density is negligible + params.atmosRadius = 1.0f + static_cast(10.0f * atmosScaleHeight) / GetRadius(); - params.planetRadius = static_cast(radiusPlanet_in_m); + params.planetRadius = static_cast(radiusPlanet_in_m); - return params; + return params; } /* @@ -694,405 +713,406 @@ SystemBody::AtmosphereParameters SystemBody::CalcAtmosphereParams() const * * We must be sneaky and avoid floating point in these places. */ -StarSystem::StarSystem(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache* cache, Random& rand) - : m_galaxy(galaxy), m_path(path.SystemOnly()), m_numStars(0), m_isCustom(false), - m_faction(nullptr), m_explored(eEXPLORED_AT_START), m_exploredTime(0.0), m_econType(GalacticEconomy::ECON_MINING), m_seed(0), - m_commodityLegal(unsigned(GalacticEconomy::Commodity::COMMODITY_COUNT), true), m_cache(cache) +StarSystem::StarSystem(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache *cache, Random &rand) : + m_galaxy(galaxy), + m_path(path.SystemOnly()), + m_numStars(0), + m_isCustom(false), + m_faction(nullptr), + m_explored(eEXPLORED_AT_START), + m_exploredTime(0.0), + m_econType(GalacticEconomy::ECON_MINING), + m_seed(0), + m_commodityLegal(unsigned(GalacticEconomy::Commodity::COMMODITY_COUNT), true), + m_cache(cache) { - PROFILE_SCOPED() - memset(m_tradeLevel, 0, sizeof(m_tradeLevel)); + PROFILE_SCOPED() + memset(m_tradeLevel, 0, sizeof(m_tradeLevel)); } -StarSystem::GeneratorAPI::GeneratorAPI(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache* cache, Random& rand) - : StarSystem(path, galaxy, cache, rand) { } +StarSystem::GeneratorAPI::GeneratorAPI(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache *cache, Random &rand) : + StarSystem(path, galaxy, cache, rand) {} #ifdef DEBUG_DUMP struct thing_t { - SystemBody* obj; - vector3d pos; - vector3d vel; + SystemBody *obj; + vector3d pos; + vector3d vel; }; void StarSystem::Dump() { - std::vector obj_stack; - std::vector pos_stack; - std::vector output; + std::vector obj_stack; + std::vector pos_stack; + std::vector output; - SystemBody *obj = m_rootBody; - vector3d pos = vector3d(0.0); + SystemBody *obj = m_rootBody; + vector3d pos = vector3d(0.0); - while (obj) { - vector3d p2 = pos; - if (obj->m_parent) { - p2 = pos + obj->m_orbit.OrbitalPosAtTime(1.0); - pos = pos + obj->m_orbit.OrbitalPosAtTime(0.0); - } + while (obj) { + vector3d p2 = pos; + if (obj->m_parent) { + p2 = pos + obj->m_orbit.OrbitalPosAtTime(1.0); + pos = pos + obj->m_orbit.OrbitalPosAtTime(0.0); + } - if ((obj->GetType() != SystemBody::TYPE_GRAVPOINT) && - (obj->GetSuperType() != SystemBody::SUPERTYPE_STARPORT)) { - struct thing_t t; - t.obj = obj; - t.pos = pos; - t.vel = (p2-pos); - output.push_back(t); - } - for (std::vector::iterator i = obj->m_children.begin(); - i != obj->m_children.end(); ++i) { - obj_stack.push_back(*i); - pos_stack.push_back(pos); - } - if (obj_stack.size() == 0) break; - pos = pos_stack.back(); - obj = obj_stack.back(); - pos_stack.pop_back(); - obj_stack.pop_back(); - } + if ((obj->GetType() != SystemBody::TYPE_GRAVPOINT) && + (obj->GetSuperType() != SystemBody::SUPERTYPE_STARPORT)) { + struct thing_t t; + t.obj = obj; + t.pos = pos; + t.vel = (p2 - pos); + output.push_back(t); + } + for (std::vector::iterator i = obj->m_children.begin(); + i != obj->m_children.end(); ++i) { + obj_stack.push_back(*i); + pos_stack.push_back(pos); + } + if (obj_stack.size() == 0) break; + pos = pos_stack.back(); + obj = obj_stack.back(); + pos_stack.pop_back(); + obj_stack.pop_back(); + } - FILE *f = fopen("starsystem.dump", "w"); - fprintf(f, SIZET_FMT " bodies\n", output.size()); - fprintf(f, "0 steps\n"); - for (std::vector::iterator i = output.begin(); - i != output.end(); ++i) { - fprintf(f, "B:%lf,%lf:%lf,%lf,%lf,%lf:%lf:%d:%lf,%lf,%lf\n", - (*i).pos.x, (*i).pos.y, (*i).pos.z, - (*i).vel.x, (*i).vel.y, (*i).vel.z, - (*i).obj->GetMass(), 0, - 1.0, 1.0, 1.0); - } - fclose(f); - Output("Junk dumped to starsystem.dump\n"); + FILE *f = fopen("starsystem.dump", "w"); + fprintf(f, SIZET_FMT " bodies\n", output.size()); + fprintf(f, "0 steps\n"); + for (std::vector::iterator i = output.begin(); + i != output.end(); ++i) { + fprintf(f, "B:%lf,%lf:%lf,%lf,%lf,%lf:%lf:%d:%lf,%lf,%lf\n", + (*i).pos.x, (*i).pos.y, (*i).pos.z, + (*i).vel.x, (*i).vel.y, (*i).vel.z, + (*i).obj->GetMass(), 0, + 1.0, 1.0, 1.0); + } + fclose(f); + Output("Junk dumped to starsystem.dump\n"); } #endif /* DEBUG_DUMP */ void StarSystem::MakeShortDescription() { - PROFILE_SCOPED() - if (GetExplored() == StarSystem::eUNEXPLORED) - SetShortDesc(Lang::UNEXPLORED_SYSTEM_NO_DATA); + PROFILE_SCOPED() + if (GetExplored() == StarSystem::eUNEXPLORED) + SetShortDesc(Lang::UNEXPLORED_SYSTEM_NO_DATA); - else if (GetExplored() == StarSystem::eEXPLORED_BY_PLAYER) - SetShortDesc(stringf(Lang::RECENTLY_EXPLORED_SYSTEM, formatarg("date", format_date_only(GetExploredTime())))); + else if (GetExplored() == StarSystem::eEXPLORED_BY_PLAYER) + SetShortDesc(stringf(Lang::RECENTLY_EXPLORED_SYSTEM, formatarg("date", format_date_only(GetExploredTime())))); - /* Total population is in billions */ - else if(GetTotalPop() == 0) { - SetShortDesc(Lang::SMALL_SCALE_PROSPECTING_NO_SETTLEMENTS); - } else if (GetTotalPop() < fixed(1,10)) { - switch (GetEconType()) { - case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::SMALL_INDUSTRIAL_OUTPOST); break; - case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::SOME_ESTABLISHED_MINING); break; - case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::YOUNG_FARMING_COLONY); break; - } - } else if (GetTotalPop() < fixed(1,2)) { - switch (GetEconType()) { - case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::INDUSTRIAL_COLONY); break; - case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::MINING_COLONY); break; - case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::OUTDOOR_AGRICULTURAL_WORLD); break; - } - } else if (GetTotalPop() < fixed(5,1)) { - switch (GetEconType()) { - case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::HEAVY_INDUSTRY); break; - case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::EXTENSIVE_MINING); break; - case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::THRIVING_OUTDOOR_WORLD); break; - } - } else { - switch (GetEconType()) { - case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::INDUSTRIAL_HUB_SYSTEM); break; - case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::VAST_STRIP_MINE); break; - case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::HIGH_POPULATION_OUTDOOR_WORLD); break; - } - } + /* Total population is in billions */ + else if (GetTotalPop() == 0) { + SetShortDesc(Lang::SMALL_SCALE_PROSPECTING_NO_SETTLEMENTS); + } else if (GetTotalPop() < fixed(1, 10)) { + switch (GetEconType()) { + case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::SMALL_INDUSTRIAL_OUTPOST); break; + case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::SOME_ESTABLISHED_MINING); break; + case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::YOUNG_FARMING_COLONY); break; + } + } else if (GetTotalPop() < fixed(1, 2)) { + switch (GetEconType()) { + case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::INDUSTRIAL_COLONY); break; + case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::MINING_COLONY); break; + case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::OUTDOOR_AGRICULTURAL_WORLD); break; + } + } else if (GetTotalPop() < fixed(5, 1)) { + switch (GetEconType()) { + case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::HEAVY_INDUSTRY); break; + case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::EXTENSIVE_MINING); break; + case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::THRIVING_OUTDOOR_WORLD); break; + } + } else { + switch (GetEconType()) { + case GalacticEconomy::ECON_INDUSTRY: SetShortDesc(Lang::INDUSTRIAL_HUB_SYSTEM); break; + case GalacticEconomy::ECON_MINING: SetShortDesc(Lang::VAST_STRIP_MINE); break; + case GalacticEconomy::ECON_AGRICULTURE: SetShortDesc(Lang::HIGH_POPULATION_OUTDOOR_WORLD); break; + } + } } - void StarSystem::ExploreSystem(double time) { - if (m_explored != eUNEXPLORED) - return; - m_explored = eEXPLORED_BY_PLAYER; - m_exploredTime = time; - RefCountedPtr sec = m_galaxy->GetMutableSector(m_path); - Sector::System& secsys = sec->m_systems[m_path.systemIndex]; - secsys.SetExplored(m_explored, m_exploredTime); - MakeShortDescription(); - LuaEvent::Queue("onSystemExplored", this); + if (m_explored != eUNEXPLORED) + return; + m_explored = eEXPLORED_BY_PLAYER; + m_exploredTime = time; + RefCountedPtr sec = m_galaxy->GetMutableSector(m_path); + Sector::System &secsys = sec->m_systems[m_path.systemIndex]; + secsys.SetExplored(m_explored, m_exploredTime); + MakeShortDescription(); + LuaEvent::Queue("onSystemExplored", this); } -void SystemBody::Dump(FILE* file, const char* indent) const +void SystemBody::Dump(FILE *file, const char *indent) const { - fprintf(file, "%sSystemBody(%d,%d,%d,%u,%u) : %s/%s %s{\n", indent, m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex, - m_path.bodyIndex, EnumStrings::GetString("BodySuperType", GetSuperType()), EnumStrings::GetString("BodyType", m_type), - m_isCustomBody ? "CUSTOM " : ""); - fprintf(file, "%s\t\"%s\"\n", indent, m_name.c_str()); - fprintf(file, "%s\tmass %.6f\n", indent, m_mass.ToDouble()); - fprintf(file, "%s\torbit a=%.6f, e=%.6f, phase=%.6f\n", indent, m_orbit.GetSemiMajorAxis(), m_orbit.GetEccentricity(), - m_orbit.GetOrbitalPhaseAtStart()); - fprintf(file, "%s\torbit a=%.6f, e=%.6f, orbMin=%.6f, orbMax=%.6f\n", indent, m_semiMajorAxis.ToDouble(), m_eccentricity.ToDouble(), - m_orbMin.ToDouble(), m_orbMax.ToDouble()); - fprintf(file, "%s\t\toffset=%.6f, phase=%.6f, inclination=%.6f\n", indent, m_orbitalOffset.ToDouble(), m_orbitalPhaseAtStart.ToDouble(), - m_inclination.ToDouble()); - if (m_type != TYPE_GRAVPOINT) { - fprintf(file, "%s\tseed %u\n", indent, m_seed); - fprintf(file, "%s\tradius %.6f, aspect %.6f\n", indent, m_radius.ToDouble(), m_aspectRatio.ToDouble()); - fprintf(file, "%s\taxial tilt %.6f, period %.6f, phase %.6f\n", indent, m_axialTilt.ToDouble(), m_rotationPeriod.ToDouble(), - m_rotationalPhaseAtStart.ToDouble()); - fprintf(file, "%s\ttemperature %d\n", indent, m_averageTemp); - fprintf(file, "%s\tmetalicity %.2f, volcanicity %.2f\n", indent, m_metallicity.ToDouble() * 100.0, m_volcanicity.ToDouble() * 100.0); - fprintf(file, "%s\tvolatiles gas=%.2f, liquid=%.2f, ice=%.2f\n", indent, m_volatileGas.ToDouble() * 100.0, - m_volatileLiquid.ToDouble() * 100.0, m_volatileIces.ToDouble() * 100.0); - fprintf(file, "%s\tlife %.2f\n", indent, m_life.ToDouble() * 100.0); - fprintf(file, "%s\tatmosphere oxidizing=%.2f, color=(%hhu,%hhu,%hhu,%hhu), density=%.6f\n", indent, - m_atmosOxidizing.ToDouble() * 100.0, m_atmosColor.r, m_atmosColor.g, m_atmosColor.b, m_atmosColor.a, m_atmosDensity); - fprintf(file, "%s\trings minRadius=%.2f, maxRadius=%.2f, color=(%hhu,%hhu,%hhu,%hhu)\n", indent, m_rings.minRadius.ToDouble() * 100.0, - m_rings.maxRadius.ToDouble() * 100.0, m_rings.baseColor.r, m_rings.baseColor.g, m_rings.baseColor.b, m_rings.baseColor.a); - fprintf(file, "%s\thuman activity %.2f, population %.0f, agricultural %.2f\n", indent, m_humanActivity.ToDouble() * 100.0, - m_population.ToDouble() * 1e9, m_agricultural.ToDouble() * 100.0); - if (!m_heightMapFilename.empty()) { - fprintf(file, "%s\theightmap \"%s\", fractal %u\n", indent, m_heightMapFilename.c_str(), m_heightMapFractal); - } - } - for (const SystemBody* kid : m_children) { - assert(kid->m_parent == this); - char buf[32]; - snprintf(buf, sizeof(buf), "%s\t", indent); - kid->Dump(file, buf); - } - fprintf(file, "%s}\n", indent); + fprintf(file, "%sSystemBody(%d,%d,%d,%u,%u) : %s/%s %s{\n", indent, m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex, + m_path.bodyIndex, EnumStrings::GetString("BodySuperType", GetSuperType()), EnumStrings::GetString("BodyType", m_type), + m_isCustomBody ? "CUSTOM " : ""); + fprintf(file, "%s\t\"%s\"\n", indent, m_name.c_str()); + fprintf(file, "%s\tmass %.6f\n", indent, m_mass.ToDouble()); + fprintf(file, "%s\torbit a=%.6f, e=%.6f, phase=%.6f\n", indent, m_orbit.GetSemiMajorAxis(), m_orbit.GetEccentricity(), + m_orbit.GetOrbitalPhaseAtStart()); + fprintf(file, "%s\torbit a=%.6f, e=%.6f, orbMin=%.6f, orbMax=%.6f\n", indent, m_semiMajorAxis.ToDouble(), m_eccentricity.ToDouble(), + m_orbMin.ToDouble(), m_orbMax.ToDouble()); + fprintf(file, "%s\t\toffset=%.6f, phase=%.6f, inclination=%.6f\n", indent, m_orbitalOffset.ToDouble(), m_orbitalPhaseAtStart.ToDouble(), + m_inclination.ToDouble()); + if (m_type != TYPE_GRAVPOINT) { + fprintf(file, "%s\tseed %u\n", indent, m_seed); + fprintf(file, "%s\tradius %.6f, aspect %.6f\n", indent, m_radius.ToDouble(), m_aspectRatio.ToDouble()); + fprintf(file, "%s\taxial tilt %.6f, period %.6f, phase %.6f\n", indent, m_axialTilt.ToDouble(), m_rotationPeriod.ToDouble(), + m_rotationalPhaseAtStart.ToDouble()); + fprintf(file, "%s\ttemperature %d\n", indent, m_averageTemp); + fprintf(file, "%s\tmetalicity %.2f, volcanicity %.2f\n", indent, m_metallicity.ToDouble() * 100.0, m_volcanicity.ToDouble() * 100.0); + fprintf(file, "%s\tvolatiles gas=%.2f, liquid=%.2f, ice=%.2f\n", indent, m_volatileGas.ToDouble() * 100.0, + m_volatileLiquid.ToDouble() * 100.0, m_volatileIces.ToDouble() * 100.0); + fprintf(file, "%s\tlife %.2f\n", indent, m_life.ToDouble() * 100.0); + fprintf(file, "%s\tatmosphere oxidizing=%.2f, color=(%hhu,%hhu,%hhu,%hhu), density=%.6f\n", indent, + m_atmosOxidizing.ToDouble() * 100.0, m_atmosColor.r, m_atmosColor.g, m_atmosColor.b, m_atmosColor.a, m_atmosDensity); + fprintf(file, "%s\trings minRadius=%.2f, maxRadius=%.2f, color=(%hhu,%hhu,%hhu,%hhu)\n", indent, m_rings.minRadius.ToDouble() * 100.0, + m_rings.maxRadius.ToDouble() * 100.0, m_rings.baseColor.r, m_rings.baseColor.g, m_rings.baseColor.b, m_rings.baseColor.a); + fprintf(file, "%s\thuman activity %.2f, population %.0f, agricultural %.2f\n", indent, m_humanActivity.ToDouble() * 100.0, + m_population.ToDouble() * 1e9, m_agricultural.ToDouble() * 100.0); + if (!m_heightMapFilename.empty()) { + fprintf(file, "%s\theightmap \"%s\", fractal %u\n", indent, m_heightMapFilename.c_str(), m_heightMapFractal); + } + } + for (const SystemBody *kid : m_children) { + assert(kid->m_parent == this); + char buf[32]; + snprintf(buf, sizeof(buf), "%s\t", indent); + kid->Dump(file, buf); + } + fprintf(file, "%s}\n", indent); } void SystemBody::ClearParentAndChildPointers() { - PROFILE_SCOPED() - for (std::vector::iterator i = m_children.begin(); i != m_children.end(); ++i) - (*i)->ClearParentAndChildPointers(); - m_parent = 0; - m_children.clear(); + PROFILE_SCOPED() + for (std::vector::iterator i = m_children.begin(); i != m_children.end(); ++i) + (*i)->ClearParentAndChildPointers(); + m_parent = 0; + m_children.clear(); } StarSystem::~StarSystem() { - PROFILE_SCOPED() - // clear parent and children pointers. someone (Lua) might still have a - // reference to things that are about to be deleted - m_rootBody->ClearParentAndChildPointers(); - if (m_cache) - m_cache->RemoveFromAttic(m_path); + PROFILE_SCOPED() + // clear parent and children pointers. someone (Lua) might still have a + // reference to things that are about to be deleted + m_rootBody->ClearParentAndChildPointers(); + if (m_cache) + m_cache->RemoveFromAttic(m_path); } void StarSystem::ToJson(Json &jsonObj, StarSystem *s) { - if (s) - { - Json starSystemObj({}); // Create JSON object to contain star system data. - starSystemObj["sector_x"] = s->m_path.sectorX; - starSystemObj["sector_y"] = s->m_path.sectorY; - starSystemObj["sector_z"] = s->m_path.sectorZ; - starSystemObj["system_index"] = s->m_path.systemIndex; - jsonObj["star_system"] = starSystemObj; // Add star system object to supplied object. - } + if (s) { + Json starSystemObj({}); // Create JSON object to contain star system data. + starSystemObj["sector_x"] = s->m_path.sectorX; + starSystemObj["sector_y"] = s->m_path.sectorY; + starSystemObj["sector_z"] = s->m_path.sectorZ; + starSystemObj["system_index"] = s->m_path.systemIndex; + jsonObj["star_system"] = starSystemObj; // Add star system object to supplied object. + } } RefCountedPtr StarSystem::FromJson(RefCountedPtr galaxy, const Json &jsonObj) { - try { - Json starSystemObj = jsonObj["star_system"]; + try { + Json starSystemObj = jsonObj["star_system"]; - int sec_x = starSystemObj["sector_x"]; - int sec_y = starSystemObj["sector_y"]; - int sec_z = starSystemObj["sector_z"]; - int sys_idx = starSystemObj["system_index"]; + int sec_x = starSystemObj["sector_x"]; + int sec_y = starSystemObj["sector_y"]; + int sec_z = starSystemObj["sector_z"]; + int sys_idx = starSystemObj["system_index"]; - return galaxy->GetStarSystem(SystemPath(sec_x, sec_y, sec_z, sys_idx)); - } catch (Json::type_error &) { - throw SavedGameCorruptException(); - } + return galaxy->GetStarSystem(SystemPath(sec_x, sec_y, sec_z, sys_idx)); + } catch (Json::type_error &) { + throw SavedGameCorruptException(); + } } std::string StarSystem::ExportBodyToLua(FILE *f, SystemBody *body) { - const int multiplier = 10000; + const int multiplier = 10000; - // strip characters that will not work in Lua - std::string code_name = body->GetName(); - std::transform(code_name.begin(), code_name.end(), code_name.begin(), ::tolower); - code_name.erase(remove_if(code_name.begin(), code_name.end(), InvalidSystemNameChar), code_name.end()); + // strip characters that will not work in Lua + std::string code_name = body->GetName(); + std::transform(code_name.begin(), code_name.end(), code_name.begin(), ::tolower); + code_name.erase(remove_if(code_name.begin(), code_name.end(), InvalidSystemNameChar), code_name.end()); - // find the body type index so we can lookup the name - const char *pBodyTypeName = nullptr; - for (int bodyTypeIdx = 0; ENUM_BodyType[bodyTypeIdx].name != 0; bodyTypeIdx++) { - if (ENUM_BodyType[bodyTypeIdx].value == body->GetType()) { - pBodyTypeName = ENUM_BodyType[bodyTypeIdx].name; - break; - } - } + // find the body type index so we can lookup the name + const char *pBodyTypeName = nullptr; + for (int bodyTypeIdx = 0; ENUM_BodyType[bodyTypeIdx].name != 0; bodyTypeIdx++) { + if (ENUM_BodyType[bodyTypeIdx].value == body->GetType()) { + pBodyTypeName = ENUM_BodyType[bodyTypeIdx].name; + break; + } + } - if (body->GetType() == SystemBody::TYPE_STARPORT_SURFACE) - { - fprintf(f, - "local %s = CustomSystemBody:new(\"%s\", '%s')\n" - "\t:latitude(math.deg2rad(%.1f))\n" - "\t:longitude(math.deg2rad(%.1f))\n", + if (body->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { + fprintf(f, + "local %s = CustomSystemBody:new(\"%s\", '%s')\n" + "\t:latitude(math.deg2rad(%.1f))\n" + "\t:longitude(math.deg2rad(%.1f))\n", - code_name.c_str(), - body->GetName().c_str(), pBodyTypeName, - body->m_inclination.ToDouble() * 180 / M_PI, - body->m_orbitalOffset.ToDouble() * 180 / M_PI - ); - } - else - { - fprintf(f, - "local %s = CustomSystemBody:new(\"%s\", '%s')\n" - "\t:radius(f(%d,%d))\n" - "\t:mass(f(%d,%d))\n", - code_name.c_str(), - body->GetName().c_str(), pBodyTypeName, - int(round(body->GetRadiusAsFixed().ToDouble()*multiplier)), multiplier, - int(round(body->GetMassAsFixed().ToDouble()*multiplier)), multiplier - ); + code_name.c_str(), + body->GetName().c_str(), pBodyTypeName, + body->m_inclination.ToDouble() * 180 / M_PI, + body->m_orbitalOffset.ToDouble() * 180 / M_PI); + } else { + fprintf(f, + "local %s = CustomSystemBody:new(\"%s\", '%s')\n" + "\t:radius(f(%d,%d))\n" + "\t:mass(f(%d,%d))\n", + code_name.c_str(), + body->GetName().c_str(), pBodyTypeName, + int(round(body->GetRadiusAsFixed().ToDouble() * multiplier)), multiplier, + int(round(body->GetMassAsFixed().ToDouble() * multiplier)), multiplier); - if (body->GetType() != SystemBody::TYPE_GRAVPOINT) - fprintf(f, - "\t:seed(%u)\n" - "\t:temp(%d)\n" - "\t:semi_major_axis(f(%d,%d))\n" - "\t:eccentricity(f(%d,%d))\n" - "\t:rotation_period(f(%d,%d))\n" - "\t:axial_tilt(fixed.deg2rad(f(%d,%d)))\n" - "\t:rotational_phase_at_start(fixed.deg2rad(f(%d,%d)))\n" - "\t:orbital_phase_at_start(fixed.deg2rad(f(%d,%d)))\n" - "\t:orbital_offset(fixed.deg2rad(f(%d,%d)))\n", - body->GetSeed(), body->GetAverageTemp(), - int(round(body->GetOrbit().GetSemiMajorAxis() / AU * multiplier)), multiplier, - int(round(body->GetOrbit().GetEccentricity()*multiplier)), multiplier, - int(round(body->m_rotationPeriod.ToDouble()*multiplier)), multiplier, - int(round(body->GetAxialTilt()*multiplier)), multiplier, - int(round(body->m_rotationalPhaseAtStart.ToDouble()*multiplier * 180 / M_PI)), multiplier, - int(round(body->m_orbitalPhaseAtStart.ToDouble()*multiplier * 180 / M_PI)), multiplier, - int(round(body->m_orbitalOffset.ToDouble()*multiplier * 180 / M_PI)), multiplier - ); + if (body->GetType() != SystemBody::TYPE_GRAVPOINT) + fprintf(f, + "\t:seed(%u)\n" + "\t:temp(%d)\n" + "\t:semi_major_axis(f(%d,%d))\n" + "\t:eccentricity(f(%d,%d))\n" + "\t:rotation_period(f(%d,%d))\n" + "\t:axial_tilt(fixed.deg2rad(f(%d,%d)))\n" + "\t:rotational_phase_at_start(fixed.deg2rad(f(%d,%d)))\n" + "\t:orbital_phase_at_start(fixed.deg2rad(f(%d,%d)))\n" + "\t:orbital_offset(fixed.deg2rad(f(%d,%d)))\n", + body->GetSeed(), body->GetAverageTemp(), + int(round(body->GetOrbit().GetSemiMajorAxis() / AU * multiplier)), multiplier, + int(round(body->GetOrbit().GetEccentricity() * multiplier)), multiplier, + int(round(body->m_rotationPeriod.ToDouble() * multiplier)), multiplier, + int(round(body->GetAxialTilt() * multiplier)), multiplier, + int(round(body->m_rotationalPhaseAtStart.ToDouble() * multiplier * 180 / M_PI)), multiplier, + int(round(body->m_orbitalPhaseAtStart.ToDouble() * multiplier * 180 / M_PI)), multiplier, + int(round(body->m_orbitalOffset.ToDouble() * multiplier * 180 / M_PI)), multiplier); - if (body->GetType() == SystemBody::TYPE_PLANET_TERRESTRIAL) - fprintf(f, - "\t:metallicity(f(%d,%d))\n" - "\t:volcanicity(f(%d,%d))\n" - "\t:atmos_density(f(%d,%d))\n" - "\t:atmos_oxidizing(f(%d,%d))\n" - "\t:ocean_cover(f(%d,%d))\n" - "\t:ice_cover(f(%d,%d))\n" - "\t:life(f(%d,%d))\n", - int(round(body->GetMetallicity()*multiplier)), multiplier, - int(round(body->GetVolcanicity()*multiplier)), multiplier, - int(round(body->GetVolatileGas()*multiplier)), multiplier, - int(round(body->GetAtmosOxidizing()*multiplier)), multiplier, - int(round(body->GetVolatileLiquid()*multiplier)), multiplier, - int(round(body->GetVolatileIces()*multiplier)), multiplier, - int(round(body->GetLife()*multiplier)), multiplier - ); - } + if (body->GetType() == SystemBody::TYPE_PLANET_TERRESTRIAL) + fprintf(f, + "\t:metallicity(f(%d,%d))\n" + "\t:volcanicity(f(%d,%d))\n" + "\t:atmos_density(f(%d,%d))\n" + "\t:atmos_oxidizing(f(%d,%d))\n" + "\t:ocean_cover(f(%d,%d))\n" + "\t:ice_cover(f(%d,%d))\n" + "\t:life(f(%d,%d))\n", + int(round(body->GetMetallicity() * multiplier)), multiplier, + int(round(body->GetVolcanicity() * multiplier)), multiplier, + int(round(body->GetVolatileGas() * multiplier)), multiplier, + int(round(body->GetAtmosOxidizing() * multiplier)), multiplier, + int(round(body->GetVolatileLiquid() * multiplier)), multiplier, + int(round(body->GetVolatileIces() * multiplier)), multiplier, + int(round(body->GetLife() * multiplier)), multiplier); + } - fprintf(f, "\n"); + fprintf(f, "\n"); - std::string code_list = code_name; - if (body->m_children.size() > 0) { - code_list = code_list + ", \n\t{\n"; - for (Uint32 ii = 0; ii < body->m_children.size(); ii++) { - code_list = code_list + "\t" + ExportBodyToLua(f, body->m_children[ii]) + ", \n"; - } - code_list = code_list + "\t}"; - } + std::string code_list = code_name; + if (body->m_children.size() > 0) { + code_list = code_list + ", \n\t{\n"; + for (Uint32 ii = 0; ii < body->m_children.size(); ii++) { + code_list = code_list + "\t" + ExportBodyToLua(f, body->m_children[ii]) + ", \n"; + } + code_list = code_list + "\t}"; + } - return code_list; + return code_list; } -std::string StarSystem::GetStarTypes(SystemBody *body) { - int bodyTypeIdx = 0; - std::string types = ""; - - if(body->GetSuperType() == SystemBody::SUPERTYPE_STAR) { - for(bodyTypeIdx = 0; ENUM_BodyType[bodyTypeIdx].name != 0; bodyTypeIdx++) { - if(ENUM_BodyType[bodyTypeIdx].value == body->GetType()) - break; - } - - types = types + "'" + ENUM_BodyType[bodyTypeIdx].name + "', "; - } - - for (Uint32 ii = 0; ii < body->m_children.size(); ii++) { - types = types + GetStarTypes(body->m_children[ii]); - } - - return types; -} - -void StarSystem::ExportToLua(const char *filename) { - FILE *f = fopen(filename,"w"); - int j; - - if(f == 0) - return; - - fprintf(f, "-- Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details\n"); - fprintf(f, "-- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt\n\n"); - - std::string stars_in_system = GetStarTypes(m_rootBody.Get()); - - for(j = 0; ENUM_PolitGovType[j].name != 0; j++) { - if(ENUM_PolitGovType[j].value == GetSysPolit().govType) - break; - } - - fprintf(f,"local system = CustomSystem:new('%s', { %s })\n\t:govtype('%s')\n\t:short_desc('%s')\n\t:long_desc([[%s]])\n\n", - GetName().c_str(), stars_in_system.c_str(), ENUM_PolitGovType[j].name, GetShortDescription().c_str(), GetLongDescription().c_str()); - - fprintf(f, "system:bodies(%s)\n\n", ExportBodyToLua(f, m_rootBody.Get()).c_str()); - - RefCountedPtr sec = m_galaxy->GetSector(GetPath()); - SystemPath pa = GetPath(); - - fprintf(f, "system:add_to_sector(%d,%d,%d,v(%.4f,%.4f,%.4f))\n", - pa.sectorX, pa.sectorY, pa.sectorZ, - sec->m_systems[pa.systemIndex].GetPosition().x/Sector::SIZE, - sec->m_systems[pa.systemIndex].GetPosition().y/Sector::SIZE, - sec->m_systems[pa.systemIndex].GetPosition().z/Sector::SIZE); - - fclose(f); -} - -void StarSystem::Dump(FILE* file, const char* indent, bool suppressSectorData) const +std::string StarSystem::GetStarTypes(SystemBody *body) { - if (suppressSectorData) { - fprintf(file, "%sStarSystem {%s\n", indent, m_hasCustomBodies ? " CUSTOM-ONLY" : m_isCustom ? " CUSTOM" : ""); - } else { - fprintf(file, "%sStarSystem(%d,%d,%d,%u) {\n", indent, m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex); - fprintf(file, "%s\t\"%s\"\n", indent, m_name.c_str()); - fprintf(file, "%s\t%sEXPLORED%s\n", indent, GetUnexplored() ? "UN" : "", m_hasCustomBodies ? ", CUSTOM-ONLY" : m_isCustom ? ", CUSTOM" : ""); - fprintf(file, "%s\tfaction %s%s%s\n", indent, m_faction ? "\"" : "NONE", m_faction ? m_faction->name.c_str() : "", m_faction ? "\"" : ""); - fprintf(file, "%s\tseed %u\n", indent, static_cast(m_seed)); - fprintf(file, "%s\t%u stars%s\n", indent, m_numStars, m_numStars > 0 ? " {" : ""); - assert(m_numStars == m_stars.size()); - for (unsigned i = 0; i < m_numStars; ++i) - fprintf(file, "%s\t\t%s\n", indent, EnumStrings::GetString("BodyType", m_stars[i]->GetType())); - if (m_numStars > 0) fprintf(file, "%s\t}\n", indent); - } - fprintf(file, "%s\t" SIZET_FMT " bodies, " SIZET_FMT " spaceports \n", indent, m_bodies.size(), m_spaceStations.size()); - fprintf(file, "%s\tpopulation %.0f\n", indent, m_totalPop.ToDouble() * 1e9); - fprintf(file, "%s\tgovernment %s/%s, lawlessness %.2f\n", indent, m_polit.GetGovernmentDesc(), m_polit.GetEconomicDesc(), - m_polit.lawlessness.ToDouble() * 100.0); - fprintf(file, "%s\teconomy type%s%s%s\n", indent, m_econType == 0 ? " NONE" : m_econType & GalacticEconomy::ECON_AGRICULTURE ? " AGRICULTURE" : "", - m_econType & GalacticEconomy::ECON_INDUSTRY ? " INDUSTRY" : "", m_econType & GalacticEconomy::ECON_MINING ? " MINING" : ""); - fprintf(file, "%s\thumanProx %.2f\n", indent, m_humanProx.ToDouble() * 100.0); - fprintf(file, "%s\tmetallicity %.2f, industrial %.2f, agricultural %.2f\n", indent, m_metallicity.ToDouble() * 100.0, - m_industrial.ToDouble() * 100.0, m_agricultural.ToDouble() * 100.0); - fprintf(file, "%s\ttrade levels {\n", indent); - for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; ++i) { - fprintf(file, "%s\t\t%s = %d\n", indent, EnumStrings::GetString("CommodityType", i), m_tradeLevel[i]); - } - fprintf(file, "%s\t}\n", indent); - if (m_rootBody) { - char buf[32]; - snprintf(buf, sizeof(buf), "%s\t", indent); - assert(m_rootBody->GetPath().IsSameSystem(m_path)); - m_rootBody->Dump(file, buf); - } - fprintf(file, "%s}\n", indent); + int bodyTypeIdx = 0; + std::string types = ""; + + if (body->GetSuperType() == SystemBody::SUPERTYPE_STAR) { + for (bodyTypeIdx = 0; ENUM_BodyType[bodyTypeIdx].name != 0; bodyTypeIdx++) { + if (ENUM_BodyType[bodyTypeIdx].value == body->GetType()) + break; + } + + types = types + "'" + ENUM_BodyType[bodyTypeIdx].name + "', "; + } + + for (Uint32 ii = 0; ii < body->m_children.size(); ii++) { + types = types + GetStarTypes(body->m_children[ii]); + } + + return types; +} + +void StarSystem::ExportToLua(const char *filename) +{ + FILE *f = fopen(filename, "w"); + int j; + + if (f == 0) + return; + + fprintf(f, "-- Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details\n"); + fprintf(f, "-- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt\n\n"); + + std::string stars_in_system = GetStarTypes(m_rootBody.Get()); + + for (j = 0; ENUM_PolitGovType[j].name != 0; j++) { + if (ENUM_PolitGovType[j].value == GetSysPolit().govType) + break; + } + + fprintf(f, "local system = CustomSystem:new('%s', { %s })\n\t:govtype('%s')\n\t:short_desc('%s')\n\t:long_desc([[%s]])\n\n", + GetName().c_str(), stars_in_system.c_str(), ENUM_PolitGovType[j].name, GetShortDescription().c_str(), GetLongDescription().c_str()); + + fprintf(f, "system:bodies(%s)\n\n", ExportBodyToLua(f, m_rootBody.Get()).c_str()); + + RefCountedPtr sec = m_galaxy->GetSector(GetPath()); + SystemPath pa = GetPath(); + + fprintf(f, "system:add_to_sector(%d,%d,%d,v(%.4f,%.4f,%.4f))\n", + pa.sectorX, pa.sectorY, pa.sectorZ, + sec->m_systems[pa.systemIndex].GetPosition().x / Sector::SIZE, + sec->m_systems[pa.systemIndex].GetPosition().y / Sector::SIZE, + sec->m_systems[pa.systemIndex].GetPosition().z / Sector::SIZE); + + fclose(f); +} + +void StarSystem::Dump(FILE *file, const char *indent, bool suppressSectorData) const +{ + if (suppressSectorData) { + fprintf(file, "%sStarSystem {%s\n", indent, m_hasCustomBodies ? " CUSTOM-ONLY" : m_isCustom ? " CUSTOM" : ""); + } else { + fprintf(file, "%sStarSystem(%d,%d,%d,%u) {\n", indent, m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex); + fprintf(file, "%s\t\"%s\"\n", indent, m_name.c_str()); + fprintf(file, "%s\t%sEXPLORED%s\n", indent, GetUnexplored() ? "UN" : "", m_hasCustomBodies ? ", CUSTOM-ONLY" : m_isCustom ? ", CUSTOM" : ""); + fprintf(file, "%s\tfaction %s%s%s\n", indent, m_faction ? "\"" : "NONE", m_faction ? m_faction->name.c_str() : "", m_faction ? "\"" : ""); + fprintf(file, "%s\tseed %u\n", indent, static_cast(m_seed)); + fprintf(file, "%s\t%u stars%s\n", indent, m_numStars, m_numStars > 0 ? " {" : ""); + assert(m_numStars == m_stars.size()); + for (unsigned i = 0; i < m_numStars; ++i) + fprintf(file, "%s\t\t%s\n", indent, EnumStrings::GetString("BodyType", m_stars[i]->GetType())); + if (m_numStars > 0) fprintf(file, "%s\t}\n", indent); + } + fprintf(file, "%s\t" SIZET_FMT " bodies, " SIZET_FMT " spaceports \n", indent, m_bodies.size(), m_spaceStations.size()); + fprintf(file, "%s\tpopulation %.0f\n", indent, m_totalPop.ToDouble() * 1e9); + fprintf(file, "%s\tgovernment %s/%s, lawlessness %.2f\n", indent, m_polit.GetGovernmentDesc(), m_polit.GetEconomicDesc(), + m_polit.lawlessness.ToDouble() * 100.0); + fprintf(file, "%s\teconomy type%s%s%s\n", indent, m_econType == 0 ? " NONE" : m_econType & GalacticEconomy::ECON_AGRICULTURE ? " AGRICULTURE" : "", + m_econType & GalacticEconomy::ECON_INDUSTRY ? " INDUSTRY" : "", m_econType & GalacticEconomy::ECON_MINING ? " MINING" : ""); + fprintf(file, "%s\thumanProx %.2f\n", indent, m_humanProx.ToDouble() * 100.0); + fprintf(file, "%s\tmetallicity %.2f, industrial %.2f, agricultural %.2f\n", indent, m_metallicity.ToDouble() * 100.0, + m_industrial.ToDouble() * 100.0, m_agricultural.ToDouble() * 100.0); + fprintf(file, "%s\ttrade levels {\n", indent); + for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; ++i) { + fprintf(file, "%s\t\t%s = %d\n", indent, EnumStrings::GetString("CommodityType", i), m_tradeLevel[i]); + } + fprintf(file, "%s\t}\n", indent); + if (m_rootBody) { + char buf[32]; + snprintf(buf, sizeof(buf), "%s\t", indent); + assert(m_rootBody->GetPath().IsSameSystem(m_path)); + m_rootBody->Dump(file, buf); + } + fprintf(file, "%s}\n", indent); } diff --git a/src/galaxy/StarSystem.h b/src/galaxy/StarSystem.h index ea8c81cce..831b3b1e3 100644 --- a/src/galaxy/StarSystem.h +++ b/src/galaxy/StarSystem.h @@ -4,18 +4,18 @@ #ifndef _STARSYSTEM_H #define _STARSYSTEM_H -#include "libs.h" -#include "galaxy/Economy.h" -#include "Polit.h" -#include -#include -#include "RefCounted.h" -#include "galaxy/SystemPath.h" -#include "galaxy/GalaxyCache.h" -#include "Orbit.h" #include "IterationProxy.h" +#include "Orbit.h" +#include "Polit.h" +#include "RefCounted.h" +#include "galaxy/Economy.h" +#include "galaxy/GalaxyCache.h" +#include "galaxy/SystemPath.h" #include "gameconsts.h" +#include "libs.h" #include +#include +#include class Galaxy; class CustomSystemBody; @@ -38,7 +38,7 @@ struct RingStyle { class SystemBody : public RefCounted { public: - SystemBody(const SystemPath& path, StarSystem *system); + SystemBody(const SystemPath &path, StarSystem *system); enum BodyType { // TYPE_GRAVPOINT = 0, @@ -50,7 +50,7 @@ public: TYPE_STAR_F = 6, //white TYPE_STAR_A = 7, //blue/white TYPE_STAR_B = 8, //blue - TYPE_STAR_O = 9, //blue/purple/white + TYPE_STAR_O = 9, //blue/purple/white TYPE_STAR_M_GIANT = 10, TYPE_STAR_K_GIANT = 11, TYPE_STAR_G_GIANT = 12, @@ -72,8 +72,8 @@ public: TYPE_STAR_A_HYPER_GIANT = 28, TYPE_STAR_B_HYPER_GIANT = 29, TYPE_STAR_O_HYPER_GIANT = 30, // these various stars do exist = they are transitional states and are rare - TYPE_STAR_M_WF = 31, //Wolf-Rayet star - TYPE_STAR_B_WF = 32, // while you do not specifically get class M,B or O WF stars, + TYPE_STAR_M_WF = 31, //Wolf-Rayet star + TYPE_STAR_B_WF = 32, // while you do not specifically get class M,B or O WF stars, TYPE_STAR_O_WF = 33, // you do get red = blue and purple from the colour of the gasses = so spectral class is an easy way to define them. TYPE_STAR_S_BH = 34, //stellar blackhole TYPE_STAR_IM_BH = 35, //Intermediate-mass blackhole @@ -98,16 +98,16 @@ public: SUPERTYPE_STARPORT = 4, }; - const SystemPath& GetPath() const { return m_path; } - SystemBody* GetParent() const { return m_parent; } + const SystemPath &GetPath() const { return m_path; } + SystemBody *GetParent() const { return m_parent; } bool IsPlanet() const; bool IsMoon() const { return GetSuperType() == SUPERTYPE_ROCKY_PLANET && !IsPlanet(); } bool HasChildren() const { return !m_children.empty(); } Uint32 GetNumChildren() const { return static_cast(m_children.size()); } - IterationProxy > GetChildren() { return MakeIterationProxy(m_children); } - const IterationProxy > GetChildren() const { return MakeIterationProxy(m_children); } + IterationProxy> GetChildren() { return MakeIterationProxy(m_children); } + const IterationProxy> GetChildren() const { return MakeIterationProxy(m_children); } std::string GetName() const { return m_name; } std::string GetAstroDescription() const; @@ -115,10 +115,11 @@ public: BodyType GetType() const { return m_type; } BodySuperType GetSuperType() const; bool IsCustomBody() const { return m_isCustomBody; } - bool IsCoOrbitalWith(const SystemBody* other) const; //this and other form a binary pair - bool IsCoOrbital() const; //is part of any binary pair + bool IsCoOrbitalWith(const SystemBody *other) const; //this and other form a binary pair + bool IsCoOrbital() const; //is part of any binary pair fixed GetRadiusAsFixed() const { return m_radius; } - double GetRadius() const { // polar radius + double GetRadius() const + { // polar radius if (GetSuperType() <= SUPERTYPE_STAR) return (m_radius.ToDouble() / m_aspectRatio.ToDouble()) * SOL_RADIUS; else @@ -126,13 +127,15 @@ public: } double GetAspectRatio() const { return m_aspectRatio.ToDouble(); } fixed GetMassAsFixed() const { return m_mass; } - double GetMass() const { + double GetMass() const + { if (GetSuperType() <= SUPERTYPE_STAR) return m_mass.ToDouble() * SOL_MASS; else return m_mass.ToDouble() * EARTH_MASS; } - fixed GetMassInEarths() const { + fixed GetMassInEarths() const + { if (GetSuperType() <= SUPERTYPE_STAR) return m_mass * 332998; else @@ -142,15 +145,16 @@ public: // returned in seconds double GetRotationPeriodInDays() const { return m_rotationPeriod.ToDouble(); } fixed GetRotationPeriodAsFixed() const { return m_rotationPeriod; } - double GetRotationPeriod() const { - return m_rotationPeriod.ToDouble()*60*60*24; + double GetRotationPeriod() const + { + return m_rotationPeriod.ToDouble() * 60 * 60 * 24; } bool HasRotationPhase() const { return m_rotationalPhaseAtStart != fixed(0); } double GetRotationPhaseAtStart() const { return m_rotationalPhaseAtStart.ToDouble(); } double GetAxialTilt() const { return m_axialTilt.ToDouble(); } fixed GetAxialTiltAsFixed() const { return m_axialTilt; } - const Orbit& GetOrbit() const { return m_orbit; } + const Orbit &GetOrbit() const { return m_orbit; } double GetEccentricity() const { return m_eccentricity.ToDouble(); } fixed GetEccentricityAsFixed() const { return m_eccentricity; } double GetOrbMin() const { return m_orbMin.ToDouble(); } @@ -191,20 +195,21 @@ public: double GetMaxChildOrbitalDistance() const; bool HasRings() const { return bool(m_rings.maxRadius.v); } - const RingStyle& GetRings() const { return m_rings; } - + const RingStyle &GetRings() const { return m_rings; } // XXX merge all this atmosphere stuff bool HasAtmosphere() const; - Color GetAlbedo() const { + Color GetAlbedo() const + { // XXX suggestions about how to determine a sensible albedo colour would be welcome // Currently (2014-03-24) this is just used as the colour for the body billboard // which is rendered when the body has a small screen size - return Color(200,200,200,255); + return Color(200, 200, 200, 255); } - void GetAtmosphereFlavor(Color *outColor, double *outDensity) const { + void GetAtmosphereFlavor(Color *outColor, double *outDensity) const + { *outColor = m_atmosColor; *outDensity = m_atmosDensity; } @@ -222,9 +227,9 @@ public: bool IsScoopable() const; - void Dump(FILE* file, const char* indent = "") const; + void Dump(FILE *file, const char *indent = "") const; - StarSystem* GetStarSystem() const { return m_system; } + StarSystem *GetStarSystem() const { return m_system; } const std::string &GetSpaceStationType() const { return m_space_station_type; } @@ -238,8 +243,8 @@ private: void ClearParentAndChildPointers(); - SystemBody *m_parent; // these are only valid if the StarSystem - std::vector m_children; // that create them still exists + SystemBody *m_parent; // these are only valid if the StarSystem + std::vector m_children; // that create them still exists SystemPath m_path; Orbit m_orbit; @@ -309,8 +314,8 @@ public: static void ToJson(Json &jsonObj, StarSystem *); static RefCountedPtr FromJson(RefCountedPtr galaxy, const Json &jsonObj); const SystemPath &GetPath() const { return m_path; } - const std::string& GetShortDescription() const { return m_shortDesc; } - const std::string& GetLongDescription() const { return m_longDesc; } + const std::string &GetShortDescription() const { return m_shortDesc; } + const std::string &GetLongDescription() const { return m_longDesc; } unsigned GetNumStars() const { return m_numStars; } const SysPolit &GetSysPolit() const { return m_polit; } @@ -323,23 +328,25 @@ public: RefCountedPtr GetRootBody() { return m_rootBody; } bool HasSpaceStations() const { return !m_spaceStations.empty(); } Uint32 GetNumSpaceStations() const { return static_cast(m_spaceStations.size()); } - IterationProxy > GetSpaceStations() { return MakeIterationProxy(m_spaceStations); } - const IterationProxy > GetSpaceStations() const { return MakeIterationProxy(m_spaceStations); } - IterationProxy > GetStars() { return MakeIterationProxy(m_stars); } - const IterationProxy > GetStars() const { return MakeIterationProxy(m_stars); } + IterationProxy> GetSpaceStations() { return MakeIterationProxy(m_spaceStations); } + const IterationProxy> GetSpaceStations() const { return MakeIterationProxy(m_spaceStations); } + IterationProxy> GetStars() { return MakeIterationProxy(m_stars); } + const IterationProxy> GetStars() const { return MakeIterationProxy(m_stars); } Uint32 GetNumBodies() const { return static_cast(m_bodies.size()); } - IterationProxy > > GetBodies() { return MakeIterationProxy(m_bodies); } - const IterationProxy > > GetBodies() const { return MakeIterationProxy(m_bodies); } + IterationProxy>> GetBodies() { return MakeIterationProxy(m_bodies); } + const IterationProxy>> GetBodies() const { return MakeIterationProxy(m_bodies); } - bool IsCommodityLegal(const GalacticEconomy::Commodity t) { + bool IsCommodityLegal(const GalacticEconomy::Commodity t) + { return m_commodityLegal[int(t)]; } - int GetCommodityBasePriceModPercent(GalacticEconomy::Commodity t) { + int GetCommodityBasePriceModPercent(GalacticEconomy::Commodity t) + { return m_tradeLevel[int(t)]; } - const Faction* GetFaction() const { return m_faction; } + const Faction *GetFaction() const { return m_faction; } bool GetUnexplored() const { return m_explored == eUNEXPLORED; } ExplorationState GetExplored() const { return m_explored; } double GetExploredTime() const { return m_exploredTime; } @@ -349,30 +356,35 @@ public: fixed GetIndustrial() const { return m_industrial; } fixed GetAgricultural() const { return m_agricultural; } GalacticEconomy::EconType GetEconType() const { return m_econType; } - const int* GetTradeLevel() const { return m_tradeLevel; } + const int *GetTradeLevel() const { return m_tradeLevel; } int GetSeed() const { return m_seed; } fixed GetHumanProx() const { return m_humanProx; } fixed GetTotalPop() const { return m_totalPop; } - void Dump(FILE* file, const char* indent = "", bool suppressSectorData = false) const; + void Dump(FILE *file, const char *indent = "", bool suppressSectorData = false) const; const RefCountedPtr m_galaxy; protected: - StarSystem(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache* cache, Random& rand); + StarSystem(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache *cache, Random &rand); virtual ~StarSystem(); - SystemBody *NewBody() { + SystemBody *NewBody() + { SystemBody *body = new SystemBody(SystemPath(m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex, static_cast(m_bodies.size())), this); m_bodies.push_back(RefCountedPtr(body)); return body; } void MakeShortDescription(); - void SetShortDesc(const std::string& desc) { m_shortDesc = desc; } + void SetShortDesc(const std::string &desc) { m_shortDesc = desc; } private: - void SetCache(StarSystemCache* cache) { assert(!m_cache); m_cache = cache; } + void SetCache(StarSystemCache *cache) + { + assert(!m_cache); + m_cache = cache; + } std::string ExportBodyToLua(FILE *f, SystemBody *body); std::string GetStarTypes(SystemBody *body); @@ -387,7 +399,7 @@ private: bool m_isCustom; bool m_hasCustomBodies; - const Faction* m_faction; + const Faction *m_faction; ExplorationState m_explored; double m_exploredTime; fixed m_metallicity; @@ -404,32 +416,40 @@ private: RefCountedPtr m_rootBody; // index into this will be the SystemBody ID used by SystemPath - std::vector< RefCountedPtr > m_bodies; - std::vector m_spaceStations; - std::vector m_stars; + std::vector> m_bodies; + std::vector m_spaceStations; + std::vector m_stars; std::vector m_commodityLegal; - StarSystemCache* m_cache; + StarSystemCache *m_cache; }; class StarSystem::GeneratorAPI : public StarSystem { private: friend class GalaxyGenerator; - GeneratorAPI(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache* cache, Random& rand); + GeneratorAPI(const SystemPath &path, RefCountedPtr galaxy, StarSystemCache *cache, Random &rand); public: bool HasCustomBodies() const { return m_hasCustomBodies; } - void SetCustom(bool isCustom, bool hasCustomBodies) { m_isCustom = isCustom; m_hasCustomBodies = hasCustomBodies; } + void SetCustom(bool isCustom, bool hasCustomBodies) + { + m_isCustom = isCustom; + m_hasCustomBodies = hasCustomBodies; + } void SetNumStars(int numStars) { m_numStars = numStars; } void SetRootBody(RefCountedPtr rootBody) { m_rootBody = rootBody; } - void SetRootBody(SystemBody* rootBody) { m_rootBody.Reset(rootBody); } - void SetName(const std::string& name) { m_name = name; } - void SetOtherNames(const std::vector& other_names) { m_other_names = other_names; } - void SetLongDesc(const std::string& desc) { m_longDesc = desc; } - void SetExplored(ExplorationState explored, double time) { m_explored = explored; m_exploredTime = time; } + void SetRootBody(SystemBody *rootBody) { m_rootBody.Reset(rootBody); } + void SetName(const std::string &name) { m_name = name; } + void SetOtherNames(const std::vector &other_names) { m_other_names = other_names; } + void SetLongDesc(const std::string &desc) { m_longDesc = desc; } + void SetExplored(ExplorationState explored, double time) + { + m_explored = explored; + m_exploredTime = time; + } void SetSeed(Uint32 seed) { m_seed = seed; } - void SetFaction(const Faction* faction) { m_faction = faction; } + void SetFaction(const Faction *faction) { m_faction = faction; } void SetEconType(GalacticEconomy::EconType econType) { m_econType = econType; } void SetSysPolit(SysPolit polit) { m_polit = polit; } void SetMetallicity(fixed metallicity) { m_metallicity = metallicity; } @@ -442,10 +462,18 @@ public: void AddTradeLevel(GalacticEconomy::Commodity type, int level) { m_tradeLevel[int(type)] += level; } void SetCommodityLegal(GalacticEconomy::Commodity type, bool legal) { m_commodityLegal[int(type)] = legal; } - void AddSpaceStation(SystemBody* station) { assert(station->GetSuperType() == SystemBody::SUPERTYPE_STARPORT); m_spaceStations.push_back(station); } - void AddStar(SystemBody* star) { assert(star->GetSuperType() == SystemBody::SUPERTYPE_STAR); m_stars.push_back(star);} - using StarSystem::NewBody; + void AddSpaceStation(SystemBody *station) + { + assert(station->GetSuperType() == SystemBody::SUPERTYPE_STARPORT); + m_spaceStations.push_back(station); + } + void AddStar(SystemBody *star) + { + assert(star->GetSuperType() == SystemBody::SUPERTYPE_STAR); + m_stars.push_back(star); + } using StarSystem::MakeShortDescription; + using StarSystem::NewBody; using StarSystem::SetShortDesc; }; diff --git a/src/galaxy/StarSystemGenerator.cpp b/src/galaxy/StarSystemGenerator.cpp index 227060607..047d6bebf 100644 --- a/src/galaxy/StarSystemGenerator.cpp +++ b/src/galaxy/StarSystemGenerator.cpp @@ -2,224 +2,185 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "StarSystemGenerator.h" +#include "Factions.h" +#include "Galaxy.h" +#include "Lang.h" #include "LuaNameGen.h" #include "Pi.h" -#include "Galaxy.h" #include "Sector.h" -#include "Factions.h" -#include "Lang.h" -static const fixed SUN_MASS_TO_EARTH_MASS = fixed(332998,1); // XXX Duplication from StarSystem.cpp +static const fixed SUN_MASS_TO_EARTH_MASS = fixed(332998, 1); // XXX Duplication from StarSystem.cpp // if binary stars have separation s, planets can have stable // orbits at (0.5 * s * SAFE_DIST_FROM_BINARY) -static const fixed SAFE_DIST_FROM_BINARY = fixed(5,1); +static const fixed SAFE_DIST_FROM_BINARY = fixed(5, 1); // very crudely -static const fixed AU_SOL_RADIUS = fixed(305,65536); +static const fixed AU_SOL_RADIUS = fixed(305, 65536); static const fixed AU_EARTH_RADIUS = fixed(3, 65536); // XXX Duplication from StarSystem.cpp -static const fixed FIXED_PI = fixed(103993,33102); // XXX Duplication from StarSystem.cpp -static const double CELSIUS = 273.15; +static const fixed FIXED_PI = fixed(103993, 33102); // XXX Duplication from StarSystem.cpp +static const double CELSIUS = 273.15; static const Uint32 POLIT_SEED = 0x1234abcd; static const Uint32 POLIT_SALT = 0x8732abdf; const fixed StarSystemLegacyGeneratorBase::starMetallicities[] = { - fixed(1,1), // GRAVPOINT - for planets that orbit them - fixed(9,10), // brown dwarf - fixed(5,10), // white dwarf - fixed(7,10), // M0 - fixed(6,10), // K0 - fixed(5,10), // G0 - fixed(4,10), // F0 - fixed(3,10), // A0 - fixed(2,10), // B0 - fixed(1,10), // O5 - fixed(8,10), // M0 Giant - fixed(65,100), // K0 Giant - fixed(55,100), // G0 Giant - fixed(4,10), // F0 Giant - fixed(3,10), // A0 Giant - fixed(2,10), // B0 Giant - fixed(1,10), // O5 Giant - fixed(9,10), // M0 Super Giant - fixed(7,10), // K0 Super Giant - fixed(6,10), // G0 Super Giant - fixed(4,10), // F0 Super Giant - fixed(3,10), // A0 Super Giant - fixed(2,10), // B0 Super Giant - fixed(1,10), // O5 Super Giant - fixed(1,1), // M0 Hyper Giant - fixed(7,10), // K0 Hyper Giant - fixed(6,10), // G0 Hyper Giant - fixed(4,10), // F0 Hyper Giant - fixed(3,10), // A0 Hyper Giant - fixed(2,10), // B0 Hyper Giant - fixed(1,10), // O5 Hyper Giant - fixed(1,1), // M WF - fixed(8,10), // B WF - fixed(6,10), // O WF - fixed(1,1), // S BH Blackholes, give them high metallicity, - fixed(1,1), // IM BH so any rocks that happen to be there - fixed(1,1) // SM BH may be mining hotspots. FUN :) + fixed(1, 1), // GRAVPOINT - for planets that orbit them + fixed(9, 10), // brown dwarf + fixed(5, 10), // white dwarf + fixed(7, 10), // M0 + fixed(6, 10), // K0 + fixed(5, 10), // G0 + fixed(4, 10), // F0 + fixed(3, 10), // A0 + fixed(2, 10), // B0 + fixed(1, 10), // O5 + fixed(8, 10), // M0 Giant + fixed(65, 100), // K0 Giant + fixed(55, 100), // G0 Giant + fixed(4, 10), // F0 Giant + fixed(3, 10), // A0 Giant + fixed(2, 10), // B0 Giant + fixed(1, 10), // O5 Giant + fixed(9, 10), // M0 Super Giant + fixed(7, 10), // K0 Super Giant + fixed(6, 10), // G0 Super Giant + fixed(4, 10), // F0 Super Giant + fixed(3, 10), // A0 Super Giant + fixed(2, 10), // B0 Super Giant + fixed(1, 10), // O5 Super Giant + fixed(1, 1), // M0 Hyper Giant + fixed(7, 10), // K0 Hyper Giant + fixed(6, 10), // G0 Hyper Giant + fixed(4, 10), // F0 Hyper Giant + fixed(3, 10), // A0 Hyper Giant + fixed(2, 10), // B0 Hyper Giant + fixed(1, 10), // O5 Hyper Giant + fixed(1, 1), // M WF + fixed(8, 10), // B WF + fixed(6, 10), // O WF + fixed(1, 1), // S BH Blackholes, give them high metallicity, + fixed(1, 1), // IM BH so any rocks that happen to be there + fixed(1, 1) // SM BH may be mining hotspots. FUN :) }; const StarSystemLegacyGeneratorBase::StarTypeInfo StarSystemLegacyGeneratorBase::starTypeInfo[] = { - { - {}, {}, - 0, 0 - }, { - //Brown Dwarf - {2,8}, {10,30}, - 1000, 2000 - }, { - //white dwarf - {20,100}, {1,2}, - 4000, 40000 - }, { - //M - {10,47}, {30,60}, - 2000, 3500 - }, { - //K - {50,78}, {60,100}, - 3500, 5000 - }, { - //G - {80,110}, {80,120}, - 5000, 6000 - }, { - //F - {115,170}, {110,150}, - 6000, 7500 - }, { - //A - {180,320}, {120,220}, - 7500, 10000 - }, { - //B - {200,300}, {120,290}, - 10000, 30000 - }, { - //O - {300,400}, {200,310}, - 30000, 60000 - }, { - //M Giant - {60,357}, {2000,5000}, - 2500, 3500 - }, { - //K Giant - {125,500}, {1500,3000}, - 3500, 5000 - }, { - //G Giant - {200,800}, {1000,2000}, - 5000, 6000 - }, { - //F Giant - {250,900}, {800,1500}, - 6000, 7500 - }, { - //A Giant - {400,1000}, {600,1000}, - 7500, 10000 - }, { - //B Giant - {500,1000}, {600,1000}, - 10000, 30000 - }, { - //O Giant - {600,1200}, {600,1000}, - 30000, 60000 - }, { - //M Super Giant - {1050,5000}, {7000,15000}, - 2500, 3500 - }, { - //K Super Giant - {1100,5000}, {5000,9000}, - 3500, 5000 - }, { - //G Super Giant - {1200,5000}, {4000,8000}, - 5000, 6000 - }, { - //F Super Giant - {1500,6000}, {3500,7000}, - 6000, 7500 - }, { - //A Super Giant - {2000,8000}, {3000,6000}, - 7500, 10000 - }, { - //B Super Giant - {3000,9000}, {2500,5000}, - 10000, 30000 - }, { - //O Super Giant - {5000,10000}, {2000,4000}, - 30000, 60000 - }, { - //M Hyper Giant - {5000,15000}, {20000,40000}, - 2500, 3500 - }, { - //K Hyper Giant - {5000,17000}, {17000,25000}, - 3500, 5000 - }, { - //G Hyper Giant - {5000,18000}, {14000,20000}, - 5000, 6000 - }, { - //F Hyper Giant - {5000,19000}, {12000,17500}, - 6000, 7500 - }, { - //A Hyper Giant - {5000,20000}, {10000,15000}, - 7500, 10000 - }, { - //B Hyper Giant - {5000,23000}, {6000,10000}, - 10000, 30000 - }, { - //O Hyper Giant - {10000,30000}, {4000,7000}, - 30000, 60000 - }, { - // M WF - {2000,5000}, {2500,5000}, - 25000, 35000 - }, { - // B WF - {2000,7500}, {2500,5000}, - 35000, 45000 - }, { - // O WF - {2000,10000}, {2500,5000}, - 45000, 60000 - }, { - // S BH - {20,2000}, {0,0}, // XXX black holes are < 1 Sol radii big; this is clamped to a non-zero value later - 10, 24 - }, { - // IM BH - {900000,1000000}, {100,500}, - 1, 10 - }, { - // SM BH - {2000000,5000000}, {10000,20000}, - 10, 24 - } + { {}, {}, + 0, 0 }, + { //Brown Dwarf + { 2, 8 }, { 10, 30 }, + 1000, 2000 }, + { //white dwarf + { 20, 100 }, { 1, 2 }, + 4000, 40000 }, + { //M + { 10, 47 }, { 30, 60 }, + 2000, 3500 }, + { //K + { 50, 78 }, { 60, 100 }, + 3500, 5000 }, + { //G + { 80, 110 }, { 80, 120 }, + 5000, 6000 }, + { //F + { 115, 170 }, { 110, 150 }, + 6000, 7500 }, + { //A + { 180, 320 }, { 120, 220 }, + 7500, 10000 }, + { //B + { 200, 300 }, { 120, 290 }, + 10000, 30000 }, + { //O + { 300, 400 }, { 200, 310 }, + 30000, 60000 }, + { //M Giant + { 60, 357 }, { 2000, 5000 }, + 2500, 3500 }, + { //K Giant + { 125, 500 }, { 1500, 3000 }, + 3500, 5000 }, + { //G Giant + { 200, 800 }, { 1000, 2000 }, + 5000, 6000 }, + { //F Giant + { 250, 900 }, { 800, 1500 }, + 6000, 7500 }, + { //A Giant + { 400, 1000 }, { 600, 1000 }, + 7500, 10000 }, + { //B Giant + { 500, 1000 }, { 600, 1000 }, + 10000, 30000 }, + { //O Giant + { 600, 1200 }, { 600, 1000 }, + 30000, 60000 }, + { //M Super Giant + { 1050, 5000 }, { 7000, 15000 }, + 2500, 3500 }, + { //K Super Giant + { 1100, 5000 }, { 5000, 9000 }, + 3500, 5000 }, + { //G Super Giant + { 1200, 5000 }, { 4000, 8000 }, + 5000, 6000 }, + { //F Super Giant + { 1500, 6000 }, { 3500, 7000 }, + 6000, 7500 }, + { //A Super Giant + { 2000, 8000 }, { 3000, 6000 }, + 7500, 10000 }, + { //B Super Giant + { 3000, 9000 }, { 2500, 5000 }, + 10000, 30000 }, + { //O Super Giant + { 5000, 10000 }, { 2000, 4000 }, + 30000, 60000 }, + { //M Hyper Giant + { 5000, 15000 }, { 20000, 40000 }, + 2500, 3500 }, + { //K Hyper Giant + { 5000, 17000 }, { 17000, 25000 }, + 3500, 5000 }, + { //G Hyper Giant + { 5000, 18000 }, { 14000, 20000 }, + 5000, 6000 }, + { //F Hyper Giant + { 5000, 19000 }, { 12000, 17500 }, + 6000, 7500 }, + { //A Hyper Giant + { 5000, 20000 }, { 10000, 15000 }, + 7500, 10000 }, + { //B Hyper Giant + { 5000, 23000 }, { 6000, 10000 }, + 10000, 30000 }, + { //O Hyper Giant + { 10000, 30000 }, { 4000, 7000 }, + 30000, 60000 }, + { // M WF + { 2000, 5000 }, { 2500, 5000 }, + 25000, 35000 }, + { // B WF + { 2000, 7500 }, { 2500, 5000 }, + 35000, 45000 }, + { // O WF + { 2000, 10000 }, { 2500, 5000 }, + 45000, 60000 }, + { // S BH + { 20, 2000 }, { 0, 0 }, // XXX black holes are < 1 Sol radii big; this is clamped to a non-zero value later + 10, 24 }, + { // IM BH + { 900000, 1000000 }, { 100, 500 }, + 1, 10 }, + { // SM BH + { 2000000, 5000000 }, { 10000, 20000 }, + 10, 24 } }; - -bool StarSystemFromSectorGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config) +bool StarSystemFromSectorGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config) { PROFILE_SCOPED() RefCountedPtr sec = galaxy->GetSector(system->GetPath()); assert(system->GetPath().systemIndex >= 0 && system->GetPath().systemIndex < sec->m_systems.size()); - const Sector::System& secSys = sec->m_systems[system->GetPath().systemIndex]; + const Sector::System &secSys = sec->m_systems[system->GetPath().systemIndex]; system->SetFaction(galaxy->GetFactions()->GetNearestClaimant(&secSys)); system->SetSeed(secSys.GetSeed()); @@ -229,8 +190,7 @@ bool StarSystemFromSectorGenerator::Apply(Random& rng, RefCountedPtr gal return true; } - -void StarSystemLegacyGeneratorBase::PickAtmosphere(SystemBody* sbody) +void StarSystemLegacyGeneratorBase::PickAtmosphere(SystemBody *sbody) { PROFILE_SCOPED() /* Alpha value isn't real alpha. in the shader fog depth is determined @@ -241,74 +201,74 @@ void StarSystemLegacyGeneratorBase::PickAtmosphere(SystemBody* sbody) for some variation to atmosphere colours */ switch (sbody->GetType()) { - case SystemBody::TYPE_PLANET_GAS_GIANT: + case SystemBody::TYPE_PLANET_GAS_GIANT: - sbody->m_atmosColor = Color(255, 255, 255, 3); - sbody->m_atmosDensity = 14.0; - break; - case SystemBody::TYPE_PLANET_ASTEROID: - sbody->m_atmosColor = Color::BLANK; - sbody->m_atmosDensity = 0.0; - break; - default: - case SystemBody::TYPE_PLANET_TERRESTRIAL: - double r = 0, g = 0, b = 0; - double atmo = sbody->GetAtmosOxidizing(); - if (sbody->GetVolatileGas() > 0.001) { - if (atmo > 0.95) { - // o2 - r = 1.0f + ((0.95f-atmo)*15.0f); - g = 0.95f + ((0.95f-atmo)*10.0f); - b = atmo*atmo*atmo*atmo*atmo; - } else if (atmo > 0.7) { - // co2 - r = atmo+0.05f; - g = 1.0f + (0.7f-atmo); - b = 0.8f; - } else if (atmo > 0.65) { - // co - r = 1.0f + (0.65f-atmo); - g = 0.8f; - b = atmo + 0.25f; - } else if (atmo > 0.55) { - // ch4 - r = 1.0f + ((0.55f-atmo)*5.0); - g = 0.35f - ((0.55f-atmo)*5.0); - b = 0.4f; - } else if (atmo > 0.3) { - // h - r = 1.0f; - g = 1.0f; - b = 1.0f; - } else if (atmo > 0.2) { - // he - r = 1.0f; - g = 1.0f; - b = 1.0f; - } else if (atmo > 0.15) { - // ar - r = 0.5f - ((0.15f-atmo)*5.0); - g = 0.0f; - b = 0.5f + ((0.15f-atmo)*5.0); - } else if (atmo > 0.1) { - // s - r = 0.8f - ((0.1f-atmo)*4.0); - g = 1.0f; - b = 0.5f - ((0.1f-atmo)*10.0); - } else { - // n - r = 1.0f; - g = 1.0f; - b = 1.0f; - } - sbody->m_atmosColor = Color(r*255, g*255, b*255, 255); + sbody->m_atmosColor = Color(255, 255, 255, 3); + sbody->m_atmosDensity = 14.0; + break; + case SystemBody::TYPE_PLANET_ASTEROID: + sbody->m_atmosColor = Color::BLANK; + sbody->m_atmosDensity = 0.0; + break; + default: + case SystemBody::TYPE_PLANET_TERRESTRIAL: + double r = 0, g = 0, b = 0; + double atmo = sbody->GetAtmosOxidizing(); + if (sbody->GetVolatileGas() > 0.001) { + if (atmo > 0.95) { + // o2 + r = 1.0f + ((0.95f - atmo) * 15.0f); + g = 0.95f + ((0.95f - atmo) * 10.0f); + b = atmo * atmo * atmo * atmo * atmo; + } else if (atmo > 0.7) { + // co2 + r = atmo + 0.05f; + g = 1.0f + (0.7f - atmo); + b = 0.8f; + } else if (atmo > 0.65) { + // co + r = 1.0f + (0.65f - atmo); + g = 0.8f; + b = atmo + 0.25f; + } else if (atmo > 0.55) { + // ch4 + r = 1.0f + ((0.55f - atmo) * 5.0); + g = 0.35f - ((0.55f - atmo) * 5.0); + b = 0.4f; + } else if (atmo > 0.3) { + // h + r = 1.0f; + g = 1.0f; + b = 1.0f; + } else if (atmo > 0.2) { + // he + r = 1.0f; + g = 1.0f; + b = 1.0f; + } else if (atmo > 0.15) { + // ar + r = 0.5f - ((0.15f - atmo) * 5.0); + g = 0.0f; + b = 0.5f + ((0.15f - atmo) * 5.0); + } else if (atmo > 0.1) { + // s + r = 0.8f - ((0.1f - atmo) * 4.0); + g = 1.0f; + b = 0.5f - ((0.1f - atmo) * 10.0); } else { - sbody->m_atmosColor = Color::BLANK; + // n + r = 1.0f; + g = 1.0f; + b = 1.0f; } - sbody->m_atmosDensity = sbody->GetVolatileGas(); - //Output("| Atmosphere :\n| red : [%f] \n| green : [%f] \n| blue : [%f] \n", r, g, b); - //Output("-------------------------------\n"); - break; + sbody->m_atmosColor = Color(r * 255, g * 255, b * 255, 255); + } else { + sbody->m_atmosColor = Color::BLANK; + } + sbody->m_atmosDensity = sbody->GetVolatileGas(); + //Output("| Atmosphere :\n| red : [%f] \n| green : [%f] \n| blue : [%f] \n", r, g, b); + //Output("-------------------------------\n"); + break; /*default: sbody->m_atmosColor = Color(0.6f, 0.6f, 0.6f, 1.0f); sbody->m_atmosDensity = m_body->m_volatileGas.ToDouble(); @@ -317,32 +277,28 @@ void StarSystemLegacyGeneratorBase::PickAtmosphere(SystemBody* sbody) } static const unsigned char RANDOM_RING_COLORS[][4] = { - { 156, 122, 98, 217 }, // jupiter-like - { 156, 122, 98, 217 }, // saturn-like + { 156, 122, 98, 217 }, // jupiter-like + { 156, 122, 98, 217 }, // saturn-like { 181, 173, 174, 217 }, // neptune-like - { 130, 122, 98, 217 }, // uranus-like - { 207, 122, 98, 217 } // brown dwarf-like + { 130, 122, 98, 217 }, // uranus-like + { 207, 122, 98, 217 } // brown dwarf-like }; -void StarSystemLegacyGeneratorBase::PickRings(SystemBody* sbody, bool forceRings) +void StarSystemLegacyGeneratorBase::PickRings(SystemBody *sbody, bool forceRings) { PROFILE_SCOPED() sbody->m_rings.minRadius = fixed(); sbody->m_rings.maxRadius = fixed(); - sbody->m_rings.baseColor = Color(255,255,255,255); + sbody->m_rings.baseColor = Color(255, 255, 255, 255); bool bHasRings = forceRings; - if (!bHasRings) - { + if (!bHasRings) { Random ringRng(sbody->GetSeed() + 965467); // today's forecast: - if (sbody->GetType() == SystemBody::TYPE_PLANET_GAS_GIANT) - { + if (sbody->GetType() == SystemBody::TYPE_PLANET_GAS_GIANT) { // 50% chance of rings bHasRings = ringRng.Double() < 0.5; - } - else if (sbody->GetType() == SystemBody::TYPE_PLANET_TERRESTRIAL) - { + } else if (sbody->GetType() == SystemBody::TYPE_PLANET_TERRESTRIAL) { // 10% chance of rings bHasRings = ringRng.Double() < 0.1; } @@ -353,19 +309,17 @@ void StarSystemLegacyGeneratorBase::PickRings(SystemBody* sbody, bool forceRings }*/ } - if (bHasRings) - { + if (bHasRings) { Random ringRng(sbody->GetSeed() + 965467); // today's forecast: 50% chance of rings double rings_die = ringRng.Double(); if (forceRings || (rings_die < 0.5)) { - const unsigned char * const baseCol - = RANDOM_RING_COLORS[ringRng.Int32(COUNTOF(RANDOM_RING_COLORS))]; - sbody->m_rings.baseColor.r = Clamp(baseCol[0] + ringRng.Int32(-20,20), 0, 255); - sbody->m_rings.baseColor.g = Clamp(baseCol[1] + ringRng.Int32(-20,20), 0, 255); - sbody->m_rings.baseColor.b = Clamp(baseCol[2] + ringRng.Int32(-20,10), 0, 255); - sbody->m_rings.baseColor.a = Clamp(baseCol[3] + ringRng.Int32(-5,5), 0, 255); + const unsigned char *const baseCol = RANDOM_RING_COLORS[ringRng.Int32(COUNTOF(RANDOM_RING_COLORS))]; + sbody->m_rings.baseColor.r = Clamp(baseCol[0] + ringRng.Int32(-20, 20), 0, 255); + sbody->m_rings.baseColor.g = Clamp(baseCol[1] + ringRng.Int32(-20, 20), 0, 255); + sbody->m_rings.baseColor.b = Clamp(baseCol[2] + ringRng.Int32(-20, 10), 0, 255); + sbody->m_rings.baseColor.a = Clamp(baseCol[3] + ringRng.Int32(-5, 5), 0, 255); // from wikipedia: http://en.wikipedia.org/wiki/Roche_limit // basic Roche limit calculation assuming a rigid satellite @@ -387,8 +341,8 @@ void StarSystemLegacyGeneratorBase::PickRings(SystemBody* sbody, bool forceRings fixed outerMin = fixed(150, 100); fixed outerMax = fixed(168642, 100000); - sbody->m_rings.minRadius = innerMin + (innerMax - innerMin)*ringRng.Fixed(); - sbody->m_rings.maxRadius = outerMin + (outerMax - outerMin)*ringRng.Fixed(); + sbody->m_rings.minRadius = innerMin + (innerMax - innerMin) * ringRng.Fixed(); + sbody->m_rings.maxRadius = outerMin + (outerMax - outerMin) * ringRng.Fixed(); } } } @@ -396,7 +350,7 @@ void StarSystemLegacyGeneratorBase::PickRings(SystemBody* sbody, bool forceRings /* * http://en.wikipedia.org/wiki/Hill_sphere */ -fixed StarSystemLegacyGeneratorBase::CalcHillRadius(SystemBody* sbody) const +fixed StarSystemLegacyGeneratorBase::CalcHillRadius(SystemBody *sbody) const { PROFILE_SCOPED() if (sbody->GetSuperType() <= SystemBody::SUPERTYPE_STAR) { @@ -409,18 +363,17 @@ fixed StarSystemLegacyGeneratorBase::CalcHillRadius(SystemBody* sbody) const fixedf<48> a = sbody->GetSemiMajorAxisAsFixed(); fixedf<48> e = sbody->GetEccentricityAsFixed(); - return fixed(a * (fixedf<48>(1,1)-e) * - fixedf<48>::CubeRootOf(fixedf<48>( - sbody->GetMassAsFixed() / (fixedf<32>(3,1)*mprimary)))); + return fixed(a * (fixedf<48>(1, 1) - e) * + fixedf<48>::CubeRootOf(fixedf<48>( + sbody->GetMassAsFixed() / (fixedf<32>(3, 1) * mprimary)))); //fixed hr = semiMajorAxis*(fixed(1,1) - eccentricity) * // fixedcuberoot(mass / (3*mprimary)); } } - void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtr system, SystemBody *parent, - const std::vector &children, int *outHumanInfestedness, Random &rand) + const std::vector &children, int *outHumanInfestedness, Random &rand) { PROFILE_SCOPED() // replaces gravpoint mass by sum of masses of its children @@ -428,19 +381,19 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrGetType() == SystemBody::TYPE_GRAVPOINT) { fixed mass(0); - for (std::vector::const_iterator i = children.begin(); i != children.end(); ++i) { + for (std::vector::const_iterator i = children.begin(); i != children.end(); ++i) { const CustomSystemBody *csbody = *i; if (csbody->type >= SystemBody::TYPE_STAR_MIN && csbody->type <= SystemBody::TYPE_STAR_MAX) mass += csbody->mass; else - mass += csbody->mass/SUN_MASS_TO_EARTH_MASS; + mass += csbody->mass / SUN_MASS_TO_EARTH_MASS; } parent->m_mass = mass; } - for (std::vector::const_iterator i = children.begin(); i != children.end(); ++i) { + for (std::vector::const_iterator i = children.begin(); i != children.end(); ++i) { const CustomSystemBody *csbody = *i; SystemBody *kid = system->NewBody(); @@ -455,16 +408,16 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrm_mass = csbody->mass; // obsolete adjustment, probably existed because of denominator precision problems, see LuaFixed.cpp -// if (kid->GetType() == SystemBody::TYPE_PLANET_ASTEROID) kid->m_mass /= 100000; + // if (kid->GetType() == SystemBody::TYPE_PLANET_ASTEROID) kid->m_mass /= 100000; - kid->m_metallicity = csbody->metallicity; + kid->m_metallicity = csbody->metallicity; //multiple of Earth's surface density - kid->m_volatileGas = csbody->volatileGas*fixed(1225,1000); + kid->m_volatileGas = csbody->volatileGas * fixed(1225, 1000); kid->m_volatileLiquid = csbody->volatileLiquid; - kid->m_volatileIces = csbody->volatileIces; - kid->m_volcanicity = csbody->volcanicity; + kid->m_volatileIces = csbody->volatileIces; + kid->m_volcanicity = csbody->volcanicity; kid->m_atmosOxidizing = csbody->atmosOxidizing; - kid->m_life = csbody->life; + kid->m_life = csbody->life; kid->m_space_station_type = csbody->spaceStationType; kid->m_rotationPeriod = csbody->rotationPeriod; kid->m_rotationalPhaseAtStart = csbody->rotationalPhaseAtStart; @@ -472,9 +425,9 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrm_orbitalOffset = csbody->orbitalOffset; kid->m_orbitalPhaseAtStart = csbody->orbitalPhaseAtStart; kid->m_axialTilt = csbody->axialTilt; - kid->m_inclination = fixed(csbody->latitude*10000,10000); - if(kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) - kid->m_orbitalOffset = fixed(csbody->longitude*10000,10000); + kid->m_inclination = fixed(csbody->latitude * 10000, 10000); + if (kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) + kid->m_orbitalOffset = fixed(csbody->longitude * 10000, 10000); kid->m_semiMajorAxis = csbody->semiMajorAxis; if (csbody->heightMapFilename.length() > 0) { @@ -482,7 +435,7 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrm_heightMapFractal = csbody->heightMapFractal; } - if(parent->GetType() == SystemBody::TYPE_GRAVPOINT) // generalize Kepler's law to multiple stars + if (parent->GetType() == SystemBody::TYPE_GRAVPOINT) // generalize Kepler's law to multiple stars kid->m_orbit.SetShapeAroundBarycentre(csbody->semiMajorAxis.ToDouble() * AU, parent->GetMass(), kid->GetMass(), csbody->eccentricity.ToDouble()); else kid->m_orbit.SetShapeAroundPrimary(csbody->semiMajorAxis.ToDouble() * AU, parent->GetMass(), csbody->eccentricity.ToDouble()); @@ -490,22 +443,20 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrm_orbit.SetPhase(csbody->orbitalPhaseAtStart.ToDouble()); if (kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { - kid->m_orbit.SetPlane(matrix3x3d::RotateY(csbody->longitude) * matrix3x3d::RotateX(-0.5*M_PI + csbody->latitude)); - } - else { + kid->m_orbit.SetPlane(matrix3x3d::RotateY(csbody->longitude) * matrix3x3d::RotateX(-0.5 * M_PI + csbody->latitude)); + } else { if (kid->GetSuperType() == SystemBody::SUPERTYPE_STARPORT) { fixed lowestOrbit = fixed().FromDouble(parent->CalcAtmosphereParams().atmosRadius + 500000.0 / EARTH_RADIUS); if (kid->m_orbit.GetSemiMajorAxis() < lowestOrbit.ToDouble()) { Error("%s's orbit is too close to its parent (%.2f/%.2f)", csbody->name.c_str(), kid->m_orbit.GetSemiMajorAxis(), lowestOrbit.ToFloat()); } - } - else { + } else { if (kid->m_orbit.GetSemiMajorAxis() < 1.2 * parent->GetRadius()) { Error("%s's orbit is too close to its parent", csbody->name.c_str()); } } double offset = csbody->want_rand_offset ? rand.Double(2 * M_PI) : (csbody->orbitalOffset.ToDouble()); - kid->m_orbit.SetPlane(matrix3x3d::RotateY(offset) * matrix3x3d::RotateX(-0.5*M_PI + csbody->latitude)); + kid->m_orbit.SetPlane(matrix3x3d::RotateY(offset) * matrix3x3d::RotateX(-0.5 * M_PI + csbody->latitude)); } if (kid->GetSuperType() == SystemBody::SUPERTYPE_STARPORT) { (*outHumanInfestedness)++; @@ -514,35 +465,35 @@ void StarSystemCustomGenerator::CustomGetKidsOf(RefCountedPtrm_children.push_back(kid); // perihelion and aphelion (in AUs) - kid->m_orbMin = csbody->semiMajorAxis - csbody->eccentricity*csbody->semiMajorAxis; - kid->m_orbMax = 2*csbody->semiMajorAxis - kid->m_orbMin; + kid->m_orbMin = csbody->semiMajorAxis - csbody->eccentricity * csbody->semiMajorAxis; + kid->m_orbMax = 2 * csbody->semiMajorAxis - kid->m_orbMin; PickAtmosphere(kid); // pick or specify rings switch (csbody->ringStatus) { - case CustomSystemBody::WANT_NO_RINGS: - kid->m_rings.minRadius = fixed(); - kid->m_rings.maxRadius = fixed(); - break; - case CustomSystemBody::WANT_RINGS: - PickRings(kid, true); - break; - case CustomSystemBody::WANT_RANDOM_RINGS: - PickRings(kid, false); - break; - case CustomSystemBody::WANT_CUSTOM_RINGS: - kid->m_rings.minRadius = csbody->ringInnerRadius; - kid->m_rings.maxRadius = csbody->ringOuterRadius; - kid->m_rings.baseColor = csbody->ringColor; - break; + case CustomSystemBody::WANT_NO_RINGS: + kid->m_rings.minRadius = fixed(); + kid->m_rings.maxRadius = fixed(); + break; + case CustomSystemBody::WANT_RINGS: + PickRings(kid, true); + break; + case CustomSystemBody::WANT_RANDOM_RINGS: + PickRings(kid, false); + break; + case CustomSystemBody::WANT_CUSTOM_RINGS: + kid->m_rings.minRadius = csbody->ringInnerRadius; + kid->m_rings.maxRadius = csbody->ringOuterRadius; + kid->m_rings.baseColor = csbody->ringColor; + break; } CustomGetKidsOf(system, kid, csbody->children, outHumanInfestedness, rand); } } -bool StarSystemCustomGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config) +bool StarSystemCustomGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config) { PROFILE_SCOPED() RefCountedPtr sec = galaxy->GetSector(system->GetPath()); @@ -556,7 +507,7 @@ bool StarSystemCustomGenerator::Apply(Random& rng, RefCountedPtr galaxy, system->SetCustom(true, true); config->isCustomOnly = true; const CustomSystemBody *csbody = customSys->sBody; - SystemBody* rootBody = system->NewBody(); + SystemBody *rootBody = system->NewBody(); rootBody->m_type = csbody->type; rootBody->m_parent = 0; rootBody->m_seed = csbody->want_rand_seed ? rng.Int32() : csbody->seed; @@ -589,7 +540,6 @@ bool StarSystemCustomGenerator::Apply(Random& rng, RefCountedPtr galaxy, return true; } - /* * These are the nice floating point surface temp calculating turds. * @@ -623,18 +573,17 @@ static double CalcSurfaceTemp(double star_radius, double star_temp, double objec static fixed calcEnergyPerUnitAreaAtDist(fixed star_radius, int star_temp, fixed object_dist) { PROFILE_SCOPED() - fixed temp = star_temp * fixed(1,5778); //normalize to Sun's temperature + fixed temp = star_temp * fixed(1, 5778); //normalize to Sun's temperature const fixed total_solar_emission = - temp*temp*temp*temp*star_radius*star_radius; + temp * temp * temp * temp * star_radius * star_radius; - return total_solar_emission / (object_dist*object_dist); //return value in solar consts (overflow prevention) + return total_solar_emission / (object_dist * object_dist); //return value in solar consts (overflow prevention) } //helper function, get branch of system tree from body all the way to the system's root and write it to path -static void getPathToRoot(const SystemBody* body, std::vector& path) +static void getPathToRoot(const SystemBody *body, std::vector &path) { - while(body) - { + while (body) { path.push_back(body); body = body->GetParent(); } @@ -648,66 +597,60 @@ int StarSystemRandomGenerator::CalcSurfaceTemp(const SystemBody *primary, fixed fixed energy_per_meter2 = calcEnergyPerUnitAreaAtDist(primary->m_radius, primary->m_averageTemp, distToPrimary); fixed dist; // find the other stars which aren't our parent star - for( auto s : primary->GetStarSystem()->GetStars()) - { - if(s != primary) - { + for (auto s : primary->GetStarSystem()->GetStars()) { + if (s != primary) { //get branches from body and star to system root - std::vector first_to_root; - std::vector second_to_root; + std::vector first_to_root; + std::vector second_to_root; getPathToRoot(primary, first_to_root); getPathToRoot(&(*s), second_to_root); - std::vector::reverse_iterator fit = first_to_root.rbegin(); - std::vector::reverse_iterator sit = second_to_root.rbegin(); - while(sit!=second_to_root.rend() && fit!=first_to_root.rend() && (*sit)==(*fit)) //keep tracing both branches from system's root - { //until they diverge + std::vector::reverse_iterator fit = first_to_root.rbegin(); + std::vector::reverse_iterator sit = second_to_root.rbegin(); + while (sit != second_to_root.rend() && fit != first_to_root.rend() && (*sit) == (*fit)) //keep tracing both branches from system's root + { //until they diverge ++sit; ++fit; } if (sit == second_to_root.rend()) --sit; - if (fit == first_to_root.rend()) --fit; //oops! one of the branches ends at lca, backtrack + if (fit == first_to_root.rend()) --fit; //oops! one of the branches ends at lca, backtrack - if((*fit)->IsCoOrbitalWith(*sit)) //planet is around one part of coorbiting pair, star is another. + if ((*fit)->IsCoOrbitalWith(*sit)) //planet is around one part of coorbiting pair, star is another. { - dist = ((*fit)->GetOrbMaxAsFixed()+(*fit)->GetOrbMinAsFixed()) >> 1; //binaries don't have fully initialized smaxes - } - else if((*sit)->IsCoOrbital()) //star is part of binary around which planet is (possibly indirectly) orbiting + dist = ((*fit)->GetOrbMaxAsFixed() + (*fit)->GetOrbMinAsFixed()) >> 1; //binaries don't have fully initialized smaxes + } else if ((*sit)->IsCoOrbital()) //star is part of binary around which planet is (possibly indirectly) orbiting { bool inverted_ancestry = false; - for(const SystemBody* body = (*sit); body; body = body->GetParent()) if(body == (*fit)) - { - inverted_ancestry = true; //ugly hack due to function being static taking planet's primary rather than being called from actual planet - break; - } - if(inverted_ancestry) //primary is star's ancestor! Don't try to take its orbit (could probably be a gravpoint check at this point, but paranoia) + for (const SystemBody *body = (*sit); body; body = body->GetParent()) + if (body == (*fit)) { + inverted_ancestry = true; //ugly hack due to function being static taking planet's primary rather than being called from actual planet + break; + } + if (inverted_ancestry) //primary is star's ancestor! Don't try to take its orbit (could probably be a gravpoint check at this point, but paranoia) { dist = distToPrimary; + } else { + dist = ((*fit)->GetOrbMaxAsFixed() + (*fit)->GetOrbMinAsFixed()) >> 1; //simplified to planet orbiting stationary star } - else - { - dist = ((*fit)->GetOrbMaxAsFixed()+(*fit)->GetOrbMinAsFixed()) >> 1; //simplified to planet orbiting stationary star - } - } - else if((*fit)->IsCoOrbital()) //planet is around one part of coorbiting pair, star isn't coorbiting with it + } else if ((*fit)->IsCoOrbital()) //planet is around one part of coorbiting pair, star isn't coorbiting with it { - dist = ((*sit)->GetOrbMaxAsFixed()+(*sit)->GetOrbMinAsFixed()) >> 1; //simplified to star orbiting stationary planet - } - else //neither is part of any binaries - hooray! + dist = ((*sit)->GetOrbMaxAsFixed() + (*sit)->GetOrbMinAsFixed()) >> 1; //simplified to star orbiting stationary planet + } else //neither is part of any binaries - hooray! { dist = (((*sit)->GetSemiMajorAxisAsFixed() - (*fit)->GetSemiMajorAxisAsFixed()).Abs() //avg of conjunction and opposition dist - + ((*sit)->GetSemiMajorAxisAsFixed() + (*fit)->GetSemiMajorAxisAsFixed())) >> 1; + + ((*sit)->GetSemiMajorAxisAsFixed() + (*fit)->GetSemiMajorAxisAsFixed())) >> + 1; } } energy_per_meter2 += calcEnergyPerUnitAreaAtDist(s->m_radius, s->m_averageTemp, dist); } - const fixed surface_temp_pow4 = energy_per_meter2 * (1-albedo)/(1-greenhouse); - return (279*int(isqrt(isqrt((surface_temp_pow4.v)))))>>(fixed::FRAC/4); //multiplied by 279 to convert from Earth's temps to Kelvin + const fixed surface_temp_pow4 = energy_per_meter2 * (1 - albedo) / (1 - greenhouse); + return (279 * int(isqrt(isqrt((surface_temp_pow4.v))))) >> (fixed::FRAC / 4); //multiplied by 279 to convert from Earth's temps to Kelvin } /* * For moons distance from star is not orbMin, orbMax. */ -const SystemBody* StarSystemRandomGenerator::FindStarAndTrueOrbitalRange(const SystemBody *planet, fixed &orbMin_, fixed &orbMax_) const +const SystemBody *StarSystemRandomGenerator::FindStarAndTrueOrbitalRange(const SystemBody *planet, fixed &orbMin_, fixed &orbMax_) const { PROFILE_SCOPED() const SystemBody *star = planet->GetParent(); @@ -732,8 +675,8 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) fixed greenhouse; fixed minDistToStar, maxDistToStar, averageDistToStar; - const SystemBody* star = FindStarAndTrueOrbitalRange(sbody, minDistToStar, maxDistToStar); - averageDistToStar = (minDistToStar+maxDistToStar)>>1; + const SystemBody *star = FindStarAndTrueOrbitalRange(sbody, minDistToStar, maxDistToStar); + averageDistToStar = (minDistToStar + maxDistToStar) >> 1; /* first calculate blackbody temp (no greenhouse effect, zero albedo) */ int bbody_temp = CalcSurfaceTemp(star, averageDistToStar, albedo, greenhouse); @@ -747,20 +690,20 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) // AndyC - Updated to use the empirically gathered data from this site: // http://phl.upr.edu/library/notes/standardmass-radiusrelationforexoplanets // but we still limit at the lowest end - if (sbody->GetMassAsFixed() <= fixed(1,1)) { + if (sbody->GetMassAsFixed() <= fixed(1, 1)) { sbody->m_radius = fixed(fixedf<48>::CubeRootOf(fixedf<48>(sbody->GetMassAsFixed()))); - } else if( sbody->GetMassAsFixed() < ONEEUMASS ) { + } else if (sbody->GetMassAsFixed() < ONEEUMASS) { // smaller than 1 Earth mass is almost certainly a rocky body - sbody->m_radius = fixed::FromDouble(pow( sbody->GetMassAsFixed().ToDouble(), 0.3 )); - } else if( sbody->GetMassAsFixed() < TWOHUNDREDEUMASSES ) { + sbody->m_radius = fixed::FromDouble(pow(sbody->GetMassAsFixed().ToDouble(), 0.3)); + } else if (sbody->GetMassAsFixed() < TWOHUNDREDEUMASSES) { // from 1 EU to 200 they transition from Earth-like rocky bodies, through Ocean worlds and on to Gas Giants - sbody->m_radius = fixed::FromDouble(pow( sbody->GetMassAsFixed().ToDouble(), 0.5 )); + sbody->m_radius = fixed::FromDouble(pow(sbody->GetMassAsFixed().ToDouble(), 0.5)); } else { // Anything bigger than 200 EU masses is a Gas Giant or bigger but the density changes to decrease from here on up... - sbody->m_radius = fixed::FromDouble( 22.6 * (1.0/pow(sbody->GetMassAsFixed().ToDouble(), double(0.0886))) ); + sbody->m_radius = fixed::FromDouble(22.6 * (1.0 / pow(sbody->GetMassAsFixed().ToDouble(), double(0.0886)))); } // enforce minimum size of 10km - sbody->m_radius = std::max(sbody->GetRadiusAsFixed(), fixed(1,630)); + sbody->m_radius = std::max(sbody->GetRadiusAsFixed(), fixed(1, 630)); if (sbody->GetParent()->GetType() <= SystemBody::TYPE_STAR_MAX) { // get it from the table now rather than setting it on stars/gravpoints as @@ -772,7 +715,7 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) } // harder to be volcanic when you are tiny (you cool down) - sbody->m_volcanicity = std::min(fixed(1,1), sbody->GetMassAsFixed()) * rand.Fixed(); + sbody->m_volcanicity = std::min(fixed(1, 1), sbody->GetMassAsFixed()) * rand.Fixed(); sbody->m_atmosOxidizing = rand.Fixed(); sbody->m_life = fixed(); sbody->m_volatileGas = fixed(); @@ -780,14 +723,14 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) sbody->m_volatileIces = fixed(); // pick body type - if (sbody->GetMassAsFixed() > 317*13) { + if (sbody->GetMassAsFixed() > 317 * 13) { // more than 13 jupiter masses can fuse deuterium - is a brown dwarf sbody->m_type = SystemBody::TYPE_BROWN_DWARF; sbody->m_averageTemp = sbody->GetAverageTemp() + rand.Int32(starTypeInfo[sbody->GetType()].tempMin, starTypeInfo[sbody->GetType()].tempMax); // prevent mass exceeding 65 jupiter masses or so, when it becomes a star // XXX since TYPE_BROWN_DWARF is supertype star, mass is now in // solar masses. what a fucking mess - sbody->m_mass = std::min(sbody->GetMassAsFixed(), fixed(317*65, 1)) / SUN_MASS_TO_EARTH_MASS; + sbody->m_mass = std::min(sbody->GetMassAsFixed(), fixed(317 * 65, 1)) / SUN_MASS_TO_EARTH_MASS; //Radius is too high as it now uses the planetary calculations to work out radius (Cube root of mass) // So tell it to use the star data instead: sbody->m_radius = fixed(rand.Int32(starTypeInfo[sbody->GetType()].radius[0], starTypeInfo[sbody->GetType()].radius[1]), 100); @@ -796,7 +739,7 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) } else if (sbody->GetMassAsFixed() > fixed(1, 15000)) { sbody->m_type = SystemBody::TYPE_PLANET_TERRESTRIAL; - fixed amount_volatiles = fixed(2,1)*rand.Fixed(); + fixed amount_volatiles = fixed(2, 1) * rand.Fixed(); if (rand.Int32(3)) amount_volatiles *= sbody->GetMassAsFixed(); // total atmosphere loss if (rand.Fixed() > sbody->GetMassAsFixed()) amount_volatiles = fixed(); @@ -806,51 +749,54 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) greenhouse = fixed(); albedo = fixed(); // CO2 sublimation - if (sbody->GetAverageTemp() > 195) greenhouse += amount_volatiles * fixed(1,3); - else albedo += fixed(2,6); + if (sbody->GetAverageTemp() > 195) + greenhouse += amount_volatiles * fixed(1, 3); + else + albedo += fixed(2, 6); // H2O liquid - if (sbody->GetAverageTemp() > 273) greenhouse += amount_volatiles * fixed(1,5); - else albedo += fixed(3,6); + if (sbody->GetAverageTemp() > 273) + greenhouse += amount_volatiles * fixed(1, 5); + else + albedo += fixed(3, 6); // H2O boils - if (sbody->GetAverageTemp() > 373) greenhouse += amount_volatiles * fixed(1,3); + if (sbody->GetAverageTemp() > 373) greenhouse += amount_volatiles * fixed(1, 3); - if(greenhouse > fixed(7,10)) { // never reach 1, but 1/(1-greenhouse) still grows + if (greenhouse > fixed(7, 10)) { // never reach 1, but 1/(1-greenhouse) still grows greenhouse *= greenhouse; greenhouse *= greenhouse; - greenhouse = greenhouse / (greenhouse + fixed(32,311)); + greenhouse = greenhouse / (greenhouse + fixed(32, 311)); } sbody->m_averageTemp = CalcSurfaceTemp(star, averageDistToStar, albedo, greenhouse); - const fixed proportion_gas = sbody->GetAverageTemp() / (fixed(100,1) + sbody->GetAverageTemp()); + const fixed proportion_gas = sbody->GetAverageTemp() / (fixed(100, 1) + sbody->GetAverageTemp()); sbody->m_volatileGas = proportion_gas * amount_volatiles; - const fixed proportion_liquid = (fixed(1,1)-proportion_gas) * (sbody->GetAverageTemp() / (fixed(50,1) + sbody->GetAverageTemp())); + const fixed proportion_liquid = (fixed(1, 1) - proportion_gas) * (sbody->GetAverageTemp() / (fixed(50, 1) + sbody->GetAverageTemp())); sbody->m_volatileLiquid = proportion_liquid * amount_volatiles; - const fixed proportion_ices = fixed(1,1) - (proportion_gas + proportion_liquid); + const fixed proportion_ices = fixed(1, 1) - (proportion_gas + proportion_liquid); sbody->m_volatileIces = proportion_ices * amount_volatiles; //Output("temp %dK, gas:liquid:ices %f:%f:%f\n", averageTemp, proportion_gas.ToFloat(), // proportion_liquid.ToFloat(), proportion_ices.ToFloat()); if ((sbody->GetVolatileLiquidAsFixed() > fixed()) && - (sbody->GetAverageTemp() > CELSIUS-60) && - (sbody->GetAverageTemp() < CELSIUS+200)) - { + (sbody->GetAverageTemp() > CELSIUS - 60) && + (sbody->GetAverageTemp() < CELSIUS + 200)) { // try for life int minTemp = CalcSurfaceTemp(star, maxDistToStar, albedo, greenhouse); int maxTemp = CalcSurfaceTemp(star, minDistToStar, albedo, greenhouse); - if ((minTemp > CELSIUS-10) && (minTemp < CELSIUS+90) && //removed explicit checks for star type (also BD and WD seem to have slight chance of having life around them) - (maxTemp > CELSIUS-10) && (maxTemp < CELSIUS+90)) //TODO: ceiling based on actual boiling point on the planet, not in 1atm + if ((minTemp > CELSIUS - 10) && (minTemp < CELSIUS + 90) && //removed explicit checks for star type (also BD and WD seem to have slight chance of having life around them) + (maxTemp > CELSIUS - 10) && (maxTemp < CELSIUS + 90)) //TODO: ceiling based on actual boiling point on the planet, not in 1atm { - fixed maxMass, lifeMult, allowedMass(1,2); - allowedMass += 2; - for( auto s : sbody->GetStarSystem()->GetStars() ) { //find the most massive star, mass is tied to lifespan - maxMass = maxMass < s->GetMassAsFixed() ? s->GetMassAsFixed() : maxMass; //this automagically eliminates O, B and so on from consideration - } //handy calculator: http://www.asc-csa.gc.ca/eng/educators/resources/astronomy/module2/calculator.asp - if(maxMass < allowedMass) { //system could have existed long enough for life to form (based on Sol) + fixed maxMass, lifeMult, allowedMass(1, 2); + allowedMass += 2; + for (auto s : sbody->GetStarSystem()->GetStars()) { //find the most massive star, mass is tied to lifespan + maxMass = maxMass < s->GetMassAsFixed() ? s->GetMassAsFixed() : maxMass; //this automagically eliminates O, B and so on from consideration + } //handy calculator: http://www.asc-csa.gc.ca/eng/educators/resources/astronomy/module2/calculator.asp + if (maxMass < allowedMass) { //system could have existed long enough for life to form (based on Sol) lifeMult = allowedMass - maxMass; } sbody->m_life = lifeMult * rand.Fixed(); @@ -866,38 +812,38 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) // Formula: time ~ semiMajorAxis^6 * radius / mass / parentMass^2 // // compared to Earth's Moon - static fixed MOON_TIDAL_LOCK = fixed(6286,1); - fixed invTidalLockTime = fixed(1,1); + static fixed MOON_TIDAL_LOCK = fixed(6286, 1); + fixed invTidalLockTime = fixed(1, 1); // fine-tuned not to give overflows, order of evaluation matters! if (sbody->GetParent()->GetType() <= SystemBody::TYPE_STAR_MAX) { invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()); invTidalLockTime *= sbody->GetMassAsFixed(); invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()); - invTidalLockTime *= sbody->GetParent()->GetMassAsFixed()*sbody->GetParent()->GetMassAsFixed(); + invTidalLockTime *= sbody->GetParent()->GetMassAsFixed() * sbody->GetParent()->GetMassAsFixed(); invTidalLockTime /= sbody->GetRadiusAsFixed(); - invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed())*MOON_TIDAL_LOCK; + invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()) * MOON_TIDAL_LOCK; } else { - invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed())*SUN_MASS_TO_EARTH_MASS; + invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()) * SUN_MASS_TO_EARTH_MASS; invTidalLockTime *= sbody->GetMassAsFixed(); - invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed())*SUN_MASS_TO_EARTH_MASS; - invTidalLockTime *= sbody->GetParent()->GetMassAsFixed()*sbody->GetParent()->GetMassAsFixed(); + invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()) * SUN_MASS_TO_EARTH_MASS; + invTidalLockTime *= sbody->GetParent()->GetMassAsFixed() * sbody->GetParent()->GetMassAsFixed(); invTidalLockTime /= sbody->GetRadiusAsFixed(); - invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed())*MOON_TIDAL_LOCK; + invTidalLockTime /= (sbody->GetSemiMajorAxisAsFixed() * sbody->GetSemiMajorAxisAsFixed()) * MOON_TIDAL_LOCK; } //Output("tidal lock of %s: %.5f, a %.5f R %.4f mp %.3f ms %.3f\n", name.c_str(), // invTidalLockTime.ToFloat(), semiMajorAxis.ToFloat(), radius.ToFloat(), parent->mass.ToFloat(), mass.ToFloat()); - if(invTidalLockTime > 10) { // 10x faster than Moon, no chance not to be tidal-locked - sbody->m_rotationPeriod = fixed(int(round(sbody->GetOrbit().Period())),3600*24); + if (invTidalLockTime > 10) { // 10x faster than Moon, no chance not to be tidal-locked + sbody->m_rotationPeriod = fixed(int(round(sbody->GetOrbit().Period())), 3600 * 24); sbody->m_axialTilt = sbody->GetInclinationAsFixed(); - } else if(invTidalLockTime > fixed(1,100)) { // rotation speed changed in favour of tidal lock + } else if (invTidalLockTime > fixed(1, 100)) { // rotation speed changed in favour of tidal lock // XXX: there should be some chance the satellite was captured only recenly and ignore this // I'm ommiting that now, I do not want to change the Universe by additional rand call. - fixed lambda = invTidalLockTime/(fixed(1,20)+invTidalLockTime); - sbody->m_rotationPeriod = (1-lambda)*sbody->GetRotationPeriodAsFixed()+ lambda*sbody->GetOrbit().Period()/3600/24; - sbody->m_axialTilt = (1-lambda)*sbody->GetAxialTiltAsFixed() + lambda*sbody->GetInclinationAsFixed(); + fixed lambda = invTidalLockTime / (fixed(1, 20) + invTidalLockTime); + sbody->m_rotationPeriod = (1 - lambda) * sbody->GetRotationPeriodAsFixed() + lambda * sbody->GetOrbit().Period() / 3600 / 24; + sbody->m_axialTilt = (1 - lambda) * sbody->GetAxialTiltAsFixed() + lambda * sbody->GetInclinationAsFixed(); } // else .. nothing happens to the satellite PickAtmosphere(sbody); @@ -921,13 +867,13 @@ static fixed mass_from_disk_area(fixed a, fixed b, fixed max) // constant factors (pi) in this equation drop out. // b = (b > max ? max : b); - assert(b>=a); - assert(a<=max); - assert(b<=max); - assert(a>=0); - fixed one_over_3max = fixed(2,1)/(3*max); - return (b*b - one_over_3max*b*b*b) - - (a*a - one_over_3max*a*a*a); + assert(b >= a); + assert(a <= max); + assert(b <= max); + assert(a >= 0); + fixed one_over_3max = fixed(2, 1) / (3 * max); + return (b * b - one_over_3max * b * b * b) - + (a * a - one_over_3max * a * a * a); } static fixed get_disc_density(SystemBody *primary, fixed discMin, fixed discMax, fixed percentOfPrimaryMass) @@ -938,18 +884,19 @@ static fixed get_disc_density(SystemBody *primary, fixed discMin, fixed discMax, return primary->GetMassInEarths() * percentOfPrimaryMass / total; } -static inline bool test_overlap(const fixed& x1, const fixed& x2, const fixed& y1, const fixed& y2) { - return (x1 >= y1 && x1 <= y2) || - (x2 >= y1 && x2 <= y2) || - (y1 >= x1 && y1 <= x2) || - (y2 >= x1 && y2 <= x2); +static inline bool test_overlap(const fixed &x1, const fixed &x2, const fixed &y1, const fixed &y2) +{ + return (x1 >= y1 && x1 <= y2) || + (x2 >= y1 && x2 <= y2) || + (y1 >= x1 && y1 <= x2) || + (y2 >= x1 && y2 <= x2); } void StarSystemRandomGenerator::MakePlanetsAround(RefCountedPtr system, SystemBody *primary, Random &rand) { PROFILE_SCOPED() fixed discMin = fixed(); - fixed discMax = fixed(5000,1); + fixed discMax = fixed(5000, 1); fixed discDensity; SystemBody::BodySuperType parentSuperType = primary->GetSuperType(); @@ -968,34 +915,33 @@ void StarSystemRandomGenerator::MakePlanetsAround(RefCountedPtrGetRadiusAsFixed() * AU_SOL_RADIUS; - discMax = 100 * rand.NFixed(2); // rand-splitting again - discMax *= fixed::SqrtOf(fixed(1,2) + fixed(8,1)*rand.Fixed()); + discMax = 100 * rand.NFixed(2); // rand-splitting again + discMax *= fixed::SqrtOf(fixed(1, 2) + fixed(8, 1) * rand.Fixed()); } else { - discMax = 100 * rand.NFixed(2)*fixed::SqrtOf(primary->GetMassAsFixed()); + discMax = 100 * rand.NFixed(2) * fixed::SqrtOf(primary->GetMassAsFixed()); } // having limited discMin by bin-separation/fake roche, and // discMax by some relation to star mass, we can now compute // disc density - discDensity = rand.Fixed() * get_disc_density(primary, discMin, discMax, fixed(2,100)); + discDensity = rand.Fixed() * get_disc_density(primary, discMin, discMax, fixed(2, 100)); if ((parentSuperType == SystemBody::SUPERTYPE_STAR) && (primary->m_parent)) { // limit planets out to 10% distance to star's binary companion - discMax = std::min(discMax, primary->m_orbMin * fixed(1,10)); + discMax = std::min(discMax, primary->m_orbMin * fixed(1, 10)); } /* in trinary and quaternary systems don't bump into other pair... */ if (system->GetNumStars() >= 3) { - discMax = std::min(discMax, fixed(5,100)*system->GetRootBody()->GetChildren()[0]->m_orbMin); + discMax = std::min(discMax, fixed(5, 100) * system->GetRootBody()->GetChildren()[0]->m_orbMin); } } else { fixed primary_rad = primary->GetRadiusAsFixed() * AU_EARTH_RADIUS; discMin = 4 * primary_rad; /* use hill radius to find max size of moon system. for stars botch it. And use planets orbit around its primary as a scaler to a moon's orbit*/ - discMax = std::min(discMax, fixed(1,20)* - CalcHillRadius(primary)*primary->m_orbMin*fixed(1,10)); + discMax = std::min(discMax, fixed(1, 20) * CalcHillRadius(primary) * primary->m_orbMin * fixed(1, 10)); - discDensity = rand.Fixed() * get_disc_density(primary, discMin, discMax, fixed(1,500)); + discDensity = rand.Fixed() * get_disc_density(primary, discMin, discMax, fixed(1, 500)); } //fixed discDensity = 20*rand.NFixed(4); @@ -1003,26 +949,27 @@ void StarSystemRandomGenerator::MakePlanetsAround(RefCountedPtr %f AU\n", primary->GetName().c_str(), discMin.ToDouble(), discMax.ToDouble()); fixed initialJump = rand.NFixed(5); - fixed pos = (fixed(1,1) - initialJump)*discMin + (initialJump*discMax); + fixed pos = (fixed(1, 1) - initialJump) * discMin + (initialJump * discMax); const RingStyle &ring = primary->GetRings(); const bool hasRings = primary->HasRings(); while (pos < discMax) { // periapsis, apoapsis = closest, farthest distance in orbit - fixed periapsis = pos + pos*fixed(1,2)*rand.NFixed(2);/* + jump */; + fixed periapsis = pos + pos * fixed(1, 2) * rand.NFixed(2); /* + jump */ + ; fixed ecc = rand.NFixed(3); - fixed semiMajorAxis = periapsis / (fixed(1,1) - ecc); - fixed apoapsis = 2*semiMajorAxis - periapsis; + fixed semiMajorAxis = periapsis / (fixed(1, 1) - ecc); + fixed apoapsis = 2 * semiMajorAxis - periapsis; if (apoapsis > discMax) break; fixed mass; { const fixed a = pos; - const fixed b = fixed(135,100)*apoapsis; + const fixed b = fixed(135, 100) * apoapsis; mass = mass_from_disk_area(a, b, discMax); mass *= rand.Fixed() * discDensity; } - if (mass < 0) {// hack around overflow + if (mass < 0) { // hack around overflow Output("WARNING: planetary mass has overflowed! (child of %s)\n", primary->GetName().c_str()); mass = fixed(Sint64(0x7fFFffFFffFFffFFull)); } @@ -1030,36 +977,35 @@ void StarSystemRandomGenerator::MakePlanetsAround(RefCountedPtrNewBody(); planet->m_eccentricity = ecc; - planet->m_axialTilt = fixed(100,157)*rand.NFixed(2); + planet->m_axialTilt = fixed(100, 157) * rand.NFixed(2); planet->m_semiMajorAxis = semiMajorAxis; planet->m_type = SystemBody::TYPE_PLANET_TERRESTRIAL; planet->m_seed = rand.Int32(); planet->m_parent = primary; planet->m_mass = mass; - planet->m_rotationPeriod = fixed(rand.Int32(1,200), 24); + planet->m_rotationPeriod = fixed(rand.Int32(1, 200), 24); const double e = ecc.ToDouble(); - if(primary->m_type == SystemBody::TYPE_GRAVPOINT) + if (primary->m_type == SystemBody::TYPE_GRAVPOINT) planet->m_orbit.SetShapeAroundBarycentre(semiMajorAxis.ToDouble() * AU, primary->GetMass(), planet->GetMass(), e); else planet->m_orbit.SetShapeAroundPrimary(semiMajorAxis.ToDouble() * AU, primary->GetMass(), e); - double r1 = rand.Double(2*M_PI); // function parameter evaluation order is implementation-dependent - double r2 = rand.NDouble(5); // can't put two rands in the same expression - planet->m_orbit.SetPlane(matrix3x3d::RotateY(r1) * matrix3x3d::RotateX(-0.5*M_PI + r2*M_PI/2.0)); + double r1 = rand.Double(2 * M_PI); // function parameter evaluation order is implementation-dependent + double r2 = rand.NDouble(5); // can't put two rands in the same expression + planet->m_orbit.SetPlane(matrix3x3d::RotateY(r1) * matrix3x3d::RotateX(-0.5 * M_PI + r2 * M_PI / 2.0)); planet->m_orbit.SetPhase(rand.Double(2 * M_PI)); planet->m_inclination = FIXED_PI; - planet->m_inclination *= r2/2.0; + planet->m_inclination *= r2 / 2.0; planet->m_orbMin = periapsis; planet->m_orbMax = apoapsis; primary->m_children.push_back(planet); if (hasRings && parentSuperType == SystemBody::SUPERTYPE_ROCKY_PLANET && - test_overlap(ring.minRadius, ring.maxRadius, periapsis, apoapsis)) - { + test_overlap(ring.minRadius, ring.maxRadius, periapsis, apoapsis)) { //Output("Overlap, eliminating rings from parent SystemBody\n"); //Overlap, eliminating rings from parent SystemBody primary->m_rings.minRadius = fixed(); @@ -1068,25 +1014,25 @@ void StarSystemRandomGenerator::MakePlanetsAround(RefCountedPtr::iterator i = primary->m_children.begin(); i != primary->m_children.end(); ++i) { + for (std::vector::iterator i = primary->m_children.begin(); i != primary->m_children.end(); ++i) { // planets around a binary pair [gravpoint] -- ignore the stars... if ((*i)->GetSuperType() == SystemBody::SUPERTYPE_STAR) continue; // Turn them into something!!!!!!! char buf[12]; if (parentSuperType <= SystemBody::SUPERTYPE_STAR) { // planet naming scheme - snprintf(buf, sizeof(buf), " %c", 'a'+idx); + snprintf(buf, sizeof(buf), " %c", 'a' + idx); } else { // moon naming scheme - snprintf(buf, sizeof(buf), " %d", 1+idx); + snprintf(buf, sizeof(buf), " %d", 1 + idx); } - (*i)->m_name = primary->GetName()+buf; + (*i)->m_name = primary->GetName() + buf; PickPlanetType(*i, rand); if (make_moons) MakePlanetsAround(system, *i, rand); idx++; @@ -1103,40 +1049,40 @@ void StarSystemRandomGenerator::MakeStarOfType(SystemBody *sbody, SystemBody::Bo // Assign aspect ratios caused by equatorial bulges due to rotation. See terrain code for details. // XXX to do: determine aspect ratio distributions for dimmer stars. Make aspect ratios consistent with rotation speeds/stability restrictions. switch (type) { - // Assign aspect ratios (roughly) between 1.0 to 1.8 with a bias towards 1 for bright stars F, A, B ,O + // Assign aspect ratios (roughly) between 1.0 to 1.8 with a bias towards 1 for bright stars F, A, B ,O - // "A large fraction of hot stars are rapid rotators with surface rotational velocities - // of more than 100 km/s (6, 7). ." Imaging the Surface of Altair, John D. Monnier, et. al. 2007 - // A reasonable amount of lot of stars will be assigned high aspect ratios. + // "A large fraction of hot stars are rapid rotators with surface rotational velocities + // of more than 100 km/s (6, 7). ." Imaging the Surface of Altair, John D. Monnier, et. al. 2007 + // A reasonable amount of lot of stars will be assigned high aspect ratios. - // Bright stars whose equatorial to polar radius ratio (the aspect ratio) is known - // seem to tend to have values between 1.0 and around 1.5 (brief survey). - // The limiting factor preventing much higher values seems to be stability as they - // are rotating 80-95% of their breakup velocity. - case SystemBody::TYPE_STAR_F: - case SystemBody::TYPE_STAR_F_GIANT: - case SystemBody::TYPE_STAR_F_HYPER_GIANT: - case SystemBody::TYPE_STAR_F_SUPER_GIANT: - case SystemBody::TYPE_STAR_A: - case SystemBody::TYPE_STAR_A_GIANT: - case SystemBody::TYPE_STAR_A_HYPER_GIANT: - case SystemBody::TYPE_STAR_A_SUPER_GIANT: - case SystemBody::TYPE_STAR_B: - case SystemBody::TYPE_STAR_B_GIANT: - case SystemBody::TYPE_STAR_B_SUPER_GIANT: - case SystemBody::TYPE_STAR_B_WF: - case SystemBody::TYPE_STAR_O: - case SystemBody::TYPE_STAR_O_GIANT: - case SystemBody::TYPE_STAR_O_HYPER_GIANT: - case SystemBody::TYPE_STAR_O_SUPER_GIANT: - case SystemBody::TYPE_STAR_O_WF: { - fixed rnd = rand.Fixed(); - sbody->m_aspectRatio = fixed(1, 1)+fixed(8, 10)*rnd*rnd; - break; - } - // aspect ratio is initialised to 1.0 for other stars currently - default: - break; + // Bright stars whose equatorial to polar radius ratio (the aspect ratio) is known + // seem to tend to have values between 1.0 and around 1.5 (brief survey). + // The limiting factor preventing much higher values seems to be stability as they + // are rotating 80-95% of their breakup velocity. + case SystemBody::TYPE_STAR_F: + case SystemBody::TYPE_STAR_F_GIANT: + case SystemBody::TYPE_STAR_F_HYPER_GIANT: + case SystemBody::TYPE_STAR_F_SUPER_GIANT: + case SystemBody::TYPE_STAR_A: + case SystemBody::TYPE_STAR_A_GIANT: + case SystemBody::TYPE_STAR_A_HYPER_GIANT: + case SystemBody::TYPE_STAR_A_SUPER_GIANT: + case SystemBody::TYPE_STAR_B: + case SystemBody::TYPE_STAR_B_GIANT: + case SystemBody::TYPE_STAR_B_SUPER_GIANT: + case SystemBody::TYPE_STAR_B_WF: + case SystemBody::TYPE_STAR_O: + case SystemBody::TYPE_STAR_O_GIANT: + case SystemBody::TYPE_STAR_O_HYPER_GIANT: + case SystemBody::TYPE_STAR_O_SUPER_GIANT: + case SystemBody::TYPE_STAR_O_WF: { + fixed rnd = rand.Fixed(); + sbody->m_aspectRatio = fixed(1, 1) + fixed(8, 10) * rnd * rnd; + break; + } + // aspect ratio is initialised to 1.0 for other stars currently + default: + break; } sbody->m_mass = fixed(rand.Int32(starTypeInfo[type].mass[0], starTypeInfo[type].mass[1]), 100); sbody->m_averageTemp = rand.Int32(starTypeInfo[type].tempMin, starTypeInfo[type].tempMax); @@ -1169,14 +1115,14 @@ void StarSystemRandomGenerator::MakeBinaryPair(SystemBody *a, SystemBody *b, fix do { switch (rand.Int32(3)) { - case 2: a->m_semiMajorAxis = fixed(rand.Int32(100,10000), 100); break; - case 1: a->m_semiMajorAxis = fixed(rand.Int32(10,1000), 100); break; - default: - case 0: a->m_semiMajorAxis = fixed(rand.Int32(1,100), 100); break; + case 2: a->m_semiMajorAxis = fixed(rand.Int32(100, 10000), 100); break; + case 1: a->m_semiMajorAxis = fixed(rand.Int32(10, 1000), 100); break; + default: + case 0: a->m_semiMajorAxis = fixed(rand.Int32(1, 100), 100); break; } a->m_semiMajorAxis *= mul; mul *= 2; - } while (a->m_semiMajorAxis - a->m_eccentricity*a->m_semiMajorAxis < minDist); + } while (a->m_semiMajorAxis - a->m_eccentricity * a->m_semiMajorAxis < minDist); const double total_mass = a->GetMass() + b->GetMass(); const double e = a->m_eccentricity.ToDouble(); @@ -1184,32 +1130,32 @@ void StarSystemRandomGenerator::MakeBinaryPair(SystemBody *a, SystemBody *b, fix a->m_orbit.SetShapeAroundBarycentre(AU * (a->m_semiMajorAxis * a0).ToDouble(), total_mass, a->GetMass(), e); b->m_orbit.SetShapeAroundBarycentre(AU * (a->m_semiMajorAxis * a1).ToDouble(), total_mass, b->GetMass(), e); - const float rotX = -0.5f*float(M_PI);//(float)(rand.Double()*M_PI/2.0); + const float rotX = -0.5f * float(M_PI); //(float)(rand.Double()*M_PI/2.0); const float rotY = static_cast(rand.Double(M_PI)); a->m_orbit.SetPlane(matrix3x3d::RotateY(rotY) * matrix3x3d::RotateX(rotX)); - b->m_orbit.SetPlane(matrix3x3d::RotateY(rotY-M_PI) * matrix3x3d::RotateX(rotX)); + b->m_orbit.SetPlane(matrix3x3d::RotateY(rotY - M_PI) * matrix3x3d::RotateX(rotX)); // store orbit parameters for later use to be accesible in other way than by rotMatrix b->m_orbitalPhaseAtStart = b->m_orbitalPhaseAtStart + FIXED_PI; - b->m_orbitalPhaseAtStart = b->m_orbitalPhaseAtStart > 2*FIXED_PI ? b->m_orbitalPhaseAtStart - 2*FIXED_PI : b->m_orbitalPhaseAtStart; - a->m_orbitalPhaseAtStart = a->m_orbitalPhaseAtStart > 2*FIXED_PI ? a->m_orbitalPhaseAtStart - 2*FIXED_PI : a->m_orbitalPhaseAtStart; - a->m_orbitalPhaseAtStart = a->m_orbitalPhaseAtStart < 0 ? a->m_orbitalPhaseAtStart + 2*FIXED_PI : a->m_orbitalPhaseAtStart; - b->m_orbitalOffset = fixed(int(round(rotY*10000)),10000); - a->m_orbitalOffset = fixed(int(round(rotY*10000)),10000); + b->m_orbitalPhaseAtStart = b->m_orbitalPhaseAtStart > 2 * FIXED_PI ? b->m_orbitalPhaseAtStart - 2 * FIXED_PI : b->m_orbitalPhaseAtStart; + a->m_orbitalPhaseAtStart = a->m_orbitalPhaseAtStart > 2 * FIXED_PI ? a->m_orbitalPhaseAtStart - 2 * FIXED_PI : a->m_orbitalPhaseAtStart; + a->m_orbitalPhaseAtStart = a->m_orbitalPhaseAtStart < 0 ? a->m_orbitalPhaseAtStart + 2 * FIXED_PI : a->m_orbitalPhaseAtStart; + b->m_orbitalOffset = fixed(int(round(rotY * 10000)), 10000); + a->m_orbitalOffset = fixed(int(round(rotY * 10000)), 10000); - fixed orbMin = a->m_semiMajorAxis - a->m_eccentricity*a->m_semiMajorAxis; - fixed orbMax = 2*a->m_semiMajorAxis - orbMin; + fixed orbMin = a->m_semiMajorAxis - a->m_eccentricity * a->m_semiMajorAxis; + fixed orbMax = 2 * a->m_semiMajorAxis - orbMin; a->m_orbMin = orbMin; b->m_orbMin = orbMin; a->m_orbMax = orbMax; b->m_orbMax = orbMax; } -bool StarSystemRandomGenerator::Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config) +bool StarSystemRandomGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config) { PROFILE_SCOPED() RefCountedPtr sec = galaxy->GetSector(system->GetPath()); - const Sector::System& secSys = sec->m_systems[system->GetPath().systemIndex]; + const Sector::System &secSys = sec->m_systems[system->GetPath().systemIndex]; if (config->isCustomOnly) return true; @@ -1234,17 +1180,17 @@ bool StarSystemRandomGenerator::Apply(Random& rng, RefCountedPtr galaxy, centGrav1 = system->NewBody(); centGrav1->m_type = SystemBody::TYPE_GRAVPOINT; centGrav1->m_parent = 0; - centGrav1->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" A,B"; + centGrav1->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " A,B"; system->SetRootBody(centGrav1); SystemBody::BodyType type = sec->m_systems[system->GetPath().systemIndex].GetStarType(0); star[0] = system->NewBody(); - star[0]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" A"; + star[0]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " A"; star[0]->m_parent = centGrav1; MakeStarOfType(star[0], type, rng); star[1] = system->NewBody(); - star[1]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" B"; + star[1]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " B"; star[1]->m_parent = centGrav1; MakeStarOfTypeLighterThan(star[1], sec->m_systems[system->GetPath().systemIndex].GetStarType(1), star[0]->GetMassAsFixed(), rng); @@ -1252,21 +1198,21 @@ bool StarSystemRandomGenerator::Apply(Random& rng, RefCountedPtr galaxy, centGrav1->m_children.push_back(star[0]); centGrav1->m_children.push_back(star[1]); // Separate stars by 0.2 radii for each, so that their planets don't bump into the other star - const fixed minDist1 = (fixed(12,10) * star[0]->GetRadiusAsFixed() + fixed(12,10) * star[1]->GetRadiusAsFixed()) * AU_SOL_RADIUS; -try_that_again_guvnah: + const fixed minDist1 = (fixed(12, 10) * star[0]->GetRadiusAsFixed() + fixed(12, 10) * star[1]->GetRadiusAsFixed()) * AU_SOL_RADIUS; + try_that_again_guvnah: MakeBinaryPair(star[0], star[1], minDist1, rng); system->SetNumStars(2); if (numStars > 2) { - if (star[0]->m_orbMax > fixed(100,1)) { + if (star[0]->m_orbMax > fixed(100, 1)) { // reduce to < 100 AU... goto try_that_again_guvnah; } // 3rd and maybe 4th star if (numStars == 3) { star[2] = system->NewBody(); - star[2]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" C"; + star[2]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " C"; star[2]->m_orbMin = 0; star[2]->m_orbMax = 0; MakeStarOfTypeLighterThan(star[2], sec->m_systems[system->GetPath().systemIndex].GetStarType(2), star[0]->GetMassAsFixed(), rng); @@ -1275,21 +1221,21 @@ try_that_again_guvnah: } else { centGrav2 = system->NewBody(); centGrav2->m_type = SystemBody::TYPE_GRAVPOINT; - centGrav2->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" C,D"; + centGrav2->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " C,D"; centGrav2->m_orbMax = 0; star[2] = system->NewBody(); - star[2]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" C"; + star[2]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " C"; star[2]->m_parent = centGrav2; MakeStarOfTypeLighterThan(star[2], sec->m_systems[system->GetPath().systemIndex].GetStarType(2), star[0]->GetMassAsFixed(), rng); star[3] = system->NewBody(); - star[3]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName()+" D"; + star[3]->m_name = sec->m_systems[system->GetPath().systemIndex].GetName() + " D"; star[3]->m_parent = centGrav2; MakeStarOfTypeLighterThan(star[3], sec->m_systems[system->GetPath().systemIndex].GetStarType(3), star[2]->GetMassAsFixed(), rng); // Separate stars by 0.2 radii for each, so that their planets don't bump into the other star - const fixed minDist2 = (fixed(12,10) * star[2]->GetRadiusAsFixed() + fixed(12,10) * star[3]->GetRadiusAsFixed()) * AU_SOL_RADIUS; + const fixed minDist2 = (fixed(12, 10) * star[2]->GetRadiusAsFixed() + fixed(12, 10) * star[3]->GetRadiusAsFixed()) * AU_SOL_RADIUS; MakeBinaryPair(star[2], star[3], minDist2, rng); centGrav2->m_mass = star[2]->GetMassAsFixed() + star[3]->GetMassAsFixed(); centGrav2->m_children.push_back(star[2]); @@ -1304,10 +1250,9 @@ try_that_again_guvnah: centGrav2->m_parent = superCentGrav; system->SetRootBody(superCentGrav); const fixed minDistSuper = star[0]->m_orbMax + star[2]->m_orbMax; - MakeBinaryPair(centGrav1, centGrav2, 4*minDistSuper, rng); + MakeBinaryPair(centGrav1, centGrav2, 4 * minDistSuper, rng); superCentGrav->m_children.push_back(centGrav1); superCentGrav->m_children.push_back(centGrav2); - } } @@ -1316,7 +1261,7 @@ try_that_again_guvnah: system->SetMetallicity(starMetallicities[system->GetRootBody()->GetType()]); // store all of the stars first ... - for (unsigned i=0; iGetNumStars(); i++) { + for (unsigned i = 0; i < system->GetNumStars(); i++) { system->AddStar(star[i]); } // ... because we need them when making planets to calculate surface temperatures @@ -1329,10 +1274,10 @@ try_that_again_guvnah: if (system->GetNumStars() == 4) MakePlanetsAround(system, centGrav2, rng); - // an example export of generated system, can be removed during the merge - //char filename[500]; - //snprintf(filename, 500, "tmp-sys/%s.lua", GetName().c_str()); - //ExportToLua(filename); + // an example export of generated system, can be removed during the merge + //char filename[500]; + //snprintf(filename, 500, "tmp-sys/%s.lua", GetName().c_str()); + //ExportToLua(filename); #ifdef DEBUG_DUMP Dump(); @@ -1344,22 +1289,20 @@ try_that_again_guvnah: * Position a surface starport anywhere. Space.cpp::MakeFrameFor() ensures it * is on dry land (discarding this position if necessary) */ -void PopulateStarSystemGenerator::PositionSettlementOnPlanet(SystemBody* sbody, std::vector &prevOrbits) +void PopulateStarSystemGenerator::PositionSettlementOnPlanet(SystemBody *sbody, std::vector &prevOrbits) { PROFILE_SCOPED() Random r(sbody->GetSeed()); // used for orientation on planet surface - double r2 = r.Double(); // function parameter evaluation order is implementation-dependent - double r1 = r.Double(); // can't put two rands in the same expression + double r2 = r.Double(); // function parameter evaluation order is implementation-dependent + double r1 = r.Double(); // can't put two rands in the same expression // try to ensure that stations are far enough apart - - for (size_t i = 0, iterations = 0; im_orbit.SetPlane(matrix3x3d::RotateZ(2*M_PI*r1) * matrix3x3d::RotateY(2*M_PI*r2)); + sbody->m_orbit.SetPlane(matrix3x3d::RotateZ(2 * M_PI * r1) * matrix3x3d::RotateY(2 * M_PI * r2)); // store latitude and longitude to equivalent orbital parameters to // be accessible easier - sbody->m_inclination = fixed(r1*10000,10000) + FIXED_PI/2; // latitide - sbody->m_orbitalOffset = FIXED_PI/2; // longitude + sbody->m_inclination = fixed(r1 * 10000, 10000) + FIXED_PI / 2; // latitide + sbody->m_orbitalOffset = FIXED_PI / 2; // longitude } /* * Set natural resources, tech level, industry strengths and population levels */ -void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem::GeneratorAPI *system, fixed &outTotalPop) +void PopulateStarSystemGenerator::PopulateStage1(SystemBody *sbody, StarSystem::GeneratorAPI *system, fixed &outTotalPop) { PROFILE_SCOPED() for (auto child : sbody->GetChildren()) { @@ -1399,7 +1342,7 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: } Uint32 _init[6] = { system->GetPath().systemIndex, Uint32(system->GetPath().sectorX), - Uint32(system->GetPath().sectorY), Uint32(system->GetPath().sectorZ), UNIVERSE_SEED, Uint32(sbody->GetSeed()) }; + Uint32(system->GetPath().sectorY), Uint32(system->GetPath().sectorZ), UNIVERSE_SEED, Uint32(sbody->GetSeed()) }; Random rand; rand.seed(_init, 6); @@ -1410,15 +1353,14 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: sbody->m_population = fixed(); /* Bad type of planet for settlement */ - if ((sbody->GetAverageTemp() > CELSIUS+100) || (sbody->GetAverageTemp() < 100) || - (sbody->GetType() != SystemBody::TYPE_PLANET_TERRESTRIAL && sbody->GetType() != SystemBody::TYPE_PLANET_ASTEROID)) - { + if ((sbody->GetAverageTemp() > CELSIUS + 100) || (sbody->GetAverageTemp() < 100) || + (sbody->GetType() != SystemBody::TYPE_PLANET_TERRESTRIAL && sbody->GetType() != SystemBody::TYPE_PLANET_ASTEROID)) { Random starportPopRand; starportPopRand.seed(_init, 6); - // orbital starports should carry a small amount of population - if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) { - sbody->m_population = fixed(1, 100000) + fixed(1, 1000000 + starportPopRand.Int32(-10000,10000)); + // orbital starports should carry a small amount of population + if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) { + sbody->m_population = fixed(1, 100000) + fixed(1, 1000000 + starportPopRand.Int32(-10000, 10000)); outTotalPop += sbody->m_population; } else if (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { sbody->m_population = fixed(1, 10000) + fixed(1, 100000 + starportPopRand.Int32(-100, 100)); @@ -1430,16 +1372,16 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: sbody->m_agricultural = fixed(); - if (sbody->GetLifeAsFixed() > fixed(9,10)) { - sbody->m_agricultural = Clamp(fixed(1,1) - fixed(CELSIUS+25-sbody->GetAverageTemp(), 40), fixed(), fixed(1,1)); - system->SetAgricultural(system->GetAgricultural() + 2*sbody->m_agricultural); - } else if (sbody->GetLifeAsFixed() > fixed(1,2)) { - sbody->m_agricultural = Clamp(fixed(1,1) - fixed(CELSIUS+30-sbody->GetAverageTemp(), 50), fixed(), fixed(1,1)); - system->SetAgricultural(system->GetAgricultural() + 1*sbody->m_agricultural); + if (sbody->GetLifeAsFixed() > fixed(9, 10)) { + sbody->m_agricultural = Clamp(fixed(1, 1) - fixed(CELSIUS + 25 - sbody->GetAverageTemp(), 40), fixed(), fixed(1, 1)); + system->SetAgricultural(system->GetAgricultural() + 2 * sbody->m_agricultural); + } else if (sbody->GetLifeAsFixed() > fixed(1, 2)) { + sbody->m_agricultural = Clamp(fixed(1, 1) - fixed(CELSIUS + 30 - sbody->GetAverageTemp(), 50), fixed(), fixed(1, 1)); + system->SetAgricultural(system->GetAgricultural() + 1 * sbody->m_agricultural); } else { // don't bother populating crap planets - if (sbody->GetMetallicityAsFixed() < fixed(5,10) && - sbody->GetMetallicityAsFixed() < (fixed(1,1) - system->GetHumanProx())) return; + if (sbody->GetMetallicityAsFixed() < fixed(5, 10) && + sbody->GetMetallicityAsFixed() < (fixed(1, 1) - system->GetHumanProx())) return; } const int NUM_CONSUMABLES = 10; @@ -1461,9 +1403,9 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { const GalacticEconomy::CommodityInfo &info = GalacticEconomy::COMMODITY_DATA[i]; - fixed affinity = fixed(1,1); + fixed affinity = fixed(1, 1); if (info.econType & GalacticEconomy::ECON_AGRICULTURE) { - affinity *= 2*sbody->GetAgriculturalAsFixed(); + affinity *= 2 * sbody->GetAgriculturalAsFixed(); } if (info.econType & GalacticEconomy::ECON_INDUSTRY) affinity *= system->GetIndustrial(); // make industry after we see if agriculture and mining are viable @@ -1472,7 +1414,7 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: } affinity *= rand.Fixed(); // producing consumables is wise - for (int j=0; jAddTradeLevel(GalacticEconomy::Commodity(i), -2*howmuch); - for (int j=0; j < GalacticEconomy::CommodityInfo::MAX_ECON_INPUTS; ++j) { + system->AddTradeLevel(GalacticEconomy::Commodity(i), -2 * howmuch); + for (int j = 0; j < GalacticEconomy::CommodityInfo::MAX_ECON_INPUTS; ++j) { if (info.inputs[j] == GalacticEconomy::Commodity::NONE) continue; system->AddTradeLevel(GalacticEconomy::Commodity(info.inputs[j]), howmuch); } @@ -1495,29 +1437,30 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody* sbody, StarSystem:: sbody->m_name = Pi::luaNameGen->BodyName(sbody, namerand); // Add a bunch of things people consume - for (int i=0; iGetLifeAsFixed() > fixed(1,2)) { + if (sbody->GetLifeAsFixed() > fixed(1, 2)) { // life planets can make this jizz probably if ((t == GalacticEconomy::Commodity::AIR_PROCESSORS) || - (t == GalacticEconomy::Commodity::LIQUID_OXYGEN) || - (t == GalacticEconomy::Commodity::GRAIN) || - (t == GalacticEconomy::Commodity::FRUIT_AND_VEG) || - (t == GalacticEconomy::Commodity::ANIMAL_MEAT)) { + (t == GalacticEconomy::Commodity::LIQUID_OXYGEN) || + (t == GalacticEconomy::Commodity::GRAIN) || + (t == GalacticEconomy::Commodity::FRUIT_AND_VEG) || + (t == GalacticEconomy::Commodity::ANIMAL_MEAT)) { continue; } } - system->AddTradeLevel(GalacticEconomy::Commodity(t), rand.Int32(32,128)); + system->AddTradeLevel(GalacticEconomy::Commodity(t), rand.Int32(32, 128)); } // well, outdoor worlds should have way more people - sbody->m_population = fixed(1,10)*sbody->m_population + sbody->m_population*sbody->GetAgriculturalAsFixed(); + sbody->m_population = fixed(1, 10) * sbody->m_population + sbody->m_population * sbody->GetAgriculturalAsFixed(); -// Output("%s: pop %.3f billion\n", name.c_str(), sbody->m_population.ToFloat()); + // Output("%s: pop %.3f billion\n", name.c_str(), sbody->m_population.ToFloat()); outTotalPop += sbody->GetPopulationAsFixed(); } -static bool check_unique_station_name(const std::string & name, const StarSystem * system) { +static bool check_unique_station_name(const std::string &name, const StarSystem *system) +{ PROFILE_SCOPED() bool ret = true; for (const SystemBody *station : system->GetSpaceStations()) @@ -1528,7 +1471,8 @@ static bool check_unique_station_name(const std::string & name, const StarSystem return ret; } -static std::string gen_unique_station_name(SystemBody *sp, const StarSystem *system, RefCountedPtr &namerand) { +static std::string gen_unique_station_name(SystemBody *sp, const StarSystem *system, RefCountedPtr &namerand) +{ PROFILE_SCOPED() std::string name; do { @@ -1537,14 +1481,14 @@ static std::string gen_unique_station_name(SystemBody *sp, const StarSystem *sys return name; } -void PopulateStarSystemGenerator::PopulateAddStations(SystemBody* sbody, StarSystem::GeneratorAPI *system) +void PopulateStarSystemGenerator::PopulateAddStations(SystemBody *sbody, StarSystem::GeneratorAPI *system) { PROFILE_SCOPED() for (auto child : sbody->GetChildren()) PopulateAddStations(child, system); Uint32 _init[6] = { system->GetPath().systemIndex, Uint32(system->GetPath().sectorX), - Uint32(system->GetPath().sectorY), Uint32(system->GetPath().sectorZ), sbody->GetSeed(), UNIVERSE_SEED }; + Uint32(system->GetPath().sectorY), Uint32(system->GetPath().sectorZ), sbody->GetSeed(), UNIVERSE_SEED }; Random rand; rand.seed(_init, 6); @@ -1552,41 +1496,38 @@ void PopulateStarSystemGenerator::PopulateAddStations(SystemBody* sbody, StarSys RefCountedPtr namerand(new Random); namerand->seed(_init, 6); - if (sbody->GetPopulationAsFixed() < fixed(1,1000)) return; - fixed orbMaxS = fixed(1,4)*CalcHillRadius(sbody); - fixed orbMinS = fixed().FromDouble((sbody->CalcAtmosphereParams().atmosRadius + + 500000.0/EARTH_RADIUS)) * AU_EARTH_RADIUS; + if (sbody->GetPopulationAsFixed() < fixed(1, 1000)) return; + fixed orbMaxS = fixed(1, 4) * CalcHillRadius(sbody); + fixed orbMinS = fixed().FromDouble((sbody->CalcAtmosphereParams().atmosRadius + +500000.0 / EARTH_RADIUS)) * AU_EARTH_RADIUS; if (sbody->GetNumChildren() > 0) - orbMaxS = std::min(orbMaxS, fixed(1,2) * sbody->GetChildren()[0]->GetOrbMinAsFixed()); + orbMaxS = std::min(orbMaxS, fixed(1, 2) * sbody->GetChildren()[0]->GetOrbMinAsFixed()); // starports - orbital fixed pop = sbody->GetPopulationAsFixed() + rand.Fixed(); - if( orbMinS < orbMaxS ) - { + if (orbMinS < orbMaxS) { // How many stations do we need? pop -= rand.Fixed(); Uint32 NumToMake = 0; - while(pop >= 0) { + while (pop >= 0) { ++NumToMake; pop -= rand.Fixed(); } // Any to position? - if( NumToMake > 0 ) - { + if (NumToMake > 0) { const double centralMass = sbody->GetMassAsFixed().ToDouble() * EARTH_MASS; // What is our innermost orbit? - fixed innerOrbit = orbMinS;// + ((orbMaxS - orbMinS) / 25); + fixed innerOrbit = orbMinS; // + ((orbMaxS - orbMinS) / 25); // Try to limit the inner orbit to at least three hours. { const double minHours = 3.0; const double seconds = Orbit::OrbitalPeriod(innerOrbit.ToDouble() * AU, centralMass); - const double hours = seconds / (60.0*60.0); - if (hours < minHours) - { + const double hours = seconds / (60.0 * 60.0); + if (hours < minHours) { //knowing that T=2*pi*R/sqrt(G*M/R) find R for set T=4 hours: - fixed orbitFromPeriod = fixed().FromDouble((std::pow(G*centralMass, 1.0/3.0)*std::pow(minHours*60.0*60.0, 2.0/3.0))/(std::pow(2.0*M_PI, 2.0/3.0)*AU)); + fixed orbitFromPeriod = fixed().FromDouble((std::pow(G * centralMass, 1.0 / 3.0) * std::pow(minHours * 60.0 * 60.0, 2.0 / 3.0)) / (std::pow(2.0 * M_PI, 2.0 / 3.0) * AU)); // We can't go higher than our maximum so set it to that. innerOrbit = std::min(orbMaxS, orbitFromPeriod); } @@ -1595,22 +1536,18 @@ void PopulateStarSystemGenerator::PopulateAddStations(SystemBody* sbody, StarSys // I like to think that we'd fill several "shells" of orbits at once rather than fill one and move out further static const Uint32 MAX_ORBIT_SHELLS = 3; fixed shells[MAX_ORBIT_SHELLS]; - if( innerOrbit != orbMaxS ) - { + if (innerOrbit != orbMaxS) { shells[0] = innerOrbit; // low - shells[1] = innerOrbit + ((orbMaxS - innerOrbit) * fixed(1,2)); // med + shells[1] = innerOrbit + ((orbMaxS - innerOrbit) * fixed(1, 2)); // med shells[2] = orbMaxS; // high - } - else - { + } else { shells[0] = shells[1] = shells[2] = innerOrbit; } Uint32 orbitIdx = 0; double orbitSlt = 0.0; - const double orbitSeparation = (NumToMake > 1) ? ((M_PI * 2.0) / double(NumToMake-1)) : M_PI; + const double orbitSeparation = (NumToMake > 1) ? ((M_PI * 2.0) / double(NumToMake - 1)) : M_PI; - for( Uint32 i=0; im_type = SystemBody::TYPE_STARPORT_ORBITAL; sp->m_seed = rand.Int32(); sp->m_parent = sbody; - sp->m_rotationPeriod = fixed(1,3600); + sp->m_rotationPeriod = fixed(1, 3600); sp->m_averageTemp = sbody->GetAverageTemp(); sp->m_mass = 0; @@ -1634,15 +1571,14 @@ void PopulateStarSystemGenerator::PopulateAddStations(SystemBody* sbody, StarSys sp->m_eccentricity = fixed(); sp->m_axialTilt = fixed(); - sp->m_orbit.SetShapeAroundPrimary(sp->GetSemiMajorAxis()*AU, centralMass, 0.0); + sp->m_orbit.SetShapeAroundPrimary(sp->GetSemiMajorAxis() * AU, centralMass, 0.0); // The rotations around X & Y perturb the orbits just a little bit so that not all stations are exactly within the same plane // The Z rotation is what gives them the separation in their orbit around the parent body as a whole. sp->m_orbit.SetPlane( matrix3x3d::RotateX(rand.Double(M_PI * 0.03125)) * matrix3x3d::RotateY(rand.Double(M_PI * 0.03125)) * - matrix3x3d::RotateZ(orbitSlt * orbitSeparation) - ); + matrix3x3d::RotateZ(orbitSlt * orbitSeparation)); sp->m_inclination = fixed(); sbody->m_children.insert(sbody->m_children.begin(), sp); @@ -1678,8 +1614,7 @@ void PopulateStarSystemGenerator::PopulateAddStations(SystemBody* sbody, StarSys } // garuantee that there is always a star port on a populated world - if( !system->HasSpaceStations() ) - { + if (!system->HasSpaceStations()) { SystemBody *sp = system->NewBody(); sp->m_type = SystemBody::TYPE_STARPORT_SURFACE; sp->m_seed = rand.Int32(); @@ -1701,7 +1636,7 @@ void PopulateStarSystemGenerator::SetSysPolit(RefCountedPtr galaxy, RefC Random rand(_init, 5); RefCountedPtr sec = galaxy->GetSector(path); - const CustomSystem* customSystem = sec->m_systems[path.systemIndex].GetCustomSystem(); + const CustomSystem *customSystem = sec->m_systems[path.systemIndex].GetCustomSystem(); SysPolit sysPolit; sysPolit.govType = Polit::GOV_INVALID; @@ -1709,7 +1644,7 @@ void PopulateStarSystemGenerator::SetSysPolit(RefCountedPtr galaxy, RefC if (customSystem) sysPolit.govType = customSystem->govType; if (sysPolit.govType == Polit::GOV_INVALID) { - if (path == SystemPath(0,0,0,0)) { + if (path == SystemPath(0, 0, 0, 0)) { sysPolit.govType = Polit::GOV_EARTHDEMOC; } else if (human_infestedness > 0) { // attempt to get the government type from the faction @@ -1741,10 +1676,10 @@ void PopulateStarSystemGenerator::SetCommodityLegality(RefCountedPtrGetSysPolit().govType; if (a == Polit::GOV_NONE) return; - if(system->GetFaction()->idx != Faction::BAD_FACTION_IDX ) { - for (const std::pair& legality : system->GetFaction()->commodity_legality) + if (system->GetFaction()->idx != Faction::BAD_FACTION_IDX) { + for (const std::pair &legality : system->GetFaction()->commodity_legality) system->SetCommodityLegal(legality.first, (rand.Int32(100) >= legality.second)); - } else { + } else { // this is a non-faction system - do some hardcoded test system->SetCommodityLegal(GalacticEconomy::Commodity::HAND_WEAPONS, (rand.Int32(2) == 0)); system->SetCommodityLegal(GalacticEconomy::Commodity::BATTLE_WEAPONS, (rand.Int32(3) == 0)); @@ -1768,8 +1703,8 @@ void PopulateStarSystemGenerator::SetEconType(RefCountedPtr galaxy, RefCountedPtr system, - GalaxyGenerator::StarSystemConfig* config) +bool PopulateStarSystemGenerator::Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, + GalaxyGenerator::StarSystemConfig *config) { PROFILE_SCOPED() const bool addSpaceStations = !config->isCustomOnly; @@ -1780,8 +1715,7 @@ bool PopulateStarSystemGenerator::Apply(Random& rng, RefCountedPtr galax /* Various system-wide characteristics */ // This is 1 in sector (0,0,0) and approaches 0 farther out // (1,0,0) ~ .688, (1,1,0) ~ .557, (1,1,1) ~ .48 - system->SetHumanProx(galaxy->GetFactions()->IsHomeSystem(system->GetPath()) ? fixed(2,3): fixed(3,1) / - isqrt(9 + 10*(system->GetPath().sectorX*system->GetPath().sectorX + system->GetPath().sectorY*system->GetPath().sectorY + system->GetPath().sectorZ*system->GetPath().sectorZ))); + system->SetHumanProx(galaxy->GetFactions()->IsHomeSystem(system->GetPath()) ? fixed(2, 3) : fixed(3, 1) / isqrt(9 + 10 * (system->GetPath().sectorX * system->GetPath().sectorX + system->GetPath().sectorY * system->GetPath().sectorY + system->GetPath().sectorZ * system->GetPath().sectorZ))); system->SetEconType(GalacticEconomy::ECON_INDUSTRY); system->SetIndustrial(rand.Fixed()); system->SetAgricultural(0); @@ -1791,7 +1725,7 @@ bool PopulateStarSystemGenerator::Apply(Random& rng, RefCountedPtr galax PopulateStage1(system->GetRootBody().Get(), system.Get(), totalPop); system->SetTotalPop(totalPop); -// Output("Trading rates:\n"); + // Output("Trading rates:\n"); // So now we have balances of trade of various commodities. // Lets use black magic to turn these into percentage base price // alterations @@ -1799,18 +1733,19 @@ bool PopulateStarSystemGenerator::Apply(Random& rng, RefCountedPtr galax for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { maximum = std::max(abs(system->GetTradeLevel()[i]), maximum); } - if (maximum) for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { - system->SetTradeLevel(GalacticEconomy::Commodity(i), (system->GetTradeLevel()[i] * MAX_COMMODITY_BASE_PRICE_ADJUSTMENT) / maximum); - system->AddTradeLevel(GalacticEconomy::Commodity(i), rand.Int32(-5, 5)); - } + if (maximum) + for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { + system->SetTradeLevel(GalacticEconomy::Commodity(i), (system->GetTradeLevel()[i] * MAX_COMMODITY_BASE_PRICE_ADJUSTMENT) / maximum); + system->AddTradeLevel(GalacticEconomy::Commodity(i), rand.Int32(-5, 5)); + } -// Unused? -// for (int i=(int)Equip::FIRST_COMMODITY; i<=(int)Equip::LAST_COMMODITY; i++) { -// Equip::Type t = (Equip::Type)i; -// const EquipType &type = Equip::types[t]; -// Output("%s: %d%%\n", type.name, m_tradeLevel[t]); -// } -// Output("System total population %.3f billion\n", m_totalPop.ToFloat()); + // Unused? + // for (int i=(int)Equip::FIRST_COMMODITY; i<=(int)Equip::LAST_COMMODITY; i++) { + // Equip::Type t = (Equip::Type)i; + // const EquipType &type = Equip::types[t]; + // Output("%s: %d%%\n", type.name, m_tradeLevel[t]); + // } + // Output("System total population %.3f billion\n", m_totalPop.ToFloat()); SetSysPolit(galaxy, system, system->GetTotalPop()); SetCommodityLegality(system); diff --git a/src/galaxy/StarSystemGenerator.h b/src/galaxy/StarSystemGenerator.h index dc1a42291..af28cbc28 100644 --- a/src/galaxy/StarSystemGenerator.h +++ b/src/galaxy/StarSystemGenerator.h @@ -4,12 +4,12 @@ #ifndef STARSYSTEM_GENERATOR_H #define STARSYSTEM_GENERATOR_H -#include "StarSystem.h" #include "GalaxyGenerator.h" +#include "StarSystem.h" class StarSystemFromSectorGenerator : public StarSystemGeneratorStage { public: - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config); + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config); }; class StarSystemLegacyGeneratorBase : public StarSystemGeneratorStage { @@ -22,22 +22,22 @@ protected: static const fixed starMetallicities[]; static const StarTypeInfo starTypeInfo[]; - void PickAtmosphere(SystemBody* sbody); - void PickRings(SystemBody* sbody, bool forceRings = false); - fixed CalcHillRadius(SystemBody* sbody) const; + void PickAtmosphere(SystemBody *sbody); + void PickRings(SystemBody *sbody, bool forceRings = false); + fixed CalcHillRadius(SystemBody *sbody) const; }; class StarSystemCustomGenerator : public StarSystemLegacyGeneratorBase { public: - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config); + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config); private: - void CustomGetKidsOf(RefCountedPtr system, SystemBody *parent, const std::vector &children, int *outHumanInfestedness, Random &rand); + void CustomGetKidsOf(RefCountedPtr system, SystemBody *parent, const std::vector &children, int *outHumanInfestedness, Random &rand); }; class StarSystemRandomGenerator : public StarSystemLegacyGeneratorBase { public: - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config); + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config); private: void MakePlanetsAround(RefCountedPtr system, SystemBody *primary, Random &rand); @@ -47,22 +47,22 @@ private: void MakeBinaryPair(SystemBody *a, SystemBody *b, fixed minDist, Random &rand); int CalcSurfaceTemp(const SystemBody *primary, fixed distToPrimary, fixed albedo, fixed greenhouse); - const SystemBody* FindStarAndTrueOrbitalRange(const SystemBody *planet, fixed &orbMin_, fixed &orbMax_) const; + const SystemBody *FindStarAndTrueOrbitalRange(const SystemBody *planet, fixed &orbMin_, fixed &orbMax_) const; void PickPlanetType(SystemBody *sbody, Random &rand); }; class PopulateStarSystemGenerator : public StarSystemLegacyGeneratorBase { public: - virtual bool Apply(Random& rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig* config); + virtual bool Apply(Random &rng, RefCountedPtr galaxy, RefCountedPtr system, GalaxyGenerator::StarSystemConfig *config); private: void SetSysPolit(RefCountedPtr galaxy, RefCountedPtr system, const fixed &human_infestedness); void SetCommodityLegality(RefCountedPtr system); void SetEconType(RefCountedPtr system); - void PopulateAddStations(SystemBody* sbody, StarSystem::GeneratorAPI* system); - void PositionSettlementOnPlanet(SystemBody* sbody, std::vector &prevOrbits); - void PopulateStage1(SystemBody* sbody, StarSystem::GeneratorAPI* system, fixed &outTotalPop); + void PopulateAddStations(SystemBody *sbody, StarSystem::GeneratorAPI *system); + void PositionSettlementOnPlanet(SystemBody *sbody, std::vector &prevOrbits); + void PopulateStage1(SystemBody *sbody, StarSystem::GeneratorAPI *system, fixed &outTotalPop); }; #endif diff --git a/src/galaxy/SystemPath.cpp b/src/galaxy/SystemPath.cpp index 0901b1eac..049a4ae21 100644 --- a/src/galaxy/SystemPath.cpp +++ b/src/galaxy/SystemPath.cpp @@ -7,19 +7,17 @@ #include // https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c -static std::vector split(const std::string& str, const std::string& delim) +static std::vector split(const std::string &str, const std::string &delim) { std::vector tokens; size_t prev = 0, pos = 0; - do - { - pos = str.find(delim, prev); - if (pos == std::string::npos) pos = str.length(); - std::string token = str.substr(prev, pos-prev); - if (!token.empty()) tokens.push_back(token); - prev = pos + delim.length(); - } - while (pos < str.length() && prev < str.length()); + do { + pos = str.find(delim, prev); + if (pos == std::string::npos) pos = str.length(); + std::string token = str.substr(prev, pos - prev); + if (!token.empty()) tokens.push_back(token); + prev = pos + delim.length(); + } while (pos < str.length() && prev < str.length()); return tokens; } @@ -28,13 +26,13 @@ static int ParseInt(const std::string &str) int i = 0; try { i = std::stoi(str); - } catch(const std::invalid_argument &e) { + } catch (const std::invalid_argument &e) { throw SystemPath::ParseFailure(); } return i; } -SystemPath SystemPath::Parse(const char * const str) +SystemPath SystemPath::Parse(const char *const str) { // Parse a system path, three to five integers separated by commas (,), optionally starting with ( and ending with ) // 0,0,0 or (0, 0, 0) or 1,3,-3,5 or (0,0,0,0,18) @@ -43,31 +41,32 @@ SystemPath SystemPath::Parse(const char * const str) assert(s.length() > 0); - if(s[0] == '(') - s = s.substr(1,s.length()); + if (s[0] == '(') + s = s.substr(1, s.length()); - if(s[s.length() - 1] == ')') - s = s.substr(0,s.length() - 1); + if (s[s.length() - 1] == ')') + s = s.substr(0, s.length() - 1); std::vector parts = split(s, ","); int x = 0, y = 0, z = 0, si = 0, bi = 0; - if(parts.size() < 3 || parts.size() > 5) + if (parts.size() < 3 || parts.size() > 5) throw SystemPath::ParseFailure(); - if(parts.size() >= 3) { + if (parts.size() >= 3) { x = ParseInt(parts[0].c_str()); y = ParseInt(parts[1].c_str()); z = ParseInt(parts[2].c_str()); } - if(parts.size() >= 4) { + if (parts.size() >= 4) { si = ParseInt(parts[3].c_str()); } - if(parts.size() == 5) { + if (parts.size() == 5) { bi = ParseInt(parts[4].c_str()); } return SystemPath(x, y, z, si, bi); } -void SystemPath::ToJson(Json &jsonObj) const { +void SystemPath::ToJson(Json &jsonObj) const +{ Json systemPathObj({}); // Create JSON object to contain system path data. systemPathObj["sector_x"] = sectorX; systemPathObj["sector_y"] = sectorY; @@ -77,7 +76,8 @@ void SystemPath::ToJson(Json &jsonObj) const { jsonObj["system_path"] = systemPathObj; // Add system path object to supplied object. } -SystemPath SystemPath::FromJson(const Json &jsonObj) { +SystemPath SystemPath::FromJson(const Json &jsonObj) +{ try { Json systemPathObj = jsonObj["system_path"]; diff --git a/src/galaxy/SystemPath.h b/src/galaxy/SystemPath.h index 94dc6d120..020354985 100644 --- a/src/galaxy/SystemPath.h +++ b/src/galaxy/SystemPath.h @@ -4,33 +4,58 @@ #ifndef _SYSTEMPATH_H #define _SYSTEMPATH_H +#include "JsonFwd.h" #include "LuaWrappable.h" -#include #include #include -#include "JsonFwd.h" +#include class SystemPath : public LuaWrappable { public: struct ParseFailure : public std::invalid_argument { - ParseFailure(): std::invalid_argument("invalid SystemPath format") {} + ParseFailure() : + std::invalid_argument("invalid SystemPath format") {} }; - static SystemPath Parse(const char * const str); + static SystemPath Parse(const char *const str); SystemPath() : - sectorX(0), sectorY(0), sectorZ(0), systemIndex(Uint32(-1)), bodyIndex(Uint32(-1)) {} + sectorX(0), + sectorY(0), + sectorZ(0), + systemIndex(Uint32(-1)), + bodyIndex(Uint32(-1)) {} SystemPath(Sint32 x, Sint32 y, Sint32 z) : - sectorX(x), sectorY(y), sectorZ(z), systemIndex(Uint32(-1)), bodyIndex(Uint32(-1)) {} + sectorX(x), + sectorY(y), + sectorZ(z), + systemIndex(Uint32(-1)), + bodyIndex(Uint32(-1)) {} SystemPath(Sint32 x, Sint32 y, Sint32 z, Uint32 si) : - sectorX(x), sectorY(y), sectorZ(z), systemIndex(si), bodyIndex(Uint32(-1)) {} + sectorX(x), + sectorY(y), + sectorZ(z), + systemIndex(si), + bodyIndex(Uint32(-1)) {} SystemPath(Sint32 x, Sint32 y, Sint32 z, Uint32 si, Uint32 bi) : - sectorX(x), sectorY(y), sectorZ(z), systemIndex(si), bodyIndex(bi) {} + sectorX(x), + sectorY(y), + sectorZ(z), + systemIndex(si), + bodyIndex(bi) {} - SystemPath(const SystemPath &path) - : sectorX(path.sectorX), sectorY(path.sectorY), sectorZ(path.sectorZ), systemIndex(path.systemIndex), bodyIndex(path.bodyIndex) {} - SystemPath(const SystemPath *path) - : sectorX(path->sectorX), sectorY(path->sectorY), sectorZ(path->sectorZ), systemIndex(path->systemIndex), bodyIndex(path->bodyIndex) {} + SystemPath(const SystemPath &path) : + sectorX(path.sectorX), + sectorY(path.sectorY), + sectorZ(path.sectorZ), + systemIndex(path.systemIndex), + bodyIndex(path.bodyIndex) {} + SystemPath(const SystemPath *path) : + sectorX(path->sectorX), + sectorY(path->sectorY), + sectorZ(path->sectorZ), + systemIndex(path->systemIndex), + bodyIndex(path->bodyIndex) {} Sint32 sectorX; Sint32 sectorY; @@ -38,7 +63,8 @@ public: Uint32 systemIndex; Uint32 bodyIndex; - friend bool operator==(const SystemPath &a, const SystemPath &b) { + friend bool operator==(const SystemPath &a, const SystemPath &b) + { if (a.sectorX != b.sectorX) return false; if (a.sectorY != b.sectorY) return false; if (a.sectorZ != b.sectorZ) return false; @@ -47,11 +73,13 @@ public: return true; } - friend bool operator!=(const SystemPath &a, const SystemPath &b) { - return !(a==b); + friend bool operator!=(const SystemPath &a, const SystemPath &b) + { + return !(a == b); } - friend bool operator<(const SystemPath &a, const SystemPath &b) { + friend bool operator<(const SystemPath &a, const SystemPath &b) + { if (a.sectorX != b.sectorX) return (a.sectorX < b.sectorX); if (a.sectorY != b.sectorY) return (a.sectorY < b.sectorY); if (a.sectorZ != b.sectorZ) return (a.sectorZ < b.sectorZ); @@ -59,23 +87,26 @@ public: return (a.bodyIndex < b.bodyIndex); } - static inline double SectorDistance(const SystemPath& a, const SystemPath& b) { + static inline double SectorDistance(const SystemPath &a, const SystemPath &b) + { const Sint32 x = b.sectorX - a.sectorX; const Sint32 y = b.sectorY - a.sectorY; const Sint32 z = b.sectorZ - b.sectorZ; - return sqrt (x*x + y*y + z*z); // sqrt is slow + return sqrt(x * x + y * y + z * z); // sqrt is slow } - static inline double SectorDistanceSqr(const SystemPath& a, const SystemPath& b) { + static inline double SectorDistanceSqr(const SystemPath &a, const SystemPath &b) + { const Sint32 x = b.sectorX - a.sectorX; const Sint32 y = b.sectorY - a.sectorY; const Sint32 z = b.sectorZ - b.sectorZ; - return (x*x + y*y + z*z); // return the square of the distance + return (x * x + y * y + z * z); // return the square of the distance } class LessSectorOnly { public: - bool operator()(const SystemPath& a, const SystemPath& b) const { + bool operator()(const SystemPath &a, const SystemPath &b) const + { if (a.sectorX != b.sectorX) return (a.sectorX < b.sectorX); if (a.sectorY != b.sectorY) return (a.sectorY < b.sectorY); return (a.sectorZ < b.sectorZ); @@ -84,7 +115,8 @@ public: class LessSystemOnly { public: - bool operator()(const SystemPath& a, const SystemPath& b) const { + bool operator()(const SystemPath &a, const SystemPath &b) const + { if (a.sectorX != b.sectorX) return (a.sectorX < b.sectorX); if (a.sectorY != b.sectorY) return (a.sectorY < b.sectorY); if (a.sectorZ != b.sectorZ) return (a.sectorZ < b.sectorZ); @@ -92,33 +124,40 @@ public: } }; - bool IsSectorPath() const { + bool IsSectorPath() const + { return (systemIndex == Uint32(-1) && bodyIndex == Uint32(-1)); } - bool IsSystemPath() const { + bool IsSystemPath() const + { return (systemIndex != Uint32(-1) && bodyIndex == Uint32(-1)); } - bool HasValidSystem() const { + bool HasValidSystem() const + { return (systemIndex != Uint32(-1)); } - bool IsBodyPath() const { + bool IsBodyPath() const + { return (systemIndex != Uint32(-1) && bodyIndex != Uint32(-1)); } - bool HasValidBody() const { + bool HasValidBody() const + { assert((bodyIndex == Uint32(-1)) || (systemIndex != Uint32(-1))); return (bodyIndex != Uint32(-1)); } - bool IsSameSector(const SystemPath &b) const { + bool IsSameSector(const SystemPath &b) const + { if (sectorX != b.sectorX) return false; if (sectorY != b.sectorY) return false; if (sectorZ != b.sectorZ) return false; return true; } - bool IsSameSystem(const SystemPath &b) const { + bool IsSameSystem(const SystemPath &b) const + { assert(HasValidSystem()); assert(b.HasValidSystem()); if (sectorX != b.sectorX) return false; @@ -128,11 +167,13 @@ public: return true; } - SystemPath SectorOnly() const { + SystemPath SectorOnly() const + { return SystemPath(sectorX, sectorY, sectorZ); } - SystemPath SystemOnly() const { + SystemPath SystemOnly() const + { assert(systemIndex != Uint32(-1)); return SystemPath(sectorX, sectorY, sectorZ, systemIndex); } @@ -144,15 +185,16 @@ public: // (for example, to be used for hashing) // see, LuaObject::PushToLua in LuaSystemPath.cpp static_assert(sizeof(Sint32) == sizeof(Uint32), "something crazy is going on!"); - static const size_t SizeAsBlob = 5*sizeof(Uint32); - void SerializeToBlob(char *blob) const { + static const size_t SizeAsBlob = 5 * sizeof(Uint32); + void SerializeToBlob(char *blob) const + { // could just memcpy(blob, this, sizeof(SystemPath)) // but that might include packing and/or vtable pointer - memcpy(blob + 0*sizeof(Uint32), §orX, sizeof(Uint32)); - memcpy(blob + 1*sizeof(Uint32), §orY, sizeof(Uint32)); - memcpy(blob + 2*sizeof(Uint32), §orZ, sizeof(Uint32)); - memcpy(blob + 3*sizeof(Uint32), &systemIndex, sizeof(Uint32)); - memcpy(blob + 4*sizeof(Uint32), &bodyIndex, sizeof(Uint32)); + memcpy(blob + 0 * sizeof(Uint32), §orX, sizeof(Uint32)); + memcpy(blob + 1 * sizeof(Uint32), §orY, sizeof(Uint32)); + memcpy(blob + 2 * sizeof(Uint32), §orZ, sizeof(Uint32)); + memcpy(blob + 3 * sizeof(Uint32), &systemIndex, sizeof(Uint32)); + memcpy(blob + 4 * sizeof(Uint32), &bodyIndex, sizeof(Uint32)); } }; diff --git a/src/gameconsts.h b/src/gameconsts.h index c68798f5b..cd82f813e 100644 --- a/src/gameconsts.h +++ b/src/gameconsts.h @@ -11,15 +11,14 @@ static const double MAX_LANDING_SPEED = 30.0; static const Uint32 UNIVERSE_SEED = 0xabcd1234; static const double EARTH_RADIUS = 6378135.0; -static const double EARTH_MASS = 5.9742e24; -static const double SOL_RADIUS = 6.955e8; -static const double SOL_MASS = 1.98892e30; +static const double EARTH_MASS = 5.9742e24; +static const double SOL_RADIUS = 6.955e8; +static const double SOL_MASS = 1.98892e30; static const double AU = 149598000000.0; static const double G = 6.67428e-11; static const double EARTH_ATMOSPHERE_SURFACE_DENSITY = 1.225; -static const double GAS_CONSTANT_R = 8.3144621; - +static const double GAS_CONSTANT_R = 8.3144621; #endif /* _GAMECONSTS_H */ diff --git a/src/gameui/BindingCapture.cpp b/src/gameui/BindingCapture.cpp index 938abdd19..7a6c041e7 100644 --- a/src/gameui/BindingCapture.cpp +++ b/src/gameui/BindingCapture.cpp @@ -7,106 +7,108 @@ using namespace UI; namespace GameUI { -KeyBindingCapture::KeyBindingCapture(UI::Context *context): Single(context) -{ -} - -KeyBindingCapture::~KeyBindingCapture() -{ - Disconnect(); -} - -void KeyBindingCapture::HandleVisible() -{ - Connect(); -} - -void KeyBindingCapture::HandleInvisible() -{ - Disconnect(); -} - -void KeyBindingCapture::HandleKeyDown(const UI::KeyboardEvent &event) -{ - if (!event.repeat) { // ignore repeated key events - const SDL_Keycode key = event.keysym.sym; - // ignore modifiers on modifiers - // (keycodes for modifier keys are contiguous between SDLK_LCTRL and SDLK_RGUI) - const SDL_Keymod mod = ((key >= SDLK_LCTRL && key <= SDLK_RGUI) ? KMOD_NONE : event.keysym.mod); - m_binding = KeyBindings::KeyBinding::FromKeyMod(key, mod); - onCapture.emit(m_binding); + KeyBindingCapture::KeyBindingCapture(UI::Context *context) : + Single(context) + { } -} -void KeyBindingCapture::Connect() -{ - assert(IsVisible()); - GetContext()->SelectWidget(this); - m_connJoystickHatMove = GetContext()->onJoystickHatMove.connect(sigc::mem_fun(this, &KeyBindingCapture::OnJoystickHatMove)); - m_connJoystickButtonDown = GetContext()->onJoystickButtonDown.connect(sigc::mem_fun(this, &KeyBindingCapture::OnJoystickButtonDown)); -} + KeyBindingCapture::~KeyBindingCapture() + { + Disconnect(); + } -void KeyBindingCapture::Disconnect() -{ - m_connJoystickHatMove.disconnect(); - m_connJoystickButtonDown.disconnect(); -} + void KeyBindingCapture::HandleVisible() + { + Connect(); + } -bool KeyBindingCapture::OnJoystickHatMove(const UI::JoystickHatMotionEvent &event) -{ - m_binding = KeyBindings::KeyBinding::FromJoystickHat(event.joystick, event.hat, static_cast(event.direction)); - onCapture.emit(m_binding); - return true; -} + void KeyBindingCapture::HandleInvisible() + { + Disconnect(); + } -bool KeyBindingCapture::OnJoystickButtonDown(const UI::JoystickButtonEvent &event) -{ - m_binding = KeyBindings::KeyBinding::FromJoystickButton(event.joystick, event.button); - onCapture.emit(m_binding); - return true; -} + void KeyBindingCapture::HandleKeyDown(const UI::KeyboardEvent &event) + { + if (!event.repeat) { // ignore repeated key events + const SDL_Keycode key = event.keysym.sym; + // ignore modifiers on modifiers + // (keycodes for modifier keys are contiguous between SDLK_LCTRL and SDLK_RGUI) + const SDL_Keymod mod = ((key >= SDLK_LCTRL && key <= SDLK_RGUI) ? KMOD_NONE : event.keysym.mod); + m_binding = KeyBindings::KeyBinding::FromKeyMod(key, mod); + onCapture.emit(m_binding); + } + } -AxisBindingCapture::AxisBindingCapture(UI::Context *context): Single(context) -{ - m_binding.Clear(); -} + void KeyBindingCapture::Connect() + { + assert(IsVisible()); + GetContext()->SelectWidget(this); + m_connJoystickHatMove = GetContext()->onJoystickHatMove.connect(sigc::mem_fun(this, &KeyBindingCapture::OnJoystickHatMove)); + m_connJoystickButtonDown = GetContext()->onJoystickButtonDown.connect(sigc::mem_fun(this, &KeyBindingCapture::OnJoystickButtonDown)); + } -AxisBindingCapture::~AxisBindingCapture() -{ - Disconnect(); -} + void KeyBindingCapture::Disconnect() + { + m_connJoystickHatMove.disconnect(); + m_connJoystickButtonDown.disconnect(); + } -void AxisBindingCapture::HandleVisible() -{ - Connect(); -} - -void AxisBindingCapture::HandleInvisible() -{ - Disconnect(); -} - -void AxisBindingCapture::Connect() -{ - assert(IsVisible()); - m_connJoystickAxisMove = GetContext()->onJoystickAxisMove.connect(sigc::mem_fun(this, &AxisBindingCapture::OnJoystickAxisMove)); -} - -void AxisBindingCapture::Disconnect() -{ - m_connJoystickAxisMove.disconnect(); -} - -bool AxisBindingCapture::OnJoystickAxisMove(const UI::JoystickAxisMotionEvent &event) -{ - const float threshold = 0.4f; // joystick axis value is in range -1 to 1 - if (event.value < -threshold || event.value > threshold) { - const auto dir = (event.value > 0 ? KeyBindings::POSITIVE : KeyBindings::NEGATIVE); - m_binding = KeyBindings::JoyAxisBinding(event.joystick, event.axis, dir); + bool KeyBindingCapture::OnJoystickHatMove(const UI::JoystickHatMotionEvent &event) + { + m_binding = KeyBindings::KeyBinding::FromJoystickHat(event.joystick, event.hat, static_cast(event.direction)); onCapture.emit(m_binding); return true; } - return false; -} -} + bool KeyBindingCapture::OnJoystickButtonDown(const UI::JoystickButtonEvent &event) + { + m_binding = KeyBindings::KeyBinding::FromJoystickButton(event.joystick, event.button); + onCapture.emit(m_binding); + return true; + } + + AxisBindingCapture::AxisBindingCapture(UI::Context *context) : + Single(context) + { + m_binding.Clear(); + } + + AxisBindingCapture::~AxisBindingCapture() + { + Disconnect(); + } + + void AxisBindingCapture::HandleVisible() + { + Connect(); + } + + void AxisBindingCapture::HandleInvisible() + { + Disconnect(); + } + + void AxisBindingCapture::Connect() + { + assert(IsVisible()); + m_connJoystickAxisMove = GetContext()->onJoystickAxisMove.connect(sigc::mem_fun(this, &AxisBindingCapture::OnJoystickAxisMove)); + } + + void AxisBindingCapture::Disconnect() + { + m_connJoystickAxisMove.disconnect(); + } + + bool AxisBindingCapture::OnJoystickAxisMove(const UI::JoystickAxisMotionEvent &event) + { + const float threshold = 0.4f; // joystick axis value is in range -1 to 1 + if (event.value < -threshold || event.value > threshold) { + const auto dir = (event.value > 0 ? KeyBindings::POSITIVE : KeyBindings::NEGATIVE); + m_binding = KeyBindings::JoyAxisBinding(event.joystick, event.axis, dir); + onCapture.emit(m_binding); + return true; + } + return false; + } + +} // namespace GameUI diff --git a/src/gameui/BindingCapture.h b/src/gameui/BindingCapture.h index c2f67fe7c..829c1a49a 100644 --- a/src/gameui/BindingCapture.h +++ b/src/gameui/BindingCapture.h @@ -4,63 +4,63 @@ #ifndef GAMEUI_BINDINGCAPTURE_H #define GAMEUI_BINDINGCAPTURE_H +#include "KeyBindings.h" #include "libs.h" #include "ui/Context.h" -#include "KeyBindings.h" namespace GameUI { -class KeyBindingCapture : public UI::Single { -public: - KeyBindingCapture(UI::Context *context); - ~KeyBindingCapture(); + class KeyBindingCapture : public UI::Single { + public: + KeyBindingCapture(UI::Context *context); + ~KeyBindingCapture(); - virtual bool IsSelectable() const { return true; } + virtual bool IsSelectable() const { return true; } - const KeyBindings::KeyBinding &GetBinding() const { return m_binding; } + const KeyBindings::KeyBinding &GetBinding() const { return m_binding; } - sigc::signal onCapture; + sigc::signal onCapture; -protected: - virtual void HandleVisible(); - virtual void HandleInvisible(); - virtual void HandleKeyDown(const UI::KeyboardEvent &event); + protected: + virtual void HandleVisible(); + virtual void HandleInvisible(); + virtual void HandleKeyDown(const UI::KeyboardEvent &event); -private: - void Connect(); - void Disconnect(); - bool OnJoystickHatMove(const UI::JoystickHatMotionEvent &event); - bool OnJoystickButtonDown(const UI::JoystickButtonEvent &event); + private: + void Connect(); + void Disconnect(); + bool OnJoystickHatMove(const UI::JoystickHatMotionEvent &event); + bool OnJoystickButtonDown(const UI::JoystickButtonEvent &event); - sigc::connection m_connJoystickHatMove; - sigc::connection m_connJoystickButtonDown; - KeyBindings::KeyBinding m_binding; -}; + sigc::connection m_connJoystickHatMove; + sigc::connection m_connJoystickButtonDown; + KeyBindings::KeyBinding m_binding; + }; -class AxisBindingCapture : public UI::Single { -public: - AxisBindingCapture(UI::Context *context); - ~AxisBindingCapture(); + class AxisBindingCapture : public UI::Single { + public: + AxisBindingCapture(UI::Context *context); + ~AxisBindingCapture(); - virtual bool IsSelectable() const { return true; } + virtual bool IsSelectable() const { return true; } - const KeyBindings::JoyAxisBinding &GetBinding() const { return m_binding; } + const KeyBindings::JoyAxisBinding &GetBinding() const { return m_binding; } - sigc::signal onCapture; + sigc::signal onCapture; -protected: - virtual void HandleVisible(); - virtual void HandleInvisible(); + protected: + virtual void HandleVisible(); + virtual void HandleInvisible(); -private: - void Connect(); - void Disconnect(); - bool OnJoystickAxisMove(const UI::JoystickAxisMotionEvent &event); + private: + void Connect(); + void Disconnect(); + bool OnJoystickAxisMove(const UI::JoystickAxisMotionEvent &event); - sigc::connection m_connJoystickAxisMove; - KeyBindings::JoyAxisBinding m_binding; -}; + sigc::connection m_connJoystickAxisMove; + KeyBindings::JoyAxisBinding m_binding; + }; -} +} // namespace GameUI #endif diff --git a/src/gameui/Face.cpp b/src/gameui/Face.cpp index 091c29501..a3aefbd8a 100644 --- a/src/gameui/Face.cpp +++ b/src/gameui/Face.cpp @@ -2,102 +2,105 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Face.h" +#include "FaceParts.h" #include "FileSystem.h" #include "SDLWrappers.h" #include "graphics/TextureBuilder.h" -#include "FaceParts.h" using namespace UI; namespace GameUI { -RefCountedPtr Face::s_material; + RefCountedPtr Face::s_material; -Face::Face(Context *context, Uint32 flags, Uint32 seed) : Single(context), m_preferredSize(INT_MAX) -{ - if (!seed) seed = time(0); + Face::Face(Context *context, Uint32 flags, Uint32 seed) : + Single(context), + m_preferredSize(INT_MAX) + { + if (!seed) seed = time(0); - m_flags = flags; - m_seed = seed; + m_flags = flags; + m_seed = seed; - SDLSurfacePtr faceim = SDLSurfacePtr::WrapNew(SDL_CreateRGBSurface(SDL_SWSURFACE, FaceParts::FACE_WIDTH, FaceParts::FACE_HEIGHT, 24, 0xff, 0xff00, 0xff0000, 0)); + SDLSurfacePtr faceim = SDLSurfacePtr::WrapNew(SDL_CreateRGBSurface(SDL_SWSURFACE, FaceParts::FACE_WIDTH, FaceParts::FACE_HEIGHT, 24, 0xff, 0xff00, 0xff0000, 0)); - FaceParts::FaceDescriptor face; - switch (flags & GENDER_MASK) { + FaceParts::FaceDescriptor face; + switch (flags & GENDER_MASK) { case RAND: face.gender = -1; break; case MALE: face.gender = 0; break; case FEMALE: face.gender = 1; break; default: assert(0); break; + } + + FaceParts::PickFaceParts(face, m_seed); + FaceParts::BuildFaceImage(faceim.Get(), face, (flags & ARMOUR)); + + m_texture.Reset(Graphics::TextureBuilder(faceim, Graphics::LINEAR_CLAMP, true, true).GetOrCreateTexture(GetContext()->GetRenderer(), std::string("face"))); + + if (!s_material) { + Graphics::MaterialDescriptor matDesc; + matDesc.textures = 1; + s_material.Reset(GetContext()->GetRenderer()->CreateMaterial(matDesc)); + } + + m_preferredSize = UI::Point(FaceParts::FACE_WIDTH, FaceParts::FACE_HEIGHT); + SetSizeControlFlags(UI::Widget::PRESERVE_ASPECT); } - FaceParts::PickFaceParts(face, m_seed); - FaceParts::BuildFaceImage(faceim.Get(), face, (flags & ARMOUR)); - - m_texture.Reset(Graphics::TextureBuilder(faceim, Graphics::LINEAR_CLAMP, true, true).GetOrCreateTexture(GetContext()->GetRenderer(), std::string("face"))); - - if (!s_material) { - Graphics::MaterialDescriptor matDesc; - matDesc.textures = 1; - s_material.Reset(GetContext()->GetRenderer()->CreateMaterial(matDesc)); + UI::Point Face::PreferredSize() + { + return m_preferredSize; } - m_preferredSize = UI::Point(FaceParts::FACE_WIDTH, FaceParts::FACE_HEIGHT); - SetSizeControlFlags(UI::Widget::PRESERVE_ASPECT); -} + void Face::Layout() + { + Point size(GetSize()); + Point activeArea(std::min(size.x, size.y)); + Point activeOffset(std::max(0, (size.x - activeArea.x) / 2), std::max(0, (size.y - activeArea.y) / 2)); + SetActiveArea(activeArea, activeOffset); -UI::Point Face::PreferredSize() { - return m_preferredSize; -} - -void Face::Layout() -{ - Point size(GetSize()); - Point activeArea(std::min(size.x, size.y)); - Point activeOffset(std::max(0, (size.x-activeArea.x)/2), std::max(0, (size.y-activeArea.y)/2)); - SetActiveArea(activeArea, activeOffset); - - Widget *innerWidget = GetInnerWidget(); - if (!innerWidget) return; - SetWidgetDimensions(innerWidget, activeOffset, activeArea); - innerWidget->Layout(); -} - -void Face::Draw() -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - if (!m_quad) { - const Point &offset = GetActiveOffset(); - const Point &area = GetActiveArea(); - - const float x = offset.x; - const float y = offset.y; - const float sx = area.x; - const float sy = area.y; - - const vector2f texSize = m_texture->GetDescriptor().texSize; - - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(x, y, 0.0f), vector2f(0.0f, 0.0f)); - va.Add(vector3f(x, y + sy, 0.0f), vector2f(0.0f, texSize.y)); - va.Add(vector3f(x + sx, y, 0.0f), vector2f(texSize.x, 0.0f)); - va.Add(vector3f(x + sx, y + sy, 0.0f), vector2f(texSize.x, texSize.y)); - - s_material->texture0 = m_texture.Get(); - auto state = GetContext()->GetSkin().GetAlphaBlendState(); - m_quad.reset(new Graphics::Drawables::TexturedQuad(r, s_material, va, state)); + Widget *innerWidget = GetInnerWidget(); + if (!innerWidget) return; + SetWidgetDimensions(innerWidget, activeOffset, activeArea); + innerWidget->Layout(); } - m_quad->Draw(r); - Single::Draw(); -} + void Face::Draw() + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + if (!m_quad) { + const Point &offset = GetActiveOffset(); + const Point &area = GetActiveArea(); -Face *Face::SetHeightLines(Uint32 lines) -{ - const Text::TextureFont *font = GetContext()->GetFont(GetFont()).Get(); - const float height = font->GetHeight() * lines; - m_preferredSize = UI::Point(height * float(FaceParts::FACE_WIDTH) / float(FaceParts::FACE_HEIGHT), height); - GetContext()->RequestLayout(); - return this; -} + const float x = offset.x; + const float y = offset.y; + const float sx = area.x; + const float sy = area.y; -} + const vector2f texSize = m_texture->GetDescriptor().texSize; + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + va.Add(vector3f(x, y, 0.0f), vector2f(0.0f, 0.0f)); + va.Add(vector3f(x, y + sy, 0.0f), vector2f(0.0f, texSize.y)); + va.Add(vector3f(x + sx, y, 0.0f), vector2f(texSize.x, 0.0f)); + va.Add(vector3f(x + sx, y + sy, 0.0f), vector2f(texSize.x, texSize.y)); + + s_material->texture0 = m_texture.Get(); + auto state = GetContext()->GetSkin().GetAlphaBlendState(); + m_quad.reset(new Graphics::Drawables::TexturedQuad(r, s_material, va, state)); + } + m_quad->Draw(r); + + Single::Draw(); + } + + Face *Face::SetHeightLines(Uint32 lines) + { + const Text::TextureFont *font = GetContext()->GetFont(GetFont()).Get(); + const float height = font->GetHeight() * lines; + m_preferredSize = UI::Point(height * float(FaceParts::FACE_WIDTH) / float(FaceParts::FACE_HEIGHT), height); + GetContext()->RequestLayout(); + return this; + } + +} // namespace GameUI diff --git a/src/gameui/Face.h b/src/gameui/Face.h index 062e0621b..6b0483e94 100644 --- a/src/gameui/Face.h +++ b/src/gameui/Face.h @@ -4,44 +4,44 @@ #ifndef GAMEUI_FACE_H #define GAMEUI_FACE_H -#include "ui/Context.h" #include "SmartPtr.h" #include "graphics/Drawables.h" #include "graphics/Texture.h" +#include "ui/Context.h" namespace GameUI { -class Face : public UI::Single { -public: - Face(UI::Context *context, Uint32 flags = 0, Uint32 seed = 0); + class Face : public UI::Single { + public: + Face(UI::Context *context, Uint32 flags = 0, Uint32 seed = 0); - virtual UI::Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + virtual UI::Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - Face *SetHeightLines(Uint32 lines); + Face *SetHeightLines(Uint32 lines); - enum Flags { // - RAND = 0, - MALE = (1<<0), - FEMALE = (1<<1), - GENDER_MASK = 0x03, // + enum Flags { // + RAND = 0, + MALE = (1 << 0), + FEMALE = (1 << 1), + GENDER_MASK = 0x03, // - ARMOUR = (1<<2), + ARMOUR = (1 << 2), + }; + + private: + UI::Point m_preferredSize; + + Uint32 m_flags; + Uint32 m_seed; + + static RefCountedPtr s_material; + + RefCountedPtr m_texture; + std::unique_ptr m_quad; }; -private: - UI::Point m_preferredSize; - - Uint32 m_flags; - Uint32 m_seed; - - static RefCountedPtr s_material; - - RefCountedPtr m_texture; - std::unique_ptr m_quad; -}; - -} +} // namespace GameUI #endif diff --git a/src/gameui/GalaxyMap.cpp b/src/gameui/GalaxyMap.cpp index 8147a03ca..eae6f17c1 100644 --- a/src/gameui/GalaxyMap.cpp +++ b/src/gameui/GalaxyMap.cpp @@ -2,123 +2,121 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GalaxyMap.h" -#include "LabelOverlay.h" -#include "galaxy/Galaxy.h" #include "Game.h" +#include "LabelOverlay.h" #include "Pi.h" +#include "galaxy/Galaxy.h" #include "matrix4x4.h" using namespace UI; namespace { -static const char GALAXY_IMAGE_FILE[] = "galaxy_colour.png"; + static const char GALAXY_IMAGE_FILE[] = "galaxy_colour.png"; } // anonymous namespace namespace GameUI { -GalaxyMap::GalaxyMap(Context *context): - OverlayStack(context), - m_baseImage(nullptr), - m_labelOverlay(nullptr), - m_zoom(1.0f), - m_displayScale(0.0f), - m_centreSector(0.0f, 0.0f) -{ - m_baseImage = context->Image( - std::string(GALAXY_IMAGE_FILE), - UI::Widget::EXPAND_WIDTH | UI::Widget::EXPAND_HEIGHT); - m_baseImage->SetPreserveAspect(true); - AddLayer(m_baseImage); + GalaxyMap::GalaxyMap(Context *context) : + OverlayStack(context), + m_baseImage(nullptr), + m_labelOverlay(nullptr), + m_zoom(1.0f), + m_displayScale(0.0f), + m_centreSector(0.0f, 0.0f) + { + m_baseImage = context->Image( + std::string(GALAXY_IMAGE_FILE), + UI::Widget::EXPAND_WIDTH | UI::Widget::EXPAND_HEIGHT); + m_baseImage->SetPreserveAspect(true); + AddLayer(m_baseImage); - m_labelOverlay = new GameUI::LabelOverlay(context); - AddLayer(m_labelOverlay); + m_labelOverlay = new GameUI::LabelOverlay(context); + AddLayer(m_labelOverlay); - GetContext()->RequestLayout(); -} - -UI::Point GalaxyMap::PreferredSize() { - return m_baseImage->PreferredSize(); -} - -void GalaxyMap::Update() -{ - const Galaxy *galaxy = Pi::game->GetGalaxy().Get(); - const float inv_sector_size = 1.0 / Sector::SIZE; - const float radius_sectors = galaxy->GALAXY_RADIUS * inv_sector_size; - - const UI::Point widget_size = m_baseImage->GetSize(); - const float widget_aspect = float(widget_size.x) / float(widget_size.y); - vector2f viewport_sectors(radius_sectors, radius_sectors); - float display_scale; - if (widget_size.x > widget_size.y) { - viewport_sectors.x *= widget_aspect; - display_scale = radius_sectors / float(widget_size.y); - } else { - viewport_sectors.y /= widget_aspect; - display_scale = radius_sectors / float(widget_size.x); - } - display_scale *= 2.0f / m_zoom; - if (!is_equal_exact(m_displayScale, display_scale)) { - m_displayScale = display_scale; - onDisplayScaleChanged.emit(m_displayScale); + GetContext()->RequestLayout(); } - const vector2f sol_offset(galaxy->SOL_OFFSET_X * inv_sector_size, - galaxy->SOL_OFFSET_Y * inv_sector_size); + UI::Point GalaxyMap::PreferredSize() + { + return m_baseImage->PreferredSize(); + } - const Graphics::Frustum frustum( - matrix4x4d::Translation(-m_centreSector.x, -m_centreSector.y, 0.0), - matrix4x4d::ScaleMatrix(m_zoom) * - matrix4x4d::OrthoFrustum(-viewport_sectors.x, viewport_sectors.x, // left, right - viewport_sectors.y, -viewport_sectors.y, // top, bottom - -1.0, 1.0)); - m_labelOverlay->SetView(frustum); + void GalaxyMap::Update() + { + const Galaxy *galaxy = Pi::game->GetGalaxy().Get(); + const float inv_sector_size = 1.0 / Sector::SIZE; + const float radius_sectors = galaxy->GALAXY_RADIUS * inv_sector_size; - m_baseImage->SetTransform(m_zoom, vector2f( - (m_centreSector.x + sol_offset.x) / radius_sectors, - (m_centreSector.y + sol_offset.y) / radius_sectors)); + const UI::Point widget_size = m_baseImage->GetSize(); + const float widget_aspect = float(widget_size.x) / float(widget_size.y); + vector2f viewport_sectors(radius_sectors, radius_sectors); + float display_scale; + if (widget_size.x > widget_size.y) { + viewport_sectors.x *= widget_aspect; + display_scale = radius_sectors / float(widget_size.y); + } else { + viewport_sectors.y /= widget_aspect; + display_scale = radius_sectors / float(widget_size.x); + } + display_scale *= 2.0f / m_zoom; + if (!is_equal_exact(m_displayScale, display_scale)) { + m_displayScale = display_scale; + onDisplayScaleChanged.emit(m_displayScale); + } - OverlayStack::Update(); -} + const vector2f sol_offset(galaxy->SOL_OFFSET_X * inv_sector_size, + galaxy->SOL_OFFSET_Y * inv_sector_size); -void GalaxyMap::ClearLabels() -{ - m_labelOverlay->Clear(); -} + const Graphics::Frustum frustum( + matrix4x4d::Translation(-m_centreSector.x, -m_centreSector.y, 0.0), + matrix4x4d::ScaleMatrix(m_zoom) * + matrix4x4d::OrthoFrustum(-viewport_sectors.x, viewport_sectors.x, // left, right + viewport_sectors.y, -viewport_sectors.y, // top, bottom + -1.0, 1.0)); + m_labelOverlay->SetView(frustum); -GalaxyMap *GalaxyMap::AddAreaLabel(const vector2f &at, const std::string &text) -{ - const vector3f at3(at, 0.0f); - LabelOverlay::Marker *m = m_labelOverlay->AddMarker(text, at3); - m->color = Color4ub(255,255,255,255); - m->style = LabelOverlay::MARKER_NONE; - m->textAnchor = UI::Align::MIDDLE; - return this; -} + m_baseImage->SetTransform(m_zoom, vector2f((m_centreSector.x + sol_offset.x) / radius_sectors, (m_centreSector.y + sol_offset.y) / radius_sectors)); -GalaxyMap *GalaxyMap::AddPointLabel(const vector2f &at, const std::string &text) -{ - const vector3f at3(at, 0.0f); - LabelOverlay::Marker *m = m_labelOverlay->AddMarker(text, at3); - m->color = Color4ub(0,255,0,255); - m->style = LabelOverlay::MARKER_DOT; - m->textAnchor = UI::Align::LEFT; - return this; -} + OverlayStack::Update(); + } -GalaxyMap *GalaxyMap::SetZoom(float v) -{ - m_zoom = Clamp(v, 0.5f, 20.0f); - return this; -} + void GalaxyMap::ClearLabels() + { + m_labelOverlay->Clear(); + } -GalaxyMap *GalaxyMap::SetCentreSector(const vector2f &at) -{ - m_centreSector = at; - return this; -} + GalaxyMap *GalaxyMap::AddAreaLabel(const vector2f &at, const std::string &text) + { + const vector3f at3(at, 0.0f); + LabelOverlay::Marker *m = m_labelOverlay->AddMarker(text, at3); + m->color = Color4ub(255, 255, 255, 255); + m->style = LabelOverlay::MARKER_NONE; + m->textAnchor = UI::Align::MIDDLE; + return this; + } -} + GalaxyMap *GalaxyMap::AddPointLabel(const vector2f &at, const std::string &text) + { + const vector3f at3(at, 0.0f); + LabelOverlay::Marker *m = m_labelOverlay->AddMarker(text, at3); + m->color = Color4ub(0, 255, 0, 255); + m->style = LabelOverlay::MARKER_DOT; + m->textAnchor = UI::Align::LEFT; + return this; + } + GalaxyMap *GalaxyMap::SetZoom(float v) + { + m_zoom = Clamp(v, 0.5f, 20.0f); + return this; + } + + GalaxyMap *GalaxyMap::SetCentreSector(const vector2f &at) + { + m_centreSector = at; + return this; + } + +} // namespace GameUI diff --git a/src/gameui/GalaxyMap.h b/src/gameui/GalaxyMap.h index c7e91b898..0d59ede9c 100644 --- a/src/gameui/GalaxyMap.h +++ b/src/gameui/GalaxyMap.h @@ -9,38 +9,39 @@ namespace GameUI { -class LabelOverlay; + class LabelOverlay; -class GalaxyMap : public UI::OverlayStack { -public: - GalaxyMap(UI::Context *context); + class GalaxyMap : public UI::OverlayStack { + public: + GalaxyMap(UI::Context *context); - virtual UI::Point PreferredSize() override; - virtual void Update() override; + virtual UI::Point PreferredSize() override; + virtual void Update() override; - float GetZoom() const { return m_zoom; } - GalaxyMap *SetZoom(float v); - GalaxyMap *SetCentreSector(const vector2f &at); + float GetZoom() const { return m_zoom; } + GalaxyMap *SetZoom(float v); + GalaxyMap *SetCentreSector(const vector2f &at); - float GetDisplayScale() const { return m_displayScale; } + float GetDisplayScale() const { return m_displayScale; } - void ClearLabels(); + void ClearLabels(); - // Position is in sector X,Y coordinates. - GalaxyMap *AddAreaLabel(const vector2f &at, const std::string &text); + // Position is in sector X,Y coordinates. + GalaxyMap *AddAreaLabel(const vector2f &at, const std::string &text); - // Position is in sector X,Y coordinates. - GalaxyMap *AddPointLabel(const vector2f &at, const std::string &text); + // Position is in sector X,Y coordinates. + GalaxyMap *AddPointLabel(const vector2f &at, const std::string &text); - sigc::signal onDisplayScaleChanged; -private: - UI::Image *m_baseImage; - GameUI::LabelOverlay *m_labelOverlay; - float m_zoom; - float m_displayScale; - vector2f m_centreSector; -}; + sigc::signal onDisplayScaleChanged; -} + private: + UI::Image *m_baseImage; + GameUI::LabelOverlay *m_labelOverlay; + float m_zoom; + float m_displayScale; + vector2f m_centreSector; + }; + +} // namespace GameUI #endif diff --git a/src/gameui/GameUI.h b/src/gameui/GameUI.h index 5a286159a..6395d5a17 100644 --- a/src/gameui/GameUI.h +++ b/src/gameui/GameUI.h @@ -6,11 +6,11 @@ #include "ui/Context.h" +#include "BindingCapture.h" #include "Face.h" #include "GalaxyMap.h" #include "LabelOverlay.h" #include "ModelSpinner.h" -#include "BindingCapture.h" #include "Lua.h" diff --git a/src/gameui/LabelOverlay.cpp b/src/gameui/LabelOverlay.cpp index b9bac6ffd..29a46a9b9 100644 --- a/src/gameui/LabelOverlay.cpp +++ b/src/gameui/LabelOverlay.cpp @@ -5,86 +5,94 @@ namespace { -static vector2f label_offset(const GameUI::LabelOverlay::Marker &m) { - if (m.style == GameUI::LabelOverlay::MARKER_NONE) { - return vector2f(0.0f, 0.0f); - } + static vector2f label_offset(const GameUI::LabelOverlay::Marker &m) + { + if (m.style == GameUI::LabelOverlay::MARKER_NONE) { + return vector2f(0.0f, 0.0f); + } - const float val = 15.0f; + const float val = 15.0f; - switch (m.textAnchor) { - case UI::Align::TOP_LEFT: return vector2f( val, val); - case UI::Align::TOP: return vector2f(0.0f, val); - case UI::Align::TOP_RIGHT: return vector2f(-val, val); - case UI::Align::LEFT: return vector2f( val, 0.0f); - case UI::Align::MIDDLE: return vector2f(0.0f, 0.0f); - case UI::Align::RIGHT: return vector2f(-val, 0.0f); - case UI::Align::BOTTOM_LEFT: return vector2f( val, -val); - case UI::Align::BOTTOM: return vector2f(0.0f, -val); - case UI::Align::BOTTOM_RIGHT: return vector2f(-val, -val); + switch (m.textAnchor) { + case UI::Align::TOP_LEFT: return vector2f(val, val); + case UI::Align::TOP: return vector2f(0.0f, val); + case UI::Align::TOP_RIGHT: return vector2f(-val, val); + case UI::Align::LEFT: return vector2f(val, 0.0f); + case UI::Align::MIDDLE: return vector2f(0.0f, 0.0f); + case UI::Align::RIGHT: return vector2f(-val, 0.0f); + case UI::Align::BOTTOM_LEFT: return vector2f(val, -val); + case UI::Align::BOTTOM: return vector2f(0.0f, -val); + case UI::Align::BOTTOM_RIGHT: return vector2f(-val, -val); default: assert(0 && "unpossible!"); return vector2f(0.0f, 0.0f); + } } -} } // anonymous namespace namespace GameUI { -LabelOverlay::LabelOverlay(UI::Context *context) : UI::Widget(context) - , m_font(GetContext()->GetFont(GetFont())) - , m_view(matrix4x4d::Identity(), matrix4x4d::Identity()) -{ - SetSizeControlFlags(UI::Widget::NO_WIDTH | UI::Widget::NO_HEIGHT); - m_markerDot.reset(new Graphics::Drawables::TexturedQuad( - context->GetRenderer(), "icons/marker_dot.png")); -} - -void LabelOverlay::Draw() -{ - RefCountedPtr ui_font = GetContext()->GetFont(GetFont()); - if (m_font != ui_font) { m_font = ui_font; } - - UI::Point size = GetSize(); - const double sx = size.x; - const double sy = size.y; - - for (const auto &m : m_markers) { - vector3d screen_pos, text_pos; - bool ok = m_view.ProjectPoint(vector3d(m->position), screen_pos); - if (!ok) { continue; } - screen_pos.x *= sx; - screen_pos.y *= sy; - - vector2f screen_posf(screen_pos.x, screen_pos.y); - DrawMarker(*m, screen_posf); - DrawLabelText(*m, screen_posf); + LabelOverlay::LabelOverlay(UI::Context *context) : + UI::Widget(context), + m_font(GetContext()->GetFont(GetFont())), + m_view(matrix4x4d::Identity(), matrix4x4d::Identity()) + { + SetSizeControlFlags(UI::Widget::NO_WIDTH | UI::Widget::NO_HEIGHT); + m_markerDot.reset(new Graphics::Drawables::TexturedQuad( + context->GetRenderer(), "icons/marker_dot.png")); } -} -void LabelOverlay::DrawMarker(const Marker &m, const vector2f &screen_pos) -{ - if (m.style == MARKER_NONE) { return; } - Graphics::Renderer *r = GetContext()->GetRenderer(); - Graphics::Renderer::MatrixTicket saveModelView(r, Graphics::MatrixMode::MODELVIEW); - r->Translate(screen_pos.x, screen_pos.y, 0.0f); - switch (m.style) { + void LabelOverlay::Draw() + { + RefCountedPtr ui_font = GetContext()->GetFont(GetFont()); + if (m_font != ui_font) { + m_font = ui_font; + } + + UI::Point size = GetSize(); + const double sx = size.x; + const double sy = size.y; + + for (const auto &m : m_markers) { + vector3d screen_pos, text_pos; + bool ok = m_view.ProjectPoint(vector3d(m->position), screen_pos); + if (!ok) { + continue; + } + screen_pos.x *= sx; + screen_pos.y *= sy; + + vector2f screen_posf(screen_pos.x, screen_pos.y); + DrawMarker(*m, screen_posf); + DrawLabelText(*m, screen_posf); + } + } + + void LabelOverlay::DrawMarker(const Marker &m, const vector2f &screen_pos) + { + if (m.style == MARKER_NONE) { + return; + } + Graphics::Renderer *r = GetContext()->GetRenderer(); + Graphics::Renderer::MatrixTicket saveModelView(r, Graphics::MatrixMode::MODELVIEW); + r->Translate(screen_pos.x, screen_pos.y, 0.0f); + switch (m.style) { case MARKER_DOT: m_markerDot->Draw(r, m.color); break; default: assert(0 && "invalid marker style"); break; + } } -} -void LabelOverlay::DrawLabelText(const Marker &m, const vector2f &screen_pos) -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - Graphics::Renderer::MatrixTicket saveModelView(r, Graphics::MatrixMode::MODELVIEW); + void LabelOverlay::DrawLabelText(const Marker &m, const vector2f &screen_pos) + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + Graphics::Renderer::MatrixTicket saveModelView(r, Graphics::MatrixMode::MODELVIEW); - vector2f text_size, text_pos = screen_pos; + vector2f text_size, text_pos = screen_pos; - m_font->MeasureString(m.text, text_size.x, text_size.y); + m_font->MeasureString(m.text, text_size.x, text_size.y); - switch (m.textAnchor) { + switch (m.textAnchor) { case UI::Align::TOP_LEFT: case UI::Align::TOP: case UI::Align::TOP_RIGHT: @@ -92,63 +100,67 @@ void LabelOverlay::DrawLabelText(const Marker &m, const vector2f &screen_pos) case UI::Align::LEFT: case UI::Align::MIDDLE: case UI::Align::RIGHT: - text_pos.y -= text_size.y*0.5f; break; + text_pos.y -= text_size.y * 0.5f; + break; case UI::Align::BOTTOM_LEFT: case UI::Align::BOTTOM: case UI::Align::BOTTOM_RIGHT: - text_pos.y -= text_size.y; break; - } + text_pos.y -= text_size.y; + break; + } - switch (m.textAnchor) { + switch (m.textAnchor) { case UI::Align::TOP_LEFT: case UI::Align::LEFT: - case UI::Align::BOTTOM_LEFT: break; + case UI::Align::BOTTOM_LEFT: break; case UI::Align::TOP: case UI::Align::MIDDLE: case UI::Align::BOTTOM: - text_pos.x -= text_size.x*0.5f; break; + text_pos.x -= text_size.x * 0.5f; + break; case UI::Align::TOP_RIGHT: case UI::Align::RIGHT: case UI::Align::BOTTOM_RIGHT: - text_pos.x -= text_size.x; break; - } + text_pos.x -= text_size.x; + break; + } - text_pos += label_offset(m); + text_pos += label_offset(m); - // Align to pixels (assumes that the rest of the transform stack doesn't - // apply any scaling or rotation or non-integer translations...) - r->Translate(std::floor(text_pos.x), std::floor(text_pos.y), 0.0f); - auto *vb = m_font->GetCachedVertexBuffer(m.text); - if (vb) { - m_font->RenderBuffer(vb); - } else { - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); - m_font->PopulateString(va, m.text, 0.0f, 0.0f, Color::WHITE); - if (va.GetNumVerts() > 0) { - vb = m_font->CreateVertexBuffer(va, m.text, true); - m_font->RenderBuffer(vb, m.color); + // Align to pixels (assumes that the rest of the transform stack doesn't + // apply any scaling or rotation or non-integer translations...) + r->Translate(std::floor(text_pos.x), std::floor(text_pos.y), 0.0f); + auto *vb = m_font->GetCachedVertexBuffer(m.text); + if (vb) { + m_font->RenderBuffer(vb); + } else { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + m_font->PopulateString(va, m.text, 0.0f, 0.0f, Color::WHITE); + if (va.GetNumVerts() > 0) { + vb = m_font->CreateVertexBuffer(va, m.text, true); + m_font->RenderBuffer(vb, m.color); + } } } -} -LabelOverlay::Marker *LabelOverlay::AddMarker(const std::string &text, const vector3f &pos) -{ - std::unique_ptr m(new Marker); - m->text = text; - m->position = pos; - Marker *mp = m.get(); - m_markers.push_back(std::move(m)); - return mp; -} + LabelOverlay::Marker *LabelOverlay::AddMarker(const std::string &text, const vector3f &pos) + { + std::unique_ptr m(new Marker); + m->text = text; + m->position = pos; + Marker *mp = m.get(); + m_markers.push_back(std::move(m)); + return mp; + } -void LabelOverlay::Clear() -{ - m_markers.clear(); -} + void LabelOverlay::Clear() + { + m_markers.clear(); + } -void LabelOverlay::SetView(const Graphics::Frustum &view_frustum) -{ - m_view = view_frustum; -} + void LabelOverlay::SetView(const Graphics::Frustum &view_frustum) + { + m_view = view_frustum; + } -} +} // namespace GameUI diff --git a/src/gameui/LabelOverlay.h b/src/gameui/LabelOverlay.h index d82dd7549..cbe3d74cb 100644 --- a/src/gameui/LabelOverlay.h +++ b/src/gameui/LabelOverlay.h @@ -4,52 +4,53 @@ #ifndef GAMEUI_LABELOVERLAY_H #define GAMEUI_LABELOVERLAY_H -#include "ui/Context.h" -#include "ui/Align.h" -#include "text/TextureFont.h" -#include "graphics/Frustum.h" #include "graphics/Drawables.h" +#include "graphics/Frustum.h" +#include "text/TextureFont.h" +#include "ui/Align.h" +#include "ui/Context.h" namespace GameUI { -class LabelOverlay : public UI::Widget { -public: - enum MarkerStyle { // - MARKER_NONE, - MARKER_DOT, + class LabelOverlay : public UI::Widget { + public: + enum MarkerStyle { // + MARKER_NONE, + MARKER_DOT, + }; + + struct Marker { + std::string text; + vector3f position; + UI::Align::Direction textAnchor = UI::Align::TOP; + Color4ub color = Color4ub(0, 255, 0, 255); + MarkerStyle style = MARKER_DOT; + }; + + LabelOverlay(UI::Context *context); + + virtual UI::Point PreferredSize() override + { + return UI::Point(UI::Widget::SIZE_EXPAND); + } + + virtual void Draw() override; + + Marker *AddMarker(const std::string &text, const vector3f &pos); + void Clear(); + + void SetView(const Graphics::Frustum &view_frustum); + + private: + void DrawMarker(const Marker &m, const vector2f &screen_pos); + void DrawLabelText(const Marker &m, const vector2f &screen_pos); + + std::vector> m_markers; + RefCountedPtr m_font; + std::unique_ptr m_markerDot; + Graphics::Frustum m_view; }; - struct Marker { - std::string text; - vector3f position; - UI::Align::Direction textAnchor = UI::Align::TOP; - Color4ub color = Color4ub(0, 255, 0, 255); - MarkerStyle style = MARKER_DOT; - }; - - LabelOverlay(UI::Context *context); - - virtual UI::Point PreferredSize() override { - return UI::Point(UI::Widget::SIZE_EXPAND); - } - - virtual void Draw() override; - - Marker *AddMarker(const std::string &text, const vector3f &pos); - void Clear(); - - void SetView(const Graphics::Frustum &view_frustum); - -private: - void DrawMarker(const Marker &m, const vector2f &screen_pos); - void DrawLabelText(const Marker &m, const vector2f &screen_pos); - - std::vector> m_markers; - RefCountedPtr m_font; - std::unique_ptr m_markerDot; - Graphics::Frustum m_view; -}; - -} +} // namespace GameUI #endif diff --git a/src/gameui/Lua.cpp b/src/gameui/Lua.cpp index 44f0c467b..4939e4a51 100644 --- a/src/gameui/Lua.cpp +++ b/src/gameui/Lua.cpp @@ -4,16 +4,16 @@ #include "Lua.h" namespace GameUI { -namespace Lua { + namespace Lua { -void Init() -{ - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); -} + void Init() + { + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + } -} -} + } // namespace Lua +} // namespace GameUI diff --git a/src/gameui/Lua.h b/src/gameui/Lua.h index 8976ea693..5cd965a19 100644 --- a/src/gameui/Lua.h +++ b/src/gameui/Lua.h @@ -4,15 +4,14 @@ #ifndef GAMEUI_LUA_H #define GAMEUI_LUA_H -#include "LuaObject.h" #include "GameUI.h" +#include "LuaObject.h" namespace GameUI { -namespace Lua { + namespace Lua { - void Init(); - -} -} + void Init(); + } +} // namespace GameUI #endif diff --git a/src/gameui/LuaBindingCapture.cpp b/src/gameui/LuaBindingCapture.cpp index 36dba705b..732b5a0b1 100644 --- a/src/gameui/LuaBindingCapture.cpp +++ b/src/gameui/LuaBindingCapture.cpp @@ -3,10 +3,11 @@ #include "BindingCapture.h" #include "LuaObject.h" -#include "ui/LuaSignal.h" #include "LuaPushPull.h" +#include "ui/LuaSignal.h" -inline void pi_lua_generic_push(lua_State * l, const KeyBindings::KeyBinding &value) { +inline void pi_lua_generic_push(lua_State *l, const KeyBindings::KeyBinding &value) +{ if (value.Enabled()) { pi_lua_generic_push(l, value.ToString()); } else { @@ -14,95 +15,100 @@ inline void pi_lua_generic_push(lua_State * l, const KeyBindings::KeyBinding &va } } -inline void pi_lua_generic_push(lua_State * l, const KeyBindings::JoyAxisBinding &value) { +inline void pi_lua_generic_push(lua_State *l, const KeyBindings::JoyAxisBinding &value) +{ pi_lua_generic_push(l, value.ToString()); } namespace GameUI { -class LuaKeyBindingCapture { -public: - - static int l_new(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(new KeyBindingCapture(c)); - return 1; - } - - static int l_attr_binding(lua_State *l) - { - KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); - pi_lua_generic_push(l, kbc->GetBinding()); - return 1; - } - - static int l_attr_binding_description(lua_State *l) - { - KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); - const KeyBindings::KeyBinding &kb = kbc->GetBinding(); - if (kb.Enabled()) { - pi_lua_generic_push(l, kb.Description()); - } else { - lua_pushnil(l); + class LuaKeyBindingCapture { + public: + static int l_new(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(new KeyBindingCapture(c)); + return 1; } - return 1; - } - static int l_attr_on_capture(lua_State *l) { - KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); - UI::LuaSignal().Wrap(l, kbc->onCapture); - return 1; - } -}; + static int l_attr_binding(lua_State *l) + { + KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); + pi_lua_generic_push(l, kbc->GetBinding()); + return 1; + } -class LuaAxisBindingCapture { -public: + static int l_attr_binding_description(lua_State *l) + { + KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); + const KeyBindings::KeyBinding &kb = kbc->GetBinding(); + if (kb.Enabled()) { + pi_lua_generic_push(l, kb.Description()); + } else { + lua_pushnil(l); + } + return 1; + } - static int l_new(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(new AxisBindingCapture(c)); - return 1; - } + static int l_attr_on_capture(lua_State *l) + { + KeyBindingCapture *kbc = LuaObject::CheckFromLua(1); + UI::LuaSignal().Wrap(l, kbc->onCapture); + return 1; + } + }; - static int l_attr_binding(lua_State *l) - { - AxisBindingCapture *abc = LuaObject::CheckFromLua(1); - pi_lua_generic_push(l, abc->GetBinding()); - return 1; - } + class LuaAxisBindingCapture { + public: + static int l_new(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(new AxisBindingCapture(c)); + return 1; + } - static int l_attr_binding_description(lua_State *l) - { - AxisBindingCapture *abc = LuaObject::CheckFromLua(1); - pi_lua_generic_push(l, abc->GetBinding().Description()); - return 1; - } + static int l_attr_binding(lua_State *l) + { + AxisBindingCapture *abc = LuaObject::CheckFromLua(1); + pi_lua_generic_push(l, abc->GetBinding()); + return 1; + } - static int l_attr_on_capture(lua_State *l) { - AxisBindingCapture *abc = LuaObject::CheckFromLua(1); - UI::LuaSignal().Wrap(l, abc->onCapture); - return 1; - } -}; + static int l_attr_binding_description(lua_State *l) + { + AxisBindingCapture *abc = LuaObject::CheckFromLua(1); + pi_lua_generic_push(l, abc->GetBinding().Description()); + return 1; + } -} + static int l_attr_on_capture(lua_State *l) + { + AxisBindingCapture *abc = LuaObject::CheckFromLua(1); + UI::LuaSignal().Wrap(l, abc->onCapture); + return 1; + } + }; + +} // namespace GameUI using namespace GameUI; -template <> const char *LuaObject::s_type = "UI.Game.KeyBindingCapture"; -template <> void LuaObject::RegisterClass() +template <> +const char *LuaObject::s_type = "UI.Game.KeyBindingCapture"; +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; static const luaL_Reg l_methods[] = { - { "New", LuaKeyBindingCapture::l_new }, + { "New", LuaKeyBindingCapture::l_new }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "binding", LuaKeyBindingCapture::l_attr_binding }, + { "binding", LuaKeyBindingCapture::l_attr_binding }, { "bindingDescription", LuaKeyBindingCapture::l_attr_binding_description }, - { "onCapture", LuaKeyBindingCapture::l_attr_on_capture }, + { "onCapture", LuaKeyBindingCapture::l_attr_on_capture }, { 0, 0 } }; @@ -110,20 +116,22 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterPromotion(l_parent, s_type, LuaObject::DynamicCastPromotionTest); } -template <> const char *LuaObject::s_type = "UI.Game.AxisBindingCapture"; -template <> void LuaObject::RegisterClass() +template <> +const char *LuaObject::s_type = "UI.Game.AxisBindingCapture"; +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; static const luaL_Reg l_methods[] = { - { "New", LuaAxisBindingCapture::l_new }, + { "New", LuaAxisBindingCapture::l_new }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "binding", LuaAxisBindingCapture::l_attr_binding }, + { "binding", LuaAxisBindingCapture::l_attr_binding }, { "bindingDescription", LuaAxisBindingCapture::l_attr_binding_description }, - { "onCapture", LuaAxisBindingCapture::l_attr_on_capture }, + { "onCapture", LuaAxisBindingCapture::l_attr_on_capture }, { 0, 0 } }; diff --git a/src/gameui/LuaFace.cpp b/src/gameui/LuaFace.cpp index b159a3ed1..2f55bc0f8 100644 --- a/src/gameui/LuaFace.cpp +++ b/src/gameui/LuaFace.cpp @@ -2,72 +2,75 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Face.h" -#include "LuaObject.h" #include "LuaConstants.h" +#include "LuaObject.h" namespace GameUI { -class LuaFace { -public: + class LuaFace { + public: + static inline Uint32 _unpack_flags(lua_State *l) + { + LUA_DEBUG_START(l); - static inline Uint32 _unpack_flags(lua_State *l) { - LUA_DEBUG_START(l); + Uint32 flags = 0; - Uint32 flags = 0; + if (lua_gettop(l) > 1) { + luaL_checktype(l, 2, LUA_TTABLE); - if (lua_gettop(l) > 1) { - luaL_checktype(l, 2, LUA_TTABLE); - - lua_pushnil(l); - while (lua_next(l, 2)) { - flags |= static_cast(LuaConstants::GetConstantFromArg(l, "GameUIFaceFlags", -1)); - lua_pop(l, 1); + lua_pushnil(l); + while (lua_next(l, 2)) { + flags |= static_cast(LuaConstants::GetConstantFromArg(l, "GameUIFaceFlags", -1)); + lua_pop(l, 1); + } } + + LUA_DEBUG_END(l, 0); + + return flags; } - LUA_DEBUG_END(l, 0); + static int l_new(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); - return flags; - } + Uint32 flags = _unpack_flags(l); - static int l_new(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); + Uint32 seed = 0; - Uint32 flags = _unpack_flags(l); + if (lua_gettop(l) > 2 && !lua_isnil(l, 3)) + seed = luaL_checkunsigned(l, 3); - Uint32 seed = 0; + LuaObject::PushToLua(new Face(c, flags, seed)); + return 1; + } - if (lua_gettop(l) > 2 && !lua_isnil(l, 3)) - seed = luaL_checkunsigned(l, 3); + static int l_set_height_lines(lua_State *l) + { + Face *f = LuaObject::CheckFromLua(1); + Uint32 lines = luaL_checkinteger(l, 2); + f->SetHeightLines(lines); + lua_pushvalue(l, 1); + return 1; + } + }; - LuaObject::PushToLua(new Face(c, flags, seed)); - return 1; - } - - static int l_set_height_lines(lua_State *l) { - Face *f = LuaObject::CheckFromLua(1); - Uint32 lines = luaL_checkinteger(l, 2); - f->SetHeightLines(lines); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace GameUI using namespace GameUI; -template <> const char *LuaObject::s_type = "UI.Game.Face"; +template <> +const char *LuaObject::s_type = "UI.Game.Face"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; static const luaL_Reg l_methods[] = { - { "New", LuaFace::l_new }, + { "New", LuaFace::l_new }, { "SetHeightLines", LuaFace::l_set_height_lines }, - { 0, 0 } + { 0, 0 } }; LuaObjectBase::CreateClass(s_type, l_parent, l_methods, 0, 0); diff --git a/src/gameui/LuaGalaxyMap.cpp b/src/gameui/LuaGalaxyMap.cpp index 0e75db71b..5d84cb16f 100644 --- a/src/gameui/LuaGalaxyMap.cpp +++ b/src/gameui/LuaGalaxyMap.cpp @@ -2,103 +2,111 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GalaxyMap.h" -#include "LuaObject.h" #include "LuaConstants.h" +#include "LuaObject.h" #include "ui/Lua.h" #include "ui/LuaSignal.h" #include "vector2.h" namespace GameUI { -class LuaGalaxyMap { -public: + class LuaGalaxyMap { + public: + static int l_new(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(new GalaxyMap(c)); + return 1; + } - static int l_new(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(new GalaxyMap(c)); - return 1; - } + static int l_set_zoom(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + map->SetZoom(luaL_checknumber(l, 2)); + lua_settop(l, 1); + return 1; + } - static int l_set_zoom(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - map->SetZoom(luaL_checknumber(l, 2)); - lua_settop(l, 1); - return 1; - } + static int l_clear_labels(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + map->ClearLabels(); + return 0; + } - static int l_clear_labels(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - map->ClearLabels(); - return 0; - } + static int l_add_area_label(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + float x = luaL_checknumber(l, 2); + float y = luaL_checknumber(l, 3); + std::string text; + pi_lua_generic_pull(l, 4, text); + map->AddAreaLabel(vector2f(x, y), text); + lua_settop(l, 1); + return 1; + } - static int l_add_area_label(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - float x = luaL_checknumber(l, 2); - float y = luaL_checknumber(l, 3); - std::string text; - pi_lua_generic_pull(l, 4, text); - map->AddAreaLabel(vector2f(x, y), text); - lua_settop(l, 1); - return 1; - } + static int l_add_point_label(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + float x = luaL_checknumber(l, 2); + float y = luaL_checknumber(l, 3); + std::string text; + pi_lua_generic_pull(l, 4, text); + map->AddPointLabel(vector2f(x, y), text); + lua_settop(l, 1); + return 1; + } - static int l_add_point_label(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - float x = luaL_checknumber(l, 2); - float y = luaL_checknumber(l, 3); - std::string text; - pi_lua_generic_pull(l, 4, text); - map->AddPointLabel(vector2f(x, y), text); - lua_settop(l, 1); - return 1; - } + static int l_set_centre_sector(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + float x = luaL_checknumber(l, 2); + float y = luaL_checknumber(l, 3); + map->SetCentreSector(vector2f(x, y)); + lua_settop(l, 1); + return 1; + } - static int l_set_centre_sector(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - float x = luaL_checknumber(l, 2); - float y = luaL_checknumber(l, 3); - map->SetCentreSector(vector2f(x, y)); - lua_settop(l, 1); - return 1; - } + static int l_attr_map_scale(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + lua_pushnumber(l, map->GetDisplayScale()); + return 1; + } - static int l_attr_map_scale(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - lua_pushnumber(l, map->GetDisplayScale()); - return 1; - } + static int l_attr_on_map_scale_changed(lua_State *l) + { + GalaxyMap *map = LuaObject::CheckFromLua(1); + UI::LuaSignal().Wrap(l, map->onDisplayScaleChanged); + return 1; + } + }; - static int l_attr_on_map_scale_changed(lua_State *l) { - GalaxyMap *map = LuaObject::CheckFromLua(1); - UI::LuaSignal().Wrap(l, map->onDisplayScaleChanged); - return 1; - } - -}; - -} +} // namespace GameUI using namespace GameUI; -template <> const char *LuaObject::s_type = "UI.Game.GalaxyMap"; +template <> +const char *LuaObject::s_type = "UI.Game.GalaxyMap"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "New", &LuaGalaxyMap::l_new }, - { "SetZoom", &LuaGalaxyMap::l_set_zoom }, - { "ClearLabels", &LuaGalaxyMap::l_clear_labels }, - { "AddAreaLabel", &LuaGalaxyMap::l_add_area_label }, - { "AddPointLabel", &LuaGalaxyMap::l_add_point_label }, + { "New", &LuaGalaxyMap::l_new }, + { "SetZoom", &LuaGalaxyMap::l_set_zoom }, + { "ClearLabels", &LuaGalaxyMap::l_clear_labels }, + { "AddAreaLabel", &LuaGalaxyMap::l_add_area_label }, + { "AddPointLabel", &LuaGalaxyMap::l_add_point_label }, { "SetCentreSector", &LuaGalaxyMap::l_set_centre_sector }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "mapScale", &LuaGalaxyMap::l_attr_map_scale }, + { "mapScale", &LuaGalaxyMap::l_attr_map_scale }, { "onMapScaleChanged", &LuaGalaxyMap::l_attr_on_map_scale_changed }, { 0, 0 } }; diff --git a/src/gameui/LuaModelSpinner.cpp b/src/gameui/LuaModelSpinner.cpp index 4f7ea86fb..b94af4542 100644 --- a/src/gameui/LuaModelSpinner.cpp +++ b/src/gameui/LuaModelSpinner.cpp @@ -1,55 +1,57 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "ModelSpinner.h" #include "LuaObject.h" +#include "ModelSpinner.h" #include "Pi.h" namespace GameUI { -class LuaModelSpinner { -public: + class LuaModelSpinner { + public: + static int l_new(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + const std::string name(luaL_checkstring(l, 2)); + SceneGraph::ModelSkin noskin, *skin = &noskin; + if (lua_gettop(l) > 2) + skin = LuaObject::CheckFromLua(3); + unsigned int pattern = 0; + if (lua_gettop(l) > 3 && !lua_isnoneornil(l, 4)) + pattern = luaL_checkinteger(l, 4) - 1; // Lua counts from 1 + SceneGraph::Model *model = Pi::FindModel(name); + LuaObject::PushToLua(new ModelSpinner(c, model, *skin, pattern)); + return 1; + } - static int l_new(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - const std::string name(luaL_checkstring(l, 2)); - SceneGraph::ModelSkin noskin, *skin = &noskin; - if (lua_gettop(l) > 2) - skin = LuaObject::CheckFromLua(3); - unsigned int pattern = 0; - if (lua_gettop(l) > 3 && !lua_isnoneornil(l, 4)) - pattern = luaL_checkinteger(l, 4) - 1; // Lua counts from 1 - SceneGraph::Model *model = Pi::FindModel(name); - LuaObject::PushToLua(new ModelSpinner(c, model, *skin, pattern)); - return 1; - } + static int l_attr_model(lua_State *l) + { + ModelSpinner *ms = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(ms->GetModel()); + return 1; + } + }; - static int l_attr_model(lua_State *l) { - ModelSpinner *ms = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(ms->GetModel()); - return 1; - } - -}; - -} +} // namespace GameUI using namespace GameUI; -template <> const char *LuaObject::s_type = "UI.Game.ModelSpinner"; +template <> +const char *LuaObject::s_type = "UI.Game.ModelSpinner"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; static const luaL_Reg l_methods[] = { { "New", LuaModelSpinner::l_new }, - { 0, 0 } + { 0, 0 } }; static const luaL_Reg l_attrs[] = { { "model", LuaModelSpinner::l_attr_model }, - { 0, 0 } + { 0, 0 } }; LuaObjectBase::CreateClass(s_type, l_parent, l_methods, l_attrs, 0); diff --git a/src/gameui/ModelSpinner.cpp b/src/gameui/ModelSpinner.cpp index a81c5f7cf..1c62691e3 100644 --- a/src/gameui/ModelSpinner.cpp +++ b/src/gameui/ModelSpinner.cpp @@ -2,90 +2,91 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ModelSpinner.h" +#include "Game.h" +#include "Pi.h" #include "Shields.h" #include "Ship.h" -#include "Pi.h" -#include "Game.h" #include "scenegraph/Model.h" using namespace UI; namespace GameUI { -ModelSpinner::ModelSpinner(Context *context, SceneGraph::Model *model, const SceneGraph::ModelSkin &skin, unsigned int pattern) : Widget(context), - m_skin(skin), - m_rotX(DEG2RAD(-15.0)), m_rotY(DEG2RAD(180.0)), - m_rightMouseButton(false) -{ - m_model.reset(model->MakeInstance()); - m_skin.Apply(m_model.get()); - m_model->SetPattern(pattern); - m_shields.reset(new Shields(model)); + ModelSpinner::ModelSpinner(Context *context, SceneGraph::Model *model, const SceneGraph::ModelSkin &skin, unsigned int pattern) : + Widget(context), + m_skin(skin), + m_rotX(DEG2RAD(-15.0)), + m_rotY(DEG2RAD(180.0)), + m_rightMouseButton(false) + { + m_model.reset(model->MakeInstance()); + m_skin.Apply(m_model.get()); + m_model->SetPattern(pattern); + m_shields.reset(new Shields(model)); - Color lc(Color::WHITE); - m_light.SetDiffuse(lc); - m_light.SetSpecular(lc); - m_light.SetPosition(vector3f(0.f, 1.f, 1.f)); - m_light.SetType(Graphics::Light::LIGHT_DIRECTIONAL); -} - -void ModelSpinner::Layout() -{ - Point size(GetSize()); - Point activeArea(std::min(size.x, size.y)); - Point activeOffset(std::max(0, (size.x-activeArea.x)/2), std::max(0, (size.y-activeArea.y)/2)); - SetActiveArea(activeArea, activeOffset); -} - -void ModelSpinner::Update() -{ - if (!(m_rightMouseButton && IsMouseActive())) - m_rotY += Pi::GetFrameTime(); - - if (m_model) { - m_shields->SetEnabled(false); - m_shields->Update(0.0f, 0.0f); + Color lc(Color::WHITE); + m_light.SetDiffuse(lc); + m_light.SetSpecular(lc); + m_light.SetPosition(vector3f(0.f, 1.f, 1.f)); + m_light.SetType(Graphics::Light::LIGHT_DIRECTIONAL); } -} -void ModelSpinner::Draw() -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - - Graphics::Renderer::StateTicket ticket(r); - - const float fov = 45.f; - r->SetPerspectiveProjection(fov, 1.f, 1.f, 10000.f); - r->SetTransform(matrix4x4f::Identity()); - - r->ClearDepthBuffer(); - - r->SetLights(1, &m_light); - - Point pos(GetAbsolutePosition() + GetActiveOffset()); - Point size(GetActiveArea()); - - r->SetViewport(pos.x, GetContext()->GetSize().y - pos.y - size.y, size.x, size.y); - - matrix4x4f rot = matrix4x4f::RotateXMatrix(m_rotX); - rot.RotateY(m_rotY); - const float dist = m_model->GetDrawClipRadius() / sinf(DEG2RAD(fov*0.5f)); - rot[14] = -dist; - m_model->Render(rot); -} - -void ModelSpinner::HandleMouseDown(const MouseButtonEvent &event) -{ - m_rightMouseButton = event.button == UI::MouseButtonEvent::BUTTON_RIGHT; -} - -void ModelSpinner::HandleMouseMove(const UI::MouseMotionEvent &event) -{ - if (m_rightMouseButton && IsMouseActive()) { - m_rotX += -0.002*event.rel.y; - m_rotY += -0.002*event.rel.x; + void ModelSpinner::Layout() + { + Point size(GetSize()); + Point activeArea(std::min(size.x, size.y)); + Point activeOffset(std::max(0, (size.x - activeArea.x) / 2), std::max(0, (size.y - activeArea.y) / 2)); + SetActiveArea(activeArea, activeOffset); } -} + void ModelSpinner::Update() + { + if (!(m_rightMouseButton && IsMouseActive())) + m_rotY += Pi::GetFrameTime(); -} + if (m_model) { + m_shields->SetEnabled(false); + m_shields->Update(0.0f, 0.0f); + } + } + + void ModelSpinner::Draw() + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + + Graphics::Renderer::StateTicket ticket(r); + + const float fov = 45.f; + r->SetPerspectiveProjection(fov, 1.f, 1.f, 10000.f); + r->SetTransform(matrix4x4f::Identity()); + + r->ClearDepthBuffer(); + + r->SetLights(1, &m_light); + + Point pos(GetAbsolutePosition() + GetActiveOffset()); + Point size(GetActiveArea()); + + r->SetViewport(pos.x, GetContext()->GetSize().y - pos.y - size.y, size.x, size.y); + + matrix4x4f rot = matrix4x4f::RotateXMatrix(m_rotX); + rot.RotateY(m_rotY); + const float dist = m_model->GetDrawClipRadius() / sinf(DEG2RAD(fov * 0.5f)); + rot[14] = -dist; + m_model->Render(rot); + } + + void ModelSpinner::HandleMouseDown(const MouseButtonEvent &event) + { + m_rightMouseButton = event.button == UI::MouseButtonEvent::BUTTON_RIGHT; + } + + void ModelSpinner::HandleMouseMove(const UI::MouseMotionEvent &event) + { + if (m_rightMouseButton && IsMouseActive()) { + m_rotX += -0.002 * event.rel.y; + m_rotY += -0.002 * event.rel.x; + } + } + +} // namespace GameUI diff --git a/src/gameui/ModelSpinner.h b/src/gameui/ModelSpinner.h index e6f03ca31..20ec0f01d 100644 --- a/src/gameui/ModelSpinner.h +++ b/src/gameui/ModelSpinner.h @@ -4,42 +4,42 @@ #ifndef GAMEUI_MODELSPINNER_H #define GAMEUI_MODELSPINNER_H -#include "ui/Context.h" -#include "graphics/Light.h" -#include "scenegraph/SceneGraph.h" -#include "scenegraph/ModelSkin.h" -#include "SmartPtr.h" #include "Shields.h" +#include "SmartPtr.h" +#include "graphics/Light.h" +#include "scenegraph/ModelSkin.h" +#include "scenegraph/SceneGraph.h" +#include "ui/Context.h" namespace GameUI { -class ModelSpinner : public UI::Widget { -public: - ModelSpinner(UI::Context *context, SceneGraph::Model *model, const SceneGraph::ModelSkin &skin, unsigned int pattern); + class ModelSpinner : public UI::Widget { + public: + ModelSpinner(UI::Context *context, SceneGraph::Model *model, const SceneGraph::ModelSkin &skin, unsigned int pattern); - virtual UI::Point PreferredSize() { return UI::Point(INT_MAX); } - virtual void Layout(); - virtual void Update(); - virtual void Draw(); + virtual UI::Point PreferredSize() { return UI::Point(INT_MAX); } + virtual void Layout(); + virtual void Update(); + virtual void Draw(); - SceneGraph::Model *GetModel() const { return m_model.get(); } + SceneGraph::Model *GetModel() const { return m_model.get(); } -protected: - virtual void HandleMouseDown(const UI::MouseButtonEvent &event); - virtual void HandleMouseMove(const UI::MouseMotionEvent &event); + protected: + virtual void HandleMouseDown(const UI::MouseButtonEvent &event); + virtual void HandleMouseMove(const UI::MouseMotionEvent &event); -private: - std::unique_ptr m_model; - SceneGraph::ModelSkin m_skin; - std::unique_ptr m_shields; + private: + std::unique_ptr m_model; + SceneGraph::ModelSkin m_skin; + std::unique_ptr m_shields; - float m_rotX, m_rotY; + float m_rotX, m_rotY; - Graphics::Light m_light; + Graphics::Light m_light; - bool m_rightMouseButton; -}; + bool m_rightMouseButton; + }; -} +} // namespace GameUI #endif diff --git a/src/gameui/Panel.cpp b/src/gameui/Panel.cpp index c442a86dd..aad480e2c 100644 --- a/src/gameui/Panel.cpp +++ b/src/gameui/Panel.cpp @@ -6,9 +6,9 @@ namespace GameUI { -UI::Point Panel::PreferredSize() -{ - return UI::Point(INT_MAX, 80/Gui::Screen::GetCoords2Pixels()[1]); -} + UI::Point Panel::PreferredSize() + { + return UI::Point(INT_MAX, 80 / Gui::Screen::GetCoords2Pixels()[1]); + } -} +} // namespace GameUI diff --git a/src/gameui/Panel.h b/src/gameui/Panel.h index a5cf8be65..2d98c2181 100644 --- a/src/gameui/Panel.h +++ b/src/gameui/Panel.h @@ -11,14 +11,15 @@ namespace GameUI { -class Panel : public UI::Widget { -public: - Panel(UI::Context *context) : UI::Widget(context) {} + class Panel : public UI::Widget { + public: + Panel(UI::Context *context) : + UI::Widget(context) {} - virtual UI::Point PreferredSize(); - virtual void Draw() {} -}; + virtual UI::Point PreferredSize(); + virtual void Draw() {} + }; -} +} // namespace GameUI #endif diff --git a/src/graphics/Drawables.cpp b/src/graphics/Drawables.cpp index e65920416..d1f6c8d02 100644 --- a/src/graphics/Drawables.cpp +++ b/src/graphics/Drawables.cpp @@ -7,924 +7,943 @@ namespace Graphics { -namespace Drawables { - -Circle::Circle(Renderer *renderer, const float radius, const Color &c, RenderState *state) : m_color(c) { - PROFILE_SCOPED() - m_renderState = state; - VertexArray vertices (ATTRIB_POSITION); - for (float theta=0; theta < 2*float(M_PI); theta += 0.05f*float(M_PI)) { - vertices.Add(vector3f(radius*sin(theta), radius*cos(theta), 0)); - } - SetupVertexBuffer(vertices, renderer); -} -Circle::Circle(Renderer *renderer, const float radius, const float x, const float y, const float z, const Color &c, RenderState *state) : m_color(c) { - PROFILE_SCOPED() - m_renderState = state; - VertexArray vertices (ATTRIB_POSITION); - for (float theta=0; theta < 2*float(M_PI); theta += 0.05f*float(M_PI)) { - vertices.Add(vector3f(radius*sin(theta) + x, radius*cos(theta) + y, z)); - } - SetupVertexBuffer(vertices, renderer); -} -Circle::Circle(Renderer *renderer, const float radius, const vector3f ¢er, const Color &c, RenderState *state) : m_color(c) { - PROFILE_SCOPED() - m_renderState = state; - VertexArray vertices (ATTRIB_POSITION); - for (float theta=0; theta < 2*float(M_PI); theta += 0.05f*float(M_PI)) { - vertices.Add(vector3f(radius*sin(theta) + center.x, radius*cos(theta) + center.y, center.z)); - } - SetupVertexBuffer(vertices, renderer); -} - -void Circle::Draw(Renderer *renderer) { - PROFILE_SCOPED() - m_material->diffuse = m_color; - renderer->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), PrimitiveType::LINE_LOOP); -} - -void Circle::SetupVertexBuffer(const Graphics::VertexArray& vertices, Graphics::Renderer *r) -{ - PROFILE_SCOPED() - MaterialDescriptor desc; - m_material.Reset(r->CreateMaterial(desc)); - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = vertices.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vertices); -} -//------------------------------------------------------------ - -Disk::Disk(Graphics::Renderer *r, Graphics::RenderState *state, const Color &c, float rad) -{ - PROFILE_SCOPED() - m_renderState = state; - - VertexArray vertices (ATTRIB_POSITION); - m_material.Reset(r->CreateMaterial(MaterialDescriptor())); - m_material->diffuse = c; - - vertices.Add(vector3f(0.f, 0.f, 0.f)); - for (int i = 72; i >= 0; i--) { - vertices.Add(vector3f( - 0.f+sinf(DEG2RAD(i*5.f))*rad, - 0.f+cosf(DEG2RAD(i*5.f))*rad, - 0.f)); - } - - SetupVertexBuffer(vertices, r); -} - -Disk::Disk(Graphics::Renderer *r, RefCountedPtr material, Graphics::RenderState *state, const int edges, const float rad) - : m_material(material) -{ - PROFILE_SCOPED() - m_renderState = state; - - VertexArray vertices (ATTRIB_POSITION); - - vertices.Add(vector3f(0.f, 0.f, 0.f)); - const float edgeStep = 360.0f / float(edges); - for (int i = edges; i >= 0; i--) { - vertices.Add(vector3f( - 0.f+sinf(DEG2RAD(i*edgeStep))*rad, - 0.f+cosf(DEG2RAD(i*edgeStep))*rad, - 0.f)); - } - - SetupVertexBuffer(vertices, r); -} - -void Disk::Draw(Renderer *r) -{ - PROFILE_SCOPED() - r->DrawBuffer(m_vertexBuffer.get(), m_renderState, m_material.Get(), TRIANGLE_FAN); -} - -void Disk::SetColor(const Color &c) -{ - m_material->diffuse = c; -} - -void Disk::SetupVertexBuffer(const Graphics::VertexArray& vertices, Graphics::Renderer *r) -{ - PROFILE_SCOPED() - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = vertices.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vertices); -} -//------------------------------------------------------------ - -Line3D::Line3D() : m_refreshVertexBuffer(true), m_width(2.0f), m_va( new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, 2) ) -{ - PROFILE_SCOPED() - assert(m_va.get()); - // XXX bug in Radeon drivers will cause crash in glLineWidth if width >= 3 - m_va->Add(vector3f(0.f), Color::BLANK); - m_va->Add(vector3f(0.f), Color::WHITE); -} - -Line3D::Line3D(const Line3D& b) : Line3D() -{ - PROFILE_SCOPED() - m_refreshVertexBuffer = (b.m_refreshVertexBuffer); - m_width = (b.m_width); - m_material = (b.m_material); - m_vertexBuffer = (b.m_vertexBuffer); - (*m_va.get()) = (*b.m_va.get()); -} - -void Line3D::SetStart(const vector3f &s) -{ - PROFILE_SCOPED() - if(!m_va->position[0].ExactlyEqual(s)) { - m_va->Set(0, s); - Dirty(); - } -} - -void Line3D::SetEnd(const vector3f &e) -{ - PROFILE_SCOPED() - if(!m_va->position[1].ExactlyEqual(e)) { - m_va->Set(1, e); - Dirty(); - } -} - -void Line3D::SetColor(const Color &c) -{ - PROFILE_SCOPED() - if( !(m_va->diffuse[0]==c) ) { - m_va->Set(0, m_va->position[0], c); - m_va->Set(1, m_va->position[1], c * 0.5); - Dirty(); - } -} - -void Line3D::Draw(Renderer *r, RenderState *rs) -{ - PROFILE_SCOPED() - if (m_va->GetNumVerts() == 0) - return; - - if( !m_vertexBuffer.Valid() ) { - CreateVertexBuffer(r, 2); - } - if( m_refreshVertexBuffer ) { - assert(m_va.get()); - m_refreshVertexBuffer = false; - m_vertexBuffer->Populate( *m_va ); - } - // XXX would be nicer to draw this as a textured triangle strip - // can't guarantee linewidth support - // glLineWidth(m_width); - r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::LINE_SINGLE); - // glLineWidth(1.f); -} - -void Line3D::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) -{ - PROFILE_SCOPED() - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; - vbd.numVertices = size; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - assert(m_vertexBuffer.Valid()); -} - -void Line3D::Dirty() { - m_refreshVertexBuffer = true; -} -//------------------------------------------------------------ - -Lines::Lines() : m_refreshVertexBuffer(true), m_va(new VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE)) -{ - PROFILE_SCOPED() - // XXX bug in Radeon drivers will cause crash in glLineWidth if width >= 3 -} - -void Lines::SetData(const Uint32 vertCount, const vector3f *vertices, const Color &color) -{ - PROFILE_SCOPED() - assert( vertices ); - - // somethings changed so even if the number of verts is constant the data must be uploaded - m_refreshVertexBuffer = true; - - // if the number of vert mismatches then clear the current vertex buffer - if( m_vertexBuffer.Valid() && m_vertexBuffer->GetCapacity() < vertCount ) { - // a new one will be created when it is drawn - m_vertexBuffer.Reset(); - } - - // populate the VertexArray - m_va->Clear(); - for( Uint32 i=0; iAdd(vertices[i], color); - } -} - -void Lines::SetData(const Uint32 vertCount, const vector3f *vertices, const Color *colors) -{ - PROFILE_SCOPED() - assert( vertices ); - - // somethings changed so even if the number of verts is constant the data must be uploaded - m_refreshVertexBuffer = true; - - // if the number of vert mismatches then clear the current vertex buffer - if( m_vertexBuffer.Valid() && m_vertexBuffer->GetCapacity() < vertCount ) { - // a new one will be created when it is drawn - m_vertexBuffer.Reset(); - } - - // populate the VertexArray - m_va->Clear(); - for( Uint32 i=0; iAdd(vertices[i], colors[i]); - } -} - -void Lines::Draw(Renderer *r, RenderState *rs, const PrimitiveType pt) -{ - PROFILE_SCOPED() - if (m_va->GetNumVerts() == 0) - return; - - if( !m_vertexBuffer.Valid() ) { - CreateVertexBuffer(r, m_va->GetNumVerts() * 2); // ask for twice as many as we need to reduce buffer thrashing - } - if( m_refreshVertexBuffer ) { - m_refreshVertexBuffer = false; - m_vertexBuffer->Populate( *m_va ); - } - // XXX would be nicer to draw this as a textured triangle strip - // can't guarantee linewidth support - // glLineWidth(m_width); - r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), pt); - // glLineWidth(1.f); -} - -void Lines::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) -{ - PROFILE_SCOPED() - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; - vbd.numVertices = size; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); -} - -//------------------------------------------------------------ -PointSprites::PointSprites() : m_refreshVertexBuffer(true) -{ -} - -void PointSprites::SetData(const int count, const vector3f *positions, const Color *colours, const float *sizes, Graphics::Material *pMaterial) -{ - PROFILE_SCOPED() - if (count < 1 ) - return; - - assert(positions); - - m_va.reset( new VertexArray(ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_DIFFUSE, count) ); - - for (int i=0; iAdd(positions[i], colours[i], vSize); - } - - m_refreshVertexBuffer = true; - m_material.Reset(pMaterial); -} - -void PointSprites::Draw(Renderer *r, RenderState *rs) -{ - PROFILE_SCOPED() - if (m_va->GetNumVerts() == 0) - return; - - if (!m_vertexBuffer.Valid() || !m_material.Valid()) { - CreateVertexBuffer(r, m_va->GetNumVerts()); - } - if( m_refreshVertexBuffer ) { - m_refreshVertexBuffer = false; - m_vertexBuffer->Populate( *m_va ); - } - r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::POINTS); -} - -void PointSprites::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) -{ - PROFILE_SCOPED() - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[2].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - vbd.numVertices = size; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); -} - -//------------------------------------------------------------ -Points::Points() : m_refreshVertexBuffer(true) -{ - PROFILE_SCOPED() -} - -void Points::SetData(Renderer* r, const int count, const vector3f *positions, const matrix4x4f &trans, const Color &color, const float size) -{ - PROFILE_SCOPED() - if (count < 1 ) - return; - - assert(positions); - const unsigned int total = (count * 6); - - if (m_va.get() && m_va->GetNumVerts() == total) { - m_va->Clear(); - } else { - m_va.reset(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE, total)); - CreateVertexBuffer(r, total); - } - - matrix4x4f rot(trans); - rot.ClearToRotOnly(); - rot = rot.Inverse(); - - const float sz = 0.5f * size; - const vector3f rotv1 = rot * vector3f(sz, sz, 0.0f); - const vector3f rotv2 = rot * vector3f(sz, -sz, 0.0f); - const vector3f rotv3 = rot * vector3f(-sz, -sz, 0.0f); - const vector3f rotv4 = rot * vector3f(-sz, sz, 0.0f); - - //do two-triangle quads. Could also do indexed surfaces. - //PiGL renderer should use actual point sprites - //(see history of Render.cpp for point code remnants) - for (int i=0; iAdd(pos + rotv4, color); //top left - m_va->Add(pos + rotv3, color); //bottom left - m_va->Add(pos + rotv1, color); //top right - - m_va->Add(pos + rotv1, color); //top right - m_va->Add(pos + rotv3, color); //bottom left - m_va->Add(pos + rotv2, color); //bottom right - } - - m_refreshVertexBuffer = true; -} - -void Points::SetData(Renderer* r, const int count, const vector3f *positions, const Color *color, const matrix4x4f &trans, const float size) -{ - PROFILE_SCOPED() - if (count < 1 ) - return; - - assert(positions); - const unsigned int total = (count * 6); - - if (m_va.get() && m_va->GetNumVerts() == total) { - m_va->Clear(); - } else { - m_va.reset(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE, total)); - CreateVertexBuffer(r, total); - } - - matrix4x4f rot(trans); - rot.ClearToRotOnly(); - rot = rot.Inverse(); - - const float sz = 0.5f * size; - const vector3f rotv1 = rot * vector3f(sz, sz, 0.0f); - const vector3f rotv2 = rot * vector3f(sz, -sz, 0.0f); - const vector3f rotv3 = rot * vector3f(-sz, -sz, 0.0f); - const vector3f rotv4 = rot * vector3f(-sz, sz, 0.0f); - - //do two-triangle quads. Could also do indexed surfaces. - //PiGL renderer should use actual point sprites - //(see history of Render.cpp for point code remnants) - for (int i=0; iAdd(pos + rotv4, color[i]); //top left - m_va->Add(pos + rotv3, color[i]); //bottom left - m_va->Add(pos + rotv1, color[i]); //top right - - m_va->Add(pos + rotv1, color[i]); //top right - m_va->Add(pos + rotv3, color[i]); //bottom left - m_va->Add(pos + rotv2, color[i]); //bottom right - } - - m_refreshVertexBuffer = true; -} - -void Points::Draw(Renderer *r, RenderState *rs) -{ - PROFILE_SCOPED() - if (m_va->GetNumVerts() == 0) - return; - - if (!m_vertexBuffer.Valid() || (m_va->GetNumVerts() != m_vertexBuffer->GetSize())) { - CreateVertexBuffer(r, m_va->GetNumVerts()); - } - if( m_refreshVertexBuffer ) { - m_refreshVertexBuffer = false; - m_vertexBuffer->Populate( *m_va ); - } - - r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::TRIANGLES); -} - -void Points::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) -{ - PROFILE_SCOPED() - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; - vbd.numVertices = size; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); -} -//------------------------------------------------------------ - -static const float ICOSX = 0.525731112119133f; -static const float ICOSZ = 0.850650808352039f; - -static const vector3f icosahedron_vertices[12] = { - vector3f(-ICOSX, 0.0, ICOSZ), vector3f(ICOSX, 0.0, ICOSZ), vector3f(-ICOSX, 0.0, -ICOSZ), vector3f(ICOSX, 0.0, -ICOSZ), - vector3f(0.0, ICOSZ, ICOSX), vector3f(0.0, ICOSZ, -ICOSX), vector3f(0.0, -ICOSZ, ICOSX), vector3f(0.0, -ICOSZ, -ICOSX), - vector3f(ICOSZ, ICOSX, 0.0), vector3f(-ICOSZ, ICOSX, 0.0), vector3f(ICOSZ, -ICOSX, 0.0), vector3f(-ICOSZ, -ICOSX, 0.0) -}; - -static const int icosahedron_faces[20][3] = { - {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, - {8,10,1}, {8,3,10},{5,3,8}, {5,2,3}, {2,7,3}, - {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, - {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} -}; - -Sphere3D::Sphere3D(Renderer *renderer, RefCountedPtr mat, Graphics::RenderState *state, int subdivs, float scale, const Uint32 attribs) -{ - PROFILE_SCOPED() - assert(attribs & ATTRIB_POSITION); - - m_material = mat; - m_renderState = state; - - subdivs = Clamp(subdivs, 0, 4); - scale = fabs(scale); - matrix4x4f trans = matrix4x4f::Identity(); - trans.Scale(scale, scale, scale); - - //reserve some data - ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0 - VertexArray vts(attribs, (subdivs * subdivs) * 20 * 3); - std::vector indices; - - //initial vertices - int vi[12]; - for (int i=0; i<12; i++) { - const vector3f &v = icosahedron_vertices[i]; - vi[i] = AddVertex(vts, trans * v, v); - } - - //subdivide - for (int i=0; i<20; i++) { - Subdivide(vts, indices, trans, icosahedron_vertices[icosahedron_faces[i][0]], - icosahedron_vertices[icosahedron_faces[i][1]], - icosahedron_vertices[icosahedron_faces[i][2]], - vi[icosahedron_faces[i][0]], - vi[icosahedron_faces[i][1]], - vi[icosahedron_faces[i][2]], - subdivs); - } - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - Uint32 attIdx = 0; - vbd.attrib[attIdx].semantic = ATTRIB_POSITION; - vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attIdx; - if (attribs & ATTRIB_NORMAL) { - vbd.attrib[attIdx].semantic = ATTRIB_NORMAL; - vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attIdx; - } - if (attribs & ATTRIB_UV0) { - vbd.attrib[attIdx].semantic = ATTRIB_UV0; - vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT2; - ++attIdx; - } - vbd.numVertices = vts.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.reset(renderer->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vts); - - m_indexBuffer.reset(renderer->CreateIndexBuffer(indices.size(), BUFFER_USAGE_STATIC)); - Uint32 *idxPtr = m_indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); - for (auto it : indices) { - *idxPtr = it; - idxPtr++; - } - m_indexBuffer->Unmap(); -} - -void Sphere3D::Draw(Renderer *r) -{ - PROFILE_SCOPED() - r->DrawBufferIndexed(m_vertexBuffer.get(), m_indexBuffer.get(), m_renderState, m_material.Get()); -} - -int Sphere3D::AddVertex(VertexArray &vts, const vector3f &v, const vector3f &n) -{ - PROFILE_SCOPED() - vts.position.push_back(v); - if (vts.HasAttrib(ATTRIB_NORMAL)) { - vts.normal.push_back(n); - } - if (vts.HasAttrib(ATTRIB_UV0)) { - //http://www.mvps.org/directx/articles/spheremap.htm - vts.uv0.push_back(vector2f(asinf(n.x) / M_PI + 0.5f, asinf(n.y) / M_PI + 0.5f)); - } - return vts.GetNumVerts() - 1; -} - -void Sphere3D::AddTriangle(std::vector &indices, int i1, int i2, int i3) -{ - PROFILE_SCOPED() - indices.push_back(i1); - indices.push_back(i2); - indices.push_back(i3); -} - -void Sphere3D::Subdivide(VertexArray &vts, std::vector &indices, - const matrix4x4f &trans, const vector3f &v1, const vector3f &v2, const vector3f &v3, - const int i1, const int i2, const int i3, int depth) -{ - PROFILE_SCOPED() - if (depth == 0) { - AddTriangle(indices, i1, i3, i2); - return; - } - - const vector3f v12 = (v1+v2).Normalized(); - const vector3f v23 = (v2+v3).Normalized(); - const vector3f v31 = (v3+v1).Normalized(); - const int i12 = AddVertex(vts, trans * v12, v12); - const int i23 = AddVertex(vts, trans * v23, v23); - const int i31 = AddVertex(vts, trans * v31, v31); - Subdivide(vts, indices, trans, v1, v12, v31, i1, i12, i31, depth-1); - Subdivide(vts, indices, trans, v2, v23, v12, i2, i23, i12, depth-1); - Subdivide(vts, indices, trans, v3, v31, v23, i3, i31, i23, depth-1); - Subdivide(vts, indices, trans, v12, v23, v31, i12, i23, i31, depth-1); -} -//------------------------------------------------------------ - -TexturedQuad::TexturedQuad(Graphics::Renderer *r, const std::string &filename) -{ - PROFILE_SCOPED() - - Graphics::TextureBuilder texbuilder = Graphics::TextureBuilder::UI(filename); - m_texture.Reset(texbuilder.GetOrCreateTexture(r, "ui")); - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthTest = false; - rsd.depthWrite = false; - m_renderState = r->CreateRenderState(rsd); - - VertexArray vertices(ATTRIB_POSITION | ATTRIB_UV0); - Graphics::MaterialDescriptor desc; - desc.effect = Graphics::EFFECT_DEFAULT; - desc.textures = 1; - desc.lighting = false; - desc.vertexColors = false; - m_material.Reset(r->CreateMaterial(desc)); - m_material->texture0 = m_texture.Get(); - - // these might need to be reversed - const vector2f texSize = m_texture->GetDescriptor().texSize; - const vector2f halfsz = 0.5f * m_texture->GetDescriptor().GetOriginalSize(); - - vertices.Add(vector3f(-halfsz.x, -halfsz.y, 0.0f), vector2f(0.0f, texSize.y)); - vertices.Add(vector3f(-halfsz.x, halfsz.y, 0.0f), vector2f(0.0f, 0.0f)); - vertices.Add(vector3f( halfsz.x, -halfsz.y, 0.0f), vector2f(texSize.x, texSize.y)); - vertices.Add(vector3f( halfsz.x, halfsz.y, 0.0f), vector2f(texSize.x, 0.0f)); - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = ATTRIB_UV0; - vbd.attrib[1].format = ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = vertices.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vertices); -} - -// a textured quad with reversed winding -TexturedQuad::TexturedQuad(Graphics::Renderer *r, Graphics::Texture *texture, const vector2f &pos, const vector2f &size, RenderState *state) - : m_texture(RefCountedPtr(texture)) -{ - PROFILE_SCOPED() - assert(state); - m_renderState = state; - - VertexArray vertices(ATTRIB_POSITION | ATTRIB_UV0); - Graphics::MaterialDescriptor desc; - desc.textures = 1; - m_material.Reset(r->CreateMaterial(desc)); - m_material->texture0 = m_texture.Get(); - - // these might need to be reversed - const vector2f texPos = vector2f(0.0f); - const vector2f texSize = m_texture->GetDescriptor().texSize; - - vertices.Add(vector3f(pos.x, pos.y, 0.0f), vector2f(texPos.x, texPos.y+texSize.y)); - vertices.Add(vector3f(pos.x, pos.y+size.y, 0.0f), vector2f(texPos.x, texPos.y)); - vertices.Add(vector3f(pos.x+size.x, pos.y, 0.0f), vector2f(texPos.x+texSize.x, texPos.y+texSize.y)); - vertices.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f), vector2f(texPos.x+texSize.x, texPos.y)); - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = ATTRIB_UV0; - vbd.attrib[1].format = ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = vertices.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vertices); -} - -TexturedQuad::TexturedQuad(Graphics::Renderer *r, RefCountedPtr &material, const Graphics::VertexArray &va, RenderState *state) - : m_material(material) -{ - PROFILE_SCOPED() - assert(state); - m_renderState = state; - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - - Uint32 attribIdx = 0; - assert(va.HasAttrib(ATTRIB_POSITION)); - vbd.attrib[attribIdx].semantic = ATTRIB_POSITION; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attribIdx; - - if (va.HasAttrib(ATTRIB_NORMAL)) { - vbd.attrib[attribIdx].semantic = ATTRIB_NORMAL; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attribIdx; - } - if (va.HasAttrib(ATTRIB_DIFFUSE)) { - vbd.attrib[attribIdx].semantic = ATTRIB_DIFFUSE; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_UBYTE4; - ++attribIdx; - } - if (va.HasAttrib(ATTRIB_UV0)) { - vbd.attrib[attribIdx].semantic = ATTRIB_UV0; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT2; - ++attribIdx; - } - if (va.HasAttrib(ATTRIB_TANGENT)) { - vbd.attrib[attribIdx].semantic = ATTRIB_TANGENT; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attribIdx; - } - - vbd.numVertices = va.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(va); -} - -void TexturedQuad::Draw(Graphics::Renderer *r) -{ - PROFILE_SCOPED() - m_material->diffuse = Color::WHITE; - r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_STRIP); -} - -void TexturedQuad::Draw(Graphics::Renderer *r, const Color4ub &tint) -{ - PROFILE_SCOPED() - m_material->diffuse = tint; - r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_STRIP); -} - -//------------------------------------------------------------ -Rect::Rect(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &c, RenderState *state, const bool bIsStatic /*= true*/) : m_renderState(state) -{ - PROFILE_SCOPED() - - using namespace Graphics; - VertexArray bgArr(ATTRIB_POSITION | ATTRIB_DIFFUSE, 4); - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - bgArr.Add(vector3f(pos.x,size.y,0), c); - bgArr.Add(vector3f(size.x,size.y,0), c); - bgArr.Add(vector3f(size.x,pos.y,0), c); - bgArr.Add(vector3f(pos.x,pos.y,0), c); - - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = ATTRIB_DIFFUSE; - vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = 4; - vbd.usage = bIsStatic ? BUFFER_USAGE_STATIC : BUFFER_USAGE_DYNAMIC; - - // VertexBuffer - m_vertexBuffer.Reset( r->CreateVertexBuffer(vbd) ); - m_vertexBuffer->Populate(bgArr); -} - -void Rect::Update(const vector2f &pos, const vector2f &size, const Color &c) -{ - using namespace Graphics; - VertexArray bgArr(ATTRIB_POSITION | ATTRIB_DIFFUSE, 4); - - bgArr.Add(vector3f(pos.x,size.y,0), c); - bgArr.Add(vector3f(size.x,size.y,0), c); - bgArr.Add(vector3f(size.x,pos.y,0), c); - bgArr.Add(vector3f(pos.x,pos.y,0), c); - - m_vertexBuffer->Populate(bgArr); -} - -void Rect::Draw(Graphics::Renderer *r) -{ - PROFILE_SCOPED() - r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_FAN); -} - -//------------------------------------------------------------ -RoundEdgedRect::RoundEdgedRect(Graphics::Renderer *r, const vector2f &size, const float rad, const Color &c, RenderState *state, const bool bIsStatic /*= true*/) : m_renderState(state) -{ - PROFILE_SCOPED() - - using namespace Graphics; - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = ATTRIB_DIFFUSE; - vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = 4 * (STEPS+1); - vbd.usage = bIsStatic ? BUFFER_USAGE_STATIC : BUFFER_USAGE_DYNAMIC; - m_vertexBuffer.Reset( r->CreateVertexBuffer(vbd) ); - - Update(size, rad, c); -} - -void RoundEdgedRect::Update(const vector2f &size, float rad, const Color &c) -{ - Graphics::VertexArray vts(Graphics::ATTRIB_POSITION | ATTRIB_DIFFUSE); - - if (rad > 0.5f*std::min(size.x, size.y)) - rad = 0.5f*std::min(size.x, size.y); - - // top left - // bottom left - for (int i=0; i<=STEPS; i++) { - float ang = M_PI*0.5f*i/float(STEPS); - vts.Add(vector3f(rad - rad*cos(ang), (size.y - rad) + rad*sin(ang), 0.f), c); - } - // bottom right - for (int i=0; i<=STEPS; i++) { - float ang = M_PI*0.5 + M_PI*0.5f*i/float(STEPS); - vts.Add(vector3f(size.x - rad - rad*cos(ang), (size.y - rad) + rad*sin(ang), 0.f), c); - } - // top right - for (int i=0; i<=STEPS; i++) { - float ang = M_PI + M_PI*0.5f*i/float(STEPS); - vts.Add(vector3f((size.x - rad) - rad*cos(ang), rad + rad*sin(ang), 0.f), c); - } - - // top right - for (int i=0; i<=STEPS; i++) { - float ang = M_PI*1.5 + M_PI*0.5f*i/float(STEPS); - vts.Add(vector3f(rad - rad*cos(ang), rad + rad*sin(ang), 0.f), c); - } - - m_vertexBuffer->Populate(vts); -} - -void RoundEdgedRect::Draw(Graphics::Renderer *r) -{ - PROFILE_SCOPED() - r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_FAN); -} - -//------------------------------------------------------------ -Axes3D::Axes3D(Graphics::Renderer *r, Graphics::RenderState *state) -{ - PROFILE_SCOPED() - if( state ) { - m_renderState = state; - } else { - Graphics::RenderStateDesc rsd; - m_renderState = r->CreateRenderState(rsd); - } - - VertexArray vertices(ATTRIB_POSITION | ATTRIB_DIFFUSE); - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(r->CreateMaterial(desc)); - - //Draw plain XYZ axes using the current transform - static const vector3f vtsXYZ[] = { - vector3f(0.f, 0.f, 0.f), - vector3f(1.f, 0.f, 0.f), - vector3f(0.f, 0.f, 0.f), - vector3f(0.f, 1.f, 0.f), - vector3f(0.f, 0.f, 0.f), - vector3f(0.f, 0.f, 1.f), - }; - static const Color colors[] = { - Color::RED, - Color::RED, - Color::BLUE, - Color::BLUE, - Color::GREEN, - Color::GREEN, - }; - - for( int i=0 ; i<6 ; i++ ) { - vertices.Add( vtsXYZ[i], colors[i] ); - } - - //Create vtx & index buffers and copy data - VertexBufferDesc vbd; - vbd.attrib[0].semantic = ATTRIB_POSITION; - vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = ATTRIB_DIFFUSE; - vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = vertices.GetNumVerts(); - vbd.usage = BUFFER_USAGE_STATIC; - m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); - m_vertexBuffer->Populate(vertices); -} - -void Axes3D::Draw(Graphics::Renderer *r) -{ - PROFILE_SCOPED() - r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), LINE_SINGLE); -} - -static Axes3D *s_axes = nullptr; -Axes3D* GetAxes3DDrawable(Graphics::Renderer *r) { - PROFILE_SCOPED() - if( !s_axes ) { - s_axes = new Axes3D(r); - } - return s_axes; -} - -} - -} + namespace Drawables { + + Circle::Circle(Renderer *renderer, const float radius, const Color &c, RenderState *state) : + m_color(c) + { + PROFILE_SCOPED() + m_renderState = state; + VertexArray vertices(ATTRIB_POSITION); + for (float theta = 0; theta < 2 * float(M_PI); theta += 0.05f * float(M_PI)) { + vertices.Add(vector3f(radius * sin(theta), radius * cos(theta), 0)); + } + SetupVertexBuffer(vertices, renderer); + } + Circle::Circle(Renderer *renderer, const float radius, const float x, const float y, const float z, const Color &c, RenderState *state) : + m_color(c) + { + PROFILE_SCOPED() + m_renderState = state; + VertexArray vertices(ATTRIB_POSITION); + for (float theta = 0; theta < 2 * float(M_PI); theta += 0.05f * float(M_PI)) { + vertices.Add(vector3f(radius * sin(theta) + x, radius * cos(theta) + y, z)); + } + SetupVertexBuffer(vertices, renderer); + } + Circle::Circle(Renderer *renderer, const float radius, const vector3f ¢er, const Color &c, RenderState *state) : + m_color(c) + { + PROFILE_SCOPED() + m_renderState = state; + VertexArray vertices(ATTRIB_POSITION); + for (float theta = 0; theta < 2 * float(M_PI); theta += 0.05f * float(M_PI)) { + vertices.Add(vector3f(radius * sin(theta) + center.x, radius * cos(theta) + center.y, center.z)); + } + SetupVertexBuffer(vertices, renderer); + } + + void Circle::Draw(Renderer *renderer) + { + PROFILE_SCOPED() + m_material->diffuse = m_color; + renderer->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), PrimitiveType::LINE_LOOP); + } + + void Circle::SetupVertexBuffer(const Graphics::VertexArray &vertices, Graphics::Renderer *r) + { + PROFILE_SCOPED() + MaterialDescriptor desc; + m_material.Reset(r->CreateMaterial(desc)); + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = vertices.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vertices); + } + //------------------------------------------------------------ + + Disk::Disk(Graphics::Renderer *r, Graphics::RenderState *state, const Color &c, float rad) + { + PROFILE_SCOPED() + m_renderState = state; + + VertexArray vertices(ATTRIB_POSITION); + m_material.Reset(r->CreateMaterial(MaterialDescriptor())); + m_material->diffuse = c; + + vertices.Add(vector3f(0.f, 0.f, 0.f)); + for (int i = 72; i >= 0; i--) { + vertices.Add(vector3f( + 0.f + sinf(DEG2RAD(i * 5.f)) * rad, + 0.f + cosf(DEG2RAD(i * 5.f)) * rad, + 0.f)); + } + + SetupVertexBuffer(vertices, r); + } + + Disk::Disk(Graphics::Renderer *r, RefCountedPtr material, Graphics::RenderState *state, const int edges, const float rad) : + m_material(material) + { + PROFILE_SCOPED() + m_renderState = state; + + VertexArray vertices(ATTRIB_POSITION); + + vertices.Add(vector3f(0.f, 0.f, 0.f)); + const float edgeStep = 360.0f / float(edges); + for (int i = edges; i >= 0; i--) { + vertices.Add(vector3f( + 0.f + sinf(DEG2RAD(i * edgeStep)) * rad, + 0.f + cosf(DEG2RAD(i * edgeStep)) * rad, + 0.f)); + } + + SetupVertexBuffer(vertices, r); + } + + void Disk::Draw(Renderer *r) + { + PROFILE_SCOPED() + r->DrawBuffer(m_vertexBuffer.get(), m_renderState, m_material.Get(), TRIANGLE_FAN); + } + + void Disk::SetColor(const Color &c) + { + m_material->diffuse = c; + } + + void Disk::SetupVertexBuffer(const Graphics::VertexArray &vertices, Graphics::Renderer *r) + { + PROFILE_SCOPED() + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = vertices.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vertices); + } + //------------------------------------------------------------ + + Line3D::Line3D() : + m_refreshVertexBuffer(true), + m_width(2.0f), + m_va(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, 2)) + { + PROFILE_SCOPED() + assert(m_va.get()); + // XXX bug in Radeon drivers will cause crash in glLineWidth if width >= 3 + m_va->Add(vector3f(0.f), Color::BLANK); + m_va->Add(vector3f(0.f), Color::WHITE); + } + + Line3D::Line3D(const Line3D &b) : + Line3D() + { + PROFILE_SCOPED() + m_refreshVertexBuffer = (b.m_refreshVertexBuffer); + m_width = (b.m_width); + m_material = (b.m_material); + m_vertexBuffer = (b.m_vertexBuffer); + (*m_va.get()) = (*b.m_va.get()); + } + + void Line3D::SetStart(const vector3f &s) + { + PROFILE_SCOPED() + if (!m_va->position[0].ExactlyEqual(s)) { + m_va->Set(0, s); + Dirty(); + } + } + + void Line3D::SetEnd(const vector3f &e) + { + PROFILE_SCOPED() + if (!m_va->position[1].ExactlyEqual(e)) { + m_va->Set(1, e); + Dirty(); + } + } + + void Line3D::SetColor(const Color &c) + { + PROFILE_SCOPED() + if (!(m_va->diffuse[0] == c)) { + m_va->Set(0, m_va->position[0], c); + m_va->Set(1, m_va->position[1], c * 0.5); + Dirty(); + } + } + + void Line3D::Draw(Renderer *r, RenderState *rs) + { + PROFILE_SCOPED() + if (m_va->GetNumVerts() == 0) + return; + + if (!m_vertexBuffer.Valid()) { + CreateVertexBuffer(r, 2); + } + if (m_refreshVertexBuffer) { + assert(m_va.get()); + m_refreshVertexBuffer = false; + m_vertexBuffer->Populate(*m_va); + } + // XXX would be nicer to draw this as a textured triangle strip + // can't guarantee linewidth support + // glLineWidth(m_width); + r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::LINE_SINGLE); + // glLineWidth(1.f); + } + + void Line3D::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) + { + PROFILE_SCOPED() + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; + vbd.numVertices = size; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + assert(m_vertexBuffer.Valid()); + } + + void Line3D::Dirty() + { + m_refreshVertexBuffer = true; + } + //------------------------------------------------------------ + + Lines::Lines() : + m_refreshVertexBuffer(true), + m_va(new VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE)) + { + PROFILE_SCOPED() + // XXX bug in Radeon drivers will cause crash in glLineWidth if width >= 3 + } + + void Lines::SetData(const Uint32 vertCount, const vector3f *vertices, const Color &color) + { + PROFILE_SCOPED() + assert(vertices); + + // somethings changed so even if the number of verts is constant the data must be uploaded + m_refreshVertexBuffer = true; + + // if the number of vert mismatches then clear the current vertex buffer + if (m_vertexBuffer.Valid() && m_vertexBuffer->GetCapacity() < vertCount) { + // a new one will be created when it is drawn + m_vertexBuffer.Reset(); + } + + // populate the VertexArray + m_va->Clear(); + for (Uint32 i = 0; i < vertCount; i++) { + m_va->Add(vertices[i], color); + } + } + + void Lines::SetData(const Uint32 vertCount, const vector3f *vertices, const Color *colors) + { + PROFILE_SCOPED() + assert(vertices); + + // somethings changed so even if the number of verts is constant the data must be uploaded + m_refreshVertexBuffer = true; + + // if the number of vert mismatches then clear the current vertex buffer + if (m_vertexBuffer.Valid() && m_vertexBuffer->GetCapacity() < vertCount) { + // a new one will be created when it is drawn + m_vertexBuffer.Reset(); + } + + // populate the VertexArray + m_va->Clear(); + for (Uint32 i = 0; i < vertCount; i++) { + m_va->Add(vertices[i], colors[i]); + } + } + + void Lines::Draw(Renderer *r, RenderState *rs, const PrimitiveType pt) + { + PROFILE_SCOPED() + if (m_va->GetNumVerts() == 0) + return; + + if (!m_vertexBuffer.Valid()) { + CreateVertexBuffer(r, m_va->GetNumVerts() * 2); // ask for twice as many as we need to reduce buffer thrashing + } + if (m_refreshVertexBuffer) { + m_refreshVertexBuffer = false; + m_vertexBuffer->Populate(*m_va); + } + // XXX would be nicer to draw this as a textured triangle strip + // can't guarantee linewidth support + // glLineWidth(m_width); + r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), pt); + // glLineWidth(1.f); + } + + void Lines::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) + { + PROFILE_SCOPED() + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; + vbd.numVertices = size; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + } + + //------------------------------------------------------------ + PointSprites::PointSprites() : + m_refreshVertexBuffer(true) + { + } + + void PointSprites::SetData(const int count, const vector3f *positions, const Color *colours, const float *sizes, Graphics::Material *pMaterial) + { + PROFILE_SCOPED() + if (count < 1) + return; + + assert(positions); + + m_va.reset(new VertexArray(ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_DIFFUSE, count)); + + for (int i = 0; i < count; i++) { + vector3f vSize(sizes[i]); + m_va->Add(positions[i], colours[i], vSize); + } + + m_refreshVertexBuffer = true; + m_material.Reset(pMaterial); + } + + void PointSprites::Draw(Renderer *r, RenderState *rs) + { + PROFILE_SCOPED() + if (m_va->GetNumVerts() == 0) + return; + + if (!m_vertexBuffer.Valid() || !m_material.Valid()) { + CreateVertexBuffer(r, m_va->GetNumVerts()); + } + if (m_refreshVertexBuffer) { + m_refreshVertexBuffer = false; + m_vertexBuffer->Populate(*m_va); + } + r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::POINTS); + } + + void PointSprites::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) + { + PROFILE_SCOPED() + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[2].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + vbd.numVertices = size; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + } + + //------------------------------------------------------------ + Points::Points() : + m_refreshVertexBuffer(true) + { + PROFILE_SCOPED() + } + + void Points::SetData(Renderer *r, const int count, const vector3f *positions, const matrix4x4f &trans, const Color &color, const float size) + { + PROFILE_SCOPED() + if (count < 1) + return; + + assert(positions); + const unsigned int total = (count * 6); + + if (m_va.get() && m_va->GetNumVerts() == total) { + m_va->Clear(); + } else { + m_va.reset(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE, total)); + CreateVertexBuffer(r, total); + } + + matrix4x4f rot(trans); + rot.ClearToRotOnly(); + rot = rot.Inverse(); + + const float sz = 0.5f * size; + const vector3f rotv1 = rot * vector3f(sz, sz, 0.0f); + const vector3f rotv2 = rot * vector3f(sz, -sz, 0.0f); + const vector3f rotv3 = rot * vector3f(-sz, -sz, 0.0f); + const vector3f rotv4 = rot * vector3f(-sz, sz, 0.0f); + + //do two-triangle quads. Could also do indexed surfaces. + //PiGL renderer should use actual point sprites + //(see history of Render.cpp for point code remnants) + for (int i = 0; i < count; i++) { + const vector3f &pos = positions[i]; + + m_va->Add(pos + rotv4, color); //top left + m_va->Add(pos + rotv3, color); //bottom left + m_va->Add(pos + rotv1, color); //top right + + m_va->Add(pos + rotv1, color); //top right + m_va->Add(pos + rotv3, color); //bottom left + m_va->Add(pos + rotv2, color); //bottom right + } + + m_refreshVertexBuffer = true; + } + + void Points::SetData(Renderer *r, const int count, const vector3f *positions, const Color *color, const matrix4x4f &trans, const float size) + { + PROFILE_SCOPED() + if (count < 1) + return; + + assert(positions); + const unsigned int total = (count * 6); + + if (m_va.get() && m_va->GetNumVerts() == total) { + m_va->Clear(); + } else { + m_va.reset(new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE, total)); + CreateVertexBuffer(r, total); + } + + matrix4x4f rot(trans); + rot.ClearToRotOnly(); + rot = rot.Inverse(); + + const float sz = 0.5f * size; + const vector3f rotv1 = rot * vector3f(sz, sz, 0.0f); + const vector3f rotv2 = rot * vector3f(sz, -sz, 0.0f); + const vector3f rotv3 = rot * vector3f(-sz, -sz, 0.0f); + const vector3f rotv4 = rot * vector3f(-sz, sz, 0.0f); + + //do two-triangle quads. Could also do indexed surfaces. + //PiGL renderer should use actual point sprites + //(see history of Render.cpp for point code remnants) + for (int i = 0; i < count; i++) { + const vector3f &pos = positions[i]; + + m_va->Add(pos + rotv4, color[i]); //top left + m_va->Add(pos + rotv3, color[i]); //bottom left + m_va->Add(pos + rotv1, color[i]); //top right + + m_va->Add(pos + rotv1, color[i]); //top right + m_va->Add(pos + rotv3, color[i]); //bottom left + m_va->Add(pos + rotv2, color[i]); //bottom right + } + + m_refreshVertexBuffer = true; + } + + void Points::Draw(Renderer *r, RenderState *rs) + { + PROFILE_SCOPED() + if (m_va->GetNumVerts() == 0) + return; + + if (!m_vertexBuffer.Valid() || (m_va->GetNumVerts() != m_vertexBuffer->GetSize())) { + CreateVertexBuffer(r, m_va->GetNumVerts()); + } + if (m_refreshVertexBuffer) { + m_refreshVertexBuffer = false; + m_vertexBuffer->Populate(*m_va); + } + + r->DrawBuffer(m_vertexBuffer.Get(), rs, m_material.Get(), Graphics::TRIANGLES); + } + + void Points::CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size) + { + PROFILE_SCOPED() + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; + vbd.numVertices = size; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + } + //------------------------------------------------------------ + + static const float ICOSX = 0.525731112119133f; + static const float ICOSZ = 0.850650808352039f; + + static const vector3f icosahedron_vertices[12] = { + vector3f(-ICOSX, 0.0, ICOSZ), vector3f(ICOSX, 0.0, ICOSZ), vector3f(-ICOSX, 0.0, -ICOSZ), vector3f(ICOSX, 0.0, -ICOSZ), + vector3f(0.0, ICOSZ, ICOSX), vector3f(0.0, ICOSZ, -ICOSX), vector3f(0.0, -ICOSZ, ICOSX), vector3f(0.0, -ICOSZ, -ICOSX), + vector3f(ICOSZ, ICOSX, 0.0), vector3f(-ICOSZ, ICOSX, 0.0), vector3f(ICOSZ, -ICOSX, 0.0), vector3f(-ICOSZ, -ICOSX, 0.0) + }; + + static const int icosahedron_faces[20][3] = { + { 0, 4, 1 }, { 0, 9, 4 }, { 9, 5, 4 }, { 4, 5, 8 }, { 4, 8, 1 }, + { 8, 10, 1 }, { 8, 3, 10 }, { 5, 3, 8 }, { 5, 2, 3 }, { 2, 7, 3 }, + { 7, 10, 3 }, { 7, 6, 10 }, { 7, 11, 6 }, { 11, 0, 6 }, { 0, 1, 6 }, + { 6, 1, 10 }, { 9, 0, 11 }, { 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } + }; + + Sphere3D::Sphere3D(Renderer *renderer, RefCountedPtr mat, Graphics::RenderState *state, int subdivs, float scale, const Uint32 attribs) + { + PROFILE_SCOPED() + assert(attribs & ATTRIB_POSITION); + + m_material = mat; + m_renderState = state; + + subdivs = Clamp(subdivs, 0, 4); + scale = fabs(scale); + matrix4x4f trans = matrix4x4f::Identity(); + trans.Scale(scale, scale, scale); + + //reserve some data - ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0 + VertexArray vts(attribs, (subdivs * subdivs) * 20 * 3); + std::vector indices; + + //initial vertices + int vi[12]; + for (int i = 0; i < 12; i++) { + const vector3f &v = icosahedron_vertices[i]; + vi[i] = AddVertex(vts, trans * v, v); + } + + //subdivide + for (int i = 0; i < 20; i++) { + Subdivide(vts, indices, trans, icosahedron_vertices[icosahedron_faces[i][0]], + icosahedron_vertices[icosahedron_faces[i][1]], + icosahedron_vertices[icosahedron_faces[i][2]], + vi[icosahedron_faces[i][0]], + vi[icosahedron_faces[i][1]], + vi[icosahedron_faces[i][2]], + subdivs); + } + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + Uint32 attIdx = 0; + vbd.attrib[attIdx].semantic = ATTRIB_POSITION; + vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attIdx; + if (attribs & ATTRIB_NORMAL) { + vbd.attrib[attIdx].semantic = ATTRIB_NORMAL; + vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attIdx; + } + if (attribs & ATTRIB_UV0) { + vbd.attrib[attIdx].semantic = ATTRIB_UV0; + vbd.attrib[attIdx].format = ATTRIB_FORMAT_FLOAT2; + ++attIdx; + } + vbd.numVertices = vts.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.reset(renderer->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vts); + + m_indexBuffer.reset(renderer->CreateIndexBuffer(indices.size(), BUFFER_USAGE_STATIC)); + Uint32 *idxPtr = m_indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); + for (auto it : indices) { + *idxPtr = it; + idxPtr++; + } + m_indexBuffer->Unmap(); + } + + void Sphere3D::Draw(Renderer *r) + { + PROFILE_SCOPED() + r->DrawBufferIndexed(m_vertexBuffer.get(), m_indexBuffer.get(), m_renderState, m_material.Get()); + } + + int Sphere3D::AddVertex(VertexArray &vts, const vector3f &v, const vector3f &n) + { + PROFILE_SCOPED() + vts.position.push_back(v); + if (vts.HasAttrib(ATTRIB_NORMAL)) { + vts.normal.push_back(n); + } + if (vts.HasAttrib(ATTRIB_UV0)) { + //http://www.mvps.org/directx/articles/spheremap.htm + vts.uv0.push_back(vector2f(asinf(n.x) / M_PI + 0.5f, asinf(n.y) / M_PI + 0.5f)); + } + return vts.GetNumVerts() - 1; + } + + void Sphere3D::AddTriangle(std::vector &indices, int i1, int i2, int i3) + { + PROFILE_SCOPED() + indices.push_back(i1); + indices.push_back(i2); + indices.push_back(i3); + } + + void Sphere3D::Subdivide(VertexArray &vts, std::vector &indices, + const matrix4x4f &trans, const vector3f &v1, const vector3f &v2, const vector3f &v3, + const int i1, const int i2, const int i3, int depth) + { + PROFILE_SCOPED() + if (depth == 0) { + AddTriangle(indices, i1, i3, i2); + return; + } + + const vector3f v12 = (v1 + v2).Normalized(); + const vector3f v23 = (v2 + v3).Normalized(); + const vector3f v31 = (v3 + v1).Normalized(); + const int i12 = AddVertex(vts, trans * v12, v12); + const int i23 = AddVertex(vts, trans * v23, v23); + const int i31 = AddVertex(vts, trans * v31, v31); + Subdivide(vts, indices, trans, v1, v12, v31, i1, i12, i31, depth - 1); + Subdivide(vts, indices, trans, v2, v23, v12, i2, i23, i12, depth - 1); + Subdivide(vts, indices, trans, v3, v31, v23, i3, i31, i23, depth - 1); + Subdivide(vts, indices, trans, v12, v23, v31, i12, i23, i31, depth - 1); + } + //------------------------------------------------------------ + + TexturedQuad::TexturedQuad(Graphics::Renderer *r, const std::string &filename) + { + PROFILE_SCOPED() + + Graphics::TextureBuilder texbuilder = Graphics::TextureBuilder::UI(filename); + m_texture.Reset(texbuilder.GetOrCreateTexture(r, "ui")); + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthTest = false; + rsd.depthWrite = false; + m_renderState = r->CreateRenderState(rsd); + + VertexArray vertices(ATTRIB_POSITION | ATTRIB_UV0); + Graphics::MaterialDescriptor desc; + desc.effect = Graphics::EFFECT_DEFAULT; + desc.textures = 1; + desc.lighting = false; + desc.vertexColors = false; + m_material.Reset(r->CreateMaterial(desc)); + m_material->texture0 = m_texture.Get(); + + // these might need to be reversed + const vector2f texSize = m_texture->GetDescriptor().texSize; + const vector2f halfsz = 0.5f * m_texture->GetDescriptor().GetOriginalSize(); + + vertices.Add(vector3f(-halfsz.x, -halfsz.y, 0.0f), vector2f(0.0f, texSize.y)); + vertices.Add(vector3f(-halfsz.x, halfsz.y, 0.0f), vector2f(0.0f, 0.0f)); + vertices.Add(vector3f(halfsz.x, -halfsz.y, 0.0f), vector2f(texSize.x, texSize.y)); + vertices.Add(vector3f(halfsz.x, halfsz.y, 0.0f), vector2f(texSize.x, 0.0f)); + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = ATTRIB_UV0; + vbd.attrib[1].format = ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = vertices.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vertices); + } + + // a textured quad with reversed winding + TexturedQuad::TexturedQuad(Graphics::Renderer *r, Graphics::Texture *texture, const vector2f &pos, const vector2f &size, RenderState *state) : + m_texture(RefCountedPtr(texture)) + { + PROFILE_SCOPED() + assert(state); + m_renderState = state; + + VertexArray vertices(ATTRIB_POSITION | ATTRIB_UV0); + Graphics::MaterialDescriptor desc; + desc.textures = 1; + m_material.Reset(r->CreateMaterial(desc)); + m_material->texture0 = m_texture.Get(); + + // these might need to be reversed + const vector2f texPos = vector2f(0.0f); + const vector2f texSize = m_texture->GetDescriptor().texSize; + + vertices.Add(vector3f(pos.x, pos.y, 0.0f), vector2f(texPos.x, texPos.y + texSize.y)); + vertices.Add(vector3f(pos.x, pos.y + size.y, 0.0f), vector2f(texPos.x, texPos.y)); + vertices.Add(vector3f(pos.x + size.x, pos.y, 0.0f), vector2f(texPos.x + texSize.x, texPos.y + texSize.y)); + vertices.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f), vector2f(texPos.x + texSize.x, texPos.y)); + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = ATTRIB_UV0; + vbd.attrib[1].format = ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = vertices.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vertices); + } + + TexturedQuad::TexturedQuad(Graphics::Renderer *r, RefCountedPtr &material, const Graphics::VertexArray &va, RenderState *state) : + m_material(material) + { + PROFILE_SCOPED() + assert(state); + m_renderState = state; + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + + Uint32 attribIdx = 0; + assert(va.HasAttrib(ATTRIB_POSITION)); + vbd.attrib[attribIdx].semantic = ATTRIB_POSITION; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attribIdx; + + if (va.HasAttrib(ATTRIB_NORMAL)) { + vbd.attrib[attribIdx].semantic = ATTRIB_NORMAL; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attribIdx; + } + if (va.HasAttrib(ATTRIB_DIFFUSE)) { + vbd.attrib[attribIdx].semantic = ATTRIB_DIFFUSE; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_UBYTE4; + ++attribIdx; + } + if (va.HasAttrib(ATTRIB_UV0)) { + vbd.attrib[attribIdx].semantic = ATTRIB_UV0; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT2; + ++attribIdx; + } + if (va.HasAttrib(ATTRIB_TANGENT)) { + vbd.attrib[attribIdx].semantic = ATTRIB_TANGENT; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attribIdx; + } + + vbd.numVertices = va.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(va); + } + + void TexturedQuad::Draw(Graphics::Renderer *r) + { + PROFILE_SCOPED() + m_material->diffuse = Color::WHITE; + r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_STRIP); + } + + void TexturedQuad::Draw(Graphics::Renderer *r, const Color4ub &tint) + { + PROFILE_SCOPED() + m_material->diffuse = tint; + r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_STRIP); + } + + //------------------------------------------------------------ + Rect::Rect(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &c, RenderState *state, const bool bIsStatic /*= true*/) : + m_renderState(state) + { + PROFILE_SCOPED() + + using namespace Graphics; + VertexArray bgArr(ATTRIB_POSITION | ATTRIB_DIFFUSE, 4); + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + bgArr.Add(vector3f(pos.x, size.y, 0), c); + bgArr.Add(vector3f(size.x, size.y, 0), c); + bgArr.Add(vector3f(size.x, pos.y, 0), c); + bgArr.Add(vector3f(pos.x, pos.y, 0), c); + + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = ATTRIB_DIFFUSE; + vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; + vbd.numVertices = 4; + vbd.usage = bIsStatic ? BUFFER_USAGE_STATIC : BUFFER_USAGE_DYNAMIC; + + // VertexBuffer + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(bgArr); + } + + void Rect::Update(const vector2f &pos, const vector2f &size, const Color &c) + { + using namespace Graphics; + VertexArray bgArr(ATTRIB_POSITION | ATTRIB_DIFFUSE, 4); + + bgArr.Add(vector3f(pos.x, size.y, 0), c); + bgArr.Add(vector3f(size.x, size.y, 0), c); + bgArr.Add(vector3f(size.x, pos.y, 0), c); + bgArr.Add(vector3f(pos.x, pos.y, 0), c); + + m_vertexBuffer->Populate(bgArr); + } + + void Rect::Draw(Graphics::Renderer *r) + { + PROFILE_SCOPED() + r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_FAN); + } + + //------------------------------------------------------------ + RoundEdgedRect::RoundEdgedRect(Graphics::Renderer *r, const vector2f &size, const float rad, const Color &c, RenderState *state, const bool bIsStatic /*= true*/) : + m_renderState(state) + { + PROFILE_SCOPED() + + using namespace Graphics; + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = ATTRIB_DIFFUSE; + vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; + vbd.numVertices = 4 * (STEPS + 1); + vbd.usage = bIsStatic ? BUFFER_USAGE_STATIC : BUFFER_USAGE_DYNAMIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + + Update(size, rad, c); + } + + void RoundEdgedRect::Update(const vector2f &size, float rad, const Color &c) + { + Graphics::VertexArray vts(Graphics::ATTRIB_POSITION | ATTRIB_DIFFUSE); + + if (rad > 0.5f * std::min(size.x, size.y)) + rad = 0.5f * std::min(size.x, size.y); + + // top left + // bottom left + for (int i = 0; i <= STEPS; i++) { + float ang = M_PI * 0.5f * i / float(STEPS); + vts.Add(vector3f(rad - rad * cos(ang), (size.y - rad) + rad * sin(ang), 0.f), c); + } + // bottom right + for (int i = 0; i <= STEPS; i++) { + float ang = M_PI * 0.5 + M_PI * 0.5f * i / float(STEPS); + vts.Add(vector3f(size.x - rad - rad * cos(ang), (size.y - rad) + rad * sin(ang), 0.f), c); + } + // top right + for (int i = 0; i <= STEPS; i++) { + float ang = M_PI + M_PI * 0.5f * i / float(STEPS); + vts.Add(vector3f((size.x - rad) - rad * cos(ang), rad + rad * sin(ang), 0.f), c); + } + + // top right + for (int i = 0; i <= STEPS; i++) { + float ang = M_PI * 1.5 + M_PI * 0.5f * i / float(STEPS); + vts.Add(vector3f(rad - rad * cos(ang), rad + rad * sin(ang), 0.f), c); + } + + m_vertexBuffer->Populate(vts); + } + + void RoundEdgedRect::Draw(Graphics::Renderer *r) + { + PROFILE_SCOPED() + r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), TRIANGLE_FAN); + } + + //------------------------------------------------------------ + Axes3D::Axes3D(Graphics::Renderer *r, Graphics::RenderState *state) + { + PROFILE_SCOPED() + if (state) { + m_renderState = state; + } else { + Graphics::RenderStateDesc rsd; + m_renderState = r->CreateRenderState(rsd); + } + + VertexArray vertices(ATTRIB_POSITION | ATTRIB_DIFFUSE); + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(r->CreateMaterial(desc)); + + //Draw plain XYZ axes using the current transform + static const vector3f vtsXYZ[] = { + vector3f(0.f, 0.f, 0.f), + vector3f(1.f, 0.f, 0.f), + vector3f(0.f, 0.f, 0.f), + vector3f(0.f, 1.f, 0.f), + vector3f(0.f, 0.f, 0.f), + vector3f(0.f, 0.f, 1.f), + }; + static const Color colors[] = { + Color::RED, + Color::RED, + Color::BLUE, + Color::BLUE, + Color::GREEN, + Color::GREEN, + }; + + for (int i = 0; i < 6; i++) { + vertices.Add(vtsXYZ[i], colors[i]); + } + + //Create vtx & index buffers and copy data + VertexBufferDesc vbd; + vbd.attrib[0].semantic = ATTRIB_POSITION; + vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = ATTRIB_DIFFUSE; + vbd.attrib[1].format = ATTRIB_FORMAT_UBYTE4; + vbd.numVertices = vertices.GetNumVerts(); + vbd.usage = BUFFER_USAGE_STATIC; + m_vertexBuffer.Reset(r->CreateVertexBuffer(vbd)); + m_vertexBuffer->Populate(vertices); + } + + void Axes3D::Draw(Graphics::Renderer *r) + { + PROFILE_SCOPED() + r->DrawBuffer(m_vertexBuffer.Get(), m_renderState, m_material.Get(), LINE_SINGLE); + } + + static Axes3D *s_axes = nullptr; + Axes3D *GetAxes3DDrawable(Graphics::Renderer *r) + { + PROFILE_SCOPED() + if (!s_axes) { + s_axes = new Axes3D(r); + } + return s_axes; + } + + } // namespace Drawables + +} // namespace Graphics diff --git a/src/graphics/Drawables.h b/src/graphics/Drawables.h index c83f58a44..dcbff1d75 100644 --- a/src/graphics/Drawables.h +++ b/src/graphics/Drawables.h @@ -4,221 +4,229 @@ #ifndef _DRAWABLES_H #define _DRAWABLES_H -#include "libs.h" +#include "graphics/Material.h" +#include "graphics/RenderState.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "graphics/RenderState.h" #include "graphics/VertexBuffer.h" -#include "graphics/Material.h" +#include "libs.h" namespace Graphics { -namespace Drawables { + namespace Drawables { -// A thing that can draw itself using renderer -// (circles, disks, polylines etc) -//------------------------------------------------------------ + // A thing that can draw itself using renderer + // (circles, disks, polylines etc) + //------------------------------------------------------------ -class Circle { -public: - Circle(Renderer *renderer, const float radius, const Color &c, RenderState *state); - Circle(Renderer *renderer, const float radius, const float x, const float y, const float z, const Color &c, RenderState *state); - Circle(Renderer *renderer, const float radius, const vector3f ¢er, const Color &c, RenderState *state); - void Draw(Renderer *renderer); + class Circle { + public: + Circle(Renderer *renderer, const float radius, const Color &c, RenderState *state); + Circle(Renderer *renderer, const float radius, const float x, const float y, const float z, const Color &c, RenderState *state); + Circle(Renderer *renderer, const float radius, const vector3f ¢er, const Color &c, RenderState *state); + void Draw(Renderer *renderer); -private: - void SetupVertexBuffer(const Graphics::VertexArray&, Graphics::Renderer *); - RefCountedPtr m_vertexBuffer; - RefCountedPtr m_material; - Color m_color; - Graphics::RenderState *m_renderState; -}; -//------------------------------------------------------------ + private: + void SetupVertexBuffer(const Graphics::VertexArray &, Graphics::Renderer *); + RefCountedPtr m_vertexBuffer; + RefCountedPtr m_material; + Color m_color; + Graphics::RenderState *m_renderState; + }; + //------------------------------------------------------------ -// Two-dimensional filled circle -class Disk { -public: - Disk(Graphics::Renderer *r, Graphics::RenderState*, const Color &c, float radius); - Disk(Graphics::Renderer *r, RefCountedPtr, Graphics::RenderState*, const int edges=72, const float radius=1.0f); - void Draw(Graphics::Renderer *r); + // Two-dimensional filled circle + class Disk { + public: + Disk(Graphics::Renderer *r, Graphics::RenderState *, const Color &c, float radius); + Disk(Graphics::Renderer *r, RefCountedPtr, Graphics::RenderState *, const int edges = 72, const float radius = 1.0f); + void Draw(Graphics::Renderer *r); - void SetColor(const Color&); + void SetColor(const Color &); -private: - void SetupVertexBuffer(const Graphics::VertexArray&, Graphics::Renderer *); - std::unique_ptr m_vertexBuffer; - RefCountedPtr m_material; - Graphics::RenderState *m_renderState; -}; -//------------------------------------------------------------ + private: + void SetupVertexBuffer(const Graphics::VertexArray &, Graphics::Renderer *); + std::unique_ptr m_vertexBuffer; + RefCountedPtr m_material; + Graphics::RenderState *m_renderState; + }; + //------------------------------------------------------------ -// A three dimensional line between two points -class Line3D { -public: - Line3D(); - Line3D(const Line3D& b); // this needs an explicit copy constructor due to the std::unique_ptr below - ~Line3D() {} - void SetStart(const vector3f &); - void SetEnd(const vector3f &); - void SetColor(const Color &); - void Draw(Renderer*, RenderState*); -private: - void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); - void Dirty(); + // A three dimensional line between two points + class Line3D { + public: + Line3D(); + Line3D(const Line3D &b); // this needs an explicit copy constructor due to the std::unique_ptr below + ~Line3D() {} + void SetStart(const vector3f &); + void SetEnd(const vector3f &); + void SetColor(const Color &); + void Draw(Renderer *, RenderState *); - bool m_refreshVertexBuffer; - float m_width; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - std::unique_ptr m_va; -}; -//------------------------------------------------------------ + private: + void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); + void Dirty(); -// Three dimensional line segments between two points -class Lines { -public: - Lines(); - void SetData(const Uint32 vertCount, const vector3f *vertices, const Color &color); - void SetData(const Uint32 vertCount, const vector3f *vertices, const Color *colors); - void Draw(Renderer*, RenderState*, const PrimitiveType pt = Graphics::LINE_SINGLE); -private: - void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); + bool m_refreshVertexBuffer; + float m_width; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + std::unique_ptr m_va; + }; + //------------------------------------------------------------ - bool m_refreshVertexBuffer; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - std::unique_ptr m_va; -}; -//------------------------------------------------------------ + // Three dimensional line segments between two points + class Lines { + public: + Lines(); + void SetData(const Uint32 vertCount, const vector3f *vertices, const Color &color); + void SetData(const Uint32 vertCount, const vector3f *vertices, const Color *colors); + void Draw(Renderer *, RenderState *, const PrimitiveType pt = Graphics::LINE_SINGLE); -// Screen aligned quad / billboard / pointsprite -class PointSprites { -public: - PointSprites(); - void SetData(const int count, const vector3f *positions, const Color *colours, const float *sizes, Graphics::Material *pMaterial); - void Draw(Renderer*, RenderState*); -private: - void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); + private: + void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); - bool m_refreshVertexBuffer; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - std::unique_ptr m_va; -}; -//------------------------------------------------------------ + bool m_refreshVertexBuffer; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + std::unique_ptr m_va; + }; + //------------------------------------------------------------ -// Screen aligned quad / billboard / pointsprite -class Points { -public: - Points(); - void SetData(Renderer*, const int count, const vector3f *positions, const matrix4x4f &trans, const Color &color, const float size); - void SetData(Renderer*, const int count, const vector3f *positions, const Color *color, const matrix4x4f &trans, const float size); - void Draw(Renderer*, RenderState*); -private: - void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); + // Screen aligned quad / billboard / pointsprite + class PointSprites { + public: + PointSprites(); + void SetData(const int count, const vector3f *positions, const Color *colours, const float *sizes, Graphics::Material *pMaterial); + void Draw(Renderer *, RenderState *); - bool m_refreshVertexBuffer; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - std::unique_ptr m_va; -}; -//------------------------------------------------------------ + private: + void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); -// Three dimensional sphere (subdivided icosahedron) with normals -// and spherical texture coordinates. -class Sphere3D { -public: - //subdivisions must be 0-4 - Sphere3D(Renderer*, RefCountedPtr material, Graphics::RenderState*, int subdivisions=0, float scale=1.f, const Uint32 attribs=(ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0)); - void Draw(Renderer *r); + bool m_refreshVertexBuffer; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + std::unique_ptr m_va; + }; + //------------------------------------------------------------ - RefCountedPtr GetMaterial() const { return m_material; } + // Screen aligned quad / billboard / pointsprite + class Points { + public: + Points(); + void SetData(Renderer *, const int count, const vector3f *positions, const matrix4x4f &trans, const Color &color, const float size); + void SetData(Renderer *, const int count, const vector3f *positions, const Color *color, const matrix4x4f &trans, const float size); + void Draw(Renderer *, RenderState *); -private: - std::unique_ptr m_vertexBuffer; - std::unique_ptr m_indexBuffer; - RefCountedPtr m_material; - Graphics::RenderState *m_renderState; + private: + void CreateVertexBuffer(Graphics::Renderer *r, const Uint32 size); - //std::unique_ptr m_surface; - //add a new vertex, return the index - int AddVertex(VertexArray&, const vector3f &v, const vector3f &n); - //add three vertex indices to form a triangle - void AddTriangle(std::vector&, int i1, int i2, int i3); - void Subdivide(VertexArray&, std::vector&, - const matrix4x4f &trans, const vector3f &v1, const vector3f &v2, const vector3f &v3, - int i1, int i2, int i3, int depth); -}; -//------------------------------------------------------------ + bool m_refreshVertexBuffer; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + std::unique_ptr m_va; + }; + //------------------------------------------------------------ -// a textured quad with reversed winding -class TexturedQuad { -public: - // Simple constructor to build a textured quad from an image. - // Note: this is intended for UI icons and similar things, and it builds the - // texture with that in mind (e.g., no texture compression because compression - // tends to create visible artefacts when used on UI-style textures that have - // edges/lines, etc) - // XXX: This is totally the wrong place for this helper function. - TexturedQuad(Graphics::Renderer *r, const std::string &filename); + // Three dimensional sphere (subdivided icosahedron) with normals + // and spherical texture coordinates. + class Sphere3D { + public: + //subdivisions must be 0-4 + Sphere3D(Renderer *, RefCountedPtr material, Graphics::RenderState *, int subdivisions = 0, float scale = 1.f, const Uint32 attribs = (ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0)); + void Draw(Renderer *r); - // Build a textured quad to display an arbitrary texture. - TexturedQuad(Graphics::Renderer *r, Graphics::Texture *texture, const vector2f &pos, const vector2f &size, RenderState *state); - TexturedQuad(Graphics::Renderer *r, RefCountedPtr &material, const Graphics::VertexArray &va, RenderState *state); + RefCountedPtr GetMaterial() const { return m_material; } - void Draw(Graphics::Renderer *r); - void Draw(Graphics::Renderer *r, const Color4ub &tint); - const Graphics::Texture* GetTexture() const { return m_texture.Get(); } -private: - RefCountedPtr m_texture; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - Graphics::RenderState *m_renderState; -}; -//------------------------------------------------------------ + private: + std::unique_ptr m_vertexBuffer; + std::unique_ptr m_indexBuffer; + RefCountedPtr m_material; + Graphics::RenderState *m_renderState; -// a coloured rectangle -class Rect { -public: - Rect(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &c, RenderState *state, const bool bIsStatic = true); - void Update(const vector2f &pos, const vector2f &size, const Color &c); - void Draw(Graphics::Renderer *r); -private: - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - Graphics::RenderState *m_renderState; -}; -//------------------------------------------------------------ + //std::unique_ptr m_surface; + //add a new vertex, return the index + int AddVertex(VertexArray &, const vector3f &v, const vector3f &n); + //add three vertex indices to form a triangle + void AddTriangle(std::vector &, int i1, int i2, int i3); + void Subdivide(VertexArray &, std::vector &, + const matrix4x4f &trans, const vector3f &v1, const vector3f &v2, const vector3f &v3, + int i1, int i2, int i3, int depth); + }; + //------------------------------------------------------------ -// a coloured rectangle -class RoundEdgedRect { -public: - RoundEdgedRect(Graphics::Renderer *r, const vector2f &size, const float rad, const Color &c, RenderState *state, const bool bIsStatic = true); - void Update(const vector2f &size, float rad, const Color &c); - void Draw(Graphics::Renderer *r); -private: - static const int STEPS = 6; - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - Graphics::RenderState *m_renderState; -}; -//------------------------------------------------------------ + // a textured quad with reversed winding + class TexturedQuad { + public: + // Simple constructor to build a textured quad from an image. + // Note: this is intended for UI icons and similar things, and it builds the + // texture with that in mind (e.g., no texture compression because compression + // tends to create visible artefacts when used on UI-style textures that have + // edges/lines, etc) + // XXX: This is totally the wrong place for this helper function. + TexturedQuad(Graphics::Renderer *r, const std::string &filename); -//industry-standard red/green/blue XYZ axis indicator -class Axes3D { -public: - Axes3D(Graphics::Renderer *r, Graphics::RenderState *state = nullptr); - void Draw(Graphics::Renderer *r); -private: - RefCountedPtr m_material; - RefCountedPtr m_vertexBuffer; - Graphics::RenderState *m_renderState; -}; + // Build a textured quad to display an arbitrary texture. + TexturedQuad(Graphics::Renderer *r, Graphics::Texture *texture, const vector2f &pos, const vector2f &size, RenderState *state); + TexturedQuad(Graphics::Renderer *r, RefCountedPtr &material, const Graphics::VertexArray &va, RenderState *state); -Axes3D* GetAxes3DDrawable(Graphics::Renderer *r); + void Draw(Graphics::Renderer *r); + void Draw(Graphics::Renderer *r, const Color4ub &tint); + const Graphics::Texture *GetTexture() const { return m_texture.Get(); } -} + private: + RefCountedPtr m_texture; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + Graphics::RenderState *m_renderState; + }; + //------------------------------------------------------------ -} + // a coloured rectangle + class Rect { + public: + Rect(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &c, RenderState *state, const bool bIsStatic = true); + void Update(const vector2f &pos, const vector2f &size, const Color &c); + void Draw(Graphics::Renderer *r); + + private: + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + Graphics::RenderState *m_renderState; + }; + //------------------------------------------------------------ + + // a coloured rectangle + class RoundEdgedRect { + public: + RoundEdgedRect(Graphics::Renderer *r, const vector2f &size, const float rad, const Color &c, RenderState *state, const bool bIsStatic = true); + void Update(const vector2f &size, float rad, const Color &c); + void Draw(Graphics::Renderer *r); + + private: + static const int STEPS = 6; + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + Graphics::RenderState *m_renderState; + }; + //------------------------------------------------------------ + + //industry-standard red/green/blue XYZ axis indicator + class Axes3D { + public: + Axes3D(Graphics::Renderer *r, Graphics::RenderState *state = nullptr); + void Draw(Graphics::Renderer *r); + + private: + RefCountedPtr m_material; + RefCountedPtr m_vertexBuffer; + Graphics::RenderState *m_renderState; + }; + + Axes3D *GetAxes3DDrawable(Graphics::Renderer *r); + + } // namespace Drawables + +} // namespace Graphics #endif diff --git a/src/graphics/Frustum.cpp b/src/graphics/Frustum.cpp index eb45f7c99..11aac82a7 100644 --- a/src/graphics/Frustum.cpp +++ b/src/graphics/Frustum.cpp @@ -6,138 +6,142 @@ namespace Graphics { -// min/max FOV in degrees -static const float FOV_MAX = 170.0f; -static const float FOV_MIN = 20.0f; + // min/max FOV in degrees + static const float FOV_MAX = 170.0f; + static const float FOV_MIN = 20.0f; -// step for translating to frustum space -static const double TRANSLATE_STEP = 0.25; + // step for translating to frustum space + static const double TRANSLATE_STEP = 0.25; -Frustum::Frustum() {} + Frustum::Frustum() {} -Frustum::Frustum(float width, float height, float fovAng, float znear, float zfar) -{ - //http://www.opengl.org/resources/faq/technical/transformations.htm - const float fov = tan(DEG2RAD(Clamp(fovAng, FOV_MIN, FOV_MAX) / 2.0f)); + Frustum::Frustum(float width, float height, float fovAng, float znear, float zfar) + { + //http://www.opengl.org/resources/faq/technical/transformations.htm + const float fov = tan(DEG2RAD(Clamp(fovAng, FOV_MIN, FOV_MAX) / 2.0f)); - const float aspect = width/height; - const float top = znear * fov; - const float bottom = -top; - const float left = bottom * aspect; - const float right = top * aspect; + const float aspect = width / height; + const float top = znear * fov; + const float bottom = -top; + const float left = bottom * aspect; + const float right = top * aspect; - m_projMatrix = matrix4x4d::FrustumMatrix(left, right, bottom, top, znear, zfar); - m_modelMatrix = matrix4x4d::Identity(); - InitFromMatrix(m_projMatrix); + m_projMatrix = matrix4x4d::FrustumMatrix(left, right, bottom, top, znear, zfar); + m_modelMatrix = matrix4x4d::Identity(); + InitFromMatrix(m_projMatrix); - m_translateThresholdSqr = zfar*zfar*TRANSLATE_STEP; -} - -Frustum::Frustum(const matrix4x4d &modelview, const matrix4x4d &projection) : m_projMatrix(projection), m_modelMatrix(modelview) -{ - const matrix4x4d m = m_projMatrix * m_modelMatrix; - InitFromMatrix(m); -} - -void Frustum::InitFromMatrix(const matrix4x4d &m) -{ - // Left clipping plane - m_planes[0].a = m[3] + m[0]; - m_planes[0].b = m[7] + m[4]; - m_planes[0].c = m[11] + m[8]; - m_planes[0].d = m[15] + m[12]; - // Right clipping plane - m_planes[1].a = m[3] - m[0]; - m_planes[1].b = m[7] - m[4]; - m_planes[1].c = m[11] - m[8]; - m_planes[1].d = m[15] - m[12]; - // Top clipping plane - m_planes[2].a = m[3] - m[1]; - m_planes[2].b = m[7] - m[5]; - m_planes[2].c = m[11] - m[9]; - m_planes[2].d = m[15] - m[13]; - // Bottom clipping plane - m_planes[3].a = m[3] + m[1]; - m_planes[3].b = m[7] + m[5]; - m_planes[3].c = m[11] + m[9]; - m_planes[3].d = m[15] + m[13]; - // Near clipping plane - m_planes[4].a = m[3] + m[2]; - m_planes[4].b = m[7] + m[6]; - m_planes[4].c = m[11] + m[10]; - m_planes[4].d = m[15] + m[14]; - // Far clipping plane - m_planes[5].a = m[3] + m[2]; - m_planes[5].b = m[7] + m[6]; - m_planes[5].c = m[11] + m[10]; - m_planes[5].d = m[15] + m[14]; - - // Normalize the fuckers - for (int i=0; i<6; i++) { - double invlen = 1.0 / sqrt(m_planes[i].a*m_planes[i].a + m_planes[i].b*m_planes[i].b + m_planes[i].c*m_planes[i].c); - m_planes[i].a *= invlen; - m_planes[i].b *= invlen; - m_planes[i].c *= invlen; - m_planes[i].d *= invlen; + m_translateThresholdSqr = zfar * zfar * TRANSLATE_STEP; } -} -bool Frustum::TestPoint(const vector3d &p, double radius) const -{ - for (int i=0; i<6; i++) - if (m_planes[i].DistanceToPoint(p)+radius < 0) - return false; - return true; -} - -bool Frustum::TestPointInfinite(const vector3d &p, double radius) const -{ - PROFILE_SCOPED() - // check all planes except far plane - for (int i=0; i<5; i++) - if (m_planes[i].DistanceToPoint(p)+radius < 0) - return false; - return true; -} - -bool Frustum::ProjectPoint(const vector3d &in, vector3d &out) const -{ - // see the OpenGL documentation - // or http://www.songho.ca/opengl/gl_transform.html - // or http://cgit.freedesktop.org/mesa/glu/tree/src/libutil/project.c (gluProject implementation from Mesa) - - const double * const M = m_modelMatrix.Data(); - const double * const P = m_projMatrix.Data(); - - const double vcam[4] = { // camera space - in.x*M[0] + in.y*M[4] + in.z*M[ 8] + M[12], - in.x*M[1] + in.y*M[5] + in.z*M[ 9] + M[13], - in.x*M[2] + in.y*M[6] + in.z*M[10] + M[14], - in.x*M[3] + in.y*M[7] + in.z*M[11] + M[15] - }; - const double vclip[4] = { // clip space - vcam[0]*P[0] + vcam[1]*P[4] + vcam[2]*P[ 8] + vcam[3]*P[12], - vcam[0]*P[1] + vcam[1]*P[5] + vcam[2]*P[ 9] + vcam[3]*P[13], - vcam[0]*P[2] + vcam[1]*P[6] + vcam[2]*P[10] + vcam[3]*P[14], - vcam[0]*P[3] + vcam[1]*P[7] + vcam[2]*P[11] + vcam[3]*P[15] - }; - - if (is_zero_exact(vclip[3])) { return false; } - - const double w = vclip[3]; - out.x = (vclip[0] / w) * 0.5 + 0.5; - out.y = (vclip[1] / w) * 0.5 + 0.5; - out.z = (vclip[2] / w) * 0.5 + 0.5; - - return true; -} - -void Frustum::TranslatePoint(const vector3d &in, vector3d &out) const -{ - out = in; - while (out.LengthSqr() > m_translateThresholdSqr) { - out *= TRANSLATE_STEP; + Frustum::Frustum(const matrix4x4d &modelview, const matrix4x4d &projection) : + m_projMatrix(projection), + m_modelMatrix(modelview) + { + const matrix4x4d m = m_projMatrix * m_modelMatrix; + InitFromMatrix(m); } -} -} + void Frustum::InitFromMatrix(const matrix4x4d &m) + { + // Left clipping plane + m_planes[0].a = m[3] + m[0]; + m_planes[0].b = m[7] + m[4]; + m_planes[0].c = m[11] + m[8]; + m_planes[0].d = m[15] + m[12]; + // Right clipping plane + m_planes[1].a = m[3] - m[0]; + m_planes[1].b = m[7] - m[4]; + m_planes[1].c = m[11] - m[8]; + m_planes[1].d = m[15] - m[12]; + // Top clipping plane + m_planes[2].a = m[3] - m[1]; + m_planes[2].b = m[7] - m[5]; + m_planes[2].c = m[11] - m[9]; + m_planes[2].d = m[15] - m[13]; + // Bottom clipping plane + m_planes[3].a = m[3] + m[1]; + m_planes[3].b = m[7] + m[5]; + m_planes[3].c = m[11] + m[9]; + m_planes[3].d = m[15] + m[13]; + // Near clipping plane + m_planes[4].a = m[3] + m[2]; + m_planes[4].b = m[7] + m[6]; + m_planes[4].c = m[11] + m[10]; + m_planes[4].d = m[15] + m[14]; + // Far clipping plane + m_planes[5].a = m[3] + m[2]; + m_planes[5].b = m[7] + m[6]; + m_planes[5].c = m[11] + m[10]; + m_planes[5].d = m[15] + m[14]; + + // Normalize the fuckers + for (int i = 0; i < 6; i++) { + double invlen = 1.0 / sqrt(m_planes[i].a * m_planes[i].a + m_planes[i].b * m_planes[i].b + m_planes[i].c * m_planes[i].c); + m_planes[i].a *= invlen; + m_planes[i].b *= invlen; + m_planes[i].c *= invlen; + m_planes[i].d *= invlen; + } + } + + bool Frustum::TestPoint(const vector3d &p, double radius) const + { + for (int i = 0; i < 6; i++) + if (m_planes[i].DistanceToPoint(p) + radius < 0) + return false; + return true; + } + + bool Frustum::TestPointInfinite(const vector3d &p, double radius) const + { + PROFILE_SCOPED() + // check all planes except far plane + for (int i = 0; i < 5; i++) + if (m_planes[i].DistanceToPoint(p) + radius < 0) + return false; + return true; + } + + bool Frustum::ProjectPoint(const vector3d &in, vector3d &out) const + { + // see the OpenGL documentation + // or http://www.songho.ca/opengl/gl_transform.html + // or http://cgit.freedesktop.org/mesa/glu/tree/src/libutil/project.c (gluProject implementation from Mesa) + + const double *const M = m_modelMatrix.Data(); + const double *const P = m_projMatrix.Data(); + + const double vcam[4] = { // camera space + in.x * M[0] + in.y * M[4] + in.z * M[8] + M[12], + in.x * M[1] + in.y * M[5] + in.z * M[9] + M[13], + in.x * M[2] + in.y * M[6] + in.z * M[10] + M[14], + in.x * M[3] + in.y * M[7] + in.z * M[11] + M[15] + }; + const double vclip[4] = { // clip space + vcam[0] * P[0] + vcam[1] * P[4] + vcam[2] * P[8] + vcam[3] * P[12], + vcam[0] * P[1] + vcam[1] * P[5] + vcam[2] * P[9] + vcam[3] * P[13], + vcam[0] * P[2] + vcam[1] * P[6] + vcam[2] * P[10] + vcam[3] * P[14], + vcam[0] * P[3] + vcam[1] * P[7] + vcam[2] * P[11] + vcam[3] * P[15] + }; + + if (is_zero_exact(vclip[3])) { + return false; + } + + const double w = vclip[3]; + out.x = (vclip[0] / w) * 0.5 + 0.5; + out.y = (vclip[1] / w) * 0.5 + 0.5; + out.z = (vclip[2] / w) * 0.5 + 0.5; + + return true; + } + + void Frustum::TranslatePoint(const vector3d &in, vector3d &out) const + { + out = in; + while (out.LengthSqr() > m_translateThresholdSqr) { + out *= TRANSLATE_STEP; + } + } + +} // namespace Graphics diff --git a/src/graphics/Frustum.h b/src/graphics/Frustum.h index 16d74acda..4cc0e11df 100644 --- a/src/graphics/Frustum.h +++ b/src/graphics/Frustum.h @@ -4,46 +4,46 @@ #ifndef _FRUSTUM_H #define _FRUSTUM_H +#include "Plane.h" #include "libs.h" #include "vector3.h" -#include "Plane.h" namespace Graphics { -// Frustum can be used for projecting points (3D to 2D) and testing -// if a point lies inside the visible area -// Its' internal projection matrix should, but does not have to, match -// the one used for rendering -class Frustum { -public: - // create for specified values - Frustum(float width, float height, float fovAng, float nearClip, float farClip); - Frustum(const matrix4x4d &modelview, const matrix4x4d &projection); + // Frustum can be used for projecting points (3D to 2D) and testing + // if a point lies inside the visible area + // Its' internal projection matrix should, but does not have to, match + // the one used for rendering + class Frustum { + public: + // create for specified values + Frustum(float width, float height, float fovAng, float nearClip, float farClip); + Frustum(const matrix4x4d &modelview, const matrix4x4d &projection); - // test if point (sphere) is in the frustum - bool TestPoint(const vector3d &p, double radius) const; - // test if point (sphere) is in the frustum, ignoring the far plane - bool TestPointInfinite(const vector3d &p, double radius) const; + // test if point (sphere) is in the frustum + bool TestPoint(const vector3d &p, double radius) const; + // test if point (sphere) is in the frustum, ignoring the far plane + bool TestPointInfinite(const vector3d &p, double radius) const; - // project a point onto the near plane (typically the screen) - bool ProjectPoint(const vector3d &in, vector3d &out) const; + // project a point onto the near plane (typically the screen) + bool ProjectPoint(const vector3d &in, vector3d &out) const; - // translate the given point outside the frustum to a point inside - // returns scale factor to make object at that point appear correctly - void TranslatePoint(const vector3d &in, vector3d &out) const; + // translate the given point outside the frustum to a point inside + // returns scale factor to make object at that point appear correctly + void TranslatePoint(const vector3d &in, vector3d &out) const; -private: - // create from current gl state - Frustum(); + private: + // create from current gl state + Frustum(); - void InitFromMatrix(const matrix4x4d &m); + void InitFromMatrix(const matrix4x4d &m); - matrix4x4d m_projMatrix; - matrix4x4d m_modelMatrix; - SPlane m_planes[6]; - double m_translateThresholdSqr; -}; + matrix4x4d m_projMatrix; + matrix4x4d m_modelMatrix; + SPlane m_planes[6]; + double m_translateThresholdSqr; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index e4958b0f3..1e95cbd9d 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -4,162 +4,160 @@ #include "Graphics.h" #include "FileSystem.h" #include "Material.h" -#include "Renderer.h" #include "OS.h" +#include "Renderer.h" #include "StringF.h" -#include #include +#include namespace Graphics { -const char* RendererNameFromType(const RendererType rType) { - static const char* s_rendererTypeNames [MAX_RENDERER_TYPE] { - "Dummy", - "Opengl 3.x" - }; - return s_rendererTypeNames[rType]; -} - -static RendererCreateFunc rendererCreateFunc[MAX_RENDERER_TYPE] = {}; - -void RegisterRenderer(RendererType type, RendererCreateFunc fn) { - assert(type < MAX_RENDERER_TYPE); - assert(fn); - rendererCreateFunc[type] = fn; -} - -static bool initted = false; -Material *vtxColorMaterial; -static int width, height; -static float g_fov = 85.f; -static float g_fovFactor = 1.f; - -int GetScreenWidth() -{ - return width; -} - -int GetScreenHeight() -{ - return height; -} - -float GetFov() -{ - return g_fov; -} - -void SetFov(float fov) -{ - g_fov = fov; - g_fovFactor = 2 * tan(DEG2RAD(g_fov) / 2.f); -} - -float GetFovFactor() -{ - return g_fovFactor; -} - -Renderer* Init(Settings vs) -{ - assert(!initted); - if (initted) return 0; - - // no mode set, find an ok one - if ((vs.width <= 0) || (vs.height <= 0)) { - const std::vector modes = GetAvailableVideoModes(); - assert(!modes.empty()); - - vs.width = modes.front().width; - vs.height = modes.front().height; - } - - // We deliberately ignore the value from GL_NUM_COMPRESSED_TEXTURE_FORMATS, because some drivers - // choose not to list any formats (despite supporting texture compression). See issue #3132. - // This is (probably) allowed by the spec, which states that only formats which are "suitable - // for general-purpose usage" should be enumerated. - - assert(vs.rendererType < MAX_RENDERER_TYPE); - assert(rendererCreateFunc[vs.rendererType]); - Renderer *renderer = rendererCreateFunc[vs.rendererType](vs); - if(renderer==nullptr) { - Error("Failed to set video mode: %s", SDL_GetError()); - return nullptr; - } - - if (vs.rendererType == Graphics::RENDERER_DUMMY) { - width = vs.width; - height = vs.height; - } else { - width = renderer->GetWindowWidth(); - height = renderer->GetWindowHeight(); - } - - Output("Initialized %s\n", renderer->GetName()); - + const char *RendererNameFromType(const RendererType rType) { - std::ostringstream buf; - renderer->WriteRendererInfo(buf); - - FILE *f = FileSystem::userFiles.OpenWriteStream("opengl.txt", FileSystem::FileSourceFS::WRITE_TEXT); - if (f) - { - const std::string &s = buf.str(); - fwrite(s.c_str(), 1, s.size(), f); - fclose(f); - } - else - { - Output("Could not open 'opengl.txt'\n"); - } + static const char *s_rendererTypeNames[MAX_RENDERER_TYPE]{ + "Dummy", + "Opengl 3.x" + }; + return s_rendererTypeNames[rType]; } - initted = true; + static RendererCreateFunc rendererCreateFunc[MAX_RENDERER_TYPE] = {}; - MaterialDescriptor desc; - desc.effect = EFFECT_VTXCOLOR; - desc.vertexColors = true; - vtxColorMaterial = renderer->CreateMaterial(desc); - vtxColorMaterial->IncRefCount(); - - return renderer; -} - -void Uninit() -{ - delete vtxColorMaterial; -} - -static bool operator==(const VideoMode &a, const VideoMode &b) { - return a.width==b.width && a.height==b.height; -} - -std::vector GetAvailableVideoModes() -{ - std::vector modes; - - const int num_displays = SDL_GetNumVideoDisplays(); - for(int display_index = 0; display_index < num_displays; display_index++) + void RegisterRenderer(RendererType type, RendererCreateFunc fn) { - const int num_modes = SDL_GetNumDisplayModes(display_index); + assert(type < MAX_RENDERER_TYPE); + assert(fn); + rendererCreateFunc[type] = fn; + } - SDL_Rect display_bounds; - SDL_GetDisplayBounds(display_index, &display_bounds); + static bool initted = false; + Material *vtxColorMaterial; + static int width, height; + static float g_fov = 85.f; + static float g_fovFactor = 1.f; + + int GetScreenWidth() + { + return width; + } + + int GetScreenHeight() + { + return height; + } + + float GetFov() + { + return g_fov; + } + + void SetFov(float fov) + { + g_fov = fov; + g_fovFactor = 2 * tan(DEG2RAD(g_fov) / 2.f); + } + + float GetFovFactor() + { + return g_fovFactor; + } + + Renderer *Init(Settings vs) + { + assert(!initted); + if (initted) return 0; + + // no mode set, find an ok one + if ((vs.width <= 0) || (vs.height <= 0)) { + const std::vector modes = GetAvailableVideoModes(); + assert(!modes.empty()); + + vs.width = modes.front().width; + vs.height = modes.front().height; + } + + // We deliberately ignore the value from GL_NUM_COMPRESSED_TEXTURE_FORMATS, because some drivers + // choose not to list any formats (despite supporting texture compression). See issue #3132. + // This is (probably) allowed by the spec, which states that only formats which are "suitable + // for general-purpose usage" should be enumerated. + + assert(vs.rendererType < MAX_RENDERER_TYPE); + assert(rendererCreateFunc[vs.rendererType]); + Renderer *renderer = rendererCreateFunc[vs.rendererType](vs); + if (renderer == nullptr) { + Error("Failed to set video mode: %s", SDL_GetError()); + return nullptr; + } + + if (vs.rendererType == Graphics::RENDERER_DUMMY) { + width = vs.width; + height = vs.height; + } else { + width = renderer->GetWindowWidth(); + height = renderer->GetWindowHeight(); + } + + Output("Initialized %s\n", renderer->GetName()); - for (int display_mode = 0; display_mode < num_modes; display_mode++) { - SDL_DisplayMode mode; - SDL_GetDisplayMode(display_index, display_mode, &mode); - // insert only if unique resolution - if( modes.end()==std::find(modes.begin(), modes.end(), VideoMode(mode.w, mode.h)) ) { - modes.push_back(VideoMode(mode.w, mode.h)); + std::ostringstream buf; + renderer->WriteRendererInfo(buf); + + FILE *f = FileSystem::userFiles.OpenWriteStream("opengl.txt", FileSystem::FileSourceFS::WRITE_TEXT); + if (f) { + const std::string &s = buf.str(); + fwrite(s.c_str(), 1, s.size(), f); + fclose(f); + } else { + Output("Could not open 'opengl.txt'\n"); } } - } - if( num_displays==0 ) { - modes.push_back(VideoMode(800, 600)); - } - return modes; -} -} + initted = true; + + MaterialDescriptor desc; + desc.effect = EFFECT_VTXCOLOR; + desc.vertexColors = true; + vtxColorMaterial = renderer->CreateMaterial(desc); + vtxColorMaterial->IncRefCount(); + + return renderer; + } + + void Uninit() + { + delete vtxColorMaterial; + } + + static bool operator==(const VideoMode &a, const VideoMode &b) + { + return a.width == b.width && a.height == b.height; + } + + std::vector GetAvailableVideoModes() + { + std::vector modes; + + const int num_displays = SDL_GetNumVideoDisplays(); + for (int display_index = 0; display_index < num_displays; display_index++) { + const int num_modes = SDL_GetNumDisplayModes(display_index); + + SDL_Rect display_bounds; + SDL_GetDisplayBounds(display_index, &display_bounds); + + for (int display_mode = 0; display_mode < num_modes; display_mode++) { + SDL_DisplayMode mode; + SDL_GetDisplayMode(display_index, display_mode, &mode); + // insert only if unique resolution + if (modes.end() == std::find(modes.begin(), modes.end(), VideoMode(mode.w, mode.h))) { + modes.push_back(VideoMode(mode.w, mode.h)); + } + } + } + if (num_displays == 0) { + modes.push_back(VideoMode(800, 600)); + } + return modes; + } + +} // namespace Graphics diff --git a/src/graphics/Graphics.h b/src/graphics/Graphics.h index ac85d4bf0..7785221e8 100644 --- a/src/graphics/Graphics.h +++ b/src/graphics/Graphics.h @@ -4,8 +4,8 @@ #ifndef _GRAPHICS_H #define _GRAPHICS_H -#include "libs.h" #include "RenderTarget.h" +#include "libs.h" /* * bunch of reused 3d drawy routines. @@ -19,7 +19,7 @@ namespace Graphics { MAX_RENDERER_TYPE }; - const char* RendererNameFromType(const RendererType rType); + const char *RendererNameFromType(const RendererType rType); // requested video settings struct Settings { @@ -40,13 +40,14 @@ namespace Graphics { class Renderer; - typedef Renderer* (*RendererCreateFunc)(const Settings &vs); + typedef Renderer *(*RendererCreateFunc)(const Settings &vs); void RegisterRenderer(RendererType type, RendererCreateFunc fn); //for querying available modes struct VideoMode { - VideoMode(int w, int h) - : width(w), height(h) { } + VideoMode(int w, int h) : + width(w), + height(h) {} int width; int height; @@ -63,7 +64,7 @@ namespace Graphics { float GetFovFactor(); //cached 2*tan(fov/2) for LOD // does SDL video init, constructs appropriate Renderer - Renderer* Init(Settings); + Renderer *Init(Settings); void Uninit(); std::vector GetAvailableVideoModes(); @@ -74,6 +75,6 @@ namespace Graphics { Uint32 stride; Uint32 bpp; }; -} +} // namespace Graphics #endif /* _RENDER_H */ diff --git a/src/graphics/Light.cpp b/src/graphics/Light.cpp index 7f8c54ece..594b21af7 100644 --- a/src/graphics/Light.cpp +++ b/src/graphics/Light.cpp @@ -5,22 +5,20 @@ namespace Graphics { -Light::Light() : - m_type(LIGHT_POINT), - m_position(0.f), - m_diffuse(Color::WHITE), - m_specular(Color::BLANK) -{ + Light::Light() : + m_type(LIGHT_POINT), + m_position(0.f), + m_diffuse(Color::WHITE), + m_specular(Color::BLANK) + { + } -} + Light::Light(LightType t, const vector3f &p, const Color &d, const Color &s) : + m_type(t), + m_position(p), + m_diffuse(d), + m_specular(s) + { + } -Light::Light(LightType t, const vector3f &p, const Color &d, const Color &s) : - m_type(t), - m_position(p), - m_diffuse(d), - m_specular(s) -{ - -} - -} +} // namespace Graphics diff --git a/src/graphics/Light.h b/src/graphics/Light.h index 5960939e3..70d3055ef 100644 --- a/src/graphics/Light.h +++ b/src/graphics/Light.h @@ -9,36 +9,35 @@ namespace Graphics { -static const Uint32 TOTAL_NUM_LIGHTS = 4U; + static const Uint32 TOTAL_NUM_LIGHTS = 4U; -class Light -{ -public: - enum LightType { - LIGHT_POINT, - LIGHT_SPOT, - LIGHT_DIRECTIONAL + class Light { + public: + enum LightType { + LIGHT_POINT, + LIGHT_SPOT, + LIGHT_DIRECTIONAL + }; + Light(); + Light(LightType t, const vector3f &position, const Color &diffuse, const Color &specular); + virtual ~Light() {} + void SetType(LightType t) { m_type = t; } + void SetPosition(const vector3f &p) { m_position = p; } + void SetDiffuse(const Color &c) { m_diffuse = c; } + void SetSpecular(const Color &c) { m_specular = c; } + + LightType GetType() const { return m_type; } + const vector3f &GetPosition() const { return m_position; } + const Color &GetDiffuse() const { return m_diffuse; } + const Color &GetSpecular() const { return m_specular; } + + private: + LightType m_type; + vector3f m_position; + Color m_diffuse; + Color m_specular; }; - Light(); - Light(LightType t, const vector3f &position, const Color &diffuse, const Color &specular); - virtual ~Light() {} - void SetType(LightType t) { m_type = t; } - void SetPosition(const vector3f &p) { m_position = p; } - void SetDiffuse(const Color &c) { m_diffuse = c; } - void SetSpecular(const Color &c) { m_specular = c; } - LightType GetType() const { return m_type; } - const vector3f &GetPosition() const { return m_position; } - const Color &GetDiffuse() const { return m_diffuse; } - const Color &GetSpecular() const { return m_specular; } - -private: - LightType m_type; - vector3f m_position; - Color m_diffuse; - Color m_specular; -}; - -} +} // namespace Graphics #endif diff --git a/src/graphics/Material.cpp b/src/graphics/Material.cpp index 1ce8c6607..7331afede 100644 --- a/src/graphics/Material.cpp +++ b/src/graphics/Material.cpp @@ -5,59 +5,58 @@ namespace Graphics { -Material::Material() : - texture0(nullptr), - texture1(nullptr), - texture2(nullptr), - texture3(nullptr), - texture4(nullptr), - texture5(nullptr), - texture6(nullptr), - heatGradient(nullptr), - diffuse(Color::WHITE), - specular(Color::BLACK), - emissive(Color::BLACK), - shininess(100), //somewhat sharp - specialParameter0(nullptr) -{ -} + Material::Material() : + texture0(nullptr), + texture1(nullptr), + texture2(nullptr), + texture3(nullptr), + texture4(nullptr), + texture5(nullptr), + texture6(nullptr), + heatGradient(nullptr), + diffuse(Color::WHITE), + specular(Color::BLACK), + emissive(Color::BLACK), + shininess(100), //somewhat sharp + specialParameter0(nullptr) + { + } -MaterialDescriptor::MaterialDescriptor() -: effect(EFFECT_DEFAULT) -, alphaTest(false) -, glowMap(false) -, ambientMap(false) -, lighting(false) -, normalMap(false) -, specularMap(false) -, usePatterns(false) -, vertexColors(false) -, instanced(false) -, textures(0) -, dirLights(0) -, quality(0) -, numShadows(0) -{ -} + MaterialDescriptor::MaterialDescriptor() : + effect(EFFECT_DEFAULT), + alphaTest(false), + glowMap(false), + ambientMap(false), + lighting(false), + normalMap(false), + specularMap(false), + usePatterns(false), + vertexColors(false), + instanced(false), + textures(0), + dirLights(0), + quality(0), + numShadows(0) + { + } -bool operator==(const MaterialDescriptor &a, const MaterialDescriptor &b) -{ - return ( - a.effect == b.effect && - a.alphaTest == b.alphaTest && - a.glowMap == b.glowMap && - a.ambientMap == b.ambientMap && - a.lighting == b.lighting && - a.normalMap == b.normalMap && - a.specularMap == b.specularMap && - a.usePatterns == b.usePatterns && - a.vertexColors == b.vertexColors && - a.instanced == b.instanced && - a.textures == b.textures && - a.dirLights == b.dirLights && - a.quality == b.quality && - a.numShadows == b.numShadows - ); -} + bool operator==(const MaterialDescriptor &a, const MaterialDescriptor &b) + { + return ( + a.effect == b.effect && + a.alphaTest == b.alphaTest && + a.glowMap == b.glowMap && + a.ambientMap == b.ambientMap && + a.lighting == b.lighting && + a.normalMap == b.normalMap && + a.specularMap == b.specularMap && + a.usePatterns == b.usePatterns && + a.vertexColors == b.vertexColors && + a.instanced == b.instanced && + a.textures == b.textures && + a.dirLights == b.dirLights && + a.quality == b.quality && + a.numShadows == b.numShadows); + } -} +} // namespace Graphics diff --git a/src/graphics/Material.h b/src/graphics/Material.h index 94b719f6b..984147631 100644 --- a/src/graphics/Material.h +++ b/src/graphics/Material.h @@ -17,105 +17,104 @@ namespace Graphics { -class Texture; -class RendererOGL; + class Texture; + class RendererOGL; -// Shorthand for unique effects -// The other descriptor parameters may or may not have effect, -// depends on the effect -enum EffectType { - EFFECT_DEFAULT, - EFFECT_VTXCOLOR, - EFFECT_UI, - EFFECT_STARFIELD, - EFFECT_PLANETRING, - EFFECT_GEOSPHERE_TERRAIN, - EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA, - EFFECT_GEOSPHERE_TERRAIN_WITH_WATER, - EFFECT_GEOSPHERE_SKY, - EFFECT_GEOSPHERE_STAR, - EFFECT_GASSPHERE_TERRAIN, - EFFECT_FRESNEL_SPHERE, - EFFECT_SHIELD, - EFFECT_SKYBOX, - EFFECT_SPHEREIMPOSTOR, - EFFECT_GEN_GASGIANT_TEXTURE, - EFFECT_BILLBOARD_ATLAS, - EFFECT_BILLBOARD -}; + // Shorthand for unique effects + // The other descriptor parameters may or may not have effect, + // depends on the effect + enum EffectType { + EFFECT_DEFAULT, + EFFECT_VTXCOLOR, + EFFECT_UI, + EFFECT_STARFIELD, + EFFECT_PLANETRING, + EFFECT_GEOSPHERE_TERRAIN, + EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA, + EFFECT_GEOSPHERE_TERRAIN_WITH_WATER, + EFFECT_GEOSPHERE_SKY, + EFFECT_GEOSPHERE_STAR, + EFFECT_GASSPHERE_TERRAIN, + EFFECT_FRESNEL_SPHERE, + EFFECT_SHIELD, + EFFECT_SKYBOX, + EFFECT_SPHEREIMPOSTOR, + EFFECT_GEN_GASGIANT_TEXTURE, + EFFECT_BILLBOARD_ATLAS, + EFFECT_BILLBOARD + }; + // XXX : there must be a better place to put this + enum MaterialQuality { + HAS_ATMOSPHERE = 1 << 0, + HAS_ECLIPSES = 1 << 1, + HAS_HEAT_GRADIENT = 1 << 2, + HAS_DETAIL_MAPS = 1 << 3 + }; -// XXX : there must be a better place to put this -enum MaterialQuality { - HAS_ATMOSPHERE = 1 << 0, - HAS_ECLIPSES = 1 << 1, - HAS_HEAT_GRADIENT = 1 << 2, - HAS_DETAIL_MAPS = 1 << 3 -}; + // Renderer creates a material that best matches these requirements. + // EffectType may override some of the other flags. + class MaterialDescriptor { + public: + MaterialDescriptor(); + EffectType effect; + bool alphaTest; + bool glowMap; + bool ambientMap; + bool lighting; + bool normalMap; + bool specularMap; + bool usePatterns; //pattern/color system + bool vertexColors; + bool instanced; + Sint32 textures; //texture count + Uint32 dirLights; //set by RendererOGL if lighting == true + Uint32 quality; // see: Graphics::MaterialQuality + Uint32 numShadows; //use by GeoSphere/GasGiant for eclipse -// Renderer creates a material that best matches these requirements. -// EffectType may override some of the other flags. -class MaterialDescriptor { -public: - MaterialDescriptor(); - EffectType effect; - bool alphaTest; - bool glowMap; - bool ambientMap; - bool lighting; - bool normalMap; - bool specularMap; - bool usePatterns; //pattern/color system - bool vertexColors; - bool instanced; - Sint32 textures; //texture count - Uint32 dirLights; //set by RendererOGL if lighting == true - Uint32 quality; // see: Graphics::MaterialQuality - Uint32 numShadows; //use by GeoSphere/GasGiant for eclipse + friend bool operator==(const MaterialDescriptor &a, const MaterialDescriptor &b); + }; - friend bool operator==(const MaterialDescriptor &a, const MaterialDescriptor &b); -}; - -/* + /* * A generic material with some generic parameters. */ -class Material : public RefCounted { -public: - Material(); - virtual ~Material() { } + class Material : public RefCounted { + public: + Material(); + virtual ~Material() {} - Texture *texture0; - Texture *texture1; - Texture *texture2; - Texture *texture3; - Texture *texture4; - Texture *texture5; - Texture *texture6; - Texture *heatGradient; + Texture *texture0; + Texture *texture1; + Texture *texture2; + Texture *texture3; + Texture *texture4; + Texture *texture5; + Texture *texture6; + Texture *heatGradient; - Color diffuse; - Color specular; - Color emissive; - int shininess; //specular power 0-128 + Color diffuse; + Color specular; + Color emissive; + int shininess; //specular power 0-128 - virtual void Apply() { } - virtual void Unapply() { } - virtual bool IsProgramLoaded() const = 0; + virtual void Apply() {} + virtual void Unapply() {} + virtual bool IsProgramLoaded() const = 0; - virtual void SetCommonUniforms(const matrix4x4f& mv, const matrix4x4f& proj) = 0; + virtual void SetCommonUniforms(const matrix4x4f &mv, const matrix4x4f &proj) = 0; - void *specialParameter0; //this can be whatever. Bit of a hack. + void *specialParameter0; //this can be whatever. Bit of a hack. - //XXX may not be necessary. Used by newmodel to check if a material uses patterns - const MaterialDescriptor &GetDescriptor() const { return m_descriptor; } + //XXX may not be necessary. Used by newmodel to check if a material uses patterns + const MaterialDescriptor &GetDescriptor() const { return m_descriptor; } -protected: - MaterialDescriptor m_descriptor; + protected: + MaterialDescriptor m_descriptor; -private: - friend class RendererOGL; -}; + private: + friend class RendererOGL; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/RenderState.h b/src/graphics/RenderState.h index 5145be9e8..f21fa8718 100644 --- a/src/graphics/RenderState.h +++ b/src/graphics/RenderState.h @@ -5,36 +5,35 @@ #define _GRAPHICS_RENDERSTATE_H #include "Renderer.h" -namespace Graphics -{ +namespace Graphics { -struct RenderStateDesc { - RenderStateDesc() - : blendMode(BLEND_SOLID) - , cullMode(CULL_BACK) - , depthTest(true) - , depthWrite(true) - { - } + struct RenderStateDesc { + RenderStateDesc() : + blendMode(BLEND_SOLID), + cullMode(CULL_BACK), + depthTest(true), + depthWrite(true) + { + } - BlendMode blendMode; - FaceCullMode cullMode; - bool depthTest; - bool depthWrite; -}; + BlendMode blendMode; + FaceCullMode cullMode; + bool depthTest; + bool depthWrite; + }; -class RenderState -{ -public: - virtual ~RenderState() { } + class RenderState { + public: + virtual ~RenderState() {} - const RenderStateDesc &GetDesc() const { return m_desc; } + const RenderStateDesc &GetDesc() const { return m_desc; } -protected: - RenderState(const RenderStateDesc &d) : m_desc(d) { } - RenderStateDesc m_desc; -}; + protected: + RenderState(const RenderStateDesc &d) : + m_desc(d) {} + RenderStateDesc m_desc; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/RenderTarget.h b/src/graphics/RenderTarget.h index 781bf8244..d3654f273 100644 --- a/src/graphics/RenderTarget.h +++ b/src/graphics/RenderTarget.h @@ -7,52 +7,57 @@ * Render target. Created by filling out a description and calling * renderer->CreateRenderTarget. */ -#include "libs.h" #include "Texture.h" +#include "libs.h" namespace Graphics { -// A render target may have a color texture, depth buffer/texture or both. -// Setting the formats to NONE will skip the texture creation, and you will -// have to set the textures yourself. -// Only request allowDepthTexture if you actually need to read the depth as texture -// Specifying a depth format with no allowDepthTexture will create a depth buffer -// fixed to this rendertarget -struct RenderTargetDesc { - RenderTargetDesc(Uint16 _width, Uint16 _height, TextureFormat _colorFormat, TextureFormat _depthFormat, bool _allowDepthTexture) : - width(_width), height(_height), colorFormat(_colorFormat), depthFormat(_depthFormat), allowDepthTexture(_allowDepthTexture) - {} + // A render target may have a color texture, depth buffer/texture or both. + // Setting the formats to NONE will skip the texture creation, and you will + // have to set the textures yourself. + // Only request allowDepthTexture if you actually need to read the depth as texture + // Specifying a depth format with no allowDepthTexture will create a depth buffer + // fixed to this rendertarget + struct RenderTargetDesc { + RenderTargetDesc(Uint16 _width, Uint16 _height, TextureFormat _colorFormat, TextureFormat _depthFormat, bool _allowDepthTexture) : + width(_width), + height(_height), + colorFormat(_colorFormat), + depthFormat(_depthFormat), + allowDepthTexture(_allowDepthTexture) + {} - const Uint16 width; - const Uint16 height; - const TextureFormat colorFormat; - const TextureFormat depthFormat; - const bool allowDepthTexture; -}; + const Uint16 width; + const Uint16 height; + const TextureFormat colorFormat; + const TextureFormat depthFormat; + const bool allowDepthTexture; + }; -class RenderTarget { -public: - virtual ~RenderTarget() { } + class RenderTarget { + public: + virtual ~RenderTarget() {} - virtual Texture *GetColorTexture() const = 0; - virtual Texture *GetDepthTexture() const = 0; - //Replace the texture attachment, or pass zero to detach - //Increases the new texture's reference count and decreases - //any existing texture's count - //Setting a depth texture is not allowed if the render target is not - //created with allowDepthTexture - virtual void SetCubeFaceTexture(const Uint32, Texture*) = 0; - virtual void SetColorTexture(Texture*) = 0; - virtual void SetDepthTexture(Texture*) = 0; + virtual Texture *GetColorTexture() const = 0; + virtual Texture *GetDepthTexture() const = 0; + //Replace the texture attachment, or pass zero to detach + //Increases the new texture's reference count and decreases + //any existing texture's count + //Setting a depth texture is not allowed if the render target is not + //created with allowDepthTexture + virtual void SetCubeFaceTexture(const Uint32, Texture *) = 0; + virtual void SetColorTexture(Texture *) = 0; + virtual void SetDepthTexture(Texture *) = 0; - const RenderTargetDesc &GetDesc() const { return m_desc; } + const RenderTargetDesc &GetDesc() const { return m_desc; } -protected: - RenderTarget(const RenderTargetDesc &d) : m_desc(d) { } + protected: + RenderTarget(const RenderTargetDesc &d) : + m_desc(d) {} - RenderTargetDesc m_desc; -}; + RenderTargetDesc m_desc; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index bf505f23a..bedde24f9 100644 --- a/src/graphics/Renderer.cpp +++ b/src/graphics/Renderer.cpp @@ -6,49 +6,52 @@ namespace Graphics { -Renderer::Renderer(SDL_Window *window, int w, int h) : - m_width(w), m_height(h), m_ambient(Color::BLACK), m_window(window) -{ -} + Renderer::Renderer(SDL_Window *window, int w, int h) : + m_width(w), + m_height(h), + m_ambient(Color::BLACK), + m_window(window) + { + } -Renderer::~Renderer() -{ - RemoveAllCachedTextures(); - SDL_DestroyWindow(m_window); -} + Renderer::~Renderer() + { + RemoveAllCachedTextures(); + SDL_DestroyWindow(m_window); + } -Texture *Renderer::GetCachedTexture(const std::string &type, const std::string &name) -{ - TextureCacheMap::iterator i = m_textures.find(TextureCacheKey(type,name)); - if (i == m_textures.end()) return 0; - return (*i).second->Get(); -} + Texture *Renderer::GetCachedTexture(const std::string &type, const std::string &name) + { + TextureCacheMap::iterator i = m_textures.find(TextureCacheKey(type, name)); + if (i == m_textures.end()) return 0; + return (*i).second->Get(); + } -void Renderer::AddCachedTexture(const std::string &type, const std::string &name, Texture *texture) -{ - RemoveCachedTexture(type,name); - m_textures.insert(std::make_pair(TextureCacheKey(type,name),new RefCountedPtr(texture))); -} + void Renderer::AddCachedTexture(const std::string &type, const std::string &name, Texture *texture) + { + RemoveCachedTexture(type, name); + m_textures.insert(std::make_pair(TextureCacheKey(type, name), new RefCountedPtr(texture))); + } -void Renderer::RemoveCachedTexture(const std::string &type, const std::string &name) -{ - TextureCacheMap::iterator i = m_textures.find(TextureCacheKey(type,name)); - if (i == m_textures.end()) return; - delete (*i).second; - m_textures.erase(i); -} - -void Renderer::RemoveAllCachedTextures() -{ - for (TextureCacheMap::iterator i = m_textures.begin(); i != m_textures.end(); ++i) + void Renderer::RemoveCachedTexture(const std::string &type, const std::string &name) + { + TextureCacheMap::iterator i = m_textures.find(TextureCacheKey(type, name)); + if (i == m_textures.end()) return; delete (*i).second; - m_textures.clear(); -} + m_textures.erase(i); + } -void Renderer::SetGrab(const bool grabbed) -{ - SDL_SetWindowGrab(m_window, SDL_bool(grabbed)); - SDL_SetRelativeMouseMode(SDL_bool(grabbed)); -} + void Renderer::RemoveAllCachedTextures() + { + for (TextureCacheMap::iterator i = m_textures.begin(); i != m_textures.end(); ++i) + delete (*i).second; + m_textures.clear(); + } -} + void Renderer::SetGrab(const bool grabbed) + { + SDL_SetWindowGrab(m_window, SDL_bool(grabbed)); + SDL_SetRelativeMouseMode(SDL_bool(grabbed)); + } + +} // namespace Graphics diff --git a/src/graphics/Renderer.h b/src/graphics/Renderer.h index d076bf9be..7fcf45fef 100644 --- a/src/graphics/Renderer.h +++ b/src/graphics/Renderer.h @@ -5,208 +5,217 @@ #define _RENDERER_H #include "Graphics.h" -#include "libs.h" -#include "Types.h" #include "Light.h" #include "Stats.h" +#include "Types.h" +#include "libs.h" #include #include namespace Graphics { -/* + /* * Renderer base class. A Renderer draws points, lines, triangles. * It is also used to create render states, materials and vertex/index buffers. */ -class Material; -class MaterialDescriptor; -class RenderState; -class RenderTarget; -class Texture; -class TextureDescriptor; -class VertexArray; -class VertexBuffer; -class IndexBuffer; -class InstanceBuffer; -struct VertexBufferDesc; -struct RenderStateDesc; -struct RenderTargetDesc; + class Material; + class MaterialDescriptor; + class RenderState; + class RenderTarget; + class Texture; + class TextureDescriptor; + class VertexArray; + class VertexBuffer; + class IndexBuffer; + class InstanceBuffer; + struct VertexBufferDesc; + struct RenderStateDesc; + struct RenderTargetDesc; -enum class MatrixMode { - MODELVIEW, - PROJECTION -}; - - -// Renderer base, functions return false if -// failed/unsupported -class Renderer -{ -public: - Renderer(SDL_Window *win, int width, int height); - virtual ~Renderer(); - - virtual const char* GetName() const = 0; - virtual RendererType GetRendererType() const = 0; - - virtual void WriteRendererInfo(std::ostream &out) const {} - - virtual void CheckRenderErrors(const char *func = nullptr, const int line = -1) const {} - - virtual bool SupportsInstancing() = 0; - - SDL_Window *GetSDLWindow() const { return m_window; } - float GetDisplayAspect() const { return static_cast(m_width) / static_cast(m_height); } - int GetWindowWidth() const { return m_width; } - int GetWindowHeight() const { return m_height; } - virtual int GetMaximumNumberAASamples() const = 0; - - //get supported minimum for z near and maximum for z far values - virtual bool GetNearFarRange(float &near_, float &far_) const = 0; - - virtual bool BeginFrame() = 0; - virtual bool EndFrame() = 0; - //traditionally gui happens between endframe and swapbuffers - virtual bool SwapBuffers() = 0; - - //set 0 to render to screen - virtual bool SetRenderTarget(RenderTarget*) = 0; - - //clear color and depth buffer - virtual bool ClearScreen() = 0; - //clear depth buffer - virtual bool ClearDepthBuffer() = 0; - virtual bool SetClearColor(const Color &c) = 0; - - virtual bool SetViewport(int x, int y, int width, int height) = 0; - - //set the model view matrix - virtual bool SetTransform(const matrix4x4d &m) = 0; - virtual bool SetTransform(const matrix4x4f &m) = 0; - //set projection matrix - virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) = 0; - virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) = 0; - virtual bool SetProjection(const matrix4x4f &m) = 0; - - virtual bool SetRenderState(RenderState*) = 0; - - // XXX maybe GL-specific. maybe should be part of the render state - virtual bool SetDepthRange(double znear, double zfar) = 0; - - virtual bool SetWireFrameMode(bool enabled) = 0; - - virtual bool SetLights(Uint32 numlights, const Light *l) = 0; - const Light& GetLight(const Uint32 idx) const { assert(idx<4); return m_lights[idx]; } - virtual Uint32 GetNumLights() const { return 0; } - virtual bool SetAmbientColor(const Color &c) = 0; - const Color &GetAmbientColor() const { return m_ambient; } - - virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) = 0; - - //drawing functions - //2d drawing is generally understood to be for gui use (unlit, ortho projection) - //unindexed triangle draw - virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type=TRIANGLES) = 0; - //high amount of textured quads for particles etc - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) = 0; - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) = 0; - //complex unchanging geometry that is worthwhile to store in VBOs etc. - virtual bool DrawBuffer(VertexBuffer*, RenderState*, Material*, PrimitiveType type=TRIANGLES) = 0; - virtual bool DrawBufferIndexed(VertexBuffer*, IndexBuffer*, RenderState*, Material*, PrimitiveType=TRIANGLES) = 0; - // instanced variations of the above - virtual bool DrawBufferInstanced(VertexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType type=TRIANGLES) = 0; - virtual bool DrawBufferIndexedInstanced(VertexBuffer*, IndexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType=TRIANGLES) = 0; - - //creates a unique material based on the descriptor. It will not be deleted automatically. - virtual Material *CreateMaterial(const MaterialDescriptor &descriptor) = 0; - virtual Texture *CreateTexture(const TextureDescriptor &descriptor) = 0; - virtual RenderState *CreateRenderState(const RenderStateDesc &) = 0; - //returns 0 if unsupported - virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &) = 0; - virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc&) = 0; - virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage) = 0; - virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage) = 0; - - Texture *GetCachedTexture(const std::string &type, const std::string &name); - void AddCachedTexture(const std::string &type, const std::string &name, Texture *texture); - void RemoveCachedTexture(const std::string &type, const std::string &name); - void RemoveAllCachedTextures(); - - virtual bool ReloadShaders() = 0; - - // our own matrix stack - // XXX state must die - virtual const matrix4x4f& GetCurrentModelView() const = 0; - virtual const matrix4x4f& GetCurrentProjection() const = 0; - virtual void GetCurrentViewport(Sint32 *vp) const = 0; - - // XXX all quite GL specific. state must die! - virtual void SetMatrixMode(MatrixMode mm) = 0; - virtual void PushMatrix() = 0; - virtual void PopMatrix() = 0; - virtual void LoadIdentity() = 0; - virtual void LoadMatrix(const matrix4x4f &m) = 0; - virtual void Translate( const float x, const float y, const float z ) = 0; - virtual void Scale( const float x, const float y, const float z ) = 0; - - // take a ticket representing the current renderer state. when the ticket - // is deleted, the renderer state is restored - // XXX state must die - class StateTicket { - public: - StateTicket(Renderer *r) : m_renderer(r) { m_renderer->PushState(); } - virtual ~StateTicket() { m_renderer->PopState(); } - private: - StateTicket(const StateTicket&); - StateTicket &operator=(const StateTicket&); - Renderer *m_renderer; + enum class MatrixMode { + MODELVIEW, + PROJECTION }; - // take a ticket representing a single state matrix. when the ticket is - // deleted, the previous matrix state is restored - // XXX state must die - class MatrixTicket { + // Renderer base, functions return false if + // failed/unsupported + class Renderer { public: - MatrixTicket(Renderer *r, MatrixMode m) : m_renderer(r), m_matrixMode(m) { - m_renderer->SetMatrixMode(m_matrixMode); - m_renderer->PushMatrix(); - } - virtual ~MatrixTicket() { - m_renderer->SetMatrixMode(m_matrixMode); - m_renderer->PopMatrix(); + Renderer(SDL_Window *win, int width, int height); + virtual ~Renderer(); + + virtual const char *GetName() const = 0; + virtual RendererType GetRendererType() const = 0; + + virtual void WriteRendererInfo(std::ostream &out) const {} + + virtual void CheckRenderErrors(const char *func = nullptr, const int line = -1) const {} + + virtual bool SupportsInstancing() = 0; + + SDL_Window *GetSDLWindow() const { return m_window; } + float GetDisplayAspect() const { return static_cast(m_width) / static_cast(m_height); } + int GetWindowWidth() const { return m_width; } + int GetWindowHeight() const { return m_height; } + virtual int GetMaximumNumberAASamples() const = 0; + + //get supported minimum for z near and maximum for z far values + virtual bool GetNearFarRange(float &near_, float &far_) const = 0; + + virtual bool BeginFrame() = 0; + virtual bool EndFrame() = 0; + //traditionally gui happens between endframe and swapbuffers + virtual bool SwapBuffers() = 0; + + //set 0 to render to screen + virtual bool SetRenderTarget(RenderTarget *) = 0; + + //clear color and depth buffer + virtual bool ClearScreen() = 0; + //clear depth buffer + virtual bool ClearDepthBuffer() = 0; + virtual bool SetClearColor(const Color &c) = 0; + + virtual bool SetViewport(int x, int y, int width, int height) = 0; + + //set the model view matrix + virtual bool SetTransform(const matrix4x4d &m) = 0; + virtual bool SetTransform(const matrix4x4f &m) = 0; + //set projection matrix + virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) = 0; + virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) = 0; + virtual bool SetProjection(const matrix4x4f &m) = 0; + + virtual bool SetRenderState(RenderState *) = 0; + + // XXX maybe GL-specific. maybe should be part of the render state + virtual bool SetDepthRange(double znear, double zfar) = 0; + + virtual bool SetWireFrameMode(bool enabled) = 0; + + virtual bool SetLights(Uint32 numlights, const Light *l) = 0; + const Light &GetLight(const Uint32 idx) const + { + assert(idx < 4); + return m_lights[idx]; } + virtual Uint32 GetNumLights() const { return 0; } + virtual bool SetAmbientColor(const Color &c) = 0; + const Color &GetAmbientColor() const { return m_ambient; } + + virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) = 0; + + //drawing functions + //2d drawing is generally understood to be for gui use (unlit, ortho projection) + //unindexed triangle draw + virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type = TRIANGLES) = 0; + //high amount of textured quads for particles etc + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) = 0; + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) = 0; + //complex unchanging geometry that is worthwhile to store in VBOs etc. + virtual bool DrawBuffer(VertexBuffer *, RenderState *, Material *, PrimitiveType type = TRIANGLES) = 0; + virtual bool DrawBufferIndexed(VertexBuffer *, IndexBuffer *, RenderState *, Material *, PrimitiveType = TRIANGLES) = 0; + // instanced variations of the above + virtual bool DrawBufferInstanced(VertexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType type = TRIANGLES) = 0; + virtual bool DrawBufferIndexedInstanced(VertexBuffer *, IndexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType = TRIANGLES) = 0; + + //creates a unique material based on the descriptor. It will not be deleted automatically. + virtual Material *CreateMaterial(const MaterialDescriptor &descriptor) = 0; + virtual Texture *CreateTexture(const TextureDescriptor &descriptor) = 0; + virtual RenderState *CreateRenderState(const RenderStateDesc &) = 0; + //returns 0 if unsupported + virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &) = 0; + virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc &) = 0; + virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage) = 0; + virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage) = 0; + + Texture *GetCachedTexture(const std::string &type, const std::string &name); + void AddCachedTexture(const std::string &type, const std::string &name, Texture *texture); + void RemoveCachedTexture(const std::string &type, const std::string &name); + void RemoveAllCachedTextures(); + + virtual bool ReloadShaders() = 0; + + // our own matrix stack + // XXX state must die + virtual const matrix4x4f &GetCurrentModelView() const = 0; + virtual const matrix4x4f &GetCurrentProjection() const = 0; + virtual void GetCurrentViewport(Sint32 *vp) const = 0; + + // XXX all quite GL specific. state must die! + virtual void SetMatrixMode(MatrixMode mm) = 0; + virtual void PushMatrix() = 0; + virtual void PopMatrix() = 0; + virtual void LoadIdentity() = 0; + virtual void LoadMatrix(const matrix4x4f &m) = 0; + virtual void Translate(const float x, const float y, const float z) = 0; + virtual void Scale(const float x, const float y, const float z) = 0; + + // take a ticket representing the current renderer state. when the ticket + // is deleted, the renderer state is restored + // XXX state must die + class StateTicket { + public: + StateTicket(Renderer *r) : + m_renderer(r) { m_renderer->PushState(); } + virtual ~StateTicket() { m_renderer->PopState(); } + + private: + StateTicket(const StateTicket &); + StateTicket &operator=(const StateTicket &); + Renderer *m_renderer; + }; + + // take a ticket representing a single state matrix. when the ticket is + // deleted, the previous matrix state is restored + // XXX state must die + class MatrixTicket { + public: + MatrixTicket(Renderer *r, MatrixMode m) : + m_renderer(r), + m_matrixMode(m) + { + m_renderer->SetMatrixMode(m_matrixMode); + m_renderer->PushMatrix(); + } + virtual ~MatrixTicket() + { + m_renderer->SetMatrixMode(m_matrixMode); + m_renderer->PopMatrix(); + } + + private: + MatrixTicket(const MatrixTicket &); + MatrixTicket &operator=(const MatrixTicket &); + Renderer *m_renderer; + MatrixMode m_matrixMode; + }; + + virtual bool Screendump(ScreendumpState &sd) { return false; } + virtual bool FrameGrab(ScreendumpState &sd) { return false; } + + Stats &GetStats() { return m_stats; } + + void SetGrab(const bool grabbed); + + protected: + int m_width; + int m_height; + Color m_ambient; + Light m_lights[4]; + Stats m_stats; + SDL_Window *m_window; + + virtual void PushState() = 0; + virtual void PopState() = 0; + private: - MatrixTicket(const MatrixTicket&); - MatrixTicket &operator=(const MatrixTicket&); - Renderer *m_renderer; - MatrixMode m_matrixMode; + typedef std::pair TextureCacheKey; + typedef std::map *> TextureCacheMap; + TextureCacheMap m_textures; }; - virtual bool Screendump(ScreendumpState &sd) { return false; } - virtual bool FrameGrab(ScreendumpState &sd) { return false; } - - Stats& GetStats() { return m_stats; } - - void SetGrab(const bool grabbed); - -protected: - int m_width; - int m_height; - Color m_ambient; - Light m_lights[4]; - Stats m_stats; - SDL_Window *m_window; - - virtual void PushState() = 0; - virtual void PopState() = 0; - -private: - typedef std::pair TextureCacheKey; - typedef std::map*> TextureCacheMap; - TextureCacheMap m_textures; -}; - -} +} // namespace Graphics #endif diff --git a/src/graphics/Stats.cpp b/src/graphics/Stats.cpp index 2cadd78cc..6ebc9f297 100644 --- a/src/graphics/Stats.cpp +++ b/src/graphics/Stats.cpp @@ -7,7 +7,8 @@ namespace Graphics { - Stats::Stats() : m_currentFrame(0U) + Stats::Stats() : + m_currentFrame(0U) { memset(&m_frameStats[0], 0, sizeof(TFrameData) * MAX_FRAMES_STORE); } @@ -20,14 +21,15 @@ namespace Graphics { void Stats::NextFrame() { ++m_currentFrame; - if(m_currentFrame >= MAX_FRAMES_STORE) { + if (m_currentFrame >= MAX_FRAMES_STORE) { m_currentFrame = 0; } assert(m_currentFrame >= 0 && m_currentFrame < MAX_FRAMES_STORE); memset(&m_frameStats[m_currentFrame], 0, sizeof(TFrameData)); } - const Stats::TFrameData& Stats::FrameStatsPrevious() const { - return m_frameStats[Clamp(m_currentFrame-1, 0U, MAX_FRAMES_STORE-1)]; + const Stats::TFrameData &Stats::FrameStatsPrevious() const + { + return m_frameStats[Clamp(m_currentFrame - 1, 0U, MAX_FRAMES_STORE - 1)]; } -} +} // namespace Graphics diff --git a/src/graphics/Stats.h b/src/graphics/Stats.h index cf8cab1d5..4ef142066 100644 --- a/src/graphics/Stats.h +++ b/src/graphics/Stats.h @@ -10,57 +10,55 @@ namespace Graphics { -class Stats -{ -public: - static const Uint32 MAX_FRAMES_STORE = 30U; - enum StatType { - // renderer entries - STAT_DRAWCALL = 0, - STAT_DRAWTRIS, - STAT_DRAWPOINTSPRITES, + class Stats { + public: + static const Uint32 MAX_FRAMES_STORE = 30U; + enum StatType { + // renderer entries + STAT_DRAWCALL = 0, + STAT_DRAWTRIS, + STAT_DRAWPOINTSPRITES, - // buffers - STAT_CREATE_BUFFER, - STAT_DESTROY_BUFFER, + // buffers + STAT_CREATE_BUFFER, + STAT_DESTROY_BUFFER, - // objects - STAT_BUILDINGS, - STAT_CITIES, - STAT_GROUNDSTATIONS, - STAT_SPACESTATIONS, - STAT_ATMOSPHERES, - STAT_PATCHES, - STAT_PLANETS, - STAT_GASGIANTS, - STAT_STARS, - STAT_SHIPS, + // objects + STAT_BUILDINGS, + STAT_CITIES, + STAT_GROUNDSTATIONS, + STAT_SPACESTATIONS, + STAT_ATMOSPHERES, + STAT_PATCHES, + STAT_PLANETS, + STAT_GASGIANTS, + STAT_STARS, + STAT_SHIPS, - // scenegraph entries - STAT_BILLBOARD, + // scenegraph entries + STAT_BILLBOARD, - MAX_STAT + MAX_STAT + }; + + struct TFrameData { + Uint32 m_stats[MAX_STAT]; + }; + + Stats(); + ~Stats() {} + + void AddToStatCount(const StatType type, const Uint32 count); + void NextFrame(); + + const TFrameData &FrameStats() const { return m_frameStats[m_currentFrame]; } + const TFrameData &FrameStatsPrevious() const; + + private: + TFrameData m_frameStats[MAX_FRAMES_STORE]; + Uint32 m_currentFrame; }; - struct TFrameData { - Uint32 m_stats[MAX_STAT]; - }; - - Stats(); - ~Stats() {} - - void AddToStatCount(const StatType type, const Uint32 count); - void NextFrame(); - - const TFrameData& FrameStats() const { return m_frameStats[m_currentFrame]; } - const TFrameData& FrameStatsPrevious() const; - -private: - - TFrameData m_frameStats[MAX_FRAMES_STORE]; - Uint32 m_currentFrame; -}; - -} +} // namespace Graphics #endif diff --git a/src/graphics/Texture.h b/src/graphics/Texture.h index 77ccf3494..cd55894f7 100644 --- a/src/graphics/Texture.h +++ b/src/graphics/Texture.h @@ -4,114 +4,141 @@ #ifndef _TEXTURE_H #define _TEXTURE_H -#include "vector2.h" #include "RefCounted.h" +#include "vector2.h" namespace Graphics { -enum TextureFormat { - TEXTURE_NONE, + enum TextureFormat { + TEXTURE_NONE, - TEXTURE_RGBA_8888, - TEXTURE_RGB_888, + TEXTURE_RGBA_8888, + TEXTURE_RGB_888, - //luminance/intensity formats are deprecated in opengl 3+ - //so we might remove them someday - TEXTURE_LUMINANCE_ALPHA_88, //luminance value put into R,G,B components; separate alpha value - TEXTURE_INTENSITY_8, //intensity value put into RGBA components + //luminance/intensity formats are deprecated in opengl 3+ + //so we might remove them someday + TEXTURE_LUMINANCE_ALPHA_88, //luminance value put into R,G,B components; separate alpha value + TEXTURE_INTENSITY_8, //intensity value put into RGBA components - TEXTURE_DXT1, // data is expected to be pre-compressed - TEXTURE_DXT5, + TEXTURE_DXT1, // data is expected to be pre-compressed + TEXTURE_DXT5, - TEXTURE_DEPTH //precision chosen by renderer -}; + TEXTURE_DEPTH //precision chosen by renderer + }; -enum TextureSampleMode { - LINEAR_CLAMP, - NEAREST_CLAMP, - LINEAR_REPEAT, - NEAREST_REPEAT -}; + enum TextureSampleMode { + LINEAR_CLAMP, + NEAREST_CLAMP, + LINEAR_REPEAT, + NEAREST_REPEAT + }; -enum TextureType { - TEXTURE_2D, - TEXTURE_CUBE_MAP -}; + enum TextureType { + TEXTURE_2D, + TEXTURE_CUBE_MAP + }; -struct TextureCubeData { - void* posX; - void* negX; - void* posY; - void* negY; - void* posZ; - void* negZ; -}; + struct TextureCubeData { + void *posX; + void *negX; + void *posY; + void *negY; + void *posZ; + void *negZ; + }; -class TextureDescriptor { -public: - TextureDescriptor() : - format(TEXTURE_RGBA_8888), dataSize(1.0f), texSize(1.0f), sampleMode(LINEAR_CLAMP), generateMipmaps(false), allowCompression(true), useAnisotropicFiltering(true), numberOfMipMaps(0), type(TEXTURE_2D) - {} + class TextureDescriptor { + public: + TextureDescriptor() : + format(TEXTURE_RGBA_8888), + dataSize(1.0f), + texSize(1.0f), + sampleMode(LINEAR_CLAMP), + generateMipmaps(false), + allowCompression(true), + useAnisotropicFiltering(true), + numberOfMipMaps(0), + type(TEXTURE_2D) + {} - TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) : - format(_format), dataSize(_dataSize), texSize(1.0f), sampleMode(_sampleMode), generateMipmaps(_generateMipmaps), allowCompression(_allowCompression), useAnisotropicFiltering(_useAnisotropicFiltering), numberOfMipMaps(_numberOfMipMaps), type(_textureType) - {} + TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) : + format(_format), + dataSize(_dataSize), + texSize(1.0f), + sampleMode(_sampleMode), + generateMipmaps(_generateMipmaps), + allowCompression(_allowCompression), + useAnisotropicFiltering(_useAnisotropicFiltering), + numberOfMipMaps(_numberOfMipMaps), + type(_textureType) + {} - TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, const vector2f &_texSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) : - format(_format), dataSize(_dataSize), texSize(_texSize), sampleMode(_sampleMode), generateMipmaps(_generateMipmaps), allowCompression(_allowCompression), useAnisotropicFiltering(_useAnisotropicFiltering), numberOfMipMaps(_numberOfMipMaps), type(_textureType) - {} + TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, const vector2f &_texSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) : + format(_format), + dataSize(_dataSize), + texSize(_texSize), + sampleMode(_sampleMode), + generateMipmaps(_generateMipmaps), + allowCompression(_allowCompression), + useAnisotropicFiltering(_useAnisotropicFiltering), + numberOfMipMaps(_numberOfMipMaps), + type(_textureType) + {} - vector2f GetOriginalSize() const { return vector2f(dataSize.x * texSize.x, dataSize.y * texSize.y); } + vector2f GetOriginalSize() const { return vector2f(dataSize.x * texSize.x, dataSize.y * texSize.y); } - const TextureFormat format; - const vector2f dataSize; - const vector2f texSize; - const TextureSampleMode sampleMode; - const bool generateMipmaps; - const bool allowCompression; - const bool useAnisotropicFiltering; - const unsigned int numberOfMipMaps; - const TextureType type; + const TextureFormat format; + const vector2f dataSize; + const vector2f texSize; + const TextureSampleMode sampleMode; + const bool generateMipmaps; + const bool allowCompression; + const bool useAnisotropicFiltering; + const unsigned int numberOfMipMaps; + const TextureType type; - TextureDescriptor& operator=(const TextureDescriptor &o) { - const_cast(format) = o.format; - const_cast(dataSize) = o.dataSize; - const_cast(texSize) = o.texSize; - const_cast(sampleMode) = o.sampleMode; - const_cast(generateMipmaps) = o.generateMipmaps; - const_cast(allowCompression) = o.allowCompression; - const_cast(useAnisotropicFiltering) = o.useAnisotropicFiltering; - const_cast(numberOfMipMaps) = o.numberOfMipMaps; - const_cast(type) = o.type; - return *this; - } -}; + TextureDescriptor &operator=(const TextureDescriptor &o) + { + const_cast(format) = o.format; + const_cast(dataSize) = o.dataSize; + const_cast(texSize) = o.texSize; + const_cast(sampleMode) = o.sampleMode; + const_cast(generateMipmaps) = o.generateMipmaps; + const_cast(allowCompression) = o.allowCompression; + const_cast(useAnisotropicFiltering) = o.useAnisotropicFiltering; + const_cast(numberOfMipMaps) = o.numberOfMipMaps; + const_cast(type) = o.type; + return *this; + } + }; -class Texture : public RefCounted { -public: - const TextureDescriptor &GetDescriptor() const { return m_descriptor; } + class Texture : public RefCounted { + public: + const TextureDescriptor &GetDescriptor() const { return m_descriptor; } - virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0; - virtual void Update(const void *data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) { - Update(data, vector2f(0,0), dataSize, format, numMips); - } - virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0; - virtual void SetSampleMode(TextureSampleMode) = 0; - virtual void BuildMipmaps() = 0; - virtual uint32_t GetTextureID() const = 0; + virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0; + virtual void Update(const void *data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) + { + Update(data, vector2f(0, 0), dataSize, format, numMips); + } + virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0; + virtual void SetSampleMode(TextureSampleMode) = 0; + virtual void BuildMipmaps() = 0; + virtual uint32_t GetTextureID() const = 0; - virtual void Bind() = 0; - virtual void Unbind() = 0; + virtual void Bind() = 0; + virtual void Unbind() = 0; - virtual ~Texture() {} + virtual ~Texture() {} -protected: - Texture(const TextureDescriptor &descriptor) : m_descriptor(descriptor) {} + protected: + Texture(const TextureDescriptor &descriptor) : + m_descriptor(descriptor) {} -private: - TextureDescriptor m_descriptor; -}; + private: + TextureDescriptor m_descriptor; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/TextureBuilder.cpp b/src/graphics/TextureBuilder.cpp index 3ceebe776..02afb2b3d 100644 --- a/src/graphics/TextureBuilder.cpp +++ b/src/graphics/TextureBuilder.cpp @@ -12,283 +12,298 @@ namespace Graphics { -//static -SDL_mutex *TextureBuilder::m_textureLock = nullptr; + //static + SDL_mutex *TextureBuilder::m_textureLock = nullptr; -TextureBuilder::TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering) : - m_surface(surface), m_sampleMode(sampleMode), m_generateMipmaps(generateMipmaps), m_potExtend(potExtend), m_forceRGBA(forceRGBA), m_compressTextures(compressTextures), m_anisotropicFiltering(anisoFiltering), m_textureType(TEXTURE_2D), m_prepared(false) -{ -} + TextureBuilder::TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering) : + m_surface(surface), + m_sampleMode(sampleMode), + m_generateMipmaps(generateMipmaps), + m_potExtend(potExtend), + m_forceRGBA(forceRGBA), + m_compressTextures(compressTextures), + m_anisotropicFiltering(anisoFiltering), + m_textureType(TEXTURE_2D), + m_prepared(false) + { + } -TextureBuilder::TextureBuilder(const std::string &filename, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering, TextureType textureType) : - m_filename(filename), m_sampleMode(sampleMode), m_generateMipmaps(generateMipmaps), m_potExtend(potExtend), m_forceRGBA(forceRGBA), m_compressTextures(compressTextures), m_anisotropicFiltering(anisoFiltering), m_textureType(textureType), m_prepared(false) -{ -} + TextureBuilder::TextureBuilder(const std::string &filename, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering, TextureType textureType) : + m_filename(filename), + m_sampleMode(sampleMode), + m_generateMipmaps(generateMipmaps), + m_potExtend(potExtend), + m_forceRGBA(forceRGBA), + m_compressTextures(compressTextures), + m_anisotropicFiltering(anisoFiltering), + m_textureType(textureType), + m_prepared(false) + { + } -TextureBuilder::~TextureBuilder() -{ -} + TextureBuilder::~TextureBuilder() + { + } -void TextureBuilder::Init() -{ - m_textureLock = SDL_CreateMutex(); -} + void TextureBuilder::Init() + { + m_textureLock = SDL_CreateMutex(); + } // RGBA and RGBpixel format for converting textures // XXX little-endian. if we ever have a port to a big-endian arch, invert shift and mask #if SDL_BYTEORDER != SDL_LIL_ENDIAN #error "SDL surface pixel formats are endian-specific" #endif -static SDL_PixelFormat pixelFormatRGBA = { - 0, // format# - 0, // palette - 32, // bits per pixel - 4, // bytes per pixel - { 0, 0 }, // padding - 0xff, 0xff00, 0xff0000, 0xff000000, // RGBA mask - 0, 0, 0, 0, // RGBA loss - 24, 16, 8, 0, // RGBA shift - 0, // colour key - 0 // alpha -}; + static SDL_PixelFormat pixelFormatRGBA = { + 0, // format# + 0, // palette + 32, // bits per pixel + 4, // bytes per pixel + { 0, 0 }, // padding + 0xff, 0xff00, 0xff0000, 0xff000000, // RGBA mask + 0, 0, 0, 0, // RGBA loss + 24, 16, 8, 0, // RGBA shift + 0, // colour key + 0 // alpha + }; -static SDL_PixelFormat pixelFormatRGB = { - 0, // format# - 0, // palette - 24, // bits per pixel - 3, // bytes per pixel - { 0, 0 }, // padding - 0xff, 0xff00, 0xff0000, 0, // RGBA mask - 0, 0, 0, 0, // RGBA loss - 16, 8, 0, 0, // RGBA shift - 0, // colour key - 0 // alpha -}; + static SDL_PixelFormat pixelFormatRGB = { + 0, // format# + 0, // palette + 24, // bits per pixel + 3, // bytes per pixel + { 0, 0 }, // padding + 0xff, 0xff00, 0xff0000, 0, // RGBA mask + 0, 0, 0, 0, // RGBA loss + 16, 8, 0, 0, // RGBA shift + 0, // colour key + 0 // alpha + }; -static inline bool GetTargetFormat(const SDL_PixelFormat *sourcePixelFormat, TextureFormat *targetTextureFormat, SDL_PixelFormat **targetPixelFormat, bool forceRGBA) -{ - if (!forceRGBA && sourcePixelFormat->BytesPerPixel == pixelFormatRGB.BytesPerPixel && + static inline bool GetTargetFormat(const SDL_PixelFormat *sourcePixelFormat, TextureFormat *targetTextureFormat, SDL_PixelFormat **targetPixelFormat, bool forceRGBA) + { + if (!forceRGBA && sourcePixelFormat->BytesPerPixel == pixelFormatRGB.BytesPerPixel && sourcePixelFormat->Rmask == pixelFormatRGB.Rmask && sourcePixelFormat->Bmask == pixelFormatRGB.Bmask && sourcePixelFormat->Gmask == pixelFormatRGB.Gmask) { - *targetTextureFormat = TEXTURE_RGB_888; - *targetPixelFormat = &pixelFormatRGB; - return true; - } + *targetTextureFormat = TEXTURE_RGB_888; + *targetPixelFormat = &pixelFormatRGB; + return true; + } - if (sourcePixelFormat->BytesPerPixel == pixelFormatRGBA.BytesPerPixel && + if (sourcePixelFormat->BytesPerPixel == pixelFormatRGBA.BytesPerPixel && sourcePixelFormat->Rmask == pixelFormatRGBA.Rmask && sourcePixelFormat->Bmask == pixelFormatRGBA.Bmask && sourcePixelFormat->Gmask == pixelFormatRGBA.Gmask) { + *targetTextureFormat = TEXTURE_RGBA_8888; + *targetPixelFormat = &pixelFormatRGBA; + return true; + } + + if (!forceRGBA && sourcePixelFormat->BytesPerPixel == 3) { + *targetTextureFormat = TEXTURE_RGB_888; + *targetPixelFormat = &pixelFormatRGB; + return false; + } + *targetTextureFormat = TEXTURE_RGBA_8888; *targetPixelFormat = &pixelFormatRGBA; - return true; - } - - if (!forceRGBA && sourcePixelFormat->BytesPerPixel == 3) { - *targetTextureFormat = TEXTURE_RGB_888; - *targetPixelFormat = &pixelFormatRGB; return false; } - *targetTextureFormat = TEXTURE_RGBA_8888; - *targetPixelFormat = &pixelFormatRGBA; - return false; -} + void TextureBuilder::PrepareSurface() + { + if (m_prepared) return; -void TextureBuilder::PrepareSurface() -{ - if (m_prepared) return; - - if (!m_surface && !m_filename.empty()) { - std::string filename = m_filename; - std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower); - if (ends_with_ci(filename, ".dds")) { - LoadDDS(); - } else { - LoadSurface(); - } - } - - TextureFormat targetTextureFormat; - unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight, numberOfMipMaps = 0, numberOfImages = 1; - if( m_surface ) { - SDL_PixelFormat *targetPixelFormat; - bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA); - - if (needConvert) { - if(m_textureType == TEXTURE_2D) { - SDL_Surface *s = SDL_ConvertSurface(m_surface.Get(), targetPixelFormat, SDL_SWSURFACE); - m_surface = SDLSurfacePtr::WrapNew(s); - } else if(m_textureType == TEXTURE_CUBE_MAP) { - assert(m_cubemap.size() == 6); - for(unsigned int i = 0; i < 6; ++i) { - SDL_Surface *s = SDL_ConvertSurface(m_cubemap[i].Get(), targetPixelFormat, SDL_SWSURFACE); - m_cubemap[i] = SDLSurfacePtr::WrapNew(s); - } + if (!m_surface && !m_filename.empty()) { + std::string filename = m_filename; + std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower); + if (ends_with_ci(filename, ".dds")) { + LoadDDS(); } else { - // Unknown texture type - assert(0); + LoadSurface(); } } - virtualWidth = actualWidth = m_surface->w; - virtualHeight = actualHeight = m_surface->h; - - if (m_potExtend) { - // extend to power-of-two if necessary - actualWidth = ceil_pow2(m_surface->w); - actualHeight = ceil_pow2(m_surface->h); - if (actualWidth != virtualWidth || actualHeight != virtualHeight) { - if(m_textureType == TEXTURE_2D) { - SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, - targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); - SDL_SetSurfaceBlendMode(m_surface.Get(), SDL_BLENDMODE_NONE); - SDL_BlitSurface(m_surface.Get(), 0, s, 0); + TextureFormat targetTextureFormat; + unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight, numberOfMipMaps = 0, numberOfImages = 1; + if (m_surface) { + SDL_PixelFormat *targetPixelFormat; + bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA); + if (needConvert) { + if (m_textureType == TEXTURE_2D) { + SDL_Surface *s = SDL_ConvertSurface(m_surface.Get(), targetPixelFormat, SDL_SWSURFACE); m_surface = SDLSurfacePtr::WrapNew(s); - } else if(m_textureType == TEXTURE_CUBE_MAP) { + } else if (m_textureType == TEXTURE_CUBE_MAP) { assert(m_cubemap.size() == 6); - for(unsigned int i = 0; i < 6; ++i) { - SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, - targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); - SDL_SetSurfaceBlendMode(m_cubemap[i].Get(), SDL_BLENDMODE_NONE); - SDL_BlitSurface(m_cubemap[i].Get(), 0, s, 0); + for (unsigned int i = 0; i < 6; ++i) { + SDL_Surface *s = SDL_ConvertSurface(m_cubemap[i].Get(), targetPixelFormat, SDL_SWSURFACE); m_cubemap[i] = SDLSurfacePtr::WrapNew(s); } } else { + // Unknown texture type assert(0); } } - } - else if (! m_filename.empty()) { - // power-of-two check - unsigned long width = ceil_pow2(m_surface->w); - unsigned long height = ceil_pow2(m_surface->h); - if (width != virtualWidth || height != virtualHeight) - Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str()); - } - } else { - switch(m_dds.GetTextureFormat()) { - case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break; - case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break; - default: - Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filename.c_str()); - assert(false); - return; - } + virtualWidth = actualWidth = m_surface->w; + virtualHeight = actualHeight = m_surface->h; - virtualWidth = actualWidth = m_dds.imgdata_.width; - virtualHeight = actualHeight = m_dds.imgdata_.height; - numberOfMipMaps = m_dds.imgdata_.numMipMaps; - numberOfImages = m_dds.imgdata_.numImages; - if(m_textureType == TEXTURE_CUBE_MAP) { - // Cube map must be fully defined (6 images) to be used correctly - assert(numberOfImages == 6); - } - } + if (m_potExtend) { + // extend to power-of-two if necessary + actualWidth = ceil_pow2(m_surface->w); + actualHeight = ceil_pow2(m_surface->h); + if (actualWidth != virtualWidth || actualHeight != virtualHeight) { + if (m_textureType == TEXTURE_2D) { + SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, + targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); + SDL_SetSurfaceBlendMode(m_surface.Get(), SDL_BLENDMODE_NONE); + SDL_BlitSurface(m_surface.Get(), 0, s, 0); - m_descriptor = TextureDescriptor( - targetTextureFormat, - vector2f(actualWidth,actualHeight), - vector2f(float(virtualWidth)/float(actualWidth),float(virtualHeight)/float(actualHeight)), - m_sampleMode, m_generateMipmaps, m_compressTextures, m_anisotropicFiltering, numberOfMipMaps, m_textureType); + m_surface = SDLSurfacePtr::WrapNew(s); + } else if (m_textureType == TEXTURE_CUBE_MAP) { + assert(m_cubemap.size() == 6); + for (unsigned int i = 0; i < 6; ++i) { + SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, + targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); + SDL_SetSurfaceBlendMode(m_cubemap[i].Get(), SDL_BLENDMODE_NONE); + SDL_BlitSurface(m_cubemap[i].Get(), 0, s, 0); + m_cubemap[i] = SDLSurfacePtr::WrapNew(s); + } + } else { + assert(0); + } + } + } else if (!m_filename.empty()) { + // power-of-two check + unsigned long width = ceil_pow2(m_surface->w); + unsigned long height = ceil_pow2(m_surface->h); - m_prepared = true; -} - -static size_t LoadDDSFromFile(const std::string &filename, PicoDDS::DDSImage& dds) -{ - RefCountedPtr filedata = FileSystem::gameDataFiles.ReadFile(filename); - if (!filedata) { - Output("LoadDDSFromFile: %s: could not read file\n", filename.c_str()); - return 0; - } - - // read the dds file - const size_t sizeRead = dds.Read( filedata->GetData(), filedata->GetSize() ); - return sizeRead; -} - -void TextureBuilder::LoadSurface() -{ - assert(!m_surface); - - SDLSurfacePtr s; - if(m_textureType == TEXTURE_2D) { - s = LoadSurfaceFromFile(m_filename); - if (! s) { - s = LoadSurfaceFromFile("textures/unknown.png"); - } - } else if(m_textureType == TEXTURE_CUBE_MAP) { - Output("LoadSurface: %s: cannot load non-DDS cubemaps\n", m_filename.c_str()); - } - - // XXX if we can't load the fallback texture, then what? - assert(s); - m_surface = s; -} - -void TextureBuilder::LoadDDS() -{ - assert(!m_dds.headerdone_); - LoadDDSFromFile(m_filename, m_dds); - - if (!m_dds.headerdone_) { - m_surface = LoadSurfaceFromFile("textures/unknown.png"); - } - // XXX if we can't load the fallback texture, then what? -} - -void TextureBuilder::UpdateTexture(Texture *texture) -{ - if( m_surface ) { - if(texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) { - texture->Update(m_surface->pixels, vector2f(m_surface->w,m_surface->h), m_descriptor.format, 0); - } else if(texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) { - assert(m_cubemap.size() == 6); - TextureCubeData tcd; - // Sequence of cube map face storage: +X -X +Y -Y -Z +Z - tcd.posX = m_cubemap[0]->pixels; - tcd.negX = m_cubemap[1]->pixels; - tcd.posY = m_cubemap[2]->pixels; - tcd.negY = m_cubemap[3]->pixels; - tcd.posZ = m_cubemap[4]->pixels; - tcd.negZ = m_cubemap[5]->pixels; - texture->Update(tcd, vector2f(m_cubemap[0]->w, m_cubemap[0]->h), m_descriptor.format, 0); + if (width != virtualWidth || height != virtualHeight) + Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str()); + } } else { - // Given texture and current texture don't have the same type! - assert(0); + switch (m_dds.GetTextureFormat()) { + case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break; + case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break; + default: + Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filename.c_str()); + assert(false); + return; + } + + virtualWidth = actualWidth = m_dds.imgdata_.width; + virtualHeight = actualHeight = m_dds.imgdata_.height; + numberOfMipMaps = m_dds.imgdata_.numMipMaps; + numberOfImages = m_dds.imgdata_.numImages; + if (m_textureType == TEXTURE_CUBE_MAP) { + // Cube map must be fully defined (6 images) to be used correctly + assert(numberOfImages == 6); + } } - } else { - assert(m_dds.headerdone_); - assert(m_descriptor.format == TEXTURE_DXT1 || m_descriptor.format == TEXTURE_DXT5); - if(texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) { - texture->Update(m_dds.imgdata_.imgData, vector2f(m_dds.imgdata_.width,m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps); - } else if(texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) { - TextureCubeData tcd; - // Size in bytes of each cube map face - size_t face_size = m_dds.imgdata_.size / m_dds.imgdata_.numImages; - // Sequence of cube map face storage: +X -X +Y -Y +Z -Z - tcd.posX = static_cast(m_dds.imgdata_.imgData + (0 * face_size)); - tcd.negX = static_cast(m_dds.imgdata_.imgData + (1 * face_size)); - tcd.posY = static_cast(m_dds.imgdata_.imgData + (2 * face_size)); - tcd.negY = static_cast(m_dds.imgdata_.imgData + (3 * face_size)); - tcd.posZ = static_cast(m_dds.imgdata_.imgData + (4 * face_size)); - tcd.negZ = static_cast(m_dds.imgdata_.imgData + (5 * face_size)); - texture->Update(tcd, vector2f(m_dds.imgdata_.width, m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps); + + m_descriptor = TextureDescriptor( + targetTextureFormat, + vector2f(actualWidth, actualHeight), + vector2f(float(virtualWidth) / float(actualWidth), float(virtualHeight) / float(actualHeight)), + m_sampleMode, m_generateMipmaps, m_compressTextures, m_anisotropicFiltering, numberOfMipMaps, m_textureType); + + m_prepared = true; + } + + static size_t LoadDDSFromFile(const std::string &filename, PicoDDS::DDSImage &dds) + { + RefCountedPtr filedata = FileSystem::gameDataFiles.ReadFile(filename); + if (!filedata) { + Output("LoadDDSFromFile: %s: could not read file\n", filename.c_str()); + return 0; + } + + // read the dds file + const size_t sizeRead = dds.Read(filedata->GetData(), filedata->GetSize()); + return sizeRead; + } + + void TextureBuilder::LoadSurface() + { + assert(!m_surface); + + SDLSurfacePtr s; + if (m_textureType == TEXTURE_2D) { + s = LoadSurfaceFromFile(m_filename); + if (!s) { + s = LoadSurfaceFromFile("textures/unknown.png"); + } + } else if (m_textureType == TEXTURE_CUBE_MAP) { + Output("LoadSurface: %s: cannot load non-DDS cubemaps\n", m_filename.c_str()); + } + + // XXX if we can't load the fallback texture, then what? + assert(s); + m_surface = s; + } + + void TextureBuilder::LoadDDS() + { + assert(!m_dds.headerdone_); + LoadDDSFromFile(m_filename, m_dds); + + if (!m_dds.headerdone_) { + m_surface = LoadSurfaceFromFile("textures/unknown.png"); + } + // XXX if we can't load the fallback texture, then what? + } + + void TextureBuilder::UpdateTexture(Texture *texture) + { + if (m_surface) { + if (texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) { + texture->Update(m_surface->pixels, vector2f(m_surface->w, m_surface->h), m_descriptor.format, 0); + } else if (texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) { + assert(m_cubemap.size() == 6); + TextureCubeData tcd; + // Sequence of cube map face storage: +X -X +Y -Y -Z +Z + tcd.posX = m_cubemap[0]->pixels; + tcd.negX = m_cubemap[1]->pixels; + tcd.posY = m_cubemap[2]->pixels; + tcd.negY = m_cubemap[3]->pixels; + tcd.posZ = m_cubemap[4]->pixels; + tcd.negZ = m_cubemap[5]->pixels; + texture->Update(tcd, vector2f(m_cubemap[0]->w, m_cubemap[0]->h), m_descriptor.format, 0); + } else { + // Given texture and current texture don't have the same type! + assert(0); + } } else { - // Given texture and current texture don't have the same type! - assert(0); + assert(m_dds.headerdone_); + assert(m_descriptor.format == TEXTURE_DXT1 || m_descriptor.format == TEXTURE_DXT5); + if (texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) { + texture->Update(m_dds.imgdata_.imgData, vector2f(m_dds.imgdata_.width, m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps); + } else if (texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) { + TextureCubeData tcd; + // Size in bytes of each cube map face + size_t face_size = m_dds.imgdata_.size / m_dds.imgdata_.numImages; + // Sequence of cube map face storage: +X -X +Y -Y +Z -Z + tcd.posX = static_cast(m_dds.imgdata_.imgData + (0 * face_size)); + tcd.negX = static_cast(m_dds.imgdata_.imgData + (1 * face_size)); + tcd.posY = static_cast(m_dds.imgdata_.imgData + (2 * face_size)); + tcd.negY = static_cast(m_dds.imgdata_.imgData + (3 * face_size)); + tcd.posZ = static_cast(m_dds.imgdata_.imgData + (4 * face_size)); + tcd.negZ = static_cast(m_dds.imgdata_.imgData + (5 * face_size)); + texture->Update(tcd, vector2f(m_dds.imgdata_.width, m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps); + } else { + // Given texture and current texture don't have the same type! + assert(0); + } } } -} -Texture *TextureBuilder::GetWhiteTexture(Renderer *r) -{ - return Model("textures/white.png").GetOrCreateTexture(r, "model"); -} + Texture *TextureBuilder::GetWhiteTexture(Renderer *r) + { + return Model("textures/white.png").GetOrCreateTexture(r, "model"); + } -Texture *TextureBuilder::GetTransparentTexture(Renderer *r) -{ - return Model("textures/transparent.png").GetOrCreateTexture(r, "model"); -} + Texture *TextureBuilder::GetTransparentTexture(Renderer *r) + { + return Model("textures/transparent.png").GetOrCreateTexture(r, "model"); + } -} +} // namespace Graphics diff --git a/src/graphics/TextureBuilder.h b/src/graphics/TextureBuilder.h index 8ad30eb94..524250056 100644 --- a/src/graphics/TextureBuilder.h +++ b/src/graphics/TextureBuilder.h @@ -4,98 +4,114 @@ #ifndef _TEXTUREBUILDER_H #define _TEXTUREBUILDER_H -#include -#include -#include "Texture.h" #include "Renderer.h" #include "SDLWrappers.h" +#include "Texture.h" +#include +#include #include "PicoDDS/PicoDDS.h" namespace Graphics { -class TextureBuilder { -public: - TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true); - TextureBuilder(const std::string &filename, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true, TextureType textureType = TEXTURE_2D); - ~TextureBuilder(); + class TextureBuilder { + public: + TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true); + TextureBuilder(const std::string &filename, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true, TextureType textureType = TEXTURE_2D); + ~TextureBuilder(); - static void Init(); + static void Init(); - // convenience constructors for common texture types - static TextureBuilder Model(const std::string &filename) { - return TextureBuilder(filename, LINEAR_REPEAT, true, false, false, true, true); - } - static TextureBuilder Normal(const std::string &filename) { - return TextureBuilder(filename, LINEAR_REPEAT, true, false, false, false, true); - } - static TextureBuilder Billboard(const std::string &filename) { - return TextureBuilder(filename, LINEAR_CLAMP, true, false, false, true, false); - } - static TextureBuilder UI(const std::string &filename) { - return TextureBuilder(filename, LINEAR_CLAMP, false, true, true, false, false); - } - static TextureBuilder Decal(const std::string &filename) { - return TextureBuilder(filename, LINEAR_CLAMP, true, true, false, true, true); - } - static TextureBuilder Raw(const std::string &filename) { - return TextureBuilder(filename, NEAREST_REPEAT, false, false, false, false, false); - } - static TextureBuilder Cube(const std::string &filename) { - return TextureBuilder(filename, LINEAR_CLAMP, true, true, false, true, false, TEXTURE_CUBE_MAP); - } - - const TextureDescriptor &GetDescriptor() { PrepareSurface(); return m_descriptor; } - - Texture *GetOrCreateTexture(Renderer *r, const std::string &type) { - if(m_filename.empty()) { - return CreateTexture(r); + // convenience constructors for common texture types + static TextureBuilder Model(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_REPEAT, true, false, false, true, true); + } + static TextureBuilder Normal(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_REPEAT, true, false, false, false, true); + } + static TextureBuilder Billboard(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_CLAMP, true, false, false, true, false); + } + static TextureBuilder UI(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_CLAMP, false, true, true, false, false); + } + static TextureBuilder Decal(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_CLAMP, true, true, false, true, true); + } + static TextureBuilder Raw(const std::string &filename) + { + return TextureBuilder(filename, NEAREST_REPEAT, false, false, false, false, false); + } + static TextureBuilder Cube(const std::string &filename) + { + return TextureBuilder(filename, LINEAR_CLAMP, true, true, false, true, false, TEXTURE_CUBE_MAP); } - SDL_LockMutex(m_textureLock); - Texture *t = r->GetCachedTexture(type, m_filename); - if (t) { SDL_UnlockMutex(m_textureLock); return t; } - t = CreateTexture(r); - r->AddCachedTexture(type, m_filename, t); - SDL_UnlockMutex(m_textureLock); - return t; - } - //commonly used dummy textures - static Texture *GetWhiteTexture(Renderer *); - static Texture *GetTransparentTexture(Renderer *); + const TextureDescriptor &GetDescriptor() + { + PrepareSurface(); + return m_descriptor; + } -private: - SDLSurfacePtr m_surface; - std::vector m_cubemap; - PicoDDS::DDSImage m_dds; - std::string m_filename; + Texture *GetOrCreateTexture(Renderer *r, const std::string &type) + { + if (m_filename.empty()) { + return CreateTexture(r); + } + SDL_LockMutex(m_textureLock); + Texture *t = r->GetCachedTexture(type, m_filename); + if (t) { + SDL_UnlockMutex(m_textureLock); + return t; + } + t = CreateTexture(r); + r->AddCachedTexture(type, m_filename, t); + SDL_UnlockMutex(m_textureLock); + return t; + } - TextureSampleMode m_sampleMode; - bool m_generateMipmaps; + //commonly used dummy textures + static Texture *GetWhiteTexture(Renderer *); + static Texture *GetTransparentTexture(Renderer *); - bool m_potExtend; - bool m_forceRGBA; - bool m_compressTextures; - bool m_anisotropicFiltering; - TextureType m_textureType; + private: + SDLSurfacePtr m_surface; + std::vector m_cubemap; + PicoDDS::DDSImage m_dds; + std::string m_filename; - TextureDescriptor m_descriptor; + TextureSampleMode m_sampleMode; + bool m_generateMipmaps; - Texture *CreateTexture(Renderer *r) { - Texture *t = r->CreateTexture(GetDescriptor()); - UpdateTexture(t); - return t; - } - void UpdateTexture(Texture *texture); // XXX pass src/dest rectangles - void PrepareSurface(); - bool m_prepared; + bool m_potExtend; + bool m_forceRGBA; + bool m_compressTextures; + bool m_anisotropicFiltering; + TextureType m_textureType; - void LoadSurface(); - void LoadDDS(); + TextureDescriptor m_descriptor; - static SDL_mutex *m_textureLock; -}; + Texture *CreateTexture(Renderer *r) + { + Texture *t = r->CreateTexture(GetDescriptor()); + UpdateTexture(t); + return t; + } + void UpdateTexture(Texture *texture); // XXX pass src/dest rectangles + void PrepareSurface(); + bool m_prepared; -} + void LoadSurface(); + void LoadDDS(); + + static SDL_mutex *m_textureLock; + }; + +} // namespace Graphics #endif diff --git a/src/graphics/Types.h b/src/graphics/Types.h index 4ae298fd3..7980e70ca 100644 --- a/src/graphics/Types.h +++ b/src/graphics/Types.h @@ -7,66 +7,66 @@ namespace Graphics { -typedef Uint32 AttributeSet; + typedef Uint32 AttributeSet; -//Vertex attribute semantic -enum VertexAttrib { - ATTRIB_NONE = 0, - ATTRIB_POSITION = (1u << 0), - ATTRIB_NORMAL = (1u << 1), - ATTRIB_DIFFUSE = (1u << 2), - ATTRIB_UV0 = (1u << 3), - //ATTRIB_UV1 = (1u << 4), - ATTRIB_TANGENT = (1u << 5), - //ATTRIB_BITANGENT = (1u << 6) - //etc. -}; + //Vertex attribute semantic + enum VertexAttrib { + ATTRIB_NONE = 0, + ATTRIB_POSITION = (1u << 0), + ATTRIB_NORMAL = (1u << 1), + ATTRIB_DIFFUSE = (1u << 2), + ATTRIB_UV0 = (1u << 3), + //ATTRIB_UV1 = (1u << 4), + ATTRIB_TANGENT = (1u << 5), + //ATTRIB_BITANGENT = (1u << 6) + //etc. + }; -enum VertexAttribFormat { - ATTRIB_FORMAT_NONE = 0, - ATTRIB_FORMAT_FLOAT2, - ATTRIB_FORMAT_FLOAT3, - ATTRIB_FORMAT_FLOAT4, - ATTRIB_FORMAT_UBYTE4 -}; + enum VertexAttribFormat { + ATTRIB_FORMAT_NONE = 0, + ATTRIB_FORMAT_FLOAT2, + ATTRIB_FORMAT_FLOAT3, + ATTRIB_FORMAT_FLOAT4, + ATTRIB_FORMAT_UBYTE4 + }; -enum BufferUsage { - BUFFER_USAGE_STATIC, - BUFFER_USAGE_DYNAMIC -}; + enum BufferUsage { + BUFFER_USAGE_STATIC, + BUFFER_USAGE_DYNAMIC + }; -enum BufferMapMode { - BUFFER_MAP_NONE, - BUFFER_MAP_WRITE, - BUFFER_MAP_READ -}; + enum BufferMapMode { + BUFFER_MAP_NONE, + BUFFER_MAP_WRITE, + BUFFER_MAP_READ + }; -enum PrimitiveType { - POINTS = 0, //GL_POINTS, - LINE_SINGLE, //GL_LINES, //draw one line per two vertices - LINE_LOOP, //GL_LINE_LOOP, //connect vertices, connect start & end - LINE_STRIP, //GL_LINE_STRIP, //connect vertices - TRIANGLES, //GL_TRIANGLES, - TRIANGLE_STRIP, //GL_TRIANGLE_STRIP, - TRIANGLE_FAN, //GL_TRIANGLE_FAN -}; + enum PrimitiveType { + POINTS = 0, //GL_POINTS, + LINE_SINGLE, //GL_LINES, //draw one line per two vertices + LINE_LOOP, //GL_LINE_LOOP, //connect vertices, connect start & end + LINE_STRIP, //GL_LINE_STRIP, //connect vertices + TRIANGLES, //GL_TRIANGLES, + TRIANGLE_STRIP, //GL_TRIANGLE_STRIP, + TRIANGLE_FAN, //GL_TRIANGLE_FAN + }; -enum BlendMode { - BLEND_SOLID, - BLEND_ADDITIVE, - BLEND_ALPHA, - BLEND_ALPHA_ONE, //"additive alpha" - BLEND_ALPHA_PREMULT, - BLEND_SET_ALPHA, // copy alpha channel - BLEND_DEST_ALPHA // XXX maybe crappy name -}; + enum BlendMode { + BLEND_SOLID, + BLEND_ADDITIVE, + BLEND_ALPHA, + BLEND_ALPHA_ONE, //"additive alpha" + BLEND_ALPHA_PREMULT, + BLEND_SET_ALPHA, // copy alpha channel + BLEND_DEST_ALPHA // XXX maybe crappy name + }; -enum FaceCullMode { - CULL_BACK, - CULL_FRONT, - CULL_NONE -}; + enum FaceCullMode { + CULL_BACK, + CULL_FRONT, + CULL_NONE + }; -} +} // namespace Graphics #endif // GRAPHICS_TYPES_H diff --git a/src/graphics/VertexArray.cpp b/src/graphics/VertexArray.cpp index a506e4650..573f360fa 100644 --- a/src/graphics/VertexArray.cpp +++ b/src/graphics/VertexArray.cpp @@ -5,142 +5,141 @@ namespace Graphics { -VertexArray::VertexArray(AttributeSet attribs, int size) -{ - PROFILE_SCOPED() - m_attribs = attribs; + VertexArray::VertexArray(AttributeSet attribs, int size) + { + PROFILE_SCOPED() + m_attribs = attribs; - if (size > 0) { - //would be rather weird without positions! - if (attribs & ATTRIB_POSITION) - position.reserve(size); - if (attribs & ATTRIB_DIFFUSE) - diffuse.reserve(size); - if (attribs & ATTRIB_NORMAL) - normal.reserve(size); - if (attribs & ATTRIB_UV0) - uv0.reserve(size); - if (attribs & ATTRIB_TANGENT) - tangent.reserve(size); + if (size > 0) { + //would be rather weird without positions! + if (attribs & ATTRIB_POSITION) + position.reserve(size); + if (attribs & ATTRIB_DIFFUSE) + diffuse.reserve(size); + if (attribs & ATTRIB_NORMAL) + normal.reserve(size); + if (attribs & ATTRIB_UV0) + uv0.reserve(size); + if (attribs & ATTRIB_TANGENT) + tangent.reserve(size); + } } -} -VertexArray::~VertexArray() -{ + VertexArray::~VertexArray() + { + } -} + void VertexArray::Clear() + { + position.clear(); + diffuse.clear(); + normal.clear(); + uv0.clear(); + tangent.clear(); + } -void VertexArray::Clear() -{ - position.clear(); - diffuse.clear(); - normal.clear(); - uv0.clear(); - tangent.clear(); -} + void VertexArray::Add(const vector3f &v) + { + position.push_back(v); + } -void VertexArray::Add(const vector3f &v) -{ - position.push_back(v); -} + void VertexArray::Add(const vector3f &v, const Color &c) + { + position.push_back(v); + diffuse.push_back(c); + } -void VertexArray::Add(const vector3f &v, const Color &c) -{ - position.push_back(v); - diffuse.push_back(c); -} + void VertexArray::Add(const vector3f &v, const Color &c, const vector3f &n) + { + position.push_back(v); + diffuse.push_back(c); + normal.push_back(n); + } -void VertexArray::Add(const vector3f &v, const Color &c, const vector3f &n) -{ - position.push_back(v); - diffuse.push_back(c); - normal.push_back(n); -} + void VertexArray::Add(const vector3f &v, const Color &c, const vector2f &uv) + { + position.push_back(v); + diffuse.push_back(c); + uv0.push_back(uv); + } -void VertexArray::Add(const vector3f &v, const Color &c, const vector2f &uv) -{ - position.push_back(v); - diffuse.push_back(c); - uv0.push_back(uv); -} + void VertexArray::Add(const vector3f &v, const vector2f &uv) + { + position.push_back(v); + uv0.push_back(uv); + } -void VertexArray::Add(const vector3f &v, const vector2f &uv) -{ - position.push_back(v); - uv0.push_back(uv); -} + void VertexArray::Add(const vector3f &v, const vector3f &n) + { + position.push_back(v); + normal.push_back(n); + } -void VertexArray::Add(const vector3f &v, const vector3f &n) -{ - position.push_back(v); - normal.push_back(n); -} + void VertexArray::Add(const vector3f &v, const vector3f &n, const vector2f &uv) + { + position.push_back(v); + normal.push_back(n); + uv0.push_back(uv); + } -void VertexArray::Add(const vector3f &v, const vector3f &n, const vector2f &uv) -{ - position.push_back(v); - normal.push_back(n); - uv0.push_back(uv); -} + void VertexArray::Add(const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang) + { + position.push_back(v); + normal.push_back(n); + uv0.push_back(uv); + tangent.push_back(tang); + } -void VertexArray::Add(const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang) -{ - position.push_back(v); - normal.push_back(n); - uv0.push_back(uv); - tangent.push_back(tang); -} + void VertexArray::Set(const Uint32 idx, const vector3f &v) + { + position[idx] = v; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v) -{ - position[idx] = v; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c) + { + position[idx] = v; + diffuse[idx] = c; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c) -{ - position[idx] = v; - diffuse[idx] = c; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c, const vector3f &n) + { + position[idx] = v; + diffuse[idx] = c; + normal[idx] = n; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c, const vector3f &n) -{ - position[idx] = v; - diffuse[idx] = c; - normal[idx] = n; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c, const vector2f &uv) + { + position[idx] = v; + diffuse[idx] = c; + uv0[idx] = uv; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const Color &c, const vector2f &uv) -{ - position[idx] = v; - diffuse[idx] = c; - uv0[idx] = uv; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector2f &uv) + { + position[idx] = v; + uv0[idx] = uv; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector2f &uv) -{ - position[idx] = v; - uv0[idx] = uv; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n) + { + position[idx] = v; + normal[idx] = n; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n) -{ - position[idx] = v; - normal[idx] = n; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv) + { + position[idx] = v; + normal[idx] = n; + uv0[idx] = uv; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv) -{ - position[idx] = v; - normal[idx] = n; - uv0[idx] = uv; -} + void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang) + { + position[idx] = v; + normal[idx] = n; + uv0[idx] = uv; + tangent[idx] = tang; + } -void VertexArray::Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang) -{ - position[idx] = v; - normal[idx] = n; - uv0[idx] = uv; - tangent[idx] = tang; -} - -} +} // namespace Graphics diff --git a/src/graphics/VertexArray.h b/src/graphics/VertexArray.h index 7c3dd387d..e0b63a7a2 100644 --- a/src/graphics/VertexArray.h +++ b/src/graphics/VertexArray.h @@ -4,67 +4,67 @@ #ifndef _VERTEXARRAY_H #define _VERTEXARRAY_H -#include "libs.h" #include "Types.h" +#include "libs.h" namespace Graphics { -/* + /* * VertexArray is a multi-purpose vertex container. Users specify * the attributes they intend to use and then add vertices. Renderers * do whatever they need to do with regards to the attribute set. * This is not optimized for high performance drawing, but okay for simple * cases. */ -class VertexArray { -public: - //specify attributes to be used, additionally reserve space for vertices - VertexArray(AttributeSet attribs, int size=0); - ~VertexArray(); + class VertexArray { + public: + //specify attributes to be used, additionally reserve space for vertices + VertexArray(AttributeSet attribs, int size = 0); + ~VertexArray(); - //check presence of an attribute - __inline bool HasAttrib(const VertexAttrib v) const { return (m_attribs & v) != 0; } - __inline Uint32 GetNumVerts() const { return static_cast(position.size()); } - __inline AttributeSet GetAttributeSet() const { return m_attribs; } + //check presence of an attribute + __inline bool HasAttrib(const VertexAttrib v) const { return (m_attribs & v) != 0; } + __inline Uint32 GetNumVerts() const { return static_cast(position.size()); } + __inline AttributeSet GetAttributeSet() const { return m_attribs; } - __inline bool IsEmpty() const { return position.empty(); } + __inline bool IsEmpty() const { return position.empty(); } - //removes vertices, does not deallocate space - void Clear(); + //removes vertices, does not deallocate space + void Clear(); - // don't mix these - void Add(const vector3f &v); - void Add(const vector3f &v, const Color &c); - void Add(const vector3f &v, const Color &c, const vector3f &n); - void Add(const vector3f &v, const Color &c, const vector2f &uv); - void Add(const vector3f &v, const vector2f &uv); - void Add(const vector3f &v, const vector3f &n); - void Add(const vector3f &v, const vector3f &n, const vector2f &uv); - void Add(const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang); - //virtual void Reserve(unsigned int howmuch) + // don't mix these + void Add(const vector3f &v); + void Add(const vector3f &v, const Color &c); + void Add(const vector3f &v, const Color &c, const vector3f &n); + void Add(const vector3f &v, const Color &c, const vector2f &uv); + void Add(const vector3f &v, const vector2f &uv); + void Add(const vector3f &v, const vector3f &n); + void Add(const vector3f &v, const vector3f &n, const vector2f &uv); + void Add(const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang); + //virtual void Reserve(unsigned int howmuch) - // don't mix these - void Set(const Uint32 idx, const vector3f &v); - void Set(const Uint32 idx, const vector3f &v, const Color &c); - void Set(const Uint32 idx, const vector3f &v, const Color &c, const vector3f &normal); - void Set(const Uint32 idx, const vector3f &v, const Color &c, const vector2f &uv); - void Set(const Uint32 idx, const vector3f &v, const vector2f &uv); - void Set(const Uint32 idx, const vector3f &v, const vector3f &n); - void Set(const Uint32 idx, const vector3f &v, const vector3f &normal, const vector2f &uv); - void Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang); + // don't mix these + void Set(const Uint32 idx, const vector3f &v); + void Set(const Uint32 idx, const vector3f &v, const Color &c); + void Set(const Uint32 idx, const vector3f &v, const Color &c, const vector3f &normal); + void Set(const Uint32 idx, const vector3f &v, const Color &c, const vector2f &uv); + void Set(const Uint32 idx, const vector3f &v, const vector2f &uv); + void Set(const Uint32 idx, const vector3f &v, const vector3f &n); + void Set(const Uint32 idx, const vector3f &v, const vector3f &normal, const vector2f &uv); + void Set(const Uint32 idx, const vector3f &v, const vector3f &n, const vector2f &uv, const vector3f &tang); - //could make these private, but it is nice to be able to - //add attributes separately... - std::vector position; - std::vector normal; - std::vector diffuse; - std::vector uv0; - std::vector tangent; + //could make these private, but it is nice to be able to + //add attributes separately... + std::vector position; + std::vector normal; + std::vector diffuse; + std::vector uv0; + std::vector tangent; -private: - AttributeSet m_attribs; -}; + private: + AttributeSet m_attribs; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/VertexBuffer.cpp b/src/graphics/VertexBuffer.cpp index 51a5d3499..cc3b4868d 100644 --- a/src/graphics/VertexBuffer.cpp +++ b/src/graphics/VertexBuffer.cpp @@ -5,110 +5,110 @@ namespace Graphics { -Uint32 VertexBufferDesc::GetAttribSize(VertexAttribFormat f) -{ - switch (f) { - case ATTRIB_FORMAT_FLOAT2: - return 8; - case ATTRIB_FORMAT_FLOAT3: - return 12; - case ATTRIB_FORMAT_FLOAT4: - return 16; - case ATTRIB_FORMAT_UBYTE4: - return 4; - default: + Uint32 VertexBufferDesc::GetAttribSize(VertexAttribFormat f) + { + switch (f) { + case ATTRIB_FORMAT_FLOAT2: + return 8; + case ATTRIB_FORMAT_FLOAT3: + return 12; + case ATTRIB_FORMAT_FLOAT4: + return 16; + case ATTRIB_FORMAT_UBYTE4: + return 4; + default: + return 0; + } + } + + VertexBufferDesc::VertexBufferDesc() : + numVertices(0), + stride(0), + usage(BUFFER_USAGE_STATIC) + { + for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { + attrib[i].semantic = ATTRIB_NONE; + attrib[i].format = ATTRIB_FORMAT_NONE; + attrib[i].offset = 0; + } + + assert(sizeof(vector2f) == 8); + assert(sizeof(vector3f) == 12); + assert(sizeof(Color4ub) == 4); + } + + Uint32 VertexBufferDesc::GetOffset(VertexAttrib attr) const + { + for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { + if (attrib[i].semantic == attr) + return attrib[i].offset; + } + + //attrib not found + assert(false); return 0; } -} -VertexBufferDesc::VertexBufferDesc() - : numVertices(0) - , stride(0) - , usage(BUFFER_USAGE_STATIC) -{ - for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { - attrib[i].semantic = ATTRIB_NONE; - attrib[i].format = ATTRIB_FORMAT_NONE; - attrib[i].offset = 0; + Uint32 VertexBufferDesc::CalculateOffset(const VertexBufferDesc &desc, VertexAttrib attr) + { + Uint32 offs = 0; + for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { + if (desc.attrib[i].semantic == attr) + return offs; + offs += GetAttribSize(desc.attrib[i].format); + } + + //attrib not found + assert(false); + return 0; } - assert(sizeof(vector2f) == 8); - assert(sizeof(vector3f) == 12); - assert(sizeof(Color4ub) == 4); -} - -Uint32 VertexBufferDesc::GetOffset(VertexAttrib attr) const -{ - for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { - if (attrib[i].semantic == attr) - return attrib[i].offset; + VertexBuffer::~VertexBuffer() + { } - //attrib not found - assert(false); - return 0; -} - -Uint32 VertexBufferDesc::CalculateOffset(const VertexBufferDesc &desc, VertexAttrib attr) -{ - Uint32 offs = 0; - for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { - if (desc.attrib[i].semantic == attr) - return offs; - offs += GetAttribSize(desc.attrib[i].format); + bool VertexBuffer::SetVertexCount(Uint32 v) + { + if (v <= m_desc.numVertices) { + m_size = v; + return true; + } + return false; } - //attrib not found - assert(false); - return 0; -} - -VertexBuffer::~VertexBuffer() -{ -} - -bool VertexBuffer::SetVertexCount(Uint32 v) -{ - if (v <= m_desc.numVertices) { - m_size = v; - return true; + // ------------------------------------------------------------ + IndexBuffer::IndexBuffer(Uint32 size, BufferUsage usage) : + Mappable(size), + m_indexCount(size), + m_usage(usage) + { } - return false; -} -// ------------------------------------------------------------ -IndexBuffer::IndexBuffer(Uint32 size, BufferUsage usage) - : Mappable(size) - , m_indexCount(size) - , m_usage(usage) -{ -} + IndexBuffer::~IndexBuffer() + { + } -IndexBuffer::~IndexBuffer() -{ -} + void IndexBuffer::SetIndexCount(Uint32 ic) + { + assert(ic <= GetSize()); + m_indexCount = std::min(ic, GetSize()); + } -void IndexBuffer::SetIndexCount(Uint32 ic) -{ - assert(ic <= GetSize()); - m_indexCount = std::min(ic, GetSize()); -} + // ------------------------------------------------------------ + InstanceBuffer::InstanceBuffer(Uint32 size, BufferUsage usage) : + Mappable(size), + m_usage(usage) + { + } -// ------------------------------------------------------------ -InstanceBuffer::InstanceBuffer(Uint32 size, BufferUsage usage) - : Mappable(size) - , m_usage(usage) -{ -} + InstanceBuffer::~InstanceBuffer() + { + } -InstanceBuffer::~InstanceBuffer() -{ -} + void InstanceBuffer::SetInstanceCount(const Uint32 ic) + { + assert(ic <= GetSize()); + m_instanceCount = std::min(ic, GetSize()); + } -void InstanceBuffer::SetInstanceCount(const Uint32 ic) -{ - assert(ic <= GetSize()); - m_instanceCount = std::min(ic, GetSize()); -} - -} +} // namespace Graphics diff --git a/src/graphics/VertexBuffer.h b/src/graphics/VertexBuffer.h index c0dc0fd2c..fba428f76 100644 --- a/src/graphics/VertexBuffer.h +++ b/src/graphics/VertexBuffer.h @@ -18,131 +18,138 @@ * * Expansion possibilities: range-based Map */ -#include "libs.h" #include "Types.h" +#include "libs.h" namespace Graphics { -// fwd declaration -class VertexArray; + // fwd declaration + class VertexArray; -const Uint32 MAX_ATTRIBS = 8; + const Uint32 MAX_ATTRIBS = 8; -struct VertexAttribDesc { - //position, texcoord, normal etc. - VertexAttrib semantic; - //float3, float2 etc. - VertexAttribFormat format; - //byte offset of the attribute, if zero this - //is automatically filled for created buffers - Uint32 offset; -}; + struct VertexAttribDesc { + //position, texcoord, normal etc. + VertexAttrib semantic; + //float3, float2 etc. + VertexAttribFormat format; + //byte offset of the attribute, if zero this + //is automatically filled for created buffers + Uint32 offset; + }; -struct VertexBufferDesc { - VertexBufferDesc(); - //byte offset of an existing attribute - Uint32 GetOffset(VertexAttrib) const; + struct VertexBufferDesc { + VertexBufferDesc(); + //byte offset of an existing attribute + Uint32 GetOffset(VertexAttrib) const; - //used internally for calculating offsets - static Uint32 CalculateOffset(const VertexBufferDesc&, VertexAttrib); - static Uint32 GetAttribSize(VertexAttribFormat); + //used internally for calculating offsets + static Uint32 CalculateOffset(const VertexBufferDesc &, VertexAttrib); + static Uint32 GetAttribSize(VertexAttribFormat); - //semantic ATTRIB_NONE ends description (when not using all attribs) - VertexAttribDesc attrib[MAX_ATTRIBS]; - Uint32 numVertices; - //byte size of one vertex, if zero this is - //automatically calculated for created buffers - Uint32 stride; - BufferUsage usage; -}; + //semantic ATTRIB_NONE ends description (when not using all attribs) + VertexAttribDesc attrib[MAX_ATTRIBS]; + Uint32 numVertices; + //byte size of one vertex, if zero this is + //automatically calculated for created buffers + Uint32 stride; + BufferUsage usage; + }; -class Mappable : public RefCounted { -public: - virtual ~Mappable() { } - virtual void Unmap() = 0; + class Mappable : public RefCounted { + public: + virtual ~Mappable() {} + virtual void Unmap() = 0; - inline Uint32 GetSize() const { return m_size; } - inline Uint32 GetCapacity() const { return m_capacity; } + inline Uint32 GetSize() const { return m_size; } + inline Uint32 GetCapacity() const { return m_capacity; } -protected: - explicit Mappable(const Uint32 size) : m_mapMode(BUFFER_MAP_NONE), m_size(size), m_capacity(size) { } - BufferMapMode m_mapMode; //tracking map state + protected: + explicit Mappable(const Uint32 size) : + m_mapMode(BUFFER_MAP_NONE), + m_size(size), + m_capacity(size) {} + BufferMapMode m_mapMode; //tracking map state - // size is the current number of elements in the buffer - Uint32 m_size; - // capacity is the maximum number of elements that can be put in the buffer - Uint32 m_capacity; -}; + // size is the current number of elements in the buffer + Uint32 m_size; + // capacity is the maximum number of elements that can be put in the buffer + Uint32 m_capacity; + }; -class VertexBuffer : public Mappable { -public: - VertexBuffer(const VertexBufferDesc &desc) : Mappable(desc.numVertices), m_desc(desc) {} - virtual ~VertexBuffer(); - const VertexBufferDesc &GetDesc() const { return m_desc; } + class VertexBuffer : public Mappable { + public: + VertexBuffer(const VertexBufferDesc &desc) : + Mappable(desc.numVertices), + m_desc(desc) {} + virtual ~VertexBuffer(); + const VertexBufferDesc &GetDesc() const { return m_desc; } - template T *Map(BufferMapMode mode) { - return reinterpret_cast(MapInternal(mode)); - } + template + T *Map(BufferMapMode mode) + { + return reinterpret_cast(MapInternal(mode)); + } - //Vertex count used for rendering. - //By default the maximum set in description, but - //you may set a smaller count for partial rendering - bool SetVertexCount(Uint32); + //Vertex count used for rendering. + //By default the maximum set in description, but + //you may set a smaller count for partial rendering + bool SetVertexCount(Uint32); - // copies the contents of the VertexArray into the buffer - virtual bool Populate(const VertexArray &) = 0; + // copies the contents of the VertexArray into the buffer + virtual bool Populate(const VertexArray &) = 0; - // change the buffer data without mapping - virtual void BufferData(const size_t, void*) = 0; + // change the buffer data without mapping + virtual void BufferData(const size_t, void *) = 0; - virtual void Bind() = 0; - virtual void Release() = 0; + virtual void Bind() = 0; + virtual void Release() = 0; -protected: - virtual Uint8 *MapInternal(BufferMapMode) = 0; - VertexBufferDesc m_desc; -}; + protected: + virtual Uint8 *MapInternal(BufferMapMode) = 0; + VertexBufferDesc m_desc; + }; -// Index buffer -class IndexBuffer : public Mappable { -public: - IndexBuffer(Uint32 size, BufferUsage); - virtual ~IndexBuffer(); - virtual Uint32 *Map(BufferMapMode) = 0; + // Index buffer + class IndexBuffer : public Mappable { + public: + IndexBuffer(Uint32 size, BufferUsage); + virtual ~IndexBuffer(); + virtual Uint32 *Map(BufferMapMode) = 0; - // change the buffer data without mapping - virtual void BufferData(const size_t, void*) = 0; + // change the buffer data without mapping + virtual void BufferData(const size_t, void *) = 0; - Uint32 GetIndexCount() const { return m_indexCount; } - void SetIndexCount(Uint32); - BufferUsage GetUsage() const { return m_usage; } + Uint32 GetIndexCount() const { return m_indexCount; } + void SetIndexCount(Uint32); + BufferUsage GetUsage() const { return m_usage; } - virtual void Bind() = 0; - virtual void Release() = 0; + virtual void Bind() = 0; + virtual void Release() = 0; -protected: - Uint32 m_indexCount; - BufferUsage m_usage; -}; + protected: + Uint32 m_indexCount; + BufferUsage m_usage; + }; -// Instance buffer -class InstanceBuffer : public Mappable { -public: - InstanceBuffer(Uint32 size, BufferUsage); - virtual ~InstanceBuffer(); - virtual matrix4x4f* Map(BufferMapMode) = 0; + // Instance buffer + class InstanceBuffer : public Mappable { + public: + InstanceBuffer(Uint32 size, BufferUsage); + virtual ~InstanceBuffer(); + virtual matrix4x4f *Map(BufferMapMode) = 0; - Uint32 GetInstanceCount() const { return m_instanceCount; } - void SetInstanceCount(const Uint32); - BufferUsage GetUsage() const { return m_usage; } + Uint32 GetInstanceCount() const { return m_instanceCount; } + void SetInstanceCount(const Uint32); + BufferUsage GetUsage() const { return m_usage; } - virtual void Bind() = 0; - virtual void Release() = 0; + virtual void Bind() = 0; + virtual void Release() = 0; -protected: - Uint32 m_instanceCount; - BufferUsage m_usage; -}; + protected: + Uint32 m_instanceCount; + BufferUsage m_usage; + }; -} +} // namespace Graphics #endif // GRAPHICS_VERTEXBUFFER_H diff --git a/src/graphics/dummy/MaterialDummy.h b/src/graphics/dummy/MaterialDummy.h index 21e2f59fc..185c4b623 100644 --- a/src/graphics/dummy/MaterialDummy.h +++ b/src/graphics/dummy/MaterialDummy.h @@ -16,17 +16,17 @@ namespace Graphics { class Material : public Graphics::Material { public: - Material() { } + Material() {} // Create an appropriate program for this material. virtual Program *CreateProgram(const MaterialDescriptor &) { return nullptr; } // bind textures, set uniforms virtual void Apply() override {} virtual void Unapply() override {} virtual bool IsProgramLoaded() const override final { return false; } - virtual void SetProgram(Program *p) { } - virtual void SetCommonUniforms(const matrix4x4f& mv, const matrix4x4f& proj) override {} + virtual void SetProgram(Program *p) {} + virtual void SetCommonUniforms(const matrix4x4f &mv, const matrix4x4f &proj) override {} }; - } -} + } // namespace Dummy +} // namespace Graphics #endif diff --git a/src/graphics/dummy/RenderStateDummy.h b/src/graphics/dummy/RenderStateDummy.h index 01c646e57..2fadbabf6 100644 --- a/src/graphics/dummy/RenderStateDummy.h +++ b/src/graphics/dummy/RenderStateDummy.h @@ -7,14 +7,15 @@ #include "graphics/RenderState.h" namespace Graphics { -namespace Dummy { + namespace Dummy { -class RenderState : public Graphics::RenderState { -public: - RenderState(const RenderStateDesc &d) : Graphics::RenderState(d) {} - void Apply() {} -}; + class RenderState : public Graphics::RenderState { + public: + RenderState(const RenderStateDesc &d) : + Graphics::RenderState(d) {} + void Apply() {} + }; -} -} + } // namespace Dummy +} // namespace Graphics #endif diff --git a/src/graphics/dummy/RenderTargetDummy.h b/src/graphics/dummy/RenderTargetDummy.h index b1b65d1b2..9a3ab207a 100644 --- a/src/graphics/dummy/RenderTargetDummy.h +++ b/src/graphics/dummy/RenderTargetDummy.h @@ -8,29 +8,30 @@ namespace Graphics { -class RendererDummy; + class RendererDummy; -namespace Dummy { + namespace Dummy { -class RenderTarget : public Graphics::RenderTarget { -public: - virtual Texture *GetColorTexture() const { return m_colorTexture.Get(); } - virtual Texture *GetDepthTexture() const { return m_depthTexture.Get(); } - virtual void SetCubeFaceTexture(const Uint32 face, Texture* t) final { m_colorTexture.Reset(t); } - virtual void SetColorTexture(Texture* t) { m_colorTexture.Reset(t); } - virtual void SetDepthTexture(Texture* t) { m_depthTexture.Reset(t); } + class RenderTarget : public Graphics::RenderTarget { + public: + virtual Texture *GetColorTexture() const { return m_colorTexture.Get(); } + virtual Texture *GetDepthTexture() const { return m_depthTexture.Get(); } + virtual void SetCubeFaceTexture(const Uint32 face, Texture *t) final { m_colorTexture.Reset(t); } + virtual void SetColorTexture(Texture *t) { m_colorTexture.Reset(t); } + virtual void SetDepthTexture(Texture *t) { m_depthTexture.Reset(t); } -protected: - friend class Graphics::RendererDummy; - RenderTarget(const RenderTargetDesc &d) : Graphics::RenderTarget(d) {} + protected: + friend class Graphics::RendererDummy; + RenderTarget(const RenderTargetDesc &d) : + Graphics::RenderTarget(d) {} -private: - RefCountedPtr m_colorTexture; - RefCountedPtr m_depthTexture; -}; + private: + RefCountedPtr m_colorTexture; + RefCountedPtr m_depthTexture; + }; -} + } // namespace Dummy -} +} // namespace Graphics #endif diff --git a/src/graphics/dummy/RendererDummy.cpp b/src/graphics/dummy/RendererDummy.cpp index ca423cfd4..67f30757d 100644 --- a/src/graphics/dummy/RendererDummy.cpp +++ b/src/graphics/dummy/RendererDummy.cpp @@ -5,12 +5,14 @@ namespace Graphics { -static Renderer *CreateRenderer(const Settings &vs) { - return new RendererDummy(); -} + static Renderer *CreateRenderer(const Settings &vs) + { + return new RendererDummy(); + } -void RendererDummy::RegisterRenderer() { - Graphics::RegisterRenderer(Graphics::RENDERER_DUMMY, CreateRenderer); -} + void RendererDummy::RegisterRenderer() + { + Graphics::RegisterRenderer(Graphics::RENDERER_DUMMY, CreateRenderer); + } -} +} // namespace Graphics diff --git a/src/graphics/dummy/RendererDummy.h b/src/graphics/dummy/RendererDummy.h index d68683199..8f4ea34de 100644 --- a/src/graphics/dummy/RendererDummy.h +++ b/src/graphics/dummy/RendererDummy.h @@ -8,95 +8,95 @@ #include "graphics/Renderer.h" #include "graphics/dummy/MaterialDummy.h" -#include "graphics/dummy/TextureDummy.h" #include "graphics/dummy/RenderStateDummy.h" #include "graphics/dummy/RenderTargetDummy.h" +#include "graphics/dummy/TextureDummy.h" #include "graphics/dummy/VertexBufferDummy.h" namespace Graphics { -class RendererDummy : public Renderer -{ -public: - static void RegisterRenderer(); + class RendererDummy : public Renderer { + public: + static void RegisterRenderer(); - RendererDummy() : Renderer(0, 0, 0), - m_identity(matrix4x4f::Identity()) - {} + RendererDummy() : + Renderer(0, 0, 0), + m_identity(matrix4x4f::Identity()) + {} - virtual const char *GetName() const override final { return "Dummy"; } - virtual RendererType GetRendererType() const override final { return RENDERER_DUMMY; } - virtual bool SupportsInstancing() override final { return false; } - virtual int GetMaximumNumberAASamples() const override final { return 0; } - virtual bool GetNearFarRange(float &near_, float &far_) const override final { return true; } + virtual const char *GetName() const override final { return "Dummy"; } + virtual RendererType GetRendererType() const override final { return RENDERER_DUMMY; } + virtual bool SupportsInstancing() override final { return false; } + virtual int GetMaximumNumberAASamples() const override final { return 0; } + virtual bool GetNearFarRange(float &near_, float &far_) const override final { return true; } - virtual bool BeginFrame() override final { return true; } - virtual bool EndFrame() override final { return true; } - virtual bool SwapBuffers() override final { return true; } + virtual bool BeginFrame() override final { return true; } + virtual bool EndFrame() override final { return true; } + virtual bool SwapBuffers() override final { return true; } - virtual bool SetRenderState(RenderState*) override final { return true; } - virtual bool SetRenderTarget(RenderTarget*) override final { return true; } + virtual bool SetRenderState(RenderState *) override final { return true; } + virtual bool SetRenderTarget(RenderTarget *) override final { return true; } - virtual bool SetDepthRange(double znear, double zfar) override final { return true; } + virtual bool SetDepthRange(double znear, double zfar) override final { return true; } - virtual bool ClearScreen() override final { return true; } - virtual bool ClearDepthBuffer() override final { return true; } - virtual bool SetClearColor(const Color &c) override final { return true; } + virtual bool ClearScreen() override final { return true; } + virtual bool ClearDepthBuffer() override final { return true; } + virtual bool SetClearColor(const Color &c) override final { return true; } - virtual bool SetViewport(int x, int y, int width, int height) override final { return true; } + virtual bool SetViewport(int x, int y, int width, int height) override final { return true; } - virtual bool SetTransform(const matrix4x4d &m) override final { return true; } - virtual bool SetTransform(const matrix4x4f &m) override final { return true; } - virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) override final { return true; } - virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) override final { return true; } - virtual bool SetProjection(const matrix4x4f &m) override final { return true; } + virtual bool SetTransform(const matrix4x4d &m) override final { return true; } + virtual bool SetTransform(const matrix4x4f &m) override final { return true; } + virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) override final { return true; } + virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) override final { return true; } + virtual bool SetProjection(const matrix4x4f &m) override final { return true; } - virtual bool SetWireFrameMode(bool enabled) override final { return true; } + virtual bool SetWireFrameMode(bool enabled) override final { return true; } - virtual bool SetLights(Uint32 numlights, const Light *l) override final { return true; } - virtual Uint32 GetNumLights() const override final { return 1; } - virtual bool SetAmbientColor(const Color &c) override final { return true; } + virtual bool SetLights(Uint32 numlights, const Light *l) override final { return true; } + virtual Uint32 GetNumLights() const override final { return 1; } + virtual bool SetAmbientColor(const Color &c) override final { return true; } - virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) override final { return true; } + virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) override final { return true; } - virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type=TRIANGLES) override final { return true; } - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) override final { return true; } - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) override final { return true; } - virtual bool DrawBuffer(VertexBuffer*, RenderState*, Material*, PrimitiveType) override final { return true; } - virtual bool DrawBufferIndexed(VertexBuffer*, IndexBuffer*, RenderState*, Material*, PrimitiveType) override final { return true; } - virtual bool DrawBufferInstanced(VertexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType type=TRIANGLES) override final { return true; } - virtual bool DrawBufferIndexedInstanced(VertexBuffer*, IndexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType=TRIANGLES) override final { return true; } + virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type = TRIANGLES) override final { return true; } + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) override final { return true; } + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) override final { return true; } + virtual bool DrawBuffer(VertexBuffer *, RenderState *, Material *, PrimitiveType) override final { return true; } + virtual bool DrawBufferIndexed(VertexBuffer *, IndexBuffer *, RenderState *, Material *, PrimitiveType) override final { return true; } + virtual bool DrawBufferInstanced(VertexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType type = TRIANGLES) override final { return true; } + virtual bool DrawBufferIndexedInstanced(VertexBuffer *, IndexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType = TRIANGLES) override final { return true; } - virtual Material *CreateMaterial(const MaterialDescriptor &d) override final { return new Graphics::Dummy::Material(); } - virtual Texture *CreateTexture(const TextureDescriptor &d) override final { return new Graphics::TextureDummy(d); } - virtual RenderState *CreateRenderState(const RenderStateDesc &d) override final { return new Graphics::Dummy::RenderState(d); } - virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &d) override final { return new Graphics::Dummy::RenderTarget(d); } - virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc &d) override final { return new Graphics::Dummy::VertexBuffer(d); } - virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage bu) override final { return new Graphics::Dummy::IndexBuffer(size, bu); } - virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage bu) override final { return new Graphics::Dummy::InstanceBuffer(size, bu); } + virtual Material *CreateMaterial(const MaterialDescriptor &d) override final { return new Graphics::Dummy::Material(); } + virtual Texture *CreateTexture(const TextureDescriptor &d) override final { return new Graphics::TextureDummy(d); } + virtual RenderState *CreateRenderState(const RenderStateDesc &d) override final { return new Graphics::Dummy::RenderState(d); } + virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &d) override final { return new Graphics::Dummy::RenderTarget(d); } + virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc &d) override final { return new Graphics::Dummy::VertexBuffer(d); } + virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage bu) override final { return new Graphics::Dummy::IndexBuffer(size, bu); } + virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage bu) override final { return new Graphics::Dummy::InstanceBuffer(size, bu); } - virtual bool ReloadShaders() override final { return true; } + virtual bool ReloadShaders() override final { return true; } - virtual const matrix4x4f& GetCurrentModelView() const override final { return m_identity; } - virtual const matrix4x4f& GetCurrentProjection() const override final { return m_identity; } - virtual void GetCurrentViewport(Sint32 *vp) const override final { } + virtual const matrix4x4f &GetCurrentModelView() const override final { return m_identity; } + virtual const matrix4x4f &GetCurrentProjection() const override final { return m_identity; } + virtual void GetCurrentViewport(Sint32 *vp) const override final {} - virtual void SetMatrixMode(MatrixMode mm) override final {} - virtual void PushMatrix() override final {} - virtual void PopMatrix() override final {} - virtual void LoadIdentity() override final {} - virtual void LoadMatrix(const matrix4x4f &m) override final {} - virtual void Translate( const float x, const float y, const float z ) override final {} - virtual void Scale( const float x, const float y, const float z ) override final {} + virtual void SetMatrixMode(MatrixMode mm) override final {} + virtual void PushMatrix() override final {} + virtual void PopMatrix() override final {} + virtual void LoadIdentity() override final {} + virtual void LoadMatrix(const matrix4x4f &m) override final {} + virtual void Translate(const float x, const float y, const float z) override final {} + virtual void Scale(const float x, const float y, const float z) override final {} -protected: - virtual void PushState() override final {} - virtual void PopState() override final {} + protected: + virtual void PushState() override final {} + virtual void PopState() override final {} -private: - const matrix4x4f m_identity; -}; + private: + const matrix4x4f m_identity; + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/dummy/TextureDummy.h b/src/graphics/dummy/TextureDummy.h index 236843ec8..158950f3e 100644 --- a/src/graphics/dummy/TextureDummy.h +++ b/src/graphics/dummy/TextureDummy.h @@ -8,23 +8,24 @@ namespace Graphics { -class TextureDummy : public Texture { -public: - virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {} - virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {} + class TextureDummy : public Texture { + public: + virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {} + virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {} - void Bind() override {} - void Unbind() override {} + void Bind() override {} + void Unbind() override {} - virtual void SetSampleMode(TextureSampleMode) override {} - virtual void BuildMipmaps() override {} - virtual uint32_t GetTextureID() const override final { return 0U; } + virtual void SetSampleMode(TextureSampleMode) override {} + virtual void BuildMipmaps() override {} + virtual uint32_t GetTextureID() const override final { return 0U; } -private: - friend class RendererDummy; - TextureDummy(const TextureDescriptor &descriptor) : Texture(descriptor) {} -}; + private: + friend class RendererDummy; + TextureDummy(const TextureDescriptor &descriptor) : + Texture(descriptor) {} + }; -} +} // namespace Graphics #endif diff --git a/src/graphics/dummy/VertexBufferDummy.h b/src/graphics/dummy/VertexBufferDummy.h index c4257f567..a21b4fd90 100644 --- a/src/graphics/dummy/VertexBufferDummy.h +++ b/src/graphics/dummy/VertexBufferDummy.h @@ -8,70 +8,73 @@ namespace Graphics { -namespace Dummy { + namespace Dummy { -class VertexBuffer : public Graphics::VertexBuffer { -public: - VertexBuffer(const VertexBufferDesc &d) : Graphics::VertexBuffer(d), - m_buffer(new Uint8[m_desc.numVertices * m_desc.stride]) - {} + class VertexBuffer : public Graphics::VertexBuffer { + public: + VertexBuffer(const VertexBufferDesc &d) : + Graphics::VertexBuffer(d), + m_buffer(new Uint8[m_desc.numVertices * m_desc.stride]) + {} - // copies the contents of the VertexArray into the buffer - virtual bool Populate(const VertexArray &) override final { return true; } + // copies the contents of the VertexArray into the buffer + virtual bool Populate(const VertexArray &) override final { return true; } - // change the buffer data without mapping - virtual void BufferData(const size_t, void*) override final {} + // change the buffer data without mapping + virtual void BufferData(const size_t, void *) override final {} - virtual void Bind() override final {} - virtual void Release() override final {} + virtual void Bind() override final {} + virtual void Release() override final {} - virtual void Unmap() override final {} + virtual void Unmap() override final {} -protected: - virtual Uint8 *MapInternal(BufferMapMode) override final { return m_buffer.get(); } + protected: + virtual Uint8 *MapInternal(BufferMapMode) override final { return m_buffer.get(); } -private: - std::unique_ptr m_buffer; -}; + private: + std::unique_ptr m_buffer; + }; -class IndexBuffer : public Graphics::IndexBuffer { -public: - IndexBuffer(Uint32 size, BufferUsage bu) : Graphics::IndexBuffer(size, bu), - m_buffer(new Uint32[size]) - {}; + class IndexBuffer : public Graphics::IndexBuffer { + public: + IndexBuffer(Uint32 size, BufferUsage bu) : + Graphics::IndexBuffer(size, bu), + m_buffer(new Uint32[size]){}; - virtual Uint32 *Map(BufferMapMode) override final { return m_buffer.get(); } - virtual void Unmap() override final {} + virtual Uint32 *Map(BufferMapMode) override final { return m_buffer.get(); } + virtual void Unmap() override final {} - virtual void BufferData(const size_t, void*) override final {} + virtual void BufferData(const size_t, void *) override final {} - virtual void Bind() override final {} - virtual void Release() override final {} + virtual void Bind() override final {} + virtual void Release() override final {} -private: - std::unique_ptr m_buffer; -}; + private: + std::unique_ptr m_buffer; + }; -// Instance buffer -class InstanceBuffer : public Graphics::InstanceBuffer { -public: - InstanceBuffer(Uint32 size, BufferUsage hint) - : Graphics::InstanceBuffer(size, hint), m_data(new matrix4x4f[size]) - {} - virtual ~InstanceBuffer() {}; - virtual matrix4x4f* Map(BufferMapMode) override final { return m_data.get(); } - virtual void Unmap() override final {} + // Instance buffer + class InstanceBuffer : public Graphics::InstanceBuffer { + public: + InstanceBuffer(Uint32 size, BufferUsage hint) : + Graphics::InstanceBuffer(size, hint), + m_data(new matrix4x4f[size]) + {} + virtual ~InstanceBuffer(){}; + virtual matrix4x4f *Map(BufferMapMode) override final { return m_data.get(); } + virtual void Unmap() override final {} - Uint32 GetSize() const { return m_size; } - BufferUsage GetUsage() const { return m_usage; } + Uint32 GetSize() const { return m_size; } + BufferUsage GetUsage() const { return m_usage; } - virtual void Bind() override final {} - virtual void Release() override final {} + virtual void Bind() override final {} + virtual void Release() override final {} -protected: - std::unique_ptr m_data; -}; + protected: + std::unique_ptr m_data; + }; -} } + } // namespace Dummy +} // namespace Graphics #endif diff --git a/src/graphics/opengl/BillboardMaterial.cpp b/src/graphics/opengl/BillboardMaterial.cpp index 8107c4634..747df0011 100644 --- a/src/graphics/opengl/BillboardMaterial.cpp +++ b/src/graphics/opengl/BillboardMaterial.cpp @@ -2,62 +2,62 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "BillboardMaterial.h" -#include "StringF.h" -#include "graphics/Graphics.h" #include "RendererGL.h" +#include "StringF.h" #include "TextureGL.h" +#include "graphics/Graphics.h" #include namespace Graphics { -namespace OGL { + namespace OGL { -BillboardProgram::BillboardProgram(const MaterialDescriptor &desc) -{ - //build some defines - std::stringstream ss; + BillboardProgram::BillboardProgram(const MaterialDescriptor &desc) + { + //build some defines + std::stringstream ss; - m_name = "billboards"; - if(desc.effect == EFFECT_BILLBOARD_ATLAS) - m_defines = stringf("#define USE_SPRITE_ATLAS\n"); + m_name = "billboards"; + if (desc.effect == EFFECT_BILLBOARD_ATLAS) + m_defines = stringf("#define USE_SPRITE_ATLAS\n"); - LoadShaders(m_name, m_defines); - InitUniforms(); -} - -void BillboardProgram::InitUniforms() -{ - Program::InitUniforms(); - coordDownScale.Init("coordDownScale", m_program); -} - -Program *BillboardMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert(desc.textures == 1); - return new BillboardProgram(desc); -} - -void BillboardMaterial::Apply() -{ - OGL::Material::Apply(); - - BillboardProgram *p = static_cast(m_program); - - assert(this->texture0); - p->texture0.Set(this->texture0, 0); - if (p->coordDownScale.IsValid()) { - if(this->specialParameter0) { - const float coordDownScale = *static_cast(this->specialParameter0); - p->coordDownScale.Set(coordDownScale); - } else { - p->coordDownScale.Set(0.5f); + LoadShaders(m_name, m_defines); + InitUniforms(); } - } -} -void BillboardMaterial::Unapply() -{ - static_cast(texture0)->Unbind(); -} + void BillboardProgram::InitUniforms() + { + Program::InitUniforms(); + coordDownScale.Init("coordDownScale", m_program); + } -} -} + Program *BillboardMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert(desc.textures == 1); + return new BillboardProgram(desc); + } + + void BillboardMaterial::Apply() + { + OGL::Material::Apply(); + + BillboardProgram *p = static_cast(m_program); + + assert(this->texture0); + p->texture0.Set(this->texture0, 0); + if (p->coordDownScale.IsValid()) { + if (this->specialParameter0) { + const float coordDownScale = *static_cast(this->specialParameter0); + p->coordDownScale.Set(coordDownScale); + } else { + p->coordDownScale.Set(0.5f); + } + } + } + + void BillboardMaterial::Unapply() + { + static_cast(texture0)->Unbind(); + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/BillboardMaterial.h b/src/graphics/opengl/BillboardMaterial.h index f4f92ff05..2fb102acb 100644 --- a/src/graphics/opengl/BillboardMaterial.h +++ b/src/graphics/opengl/BillboardMaterial.h @@ -19,6 +19,7 @@ namespace Graphics { public: BillboardProgram(const MaterialDescriptor &); Uniform coordDownScale; + protected: virtual void InitUniforms() override; }; @@ -29,6 +30,6 @@ namespace Graphics { virtual void Apply() override; virtual void Unapply() override; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/FresnelColourMaterial.cpp b/src/graphics/opengl/FresnelColourMaterial.cpp index e4af935bf..f7e5e9eff 100644 --- a/src/graphics/opengl/FresnelColourMaterial.cpp +++ b/src/graphics/opengl/FresnelColourMaterial.cpp @@ -2,39 +2,39 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "FresnelColourMaterial.h" -#include "graphics/Material.h" -#include "graphics/Graphics.h" -#include "TextureGL.h" #include "RendererGL.h" -#include #include "StringF.h" +#include "TextureGL.h" +#include "graphics/Graphics.h" +#include "graphics/Material.h" +#include namespace Graphics { -namespace OGL { + namespace OGL { -FresnelColourProgram::FresnelColourProgram(const MaterialDescriptor &desc) -{ - //build some defines - std::stringstream ss; + FresnelColourProgram::FresnelColourProgram(const MaterialDescriptor &desc) + { + //build some defines + std::stringstream ss; - m_name = "FresnelColour"; - m_defines = ss.str(); + m_name = "FresnelColour"; + m_defines = ss.str(); - LoadShaders(m_name, m_defines); - InitUniforms(); -} + LoadShaders(m_name, m_defines); + InitUniforms(); + } -Program *FresnelColourMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - return new FresnelColourProgram(desc); -} + Program *FresnelColourMaterial::CreateProgram(const MaterialDescriptor &desc) + { + return new FresnelColourProgram(desc); + } -void FresnelColourMaterial::Apply() -{ - OGL::Material::Apply(); - FresnelColourProgram *p = static_cast(m_program); - p->diffuse.Set(this->diffuse); -} + void FresnelColourMaterial::Apply() + { + OGL::Material::Apply(); + FresnelColourProgram *p = static_cast(m_program); + p->diffuse.Set(this->diffuse); + } -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/FresnelColourMaterial.h b/src/graphics/opengl/FresnelColourMaterial.h index b11336a26..c34f76707 100644 --- a/src/graphics/opengl/FresnelColourMaterial.h +++ b/src/graphics/opengl/FresnelColourMaterial.h @@ -24,7 +24,7 @@ namespace Graphics { virtual Program *CreateProgram(const MaterialDescriptor &) override; virtual void Apply() override; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/GLDebug.h b/src/graphics/opengl/GLDebug.h index 268f92c03..68bf485fe 100644 --- a/src/graphics/opengl/GLDebug.h +++ b/src/graphics/opengl/GLDebug.h @@ -12,6 +12,7 @@ * which also includes stack printout */ #include "OpenGLLibs.h" +#include "utils.h" #ifdef _WIN32 #define STDCALL __stdcall @@ -26,61 +27,64 @@ namespace Graphics { class GLDebug { private: - static const char *type_to_string(GLenum type) { - switch(type) { - case GL_DEBUG_TYPE_ERROR: - return("Error"); - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - return("Deprecated Behaviour"); - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - return("Undefined Behaviour"); - case GL_DEBUG_TYPE_PORTABILITY: - return("Portability"); - case GL_DEBUG_TYPE_PERFORMANCE: - return("Performance"); - case GL_DEBUG_TYPE_OTHER: - return("Other"); - default: - return(""); + static const char *type_to_string(GLenum type) + { + switch (type) { + case GL_DEBUG_TYPE_ERROR: + return ("Error"); + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + return ("Deprecated Behaviour"); + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + return ("Undefined Behaviour"); + case GL_DEBUG_TYPE_PORTABILITY: + return ("Portability"); + case GL_DEBUG_TYPE_PERFORMANCE: + return ("Performance"); + case GL_DEBUG_TYPE_OTHER: + return ("Other"); + default: + return (""); } } - static const char *source_to_string(GLenum source) { - switch(source) { - case GL_DEBUG_SOURCE_API: - return("API"); - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: - return("Window System"); - case GL_DEBUG_SOURCE_SHADER_COMPILER: - return("Shader Compiler"); - case GL_DEBUG_SOURCE_THIRD_PARTY: - return("Third Party"); - case GL_DEBUG_SOURCE_APPLICATION: - return("Application"); - case GL_DEBUG_SOURCE_OTHER: - return("Other"); - default: - return(""); + static const char *source_to_string(GLenum source) + { + switch (source) { + case GL_DEBUG_SOURCE_API: + return ("API"); + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + return ("Window System"); + case GL_DEBUG_SOURCE_SHADER_COMPILER: + return ("Shader Compiler"); + case GL_DEBUG_SOURCE_THIRD_PARTY: + return ("Third Party"); + case GL_DEBUG_SOURCE_APPLICATION: + return ("Application"); + case GL_DEBUG_SOURCE_OTHER: + return ("Other"); + default: + return (""); } } - static const char *severity_to_string(GLenum severity) { - switch(severity) { - case GL_DEBUG_SEVERITY_HIGH: - return("High"); - case GL_DEBUG_SEVERITY_MEDIUM: - return("Medium"); - case GL_DEBUG_SEVERITY_LOW: - return("Low"); - default: - return(""); + static const char *severity_to_string(GLenum severity) + { + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: + return ("High"); + case GL_DEBUG_SEVERITY_MEDIUM: + return ("Medium"); + case GL_DEBUG_SEVERITY_LOW: + return ("Low"); + default: + return (""); } } // put a breakpoint in this function static void STDCALL PrintMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar* message, const void* userParam) + const GLchar *message, const void *userParam) { OpenGLDebugMsg("Type: %s, Source: %s, ID: %u, Severity: %s, Message: %s\n", type_to_string(type), source_to_string(source), id, @@ -89,7 +93,8 @@ namespace Graphics { public: //register the callback function, if the extension is available - static void Enable() { + static void Enable() + { if (!glewIsSupported("GL_KHR_debug")) { Output("GL_KHR_debug is not supported; GLDebug will not work\n"); return; @@ -104,15 +109,15 @@ namespace Graphics { //glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, true); } - static void Disable() { + static void Disable() + { if (glewIsSupported("GL_KHR_debug")) { glDisable(GL_DEBUG_OUTPUT); } } - }; -} +} // namespace Graphics #else @@ -120,15 +125,15 @@ namespace Graphics { class GLDebug { public: - static void Enable() { + static void Enable() + { Output("GL Debug support was excluded from this build because the glLoadGen headers did not include support for it.\n"); } static void Disable() {} - }; -} +} // namespace Graphics #endif diff --git a/src/graphics/opengl/GasGiantMaterial.cpp b/src/graphics/opengl/GasGiantMaterial.cpp index 79c22c5bf..7b274b9f1 100644 --- a/src/graphics/opengl/GasGiantMaterial.cpp +++ b/src/graphics/opengl/GasGiantMaterial.cpp @@ -2,156 +2,157 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GasGiantMaterial.h" -#include "GeoSphere.h" #include "Camera.h" +#include "GeoSphere.h" +#include "RendererGL.h" #include "StringF.h" #include "graphics/Graphics.h" -#include "RendererGL.h" #include namespace Graphics { -namespace OGL { + namespace OGL { -// GasGiantProgram ------------------------------------------- -GasGiantProgram::GasGiantProgram(const std::string &filename, const std::string &defines) -{ - m_name = filename; - m_defines = defines; - LoadShaders(filename, defines); - InitUniforms(); -} - -void GasGiantProgram::InitUniforms() -{ - Program::InitUniforms(); - atmosColor.Init("atmosColor", m_program); - geosphereAtmosFogDensity.Init("geosphereAtmosFogDensity", m_program); - geosphereAtmosInvScaleHeight.Init("geosphereAtmosInvScaleHeight", m_program); - geosphereAtmosTopRad.Init("geosphereAtmosTopRad", m_program); - geosphereCenter.Init("geosphereCenter", m_program); - geosphereRadius.Init("geosphereRadius", m_program); - geosphereInvRadius.Init("geosphereInvRadius", m_program); - - shadowCentreX.Init("shadowCentreX", m_program); - shadowCentreY.Init("shadowCentreY", m_program); - shadowCentreZ.Init("shadowCentreZ", m_program); - srad.Init("srad", m_program); - lrad.Init("lrad", m_program); - sdivlrad.Init("sdivlrad", m_program); -} - -// GasGiantSurfaceMaterial ----------------------------------- -GasGiantSurfaceMaterial::GasGiantSurfaceMaterial() : m_curNumShadows(0) -{ - for(int i=0;i<4;i++) - m_programs[i] = nullptr; -} - -Program *GasGiantSurfaceMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert(desc.effect == EFFECT_GASSPHERE_TERRAIN); - assert(desc.dirLights < 5); - std::stringstream ss; - ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); - if(desc.dirLights>0) { - const float invNumLights = 1.0f / float(desc.dirLights); - ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); - } - if (desc.textures > 0) - ss << "#define TEXTURE0\n"; - if (desc.quality & HAS_ATMOSPHERE) - ss << "#define ATMOSPHERE\n"; - if (desc.quality & HAS_ECLIPSES) - ss << "#define ECLIPSE\n"; - - ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); - - return new Graphics::OGL::GasGiantProgram("gassphere_base", ss.str()); -} - -void GasGiantSurfaceMaterial::SetProgram(Program *p) -{ - m_programs[m_curNumShadows] = p; - m_program = p; -} - -void GasGiantSurfaceMaterial::Apply() -{ - SwitchShadowVariant(); - SetGSUniforms(); -} - -void GasGiantSurfaceMaterial::SetGSUniforms() -{ - OGL::Material::Apply(); - - GasGiantProgram *p = static_cast(m_program); - const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); - const SystemBody::AtmosphereParameters ap = params.atmosphere; - - p->emission.Set(this->emissive); - p->sceneAmbient.Set(m_renderer->GetAmbientColor()); - p->atmosColor.Set(ap.atmosCol); - p->geosphereAtmosFogDensity.Set(ap.atmosDensity); - p->geosphereAtmosInvScaleHeight.Set(ap.atmosInvScaleHeight); - p->geosphereAtmosTopRad.Set(ap.atmosRadius); - p->geosphereCenter.Set(ap.center); - p->geosphereRadius.Set(ap.planetRadius); - p->geosphereInvRadius.Set(1.0f / ap.planetRadius); - - //Light uniform parameters - for( Uint32 i=0 ; iGetNumLights() ; i++ ) { - const Light& Light = m_renderer->GetLight(i); - p->lights[i].diffuse.Set( Light.GetDiffuse() ); - p->lights[i].specular.Set( Light.GetSpecular() ); - const vector3f& pos = Light.GetPosition(); - p->lights[i].position.Set( pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); - } - - p->diffuse.Set(this->diffuse); - p->texture0.Set(this->texture0, 0); - - // we handle up to three shadows at a time - vector3f shadowCentreX; - vector3f shadowCentreY; - vector3f shadowCentreZ; - vector3f srad; - vector3f lrad; - vector3f sdivlrad; - std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); - int j = 0; - while (j<3 && it != itEnd) { - shadowCentreX[j] = it->centre[0]; - shadowCentreY[j] = it->centre[1]; - shadowCentreZ[j] = it->centre[2]; - srad[j] = it->srad; - lrad[j] = it->lrad; - sdivlrad[j] = it->srad / it->lrad; - ++it; - ++j; - } - p->shadowCentreX.Set(shadowCentreX); - p->shadowCentreY.Set(shadowCentreY); - p->shadowCentreZ.Set(shadowCentreZ); - p->srad.Set(srad); - p->lrad.Set(lrad); - p->sdivlrad.Set(sdivlrad); -} - -void GasGiantSurfaceMaterial::SwitchShadowVariant() -{ - const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); - // std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); - //request a new shadow variation - if (m_curNumShadows != params.shadows.size()) { - m_curNumShadows = std::min(Uint32(params.shadows.size()), 4U); - if (m_programs[m_curNumShadows] == nullptr) { - m_descriptor.numShadows = m_curNumShadows; //hax - so that GetOrCreateProgram will create a NEW shader instead of reusing the existing one - m_programs[m_curNumShadows] = m_renderer->GetOrCreateProgram(this); + // GasGiantProgram ------------------------------------------- + GasGiantProgram::GasGiantProgram(const std::string &filename, const std::string &defines) + { + m_name = filename; + m_defines = defines; + LoadShaders(filename, defines); + InitUniforms(); } - m_program = m_programs[m_curNumShadows]; - } -} -} -} + void GasGiantProgram::InitUniforms() + { + Program::InitUniforms(); + atmosColor.Init("atmosColor", m_program); + geosphereAtmosFogDensity.Init("geosphereAtmosFogDensity", m_program); + geosphereAtmosInvScaleHeight.Init("geosphereAtmosInvScaleHeight", m_program); + geosphereAtmosTopRad.Init("geosphereAtmosTopRad", m_program); + geosphereCenter.Init("geosphereCenter", m_program); + geosphereRadius.Init("geosphereRadius", m_program); + geosphereInvRadius.Init("geosphereInvRadius", m_program); + + shadowCentreX.Init("shadowCentreX", m_program); + shadowCentreY.Init("shadowCentreY", m_program); + shadowCentreZ.Init("shadowCentreZ", m_program); + srad.Init("srad", m_program); + lrad.Init("lrad", m_program); + sdivlrad.Init("sdivlrad", m_program); + } + + // GasGiantSurfaceMaterial ----------------------------------- + GasGiantSurfaceMaterial::GasGiantSurfaceMaterial() : + m_curNumShadows(0) + { + for (int i = 0; i < 4; i++) + m_programs[i] = nullptr; + } + + Program *GasGiantSurfaceMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert(desc.effect == EFFECT_GASSPHERE_TERRAIN); + assert(desc.dirLights < 5); + std::stringstream ss; + ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); + if (desc.dirLights > 0) { + const float invNumLights = 1.0f / float(desc.dirLights); + ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); + } + if (desc.textures > 0) + ss << "#define TEXTURE0\n"; + if (desc.quality & HAS_ATMOSPHERE) + ss << "#define ATMOSPHERE\n"; + if (desc.quality & HAS_ECLIPSES) + ss << "#define ECLIPSE\n"; + + ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); + + return new Graphics::OGL::GasGiantProgram("gassphere_base", ss.str()); + } + + void GasGiantSurfaceMaterial::SetProgram(Program *p) + { + m_programs[m_curNumShadows] = p; + m_program = p; + } + + void GasGiantSurfaceMaterial::Apply() + { + SwitchShadowVariant(); + SetGSUniforms(); + } + + void GasGiantSurfaceMaterial::SetGSUniforms() + { + OGL::Material::Apply(); + + GasGiantProgram *p = static_cast(m_program); + const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); + const SystemBody::AtmosphereParameters ap = params.atmosphere; + + p->emission.Set(this->emissive); + p->sceneAmbient.Set(m_renderer->GetAmbientColor()); + p->atmosColor.Set(ap.atmosCol); + p->geosphereAtmosFogDensity.Set(ap.atmosDensity); + p->geosphereAtmosInvScaleHeight.Set(ap.atmosInvScaleHeight); + p->geosphereAtmosTopRad.Set(ap.atmosRadius); + p->geosphereCenter.Set(ap.center); + p->geosphereRadius.Set(ap.planetRadius); + p->geosphereInvRadius.Set(1.0f / ap.planetRadius); + + //Light uniform parameters + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + p->lights[i].diffuse.Set(Light.GetDiffuse()); + p->lights[i].specular.Set(Light.GetSpecular()); + const vector3f &pos = Light.GetPosition(); + p->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + } + + p->diffuse.Set(this->diffuse); + p->texture0.Set(this->texture0, 0); + + // we handle up to three shadows at a time + vector3f shadowCentreX; + vector3f shadowCentreY; + vector3f shadowCentreZ; + vector3f srad; + vector3f lrad; + vector3f sdivlrad; + std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); + int j = 0; + while (j < 3 && it != itEnd) { + shadowCentreX[j] = it->centre[0]; + shadowCentreY[j] = it->centre[1]; + shadowCentreZ[j] = it->centre[2]; + srad[j] = it->srad; + lrad[j] = it->lrad; + sdivlrad[j] = it->srad / it->lrad; + ++it; + ++j; + } + p->shadowCentreX.Set(shadowCentreX); + p->shadowCentreY.Set(shadowCentreY); + p->shadowCentreZ.Set(shadowCentreZ); + p->srad.Set(srad); + p->lrad.Set(lrad); + p->sdivlrad.Set(sdivlrad); + } + + void GasGiantSurfaceMaterial::SwitchShadowVariant() + { + const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); + // std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); + //request a new shadow variation + if (m_curNumShadows != params.shadows.size()) { + m_curNumShadows = std::min(Uint32(params.shadows.size()), 4U); + if (m_programs[m_curNumShadows] == nullptr) { + m_descriptor.numShadows = m_curNumShadows; //hax - so that GetOrCreateProgram will create a NEW shader instead of reusing the existing one + m_programs[m_curNumShadows] = m_renderer->GetOrCreateProgram(this); + } + m_program = m_programs[m_curNumShadows]; + } + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/GasGiantMaterial.h b/src/graphics/opengl/GasGiantMaterial.h index 0d09d473a..4dfd3f876 100644 --- a/src/graphics/opengl/GasGiantMaterial.h +++ b/src/graphics/opengl/GasGiantMaterial.h @@ -6,8 +6,8 @@ /* * Programs & Materials used by terrain */ -#include "OpenGLLibs.h" #include "MaterialGL.h" +#include "OpenGLLibs.h" #include "Program.h" #include "galaxy/StarSystem.h" @@ -48,9 +48,9 @@ namespace Graphics { // We actually have multiple programs at work here, one compiled for each of the number of shadows. // They are chosen/created based on what the current parameters passed in by the specialParameter0 are. void SwitchShadowVariant(); - Program* m_programs[4]; // 0 to 3 shadows + Program *m_programs[4]; // 0 to 3 shadows Uint32 m_curNumShadows; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/GenGasGiantColourMaterial.cpp b/src/graphics/opengl/GenGasGiantColourMaterial.cpp index d102751eb..ab9f4eb9d 100644 --- a/src/graphics/opengl/GenGasGiantColourMaterial.cpp +++ b/src/graphics/opengl/GenGasGiantColourMaterial.cpp @@ -2,152 +2,149 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GenGasGiantColourMaterial.h" -#include "TextureGL.h" -#include "graphics/Graphics.h" #include "RendererGL.h" -#include -#include "StringF.h" #include "Ship.h" +#include "StringF.h" +#include "TextureGL.h" #include "galaxy/StarSystem.h" +#include "graphics/Graphics.h" +#include namespace Graphics { -namespace OGL { + namespace OGL { + GenGasGiantColourProgram::GenGasGiantColourProgram(const MaterialDescriptor &desc) + { + //build some defines + std::stringstream ss; + if (desc.textures > 0) + ss << "#define TEXTURE0\n"; -GenGasGiantColourProgram::GenGasGiantColourProgram(const MaterialDescriptor &desc) -{ - //build some defines - std::stringstream ss; - if (desc.textures > 0) - ss << "#define TEXTURE0\n"; + // this masking hack is because I also need to encode data in the UPPER 16-bits + const Uint32 quality = desc.quality & 0x0000FFFF; + switch (quality) { + default: + case GEN_JUPITER_TEXTURE: + ss << "#define GEN_JUPITER_ESQUE\n"; + break; + case GEN_SATURN_TEXTURE: + ss << "#define GEN_SATURN_ESQUE\n"; + break; + case GEN_SATURN2_TEXTURE: + ss << "#define GEN_SATURN2_ESQUE\n"; + break; + // technically Ice Giants not Gas Giants... + case GEN_NEPTUNE_TEXTURE: + ss << "#define GEN_NEPTUNE_ESQUE\n"; + break; + case GEN_NEPTUNE2_TEXTURE: + ss << "#define GEN_NEPTUNE2_ESQUE\n"; + break; + case GEN_URANUS_TEXTURE: + ss << "#define GEN_URANUS_ESQUE\n"; + break; + } + // extract the top 16-bits to get how many octaves we can use + const Uint32 octaves = (desc.quality & 0xFFFF0000) >> 16; + ss << "#define FBM_OCTAVES " << std::to_string(octaves) << std::endl; - // this masking hack is because I also need to encode data in the UPPER 16-bits - const Uint32 quality = desc.quality & 0x0000FFFF; - switch( quality ) - { - default: - case GEN_JUPITER_TEXTURE: - ss << "#define GEN_JUPITER_ESQUE\n"; - break; - case GEN_SATURN_TEXTURE: - ss << "#define GEN_SATURN_ESQUE\n"; - break; - case GEN_SATURN2_TEXTURE: - ss << "#define GEN_SATURN2_ESQUE\n"; - break; - // technically Ice Giants not Gas Giants... - case GEN_NEPTUNE_TEXTURE: - ss << "#define GEN_NEPTUNE_ESQUE\n"; - break; - case GEN_NEPTUNE2_TEXTURE: - ss << "#define GEN_NEPTUNE2_ESQUE\n"; - break; - case GEN_URANUS_TEXTURE: - ss << "#define GEN_URANUS_ESQUE\n"; - break; - } - // extract the top 16-bits to get how many octaves we can use - const Uint32 octaves = (desc.quality & 0xFFFF0000) >> 16; - ss << "#define FBM_OCTAVES " << std::to_string(octaves) << std::endl; + // No lights + ss << "#define NUM_LIGHTS 0\n"; - // No lights - ss << "#define NUM_LIGHTS 0\n"; + m_name = "gen-gas-giant-colour"; + m_defines = ss.str(); - m_name = "gen-gas-giant-colour"; - m_defines = ss.str(); + LoadShaders(m_name, m_defines); + InitUniforms(); + } - LoadShaders(m_name, m_defines); - InitUniforms(); -} + void GenGasGiantColourProgram::InitUniforms() + { + Program::InitUniforms(); -void GenGasGiantColourProgram::InitUniforms() -{ - Program::InitUniforms(); + v0.Init("v0", m_program); + v1.Init("v1", m_program); + v2.Init("v2", m_program); + v3.Init("v3", m_program); + fracStep.Init("fracStep", m_program); - v0.Init("v0", m_program); - v1.Init("v1", m_program); - v2.Init("v2", m_program); - v3.Init("v3", m_program); - fracStep.Init("fracStep", m_program); + permTexture.Init("permTexture", m_program); + gradTexture.Init("gradTexture", m_program); + time.Init("time", m_program); - permTexture.Init("permTexture", m_program); - gradTexture.Init("gradTexture", m_program); - time.Init("time", m_program); + frequency.Init("frequency", m_program); + hueAdjust.Init("hueAdjust", m_program); + } - frequency.Init("frequency", m_program); - hueAdjust.Init("hueAdjust", m_program); -} + Program *GenGasGiantColourMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert(desc.effect == EFFECT_GEN_GASGIANT_TEXTURE); + assert(desc.dirLights < 5); + return new GenGasGiantColourProgram(desc); + } -Program *GenGasGiantColourMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert(desc.effect == EFFECT_GEN_GASGIANT_TEXTURE); - assert(desc.dirLights < 5); - return new GenGasGiantColourProgram(desc); -} + void GenGasGiantColourMaterial::Apply() + { + PROFILE_SCOPED() + OGL::Material::Apply(); -void GenGasGiantColourMaterial::Apply() -{ - PROFILE_SCOPED() - OGL::Material::Apply(); + GenGasGiantColourProgram *p = static_cast(m_program); - GenGasGiantColourProgram *p = static_cast(m_program); + const Graphics::GenGasGiantColourMaterialParameters params = *static_cast(this->specialParameter0); + assert(params.v); + p->v0.Set(params.v[0]); + p->v1.Set(params.v[1]); + p->v2.Set(params.v[2]); + p->v3.Set(params.v[3]); + p->fracStep.Set(params.fracStep); - const Graphics::GenGasGiantColourMaterialParameters params = *static_cast(this->specialParameter0); - assert(params.v); - p->v0.Set( params.v[0] ); - p->v1.Set( params.v[1] ); - p->v2.Set( params.v[2] ); - p->v3.Set( params.v[3] ); - p->fracStep.Set( params.fracStep ); + // Quad generation specific paramters + p->permTexture.Set(this->texture0, 0); + p->gradTexture.Set(this->texture1, 1); + p->time.Set(params.time); + p->frequency.Set(params.frequency); + p->hueAdjust.Set(params.hueAdjust); - // Quad generation specific paramters - p->permTexture.Set(this->texture0, 0); - p->gradTexture.Set(this->texture1, 1); - p->time.Set(params.time); - p->frequency.Set(params.frequency); - p->hueAdjust.Set(params.hueAdjust); + //Light uniform parameters + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + p->lights[i].diffuse.Set(Light.GetDiffuse()); + p->lights[i].specular.Set(Light.GetSpecular()); + const vector3f &pos = Light.GetPosition(); + p->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + } - //Light uniform parameters - for (Uint32 i = 0; iGetNumLights(); i++) { - const Light& Light = m_renderer->GetLight(i); - p->lights[i].diffuse.Set(Light.GetDiffuse()); - p->lights[i].specular.Set(Light.GetSpecular()); - const vector3f& pos = Light.GetPosition(); - p->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); - } + p->diffuse.Set(this->diffuse); - p->diffuse.Set(this->diffuse); + if (this->texture2) { + p->texture2.Set(this->texture2, 2); + } + } - if( this->texture2 ) - { - p->texture2.Set(this->texture2, 2); - } -} + void GenGasGiantColourMaterial::Unapply() + { + PROFILE_SCOPED() + // Might not be necessary to unbind textures, but let's not old graphics code (eg, old-UI) + if (texture4) { + static_cast(texture4)->Unbind(); + glActiveTexture(GL_TEXTURE3); + } + if (texture3) { + static_cast(texture3)->Unbind(); + glActiveTexture(GL_TEXTURE2); + } + if (texture2) { + static_cast(texture2)->Unbind(); + glActiveTexture(GL_TEXTURE1); + } + if (texture1) { + static_cast(texture1)->Unbind(); + glActiveTexture(GL_TEXTURE0); + } + if (texture0) { + static_cast(texture0)->Unbind(); + } + } -void GenGasGiantColourMaterial::Unapply() -{ - PROFILE_SCOPED() - // Might not be necessary to unbind textures, but let's not old graphics code (eg, old-UI) - if (texture4) { - static_cast(texture4)->Unbind(); - glActiveTexture(GL_TEXTURE3); - } - if (texture3) { - static_cast(texture3)->Unbind(); - glActiveTexture(GL_TEXTURE2); - } - if (texture2) { - static_cast(texture2)->Unbind(); - glActiveTexture(GL_TEXTURE1); - } - if (texture1) { - static_cast(texture1)->Unbind(); - glActiveTexture(GL_TEXTURE0); - } - if (texture0) { - static_cast(texture0)->Unbind(); - } -} - -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/GenGasGiantColourMaterial.h b/src/graphics/opengl/GenGasGiantColourMaterial.h index dd29bb150..c279e5b9d 100644 --- a/src/graphics/opengl/GenGasGiantColourMaterial.h +++ b/src/graphics/opengl/GenGasGiantColourMaterial.h @@ -57,7 +57,7 @@ namespace Graphics { virtual void Apply() override final; virtual void Unapply() override final; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/GeoSphereMaterial.cpp b/src/graphics/opengl/GeoSphereMaterial.cpp index 00c38dc2f..5e0317117 100644 --- a/src/graphics/opengl/GeoSphereMaterial.cpp +++ b/src/graphics/opengl/GeoSphereMaterial.cpp @@ -2,242 +2,244 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GeoSphereMaterial.h" -#include "GeoSphere.h" #include "Camera.h" -#include "StringF.h" -#include "graphics/Graphics.h" +#include "GeoSphere.h" #include "RendererGL.h" +#include "StringF.h" #include "TextureGL.h" +#include "graphics/Graphics.h" #include namespace Graphics { -namespace OGL { + namespace OGL { -GeoSphereProgram::GeoSphereProgram(const std::string &filename, const std::string &defines) -{ - m_name = filename; - m_defines = defines; - LoadShaders(filename, defines); - InitUniforms(); -} - -void GeoSphereProgram::InitUniforms() -{ - Program::InitUniforms(); - atmosColor.Init("atmosColor", m_program); - geosphereAtmosFogDensity.Init("geosphereAtmosFogDensity", m_program); - geosphereAtmosInvScaleHeight.Init("geosphereAtmosInvScaleHeight", m_program); - geosphereAtmosTopRad.Init("geosphereAtmosTopRad", m_program); - geosphereCenter.Init("geosphereCenter", m_program); - geosphereRadius.Init("geosphereRadius", m_program); - geosphereInvRadius.Init("geosphereInvRadius", m_program); - - detailScaleHi.Init("detailScaleHi", m_program); - detailScaleLo.Init("detailScaleLo", m_program); - - shadowCentreX.Init("shadowCentreX", m_program); - shadowCentreY.Init("shadowCentreY", m_program); - shadowCentreZ.Init("shadowCentreZ", m_program); - srad.Init("srad", m_program); - lrad.Init("lrad", m_program); - sdivlrad.Init("sdivlrad", m_program); -} - -GeoSphereSurfaceMaterial::GeoSphereSurfaceMaterial() : m_curNumShadows(0) -{ - for(int i=0;i<4;i++) - m_programs[i] = nullptr; -} - -Program *GeoSphereSurfaceMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert((desc.effect == EFFECT_GEOSPHERE_TERRAIN) || - (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA) || - (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_WATER)); - assert(desc.dirLights < 5); - std::stringstream ss; - ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); - if(desc.dirLights>0) { - const float invNumLights = 1.0f / float(desc.dirLights); - ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); - } - if (desc.quality & HAS_ATMOSPHERE) - ss << "#define ATMOSPHERE\n"; - if (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA) - ss << "#define TERRAIN_WITH_LAVA\n"; - if (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_WATER) - ss << "#define TERRAIN_WITH_WATER\n"; - if (desc.quality & HAS_ECLIPSES) - ss << "#define ECLIPSE\n"; - if (desc.quality & HAS_DETAIL_MAPS) - ss << "#define DETAIL_MAPS\n"; - - ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); - - return new Graphics::OGL::GeoSphereProgram("geosphere_terrain", ss.str()); -} - -void GeoSphereSurfaceMaterial::SetProgram(Program *p) -{ - m_programs[m_curNumShadows] = p; - m_program = p; -} - -void GeoSphereSurfaceMaterial::Apply() -{ - SwitchShadowVariant(); - SetGSUniforms(); -} - -void GeoSphereSurfaceMaterial::Unapply() -{ - if(texture0) { - static_cast(texture1)->Unbind(); - static_cast(texture0)->Unbind(); - } -} - -static const float hiScale = 4.0f; -static const float loScale = 0.5f; -void GeoSphereSurfaceMaterial::SetGSUniforms() -{ - OGL::Material::Apply(); - - GeoSphereProgram *p = static_cast(m_program); - const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); - const SystemBody::AtmosphereParameters ap = params.atmosphere; - - p->emission.Set(this->emissive); - p->sceneAmbient.Set(m_renderer->GetAmbientColor()); - p->atmosColor.Set(ap.atmosCol); - p->geosphereAtmosFogDensity.Set(ap.atmosDensity); - p->geosphereAtmosInvScaleHeight.Set(ap.atmosInvScaleHeight); - p->geosphereAtmosTopRad.Set(ap.atmosRadius); - p->geosphereCenter.Set(ap.center); - p->geosphereRadius.Set(ap.planetRadius); - p->geosphereInvRadius.Set(1.0f / ap.planetRadius); - - if(this->texture0) { - p->texture0.Set(this->texture0, 0); - p->texture1.Set(this->texture1, 1); - - const float fDetailFrequency = pow(2.0f, float(params.maxPatchDepth) - float(params.patchDepth)); - - p->detailScaleHi.Set(hiScale * fDetailFrequency); - p->detailScaleLo.Set(loScale * fDetailFrequency); - } - - //Light uniform parameters - for( Uint32 i=0 ; iGetNumLights() ; i++ ) { - const Light& Light = m_renderer->GetLight(i); - p->lights[i].diffuse.Set( Light.GetDiffuse() ); - p->lights[i].specular.Set( Light.GetSpecular() ); - const vector3f& pos = Light.GetPosition(); - p->lights[i].position.Set( pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); - } - - // we handle up to three shadows at a time - vector3f shadowCentreX; - vector3f shadowCentreY; - vector3f shadowCentreZ; - vector3f srad; - vector3f lrad; - vector3f sdivlrad; - std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); - int j = 0; - while (j<3 && it != itEnd) { - shadowCentreX[j] = it->centre[0]; - shadowCentreY[j] = it->centre[1]; - shadowCentreZ[j] = it->centre[2]; - srad[j] = it->srad; - lrad[j] = it->lrad; - sdivlrad[j] = it->srad / it->lrad; - ++it; - ++j; - } - p->shadowCentreX.Set(shadowCentreX); - p->shadowCentreY.Set(shadowCentreY); - p->shadowCentreZ.Set(shadowCentreZ); - p->srad.Set(srad); - p->lrad.Set(lrad); - p->sdivlrad.Set(sdivlrad); -} - -void GeoSphereSurfaceMaterial::SwitchShadowVariant() -{ - const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); - // std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); - //request a new shadow variation - if (m_curNumShadows != params.shadows.size()) { - m_curNumShadows = std::min(Uint32(params.shadows.size()), 4U); - if (m_programs[m_curNumShadows] == nullptr) { - m_descriptor.numShadows = m_curNumShadows; //hax - so that GetOrCreateProgram will create a NEW shader instead of reusing the existing one - m_programs[m_curNumShadows] = m_renderer->GetOrCreateProgram(this); + GeoSphereProgram::GeoSphereProgram(const std::string &filename, const std::string &defines) + { + m_name = filename; + m_defines = defines; + LoadShaders(filename, defines); + InitUniforms(); } - m_program = m_programs[m_curNumShadows]; - } -} -GeoSphereSkyMaterial::GeoSphereSkyMaterial() : GeoSphereSurfaceMaterial() -{ -} + void GeoSphereProgram::InitUniforms() + { + Program::InitUniforms(); + atmosColor.Init("atmosColor", m_program); + geosphereAtmosFogDensity.Init("geosphereAtmosFogDensity", m_program); + geosphereAtmosInvScaleHeight.Init("geosphereAtmosInvScaleHeight", m_program); + geosphereAtmosTopRad.Init("geosphereAtmosTopRad", m_program); + geosphereCenter.Init("geosphereCenter", m_program); + geosphereRadius.Init("geosphereRadius", m_program); + geosphereInvRadius.Init("geosphereInvRadius", m_program); -Program *GeoSphereSkyMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert(desc.effect == EFFECT_GEOSPHERE_SKY); - assert(desc.dirLights > 0 && desc.dirLights < 5); - std::stringstream ss; - ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); - if(desc.dirLights>0) { - const float invNumLights = 1.0f / float(desc.dirLights); - ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); - } - ss << "#define ATMOSPHERE\n"; - if (desc.quality & HAS_ECLIPSES) - ss << "#define ECLIPSE\n"; + detailScaleHi.Init("detailScaleHi", m_program); + detailScaleLo.Init("detailScaleLo", m_program); - ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); + shadowCentreX.Init("shadowCentreX", m_program); + shadowCentreY.Init("shadowCentreY", m_program); + shadowCentreZ.Init("shadowCentreZ", m_program); + srad.Init("srad", m_program); + lrad.Init("lrad", m_program); + sdivlrad.Init("sdivlrad", m_program); + } - return new Graphics::OGL::GeoSphereProgram("geosphere_sky", ss.str()); -} + GeoSphereSurfaceMaterial::GeoSphereSurfaceMaterial() : + m_curNumShadows(0) + { + for (int i = 0; i < 4; i++) + m_programs[i] = nullptr; + } -void GeoSphereSkyMaterial::Apply() -{ - SwitchShadowVariant(); - SetGSUniforms(); -} + Program *GeoSphereSurfaceMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert((desc.effect == EFFECT_GEOSPHERE_TERRAIN) || + (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA) || + (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_WATER)); + assert(desc.dirLights < 5); + std::stringstream ss; + ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); + if (desc.dirLights > 0) { + const float invNumLights = 1.0f / float(desc.dirLights); + ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); + } + if (desc.quality & HAS_ATMOSPHERE) + ss << "#define ATMOSPHERE\n"; + if (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA) + ss << "#define TERRAIN_WITH_LAVA\n"; + if (desc.effect == EFFECT_GEOSPHERE_TERRAIN_WITH_WATER) + ss << "#define TERRAIN_WITH_WATER\n"; + if (desc.quality & HAS_ECLIPSES) + ss << "#define ECLIPSE\n"; + if (desc.quality & HAS_DETAIL_MAPS) + ss << "#define DETAIL_MAPS\n"; -Program *GeoSphereStarMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert((desc.effect == EFFECT_GEOSPHERE_STAR)); - assert(desc.dirLights < 5); - std::stringstream ss; - ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); + ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); - return new Graphics::OGL::GeoSphereProgram("geosphere_star", ss.str()); -} + return new Graphics::OGL::GeoSphereProgram("geosphere_terrain", ss.str()); + } -void GeoSphereStarMaterial::Apply() -{ - SetGSUniforms(); -} + void GeoSphereSurfaceMaterial::SetProgram(Program *p) + { + m_programs[m_curNumShadows] = p; + m_program = p; + } -void GeoSphereStarMaterial::Unapply() -{ - if (texture0) { - static_cast(texture1)->Unbind(); - static_cast(texture0)->Unbind(); - } -} + void GeoSphereSurfaceMaterial::Apply() + { + SwitchShadowVariant(); + SetGSUniforms(); + } -void GeoSphereStarMaterial::SetGSUniforms() -{ - OGL::Material::Apply(); + void GeoSphereSurfaceMaterial::Unapply() + { + if (texture0) { + static_cast(texture1)->Unbind(); + static_cast(texture0)->Unbind(); + } + } - GeoSphereProgram *p = static_cast(m_program); + static const float hiScale = 4.0f; + static const float loScale = 0.5f; + void GeoSphereSurfaceMaterial::SetGSUniforms() + { + OGL::Material::Apply(); - p->emission.Set(this->emissive); -} + GeoSphereProgram *p = static_cast(m_program); + const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); + const SystemBody::AtmosphereParameters ap = params.atmosphere; -} -} + p->emission.Set(this->emissive); + p->sceneAmbient.Set(m_renderer->GetAmbientColor()); + p->atmosColor.Set(ap.atmosCol); + p->geosphereAtmosFogDensity.Set(ap.atmosDensity); + p->geosphereAtmosInvScaleHeight.Set(ap.atmosInvScaleHeight); + p->geosphereAtmosTopRad.Set(ap.atmosRadius); + p->geosphereCenter.Set(ap.center); + p->geosphereRadius.Set(ap.planetRadius); + p->geosphereInvRadius.Set(1.0f / ap.planetRadius); + + if (this->texture0) { + p->texture0.Set(this->texture0, 0); + p->texture1.Set(this->texture1, 1); + + const float fDetailFrequency = pow(2.0f, float(params.maxPatchDepth) - float(params.patchDepth)); + + p->detailScaleHi.Set(hiScale * fDetailFrequency); + p->detailScaleLo.Set(loScale * fDetailFrequency); + } + + //Light uniform parameters + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + p->lights[i].diffuse.Set(Light.GetDiffuse()); + p->lights[i].specular.Set(Light.GetSpecular()); + const vector3f &pos = Light.GetPosition(); + p->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + } + + // we handle up to three shadows at a time + vector3f shadowCentreX; + vector3f shadowCentreY; + vector3f shadowCentreZ; + vector3f srad; + vector3f lrad; + vector3f sdivlrad; + std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); + int j = 0; + while (j < 3 && it != itEnd) { + shadowCentreX[j] = it->centre[0]; + shadowCentreY[j] = it->centre[1]; + shadowCentreZ[j] = it->centre[2]; + srad[j] = it->srad; + lrad[j] = it->lrad; + sdivlrad[j] = it->srad / it->lrad; + ++it; + ++j; + } + p->shadowCentreX.Set(shadowCentreX); + p->shadowCentreY.Set(shadowCentreY); + p->shadowCentreZ.Set(shadowCentreZ); + p->srad.Set(srad); + p->lrad.Set(lrad); + p->sdivlrad.Set(sdivlrad); + } + + void GeoSphereSurfaceMaterial::SwitchShadowVariant() + { + const GeoSphere::MaterialParameters params = *static_cast(this->specialParameter0); + // std::vector::const_iterator it = params.shadows.begin(), itEnd = params.shadows.end(); + //request a new shadow variation + if (m_curNumShadows != params.shadows.size()) { + m_curNumShadows = std::min(Uint32(params.shadows.size()), 4U); + if (m_programs[m_curNumShadows] == nullptr) { + m_descriptor.numShadows = m_curNumShadows; //hax - so that GetOrCreateProgram will create a NEW shader instead of reusing the existing one + m_programs[m_curNumShadows] = m_renderer->GetOrCreateProgram(this); + } + m_program = m_programs[m_curNumShadows]; + } + } + + GeoSphereSkyMaterial::GeoSphereSkyMaterial() : + GeoSphereSurfaceMaterial() + { + } + + Program *GeoSphereSkyMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert(desc.effect == EFFECT_GEOSPHERE_SKY); + assert(desc.dirLights > 0 && desc.dirLights < 5); + std::stringstream ss; + ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); + if (desc.dirLights > 0) { + const float invNumLights = 1.0f / float(desc.dirLights); + ss << stringf("#define INV_NUM_LIGHTS %0{f}\n", invNumLights); + } + ss << "#define ATMOSPHERE\n"; + if (desc.quality & HAS_ECLIPSES) + ss << "#define ECLIPSE\n"; + + ss << stringf("#define NUM_SHADOWS %0{u}\n", m_curNumShadows); + + return new Graphics::OGL::GeoSphereProgram("geosphere_sky", ss.str()); + } + + void GeoSphereSkyMaterial::Apply() + { + SwitchShadowVariant(); + SetGSUniforms(); + } + + Program *GeoSphereStarMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert((desc.effect == EFFECT_GEOSPHERE_STAR)); + assert(desc.dirLights < 5); + std::stringstream ss; + ss << stringf("#define NUM_LIGHTS %0{u}\n", desc.dirLights); + + return new Graphics::OGL::GeoSphereProgram("geosphere_star", ss.str()); + } + + void GeoSphereStarMaterial::Apply() + { + SetGSUniforms(); + } + + void GeoSphereStarMaterial::Unapply() + { + if (texture0) { + static_cast(texture1)->Unbind(); + static_cast(texture0)->Unbind(); + } + } + + void GeoSphereStarMaterial::SetGSUniforms() + { + OGL::Material::Apply(); + + GeoSphereProgram *p = static_cast(m_program); + + p->emission.Set(this->emissive); + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/GeoSphereMaterial.h b/src/graphics/opengl/GeoSphereMaterial.h index 70443c335..cbaddac86 100644 --- a/src/graphics/opengl/GeoSphereMaterial.h +++ b/src/graphics/opengl/GeoSphereMaterial.h @@ -6,8 +6,8 @@ /* * Programs & Materials used by terrain */ -#include "OpenGLLibs.h" #include "MaterialGL.h" +#include "OpenGLLibs.h" #include "Program.h" #include "galaxy/StarSystem.h" @@ -52,7 +52,7 @@ namespace Graphics { // We actually have multiple programs at work here, one compiled for each of the number of shadows. // They are chosen/created based on what the current parameters passed in by the specialParameter0 are. void SwitchShadowVariant(); - Program* m_programs[4]; // 0 to 3 shadows + Program *m_programs[4]; // 0 to 3 shadows Uint32 m_curNumShadows; }; @@ -63,7 +63,6 @@ namespace Graphics { virtual void Apply() override; }; - class GeoSphereStarMaterial : public Material { public: virtual Program *CreateProgram(const MaterialDescriptor &) override; @@ -74,6 +73,6 @@ namespace Graphics { void SetGSUniforms(); }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/MaterialGL.cpp b/src/graphics/opengl/MaterialGL.cpp index d5d90b157..a1e1c71a6 100644 --- a/src/graphics/opengl/MaterialGL.cpp +++ b/src/graphics/opengl/MaterialGL.cpp @@ -6,36 +6,36 @@ #include "RendererGL.h" namespace Graphics { -namespace OGL { + namespace OGL { -void Material::Apply() -{ - m_program->Use(); - m_program->invLogZfarPlus1.Set(m_renderer->m_invLogZfarPlus1); -} + void Material::Apply() + { + m_program->Use(); + m_program->invLogZfarPlus1.Set(m_renderer->m_invLogZfarPlus1); + } -void Material::Unapply() -{ -} + void Material::Unapply() + { + } -bool Material::IsProgramLoaded() const -{ - return m_program->Loaded(); -} + bool Material::IsProgramLoaded() const + { + return m_program->Loaded(); + } -void Material::SetCommonUniforms(const matrix4x4f& mv, const matrix4x4f& proj) -{ - const matrix4x4f ViewProjection = proj * mv; - const matrix3x3f orient(mv.GetOrient()); - const matrix3x3f NormalMatrix(orient.Inverse()); + void Material::SetCommonUniforms(const matrix4x4f &mv, const matrix4x4f &proj) + { + const matrix4x4f ViewProjection = proj * mv; + const matrix3x3f orient(mv.GetOrient()); + const matrix3x3f NormalMatrix(orient.Inverse()); - m_program->uProjectionMatrix.Set( proj ); - m_program->uViewMatrix.Set( mv ); - m_program->uViewMatrixInverse.Set( mv.Inverse() ); - m_program->uViewProjectionMatrix.Set( ViewProjection ); - m_program->uNormalMatrix.Set( NormalMatrix ); - CHECKERRORS(); -} + m_program->uProjectionMatrix.Set(proj); + m_program->uViewMatrix.Set(mv); + m_program->uViewMatrixInverse.Set(mv.Inverse()); + m_program->uViewProjectionMatrix.Set(ViewProjection); + m_program->uNormalMatrix.Set(NormalMatrix); + CHECKERRORS(); + } -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/MaterialGL.h b/src/graphics/opengl/MaterialGL.h index 8b3a86b35..e253d5d1b 100644 --- a/src/graphics/opengl/MaterialGL.h +++ b/src/graphics/opengl/MaterialGL.h @@ -25,7 +25,7 @@ namespace Graphics { class Material : public Graphics::Material { public: - Material() { } + Material() {} // Create an appropriate program for this material. virtual Program *CreateProgram(const MaterialDescriptor &) = 0; // bind textures, set uniforms @@ -33,13 +33,13 @@ namespace Graphics { virtual void Unapply() override; virtual bool IsProgramLoaded() const override final; virtual void SetProgram(Program *p) { m_program = p; } - virtual void SetCommonUniforms(const matrix4x4f& mv, const matrix4x4f& proj) override; + virtual void SetCommonUniforms(const matrix4x4f &mv, const matrix4x4f &proj) override; protected: friend class Graphics::RendererOGL; Program *m_program; RendererOGL *m_renderer; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/MultiMaterial.cpp b/src/graphics/opengl/MultiMaterial.cpp index a67619867..d75f5612f 100644 --- a/src/graphics/opengl/MultiMaterial.cpp +++ b/src/graphics/opengl/MultiMaterial.cpp @@ -2,174 +2,174 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "MultiMaterial.h" -#include "graphics/Material.h" -#include "graphics/Graphics.h" #include "RendererGL.h" -#include "TextureGL.h" -#include -#include "StringF.h" #include "Ship.h" +#include "StringF.h" +#include "TextureGL.h" +#include "graphics/Graphics.h" +#include "graphics/Material.h" +#include namespace Graphics { -namespace OGL { + namespace OGL { -MultiProgram::MultiProgram(const MaterialDescriptor &desc, int numLights) -{ - numLights = Clamp(numLights, 1, 4); + MultiProgram::MultiProgram(const MaterialDescriptor &desc, int numLights) + { + numLights = Clamp(numLights, 1, 4); - //build some defines - std::stringstream ss; - if (desc.textures > 0) - ss << "#define TEXTURE0\n"; - if (desc.vertexColors) - ss << "#define VERTEXCOLOR\n"; - if (desc.alphaTest) - ss << "#define ALPHA_TEST\n"; - //using only one light - if (desc.lighting && numLights > 0) - ss << stringf("#define NUM_LIGHTS %0{d}\n", numLights); - else - ss << "#define NUM_LIGHTS 0\n"; - if (desc.normalMap && desc.lighting && numLights > 0) - ss << "#define MAP_NORMAL\n"; - if (desc.specularMap) - ss << "#define MAP_SPECULAR\n"; - if (desc.glowMap) - ss << "#define MAP_EMISSIVE\n"; - if (desc.ambientMap) - ss << "#define MAP_AMBIENT\n"; - if (desc.usePatterns) - ss << "#define MAP_COLOR\n"; - if (desc.quality & HAS_HEAT_GRADIENT) - ss << "#define HEAT_COLOURING\n"; - if (desc.instanced) - ss << "#define USE_INSTANCING\n"; + //build some defines + std::stringstream ss; + if (desc.textures > 0) + ss << "#define TEXTURE0\n"; + if (desc.vertexColors) + ss << "#define VERTEXCOLOR\n"; + if (desc.alphaTest) + ss << "#define ALPHA_TEST\n"; + //using only one light + if (desc.lighting && numLights > 0) + ss << stringf("#define NUM_LIGHTS %0{d}\n", numLights); + else + ss << "#define NUM_LIGHTS 0\n"; + if (desc.normalMap && desc.lighting && numLights > 0) + ss << "#define MAP_NORMAL\n"; + if (desc.specularMap) + ss << "#define MAP_SPECULAR\n"; + if (desc.glowMap) + ss << "#define MAP_EMISSIVE\n"; + if (desc.ambientMap) + ss << "#define MAP_AMBIENT\n"; + if (desc.usePatterns) + ss << "#define MAP_COLOR\n"; + if (desc.quality & HAS_HEAT_GRADIENT) + ss << "#define HEAT_COLOURING\n"; + if (desc.instanced) + ss << "#define USE_INSTANCING\n"; - m_name = "multi"; - m_defines = ss.str(); + m_name = "multi"; + m_defines = ss.str(); - LoadShaders(m_name, m_defines); - InitUniforms(); -} - -LitMultiMaterial::LitMultiMaterial() -: m_programs() -, m_curNumLights(0) -{ -} - -Program *MultiMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - return new MultiProgram(desc); -} - -Program *LitMultiMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - m_curNumLights = m_renderer->m_numDirLights; - return new MultiProgram(desc, m_curNumLights); -} - -void LitMultiMaterial::SetProgram(Program *p) -{ - m_programs[m_curNumLights] = p; - m_program = p; -} - -void MultiMaterial::Apply() -{ - OGL::Material::Apply(); - - MultiProgram *p = static_cast(m_program); - - p->diffuse.Set(this->diffuse); - - p->texture0.Set(this->texture0, 0); - p->texture1.Set(this->texture1, 1); - p->texture2.Set(this->texture2, 2); - p->texture3.Set(this->texture3, 3); - p->texture4.Set(this->texture4, 4); - p->texture5.Set(this->texture5, 5); - p->texture6.Set(this->texture6, 6); - - p->heatGradient.Set(this->heatGradient, 7); - if(nullptr!=specialParameter0) { - HeatGradientParameters_t *pMGP = static_cast(specialParameter0); - p->heatingMatrix.Set(pMGP->heatingMatrix); - p->heatingNormal.Set(pMGP->heatingNormal); - p->heatingAmount.Set(pMGP->heatingAmount); - } else { - p->heatingMatrix.Set(matrix3x3f::Identity()); - p->heatingNormal.Set(vector3f(0.0f, -1.0f, 0.0f)); - p->heatingAmount.Set(0.0f); - } -} - -void LitMultiMaterial::Apply() -{ - //request a new light variation - if (m_curNumLights != m_renderer->m_numDirLights) { - m_curNumLights = m_renderer->m_numDirLights; - if (m_programs[m_curNumLights] == 0) { - m_descriptor.dirLights = m_curNumLights; //hax - m_programs[m_curNumLights] = m_renderer->GetOrCreateProgram(this); + LoadShaders(m_name, m_defines); + InitUniforms(); } - m_program = m_programs[m_curNumLights]; - } - MultiMaterial::Apply(); + LitMultiMaterial::LitMultiMaterial() : + m_programs(), + m_curNumLights(0) + { + } - MultiProgram *p = static_cast(m_program); - p->emission.Set(this->emissive); - p->specular.Set(this->specular); - p->shininess.Set(float(this->shininess)); - p->sceneAmbient.Set(m_renderer->GetAmbientColor()); + Program *MultiMaterial::CreateProgram(const MaterialDescriptor &desc) + { + return new MultiProgram(desc); + } - //Light uniform parameters - for( Uint32 i=0 ; iGetNumLights() ; i++ ) { - const Light& Light = m_renderer->GetLight(i); - p->lights[i].diffuse.Set( Light.GetDiffuse() ); - p->lights[i].specular.Set( Light.GetSpecular() ); - const vector3f pos = Light.GetPosition(); - p->lights[i].position.Set( pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); - } - CHECKERRORS(); -} + Program *LitMultiMaterial::CreateProgram(const MaterialDescriptor &desc) + { + m_curNumLights = m_renderer->m_numDirLights; + return new MultiProgram(desc, m_curNumLights); + } -void MultiMaterial::Unapply() -{ - // Might not be necessary to unbind textures, but let's not old graphics code (eg, old-UI) - if (heatGradient) { - static_cast(heatGradient)->Unbind(); - glActiveTexture(GL_TEXTURE6); - } - if (texture6) { - static_cast(texture6)->Unbind(); - glActiveTexture(GL_TEXTURE5); - } - if (texture5) { - static_cast(texture5)->Unbind(); - glActiveTexture(GL_TEXTURE4); - } - if (texture4) { - static_cast(texture4)->Unbind(); - glActiveTexture(GL_TEXTURE3); - } - if (texture3) { - static_cast(texture3)->Unbind(); - glActiveTexture(GL_TEXTURE2); - } - if (texture2) { - static_cast(texture2)->Unbind(); - glActiveTexture(GL_TEXTURE1); - } - if (texture1) { - static_cast(texture1)->Unbind(); - glActiveTexture(GL_TEXTURE0); - } - if (texture0) { - static_cast(texture0)->Unbind(); - } -} + void LitMultiMaterial::SetProgram(Program *p) + { + m_programs[m_curNumLights] = p; + m_program = p; + } -} -} + void MultiMaterial::Apply() + { + OGL::Material::Apply(); + + MultiProgram *p = static_cast(m_program); + + p->diffuse.Set(this->diffuse); + + p->texture0.Set(this->texture0, 0); + p->texture1.Set(this->texture1, 1); + p->texture2.Set(this->texture2, 2); + p->texture3.Set(this->texture3, 3); + p->texture4.Set(this->texture4, 4); + p->texture5.Set(this->texture5, 5); + p->texture6.Set(this->texture6, 6); + + p->heatGradient.Set(this->heatGradient, 7); + if (nullptr != specialParameter0) { + HeatGradientParameters_t *pMGP = static_cast(specialParameter0); + p->heatingMatrix.Set(pMGP->heatingMatrix); + p->heatingNormal.Set(pMGP->heatingNormal); + p->heatingAmount.Set(pMGP->heatingAmount); + } else { + p->heatingMatrix.Set(matrix3x3f::Identity()); + p->heatingNormal.Set(vector3f(0.0f, -1.0f, 0.0f)); + p->heatingAmount.Set(0.0f); + } + } + + void LitMultiMaterial::Apply() + { + //request a new light variation + if (m_curNumLights != m_renderer->m_numDirLights) { + m_curNumLights = m_renderer->m_numDirLights; + if (m_programs[m_curNumLights] == 0) { + m_descriptor.dirLights = m_curNumLights; //hax + m_programs[m_curNumLights] = m_renderer->GetOrCreateProgram(this); + } + m_program = m_programs[m_curNumLights]; + } + + MultiMaterial::Apply(); + + MultiProgram *p = static_cast(m_program); + p->emission.Set(this->emissive); + p->specular.Set(this->specular); + p->shininess.Set(float(this->shininess)); + p->sceneAmbient.Set(m_renderer->GetAmbientColor()); + + //Light uniform parameters + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + p->lights[i].diffuse.Set(Light.GetDiffuse()); + p->lights[i].specular.Set(Light.GetSpecular()); + const vector3f pos = Light.GetPosition(); + p->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + } + CHECKERRORS(); + } + + void MultiMaterial::Unapply() + { + // Might not be necessary to unbind textures, but let's not old graphics code (eg, old-UI) + if (heatGradient) { + static_cast(heatGradient)->Unbind(); + glActiveTexture(GL_TEXTURE6); + } + if (texture6) { + static_cast(texture6)->Unbind(); + glActiveTexture(GL_TEXTURE5); + } + if (texture5) { + static_cast(texture5)->Unbind(); + glActiveTexture(GL_TEXTURE4); + } + if (texture4) { + static_cast(texture4)->Unbind(); + glActiveTexture(GL_TEXTURE3); + } + if (texture3) { + static_cast(texture3)->Unbind(); + glActiveTexture(GL_TEXTURE2); + } + if (texture2) { + static_cast(texture2)->Unbind(); + glActiveTexture(GL_TEXTURE1); + } + if (texture1) { + static_cast(texture1)->Unbind(); + glActiveTexture(GL_TEXTURE0); + } + if (texture0) { + static_cast(texture0)->Unbind(); + } + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/MultiMaterial.h b/src/graphics/opengl/MultiMaterial.h index 2bf7987d8..38037bd9c 100644 --- a/src/graphics/opengl/MultiMaterial.h +++ b/src/graphics/opengl/MultiMaterial.h @@ -16,7 +16,7 @@ namespace Graphics { namespace OGL { class MultiProgram : public Program { public: - MultiProgram(const MaterialDescriptor &, int numLights=0); + MultiProgram(const MaterialDescriptor &, int numLights = 0); }; class MultiMaterial : public Material { //unlit @@ -38,10 +38,10 @@ namespace Graphics { virtual void Apply() override; private: - Program* m_programs[5]; + Program *m_programs[5]; Uint32 m_curNumLights; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/Program.cpp b/src/graphics/opengl/Program.cpp index 3d400e884..53458019f 100644 --- a/src/graphics/opengl/Program.cpp +++ b/src/graphics/opengl/Program.cpp @@ -3,48 +3,48 @@ #include "Program.h" #include "FileSystem.h" -#include "StringRange.h" -#include "StringF.h" #include "OS.h" +#include "StringF.h" +#include "StringRange.h" #include "graphics/Graphics.h" #include namespace Graphics { -namespace OGL { + namespace OGL { -// #version 140 for OpenGL3.1 -// #version 150 for OpenGL3.2 -// #version 330 for OpenGL3.3 -static const char *s_glslVersion = "#version 140\n"; -GLuint Program::s_curProgram = 0; + // #version 140 for OpenGL3.1 + // #version 150 for OpenGL3.2 + // #version 330 for OpenGL3.3 + static const char *s_glslVersion = "#version 140\n"; + GLuint Program::s_curProgram = 0; -// Check and warn about compile & link errors -static bool check_glsl_errors(const char *filename, GLuint obj) -{ - //check if shader or program - bool isShader = (glIsShader(obj) == GL_TRUE); + // Check and warn about compile & link errors + static bool check_glsl_errors(const char *filename, GLuint obj) + { + //check if shader or program + bool isShader = (glIsShader(obj) == GL_TRUE); - int infologLength = 0; - char infoLog[1024]; + int infologLength = 0; + char infoLog[1024]; - if (isShader) - glGetShaderInfoLog(obj, 1024, &infologLength, infoLog); - else - glGetProgramInfoLog(obj, 1024, &infologLength, infoLog); + if (isShader) + glGetShaderInfoLog(obj, 1024, &infologLength, infoLog); + else + glGetProgramInfoLog(obj, 1024, &infologLength, infoLog); - GLint status; - if (isShader) - glGetShaderiv(obj, GL_COMPILE_STATUS, &status); - else - glGetProgramiv(obj, GL_LINK_STATUS, &status); + GLint status; + if (isShader) + glGetShaderiv(obj, GL_COMPILE_STATUS, &status); + else + glGetProgramiv(obj, GL_LINK_STATUS, &status); - if (status == GL_FALSE) { - Error("Error compiling shader: %s:\n%sOpenGL vendor: %s\nOpenGL renderer string: %s", - filename, infoLog, glGetString(GL_VENDOR), glGetString(GL_RENDERER)); - return false; - } + if (status == GL_FALSE) { + Error("Error compiling shader: %s:\n%sOpenGL vendor: %s\nOpenGL renderer string: %s", + filename, infoLog, glGetString(GL_VENDOR), glGetString(GL_RENDERER)); + return false; + } #if 0 if (!isShader) { @@ -61,74 +61,71 @@ static bool check_glsl_errors(const char *filename, GLuint obj) } #endif - // Log warnings even if successfully compiled - // Sometimes the log is full of junk "success" messages so - // this is not a good use for OS::Warning + // Log warnings even if successfully compiled + // Sometimes the log is full of junk "success" messages so + // this is not a good use for OS::Warning #ifndef NDEBUG - if (infologLength > 0) { - if (pi_strcasestr("infoLog", "warning")) - Output("%s: %s", filename, infoLog); - } + if (infologLength > 0) { + if (pi_strcasestr("infoLog", "warning")) + Output("%s: %s", filename, infoLog); + } #endif - return true; -} - -struct Shader { - Shader(GLenum type, const std::string &filename, const std::string &defines) - { - RefCountedPtr filecode = FileSystem::gameDataFiles.ReadFile(filename); - - if (!filecode.Valid()) - Error("Could not load %s", filename.c_str()); - - std::string strCode(filecode->AsStringRange().ToString()); - size_t found = strCode.find("#include"); - while (found != std::string::npos) - { - // find the name of the file to include - const size_t begFilename = strCode.find_first_of("\"", found + 8) + 1; - const size_t endFilename = strCode.find_first_of("\"", begFilename + 1); - - const std::string incFilename = strCode.substr(begFilename, endFilename - begFilename); - - // check we haven't it already included it (avoids circular dependencies) - const std::set::const_iterator foundIt = previousIncludes.find(incFilename); - if (foundIt != previousIncludes.end()) { - Error("Circular, or multiple, include of %s\n", incFilename.c_str()); - } - else { - previousIncludes.insert(incFilename); - } - - // build path for include - const std::string incPathBuffer = stringf("shaders/opengl/%0", incFilename); - - // read included file - RefCountedPtr incCode = FileSystem::gameDataFiles.ReadFile(incPathBuffer); - assert(incCode.Valid()); - - if (incCode.Valid()) { - // replace the #include and filename with the included files text - strCode.replace(found, (endFilename + 1) - found, incCode->GetData(), incCode->GetSize()); - found = strCode.find("#include"); - } - else { - Error("Could not load %s", incPathBuffer.c_str()); - } + return true; } - // Store the modified text with the included files (if any) - const StringRange code(strCode.c_str(), strCode.size()); - // Build the final shader text to be compiled - AppendSource(s_glslVersion); - AppendSource(defines.c_str()); - if (type == GL_VERTEX_SHADER) { - AppendSource("#define VERTEX_SHADER\n"); - } else { - AppendSource("#define FRAGMENT_SHADER\n"); - } - AppendSource(code.StripUTF8BOM()); + struct Shader { + Shader(GLenum type, const std::string &filename, const std::string &defines) + { + RefCountedPtr filecode = FileSystem::gameDataFiles.ReadFile(filename); + + if (!filecode.Valid()) + Error("Could not load %s", filename.c_str()); + + std::string strCode(filecode->AsStringRange().ToString()); + size_t found = strCode.find("#include"); + while (found != std::string::npos) { + // find the name of the file to include + const size_t begFilename = strCode.find_first_of("\"", found + 8) + 1; + const size_t endFilename = strCode.find_first_of("\"", begFilename + 1); + + const std::string incFilename = strCode.substr(begFilename, endFilename - begFilename); + + // check we haven't it already included it (avoids circular dependencies) + const std::set::const_iterator foundIt = previousIncludes.find(incFilename); + if (foundIt != previousIncludes.end()) { + Error("Circular, or multiple, include of %s\n", incFilename.c_str()); + } else { + previousIncludes.insert(incFilename); + } + + // build path for include + const std::string incPathBuffer = stringf("shaders/opengl/%0", incFilename); + + // read included file + RefCountedPtr incCode = FileSystem::gameDataFiles.ReadFile(incPathBuffer); + assert(incCode.Valid()); + + if (incCode.Valid()) { + // replace the #include and filename with the included files text + strCode.replace(found, (endFilename + 1) - found, incCode->GetData(), incCode->GetSize()); + found = strCode.find("#include"); + } else { + Error("Could not load %s", incPathBuffer.c_str()); + } + } + // Store the modified text with the included files (if any) + const StringRange code(strCode.c_str(), strCode.size()); + + // Build the final shader text to be compiled + AppendSource(s_glslVersion); + AppendSource(defines.c_str()); + if (type == GL_VERTEX_SHADER) { + AppendSource("#define VERTEX_SHADER\n"); + } else { + AppendSource("#define FRAGMENT_SHADER\n"); + } + AppendSource(code.StripUTF8BOM()); #if 0 static bool s_bDumpShaderSource = true; if (s_bDumpShaderSource) { @@ -153,170 +150,171 @@ struct Shader { } } #endif - shader = glCreateShader(type); - if(glIsShader(shader)!=GL_TRUE) - throw ShaderException(); + shader = glCreateShader(type); + if (glIsShader(shader) != GL_TRUE) + throw ShaderException(); - Compile(shader); + Compile(shader); - // CheckGLSL may use OS::Warning instead of Error so the game may still (attempt to) run - if (!check_glsl_errors(filename.c_str(), shader)) - throw ShaderException(); - }; + // CheckGLSL may use OS::Warning instead of Error so the game may still (attempt to) run + if (!check_glsl_errors(filename.c_str(), shader)) + throw ShaderException(); + }; - ~Shader() { - glDeleteShader(shader); - } + ~Shader() + { + glDeleteShader(shader); + } - GLuint shader; + GLuint shader; -private: - void AppendSource(const char *str) - { - blocks.push_back(str); - block_sizes.push_back(std::strlen(str)); - } + private: + void AppendSource(const char *str) + { + blocks.push_back(str); + block_sizes.push_back(std::strlen(str)); + } - void AppendSource(StringRange str) - { - blocks.push_back(str.begin); - block_sizes.push_back(str.Size()); - } + void AppendSource(StringRange str) + { + blocks.push_back(str.begin); + block_sizes.push_back(str.Size()); + } - void Compile(GLuint shader_id) - { - assert(blocks.size() == block_sizes.size()); - glShaderSource(shader_id, blocks.size(), &blocks[0], &block_sizes[0]); - glCompileShader(shader_id); - } + void Compile(GLuint shader_id) + { + assert(blocks.size() == block_sizes.size()); + glShaderSource(shader_id, blocks.size(), &blocks[0], &block_sizes[0]); + glCompileShader(shader_id); + } - std::vector blocks; - std::vector block_sizes; - std::set previousIncludes; -}; + std::vector blocks; + std::vector block_sizes; + std::set previousIncludes; + }; -Program::Program() -: m_name("") -, m_defines("") -, m_program(0) -, success(false) -{ -} + Program::Program() : + m_name(""), + m_defines(""), + m_program(0), + success(false) + { + } -Program::Program(const std::string &name, const std::string &defines) -: m_name(name) -, m_defines(defines) -, m_program(0) -, success(false) -{ - LoadShaders(name, defines); - InitUniforms(); -} + Program::Program(const std::string &name, const std::string &defines) : + m_name(name), + m_defines(defines), + m_program(0), + success(false) + { + LoadShaders(name, defines); + InitUniforms(); + } -Program::~Program() -{ - glDeleteProgram(m_program); -} + Program::~Program() + { + glDeleteProgram(m_program); + } -void Program::Reload() -{ - Unuse(); - glDeleteProgram(m_program); - LoadShaders(m_name, m_defines); - InitUniforms(); -} + void Program::Reload() + { + Unuse(); + glDeleteProgram(m_program); + LoadShaders(m_name, m_defines); + InitUniforms(); + } -void Program::Use() -{ - if (s_curProgram != m_program) - glUseProgram(m_program); - s_curProgram = m_program; -} + void Program::Use() + { + if (s_curProgram != m_program) + glUseProgram(m_program); + s_curProgram = m_program; + } -void Program::Unuse() -{ - glUseProgram(0); - s_curProgram = 0; -} + void Program::Unuse() + { + glUseProgram(0); + s_curProgram = 0; + } -//load, compile and link -void Program::LoadShaders(const std::string &name, const std::string &defines) -{ - PROFILE_SCOPED() - const std::string filename = std::string("shaders/opengl/") + name; + //load, compile and link + void Program::LoadShaders(const std::string &name, const std::string &defines) + { + PROFILE_SCOPED() + const std::string filename = std::string("shaders/opengl/") + name; - //load, create and compile shaders - Shader vs(GL_VERTEX_SHADER, filename + ".vert", defines); - Shader fs(GL_FRAGMENT_SHADER, filename + ".frag", defines); + //load, create and compile shaders + Shader vs(GL_VERTEX_SHADER, filename + ".vert", defines); + Shader fs(GL_FRAGMENT_SHADER, filename + ".frag", defines); - //create program, attach shaders and link - m_program = glCreateProgram(); - if(glIsProgram(m_program)!=GL_TRUE) - throw ProgramException(); + //create program, attach shaders and link + m_program = glCreateProgram(); + if (glIsProgram(m_program) != GL_TRUE) + throw ProgramException(); - glAttachShader(m_program, vs.shader); + glAttachShader(m_program, vs.shader); - glAttachShader(m_program, fs.shader); + glAttachShader(m_program, fs.shader); - //extra attribs, if they exist - glBindAttribLocation(m_program, 0, "a_vertex"); - glBindAttribLocation(m_program, 1, "a_normal"); - glBindAttribLocation(m_program, 2, "a_color"); - glBindAttribLocation(m_program, 3, "a_uv0"); - glBindAttribLocation(m_program, 4, "a_uv1"); - glBindAttribLocation(m_program, 5, "a_tangent"); - glBindAttribLocation(m_program, 6, "a_transform"); - // a_transform @ 6 shadows (uses) 7, 8, and 9 - // next available is layout (location = 10) + //extra attribs, if they exist + glBindAttribLocation(m_program, 0, "a_vertex"); + glBindAttribLocation(m_program, 1, "a_normal"); + glBindAttribLocation(m_program, 2, "a_color"); + glBindAttribLocation(m_program, 3, "a_uv0"); + glBindAttribLocation(m_program, 4, "a_uv1"); + glBindAttribLocation(m_program, 5, "a_tangent"); + glBindAttribLocation(m_program, 6, "a_transform"); + // a_transform @ 6 shadows (uses) 7, 8, and 9 + // next available is layout (location = 10) - glBindFragDataLocation(m_program, 0, "frag_color"); + glBindFragDataLocation(m_program, 0, "frag_color"); - glLinkProgram(m_program); + glLinkProgram(m_program); - success = check_glsl_errors(name.c_str(), m_program); + success = check_glsl_errors(name.c_str(), m_program); - //shaders may now be deleted by Shader destructor -} + //shaders may now be deleted by Shader destructor + } -void Program::InitUniforms() -{ - PROFILE_SCOPED() - //Init generic uniforms, like matrices - uProjectionMatrix.Init("uProjectionMatrix", m_program); - uViewMatrix.Init("uViewMatrix", m_program); - uViewMatrixInverse.Init("uViewMatrixInverse", m_program); - uViewProjectionMatrix.Init("uViewProjectionMatrix", m_program); - uNormalMatrix.Init("uNormalMatrix", m_program); + void Program::InitUniforms() + { + PROFILE_SCOPED() + //Init generic uniforms, like matrices + uProjectionMatrix.Init("uProjectionMatrix", m_program); + uViewMatrix.Init("uViewMatrix", m_program); + uViewMatrixInverse.Init("uViewMatrixInverse", m_program); + uViewProjectionMatrix.Init("uViewProjectionMatrix", m_program); + uNormalMatrix.Init("uNormalMatrix", m_program); - //Light uniform parameters - char cLight[64]; - for( int i=0 ; i<4 ; i++ ) { - snprintf(cLight, 64, "uLight[%d]", i); - const std::string strLight( cLight ); - lights[i].diffuse.Init( (strLight + ".diffuse").c_str(), m_program ); - lights[i].specular.Init( (strLight + ".specular").c_str(), m_program ); - lights[i].position.Init( (strLight + ".position").c_str(), m_program ); - } + //Light uniform parameters + char cLight[64]; + for (int i = 0; i < 4; i++) { + snprintf(cLight, 64, "uLight[%d]", i); + const std::string strLight(cLight); + lights[i].diffuse.Init((strLight + ".diffuse").c_str(), m_program); + lights[i].specular.Init((strLight + ".specular").c_str(), m_program); + lights[i].position.Init((strLight + ".position").c_str(), m_program); + } - invLogZfarPlus1.Init("invLogZfarPlus1", m_program); - diffuse.Init("material.diffuse", m_program); - emission.Init("material.emission", m_program); - specular.Init("material.specular", m_program); - shininess.Init("material.shininess", m_program); - texture0.Init("texture0", m_program); - texture1.Init("texture1", m_program); - texture2.Init("texture2", m_program); - texture3.Init("texture3", m_program); - texture4.Init("texture4", m_program); - texture5.Init("texture5", m_program); - texture6.Init("texture6", m_program); - heatGradient.Init("heatGradient", m_program); - heatingMatrix.Init("heatingMatrix", m_program); - heatingNormal.Init("heatingNormal", m_program); - heatingAmount.Init("heatingAmount", m_program); - sceneAmbient.Init("scene.ambient", m_program); -} + invLogZfarPlus1.Init("invLogZfarPlus1", m_program); + diffuse.Init("material.diffuse", m_program); + emission.Init("material.emission", m_program); + specular.Init("material.specular", m_program); + shininess.Init("material.shininess", m_program); + texture0.Init("texture0", m_program); + texture1.Init("texture1", m_program); + texture2.Init("texture2", m_program); + texture3.Init("texture3", m_program); + texture4.Init("texture4", m_program); + texture5.Init("texture5", m_program); + texture6.Init("texture6", m_program); + heatGradient.Init("heatGradient", m_program); + heatingMatrix.Init("heatingMatrix", m_program); + heatingNormal.Init("heatingNormal", m_program); + heatingAmount.Init("heatingAmount", m_program); + sceneAmbient.Init("scene.ambient", m_program); + } -} // OGL + } // namespace OGL -} // Graphics +} // namespace Graphics diff --git a/src/graphics/opengl/Program.h b/src/graphics/opengl/Program.h index 51d47ad39..0dc5b423d 100644 --- a/src/graphics/opengl/Program.h +++ b/src/graphics/opengl/Program.h @@ -16,9 +16,9 @@ namespace Graphics { namespace OGL { - struct ShaderException { }; + struct ShaderException {}; - struct ProgramException { }; + struct ProgramException {}; class Program { public: @@ -67,7 +67,7 @@ namespace Graphics { protected: static GLuint s_curProgram; - void LoadShaders(const std::string&, const std::string &defines); + void LoadShaders(const std::string &, const std::string &defines); virtual void InitUniforms(); std::string m_name; std::string m_defines; @@ -75,7 +75,7 @@ namespace Graphics { bool success; }; - } + } // namespace OGL -} +} // namespace Graphics #endif diff --git a/src/graphics/opengl/RenderStateGL.cpp b/src/graphics/opengl/RenderStateGL.cpp index 53c9bae13..371b04021 100644 --- a/src/graphics/opengl/RenderStateGL.cpp +++ b/src/graphics/opengl/RenderStateGL.cpp @@ -4,71 +4,68 @@ #include "graphics/opengl/RenderStateGL.h" #include "OpenGLLibs.h" -namespace Graphics -{ -namespace OGL -{ +namespace Graphics { + namespace OGL { -RenderState::RenderState(const RenderStateDesc &d) - : Graphics::RenderState(d) -{ -} + RenderState::RenderState(const RenderStateDesc &d) : + Graphics::RenderState(d) + { + } -void RenderState::Apply() -{ - switch (m_desc.blendMode) { - case BLEND_SOLID: - glDisable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ZERO); - break; - case BLEND_ADDITIVE: - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - break; - case BLEND_ALPHA: - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case BLEND_ALPHA_ONE: - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - break; - case BLEND_ALPHA_PREMULT: - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - break; - case BLEND_SET_ALPHA: - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO); - break; - case BLEND_DEST_ALPHA: - glEnable(GL_BLEND); - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); - default: - break; - } + void RenderState::Apply() + { + switch (m_desc.blendMode) { + case BLEND_SOLID: + glDisable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ZERO); + break; + case BLEND_ADDITIVE: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + break; + case BLEND_ALPHA: + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case BLEND_ALPHA_ONE: + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case BLEND_ALPHA_PREMULT: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + break; + case BLEND_SET_ALPHA: + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO); + break; + case BLEND_DEST_ALPHA: + glEnable(GL_BLEND); + glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); + default: + break; + } - if (m_desc.cullMode == CULL_BACK) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } else if (m_desc.cullMode == CULL_FRONT) { - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - } else { - glDisable(GL_CULL_FACE); - } + if (m_desc.cullMode == CULL_BACK) { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } else if (m_desc.cullMode == CULL_FRONT) { + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + } else { + glDisable(GL_CULL_FACE); + } + if (m_desc.depthTest) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); - if (m_desc.depthTest) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); + if (m_desc.depthWrite) + glDepthMask(GL_TRUE); + else + glDepthMask(GL_FALSE); + } - if (m_desc.depthWrite) - glDepthMask(GL_TRUE); - else - glDepthMask(GL_FALSE); -} - -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/RenderStateGL.h b/src/graphics/opengl/RenderStateGL.h index 9e151cddb..56b1fc97f 100644 --- a/src/graphics/opengl/RenderStateGL.h +++ b/src/graphics/opengl/RenderStateGL.h @@ -6,14 +6,14 @@ #include "graphics/RenderState.h" namespace Graphics { -namespace OGL { + namespace OGL { -class RenderState : public Graphics::RenderState { -public: - RenderState(const RenderStateDesc&); - void Apply(); -}; + class RenderState : public Graphics::RenderState { + public: + RenderState(const RenderStateDesc &); + void Apply(); + }; -} -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/RenderTargetGL.cpp b/src/graphics/opengl/RenderTargetGL.cpp index 84f91720f..20c94ee8c 100644 --- a/src/graphics/opengl/RenderTargetGL.cpp +++ b/src/graphics/opengl/RenderTargetGL.cpp @@ -4,119 +4,121 @@ #include "RenderTargetGL.h" #include "TextureGL.h" -namespace Graphics { namespace OGL { +namespace Graphics { + namespace OGL { -RenderBuffer::RenderBuffer() -{ - glGenRenderbuffers(1, &buffer); -} + RenderBuffer::RenderBuffer() + { + glGenRenderbuffers(1, &buffer); + } -RenderBuffer::~RenderBuffer() -{ - glDeleteRenderbuffers(1, &buffer); -} + RenderBuffer::~RenderBuffer() + { + glDeleteRenderbuffers(1, &buffer); + } -void RenderBuffer::Bind() -{ - glBindRenderbuffer(GL_RENDERBUFFER, buffer); -} + void RenderBuffer::Bind() + { + glBindRenderbuffer(GL_RENDERBUFFER, buffer); + } -void RenderBuffer::Unbind() -{ - glBindRenderbuffer(GL_RENDERBUFFER, 0); -} + void RenderBuffer::Unbind() + { + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } -void RenderBuffer::Attach(GLenum attachment) -{ - glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, buffer); -} + void RenderBuffer::Attach(GLenum attachment) + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, buffer); + } -RenderTarget::RenderTarget(const RenderTargetDesc &d) -: Graphics::RenderTarget(d) -, m_active(false) -{ - glGenFramebuffers(1, &m_fbo); -} + RenderTarget::RenderTarget(const RenderTargetDesc &d) : + Graphics::RenderTarget(d), + m_active(false) + { + glGenFramebuffers(1, &m_fbo); + } -RenderTarget::~RenderTarget() -{ - glDeleteFramebuffers(1, &m_fbo); -} + RenderTarget::~RenderTarget() + { + glDeleteFramebuffers(1, &m_fbo); + } -Texture *RenderTarget::GetColorTexture() const -{ - return m_colorTexture.Get(); -} + Texture *RenderTarget::GetColorTexture() const + { + return m_colorTexture.Get(); + } -Texture *RenderTarget::GetDepthTexture() const -{ - assert(GetDesc().allowDepthTexture); - return m_depthTexture.Get(); -} + Texture *RenderTarget::GetDepthTexture() const + { + assert(GetDesc().allowDepthTexture); + return m_depthTexture.Get(); + } -void RenderTarget::SetCubeFaceTexture(const Uint32 face, Texture* t) -{ - const bool bound = m_active; - if (!bound) Bind(); - //texture format should match the intended fbo format (aka. the one attached first) - GLuint texId = 0; - if (t) texId = static_cast(t)->GetTextureID(); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texId, 0); - m_colorTexture.Reset(t); - if (!bound) Unbind(); -} + void RenderTarget::SetCubeFaceTexture(const Uint32 face, Texture *t) + { + const bool bound = m_active; + if (!bound) Bind(); + //texture format should match the intended fbo format (aka. the one attached first) + GLuint texId = 0; + if (t) texId = static_cast(t)->GetTextureID(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texId, 0); + m_colorTexture.Reset(t); + if (!bound) Unbind(); + } -void RenderTarget::SetColorTexture(Texture* t) -{ - const bool bound = m_active; - if (!bound) Bind(); - //texture format should match the intended fbo format (aka. the one attached first) - GLuint texId = 0; - if (t) texId = static_cast(t)->GetTextureID(); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); - m_colorTexture.Reset(t); - if (!bound) Unbind(); -} + void RenderTarget::SetColorTexture(Texture *t) + { + const bool bound = m_active; + if (!bound) Bind(); + //texture format should match the intended fbo format (aka. the one attached first) + GLuint texId = 0; + if (t) texId = static_cast(t)->GetTextureID(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); + m_colorTexture.Reset(t); + if (!bound) Unbind(); + } -void RenderTarget::SetDepthTexture(Texture* t) -{ - assert(GetDesc().allowDepthTexture); - const bool bound = m_active; - if (!bound) Bind(); - if (!GetDesc().allowDepthTexture) return; - GLuint texId = 0; - if (t) texId = static_cast(t)->GetTextureID(); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0); - m_depthTexture.Reset(t); - if (!bound) Unbind(); -} + void RenderTarget::SetDepthTexture(Texture *t) + { + assert(GetDesc().allowDepthTexture); + const bool bound = m_active; + if (!bound) Bind(); + if (!GetDesc().allowDepthTexture) return; + GLuint texId = 0; + if (t) texId = static_cast(t)->GetTextureID(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0); + m_depthTexture.Reset(t); + if (!bound) Unbind(); + } -void RenderTarget::Bind() -{ - glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); - m_active = true; -} + void RenderTarget::Bind() + { + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + m_active = true; + } -void RenderTarget::Unbind() -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); - m_active = false; -} + void RenderTarget::Unbind() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + m_active = false; + } -bool RenderTarget::CheckStatus() -{ - return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; -} + bool RenderTarget::CheckStatus() + { + return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; + } -void RenderTarget::CreateDepthRenderbuffer() -{ - assert(!GetDesc().allowDepthTexture); - assert(m_active); - m_depthRenderBuffer.Reset(new RenderBuffer()); - m_depthRenderBuffer->Bind(); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, GetDesc().width, GetDesc().height); - m_depthRenderBuffer->Attach(GL_DEPTH_ATTACHMENT); - m_depthRenderBuffer->Unbind(); -} + void RenderTarget::CreateDepthRenderbuffer() + { + assert(!GetDesc().allowDepthTexture); + assert(m_active); + m_depthRenderBuffer.Reset(new RenderBuffer()); + m_depthRenderBuffer->Bind(); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, GetDesc().width, GetDesc().height); + m_depthRenderBuffer->Attach(GL_DEPTH_ATTACHMENT); + m_depthRenderBuffer->Unbind(); + } -} } + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/RenderTargetGL.h b/src/graphics/opengl/RenderTargetGL.h index 4e225cc96..6b81f164e 100644 --- a/src/graphics/opengl/RenderTargetGL.h +++ b/src/graphics/opengl/RenderTargetGL.h @@ -13,52 +13,52 @@ namespace Graphics { -class RendererOGL; + class RendererOGL; -namespace OGL { + namespace OGL { -class RenderTarget; + class RenderTarget; -class RenderBuffer : public RefCounted { -public: - ~RenderBuffer(); - void Bind(); - void Unbind(); - void Attach(GLenum attachment); + class RenderBuffer : public RefCounted { + public: + ~RenderBuffer(); + void Bind(); + void Unbind(); + void Attach(GLenum attachment); -protected: - friend class RenderTarget; - RenderBuffer(); - GLuint buffer; -}; + protected: + friend class RenderTarget; + RenderBuffer(); + GLuint buffer; + }; -class RenderTarget : public Graphics::RenderTarget { -public: - ~RenderTarget(); - virtual Texture *GetColorTexture() const; - virtual Texture *GetDepthTexture() const; - virtual void SetCubeFaceTexture(const Uint32 face, Texture* t) final; - virtual void SetColorTexture(Texture*) final; - virtual void SetDepthTexture(Texture*) final; + class RenderTarget : public Graphics::RenderTarget { + public: + ~RenderTarget(); + virtual Texture *GetColorTexture() const; + virtual Texture *GetDepthTexture() const; + virtual void SetCubeFaceTexture(const Uint32 face, Texture *t) final; + virtual void SetColorTexture(Texture *) final; + virtual void SetDepthTexture(Texture *) final; -protected: - friend class Graphics::RendererOGL; - RenderTarget(const RenderTargetDesc &); - void Bind(); - void Unbind(); - void CreateDepthRenderbuffer(); - bool CheckStatus(); + protected: + friend class Graphics::RendererOGL; + RenderTarget(const RenderTargetDesc &); + void Bind(); + void Unbind(); + void CreateDepthRenderbuffer(); + bool CheckStatus(); - bool m_active; - GLuint m_fbo; + bool m_active; + GLuint m_fbo; - RefCountedPtr m_depthRenderBuffer; - RefCountedPtr m_colorTexture; - RefCountedPtr m_depthTexture; -}; + RefCountedPtr m_depthRenderBuffer; + RefCountedPtr m_colorTexture; + RefCountedPtr m_depthTexture; + }; -} + } // namespace OGL -} +} // namespace Graphics #endif diff --git a/src/graphics/opengl/RendererGL.cpp b/src/graphics/opengl/RendererGL.cpp index a52519cdb..7b6a664b9 100644 --- a/src/graphics/opengl/RendererGL.cpp +++ b/src/graphics/opengl/RendererGL.cpp @@ -2,262 +2,261 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "RendererGL.h" +#include "GLDebug.h" +#include "OS.h" +#include "Program.h" +#include "RenderStateGL.h" +#include "RenderTargetGL.h" +#include "StringF.h" +#include "TextureGL.h" +#include "VertexBufferGL.h" #include "graphics/Graphics.h" #include "graphics/Light.h" #include "graphics/Material.h" -#include "OS.h" -#include "StringF.h" #include "graphics/Texture.h" #include "graphics/TextureBuilder.h" -#include "TextureGL.h" #include "graphics/VertexArray.h" -#include "GLDebug.h" -#include "GasGiantMaterial.h" -#include "GeoSphereMaterial.h" -#include "GenGasGiantColourMaterial.h" -#include "MaterialGL.h" -#include "RenderStateGL.h" -#include "RenderTargetGL.h" -#include "VertexBufferGL.h" -#include "MultiMaterial.h" -#include "Program.h" -#include "RingMaterial.h" -#include "StarfieldMaterial.h" + +#include "BillboardMaterial.h" #include "FresnelColourMaterial.h" +#include "GasGiantMaterial.h" +#include "GenGasGiantColourMaterial.h" +#include "GeoSphereMaterial.h" +#include "MaterialGL.h" +#include "MultiMaterial.h" +#include "RingMaterial.h" #include "ShieldMaterial.h" #include "SkyboxMaterial.h" #include "SphereImpostorMaterial.h" +#include "StarfieldMaterial.h" #include "UIMaterial.h" #include "VtxColorMaterial.h" -#include "BillboardMaterial.h" #include //for offsetof +#include #include #include -#include namespace Graphics { -static bool CreateWindowAndContext(const char *name, const Graphics::Settings &vs, int samples, int depth_bits, SDL_Window **window, SDL_GLContext *context) -{ - Uint32 winFlags = 0; - - assert(vs.rendererType==Graphics::RendererType::RENDERER_OPENGL_3x); - - winFlags |= SDL_WINDOW_OPENGL; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - // cannot initialise 3.x content on OSX with anything but CORE profile - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - // OSX also forces us to use this for 3.2 onwards - if (vs.gl3ForwardCompatible) SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth_bits); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); - - // need full 32-bit color - // (need an alpha channel because of the way progress bars are drawn) - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - winFlags |= (vs.hidden ? SDL_WINDOW_HIDDEN : SDL_WINDOW_SHOWN); - if (!vs.hidden && vs.fullscreen) - winFlags |= SDL_WINDOW_FULLSCREEN; - - (*window) = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, vs.width, vs.height, winFlags); - if (!(*window)) - return false; - - (*context) = SDL_GL_CreateContext((*window)); - if (!(*context)) { - SDL_DestroyWindow((*window)); - (*window) = nullptr; - return false; - } - - return true; -} - -static Renderer *CreateRenderer(const Settings &vs) -{ - bool ok; - - const std::string name("Pioneer"); - SDL_Window *window = nullptr; - SDL_GLContext glContext = nullptr; - - // attempt sequence is: - // 1- requested mode - ok = CreateWindowAndContext(name.c_str(), vs, vs.requestedSamples, 24, &window, &glContext); - - // 2- requested mode with no anti-aliasing (skipped if no AA was requested anyway) - // (skipped if no AA was requested anyway) - if (!ok && vs.requestedSamples) { - Output("Failed to set video mode. (%s). Re-trying without multisampling.\n", SDL_GetError()); - ok = CreateWindowAndContext(name.c_str(), vs, 0, 24, &window, &glContext); - } - - // 3- requested mode with 16 bit depth buffer - if (!ok) { - Output("Failed to set video mode. (%s). Re-trying with 16-bit depth buffer\n", SDL_GetError()); - ok = CreateWindowAndContext(name.c_str(), vs, vs.requestedSamples, 16, &window, &glContext); - } - - // 4- requested mode with 16-bit depth buffer and no anti-aliasing - // (skipped if no AA was requested anyway) - if (!ok && vs.requestedSamples) { - Output("Failed to set video mode. (%s). Re-trying with 16-bit depth buffer and no multisampling\n", SDL_GetError()); - ok = CreateWindowAndContext(name.c_str(), vs, 0, 16, &window, &glContext); - } - - // 5- abort! - if (!ok) { - Warning("Failed to set video mode: %s", SDL_GetError()); - return nullptr; - } - - SDLSurfacePtr surface = LoadSurfaceFromFile(vs.iconFile); - if (surface) - SDL_SetWindowIcon(window, surface.Get()); - - SDL_SetWindowTitle(window, vs.title); - SDL_ShowCursor(0); - - SDL_GL_SetSwapInterval((vs.vsync!=0) ? 1 : 0); - - return new RendererOGL(window, vs, glContext); -} - -// static method instantiations -void RendererOGL::RegisterRenderer() { - Graphics::RegisterRenderer(Graphics::RENDERER_OPENGL_3x, CreateRenderer); -} - -// static member instantiations -bool RendererOGL::initted = false; -RendererOGL::AttribBufferMap RendererOGL::s_AttribBufferMap; - -// typedefs -typedef std::vector >::const_iterator ProgramIterator; - -// ---------------------------------------------------------------------------- -RendererOGL::RendererOGL(SDL_Window *window, const Graphics::Settings &vs, SDL_GLContext &glContext) -: Renderer(window, vs.width, vs.height) -, m_numLights(0) -, m_numDirLights(0) -//the range is very large due to a "logarithmic z-buffer" trick used -//http://outerra.blogspot.com/2009/08/logarithmic-z-buffer.html -//http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/ -, m_minZNear(0.001f) -, m_maxZFar(100000000.0f) -, m_useCompressedTextures(false) -, m_invLogZfarPlus1(0.f) -, m_activeRenderTarget(0) -, m_activeRenderState(nullptr) -, m_matrixMode(MatrixMode::MODELVIEW) -, m_glContext(glContext) -{ - glewExperimental = true; - GLenum glew_err; - if ((glew_err = glewInit()) != GLEW_OK) - Error("GLEW initialisation failed: %s", glewGetErrorString(glew_err)); - - // pump this once as glewExperimental is necessary but spews a single error - glGetError(); - - if (!glewIsSupported("GL_VERSION_3_1") ) + static bool CreateWindowAndContext(const char *name, const Graphics::Settings &vs, int samples, int depth_bits, SDL_Window **window, SDL_GLContext *context) { - Error( - "Pioneer can not run on your graphics card as it does not appear to support OpenGL 3.1\n" - "Please check to see if your GPU driver vendor has an updated driver - or that drivers are installed correctly." - ); - } + Uint32 winFlags = 0; - if (!glewIsSupported("GL_EXT_texture_compression_s3tc")) - { - if (glewIsSupported("GL_ARB_texture_compression")) { - GLint intv[4]; - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &intv[0]); - if( intv[0] == 0 ) { - Error("GL_NUM_COMPRESSED_TEXTURE_FORMATS is zero.\nPioneer can not run on your graphics card as it does not support compressed (DXTn/S3TC) format textures."); - } - } else { - Error( - "OpenGL extension GL_EXT_texture_compression_s3tc not supported.\n" - "Pioneer can not run on your graphics card as it does not support compressed (DXTn/S3TC) format textures." - ); + assert(vs.rendererType == Graphics::RendererType::RENDERER_OPENGL_3x); + + winFlags |= SDL_WINDOW_OPENGL; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + // cannot initialise 3.x content on OSX with anything but CORE profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + // OSX also forces us to use this for 3.2 onwards + if (vs.gl3ForwardCompatible) SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth_bits); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); + + // need full 32-bit color + // (need an alpha channel because of the way progress bars are drawn) + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + + winFlags |= (vs.hidden ? SDL_WINDOW_HIDDEN : SDL_WINDOW_SHOWN); + if (!vs.hidden && vs.fullscreen) + winFlags |= SDL_WINDOW_FULLSCREEN; + + (*window) = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, vs.width, vs.height, winFlags); + if (!(*window)) + return false; + + (*context) = SDL_GL_CreateContext((*window)); + if (!(*context)) { + SDL_DestroyWindow((*window)); + (*window) = nullptr; + return false; } + + return true; } - const char *ver = reinterpret_cast(glGetString(GL_VERSION)); - if (vs.gl3ForwardCompatible && strstr(ver, "9.17.10.4229")) { - Warning("Driver needs GL3ForwardCompatible=0 in config.ini to display billboards (stars, navlights etc.)"); + static Renderer *CreateRenderer(const Settings &vs) + { + bool ok; + + const std::string name("Pioneer"); + SDL_Window *window = nullptr; + SDL_GLContext glContext = nullptr; + + // attempt sequence is: + // 1- requested mode + ok = CreateWindowAndContext(name.c_str(), vs, vs.requestedSamples, 24, &window, &glContext); + + // 2- requested mode with no anti-aliasing (skipped if no AA was requested anyway) + // (skipped if no AA was requested anyway) + if (!ok && vs.requestedSamples) { + Output("Failed to set video mode. (%s). Re-trying without multisampling.\n", SDL_GetError()); + ok = CreateWindowAndContext(name.c_str(), vs, 0, 24, &window, &glContext); + } + + // 3- requested mode with 16 bit depth buffer + if (!ok) { + Output("Failed to set video mode. (%s). Re-trying with 16-bit depth buffer\n", SDL_GetError()); + ok = CreateWindowAndContext(name.c_str(), vs, vs.requestedSamples, 16, &window, &glContext); + } + + // 4- requested mode with 16-bit depth buffer and no anti-aliasing + // (skipped if no AA was requested anyway) + if (!ok && vs.requestedSamples) { + Output("Failed to set video mode. (%s). Re-trying with 16-bit depth buffer and no multisampling\n", SDL_GetError()); + ok = CreateWindowAndContext(name.c_str(), vs, 0, 16, &window, &glContext); + } + + // 5- abort! + if (!ok) { + Warning("Failed to set video mode: %s", SDL_GetError()); + return nullptr; + } + + SDLSurfacePtr surface = LoadSurfaceFromFile(vs.iconFile); + if (surface) + SDL_SetWindowIcon(window, surface.Get()); + + SDL_SetWindowTitle(window, vs.title); + SDL_ShowCursor(0); + + SDL_GL_SetSwapInterval((vs.vsync != 0) ? 1 : 0); + + return new RendererOGL(window, vs, glContext); } - TextureBuilder::Init(); + // static method instantiations + void RendererOGL::RegisterRenderer() + { + Graphics::RegisterRenderer(Graphics::RENDERER_OPENGL_3x, CreateRenderer); + } - m_viewportStack.push(Viewport()); + // static member instantiations + bool RendererOGL::initted = false; + RendererOGL::AttribBufferMap RendererOGL::s_AttribBufferMap; - const bool useDXTnTextures = vs.useTextureCompression; - m_useCompressedTextures = useDXTnTextures; + // typedefs + typedef std::vector>::const_iterator ProgramIterator; - const bool useAnisotropicFiltering = vs.useAnisotropicFiltering; - m_useAnisotropicFiltering = useAnisotropicFiltering; + // ---------------------------------------------------------------------------- + RendererOGL::RendererOGL(SDL_Window *window, const Graphics::Settings &vs, SDL_GLContext &glContext) : + Renderer(window, vs.width, vs.height), + m_numLights(0), + m_numDirLights(0) + //the range is very large due to a "logarithmic z-buffer" trick used + //http://outerra.blogspot.com/2009/08/logarithmic-z-buffer.html + //http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/ + , + m_minZNear(0.001f), + m_maxZFar(100000000.0f), + m_useCompressedTextures(false), + m_invLogZfarPlus1(0.f), + m_activeRenderTarget(0), + m_activeRenderState(nullptr), + m_matrixMode(MatrixMode::MODELVIEW), + m_glContext(glContext) + { + glewExperimental = true; + GLenum glew_err; + if ((glew_err = glewInit()) != GLEW_OK) + Error("GLEW initialisation failed: %s", glewGetErrorString(glew_err)); - //XXX bunch of fixed function states here! - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glDepthRange(0.0,1.0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - glEnable(GL_PROGRAM_POINT_SIZE); - if (!vs.gl3ForwardCompatible) glEnable(GL_POINT_SPRITE); // GL_POINT_SPRITE hack for compatibility contexts + // pump this once as glewExperimental is necessary but spews a single error + glGetError(); - glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); - glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_NICEST); + if (!glewIsSupported("GL_VERSION_3_1")) { + Error( + "Pioneer can not run on your graphics card as it does not appear to support OpenGL 3.1\n" + "Please check to see if your GPU driver vendor has an updated driver - or that drivers are installed correctly."); + } - SetMatrixMode(MatrixMode::MODELVIEW); + if (!glewIsSupported("GL_EXT_texture_compression_s3tc")) { + if (glewIsSupported("GL_ARB_texture_compression")) { + GLint intv[4]; + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &intv[0]); + if (intv[0] == 0) { + Error("GL_NUM_COMPRESSED_TEXTURE_FORMATS is zero.\nPioneer can not run on your graphics card as it does not support compressed (DXTn/S3TC) format textures."); + } + } else { + Error( + "OpenGL extension GL_EXT_texture_compression_s3tc not supported.\n" + "Pioneer can not run on your graphics card as it does not support compressed (DXTn/S3TC) format textures."); + } + } - m_modelViewStack.push(matrix4x4f::Identity()); - m_projectionStack.push(matrix4x4f::Identity()); + const char *ver = reinterpret_cast(glGetString(GL_VERSION)); + if (vs.gl3ForwardCompatible && strstr(ver, "9.17.10.4229")) { + Warning("Driver needs GL3ForwardCompatible=0 in config.ini to display billboards (stars, navlights etc.)"); + } - SetClearColor(Color4f(0.f, 0.f, 0.f, 0.f)); - SetViewport(0, 0, m_width, m_height); + TextureBuilder::Init(); - if (vs.enableDebugMessages) - GLDebug::Enable(); + m_viewportStack.push(Viewport()); - // check enum PrimitiveType matches OpenGL values - assert(POINTS == GL_POINTS); - assert(LINE_SINGLE == GL_LINES); - assert(LINE_LOOP == GL_LINE_LOOP); - assert(LINE_STRIP == GL_LINE_STRIP); - assert(TRIANGLES == GL_TRIANGLES); - assert(TRIANGLE_STRIP == GL_TRIANGLE_STRIP); - assert(TRIANGLE_FAN == GL_TRIANGLE_FAN); -} + const bool useDXTnTextures = vs.useTextureCompression; + m_useCompressedTextures = useDXTnTextures; -RendererOGL::~RendererOGL() -{ - // HACK ANDYC - this crashes when shutting down? They'll be released anyway right? - //while (!m_programs.empty()) delete m_programs.back().second, m_programs.pop_back(); - for (auto state : m_renderStates) - delete state.second; + const bool useAnisotropicFiltering = vs.useAnisotropicFiltering; + m_useAnisotropicFiltering = useAnisotropicFiltering; - SDL_GL_DeleteContext(m_glContext); -} + //XXX bunch of fixed function states here! + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDepthRange(0.0, 1.0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + glEnable(GL_PROGRAM_POINT_SIZE); + if (!vs.gl3ForwardCompatible) glEnable(GL_POINT_SPRITE); // GL_POINT_SPRITE hack for compatibility contexts -static const char *gl_error_to_string(GLenum err) -{ - switch (err) { + glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); + glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_NICEST); + + SetMatrixMode(MatrixMode::MODELVIEW); + + m_modelViewStack.push(matrix4x4f::Identity()); + m_projectionStack.push(matrix4x4f::Identity()); + + SetClearColor(Color4f(0.f, 0.f, 0.f, 0.f)); + SetViewport(0, 0, m_width, m_height); + + if (vs.enableDebugMessages) + GLDebug::Enable(); + + // check enum PrimitiveType matches OpenGL values + assert(POINTS == GL_POINTS); + assert(LINE_SINGLE == GL_LINES); + assert(LINE_LOOP == GL_LINE_LOOP); + assert(LINE_STRIP == GL_LINE_STRIP); + assert(TRIANGLES == GL_TRIANGLES); + assert(TRIANGLE_STRIP == GL_TRIANGLE_STRIP); + assert(TRIANGLE_FAN == GL_TRIANGLE_FAN); + } + + RendererOGL::~RendererOGL() + { + // HACK ANDYC - this crashes when shutting down? They'll be released anyway right? + //while (!m_programs.empty()) delete m_programs.back().second, m_programs.pop_back(); + for (auto state : m_renderStates) + delete state.second; + + SDL_GL_DeleteContext(m_glContext); + } + + static const char *gl_error_to_string(GLenum err) + { + switch (err) { case GL_NO_ERROR: return "(no error)"; case GL_INVALID_ENUM: return "invalid enum"; case GL_INVALID_VALUE: return "invalid value"; @@ -265,824 +264,801 @@ static const char *gl_error_to_string(GLenum err) case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffer operation"; case GL_OUT_OF_MEMORY: return "out of memory"; default: return "(unknown error)"; - } -} - -static void dump_and_clear_opengl_errors(std::ostream &out, GLenum first_error = GL_NO_ERROR) -{ - GLenum err = ((first_error == GL_NO_ERROR) ? glGetError() : first_error); - if (err != GL_NO_ERROR) { - out << "errors: "; - do { - out << gl_error_to_string(err) << " "; - err = glGetError(); - } while (err != GL_NO_ERROR); - out << std::endl; - } -} - -static void dump_opengl_value(std::ostream &out, const char *name, GLenum id, int num_elems) -{ - assert(num_elems > 0 && num_elems <= 4); - assert(name); - - GLdouble e[4]; - glGetDoublev(id, e); - - GLenum err = glGetError(); - if (err == GL_NO_ERROR) { - out << name << " = " << e[0]; - for (int i = 1; i < num_elems; ++i) - out << ", " << e[i]; - out << "\n"; - } else { - while (err != GL_NO_ERROR) { - if (err == GL_INVALID_ENUM) { out << name << " -- not supported\n"; } - else { out << name << " -- unexpected error (" << err << ") retrieving value\n"; } - err = glGetError(); } } -} -void RendererOGL::WriteRendererInfo(std::ostream &out) const -{ - out << "OpenGL version " << glGetString(GL_VERSION); - out << ", running on " << glGetString(GL_VENDOR); - out << " " << glGetString(GL_RENDERER) << "\n"; - - out << "Available extensions:" << "\n"; - if (glewIsSupported("GL_VERSION_3_1")) + static void dump_and_clear_opengl_errors(std::ostream &out, GLenum first_error = GL_NO_ERROR) { - out << "Shading language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "\n"; - GLint numext = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &numext); - for (int i = 0; i < numext; ++i) { - out << " " << glGetStringi(GL_EXTENSIONS, i) << "\n"; + GLenum err = ((first_error == GL_NO_ERROR) ? glGetError() : first_error); + if (err != GL_NO_ERROR) { + out << "errors: "; + do { + out << gl_error_to_string(err) << " "; + err = glGetError(); + } while (err != GL_NO_ERROR); + out << std::endl; } } - else + + static void dump_opengl_value(std::ostream &out, const char *name, GLenum id, int num_elems) { - out << " "; - std::istringstream ext(reinterpret_cast(glGetString(GL_EXTENSIONS))); - std::copy( - std::istream_iterator(ext), - std::istream_iterator(), - std::ostream_iterator(out, "\n ")); + assert(num_elems > 0 && num_elems <= 4); + assert(name); + + GLdouble e[4]; + glGetDoublev(id, e); + + GLenum err = glGetError(); + if (err == GL_NO_ERROR) { + out << name << " = " << e[0]; + for (int i = 1; i < num_elems; ++i) + out << ", " << e[i]; + out << "\n"; + } else { + while (err != GL_NO_ERROR) { + if (err == GL_INVALID_ENUM) { + out << name << " -- not supported\n"; + } else { + out << name << " -- unexpected error (" << err << ") retrieving value\n"; + } + err = glGetError(); + } + } } - out << "\nImplementation Limits:\n"; + void RendererOGL::WriteRendererInfo(std::ostream &out) const + { + out << "OpenGL version " << glGetString(GL_VERSION); + out << ", running on " << glGetString(GL_VENDOR); + out << " " << glGetString(GL_RENDERER) << "\n"; - // first, clear all OpenGL error flags - dump_and_clear_opengl_errors(out); + out << "Available extensions:" + << "\n"; + if (glewIsSupported("GL_VERSION_3_1")) { + out << "Shading language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "\n"; + GLint numext = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numext); + for (int i = 0; i < numext; ++i) { + out << " " << glGetStringi(GL_EXTENSIONS, i) << "\n"; + } + } else { + out << " "; + std::istringstream ext(reinterpret_cast(glGetString(GL_EXTENSIONS))); + std::copy( + std::istream_iterator(ext), + std::istream_iterator(), + std::ostream_iterator(out, "\n ")); + } + + out << "\nImplementation Limits:\n"; + + // first, clear all OpenGL error flags + dump_and_clear_opengl_errors(out); #define DUMP_GL_VALUE(name) dump_opengl_value(out, #name, name, 1) #define DUMP_GL_VALUE2(name) dump_opengl_value(out, #name, name, 2) - DUMP_GL_VALUE(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); - DUMP_GL_VALUE(GL_MAX_CUBE_MAP_TEXTURE_SIZE); - DUMP_GL_VALUE(GL_MAX_DRAW_BUFFERS); - DUMP_GL_VALUE(GL_MAX_ELEMENTS_INDICES); - DUMP_GL_VALUE(GL_MAX_ELEMENTS_VERTICES); - DUMP_GL_VALUE(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); - DUMP_GL_VALUE(GL_MAX_TEXTURE_IMAGE_UNITS); - DUMP_GL_VALUE(GL_MAX_TEXTURE_LOD_BIAS); - DUMP_GL_VALUE(GL_MAX_TEXTURE_SIZE); - DUMP_GL_VALUE(GL_MAX_VERTEX_ATTRIBS); - DUMP_GL_VALUE(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - DUMP_GL_VALUE(GL_MAX_VERTEX_UNIFORM_COMPONENTS); - DUMP_GL_VALUE(GL_NUM_COMPRESSED_TEXTURE_FORMATS); - DUMP_GL_VALUE(GL_SAMPLE_BUFFERS); - DUMP_GL_VALUE(GL_SAMPLES); - DUMP_GL_VALUE2(GL_ALIASED_LINE_WIDTH_RANGE); - DUMP_GL_VALUE2(GL_MAX_VIEWPORT_DIMS); - DUMP_GL_VALUE2(GL_SMOOTH_LINE_WIDTH_RANGE); - DUMP_GL_VALUE2(GL_SMOOTH_POINT_SIZE_RANGE); + DUMP_GL_VALUE(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); + DUMP_GL_VALUE(GL_MAX_CUBE_MAP_TEXTURE_SIZE); + DUMP_GL_VALUE(GL_MAX_DRAW_BUFFERS); + DUMP_GL_VALUE(GL_MAX_ELEMENTS_INDICES); + DUMP_GL_VALUE(GL_MAX_ELEMENTS_VERTICES); + DUMP_GL_VALUE(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); + DUMP_GL_VALUE(GL_MAX_TEXTURE_IMAGE_UNITS); + DUMP_GL_VALUE(GL_MAX_TEXTURE_LOD_BIAS); + DUMP_GL_VALUE(GL_MAX_TEXTURE_SIZE); + DUMP_GL_VALUE(GL_MAX_VERTEX_ATTRIBS); + DUMP_GL_VALUE(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + DUMP_GL_VALUE(GL_MAX_VERTEX_UNIFORM_COMPONENTS); + DUMP_GL_VALUE(GL_NUM_COMPRESSED_TEXTURE_FORMATS); + DUMP_GL_VALUE(GL_SAMPLE_BUFFERS); + DUMP_GL_VALUE(GL_SAMPLES); + DUMP_GL_VALUE2(GL_ALIASED_LINE_WIDTH_RANGE); + DUMP_GL_VALUE2(GL_MAX_VIEWPORT_DIMS); + DUMP_GL_VALUE2(GL_SMOOTH_LINE_WIDTH_RANGE); + DUMP_GL_VALUE2(GL_SMOOTH_POINT_SIZE_RANGE); #undef DUMP_GL_VALUE #undef DUMP_GL_VALUE2 - // enumerate compressed texture formats - { - dump_and_clear_opengl_errors(out); - out << "\nCompressed texture formats:\n"; + // enumerate compressed texture formats + { + dump_and_clear_opengl_errors(out); + out << "\nCompressed texture formats:\n"; - GLint nformats; - GLint formats[128]; // XXX 128 should be enough, right? + GLint nformats; + GLint formats[128]; // XXX 128 should be enough, right? - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nformats); - GLenum err = glGetError(); - if (err != GL_NO_ERROR) { - out << "Get NUM_COMPRESSED_TEXTURE_FORMATS failed\n"; - dump_and_clear_opengl_errors(out, err); - } else { - assert(nformats >= 0 && nformats < int(COUNTOF(formats))); - glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); - err = glGetError(); + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nformats); + GLenum err = glGetError(); if (err != GL_NO_ERROR) { - out << "Get COMPRESSED_TEXTURE_FORMATS failed\n"; + out << "Get NUM_COMPRESSED_TEXTURE_FORMATS failed\n"; dump_and_clear_opengl_errors(out, err); } else { - for (int i = 0; i < nformats; ++i) { - out << stringf(" %0{x#}\n", unsigned(formats[i])); + assert(nformats >= 0 && nformats < int(COUNTOF(formats))); + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); + err = glGetError(); + if (err != GL_NO_ERROR) { + out << "Get COMPRESSED_TEXTURE_FORMATS failed\n"; + dump_and_clear_opengl_errors(out, err); + } else { + for (int i = 0; i < nformats; ++i) { + out << stringf(" %0{x#}\n", unsigned(formats[i])); + } } } } + // one last time + dump_and_clear_opengl_errors(out); } - // one last time - dump_and_clear_opengl_errors(out); -} -int RendererOGL::GetMaximumNumberAASamples() const -{ - GLint value = 0; - glGetIntegerv(GL_MAX_SAMPLES, &value); - return value; -} - -bool RendererOGL::GetNearFarRange(float &near_, float &far_) const -{ - near_ = m_minZNear; - far_ = m_maxZFar; - return true; -} - -bool RendererOGL::BeginFrame() -{ - PROFILE_SCOPED() - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - return true; -} - -bool RendererOGL::EndFrame() -{ - return true; -} - -static std::string glerr_to_string(GLenum err) -{ - switch (err) + int RendererOGL::GetMaximumNumberAASamples() const { - case GL_INVALID_ENUM: - return "GL_INVALID_ENUM"; - case GL_INVALID_VALUE: - return "GL_INVALID_VALUE"; - case GL_INVALID_OPERATION: - return "GL_INVALID_OPERATION"; - case GL_OUT_OF_MEMORY: - return "GL_OUT_OF_MEMORY"; - default: - return stringf("Unknown error 0x0%0{x}", err); + GLint value = 0; + glGetIntegerv(GL_MAX_SAMPLES, &value); + return value; } -} -void RendererOGL::CheckErrors(const char *func, const int line) -{ - PROFILE_SCOPED() + bool RendererOGL::GetNearFarRange(float &near_, float &far_) const + { + near_ = m_minZNear; + far_ = m_maxZFar; + return true; + } + + bool RendererOGL::BeginFrame() + { + PROFILE_SCOPED() + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + return true; + } + + bool RendererOGL::EndFrame() + { + return true; + } + + static std::string glerr_to_string(GLenum err) + { + switch (err) { + case GL_INVALID_ENUM: + return "GL_INVALID_ENUM"; + case GL_INVALID_VALUE: + return "GL_INVALID_VALUE"; + case GL_INVALID_OPERATION: + return "GL_INVALID_OPERATION"; + case GL_OUT_OF_MEMORY: + return "GL_OUT_OF_MEMORY"; + default: + return stringf("Unknown error 0x0%0{x}", err); + } + } + + void RendererOGL::CheckErrors(const char *func, const int line) + { + PROFILE_SCOPED() #ifndef PIONEER_PROFILER - GLenum err = glGetError(); - if( err ) { - // static-cache current err that sparked this - static GLenum s_prevErr = GL_NO_ERROR; - const bool showWarning = (s_prevErr != err); - s_prevErr = err; - // now build info string - std::stringstream ss; - assert(func!=nullptr && line>=0); - ss << "OpenGL error(s) during frame:\n"; - ss << "In function " << std::string(func) << "\nOn line " << std::to_string(line) << "\n"; - while (err != GL_NO_ERROR) { - ss << glerr_to_string(err) << '\n'; - err = glGetError(); - if( err == GL_OUT_OF_MEMORY ) { - ss << "Out-of-memory on graphics card." << std::endl - << "Recommend enabling \"Compress Textures\" in game options." << std::endl - << "Also try reducing City and Planet detail settings." << std::endl; - } + GLenum err = glGetError(); + if (err) { + // static-cache current err that sparked this + static GLenum s_prevErr = GL_NO_ERROR; + const bool showWarning = (s_prevErr != err); + s_prevErr = err; + // now build info string + std::stringstream ss; + assert(func != nullptr && line >= 0); + ss << "OpenGL error(s) during frame:\n"; + ss << "In function " << std::string(func) << "\nOn line " << std::to_string(line) << "\n"; + while (err != GL_NO_ERROR) { + ss << glerr_to_string(err) << '\n'; + err = glGetError(); + if (err == GL_OUT_OF_MEMORY) { + ss << "Out-of-memory on graphics card." << std::endl + << "Recommend enabling \"Compress Textures\" in game options." << std::endl + << "Also try reducing City and Planet detail settings." << std::endl; + } #ifdef _WIN32 - else if (err == GL_INVALID_OPERATION) { - ss << "Invalid operations can occur if you are using overlay software." << std::endl - << "Such as FRAPS, RivaTuner, MSI Afterburner etc." << std::endl - << "Please try disabling this kind of software and testing again, thankyou." << std::endl; + else if (err == GL_INVALID_OPERATION) { + ss << "Invalid operations can occur if you are using overlay software." << std::endl + << "Such as FRAPS, RivaTuner, MSI Afterburner etc." << std::endl + << "Please try disabling this kind of software and testing again, thankyou." << std::endl; + } +#endif } -#endif + // show warning dialog or just log to output + if (showWarning) + Warning("%s", ss.str().c_str()); + else + Output("%s", ss.str().c_str()); } - // show warning dialog or just log to output - if(showWarning) - Warning("%s", ss.str().c_str()); - else - Output("%s", ss.str().c_str()); - } #endif -} - -bool RendererOGL::SwapBuffers() -{ - PROFILE_SCOPED() - CheckRenderErrors(__FUNCTION__,__LINE__); - - SDL_GL_SwapWindow(m_window); - m_stats.NextFrame(); - return true; -} - -bool RendererOGL::SetRenderState(RenderState *rs) -{ - if (m_activeRenderState != rs) { - static_cast(rs)->Apply(); - m_activeRenderState = rs; } - CheckRenderErrors(__FUNCTION__,__LINE__); - return true; -} -bool RendererOGL::SetRenderTarget(RenderTarget *rt) -{ - PROFILE_SCOPED() - if (rt) - static_cast(rt)->Bind(); - else if (m_activeRenderTarget) - m_activeRenderTarget->Unbind(); + bool RendererOGL::SwapBuffers() + { + PROFILE_SCOPED() + CheckRenderErrors(__FUNCTION__, __LINE__); - m_activeRenderTarget = static_cast(rt); - CheckRenderErrors(__FUNCTION__,__LINE__); + SDL_GL_SwapWindow(m_window); + m_stats.NextFrame(); + return true; + } - return true; -} + bool RendererOGL::SetRenderState(RenderState *rs) + { + if (m_activeRenderState != rs) { + static_cast(rs)->Apply(); + m_activeRenderState = rs; + } + CheckRenderErrors(__FUNCTION__, __LINE__); + return true; + } -bool RendererOGL::SetDepthRange(double znear, double zfar) -{ - glDepthRange(znear, zfar); - return true; -} + bool RendererOGL::SetRenderTarget(RenderTarget *rt) + { + PROFILE_SCOPED() + if (rt) + static_cast(rt)->Bind(); + else if (m_activeRenderTarget) + m_activeRenderTarget->Unbind(); -bool RendererOGL::ClearScreen() -{ - m_activeRenderState = nullptr; - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - CheckRenderErrors(__FUNCTION__,__LINE__); + m_activeRenderTarget = static_cast(rt); + CheckRenderErrors(__FUNCTION__, __LINE__); - return true; -} + return true; + } -bool RendererOGL::ClearDepthBuffer() -{ - m_activeRenderState = nullptr; - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); - CheckRenderErrors(__FUNCTION__,__LINE__); + bool RendererOGL::SetDepthRange(double znear, double zfar) + { + glDepthRange(znear, zfar); + return true; + } - return true; -} + bool RendererOGL::ClearScreen() + { + m_activeRenderState = nullptr; + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + CheckRenderErrors(__FUNCTION__, __LINE__); -bool RendererOGL::SetClearColor(const Color &c) -{ - glClearColor(c.r, c.g, c.b, c.a); - return true; -} + return true; + } -bool RendererOGL::SetViewport(int x, int y, int width, int height) -{ - assert(!m_viewportStack.empty()); - Viewport& currentViewport = m_viewportStack.top(); - currentViewport.x = x; - currentViewport.y = y; - currentViewport.w = width; - currentViewport.h = height; - glViewport(x, y, width, height); - return true; -} + bool RendererOGL::ClearDepthBuffer() + { + m_activeRenderState = nullptr; + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + CheckRenderErrors(__FUNCTION__, __LINE__); -bool RendererOGL::SetTransform(const matrix4x4d &m) -{ - PROFILE_SCOPED() - matrix4x4f mf; - matrix4x4dtof(m, mf); - return SetTransform(mf); -} + return true; + } -bool RendererOGL::SetTransform(const matrix4x4f &m) -{ - PROFILE_SCOPED() - //same as above - SetMatrixMode(MatrixMode::MODELVIEW); - LoadMatrix(m); - return true; -} + bool RendererOGL::SetClearColor(const Color &c) + { + glClearColor(c.r, c.g, c.b, c.a); + return true; + } -bool RendererOGL::SetPerspectiveProjection(float fov, float aspect, float near_, float far_) -{ - PROFILE_SCOPED() + bool RendererOGL::SetViewport(int x, int y, int width, int height) + { + assert(!m_viewportStack.empty()); + Viewport ¤tViewport = m_viewportStack.top(); + currentViewport.x = x; + currentViewport.y = y; + currentViewport.w = width; + currentViewport.h = height; + glViewport(x, y, width, height); + return true; + } - // update values for log-z hack - m_invLogZfarPlus1 = 1.0f / (log1p(far_)/log(2.0f)); + bool RendererOGL::SetTransform(const matrix4x4d &m) + { + PROFILE_SCOPED() + matrix4x4f mf; + matrix4x4dtof(m, mf); + return SetTransform(mf); + } - Graphics::SetFov(fov); + bool RendererOGL::SetTransform(const matrix4x4f &m) + { + PROFILE_SCOPED() + //same as above + SetMatrixMode(MatrixMode::MODELVIEW); + LoadMatrix(m); + return true; + } - float ymax = near_ * tan(fov * M_PI / 360.0); - float ymin = -ymax; - float xmin = ymin * aspect; - float xmax = ymax * aspect; + bool RendererOGL::SetPerspectiveProjection(float fov, float aspect, float near_, float far_) + { + PROFILE_SCOPED() - const matrix4x4f frustrumMat = matrix4x4f::FrustumMatrix(xmin, xmax, ymin, ymax, near_, far_); - SetProjection(frustrumMat); - return true; -} + // update values for log-z hack + m_invLogZfarPlus1 = 1.0f / (log1p(far_) / log(2.0f)); -bool RendererOGL::SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) -{ - PROFILE_SCOPED() - const matrix4x4f orthoMat = matrix4x4f::OrthoFrustum(xmin, xmax, ymin, ymax, zmin, zmax); - SetProjection(orthoMat); - return true; -} + Graphics::SetFov(fov); -bool RendererOGL::SetProjection(const matrix4x4f &m) -{ - PROFILE_SCOPED() - //same as above - SetMatrixMode(MatrixMode::PROJECTION); - LoadMatrix(m); - return true; -} + float ymax = near_ * tan(fov * M_PI / 360.0); + float ymin = -ymax; + float xmin = ymin * aspect; + float xmax = ymax * aspect; -bool RendererOGL::SetWireFrameMode(bool enabled) -{ - glPolygonMode(GL_FRONT_AND_BACK, enabled ? GL_LINE : GL_FILL); - return true; -} + const matrix4x4f frustrumMat = matrix4x4f::FrustumMatrix(xmin, xmax, ymin, ymax, near_, far_); + SetProjection(frustrumMat); + return true; + } -bool RendererOGL::SetLights(Uint32 numlights, const Light *lights) -{ - numlights = std::min(numlights, TOTAL_NUM_LIGHTS); - if (numlights < 1) { - m_numLights = 0; + bool RendererOGL::SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) + { + PROFILE_SCOPED() + const matrix4x4f orthoMat = matrix4x4f::OrthoFrustum(xmin, xmax, ymin, ymax, zmin, zmax); + SetProjection(orthoMat); + return true; + } + + bool RendererOGL::SetProjection(const matrix4x4f &m) + { + PROFILE_SCOPED() + //same as above + SetMatrixMode(MatrixMode::PROJECTION); + LoadMatrix(m); + return true; + } + + bool RendererOGL::SetWireFrameMode(bool enabled) + { + glPolygonMode(GL_FRONT_AND_BACK, enabled ? GL_LINE : GL_FILL); + return true; + } + + bool RendererOGL::SetLights(Uint32 numlights, const Light *lights) + { + numlights = std::min(numlights, TOTAL_NUM_LIGHTS); + if (numlights < 1) { + m_numLights = 0; + m_numDirLights = 0; + return false; + } + + m_numLights = numlights; m_numDirLights = 0; - return false; + + for (Uint32 i = 0; i < numlights; i++) { + const Light &l = lights[i]; + m_lights[i].SetPosition(l.GetPosition()); + m_lights[i].SetDiffuse(l.GetDiffuse()); + m_lights[i].SetSpecular(l.GetSpecular()); + + if (l.GetType() == Light::LIGHT_DIRECTIONAL) + m_numDirLights++; + + assert(m_numDirLights <= TOTAL_NUM_LIGHTS); + } + + return true; } - m_numLights = numlights; - m_numDirLights = 0; - - for (Uint32 i = 0; iSetCommonUniforms(m_modelViewStack.top(), m_projectionStack.top()); - CheckRenderErrors(__FUNCTION__,__LINE__); -} + void RendererOGL::SetMaterialShaderTransforms(Material *m) + { + m->SetCommonUniforms(m_modelViewStack.top(), m_projectionStack.top()); + CheckRenderErrors(__FUNCTION__, __LINE__); + } -bool RendererOGL::DrawTriangles(const VertexArray *v, RenderState *rs, Material *m, PrimitiveType t) -{ - PROFILE_SCOPED() - if (!v || v->position.size() < 3) return false; + bool RendererOGL::DrawTriangles(const VertexArray *v, RenderState *rs, Material *m, PrimitiveType t) + { + PROFILE_SCOPED() + if (!v || v->position.size() < 3) return false; - const AttributeSet attribs = v->GetAttributeSet(); - RefCountedPtr drawVB; + const AttributeSet attribs = v->GetAttributeSet(); + RefCountedPtr drawVB; - // see if we have a buffer to re-use - AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(attribs, v->position.size())); - if (iter == s_AttribBufferMap.end()) { - // not found a buffer so create a new one - VertexBufferDesc vbd; - Uint32 attribIdx = 0; - assert(v->HasAttrib(ATTRIB_POSITION)); - vbd.attrib[attribIdx].semantic = ATTRIB_POSITION; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attribIdx; - - if (v->HasAttrib(ATTRIB_NORMAL)) { - vbd.attrib[attribIdx].semantic = ATTRIB_NORMAL; + // see if we have a buffer to re-use + AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(attribs, v->position.size())); + if (iter == s_AttribBufferMap.end()) { + // not found a buffer so create a new one + VertexBufferDesc vbd; + Uint32 attribIdx = 0; + assert(v->HasAttrib(ATTRIB_POSITION)); + vbd.attrib[attribIdx].semantic = ATTRIB_POSITION; vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; ++attribIdx; - } - if (v->HasAttrib(ATTRIB_DIFFUSE)) { - vbd.attrib[attribIdx].semantic = ATTRIB_DIFFUSE; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_UBYTE4; - ++attribIdx; - } - if (v->HasAttrib(ATTRIB_UV0)) { - vbd.attrib[attribIdx].semantic = ATTRIB_UV0; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT2; - ++attribIdx; - } - if (v->HasAttrib(ATTRIB_TANGENT)) { - vbd.attrib[attribIdx].semantic = ATTRIB_TANGENT; - vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; - ++attribIdx; - } - vbd.numVertices = static_cast(v->position.size()); - vbd.usage = BUFFER_USAGE_DYNAMIC; // dynamic since we'll be reusing these buffers if possible - // VertexBuffer - RefCountedPtr vb; - vb.Reset(CreateVertexBuffer(vbd)); - vb->Populate(*v); + if (v->HasAttrib(ATTRIB_NORMAL)) { + vbd.attrib[attribIdx].semantic = ATTRIB_NORMAL; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attribIdx; + } + if (v->HasAttrib(ATTRIB_DIFFUSE)) { + vbd.attrib[attribIdx].semantic = ATTRIB_DIFFUSE; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_UBYTE4; + ++attribIdx; + } + if (v->HasAttrib(ATTRIB_UV0)) { + vbd.attrib[attribIdx].semantic = ATTRIB_UV0; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT2; + ++attribIdx; + } + if (v->HasAttrib(ATTRIB_TANGENT)) { + vbd.attrib[attribIdx].semantic = ATTRIB_TANGENT; + vbd.attrib[attribIdx].format = ATTRIB_FORMAT_FLOAT3; + ++attribIdx; + } + vbd.numVertices = static_cast(v->position.size()); + vbd.usage = BUFFER_USAGE_DYNAMIC; // dynamic since we'll be reusing these buffers if possible - // add to map - s_AttribBufferMap[std::make_pair(attribs, v->position.size())] = vb; - drawVB = vb; + // VertexBuffer + RefCountedPtr vb; + vb.Reset(CreateVertexBuffer(vbd)); + vb->Populate(*v); + + // add to map + s_AttribBufferMap[std::make_pair(attribs, v->position.size())] = vb; + drawVB = vb; + } else { + // got a buffer so use it and fill it with newest data + drawVB = iter->second; + drawVB->Populate(*v); + } + + const bool res = DrawBuffer(drawVB.Get(), rs, m, t); + CheckRenderErrors(__FUNCTION__, __LINE__); + + m_stats.AddToStatCount(Stats::STAT_DRAWTRIS, 1); + + return res; } - else { + + bool RendererOGL::DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) + { + PROFILE_SCOPED() + if (count == 0 || !material || !material->texture0) + return false; + + size = Clamp(size, 0.1f, FLT_MAX); + +#pragma pack(push, 4) + struct PosNormVert { + vector3f pos; + vector3f norm; + }; +#pragma pack(pop) + + RefCountedPtr drawVB; + AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)); + if (iter == s_AttribBufferMap.end()) { + // NB - we're (ab)using the normal type to hold (uv coordinate offset value + point size) + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = count; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + + // VertexBuffer + RefCountedPtr vb; + vb.Reset(CreateVertexBuffer(vbd)); + + // add to map + s_AttribBufferMap[std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)] = vb; + drawVB = vb; + } else { + drawVB = iter->second; + } + // got a buffer so use it and fill it with newest data - drawVB = iter->second; - drawVB->Populate(*v); + PosNormVert *vtxPtr = drawVB->Map(Graphics::BUFFER_MAP_WRITE); + assert(drawVB->GetDesc().stride == sizeof(PosNormVert)); + for (Uint32 i = 0; i < count; i++) { + vtxPtr[i].pos = positions[i]; + vtxPtr[i].norm = vector3f(0.0f, 0.0f, size); + } + drawVB->Unmap(); + + SetTransform(matrix4x4f::Identity()); + DrawBuffer(drawVB.Get(), rs, material, Graphics::POINTS); + GetStats().AddToStatCount(Graphics::Stats::STAT_DRAWPOINTSPRITES, 1); + CheckRenderErrors(__FUNCTION__, __LINE__); + + return true; } - const bool res = DrawBuffer(drawVB.Get(), rs, m, t); - CheckRenderErrors(__FUNCTION__,__LINE__); - - m_stats.AddToStatCount(Stats::STAT_DRAWTRIS, 1); - - return res; -} - -bool RendererOGL::DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) -{ - PROFILE_SCOPED() - if (count == 0 || !material || !material->texture0) - return false; - - size = Clamp(size, 0.1f, FLT_MAX); - - #pragma pack(push, 4) - struct PosNormVert { - vector3f pos; - vector3f norm; - }; - #pragma pack(pop) - - RefCountedPtr drawVB; - AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)); - if (iter == s_AttribBufferMap.end()) + bool RendererOGL::DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) { - // NB - we're (ab)using the normal type to hold (uv coordinate offset value + point size) - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = count; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + PROFILE_SCOPED() + if (count == 0 || !material || !material->texture0) + return false; - // VertexBuffer - RefCountedPtr vb; - vb.Reset(CreateVertexBuffer(vbd)); +#pragma pack(push, 4) + struct PosNormVert { + vector3f pos; + vector3f norm; + }; +#pragma pack(pop) - // add to map - s_AttribBufferMap[std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)] = vb; - drawVB = vb; + RefCountedPtr drawVB; + AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)); + if (iter == s_AttribBufferMap.end()) { + // NB - we're (ab)using the normal type to hold (uv coordinate offset value + point size) + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = count; + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + + // VertexBuffer + RefCountedPtr vb; + vb.Reset(CreateVertexBuffer(vbd)); + + // add to map + s_AttribBufferMap[std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)] = vb; + drawVB = vb; + } else { + drawVB = iter->second; + } + + // got a buffer so use it and fill it with newest data + PosNormVert *vtxPtr = drawVB->Map(Graphics::BUFFER_MAP_WRITE); + assert(drawVB->GetDesc().stride == sizeof(PosNormVert)); + for (Uint32 i = 0; i < count; i++) { + vtxPtr[i].pos = positions[i]; + vtxPtr[i].norm = vector3f(offsets[i], Clamp(sizes[i], 0.1f, FLT_MAX)); + } + drawVB->Unmap(); + + SetTransform(matrix4x4f::Identity()); + DrawBuffer(drawVB.Get(), rs, material, Graphics::POINTS); + GetStats().AddToStatCount(Graphics::Stats::STAT_DRAWPOINTSPRITES, 1); + CheckRenderErrors(__FUNCTION__, __LINE__); + + return true; } - else + + bool RendererOGL::DrawBuffer(VertexBuffer *vb, RenderState *state, Material *mat, PrimitiveType pt) { - drawVB = iter->second; + PROFILE_SCOPED() + SetRenderState(state); + mat->Apply(); + + SetMaterialShaderTransforms(mat); + + vb->Bind(); + glDrawArrays(pt, 0, vb->GetSize()); + vb->Release(); + CheckRenderErrors(__FUNCTION__, __LINE__); + + m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); + + return true; } - // got a buffer so use it and fill it with newest data - PosNormVert* vtxPtr = drawVB->Map(Graphics::BUFFER_MAP_WRITE); - assert(drawVB->GetDesc().stride == sizeof(PosNormVert)); - for(Uint32 i=0 ; iApply(); + + SetMaterialShaderTransforms(mat); + + vb->Bind(); + ib->Bind(); + glDrawElements(pt, ib->GetIndexCount(), GL_UNSIGNED_INT, 0); + ib->Release(); + vb->Release(); + CheckRenderErrors(__FUNCTION__, __LINE__); + + m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); + + return true; } - drawVB->Unmap(); - SetTransform(matrix4x4f::Identity()); - DrawBuffer(drawVB.Get(), rs, material, Graphics::POINTS); - GetStats().AddToStatCount(Graphics::Stats::STAT_DRAWPOINTSPRITES, 1); - CheckRenderErrors(__FUNCTION__,__LINE__); - - return true; -} - -bool RendererOGL::DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) -{ - PROFILE_SCOPED() - if (count == 0 || !material || !material->texture0) - return false; - - #pragma pack(push, 4) - struct PosNormVert { - vector3f pos; - vector3f norm; - }; - #pragma pack(pop) - - RefCountedPtr drawVB; - AttribBufferIter iter = s_AttribBufferMap.find(std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)); - if (iter == s_AttribBufferMap.end()) + bool RendererOGL::DrawBufferInstanced(VertexBuffer *vb, RenderState *state, Material *mat, InstanceBuffer *instb, PrimitiveType pt) { - // NB - we're (ab)using the normal type to hold (uv coordinate offset value + point size) - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = count; - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + PROFILE_SCOPED() + SetRenderState(state); + mat->Apply(); - // VertexBuffer - RefCountedPtr vb; - vb.Reset(CreateVertexBuffer(vbd)); + SetMaterialShaderTransforms(mat); - // add to map - s_AttribBufferMap[std::make_pair(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL, count)] = vb; - drawVB = vb; + vb->Bind(); + instb->Bind(); + glDrawArraysInstanced(pt, 0, vb->GetSize(), instb->GetInstanceCount()); + instb->Release(); + vb->Release(); + CheckRenderErrors(__FUNCTION__, __LINE__); + + m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); + + return true; } - else + + bool RendererOGL::DrawBufferIndexedInstanced(VertexBuffer *vb, IndexBuffer *ib, RenderState *state, Material *mat, InstanceBuffer *instb, PrimitiveType pt) { - drawVB = iter->second; + PROFILE_SCOPED() + SetRenderState(state); + mat->Apply(); + + SetMaterialShaderTransforms(mat); + + vb->Bind(); + ib->Bind(); + instb->Bind(); + glDrawElementsInstanced(pt, ib->GetIndexCount(), GL_UNSIGNED_INT, 0, instb->GetInstanceCount()); + instb->Release(); + ib->Release(); + vb->Release(); + CheckRenderErrors(__FUNCTION__, __LINE__); + + m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); + + return true; } - // got a buffer so use it and fill it with newest data - PosNormVert* vtxPtr = drawVB->Map(Graphics::BUFFER_MAP_WRITE); - assert(drawVB->GetDesc().stride == sizeof(PosNormVert)); - for(Uint32 i=0 ; iUnmap(); + PROFILE_SCOPED() + MaterialDescriptor desc = d; - SetTransform(matrix4x4f::Identity()); - DrawBuffer(drawVB.Get(), rs, material, Graphics::POINTS); - GetStats().AddToStatCount(Graphics::Stats::STAT_DRAWPOINTSPRITES, 1); - CheckRenderErrors(__FUNCTION__,__LINE__); + OGL::Material *mat = 0; + OGL::Program *p = 0; - return true; -} + if (desc.lighting) { + desc.dirLights = m_numDirLights; + } -bool RendererOGL::DrawBuffer(VertexBuffer* vb, RenderState* state, Material* mat, PrimitiveType pt) -{ - PROFILE_SCOPED() - SetRenderState(state); - mat->Apply(); - - SetMaterialShaderTransforms(mat); - - vb->Bind(); - glDrawArrays(pt, 0, vb->GetSize()); - vb->Release(); - CheckRenderErrors(__FUNCTION__,__LINE__); - - m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); - - return true; -} - -bool RendererOGL::DrawBufferIndexed(VertexBuffer *vb, IndexBuffer *ib, RenderState *state, Material *mat, PrimitiveType pt) -{ - PROFILE_SCOPED() - SetRenderState(state); - mat->Apply(); - - SetMaterialShaderTransforms(mat); - - vb->Bind(); - ib->Bind(); - glDrawElements(pt, ib->GetIndexCount(), GL_UNSIGNED_INT, 0); - ib->Release(); - vb->Release(); - CheckRenderErrors(__FUNCTION__,__LINE__); - - m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); - - return true; -} - -bool RendererOGL::DrawBufferInstanced(VertexBuffer* vb, RenderState* state, Material* mat, InstanceBuffer* instb, PrimitiveType pt) -{ - PROFILE_SCOPED() - SetRenderState(state); - mat->Apply(); - - SetMaterialShaderTransforms(mat); - - vb->Bind(); - instb->Bind(); - glDrawArraysInstanced(pt, 0, vb->GetSize(), instb->GetInstanceCount()); - instb->Release(); - vb->Release(); - CheckRenderErrors(__FUNCTION__,__LINE__); - - m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); - - return true; -} - -bool RendererOGL::DrawBufferIndexedInstanced(VertexBuffer *vb, IndexBuffer *ib, RenderState *state, Material *mat, InstanceBuffer* instb, PrimitiveType pt) -{ - PROFILE_SCOPED() - SetRenderState(state); - mat->Apply(); - - SetMaterialShaderTransforms(mat); - - vb->Bind(); - ib->Bind(); - instb->Bind(); - glDrawElementsInstanced(pt, ib->GetIndexCount(), GL_UNSIGNED_INT, 0, instb->GetInstanceCount()); - instb->Release(); - ib->Release(); - vb->Release(); - CheckRenderErrors(__FUNCTION__,__LINE__); - - m_stats.AddToStatCount(Stats::STAT_DRAWCALL, 1); - - return true; -} - -Material *RendererOGL::CreateMaterial(const MaterialDescriptor &d) -{ - PROFILE_SCOPED() - MaterialDescriptor desc = d; - - OGL::Material *mat = 0; - OGL::Program *p = 0; - - if (desc.lighting) { - desc.dirLights = m_numDirLights; - } - - // Create the material. It will be also used to create the shader, - // like a tiny factory - switch (desc.effect) { - case EFFECT_VTXCOLOR: - mat = new OGL::VtxColorMaterial(); - break; - case EFFECT_UI: - mat = new OGL::UIMaterial(); - break; - case EFFECT_PLANETRING: - mat = new OGL::RingMaterial(); - break; - case EFFECT_STARFIELD: - mat = new OGL::StarfieldMaterial(); - break; - case EFFECT_GEOSPHERE_TERRAIN: - case EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA: - case EFFECT_GEOSPHERE_TERRAIN_WITH_WATER: - mat = new OGL::GeoSphereSurfaceMaterial(); - break; - case EFFECT_GEOSPHERE_SKY: - mat = new OGL::GeoSphereSkyMaterial(); - break; - case EFFECT_GEOSPHERE_STAR: - mat = new OGL::GeoSphereStarMaterial(); - break; - case EFFECT_FRESNEL_SPHERE: - mat = new OGL::FresnelColourMaterial(); - break; - case EFFECT_SHIELD: - mat = new OGL::ShieldMaterial(); - break; - case EFFECT_SKYBOX: - mat = new OGL::SkyboxMaterial(); - break; - case EFFECT_SPHEREIMPOSTOR: - mat = new OGL::SphereImpostorMaterial(); - break; - case EFFECT_GASSPHERE_TERRAIN: - mat = new OGL::GasGiantSurfaceMaterial(); - break; - case EFFECT_GEN_GASGIANT_TEXTURE: - mat = new OGL::GenGasGiantColourMaterial(); - break; - case EFFECT_BILLBOARD_ATLAS: - case EFFECT_BILLBOARD: - mat = new OGL::BillboardMaterial(); - break; - default: - if (desc.lighting) - mat = new OGL::LitMultiMaterial(); - else - mat = new OGL::MultiMaterial(); - } - - mat->m_renderer = this; - mat->m_descriptor = desc; - - p = GetOrCreateProgram(mat); // XXX throws ShaderException on compile/link failure - - mat->SetProgram(p); - CheckRenderErrors(__FUNCTION__,__LINE__); - return mat; -} - -bool RendererOGL::ReloadShaders() -{ - Output("Reloading " SIZET_FMT " programs...\n", m_programs.size()); - for (ProgramIterator it = m_programs.begin(); it != m_programs.end(); ++it) { - it->second->Reload(); - } - Output("Done.\n"); - - return true; -} - -OGL::Program* RendererOGL::GetOrCreateProgram(OGL::Material *mat) -{ - PROFILE_SCOPED() - const MaterialDescriptor &desc = mat->GetDescriptor(); - OGL::Program *p = 0; - - // Find an existing program... - for (ProgramIterator it = m_programs.begin(); it != m_programs.end(); ++it) { - if ((*it).first == desc) { - p = (*it).second; + // Create the material. It will be also used to create the shader, + // like a tiny factory + switch (desc.effect) { + case EFFECT_VTXCOLOR: + mat = new OGL::VtxColorMaterial(); break; + case EFFECT_UI: + mat = new OGL::UIMaterial(); + break; + case EFFECT_PLANETRING: + mat = new OGL::RingMaterial(); + break; + case EFFECT_STARFIELD: + mat = new OGL::StarfieldMaterial(); + break; + case EFFECT_GEOSPHERE_TERRAIN: + case EFFECT_GEOSPHERE_TERRAIN_WITH_LAVA: + case EFFECT_GEOSPHERE_TERRAIN_WITH_WATER: + mat = new OGL::GeoSphereSurfaceMaterial(); + break; + case EFFECT_GEOSPHERE_SKY: + mat = new OGL::GeoSphereSkyMaterial(); + break; + case EFFECT_GEOSPHERE_STAR: + mat = new OGL::GeoSphereStarMaterial(); + break; + case EFFECT_FRESNEL_SPHERE: + mat = new OGL::FresnelColourMaterial(); + break; + case EFFECT_SHIELD: + mat = new OGL::ShieldMaterial(); + break; + case EFFECT_SKYBOX: + mat = new OGL::SkyboxMaterial(); + break; + case EFFECT_SPHEREIMPOSTOR: + mat = new OGL::SphereImpostorMaterial(); + break; + case EFFECT_GASSPHERE_TERRAIN: + mat = new OGL::GasGiantSurfaceMaterial(); + break; + case EFFECT_GEN_GASGIANT_TEXTURE: + mat = new OGL::GenGasGiantColourMaterial(); + break; + case EFFECT_BILLBOARD_ATLAS: + case EFFECT_BILLBOARD: + mat = new OGL::BillboardMaterial(); + break; + default: + if (desc.lighting) + mat = new OGL::LitMultiMaterial(); + else + mat = new OGL::MultiMaterial(); + } + + mat->m_renderer = this; + mat->m_descriptor = desc; + + p = GetOrCreateProgram(mat); // XXX throws ShaderException on compile/link failure + + mat->SetProgram(p); + CheckRenderErrors(__FUNCTION__, __LINE__); + return mat; + } + + bool RendererOGL::ReloadShaders() + { + Output("Reloading " SIZET_FMT " programs...\n", m_programs.size()); + for (ProgramIterator it = m_programs.begin(); it != m_programs.end(); ++it) { + it->second->Reload(); + } + Output("Done.\n"); + + return true; + } + + OGL::Program *RendererOGL::GetOrCreateProgram(OGL::Material *mat) + { + PROFILE_SCOPED() + const MaterialDescriptor &desc = mat->GetDescriptor(); + OGL::Program *p = 0; + + // Find an existing program... + for (ProgramIterator it = m_programs.begin(); it != m_programs.end(); ++it) { + if ((*it).first == desc) { + p = (*it).second; + break; + } + } + + // ...or create a new one + if (!p) { + p = mat->CreateProgram(desc); + m_programs.push_back(std::make_pair(desc, p)); + } + CheckRenderErrors(__FUNCTION__, __LINE__); + + return p; + } + + Texture *RendererOGL::CreateTexture(const TextureDescriptor &descriptor) + { + PROFILE_SCOPED() + return new OGL::TextureGL(descriptor, m_useCompressedTextures, m_useAnisotropicFiltering); + } + + RenderState *RendererOGL::CreateRenderState(const RenderStateDesc &desc) + { + PROFILE_SCOPED() + const uint32_t hash = lookup3_hashlittle(&desc, sizeof(RenderStateDesc), 0); + auto it = m_renderStates.find(hash); + if (it != m_renderStates.end()) { + CheckRenderErrors(__FUNCTION__, __LINE__); + return it->second; + } else { + auto *rs = new OGL::RenderState(desc); + m_renderStates[hash] = rs; + CheckRenderErrors(__FUNCTION__, __LINE__); + return rs; } } - // ...or create a new one - if (!p) { - p = mat->CreateProgram(desc); - m_programs.push_back(std::make_pair(desc, p)); - } - CheckRenderErrors(__FUNCTION__,__LINE__); - - return p; -} - -Texture *RendererOGL::CreateTexture(const TextureDescriptor &descriptor) -{ - PROFILE_SCOPED() - return new OGL::TextureGL(descriptor, m_useCompressedTextures, m_useAnisotropicFiltering); -} - -RenderState *RendererOGL::CreateRenderState(const RenderStateDesc &desc) -{ - PROFILE_SCOPED() - const uint32_t hash = lookup3_hashlittle(&desc, sizeof(RenderStateDesc), 0); - auto it = m_renderStates.find(hash); - if (it != m_renderStates.end()) { - CheckRenderErrors(__FUNCTION__,__LINE__); - return it->second; - } else { - auto *rs = new OGL::RenderState(desc); - m_renderStates[hash] = rs; - CheckRenderErrors(__FUNCTION__,__LINE__); - return rs; - } -} - -RenderTarget *RendererOGL::CreateRenderTarget(const RenderTargetDesc &desc) -{ - PROFILE_SCOPED() - OGL::RenderTarget* rt = new OGL::RenderTarget(desc); - CheckRenderErrors(__FUNCTION__,__LINE__); - rt->Bind(); - if (desc.colorFormat != TEXTURE_NONE) { - Graphics::TextureDescriptor cdesc( - desc.colorFormat, - vector2f(desc.width, desc.height), - vector2f(desc.width, desc.height), - LINEAR_CLAMP, - false, - false, - false, - 0, Graphics::TEXTURE_2D); - OGL::TextureGL *colorTex = new OGL::TextureGL(cdesc, false, false); - rt->SetColorTexture(colorTex); - } - if (desc.depthFormat != TEXTURE_NONE) { - if (desc.allowDepthTexture) { - Graphics::TextureDescriptor ddesc( - TEXTURE_DEPTH, + RenderTarget *RendererOGL::CreateRenderTarget(const RenderTargetDesc &desc) + { + PROFILE_SCOPED() + OGL::RenderTarget *rt = new OGL::RenderTarget(desc); + CheckRenderErrors(__FUNCTION__, __LINE__); + rt->Bind(); + if (desc.colorFormat != TEXTURE_NONE) { + Graphics::TextureDescriptor cdesc( + desc.colorFormat, vector2f(desc.width, desc.height), vector2f(desc.width, desc.height), LINEAR_CLAMP, @@ -1090,83 +1066,97 @@ RenderTarget *RendererOGL::CreateRenderTarget(const RenderTargetDesc &desc) false, false, 0, Graphics::TEXTURE_2D); - OGL::TextureGL *depthTex = new OGL::TextureGL(ddesc, false, false); - rt->SetDepthTexture(depthTex); - } else { - rt->CreateDepthRenderbuffer(); + OGL::TextureGL *colorTex = new OGL::TextureGL(cdesc, false, false); + rt->SetColorTexture(colorTex); + } + if (desc.depthFormat != TEXTURE_NONE) { + if (desc.allowDepthTexture) { + Graphics::TextureDescriptor ddesc( + TEXTURE_DEPTH, + vector2f(desc.width, desc.height), + vector2f(desc.width, desc.height), + LINEAR_CLAMP, + false, + false, + false, + 0, Graphics::TEXTURE_2D); + OGL::TextureGL *depthTex = new OGL::TextureGL(ddesc, false, false); + rt->SetDepthTexture(depthTex); + } else { + rt->CreateDepthRenderbuffer(); + } + } + rt->CheckStatus(); + rt->Unbind(); + CheckRenderErrors(__FUNCTION__, __LINE__); + return rt; + } + + VertexBuffer *RendererOGL::CreateVertexBuffer(const VertexBufferDesc &desc) + { + m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); + return new OGL::VertexBuffer(desc); + } + + IndexBuffer *RendererOGL::CreateIndexBuffer(Uint32 size, BufferUsage usage) + { + m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); + return new OGL::IndexBuffer(size, usage); + } + + InstanceBuffer *RendererOGL::CreateInstanceBuffer(Uint32 size, BufferUsage usage) + { + m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); + return new OGL::InstanceBuffer(size, usage); + } + + // XXX very heavy. in the future when all GL calls are made through the + // renderer, we can probably do better by trackingn current state and + // only restoring the things that have changed + void RendererOGL::PushState() + { + SetMatrixMode(MatrixMode::PROJECTION); + PushMatrix(); + SetMatrixMode(MatrixMode::MODELVIEW); + PushMatrix(); + m_viewportStack.push(m_viewportStack.top()); + } + + void RendererOGL::PopState() + { + m_viewportStack.pop(); + assert(!m_viewportStack.empty()); + const Viewport &cvp = m_viewportStack.top(); + SetViewport(cvp.x, cvp.y, cvp.w, cvp.h); + + SetMatrixMode(MatrixMode::PROJECTION); + PopMatrix(); + SetMatrixMode(MatrixMode::MODELVIEW); + PopMatrix(); + } + + void RendererOGL::SetMatrixMode(MatrixMode mm) + { + if (mm != m_matrixMode) { + m_matrixMode = mm; } } - rt->CheckStatus(); - rt->Unbind(); - CheckRenderErrors(__FUNCTION__,__LINE__); - return rt; -} -VertexBuffer *RendererOGL::CreateVertexBuffer(const VertexBufferDesc &desc) -{ - m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); - return new OGL::VertexBuffer(desc); -} - -IndexBuffer *RendererOGL::CreateIndexBuffer(Uint32 size, BufferUsage usage) -{ - m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); - return new OGL::IndexBuffer(size, usage); -} - -InstanceBuffer *RendererOGL::CreateInstanceBuffer(Uint32 size, BufferUsage usage) -{ - m_stats.AddToStatCount(Stats::STAT_CREATE_BUFFER, 1); - return new OGL::InstanceBuffer(size, usage); -} - -// XXX very heavy. in the future when all GL calls are made through the -// renderer, we can probably do better by trackingn current state and -// only restoring the things that have changed -void RendererOGL::PushState() -{ - SetMatrixMode(MatrixMode::PROJECTION); - PushMatrix(); - SetMatrixMode(MatrixMode::MODELVIEW); - PushMatrix(); - m_viewportStack.push( m_viewportStack.top() ); -} - -void RendererOGL::PopState() -{ - m_viewportStack.pop(); - assert(!m_viewportStack.empty()); - const Viewport& cvp = m_viewportStack.top(); - SetViewport(cvp.x, cvp.y, cvp.w, cvp.h); - - SetMatrixMode(MatrixMode::PROJECTION); - PopMatrix(); - SetMatrixMode(MatrixMode::MODELVIEW); - PopMatrix(); -} - -void RendererOGL::SetMatrixMode(MatrixMode mm) -{ - if( mm != m_matrixMode ) { - m_matrixMode = mm; - } -} - -void RendererOGL::PushMatrix() -{ - switch(m_matrixMode) { + void RendererOGL::PushMatrix() + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: m_modelViewStack.push(m_modelViewStack.top()); break; case MatrixMode::PROJECTION: m_projectionStack.push(m_projectionStack.top()); break; + } } -} -void RendererOGL::PopMatrix() -{ - switch(m_matrixMode) { + void RendererOGL::PopMatrix() + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: m_modelViewStack.pop(); assert(m_modelViewStack.size()); @@ -1175,98 +1165,98 @@ void RendererOGL::PopMatrix() m_projectionStack.pop(); assert(m_projectionStack.size()); break; + } } -} -void RendererOGL::LoadIdentity() -{ - switch(m_matrixMode) { + void RendererOGL::LoadIdentity() + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: m_modelViewStack.top() = matrix4x4f::Identity(); break; case MatrixMode::PROJECTION: m_projectionStack.top() = matrix4x4f::Identity(); break; + } } -} -void RendererOGL::LoadMatrix(const matrix4x4f &m) -{ - switch(m_matrixMode) { + void RendererOGL::LoadMatrix(const matrix4x4f &m) + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: m_modelViewStack.top() = m; break; case MatrixMode::PROJECTION: m_projectionStack.top() = m; break; + } } -} -void RendererOGL::Translate( const float x, const float y, const float z ) -{ - switch(m_matrixMode) { + void RendererOGL::Translate(const float x, const float y, const float z) + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: - m_modelViewStack.top().Translate(x,y,z); + m_modelViewStack.top().Translate(x, y, z); break; case MatrixMode::PROJECTION: - m_projectionStack.top().Translate(x,y,z); + m_projectionStack.top().Translate(x, y, z); break; + } } -} -void RendererOGL::Scale( const float x, const float y, const float z ) -{ - switch(m_matrixMode) { + void RendererOGL::Scale(const float x, const float y, const float z) + { + switch (m_matrixMode) { case MatrixMode::MODELVIEW: - m_modelViewStack.top().Scale(x,y,z); + m_modelViewStack.top().Scale(x, y, z); break; case MatrixMode::PROJECTION: - m_modelViewStack.top().Scale(x,y,z); + m_modelViewStack.top().Scale(x, y, z); break; + } } -} -bool RendererOGL::Screendump(ScreendumpState &sd) -{ - int w, h; - SDL_GetWindowSize(m_window, &w, &h); - sd.width = w; - sd.height = h; - sd.bpp = 4; // XXX get from window + bool RendererOGL::Screendump(ScreendumpState &sd) + { + int w, h; + SDL_GetWindowSize(m_window, &w, &h); + sd.width = w; + sd.height = h; + sd.bpp = 4; // XXX get from window - // pad rows to 4 bytes, which is the default row alignment for OpenGL - sd.stride = ((sd.bpp * sd.width) + 3) & ~3; + // pad rows to 4 bytes, which is the default row alignment for OpenGL + sd.stride = ((sd.bpp * sd.width) + 3) & ~3; - sd.pixels.reset(new Uint8[sd.stride * sd.height]); + sd.pixels.reset(new Uint8[sd.stride * sd.height]); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 4); // never trust defaults - glReadBuffer(GL_FRONT); - glReadPixels(0, 0, sd.width, sd.height, GL_RGBA, GL_UNSIGNED_BYTE, sd.pixels.get()); - glFinish(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 4); // never trust defaults + glReadBuffer(GL_FRONT); + glReadPixels(0, 0, sd.width, sd.height, GL_RGBA, GL_UNSIGNED_BYTE, sd.pixels.get()); + glFinish(); - return true; -} + return true; + } -bool RendererOGL::FrameGrab(ScreendumpState &sd) -{ - int w, h; - SDL_GetWindowSize(m_window, &w, &h); - sd.width = w; - sd.height = h; - sd.bpp = 4; // XXX get from window + bool RendererOGL::FrameGrab(ScreendumpState &sd) + { + int w, h; + SDL_GetWindowSize(m_window, &w, &h); + sd.width = w; + sd.height = h; + sd.bpp = 4; // XXX get from window - sd.stride = (4 * sd.width); + sd.stride = (4 * sd.width); - sd.pixels.reset(new Uint8[sd.stride * sd.height]); + sd.pixels.reset(new Uint8[sd.stride * sd.height]); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 4); // never trust defaults - glReadBuffer(GL_FRONT); - glReadPixels(0, 0, sd.width, sd.height, GL_RGBA, GL_UNSIGNED_BYTE, sd.pixels.get()); - glFinish(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 4); // never trust defaults + glReadBuffer(GL_FRONT); + glReadPixels(0, 0, sd.width, sd.height, GL_RGBA, GL_UNSIGNED_BYTE, sd.pixels.get()); + glFinish(); - return true; -} + return true; + } -} +} // namespace Graphics diff --git a/src/graphics/opengl/RendererGL.h b/src/graphics/opengl/RendererGL.h index 3169fbc8e..d27a84c0c 100644 --- a/src/graphics/opengl/RendererGL.h +++ b/src/graphics/opengl/RendererGL.h @@ -20,171 +20,178 @@ namespace Graphics { -class Texture; -struct Settings; + class Texture; + struct Settings; -namespace OGL { - class GasGiantSurfaceMaterial; - class GeoSphereSkyMaterial; - class GeoSphereStarMaterial; - class GeoSphereSurfaceMaterial; - class GenGasGiantColourMaterial; - class Material; - class MultiMaterial; - class LitMultiMaterial; - class Program; - class RenderState; - class RenderTarget; - class RingMaterial; - class FresnelColourMaterial; - class ShieldMaterial; - class UIMaterial; - class BillboardMaterial; -} + namespace OGL { + class GasGiantSurfaceMaterial; + class GeoSphereSkyMaterial; + class GeoSphereStarMaterial; + class GeoSphereSurfaceMaterial; + class GenGasGiantColourMaterial; + class Material; + class MultiMaterial; + class LitMultiMaterial; + class Program; + class RenderState; + class RenderTarget; + class RingMaterial; + class FresnelColourMaterial; + class ShieldMaterial; + class UIMaterial; + class BillboardMaterial; + } // namespace OGL -class RendererOGL : public Renderer -{ -public: - static void RegisterRenderer(); + class RendererOGL : public Renderer { + public: + static void RegisterRenderer(); - RendererOGL(SDL_Window *window, const Graphics::Settings &vs, SDL_GLContext &glContext); - virtual ~RendererOGL() override final; + RendererOGL(SDL_Window *window, const Graphics::Settings &vs, SDL_GLContext &glContext); + virtual ~RendererOGL() override final; - virtual const char* GetName() const override final { return "OpenGL 3.1, with extensions, renderer"; } - virtual RendererType GetRendererType() const override final { return RENDERER_OPENGL_3x; } + virtual const char *GetName() const override final { return "OpenGL 3.1, with extensions, renderer"; } + virtual RendererType GetRendererType() const override final { return RENDERER_OPENGL_3x; } - virtual void WriteRendererInfo(std::ostream &out) const override final; + virtual void WriteRendererInfo(std::ostream &out) const override final; - virtual void CheckRenderErrors(const char *func = nullptr, const int line = -1) const override final { CheckErrors(func, line); } - static void CheckErrors(const char *func = nullptr, const int line = -1); + virtual void CheckRenderErrors(const char *func = nullptr, const int line = -1) const override final { CheckErrors(func, line); } + static void CheckErrors(const char *func = nullptr, const int line = -1); - virtual bool SupportsInstancing() override final { return true; } + virtual bool SupportsInstancing() override final { return true; } - virtual int GetMaximumNumberAASamples() const override final; - virtual bool GetNearFarRange(float &near_, float &far_) const override final; + virtual int GetMaximumNumberAASamples() const override final; + virtual bool GetNearFarRange(float &near_, float &far_) const override final; - virtual bool BeginFrame() override final; - virtual bool EndFrame() override final; - virtual bool SwapBuffers() override final; + virtual bool BeginFrame() override final; + virtual bool EndFrame() override final; + virtual bool SwapBuffers() override final; - virtual bool SetRenderState(RenderState*) override final; - virtual bool SetRenderTarget(RenderTarget*) override final; + virtual bool SetRenderState(RenderState *) override final; + virtual bool SetRenderTarget(RenderTarget *) override final; - virtual bool SetDepthRange(double znear, double zfar) override final; + virtual bool SetDepthRange(double znear, double zfar) override final; - virtual bool ClearScreen() override final; - virtual bool ClearDepthBuffer() override final; - virtual bool SetClearColor(const Color &c) override final; + virtual bool ClearScreen() override final; + virtual bool ClearDepthBuffer() override final; + virtual bool SetClearColor(const Color &c) override final; - virtual bool SetViewport(int x, int y, int width, int height) override final; + virtual bool SetViewport(int x, int y, int width, int height) override final; - virtual bool SetTransform(const matrix4x4d &m) override final; - virtual bool SetTransform(const matrix4x4f &m) override final; - virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) override final; - virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) override final; - virtual bool SetProjection(const matrix4x4f &m) override final; + virtual bool SetTransform(const matrix4x4d &m) override final; + virtual bool SetTransform(const matrix4x4f &m) override final; + virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) override final; + virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) override final; + virtual bool SetProjection(const matrix4x4f &m) override final; - virtual bool SetWireFrameMode(bool enabled) override final; + virtual bool SetWireFrameMode(bool enabled) override final; - virtual bool SetLights(Uint32 numlights, const Light *l) override final; - virtual Uint32 GetNumLights() const override final { return m_numLights; } - virtual bool SetAmbientColor(const Color &c) override final; + virtual bool SetLights(Uint32 numlights, const Light *l) override final; + virtual Uint32 GetNumLights() const override final { return m_numLights; } + virtual bool SetAmbientColor(const Color &c) override final; - virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) override final; + virtual bool SetScissor(bool enabled, const vector2f &pos = vector2f(0.0f), const vector2f &size = vector2f(0.0f)) override final; - virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type=TRIANGLES) override final; - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) override final; - virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) override final; - virtual bool DrawBuffer(VertexBuffer*, RenderState*, Material*, PrimitiveType) override final; - virtual bool DrawBufferIndexed(VertexBuffer*, IndexBuffer*, RenderState*, Material*, PrimitiveType) override final; - virtual bool DrawBufferInstanced(VertexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType type=TRIANGLES) override final; - virtual bool DrawBufferIndexedInstanced(VertexBuffer*, IndexBuffer*, RenderState*, Material*, InstanceBuffer*, PrimitiveType=TRIANGLES) override final; + virtual bool DrawTriangles(const VertexArray *vertices, RenderState *state, Material *material, PrimitiveType type = TRIANGLES) override final; + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, RenderState *rs, Material *material, float size) override final; + virtual bool DrawPointSprites(const Uint32 count, const vector3f *positions, const vector2f *offsets, const float *sizes, RenderState *rs, Material *material) override final; + virtual bool DrawBuffer(VertexBuffer *, RenderState *, Material *, PrimitiveType) override final; + virtual bool DrawBufferIndexed(VertexBuffer *, IndexBuffer *, RenderState *, Material *, PrimitiveType) override final; + virtual bool DrawBufferInstanced(VertexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType type = TRIANGLES) override final; + virtual bool DrawBufferIndexedInstanced(VertexBuffer *, IndexBuffer *, RenderState *, Material *, InstanceBuffer *, PrimitiveType = TRIANGLES) override final; - virtual Material *CreateMaterial(const MaterialDescriptor &descriptor) override final; - virtual Texture *CreateTexture(const TextureDescriptor &descriptor) override final; - virtual RenderState *CreateRenderState(const RenderStateDesc &) override final; - virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &) override final; - virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc&) override final; - virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage) override final; - virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage) override final; + virtual Material *CreateMaterial(const MaterialDescriptor &descriptor) override final; + virtual Texture *CreateTexture(const TextureDescriptor &descriptor) override final; + virtual RenderState *CreateRenderState(const RenderStateDesc &) override final; + virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &) override final; + virtual VertexBuffer *CreateVertexBuffer(const VertexBufferDesc &) override final; + virtual IndexBuffer *CreateIndexBuffer(Uint32 size, BufferUsage) override final; + virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage) override final; - virtual bool ReloadShaders() override final; + virtual bool ReloadShaders() override final; - virtual const matrix4x4f& GetCurrentModelView() const override final { return m_modelViewStack.top(); } - virtual const matrix4x4f& GetCurrentProjection() const override final { return m_projectionStack.top(); } - virtual void GetCurrentViewport(Sint32 *vp) const override final { - const Viewport &cur = m_viewportStack.top(); - vp[0] = cur.x; vp[1] = cur.y; vp[2] = cur.w; vp[3] = cur.h; - } + virtual const matrix4x4f &GetCurrentModelView() const override final { return m_modelViewStack.top(); } + virtual const matrix4x4f &GetCurrentProjection() const override final { return m_projectionStack.top(); } + virtual void GetCurrentViewport(Sint32 *vp) const override final + { + const Viewport &cur = m_viewportStack.top(); + vp[0] = cur.x; + vp[1] = cur.y; + vp[2] = cur.w; + vp[3] = cur.h; + } - virtual void SetMatrixMode(MatrixMode mm) override final; - virtual void PushMatrix() override final; - virtual void PopMatrix() override final; - virtual void LoadIdentity() override final; - virtual void LoadMatrix(const matrix4x4f &m) override final; - virtual void Translate( const float x, const float y, const float z ) override final; - virtual void Scale( const float x, const float y, const float z ) override final; + virtual void SetMatrixMode(MatrixMode mm) override final; + virtual void PushMatrix() override final; + virtual void PopMatrix() override final; + virtual void LoadIdentity() override final; + virtual void LoadMatrix(const matrix4x4f &m) override final; + virtual void Translate(const float x, const float y, const float z) override final; + virtual void Scale(const float x, const float y, const float z) override final; - virtual bool Screendump(ScreendumpState &sd) override final; - virtual bool FrameGrab(ScreendumpState &sd) override final; + virtual bool Screendump(ScreendumpState &sd) override final; + virtual bool FrameGrab(ScreendumpState &sd) override final; -protected: - virtual void PushState() override final; - virtual void PopState() override final; + protected: + virtual void PushState() override final; + virtual void PopState() override final; - Uint32 m_numLights; - Uint32 m_numDirLights; - std::vector m_vertexAttribsSet; - float m_minZNear; - float m_maxZFar; - bool m_useCompressedTextures; - bool m_useAnisotropicFiltering; + Uint32 m_numLights; + Uint32 m_numDirLights; + std::vector m_vertexAttribsSet; + float m_minZNear; + float m_maxZFar; + bool m_useCompressedTextures; + bool m_useAnisotropicFiltering; - void SetMaterialShaderTransforms(Material *); + void SetMaterialShaderTransforms(Material *); - matrix4x4f& GetCurrentTransform() { return m_currentTransform; } - matrix4x4f m_currentTransform; + matrix4x4f &GetCurrentTransform() { return m_currentTransform; } + matrix4x4f m_currentTransform; - OGL::Program* GetOrCreateProgram(OGL::Material*); - friend class OGL::Material; - friend class OGL::GasGiantSurfaceMaterial; - friend class OGL::GeoSphereSurfaceMaterial; - friend class OGL::GeoSphereSkyMaterial; - friend class OGL::GeoSphereStarMaterial; - friend class OGL::GenGasGiantColourMaterial; - friend class OGL::MultiMaterial; - friend class OGL::LitMultiMaterial; - friend class OGL::RingMaterial; - friend class OGL::FresnelColourMaterial; - friend class OGL::ShieldMaterial; - friend class OGL::BillboardMaterial; - std::vector > m_programs; - std::unordered_map m_renderStates; - float m_invLogZfarPlus1; - OGL::RenderTarget *m_activeRenderTarget; - RenderState *m_activeRenderState; + OGL::Program *GetOrCreateProgram(OGL::Material *); + friend class OGL::Material; + friend class OGL::GasGiantSurfaceMaterial; + friend class OGL::GeoSphereSurfaceMaterial; + friend class OGL::GeoSphereSkyMaterial; + friend class OGL::GeoSphereStarMaterial; + friend class OGL::GenGasGiantColourMaterial; + friend class OGL::MultiMaterial; + friend class OGL::LitMultiMaterial; + friend class OGL::RingMaterial; + friend class OGL::FresnelColourMaterial; + friend class OGL::ShieldMaterial; + friend class OGL::BillboardMaterial; + std::vector> m_programs; + std::unordered_map m_renderStates; + float m_invLogZfarPlus1; + OGL::RenderTarget *m_activeRenderTarget; + RenderState *m_activeRenderState; - MatrixMode m_matrixMode; - std::stack m_modelViewStack; - std::stack m_projectionStack; + MatrixMode m_matrixMode; + std::stack m_modelViewStack; + std::stack m_projectionStack; - struct Viewport { - Viewport() : x(0), y(0), w(0), h(0) {} - Sint32 x, y, w, h; + struct Viewport { + Viewport() : + x(0), + y(0), + w(0), + h(0) {} + Sint32 x, y, w, h; + }; + std::stack m_viewportStack; + + private: + static bool initted; + + typedef std::map, RefCountedPtr> AttribBufferMap; + typedef AttribBufferMap::iterator AttribBufferIter; + static AttribBufferMap s_AttribBufferMap; + + SDL_GLContext m_glContext; }; - std::stack m_viewportStack; - -private: - static bool initted; - - typedef std::map, RefCountedPtr> AttribBufferMap; - typedef AttribBufferMap::iterator AttribBufferIter; - static AttribBufferMap s_AttribBufferMap; - - SDL_GLContext m_glContext; -}; #define CHECKERRORS() RendererOGL::CheckErrors(__FUNCTION__, __LINE__) -} +} // namespace Graphics #endif diff --git a/src/graphics/opengl/RingMaterial.cpp b/src/graphics/opengl/RingMaterial.cpp index 9f8921a50..69b24d1ce 100644 --- a/src/graphics/opengl/RingMaterial.cpp +++ b/src/graphics/opengl/RingMaterial.cpp @@ -2,44 +2,44 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "RingMaterial.h" -#include "StringF.h" -#include "graphics/Graphics.h" #include "RendererGL.h" +#include "StringF.h" #include "TextureGL.h" +#include "graphics/Graphics.h" namespace Graphics { -namespace OGL { + namespace OGL { -Program *RingMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - assert(desc.textures == 1); - //pick light count and some defines - unsigned int numLights = Clamp(desc.dirLights, 1u, 4u); - std::string defines = stringf("#define NUM_LIGHTS %0{u}\n", numLights); - return new Program("planetrings", defines); -} + Program *RingMaterial::CreateProgram(const MaterialDescriptor &desc) + { + assert(desc.textures == 1); + //pick light count and some defines + unsigned int numLights = Clamp(desc.dirLights, 1u, 4u); + std::string defines = stringf("#define NUM_LIGHTS %0{u}\n", numLights); + return new Program("planetrings", defines); + } -void RingMaterial::Apply() -{ - OGL::Material::Apply(); + void RingMaterial::Apply() + { + OGL::Material::Apply(); - assert(this->texture0); - m_program->texture0.Set(this->texture0, 0); + assert(this->texture0); + m_program->texture0.Set(this->texture0, 0); - //Light uniform parameters - for( Uint32 i=0 ; iGetNumLights() ; i++ ) { - const Light& Light = m_renderer->GetLight(i); - m_program->lights[i].diffuse.Set( Light.GetDiffuse() ); - m_program->lights[i].specular.Set( Light.GetSpecular() ); - const vector3f& pos = Light.GetPosition(); - m_program->lights[i].position.Set( pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); - } -} + //Light uniform parameters + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + m_program->lights[i].diffuse.Set(Light.GetDiffuse()); + m_program->lights[i].specular.Set(Light.GetSpecular()); + const vector3f &pos = Light.GetPosition(); + m_program->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + } + } -void RingMaterial::Unapply() -{ - static_cast(texture0)->Unbind(); -} + void RingMaterial::Unapply() + { + static_cast(texture0)->Unbind(); + } -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/RingMaterial.h b/src/graphics/opengl/RingMaterial.h index e026467c3..0e8003ad2 100644 --- a/src/graphics/opengl/RingMaterial.h +++ b/src/graphics/opengl/RingMaterial.h @@ -6,8 +6,8 @@ /* * Planet ring material */ -#include "OpenGLLibs.h" #include "MaterialGL.h" +#include "OpenGLLibs.h" #include "Program.h" namespace Graphics { @@ -19,6 +19,6 @@ namespace Graphics { virtual void Apply() override; virtual void Unapply() override; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/ShieldMaterial.cpp b/src/graphics/opengl/ShieldMaterial.cpp index 935b3e30b..57ad10f7a 100644 --- a/src/graphics/opengl/ShieldMaterial.cpp +++ b/src/graphics/opengl/ShieldMaterial.cpp @@ -2,78 +2,78 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ShieldMaterial.h" -#include "graphics/Material.h" -#include "graphics/Graphics.h" -#include "TextureGL.h" #include "RendererGL.h" -#include -#include "StringF.h" #include "Shields.h" +#include "StringF.h" +#include "TextureGL.h" +#include "graphics/Graphics.h" +#include "graphics/Material.h" +#include namespace Graphics { -namespace OGL { + namespace OGL { -ShieldProgram::ShieldProgram(const MaterialDescriptor &desc) -{ - //build some defines - std::stringstream ss; + ShieldProgram::ShieldProgram(const MaterialDescriptor &desc) + { + //build some defines + std::stringstream ss; - m_name = "shield"; - m_defines = ss.str(); + m_name = "shield"; + m_defines = ss.str(); - LoadShaders(m_name, m_defines); - InitUniforms(); -} - -void ShieldProgram::InitUniforms() -{ - Program::InitUniforms(); - - shieldStrength.Init("shieldStrength", m_program); - shieldCooldown.Init("shieldCooldown", m_program); - - char whatsInAName[256]; - for (Sint32 i = 0; i < MAX_SHIELD_HITS; i++) { - sprintf(whatsInAName, "hitPos[%d]", i); - hitPos[i].Init(whatsInAName, m_program); - } - for (Sint32 i = 0; i < MAX_SHIELD_HITS; i++) { - sprintf(whatsInAName, "radii[%d]", i); - radii[i].Init(whatsInAName, m_program); - } - numHits.Init("numHits", m_program); -} - -Program *ShieldMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - return new ShieldProgram(desc); -} - -void ShieldMaterial::Apply() -{ - OGL::Material::Apply(); - - ShieldProgram *p = static_cast(m_program); - - p->diffuse.Set(this->diffuse); - - if (this->specialParameter0) { - const ShieldRenderParameters srp = *static_cast(this->specialParameter0); - p->shieldStrength.Set(srp.strength); - p->shieldCooldown.Set(srp.coolDown); - for (Sint32 i = 0; i < srp.numHits && i < MAX_SHIELD_HITS; i++) { - p->hitPos[i].Set( srp.hitPos[i] ); + LoadShaders(m_name, m_defines); + InitUniforms(); } - for (Sint32 i = 0; i < srp.numHits && i < MAX_SHIELD_HITS; i++) { - p->radii[i].Set( srp.radii[i] ); - } - p->numHits.Set( int(std::min(srp.numHits, MAX_SHIELD_HITS)) ); - } else { - p->shieldStrength.Set(0.0f); - p->shieldCooldown.Set(0.0f); - p->numHits.Set( 0 ); - } -} -} -} + void ShieldProgram::InitUniforms() + { + Program::InitUniforms(); + + shieldStrength.Init("shieldStrength", m_program); + shieldCooldown.Init("shieldCooldown", m_program); + + char whatsInAName[256]; + for (Sint32 i = 0; i < MAX_SHIELD_HITS; i++) { + sprintf(whatsInAName, "hitPos[%d]", i); + hitPos[i].Init(whatsInAName, m_program); + } + for (Sint32 i = 0; i < MAX_SHIELD_HITS; i++) { + sprintf(whatsInAName, "radii[%d]", i); + radii[i].Init(whatsInAName, m_program); + } + numHits.Init("numHits", m_program); + } + + Program *ShieldMaterial::CreateProgram(const MaterialDescriptor &desc) + { + return new ShieldProgram(desc); + } + + void ShieldMaterial::Apply() + { + OGL::Material::Apply(); + + ShieldProgram *p = static_cast(m_program); + + p->diffuse.Set(this->diffuse); + + if (this->specialParameter0) { + const ShieldRenderParameters srp = *static_cast(this->specialParameter0); + p->shieldStrength.Set(srp.strength); + p->shieldCooldown.Set(srp.coolDown); + for (Sint32 i = 0; i < srp.numHits && i < MAX_SHIELD_HITS; i++) { + p->hitPos[i].Set(srp.hitPos[i]); + } + for (Sint32 i = 0; i < srp.numHits && i < MAX_SHIELD_HITS; i++) { + p->radii[i].Set(srp.radii[i]); + } + p->numHits.Set(int(std::min(srp.numHits, MAX_SHIELD_HITS))); + } else { + p->shieldStrength.Set(0.0f); + p->shieldCooldown.Set(0.0f); + p->numHits.Set(0); + } + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/ShieldMaterial.h b/src/graphics/opengl/ShieldMaterial.h index ea0f40cab..c4de1577a 100644 --- a/src/graphics/opengl/ShieldMaterial.h +++ b/src/graphics/opengl/ShieldMaterial.h @@ -24,6 +24,7 @@ namespace Graphics { Uniform hitPos[MAX_SHIELD_HITS]; Uniform radii[MAX_SHIELD_HITS]; Uniform numHits; + protected: virtual void InitUniforms() override; }; @@ -33,7 +34,7 @@ namespace Graphics { virtual Program *CreateProgram(const MaterialDescriptor &) override; virtual void Apply() override; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/SkyboxMaterial.h b/src/graphics/opengl/SkyboxMaterial.h index 0d7b656f1..719364a4e 100644 --- a/src/graphics/opengl/SkyboxMaterial.h +++ b/src/graphics/opengl/SkyboxMaterial.h @@ -14,20 +14,22 @@ namespace Graphics { namespace OGL { class SkyboxMaterial : public Material { private: - public: - SkyboxMaterial() { + SkyboxMaterial() + { texture0 = nullptr; fSkyboxFactor = 0.8f; } - virtual Program *CreateProgram(const MaterialDescriptor &) override { + virtual Program *CreateProgram(const MaterialDescriptor &) override + { return new Program("skybox", ""); } - virtual void Apply() override { + virtual void Apply() override + { m_program->Use(); - if(texture0) { + if (texture0) { m_program->texture0.Set(texture0, 0); } const float em = (float(emissive.r) * 0.003921568627451f); @@ -37,7 +39,7 @@ namespace Graphics { // Skybox multiplier float fSkyboxFactor; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/SphereImpostorMaterial.h b/src/graphics/opengl/SphereImpostorMaterial.h index 3a195b282..2162fb126 100644 --- a/src/graphics/opengl/SphereImpostorMaterial.h +++ b/src/graphics/opengl/SphereImpostorMaterial.h @@ -5,33 +5,35 @@ /* * Billboard sphere impostor */ -#include "libs.h" #include "MaterialGL.h" #include "Program.h" +#include "libs.h" namespace Graphics { namespace OGL { class SphereImpostorMaterial : public Material { public: - Program *CreateProgram(const MaterialDescriptor &) override { + Program *CreateProgram(const MaterialDescriptor &) override + { return new Program("billboard_sphereimpostor", ""); } - virtual void Apply() override { + virtual void Apply() override + { OGL::Material::Apply(); m_program->sceneAmbient.Set(m_renderer->GetAmbientColor()); //Light uniform parameters - for( Uint32 i=0 ; iGetNumLights() ; i++ ) { - const Light& Light = m_renderer->GetLight(i); - m_program->lights[i].diffuse.Set( Light.GetDiffuse() ); - m_program->lights[i].specular.Set( Light.GetSpecular() ); - const vector3f& pos = Light.GetPosition(); - m_program->lights[i].position.Set( pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); + for (Uint32 i = 0; i < m_renderer->GetNumLights(); i++) { + const Light &Light = m_renderer->GetLight(i); + m_program->lights[i].diffuse.Set(Light.GetDiffuse()); + m_program->lights[i].specular.Set(Light.GetSpecular()); + const vector3f &pos = Light.GetPosition(); + m_program->lights[i].position.Set(pos.x, pos.y, pos.z, (Light.GetType() == Light::LIGHT_DIRECTIONAL ? 0.f : 1.f)); } } }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/StarfieldMaterial.h b/src/graphics/opengl/StarfieldMaterial.h index 940a5df58..cb3d5715e 100644 --- a/src/graphics/opengl/StarfieldMaterial.h +++ b/src/graphics/opengl/StarfieldMaterial.h @@ -9,18 +9,20 @@ * The Program requires setting intensity using the generic emission parameter */ #include "OpenGLLibs.h" -#include "graphics/Material.h" #include "Program.h" +#include "graphics/Material.h" namespace Graphics { namespace OGL { class StarfieldMaterial : public Material { public: - virtual Program *CreateProgram(const MaterialDescriptor &) override { + virtual Program *CreateProgram(const MaterialDescriptor &) override + { return new Program("starfield", ""); } - virtual void Apply() override { + virtual void Apply() override + { OGL::Material::Apply(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); assert(this->texture0); @@ -29,12 +31,13 @@ namespace Graphics { m_program->emission.Set(this->emissive); } - virtual void Unapply() override { - static_cast(texture0)->Unbind(); + virtual void Unapply() override + { + static_cast(texture0)->Unbind(); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); } }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/TextureGL.cpp b/src/graphics/opengl/TextureGL.cpp index dfca01328..1c33f0cb6 100644 --- a/src/graphics/opengl/TextureGL.cpp +++ b/src/graphics/opengl/TextureGL.cpp @@ -1,412 +1,419 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "graphics/Renderer.h" -#include "RendererGL.h" #include "TextureGL.h" -#include +#include "RendererGL.h" +#include "graphics/Renderer.h" #include "utils.h" +#include static const unsigned int MIN_COMPRESSED_TEXTURE_DIMENSION = 16; namespace Graphics { -namespace OGL { + namespace OGL { -inline GLint GLInternalFormat(TextureFormat format) { - switch (format) { - case TEXTURE_RGB_888: return GL_RGB; - case TEXTURE_RGBA_8888: return GL_RGBA; - case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; - case TEXTURE_INTENSITY_8: return GL_RED; - case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case TEXTURE_DEPTH: return GL_DEPTH_COMPONENT; - default: assert(0); return 0; - } -} - -//for on the fly compression of textures -//luminance/intensity is used for fonts, so we prefer not to compress them -inline GLint GLCompressedInternalFormat(TextureFormat format) { - switch (format) { - case TEXTURE_RGBA_8888: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case TEXTURE_RGB_888: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; - case TEXTURE_INTENSITY_8: return GL_RED; - case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - default: assert(0); return 0; - } -} - -inline GLint GLImageFormat(TextureFormat format) { - switch (format) { - case TEXTURE_RGBA_8888: return GL_RGBA; - case TEXTURE_RGB_888: return GL_RGB; - case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; - case TEXTURE_INTENSITY_8: return GL_RED; - case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case TEXTURE_DEPTH: return GL_DEPTH_COMPONENT; - default: assert(0); return 0; - } -} - -inline GLint GLTextureType(TextureType type) { - switch (type) { - case TEXTURE_2D: return GL_TEXTURE_2D; - case TEXTURE_CUBE_MAP: return GL_TEXTURE_CUBE_MAP; - default: assert(0); return 0; - } -} - -inline GLint GLImageType(TextureFormat format) { - return GL_UNSIGNED_BYTE; -} - -inline int GetMinSize(TextureFormat flag) { - switch(flag) { - case TEXTURE_DXT1: return 8; - case TEXTURE_DXT5: return 16; - default: return 1; - } -} - -inline bool IsCompressed(TextureFormat format) { - return (format == TEXTURE_DXT1 || format == TEXTURE_DXT5); -} - -TextureGL::TextureGL(const TextureDescriptor &descriptor, const bool useCompressed, const bool useAnisoFiltering) : - Texture(descriptor), m_useAnisoFiltering(useAnisoFiltering && descriptor.useAnisotropicFiltering) -{ - PROFILE_SCOPED() - m_target = GLTextureType(descriptor.type); - - glGenTextures(1, &m_texture); - glBindTexture(m_target, m_texture); - CHECKERRORS(); - - // useCompressed is the global scope flag whereas descriptor.allowCompression is the local texture mode flag - // either both or neither might be true however only compress the texture when both are true. - const bool compressTexture = useCompressed && descriptor.allowCompression; - - switch (m_target) { - case GL_TEXTURE_2D: - if (!IsCompressed(descriptor.format)) { - if (!descriptor.generateMipmaps) - glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); - CHECKERRORS(); - - glTexImage2D( - m_target, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - CHECKERRORS(); - } else { - const GLint oglFormatMinSize = GetMinSize(descriptor.format); - size_t Width = descriptor.dataSize.x; - size_t Height = descriptor.dataSize.y; - size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; - - GLint maxMip = 0; - for( unsigned int i=0; i < descriptor.numberOfMipMaps; ++i ) { - maxMip = i; - glCompressedTexImage2D(GL_TEXTURE_2D, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { - break; - } - bufSize /= 4; - Width /= 2; - Height /= 2; - } - glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); - CHECKERRORS(); + inline GLint GLInternalFormat(TextureFormat format) + { + switch (format) { + case TEXTURE_RGB_888: return GL_RGB; + case TEXTURE_RGBA_8888: return GL_RGBA; + case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; + case TEXTURE_INTENSITY_8: return GL_RED; + case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case TEXTURE_DEPTH: return GL_DEPTH_COMPONENT; + default: assert(0); return 0; } - break; + } - case GL_TEXTURE_CUBE_MAP: - if(!IsCompressed(descriptor.format)) { - if(!descriptor.generateMipmaps) - glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); - CHECKERRORS(); - - glTexImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - glTexImage2D( - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - glTexImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - glTexImage2D( - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - glTexImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - glTexImage2D( - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), - descriptor.dataSize.x, descriptor.dataSize.y, 0, - GLImageFormat(descriptor.format), - GLImageType(descriptor.format), 0); - CHECKERRORS(); - } else { - const GLint oglFormatMinSize = GetMinSize(descriptor.format); - size_t Width = descriptor.dataSize.x; - size_t Height = descriptor.dataSize.y; - size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; - - GLint maxMip = 0; - for( unsigned int i=0; i < descriptor.numberOfMipMaps; ++i ) { - maxMip = i; - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); - if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { - break; - } - bufSize /= 4; - Width /= 2; - Height /= 2; - } - glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); - CHECKERRORS(); + //for on the fly compression of textures + //luminance/intensity is used for fonts, so we prefer not to compress them + inline GLint GLCompressedInternalFormat(TextureFormat format) + { + switch (format) { + case TEXTURE_RGBA_8888: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case TEXTURE_RGB_888: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; + case TEXTURE_INTENSITY_8: return GL_RED; + case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + default: assert(0); return 0; } - break; + } - default: - assert(0); - } - CHECKERRORS(); - - GLenum magFilter, minFilter, wrapS, wrapT; - switch (descriptor.sampleMode) { - default: // safe default will fall through to LINEAR_CLAMP when run in release builds without assert - assert(0); - case LINEAR_CLAMP: - magFilter = GL_LINEAR; - minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - wrapS = wrapT = GL_CLAMP_TO_EDGE; - break; - - case NEAREST_CLAMP: - magFilter = GL_NEAREST; - minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - wrapS = wrapT = GL_CLAMP_TO_EDGE; - break; - - case LINEAR_REPEAT: - magFilter = GL_LINEAR; - minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - wrapS = wrapT = GL_REPEAT; - break; - - case NEAREST_REPEAT: - magFilter = GL_NEAREST; - minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - wrapS = wrapT = GL_REPEAT; - break; - } - - glTexParameteri(m_target, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(m_target, GL_TEXTURE_WRAP_T, wrapS); - glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, magFilter); - glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, minFilter); - - // Anisotropic texture filtering - if (m_useAnisoFiltering) { - GLfloat maxAniso = 0.0f; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); - glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); - } - - CHECKERRORS(); -} - -TextureGL::~TextureGL() -{ - glDeleteTextures(1, &m_texture); -} - -void TextureGL::Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) -{ - PROFILE_SCOPED() - assert(m_target == GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(m_target, m_texture); - - switch (m_target) { - case GL_TEXTURE_2D: - if (!IsCompressed(format)) { - glTexSubImage2D(m_target, 0, pos.x, pos.y, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data); - } else { - const GLint oglInternalFormat = GLImageFormat(format); - size_t Offset = 0; - size_t Width = dataSize.x; - size_t Height = dataSize.y; - size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); - - const unsigned char *pData = static_cast(data); - for( unsigned int i = 0; i < numMips; ++i ) { - glCompressedTexSubImage2D(m_target, i, pos.x, pos.y, Width, Height, oglInternalFormat, bufSize, &pData[Offset]); - if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { - break; - } - Offset += bufSize; - bufSize /= 4; - Width /= 2; - Height /= 2; - } + inline GLint GLImageFormat(TextureFormat format) + { + switch (format) { + case TEXTURE_RGBA_8888: return GL_RGBA; + case TEXTURE_RGB_888: return GL_RGB; + case TEXTURE_LUMINANCE_ALPHA_88: return GL_RG; + case TEXTURE_INTENSITY_8: return GL_RED; + case TEXTURE_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case TEXTURE_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case TEXTURE_DEPTH: return GL_DEPTH_COMPONENT; + default: assert(0); return 0; } - break; + } - default: - assert(0); - } - - if (GetDescriptor().generateMipmaps && !IsCompressed(format)) - glGenerateMipmap(m_target); - - glBindTexture(m_target, 0); - CHECKERRORS(); -} - -void TextureGL::Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) -{ - PROFILE_SCOPED() - assert(m_target == GL_TEXTURE_CUBE_MAP); - glActiveTexture(GL_TEXTURE0); - glBindTexture(m_target, m_texture); - - switch (m_target) { - case GL_TEXTURE_CUBE_MAP: - if (!IsCompressed(format)) { - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posX); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negX); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posY); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negY); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posZ); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negZ); - } else { - const GLint oglInternalFormat = GLImageFormat(format); - size_t Offset = 0; - size_t Width = dataSize.x; - size_t Height = dataSize.y; - size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); - - const unsigned char *pData_px = static_cast(data.posX); - const unsigned char *pData_nx = static_cast(data.negX); - const unsigned char *pData_py = static_cast(data.posY); - const unsigned char *pData_ny = static_cast(data.negY); - const unsigned char *pData_pz = static_cast(data.posZ); - const unsigned char *pData_nz = static_cast(data.negZ); - for( unsigned int i = 0; i < numMips; ++i ) { - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_px[Offset]); - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nx[Offset]); - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_py[Offset]); - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_ny[Offset]); - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_pz[Offset]); - glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nz[Offset]); - if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { - break; - } - Offset += bufSize; - bufSize /= 4; - Width /= 2; - Height /= 2; - } + inline GLint GLTextureType(TextureType type) + { + switch (type) { + case TEXTURE_2D: return GL_TEXTURE_2D; + case TEXTURE_CUBE_MAP: return GL_TEXTURE_CUBE_MAP; + default: assert(0); return 0; } - break; + } - default: - assert(0); - } + inline GLint GLImageType(TextureFormat format) + { + return GL_UNSIGNED_BYTE; + } - if (GetDescriptor().generateMipmaps && !IsCompressed(format)) - glGenerateMipmap(m_target); + inline int GetMinSize(TextureFormat flag) + { + switch (flag) { + case TEXTURE_DXT1: return 8; + case TEXTURE_DXT5: return 16; + default: return 1; + } + } - glBindTexture(m_target, 0); - CHECKERRORS(); -} + inline bool IsCompressed(TextureFormat format) + { + return (format == TEXTURE_DXT1 || format == TEXTURE_DXT5); + } -void TextureGL::Bind() -{ - glBindTexture(m_target, m_texture); -} + TextureGL::TextureGL(const TextureDescriptor &descriptor, const bool useCompressed, const bool useAnisoFiltering) : + Texture(descriptor), + m_useAnisoFiltering(useAnisoFiltering && descriptor.useAnisotropicFiltering) + { + PROFILE_SCOPED() + m_target = GLTextureType(descriptor.type); -void TextureGL::Unbind() -{ - glBindTexture(m_target, 0); -} + glGenTextures(1, &m_texture); + glBindTexture(m_target, m_texture); + CHECKERRORS(); -void TextureGL::SetSampleMode(TextureSampleMode mode) -{ - GLenum magFilter, minFilter; - const bool mipmaps = GetDescriptor().generateMipmaps; - switch (mode) { - default: // safe default will fall through to LINEAR_CLAMP when run in release builds without assert - assert(0); - case LINEAR_CLAMP: - magFilter = GL_LINEAR; - minFilter = mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - break; + // useCompressed is the global scope flag whereas descriptor.allowCompression is the local texture mode flag + // either both or neither might be true however only compress the texture when both are true. + const bool compressTexture = useCompressed && descriptor.allowCompression; - case NEAREST_CLAMP: - magFilter = GL_NEAREST; - minFilter = mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - break; + switch (m_target) { + case GL_TEXTURE_2D: + if (!IsCompressed(descriptor.format)) { + if (!descriptor.generateMipmaps) + glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); + CHECKERRORS(); - case LINEAR_REPEAT: - magFilter = GL_LINEAR; - minFilter = mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - break; + glTexImage2D( + m_target, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + CHECKERRORS(); + } else { + const GLint oglFormatMinSize = GetMinSize(descriptor.format); + size_t Width = descriptor.dataSize.x; + size_t Height = descriptor.dataSize.y; + size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; - case NEAREST_REPEAT: - magFilter = GL_NEAREST; - minFilter = mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - break; - } - glBindTexture(m_target, m_texture); - glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, magFilter); - glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, minFilter); + GLint maxMip = 0; + for (unsigned int i = 0; i < descriptor.numberOfMipMaps; ++i) { + maxMip = i; + glCompressedTexImage2D(GL_TEXTURE_2D, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + if (Width <= MIN_COMPRESSED_TEXTURE_DIMENSION || Height <= MIN_COMPRESSED_TEXTURE_DIMENSION) { + break; + } + bufSize /= 4; + Width /= 2; + Height /= 2; + } + glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); + CHECKERRORS(); + } + break; - // Anisotropic texture filtering - if (m_useAnisoFiltering) { - GLfloat maxAniso = 0.0f; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); - glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); - } + case GL_TEXTURE_CUBE_MAP: + if (!IsCompressed(descriptor.format)) { + if (!descriptor.generateMipmaps) + glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); + CHECKERRORS(); - glBindTexture(m_target, 0); - CHECKERRORS(); -} + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), + descriptor.dataSize.x, descriptor.dataSize.y, 0, + GLImageFormat(descriptor.format), + GLImageType(descriptor.format), 0); + CHECKERRORS(); + } else { + const GLint oglFormatMinSize = GetMinSize(descriptor.format); + size_t Width = descriptor.dataSize.x; + size_t Height = descriptor.dataSize.y; + size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; -void TextureGL::BuildMipmaps() -{ - const TextureDescriptor& descriptor = GetDescriptor(); - const bool mipmaps = descriptor.generateMipmaps; - if (mipmaps) - { - glBindTexture(m_target, m_texture); - glGenerateMipmap(m_target); - glBindTexture(m_target, 0); - } -} + GLint maxMip = 0; + for (unsigned int i = 0; i < descriptor.numberOfMipMaps; ++i) { + maxMip = i; + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); + if (Width <= MIN_COMPRESSED_TEXTURE_DIMENSION || Height <= MIN_COMPRESSED_TEXTURE_DIMENSION) { + break; + } + bufSize /= 4; + Width /= 2; + Height /= 2; + } + glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); + CHECKERRORS(); + } + break; -} -} + default: + assert(0); + } + CHECKERRORS(); + + GLenum magFilter, minFilter, wrapS, wrapT; + switch (descriptor.sampleMode) { + default: // safe default will fall through to LINEAR_CLAMP when run in release builds without assert + assert(0); + case LINEAR_CLAMP: + magFilter = GL_LINEAR; + minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + wrapS = wrapT = GL_CLAMP_TO_EDGE; + break; + + case NEAREST_CLAMP: + magFilter = GL_NEAREST; + minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + wrapS = wrapT = GL_CLAMP_TO_EDGE; + break; + + case LINEAR_REPEAT: + magFilter = GL_LINEAR; + minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + wrapS = wrapT = GL_REPEAT; + break; + + case NEAREST_REPEAT: + magFilter = GL_NEAREST; + minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + wrapS = wrapT = GL_REPEAT; + break; + } + + glTexParameteri(m_target, GL_TEXTURE_WRAP_S, wrapS); + glTexParameteri(m_target, GL_TEXTURE_WRAP_T, wrapS); + glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, magFilter); + glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, minFilter); + + // Anisotropic texture filtering + if (m_useAnisoFiltering) { + GLfloat maxAniso = 0.0f; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); + glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); + } + + CHECKERRORS(); + } + + TextureGL::~TextureGL() + { + glDeleteTextures(1, &m_texture); + } + + void TextureGL::Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) + { + PROFILE_SCOPED() + assert(m_target == GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(m_target, m_texture); + + switch (m_target) { + case GL_TEXTURE_2D: + if (!IsCompressed(format)) { + glTexSubImage2D(m_target, 0, pos.x, pos.y, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data); + } else { + const GLint oglInternalFormat = GLImageFormat(format); + size_t Offset = 0; + size_t Width = dataSize.x; + size_t Height = dataSize.y; + size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); + + const unsigned char *pData = static_cast(data); + for (unsigned int i = 0; i < numMips; ++i) { + glCompressedTexSubImage2D(m_target, i, pos.x, pos.y, Width, Height, oglInternalFormat, bufSize, &pData[Offset]); + if (Width <= MIN_COMPRESSED_TEXTURE_DIMENSION || Height <= MIN_COMPRESSED_TEXTURE_DIMENSION) { + break; + } + Offset += bufSize; + bufSize /= 4; + Width /= 2; + Height /= 2; + } + } + break; + + default: + assert(0); + } + + if (GetDescriptor().generateMipmaps && !IsCompressed(format)) + glGenerateMipmap(m_target); + + glBindTexture(m_target, 0); + CHECKERRORS(); + } + + void TextureGL::Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) + { + PROFILE_SCOPED() + assert(m_target == GL_TEXTURE_CUBE_MAP); + glActiveTexture(GL_TEXTURE0); + glBindTexture(m_target, m_texture); + + switch (m_target) { + case GL_TEXTURE_CUBE_MAP: + if (!IsCompressed(format)) { + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posX); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negX); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posY); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negY); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posZ); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negZ); + } else { + const GLint oglInternalFormat = GLImageFormat(format); + size_t Offset = 0; + size_t Width = dataSize.x; + size_t Height = dataSize.y; + size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); + + const unsigned char *pData_px = static_cast(data.posX); + const unsigned char *pData_nx = static_cast(data.negX); + const unsigned char *pData_py = static_cast(data.posY); + const unsigned char *pData_ny = static_cast(data.negY); + const unsigned char *pData_pz = static_cast(data.posZ); + const unsigned char *pData_nz = static_cast(data.negZ); + for (unsigned int i = 0; i < numMips; ++i) { + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_px[Offset]); + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nx[Offset]); + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_py[Offset]); + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_ny[Offset]); + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_pz[Offset]); + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nz[Offset]); + if (Width <= MIN_COMPRESSED_TEXTURE_DIMENSION || Height <= MIN_COMPRESSED_TEXTURE_DIMENSION) { + break; + } + Offset += bufSize; + bufSize /= 4; + Width /= 2; + Height /= 2; + } + } + break; + + default: + assert(0); + } + + if (GetDescriptor().generateMipmaps && !IsCompressed(format)) + glGenerateMipmap(m_target); + + glBindTexture(m_target, 0); + CHECKERRORS(); + } + + void TextureGL::Bind() + { + glBindTexture(m_target, m_texture); + } + + void TextureGL::Unbind() + { + glBindTexture(m_target, 0); + } + + void TextureGL::SetSampleMode(TextureSampleMode mode) + { + GLenum magFilter, minFilter; + const bool mipmaps = GetDescriptor().generateMipmaps; + switch (mode) { + default: // safe default will fall through to LINEAR_CLAMP when run in release builds without assert + assert(0); + case LINEAR_CLAMP: + magFilter = GL_LINEAR; + minFilter = mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + break; + + case NEAREST_CLAMP: + magFilter = GL_NEAREST; + minFilter = mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + break; + + case LINEAR_REPEAT: + magFilter = GL_LINEAR; + minFilter = mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + break; + + case NEAREST_REPEAT: + magFilter = GL_NEAREST; + minFilter = mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + break; + } + glBindTexture(m_target, m_texture); + glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, magFilter); + glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, minFilter); + + // Anisotropic texture filtering + if (m_useAnisoFiltering) { + GLfloat maxAniso = 0.0f; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); + glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); + } + + glBindTexture(m_target, 0); + CHECKERRORS(); + } + + void TextureGL::BuildMipmaps() + { + const TextureDescriptor &descriptor = GetDescriptor(); + const bool mipmaps = descriptor.generateMipmaps; + if (mipmaps) { + glBindTexture(m_target, m_texture); + glGenerateMipmap(m_target); + glBindTexture(m_target, 0); + } + } + + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/TextureGL.h b/src/graphics/opengl/TextureGL.h index 7bcd34fdb..0ef83da29 100644 --- a/src/graphics/opengl/TextureGL.h +++ b/src/graphics/opengl/TextureGL.h @@ -7,10 +7,8 @@ #include "OpenGLLibs.h" #include "graphics/Texture.h" -namespace Graphics -{ - namespace OGL - { +namespace Graphics { + namespace OGL { class TextureGL : public Texture { public: virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override final; @@ -24,14 +22,18 @@ namespace Graphics virtual void SetSampleMode(TextureSampleMode) override final; virtual void BuildMipmaps() override final; - virtual uint32_t GetTextureID() const override final { assert(sizeof(uint32_t)==sizeof(GLuint)); return m_texture; } + virtual uint32_t GetTextureID() const override final + { + assert(sizeof(uint32_t) == sizeof(GLuint)); + return m_texture; + } private: GLenum m_target; GLuint m_texture; const bool m_useAnisoFiltering; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/UIMaterial.cpp b/src/graphics/opengl/UIMaterial.cpp index 4715f7240..7855760fa 100644 --- a/src/graphics/opengl/UIMaterial.cpp +++ b/src/graphics/opengl/UIMaterial.cpp @@ -2,12 +2,12 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "UIMaterial.h" -#include "graphics/Material.h" -#include "graphics/Graphics.h" -#include "TextureGL.h" #include "RendererGL.h" -#include #include "StringF.h" +#include "TextureGL.h" +#include "graphics/Graphics.h" +#include "graphics/Material.h" +#include namespace Graphics { namespace OGL { @@ -30,7 +30,7 @@ namespace Graphics { { OGL::Material::Apply(); - UIProgram *p = static_cast(m_program); + UIProgram *p = static_cast(m_program); p->diffuse.Set(this->diffuse); @@ -41,13 +41,13 @@ namespace Graphics { void UIMaterial::Unapply() { // Might not be necessary to unbind textures, but let's not old graphics code (eg, old-UI) - if ( texture1 ) { - static_cast(texture1)->Unbind(); + if (texture1) { + static_cast(texture1)->Unbind(); glActiveTexture(GL_TEXTURE0); } - if ( texture0 ) { - static_cast(texture0)->Unbind(); + if (texture0) { + static_cast(texture0)->Unbind(); } } - } -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/UIMaterial.h b/src/graphics/opengl/UIMaterial.h index b9162b1b3..401a0cead 100644 --- a/src/graphics/opengl/UIMaterial.h +++ b/src/graphics/opengl/UIMaterial.h @@ -26,7 +26,7 @@ namespace Graphics { virtual void Apply() override final; virtual void Unapply() override final; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/Uniform.cpp b/src/graphics/opengl/Uniform.cpp index 4c0cfebd9..6dc2b87db 100644 --- a/src/graphics/opengl/Uniform.cpp +++ b/src/graphics/opengl/Uniform.cpp @@ -5,87 +5,87 @@ #include "TextureGL.h" namespace Graphics { -namespace OGL { + namespace OGL { -Uniform::Uniform() -: m_location(-1) -{ -} + Uniform::Uniform() : + m_location(-1) + { + } -void Uniform::Init(const char *name, GLuint program) -{ - m_location = glGetUniformLocation(program, name); -} + void Uniform::Init(const char *name, GLuint program) + { + m_location = glGetUniformLocation(program, name); + } -void Uniform::Set(int i) -{ - if (m_location != -1) - glUniform1i(m_location, i); -} + void Uniform::Set(int i) + { + if (m_location != -1) + glUniform1i(m_location, i); + } -void Uniform::Set(float f) -{ - if (m_location != -1) - glUniform1f(m_location, f); -} + void Uniform::Set(float f) + { + if (m_location != -1) + glUniform1f(m_location, f); + } -void Uniform::Set(const vector3f &v) -{ - if (m_location != -1) - glUniform3f(m_location, v.x, v.y, v.z); -} + void Uniform::Set(const vector3f &v) + { + if (m_location != -1) + glUniform3f(m_location, v.x, v.y, v.z); + } -void Uniform::Set(const vector3d &v) -{ - if (m_location != -1) - glUniform3f(m_location, static_cast(v.x), static_cast(v.y), static_cast(v.z)); //yes, 3f -} + void Uniform::Set(const vector3d &v) + { + if (m_location != -1) + glUniform3f(m_location, static_cast(v.x), static_cast(v.y), static_cast(v.z)); //yes, 3f + } -void Uniform::Set(const Color &c) -{ - Color4f c4f = c.ToColor4f(); - if (m_location != -1) - glUniform4f(m_location, c4f.r, c4f.g, c4f.b, c4f.a); -} + void Uniform::Set(const Color &c) + { + Color4f c4f = c.ToColor4f(); + if (m_location != -1) + glUniform4f(m_location, c4f.r, c4f.g, c4f.b, c4f.a); + } -void Uniform::Set(const int v[3]) -{ - if (m_location != -1) - glUniform3i(m_location, v[0],v[1],v[2]); -} + void Uniform::Set(const int v[3]) + { + if (m_location != -1) + glUniform3i(m_location, v[0], v[1], v[2]); + } -void Uniform::Set(const float x, const float y, const float z, const float w) -{ - if (m_location != -1) - glUniform4f(m_location, x, y, z, w); -} + void Uniform::Set(const float x, const float y, const float z, const float w) + { + if (m_location != -1) + glUniform4f(m_location, x, y, z, w); + } -void Uniform::Set(const float m[9]) -{ - if (m_location != -1) - glUniformMatrix3fv(m_location, 1, GL_FALSE, m); -} + void Uniform::Set(const float m[9]) + { + if (m_location != -1) + glUniformMatrix3fv(m_location, 1, GL_FALSE, m); + } -void Uniform::Set(const matrix3x3f &m) -{ - if (m_location != -1) - glUniformMatrix3fv(m_location, 1, GL_FALSE, &m[0]); -} + void Uniform::Set(const matrix3x3f &m) + { + if (m_location != -1) + glUniformMatrix3fv(m_location, 1, GL_FALSE, &m[0]); + } -void Uniform::Set(const matrix4x4f &m) -{ - if (m_location != -1) - glUniformMatrix4fv(m_location, 1, GL_FALSE, &m[0]); -} + void Uniform::Set(const matrix4x4f &m) + { + if (m_location != -1) + glUniformMatrix4fv(m_location, 1, GL_FALSE, &m[0]); + } -void Uniform::Set(Texture *tex, unsigned int unit) -{ - if (m_location != -1 && tex) { - glActiveTexture(GL_TEXTURE0 + unit); - static_cast(tex)->Bind(); - glUniform1i(m_location, unit); - } -} + void Uniform::Set(Texture *tex, unsigned int unit) + { + if (m_location != -1 && tex) { + glActiveTexture(GL_TEXTURE0 + unit); + static_cast(tex)->Bind(); + glUniform1i(m_location, unit); + } + } -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/Uniform.h b/src/graphics/opengl/Uniform.h index 7931ddbc3..2403e34bd 100644 --- a/src/graphics/opengl/Uniform.h +++ b/src/graphics/opengl/Uniform.h @@ -8,10 +8,10 @@ */ #include "OpenGLLibs.h" -#include "vector3.h" +#include "Color.h" #include "matrix3x3.h" #include "matrix4x4.h" -#include "Color.h" +#include "vector3.h" namespace Graphics { @@ -24,21 +24,21 @@ namespace Graphics { void Init(const char *name, GLuint program); void Set(int); void Set(float); - void Set(const vector3f&); - void Set(const vector3d&); - void Set(const Color&); + void Set(const vector3f &); + void Set(const vector3d &); + void Set(const Color &); void Set(const int v[3]); void Set(const float x, const float y, const float z, const float w); void Set(const float m[9]); - void Set(const matrix3x3f&); - void Set(const matrix4x4f&); + void Set(const matrix3x3f &); + void Set(const matrix4x4f &); void Set(Texture *t, unsigned int unit); bool IsValid() const { return (m_location != -1); } private: GLint m_location; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/graphics/opengl/VertexBufferGL.cpp b/src/graphics/opengl/VertexBufferGL.cpp index e6ed14bdf..323b380b0 100644 --- a/src/graphics/opengl/VertexBufferGL.cpp +++ b/src/graphics/opengl/VertexBufferGL.cpp @@ -5,535 +5,555 @@ #include "graphics/VertexArray.h" #include "utils.h" -namespace Graphics { namespace OGL { +namespace Graphics { + namespace OGL { -GLint get_num_components(VertexAttribFormat fmt) -{ - switch (fmt) { - case ATTRIB_FORMAT_FLOAT2: - return 2; - case ATTRIB_FORMAT_FLOAT3: - return 3; - case ATTRIB_FORMAT_FLOAT4: - case ATTRIB_FORMAT_UBYTE4: - return 4; - default: - assert(false); - return 0; - } -} - -GLenum get_component_type(VertexAttribFormat fmt) -{ - switch (fmt) { - case ATTRIB_FORMAT_UBYTE4: - return GL_UNSIGNED_BYTE; - case ATTRIB_FORMAT_FLOAT2: - case ATTRIB_FORMAT_FLOAT3: - case ATTRIB_FORMAT_FLOAT4: - default: - return GL_FLOAT; - } -} - -VertexBuffer::VertexBuffer(const VertexBufferDesc &desc) : - Graphics::VertexBuffer(desc) -{ - PROFILE_SCOPED() - //update offsets in desc - for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { - if (m_desc.attrib[i].offset == 0) - m_desc.attrib[i].offset = VertexBufferDesc::CalculateOffset(m_desc, m_desc.attrib[i].semantic); - } - - //update stride in desc (respecting offsets) - if (m_desc.stride == 0) - { - Uint32 lastAttrib = 0; - while (lastAttrib < MAX_ATTRIBS) { - if (m_desc.attrib[lastAttrib].semantic == ATTRIB_NONE) - break; - lastAttrib++; + GLint get_num_components(VertexAttribFormat fmt) + { + switch (fmt) { + case ATTRIB_FORMAT_FLOAT2: + return 2; + case ATTRIB_FORMAT_FLOAT3: + return 3; + case ATTRIB_FORMAT_FLOAT4: + case ATTRIB_FORMAT_UBYTE4: + return 4; + default: + assert(false); + return 0; + } } - m_desc.stride = m_desc.attrib[lastAttrib].offset + VertexBufferDesc::GetAttribSize(m_desc.attrib[lastAttrib].format); - } - assert(m_desc.stride > 0); - assert(m_desc.numVertices > 0); - - //SetVertexCount(m_desc.numVertices); - - glGenVertexArrays(1, &m_vao); - glBindVertexArray(m_vao); - - glGenBuffers(1, &m_buffer); - - //Allocate GL buffer with undefined contents - //Critical optimisation for some architectures in cases where buffer is created and written in the same frame - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - const Uint32 dataSize = m_desc.numVertices * m_desc.stride; - const GLenum usage = (m_desc.usage == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; - glBufferData(GL_ARRAY_BUFFER, dataSize, 0, usage); - - //Setup the VAO pointers - for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { - const auto& attr = m_desc.attrib[i]; - if (attr.semantic == ATTRIB_NONE) - break; - - // Tell OpenGL what the array contains - const auto offset = reinterpret_cast(attr.offset); - switch (attr.semantic) { - case ATTRIB_POSITION: - glEnableVertexAttribArray(0); // Enable the attribute at that location - glVertexAttribPointer(0, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); - break; - case ATTRIB_NORMAL: - glEnableVertexAttribArray(1); // Enable the attribute at that location - glVertexAttribPointer(1, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); - break; - case ATTRIB_DIFFUSE: - glEnableVertexAttribArray(2); // Enable the attribute at that location - glVertexAttribPointer(2, get_num_components(attr.format), get_component_type(attr.format), GL_TRUE, m_desc.stride, offset); // only normalise the colours - break; - case ATTRIB_UV0: - glEnableVertexAttribArray(3); // Enable the attribute at that location - glVertexAttribPointer(3, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); - break; - case ATTRIB_TANGENT: - glEnableVertexAttribArray(4); // Enable the attribute at that location - glVertexAttribPointer(4, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); - break; - case ATTRIB_NONE: - default: - break; + GLenum get_component_type(VertexAttribFormat fmt) + { + switch (fmt) { + case ATTRIB_FORMAT_UBYTE4: + return GL_UNSIGNED_BYTE; + case ATTRIB_FORMAT_FLOAT2: + case ATTRIB_FORMAT_FLOAT3: + case ATTRIB_FORMAT_FLOAT4: + default: + return GL_FLOAT; + } } - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + VertexBuffer::VertexBuffer(const VertexBufferDesc &desc) : + Graphics::VertexBuffer(desc) + { + PROFILE_SCOPED() + //update offsets in desc + for (Uint32 i = 0; i < MAX_ATTRIBS; i++) { + if (m_desc.attrib[i].offset == 0) + m_desc.attrib[i].offset = VertexBufferDesc::CalculateOffset(m_desc, m_desc.attrib[i].semantic); + } - // Allocate client data store for dynamic buffers - if (GetDesc().usage != BUFFER_USAGE_STATIC) { - m_data = new Uint8[dataSize]; - memset(m_data, 0, dataSize); - } - else m_data = nullptr; -} + //update stride in desc (respecting offsets) + if (m_desc.stride == 0) { + Uint32 lastAttrib = 0; + while (lastAttrib < MAX_ATTRIBS) { + if (m_desc.attrib[lastAttrib].semantic == ATTRIB_NONE) + break; + lastAttrib++; + } -VertexBuffer::~VertexBuffer() -{ - glDeleteBuffers(1, &m_buffer); - glDeleteVertexArrays(1, &m_vao); - delete[] m_data; -} + m_desc.stride = m_desc.attrib[lastAttrib].offset + VertexBufferDesc::GetAttribSize(m_desc.attrib[lastAttrib].format); + } + assert(m_desc.stride > 0); + assert(m_desc.numVertices > 0); -Uint8 *VertexBuffer::MapInternal(BufferMapMode mode) -{ - PROFILE_SCOPED() - assert(mode != BUFFER_MAP_NONE); //makes no sense - assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped - m_mapMode = mode; - if (GetDesc().usage == BUFFER_USAGE_STATIC) { - glBindVertexArray(m_vao); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - if (mode == BUFFER_MAP_READ) - return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY)); - else if (mode == BUFFER_MAP_WRITE) - return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); - } + //SetVertexCount(m_desc.numVertices); - return m_data; -} + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); -void VertexBuffer::Unmap() -{ - PROFILE_SCOPED() - assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped + glGenBuffers(1, &m_buffer); - if (GetDesc().usage == BUFFER_USAGE_STATIC) { - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } else { - if (m_mapMode == BUFFER_MAP_WRITE) { - const GLsizei dataSize = m_desc.numVertices * m_desc.stride; + //Allocate GL buffer with undefined contents + //Critical optimisation for some architectures in cases where buffer is created and written in the same frame glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, dataSize, 0, GL_DYNAMIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, m_data); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - } - glBindVertexArray(0); + const Uint32 dataSize = m_desc.numVertices * m_desc.stride; + const GLenum usage = (m_desc.usage == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; + glBufferData(GL_ARRAY_BUFFER, dataSize, 0, usage); - m_mapMode = BUFFER_MAP_NONE; - m_written = true; -} + //Setup the VAO pointers + for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { + const auto &attr = m_desc.attrib[i]; + if (attr.semantic == ATTRIB_NONE) + break; + + // Tell OpenGL what the array contains + const auto offset = reinterpret_cast(attr.offset); + switch (attr.semantic) { + case ATTRIB_POSITION: + glEnableVertexAttribArray(0); // Enable the attribute at that location + glVertexAttribPointer(0, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); + break; + case ATTRIB_NORMAL: + glEnableVertexAttribArray(1); // Enable the attribute at that location + glVertexAttribPointer(1, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); + break; + case ATTRIB_DIFFUSE: + glEnableVertexAttribArray(2); // Enable the attribute at that location + glVertexAttribPointer(2, get_num_components(attr.format), get_component_type(attr.format), GL_TRUE, m_desc.stride, offset); // only normalise the colours + break; + case ATTRIB_UV0: + glEnableVertexAttribArray(3); // Enable the attribute at that location + glVertexAttribPointer(3, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); + break; + case ATTRIB_TANGENT: + glEnableVertexAttribArray(4); // Enable the attribute at that location + glVertexAttribPointer(4, get_num_components(attr.format), get_component_type(attr.format), GL_FALSE, m_desc.stride, offset); + break; + case ATTRIB_NONE: + default: + break; + } + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + // Allocate client data store for dynamic buffers + if (GetDesc().usage != BUFFER_USAGE_STATIC) { + m_data = new Uint8[dataSize]; + memset(m_data, 0, dataSize); + } else + m_data = nullptr; + } + + VertexBuffer::~VertexBuffer() + { + glDeleteBuffers(1, &m_buffer); + glDeleteVertexArrays(1, &m_vao); + delete[] m_data; + } + + Uint8 *VertexBuffer::MapInternal(BufferMapMode mode) + { + PROFILE_SCOPED() + assert(mode != BUFFER_MAP_NONE); //makes no sense + assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped + m_mapMode = mode; + if (GetDesc().usage == BUFFER_USAGE_STATIC) { + glBindVertexArray(m_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + if (mode == BUFFER_MAP_READ) + return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY)); + else if (mode == BUFFER_MAP_WRITE) + return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); + } + + return m_data; + } + + void VertexBuffer::Unmap() + { + PROFILE_SCOPED() + assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped + + if (GetDesc().usage == BUFFER_USAGE_STATIC) { + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } else { + if (m_mapMode == BUFFER_MAP_WRITE) { + const GLsizei dataSize = m_desc.numVertices * m_desc.stride; + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + glBufferData(GL_ARRAY_BUFFER, dataSize, 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, m_data); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + glBindVertexArray(0); + + m_mapMode = BUFFER_MAP_NONE; + m_written = true; + } #pragma pack(push, 4) -struct PosUVVert { - vector3f pos; - vector2f uv; -}; + struct PosUVVert { + vector3f pos; + vector2f uv; + }; -struct PosNormVert { - vector3f pos; - vector3f norm; -}; + struct PosNormVert { + vector3f pos; + vector3f norm; + }; -struct PosColVert { - vector3f pos; - Color4ub col; -}; + struct PosColVert { + vector3f pos; + Color4ub col; + }; -struct PosVert { - vector3f pos; -}; + struct PosVert { + vector3f pos; + }; -struct PosColUVVert { - vector3f pos; - Color4ub col; - vector2f uv; -}; + struct PosColUVVert { + vector3f pos; + Color4ub col; + vector2f uv; + }; -struct PosNormUVVert { - vector3f pos; - vector3f norm; - vector2f uv; -}; + struct PosNormUVVert { + vector3f pos; + vector3f norm; + vector2f uv; + }; -struct PosNormColVert { - vector3f pos; - vector3f norm; - Color4ub col; -}; + struct PosNormColVert { + vector3f pos; + vector3f norm; + Color4ub col; + }; #pragma pack(pop) -static inline void CopyPosNorm(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosNormVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosNormVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPosUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosUVVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosUVVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPosCol(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosColVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosColVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPos(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPosColUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosColUVVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosColUVVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPosNormUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosNormUVVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosNormUVVert)); - for(Uint32 i=0 ; iUnmap(); -} - -static inline void CopyPosNormCol(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) -{ - PosNormColVert* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(PosNormColVert)); - for(Uint32 i=0 ; iUnmap(); -} - -// copies the contents of the VertexArray into the buffer -bool VertexBuffer::Populate(const VertexArray &va) -{ - PROFILE_SCOPED() - assert(va.GetNumVerts()>0); - assert(va.GetNumVerts()<=m_capacity); - bool result = false; - const Graphics::AttributeSet as = va.GetAttributeSet(); - switch( as ) { - case Graphics::ATTRIB_POSITION: CopyPos(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE: CopyPosCol(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL: CopyPosNorm(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0: CopyPosUV0(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0: CopyPosColUV0(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_UV0: CopyPosNormUV0(this, va); result = true; break; - case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_DIFFUSE:CopyPosNormCol(this, va); result = true; break; - } - SetVertexCount(va.GetNumVerts()); - return result; -} - -void VertexBuffer::BufferData(const size_t size, void *data) -{ - PROFILE_SCOPED() - assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped - if (GetDesc().usage == BUFFER_USAGE_DYNAMIC) { - glBindVertexArray(m_vao); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, static_cast(size), static_cast(data), GL_DYNAMIC_DRAW); - } -} - -void VertexBuffer::Bind() { - assert(m_written); - glBindVertexArray(m_vao); - - // Enable the Vertex attributes - for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { - const auto& attr = m_desc.attrib[i]; - switch (attr.semantic) { - case ATTRIB_POSITION: glEnableVertexAttribArray(0); break; - case ATTRIB_NORMAL: glEnableVertexAttribArray(1); break; - case ATTRIB_DIFFUSE: glEnableVertexAttribArray(2); break; - case ATTRIB_UV0: glEnableVertexAttribArray(3); break; - case ATTRIB_TANGENT: glEnableVertexAttribArray(4); break; - case ATTRIB_NONE: - default: - return; + static inline void CopyPosNorm(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosNormVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosNormVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].norm = va.normal[i]; + } + vb->Unmap(); } - } -} -void VertexBuffer::Release() { - // Enable the Vertex attributes - for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { - const auto& attr = m_desc.attrib[i]; - switch (attr.semantic) { - case ATTRIB_POSITION: glDisableVertexAttribArray(0); break; - case ATTRIB_NORMAL: glDisableVertexAttribArray(1); break; - case ATTRIB_DIFFUSE: glDisableVertexAttribArray(2); break; - case ATTRIB_UV0: glDisableVertexAttribArray(3); break; - case ATTRIB_TANGENT: glDisableVertexAttribArray(4); break; - case ATTRIB_NONE: - default: - return; + static inline void CopyPosUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosUVVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosUVVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].uv = va.uv0[i]; + } + vb->Unmap(); } - } - glBindVertexArray(0); -} + static inline void CopyPosCol(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosColVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosColVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].col = va.diffuse[i]; + } + vb->Unmap(); + } -// ------------------------------------------------------------ -IndexBuffer::IndexBuffer(Uint32 size, BufferUsage hint) - : Graphics::IndexBuffer(size, hint) -{ - assert(size > 0); + static inline void CopyPos(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + } + vb->Unmap(); + } - const GLenum usage = (hint == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Uint32) * m_size, 0, usage); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + static inline void CopyPosColUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosColUVVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosColUVVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].col = va.diffuse[i]; + vtxPtr[i].uv = va.uv0[i]; + } + vb->Unmap(); + } - if (GetUsage() != BUFFER_USAGE_STATIC) { - m_data = new Uint32[size]; - memset(m_data, 0, sizeof(Uint32) * size); - } - else m_data = nullptr; -} + static inline void CopyPosNormUV0(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosNormUVVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosNormUVVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].norm = va.normal[i]; + vtxPtr[i].uv = va.uv0[i]; + } + vb->Unmap(); + } -IndexBuffer::~IndexBuffer() -{ - glDeleteBuffers(1, &m_buffer); - delete[] m_data; -} + static inline void CopyPosNormCol(Graphics::VertexBuffer *vb, const Graphics::VertexArray &va) + { + PosNormColVert *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(PosNormColVert)); + for (Uint32 i = 0; i < va.GetNumVerts(); i++) { + vtxPtr[i].pos = va.position[i]; + vtxPtr[i].norm = va.normal[i]; + vtxPtr[i].col = va.diffuse[i]; + } + vb->Unmap(); + } -Uint32 *IndexBuffer::Map(BufferMapMode mode) -{ - assert(mode != BUFFER_MAP_NONE); //makes no sense - assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped - m_mapMode = mode; - if (GetUsage() == BUFFER_USAGE_STATIC) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - if (mode == BUFFER_MAP_READ) - return reinterpret_cast(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY)); - else if (mode == BUFFER_MAP_WRITE) - return reinterpret_cast(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY)); - } + // copies the contents of the VertexArray into the buffer + bool VertexBuffer::Populate(const VertexArray &va) + { + PROFILE_SCOPED() + assert(va.GetNumVerts() > 0); + assert(va.GetNumVerts() <= m_capacity); + bool result = false; + const Graphics::AttributeSet as = va.GetAttributeSet(); + switch (as) { + case Graphics::ATTRIB_POSITION: + CopyPos(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE: + CopyPosCol(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL: + CopyPosNorm(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0: + CopyPosUV0(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0: + CopyPosColUV0(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_UV0: + CopyPosNormUV0(this, va); + result = true; + break; + case Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_DIFFUSE: + CopyPosNormCol(this, va); + result = true; + break; + } + SetVertexCount(va.GetNumVerts()); + return result; + } - return m_data; -} + void VertexBuffer::BufferData(const size_t size, void *data) + { + PROFILE_SCOPED() + assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped + if (GetDesc().usage == BUFFER_USAGE_DYNAMIC) { + glBindVertexArray(m_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + glBufferData(GL_ARRAY_BUFFER, static_cast(size), static_cast(data), GL_DYNAMIC_DRAW); + } + } -void IndexBuffer::Unmap() -{ - assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped + void VertexBuffer::Bind() + { + assert(m_written); + glBindVertexArray(m_vao); - if (GetUsage() == BUFFER_USAGE_STATIC) { - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } else { - if (m_mapMode == BUFFER_MAP_WRITE) { + // Enable the Vertex attributes + for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { + const auto &attr = m_desc.attrib[i]; + switch (attr.semantic) { + case ATTRIB_POSITION: glEnableVertexAttribArray(0); break; + case ATTRIB_NORMAL: glEnableVertexAttribArray(1); break; + case ATTRIB_DIFFUSE: glEnableVertexAttribArray(2); break; + case ATTRIB_UV0: glEnableVertexAttribArray(3); break; + case ATTRIB_TANGENT: glEnableVertexAttribArray(4); break; + case ATTRIB_NONE: + default: + return; + } + } + } + + void VertexBuffer::Release() + { + // Enable the Vertex attributes + for (Uint8 i = 0; i < MAX_ATTRIBS; i++) { + const auto &attr = m_desc.attrib[i]; + switch (attr.semantic) { + case ATTRIB_POSITION: glDisableVertexAttribArray(0); break; + case ATTRIB_NORMAL: glDisableVertexAttribArray(1); break; + case ATTRIB_DIFFUSE: glDisableVertexAttribArray(2); break; + case ATTRIB_UV0: glDisableVertexAttribArray(3); break; + case ATTRIB_TANGENT: glDisableVertexAttribArray(4); break; + case ATTRIB_NONE: + default: + return; + } + } + + glBindVertexArray(0); + } + + // ------------------------------------------------------------ + IndexBuffer::IndexBuffer(Uint32 size, BufferUsage hint) : + Graphics::IndexBuffer(size, hint) + { + assert(size > 0); + + const GLenum usage = (hint == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; + glGenBuffers(1, &m_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(Uint32) * m_size, 0, GL_DYNAMIC_DRAW); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(Uint32) * m_size, m_data); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Uint32) * m_size, 0, usage); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + if (GetUsage() != BUFFER_USAGE_STATIC) { + m_data = new Uint32[size]; + memset(m_data, 0, sizeof(Uint32) * size); + } else + m_data = nullptr; + } + + IndexBuffer::~IndexBuffer() + { + glDeleteBuffers(1, &m_buffer); + delete[] m_data; + } + + Uint32 *IndexBuffer::Map(BufferMapMode mode) + { + assert(mode != BUFFER_MAP_NONE); //makes no sense + assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped + m_mapMode = mode; + if (GetUsage() == BUFFER_USAGE_STATIC) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); + if (mode == BUFFER_MAP_READ) + return reinterpret_cast(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY)); + else if (mode == BUFFER_MAP_WRITE) + return reinterpret_cast(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY)); + } + + return m_data; + } + + void IndexBuffer::Unmap() + { + assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped + + if (GetUsage() == BUFFER_USAGE_STATIC) { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } else { + if (m_mapMode == BUFFER_MAP_WRITE) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(Uint32) * m_size, 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(Uint32) * m_size, m_data); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + } + + m_mapMode = BUFFER_MAP_NONE; + m_written = true; + } + + void IndexBuffer::BufferData(const size_t size, void *data) + { + PROFILE_SCOPED() + assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped + if (GetUsage() == BUFFER_USAGE_DYNAMIC) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast(size), static_cast(data), GL_DYNAMIC_DRAW); + } + } + + void IndexBuffer::Bind() + { + assert(m_written); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); + } + + void IndexBuffer::Release() + { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - } - m_mapMode = BUFFER_MAP_NONE; - m_written = true; -} + // ------------------------------------------------------------ + InstanceBuffer::InstanceBuffer(Uint32 size, BufferUsage hint) : + Graphics::InstanceBuffer(size, hint) + { + assert(size > 0); -void IndexBuffer::BufferData(const size_t size, void *data) -{ - PROFILE_SCOPED() - assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped - if (GetUsage() == BUFFER_USAGE_DYNAMIC) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast(size), static_cast(data), GL_DYNAMIC_DRAW); - } -} - -void IndexBuffer::Bind() { - assert(m_written); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); -} - -void IndexBuffer::Release() { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -// ------------------------------------------------------------ -InstanceBuffer::InstanceBuffer(Uint32 size, BufferUsage hint) - : Graphics::InstanceBuffer(size, hint) -{ - assert(size > 0); - - const GLenum usage = (hint == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(matrix4x4f) * m_size, 0, usage); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - if (GetUsage() != BUFFER_USAGE_STATIC) { - m_data.reset(new matrix4x4f[size]); - memset(m_data.get(), 0, sizeof(matrix4x4f) * size); - } -} - -InstanceBuffer::~InstanceBuffer() -{ - glDeleteBuffers(1, &m_buffer); -} - -matrix4x4f* InstanceBuffer::Map(BufferMapMode mode) -{ - assert(mode != BUFFER_MAP_NONE); //makes no sense - assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped - m_mapMode = mode; - if (GetUsage() == BUFFER_USAGE_STATIC) { - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - if (mode == BUFFER_MAP_READ) - return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY)); - else if (mode == BUFFER_MAP_WRITE) - return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); - } - - return m_data.get(); -} - -void InstanceBuffer::Unmap() -{ - assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped - - if (GetUsage() == BUFFER_USAGE_STATIC) { - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } else { - if (m_mapMode == BUFFER_MAP_WRITE) { + const GLenum usage = (hint == BUFFER_USAGE_STATIC) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; + glGenBuffers(1, &m_buffer); glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(matrix4x4f) * m_size, 0, GL_DYNAMIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(matrix4x4f) * m_size, m_data.get()); + glBufferData(GL_ARRAY_BUFFER, sizeof(matrix4x4f) * m_size, 0, usage); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + if (GetUsage() != BUFFER_USAGE_STATIC) { + m_data.reset(new matrix4x4f[size]); + memset(m_data.get(), 0, sizeof(matrix4x4f) * size); + } + } + + InstanceBuffer::~InstanceBuffer() + { + glDeleteBuffers(1, &m_buffer); + } + + matrix4x4f *InstanceBuffer::Map(BufferMapMode mode) + { + assert(mode != BUFFER_MAP_NONE); //makes no sense + assert(m_mapMode == BUFFER_MAP_NONE); //must not be currently mapped + m_mapMode = mode; + if (GetUsage() == BUFFER_USAGE_STATIC) { + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + if (mode == BUFFER_MAP_READ) + return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY)); + else if (mode == BUFFER_MAP_WRITE) + return reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); + } + + return m_data.get(); + } + + void InstanceBuffer::Unmap() + { + assert(m_mapMode != BUFFER_MAP_NONE); //not currently mapped + + if (GetUsage() == BUFFER_USAGE_STATIC) { + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } else { + if (m_mapMode == BUFFER_MAP_WRITE) { + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(matrix4x4f) * m_size, 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(matrix4x4f) * m_size, m_data.get()); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + + m_mapMode = BUFFER_MAP_NONE; + m_written = true; + } + + void InstanceBuffer::Bind() + { + assert(m_written); + glBindBuffer(GL_ARRAY_BUFFER, m_buffer); + + // used to pass a matrix4x4f in, however each attrib array is max size of (GLSL) vec4 so must enable 4 arrays + const size_t sizeVec4 = (sizeof(float) * 4); + glEnableVertexAttribArray(INSTOFFS_MAT0); + glVertexAttribPointer(INSTOFFS_MAT0, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(0)); + glEnableVertexAttribArray(INSTOFFS_MAT1); + glVertexAttribPointer(INSTOFFS_MAT1, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(sizeVec4)); + glEnableVertexAttribArray(INSTOFFS_MAT2); + glVertexAttribPointer(INSTOFFS_MAT2, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(2 * sizeVec4)); + glEnableVertexAttribArray(INSTOFFS_MAT3); + glVertexAttribPointer(INSTOFFS_MAT3, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(3 * sizeVec4)); + + glVertexAttribDivisor(INSTOFFS_MAT0, 1); + glVertexAttribDivisor(INSTOFFS_MAT1, 1); + glVertexAttribDivisor(INSTOFFS_MAT2, 1); + glVertexAttribDivisor(INSTOFFS_MAT3, 1); + } + + void InstanceBuffer::Release() + { + // see enable comment above + glDisableVertexAttribArray(INSTOFFS_MAT0); + glDisableVertexAttribArray(INSTOFFS_MAT1); + glDisableVertexAttribArray(INSTOFFS_MAT2); + glDisableVertexAttribArray(INSTOFFS_MAT3); + glBindBuffer(GL_ARRAY_BUFFER, 0); } - } - m_mapMode = BUFFER_MAP_NONE; - m_written = true; -} - -void InstanceBuffer::Bind() { - assert(m_written); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - - // used to pass a matrix4x4f in, however each attrib array is max size of (GLSL) vec4 so must enable 4 arrays - const size_t sizeVec4 = (sizeof(float)*4); - glEnableVertexAttribArray(INSTOFFS_MAT0); - glVertexAttribPointer(INSTOFFS_MAT0, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(0)); - glEnableVertexAttribArray(INSTOFFS_MAT1); - glVertexAttribPointer(INSTOFFS_MAT1, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(sizeVec4)); - glEnableVertexAttribArray(INSTOFFS_MAT2); - glVertexAttribPointer(INSTOFFS_MAT2, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(2 * sizeVec4)); - glEnableVertexAttribArray(INSTOFFS_MAT3); - glVertexAttribPointer(INSTOFFS_MAT3, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast(3 * sizeVec4)); - - glVertexAttribDivisor(INSTOFFS_MAT0, 1); - glVertexAttribDivisor(INSTOFFS_MAT1, 1); - glVertexAttribDivisor(INSTOFFS_MAT2, 1); - glVertexAttribDivisor(INSTOFFS_MAT3, 1); -} - -void InstanceBuffer::Release() { - // see enable comment above - glDisableVertexAttribArray(INSTOFFS_MAT0); - glDisableVertexAttribArray(INSTOFFS_MAT1); - glDisableVertexAttribArray(INSTOFFS_MAT2); - glDisableVertexAttribArray(INSTOFFS_MAT3); - - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -} //namespace OGL + } //namespace OGL } //namespace Graphics diff --git a/src/graphics/opengl/VertexBufferGL.h b/src/graphics/opengl/VertexBufferGL.h index d3f0ba5fc..0338dac16 100644 --- a/src/graphics/opengl/VertexBufferGL.h +++ b/src/graphics/opengl/VertexBufferGL.h @@ -6,81 +6,84 @@ #include "OpenGLLibs.h" #include "graphics/VertexBuffer.h" -namespace Graphics { namespace OGL { +namespace Graphics { + namespace OGL { -class GLBufferBase { -public: - GLBufferBase() : m_written(false) {} - GLuint GetBuffer() const { return m_buffer; } + class GLBufferBase { + public: + GLBufferBase() : + m_written(false) {} + GLuint GetBuffer() const { return m_buffer; } -protected: - GLuint m_buffer; - bool m_written; // to check for invalid data rendering -}; + protected: + GLuint m_buffer; + bool m_written; // to check for invalid data rendering + }; -class VertexBuffer : public Graphics::VertexBuffer, public GLBufferBase { -public: - VertexBuffer(const VertexBufferDesc&); - ~VertexBuffer(); + class VertexBuffer : public Graphics::VertexBuffer, public GLBufferBase { + public: + VertexBuffer(const VertexBufferDesc &); + ~VertexBuffer(); - virtual void Unmap() override final; + virtual void Unmap() override final; - // copies the contents of the VertexArray into the buffer - virtual bool Populate(const VertexArray &) override final; + // copies the contents of the VertexArray into the buffer + virtual bool Populate(const VertexArray &) override final; - // change the buffer data without mapping - virtual void BufferData(const size_t, void*) override final; + // change the buffer data without mapping + virtual void BufferData(const size_t, void *) override final; - virtual void Bind() override final; - virtual void Release() override final; + virtual void Bind() override final; + virtual void Release() override final; -protected: - virtual Uint8 *MapInternal(BufferMapMode) override final; + protected: + virtual Uint8 *MapInternal(BufferMapMode) override final; -private: - GLuint m_vao; - Uint8 *m_data; -}; + private: + GLuint m_vao; + Uint8 *m_data; + }; -class IndexBuffer : public Graphics::IndexBuffer, public GLBufferBase { -public: - IndexBuffer(Uint32 size, BufferUsage); - ~IndexBuffer(); + class IndexBuffer : public Graphics::IndexBuffer, public GLBufferBase { + public: + IndexBuffer(Uint32 size, BufferUsage); + ~IndexBuffer(); - virtual Uint32 *Map(BufferMapMode) override final; - virtual void Unmap() override final; + virtual Uint32 *Map(BufferMapMode) override final; + virtual void Unmap() override final; - // change the buffer data without mapping - virtual void BufferData(const size_t, void*) override final; + // change the buffer data without mapping + virtual void BufferData(const size_t, void *) override final; - virtual void Bind() override final; - virtual void Release() override final; + virtual void Bind() override final; + virtual void Release() override final; -private: - Uint32 *m_data; -}; + private: + Uint32 *m_data; + }; -// Instance buffer -class InstanceBuffer : public Graphics::InstanceBuffer, public GLBufferBase { -public: - InstanceBuffer(Uint32 size, BufferUsage); - virtual ~InstanceBuffer() override final; - virtual matrix4x4f* Map(BufferMapMode) override final; - virtual void Unmap() override final; + // Instance buffer + class InstanceBuffer : public Graphics::InstanceBuffer, public GLBufferBase { + public: + InstanceBuffer(Uint32 size, BufferUsage); + virtual ~InstanceBuffer() override final; + virtual matrix4x4f *Map(BufferMapMode) override final; + virtual void Unmap() override final; - virtual void Bind() override final; - virtual void Release() override final; + virtual void Bind() override final; + virtual void Release() override final; -protected: - enum InstOffs { - INSTOFFS_MAT0 = 6, // these value must match those of a_transform within data/shaders/opengl/attributes.glsl - INSTOFFS_MAT1 = 7, - INSTOFFS_MAT2 = 8, - INSTOFFS_MAT3 = 9 - }; - std::unique_ptr m_data; -}; + protected: + enum InstOffs { + INSTOFFS_MAT0 = 6, // these value must match those of a_transform within data/shaders/opengl/attributes.glsl + INSTOFFS_MAT1 = 7, + INSTOFFS_MAT2 = 8, + INSTOFFS_MAT3 = 9 + }; + std::unique_ptr m_data; + }; -} } + } // namespace OGL +} // namespace Graphics #endif // OGL_VERTEXBUFFER_H diff --git a/src/graphics/opengl/VtxColorMaterial.cpp b/src/graphics/opengl/VtxColorMaterial.cpp index fb36cd02f..56eca32f8 100644 --- a/src/graphics/opengl/VtxColorMaterial.cpp +++ b/src/graphics/opengl/VtxColorMaterial.cpp @@ -2,29 +2,29 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "VtxColorMaterial.h" -#include "graphics/Material.h" -#include "graphics/Graphics.h" -#include "TextureGL.h" #include "RendererGL.h" -#include #include "StringF.h" +#include "TextureGL.h" +#include "graphics/Graphics.h" +#include "graphics/Material.h" +#include namespace Graphics { -namespace OGL { + namespace OGL { -VtxColorProgram::VtxColorProgram(const MaterialDescriptor &desc) -{ - m_name = "vtxColor"; - CHECKERRORS(); + VtxColorProgram::VtxColorProgram(const MaterialDescriptor &desc) + { + m_name = "vtxColor"; + CHECKERRORS(); - LoadShaders(m_name, m_defines); - InitUniforms(); -} + LoadShaders(m_name, m_defines); + InitUniforms(); + } -Program *VtxColorMaterial::CreateProgram(const MaterialDescriptor &desc) -{ - return new VtxColorProgram(desc); -} + Program *VtxColorMaterial::CreateProgram(const MaterialDescriptor &desc) + { + return new VtxColorProgram(desc); + } -} -} + } // namespace OGL +} // namespace Graphics diff --git a/src/graphics/opengl/VtxColorMaterial.h b/src/graphics/opengl/VtxColorMaterial.h index cb5516b99..28c07eb9d 100644 --- a/src/graphics/opengl/VtxColorMaterial.h +++ b/src/graphics/opengl/VtxColorMaterial.h @@ -23,7 +23,7 @@ namespace Graphics { public: virtual Program *CreateProgram(const MaterialDescriptor &) override final; }; - } -} + } // namespace OGL +} // namespace Graphics #endif diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 9b8441619..a3bf69274 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -1,30 +1,30 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" #include "graphics/Graphics.h" #include "graphics/RenderState.h" +#include "libs.h" namespace Gui { -namespace RawEvents { - sigc::signal onMouseMotion; - sigc::signal onMouseDown; - sigc::signal onMouseUp; - sigc::signal onKeyDown; - sigc::signal onKeyUp; - sigc::signal onJoyAxisMotion; - sigc::signal onJoyButtonDown; - sigc::signal onJoyButtonUp; - sigc::signal onJoyHatMotion; -} + namespace RawEvents { + sigc::signal onMouseMotion; + sigc::signal onMouseDown; + sigc::signal onMouseUp; + sigc::signal onKeyDown; + sigc::signal onKeyUp; + sigc::signal onJoyAxisMotion; + sigc::signal onJoyButtonDown; + sigc::signal onJoyButtonUp; + sigc::signal onJoyHatMotion; + } // namespace RawEvents -static Sint32 lastMouseX, lastMouseY; -void HandleSDLEvent(SDL_Event *event) -{ - PROFILE_SCOPED() - switch (event->type) { + static Sint32 lastMouseX, lastMouseY; + void HandleSDLEvent(SDL_Event *event) + { + PROFILE_SCOPED() + switch (event->type) { case SDL_MOUSEBUTTONDOWN: lastMouseX = event->button.x; lastMouseY = event->button.y; @@ -38,14 +38,14 @@ void HandleSDLEvent(SDL_Event *event) case SDL_MOUSEWHEEL: { // synthesizing an SDL1.2-style button event for mouse wheels SDL_MouseButtonEvent ev; - ev.type = SDL_MOUSEBUTTONDOWN; + ev.type = SDL_MOUSEBUTTONDOWN; ev.button = event->wheel.y > 0 ? MouseButtonEvent::BUTTON_WHEELUP : MouseButtonEvent::BUTTON_WHEELDOWN; ev.state = SDL_PRESSED; ev.x = lastMouseX; ev.y = lastMouseY; Screen::OnClick(&ev); break; - } + } case SDL_KEYDOWN: Screen::OnKeyDown(&event->key.keysym); RawEvents::onKeyDown.emit(&event->key); @@ -74,170 +74,86 @@ void HandleSDLEvent(SDL_Event *event) case SDL_JOYHATMOTION: RawEvents::onJoyHatMotion(&event->jhat); break; + } } -} -struct TimerSignal { - Uint32 goTime; - sigc::signal sig; -}; + struct TimerSignal { + Uint32 goTime; + sigc::signal sig; + }; -static std::list g_timeSignals; + static std::list g_timeSignals; -sigc::connection AddTimer(Uint32 ms, sigc::slot slot) -{ - TimerSignal *_s = new TimerSignal; - _s->goTime = SDL_GetTicks() + ms; - sigc::connection con = _s->sig.connect(slot); - g_timeSignals.push_back(_s); - return con; -} + sigc::connection AddTimer(Uint32 ms, sigc::slot slot) + { + TimerSignal *_s = new TimerSignal; + _s->goTime = SDL_GetTicks() + ms; + sigc::connection con = _s->sig.connect(slot); + g_timeSignals.push_back(_s); + return con; + } -void Draw() -{ - PROFILE_SCOPED() - Uint32 t = SDL_GetTicks(); - // also abused like an update() function... - for (std::list::iterator i = g_timeSignals.begin(); i != g_timeSignals.end();) { - if (t >= (*i)->goTime) { - (*i)->sig.emit(); + void Draw() + { + PROFILE_SCOPED() + Uint32 t = SDL_GetTicks(); + // also abused like an update() function... + for (std::list::iterator i = g_timeSignals.begin(); i != g_timeSignals.end();) { + if (t >= (*i)->goTime) { + (*i)->sig.emit(); + delete *i; + i = g_timeSignals.erase(i); + } else { + ++i; + } + } + // ExpireTimers(t); + + Screen::Draw(); + } + + void Init(Graphics::Renderer *renderer, int screen_width, int screen_height, int ui_width, int ui_height) + { + Screen::Init(renderer, screen_width, screen_height, ui_width, ui_height); + } + + void Uninit() + { + std::list::iterator i; + for (i = g_timeSignals.begin(); i != g_timeSignals.end(); ++i) delete *i; - i = g_timeSignals.erase(i); - } else { - ++i; - } + + Screen::Uninit(); } -// ExpireTimers(t); - Screen::Draw(); -} + namespace Theme { + namespace Colors { + const Color bg(64, 94, 161); + const Color bgShadow(20, 31, 54); + const Color tableHeading(178, 178, 255); + } // namespace Colors + static const float BORDER_WIDTH = 2.0; -void Init(Graphics::Renderer *renderer, int screen_width, int screen_height, int ui_width, int ui_height) -{ - Screen::Init(renderer, screen_width, screen_height, ui_width, ui_height); -} - -void Uninit() -{ - std::list::iterator i; - for (i=g_timeSignals.begin(); i!=g_timeSignals.end(); ++i) delete *i; - - Screen::Uninit(); -} - -namespace Theme { - namespace Colors { - const Color bg(64, 94, 161); - const Color bgShadow(20, 31, 54); - const Color tableHeading(178, 178, 255); - } - static const float BORDER_WIDTH = 2.0; - - struct TPos { - vector3f pos; - }; - - void DrawHollowRect(const float size[2], const Color &color, Graphics::RenderState *state) - { - const vector3f vertices[] = { - /* 0 */ vector3f(0,0,0), - /* 1 */ vector3f(0,size[1],0), - /* 2 */ vector3f(size[0],size[1],0), - /* 3 */ vector3f(size[0],0,0), - /* 4 */ vector3f(BORDER_WIDTH,BORDER_WIDTH,0), - /* 5 */ vector3f(BORDER_WIDTH,size[1]-BORDER_WIDTH,0), - /* 6 */ vector3f(size[0]-BORDER_WIDTH,size[1]-BORDER_WIDTH,0), - /* 7 */ vector3f(size[0]-BORDER_WIDTH,BORDER_WIDTH,0) + struct TPos { + vector3f pos; }; - const Uint32 indices[] = { - 0,1,5, 0,5,4, 0,4,7, 0,7,3, - 3,7,6, 3,6,2, 1,2,6, 1,6,5 }; - // create buffer - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = 8; - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - // Upload data - // VertexBuffer - std::unique_ptr vb; - vb.reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); - TPos* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(TPos)); - for(Uint32 i=0 ; i<8 ; i++) { - vtxPtr[i].pos = vertices[i]; - } - vb->Unmap(); - - //create index buffer & copy - std::unique_ptr ib; - ib.reset(Screen::GetRenderer()->CreateIndexBuffer(24, Graphics::BUFFER_USAGE_STATIC)); - Uint32* idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); - for (Uint32 j = 0; j < 24; j++) { - idxPtr[j] = indices[j]; - } - ib->Unmap(); - - Screen::flatColorMaterial->diffuse = color; - Screen::GetRenderer()->DrawBufferIndexed(vb.get(), ib.get(), state, Screen::flatColorMaterial); - } - - Graphics::IndexBuffer* CreateIndexBuffer(const Uint32 indices[], const Uint32 IndexStart, const Uint32 IndexEnd, const Uint32 NumIndices) - { - Graphics::IndexBuffer *ib = Screen::GetRenderer()->CreateIndexBuffer(NumIndices, Graphics::BUFFER_USAGE_STATIC); - Uint32* idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); - for (Uint32 j = 0; j < NumIndices; j++) { - idxPtr[j] = indices[j + IndexStart]; - } - ib->Unmap(); - - return ib; - } - - struct TIndentBuffers { - RefCountedPtr vb; - RefCountedPtr ib[3]; - }; - typedef std::map MapIndentBuffers; - static MapIndentBuffers s_indentBuffers; - void DrawIndent(const float size[2], Graphics::RenderState *state) - { - PROFILE_SCOPED() - - // locals - RefCountedPtr vb; - RefCountedPtr ib[3]; - - // see if we have this size of indent in the cache already - const vector2f vsize(size[0], size[1]); - MapIndentBuffers::iterator bufIt = s_indentBuffers.find(vsize); - if (bufIt != s_indentBuffers.end()) + void DrawHollowRect(const float size[2], const Color &color, Graphics::RenderState *state) { - // found it - vb = bufIt->second.vb; - ib[0] = bufIt->second.ib[0]; - ib[1] = bufIt->second.ib[1]; - ib[2] = bufIt->second.ib[2]; - } - else - { - // generate it const vector3f vertices[] = { - /* 0 */ vector3f(0, 0, 0), - /* 1 */ vector3f(0, size[1], 0), - /* 2 */ vector3f(size[0], size[1], 0), - /* 3 */ vector3f(size[0], 0, 0), - /* 4 */ vector3f(BORDER_WIDTH, BORDER_WIDTH, 0), - /* 5 */ vector3f(BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), - /* 6 */ vector3f(size[0] - BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), - /* 7 */ vector3f(size[0] - BORDER_WIDTH, BORDER_WIDTH, 0) + /* 0 */ vector3f(0, 0, 0), + /* 1 */ vector3f(0, size[1], 0), + /* 2 */ vector3f(size[0], size[1], 0), + /* 3 */ vector3f(size[0], 0, 0), + /* 4 */ vector3f(BORDER_WIDTH, BORDER_WIDTH, 0), + /* 5 */ vector3f(BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 6 */ vector3f(size[0] - BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 7 */ vector3f(size[0] - BORDER_WIDTH, BORDER_WIDTH, 0) }; const Uint32 indices[] = { 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3, - 3, 7, 6, 3, 6, 2, 1, 2, 6, 1, 6, 5, - 4, 5, 6, 4, 6, 7 }; + 3, 7, 6, 3, 6, 2, 1, 2, 6, 1, 6, 5 + }; // create buffer Graphics::VertexBufferDesc vbd; @@ -247,144 +163,226 @@ namespace Theme { vbd.usage = Graphics::BUFFER_USAGE_STATIC; // Upload data - vb.Reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); - TPos* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + // VertexBuffer + std::unique_ptr vb; + vb.reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); + TPos *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); assert(vb->GetDesc().stride == sizeof(TPos)); for (Uint32 i = 0; i < 8; i++) { vtxPtr[i].pos = vertices[i]; } vb->Unmap(); - // indices - Uint32 IndexStart = 0; - Uint32 IndexEnd = 12; - Uint32 NumIndices = 12; - - ib[0].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - IndexStart += NumIndices; - NumIndices = 12; - IndexEnd += NumIndices; - - ib[1].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - IndexStart += NumIndices; - NumIndices = 6; - IndexEnd += NumIndices; - - ib[2].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - TIndentBuffers tib; - tib.vb = vb; - tib.ib[0] = ib[0]; - tib.ib[1] = ib[1]; - tib.ib[2] = ib[2]; - s_indentBuffers[vsize] = tib; - } - - // Draw it! - Screen::flatColorMaterial->diffuse = Colors::bgShadow; - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[0].Get(), state, Screen::flatColorMaterial); - Screen::flatColorMaterial->diffuse = Color(153,153,153,255); - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[1].Get(), state, Screen::flatColorMaterial); - Screen::flatColorMaterial->diffuse = Colors::bg; - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[2].Get(), state, Screen::flatColorMaterial); - } - - struct TOutdentBuffers { - RefCountedPtr vb; - RefCountedPtr ib[3]; - }; - typedef std::map MapOutdentBuffers; - static MapOutdentBuffers s_outdentBuffers; - void DrawOutdent(const float size[2], Graphics::RenderState *state) - { - PROFILE_SCOPED() - - // locals - RefCountedPtr vb; - RefCountedPtr ib[3]; - - // see if we have this size of indent in the cache already - const vector2f vsize(size[0], size[1]); - MapOutdentBuffers::iterator bufIt = s_outdentBuffers.find(vsize); - if (bufIt != s_outdentBuffers.end()) - { - // found it - vb = bufIt->second.vb; - ib[0] = bufIt->second.ib[0]; - ib[1] = bufIt->second.ib[1]; - ib[2] = bufIt->second.ib[2]; - } - else - { - // generate it - const vector3f vertices[] = { - /* 0 */ vector3f(0, 0, 0), - /* 1 */ vector3f(0, size[1], 0), - /* 2 */ vector3f(size[0], size[1], 0), - /* 3 */ vector3f(size[0], 0, 0), - /* 4 */ vector3f(BORDER_WIDTH, BORDER_WIDTH, 0), - /* 5 */ vector3f(BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), - /* 6 */ vector3f(size[0] - BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), - /* 7 */ vector3f(size[0] - BORDER_WIDTH, BORDER_WIDTH, 0) - }; - const Uint32 indices[] = { - 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3, - 3, 7, 6, 3, 6, 2, 1, 2, 6, 1, 6, 5, - 4, 5, 6, 4, 6, 7 }; - - // create buffer - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = 8; - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - // Upload data - vb.Reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); - TPos* vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - assert(vb->GetDesc().stride == sizeof(TPos)); - for (Uint32 i = 0; i < 8; i++) { - vtxPtr[i].pos = vertices[i]; + //create index buffer & copy + std::unique_ptr ib; + ib.reset(Screen::GetRenderer()->CreateIndexBuffer(24, Graphics::BUFFER_USAGE_STATIC)); + Uint32 *idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); + for (Uint32 j = 0; j < 24; j++) { + idxPtr[j] = indices[j]; } - vb->Unmap(); + ib->Unmap(); - // indices - Uint32 IndexStart = 0; - Uint32 IndexEnd = 12; - Uint32 NumIndices = 12; - - ib[0].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - IndexStart += NumIndices; - NumIndices = 12; - IndexEnd += NumIndices; - - ib[1].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - IndexStart += NumIndices; - NumIndices = 6; - IndexEnd += NumIndices; - - ib[2].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); - - TOutdentBuffers tib; - tib.vb = vb; - tib.ib[0] = ib[0]; - tib.ib[1] = ib[1]; - tib.ib[2] = ib[2]; - s_outdentBuffers[vsize] = tib; + Screen::flatColorMaterial->diffuse = color; + Screen::GetRenderer()->DrawBufferIndexed(vb.get(), ib.get(), state, Screen::flatColorMaterial); } - // Draw it! - Screen::flatColorMaterial->diffuse = Color(153,153,153,255); - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[0].Get(), state, Screen::flatColorMaterial); - Screen::flatColorMaterial->diffuse = Colors::bgShadow; - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[1].Get(), state, Screen::flatColorMaterial); - Screen::flatColorMaterial->diffuse = Colors::bg; - Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[2].Get(), state, Screen::flatColorMaterial); - } -} + Graphics::IndexBuffer *CreateIndexBuffer(const Uint32 indices[], const Uint32 IndexStart, const Uint32 IndexEnd, const Uint32 NumIndices) + { + Graphics::IndexBuffer *ib = Screen::GetRenderer()->CreateIndexBuffer(NumIndices, Graphics::BUFFER_USAGE_STATIC); + Uint32 *idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); + for (Uint32 j = 0; j < NumIndices; j++) { + idxPtr[j] = indices[j + IndexStart]; + } + ib->Unmap(); -} + return ib; + } + + struct TIndentBuffers { + RefCountedPtr vb; + RefCountedPtr ib[3]; + }; + typedef std::map MapIndentBuffers; + static MapIndentBuffers s_indentBuffers; + void DrawIndent(const float size[2], Graphics::RenderState *state) + { + PROFILE_SCOPED() + + // locals + RefCountedPtr vb; + RefCountedPtr ib[3]; + + // see if we have this size of indent in the cache already + const vector2f vsize(size[0], size[1]); + MapIndentBuffers::iterator bufIt = s_indentBuffers.find(vsize); + if (bufIt != s_indentBuffers.end()) { + // found it + vb = bufIt->second.vb; + ib[0] = bufIt->second.ib[0]; + ib[1] = bufIt->second.ib[1]; + ib[2] = bufIt->second.ib[2]; + } else { + // generate it + const vector3f vertices[] = { + /* 0 */ vector3f(0, 0, 0), + /* 1 */ vector3f(0, size[1], 0), + /* 2 */ vector3f(size[0], size[1], 0), + /* 3 */ vector3f(size[0], 0, 0), + /* 4 */ vector3f(BORDER_WIDTH, BORDER_WIDTH, 0), + /* 5 */ vector3f(BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 6 */ vector3f(size[0] - BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 7 */ vector3f(size[0] - BORDER_WIDTH, BORDER_WIDTH, 0) + }; + const Uint32 indices[] = { + 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3, + 3, 7, 6, 3, 6, 2, 1, 2, 6, 1, 6, 5, + 4, 5, 6, 4, 6, 7 + }; + + // create buffer + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = 8; + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + // Upload data + vb.Reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); + TPos *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(TPos)); + for (Uint32 i = 0; i < 8; i++) { + vtxPtr[i].pos = vertices[i]; + } + vb->Unmap(); + + // indices + Uint32 IndexStart = 0; + Uint32 IndexEnd = 12; + Uint32 NumIndices = 12; + + ib[0].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + IndexStart += NumIndices; + NumIndices = 12; + IndexEnd += NumIndices; + + ib[1].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + IndexStart += NumIndices; + NumIndices = 6; + IndexEnd += NumIndices; + + ib[2].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + TIndentBuffers tib; + tib.vb = vb; + tib.ib[0] = ib[0]; + tib.ib[1] = ib[1]; + tib.ib[2] = ib[2]; + s_indentBuffers[vsize] = tib; + } + + // Draw it! + Screen::flatColorMaterial->diffuse = Colors::bgShadow; + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[0].Get(), state, Screen::flatColorMaterial); + Screen::flatColorMaterial->diffuse = Color(153, 153, 153, 255); + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[1].Get(), state, Screen::flatColorMaterial); + Screen::flatColorMaterial->diffuse = Colors::bg; + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[2].Get(), state, Screen::flatColorMaterial); + } + + struct TOutdentBuffers { + RefCountedPtr vb; + RefCountedPtr ib[3]; + }; + typedef std::map MapOutdentBuffers; + static MapOutdentBuffers s_outdentBuffers; + void DrawOutdent(const float size[2], Graphics::RenderState *state) + { + PROFILE_SCOPED() + + // locals + RefCountedPtr vb; + RefCountedPtr ib[3]; + + // see if we have this size of indent in the cache already + const vector2f vsize(size[0], size[1]); + MapOutdentBuffers::iterator bufIt = s_outdentBuffers.find(vsize); + if (bufIt != s_outdentBuffers.end()) { + // found it + vb = bufIt->second.vb; + ib[0] = bufIt->second.ib[0]; + ib[1] = bufIt->second.ib[1]; + ib[2] = bufIt->second.ib[2]; + } else { + // generate it + const vector3f vertices[] = { + /* 0 */ vector3f(0, 0, 0), + /* 1 */ vector3f(0, size[1], 0), + /* 2 */ vector3f(size[0], size[1], 0), + /* 3 */ vector3f(size[0], 0, 0), + /* 4 */ vector3f(BORDER_WIDTH, BORDER_WIDTH, 0), + /* 5 */ vector3f(BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 6 */ vector3f(size[0] - BORDER_WIDTH, size[1] - BORDER_WIDTH, 0), + /* 7 */ vector3f(size[0] - BORDER_WIDTH, BORDER_WIDTH, 0) + }; + const Uint32 indices[] = { + 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3, + 3, 7, 6, 3, 6, 2, 1, 2, 6, 1, 6, 5, + 4, 5, 6, 4, 6, 7 + }; + + // create buffer + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = 8; + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + // Upload data + vb.Reset(Screen::GetRenderer()->CreateVertexBuffer(vbd)); + TPos *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + assert(vb->GetDesc().stride == sizeof(TPos)); + for (Uint32 i = 0; i < 8; i++) { + vtxPtr[i].pos = vertices[i]; + } + vb->Unmap(); + + // indices + Uint32 IndexStart = 0; + Uint32 IndexEnd = 12; + Uint32 NumIndices = 12; + + ib[0].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + IndexStart += NumIndices; + NumIndices = 12; + IndexEnd += NumIndices; + + ib[1].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + IndexStart += NumIndices; + NumIndices = 6; + IndexEnd += NumIndices; + + ib[2].Reset(CreateIndexBuffer(indices, IndexStart, IndexEnd, NumIndices)); + + TOutdentBuffers tib; + tib.vb = vb; + tib.ib[0] = ib[0]; + tib.ib[1] = ib[1]; + tib.ib[2] = ib[2]; + s_outdentBuffers[vsize] = tib; + } + + // Draw it! + Screen::flatColorMaterial->diffuse = Color(153, 153, 153, 255); + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[0].Get(), state, Screen::flatColorMaterial); + Screen::flatColorMaterial->diffuse = Colors::bgShadow; + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[1].Get(), state, Screen::flatColorMaterial); + Screen::flatColorMaterial->diffuse = Colors::bg; + Screen::GetRenderer()->DrawBufferIndexed(vb.Get(), ib[2].Get(), state, Screen::flatColorMaterial); + } + } // namespace Theme + +} // namespace Gui diff --git a/src/gui/Gui.h b/src/gui/Gui.h index 6e65cc87a..22fb00956 100644 --- a/src/gui/Gui.h +++ b/src/gui/Gui.h @@ -4,35 +4,34 @@ #ifndef _GUI_H #define _GUI_H -#include "libs.h" #include "Color.h" +#include "libs.h" namespace Graphics { class Renderer; class VertexBuffer; class RenderState; -} +} // namespace Graphics namespace Gui { namespace Theme { - void DrawIndent(const float size[2], Graphics::RenderState*); - void DrawOutdent(const float size[2], Graphics::RenderState*); - void DrawHollowRect(const float size[2], const Color&, Graphics::RenderState*); + void DrawIndent(const float size[2], Graphics::RenderState *); + void DrawOutdent(const float size[2], Graphics::RenderState *); + void DrawHollowRect(const float size[2], const Color &, Graphics::RenderState *); namespace Colors { extern const Color bg; extern const Color bgShadow; extern const Color tableHeading; - } - } - + } // namespace Colors + } // namespace Theme void HandleSDLEvent(SDL_Event *event); void Draw(); sigc::connection AddTimer(Uint32 ms, sigc::slot slot); void Init(Graphics::Renderer *renderer, int screen_width, int screen_height, int ui_width, int ui_height); void Uninit(); -} +} // namespace Gui #include "GuiEvents.h" @@ -47,33 +46,33 @@ namespace Gui { extern sigc::signal onJoyButtonDown; extern sigc::signal onJoyButtonUp; extern sigc::signal onJoyHatMotion; - } -} + } // namespace RawEvents +} // namespace Gui -#include "GuiWidget.h" #include "GuiAdjustment.h" -#include "GuiImage.h" -#include "GuiButton.h" -#include "GuiToggleButton.h" -#include "GuiMultiStateImageButton.h" -#include "GuiImageButton.h" -#include "GuiISelectable.h" -#include "GuiRadioButton.h" -#include "GuiImageRadioButton.h" -#include "GuiRadioGroup.h" #include "GuiBox.h" +#include "GuiButton.h" #include "GuiFixed.h" -#include "GuiVScrollPortal.h" -#include "GuiVScrollBar.h" -#include "GuiTextLayout.h" +#include "GuiISelectable.h" +#include "GuiImage.h" +#include "GuiImageButton.h" +#include "GuiImageRadioButton.h" #include "GuiLabel.h" -#include "GuiToolTip.h" -#include "GuiTabbed.h" -#include "GuiTextEntry.h" -#include "GuiMeterBar.h" #include "GuiLabelSet.h" +#include "GuiMeterBar.h" +#include "GuiMultiStateImageButton.h" +#include "GuiRadioButton.h" +#include "GuiRadioGroup.h" #include "GuiScreen.h" #include "GuiStack.h" +#include "GuiTabbed.h" +#include "GuiTextEntry.h" +#include "GuiTextLayout.h" #include "GuiTexturedQuad.h" +#include "GuiToggleButton.h" +#include "GuiToolTip.h" +#include "GuiVScrollBar.h" +#include "GuiVScrollPortal.h" +#include "GuiWidget.h" #endif /* _GUI_H */ diff --git a/src/gui/GuiAdjustment.h b/src/gui/GuiAdjustment.h index 60339fa12..5d1a57831 100644 --- a/src/gui/GuiAdjustment.h +++ b/src/gui/GuiAdjustment.h @@ -7,17 +7,20 @@ /* for scrollbars to fiddle with */ namespace Gui { class Adjustment { - public: - Adjustment(): m_value(0) {} - float GetValue() { return m_value; } - void SetValue(float v) { - m_value = (v>0?(v<1?v:1):0); - onValueChanged.emit(); - } - sigc::signal onValueChanged; - private: - float m_value; + public: + Adjustment() : + m_value(0) {} + float GetValue() { return m_value; } + void SetValue(float v) + { + m_value = (v > 0 ? (v < 1 ? v : 1) : 0); + onValueChanged.emit(); + } + sigc::signal onValueChanged; + + private: + float m_value; }; -} +} // namespace Gui #endif /* _GUIADJUSTMENT_H */ diff --git a/src/gui/GuiBox.cpp b/src/gui/GuiBox.cpp index c0b176bf3..44825326b 100644 --- a/src/gui/GuiBox.cpp +++ b/src/gui/GuiBox.cpp @@ -1,172 +1,172 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt - -#include "libs.h" #include "Gui.h" +#include "libs.h" namespace Gui { -Box::Box(BoxOrientation orient): Container() -{ - m_orient = orient; - _Init(); -} - -void Box::_Init() -{ - m_spacing = 0; - m_wantedSize[0] = m_wantedSize[1] = 0; - m_eventMask = EVENT_ALL; -} - -void Box::SetSizeRequest(float x, float y) -{ - m_wantedSize[0] = x; - m_wantedSize[1] = y; -} - -void Box::SetSizeRequest(float size[2]) -{ - SetSizeRequest(size[0], size[1]); -} - -void Box::GetSizeRequestedOrMinimum(float size[2], bool minimum) -{ - if (m_wantedSize[0] > 0.0f && m_wantedSize[1] > 0.0f) { - size[0] = m_wantedSize[0]; - size[1] = m_wantedSize[1]; - } else { - int num_kids = 0; - float want[2]; - want[0] = want[1] = 0; - // see how big we need to be - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - if (!(*i).w->IsVisible()) continue; - num_kids++; - float rsize[2]; - rsize[0] = size[0]; - rsize[1] = size[1]; - if (!minimum) - (*i).w->GetSizeRequested(rsize); - else - (*i).w->GetMinimumSize(rsize); - if (m_orient == BOX_VERTICAL) { - want[0] = std::max(want[0], rsize[0]); - want[1] += rsize[1]; - } else { - want[0] += rsize[0]; - want[1] = std::max(want[1], rsize[1]); - } - } - if (num_kids) want[m_orient] += (num_kids-1)*m_spacing; - size[0] = want[0]; - size[1] = want[1]; + Box::Box(BoxOrientation orient) : + Container() + { + m_orient = orient; + _Init(); } -} -Box::~Box() -{ - Screen::RemoveBaseWidget(this); -} + void Box::_Init() + { + m_spacing = 0; + m_wantedSize[0] = m_wantedSize[1] = 0; + m_eventMask = EVENT_ALL; + } -void Box::OnChildResizeRequest(Widget *child) -{ - UpdateAllChildSizes(); -} + void Box::SetSizeRequest(float x, float y) + { + m_wantedSize[0] = x; + m_wantedSize[1] = y; + } -void Box::PackStart(Widget *child) -{ - PrependChild(child, 0, 0); - ResizeRequest(); -} + void Box::SetSizeRequest(float size[2]) + { + SetSizeRequest(size[0], size[1]); + } -void Box::PackEnd(Widget *child) -{ - AppendChild(child, 0, 0); - ResizeRequest(); -} - -void Box::UpdateAllChildSizes() -{ - float size[2]; - GetSize(size); - float pos = 0; - float space = (m_orient == BOX_VERTICAL ? size[1] : size[0]); - int num_expand_children = 0; - // look at all children... - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - float msize[2], bsize[2]; - - if (m_orient == BOX_VERTICAL) { - msize[0] = bsize[0] = size[0]; - msize[1] = bsize[1] = space; - (*i).w->GetMinimumSize(msize); - (*i).w->GetSizeRequested(bsize); - - (*i).flags = (msize[1] < bsize[1]) ? 1 : 0; - - if (msize[0] > size[0]) msize[0] = size[0]; - if (msize[1] > space) msize[1] = space; - (*i).w->SetSize(size[0], msize[1]); - (*i).pos[0] = 0; - (*i).pos[1] = pos; - pos += msize[1] + m_spacing; - space -= msize[1] + m_spacing; + void Box::GetSizeRequestedOrMinimum(float size[2], bool minimum) + { + if (m_wantedSize[0] > 0.0f && m_wantedSize[1] > 0.0f) { + size[0] = m_wantedSize[0]; + size[1] = m_wantedSize[1]; } else { - msize[0] = bsize[0] = size[0]; - msize[1] = bsize[1] = space; - (*i).w->GetMinimumSize(msize); - (*i).w->GetSizeRequested(bsize); - - (*i).flags = (msize[0] < bsize[0]) ? 1 : 0; - - if (msize[0] > space) msize[0] = space; - if (msize[1] > size[1]) msize[1] = size[1]; - (*i).w->SetSize(msize[0], size[1]); - (*i).pos[0] = pos; - (*i).pos[1] = 0; - pos += msize[0] + m_spacing; - space -= msize[0] + m_spacing; + int num_kids = 0; + float want[2]; + want[0] = want[1] = 0; + // see how big we need to be + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + if (!(*i).w->IsVisible()) continue; + num_kids++; + float rsize[2]; + rsize[0] = size[0]; + rsize[1] = size[1]; + if (!minimum) + (*i).w->GetSizeRequested(rsize); + else + (*i).w->GetMinimumSize(rsize); + if (m_orient == BOX_VERTICAL) { + want[0] = std::max(want[0], rsize[0]); + want[1] += rsize[1]; + } else { + want[0] += rsize[0]; + want[1] = std::max(want[1], rsize[1]); + } + } + if (num_kids) want[m_orient] += (num_kids - 1) * m_spacing; + size[0] = want[0]; + size[1] = want[1]; } - - if ((*i).flags) num_expand_children++; } - // last item does not need spacing after it... - space += m_spacing; - pos = 0; - if ((space > 0) && num_expand_children) { - /* give expand children the space space */ + + Box::~Box() + { + Screen::RemoveBaseWidget(this); + } + + void Box::OnChildResizeRequest(Widget *child) + { + UpdateAllChildSizes(); + } + + void Box::PackStart(Widget *child) + { + PrependChild(child, 0, 0); + ResizeRequest(); + } + + void Box::PackEnd(Widget *child) + { + AppendChild(child, 0, 0); + ResizeRequest(); + } + + void Box::UpdateAllChildSizes() + { + float size[2]; + GetSize(size); + float pos = 0; + float space = (m_orient == BOX_VERTICAL ? size[1] : size[0]); + int num_expand_children = 0; + // look at all children... for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - bool expand = (*i).flags != 0; - float s[2]; - (*i).w->GetSize(s); + float msize[2], bsize[2]; if (m_orient == BOX_VERTICAL) { + msize[0] = bsize[0] = size[0]; + msize[1] = bsize[1] = space; + (*i).w->GetMinimumSize(msize); + (*i).w->GetSizeRequested(bsize); + + (*i).flags = (msize[1] < bsize[1]) ? 1 : 0; + + if (msize[0] > size[0]) msize[0] = size[0]; + if (msize[1] > space) msize[1] = space; + (*i).w->SetSize(size[0], msize[1]); (*i).pos[0] = 0; (*i).pos[1] = pos; - if (expand) { - s[1] += space / num_expand_children; - (*i).w->SetSize(s[0], s[1]); - } - pos += s[1] + m_spacing; + pos += msize[1] + m_spacing; + space -= msize[1] + m_spacing; } else { + msize[0] = bsize[0] = size[0]; + msize[1] = bsize[1] = space; + (*i).w->GetMinimumSize(msize); + (*i).w->GetSizeRequested(bsize); + + (*i).flags = (msize[0] < bsize[0]) ? 1 : 0; + + if (msize[0] > space) msize[0] = space; + if (msize[1] > size[1]) msize[1] = size[1]; + (*i).w->SetSize(msize[0], size[1]); (*i).pos[0] = pos; (*i).pos[1] = 0; - if (expand) { - s[0] += space / num_expand_children; - (*i).w->SetSize(s[0], s[1]); + pos += msize[0] + m_spacing; + space -= msize[0] + m_spacing; + } + + if ((*i).flags) num_expand_children++; + } + // last item does not need spacing after it... + space += m_spacing; + pos = 0; + if ((space > 0) && num_expand_children) { + /* give expand children the space space */ + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + bool expand = (*i).flags != 0; + float s[2]; + (*i).w->GetSize(s); + + if (m_orient == BOX_VERTICAL) { + (*i).pos[0] = 0; + (*i).pos[1] = pos; + if (expand) { + s[1] += space / num_expand_children; + (*i).w->SetSize(s[0], s[1]); + } + pos += s[1] + m_spacing; + } else { + (*i).pos[0] = pos; + (*i).pos[1] = 0; + if (expand) { + s[0] += space / num_expand_children; + (*i).w->SetSize(s[0], s[1]); + } + pos += s[0] + m_spacing; } - pos += s[0] + m_spacing; } } } -} -void Box::Remove(Widget *child) -{ - Container::RemoveChild(child); - ResizeRequest(); -} + void Box::Remove(Widget *child) + { + Container::RemoveChild(child); + ResizeRequest(); + } -} +} // namespace Gui diff --git a/src/gui/GuiBox.h b/src/gui/GuiBox.h index a7246e4b5..1cfbcc873 100644 --- a/src/gui/GuiBox.h +++ b/src/gui/GuiBox.h @@ -7,8 +7,8 @@ * Box oriented packing widget container. */ -#include "GuiWidget.h" #include "GuiContainer.h" +#include "GuiWidget.h" namespace Gui { enum BoxOrientation { @@ -16,7 +16,7 @@ namespace Gui { BOX_VERTICAL = 1 }; - class Box: public Container { + class Box : public Container { public: Box(BoxOrientation orient); void PackStart(Widget *child); @@ -30,6 +30,7 @@ namespace Gui { void SetSizeRequest(float size[2]); void SetSizeRequest(float x, float y); void SetSpacing(float spacing) { m_spacing = spacing; } + private: void _Init(); void GetSizeRequestedOrMinimum(float size[2], bool minimum); @@ -38,16 +39,17 @@ namespace Gui { enum BoxOrientation m_orient; }; - class VBox: public Box { + class VBox : public Box { public: - VBox(): Box(BOX_VERTICAL) {} + VBox() : + Box(BOX_VERTICAL) {} }; - class HBox: public Box { + class HBox : public Box { public: - HBox(): Box(BOX_HORIZONTAL) {} + HBox() : + Box(BOX_HORIZONTAL) {} }; -} +} // namespace Gui #endif /* _GUIBOX_H */ - diff --git a/src/gui/GuiButton.cpp b/src/gui/GuiButton.cpp index eb24424b6..54b68c9bd 100644 --- a/src/gui/GuiButton.cpp +++ b/src/gui/GuiButton.cpp @@ -1,144 +1,145 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" static const float BUTTON_SIZE = 16.f; namespace Gui { -Button::Button() -{ - m_isPressed = false; - m_eventMask = EVENT_MOUSEDOWN | EVENT_MOUSEUP | EVENT_MOUSEMOTION; - SetSize(BUTTON_SIZE, BUTTON_SIZE); -} - -Button::~Button() -{ - _m_release.disconnect(); - _m_kbrelease.disconnect(); -} - -bool Button::OnMouseDown(MouseButtonEvent *e) -{ - if (e->button == SDL_BUTTON_LEFT) { - m_isPressed = true; - onPress.emit(); - // wait for mouse release, regardless of where on screen - _m_release = RawEvents::onMouseUp.connect(sigc::mem_fun(this, &Button::OnRawMouseUp)); - } - return false; -} - -bool Button::OnMouseUp(MouseButtonEvent *e) -{ - if ((e->button == SDL_BUTTON_LEFT) && m_isPressed) { + Button::Button() + { m_isPressed = false; + m_eventMask = EVENT_MOUSEDOWN | EVENT_MOUSEUP | EVENT_MOUSEMOTION; + SetSize(BUTTON_SIZE, BUTTON_SIZE); + } + + Button::~Button() + { _m_release.disconnect(); - onRelease.emit(); - onClick.emit(); - } - return false; -} - -void Button::OnActivate() -{ - // activated by keyboard shortcut - m_isPressed = true; - _m_kbrelease = RawEvents::onKeyUp.connect(sigc::mem_fun(this, &Button::OnRawKeyUp)); - onPress.emit(); -} - -void Button::OnRawKeyUp(SDL_KeyboardEvent *e) -{ - if (e->keysym.sym == m_shortcut.sym) { - m_isPressed = false; _m_kbrelease.disconnect(); - onRelease.emit(); - onClick.emit(); - } -} - -void Button::OnRawMouseUp(MouseButtonEvent *e) -{ - if (e->button == SDL_BUTTON_LEFT) { - m_isPressed = false; - _m_release.disconnect(); - onRelease.emit(); - } -} - -void SolidButton::GetSizeRequested(float size[2]) -{ - size[0] = size[1] = BUTTON_SIZE; -} - -void TransparentButton::GetSizeRequested(float size[2]) -{ - size[0] = size[1] = BUTTON_SIZE; -} - -void SolidButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - if (IsPressed()) { - Theme::DrawIndent(size, Screen::alphaBlendState); - } else { - Theme::DrawOutdent(size, Screen::alphaBlendState); - } -} -void TransparentButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - Theme::DrawHollowRect(size, Color::WHITE, Screen::alphaBlendState); -} - -LabelButton::LabelButton(Label *label): Button() -{ - m_label = label; - m_padding = 2.0; - onSetSize.connect(sigc::mem_fun(this, &LabelButton::OnSetSize)); -} - -LabelButton::~LabelButton() { delete m_label; } - -void LabelButton::GetSizeRequested(float size[2]) -{ - m_label->GetSizeRequested(size); - size[0] += 2*m_padding; - //size[1] += 2*m_padding; -} - -void LabelButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - - if (IsPressed()) { - Theme::DrawIndent(size, Screen::alphaBlendState); - } else { - Theme::DrawOutdent(size, Screen::alphaBlendState); } - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + bool Button::OnMouseDown(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + m_isPressed = true; + onPress.emit(); + // wait for mouse release, regardless of where on screen + _m_release = RawEvents::onMouseUp.connect(sigc::mem_fun(this, &Button::OnRawMouseUp)); + } + return false; + } - r->Translate(m_padding, m_padding*0.5, 0); - m_label->Draw(); -} + bool Button::OnMouseUp(MouseButtonEvent *e) + { + if ((e->button == SDL_BUTTON_LEFT) && m_isPressed) { + m_isPressed = false; + _m_release.disconnect(); + onRelease.emit(); + onClick.emit(); + } + return false; + } -void LabelButton::OnSetSize() -{ - float size[2]; - GetSize(size); + void Button::OnActivate() + { + // activated by keyboard shortcut + m_isPressed = true; + _m_kbrelease = RawEvents::onKeyUp.connect(sigc::mem_fun(this, &Button::OnRawKeyUp)); + onPress.emit(); + } - m_label->SetSize(size[0]-2*m_padding, size[1]); -} + void Button::OnRawKeyUp(SDL_KeyboardEvent *e) + { + if (e->keysym.sym == m_shortcut.sym) { + m_isPressed = false; + _m_kbrelease.disconnect(); + onRelease.emit(); + onClick.emit(); + } + } -} + void Button::OnRawMouseUp(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + m_isPressed = false; + _m_release.disconnect(); + onRelease.emit(); + } + } + + void SolidButton::GetSizeRequested(float size[2]) + { + size[0] = size[1] = BUTTON_SIZE; + } + + void TransparentButton::GetSizeRequested(float size[2]) + { + size[0] = size[1] = BUTTON_SIZE; + } + + void SolidButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + if (IsPressed()) { + Theme::DrawIndent(size, Screen::alphaBlendState); + } else { + Theme::DrawOutdent(size, Screen::alphaBlendState); + } + } + void TransparentButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + Theme::DrawHollowRect(size, Color::WHITE, Screen::alphaBlendState); + } + + LabelButton::LabelButton(Label *label) : + Button() + { + m_label = label; + m_padding = 2.0; + onSetSize.connect(sigc::mem_fun(this, &LabelButton::OnSetSize)); + } + + LabelButton::~LabelButton() { delete m_label; } + + void LabelButton::GetSizeRequested(float size[2]) + { + m_label->GetSizeRequested(size); + size[0] += 2 * m_padding; + //size[1] += 2*m_padding; + } + + void LabelButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + + if (IsPressed()) { + Theme::DrawIndent(size, Screen::alphaBlendState); + } else { + Theme::DrawOutdent(size, Screen::alphaBlendState); + } + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + r->Translate(m_padding, m_padding * 0.5, 0); + m_label->Draw(); + } + + void LabelButton::OnSetSize() + { + float size[2]; + GetSize(size); + + m_label->SetSize(size[0] - 2 * m_padding, size[1]); + } + +} // namespace Gui diff --git a/src/gui/GuiButton.h b/src/gui/GuiButton.h index b7e75e924..4534e88e3 100644 --- a/src/gui/GuiButton.h +++ b/src/gui/GuiButton.h @@ -10,7 +10,7 @@ namespace Gui { class Label; - class Button: public Widget { + class Button : public Widget { public: Button(); virtual ~Button(); @@ -23,6 +23,7 @@ namespace Gui { sigc::signal onRelease; sigc::signal onClick; bool IsPressed() { return m_isPressed; } + private: void OnRawMouseUp(MouseButtonEvent *e); void OnRawKeyUp(SDL_KeyboardEvent *e); @@ -32,35 +33,39 @@ namespace Gui { sigc::connection _m_kbrelease; }; - class SolidButton: public Button { + class SolidButton : public Button { public: - SolidButton(): Button() {} + SolidButton() : + Button() {} virtual ~SolidButton() {} virtual void GetSizeRequested(float size[2]); virtual void Draw(); }; - class TransparentButton: public Button { + class TransparentButton : public Button { public: - TransparentButton(): Button() {} + TransparentButton() : + Button() {} virtual ~TransparentButton() {} virtual void GetSizeRequested(float size[2]); virtual void Draw(); }; - class LabelButton: public Button { + class LabelButton : public Button { public: LabelButton(Label *label); virtual ~LabelButton(); virtual void GetSizeRequested(float size[2]); virtual void Draw(); void SetPadding(float p) { m_padding = p; } + protected: Label *m_label; + private: void OnSetSize(); float m_padding; }; -} +} // namespace Gui #endif /* _GUIBUTTON_H */ diff --git a/src/gui/GuiContainer.cpp b/src/gui/GuiContainer.cpp index 39b397e1d..e1ed4b71e 100644 --- a/src/gui/GuiContainer.cpp +++ b/src/gui/GuiContainer.cpp @@ -1,281 +1,283 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Gui.h" #include "GuiContainer.h" +#include "Gui.h" #include namespace Gui { -Container::Container() -{ - m_transparent = true; - SetBgColor(Theme::Colors::bg); - onMouseLeave.connect(sigc::mem_fun(this, &Container::_OnMouseLeave)); - onSetSize.connect(sigc::mem_fun(this, &Container::_OnSetSize)); -} - -Container::~Container() -{ - DeleteAllChildren(); -} - -void Container::_OnSetSize() -{ - if (IsVisible()) UpdateAllChildSizes(); -} - -void Container::_OnMouseLeave() -{ - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - if ((*i).w->IsMouseOver() == true) - (*i).w->OnMouseLeave(); + Container::Container() + { + m_transparent = true; + SetBgColor(Theme::Colors::bg); + onMouseLeave.connect(sigc::mem_fun(this, &Container::_OnMouseLeave)); + onSetSize.connect(sigc::mem_fun(this, &Container::_OnSetSize)); } -} -bool Container::OnMouseMotion(MouseMotionEvent *e) -{ - float x = e->x; - float y = e->y; - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - float *pos,size[2]; - if (!(*i).w->IsVisible()) { + Container::~Container() + { + DeleteAllChildren(); + } + + void Container::_OnSetSize() + { + if (IsVisible()) UpdateAllChildSizes(); + } + + void Container::_OnMouseLeave() + { + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { if ((*i).w->IsMouseOver() == true) (*i).w->OnMouseLeave(); - continue; } - int evmask = (*i).w->GetEventMask(); - if (!(evmask & Widget::EVENT_MOUSEMOTION)) continue; + } - pos = (*i).pos; - (*i).w->GetSize(size); - - if ((x >= pos[0]) && (x < pos[0]+size[0]) && - (y >= pos[1]) && (y < pos[1]+size[1])) { - e->x = x-pos[0]; - e->y = y-pos[1]; - if ((*i).w->IsMouseOver() == false) { - (*i).w->OnMouseEnter(); + bool Container::OnMouseMotion(MouseMotionEvent *e) + { + float x = e->x; + float y = e->y; + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + float *pos, size[2]; + if (!(*i).w->IsVisible()) { + if ((*i).w->IsMouseOver() == true) + (*i).w->OnMouseLeave(); + continue; } - bool alive = (*i).w->OnMouseMotion(e); - if (!alive) return false; - } else { - if ((*i).w->IsMouseOver() == true) - (*i).w->OnMouseLeave(); - } - } - return true; -} + int evmask = (*i).w->GetEventMask(); + if (!(evmask & Widget::EVENT_MOUSEMOTION)) continue; -bool Container::HandleMouseEvent(MouseButtonEvent *e) -{ - float x = e->x; - float y = e->y; - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - float *pos,size[2]; - if (!(*i).w->IsVisible()) continue; - if (!(*i).w->GetEnabled()) continue; - int evmask = (*i).w->GetEventMask(); - if (e->isdown) { - if (!(evmask & Widget::EVENT_MOUSEDOWN)) continue; - } else { - if (!(evmask & Widget::EVENT_MOUSEUP)) continue; - } - pos = (*i).pos; - (*i).w->GetSize(size); + pos = (*i).pos; + (*i).w->GetSize(size); - if ((x >= pos[0]) && (x < pos[0]+size[0]) && - (y >= pos[1]) && (y < pos[1]+size[1])) { - e->x = x-pos[0]; - e->y = y-pos[1]; - bool alive; - if (e->isdown) { - alive = (*i).w->OnMouseDown(e); + if ((x >= pos[0]) && (x < pos[0] + size[0]) && + (y >= pos[1]) && (y < pos[1] + size[1])) { + e->x = x - pos[0]; + e->y = y - pos[1]; + if ((*i).w->IsMouseOver() == false) { + (*i).w->OnMouseEnter(); + } + bool alive = (*i).w->OnMouseMotion(e); + if (!alive) return false; } else { - alive = (*i).w->OnMouseUp(e); + if ((*i).w->IsMouseOver() == true) + (*i).w->OnMouseLeave(); } - if (!alive) return false; + } + return true; + } + + bool Container::HandleMouseEvent(MouseButtonEvent *e) + { + float x = e->x; + float y = e->y; + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + float *pos, size[2]; + if (!(*i).w->IsVisible()) continue; + if (!(*i).w->GetEnabled()) continue; + int evmask = (*i).w->GetEventMask(); + if (e->isdown) { + if (!(evmask & Widget::EVENT_MOUSEDOWN)) continue; + } else { + if (!(evmask & Widget::EVENT_MOUSEUP)) continue; + } + pos = (*i).pos; + (*i).w->GetSize(size); + + if ((x >= pos[0]) && (x < pos[0] + size[0]) && + (y >= pos[1]) && (y < pos[1] + size[1])) { + e->x = x - pos[0]; + e->y = y - pos[1]; + bool alive; + if (e->isdown) { + alive = (*i).w->OnMouseDown(e); + } else { + alive = (*i).w->OnMouseUp(e); + } + if (!alive) return false; + } + } + onMouseButtonEvent.emit(e); + return true; + } + + void Container::DeleteAllChildren() + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + delete (*i).w; + } + m_children.clear(); + } + + void Container::RemoveAllChildren() + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + i->w->SetParent(0); + } + m_children.clear(); + } + + void Container::PrependChild(Widget *child, float x, float y) + { + PROFILE_SCOPED() + assert(child->GetParent() == 0); + assert(FindChild(child) == m_children.end()); + + widget_pos wp; + wp.w = child; + wp.pos[0] = x; + wp.pos[1] = y; + wp.flags = 0; + child->SetParent(this); + m_children.push_front(wp); + } + + void Container::AppendChild(Widget *child, float x, float y) + { + PROFILE_SCOPED() + assert(child->GetParent() == 0); + assert(FindChild(child) == m_children.end()); + + widget_pos wp; + wp.w = child; + wp.pos[0] = x; + wp.pos[1] = y; + wp.flags = 0; + child->SetParent(this); + m_children.push_back(wp); + } + + void Container::MoveChild(Widget *child, float x, float y) + { + PROFILE_SCOPED() + WidgetList::iterator it = FindChild(child); + if (it != m_children.end()) { + it->pos[0] = x; + it->pos[1] = y; } } - onMouseButtonEvent.emit(e); - return true; -} -void Container::DeleteAllChildren() -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - delete (*i).w; - } - m_children.clear(); -} - -void Container::RemoveAllChildren() -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - i->w->SetParent(0); - } - m_children.clear(); -} - -void Container::PrependChild(Widget *child, float x, float y) -{ - PROFILE_SCOPED() - assert(child->GetParent() == 0); - assert(FindChild(child) == m_children.end()); - - widget_pos wp; - wp.w = child; - wp.pos[0] = x; wp.pos[1] = y; - wp.flags = 0; - child->SetParent(this); - m_children.push_front(wp); -} - -void Container::AppendChild(Widget *child, float x, float y) -{ - PROFILE_SCOPED() - assert(child->GetParent() == 0); - assert(FindChild(child) == m_children.end()); - - widget_pos wp; - wp.w = child; - wp.pos[0] = x; wp.pos[1] = y; - wp.flags = 0; - child->SetParent(this); - m_children.push_back(wp); -} - -void Container::MoveChild(Widget *child, float x, float y) -{ - PROFILE_SCOPED() - WidgetList::iterator it = FindChild(child); - if (it != m_children.end()) { - it->pos[0] = x; - it->pos[1] = y; - } -} - -void Container::RemoveChild(Widget *child) -{ - PROFILE_SCOPED() - WidgetList::iterator it = FindChild(child); - if (it != m_children.end()) { - it->w->SetParent(0); - m_children.erase(it); - } -} - -Container::WidgetList::const_iterator Container::FindChild(const Widget *w) const -{ - PROFILE_SCOPED() - for (WidgetList::const_iterator i = m_children.begin(); i != m_children.end(); ++i) - if (i->w == w) return i; - return m_children.end(); -} - -Container::WidgetList::iterator Container::FindChild(const Widget *w) -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) - if (i->w == w) return i; - return m_children.end(); -} - -void Container::Draw() -{ - PROFILE_SCOPED() - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - r->SetRenderState(Gui::Screen::alphaBlendState); - - float size[2]; - GetSize(size); - if (!m_transparent) { - PROFILE_SCOPED_RAW("Container::Draw - !m_transparent") - if(!m_rect) { - m_rect.reset(new Graphics::Drawables::Rect(Screen::GetRenderer(),vector2f(0.f), vector2f(size[0], size[0]), m_bgcol, Screen::alphaBlendState, false)); - } else { - m_rect->Update(vector2f(0.f), vector2f(size[0], size[1]), m_bgcol); + void Container::RemoveChild(Widget *child) + { + PROFILE_SCOPED() + WidgetList::iterator it = FindChild(child); + if (it != m_children.end()) { + it->w->SetParent(0); + m_children.erase(it); } - m_rect->Draw(Screen::GetRenderer()); } - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - PROFILE_SCOPED_RAW("Container::Draw - Child Loop") - if (!(*i).w->IsVisible()) - continue; - - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); - r->Translate((*i).pos[0], (*i).pos[1], 0); - (*i).w->Draw(); + Container::WidgetList::const_iterator Container::FindChild(const Widget *w) const + { + PROFILE_SCOPED() + for (WidgetList::const_iterator i = m_children.begin(); i != m_children.end(); ++i) + if (i->w == w) return i; + return m_children.end(); } -} -bool Container::OnMouseDown(MouseButtonEvent *e) -{ - return HandleMouseEvent(e); -} - -bool Container::OnMouseUp(MouseButtonEvent *e) -{ - return HandleMouseEvent(e); -} - -void Container::ShowChildren() -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - (*i).w->Show(); + Container::WidgetList::iterator Container::FindChild(const Widget *w) + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) + if (i->w == w) return i; + return m_children.end(); } -} -void Container::HideChildren() -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - (*i).w->Hide(); + void Container::Draw() + { + PROFILE_SCOPED() + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + r->SetRenderState(Gui::Screen::alphaBlendState); + + float size[2]; + GetSize(size); + if (!m_transparent) { + PROFILE_SCOPED_RAW("Container::Draw - !m_transparent") + if (!m_rect) { + m_rect.reset(new Graphics::Drawables::Rect(Screen::GetRenderer(), vector2f(0.f), vector2f(size[0], size[0]), m_bgcol, Screen::alphaBlendState, false)); + } else { + m_rect->Update(vector2f(0.f), vector2f(size[0], size[1]), m_bgcol); + } + m_rect->Draw(Screen::GetRenderer()); + } + + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + PROFILE_SCOPED_RAW("Container::Draw - Child Loop") + if (!(*i).w->IsVisible()) + continue; + + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + r->Translate((*i).pos[0], (*i).pos[1], 0); + (*i).w->Draw(); + } } -} -void Container::GetChildPosition(const Widget *child, float outPos[2]) const -{ - WidgetList::const_iterator it = FindChild(child); - assert(it != m_children.end()); - outPos[0] = it->pos[0]; - outPos[1] = it->pos[1]; -} - -void Container::Show() -{ - PROFILE_SCOPED() - Widget::Show(); - if (IsVisible()) { - ResizeRequest(); + bool Container::OnMouseDown(MouseButtonEvent *e) + { + return HandleMouseEvent(e); } -} -void Container::ShowAll() -{ - PROFILE_SCOPED() - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - (*i).w->ShowAll(); + bool Container::OnMouseUp(MouseButtonEvent *e) + { + return HandleMouseEvent(e); } - Show(); -} -void Container::HideAll() -{ - PROFILE_SCOPED() - HideChildren(); - Hide(); -} + void Container::ShowChildren() + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + (*i).w->Show(); + } + } -void Container::SetBgColor(const Color &col) -{ - m_bgcol = col; -} + void Container::HideChildren() + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + (*i).w->Hide(); + } + } -} + void Container::GetChildPosition(const Widget *child, float outPos[2]) const + { + WidgetList::const_iterator it = FindChild(child); + assert(it != m_children.end()); + outPos[0] = it->pos[0]; + outPos[1] = it->pos[1]; + } + + void Container::Show() + { + PROFILE_SCOPED() + Widget::Show(); + if (IsVisible()) { + ResizeRequest(); + } + } + + void Container::ShowAll() + { + PROFILE_SCOPED() + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + (*i).w->ShowAll(); + } + Show(); + } + + void Container::HideAll() + { + PROFILE_SCOPED() + HideChildren(); + Hide(); + } + + void Container::SetBgColor(const Color &col) + { + m_bgcol = col; + } + +} // namespace Gui diff --git a/src/gui/GuiContainer.h b/src/gui/GuiContainer.h index 6c630fd13..84020ecbb 100644 --- a/src/gui/GuiContainer.h +++ b/src/gui/GuiContainer.h @@ -8,11 +8,12 @@ */ #include "GuiWidget.h" -#include +#include "graphics/Drawables.h" #include +#include namespace Gui { - class Container: public Widget { + class Container : public Widget { public: Container(); virtual ~Container(); @@ -35,7 +36,8 @@ namespace Gui { virtual void UpdateAllChildSizes() = 0; void RemoveChild(Widget *w); // only fired if child widgets do not eat event - sigc::signal onMouseButtonEvent; + sigc::signal onMouseButtonEvent; + private: void _OnMouseLeave(); void _OnSetSize(); @@ -43,6 +45,7 @@ namespace Gui { Color m_bgcol; bool m_transparent; std::unique_ptr m_rect; + protected: struct widget_pos { Widget *w; @@ -59,7 +62,6 @@ namespace Gui { WidgetList m_children; }; -} +} // namespace Gui #endif /* _GUICONTAINER_H */ - diff --git a/src/gui/GuiEvents.h b/src/gui/GuiEvents.h index 7fe1c19b4..8cbde9896 100644 --- a/src/gui/GuiEvents.h +++ b/src/gui/GuiEvents.h @@ -11,7 +11,7 @@ namespace Gui { float x, y; // widget coords float screenX, screenY; // screen coords enum { - BUTTON_WHEELUP = 0xfe, + BUTTON_WHEELUP = 0xfe, BUTTON_WHEELDOWN = 0xff }; }; @@ -19,6 +19,6 @@ namespace Gui { float x, y; // widget coords float screenX, screenY; // screen coords }; -} +} // namespace Gui #endif /* _GUIEVENTS_H */ diff --git a/src/gui/GuiFixed.cpp b/src/gui/GuiFixed.cpp index 0b748f0cd..5e861e70e 100644 --- a/src/gui/GuiFixed.cpp +++ b/src/gui/GuiFixed.cpp @@ -1,113 +1,115 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" namespace Gui { -Fixed::Fixed(): Container() -{ - _Init(); - SetSize(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight())); -} + Fixed::Fixed() : + Container() + { + _Init(); + SetSize(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight())); + } -Fixed::Fixed(float w, float h): Container() -{ - float s[2] = { w, h }; - _Init(); - SetSize(w, h); - SetSizeRequest(s); -} + Fixed::Fixed(float w, float h) : + Container() + { + float s[2] = { w, h }; + _Init(); + SetSize(w, h); + SetSizeRequest(s); + } -void Fixed::_Init() -{ - m_userWantedSize[0] = m_userWantedSize[1] = 0; - m_eventMask = EVENT_ALL; -} + void Fixed::_Init() + { + m_userWantedSize[0] = m_userWantedSize[1] = 0; + m_eventMask = EVENT_ALL; + } -void Fixed::SetSizeRequest(float x, float y) -{ - m_userWantedSize[0] = x; - m_userWantedSize[1] = y; -} + void Fixed::SetSizeRequest(float x, float y) + { + m_userWantedSize[0] = x; + m_userWantedSize[1] = y; + } -void Fixed::SetSizeRequest(float size[2]) -{ - SetSizeRequest(size[0], size[1]); -} + void Fixed::SetSizeRequest(float size[2]) + { + SetSizeRequest(size[0], size[1]); + } -void Fixed::GetSizeRequested(float size[2]) -{ - if (m_userWantedSize[0] > 0.0f && m_userWantedSize[1] > 0.0f) { - size[0] = m_userWantedSize[0]; - size[1] = m_userWantedSize[1]; - } else { - float wanted[2]; - wanted[0] = wanted[1] = 0; + void Fixed::GetSizeRequested(float size[2]) + { + if (m_userWantedSize[0] > 0.0f && m_userWantedSize[1] > 0.0f) { + size[0] = m_userWantedSize[0]; + size[1] = m_userWantedSize[1]; + } else { + float wanted[2]; + wanted[0] = wanted[1] = 0; + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + float rsize[2] = { size[0] - (*i).pos[0], + size[1] - (*i).pos[1] }; + (*i).w->GetSizeRequested(rsize); + if ((*i).pos[0] + rsize[0] > size[0]) rsize[0] = size[0] - (*i).pos[0]; + if ((*i).pos[1] + rsize[1] > size[1]) rsize[1] = size[1] - (*i).pos[1]; + wanted[0] = std::max(wanted[0], rsize[0] + (*i).pos[0]); + wanted[1] = std::max(wanted[1], rsize[1] + (*i).pos[1]); + } + size[0] = wanted[0]; + size[1] = wanted[1]; + } + } + + Fixed::~Fixed() + { + } + + void Fixed::UpdateAllChildSizes() + { + float size[2]; + GetSize(size); for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { float rsize[2] = { size[0] - (*i).pos[0], - size[1] - (*i).pos[1] }; + size[1] - (*i).pos[1] }; (*i).w->GetSizeRequested(rsize); if ((*i).pos[0] + rsize[0] > size[0]) rsize[0] = size[0] - (*i).pos[0]; if ((*i).pos[1] + rsize[1] > size[1]) rsize[1] = size[1] - (*i).pos[1]; - wanted[0] = std::max(wanted[0], rsize[0] + (*i).pos[0]); - wanted[1] = std::max(wanted[1], rsize[1] + (*i).pos[1]); - } - size[0] = wanted[0]; - size[1] = wanted[1]; - } -} - -Fixed::~Fixed() -{ -} - -void Fixed::UpdateAllChildSizes() -{ - float size[2]; - GetSize(size); - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - float rsize[2] = { size[0] - (*i).pos[0], - size[1] - (*i).pos[1] }; - (*i).w->GetSizeRequested(rsize); - if ((*i).pos[0] + rsize[0] > size[0]) rsize[0] = size[0] - (*i).pos[0]; - if ((*i).pos[1] + rsize[1] > size[1]) rsize[1] = size[1] - (*i).pos[1]; - (*i).w->SetSize(rsize[0], rsize[1]); - } -} - -void Fixed::OnChildResizeRequest(Widget *child) -{ - float size[2]; - GetSize(size); - for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { - if ((*i).w == child) { - float rsize[2] = { size[0] - (*i).pos[0], - size[1] - (*i).pos[1] }; - (*i).w->GetSizeRequested(rsize); - if ((*i).pos[0] + rsize[0] > size[0]) rsize[0] = size[0] - (*i).pos[0]; - if ((*i).pos[1] + rsize[1] > size[1]) rsize[1] = size[0] - (*i).pos[1]; - child->SetSize(rsize[0], rsize[1]); + (*i).w->SetSize(rsize[0], rsize[1]); } } -} -void Fixed::Add(Widget *child, float x, float y) -{ - float size[2]; - GetSize(size); - AppendChild(child, x, y); - float rsize[2] = { size[0] - x, size[1] - y }; - child->GetSizeRequested(rsize); - if (x+rsize[0] > size[0]) rsize[0] = size[0]-x; - if (y+rsize[1] > size[1]) rsize[1] = size[1]-y; - child->SetSize(rsize[0], rsize[1]); -} + void Fixed::OnChildResizeRequest(Widget *child) + { + float size[2]; + GetSize(size); + for (WidgetList::iterator i = m_children.begin(), itEnd = m_children.end(); i != itEnd; ++i) { + if ((*i).w == child) { + float rsize[2] = { size[0] - (*i).pos[0], + size[1] - (*i).pos[1] }; + (*i).w->GetSizeRequested(rsize); + if ((*i).pos[0] + rsize[0] > size[0]) rsize[0] = size[0] - (*i).pos[0]; + if ((*i).pos[1] + rsize[1] > size[1]) rsize[1] = size[0] - (*i).pos[1]; + child->SetSize(rsize[0], rsize[1]); + } + } + } -void Fixed::Remove(Widget *child) -{ - Container::RemoveChild(child); -} + void Fixed::Add(Widget *child, float x, float y) + { + float size[2]; + GetSize(size); + AppendChild(child, x, y); + float rsize[2] = { size[0] - x, size[1] - y }; + child->GetSizeRequested(rsize); + if (x + rsize[0] > size[0]) rsize[0] = size[0] - x; + if (y + rsize[1] > size[1]) rsize[1] = size[1] - y; + child->SetSize(rsize[0], rsize[1]); + } -} + void Fixed::Remove(Widget *child) + { + Container::RemoveChild(child); + } + +} // namespace Gui diff --git a/src/gui/GuiFixed.h b/src/gui/GuiFixed.h index ad889de59..1fb68a14b 100644 --- a/src/gui/GuiFixed.h +++ b/src/gui/GuiFixed.h @@ -7,11 +7,11 @@ * Fixed position widget container. */ -#include "GuiWidget.h" #include "GuiContainer.h" +#include "GuiWidget.h" namespace Gui { - class Fixed: public Container { + class Fixed : public Container { public: Fixed(float w, float h); Fixed(); @@ -23,11 +23,11 @@ namespace Gui { virtual void UpdateAllChildSizes(); void SetSizeRequest(float x, float y); void SetSizeRequest(float size[2]); + private: void _Init(); float m_userWantedSize[2]; }; -} +} // namespace Gui #endif /* _GUIFIXED_H */ - diff --git a/src/gui/GuiISelectable.h b/src/gui/GuiISelectable.h index ea16986f5..bb86f23c4 100644 --- a/src/gui/GuiISelectable.h +++ b/src/gui/GuiISelectable.h @@ -4,12 +4,14 @@ #ifndef _GUIISELECTABLE_H #define _GUIISELECTABLE_H +#include "libs.h" + namespace Gui { class ISelectable { public: sigc::signal onSelect; virtual void SetSelected(bool) = 0; }; -} +} // namespace Gui #endif /* _GUIISELECTABLE_H */ diff --git a/src/gui/GuiImage.cpp b/src/gui/GuiImage.cpp index 3ddd83bf6..ecbd91584 100644 --- a/src/gui/GuiImage.cpp +++ b/src/gui/GuiImage.cpp @@ -1,61 +1,62 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "GuiImage.h" #include "GuiScreen.h" #include "graphics/TextureBuilder.h" +#include "libs.h" namespace Gui { -Image::Image(const char *filename): - Widget(), m_color(Color::WHITE) -{ - InitTexture(filename); + Image::Image(const char *filename) : + Widget(), + m_color(Color::WHITE) + { + InitTexture(filename); - const Graphics::TextureDescriptor &descriptor = m_quad->GetTexture()->GetDescriptor(); - m_width = descriptor.dataSize.x*descriptor.texSize.x; - m_height = descriptor.dataSize.y*descriptor.texSize.y; - SetSize(m_width, m_height); -} + const Graphics::TextureDescriptor &descriptor = m_quad->GetTexture()->GetDescriptor(); + m_width = descriptor.dataSize.x * descriptor.texSize.x; + m_height = descriptor.dataSize.y * descriptor.texSize.y; + SetSize(m_width, m_height); + } -Image::Image(const char *filename, float renderWidth, float renderHeight): - Widget(), m_color(Color::WHITE) -{ - InitTexture(filename); + Image::Image(const char *filename, float renderWidth, float renderHeight) : + Widget(), + m_color(Color::WHITE) + { + InitTexture(filename); - m_width = renderWidth; - m_height = renderHeight; - SetSize(m_width, m_height); -} + m_width = renderWidth; + m_height = renderHeight; + SetSize(m_width, m_height); + } -void Image::InitTexture(const char* filename) -{ - Graphics::TextureBuilder b = Graphics::TextureBuilder::UI(filename); - m_quad.reset(new TexturedQuad(b.GetOrCreateTexture(Gui::Screen::GetRenderer(), "ui"))); -} + void Image::InitTexture(const char *filename) + { + Graphics::TextureBuilder b = Graphics::TextureBuilder::UI(filename); + m_quad.reset(new TexturedQuad(b.GetOrCreateTexture(Gui::Screen::GetRenderer(), "ui"))); + } -void Image::GetSizeRequested(float size[2]) -{ - size[0] = m_width; - size[1] = m_height; -} + void Image::GetSizeRequested(float size[2]) + { + size[0] = m_width; + size[1] = m_height; + } -void Image::SetRenderDimensions(const float wide, const float high) -{ - m_width = wide; - m_height = high; -} + void Image::SetRenderDimensions(const float wide, const float high) + { + m_width = wide; + m_height = high; + } -void Image::Draw() -{ - PROFILE_SCOPED() - float allocSize[2]; - GetSize(allocSize); + void Image::Draw() + { + PROFILE_SCOPED() + float allocSize[2]; + GetSize(allocSize); - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - m_quad->Draw(r, vector2f(0.0f), vector2f(allocSize[0],allocSize[1]), m_color); -} - -} + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + m_quad->Draw(r, vector2f(0.0f), vector2f(allocSize[0], allocSize[1]), m_color); + } +} // namespace Gui diff --git a/src/gui/GuiImage.h b/src/gui/GuiImage.h index 1e11cb20b..7dc87fedf 100644 --- a/src/gui/GuiImage.h +++ b/src/gui/GuiImage.h @@ -4,12 +4,12 @@ #ifndef _GUIIMAGE_H #define _GUIIMAGE_H -#include "GuiWidget.h" -#include "GuiTexturedQuad.h" #include "Color.h" +#include "GuiTexturedQuad.h" +#include "GuiWidget.h" namespace Gui { - class Image: public Widget { + class Image : public Widget { public: Image(const char *filename); Image(const char *filename, float renderWidth, float renderHeight); @@ -17,12 +17,13 @@ namespace Gui { virtual void GetSizeRequested(float size[2]); void SetModulateColor(const Color &color) { m_color = color; } void SetRenderDimensions(const float wide, const float high); + private: - void InitTexture(const char* filename); + void InitTexture(const char *filename); std::unique_ptr m_quad; Color m_color; float m_width, m_height; }; -} +} // namespace Gui #endif /* _GUIIMAGE_H */ diff --git a/src/gui/GuiImageButton.cpp b/src/gui/GuiImageButton.cpp index 9a3d70968..c0e3217e0 100644 --- a/src/gui/GuiImageButton.cpp +++ b/src/gui/GuiImageButton.cpp @@ -1,68 +1,72 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Gui.h" #include "GuiImageButton.h" +#include "Gui.h" +#include "libs.h" namespace Gui { -ImageButton::ImageButton(const char *img_normal): Button() -{ - LoadImages(img_normal, 0); -} + ImageButton::ImageButton(const char *img_normal) : + Button() + { + LoadImages(img_normal, 0); + } -ImageButton::ImageButton(const char *img_normal, const char *img_pressed): Button() -{ - LoadImages(img_normal, img_pressed); -} + ImageButton::ImageButton(const char *img_normal, const char *img_pressed) : + Button() + { + LoadImages(img_normal, img_pressed); + } -ImageButton::~ImageButton() -{ - delete m_imgNormal; - if (m_imgPressed) delete m_imgPressed; -} + ImageButton::~ImageButton() + { + delete m_imgNormal; + if (m_imgPressed) delete m_imgPressed; + } -void ImageButton::LoadImages(const char *img_normal, const char *img_pressed) -{ - m_imgNormal = new Image(img_normal); - float size[2]; - m_imgNormal->GetSizeRequested(size); - SetSize(size[0], size[1]); + void ImageButton::LoadImages(const char *img_normal, const char *img_pressed) + { + m_imgNormal = new Image(img_normal); + float size[2]; + m_imgNormal->GetSizeRequested(size); + SetSize(size[0], size[1]); - if (img_pressed) m_imgPressed = new Image(img_pressed); - else m_imgPressed = 0; -} + if (img_pressed) + m_imgPressed = new Image(img_pressed); + else + m_imgPressed = 0; + } -void ImageButton::GetSizeRequested(float size[2]) -{ - m_imgNormal->GetSizeRequested(size); -} + void ImageButton::GetSizeRequested(float size[2]) + { + m_imgNormal->GetSizeRequested(size); + } -void ImageButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - Gui::Image *img; - if (m_imgPressed && IsPressed()) - img = m_imgPressed; - else - img = m_imgNormal; - if (GetEnabled()) - img->SetModulateColor(Color::WHITE); - else - img->SetModulateColor(Color(128,128,128,255)); - img->SetSize(size[0], size[1]); - img->Draw(); -} + void ImageButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + Gui::Image *img; + if (m_imgPressed && IsPressed()) + img = m_imgPressed; + else + img = m_imgNormal; + if (GetEnabled()) + img->SetModulateColor(Color::WHITE); + else + img->SetModulateColor(Color(128, 128, 128, 255)); + img->SetSize(size[0], size[1]); + img->Draw(); + } -void ImageButton::SetRenderDimensions(const float wide, const float high) -{ - assert(m_imgNormal); - m_imgNormal->SetRenderDimensions(wide, high); - if(m_imgPressed) - m_imgPressed->SetRenderDimensions(wide, high); -} + void ImageButton::SetRenderDimensions(const float wide, const float high) + { + assert(m_imgNormal); + m_imgNormal->SetRenderDimensions(wide, high); + if (m_imgPressed) + m_imgPressed->SetRenderDimensions(wide, high); + } -} +} // namespace Gui diff --git a/src/gui/GuiImageButton.h b/src/gui/GuiImageButton.h index c42dd5974..1b9d7a78e 100644 --- a/src/gui/GuiImageButton.h +++ b/src/gui/GuiImageButton.h @@ -4,13 +4,14 @@ #ifndef _GUIIMAGEBUTTON_H #define _GUIIMAGEBUTTON_H -#include "GuiWidget.h" #include "GuiButton.h" +#include "GuiWidget.h" +#include "gui/GuiImage.h" #include namespace Gui { - class ImageButton: public Button { + class ImageButton : public Button { public: ImageButton(const char *img_normal); ImageButton(const char *img_normal, const char *img_pressed); @@ -18,11 +19,12 @@ namespace Gui { virtual ~ImageButton(); virtual void GetSizeRequested(float size[2]); void SetRenderDimensions(const float wide, const float high); + private: void LoadImages(const char *img_normal, const char *img_pressed); Image *m_imgNormal; Image *m_imgPressed; }; -} +} // namespace Gui #endif /* _GUIIMAGEBUTTON_H */ diff --git a/src/gui/GuiImageRadioButton.cpp b/src/gui/GuiImageRadioButton.cpp index 0a2a4fe4f..5ca8a454c 100644 --- a/src/gui/GuiImageRadioButton.cpp +++ b/src/gui/GuiImageRadioButton.cpp @@ -1,51 +1,52 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Gui.h" #include "GuiImageRadioButton.h" +#include "Gui.h" +#include "libs.h" namespace Gui { -ImageRadioButton::ImageRadioButton(RadioGroup *g, const char *img_normal, const char *img_pressed): RadioButton(g) -{ - m_imgNormal = new Image(img_normal); - m_imgPressed = new Image(img_pressed); - float size[2]; - m_imgNormal->GetSizeRequested(size); - SetSize(size[0], size[1]); -} - -ImageRadioButton::~ImageRadioButton() -{ - delete m_imgNormal; - delete m_imgPressed; -} - -void ImageRadioButton::GetSizeRequested(float size[2]) -{ - m_imgNormal->GetSizeRequested(size); -} - -void ImageRadioButton::Draw() -{ - PROFILE_SCOPED() - float sz[2]; - GetSize(sz); - if (m_pressed) { - m_imgPressed->SetSize(sz[0], sz[1]); - m_imgPressed->Draw(); - } else { - m_imgNormal->SetSize(sz[0], sz[1]); - m_imgNormal->Draw(); + ImageRadioButton::ImageRadioButton(RadioGroup *g, const char *img_normal, const char *img_pressed) : + RadioButton(g) + { + m_imgNormal = new Image(img_normal); + m_imgPressed = new Image(img_pressed); + float size[2]; + m_imgNormal->GetSizeRequested(size); + SetSize(size[0], size[1]); } -} -void ImageRadioButton::SetRenderDimensions(const float wide, const float high) -{ - assert(m_imgPressed && m_imgNormal); - m_imgPressed->SetRenderDimensions(wide, high); - m_imgNormal->SetRenderDimensions(wide, high); -} + ImageRadioButton::~ImageRadioButton() + { + delete m_imgNormal; + delete m_imgPressed; + } -} + void ImageRadioButton::GetSizeRequested(float size[2]) + { + m_imgNormal->GetSizeRequested(size); + } + + void ImageRadioButton::Draw() + { + PROFILE_SCOPED() + float sz[2]; + GetSize(sz); + if (m_pressed) { + m_imgPressed->SetSize(sz[0], sz[1]); + m_imgPressed->Draw(); + } else { + m_imgNormal->SetSize(sz[0], sz[1]); + m_imgNormal->Draw(); + } + } + + void ImageRadioButton::SetRenderDimensions(const float wide, const float high) + { + assert(m_imgPressed && m_imgNormal); + m_imgPressed->SetRenderDimensions(wide, high); + m_imgNormal->SetRenderDimensions(wide, high); + } + +} // namespace Gui diff --git a/src/gui/GuiImageRadioButton.h b/src/gui/GuiImageRadioButton.h index c83faedc3..38ee35b1c 100644 --- a/src/gui/GuiImageRadioButton.h +++ b/src/gui/GuiImageRadioButton.h @@ -5,22 +5,24 @@ #define _GUIIMAGERADIOBUTTON_H #include "GuiRadioButton.h" +#include "gui/GuiImage.h" #include class RadioGroup; namespace Gui { - class ImageRadioButton: public RadioButton { + class ImageRadioButton : public RadioButton { public: ImageRadioButton(RadioGroup *, const char *img_normal, const char *img_pressed); virtual ~ImageRadioButton(); virtual void Draw(); virtual void GetSizeRequested(float size[2]); void SetRenderDimensions(const float wide, const float high); + private: Image *m_imgNormal; Image *m_imgPressed; }; -} +} // namespace Gui #endif /* _GUIIMAGERADIOBUTTON_H */ diff --git a/src/gui/GuiLabel.cpp b/src/gui/GuiLabel.cpp index bb87ce6b4..30c225ad6 100644 --- a/src/gui/GuiLabel.cpp +++ b/src/gui/GuiLabel.cpp @@ -5,102 +5,103 @@ namespace Gui { -Label::Label(const char *text, TextLayout::ColourMarkupMode colourMarkupMode) -{ - Init(std::string(text), colourMarkupMode); -} - -Label::Label(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode) -{ - Init(text, colourMarkupMode); -} - -Label::~Label() -{ - m_layout.reset(); -} - -void Label::Init(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode) -{ - m_needsUpdate = true; - m_colourMarkupMode = colourMarkupMode; - m_shadow = false; - m_layout = 0; - m_dlist = 0; - m_font = Gui::Screen::GetFont(); - m_color = ::Color::WHITE; - UpdateLayout(); - SetText(text); -} - -void Label::UpdateLayout() -{ - if (!m_layout.get() || m_needsUpdate) { - m_needsUpdate = false; - m_layout.reset(new TextLayout(m_text.c_str(), m_font, m_colourMarkupMode)); + Label::Label(const char *text, TextLayout::ColourMarkupMode colourMarkupMode) + { + Init(std::string(text), colourMarkupMode); } -} -void Label::RecalcSize() -{ - ResizeRequest(); -} - -Label *Label::Color(Uint8 r, Uint8 g, Uint8 b) -{ - ::Color c(r, g, b); - if (m_color != c) { - m_color = c; + Label::Label(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode) + { + Init(text, colourMarkupMode); } - return this; -} -Label *Label::Color(const ::Color &c) -{ - if (m_color != c) { - m_color = c; + Label::~Label() + { + m_layout.reset(); } - return this; -} -void Label::SetText(const char *text) -{ - SetText(std::string(text)); -} - -void Label::SetText(const std::string &text) -{ - if (m_text != text || m_needsUpdate) { - m_text = text; - m_layout->SetText(m_text.c_str()); - RecalcSize(); - } -} - -void Label::Draw() -{ - PROFILE_SCOPED() - if (!m_layout || m_needsUpdate) + void Label::Init(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode) + { + m_needsUpdate = true; + m_colourMarkupMode = colourMarkupMode; + m_shadow = false; + m_layout = 0; + m_dlist = 0; + m_font = Gui::Screen::GetFont(); + m_color = ::Color::WHITE; UpdateLayout(); - - // the size might not have bene updated, poke it until it is - float size[2]; GetSize(size); - if (is_equal_exact(size[0], 0.0f)) - RecalcSize(); - m_layout->Update(size[0], m_color); - - if (m_shadow) { - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - r->Translate(1,1,0); - m_layout->Render(size[0], Color::BLACK); - r->Translate(-1,-1,0); + SetText(text); } - m_layout->Render(size[0], m_color); -} -void Label::GetSizeRequested(float size[2]) -{ - m_layout->MeasureSize(size[0], size); -} + void Label::UpdateLayout() + { + if (!m_layout.get() || m_needsUpdate) { + m_needsUpdate = false; + m_layout.reset(new TextLayout(m_text.c_str(), m_font, m_colourMarkupMode)); + } + } -} + void Label::RecalcSize() + { + ResizeRequest(); + } + + Label *Label::Color(Uint8 r, Uint8 g, Uint8 b) + { + ::Color c(r, g, b); + if (m_color != c) { + m_color = c; + } + return this; + } + + Label *Label::Color(const ::Color &c) + { + if (m_color != c) { + m_color = c; + } + return this; + } + + void Label::SetText(const char *text) + { + SetText(std::string(text)); + } + + void Label::SetText(const std::string &text) + { + if (m_text != text || m_needsUpdate) { + m_text = text; + m_layout->SetText(m_text.c_str()); + RecalcSize(); + } + } + + void Label::Draw() + { + PROFILE_SCOPED() + if (!m_layout || m_needsUpdate) + UpdateLayout(); + + // the size might not have bene updated, poke it until it is + float size[2]; + GetSize(size); + if (is_equal_exact(size[0], 0.0f)) + RecalcSize(); + m_layout->Update(size[0], m_color); + + if (m_shadow) { + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + r->Translate(1, 1, 0); + m_layout->Render(size[0], Color::BLACK); + r->Translate(-1, -1, 0); + } + m_layout->Render(size[0], m_color); + } + + void Label::GetSizeRequested(float size[2]) + { + m_layout->MeasureSize(size[0], size); + } + +} // namespace Gui diff --git a/src/gui/GuiLabel.h b/src/gui/GuiLabel.h index 8a23e9910..d2aa93c77 100644 --- a/src/gui/GuiLabel.h +++ b/src/gui/GuiLabel.h @@ -4,15 +4,17 @@ #ifndef _GUILABEL_H #define _GUILABEL_H -#include "GuiWidget.h" #include "GuiTextLayout.h" -#include +#include "GuiWidget.h" #include +#include -namespace Text { class TextureFont; } +namespace Text { + class TextureFont; +} namespace Gui { - class Label: public Widget { + class Label : public Widget { public: Label(const char *text, TextLayout::ColourMarkupMode colourMarkupMode = TextLayout::ColourMarkupUse); Label(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode = TextLayout::ColourMarkupUse); @@ -21,9 +23,14 @@ namespace Gui { virtual void GetSizeRequested(float size[2]); void SetText(const char *text); void SetText(const std::string &text); - Label *Shadow(bool isOn) { m_shadow = isOn; return this; } + Label *Shadow(bool isOn) + { + m_shadow = isOn; + return this; + } Label *Color(Uint8 r, Uint8 g, Uint8 b); Label *Color(const ::Color &); + private: void Init(const std::string &text, TextLayout::ColourMarkupMode colourMarkupMode); void UpdateLayout(); @@ -37,6 +44,6 @@ namespace Gui { TextLayout::ColourMarkupMode m_colourMarkupMode; bool m_needsUpdate; }; -} +} // namespace Gui #endif /* _GUILABEL_H */ diff --git a/src/gui/GuiLabelSet.cpp b/src/gui/GuiLabelSet.cpp index ff00e29bb..fdf8afbb0 100644 --- a/src/gui/GuiLabelSet.cpp +++ b/src/gui/GuiLabelSet.cpp @@ -5,70 +5,71 @@ namespace Gui { -LabelSet::LabelSet() : Widget() -{ - m_eventMask = EVENT_MOUSEDOWN; - m_labelsVisible = true; - m_labelsClickable = true; - m_labelColor = Color::WHITE; - m_font = Screen::GetFont(); -} + LabelSet::LabelSet() : + Widget() + { + m_eventMask = EVENT_MOUSEDOWN; + m_labelsVisible = true; + m_labelsClickable = true; + m_labelColor = Color::WHITE; + m_font = Screen::GetFont(); + } -bool LabelSet::OnMouseDown(Gui::MouseButtonEvent *e) -{ - if ((e->button == SDL_BUTTON_LEFT) && (m_labelsClickable)) { - for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { - if ((fabs(e->x - (*i).screenx) < 10.0f) && - (fabs(e->y - (*i).screeny) < 10.0f)) { - (*i).onClick(); - return false; + bool LabelSet::OnMouseDown(Gui::MouseButtonEvent *e) + { + if ((e->button == SDL_BUTTON_LEFT) && (m_labelsClickable)) { + for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { + if ((fabs(e->x - (*i).screenx) < 10.0f) && + (fabs(e->y - (*i).screeny) < 10.0f)) { + (*i).onClick(); + return false; + } } } + return true; } - return true; -} -bool LabelSet::CanPutItem(float x, float y) -{ - for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { - if ((fabs(x-(*i).screenx) < 5.0f) && - (fabs(y-(*i).screeny) < 5.0f)) return false; + bool LabelSet::CanPutItem(float x, float y) + { + for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { + if ((fabs(x - (*i).screenx) < 5.0f) && + (fabs(y - (*i).screeny) < 5.0f)) return false; + } + return true; } - return true; -} -void LabelSet::Add(std::string text, sigc::slot onClick, float screenx, float screeny) -{ - if (CanPutItem(screenx, screeny)) { - m_items.push_back(LabelSetItem(text, onClick, screenx, screeny)); + void LabelSet::Add(std::string text, sigc::slot onClick, float screenx, float screeny) + { + if (CanPutItem(screenx, screeny)) { + m_items.push_back(LabelSetItem(text, onClick, screenx, screeny)); + } } -} -void LabelSet::Add(std::string text, sigc::slot onClick, float screenx, float screeny, const Color &col) -{ - if (CanPutItem(screenx, screeny)) { - m_items.push_back(LabelSetItem(text, onClick, screenx, screeny, col)); + void LabelSet::Add(std::string text, sigc::slot onClick, float screenx, float screeny, const Color &col) + { + if (CanPutItem(screenx, screeny)) { + m_items.push_back(LabelSetItem(text, onClick, screenx, screeny, col)); + } } -} -void LabelSet::Clear() -{ - m_items.clear(); -} - -void LabelSet::Draw() -{ - PROFILE_SCOPED() - if (!m_labelsVisible) return; - for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { - Gui::Screen::RenderStringBuffer((*i).m_vb, (*i).text, (*i).screenx, (*i).screeny - Gui::Screen::GetFontHeight()*0.5f, (*i).hasOwnColor ? (*i).color : m_labelColor, m_font.Get()); + void LabelSet::Clear() + { + m_items.clear(); } -} -void LabelSet::GetSizeRequested(float size[2]) -{ - size[0] = 800.0f; - size[1] = 600.0f; -} + void LabelSet::Draw() + { + PROFILE_SCOPED() + if (!m_labelsVisible) return; + for (std::vector::iterator i = m_items.begin(); i != m_items.end(); ++i) { + Gui::Screen::RenderStringBuffer((*i).m_vb, (*i).text, (*i).screenx, (*i).screeny - Gui::Screen::GetFontHeight() * 0.5f, (*i).hasOwnColor ? (*i).color : m_labelColor, m_font.Get()); + } + } -} + void LabelSet::GetSizeRequested(float size[2]) + { + size[0] = 800.0f; + size[1] = 600.0f; + } + +} // namespace Gui diff --git a/src/gui/GuiLabelSet.h b/src/gui/GuiLabelSet.h index 0e5310fff..c4583c544 100644 --- a/src/gui/GuiLabelSet.h +++ b/src/gui/GuiLabelSet.h @@ -12,47 +12,57 @@ * bodies, and SystemView, SectorView etc. */ namespace Gui { -class LabelSet: public Widget { -public: - class LabelSetItem { + class LabelSet : public Widget { public: - LabelSetItem(std::string text_, sigc::slot onClick_, float screenx_, float screeny_) : - text(text_), hasOwnColor(false), onClick(onClick_), screenx(screenx_), screeny(screeny_) - { - } - LabelSetItem(std::string text_, sigc::slot onClick_, float screenx_, float screeny_, const Color &c) : - text(text_), color(c), hasOwnColor(true), onClick(onClick_), screenx(screenx_), screeny(screeny_) - { - } - std::string text; - Color color; - bool hasOwnColor; - sigc::slot onClick; - float screenx, screeny; - RefCountedPtr m_vb; + class LabelSetItem { + public: + LabelSetItem(std::string text_, sigc::slot onClick_, float screenx_, float screeny_) : + text(text_), + hasOwnColor(false), + onClick(onClick_), + screenx(screenx_), + screeny(screeny_) + { + } + LabelSetItem(std::string text_, sigc::slot onClick_, float screenx_, float screeny_, const Color &c) : + text(text_), + color(c), + hasOwnColor(true), + onClick(onClick_), + screenx(screenx_), + screeny(screeny_) + { + } + std::string text; + Color color; + bool hasOwnColor; + sigc::slot onClick; + float screenx, screeny; + RefCountedPtr m_vb; + }; + + LabelSet(); + bool OnMouseDown(MouseButtonEvent *e); + virtual void Draw(); + virtual void GetSizeRequested(float size[2]); + void Clear(); + void Add(std::string text, sigc::slot onClick, float screenx, float screeny); + /** Overrides color set by SetLabelColor */ + void Add(std::string text, sigc::slot onClick, float screenx, float screeny, const Color &col); + void SetLabelsClickable(bool v) { m_labelsClickable = v; } + void SetLabelsVisible(bool v) { m_labelsVisible = v; } + void SetLabelColor(const Color &c) { m_labelColor = c; } + + private: + bool CanPutItem(float x, float y); + + std::vector m_items; + bool m_labelsVisible; + bool m_labelsClickable; + Color m_labelColor; + + RefCountedPtr m_font; }; - - LabelSet(); - bool OnMouseDown(MouseButtonEvent *e); - virtual void Draw(); - virtual void GetSizeRequested(float size[2]); - void Clear(); - void Add(std::string text, sigc::slot onClick, float screenx, float screeny); - /** Overrides color set by SetLabelColor */ - void Add(std::string text, sigc::slot onClick, float screenx, float screeny, const Color &col); - void SetLabelsClickable(bool v) { m_labelsClickable = v; } - void SetLabelsVisible(bool v) { m_labelsVisible = v; } - void SetLabelColor(const Color &c) { m_labelColor = c; } -private: - bool CanPutItem(float x, float y); - - std::vector m_items; - bool m_labelsVisible; - bool m_labelsClickable; - Color m_labelColor; - - RefCountedPtr m_font; -}; -} +} // namespace Gui #endif /* GUILABELSET_H */ diff --git a/src/gui/GuiMeterBar.cpp b/src/gui/GuiMeterBar.cpp index c528d846d..aaa3ed5c8 100644 --- a/src/gui/GuiMeterBar.cpp +++ b/src/gui/GuiMeterBar.cpp @@ -3,58 +3,58 @@ #include "Gui.h" -static const float METERBAR_PADDING = 5.0f; +static const float METERBAR_PADDING = 5.0f; static const float METERBAR_BAR_HEIGHT = 8.0f; -static const Color OUTER_COLOUR(255,255,255,32); +static const Color OUTER_COLOUR(255, 255, 255, 32); namespace Gui { -MeterBar::MeterBar(float width, const char *label, const ::Color &graphCol) -{ - m_requestedWidth = width; - m_barValue = 0; - m_barColor = graphCol; - m_label = new Gui::Label(label); - Add(m_label, METERBAR_PADDING, METERBAR_PADDING + METERBAR_BAR_HEIGHT); - m_label->Show(); -} - -void MeterBar::Draw() -{ - PROFILE_SCOPED() - float fsize[2]; - GetSize(fsize); - vector2f size(fsize[0], fsize[1]); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - - if(!m_outer) - m_outer.reset( new Graphics::Drawables::RoundEdgedRect(r, size, 5.0f, OUTER_COLOUR, Screen::alphaBlendState, false) ); - else - m_outer->Update(size, 5.0f, OUTER_COLOUR); - - m_outer->Draw(r); - - // draw inner bar + MeterBar::MeterBar(float width, const char *label, const ::Color &graphCol) { - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); - r->Translate(METERBAR_PADDING, METERBAR_PADDING, 0.0f); - size.x = m_barValue * (size.x - 2.0f*METERBAR_PADDING); - size.y = METERBAR_BAR_HEIGHT; - if(!m_inner) - m_inner.reset( new Graphics::Drawables::RoundEdgedRect(r, size, 3.0f, m_barColor, Screen::alphaBlendState, false) ); - else - m_inner->Update(size, 3.0f, m_barColor); - - m_inner->Draw(r); + m_requestedWidth = width; + m_barValue = 0; + m_barColor = graphCol; + m_label = new Gui::Label(label); + Add(m_label, METERBAR_PADDING, METERBAR_PADDING + METERBAR_BAR_HEIGHT); + m_label->Show(); } - Gui::Fixed::Draw(); -} -void MeterBar::GetSizeRequested(float size[2]) -{ - size[0] = m_requestedWidth; - size[1] = METERBAR_PADDING*2.0f + METERBAR_BAR_HEIGHT + Gui::Screen::GetFontHeight(); -} + void MeterBar::Draw() + { + PROFILE_SCOPED() + float fsize[2]; + GetSize(fsize); + vector2f size(fsize[0], fsize[1]); -} + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + + if (!m_outer) + m_outer.reset(new Graphics::Drawables::RoundEdgedRect(r, size, 5.0f, OUTER_COLOUR, Screen::alphaBlendState, false)); + else + m_outer->Update(size, 5.0f, OUTER_COLOUR); + + m_outer->Draw(r); + + // draw inner bar + { + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + r->Translate(METERBAR_PADDING, METERBAR_PADDING, 0.0f); + size.x = m_barValue * (size.x - 2.0f * METERBAR_PADDING); + size.y = METERBAR_BAR_HEIGHT; + if (!m_inner) + m_inner.reset(new Graphics::Drawables::RoundEdgedRect(r, size, 3.0f, m_barColor, Screen::alphaBlendState, false)); + else + m_inner->Update(size, 3.0f, m_barColor); + + m_inner->Draw(r); + } + Gui::Fixed::Draw(); + } + + void MeterBar::GetSizeRequested(float size[2]) + { + size[0] = m_requestedWidth; + size[1] = METERBAR_PADDING * 2.0f + METERBAR_BAR_HEIGHT + Gui::Screen::GetFontHeight(); + } + +} // namespace Gui diff --git a/src/gui/GuiMeterBar.h b/src/gui/GuiMeterBar.h index d0ce2961d..1044636b1 100644 --- a/src/gui/GuiMeterBar.h +++ b/src/gui/GuiMeterBar.h @@ -5,20 +5,21 @@ #define GUIMETERBAR_H #include "Color.h" -#include "GuiLabel.h" #include "GuiFixed.h" +#include "GuiLabel.h" /* A cute horizontal bar readout of some value from 0 to 1, with a text label also. Hull and weapon temperature are shown with these */ namespace Gui { - class MeterBar: public Gui::Fixed { + class MeterBar : public Gui::Fixed { public: MeterBar(float width, const char *label, const ::Color &graphCol); virtual ~MeterBar() {} virtual void Draw(); virtual void GetSizeRequested(float size[2]); - void SetValue(float v) { m_barValue = Clamp(v,0.0f,1.0f); } + void SetValue(float v) { m_barValue = Clamp(v, 0.0f, 1.0f); } void SetColor(const ::Color &c) { m_barColor = c; } + private: float m_requestedWidth; Gui::Label *m_label; @@ -27,6 +28,6 @@ namespace Gui { std::unique_ptr m_outer; std::unique_ptr m_inner; }; -} +} // namespace Gui #endif /* GUIMETERBAR_H */ diff --git a/src/gui/GuiMultiStateImageButton.cpp b/src/gui/GuiMultiStateImageButton.cpp index bf7aeb773..1d975b9a5 100644 --- a/src/gui/GuiMultiStateImageButton.cpp +++ b/src/gui/GuiMultiStateImageButton.cpp @@ -1,121 +1,123 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" namespace Gui { -MultiStateImageButton::MultiStateImageButton(): Button() -{ - m_curState = 0; - m_isSelected = true; - Button::onClick.connect(sigc::mem_fun(this, &MultiStateImageButton::OnActivate)); -} - -MultiStateImageButton::~MultiStateImageButton() -{ - for (std::vector::iterator i = m_states.begin(); i != m_states.end(); ++i) { - delete (*i).activeImage; - delete (*i).inactiveImage; - } -} - -void MultiStateImageButton::StateNext() -{ - m_curState++; - if (m_curState >= signed(m_states.size())) m_curState = 0; - UpdateOverriddenTooltip(); -} - -void MultiStateImageButton::StatePrev() -{ - m_curState--; - if (m_curState < 0) m_curState = signed(m_states.size())-1; - UpdateOverriddenTooltip(); -} - -void MultiStateImageButton::OnActivate() -{ - // only iterate through states once widget is selected. - if (m_isSelected) StateNext(); - else { + MultiStateImageButton::MultiStateImageButton() : + Button() + { + m_curState = 0; m_isSelected = true; - onSelect.emit(); + Button::onClick.connect(sigc::mem_fun(this, &MultiStateImageButton::OnActivate)); } - onClick.emit(this); -} -void MultiStateImageButton::SetActiveState(int state) -{ - for (unsigned int i=0; i::iterator i = m_states.begin(); i != m_states.end(); ++i) { + delete (*i).activeImage; + delete (*i).inactiveImage; } } -} -void MultiStateImageButton::SetSelected(bool state) -{ - m_isSelected = state; -} - -void MultiStateImageButton::GetSizeRequested(float size[2]) -{ - assert(m_states.size()); - m_states[0].activeImage->GetSizeRequested(size); - m_states[0].inactiveImage->GetSizeRequested(size); -} - -void MultiStateImageButton::Draw() -{ - PROFILE_SCOPED() - float sz[2]; - GetSize(sz); - if (m_isSelected) { - m_states[m_curState].activeImage->SetSize(sz[0], sz[1]); - m_states[m_curState].activeImage->Draw(); - } else { - m_states[m_curState].inactiveImage->SetSize(sz[0], sz[1]); - m_states[m_curState].inactiveImage->Draw(); + void MultiStateImageButton::StateNext() + { + m_curState++; + if (m_curState >= signed(m_states.size())) m_curState = 0; + UpdateOverriddenTooltip(); } -} -void MultiStateImageButton::AddState(int state, const char *filename) -{ - AddState(state, filename, filename, ""); -} - -void MultiStateImageButton::AddState(int state, const char *filename, std::string tooltip) -{ - AddState(state, filename, filename, tooltip); -} - -void MultiStateImageButton::AddState(int state, const char *inactiveImage, const char *activeImage, std::string tooltip) -{ - State s; - s.state = state; - s.inactiveImage = new Image(inactiveImage); - s.activeImage = new Image(activeImage); - s.tooltip = tooltip; - m_states.push_back(s); - float size[2]; - s.activeImage->GetSizeRequested(size); - SetSize(size[0], size[1]); -} - -std::string MultiStateImageButton::GetOverrideTooltip() -{ - return m_states[m_curState].tooltip; -} - -void MultiStateImageButton::SetRenderDimensions(const float wide, const float high) -{ - for (std::vector::iterator i = m_states.begin(); i != m_states.end(); ++i) { - assert((*i).activeImage && (*i).inactiveImage); - (*i).activeImage->SetRenderDimensions(wide, high); - (*i).inactiveImage->SetRenderDimensions(wide, high); + void MultiStateImageButton::StatePrev() + { + m_curState--; + if (m_curState < 0) m_curState = signed(m_states.size()) - 1; + UpdateOverriddenTooltip(); } -} -} + void MultiStateImageButton::OnActivate() + { + // only iterate through states once widget is selected. + if (m_isSelected) + StateNext(); + else { + m_isSelected = true; + onSelect.emit(); + } + onClick.emit(this); + } + + void MultiStateImageButton::SetActiveState(int state) + { + for (unsigned int i = 0; i < m_states.size(); i++) { + if (m_states[i].state == state) { + m_curState = i; + break; + } + } + } + + void MultiStateImageButton::SetSelected(bool state) + { + m_isSelected = state; + } + + void MultiStateImageButton::GetSizeRequested(float size[2]) + { + assert(m_states.size()); + m_states[0].activeImage->GetSizeRequested(size); + m_states[0].inactiveImage->GetSizeRequested(size); + } + + void MultiStateImageButton::Draw() + { + PROFILE_SCOPED() + float sz[2]; + GetSize(sz); + if (m_isSelected) { + m_states[m_curState].activeImage->SetSize(sz[0], sz[1]); + m_states[m_curState].activeImage->Draw(); + } else { + m_states[m_curState].inactiveImage->SetSize(sz[0], sz[1]); + m_states[m_curState].inactiveImage->Draw(); + } + } + + void MultiStateImageButton::AddState(int state, const char *filename) + { + AddState(state, filename, filename, ""); + } + + void MultiStateImageButton::AddState(int state, const char *filename, std::string tooltip) + { + AddState(state, filename, filename, tooltip); + } + + void MultiStateImageButton::AddState(int state, const char *inactiveImage, const char *activeImage, std::string tooltip) + { + State s; + s.state = state; + s.inactiveImage = new Image(inactiveImage); + s.activeImage = new Image(activeImage); + s.tooltip = tooltip; + m_states.push_back(s); + float size[2]; + s.activeImage->GetSizeRequested(size); + SetSize(size[0], size[1]); + } + + std::string MultiStateImageButton::GetOverrideTooltip() + { + return m_states[m_curState].tooltip; + } + + void MultiStateImageButton::SetRenderDimensions(const float wide, const float high) + { + for (std::vector::iterator i = m_states.begin(); i != m_states.end(); ++i) { + assert((*i).activeImage && (*i).inactiveImage); + (*i).activeImage->SetRenderDimensions(wide, high); + (*i).inactiveImage->SetRenderDimensions(wide, high); + } + } + +} // namespace Gui diff --git a/src/gui/GuiMultiStateImageButton.h b/src/gui/GuiMultiStateImageButton.h index 1363c23a9..ddae81b74 100644 --- a/src/gui/GuiMultiStateImageButton.h +++ b/src/gui/GuiMultiStateImageButton.h @@ -10,7 +10,7 @@ #include namespace Gui { - class MultiStateImageButton: public Button, public ISelectable { + class MultiStateImageButton : public Button, public ISelectable { public: MultiStateImageButton(); virtual void Draw(); @@ -23,12 +23,14 @@ namespace Gui { void StateNext(); void StatePrev(); virtual void OnActivate(); - sigc::signal onClick; + sigc::signal onClick; virtual void SetSelected(bool state); void SetActiveState(int state); void SetRenderDimensions(const float wide, const float high); + protected: virtual std::string GetOverrideTooltip(); + private: struct State { int state; @@ -40,6 +42,6 @@ namespace Gui { int m_curState; bool m_isSelected; }; -} +} // namespace Gui #endif /* _GUIMULTISTATEIMAGEBUTTON_H */ diff --git a/src/gui/GuiRadioButton.cpp b/src/gui/GuiRadioButton.cpp index 4780e6a1f..a9b409ce9 100644 --- a/src/gui/GuiRadioButton.cpp +++ b/src/gui/GuiRadioButton.cpp @@ -1,52 +1,51 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" static const float BUTTON_SIZE = 16.f; namespace Gui { -RadioButton::RadioButton(Gui::RadioGroup *g) -{ - m_pressed = false; - SetSize(BUTTON_SIZE, BUTTON_SIZE); - if (g) g->Add(this); -} -RadioButton::~RadioButton() -{ - -} -bool RadioButton::OnMouseDown(MouseButtonEvent *e) -{ - if (e->button == SDL_BUTTON_LEFT) { - onPress.emit(); - OnActivate(); - return false; - } else - return true; -} -void RadioButton::OnActivate() -{ -// if (!m_pressed) onSelect.emit(); - onSelect.emit(); // needs to emit even when pressed for time accel buttons - m_pressed = true; // does this break anything? -} -void RadioButton::GetSizeRequested(float size[2]) -{ - size[0] = BUTTON_SIZE; - size[1] = BUTTON_SIZE; -} - -void RadioButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - if (m_pressed) { - Theme::DrawIndent(size, Screen::alphaBlendState); - } else { - Theme::DrawOutdent(size, Screen::alphaBlendState); + RadioButton::RadioButton(Gui::RadioGroup *g) + { + m_pressed = false; + SetSize(BUTTON_SIZE, BUTTON_SIZE); + if (g) g->Add(this); } -} -} + RadioButton::~RadioButton() + { + } + bool RadioButton::OnMouseDown(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + onPress.emit(); + OnActivate(); + return false; + } else + return true; + } + void RadioButton::OnActivate() + { + // if (!m_pressed) onSelect.emit(); + onSelect.emit(); // needs to emit even when pressed for time accel buttons + m_pressed = true; // does this break anything? + } + void RadioButton::GetSizeRequested(float size[2]) + { + size[0] = BUTTON_SIZE; + size[1] = BUTTON_SIZE; + } + + void RadioButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + if (m_pressed) { + Theme::DrawIndent(size, Screen::alphaBlendState); + } else { + Theme::DrawOutdent(size, Screen::alphaBlendState); + } + } +} // namespace Gui diff --git a/src/gui/GuiRadioButton.h b/src/gui/GuiRadioButton.h index 0e9e5e187..d5700814d 100644 --- a/src/gui/GuiRadioButton.h +++ b/src/gui/GuiRadioButton.h @@ -4,14 +4,15 @@ #ifndef _GUIRADIOBUTTON_H #define _GUIRADIOBUTTON_H -#include "GuiWidget.h" +#include "GuiButton.h" #include "GuiISelectable.h" +#include "GuiWidget.h" #include namespace Gui { class RadioGroup; - class RadioButton: public Button, public ISelectable { + class RadioButton : public Button, public ISelectable { public: RadioButton(RadioGroup *); virtual ~RadioButton(); @@ -21,10 +22,11 @@ namespace Gui { virtual void OnActivate(); virtual void SetSelected(bool state) { m_pressed = state; } bool GetSelected() { return m_pressed; } + protected: bool m_pressed; }; -} +} // namespace Gui #endif /* _GUIRADIOBUTTON_H */ diff --git a/src/gui/GuiRadioGroup.cpp b/src/gui/GuiRadioGroup.cpp index c869f799e..76250d4c1 100644 --- a/src/gui/GuiRadioGroup.cpp +++ b/src/gui/GuiRadioGroup.cpp @@ -1,33 +1,32 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "GuiRadioGroup.h" #include "GuiISelectable.h" +#include "libs.h" namespace Gui { -void RadioGroup::Add(ISelectable *b) -{ - b->onSelect.connect(sigc::bind(sigc::mem_fun(*this, &RadioGroup::OnSelected), b)); - m_members.push_back(b); -} + void RadioGroup::Add(ISelectable *b) + { + b->onSelect.connect(sigc::bind(sigc::mem_fun(*this, &RadioGroup::OnSelected), b)); + m_members.push_back(b); + } -void RadioGroup::OnSelected(ISelectable *b) -{ - for(std::list::iterator i = m_members.begin(); i != m_members.end(); ++i) { - if (*i != b) { - (*i)->SetSelected(false); + void RadioGroup::OnSelected(ISelectable *b) + { + for (std::list::iterator i = m_members.begin(); i != m_members.end(); ++i) { + if (*i != b) { + (*i)->SetSelected(false); + } } } -} -void RadioGroup::SetSelected(int member_idx) -{ - int idx = 0; - for(std::list::iterator i = m_members.begin(); i != m_members.end(); ++i, ++idx) { - (*i)->SetSelected(idx == member_idx); + void RadioGroup::SetSelected(int member_idx) + { + int idx = 0; + for (std::list::iterator i = m_members.begin(); i != m_members.end(); ++i, ++idx) { + (*i)->SetSelected(idx == member_idx); + } } -} - -} +} // namespace Gui diff --git a/src/gui/GuiRadioGroup.h b/src/gui/GuiRadioGroup.h index 7f6f5dae2..882e09e44 100644 --- a/src/gui/GuiRadioGroup.h +++ b/src/gui/GuiRadioGroup.h @@ -10,14 +10,15 @@ namespace Gui { class RadioGroup { public: - RadioGroup() {}; - virtual ~RadioGroup() {}; + RadioGroup(){}; + virtual ~RadioGroup(){}; void Add(ISelectable *b); void SetSelected(int member_idx); + private: void OnSelected(ISelectable *b); - std::list m_members; + std::list m_members; }; -} +} // namespace Gui #endif /* _GUIRADIOGROUP_H */ diff --git a/src/gui/GuiScreen.cpp b/src/gui/GuiScreen.cpp index 3eb41ad60..5786cfd07 100644 --- a/src/gui/GuiScreen.cpp +++ b/src/gui/GuiScreen.cpp @@ -2,382 +2,380 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Gui.h" -#include "vector3.h" // for projection #include "text/TextSupport.h" +#include "vector3.h" // for projection namespace Gui { -bool Screen::initted = false; -int Screen::width; -int Screen::height; -int Screen::realWidth; -int Screen::realHeight; -float Screen::invRealWidth; -float Screen::invRealHeight; -float Screen::fontScale[2]; -std::list Screen::kbshortcut_widgets; -Gui::Fixed *Screen::baseContainer; -Gui::Widget *Screen::focusedWidget; -matrix4x4f Screen::modelMatrix; -matrix4x4f Screen::projMatrix; -Sint32 Screen::viewport[4]; + bool Screen::initted = false; + int Screen::width; + int Screen::height; + int Screen::realWidth; + int Screen::realHeight; + float Screen::invRealWidth; + float Screen::invRealHeight; + float Screen::fontScale[2]; + std::list Screen::kbshortcut_widgets; + Gui::Fixed *Screen::baseContainer; + Gui::Widget *Screen::focusedWidget; + matrix4x4f Screen::modelMatrix; + matrix4x4f Screen::projMatrix; + Sint32 Screen::viewport[4]; -FontCache Screen::s_fontCache; -std::stack< RefCountedPtr > Screen::s_fontStack; -RefCountedPtrScreen::s_defaultFont; + FontCache Screen::s_fontCache; + std::stack> Screen::s_fontStack; + RefCountedPtr Screen::s_defaultFont; -Graphics::Renderer *Screen::s_renderer; -Graphics::RenderState *Screen::alphaBlendState = nullptr; -Graphics::Material *Screen::flatColorMaterial = nullptr; + Graphics::Renderer *Screen::s_renderer; + Graphics::RenderState *Screen::alphaBlendState = nullptr; + Graphics::Material *Screen::flatColorMaterial = nullptr; -void Screen::Init(Graphics::Renderer *renderer, int real_width, int real_height, int ui_width, int ui_height) -{ - s_renderer = renderer; - - Screen::width = ui_width; - Screen::height = ui_height; - Screen::realWidth = real_width; - Screen::realHeight = real_height; - Screen::invRealWidth = 1.0f/real_width; - Screen::invRealHeight = 1.0f/real_height; - Screen::initted = true; - // Why? because although our font textures get bigger with screen - // resolution, our Gui Ortho projection is still 800x600 so vertex - // coords must be scaled. - Screen::fontScale[0] = ui_width / float(real_width); - Screen::fontScale[1] = ui_height / float(real_height); - s_defaultFont = s_fontCache.GetTextureFont("GuiFont"); - PushFont(s_defaultFont); - Screen::baseContainer = new Gui::Fixed(); - Screen::baseContainer->SetSize(float(Screen::width), float(Screen::height)); - Screen::baseContainer->Show(); - - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthWrite = false; - alphaBlendState = renderer->CreateRenderState(rsd); - - Graphics::MaterialDescriptor mdesc; - flatColorMaterial = renderer->CreateMaterial(mdesc); -} - -void Screen::Uninit() -{ - Screen::baseContainer->RemoveAllChildren(); // children deleted elsewhere? - delete Screen::baseContainer; - delete flatColorMaterial; -} - -static sigc::connection _focusedWidgetOnDelete; - -void Screen::OnDeleteFocusedWidget() -{ - _focusedWidgetOnDelete.disconnect(); - focusedWidget = 0; -} - -void Screen::SetFocused(Widget *w, bool enableKeyRepeat) -{ - ClearFocus(); - _focusedWidgetOnDelete = w->onDelete.connect(sigc::ptr_fun(&Screen::OnDeleteFocusedWidget)); - focusedWidget = w; -} - -void Screen::ClearFocus() -{ - if (!focusedWidget) return; - _focusedWidgetOnDelete.disconnect(); - focusedWidget = 0; -} - -bool Screen::Project(const vector3d &in, vector3d &out) -{ - PROFILE_SCOPED() - // implements gluProject (see the OpenGL documentation or the Mesa implementation of gluProject) - const float * const M = modelMatrix.Data(); - const float * const P = projMatrix.Data(); - - const double vcam[4] = { // camera space - in.x*M[0] + in.y*M[4] + in.z*M[ 8] + M[12], - in.x*M[1] + in.y*M[5] + in.z*M[ 9] + M[13], - in.x*M[2] + in.y*M[6] + in.z*M[10] + M[14], - in.x*M[3] + in.y*M[7] + in.z*M[11] + M[15] - }; - const double vclip[4] = { // clip space - vcam[0]*P[0] + vcam[1]*P[4] + vcam[2]*P[ 8] + vcam[3]*P[12], - vcam[0]*P[1] + vcam[1]*P[5] + vcam[2]*P[ 9] + vcam[3]*P[13], - vcam[0]*P[2] + vcam[1]*P[6] + vcam[2]*P[10] + vcam[3]*P[14], - vcam[0]*P[3] + vcam[1]*P[7] + vcam[2]*P[11] + vcam[3]*P[15] - }; - - if (is_zero_exact(vclip[3])) { return false; } - - const double w = vclip[3]; - - const double v[3] = { - (vclip[0] / w) * 0.5 + 0.5, - (vclip[1] / w) * 0.5 + 0.5, - (vclip[2] / w) * 0.5 + 0.5 - }; - - out.x = v[0] * viewport[2] + viewport[0]; - out.y = v[1] * viewport[3] + viewport[1]; - out.z = v[2]; - - // map to pixels - out.x = out.x * width * invRealWidth; - out.y = GetHeight() - out.y * height * invRealHeight; - return true; -} - -void Screen::EnterOrtho() -{ - PROFILE_SCOPED() - - Graphics::Renderer *r = GetRenderer(); - - modelMatrix = r->GetCurrentModelView(); - projMatrix = r->GetCurrentProjection(); - - r->GetCurrentViewport(&viewport[0]); - r->SetOrthographicProjection(0, width, height, 0, -1, 1); - r->SetTransform(matrix4x4f::Identity()); -} - -void Screen::LeaveOrtho() -{ - PROFILE_SCOPED() - - Graphics::Renderer *r = GetRenderer(); - - r->SetProjection(projMatrix); - r->SetTransform(modelMatrix); -} - -void Screen::Draw() -{ - PROFILE_SCOPED() - assert(Screen::initted); - EnterOrtho(); - baseContainer->Draw(); - LeaveOrtho(); -} - -bool Screen::IsBaseWidget(const Widget *w) -{ - PROFILE_SCOPED() - return w == static_cast(baseContainer); -} - -void Screen::AddBaseWidget(Widget *w, int x, int y) -{ - baseContainer->Add(w, float(x), float(y)); -} - -void Screen::RemoveBaseWidget(Widget *w) -{ - baseContainer->Remove(w); -} - -void Screen::SDLEventCoordToScreenCoord(int sdlev_x, int sdlev_y, float *x, float *y) -{ - *y = sdlev_y*height*invRealHeight; - *x = sdlev_x*width*invRealWidth; -} - -void Screen::OnMouseMotion(SDL_MouseMotionEvent *e) -{ - MouseMotionEvent ev; - float x, y; - Screen::SDLEventCoordToScreenCoord(e->x, e->y, &x, &y); - ev.screenX = ev.x = x; - ev.screenY = ev.y = y; - baseContainer->OnMouseMotion(&ev); - ev.screenX = ev.x = x; - ev.screenY = ev.y = y; - RawEvents::onMouseMotion.emit(&ev); -} - -void Screen::OnClick(SDL_MouseButtonEvent *e) -{ - MouseButtonEvent ev; - float x, y; - Screen::SDLEventCoordToScreenCoord(e->x, e->y, &x, &y); - ev.button = e->button; - ev.isdown = (e->type == SDL_MOUSEBUTTONDOWN); - ev.screenX = ev.x = x; - ev.screenY = ev.y = y; - if (ev.isdown) { - baseContainer->OnMouseDown(&ev); - RawEvents::onMouseDown.emit(&ev); - } else { - baseContainer->OnMouseUp(&ev); - RawEvents::onMouseUp.emit(&ev); - } -} - -void Screen::OnKeyDown(const SDL_Keysym *sym) -{ - if (focusedWidget) { - bool accepted = focusedWidget->OnKeyDown(sym); - // don't check shortcuts if the focused widget accepted the key-press - if (accepted) - return; - } - for (std::list::iterator i = kbshortcut_widgets.begin(); i != kbshortcut_widgets.end(); ++i) { - if (!(*i)->IsVisible()) continue; - if (!(*i)->GetEnabled()) continue; - (*i)->OnPreShortcut(sym); - } -} - -void Screen::OnKeyUp(const SDL_Keysym *sym) -{ -} - -void Screen::OnTextInput(const SDL_TextInputEvent *e) -{ - if (!focusedWidget) return; - Uint32 unicode; - Text::utf8_decode_char(&unicode, e->text); - focusedWidget->OnTextInput(unicode); -} - -float Screen::GetFontHeight(Text::TextureFont *font) -{ - if (!font) font = GetFont().Get(); - - return font->GetHeight() * fontScale[1]; -} - -float Screen::GetFontDescender(Text::TextureFont *font) -{ - if (!font) font = GetFont().Get(); - - return font->GetDescender() * fontScale[1]; -} - -void Screen::MeasureString(const std::string &s, float &w, float &h, Text::TextureFont *font) -{ - if (!font) font = GetFont().Get(); - assert(font); - - font->MeasureString(s.c_str(), w, h); - w *= fontScale[0]; - h *= fontScale[1]; -} - -void Screen::MeasureCharacterPos(const std::string &s, int charIndex, float &x, float &y, Text::TextureFont *font) -{ - assert((charIndex >= 0) && (charIndex <= int(s.size()))); - - if (!font) font = GetFont().Get(); - assert(font); - - font->MeasureCharacterPos(s.c_str(), charIndex, x, y); - x *= fontScale[0]; - y *= fontScale[1]; -} - -int Screen::PickCharacterInString(const std::string &s, float x, float y, Text::TextureFont *font) -{ - if (!font) font = GetFont().Get(); - assert(font); - - x /= fontScale[0]; - y /= fontScale[1]; - - return font->PickCharacter(s.c_str(), x, y); -} - -void Screen::RenderStringBuffer(RefCountedPtr vb, const std::string &s, float xoff, float yoff, const Color &color, Text::TextureFont *font) -{ - PROFILE_SCOPED() - if (!font) font = GetFont().Get(); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - - const matrix4x4f &modelMatrix_ = r->GetCurrentModelView(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); - - const float x = modelMatrix_[12] + xoff; - const float y = modelMatrix_[13] + yoff; - - r->LoadIdentity(); - r->Translate(floor(x/Screen::fontScale[0])*Screen::fontScale[0], floor(y/Screen::fontScale[1])*Screen::fontScale[1], 0); - r->Scale(Screen::fontScale[0], Screen::fontScale[1], 1); - - // temporary, owned by the font - Graphics::VertexBuffer *pVB = font->GetCachedVertexBuffer(s); - if (pVB) { - // found the buffer - font->RenderBuffer(pVB, color); - } - else + void Screen::Init(Graphics::Renderer *renderer, int real_width, int real_height, int ui_width, int ui_height) { - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); - font->PopulateString(va, s.c_str(), 0, 0, color); + s_renderer = renderer; - if (va.GetNumVerts() > 0) { - if (!vb.Valid() || vb->GetCapacity() < va.GetNumVerts()) { - vb.Reset(font->CreateVertexBuffer(va, s, true)); - } + Screen::width = ui_width; + Screen::height = ui_height; + Screen::realWidth = real_width; + Screen::realHeight = real_height; + Screen::invRealWidth = 1.0f / real_width; + Screen::invRealHeight = 1.0f / real_height; + Screen::initted = true; + // Why? because although our font textures get bigger with screen + // resolution, our Gui Ortho projection is still 800x600 so vertex + // coords must be scaled. + Screen::fontScale[0] = ui_width / float(real_width); + Screen::fontScale[1] = ui_height / float(real_height); + s_defaultFont = s_fontCache.GetTextureFont("GuiFont"); + PushFont(s_defaultFont); + Screen::baseContainer = new Gui::Fixed(); + Screen::baseContainer->SetSize(float(Screen::width), float(Screen::height)); + Screen::baseContainer->Show(); - vb->Populate(va); + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthWrite = false; + alphaBlendState = renderer->CreateRenderState(rsd); - font->RenderBuffer(vb.Get(), color); + Graphics::MaterialDescriptor mdesc; + flatColorMaterial = renderer->CreateMaterial(mdesc); + } + + void Screen::Uninit() + { + Screen::baseContainer->RemoveAllChildren(); // children deleted elsewhere? + delete Screen::baseContainer; + delete flatColorMaterial; + } + + static sigc::connection _focusedWidgetOnDelete; + + void Screen::OnDeleteFocusedWidget() + { + _focusedWidgetOnDelete.disconnect(); + focusedWidget = 0; + } + + void Screen::SetFocused(Widget *w, bool enableKeyRepeat) + { + ClearFocus(); + _focusedWidgetOnDelete = w->onDelete.connect(sigc::ptr_fun(&Screen::OnDeleteFocusedWidget)); + focusedWidget = w; + } + + void Screen::ClearFocus() + { + if (!focusedWidget) return; + _focusedWidgetOnDelete.disconnect(); + focusedWidget = 0; + } + + bool Screen::Project(const vector3d &in, vector3d &out) + { + PROFILE_SCOPED() + // implements gluProject (see the OpenGL documentation or the Mesa implementation of gluProject) + const float *const M = modelMatrix.Data(); + const float *const P = projMatrix.Data(); + + const double vcam[4] = { // camera space + in.x * M[0] + in.y * M[4] + in.z * M[8] + M[12], + in.x * M[1] + in.y * M[5] + in.z * M[9] + M[13], + in.x * M[2] + in.y * M[6] + in.z * M[10] + M[14], + in.x * M[3] + in.y * M[7] + in.z * M[11] + M[15] + }; + const double vclip[4] = { // clip space + vcam[0] * P[0] + vcam[1] * P[4] + vcam[2] * P[8] + vcam[3] * P[12], + vcam[0] * P[1] + vcam[1] * P[5] + vcam[2] * P[9] + vcam[3] * P[13], + vcam[0] * P[2] + vcam[1] * P[6] + vcam[2] * P[10] + vcam[3] * P[14], + vcam[0] * P[3] + vcam[1] * P[7] + vcam[2] * P[11] + vcam[3] * P[15] + }; + + if (is_zero_exact(vclip[3])) { + return false; + } + + const double w = vclip[3]; + + const double v[3] = { + (vclip[0] / w) * 0.5 + 0.5, + (vclip[1] / w) * 0.5 + 0.5, + (vclip[2] / w) * 0.5 + 0.5 + }; + + out.x = v[0] * viewport[2] + viewport[0]; + out.y = v[1] * viewport[3] + viewport[1]; + out.z = v[2]; + + // map to pixels + out.x = out.x * width * invRealWidth; + out.y = GetHeight() - out.y * height * invRealHeight; + return true; + } + + void Screen::EnterOrtho() + { + PROFILE_SCOPED() + + Graphics::Renderer *r = GetRenderer(); + + modelMatrix = r->GetCurrentModelView(); + projMatrix = r->GetCurrentProjection(); + + r->GetCurrentViewport(&viewport[0]); + r->SetOrthographicProjection(0, width, height, 0, -1, 1); + r->SetTransform(matrix4x4f::Identity()); + } + + void Screen::LeaveOrtho() + { + PROFILE_SCOPED() + + Graphics::Renderer *r = GetRenderer(); + + r->SetProjection(projMatrix); + r->SetTransform(modelMatrix); + } + + void Screen::Draw() + { + PROFILE_SCOPED() + assert(Screen::initted); + EnterOrtho(); + baseContainer->Draw(); + LeaveOrtho(); + } + + bool Screen::IsBaseWidget(const Widget *w) + { + PROFILE_SCOPED() + return w == static_cast(baseContainer); + } + + void Screen::AddBaseWidget(Widget *w, int x, int y) + { + baseContainer->Add(w, float(x), float(y)); + } + + void Screen::RemoveBaseWidget(Widget *w) + { + baseContainer->Remove(w); + } + + void Screen::SDLEventCoordToScreenCoord(int sdlev_x, int sdlev_y, float *x, float *y) + { + *y = sdlev_y * height * invRealHeight; + *x = sdlev_x * width * invRealWidth; + } + + void Screen::OnMouseMotion(SDL_MouseMotionEvent *e) + { + MouseMotionEvent ev; + float x, y; + Screen::SDLEventCoordToScreenCoord(e->x, e->y, &x, &y); + ev.screenX = ev.x = x; + ev.screenY = ev.y = y; + baseContainer->OnMouseMotion(&ev); + ev.screenX = ev.x = x; + ev.screenY = ev.y = y; + RawEvents::onMouseMotion.emit(&ev); + } + + void Screen::OnClick(SDL_MouseButtonEvent *e) + { + MouseButtonEvent ev; + float x, y; + Screen::SDLEventCoordToScreenCoord(e->x, e->y, &x, &y); + ev.button = e->button; + ev.isdown = (e->type == SDL_MOUSEBUTTONDOWN); + ev.screenX = ev.x = x; + ev.screenY = ev.y = y; + if (ev.isdown) { + baseContainer->OnMouseDown(&ev); + RawEvents::onMouseDown.emit(&ev); + } else { + baseContainer->OnMouseUp(&ev); + RawEvents::onMouseUp.emit(&ev); } } -} -void Screen::RenderMarkupBuffer(RefCountedPtr vb, const std::string &s, const Color &color, Text::TextureFont *font) -{ - PROFILE_SCOPED() - if (!font) font = GetFont().Get(); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - - const matrix4x4f &modelMatrix_ = r->GetCurrentModelView(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); - - const float x = modelMatrix_[12]; - const float y = modelMatrix_[13]; - - r->LoadIdentity(); - r->Translate(floor(x/Screen::fontScale[0])*Screen::fontScale[0], floor(y/Screen::fontScale[1])*Screen::fontScale[1], 0); - r->Scale(Screen::fontScale[0], Screen::fontScale[1], 1); - - // temporary, owned by the font - Graphics::VertexBuffer *pVB = font->GetCachedVertexBuffer(s); - if (pVB) { - // found the buffer - font->RenderBuffer(pVB, color); - } - else + void Screen::OnKeyDown(const SDL_Keysym *sym) { - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); - font->PopulateMarkup(va, s.c_str(), 0, 0, color); - - if (va.GetNumVerts() > 0) { - if (!vb.Valid() || vb->GetCapacity() < va.GetNumVerts()) { - vb.Reset(font->CreateVertexBuffer(va, s, true)); - } - - vb->Populate(va); - - font->RenderBuffer(vb.Get()); + if (focusedWidget) { + bool accepted = focusedWidget->OnKeyDown(sym); + // don't check shortcuts if the focused widget accepted the key-press + if (accepted) + return; + } + for (std::list::iterator i = kbshortcut_widgets.begin(); i != kbshortcut_widgets.end(); ++i) { + if (!(*i)->IsVisible()) continue; + if (!(*i)->GetEnabled()) continue; + (*i)->OnPreShortcut(sym); } } -} -void Screen::AddShortcutWidget(Widget *w) -{ - kbshortcut_widgets.push_back(w); -} + void Screen::OnKeyUp(const SDL_Keysym *sym) + { + } -void Screen::RemoveShortcutWidget(Widget *w) -{ - kbshortcut_widgets.remove(w); -} + void Screen::OnTextInput(const SDL_TextInputEvent *e) + { + if (!focusedWidget) return; + Uint32 unicode; + Text::utf8_decode_char(&unicode, e->text); + focusedWidget->OnTextInput(unicode); + } -} + float Screen::GetFontHeight(Text::TextureFont *font) + { + if (!font) font = GetFont().Get(); + + return font->GetHeight() * fontScale[1]; + } + + float Screen::GetFontDescender(Text::TextureFont *font) + { + if (!font) font = GetFont().Get(); + + return font->GetDescender() * fontScale[1]; + } + + void Screen::MeasureString(const std::string &s, float &w, float &h, Text::TextureFont *font) + { + if (!font) font = GetFont().Get(); + assert(font); + + font->MeasureString(s.c_str(), w, h); + w *= fontScale[0]; + h *= fontScale[1]; + } + + void Screen::MeasureCharacterPos(const std::string &s, int charIndex, float &x, float &y, Text::TextureFont *font) + { + assert((charIndex >= 0) && (charIndex <= int(s.size()))); + + if (!font) font = GetFont().Get(); + assert(font); + + font->MeasureCharacterPos(s.c_str(), charIndex, x, y); + x *= fontScale[0]; + y *= fontScale[1]; + } + + int Screen::PickCharacterInString(const std::string &s, float x, float y, Text::TextureFont *font) + { + if (!font) font = GetFont().Get(); + assert(font); + + x /= fontScale[0]; + y /= fontScale[1]; + + return font->PickCharacter(s.c_str(), x, y); + } + + void Screen::RenderStringBuffer(RefCountedPtr vb, const std::string &s, float xoff, float yoff, const Color &color, Text::TextureFont *font) + { + PROFILE_SCOPED() + if (!font) font = GetFont().Get(); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + + const matrix4x4f &modelMatrix_ = r->GetCurrentModelView(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + const float x = modelMatrix_[12] + xoff; + const float y = modelMatrix_[13] + yoff; + + r->LoadIdentity(); + r->Translate(floor(x / Screen::fontScale[0]) * Screen::fontScale[0], floor(y / Screen::fontScale[1]) * Screen::fontScale[1], 0); + r->Scale(Screen::fontScale[0], Screen::fontScale[1], 1); + + // temporary, owned by the font + Graphics::VertexBuffer *pVB = font->GetCachedVertexBuffer(s); + if (pVB) { + // found the buffer + font->RenderBuffer(pVB, color); + } else { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + font->PopulateString(va, s.c_str(), 0, 0, color); + + if (va.GetNumVerts() > 0) { + if (!vb.Valid() || vb->GetCapacity() < va.GetNumVerts()) { + vb.Reset(font->CreateVertexBuffer(va, s, true)); + } + + vb->Populate(va); + + font->RenderBuffer(vb.Get(), color); + } + } + } + + void Screen::RenderMarkupBuffer(RefCountedPtr vb, const std::string &s, const Color &color, Text::TextureFont *font) + { + PROFILE_SCOPED() + if (!font) font = GetFont().Get(); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + + const matrix4x4f &modelMatrix_ = r->GetCurrentModelView(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + const float x = modelMatrix_[12]; + const float y = modelMatrix_[13]; + + r->LoadIdentity(); + r->Translate(floor(x / Screen::fontScale[0]) * Screen::fontScale[0], floor(y / Screen::fontScale[1]) * Screen::fontScale[1], 0); + r->Scale(Screen::fontScale[0], Screen::fontScale[1], 1); + + // temporary, owned by the font + Graphics::VertexBuffer *pVB = font->GetCachedVertexBuffer(s); + if (pVB) { + // found the buffer + font->RenderBuffer(pVB, color); + } else { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + font->PopulateMarkup(va, s.c_str(), 0, 0, color); + + if (va.GetNumVerts() > 0) { + if (!vb.Valid() || vb->GetCapacity() < va.GetNumVerts()) { + vb.Reset(font->CreateVertexBuffer(va, s, true)); + } + + vb->Populate(va); + + font->RenderBuffer(vb.Get()); + } + } + } + + void Screen::AddShortcutWidget(Widget *w) + { + kbshortcut_widgets.push_back(w); + } + + void Screen::RemoveShortcutWidget(Widget *w) + { + kbshortcut_widgets.remove(w); + } + +} // namespace Gui diff --git a/src/gui/GuiScreen.h b/src/gui/GuiScreen.h index 2858e1ba9..cc131354d 100644 --- a/src/gui/GuiScreen.h +++ b/src/gui/GuiScreen.h @@ -4,14 +4,16 @@ #ifndef _GUISCREEN_H #define _GUISCREEN_H -#include "Gui.h" #include "FontCache.h" -#include "text/TextureFont.h" +#include "Gui.h" #include "graphics/RenderState.h" +#include "text/TextureFont.h" #include #include -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} namespace Gui { class Screen { @@ -35,14 +37,16 @@ namespace Gui { friend void Widget::SetShortcut(SDL_Keycode key, SDL_Keymod mod); friend Widget::~Widget(); static bool IsBaseWidget(const Widget *); - static void GetCoords2Pixels(float scale[2]) { + static void GetCoords2Pixels(float scale[2]) + { scale[0] = fontScale[0]; scale[1] = fontScale[1]; } - static const float* GetCoords2Pixels() { return fontScale; } + static const float *GetCoords2Pixels() { return fontScale; } static void SetFocused(Widget *w, bool enableKeyRepeat = false); static void ClearFocus(); - static bool IsFocused(Widget *w) { + static bool IsFocused(Widget *w) + { return w == focusedWidget; } @@ -64,7 +68,7 @@ namespace Gui { static Graphics::Renderer *GetRenderer() { return s_renderer; } static Graphics::RenderState *alphaBlendState; - static Graphics::Material* flatColorMaterial; + static Graphics::Material *flatColorMaterial; private: static void AddShortcutWidget(Widget *w); @@ -75,8 +79,8 @@ namespace Gui { static int width, height; static int realWidth, realHeight; static float invRealWidth, invRealHeight; - static std::list kbshortcut_widgets; - static std::list mouseHoveredWidgets; + static std::list kbshortcut_widgets; + static std::list mouseHoveredWidgets; static float fontScale[2]; static Gui::Fixed *baseContainer; static Gui::Widget *focusedWidget; @@ -86,11 +90,11 @@ namespace Gui { static Sint32 viewport[4]; static FontCache s_fontCache; - static std::stack< RefCountedPtr > s_fontStack; + static std::stack> s_fontStack; static RefCountedPtr s_defaultFont; static Graphics::Renderer *s_renderer; }; -} +} // namespace Gui #endif /* _GUISCREEN_H */ diff --git a/src/gui/GuiStack.cpp b/src/gui/GuiStack.cpp index cc362fe29..3756d31a9 100644 --- a/src/gui/GuiStack.cpp +++ b/src/gui/GuiStack.cpp @@ -1,103 +1,105 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" namespace Gui { -Stack::Stack(): Container() -{ - m_eventMask = EVENT_ALL; -} + Stack::Stack() : + Container() + { + m_eventMask = EVENT_ALL; + } -Stack::~Stack() -{ - Clear(); -} + Stack::~Stack() + { + Clear(); + } -void Stack::GetSizeRequested(float size[2]) -{ - if (m_widgets.empty()) - size[0] = size[1] = 0.0; - else - m_widgets.top()->GetSizeRequested(size); -} + void Stack::GetSizeRequested(float size[2]) + { + if (m_widgets.empty()) + size[0] = size[1] = 0.0; + else + m_widgets.top()->GetSizeRequested(size); + } -void Stack::OnChildResizeRequest(Widget *w) -{ - float container_size[2]; - GetSize(container_size); + void Stack::OnChildResizeRequest(Widget *w) + { + float container_size[2]; + GetSize(container_size); - float widget_size[2]; - w->GetSizeRequested(widget_size); + float widget_size[2]; + w->GetSizeRequested(widget_size); - widget_size[0] = std::min(widget_size[0], container_size[0]); - widget_size[1] = std::min(widget_size[1], container_size[1]); + widget_size[0] = std::min(widget_size[0], container_size[0]); + widget_size[1] = std::min(widget_size[1], container_size[1]); - w->SetSize(widget_size[0], widget_size[1]); -} + w->SetSize(widget_size[0], widget_size[1]); + } -void Stack::UpdateAllChildSizes() -{ - if (m_widgets.empty()) return; + void Stack::UpdateAllChildSizes() + { + if (m_widgets.empty()) return; - OnChildResizeRequest(m_widgets.top()); -} + OnChildResizeRequest(m_widgets.top()); + } -void Stack::ShowAll() -{ - if (!m_widgets.empty()) - m_widgets.top()->ShowAll(); - Show(); -} + void Stack::ShowAll() + { + if (!m_widgets.empty()) + m_widgets.top()->ShowAll(); + Show(); + } -Widget *Stack::Top() -{ - return m_widgets.empty() ? 0 : m_widgets.top(); -} + Widget *Stack::Top() + { + return m_widgets.empty() ? 0 : m_widgets.top(); + } -int Stack::Size() -{ - return m_widgets.size(); -} + int Stack::Size() + { + return m_widgets.size(); + } -void Stack::Push(Widget *w) -{ - if (!m_widgets.empty()) - m_widgets.top()->Hide(); + void Stack::Push(Widget *w) + { + if (!m_widgets.empty()) + m_widgets.top()->Hide(); - m_widgets.push(w); - AppendChild(w,0,0); + m_widgets.push(w); + AppendChild(w, 0, 0); - ResizeRequest(); -} + ResizeRequest(); + } -void Stack::Pop() -{ - if (m_widgets.empty()) return; + void Stack::Pop() + { + if (m_widgets.empty()) return; - Widget *w = m_widgets.top(); - m_widgets.pop(); + Widget *w = m_widgets.top(); + m_widgets.pop(); - RemoveChild(w); - delete w; + RemoveChild(w); + delete w; - ResizeRequest(); -} + ResizeRequest(); + } -void Stack::Clear() -{ - DeleteAllChildren(); - while (!m_widgets.empty()) m_widgets.pop(); + void Stack::Clear() + { + DeleteAllChildren(); + while (!m_widgets.empty()) + m_widgets.pop(); - ResizeRequest(); -} + ResizeRequest(); + } -void Stack::JumpTo(Widget *w) -{ - Clear(); - Push(w); -} + void Stack::JumpTo(Widget *w) + { + Clear(); + Push(w); + } -} +} // namespace Gui diff --git a/src/gui/GuiStack.h b/src/gui/GuiStack.h index dca475415..bcdc86d9a 100644 --- a/src/gui/GuiStack.h +++ b/src/gui/GuiStack.h @@ -4,12 +4,12 @@ #ifndef _GUISTACK_H #define _GUISTACK_H -#include "GuiWidget.h" #include "GuiContainer.h" +#include "GuiWidget.h" #include namespace Gui { - class Stack: public Container { + class Stack : public Container { public: Stack(); virtual ~Stack(); @@ -27,8 +27,8 @@ namespace Gui { virtual void JumpTo(Widget *w); private: - std::stack m_widgets; + std::stack m_widgets; }; -} +} // namespace Gui #endif diff --git a/src/gui/GuiTabbed.cpp b/src/gui/GuiTabbed.cpp index 11b0f59d2..7463ab020 100644 --- a/src/gui/GuiTabbed.cpp +++ b/src/gui/GuiTabbed.cpp @@ -1,188 +1,187 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Gui.h" #include "GuiTabbed.h" +#include "Gui.h" +#include "libs.h" namespace Gui { -static const float TAB_BAR_HEIGHT = 20.0f; -static const float LABEL_PADDING = 10.0f; + static const float TAB_BAR_HEIGHT = 20.0f; + static const float LABEL_PADDING = 10.0f; -Tabbed::Tabbed() -{ - m_eventMask = EVENT_ALL; - m_page = 0; -} + Tabbed::Tabbed() + { + m_eventMask = EVENT_ALL; + m_page = 0; + } -void Tabbed::AddPage(Widget *label, Widget *child) -{ - AppendChild(label, 0, 0); - AppendChild(child, 0, TAB_BAR_HEIGHT); - m_pages.push_back(std::pair(label,child)); - if (m_page != m_pages.size()-1) child->Hide(); - label->Show(); - ShuffleLabels(); -} + void Tabbed::AddPage(Widget *label, Widget *child) + { + AppendChild(label, 0, 0); + AppendChild(child, 0, TAB_BAR_HEIGHT); + m_pages.push_back(std::pair(label, child)); + if (m_page != m_pages.size() - 1) child->Hide(); + label->Show(); + ShuffleLabels(); + } -void Tabbed::Remove(Widget *child) -{ - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); ++i) { - if ((*i).second == child) { - RemoveChild((*i).first); - RemoveChild((*i).second); - m_pages.erase(i); - return; + void Tabbed::Remove(Widget *child) + { + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i) { + if ((*i).second == child) { + RemoveChild((*i).first); + RemoveChild((*i).second); + m_pages.erase(i); + return; + } } } -} -void Tabbed::GetSizeRequested(float size[2]) -{ -} + void Tabbed::GetSizeRequested(float size[2]) + { + } -void Tabbed::SelectPage(int page) -{ - m_page = page; - Show(); -} + void Tabbed::SelectPage(int page) + { + m_page = page; + Show(); + } -void Tabbed::OnActivate() -{ - SelectPage((m_page+1)%m_pages.size()); -} + void Tabbed::OnActivate() + { + SelectPage((m_page + 1) % m_pages.size()); + } -bool Tabbed::OnMouseDown(MouseButtonEvent *e) -{ - if ((e->button == SDL_BUTTON_LEFT) && (e->y < TAB_BAR_HEIGHT)) { - float xpos = 0.0; + bool Tabbed::OnMouseDown(MouseButtonEvent *e) + { + if ((e->button == SDL_BUTTON_LEFT) && (e->y < TAB_BAR_HEIGHT)) { + float xpos = 0.0; + int index = 0; + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); + ++i, index++) { + float csize[2]; + (*i).first->GetSize(csize); + csize[0] += 2 * LABEL_PADDING; + if (e->x - xpos < csize[0]) { + SelectPage(index); + onSelectPage.emit(index); + break; + } + xpos += csize[0]; + } + return false; + } else { + return Container::OnMouseDown(e); + } + } + + void Tabbed::ShuffleLabels() + { + float xpos = LABEL_PADDING; int index = 0; - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); - ++i, index++) { + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i, index++) { + Container::MoveChild((*i).first, xpos, 0); float csize[2]; (*i).first->GetSize(csize); - csize[0] += 2*LABEL_PADDING; - if (e->x - xpos < csize[0]) { - SelectPage(index); - onSelectPage.emit(index); - break; + xpos += csize[0] + 2 * LABEL_PADDING; + } + } + + void Tabbed::OnChildResizeRequest(Widget *child) + { + if (IsLabelWidget(child)) { + float size[2], rsize[2]; + GetSize(size); + rsize[0] = size[0]; + rsize[1] = TAB_BAR_HEIGHT; + child->GetSizeRequested(rsize); + rsize[0] = std::min(rsize[0], size[0]); + rsize[1] = std::min(rsize[1], TAB_BAR_HEIGHT); + child->SetSize(rsize[0], rsize[1]); + ShuffleLabels(); + } else { + float size[2], rsize[2]; + GetSize(size); + rsize[0] = size[0]; + rsize[1] = size[1] - TAB_BAR_HEIGHT; + child->GetSizeRequested(rsize); + rsize[0] = std::min(rsize[0], size[0]); + child->SetSize(rsize[0], rsize[1]); + } + } + + void Tabbed::UpdateAllChildSizes() + { + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i) { + OnChildResizeRequest((*i).first); + OnChildResizeRequest((*i).second); + } + } + + void Tabbed::Show() + { + unsigned int index = 0; + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i, index++) { + (*i).first->Show(); + if (index == m_page) + (*i).second->Show(); + else + (*i).second->Hide(); + } + Container::Show(); + } + + void Tabbed::Hide() + { + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i) { + (*i).first->Hide(); + (*i).second->Hide(); + } + Widget::Hide(); + } + + bool Tabbed::IsLabelWidget(const Widget *w) + { + for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i) { + if ((*i).first == w) return true; + } + return false; + } + + void Tabbed::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + float xpos = 0; + unsigned int index = 0; + + if (!m_rectBGShadow) { + m_rectBGShadow.reset(new Graphics::Drawables::Rect(Screen::GetRenderer(), vector2f(0.f), vector2f(size[0], TAB_BAR_HEIGHT), Theme::Colors::bgShadow, Screen::alphaBlendState)); + } + m_rectBGShadow->Draw(Screen::GetRenderer()); + + for (pagecontainer_t::iterator i = m_pages.begin(), iEnd = m_pages.end(); i != iEnd; ++i, index++) { + float csize[2]; + (*i).first->GetSize(csize); + csize[0] += 2 * LABEL_PADDING; + if (index == m_page) { + vector2f newpos(xpos, 0.f); + vector2f newsize(xpos + csize[0], TAB_BAR_HEIGHT); + if (!BGVBTracker_.m_rectBG || !BGVBTracker_.prevPos_.ExactlyEqual(newpos) || !BGVBTracker_.prevSize_.ExactlyEqual(newsize)) { + BGVBTracker_.prevPos_ = newpos; + BGVBTracker_.prevSize_ = newsize; + BGVBTracker_.m_rectBG.reset(new Graphics::Drawables::Rect(Screen::GetRenderer(), newpos, newsize, Theme::Colors::bg, Screen::alphaBlendState, false)); + } else { + BGVBTracker_.m_rectBG->Update(newpos, newsize, Theme::Colors::bg); + } + BGVBTracker_.m_rectBG->Draw(Screen::GetRenderer()); } xpos += csize[0]; } - return false; - } else { - return Container::OnMouseDown(e); + //AppendChild(label, m_pages.size()*50 + (2*m_pages.size()+1)*LABEL_PADDING, 0); + Container::Draw(); } -} -void Tabbed::ShuffleLabels() -{ - float xpos = LABEL_PADDING; - int index=0; - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); ++i, index++) { - Container::MoveChild((*i).first, xpos, 0); - float csize[2]; - (*i).first->GetSize(csize); - xpos += csize[0] + 2*LABEL_PADDING; - } -} - -void Tabbed::OnChildResizeRequest(Widget *child) -{ - if (IsLabelWidget(child)) { - float size[2], rsize[2]; - GetSize(size); - rsize[0] = size[0]; - rsize[1] = TAB_BAR_HEIGHT; - child->GetSizeRequested(rsize); - rsize[0] = std::min(rsize[0], size[0]); - rsize[1] = std::min(rsize[1], TAB_BAR_HEIGHT); - child->SetSize(rsize[0], rsize[1]); - ShuffleLabels(); - } else { - float size[2], rsize[2]; - GetSize(size); - rsize[0] = size[0]; - rsize[1] = size[1] - TAB_BAR_HEIGHT; - child->GetSizeRequested(rsize); - rsize[0] = std::min(rsize[0], size[0]); - child->SetSize(rsize[0], rsize[1]); - } -} - -void Tabbed::UpdateAllChildSizes() -{ - for (pagecontainer_t::iterator i = m_pages.begin(); i != m_pages.end(); ++i) { - OnChildResizeRequest((*i).first); - OnChildResizeRequest((*i).second); - } -} - -void Tabbed::Show() -{ - unsigned int index=0; - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); ++i, index++) { - (*i).first->Show(); - if (index == m_page) (*i).second->Show(); - else (*i).second->Hide(); - } - Container::Show(); -} - -void Tabbed::Hide() -{ - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); ++i) { - (*i).first->Hide(); - (*i).second->Hide(); - } - Widget::Hide(); -} - -bool Tabbed::IsLabelWidget(const Widget *w) -{ - for (pagecontainer_t::iterator i = m_pages.begin(); i!=m_pages.end(); ++i) { - if ((*i).first == w) return true; - } - return false; -} - -void Tabbed::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - float xpos = 0; - unsigned int index = 0; - - if(!m_rectBGShadow) { - m_rectBGShadow.reset( new Graphics::Drawables::Rect(Screen::GetRenderer(), vector2f(0.f), vector2f(size[0], TAB_BAR_HEIGHT), Theme::Colors::bgShadow, Screen::alphaBlendState) ); - } - m_rectBGShadow->Draw(Screen::GetRenderer()); - - for (pagecontainer_t::iterator i = m_pages.begin(), iEnd = m_pages.end(); i!=iEnd; ++i, index++) - { - float csize[2]; - (*i).first->GetSize(csize); - csize[0] += 2*LABEL_PADDING; - if (index == m_page) { - vector2f newpos(xpos, 0.f); - vector2f newsize(xpos+csize[0], TAB_BAR_HEIGHT); - if(!BGVBTracker_.m_rectBG || !BGVBTracker_.prevPos_.ExactlyEqual(newpos) || !BGVBTracker_.prevSize_.ExactlyEqual(newsize)) { - BGVBTracker_.prevPos_ = newpos; - BGVBTracker_.prevSize_ = newsize; - BGVBTracker_.m_rectBG.reset( new Graphics::Drawables::Rect(Screen::GetRenderer(), newpos, newsize, Theme::Colors::bg, Screen::alphaBlendState, false) ); - } - else - { - BGVBTracker_.m_rectBG->Update(newpos, newsize, Theme::Colors::bg); - } - BGVBTracker_.m_rectBG->Draw(Screen::GetRenderer()); - } - xpos += csize[0]; - } - //AppendChild(label, m_pages.size()*50 + (2*m_pages.size()+1)*LABEL_PADDING, 0); - Container::Draw(); -} - -} +} // namespace Gui diff --git a/src/gui/GuiTabbed.h b/src/gui/GuiTabbed.h index 039a9bbab..8ae8840ea 100644 --- a/src/gui/GuiTabbed.h +++ b/src/gui/GuiTabbed.h @@ -7,8 +7,7 @@ #include "GuiContainer.h" namespace Gui { - class Tabbed: public Container - { + class Tabbed : public Container { public: Tabbed(); void AddPage(Widget *label, Widget *child); @@ -22,12 +21,13 @@ namespace Gui { virtual bool OnMouseDown(MouseButtonEvent *e); void SelectPage(int page); int GetCurrentPage() const { return m_page; } - sigc::signal onSelectPage; + sigc::signal onSelectPage; virtual void OnActivate(); + private: bool IsLabelWidget(const Widget *); void ShuffleLabels(); - typedef std::list< std::pair > pagecontainer_t; + typedef std::list> pagecontainer_t; pagecontainer_t m_pages; unsigned int m_page; std::unique_ptr m_rectBGShadow; @@ -37,6 +37,6 @@ namespace Gui { std::unique_ptr m_rectBG; } BGVBTracker_; }; -} +} // namespace Gui #endif /* _GUITABBED_H */ diff --git a/src/gui/GuiTextEntry.cpp b/src/gui/GuiTextEntry.cpp index 40beb3771..0f1c9217c 100644 --- a/src/gui/GuiTextEntry.cpp +++ b/src/gui/GuiTextEntry.cpp @@ -1,120 +1,120 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" -#include "text/TextureFont.h" +#include "libs.h" #include "text/TextSupport.h" +#include "text/TextureFont.h" namespace Gui { -TextEntry::TextEntry() -{ - m_eventMask = EVENT_MOUSEDOWN; - m_cursPos = 0; - m_scroll = 0; - m_font = Gui::Screen::GetFont(); - m_newlineMode = IgnoreNewline; - m_newlineCount = 0; -} - -TextEntry::~TextEntry() -{ - m_clickout.disconnect(); -} - -void TextEntry::SetText(const std::string &text) -{ - m_text = text; - SetCursorPos(m_text.size()); - - int count = 0; - for (int i = 0; i < int(text.size()); ++i) { - if (text[i] == '\n') - ++count; + TextEntry::TextEntry() + { + m_eventMask = EVENT_MOUSEDOWN; + m_cursPos = 0; + m_scroll = 0; + m_font = Gui::Screen::GetFont(); + m_newlineMode = IgnoreNewline; + m_newlineCount = 0; } - m_newlineCount = count; - ResizeRequest(); -} -bool TextEntry::OnKeyDown(const SDL_Keysym *sym) -{ - bool accepted = false; - bool changed = false; + TextEntry::~TextEntry() + { + m_clickout.disconnect(); + } - int oldNewlineCount = m_newlineCount; + void TextEntry::SetText(const std::string &text) + { + m_text = text; + SetCursorPos(m_text.size()); - // XXX moving the cursor is not UTF-8 safe - if (sym->sym == SDLK_LEFT || sym->sym == SDLK_RIGHT) { - bool forward = (sym->sym == SDLK_RIGHT); - int direction = (forward) ? 1 : -1; - if (!(sym->mod & KMOD_CTRL)) { - SetCursorPos(m_cursPos + direction); - } else { - int inspect_offset = (forward) ? 0 : -1; // When going back, we need the character before the cursor. - int ending = (forward) ? m_text.size() : 0; - int current = m_cursPos+inspect_offset; - bool found_word = false; + int count = 0; + for (int i = 0; i < int(text.size()); ++i) { + if (text[i] == '\n') + ++count; + } + m_newlineCount = count; + ResizeRequest(); + } - while(current != ending) { - bool alphanum; + bool TextEntry::OnKeyDown(const SDL_Keysym *sym) + { + bool accepted = false; + bool changed = false; - alphanum = Text::is_alphanumunderscore(m_text[current]); + int oldNewlineCount = m_newlineCount; - if (found_word && !alphanum) { // Word boundary. - current -= inspect_offset; // Make up for the initial offset. - break; + // XXX moving the cursor is not UTF-8 safe + if (sym->sym == SDLK_LEFT || sym->sym == SDLK_RIGHT) { + bool forward = (sym->sym == SDLK_RIGHT); + int direction = (forward) ? 1 : -1; + if (!(sym->mod & KMOD_CTRL)) { + SetCursorPos(m_cursPos + direction); + } else { + int inspect_offset = (forward) ? 0 : -1; // When going back, we need the character before the cursor. + int ending = (forward) ? m_text.size() : 0; + int current = m_cursPos + inspect_offset; + bool found_word = false; + + while (current != ending) { + bool alphanum; + + alphanum = Text::is_alphanumunderscore(m_text[current]); + + if (found_word && !alphanum) { // Word boundary. + current -= inspect_offset; // Make up for the initial offset. + break; + } + current += direction; + found_word = found_word || alphanum; // You need to be in a word before finding its boudaries. } - current += direction; - found_word = found_word || alphanum; // You need to be in a word before finding its boudaries. + SetCursorPos(current); } - SetCursorPos(current); + accepted = true; } - accepted = true; - } - if (sym->sym == SDLK_BACKSPACE) { - if (m_cursPos > 0) { - if (m_text[m_cursPos-1] == '\n') - --m_newlineCount; - const char *cstr = m_text.c_str(); - const int len = Text::utf8_prev_char_offset(cstr + m_cursPos, cstr); - m_text = m_text.substr(0, m_cursPos-len) + m_text.substr(m_cursPos); - SetCursorPos(m_cursPos-len); - changed = true; + if (sym->sym == SDLK_BACKSPACE) { + if (m_cursPos > 0) { + if (m_text[m_cursPos - 1] == '\n') + --m_newlineCount; + const char *cstr = m_text.c_str(); + const int len = Text::utf8_prev_char_offset(cstr + m_cursPos, cstr); + m_text = m_text.substr(0, m_cursPos - len) + m_text.substr(m_cursPos); + SetCursorPos(m_cursPos - len); + changed = true; + } + accepted = true; } - accepted = true; - } - if (sym->sym == SDLK_DELETE) { - if (m_cursPos < signed(m_text.size())) { - if (m_text[m_cursPos] == '\n') - --m_newlineCount; - const char *cstr = m_text.c_str(); - const int len = Text::utf8_next_char_offset(cstr + m_cursPos); - m_text = m_text.substr(0, m_cursPos) + m_text.substr(m_cursPos+len); - changed = true; + if (sym->sym == SDLK_DELETE) { + if (m_cursPos < signed(m_text.size())) { + if (m_text[m_cursPos] == '\n') + --m_newlineCount; + const char *cstr = m_text.c_str(); + const int len = Text::utf8_next_char_offset(cstr + m_cursPos); + m_text = m_text.substr(0, m_cursPos) + m_text.substr(m_cursPos + len); + changed = true; + } + accepted = true; } - accepted = true; - } - if (sym->sym == SDLK_HOME) { - size_t pos = m_text.rfind('\n', std::max(m_cursPos-1, 0)); - if (pos == std::string::npos) - pos = 0; - else - ++pos; - m_cursPos = int(pos); - accepted = true; - } - if (sym->sym == SDLK_END) { - size_t pos = m_text.find('\n', m_cursPos); - if (pos == std::string::npos) - pos = m_text.size(); - m_cursPos = int(pos); - accepted = true; - } - if (sym->sym == SDLK_RETURN) { - switch (m_newlineMode) { + if (sym->sym == SDLK_HOME) { + size_t pos = m_text.rfind('\n', std::max(m_cursPos - 1, 0)); + if (pos == std::string::npos) + pos = 0; + else + ++pos; + m_cursPos = int(pos); + accepted = true; + } + if (sym->sym == SDLK_END) { + size_t pos = m_text.find('\n', m_cursPos); + if (pos == std::string::npos) + pos = m_text.size(); + m_cursPos = int(pos); + accepted = true; + } + if (sym->sym == SDLK_RETURN) { + switch (m_newlineMode) { case IgnoreNewline: accepted = false; break; @@ -124,136 +124,136 @@ bool TextEntry::OnKeyDown(const SDL_Keysym *sym) case AcceptCtrlNewline: accepted = sym->mod & KMOD_CTRL; break; + } + if (accepted) { + ++m_newlineCount; + OnTextInput('\n'); + } } - if (accepted) { - ++m_newlineCount; - OnTextInput('\n'); + + if (oldNewlineCount != m_newlineCount) + ResizeRequest(); + + onKeyPress.emit(sym); + if (changed) onValueChanged.emit(); + + return accepted; + } + + void TextEntry::OnTextInput(Uint32 unicode) + { + bool changed = false; + + if (isgraph(unicode) || (unicode == ' ') || (unicode == '\n')) { + char buf[4]; + int len = Text::utf8_encode_char(unicode, buf); + m_text.insert(m_cursPos, buf, len); + SetCursorPos(m_cursPos + len); + changed = true; } + + if (changed) onValueChanged.emit(); } - if (oldNewlineCount != m_newlineCount) - ResizeRequest(); - - onKeyPress.emit(sym); - if (changed) onValueChanged.emit(); - - return accepted; -} - -void TextEntry::OnTextInput(Uint32 unicode) -{ - bool changed = false; - - if (isgraph(unicode) || (unicode == ' ') || (unicode == '\n')) { - char buf[4]; - int len = Text::utf8_encode_char(unicode, buf); - m_text.insert(m_cursPos, buf, len); - SetCursorPos(m_cursPos+len); - changed = true; + void TextEntry::GetSizeRequested(float size[2]) + { + size[1] = Gui::Screen::GetFontHeight(m_font.Get()) * (m_newlineCount + 1) + Gui::Screen::GetFontDescender(m_font.Get()); } - if (changed) onValueChanged.emit(); -} + bool TextEntry::OnMouseDown(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + m_clickout = RawEvents::onMouseDown.connect(sigc::mem_fun(this, &TextEntry::OnRawMouseDown)); + GrabFocus(); + m_justFocused = true; -void TextEntry::GetSizeRequested(float size[2]) -{ - size[1] = Gui::Screen::GetFontHeight(m_font.Get()) * (m_newlineCount+1) + Gui::Screen::GetFontDescender(m_font.Get()); -} + int i = Gui::Screen::PickCharacterInString(m_text, e->x - m_scroll, e->y, m_font.Get()); + SetCursorPos(i); -bool TextEntry::OnMouseDown(MouseButtonEvent *e) -{ - if (e->button == SDL_BUTTON_LEFT) { - m_clickout = RawEvents::onMouseDown.connect(sigc::mem_fun(this, &TextEntry::OnRawMouseDown)); - GrabFocus(); - m_justFocused = true; - - int i = Gui::Screen::PickCharacterInString(m_text, e->x - m_scroll, e->y, m_font.Get()); - SetCursorPos(i); - - return false; - } else - return true; -} - -void TextEntry::OnRawMouseDown(MouseButtonEvent *e) -{ - if (!m_justFocused) - Unfocus(); -} - -void TextEntry::GrabFocus() -{ - Screen::SetFocused(this, true); - // XXX should this be here? or somewhere else? - // In some places (at least the Lua console and the sector view search box), - // a keyboard shortcut is used to switch to the text entry widget. - // Pressing '`' opens the console, pressing '/' in the sector view selects the search box. - // Those are normal text keys, so SDL generates an SDL_TEXTINPUT event for them. - // But we don't want to capture that text, because it's not really text input - // (it happens "before" the text entry widget gets focus) - // So we flush those events from the queue here. - SDL_FlushEvents(SDL_TEXTEDITING, SDL_TEXTINPUT); -} - -void TextEntry::Unfocus() -{ - if (!Screen::IsFocused(this)) - return; - Screen::ClearFocus(); - m_clickout.disconnect(); - SetCursorPos(0); -} - -void TextEntry::Draw() -{ - PROFILE_SCOPED() - m_justFocused = false; - - Graphics::Renderer *pRenderer = Screen::GetRenderer(); - - float size[2]; - GetSize(size); - - // find cursor position - float curs_x, curs_y; - Gui::Screen::MeasureCharacterPos(m_text, m_cursPos, curs_x, curs_y, m_font.Get()); - - if (curs_x - m_scroll > size[0]*0.75f) { - m_scroll += int(size[0]*0.25f); - } else if (curs_x - m_scroll < size[0]*0.25f) { - m_scroll -= int(size[0]*0.25f); - if (m_scroll < 0) m_scroll = 0; + return false; + } else + return true; } - //background - if(!m_background) { - m_background.reset( new Graphics::Drawables::Rect(pRenderer, vector2f(0.f), vector2f(size[0], size[1]), Color(0,0,0,192), Screen::alphaBlendState)); + void TextEntry::OnRawMouseDown(MouseButtonEvent *e) + { + if (!m_justFocused) + Unfocus(); } - m_background->Draw(pRenderer); - //outline - const Color c = IsFocused() ? Color::WHITE : Color(192, 192, 192, 255); - const vector3f boxVts[] = { - vector3f(0.f, 0.f, 0.f), - vector3f(size[0],0.f, 0.f), - vector3f(size[0],size[1], 0.f), - vector3f(0,size[1], 0.f) - }; - m_outlines.SetData(2, &boxVts[0], c); - m_outlines.Draw(pRenderer, Screen::alphaBlendState, Graphics::LINE_LOOP); + void TextEntry::GrabFocus() + { + Screen::SetFocused(this, true); + // XXX should this be here? or somewhere else? + // In some places (at least the Lua console and the sector view search box), + // a keyboard shortcut is used to switch to the text entry widget. + // Pressing '`' opens the console, pressing '/' in the sector view selects the search box. + // Those are normal text keys, so SDL generates an SDL_TEXTINPUT event for them. + // But we don't want to capture that text, because it's not really text input + // (it happens "before" the text entry widget gets focus) + // So we flush those events from the queue here. + SDL_FlushEvents(SDL_TEXTEDITING, SDL_TEXTINPUT); + } - //text - SetScissor(true); - Gui::Screen::RenderStringBuffer(m_vb, m_text, 1.0f - m_scroll, 0.0f, c, m_font.Get()); - SetScissor(false); + void TextEntry::Unfocus() + { + if (!Screen::IsFocused(this)) + return; + Screen::ClearFocus(); + m_clickout.disconnect(); + SetCursorPos(0); + } - //cursor - const vector3f cursorVts[] = { - vector3f(curs_x + 1.0f - m_scroll, curs_y + Gui::Screen::GetFontDescender(m_font.Get()) - Gui::Screen::GetFontHeight(m_font.Get()), 0.f), - vector3f(curs_x + 1.0f - m_scroll, curs_y + Gui::Screen::GetFontDescender(m_font.Get()), 0.f), - }; - m_cursorLines.SetData(2, &cursorVts[0], Color(128, 128, 128)); - m_cursorLines.Draw(pRenderer, Screen::alphaBlendState); -} + void TextEntry::Draw() + { + PROFILE_SCOPED() + m_justFocused = false; + + Graphics::Renderer *pRenderer = Screen::GetRenderer(); + + float size[2]; + GetSize(size); + + // find cursor position + float curs_x, curs_y; + Gui::Screen::MeasureCharacterPos(m_text, m_cursPos, curs_x, curs_y, m_font.Get()); + + if (curs_x - m_scroll > size[0] * 0.75f) { + m_scroll += int(size[0] * 0.25f); + } else if (curs_x - m_scroll < size[0] * 0.25f) { + m_scroll -= int(size[0] * 0.25f); + if (m_scroll < 0) m_scroll = 0; + } + + //background + if (!m_background) { + m_background.reset(new Graphics::Drawables::Rect(pRenderer, vector2f(0.f), vector2f(size[0], size[1]), Color(0, 0, 0, 192), Screen::alphaBlendState)); + } + m_background->Draw(pRenderer); + + //outline + const Color c = IsFocused() ? Color::WHITE : Color(192, 192, 192, 255); + const vector3f boxVts[] = { + vector3f(0.f, 0.f, 0.f), + vector3f(size[0], 0.f, 0.f), + vector3f(size[0], size[1], 0.f), + vector3f(0, size[1], 0.f) + }; + m_outlines.SetData(2, &boxVts[0], c); + m_outlines.Draw(pRenderer, Screen::alphaBlendState, Graphics::LINE_LOOP); + + //text + SetScissor(true); + Gui::Screen::RenderStringBuffer(m_vb, m_text, 1.0f - m_scroll, 0.0f, c, m_font.Get()); + SetScissor(false); + + //cursor + const vector3f cursorVts[] = { + vector3f(curs_x + 1.0f - m_scroll, curs_y + Gui::Screen::GetFontDescender(m_font.Get()) - Gui::Screen::GetFontHeight(m_font.Get()), 0.f), + vector3f(curs_x + 1.0f - m_scroll, curs_y + Gui::Screen::GetFontDescender(m_font.Get()), 0.f), + }; + m_cursorLines.SetData(2, &cursorVts[0], Color(128, 128, 128)); + m_cursorLines.Draw(pRenderer, Screen::alphaBlendState); + } } /* namespace Gui */ diff --git a/src/gui/GuiTextEntry.h b/src/gui/GuiTextEntry.h index d0585a15b..8a4fa211e 100644 --- a/src/gui/GuiTextEntry.h +++ b/src/gui/GuiTextEntry.h @@ -7,10 +7,12 @@ #include "GuiWidget.h" #include -namespace Text { class TextureFont; } +namespace Text { + class TextureFont; +} namespace Gui { - class TextEntry: public Widget { + class TextEntry : public Widget { public: enum NewlineMode { IgnoreNewline, @@ -29,16 +31,20 @@ namespace Gui { int GetCursorPos() const { return m_cursPos; }; virtual bool OnKeyDown(const SDL_Keysym *); virtual void OnTextInput(Uint32 unicode); - virtual void Show() { GrabFocus(); Widget::Show(); } + virtual void Show() + { + GrabFocus(); + Widget::Show(); + } virtual void GrabFocus(); void Unfocus(); NewlineMode GetNewlineMode() const { return m_newlineMode; } void SetNewlineMode(NewlineMode mode) { m_newlineMode = mode; } - sigc::signal onKeyPress; + sigc::signal onKeyPress; sigc::signal onValueChanged; - private: + private: void OnRawMouseDown(MouseButtonEvent *e); std::string m_text; @@ -56,6 +62,6 @@ namespace Gui { std::unique_ptr m_background; RefCountedPtr m_vb; }; -} +} // namespace Gui #endif /* _GUITEXTENTRY_H */ diff --git a/src/gui/GuiTextLayout.cpp b/src/gui/GuiTextLayout.cpp index 92c6ce3ea..ba562ef7d 100644 --- a/src/gui/GuiTextLayout.cpp +++ b/src/gui/GuiTextLayout.cpp @@ -9,272 +9,274 @@ static const float PARAGRAPH_SPACING = 1.5f; namespace Gui { -TextLayout::TextLayout(const char *_str, RefCountedPtr font, ColourMarkupMode markup) -{ - // XXX ColourMarkupSkip not correctly implemented yet - assert(markup != ColourMarkupSkip); + TextLayout::TextLayout(const char *_str, RefCountedPtr font, ColourMarkupMode markup) + { + // XXX ColourMarkupSkip not correctly implemented yet + assert(markup != ColourMarkupSkip); - m_colourMarkup = markup; - m_font = font ? font : Gui::Screen::GetFont(); + m_colourMarkup = markup; + m_font = font ? font : Gui::Screen::GetFont(); - SetText(_str); + SetText(_str); - prevWidth = -1.0f; - prevColor = Color::WHITE; -} + prevWidth = -1.0f; + prevColor = Color::WHITE; + } -void TextLayout::SetText(const char *_str) -{ - str = std::string(_str); + void TextLayout::SetText(const char *_str) + { + str = std::string(_str); - m_justify = false; - float wordWidth = 0; - const char *wordstart = str.c_str(); - words.clear(); + m_justify = false; + float wordWidth = 0; + const char *wordstart = str.c_str(); + words.clear(); - int i = 0; - while (str[i]) { - wordWidth = 0; - wordstart = &str[i]; + int i = 0; + while (str[i]) { + wordWidth = 0; + wordstart = &str[i]; - while (str[i] && str[i] != ' ' && str[i] != '\r' && str[i] != '\n') { - /* skip color control code things! */ - if ((m_colourMarkup != ColourMarkupNone) && (str[i] == '#')) { - unsigned int hexcol; - if (sscanf(&str[i], "#%3x", &hexcol)==1) { - i+=4; - continue; + while (str[i] && str[i] != ' ' && str[i] != '\r' && str[i] != '\n') { + /* skip color control code things! */ + if ((m_colourMarkup != ColourMarkupNone) && (str[i] == '#')) { + unsigned int hexcol; + if (sscanf(&str[i], "#%3x", &hexcol) == 1) { + i += 4; + continue; + } } + + Uint32 chr; + int n = Text::utf8_decode_char(&chr, &str[i]); + assert(n); + i += n; + + const Text::TextureFont::Glyph &glyph = m_font->GetGlyph(chr); + wordWidth += glyph.advX; + + // XXX this should do kerning } - Uint32 chr; - int n = Text::utf8_decode_char(&chr, &str[i]); - assert(n); - i += n; + words.push_back(word_t(wordstart, wordWidth)); - const Text::TextureFont::Glyph &glyph = m_font->GetGlyph(chr); - wordWidth += glyph.advX; - - // XXX this should do kerning + if (str[i]) { + if (str[i] == '\n') words.push_back(word_t(0, 0)); + str[i++] = 0; + } } - words.push_back(word_t(wordstart, wordWidth)); + prevWidth = -1.0f; + prevColor = Color::WHITE; + } - if (str[i]) { - if (str[i] == '\n') words.push_back(word_t(0,0)); - str[i++] = 0; + void TextLayout::MeasureSize(const float width, float outSize[2]) const + { + float fontScale[2]; + Gui::Screen::GetCoords2Pixels(fontScale); + _MeasureSizeRaw(width / fontScale[0], outSize); + outSize[0] = ceil(outSize[0] * fontScale[0]); + outSize[1] = ceil(outSize[1] * fontScale[1]); + } + + void TextLayout::Render(const float width, const Color &color) const + { + PROFILE_SCOPED() + if (words.empty()) + return; + + float fontScale[2]; + Gui::Screen::GetCoords2Pixels(fontScale); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + + const matrix4x4f &modelMatrix = r->GetCurrentModelView(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + { + const float x = modelMatrix[12]; + const float y = modelMatrix[13]; + r->LoadIdentity(); + r->Translate(floor(x / fontScale[0]) * fontScale[0], floor(y / fontScale[1]) * fontScale[1], 0); + r->Scale(fontScale[0], fontScale[1], 1); + m_font->RenderBuffer(m_vbuffer.Get(), color); } } - prevWidth = -1.0f; - prevColor = Color::WHITE; -} - -void TextLayout::MeasureSize(const float width, float outSize[2]) const -{ - float fontScale[2]; - Gui::Screen::GetCoords2Pixels(fontScale); - _MeasureSizeRaw(width / fontScale[0], outSize); - outSize[0] = ceil(outSize[0] * fontScale[0]); - outSize[1] = ceil(outSize[1] * fontScale[1]); -} - -void TextLayout::Render(const float width, const Color &color) const -{ - PROFILE_SCOPED() - if(words.empty()) - return; - - float fontScale[2]; - Gui::Screen::GetCoords2Pixels(fontScale); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - - const matrix4x4f &modelMatrix = r->GetCurrentModelView(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + void TextLayout::Update(const float width, const Color &color) { - const float x = modelMatrix[12]; - const float y = modelMatrix[13]; - r->LoadIdentity(); - r->Translate(floor(x/fontScale[0])*fontScale[0], floor(y/fontScale[1])*fontScale[1], 0); - r->Scale(fontScale[0], fontScale[1], 1); - m_font->RenderBuffer( m_vbuffer.Get(), color ); - } -} + PROFILE_SCOPED() + if (words.empty()) { + m_vbuffer.Reset(); + return; + } + // see if anything has changed + if (is_equal_exact(prevWidth, width) && (prevColor == color)) { + return; + } -void TextLayout::Update(const float width, const Color &color) -{ - PROFILE_SCOPED() - if(words.empty()) { - m_vbuffer.Reset(); - return; + prevWidth = width; + prevColor = color; + + float fontScale[2]; + Gui::Screen::GetCoords2Pixels(fontScale); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + + if (r) { + const float maxWidth = width / fontScale[0]; + + float py = 0; + + const float spaceWidth = m_font->GetGlyph(' ').advX; + + Color c = color; + + // vertex array pre-assignment, because TextureFont botches it + // over-reserves for markup, but we don't care + int numChars = 0; + std::list::const_iterator wpos = this->words.begin(); + for (; wpos != this->words.end(); ++wpos) + if ((*wpos).word) numChars += strlen((*wpos).word); + + va.position.reserve(6 * numChars); + va.diffuse.reserve(6 * numChars); + va.uv0.reserve(6 * numChars); + + // build lines of text + wpos = this->words.begin(); + while (wpos != this->words.end()) { + float len = 0; + int num = 0; + + std::list::const_iterator i = wpos; + len += (*i).advx; + num++; + bool overflow = false; + bool explicit_newline = false; + if ((*i).word != 0) { + ++i; + for (; i != this->words.end(); ++i) { + if ((*i).word == 0) { + // newline + explicit_newline = true; + num++; + break; + } + if (len + spaceWidth + (*i).advx > maxWidth) { + overflow = true; + break; + } + len += (*i).advx + spaceWidth; + num++; + } + } + + float _spaceWidth; + if ((m_justify) && (num > 1) && overflow) { + float spaceleft = maxWidth - len; + _spaceWidth = spaceWidth + (spaceleft / float(num - 1)); + } else { + _spaceWidth = spaceWidth; + } + + float px = 0; + for (int j = 0; j < num; j++) { + if ((*wpos).word) { + const std::string word((*wpos).word); + if (m_colourMarkup == ColourMarkupUse) { + Color newColor = m_font->PopulateMarkup(va, word, round(px), round(py), c); + if (!word.empty()) + c = std::move(newColor); + } else + m_font->PopulateString(va, word, round(px), round(py), c); + } + px += (*wpos).advx + _spaceWidth; + ++wpos; + } + py += m_font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : 1.0f); + } + } + + if (va.GetNumVerts() > 0) { + if (!m_vbuffer.Valid() || m_vbuffer->GetCapacity() < va.GetNumVerts()) { + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = va.GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + m_vbuffer.Reset(r->CreateVertexBuffer(vbd)); + } + + m_vbuffer->Populate(va); + } else { + m_vbuffer.Reset(); + } } - // see if anything has changed - if(is_equal_exact(prevWidth,width) && (prevColor==color)) { - return; - } - - prevWidth = width; - prevColor = color; - - float fontScale[2]; - Gui::Screen::GetCoords2Pixels(fontScale); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); - - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); - - if( r ) + void TextLayout::_MeasureSizeRaw(const float layoutWidth, float outSize[2]) const { - const float maxWidth = width / fontScale[0]; - - float py = 0; + outSize[0] = 0; + outSize[1] = 0; const float spaceWidth = m_font->GetGlyph(' ').advX; - Color c = color; - - // vertex array pre-assignment, because TextureFont botches it - // over-reserves for markup, but we don't care - int numChars = 0; - std::list::const_iterator wpos = this->words.begin(); - for (; wpos != this->words.end(); ++wpos) - if ((*wpos).word) numChars += strlen((*wpos).word); - - va.position.reserve(6 * numChars); - va.diffuse.reserve(6 * numChars); - va.uv0.reserve(6 * numChars); - // build lines of text - wpos = this->words.begin(); - while (wpos != this->words.end()) { + for (std::list::const_iterator wpos = words.begin(); wpos != words.end();) { float len = 0; int num = 0; + bool explicit_newline = false; std::list::const_iterator i = wpos; len += (*i).advx; num++; bool overflow = false; - bool explicit_newline = false; if ((*i).word != 0) { ++i; - for (; i != this->words.end(); ++i) { + for (; i != words.end(); ++i) { if ((*i).word == 0) { // newline explicit_newline = true; num++; break; } - if (len + spaceWidth + (*i).advx > maxWidth) { overflow = true; break; } + if (len + spaceWidth + (*i).advx > layoutWidth) { + overflow = true; + break; + } len += (*i).advx + spaceWidth; num++; } } float _spaceWidth; - if ((m_justify) && (num>1) && overflow) { - float spaceleft = maxWidth - len; - _spaceWidth = spaceWidth + (spaceleft/float(num-1)); + if ((m_justify) && (num > 1) && overflow) { + float spaceleft = layoutWidth - len; + _spaceWidth = spaceWidth + (spaceleft / float(num - 1)); } else { _spaceWidth = spaceWidth; } - float px = 0; - for (int j=0; jPopulateMarkup(va, word, round(px), round(py), c); - if(!word.empty()) - c = std::move(newColor); - } - else - m_font->PopulateString(va, word, round(px), round(py), c); - } - px += (*wpos).advx + _spaceWidth; + float lineLen = 0; + for (int j = 0; j < num; j++) { + word_t word = (*wpos); + lineLen += word.advx; + if (j < num - 1) lineLen += _spaceWidth; ++wpos; } - py += m_font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : 1.0f); + if (lineLen > outSize[0]) outSize[0] = lineLen; + outSize[1] += m_font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : 1.0f); } + if (outSize[1] > 0.0f) + outSize[1] += m_font->GetDescender(); } - if( va.GetNumVerts() > 0 ) { - if( !m_vbuffer.Valid() || m_vbuffer->GetCapacity() < va.GetNumVerts() ) { - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = va.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame - m_vbuffer.Reset( r->CreateVertexBuffer(vbd) ); - } - - m_vbuffer->Populate(va); - } else { - m_vbuffer.Reset(); - } -} - -void TextLayout::_MeasureSizeRaw(const float layoutWidth, float outSize[2]) const -{ - outSize[0] = 0; - outSize[1] = 0; - - const float spaceWidth = m_font->GetGlyph(' ').advX; - - // build lines of text - for (std::list::const_iterator wpos = words.begin(); wpos != words.end(); ) { - float len = 0; - int num = 0; - bool explicit_newline = false; - - std::list::const_iterator i = wpos; - len += (*i).advx; - num++; - bool overflow = false; - if ((*i).word != 0) { - ++i; - for (; i != words.end(); ++i) { - if ((*i).word == 0) { - // newline - explicit_newline = true; - num++; - break; - } - if (len + spaceWidth + (*i).advx > layoutWidth) { overflow = true; break; } - len += (*i).advx + spaceWidth; - num++; - } - } - - float _spaceWidth; - if ((m_justify) && (num>1) && overflow) { - float spaceleft = layoutWidth - len; - _spaceWidth = spaceWidth + (spaceleft/float(num-1)); - } else { - _spaceWidth = spaceWidth; - } - - float lineLen = 0; - for (int j=0; j outSize[0]) outSize[0] = lineLen; - outSize[1] += m_font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : 1.0f); - } - if (outSize[1] > 0.0f) - outSize[1] += m_font->GetDescender(); -} - -} +} // namespace Gui diff --git a/src/gui/GuiTextLayout.h b/src/gui/GuiTextLayout.h index d0130ebd8..3d191e128 100644 --- a/src/gui/GuiTextLayout.h +++ b/src/gui/GuiTextLayout.h @@ -11,37 +11,40 @@ namespace Graphics { } namespace Gui { -class TextLayout { -public: - enum ColourMarkupMode { - ColourMarkupNone, // treats markup as normal text - ColourMarkupSkip, // skips markup tags - ColourMarkupUse // interprets markup tags - }; - explicit TextLayout(const char *_str, RefCountedPtr font = RefCountedPtr(0), ColourMarkupMode markup = ColourMarkupUse); - void Render(const float layoutWidth, const Color &color = Color::WHITE) const; - void Update(const float layoutWidth, const Color &color = Color::WHITE); - void SetText(const char *_str); - void MeasureSize(const float layoutWidth, float outSize[2]) const; - void _MeasureSizeRaw(const float layoutWidth, float outSize[2]) const; - void SetJustified(bool v) { m_justify = v; } -private: - struct word_t { - const char *word; - const float advx; - word_t(const char *_word, const float _advx): word(_word), advx(_advx) {} - }; - std::list words; - std::string str; - bool m_justify; - ColourMarkupMode m_colourMarkup; + class TextLayout { + public: + enum ColourMarkupMode { + ColourMarkupNone, // treats markup as normal text + ColourMarkupSkip, // skips markup tags + ColourMarkupUse // interprets markup tags + }; + explicit TextLayout(const char *_str, RefCountedPtr font = RefCountedPtr(0), ColourMarkupMode markup = ColourMarkupUse); + void Render(const float layoutWidth, const Color &color = Color::WHITE) const; + void Update(const float layoutWidth, const Color &color = Color::WHITE); + void SetText(const char *_str); + void MeasureSize(const float layoutWidth, float outSize[2]) const; + void _MeasureSizeRaw(const float layoutWidth, float outSize[2]) const; + void SetJustified(bool v) { m_justify = v; } - float prevWidth; - Color prevColor; + private: + struct word_t { + const char *word; + const float advx; + word_t(const char *_word, const float _advx) : + word(_word), + advx(_advx) {} + }; + std::list words; + std::string str; + bool m_justify; + ColourMarkupMode m_colourMarkup; - RefCountedPtr m_font; - RefCountedPtr m_vbuffer; -}; -} + float prevWidth; + Color prevColor; + + RefCountedPtr m_font; + RefCountedPtr m_vbuffer; + }; +} // namespace Gui #endif /* _GUITEXTLAYOUT_H */ diff --git a/src/gui/GuiTexturedQuad.cpp b/src/gui/GuiTexturedQuad.cpp index b4f9be28d..31058ce2a 100644 --- a/src/gui/GuiTexturedQuad.cpp +++ b/src/gui/GuiTexturedQuad.cpp @@ -2,63 +2,63 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "GuiTexturedQuad.h" -#include "graphics/Renderer.h" -#include "graphics/Material.h" -#include "graphics/VertexArray.h" #include "GuiScreen.h" +#include "graphics/Material.h" +#include "graphics/Renderer.h" +#include "graphics/VertexArray.h" using namespace Graphics; namespace Gui { -void TexturedQuad::Draw(Graphics::Renderer *renderer, const vector2f &pos, const vector2f &size, const vector2f &texPos, const vector2f &texSize, const Color &tint) -{ - PROFILE_SCOPED() - - // Create material on first use. Bit of a hack. - if (!m_material) { - PROFILE_SCOPED_RAW("!material") - Graphics::MaterialDescriptor desc; - desc.textures = 1; - m_material.reset(renderer->CreateMaterial(desc)); - m_material->texture0 = m_texture.Get(); - } - - if(!m_vb.Get()) { - PROFILE_SCOPED_RAW("!m_vb.get()") - Graphics::VertexArray va(ATTRIB_POSITION | ATTRIB_UV0); - - // Size is always the same, modify it's position using the transform - va.Add(vector3f(0.0f, 0.0f, 0.0f), vector2f(texPos.x, texPos.y)); - va.Add(vector3f(0.0f, 0.0f+1.0f, 0.0f), vector2f(texPos.x, texPos.y+texSize.y)); - va.Add(vector3f(0.0f+1.0f, 0.0f, 0.0f), vector2f(texPos.x+texSize.x, texPos.y)); - va.Add(vector3f(0.0f+1.0f, 0.0f+1.0f, 0.0f), vector2f(texPos.x+texSize.x, texPos.y+texSize.y)); - - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = 4; - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - m_vb.Reset(renderer->CreateVertexBuffer(vbd)); - - m_vb->Populate(va); - } - + void TexturedQuad::Draw(Graphics::Renderer *renderer, const vector2f &pos, const vector2f &size, const vector2f &texPos, const vector2f &texSize, const Color &tint) { - // move and scale the quad on-screen - Graphics::Renderer::MatrixTicket mt(renderer, Graphics::MatrixMode::MODELVIEW); - const matrix4x4f& mv = renderer->GetCurrentModelView(); - matrix4x4f trans(matrix4x4f::Translation(vector3f(pos.x, pos.y, 0.0f))); - trans.Scale(size.x, size.y, 0.0f); - renderer->SetTransform(mv * trans); + PROFILE_SCOPED() - m_material->diffuse = tint; - renderer->DrawBuffer(m_vb.Get(), Gui::Screen::alphaBlendState, m_material.get(), TRIANGLE_STRIP); + // Create material on first use. Bit of a hack. + if (!m_material) { + PROFILE_SCOPED_RAW("!material") + Graphics::MaterialDescriptor desc; + desc.textures = 1; + m_material.reset(renderer->CreateMaterial(desc)); + m_material->texture0 = m_texture.Get(); + } + + if (!m_vb.Get()) { + PROFILE_SCOPED_RAW("!m_vb.get()") + Graphics::VertexArray va(ATTRIB_POSITION | ATTRIB_UV0); + + // Size is always the same, modify it's position using the transform + va.Add(vector3f(0.0f, 0.0f, 0.0f), vector2f(texPos.x, texPos.y)); + va.Add(vector3f(0.0f, 0.0f + 1.0f, 0.0f), vector2f(texPos.x, texPos.y + texSize.y)); + va.Add(vector3f(0.0f + 1.0f, 0.0f, 0.0f), vector2f(texPos.x + texSize.x, texPos.y)); + va.Add(vector3f(0.0f + 1.0f, 0.0f + 1.0f, 0.0f), vector2f(texPos.x + texSize.x, texPos.y + texSize.y)); + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = 4; + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + m_vb.Reset(renderer->CreateVertexBuffer(vbd)); + + m_vb->Populate(va); + } + + { + // move and scale the quad on-screen + Graphics::Renderer::MatrixTicket mt(renderer, Graphics::MatrixMode::MODELVIEW); + const matrix4x4f &mv = renderer->GetCurrentModelView(); + matrix4x4f trans(matrix4x4f::Translation(vector3f(pos.x, pos.y, 0.0f))); + trans.Scale(size.x, size.y, 0.0f); + renderer->SetTransform(mv * trans); + + m_material->diffuse = tint; + renderer->DrawBuffer(m_vb.Get(), Gui::Screen::alphaBlendState, m_material.get(), TRIANGLE_STRIP); + } } -} -} +} // namespace Gui diff --git a/src/gui/GuiTexturedQuad.h b/src/gui/GuiTexturedQuad.h index c8436098a..96f3ba707 100644 --- a/src/gui/GuiTexturedQuad.h +++ b/src/gui/GuiTexturedQuad.h @@ -4,38 +4,40 @@ #ifndef _GUITEXTURE_H #define _GUITEXTURE_H -#include "graphics/Texture.h" -#include "graphics/Drawables.h" -#include "RefCounted.h" #include "Color.h" +#include "RefCounted.h" +#include "graphics/Drawables.h" +#include "graphics/Texture.h" namespace Graphics { class Renderer; class Material; class VertexBuffer; -} +} // namespace Graphics namespace Gui { -// a textured quad with reversed winding for the UI -// XXX possibly doesn't belong in Gui::, but its knowledge of reverse-winding -// makes it seem odd for Graphics::Drawables -class TexturedQuad { -public: - TexturedQuad(Graphics::Texture *texture) : m_texture(RefCountedPtr(texture)) {} - virtual ~TexturedQuad() {} - virtual void Draw(Graphics::Renderer *r) { Draw(r, vector2f(0.0f), vector2f(1.0f)); } - void Draw(Graphics::Renderer *r, const Color &tint) { Draw(r, vector2f(0.0f), vector2f(1.0f), tint); } - void Draw(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &tint = Color::WHITE) { Draw(r, pos, size, vector2f(0.0f), m_texture->GetDescriptor().texSize, tint); } - void Draw(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const vector2f &texPos, const vector2f &texSize, const Color &tint = Color::WHITE); + // a textured quad with reversed winding for the UI + // XXX possibly doesn't belong in Gui::, but its knowledge of reverse-winding + // makes it seem odd for Graphics::Drawables + class TexturedQuad { + public: + TexturedQuad(Graphics::Texture *texture) : + m_texture(RefCountedPtr(texture)) {} + virtual ~TexturedQuad() {} + virtual void Draw(Graphics::Renderer *r) { Draw(r, vector2f(0.0f), vector2f(1.0f)); } + void Draw(Graphics::Renderer *r, const Color &tint) { Draw(r, vector2f(0.0f), vector2f(1.0f), tint); } + void Draw(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const Color &tint = Color::WHITE) { Draw(r, pos, size, vector2f(0.0f), m_texture->GetDescriptor().texSize, tint); } + void Draw(Graphics::Renderer *r, const vector2f &pos, const vector2f &size, const vector2f &texPos, const vector2f &texSize, const Color &tint = Color::WHITE); - const Graphics::Texture* GetTexture() const { return m_texture.Get(); } -private: - RefCountedPtr m_texture; - std::unique_ptr m_material; - RefCountedPtr m_vb; -}; + const Graphics::Texture *GetTexture() const { return m_texture.Get(); } -} + private: + RefCountedPtr m_texture; + std::unique_ptr m_material; + RefCountedPtr m_vb; + }; + +} // namespace Gui #endif diff --git a/src/gui/GuiToggleButton.cpp b/src/gui/GuiToggleButton.cpp index 66230b92d..ce0a10739 100644 --- a/src/gui/GuiToggleButton.cpp +++ b/src/gui/GuiToggleButton.cpp @@ -1,21 +1,33 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" static const float BUTTON_SIZE = 16.f; namespace Gui { -ToggleButton::ToggleButton() -{ - m_pressed = false; - SetSize(BUTTON_SIZE, BUTTON_SIZE); -} -bool ToggleButton::OnMouseDown(MouseButtonEvent *e) -{ - if (e->button == SDL_BUTTON_LEFT) { - onPress.emit(); + ToggleButton::ToggleButton() + { + m_pressed = false; + SetSize(BUTTON_SIZE, BUTTON_SIZE); + } + bool ToggleButton::OnMouseDown(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + onPress.emit(); + m_pressed = !m_pressed; + if (m_pressed) { + onChange.emit(this, true); + } else { + onChange.emit(this, false); + } + } + return false; + } + + void ToggleButton::OnActivate() + { m_pressed = !m_pressed; if (m_pressed) { onChange.emit(this, true); @@ -23,35 +35,23 @@ bool ToggleButton::OnMouseDown(MouseButtonEvent *e) onChange.emit(this, false); } } - return false; -} -void ToggleButton::OnActivate() -{ - m_pressed = !m_pressed; - if (m_pressed) { - onChange.emit(this, true); - } else { - onChange.emit(this, false); + void ToggleButton::GetSizeRequested(float size[2]) + { + size[0] = BUTTON_SIZE; + size[1] = BUTTON_SIZE; } -} -void ToggleButton::GetSizeRequested(float size[2]) -{ - size[0] = BUTTON_SIZE; - size[1] = BUTTON_SIZE; -} - -void ToggleButton::Draw() -{ - PROFILE_SCOPED() - float size[2]; - GetSize(size); - if (m_pressed) { - Theme::DrawIndent(size, Screen::alphaBlendState); - } else { - Theme::DrawOutdent(size, Screen::alphaBlendState); + void ToggleButton::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + if (m_pressed) { + Theme::DrawIndent(size, Screen::alphaBlendState); + } else { + Theme::DrawOutdent(size, Screen::alphaBlendState); + } } -} -} +} // namespace Gui diff --git a/src/gui/GuiToggleButton.h b/src/gui/GuiToggleButton.h index a1bdf8a5d..db6a33643 100644 --- a/src/gui/GuiToggleButton.h +++ b/src/gui/GuiToggleButton.h @@ -8,7 +8,7 @@ #include namespace Gui { - class ToggleButton: public Button { + class ToggleButton : public Button { public: ToggleButton(); virtual void Draw(); @@ -20,9 +20,10 @@ namespace Gui { bool GetPressed() { return m_pressed != 0; } sigc::signal onChange; + private: bool m_pressed; }; -} +} // namespace Gui #endif /* _GUITOGGLEBUTTON_H */ diff --git a/src/gui/GuiToolTip.cpp b/src/gui/GuiToolTip.cpp index 6e994bc4e..17435aa5f 100644 --- a/src/gui/GuiToolTip.cpp +++ b/src/gui/GuiToolTip.cpp @@ -5,93 +5,93 @@ namespace Gui { -static const float TOOLTIP_PADDING = 5.f; -static const float FADE_TIME_MS = 500.f; + static const float TOOLTIP_PADDING = 5.f; + static const float FADE_TIME_MS = 500.f; -ToolTip::ToolTip(Widget *owner, const char *text) -{ - m_owner = owner; - m_layout = 0; - SetText(text); - m_createdTime = SDL_GetTicks(); -} - -ToolTip::ToolTip(Widget *owner, std::string &text) -{ - m_owner = owner; - m_layout = 0; - SetText(text.c_str()); - m_createdTime = SDL_GetTicks(); -} - -ToolTip::~ToolTip() -{ - m_layout.reset(); -} - -void ToolTip::CalcSize() -{ - float size[2]; - m_layout->MeasureSize(400.0, size); - size[0] += 2*TOOLTIP_PADDING; - SetSize(size[0], size[1]); - m_layout->Update(size[0]); -} - -void ToolTip::SetText(const char *text) -{ - if (m_text != text) { - m_text = text; - m_layout.reset(new TextLayout(text)); - CalcSize(); + ToolTip::ToolTip(Widget *owner, const char *text) + { + m_owner = owner; + m_layout = 0; + SetText(text); + m_createdTime = SDL_GetTicks(); } -} -void ToolTip::SetText(std::string &text) -{ - SetText(text.c_str()); -} - -void ToolTip::Draw() -{ - PROFILE_SCOPED() - if (m_owner && !m_owner->IsVisible()) - return; - - float size[2]; - const int age = SDL_GetTicks() - m_createdTime; - const float alpha = std::min(age / FADE_TIME_MS, 0.75f); - - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - - GetSize(size); - const Color color(Color4f(0.2f, 0.2f, 0.6f, alpha)); - if(!m_background) { - m_background.reset( new Graphics::Drawables::Rect(r, vector2f(0.f), vector2f(size[0], size[1]), color, Screen::alphaBlendState, false)); + ToolTip::ToolTip(Widget *owner, std::string &text) + { + m_owner = owner; + m_layout = 0; + SetText(text.c_str()); + m_createdTime = SDL_GetTicks(); } - m_background->Update(vector2f(0.f), vector2f(size[0], size[1]), color); - m_background->Draw(r); - const vector3f outlineVts[] = { - vector3f(size[0], 0, 0), - vector3f(size[0], size[1], 0), - vector3f(0, size[1], 0), - vector3f(0, 0, 0) - }; - const Color outlineColor(Color4f(0,0,.8f,alpha)); - m_outlines.SetData(2, &outlineVts[0], outlineColor); - m_outlines.Draw(r, Screen::alphaBlendState, Graphics::LINE_LOOP); + ToolTip::~ToolTip() + { + m_layout.reset(); + } - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + void ToolTip::CalcSize() + { + float size[2]; + m_layout->MeasureSize(400.0, size); + size[0] += 2 * TOOLTIP_PADDING; + SetSize(size[0], size[1]); + m_layout->Update(size[0]); + } - r->Translate(TOOLTIP_PADDING,0,0); - m_layout->Render(size[0]-2*TOOLTIP_PADDING); -} + void ToolTip::SetText(const char *text) + { + if (m_text != text) { + m_text = text; + m_layout.reset(new TextLayout(text)); + CalcSize(); + } + } -void ToolTip::GetSizeRequested(float size[2]) -{ - m_layout->MeasureSize(size[0] - 2*TOOLTIP_PADDING, size); - size[0] += 2*TOOLTIP_PADDING; -} + void ToolTip::SetText(std::string &text) + { + SetText(text.c_str()); + } -} + void ToolTip::Draw() + { + PROFILE_SCOPED() + if (m_owner && !m_owner->IsVisible()) + return; + + float size[2]; + const int age = SDL_GetTicks() - m_createdTime; + const float alpha = std::min(age / FADE_TIME_MS, 0.75f); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + + GetSize(size); + const Color color(Color4f(0.2f, 0.2f, 0.6f, alpha)); + if (!m_background) { + m_background.reset(new Graphics::Drawables::Rect(r, vector2f(0.f), vector2f(size[0], size[1]), color, Screen::alphaBlendState, false)); + } + m_background->Update(vector2f(0.f), vector2f(size[0], size[1]), color); + m_background->Draw(r); + + const vector3f outlineVts[] = { + vector3f(size[0], 0, 0), + vector3f(size[0], size[1], 0), + vector3f(0, size[1], 0), + vector3f(0, 0, 0) + }; + const Color outlineColor(Color4f(0, 0, .8f, alpha)); + m_outlines.SetData(2, &outlineVts[0], outlineColor); + m_outlines.Draw(r, Screen::alphaBlendState, Graphics::LINE_LOOP); + + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + r->Translate(TOOLTIP_PADDING, 0, 0); + m_layout->Render(size[0] - 2 * TOOLTIP_PADDING); + } + + void ToolTip::GetSizeRequested(float size[2]) + { + m_layout->MeasureSize(size[0] - 2 * TOOLTIP_PADDING, size); + size[0] += 2 * TOOLTIP_PADDING; + } + +} // namespace Gui diff --git a/src/gui/GuiToolTip.h b/src/gui/GuiToolTip.h index 93f840974..5340e5534 100644 --- a/src/gui/GuiToolTip.h +++ b/src/gui/GuiToolTip.h @@ -8,7 +8,7 @@ #include namespace Gui { - class ToolTip: public Widget { + class ToolTip : public Widget { public: ToolTip(Widget *owner, const char *text); ToolTip(Widget *owner, std::string &text); @@ -17,6 +17,7 @@ namespace Gui { virtual void GetSizeRequested(float size[2]); void SetText(const char *text); void SetText(std::string &text); + private: void CalcSize(); Widget *m_owner; @@ -26,6 +27,6 @@ namespace Gui { Graphics::Drawables::Lines m_outlines; std::unique_ptr m_background; }; -} +} // namespace Gui #endif /* _GUITOOLTIP_H */ diff --git a/src/gui/GuiVScrollBar.cpp b/src/gui/GuiVScrollBar.cpp index 2258206fa..cbeccdc7e 100644 --- a/src/gui/GuiVScrollBar.cpp +++ b/src/gui/GuiVScrollBar.cpp @@ -1,108 +1,109 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" static const float SCROLLBAR_SIZE = 12.f; static const float BORDER = 2.f; namespace Gui { -ScrollBar::ScrollBar(bool isHoriz) -{ - m_isHoriz = isHoriz; - m_isPressed = false; - m_eventMask = EVENT_MOUSEDOWN; - SetSize(SCROLLBAR_SIZE, SCROLLBAR_SIZE); -} - -ScrollBar::~ScrollBar() -{ - if (_m_release) _m_release.disconnect(); - if (_m_motion) _m_motion.disconnect(); -} - -bool ScrollBar::OnMouseDown(MouseButtonEvent *e) -{ - float size[2]; - GetSize(size); - if (e->button == SDL_BUTTON_LEFT) { - m_isPressed = true; - if (m_isHoriz) { - m_adjustment->SetValue(e->x / float(size[0])); - } else { - m_adjustment->SetValue(e->y / float(size[1])); - } - _m_release = RawEvents::onMouseUp.connect(sigc::mem_fun(this, &ScrollBar::OnRawMouseUp)); - _m_motion = RawEvents::onMouseMotion.connect(sigc::mem_fun(this, &ScrollBar::OnRawMouseMotion)); - } - else if (e->button == MouseButtonEvent::BUTTON_WHEELUP || e->button == MouseButtonEvent::BUTTON_WHEELDOWN) { - float change = e->button == MouseButtonEvent::BUTTON_WHEELUP ? -0.1 : 0.1; - float pos = m_adjustment->GetValue(); - m_adjustment->SetValue(Clamp(pos+change, 0.0f, 1.0f)); - } - return false; -} - -void ScrollBar::OnRawMouseUp(MouseButtonEvent *e) { - if (e->button == SDL_BUTTON_LEFT) { + ScrollBar::ScrollBar(bool isHoriz) + { + m_isHoriz = isHoriz; m_isPressed = false; - _m_release.disconnect(); - _m_motion.disconnect(); + m_eventMask = EVENT_MOUSEDOWN; + SetSize(SCROLLBAR_SIZE, SCROLLBAR_SIZE); } -} -void ScrollBar::OnRawMouseMotion(MouseMotionEvent *e) -{ - if (m_isPressed) { - float pos[2]; - GetAbsolutePosition(pos); + ScrollBar::~ScrollBar() + { + if (_m_release) _m_release.disconnect(); + if (_m_motion) _m_motion.disconnect(); + } + + bool ScrollBar::OnMouseDown(MouseButtonEvent *e) + { float size[2]; GetSize(size); - if (m_isHoriz) { - m_adjustment->SetValue((e->x-pos[0]) / float(size[0])); - } else { - m_adjustment->SetValue((e->y-pos[1]) / float(size[1])); + if (e->button == SDL_BUTTON_LEFT) { + m_isPressed = true; + if (m_isHoriz) { + m_adjustment->SetValue(e->x / float(size[0])); + } else { + m_adjustment->SetValue(e->y / float(size[1])); + } + _m_release = RawEvents::onMouseUp.connect(sigc::mem_fun(this, &ScrollBar::OnRawMouseUp)); + _m_motion = RawEvents::onMouseMotion.connect(sigc::mem_fun(this, &ScrollBar::OnRawMouseMotion)); + } else if (e->button == MouseButtonEvent::BUTTON_WHEELUP || e->button == MouseButtonEvent::BUTTON_WHEELDOWN) { + float change = e->button == MouseButtonEvent::BUTTON_WHEELUP ? -0.1 : 0.1; + float pos = m_adjustment->GetValue(); + m_adjustment->SetValue(Clamp(pos + change, 0.0f, 1.0f)); + } + return false; + } + + void ScrollBar::OnRawMouseUp(MouseButtonEvent *e) + { + if (e->button == SDL_BUTTON_LEFT) { + m_isPressed = false; + _m_release.disconnect(); + _m_motion.disconnect(); } } -} -void ScrollBar::Draw() -{ - PROFILE_SCOPED() - float size[2]; GetSize(size); - Theme::DrawIndent(size, Screen::alphaBlendState); - float pos = m_adjustment->GetValue(); - vector3f lines[2]; - if (m_isHoriz) { - lines[0] = vector3f(BORDER+(size[0]-2*BORDER)*pos, BORDER, 0.f); - lines[1] = vector3f(BORDER+(size[0]-2*BORDER)*pos, size[1]-BORDER, 0.f); - } else { - lines[0] = vector3f(BORDER, BORDER+(size[1]-2*BORDER)*pos, 0.f); - lines[1] = vector3f(size[0]-BORDER, BORDER+(size[1]-2*BORDER)*pos, 0.f); + void ScrollBar::OnRawMouseMotion(MouseMotionEvent *e) + { + if (m_isPressed) { + float pos[2]; + GetAbsolutePosition(pos); + float size[2]; + GetSize(size); + if (m_isHoriz) { + m_adjustment->SetValue((e->x - pos[0]) / float(size[0])); + } else { + m_adjustment->SetValue((e->y - pos[1]) / float(size[1])); + } + } } - m_lines.SetData(2, &lines[0], Color::WHITE); - m_lines.Draw(Screen::GetRenderer(), Screen::alphaBlendState); -} -void ScrollBar::GetSizeRequested(float size[2]) -{ - if (m_isHoriz) { - // full X size, minimal Y size - size[1] = SCROLLBAR_SIZE; - } else { - // full Y size, minimal X size - size[0] = SCROLLBAR_SIZE; + void ScrollBar::Draw() + { + PROFILE_SCOPED() + float size[2]; + GetSize(size); + Theme::DrawIndent(size, Screen::alphaBlendState); + float pos = m_adjustment->GetValue(); + vector3f lines[2]; + if (m_isHoriz) { + lines[0] = vector3f(BORDER + (size[0] - 2 * BORDER) * pos, BORDER, 0.f); + lines[1] = vector3f(BORDER + (size[0] - 2 * BORDER) * pos, size[1] - BORDER, 0.f); + } else { + lines[0] = vector3f(BORDER, BORDER + (size[1] - 2 * BORDER) * pos, 0.f); + lines[1] = vector3f(size[0] - BORDER, BORDER + (size[1] - 2 * BORDER) * pos, 0.f); + } + m_lines.SetData(2, &lines[0], Color::WHITE); + m_lines.Draw(Screen::GetRenderer(), Screen::alphaBlendState); } -} -void ScrollBar::GetMinimumSize(float size[2]) -{ - // who knows what the minimum size size is. odds are good that we're next - // to a VScrollPortal which will provide a sane minimum size and the - // container will sort out the rest - size[0] = size[1] = SCROLLBAR_SIZE; -} + void ScrollBar::GetSizeRequested(float size[2]) + { + if (m_isHoriz) { + // full X size, minimal Y size + size[1] = SCROLLBAR_SIZE; + } else { + // full Y size, minimal X size + size[0] = SCROLLBAR_SIZE; + } + } -} + void ScrollBar::GetMinimumSize(float size[2]) + { + // who knows what the minimum size size is. odds are good that we're next + // to a VScrollPortal which will provide a sane minimum size and the + // container will sort out the rest + size[0] = size[1] = SCROLLBAR_SIZE; + } + +} // namespace Gui diff --git a/src/gui/GuiVScrollBar.h b/src/gui/GuiVScrollBar.h index e22acc5d1..0c47adbf3 100644 --- a/src/gui/GuiVScrollBar.h +++ b/src/gui/GuiVScrollBar.h @@ -7,7 +7,7 @@ #include "GuiWidget.h" namespace Gui { - class ScrollBar: public Widget { + class ScrollBar : public Widget { public: ScrollBar(bool isHoriz); virtual ~ScrollBar(); @@ -15,11 +15,14 @@ namespace Gui { virtual void GetSizeRequested(float size[2]); virtual void GetMinimumSize(float size[2]); virtual void Draw(); - void SetAdjustment(Adjustment *adj) { + void SetAdjustment(Adjustment *adj) + { m_adjustment = adj; } + protected: Adjustment *m_adjustment; + private: void OnRawMouseUp(MouseButtonEvent *e); void OnRawMouseMotion(MouseMotionEvent *e); @@ -28,10 +31,11 @@ namespace Gui { Graphics::Drawables::Lines m_lines; }; - class VScrollBar: public ScrollBar { + class VScrollBar : public ScrollBar { public: - VScrollBar(): ScrollBar(false) {} + VScrollBar() : + ScrollBar(false) {} }; -} +} // namespace Gui #endif /* _GUIVSCROLLBAR */ diff --git a/src/gui/GuiVScrollPortal.cpp b/src/gui/GuiVScrollPortal.cpp index 2e4e69cc5..ba2b56dc2 100644 --- a/src/gui/GuiVScrollPortal.cpp +++ b/src/gui/GuiVScrollPortal.cpp @@ -1,141 +1,139 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "Gui.h" +#include "libs.h" #include "vector2.h" static const float MINIMUM_HEIGHT = 100.0f; namespace Gui { -VScrollPortal::VScrollPortal(float forceWidth): - Container(), - m_forceWidth(forceWidth), - m_child(0) -{ - m_eventMask = EVENT_ALL; -} - -VScrollPortal::VScrollPortal(): - Container(), - m_forceWidth(0), - m_child(0) -{ - m_eventMask = EVENT_ALL; -} - -void VScrollPortal::GetSizeRequested(float size[2]) -{ - if (m_child) - m_child->GetSizeRequested(size); - else - size[0] = size[1] = 0; - - if (m_forceWidth > 0.0f) size[0] = m_forceWidth; -} - -void VScrollPortal::GetMinimumSize(float size[2]) -{ - if (m_child) { - m_child->GetSizeRequested(size); - size[1] = std::min(size[1], MINIMUM_HEIGHT); - } - else - size[0] = size[1] = 0; - - if (m_forceWidth > 0.0f) size[0] = m_forceWidth; -} - -void VScrollPortal::OnChildResizeRequest(Widget *child) -{ - assert(child == m_child); - float size[2], rsize[2]; - GetSize(size); - rsize[0] = size[0]; - rsize[1] = FLT_MAX; - child->GetSizeRequested(rsize); - rsize[0] = std::min(rsize[0], size[0]); - m_childSizeY = rsize[1]; - child->SetSize(rsize[0], rsize[1]); -} - -void VScrollPortal::UpdateAllChildSizes() -{ - if (m_child) OnChildResizeRequest(m_child); -} - -void VScrollPortal::Add(Widget *child) -{ - assert(m_child == 0); - m_child = child; - AppendChild(child, 0, 0); - OnChildResizeRequest(child); -} - -void VScrollPortal::Remove(Widget *child) -{ - assert(m_child == child); - Container::RemoveChild(child); - m_child = 0; - m_childSizeY = 0; -} - -float VScrollPortal::GetScrollPixels() -{ - float size[2]; - GetSize(size); - return m_scrollY*((m_childSizeY-size[1]) > 0 ? (m_childSizeY-size[1]) : 0); -} - -bool VScrollPortal::OnMouseDown(MouseButtonEvent *e) -{ - if (e->button == MouseButtonEvent::BUTTON_WHEELUP || e->button == MouseButtonEvent::BUTTON_WHEELDOWN) { - float change = e->button == MouseButtonEvent::BUTTON_WHEELUP ? -0.1 : 0.1; - float pos = vscrollAdjust.GetValue(); - vscrollAdjust.SetValue(Clamp(pos+change, 0.0f, 1.0f)); - return false; + VScrollPortal::VScrollPortal(float forceWidth) : + Container(), + m_forceWidth(forceWidth), + m_child(0) + { + m_eventMask = EVENT_ALL; } - e->y += GetScrollPixels(); - return Container::OnMouseDown(e); -} -bool VScrollPortal::OnMouseUp(MouseButtonEvent *e) -{ - e->y += GetScrollPixels(); - return Container::OnMouseUp(e); -} -bool VScrollPortal::OnMouseMotion(MouseMotionEvent *e) -{ - e->y += GetScrollPixels(); - return Container::OnMouseMotion(e); -} + VScrollPortal::VScrollPortal() : + Container(), + m_forceWidth(0), + m_child(0) + { + m_eventMask = EVENT_ALL; + } -void VScrollPortal::Draw() -{ - PROFILE_SCOPED() - SetScissor(true); + void VScrollPortal::GetSizeRequested(float size[2]) + { + if (m_child) + m_child->GetSizeRequested(size); + else + size[0] = size[1] = 0; - float size[2]; - GetSize(size); + if (m_forceWidth > 0.0f) size[0] = m_forceWidth; + } - m_scrollY = vscrollAdjust.GetValue(); + void VScrollPortal::GetMinimumSize(float size[2]) + { + if (m_child) { + m_child->GetSizeRequested(size); + size[1] = std::min(size[1], MINIMUM_HEIGHT); + } else + size[0] = size[1] = 0; - float toScroll = m_childSizeY - size[1]; - if (toScroll < 0) toScroll = 0; + if (m_forceWidth > 0.0f) size[0] = m_forceWidth; + } - float scale[2]; - Screen::GetCoords2Pixels(scale); + void VScrollPortal::OnChildResizeRequest(Widget *child) + { + assert(child == m_child); + float size[2], rsize[2]; + GetSize(size); + rsize[0] = size[0]; + rsize[1] = FLT_MAX; + child->GetSizeRequested(rsize); + rsize[0] = std::min(rsize[0], size[0]); + m_childSizeY = rsize[1]; + child->SetSize(rsize[0], rsize[1]); + } - Graphics::Renderer *r = Gui::Screen::GetRenderer(); - Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + void VScrollPortal::UpdateAllChildSizes() + { + if (m_child) OnChildResizeRequest(m_child); + } - // scroll to whole pixel locations whatever the resolution - r->Translate(0, floor((-m_scrollY*toScroll)/scale[1])*scale[1], 0); - Container::Draw(); + void VScrollPortal::Add(Widget *child) + { + assert(m_child == 0); + m_child = child; + AppendChild(child, 0, 0); + OnChildResizeRequest(child); + } - SetScissor(false); -} + void VScrollPortal::Remove(Widget *child) + { + assert(m_child == child); + Container::RemoveChild(child); + m_child = 0; + m_childSizeY = 0; + } -} + float VScrollPortal::GetScrollPixels() + { + float size[2]; + GetSize(size); + return m_scrollY * ((m_childSizeY - size[1]) > 0 ? (m_childSizeY - size[1]) : 0); + } + bool VScrollPortal::OnMouseDown(MouseButtonEvent *e) + { + if (e->button == MouseButtonEvent::BUTTON_WHEELUP || e->button == MouseButtonEvent::BUTTON_WHEELDOWN) { + float change = e->button == MouseButtonEvent::BUTTON_WHEELUP ? -0.1 : 0.1; + float pos = vscrollAdjust.GetValue(); + vscrollAdjust.SetValue(Clamp(pos + change, 0.0f, 1.0f)); + return false; + } + + e->y += GetScrollPixels(); + return Container::OnMouseDown(e); + } + bool VScrollPortal::OnMouseUp(MouseButtonEvent *e) + { + e->y += GetScrollPixels(); + return Container::OnMouseUp(e); + } + bool VScrollPortal::OnMouseMotion(MouseMotionEvent *e) + { + e->y += GetScrollPixels(); + return Container::OnMouseMotion(e); + } + + void VScrollPortal::Draw() + { + PROFILE_SCOPED() + SetScissor(true); + + float size[2]; + GetSize(size); + + m_scrollY = vscrollAdjust.GetValue(); + + float toScroll = m_childSizeY - size[1]; + if (toScroll < 0) toScroll = 0; + + float scale[2]; + Screen::GetCoords2Pixels(scale); + + Graphics::Renderer *r = Gui::Screen::GetRenderer(); + Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW); + + // scroll to whole pixel locations whatever the resolution + r->Translate(0, floor((-m_scrollY * toScroll) / scale[1]) * scale[1], 0); + Container::Draw(); + + SetScissor(false); + } + +} // namespace Gui diff --git a/src/gui/GuiVScrollPortal.h b/src/gui/GuiVScrollPortal.h index dc26b5444..454e880e4 100644 --- a/src/gui/GuiVScrollPortal.h +++ b/src/gui/GuiVScrollPortal.h @@ -7,8 +7,7 @@ #include "GuiContainer.h" namespace Gui { - class VScrollPortal: public Container - { + class VScrollPortal : public Container { public: VScrollPortal(float forceWidth); VScrollPortal(); @@ -25,6 +24,7 @@ namespace Gui { void SetBgColor(float rgb[3]); void SetBgColor(float r, float g, float b); Adjustment vscrollAdjust; + private: float GetScrollPixels(); void OnScroll(float); @@ -32,6 +32,6 @@ namespace Gui { float m_scrollY, m_childSizeY; Widget *m_child; }; -} +} // namespace Gui #endif /* _GUIVSCROLLPORTAL_H */ diff --git a/src/gui/GuiWidget.cpp b/src/gui/GuiWidget.cpp index bcee5f0b1..223637773 100644 --- a/src/gui/GuiWidget.cpp +++ b/src/gui/GuiWidget.cpp @@ -6,177 +6,177 @@ namespace Gui { -Widget::Widget() -{ - m_parent = 0; - m_size.w = m_size.h = 0.0f; - m_enabled = true; - m_visible = false; - m_mouseOver = false; - m_eventMask = EVENT_MOUSEMOTION; - m_tooltipWidget = 0; - m_shortcut.sym = SDLK_UNKNOWN; - m_shortcut.mod = KMOD_NONE; -} - -bool Widget::IsVisible() const -{ - PROFILE_SCOPED() - if (!m_visible || !m_parent) - return false; - - Container *parent = m_parent; - while (parent && parent->m_parent) { - if (parent->m_visible == false) return false; - parent = parent->m_parent; - } - if (Screen::IsBaseWidget(parent)) - return parent->m_visible; - else - return false; -} - -void Widget::SetScissor(bool enabled) -{ - if (enabled) { - float pos[2]; - GetAbsolutePosition(pos); - float scale[2]; - Gui::Screen::GetCoords2Pixels(scale); - - vector2f scissorPos(pos[0]/scale[0],(float(Gui::Screen::GetHeight())-(pos[1]+m_size.h))/scale[1]); - vector2f scissorSize(m_size.w/scale[0],m_size.h/scale[1]); - - assert(scissorPos.x >= 0.0f && scissorPos.y >= 0.0f); - assert(scissorSize.x >= 0.0f && scissorSize.y >= 0.0f); - - Gui::Screen::GetRenderer()->SetScissor(true, scissorPos, scissorSize); - } - else - Gui::Screen::GetRenderer()->SetScissor(false); -} - -void Widget::GrabFocus() -{ - Screen::SetFocused(this); -} - -bool Widget::IsFocused() -{ - return Screen::IsFocused(this); -} - -void Widget::SetShortcut(SDL_Keycode key, SDL_Keymod mod) -{ - assert(m_shortcut.sym == 0); // because AddShortcutWidget will add more than once. fix this otherwise on destruct we leave bad pointers in the Screen shortcut widgets list - m_shortcut.sym = key; - m_shortcut.mod = mod; - Screen::AddShortcutWidget(this); -} - -void Widget::OnPreShortcut(const SDL_Keysym *sym) -{ - int mod = sym->mod & 0xfff; // filters out numlock, capslock, which fuck things up - if ((sym->sym == m_shortcut.sym) && (mod == m_shortcut.mod)) { - OnActivate(); - } -} - -void Widget::GetAbsolutePosition(float pos[2]) const -{ - const Container *parent = GetParent(); - - if (parent) { - float parentPos[2]; - parent->GetAbsolutePosition(parentPos); - parent->GetChildPosition(this, pos); - pos[0] += parentPos[0]; - pos[1] += parentPos[1]; - } else { - pos[0] = pos[1] = 0; - } -} - -void Widget::OnMouseEnter() -{ - m_mouseOver = true; - m_tooltipTimerConnection = Gui::AddTimer(1000, sigc::mem_fun(this, &Widget::OnToolTip)); - onMouseEnter.emit(); -} - -void Widget::OnMouseLeave() -{ - m_mouseOver = false; - HideTooltip(); - assert(!m_tooltipWidget); - m_tooltipTimerConnection.disconnect(); - onMouseLeave.emit(); -} - -void Widget::UpdateOverriddenTooltip() -{ - if (m_tooltipWidget) { - std::string text = GetOverrideTooltip(); - m_tooltipWidget->SetText(text); - } -} - -void Widget::OnToolTip() -{ - if (! IsVisible()) return; - - if (!m_tooltipWidget) { - std::string text = GetOverrideTooltip(); - if (text == "") text = m_tooltip; - if (text == "") return; - - float pos[2]; - GetAbsolutePosition(pos); - m_tooltipWidget = new ToolTip(this, text); - if (m_tooltipWidget->m_size.w + pos[0] > Screen::GetWidth()) - pos[0] = Screen::GetWidth() - m_tooltipWidget->m_size.w; - if (m_tooltipWidget->m_size.h + pos[1] > Screen::GetHeight()) - pos[1] = Screen::GetHeight() - m_tooltipWidget->m_size.h; - - Screen::AddBaseWidget(m_tooltipWidget, int(pos[0]), int(pos[1])); - m_tooltipWidget->Show(); - } -} - -void Widget::Hide() -{ - m_visible = false; - HideTooltip(); - assert(!m_tooltipWidget); - m_tooltipTimerConnection.disconnect(); -} - -void Widget::HideTooltip() -{ - if (m_tooltipWidget) { - Screen::RemoveBaseWidget(m_tooltipWidget); - delete m_tooltipWidget; + Widget::Widget() + { + m_parent = 0; + m_size.w = m_size.h = 0.0f; + m_enabled = true; + m_visible = false; + m_mouseOver = false; + m_eventMask = EVENT_MOUSEMOTION; m_tooltipWidget = 0; + m_shortcut.sym = SDLK_UNKNOWN; + m_shortcut.mod = KMOD_NONE; } -} -void Widget::ResizeRequest() -{ - if (!IsVisible()) return; - if (m_parent) m_parent->OnChildResizeRequest(this); - else { - float size[2] = { FLT_MAX, FLT_MAX }; - GetSizeRequested(size); - SetSize(size[0], size[1]); + bool Widget::IsVisible() const + { + PROFILE_SCOPED() + if (!m_visible || !m_parent) + return false; + + Container *parent = m_parent; + while (parent && parent->m_parent) { + if (parent->m_visible == false) return false; + parent = parent->m_parent; + } + if (Screen::IsBaseWidget(parent)) + return parent->m_visible; + else + return false; } -} -Widget::~Widget() -{ - onDelete.emit(); - HideTooltip(); - Screen::RemoveShortcutWidget(this); - m_tooltipTimerConnection.disconnect(); -} + void Widget::SetScissor(bool enabled) + { + if (enabled) { + float pos[2]; + GetAbsolutePosition(pos); + float scale[2]; + Gui::Screen::GetCoords2Pixels(scale); -} + vector2f scissorPos(pos[0] / scale[0], (float(Gui::Screen::GetHeight()) - (pos[1] + m_size.h)) / scale[1]); + vector2f scissorSize(m_size.w / scale[0], m_size.h / scale[1]); + + assert(scissorPos.x >= 0.0f && scissorPos.y >= 0.0f); + assert(scissorSize.x >= 0.0f && scissorSize.y >= 0.0f); + + Gui::Screen::GetRenderer()->SetScissor(true, scissorPos, scissorSize); + } else + Gui::Screen::GetRenderer()->SetScissor(false); + } + + void Widget::GrabFocus() + { + Screen::SetFocused(this); + } + + bool Widget::IsFocused() + { + return Screen::IsFocused(this); + } + + void Widget::SetShortcut(SDL_Keycode key, SDL_Keymod mod) + { + assert(m_shortcut.sym == 0); // because AddShortcutWidget will add more than once. fix this otherwise on destruct we leave bad pointers in the Screen shortcut widgets list + m_shortcut.sym = key; + m_shortcut.mod = mod; + Screen::AddShortcutWidget(this); + } + + void Widget::OnPreShortcut(const SDL_Keysym *sym) + { + int mod = sym->mod & 0xfff; // filters out numlock, capslock, which fuck things up + if ((sym->sym == m_shortcut.sym) && (mod == m_shortcut.mod)) { + OnActivate(); + } + } + + void Widget::GetAbsolutePosition(float pos[2]) const + { + const Container *parent = GetParent(); + + if (parent) { + float parentPos[2]; + parent->GetAbsolutePosition(parentPos); + parent->GetChildPosition(this, pos); + pos[0] += parentPos[0]; + pos[1] += parentPos[1]; + } else { + pos[0] = pos[1] = 0; + } + } + + void Widget::OnMouseEnter() + { + m_mouseOver = true; + m_tooltipTimerConnection = Gui::AddTimer(1000, sigc::mem_fun(this, &Widget::OnToolTip)); + onMouseEnter.emit(); + } + + void Widget::OnMouseLeave() + { + m_mouseOver = false; + HideTooltip(); + assert(!m_tooltipWidget); + m_tooltipTimerConnection.disconnect(); + onMouseLeave.emit(); + } + + void Widget::UpdateOverriddenTooltip() + { + if (m_tooltipWidget) { + std::string text = GetOverrideTooltip(); + m_tooltipWidget->SetText(text); + } + } + + void Widget::OnToolTip() + { + if (!IsVisible()) return; + + if (!m_tooltipWidget) { + std::string text = GetOverrideTooltip(); + if (text == "") text = m_tooltip; + if (text == "") return; + + float pos[2]; + GetAbsolutePosition(pos); + m_tooltipWidget = new ToolTip(this, text); + if (m_tooltipWidget->m_size.w + pos[0] > Screen::GetWidth()) + pos[0] = Screen::GetWidth() - m_tooltipWidget->m_size.w; + if (m_tooltipWidget->m_size.h + pos[1] > Screen::GetHeight()) + pos[1] = Screen::GetHeight() - m_tooltipWidget->m_size.h; + + Screen::AddBaseWidget(m_tooltipWidget, int(pos[0]), int(pos[1])); + m_tooltipWidget->Show(); + } + } + + void Widget::Hide() + { + m_visible = false; + HideTooltip(); + assert(!m_tooltipWidget); + m_tooltipTimerConnection.disconnect(); + } + + void Widget::HideTooltip() + { + if (m_tooltipWidget) { + Screen::RemoveBaseWidget(m_tooltipWidget); + delete m_tooltipWidget; + m_tooltipWidget = 0; + } + } + + void Widget::ResizeRequest() + { + if (!IsVisible()) return; + if (m_parent) + m_parent->OnChildResizeRequest(this); + else { + float size[2] = { FLT_MAX, FLT_MAX }; + GetSizeRequested(size); + SetSize(size[0], size[1]); + } + } + + Widget::~Widget() + { + onDelete.emit(); + HideTooltip(); + Screen::RemoveShortcutWidget(this); + m_tooltipTimerConnection.disconnect(); + } + +} // namespace Gui diff --git a/src/gui/GuiWidget.h b/src/gui/GuiWidget.h index f1700a331..cafcf330e 100644 --- a/src/gui/GuiWidget.h +++ b/src/gui/GuiWidget.h @@ -6,6 +6,7 @@ #include "Color.h" #include "GuiEvents.h" +#include "libs.h" namespace Gui { class Container; @@ -21,8 +22,17 @@ namespace Gui { // the minimum size the widget requires to operate effectively virtual void GetMinimumSize(float size[2]) { GetSizeRequested(size); } void GetAbsolutePosition(float pos[2]) const; - void GetSize(float size[2]) { size[0] = m_size.w; size[1] = m_size.h; } - void SetSize(float w, float h) { m_size.w = w; m_size.h = h; onSetSize.emit(); } + void GetSize(float size[2]) + { + size[0] = m_size.w; + size[1] = m_size.h; + } + void SetSize(float w, float h) + { + m_size.w = w; + m_size.h = h; + onSetSize.emit(); + } void ResizeRequest(); void SetShortcut(SDL_Keycode key, SDL_Keymod mod); void SetScissor(bool enabled); @@ -54,19 +64,20 @@ namespace Gui { void OnPreShortcut(const SDL_Keysym *sym); enum EventMask { EVENT_NONE = 0, - EVENT_KEYDOWN = 1<<0, - EVENT_KEYUP = 1<<1, - EVENT_MOUSEDOWN = 1<<2, - EVENT_MOUSEUP = 1<<3, - EVENT_MOUSEMOTION = 1<<4 // needed for OnMouseEnter,Leave,IsMouseOver + EVENT_KEYDOWN = 1 << 0, + EVENT_KEYUP = 1 << 1, + EVENT_MOUSEDOWN = 1 << 2, + EVENT_MOUSEUP = 1 << 3, + EVENT_MOUSEMOTION = 1 << 4 // needed for OnMouseEnter,Leave,IsMouseOver }; - static const unsigned int EVENT_ALL = 0xffffffff; // not in the enum because 0xffffffff is an unsigned int, and an enum is an int (before C++11 which allows strong-typed enums) + static const unsigned int EVENT_ALL = 0xffffffff; // not in the enum because 0xffffffff is an unsigned int, and an enum is an int (before C++11 which allows strong-typed enums) unsigned int GetEventMask() { return m_eventMask; } sigc::signal onMouseEnter; sigc::signal onMouseLeave; sigc::signal onSetSize; sigc::signal onDelete; + protected: unsigned int m_eventMask; struct { @@ -76,9 +87,10 @@ namespace Gui { virtual std::string GetOverrideTooltip() { return ""; } void UpdateOverriddenTooltip(); + private: struct { - float w,h; + float w, h; } m_size; bool m_visible; bool m_mouseOver; @@ -89,6 +101,6 @@ namespace Gui { ToolTip *m_tooltipWidget; void OnToolTip(); }; -} +} // namespace Gui #endif /* _GUIWIDGET_H */ diff --git a/src/libs.h b/src/libs.h index b87b9b9f5..b1989110f 100644 --- a/src/libs.h +++ b/src/libs.h @@ -6,41 +6,41 @@ #include "buildopts.h" -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #ifdef _WIN32 -# include +#include -# ifdef _MSC_VER -# pragma warning(disable : 4244) // "conversion from x to x: possible loss of data" -# pragma warning(disable : 4800) // int-to-bool "performance warning" -# pragma warning(disable : 4355) // 'this' used in base member initializer list -# pragma warning(disable : 4351) // new behavior [after vs2003!]: elements of array 'array' will be default initialized -# endif +#ifdef _MSC_VER +#pragma warning(disable : 4244) // "conversion from x to x: possible loss of data" +#pragma warning(disable : 4800) // int-to-bool "performance warning" +#pragma warning(disable : 4355) // 'this' used in base member initializer list +#pragma warning(disable : 4351) // new behavior [after vs2003!]: elements of array 'array' will be default initialized +#endif -# ifndef __MINGW32__ -# define strncasecmp _strnicmp -# define strcasecmp _stricmp -# endif +#ifndef __MINGW32__ +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif #endif #ifdef _WIN32 // MSVC doesn't support the %z specifier, but has its own %I specifier @@ -50,37 +50,39 @@ #endif #include "fixed.h" -#include "vector2.h" -#include "vector3.h" -#include "Aabb.h" #include "matrix3x3.h" #include "matrix4x4.h" +#include "vector2.h" +#include "vector3.h" + +#include "Aabb.h" #include "Color.h" #include "Random.h" #include "FloatComparison.h" -#include "SmartPtr.h" #include "RefCounted.h" +#include "SmartPtr.h" #include "profiler/Profiler.h" #ifdef NDEBUG -#define PiVerify(x) ((void)(x)) +#define PiVerify(x) ((void)(x)) #else #define PiVerify(x) assert(x) #endif -template inline const T& Clamp(const T& x, const T& min, const T& max) { return x > max ? max : (x < min ? min : x); } +template +inline const T &Clamp(const T &x, const T &min, const T &max) { return x > max ? max : (x < min ? min : x); } -inline double DEG2RAD(double x) { return x*(M_PI/180.); } -inline float DEG2RAD(float x) { return x*(float(M_PI)/180.f); } -inline double RAD2DEG(double x) { return x*(180./M_PI); } -inline float RAD2DEG(float x) { return x*(180.f/float(M_PI)); } +inline double DEG2RAD(double x) { return x * (M_PI / 180.); } +inline float DEG2RAD(float x) { return x * (float(M_PI) / 180.f); } +inline double RAD2DEG(double x) { return x * (180. / M_PI); } +inline float RAD2DEG(float x) { return x * (180.f / float(M_PI)); } // from StackOverflow: http://stackoverflow.com/a/1500517/52251 // Q: "Compile time sizeof_array without using a macro" template -char ( &COUNTOF_Helper( T (&array)[N] ))[N]; -#define COUNTOF( array ) (sizeof( COUNTOF_Helper( array ) )) +char (&COUNTOF_Helper(T (&array)[N]))[N]; +#define COUNTOF(array) (sizeof(COUNTOF_Helper(array))) #endif /* _LIBS_H */ diff --git a/src/main.cpp b/src/main.cpp index ce49c4502..22e6cb9da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" -#include "Pi.h" -#include "ModelViewer.h" #include "Game.h" -#include "galaxy/GalaxyGenerator.h" +#include "ModelViewer.h" +#include "Pi.h" #include "galaxy/Galaxy.h" +#include "galaxy/GalaxyGenerator.h" +#include "libs.h" #include "utils.h" #include "versioningInfo.h" #include @@ -22,10 +22,10 @@ enum RunMode { MODE_USAGE_ERROR }; -int main(int argc, char** argv) +int main(int argc, char **argv) { #ifdef PIONEER_PROFILER - Profiler::detect( argc, argv ); + Profiler::detect(argc, argv); #endif RunMode mode = MODE_GAME; @@ -56,8 +56,7 @@ int main(int argc, char** argv) } if (modeopt.find("startat", 0, 7) != std::string::npos || - modeopt.find("sa", 0, 2) != std::string::npos) - { + modeopt.find("sa", 0, 2) != std::string::npos) { mode = MODE_START_AT; goto start; } @@ -81,159 +80,153 @@ start: long int radius = 4; long int sx = 0, sy = 0, sz = 0; std::string filename; - SystemPath startPath(0,0,0,0,0); + SystemPath startPath(0, 0, 0, 0, 0); switch (mode) { - case MODE_GALAXYDUMP: { - if (argc < 3) { - Output("pioneer: galaxy dump requires a filename\n"); + case MODE_GALAXYDUMP: { + if (argc < 3) { + Output("pioneer: galaxy dump requires a filename\n"); + break; + } + filename = argv[pos]; + ++pos; + if (argc > pos) { // radius (optional) + char *end = nullptr; + radius = std::strtol(argv[pos], &end, 0); + if (end == nullptr || *end != 0 || radius < 0 || radius > 10000) { + Output("pioneer: invalid radius: %s\n", argv[pos]); break; } - filename = argv[pos]; ++pos; - if (argc > pos) { // radius (optional) - char* end = nullptr; - radius = std::strtol(argv[pos], &end, 0); - if (end == nullptr || *end != 0 || radius < 0 || radius > 10000) { - Output("pioneer: invalid radius: %s\n", argv[pos]); - break; - } - ++pos; - } - if (argc > pos) { // center of dump (three comma separated coordinates, optional) - char* end = nullptr; - sx = std::strtol(argv[pos], &end, 0); - if (end == nullptr || *end != ',' || sx < -10000 || sx > 10000) { - Output("pioneer: invalid center: %s\n", argv[pos]); - break; - } - sy = std::strtol(end + 1, &end, 0); - if (end == nullptr || *end != ',' || sy < -10000 || sy > 10000) { - Output("pioneer: invalid center: %s\n", argv[pos]); - break; - } - sz = std::strtol(end + 1, &end, 0); - if (end == nullptr || *end != 0 || sz < -10000 || sz > 10000) { - Output("pioneer: invalid center: %s\n", argv[pos]); - break; - } - ++pos; - } - // fallthrough } - case MODE_START_AT: { - // fallthrough protect - if (mode == MODE_START_AT) - { - // try to get start planet number - std::vector keyValue = SplitString(modeopt, "="); + if (argc > pos) { // center of dump (three comma separated coordinates, optional) + char *end = nullptr; + sx = std::strtol(argv[pos], &end, 0); + if (end == nullptr || *end != ',' || sx < -10000 || sx > 10000) { + Output("pioneer: invalid center: %s\n", argv[pos]); + break; + } + sy = std::strtol(end + 1, &end, 0); + if (end == nullptr || *end != ',' || sy < -10000 || sy > 10000) { + Output("pioneer: invalid center: %s\n", argv[pos]); + break; + } + sz = std::strtol(end + 1, &end, 0); + if (end == nullptr || *end != 0 || sz < -10000 || sz > 10000) { + Output("pioneer: invalid center: %s\n", argv[pos]); + break; + } + ++pos; + } + // fallthrough + } + case MODE_START_AT: { + // fallthrough protect + if (mode == MODE_START_AT) { + // try to get start planet number + std::vector keyValue = SplitString(modeopt, "="); - // if found value - if (keyValue.size() == 2) - { - if (keyValue[1].empty()) - { - startPath = SystemPath(0,0,0,0,0); - Error("Please provide an actual SystemPath, like 0,0,0,0,18\n"); + // if found value + if (keyValue.size() == 2) { + if (keyValue[1].empty()) { + startPath = SystemPath(0, 0, 0, 0, 0); + Error("Please provide an actual SystemPath, like 0,0,0,0,18\n"); + return -1; + } else { + try { + startPath = SystemPath::Parse(keyValue[1].c_str()); + } catch (const SystemPath::ParseFailure &spf) { + startPath = SystemPath(0, 0, 0, 0, 0); + Error("Failed to parse system path %s\n", keyValue[1].c_str()); return -1; } - else - { - try { - startPath = SystemPath::Parse(keyValue[1].c_str()); - } catch(const SystemPath::ParseFailure &spf) { - startPath = SystemPath(0,0,0,0,0); - Error("Failed to parse system path %s\n", keyValue[1].c_str()); - return -1; - } - } - } - // if value not exists - start on Sol, Mars, Cydonia - else - startPath = SystemPath(0,0,0,0,18); - // set usual mode - mode = MODE_GAME; - } - // fallthrough - } - case MODE_GAME: { - std::map options; - - // if arguments more than parsed already - if (argc > pos) { - static const std::string delim("="); - - // for each argument - for (; pos < argc; pos++) { - const std::string arg(argv[pos]); - std::vector keyValue = SplitString(arg, "="); - - // if there no key and value || key is empty || value is empty - if (keyValue.size() != 2 || keyValue[0].empty() || keyValue[1].empty()) { - Output("malformed option: %s\n", arg.c_str()); - return 1; - } - - // put key and value to config - options[keyValue[0]] = keyValue[1]; } } + // if value not exists - start on Sol, Mars, Cydonia + else + startPath = SystemPath(0, 0, 0, 0, 18); + // set usual mode + mode = MODE_GAME; + } + // fallthrough + } + case MODE_GAME: { + std::map options; - Pi::Init(options, mode == MODE_GALAXYDUMP); + // if arguments more than parsed already + if (argc > pos) { + static const std::string delim("="); - if (mode == MODE_GAME) - for (;;) { - Pi::Start(startPath); - startPath = SystemPath(0,0,0,0,0); // Reset the start planet when coming back to the menu - } - else if (mode == MODE_GALAXYDUMP) { - FILE* file = filename == "-" ? stdout : fopen(filename.c_str(), "w"); - if (file == nullptr) { - Output("pioneer: could not open \"%s\" for writing: %s\n", filename.c_str(), strerror(errno)); - break; - } - RefCountedPtr galaxy = GalaxyGenerator::Create(); - galaxy->Dump(file, sx, sy, sz, radius); - if (filename != "-" && fclose(file) != 0) { - Output("pioneer: writing to \"%s\" failed: %s\n", filename.c_str(), strerror(errno)); + // for each argument + for (; pos < argc; pos++) { + const std::string arg(argv[pos]); + std::vector keyValue = SplitString(arg, "="); + + // if there no key and value || key is empty || value is empty + if (keyValue.size() != 2 || keyValue[0].empty() || keyValue[1].empty()) { + Output("malformed option: %s\n", arg.c_str()); + return 1; } + + // put key and value to config + options[keyValue[0]] = keyValue[1]; } - break; } - case MODE_MODELVIEWER: { - std::string modelName; - if (argc > 2) - modelName = argv[2]; - ModelViewer::Run(modelName); - break; + Pi::Init(options, mode == MODE_GALAXYDUMP); + + if (mode == MODE_GAME) + for (;;) { + Pi::Start(startPath); + startPath = SystemPath(0, 0, 0, 0, 0); // Reset the start planet when coming back to the menu + } + else if (mode == MODE_GALAXYDUMP) { + FILE *file = filename == "-" ? stdout : fopen(filename.c_str(), "w"); + if (file == nullptr) { + Output("pioneer: could not open \"%s\" for writing: %s\n", filename.c_str(), strerror(errno)); + break; + } + RefCountedPtr galaxy = GalaxyGenerator::Create(); + galaxy->Dump(file, sx, sy, sz, radius); + if (filename != "-" && fclose(file) != 0) { + Output("pioneer: writing to \"%s\" failed: %s\n", filename.c_str(), strerror(errno)); + } } + break; + } - case MODE_VERSION: { - std::string version(PIONEER_VERSION); - if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")"; - Output("pioneer %s\n", version.c_str()); - OutputVersioningInfo(); - break; - } + case MODE_MODELVIEWER: { + std::string modelName; + if (argc > 2) + modelName = argv[2]; + ModelViewer::Run(modelName); + break; + } - case MODE_USAGE_ERROR: - Output("pioneer: unknown mode %s\n", argv[1]); - // fall through + case MODE_VERSION: { + std::string version(PIONEER_VERSION); + if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")"; + Output("pioneer %s\n", version.c_str()); + OutputVersioningInfo(); + break; + } - case MODE_USAGE: - Output( - "usage: pioneer [mode] [options...]\n" - "available modes:\n" - " -game [-g] game (default)\n" - " -modelviewer [-mv] model viewer\n" - " -galaxydump [-gd] galaxy dumper\n" - " -startat [-sa] skip main menu and start at Mars\n" - " -startat=sp [-sa=sp] skip main menu and start at systempath x,y,z,si,bi\n" - " -version [-v] show version\n" - " -help [-h,-?] this help\n" - ); - break; + case MODE_USAGE_ERROR: + Output("pioneer: unknown mode %s\n", argv[1]); + // fall through + + case MODE_USAGE: + Output( + "usage: pioneer [mode] [options...]\n" + "available modes:\n" + " -game [-g] game (default)\n" + " -modelviewer [-mv] model viewer\n" + " -galaxydump [-gd] galaxy dumper\n" + " -startat [-sa] skip main menu and start at Mars\n" + " -startat=sp [-sa=sp] skip main menu and start at systempath x,y,z,si,bi\n" + " -version [-v] show version\n" + " -help [-h,-?] this help\n"); + break; } return 0; diff --git a/src/matrix3x3.h b/src/matrix3x3.h index 2386229d9..fc644d21b 100644 --- a/src/matrix3x3.h +++ b/src/matrix3x3.h @@ -4,149 +4,204 @@ #ifndef _MATRIX3X3_H #define _MATRIX3X3_H +#include "vector3.h" #include #include -#include "vector3.h" template class matrix3x3 { private: T cell[9]; + public: - matrix3x3 () {} - matrix3x3 (T val) { + matrix3x3() {} + matrix3x3(T val) + { cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] = - cell[7] = cell[8] = val; + cell[7] = cell[8] = val; } - matrix3x3 (const T *vals) { - memcpy(cell, vals, sizeof(T)*9); + matrix3x3(const T *vals) + { + memcpy(cell, vals, sizeof(T) * 9); } - T& operator [] (const size_t i) { return cell[i]; } // used for serializing - const T& operator[] (const size_t i) const { return cell[i]; } + T &operator[](const size_t i) { return cell[i]; } // used for serializing + const T &operator[](const size_t i) const { return cell[i]; } - const T* Data() const { return cell; } - T* Data() { return cell; } + const T *Data() const { return cell; } + T *Data() { return cell; } vector3 VectorX() const { return vector3(cell[0], cell[3], cell[6]); } vector3 VectorY() const { return vector3(cell[1], cell[4], cell[7]); } vector3 VectorZ() const { return vector3(cell[2], cell[5], cell[8]); } - static matrix3x3 Identity () { + static matrix3x3 Identity() + { matrix3x3 m; m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f; m.cell[0] = m.cell[4] = m.cell[8] = 1.0f; return m; } - static matrix3x3 Scale(T x, T y, T z) { + static matrix3x3 Scale(T x, T y, T z) + { matrix3x3 m; m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f; - m.cell[0] = x; m.cell[4] = y; m.cell[8] = z; + m.cell[0] = x; + m.cell[4] = y; + m.cell[8] = z; return m; } - static matrix3x3 Scale(T scale) { + static matrix3x3 Scale(T scale) + { matrix3x3 m; m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f; m.cell[0] = m.cell[4] = m.cell[8] = scale; return m; } - static matrix3x3 FromVectors(const vector3 &rx, const vector3 &ry, const vector3 &rz) { + static matrix3x3 FromVectors(const vector3 &rx, const vector3 &ry, const vector3 &rz) + { matrix3x3 m; - m[0] = rx.x; m[1] = ry.x; m[2] = rz.x; - m[3] = rx.y; m[4] = ry.y; m[5] = rz.y; - m[6] = rx.z; m[7] = ry.z; m[8] = rz.z; + m[0] = rx.x; + m[1] = ry.x; + m[2] = rz.x; + m[3] = rx.y; + m[4] = ry.y; + m[5] = rz.y; + m[6] = rx.z; + m[7] = ry.z; + m[8] = rz.z; return m; } - static matrix3x3 FromVectors(const vector3 &rx, const vector3 &ry) { + static matrix3x3 FromVectors(const vector3 &rx, const vector3 &ry) + { return FromVectors(rx, ry, rx.Cross(ry)); } // (x,y,z) must be normalized - static matrix3x3 Rotate(T ang, const vector3 &v) { + static matrix3x3 Rotate(T ang, const vector3 &v) + { matrix3x3 m; T c = cos(ang); T s = sin(ang); - m[0] = v.x*v.x*(1-c)+c; m[1] = v.x*v.y*(1-c)-v.z*s; m[2] = v.x*v.z*(1-c)+v.y*s; - m[3] = v.y*v.x*(1-c)+v.z*s; m[4] = v.y*v.y*(1-c)+c; m[5] = v.y*v.z*(1-c)-v.x*s; - m[6] = v.x*v.z*(1-c)-v.y*s; m[7] = v.y*v.z*(1-c)+v.x*s; m[8] = v.z*v.z*(1-c)+c; + m[0] = v.x * v.x * (1 - c) + c; + m[1] = v.x * v.y * (1 - c) - v.z * s; + m[2] = v.x * v.z * (1 - c) + v.y * s; + m[3] = v.y * v.x * (1 - c) + v.z * s; + m[4] = v.y * v.y * (1 - c) + c; + m[5] = v.y * v.z * (1 - c) - v.x * s; + m[6] = v.x * v.z * (1 - c) - v.y * s; + m[7] = v.y * v.z * (1 - c) + v.x * s; + m[8] = v.z * v.z * (1 - c) + c; return m; } // Note: these three are backwards compared to the right-handed rotation convention - static matrix3x3 RotateX (T radians) { + static matrix3x3 RotateX(T radians) + { matrix3x3 m; T c = cos(radians); T s = sin(radians); - m[0] = 1.0f; m[1] = 0; m[2] = 0; - m[3] = 0; m[4] = c; m[5] = s; - m[6] = 0; m[7] = -s; m[8] = c; + m[0] = 1.0f; + m[1] = 0; + m[2] = 0; + m[3] = 0; + m[4] = c; + m[5] = s; + m[6] = 0; + m[7] = -s; + m[8] = c; return m; } - static matrix3x3 RotateY (T radians) { + static matrix3x3 RotateY(T radians) + { matrix3x3 m; T c = cos(radians); T s = sin(radians); - m[0] = c; m[1] = 0; m[2] = -s; - m[3] = 0; m[4] = 1.0; m[5] = 0; - m[6] = s; m[7] = 0; m[8] = c; + m[0] = c; + m[1] = 0; + m[2] = -s; + m[3] = 0; + m[4] = 1.0; + m[5] = 0; + m[6] = s; + m[7] = 0; + m[8] = c; return m; } - static matrix3x3 RotateZ (T radians) { + static matrix3x3 RotateZ(T radians) + { matrix3x3 m; T c = cos(radians); T s = sin(radians); - m[0] = c; m[1] = s; m[2] = 0; - m[3] = -s; m[4] = c; m[5] = 0; - m[6] = 0; m[7] = 0; m[8] = 1.0; + m[0] = c; + m[1] = s; + m[2] = 0; + m[3] = -s; + m[4] = c; + m[5] = 0; + m[6] = 0; + m[7] = 0; + m[8] = 1.0; return m; } - friend matrix3x3 operator* (const matrix3x3 &a, const matrix3x3 &b) { + friend matrix3x3 operator*(const matrix3x3 &a, const matrix3x3 &b) + { matrix3x3 m; - m.cell[0] = a.cell[0]*b.cell[0] + a.cell[1]*b.cell[3] + a.cell[2]*b.cell[6]; - m.cell[1] = a.cell[0]*b.cell[1] + a.cell[1]*b.cell[4] + a.cell[2]*b.cell[7]; - m.cell[2] = a.cell[0]*b.cell[2] + a.cell[1]*b.cell[5] + a.cell[2]*b.cell[8]; + m.cell[0] = a.cell[0] * b.cell[0] + a.cell[1] * b.cell[3] + a.cell[2] * b.cell[6]; + m.cell[1] = a.cell[0] * b.cell[1] + a.cell[1] * b.cell[4] + a.cell[2] * b.cell[7]; + m.cell[2] = a.cell[0] * b.cell[2] + a.cell[1] * b.cell[5] + a.cell[2] * b.cell[8]; - m.cell[3] = a.cell[3]*b.cell[0] + a.cell[4]*b.cell[3] + a.cell[5]*b.cell[6]; - m.cell[4] = a.cell[3]*b.cell[1] + a.cell[4]*b.cell[4] + a.cell[5]*b.cell[7]; - m.cell[5] = a.cell[3]*b.cell[2] + a.cell[4]*b.cell[5] + a.cell[5]*b.cell[8]; + m.cell[3] = a.cell[3] * b.cell[0] + a.cell[4] * b.cell[3] + a.cell[5] * b.cell[6]; + m.cell[4] = a.cell[3] * b.cell[1] + a.cell[4] * b.cell[4] + a.cell[5] * b.cell[7]; + m.cell[5] = a.cell[3] * b.cell[2] + a.cell[4] * b.cell[5] + a.cell[5] * b.cell[8]; - m.cell[6] = a.cell[6]*b.cell[0] + a.cell[7]*b.cell[3] + a.cell[8]*b.cell[6]; - m.cell[7] = a.cell[6]*b.cell[1] + a.cell[7]*b.cell[4] + a.cell[8]*b.cell[7]; - m.cell[8] = a.cell[6]*b.cell[2] + a.cell[7]*b.cell[5] + a.cell[8]*b.cell[8]; + m.cell[6] = a.cell[6] * b.cell[0] + a.cell[7] * b.cell[3] + a.cell[8] * b.cell[6]; + m.cell[7] = a.cell[6] * b.cell[1] + a.cell[7] * b.cell[4] + a.cell[8] * b.cell[7]; + m.cell[8] = a.cell[6] * b.cell[2] + a.cell[7] * b.cell[5] + a.cell[8] * b.cell[8]; return m; } - friend vector3 operator * (const matrix3x3 &a, const vector3 &v) { + friend vector3 operator*(const matrix3x3 &a, const vector3 &v) + { vector3 out; - out.x = a.cell[0]*v.x + a.cell[1]*v.y + a.cell[2]*v.z; - out.y = a.cell[3]*v.x + a.cell[4]*v.y + a.cell[5]*v.z; - out.z = a.cell[6]*v.x + a.cell[7]*v.y + a.cell[8]*v.z; + out.x = a.cell[0] * v.x + a.cell[1] * v.y + a.cell[2] * v.z; + out.y = a.cell[3] * v.x + a.cell[4] * v.y + a.cell[5] * v.z; + out.z = a.cell[6] * v.x + a.cell[7] * v.y + a.cell[8] * v.z; return out; } // V * M same as transpose(M) * V - friend vector3 operator * (const vector3 &v, const matrix3x3 &a) { + friend vector3 operator*(const vector3 &v, const matrix3x3 &a) + { vector3 out; - out.x = a.cell[0]*v.x + a.cell[3]*v.y + a.cell[6]*v.z; - out.y = a.cell[1]*v.x + a.cell[4]*v.y + a.cell[7]*v.z; - out.z = a.cell[2]*v.x + a.cell[5]*v.y + a.cell[8]*v.z; + out.x = a.cell[0] * v.x + a.cell[3] * v.y + a.cell[6] * v.z; + out.y = a.cell[1] * v.x + a.cell[4] * v.y + a.cell[7] * v.z; + out.z = a.cell[2] * v.x + a.cell[5] * v.y + a.cell[8] * v.z; return out; } - matrix3x3 Transpose() const { + matrix3x3 Transpose() const + { matrix3x3 m; - m[0] = cell[0]; m[1] = cell[3]; m[2] = cell[6]; - m[3] = cell[1]; m[4] = cell[4]; m[5] = cell[7]; - m[6] = cell[2]; m[7] = cell[5]; m[8] = cell[8]; + m[0] = cell[0]; + m[1] = cell[3]; + m[2] = cell[6]; + m[3] = cell[1]; + m[4] = cell[4]; + m[5] = cell[7]; + m[6] = cell[2]; + m[7] = cell[5]; + m[8] = cell[8]; return m; } - matrix3x3 Inverse() const { - // computes the inverse of a matrix m - #define cell2d(x,y) cell[((y*3) + x)] + matrix3x3 Inverse() const + { +// computes the inverse of a matrix m +#define cell2d(x, y) cell[((y * 3) + x)] const T det = cell2d(0, 0) * (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) - - cell2d(0, 1) * (cell2d(1, 0) * cell2d(2, 2) - cell2d(1, 2) * cell2d(2, 0)) + - cell2d(0, 2) * (cell2d(1, 0) * cell2d(2, 1) - cell2d(1, 1) * cell2d(2, 0)); + cell2d(0, 1) * (cell2d(1, 0) * cell2d(2, 2) - cell2d(1, 2) * cell2d(2, 0)) + + cell2d(0, 2) * (cell2d(1, 0) * cell2d(2, 1) - cell2d(1, 1) * cell2d(2, 0)); const T invdet = T(1.0) / det; matrix3x3 minv; // inverse of matrix m - #define idx2d(x,y) ((y*3) + x) +#define idx2d(x, y) ((y * 3) + x) minv[idx2d(0, 0)] = (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) * invdet; minv[idx2d(0, 1)] = (cell2d(0, 2) * cell2d(2, 1) - cell2d(0, 1) * cell2d(2, 2)) * invdet; minv[idx2d(0, 2)] = (cell2d(0, 1) * cell2d(1, 2) - cell2d(0, 2) * cell2d(1, 1)) * invdet; @@ -158,16 +213,18 @@ public: minv[idx2d(2, 2)] = (cell2d(0, 0) * cell2d(1, 1) - cell2d(1, 0) * cell2d(0, 1)) * invdet; return minv; } - void Renormalize() { + void Renormalize() + { vector3 x = VectorX().Normalized(); vector3 y = VectorZ().Cross(x).Normalized(); *this = FromVectors(x, y); } - void Print () const { - for (int i=0; i<3; i++) { - printf ("%.2f %.2f %.2f\n", cell[3*i], cell[3*i+1], cell[3*i+2]); + void Print() const + { + for (int i = 0; i < 3; i++) { + printf("%.2f %.2f %.2f\n", cell[3 * i], cell[3 * i + 1], cell[3 * i + 2]); } - printf ("\n"); + printf("\n"); } }; diff --git a/src/matrix4x4.h b/src/matrix4x4.h index 7f87882d2..2c5850142 100644 --- a/src/matrix4x4.h +++ b/src/matrix4x4.h @@ -4,103 +4,191 @@ #ifndef _MATRIX4X4_H #define _MATRIX4X4_H +#include "matrix3x3.h" +#include "vector3.h" #include #include -#include "vector3.h" -#include "matrix3x3.h" template class matrix4x4 { private: T cell[16]; + public: - matrix4x4 () {} - matrix4x4 (T val) { - cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] = - cell[7] = cell[8] = cell[9] = cell[10] = cell[11] = cell[12] = cell[13] = - cell[14] = cell[15] = val; - } - matrix4x4 (const T *vals) { - memcpy(cell, vals, sizeof(T)*16); - } - void SetTranslate(const vector3 &v) { cell[12] = v.x; cell[13] = v.y; cell[14] = v.z; } - vector3 GetTranslate() const { return vector3(cell[12], cell[13], cell[14]); } - void SetRotationOnly(const matrix4x4& m) { - for (int i=0; i<12; i++) cell[i] = m.cell[i]; - } - matrix4x4 (const matrix3x3 &m) + matrix4x4() {} + matrix4x4(T val) { - cell[0] = m[0]; cell[4] = m[1]; cell[8] = m[2]; cell[12] = 0; - cell[1] = m[3]; cell[5] = m[4]; cell[9] = m[5]; cell[13] = 0; - cell[2] = m[6]; cell[6] = m[7]; cell[10] = m[8]; cell[14] = 0; - cell[3] = 0; cell[7] = 0; cell[11] = 0; cell[15] = 1; + cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] = + cell[7] = cell[8] = cell[9] = cell[10] = cell[11] = cell[12] = cell[13] = + cell[14] = cell[15] = val; + } + matrix4x4(const T *vals) + { + memcpy(cell, vals, sizeof(T) * 16); + } + void SetTranslate(const vector3 &v) + { + cell[12] = v.x; + cell[13] = v.y; + cell[14] = v.z; + } + vector3 GetTranslate() const { return vector3(cell[12], cell[13], cell[14]); } + void SetRotationOnly(const matrix4x4 &m) + { + for (int i = 0; i < 12; i++) + cell[i] = m.cell[i]; + } + matrix4x4(const matrix3x3 &m) + { + cell[0] = m[0]; + cell[4] = m[1]; + cell[8] = m[2]; + cell[12] = 0; + cell[1] = m[3]; + cell[5] = m[4]; + cell[9] = m[5]; + cell[13] = 0; + cell[2] = m[6]; + cell[6] = m[7]; + cell[10] = m[8]; + cell[14] = 0; + cell[3] = 0; + cell[7] = 0; + cell[11] = 0; + cell[15] = 1; } matrix3x3 GetOrient() const { matrix3x3 m; - m[0] = cell[0]; m[1] = cell[4]; m[2] = cell[8]; - m[3] = cell[1]; m[4] = cell[5]; m[5] = cell[9]; - m[6] = cell[2]; m[7] = cell[6]; m[8] = cell[10]; + m[0] = cell[0]; + m[1] = cell[4]; + m[2] = cell[8]; + m[3] = cell[1]; + m[4] = cell[5]; + m[5] = cell[9]; + m[6] = cell[2]; + m[7] = cell[6]; + m[8] = cell[10]; return m; } // row-major 3x3 matrix - void LoadFrom3x3Matrix(const T *r) { - cell[0] = r[0]; cell[4] = r[1]; cell[8] = r[2]; cell[12] = 0; - cell[1] = r[3]; cell[5] = r[4]; cell[9] = r[5]; cell[13] = 0; - cell[2] = r[6]; cell[6] = r[7]; cell[10] = r[8]; cell[14] = 0; - cell[3] = 0; cell[7] = 0; cell[11] = 0; cell[15] = 1; + void LoadFrom3x3Matrix(const T *r) + { + cell[0] = r[0]; + cell[4] = r[1]; + cell[8] = r[2]; + cell[12] = 0; + cell[1] = r[3]; + cell[5] = r[4]; + cell[9] = r[5]; + cell[13] = 0; + cell[2] = r[6]; + cell[6] = r[7]; + cell[10] = r[8]; + cell[14] = 0; + cell[3] = 0; + cell[7] = 0; + cell[11] = 0; + cell[15] = 1; } // row-major - void SaveTo3x3Matrix(T *r) const { - r[0] = cell[0]; r[1] = cell[4]; r[2] = cell[8]; - r[3] = cell[1]; r[4] = cell[5]; r[5] = cell[9]; - r[6] = cell[2]; r[7] = cell[6]; r[8] = cell[10]; + void SaveTo3x3Matrix(T *r) const + { + r[0] = cell[0]; + r[1] = cell[4]; + r[2] = cell[8]; + r[3] = cell[1]; + r[4] = cell[5]; + r[5] = cell[9]; + r[6] = cell[2]; + r[7] = cell[6]; + r[8] = cell[10]; } - static matrix4x4 Identity () { + static matrix4x4 Identity() + { matrix4x4 m = matrix4x4(0.0); m.cell[0] = m.cell[5] = m.cell[10] = m.cell[15] = 1.0f; return m; } //glscale equivalent - void Scale(T x, T y, T z) { - *this = (*this) * ScaleMatrix (x, y, z); + void Scale(T x, T y, T z) + { + *this = (*this) * ScaleMatrix(x, y, z); } - void Scale(T s) { - *this = (*this) * ScaleMatrix (s, s, s); + void Scale(T s) + { + *this = (*this) * ScaleMatrix(s, s, s); } - static matrix4x4 ScaleMatrix(T x, T y, T z) { + static matrix4x4 ScaleMatrix(T x, T y, T z) + { matrix4x4 m; - m[0] = x; m[1] = m[2] = m[3] = 0; - m[5] = y; m[4] = m[6] = m[7] = 0; - m[10] = z; m[8] = m[9] = m[11] = 0; - m[12] = m[13] = m[14] = 0; m[15] = 1; + m[0] = x; + m[1] = m[2] = m[3] = 0; + m[5] = y; + m[4] = m[6] = m[7] = 0; + m[10] = z; + m[8] = m[9] = m[11] = 0; + m[12] = m[13] = m[14] = 0; + m[15] = 1; return m; } - static matrix4x4 ScaleMatrix(T scale) { + static matrix4x4 ScaleMatrix(T scale) + { matrix4x4 m; - m[0] = scale; m[1] = m[2] = m[3] = 0; - m[5] = scale; m[4] = m[6] = m[7] = 0; - m[10] = scale; m[8] = m[9] = m[11] = 0; - m[12] = m[13] = m[14] = 0; m[15] = 1; + m[0] = scale; + m[1] = m[2] = m[3] = 0; + m[5] = scale; + m[4] = m[6] = m[7] = 0; + m[10] = scale; + m[8] = m[9] = m[11] = 0; + m[12] = m[13] = m[14] = 0; + m[15] = 1; return m; } - static matrix4x4 MakeRotMatrix(const vector3 &rx, const vector3 &ry, const vector3 &rz) { + static matrix4x4 MakeRotMatrix(const vector3 &rx, const vector3 &ry, const vector3 &rz) + { matrix4x4 m; - m[0] = rx.x; m[4] = rx.y; m[8] = rx.z; m[12] = 0; - m[1] = ry.x; m[5] = ry.y; m[9] = ry.z; m[13] = 0; - m[2] = rz.x; m[6] = rz.y; m[10] = rz.z; m[14] = 0; - m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1; + m[0] = rx.x; + m[4] = rx.y; + m[8] = rx.z; + m[12] = 0; + m[1] = ry.x; + m[5] = ry.y; + m[9] = ry.z; + m[13] = 0; + m[2] = rz.x; + m[6] = rz.y; + m[10] = rz.z; + m[14] = 0; + m[3] = 0; + m[7] = 0; + m[11] = 0; + m[15] = 1; return m; } - static matrix4x4 MakeInvRotMatrix(const vector3 &rx, const vector3 &ry, const vector3 &rz) { + static matrix4x4 MakeInvRotMatrix(const vector3 &rx, const vector3 &ry, const vector3 &rz) + { matrix4x4 m; - m[0] = rx.x; m[4] = ry.x; m[8] = rz.x; m[12] = 0; - m[1] = rx.y; m[5] = ry.y; m[9] = rz.y; m[13] = 0; - m[2] = rx.z; m[6] = ry.z; m[10] = rz.z; m[14] = 0; - m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1; + m[0] = rx.x; + m[4] = ry.x; + m[8] = rz.x; + m[12] = 0; + m[1] = rx.y; + m[5] = ry.y; + m[9] = rz.y; + m[13] = 0; + m[2] = rx.z; + m[6] = ry.z; + m[10] = rz.z; + m[14] = 0; + m[3] = 0; + m[7] = 0; + m[11] = 0; + m[15] = 1; return m; } - static matrix4x4 FrustumMatrix (T left, T right, T bottom, T top, T znear, T zfar) { + static matrix4x4 FrustumMatrix(T left, T right, T bottom, T top, T znear, T zfar) + { assert((znear > T(0)) && (zfar > T(0))); // these expressions come from the documentation for glFrustum const T sx = (T(2) * znear) / (right - left); @@ -110,25 +198,38 @@ public: const T C = -(zfar + znear) / (zfar - znear); const T D = -(T(2) * zfar * znear) / (zfar - znear); matrix4x4 m; - m[ 0] = sx; m[ 4] = 0; m[ 8] = A; m[12] = 0; - m[ 1] = 0; m[ 5] = sy; m[ 9] = B; m[13] = 0; - m[ 2] = 0; m[ 6] = 0; m[10] = C; m[14] = D; - m[ 3] = 0; m[ 7] = 0; m[11] = -1; m[15] = 0; + m[0] = sx; + m[4] = 0; + m[8] = A; + m[12] = 0; + m[1] = 0; + m[5] = sy; + m[9] = B; + m[13] = 0; + m[2] = 0; + m[6] = 0; + m[10] = C; + m[14] = D; + m[3] = 0; + m[7] = 0; + m[11] = -1; + m[15] = 0; return m; } /////////////////////////////////////////////////////////////////////////////// // set a orthographic frustum with 6 params similar to glOrtho() // (left, right, bottom, top, near, far) /////////////////////////////////////////////////////////////////////////////// - static matrix4x4 OrthoFrustum (T left, T right, T bottom, T top, T znear, T zfar) { + static matrix4x4 OrthoFrustum(T left, T right, T bottom, T top, T znear, T zfar) + { assert((znear >= T(-1)) && (zfar > T(0))); T a = T(2) / (right - left); - T b = T(2) / (top - bottom); - T c = -T(2) / (zfar - znear); + T b = T(2) / (top - bottom); + T c = -T(2) / (zfar - znear); - T tx = - (right + left)/(right - left); - T ty = - (top + bottom)/(top - bottom); - T tz = - (zfar + znear)/(zfar - znear); + T tx = -(right + left) / (right - left); + T ty = -(top + bottom) / (top - bottom); + T tz = -(zfar + znear) / (zfar - znear); T ortho[16] = { a, 0, 0, 0, @@ -141,25 +242,27 @@ public: } //glRotate equivalent (except radians instead of degrees) - void Rotate (T ang, T x, T y, T z) { - *this = (*this) * RotateMatrix (ang, x, y, z); + void Rotate(T ang, T x, T y, T z) + { + *this = (*this) * RotateMatrix(ang, x, y, z); } // (x,y,z) must be normalized - static matrix4x4 RotateMatrix (T ang, T x, T y, T z) { + static matrix4x4 RotateMatrix(T ang, T x, T y, T z) + { matrix4x4 m; T c = cos(ang); T s = sin(ang); - m[0] = x*x*(1-c)+c; - m[1] = y*x*(1-c)+z*s; - m[2] = x*z*(1-c)-y*s; + m[0] = x * x * (1 - c) + c; + m[1] = y * x * (1 - c) + z * s; + m[2] = x * z * (1 - c) - y * s; m[3] = 0; - m[4] = x*y*(1-c)-z*s; - m[5] = y*y*(1-c)+c; - m[6] = y*z*(1-c)+x*s; + m[4] = x * y * (1 - c) - z * s; + m[5] = y * y * (1 - c) + c; + m[6] = y * z * (1 - c) + x * s; m[7] = 0; - m[8] = x*z*(1-c)+y*s; - m[9] = y*z*(1-c)-x*s; - m[10] = z*z*(1-c)+c; + m[8] = x * z * (1 - c) + y * s; + m[9] = y * z * (1 - c) - x * s; + m[10] = z * z * (1 - c) + c; m[11] = 0; m[12] = 0; m[13] = 0; @@ -167,13 +270,14 @@ public: m[15] = 1; return m; } - void RotateZ (T radians) { *this = (*this) * RotateZMatrix (radians); } - void RotateY (T radians) { *this = (*this) * RotateYMatrix (radians); } - void RotateX (T radians) { *this = (*this) * RotateXMatrix (radians); } - static matrix4x4 RotateXMatrix (T radians) { + void RotateZ(T radians) { *this = (*this) * RotateZMatrix(radians); } + void RotateY(T radians) { *this = (*this) * RotateYMatrix(radians); } + void RotateX(T radians) { *this = (*this) * RotateXMatrix(radians); } + static matrix4x4 RotateXMatrix(T radians) + { matrix4x4 m; - T cos_r = cosf (float(radians)); - T sin_r = sinf (float(radians)); + T cos_r = cosf(float(radians)); + T sin_r = sinf(float(radians)); m[0] = 1.0f; m[1] = 0; m[2] = 0; @@ -195,10 +299,11 @@ public: m[15] = 1.0f; return m; } - static matrix4x4 RotateYMatrix (T radians) { + static matrix4x4 RotateYMatrix(T radians) + { matrix4x4 m; - T cos_r = cosf (float(radians)); - T sin_r = sinf (float(radians)); + T cos_r = cosf(float(radians)); + T sin_r = sinf(float(radians)); m[0] = cos_r; m[1] = 0; m[2] = sin_r; @@ -220,7 +325,8 @@ public: m[15] = 1.0f; return m; } - static matrix4x4 RotateZMatrix (T radians) { + static matrix4x4 RotateZMatrix(T radians) + { matrix4x4 m; T cos_r = cosf(float(radians)); T sin_r = sinf(float(radians)); @@ -245,155 +351,205 @@ public: m[15] = 1.0f; return m; } - void Renormalize() { + void Renormalize() + { vector3 x(cell[0], cell[4], cell[8]); vector3 y(cell[1], cell[5], cell[9]); vector3 z(cell[2], cell[6], cell[10]); x = x.Normalized(); z = x.Cross(y).Normalized(); y = z.Cross(x).Normalized(); - cell[0] = x.x; cell[4] = x.y; cell[8] = x.z; - cell[1] = y.x; cell[5] = y.y; cell[9] = y.z; - cell[2] = z.x; cell[6] = z.y; cell[10] = z.z; + cell[0] = x.x; + cell[4] = x.y; + cell[8] = x.z; + cell[1] = y.x; + cell[5] = y.y; + cell[9] = y.z; + cell[2] = z.x; + cell[6] = z.y; + cell[10] = z.z; } - void ClearToRotOnly() { + void ClearToRotOnly() + { cell[12] = 0; cell[13] = 0; cell[14] = 0; } - T& operator [] (const size_t i) { return cell[i]; } - const T& operator[] (const size_t i) const { return cell[i]; } - const T* Data() const { return cell; } - T* Data() { return cell; } - friend matrix4x4 operator+ (const matrix4x4 &a, const matrix4x4 &b) { + T &operator[](const size_t i) { return cell[i]; } + const T &operator[](const size_t i) const { return cell[i]; } + const T *Data() const { return cell; } + T *Data() { return cell; } + friend matrix4x4 operator+(const matrix4x4 &a, const matrix4x4 &b) + { matrix4x4 m; - for (int i=0; i<16; i++) m.cell[i] = a.cell[i] + b.cell[i]; + for (int i = 0; i < 16; i++) + m.cell[i] = a.cell[i] + b.cell[i]; return m; } - friend matrix4x4 operator- (const matrix4x4 &a, const matrix4x4 &b) { + friend matrix4x4 operator-(const matrix4x4 &a, const matrix4x4 &b) + { matrix4x4 m; - for (int i=0; i<16; i++) m.cell[i] = a.cell[i] - b.cell[i]; + for (int i = 0; i < 16; i++) + m.cell[i] = a.cell[i] - b.cell[i]; return m; } - friend matrix4x4 operator- (const matrix4x4 &a) { + friend matrix4x4 operator-(const matrix4x4 &a) + { matrix4x4 m; - for (int i = 0; i < 16; ++i) { m.cell[i] = -a.cell[i]; } + for (int i = 0; i < 16; ++i) { + m.cell[i] = -a.cell[i]; + } return m; } - friend matrix4x4 operator* (const matrix4x4 &a, const matrix4x4 &b) { + friend matrix4x4 operator*(const matrix4x4 &a, const matrix4x4 &b) + { matrix4x4 m; - m.cell[0] = a.cell[0]*b.cell[0] + a.cell[4]*b.cell[1] + a.cell[8]*b.cell[2] + a.cell[12]*b.cell[3]; - m.cell[1] = a.cell[1]*b.cell[0] + a.cell[5]*b.cell[1] + a.cell[9]*b.cell[2] + a.cell[13]*b.cell[3]; - m.cell[2] = a.cell[2]*b.cell[0] + a.cell[6]*b.cell[1] + a.cell[10]*b.cell[2] + a.cell[14]*b.cell[3]; - m.cell[3] = a.cell[3]*b.cell[0] + a.cell[7]*b.cell[1] + a.cell[11]*b.cell[2] + a.cell[15]*b.cell[3]; + m.cell[0] = a.cell[0] * b.cell[0] + a.cell[4] * b.cell[1] + a.cell[8] * b.cell[2] + a.cell[12] * b.cell[3]; + m.cell[1] = a.cell[1] * b.cell[0] + a.cell[5] * b.cell[1] + a.cell[9] * b.cell[2] + a.cell[13] * b.cell[3]; + m.cell[2] = a.cell[2] * b.cell[0] + a.cell[6] * b.cell[1] + a.cell[10] * b.cell[2] + a.cell[14] * b.cell[3]; + m.cell[3] = a.cell[3] * b.cell[0] + a.cell[7] * b.cell[1] + a.cell[11] * b.cell[2] + a.cell[15] * b.cell[3]; - m.cell[4] = a.cell[0]*b.cell[4] + a.cell[4]*b.cell[5] + a.cell[8]*b.cell[6] + a.cell[12]*b.cell[7]; - m.cell[5] = a.cell[1]*b.cell[4] + a.cell[5]*b.cell[5] + a.cell[9]*b.cell[6] + a.cell[13]*b.cell[7]; - m.cell[6] = a.cell[2]*b.cell[4] + a.cell[6]*b.cell[5] + a.cell[10]*b.cell[6] + a.cell[14]*b.cell[7]; - m.cell[7] = a.cell[3]*b.cell[4] + a.cell[7]*b.cell[5] + a.cell[11]*b.cell[6] + a.cell[15]*b.cell[7]; + m.cell[4] = a.cell[0] * b.cell[4] + a.cell[4] * b.cell[5] + a.cell[8] * b.cell[6] + a.cell[12] * b.cell[7]; + m.cell[5] = a.cell[1] * b.cell[4] + a.cell[5] * b.cell[5] + a.cell[9] * b.cell[6] + a.cell[13] * b.cell[7]; + m.cell[6] = a.cell[2] * b.cell[4] + a.cell[6] * b.cell[5] + a.cell[10] * b.cell[6] + a.cell[14] * b.cell[7]; + m.cell[7] = a.cell[3] * b.cell[4] + a.cell[7] * b.cell[5] + a.cell[11] * b.cell[6] + a.cell[15] * b.cell[7]; - m.cell[8] = a.cell[0]*b.cell[8] + a.cell[4]*b.cell[9] + a.cell[8]*b.cell[10] + a.cell[12]*b.cell[11]; - m.cell[9] = a.cell[1]*b.cell[8] + a.cell[5]*b.cell[9] + a.cell[9]*b.cell[10] + a.cell[13]*b.cell[11]; - m.cell[10] = a.cell[2]*b.cell[8] + a.cell[6]*b.cell[9] + a.cell[10]*b.cell[10] + a.cell[14]*b.cell[11]; - m.cell[11] = a.cell[3]*b.cell[8] + a.cell[7]*b.cell[9] + a.cell[11]*b.cell[10] + a.cell[15]*b.cell[11]; + m.cell[8] = a.cell[0] * b.cell[8] + a.cell[4] * b.cell[9] + a.cell[8] * b.cell[10] + a.cell[12] * b.cell[11]; + m.cell[9] = a.cell[1] * b.cell[8] + a.cell[5] * b.cell[9] + a.cell[9] * b.cell[10] + a.cell[13] * b.cell[11]; + m.cell[10] = a.cell[2] * b.cell[8] + a.cell[6] * b.cell[9] + a.cell[10] * b.cell[10] + a.cell[14] * b.cell[11]; + m.cell[11] = a.cell[3] * b.cell[8] + a.cell[7] * b.cell[9] + a.cell[11] * b.cell[10] + a.cell[15] * b.cell[11]; - m.cell[12] = a.cell[0]*b.cell[12] + a.cell[4]*b.cell[13] + a.cell[8]*b.cell[14] + a.cell[12]*b.cell[15]; - m.cell[13] = a.cell[1]*b.cell[12] + a.cell[5]*b.cell[13] + a.cell[9]*b.cell[14] + a.cell[13]*b.cell[15]; - m.cell[14] = a.cell[2]*b.cell[12] + a.cell[6]*b.cell[13] + a.cell[10]*b.cell[14] + a.cell[14]*b.cell[15]; - m.cell[15] = a.cell[3]*b.cell[12] + a.cell[7]*b.cell[13] + a.cell[11]*b.cell[14] + a.cell[15]*b.cell[15]; + m.cell[12] = a.cell[0] * b.cell[12] + a.cell[4] * b.cell[13] + a.cell[8] * b.cell[14] + a.cell[12] * b.cell[15]; + m.cell[13] = a.cell[1] * b.cell[12] + a.cell[5] * b.cell[13] + a.cell[9] * b.cell[14] + a.cell[13] * b.cell[15]; + m.cell[14] = a.cell[2] * b.cell[12] + a.cell[6] * b.cell[13] + a.cell[10] * b.cell[14] + a.cell[14] * b.cell[15]; + m.cell[15] = a.cell[3] * b.cell[12] + a.cell[7] * b.cell[13] + a.cell[11] * b.cell[14] + a.cell[15] * b.cell[15]; return m; } - friend vector3 operator * (const matrix4x4 &a, const vector3 &v) { + friend vector3 operator*(const matrix4x4 &a, const vector3 &v) + { vector3 out; - out.x = a.cell[0]*v.x + a.cell[4]*v.y + a.cell[8]*v.z + a.cell[12]; - out.y = a.cell[1]*v.x + a.cell[5]*v.y + a.cell[9]*v.z + a.cell[13]; - out.z = a.cell[2]*v.x + a.cell[6]*v.y + a.cell[10]*v.z + a.cell[14]; + out.x = a.cell[0] * v.x + a.cell[4] * v.y + a.cell[8] * v.z + a.cell[12]; + out.y = a.cell[1] * v.x + a.cell[5] * v.y + a.cell[9] * v.z + a.cell[13]; + out.z = a.cell[2] * v.x + a.cell[6] * v.y + a.cell[10] * v.z + a.cell[14]; return out; } // scam for doing a transpose operation - friend vector3 operator * (const vector3 &v, const matrix4x4 &a) { + friend vector3 operator*(const vector3 &v, const matrix4x4 &a) + { vector3 out; - out.x = a.cell[0]*v.x + a.cell[1]*v.y + a.cell[2]*v.z; - out.y = a.cell[4]*v.x + a.cell[5]*v.y + a.cell[6]*v.z; - out.z = a.cell[8]*v.x + a.cell[9]*v.y + a.cell[10]*v.z; + out.x = a.cell[0] * v.x + a.cell[1] * v.y + a.cell[2] * v.z; + out.y = a.cell[4] * v.x + a.cell[5] * v.y + a.cell[6] * v.z; + out.z = a.cell[8] * v.x + a.cell[9] * v.y + a.cell[10] * v.z; return out; } - friend matrix4x4 operator* (const matrix4x4 &a, T v) { + friend matrix4x4 operator*(const matrix4x4 &a, T v) + { matrix4x4 m; - for (int i=0; i<16; i++) m[i] = a.cell[i] * v; + for (int i = 0; i < 16; i++) + m[i] = a.cell[i] * v; return m; } - friend matrix4x4 operator* (T v, const matrix4x4 &a) { - return (a*v); + friend matrix4x4 operator*(T v, const matrix4x4 &a) + { + return (a * v); } - vector3 ApplyRotationOnly (const vector3 &v) const { + vector3 ApplyRotationOnly(const vector3 &v) const + { vector3 out; - out.x = cell[0]*v.x + cell[4]*v.y + cell[8]*v.z; - out.y = cell[1]*v.x + cell[5]*v.y + cell[9]*v.z; - out.z = cell[2]*v.x + cell[6]*v.y + cell[10]*v.z; + out.x = cell[0] * v.x + cell[4] * v.y + cell[8] * v.z; + out.y = cell[1] * v.x + cell[5] * v.y + cell[9] * v.z; + out.z = cell[2] * v.x + cell[6] * v.y + cell[10] * v.z; return out; } //gltranslate equivalent - void Translate(const vector3 &t) { + void Translate(const vector3 &t) + { Translate(t.x, t.y, t.z); } - void Translate(T x, T y, T z) { - matrix4x4 m = Identity (); + void Translate(T x, T y, T z) + { + matrix4x4 m = Identity(); m[12] = x; m[13] = y; m[14] = z; *this = (*this) * m; } - static matrix4x4 Translation(const vector3 &v) { + static matrix4x4 Translation(const vector3 &v) + { return Translation(v.x, v.y, v.z); } - static matrix4x4 Translation(T x, T y, T z) { - matrix4x4 m = Identity (); + static matrix4x4 Translation(T x, T y, T z) + { + matrix4x4 m = Identity(); m[12] = x; m[13] = y; m[14] = z; return m; } - matrix4x4 Inverse() const { + matrix4x4 Inverse() const + { matrix4x4 m; // this only works for matrices containing only rotation and transform - m[0] = cell[0]; m[1] = cell[4]; m[2] = cell[8]; - m[4] = cell[1]; m[5] = cell[5]; m[6] = cell[9]; - m[8] = cell[2]; m[9] = cell[6]; m[10] = cell[10]; - m[12] = -(cell[0]*cell[12] + cell[1]*cell[13] + cell[2]*cell[14]); - m[13] = -(cell[4]*cell[12] + cell[5]*cell[13] + cell[6]*cell[14]); - m[14] = -(cell[8]*cell[12] + cell[9]*cell[13] + cell[10]*cell[14]); + m[0] = cell[0]; + m[1] = cell[4]; + m[2] = cell[8]; + m[4] = cell[1]; + m[5] = cell[5]; + m[6] = cell[9]; + m[8] = cell[2]; + m[9] = cell[6]; + m[10] = cell[10]; + m[12] = -(cell[0] * cell[12] + cell[1] * cell[13] + cell[2] * cell[14]); + m[13] = -(cell[4] * cell[12] + cell[5] * cell[13] + cell[6] * cell[14]); + m[14] = -(cell[8] * cell[12] + cell[9] * cell[13] + cell[10] * cell[14]); m[3] = m[7] = m[11] = 0; m[15] = 1.0f; return m; } - matrix4x4 Transpose() const { + matrix4x4 Transpose() const + { matrix4x4 m; - m[0] = cell[0]; m[1] = cell[4]; m[2] = cell[8]; m[3] = cell[12]; - m[4] = cell[1]; m[5] = cell[5]; m[6] = cell[9]; m[7] = cell[13]; - m[8] = cell[2]; m[9] = cell[6]; m[10] = cell[10]; m[11] = cell[14]; - m[12] = cell[3]; m[13] = cell[7]; m[14] = cell[11]; m[15] = cell[15]; + m[0] = cell[0]; + m[1] = cell[4]; + m[2] = cell[8]; + m[3] = cell[12]; + m[4] = cell[1]; + m[5] = cell[5]; + m[6] = cell[9]; + m[7] = cell[13]; + m[8] = cell[2]; + m[9] = cell[6]; + m[10] = cell[10]; + m[11] = cell[14]; + m[12] = cell[3]; + m[13] = cell[7]; + m[14] = cell[11]; + m[15] = cell[15]; return m; } - void Print () const { - for (int i=0; i<4; i++) { - printf ("%.12f %.12f %.12f %.12f\n", cell[i], cell[i+4], cell[i+8], cell[i+12]); + void Print() const + { + for (int i = 0; i < 4; i++) { + printf("%.12f %.12f %.12f %.12f\n", cell[i], cell[i + 4], cell[i + 8], cell[i + 12]); } - printf ("\n"); + printf("\n"); } //convenience accessors for getting right/up/back vectors //from rotation matrices - vector3 Right() const { + vector3 Right() const + { return vector3(cell[0], cell[4], cell[8]); } - vector3 Up() const { + vector3 Up() const + { return vector3(cell[1], cell[5], cell[9]); } - vector3 Back() const { + vector3 Back() const + { return vector3(cell[2], cell[6], cell[10]); } }; diff --git a/src/modelcompiler.cpp b/src/modelcompiler.cpp index 29684bb4a..b57be1d3d 100644 --- a/src/modelcompiler.cpp +++ b/src/modelcompiler.cpp @@ -10,22 +10,22 @@ #include "FileSystem.h" #include "GameConfig.h" +#include "GameSaveError.h" #include "JobQueue.h" -#include "graphics/dummy/RendererDummy.h" +#include "ModManager.h" +#include "OS.h" +#include "StringF.h" +#include "graphics/Drawables.h" #include "graphics/Graphics.h" #include "graphics/Light.h" #include "graphics/Renderer.h" #include "graphics/Texture.h" #include "graphics/TextureBuilder.h" -#include "graphics/Drawables.h" #include "graphics/VertexArray.h" +#include "graphics/dummy/RendererDummy.h" +#include "scenegraph/BinaryConverter.h" #include "scenegraph/DumpVisitor.h" #include "scenegraph/FindNodeVisitor.h" -#include "scenegraph/BinaryConverter.h" -#include "OS.h" -#include "StringF.h" -#include "ModManager.h" -#include "GameSaveError.h" #include std::unique_ptr s_config; @@ -40,21 +40,22 @@ void RunCompiler(const std::string &modelName, const std::string &filepath, cons // ******************************************************************************** // Overloaded PureJob class to handle compiling each model // ******************************************************************************** -class CompileJob : public Job -{ +class CompileJob : public Job { public: - CompileJob() {}; - CompileJob(const std::string &name, const std::string &path, const bool inPlace) - : m_name(name), m_path(path), m_inPlace(inPlace) {} + CompileJob(){}; + CompileJob(const std::string &name, const std::string &path, const bool inPlace) : + m_name(name), + m_path(path), + m_inPlace(inPlace) {} - virtual void OnRun() override final { RunCompiler(m_name, m_path, m_inPlace); } // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! + virtual void OnRun() override final { RunCompiler(m_name, m_path, m_inPlace); } // RUNS IN ANOTHER THREAD!! MUST BE THREAD SAFE! virtual void OnFinish() override final {} virtual void OnCancel() override final {} protected: - std::string m_name; - std::string m_path; - bool m_inPlace; + std::string m_name; + std::string m_path; + bool m_inPlace; }; // ******************************************************************************** @@ -116,8 +117,7 @@ void RunCompiler(const std::string &modelName, const std::string &filepath, cons model.reset(ld.LoadModel(modelName)); //dump warnings for (std::vector::const_iterator it = ld.GetLogMessages().begin(); - it != ld.GetLogMessages().end(); ++it) - { + it != ld.GetLogMessages().end(); ++it) { Output("%s\n", (*it).c_str()); } } catch (...) { @@ -126,33 +126,32 @@ void RunCompiler(const std::string &modelName, const std::string &filepath, cons } try { - const std::string DataPath = FileSystem::NormalisePath(filepath.substr(0, filepath.size()-6)); + const std::string DataPath = FileSystem::NormalisePath(filepath.substr(0, filepath.size() - 6)); SceneGraph::BinaryConverter bc(s_renderer.get()); bc.Save(modelName, DataPath, model.get(), bInPlace); - } catch (const CouldNotOpenFileException&) { - } catch (const CouldNotWriteToFileException&) { + } catch (const CouldNotOpenFileException &) { + } catch (const CouldNotWriteToFileException &) { } timer.Stop(); Output("Compiling \"%s\" took: %lf\n", modelName.c_str(), timer.millicycles()); } - // ******************************************************************************** // functions // ******************************************************************************** enum RunMode { - MODE_MODELCOMPILER=0, + MODE_MODELCOMPILER = 0, MODE_MODELBATCHEXPORT, MODE_VERSION, MODE_USAGE, MODE_USAGE_ERROR }; -int main(int argc, char** argv) +int main(int argc, char **argv) { #ifdef PIONEER_PROFILER - Profiler::detect( argc, argv ); + Profiler::detect(argc, argv); #endif RunMode mode = MODE_MODELCOMPILER; @@ -201,113 +200,110 @@ start: // what mode are we in? switch (mode) { - case MODE_MODELCOMPILER: { - std::string modelName; - std::string filePath; - if (argc > 2) { - filePath = modelName = argv[2]; - // determine if we're meant to be writing these in the source directory - bool isInPlace = false; - if (argc > 3) { - std::string arg3 = argv[3]; - isInPlace = (arg3 == "inplace" || arg3 == "true"); + case MODE_MODELCOMPILER: { + std::string modelName; + std::string filePath; + if (argc > 2) { + filePath = modelName = argv[2]; + // determine if we're meant to be writing these in the source directory + bool isInPlace = false; + if (argc > 3) { + std::string arg3 = argv[3]; + isInPlace = (arg3 == "inplace" || arg3 == "true"); - // find all of the models - FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; - for (FileSystem::FileEnumerator files(fileSource, "models", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) - { - const FileSystem::FileInfo &info = files.Current(); - const std::string &fpath = info.GetPath(); + // find all of the models + FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; + for (FileSystem::FileEnumerator files(fileSource, "models", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { + const FileSystem::FileInfo &info = files.Current(); + const std::string &fpath = info.GetPath(); - //check it's the expected type - if (info.IsFile()) { - if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files - const std::string shortname(info.GetName().substr(0, info.GetName().size() - 6)); - if (shortname == modelName) { - filePath = fpath; - break; - } + //check it's the expected type + if (info.IsFile()) { + if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files + const std::string shortname(info.GetName().substr(0, info.GetName().size() - 6)); + if (shortname == modelName) { + filePath = fpath; + break; } } } } - SetupRenderer(); - RunCompiler(modelName, filePath, isInPlace); } - break; + SetupRenderer(); + RunCompiler(modelName, filePath, isInPlace); + } + break; + } + + case MODE_MODELBATCHEXPORT: { + // determine if we're meant to be writing these in the source directory + bool isInPlace = false; + if (argc > 2) { + std::string arg2 = argv[2]; + isInPlace = (arg2 == "inplace" || arg2 == "true"); } - case MODE_MODELBATCHEXPORT: { - // determine if we're meant to be writing these in the source directory - bool isInPlace = false; - if (argc > 2) { - std::string arg2 = argv[2]; - isInPlace = (arg2 == "inplace" || arg2 == "true"); - } + // find all of the models + std::vector> list_model; + FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; + for (FileSystem::FileEnumerator files(fileSource, "models", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { + const FileSystem::FileInfo &info = files.Current(); + const std::string &fpath = info.GetPath(); - // find all of the models - std::vector> list_model; - FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; - for (FileSystem::FileEnumerator files(fileSource, "models", FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) - { - const FileSystem::FileInfo &info = files.Current(); - const std::string &fpath = info.GetPath(); - - //check it's the expected type - if (info.IsFile()) { - if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files - list_model.push_back( std::make_pair(info.GetName().substr(0, info.GetName().size()-6), fpath) ); - } + //check it's the expected type + if (info.IsFile()) { + if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files + list_model.push_back(std::make_pair(info.GetName().substr(0, info.GetName().size() - 6), fpath)); } } + } - SetupRenderer(); + SetupRenderer(); #if 1 - for (auto &modelName : list_model) { - RunCompiler(modelName.first, modelName.second, isInPlace); - } + for (auto &modelName : list_model) { + RunCompiler(modelName.first, modelName.second, isInPlace); + } #else - std::deque handles; - for (auto &modelName : list_model) { - handles.push_back( asyncJobQueue->Queue(new CompileJob(modelName.first, modelName.second, isInPlace)) ); - } + std::deque handles; + for (auto &modelName : list_model) { + handles.push_back(asyncJobQueue->Queue(new CompileJob(modelName.first, modelName.second, isInPlace))); + } - while(true) { - asyncJobQueue->FinishJobs(); - bool hasJobs = false; - for(auto &handle : handles) - hasJobs |= handle.HasJob(); + while (true) { + asyncJobQueue->FinishJobs(); + bool hasJobs = false; + for (auto &handle : handles) + hasJobs |= handle.HasJob(); - if(!hasJobs) - break; - } + if (!hasJobs) + break; + } #endif - break; - } + break; + } - case MODE_VERSION: { - std::string version(PIONEER_VERSION); - if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")"; - Output("modelcompiler %s\n", version.c_str()); - break; - } + case MODE_VERSION: { + std::string version(PIONEER_VERSION); + if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")"; + Output("modelcompiler %s\n", version.c_str()); + break; + } - case MODE_USAGE_ERROR: - Output("modelcompiler: unknown mode %s\n", argv[1]); - // fall through + case MODE_USAGE_ERROR: + Output("modelcompiler: unknown mode %s\n", argv[1]); + // fall through - case MODE_USAGE: - Output( - "usage: modelcompiler [mode] [options...]\n" - "available modes:\n" - " -compile [-c ...] model compiler\n" - " -compile inplace [-c ... inplace] model compiler\n" - " -batch [-b] batch mode output into users home/Pioneer directory\n" - " -batch inplace [-b inplace] batch mode output into the source folder\n" - " -version [-v] show version\n" - " -help [-h,-?] this help\n" - ); - break; + case MODE_USAGE: + Output( + "usage: modelcompiler [mode] [options...]\n" + "available modes:\n" + " -compile [-c ...] model compiler\n" + " -compile inplace [-c ... inplace] model compiler\n" + " -batch [-b] batch mode output into users home/Pioneer directory\n" + " -batch inplace [-b inplace] batch mode output into the source folder\n" + " -version [-v] show version\n" + " -help [-h,-?] this help\n"); + break; } #ifdef PIONEER_PROFILER diff --git a/src/perlin.cpp b/src/perlin.cpp index 4abc49700..b0f9e9b2d 100644 --- a/src/perlin.cpp +++ b/src/perlin.cpp @@ -56,54 +56,54 @@ inline int fastfloor(const double x) { return int(x > 0 ? x : x - 1); } //static double dot( const int* g, const double x, const double y ) { return g[0]*x + g[1]*y; } -inline double dot(const double* g, const double x, const double y, const double z) { return g[0] * x + g[1] * y + g[2] * z; } +inline double dot(const double *g, const double x, const double y, const double z) { return g[0] * x + g[1] * y + g[2] * z; } //static double dot( const int* g, const double x, const double y, const double z, const double w ) { return g[0]*x + g[1]*y + g[2]*z + g[3]*w; } // The gradients are the midpoints of the vertices of a cube. static const double grad3[12][3] = { - {1,1,0}, {-1,1,0}, {1,-1,0}, {-1,-1,0}, - {1,0,1}, {-1,0,1}, {1,0,-1}, {-1,0,-1}, - {0,1,1}, {0,-1,1}, {0,1,-1}, {0,-1,-1} + { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, + { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, { -1, 0, -1 }, + { 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 } }; // Permutation table. The same list is repeated twice. static const unsigned char perm[512] = { - 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142, - 8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117, - 35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71, - 134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41, - 55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208, 89, - 18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226, - 250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182, - 189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43, - 172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97, - 228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239, - 107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254, - 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, + 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, + 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, + 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, + 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, + 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, + 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, + 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, + 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, + 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, + 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, + 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, - 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142, - 8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117, - 35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71, - 134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41, - 55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208, 89, - 18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226, - 250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182, - 189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43, - 172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97, - 228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239, - 107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254, - 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, + 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, + 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, + 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, + 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, + 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, + 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, + 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, + 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, + 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, + 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, + 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 }; static const unsigned char mod12[] = { - 0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10, - 11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9, - 10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8, - 9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7, - 8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6, - 7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5, - 6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4, - 5,6,7,8,9,10,11,0,1,2,3 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3 }; const double F3 = 1.0 / 3.0; @@ -114,12 +114,12 @@ const double G3mul3 = 0.5; double noise(const vector3d &p) { // Skew the input space to determine which simplex cell we're in - const double s = (p.x + p.y + p.z)*F3; // Very nice and simple skew factor for 3D + const double s = (p.x + p.y + p.z) * F3; // Very nice and simple skew factor for 3D const int i = fastfloor(p.x + s); const int j = fastfloor(p.y + s); const int k = fastfloor(p.z + s); - const double t = (i + j + k)*G3; + const double t = (i + j + k) * G3; const double X0 = i - t; // Unskew the cell origin back to (x,y,z) space const double Y0 = j - t; const double Z0 = k - t; @@ -132,14 +132,56 @@ double noise(const vector3d &p) int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords - if ( x0 >= y0 ) { - if (y0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // X Y Z order - else if ( x0 >= z0 ) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } // X Z Y order - else { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } // Z X Y order + if (x0 >= y0) { + if (y0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 1; + k2 = 0; + } // X Y Z order + else if (x0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 0; + k2 = 1; + } // X Z Y order + else { + i1 = 0; + j1 = 0; + k1 = 1; + i2 = 1; + j2 = 0; + k2 = 1; + } // Z X Y order } else { // x0 #include +#include int main() { - double x,y,z; + double x, y, z; double a = 0.0; - x = 0.0; y = 0.0; z = 0.0; - for (int i=0; i<10000000; i++) { - a += noise(x,y,z); + x = 0.0; + y = 0.0; + z = 0.0; + for (int i = 0; i < 10000000; i++) { + a += noise(x, y, z); x += 0.1; y += 0.2; z += 0.3; diff --git a/src/posix/FileSystemPosix.cpp b/src/posix/FileSystemPosix.cpp index 767f6e8b3..55005f45f 100644 --- a/src/posix/FileSystemPosix.cpp +++ b/src/posix/FileSystemPosix.cpp @@ -1,16 +1,16 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "libs.h" #include "FileSystem.h" +#include "libs.h" #include "utils.h" -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include +#include // on unix this is set from configure #ifndef PIONEER_DATA_DIR @@ -25,11 +25,13 @@ namespace FileSystem { static FileInfo::FileType stat_path(const char *, Time::DateTime &); - static std::string absolute_path(const std::string &path) { - if (!path.empty() && path[0] == '/') { return path; } - else { + static std::string absolute_path(const std::string &path) + { + if (!path.empty() && path[0] == '/') { + return path; + } else { const size_t bufsize = 512; - std::unique_ptr buf(static_cast(std::malloc(bufsize))); + std::unique_ptr buf(static_cast(std::malloc(bufsize))); char *cwd = getcwd(buf.get(), bufsize); if (!cwd) { Output("failed to get current working directory\n"); @@ -47,7 +49,7 @@ namespace FileSystem { static std::string FindUserDir() { std::string path = getenv("HOME"); - if (!path.empty() && (path[path.size()-1] != '/')) { + if (!path.empty() && (path[path.size() - 1] != '/')) { path += '/'; } @@ -59,40 +61,39 @@ namespace FileSystem { return path; } - static std::string FindDataDir() - { + static std::string FindDataDir() + { #ifdef _XCODE - // On OSX, the data directory is located in the resources folder of the application - // bundle (Contents/Resources). Rather than using cwd (which is the cwd of the app.bundle - // folder) - // - This is XCode/App Bundle specific - std::string path; + // On OSX, the data directory is located in the resources folder of the application + // bundle (Contents/Resources). Rather than using cwd (which is the cwd of the app.bundle + // folder) + // - This is XCode/App Bundle specific + std::string path; - char appbundlepath[MAXPATHLEN]; - CFBundleRef mainBundle = CFBundleGetMainBundle(); - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); - if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)appbundlepath, MAXPATHLEN)) - { - path = appbundlepath; - path += '/'; - path += PIONEER_DATA_DIR; - } - CFRelease(resourcesURL); - return path; + char appbundlepath[MAXPATHLEN]; + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); + if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)appbundlepath, MAXPATHLEN)) { + path = appbundlepath; + path += '/'; + path += PIONEER_DATA_DIR; + } + CFRelease(resourcesURL); + return path; #else - /* PIONEER_DATA_DIR should point to ${prefix}/share/pioneer/data. + /* PIONEER_DATA_DIR should point to ${prefix}/share/pioneer/data. * If this directory does not exist, try to use the "data" folder * in the current directory. */ - Time::DateTime mtime; - std::string str = absolute_path(std::string(PIONEER_DATA_DIR)); - FileInfo::FileType ty = stat_path(str.c_str(), mtime); + Time::DateTime mtime; + std::string str = absolute_path(std::string(PIONEER_DATA_DIR)); + FileInfo::FileType ty = stat_path(str.c_str(), mtime); - if (ty == FileInfo::FT_DIR) - return str; + if (ty == FileInfo::FT_DIR) + return str; - return absolute_path(std::string("data")); + return absolute_path(std::string("data")); #endif - } + } std::string GetUserDir() { @@ -102,16 +103,17 @@ namespace FileSystem { std::string GetDataDir() { - static const std::string data_path = FindDataDir(); + static const std::string data_path = FindDataDir(); return data_path; } - FileSourceFS::FileSourceFS(const std::string &root, bool trusted): + FileSourceFS::FileSourceFS(const std::string &root, bool trusted) : FileSource(absolute_path(root), trusted) {} FileSourceFS::~FileSourceFS() {} - static FileInfo::FileType interpret_stat(const struct stat &info, Time::DateTime &mtime) { + static FileInfo::FileType interpret_stat(const struct stat &info, Time::DateTime &mtime) + { FileInfo::FileType ty; if (S_ISREG(info.st_mode)) { ty = FileInfo::FT_FILE; @@ -124,14 +126,15 @@ namespace FileSystem { struct tm timeparts; if (localtime_r(&info.st_mtime, &timeparts) != nullptr) { mtime = Time::DateTime( - 1900 + timeparts.tm_year, timeparts.tm_mon+1, timeparts.tm_mday, + 1900 + timeparts.tm_year, timeparts.tm_mon + 1, timeparts.tm_mday, timeparts.tm_hour, timeparts.tm_min, timeparts.tm_sec); } return ty; } - static FileInfo::FileType stat_path(const char *fullpath, Time::DateTime &mtime) { + static FileInfo::FileType stat_path(const char *fullpath, Time::DateTime &mtime) + { struct stat info; if (stat(fullpath, &info) == 0) { return interpret_stat(info, mtime); @@ -162,7 +165,7 @@ namespace FileSystem { fseek(fl, 0, SEEK_END); long sz = ftell(fl); fseek(fl, 0, SEEK_SET); - char *data = static_cast(std::malloc(sz)); + char *data = static_cast(std::malloc(sz)); if (!data) { // XXX handling memory allocation failure gracefully is too hard right now Output("failed when allocating buffer for '%s'\n", fullpath.c_str()); @@ -187,7 +190,9 @@ namespace FileSystem { { const std::string fulldirpath = JoinPathBelow(GetRoot(), dirpath); DIR *dir = opendir(fulldirpath.c_str()); - if (!dir) { return false; } + if (!dir) { + return false; + } struct dirent *entry; const size_t output_head_size = output.size(); @@ -219,25 +224,23 @@ namespace FileSystem { { // allow multiple tries (to build parent directories) while (true) { - if (mkdir(path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == -1) { + if (mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == -1) { switch (errno) { - case EEXIST: - { - struct stat statinfo; - stat(path.c_str(), &statinfo); - return S_ISDIR(statinfo.st_mode); - } - case ENOENT: - { - size_t pos = path.rfind('/'); - if (pos != std::string::npos) { - const std::string dirname = path.substr(0, pos-1); - if (dirname.empty() || !make_directory_raw(dirname)) { - return false; - } - } else + case EEXIST: { + struct stat statinfo; + stat(path.c_str(), &statinfo); + return S_ISDIR(statinfo.st_mode); + } + case ENOENT: { + size_t pos = path.rfind('/'); + if (pos != std::string::npos) { + const std::string dirname = path.substr(0, pos - 1); + if (dirname.empty() || !make_directory_raw(dirname)) { return false; - } + } + } else + return false; + } default: return false; } } else { @@ -252,15 +255,15 @@ namespace FileSystem { return make_directory_raw(fullpath); } - FILE* FileSourceFS::OpenReadStream(const std::string &path) + FILE *FileSourceFS::OpenReadStream(const std::string &path) { const std::string fullpath = JoinPathBelow(GetRoot(), path); return fopen(fullpath.c_str(), "rb"); } - FILE* FileSourceFS::OpenWriteStream(const std::string &path, int flags) + FILE *FileSourceFS::OpenWriteStream(const std::string &path, int flags) { const std::string fullpath = JoinPathBelow(GetRoot(), path); return fopen(fullpath.c_str(), (flags & WRITE_TEXT) ? "w" : "wb"); } -} +} // namespace FileSystem diff --git a/src/posix/OSPosix.cpp b/src/posix/OSPosix.cpp index 87d5ec365..16ab51714 100644 --- a/src/posix/OSPosix.cpp +++ b/src/posix/OSPosix.cpp @@ -1,11 +1,11 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "OS.h" #include "FileSystem.h" +#include "OS.h" #include -#include #include +#include #if defined(__APPLE__) #include #include @@ -20,120 +20,123 @@ namespace OS { static const std::string s_NoOSIdentified("No OS Identified\n"); } -void NotifyLoadBegin() -{ -} + void NotifyLoadBegin() + { + } -void NotifyLoadEnd() -{ -} + void NotifyLoadEnd() + { + } -const char *GetIconFilename() -{ - return "icons/badge.png"; -} + const char *GetIconFilename() + { + return "icons/badge.png"; + } -void RedirectStdio() -{ - std::string output_path = FileSystem::JoinPath(FileSystem::GetUserDir(), "output.txt"); + void RedirectStdio() + { + std::string output_path = FileSystem::JoinPath(FileSystem::GetUserDir(), "output.txt"); - FILE *f; + FILE *f; - f = freopen(output_path.c_str(), "w", stderr); - if (!f) - Output("ERROR: Couldn't redirect output to '%s': %s\n", output_path.c_str(), strerror(errno)); - else - setvbuf(f, 0, _IOLBF, BUFSIZ); -} + f = freopen(output_path.c_str(), "w", stderr); + if (!f) + Output("ERROR: Couldn't redirect output to '%s': %s\n", output_path.c_str(), strerror(errno)); + else + setvbuf(f, 0, _IOLBF, BUFSIZ); + } -void EnableFPE() -{ + void EnableFPE() + { #if defined(_GNU_SOURCE) && !defined(__APPLE__) - // clear any outstanding exceptions before enabling, otherwise they'll - // trip immediately - feclearexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); - feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + // clear any outstanding exceptions before enabling, otherwise they'll + // trip immediately + feclearexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); #endif -} + } -void DisableFPE() -{ + void DisableFPE() + { #if defined(_GNU_SOURCE) && !defined(__APPLE__) - fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); #endif -} + } -Uint64 HFTimerFreq() -{ - return 1000000; -} + Uint64 HFTimerFreq() + { + return 1000000; + } -Uint64 HFTimer() -{ - timeval t; - gettimeofday(&t, 0); - return Uint64(t.tv_sec)*1000000 + Uint64(t.tv_usec); -} + Uint64 HFTimer() + { + timeval t; + gettimeofday(&t, 0); + return Uint64(t.tv_sec) * 1000000 + Uint64(t.tv_usec); + } -int GetNumCores() -{ + int GetNumCores() + { #if defined(__APPLE__) - int nm[2]; - size_t len = 4; - u_int count; + int nm[2]; + size_t len = 4; + u_int count; - nm[0] = CTL_HW; nm[1] = HW_AVAILCPU; - sysctl(nm, 2, &count, &len, NULL, 0); - - if (count < 1) { - nm[1] = HW_NCPU; + nm[0] = CTL_HW; + nm[1] = HW_AVAILCPU; sysctl(nm, 2, &count, &len, NULL, 0); - if(count < 1) { count = 1; } - } - return count; + + if (count < 1) { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + if (count < 1) { + count = 1; + } + } + return count; #else - return sysconf(_SC_NPROCESSORS_ONLN); + return sysconf(_SC_NPROCESSORS_ONLN); #endif -} - -const std::string GetOSInfoString() -{ - int z; - struct utsname uts; - z = uname(&uts); - - if ( z == -1 ) { - return s_NoOSIdentified; } - char infoString[2048]; + const std::string GetOSInfoString() + { + int z; + struct utsname uts; + z = uname(&uts); + + if (z == -1) { + return s_NoOSIdentified; + } + + char infoString[2048]; #if !defined(_GNU_SOURCE) - snprintf(infoString, 2048, "System Name: %s\nHost Name: %s\nRelease(Kernel) Version: %s\nKernel Build Timestamp: %s\nMachine Arch: %s\n", - uts.sysname, uts.nodename, uts.release, uts.version, uts.machine); + snprintf(infoString, 2048, "System Name: %s\nHost Name: %s\nRelease(Kernel) Version: %s\nKernel Build Timestamp: %s\nMachine Arch: %s\n", + uts.sysname, uts.nodename, uts.release, uts.version, uts.machine); #else - snprintf(infoString, 2048, "System Name: %s\nHost Name: %s\nRelease(Kernel) Version: %s\nKernel Build Timestamp: %s\nMachine Arch: %s\nDomain Name: %s\n", - uts.sysname, uts.nodename, uts.release, uts.version, uts.machine, uts.domainname); + snprintf(infoString, 2048, "System Name: %s\nHost Name: %s\nRelease(Kernel) Version: %s\nKernel Build Timestamp: %s\nMachine Arch: %s\nDomain Name: %s\n", + uts.sysname, uts.nodename, uts.release, uts.version, uts.machine, uts.domainname); #endif - return std::string(infoString); -} + return std::string(infoString); + } -void EnableBreakpad() -{ - // Support for Mac and Linux should be added -} + void EnableBreakpad() + { + // Support for Mac and Linux should be added + } -// Open the Explorer/Finder/etc -bool SupportsFolderBrowser() -{ - return false; -} + // Open the Explorer/Finder/etc + bool SupportsFolderBrowser() + { + return false; + } -void OpenUserFolderBrowser() -{ - // Support for Mac and Linux should be added - // Display the path instead for now - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Pioneer", FileSystem::userFiles.GetRoot().c_str(), 0); -} + void OpenUserFolderBrowser() + { + // Support for Mac and Linux should be added + // Display the path instead for now + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Pioneer", FileSystem::userFiles.GetRoot().c_str(), 0); + } } // namespace OS diff --git a/src/savegamedump.cpp b/src/savegamedump.cpp index 24f920e28..d41e00855 100644 --- a/src/savegamedump.cpp +++ b/src/savegamedump.cpp @@ -1,65 +1,67 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Json.h" #include "FileSystem.h" #include "GZipFormat.h" +#include "Json.h" -int main(int argc, const char **argv) { - if (argc < 2 || argc > 3) { - printf( - "savegamedump - Dump saved games to JSON for easy inspection.\n" - "All paths are relative to the pioneer data folder.\n" - "USAGE: savegamedump [output]\n" - ); - return 1; - } - std::string filename = argv[1]; - std::string outname = argc > 2 ? argv[2] : filename + ".json"; +int main(int argc, const char **argv) +{ + if (argc < 2 || argc > 3) { + printf( + "savegamedump - Dump saved games to JSON for easy inspection.\n" + "All paths are relative to the pioneer data folder.\n" + "USAGE: savegamedump [output]\n"); + return 1; + } + std::string filename = argv[1]; + std::string outname = argc > 2 ? argv[2] : filename + ".json"; - auto fileinfo = FileSystem::userFiles.Lookup(filename); - if (!fileinfo.Exists()) { - printf("Input file %s could not be found.\n", filename.c_str()); - printf("%s\n", fileinfo.GetPath().c_str()); - return 1; - } + auto fileinfo = FileSystem::userFiles.Lookup(filename); + if (!fileinfo.Exists()) { + printf("Input file %s could not be found.\n", filename.c_str()); + printf("%s\n", fileinfo.GetPath().c_str()); + return 1; + } - auto file = FileSystem::userFiles.ReadFile(filename); + auto file = FileSystem::userFiles.ReadFile(filename); if (!file) { - printf( "Could not open file %s.\n", filename.c_str()); - return 1; - } + printf("Could not open file %s.\n", filename.c_str()); + return 1; + } const auto compressed_data = file->AsByteRange(); - Json rootNode; + Json rootNode; try { - const std::string plain_data = gzip::DecompressDeflateOrGZip(reinterpret_cast(compressed_data.begin), compressed_data.Size()); + const std::string plain_data = gzip::DecompressDeflateOrGZip(reinterpret_cast(compressed_data.begin), compressed_data.Size()); try { // Allow loading files in JSON format as well as CBOR - if (plain_data[0] == '{') rootNode = Json::parse(plain_data); - else rootNode = Json::from_cbor(plain_data); + if (plain_data[0] == '{') + rootNode = Json::parse(plain_data); + else + rootNode = Json::from_cbor(plain_data); } catch (Json::parse_error &e) { printf("Saved game is not a valid JSON object: %s.\n", e.what()); return 2; } if (!rootNode.is_object()) { - printf("Saved game's root is not a JSON object.\n"); - return 2; - } + printf("Saved game's root is not a JSON object.\n"); + return 2; + } } catch (gzip::DecompressionFailedException) { printf("Decompressing saved data failed - saved game is corrupt.\n"); - return 3; + return 3; } - auto outFile = FileSystem::userFiles.OpenWriteStream(outname); - if (!outFile) { - printf("Could not open output file %s.\n", outname.c_str()); - return 1; - } + auto outFile = FileSystem::userFiles.OpenWriteStream(outname); + if (!outFile) { + printf("Could not open output file %s.\n", outname.c_str()); + return 1; + } - fputs(rootNode.dump(2).c_str(), outFile); - fclose(outFile); + fputs(rootNode.dump(2).c_str(), outFile); + fclose(outFile); - return 0; + return 0; } diff --git a/src/scenegraph/Animation.cpp b/src/scenegraph/Animation.cpp index d0e9dfbee..8b8971498 100644 --- a/src/scenegraph/Animation.cpp +++ b/src/scenegraph/Animation.cpp @@ -7,129 +7,129 @@ namespace SceneGraph { -typedef std::vector ChannelList; -typedef ChannelList::iterator ChannelIterator; + typedef std::vector ChannelList; + typedef ChannelList::iterator ChannelIterator; -Animation::Animation(const std::string &name, double duration) -: m_duration(duration) -, m_time(0.0) -, m_name(name) -{ -} - -Animation::Animation(const Animation &anim) -: m_duration(anim.m_duration) -, m_time(0.0) -, m_name(anim.m_name) -{ - for(ChannelList::const_iterator chan = anim.m_channels.begin(); chan != anim.m_channels.end(); ++chan) { - m_channels.push_back(*chan); + Animation::Animation(const std::string &name, double duration) : + m_duration(duration), + m_time(0.0), + m_name(name) + { } -} -void Animation::UpdateChannelTargets(Node *root) -{ - for(ChannelList::iterator chan = m_channels.begin(); chan != m_channels.end(); ++chan) { - //update channels to point to new node structure - MatrixTransform *trans = dynamic_cast(root->FindNode(chan->node->GetName())); - assert(trans); - chan->node = trans; + Animation::Animation(const Animation &anim) : + m_duration(anim.m_duration), + m_time(0.0), + m_name(anim.m_name) + { + for (ChannelList::const_iterator chan = anim.m_channels.begin(); chan != anim.m_channels.end(); ++chan) { + m_channels.push_back(*chan); + } } -} -void Animation::Interpolate() -{ - PROFILE_SCOPED() - const double mtime = m_time; - - //go through channels and calculate transforms - for(ChannelIterator chan = m_channels.begin(); chan != m_channels.end(); ++chan) { - matrix4x4f trans = chan->node->GetTransform(); - - if (!chan->rotationKeys.empty()) { - //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) - unsigned int frame = 0; - while (frame + 1 < chan->rotationKeys.size()) { - if (mtime < chan->rotationKeys[frame+1].time) - break; - frame++; - } - - const RotationKey &a = chan->rotationKeys[frame]; - vector3f saved_position = trans.GetTranslate(); - if (frame + 1 < chan->rotationKeys.size()) { - const RotationKey &b = chan->rotationKeys[frame + 1]; - double diffTime = b.time - a.time; - assert(diffTime > 0.0); - const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); - trans = Quaternionf::Slerp(a.rotation, b.rotation, factor).ToMatrix3x3(); - } else { - trans = a.rotation.ToMatrix3x3(); - } - trans.SetTranslate(saved_position); + void Animation::UpdateChannelTargets(Node *root) + { + for (ChannelList::iterator chan = m_channels.begin(); chan != m_channels.end(); ++chan) { + //update channels to point to new node structure + MatrixTransform *trans = dynamic_cast(root->FindNode(chan->node->GetName())); + assert(trans); + chan->node = trans; } - - //scaling will not work without rotation since it would - //continously scale the transform (would have to add originalTransform or - //something to MT) - if (!chan->scaleKeys.empty() && !chan->rotationKeys.empty()) { - //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) - unsigned int frame = 0; - while (frame + 1 < chan->scaleKeys.size()) { - if (mtime < chan->scaleKeys[frame+1].time) - break; - frame++; - } - - const ScaleKey &a = chan->scaleKeys[frame]; - vector3f out; - if (frame + 1 < chan->scaleKeys.size()) { - const ScaleKey &b = chan->scaleKeys[frame + 1]; - double diffTime = b.time - a.time; - assert(diffTime > 0.0); - const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); - out = a.scale + (b.scale - a.scale) * factor; - } else { - out = a.scale; - } - trans.Scale(out.x, out.y, out.z); - } - - if (!chan->positionKeys.empty()) { - //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) - unsigned int frame = 0; - while (frame + 1 < chan->positionKeys.size()) { - if (mtime < chan->positionKeys[frame+1].time) - break; - frame++; - } - - const PositionKey &a = chan->positionKeys[frame]; - vector3f out; - if (frame + 1 < chan->positionKeys.size()) { - const PositionKey &b = chan->positionKeys[frame + 1]; - double diffTime = b.time - a.time; - assert(diffTime > 0.0); - const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); - out = a.position + (b.position - a.position) * factor; - } else { - out = a.position; - } - trans.SetTranslate(out); - } - - chan->node->SetTransform(trans); } -} -double Animation::GetProgress() -{ - return m_time / m_duration; -} + void Animation::Interpolate() + { + PROFILE_SCOPED() + const double mtime = m_time; -void Animation::SetProgress(double prog) -{ - m_time = Clamp(prog, 0.0, 1.0) * m_duration; -} + //go through channels and calculate transforms + for (ChannelIterator chan = m_channels.begin(); chan != m_channels.end(); ++chan) { + matrix4x4f trans = chan->node->GetTransform(); -} + if (!chan->rotationKeys.empty()) { + //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) + unsigned int frame = 0; + while (frame + 1 < chan->rotationKeys.size()) { + if (mtime < chan->rotationKeys[frame + 1].time) + break; + frame++; + } + + const RotationKey &a = chan->rotationKeys[frame]; + vector3f saved_position = trans.GetTranslate(); + if (frame + 1 < chan->rotationKeys.size()) { + const RotationKey &b = chan->rotationKeys[frame + 1]; + double diffTime = b.time - a.time; + assert(diffTime > 0.0); + const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); + trans = Quaternionf::Slerp(a.rotation, b.rotation, factor).ToMatrix3x3(); + } else { + trans = a.rotation.ToMatrix3x3(); + } + trans.SetTranslate(saved_position); + } + + //scaling will not work without rotation since it would + //continously scale the transform (would have to add originalTransform or + //something to MT) + if (!chan->scaleKeys.empty() && !chan->rotationKeys.empty()) { + //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) + unsigned int frame = 0; + while (frame + 1 < chan->scaleKeys.size()) { + if (mtime < chan->scaleKeys[frame + 1].time) + break; + frame++; + } + + const ScaleKey &a = chan->scaleKeys[frame]; + vector3f out; + if (frame + 1 < chan->scaleKeys.size()) { + const ScaleKey &b = chan->scaleKeys[frame + 1]; + double diffTime = b.time - a.time; + assert(diffTime > 0.0); + const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); + out = a.scale + (b.scale - a.scale) * factor; + } else { + out = a.scale; + } + trans.Scale(out.x, out.y, out.z); + } + + if (!chan->positionKeys.empty()) { + //find a frame. To optimize, should begin search from previous frame (when mTime > previous mTime) + unsigned int frame = 0; + while (frame + 1 < chan->positionKeys.size()) { + if (mtime < chan->positionKeys[frame + 1].time) + break; + frame++; + } + + const PositionKey &a = chan->positionKeys[frame]; + vector3f out; + if (frame + 1 < chan->positionKeys.size()) { + const PositionKey &b = chan->positionKeys[frame + 1]; + double diffTime = b.time - a.time; + assert(diffTime > 0.0); + const float factor = Clamp(float((mtime - a.time) / diffTime), 0.f, 1.f); + out = a.position + (b.position - a.position) * factor; + } else { + out = a.position; + } + trans.SetTranslate(out); + } + + chan->node->SetTransform(trans); + } + } + + double Animation::GetProgress() + { + return m_time / m_duration; + } + + void Animation::SetProgress(double prog) + { + m_time = Clamp(prog, 0.0, 1.0) * m_duration; + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Animation.h b/src/scenegraph/Animation.h index 21165b28b..e411c6646 100644 --- a/src/scenegraph/Animation.h +++ b/src/scenegraph/Animation.h @@ -12,31 +12,31 @@ namespace SceneGraph { -class Loader; -class BinaryConverter; -class Node; + class Loader; + class BinaryConverter; + class Node; -class Animation { -public: - Animation(const std::string &name, double duration); - Animation(const Animation&); - void UpdateChannelTargets(Node *root); - double GetDuration() const { return m_duration; } - const std::string &GetName() const { return m_name; } - double GetProgress(); - void SetProgress(double); //0.0 -- 1.0, overrides m_time - void Interpolate(); //update transforms according to m_time; - const std::vector& GetChannels() const { return m_channels; } + class Animation { + public: + Animation(const std::string &name, double duration); + Animation(const Animation &); + void UpdateChannelTargets(Node *root); + double GetDuration() const { return m_duration; } + const std::string &GetName() const { return m_name; } + double GetProgress(); + void SetProgress(double); //0.0 -- 1.0, overrides m_time + void Interpolate(); //update transforms according to m_time; + const std::vector &GetChannels() const { return m_channels; } -private: - friend class Loader; - friend class BinaryConverter; - double m_duration; - double m_time; - std::string m_name; - std::vector m_channels; -}; + private: + friend class Loader; + friend class BinaryConverter; + double m_duration; + double m_time; + std::string m_name; + std::vector m_channels; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/AnimationChannel.h b/src/scenegraph/AnimationChannel.h index 09629eae8..dabed3eb5 100644 --- a/src/scenegraph/AnimationChannel.h +++ b/src/scenegraph/AnimationChannel.h @@ -6,19 +6,20 @@ /* * Animation channel affecting a single transform node */ -#include "MatrixTransform.h" #include "AnimationKey.h" +#include "MatrixTransform.h" namespace SceneGraph { -class AnimationChannel { -public: - AnimationChannel(MatrixTransform *t) : node(t) { } - std::vector positionKeys; - std::vector rotationKeys; - std::vector scaleKeys; - MatrixTransform *node; -}; + class AnimationChannel { + public: + AnimationChannel(MatrixTransform *t) : + node(t) {} + std::vector positionKeys; + std::vector rotationKeys; + std::vector scaleKeys; + MatrixTransform *node; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/AnimationKey.h b/src/scenegraph/AnimationKey.h index 70fa32adb..0850c06c2 100644 --- a/src/scenegraph/AnimationKey.h +++ b/src/scenegraph/AnimationKey.h @@ -4,41 +4,42 @@ #ifndef _SCENEGRAPH_ANIMATIONKEY_H #define _SCENEGRAPH_ANIMATIONKEY_H -#include "vector3.h" #include "Quaternion.h" +#include "vector3.h" namespace SceneGraph { -struct AnimationKey { - double time; + struct AnimationKey { + double time; - AnimationKey(double t) : time(t) { } -}; + AnimationKey(double t) : + time(t) {} + }; -struct PositionKey : public AnimationKey { - vector3f position; + struct PositionKey : public AnimationKey { + vector3f position; - PositionKey(double t, const vector3f &pos) - : AnimationKey(t) - , position(pos) { } -}; + PositionKey(double t, const vector3f &pos) : + AnimationKey(t), + position(pos) {} + }; -struct RotationKey : public AnimationKey { - Quaternionf rotation; + struct RotationKey : public AnimationKey { + Quaternionf rotation; - RotationKey(double t, const Quaternionf &q) - : AnimationKey(t) - , rotation(q) { } -}; + RotationKey(double t, const Quaternionf &q) : + AnimationKey(t), + rotation(q) {} + }; -struct ScaleKey : public AnimationKey { - vector3f scale; + struct ScaleKey : public AnimationKey { + vector3f scale; - ScaleKey(double t, const vector3f &s) - : AnimationKey(t) - , scale(s) { } -}; + ScaleKey(double t, const vector3f &s) : + AnimationKey(t), + scale(s) {} + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/BaseLoader.cpp b/src/scenegraph/BaseLoader.cpp index a17e2fc2a..b2bc3bc20 100644 --- a/src/scenegraph/BaseLoader.cpp +++ b/src/scenegraph/BaseLoader.cpp @@ -8,12 +8,13 @@ using namespace SceneGraph; -BaseLoader::BaseLoader(Graphics::Renderer *r) -: m_renderer(r) -, m_model(nullptr) +BaseLoader::BaseLoader(Graphics::Renderer *r) : + m_renderer(r), + m_model(nullptr) { Graphics::Texture *sdfTex = Graphics::TextureBuilder("fonts/label3d.dds", - Graphics::LINEAR_CLAMP, true, true, true).GetOrCreateTexture(r, "model"); + Graphics::LINEAR_CLAMP, true, true, true) + .GetOrCreateTexture(r, "model"); m_labelFont.Reset(new Text::DistanceFieldFont("fonts/sdf_definition.txt", sdfTex)); } @@ -68,14 +69,13 @@ void BaseLoader::ConvertMaterialDefinition(const MaterialDefinition &mdef) if (!normTex.empty()) mat->texture6 = Graphics::TextureBuilder::Normal(normTex).GetOrCreateTexture(m_renderer, "model"); - m_model->m_materials.push_back(std::make_pair(mdef.name, mat)); } RefCountedPtr BaseLoader::GetDecalMaterial(unsigned int index) { assert(index <= Model::MAX_DECAL_MATERIALS); - RefCountedPtr &decMat = m_model->m_decalMaterials[index-1]; + RefCountedPtr &decMat = m_model->m_decalMaterials[index - 1]; if (!decMat.Valid()) { Graphics::MaterialDescriptor matDesc; matDesc.textures = 1; diff --git a/src/scenegraph/BaseLoader.h b/src/scenegraph/BaseLoader.h index 21e87131b..2b2f7f6fc 100644 --- a/src/scenegraph/BaseLoader.h +++ b/src/scenegraph/BaseLoader.h @@ -6,37 +6,37 @@ /** * Model loader baseclass */ -#include "libs.h" -#include "Model.h" #include "LoaderDefinitions.h" +#include "Model.h" #include "StaticGeometry.h" #include "graphics/Material.h" +#include "libs.h" #include "text/DistanceFieldFont.h" namespace SceneGraph { -class BaseLoader { -public: - BaseLoader(Graphics::Renderer *r); + class BaseLoader { + public: + BaseLoader(Graphics::Renderer *r); - Graphics::Renderer *GetRenderer() const { return m_renderer; } - RefCountedPtr GetLabel3DFont() const { return m_labelFont; } + Graphics::Renderer *GetRenderer() const { return m_renderer; } + RefCountedPtr GetLabel3DFont() const { return m_labelFont; } - //allocate material for dynamic decal, should be used in order 1..4 - RefCountedPtr GetDecalMaterial(unsigned int index); + //allocate material for dynamic decal, should be used in order 1..4 + RefCountedPtr GetDecalMaterial(unsigned int index); -protected: - Graphics::Renderer *m_renderer; - Model *m_model; - std::string m_curPath; //path of current model file - RefCountedPtr m_labelFont; + protected: + Graphics::Renderer *m_renderer; + Model *m_model; + std::string m_curPath; //path of current model file + RefCountedPtr m_labelFont; - //create a material from definition and add it to m_model - void ConvertMaterialDefinition(const MaterialDefinition&); - //find pattern texture files from the model directory - void FindPatterns(PatternContainer &output); - void SetUpPatterns(); -}; + //create a material from definition and add it to m_model + void ConvertMaterialDefinition(const MaterialDefinition &); + //find pattern texture files from the model directory + void FindPatterns(PatternContainer &output); + void SetUpPatterns(); + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Billboard.cpp b/src/scenegraph/Billboard.cpp index 2aae2a96f..cdea796e5 100644 --- a/src/scenegraph/Billboard.cpp +++ b/src/scenegraph/Billboard.cpp @@ -5,47 +5,47 @@ #include "Model.h" #include "NodeVisitor.h" #include "graphics/Graphics.h" -#include "graphics/Renderer.h" -#include "graphics/VertexArray.h" -#include "graphics/VertexBuffer.h" #include "graphics/Material.h" #include "graphics/RenderState.h" +#include "graphics/Renderer.h" #include "graphics/Stats.h" +#include "graphics/VertexArray.h" +#include "graphics/VertexBuffer.h" namespace SceneGraph { -Billboard::Billboard(Graphics::VertexArray& bbVA, Graphics::Renderer *r, float size) -: Node(r, NODE_TRANSPARENT) -, m_bbVA(bbVA) -, m_size(size) -{ -} + Billboard::Billboard(Graphics::VertexArray &bbVA, Graphics::Renderer *r, float size) : + Node(r, NODE_TRANSPARENT), + m_bbVA(bbVA), + m_size(size) + { + } -Billboard::Billboard(const Billboard &billboard, NodeCopyCache *cache) -: Node(billboard, cache) -, m_bbVA(billboard.m_bbVA) -, m_size(billboard.m_size) -{ -} + Billboard::Billboard(const Billboard &billboard, NodeCopyCache *cache) : + Node(billboard, cache), + m_bbVA(billboard.m_bbVA), + m_size(billboard.m_size) + { + } -Node* Billboard::Clone(NodeCopyCache *cache) -{ - return new Billboard(*this, cache); -} + Node *Billboard::Clone(NodeCopyCache *cache) + { + return new Billboard(*this, cache); + } -void Billboard::Accept(NodeVisitor &nv) -{ - nv.ApplyBillboard(*this); -} + void Billboard::Accept(NodeVisitor &nv) + { + nv.ApplyBillboard(*this); + } -void Billboard::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() + void Billboard::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() - //some hand-tweaked scaling, to make the lights seem larger from distance (final size is in pixels) - const float pixrad = Clamp(Graphics::GetScreenHeight() / trans.GetTranslate().Length(), 1.0f, 15.0f); - const float size = (m_size * Graphics::GetFovFactor()) * pixrad; - m_bbVA.Add(trans * vector3f(0.0f), vector3f(m_colorUVoffset, size)); -} + //some hand-tweaked scaling, to make the lights seem larger from distance (final size is in pixels) + const float pixrad = Clamp(Graphics::GetScreenHeight() / trans.GetTranslate().Length(), 1.0f, 15.0f); + const float size = (m_size * Graphics::GetFovFactor()) * pixrad; + m_bbVA.Add(trans * vector3f(0.0f), vector3f(m_colorUVoffset, size)); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/Billboard.h b/src/scenegraph/Billboard.h index f5382c68b..80a105414 100644 --- a/src/scenegraph/Billboard.h +++ b/src/scenegraph/Billboard.h @@ -12,26 +12,26 @@ namespace Graphics { class Material; class VertexBuffer; class RenderState; -} +} // namespace Graphics namespace SceneGraph { -class Billboard : public Node { -public: - Billboard(Graphics::VertexArray& bbVA, Graphics::Renderer *r, float size); - Billboard(const Billboard&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0); - virtual void Accept(NodeVisitor &v); - virtual const char *GetTypeName() const { return "Billboard"; } - virtual void Render(const matrix4x4f &trans, const RenderData *rd); - void SetColorUVoffset(const vector2f& c) { m_colorUVoffset = c; } + class Billboard : public Node { + public: + Billboard(Graphics::VertexArray &bbVA, Graphics::Renderer *r, float size); + Billboard(const Billboard &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0); + virtual void Accept(NodeVisitor &v); + virtual const char *GetTypeName() const { return "Billboard"; } + virtual void Render(const matrix4x4f &trans, const RenderData *rd); + void SetColorUVoffset(const vector2f &c) { m_colorUVoffset = c; } -private: - Graphics::VertexArray& m_bbVA; - float m_size; - vector2f m_colorUVoffset; -}; + private: + Graphics::VertexArray &m_bbVA; + float m_size; + vector2f m_colorUVoffset; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/BinaryConverter.cpp b/src/scenegraph/BinaryConverter.cpp index 56e196e8a..e8a340942 100644 --- a/src/scenegraph/BinaryConverter.cpp +++ b/src/scenegraph/BinaryConverter.cpp @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "BinaryConverter.h" +#include "FileSystem.h" +#include "GameSaveError.h" #include "NodeVisitor.h" #include "Parser.h" -#include "FileSystem.h" #include "StringF.h" #include "utils.h" -#include "GameSaveError.h" extern "C" { #include "miniz/miniz.h" @@ -22,18 +22,17 @@ using namespace SceneGraph; // 5: normal mapping // 6: 32-bit indicies const Uint32 SGM_VERSION = 6; -union SGM_STRING_VALUE{ +union SGM_STRING_VALUE { char name[4]; Uint32 value; }; -const SGM_STRING_VALUE SGM_STRING_ID = { {'s', 'g', 'm', SGM_VERSION} }; +const SGM_STRING_VALUE SGM_STRING_ID = { { 's', 'g', 'm', SGM_VERSION } }; const std::string SGM_EXTENSION = ".sgm"; const std::string SAVE_TARGET_DIR = "binarymodels"; -class SaveHelperVisitor : public NodeVisitor -{ +class SaveHelperVisitor : public NodeVisitor { public: - SaveHelperVisitor(Serializer::Writer* wr, Model *m) + SaveHelperVisitor(Serializer::Writer *wr, Model *m) { db.wr = wr; db.rd = nullptr; @@ -47,7 +46,7 @@ public: virtual void ApplyGroup(Group &g) override { - ApplyNode(static_cast(g)); + ApplyNode(static_cast(g)); db.wr->Int32(g.GetNumChildren()); g.Traverse(*this); } @@ -55,9 +54,9 @@ public: NodeDatabase db; }; -BinaryConverter::BinaryConverter(Graphics::Renderer *r) - : BaseLoader(r) - , m_patternsUsed(false) +BinaryConverter::BinaryConverter(Graphics::Renderer *r) : + BaseLoader(r), + m_patternsUsed(false) { //register core loaders RegisterLoader("Group", &Group::Load); @@ -69,19 +68,19 @@ BinaryConverter::BinaryConverter(Graphics::Renderer *r) RegisterLoader("Label3D", &LoadLabel3D); } -void BinaryConverter::RegisterLoader(const std::string &typeName, std::function func) +void BinaryConverter::RegisterLoader(const std::string &typeName, std::function func) { m_loaders[typeName] = func; } -void BinaryConverter::Save(const std::string& filename, Model* m) +void BinaryConverter::Save(const std::string &filename, Model *m) { PROFILE_SCOPED() static const std::string s_EmptyString; Save(filename, s_EmptyString, m, false); } -void BinaryConverter::Save(const std::string& filename, const std::string& savepath, Model* m, const bool bInPlace) +void BinaryConverter::Save(const std::string &filename, const std::string &savepath, Model *m, const bool bInPlace) { PROFILE_SCOPED() printf("Saving file (%s)\n", filename.c_str()); @@ -91,14 +90,14 @@ void BinaryConverter::Save(const std::string& filename, const std::string& savep if (!FileSystem::userFiles.MakeDirectory(SAVE_TARGET_DIR)) throw CouldNotOpenFileException(); - std::string newpath = savepath.substr(0, savepath.size()-filename.size()); + std::string newpath = savepath.substr(0, savepath.size() - filename.size()); size_t pos = newpath.find_first_of("/", 0); - while(pos binfile = info.Read(); if (binfile.Valid()) { - Model* model(nullptr); + Model *model(nullptr); size_t outSize(0); // decompress the loaded ByteRange in memory const ByteRange bin = binfile->AsByteRange(); void *pDecompressedData = tinfl_decompress_mem_to_heap(&bin[0], bin.Size(), &outSize, 0); if (pDecompressedData) { // now parse in-memory representation as new ByteRange. - Serializer::Reader rd(ByteRange(static_cast(pDecompressedData), outSize)); + Serializer::Reader rd(ByteRange(static_cast(pDecompressedData), outSize)); model = CreateModel(name, rd); mz_free(pDecompressedData); } @@ -194,11 +193,11 @@ Model *BinaryConverter::Load(const std::string &shortname, const std::string &ba } } - throw (LoadingError("File not found")); + throw(LoadingError("File not found")); return nullptr; } -Model *BinaryConverter::CreateModel(const std::string& filename, Serializer::Reader &rd) +Model *BinaryConverter::CreateModel(const std::string &filename, Serializer::Reader &rd) { PROFILE_SCOPED() //verify signature @@ -221,7 +220,7 @@ Model *BinaryConverter::CreateModel(const std::string& filename, Serializer::Rea m_patternsUsed = false; LoadMaterials(rd); - Group* root = dynamic_cast(LoadNode(rd)); + Group *root = dynamic_cast(LoadNode(rd)); if (!root) throw LoadingError("Expected root"); m_model->m_root.Reset(root); @@ -239,7 +238,7 @@ Model *BinaryConverter::CreateModel(const std::string& filename, Serializer::Rea return m_model; } -void BinaryConverter::SaveMaterials(Serializer::Writer& wr, Model* model) +void BinaryConverter::SaveMaterials(Serializer::Writer &wr, Model *model) { PROFILE_SCOPED() //Look for the .model definition and parse it @@ -248,7 +247,7 @@ void BinaryConverter::SaveMaterials(Serializer::Writer& wr, Model* model) wr.Int32(modelDef.matDefs.size()); - for (const auto& m : modelDef.matDefs) { + for (const auto &m : modelDef.matDefs) { wr.String(m.name); wr.String(m.tex_diff); wr.String(m.tex_spec); @@ -297,9 +296,9 @@ void BinaryConverter::LoadMaterials(Serializer::Reader &rd) void BinaryConverter::SaveAnimations(Serializer::Writer &wr, Model *m) { PROFILE_SCOPED() - const auto& anims = m->GetAnimations(); + const auto &anims = m->GetAnimations(); wr.Int32(anims.size()); - for (const auto& anim : anims) { + for (const auto &anim : anims) { wr.String(anim->GetName()); wr.Double(anim->GetDuration()); wr.Int32(anim->GetChannels().size()); @@ -337,9 +336,9 @@ void BinaryConverter::LoadAnimations(Serializer::Reader &rd) const Uint32 numChans = rd.Int32(); for (Uint32 j = 0; j < numChans; j++) { const std::string tgtName = rd.String(); - MatrixTransform* tgtNode = dynamic_cast(m_model->m_root->FindNode(tgtName)); + MatrixTransform *tgtNode = dynamic_cast(m_model->m_root->FindNode(tgtName)); anim->m_channels.push_back(AnimationChannel(tgtNode)); - auto& chan = anim->m_channels.back(); + auto &chan = anim->m_channels.back(); for (Uint32 numKeys = rd.Int32(); numKeys > 0; numKeys--) { const double ktime = rd.Double(); const vector3f kpos = rd.Vector3f(); @@ -375,7 +374,7 @@ ModelDefinition BinaryConverter::FindModelDefinition(const std::string &shortnam //check it's the wanted name & load it const std::string name = info.GetName(); - if (shortname == name.substr(0, name.length()-6)) { + if (shortname == name.substr(0, name.length() - 6)) { ModelDefinition modelDefinition; try { //curPath is used to find textures, patterns, @@ -383,8 +382,8 @@ ModelDefinition BinaryConverter::FindModelDefinition(const std::string &shortnam //Strip trailing slash m_curPath = info.GetDir(); assert(!m_curPath.empty()); - if (m_curPath[m_curPath.length()-1] == '/') - m_curPath = m_curPath.substr(0, m_curPath.length()-1); + if (m_curPath[m_curPath.length() - 1] == '/') + m_curPath = m_curPath.substr(0, m_curPath.length() - 1); Parser p(fileSource, fpath, m_curPath); p.Parse(&modelDefinition); @@ -396,10 +395,10 @@ ModelDefinition BinaryConverter::FindModelDefinition(const std::string &shortnam } } } - throw (LoadingError("File not found")); + throw(LoadingError("File not found")); } -Node* BinaryConverter::LoadNode(Serializer::Reader &rd) +Node *BinaryConverter::LoadNode(Serializer::Reader &rd) { PROFILE_SCOPED() const std::string ntype = rd.String(); @@ -407,7 +406,7 @@ Node* BinaryConverter::LoadNode(Serializer::Reader &rd) //Output("Loading: %s %s\n", ntype.c_str(), nname.c_str()); const Uint32 nmask = rd.Int32(); const Uint32 nflags = rd.Int32(); - Node* node = nullptr; + Node *node = nullptr; NodeDatabase db; db.loader = this; @@ -421,13 +420,13 @@ Node* BinaryConverter::LoadNode(Serializer::Reader &rd) } node = loadFuncIt->second(db); - Group *grp = dynamic_cast(node); + Group *grp = dynamic_cast(node); if (grp) LoadChildren(rd, grp); //register tag nodes if (nflags & NODE_TAG) - m_model->m_tags.push_back(static_cast(node)); + m_model->m_tags.push_back(static_cast(node)); node->SetName(nname); node->SetNodeMask(nmask); @@ -446,7 +445,7 @@ void BinaryConverter::LoadChildren(Serializer::Reader &rd, Group *parent) Label3D *BinaryConverter::LoadLabel3D(NodeDatabase &db) { PROFILE_SCOPED() - Label3D* lbl = new Label3D(db.loader->GetRenderer(), db.loader->GetLabel3DFont()); + Label3D *lbl = new Label3D(db.loader->GetRenderer(), db.loader->GetLabel3DFont()); lbl->SetText("NCC-1982"); return lbl; } diff --git a/src/scenegraph/BinaryConverter.h b/src/scenegraph/BinaryConverter.h index 81d91ddb3..f1dcd963f 100644 --- a/src/scenegraph/BinaryConverter.h +++ b/src/scenegraph/BinaryConverter.h @@ -12,44 +12,42 @@ */ #include "BaseLoader.h" +#include "Billboard.h" +#include "CollisionGeometry.h" #include "LOD.h" #include "StaticGeometry.h" -#include "CollisionGeometry.h" #include "Thruster.h" -#include "Billboard.h" #include -namespace SceneGraph -{ -class BinaryConverter : public BaseLoader -{ -public: - BinaryConverter(Graphics::Renderer*); - void Save(const std::string& filename, Model* m); - void Save(const std::string& filename, const std::string& savepath, Model* m, const bool bInPlace); - Model *Load(const std::string &filename); - Model *Load(const std::string &filename, const std::string &path); +namespace SceneGraph { + class BinaryConverter : public BaseLoader { + public: + BinaryConverter(Graphics::Renderer *); + void Save(const std::string &filename, Model *m); + void Save(const std::string &filename, const std::string &savepath, Model *m, const bool bInPlace); + Model *Load(const std::string &filename); + Model *Load(const std::string &filename, const std::string &path); - //if you implement any new node types, you must also register a loader function - //before calling Load. - void RegisterLoader(const std::string &typeName, std::function); + //if you implement any new node types, you must also register a loader function + //before calling Load. + void RegisterLoader(const std::string &typeName, std::function); -private: - Model *CreateModel(const std::string& filename, Serializer::Reader&); - void SaveMaterials(Serializer::Writer&, Model* m); - void LoadMaterials(Serializer::Reader&); - void SaveAnimations(Serializer::Writer&, Model* m); - void LoadAnimations(Serializer::Reader&); - ModelDefinition FindModelDefinition(const std::string&); + private: + Model *CreateModel(const std::string &filename, Serializer::Reader &); + void SaveMaterials(Serializer::Writer &, Model *m); + void LoadMaterials(Serializer::Reader &); + void SaveAnimations(Serializer::Writer &, Model *m); + void LoadAnimations(Serializer::Reader &); + ModelDefinition FindModelDefinition(const std::string &); - Node* LoadNode(Serializer::Reader&); - void LoadChildren(Serializer::Reader&, Group* parent); - //this is a very simple loader so it's implemented here - static Label3D *LoadLabel3D(NodeDatabase&); + Node *LoadNode(Serializer::Reader &); + void LoadChildren(Serializer::Reader &, Group *parent); + //this is a very simple loader so it's implemented here + static Label3D *LoadLabel3D(NodeDatabase &); - bool m_patternsUsed; - std::map > m_loaders; -}; -} + bool m_patternsUsed; + std::map> m_loaders; + }; +} // namespace SceneGraph #endif diff --git a/src/scenegraph/CollisionGeometry.cpp b/src/scenegraph/CollisionGeometry.cpp index 9a915b282..c80533c9f 100644 --- a/src/scenegraph/CollisionGeometry.cpp +++ b/src/scenegraph/CollisionGeometry.cpp @@ -2,107 +2,106 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "CollisionGeometry.h" -#include "NodeVisitor.h" -#include "NodeCopyCache.h" #include "BaseLoader.h" +#include "NodeCopyCache.h" +#include "NodeVisitor.h" namespace SceneGraph { -CollisionGeometry::CollisionGeometry(Graphics::Renderer *r, const std::vector &vts, const std::vector &idx, - unsigned int geomflag) -: Node(r) -, m_triFlag(geomflag) -, m_dynamic(false) -, m_geomTree(0) -, m_geom(0) -{ - PROFILE_SCOPED() - CopyData(vts, idx); -} + CollisionGeometry::CollisionGeometry(Graphics::Renderer *r, const std::vector &vts, const std::vector &idx, + unsigned int geomflag) : + Node(r), + m_triFlag(geomflag), + m_dynamic(false), + m_geomTree(0), + m_geom(0) + { + PROFILE_SCOPED() + CopyData(vts, idx); + } -CollisionGeometry::CollisionGeometry(const CollisionGeometry &cg, NodeCopyCache *cache) -: Node(cg, cache) -, m_vertices(cg.m_vertices) -, m_indices(cg.m_indices) -, m_triFlag(cg.m_triFlag) -, m_dynamic(cg.m_dynamic) -, m_geomTree(cg.m_geomTree) -, m_geom(cg.m_geom) -{ - PROFILE_SCOPED() -} + CollisionGeometry::CollisionGeometry(const CollisionGeometry &cg, NodeCopyCache *cache) : + Node(cg, cache), + m_vertices(cg.m_vertices), + m_indices(cg.m_indices), + m_triFlag(cg.m_triFlag), + m_dynamic(cg.m_dynamic), + m_geomTree(cg.m_geomTree), + m_geom(cg.m_geom){ + PROFILE_SCOPED() + } -CollisionGeometry::~CollisionGeometry() -{ -} + CollisionGeometry::~CollisionGeometry() + { + } -Node* CollisionGeometry::Clone(NodeCopyCache *cache) -{ - PROFILE_SCOPED() - //static collgeoms are shared, - //dynamic geoms are copied (they should be tiny) - if (IsDynamic()) - return cache->Copy(this); - else - return this; -} + Node *CollisionGeometry::Clone(NodeCopyCache *cache) + { + PROFILE_SCOPED() + //static collgeoms are shared, + //dynamic geoms are copied (they should be tiny) + if (IsDynamic()) + return cache->Copy(this); + else + return this; + } -void CollisionGeometry::Accept(NodeVisitor &nv) -{ - PROFILE_SCOPED() - nv.ApplyCollisionGeometry(*this); -} + void CollisionGeometry::Accept(NodeVisitor &nv) + { + PROFILE_SCOPED() + nv.ApplyCollisionGeometry(*this); + } -void CollisionGeometry::Save(NodeDatabase &db) -{ - PROFILE_SCOPED() - Node::Save(db); - db.wr->Int32(m_vertices.size()); - for (const auto& pos : m_vertices) - db.wr->Vector3f(pos); - db.wr->Int32(m_indices.size()); - for (const auto idx : m_indices) - db.wr->Int32(idx); - db.wr->Int32(m_triFlag); - db.wr->Bool(m_dynamic); -} + void CollisionGeometry::Save(NodeDatabase &db) + { + PROFILE_SCOPED() + Node::Save(db); + db.wr->Int32(m_vertices.size()); + for (const auto &pos : m_vertices) + db.wr->Vector3f(pos); + db.wr->Int32(m_indices.size()); + for (const auto idx : m_indices) + db.wr->Int32(idx); + db.wr->Int32(m_triFlag); + db.wr->Bool(m_dynamic); + } -CollisionGeometry *CollisionGeometry::Load(NodeDatabase &db) -{ - PROFILE_SCOPED() - std::vector pos; - std::vector idx; - Serializer::Reader &rd = *db.rd; + CollisionGeometry *CollisionGeometry::Load(NodeDatabase &db) + { + PROFILE_SCOPED() + std::vector pos; + std::vector idx; + Serializer::Reader &rd = *db.rd; - Uint32 n = rd.Int32(); - pos.reserve(n); - for (Uint32 i = 0; i < n; i++) - pos.push_back(rd.Vector3f()); + Uint32 n = rd.Int32(); + pos.reserve(n); + for (Uint32 i = 0; i < n; i++) + pos.push_back(rd.Vector3f()); - n = rd.Int32(); - idx.reserve(n); - for (Uint32 i = 0; i < n; i++) - idx.push_back(rd.Int32()); + n = rd.Int32(); + idx.reserve(n); + for (Uint32 i = 0; i < n; i++) + idx.push_back(rd.Int32()); - const Uint32 flag = rd.Int32(); - const bool dynamic = rd.Bool(); + const Uint32 flag = rd.Int32(); + const bool dynamic = rd.Bool(); - CollisionGeometry *cg = new CollisionGeometry(db.loader->GetRenderer(), pos, idx, flag); - cg->SetDynamic(dynamic); + CollisionGeometry *cg = new CollisionGeometry(db.loader->GetRenderer(), pos, idx, flag); + cg->SetDynamic(dynamic); - return cg; -} + return cg; + } -void CollisionGeometry::CopyData(const std::vector &vts, const std::vector &idx) -{ - PROFILE_SCOPED() - //copy vertices and indices from surface. Add flag for every three indices. - using std::vector; + void CollisionGeometry::CopyData(const std::vector &vts, const std::vector &idx) + { + PROFILE_SCOPED() + //copy vertices and indices from surface. Add flag for every three indices. + using std::vector; - for (vector::const_iterator it = vts.begin(); it != vts.end(); ++it) - m_vertices.push_back(*it); + for (vector::const_iterator it = vts.begin(); it != vts.end(); ++it) + m_vertices.push_back(*it); - for (vector::const_iterator it = idx.begin(); it != idx.end(); ++it) - m_indices.push_back(*it); -} -} + for (vector::const_iterator it = idx.begin(); it != idx.end(); ++it) + m_indices.push_back(*it); + } +} // namespace SceneGraph diff --git a/src/scenegraph/CollisionGeometry.h b/src/scenegraph/CollisionGeometry.h index b0c8d794f..64a8555d9 100644 --- a/src/scenegraph/CollisionGeometry.h +++ b/src/scenegraph/CollisionGeometry.h @@ -11,50 +11,52 @@ #include "Node.h" -namespace Graphics { class Surface; } +namespace Graphics { + class Surface; +} class GeomTree; class Geom; namespace SceneGraph { -class CollisionGeometry : public Node { -public: - CollisionGeometry(Graphics::Renderer *r, const std::vector&, const std::vector&, unsigned int flag); - CollisionGeometry(const CollisionGeometry&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0) override; - virtual const char *GetTypeName() const override { return "CollisionGeometry"; } - virtual void Accept(NodeVisitor &nv) override; - virtual void Save(NodeDatabase&) override; - static CollisionGeometry *Load(NodeDatabase&); + class CollisionGeometry : public Node { + public: + CollisionGeometry(Graphics::Renderer *r, const std::vector &, const std::vector &, unsigned int flag); + CollisionGeometry(const CollisionGeometry &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0) override; + virtual const char *GetTypeName() const override { return "CollisionGeometry"; } + virtual void Accept(NodeVisitor &nv) override; + virtual void Save(NodeDatabase &) override; + static CollisionGeometry *Load(NodeDatabase &); - const std::vector &GetVertices() const { return m_vertices; } - const std::vector &GetIndices() const { return m_indices; } - unsigned int GetTriFlag() const { return m_triFlag; } + const std::vector &GetVertices() const { return m_vertices; } + const std::vector &GetIndices() const { return m_indices; } + unsigned int GetTriFlag() const { return m_triFlag; } - bool IsDynamic() const { return m_dynamic; } - void SetDynamic(bool b) { m_dynamic = b; } + bool IsDynamic() const { return m_dynamic; } + void SetDynamic(bool b) { m_dynamic = b; } - //for linking game collision objects with these nodes - GeomTree *GetGeomTree() const { return m_geomTree; } - void SetGeomTree(GeomTree *c) { m_geomTree = c; } + //for linking game collision objects with these nodes + GeomTree *GetGeomTree() const { return m_geomTree; } + void SetGeomTree(GeomTree *c) { m_geomTree = c; } - Geom *GetGeom() const { return m_geom; } - void SetGeom(Geom *g) { m_geom = g; } + Geom *GetGeom() const { return m_geom; } + void SetGeom(Geom *g) { m_geom = g; } -protected: - ~CollisionGeometry(); + protected: + ~CollisionGeometry(); -private: - void CopyData(const std::vector&, const std::vector&); - std::vector m_vertices; - std::vector m_indices; - unsigned int m_triFlag; //only one per node - bool m_dynamic; + private: + void CopyData(const std::vector &, const std::vector &); + std::vector m_vertices; + std::vector m_indices; + unsigned int m_triFlag; //only one per node + bool m_dynamic; - //for dynamic collisions - GeomTree *m_geomTree; - Geom *m_geom; -}; -} + //for dynamic collisions + GeomTree *m_geomTree; + Geom *m_geom; + }; +} // namespace SceneGraph #endif diff --git a/src/scenegraph/CollisionVisitor.cpp b/src/scenegraph/CollisionVisitor.cpp index d630b1696..9ce339862 100644 --- a/src/scenegraph/CollisionVisitor.cpp +++ b/src/scenegraph/CollisionVisitor.cpp @@ -2,222 +2,222 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "CollisionVisitor.h" -#include "CollisionGeometry.h" #include "CollMesh.h" +#include "CollisionGeometry.h" #include "Group.h" #include "MatrixTransform.h" #include "StaticGeometry.h" namespace SceneGraph { -CollisionVisitor::CollisionVisitor() -: m_properData(false) -, m_totalTris(0) -{ - m_collMesh.Reset(new CollMesh()); - m_vertices.reserve(300); - m_indices.reserve(300 * 3); - m_flags.reserve(300); -} - -void CollisionVisitor::ApplyStaticGeometry(StaticGeometry &g) -{ - PROFILE_SCOPED() - if (m_matrixStack.empty()) { - m_collMesh->GetAabb().Update(g.m_boundingBox.min); - m_collMesh->GetAabb().Update(g.m_boundingBox.max); - } else { - const matrix4x4f &matrix = m_matrixStack.back(); - vector3f min = matrix * vector3f(g.m_boundingBox.min); - vector3f max = matrix * vector3f(g.m_boundingBox.max); - m_collMesh->GetAabb().Update(vector3d(min)); - m_collMesh->GetAabb().Update(vector3d(max)); - } -} - -void CollisionVisitor::ApplyMatrixTransform(MatrixTransform &m) -{ - PROFILE_SCOPED() - matrix4x4f matrix = matrix4x4f::Identity(); - if (!m_matrixStack.empty()) matrix = m_matrixStack.back(); - - m_matrixStack.push_back(matrix * m.GetTransform()); - m.Traverse(*this); - m_matrixStack.pop_back(); -} - -void CollisionVisitor::ApplyCollisionGeometry(CollisionGeometry &cg) -{ - PROFILE_SCOPED() - using std::vector; - - if (cg.IsDynamic()) return ApplyDynamicCollisionGeometry(cg); - - const matrix4x4f matrix = m_matrixStack.empty() ? matrix4x4f::Identity() : m_matrixStack.back(); - - //copy data (with index offset) - int idxOffset = m_vertices.size(); - for (vector::const_iterator it = cg.GetVertices().begin(); it != cg.GetVertices().end(); ++it) { - const vector3f pos = matrix * (*it); - m_vertices.push_back(pos); - m_collMesh->GetAabb().Update(pos.x, pos.y, pos.z); + CollisionVisitor::CollisionVisitor() : + m_properData(false), + m_totalTris(0) + { + m_collMesh.Reset(new CollMesh()); + m_vertices.reserve(300); + m_indices.reserve(300 * 3); + m_flags.reserve(300); } - for (vector::const_iterator it = cg.GetIndices().begin(); it != cg.GetIndices().end(); ++it) - m_indices.push_back(*it + idxOffset); + void CollisionVisitor::ApplyStaticGeometry(StaticGeometry &g) + { + PROFILE_SCOPED() + if (m_matrixStack.empty()) { + m_collMesh->GetAabb().Update(g.m_boundingBox.min); + m_collMesh->GetAabb().Update(g.m_boundingBox.max); + } else { + const matrix4x4f &matrix = m_matrixStack.back(); + vector3f min = matrix * vector3f(g.m_boundingBox.min); + vector3f max = matrix * vector3f(g.m_boundingBox.max); + m_collMesh->GetAabb().Update(vector3d(min)); + m_collMesh->GetAabb().Update(vector3d(max)); + } + } - //at least some of the geoms should be default collision - if (cg.GetTriFlag() == 0) - m_properData = true; + void CollisionVisitor::ApplyMatrixTransform(MatrixTransform &m) + { + PROFILE_SCOPED() + matrix4x4f matrix = matrix4x4f::Identity(); + if (!m_matrixStack.empty()) matrix = m_matrixStack.back(); - for (unsigned int i = 0; i < cg.GetIndices().size() / 3; i++) - m_flags.push_back(cg.GetTriFlag()); -} + m_matrixStack.push_back(matrix * m.GetTransform()); + m.Traverse(*this); + m_matrixStack.pop_back(); + } -void CollisionVisitor::ApplyDynamicCollisionGeometry(CollisionGeometry &cg) -{ - PROFILE_SCOPED() - //don't transform geometry, one geomtree per cg, create tree right away + void CollisionVisitor::ApplyCollisionGeometry(CollisionGeometry &cg) + { + PROFILE_SCOPED() + using std::vector; - const int numVertices = cg.GetVertices().size(); - const int numIndices = cg.GetIndices().size(); - const int numTris = numIndices / 3; - std::vector vertices(numVertices); - Uint32 *indices = new Uint32[numIndices]; - unsigned int *triFlags = new unsigned int[numTris]; + if (cg.IsDynamic()) return ApplyDynamicCollisionGeometry(cg); - for (int i = 0; i < numVertices; i++) - vertices[i] = cg.GetVertices()[i]; + const matrix4x4f matrix = m_matrixStack.empty() ? matrix4x4f::Identity() : m_matrixStack.back(); - for (int i = 0; i < numIndices; i++) - indices[i] = cg.GetIndices()[i]; + //copy data (with index offset) + int idxOffset = m_vertices.size(); + for (vector::const_iterator it = cg.GetVertices().begin(); it != cg.GetVertices().end(); ++it) { + const vector3f pos = matrix * (*it); + m_vertices.push_back(pos); + m_collMesh->GetAabb().Update(pos.x, pos.y, pos.z); + } - for (int i = 0; i < numTris; i++) - triFlags[i] = cg.GetTriFlag(); + for (vector::const_iterator it = cg.GetIndices().begin(); it != cg.GetIndices().end(); ++it) + m_indices.push_back(*it + idxOffset); - //create geomtree - //takes ownership of data - GeomTree *gt = new GeomTree( - numVertices, numTris, - vertices, - indices, triFlags); - cg.SetGeomTree(gt); + //at least some of the geoms should be default collision + if (cg.GetTriFlag() == 0) + m_properData = true; - m_collMesh->AddDynGeomTree(gt); + for (unsigned int i = 0; i < cg.GetIndices().size() / 3; i++) + m_flags.push_back(cg.GetTriFlag()); + } - m_totalTris += numTris; -} + void CollisionVisitor::ApplyDynamicCollisionGeometry(CollisionGeometry &cg) + { + PROFILE_SCOPED() + //don't transform geometry, one geomtree per cg, create tree right away -void CollisionVisitor::AabbToMesh(const Aabb &bb) -{ - PROFILE_SCOPED() - std::vector &vts = m_vertices; - std::vector &ind = m_indices; - const int offs = vts.size(); + const int numVertices = cg.GetVertices().size(); + const int numIndices = cg.GetIndices().size(); + const int numTris = numIndices / 3; + std::vector vertices(numVertices); + Uint32 *indices = new Uint32[numIndices]; + unsigned int *triFlags = new unsigned int[numTris]; - const vector3f min(bb.min.x, bb.min.y, bb.min.z); - const vector3f max(bb.max.x, bb.max.y, bb.max.z); - const vector3f fbl(min.x, min.y, min.z); //front bottom left - const vector3f fbr(max.x, min.y, min.z); //front bottom right - const vector3f ftl(min.x, max.y, min.z); //front top left - const vector3f ftr(max.x, max.y, min.z); //front top right - const vector3f rtl(min.x, max.y, max.z); //rear top left - const vector3f rtr(max.x, max.y, max.z); //rear top right - const vector3f rbl(min.x, min.y, max.z); //rear bottom left - const vector3f rbr(max.x, min.y, max.z); //rear bottom right + for (int i = 0; i < numVertices; i++) + vertices[i] = cg.GetVertices()[i]; - vts.push_back(fbl); //0 - vts.push_back(fbr); //1 - vts.push_back(ftl); //2 - vts.push_back(ftr); //3 + for (int i = 0; i < numIndices; i++) + indices[i] = cg.GetIndices()[i]; - vts.push_back(rtl); //4 - vts.push_back(rtr); //5 - vts.push_back(rbl); //6 - vts.push_back(rbr); //7 + for (int i = 0; i < numTris; i++) + triFlags[i] = cg.GetTriFlag(); -#define ADDTRI(_i1, _i2, _i3) \ + //create geomtree + //takes ownership of data + GeomTree *gt = new GeomTree( + numVertices, numTris, + vertices, + indices, triFlags); + cg.SetGeomTree(gt); + + m_collMesh->AddDynGeomTree(gt); + + m_totalTris += numTris; + } + + void CollisionVisitor::AabbToMesh(const Aabb &bb) + { + PROFILE_SCOPED() + std::vector &vts = m_vertices; + std::vector &ind = m_indices; + const int offs = vts.size(); + + const vector3f min(bb.min.x, bb.min.y, bb.min.z); + const vector3f max(bb.max.x, bb.max.y, bb.max.z); + const vector3f fbl(min.x, min.y, min.z); //front bottom left + const vector3f fbr(max.x, min.y, min.z); //front bottom right + const vector3f ftl(min.x, max.y, min.z); //front top left + const vector3f ftr(max.x, max.y, min.z); //front top right + const vector3f rtl(min.x, max.y, max.z); //rear top left + const vector3f rtr(max.x, max.y, max.z); //rear top right + const vector3f rbl(min.x, min.y, max.z); //rear bottom left + const vector3f rbr(max.x, min.y, max.z); //rear bottom right + + vts.push_back(fbl); //0 + vts.push_back(fbr); //1 + vts.push_back(ftl); //2 + vts.push_back(ftr); //3 + + vts.push_back(rtl); //4 + vts.push_back(rtr); //5 + vts.push_back(rbl); //6 + vts.push_back(rbr); //7 + +#define ADDTRI(_i1, _i2, _i3) \ ind.push_back(offs + _i1); \ ind.push_back(offs + _i2); \ ind.push_back(offs + _i3); - //indices - //Front face - ADDTRI(3, 1, 0); - ADDTRI(0, 2, 3); + //indices + //Front face + ADDTRI(3, 1, 0); + ADDTRI(0, 2, 3); - //Rear face - ADDTRI(7, 5, 6); - ADDTRI(6, 5, 4); + //Rear face + ADDTRI(7, 5, 6); + ADDTRI(6, 5, 4); - //Top face - ADDTRI(4, 5, 3); - ADDTRI(3, 2, 4); + //Top face + ADDTRI(4, 5, 3); + ADDTRI(3, 2, 4); - //bottom face - ADDTRI(1, 7, 6); - ADDTRI(6, 0, 1); + //bottom face + ADDTRI(1, 7, 6); + ADDTRI(6, 0, 1); - //left face - ADDTRI(0, 6, 4); - ADDTRI(4, 2, 0); + //left face + ADDTRI(0, 6, 4); + ADDTRI(4, 2, 0); - //right face - ADDTRI(5, 7, 1); - ADDTRI(1, 3, 5); + //right face + ADDTRI(5, 7, 1); + ADDTRI(1, 3, 5); #undef ADDTRI - for(unsigned int i = 0; i < ind.size()/3; i++) - m_flags.push_back(0); -} + for (unsigned int i = 0; i < ind.size() / 3; i++) + m_flags.push_back(0); + } -RefCountedPtr CollisionVisitor::CreateCollisionMesh() -{ - PROFILE_SCOPED() - Profiler::Timer timer; - timer.Start(); + RefCountedPtr CollisionVisitor::CreateCollisionMesh() + { + PROFILE_SCOPED() + Profiler::Timer timer; + timer.Start(); - //convert from model AABB if no collisiongeoms found - if (!m_properData) - AabbToMesh(m_collMesh->GetAabb()); + //convert from model AABB if no collisiongeoms found + if (!m_properData) + AabbToMesh(m_collMesh->GetAabb()); - assert(m_collMesh->GetGeomTree() == 0); - assert(!m_vertices.empty() && !m_indices.empty()); + assert(m_collMesh->GetGeomTree() == 0); + assert(!m_vertices.empty() && !m_indices.empty()); - //duplicate data again for geomtree... - const size_t numVertices = m_vertices.size(); - const size_t numIndices = m_indices.size(); - const size_t numTris = numIndices / 3; - std::vector vertices(numVertices); - Uint32 *indices = new Uint32[numIndices]; - Uint32 *triFlags = new Uint32[numTris]; + //duplicate data again for geomtree... + const size_t numVertices = m_vertices.size(); + const size_t numIndices = m_indices.size(); + const size_t numTris = numIndices / 3; + std::vector vertices(numVertices); + Uint32 *indices = new Uint32[numIndices]; + Uint32 *triFlags = new Uint32[numTris]; - m_totalTris += numTris; + m_totalTris += numTris; - for (size_t i = 0; i < numVertices; i++) - vertices[i] = m_vertices[i]; + for (size_t i = 0; i < numVertices; i++) + vertices[i] = m_vertices[i]; - for (size_t i = 0; i < numIndices; i++) - indices[i] = m_indices[i]; + for (size_t i = 0; i < numIndices; i++) + indices[i] = m_indices[i]; - for (size_t i = 0; i < numTris; i++) - triFlags[i] = m_flags[i]; + for (size_t i = 0; i < numTris; i++) + triFlags[i] = m_flags[i]; - //create geomtree - //takes ownership of data - GeomTree *gt = new GeomTree( - numVertices, numTris, - vertices, - indices, triFlags); - m_collMesh->SetGeomTree(gt); - m_collMesh->SetNumTriangles(m_totalTris); - m_boundingRadius = m_collMesh->GetAabb().GetRadius(); + //create geomtree + //takes ownership of data + GeomTree *gt = new GeomTree( + numVertices, numTris, + vertices, + indices, triFlags); + m_collMesh->SetGeomTree(gt); + m_collMesh->SetNumTriangles(m_totalTris); + m_boundingRadius = m_collMesh->GetAabb().GetRadius(); - m_vertices.clear(); - m_indices.clear(); - m_flags.clear(); + m_vertices.clear(); + m_indices.clear(); + m_flags.clear(); - timer.Stop(); - //Output(" - CreateCollisionMesh took: %lf milliseconds\n", timer.millicycles()); + timer.Stop(); + //Output(" - CreateCollisionMesh took: %lf milliseconds\n", timer.millicycles()); - return m_collMesh; -} -} + return m_collMesh; + } +} // namespace SceneGraph diff --git a/src/scenegraph/CollisionVisitor.h b/src/scenegraph/CollisionVisitor.h index 2abeb90a0..9375a965f 100644 --- a/src/scenegraph/CollisionVisitor.h +++ b/src/scenegraph/CollisionVisitor.h @@ -7,42 +7,41 @@ * Creates a new collision mesh from CollisionGeometry nodes * or the nodes' AABB, when no CGeoms found. */ +#include "CollMesh.h" #include "NodeVisitor.h" #include "libs.h" -#include "CollMesh.h" namespace SceneGraph { -class Group; -class MatrixTransform; -class StaticGeometry; + class Group; + class MatrixTransform; + class StaticGeometry; -class CollisionVisitor : public NodeVisitor -{ -public: - CollisionVisitor(); - virtual void ApplyStaticGeometry(StaticGeometry &); - virtual void ApplyMatrixTransform(MatrixTransform &); - virtual void ApplyCollisionGeometry(CollisionGeometry &); - //call after traversal complete - RefCountedPtr CreateCollisionMesh(); - float GetBoundingRadius() const { return m_boundingRadius; } + class CollisionVisitor : public NodeVisitor { + public: + CollisionVisitor(); + virtual void ApplyStaticGeometry(StaticGeometry &); + virtual void ApplyMatrixTransform(MatrixTransform &); + virtual void ApplyCollisionGeometry(CollisionGeometry &); + //call after traversal complete + RefCountedPtr CreateCollisionMesh(); + float GetBoundingRadius() const { return m_boundingRadius; } -private: - void ApplyDynamicCollisionGeometry(CollisionGeometry &); - void AabbToMesh(const Aabb&); - //geomtree is not built until all nodes are visited and - //BuildCollMesh called - RefCountedPtr m_collMesh; - std::vector m_matrixStack; - float m_boundingRadius; - bool m_properData; + private: + void ApplyDynamicCollisionGeometry(CollisionGeometry &); + void AabbToMesh(const Aabb &); + //geomtree is not built until all nodes are visited and + //BuildCollMesh called + RefCountedPtr m_collMesh; + std::vector m_matrixStack; + float m_boundingRadius; + bool m_properData; - //temporary arrays for static geometry - std::vector m_vertices; - std::vector m_indices; - std::vector m_flags; + //temporary arrays for static geometry + std::vector m_vertices; + std::vector m_indices; + std::vector m_flags; - Uint32 m_totalTris; -}; -} + Uint32 m_totalTris; + }; +} // namespace SceneGraph #endif diff --git a/src/scenegraph/ColorMap.cpp b/src/scenegraph/ColorMap.cpp index 8b631526d..8cf2a71e1 100644 --- a/src/scenegraph/ColorMap.cpp +++ b/src/scenegraph/ColorMap.cpp @@ -7,53 +7,52 @@ namespace SceneGraph { -ColorMap::ColorMap() -: m_smooth(true) -{ - -} - -Graphics::Texture *ColorMap::GetTexture() -{ - assert(m_texture.Valid()); - return m_texture.Get(); -} - -void ColorMap::AddColor(int width, const Color &c, std::vector &out) -{ - for (int i=0; i < width; i++) { - out.push_back(c.r); - out.push_back(c.g); - out.push_back(c.b); - } -} - -void ColorMap::Generate(Graphics::Renderer *r, const Color &a, const Color &b, const Color &c) -{ - std::vector colors; - const int w = 4; - AddColor(w, Color(255, 255, 255), colors); - AddColor(w, a, colors); - AddColor(w, b, colors); - AddColor(w, c, colors); - vector2f size(colors.size()/3, 1.f); - - const Graphics::TextureFormat format = Graphics::TEXTURE_RGB_888; - - if (!m_texture.Valid()) { - const Graphics::TextureSampleMode sampleMode = m_smooth ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP; - m_texture.Reset(r->CreateTexture(Graphics::TextureDescriptor(Graphics::TEXTURE_RGB_888, size, sampleMode, true, true, true, 0, Graphics::TEXTURE_2D))); + ColorMap::ColorMap() : + m_smooth(true) + { } - m_texture->Update(&colors[0], size, format); -} - -void ColorMap::SetSmooth(bool smooth) -{ - m_smooth = smooth; - if (m_texture.Valid()) { - m_texture->SetSampleMode(m_smooth ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP); + Graphics::Texture *ColorMap::GetTexture() + { + assert(m_texture.Valid()); + return m_texture.Get(); } -} -} + void ColorMap::AddColor(int width, const Color &c, std::vector &out) + { + for (int i = 0; i < width; i++) { + out.push_back(c.r); + out.push_back(c.g); + out.push_back(c.b); + } + } + + void ColorMap::Generate(Graphics::Renderer *r, const Color &a, const Color &b, const Color &c) + { + std::vector colors; + const int w = 4; + AddColor(w, Color(255, 255, 255), colors); + AddColor(w, a, colors); + AddColor(w, b, colors); + AddColor(w, c, colors); + vector2f size(colors.size() / 3, 1.f); + + const Graphics::TextureFormat format = Graphics::TEXTURE_RGB_888; + + if (!m_texture.Valid()) { + const Graphics::TextureSampleMode sampleMode = m_smooth ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP; + m_texture.Reset(r->CreateTexture(Graphics::TextureDescriptor(Graphics::TEXTURE_RGB_888, size, sampleMode, true, true, true, 0, Graphics::TEXTURE_2D))); + } + + m_texture->Update(&colors[0], size, format); + } + + void ColorMap::SetSmooth(bool smooth) + { + m_smooth = smooth; + if (m_texture.Valid()) { + m_texture->SetSampleMode(m_smooth ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP); + } + } + +} // namespace SceneGraph diff --git a/src/scenegraph/ColorMap.h b/src/scenegraph/ColorMap.h index c56b9e3ba..cc10871f8 100644 --- a/src/scenegraph/ColorMap.h +++ b/src/scenegraph/ColorMap.h @@ -6,28 +6,30 @@ /* * Color look-up texture generator for newmodel pattern system */ -#include "libs.h" #include "graphics/Texture.h" +#include "libs.h" #include -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} namespace SceneGraph { -class ColorMap { -public: - ColorMap(); - Graphics::Texture *GetTexture(); - void Generate(Graphics::Renderer *r, const Color &a, const Color &b, const Color &c); - void SetSmooth(bool); + class ColorMap { + public: + ColorMap(); + Graphics::Texture *GetTexture(); + void Generate(Graphics::Renderer *r, const Color &a, const Color &b, const Color &c); + void SetSmooth(bool); -private: - void AddColor(int width, const Color &c, std::vector &out); + private: + void AddColor(int width, const Color &c, std::vector &out); - bool m_smooth; - RefCountedPtr m_texture; -}; + bool m_smooth; + RefCountedPtr m_texture; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/DumpVisitor.cpp b/src/scenegraph/DumpVisitor.cpp index 8cfbe98d3..8816bcc18 100644 --- a/src/scenegraph/DumpVisitor.cpp +++ b/src/scenegraph/DumpVisitor.cpp @@ -4,106 +4,106 @@ #include "DumpVisitor.h" #include "Group.h" #include "LOD.h" +#include "Model.h" #include "Node.h" #include "StaticGeometry.h" -#include "Model.h" #include "utils.h" #include #include namespace SceneGraph { -DumpVisitor::DumpVisitor(const Model *m) -: m_level(0) -, m_stats() -{ - //model statistics that cannot be visited) - m_modelStats.collTriCount = m->GetCollisionMesh() ? m->GetCollisionMesh()->GetNumTriangles() : 0; - m_modelStats.materialCount = m->GetNumMaterials(); -} - -std::string DumpVisitor::GetModelStatistics() -{ - std::ostringstream ss; - - // Print collected statistics per lod - if (m_lodStats.empty()) - m_lodStats.push_back(m_stats); - - std::vector::iterator it = m_lodStats.begin(); - unsigned int idx = 1; - while (it != m_lodStats.end()) { - ss << "\nLOD " << idx << '\n'; - ss << "Nodes: " << it->nodeCount << '\n'; - ss << "Geoms: " << it->opaqueGeomCount << " opaque, " << it->transGeomCount << " transparent\n"; - ss << "Triangles: " << it->triangles << '\n'; - ++it; - idx++; - }; - - ss << '\n'; - ss << "Materials: " << m_modelStats.materialCount << '\n'; - ss << "Collision triangles: " << m_modelStats.collTriCount << '\n'; - - return ss.str(); -} - -void DumpVisitor::ApplyNode(Node &n) -{ - PutIndent(); - PutNodeName(n); - - m_stats.nodeCount++; -} - -void DumpVisitor::ApplyGroup(Group &g) -{ - PutIndent(); - PutNodeName(g); - - m_level++; - g.Traverse(*this); - m_level--; - - m_stats.nodeCount++; -} - -void DumpVisitor::ApplyLOD(LOD &l) -{ - ApplyNode(l); - - m_level++; - for (unsigned int i = 0; i < l.GetNumChildren(); i++) { - l.GetChildAt(i)->Accept(*this); - m_lodStats.push_back(m_stats); - memset(&m_stats, 0, sizeof(LodStatistics)); + DumpVisitor::DumpVisitor(const Model *m) : + m_level(0), + m_stats() + { + //model statistics that cannot be visited) + m_modelStats.collTriCount = m->GetCollisionMesh() ? m->GetCollisionMesh()->GetNumTriangles() : 0; + m_modelStats.materialCount = m->GetNumMaterials(); } - m_level--; -} -void DumpVisitor::ApplyStaticGeometry(StaticGeometry &g) -{ - if (g.GetNodeMask() & NODE_TRANSPARENT) - m_stats.transGeomCount++; - else - m_stats.opaqueGeomCount++; + std::string DumpVisitor::GetModelStatistics() + { + std::ostringstream ss; - for (unsigned int i = 0; i < g.GetNumMeshes(); i++) - m_stats.triangles += g.GetMeshAt(i).indexBuffer->GetSize() / 3; + // Print collected statistics per lod + if (m_lodStats.empty()) + m_lodStats.push_back(m_stats); - ApplyNode(static_cast(g)); -} + std::vector::iterator it = m_lodStats.begin(); + unsigned int idx = 1; + while (it != m_lodStats.end()) { + ss << "\nLOD " << idx << '\n'; + ss << "Nodes: " << it->nodeCount << '\n'; + ss << "Geoms: " << it->opaqueGeomCount << " opaque, " << it->transGeomCount << " transparent\n"; + ss << "Triangles: " << it->triangles << '\n'; + ++it; + idx++; + }; -void DumpVisitor::PutIndent() const -{ - for (unsigned int i = 0; i < m_level; i++) - Output(" "); -} + ss << '\n'; + ss << "Materials: " << m_modelStats.materialCount << '\n'; + ss << "Collision triangles: " << m_modelStats.collTriCount << '\n'; -void DumpVisitor::PutNodeName(const Node &g) const -{ - if (g.GetName().empty()) - Output("%s\n", g.GetTypeName()); - else - Output("%s - %s\n", g.GetTypeName(), g.GetName().c_str()); -} -} + return ss.str(); + } + + void DumpVisitor::ApplyNode(Node &n) + { + PutIndent(); + PutNodeName(n); + + m_stats.nodeCount++; + } + + void DumpVisitor::ApplyGroup(Group &g) + { + PutIndent(); + PutNodeName(g); + + m_level++; + g.Traverse(*this); + m_level--; + + m_stats.nodeCount++; + } + + void DumpVisitor::ApplyLOD(LOD &l) + { + ApplyNode(l); + + m_level++; + for (unsigned int i = 0; i < l.GetNumChildren(); i++) { + l.GetChildAt(i)->Accept(*this); + m_lodStats.push_back(m_stats); + memset(&m_stats, 0, sizeof(LodStatistics)); + } + m_level--; + } + + void DumpVisitor::ApplyStaticGeometry(StaticGeometry &g) + { + if (g.GetNodeMask() & NODE_TRANSPARENT) + m_stats.transGeomCount++; + else + m_stats.opaqueGeomCount++; + + for (unsigned int i = 0; i < g.GetNumMeshes(); i++) + m_stats.triangles += g.GetMeshAt(i).indexBuffer->GetSize() / 3; + + ApplyNode(static_cast(g)); + } + + void DumpVisitor::PutIndent() const + { + for (unsigned int i = 0; i < m_level; i++) + Output(" "); + } + + void DumpVisitor::PutNodeName(const Node &g) const + { + if (g.GetName().empty()) + Output("%s\n", g.GetTypeName()); + else + Output("%s - %s\n", g.GetTypeName(), g.GetName().c_str()); + } +} // namespace SceneGraph diff --git a/src/scenegraph/DumpVisitor.h b/src/scenegraph/DumpVisitor.h index 8a811ffdf..35009fd09 100644 --- a/src/scenegraph/DumpVisitor.h +++ b/src/scenegraph/DumpVisitor.h @@ -8,40 +8,40 @@ */ namespace SceneGraph { -class Model; + class Model; -class DumpVisitor : public NodeVisitor { -public: - struct LodStatistics { - unsigned int nodeCount; - unsigned int opaqueGeomCount; - unsigned int transGeomCount; + class DumpVisitor : public NodeVisitor { + public: + struct LodStatistics { + unsigned int nodeCount; + unsigned int opaqueGeomCount; + unsigned int transGeomCount; - unsigned int triangles; + unsigned int triangles; + }; + + struct ModelStatistics { + unsigned int materialCount; + unsigned int collTriCount; + }; + + DumpVisitor(const Model *m); + + std::string GetModelStatistics(); + + virtual void ApplyNode(Node &); + virtual void ApplyGroup(Group &); + virtual void ApplyLOD(LOD &); + virtual void ApplyStaticGeometry(StaticGeometry &); + + private: + void PutIndent() const; + void PutNodeName(const Node &) const; + + unsigned int m_level; + ModelStatistics m_modelStats; + LodStatistics m_stats; + std::vector m_lodStats; }; - struct ModelStatistics { - unsigned int materialCount; - unsigned int collTriCount; - }; - - DumpVisitor(const Model *m); - - std::string GetModelStatistics(); - - virtual void ApplyNode(Node&); - virtual void ApplyGroup(Group&); - virtual void ApplyLOD(LOD&); - virtual void ApplyStaticGeometry(StaticGeometry&); - -private: - void PutIndent() const; - void PutNodeName(const Node&) const; - - unsigned int m_level; - ModelStatistics m_modelStats; - LodStatistics m_stats; - std::vector m_lodStats; -}; - -} +} // namespace SceneGraph diff --git a/src/scenegraph/FindNodeVisitor.cpp b/src/scenegraph/FindNodeVisitor.cpp index 62673b15d..b32f40a58 100644 --- a/src/scenegraph/FindNodeVisitor.cpp +++ b/src/scenegraph/FindNodeVisitor.cpp @@ -7,26 +7,26 @@ namespace SceneGraph { -FindNodeVisitor::FindNodeVisitor(Criteria c, const std::string &s) -: m_criteria(c) -, m_string(s) -{ -} - -void FindNodeVisitor::ApplyNode(Node &n) -{ - if (m_criteria == MATCH_NAME_STARTSWITH) { - if (!n.GetName().empty() && starts_with(n.GetName(), m_string.c_str())) - m_results.push_back(&n); - } else if (m_criteria == MATCH_NAME_ENDSWITH ) { - if (!n.GetName().empty() && ends_with(n.GetName(), m_string.c_str())) - m_results.push_back(&n); - } else { - if (!n.GetName().empty() && n.GetName() == m_string) - m_results.push_back(&n); + FindNodeVisitor::FindNodeVisitor(Criteria c, const std::string &s) : + m_criteria(c), + m_string(s) + { } - n.Traverse(*this); -} + void FindNodeVisitor::ApplyNode(Node &n) + { + if (m_criteria == MATCH_NAME_STARTSWITH) { + if (!n.GetName().empty() && starts_with(n.GetName(), m_string.c_str())) + m_results.push_back(&n); + } else if (m_criteria == MATCH_NAME_ENDSWITH) { + if (!n.GetName().empty() && ends_with(n.GetName(), m_string.c_str())) + m_results.push_back(&n); + } else { + if (!n.GetName().empty() && n.GetName() == m_string) + m_results.push_back(&n); + } -} + n.Traverse(*this); + } + +} // namespace SceneGraph diff --git a/src/scenegraph/FindNodeVisitor.h b/src/scenegraph/FindNodeVisitor.h index 973ed12f8..4441e2693 100644 --- a/src/scenegraph/FindNodeVisitor.h +++ b/src/scenegraph/FindNodeVisitor.h @@ -11,25 +11,25 @@ namespace SceneGraph { -class FindNodeVisitor : public NodeVisitor { -public: - enum Criteria { //or criterion. whatever. - MATCH_NAME_FULL, - MATCH_NAME_STARTSWITH, - MATCH_NAME_ENDSWITH - //match type etc. + class FindNodeVisitor : public NodeVisitor { + public: + enum Criteria { //or criterion. whatever. + MATCH_NAME_FULL, + MATCH_NAME_STARTSWITH, + MATCH_NAME_ENDSWITH + //match type etc. + }; + FindNodeVisitor(Criteria crit, const std::string &searchstring); + virtual void ApplyNode(Node &); + + const std::vector &GetResults() { return m_results; } + + private: + std::vector m_results; + Criteria m_criteria; + std::string m_string; }; - FindNodeVisitor(Criteria crit, const std::string &searchstring); - virtual void ApplyNode(Node&); - const std::vector &GetResults() { return m_results; } - -private: - std::vector m_results; - Criteria m_criteria; - std::string m_string; -}; - -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Group.cpp b/src/scenegraph/Group.cpp index c53c2e98f..9ba90b4cd 100644 --- a/src/scenegraph/Group.cpp +++ b/src/scenegraph/Group.cpp @@ -2,149 +2,142 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Group.h" -#include "NodeVisitor.h" -#include "NodeCopyCache.h" #include "BaseLoader.h" +#include "NodeCopyCache.h" +#include "NodeVisitor.h" #include "utils.h" namespace SceneGraph { -Group::Group(Graphics::Renderer *r) -: Node(r, NODE_SOLID | NODE_TRANSPARENT) -{ -} - -Group::~Group() -{ - for(std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) + Group::Group(Graphics::Renderer *r) : + Node(r, NODE_SOLID | NODE_TRANSPARENT) { - (*itr)->DecRefCount(); } -} -Group::Group(const Group &group, NodeCopyCache *cache) -: Node(group, cache) -{ - for(std::vector::const_iterator itr = group.m_children.begin(); - itr != group.m_children.end(); - ++itr) + Group::~Group() { - Node *node = (*itr)->Clone(cache); - AddChild(node); - } -} - -Node* Group::Clone(NodeCopyCache *cache) -{ - return cache->Copy(this); -} - -void Group::Save(NodeDatabase &db) -{ - Node::Save(db); - //for all groups, children are saved by Loader -} - -Group *Group::Load(NodeDatabase &db) -{ - return new Group(db.loader->GetRenderer()); - //children are loaded by Loader -} - -void Group::AddChild(Node *child) -{ - child->IncRefCount(); - m_children.push_back(child); -} - -bool Group::RemoveChild(Node *node) -{ - if (!node) return false; - for(std::vector::iterator itr = m_children.begin(); - itr != m_children.end(); - ++itr) - { - if((*itr) == node) { - itr = m_children.erase(itr); - node->DecRefCount(); - return true; + for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) { + (*itr)->DecRefCount(); } } - return false; -} -bool Group::RemoveChildAt(unsigned int idx) -{ - if (m_children.empty() || idx > m_children.size() - 1) return false; - Node *node = m_children.at(idx); - node->DecRefCount(); - m_children.erase(m_children.begin() + idx); - return true; -} - -Node* Group::GetChildAt(unsigned int idx) -{ - return m_children.at(idx); -} - -Node* Group::FindNode(const std::string &name) -{ - if (m_name == name) - return this; - - Node* result = 0; - for(std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) + Group::Group(const Group &group, NodeCopyCache *cache) : + Node(group, cache) { - result = (*itr)->FindNode(name); - if (result) break; + for (std::vector::const_iterator itr = group.m_children.begin(); + itr != group.m_children.end(); + ++itr) { + Node *node = (*itr)->Clone(cache); + AddChild(node); + } } - return result; -} - -void Group::Accept(NodeVisitor &nv) -{ - nv.ApplyGroup(*this); -} - -void Group::Traverse(NodeVisitor &nv) -{ - for(std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) + Node *Group::Clone(NodeCopyCache *cache) { - (*itr)->Accept(nv); + return cache->Copy(this); } -} -void Group::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - RenderChildren(trans, rd); -} - -void Group::RenderChildren(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - for(std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) + void Group::Save(NodeDatabase &db) { - if((*itr)->GetNodeMask() & rd->nodemask) - (*itr)->Render(trans, rd); + Node::Save(db); + //for all groups, children are saved by Loader } -} -void Group::Render(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - RenderChildren(trans, rd); -} - -void Group::RenderChildren(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) + Group *Group::Load(NodeDatabase &db) { - if ((*itr)->GetNodeMask() & rd->nodemask) - (*itr)->Render(trans, rd); + return new Group(db.loader->GetRenderer()); + //children are loaded by Loader } -} -} + void Group::AddChild(Node *child) + { + child->IncRefCount(); + m_children.push_back(child); + } + + bool Group::RemoveChild(Node *node) + { + if (!node) return false; + for (std::vector::iterator itr = m_children.begin(); + itr != m_children.end(); + ++itr) { + if ((*itr) == node) { + itr = m_children.erase(itr); + node->DecRefCount(); + return true; + } + } + return false; + } + + bool Group::RemoveChildAt(unsigned int idx) + { + if (m_children.empty() || idx > m_children.size() - 1) return false; + Node *node = m_children.at(idx); + node->DecRefCount(); + m_children.erase(m_children.begin() + idx); + return true; + } + + Node *Group::GetChildAt(unsigned int idx) + { + return m_children.at(idx); + } + + Node *Group::FindNode(const std::string &name) + { + if (m_name == name) + return this; + + Node *result = 0; + for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) { + result = (*itr)->FindNode(name); + if (result) break; + } + + return result; + } + + void Group::Accept(NodeVisitor &nv) + { + nv.ApplyGroup(*this); + } + + void Group::Traverse(NodeVisitor &nv) + { + for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) { + (*itr)->Accept(nv); + } + } + + void Group::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + RenderChildren(trans, rd); + } + + void Group::RenderChildren(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) { + if ((*itr)->GetNodeMask() & rd->nodemask) + (*itr)->Render(trans, rd); + } + } + + void Group::Render(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED() + RenderChildren(trans, rd); + } + + void Group::RenderChildren(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED() + for (std::vector::iterator itr = m_children.begin(), itEnd = m_children.end(); itr != itEnd; ++itr) { + if ((*itr)->GetNodeMask() & rd->nodemask) + (*itr)->Render(trans, rd); + } + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Group.h b/src/scenegraph/Group.h index ef7923525..e28a821ee 100644 --- a/src/scenegraph/Group.h +++ b/src/scenegraph/Group.h @@ -9,34 +9,33 @@ namespace SceneGraph { -class Group : public Node -{ -public: - Group(Graphics::Renderer *r); - Group(const Group&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0) override; - virtual const char *GetTypeName() const override { return "Group"; } - virtual void Save(NodeDatabase&) override; - static Group *Load(NodeDatabase&); + class Group : public Node { + public: + Group(Graphics::Renderer *r); + Group(const Group &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0) override; + virtual const char *GetTypeName() const override { return "Group"; } + virtual void Save(NodeDatabase &) override; + static Group *Load(NodeDatabase &); - virtual void AddChild(Node *child); - virtual bool RemoveChild(Node *node); //true on success - virtual bool RemoveChildAt(unsigned int position); //true on success - unsigned int GetNumChildren() const { return static_cast(m_children.size()); } - Node* GetChildAt(unsigned int); - virtual void Accept(NodeVisitor &v) override; - virtual void Traverse(NodeVisitor &v) override; - virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; - virtual void Render(const std::vector &trans, const RenderData *rd) override; - virtual Node* FindNode(const std::string &) override; + virtual void AddChild(Node *child); + virtual bool RemoveChild(Node *node); //true on success + virtual bool RemoveChildAt(unsigned int position); //true on success + unsigned int GetNumChildren() const { return static_cast(m_children.size()); } + Node *GetChildAt(unsigned int); + virtual void Accept(NodeVisitor &v) override; + virtual void Traverse(NodeVisitor &v) override; + virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; + virtual void Render(const std::vector &trans, const RenderData *rd) override; + virtual Node *FindNode(const std::string &) override; -protected: - virtual ~Group(); - virtual void RenderChildren(const matrix4x4f &trans, const RenderData *rd); - virtual void RenderChildren(const std::vector &trans, const RenderData *rd); - std::vector m_children; -}; + protected: + virtual ~Group(); + virtual void RenderChildren(const matrix4x4f &trans, const RenderData *rd); + virtual void RenderChildren(const std::vector &trans, const RenderData *rd); + std::vector m_children; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/LOD.cpp b/src/scenegraph/LOD.cpp index 18dc5a283..e736b59b9 100644 --- a/src/scenegraph/LOD.cpp +++ b/src/scenegraph/LOD.cpp @@ -2,123 +2,122 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "LOD.h" -#include "NodeVisitor.h" #include "BaseLoader.h" #include "NodeCopyCache.h" +#include "NodeVisitor.h" #include "StringF.h" #include "graphics/Graphics.h" #include "graphics/VertexBuffer.h" namespace SceneGraph { -LOD::LOD(Graphics::Renderer *r) : Group(r) -{ -} - -LOD::LOD(const LOD &lod, NodeCopyCache *cache) -: Group(lod, cache) -, m_pixelSizes(lod.m_pixelSizes) -{ -} - -Node* LOD::Clone(NodeCopyCache *cache) -{ - return cache->Copy(this); -} - -void LOD::Accept(NodeVisitor &nv) -{ - nv.ApplyLOD(*this); -} - -void LOD::AddLevel(float pixelSize, Node *nod) -{ - m_pixelSizes.push_back(pixelSize); - if (nod->GetName().empty()) { - nod->SetName(stringf("%0{f.0}", pixelSize)); - } - AddChild(nod); -} - -void LOD::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - //figure out approximate pixel size of object's bounding radius - //on screen and pick a child to render - const vector3f cameraPos(-trans[12], -trans[13], -trans[14]); - //fov is vertical, so using screen height - const float pixrad = Graphics::GetScreenHeight() * rd->boundingRadius / (cameraPos.Length() * Graphics::GetFovFactor()); - if (m_pixelSizes.empty()) return; - unsigned int lod = m_children.size() - 1; - for (unsigned int i=m_pixelSizes.size(); i > 0; i--) { - if (pixrad < m_pixelSizes[i-1]) lod = i-1; - } - m_children[lod]->Render(trans, rd); -} - -void LOD::Render(const std::vector &trans, const RenderData *rd) -{ - // anything to draw? - if (m_pixelSizes.empty()) - return; - - // got something to draw with - Graphics::Renderer *r = GetRenderer(); - if ( r!=nullptr ) + LOD::LOD(Graphics::Renderer *r) : + Group(r) { - const size_t count = m_pixelSizes.size(); - const size_t tsize = trans.size(); + } - // transformation buffers - std::vector< std::vector > transform; - transform.resize(count); - for (Uint32 i = 0; iCopy(this); + } + + void LOD::Accept(NodeVisitor &nv) + { + nv.ApplyLOD(*this); + } + + void LOD::AddLevel(float pixelSize, Node *nod) + { + m_pixelSizes.push_back(pixelSize); + if (nod->GetName().empty()) { + nod->SetName(stringf("%0{f.0}", pixelSize)); } + AddChild(nod); + } - // seperate out the transformations - for (auto mt : trans) - { - //figure out approximate pixel size of object's bounding radius - //on screen and pick a child to render - const vector3f cameraPos(-mt[12], -mt[13], -mt[14]); - //fov is vertical, so using screen height - const float pixrad = Graphics::GetScreenHeight() * rd->boundingRadius / (cameraPos.Length() * Graphics::GetFovFactor()); - unsigned int lod = m_children.size() - 1; - for (unsigned int i = m_pixelSizes.size(); i > 0; i--) { - if (pixrad < m_pixelSizes[i - 1]) { - lod = i - 1; + void LOD::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + //figure out approximate pixel size of object's bounding radius + //on screen and pick a child to render + const vector3f cameraPos(-trans[12], -trans[13], -trans[14]); + //fov is vertical, so using screen height + const float pixrad = Graphics::GetScreenHeight() * rd->boundingRadius / (cameraPos.Length() * Graphics::GetFovFactor()); + if (m_pixelSizes.empty()) return; + unsigned int lod = m_children.size() - 1; + for (unsigned int i = m_pixelSizes.size(); i > 0; i--) { + if (pixrad < m_pixelSizes[i - 1]) lod = i - 1; + } + m_children[lod]->Render(trans, rd); + } + + void LOD::Render(const std::vector &trans, const RenderData *rd) + { + // anything to draw? + if (m_pixelSizes.empty()) + return; + + // got something to draw with + Graphics::Renderer *r = GetRenderer(); + if (r != nullptr) { + const size_t count = m_pixelSizes.size(); + const size_t tsize = trans.size(); + + // transformation buffers + std::vector> transform; + transform.resize(count); + for (Uint32 i = 0; i < count; i++) { + transform[i].reserve(tsize); + } + + // seperate out the transformations + for (auto mt : trans) { + //figure out approximate pixel size of object's bounding radius + //on screen and pick a child to render + const vector3f cameraPos(-mt[12], -mt[13], -mt[14]); + //fov is vertical, so using screen height + const float pixrad = Graphics::GetScreenHeight() * rd->boundingRadius / (cameraPos.Length() * Graphics::GetFovFactor()); + unsigned int lod = m_children.size() - 1; + for (unsigned int i = m_pixelSizes.size(); i > 0; i--) { + if (pixrad < m_pixelSizes[i - 1]) { + lod = i - 1; + } + } + + transform[lod].push_back(mt); + } + + // now render each of the buffers for each of the lods + for (Uint32 inst = 0; inst < transform.size(); inst++) { + if (!transform[inst].empty()) { + m_children[inst]->Render(transform[inst], rd); } } - - transform[lod].push_back(mt); - } - - // now render each of the buffers for each of the lods - for (Uint32 inst = 0; inst < transform.size(); inst++) { - if (!transform[inst].empty()) { - m_children[inst]->Render(transform[inst], rd); - } } } -} -void LOD::Save(NodeDatabase &db) -{ - Group::Save(db); - //same number as children - db.wr->Int32(m_pixelSizes.size()); - for (auto i : m_pixelSizes) - db.wr->Int32(i); -} + void LOD::Save(NodeDatabase &db) + { + Group::Save(db); + //same number as children + db.wr->Int32(m_pixelSizes.size()); + for (auto i : m_pixelSizes) + db.wr->Int32(i); + } -LOD* LOD::Load(NodeDatabase &db) -{ - LOD* lod = new LOD(db.loader->GetRenderer()); - const Uint32 numLevels = db.rd->Int32(); - for (Uint32 i = 0; i < numLevels; i++) - lod->m_pixelSizes.push_back(db.rd->Int32()); - return lod; -} + LOD *LOD::Load(NodeDatabase &db) + { + LOD *lod = new LOD(db.loader->GetRenderer()); + const Uint32 numLevels = db.rd->Int32(); + for (Uint32 i = 0; i < numLevels; i++) + lod->m_pixelSizes.push_back(db.rd->Int32()); + return lod; + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/LOD.h b/src/scenegraph/LOD.h index 2d4d9bf81..fde46e414 100644 --- a/src/scenegraph/LOD.h +++ b/src/scenegraph/LOD.h @@ -10,24 +10,24 @@ namespace SceneGraph { -class LOD : public Group { -public: - LOD(Graphics::Renderer *r); - LOD(const LOD&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0) override; - virtual const char *GetTypeName() const override { return "LOD"; } - virtual void Accept(NodeVisitor &v) override; - virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; - virtual void Render(const std::vector &trans, const RenderData *rd) override; - void AddLevel(float pixelRadius, Node *child); - virtual void Save(NodeDatabase&) override; - static LOD* Load(NodeDatabase&); + class LOD : public Group { + public: + LOD(Graphics::Renderer *r); + LOD(const LOD &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0) override; + virtual const char *GetTypeName() const override { return "LOD"; } + virtual void Accept(NodeVisitor &v) override; + virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; + virtual void Render(const std::vector &trans, const RenderData *rd) override; + void AddLevel(float pixelRadius, Node *child); + virtual void Save(NodeDatabase &) override; + static LOD *Load(NodeDatabase &); -protected: - virtual ~LOD() { } - std::vector m_pixelSizes; // same number as children -}; + protected: + virtual ~LOD() {} + std::vector m_pixelSizes; // same number as children + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Label3D.cpp b/src/scenegraph/Label3D.cpp index d602e542d..8c1fa72f9 100644 --- a/src/scenegraph/Label3D.cpp +++ b/src/scenegraph/Label3D.cpp @@ -9,82 +9,83 @@ namespace SceneGraph { -Label3D::Label3D(Graphics::Renderer *r, RefCountedPtr font) -: Node(r, NODE_TRANSPARENT) -, m_font(font) -{ - Graphics::MaterialDescriptor matdesc; - matdesc.textures = 1; - matdesc.alphaTest = true; - matdesc.lighting = true; - m_geometry.reset(font->CreateVertexArray()); - m_material.Reset(r->CreateMaterial(matdesc)); - m_material->texture0 = font->GetTexture(); - m_material->diffuse = Color::WHITE; - m_material->emissive = Color(38, 38, 38); - m_material->specular = Color::WHITE; - - Graphics::RenderStateDesc rsd; - rsd.depthWrite = false; - m_renderState = r->CreateRenderState(rsd); -} - -Label3D::Label3D(const Label3D &label, NodeCopyCache *cache) -: Node(label, cache) -, m_material(label.m_material) -, m_font(label.m_font) -, m_renderState(label.m_renderState) -{ - m_geometry.reset(m_font->CreateVertexArray()); -} - -Node* Label3D::Clone(NodeCopyCache *cache) -{ - return new Label3D(*this, cache); -} - -void Label3D::SetText(const std::string &text) -{ - //regenerate geometry - m_geometry->Clear(); - if (!text.empty()) { - m_font->GetGeometry(*m_geometry, text, vector2f(0.f)); - - // Happens if none of the characters in the string have glyphs in the SDF font. - // Most noticeably, this means text consisting of entirely Cyrillic - // or Chinese characters will vanish when rendered on a Label3D. - if (m_geometry->IsEmpty()) { return; } - - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = m_geometry->GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - - m_vbuffer.reset( m_renderer->CreateVertexBuffer(vbd) ); - m_vbuffer->Populate(*m_geometry); - } -} - -void Label3D::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - if( m_vbuffer.get() ) + Label3D::Label3D(Graphics::Renderer *r, RefCountedPtr font) : + Node(r, NODE_TRANSPARENT), + m_font(font) { - Graphics::Renderer *r = GetRenderer(); - r->SetTransform(trans); - r->DrawBuffer(m_vbuffer.get(), m_renderState, m_material.Get()); + Graphics::MaterialDescriptor matdesc; + matdesc.textures = 1; + matdesc.alphaTest = true; + matdesc.lighting = true; + m_geometry.reset(font->CreateVertexArray()); + m_material.Reset(r->CreateMaterial(matdesc)); + m_material->texture0 = font->GetTexture(); + m_material->diffuse = Color::WHITE; + m_material->emissive = Color(38, 38, 38); + m_material->specular = Color::WHITE; + + Graphics::RenderStateDesc rsd; + rsd.depthWrite = false; + m_renderState = r->CreateRenderState(rsd); } -} -void Label3D::Accept(NodeVisitor &nv) -{ - nv.ApplyLabel(*this); -} + Label3D::Label3D(const Label3D &label, NodeCopyCache *cache) : + Node(label, cache), + m_material(label.m_material), + m_font(label.m_font), + m_renderState(label.m_renderState) + { + m_geometry.reset(m_font->CreateVertexArray()); + } -} + Node *Label3D::Clone(NodeCopyCache *cache) + { + return new Label3D(*this, cache); + } + + void Label3D::SetText(const std::string &text) + { + //regenerate geometry + m_geometry->Clear(); + if (!text.empty()) { + m_font->GetGeometry(*m_geometry, text, vector2f(0.f)); + + // Happens if none of the characters in the string have glyphs in the SDF font. + // Most noticeably, this means text consisting of entirely Cyrillic + // or Chinese characters will vanish when rendered on a Label3D. + if (m_geometry->IsEmpty()) { + return; + } + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = m_geometry->GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + m_vbuffer.reset(m_renderer->CreateVertexBuffer(vbd)); + m_vbuffer->Populate(*m_geometry); + } + } + + void Label3D::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + if (m_vbuffer.get()) { + Graphics::Renderer *r = GetRenderer(); + r->SetTransform(trans); + r->DrawBuffer(m_vbuffer.get(), m_renderState, m_material.Get()); + } + } + + void Label3D::Accept(NodeVisitor &nv) + { + nv.ApplyLabel(*this); + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Label3D.h b/src/scenegraph/Label3D.h index c058326db..d73b15ef4 100644 --- a/src/scenegraph/Label3D.h +++ b/src/scenegraph/Label3D.h @@ -7,9 +7,9 @@ * Text geometry node, mostly for ship labels */ #include "Node.h" -#include "text/DistanceFieldFont.h" #include "graphics/Material.h" #include "graphics/RenderState.h" +#include "text/DistanceFieldFont.h" namespace Graphics { class Renderer; @@ -17,24 +17,24 @@ namespace Graphics { namespace SceneGraph { -class Label3D : public Node { -public: - Label3D(Graphics::Renderer *r, RefCountedPtr); - Label3D(const Label3D&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0); - virtual const char *GetTypeName() const { return "Label3D"; } - void SetText(const std::string&); - virtual void Render(const matrix4x4f &trans, const RenderData *rd); - virtual void Accept(NodeVisitor &v); + class Label3D : public Node { + public: + Label3D(Graphics::Renderer *r, RefCountedPtr); + Label3D(const Label3D &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0); + virtual const char *GetTypeName() const { return "Label3D"; } + void SetText(const std::string &); + virtual void Render(const matrix4x4f &trans, const RenderData *rd); + virtual void Accept(NodeVisitor &v); -private: - RefCountedPtr m_material; - std::unique_ptr m_geometry; - std::unique_ptr m_vbuffer; - RefCountedPtr m_font; - Graphics::RenderState *m_renderState; -}; + private: + RefCountedPtr m_material; + std::unique_ptr m_geometry; + std::unique_ptr m_vbuffer; + RefCountedPtr m_font; + Graphics::RenderState *m_renderState; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Loader.cpp b/src/scenegraph/Loader.cpp index ccdad0c56..81c741134 100644 --- a/src/scenegraph/Loader.cpp +++ b/src/scenegraph/Loader.cpp @@ -2,29 +2,28 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Loader.h" +#include "BinaryConverter.h" #include "CollisionGeometry.h" #include "FileSystem.h" #include "LOD.h" #include "Parser.h" #include "SceneGraph.h" -#include "BinaryConverter.h" #include "StringF.h" -#include "utils.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" -#include "FileSystem.h" -#include -#include -#include +#include "utils.h" +#include #include #include -#include +#include +#include +#include namespace { - class AssimpFileReadStream : public Assimp::IOStream - { + class AssimpFileReadStream : public Assimp::IOStream { public: - explicit AssimpFileReadStream(const RefCountedPtr& data): m_data(data) + explicit AssimpFileReadStream(const RefCountedPtr &data) : + m_data(data) { m_cursor = m_data->GetData(); } @@ -35,11 +34,11 @@ namespace { virtual size_t Read(void *buf, size_t size, size_t count) { - const char * const data_end = m_data->GetData() + m_data->GetSize(); + const char *const data_end = m_data->GetData() + m_data->GetSize(); const size_t remaining = (data_end - m_cursor); const size_t requested = size * count; const size_t len = std::min(remaining, requested); - memcpy(static_cast(buf), m_cursor, len); + memcpy(static_cast(buf), m_cursor, len); m_cursor += len; return len; } @@ -47,10 +46,10 @@ namespace { virtual aiReturn Seek(size_t offset, aiOrigin origin) { switch (origin) { - case aiOrigin_SET: break; - case aiOrigin_CUR: offset += Tell(); break; - case aiOrigin_END: offset += m_data->GetSize(); break; - default: assert(0); break; + case aiOrigin_SET: break; + case aiOrigin_CUR: offset += Tell(); break; + case aiOrigin_END: offset += m_data->GetSize(); break; + default: assert(0); break; } if (offset > m_data->GetSize()) return aiReturn_FAILURE; @@ -81,10 +80,10 @@ namespace { const char *m_cursor; }; - class AssimpFileSystem : public Assimp::IOSystem - { + class AssimpFileSystem : public Assimp::IOSystem { public: - AssimpFileSystem(FileSystem::FileSource& fs): m_fs(fs) {} + AssimpFileSystem(FileSystem::FileSource &fs) : + m_fs(fs) {} virtual ~AssimpFileSystem() {} virtual bool Exists(const char *path) const @@ -114,882 +113,871 @@ namespace { } // anonymous namespace namespace SceneGraph { -Loader::Loader(Graphics::Renderer *r, bool logWarnings, bool loadSGMfiles) -: BaseLoader(r) -, m_doLog(logWarnings) -, m_loadSGMs(loadSGMfiles) -, m_mostDetailedLod(false) -{ -} - -Model *Loader::LoadModel(const std::string &filename) -{ - PROFILE_SCOPED() - Model *m = LoadModel(filename, "models"); - return m; -} - -Model *Loader::LoadModel(const std::string &shortname, const std::string &basepath) -{ - PROFILE_SCOPED() - m_logMessages.clear(); - - std::vector list_model; - std::vector list_sgm; - FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; - for (FileSystem::FileEnumerator files(fileSource, basepath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) + Loader::Loader(Graphics::Renderer *r, bool logWarnings, bool loadSGMfiles) : + BaseLoader(r), + m_doLog(logWarnings), + m_loadSGMs(loadSGMfiles), + m_mostDetailedLod(false) { - const FileSystem::FileInfo &info = files.Current(); - const std::string &fpath = info.GetPath(); - - //check it's the expected type - if (info.IsFile()) { - if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files - list_model.push_back(fpath); - } else if (m_loadSGMs & ends_with_ci(fpath, ".sgm")) {// store only the shortname for ".sgm" files. - list_sgm.push_back(info.GetName().substr(0, info.GetName().size()-4)); - } - } } - if (m_loadSGMs) { - for (auto &sgmname : list_sgm) { - if (sgmname == shortname) { - //binary loader expects extension-less name. Might want to change this. - SceneGraph::BinaryConverter bc(m_renderer); - m_model = bc.Load(shortname); - if (m_model) - return m_model; - else - break; // we'll have to load the non-sgm file - } - } - } - - for (auto &fpath : list_model) { - RefCountedPtr filedata = FileSystem::gameDataFiles.ReadFile(fpath); - if (!filedata) { - Output("LoadModel: %s: could not read file\n", fpath.c_str()); - return nullptr; - } - - //check it's the wanted name & load it - const FileSystem::FileInfo& info = filedata->GetInfo(); - const std::string name = info.GetName(); - if (name.substr(0, name.length()-6) == shortname) { - ModelDefinition modelDefinition; - try { - //curPath is used to find textures, patterns, - //possibly other data files for this model. - //Strip trailing slash - m_curPath = info.GetDir(); - assert(!m_curPath.empty()); - if (m_curPath[m_curPath.length()-1] == '/') - m_curPath = m_curPath.substr(0, m_curPath.length()-1); - - Parser p(fileSource, fpath, m_curPath); - p.Parse(&modelDefinition); - } catch (ParseError &err) { - Output("%s\n", err.what()); - throw LoadingError(err.what()); - } - modelDefinition.name = shortname; - return CreateModel(modelDefinition); - } - } - throw (LoadingError("File not found")); -} - -Model *Loader::CreateModel(ModelDefinition &def) -{ - PROFILE_SCOPED() - using Graphics::Material; - if (def.matDefs.empty()) return 0; - if (def.lodDefs.empty()) return 0; - - Model *model = new Model(m_renderer, def.name); - m_model = model; - bool patternsUsed = false; - - m_thrustersRoot.Reset(new Group(m_renderer)); - m_billboardsRoot.Reset(new Group(m_renderer)); - - //create materials from definitions - for(std::vector::const_iterator it = def.matDefs.begin(); - it != def.matDefs.end(); ++it) + Model *Loader::LoadModel(const std::string &filename) { - if (it->use_pattern) patternsUsed = true; - ConvertMaterialDefinition(*it); + PROFILE_SCOPED() + Model *m = LoadModel(filename, "models"); + return m; } - //Output("Loaded %d materials\n", int(model->m_materials.size())); - //load meshes - //"mesh" here refers to a "mesh xxx.yyy" - //defined in the .model - std::map > meshCache; - LOD *lodNode = 0; - if (def.lodDefs.size() > 1) { //don't bother with a lod node if only one level - lodNode = new LOD(m_renderer); - model->GetRoot()->AddChild(lodNode); - } - for(std::vector::const_iterator lod = def.lodDefs.begin(); - lod != def.lodDefs.end(); ++lod) + Model *Loader::LoadModel(const std::string &shortname, const std::string &basepath) { - m_mostDetailedLod = (lod == def.lodDefs.end() - 1); + PROFILE_SCOPED() + m_logMessages.clear(); - //does a detail level have multiple meshes? If so, we need a Group. - Group *group = 0; - if (lodNode && (*lod).meshNames.size() > 1) { - group = new Group(m_renderer); - lodNode->AddLevel((*lod).pixelSize, group); - } - for(std::vector::const_iterator it = (*lod).meshNames.begin(); - it != (*lod).meshNames.end(); ++it) - { - try { - //multiple lods might use the same mesh - RefCountedPtr mesh; - std::map >::iterator cacheIt = meshCache.find((*it)); - if (cacheIt != meshCache.end()) - mesh = (*cacheIt).second; - else { - try { - mesh = LoadMesh(*it, def.animDefs); - } catch (LoadingError &err) { - //append filename - easiest to do here - throw (LoadingError(stringf("%0:\n%1", *it, err.what()))); - } - meshCache[*(it)] = mesh; + std::vector list_model; + std::vector list_sgm; + FileSystem::FileSource &fileSource = FileSystem::gameDataFiles; + for (FileSystem::FileEnumerator files(fileSource, basepath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) { + const FileSystem::FileInfo &info = files.Current(); + const std::string &fpath = info.GetPath(); + + //check it's the expected type + if (info.IsFile()) { + if (ends_with_ci(fpath, ".model")) { // store the path for ".model" files + list_model.push_back(fpath); + } else if (m_loadSGMs & ends_with_ci(fpath, ".sgm")) { // store only the shortname for ".sgm" files. + list_sgm.push_back(info.GetName().substr(0, info.GetName().size() - 4)); } - assert(mesh.Valid()); - - if (group) - group->AddChild(mesh.Get()); - else if(lodNode) { - lodNode->AddLevel((*lod).pixelSize, mesh.Get()); - } else - model->GetRoot()->AddChild(mesh.Get()); - } catch (LoadingError &err) { - delete model; - Output("%s\n", err.what()); - throw; } } + + if (m_loadSGMs) { + for (auto &sgmname : list_sgm) { + if (sgmname == shortname) { + //binary loader expects extension-less name. Might want to change this. + SceneGraph::BinaryConverter bc(m_renderer); + m_model = bc.Load(shortname); + if (m_model) + return m_model; + else + break; // we'll have to load the non-sgm file + } + } + } + + for (auto &fpath : list_model) { + RefCountedPtr filedata = FileSystem::gameDataFiles.ReadFile(fpath); + if (!filedata) { + Output("LoadModel: %s: could not read file\n", fpath.c_str()); + return nullptr; + } + + //check it's the wanted name & load it + const FileSystem::FileInfo &info = filedata->GetInfo(); + const std::string name = info.GetName(); + if (name.substr(0, name.length() - 6) == shortname) { + ModelDefinition modelDefinition; + try { + //curPath is used to find textures, patterns, + //possibly other data files for this model. + //Strip trailing slash + m_curPath = info.GetDir(); + assert(!m_curPath.empty()); + if (m_curPath[m_curPath.length() - 1] == '/') + m_curPath = m_curPath.substr(0, m_curPath.length() - 1); + + Parser p(fileSource, fpath, m_curPath); + p.Parse(&modelDefinition); + } catch (ParseError &err) { + Output("%s\n", err.what()); + throw LoadingError(err.what()); + } + modelDefinition.name = shortname; + return CreateModel(modelDefinition); + } + } + throw(LoadingError("File not found")); } - if (m_thrustersRoot->GetNumChildren() > 0) { - m_thrustersRoot->SetName("thrusters"); - m_thrustersRoot->SetNodeMask(NODE_TRANSPARENT); - model->GetRoot()->AddChild(m_thrustersRoot.Get()); - } - - if (m_billboardsRoot->GetNumChildren() > 0) { - m_billboardsRoot->SetName("navlights"); - m_billboardsRoot->SetNodeMask(NODE_TRANSPARENT); - model->GetRoot()->AddChild(m_billboardsRoot.Get()); - } - - // Load collision meshes - // They are added at the top level of the model root as CollisionGeometry nodes - for (std::vector::const_iterator it = def.collisionDefs.begin(); - it != def.collisionDefs.end(); ++it) + Model *Loader::CreateModel(ModelDefinition &def) { - try { - LoadCollision(*it); - } catch (LoadingError &err) { - throw (LoadingError(stringf("%0:\n%1", *it, err.what()))); + PROFILE_SCOPED() + using Graphics::Material; + if (def.matDefs.empty()) return 0; + if (def.lodDefs.empty()) return 0; + + Model *model = new Model(m_renderer, def.name); + m_model = model; + bool patternsUsed = false; + + m_thrustersRoot.Reset(new Group(m_renderer)); + m_billboardsRoot.Reset(new Group(m_renderer)); + + //create materials from definitions + for (std::vector::const_iterator it = def.matDefs.begin(); + it != def.matDefs.end(); ++it) { + if (it->use_pattern) patternsUsed = true; + ConvertMaterialDefinition(*it); } + //Output("Loaded %d materials\n", int(model->m_materials.size())); + + //load meshes + //"mesh" here refers to a "mesh xxx.yyy" + //defined in the .model + std::map> meshCache; + LOD *lodNode = 0; + if (def.lodDefs.size() > 1) { //don't bother with a lod node if only one level + lodNode = new LOD(m_renderer); + model->GetRoot()->AddChild(lodNode); + } + for (std::vector::const_iterator lod = def.lodDefs.begin(); + lod != def.lodDefs.end(); ++lod) { + m_mostDetailedLod = (lod == def.lodDefs.end() - 1); + + //does a detail level have multiple meshes? If so, we need a Group. + Group *group = 0; + if (lodNode && (*lod).meshNames.size() > 1) { + group = new Group(m_renderer); + lodNode->AddLevel((*lod).pixelSize, group); + } + for (std::vector::const_iterator it = (*lod).meshNames.begin(); + it != (*lod).meshNames.end(); ++it) { + try { + //multiple lods might use the same mesh + RefCountedPtr mesh; + std::map>::iterator cacheIt = meshCache.find((*it)); + if (cacheIt != meshCache.end()) + mesh = (*cacheIt).second; + else { + try { + mesh = LoadMesh(*it, def.animDefs); + } catch (LoadingError &err) { + //append filename - easiest to do here + throw(LoadingError(stringf("%0:\n%1", *it, err.what()))); + } + meshCache[*(it)] = mesh; + } + assert(mesh.Valid()); + + if (group) + group->AddChild(mesh.Get()); + else if (lodNode) { + lodNode->AddLevel((*lod).pixelSize, mesh.Get()); + } else + model->GetRoot()->AddChild(mesh.Get()); + } catch (LoadingError &err) { + delete model; + Output("%s\n", err.what()); + throw; + } + } + } + + if (m_thrustersRoot->GetNumChildren() > 0) { + m_thrustersRoot->SetName("thrusters"); + m_thrustersRoot->SetNodeMask(NODE_TRANSPARENT); + model->GetRoot()->AddChild(m_thrustersRoot.Get()); + } + + if (m_billboardsRoot->GetNumChildren() > 0) { + m_billboardsRoot->SetName("navlights"); + m_billboardsRoot->SetNodeMask(NODE_TRANSPARENT); + model->GetRoot()->AddChild(m_billboardsRoot.Get()); + } + + // Load collision meshes + // They are added at the top level of the model root as CollisionGeometry nodes + for (std::vector::const_iterator it = def.collisionDefs.begin(); + it != def.collisionDefs.end(); ++it) { + try { + LoadCollision(*it); + } catch (LoadingError &err) { + throw(LoadingError(stringf("%0:\n%1", *it, err.what()))); + } + } + + // Run CollisionVisitor to create the initial CM and its GeomTree. + // If no collision mesh is defined, a simple bounding box will be generated + Output("CreateCollisionMesh for : (%s)\n", m_model->m_name.c_str()); + m_model->CreateCollisionMesh(); + + // Do an initial animation update to get all the animation transforms correct + m_model->UpdateAnimations(); + + //find usable pattern textures from the model directory + if (patternsUsed) + SetUpPatterns(); + + return model; } - // Run CollisionVisitor to create the initial CM and its GeomTree. - // If no collision mesh is defined, a simple bounding box will be generated - Output("CreateCollisionMesh for : (%s)\n", m_model->m_name.c_str()); - m_model->CreateCollisionMesh(); + RefCountedPtr Loader::LoadMesh(const std::string &filename, const AnimList &animDefs) + { + PROFILE_SCOPED() + //remove path from filename for nicer logging + size_t slashpos = filename.rfind("/"); + m_curMeshDef = filename.substr(slashpos + 1, filename.length() - slashpos); - // Do an initial animation update to get all the animation transforms correct - m_model->UpdateAnimations(); + Assimp::Importer importer; + importer.SetIOHandler(new AssimpFileSystem(FileSystem::gameDataFiles)); - //find usable pattern textures from the model directory - if (patternsUsed) - SetUpPatterns(); + //Removing components is suggested to optimize loading. We do not care about vtx colors now. + importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS); + importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT, AI_SLM_DEFAULT_MAX_VERTICES); - return model; -} + //There are several optimizations assimp can do, intentionally skipping them now + const aiScene *scene = importer.ReadFile( + filename, + aiProcess_RemoveComponent | + aiProcess_Triangulate | + aiProcess_SortByPType | //ignore point, line primitive types (collada dummy nodes seem to be fine) + aiProcess_GenUVCoords | + aiProcess_FlipUVs | + aiProcess_CalcTangentSpace | + aiProcess_JoinIdenticalVertices | + aiProcess_GenSmoothNormals | //only if normals not specified + aiProcess_ImproveCacheLocality | + aiProcess_LimitBoneWeights | + aiProcess_FindDegenerates | + aiProcess_FindInvalidData); -RefCountedPtr Loader::LoadMesh(const std::string &filename, const AnimList &animDefs) -{ - PROFILE_SCOPED() - //remove path from filename for nicer logging - size_t slashpos = filename.rfind("/"); - m_curMeshDef = filename.substr(slashpos+1, filename.length()-slashpos); + if (!scene) + throw LoadingError("Couldn't load file"); - Assimp::Importer importer; - importer.SetIOHandler(new AssimpFileSystem(FileSystem::gameDataFiles)); + if (scene->mNumMeshes == 0) + throw LoadingError("No geometry found"); - //Removing components is suggested to optimize loading. We do not care about vtx colors now. - importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS); - importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT, AI_SLM_DEFAULT_MAX_VERTICES); + //turn all scene aiMeshes into Surfaces + //Index matches assimp index. + std::vector> geoms; + ConvertAiMeshes(geoms, scene); - //There are several optimizations assimp can do, intentionally skipping them now - const aiScene *scene = importer.ReadFile( - filename, - aiProcess_RemoveComponent | - aiProcess_Triangulate | - aiProcess_SortByPType | //ignore point, line primitive types (collada dummy nodes seem to be fine) - aiProcess_GenUVCoords | - aiProcess_FlipUVs | - aiProcess_CalcTangentSpace | - aiProcess_JoinIdenticalVertices | - aiProcess_GenSmoothNormals | //only if normals not specified - aiProcess_ImproveCacheLocality | - aiProcess_LimitBoneWeights | - aiProcess_FindDegenerates | - aiProcess_FindInvalidData); + // Recursive structure conversion. Matrix needs to be accumulated for + // special features that are absolute-positioned (thrusters) + RefCountedPtr meshRoot(new Group(m_renderer)); - if(!scene) - throw LoadingError("Couldn't load file"); + ConvertNodes(scene->mRootNode, static_cast(meshRoot.Get()), geoms, matrix4x4f::Identity()); + ConvertAnimations(scene, animDefs, static_cast(meshRoot.Get())); - if(scene->mNumMeshes == 0) - throw LoadingError("No geometry found"); - - //turn all scene aiMeshes into Surfaces - //Index matches assimp index. - std::vector > geoms; - ConvertAiMeshes(geoms, scene); - - // Recursive structure conversion. Matrix needs to be accumulated for - // special features that are absolute-positioned (thrusters) - RefCountedPtr meshRoot(new Group(m_renderer)); - - ConvertNodes(scene->mRootNode, static_cast(meshRoot.Get()), geoms, matrix4x4f::Identity()); - ConvertAnimations(scene, animDefs, static_cast(meshRoot.Get())); - - return meshRoot; -} - -static bool in_range(double keytime, double start, double end) -{ - return (keytime >= start - 0.001 && keytime - 0.001 <= end); -} - -// check animation channel has a key within time range -bool Loader::CheckKeysInRange(const aiNodeAnim *chan, double start, double end) -{ - int posKeysInRange = 0; - int rotKeysInRange = 0; - int sclKeysInRange = 0; - - for (unsigned int k=0; kmNumPositionKeys; k++) { - const aiVectorKey &aikey = chan->mPositionKeys[k]; - if (in_range(aikey.mTime, start, end)) posKeysInRange++; + return meshRoot; } - for (unsigned int k=0; kmNumRotationKeys; k++) { - const aiQuatKey &aikey = chan->mRotationKeys[k]; - if (in_range(aikey.mTime, start, end)) rotKeysInRange++; + static bool in_range(double keytime, double start, double end) + { + return (keytime >= start - 0.001 && keytime - 0.001 <= end); } - for (unsigned int k=0; kmNumScalingKeys; k++) { - const aiVectorKey &aikey = chan->mScalingKeys[k]; - if (in_range(aikey.mTime, start, end)) sclKeysInRange++; + // check animation channel has a key within time range + bool Loader::CheckKeysInRange(const aiNodeAnim *chan, double start, double end) + { + int posKeysInRange = 0; + int rotKeysInRange = 0; + int sclKeysInRange = 0; + + for (unsigned int k = 0; k < chan->mNumPositionKeys; k++) { + const aiVectorKey &aikey = chan->mPositionKeys[k]; + if (in_range(aikey.mTime, start, end)) posKeysInRange++; + } + + for (unsigned int k = 0; k < chan->mNumRotationKeys; k++) { + const aiQuatKey &aikey = chan->mRotationKeys[k]; + if (in_range(aikey.mTime, start, end)) rotKeysInRange++; + } + + for (unsigned int k = 0; k < chan->mNumScalingKeys; k++) { + const aiVectorKey &aikey = chan->mScalingKeys[k]; + if (in_range(aikey.mTime, start, end)) sclKeysInRange++; + } + + return (posKeysInRange > 0 || rotKeysInRange > 0 || sclKeysInRange > 0); } - return (posKeysInRange > 0 || rotKeysInRange > 0 || sclKeysInRange > 0); -} + void Loader::AddLog(const std::string &msg) + { + if (m_doLog) m_logMessages.push_back(msg); + } -void Loader::AddLog(const std::string &msg) -{ - if (m_doLog) m_logMessages.push_back(msg); -} + void Loader::CheckAnimationConflicts(const Animation *anim, const std::vector &otherAnims) + { + typedef std::vector::const_iterator ChannelIterator; + typedef std::vector::const_iterator AnimIterator; -void Loader::CheckAnimationConflicts(const Animation* anim, const std::vector &otherAnims) -{ - typedef std::vector::const_iterator ChannelIterator; - typedef std::vector::const_iterator AnimIterator; + if (anim->m_channels.empty() || otherAnims.empty()) return; - if (anim->m_channels.empty() || otherAnims.empty()) return; - - //check all other animations that they don't control the same nodes as this animation, since - //that is not supported at this point - for (ChannelIterator chan = anim->m_channels.begin(); chan != anim->m_channels.end(); ++chan) { - for (AnimIterator other = otherAnims.begin(); other != otherAnims.end(); ++other) { - const Animation *otherAnim = (*other); - if (otherAnim == anim) - continue; - for (ChannelIterator otherChan = otherAnim->m_channels.begin(); otherChan != otherAnim->m_channels.end(); ++otherChan) { - //warnings as errors mentality - this is not really fatal - if (chan->node == otherChan->node) - throw LoadingError(stringf("Animations %0 and %1 both control node: %2", anim->GetName(), otherAnim->GetName(), chan->node->GetName())); + //check all other animations that they don't control the same nodes as this animation, since + //that is not supported at this point + for (ChannelIterator chan = anim->m_channels.begin(); chan != anim->m_channels.end(); ++chan) { + for (AnimIterator other = otherAnims.begin(); other != otherAnims.end(); ++other) { + const Animation *otherAnim = (*other); + if (otherAnim == anim) + continue; + for (ChannelIterator otherChan = otherAnim->m_channels.begin(); otherChan != otherAnim->m_channels.end(); ++otherChan) { + //warnings as errors mentality - this is not really fatal + if (chan->node == otherChan->node) + throw LoadingError(stringf("Animations %0 and %1 both control node: %2", anim->GetName(), otherAnim->GetName(), chan->node->GetName())); + } } } } -} #pragma pack(push, 4) -struct ModelVtx { - vector3f pos; - vector3f nrm; - vector2f uv0; -}; + struct ModelVtx { + vector3f pos; + vector3f nrm; + vector2f uv0; + }; -struct ModelTangentVtx { - vector3f pos; - vector3f nrm; - vector2f uv0; - vector3f tangent; -}; + struct ModelTangentVtx { + vector3f pos; + vector3f nrm; + vector2f uv0; + vector3f tangent; + }; #pragma pack(pop) -void Loader::ConvertAiMeshes(std::vector > &geoms, const aiScene *scene) -{ - PROFILE_SCOPED() - //XXX sigh, workaround for obj loader - int matIdxOffs = 0; - if (scene->mNumMaterials > scene->mNumMeshes) - matIdxOffs = 1; + void Loader::ConvertAiMeshes(std::vector> &geoms, const aiScene *scene) + { + PROFILE_SCOPED() + //XXX sigh, workaround for obj loader + int matIdxOffs = 0; + if (scene->mNumMaterials > scene->mNumMeshes) + matIdxOffs = 1; - //turn meshes into static geometry nodes - for (unsigned int i=0; imNumMeshes; i++) { - const aiMesh *mesh = scene->mMeshes[i]; - assert(mesh->HasNormals()); + //turn meshes into static geometry nodes + for (unsigned int i = 0; i < scene->mNumMeshes; i++) { + const aiMesh *mesh = scene->mMeshes[i]; + assert(mesh->HasNormals()); - RefCountedPtr geom(new StaticGeometry(m_renderer)); - geom->SetName(stringf("sgMesh%0{u}", i)); + RefCountedPtr geom(new StaticGeometry(m_renderer)); + geom->SetName(stringf("sgMesh%0{u}", i)); - const bool hasUVs = mesh->HasTextureCoords(0); - const bool hasTangents = mesh->HasTangentsAndBitangents(); - if (!hasUVs) - AddLog(stringf("%0: missing UV coordinates", m_curMeshDef)); - if (!hasTangents) - AddLog(stringf("%0: missing Tangents and Bitangents coordinates", m_curMeshDef)); - //sadly, aimesh name is usually empty so no help for logging + const bool hasUVs = mesh->HasTextureCoords(0); + const bool hasTangents = mesh->HasTangentsAndBitangents(); + if (!hasUVs) + AddLog(stringf("%0: missing UV coordinates", m_curMeshDef)); + if (!hasTangents) + AddLog(stringf("%0: missing Tangents and Bitangents coordinates", m_curMeshDef)); + //sadly, aimesh name is usually empty so no help for logging - //Material names are not consistent throughout formats. - //try matching name first, if that fails use index - RefCountedPtr mat; - const aiMaterial *amat = scene->mMaterials[mesh->mMaterialIndex]; - aiString aiMatName; - if(AI_SUCCESS == amat->Get(AI_MATKEY_NAME,aiMatName)) - mat = m_model->GetMaterialByName(std::string(aiMatName.C_Str())); + //Material names are not consistent throughout formats. + //try matching name first, if that fails use index + RefCountedPtr mat; + const aiMaterial *amat = scene->mMaterials[mesh->mMaterialIndex]; + aiString aiMatName; + if (AI_SUCCESS == amat->Get(AI_MATKEY_NAME, aiMatName)) + mat = m_model->GetMaterialByName(std::string(aiMatName.C_Str())); - if (!mat.Valid()) { - const unsigned int matIdx = mesh->mMaterialIndex - matIdxOffs; - AddLog(stringf("%0: no material %1, using material %2{u} instead", m_curMeshDef, aiMatName.C_Str(), matIdx+1)); - mat = m_model->GetMaterialByIndex(matIdx); + if (!mat.Valid()) { + const unsigned int matIdx = mesh->mMaterialIndex - matIdxOffs; + AddLog(stringf("%0: no material %1, using material %2{u} instead", m_curMeshDef, aiMatName.C_Str(), matIdx + 1)); + mat = m_model->GetMaterialByIndex(matIdx); + } + assert(mat.Valid()); + + Graphics::RenderStateDesc rsd; + //turn on alpha blending and mark entire node as transparent + //(all importers split by material so far) + if (mat->diffuse.a < 255) { + geom->SetNodeMask(NODE_TRANSPARENT); + geom->m_blendMode = Graphics::BLEND_ALPHA; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthWrite = false; + } + + geom->SetRenderState(m_renderer->CreateRenderState(rsd)); + + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[0].offset = hasTangents ? offsetof(ModelTangentVtx, pos) : offsetof(ModelVtx, pos); + vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].offset = hasTangents ? offsetof(ModelTangentVtx, nrm) : offsetof(ModelVtx, nrm); + vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.attrib[2].offset = hasTangents ? offsetof(ModelTangentVtx, uv0) : offsetof(ModelVtx, uv0); + if (hasTangents) { + vbd.attrib[3].semantic = Graphics::ATTRIB_TANGENT; + vbd.attrib[3].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[3].offset = offsetof(ModelTangentVtx, tangent); + } + vbd.stride = hasTangents ? sizeof(ModelTangentVtx) : sizeof(ModelVtx); + vbd.numVertices = mesh->mNumVertices; + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + + RefCountedPtr vb(m_renderer->CreateVertexBuffer(vbd)); + + // huge meshes are split by the importer so this should not exceed 65K indices + std::vector indices; + if (mesh->mNumFaces > 0) { + indices.reserve(mesh->mNumFaces * 3); + for (unsigned int f = 0; f < mesh->mNumFaces; f++) { + const aiFace *face = &mesh->mFaces[f]; + for (unsigned int j = 0; j < face->mNumIndices; j++) { + indices.push_back(face->mIndices[j]); + } + } + } else { + //generate dummy indices + AddLog(stringf("Missing indices in mesh %0{u}", i)); + indices.reserve(mesh->mNumVertices); + for (unsigned int v = 0; v < mesh->mNumVertices; v++) + indices.push_back(v); + } + + assert(indices.size() > 0); + + //create buffer & copy + RefCountedPtr ib(m_renderer->CreateIndexBuffer(indices.size(), Graphics::BUFFER_USAGE_STATIC)); + Uint32 *idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); + for (Uint32 j = 0; j < indices.size(); j++) + idxPtr[j] = indices[j]; + ib->Unmap(); + + //copy vertices, always assume normals + //replace nonexistent UVs with zeros + if (!hasTangents) { + ModelVtx *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + for (unsigned int v = 0; v < mesh->mNumVertices; v++) { + const aiVector3D &vtx = mesh->mVertices[v]; + const aiVector3D &norm = mesh->mNormals[v]; + const aiVector3D &uv0 = hasUVs ? mesh->mTextureCoords[0][v] : aiVector3D(0.f); + vtxPtr[v].pos = vector3f(vtx.x, vtx.y, vtx.z); + vtxPtr[v].nrm = vector3f(norm.x, norm.y, norm.z); + vtxPtr[v].uv0 = vector2f(uv0.x, uv0.y); + + //update bounding box + //untransformed points, collision visitor will transform + geom->m_boundingBox.Update(vtx.x, vtx.y, vtx.z); + } + vb->Unmap(); + } else { + ModelTangentVtx *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + for (unsigned int v = 0; v < mesh->mNumVertices; v++) { + const aiVector3D &vtx = mesh->mVertices[v]; + const aiVector3D &norm = mesh->mNormals[v]; + const aiVector3D &uv0 = hasUVs ? mesh->mTextureCoords[0][v] : aiVector3D(0.f); + const aiVector3D &tangents = mesh->mTangents[v]; + vtxPtr[v].pos = vector3f(vtx.x, vtx.y, vtx.z); + vtxPtr[v].nrm = vector3f(norm.x, norm.y, norm.z); + vtxPtr[v].uv0 = vector2f(uv0.x, uv0.y); + vtxPtr[v].tangent = vector3f(tangents.x, tangents.y, tangents.z); + + //update bounding box + //untransformed points, collision visitor will transform + geom->m_boundingBox.Update(vtx.x, vtx.y, vtx.z); + } + vb->Unmap(); + } + + geom->AddMesh(vb, ib, mat); + + geoms.push_back(geom); } - assert(mat.Valid()); + } - Graphics::RenderStateDesc rsd; - //turn on alpha blending and mark entire node as transparent - //(all importers split by material so far) - if (mat->diffuse.a < 255) { - geom->SetNodeMask(NODE_TRANSPARENT); - geom->m_blendMode = Graphics::BLEND_ALPHA; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthWrite = false; + void Loader::ConvertAnimations(const aiScene *scene, const AnimList &animDefs, Node *meshRoot) + { + PROFILE_SCOPED() + //Split convert assimp animations according to anim defs + //This is very limited, and all animdefs are processed for all + //meshes, potentially leading to duplicate and wrongly split animations + if (animDefs.empty() || scene->mNumAnimations == 0) return; + if (scene->mNumAnimations > 1) Output("File has %d animations, treating as one animation\n", scene->mNumAnimations); + + std::vector &animations = m_model->m_animations; + + for (AnimList::const_iterator def = animDefs.begin(); + def != animDefs.end(); + ++def) { + //XXX format differences: for a 40-frame animation exported from Blender, + //.X results in duration 39 and Collada in Duration 1.25. + //duration is calculated after adding all keys + //take TPS from the first animation + const aiAnimation *firstAnim = scene->mAnimations[0]; + const double ticksPerSecond = firstAnim->mTicksPerSecond > 0.0 ? firstAnim->mTicksPerSecond : 24.0; + const double secondsPerTick = 1.0 / ticksPerSecond; + + double start = DBL_MAX; + double end = -DBL_MAX; + + //Ranges are specified in frames (since that's nice) but Collada + //uses seconds. This is easiest to detect from ticksPerSecond, + //but assuming 24 FPS here + //Could make FPS an additional define or always require 24 + double defStart = def->start; + double defEnd = def->end; + if (is_equal_exact(ticksPerSecond, 1.0)) { + defStart /= 24.0; + defEnd /= 24.0; + } + + // Add channels to current animation if it's already present + // Necessary to make animations work in multiple LODs + Animation *animation = m_model->FindAnimation(def->name); + const bool newAnim = !animation; + if (newAnim) animation = new Animation(def->name, 0.0); + + const size_t first_new_channel = animation->m_channels.size(); + + for (unsigned int i = 0; i < scene->mNumAnimations; i++) { + const aiAnimation *aianim = scene->mAnimations[i]; + for (unsigned int j = 0; j < aianim->mNumChannels; j++) { + const aiNodeAnim *aichan = aianim->mChannels[j]; + //do a preliminary check that at least two keys in one channel are within range + if (!CheckKeysInRange(aichan, defStart, defEnd)) + continue; + + const std::string channame(aichan->mNodeName.C_Str()); + MatrixTransform *trans = dynamic_cast(meshRoot->FindNode(channame)); + assert(trans); + animation->m_channels.push_back(AnimationChannel(trans)); + AnimationChannel &chan = animation->m_channels.back(); + + for (unsigned int k = 0; k < aichan->mNumPositionKeys; k++) { + const aiVectorKey &aikey = aichan->mPositionKeys[k]; + const aiVector3D &aipos = aikey.mValue; + if (in_range(aikey.mTime, defStart, defEnd)) { + const double t = aikey.mTime * secondsPerTick; + chan.positionKeys.push_back(PositionKey(t, vector3f(aipos.x, aipos.y, aipos.z))); + start = std::min(start, t); + end = std::max(end, t); + } + } + + //scale interpolation will blow up without rotation keys, + //so skipping them when rotkeys < 2 is correct + if (aichan->mNumRotationKeys < 2) continue; + + for (unsigned int k = 0; k < aichan->mNumRotationKeys; k++) { + const aiQuatKey &aikey = aichan->mRotationKeys[k]; + const aiQuaternion &airot = aikey.mValue; + if (in_range(aikey.mTime, defStart, defEnd)) { + const double t = aikey.mTime * secondsPerTick; + chan.rotationKeys.push_back(RotationKey(t, Quaternionf(airot.w, airot.x, airot.y, airot.z))); + start = std::min(start, t); + end = std::max(end, t); + } + } + + for (unsigned int k = 0; k < aichan->mNumScalingKeys; k++) { + const aiVectorKey &aikey = aichan->mScalingKeys[k]; + const aiVector3D &aipos = aikey.mValue; + if (in_range(aikey.mTime, defStart, defEnd)) { + const double t = aikey.mTime * secondsPerTick; + chan.scaleKeys.push_back(ScaleKey(t, vector3f(aipos.x, aipos.y, aipos.z))); + start = std::min(start, t); + end = std::max(end, t); + } + } + } + } + + // convert remove initial offset (so the first keyframe is at exactly t=0) + for (std::vector::iterator chan = animation->m_channels.begin() + first_new_channel; + chan != animation->m_channels.end(); ++chan) { + for (unsigned int k = 0; k < chan->positionKeys.size(); ++k) { + chan->positionKeys[k].time -= start; + assert(chan->positionKeys[k].time >= 0.0); + } + for (unsigned int k = 0; k < chan->rotationKeys.size(); ++k) { + chan->rotationKeys[k].time -= start; + assert(chan->rotationKeys[k].time >= 0.0); + } + for (unsigned int k = 0; k < chan->scaleKeys.size(); ++k) { + chan->scaleKeys[k].time -= start; + assert(chan->scaleKeys[k].time >= 0.0); + } + } + + // set actual duration + const double dur = end - start; + animation->m_duration = newAnim ? dur : std::max(animation->m_duration, dur); + + //do final sanity checking before adding + try { + CheckAnimationConflicts(animation, animations); + } catch (LoadingError &) { + if (newAnim) delete animation; + throw; + } + + if (newAnim) { + if (animation->m_channels.empty()) + delete animation; + else + animations.push_back(animation); + } + } + } + + matrix4x4f Loader::ConvertMatrix(const aiMatrix4x4 &trans) const + { + matrix4x4f m; + m[0] = trans.a1; + m[1] = trans.b1; + m[2] = trans.c1; + m[3] = trans.d1; + + m[4] = trans.a2; + m[5] = trans.b2; + m[6] = trans.c2; + m[7] = trans.d2; + + m[8] = trans.a3; + m[9] = trans.b3; + m[10] = trans.c3; + m[11] = trans.d3; + + m[12] = trans.a4; + m[13] = trans.b4; + m[14] = trans.c4; + m[15] = trans.d4; + return m; + } + + void Loader::CreateLabel(Group *parent, const matrix4x4f &m) + { + PROFILE_SCOPED() + MatrixTransform *trans = new MatrixTransform(m_renderer, m); + Label3D *label = new Label3D(m_renderer, m_labelFont); + label->SetText("Bananas"); + trans->AddChild(label); + parent->AddChild(trans); + } + + void Loader::CreateThruster(const std::string &name, const matrix4x4f &m) + { + PROFILE_SCOPED() + if (!m_mostDetailedLod) return AddLog("Thruster outside highest LOD, ignored"); + + const bool linear = starts_with(name, "thruster_linear"); + + matrix4x4f transform = m; + + MatrixTransform *trans = new MatrixTransform(m_renderer, transform); + + const vector3f pos = transform.GetTranslate(); + transform.ClearToRotOnly(); + + const vector3f direction = transform * vector3f(0.f, 0.f, 1.f); + + Thruster *thruster = new Thruster(m_renderer, linear, + pos, direction.Normalized()); + + thruster->SetName(name); + trans->AddChild(thruster); + + m_thrustersRoot->AddChild(trans); + } + + void Loader::CreateNavlight(const std::string &name, const matrix4x4f &m) + { + PROFILE_SCOPED() + if (!m_mostDetailedLod) return AddLog("Navlight outside highest LOD, ignored"); + + //Create a MT, lights are attached by client + //we only really need the final position, so this is + //a waste of transform + const matrix4x4f lightPos = matrix4x4f::Translation(m.GetTranslate()); + MatrixTransform *lightPoint = new MatrixTransform(m_renderer, lightPos); + lightPoint->SetNodeMask(0x0); //don't render + lightPoint->SetName(name); + + m_billboardsRoot->AddChild(lightPoint); + } + + RefCountedPtr Loader::CreateCollisionGeometry(RefCountedPtr geom, unsigned int collFlag) + { + PROFILE_SCOPED() + //Convert StaticMesh points & indices into cgeom + //note: it's not slow, but the amount of data being copied is just stupid: + //assimp to vtxbuffer, vtxbuffer to vector, vector to cgeom, cgeom to geomtree... + assert(geom->GetNumMeshes() == 1); + StaticGeometry::Mesh mesh = geom->GetMeshAt(0); + + const Uint32 posOffs = mesh.vertexBuffer->GetDesc().GetOffset(Graphics::ATTRIB_POSITION); + const Uint32 stride = mesh.vertexBuffer->GetDesc().stride; + const Uint32 numVtx = mesh.vertexBuffer->GetDesc().numVertices; + const Uint32 numIdx = mesh.indexBuffer->GetSize(); + + //copy vertex positions from buffer + std::vector pos; + pos.reserve(numVtx); + + Uint8 *vtxPtr = mesh.vertexBuffer->Map(Graphics::BUFFER_MAP_READ); + for (Uint32 i = 0; i < numVtx; i++) + pos.push_back(*reinterpret_cast(vtxPtr + (i * stride) + posOffs)); + mesh.vertexBuffer->Unmap(); + + //copy indices from buffer + std::vector idx; + idx.reserve(numIdx); + + Uint32 *idxPtr = mesh.indexBuffer->Map(Graphics::BUFFER_MAP_READ); + for (Uint32 i = 0; i < numIdx; i++) + idx.push_back(idxPtr[i]); + mesh.indexBuffer->Unmap(); + RefCountedPtr cgeom(new CollisionGeometry(m_renderer, pos, idx, collFlag)); + return cgeom; + } + + void Loader::ConvertNodes(aiNode *node, Group *_parent, std::vector> &geoms, const matrix4x4f &accum) + { + PROFILE_SCOPED() + Group *parent = _parent; + const std::string nodename(node->mName.C_Str()); + const aiMatrix4x4 &trans = node->mTransformation; + matrix4x4f m = ConvertMatrix(trans); + + //lights, and possibly other special nodes should be leaf nodes (without meshes) + if (node->mNumChildren == 0 && node->mNumMeshes == 0) { + if (starts_with(nodename, "navlight_")) { + CreateNavlight(nodename, accum * m); + } else if (starts_with(nodename, "thruster_")) { + CreateThruster(nodename, accum * m); + } else if (starts_with(nodename, "label_")) { + CreateLabel(parent, m); + } else if (starts_with(nodename, "tag_")) { + m_model->AddTag(nodename, new MatrixTransform(m_renderer, accum * m)); + } else if (starts_with(nodename, "entrance_")) { + m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); + } else if (starts_with(nodename, "loc_")) { + m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); + } else if (starts_with(nodename, "exit_")) { + m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); + } + return; } - geom->SetRenderState(m_renderer->CreateRenderState(rsd)); + //if the transform is identity and the node is not animated, + //could just add a group + parent = new MatrixTransform(m_renderer, m); + _parent->AddChild(parent); + parent->SetName(nodename); - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[0].offset = hasTangents ? offsetof(ModelTangentVtx, pos) : offsetof(ModelVtx, pos); - vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].offset = hasTangents ? offsetof(ModelTangentVtx, nrm) : offsetof(ModelVtx, nrm); - vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.attrib[2].offset = hasTangents ? offsetof(ModelTangentVtx, uv0) : offsetof(ModelVtx, uv0); - if (hasTangents) { - vbd.attrib[3].semantic = Graphics::ATTRIB_TANGENT; - vbd.attrib[3].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[3].offset = offsetof(ModelTangentVtx, tangent); + //nodes named collision_* are not added as renderable geometry + if (node->mNumMeshes == 1 && starts_with(nodename, "collision_")) { + const unsigned int collflag = GetGeomFlagForNodeName(nodename); + RefCountedPtr cgeom = CreateCollisionGeometry(geoms.at(node->mMeshes[0]), collflag); + cgeom->SetName(nodename + "_cgeom"); + cgeom->SetDynamic(starts_with(nodename, "collision_d")); + parent->AddChild(cgeom.Get()); + return; } - vbd.stride = hasTangents ? sizeof(ModelTangentVtx) : sizeof(ModelVtx); - vbd.numVertices = mesh->mNumVertices; - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - RefCountedPtr vb(m_renderer->CreateVertexBuffer(vbd)); + //nodes with visible geometry (StaticGeometry and decals) + if (node->mNumMeshes > 0) { + //expecting decal_0X + unsigned int numDecal = 0; + if (starts_with(nodename, "decal_")) { + numDecal = atoi(nodename.substr(7, 1).c_str()); + if (numDecal > 4) + throw LoadingError("More than 4 different decals"); + } + + for (unsigned int i = 0; i < node->mNumMeshes; i++) { + RefCountedPtr geom = geoms.at(node->mMeshes[i]); + + //handle special decal material + //set special material for decals + if (numDecal > 0) { + geom->SetNodeMask(NODE_TRANSPARENT); + geom->m_blendMode = Graphics::BLEND_ALPHA; + geom->GetMeshAt(0).material = GetDecalMaterial(numDecal); + geom->SetNodeFlags(geom->GetNodeFlags() | NODE_DECAL); + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthWrite = false; + //XXX add polygon offset to decal state + geom->SetRenderState(m_renderer->CreateRenderState(rsd)); + } + + parent->AddChild(geom.Get()); + } + } + + for (unsigned int i = 0; i < node->mNumChildren; i++) { + aiNode *child = node->mChildren[i]; + ConvertNodes(child, parent, geoms, accum * m); + } + } + + void Loader::LoadCollision(const std::string &filename) + { + PROFILE_SCOPED() + //Convert all found aiMeshes into a geomtree. Materials, + //Animations and node structure can be ignored + assert(m_model); + + Assimp::Importer importer; + importer.SetIOHandler(new AssimpFileSystem(FileSystem::gameDataFiles)); + + //discard extra data + importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, + aiComponent_COLORS | + aiComponent_TEXCOORDS | + aiComponent_NORMALS | + aiComponent_MATERIALS); + const aiScene *scene = importer.ReadFile( + filename, + aiProcess_RemoveComponent | + aiProcess_Triangulate | + aiProcess_PreTransformVertices //"bake" transformations so we can disregard the structure + ); + + if (!scene) + throw LoadingError("Could not load file"); + + if (scene->mNumMeshes == 0) + throw LoadingError("No geometry found"); - // huge meshes are split by the importer so this should not exceed 65K indices std::vector indices; - if (mesh->mNumFaces > 0) - { - indices.reserve(mesh->mNumFaces * 3); + std::vector vertices; + Uint32 indexOffset = 0; + + for (Uint32 i = 0; i < scene->mNumMeshes; i++) { + aiMesh *mesh = scene->mMeshes[i]; + + //copy indices + //we assume aiProcess_Triangulate does its job + assert(mesh->mNumFaces > 0); for (unsigned int f = 0; f < mesh->mNumFaces; f++) { const aiFace *face = &mesh->mFaces[f]; for (unsigned int j = 0; j < face->mNumIndices; j++) { - indices.push_back(face->mIndices[j]); + indices.push_back(indexOffset + face->mIndices[j]); } } - } else { - //generate dummy indices - AddLog(stringf("Missing indices in mesh %0{u}", i)); - indices.reserve(mesh->mNumVertices); - for (unsigned int v = 0; v < mesh->mNumVertices; v++) - indices.push_back(v); - } + indexOffset += mesh->mNumFaces * 3; - assert(indices.size() > 0); - - //create buffer & copy - RefCountedPtr ib(m_renderer->CreateIndexBuffer(indices.size(), Graphics::BUFFER_USAGE_STATIC)); - Uint32* idxPtr = ib->Map(Graphics::BUFFER_MAP_WRITE); - for (Uint32 j = 0; j < indices.size(); j++) - idxPtr[j] = indices[j]; - ib->Unmap(); - - //copy vertices, always assume normals - //replace nonexistent UVs with zeros - if (!hasTangents) - { - ModelVtx *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); + //vertices for (unsigned int v = 0; v < mesh->mNumVertices; v++) { const aiVector3D &vtx = mesh->mVertices[v]; - const aiVector3D &norm = mesh->mNormals[v]; - const aiVector3D &uv0 = hasUVs ? mesh->mTextureCoords[0][v] : aiVector3D(0.f); - vtxPtr[v].pos = vector3f(vtx.x, vtx.y, vtx.z); - vtxPtr[v].nrm = vector3f(norm.x, norm.y, norm.z); - vtxPtr[v].uv0 = vector2f(uv0.x, uv0.y); - - //update bounding box - //untransformed points, collision visitor will transform - geom->m_boundingBox.Update(vtx.x, vtx.y, vtx.z); + vertices.push_back(vector3f(vtx.x, vtx.y, vtx.z)); } - vb->Unmap(); - } - else - { - ModelTangentVtx *vtxPtr = vb->Map(Graphics::BUFFER_MAP_WRITE); - for (unsigned int v = 0; v < mesh->mNumVertices; v++) { - const aiVector3D &vtx = mesh->mVertices[v]; - const aiVector3D &norm = mesh->mNormals[v]; - const aiVector3D &uv0 = hasUVs ? mesh->mTextureCoords[0][v] : aiVector3D(0.f); - const aiVector3D &tangents = mesh->mTangents[v]; - vtxPtr[v].pos = vector3f(vtx.x, vtx.y, vtx.z); - vtxPtr[v].nrm = vector3f(norm.x, norm.y, norm.z); - vtxPtr[v].uv0 = vector2f(uv0.x, uv0.y); - vtxPtr[v].tangent = vector3f(tangents.x, tangents.y, tangents.z); - - //update bounding box - //untransformed points, collision visitor will transform - geom->m_boundingBox.Update(vtx.x, vtx.y, vtx.z); - } - vb->Unmap(); } - geom->AddMesh(vb, ib, mat); + assert(!vertices.empty() && !indices.empty()); - geoms.push_back(geom); + //add pre-transformed geometry at the top level + m_model->GetRoot()->AddChild(new CollisionGeometry(m_renderer, vertices, indices, 0)); } -} -void Loader::ConvertAnimations(const aiScene* scene, const AnimList &animDefs, Node *meshRoot) -{ - PROFILE_SCOPED() - //Split convert assimp animations according to anim defs - //This is very limited, and all animdefs are processed for all - //meshes, potentially leading to duplicate and wrongly split animations - if (animDefs.empty() || scene->mNumAnimations == 0) return; - if (scene->mNumAnimations > 1) Output("File has %d animations, treating as one animation\n", scene->mNumAnimations); - - std::vector &animations = m_model->m_animations; - - for (AnimList::const_iterator def = animDefs.begin(); - def != animDefs.end(); - ++def) + unsigned int Loader::GetGeomFlagForNodeName(const std::string &nodename) { - //XXX format differences: for a 40-frame animation exported from Blender, - //.X results in duration 39 and Collada in Duration 1.25. - //duration is calculated after adding all keys - //take TPS from the first animation - const aiAnimation* firstAnim = scene->mAnimations[0]; - const double ticksPerSecond = firstAnim->mTicksPerSecond > 0.0 ? firstAnim->mTicksPerSecond : 24.0; - const double secondsPerTick = 1.0 / ticksPerSecond; - - double start = DBL_MAX; - double end = -DBL_MAX; - - //Ranges are specified in frames (since that's nice) but Collada - //uses seconds. This is easiest to detect from ticksPerSecond, - //but assuming 24 FPS here - //Could make FPS an additional define or always require 24 - double defStart = def->start; - double defEnd = def->end; - if (is_equal_exact(ticksPerSecond, 1.0)) { - defStart /= 24.0; - defEnd /= 24.0; - } - - // Add channels to current animation if it's already present - // Necessary to make animations work in multiple LODs - Animation *animation = m_model->FindAnimation(def->name); - const bool newAnim = !animation; - if (newAnim) animation = new Animation(def->name, 0.0); - - const size_t first_new_channel = animation->m_channels.size(); - - for (unsigned int i=0; i < scene->mNumAnimations; i++) { - const aiAnimation* aianim = scene->mAnimations[i]; - for (unsigned int j=0; jmNumChannels; j++) { - const aiNodeAnim *aichan = aianim->mChannels[j]; - //do a preliminary check that at least two keys in one channel are within range - if (!CheckKeysInRange(aichan, defStart, defEnd)) - continue; - - const std::string channame(aichan->mNodeName.C_Str()); - MatrixTransform *trans = dynamic_cast(meshRoot->FindNode(channame)); - assert(trans); - animation->m_channels.push_back(AnimationChannel(trans)); - AnimationChannel &chan = animation->m_channels.back(); - - for(unsigned int k=0; kmNumPositionKeys; k++) { - const aiVectorKey &aikey = aichan->mPositionKeys[k]; - const aiVector3D &aipos = aikey.mValue; - if (in_range(aikey.mTime, defStart, defEnd)) { - const double t = aikey.mTime * secondsPerTick; - chan.positionKeys.push_back(PositionKey(t, vector3f(aipos.x, aipos.y, aipos.z))); - start = std::min(start, t); - end = std::max(end, t); - } - } - - //scale interpolation will blow up without rotation keys, - //so skipping them when rotkeys < 2 is correct - if (aichan->mNumRotationKeys < 2) continue; - - for(unsigned int k=0; kmNumRotationKeys; k++) { - const aiQuatKey &aikey = aichan->mRotationKeys[k]; - const aiQuaternion &airot = aikey.mValue; - if (in_range(aikey.mTime, defStart, defEnd)) { - const double t = aikey.mTime * secondsPerTick; - chan.rotationKeys.push_back(RotationKey(t, Quaternionf(airot.w, airot.x, airot.y, airot.z))); - start = std::min(start, t); - end = std::max(end, t); - } - } - - for(unsigned int k=0; kmNumScalingKeys; k++) { - const aiVectorKey &aikey = aichan->mScalingKeys[k]; - const aiVector3D &aipos = aikey.mValue; - if (in_range(aikey.mTime, defStart, defEnd)) { - const double t = aikey.mTime * secondsPerTick; - chan.scaleKeys.push_back(ScaleKey(t, vector3f(aipos.x, aipos.y, aipos.z))); - start = std::min(start, t); - end = std::max(end, t); - } + PROFILE_SCOPED() + //special names after collision_ + if (nodename.length() > 10) { + //landing pads + if (nodename.length() >= 14 && nodename.substr(10, 3) == "pad") { + const std::string pad = nodename.substr(13); + const int padID = atoi(pad.c_str()) - 1; + if (padID < 240) { + return 0x10 + padID; } } } - - // convert remove initial offset (so the first keyframe is at exactly t=0) - for (std::vector::iterator chan = animation->m_channels.begin() + first_new_channel; - chan != animation->m_channels.end(); ++chan) { - for (unsigned int k = 0; k < chan->positionKeys.size(); ++k) { - chan->positionKeys[k].time -= start; - assert(chan->positionKeys[k].time >= 0.0); - } - for (unsigned int k = 0; k < chan->rotationKeys.size(); ++k) { - chan->rotationKeys[k].time -= start; - assert(chan->rotationKeys[k].time >= 0.0); - } - for (unsigned int k = 0; k < chan->scaleKeys.size(); ++k) { - chan->scaleKeys[k].time -= start; - assert(chan->scaleKeys[k].time >= 0.0); - } - } - - // set actual duration - const double dur = end - start; - animation->m_duration = newAnim ? dur : std::max(animation->m_duration, dur); - - //do final sanity checking before adding - try { - CheckAnimationConflicts(animation, animations); - } catch (LoadingError &) { - if (newAnim) delete animation; - throw; - } - - if (newAnim) { - if (animation->m_channels.empty()) - delete animation; - else - animations.push_back(animation); - } - } -} - -matrix4x4f Loader::ConvertMatrix(const aiMatrix4x4& trans) const -{ - matrix4x4f m; - m[0] = trans.a1; - m[1] = trans.b1; - m[2] = trans.c1; - m[3] = trans.d1; - - m[4] = trans.a2; - m[5] = trans.b2; - m[6] = trans.c2; - m[7] = trans.d2; - - m[8] = trans.a3; - m[9] = trans.b3; - m[10] = trans.c3; - m[11] = trans.d3; - - m[12] = trans.a4; - m[13] = trans.b4; - m[14] = trans.c4; - m[15] = trans.d4; - return m; -} - -void Loader::CreateLabel(Group *parent, const matrix4x4f &m) -{ - PROFILE_SCOPED() - MatrixTransform *trans = new MatrixTransform(m_renderer, m); - Label3D *label = new Label3D(m_renderer, m_labelFont); - label->SetText("Bananas"); - trans->AddChild(label); - parent->AddChild(trans); -} - -void Loader::CreateThruster(const std::string &name, const matrix4x4f &m) -{ - PROFILE_SCOPED() - if (!m_mostDetailedLod) return AddLog("Thruster outside highest LOD, ignored"); - - const bool linear = starts_with(name, "thruster_linear"); - - matrix4x4f transform = m; - - MatrixTransform *trans = new MatrixTransform(m_renderer, transform); - - const vector3f pos = transform.GetTranslate(); - transform.ClearToRotOnly(); - - const vector3f direction = transform * vector3f(0.f, 0.f, 1.f); - - Thruster *thruster = new Thruster(m_renderer, linear, - pos, direction.Normalized()); - - thruster->SetName(name); - trans->AddChild(thruster); - - m_thrustersRoot->AddChild(trans); -} - -void Loader::CreateNavlight(const std::string &name, const matrix4x4f &m) -{ - PROFILE_SCOPED() - if (!m_mostDetailedLod) return AddLog("Navlight outside highest LOD, ignored"); - - //Create a MT, lights are attached by client - //we only really need the final position, so this is - //a waste of transform - const matrix4x4f lightPos = matrix4x4f::Translation(m.GetTranslate()); - MatrixTransform *lightPoint = new MatrixTransform(m_renderer, lightPos); - lightPoint->SetNodeMask(0x0); //don't render - lightPoint->SetName(name); - - m_billboardsRoot->AddChild(lightPoint); -} - -RefCountedPtr Loader::CreateCollisionGeometry(RefCountedPtr geom, unsigned int collFlag) -{ - PROFILE_SCOPED() - //Convert StaticMesh points & indices into cgeom - //note: it's not slow, but the amount of data being copied is just stupid: - //assimp to vtxbuffer, vtxbuffer to vector, vector to cgeom, cgeom to geomtree... - assert(geom->GetNumMeshes() == 1); - StaticGeometry::Mesh mesh = geom->GetMeshAt(0); - - const Uint32 posOffs = mesh.vertexBuffer->GetDesc().GetOffset(Graphics::ATTRIB_POSITION); - const Uint32 stride = mesh.vertexBuffer->GetDesc().stride; - const Uint32 numVtx = mesh.vertexBuffer->GetDesc().numVertices; - const Uint32 numIdx = mesh.indexBuffer->GetSize(); - - //copy vertex positions from buffer - std::vector pos; - pos.reserve(numVtx); - - Uint8 *vtxPtr = mesh.vertexBuffer->Map(Graphics::BUFFER_MAP_READ); - for (Uint32 i = 0; i < numVtx; i++) - pos.push_back(*reinterpret_cast(vtxPtr + (i * stride) + posOffs)); - mesh.vertexBuffer->Unmap(); - - //copy indices from buffer - std::vector idx; - idx.reserve(numIdx); - - Uint32 *idxPtr = mesh.indexBuffer->Map(Graphics::BUFFER_MAP_READ); - for (Uint32 i = 0; i < numIdx; i++) - idx.push_back(idxPtr[i]); - mesh.indexBuffer->Unmap(); - RefCountedPtr cgeom(new CollisionGeometry(m_renderer, pos, idx, collFlag)); - return cgeom; -} - -void Loader::ConvertNodes(aiNode *node, Group *_parent, std::vector >& geoms, const matrix4x4f &accum) -{ - PROFILE_SCOPED() - Group *parent = _parent; - const std::string nodename(node->mName.C_Str()); - const aiMatrix4x4& trans = node->mTransformation; - matrix4x4f m = ConvertMatrix(trans); - - //lights, and possibly other special nodes should be leaf nodes (without meshes) - if (node->mNumChildren == 0 && node->mNumMeshes == 0) { - if (starts_with(nodename, "navlight_")) { - CreateNavlight(nodename, accum*m); - } else if (starts_with(nodename, "thruster_")) { - CreateThruster(nodename, accum*m); - } else if (starts_with(nodename, "label_")) { - CreateLabel(parent, m); - } else if (starts_with(nodename, "tag_")) { - m_model->AddTag(nodename, new MatrixTransform(m_renderer, accum*m)); - } else if (starts_with(nodename, "entrance_")) { - m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); - } else if (starts_with(nodename, "loc_")) { - m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); - } else if (starts_with(nodename, "exit_")) { - m_model->AddTag(nodename, new MatrixTransform(m_renderer, m)); - } - return; + //anything else is static collision + return 0x0; } - //if the transform is identity and the node is not animated, - //could just add a group - parent = new MatrixTransform(m_renderer, m); - _parent->AddChild(parent); - parent->SetName(nodename); - - //nodes named collision_* are not added as renderable geometry - if (node->mNumMeshes == 1 && starts_with(nodename, "collision_")) { - const unsigned int collflag = GetGeomFlagForNodeName(nodename); - RefCountedPtr cgeom = CreateCollisionGeometry(geoms.at(node->mMeshes[0]), collflag); - cgeom->SetName(nodename + "_cgeom"); - cgeom->SetDynamic(starts_with(nodename, "collision_d")); - parent->AddChild(cgeom.Get()); - return; - } - - //nodes with visible geometry (StaticGeometry and decals) - if (node->mNumMeshes > 0) { - //expecting decal_0X - unsigned int numDecal = 0; - if (starts_with(nodename, "decal_")) { - numDecal = atoi(nodename.substr(7,1).c_str()); - if (numDecal > 4) - throw LoadingError("More than 4 different decals"); - } - - for(unsigned int i=0; imNumMeshes; i++) { - RefCountedPtr geom = geoms.at(node->mMeshes[i]); - - //handle special decal material - //set special material for decals - if (numDecal > 0) { - geom->SetNodeMask(NODE_TRANSPARENT); - geom->m_blendMode = Graphics::BLEND_ALPHA; - geom->GetMeshAt(0).material = GetDecalMaterial(numDecal); - geom->SetNodeFlags(geom->GetNodeFlags() | NODE_DECAL); - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthWrite = false; - //XXX add polygon offset to decal state - geom->SetRenderState(m_renderer->CreateRenderState(rsd)); - } - - parent->AddChild(geom.Get()); - } - } - - for(unsigned int i=0; imNumChildren; i++) { - aiNode *child = node->mChildren[i]; - ConvertNodes(child, parent, geoms, accum * m); - } -} - -void Loader::LoadCollision(const std::string &filename) -{ - PROFILE_SCOPED() - //Convert all found aiMeshes into a geomtree. Materials, - //Animations and node structure can be ignored - assert(m_model); - - Assimp::Importer importer; - importer.SetIOHandler(new AssimpFileSystem(FileSystem::gameDataFiles)); - - //discard extra data - importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, - aiComponent_COLORS | - aiComponent_TEXCOORDS | - aiComponent_NORMALS | - aiComponent_MATERIALS - ); - const aiScene *scene = importer.ReadFile( - filename, - aiProcess_RemoveComponent | - aiProcess_Triangulate | - aiProcess_PreTransformVertices //"bake" transformations so we can disregard the structure - ); - - if(!scene) - throw LoadingError("Could not load file"); - - if(scene->mNumMeshes == 0) - throw LoadingError("No geometry found"); - - std::vector indices; - std::vector vertices; - Uint32 indexOffset = 0; - - for(Uint32 i=0; imNumMeshes; i++) { - aiMesh* mesh = scene->mMeshes[i]; - - //copy indices - //we assume aiProcess_Triangulate does its job - assert(mesh->mNumFaces > 0); - for (unsigned int f = 0; f < mesh->mNumFaces; f++) { - const aiFace *face = &mesh->mFaces[f]; - for (unsigned int j = 0; j < face->mNumIndices; j++) { - indices.push_back(indexOffset + face->mIndices[j]); - } - } - indexOffset += mesh->mNumFaces*3; - - //vertices - for (unsigned int v = 0; v < mesh->mNumVertices; v++) { - const aiVector3D &vtx = mesh->mVertices[v]; - vertices.push_back(vector3f(vtx.x, vtx.y, vtx.z)); - } - } - - assert(!vertices.empty() && !indices.empty()); - - //add pre-transformed geometry at the top level - m_model->GetRoot()->AddChild(new CollisionGeometry(m_renderer, vertices, indices, 0)); -} - -unsigned int Loader::GetGeomFlagForNodeName(const std::string &nodename) -{ - PROFILE_SCOPED() - //special names after collision_ - if (nodename.length() > 10) { - //landing pads - if (nodename.length() >= 14 && nodename.substr(10,3) == "pad") { - const std::string pad = nodename.substr(13); - const int padID = atoi(pad.c_str())-1; - if(padID<240) { - return 0x10 + padID; - } - } - } - //anything else is static collision - return 0x0; -} - -} //namespace +} // namespace SceneGraph diff --git a/src/scenegraph/Loader.h b/src/scenegraph/Loader.h index 5c707dd1c..fa982cb88 100644 --- a/src/scenegraph/Loader.h +++ b/src/scenegraph/Loader.h @@ -12,14 +12,14 @@ // Disable some GCC diagnostics errors. #ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" - #pragma GCC diagnostic ignored "-Wshadow" - #pragma GCC diagnostic ignored "-Wold-style-cast" - #include - #pragma GCC diagnostic pop +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include +#pragma GCC diagnostic pop #else - #include +#include #endif struct aiNode; @@ -29,43 +29,43 @@ struct aiNodeAnim; namespace SceneGraph { -class Loader : public BaseLoader { -public: - Loader(Graphics::Renderer *r, bool logWarnings = false, bool loadSGMfiles = true); + class Loader : public BaseLoader { + public: + Loader(Graphics::Renderer *r, bool logWarnings = false, bool loadSGMfiles = true); - //find & attempt to load a model, based on filename (without path or .model suffix) - Model *LoadModel(const std::string &name); - Model *LoadModel(const std::string &name, const std::string &basepath); + //find & attempt to load a model, based on filename (without path or .model suffix) + Model *LoadModel(const std::string &name); + Model *LoadModel(const std::string &name, const std::string &basepath); - const std::vector &GetLogMessages() const { return m_logMessages; } + const std::vector &GetLogMessages() const { return m_logMessages; } -protected: - bool m_doLog; - bool m_loadSGMs; - bool m_mostDetailedLod; - std::vector m_logMessages; - std::string m_curMeshDef; //for logging + protected: + bool m_doLog; + bool m_loadSGMs; + bool m_mostDetailedLod; + std::vector m_logMessages; + std::string m_curMeshDef; //for logging - RefCountedPtr m_thrustersRoot; - RefCountedPtr m_billboardsRoot; + RefCountedPtr m_thrustersRoot; + RefCountedPtr m_billboardsRoot; - bool CheckKeysInRange(const aiNodeAnim *, double start, double end); - matrix4x4f ConvertMatrix(const aiMatrix4x4&) const; - Model *CreateModel(ModelDefinition &def); - RefCountedPtr LoadMesh(const std::string &filename, const AnimList &animDefs); //load one mesh file so it can be added to the model scenegraph. Materials should be created before this! - void AddLog(const std::string&); - void CheckAnimationConflicts(const Animation*, const std::vector&); //detect animation overlap - void ConvertAiMeshes(std::vector >&, const aiScene*); //model is only for material lookup - void ConvertAnimations(const aiScene *, const AnimList &, Node *meshRoot); - void ConvertNodes(aiNode *node, Group *parent, std::vector >& meshes, const matrix4x4f&); - void CreateLabel(Group *parent, const matrix4x4f&); - void CreateThruster(const std::string &name, const matrix4x4f& nodeTrans); - void CreateNavlight(const std::string &name, const matrix4x4f& nodeTrans); - RefCountedPtr CreateCollisionGeometry(RefCountedPtr, unsigned int collFlag); - void LoadCollision(const std::string &filename); + bool CheckKeysInRange(const aiNodeAnim *, double start, double end); + matrix4x4f ConvertMatrix(const aiMatrix4x4 &) const; + Model *CreateModel(ModelDefinition &def); + RefCountedPtr LoadMesh(const std::string &filename, const AnimList &animDefs); //load one mesh file so it can be added to the model scenegraph. Materials should be created before this! + void AddLog(const std::string &); + void CheckAnimationConflicts(const Animation *, const std::vector &); //detect animation overlap + void ConvertAiMeshes(std::vector> &, const aiScene *); //model is only for material lookup + void ConvertAnimations(const aiScene *, const AnimList &, Node *meshRoot); + void ConvertNodes(aiNode *node, Group *parent, std::vector> &meshes, const matrix4x4f &); + void CreateLabel(Group *parent, const matrix4x4f &); + void CreateThruster(const std::string &name, const matrix4x4f &nodeTrans); + void CreateNavlight(const std::string &name, const matrix4x4f &nodeTrans); + RefCountedPtr CreateCollisionGeometry(RefCountedPtr, unsigned int collFlag); + void LoadCollision(const std::string &filename); - unsigned int GetGeomFlagForNodeName(const std::string&); -}; + unsigned int GetGeomFlagForNodeName(const std::string &); + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/LoaderDefinitions.h b/src/scenegraph/LoaderDefinitions.h index 122a78dd5..e88570e17 100644 --- a/src/scenegraph/LoaderDefinitions.h +++ b/src/scenegraph/LoaderDefinitions.h @@ -9,70 +9,71 @@ #include "libs.h" namespace SceneGraph { -struct MaterialDefinition { - MaterialDefinition(const std::string &n) : - name(n), - tex_diff(""), - tex_spec(""), - tex_glow(""), - tex_ambi(""), - tex_norm(""), - diffuse(Color::WHITE), - specular(Color::WHITE), - ambient(Color::BLANK), - emissive(Color::BLANK), - shininess(100), - opacity(100), - alpha_test(false), - unlit(false), - use_pattern(false) - { } - std::string name; - std::string tex_diff; - std::string tex_spec; - std::string tex_glow; - std::string tex_ambi; - std::string tex_norm; - Color diffuse; - Color specular; - Color ambient; - Color emissive; - unsigned int shininess; //specular power, 0-128 - unsigned int opacity; //0-100 - bool alpha_test; - bool unlit; - bool use_pattern; -}; + struct MaterialDefinition { + MaterialDefinition(const std::string &n) : + name(n), + tex_diff(""), + tex_spec(""), + tex_glow(""), + tex_ambi(""), + tex_norm(""), + diffuse(Color::WHITE), + specular(Color::WHITE), + ambient(Color::BLANK), + emissive(Color::BLANK), + shininess(100), + opacity(100), + alpha_test(false), + unlit(false), + use_pattern(false) + {} + std::string name; + std::string tex_diff; + std::string tex_spec; + std::string tex_glow; + std::string tex_ambi; + std::string tex_norm; + Color diffuse; + Color specular; + Color ambient; + Color emissive; + unsigned int shininess; //specular power, 0-128 + unsigned int opacity; //0-100 + bool alpha_test; + bool unlit; + bool use_pattern; + }; -struct LodDefinition { - LodDefinition(float size) : pixelSize(size) - { } - float pixelSize; - std::vector meshNames; -}; + struct LodDefinition { + LodDefinition(float size) : + pixelSize(size) + {} + float pixelSize; + std::vector meshNames; + }; -struct AnimDefinition { - AnimDefinition(const std::string &name_, double start_, double end_, bool loop_) : - name(name_), - start(start_), - end(end_), - loop(loop_) - { } - std::string name; - double start; - double end; - bool loop; -}; -typedef std::vector AnimList; + struct AnimDefinition { + AnimDefinition(const std::string &name_, double start_, double end_, bool loop_) : + name(name_), + start(start_), + end(end_), + loop(loop_) + {} + std::string name; + double start; + double end; + bool loop; + }; + typedef std::vector AnimList; -struct ModelDefinition { - std::string name; - std::vector lodDefs; - std::vector matDefs; - std::vector collisionDefs; - AnimList animDefs; -}; + struct ModelDefinition { + std::string name; + std::vector lodDefs; + std::vector matDefs; + std::vector collisionDefs; + AnimList animDefs; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Lua.cpp b/src/scenegraph/Lua.cpp index e85d33f99..4514c1cc9 100644 --- a/src/scenegraph/Lua.cpp +++ b/src/scenegraph/Lua.cpp @@ -7,14 +7,13 @@ #include "ModelSkin.h" namespace SceneGraph { -namespace Lua { + namespace Lua { -void Init() -{ - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); -} - -} -} + void Init() + { + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + } + } // namespace Lua +} // namespace SceneGraph diff --git a/src/scenegraph/Lua.h b/src/scenegraph/Lua.h index e976b4fd3..8418e9c53 100644 --- a/src/scenegraph/Lua.h +++ b/src/scenegraph/Lua.h @@ -5,11 +5,10 @@ #define SCENEGRAPH_LUA_H namespace SceneGraph { -namespace Lua { + namespace Lua { - void Init(); - -} -} + void Init(); + } +} // namespace SceneGraph #endif diff --git a/src/scenegraph/LuaModel.cpp b/src/scenegraph/LuaModel.cpp index b3d3f204c..c18bb73ce 100644 --- a/src/scenegraph/LuaModel.cpp +++ b/src/scenegraph/LuaModel.cpp @@ -1,102 +1,107 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Model.h" -#include "LuaObject.h" #include "LuaConstants.h" +#include "LuaObject.h" +#include "Model.h" namespace SceneGraph { -class LuaModel { -public: - - static int l_attr_name(lua_State *l) { - SceneGraph::Model *model = LuaObject::CheckFromLua(1); - const std::string &name = model->GetName(); - lua_pushlstring(l, name.c_str(), name.size()); - return 1; - } - - static int l_set_pattern(lua_State *l) { - SceneGraph::Model *model = LuaObject::CheckFromLua(1); - if (!model->SupportsPatterns()) - return luaL_error(l, "model '%s' does not support patterns", model->GetName().c_str()); - unsigned int pattern = luaL_checkinteger(l, 2); - pattern--; // Lua counts from 1 - if (pattern >= model->GetNumPatterns()) - return luaL_error(l, "invalid pattern number '%d'; model '%s' has patterns 1-%d", pattern+1, model->GetName().c_str(), model->GetNumPatterns()); - model->SetPattern(pattern); - return 0; - } - - static int l_attr_pattern(lua_State *l) { - SceneGraph::Model *model = LuaObject::CheckFromLua(1); - if (!model->SupportsPatterns()) - return 0; - lua_pushinteger(l, model->GetPattern()+1); // Lua counts from 1 - return 1; - } - - static int l_attr_num_patterns(lua_State *l) { - SceneGraph::Model *model = LuaObject::CheckFromLua(1); - if (!model->SupportsPatterns()) - lua_pushinteger(l, 0); - else - lua_pushinteger(l, model->GetNumPatterns()); - return 1; - } - - static inline Uint32 _unpack_flags(lua_State *l, int idx, const char *constants) { - int table = lua_absindex(l, idx); - - if (!lua_istable(l, table)) - return 0; - - LUA_DEBUG_START(l); - - Uint32 flags = 0; - - lua_pushnil(l); - while (lua_next(l, table)) { - flags |= static_cast(LuaConstants::GetConstantFromArg(l, constants, -1)); - lua_pop(l, 1); + class LuaModel { + public: + static int l_attr_name(lua_State *l) + { + SceneGraph::Model *model = LuaObject::CheckFromLua(1); + const std::string &name = model->GetName(); + lua_pushlstring(l, name.c_str(), name.size()); + return 1; } - LUA_DEBUG_END(l, 0); + static int l_set_pattern(lua_State *l) + { + SceneGraph::Model *model = LuaObject::CheckFromLua(1); + if (!model->SupportsPatterns()) + return luaL_error(l, "model '%s' does not support patterns", model->GetName().c_str()); + unsigned int pattern = luaL_checkinteger(l, 2); + pattern--; // Lua counts from 1 + if (pattern >= model->GetNumPatterns()) + return luaL_error(l, "invalid pattern number '%d'; model '%s' has patterns 1-%d", pattern + 1, model->GetName().c_str(), model->GetNumPatterns()); + model->SetPattern(pattern); + return 0; + } - return flags; - } + static int l_attr_pattern(lua_State *l) + { + SceneGraph::Model *model = LuaObject::CheckFromLua(1); + if (!model->SupportsPatterns()) + return 0; + lua_pushinteger(l, model->GetPattern() + 1); // Lua counts from 1 + return 1; + } - static int l_set_debug_flags(lua_State *l) { - SceneGraph::Model *model = LuaObject::CheckFromLua(1); - Uint32 debugFlags = _unpack_flags(l, 2, "ModelDebugFlags"); - model->SetDebugFlags(debugFlags); - return 0; - } + static int l_attr_num_patterns(lua_State *l) + { + SceneGraph::Model *model = LuaObject::CheckFromLua(1); + if (!model->SupportsPatterns()) + lua_pushinteger(l, 0); + else + lua_pushinteger(l, model->GetNumPatterns()); + return 1; + } -}; + static inline Uint32 _unpack_flags(lua_State *l, int idx, const char *constants) + { + int table = lua_absindex(l, idx); -} + if (!lua_istable(l, table)) + return 0; + + LUA_DEBUG_START(l); + + Uint32 flags = 0; + + lua_pushnil(l); + while (lua_next(l, table)) { + flags |= static_cast(LuaConstants::GetConstantFromArg(l, constants, -1)); + lua_pop(l, 1); + } + + LUA_DEBUG_END(l, 0); + + return flags; + } + + static int l_set_debug_flags(lua_State *l) + { + SceneGraph::Model *model = LuaObject::CheckFromLua(1); + Uint32 debugFlags = _unpack_flags(l, 2, "ModelDebugFlags"); + model->SetDebugFlags(debugFlags); + return 0; + } + }; + +} // namespace SceneGraph using namespace SceneGraph; -template <> const char *LuaObject::s_type = "SceneGraph.Model"; +template <> +const char *LuaObject::s_type = "SceneGraph.Model"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { - { "SetPattern", LuaModel::l_set_pattern }, + { "SetPattern", LuaModel::l_set_pattern }, { "SetDebugFlags", LuaModel::l_set_debug_flags }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "name", LuaModel::l_attr_name }, - { "pattern", LuaModel::l_attr_pattern }, + { "name", LuaModel::l_attr_name }, + { "pattern", LuaModel::l_attr_pattern }, { "numPatterns", LuaModel::l_attr_num_patterns }, { 0, 0 } }; LuaObjectBase::CreateClass(s_type, 0, l_methods, l_attrs, 0); } - diff --git a/src/scenegraph/LuaModelSkin.cpp b/src/scenegraph/LuaModelSkin.cpp index 677374035..18d0da741 100644 --- a/src/scenegraph/LuaModelSkin.cpp +++ b/src/scenegraph/LuaModelSkin.cpp @@ -1,103 +1,101 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "ModelSkin.h" #include "LuaObject.h" +#include "ModelSkin.h" namespace SceneGraph { -class LuaModelSkin { -public: + class LuaModelSkin { + public: + static int l_new(lua_State *l) + { + ModelSkin skin; + LuaObject::PushToLua(skin); + return 1; + } - static int l_new(lua_State *l) - { - ModelSkin skin; - LuaObject::PushToLua(skin); - return 1; - } + static int l_set_colors(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); - static int l_set_colors(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); + luaL_checktype(l, 2, LUA_TTABLE); - luaL_checktype(l, 2, LUA_TTABLE); + lua_getfield(l, 2, "primary"); + if (lua_istable(l, -1)) + skin->SetPrimaryColor(Color(Color4f::FromLuaTable(l, -1))); - lua_getfield(l, 2, "primary"); - if (lua_istable(l, -1)) - skin->SetPrimaryColor(Color(Color4f::FromLuaTable(l, -1))); + lua_getfield(l, 2, "secondary"); + if (lua_istable(l, -1)) + skin->SetSecondaryColor(Color(Color4f::FromLuaTable(l, -1))); - lua_getfield(l, 2, "secondary"); - if (lua_istable(l, -1)) - skin->SetSecondaryColor(Color(Color4f::FromLuaTable(l, -1))); + lua_getfield(l, 2, "trim"); + if (lua_istable(l, -1)) + skin->SetTrimColor(Color(Color4f::FromLuaTable(l, -1))); - lua_getfield(l, 2, "trim"); - if (lua_istable(l, -1)) - skin->SetTrimColor(Color(Color4f::FromLuaTable(l, -1))); + lua_pop(l, 3); - lua_pop(l, 3); + lua_pushvalue(l, 1); + return 1; + } - lua_pushvalue(l, 1); - return 1; - } + static int l_set_random_colors(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); + Random *rand = LuaObject::CheckFromLua(2); + skin->SetRandomColors(*rand); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_random_colors(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); - Random *rand = LuaObject::CheckFromLua(2); - skin->SetRandomColors(*rand); - lua_pushvalue(l, 1); - return 1; - } + static int l_set_decal(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); + const char *name = luaL_checkstring(l, 2); + unsigned int index = 0; + if (lua_gettop(l) > 2) + index = luaL_checkinteger(l, 3); + skin->SetDecal(name, index); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_decal(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); - const char *name = luaL_checkstring(l, 2); - unsigned int index = 0; - if (lua_gettop(l) > 2) - index = luaL_checkinteger(l, 3); - skin->SetDecal(name, index); - lua_pushvalue(l, 1); - return 1; - } + static int l_clear_decal(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); + unsigned int index = 0; + if (lua_gettop(l) > 1) + index = luaL_checkinteger(l, 3); + skin->ClearDecal(index); + lua_pushvalue(l, 1); + return 1; + } - static int l_clear_decal(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); - unsigned int index = 0; - if (lua_gettop(l) > 1) - index = luaL_checkinteger(l, 3); - skin->ClearDecal(index); - lua_pushvalue(l, 1); - return 1; - } + static int l_clear_decals(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); + skin->ClearDecals(); + lua_pushvalue(l, 1); + return 1; + } - static int l_clear_decals(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); - skin->ClearDecals(); - lua_pushvalue(l, 1); - return 1; - } + static int l_set_label(lua_State *l) + { + ModelSkin *skin = LuaObject::CheckFromLua(1); + const char *label = luaL_checkstring(l, 2); + skin->SetLabel(label); + lua_pushvalue(l, 1); + return 1; + } + }; - static int l_set_label(lua_State *l) - { - ModelSkin *skin = LuaObject::CheckFromLua(1); - const char *label = luaL_checkstring(l, 2); - skin->SetLabel(label); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace SceneGraph static std::string _modelskin_serializer(LuaWrappable *o) { static char buf[256]; - SceneGraph::ModelSkin *skin = static_cast(o); + SceneGraph::ModelSkin *skin = static_cast(o); Serializer::Writer wr; skin->Save(wr); @@ -111,9 +109,9 @@ static bool _modelskin_deserializer(const char *pos, const char **next) { const char *end; - Uint32 serlen = strtoul(pos, const_cast(&end), 0); + Uint32 serlen = strtoul(pos, const_cast(&end), 0); if (pos == end) return false; - pos = end+1; // skip newline + pos = end + 1; // skip newline std::string buf(pos, serlen); const char *bufp = buf.c_str(); @@ -130,7 +128,7 @@ static bool _modelskin_deserializer(const char *pos, const char **next) static void _modelskin_to_json(Json &out, LuaWrappable *o) { - SceneGraph::ModelSkin *skin = static_cast(o); + SceneGraph::ModelSkin *skin = static_cast(o); skin->SaveToJson(out); } @@ -144,23 +142,23 @@ static bool _modelskin_from_json(const Json &obj) using namespace SceneGraph; -template <> const char *LuaObject::s_type = "SceneGraph.ModelSkin"; +template <> +const char *LuaObject::s_type = "SceneGraph.ModelSkin"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { - { "New", LuaModelSkin::l_new }, - { "SetColors", LuaModelSkin::l_set_colors }, + { "New", LuaModelSkin::l_new }, + { "SetColors", LuaModelSkin::l_set_colors }, { "SetRandomColors", LuaModelSkin::l_set_random_colors }, - { "SetDecal", LuaModelSkin::l_set_decal }, - { "ClearDecal", LuaModelSkin::l_clear_decal }, - { "ClearDecals", LuaModelSkin::l_clear_decals }, - { "SetLabel", LuaModelSkin::l_set_label }, + { "SetDecal", LuaModelSkin::l_set_decal }, + { "ClearDecal", LuaModelSkin::l_clear_decal }, + { "ClearDecals", LuaModelSkin::l_clear_decals }, + { "SetLabel", LuaModelSkin::l_set_label }, { 0, 0 } }; LuaObjectBase::CreateClass(s_type, 0, l_methods, 0, 0); - LuaObjectBase::RegisterSerializer(s_type, SerializerPair( - _modelskin_serializer, _modelskin_deserializer, _modelskin_to_json, _modelskin_from_json)); + LuaObjectBase::RegisterSerializer(s_type, SerializerPair(_modelskin_serializer, _modelskin_deserializer, _modelskin_to_json, _modelskin_from_json)); } - diff --git a/src/scenegraph/MatrixTransform.cpp b/src/scenegraph/MatrixTransform.cpp index 78a39e820..01a88944b 100644 --- a/src/scenegraph/MatrixTransform.cpp +++ b/src/scenegraph/MatrixTransform.cpp @@ -2,74 +2,74 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "MatrixTransform.h" -#include "NodeVisitor.h" -#include "NodeCopyCache.h" #include "BaseLoader.h" +#include "NodeCopyCache.h" +#include "NodeVisitor.h" #include "graphics/Renderer.h" namespace SceneGraph { -MatrixTransform::MatrixTransform(Graphics::Renderer *r, const matrix4x4f &m) -: Group(r) -, m_transform(m) -{ -} + MatrixTransform::MatrixTransform(Graphics::Renderer *r, const matrix4x4f &m) : + Group(r), + m_transform(m) + { + } -MatrixTransform::MatrixTransform(const MatrixTransform &mt, NodeCopyCache *cache) -: Group(mt, cache) -, m_transform(mt.m_transform) -{ -} + MatrixTransform::MatrixTransform(const MatrixTransform &mt, NodeCopyCache *cache) : + Group(mt, cache), + m_transform(mt.m_transform) + { + } -Node* MatrixTransform::Clone(NodeCopyCache *cache) -{ - return cache->Copy(this); -} + Node *MatrixTransform::Clone(NodeCopyCache *cache) + { + return cache->Copy(this); + } -void MatrixTransform::Accept(NodeVisitor &nv) -{ - nv.ApplyMatrixTransform(*this); -} + void MatrixTransform::Accept(NodeVisitor &nv) + { + nv.ApplyMatrixTransform(*this); + } -void MatrixTransform::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED(); - const matrix4x4f t = trans * m_transform; - RenderChildren(t, rd); -} - -static const matrix4x4f s_ident(matrix4x4f::Identity()); -void MatrixTransform::Render(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED(); - if(0==memcmp(&m_transform, &s_ident, sizeof(matrix4x4f))) { - // m_transform is identity so avoid performing all multiplications - RenderChildren(trans, rd); - } else { - // m_transform is valid, modify all positions by it - const size_t transSize = trans.size(); - std::vector t; - t.resize(transSize); - for (size_t tIdx = 0; tIdx < transSize; tIdx++) { - t[tIdx] = trans[tIdx] * m_transform; - } + void MatrixTransform::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED(); + const matrix4x4f t = trans * m_transform; RenderChildren(t, rd); } -} -void MatrixTransform::Save(NodeDatabase &db) -{ - Group::Save(db); - for (Uint32 i = 0; i < 16; i++) - db.wr->Float(m_transform[i]); -} + static const matrix4x4f s_ident(matrix4x4f::Identity()); + void MatrixTransform::Render(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED(); + if (0 == memcmp(&m_transform, &s_ident, sizeof(matrix4x4f))) { + // m_transform is identity so avoid performing all multiplications + RenderChildren(trans, rd); + } else { + // m_transform is valid, modify all positions by it + const size_t transSize = trans.size(); + std::vector t; + t.resize(transSize); + for (size_t tIdx = 0; tIdx < transSize; tIdx++) { + t[tIdx] = trans[tIdx] * m_transform; + } + RenderChildren(t, rd); + } + } -MatrixTransform *MatrixTransform::Load(NodeDatabase &db) -{ - matrix4x4f matrix; - for (Uint32 i = 0; i < 16; i++) - matrix[i] = db.rd->Float(); - MatrixTransform *mt = new MatrixTransform(db.loader->GetRenderer(), matrix); - return mt; -} + void MatrixTransform::Save(NodeDatabase &db) + { + Group::Save(db); + for (Uint32 i = 0; i < 16; i++) + db.wr->Float(m_transform[i]); + } -} + MatrixTransform *MatrixTransform::Load(NodeDatabase &db) + { + matrix4x4f matrix; + for (Uint32 i = 0; i < 16; i++) + matrix[i] = db.rd->Float(); + MatrixTransform *mt = new MatrixTransform(db.loader->GetRenderer(), matrix); + return mt; + } + +} // namespace SceneGraph diff --git a/src/scenegraph/MatrixTransform.h b/src/scenegraph/MatrixTransform.h index 0af67f2cb..ed0230d7e 100644 --- a/src/scenegraph/MatrixTransform.h +++ b/src/scenegraph/MatrixTransform.h @@ -8,32 +8,34 @@ */ #include "Group.h" #include "matrix4x4.h" -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} namespace SceneGraph { -class MatrixTransform : public Group { -public: - MatrixTransform(Graphics::Renderer *r, const matrix4x4f &m); - MatrixTransform(const MatrixTransform&, NodeCopyCache *cache = 0); + class MatrixTransform : public Group { + public: + MatrixTransform(Graphics::Renderer *r, const matrix4x4f &m); + MatrixTransform(const MatrixTransform &, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0) override; - virtual const char *GetTypeName() const override { return "MatrixTransform"; } - virtual void Accept(NodeVisitor &v) override; + virtual Node *Clone(NodeCopyCache *cache = 0) override; + virtual const char *GetTypeName() const override { return "MatrixTransform"; } + virtual void Accept(NodeVisitor &v) override; - virtual void Save(NodeDatabase&) override; - static MatrixTransform *Load(NodeDatabase&); + virtual void Save(NodeDatabase &) override; + static MatrixTransform *Load(NodeDatabase &); - virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; - virtual void Render(const std::vector &trans, const RenderData *rd) override; + virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; + virtual void Render(const std::vector &trans, const RenderData *rd) override; - const matrix4x4f &GetTransform() const { return m_transform; } - void SetTransform(const matrix4x4f &m) { m_transform = m; } + const matrix4x4f &GetTransform() const { return m_transform; } + void SetTransform(const matrix4x4f &m) { m_transform = m; } -protected: - virtual ~MatrixTransform() { } + protected: + virtual ~MatrixTransform() {} -private: - matrix4x4f m_transform; -}; -} + private: + matrix4x4f m_transform; + }; +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Model.cpp b/src/scenegraph/Model.cpp index 0714254ef..0468c8bdb 100644 --- a/src/scenegraph/Model.cpp +++ b/src/scenegraph/Model.cpp @@ -3,662 +3,663 @@ #include "Model.h" #include "CollisionVisitor.h" +#include "FindNodeVisitor.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "NodeCopyCache.h" +#include "StringF.h" +#include "Thruster.h" #include "graphics/Renderer.h" #include "graphics/TextureBuilder.h" #include "graphics/VertexArray.h" -#include "StringF.h" -#include "JsonUtils.h" -#include "FindNodeVisitor.h" -#include "Thruster.h" #include "utils.h" -#include "GameSaveError.h" namespace SceneGraph { -class LabelUpdateVisitor : public NodeVisitor { -public: - virtual void ApplyLabel(Label3D &l) { - l.SetText(label); - } - - std::string label; -}; - -Model::Model(Graphics::Renderer *r, const std::string &name) -: m_boundingRadius(10.f) -, m_renderer(r) -, m_name(name) -, m_curPatternIndex(0) -, m_curPattern(0) -, m_debugFlags(0) -{ - m_root.Reset(new Group(m_renderer)); - m_root->SetName(name); - ClearDecals(); -} - -Model::Model(const Model &model) -: m_boundingRadius(model.m_boundingRadius) -, m_materials(model.m_materials) -, m_patterns(model.m_patterns) -, m_collMesh(model.m_collMesh) //might have to make this per-instance at some point -, m_renderer(model.m_renderer) -, m_name(model.m_name) -, m_curPatternIndex(model.m_curPatternIndex) -, m_curPattern(model.m_curPattern) -, m_debugFlags(0) -{ - //selective copying of node structure - NodeCopyCache cache; - m_root.Reset(dynamic_cast(model.m_root->Clone(&cache))); - - //materials are shared by meshes - for (unsigned int i=0; i colors; - colors.push_back(Color::RED); - colors.push_back(Color::GREEN); - colors.push_back(Color::BLUE); - SetColors(colors); - SetPattern(0); - } - - //animations need to be copied and retargeted - for (AnimationContainer::const_iterator it = model.m_animations.begin(); it != model.m_animations.end(); ++it) { - const Animation *anim = *it; - m_animations.push_back(new Animation(*anim)); - m_animations.back()->UpdateChannelTargets(m_root.Get()); - } - - //m_tags needs to be updated - for (TagContainer::const_iterator it = model.m_tags.begin(); it != model.m_tags.end(); ++it) { - MatrixTransform *t = dynamic_cast(m_root->FindNode((*it)->GetName())); - assert(t != 0); - m_tags.push_back(t); - } -} - -Model::~Model() -{ - while(!m_animations.empty()) delete m_animations.back(), m_animations.pop_back(); -} - -Model *Model::MakeInstance() const -{ - Model *m = new Model(*this); - return m; -} - -void Model::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - //update color parameters (materials are shared by model instances) - if (m_curPattern) { - for (MaterialContainer::const_iterator it = m_materials.begin(); it != m_materials.end(); ++it) { - if ((*it).second->GetDescriptor().usePatterns) { - (*it).second->texture5 = m_colorMap.GetTexture(); - (*it).second->texture4 = m_curPattern; - } + class LabelUpdateVisitor : public NodeVisitor { + public: + virtual void ApplyLabel(Label3D &l) + { + l.SetText(label); } - } - //update decals (materials and geometries are shared) - for (unsigned int i=0; i < MAX_DECAL_MATERIALS; i++) - if (m_decalMaterials[i]) - m_decalMaterials[i]->texture0 = m_curDecals[i]; - - //Override renderdata if this model is called from ModelNode - RenderData params = (rd != 0) ? (*rd) : m_renderData; - - m_renderer->SetTransform(trans); - - //using the entire model bounding radius for all nodes at the moment. - //BR could also be a property of Node. - params.boundingRadius = GetDrawClipRadius(); - - //render in two passes, if this is the top-level model - if (m_debugFlags & DEBUG_WIREFRAME) - m_renderer->SetWireFrameMode(true); - - if (params.nodemask & MASK_IGNORE) { - m_root->Render(trans, ¶ms); - } else { - params.nodemask = NODE_SOLID; - m_root->Render(trans, ¶ms); - params.nodemask = NODE_TRANSPARENT; - m_root->Render(trans, ¶ms); - } - - if (!m_debugFlags) - return; - - if (m_debugFlags & DEBUG_WIREFRAME) - m_renderer->SetWireFrameMode(false); - - if (m_debugFlags & DEBUG_BBOX) { - m_renderer->SetTransform(trans); - DrawAabb(); - } - - if (m_debugFlags & DEBUG_COLLMESH) { - m_renderer->SetTransform(trans); - DrawCollisionMesh(); - } - - if (m_debugFlags & DEBUG_TAGS) { - m_renderer->SetTransform(trans); - DrawAxisIndicators(m_tagPoints); - } - - if (m_debugFlags & DEBUG_DOCKING) { - m_renderer->SetTransform(trans); - DrawAxisIndicators(m_dockingPoints); - } -} - -void Model::Render(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED(); - - //update color parameters (materials are shared by model instances) - if (m_curPattern) { - for (MaterialContainer::const_iterator it = m_materials.begin(); it != m_materials.end(); ++it) { - if ((*it).second->GetDescriptor().usePatterns) { - (*it).second->texture5 = m_colorMap.GetTexture(); - (*it).second->texture4 = m_curPattern; - } - } - } - - //update decals (materials and geometries are shared) - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) - if (m_decalMaterials[i]) - m_decalMaterials[i]->texture0 = m_curDecals[i]; - - //Override renderdata if this model is called from ModelNode - RenderData params = (rd != 0) ? (*rd) : m_renderData; - - //using the entire model bounding radius for all nodes at the moment. - //BR could also be a property of Node. - params.boundingRadius = GetDrawClipRadius(); - - //render in two passes, if this is the top-level model - if (m_debugFlags & DEBUG_WIREFRAME) - m_renderer->SetWireFrameMode(true); - - if (params.nodemask & MASK_IGNORE) { - m_root->Render(trans, ¶ms); - } else { - params.nodemask = NODE_SOLID; - m_root->Render(trans, ¶ms); - params.nodemask = NODE_TRANSPARENT; - m_root->Render(trans, ¶ms); - } -} - -void Model::CreateAabbVB() -{ - PROFILE_SCOPED() - if (!m_collMesh) return; - - const Aabb aabb = m_collMesh->GetAabb(); - - const vector3f verts[16] = { - vector3f(aabb.min.x, aabb.min.y, aabb.min.z), - vector3f(aabb.max.x, aabb.min.y, aabb.min.z), - vector3f(aabb.max.x, aabb.max.y, aabb.min.z), - vector3f(aabb.min.x, aabb.max.y, aabb.min.z), - vector3f(aabb.min.x, aabb.min.y, aabb.min.z), - vector3f(aabb.min.x, aabb.min.y, aabb.max.z), - vector3f(aabb.max.x, aabb.min.y, aabb.max.z), - vector3f(aabb.max.x, aabb.min.y, aabb.min.z), - - vector3f(aabb.max.x, aabb.max.y, aabb.max.z), - vector3f(aabb.min.x, aabb.max.y, aabb.max.z), - vector3f(aabb.min.x, aabb.min.y, aabb.max.z), - vector3f(aabb.max.x, aabb.min.y, aabb.max.z), - vector3f(aabb.max.x, aabb.max.y, aabb.max.z), - vector3f(aabb.max.x, aabb.max.y, aabb.min.z), - vector3f(aabb.min.x, aabb.max.y, aabb.min.z), - vector3f(aabb.min.x, aabb.max.y, aabb.max.z), + std::string label; }; - if( !m_aabbVB.Valid() ) + Model::Model(Graphics::Renderer *r, const std::string &name) : + m_boundingRadius(10.f), + m_renderer(r), + m_name(name), + m_curPatternIndex(0), + m_curPattern(0), + m_debugFlags(0) { - Graphics::VertexArray va(Graphics::ATTRIB_POSITION, 28); - for(unsigned int i = 0; i < 7; i++) { - va.Add(verts[i]); - va.Add(verts[i+1]); -} + m_root.Reset(new Group(m_renderer)); + m_root->SetName(name); + ClearDecals(); + } - for(unsigned int i = 8; i < 15; i++) { - va.Add(verts[i]); - va.Add(verts[i+1]); + Model::Model(const Model &model) : + m_boundingRadius(model.m_boundingRadius), + m_materials(model.m_materials), + m_patterns(model.m_patterns), + m_collMesh(model.m_collMesh) //might have to make this per-instance at some point + , + m_renderer(model.m_renderer), + m_name(model.m_name), + m_curPatternIndex(model.m_curPatternIndex), + m_curPattern(model.m_curPattern), + m_debugFlags(0) + { + //selective copying of node structure + NodeCopyCache cache; + m_root.Reset(dynamic_cast(model.m_root->Clone(&cache))); + + //materials are shared by meshes + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + m_decalMaterials[i] = model.m_decalMaterials[i]; + ClearDecals(); + + //create unique color texture, if used + //patterns are shared + if (SupportsPatterns()) { + std::vector colors; + colors.push_back(Color::RED); + colors.push_back(Color::GREEN); + colors.push_back(Color::BLUE); + SetColors(colors); + SetPattern(0); } - Graphics::MaterialDescriptor desc; - m_aabbMat.Reset(m_renderer->CreateMaterial(desc)); - m_aabbMat->diffuse = Color::GREEN; - - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.numVertices = va.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - m_aabbVB.Reset( m_renderer->CreateVertexBuffer(vbd) ); - m_aabbVB->Populate( va ); - } - - m_state = m_renderer->CreateRenderState(Graphics::RenderStateDesc()); -} - -void Model::DrawAabb() -{ - if (!m_collMesh) return; - - if( !m_aabbVB.Valid() ) { - CreateAabbVB(); - } - - m_renderer->DrawBuffer( m_aabbVB.Get(), m_state, m_aabbMat.Get(), Graphics::LINE_SINGLE); - -} - -// Draw collision mesh as a wireframe overlay -void Model::DrawCollisionMesh() -{ - PROFILE_SCOPED() - if (!m_collMesh) return; - - if( !m_collisionMeshVB.Valid() ) - { - const std::vector &vertices = m_collMesh->GetGeomTree()->GetVertices(); - const Uint32 *indices = m_collMesh->GetGeomTree()->GetIndices(); - const unsigned int *triFlags = m_collMesh->GetGeomTree()->GetTriFlags(); - const unsigned int numIndices = m_collMesh->GetGeomTree()->GetNumTris() * 3; - - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, numIndices * 3); - int trindex = -1; - for(unsigned int i = 0; i < numIndices; i++) { - if (i % 3 == 0) - trindex++; - const unsigned int flag = triFlags[trindex]; - //show special geomflags in red - va.Add(vertices[indices[i]], flag > 0 ? Color::RED : Color::WHITE); + //animations need to be copied and retargeted + for (AnimationContainer::const_iterator it = model.m_animations.begin(); it != model.m_animations.end(); ++it) { + const Animation *anim = *it; + m_animations.push_back(new Animation(*anim)); + m_animations.back()->UpdateChannelTargets(m_root.Get()); } - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = va.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - m_collisionMeshVB.Reset( m_renderer->CreateVertexBuffer(vbd) ); - m_collisionMeshVB->Populate( va ); - } - - //might want to add some offset - m_renderer->SetWireFrameMode(true); - Graphics::RenderStateDesc rsd; - rsd.cullMode = Graphics::CULL_NONE; - m_renderer->DrawBuffer(m_collisionMeshVB.Get(), m_renderer->CreateRenderState(rsd), Graphics::vtxColorMaterial); - m_renderer->SetWireFrameMode(false); -} - -void Model::DrawAxisIndicators(std::vector &lines) -{ - for(auto i = lines.begin(); i != lines.end(); ++i) - (*i).Draw(m_renderer, m_renderer->CreateRenderState(Graphics::RenderStateDesc())); -} - -RefCountedPtr Model::CreateCollisionMesh() -{ - CollisionVisitor cv; - m_root->Accept(cv); - m_collMesh = cv.CreateCollisionMesh(); - m_boundingRadius = cv.GetBoundingRadius(); - return m_collMesh; -} - -RefCountedPtr Model::GetMaterialByName(const std::string &name) const -{ - for (auto it : m_materials) - { - if (it.first == name) - return it.second; - } - return RefCountedPtr(); //return invalid -} - -RefCountedPtr Model::GetMaterialByIndex(const int i) const -{ - return m_materials.at(Clamp(i, 0, int(m_materials.size())-1)).second; -} - -MatrixTransform * const Model::GetTagByIndex(const unsigned int i) const -{ - if (m_tags.empty() || i > m_tags.size()-1) return 0; - return m_tags.at(i); -} - -MatrixTransform * const Model::FindTagByName(const std::string &name) const -{ - for (TagContainer::const_iterator it = m_tags.begin(); - it != m_tags.end(); - ++it) - { - assert(!(*it)->GetName().empty()); //tags must have a name - if ((*it)->GetName() == name) return (*it); - } - return 0; -} - -void Model::FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const -{ - for (TagContainer::const_iterator it = m_tags.begin(); - it != m_tags.end(); - ++it) - { - assert(!(*it)->GetName().empty()); //tags must have a name - if (starts_with((*it)->GetName(), name)) { - outNameMTs.push_back((*it)); + //m_tags needs to be updated + for (TagContainer::const_iterator it = model.m_tags.begin(); it != model.m_tags.end(); ++it) { + MatrixTransform *t = dynamic_cast(m_root->FindNode((*it)->GetName())); + assert(t != 0); + m_tags.push_back(t); } } - return; -} -void Model::AddTag(const std::string &name, MatrixTransform *node) -{ - if (FindTagByName(name)) return; - node->SetName(name); - node->SetNodeFlags(node->GetNodeFlags() | NODE_TAG); - m_root->AddChild(node); - m_tags.push_back(node); -} - -void Model::SetPattern(unsigned int index) -{ - if (m_patterns.empty() || index > m_patterns.size() - 1) return; - const Pattern &pat = m_patterns.at(index); - m_colorMap.SetSmooth(pat.smoothColor); - m_curPatternIndex = index; - m_curPattern = pat.texture.Get(); -} - -void Model::SetColors(const std::vector &colors) -{ - assert(colors.size() == 3); //primary, seconday, trim - m_colorMap.Generate(GetRenderer(), colors.at(0), colors.at(1), colors.at(2)); -} - -void Model::SetDecalTexture(Graphics::Texture *t, unsigned int index) -{ - index = std::min(index, MAX_DECAL_MATERIALS-1); - if (m_decalMaterials[index]) - m_curDecals[index] = t; -} - -void Model::SetLabel(const std::string &text) -{ - LabelUpdateVisitor vis; - vis.label = text; - m_root->Accept(vis); -} - -void Model::ClearDecals() -{ - Graphics::Texture *t = Graphics::TextureBuilder::GetTransparentTexture(m_renderer); - for (unsigned int i=0; iGetDescriptor().usePatterns) - return true; + while (!m_animations.empty()) + delete m_animations.back(), m_animations.pop_back(); } - return false; -} - -Animation *Model::FindAnimation(const std::string &name) const -{ - for (AnimationContainer::const_iterator anim = m_animations.begin(); anim != m_animations.end(); ++anim) { - if ((*anim)->GetName() == name) return (*anim); - } - return 0; -} - -void Model::UpdateAnimations() -{ - // XXX WIP. Assuming animations are controlled manually by SetProgress. - for (AnimationContainer::iterator anim = m_animations.begin(); anim != m_animations.end(); ++anim) - (*anim)->Interpolate(); -} - -void Model::SetThrust(const vector3f &lin, const vector3f &ang) -{ - m_renderData.linthrust[0] = lin.x; - m_renderData.linthrust[1] = lin.y; - m_renderData.linthrust[2] = lin.z; - - m_renderData.angthrust[0] = ang.x; - m_renderData.angthrust[1] = ang.y; - m_renderData.angthrust[2] = ang.z; -} - -void Model::SetThrusterColor(const vector3f &dir, const Color &color) -{ - assert(m_root!=nullptr); - - FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, "thrusters"); - m_root->Accept(thrusterFinder); - const std::vector &results = thrusterFinder.GetResults(); - Group* thrusters = static_cast(results.at(0)); - - for (unsigned int i=0; iGetNumChildren(); i++) { - MatrixTransform *mt = static_cast(thrusters->GetChildAt(i)); - Thruster* my_thruster = static_cast(mt->GetChildAt(0)); - if (my_thruster==nullptr) continue; - float dot = my_thruster->GetDirection().Dot(dir); - if (dot>0.99) my_thruster->SetColor(color); - } -} - -void Model::SetThrusterColor(const std::string &name, const Color &color) -{ - assert(m_root!=nullptr); - - FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, name); - m_root->Accept(thrusterFinder); - const std::vector &results = thrusterFinder.GetResults(); - - //Hope there's only 1 result... - Thruster* my_thruster = static_cast(results.at(0)); - if (my_thruster!=nullptr) my_thruster->SetColor(color); -} - -void Model::SetThrusterColor(const Color &color) -{ - assert(m_root!=nullptr); - - FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, "thrusters"); - m_root->Accept(thrusterFinder); - const std::vector &results = thrusterFinder.GetResults(); - Group* thrusters = static_cast(results.at(0)); - - for (unsigned int i=0; iGetNumChildren(); i++) { - MatrixTransform *mt = static_cast(thrusters->GetChildAt(i)); - Thruster* my_thruster = static_cast(mt->GetChildAt(0)); - assert(my_thruster!=nullptr); - my_thruster->SetColor(color); - } -} - -class SaveVisitorJson : public NodeVisitor { -public: - SaveVisitorJson(Json &jsonObj) : m_jsonArray(jsonObj) {} - - void ApplyMatrixTransform(MatrixTransform &node) + Model *Model::MakeInstance() const { - const matrix4x4f &m = node.GetTransform(); - Json matrixTransformObj({}); // Create JSON object to contain matrix transform data. - matrixTransformObj["m"] = m; - m_jsonArray.push_back(matrixTransformObj); // Append matrix transform object to array. + Model *m = new Model(*this); + return m; } -private: - Json &m_jsonArray; -}; - -void Model::SaveToJson(Json &jsonObj) const -{ - Json modelObj({}); // Create JSON object to contain model data. - - Json visitorArray = Json::array(); // Create JSON array to contain visitor data. - SaveVisitorJson sv(visitorArray); - m_root->Accept(sv); - modelObj["visitor"] = visitorArray; // Add visitor array to model object. - - Json animationArray = Json::array(); // Create JSON array to contain animation data. - for (auto i : m_animations) animationArray.push_back(i->GetProgress()); - modelObj["animations"] = animationArray; // Add animation array to model object. - - modelObj["cur_pattern_index"] = m_curPatternIndex; - - jsonObj["model"] = modelObj; // Add model object to supplied object. -} - -class LoadVisitorJson : public NodeVisitor { -public: - LoadVisitorJson(const Json &jsonObj) : m_jsonArray(jsonObj), m_arrayIndex(0) {} - - void ApplyMatrixTransform(MatrixTransform &node) + void Model::Render(const matrix4x4f &trans, const RenderData *rd) { - node.SetTransform(m_jsonArray[m_arrayIndex++]["m"]); + PROFILE_SCOPED() + //update color parameters (materials are shared by model instances) + if (m_curPattern) { + for (MaterialContainer::const_iterator it = m_materials.begin(); it != m_materials.end(); ++it) { + if ((*it).second->GetDescriptor().usePatterns) { + (*it).second->texture5 = m_colorMap.GetTexture(); + (*it).second->texture4 = m_curPattern; + } + } + } + + //update decals (materials and geometries are shared) + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + if (m_decalMaterials[i]) + m_decalMaterials[i]->texture0 = m_curDecals[i]; + + //Override renderdata if this model is called from ModelNode + RenderData params = (rd != 0) ? (*rd) : m_renderData; + + m_renderer->SetTransform(trans); + + //using the entire model bounding radius for all nodes at the moment. + //BR could also be a property of Node. + params.boundingRadius = GetDrawClipRadius(); + + //render in two passes, if this is the top-level model + if (m_debugFlags & DEBUG_WIREFRAME) + m_renderer->SetWireFrameMode(true); + + if (params.nodemask & MASK_IGNORE) { + m_root->Render(trans, ¶ms); + } else { + params.nodemask = NODE_SOLID; + m_root->Render(trans, ¶ms); + params.nodemask = NODE_TRANSPARENT; + m_root->Render(trans, ¶ms); + } + + if (!m_debugFlags) + return; + + if (m_debugFlags & DEBUG_WIREFRAME) + m_renderer->SetWireFrameMode(false); + + if (m_debugFlags & DEBUG_BBOX) { + m_renderer->SetTransform(trans); + DrawAabb(); + } + + if (m_debugFlags & DEBUG_COLLMESH) { + m_renderer->SetTransform(trans); + DrawCollisionMesh(); + } + + if (m_debugFlags & DEBUG_TAGS) { + m_renderer->SetTransform(trans); + DrawAxisIndicators(m_tagPoints); + } + + if (m_debugFlags & DEBUG_DOCKING) { + m_renderer->SetTransform(trans); + DrawAxisIndicators(m_dockingPoints); + } } -private: - const Json &m_jsonArray; - unsigned int m_arrayIndex; -}; + void Model::Render(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED(); -void Model::LoadFromJson(const Json &jsonObj) -{ - try { - Json modelObj = jsonObj["model"]; + //update color parameters (materials are shared by model instances) + if (m_curPattern) { + for (MaterialContainer::const_iterator it = m_materials.begin(); it != m_materials.end(); ++it) { + if ((*it).second->GetDescriptor().usePatterns) { + (*it).second->texture5 = m_colorMap.GetTexture(); + (*it).second->texture4 = m_curPattern; + } + } + } - Json visitorArray = modelObj["visitor"].get(); - LoadVisitorJson lv(visitorArray); - m_root->Accept(lv); + //update decals (materials and geometries are shared) + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + if (m_decalMaterials[i]) + m_decalMaterials[i]->texture0 = m_curDecals[i]; - Json animationArray = modelObj["animations"].get(); - assert(m_animations.size() == animationArray.size()); - unsigned int arrayIndex = 0; - for (auto i : m_animations) i->SetProgress(animationArray[arrayIndex++]); - UpdateAnimations(); + //Override renderdata if this model is called from ModelNode + RenderData params = (rd != 0) ? (*rd) : m_renderData; - SetPattern(modelObj["cur_pattern_index"]); - } catch (Json::type_error &) { - throw SavedGameCorruptException(); + //using the entire model bounding radius for all nodes at the moment. + //BR could also be a property of Node. + params.boundingRadius = GetDrawClipRadius(); + + //render in two passes, if this is the top-level model + if (m_debugFlags & DEBUG_WIREFRAME) + m_renderer->SetWireFrameMode(true); + + if (params.nodemask & MASK_IGNORE) { + m_root->Render(trans, ¶ms); + } else { + params.nodemask = NODE_SOLID; + m_root->Render(trans, ¶ms); + params.nodemask = NODE_TRANSPARENT; + m_root->Render(trans, ¶ms); + } } -} + void Model::CreateAabbVB() + { + PROFILE_SCOPED() + if (!m_collMesh) return; -std::string Model::GetNameForMaterial(Graphics::Material *mat) const -{ - for (auto it : m_materials) { - Graphics::Material* modelMat = it.second.Get(); - if (modelMat == mat) return it.first; + const Aabb aabb = m_collMesh->GetAabb(); + + const vector3f verts[16] = { + vector3f(aabb.min.x, aabb.min.y, aabb.min.z), + vector3f(aabb.max.x, aabb.min.y, aabb.min.z), + vector3f(aabb.max.x, aabb.max.y, aabb.min.z), + vector3f(aabb.min.x, aabb.max.y, aabb.min.z), + vector3f(aabb.min.x, aabb.min.y, aabb.min.z), + vector3f(aabb.min.x, aabb.min.y, aabb.max.z), + vector3f(aabb.max.x, aabb.min.y, aabb.max.z), + vector3f(aabb.max.x, aabb.min.y, aabb.min.z), + + vector3f(aabb.max.x, aabb.max.y, aabb.max.z), + vector3f(aabb.min.x, aabb.max.y, aabb.max.z), + vector3f(aabb.min.x, aabb.min.y, aabb.max.z), + vector3f(aabb.max.x, aabb.min.y, aabb.max.z), + vector3f(aabb.max.x, aabb.max.y, aabb.max.z), + vector3f(aabb.max.x, aabb.max.y, aabb.min.z), + vector3f(aabb.min.x, aabb.max.y, aabb.min.z), + vector3f(aabb.min.x, aabb.max.y, aabb.max.z), + }; + + if (!m_aabbVB.Valid()) { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION, 28); + for (unsigned int i = 0; i < 7; i++) { + va.Add(verts[i]); + va.Add(verts[i + 1]); + } + + for (unsigned int i = 8; i < 15; i++) { + va.Add(verts[i]); + va.Add(verts[i + 1]); + } + + Graphics::MaterialDescriptor desc; + m_aabbMat.Reset(m_renderer->CreateMaterial(desc)); + m_aabbMat->diffuse = Color::GREEN; + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.numVertices = va.GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + m_aabbVB.Reset(m_renderer->CreateVertexBuffer(vbd)); + m_aabbVB->Populate(va); + } + + m_state = m_renderer->CreateRenderState(Graphics::RenderStateDesc()); } - //check decal materials - for (Uint32 i = 0; i < MAX_DECAL_MATERIALS; i++) { - if (m_decalMaterials[i].Valid() && m_decalMaterials[i].Get() == mat) - return stringf("decal_%0{u}", i + 1); + void Model::DrawAabb() + { + if (!m_collMesh) return; + + if (!m_aabbVB.Valid()) { + CreateAabbVB(); + } + + m_renderer->DrawBuffer(m_aabbVB.Get(), m_state, m_aabbMat.Get(), Graphics::LINE_SINGLE); } - return "unknown"; -} + // Draw collision mesh as a wireframe overlay + void Model::DrawCollisionMesh() + { + PROFILE_SCOPED() + if (!m_collMesh) return; -void Model::AddAxisIndicators(const std::vector &mts, std::vector &lines) -{ - for (std::vector::const_iterator i = mts.begin(); i != mts.end(); ++i) { - const matrix4x4f &trans = (*i)->GetTransform(); - const vector3f pos = trans.GetTranslate(); - const matrix3x3f &orient = trans.GetOrient(); - const vector3f x = orient.VectorX().Normalized(); - const vector3f y = orient.VectorY().Normalized(); - const vector3f z = orient.VectorZ().Normalized(); + if (!m_collisionMeshVB.Valid()) { + const std::vector &vertices = m_collMesh->GetGeomTree()->GetVertices(); + const Uint32 *indices = m_collMesh->GetGeomTree()->GetIndices(); + const unsigned int *triFlags = m_collMesh->GetGeomTree()->GetTriFlags(); + const unsigned int numIndices = m_collMesh->GetGeomTree()->GetNumTris() * 3; - Graphics::Drawables::Line3D lineX; - lineX.SetStart(pos); - lineX.SetEnd(pos+x); - lineX.SetColor(Color::RED); + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE, numIndices * 3); + int trindex = -1; + for (unsigned int i = 0; i < numIndices; i++) { + if (i % 3 == 0) + trindex++; + const unsigned int flag = triFlags[trindex]; + //show special geomflags in red + va.Add(vertices[indices[i]], flag > 0 ? Color::RED : Color::WHITE); + } - Graphics::Drawables::Line3D lineY; - lineY.SetStart(pos); - lineY.SetEnd(pos+y); - lineY.SetColor(Color::GREEN); + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.numVertices = va.GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + m_collisionMeshVB.Reset(m_renderer->CreateVertexBuffer(vbd)); + m_collisionMeshVB->Populate(va); + } - Graphics::Drawables::Line3D lineZ; - lineZ.SetStart(pos); - lineZ.SetEnd(pos+z); - lineZ.SetColor(Color::BLUE); - - lines.push_back(lineX); - lines.push_back(lineY); - lines.push_back(lineZ); - } -} - -void Model::SetDebugFlags(Uint32 flags) { - m_debugFlags = flags; - - if (m_debugFlags & SceneGraph::Model::DEBUG_TAGS && m_tagPoints.empty()) { - std::vector mts; - FindTagsByStartOfName("tag_", mts); - AddAxisIndicators(mts, m_tagPoints); + //might want to add some offset + m_renderer->SetWireFrameMode(true); + Graphics::RenderStateDesc rsd; + rsd.cullMode = Graphics::CULL_NONE; + m_renderer->DrawBuffer(m_collisionMeshVB.Get(), m_renderer->CreateRenderState(rsd), Graphics::vtxColorMaterial); + m_renderer->SetWireFrameMode(false); } - if (m_debugFlags & SceneGraph::Model::DEBUG_DOCKING && m_dockingPoints.empty()) { - std::vector mts; - FindTagsByStartOfName("entrance_", mts); - AddAxisIndicators(mts, m_dockingPoints); - FindTagsByStartOfName("loc_", mts); - AddAxisIndicators(mts, m_dockingPoints); - FindTagsByStartOfName("exit_", mts); - AddAxisIndicators(mts, m_dockingPoints); - } -} + void Model::DrawAxisIndicators(std::vector &lines) + { + for (auto i = lines.begin(); i != lines.end(); ++i) + (*i).Draw(m_renderer, m_renderer->CreateRenderState(Graphics::RenderStateDesc())); + } -} + RefCountedPtr Model::CreateCollisionMesh() + { + CollisionVisitor cv; + m_root->Accept(cv); + m_collMesh = cv.CreateCollisionMesh(); + m_boundingRadius = cv.GetBoundingRadius(); + return m_collMesh; + } + + RefCountedPtr Model::GetMaterialByName(const std::string &name) const + { + for (auto it : m_materials) { + if (it.first == name) + return it.second; + } + return RefCountedPtr(); //return invalid + } + + RefCountedPtr Model::GetMaterialByIndex(const int i) const + { + return m_materials.at(Clamp(i, 0, int(m_materials.size()) - 1)).second; + } + + MatrixTransform *const Model::GetTagByIndex(const unsigned int i) const + { + if (m_tags.empty() || i > m_tags.size() - 1) return 0; + return m_tags.at(i); + } + + MatrixTransform *const Model::FindTagByName(const std::string &name) const + { + for (TagContainer::const_iterator it = m_tags.begin(); + it != m_tags.end(); + ++it) { + assert(!(*it)->GetName().empty()); //tags must have a name + if ((*it)->GetName() == name) return (*it); + } + return 0; + } + + void Model::FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const + { + for (TagContainer::const_iterator it = m_tags.begin(); + it != m_tags.end(); + ++it) { + assert(!(*it)->GetName().empty()); //tags must have a name + if (starts_with((*it)->GetName(), name)) { + outNameMTs.push_back((*it)); + } + } + return; + } + + void Model::AddTag(const std::string &name, MatrixTransform *node) + { + if (FindTagByName(name)) return; + node->SetName(name); + node->SetNodeFlags(node->GetNodeFlags() | NODE_TAG); + m_root->AddChild(node); + m_tags.push_back(node); + } + + void Model::SetPattern(unsigned int index) + { + if (m_patterns.empty() || index > m_patterns.size() - 1) return; + const Pattern &pat = m_patterns.at(index); + m_colorMap.SetSmooth(pat.smoothColor); + m_curPatternIndex = index; + m_curPattern = pat.texture.Get(); + } + + void Model::SetColors(const std::vector &colors) + { + assert(colors.size() == 3); //primary, seconday, trim + m_colorMap.Generate(GetRenderer(), colors.at(0), colors.at(1), colors.at(2)); + } + + void Model::SetDecalTexture(Graphics::Texture *t, unsigned int index) + { + index = std::min(index, MAX_DECAL_MATERIALS - 1); + if (m_decalMaterials[index]) + m_curDecals[index] = t; + } + + void Model::SetLabel(const std::string &text) + { + LabelUpdateVisitor vis; + vis.label = text; + m_root->Accept(vis); + } + + void Model::ClearDecals() + { + Graphics::Texture *t = Graphics::TextureBuilder::GetTransparentTexture(m_renderer); + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + m_curDecals[i] = t; + } + + void Model::ClearDecal(unsigned int index) + { + index = std::min(index, MAX_DECAL_MATERIALS - 1); + if (m_decalMaterials[index]) + m_curDecals[index] = Graphics::TextureBuilder::GetTransparentTexture(m_renderer); + } + + bool Model::SupportsDecals() + { + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + if (m_decalMaterials[i].Valid()) return true; + + return false; + } + + bool Model::SupportsPatterns() + { + for (MaterialContainer::const_iterator it = m_materials.begin(), itEnd = m_materials.end(); + it != itEnd; + ++it) { + //Set pattern only on a material that supports it + if ((*it).second->GetDescriptor().usePatterns) + return true; + } + + return false; + } + + Animation *Model::FindAnimation(const std::string &name) const + { + for (AnimationContainer::const_iterator anim = m_animations.begin(); anim != m_animations.end(); ++anim) { + if ((*anim)->GetName() == name) return (*anim); + } + return 0; + } + + void Model::UpdateAnimations() + { + // XXX WIP. Assuming animations are controlled manually by SetProgress. + for (AnimationContainer::iterator anim = m_animations.begin(); anim != m_animations.end(); ++anim) + (*anim)->Interpolate(); + } + + void Model::SetThrust(const vector3f &lin, const vector3f &ang) + { + m_renderData.linthrust[0] = lin.x; + m_renderData.linthrust[1] = lin.y; + m_renderData.linthrust[2] = lin.z; + + m_renderData.angthrust[0] = ang.x; + m_renderData.angthrust[1] = ang.y; + m_renderData.angthrust[2] = ang.z; + } + + void Model::SetThrusterColor(const vector3f &dir, const Color &color) + { + assert(m_root != nullptr); + + FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, "thrusters"); + m_root->Accept(thrusterFinder); + const std::vector &results = thrusterFinder.GetResults(); + Group *thrusters = static_cast(results.at(0)); + + for (unsigned int i = 0; i < thrusters->GetNumChildren(); i++) { + MatrixTransform *mt = static_cast(thrusters->GetChildAt(i)); + Thruster *my_thruster = static_cast(mt->GetChildAt(0)); + if (my_thruster == nullptr) continue; + float dot = my_thruster->GetDirection().Dot(dir); + if (dot > 0.99) my_thruster->SetColor(color); + } + } + + void Model::SetThrusterColor(const std::string &name, const Color &color) + { + assert(m_root != nullptr); + + FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, name); + m_root->Accept(thrusterFinder); + const std::vector &results = thrusterFinder.GetResults(); + + //Hope there's only 1 result... + Thruster *my_thruster = static_cast(results.at(0)); + if (my_thruster != nullptr) my_thruster->SetColor(color); + } + + void Model::SetThrusterColor(const Color &color) + { + assert(m_root != nullptr); + + FindNodeVisitor thrusterFinder(FindNodeVisitor::MATCH_NAME_FULL, "thrusters"); + m_root->Accept(thrusterFinder); + const std::vector &results = thrusterFinder.GetResults(); + Group *thrusters = static_cast(results.at(0)); + + for (unsigned int i = 0; i < thrusters->GetNumChildren(); i++) { + MatrixTransform *mt = static_cast(thrusters->GetChildAt(i)); + Thruster *my_thruster = static_cast(mt->GetChildAt(0)); + assert(my_thruster != nullptr); + my_thruster->SetColor(color); + } + } + + class SaveVisitorJson : public NodeVisitor { + public: + SaveVisitorJson(Json &jsonObj) : + m_jsonArray(jsonObj) {} + + void ApplyMatrixTransform(MatrixTransform &node) + { + const matrix4x4f &m = node.GetTransform(); + Json matrixTransformObj({}); // Create JSON object to contain matrix transform data. + matrixTransformObj["m"] = m; + m_jsonArray.push_back(matrixTransformObj); // Append matrix transform object to array. + } + + private: + Json &m_jsonArray; + }; + + void Model::SaveToJson(Json &jsonObj) const + { + Json modelObj({}); // Create JSON object to contain model data. + + Json visitorArray = Json::array(); // Create JSON array to contain visitor data. + SaveVisitorJson sv(visitorArray); + m_root->Accept(sv); + modelObj["visitor"] = visitorArray; // Add visitor array to model object. + + Json animationArray = Json::array(); // Create JSON array to contain animation data. + for (auto i : m_animations) + animationArray.push_back(i->GetProgress()); + modelObj["animations"] = animationArray; // Add animation array to model object. + + modelObj["cur_pattern_index"] = m_curPatternIndex; + + jsonObj["model"] = modelObj; // Add model object to supplied object. + } + + class LoadVisitorJson : public NodeVisitor { + public: + LoadVisitorJson(const Json &jsonObj) : + m_jsonArray(jsonObj), + m_arrayIndex(0) {} + + void ApplyMatrixTransform(MatrixTransform &node) + { + node.SetTransform(m_jsonArray[m_arrayIndex++]["m"]); + } + + private: + const Json &m_jsonArray; + unsigned int m_arrayIndex; + }; + + void Model::LoadFromJson(const Json &jsonObj) + { + try { + Json modelObj = jsonObj["model"]; + + Json visitorArray = modelObj["visitor"].get(); + LoadVisitorJson lv(visitorArray); + m_root->Accept(lv); + + Json animationArray = modelObj["animations"].get(); + assert(m_animations.size() == animationArray.size()); + unsigned int arrayIndex = 0; + for (auto i : m_animations) + i->SetProgress(animationArray[arrayIndex++]); + UpdateAnimations(); + + SetPattern(modelObj["cur_pattern_index"]); + } catch (Json::type_error &) { + throw SavedGameCorruptException(); + } + } + + std::string Model::GetNameForMaterial(Graphics::Material *mat) const + { + for (auto it : m_materials) { + Graphics::Material *modelMat = it.second.Get(); + if (modelMat == mat) return it.first; + } + + //check decal materials + for (Uint32 i = 0; i < MAX_DECAL_MATERIALS; i++) { + if (m_decalMaterials[i].Valid() && m_decalMaterials[i].Get() == mat) + return stringf("decal_%0{u}", i + 1); + } + + return "unknown"; + } + + void Model::AddAxisIndicators(const std::vector &mts, std::vector &lines) + { + for (std::vector::const_iterator i = mts.begin(); i != mts.end(); ++i) { + const matrix4x4f &trans = (*i)->GetTransform(); + const vector3f pos = trans.GetTranslate(); + const matrix3x3f &orient = trans.GetOrient(); + const vector3f x = orient.VectorX().Normalized(); + const vector3f y = orient.VectorY().Normalized(); + const vector3f z = orient.VectorZ().Normalized(); + + Graphics::Drawables::Line3D lineX; + lineX.SetStart(pos); + lineX.SetEnd(pos + x); + lineX.SetColor(Color::RED); + + Graphics::Drawables::Line3D lineY; + lineY.SetStart(pos); + lineY.SetEnd(pos + y); + lineY.SetColor(Color::GREEN); + + Graphics::Drawables::Line3D lineZ; + lineZ.SetStart(pos); + lineZ.SetEnd(pos + z); + lineZ.SetColor(Color::BLUE); + + lines.push_back(lineX); + lines.push_back(lineY); + lines.push_back(lineZ); + } + } + + void Model::SetDebugFlags(Uint32 flags) + { + m_debugFlags = flags; + + if (m_debugFlags & SceneGraph::Model::DEBUG_TAGS && m_tagPoints.empty()) { + std::vector mts; + FindTagsByStartOfName("tag_", mts); + AddAxisIndicators(mts, m_tagPoints); + } + + if (m_debugFlags & SceneGraph::Model::DEBUG_DOCKING && m_dockingPoints.empty()) { + std::vector mts; + FindTagsByStartOfName("entrance_", mts); + AddAxisIndicators(mts, m_dockingPoints); + FindTagsByStartOfName("loc_", mts); + AddAxisIndicators(mts, m_dockingPoints); + FindTagsByStartOfName("exit_", mts); + AddAxisIndicators(mts, m_dockingPoints); + } + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Model.h b/src/scenegraph/Model.h index e3852adda..9ac6313ea 100644 --- a/src/scenegraph/Model.h +++ b/src/scenegraph/Model.h @@ -59,158 +59,157 @@ * - model cache * - removing unnecessary nodes from the scene graph: pre-translate unanimated meshes etc. */ -#include "libs.h" #include "Animation.h" +#include "CollMesh.h" #include "ColorMap.h" +#include "DeleteEmitter.h" #include "Group.h" +#include "Json.h" #include "Label3D.h" #include "Pattern.h" -#include "CollMesh.h" -#include "graphics/Material.h" -#include "graphics/Drawables.h" #include "Serializer.h" -#include "DeleteEmitter.h" -#include "Json.h" +#include "graphics/Drawables.h" +#include "graphics/Material.h" +#include "libs.h" #include namespace Graphics { class Renderer; class VertexBuffer; -} +} // namespace Graphics -namespace SceneGraph -{ -class BaseLoader; -class ModelBinarizer; -class BinaryConverter; +namespace SceneGraph { + class BaseLoader; + class ModelBinarizer; + class BinaryConverter; -struct LoadingError : public std::runtime_error { - LoadingError(const std::string &str) : std::runtime_error(str.c_str()) { } -}; - -typedef std::vector > > MaterialContainer; -typedef std::vector AnimationContainer; -typedef std::vector TagContainer; - -class Model : public DeleteEmitter -{ -public: - friend class BaseLoader; - friend class Loader; - friend class ModelBinarizer; - friend class BinaryConverter; - Model(Graphics::Renderer *r, const std::string &name); - ~Model(); - - Model *MakeInstance() const; - - const std::string& GetName() const { return m_name; } - - float GetDrawClipRadius() const { return m_boundingRadius; } - void SetDrawClipRadius(float clipRadius) { m_boundingRadius = clipRadius; } - - void Render(const matrix4x4f &trans, const RenderData *rd = 0); //ModelNode can override RD - void Render(const std::vector &trans, const RenderData *rd = 0); //ModelNode can override RD - - RefCountedPtr CreateCollisionMesh(); - RefCountedPtr GetCollisionMesh() const { return m_collMesh; } - void SetCollisionMesh(RefCountedPtr collMesh) { m_collMesh.Reset(collMesh.Get()); } - - RefCountedPtr GetRoot() { return m_root; } - - //materials used in the nodes should be accessible from here for convenience - RefCountedPtr GetMaterialByName(const std::string &name) const; - RefCountedPtr GetMaterialByIndex(const int) const; - unsigned int GetNumMaterials() const { return static_cast(m_materials.size()); } - - unsigned int GetNumTags() const { return static_cast(m_tags.size()); } - MatrixTransform *const GetTagByIndex(unsigned int index) const; - MatrixTransform *const FindTagByName(const std::string &name) const; - typedef std::vector TVecMT; - void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const; - void AddTag(const std::string &name, MatrixTransform *node); - - const PatternContainer &GetPatterns() const { return m_patterns; } - unsigned int GetNumPatterns() const { return static_cast(m_patterns.size()); } - void SetPattern(unsigned int index); - unsigned int GetPattern() const { return m_curPatternIndex; } - void SetColors(const std::vector &colors); - void SetDecalTexture(Graphics::Texture *t, unsigned int index = 0); - void ClearDecal(unsigned int index = 0); - void ClearDecals(); - void SetLabel(const std::string&); - - //for modelviewer, at least - bool SupportsDecals(); - bool SupportsPatterns(); - - Animation *FindAnimation(const std::string&) const; //0 if not found - const std::vector GetAnimations() const { return m_animations; } - void UpdateAnimations(); - - Graphics::Renderer *GetRenderer() const { return m_renderer; } - - //special for ship model use - void SetThrust(const vector3f &linear, const vector3f &angular); - - void SetThrusterColor(const vector3f &dir, const Color &color); - void SetThrusterColor(const std::string &name, const Color &color); - void SetThrusterColor(const Color &color); - - void SaveToJson(Json &jsonObj) const; - void LoadFromJson(const Json &jsonObj); - - //serialization aid - std::string GetNameForMaterial(Graphics::Material*) const; - - enum DebugFlags { // - DEBUG_NONE = 0x0, - DEBUG_BBOX = 0x1, - DEBUG_COLLMESH = 0x2, - DEBUG_WIREFRAME = 0x4, - DEBUG_TAGS = 0x8, - DEBUG_DOCKING = 0x10 + struct LoadingError : public std::runtime_error { + LoadingError(const std::string &str) : + std::runtime_error(str.c_str()) {} }; - void SetDebugFlags(Uint32 flags); -private: - Model(const Model&); + typedef std::vector>> MaterialContainer; + typedef std::vector AnimationContainer; + typedef std::vector TagContainer; - static const unsigned int MAX_DECAL_MATERIALS = 4; - ColorMap m_colorMap; - float m_boundingRadius; - MaterialContainer m_materials; //materials are shared throughout the model graph - PatternContainer m_patterns; - RefCountedPtr m_collMesh; - RefCountedPtr m_decalMaterials[MAX_DECAL_MATERIALS]; //spaceship insignia, advertising billboards - RefCountedPtr m_root; - Graphics::Renderer *m_renderer; - std::string m_name; - std::vector m_animations; - TagContainer m_tags; //named attachment points - RenderData m_renderData; + class Model : public DeleteEmitter { + public: + friend class BaseLoader; + friend class Loader; + friend class ModelBinarizer; + friend class BinaryConverter; + Model(Graphics::Renderer *r, const std::string &name); + ~Model(); - //per-instance flavour data - unsigned int m_curPatternIndex; - Graphics::Texture *m_curPattern; - Graphics::Texture *m_curDecals[MAX_DECAL_MATERIALS]; + Model *MakeInstance() const; - // debug support - void CreateAabbVB(); - void DrawAabb(); - void DrawCollisionMesh(); - void DrawAxisIndicators(std::vector &lines); - void AddAxisIndicators(const std::vector &mts, std::vector &lines); + const std::string &GetName() const { return m_name; } - Uint32 m_debugFlags; - std::vector m_tagPoints; - std::vector m_dockingPoints; - RefCountedPtr m_collisionMeshVB; - RefCountedPtr m_aabbVB; - RefCountedPtr m_aabbMat; - Graphics::RenderState* m_state; -}; + float GetDrawClipRadius() const { return m_boundingRadius; } + void SetDrawClipRadius(float clipRadius) { m_boundingRadius = clipRadius; } -} + void Render(const matrix4x4f &trans, const RenderData *rd = 0); //ModelNode can override RD + void Render(const std::vector &trans, const RenderData *rd = 0); //ModelNode can override RD + + RefCountedPtr CreateCollisionMesh(); + RefCountedPtr GetCollisionMesh() const { return m_collMesh; } + void SetCollisionMesh(RefCountedPtr collMesh) { m_collMesh.Reset(collMesh.Get()); } + + RefCountedPtr GetRoot() { return m_root; } + + //materials used in the nodes should be accessible from here for convenience + RefCountedPtr GetMaterialByName(const std::string &name) const; + RefCountedPtr GetMaterialByIndex(const int) const; + unsigned int GetNumMaterials() const { return static_cast(m_materials.size()); } + + unsigned int GetNumTags() const { return static_cast(m_tags.size()); } + MatrixTransform *const GetTagByIndex(unsigned int index) const; + MatrixTransform *const FindTagByName(const std::string &name) const; + typedef std::vector TVecMT; + void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const; + void AddTag(const std::string &name, MatrixTransform *node); + + const PatternContainer &GetPatterns() const { return m_patterns; } + unsigned int GetNumPatterns() const { return static_cast(m_patterns.size()); } + void SetPattern(unsigned int index); + unsigned int GetPattern() const { return m_curPatternIndex; } + void SetColors(const std::vector &colors); + void SetDecalTexture(Graphics::Texture *t, unsigned int index = 0); + void ClearDecal(unsigned int index = 0); + void ClearDecals(); + void SetLabel(const std::string &); + + //for modelviewer, at least + bool SupportsDecals(); + bool SupportsPatterns(); + + Animation *FindAnimation(const std::string &) const; //0 if not found + const std::vector GetAnimations() const { return m_animations; } + void UpdateAnimations(); + + Graphics::Renderer *GetRenderer() const { return m_renderer; } + + //special for ship model use + void SetThrust(const vector3f &linear, const vector3f &angular); + + void SetThrusterColor(const vector3f &dir, const Color &color); + void SetThrusterColor(const std::string &name, const Color &color); + void SetThrusterColor(const Color &color); + + void SaveToJson(Json &jsonObj) const; + void LoadFromJson(const Json &jsonObj); + + //serialization aid + std::string GetNameForMaterial(Graphics::Material *) const; + + enum DebugFlags { // + DEBUG_NONE = 0x0, + DEBUG_BBOX = 0x1, + DEBUG_COLLMESH = 0x2, + DEBUG_WIREFRAME = 0x4, + DEBUG_TAGS = 0x8, + DEBUG_DOCKING = 0x10 + }; + void SetDebugFlags(Uint32 flags); + + private: + Model(const Model &); + + static const unsigned int MAX_DECAL_MATERIALS = 4; + ColorMap m_colorMap; + float m_boundingRadius; + MaterialContainer m_materials; //materials are shared throughout the model graph + PatternContainer m_patterns; + RefCountedPtr m_collMesh; + RefCountedPtr m_decalMaterials[MAX_DECAL_MATERIALS]; //spaceship insignia, advertising billboards + RefCountedPtr m_root; + Graphics::Renderer *m_renderer; + std::string m_name; + std::vector m_animations; + TagContainer m_tags; //named attachment points + RenderData m_renderData; + + //per-instance flavour data + unsigned int m_curPatternIndex; + Graphics::Texture *m_curPattern; + Graphics::Texture *m_curDecals[MAX_DECAL_MATERIALS]; + + // debug support + void CreateAabbVB(); + void DrawAabb(); + void DrawCollisionMesh(); + void DrawAxisIndicators(std::vector &lines); + void AddAxisIndicators(const std::vector &mts, std::vector &lines); + + Uint32 m_debugFlags; + std::vector m_tagPoints; + std::vector m_dockingPoints; + RefCountedPtr m_collisionMeshVB; + RefCountedPtr m_aabbVB; + RefCountedPtr m_aabbMat; + Graphics::RenderState *m_state; + }; + +} // namespace SceneGraph #endif diff --git a/src/scenegraph/ModelNode.cpp b/src/scenegraph/ModelNode.cpp index 78c71a6f0..ddecb67f3 100644 --- a/src/scenegraph/ModelNode.cpp +++ b/src/scenegraph/ModelNode.cpp @@ -6,39 +6,39 @@ namespace SceneGraph { -ModelNode::ModelNode(Model *m) -: Node(m->GetRenderer()) -, m_model(m) -{ -} + ModelNode::ModelNode(Model *m) : + Node(m->GetRenderer()), + m_model(m) + { + } -ModelNode::ModelNode(const ModelNode &modelNode, NodeCopyCache *cache) -: Node(modelNode, cache) -, m_model(modelNode.m_model) -{ -} + ModelNode::ModelNode(const ModelNode &modelNode, NodeCopyCache *cache) : + Node(modelNode, cache), + m_model(modelNode.m_model) + { + } -Node* ModelNode::Clone(NodeCopyCache *cache) -{ - return this; //modelnodes are shared -} + Node *ModelNode::Clone(NodeCopyCache *cache) + { + return this; //modelnodes are shared + } -void ModelNode::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - //slight hack here - RenderData newrd = *rd; - newrd.nodemask |= MASK_IGNORE; - m_model->Render(trans, &newrd); -} + void ModelNode::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + //slight hack here + RenderData newrd = *rd; + newrd.nodemask |= MASK_IGNORE; + m_model->Render(trans, &newrd); + } -void ModelNode::Render(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - //slight hack here - RenderData newrd = *rd; - newrd.nodemask |= MASK_IGNORE; - m_model->Render(trans, &newrd); -} + void ModelNode::Render(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED() + //slight hack here + RenderData newrd = *rd; + newrd.nodemask |= MASK_IGNORE; + m_model->Render(trans, &newrd); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/ModelNode.h b/src/scenegraph/ModelNode.h index 53f5f4f56..2430fc02e 100644 --- a/src/scenegraph/ModelNode.h +++ b/src/scenegraph/ModelNode.h @@ -6,27 +6,27 @@ /* * Use another model as a submodel */ -#include "Node.h" #include "Model.h" +#include "Node.h" namespace SceneGraph { -class ModelNode : public Node { -public: - ModelNode(Model *m); - ModelNode(const ModelNode&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0); - virtual const char *GetTypeName() const { return "ModelNode"; } - virtual void Render(const matrix4x4f &trans, const RenderData *rd); - virtual void Render(const std::vector &trans, const RenderData *rd); + class ModelNode : public Node { + public: + ModelNode(Model *m); + ModelNode(const ModelNode &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0); + virtual const char *GetTypeName() const { return "ModelNode"; } + virtual void Render(const matrix4x4f &trans, const RenderData *rd); + virtual void Render(const std::vector &trans, const RenderData *rd); -protected: - virtual ~ModelNode() { } + protected: + virtual ~ModelNode() {} -private: - Model *m_model; -}; + private: + Model *m_model; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/ModelSkin.cpp b/src/scenegraph/ModelSkin.cpp index 37c954983..191d9cbdb 100644 --- a/src/scenegraph/ModelSkin.cpp +++ b/src/scenegraph/ModelSkin.cpp @@ -2,11 +2,11 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "ModelSkin.h" +#include "GameSaveError.h" +#include "JsonUtils.h" #include "Model.h" #include "StringF.h" #include "graphics/TextureBuilder.h" -#include "JsonUtils.h" -#include "GameSaveError.h" #include "RandomColor.h" @@ -14,148 +14,148 @@ namespace SceneGraph { -ModelSkin::ModelSkin() : - m_colors(3) -{ -} - -void ModelSkin::Apply(Model *model) const -{ - model->SetColors(m_colors); - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { - if (m_decals[i].empty()) - model->ClearDecal(i); - else - model->SetDecalTexture(Graphics::TextureBuilder::Decal(stringf("textures/decals/%0.dds", m_decals[i])).GetOrCreateTexture(model->GetRenderer(), "decal"), i); + ModelSkin::ModelSkin() : + m_colors(3) + { } - model->SetLabel(m_label); -} -void ModelSkin::SetColors(const std::vector &colors) -{ - assert(colors.size() == 3); - m_colors = colors; -} - -void ModelSkin::SetPrimaryColor(const Color &color) -{ - m_colors[0] = color; -} - -void ModelSkin::SetSecondaryColor(const Color &color) -{ - m_colors[1] = color; -} - -void ModelSkin::SetTrimColor(const Color &color) -{ - m_colors[2] = color; -} - -void ModelSkin::SetRandomColors(Random &rand) -{ - using namespace RandomColorGenerator; - static RandomColor s_randomColor; - m_colors = RandomColor::GetColors(rand, SCHEME_RANDOM, LUMINOSITY_BRIGHT, 3); -} - -void ModelSkin::SetDecal(const std::string &name, unsigned int index) -{ - assert(index < MAX_DECAL_MATERIALS); - m_decals[index] = name; -} - -void ModelSkin::ClearDecal(unsigned int index) -{ - assert(index < MAX_DECAL_MATERIALS); - m_decals[index] = ""; -} - -void ModelSkin::ClearDecals() -{ - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) - ClearDecal(i); -} - -void ModelSkin::SetLabel(const std::string &label) -{ - m_label = label; -} - -void ModelSkin::Load(Serializer::Reader &rd) -{ - for (unsigned int i = 0; i < 3; i++) { - m_colors[i].r = rd.Byte(); - m_colors[i].g = rd.Byte(); - m_colors[i].b = rd.Byte(); + void ModelSkin::Apply(Model *model) const + { + model->SetColors(m_colors); + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { + if (m_decals[i].empty()) + model->ClearDecal(i); + else + model->SetDecalTexture(Graphics::TextureBuilder::Decal(stringf("textures/decals/%0.dds", m_decals[i])).GetOrCreateTexture(model->GetRenderer(), "decal"), i); + } + model->SetLabel(m_label); } - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) - m_decals[i] = rd.String(); - m_label = rd.String(); -} -void ModelSkin::LoadFromJson(const Json &jsonObj) -{ - try { - Json modelSkinObj = jsonObj["model_skin"]; - - Json colorsArray = modelSkinObj["colors"].get(); - if (colorsArray.size() != 3) throw SavedGameCorruptException(); - for (unsigned int i = 0; i < 3; i++) { - Json arrayElem = colorsArray[i]; - m_colors[i] = arrayElem["color"]; - } - - Json decalsArray = modelSkinObj["decals"].get(); - if (decalsArray.size() != MAX_DECAL_MATERIALS) throw SavedGameCorruptException(); - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { - Json arrayElem = decalsArray[i]; - m_decals[i] = arrayElem["decal"]; - } - - m_label = modelSkinObj["label"]; - } catch (Json::type_error &) { - throw SavedGameCorruptException(); + void ModelSkin::SetColors(const std::vector &colors) + { + assert(colors.size() == 3); + m_colors = colors; } -} -void ModelSkin::Save(Serializer::Writer &wr) const -{ - for (unsigned int i = 0; i < 3; i++) { - wr.Byte(m_colors[i].r); - wr.Byte(m_colors[i].g); - wr.Byte(m_colors[i].b); + void ModelSkin::SetPrimaryColor(const Color &color) + { + m_colors[0] = color; } - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) - wr.String(m_decals[i]); - wr.String(m_label); -} -void ModelSkin::SaveToJson(Json &jsonObj) const -{ - Json modelSkinObj({}); // Create JSON object to contain model skin data. + void ModelSkin::SetSecondaryColor(const Color &color) + { + m_colors[1] = color; + } - Json colorsArray = Json::array(); // Create JSON array to contain colors data. - for (unsigned int i = 0; i < 3; i++) { - Json arrayElem({}); - arrayElem["color"] = m_colors[i]; - colorsArray.push_back(arrayElem); - } + void ModelSkin::SetTrimColor(const Color &color) + { + m_colors[2] = color; + } - modelSkinObj["colors"] = colorsArray; // Add colors array to model skin object. + void ModelSkin::SetRandomColors(Random &rand) + { + using namespace RandomColorGenerator; + static RandomColor s_randomColor; + m_colors = RandomColor::GetColors(rand, SCHEME_RANDOM, LUMINOSITY_BRIGHT, 3); + } - Json decalsArray = Json::array(); // Create JSON array to contain decals data. - for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { - Json arrayElem({}); - arrayElem["decal"] = m_decals[i]; - decalsArray.push_back(arrayElem); - } + void ModelSkin::SetDecal(const std::string &name, unsigned int index) + { + assert(index < MAX_DECAL_MATERIALS); + m_decals[index] = name; + } - modelSkinObj["decals"] = decalsArray; // Add decals array to model skin object. + void ModelSkin::ClearDecal(unsigned int index) + { + assert(index < MAX_DECAL_MATERIALS); + m_decals[index] = ""; + } - modelSkinObj["label"] = m_label; + void ModelSkin::ClearDecals() + { + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + ClearDecal(i); + } - jsonObj["model_skin"] = modelSkinObj; // Add model skin object to supplied object. -} + void ModelSkin::SetLabel(const std::string &label) + { + m_label = label; + } -} + void ModelSkin::Load(Serializer::Reader &rd) + { + for (unsigned int i = 0; i < 3; i++) { + m_colors[i].r = rd.Byte(); + m_colors[i].g = rd.Byte(); + m_colors[i].b = rd.Byte(); + } + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + m_decals[i] = rd.String(); + m_label = rd.String(); + } + + void ModelSkin::LoadFromJson(const Json &jsonObj) + { + try { + Json modelSkinObj = jsonObj["model_skin"]; + + Json colorsArray = modelSkinObj["colors"].get(); + if (colorsArray.size() != 3) throw SavedGameCorruptException(); + for (unsigned int i = 0; i < 3; i++) { + Json arrayElem = colorsArray[i]; + m_colors[i] = arrayElem["color"]; + } + + Json decalsArray = modelSkinObj["decals"].get(); + if (decalsArray.size() != MAX_DECAL_MATERIALS) throw SavedGameCorruptException(); + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { + Json arrayElem = decalsArray[i]; + m_decals[i] = arrayElem["decal"]; + } + + m_label = modelSkinObj["label"]; + } catch (Json::type_error &) { + throw SavedGameCorruptException(); + } + } + + void ModelSkin::Save(Serializer::Writer &wr) const + { + for (unsigned int i = 0; i < 3; i++) { + wr.Byte(m_colors[i].r); + wr.Byte(m_colors[i].g); + wr.Byte(m_colors[i].b); + } + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) + wr.String(m_decals[i]); + wr.String(m_label); + } + + void ModelSkin::SaveToJson(Json &jsonObj) const + { + Json modelSkinObj({}); // Create JSON object to contain model skin data. + + Json colorsArray = Json::array(); // Create JSON array to contain colors data. + for (unsigned int i = 0; i < 3; i++) { + Json arrayElem({}); + arrayElem["color"] = m_colors[i]; + colorsArray.push_back(arrayElem); + } + + modelSkinObj["colors"] = colorsArray; // Add colors array to model skin object. + + Json decalsArray = Json::array(); // Create JSON array to contain decals data. + for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { + Json arrayElem({}); + arrayElem["decal"] = m_decals[i]; + decalsArray.push_back(arrayElem); + } + + modelSkinObj["decals"] = decalsArray; // Add decals array to model skin object. + + modelSkinObj["label"] = m_label; + + jsonObj["model_skin"] = modelSkinObj; // Add model skin object to supplied object. + } + +} // namespace SceneGraph diff --git a/src/scenegraph/ModelSkin.h b/src/scenegraph/ModelSkin.h index 7e97645ba..525c2dcb6 100644 --- a/src/scenegraph/ModelSkin.h +++ b/src/scenegraph/ModelSkin.h @@ -5,49 +5,49 @@ #define SCENEGRAPH_MODELSKIN_H #include "Color.h" -#include "Serializer.h" -#include "Random.h" -#include "LuaWrappable.h" #include "Json.h" +#include "LuaWrappable.h" +#include "Random.h" +#include "Serializer.h" #include namespace SceneGraph { -class Model; + class Model; -class ModelSkin : public LuaWrappable { -public: - ModelSkin(); + class ModelSkin : public LuaWrappable { + public: + ModelSkin(); - void Apply(Model *model) const; + void Apply(Model *model) const; - void SetColors(const std::vector &colors); - void SetPrimaryColor(const Color &color); - void SetSecondaryColor(const Color &color); - void SetTrimColor(const Color &color); - void SetRandomColors(Random &rand); + void SetColors(const std::vector &colors); + void SetPrimaryColor(const Color &color); + void SetSecondaryColor(const Color &color); + void SetTrimColor(const Color &color); + void SetRandomColors(Random &rand); - void SetDecal(const std::string &name, unsigned int index = 0); - void ClearDecal(unsigned int index = 0); - void ClearDecals(); + void SetDecal(const std::string &name, unsigned int index = 0); + void ClearDecal(unsigned int index = 0); + void ClearDecals(); - void SetLabel(const std::string &label); + void SetLabel(const std::string &label); - void Load(Serializer::Reader &rd); - void LoadFromJson(const Json &jsonObj); - void Save(Serializer::Writer &wr) const; - void SaveToJson(Json &jsonObj) const; + void Load(Serializer::Reader &rd); + void LoadFromJson(const Json &jsonObj); + void Save(Serializer::Writer &wr) const; + void SaveToJson(Json &jsonObj) const; - const std::vector& GetColors() const { return m_colors; } + const std::vector &GetColors() const { return m_colors; } -private: - static const unsigned int MAX_DECAL_MATERIALS = 4; + private: + static const unsigned int MAX_DECAL_MATERIALS = 4; - std::vector m_colors; - std::string m_decals[MAX_DECAL_MATERIALS]; - std::string m_label; -}; + std::vector m_colors; + std::string m_decals[MAX_DECAL_MATERIALS]; + std::string m_label; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Node.cpp b/src/scenegraph/Node.cpp index 3d811a20b..b927a7373 100644 --- a/src/scenegraph/Node.cpp +++ b/src/scenegraph/Node.cpp @@ -8,63 +8,63 @@ namespace SceneGraph { -Node::Node(Graphics::Renderer *r) -: m_name("") -, m_nodeMask(NODE_SOLID) -, m_nodeFlags(0) -, m_renderer(r) -{ -} + Node::Node(Graphics::Renderer *r) : + m_name(""), + m_nodeMask(NODE_SOLID), + m_nodeFlags(0), + m_renderer(r) + { + } -Node::Node(Graphics::Renderer *r, unsigned int nodemask) -: m_name("") -, m_nodeMask(nodemask) -, m_nodeFlags(0) -, m_renderer(r) -{ -} + Node::Node(Graphics::Renderer *r, unsigned int nodemask) : + m_name(""), + m_nodeMask(nodemask), + m_nodeFlags(0), + m_renderer(r) + { + } -Node::Node(const Node &node, NodeCopyCache *cache) -: m_name(node.m_name) -, m_nodeMask(node.m_nodeMask) -, m_nodeFlags(node.m_nodeFlags) -, m_renderer(node.m_renderer) -{ -} + Node::Node(const Node &node, NodeCopyCache *cache) : + m_name(node.m_name), + m_nodeMask(node.m_nodeMask), + m_nodeFlags(node.m_nodeFlags), + m_renderer(node.m_renderer) + { + } -Node::~Node() -{ -} + Node::~Node() + { + } -void Node::Accept(NodeVisitor &v) -{ - v.ApplyNode(*this); -} + void Node::Accept(NodeVisitor &v) + { + v.ApplyNode(*this); + } -void Node::Traverse(NodeVisitor &v) -{ -} + void Node::Traverse(NodeVisitor &v) + { + } -Node* Node::FindNode(const std::string &name) -{ - if (m_name == name) - return this; - else - return nullptr; -} + Node *Node::FindNode(const std::string &name) + { + if (m_name == name) + return this; + else + return nullptr; + } -void Node::DrawAxes() -{ - Graphics::Drawables::Axes3D *axes = Graphics::Drawables::GetAxes3DDrawable(m_renderer); - axes->Draw(m_renderer); -} + void Node::DrawAxes() + { + Graphics::Drawables::Axes3D *axes = Graphics::Drawables::GetAxes3DDrawable(m_renderer); + axes->Draw(m_renderer); + } -void Node::Save(NodeDatabase &db) -{ - db.wr->String(GetTypeName()); - db.wr->String(m_name.c_str()); - db.wr->Int32(m_nodeMask); - db.wr->Int32(m_nodeFlags); -} + void Node::Save(NodeDatabase &db) + { + db.wr->String(GetTypeName()); + db.wr->String(m_name.c_str()); + db.wr->Int32(m_nodeMask); + db.wr->Int32(m_nodeFlags); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/Node.h b/src/scenegraph/Node.h index 66bbf0be4..078005958 100644 --- a/src/scenegraph/Node.h +++ b/src/scenegraph/Node.h @@ -6,103 +6,102 @@ /* * Generic node for the model scenegraph */ -#include "libs.h" #include "RefCounted.h" #include "Serializer.h" #include "graphics/Material.h" #include "graphics/RenderState.h" +#include "libs.h" -namespace Graphics { class Renderer; } - -namespace SceneGraph -{ - -class BaseLoader; -class NodeVisitor; -class NodeCopyCache; -class Model; - -//Node traversal mask - for other -//purposes, use NodeFlags -enum NodeMask { - NODE_SOLID = 0x1, - NODE_TRANSPARENT = 0x2, - MASK_IGNORE = 0x4 -}; - -//misc flags to identify features -enum NodeFlags { - NODE_TAG = 0x1, - NODE_DECAL = 0x2 -}; - -//Small structure used internally to pass rendering data -struct RenderData -{ - float linthrust[3]; // 1.0 to -1.0 - float angthrust[3]; // 1.0 to -1.0 - Color customColor; - - float boundingRadius; //updated by model and passed to submodels - unsigned int nodemask; - - RenderData() - : linthrust() - , angthrust() - , boundingRadius(0.f) - , nodemask(NODE_SOLID) //draw solids - { - } -}; - -//Collection of stuff nodes need for serialization - -//makes maintaining function signatures easier -struct NodeDatabase { - Serializer::Writer *wr; - Serializer::Reader *rd; -// Graphics::Renderer *renderer; - Model *model; - std::vector > > *materials; - BaseLoader *loader; -}; - -class Node : public RefCounted -{ -public: - Node(Graphics::Renderer *r); - Node(Graphics::Renderer *r, unsigned int nodemask); - Node(const Node&, NodeCopyCache*); - virtual Node *Clone(NodeCopyCache*) = 0; //implement clone to return shallow or deep copy - virtual const char *GetTypeName() const { return "Node"; } - virtual void Save(NodeDatabase&); - - virtual void Accept(NodeVisitor &v); - virtual void Traverse(NodeVisitor &v); - virtual void Render(const matrix4x4f &trans, const RenderData *rd) { } - virtual void Render(const std::vector &trans, const RenderData *rd) { } - void DrawAxes(); - void SetName(const std::string &name) { m_name = name; } - const std::string &GetName() const { return m_name; } - - virtual Node* FindNode(const std::string &); - - unsigned int GetNodeMask() const { return m_nodeMask; } - void SetNodeMask(unsigned int m) { m_nodeMask = m; } - - unsigned int GetNodeFlags() const { return m_nodeFlags; } - void SetNodeFlags(unsigned int m) { m_nodeFlags = m; } - - Graphics::Renderer *GetRenderer() const { return m_renderer; } - -protected: - //can only to be deleted using DecRefCount - virtual ~Node(); - std::string m_name; - unsigned int m_nodeMask; - unsigned int m_nodeFlags; - Graphics::Renderer *m_renderer; -}; - +namespace Graphics { + class Renderer; } +namespace SceneGraph { + + class BaseLoader; + class NodeVisitor; + class NodeCopyCache; + class Model; + + //Node traversal mask - for other + //purposes, use NodeFlags + enum NodeMask { + NODE_SOLID = 0x1, + NODE_TRANSPARENT = 0x2, + MASK_IGNORE = 0x4 + }; + + //misc flags to identify features + enum NodeFlags { + NODE_TAG = 0x1, + NODE_DECAL = 0x2 + }; + + //Small structure used internally to pass rendering data + struct RenderData { + float linthrust[3]; // 1.0 to -1.0 + float angthrust[3]; // 1.0 to -1.0 + Color customColor; + + float boundingRadius; //updated by model and passed to submodels + unsigned int nodemask; + + RenderData() : + linthrust(), + angthrust(), + boundingRadius(0.f), + nodemask(NODE_SOLID) //draw solids + { + } + }; + + //Collection of stuff nodes need for serialization - + //makes maintaining function signatures easier + struct NodeDatabase { + Serializer::Writer *wr; + Serializer::Reader *rd; + // Graphics::Renderer *renderer; + Model *model; + std::vector>> *materials; + BaseLoader *loader; + }; + + class Node : public RefCounted { + public: + Node(Graphics::Renderer *r); + Node(Graphics::Renderer *r, unsigned int nodemask); + Node(const Node &, NodeCopyCache *); + virtual Node *Clone(NodeCopyCache *) = 0; //implement clone to return shallow or deep copy + virtual const char *GetTypeName() const { return "Node"; } + virtual void Save(NodeDatabase &); + + virtual void Accept(NodeVisitor &v); + virtual void Traverse(NodeVisitor &v); + virtual void Render(const matrix4x4f &trans, const RenderData *rd) {} + virtual void Render(const std::vector &trans, const RenderData *rd) {} + void DrawAxes(); + void SetName(const std::string &name) { m_name = name; } + const std::string &GetName() const { return m_name; } + + virtual Node *FindNode(const std::string &); + + unsigned int GetNodeMask() const { return m_nodeMask; } + void SetNodeMask(unsigned int m) { m_nodeMask = m; } + + unsigned int GetNodeFlags() const { return m_nodeFlags; } + void SetNodeFlags(unsigned int m) { m_nodeFlags = m; } + + Graphics::Renderer *GetRenderer() const { return m_renderer; } + + protected: + //can only to be deleted using DecRefCount + virtual ~Node(); + std::string m_name; + unsigned int m_nodeMask; + unsigned int m_nodeFlags; + Graphics::Renderer *m_renderer; + }; + +} // namespace SceneGraph + #endif diff --git a/src/scenegraph/NodeCopyCache.h b/src/scenegraph/NodeCopyCache.h index accf7649b..445155ba7 100644 --- a/src/scenegraph/NodeCopyCache.h +++ b/src/scenegraph/NodeCopyCache.h @@ -9,27 +9,29 @@ namespace SceneGraph { -class Node; + class Node; -class NodeCopyCache { -public: - template T *Copy(const T *origNode) { - const bool doCache = origNode->GetRefCount() > 1; - if (doCache) { - std::map::const_iterator i = m_cache.find(origNode); - if (i != m_cache.end()) - return static_cast((*i).second); + class NodeCopyCache { + public: + template + T *Copy(const T *origNode) + { + const bool doCache = origNode->GetRefCount() > 1; + if (doCache) { + std::map::const_iterator i = m_cache.find(origNode); + if (i != m_cache.end()) + return static_cast((*i).second); + } + T *newNode = new T(*origNode, this); + if (doCache) + m_cache.insert(std::make_pair(origNode, newNode)); + return newNode; } - T *newNode = new T(*origNode, this); - if (doCache) - m_cache.insert(std::make_pair(origNode, newNode)); - return newNode; - } -private: - std::map m_cache; -}; + private: + std::map m_cache; + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/NodeVisitor.cpp b/src/scenegraph/NodeVisitor.cpp index cfa63a312..127dd727f 100644 --- a/src/scenegraph/NodeVisitor.cpp +++ b/src/scenegraph/NodeVisitor.cpp @@ -5,8 +5,8 @@ #include "Billboard.h" #include "CollisionGeometry.h" #include "Group.h" -#include "Label3D.h" #include "LOD.h" +#include "Label3D.h" #include "MatrixTransform.h" #include "Node.h" #include "StaticGeometry.h" @@ -14,49 +14,49 @@ namespace SceneGraph { -void NodeVisitor::ApplyNode(Node &n) -{ - n.Traverse(*this); -} + void NodeVisitor::ApplyNode(Node &n) + { + n.Traverse(*this); + } -void NodeVisitor::ApplyGroup(Group &g) -{ - ApplyNode(static_cast(g)); -} + void NodeVisitor::ApplyGroup(Group &g) + { + ApplyNode(static_cast(g)); + } -void NodeVisitor::ApplyStaticGeometry(StaticGeometry &g) -{ - ApplyNode(static_cast(g)); -} + void NodeVisitor::ApplyStaticGeometry(StaticGeometry &g) + { + ApplyNode(static_cast(g)); + } -void NodeVisitor::ApplyLabel(Label3D &l) -{ - ApplyNode(static_cast(l)); -} + void NodeVisitor::ApplyLabel(Label3D &l) + { + ApplyNode(static_cast(l)); + } -void NodeVisitor::ApplyMatrixTransform(MatrixTransform &m) -{ - ApplyGroup(static_cast(m)); -} + void NodeVisitor::ApplyMatrixTransform(MatrixTransform &m) + { + ApplyGroup(static_cast(m)); + } -void NodeVisitor::ApplyBillboard(Billboard &b) -{ - ApplyNode(static_cast(b)); -} + void NodeVisitor::ApplyBillboard(Billboard &b) + { + ApplyNode(static_cast(b)); + } -void NodeVisitor::ApplyThruster(Thruster &t) -{ - ApplyNode(static_cast(t)); -} + void NodeVisitor::ApplyThruster(Thruster &t) + { + ApplyNode(static_cast(t)); + } -void NodeVisitor::ApplyLOD(LOD &l) -{ - ApplyGroup(static_cast(l)); -} + void NodeVisitor::ApplyLOD(LOD &l) + { + ApplyGroup(static_cast(l)); + } -void NodeVisitor::ApplyCollisionGeometry(CollisionGeometry &g) -{ - ApplyNode(static_cast(g)); -} + void NodeVisitor::ApplyCollisionGeometry(CollisionGeometry &g) + { + ApplyNode(static_cast(g)); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/NodeVisitor.h b/src/scenegraph/NodeVisitor.h index 6f701f0c7..2c3e3f481 100644 --- a/src/scenegraph/NodeVisitor.h +++ b/src/scenegraph/NodeVisitor.h @@ -13,30 +13,29 @@ namespace SceneGraph { -class Billboard; -class CollisionGeometry; -class Group; -class Label3D; -class LOD; -class MatrixTransform; -class Node; -class StaticGeometry; -class Thruster; + class Billboard; + class CollisionGeometry; + class Group; + class Label3D; + class LOD; + class MatrixTransform; + class Node; + class StaticGeometry; + class Thruster; -class NodeVisitor -{ -public: - virtual ~NodeVisitor() { } - virtual void ApplyNode(Node&); - virtual void ApplyGroup(Group&); - virtual void ApplyStaticGeometry(StaticGeometry&); - virtual void ApplyLabel(Label3D&); - virtual void ApplyMatrixTransform(MatrixTransform&); - virtual void ApplyBillboard(Billboard&); - virtual void ApplyThruster(Thruster&); - virtual void ApplyLOD(LOD&); - virtual void ApplyCollisionGeometry(CollisionGeometry&); -}; + class NodeVisitor { + public: + virtual ~NodeVisitor() {} + virtual void ApplyNode(Node &); + virtual void ApplyGroup(Group &); + virtual void ApplyStaticGeometry(StaticGeometry &); + virtual void ApplyLabel(Label3D &); + virtual void ApplyMatrixTransform(MatrixTransform &); + virtual void ApplyBillboard(Billboard &); + virtual void ApplyThruster(Thruster &); + virtual void ApplyLOD(LOD &); + virtual void ApplyCollisionGeometry(CollisionGeometry &); + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Parser.cpp b/src/scenegraph/Parser.cpp index 1fc793375..a6c37eb5c 100644 --- a/src/scenegraph/Parser.cpp +++ b/src/scenegraph/Parser.cpp @@ -9,229 +9,229 @@ namespace SceneGraph { -bool LodSortPredicate(const LodDefinition &a, const LodDefinition &b) -{ - return a.pixelSize < b.pixelSize; -} - -Parser::Parser(FileSystem::FileSource &fs, const std::string &filename, const std::string &path) -: m_isMaterial(false) -, m_curMat(0) -, m_model(0) -, m_path(path) -{ - RefCountedPtr data = fs.ReadFile(filename); - if (!data) throw ParseError("Could not open"); - m_file = data; -} - -void Parser::Parse(ModelDefinition *m) -{ - PROFILE_SCOPED() - StringRange buffer = m_file->AsStringRange(); - buffer = buffer.StripUTF8BOM(); - - m_model = m; - int lineno = 0; - while (!buffer.Empty()) { - lineno++; - StringRange line = buffer.ReadLine(); - try { - if (!parseLine(line.ToString())) - throw ParseError("Mystery fail"); - } catch (ParseError &err) { - std::stringstream ss; - ss << "Error parsing line " << lineno << ":" << std::endl; - ss << line.ToString() << std::endl; - ss << err.what(); - throw ParseError(ss.str()); - } + bool LodSortPredicate(const LodDefinition &a, const LodDefinition &b) + { + return a.pixelSize < b.pixelSize; } - if (m->lodDefs.empty() || m->lodDefs.back().meshNames.empty()) - throw ParseError("No meshes defined"); + Parser::Parser(FileSystem::FileSource &fs, const std::string &filename, const std::string &path) : + m_isMaterial(false), + m_curMat(0), + m_model(0), + m_path(path) + { + RefCountedPtr data = fs.ReadFile(filename); + if (!data) throw ParseError("Could not open"); + m_file = data; + } - //model without materials is not very useful, but not fatal - add white default mat - if (m->matDefs.empty()) - m->matDefs.push_back(MaterialDefinition("Default")); + void Parser::Parse(ModelDefinition *m) + { + PROFILE_SCOPED() + StringRange buffer = m_file->AsStringRange(); + buffer = buffer.StripUTF8BOM(); - //sort lods by feature size - std::sort(m->lodDefs.begin(), m->lodDefs.end(), LodSortPredicate); -} - -bool Parser::isComment(const std::string &s) { - assert(!s.empty()); - return (s[0] == '#'); -} - -//check if string matches completely -bool Parser::match(const std::string &s, const std::string &what) -{ - return (s.compare(what) == 0); -} - -//check for a string, but don't accept comments -bool Parser::checkString(std::stringstream &ss, std::string &out, const std::string &what) -{ - if (!(ss >> out)) throw ParseError(stringf("Expected %0, got nothing", what)); - if (isComment(out)) throw ParseError(stringf("Expected %0, got comment", what)); - return true; -} - -bool Parser::checkTexture(std::stringstream &ss, std::string &out) -{ - checkString(ss, out, "file name"); - //add newmodels/some_model/ to path - out = FileSystem::JoinPathBelow(m_path, out); - return true; -} - -inline bool Parser::checkMesh(std::stringstream &ss, std::string &out) -{ - return checkTexture(ss, out); -} - -inline bool Parser::checkMaterialName(std::stringstream &ss, std::string &out) -{ - return checkString(ss, out, "material name"); -} - -bool Parser::checkColor(std::stringstream &ss, Color &color) -{ - float r, g, b; - ss >> r >> g >> b; - color.r = Clamp(r, 0.f, 1.f) * 255; - color.g = Clamp(g, 0.f, 1.f) * 255; - color.b = Clamp(b, 0.f, 1.f) * 255; - color.a = 255; //alpha comes from opacity statement - return true; -} - -bool Parser::parseLine(const std::string &line) -{ - PROFILE_SCOPED() - using std::stringstream; - using std::string; - stringstream ss(stringstream::in | stringstream::out); - ss.str(line); - if (ss.fail()) throw ParseError("Stringstream failure"); - string token; - if (ss >> token) { - //line contains something - if (isComment(token)) - return true; //skip comments - if (match(token, "material")) { - //beginning of a new material definition, - //expect a name and then parameters on following lines - m_isMaterial = true; - string matname; - checkMaterialName(ss, matname); - m_model->matDefs.push_back(MaterialDefinition(matname)); - m_curMat = &m_model->matDefs.back(); - return true; - } else if(match(token, "lod")) { - endMaterial(); - float featuresize; - if (!(ss >> featuresize)) - throw ParseError("Detail level must specify a pixel size"); - if (is_zero_general(featuresize)) - throw ParseError("Detail level pixel size must be greater than 0"); - m_model->lodDefs.push_back(LodDefinition(featuresize)); - return true; - } else if(match(token, "mesh")) { - //mesh definitionss only contain a filename - endMaterial(); - string meshname; - checkMesh(ss, meshname); - //model might not have specified lods at all. - if (m_model->lodDefs.empty()) { - m_model->lodDefs.push_back(LodDefinition(100.f)); + m_model = m; + int lineno = 0; + while (!buffer.Empty()) { + lineno++; + StringRange line = buffer.ReadLine(); + try { + if (!parseLine(line.ToString())) + throw ParseError("Mystery fail"); + } catch (ParseError &err) { + std::stringstream ss; + ss << "Error parsing line " << lineno << ":" << std::endl; + ss << line.ToString() << std::endl; + ss << err.what(); + throw ParseError(ss.str()); } - m_model->lodDefs.back().meshNames.push_back(meshname); - return true; - } else if(match(token, "collision")) { - //collision mesh definitions contain also only a filename - endMaterial(); - string cmeshname; - checkMesh(ss, cmeshname); - m_model->collisionDefs.push_back(cmeshname); - return true; - } else if(match(token, "anim")) { - //anims should only affect the previously defined mesh but eh - if (m_isMaterial || m_model->lodDefs.empty() || m_model->lodDefs.back().meshNames.empty()) - throw ParseError("Animation definition must come after a mesh definition"); - std::string animName; - double startFrame; - double endFrame; - bool loopMode = false; - std::string loop; - checkString(ss, animName, "animation name"); - if (!(ss >> startFrame)) - throw ParseError("Animation start frame not defined"); - if (!(ss >> endFrame)) - throw ParseError("Animation end frame not defined"); - if (ss >> loop && match(loop, "loop")) - loopMode = true; - if (startFrame < 0 || endFrame < startFrame) - throw ParseError("Animation start/end frames seem wrong"); - m_model->animDefs.push_back(AnimDefinition(animName, startFrame, endFrame, loopMode)); - return true; - } else { - if (m_isMaterial) { - //material definition in progress, check known parameters - if (match(token, "tex_diff")) - return checkTexture(ss, m_curMat->tex_diff); - else if (match(token, "tex_spec")) - return checkTexture(ss, m_curMat->tex_spec); - else if (match(token, "tex_glow")) - return checkTexture(ss, m_curMat->tex_glow); - else if (match(token, "tex_ambi")) - return checkTexture(ss, m_curMat->tex_ambi); - else if (match(token, "tex_norm")) - return checkTexture(ss, m_curMat->tex_norm); - else if (match(token, "diffuse")) - return checkColor(ss, m_curMat->diffuse); - else if (match(token, "specular")) - return checkColor(ss, m_curMat->specular); - else if (match(token, "ambient")) - return checkColor(ss, m_curMat->ambient); - else if (match(token, "emissive")) - return checkColor(ss, m_curMat->emissive); - else if (match(token, "shininess")) { - int shininess; - ss >> shininess; - m_curMat->shininess = Clamp(shininess, 0, 128); - return true; - } else if (match(token, "opacity")) { - int opacity; - ss >> opacity; - m_curMat->opacity = Clamp(opacity, 0, 100); - return true; - } else if (match(token, "alpha_test")) { - m_curMat->alpha_test = true; - return true; - } else if (match(token, "unlit")) { - m_curMat->unlit = true; - return true; - } else if (match(token, "use_patterns")) { - m_curMat->use_pattern = true; - return true; - } - else - throw ParseError("Unknown instruction"); - } - throw ParseError("Unknown instruction"); } - } else { - //empty line, skip + + if (m->lodDefs.empty() || m->lodDefs.back().meshNames.empty()) + throw ParseError("No meshes defined"); + + //model without materials is not very useful, but not fatal - add white default mat + if (m->matDefs.empty()) + m->matDefs.push_back(MaterialDefinition("Default")); + + //sort lods by feature size + std::sort(m->lodDefs.begin(), m->lodDefs.end(), LodSortPredicate); + } + + bool Parser::isComment(const std::string &s) + { + assert(!s.empty()); + return (s[0] == '#'); + } + + //check if string matches completely + bool Parser::match(const std::string &s, const std::string &what) + { + return (s.compare(what) == 0); + } + + //check for a string, but don't accept comments + bool Parser::checkString(std::stringstream &ss, std::string &out, const std::string &what) + { + if (!(ss >> out)) throw ParseError(stringf("Expected %0, got nothing", what)); + if (isComment(out)) throw ParseError(stringf("Expected %0, got comment", what)); return true; } -} -void Parser::endMaterial() -{ - m_isMaterial = false; - m_curMat = 0; -} + bool Parser::checkTexture(std::stringstream &ss, std::string &out) + { + checkString(ss, out, "file name"); + //add newmodels/some_model/ to path + out = FileSystem::JoinPathBelow(m_path, out); + return true; + } -} + inline bool Parser::checkMesh(std::stringstream &ss, std::string &out) + { + return checkTexture(ss, out); + } + + inline bool Parser::checkMaterialName(std::stringstream &ss, std::string &out) + { + return checkString(ss, out, "material name"); + } + + bool Parser::checkColor(std::stringstream &ss, Color &color) + { + float r, g, b; + ss >> r >> g >> b; + color.r = Clamp(r, 0.f, 1.f) * 255; + color.g = Clamp(g, 0.f, 1.f) * 255; + color.b = Clamp(b, 0.f, 1.f) * 255; + color.a = 255; //alpha comes from opacity statement + return true; + } + + bool Parser::parseLine(const std::string &line) + { + PROFILE_SCOPED() + using std::string; + using std::stringstream; + stringstream ss(stringstream::in | stringstream::out); + ss.str(line); + if (ss.fail()) throw ParseError("Stringstream failure"); + string token; + if (ss >> token) { + //line contains something + if (isComment(token)) + return true; //skip comments + if (match(token, "material")) { + //beginning of a new material definition, + //expect a name and then parameters on following lines + m_isMaterial = true; + string matname; + checkMaterialName(ss, matname); + m_model->matDefs.push_back(MaterialDefinition(matname)); + m_curMat = &m_model->matDefs.back(); + return true; + } else if (match(token, "lod")) { + endMaterial(); + float featuresize; + if (!(ss >> featuresize)) + throw ParseError("Detail level must specify a pixel size"); + if (is_zero_general(featuresize)) + throw ParseError("Detail level pixel size must be greater than 0"); + m_model->lodDefs.push_back(LodDefinition(featuresize)); + return true; + } else if (match(token, "mesh")) { + //mesh definitionss only contain a filename + endMaterial(); + string meshname; + checkMesh(ss, meshname); + //model might not have specified lods at all. + if (m_model->lodDefs.empty()) { + m_model->lodDefs.push_back(LodDefinition(100.f)); + } + m_model->lodDefs.back().meshNames.push_back(meshname); + return true; + } else if (match(token, "collision")) { + //collision mesh definitions contain also only a filename + endMaterial(); + string cmeshname; + checkMesh(ss, cmeshname); + m_model->collisionDefs.push_back(cmeshname); + return true; + } else if (match(token, "anim")) { + //anims should only affect the previously defined mesh but eh + if (m_isMaterial || m_model->lodDefs.empty() || m_model->lodDefs.back().meshNames.empty()) + throw ParseError("Animation definition must come after a mesh definition"); + std::string animName; + double startFrame; + double endFrame; + bool loopMode = false; + std::string loop; + checkString(ss, animName, "animation name"); + if (!(ss >> startFrame)) + throw ParseError("Animation start frame not defined"); + if (!(ss >> endFrame)) + throw ParseError("Animation end frame not defined"); + if (ss >> loop && match(loop, "loop")) + loopMode = true; + if (startFrame < 0 || endFrame < startFrame) + throw ParseError("Animation start/end frames seem wrong"); + m_model->animDefs.push_back(AnimDefinition(animName, startFrame, endFrame, loopMode)); + return true; + } else { + if (m_isMaterial) { + //material definition in progress, check known parameters + if (match(token, "tex_diff")) + return checkTexture(ss, m_curMat->tex_diff); + else if (match(token, "tex_spec")) + return checkTexture(ss, m_curMat->tex_spec); + else if (match(token, "tex_glow")) + return checkTexture(ss, m_curMat->tex_glow); + else if (match(token, "tex_ambi")) + return checkTexture(ss, m_curMat->tex_ambi); + else if (match(token, "tex_norm")) + return checkTexture(ss, m_curMat->tex_norm); + else if (match(token, "diffuse")) + return checkColor(ss, m_curMat->diffuse); + else if (match(token, "specular")) + return checkColor(ss, m_curMat->specular); + else if (match(token, "ambient")) + return checkColor(ss, m_curMat->ambient); + else if (match(token, "emissive")) + return checkColor(ss, m_curMat->emissive); + else if (match(token, "shininess")) { + int shininess; + ss >> shininess; + m_curMat->shininess = Clamp(shininess, 0, 128); + return true; + } else if (match(token, "opacity")) { + int opacity; + ss >> opacity; + m_curMat->opacity = Clamp(opacity, 0, 100); + return true; + } else if (match(token, "alpha_test")) { + m_curMat->alpha_test = true; + return true; + } else if (match(token, "unlit")) { + m_curMat->unlit = true; + return true; + } else if (match(token, "use_patterns")) { + m_curMat->use_pattern = true; + return true; + } else + throw ParseError("Unknown instruction"); + } + throw ParseError("Unknown instruction"); + } + } else { + //empty line, skip + return true; + } + } + + void Parser::endMaterial() + { + m_isMaterial = false; + m_curMat = 0; + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Parser.h b/src/scenegraph/Parser.h index 5c35eb6e0..1883ee8f9 100644 --- a/src/scenegraph/Parser.h +++ b/src/scenegraph/Parser.h @@ -7,41 +7,41 @@ * Newmodel .model config file parser. * It's pretty bad, someone please redesign. */ -#include "Loader.h" #include "FileSystem.h" +#include "Loader.h" #include namespace SceneGraph { -struct ParseError : public std::runtime_error { - ParseError(const std::string &str) : std::runtime_error(str.c_str()) { } -}; + struct ParseError : public std::runtime_error { + ParseError(const std::string &str) : + std::runtime_error(str.c_str()) {} + }; -class Parser -{ -public: - Parser(FileSystem::FileSource &, const std::string &filename, const std::string &path); + class Parser { + public: + Parser(FileSystem::FileSource &, const std::string &filename, const std::string &path); - void Parse(ModelDefinition *m); + void Parse(ModelDefinition *m); -private: - bool m_isMaterial; - MaterialDefinition *m_curMat; - ModelDefinition *m_model; - RefCountedPtr m_file; - std::string m_path; + private: + bool m_isMaterial; + MaterialDefinition *m_curMat; + ModelDefinition *m_model; + RefCountedPtr m_file; + std::string m_path; - bool checkColor(std::stringstream &ss, Color &color); - bool checkString(std::stringstream &ss, std::string &out, const std::string &what); - bool checkTexture(std::stringstream &ss, std::string &out); - bool isComment(const std::string &s); - bool match(const std::string &s, const std::string &what); - bool parseLine(const std::string &line); - inline bool checkMaterialName(std::stringstream &ss, std::string &out); - inline bool checkMesh(std::stringstream &ss, std::string &out); - void endMaterial(); -}; + bool checkColor(std::stringstream &ss, Color &color); + bool checkString(std::stringstream &ss, std::string &out, const std::string &what); + bool checkTexture(std::stringstream &ss, std::string &out); + bool isComment(const std::string &s); + bool match(const std::string &s, const std::string &what); + bool parseLine(const std::string &line); + inline bool checkMaterialName(std::stringstream &ss, std::string &out); + inline bool checkMesh(std::stringstream &ss, std::string &out); + void endMaterial(); + }; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Pattern.cpp b/src/scenegraph/Pattern.cpp index 90ded564b..bb8735641 100644 --- a/src/scenegraph/Pattern.cpp +++ b/src/scenegraph/Pattern.cpp @@ -8,31 +8,31 @@ namespace SceneGraph { -Pattern::Pattern() -: smoothColor(false) -, smoothPattern(false) -, name("") -{ -} + Pattern::Pattern() : + smoothColor(false), + smoothPattern(false), + name("") + { + } -Pattern::Pattern(const std::string &name_, const std::string& path, Graphics::Renderer* r) -: smoothColor(false) -, smoothPattern(true) -, name(name_) -{ - //load as a pattern, allowed: - //patternNN.png - //patternNN_n.png - //patternNN_n_s.png - //s = smooth (default for pattern) - //n = nearest (default for color) - if (name.length() >= 11 && name.compare(10,1, "n") == 0) smoothPattern = false; - if (name.length() >= 13 && name.compare(12,1, "s") == 0) smoothColor = true; + Pattern::Pattern(const std::string &name_, const std::string &path, Graphics::Renderer *r) : + smoothColor(false), + smoothPattern(true), + name(name_) + { + //load as a pattern, allowed: + //patternNN.png + //patternNN_n.png + //patternNN_n_s.png + //s = smooth (default for pattern) + //n = nearest (default for color) + if (name.length() >= 11 && name.compare(10, 1, "n") == 0) smoothPattern = false; + if (name.length() >= 13 && name.compare(12, 1, "s") == 0) smoothColor = true; - const std::string patternPath = FileSystem::JoinPathBelow(path, name); + const std::string patternPath = FileSystem::JoinPathBelow(path, name); - Graphics::TextureSampleMode sampleMode = smoothPattern ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP; - texture.Reset(Graphics::TextureBuilder(patternPath, sampleMode, true, true, false).GetOrCreateTexture(r,std::string("pattern"))); -} + Graphics::TextureSampleMode sampleMode = smoothPattern ? Graphics::LINEAR_CLAMP : Graphics::NEAREST_CLAMP; + texture.Reset(Graphics::TextureBuilder(patternPath, sampleMode, true, true, false).GetOrCreateTexture(r, std::string("pattern"))); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/Pattern.h b/src/scenegraph/Pattern.h index bcfa5b1df..ffcffd458 100644 --- a/src/scenegraph/Pattern.h +++ b/src/scenegraph/Pattern.h @@ -9,27 +9,27 @@ * and accompanied by a tiny runtime generated gradient texture * with 2-3 colours */ -#include "libs.h" #include "SmartPtr.h" +#include "libs.h" namespace Graphics { class Texture; class Renderer; -} +} // namespace Graphics namespace SceneGraph { -struct Pattern { - bool smoothColor; - bool smoothPattern; - RefCountedPtr texture; - std::string name; + struct Pattern { + bool smoothColor; + bool smoothPattern; + RefCountedPtr texture; + std::string name; - Pattern(); - Pattern(const std::string &name, const std::string& path, Graphics::Renderer* r); -}; + Pattern(); + Pattern(const std::string &name, const std::string &path, Graphics::Renderer *r); + }; -typedef std::vector PatternContainer; + typedef std::vector PatternContainer; -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/SceneGraph.h b/src/scenegraph/SceneGraph.h index c5f0719ef..77a05307d 100644 --- a/src/scenegraph/SceneGraph.h +++ b/src/scenegraph/SceneGraph.h @@ -4,11 +4,11 @@ //this file includes common headers #ifndef _SCENEGRAPH_H #define _SCENEGRAPH_H -#include "Model.h" #include "Billboard.h" #include "Label3D.h" #include "Loader.h" #include "MatrixTransform.h" +#include "Model.h" #include "ModelNode.h" #include "StaticGeometry.h" #include "Thruster.h" diff --git a/src/scenegraph/StaticGeometry.cpp b/src/scenegraph/StaticGeometry.cpp index 09345711b..6dae25dcb 100644 --- a/src/scenegraph/StaticGeometry.cpp +++ b/src/scenegraph/StaticGeometry.cpp @@ -2,388 +2,380 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "StaticGeometry.h" -#include "NodeVisitor.h" -#include "Model.h" #include "BaseLoader.h" +#include "Model.h" +#include "NodeVisitor.h" #include "graphics/Graphics.h" -#include "graphics/Renderer.h" #include "graphics/Material.h" +#include "graphics/Renderer.h" #include "utils.h" namespace SceneGraph { -StaticGeometry::StaticGeometry(Graphics::Renderer *r) -: Node(r, NODE_SOLID) -, m_blendMode(Graphics::BLEND_SOLID) -, m_renderState(nullptr) -{ -} - -StaticGeometry::~StaticGeometry() -{ -} - -StaticGeometry::StaticGeometry(const StaticGeometry &sg, NodeCopyCache *cache) -: Node(sg, cache) -, m_boundingBox(sg.m_boundingBox) -, m_blendMode(sg.m_blendMode) -, m_meshes(sg.m_meshes) -, m_renderState(sg.m_renderState) -{ -} - -Node* StaticGeometry::Clone(NodeCopyCache *cache) -{ - return this; //geometries are shared -} - -void StaticGeometry::Accept(NodeVisitor &nv) -{ - nv.ApplyStaticGeometry(*this); -} - -void StaticGeometry::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - SDL_assert(m_renderState); - Graphics::Renderer *r = GetRenderer(); - r->SetTransform(trans); - for (auto& it : m_meshes) - r->DrawBufferIndexed(it.vertexBuffer.Get(), it.indexBuffer.Get(), m_renderState, it.material.Get()); - - //DrawBoundingBox(m_boundingBox); -} - -void StaticGeometry::Render(const std::vector &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - SDL_assert(m_renderState); - Graphics::Renderer *r = GetRenderer(); - - const size_t numTrans = trans.size(); - if (!m_instBuffer.Valid() || (numTrans > m_instBuffer->GetSize())) + StaticGeometry::StaticGeometry(Graphics::Renderer *r) : + Node(r, NODE_SOLID), + m_blendMode(Graphics::BLEND_SOLID), + m_renderState(nullptr) { - // create the InstanceBuffer with the maximum number of transformations we might use within it. - m_instBuffer.Reset( r->CreateInstanceBuffer(numTrans, Graphics::BUFFER_USAGE_DYNAMIC) ); } - // Update the InstanceBuffer data - Graphics::InstanceBuffer* ib = m_instBuffer.Get(); - matrix4x4f *pBuffer = ib->Map(Graphics::BUFFER_MAP_WRITE); - if(pBuffer) { - // Copy the transforms into the buffer - for(const matrix4x4f &mt : trans) { - (*pBuffer) = mt; - ++pBuffer; + StaticGeometry::~StaticGeometry() + { + } + + StaticGeometry::StaticGeometry(const StaticGeometry &sg, NodeCopyCache *cache) : + Node(sg, cache), + m_boundingBox(sg.m_boundingBox), + m_blendMode(sg.m_blendMode), + m_meshes(sg.m_meshes), + m_renderState(sg.m_renderState) + { + } + + Node *StaticGeometry::Clone(NodeCopyCache *cache) + { + return this; //geometries are shared + } + + void StaticGeometry::Accept(NodeVisitor &nv) + { + nv.ApplyStaticGeometry(*this); + } + + void StaticGeometry::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + SDL_assert(m_renderState); + Graphics::Renderer *r = GetRenderer(); + r->SetTransform(trans); + for (auto &it : m_meshes) + r->DrawBufferIndexed(it.vertexBuffer.Get(), it.indexBuffer.Get(), m_renderState, it.material.Get()); + + //DrawBoundingBox(m_boundingBox); + } + + void StaticGeometry::Render(const std::vector &trans, const RenderData *rd) + { + PROFILE_SCOPED() + SDL_assert(m_renderState); + Graphics::Renderer *r = GetRenderer(); + + const size_t numTrans = trans.size(); + if (!m_instBuffer.Valid() || (numTrans > m_instBuffer->GetSize())) { + // create the InstanceBuffer with the maximum number of transformations we might use within it. + m_instBuffer.Reset(r->CreateInstanceBuffer(numTrans, Graphics::BUFFER_USAGE_DYNAMIC)); } - ib->Unmap(); - ib->SetInstanceCount(numTrans); - } - // we'll set the transformation within the vertex shader so identity the global one - r->SetTransform(matrix4x4f::Identity()); + // Update the InstanceBuffer data + Graphics::InstanceBuffer *ib = m_instBuffer.Get(); + matrix4x4f *pBuffer = ib->Map(Graphics::BUFFER_MAP_WRITE); + if (pBuffer) { + // Copy the transforms into the buffer + for (const matrix4x4f &mt : trans) { + (*pBuffer) = mt; + ++pBuffer; + } + ib->Unmap(); + ib->SetInstanceCount(numTrans); + } + + // we'll set the transformation within the vertex shader so identity the global one + r->SetTransform(matrix4x4f::Identity()); + + if (m_instanceMaterials.empty()) { + // process each mesh + for (auto &it : m_meshes) { + // Due to the shader needing to change we have to get the material and force it to the instanced variant + Graphics::MaterialDescriptor mdesc = it.material->GetDescriptor(); + mdesc.instanced = true; + // create the "new" material with the instanced description + RefCountedPtr mat(r->CreateMaterial(mdesc)); + // copy over all of the other details + mat->texture0 = it.material->texture0; + mat->texture1 = it.material->texture1; + mat->texture2 = it.material->texture2; + mat->texture3 = it.material->texture3; + mat->texture4 = it.material->texture4; + mat->texture5 = it.material->texture5; + mat->texture6 = it.material->texture5; + mat->heatGradient = it.material->heatGradient; + mat->diffuse = it.material->diffuse; + mat->specular = it.material->specular; + mat->emissive = it.material->emissive; + mat->shininess = it.material->shininess; + mat->specialParameter0 = it.material->specialParameter0; + m_instanceMaterials.push_back(mat); + } + } - if(m_instanceMaterials.empty()) { // process each mesh - for (auto& it : m_meshes) { - // Due to the shader needing to change we have to get the material and force it to the instanced variant - Graphics::MaterialDescriptor mdesc = it.material->GetDescriptor(); - mdesc.instanced = true; - // create the "new" material with the instanced description - RefCountedPtr mat(r->CreateMaterial(mdesc)); - // copy over all of the other details - mat->texture0 = it.material->texture0; - mat->texture1 = it.material->texture1; - mat->texture2 = it.material->texture2; - mat->texture3 = it.material->texture3; - mat->texture4 = it.material->texture4; - mat->texture5 = it.material->texture5; - mat->texture6 = it.material->texture5; - mat->heatGradient = it.material->heatGradient; - mat->diffuse = it.material->diffuse; - mat->specular = it.material->specular; - mat->emissive = it.material->emissive; - mat->shininess = it.material->shininess; - mat->specialParameter0 = it.material->specialParameter0; - m_instanceMaterials.push_back(mat); + int i = 0; + for (auto &it : m_meshes) { + // finally render using the instance material + r->DrawBufferIndexedInstanced(it.vertexBuffer.Get(), it.indexBuffer.Get(), m_renderState, m_instanceMaterials[i].Get(), m_instBuffer.Get()); + ++i; } } - // process each mesh - int i=0; - for (auto& it : m_meshes) { - // finally render using the instance material - r->DrawBufferIndexedInstanced(it.vertexBuffer.Get(), it.indexBuffer.Get(), m_renderState, m_instanceMaterials[i].Get(), m_instBuffer.Get()); - ++i; + typedef std::vector>> MaterialContainer; + void StaticGeometry::Save(NodeDatabase &db) + { + Node::Save(db); + db.wr->Int32(m_blendMode); + db.wr->Vector3d(m_boundingBox.min); + db.wr->Vector3d(m_boundingBox.max); + + db.wr->Int32(m_meshes.size()); + + for (auto mesh : m_meshes) { + //do ptr to material name mapping + const std::string &matname = db.model->GetNameForMaterial(mesh.material.Get()); + db.wr->String(matname); + + //save vertex attrib description + const auto &vbDesc = mesh.vertexBuffer->GetDesc(); + Uint32 attribCombo = 0; + for (Uint32 i = 0; i < Graphics::MAX_ATTRIBS; i++) + attribCombo |= vbDesc.attrib[i].semantic; + + db.wr->Int32(attribCombo); + + const bool hasTangents = (attribCombo & Graphics::ATTRIB_TANGENT); + + //save positions, normals and uvs interleaved (only known format now) + const Uint32 posOffset = vbDesc.GetOffset(Graphics::ATTRIB_POSITION); + const Uint32 nrmOffset = vbDesc.GetOffset(Graphics::ATTRIB_NORMAL); + const Uint32 uv0Offset = vbDesc.GetOffset(Graphics::ATTRIB_UV0); + const Uint32 tanOffset = hasTangents ? vbDesc.GetOffset(Graphics::ATTRIB_TANGENT) : 0; + const Uint32 stride = vbDesc.stride; + db.wr->Int32(vbDesc.numVertices); + Uint8 *vtxPtr = mesh.vertexBuffer->Map(Graphics::BUFFER_MAP_READ); + if (hasTangents) { + for (Uint32 i = 0; i < vbDesc.numVertices; i++) { + db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + posOffset)); + db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + nrmOffset)); + db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->x); + db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->y); + db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + tanOffset)); + } + } else { + for (Uint32 i = 0; i < vbDesc.numVertices; i++) { + db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + posOffset)); + db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + nrmOffset)); + db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->x); + db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->y); + } + } + mesh.vertexBuffer->Unmap(); + + //indices + const Uint32 *indexPtr = mesh.indexBuffer->Map(Graphics::BUFFER_MAP_READ); + const Uint32 numIndices = mesh.indexBuffer->GetSize(); + db.wr->Int32(numIndices); + for (Uint32 i = 0; i < numIndices; i++) + db.wr->Int32(indexPtr[i]); + mesh.indexBuffer->Unmap(); + } } -} -typedef std::vector > > MaterialContainer; -void StaticGeometry::Save(NodeDatabase &db) -{ - Node::Save(db); - db.wr->Int32(m_blendMode); - db.wr->Vector3d(m_boundingBox.min); - db.wr->Vector3d(m_boundingBox.max); + StaticGeometry *StaticGeometry::Load(NodeDatabase &db) + { + using namespace Graphics; - db.wr->Int32(m_meshes.size()); + StaticGeometry *sg = new StaticGeometry(db.loader->GetRenderer()); + Serializer::Reader &rd = *db.rd; - for (auto mesh : m_meshes) { - //do ptr to material name mapping - const std::string &matname = db.model->GetNameForMaterial(mesh.material.Get()); - db.wr->String(matname); + sg->m_blendMode = static_cast(rd.Int32()); + sg->m_boundingBox.min = rd.Vector3d(); + sg->m_boundingBox.max = rd.Vector3d(); - //save vertex attrib description - const auto& vbDesc = mesh.vertexBuffer->GetDesc(); - Uint32 attribCombo = 0; - for (Uint32 i = 0; i < Graphics::MAX_ATTRIBS; i++) - attribCombo |= vbDesc.attrib[i].semantic; + Graphics::RenderStateDesc rsd; + rsd.blendMode = sg->m_blendMode; + rsd.depthWrite = rsd.blendMode == Graphics::BLEND_SOLID; + sg->SetRenderState(sg->GetRenderer()->CreateRenderState(rsd)); - db.wr->Int32(attribCombo); + const Uint32 numMeshes = rd.Int32(); + for (Uint32 mesh = 0; mesh < numMeshes; mesh++) { + //material + RefCountedPtr material; + const std::string matName = rd.String(); + if (starts_with(matName, "decal_")) { + const unsigned int di = atoi(matName.substr(6).c_str()); + material = db.loader->GetDecalMaterial(di); + } else + material = db.model->GetMaterialByName(matName); - const bool hasTangents = (attribCombo & Graphics::ATTRIB_TANGENT); - - //save positions, normals and uvs interleaved (only known format now) - const Uint32 posOffset = vbDesc.GetOffset(Graphics::ATTRIB_POSITION); - const Uint32 nrmOffset = vbDesc.GetOffset(Graphics::ATTRIB_NORMAL); - const Uint32 uv0Offset = vbDesc.GetOffset(Graphics::ATTRIB_UV0); - const Uint32 tanOffset = hasTangents ? vbDesc.GetOffset(Graphics::ATTRIB_TANGENT) : 0; - const Uint32 stride = vbDesc.stride; - db.wr->Int32(vbDesc.numVertices); - Uint8 *vtxPtr = mesh.vertexBuffer->Map(Graphics::BUFFER_MAP_READ); - if (hasTangents) - { - for (Uint32 i = 0; i < vbDesc.numVertices; i++) { - db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + posOffset)); - db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + nrmOffset)); - db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->x); - db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->y); - db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + tanOffset)); + //vertex format check + const Uint32 vtxFormat = db.rd->Int32(); + if (vtxFormat != (ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0 | ATTRIB_TANGENT) && vtxFormat != (ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0)) { + throw LoadingError("Unsupported vertex format"); } - } - else - { - for (Uint32 i = 0; i < vbDesc.numVertices; i++) { - db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + posOffset)); - db.wr->Vector3f(*reinterpret_cast(vtxPtr + i * stride + nrmOffset)); - db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->x); - db.wr->Float(reinterpret_cast(vtxPtr + i * stride + uv0Offset)->y); + + const bool hasTangents = (vtxFormat & Graphics::ATTRIB_TANGENT); + + //vertex buffer + Graphics::VertexBufferDesc vbDesc; + vbDesc.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbDesc.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbDesc.attrib[1].semantic = Graphics::ATTRIB_NORMAL; + vbDesc.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbDesc.attrib[2].semantic = Graphics::ATTRIB_UV0; + vbDesc.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; + if (hasTangents) { + vbDesc.attrib[3].semantic = Graphics::ATTRIB_TANGENT; + vbDesc.attrib[3].format = Graphics::ATTRIB_FORMAT_FLOAT3; } - } - mesh.vertexBuffer->Unmap(); + vbDesc.usage = Graphics::BUFFER_USAGE_STATIC; + vbDesc.numVertices = db.rd->Int32(); - //indices - const Uint32 *indexPtr = mesh.indexBuffer->Map(Graphics::BUFFER_MAP_READ); - const Uint32 numIndices = mesh.indexBuffer->GetSize(); - db.wr->Int32(numIndices); - for (Uint32 i = 0; i < numIndices; i++) - db.wr->Int32(indexPtr[i]); - mesh.indexBuffer->Unmap(); - } -} - -StaticGeometry *StaticGeometry::Load(NodeDatabase &db) -{ - using namespace Graphics; - - StaticGeometry *sg = new StaticGeometry(db.loader->GetRenderer()); - Serializer::Reader &rd = *db.rd; - - sg->m_blendMode = static_cast(rd.Int32()); - sg->m_boundingBox.min = rd.Vector3d(); - sg->m_boundingBox.max = rd.Vector3d(); - - Graphics::RenderStateDesc rsd; - rsd.blendMode = sg->m_blendMode; - rsd.depthWrite = rsd.blendMode == Graphics::BLEND_SOLID; - sg->SetRenderState(sg->GetRenderer()->CreateRenderState(rsd)); - - const Uint32 numMeshes = rd.Int32(); - for (Uint32 mesh = 0; mesh < numMeshes; mesh++) { - //material - RefCountedPtr material; - const std::string matName = rd.String(); - if (starts_with(matName, "decal_")) { - const unsigned int di = atoi(matName.substr(6).c_str()); - material = db.loader->GetDecalMaterial(di); - } else - material = db.model->GetMaterialByName(matName); - - //vertex format check - const Uint32 vtxFormat = db.rd->Int32(); - if (vtxFormat != (ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0 | ATTRIB_TANGENT) && vtxFormat != (ATTRIB_POSITION | ATTRIB_NORMAL | ATTRIB_UV0)) - { - throw LoadingError("Unsupported vertex format"); - } - - const bool hasTangents = (vtxFormat & Graphics::ATTRIB_TANGENT); - - //vertex buffer - Graphics::VertexBufferDesc vbDesc; - vbDesc.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbDesc.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbDesc.attrib[1].semantic = Graphics::ATTRIB_NORMAL; - vbDesc.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbDesc.attrib[2].semantic = Graphics::ATTRIB_UV0; - vbDesc.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; - if (hasTangents) { - vbDesc.attrib[3].semantic = Graphics::ATTRIB_TANGENT; - vbDesc.attrib[3].format = Graphics::ATTRIB_FORMAT_FLOAT3; - } - vbDesc.usage = Graphics::BUFFER_USAGE_STATIC; - vbDesc.numVertices = db.rd->Int32(); - - RefCountedPtr vtxBuffer(db.loader->GetRenderer()->CreateVertexBuffer(vbDesc)); - const Uint32 posOffset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_POSITION); - const Uint32 nrmOffset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_NORMAL); - const Uint32 uv0Offset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_UV0); - const Uint32 tanOffset = hasTangents ? vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_TANGENT) : 0; - const Uint32 stride = vtxBuffer->GetDesc().stride; - Uint8 *vtxPtr = vtxBuffer->Map(BUFFER_MAP_WRITE); - if (hasTangents) - { - for (Uint32 i = 0; i < vbDesc.numVertices; i++) { - *reinterpret_cast(vtxPtr + i * stride + posOffset) = db.rd->Vector3f(); - *reinterpret_cast(vtxPtr + i * stride + nrmOffset) = db.rd->Vector3f(); - const float uvx = db.rd->Float(); - const float uvy = db.rd->Float(); - *reinterpret_cast(vtxPtr + i * stride + uv0Offset) = vector2f(uvx, uvy); - *reinterpret_cast(vtxPtr + i * stride + tanOffset) = db.rd->Vector3f(); + RefCountedPtr vtxBuffer(db.loader->GetRenderer()->CreateVertexBuffer(vbDesc)); + const Uint32 posOffset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_POSITION); + const Uint32 nrmOffset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_NORMAL); + const Uint32 uv0Offset = vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_UV0); + const Uint32 tanOffset = hasTangents ? vtxBuffer->GetDesc().GetOffset(Graphics::ATTRIB_TANGENT) : 0; + const Uint32 stride = vtxBuffer->GetDesc().stride; + Uint8 *vtxPtr = vtxBuffer->Map(BUFFER_MAP_WRITE); + if (hasTangents) { + for (Uint32 i = 0; i < vbDesc.numVertices; i++) { + *reinterpret_cast(vtxPtr + i * stride + posOffset) = db.rd->Vector3f(); + *reinterpret_cast(vtxPtr + i * stride + nrmOffset) = db.rd->Vector3f(); + const float uvx = db.rd->Float(); + const float uvy = db.rd->Float(); + *reinterpret_cast(vtxPtr + i * stride + uv0Offset) = vector2f(uvx, uvy); + *reinterpret_cast(vtxPtr + i * stride + tanOffset) = db.rd->Vector3f(); + } + } else { + for (Uint32 i = 0; i < vbDesc.numVertices; i++) { + *reinterpret_cast(vtxPtr + i * stride + posOffset) = db.rd->Vector3f(); + *reinterpret_cast(vtxPtr + i * stride + nrmOffset) = db.rd->Vector3f(); + const float uvx = db.rd->Float(); + const float uvy = db.rd->Float(); + *reinterpret_cast(vtxPtr + i * stride + uv0Offset) = vector2f(uvx, uvy); + } } - } - else - { - for (Uint32 i = 0; i < vbDesc.numVertices; i++) { - *reinterpret_cast(vtxPtr + i * stride + posOffset) = db.rd->Vector3f(); - *reinterpret_cast(vtxPtr + i * stride + nrmOffset) = db.rd->Vector3f(); - const float uvx = db.rd->Float(); - const float uvy = db.rd->Float(); - *reinterpret_cast(vtxPtr + i * stride + uv0Offset) = vector2f(uvx, uvy); - } - } - vtxBuffer->Unmap(); + vtxBuffer->Unmap(); - //index buffer - const Uint32 numIndices = db.rd->Int32(); - RefCountedPtr idxBuffer(db.loader->GetRenderer()->CreateIndexBuffer(numIndices, Graphics::BUFFER_USAGE_STATIC)); - Uint32 *idxPtr = idxBuffer->Map(BUFFER_MAP_WRITE); - for (Uint32 i = 0; i < numIndices; i++) - idxPtr[i] = db.rd->Int32(); - idxBuffer->Unmap(); + //index buffer + const Uint32 numIndices = db.rd->Int32(); + RefCountedPtr idxBuffer(db.loader->GetRenderer()->CreateIndexBuffer(numIndices, Graphics::BUFFER_USAGE_STATIC)); + Uint32 *idxPtr = idxBuffer->Map(BUFFER_MAP_WRITE); + for (Uint32 i = 0; i < numIndices; i++) + idxPtr[i] = db.rd->Int32(); + idxBuffer->Unmap(); - sg->AddMesh(vtxBuffer, idxBuffer, material); + sg->AddMesh(vtxBuffer, idxBuffer, material); + } + return sg; } - return sg; -} -void StaticGeometry::AddMesh( - RefCountedPtr vb, - RefCountedPtr ib, - RefCountedPtr mat) -{ - Mesh m; - m.vertexBuffer = vb; - m.indexBuffer = ib; - m.material = mat; - m_meshes.push_back(m); -} + void StaticGeometry::AddMesh( + RefCountedPtr vb, + RefCountedPtr ib, + RefCountedPtr mat) + { + Mesh m; + m.vertexBuffer = vb; + m.indexBuffer = ib; + m.material = mat; + m_meshes.push_back(m); + } -StaticGeometry::Mesh &StaticGeometry::GetMeshAt(unsigned int i) -{ - return m_meshes.at(i); -} + StaticGeometry::Mesh &StaticGeometry::GetMeshAt(unsigned int i) + { + return m_meshes.at(i); + } -void StaticGeometry::DrawBoundingBox(const Aabb &bb) -{ - const vector3f min(bb.min.x, bb.min.y, bb.min.z); - const vector3f max(bb.max.x, bb.max.y, bb.max.z); - const vector3f fbl(min.x, min.y, min.z); //front bottom left - const vector3f fbr(max.x, min.y, min.z); //front bottom right - const vector3f ftl(min.x, max.y, min.z); //front top left - const vector3f ftr(max.x, max.y, min.z); //front top right - const vector3f rtl(min.x, max.y, max.z); //rear top left - const vector3f rtr(max.x, max.y, max.z); //rear top right - const vector3f rbl(min.x, min.y, max.z); //rear bottom left - const vector3f rbr(max.x, min.y, max.z); //rear bottom right + void StaticGeometry::DrawBoundingBox(const Aabb &bb) + { + const vector3f min(bb.min.x, bb.min.y, bb.min.z); + const vector3f max(bb.max.x, bb.max.y, bb.max.z); + const vector3f fbl(min.x, min.y, min.z); //front bottom left + const vector3f fbr(max.x, min.y, min.z); //front bottom right + const vector3f ftl(min.x, max.y, min.z); //front top left + const vector3f ftr(max.x, max.y, min.z); //front top right + const vector3f rtl(min.x, max.y, max.z); //rear top left + const vector3f rtr(max.x, max.y, max.z); //rear top right + const vector3f rbl(min.x, min.y, max.z); //rear bottom left + const vector3f rbr(max.x, min.y, max.z); //rear bottom right - const Color c(Color::WHITE); + const Color c(Color::WHITE); - std::unique_ptr vts(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE)); + std::unique_ptr vts(new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE)); - //Front face - vts->Add(ftr, c); //3 - vts->Add(fbr, c); //1 - vts->Add(fbl, c); //0 + //Front face + vts->Add(ftr, c); //3 + vts->Add(fbr, c); //1 + vts->Add(fbl, c); //0 - vts->Add(fbl, c); //0 - vts->Add(ftl, c); //2 - vts->Add(ftr, c); //3 + vts->Add(fbl, c); //0 + vts->Add(ftl, c); //2 + vts->Add(ftr, c); //3 - //Rear face - vts->Add(rbr, c); //7 - vts->Add(rtr, c); //5 - vts->Add(rbl, c); //6 + //Rear face + vts->Add(rbr, c); //7 + vts->Add(rtr, c); //5 + vts->Add(rbl, c); //6 - vts->Add(rbl, c); //6 - vts->Add(rtr, c); //5 - vts->Add(rtl, c); //4 + vts->Add(rbl, c); //6 + vts->Add(rtr, c); //5 + vts->Add(rtl, c); //4 - //Top face - vts->Add(rtl, c); //4 - vts->Add(rtr, c); //5 - vts->Add(ftr, c); //3 + //Top face + vts->Add(rtl, c); //4 + vts->Add(rtr, c); //5 + vts->Add(ftr, c); //3 - vts->Add(ftr, c); //3 - vts->Add(ftl, c); //2 - vts->Add(rtl, c); //4 + vts->Add(ftr, c); //3 + vts->Add(ftl, c); //2 + vts->Add(rtl, c); //4 - //bottom face - vts->Add(fbr, c); //1 - vts->Add(rbr, c); //7 - vts->Add(rbl, c); //6 + //bottom face + vts->Add(fbr, c); //1 + vts->Add(rbr, c); //7 + vts->Add(rbl, c); //6 - vts->Add(rbl, c); //6 - vts->Add(fbl, c); //0 - vts->Add(fbr, c); //1 + vts->Add(rbl, c); //6 + vts->Add(fbl, c); //0 + vts->Add(fbr, c); //1 - //left face - vts->Add(fbl, c); //0 - vts->Add(rbl, c); //6 - vts->Add(rtl, c); //4 + //left face + vts->Add(fbl, c); //0 + vts->Add(rbl, c); //6 + vts->Add(rtl, c); //4 - vts->Add(rtl, c); //4 - vts->Add(ftl, c); //2 - vts->Add(fbl, c); //0 + vts->Add(rtl, c); //4 + vts->Add(ftl, c); //2 + vts->Add(fbl, c); //0 - //right face - vts->Add(rtr, c); //5 - vts->Add(rbr, c); //7 - vts->Add(fbr, c); //1 + //right face + vts->Add(rtr, c); //5 + vts->Add(rbr, c); //7 + vts->Add(fbr, c); //1 - vts->Add(fbr, c); //1 - vts->Add(ftr, c); //3 - vts->Add(rtr, c); //5 + vts->Add(fbr, c); //1 + vts->Add(ftr, c); //3 + vts->Add(rtr, c); //5 - Graphics::Renderer *r = GetRenderer(); + Graphics::Renderer *r = GetRenderer(); - Graphics::RenderStateDesc rsd; - rsd.cullMode = Graphics::CULL_NONE; + Graphics::RenderStateDesc rsd; + rsd.cullMode = Graphics::CULL_NONE; - RefCountedPtr vb; - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.numVertices = vts->GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - vb.Reset( m_renderer->CreateVertexBuffer(vbd) ); - vb->Populate( *vts ); + RefCountedPtr vb; + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.numVertices = vts->GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + vb.Reset(m_renderer->CreateVertexBuffer(vbd)); + vb->Populate(*vts); - r->SetWireFrameMode(true); - r->DrawBuffer(vb.Get(), r->CreateRenderState(rsd), Graphics::vtxColorMaterial); - r->SetWireFrameMode(false); -} + r->SetWireFrameMode(true); + r->DrawBuffer(vb.Get(), r->CreateRenderState(rsd), Graphics::vtxColorMaterial); + r->SetWireFrameMode(false); + } -} +} // namespace SceneGraph diff --git a/src/scenegraph/StaticGeometry.h b/src/scenegraph/StaticGeometry.h index 27758c2b9..5d8ff91f3 100644 --- a/src/scenegraph/StaticGeometry.h +++ b/src/scenegraph/StaticGeometry.h @@ -6,54 +6,53 @@ /* * Geometry node containing one or more meshes. */ -#include "libs.h" -#include "Node.h" #include "Aabb.h" +#include "Node.h" #include "graphics/Renderer.h" #include "graphics/VertexBuffer.h" +#include "libs.h" namespace SceneGraph { -class NodeVisitor; + class NodeVisitor; -class StaticGeometry : public Node -{ -public: - struct Mesh { - RefCountedPtr vertexBuffer; - RefCountedPtr indexBuffer; - RefCountedPtr material; + class StaticGeometry : public Node { + public: + struct Mesh { + RefCountedPtr vertexBuffer; + RefCountedPtr indexBuffer; + RefCountedPtr material; + }; + StaticGeometry(Graphics::Renderer *r); + StaticGeometry(const StaticGeometry &, NodeCopyCache *cache = 0); + virtual Node *Clone(NodeCopyCache *cache = 0) override; + virtual const char *GetTypeName() const override { return "StaticGeometry"; } + virtual void Accept(NodeVisitor &nv) override; + virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; + virtual void Render(const std::vector &trans, const RenderData *rd) override; + + virtual void Save(NodeDatabase &) override; + static StaticGeometry *Load(NodeDatabase &); + + void AddMesh(RefCountedPtr, + RefCountedPtr, + RefCountedPtr); + unsigned int GetNumMeshes() const { return static_cast(m_meshes.size()); } + Mesh &GetMeshAt(unsigned int i); + + void SetRenderState(Graphics::RenderState *s) { m_renderState = s; } + + Aabb m_boundingBox; + Graphics::BlendMode m_blendMode; + + protected: + ~StaticGeometry(); + void DrawBoundingBox(const Aabb &bb); + std::vector m_meshes; + std::vector> m_instanceMaterials; + Graphics::RenderState *m_renderState; + RefCountedPtr m_instBuffer; }; - StaticGeometry(Graphics::Renderer *r); - StaticGeometry(const StaticGeometry&, NodeCopyCache *cache = 0); - virtual Node *Clone(NodeCopyCache *cache = 0) override; - virtual const char *GetTypeName() const override { return "StaticGeometry"; } - virtual void Accept(NodeVisitor &nv) override; - virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; - virtual void Render(const std::vector &trans, const RenderData *rd) override; - virtual void Save(NodeDatabase&) override; - static StaticGeometry *Load(NodeDatabase&); - - void AddMesh(RefCountedPtr, - RefCountedPtr, - RefCountedPtr); - unsigned int GetNumMeshes() const { return static_cast(m_meshes.size()); } - Mesh &GetMeshAt(unsigned int i); - - void SetRenderState(Graphics::RenderState *s) { m_renderState = s; } - - Aabb m_boundingBox; - Graphics::BlendMode m_blendMode; - -protected: - ~StaticGeometry(); - void DrawBoundingBox(const Aabb &bb); - std::vector m_meshes; - std::vector> m_instanceMaterials; - Graphics::RenderState *m_renderState; - RefCountedPtr m_instBuffer; -}; - -} +} // namespace SceneGraph #endif diff --git a/src/scenegraph/Thruster.cpp b/src/scenegraph/Thruster.cpp index 5c0dfb3e8..dc9dd459d 100644 --- a/src/scenegraph/Thruster.cpp +++ b/src/scenegraph/Thruster.cpp @@ -1,225 +1,228 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Easing.h" #include "Thruster.h" -#include "NodeVisitor.h" #include "BaseLoader.h" -#include "graphics/Renderer.h" -#include "graphics/VertexArray.h" +#include "Easing.h" +#include "NodeVisitor.h" #include "graphics/Material.h" -#include "graphics/TextureBuilder.h" #include "graphics/RenderState.h" +#include "graphics/Renderer.h" +#include "graphics/TextureBuilder.h" +#include "graphics/VertexArray.h" namespace SceneGraph { -static const std::string thrusterTextureFilename("textures/thruster.dds"); -static const std::string thrusterGlowTextureFilename("textures/halo.dds"); -static Color baseColor(178, 153, 255, 255); + static const std::string thrusterTextureFilename("textures/thruster.dds"); + static const std::string thrusterGlowTextureFilename("textures/halo.dds"); + static Color baseColor(178, 153, 255, 255); -Thruster::Thruster(Graphics::Renderer *r, bool _linear, const vector3f &_pos, const vector3f &_dir) -: Node(r, NODE_TRANSPARENT) -, linearOnly(_linear) -, dir(_dir) -, pos(_pos) -, currentColor(baseColor) -{ - //set up materials - Graphics::MaterialDescriptor desc; - desc.textures = 1; + Thruster::Thruster(Graphics::Renderer *r, bool _linear, const vector3f &_pos, const vector3f &_dir) : + Node(r, NODE_TRANSPARENT), + linearOnly(_linear), + dir(_dir), + pos(_pos), + currentColor(baseColor) + { + //set up materials + Graphics::MaterialDescriptor desc; + desc.textures = 1; - m_tMat.Reset(r->CreateMaterial(desc)); - m_tMat->texture0 = Graphics::TextureBuilder::Billboard(thrusterTextureFilename).GetOrCreateTexture(r, "billboard"); - m_tMat->diffuse = baseColor; + m_tMat.Reset(r->CreateMaterial(desc)); + m_tMat->texture0 = Graphics::TextureBuilder::Billboard(thrusterTextureFilename).GetOrCreateTexture(r, "billboard"); + m_tMat->diffuse = baseColor; - m_glowMat.Reset(r->CreateMaterial(desc)); - m_glowMat->texture0 = Graphics::TextureBuilder::Billboard(thrusterGlowTextureFilename).GetOrCreateTexture(r, "billboard"); - m_glowMat->diffuse = baseColor; + m_glowMat.Reset(r->CreateMaterial(desc)); + m_glowMat->texture0 = Graphics::TextureBuilder::Billboard(thrusterGlowTextureFilename).GetOrCreateTexture(r, "billboard"); + m_glowMat->diffuse = baseColor; - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA_ONE; - rsd.depthWrite = false; - rsd.cullMode = Graphics::CULL_NONE; - m_renderState = r->CreateRenderState(rsd); -} + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA_ONE; + rsd.depthWrite = false; + rsd.cullMode = Graphics::CULL_NONE; + m_renderState = r->CreateRenderState(rsd); + } -Thruster::Thruster(const Thruster &thruster, NodeCopyCache *cache) -: Node(thruster, cache) -, m_tMat(thruster.m_tMat) -, m_renderState(thruster.m_renderState) -, linearOnly(thruster.linearOnly) -, dir(thruster.dir) -, pos(thruster.pos) -, currentColor(thruster.currentColor) -{ -} + Thruster::Thruster(const Thruster &thruster, NodeCopyCache *cache) : + Node(thruster, cache), + m_tMat(thruster.m_tMat), + m_renderState(thruster.m_renderState), + linearOnly(thruster.linearOnly), + dir(thruster.dir), + pos(thruster.pos), + currentColor(thruster.currentColor) + { + } -Node* Thruster::Clone(NodeCopyCache *cache) -{ - return this; //thrusters are shared -} + Node *Thruster::Clone(NodeCopyCache *cache) + { + return this; //thrusters are shared + } -void Thruster::Accept(NodeVisitor &nv) -{ - nv.ApplyThruster(*this); -} + void Thruster::Accept(NodeVisitor &nv) + { + nv.ApplyThruster(*this); + } -void Thruster::Render(const matrix4x4f &trans, const RenderData *rd) -{ - PROFILE_SCOPED() - float power = -dir.Dot(vector3f(rd->linthrust)); + void Thruster::Render(const matrix4x4f &trans, const RenderData *rd) + { + PROFILE_SCOPED() + float power = -dir.Dot(vector3f(rd->linthrust)); - if (!linearOnly) { - // pitch X - // yaw Y - // roll Z - //model center is at 0,0,0, no need for invSubModelMat stuff - const vector3f at = vector3f(rd->angthrust); - const vector3f angdir = pos.Cross(dir); + if (!linearOnly) { + // pitch X + // yaw Y + // roll Z + //model center is at 0,0,0, no need for invSubModelMat stuff + const vector3f at = vector3f(rd->angthrust); + const vector3f angdir = pos.Cross(dir); - const float xp = angdir.x * at.x; - const float yp = angdir.y * at.y; - const float zp = angdir.z * at.z; + const float xp = angdir.x * at.x; + const float yp = angdir.y * at.y; + const float zp = angdir.z * at.z; - if (xp+yp+zp > 0) { - if (xp > yp && xp > zp && fabs(at.x) > power) power = fabs(at.x); - else if (yp > xp && yp > zp && fabs(at.y) > power) power = fabs(at.y); - else if (zp > xp && zp > yp && fabs(at.z) > power) power = fabs(at.z); + if (xp + yp + zp > 0) { + if (xp > yp && xp > zp && fabs(at.x) > power) + power = fabs(at.x); + else if (yp > xp && yp > zp && fabs(at.y) > power) + power = fabs(at.y); + else if (zp > xp && zp > yp && fabs(at.z) > power) + power = fabs(at.z); + } } - } - if (power < 0.001f) return; + if (power < 0.001f) return; - m_tMat->diffuse = m_glowMat->diffuse = currentColor * power; + m_tMat->diffuse = m_glowMat->diffuse = currentColor * power; - //directional fade - vector3f cdir = vector3f(trans * -dir).Normalized(); - vector3f vdir = vector3f(trans[2], trans[6], -trans[10]).Normalized(); - // XXX check this for transition to new colors. - m_glowMat->diffuse.a = Easing::Circ::EaseIn(Clamp(vdir.Dot(cdir), 0.f, 1.f), 0.f, 1.f, 1.f) * 255; - m_tMat->diffuse.a = 255 - m_glowMat->diffuse.a; + //directional fade + vector3f cdir = vector3f(trans * -dir).Normalized(); + vector3f vdir = vector3f(trans[2], trans[6], -trans[10]).Normalized(); + // XXX check this for transition to new colors. + m_glowMat->diffuse.a = Easing::Circ::EaseIn(Clamp(vdir.Dot(cdir), 0.f, 1.f), 0.f, 1.f, 1.f) * 255; + m_tMat->diffuse.a = 255 - m_glowMat->diffuse.a; - Graphics::Renderer *r = GetRenderer(); - if( !m_tBuffer.Valid() ) { - m_tBuffer.Reset(CreateThrusterGeometry(r, m_tMat.Get())); - m_glowBuffer.Reset(CreateGlowGeometry(r, m_glowMat.Get())); + Graphics::Renderer *r = GetRenderer(); + if (!m_tBuffer.Valid()) { + m_tBuffer.Reset(CreateThrusterGeometry(r, m_tMat.Get())); + m_glowBuffer.Reset(CreateGlowGeometry(r, m_glowMat.Get())); + } + + r->SetTransform(trans); + r->DrawBuffer(m_tBuffer.Get(), m_renderState, m_tMat.Get()); + r->DrawBuffer(m_glowBuffer.Get(), m_renderState, m_glowMat.Get()); } - r->SetTransform(trans); - r->DrawBuffer(m_tBuffer.Get(), m_renderState, m_tMat.Get()); - r->DrawBuffer(m_glowBuffer.Get(), m_renderState, m_glowMat.Get()); -} - -void Thruster::Save(NodeDatabase &db) -{ - Node::Save(db); - db.wr->Bool(linearOnly); - db.wr->Vector3f(dir); - db.wr->Vector3f(pos); -} - -Thruster *Thruster::Load(NodeDatabase &db) -{ - const bool linear = db.rd->Bool(); - const vector3f dir = db.rd->Vector3f(); - const vector3f pos = db.rd->Vector3f(); - Thruster *t = new Thruster(db.loader->GetRenderer(), linear, pos, dir); - return t; -} - -Graphics::VertexBuffer *Thruster::CreateThrusterGeometry(Graphics::Renderer *r, Graphics::Material *mat) -{ - Graphics::VertexArray verts(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - - //zero at thruster center - //+x down - //+y right - //+z backwards (or thrust direction) - const float w = 0.5f; - - vector3f one(0.f, -w, 0.f); //top left - vector3f two(0.f, w, 0.f); //top right - vector3f three(0.f, w, 1.f); //bottom right - vector3f four(0.f, -w, 1.f); //bottom left - - //uv coords - const vector2f topLeft(0.f, 1.f); - const vector2f topRight(1.f, 1.f); - const vector2f botLeft(0.f, 0.f); - const vector2f botRight(1.f, 0.f); - - //add four intersecting planes to create a volumetric effect - for (int i=0; i < 4; i++) { - verts.Add(one, topLeft); - verts.Add(two, topRight); - verts.Add(three, botRight); - - verts.Add(three, botRight); - verts.Add(four, botLeft); - verts.Add(one, topLeft); - - one.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); - two.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); - three.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); - four.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); + void Thruster::Save(NodeDatabase &db) + { + Node::Save(db); + db.wr->Bool(linearOnly); + db.wr->Vector3f(dir); + db.wr->Vector3f(pos); } - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = verts.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - Graphics::VertexBuffer *vb = r->CreateVertexBuffer(vbd); - vb->Populate(verts); - - return vb; -} - -Graphics::VertexBuffer *Thruster::CreateGlowGeometry(Graphics::Renderer *r, Graphics::Material *mat) -{ - Graphics::VertexArray verts(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - - //create glow billboard for linear thrusters - const float w = 0.2; - - vector3f one(-w, -w, 0.f); //top left - vector3f two(-w, w, 0.f); //top right - vector3f three(w, w, 0.f); //bottom right - vector3f four(w, -w, 0.f); //bottom left - - //uv coords - const vector2f topLeft(0.f, 1.f); - const vector2f topRight(1.f, 1.f); - const vector2f botLeft(0.f, 0.f); - const vector2f botRight(1.f, 0.f); - - for (int i = 0; i < 5; i++) { - verts.Add(one, topLeft); - verts.Add(two, topRight); - verts.Add(three, botRight); - - verts.Add(three, botRight); - verts.Add(four, botLeft); - verts.Add(one, topLeft); - - one.z += .1f; - two.z = three.z = four.z = one.z; + Thruster *Thruster::Load(NodeDatabase &db) + { + const bool linear = db.rd->Bool(); + const vector3f dir = db.rd->Vector3f(); + const vector3f pos = db.rd->Vector3f(); + Thruster *t = new Thruster(db.loader->GetRenderer(), linear, pos, dir); + return t; } - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = verts.GetNumVerts(); - vbd.usage = Graphics::BUFFER_USAGE_STATIC; - Graphics::VertexBuffer *vb = r->CreateVertexBuffer(vbd); - vb->Populate(verts); + Graphics::VertexBuffer *Thruster::CreateThrusterGeometry(Graphics::Renderer *r, Graphics::Material *mat) + { + Graphics::VertexArray verts(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - return vb; -} + //zero at thruster center + //+x down + //+y right + //+z backwards (or thrust direction) + const float w = 0.5f; -} + vector3f one(0.f, -w, 0.f); //top left + vector3f two(0.f, w, 0.f); //top right + vector3f three(0.f, w, 1.f); //bottom right + vector3f four(0.f, -w, 1.f); //bottom left + + //uv coords + const vector2f topLeft(0.f, 1.f); + const vector2f topRight(1.f, 1.f); + const vector2f botLeft(0.f, 0.f); + const vector2f botRight(1.f, 0.f); + + //add four intersecting planes to create a volumetric effect + for (int i = 0; i < 4; i++) { + verts.Add(one, topLeft); + verts.Add(two, topRight); + verts.Add(three, botRight); + + verts.Add(three, botRight); + verts.Add(four, botLeft); + verts.Add(one, topLeft); + + one.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); + two.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); + three.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); + four.ArbRotate(vector3f(0.f, 0.f, 1.f), DEG2RAD(45.f)); + } + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = verts.GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + Graphics::VertexBuffer *vb = r->CreateVertexBuffer(vbd); + vb->Populate(verts); + + return vb; + } + + Graphics::VertexBuffer *Thruster::CreateGlowGeometry(Graphics::Renderer *r, Graphics::Material *mat) + { + Graphics::VertexArray verts(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + + //create glow billboard for linear thrusters + const float w = 0.2; + + vector3f one(-w, -w, 0.f); //top left + vector3f two(-w, w, 0.f); //top right + vector3f three(w, w, 0.f); //bottom right + vector3f four(w, -w, 0.f); //bottom left + + //uv coords + const vector2f topLeft(0.f, 1.f); + const vector2f topRight(1.f, 1.f); + const vector2f botLeft(0.f, 0.f); + const vector2f botRight(1.f, 0.f); + + for (int i = 0; i < 5; i++) { + verts.Add(one, topLeft); + verts.Add(two, topRight); + verts.Add(three, botRight); + + verts.Add(three, botRight); + verts.Add(four, botLeft); + verts.Add(one, topLeft); + + one.z += .1f; + two.z = three.z = four.z = one.z; + } + + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = verts.GetNumVerts(); + vbd.usage = Graphics::BUFFER_USAGE_STATIC; + Graphics::VertexBuffer *vb = r->CreateVertexBuffer(vbd); + vb->Populate(verts); + + return vb; + } + +} // namespace SceneGraph diff --git a/src/scenegraph/Thruster.h b/src/scenegraph/Thruster.h index 44433b3ff..d1a54e11d 100644 --- a/src/scenegraph/Thruster.h +++ b/src/scenegraph/Thruster.h @@ -6,45 +6,45 @@ /* * Spaceship thruster */ -#include "libs.h" #include "Node.h" +#include "libs.h" namespace Graphics { class Renderer; class VertexBuffer; class Material; class RenderState; -} +} // namespace Graphics namespace SceneGraph { -class Thruster : public Node { -public: - Thruster(Graphics::Renderer *, bool linear, const vector3f &pos, const vector3f &dir); - Thruster(const Thruster&, NodeCopyCache *cache = 0); - Node *Clone(NodeCopyCache *cache = 0) override; - virtual void Accept(NodeVisitor &v) override; - virtual const char *GetTypeName() const override { return "Thruster"; } - virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; - virtual void Save(NodeDatabase&) override; - static Thruster *Load(NodeDatabase&); - void SetColor(const Color c) { currentColor = c; } - const vector3f &GetDirection() { return dir; } + class Thruster : public Node { + public: + Thruster(Graphics::Renderer *, bool linear, const vector3f &pos, const vector3f &dir); + Thruster(const Thruster &, NodeCopyCache *cache = 0); + Node *Clone(NodeCopyCache *cache = 0) override; + virtual void Accept(NodeVisitor &v) override; + virtual const char *GetTypeName() const override { return "Thruster"; } + virtual void Render(const matrix4x4f &trans, const RenderData *rd) override; + virtual void Save(NodeDatabase &) override; + static Thruster *Load(NodeDatabase &); + void SetColor(const Color c) { currentColor = c; } + const vector3f &GetDirection() { return dir; } -private: - static Graphics::VertexBuffer* CreateThrusterGeometry(Graphics::Renderer*, Graphics::Material*); - static Graphics::VertexBuffer* CreateGlowGeometry(Graphics::Renderer*, Graphics::Material*); - RefCountedPtr m_tMat; - RefCountedPtr m_glowMat; - RefCountedPtr m_tBuffer; - RefCountedPtr m_glowBuffer; - Graphics::RenderState *m_renderState; - bool linearOnly; - vector3f dir; - vector3f pos; - Color currentColor; -}; + private: + static Graphics::VertexBuffer *CreateThrusterGeometry(Graphics::Renderer *, Graphics::Material *); + static Graphics::VertexBuffer *CreateGlowGeometry(Graphics::Renderer *, Graphics::Material *); + RefCountedPtr m_tMat; + RefCountedPtr m_glowMat; + RefCountedPtr m_tBuffer; + RefCountedPtr m_glowBuffer; + Graphics::RenderState *m_renderState; + bool linearOnly; + vector3f dir; + vector3f pos; + Color currentColor; + }; -} +} // namespace SceneGraph #endif diff --git a/src/terrain/Terrain.cpp b/src/terrain/Terrain.cpp index b21a38182..ed6a94e26 100644 --- a/src/terrain/Terrain.cpp +++ b/src/terrain/Terrain.cpp @@ -2,10 +2,10 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "perlin.h" -#include "Pi.h" #include "FileSystem.h" #include "FloatComparison.h" +#include "Pi.h" +#include "perlin.h" // static instancer. selects the best height and color classes for the body Terrain *Terrain::InstanceTerrain(const SystemBody *body) @@ -16,8 +16,8 @@ Terrain *Terrain::InstanceTerrain(const SystemBody *body) // the check in CustomSystem::l_height_map if (!body->GetHeightMapFilename().empty()) { const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator + InstanceGenerator, + InstanceGenerator }; assert(body->GetHeightMapFractal() < COUNTOF(choices)); return choices[body->GetHeightMapFractal()](body); @@ -29,328 +29,328 @@ Terrain *Terrain::InstanceTerrain(const SystemBody *body) switch (body->GetType()) { - case SystemBody::TYPE_BROWN_DWARF: - gi = InstanceGenerator; - break; + case SystemBody::TYPE_BROWN_DWARF: + gi = InstanceGenerator; + break; - case SystemBody::TYPE_WHITE_DWARF: - gi = InstanceGenerator; - break; + case SystemBody::TYPE_WHITE_DWARF: + gi = InstanceGenerator; + break; - case SystemBody::TYPE_STAR_M: - case SystemBody::TYPE_STAR_M_GIANT: - case SystemBody::TYPE_STAR_M_SUPER_GIANT: - case SystemBody::TYPE_STAR_M_HYPER_GIANT: { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + case SystemBody::TYPE_STAR_M: + case SystemBody::TYPE_STAR_M_GIANT: + case SystemBody::TYPE_STAR_M_SUPER_GIANT: + case SystemBody::TYPE_STAR_M_HYPER_GIANT: { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - case SystemBody::TYPE_STAR_K: - case SystemBody::TYPE_STAR_K_GIANT: - case SystemBody::TYPE_STAR_K_SUPER_GIANT: - case SystemBody::TYPE_STAR_K_HYPER_GIANT: { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + case SystemBody::TYPE_STAR_K: + case SystemBody::TYPE_STAR_K_GIANT: + case SystemBody::TYPE_STAR_K_SUPER_GIANT: + case SystemBody::TYPE_STAR_K_HYPER_GIANT: { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - case SystemBody::TYPE_STAR_G: - case SystemBody::TYPE_STAR_G_GIANT: - case SystemBody::TYPE_STAR_G_SUPER_GIANT: - case SystemBody::TYPE_STAR_G_HYPER_GIANT: { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + case SystemBody::TYPE_STAR_G: + case SystemBody::TYPE_STAR_G_GIANT: + case SystemBody::TYPE_STAR_G_SUPER_GIANT: + case SystemBody::TYPE_STAR_G_HYPER_GIANT: { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - case SystemBody::TYPE_STAR_F: - case SystemBody::TYPE_STAR_F_GIANT: - case SystemBody::TYPE_STAR_F_HYPER_GIANT: - case SystemBody::TYPE_STAR_F_SUPER_GIANT: - case SystemBody::TYPE_STAR_A: - case SystemBody::TYPE_STAR_A_GIANT: - case SystemBody::TYPE_STAR_A_HYPER_GIANT: - case SystemBody::TYPE_STAR_A_SUPER_GIANT: - case SystemBody::TYPE_STAR_B: - case SystemBody::TYPE_STAR_B_GIANT: - case SystemBody::TYPE_STAR_B_SUPER_GIANT: - case SystemBody::TYPE_STAR_B_WF: - case SystemBody::TYPE_STAR_O: - case SystemBody::TYPE_STAR_O_GIANT: - case SystemBody::TYPE_STAR_O_HYPER_GIANT: - case SystemBody::TYPE_STAR_O_SUPER_GIANT: - case SystemBody::TYPE_STAR_O_WF: - gi = InstanceGenerator; - break; + case SystemBody::TYPE_STAR_F: + case SystemBody::TYPE_STAR_F_GIANT: + case SystemBody::TYPE_STAR_F_HYPER_GIANT: + case SystemBody::TYPE_STAR_F_SUPER_GIANT: + case SystemBody::TYPE_STAR_A: + case SystemBody::TYPE_STAR_A_GIANT: + case SystemBody::TYPE_STAR_A_HYPER_GIANT: + case SystemBody::TYPE_STAR_A_SUPER_GIANT: + case SystemBody::TYPE_STAR_B: + case SystemBody::TYPE_STAR_B_GIANT: + case SystemBody::TYPE_STAR_B_SUPER_GIANT: + case SystemBody::TYPE_STAR_B_WF: + case SystemBody::TYPE_STAR_O: + case SystemBody::TYPE_STAR_O_GIANT: + case SystemBody::TYPE_STAR_O_HYPER_GIANT: + case SystemBody::TYPE_STAR_O_SUPER_GIANT: + case SystemBody::TYPE_STAR_O_WF: + gi = InstanceGenerator; + break; - case SystemBody::TYPE_STAR_S_BH: - case SystemBody::TYPE_STAR_IM_BH: - case SystemBody::TYPE_STAR_SM_BH: - gi = InstanceGenerator; - break; + case SystemBody::TYPE_STAR_S_BH: + case SystemBody::TYPE_STAR_IM_BH: + case SystemBody::TYPE_STAR_SM_BH: + gi = InstanceGenerator; + break; - case SystemBody::TYPE_PLANET_GAS_GIANT: { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + case SystemBody::TYPE_PLANET_GAS_GIANT: { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - case SystemBody::TYPE_PLANET_ASTEROID: { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + case SystemBody::TYPE_PLANET_ASTEROID: { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - case SystemBody::TYPE_PLANET_TERRESTRIAL: { + case SystemBody::TYPE_PLANET_TERRESTRIAL: { - //Over-ride: - //gi = InstanceGenerator; - //break; - // Earth-like world + //Over-ride: + //gi = InstanceGenerator; + //break; + // Earth-like world - if ((body->GetLifeAsFixed() > fixed(7,10)) && (body->GetVolatileGasAsFixed() > fixed(2,10))) { - // There would be no life on the surface without atmosphere - - if (body->GetAverageTemp() > 240) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } + if ((body->GetLifeAsFixed() > fixed(7, 10)) && (body->GetVolatileGasAsFixed() > fixed(2, 10))) { + // There would be no life on the surface without atmosphere + if (body->GetAverageTemp() > 240) { const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator//, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } + + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator //, + //InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } + + // Harsh, habitable world + if ((body->GetVolatileGasAsFixed() > fixed(2, 10)) && (body->GetLifeAsFixed() > fixed(4, 10))) { + + if (body->GetAverageTemp() > 240) { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator //InstanceGenerator }; gi = choices[rand.Int32(COUNTOF(choices))]; break; } - // Harsh, habitable world - if ((body->GetVolatileGasAsFixed() > fixed(2,10)) && (body->GetLifeAsFixed() > fixed(4,10)) ) { - - if (body->GetAverageTemp() > 240) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - //InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - // Marginally habitable world/ verging on mars like :) - else if ((body->GetVolatileGasAsFixed() > fixed(1,10)) && (body->GetLifeAsFixed() > fixed(1,10)) ) { - - if (body->GetAverageTemp() > 240) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - // Desert-like world, Mars -like. - if ((body->GetVolatileLiquidAsFixed() < fixed(1,10)) && (body->GetVolatileGasAsFixed() > fixed(1,5))) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - // Frozen world - if ((body->GetVolatileIcesAsFixed() > fixed(8,10)) && (body->GetAverageTemp() < 250)) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; - } - - // Volcanic world - if (body->GetVolcanicityAsFixed() > fixed(7,10)) { - - if (body->GetLifeAsFixed() > fixed(5,10)) // life on a volcanic world ;) - gi = InstanceGenerator; - else if (body->GetLifeAsFixed() > fixed(2,10)) - gi = InstanceGenerator; - else - gi = InstanceGenerator; - break; - } - - //Below might not be needed. - //Alien life world: - if (body->GetLifeAsFixed() > fixed(1,10)) { - const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator - }; - gi = choices[rand.Int32(COUNTOF(choices))]; - break; + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } - if (body->GetVolatileGasAsFixed() > fixed(1,10)) { + // Marginally habitable world/ verging on mars like :) + else if ((body->GetVolatileGasAsFixed() > fixed(1, 10)) && (body->GetLifeAsFixed() > fixed(1, 10))) { + + if (body->GetAverageTemp() > 240) { const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator, - InstanceGenerator + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator }; gi = choices[rand.Int32(COUNTOF(choices))]; break; } const GeneratorInstancer choices[] = { - InstanceGenerator, - InstanceGenerator, - InstanceGenerator + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator }; gi = choices[rand.Int32(COUNTOF(choices))]; break; } - default: - gi = InstanceGenerator; + // Desert-like world, Mars -like. + if ((body->GetVolatileLiquidAsFixed() < fixed(1, 10)) && (body->GetVolatileGasAsFixed() > fixed(1, 5))) { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; break; + } + + // Frozen world + if ((body->GetVolatileIcesAsFixed() > fixed(8, 10)) && (body->GetAverageTemp() < 250)) { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } + + // Volcanic world + if (body->GetVolcanicityAsFixed() > fixed(7, 10)) { + + if (body->GetLifeAsFixed() > fixed(5, 10)) // life on a volcanic world ;) + gi = InstanceGenerator; + else if (body->GetLifeAsFixed() > fixed(2, 10)) + gi = InstanceGenerator; + else + gi = InstanceGenerator; + break; + } + + //Below might not be needed. + //Alien life world: + if (body->GetLifeAsFixed() > fixed(1, 10)) { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + }; + + if (body->GetVolatileGasAsFixed() > fixed(1, 10)) { + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } + + const GeneratorInstancer choices[] = { + InstanceGenerator, + InstanceGenerator, + InstanceGenerator + }; + gi = choices[rand.Int32(COUNTOF(choices))]; + break; + } + + default: + gi = InstanceGenerator; + break; } return gi(body); @@ -358,7 +358,7 @@ Terrain *Terrain::InstanceTerrain(const SystemBody *body) static size_t bufread_or_die(void *ptr, size_t size, size_t nmemb, ByteRange &buf) { - size_t read_count = buf.read(static_cast(ptr), size, nmemb); + size_t read_count = buf.read(static_cast(ptr), size, nmemb); if (read_count < nmemb) { Output("Error: failed to read file (truncated)\n"); abort(); @@ -368,16 +368,22 @@ static size_t bufread_or_die(void *ptr, size_t size, size_t nmemb, ByteRange &bu // XXX this sucks, but there isn't a reliable cross-platform way to get them #ifndef INT16_MIN -# define INT16_MIN (-32767-1) +#define INT16_MIN (-32767 - 1) #endif #ifndef INT16_MAX -# define INT16_MAX (32767) +#define INT16_MAX (32767) #endif #ifndef UINT16_MAX -# define UINT16_MAX (65535) +#define UINT16_MAX (65535) #endif -Terrain::Terrain(const SystemBody *body) : m_seed(body->GetSeed()), m_rand(body->GetSeed()), m_heightScaling(0), m_minh(0), m_minBody(body) { +Terrain::Terrain(const SystemBody *body) : + m_seed(body->GetSeed()), + m_rand(body->GetSeed()), + m_heightScaling(0), + m_minh(0), + m_minBody(body) +{ // load the heightmap if (!body->GetHeightMapFilename().empty()) { @@ -394,97 +400,104 @@ Terrain::Terrain(const SystemBody *body) : m_seed(body->GetSeed()), m_rand(body- // XXX unify heightmap types switch (body->GetHeightMapFractal()) { - case 0: { - Uint16 v; - bufread_or_die(&v, 2, 1, databuf); m_heightMapSizeX = v; - bufread_or_die(&v, 2, 1, databuf); m_heightMapSizeY = v; - const Uint32 heightmapPixelArea = (m_heightMapSizeX * m_heightMapSizeY); + case 0: { + Uint16 v; + bufread_or_die(&v, 2, 1, databuf); + m_heightMapSizeX = v; + bufread_or_die(&v, 2, 1, databuf); + m_heightMapSizeY = v; + const Uint32 heightmapPixelArea = (m_heightMapSizeX * m_heightMapSizeY); - std::unique_ptr heightMap(new Sint16[heightmapPixelArea]); - bufread_or_die(heightMap.get(), sizeof(Sint16), heightmapPixelArea, databuf); - m_heightMap.reset(new double[heightmapPixelArea]); - double *pHeightMap = m_heightMap.get(); - for(Uint32 i=0; i heightMap(new Sint16[heightmapPixelArea]); + bufread_or_die(heightMap.get(), sizeof(Sint16), heightmapPixelArea, databuf); + m_heightMap.reset(new double[heightmapPixelArea]); + double *pHeightMap = m_heightMap.get(); + for (Uint32 i = 0; i < heightmapPixelArea; i++) { + const Sint16 val = heightMap.get()[i]; + minHMap = std::min(minHMap, val); + maxHMap = std::max(maxHMap, val); + // store then increment pointer + (*pHeightMap) = val; + ++pHeightMap; } - - case 1: { - Uint16 v; - // XXX x and y reversed from above *sigh* - bufread_or_die(&v, 2, 1, databuf); m_heightMapSizeY = v; - bufread_or_die(&v, 2, 1, databuf); m_heightMapSizeX = v; - const Uint32 heightmapPixelArea = (m_heightMapSizeX * m_heightMapSizeY); - - // read height scaling and min height which are doubles - double te; - bufread_or_die(&te, 8, 1, databuf); - m_heightScaling = te; - bufread_or_die(&te, 8, 1, databuf); - m_minh = te; - - std::unique_ptr heightMapScaled(new Uint16[heightmapPixelArea]); - bufread_or_die(heightMapScaled.get(), sizeof(Uint16), heightmapPixelArea, databuf); - m_heightMap.reset(new double[heightmapPixelArea]); - double *pHeightMap = m_heightMap.get(); - for(Uint32 i=0; i heightMapScaled(new Uint16[heightmapPixelArea]); + bufread_or_die(heightMapScaled.get(), sizeof(Uint16), heightmapPixelArea, databuf); + m_heightMap.reset(new double[heightmapPixelArea]); + double *pHeightMap = m_heightMap.get(); + for (Uint32 i = 0; i < heightmapPixelArea; i++) { + const Uint16 val = heightMapScaled[i]; + minHMapScld = std::min(minHMapScld, val); + maxHMapScld = std::max(maxHMapScld, val); + // store then increment pointer + (*pHeightMap) = val; + ++pHeightMap; + } + assert(pHeightMap == &m_heightMap[heightmapPixelArea]); + //Output("minHMapScld = (%hu), maxHMapScld = (%hu)\n", minHMapScld, maxHMapScld); + break; + } + + default: + assert(0); + } } switch (Pi::detail.textures) { - case 0: textures = false; - m_fracnum = 2;break; - default: - case 1: textures = true; - m_fracnum = 0;break; + case 0: + textures = false; + m_fracnum = 2; + break; + default: + case 1: + textures = true; + m_fracnum = 0; + break; } switch (Pi::detail.fracmult) { - case 0: m_fracmult = 100;break; - case 1: m_fracmult = 10;break; - case 2: m_fracmult = 1;break; - case 3: m_fracmult = 0.5;break; - default: - case 4: m_fracmult = 0.1;break; + case 0: m_fracmult = 100; break; + case 1: m_fracmult = 10; break; + case 2: m_fracmult = 1; break; + case 3: m_fracmult = 0.5; break; + default: + case 4: m_fracmult = 0.1; break; } m_sealevel = Clamp(body->GetVolatileLiquid(), 0.0, 1.0); - m_icyness = Clamp(body->GetVolatileIces(), 0.0, 1.0); + m_icyness = Clamp(body->GetVolatileIces(), 0.0, 1.0); m_volcanic = Clamp(body->GetVolcanicity(), 0.0, 1.0); // height scales with volcanicity as well m_surfaceEffects = 0; const double rad = m_minBody.m_radius; // calculate max height - if (!body->GetHeightMapFilename().empty() && body->GetHeightMapFractal() > 1){ // if scaled heightmap - m_maxHeightInMeters = 1.1*pow(2.0, 16.0)*m_heightScaling; // no min height required as it's added to radius in lua - }else { + if (!body->GetHeightMapFilename().empty() && body->GetHeightMapFractal() > 1) { // if scaled heightmap + m_maxHeightInMeters = 1.1 * pow(2.0, 16.0) * m_heightScaling; // no min height required as it's added to radius in lua + } else { // max mountain height for earth-like planet (same mass, radius) - m_maxHeightInMeters = std::max(100.0, (9000.0*rad*rad*(m_volcanic+0.5)) / (body->GetMass() * 6.64e-12)); - m_maxHeightInMeters = std::min(rad, m_maxHeightInMeters); // small asteroid case + m_maxHeightInMeters = std::max(100.0, (9000.0 * rad * rad * (m_volcanic + 0.5)) / (body->GetMass() * 6.64e-12)); + m_maxHeightInMeters = std::min(rad, m_maxHeightInMeters); // small asteroid case } // and then in sphere normalized jizz m_maxHeight = m_maxHeightInMeters / rad; @@ -494,9 +507,10 @@ Terrain::Terrain(const SystemBody *body) : m_seed(body->GetSeed()), m_rand(body- m_planetEarthRadii = rad / EARTH_RADIUS; // Pick some colors, mainly reds and greens - for (int i=0; iGetSeed()), m_rand(body- } // Pick some darker colours mainly reds and greens - for (int i=0; iGetSeed()), m_rand(body- } // grey colours, in case you simply must have a grey colour on a world with high metallicity - for (int i=0; iGetSeed()), m_rand(body- // Pick some plant colours, mainly greens // TODO take star class into account - for (int i=0; iGetLife()); - b *= (1.0-body->GetLife()); + b *= (1.0 - body->GetLife()); m_plantColor[i] = vector3d(r, g, b); } // Pick some darker plant colours mainly greens // TODO take star class into account - for (int i=0; iGetLife()); - b *= (1.0-body->GetLife()); + b *= (1.0 - body->GetLife()); m_darkplantColor[i] = vector3d(r, g, b); } // Pick some sand colours, mainly yellow // TODO let some planetary value scale this colour - for (int i=0; iGetSeed()), m_rand(body- // Pick some darker sand colours mainly yellow // TODO let some planetary value scale this colour - for (int i=0; iGetSeed()), m_rand(body- // Pick some dirt colours, mainly red/brown // TODO let some planetary value scale this colour - for (int i=0; i=0 && index= 0 && index < MAX_FRACDEFS); // feature m_fracdef[index].amplitude = featureHeightMeters / (m_maxHeight * m_planetRadius); m_fracdef[index].frequency = m_planetRadius / featureWidthMeters; diff --git a/src/terrain/Terrain.h b/src/terrain/Terrain.h index 3846b2bf5..ed446114d 100644 --- a/src/terrain/Terrain.h +++ b/src/terrain/Terrain.h @@ -4,31 +4,34 @@ #ifndef _TERRAIN_H #define _TERRAIN_H -#include "libs.h" #include "galaxy/StarSystem.h" +#include "libs.h" #ifdef _MSC_VER -#pragma warning(disable : 4250) // workaround for MSVC 2008 multiple inheritance bug +#pragma warning(disable : 4250) // workaround for MSVC 2008 multiple inheritance bug #endif struct fracdef_t { - fracdef_t() : amplitude(0.0), frequency(0.0), lacunarity(0.0), octaves(0) {} + fracdef_t() : + amplitude(0.0), + frequency(0.0), + lacunarity(0.0), + octaves(0) {} double amplitude; double frequency; double lacunarity; int octaves; }; - -template class TerrainGenerator; - +template +class TerrainGenerator; class Terrain : public RefCounted { public: // location and intensity of effects are controlled by the colour fractals; // it's possible for a Terrain to have a flag set but not actually to exhibit any of that effect enum SurfaceEffectFlags { - EFFECT_LAVA = 1 << 0, + EFFECT_LAVA = 1 << 0, EFFECT_WATER = 2 // can add other effect flags here (e.g., water, snow, ice) }; @@ -38,7 +41,11 @@ public: virtual ~Terrain(); void SetFracDef(const unsigned int index, const double featureHeightMeters, const double featureWidthMeters, const double smallestOctaveMeters = 20.0); - inline const fracdef_t &GetFracDef(const unsigned int index) const { assert(index>=0 && index= 0 && index < MAX_FRACDEFS); + return m_fracdef[index]; + } virtual double GetHeight(const vector3d &p) const = 0; virtual vector3d GetColor(const vector3d &p, double height, const vector3d &norm) const = 0; @@ -54,10 +61,9 @@ public: private: template - static Terrain *InstanceGenerator(const SystemBody *body) { return new TerrainGenerator(body); } - - typedef Terrain* (*GeneratorInstancer)(const SystemBody *); + static Terrain *InstanceGenerator(const SystemBody *body) { return new TerrainGenerator(body); } + typedef Terrain *(*GeneratorInstancer)(const SystemBody *); protected: Terrain(const SystemBody *body); @@ -110,7 +116,8 @@ protected: fracdef_t m_fracdef[MAX_FRACDEFS]; struct MinBodyData { - MinBodyData(const SystemBody* body) { + MinBodyData(const SystemBody *body) + { m_radius = body->GetRadius(); m_aspectRatio = body->GetAspectRatio(); m_path = body->GetPath(); @@ -124,14 +131,15 @@ protected: MinBodyData m_minBody; }; - template class TerrainHeightFractal : virtual public Terrain { public: virtual double GetHeight(const vector3d &p) const; virtual const char *GetHeightFractalName() const; + protected: TerrainHeightFractal(const SystemBody *body); + private: TerrainHeightFractal() {} }; @@ -141,17 +149,21 @@ class TerrainColorFractal : virtual public Terrain { public: virtual vector3d GetColor(const vector3d &p, double height, const vector3d &norm) const; virtual const char *GetColorFractalName() const; + protected: TerrainColorFractal(const SystemBody *body); + private: TerrainColorFractal() {} }; - template class TerrainGenerator : public TerrainHeightFractal, public TerrainColorFractal { public: - TerrainGenerator(const SystemBody *body) : Terrain(body), TerrainHeightFractal(body), TerrainColorFractal(body) {} + TerrainGenerator(const SystemBody *body) : + Terrain(body), + TerrainHeightFractal(body), + TerrainColorFractal(body) {} private: TerrainGenerator() {} @@ -197,15 +209,13 @@ class TerrainHeightMountainsCraters; class TerrainHeightMountainsNormal; // Based on TerrainHeightMountainsNormal : class TerrainHeightMountainsRivers; - /*Pictures from the above two terrains generating Earth-like worlds: +/*Pictures from the above two terrains generating Earth-like worlds: http://www.spacesimcentral.com/forum/download/file.php?id=1533&mode=view http://www.spacesimcentral.com/forum/download/file.php?id=1544&mode=view http://www.spacesimcentral.com/forum/download/file.php?id=1550&mode=view http://www.spacesimcentral.com/forum/download/file.php?id=1540&mode=view */ - - // Older terrains: class TerrainHeightMountainsRidged; class TerrainHeightMountainsRiversVolcano; @@ -223,7 +233,6 @@ only terrain to use the much neglected impact crater function class TerrainHeightWaterSolidCanyons; class TerrainHeightWaterSolid; - class TerrainColorAsteroid; class TerrainColorBandedRock; class TerrainColorBlack; diff --git a/src/terrain/TerrainColorAsteroid.cpp b/src/terrain/TerrainColorAsteroid.cpp index fa9f97f1b..0a2dbc7fd 100644 --- a/src/terrain/TerrainColorAsteroid.cpp +++ b/src/terrain/TerrainColorAsteroid.cpp @@ -10,33 +10,34 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Asteroid"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height/2; + double n = m_invMaxHeight * height / 2; if (n <= 0.02) { const double flatness = pow(p.Dot(norm), 6.0); const vector3d color_cliffs = m_rockColor[1]; - double equatorial_desert = (2.0)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0)*(1.0-p.y*p.y); + double equatorial_desert = (2.0) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0) * (1.0 - p.y * p.y); vector3d col; col = interpolate_color(equatorial_desert, m_rockColor[0], m_greyrockColor[3]); - col = interpolate_color(n, col, vector3d(1.5,1.35,1.3)); + col = interpolate_color(n, col, vector3d(1.5, 1.35, 1.3)); col = interpolate_color(flatness, color_cliffs, col); return col; } else { const double flatness = pow(p.Dot(norm), 6.0); const vector3d color_cliffs = m_greyrockColor[1]; - double equatorial_desert = (2.0)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0)*(1.0-p.y*p.y); + double equatorial_desert = (2.0) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0) * (1.0 - p.y * p.y); vector3d col; col = interpolate_color(equatorial_desert, m_greyrockColor[0], m_greyrockColor[2]); @@ -45,4 +46,3 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, return col; } } - diff --git a/src/terrain/TerrainColorBandedRock.cpp b/src/terrain/TerrainColorBandedRock.cpp index 1b5cf11f7..1cab848a1 100644 --- a/src/terrain/TerrainColorBandedRock.cpp +++ b/src/terrain/TerrainColorBandedRock.cpp @@ -10,7 +10,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "BandedRock"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } @@ -18,8 +19,7 @@ template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { const double flatness = pow(p.Dot(norm), 6.0); - double n = fabs(noise(vector3d(height*10000.0,0.0,0.0))); + double n = fabs(noise(vector3d(height * 10000.0, 0.0, 0.0))); vector3d col = interpolate_color(n, m_rockColor[0], m_rockColor[1]); return interpolate_color(flatness, col, m_rockColor[2]); } - diff --git a/src/terrain/TerrainColorBlack.cpp b/src/terrain/TerrainColorBlack.cpp index 62a6a4005..682ea42b7 100644 --- a/src/terrain/TerrainColorBlack.cpp +++ b/src/terrain/TerrainColorBlack.cpp @@ -9,7 +9,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Solid"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } diff --git a/src/terrain/TerrainColorDeadWithWater.cpp b/src/terrain/TerrainColorDeadWithWater.cpp index ebb215fa5..d827d96f3 100644 --- a/src/terrain/TerrainColorDeadWithWater.cpp +++ b/src/terrain/TerrainColorDeadWithWater.cpp @@ -10,7 +10,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "DeadWithWater"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { m_surfaceEffects |= Terrain::EFFECT_WATER; } @@ -18,8 +19,9 @@ TerrainColorFractal::TerrainColorFractal(const System template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; - if (n <= 0) return vector3d(0.0,0.0,0.5); - else return interpolate_color(n, vector3d(.2,.2,.2), vector3d(.6,.6,.6)); + double n = m_invMaxHeight * height; + if (n <= 0) + return vector3d(0.0, 0.0, 0.5); + else + return interpolate_color(n, vector3d(.2, .2, .2), vector3d(.6, .6, .6)); } - diff --git a/src/terrain/TerrainColorDesert.cpp b/src/terrain/TerrainColorDesert.cpp index 839b26528..cfb65a59b 100644 --- a/src/terrain/TerrainColorDesert.cpp +++ b/src/terrain/TerrainColorDesert.cpp @@ -10,33 +10,34 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Desert"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height/2; + double n = m_invMaxHeight * height / 2; const double flatness = pow(p.Dot(norm), 6.0); const vector3d color_cliffs = m_rockColor[1]; // Ice has been left as is so the occasional desert world will have polar ice-caps like mars - if (fabs(m_icyness*p.y) + m_icyness*n > 1) { - return interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + if (fabs(m_icyness * p.y) + m_icyness * n > 1) { + return interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); } - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); vector3d col; if (n > .4) { - n = n*n; - col = interpolate_color(equatorial_desert, vector3d(.8,.75,.5), vector3d(.52, .5, .3)); + n = n * n; + col = interpolate_color(equatorial_desert, vector3d(.8, .75, .5), vector3d(.52, .5, .3)); col = interpolate_color(n, col, vector3d(.1, .0, .0)); col = interpolate_color(flatness, color_cliffs, col); return col; } else if (n > .3) { - n = n*n; + n = n * n; col = interpolate_color(equatorial_desert, vector3d(.81, .68, .3), vector3d(.85, .7, 0)); - col = interpolate_color(n, col, vector3d(-1.2,-.84,.35)); + col = interpolate_color(n, col, vector3d(-1.2, -.84, .35)); col = interpolate_color(flatness, color_cliffs, col); return col; } else if (n > .2) { @@ -51,4 +52,3 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do return col; } } - diff --git a/src/terrain/TerrainColorEarthLike.cpp b/src/terrain/TerrainColorEarthLike.cpp index 1aeafca0d..034dfe3ea 100644 --- a/src/terrain/TerrainColorEarthLike.cpp +++ b/src/terrain/TerrainColorEarthLike.cpp @@ -10,7 +10,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "EarthLike"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { // crappy water //double height = m_maxHeightInMeters*0.5; @@ -22,52 +23,54 @@ TerrainColorFractal::TerrainColorFractal(const SystemBody template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; double flatness = pow(p.Dot(norm), 8.0); double continents = 0; - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); vector3d color_cliffs = m_darkrockColor[5]; vector3d col, tex1, tex2; // ice on mountains //Output("flatness : %d", flatness); - if (flatness > 0.6/Clamp(n*m_icyness+(m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)), 0.1, 1.0)) { + if (flatness > 0.6 / Clamp(n * m_icyness + (m_icyness * 0.5) + (fabs(p.y * p.y * p.y * 0.38)), 0.1, 1.0)) { if (textures) { col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]); - col = interpolate_color(flatness, col, vector3d(1,1,1)); - } else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); + } else + col = interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); return col; } //polar ice-caps - if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) { + if ((m_icyness * 0.5) + (fabs(p.y * p.y * p.y * 0.38)) > 0.6) { //if (flatness > 0.5/Clamp(fabs(p.y*m_icyness), 0.1, 1.0)) { if (textures) { col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]); - col = interpolate_color(flatness, col, vector3d(1,1,1)); - } else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); + } else + col = interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); return col; } - // This is for fake ocean depth by the coast. - continents = ridged_octavenoise(GetFracDef(3-m_fracnum), 0.55, p) * (1.0-m_sealevel) - ((m_sealevel*0.1)-0.1); + continents = ridged_octavenoise(GetFracDef(3 - m_fracnum), 0.55, p) * (1.0 - m_sealevel) - ((m_sealevel * 0.1) - 0.1); // water if (n <= 0) { // Oooh, pretty coastal regions with shading based on underwater depth. - n += continents;// - (GetFracDef(3).amplitude*m_sealevel*0.49); - n *= n*10.0; + n += continents; // - (GetFracDef(3).amplitude*m_sealevel*0.49); + n *= n * 10.0; //n = (n>0.3 ? 0.3-(n*n*n-0.027) : n); - col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25)); - col = interpolate_color(n, col, vector3d(0,0.8,0.6)); + col = interpolate_color(equatorial_desert, vector3d(0, 0, 0.15), vector3d(0, 0, 0.25)); + col = interpolate_color(n, col, vector3d(0, 0.8, 0.6)); return col; } flatness = pow(p.Dot(norm), 16.0); // More sensitive height detection for application of colours if (n > 0.5) { - n -= 0.5; n *= 2.0; + n -= 0.5; + n *= 2.0; color_cliffs = interpolate_color(n, m_darkrockColor[2], m_rockColor[4]); col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]); col = interpolate_color(n, col, m_darkrockColor[6]); @@ -75,11 +78,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.25) { - n -= 0.25; n *= 4.0; + } else if (n > 0.25) { + n -= 0.25; + n *= 4.0; color_cliffs = interpolate_color(n, m_rockColor[3], m_darkplantColor[4]); col = interpolate_color(equatorial_desert, m_darkrockColor[3], m_darksandColor[1]); col = interpolate_color(n, col, m_rockColor[2]); @@ -87,11 +91,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.05) { - n -= 0.05; n *= 5.0; + } else if (n > 0.05) { + n -= 0.05; + n *= 5.0; color_cliffs = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]); col = interpolate_color(equatorial_desert, m_darkplantColor[2], m_sandColor[2]); col = interpolate_color(n, col, m_darkrockColor[3]); @@ -99,11 +104,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_forest, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.01) { - n -= 0.01; n *= 25.0; + } else if (n > 0.01) { + n -= 0.01; + n *= 25.0; color_cliffs = m_darkdirtColor[7]; col = interpolate_color(equatorial_desert, m_plantColor[1], m_plantColor[0]); col = interpolate_color(n, col, m_darkplantColor[2]); @@ -111,11 +117,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.005) { - n -= 0.005; n *= 200.0; + } else if (n > 0.005) { + n -= 0.005; + n *= 200.0; color_cliffs = m_dirtColor[2]; col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]); col = interpolate_color(n, col, m_plantColor[0]); @@ -123,10 +130,10 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else { + } else { n *= 200.0; color_cliffs = m_darksandColor[0]; col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]); @@ -140,4 +147,3 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, } } } - diff --git a/src/terrain/TerrainColorEarthLikeHeightmapped.cpp b/src/terrain/TerrainColorEarthLikeHeightmapped.cpp index ec6d2be9a..c89981473 100644 --- a/src/terrain/TerrainColorEarthLikeHeightmapped.cpp +++ b/src/terrain/TerrainColorEarthLikeHeightmapped.cpp @@ -10,7 +10,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "EarthLikeHeightmapped"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { // crappy water //double height = m_maxHeightInMeters*0.5; @@ -22,30 +23,32 @@ TerrainColorFractal::TerrainColorFractal(cons template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; double flatness = pow(p.Dot(norm), 8.0); - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); vector3d color_cliffs = m_darkrockColor[5]; vector3d col, tex1, tex2; if (n > 0) { // ice on mountains - if (flatness > 0.6/Clamp(n*m_icyness+(m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)), 0.1, 1.0)) { + if (flatness > 0.6 / Clamp(n * m_icyness + (m_icyness * 0.5) + (fabs(p.y * p.y * p.y * 0.38)), 0.1, 1.0)) { if (textures) { col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]); - col = interpolate_color(flatness, col, vector3d(1,1,1)); - } else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); + } else + col = interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); return col; } //polar ice-caps - if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) { + if ((m_icyness * 0.5) + (fabs(p.y * p.y * p.y * 0.38)) > 0.6) { //if (flatness > 0.5/Clamp(fabs(p.y*m_icyness), 0.1, 1.0)) { if (textures) { col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]); - col = interpolate_color(flatness, col, vector3d(1,1,1)); - } else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); + } else + col = interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); return col; } } @@ -57,14 +60,15 @@ vector3d TerrainColorFractal::GetColor(const n += terrain_colournoise_water; n *= 0.1; } - col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25)); - col = interpolate_color(n, col, vector3d(0,0.8,0.6)); + col = interpolate_color(equatorial_desert, vector3d(0, 0, 0.15), vector3d(0, 0, 0.25)); + col = interpolate_color(n, col, vector3d(0, 0.8, 0.6)); return col; } flatness = pow(p.Dot(norm), 16.0); // More sensitive height detection for application of colours if (n > 0.5) { - n -= 0.5; n *= 2.0; + n -= 0.5; + n *= 2.0; color_cliffs = interpolate_color(n, m_darkrockColor[2], m_rockColor[4]); col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]); col = interpolate_color(n, col, m_darkrockColor[6]); @@ -72,11 +76,12 @@ vector3d TerrainColorFractal::GetColor(const tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.25) { - n -= 0.25; n *= 4.0; + } else if (n > 0.25) { + n -= 0.25; + n *= 4.0; color_cliffs = interpolate_color(n, m_rockColor[3], m_darkplantColor[4]); col = interpolate_color(equatorial_desert, m_darkrockColor[3], m_darksandColor[1]); col = interpolate_color(n, col, m_rockColor[2]); @@ -84,11 +89,12 @@ vector3d TerrainColorFractal::GetColor(const tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.05) { - n -= 0.05; n *= 5.0; + } else if (n > 0.05) { + n -= 0.05; + n *= 5.0; color_cliffs = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]); col = interpolate_color(equatorial_desert, m_darkplantColor[2], m_sandColor[2]); col = interpolate_color(n, col, m_darkrockColor[3]); @@ -96,11 +102,12 @@ vector3d TerrainColorFractal::GetColor(const tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_forest, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.01) { - n -= 0.01; n *= 25.0; + } else if (n > 0.01) { + n -= 0.01; + n *= 25.0; color_cliffs = m_darkdirtColor[7]; col = interpolate_color(equatorial_desert, m_plantColor[1], m_plantColor[0]); col = interpolate_color(n, col, m_darkplantColor[2]); @@ -108,11 +115,12 @@ vector3d TerrainColorFractal::GetColor(const tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.005) { - n -= 0.005; n *= 200.0; + } else if (n > 0.005) { + n -= 0.005; + n *= 200.0; color_cliffs = m_dirtColor[2]; col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]); col = interpolate_color(n, col, m_plantColor[0]); @@ -120,10 +128,10 @@ vector3d TerrainColorFractal::GetColor(const tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else { + } else { n *= 200.0; color_cliffs = m_darksandColor[0]; col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]); @@ -137,4 +145,3 @@ vector3d TerrainColorFractal::GetColor(const } } } - diff --git a/src/terrain/TerrainColorGGJupiter.cpp b/src/terrain/TerrainColorGGJupiter.cpp index 5f8ef75a1..1c6242465 100644 --- a/src/terrain/TerrainColorGGJupiter.cpp +++ b/src/terrain/TerrainColorGGJupiter.cpp @@ -10,22 +10,24 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGJupiter"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { // spots - const double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 1e8, 1000.0*m_fracmult); - SetFracDef(1, height, 8e7, 1000.0*m_fracmult); - SetFracDef(2, height, 4e7, 1000.0*m_fracmult); - SetFracDef(3, height, 1e7, 100.0*m_fracmult); + const double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 1e8, 1000.0 * m_fracmult); + SetFracDef(1, height, 8e7, 1000.0 * m_fracmult); + SetFracDef(2, height, 4e7, 1000.0 * m_fracmult); + SetFracDef(3, height, 1e7, 100.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { double n; - const double h = river_octavenoise(GetFracDef(0), 0.5*m_entropy[0] + 0.25f, - vector3d(noise(vector3d(p.x*8, p.y*32, p.z*8))))*.125; + const double h = river_octavenoise(GetFracDef(0), 0.5 * m_entropy[0] + 0.25f, + vector3d(noise(vector3d(p.x * 8, p.y * 32, p.z * 8)))) * + .125; const double equatorial_region_1 = billow_octavenoise(GetFracDef(0), 0.7, p) * p.y * p.x; const double equatorial_region_2 = octavenoise(GetFracDef(1), 0.8, p) * p.x * p.x; vector3d col; @@ -33,132 +35,140 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, col = interpolate_color(equatorial_region_2, col, vector3d(.45, .3, .0)); //top stripe if (p.y < 0.5 && p.y > 0.1) { - for(float i=-1 ; i < 1; i+=0.6f){ + for (float i = -1; i < 1; i += 0.6f) { double temp = p.y - i; - if ( temp < .15+h && temp > -.15+h ){ - n = billow_octavenoise(GetFracDef(2), 0.7*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); - n += 0.5*octavenoise(GetFracDef(1), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii, p.z))*p); - n += ridged_octavenoise(GetFracDef(1), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); + if (temp < .15 + h && temp > -.15 + h) { + n = billow_octavenoise(GetFracDef(2), 0.7 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); + n += 0.5 * octavenoise(GetFracDef(1), 0.6 * m_entropy[0], noise(vector3d(p.x, p.y * m_planetEarthRadii, p.z)) * p); + n += ridged_octavenoise(GetFracDef(1), 0.6 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); //n += 0.5; n *= n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); - if (n >0.8) { - n -= 0.8; n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[7] ); + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); + if (n > 0.8) { + n -= 0.8; + n *= 5.0; + col = interpolate_color(n, col, m_ggdarkColor[7]); return col; - } else if (n>0.6) { - n -= 0.6; n*= 5.0; - col = interpolate_color(n, m_gglightColor[4], col ); + } else if (n > 0.6) { + n -= 0.6; + n *= 5.0; + col = interpolate_color(n, m_gglightColor[4], col); return col; - } else if (n>0.4) { - n -= 0.4; n*= 5.0; - col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4] ); + } else if (n > 0.4) { + n -= 0.4; + n *= 5.0; + col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4]); return col; - } else if (n>0.2) { - n -= 0.2; n*= 5.0; - col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85) ); + } else if (n > 0.2) { + n -= 0.2; + n *= 5.0; + col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85)); return col; } else { n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; } } } // bottom stripe } else if (p.y < -0.1 && p.y > -0.5) { - for(float i=-1 ; i < 1; i+=0.6f){ + for (float i = -1; i < 1; i += 0.6f) { double temp = p.y - i; - if ( temp < .15+h && temp > -.15+h ){ - n = billow_octavenoise(GetFracDef(2), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); - n += 0.5*octavenoise(GetFracDef(1), 0.7*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii, p.z))*p); - n += ridged_octavenoise(GetFracDef(1), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); + if (temp < .15 + h && temp > -.15 + h) { + n = billow_octavenoise(GetFracDef(2), 0.6 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); + n += 0.5 * octavenoise(GetFracDef(1), 0.7 * m_entropy[0], noise(vector3d(p.x, p.y * m_planetEarthRadii, p.z)) * p); + n += ridged_octavenoise(GetFracDef(1), 0.6 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); //n += 0.5; //n *= n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); - if (n >0.8) { - n -= 0.8; n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[7] ); + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); + if (n > 0.8) { + n -= 0.8; + n *= 5.0; + col = interpolate_color(n, col, m_ggdarkColor[7]); return col; - } else if (n>0.6) { - n -= 0.6; n*= 5.0; - col = interpolate_color(n, m_gglightColor[4], col ); + } else if (n > 0.6) { + n -= 0.6; + n *= 5.0; + col = interpolate_color(n, m_gglightColor[4], col); return col; - } else if (n>0.4) { - n -= 0.4; n*= 5.0; - col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4] ); + } else if (n > 0.4) { + n -= 0.4; + n *= 5.0; + col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4]); return col; - } else if (n>0.2) { - n -= 0.2; n*= 5.0; - col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85) ); + } else if (n > 0.2) { + n -= 0.2; + n *= 5.0; + col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85)); return col; } else { n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; } } } - } else { //small stripes - for(float i=-1 ; i < 1; i+=0.3f){ + } else { //small stripes + for (float i = -1; i < 1; i += 0.3f) { double temp = p.y - i; - if ( temp < .1+h && temp > -.0+h ){ - n = billow_octavenoise(GetFracDef(2), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); - n += 0.5*octavenoise(GetFracDef(1), 0.6*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii, p.z))*p); - n += ridged_octavenoise(GetFracDef(1), 0.7*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); + if (temp < .1 + h && temp > -.0 + h) { + n = billow_octavenoise(GetFracDef(2), 0.6 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); + n += 0.5 * octavenoise(GetFracDef(1), 0.6 * m_entropy[0], noise(vector3d(p.x, p.y * m_planetEarthRadii, p.z)) * p); + n += ridged_octavenoise(GetFracDef(1), 0.7 * m_entropy[0], + noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); //n += 0.5; //n *= n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); - if (n >0.8) { - n -= 0.8; n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[7] ); + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); + if (n > 0.8) { + n -= 0.8; + n *= 5.0; + col = interpolate_color(n, col, m_ggdarkColor[7]); return col; - } else if (n>0.6) { - n -= 0.6; n*= 5.0; - col = interpolate_color(n, m_gglightColor[4], col ); + } else if (n > 0.6) { + n -= 0.6; + n *= 5.0; + col = interpolate_color(n, m_gglightColor[4], col); return col; - } else if (n>0.4) { - n -= 0.4; n*= 5.0; - col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4] ); + } else if (n > 0.4) { + n -= 0.4; + n *= 5.0; + col = interpolate_color(n, vector3d(.9, .89, .85), m_gglightColor[4]); return col; - } else if (n>0.2) { - n -= 0.2; n*= 5.0; - col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85) ); + } else if (n > 0.2) { + n -= 0.2; + n *= 5.0; + col = interpolate_color(n, m_ggdarkColor[2], vector3d(.9, .89, .85)); return col; } else { n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; } } } } //if is not a stripe. - n = octavenoise(GetFracDef(1), 0.6*m_entropy[0] + - 0.25f,noise(vector3d(p.x, p.y*m_planetEarthRadii*3, p.z))*p); - n *= n*n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); + n = octavenoise(GetFracDef(1), 0.6 * m_entropy[0] + 0.25f, noise(vector3d(p.x, p.y * m_planetEarthRadii * 3, p.z)) * p); + n *= n * n; + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); - if (n>0.5) { - n -= 0.5; n*= 2.0; - col = interpolate_color(n, col, m_gglightColor[2] ); + if (n > 0.5) { + n -= 0.5; + n *= 2.0; + col = interpolate_color(n, col, m_gglightColor[2]); return col; } else { n *= 2.0; - col = interpolate_color(n, vector3d(.9, .89, .85), col ); + col = interpolate_color(n, vector3d(.9, .89, .85), col); return col; } } - diff --git a/src/terrain/TerrainColorGGNeptune.cpp b/src/terrain/TerrainColorGGNeptune.cpp index 8dbce7f46..6a4101fd6 100644 --- a/src/terrain/TerrainColorGGNeptune.cpp +++ b/src/terrain/TerrainColorGGNeptune.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,29 +12,29 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGNeptune"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - const double height = m_maxHeightInMeters*0.1; + const double height = m_maxHeightInMeters * 0.1; //spot boundary - SetFracDef(0, height, 3e7, 10000000.0*m_fracmult); + SetFracDef(0, height, 3e7, 10000000.0 * m_fracmult); //spot - SetFracDef(1, height, 9e7, 100.0*m_fracmult); + SetFracDef(1, height, 9e7, 100.0 * m_fracmult); //bands - SetFracDef(2, height, 8e7, 1000.0*m_fracmult); - SetFracDef(3, height, 1e8, 1000.0*m_fracmult); + SetFracDef(2, height, 8e7, 1000.0 * m_fracmult); + SetFracDef(3, height, 1e8, 1000.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = 0.8*octavenoise(GetFracDef(2), 0.6, vector3d(3.142*p.y*p.y)); - n += 0.25*ridged_octavenoise(GetFracDef(3), 0.55, vector3d(3.142*p.y*p.y)); - n += 0.2*octavenoise(GetFracDef(3), 0.5, vector3d(3.142*p.y*p.y)); + double n = 0.8 * octavenoise(GetFracDef(2), 0.6, vector3d(3.142 * p.y * p.y)); + n += 0.25 * ridged_octavenoise(GetFracDef(3), 0.55, vector3d(3.142 * p.y * p.y)); + n += 0.2 * octavenoise(GetFracDef(3), 0.5, vector3d(3.142 * p.y * p.y)); //spot - n += 0.8*billow_octavenoise(GetFracDef(1), 0.8, vector3d(noise(p*3.142)*p))* - megavolcano_function(GetFracDef(0), p); + n += 0.8 * billow_octavenoise(GetFracDef(1), 0.8, vector3d(noise(p * 3.142) * p)) * + megavolcano_function(GetFracDef(0), p); n /= 2.0; - n *= n*n; - return interpolate_color(n, vector3d(.04, .05, .15), vector3d(.80,.94,.96)); + n *= n * n; + return interpolate_color(n, vector3d(.04, .05, .15), vector3d(.80, .94, .96)); } - diff --git a/src/terrain/TerrainColorGGNeptune2.cpp b/src/terrain/TerrainColorGGNeptune2.cpp index bd9ae8534..f1df59d2e 100644 --- a/src/terrain/TerrainColorGGNeptune2.cpp +++ b/src/terrain/TerrainColorGGNeptune2.cpp @@ -10,22 +10,24 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGNeptune2"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { // spots - const double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 2e8, 1000.0*m_fracmult); - SetFracDef(1, height, 9e7, 1000.0*m_fracmult); - SetFracDef(2, height, 6e7, 1000.0*m_fracmult); - SetFracDef(3, height, 1e8, 100.0*m_fracmult); + const double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 2e8, 1000.0 * m_fracmult); + SetFracDef(1, height, 9e7, 1000.0 * m_fracmult); + SetFracDef(2, height, 6e7, 1000.0 * m_fracmult); + SetFracDef(3, height, 1e8, 100.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { double n; - const double h = billow_octavenoise(GetFracDef(0), 0.5*m_entropy[0] + 0.25f, - vector3d(noise(vector3d(p.x*8, p.y*32, p.z*8))))*.125; + const double h = billow_octavenoise(GetFracDef(0), 0.5 * m_entropy[0] + 0.25f, + vector3d(noise(vector3d(p.x * 8, p.y * 32, p.z * 8)))) * + .125; const double equatorial_region_1 = billow_octavenoise(GetFracDef(0), 0.54, p) * p.y * p.x; const double equatorial_region_2 = octavenoise(GetFracDef(1), 0.58, p) * p.x * p.x; vector3d col; @@ -33,58 +35,59 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p col = interpolate_color(equatorial_region_2, col, vector3d(0, 0, .2)); //stripes if (p.y < 0.5 && p.y > -0.5) { - for(float i=-1 ; i < 1; i+=0.6f){ + for (float i = -1; i < 1; i += 0.6f) { double temp = p.y - i; - if ( temp < .07+h && temp > -.07+h ){ - n = 2.0*billow_octavenoise(GetFracDef(2), 0.5*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii*0.3, p.z))*p); - n += 0.8*octavenoise(GetFracDef(1), 0.5*m_entropy[0], - noise(vector3d(p.x, p.y*m_planetEarthRadii, p.z))*p); - n += 0.5*billow_octavenoise(GetFracDef(3), 0.6, p); + if (temp < .07 + h && temp > -.07 + h) { + n = 2.0 * billow_octavenoise(GetFracDef(2), 0.5 * m_entropy[0], noise(vector3d(p.x, p.y * m_planetEarthRadii * 0.3, p.z)) * p); + n += 0.8 * octavenoise(GetFracDef(1), 0.5 * m_entropy[0], noise(vector3d(p.x, p.y * m_planetEarthRadii, p.z)) * p); + n += 0.5 * billow_octavenoise(GetFracDef(3), 0.6, p); n *= n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); - if (n >0.8) { - n -= 0.8; n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); + if (n > 0.8) { + n -= 0.8; + n *= 5.0; + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; - } else if (n>0.6) { - n -= 0.6; n*= 5.0; - col = interpolate_color(n, vector3d(.03, .03, .15), col ); + } else if (n > 0.6) { + n -= 0.6; + n *= 5.0; + col = interpolate_color(n, vector3d(.03, .03, .15), col); return col; - } else if (n>0.4) { - n -= 0.4; n*= 5.0; - col = interpolate_color(n, vector3d(.0, .0, .05), vector3d(.03, .03, .15) ); + } else if (n > 0.4) { + n -= 0.4; + n *= 5.0; + col = interpolate_color(n, vector3d(.0, .0, .05), vector3d(.03, .03, .15)); return col; - } else if (n>0.2) { - n -= 0.2; n*= 5.0; - col = interpolate_color(n, m_ggdarkColor[2], vector3d(.0, .0, .05) ); + } else if (n > 0.2) { + n -= 0.2; + n *= 5.0; + col = interpolate_color(n, m_ggdarkColor[2], vector3d(.0, .0, .05)); return col; } else { n *= 5.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; } } } } //if is not a stripe. - n = octavenoise(GetFracDef(1), 0.5*m_entropy[0] + - 0.25f,noise(vector3d(p.x*0.2, p.y*m_planetEarthRadii*10, p.z))*p); + n = octavenoise(GetFracDef(1), 0.5 * m_entropy[0] + 0.25f, noise(vector3d(p.x * 0.2, p.y * m_planetEarthRadii * 10, p.z)) * p); //n += 0.5; //n += octavenoise(GetFracDef(0), 0.6*m_entropy[0], 3.142*p.z*p.z); - n *= n*n*n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); + n *= n * n * n; + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); - if (n>0.5) { - n -= 0.5; n*= 2.0; - col = interpolate_color(n, col, m_ggdarkColor[2] ); + if (n > 0.5) { + n -= 0.5; + n *= 2.0; + col = interpolate_color(n, col, m_ggdarkColor[2]); return col; } else { n *= 2.0; - col = interpolate_color(n, vector3d(.0, .0, .0), col ); + col = interpolate_color(n, vector3d(.0, .0, .0), col); return col; } } - diff --git a/src/terrain/TerrainColorGGSaturn.cpp b/src/terrain/TerrainColorGGSaturn.cpp index 95adddb02..b006af6b9 100644 --- a/src/terrain/TerrainColorGGSaturn.cpp +++ b/src/terrain/TerrainColorGGSaturn.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,29 +12,29 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGSaturn"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - const double height = m_maxHeightInMeters*0.1; + const double height = m_maxHeightInMeters * 0.1; //spot + clouds - SetFracDef(0, height, 3e7, 10.0*m_fracmult); - SetFracDef(1, height, 9e7, 1000.0*m_fracmult); - SetFracDef(2, height, 8e7, 100.0*m_fracmult); + SetFracDef(0, height, 3e7, 10.0 * m_fracmult); + SetFracDef(1, height, 9e7, 1000.0 * m_fracmult); + SetFracDef(2, height, 8e7, 100.0 * m_fracmult); //spot boundary - SetFracDef(3, height, 3e7, 10000000.0*m_fracmult); + SetFracDef(3, height, 3e7, 10000000.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = 0.4*ridged_octavenoise(GetFracDef(0), 0.7, vector3d(3.142*p.y*p.y)); - n += 0.4*octavenoise(GetFracDef(1), 0.6, vector3d(3.142*p.y*p.y)); - n += 0.3*octavenoise(GetFracDef(2), 0.5, vector3d(3.142*p.y*p.y)); - n += 0.8*octavenoise(GetFracDef(0), 0.7, vector3d(p*p.y*p.y)); - n += 0.5*ridged_octavenoise(GetFracDef(1), 0.7, vector3d(p*p.y*p.y)); + double n = 0.4 * ridged_octavenoise(GetFracDef(0), 0.7, vector3d(3.142 * p.y * p.y)); + n += 0.4 * octavenoise(GetFracDef(1), 0.6, vector3d(3.142 * p.y * p.y)); + n += 0.3 * octavenoise(GetFracDef(2), 0.5, vector3d(3.142 * p.y * p.y)); + n += 0.8 * octavenoise(GetFracDef(0), 0.7, vector3d(p * p.y * p.y)); + n += 0.5 * ridged_octavenoise(GetFracDef(1), 0.7, vector3d(p * p.y * p.y)); n /= 2.0; - n *= n*n; - n += billow_octavenoise(GetFracDef(0), 0.8, vector3d(noise(p*3.142)*p))* - megavolcano_function(GetFracDef(3), p); + n *= n * n; + n += billow_octavenoise(GetFracDef(0), 0.8, vector3d(noise(p * 3.142) * p)) * + megavolcano_function(GetFracDef(3), p); return interpolate_color(n, vector3d(.69, .53, .43), vector3d(.99, .76, .62)); } - diff --git a/src/terrain/TerrainColorGGSaturn2.cpp b/src/terrain/TerrainColorGGSaturn2.cpp index a4db631a9..4b600ec70 100644 --- a/src/terrain/TerrainColorGGSaturn2.cpp +++ b/src/terrain/TerrainColorGGSaturn2.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,54 +12,58 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGSaturn2"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - const double height = m_maxHeightInMeters*0.1; + const double height = m_maxHeightInMeters * 0.1; //spot + clouds - SetFracDef(0, height, 3e7, 10.0*m_fracmult); - SetFracDef(1, height, 9e7, 1000.0*m_fracmult); - SetFracDef(2, height, 8e7, 100.0*m_fracmult); + SetFracDef(0, height, 3e7, 10.0 * m_fracmult); + SetFracDef(1, height, 9e7, 1000.0 * m_fracmult); + SetFracDef(2, height, 8e7, 100.0 * m_fracmult); //spot boundary - SetFracDef(3, height, 3e7, 10000000.0*m_fracmult); + SetFracDef(3, height, 3e7, 10000000.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = 0.2*billow_octavenoise(GetFracDef(0), 0.8, p*p.y*p.y); - n += 0.5*ridged_octavenoise(GetFracDef(1), 0.7, p*p.y*p.y); - n += 0.25*octavenoise(GetFracDef(2), 0.7, p*p.y*p.y); + double n = 0.2 * billow_octavenoise(GetFracDef(0), 0.8, p * p.y * p.y); + n += 0.5 * ridged_octavenoise(GetFracDef(1), 0.7, p * p.y * p.y); + n += 0.25 * octavenoise(GetFracDef(2), 0.7, p * p.y * p.y); //spot - n *= n*n*0.5; - n += billow_octavenoise(GetFracDef(0), 0.8, noise(p*3.142)*p)* - megavolcano_function(GetFracDef(3), p); + n *= n * n * 0.5; + n += billow_octavenoise(GetFracDef(0), 0.8, noise(p * 3.142) * p) * + megavolcano_function(GetFracDef(3), p); vector3d col; //col = interpolate_color(octavenoise(GetFracDef(2), 0.7, noise(p*3.142)*p), vector3d(.05, .0, .0), vector3d(.4,.0,.35)); if (n > 1.0) { - n -= 1.0;// n *= 5.0; - col = interpolate_color(n, vector3d(.25, .3, .4), vector3d(.0, .2, .0) ); - } else if (n >0.8) { - n -= 0.8; n *= 5.0; - col = interpolate_color(n, vector3d(.0, .0, .15), vector3d(.25, .3, .4) ); + n -= 1.0; // n *= 5.0; + col = interpolate_color(n, vector3d(.25, .3, .4), vector3d(.0, .2, .0)); + } else if (n > 0.8) { + n -= 0.8; + n *= 5.0; + col = interpolate_color(n, vector3d(.0, .0, .15), vector3d(.25, .3, .4)); return col; - } else if (n>0.6) { - n -= 0.6; n*= 5.0; - col = interpolate_color(n, vector3d(.0, .0, .1), vector3d(.0, .0, .15) ); + } else if (n > 0.6) { + n -= 0.6; + n *= 5.0; + col = interpolate_color(n, vector3d(.0, .0, .1), vector3d(.0, .0, .15)); return col; - } else if (n>0.4) { - n -= 0.4; n*= 5.0; - col = interpolate_color(n, vector3d(.05, .0, .05), vector3d(.0, .0, .1) ); + } else if (n > 0.4) { + n -= 0.4; + n *= 5.0; + col = interpolate_color(n, vector3d(.05, .0, .05), vector3d(.0, .0, .1)); return col; - } else if (n>0.2) { - n -= 0.2; n*= 5.0; - col = interpolate_color(n, vector3d(.0, .0, .1), vector3d(.05, .0, .05) ); + } else if (n > 0.2) { + n -= 0.2; + n *= 5.0; + col = interpolate_color(n, vector3d(.0, .0, .1), vector3d(.05, .0, .05)); return col; } else { n *= 5.0; - col = interpolate_color(n, vector3d(.0, .0, .0), vector3d(.0, .0, .1) ); + col = interpolate_color(n, vector3d(.0, .0, .0), vector3d(.0, .0, .1)); return col; } // never happens, just silencing a warning return col; } - diff --git a/src/terrain/TerrainColorGGUranus.cpp b/src/terrain/TerrainColorGGUranus.cpp index 6eacb789e..0bc5c3f12 100644 --- a/src/terrain/TerrainColorGGUranus.cpp +++ b/src/terrain/TerrainColorGGUranus.cpp @@ -10,22 +10,22 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "GGUranus"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - const double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 3e7, 1000.0*m_fracmult); - SetFracDef(1, height, 9e7, 1000.0*m_fracmult); - SetFracDef(2, height, 8e7, 1000.0*m_fracmult); + const double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 3e7, 1000.0 * m_fracmult); + SetFracDef(1, height, 9e7, 1000.0 * m_fracmult); + SetFracDef(2, height, 8e7, 1000.0 * m_fracmult); } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = 0.5*ridged_octavenoise(GetFracDef(0), 0.7, vector3d(3.142*p.y*p.y)); - n += 0.5*octavenoise(GetFracDef(1), 0.6, vector3d(3.142*p.y*p.y)); - n += 0.2*octavenoise(GetFracDef(2), 0.5, vector3d(3.142*p.y*p.y)); + double n = 0.5 * ridged_octavenoise(GetFracDef(0), 0.7, vector3d(3.142 * p.y * p.y)); + n += 0.5 * octavenoise(GetFracDef(1), 0.6, vector3d(3.142 * p.y * p.y)); + n += 0.2 * octavenoise(GetFracDef(2), 0.5, vector3d(3.142 * p.y * p.y)); n /= 2.0; - n *= n*n; - return interpolate_color(n, vector3d(.4, .5, .55), vector3d(.85,.95,.96)); + n *= n * n; + return interpolate_color(n, vector3d(.4, .5, .55), vector3d(.85, .95, .96)); } - diff --git a/src/terrain/TerrainColorIce.cpp b/src/terrain/TerrainColorIce.cpp index afcbe3e03..657f29a5c 100644 --- a/src/terrain/TerrainColorIce.cpp +++ b/src/terrain/TerrainColorIce.cpp @@ -10,51 +10,51 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Ice"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; - if (n <= 0.0) return vector3d(0.96,0.96,0.96); + if (n <= 0.0) return vector3d(0.96, 0.96, 0.96); const double flatness = pow(p.Dot(norm), 24.0); - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); double equatorial_region_1 = billow_octavenoise(GetFracDef(0), 0.5, p) * p.y * p.y; double equatorial_region_2 = ridged_octavenoise(GetFracDef(5), 0.5, p) * p.x * p.x; // cliff colours vector3d color_cliffs; // adds some variation - color_cliffs = interpolate_color(equatorial_region_1, m_rockColor[3], m_rockColor[0] ); - color_cliffs = interpolate_color(equatorial_region_2, color_cliffs, m_rockColor[2] ); + color_cliffs = interpolate_color(equatorial_region_1, m_rockColor[3], m_rockColor[0]); + color_cliffs = interpolate_color(equatorial_region_2, color_cliffs, m_rockColor[2]); // main colours vector3d col; // start by interpolating between noise values for variation - col = interpolate_color(equatorial_region_1, m_darkrockColor[0], vector3d(1, 1, 1) ); - col = interpolate_color(equatorial_region_2, m_darkrockColor[1], col ); + col = interpolate_color(equatorial_region_1, m_darkrockColor[0], vector3d(1, 1, 1)); + col = interpolate_color(equatorial_region_2, m_darkrockColor[1], col); col = interpolate_color(equatorial_desert, col, vector3d(.96, .95, .94)); // scale by different colours depending on height for more variation if (n > .666) { - n -= 0.666; n*= 3.0; + n -= 0.666; + n *= 3.0; col = interpolate_color(n, vector3d(.96, .95, .94), col); col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.333) { - n -= 0.333; n*= 3.0; + } else if (n > 0.333) { + n -= 0.333; + n *= 3.0; col = interpolate_color(n, col, vector3d(.96, .95, .94)); col = interpolate_color(flatness, color_cliffs, col); return col; - } - else { + } else { n *= 3.0; col = interpolate_color(n, vector3d(.96, .95, .94), col); col = interpolate_color(flatness, color_cliffs, col); return col; } } - diff --git a/src/terrain/TerrainColorMethane.cpp b/src/terrain/TerrainColorMethane.cpp index 884775c2e..49de8c27a 100644 --- a/src/terrain/TerrainColorMethane.cpp +++ b/src/terrain/TerrainColorMethane.cpp @@ -10,15 +10,17 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Methane"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; - if (n <= 0) return vector3d(.3,.0,.0); - else return interpolate_color(n, vector3d(.3,.2,.0), vector3d(.6,.3,.0)); + double n = m_invMaxHeight * height; + if (n <= 0) + return vector3d(.3, .0, .0); + else + return interpolate_color(n, vector3d(.3, .2, .0), vector3d(.6, .3, .0)); } - diff --git a/src/terrain/TerrainColorRock.cpp b/src/terrain/TerrainColorRock.cpp index 5670140a3..3d21ec8fd 100644 --- a/src/terrain/TerrainColorRock.cpp +++ b/src/terrain/TerrainColorRock.cpp @@ -10,19 +10,20 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Rock"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height/2; + double n = m_invMaxHeight * height / 2; if (n <= 0) return m_darkrockColor[0]; const double flatness = pow(p.Dot(norm), 20.0); const vector3d color_cliffs = m_rockColor[0]; - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(4, 0.05, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(4, 0.05, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); //double equatorial_region = octavenoise(GetFracDef(0), 0.54, p) * p.y * p.x; //double equatorial_region_2 = ridged_octavenoise(GetFracDef(1), 0.58, p) * p.x * p.x; // Below is to do with variable colours for different heights, it gives a nice effect. @@ -32,104 +33,114 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, doub //col = interpolate_color(equatorial_region, col, m_darkrockColor[4]); //col = interpolate_color(equatorial_region_2, m_rockColor[1], col); if (n > 0.9) { - n -= 0.9; n *= 10.0; - col = interpolate_color(n, m_rockColor[5], col ); + n -= 0.9; + n *= 10.0; + col = interpolate_color(n, m_rockColor[5], col); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.8) { - n -= 0.8; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.8) { + n -= 0.8; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[5]); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.7) { - n -= 0.7; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.7) { + n -= 0.7; + n *= 10.0; col = interpolate_color(n, m_rockColor[4], col); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.6) { - n -= 0.6; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.6) { + n -= 0.6; + n *= 10.0; col = interpolate_color(n, m_rockColor[1], m_rockColor[4]); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.5) { - n -= 0.5; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.5) { + n -= 0.5; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[1]); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.4) { - n -= 0.4; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.4) { + n -= 0.4; + n *= 10.0; col = interpolate_color(n, m_darkrockColor[3], col); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; } if (n > 0.3) { - n -= 0.3; n *= 10.0; + n -= 0.3; + n *= 10.0; col = interpolate_color(n, col, m_darkrockColor[3]); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, m_darkrockColor[6]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.2) { - n -= 0.2; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.2) { + n -= 0.2; + n *= 10.0; col = interpolate_color(n, m_rockColor[1], col); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.1) { - n -= 0.1; n *= 10.0; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.1) { + n -= 0.1; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[1]); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else { + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else { n *= 10.0; col = interpolate_color(n, m_darkrockColor[0], col); if (textures) { tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); - return col; + } else + col = interpolate_color(flatness, color_cliffs, col); + return col; } } - diff --git a/src/terrain/TerrainColorRock2.cpp b/src/terrain/TerrainColorRock2.cpp index 5a02776c0..403e0df1c 100644 --- a/src/terrain/TerrainColorRock2.cpp +++ b/src/terrain/TerrainColorRock2.cpp @@ -10,19 +10,20 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Rock2"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height/2; + double n = m_invMaxHeight * height / 2; if (n <= 0) return m_darkrockColor[0]; const double flatness = pow(p.Dot(norm), 6.0); const vector3d color_cliffs = m_rockColor[0]; - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(4, 0.05, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(4, 0.05, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); //double equatorial_region = octavenoise(GetFracDef(0), 0.54, p) * p.y * p.x; //double equatorial_region_2 = ridged_octavenoise(GetFracDef(1), 0.58, p) * p.x * p.x; // Below is to do with variable colours for different heights, it gives a nice effect. @@ -32,64 +33,64 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, dou //col = interpolate_color(equatorial_region, col, m_darkrockColor[4]); //col = interpolate_color(equatorial_region_2, m_rockColor[1], col); if (n > 0.9) { - n -= 0.9; n *= 10.0; - col = interpolate_color(n, m_rockColor[5], col ); + n -= 0.9; + n *= 10.0; + col = interpolate_color(n, m_rockColor[5], col); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.8) { - n -= 0.8; n *= 10.0; + return col; + } else if (n > 0.8) { + n -= 0.8; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[5]); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.7) { - n -= 0.7; n *= 10.0; + return col; + } else if (n > 0.7) { + n -= 0.7; + n *= 10.0; col = interpolate_color(n, m_rockColor[4], col); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.6) { - n -= 0.6; n *= 10.0; + return col; + } else if (n > 0.6) { + n -= 0.6; + n *= 10.0; col = interpolate_color(n, m_rockColor[0], m_rockColor[4]); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.5) { - n -= 0.5; n *= 10.0; + return col; + } else if (n > 0.5) { + n -= 0.5; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[0]); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.4) { - n -= 0.4; n *= 10.0; + return col; + } else if (n > 0.4) { + n -= 0.4; + n *= 10.0; col = interpolate_color(n, m_darkrockColor[3], col); col = interpolate_color(flatness, color_cliffs, col); - return col; + return col; } if (n > 0.3) { - n -= 0.3; n *= 10.0; + n -= 0.3; + n *= 10.0; col = interpolate_color(n, col, m_darkrockColor[3]); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.2) { - n -= 0.2; n *= 10.0; + return col; + } else if (n > 0.2) { + n -= 0.2; + n *= 10.0; col = interpolate_color(n, m_rockColor[1], col); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.1) { - n -= 0.1; n *= 10.0; + return col; + } else if (n > 0.1) { + n -= 0.1; + n *= 10.0; col = interpolate_color(n, col, m_rockColor[1]); col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else { + return col; + } else { n *= 10.0; col = interpolate_color(n, m_darkrockColor[0], col); col = interpolate_color(flatness, color_cliffs, col); - return col; + return col; } } - diff --git a/src/terrain/TerrainColorStarBrownDwarf.cpp b/src/terrain/TerrainColorStarBrownDwarf.cpp index 5eef43982..848a0084a 100644 --- a/src/terrain/TerrainColorStarBrownDwarf.cpp +++ b/src/terrain/TerrainColorStarBrownDwarf.cpp @@ -10,11 +10,11 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "StarBrownDwarf"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 5e8, 100.0*m_fracmult); - + double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 5e8, 100.0 * m_fracmult); } template <> @@ -24,17 +24,18 @@ vector3d TerrainColorFractal::GetColor(const vector3 vector3d col; n = voronoiscam_octavenoise(GetFracDef(0), 0.6, p) * 0.5; if (n > 0.666) { - n -= 0.666; n *= 3.0; - col = interpolate_color(n, vector3d(.25, .2, .2), vector3d(.1, .0, .0) ); + n -= 0.666; + n *= 3.0; + col = interpolate_color(n, vector3d(.25, .2, .2), vector3d(.1, .0, .0)); return col; } else if (n > 0.333) { - n -= 0.333; n *= 3.0; - col = interpolate_color(n, vector3d(.2, .25, .1), vector3d(.25, .2, .2) ); + n -= 0.333; + n *= 3.0; + col = interpolate_color(n, vector3d(.2, .25, .1), vector3d(.25, .2, .2)); return col; } else { n *= 3.0; - col = interpolate_color(n, vector3d(1.5, 1.0, 1.0), vector3d(.2, .25, .1) ); + col = interpolate_color(n, vector3d(1.5, 1.0, 1.0), vector3d(.2, .25, .1)); return col; } } - diff --git a/src/terrain/TerrainColorStarG.cpp b/src/terrain/TerrainColorStarG.cpp index 6750976e8..b322be161 100644 --- a/src/terrain/TerrainColorStarG.cpp +++ b/src/terrain/TerrainColorStarG.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,13 +12,14 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "StarG"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 8e8, 1000.0*m_fracmult); - SetFracDef(1, height, 7e8, 10000.0*m_fracmult); - SetFracDef(2, height, 4e6, 100.0*m_fracmult); - SetFracDef(3, height, 2e5, 100.0*m_fracmult); + double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 8e8, 1000.0 * m_fracmult); + SetFracDef(1, height, 7e8, 10000.0 * m_fracmult); + SetFracDef(2, height, 4e6, 100.0 * m_fracmult); + SetFracDef(3, height, 2e5, 100.0 * m_fracmult); } template <> @@ -29,29 +30,29 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, dou n = octavenoise(GetFracDef(0), 0.5, p) * 0.5; n += voronoiscam_octavenoise(GetFracDef(1), 0.5, p) * 0.5; n += octavenoise(GetFracDef(0), 0.5, p) * billow_octavenoise(GetFracDef(1), 0.5, p); - n += octavenoise(GetFracDef(2), 0.5, p) * 0.5 * Clamp(GetFracDef(0).amplitude-0.2, 0.0, 1.0); - n += 15.0*billow_octavenoise(GetFracDef(0), 0.8, noise(p*3.142)*p)* - megavolcano_function(GetFracDef(1), p); + n += octavenoise(GetFracDef(2), 0.5, p) * 0.5 * Clamp(GetFracDef(0).amplitude - 0.2, 0.0, 1.0); + n += 15.0 * billow_octavenoise(GetFracDef(0), 0.8, noise(p * 3.142) * p) * + megavolcano_function(GetFracDef(1), p); n *= n * 0.15; - n = 1.0-n; + n = 1.0 - n; if (n > 0.666) { //n -= 0.666; n *= 3.0; //col = interpolate_color(n, vector3d(1.0, 1.0, 1.0), vector3d(1.0, 1.0, 1.0) ); col = vector3d(1.0, 1.0, 1.0); return col; } else if (n > 0.333) { - n -= 0.333; n *= 3.0; - col = interpolate_color(n, vector3d(.6, .6, .0), vector3d(1.0, 1.0, 1.0) ); + n -= 0.333; + n *= 3.0; + col = interpolate_color(n, vector3d(.6, .6, .0), vector3d(1.0, 1.0, 1.0)); return col; } else if (n > 0.05) { n -= 0.05; n *= 3.533; - col = interpolate_color(n, vector3d(.8, .8, .0), vector3d(.6, .6, .0) ); + col = interpolate_color(n, vector3d(.8, .8, .0), vector3d(.6, .6, .0)); return col; } else { n *= 20.0; - col = interpolate_color(n, vector3d(.02, .0, .0), vector3d(.8, .8, .0) ); + col = interpolate_color(n, vector3d(.02, .0, .0), vector3d(.8, .8, .0)); return col; } } - diff --git a/src/terrain/TerrainColorStarK.cpp b/src/terrain/TerrainColorStarK.cpp index 44a3bf5ff..4440e80c7 100644 --- a/src/terrain/TerrainColorStarK.cpp +++ b/src/terrain/TerrainColorStarK.cpp @@ -10,13 +10,14 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "StarK"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 2e9, 100.0*m_fracmult); - SetFracDef(1, height, 7e7, 100.0*m_fracmult); - SetFracDef(2, height, 1e6, 100.0*m_fracmult); - SetFracDef(3, height, 1e3, 100.0*m_fracmult); + double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 2e9, 100.0 * m_fracmult); + SetFracDef(1, height, 7e7, 100.0 * m_fracmult); + SetFracDef(2, height, 1e6, 100.0 * m_fracmult); + SetFracDef(3, height, 1e3, 100.0 * m_fracmult); } template <> @@ -31,22 +32,23 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, dou n += octavenoise(GetFracDef(3), 0.6, p) * 0.5; n *= n * 0.3; if (n > 0.666) { - n -= 0.666; n *= 3.0; - col = interpolate_color(n, vector3d(.95, .7, .25), vector3d(1.0, 1.0, 1.0) ); + n -= 0.666; + n *= 3.0; + col = interpolate_color(n, vector3d(.95, .7, .25), vector3d(1.0, 1.0, 1.0)); return col; } else if (n > 0.333) { - n -= 0.333; n *= 3.0; - col = interpolate_color(n, vector3d(.4, .25, .0), vector3d(.95, .7, .25) ); + n -= 0.333; + n *= 3.0; + col = interpolate_color(n, vector3d(.4, .25, .0), vector3d(.95, .7, .25)); return col; } else if (n > 0.05) { n -= 0.05; n *= 3.533; - col = interpolate_color(n, vector3d(.2, .1, 0), vector3d(.4, .25, .0) ); + col = interpolate_color(n, vector3d(.2, .1, 0), vector3d(.4, .25, .0)); return col; } else { n *= 20.0; - col = interpolate_color(n, vector3d(.015, .015, .015), vector3d(.2, .1, .0) ); + col = interpolate_color(n, vector3d(.015, .015, .015), vector3d(.2, .1, .0)); return col; } } - diff --git a/src/terrain/TerrainColorStarM.cpp b/src/terrain/TerrainColorStarM.cpp index 435fd69e0..1bfea924d 100644 --- a/src/terrain/TerrainColorStarM.cpp +++ b/src/terrain/TerrainColorStarM.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; @@ -11,13 +11,14 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "StarM"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 22e7, 1000.0*m_fracmult); - SetFracDef(1, height, 2e8, 10000.0*m_fracmult); - SetFracDef(2, height, 6e6, 100.0*m_fracmult); - SetFracDef(3, height, 5e5, 100.0*m_fracmult); + double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 22e7, 1000.0 * m_fracmult); + SetFracDef(1, height, 2e8, 10000.0 * m_fracmult); + SetFracDef(2, height, 6e6, 100.0 * m_fracmult); + SetFracDef(3, height, 5e5, 100.0 * m_fracmult); } using namespace TerrainFeature; @@ -32,22 +33,23 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, dou n *= n * n; n += ridged_octavenoise(GetFracDef(2), 0.6, p) * 0.5; n += ridged_octavenoise(GetFracDef(3), 0.6, p) * 0.5; - n += 15.0*billow_octavenoise(GetFracDef(0), 0.8, noise(p*3.142)*p)* - megavolcano_function(GetFracDef(1), p); + n += 15.0 * billow_octavenoise(GetFracDef(0), 0.8, noise(p * 3.142) * p) * + megavolcano_function(GetFracDef(1), p); n *= 0.15; - n = 1.0-n; + n = 1.0 - n; if (n > 0.666) { - n -= 0.666; n *= 3.0; - col = interpolate_color(n, vector3d(.65, .5, .25), vector3d(1.0, 1.0, 1.0) ); + n -= 0.666; + n *= 3.0; + col = interpolate_color(n, vector3d(.65, .5, .25), vector3d(1.0, 1.0, 1.0)); return col; } else if (n > 0.333) { - n -= 0.333; n *= 3.0; - col = interpolate_color(n, vector3d(.3, .1, .0), vector3d(.65, .5, .25) ); + n -= 0.333; + n *= 3.0; + col = interpolate_color(n, vector3d(.3, .1, .0), vector3d(.65, .5, .25)); return col; } else { n *= 3.0; - col = interpolate_color(n, vector3d(.03, .0, .0), vector3d(.3, .1, .0) ); + col = interpolate_color(n, vector3d(.03, .0, .0), vector3d(.3, .1, .0)); return col; } } - diff --git a/src/terrain/TerrainColorStarWhiteDwarf.cpp b/src/terrain/TerrainColorStarWhiteDwarf.cpp index c9468bc88..09326ae5e 100644 --- a/src/terrain/TerrainColorStarWhiteDwarf.cpp +++ b/src/terrain/TerrainColorStarWhiteDwarf.cpp @@ -10,11 +10,12 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "StarWhiteDwarf"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - double height = m_maxHeightInMeters*0.1; - SetFracDef(0, height, 3e9, 100.0*m_fracmult); //why on Earth we need a feature size of 3,000,000 KM (2.2x the sun) I don't know, but we do... :) - SetFracDef(1, height, 1e7, 100.0*m_fracmult); + double height = m_maxHeightInMeters * 0.1; + SetFracDef(0, height, 3e9, 100.0 * m_fracmult); //why on Earth we need a feature size of 3,000,000 KM (2.2x the sun) I don't know, but we do... :) + SetFracDef(1, height, 1e7, 100.0 * m_fracmult); //Original settings with correct feature size, does not seem to work anymore: //SetFracDef(0, height, 3e5, 10.0*m_fracmult); //SetFracDef(1, height, 1e5, 10.0*m_fracmult); @@ -25,16 +26,18 @@ vector3d TerrainColorFractal::GetColor(const vector3 { double n; vector3d col; - n = ridged_octavenoise(GetFracDef(0), 0.8, p*p.x); + n = ridged_octavenoise(GetFracDef(0), 0.8, p * p.x); n += ridged_octavenoise(GetFracDef(1), 0.8, p); n += voronoiscam_octavenoise(GetFracDef(0), 0.8 * octavenoise(GetFracDef(1), 0.6, p), p); - n *= n*n; + n *= n * n; if (n > 0.666) { - n -= 0.666; n *= 3.0; + n -= 0.666; + n *= 3.0; col = interpolate_color(n, vector3d(.8, .8, 1.0), vector3d(1.0, 1.0, 1.0)); return col; } else if (n > 0.333) { - n -= 0.333; n *= 3.0; + n -= 0.333; + n *= 3.0; col = interpolate_color(n, vector3d(.6, .8, .8), vector3d(.8, .8, 1.0)); return col; } else { @@ -43,4 +46,3 @@ vector3d TerrainColorFractal::GetColor(const vector3 return col; } } - diff --git a/src/terrain/TerrainColorTFGood.cpp b/src/terrain/TerrainColorTFGood.cpp index 22dcf8f8b..01ff5c0fb 100644 --- a/src/terrain/TerrainColorTFGood.cpp +++ b/src/terrain/TerrainColorTFGood.cpp @@ -10,89 +10,83 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "TFGood"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - m_surfaceEffects |= Terrain::EFFECT_WATER; + m_surfaceEffects |= Terrain::EFFECT_WATER; } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; const double flatness = pow(p.Dot(norm), 8.0); vector3d color_cliffs = m_rockColor[5]; // ice on mountains and poles - if (fabs(m_icyness*p.y) + m_icyness*n > 1) { - return interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); - } + if (fabs(m_icyness * p.y) + m_icyness * n > 1) { + return interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); + } - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); // This is for fake ocean depth by the coast. - double continents = octavenoise(GetFracDef(0), 0.7* - ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel*0.6; + double continents = octavenoise(GetFracDef(0), 0.7 * ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel * 0.6; vector3d col; //we don't want water on the poles if there are ice-caps - if (fabs(m_icyness*p.y) > 0.75) { + if (fabs(m_icyness * p.y) > 0.75) { col = interpolate_color(equatorial_desert, vector3d(0.42, 0.46, 0), vector3d(0.5, 0.3, 0)); - col = interpolate_color(flatness, col, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); return col; } // water if (n <= 0) { - // Oooh, pretty coastal regions with shading based on underwater depth. - n += continents - (GetFracDef(0).amplitude*m_sealevel*0.49); + // Oooh, pretty coastal regions with shading based on underwater depth. + n += continents - (GetFracDef(0).amplitude * m_sealevel * 0.49); n *= 10.0; - n = (n>0.3 ? 0.3-(n*n*n-0.027) : n); - col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25)); - col = interpolate_color(n, col, vector3d(0,0.8,0.6)); + n = (n > 0.3 ? 0.3 - (n * n * n - 0.027) : n); + col = interpolate_color(equatorial_desert, vector3d(0, 0, 0.15), vector3d(0, 0, 0.25)); + col = interpolate_color(n, col, vector3d(0, 0.8, 0.6)); return col; } // More sensitive height detection for application of colours if (n > 0.5) { - col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]); - col = interpolate_color(n, col, m_darkrockColor[6]); - col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.25) { - color_cliffs = m_darkrockColor[1]; - col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]); - col = interpolate_color(n, col, m_rockColor[1]); - col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.05) { - col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]); - color_cliffs = col; - col = interpolate_color(equatorial_desert, vector3d(.45,.43, .2), vector3d(.4, .43, .2)); - col = interpolate_color(n, col, vector3d(-1.66,-2.3, -1.75)); - col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.01) { - color_cliffs = vector3d(0.2,0.28,0.2); - col = interpolate_color(equatorial_desert, vector3d(.15,.5, -.1), vector3d(.2, .6, -.1)); - col = interpolate_color(n, col, vector3d(5,-5, 5)); - col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else if (n > 0.005) { - color_cliffs = vector3d(0.25,0.28,0.2); - col = interpolate_color(equatorial_desert, vector3d(.45,.6,0), vector3d(.5, .6, .0)); - col = interpolate_color(n, col, vector3d(-10,-10,0)); - col = interpolate_color(flatness, color_cliffs, col); - return col; - } - else { - color_cliffs = vector3d(0.3,0.1,0.0); - col = interpolate_color(equatorial_desert, vector3d(.35,.3,0), vector3d(.4, .3, .0)); - col = interpolate_color(n, col, vector3d(0,20,0)); - col = interpolate_color(flatness, color_cliffs, col); - return col; + col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]); + col = interpolate_color(n, col, m_darkrockColor[6]); + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.25) { + color_cliffs = m_darkrockColor[1]; + col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]); + col = interpolate_color(n, col, m_rockColor[1]); + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.05) { + col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]); + color_cliffs = col; + col = interpolate_color(equatorial_desert, vector3d(.45, .43, .2), vector3d(.4, .43, .2)); + col = interpolate_color(n, col, vector3d(-1.66, -2.3, -1.75)); + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.01) { + color_cliffs = vector3d(0.2, 0.28, 0.2); + col = interpolate_color(equatorial_desert, vector3d(.15, .5, -.1), vector3d(.2, .6, -.1)); + col = interpolate_color(n, col, vector3d(5, -5, 5)); + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else if (n > 0.005) { + color_cliffs = vector3d(0.25, 0.28, 0.2); + col = interpolate_color(equatorial_desert, vector3d(.45, .6, 0), vector3d(.5, .6, .0)); + col = interpolate_color(n, col, vector3d(-10, -10, 0)); + col = interpolate_color(flatness, color_cliffs, col); + return col; + } else { + color_cliffs = vector3d(0.3, 0.1, 0.0); + col = interpolate_color(equatorial_desert, vector3d(.35, .3, 0), vector3d(.4, .3, .0)); + col = interpolate_color(n, col, vector3d(0, 20, 0)); + col = interpolate_color(flatness, color_cliffs, col); + return col; } } - diff --git a/src/terrain/TerrainColorTFPoor.cpp b/src/terrain/TerrainColorTFPoor.cpp index 8e9e9ef98..317379f31 100644 --- a/src/terrain/TerrainColorTFPoor.cpp +++ b/src/terrain/TerrainColorTFPoor.cpp @@ -10,51 +10,54 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "TFPoor"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { - m_surfaceEffects |= Terrain::EFFECT_WATER; + m_surfaceEffects |= Terrain::EFFECT_WATER; } template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; double flatness = pow(p.Dot(norm), 8.0); double continents = 0; - double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(2.0-m_icyness)*(1.0-p.y*p.y); + double equatorial_desert = (2.0 - m_icyness) * (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (2.0 - m_icyness) * (1.0 - p.y * p.y); vector3d color_cliffs = m_darkrockColor[5]; vector3d col, tex1, tex2; // ice on mountains and poles - if (fabs(m_icyness*p.y) + m_icyness*n > 1) { + if (fabs(m_icyness * p.y) + m_icyness * n > 1) { if (textures) { - col = interpolate_color(terrain_colournoise_rock2, color_cliffs, vector3d(.9,.9,.9)); - col = interpolate_color(flatness, col, vector3d(1,1,1)); - } else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1)); + col = interpolate_color(terrain_colournoise_rock2, color_cliffs, vector3d(.9, .9, .9)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); + } else + col = interpolate_color(flatness, color_cliffs, vector3d(1, 1, 1)); return col; } //we don't want water on the poles if there are ice-caps - if (fabs(m_icyness*p.y) > 0.67) { + if (fabs(m_icyness * p.y) > 0.67) { col = interpolate_color(equatorial_desert, m_sandColor[2], m_darksandColor[5]); - col = interpolate_color(flatness, col, vector3d(1,1,1)); + col = interpolate_color(flatness, col, vector3d(1, 1, 1)); return col; } // This is for fake ocean depth by the coast. - continents = ridged_octavenoise(GetFracDef(3-m_fracnum), 0.55, p) * (1.0-m_sealevel) - ((m_sealevel*0.1)-0.1); + continents = ridged_octavenoise(GetFracDef(3 - m_fracnum), 0.55, p) * (1.0 - m_sealevel) - ((m_sealevel * 0.1) - 0.1); // water if (n <= 0) { // Oooh, pretty coastal regions with shading based on underwater depth. - n += continents;// - (GetFracDef(3).amplitude*m_sealevel*0.49); - n *= n*10.0; + n += continents; // - (GetFracDef(3).amplitude*m_sealevel*0.49); + n *= n * 10.0; //n = (n>0.3 ? 0.3-(n*n*n-0.027) : n); - col = interpolate_color(n, vector3d(0,0.0,0.1), vector3d(0,0.5,0.5)); + col = interpolate_color(n, vector3d(0, 0.0, 0.1), vector3d(0, 0.5, 0.5)); return col; } // More sensitive height detection for application of colours if (n > 0.5) { - n -= 0.5; n *= 2.0; + n -= 0.5; + n *= 2.0; //color_cliffs = m_rockColor[1]; col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[6]); col = interpolate_color(n, col, m_darkrockColor[6]); @@ -62,11 +65,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.25) { - n -= 0.25; n *= 4.0; + } else if (n > 0.25) { + n -= 0.25; + n *= 4.0; color_cliffs = m_rockColor[3]; col = interpolate_color(equatorial_desert, m_darkrockColor[4], m_darksandColor[6]); col = interpolate_color(n, col, m_rockColor[2]); @@ -74,11 +78,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.05) { - n -= 0.05; n *= 5.0; + } else if (n > 0.05) { + n -= 0.05; + n *= 5.0; col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]); color_cliffs = col; col = interpolate_color(equatorial_desert, m_darksandColor[2], m_sandColor[2]); @@ -87,11 +92,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_mud, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.01) { - n -= 0.01; n *= 25.0; + } else if (n > 0.01) { + n -= 0.01; + n *= 25.0; color_cliffs = m_darkplantColor[0]; col = interpolate_color(equatorial_desert, m_sandColor[1], m_sandColor[0]); col = interpolate_color(n, col, m_darksandColor[2]); @@ -99,11 +105,12 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_grass, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass2, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else if (n > 0.005) { - n -= 0.005; n *= 200.0; + } else if (n > 0.005) { + n -= 0.005; + n *= 200.0; color_cliffs = m_plantColor[0]; col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]); col = interpolate_color(n, col, m_plantColor[0]); @@ -111,10 +118,10 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_sand2, col, color_cliffs); tex2 = interpolate_color(terrain_colournoise_grass, col, color_cliffs); col = interpolate_color(flatness, tex1, tex2); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; - } - else { + } else { n *= 200.0; color_cliffs = m_darksandColor[0]; col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]); @@ -123,8 +130,8 @@ vector3d TerrainColorFractal::GetColor(const vector3d &p, do tex1 = interpolate_color(terrain_colournoise_sand, col, color_cliffs); //tex2 = interpolate_color(terrain_colournoise_sand2, col, color_cliffs); col = interpolate_color(flatness, tex1, col); - } else col = interpolate_color(flatness, color_cliffs, col); + } else + col = interpolate_color(flatness, color_cliffs, col); return col; } } - diff --git a/src/terrain/TerrainColorVolcanic.cpp b/src/terrain/TerrainColorVolcanic.cpp index 3b92cf0f5..8601f2703 100644 --- a/src/terrain/TerrainColorVolcanic.cpp +++ b/src/terrain/TerrainColorVolcanic.cpp @@ -10,7 +10,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Volcanic"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { // 50 percent chance of there being exposed lava if (m_rand.Int32(100) > 50) @@ -20,31 +21,30 @@ TerrainColorFractal::TerrainColorFractal(const SystemBody template <> vector3d TerrainColorFractal::GetColor(const vector3d &p, double height, const vector3d &norm) const { - double n = m_invMaxHeight*height; + double n = m_invMaxHeight * height; const double flatness = pow(p.Dot(norm), 6.0); const vector3d color_cliffs = m_rockColor[2]; - double equatorial_desert = (-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) * - 1.0*(1.0-p.y*p.y); + double equatorial_desert = (-1.0 + 2.0 * octavenoise(12, 0.5, 2.0, (n * 2.0) * p)) * + 1.0 * (1.0 - p.y * p.y); vector3d col; - if (n > 0.4){ - col = interpolate_color(equatorial_desert, vector3d(.3,.2,0), vector3d(.3, .1, .0)); + if (n > 0.4) { + col = interpolate_color(equatorial_desert, vector3d(.3, .2, 0), vector3d(.3, .1, .0)); col = interpolate_color(n, col, vector3d(.1, .0, .0)); col = interpolate_color(flatness, color_cliffs, col); - } else if (n > 0.2){ - col = interpolate_color(equatorial_desert, vector3d(1.2,1,0), vector3d(.9, .3, .0)); + } else if (n > 0.2) { + col = interpolate_color(equatorial_desert, vector3d(1.2, 1, 0), vector3d(.9, .3, .0)); col = interpolate_color(n, col, vector3d(-1.1, -1, .0)); col = interpolate_color(flatness, color_cliffs, col); - } else if (n > 0.1){ - col = interpolate_color(equatorial_desert, vector3d(.2,.1,0), vector3d(.1, .05, .0)); + } else if (n > 0.1) { + col = interpolate_color(equatorial_desert, vector3d(.2, .1, 0), vector3d(.1, .05, .0)); col = interpolate_color(n, col, vector3d(2.5, 2, .0)); col = interpolate_color(flatness, color_cliffs, col); } else { - col = interpolate_color(equatorial_desert, vector3d(.75,.6,0), vector3d(.75, .2, .0)); + col = interpolate_color(equatorial_desert, vector3d(.75, .6, 0), vector3d(.75, .2, .0)); col = interpolate_color(n, col, vector3d(-2, -2.2, .0)); col = interpolate_color(flatness, color_cliffs, col); } return col; } - diff --git a/src/terrain/TerrainColorWhite.cpp b/src/terrain/TerrainColorWhite.cpp index 83d76f56b..346c39998 100644 --- a/src/terrain/TerrainColorWhite.cpp +++ b/src/terrain/TerrainColorWhite.cpp @@ -9,7 +9,8 @@ template <> const char *TerrainColorFractal::GetColorFractalName() const { return "Solid"; } template <> -TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : Terrain(body) +TerrainColorFractal::TerrainColorFractal(const SystemBody *body) : + Terrain(body) { } diff --git a/src/terrain/TerrainFeature.cpp b/src/terrain/TerrainFeature.cpp index ed1351743..83c0baf60 100644 --- a/src/terrain/TerrainFeature.cpp +++ b/src/terrain/TerrainFeature.cpp @@ -8,286 +8,286 @@ using namespace TerrainNoise; namespace TerrainFeature { -// Creates small canyons. -double canyon_ridged_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = ridged_octavenoise(def.octaves, 0.54, 2.0, def.frequency*p); - const double outer = 0.71; - const double inner = 0.715; - const double inner2 = 0.715; - const double outer2 = 0.72; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + // Creates small canyons. + double canyon_ridged_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = ridged_octavenoise(def.octaves, 0.54, 2.0, def.frequency * p); + const double outer = 0.71; + const double inner = 0.715; + const double inner2 = 0.715; + const double outer2 = 0.72; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -// Larger canyon. -double canyon2_ridged_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; //octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); - n = ridged_octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + // Larger canyon. + double canyon2_ridged_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; //octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); + n = ridged_octavenoise(def.octaves, 0.56, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -// Largest and best looking canyon, combine them together for best results. -double canyon3_ridged_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; //octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); - n = ridged_octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1.0; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0.0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + // Largest and best looking canyon, combine them together for best results. + double canyon3_ridged_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; //octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); + n = ridged_octavenoise(def.octaves, 0.585, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1.0; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0.0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon_normal_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.54, 2.0, def.frequency*p); - const double outer = 0.71; - const double inner = 0.715; - const double inner2 = 0.715; - const double outer2 = 0.72; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon_normal_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.54, 2.0, def.frequency * p); + const double outer = 0.71; + const double inner = 0.715; + const double inner2 = 0.715; + const double outer2 = 0.72; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon2_normal_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon2_normal_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.56, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon3_normal_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1.0; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0.0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon3_normal_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.585, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1.0; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0.0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon_voronoi_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.54, 2.0, def.frequency*p); - const double outer = 0.71; - const double inner = 0.715; - const double inner2 = 0.715; - const double outer2 = 0.72; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon_voronoi_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.54, 2.0, def.frequency * p); + const double outer = 0.71; + const double inner = 0.715; + const double inner2 = 0.715; + const double outer2 = 0.72; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon2_voronoi_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon2_voronoi_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.56, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon3_voronoi_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1.0; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0.0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon3_voronoi_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.585, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1.0; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0.0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon_billow_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.54, 2.0, def.frequency*p); - const double outer = 0.71; - const double inner = 0.715; - const double inner2 = 0.715; - const double outer2 = 0.72; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon_billow_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.54, 2.0, def.frequency * p); + const double outer = 0.71; + const double inner = 0.715; + const double inner2 = 0.715; + const double outer2 = 0.72; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon2_billow_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.56, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon2_billow_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.56, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -double canyon3_billow_function(const fracdef_t &def, const vector3d &p) -{ - double h; - double n = 0; - n = octavenoise(def.octaves, 0.585, 2.0, def.frequency*p); - const double outer = 0.7; - const double inner = 0.71; - const double inner2 = 0.72; - const double outer2 = 0.73; - if (n > outer2) { - h = 1.0; - } else if (n > inner2) { - h = 0.0+1.0*(n-inner2)*(1.0/(outer2-inner2)); - } else if (n > inner) { - h = 0.0; - } else if (n > outer) { - h = 1.0-1.0*(n-outer)*(1.0/(inner-outer)); - } else { - h = 1.0; + double canyon3_billow_function(const fracdef_t &def, const vector3d &p) + { + double h; + double n = 0; + n = octavenoise(def.octaves, 0.585, 2.0, def.frequency * p); + const double outer = 0.7; + const double inner = 0.71; + const double inner2 = 0.72; + const double outer2 = 0.73; + if (n > outer2) { + h = 1.0; + } else if (n > inner2) { + h = 0.0 + 1.0 * (n - inner2) * (1.0 / (outer2 - inner2)); + } else if (n > inner) { + h = 0.0; + } else if (n > outer) { + h = 1.0 - 1.0 * (n - outer) * (1.0 / (inner - outer)); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} -/*double rock_function(const fracdef_t &def, const vector3d &p) + /*double rock_function(const fracdef_t &def, const vector3d &p) { double h; double n = octavenoise(def.octaves, 0.788, 2.0, def.frequency*p); @@ -309,175 +309,175 @@ double canyon3_billow_function(const fracdef_t &def, const vector3d &p) return h * def.amplitude; }*/ -void crater_function_1pass(const vector3d &p, double &out, const double height) -{ - double n = fabs(noise(p)); - const double ejecta_outer = 0.6; - const double outer = 0.9; - const double inner = 0.94; - const double midrim = 0.93; - if (n > inner) { - //out = 0; - } else if (n > midrim) { - double hrim = inner - midrim; - double descent = (hrim-(n-midrim))/hrim; - out += height * descent * descent; - } else if (n > outer) { - double hrim = midrim - outer; - double ascent = (n-outer)/hrim; - out += height * ascent * ascent; - } else if (n > ejecta_outer) { - // blow down walls of other craters too near this one, - // so we don't have sharp transition - //out *= (outer-n)/-(ejecta_outer-outer); + void crater_function_1pass(const vector3d &p, double &out, const double height) + { + double n = fabs(noise(p)); + const double ejecta_outer = 0.6; + const double outer = 0.9; + const double inner = 0.94; + const double midrim = 0.93; + if (n > inner) { + //out = 0; + } else if (n > midrim) { + double hrim = inner - midrim; + double descent = (hrim - (n - midrim)) / hrim; + out += height * descent * descent; + } else if (n > outer) { + double hrim = midrim - outer; + double ascent = (n - outer) / hrim; + out += height * ascent * ascent; + } else if (n > ejecta_outer) { + // blow down walls of other craters too near this one, + // so we don't have sharp transition + //out *= (outer-n)/-(ejecta_outer-outer); + } } -} -// makes large and small craters across the entire planet. -double crater_function(const fracdef_t &def, const vector3d &p) -{ - double crater = 0.0; - double sz = def.frequency; - double max_h = def.amplitude; - for (int i=0; i midrim) { - out -= height; - } else if (n > outer) { - hrim = midrim - outer; - descent = (n-outer)/hrim; - out -= height * descent * descent; - } else if (n > ejecta_outer) { - // blow down walls of other craters too near this one, - // so we don't have sharp transition - //out *= (outer-n)/-(ejecta_outer-outer); + void impact_crater_function_1pass(const vector3d &p, double &out, const double height) + { + double n = fabs(noise(p)); + const double ejecta_outer = 0.6; + const double outer = 0.9; + const double midrim = 0.93; + double hrim; + double descent; + if (n > midrim) { + out -= height; + } else if (n > outer) { + hrim = midrim - outer; + descent = (n - outer) / hrim; + out -= height * descent * descent; + } else if (n > ejecta_outer) { + // blow down walls of other craters too near this one, + // so we don't have sharp transition + //out *= (outer-n)/-(ejecta_outer-outer); + } } -} -// makes large and small craters across the entire planet. -double impact_crater_function(const fracdef_t &def, const vector3d &p) -{ - double crater = 0.0; - double sz = def.frequency; - double max_h = def.amplitude; - for (int i=0; i inner) { - //out = 0; - } else if (n > midrim) { - double hrim = inner - midrim; - double descent = (hrim-(n-midrim))/hrim; - out += height * descent; - } else if (n > outer) { - double hrim = midrim - outer; - double ascent = (n-outer)/hrim; - out += height * ascent * ascent; - } else if (n > ejecta_outer) { - // blow down walls of other craters too near this one, - // so we don't have sharp transition - out *= (outer-n)/-(ejecta_outer-outer); + void volcano_function_1pass(const vector3d &p, double &out, const double height) + { + double n = fabs(noise(p)); + const double ejecta_outer = 0.6; + const double outer = 0.9; + const double inner = 0.975; + const double midrim = 0.971; + if (n > inner) { + //out = 0; + } else if (n > midrim) { + double hrim = inner - midrim; + double descent = (hrim - (n - midrim)) / hrim; + out += height * descent; + } else if (n > outer) { + double hrim = midrim - outer; + double ascent = (n - outer) / hrim; + out += height * ascent * ascent; + } else if (n > ejecta_outer) { + // blow down walls of other craters too near this one, + // so we don't have sharp transition + out *= (outer - n) / -(ejecta_outer - outer); + } } -} -double volcano_function(const fracdef_t &def, const vector3d &p) -{ - double crater = 0.0; - double sz = def.frequency; - double max_h = def.amplitude; - for (int i=0; i inner) { - //out = 0; - } else if (n > midrim) { - double hrim = inner - midrim; - double descent = (hrim-(n-midrim))/hrim; - out += height * descent; - } else if (n > outer) { - double hrim = midrim - outer; - double ascent = (n-outer)/hrim; - out += height * ascent * ascent; - } else if (n > ejecta_outer) { - // blow down walls of other craters too near this one, - // so we don't have sharp transition - out *= (outer-n)/-(ejecta_outer-outer); + void megavolcano_function_1pass(const vector3d &p, double &out, const double height) + { + double n = fabs(noise(p)); + const double ejecta_outer = 0.6; + const double outer = 0.76; //Radius + const double inner = 0.98; + const double midrim = 0.964; + if (n > inner) { + //out = 0; + } else if (n > midrim) { + double hrim = inner - midrim; + double descent = (hrim - (n - midrim)) / hrim; + out += height * descent; + } else if (n > outer) { + double hrim = midrim - outer; + double ascent = (n - outer) / hrim; + out += height * ascent * ascent; + } else if (n > ejecta_outer) { + // blow down walls of other craters too near this one, + // so we don't have sharp transition + out *= (outer - n) / -(ejecta_outer - outer); + } } -} -double megavolcano_function(const fracdef_t &def, const vector3d &p) -{ - double crater = 0.0; - double sz = def.frequency; - double max_h = def.amplitude; - for (int i=0; i= 0 && style < 2); - double h; - double n = octavenoise(def.octaves, 0.585, 2.0, def.frequency*p*0.5); - const double outer[] = {0.67, 0.01}; - const double inner[] = {0.715, 0.49}; - const double inner2[] = {0.715, 0.51}; - const double outer2[] = {0.76, 0.99}; - if (n > outer2[style]) { - h = 1; - } else if (n > inner2[style]) { - h = 0.0+1.0*(n-inner2[style])*(1.0/(outer2[style]-inner2[style])); - } else if (n > inner[style]) { - h = 0; - } else if (n > outer[style]) { - h = 1.0-1.0*(n-outer[style])*(1.0/(inner[style]-outer[style])); - } else { - h = 1.0; + double river_function(const fracdef_t &def, const vector3d &p, int style) + { + assert(style >= 0 && style < 2); + double h; + double n = octavenoise(def.octaves, 0.585, 2.0, def.frequency * p * 0.5); + const double outer[] = { 0.67, 0.01 }; + const double inner[] = { 0.715, 0.49 }; + const double inner2[] = { 0.715, 0.51 }; + const double outer2[] = { 0.76, 0.99 }; + if (n > outer2[style]) { + h = 1; + } else if (n > inner2[style]) { + h = 0.0 + 1.0 * (n - inner2[style]) * (1.0 / (outer2[style] - inner2[style])); + } else if (n > inner[style]) { + h = 0; + } else if (n > outer[style]) { + h = 1.0 - 1.0 * (n - outer[style]) * (1.0 / (inner[style] - outer[style])); + } else { + h = 1.0; + } + return h * def.amplitude; } - return h * def.amplitude; -} // Original canyon function, But really it generates cliffs. #if 0 @@ -498,4 +498,4 @@ double cliff_function(const fracdef_t &def, const vector3d &p) } #endif -} +} // namespace TerrainFeature diff --git a/src/terrain/TerrainFeature.h b/src/terrain/TerrainFeature.h index 2a2ec6d37..57adcc90b 100644 --- a/src/terrain/TerrainFeature.h +++ b/src/terrain/TerrainFeature.h @@ -26,6 +26,6 @@ namespace TerrainFeature { double megavolcano_function(const fracdef_t &def, const vector3d &p); double river_function(const fracdef_t &def, const vector3d &p, int style = 0); -} +} // namespace TerrainFeature #endif diff --git a/src/terrain/TerrainHeightAsteroid.cpp b/src/terrain/TerrainHeightAsteroid.cpp index 3e0941381..ecbb363cf 100644 --- a/src/terrain/TerrainHeightAsteroid.cpp +++ b/src/terrain/TerrainHeightAsteroid.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,11 +14,12 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Asteroid"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); - const double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); + SetFracDef(0, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); + const double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); } template <> @@ -26,5 +27,5 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) { const double n = octavenoise(GetFracDef(0), 0.4, p) * dunes_octavenoise(GetFracDef(1), 0.5, p); - return (n > 0.0 ? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightAsteroid2.cpp b/src/terrain/TerrainHeightAsteroid2.cpp index a75c832df..907e6c420 100644 --- a/src/terrain/TerrainHeightAsteroid2.cpp +++ b/src/terrain/TerrainHeightAsteroid2.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,14 +14,15 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Asteroid2"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); - const double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(3, m_maxHeightInMeters*0.07, 1e6, 100.0*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.05, 8e5, 100.0*m_fracmult); + SetFracDef(0, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); + const double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(3, m_maxHeightInMeters * 0.07, 1e6, 100.0 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.05, 8e5, 100.0 * m_fracmult); } template <> @@ -30,5 +31,5 @@ double TerrainHeightFractal::GetHeight(const vector3d &p const double n = voronoiscam_octavenoise(6, 0.2 * octavenoise(GetFracDef(0), 0.3, p), 15.0 * octavenoise(GetFracDef(1), 0.5, p), p) * 0.75 * ridged_octavenoise(16.0 * octavenoise(GetFracDef(2), 0.275, p), 0.4 * ridged_octavenoise(GetFracDef(3), 0.4, p), 4.0 * octavenoise(GetFracDef(4), 0.35, p), p); - return (n > 0.0 ? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightAsteroid3.cpp b/src/terrain/TerrainHeightAsteroid3.cpp index 53a18f1de..95e05c0e5 100644 --- a/src/terrain/TerrainHeightAsteroid3.cpp +++ b/src/terrain/TerrainHeightAsteroid3.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,11 +14,12 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Asteroid3"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); - const double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); + SetFracDef(0, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); + const double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); } template <> @@ -26,5 +27,5 @@ double TerrainHeightFractal::GetHeight(const vector3d &p { const double n = octavenoise(GetFracDef(0), 0.5, p) * ridged_octavenoise(GetFracDef(1), 0.5, p); - return (n > 0.0 ? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightAsteroid4.cpp b/src/terrain/TerrainHeightAsteroid4.cpp index d9ebbc646..b2eec1d17 100644 --- a/src/terrain/TerrainHeightAsteroid4.cpp +++ b/src/terrain/TerrainHeightAsteroid4.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,21 +14,22 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Asteroid4"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); - const double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(3, m_maxHeightInMeters*0.07, 1e6, 100.0*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.05, 8e5, 100.0*m_fracmult); + SetFracDef(0, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); + const double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(3, m_maxHeightInMeters * 0.07, 1e6, 100.0 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.05, 8e5, 100.0 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - const double n = octavenoise(6, 0.2*octavenoise(GetFracDef(0), 0.3, p), 2.8*ridged_octavenoise(GetFracDef(1), 0.5, p), p) * - 0.75*ridged_octavenoise(16*octavenoise(GetFracDef(2), 0.275, p), 0.3*octavenoise(GetFracDef(3), 0.4, p), 2.8*ridged_octavenoise(GetFracDef(4), 0.35, p), p); + const double n = octavenoise(6, 0.2 * octavenoise(GetFracDef(0), 0.3, p), 2.8 * ridged_octavenoise(GetFracDef(1), 0.5, p), p) * + 0.75 * ridged_octavenoise(16 * octavenoise(GetFracDef(2), 0.275, p), 0.3 * octavenoise(GetFracDef(3), 0.4, p), 2.8 * ridged_octavenoise(GetFracDef(4), 0.35, p), p); - return (n > 0.0 ? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightBarrenRock.cpp b/src/terrain/TerrainHeightBarrenRock.cpp index f62f8f2c2..08c64756d 100644 --- a/src/terrain/TerrainHeightBarrenRock.cpp +++ b/src/terrain/TerrainHeightBarrenRock.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,7 +14,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Barren Rock"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //SetFracDef(0, m_maxHeightInMeters, m_planetRadius); // craters @@ -26,8 +27,8 @@ double TerrainHeightFractal::GetHeight(const vector3d & { /*return std::max(0.0, m_maxHeight * (octavenoise(GetFracDef(0), 0.5, p) + GetFracDef(1).amplitude * crater_function(GetFracDef(1), p)));*/ - //fuck the fracdefs, direct control is better: - double n = ridged_octavenoise(16, 0.5*octavenoise(8, 0.4, 2.5, p),Clamp(5.0*octavenoise(8, 0.257, 4.0, p), 1.0, 5.0), p); + //fuck the fracdefs, direct control is better: + double n = ridged_octavenoise(16, 0.5 * octavenoise(8, 0.4, 2.5, p), Clamp(5.0 * octavenoise(8, 0.257, 4.0, p), 1.0, 5.0), p); - return (n > 0.0 ? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightBarrenRock2.cpp b/src/terrain/TerrainHeightBarrenRock2.cpp index afc0aa917..0bce2716f 100644 --- a/src/terrain/TerrainHeightBarrenRock2.cpp +++ b/src/terrain/TerrainHeightBarrenRock2.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -15,7 +15,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Barren Rock 2"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { } @@ -23,7 +24,7 @@ template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double n = billow_octavenoise(16, 0.3*octavenoise(8, 0.4, 2.5, p),Clamp(5.0*ridged_octavenoise(8, 0.377, 4.0, p), 1.0, 5.0), p); + double n = billow_octavenoise(16, 0.3 * octavenoise(8, 0.4, 2.5, p), Clamp(5.0 * ridged_octavenoise(8, 0.377, 4.0, p), 1.0, 5.0), p); - return (n > 0.0? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightBarrenRock3.cpp b/src/terrain/TerrainHeightBarrenRock3.cpp index eafdc432a..8b25ba111 100644 --- a/src/terrain/TerrainHeightBarrenRock3.cpp +++ b/src/terrain/TerrainHeightBarrenRock3.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,7 +14,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Barren Rock 3"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { } @@ -22,7 +23,7 @@ template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - float n = 0.07*voronoiscam_octavenoise(12, Clamp(fabs(0.165 - (0.38*river_octavenoise(12, 0.4, 2.5, p))), 0.15, 0.5),Clamp(8.0*billow_octavenoise(12, 0.37, 4.0, p), 0.5, 9.0), p); + float n = 0.07 * voronoiscam_octavenoise(12, Clamp(fabs(0.165 - (0.38 * river_octavenoise(12, 0.4, 2.5, p))), 0.15, 0.5), Clamp(8.0 * billow_octavenoise(12, 0.37, 4.0, p), 0.5, 9.0), p); - return (n > 0.0? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } diff --git a/src/terrain/TerrainHeightEllipsoid.cpp b/src/terrain/TerrainHeightEllipsoid.cpp index 8546b19b8..ccc31f554 100644 --- a/src/terrain/TerrainHeightEllipsoid.cpp +++ b/src/terrain/TerrainHeightEllipsoid.cpp @@ -7,7 +7,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Ellipsoid"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { const double rad = m_minBody.m_radius; m_maxHeight = m_minBody.m_aspectRatio - 1.0; @@ -55,12 +56,11 @@ double TerrainHeightFractal::GetHeight(const vector3d &p { const double ar = m_minBody.m_aspectRatio; // x_^2 = (p.z^2+p.x^2) (eqn. 5) - const double x_squared = (p.x*p.x+p.z*p.z); + const double x_squared = (p.x * p.x + p.z * p.z); // y_ = p.y - const double y_squared = p.y*p.y; - const double distFromCenter_R = ar/sqrt(x_squared+ar*ar*y_squared); // (eqn. 9) + const double y_squared = p.y * p.y; + const double distFromCenter_R = ar / sqrt(x_squared + ar * ar * y_squared); // (eqn. 9) // GetHeight must return the difference in the distance from center between a point in a sphere of // Polar radius (in coords scaled to a unit sphere) and the point on the ellipsoid surface. return std::max(distFromCenter_R - 1.0, 0.0); } - diff --git a/src/terrain/TerrainHeightFlat.cpp b/src/terrain/TerrainHeightFlat.cpp index f44039e76..43beb2153 100644 --- a/src/terrain/TerrainHeightFlat.cpp +++ b/src/terrain/TerrainHeightFlat.cpp @@ -7,7 +7,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Flat"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { } diff --git a/src/terrain/TerrainHeightHillsCraters.cpp b/src/terrain/TerrainHeightHillsCraters.cpp index 0167b59e2..735bb2ddb 100644 --- a/src/terrain/TerrainHeightHillsCraters.cpp +++ b/src/terrain/TerrainHeightHillsCraters.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,14 +12,15 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsCraters"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(3, m_maxHeightInMeters*0.07, 1e6, 100.0*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.05, 8e5, 100.0*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(3, m_maxHeightInMeters * 0.07, 1e6, 100.0 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.05, 8e5, 100.0 * m_fracmult); } template <> @@ -30,10 +31,12 @@ double TerrainHeightFractal::GetHeight(const vector3d // == TERRAIN_HILLS_NORMAL except river_octavenoise double n = 0.3 * continents; double distrib = river_octavenoise(GetFracDef(2), 0.5, p); - double m = GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5*distrib, p); + double m = GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5 * distrib, p); // cliffs at shore - if (continents < 0.001) n += m * continents * 1000.0f; - else n += m; + if (continents < 0.001) + n += m * continents * 1000.0f; + else + n += m; n += crater_function(GetFracDef(3), p); n += crater_function(GetFracDef(4), p); n *= m_maxHeight; diff --git a/src/terrain/TerrainHeightHillsCraters2.cpp b/src/terrain/TerrainHeightHillsCraters2.cpp index 97c2c30fc..740d48c09 100644 --- a/src/terrain/TerrainHeightHillsCraters2.cpp +++ b/src/terrain/TerrainHeightHillsCraters2.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,18 +12,19 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsCraters2"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.6; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(3, m_maxHeightInMeters*0.07, 11e5, 1000.0*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.05, 98e4, 800.0*m_fracmult); - SetFracDef(5, m_maxHeightInMeters*0.05, 1e6, 400.0*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.04, 99e4, 200.0*m_fracmult); - SetFracDef(7, m_maxHeightInMeters*0.05, 12e5, 100.0*m_fracmult); - SetFracDef(8, m_maxHeightInMeters*0.04, 9e5, 100.0*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.6; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(3, m_maxHeightInMeters * 0.07, 11e5, 1000.0 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.05, 98e4, 800.0 * m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.05, 1e6, 400.0 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.04, 99e4, 200.0 * m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.05, 12e5, 100.0 * m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 0.04, 9e5, 100.0 * m_fracmult); } template <> @@ -34,10 +35,12 @@ double TerrainHeightFractal::GetHeight(const vector3 // == TERRAIN_HILLS_NORMAL except river_octavenoise double n = 0.3 * continents; double distrib = river_octavenoise(GetFracDef(2), 0.5, p); - double m = GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5*distrib, p); + double m = GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5 * distrib, p); // cliffs at shore - if (continents < 0.001) n += m * continents * 1000.0f; - else n += m; + if (continents < 0.001) + n += m * continents * 1000.0f; + else + n += m; n += crater_function(GetFracDef(3), p); n += crater_function(GetFracDef(4), p); n += crater_function(GetFracDef(5), p); diff --git a/src/terrain/TerrainHeightHillsDunes.cpp b/src/terrain/TerrainHeightHillsDunes.cpp index e7b37a496..e56e838c5 100644 --- a/src/terrain/TerrainHeightHillsDunes.cpp +++ b/src/terrain/TerrainHeightHillsDunes.cpp @@ -10,46 +10,46 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsDunes"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //textures - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(50, 100), 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(300, 500), 10*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(50, 100), 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(300, 500), 10 * m_fracmult); //small fractal/high detail - SetFracDef(2, m_maxHeightInMeters*0.00000000001, 50, 50*m_fracmult); + SetFracDef(2, m_maxHeightInMeters * 0.00000000001, 50, 50 * m_fracmult); //continental: - SetFracDef(3, m_maxHeightInMeters*0.00001, 1e7, 1000*m_fracmult); + SetFracDef(3, m_maxHeightInMeters * 0.00001, 1e7, 1000 * m_fracmult); //large fractal: - SetFracDef(4, m_maxHeightInMeters*0.00001, 1e5, 200*m_fracmult); - SetFracDef(5, m_maxHeightInMeters*0.000001, 5e4, 100*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.0000001, 1e4, 50*m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.00001, 1e5, 200 * m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.000001, 5e4, 100 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.0000001, 1e4, 50 * m_fracmult); //medium fractal: - SetFracDef(7, m_maxHeightInMeters*0.0000000002, 1e3, 20*m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.0000000002, 1e3, 20 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = ridged_octavenoise(GetFracDef(3), 0.65, p) * (1.0-m_sealevel) - (m_sealevel*0.1); + double continents = ridged_octavenoise(GetFracDef(3), 0.65, p) * (1.0 - m_sealevel) - (m_sealevel * 0.1); if (continents < 0) return 0; double n = continents; double distrib = dunes_octavenoise(GetFracDef(4), 0.4, p); distrib *= distrib * distrib; - double m = octavenoise(GetFracDef(7), 0.5, p) * dunes_octavenoise(GetFracDef(7), 0.5, p) - * Clamp(0.2-distrib, 0.0, 0.05); - m += octavenoise(GetFracDef(2), 0.5, p) * dunes_octavenoise(GetFracDef(2), 0.5 - *octavenoise(GetFracDef(6), 0.5*distrib, p), p) * Clamp(1.0-distrib, 0.0, 0.0005); - double mountains = ridged_octavenoise(GetFracDef(5), 0.5*distrib, p) - * octavenoise(GetFracDef(4), 0.5*distrib, p) * octavenoise(GetFracDef(6), 0.5, p) * distrib; + double m = octavenoise(GetFracDef(7), 0.5, p) * dunes_octavenoise(GetFracDef(7), 0.5, p) * Clamp(0.2 - distrib, 0.0, 0.05); + m += octavenoise(GetFracDef(2), 0.5, p) * dunes_octavenoise(GetFracDef(2), 0.5 * octavenoise(GetFracDef(6), 0.5 * distrib, p), p) * Clamp(1.0 - distrib, 0.0, 0.0005); + double mountains = ridged_octavenoise(GetFracDef(5), 0.5 * distrib, p) * octavenoise(GetFracDef(4), 0.5 * distrib, p) * octavenoise(GetFracDef(6), 0.5, p) * distrib; mountains *= mountains; m += mountains; //detail for mountains, stops them looking smooth. //m += mountains*mountains*0.02*octavenoise(GetFracDef(2), 0.6*mountains*mountains*distrib, p); //m *= m*m*m*10.0; // smooth cliffs at shore - if (continents < 0.01) n += m * continents * 100.0f; - else n += m; + if (continents < 0.01) + n += m * continents * 100.0f; + else + n += m; //n += continents*Clamp(0.5-m, 0.0, 0.5)*0.2*dunes_octavenoise(GetFracDef(6), 0.6*distrib, p); //n += continents*Clamp(0.05-n, 0.0, 0.01)*0.2*dunes_octavenoise(GetFracDef(2), Clamp(0.5-n, 0.0, 0.5), p); - return (n > 0.0 ? n*m_maxHeight : 0.0); + return (n > 0.0 ? n * m_maxHeight : 0.0); } diff --git a/src/terrain/TerrainHeightHillsNormal.cpp b/src/terrain/TerrainHeightHillsNormal.cpp index b06fc26cf..e6907a36c 100644 --- a/src/terrain/TerrainHeightHillsNormal.cpp +++ b/src/terrain/TerrainHeightHillsNormal.cpp @@ -10,45 +10,45 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsNormal"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //textures if (textures) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10 * m_fracmult); } //small fractal/high detail - SetFracDef(2-m_fracnum, m_maxHeightInMeters*0.000000005, 500, 20*m_fracmult); + SetFracDef(2 - m_fracnum, m_maxHeightInMeters * 0.000000005, 500, 20 * m_fracmult); //continental: - SetFracDef(3-m_fracnum, m_maxHeightInMeters*0.00001, 1e7, 1000*m_fracmult); + SetFracDef(3 - m_fracnum, m_maxHeightInMeters * 0.00001, 1e7, 1000 * m_fracmult); //large fractal: - SetFracDef(4-m_fracnum, m_maxHeightInMeters, 1e5, 200*m_fracmult); + SetFracDef(4 - m_fracnum, m_maxHeightInMeters, 1e5, 200 * m_fracmult); //medium fractal: - SetFracDef(5-m_fracnum, m_maxHeightInMeters*0.00005, 2e4, 200*m_fracmult); - SetFracDef(6-m_fracnum, m_maxHeightInMeters*0.000000005, 1000, 20*m_fracmult); + SetFracDef(5 - m_fracnum, m_maxHeightInMeters * 0.00005, 2e4, 200 * m_fracmult); + SetFracDef(6 - m_fracnum, m_maxHeightInMeters * 0.000000005, 1000, 20 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = octavenoise(GetFracDef(3-m_fracnum), 0.65, p) * (1.0-m_sealevel) - (m_sealevel*0.1); + double continents = octavenoise(GetFracDef(3 - m_fracnum), 0.65, p) * (1.0 - m_sealevel) - (m_sealevel * 0.1); if (continents < 0) return 0; double n = continents; - double distrib = octavenoise(GetFracDef(4-m_fracnum), 0.5, p); + double distrib = octavenoise(GetFracDef(4 - m_fracnum), 0.5, p); distrib *= distrib; - double m = 0.5*GetFracDef(3-m_fracnum).amplitude * octavenoise(GetFracDef(4-m_fracnum), 0.55*distrib, p) - * GetFracDef(5-m_fracnum).amplitude; - m += 0.25*billow_octavenoise(GetFracDef(5-m_fracnum), 0.55*distrib, p); + double m = 0.5 * GetFracDef(3 - m_fracnum).amplitude * octavenoise(GetFracDef(4 - m_fracnum), 0.55 * distrib, p) * GetFracDef(5 - m_fracnum).amplitude; + m += 0.25 * billow_octavenoise(GetFracDef(5 - m_fracnum), 0.55 * distrib, p); //hill footings - m -= octavenoise(GetFracDef(2-m_fracnum), 0.6*(1.0-distrib), p) - * Clamp(0.05-m, 0.0, 0.05) * Clamp(0.05-m, 0.0, 0.05); + m -= octavenoise(GetFracDef(2 - m_fracnum), 0.6 * (1.0 - distrib), p) * Clamp(0.05 - m, 0.0, 0.05) * Clamp(0.05 - m, 0.0, 0.05); //hill footings - m += voronoiscam_octavenoise(GetFracDef(6-m_fracnum), 0.765*distrib, p) - * Clamp(0.025-m, 0.0, 0.025) * Clamp(0.025-m, 0.0, 0.025); + m += voronoiscam_octavenoise(GetFracDef(6 - m_fracnum), 0.765 * distrib, p) * Clamp(0.025 - m, 0.0, 0.025) * Clamp(0.025 - m, 0.0, 0.025); // cliffs at shore - if (continents < 0.01) n += m * continents * 100.0f; - else n += m; + if (continents < 0.01) + n += m * continents * 100.0f; + else + n += m; - if (n > 0.0) return n*m_maxHeight; - return 0.0; + if (n > 0.0) return n * m_maxHeight; + return 0.0; } diff --git a/src/terrain/TerrainHeightHillsRidged.cpp b/src/terrain/TerrainHeightHillsRidged.cpp index f6100a760..310489c8f 100644 --- a/src/terrain/TerrainHeightHillsRidged.cpp +++ b/src/terrain/TerrainHeightHillsRidged.cpp @@ -10,37 +10,40 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsRidged"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //textures: - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10 * m_fracmult); //small fractal/high detail: - SetFracDef(2, m_maxHeightInMeters*0.000000005, m_rand.Double(40, 80), 10*m_fracmult); + SetFracDef(2, m_maxHeightInMeters * 0.000000005, m_rand.Double(40, 80), 10 * m_fracmult); //continental: - SetFracDef(3, m_maxHeightInMeters*0.00001, m_rand.Double(1e6, 2e7), 1000*m_fracmult); + SetFracDef(3, m_maxHeightInMeters * 0.00001, m_rand.Double(1e6, 2e7), 1000 * m_fracmult); //large fractal: - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(1e5, 5e6), 200*m_fracmult); + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(1e5, 5e6), 200 * m_fracmult); //medium fractal: - SetFracDef(5, m_maxHeightInMeters*0.00005, m_rand.Double(1e3, 5e4), 100*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.00000002, m_rand.Double(250, 1e3), 50*m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.00005, m_rand.Double(1e3, 5e4), 100 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.00000002, m_rand.Double(250, 1e3), 50 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = ridged_octavenoise(GetFracDef(3), 0.65, p) * (1.0-m_sealevel) - (m_sealevel*0.1); + double continents = ridged_octavenoise(GetFracDef(3), 0.65, p) * (1.0 - m_sealevel) - (m_sealevel * 0.1); if (continents < 0) return 0; double n = continents; double distrib = river_octavenoise(GetFracDef(4), 0.5, p); - double m = 0.5* ridged_octavenoise(GetFracDef(4), 0.55*distrib, p); - m += continents*0.25*ridged_octavenoise(GetFracDef(5), 0.58*distrib, p); + double m = 0.5 * ridged_octavenoise(GetFracDef(4), 0.55 * distrib, p); + m += continents * 0.25 * ridged_octavenoise(GetFracDef(5), 0.58 * distrib, p); // ** - m += 0.001*ridged_octavenoise(GetFracDef(6), 0.55*distrib*m, p); + m += 0.001 * ridged_octavenoise(GetFracDef(6), 0.55 * distrib * m, p); // cliffs at shore - if (continents < 0.01) n += m * continents * 100.0f; - else n += m; + if (continents < 0.01) + n += m * continents * 100.0f; + else + n += m; // was n -= 0.001*ridged_octavenoise(GetFracDef(6), 0.55*distrib*m, p); //n += 0.001*ridged_octavenoise(GetFracDef(6), 0.55*distrib*m, p); - return (n > 0.0 ? n*m_maxHeight : 0.0); + return (n > 0.0 ? n * m_maxHeight : 0.0); } diff --git a/src/terrain/TerrainHeightHillsRivers.cpp b/src/terrain/TerrainHeightHillsRivers.cpp index e2b847e7b..ed5d5101c 100644 --- a/src/terrain/TerrainHeightHillsRivers.cpp +++ b/src/terrain/TerrainHeightHillsRivers.cpp @@ -10,41 +10,44 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "HillsRivers"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //textures - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5, 15), 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(20, 40), 10 * m_fracmult); //small fractal/high detail - SetFracDef(2, m_maxHeightInMeters*0.000000008, m_rand.Double(5, 70), 10*m_fracmult); + SetFracDef(2, m_maxHeightInMeters * 0.000000008, m_rand.Double(5, 70), 10 * m_fracmult); //continental: - SetFracDef(3, m_maxHeightInMeters, m_rand.Double(1e6, 2e7), 10000*m_fracmult); + SetFracDef(3, m_maxHeightInMeters, m_rand.Double(1e6, 2e7), 10000 * m_fracmult); //large fractal: - SetFracDef(4, m_maxHeightInMeters*0.00001, 1e5, 1000*m_fracmult); - SetFracDef(5, m_maxHeightInMeters*0.000001, m_rand.Double(1e5, 1e6), 100*m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.00001, 1e5, 1000 * m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.000001, m_rand.Double(1e5, 1e6), 100 * m_fracmult); //medium fractal: - SetFracDef(6, m_maxHeightInMeters*0.0000002, m_rand.Double(500, 2e4), 50*m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.0000002, m_rand.Double(500, 2e4), 50 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = river_octavenoise(GetFracDef(3), 0.65, p) * (1.0-m_sealevel) - (m_sealevel*0.1); + double continents = river_octavenoise(GetFracDef(3), 0.65, p) * (1.0 - m_sealevel) - (m_sealevel * 0.1); if (continents < 0) return 0; double n = continents; - double distrib = voronoiscam_octavenoise(GetFracDef(4), 0.5*GetFracDef(5).amplitude, p); - double m = 0.1 * GetFracDef(4).amplitude * river_octavenoise(GetFracDef(5), 0.5*distrib, p); - double mountains = ridged_octavenoise(GetFracDef(5), 0.5*distrib, p) * billow_octavenoise(GetFracDef(5), 0.5, p) * - voronoiscam_octavenoise(GetFracDef(4), 0.5*distrib, p) * distrib; + double distrib = voronoiscam_octavenoise(GetFracDef(4), 0.5 * GetFracDef(5).amplitude, p); + double m = 0.1 * GetFracDef(4).amplitude * river_octavenoise(GetFracDef(5), 0.5 * distrib, p); + double mountains = ridged_octavenoise(GetFracDef(5), 0.5 * distrib, p) * billow_octavenoise(GetFracDef(5), 0.5, p) * + voronoiscam_octavenoise(GetFracDef(4), 0.5 * distrib, p) * distrib; m += mountains; //detail for mountains, stops them looking smooth. - m += mountains*mountains*0.02*ridged_octavenoise(GetFracDef(2), 0.6*mountains*mountains*distrib, p); - m *= m*m*m*10.0; + m += mountains * mountains * 0.02 * ridged_octavenoise(GetFracDef(2), 0.6 * mountains * mountains * distrib, p); + m *= m * m * m * 10.0; // smooth cliffs at shore - if (continents < 0.01) n += m * continents * 100.0f; - else n += m; - n += continents*Clamp(0.5-m, 0.0, 0.5)*0.2*river_octavenoise(GetFracDef(6), 0.6*distrib, p); - n += continents*Clamp(0.05-n, 0.0, 0.01)*0.2*dunes_octavenoise(GetFracDef(2), Clamp(0.5-n, 0.0, 0.5), p); + if (continents < 0.01) + n += m * continents * 100.0f; + else + n += m; + n += continents * Clamp(0.5 - m, 0.0, 0.5) * 0.2 * river_octavenoise(GetFracDef(6), 0.6 * distrib, p); + n += continents * Clamp(0.05 - n, 0.0, 0.01) * 0.2 * dunes_octavenoise(GetFracDef(2), Clamp(0.5 - n, 0.0, 0.5), p); n *= m_maxHeight; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightMapped.cpp b/src/terrain/TerrainHeightMapped.cpp index 013bc0b34..3fc0dcb00 100644 --- a/src/terrain/TerrainHeightMapped.cpp +++ b/src/terrain/TerrainHeightMapped.cpp @@ -10,44 +10,45 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Mapped"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { //textures if (textures) { - SetFracDef(0, m_maxHeightInMeters, 10, 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, 25, 10*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, 10, 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, 25, 10 * m_fracmult); } //small fractal/high detail - SetFracDef(2-m_fracnum, m_maxHeightInMeters*0.0000005, 50, 20*m_fracmult);//[2] + SetFracDef(2 - m_fracnum, m_maxHeightInMeters * 0.0000005, 50, 20 * m_fracmult); //[2] //continental/large type fractal - SetFracDef(3-m_fracnum, m_maxHeightInMeters*0.00005, 1e6, 800*m_fracmult);//[0] - SetFracDef(4-m_fracnum, m_maxHeightInMeters*0.00005, 1e5, 400*m_fracmult);//[4] + SetFracDef(3 - m_fracnum, m_maxHeightInMeters * 0.00005, 1e6, 800 * m_fracmult); //[0] + SetFracDef(4 - m_fracnum, m_maxHeightInMeters * 0.00005, 1e5, 400 * m_fracmult); //[4] //medium fractal - SetFracDef(5-m_fracnum, m_maxHeightInMeters*0.000005, 2e4, 200*m_fracmult);//[5] - SetFracDef(6-m_fracnum, m_maxHeightInMeters*0.0000005, 5e3, 100*m_fracmult);//[3] + SetFracDef(5 - m_fracnum, m_maxHeightInMeters * 0.000005, 2e4, 200 * m_fracmult); //[5] + SetFracDef(6 - m_fracnum, m_maxHeightInMeters * 0.0000005, 5e3, 100 * m_fracmult); //[3] } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - // This is all used for Earth and Earth alone + // This is all used for Earth and Earth alone double latitude = -asin(p.y); - if (p.y < -1.0) latitude = -0.5*M_PI; - if (p.y > 1.0) latitude = 0.5*M_PI; -// if (!isfinite(latitude)) { -// // p.y is just n of asin domain [-1,1] -// latitude = (p.y < 0 ? -0.5*M_PI : M_PI*0.5); -// } + if (p.y < -1.0) latitude = -0.5 * M_PI; + if (p.y > 1.0) latitude = 0.5 * M_PI; + // if (!isfinite(latitude)) { + // // p.y is just n of asin domain [-1,1] + // latitude = (p.y < 0 ? -0.5*M_PI : M_PI*0.5); + // } double longitude = atan2(p.x, p.z); - double px = (((m_heightMapSizeX-1) * (longitude + M_PI)) / (2*M_PI)); - double py = ((m_heightMapSizeY-1)*(latitude + 0.5*M_PI)) / M_PI; + double px = (((m_heightMapSizeX - 1) * (longitude + M_PI)) / (2 * M_PI)); + double py = ((m_heightMapSizeY - 1) * (latitude + 0.5 * M_PI)) / M_PI; int ix = int(floor(px)); int iy = int(floor(py)); - ix = Clamp(ix, 0, m_heightMapSizeX-1); - iy = Clamp(iy, 0, m_heightMapSizeY-1); - double dx = px-ix; - double dy = py-iy; + ix = Clamp(ix, 0, m_heightMapSizeX - 1); + iy = Clamp(iy, 0, m_heightMapSizeY - 1); + double dx = px - ix; + double dy = py - iy; // p0,3 p1,3 p2,3 p3,3 // p0,2 p1,2 p2,2 p3,2 @@ -55,22 +56,22 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) c // p0,0 p1,0 p2,0 p3,0 double map[4][4]; const double *pHMap = m_heightMap.get(); - for (int x=-1; x<3; x++) { - for (int y=-1; y<3; y++) { - map[x+1][y+1] = pHMap[Clamp(iy+y, 0, m_heightMapSizeY-1)*m_heightMapSizeX + Clamp(ix+x, 0, m_heightMapSizeX-1)]; + for (int x = -1; x < 3; x++) { + for (int y = -1; y < 3; y++) { + map[x + 1][y + 1] = pHMap[Clamp(iy + y, 0, m_heightMapSizeY - 1) * m_heightMapSizeX + Clamp(ix + x, 0, m_heightMapSizeX - 1)]; } } double c[4]; - for (int j=0; j<4; j++) { + for (int j = 0; j < 4; j++) { double d0 = map[0][j] - map[1][j]; double d2 = map[2][j] - map[1][j]; double d3 = map[3][j] - map[1][j]; double a0 = map[1][j]; - double a1 = -(1/3.0)*d0 + d2 - (1/6.0)*d3; - double a2 = 0.5*d0 + 0.5*d2; - double a3 = -(1/6.0)*d0 - 0.5*d2 + (1/6.0)*d3; - c[j] = a0 + a1*dx + a2*dx*dx + a3*dx*dx*dx; + double a1 = -(1 / 3.0) * d0 + d2 - (1 / 6.0) * d3; + double a2 = 0.5 * d0 + 0.5 * d2; + double a3 = -(1 / 6.0) * d0 - 0.5 * d2 + (1 / 6.0) * d3; + c[j] = a0 + a1 * dx + a2 * dx * dx + a3 * dx * dx * dx; } { @@ -78,66 +79,60 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) c double d2 = c[2] - c[1]; double d3 = c[3] - c[1]; double a0 = c[1]; - double a1 = -(1/3.0)*d0 + d2 - (1/6.0)*d3; - double a2 = 0.5*d0 + 0.5*d2; - double a3 = -(1/6.0)*d0 - 0.5*d2 + (1/6.0)*d3; - double v = a0 + a1*dy + a2*dy*dy + a3*dy*dy*dy; + double a1 = -(1 / 3.0) * d0 + d2 - (1 / 6.0) * d3; + double a2 = 0.5 * d0 + 0.5 * d2; + double a3 = -(1 / 6.0) * d0 - 0.5 * d2 + (1 / 6.0) * d3; + double v = a0 + a1 * dy + a2 * dy * dy + a3 * dy * dy * dy; - v = (v<0 ? 0 : v); + v = (v < 0 ? 0 : v); double h = v; //Here's where we add some noise over the heightmap so it doesnt look so boring, we scale by height so values are greater high up //large mountainous shapes - double mountains = h*h*0.001*octavenoise(GetFracDef(3-m_fracnum), 0.5*octavenoise(GetFracDef(5-m_fracnum), 0.45, p), - p)*ridged_octavenoise(GetFracDef(4-m_fracnum), 0.475*octavenoise(GetFracDef(6-m_fracnum), 0.4, p), p); + double mountains = h * h * 0.001 * octavenoise(GetFracDef(3 - m_fracnum), 0.5 * octavenoise(GetFracDef(5 - m_fracnum), 0.45, p), p) * ridged_octavenoise(GetFracDef(4 - m_fracnum), 0.475 * octavenoise(GetFracDef(6 - m_fracnum), 0.4, p), p); v += mountains; //smaller ridged mountains - if (v < 50.0){ - v += v*v*0.04*ridged_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); - } else if (v <100.0){ - v += 100.0*ridged_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); + if (v < 50.0) { + v += v * v * 0.04 * ridged_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); + } else if (v < 100.0) { + v += 100.0 * ridged_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); } else { - v += (100.0/v)*(100.0/v)*(100.0/v)*(100.0/v)*(100.0/v)* - 100.0*ridged_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); + v += (100.0 / v) * (100.0 / v) * (100.0 / v) * (100.0 / v) * (100.0 / v) * + 100.0 * ridged_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); } //high altitude detail/mountains //v += Clamp(h, 0.0, 0.5)*octavenoise(GetFracDef(2-m_fracnum), 0.5, p); //low altitude detail/dunes //v += h*0.000003*ridged_octavenoise(GetFracDef(2-m_fracnum), Clamp(1.0-h*0.002, 0.0, 0.5), p); - if (v < 10.0){ - v += 2.0*v*dunes_octavenoise(GetFracDef(6-m_fracnum), 0.5, p) - *octavenoise(GetFracDef(6-m_fracnum), 0.5, p); - } else if (v <50.0){ - v += 20.0*dunes_octavenoise(GetFracDef(6-m_fracnum), 0.5, p) - *octavenoise(GetFracDef(6-m_fracnum), 0.5, p); + if (v < 10.0) { + v += 2.0 * v * dunes_octavenoise(GetFracDef(6 - m_fracnum), 0.5, p) * octavenoise(GetFracDef(6 - m_fracnum), 0.5, p); + } else if (v < 50.0) { + v += 20.0 * dunes_octavenoise(GetFracDef(6 - m_fracnum), 0.5, p) * octavenoise(GetFracDef(6 - m_fracnum), 0.5, p); } else { - v += (50.0/v)*(50.0/v)*(50.0/v)*(50.0/v)*(50.0/v) - *20.0*dunes_octavenoise(GetFracDef(6-m_fracnum), 0.5, p) - *octavenoise(GetFracDef(6-m_fracnum), 0.5, p); + v += (50.0 / v) * (50.0 / v) * (50.0 / v) * (50.0 / v) * (50.0 / v) * 20.0 * dunes_octavenoise(GetFracDef(6 - m_fracnum), 0.5, p) * octavenoise(GetFracDef(6 - m_fracnum), 0.5, p); } - if (v<40.0) { + if (v < 40.0) { //v = v; - } else if (v <60.0){ - v += (v-40.0)*billow_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); + } else if (v < 60.0) { + v += (v - 40.0) * billow_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); //Output("V/height: %f\n", Clamp(v-20.0, 0.0, 1.0)); } else { - v += (30.0/v)*(30.0/v)*(30.0/v)*20.0*billow_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); + v += (30.0 / v) * (30.0 / v) * (30.0 / v) * 20.0 * billow_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); } //ridges and bumps //v += h*0.1*ridged_octavenoise(GetFracDef(6-m_fracnum), Clamp(h*0.0002, 0.3, 0.5), p) // * Clamp(h*0.0002, 0.1, 0.5); - v += h*0.2*voronoiscam_octavenoise(GetFracDef(5-m_fracnum), Clamp(1.0-(h*0.0002), 0.0, 0.6), p) - * Clamp(1.0-(h*0.0006), 0.0, 1.0); + v += h * 0.2 * voronoiscam_octavenoise(GetFracDef(5 - m_fracnum), Clamp(1.0 - (h * 0.0002), 0.0, 0.6), p) * Clamp(1.0 - (h * 0.0006), 0.0, 1.0); //polar ice caps with cracks - if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) { - h = Clamp(1.0-(v*10.0), 0.0, 1.0)*voronoiscam_octavenoise(GetFracDef(5-m_fracnum), 0.5, p); - h *= h*h*2.0; + if ((m_icyness * 0.5) + (fabs(p.y * p.y * p.y * 0.38)) > 0.6) { + h = Clamp(1.0 - (v * 10.0), 0.0, 1.0) * voronoiscam_octavenoise(GetFracDef(5 - m_fracnum), 0.5, p); + h *= h * h * 2.0; h -= 3.0; v += h; } - return v<0 ? 0 : (v/m_planetRadius); + return v < 0 ? 0 : (v / m_planetRadius); } } diff --git a/src/terrain/TerrainHeightMapped2.cpp b/src/terrain/TerrainHeightMapped2.cpp index db151f43a..d47039828 100644 --- a/src/terrain/TerrainHeightMapped2.cpp +++ b/src/terrain/TerrainHeightMapped2.cpp @@ -9,7 +9,8 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "Mapped2"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { } @@ -18,21 +19,21 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) { double latitude = -asin(p.y); - if (p.y < -1.0) latitude = -0.5*M_PI; - if (p.y > 1.0) latitude = 0.5*M_PI; -// if (!isfinite(latitude)) { -// // p.y is just n of asin domain [-1,1] -// latitude = (p.y < 0 ? -0.5*M_PI : M_PI*0.5); -// } + if (p.y < -1.0) latitude = -0.5 * M_PI; + if (p.y > 1.0) latitude = 0.5 * M_PI; + // if (!isfinite(latitude)) { + // // p.y is just n of asin domain [-1,1] + // latitude = (p.y < 0 ? -0.5*M_PI : M_PI*0.5); + // } double longitude = atan2(p.x, p.z); - double px = (((m_heightMapSizeX-1) * (longitude + M_PI)) / (2*M_PI)); - double py = ((m_heightMapSizeY-1)*(latitude + 0.5*M_PI)) / M_PI; + double px = (((m_heightMapSizeX - 1) * (longitude + M_PI)) / (2 * M_PI)); + double py = ((m_heightMapSizeY - 1) * (latitude + 0.5 * M_PI)) / M_PI; int ix = int(floor(px)); int iy = int(floor(py)); - ix = Clamp(ix, 0, m_heightMapSizeX-1); - iy = Clamp(iy, 0, m_heightMapSizeY-1); - double dx = px-ix; - double dy = py-iy; + ix = Clamp(ix, 0, m_heightMapSizeX - 1); + iy = Clamp(iy, 0, m_heightMapSizeY - 1); + double dx = px - ix; + double dy = py - iy; // p0,3 p1,3 p2,3 p3,3 // p0,2 p1,2 p2,2 p3,2 @@ -40,22 +41,22 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) // p0,0 p1,0 p2,0 p3,0 double map[4][4]; const double *pHMap = m_heightMap.get(); - for (int x=-1; x<3; x++) { - for (int y=-1; y<3; y++) { - map[x+1][y+1] = pHMap[Clamp(iy+y, 0, m_heightMapSizeY-1)*m_heightMapSizeX + Clamp(ix+x, 0, m_heightMapSizeX-1)]; + for (int x = -1; x < 3; x++) { + for (int y = -1; y < 3; y++) { + map[x + 1][y + 1] = pHMap[Clamp(iy + y, 0, m_heightMapSizeY - 1) * m_heightMapSizeX + Clamp(ix + x, 0, m_heightMapSizeX - 1)]; } } double c[4]; - for (int j=0; j<4; j++) { + for (int j = 0; j < 4; j++) { double d0 = map[0][j] - map[1][j]; double d2 = map[2][j] - map[1][j]; double d3 = map[3][j] - map[1][j]; double a0 = map[1][j]; - double a1 = -(1/3.0)*d0 + d2 - (1/6.0)*d3; - double a2 = 0.5*d0 + 0.5*d2; - double a3 = -(1/6.0)*d0 - 0.5*d2 + (1/6.0)*d3; - c[j] = a0 + a1*dx + a2*dx*dx + a3*dx*dx*dx; + double a1 = -(1 / 3.0) * d0 + d2 - (1 / 6.0) * d3; + double a2 = 0.5 * d0 + 0.5 * d2; + double a3 = -(1 / 6.0) * d0 - 0.5 * d2 + (1 / 6.0) * d3; + c[j] = a0 + a1 * dx + a2 * dx * dx + a3 * dx * dx * dx; } { @@ -63,25 +64,22 @@ double TerrainHeightFractal::GetHeight(const vector3d &p) double d2 = c[2] - c[1]; double d3 = c[3] - c[1]; double a0 = c[1]; - double a1 = -(1/3.0)*d0 + d2 - (1/6.0)*d3; - double a2 = 0.5*d0 + 0.5*d2; - double a3 = -(1/6.0)*d0 - 0.5*d2 + (1/6.0)*d3; - double v = 0.1 + a0 + a1*dy + a2*dy*dy + a3*dy*dy*dy; + double a1 = -(1 / 3.0) * d0 + d2 - (1 / 6.0) * d3; + double a2 = 0.5 * d0 + 0.5 * d2; + double a3 = -(1 / 6.0) * d0 - 0.5 * d2 + (1 / 6.0) * d3; + double v = 0.1 + a0 + a1 * dy + a2 * dy * dy + a3 * dy * dy * dy; //v = (v<0 ? 0 : v); - v=v*m_heightScaling+m_minh; // v = v*height scaling+min height - v/=m_planetRadius; + v = v * m_heightScaling + m_minh; // v = v*height scaling+min height + v /= m_planetRadius; v += 0.1; - double h = 1.5*v*v*v*ridged_octavenoise(16, 4.0*v, 4.0, p); - h += 30000.0*v*v*v*v*v*v*v*ridged_octavenoise(16, 5.0*v, 20.0*v, p); + double h = 1.5 * v * v * v * ridged_octavenoise(16, 4.0 * v, 4.0, p); + h += 30000.0 * v * v * v * v * v * v * v * ridged_octavenoise(16, 5.0 * v, 20.0 * v, p); h += v; h -= 0.09; return (h > 0.0 ? h : 0.0); - } - } - diff --git a/src/terrain/TerrainHeightMountainsCraters.cpp b/src/terrain/TerrainHeightMountainsCraters.cpp index 574c2709e..7802b9eb3 100644 --- a/src/terrain/TerrainHeightMountainsCraters.cpp +++ b/src/terrain/TerrainHeightMountainsCraters.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,19 +12,20 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsCraters"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); - height = m_maxHeightInMeters*0.3; - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(3, height, m_rand.Double(2.5,3.5)*height); + height = m_maxHeightInMeters * 0.3; + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(3, height, m_rand.Double(2.5, 3.5) * height); - SetFracDef(5, m_maxHeightInMeters*0.05, 8e5, 1000.0*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.05, 8e5, 1000.0 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); } template <> @@ -35,10 +36,12 @@ double TerrainHeightFractal::GetHeight(const vect double n = 0.3 * continents; double m = GetFracDef(1).amplitude * ridged_octavenoise(GetFracDef(1), 0.5, p); double distrib = ridged_octavenoise(GetFracDef(4), 0.5, p); - if (distrib > 0.5) m += 2.0 * (distrib-0.5) * GetFracDef(3).amplitude * ridged_octavenoise(GetFracDef(3), 0.5*distrib, p); + if (distrib > 0.5) m += 2.0 * (distrib - 0.5) * GetFracDef(3).amplitude * ridged_octavenoise(GetFracDef(3), 0.5 * distrib, p); // cliffs at shore - if (continents < 0.001) n += m * continents * 1000.0f; - else n += m; + if (continents < 0.001) + n += m * continents * 1000.0f; + else + n += m; n += crater_function(GetFracDef(5), p); n += crater_function(GetFracDef(6), p); n *= m_maxHeight; diff --git a/src/terrain/TerrainHeightMountainsCraters2.cpp b/src/terrain/TerrainHeightMountainsCraters2.cpp index 48c304a45..31ff86122 100644 --- a/src/terrain/TerrainHeightMountainsCraters2.cpp +++ b/src/terrain/TerrainHeightMountainsCraters2.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,21 +12,22 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsCraters2"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.5; - SetFracDef(1, height, m_rand.Double(50.0, 200.0)*height, 10*m_fracmult); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(500.0, 5000.0)*m_maxHeightInMeters); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.5; + SetFracDef(1, height, m_rand.Double(50.0, 200.0) * height, 10 * m_fracmult); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(500.0, 5000.0) * m_maxHeightInMeters); - height = m_maxHeightInMeters*0.4; - SetFracDef(3, height, m_rand.Double(2.5,3.5)*height); - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(5, m_maxHeightInMeters*0.05, 1e6, 10000.0*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.04, 9e5, 10000.0*m_fracmult); - SetFracDef(7, m_maxHeightInMeters*0.05, 8e5, 10000.0*m_fracmult); - SetFracDef(8, m_maxHeightInMeters*0.04, 11e5, 10000.0*m_fracmult); - SetFracDef(9, m_maxHeightInMeters*0.07, 12e5, 10000.0*m_fracmult); + height = m_maxHeightInMeters * 0.4; + SetFracDef(3, height, m_rand.Double(2.5, 3.5) * height); + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(5, m_maxHeightInMeters * 0.05, 1e6, 10000.0 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.04, 9e5, 10000.0 * m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.05, 8e5, 10000.0 * m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 0.04, 11e5, 10000.0 * m_fracmult); + SetFracDef(9, m_maxHeightInMeters * 0.07, 12e5, 10000.0 * m_fracmult); } template <> @@ -35,15 +36,17 @@ double TerrainHeightFractal::GetHeight(const vec double continents = octavenoise(GetFracDef(0), 0.5, p) - m_sealevel; if (continents < 0) return 0; double n = 0.3 * continents; - double m = 0;//GetFracDef(1).amplitude * octavenoise(GetFracDef(1), 0.5, p); - double distrib = 0.5*ridged_octavenoise(GetFracDef(1), 0.5*octavenoise(GetFracDef(2), 0.5, p), p); - distrib += 0.7*billow_octavenoise(GetFracDef(2), 0.5*ridged_octavenoise(GetFracDef(1), 0.5, p), p) + - 0.1*octavenoise(GetFracDef(3), 0.5*ridged_octavenoise(GetFracDef(2), 0.5, p), p); + double m = 0; //GetFracDef(1).amplitude * octavenoise(GetFracDef(1), 0.5, p); + double distrib = 0.5 * ridged_octavenoise(GetFracDef(1), 0.5 * octavenoise(GetFracDef(2), 0.5, p), p); + distrib += 0.7 * billow_octavenoise(GetFracDef(2), 0.5 * ridged_octavenoise(GetFracDef(1), 0.5, p), p) + + 0.1 * octavenoise(GetFracDef(3), 0.5 * ridged_octavenoise(GetFracDef(2), 0.5, p), p); - if (distrib > 0.5) m += 2.0 * (distrib-0.5) * GetFracDef(3).amplitude * octavenoise(GetFracDef(4), 0.5*distrib, p); + if (distrib > 0.5) m += 2.0 * (distrib - 0.5) * GetFracDef(3).amplitude * octavenoise(GetFracDef(4), 0.5 * distrib, p); // cliffs at shore - if (continents < 0.001) n += m * continents * 1000.0f; - else n += m; + if (continents < 0.001) + n += m * continents * 1000.0f; + else + n += m; n += crater_function(GetFracDef(5), p); n += crater_function(GetFracDef(6), p); n += crater_function(GetFracDef(7), p); diff --git a/src/terrain/TerrainHeightMountainsNormal.cpp b/src/terrain/TerrainHeightMountainsNormal.cpp index b5343c1f2..ffff63b24 100644 --- a/src/terrain/TerrainHeightMountainsNormal.cpp +++ b/src/terrain/TerrainHeightMountainsNormal.cpp @@ -10,79 +10,67 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsNormal"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7), 10000*m_fracmult); - SetFracDef(1, m_maxHeightInMeters*0.00000000001, 100.0, 10*m_fracmult); - SetFracDef(2, m_maxHeightInMeters*0.0000001, m_rand.Double(500, 2e3), 1000*m_fracmult); - SetFracDef(3, m_maxHeightInMeters*0.00002, m_rand.Double(1500, 1e4), 100*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.08, 1e4, 100*m_fracmult); - SetFracDef(5, m_maxHeightInMeters*0.2, 1e5, 100*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.5, 1e6, 1000*m_fracmult); - SetFracDef(7, m_maxHeightInMeters*0.5, m_rand.Double(1e6,1e7), 1000*m_fracmult); - SetFracDef(8, m_maxHeightInMeters, m_rand.Double(3e6, 1e7), 1000*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7), 10000 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters * 0.00000000001, 100.0, 10 * m_fracmult); + SetFracDef(2, m_maxHeightInMeters * 0.0000001, m_rand.Double(500, 2e3), 1000 * m_fracmult); + SetFracDef(3, m_maxHeightInMeters * 0.00002, m_rand.Double(1500, 1e4), 100 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.08, 1e4, 100 * m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.2, 1e5, 100 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.5, 1e6, 1000 * m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.5, m_rand.Double(1e6, 1e7), 1000 * m_fracmult); + SetFracDef(8, m_maxHeightInMeters, m_rand.Double(3e6, 1e7), 1000 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const - //This is among the most complex of terrains, so I'll use this as an example: +//This is among the most complex of terrains, so I'll use this as an example: { //We need a continental pattern to place our noise onto, the 0.7*ridged_octavnoise..... is important here // for making 'broken up' coast lines, as opposed to circular land masses, it will reduce the frequency of our // continents depending on the ridged noise value, we subtract sealevel so that sea level will have an effect on the continents size - double continents = octavenoise(GetFracDef(0), 0.7* - ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel*0.65; + double continents = octavenoise(GetFracDef(0), 0.7 * ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel * 0.65; // if there are no continents on an area, we want it to be sea level if (continents < 0) return 0; - double n = continents - (GetFracDef(0).amplitude*m_sealevel*0.5); + double n = continents - (GetFracDef(0).amplitude * m_sealevel * 0.5); // we save the height n now as a constant h const double h = n; //We don't want to apply noise to sea level n=0 if (n > 0.0) { //large mountainous shapes - n += h*0.2*ridged_octavenoise(GetFracDef(7), - 0.5*octavenoise(GetFracDef(6), 0.5, p), p); + n += h * 0.2 * ridged_octavenoise(GetFracDef(7), 0.5 * octavenoise(GetFracDef(6), 0.5, p), p); // This smoothes edges near the coast, we cant have vertical terrain its not handled correctly. - if (n < 0.4){ - n += n*1.25*ridged_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.3, 0.7)* - ridged_octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.4) { + n += n * 1.25 * ridged_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.3, 0.7) * ridged_octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += 0.5*ridged_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.3, 0.7)* - ridged_octavenoise(GetFracDef(5), 0.5, p), p); + n += 0.5 * ridged_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.3, 0.7) * ridged_octavenoise(GetFracDef(5), 0.5, p), p); } - if (n < 0.2){ - n += n*15.0*river_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.5, 0.7), p); + if (n < 0.2) { + n += n * 15.0 * river_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.5, 0.7), p); } else { - n += 3.0*river_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.5, 0.7), p); + n += 3.0 * river_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.5, 0.7), p); } n *= 0.33333333333; - if (n < 0.133){ - n += n*billow_octavenoise(GetFracDef(6), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.133) { + n += n * billow_octavenoise(GetFracDef(6), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += (0.16/n)*billow_octavenoise(GetFracDef(6), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + n += (0.16 / n) * billow_octavenoise(GetFracDef(6), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } - if (n < 0.066667){ - n += n*billow_octavenoise(GetFracDef(5), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.066667) { + n += n * billow_octavenoise(GetFracDef(5), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += (0.04/n)*billow_octavenoise(GetFracDef(5), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + n += (0.04 / n) * billow_octavenoise(GetFracDef(5), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } //smaller ridged mountains - n += n*0.7*ridged_octavenoise(GetFracDef(5), - 0.5*octavenoise(GetFracDef(6), 0.5, p), p); + n += n * 0.7 * ridged_octavenoise(GetFracDef(5), 0.5 * octavenoise(GetFracDef(6), 0.5, p), p); - n = (n*0.5)+(n*n); + n = (n * 0.5) + (n * n); //jagged surface for mountains //This is probably using far too much noise, some of it is just not needed @@ -93,76 +81,52 @@ double TerrainHeightFractal::GetHeight(const vecto // 0.1, // 0.5) But I have no time for testing if (n > 0.25) { - n += (n-0.25)*0.1*octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p)), p); //[4]? + n += (n - 0.25) * 0.1 * octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p)), p); //[4]? } if (n > 0.2 && n <= 0.25) { - n += (0.25-n)*0.2*ridged_octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.5*octavenoise(GetFracDef(4), 0.5, p)), p); + n += (0.25 - n) * 0.2 * ridged_octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.5 * octavenoise(GetFracDef(4), 0.5, p)), p); } else if (n > 0.05) { - n += ((n-0.05)/15)*ridged_octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.5*octavenoise(GetFracDef(4), 0.5, p)), p); + n += ((n - 0.05) / 15) * ridged_octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.5 * octavenoise(GetFracDef(4), 0.5, p)), p); } - n = n*0.2; + n = n * 0.2; - if (n < 0.01){ - n += n*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); - } else if (n <0.02){ - n += 0.01*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); + if (n < 0.01) { + n += n * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); + } else if (n < 0.02) { + n += 0.01 * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); } else { - n += (0.02/n)*0.01*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); + n += (0.02 / n) * 0.01 * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); } - if (n < 0.001){ - n += n*3*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); - } else if (n <0.01){ - n += 0.003*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); + if (n < 0.001) { + n += n * 3 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); + } else if (n < 0.01) { + n += 0.003 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); } else { - n += (0.01/n)*0.003*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); + n += (0.01 / n) * 0.003 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); } - if (n < 0.001){ - n += n*0.2*ridged_octavenoise(GetFracDef(1), - 0.5*octavenoise(GetFracDef(2), 0.5, p), p); - } else if (n <0.01){ - n += 0.0002*ridged_octavenoise(GetFracDef(1), - 0.5*octavenoise(GetFracDef(2), 0.5, p), p); + if (n < 0.001) { + n += n * 0.2 * ridged_octavenoise(GetFracDef(1), 0.5 * octavenoise(GetFracDef(2), 0.5, p), p); + } else if (n < 0.01) { + n += 0.0002 * ridged_octavenoise(GetFracDef(1), 0.5 * octavenoise(GetFracDef(2), 0.5, p), p); } else { - n += (0.01/n)*0.0002*ridged_octavenoise(GetFracDef(1), - 0.5*octavenoise(GetFracDef(2), 0.5, p), p); + n += (0.01 / n) * 0.0002 * ridged_octavenoise(GetFracDef(1), 0.5 * octavenoise(GetFracDef(2), 0.5, p), p); } - if (n < 0.1){ - n += n*0.05*dunes_octavenoise(GetFracDef(2), - n*river_octavenoise(GetFracDef(2), 0.5, p), p); - } else if (n <0.2){ - n += 0.005*dunes_octavenoise(GetFracDef(2), - ((n*n*10.0)+(3*(n-0.1)))* - river_octavenoise(GetFracDef(2), 0.5, p), p); + if (n < 0.1) { + n += n * 0.05 * dunes_octavenoise(GetFracDef(2), n * river_octavenoise(GetFracDef(2), 0.5, p), p); + } else if (n < 0.2) { + n += 0.005 * dunes_octavenoise(GetFracDef(2), ((n * n * 10.0) + (3 * (n - 0.1))) * river_octavenoise(GetFracDef(2), 0.5, p), p); } else { - n += (0.2/n)*0.005*dunes_octavenoise(GetFracDef(2), - Clamp(0.7-(1-(5*n)), 0.0, 0.7)* - river_octavenoise(GetFracDef(2), 0.5, p), p); + n += (0.2 / n) * 0.005 * dunes_octavenoise(GetFracDef(2), Clamp(0.7 - (1 - (5 * n)), 0.0, 0.7) * river_octavenoise(GetFracDef(2), 0.5, p), p); } //terrain is too mountainous, so we reduce the height //n *= 0.3; - } - n = m_maxHeight*n; + n = m_maxHeight * n; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightMountainsRidged.cpp b/src/terrain/TerrainHeightMountainsRidged.cpp index 4b4b9a8c6..2ddae4139 100644 --- a/src/terrain/TerrainHeightMountainsRidged.cpp +++ b/src/terrain/TerrainHeightMountainsRidged.cpp @@ -10,22 +10,23 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsRidged"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.9; - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters, 8*m_fracmult); - SetFracDef(2, height, m_rand.Double(4.0, 200.0)*height, 10*m_fracmult); - SetFracDef(3, m_maxHeightInMeters, m_rand.Double(120.0, 2000.0)*m_maxHeightInMeters, 1000*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.9; + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters, 8 * m_fracmult); + SetFracDef(2, height, m_rand.Double(4.0, 200.0) * height, 10 * m_fracmult); + SetFracDef(3, m_maxHeightInMeters, m_rand.Double(120.0, 2000.0) * m_maxHeightInMeters, 1000 * m_fracmult); - height = m_maxHeightInMeters*0.4; - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(5, height*0.4, m_rand.Double(2.5,30.5)*height); - SetFracDef(6, height*0.2, m_rand.Double(20.5,350.5)*height, 10000*m_fracmult); + height = m_maxHeightInMeters * 0.4; + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(5, height * 0.4, m_rand.Double(2.5, 30.5) * height); + SetFracDef(6, height * 0.2, m_rand.Double(20.5, 350.5) * height, 10000 * m_fracmult); - SetFracDef(7, m_maxHeightInMeters, m_rand.Double(100.0, 2000.0)*m_maxHeightInMeters, 100*m_fracmult); - SetFracDef(8, height*0.3, m_rand.Double(2.5,300.5)*height, 500*m_fracmult); - SetFracDef(9, height*0.2, m_rand.Double(2.5,300.5)*height, 20*m_fracmult); + SetFracDef(7, m_maxHeightInMeters, m_rand.Double(100.0, 2000.0) * m_maxHeightInMeters, 100 * m_fracmult); + SetFracDef(8, height * 0.3, m_rand.Double(2.5, 300.5) * height, 500 * m_fracmult); + SetFracDef(9, height * 0.2, m_rand.Double(2.5, 300.5) * height, 20 * m_fracmult); } template <> @@ -45,29 +46,39 @@ double TerrainHeightFractal::GetHeight(const vecto double hills3 = hill2_distrib * GetFracDef(8).amplitude * ridged_octavenoise(GetFracDef(8), 0.5, p); double hills4 = hill2_distrib * GetFracDef(9).amplitude * ridged_octavenoise(GetFracDef(9), 0.5, p); - double n = continents - (GetFracDef(0).amplitude*m_sealevel); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); if (n > 0.0) { // smooth in hills at shore edges - if (n < 0.1) n += hills * n * 10.0f; - else n += hills; - if (n < 0.05) n += hills2 * n * 20.0f; - else n += hills2 ; + if (n < 0.1) + n += hills * n * 10.0f; + else + n += hills; + if (n < 0.05) + n += hills2 * n * 20.0f; + else + n += hills2; - if (n < 0.1) n += hills3 * n * 10.0f; - else n += hills3; - if (n < 0.05) n += hills4 * n * 20.0f; - else n += hills4 ; + if (n < 0.1) + n += hills3 * n * 10.0f; + else + n += hills3; + if (n < 0.05) + n += hills4 * n * 20.0f; + else + n += hills4; - mountains = octavenoise(GetFracDef(1), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; + mountains = octavenoise(GetFracDef(1), 0.5, p) * + GetFracDef(2).amplitude * mountains * mountains * mountains; mountains2 = octavenoise(GetFracDef(4), 0.5, p) * - GetFracDef(3).amplitude * mountains2*mountains2*mountains2*mountains2; - if (n > 0.2) n += mountains2 * (n - 0.2) ; - if (n < 0.2) n += mountains * n * 5.0f ; - else n += mountains ; + GetFracDef(3).amplitude * mountains2 * mountains2 * mountains2 * mountains2; + if (n > 0.2) n += mountains2 * (n - 0.2); + if (n < 0.2) + n += mountains * n * 5.0f; + else + n += mountains; } - n = m_maxHeight*n; + n = m_maxHeight * n; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightMountainsRivers.cpp b/src/terrain/TerrainHeightMountainsRivers.cpp index 1231357a7..a999013d7 100644 --- a/src/terrain/TerrainHeightMountainsRivers.cpp +++ b/src/terrain/TerrainHeightMountainsRivers.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,31 +12,31 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsRivers"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 2e6), 10*m_fracmult); - SetFracDef(1, m_maxHeightInMeters, 15e6, 100.0*m_fracmult); - SetFracDef(2, m_maxHeightInMeters*0.0000001, m_rand.Double(500, 2e3), 10*m_fracmult); - SetFracDef(3, m_maxHeightInMeters*0.00002, m_rand.Double(1500, 1e4), 10*m_fracmult); - SetFracDef(4, m_maxHeightInMeters*0.08, 1e4, 10*m_fracmult); - SetFracDef(5, m_maxHeightInMeters*0.2, 1e5, 10*m_fracmult); - SetFracDef(6, m_maxHeightInMeters*0.5, 1e6, 100*m_fracmult); - SetFracDef(7, m_maxHeightInMeters*0.5, m_rand.Double(1e6,5e6), 100*m_fracmult); - SetFracDef(8, m_maxHeightInMeters, m_rand.Double(12e5, 22e5), 10*m_fracmult); - SetFracDef(9, m_maxHeightInMeters, 1e7, 100.0*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 2e6), 10 * m_fracmult); + SetFracDef(1, m_maxHeightInMeters, 15e6, 100.0 * m_fracmult); + SetFracDef(2, m_maxHeightInMeters * 0.0000001, m_rand.Double(500, 2e3), 10 * m_fracmult); + SetFracDef(3, m_maxHeightInMeters * 0.00002, m_rand.Double(1500, 1e4), 10 * m_fracmult); + SetFracDef(4, m_maxHeightInMeters * 0.08, 1e4, 10 * m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.2, 1e5, 10 * m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.5, 1e6, 100 * m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.5, m_rand.Double(1e6, 5e6), 100 * m_fracmult); + SetFracDef(8, m_maxHeightInMeters, m_rand.Double(12e5, 22e5), 10 * m_fracmult); + SetFracDef(9, m_maxHeightInMeters, 1e7, 100.0 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = octavenoise(GetFracDef(0), 0.7* - ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel*0.65; + double continents = octavenoise(GetFracDef(0), 0.7 * ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel * 0.65; if (continents < 0) return 0; - double n = (river_function(GetFracDef(9), p)* - river_function(GetFracDef(7), p)* - river_function(GetFracDef(6), p)* - canyon3_normal_function(GetFracDef(1), p)*continents) - - (GetFracDef(0).amplitude*m_sealevel*0.1); + double n = (river_function(GetFracDef(9), p) * + river_function(GetFracDef(7), p) * + river_function(GetFracDef(6), p) * + canyon3_normal_function(GetFracDef(1), p) * continents) - + (GetFracDef(0).amplitude * m_sealevel * 0.1); n *= 0.5; double h = n; @@ -44,8 +44,7 @@ double TerrainHeightFractal::GetHeight(const vecto if (n > 0.0) { // smooth in hills at shore edges //large mountainous shapes - n += h*river_octavenoise(GetFracDef(7), - 0.5*octavenoise(GetFracDef(6), 0.5, p), p); + n += h * river_octavenoise(GetFracDef(7), 0.5 * octavenoise(GetFracDef(6), 0.5, p), p); //if (n < 0.2) n += canyon3_billow_function(GetFracDef(9), p) * n * 5; //else if (n < 0.4) n += canyon3_billow_function(GetFracDef(9), p); @@ -54,46 +53,36 @@ double TerrainHeightFractal::GetHeight(const vecto } if (n > 0.0) { - if (n < 0.4){ - n += n*2.5*river_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.3, 0.7)* - ridged_octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.4) { + n += n * 2.5 * river_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.3, 0.7) * ridged_octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += 1.0*river_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.3, 0.7)* - ridged_octavenoise(GetFracDef(5), 0.5, p), p); + n += 1.0 * river_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.3, 0.7) * ridged_octavenoise(GetFracDef(5), 0.5, p), p); } } if (n > 0.0) { - if (n < 0.2){ - n += n*5.0*billow_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.5, 0.7), p); + if (n < 0.2) { + n += n * 5.0 * billow_octavenoise(GetFracDef(6), Clamp(h * 0.00002, 0.5, 0.7), p); } else { n += billow_octavenoise(GetFracDef(6), - Clamp(h*0.00002, 0.5, 0.7), p); + Clamp(h * 0.00002, 0.5, 0.7), p); } } if (n > 0.0) { - if (n < 0.4){ - n += n*2.0*river_octavenoise(GetFracDef(6), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.4) { + n += n * 2.0 * river_octavenoise(GetFracDef(6), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += (0.32/n)*river_octavenoise(GetFracDef(6), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + n += (0.32 / n) * river_octavenoise(GetFracDef(6), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } - if (n < 0.2){ - n += n*ridged_octavenoise(GetFracDef(5), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + if (n < 0.2) { + n += n * ridged_octavenoise(GetFracDef(5), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } else { - n += (0.04/n)*ridged_octavenoise(GetFracDef(5), - 0.5*octavenoise(GetFracDef(5), 0.5, p), p); + n += (0.04 / n) * ridged_octavenoise(GetFracDef(5), 0.5 * octavenoise(GetFracDef(5), 0.5, p), p); } //smaller ridged mountains - n += n*0.7*ridged_octavenoise(GetFracDef(5), - 0.7*octavenoise(GetFracDef(6), 0.6, p), p); + n += n * 0.7 * ridged_octavenoise(GetFracDef(5), 0.7 * octavenoise(GetFracDef(6), 0.6, p), p); //n += n*0.7*voronoiscam_octavenoise(GetFracDef(5), // 0.7*octavenoise(GetFracDef(6), 0.6, p), p); @@ -102,45 +91,30 @@ double TerrainHeightFractal::GetHeight(const vecto //jagged surface for mountains if (n > 0.25) { - n += (n-0.25)*0.1*octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.6, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.6*octavenoise(GetFracDef(4), 0.6, p)), p); + n += (n - 0.25) * 0.1 * octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.6, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.6 * octavenoise(GetFracDef(4), 0.6, p)), p); } if (n > 0.2 && n <= 0.25) { - n += (0.25-n)*0.2*ridged_octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.5*octavenoise(GetFracDef(4), 0.5, p)), p); + n += (0.25 - n) * 0.2 * ridged_octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.5 * octavenoise(GetFracDef(4), 0.5, p)), p); } else if (n > 0.05) { - n += ((n-0.05)/15)*ridged_octavenoise(GetFracDef(3), - Clamp(h*0.0002*octavenoise(GetFracDef(5), 0.5, p), - 0.5*octavenoise(GetFracDef(3), 0.5, p), - 0.5*octavenoise(GetFracDef(4), 0.5, p)), p); + n += ((n - 0.05) / 15) * ridged_octavenoise(GetFracDef(3), Clamp(h * 0.0002 * octavenoise(GetFracDef(5), 0.5, p), 0.5 * octavenoise(GetFracDef(3), 0.5, p), 0.5 * octavenoise(GetFracDef(4), 0.5, p)), p); } //n = n*0.2; - if (n < 0.01){ - n += n*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); - } else if (n <0.02){ - n += 0.01*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); + if (n < 0.01) { + n += n * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); + } else if (n < 0.02) { + n += 0.01 * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); } else { - n += (0.02/n)*0.01*voronoiscam_octavenoise(GetFracDef(3), - Clamp(h*0.00002, 0.5, 0.5), p); + n += (0.02 / n) * 0.01 * voronoiscam_octavenoise(GetFracDef(3), Clamp(h * 0.00002, 0.5, 0.5), p); } - if (n < 0.001){ - n += n*3*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); - } else if (n <0.01){ - n += 0.003*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); + if (n < 0.001) { + n += n * 3 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); + } else if (n < 0.01) { + n += 0.003 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); } else { - n += (0.01/n)*0.003*dunes_octavenoise(GetFracDef(2), - 1.0*octavenoise(GetFracDef(2), 0.5, p), p); + n += (0.01 / n) * 0.003 * dunes_octavenoise(GetFracDef(2), 1.0 * octavenoise(GetFracDef(2), 0.5, p), p); } //if (n < 0.001){ @@ -154,23 +128,17 @@ double TerrainHeightFractal::GetHeight(const vecto // 0.5*octavenoise(GetFracDef(2), 0.5, p), p); //} - if (n < 0.1){ - n += n*0.05*dunes_octavenoise(GetFracDef(2), - n*river_octavenoise(GetFracDef(2), 0.5, p), p); - } else if (n <0.2){ - n += 0.005*dunes_octavenoise(GetFracDef(2), - ((n*n*10.0)+(3*(n-0.1)))* - river_octavenoise(GetFracDef(2), 0.5, p), p); + if (n < 0.1) { + n += n * 0.05 * dunes_octavenoise(GetFracDef(2), n * river_octavenoise(GetFracDef(2), 0.5, p), p); + } else if (n < 0.2) { + n += 0.005 * dunes_octavenoise(GetFracDef(2), ((n * n * 10.0) + (3 * (n - 0.1))) * river_octavenoise(GetFracDef(2), 0.5, p), p); } else { - n += (0.2/n)*0.005*dunes_octavenoise(GetFracDef(2), - Clamp(0.7-(1-(5*n)), 0.0, 0.7)* - river_octavenoise(GetFracDef(2), 0.5, p), p); + n += (0.2 / n) * 0.005 * dunes_octavenoise(GetFracDef(2), Clamp(0.7 - (1 - (5 * n)), 0.0, 0.7) * river_octavenoise(GetFracDef(2), 0.5, p), p); } n *= 0.3; - } - n = m_maxHeight*n; + n = m_maxHeight * n; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightMountainsRiversVolcano.cpp b/src/terrain/TerrainHeightMountainsRiversVolcano.cpp index 3becc2770..5b8bafc1e 100644 --- a/src/terrain/TerrainHeightMountainsRiversVolcano.cpp +++ b/src/terrain/TerrainHeightMountainsRiversVolcano.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,24 +12,25 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsRiversVolcano"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.6; - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(2, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(3, m_maxHeightInMeters, m_rand.Double(120.0, 2000.0)*m_maxHeightInMeters, 20*m_fracmult); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.6; + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(2, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(3, m_maxHeightInMeters, m_rand.Double(120.0, 2000.0) * m_maxHeightInMeters, 20 * m_fracmult); - height = m_maxHeightInMeters*0.3; - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(5, height, m_rand.Double(2.5,3.5)*height); - SetFracDef(6, height, m_rand.Double(2.5,3.5)*height); + height = m_maxHeightInMeters * 0.3; + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(5, height, m_rand.Double(2.5, 3.5) * height); + SetFracDef(6, height, m_rand.Double(2.5, 3.5) * height); // volcano - SetFracDef(7, 20000.0, 5000000.0, 100.0*m_fracmult); + SetFracDef(7, 20000.0, 5000000.0, 100.0 * m_fracmult); // canyons and rivers - SetFracDef(8, m_maxHeightInMeters*1.0, 4e6, 100.0*m_fracmult); - SetFracDef(9, m_maxHeightInMeters*1.0, 5e6, 100.0*m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 1.0, 4e6, 100.0 * m_fracmult); + SetFracDef(9, m_maxHeightInMeters * 1.0, 5e6, 100.0 * m_fracmult); //SetFracDef(10, m_maxHeightInMeters*0.5, 2e6, 100.0); } @@ -45,121 +46,179 @@ double TerrainHeightFractal::GetHeight(cons double hills = hill_distrib * GetFracDef(5).amplitude * octavenoise(GetFracDef(5), 0.5, p); double hills2 = hill_distrib * GetFracDef(6).amplitude * octavenoise(GetFracDef(6), 0.5, p); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); - - double n = continents - (GetFracDef(0).amplitude*m_sealevel); - - - if (n < 0.01) n += megavolcano_function(GetFracDef(7), p) * n * 800.0f; - else n += megavolcano_function(GetFracDef(7), p) * 8.0f; + if (n < 0.01) + n += megavolcano_function(GetFracDef(7), p) * n * 800.0f; + else + n += megavolcano_function(GetFracDef(7), p) * 8.0f; //n = (n > 0.0 ? n : 0.0); //n = n*.1f; // BEWARE THE WALL OF TEXT - if ((m_seed>>2) %3 > 2) { + if ((m_seed >> 2) % 3 > 2) { - if (n < .2f) n += canyon3_ridged_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_ridged_function(GetFracDef(8), p) * .4; - else n += canyon3_ridged_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_ridged_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_ridged_function(GetFracDef(8), p) * .4; + else + n += canyon3_ridged_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_ridged_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon2_ridged_function(GetFracDef(8), p) * .4; - else n += canyon2_ridged_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_ridged_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon2_ridged_function(GetFracDef(8), p) * .4; + else + n += canyon2_ridged_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon_ridged_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon_ridged_function(GetFracDef(8), p) * .4; - else n += canyon_ridged_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon_ridged_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon_ridged_function(GetFracDef(8), p) * .4; + else + n += canyon_ridged_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon3_ridged_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon3_ridged_function(GetFracDef(9), p) * .4; - else n += canyon3_ridged_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_ridged_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon3_ridged_function(GetFracDef(9), p) * .4; + else + n += canyon3_ridged_function(GetFracDef(9), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_ridged_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon2_ridged_function(GetFracDef(9), p) * .4; - else n += canyon2_ridged_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_ridged_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon2_ridged_function(GetFracDef(9), p) * .4; + else + n += canyon2_ridged_function(GetFracDef(9), p) * (.4 / n) * .4; - if (n < .2f) n += canyon_ridged_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon_ridged_function(GetFracDef(9), p) * .4; - else n += canyon_ridged_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon_ridged_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon_ridged_function(GetFracDef(9), p) * .4; + else + n += canyon_ridged_function(GetFracDef(9), p) * (.4 / n) * .4; - } else if ((m_seed>>2) %3 > 1) { + } else if ((m_seed >> 2) % 3 > 1) { - if (n < .2f) n += canyon3_billow_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_billow_function(GetFracDef(8), p) * .4; - else n += canyon3_billow_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_billow_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_billow_function(GetFracDef(8), p) * .4; + else + n += canyon3_billow_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_billow_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon2_billow_function(GetFracDef(8), p) * .4; - else n += canyon2_billow_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_billow_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon2_billow_function(GetFracDef(8), p) * .4; + else + n += canyon2_billow_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon_billow_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon_billow_function(GetFracDef(8), p) * .4; - else n += canyon_billow_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon_billow_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon_billow_function(GetFracDef(8), p) * .4; + else + n += canyon_billow_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon3_billow_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon3_billow_function(GetFracDef(9), p) * .4; - else n += canyon3_billow_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_billow_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon3_billow_function(GetFracDef(9), p) * .4; + else + n += canyon3_billow_function(GetFracDef(9), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_billow_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon2_billow_function(GetFracDef(9), p) * .4; - else n += canyon2_billow_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_billow_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon2_billow_function(GetFracDef(9), p) * .4; + else + n += canyon2_billow_function(GetFracDef(9), p) * (.4 / n) * .4; - if (n < .2f) n += canyon_billow_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon_billow_function(GetFracDef(9), p) * .4; - else n += canyon_billow_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon_billow_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon_billow_function(GetFracDef(9), p) * .4; + else + n += canyon_billow_function(GetFracDef(9), p) * (.4 / n) * .4; } else { - if (n < .2f) n += canyon3_voronoi_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_voronoi_function(GetFracDef(8), p) * .4; - else n += canyon3_voronoi_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_voronoi_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_voronoi_function(GetFracDef(8), p) * .4; + else + n += canyon3_voronoi_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_voronoi_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon2_voronoi_function(GetFracDef(8), p) * .4; - else n += canyon2_voronoi_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_voronoi_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon2_voronoi_function(GetFracDef(8), p) * .4; + else + n += canyon2_voronoi_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon_voronoi_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon_voronoi_function(GetFracDef(8), p) * .4; - else n += canyon_voronoi_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon_voronoi_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon_voronoi_function(GetFracDef(8), p) * .4; + else + n += canyon_voronoi_function(GetFracDef(8), p) * (.4 / n) * .4; - if (n < .2f) n += canyon3_voronoi_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon3_voronoi_function(GetFracDef(9), p) * .4; - else n += canyon3_voronoi_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_voronoi_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon3_voronoi_function(GetFracDef(9), p) * .4; + else + n += canyon3_voronoi_function(GetFracDef(9), p) * (.4 / n) * .4; - if (n < .2f) n += canyon2_voronoi_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon2_voronoi_function(GetFracDef(9), p) * .4; - else n += canyon2_voronoi_function(GetFracDef(9), p) * (.4/n) * .4; - - if (n < .2f) n += canyon_voronoi_function(GetFracDef(9), p) * n * 2; - else if (n < .4f) n += canyon_voronoi_function(GetFracDef(9), p) * .4; - else n += canyon_voronoi_function(GetFracDef(9), p) * (.4/n) * .4; + if (n < .2f) + n += canyon2_voronoi_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon2_voronoi_function(GetFracDef(9), p) * .4; + else + n += canyon2_voronoi_function(GetFracDef(9), p) * (.4 / n) * .4; + if (n < .2f) + n += canyon_voronoi_function(GetFracDef(9), p) * n * 2; + else if (n < .4f) + n += canyon_voronoi_function(GetFracDef(9), p) * .4; + else + n += canyon_voronoi_function(GetFracDef(9), p) * (.4 / n) * .4; } n += -1.0f; n = (n > 0.0 ? n : 0.0); - n = n*.03f; + n = n * .03f; //n += continents - (GetFracDef(0).amplitude*m_sealevel); if (n > 0.0) { // smooth in hills at shore edges - if (n < 0.1) n += hills * n * 10.0f; - else n += hills; - if (n < 0.05) n += hills2 * n * 20.0f; - else n += hills2 ; + if (n < 0.1) + n += hills * n * 10.0f; + else + n += hills; + if (n < 0.05) + n += hills2 * n * 20.0f; + else + n += hills2; - mountains = octavenoise(GetFracDef(1), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; + mountains = octavenoise(GetFracDef(1), 0.5, p) * + GetFracDef(2).amplitude * mountains * mountains * mountains; mountains2 = octavenoise(GetFracDef(4), 0.5, p) * - GetFracDef(3).amplitude * mountains2*mountains2*mountains2; - if (n > 0.5) n += mountains2 * (n - 0.5) ; - if (n < 0.2) n += mountains * n * 5.0f ; - else n += mountains ; + GetFracDef(3).amplitude * mountains2 * mountains2 * mountains2; + if (n > 0.5) n += mountains2 * (n - 0.5); + if (n < 0.2) + n += mountains * n * 5.0f; + else + n += mountains; } - n = m_maxHeight*n; + n = m_maxHeight * n; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightMountainsVolcano.cpp b/src/terrain/TerrainHeightMountainsVolcano.cpp index 246a81ff5..2e3667547 100644 --- a/src/terrain/TerrainHeightMountainsVolcano.cpp +++ b/src/terrain/TerrainHeightMountainsVolcano.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,23 +12,24 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "MountainsVolcano"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*0.8; - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(2, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(3, height, m_rand.Double(12.0, 200.0)*height); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 0.8; + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(2, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(3, height, m_rand.Double(12.0, 200.0) * height); - height = m_maxHeightInMeters*0.7; - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(5, height, m_rand.Double(2.5,3.5)*height); - SetFracDef(6, height, m_rand.Double(2.5,3.5)*height); + height = m_maxHeightInMeters * 0.7; + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(5, height, m_rand.Double(2.5, 3.5) * height); + SetFracDef(6, height, m_rand.Double(2.5, 3.5) * height); // volcano - SetFracDef(7, 20000.0, 5000000.0, 1000.0*m_fracmult); + SetFracDef(7, 20000.0, 5000000.0, 1000.0 * m_fracmult); // canyons - SetFracDef(8, m_maxHeightInMeters*0.5, 2e6, 100.0*m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 0.5, 2e6, 100.0 * m_fracmult); //SetFracDef(9, m_maxHeightInMeters*0.1, 1.5e6, 100.0*m_fracmult); //SetFracDef(10, m_maxHeightInMeters*0.1, 2e6, 100.0*m_fracmult); } @@ -45,51 +46,65 @@ double TerrainHeightFractal::GetHeight(const vect double hills = hill_distrib * GetFracDef(5).amplitude * octavenoise(GetFracDef(5), 0.5, p); double hills2 = hill_distrib * GetFracDef(6).amplitude * octavenoise(GetFracDef(6), 0.5, p); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); - - double n = continents - (GetFracDef(0).amplitude*m_sealevel); - - - if (n < 0.01) n += megavolcano_function(GetFracDef(7), p) * n * 3000.0f; - else n += megavolcano_function(GetFracDef(7), p) * 30.0f; + if (n < 0.01) + n += megavolcano_function(GetFracDef(7), p) * n * 3000.0f; + else + n += megavolcano_function(GetFracDef(7), p) * 30.0f; n = (n > 0.0 ? n : 0.0); - if ((m_seed>>2)%3 > 2) { - if (n < .2f) n += canyon3_ridged_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_ridged_function(GetFracDef(8), p) * .4; - else n += canyon3_ridged_function(GetFracDef(8), p) * (.4/n) * .4; - } else if ((m_seed>>2)%3 > 1) { - if (n < .2f) n += canyon3_billow_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_billow_function(GetFracDef(8), p) * .4; - else n += canyon3_billow_function(GetFracDef(8), p) * (.4/n) * .4; + if ((m_seed >> 2) % 3 > 2) { + if (n < .2f) + n += canyon3_ridged_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_ridged_function(GetFracDef(8), p) * .4; + else + n += canyon3_ridged_function(GetFracDef(8), p) * (.4 / n) * .4; + } else if ((m_seed >> 2) % 3 > 1) { + if (n < .2f) + n += canyon3_billow_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_billow_function(GetFracDef(8), p) * .4; + else + n += canyon3_billow_function(GetFracDef(8), p) * (.4 / n) * .4; } else { - if (n < .2f) n += canyon3_voronoi_function(GetFracDef(8), p) * n * 2; - else if (n < .4f) n += canyon3_voronoi_function(GetFracDef(8), p) * .4; - else n += canyon3_voronoi_function(GetFracDef(8), p) * (.4/n) * .4; + if (n < .2f) + n += canyon3_voronoi_function(GetFracDef(8), p) * n * 2; + else if (n < .4f) + n += canyon3_voronoi_function(GetFracDef(8), p) * .4; + else + n += canyon3_voronoi_function(GetFracDef(8), p) * (.4 / n) * .4; } n += -0.05f; n = (n > 0.0 ? n : 0.0); - n = n*.01f; + n = n * .01f; if (n > 0.0) { // smooth in hills at shore edges - if (n < 0.01) n += hills * n * 100.0f; - else n += hills; - if (n < 0.02) n += hills2 * n * 50.0f; - else n += hills2 * (0.02f/n); + if (n < 0.01) + n += hills * n * 100.0f; + else + n += hills; + if (n < 0.02) + n += hills2 * n * 50.0f; + else + n += hills2 * (0.02f / n); - mountains = octavenoise(GetFracDef(1), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; + mountains = octavenoise(GetFracDef(1), 0.5, p) * + GetFracDef(2).amplitude * mountains * mountains * mountains; mountains2 = octavenoise(GetFracDef(4), 0.5, p) * - GetFracDef(3).amplitude * mountains2*mountains2*mountains2; + GetFracDef(3).amplitude * mountains2 * mountains2 * mountains2; if (n > 2.5) n += mountains2 * (n - 2.5) * 0.6f; - if (n < 0.01) n += mountains * n * 60.0f ; - else n += mountains * 0.6f ; + if (n < 0.01) + n += mountains * n * 60.0f; + else + n += mountains * 0.6f; } - n = m_maxHeight*n; + n = m_maxHeight * n; return (n > 0.0 ? n : 0.0); } diff --git a/src/terrain/TerrainHeightRuggedDesert.cpp b/src/terrain/TerrainHeightRuggedDesert.cpp index 5901415a2..05bcd6e79 100644 --- a/src/terrain/TerrainHeightRuggedDesert.cpp +++ b/src/terrain/TerrainHeightRuggedDesert.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -14,7 +14,7 @@ const char *TerrainHeightFractal::GetHeightFractalNam template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = octavenoise(GetFracDef(0), 0.5, p) - m_sealevel;// + (cliff_function(GetFracDef(7), p)*0.5); + double continents = octavenoise(GetFracDef(0), 0.5, p) - m_sealevel; // + (cliff_function(GetFracDef(7), p)*0.5); if (continents < 0) return 0; double mountain_distrib = octavenoise(GetFracDef(2), 0.5, p); double mountains = ridged_octavenoise(GetFracDef(1), 0.5, p); @@ -22,45 +22,52 @@ double TerrainHeightFractal::GetHeight(const vector3d double hill_distrib = octavenoise(GetFracDef(4), 0.5, p); double hills = hill_distrib * GetFracDef(3).amplitude * billow_octavenoise(GetFracDef(3), 0.5, p); double dunes = hill_distrib * GetFracDef(5).amplitude * dunes_octavenoise(GetFracDef(5), 0.5, p); - double n = continents * GetFracDef(0).amplitude * 2 ;//+ (cliff_function(GetFracDef(6), p)*0.5); - n += (n<0.0 ? 0.0 : n); + double n = continents * GetFracDef(0).amplitude * 2; //+ (cliff_function(GetFracDef(6), p)*0.5); + n += (n < 0.0 ? 0.0 : n); // makes larger dunes at lower altitudes, flat ones at high altitude. - mountains = mountain_distrib * GetFracDef(3).amplitude * mountains*mountains*mountains; + mountains = mountain_distrib * GetFracDef(3).amplitude * mountains * mountains * mountains; // smoothes edges of mountains and places them only above a set altitude - if (n < 0.1) n += n * 10.0f * hills; - else n += hills; - if (n > 0.2) n += dunes * (0.2/n); - else n += dunes; - if (n < 0.1) n += n * 10.0f * mountains; - else n += mountains; + if (n < 0.1) + n += n * 10.0f * hills; + else + n += hills; + if (n > 0.2) + n += dunes * (0.2 / n); + else + n += dunes; + if (n < 0.1) + n += n * 10.0f * mountains; + else + n += mountains; //rocks = mountain_distrib * GetFracDef(9).amplitude * rocks*rocks*rocks; //n += rocks ; - return (n > 0.0? m_maxHeight*n : 0.0); + return (n > 0.0 ? m_maxHeight * n : 0.0); } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, 0.1*m_maxHeightInMeters, 2e6, 180e3*m_fracmult); - double height = m_maxHeightInMeters*0.9; - SetFracDef(1, height, m_rand.Double(120.0, 10000.0)*height, 100*m_fracmult); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(1.0, 2.0)*m_maxHeightInMeters); + SetFracDef(0, 0.1 * m_maxHeightInMeters, 2e6, 180e3 * m_fracmult); + double height = m_maxHeightInMeters * 0.9; + SetFracDef(1, height, m_rand.Double(120.0, 10000.0) * height, 100 * m_fracmult); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(1.0, 2.0) * m_maxHeightInMeters); - height = m_maxHeightInMeters*0.3; - SetFracDef(3, height, m_rand.Double(20.0,240.0)*height); - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(1.0, 2.0)*m_maxHeightInMeters); + height = m_maxHeightInMeters * 0.3; + SetFracDef(3, height, m_rand.Double(20.0, 240.0) * height); + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(1.0, 2.0) * m_maxHeightInMeters); // dunes - height = m_maxHeightInMeters*0.2; - SetFracDef(5, height*0.1, m_rand.Double(5,75)*height, 10000.0*m_fracmult); + height = m_maxHeightInMeters * 0.2; + SetFracDef(5, height * 0.1, m_rand.Double(5, 75) * height, 10000.0 * m_fracmult); // canyon - SetFracDef(6, m_maxHeightInMeters*0.2, 1e6, 200.0*m_fracmult); - SetFracDef(7, m_maxHeightInMeters*0.35, 1.5e6, 100.0*m_fracmult); - SetFracDef(8, m_maxHeightInMeters*0.2, 3e6, 100.0*m_fracmult); + SetFracDef(6, m_maxHeightInMeters * 0.2, 1e6, 200.0 * m_fracmult); + SetFracDef(7, m_maxHeightInMeters * 0.35, 1.5e6, 100.0 * m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 0.2, 3e6, 100.0 * m_fracmult); //SetFracDef(9, m_maxHeightInMeters*0.1, 100, 10.0); // adds bumps to the landscape - SetFracDef(9, height*0.0025, m_rand.Double(1,100), 100.0*m_fracmult); + SetFracDef(9, height * 0.0025, m_rand.Double(1, 100), 100.0 * m_fracmult); } diff --git a/src/terrain/TerrainHeightRuggedLava.cpp b/src/terrain/TerrainHeightRuggedLava.cpp index e2aabda78..3b574b252 100644 --- a/src/terrain/TerrainHeightRuggedLava.cpp +++ b/src/terrain/TerrainHeightRuggedLava.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,32 +12,33 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "RuggedLava"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6,1e7)); - double height = m_maxHeightInMeters*1.0; - SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0)*m_maxHeightInMeters); - SetFracDef(2, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(3, height, m_rand.Double(12.0, 200.0)*height); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(1e6, 1e7)); + double height = m_maxHeightInMeters * 1.0; + SetFracDef(1, m_maxHeightInMeters, m_rand.Double(50.0, 100.0) * m_maxHeightInMeters); + SetFracDef(2, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(3, height, m_rand.Double(12.0, 200.0) * height); - height = m_maxHeightInMeters*0.3; - SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0)*m_maxHeightInMeters); - SetFracDef(5, height, m_rand.Double(2.5,3.5)*height); + height = m_maxHeightInMeters * 0.3; + SetFracDef(4, m_maxHeightInMeters, m_rand.Double(100.0, 200.0) * m_maxHeightInMeters); + SetFracDef(5, height, m_rand.Double(2.5, 3.5) * height); // volcanoes - SetFracDef(6, height, 6e6, 100000.0*m_fracmult); - SetFracDef(7, height, 3e6, 1000.0*m_fracmult); + SetFracDef(6, height, 6e6, 100000.0 * m_fracmult); + SetFracDef(7, height, 3e6, 1000.0 * m_fracmult); // canyon - SetFracDef(8, m_maxHeightInMeters*0.4, 4e6, 100.0*m_fracmult); + SetFracDef(8, m_maxHeightInMeters * 0.4, 4e6, 100.0 * m_fracmult); // bumps/rocks - SetFracDef(9, height*0.001, m_rand.Double(10,100), 2.0*m_fracmult); + SetFracDef(9, height * 0.001, m_rand.Double(10, 100), 2.0 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = octavenoise(GetFracDef(0), Clamp(0.725-(m_sealevel/2), 0.1, 0.725), p) - m_sealevel; + double continents = octavenoise(GetFracDef(0), Clamp(0.725 - (m_sealevel / 2), 0.1, 0.725), p) - m_sealevel; if (continents < 0) return 0; double mountain_distrib = octavenoise(GetFracDef(1), 0.55, p); double mountains = octavenoise(GetFracDef(2), 0.5, p) * ridged_octavenoise(GetFracDef(2), 0.575, p); @@ -46,49 +47,53 @@ double TerrainHeightFractal::GetHeight(const vector3d & double hills = hill_distrib * GetFracDef(5).amplitude * octavenoise(GetFracDef(5), 0.5, p); double rocks = octavenoise(GetFracDef(9), 0.5, p); - - double n = continents - (GetFracDef(0).amplitude*m_sealevel); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); //double n = (megavolcano_function(p) + volcano_function(p) + smlvolcano_function(p)); - n += mountains*mountains2*5.0*megavolcano_function(GetFracDef(6), p); - n += 2.5*megavolcano_function(GetFracDef(6), p); - n += mountains*mountains2*5.0*volcano_function(GetFracDef(6), p)*volcano_function(GetFracDef(6), p); - n += 2.5*volcano_function(GetFracDef(6), p); - - n += mountains*mountains2*7.5*megavolcano_function(GetFracDef(7), p); - n += 2.5*megavolcano_function(GetFracDef(7), p); - n += mountains*mountains2*7.5*volcano_function(GetFracDef(7), p)*volcano_function(GetFracDef(7), p); - n += 2.5*volcano_function(GetFracDef(7), p); + n += mountains * mountains2 * 5.0 * megavolcano_function(GetFracDef(6), p); + n += 2.5 * megavolcano_function(GetFracDef(6), p); + n += mountains * mountains2 * 5.0 * volcano_function(GetFracDef(6), p) * volcano_function(GetFracDef(6), p); + n += 2.5 * volcano_function(GetFracDef(6), p); + n += mountains * mountains2 * 7.5 * megavolcano_function(GetFracDef(7), p); + n += 2.5 * megavolcano_function(GetFracDef(7), p); + n += mountains * mountains2 * 7.5 * volcano_function(GetFracDef(7), p) * volcano_function(GetFracDef(7), p); + n += 2.5 * volcano_function(GetFracDef(7), p); //n += 1.4*(continents - targ.continents.amplitude*targ.sealevel + (volcano_function(p)*1)) ; //smooth canyon transitions and limit height of canyon placement - if (n < .01) n += n * 100.0f * canyon3_ridged_function(GetFracDef(8), p); - else n += canyon3_ridged_function(GetFracDef(8), p); + if (n < .01) + n += n * 100.0f * canyon3_ridged_function(GetFracDef(8), p); + else + n += canyon3_ridged_function(GetFracDef(8), p); - if (n < .01) n += n * 100.0f * canyon2_ridged_function(GetFracDef(8), p); - else n += canyon2_ridged_function(GetFracDef(8), p); + if (n < .01) + n += n * 100.0f * canyon2_ridged_function(GetFracDef(8), p); + else + n += canyon2_ridged_function(GetFracDef(8), p); n *= 0.5; - n += continents*hills*hill_distrib*mountain_distrib; + n += continents * hills * hill_distrib * mountain_distrib; - mountains = octavenoise(GetFracDef(1), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; + mountains = octavenoise(GetFracDef(1), 0.5, p) * + GetFracDef(2).amplitude * mountains * mountains * mountains; mountains2 = octavenoise(GetFracDef(4), 0.5, p) * - GetFracDef(3).amplitude * mountains2*mountains2*mountains2; + GetFracDef(3).amplitude * mountains2 * mountains2 * mountains2; /*mountains = fractal(2, targ.mountainDistrib, (m_seed>>2)&3, p) * targ.mountains.amplitude * mountains*mountains*mountains; mountains2 = fractal(24, targ.mountainDistrib, (m_seed>>2)&3, p) * targ.mountains.amplitude * mountains*mountains*mountains;*/ - n += continents*mountains*hill_distrib ; - if (n < 0.01) n += continents*mountains2 * n * 40.0f ; - else n += continents*mountains2*.4f ; + n += continents * mountains * hill_distrib; + if (n < 0.01) + n += continents * mountains2 * n * 40.0f; + else + n += continents * mountains2 * .4f; n *= 0.2; - n += mountains*mountains2*mountains2*hills*hills*hill_distrib*mountain_distrib*20.0; + n += mountains * mountains2 * mountains2 * hills * hills * hill_distrib * mountain_distrib * 20.0; - rocks = continents * mountain_distrib * GetFracDef(9).amplitude * rocks*rocks*rocks * 2.0; + rocks = continents * mountain_distrib * GetFracDef(9).amplitude * rocks * rocks * rocks * 2.0; n += rocks; - n = (n<0.0 ? 0.0 : m_maxHeight*n); + n = (n < 0.0 ? 0.0 : m_maxHeight * n); return n; } diff --git a/src/terrain/TerrainHeightWaterSolid.cpp b/src/terrain/TerrainHeightWaterSolid.cpp index 2f9a131c3..3194459df 100644 --- a/src/terrain/TerrainHeightWaterSolid.cpp +++ b/src/terrain/TerrainHeightWaterSolid.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,59 +12,53 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "WaterSolid"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5e6,1e8)); - double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(200.0, 1000.0)*m_maxHeightInMeters); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5e6, 1e8)); + double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(200.0, 1000.0) * m_maxHeightInMeters); // mountains with some canyons - SetFracDef(3, m_maxHeightInMeters*0.4, 4e6); - SetFracDef(4, m_maxHeightInMeters*0.4, 5e6); + SetFracDef(3, m_maxHeightInMeters * 0.4, 4e6); + SetFracDef(4, m_maxHeightInMeters * 0.4, 5e6); //crater - SetFracDef(5, m_maxHeightInMeters*0.4, 1.5e7, 50000.0*m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.4, 1.5e7, 50000.0 * m_fracmult); } template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = 0.7*river_octavenoise(GetFracDef(2), 0.5, p)-m_sealevel; - continents = GetFracDef(0).amplitude * ridged_octavenoise(GetFracDef(0), - Clamp(continents, 0.0, 0.6), p); + double continents = 0.7 * river_octavenoise(GetFracDef(2), 0.5, p) - m_sealevel; + continents = GetFracDef(0).amplitude * ridged_octavenoise(GetFracDef(0), Clamp(continents, 0.0, 0.6), p); double mountains = ridged_octavenoise(GetFracDef(2), 0.5, p); double hills = octavenoise(GetFracDef(2), 0.5, p) * GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5, p); - double n = continents - (GetFracDef(0).amplitude*m_sealevel); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); // craters n += crater_function(GetFracDef(5), p); if (n > 0.0) { // smooth in hills at shore edges if (n < 0.05) { - n += hills * n * 4.0 ; - n += n * 20.0 * (billow_octavenoise(GetFracDef(3), 0.5* - ridged_octavenoise(GetFracDef(2), 0.5, p), p) + - river_octavenoise(GetFracDef(4), 0.5* - ridged_octavenoise(GetFracDef(3), 0.5, p), p) + - billow_octavenoise(GetFracDef(3), 0.6* - ridged_octavenoise(GetFracDef(4), 0.55, p), p)); + n += hills * n * 4.0; + n += n * 20.0 * (billow_octavenoise(GetFracDef(3), 0.5 * ridged_octavenoise(GetFracDef(2), 0.5, p), p) + river_octavenoise(GetFracDef(4), 0.5 * ridged_octavenoise(GetFracDef(3), 0.5, p), p) + billow_octavenoise(GetFracDef(3), 0.6 * ridged_octavenoise(GetFracDef(4), 0.55, p), p)); } else { - n += hills * .2f ; - n += billow_octavenoise(GetFracDef(3), 0.5* - ridged_octavenoise(GetFracDef(2), 0.5, p), p) + - river_octavenoise(GetFracDef(4), 0.5* - ridged_octavenoise(GetFracDef(3), 0.5, p), p) + - billow_octavenoise(GetFracDef(3), 0.6* - ridged_octavenoise(GetFracDef(4), 0.55, p), p); + n += hills * .2f; + n += billow_octavenoise(GetFracDef(3), 0.5 * ridged_octavenoise(GetFracDef(2), 0.5, p), p) + + river_octavenoise(GetFracDef(4), 0.5 * ridged_octavenoise(GetFracDef(3), 0.5, p), p) + + billow_octavenoise(GetFracDef(3), 0.6 * ridged_octavenoise(GetFracDef(4), 0.55, p), p); } // adds mountains hills craters mountains = octavenoise(GetFracDef(3), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; - if (n < 0.4) n += 2.0 * n * mountains; - else n += mountains * .8f; + GetFracDef(2).amplitude * mountains * mountains * mountains; + if (n < 0.4) + n += 2.0 * n * mountains; + else + n += mountains * .8f; } - n = m_maxHeight*n; - n = (n<0.0 ? -n : n); - n = (n>1.0 ? 2.0-n : n); + n = m_maxHeight * n; + n = (n < 0.0 ? -n : n); + n = (n > 1.0 ? 2.0 - n : n); return n; } diff --git a/src/terrain/TerrainHeightWaterSolidCanyons.cpp b/src/terrain/TerrainHeightWaterSolidCanyons.cpp index 87d75ce7f..eed5ae08b 100644 --- a/src/terrain/TerrainHeightWaterSolidCanyons.cpp +++ b/src/terrain/TerrainHeightWaterSolidCanyons.cpp @@ -2,8 +2,8 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Terrain.h" -#include "TerrainNoise.h" #include "TerrainFeature.h" +#include "TerrainNoise.h" using namespace TerrainNoise; using namespace TerrainFeature; @@ -12,18 +12,19 @@ template <> const char *TerrainHeightFractal::GetHeightFractalName() const { return "WaterSolidCanyons"; } template <> -TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : Terrain(body) +TerrainHeightFractal::TerrainHeightFractal(const SystemBody *body) : + Terrain(body) { - SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5e6,1e8)); - double height = m_maxHeightInMeters*0.3; - SetFracDef(1, height, m_rand.Double(4.0, 20.0)*height); - SetFracDef(2, m_maxHeightInMeters, m_rand.Double(200.0, 1000.0)*m_maxHeightInMeters); + SetFracDef(0, m_maxHeightInMeters, m_rand.Double(5e6, 1e8)); + double height = m_maxHeightInMeters * 0.3; + SetFracDef(1, height, m_rand.Double(4.0, 20.0) * height); + SetFracDef(2, m_maxHeightInMeters, m_rand.Double(200.0, 1000.0) * m_maxHeightInMeters); // mountains with some canyons - SetFracDef(3, m_maxHeightInMeters*0.4, 4e6); - SetFracDef(4, m_maxHeightInMeters*0.4, 5e6); + SetFracDef(3, m_maxHeightInMeters * 0.4, 4e6); + SetFracDef(4, m_maxHeightInMeters * 0.4, 5e6); //crater - SetFracDef(5, m_maxHeightInMeters*0.4, 15e6, 50000.0*m_fracmult); + SetFracDef(5, m_maxHeightInMeters * 0.4, 15e6, 50000.0 * m_fracmult); //canyons //SetFracDef(6, m_maxHeightInMeters*0.4, 12e6, 50000.0); //SetFracDef(7, m_maxHeightInMeters*0.4, 9e6, 50000.0); @@ -32,42 +33,35 @@ TerrainHeightFractal::TerrainHeightFractal(const template <> double TerrainHeightFractal::GetHeight(const vector3d &p) const { - double continents = 0.7*river_octavenoise(GetFracDef(2), 0.5, p)-m_sealevel; - continents = GetFracDef(0).amplitude * ridged_octavenoise(GetFracDef(0), - Clamp(continents, 0.0, 0.6), p); + double continents = 0.7 * river_octavenoise(GetFracDef(2), 0.5, p) - m_sealevel; + continents = GetFracDef(0).amplitude * ridged_octavenoise(GetFracDef(0), Clamp(continents, 0.0, 0.6), p); double mountains = ridged_octavenoise(GetFracDef(2), 0.5, p); double hills = octavenoise(GetFracDef(2), 0.5, p) * GetFracDef(1).amplitude * river_octavenoise(GetFracDef(1), 0.5, p); - double n = continents - (GetFracDef(0).amplitude*m_sealevel); + double n = continents - (GetFracDef(0).amplitude * m_sealevel); if (n > 0.0) { // smooth in hills at shore edges if (n < 0.05) { - n += hills * n * 4.0 ; - n += n * 20.0 * (billow_octavenoise(GetFracDef(3), 0.5* - ridged_octavenoise(GetFracDef(2), 0.5, p), p) + - river_octavenoise(GetFracDef(4), 0.5* - ridged_octavenoise(GetFracDef(3), 0.5, p), p) + - billow_octavenoise(GetFracDef(3), 0.6* - ridged_octavenoise(GetFracDef(4), 0.55, p), p)); + n += hills * n * 4.0; + n += n * 20.0 * (billow_octavenoise(GetFracDef(3), 0.5 * ridged_octavenoise(GetFracDef(2), 0.5, p), p) + river_octavenoise(GetFracDef(4), 0.5 * ridged_octavenoise(GetFracDef(3), 0.5, p), p) + billow_octavenoise(GetFracDef(3), 0.6 * ridged_octavenoise(GetFracDef(4), 0.55, p), p)); } else { - n += hills * .2f ; - n += billow_octavenoise(GetFracDef(3), 0.5* - ridged_octavenoise(GetFracDef(2), 0.5, p), p) + - river_octavenoise(GetFracDef(4), 0.5* - ridged_octavenoise(GetFracDef(3), 0.5, p), p) + - billow_octavenoise(GetFracDef(3), 0.6* - ridged_octavenoise(GetFracDef(4), 0.55, p), p); + n += hills * .2f; + n += billow_octavenoise(GetFracDef(3), 0.5 * ridged_octavenoise(GetFracDef(2), 0.5, p), p) + + river_octavenoise(GetFracDef(4), 0.5 * ridged_octavenoise(GetFracDef(3), 0.5, p), p) + + billow_octavenoise(GetFracDef(3), 0.6 * ridged_octavenoise(GetFracDef(4), 0.55, p), p); } // adds mountains hills craters mountains = octavenoise(GetFracDef(3), 0.5, p) * - GetFracDef(2).amplitude * mountains*mountains*mountains; - if (n < 0.4) n += 2.0 * n * mountains; - else n += mountains * .8f; + GetFracDef(2).amplitude * mountains * mountains * mountains; + if (n < 0.4) + n += 2.0 * n * mountains; + else + n += mountains * .8f; } // craters - n += 3.0*impact_crater_function(GetFracDef(5), p); - n = m_maxHeight*n; - n = (n<0.0 ? 0 : n); - n = (n>1.0 ? 2.0-n : n); + n += 3.0 * impact_crater_function(GetFracDef(5), p); + n = m_maxHeight * n; + n = (n < 0.0 ? 0 : n); + n = (n > 1.0 ? 2.0 - n : n); return n; } diff --git a/src/terrain/TerrainNoise.h b/src/terrain/TerrainNoise.h index 3dabb1203..6c554cac4 100644 --- a/src/terrain/TerrainNoise.h +++ b/src/terrain/TerrainNoise.h @@ -10,39 +10,42 @@ namespace TerrainNoise { // octavenoise functions return range [0,1] if persistence = 0.5 - inline double octavenoise(const fracdef_t &def, const double persistence, const vector3d &p) { + inline double octavenoise(const fracdef_t &def, const double persistence, const vector3d &p) + { //assert(persistence <= (1.0 / def.lacunarity)); double n = 0; double amplitude = persistence; double frequency = def.frequency; - for (int i=0; i #include #include -#include using namespace Time; -static void check_datetime_round_trip(int year, int month, int day, int hour, int minute, int second, bool emit_message) { +static void check_datetime_round_trip(int year, int month, int day, int hour, int minute, int second, bool emit_message) +{ const DateTime t(year, month, day, hour, minute, second); int year2, month2, day2, hour2, minute2, second2; t.GetDateParts(&year2, &month2, &day2); @@ -27,37 +28,38 @@ static void check_datetime_round_trip(int year, int month, int day, int hour, in } static const int CHECK_AROUND_TIMES[][6] = { - {1600,1,1, 6,0,0}, - {1601,1,1, 6,0,0}, + { 1600, 1, 1, 6, 0, 0 }, + { 1601, 1, 1, 6, 0, 0 }, - {2000,2,28, 23,59,59}, - {2000,2,29, 0,0,0}, - {2000,2,29, 0,0,1}, + { 2000, 2, 28, 23, 59, 59 }, + { 2000, 2, 29, 0, 0, 0 }, + { 2000, 2, 29, 0, 0, 1 }, - {2000,2,29, 12,0,0}, - {2004,2,29, 12,0,0}, - {2008,2,29, 12,0,0}, + { 2000, 2, 29, 12, 0, 0 }, + { 2004, 2, 29, 12, 0, 0 }, + { 2008, 2, 29, 12, 0, 0 }, - {2100,2,28, 23,59,59}, - {2100,3,1, 0,0,0}, - {2100,3,1, 0,0,1}, + { 2100, 2, 28, 23, 59, 59 }, + { 2100, 3, 1, 0, 0, 0 }, + { 2100, 3, 1, 0, 0, 1 }, - {1999,12,31, 23,59,59}, - {2000,1,1, 0,0,0}, - {2000,1,1, 0,0,1}, + { 1999, 12, 31, 23, 59, 59 }, + { 2000, 1, 1, 0, 0, 0 }, + { 2000, 1, 1, 0, 0, 1 }, - {2000,12,31, 23,59,59}, - {2001,1,1, 0,0,0}, - {2001,1,1, 0,0,1}, + { 2000, 12, 31, 23, 59, 59 }, + { 2001, 1, 1, 0, 0, 0 }, + { 2001, 1, 1, 0, 0, 1 }, - {3200,1,1, 0,0,0}, - {3200,2,28, 0,0,0}, - {3200,2,29, 0,0,0}, + { 3200, 1, 1, 0, 0, 0 }, + { 3200, 2, 28, 0, 0, 0 }, + { 3200, 2, 29, 0, 0, 0 }, - {-1,-1,-1,-1,-1,-1} + { -1, -1, -1, -1, -1, -1 } }; -static void check_datetime_round_trip_2(Sint64 timestamp) { +static void check_datetime_round_trip_2(Sint64 timestamp) +{ const DateTime t = DateTime() + TimeDelta(timestamp, TimeUnit(1)); int year, month, day, hour, minute, second; @@ -67,7 +69,8 @@ static void check_datetime_round_trip_2(Sint64 timestamp) { check_datetime_round_trip(year, month, day, hour, minute, second, false); } -void test_datetime() { +void test_datetime() +{ const Time::DateTime EPOCH; std::cout << "Microsecond: " << std::setw(12) << Sint64(Time::Microsecond) << "\n"; @@ -92,10 +95,10 @@ void test_datetime() { for (int i = 0; CHECK_AROUND_TIMES[i][3] != -1; ++i) { const int *x = CHECK_AROUND_TIMES[i]; - check_datetime_round_trip(x[0],x[1],x[2], x[3],x[4],x[5], true); + check_datetime_round_trip(x[0], x[1], x[2], x[3], x[4], x[5], true); } - Time::DateTime t = DateTime(1600,1,1, 0,0,0); + Time::DateTime t = DateTime(1600, 1, 1, 0, 0, 0); std::cout << "Checking round trips for *many* timestamps...\n"; std::cout << " beginning at " << t.ToDateString() << " " << t.ToTimeString() << "\n"; std::cout << " (checking round-trip every 6 hours)\n"; diff --git a/src/test_FileSystem.cpp b/src/test_FileSystem.cpp index 890d39b92..7901b8357 100644 --- a/src/test_FileSystem.cpp +++ b/src/test_FileSystem.cpp @@ -1,17 +1,23 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "FileSystem.h" #include "FileSourceZip.h" +#include "FileSystem.h" #include "utils.h" #include #include -static const char *ftype_name(const FileSystem::FileInfo &info) { - if (info.IsDir()) { return "directory"; } - else if (info.IsFile()) { return "file"; } - else if (info.IsSpecial()) { return "special"; } - else { return "non-existent"; } +static const char *ftype_name(const FileSystem::FileInfo &info) +{ + if (info.IsDir()) { + return "directory"; + } else if (info.IsFile()) { + return "file"; + } else if (info.IsSpecial()) { + return "special"; + } else { + return "non-existent"; + } } void test_normpath() diff --git a/src/test_Frame.cpp b/src/test_Frame.cpp index 5a4824a1c..4cec3c6d4 100644 --- a/src/test_Frame.cpp +++ b/src/test_Frame.cpp @@ -1,12 +1,12 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Pi.h" #include "Frame.h" +#include "Pi.h" #include "Space.h" #if 0 -#define CRAP 0.00001 +#define CRAP 0.00001 static void test(vector3d a, vector3d b) { vector3d c = a-b; @@ -83,5 +83,6 @@ void test_frames() } #endif -void test_frames() { +void test_frames() +{ } diff --git a/src/test_Random.cpp b/src/test_Random.cpp index 010777716..c356b9357 100644 --- a/src/test_Random.cpp +++ b/src/test_Random.cpp @@ -1,25 +1,26 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include -#include #include "Random.h" +#include +#include using namespace std; // Test suite for random number generator -void test_random() { +void test_random() +{ // The deterministic pseudo-random sequence generator // must produce the same numbers on all platforms. - const Uint32 in32[] = {1, 56789, 71, 63, 0xbadf00d}; - const Uint32 in32out32[] = {103039557, 3621827031, 1026123746, 2947867049, 4032124254}; - const double in32outDbl[] = {0.0297203, 0.313619, 0.888806, 0.717738, 0.0670876}; + const Uint32 in32[] = { 1, 56789, 71, 63, 0xbadf00d }; + const Uint32 in32out32[] = { 103039557, 3621827031, 1026123746, 2947867049, 4032124254 }; + const double in32outDbl[] = { 0.0297203, 0.313619, 0.888806, 0.717738, 0.0670876 }; - const Uint64 in64[] = {0xdeadbeefbadf000d, 23976134785912, 1, 2, 1}; - const Uint32 in64out32[] = {3697722658, 2452550324, 2683066595, 3947765649, 1497178833}; - const double in64outDbl[] = {0.560166, 0.684969, 0.318901, 0.699317, 0.277869}; + const Uint64 in64[] = { 0xdeadbeefbadf000d, 23976134785912, 1, 2, 1 }; + const Uint32 in64out32[] = { 3697722658, 2452550324, 2683066595, 3947765649, 1497178833 }; + const double in64outDbl[] = { 0.560166, 0.684969, 0.318901, 0.699317, 0.277869 }; cout << "--------------------" << endl; cout << "Running random tests" << endl; @@ -29,19 +30,23 @@ void test_random() { Random rnd(in32, 5); cout << "32-bit seeds, Uint32 out: " << endl; - for (int i=0; i<5; ++i) cout << i+1 << ": " << (rnd.Int32() - in32out32[i] == 0 ? "pass" : "fail") << endl; + for (int i = 0; i < 5; ++i) + cout << i + 1 << ": " << (rnd.Int32() - in32out32[i] == 0 ? "pass" : "fail") << endl; cout << "32-bit seeds, Double out: " << endl; - for (int i=0; i<5; ++i) cout << i+1 << ": " << (fabs(rnd.Double() - in32outDbl[i]) < 0.000001 ? "pass" : "fail") << endl; // close enough + for (int i = 0; i < 5; ++i) + cout << i + 1 << ": " << (fabs(rnd.Double() - in32outDbl[i]) < 0.000001 ? "pass" : "fail") << endl; // close enough // now seed with 64-bit numbers rnd.seed(in64, 5); cout << "64-bit seeds, Uint32 out: " << endl; - for (int i=0; i<5; ++i) cout << i+1 << ": " << (rnd.Int32() - in64out32[i] == 0 ? "pass" : "fail") << endl; + for (int i = 0; i < 5; ++i) + cout << i + 1 << ": " << (rnd.Int32() - in64out32[i] == 0 ? "pass" : "fail") << endl; cout << "64-bit seeds, Double out: " << endl; - for (int i=0; i<5; ++i) cout << i+1 << ": " << (fabs(rnd.Double() - in64outDbl[i]) < 0.000001 ? "pass" : "fail") << endl; // close enough + for (int i = 0; i < 5; ++i) + cout << i + 1 << ": " << (fabs(rnd.Double() - in64outDbl[i]) < 0.000001 ? "pass" : "fail") << endl; // close enough cout << "--------------------" << endl; cout << "End of random tests." << endl; diff --git a/src/test_StringF.cpp b/src/test_StringF.cpp index 2a48603be..dd4abbc0b 100644 --- a/src/test_StringF.cpp +++ b/src/test_StringF.cpp @@ -2,15 +2,16 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "StringF.h" -#include -#include -#include #include #include +#include +#include +#include static int verbose = 2; -static void check(int line, const char* format, const char* expected, const std::string& result) { +static void check(int line, const char *format, const char *expected, const std::string &result) +{ if (result == std::string(expected)) { if (verbose >= 2) printf("[line %5d] OK ('%s' -> '%s')\n", line, format, result.c_str()); @@ -34,13 +35,14 @@ static char tmpbuf[512]; #define TEST4(format, arg0, arg1, arg2, arg3, expected) \ check(__LINE__, (format), (expected), stringf((format), (arg0), (arg1), (arg2), (arg3))) -#define TESTPF1(format, arg0, pfformat) \ - do { \ - snprintf(tmpbuf, sizeof(tmpbuf), (pfformat), (arg0)); \ +#define TESTPF1(format, arg0, pfformat) \ + do { \ + snprintf(tmpbuf, sizeof(tmpbuf), (pfformat), (arg0)); \ check(__LINE__, (format), tmpbuf, stringf((format), (arg0))); \ } while (0) -void test_stringf() { +void test_stringf() +{ TEST0("", ""); TEST0("Hello.", "Hello."); diff --git a/src/text/DistanceFieldFont.cpp b/src/text/DistanceFieldFont.cpp index 884850642..4ca688639 100644 --- a/src/text/DistanceFieldFont.cpp +++ b/src/text/DistanceFieldFont.cpp @@ -2,145 +2,145 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "DistanceFieldFont.h" +#include "FileSystem.h" +#include "StringRange.h" #include "graphics/Texture.h" #include "graphics/VertexArray.h" #include "utils.h" -#include "FileSystem.h" -#include "StringRange.h" -#include #include +#include namespace Text { -DistanceFieldFont::DistanceFieldFont(const std::string &definition, Graphics::Texture *tex) -: m_texture(tex) -, m_sheetSize(0.f) -, m_fontSize(0.f) -{ - //parse definition - RefCountedPtr fontdef = FileSystem::gameDataFiles.ReadFile(definition); - StringRange data = fontdef->AsStringRange(); + DistanceFieldFont::DistanceFieldFont(const std::string &definition, Graphics::Texture *tex) : + m_texture(tex), + m_sheetSize(0.f), + m_fontSize(0.f) + { + //parse definition + RefCountedPtr fontdef = FileSystem::gameDataFiles.ReadFile(definition); + StringRange data = fontdef->AsStringRange(); - bool doingCharacters = false; + bool doingCharacters = false; - while (!data.Empty()) { - const StringRange line = data.ReadLine(); - if (line.Empty()) continue; + while (!data.Empty()) { + const StringRange line = data.ReadLine(); + if (line.Empty()) continue; - if (doingCharacters) { - ParseChar(line); - } else { - if (starts_with(line.begin, "info")) //contains font size - ParseInfo(line); - else if (starts_with(line.begin, "common ")) //contains UV sheet w/h - ParseCommon(line); - else if (starts_with(line.begin, "chars ")) //after this, file should be all characters - doingCharacters = true; - } - } -} - -void DistanceFieldFont::GetGeometry(Graphics::VertexArray &va, const std::string &text, const vector2f &offset) -{ - assert(va.HasAttrib(Graphics::ATTRIB_NORMAL) && va.HasAttrib(Graphics::ATTRIB_UV0)); - assert(!text.empty()); - - //add glyphs, initial cursor pos is where first glyph's lower left will be - vector2f cursor = offset; - vector2f bounds(0.f); - for(unsigned int i=0; i::const_iterator it = m_glyphs.find(chr); - if (it != m_glyphs.end()) { - const Glyph &glyph = it->second; - AddGlyph(va, cursor + glyph.offset, glyph, bounds); - cursor.x += glyph.xAdvance; + if (doingCharacters) { + ParseChar(line); + } else { + if (starts_with(line.begin, "info")) //contains font size + ParseInfo(line); + else if (starts_with(line.begin, "common ")) //contains UV sheet w/h + ParseCommon(line); + else if (starts_with(line.begin, "chars ")) //after this, file should be all characters + doingCharacters = true; } } } - //do an adjustment pass for centering now that the bounds are known - vector2f center = bounds / 2.f; - for (unsigned int i=0; i::const_iterator it = m_glyphs.find(chr); + if (it != m_glyphs.end()) { + const Glyph &glyph = it->second; + AddGlyph(va, cursor + glyph.offset, glyph, bounds); + cursor.x += glyph.xAdvance; + } + } + } + + //do an adjustment pass for centering now that the bounds are known + vector2f center = bounds / 2.f; + for (unsigned int i = 0; i < va.position.size(); i++) { + va.position.at(i).x -= center.x; + va.position.at(i).y -= center.y; + } } -} -// create a preferred format vertex array -Graphics::VertexArray *DistanceFieldFont::CreateVertexArray() const -{ - return new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_UV0); -} + // create a preferred format vertex array + Graphics::VertexArray *DistanceFieldFont::CreateVertexArray() const + { + return new Graphics::VertexArray(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_NORMAL | Graphics::ATTRIB_UV0); + } -void DistanceFieldFont::AddGlyph(Graphics::VertexArray &va, const vector2f &pos, const Glyph& g, vector2f &bounds) -{ - vector3f norm(0.f, 0.f, 1.f); - const vector2f &uv = g.uv; //uv offset - const float uWidth = g.uvSize.x; - const float vHeight = g.uvSize.y; - const float w = g.size.x; - const float h = g.size.y; - va.Add(vector3f(pos.x, pos.y, 0.f), norm, vector2f(uv.x, uv.y+vHeight)); - va.Add(vector3f(pos.x + w, pos.y, 0.f), norm, vector2f(uv.x+uWidth, uv.y+vHeight)); - va.Add(vector3f(pos.x, pos.y + h, 0.f), norm, vector2f(uv.x, uv.y)); + void DistanceFieldFont::AddGlyph(Graphics::VertexArray &va, const vector2f &pos, const Glyph &g, vector2f &bounds) + { + vector3f norm(0.f, 0.f, 1.f); + const vector2f &uv = g.uv; //uv offset + const float uWidth = g.uvSize.x; + const float vHeight = g.uvSize.y; + const float w = g.size.x; + const float h = g.size.y; + va.Add(vector3f(pos.x, pos.y, 0.f), norm, vector2f(uv.x, uv.y + vHeight)); + va.Add(vector3f(pos.x + w, pos.y, 0.f), norm, vector2f(uv.x + uWidth, uv.y + vHeight)); + va.Add(vector3f(pos.x, pos.y + h, 0.f), norm, vector2f(uv.x, uv.y)); - va.Add(vector3f(pos.x, pos.y + h, 0.f), norm, vector2f(uv.x, uv.y)); - va.Add(vector3f(pos.x + w, pos.y, 0.f), norm, vector2f(uv.x+uWidth, uv.y+vHeight)); - va.Add(vector3f(pos.x + w, pos.y + h, 0.f), norm, vector2f(uv.x+uWidth, uv.y)); + va.Add(vector3f(pos.x, pos.y + h, 0.f), norm, vector2f(uv.x, uv.y)); + va.Add(vector3f(pos.x + w, pos.y, 0.f), norm, vector2f(uv.x + uWidth, uv.y + vHeight)); + va.Add(vector3f(pos.x + w, pos.y + h, 0.f), norm, vector2f(uv.x + uWidth, uv.y)); - bounds.x = std::max(bounds.x, pos.x + w); - bounds.y = std::max(bounds.y, pos.y + h); -} + bounds.x = std::max(bounds.x, pos.x + w); + bounds.y = std::max(bounds.y, pos.y + h); + } -//split key=value -static bool split_token(const std::string &t, std::pair &out) -{ - size_t pos = t.find_first_of("="); + //split key=value + static bool split_token(const std::string &t, std::pair &out) + { + size_t pos = t.find_first_of("="); - if (pos == std::string::npos) return false; + if (pos == std::string::npos) return false; - out.first = t.substr(0, pos); - out.second = t.substr(pos+1); + out.first = t.substr(0, pos); + out.second = t.substr(pos + 1); - return true; -} + return true; + } -template -T get_value(const std::string& in) -{ - //should check for quotes... - //int startpos = txt.find("\"")+1; - //int endpos = txt.rfind("\""); - //double value = atof(txt.substr(startpos, endpos-startpos).c_str()); - //return value; - T out; - std::stringstream ss(in); - ss >> out; - return out; -} + template + T get_value(const std::string &in) + { + //should check for quotes... + //int startpos = txt.find("\"")+1; + //int endpos = txt.rfind("\""); + //double value = atof(txt.substr(startpos, endpos-startpos).c_str()); + //return value; + T out; + std::stringstream ss(in); + ss >> out; + return out; + } -//get font definitions from a line of xml, insert glyph information into the map -void DistanceFieldFont::ParseChar(const StringRange &r) -{ - std::stringstream ss(r.ToString()); - std::string token; + //get font definitions from a line of xml, insert glyph information into the map + void DistanceFieldFont::ParseChar(const StringRange &r) + { + std::stringstream ss(r.ToString()); + std::string token; - Uint32 id = 0; - double x = 0.0; - double y = 0.0; - double uSize = 0.0; - double vSize = 0.0; - double xoffset = 0.0; - double yoffset = 0.0; - double advance = 0.0; + Uint32 id = 0; + double x = 0.0; + double y = 0.0; + double uSize = 0.0; + double vSize = 0.0; + double xoffset = 0.0; + double yoffset = 0.0; + double advance = 0.0; - while (ss >> token) { + while (ss >> token) { std::pair pair; split_token(token, pair); @@ -161,48 +161,48 @@ void DistanceFieldFont::ParseChar(const StringRange &r) yoffset = get_value(pair.second); else if (pair.first == "xadvance") advance = get_value(pair.second); + } + + const float scale = 1.f / m_fontSize; + Glyph g; + g.uv = vector2f(float(x) / m_sheetSize.x, float(y) / m_sheetSize.y); + g.uvSize = vector2f(float(uSize) / m_sheetSize.x, float(vSize) / m_sheetSize.y); + g.size = vector2f(float(uSize), float(vSize)) * scale; + g.offset = vector2f(float(xoffset), float(m_lineHeight - vSize - yoffset)) * scale; + g.xAdvance = advance * scale; + m_glyphs[id] = g; } - const float scale = 1.f/m_fontSize; - Glyph g; - g.uv = vector2f(float(x)/m_sheetSize.x, float(y)/m_sheetSize.y); - g.uvSize = vector2f(float(uSize)/m_sheetSize.x, float(vSize)/m_sheetSize.y); - g.size = vector2f(float(uSize), float(vSize)) * scale; - g.offset = vector2f(float(xoffset), float(m_lineHeight-vSize-yoffset)) * scale; - g.xAdvance = advance * scale; - m_glyphs[id] = g; -} + void DistanceFieldFont::ParseCommon(const StringRange &line) + { + std::stringstream ss(line.ToString()); + std::string token; -void DistanceFieldFont::ParseCommon(const StringRange &line) -{ - std::stringstream ss(line.ToString()); - std::string token; - - while (ss >> token) { - std::pair pair; - split_token(token, pair); - if (pair.first == "scaleW") - m_sheetSize.x = get_value(pair.second); - else if (pair.first == "scaleH") - m_sheetSize.y = get_value(pair.second); - else if (pair.first == "lineHeight") - m_lineHeight = get_value(pair.second); - } -} - -void DistanceFieldFont::ParseInfo(const StringRange &line) -{ - std::stringstream ss(line.ToString()); - std::string token; - - while (ss >> token) { - std::pair pair; - split_token(token, pair); - if (pair.first == "size") { - m_fontSize = get_value(pair.second); - return; + while (ss >> token) { + std::pair pair; + split_token(token, pair); + if (pair.first == "scaleW") + m_sheetSize.x = get_value(pair.second); + else if (pair.first == "scaleH") + m_sheetSize.y = get_value(pair.second); + else if (pair.first == "lineHeight") + m_lineHeight = get_value(pair.second); } } -} -} + void DistanceFieldFont::ParseInfo(const StringRange &line) + { + std::stringstream ss(line.ToString()); + std::string token; + + while (ss >> token) { + std::pair pair; + split_token(token, pair); + if (pair.first == "size") { + m_fontSize = get_value(pair.second); + return; + } + } + } + +} // namespace Text diff --git a/src/text/DistanceFieldFont.h b/src/text/DistanceFieldFont.h index 20e8da6d7..b61f30278 100644 --- a/src/text/DistanceFieldFont.h +++ b/src/text/DistanceFieldFont.h @@ -22,43 +22,43 @@ * char id=32 x=253.875 y=0 width=2 height=2.125 xoffset=-1 yoffset=30.875 xadvance=16 page=0 chnl=15 * (etc) */ -#include "libs.h" #include "StringRange.h" +#include "libs.h" namespace Graphics { class Texture; class VertexArray; -} +} // namespace Graphics namespace Text { -class DistanceFieldFont : public RefCounted { -public: - DistanceFieldFont(const std::string &definitionFileName, Graphics::Texture*); - void GetGeometry(Graphics::VertexArray&, const std::string&, const vector2f &offset); - Graphics::Texture *GetTexture() const { return m_texture; } - Graphics::VertexArray *CreateVertexArray() const; + class DistanceFieldFont : public RefCounted { + public: + DistanceFieldFont(const std::string &definitionFileName, Graphics::Texture *); + void GetGeometry(Graphics::VertexArray &, const std::string &, const vector2f &offset); + Graphics::Texture *GetTexture() const { return m_texture; } + Graphics::VertexArray *CreateVertexArray() const; -private: - struct Glyph { - vector2f uv; - vector2f uvSize; - vector2f size; //geometry size - vector2f offset; //offset applied to the cursor position - float xAdvance; //how much the cursor should be moved after a character + private: + struct Glyph { + vector2f uv; + vector2f uvSize; + vector2f size; //geometry size + vector2f offset; //offset applied to the cursor position + float xAdvance; //how much the cursor should be moved after a character + }; + Graphics::Texture *m_texture; + std::map m_glyphs; + vector2f m_sheetSize; + float m_lineHeight; + float m_fontSize; //32 etc. Glyph size/advance will be scaled to 1/fontSize. + + void AddGlyph(Graphics::VertexArray &va, const vector2f &pos, const Glyph &, vector2f &bounds); + void ParseChar(const StringRange &line); + void ParseCommon(const StringRange &line); + void ParseInfo(const StringRange &line); }; - Graphics::Texture *m_texture; - std::map m_glyphs; - vector2f m_sheetSize; - float m_lineHeight; - float m_fontSize; //32 etc. Glyph size/advance will be scaled to 1/fontSize. - void AddGlyph(Graphics::VertexArray &va, const vector2f &pos, const Glyph&, vector2f &bounds); - void ParseChar(const StringRange& line); - void ParseCommon(const StringRange& line); - void ParseInfo(const StringRange& line); -}; - -} +} // namespace Text #endif diff --git a/src/text/FontConfig.cpp b/src/text/FontConfig.cpp index 2b31d8dcd..caa1a85e7 100644 --- a/src/text/FontConfig.cpp +++ b/src/text/FontConfig.cpp @@ -8,58 +8,58 @@ namespace Text { -FontConfig::FontConfig(const std::string &name, float scaleX, float scaleY) -{ - const std::string path("fonts/" + name + ".json"); - Json data = JsonUtils::LoadJsonFile(path, FileSystem::gameDataFiles); - if (data.is_null()) { - Output("couldn't read font file '%s'\n", path.c_str()); - abort(); - } + FontConfig::FontConfig(const std::string &name, float scaleX, float scaleY) + { + const std::string path("fonts/" + name + ".json"); + Json data = JsonUtils::LoadJsonFile(path, FileSystem::gameDataFiles); + if (data.is_null()) { + Output("couldn't read font file '%s'\n", path.c_str()); + abort(); + } - m_name = data.value("name", "unknown"); - m_outline = data.value("outline", false); + m_name = data.value("name", "unknown"); + m_outline = data.value("outline", false); - Json faces = data.value("faces", Json::array()); - for (auto &i : faces ) { - const std::string &fontFile = i.value("fontFile", ""); - const int pixelWidth = 1.0f/scaleX * i.value("pixelWidth", 14); - const int pixelHeight = 1.0f/scaleY * i.value("pixelWidth", 14); - const float advanceXAdjustment = i.value("advanceXAdjustment", 0.0f); + Json faces = data.value("faces", Json::array()); + for (auto &i : faces) { + const std::string &fontFile = i.value("fontFile", ""); + const int pixelWidth = 1.0f / scaleX * i.value("pixelWidth", 14); + const int pixelHeight = 1.0f / scaleY * i.value("pixelWidth", 14); + const float advanceXAdjustment = i.value("advanceXAdjustment", 0.0f); - Json ranges = i.value("ranges", Json::array()); - if (ranges.empty()) - m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, 0x000000, 0x1fffff)); - else { - for (auto &j : ranges) { - Uint32 rangeMin = 0x000000, rangeMax = 0x1fffff; - const std::string rangeMinStr = j[0].is_string() ? j[0] : "0x000000"; - const std::string rangeMaxStr = j[1].is_string() ? j[1] : "0x1fffff"; - sscanf(rangeMinStr.c_str(), "%x", &rangeMin); - sscanf(rangeMaxStr.c_str(), "%x", &rangeMax); - m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, rangeMin, rangeMax)); + Json ranges = i.value("ranges", Json::array()); + if (ranges.empty()) + m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, 0x000000, 0x1fffff)); + else { + for (auto &j : ranges) { + Uint32 rangeMin = 0x000000, rangeMax = 0x1fffff; + const std::string rangeMinStr = j[0].is_string() ? j[0] : "0x000000"; + const std::string rangeMaxStr = j[1].is_string() ? j[1] : "0x1fffff"; + sscanf(rangeMinStr.c_str(), "%x", &rangeMin); + sscanf(rangeMaxStr.c_str(), "%x", &rangeMax); + m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, rangeMin, rangeMax)); + } } } } -} -const FontConfig::Face &FontConfig::GetFaceForCodePoint(Uint32 cp) -{ - // XXX naive. map and custom comparator would be better - auto best = m_faces.end(); - for (auto i = m_faces.begin(); i != m_faces.end(); ++i) { - if (cp < (*i).rangeMin || cp > (*i).rangeMax) - continue; - if (best == m_faces.end()) { - best = i; - continue; - } - if ((*i).rangeMax - (*i).rangeMin < (*best).rangeMax - (*best).rangeMin) { - best = i; - continue; + const FontConfig::Face &FontConfig::GetFaceForCodePoint(Uint32 cp) + { + // XXX naive. map and custom comparator would be better + auto best = m_faces.end(); + for (auto i = m_faces.begin(); i != m_faces.end(); ++i) { + if (cp < (*i).rangeMin || cp > (*i).rangeMax) + continue; + if (best == m_faces.end()) { + best = i; + continue; + } + if ((*i).rangeMax - (*i).rangeMin < (*best).rangeMax - (*best).rangeMin) { + best = i; + continue; + } } + return *best; } - return *best; -} -} +} // namespace Text diff --git a/src/text/FontConfig.h b/src/text/FontConfig.h index 4fcc7b672..ffa9191b9 100644 --- a/src/text/FontConfig.h +++ b/src/text/FontConfig.h @@ -9,51 +9,57 @@ namespace Text { -class FontConfig { -public: - // XXX scale is to support to the old UI, and will be removed - FontConfig(const std::string &name, float scaleX = 1.0f, float scaleY = 1.0f); + class FontConfig { + public: + // XXX scale is to support to the old UI, and will be removed + FontConfig(const std::string &name, float scaleX = 1.0f, float scaleY = 1.0f); - struct Face { - Face(const std::string &fontFile_, int pixelWidth_, int pixelHeight_, float advanceXAdjustment_, Uint32 rangeMin_, Uint32 rangeMax_) : - fontFile(fontFile_), pixelWidth(pixelWidth_), pixelHeight(pixelHeight_), advanceXAdjustment(advanceXAdjustment_), rangeMin(rangeMin_), rangeMax(rangeMax_) {} - const std::string fontFile; - const int pixelWidth; - const int pixelHeight; - const float advanceXAdjustment; - const Uint32 rangeMin; - const Uint32 rangeMax; + struct Face { + Face(const std::string &fontFile_, int pixelWidth_, int pixelHeight_, float advanceXAdjustment_, Uint32 rangeMin_, Uint32 rangeMax_) : + fontFile(fontFile_), + pixelWidth(pixelWidth_), + pixelHeight(pixelHeight_), + advanceXAdjustment(advanceXAdjustment_), + rangeMin(rangeMin_), + rangeMax(rangeMax_) {} + const std::string fontFile; + const int pixelWidth; + const int pixelHeight; + const float advanceXAdjustment; + const Uint32 rangeMin; + const Uint32 rangeMax; - Face & operator=(const Face &o) { - const_cast(fontFile) = o.fontFile; - const_cast(pixelWidth) = o.pixelWidth; - const_cast(pixelHeight) = o.pixelHeight; - const_cast(advanceXAdjustment) = o.advanceXAdjustment; - const_cast(rangeMin) = o.rangeMin; - const_cast(rangeMax) = o.rangeMax; - return *this; - } + Face &operator=(const Face &o) + { + const_cast(fontFile) = o.fontFile; + const_cast(pixelWidth) = o.pixelWidth; + const_cast(pixelHeight) = o.pixelHeight; + const_cast(advanceXAdjustment) = o.advanceXAdjustment; + const_cast(rangeMin) = o.rangeMin; + const_cast(rangeMax) = o.rangeMax; + return *this; + } - bool operator<(const Face &o) const { - if (pixelWidth < o.pixelWidth) return true; - if (pixelHeight < o.pixelHeight) return true; - if (fontFile < o.fontFile) return true; - return false; - } + bool operator<(const Face &o) const + { + if (pixelWidth < o.pixelWidth) return true; + if (pixelHeight < o.pixelHeight) return true; + if (fontFile < o.fontFile) return true; + return false; + } + }; + + const std::string &GetName() const { return m_name; } + bool IsOutline() const { return m_outline; } + + const Face &GetFaceForCodePoint(Uint32 cp); + + private: + std::string m_name; + bool m_outline; + std::vector m_faces; }; - const std::string &GetName() const { return m_name; } - bool IsOutline() const { return m_outline; } - - const Face &GetFaceForCodePoint(Uint32 cp); - -private: - std::string m_name; - bool m_outline; - std::vector m_faces; - -}; - -} +} // namespace Text #endif diff --git a/src/text/TextSupport.cpp b/src/text/TextSupport.cpp index 5b8ec1e15..3e2cac79a 100644 --- a/src/text/TextSupport.cpp +++ b/src/text/TextSupport.cpp @@ -6,65 +6,71 @@ namespace Text { -// returns num bytes consumed, or 0 for end/bogus -int utf8_decode_char(Uint32 *chr, const char *src) -{ - unsigned int c = *(reinterpret_cast(src)); - if (!c) { *chr = c; return 0; } - if (!(c & 0x80)) { *chr = c; return 1; } - else if (c >= 0xf0) { - if (!src[1] || !src[2] || !src[3]) return 0; - c = (c & 0x7) << 18; - c |= (src[1] & 0x3f) << 12; - c |= (src[2] & 0x3f) << 6; - c |= src[3] & 0x3f; - *chr = c; return 4; + // returns num bytes consumed, or 0 for end/bogus + int utf8_decode_char(Uint32 *chr, const char *src) + { + unsigned int c = *(reinterpret_cast(src)); + if (!c) { + *chr = c; + return 0; + } + if (!(c & 0x80)) { + *chr = c; + return 1; + } else if (c >= 0xf0) { + if (!src[1] || !src[2] || !src[3]) return 0; + c = (c & 0x7) << 18; + c |= (src[1] & 0x3f) << 12; + c |= (src[2] & 0x3f) << 6; + c |= src[3] & 0x3f; + *chr = c; + return 4; + } else if (c >= 0xe0) { + if (!src[1] || !src[2]) return 0; + c = (c & 0xf) << 12; + c |= (src[1] & 0x3f) << 6; + c |= src[2] & 0x3f; + *chr = c; + return 3; + } else { + if (!src[1]) return 0; + c = (c & 0x1f) << 6; + c |= src[1] & 0x3f; + *chr = c; + return 2; + } } - else if (c >= 0xe0) { - if (!src[1] || !src[2]) return 0; - c = (c & 0xf) << 12; - c |= (src[1] & 0x3f) << 6; - c |= src[2] & 0x3f; - *chr = c; return 3; - } - else { - if (!src[1]) return 0; - c = (c & 0x1f) << 6; - c |= src[1] & 0x3f; - *chr = c; return 2; - } -} -// encode one Unicode code-point as UTF-8 -// chr: the Unicode code-point -// buf: a character buffer, which must have space for at least 4 bytes -// (i.e., assigning to buf[3] must be a valid operation) -// returns: number of bytes in the encoded character -int utf8_encode_char(Uint32 chr, char buf[4]) -{ - unsigned char *ubuf = reinterpret_cast(buf); - if (chr <= 0x7f) { - ubuf[0] = chr; - return 1; - } else if (chr <= 0x7ff) { - ubuf[0] = 0xc0 | (chr >> 6); - ubuf[1] = 0x80 | (chr & 0x3f); - return 2; - } else if (chr <= 0xffff) { - ubuf[0] = 0xe0 | (chr >> 12); - ubuf[1] = 0x80 | ((chr >> 6) & 0x3f); - ubuf[2] = 0x80 | (chr & 0x3f); - return 3; - } else if (chr <= 0x10fff) { - ubuf[0] = 0xf0 | (chr >> 18); - ubuf[1] = 0x80 | ((chr >> 12) & 0x3f); - ubuf[2] = 0x80 | ((chr >> 6) & 0x3f); - ubuf[3] = 0x80 | (chr & 0x3f); - return 4; - } else { - assert(0 && "Invalid Unicode code-point."); - return 0; + // encode one Unicode code-point as UTF-8 + // chr: the Unicode code-point + // buf: a character buffer, which must have space for at least 4 bytes + // (i.e., assigning to buf[3] must be a valid operation) + // returns: number of bytes in the encoded character + int utf8_encode_char(Uint32 chr, char buf[4]) + { + unsigned char *ubuf = reinterpret_cast(buf); + if (chr <= 0x7f) { + ubuf[0] = chr; + return 1; + } else if (chr <= 0x7ff) { + ubuf[0] = 0xc0 | (chr >> 6); + ubuf[1] = 0x80 | (chr & 0x3f); + return 2; + } else if (chr <= 0xffff) { + ubuf[0] = 0xe0 | (chr >> 12); + ubuf[1] = 0x80 | ((chr >> 6) & 0x3f); + ubuf[2] = 0x80 | (chr & 0x3f); + return 3; + } else if (chr <= 0x10fff) { + ubuf[0] = 0xf0 | (chr >> 18); + ubuf[1] = 0x80 | ((chr >> 12) & 0x3f); + ubuf[2] = 0x80 | ((chr >> 6) & 0x3f); + ubuf[3] = 0x80 | (chr & 0x3f); + return 4; + } else { + assert(0 && "Invalid Unicode code-point."); + return 0; + } } -} -} +} // namespace Text diff --git a/src/text/TextSupport.h b/src/text/TextSupport.h index ed41265c6..8025637f8 100644 --- a/src/text/TextSupport.h +++ b/src/text/TextSupport.h @@ -9,59 +9,66 @@ namespace Text { -// various text-related functions. a proper home needs to be found for them. + // various text-related functions. a proper home needs to be found for them. -// convert one multibyte (utf8) char to a widechar (utf32/ucs4) -// chr: pointer to output storage -// src: multibyte string -// returns: number of bytes swallowed, or 0 if end of string -int utf8_decode_char(Uint32 *chr, const char *src); + // convert one multibyte (utf8) char to a widechar (utf32/ucs4) + // chr: pointer to output storage + // src: multibyte string + // returns: number of bytes swallowed, or 0 if end of string + int utf8_decode_char(Uint32 *chr, const char *src); -// encode one Unicode code-point as UTF-8 -// chr: the Unicode code-point -// buf: a character buffer, which must have space for at least 4 bytes -// (i.e., assigning to buf[3] must be a valid operation) -// returns: number of bytes in the encoded character -int utf8_encode_char(Uint32 chr, char buf[4]); + // encode one Unicode code-point as UTF-8 + // chr: the Unicode code-point + // buf: a character buffer, which must have space for at least 4 bytes + // (i.e., assigning to buf[3] must be a valid operation) + // returns: number of bytes in the encoded character + int utf8_encode_char(Uint32 chr, char buf[4]); -// this can tell you the length of a UTF-8 character, or more generally -// it tells you the number of bytes to move forward to get to the beginning -// of the next character -inline int utf8_next_char_offset(const char *str) { - assert(str); - assert(*str); - const char * const start = str; - if (*str & 0x80) { - // technically, the first byte of a UTF-8 multi-byte sequence is enough - // to determine the length of the sequence, but a loop is simpler and - // more robust to incorrectly encoded text - do { ++str; } while ((*str & 0xC0) == 0x80); - return (str - start); - } else - return 1; -} + // this can tell you the length of a UTF-8 character, or more generally + // it tells you the number of bytes to move forward to get to the beginning + // of the next character + inline int utf8_next_char_offset(const char *str) + { + assert(str); + assert(*str); + const char *const start = str; + if (*str & 0x80) { + // technically, the first byte of a UTF-8 multi-byte sequence is enough + // to determine the length of the sequence, but a loop is simpler and + // more robust to incorrectly encoded text + do { + ++str; + } while ((*str & 0xC0) == 0x80); + return (str - start); + } else + return 1; + } -// this tells you the number of bytes to move backwards to get to the -// beginning of the previous character (or the current character if you start inside a multi-byte sequence) -// ('begin' indicates the start of the array and is used to avoid walking off the front) -inline int utf8_prev_char_offset(const char *str, const char * const begin) { - assert(str); - assert(str > begin); - const char * const start = str; - --str; - if (*str & 0x80) { - while ((str > begin) && ((*str & 0xC0) == 0x80)) { --str; } - return (start - str); - } else - return 1; -} + // this tells you the number of bytes to move backwards to get to the + // beginning of the previous character (or the current character if you start inside a multi-byte sequence) + // ('begin' indicates the start of the array and is used to avoid walking off the front) + inline int utf8_prev_char_offset(const char *str, const char *const begin) + { + assert(str); + assert(str > begin); + const char *const start = str; + --str; + if (*str & 0x80) { + while ((str > begin) && ((*str & 0xC0) == 0x80)) { + --str; + } + return (start - str); + } else + return 1; + } -// returns true if the char c is an ASCII letter, a digit -// or an underscore. -inline bool is_alphanumunderscore(char c) { - return (c == '_' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); -} + // returns true if the char c is an ASCII letter, a digit + // or an underscore. + inline bool is_alphanumunderscore(char c) + { + return (c == '_' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); + } -} +} // namespace Text #endif diff --git a/src/text/TextureFont.cpp b/src/text/TextureFont.cpp index 2fcfb7845..fd7b3d305 100644 --- a/src/text/TextureFont.cpp +++ b/src/text/TextureFont.cpp @@ -3,11 +3,11 @@ #include "TextureFont.h" #include "FileSystem.h" -#include "libs.h" +#include "TextSupport.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" #include "graphics/VertexBuffer.h" -#include "TextSupport.h" +#include "libs.h" #include "utils.h" #ifdef __clang__ @@ -29,674 +29,666 @@ namespace { static const int ATLAS_SIZE = 1024; static double CACHE_EVICTION_TIME = 0.25; -}; +}; // namespace namespace Text { -int TextureFont::s_glyphCount = 0; + int TextureFont::s_glyphCount = 0; -void TextureFont::AddGlyphGeometry(Graphics::VertexArray &va, const Glyph &glyph, const float x, const float y, const Color &c) -{ - const float offX = x + float(glyph.offX); - const float offY = y + GetHeight() - float(glyph.offY); - const float offU = glyph.offU; - const float offV = glyph.offV; - - const vector3f p0(offX, offY, 0.0f); - const vector3f p1(offX, offY+glyph.height, 0.0f); - const vector3f p2(offX+glyph.width, offY, 0.0f); - const vector3f p3(offX+glyph.width, offY+glyph.height, 0.0f); - - const vector2f t0(offU, offV ); - const vector2f t1(offU, offV+glyph.texHeight); - const vector2f t2(offU+glyph.texWidth, offV ); - const vector2f t3(offU+glyph.texWidth, offV+glyph.texHeight); - - va.Add(p0, c, t0); - va.Add(p1, c, t1); - va.Add(p2, c, t2); - - va.Add(p2, c, t2); - va.Add(p1, c, t1); - va.Add(p3, c, t3); - - s_glyphCount++; -} - -void TextureFont::MeasureString(const std::string &str, float &w, float &h) -{ - w = h = 0.0f; - - float line_width = 0.0f; - - int i = 0; - while (str[i]) { - if (str[i] == '\n') { - if (line_width > w) w = line_width; - line_width = 0.0f; - h += GetHeight(); - i++; - } else { - Uint32 chr; - int n = utf8_decode_char(&chr, &str[i]); - if (n == 0) - break; - i += n; - - const Glyph &glyph = GetGlyph(chr); - - line_width += glyph.advX; - - if (str[i]) { - Uint32 chr2; - n = utf8_decode_char(&chr2, &str[i]); - assert(n); - line_width += GetKern(glyph, GetGlyph(chr2)); - } - } - } - - if (line_width > w) w = line_width; - h += GetHeight() + GetDescender(); -} - -void TextureFont::MeasureCharacterPos(const std::string &str, int charIndex, float &charX, float &charY) -{ - assert(charIndex >= 0); - - float x = 0.0f, y = GetHeight(); - int i = 0; - Uint32 chr; - int len = utf8_decode_char(&chr, &str[i]); - while (str[i] && (i < charIndex)) { - Uint32 nextChar; - i += len; - len = utf8_decode_char(&nextChar, &str[i]); - assert(!str[i] || len); // assert valid encoding - - if (chr == '\n') { - x = 0.0f; - y += GetHeight(); - } else { - const Glyph &glyph = GetGlyph(chr); - float advance = glyph.advX; - - if (nextChar != '\n' && nextChar != '\0') - advance += GetKern(glyph, GetGlyph(nextChar)); - - x += advance; - } - - chr = nextChar; - } - - charX = x; - charY = y; -} - -int TextureFont::PickCharacter(const std::string &str, float mouseX, float mouseY) -{ - assert(mouseX >= 0.0f && mouseY >= 0.0f); - - // at the point of the mouse in-box test, the vars have the following values: - // i1: the index of the character being tested - // i2: the index of the next character - // charBytes: the number of bytes used to encode the next character - // right: the right edge of the box being tested - // bottom: the bottom of the box being tested - // x: the x-coordinate of the next character - // chr1: the Unicode value of the character being tested - // chr2: the Unicode value of the next character - - Uint32 chr2 = '\n'; // pretend we've just had a new line - float bottom = 0.0f, x = 0.0f; - int i2 = 0, charBytes = 0; - do { - int i1 = i2; - Uint32 chr1 = chr2; - - // read the next character - i2 += charBytes; - charBytes = utf8_decode_char(&chr2, &str[i2]); - assert(!str[i2] || charBytes); // assert valid encoding - - float right; - if (chr1 == '\n') { - right = std::numeric_limits::max(); - x = 0.0f; - } else { - const Glyph &glyph = GetGlyph(chr1); - float advance = glyph.advX; - - if (chr2 != '\n' && chr2 != '\0') - advance += GetKern(glyph, GetGlyph(chr2)); - - right = x + (advance / 2.0f); - x += advance; - } - - if ((mouseY < bottom) && (mouseX < right)) - return i1; - - if (chr1 == '\n') - bottom += GetHeight(); - } while (charBytes); - - return i2; -} - -void TextureFont::RenderBuffer(Graphics::VertexBuffer *vb, const Color &color) -{ - if( vb && vb->GetSize() > 0 ) + void TextureFont::AddGlyphGeometry(Graphics::VertexArray &va, const Glyph &glyph, const float x, const float y, const Color &c) { - m_mat->diffuse = color; - m_renderer->DrawBuffer(vb, m_renderState, m_mat.get()); + const float offX = x + float(glyph.offX); + const float offY = y + GetHeight() - float(glyph.offY); + const float offU = glyph.offU; + const float offV = glyph.offV; + + const vector3f p0(offX, offY, 0.0f); + const vector3f p1(offX, offY + glyph.height, 0.0f); + const vector3f p2(offX + glyph.width, offY, 0.0f); + const vector3f p3(offX + glyph.width, offY + glyph.height, 0.0f); + + const vector2f t0(offU, offV); + const vector2f t1(offU, offV + glyph.texHeight); + const vector2f t2(offU + glyph.texWidth, offV); + const vector2f t3(offU + glyph.texWidth, offV + glyph.texHeight); + + va.Add(p0, c, t0); + va.Add(p1, c, t1); + va.Add(p2, c, t2); + + va.Add(p2, c, t2); + va.Add(p1, c, t1); + va.Add(p3, c, t3); + + s_glyphCount++; } -} -void TextureFont::PopulateString(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color) -{ - PROFILE_SCOPED() + void TextureFont::MeasureString(const std::string &str, float &w, float &h) + { + w = h = 0.0f; - if(str.empty()) return; + float line_width = 0.0f; - float alpha_f = color.a / 255.0f; - const Color premult_color = Color(color.r * alpha_f, color.g * alpha_f, color.b * alpha_f, color.a); - - float px = x; - float py = y; - - // we know how many we're adding so reserve space ahead of time - va.position.reserve(va.position.size() + str.size() * 6); - va.diffuse.reserve(va.diffuse.size() + str.size() * 6); - va.uv0.reserve(va.uv0.size() + str.size() * 6); - - // add all of the glyphs individually - int i = 0; - while (str[i]) { - if (str[i] == '\n') { - px = x; - py += GetHeight(); - i++; - } else { - Uint32 chr; - int n = utf8_decode_char(&chr, &str[i]); - if(n<=0) - break; - i += n; - - const Glyph &glyph = GetGlyph(chr); - AddGlyphGeometry(va, glyph, roundf(px), py, premult_color); - - if (str[i]) { - Uint32 chr2; - n = utf8_decode_char(&chr2, &str[i]); - if(n<=0) + int i = 0; + while (str[i]) { + if (str[i] == '\n') { + if (line_width > w) w = line_width; + line_width = 0.0f; + h += GetHeight(); + i++; + } else { + Uint32 chr; + int n = utf8_decode_char(&chr, &str[i]); + if (n == 0) break; + i += n; - px += GetKern(glyph, GetGlyph(chr2)); + const Glyph &glyph = GetGlyph(chr); + + line_width += glyph.advX; + + if (str[i]) { + Uint32 chr2; + n = utf8_decode_char(&chr2, &str[i]); + assert(n); + line_width += GetKern(glyph, GetGlyph(chr2)); + } + } + } + + if (line_width > w) w = line_width; + h += GetHeight() + GetDescender(); + } + + void TextureFont::MeasureCharacterPos(const std::string &str, int charIndex, float &charX, float &charY) + { + assert(charIndex >= 0); + + float x = 0.0f, y = GetHeight(); + int i = 0; + Uint32 chr; + int len = utf8_decode_char(&chr, &str[i]); + while (str[i] && (i < charIndex)) { + Uint32 nextChar; + i += len; + len = utf8_decode_char(&nextChar, &str[i]); + assert(!str[i] || len); // assert valid encoding + + if (chr == '\n') { + x = 0.0f; + y += GetHeight(); + } else { + const Glyph &glyph = GetGlyph(chr); + float advance = glyph.advX; + + if (nextChar != '\n' && nextChar != '\0') + advance += GetKern(glyph, GetGlyph(nextChar)); + + x += advance; } - px += glyph.advX; + chr = nextChar; + } + + charX = x; + charY = y; + } + + int TextureFont::PickCharacter(const std::string &str, float mouseX, float mouseY) + { + assert(mouseX >= 0.0f && mouseY >= 0.0f); + + // at the point of the mouse in-box test, the vars have the following values: + // i1: the index of the character being tested + // i2: the index of the next character + // charBytes: the number of bytes used to encode the next character + // right: the right edge of the box being tested + // bottom: the bottom of the box being tested + // x: the x-coordinate of the next character + // chr1: the Unicode value of the character being tested + // chr2: the Unicode value of the next character + + Uint32 chr2 = '\n'; // pretend we've just had a new line + float bottom = 0.0f, x = 0.0f; + int i2 = 0, charBytes = 0; + do { + int i1 = i2; + Uint32 chr1 = chr2; + + // read the next character + i2 += charBytes; + charBytes = utf8_decode_char(&chr2, &str[i2]); + assert(!str[i2] || charBytes); // assert valid encoding + + float right; + if (chr1 == '\n') { + right = std::numeric_limits::max(); + x = 0.0f; + } else { + const Glyph &glyph = GetGlyph(chr1); + float advance = glyph.advX; + + if (chr2 != '\n' && chr2 != '\0') + advance += GetKern(glyph, GetGlyph(chr2)); + + right = x + (advance / 2.0f); + x += advance; + } + + if ((mouseY < bottom) && (mouseX < right)) + return i1; + + if (chr1 == '\n') + bottom += GetHeight(); + } while (charBytes); + + return i2; + } + + void TextureFont::RenderBuffer(Graphics::VertexBuffer *vb, const Color &color) + { + if (vb && vb->GetSize() > 0) { + m_mat->diffuse = color; + m_renderer->DrawBuffer(vb, m_renderState, m_mat.get()); } } -} -Color TextureFont::PopulateMarkup(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color) -{ - PROFILE_SCOPED() + void TextureFont::PopulateString(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color) + { + PROFILE_SCOPED() - if(str.empty()) return Color::BLACK; + if (str.empty()) return; - // we know how many we're adding so reserve space ahead of time - va.position.reserve(va.position.size() + str.size() * 6); - va.diffuse.reserve(va.diffuse.size() + str.size() * 6); - va.uv0.reserve(va.uv0.size() + str.size() * 6); + float alpha_f = color.a / 255.0f; + const Color premult_color = Color(color.r * alpha_f, color.g * alpha_f, color.b * alpha_f, color.a); - float px = x; - float py = y; + float px = x; + float py = y; - Color c = color; - float alpha_f = c.a / 255.0f; - Color premult_c = Color(c.r * alpha_f, c.g * alpha_f, c.b * alpha_f, c.a); + // we know how many we're adding so reserve space ahead of time + va.position.reserve(va.position.size() + str.size() * 6); + va.diffuse.reserve(va.diffuse.size() + str.size() * 6); + va.uv0.reserve(va.uv0.size() + str.size() * 6); - int i = 0; - while (str[i]) { - if (str[i] == '#') { - Uint32 hexcol; - if (sscanf(&str[i], "#%3x", &hexcol)==1) { - c.r = float((hexcol&0xf00)>>4); - c.g = float((hexcol&0xf0)); - c.b = float((hexcol&0xf)<<4); - // retain alpha value from RenderMarkup color parameter - premult_c.r = c.r * alpha_f; - premult_c.g = c.g * alpha_f; - premult_c.b = c.b * alpha_f; - i+=4; - continue; - } - } - - if (str[i] == '\n') { - px = x; - py += GetHeight(); - i++; - } else { - Uint32 chr; - int n = utf8_decode_char(&chr, &str[i]); - if(n<=0) - break; - i += n; - - const Glyph &glyph = GetGlyph(chr); - AddGlyphGeometry(va, glyph, roundf(px), py, premult_c); - - // XXX kerning doesn't skip markup - if (str[i]) { - Uint32 chr2; - n = utf8_decode_char(&chr2, &str[i]); - if(n<=0) + // add all of the glyphs individually + int i = 0; + while (str[i]) { + if (str[i] == '\n') { + px = x; + py += GetHeight(); + i++; + } else { + Uint32 chr; + int n = utf8_decode_char(&chr, &str[i]); + if (n <= 0) break; + i += n; - px += GetKern(glyph, GetGlyph(chr2)); + const Glyph &glyph = GetGlyph(chr); + AddGlyphGeometry(va, glyph, roundf(px), py, premult_color); + + if (str[i]) { + Uint32 chr2; + n = utf8_decode_char(&chr2, &str[i]); + if (n <= 0) + break; + + px += GetKern(glyph, GetGlyph(chr2)); + } + + px += glyph.advX; } - - px += glyph.advX; } } - return c; -} - -Graphics::VertexBuffer* TextureFont::CreateVertexBuffer(const Graphics::VertexArray &va, const bool bIsStatic) const -{ - if (va.GetNumVerts() > 0) + Color TextureFont::PopulateMarkup(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color) { - //create buffer and upload data - Graphics::VertexBufferDesc vbd; - vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; - vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; - vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; - vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; - vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; - vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; - vbd.numVertices = va.GetNumVerts(); - vbd.usage = bIsStatic ? Graphics::BUFFER_USAGE_STATIC : Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame - Graphics::VertexBuffer *vbuffer = m_renderer->CreateVertexBuffer(vbd); - vbuffer->Populate(va); + PROFILE_SCOPED() - return vbuffer; + if (str.empty()) return Color::BLACK; + + // we know how many we're adding so reserve space ahead of time + va.position.reserve(va.position.size() + str.size() * 6); + va.diffuse.reserve(va.diffuse.size() + str.size() * 6); + va.uv0.reserve(va.uv0.size() + str.size() * 6); + + float px = x; + float py = y; + + Color c = color; + float alpha_f = c.a / 255.0f; + Color premult_c = Color(c.r * alpha_f, c.g * alpha_f, c.b * alpha_f, c.a); + + int i = 0; + while (str[i]) { + if (str[i] == '#') { + Uint32 hexcol; + if (sscanf(&str[i], "#%3x", &hexcol) == 1) { + c.r = float((hexcol & 0xf00) >> 4); + c.g = float((hexcol & 0xf0)); + c.b = float((hexcol & 0xf) << 4); + // retain alpha value from RenderMarkup color parameter + premult_c.r = c.r * alpha_f; + premult_c.g = c.g * alpha_f; + premult_c.b = c.b * alpha_f; + i += 4; + continue; + } + } + + if (str[i] == '\n') { + px = x; + py += GetHeight(); + i++; + } else { + Uint32 chr; + int n = utf8_decode_char(&chr, &str[i]); + if (n <= 0) + break; + i += n; + + const Glyph &glyph = GetGlyph(chr); + AddGlyphGeometry(va, glyph, roundf(px), py, premult_c); + + // XXX kerning doesn't skip markup + if (str[i]) { + Uint32 chr2; + n = utf8_decode_char(&chr2, &str[i]); + if (n <= 0) + break; + + px += GetKern(glyph, GetGlyph(chr2)); + } + + px += glyph.advX; + } + } + + return c; } - return nullptr; -} -Graphics::VertexBuffer* TextureFont::CreateVertexBuffer(const Graphics::VertexArray &va, const std::string &str, const bool bIsStatic) -{ - if( va.GetNumVerts() > 0 ) + Graphics::VertexBuffer *TextureFont::CreateVertexBuffer(const Graphics::VertexArray &va, const bool bIsStatic) const { - Graphics::VertexBuffer *pVB = GetCachedVertexBuffer(str); - if (pVB) - return pVB; + if (va.GetNumVerts() > 0) { + //create buffer and upload data + Graphics::VertexBufferDesc vbd; + vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; + vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; + vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; + vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; + vbd.attrib[2].semantic = Graphics::ATTRIB_UV0; + vbd.attrib[2].format = Graphics::ATTRIB_FORMAT_FLOAT2; + vbd.numVertices = va.GetNumVerts(); + vbd.usage = bIsStatic ? Graphics::BUFFER_USAGE_STATIC : Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame + Graphics::VertexBuffer *vbuffer = m_renderer->CreateVertexBuffer(vbd); + vbuffer->Populate(va); - //create buffer and upload data - Graphics::VertexBuffer *vbuffer = CreateVertexBuffer(va, bIsStatic); - AddCachedVertexBuffer(vbuffer, str); - - return vbuffer; - } - return nullptr; -} - -Graphics::VertexBuffer* TextureFont::GetCachedVertexBuffer(const std::string &str) -{ - VBHashMapIter found = m_vbTextCache.find(str); - if (found == m_vbTextCache.end()) { + return vbuffer; + } return nullptr; } - // update the last access time - const double lastAccessTime = 0.001 * double(SDL_GetTicks()); - found->second.first = lastAccessTime; + Graphics::VertexBuffer *TextureFont::CreateVertexBuffer(const Graphics::VertexArray &va, const std::string &str, const bool bIsStatic) + { + if (va.GetNumVerts() > 0) { + Graphics::VertexBuffer *pVB = GetCachedVertexBuffer(str); + if (pVB) + return pVB; - if ((lastAccessTime - m_lfLastCacheCleanTime) > CACHE_EVICTION_TIME) { - CleanVertexBufferCache(); - m_lfLastCacheCleanTime = lastAccessTime; - } + //create buffer and upload data + Graphics::VertexBuffer *vbuffer = CreateVertexBuffer(va, bIsStatic); + AddCachedVertexBuffer(vbuffer, str); - // return the vertex buffer - return found->second.second.Get(); -} - -void TextureFont::AddCachedVertexBuffer(Graphics::VertexBuffer *pVB, const std::string &str) -{ - Graphics::VertexBuffer *pLocalVB = GetCachedVertexBuffer(str); - if (pLocalVB) - return; - - // set the time that the buffer was added to the cache - const double lastAccessTime = 0.001 * double(SDL_GetTicks()); - m_vbTextCache[str] = std::make_pair(lastAccessTime, RefCountedPtr(pVB)); -} - -Uint32 TextureFont::CleanVertexBufferCache() -{ - // update the last access time - Uint32 numDeleted = 0; - const double currentTime = 0.001 * double(SDL_GetTicks()); - for (auto it : m_vbTextCache) { - if ((currentTime - it.second.first) > CACHE_EVICTION_TIME) { - it.second.second.Reset(); - ++numDeleted; + return vbuffer; } - } - return numDeleted; -} - -const TextureFont::Glyph &TextureFont::GetGlyph(Uint32 chr) -{ - auto i = m_glyphs.find(chr); - if (i != m_glyphs.end()) - return (*i).second; - - m_glyphs[chr] = BakeGlyph(chr); - return m_glyphs[chr]; -} - - -TextureFont::Glyph TextureFont::BakeGlyph(Uint32 chr) -{ - int err; - Glyph glyph; - FT_Glyph ftGlyph; - - const FontConfig::Face &face = m_config.GetFaceForCodePoint(chr); - glyph.ftFace = GetFTFace(face); - glyph.ftIndex = FT_Get_Char_Index(glyph.ftFace, chr); - - err = FT_Load_Char(glyph.ftFace, chr, FT_LOAD_FORCE_AUTOHINT); - if (err) { - Output("Error %d loading glyph\n", err); - return Glyph(); + return nullptr; } - // get base glyph again - err = FT_Get_Glyph(glyph.ftFace->glyph, &ftGlyph); - if (err) { - Output("Glyph get error %d\n", err); - return Glyph(); + Graphics::VertexBuffer *TextureFont::GetCachedVertexBuffer(const std::string &str) + { + VBHashMapIter found = m_vbTextCache.find(str); + if (found == m_vbTextCache.end()) { + return nullptr; + } + + // update the last access time + const double lastAccessTime = 0.001 * double(SDL_GetTicks()); + found->second.first = lastAccessTime; + + if ((lastAccessTime - m_lfLastCacheCleanTime) > CACHE_EVICTION_TIME) { + CleanVertexBufferCache(); + m_lfLastCacheCleanTime = lastAccessTime; + } + + // return the vertex buffer + return found->second.second.Get(); } - // convert to bitmap - if (ftGlyph->format != FT_GLYPH_FORMAT_BITMAP) { - err = FT_Glyph_To_Bitmap(&ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1); + void TextureFont::AddCachedVertexBuffer(Graphics::VertexBuffer *pVB, const std::string &str) + { + Graphics::VertexBuffer *pLocalVB = GetCachedVertexBuffer(str); + if (pLocalVB) + return; + + // set the time that the buffer was added to the cache + const double lastAccessTime = 0.001 * double(SDL_GetTicks()); + m_vbTextCache[str] = std::make_pair(lastAccessTime, RefCountedPtr(pVB)); + } + + Uint32 TextureFont::CleanVertexBufferCache() + { + // update the last access time + Uint32 numDeleted = 0; + const double currentTime = 0.001 * double(SDL_GetTicks()); + for (auto it : m_vbTextCache) { + if ((currentTime - it.second.first) > CACHE_EVICTION_TIME) { + it.second.second.Reset(); + ++numDeleted; + } + } + return numDeleted; + } + + const TextureFont::Glyph &TextureFont::GetGlyph(Uint32 chr) + { + auto i = m_glyphs.find(chr); + if (i != m_glyphs.end()) + return (*i).second; + + m_glyphs[chr] = BakeGlyph(chr); + return m_glyphs[chr]; + } + + TextureFont::Glyph TextureFont::BakeGlyph(Uint32 chr) + { + int err; + Glyph glyph; + FT_Glyph ftGlyph; + + const FontConfig::Face &face = m_config.GetFaceForCodePoint(chr); + glyph.ftFace = GetFTFace(face); + glyph.ftIndex = FT_Get_Char_Index(glyph.ftFace, chr); + + err = FT_Load_Char(glyph.ftFace, chr, FT_LOAD_FORCE_AUTOHINT); if (err) { - Output("Couldn't convert glyph to bitmap, error %d\n", err); + Output("Error %d loading glyph\n", err); return Glyph(); } - } - const FT_BitmapGlyph bmGlyph = FT_BitmapGlyph(ftGlyph); - - glyph.advX = float(glyph.ftFace->glyph->advance.x) / 64.f + face.advanceXAdjustment; - glyph.advY = float(glyph.ftFace->glyph->advance.y) / 64.f; - - if (!bmGlyph->bitmap.rows || !bmGlyph->bitmap.width) { - // no bitmap, we can just return advance metrics (for eg space) - FT_Done_Glyph(ftGlyph); - return glyph; - } - - if (m_config.IsOutline()) { - FT_Glyph strokeGlyph; - - err = FT_Get_Glyph(glyph.ftFace->glyph, &strokeGlyph); + // get base glyph again + err = FT_Get_Glyph(glyph.ftFace->glyph, &ftGlyph); if (err) { Output("Glyph get error %d\n", err); return Glyph(); } - err = FT_Glyph_Stroke(&strokeGlyph, m_stroker, 1); - if (err) { - Output("Glyph stroke error %d\n", err); - FT_Done_Glyph(strokeGlyph); - return Glyph(); - } - - //convert to bitmap - if (strokeGlyph->format != FT_GLYPH_FORMAT_BITMAP) { - err = FT_Glyph_To_Bitmap(&strokeGlyph, FT_RENDER_MODE_NORMAL, 0, 1); + // convert to bitmap + if (ftGlyph->format != FT_GLYPH_FORMAT_BITMAP) { + err = FT_Glyph_To_Bitmap(&ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1); if (err) { Output("Couldn't convert glyph to bitmap, error %d\n", err); - FT_Done_Glyph(strokeGlyph); return Glyph(); } } - const FT_BitmapGlyph bmStrokeGlyph = FT_BitmapGlyph(strokeGlyph); + const FT_BitmapGlyph bmGlyph = FT_BitmapGlyph(ftGlyph); - //don't run off atlas borders - m_atlasVIncrement = std::max(m_atlasVIncrement, static_cast(bmStrokeGlyph->bitmap.rows)); - if (m_atlasU + static_cast(bmStrokeGlyph->bitmap.width) > ATLAS_SIZE) { - m_atlasU = 0; - m_atlasV += m_atlasVIncrement; - m_atlasVIncrement = 0; + glyph.advX = float(glyph.ftFace->glyph->advance.x) / 64.f + face.advanceXAdjustment; + glyph.advY = float(glyph.ftFace->glyph->advance.y) / 64.f; + + if (!bmGlyph->bitmap.rows || !bmGlyph->bitmap.width) { + // no bitmap, we can just return advance metrics (for eg space) + FT_Done_Glyph(ftGlyph); + return glyph; } - if (m_atlasV + bmStrokeGlyph->bitmap.rows > ATLAS_SIZE) { - char utf8buf[8]; - int len = utf8_encode_char(chr, utf8buf); - utf8buf[len] = '\0'; - Output("glyph doesn't fit in atlas (U+%04X; height = %d; char: %s; atlasV = %d)\n", chr, bmStrokeGlyph->bitmap.rows, utf8buf, m_atlasV); + if (m_config.IsOutline()) { + FT_Glyph strokeGlyph; + + err = FT_Get_Glyph(glyph.ftFace->glyph, &strokeGlyph); + if (err) { + Output("Glyph get error %d\n", err); + return Glyph(); + } + + err = FT_Glyph_Stroke(&strokeGlyph, m_stroker, 1); + if (err) { + Output("Glyph stroke error %d\n", err); + FT_Done_Glyph(strokeGlyph); + return Glyph(); + } + + //convert to bitmap + if (strokeGlyph->format != FT_GLYPH_FORMAT_BITMAP) { + err = FT_Glyph_To_Bitmap(&strokeGlyph, FT_RENDER_MODE_NORMAL, 0, 1); + if (err) { + Output("Couldn't convert glyph to bitmap, error %d\n", err); + FT_Done_Glyph(strokeGlyph); + return Glyph(); + } + } + + const FT_BitmapGlyph bmStrokeGlyph = FT_BitmapGlyph(strokeGlyph); + + //don't run off atlas borders + m_atlasVIncrement = std::max(m_atlasVIncrement, static_cast(bmStrokeGlyph->bitmap.rows)); + if (m_atlasU + static_cast(bmStrokeGlyph->bitmap.width) > ATLAS_SIZE) { + m_atlasU = 0; + m_atlasV += m_atlasVIncrement; + m_atlasVIncrement = 0; + } + + if (m_atlasV + bmStrokeGlyph->bitmap.rows > ATLAS_SIZE) { + char utf8buf[8]; + int len = utf8_encode_char(chr, utf8buf); + utf8buf[len] = '\0'; + Output("glyph doesn't fit in atlas (U+%04X; height = %d; char: %s; atlasV = %d)\n", chr, bmStrokeGlyph->bitmap.rows, utf8buf, m_atlasV); + FT_Done_Glyph(strokeGlyph); + return Glyph(); + } + + const int pitch = bmGlyph->bitmap.pitch; + const int rows = bmGlyph->bitmap.rows; + const int strokePitch = bmStrokeGlyph->bitmap.pitch; + const int strokeRows = bmStrokeGlyph->bitmap.rows; + + const int xoff = (bmStrokeGlyph->bitmap.width - bmGlyph->bitmap.width) / 2; + const int yoff = (bmStrokeGlyph->bitmap.rows - bmGlyph->bitmap.rows) / 2; + + // make enough space for both glyphs including offset + m_buf.resize(ALIGN(strokePitch, 4) * strokeRows * 2); + std::fill(m_buf.begin(), m_buf.end(), 0); + + // stroke first into the alpha channel + for (int y = 0; y < strokeRows; y++) { + for (int x = 0; x < strokePitch; x++) { + const int d = ALIGN(strokePitch * 2, 4) * y + x * 2; + const int s = strokePitch * y + x; + m_buf[d + 1] = bmStrokeGlyph->bitmap.buffer[s]; // alpha + } + } + + // now the normal glyph into the luminance channel + for (int y = 0; y < rows; y++) { + for (int x = 0; x < pitch; x++) { + const int d = ALIGN(strokePitch * 2, 4) * (y + yoff) + (x + xoff) * 2; + const int s = pitch * y + x; + m_buf[d] = bmGlyph->bitmap.buffer[s]; // luminance + } + } + + glyph.width = bmStrokeGlyph->bitmap.width; + glyph.height = bmStrokeGlyph->bitmap.rows; + glyph.offX = bmStrokeGlyph->left; + glyph.offY = bmStrokeGlyph->top; + glyph.offU = float(m_atlasU) / float(ATLAS_SIZE); + glyph.offV = float(m_atlasV) / float(ATLAS_SIZE); + glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE); + glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE); + + m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat); + + m_atlasU += bmStrokeGlyph->bitmap.width; + FT_Done_Glyph(strokeGlyph); - return Glyph(); - } - - const int pitch = bmGlyph->bitmap.pitch; - const int rows = bmGlyph->bitmap.rows; - const int strokePitch = bmStrokeGlyph->bitmap.pitch; - const int strokeRows = bmStrokeGlyph->bitmap.rows; - - const int xoff = (bmStrokeGlyph->bitmap.width - bmGlyph->bitmap.width) / 2; - const int yoff = (bmStrokeGlyph->bitmap.rows - bmGlyph->bitmap.rows) / 2; - - // make enough space for both glyphs including offset - m_buf.resize(ALIGN(strokePitch,4)*strokeRows*2); - std::fill(m_buf.begin(), m_buf.end(), 0); - - // stroke first into the alpha channel - for (int y = 0; y < strokeRows; y++) { - for (int x = 0; x < strokePitch; x++) { - const int d = ALIGN(strokePitch*2,4)*y+x*2; - const int s = strokePitch*y+x; - m_buf[d+1] = bmStrokeGlyph->bitmap.buffer[s]; // alpha + } else { + //don't run off atlas borders + m_atlasVIncrement = std::max(m_atlasVIncrement, static_cast(bmGlyph->bitmap.rows)); + if (m_atlasU + static_cast(bmGlyph->bitmap.width) >= ATLAS_SIZE) { + m_atlasU = 0; + m_atlasV += m_atlasVIncrement; + m_atlasVIncrement = 0; } - } - // now the normal glyph into the luminance channel - for (int y = 0; y < rows; y++) { - for (int x = 0; x < pitch; x++) { - const int d = ALIGN(strokePitch*2,4)*(y+yoff)+(x+xoff)*2; - const int s = pitch*y+x; - m_buf[d] = bmGlyph->bitmap.buffer[s]; // luminance + if (m_atlasV + bmGlyph->bitmap.rows > ATLAS_SIZE) { + char utf8buf[8]; + int len = utf8_encode_char(chr, utf8buf); + utf8buf[len] = '\0'; + Output("glyph doesn't fit in atlas (U+%04X; height = %d; char: %s; atlasV = %d)\n", chr, bmGlyph->bitmap.rows, utf8buf, m_atlasV); + return Glyph(); } + + // draw the glyph into the draw buffer + const int pitch = bmGlyph->bitmap.pitch; + const int rows = bmGlyph->bitmap.rows; + m_buf.resize(ALIGN(pitch, 4) * rows); + std::fill(m_buf.begin(), m_buf.end(), 0); + for (int y = 0; y < rows; y++) + memcpy(&m_buf[ALIGN(pitch, 4) * y], &(bmGlyph->bitmap.buffer[pitch * y]), pitch); + + glyph.width = bmGlyph->bitmap.width; + glyph.height = bmGlyph->bitmap.rows; + glyph.offX = bmGlyph->left; + glyph.offY = bmGlyph->top; + glyph.offU = float(m_atlasU) / float(ATLAS_SIZE); + glyph.offV = float(m_atlasV) / float(ATLAS_SIZE); + glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE); + glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE); + + m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat); + + m_atlasU += glyph.width; } - glyph.width = bmStrokeGlyph->bitmap.width; - glyph.height = bmStrokeGlyph->bitmap.rows; - glyph.offX = bmStrokeGlyph->left; - glyph.offY = bmStrokeGlyph->top; - glyph.offU = float(m_atlasU) / float(ATLAS_SIZE); - glyph.offV = float(m_atlasV) / float(ATLAS_SIZE); - glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE); - glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE); + FT_Done_Glyph(ftGlyph); - m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat); - - m_atlasU += bmStrokeGlyph->bitmap.width; - - FT_Done_Glyph(strokeGlyph); + return glyph; } - else + + TextureFont::TextureFont(const FontConfig &config, Graphics::Renderer *renderer, float scale) : + m_config(config), + m_renderer(renderer), + m_scale(scale), + m_ftLib(nullptr), + m_stroker(nullptr), + m_atlasU(0), + m_atlasV(0), + m_atlasVIncrement(0), + m_lfLastCacheCleanTime(0.0) { - //don't run off atlas borders - m_atlasVIncrement = std::max(m_atlasVIncrement, static_cast(bmGlyph->bitmap.rows)); - if (m_atlasU + static_cast(bmGlyph->bitmap.width) >= ATLAS_SIZE) { - m_atlasU = 0; - m_atlasV += m_atlasVIncrement; - m_atlasVIncrement = 0; - } + renderer->CheckRenderErrors(__FUNCTION__, __LINE__); - if (m_atlasV + bmGlyph->bitmap.rows > ATLAS_SIZE) { - char utf8buf[8]; - int len = utf8_encode_char(chr, utf8buf); - utf8buf[len] = '\0'; - Output("glyph doesn't fit in atlas (U+%04X; height = %d; char: %s; atlasV = %d)\n", chr, bmGlyph->bitmap.rows, utf8buf, m_atlasV); - return Glyph(); - } + FT_Error err; // used to store freetype error return codes - // draw the glyph into the draw buffer - const int pitch = bmGlyph->bitmap.pitch; - const int rows = bmGlyph->bitmap.rows; - m_buf.resize(ALIGN(pitch,4)*rows); - std::fill(m_buf.begin(), m_buf.end(), 0); - for (int y = 0; y < rows; y++) - memcpy(&m_buf[ALIGN(pitch,4)*y], &(bmGlyph->bitmap.buffer[pitch*y]), pitch); - - glyph.width = bmGlyph->bitmap.width; - glyph.height = bmGlyph->bitmap.rows; - glyph.offX = bmGlyph->left; - glyph.offY = bmGlyph->top; - glyph.offU = float(m_atlasU) / float(ATLAS_SIZE); - glyph.offV = float(m_atlasV) / float(ATLAS_SIZE); - glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE); - glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE); - - m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat); - - m_atlasU += glyph.width; - } - - FT_Done_Glyph(ftGlyph); - - return glyph; -} - -TextureFont::TextureFont(const FontConfig &config, Graphics::Renderer *renderer, float scale) - : m_config(config) - , m_renderer(renderer) - , m_scale(scale) - , m_ftLib(nullptr) - , m_stroker(nullptr) - , m_atlasU(0) - , m_atlasV(0) - , m_atlasVIncrement(0) - , m_lfLastCacheCleanTime(0.0) -{ - renderer->CheckRenderErrors(__FUNCTION__,__LINE__); - - FT_Error err; // used to store freetype error return codes - - err = FT_Init_FreeType(&m_ftLib); - if (err != 0) { - Output("Couldn't create FreeType library context (%d)\n", err); - abort(); - } - - if (m_config.IsOutline()) { - if (FT_Stroker_New(m_ftLib, &m_stroker)) { - Output("Freetype stroker init error\n"); + err = FT_Init_FreeType(&m_ftLib); + if (err != 0) { + Output("Couldn't create FreeType library context (%d)\n", err); abort(); } - //1*64 = stroke width - FT_Stroker_Set(m_stroker, 1*64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + if (m_config.IsOutline()) { + if (FT_Stroker_New(m_ftLib, &m_stroker)) { + Output("Freetype stroker init error\n"); + abort(); + } + + //1*64 = stroke width + FT_Stroker_Set(m_stroker, 1 * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + } + + renderer->CheckRenderErrors(__FUNCTION__, __LINE__); + + m_texFormat = m_config.IsOutline() ? Graphics::TEXTURE_LUMINANCE_ALPHA_88 : Graphics::TEXTURE_INTENSITY_8; + m_bpp = m_config.IsOutline() ? 2 : 1; + + renderer->CheckRenderErrors(__FUNCTION__, __LINE__); + + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA_PREMULT; + rsd.depthWrite = false; + m_renderState = m_renderer->CreateRenderState(rsd); + + Graphics::MaterialDescriptor desc; + desc.effect = Graphics::EFFECT_UI; + desc.vertexColors = true; //to allow per-character colors + desc.textures = 1; + m_mat.reset(m_renderer->CreateMaterial(desc)); + Graphics::TextureDescriptor textureDescriptor(m_texFormat, vector2f(ATLAS_SIZE), Graphics::NEAREST_CLAMP, false, false, false, 0, Graphics::TEXTURE_2D); + m_texture.Reset(m_renderer->CreateTexture(textureDescriptor)); + { + const size_t sz = m_bpp * ATLAS_SIZE * ATLAS_SIZE; + char *buf = static_cast(malloc(sz)); + memset(buf, 0, sz); + m_texture->Update(buf, vector2f(0.0f, 0.0f), vector2f(ATLAS_SIZE, ATLAS_SIZE), m_texFormat); + free(buf); + } + m_mat->texture0 = m_texture.Get(); + + // font-wide metrics. we assume that these match for all faces + // XXX loop all the faces and take the min/max as appropriate + FT_Face ftFace = GetFTFace(m_config.GetFaceForCodePoint(0x20)); + m_height = float(ftFace->height) / 64.f * float(ftFace->size->metrics.y_scale) / 65536.f; + m_descender = -float(ftFace->descender) / 64.f * float(ftFace->size->metrics.y_scale) / 65536.f; } - renderer->CheckRenderErrors(__FUNCTION__,__LINE__); - - m_texFormat = m_config.IsOutline() ? Graphics::TEXTURE_LUMINANCE_ALPHA_88 : Graphics::TEXTURE_INTENSITY_8; - m_bpp = m_config.IsOutline() ? 2 : 1; - - renderer->CheckRenderErrors(__FUNCTION__,__LINE__); - - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA_PREMULT; - rsd.depthWrite = false; - m_renderState = m_renderer->CreateRenderState(rsd); - - Graphics::MaterialDescriptor desc; - desc.effect = Graphics::EFFECT_UI; - desc.vertexColors = true; //to allow per-character colors - desc.textures = 1; - m_mat.reset(m_renderer->CreateMaterial(desc)); - Graphics::TextureDescriptor textureDescriptor(m_texFormat, vector2f(ATLAS_SIZE), Graphics::NEAREST_CLAMP, false, false, false, 0, Graphics::TEXTURE_2D); - m_texture.Reset(m_renderer->CreateTexture(textureDescriptor)); + TextureFont::~TextureFont() { - const size_t sz = m_bpp * ATLAS_SIZE * ATLAS_SIZE; - char *buf = static_cast(malloc(sz)); - memset(buf, 0, sz); - m_texture->Update(buf, vector2f(0.0f, 0.0f), vector2f(ATLAS_SIZE, ATLAS_SIZE), m_texFormat); - free(buf); + for (auto i = m_faces.begin(); i != m_faces.end(); ++i) + FT_Done_Face((*i).second.first); + if (m_stroker) + FT_Stroker_Done(m_stroker); + FT_Done_FreeType(m_ftLib); } - m_mat->texture0 = m_texture.Get(); - // font-wide metrics. we assume that these match for all faces - // XXX loop all the faces and take the min/max as appropriate - FT_Face ftFace = GetFTFace(m_config.GetFaceForCodePoint(0x20)); - m_height = float(ftFace->height) / 64.f * float(ftFace->size->metrics.y_scale) / 65536.f; - m_descender = -float(ftFace->descender) / 64.f * float(ftFace->size->metrics.y_scale) / 65536.f; -} - -TextureFont::~TextureFont() -{ - for (auto i = m_faces.begin(); i != m_faces.end(); ++i) - FT_Done_Face((*i).second.first); - if (m_stroker) - FT_Stroker_Done(m_stroker); - FT_Done_FreeType(m_ftLib); -} - -FT_Face TextureFont::GetFTFace(const FontConfig::Face &face) -{ + FT_Face TextureFont::GetFTFace(const FontConfig::Face &face) { - auto i = m_faces.find(face); - if (i != m_faces.end()) - return (*i).second.first; + { + auto i = m_faces.find(face); + if (i != m_faces.end()) + return (*i).second.first; + } + + RefCountedPtr fd; + + fd = FileSystem::gameDataFiles.ReadFile("fonts/" + face.fontFile); + if (!fd) { + Output("Terrible error! Couldn't load '%s'.\n", face.fontFile.c_str()); + abort(); + } + + FT_Face ftFace; + FT_Error err; + + if (0 != (err = FT_New_Memory_Face(m_ftLib, reinterpret_cast(fd->GetData()), fd->GetSize(), 0, &ftFace))) { + Output("Terrible error! Couldn't understand '%s'; error %d.\n", face.fontFile.c_str(), err); + abort(); + } + + FT_Set_Pixel_Sizes(ftFace, m_scale * face.pixelWidth, m_scale * face.pixelHeight); + + m_faces.insert(std::make_pair(face, std::make_pair(ftFace, fd))); + + return ftFace; } - RefCountedPtr fd; + float TextureFont::GetKern(const Glyph &a, const Glyph &b) + { + if (a.ftFace != b.ftFace) + return 0.0f; - fd = FileSystem::gameDataFiles.ReadFile("fonts/" + face.fontFile); - if (!fd) { - Output("Terrible error! Couldn't load '%s'.\n", face.fontFile.c_str()); - abort(); + FT_Vector kern; + FT_Get_Kerning(a.ftFace, a.ftIndex, b.ftIndex, FT_KERNING_UNFITTED, &kern); + return float(kern.x) / 64.0f; } - FT_Face ftFace; - FT_Error err; - - if (0 != (err = FT_New_Memory_Face(m_ftLib, - reinterpret_cast(fd->GetData()), - fd->GetSize(), 0, &ftFace))) { - Output("Terrible error! Couldn't understand '%s'; error %d.\n", face.fontFile.c_str(), err); - abort(); - } - - FT_Set_Pixel_Sizes(ftFace, m_scale*face.pixelWidth, m_scale*face.pixelHeight); - - m_faces.insert(std::make_pair(face, std::make_pair(ftFace, fd))); - - return ftFace; -} - -float TextureFont::GetKern(const Glyph &a, const Glyph &b) -{ - if (a.ftFace != b.ftFace) - return 0.0f; - - FT_Vector kern; - FT_Get_Kerning(a.ftFace, a.ftIndex, b.ftIndex, FT_KERNING_UNFITTED, &kern); - return float(kern.x) / 64.0f; -} - -} +} // namespace Text diff --git a/src/text/TextureFont.h b/src/text/TextureFont.h index d5fcc2c7e..988976b5b 100644 --- a/src/text/TextureFont.h +++ b/src/text/TextureFont.h @@ -4,17 +4,19 @@ #ifndef _TEXT_TEXTUREFONT_H #define _TEXT_TEXTUREFONT_H -#include "libs.h" #include "FontConfig.h" #include "RefCounted.h" -#include "graphics/Texture.h" #include "graphics/Material.h" -#include "graphics/VertexBuffer.h" #include "graphics/RenderState.h" +#include "graphics/Texture.h" +#include "graphics/VertexBuffer.h" +#include "libs.h" #include -namespace FileSystem { class FileData; } +namespace FileSystem { + class FileData; +} // forward declarations for FreeType types struct FT_FaceRec_; @@ -26,96 +28,108 @@ typedef struct FT_StrokerRec_ *FT_Stroker; namespace Text { -class TextureFont : public RefCounted { + class TextureFont : public RefCounted { -public: - TextureFont(const FontConfig &config, Graphics::Renderer *renderer, float scale = 1.0f); - ~TextureFont(); + public: + TextureFont(const FontConfig &config, Graphics::Renderer *renderer, float scale = 1.0f); + ~TextureFont(); - void RenderBuffer(Graphics::VertexBuffer *vb, const Color &color = Color::WHITE); - void MeasureString(const std::string &str, float &w, float &h); - void MeasureCharacterPos(const std::string &str, int charIndex, float &x, float &y); - int PickCharacter(const std::string &str, float mouseX, float mouseY); + void RenderBuffer(Graphics::VertexBuffer *vb, const Color &color = Color::WHITE); + void MeasureString(const std::string &str, float &w, float &h); + void MeasureCharacterPos(const std::string &str, int charIndex, float &x, float &y); + int PickCharacter(const std::string &str, float mouseX, float mouseY); - void PopulateString(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color = Color::WHITE); - Color PopulateMarkup(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color = Color::WHITE); - Graphics::VertexBuffer* CreateVertexBuffer(const Graphics::VertexArray &va, const bool bIsStatic) const; - Graphics::VertexBuffer* CreateVertexBuffer(const Graphics::VertexArray &va, const std::string &str, const bool bIsStatic); - Graphics::VertexBuffer* GetCachedVertexBuffer(const std::string &str); + void PopulateString(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color = Color::WHITE); + Color PopulateMarkup(Graphics::VertexArray &va, const std::string &str, const float x, const float y, const Color &color = Color::WHITE); + Graphics::VertexBuffer *CreateVertexBuffer(const Graphics::VertexArray &va, const bool bIsStatic) const; + Graphics::VertexBuffer *CreateVertexBuffer(const Graphics::VertexArray &va, const std::string &str, const bool bIsStatic); + Graphics::VertexBuffer *GetCachedVertexBuffer(const std::string &str); - // general baseline-to-baseline height - float GetHeight() const { return m_height; } - // general descender height - float GetDescender() const { return m_descender; } + // general baseline-to-baseline height + float GetHeight() const { return m_height; } + // general descender height + float GetDescender() const { return m_descender; } - struct Glyph { - Glyph() : advX(0), advY(0), width(0), height(0), texWidth(0), texHeight(0), offX(0), offY(0), offU(0), offV(0), ftFace(nullptr), ftIndex(0) {} - float advX, advY; - float width, height; - float texWidth, texHeight; - int offX, offY; - float offU, offV; //atlas UV offset - FT_Face ftFace; - Uint32 ftIndex; + struct Glyph { + Glyph() : + advX(0), + advY(0), + width(0), + height(0), + texWidth(0), + texHeight(0), + offX(0), + offY(0), + offU(0), + offV(0), + ftFace(nullptr), + ftIndex(0) {} + float advX, advY; + float width, height; + float texWidth, texHeight; + int offX, offY; + float offU, offV; //atlas UV offset + FT_Face ftFace; + Uint32 ftIndex; + }; + const Glyph &GetGlyph(Uint32 ch); + + static int GetGlyphCount() { return s_glyphCount; } + static void ClearGlyphCount() { s_glyphCount = 0; } + + RefCountedPtr GetTexture() const { return m_texture; } + Graphics::Material *GetMaterial() const { return m_mat.get(); } + + private: + TextureFont(const TextureFont &); + TextureFont &operator=(const TextureFont &); + + void AddCachedVertexBuffer(Graphics::VertexBuffer *pVB, const std::string &str); + Uint32 CleanVertexBufferCache(); + + FontConfig m_config; + Graphics::Renderer *m_renderer; + float m_scale; + + FT_Library m_ftLib; + FT_Stroker m_stroker; + + FT_Face GetFTFace(const FontConfig::Face &face); + std::map>> m_faces; + + Glyph BakeGlyph(Uint32 chr); + + float GetKern(const Glyph &a, const Glyph &b); + + void AddGlyphGeometry(Graphics::VertexArray &va, const Glyph &glyph, const float x, const float y, const Color &color); + float m_height; + float m_descender; + std::unique_ptr m_mat; + Graphics::RenderState *m_renderState; + + static int s_glyphCount; + + std::map m_glyphs; + + // UV offsets for glyphs + unsigned int m_atlasU; + unsigned int m_atlasV; + unsigned int m_atlasVIncrement; + + RefCountedPtr m_texture; + Graphics::TextureFormat m_texFormat; + + std::vector m_buf; + int m_bufWidth, m_bufHeight; + int m_bpp; + + typedef std::unordered_map>> VBHashMap; + typedef VBHashMap::iterator VBHashMapIter; + typedef VBHashMap::const_iterator VBHashMapConstIter; + VBHashMap m_vbTextCache; + double m_lfLastCacheCleanTime; }; - const Glyph &GetGlyph(Uint32 ch); - static int GetGlyphCount() { return s_glyphCount; } - static void ClearGlyphCount() { s_glyphCount = 0; } - - RefCountedPtr GetTexture() const { return m_texture; } - Graphics::Material* GetMaterial() const { return m_mat.get(); } - -private: - TextureFont(const TextureFont &); - TextureFont &operator=(const TextureFont &); - - void AddCachedVertexBuffer(Graphics::VertexBuffer *pVB, const std::string &str); - Uint32 CleanVertexBufferCache(); - - FontConfig m_config; - Graphics::Renderer *m_renderer; - float m_scale; - - FT_Library m_ftLib; - FT_Stroker m_stroker; - - FT_Face GetFTFace(const FontConfig::Face &face); - std::map>> m_faces; - - Glyph BakeGlyph(Uint32 chr); - - float GetKern(const Glyph &a, const Glyph &b); - - void AddGlyphGeometry(Graphics::VertexArray &va, const Glyph &glyph, const float x, const float y, const Color &color); - float m_height; - float m_descender; - std::unique_ptr m_mat; - Graphics::RenderState *m_renderState; - - static int s_glyphCount; - - std::map m_glyphs; - - // UV offsets for glyphs - unsigned int m_atlasU; - unsigned int m_atlasV; - unsigned int m_atlasVIncrement; - - RefCountedPtr m_texture; - Graphics::TextureFormat m_texFormat; - - std::vector m_buf; - int m_bufWidth, m_bufHeight; - int m_bpp; - - typedef std::unordered_map>> VBHashMap; - typedef VBHashMap::iterator VBHashMapIter; - typedef VBHashMap::const_iterator VBHashMapConstIter; - VBHashMap m_vbTextCache; - double m_lfLastCacheCleanTime; -}; - -} +} // namespace Text #endif diff --git a/src/textstress.cpp b/src/textstress.cpp index 52750546f..1e965ddf2 100644 --- a/src/textstress.cpp +++ b/src/textstress.cpp @@ -1,16 +1,16 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include -#include "SDL.h" #include "FileSystem.h" #include "OS.h" +#include "SDL.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" #include "text/FontDescriptor.h" #include "text/TextureFont.h" +#include -static const int WIDTH = 1024; +static const int WIDTH = 1024; static const int HEIGHT = 768; int main(int argc, char **argv) @@ -61,7 +61,7 @@ int main(int argc, char **argv) if (done) break; - font->RenderString(str.c_str(), rand()%(WIDTH*2)-WIDTH, rand()%HEIGHT, Color::WHITE); + font->RenderString(str.c_str(), rand() % (WIDTH * 2) - WIDTH, rand() % HEIGHT, Color::WHITE); r->SwapBuffers(); } diff --git a/src/ui/Align.cpp b/src/ui/Align.cpp index eb62c4b89..d9e3f195a 100644 --- a/src/ui/Align.cpp +++ b/src/ui/Align.cpp @@ -5,22 +5,22 @@ namespace UI { -Point Align::PreferredSize() -{ - if (!GetInnerWidget()) return Point(); - return GetInnerWidget()->PreferredSize(); -} + Point Align::PreferredSize() + { + if (!GetInnerWidget()) return Point(); + return GetInnerWidget()->PreferredSize(); + } -void Align::Layout() -{ - if (!GetInnerWidget()) return; + void Align::Layout() + { + if (!GetInnerWidget()) return; - const Point &size = GetSize(); - const Point preferred(GetInnerWidget()->CalcLayoutContribution()); + const Point &size = GetSize(); + const Point preferred(GetInnerWidget()->CalcLayoutContribution()); - Point pos; + Point pos; - switch (m_direction) { + switch (m_direction) { case TOP_LEFT: case LEFT: case BOTTOM_LEFT: @@ -30,17 +30,17 @@ void Align::Layout() case TOP: case MIDDLE: case BOTTOM: - pos.x = std::max(0, (size.x-preferred.x)/2); + pos.x = std::max(0, (size.x - preferred.x) / 2); break; case TOP_RIGHT: case RIGHT: case BOTTOM_RIGHT: - pos.x = std::max(0, size.x-preferred.x); + pos.x = std::max(0, size.x - preferred.x); break; - } + } - switch (m_direction) { + switch (m_direction) { case TOP_LEFT: case TOP: case TOP_RIGHT: @@ -50,18 +50,18 @@ void Align::Layout() case LEFT: case MIDDLE: case RIGHT: - pos.y = std::max(0, (size.y-preferred.y)/2); + pos.y = std::max(0, (size.y - preferred.y) / 2); break; case BOTTOM_LEFT: case BOTTOM: case BOTTOM_RIGHT: - pos.y = std::max(0, size.y-preferred.y); + pos.y = std::max(0, size.y - preferred.y); break; + } + + SetWidgetDimensions(GetInnerWidget(), pos, Point(std::min(size.x, preferred.x), std::min(size.y, preferred.y))); + GetInnerWidget()->Layout(); } - SetWidgetDimensions(GetInnerWidget(), pos, Point(std::min(size.x, preferred.x), std::min(size.y, preferred.y))); - GetInnerWidget()->Layout(); -} - -} +} // namespace UI diff --git a/src/ui/Align.h b/src/ui/Align.h index 8867f6654..5cfa375cf 100644 --- a/src/ui/Align.h +++ b/src/ui/Align.h @@ -8,31 +8,33 @@ namespace UI { -class Align : public Single { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class Align : public Single { + public: + virtual Point PreferredSize(); + virtual void Layout(); - enum Direction { // - TOP_LEFT, - TOP, - TOP_RIGHT, - LEFT, - MIDDLE, - RIGHT, - BOTTOM_LEFT, - BOTTOM, - BOTTOM_RIGHT + enum Direction { // + TOP_LEFT, + TOP, + TOP_RIGHT, + LEFT, + MIDDLE, + RIGHT, + BOTTOM_LEFT, + BOTTOM, + BOTTOM_RIGHT + }; + + protected: + friend class Context; + Align(Context *context, Direction direction) : + Single(context), + m_direction(direction) {} + + private: + Direction m_direction; }; -protected: - friend class Context; - Align(Context *context, Direction direction) : Single(context), m_direction(direction) {} - -private: - Direction m_direction; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Animation.cpp b/src/ui/Animation.cpp index dc27b8cb8..b53ba6d6c 100644 --- a/src/ui/Animation.cpp +++ b/src/ui/Animation.cpp @@ -5,101 +5,101 @@ namespace UI { -Animation::Animation(Widget *widget, Type type, Easing easing, Target target, float duration, bool continuous, Animation *next, sigc::slot callback) : - m_widget(widget), - m_type(type), - m_easing(easing), - m_target(target), - m_duration(duration), - m_continuous(continuous), - m_next(next), - m_callback(callback), - m_running(false), - m_completed(false) -{ - SelectFunctions(); -} + Animation::Animation(Widget *widget, Type type, Easing easing, Target target, float duration, bool continuous, Animation *next, sigc::slot callback) : + m_widget(widget), + m_type(type), + m_easing(easing), + m_target(target), + m_duration(duration), + m_continuous(continuous), + m_next(next), + m_callback(callback), + m_running(false), + m_completed(false) + { + SelectFunctions(); + } -static float easingZero(float t, float b, float c, float d) -{ - return 0.0f; -} + static float easingZero(float t, float b, float c, float d) + { + return 0.0f; + } -static float easingOne(float t, float b, float c, float d) -{ - return 1.0f; -} + static float easingOne(float t, float b, float c, float d) + { + return 1.0f; + } -static float easeIn(::Easing::Function::Type easingFunc, float t, float d) -{ - return easingFunc(t, 0.0f, 1.0f, d); -} + static float easeIn(::Easing::Function::Type easingFunc, float t, float d) + { + return easingFunc(t, 0.0f, 1.0f, d); + } -static float easeOut(::Easing::Function::Type easingFunc, float t, float d) -{ - return 1.0f-easingFunc(t, 0.0f, 1.0f, d); -} + static float easeOut(::Easing::Function::Type easingFunc, float t, float d) + { + return 1.0f - easingFunc(t, 0.0f, 1.0f, d); + } -static float easeInOut(::Easing::Function::Type easingFunc, float t, float d) -{ - return 1.0f-fabsf(easingFunc(t, -1.0, 2.0, d)); -} + static float easeInOut(::Easing::Function::Type easingFunc, float t, float d) + { + return 1.0f - fabsf(easingFunc(t, -1.0, 2.0, d)); + } -void Animation::TargetPause(const float &pos) -{ -} + void Animation::TargetPause(const float &pos) + { + } -void Animation::TargetOpacity(const float &pos) -{ - m_widget->SetAnimatedOpacity(pos); -} + void Animation::TargetOpacity(const float &pos) + { + m_widget->SetAnimatedOpacity(pos); + } -void Animation::TargetPositionX(const float &pos) -{ - m_widget->SetAnimatedPositionX(pos); -} + void Animation::TargetPositionX(const float &pos) + { + m_widget->SetAnimatedPositionX(pos); + } -void Animation::TargetPositionY(const float &pos) -{ - m_widget->SetAnimatedPositionY(pos); -} + void Animation::TargetPositionY(const float &pos) + { + m_widget->SetAnimatedPositionY(pos); + } -void Animation::TargetPositionXRev(const float &pos) -{ - m_widget->SetAnimatedPositionX(-pos); -} + void Animation::TargetPositionXRev(const float &pos) + { + m_widget->SetAnimatedPositionX(-pos); + } -void Animation::TargetPositionYRev(const float &pos) -{ - m_widget->SetAnimatedPositionY(-pos); -} + void Animation::TargetPositionYRev(const float &pos) + { + m_widget->SetAnimatedPositionY(-pos); + } -void Animation::SelectFunctions() -{ - switch (m_target) { - case TARGET_PAUSE: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPause); break; - case TARGET_OPACITY: m_targetFunc = sigc::mem_fun(this, &Animation::TargetOpacity); break; - case TARGET_POSITION_X: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionX); break; - case TARGET_POSITION_Y: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionY); break; + void Animation::SelectFunctions() + { + switch (m_target) { + case TARGET_PAUSE: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPause); break; + case TARGET_OPACITY: m_targetFunc = sigc::mem_fun(this, &Animation::TargetOpacity); break; + case TARGET_POSITION_X: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionX); break; + case TARGET_POSITION_Y: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionY); break; case TARGET_POSITION_X_REV: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionXRev); break; case TARGET_POSITION_Y_REV: m_targetFunc = sigc::mem_fun(this, &Animation::TargetPositionYRev); break; - } - assert(m_targetFunc); + } + assert(m_targetFunc); - switch (m_type) { + switch (m_type) { case TYPE_IN: { m_wrapFunc = easeIn; switch (m_easing) { - case EASING_ZERO: m_easingFunc = easingZero; return; - case EASING_ONE: m_easingFunc = easingOne; return; - case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseIn; return; - case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseIn; return; - case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseIn; return; - case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseIn; return; - case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseIn; return; - case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseIn; return; - case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseIn; return; - case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseIn; return; + case EASING_ZERO: m_easingFunc = easingZero; return; + case EASING_ONE: m_easingFunc = easingOne; return; + case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseIn; return; + case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseIn; return; + case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseIn; return; + case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseIn; return; + case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseIn; return; + case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseIn; return; + case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseIn; return; + case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseIn; return; } assert(m_easingFunc); return; @@ -108,16 +108,16 @@ void Animation::SelectFunctions() case TYPE_OUT: { m_wrapFunc = easeOut; switch (m_easing) { - case EASING_ZERO: m_easingFunc = easingZero; return; - case EASING_ONE: m_easingFunc = easingOne; return; - case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseOut; return; - case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseOut; return; - case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseOut; return; - case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseOut; return; - case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseOut; return; - case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseOut; return; - case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseOut; return; - case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseOut; return; + case EASING_ZERO: m_easingFunc = easingZero; return; + case EASING_ONE: m_easingFunc = easingOne; return; + case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseOut; return; + case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseOut; return; + case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseOut; return; + case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseOut; return; + case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseOut; return; + case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseOut; return; + case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseOut; return; + case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseOut; return; } assert(m_easingFunc); return; @@ -126,90 +126,89 @@ void Animation::SelectFunctions() case TYPE_IN_OUT: { m_wrapFunc = easeInOut; switch (m_easing) { - case EASING_ZERO: m_easingFunc = easingZero; return; - case EASING_ONE: m_easingFunc = easingOne; return; - case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseInOut; return; - case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseInOut; return; - case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseInOut; return; - case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseInOut; return; - case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseInOut; return; - case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseInOut; return; - case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseInOut; return; - case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseInOut; return; + case EASING_ZERO: m_easingFunc = easingZero; return; + case EASING_ONE: m_easingFunc = easingOne; return; + case EASING_LINEAR: m_easingFunc = ::Easing::Linear::EaseInOut; return; + case EASING_QUAD: m_easingFunc = ::Easing::Quad::EaseInOut; return; + case EASING_CUBIC: m_easingFunc = ::Easing::Cubic::EaseInOut; return; + case EASING_QUART: m_easingFunc = ::Easing::Quart::EaseInOut; return; + case EASING_QUINT: m_easingFunc = ::Easing::Quint::EaseInOut; return; + case EASING_SINE: m_easingFunc = ::Easing::Sine::EaseInOut; return; + case EASING_EXPO: m_easingFunc = ::Easing::Expo::EaseInOut; return; + case EASING_CIRC: m_easingFunc = ::Easing::Circ::EaseInOut; return; } assert(m_easingFunc); return; } - } - - assert(m_easingFunc); -} - -float Animation::Update(float time) -{ - PROFILE_SCOPED(); - if (m_completed) - return 0.0f; - - const float remaining = m_continuous ? m_duration : (m_duration - time); - m_completed = remaining < 0.0f; - - float pos; - if (m_continuous) - pos = m_completed ? m_duration : fmodf(time, m_duration); - else - pos = m_completed ? m_duration : Clamp(time, 0.0f, m_duration); - - m_targetFunc(m_wrapFunc(m_easingFunc, pos, m_duration)); - - m_running = !m_completed; - - if (m_completed && m_callback) - m_callback(); - - return remaining; -} - -void Animation::Finish() -{ - if (m_completed) return; - m_targetFunc(1.0f); - m_running = false; - m_completed = true; -} - -void AnimationController::Add(Animation *animation) -{ - assert(!animation->IsRunning()); - m_animations.push_back(std::make_pair(RefCountedPtr(animation), SDL_GetTicks())); - animation->Running(); -} - -void AnimationController::Update() -{ - PROFILE_SCOPED(); - const Uint32 now = SDL_GetTicks(); - - for (auto i = m_animations.begin(); i != m_animations.end();) { - Animation *animation = (*i).first.Get(); - Uint32 start = (*i).second; - - float remaining = 0.0f; - if (!animation->IsCompleted()) - remaining = animation->Update(float(now-start)/1000.f); - - if (animation->IsCompleted()) { - Animation *nextAnimation = animation->GetNext(); - if (nextAnimation) { - assert(!animation->IsRunning()); - m_animations.push_back(std::make_pair(RefCountedPtr(nextAnimation), now-Uint32(-remaining*1000.0f))); - nextAnimation->Running(); - } - m_animations.erase(i++); } - else - ++i; - } -} -} + assert(m_easingFunc); + } + + float Animation::Update(float time) + { + PROFILE_SCOPED(); + if (m_completed) + return 0.0f; + + const float remaining = m_continuous ? m_duration : (m_duration - time); + m_completed = remaining < 0.0f; + + float pos; + if (m_continuous) + pos = m_completed ? m_duration : fmodf(time, m_duration); + else + pos = m_completed ? m_duration : Clamp(time, 0.0f, m_duration); + + m_targetFunc(m_wrapFunc(m_easingFunc, pos, m_duration)); + + m_running = !m_completed; + + if (m_completed && m_callback) + m_callback(); + + return remaining; + } + + void Animation::Finish() + { + if (m_completed) return; + m_targetFunc(1.0f); + m_running = false; + m_completed = true; + } + + void AnimationController::Add(Animation *animation) + { + assert(!animation->IsRunning()); + m_animations.push_back(std::make_pair(RefCountedPtr(animation), SDL_GetTicks())); + animation->Running(); + } + + void AnimationController::Update() + { + PROFILE_SCOPED(); + const Uint32 now = SDL_GetTicks(); + + for (auto i = m_animations.begin(); i != m_animations.end();) { + Animation *animation = (*i).first.Get(); + Uint32 start = (*i).second; + + float remaining = 0.0f; + if (!animation->IsCompleted()) + remaining = animation->Update(float(now - start) / 1000.f); + + if (animation->IsCompleted()) { + Animation *nextAnimation = animation->GetNext(); + if (nextAnimation) { + assert(!animation->IsRunning()); + m_animations.push_back(std::make_pair(RefCountedPtr(nextAnimation), now - Uint32(-remaining * 1000.0f))); + nextAnimation->Running(); + } + m_animations.erase(i++); + } else + ++i; + } + } + +} // namespace UI diff --git a/src/ui/Animation.h b/src/ui/Animation.h index d0e1e7d4f..f2c482772 100644 --- a/src/ui/Animation.h +++ b/src/ui/Animation.h @@ -4,94 +4,94 @@ #ifndef UI_ANIMATION_H #define UI_ANIMATION_H -#include "libs.h" +#include "Easing.h" #include "RefCounted.h" #include "Widget.h" -#include "Easing.h" +#include "libs.h" namespace UI { -class Animation : public RefCounted { -public: - enum Type { // - TYPE_IN, - TYPE_OUT, - TYPE_IN_OUT, + class Animation : public RefCounted { + public: + enum Type { // + TYPE_IN, + TYPE_OUT, + TYPE_IN_OUT, + }; + + enum Easing { // + EASING_ZERO, + EASING_ONE, + EASING_LINEAR, + EASING_QUAD, + EASING_CUBIC, + EASING_QUART, + EASING_QUINT, + EASING_SINE, + EASING_EXPO, + EASING_CIRC, + }; + + enum Target { // + TARGET_PAUSE, + TARGET_OPACITY, + TARGET_POSITION_X, + TARGET_POSITION_Y, + TARGET_POSITION_X_REV, + TARGET_POSITION_Y_REV + }; + + Animation(Widget *widget, Type type, Easing easing, Target target, float duration = 1.0f, bool continuous = false, Animation *next = nullptr, sigc::slot callback = sigc::slot()); + Animation *GetNext() const { return m_next.Get(); } + void SetNext(Animation *next) { m_next.Reset(next); } + + float Update(float time); + + void Finish(); + + bool IsRunning() const { return m_running; } + bool IsCompleted() const { return m_completed; } + + private: + RefCountedPtr m_widget; + Type m_type; + Easing m_easing; + Target m_target; + float m_duration; + bool m_continuous; + RefCountedPtr m_next; + sigc::slot m_callback; + + void TargetPause(const float &pos); + void TargetOpacity(const float &pos); + void TargetPositionX(const float &pos); + void TargetPositionY(const float &pos); + void TargetPositionXRev(const float &pos); + void TargetPositionYRev(const float &pos); + + void SelectFunctions(); + ::Easing::Function::Type m_easingFunc; + float (*m_wrapFunc)(::Easing::Function::Type easingFunc, float t, float d); + sigc::slot m_targetFunc; + + // AnimationController needs to set the running flag when the anim starts + friend class AnimationController; + void Running() { m_running = true; } + + bool m_running; + bool m_completed; }; - enum Easing { // - EASING_ZERO, - EASING_ONE, - EASING_LINEAR, - EASING_QUAD, - EASING_CUBIC, - EASING_QUART, - EASING_QUINT, - EASING_SINE, - EASING_EXPO, - EASING_CIRC, + class AnimationController { + public: + void Add(Animation *animation); + + void Update(); + + private: + std::list, Uint32>> m_animations; }; - enum Target { // - TARGET_PAUSE, - TARGET_OPACITY, - TARGET_POSITION_X, - TARGET_POSITION_Y, - TARGET_POSITION_X_REV, - TARGET_POSITION_Y_REV - }; - - Animation(Widget *widget, Type type, Easing easing, Target target, float duration = 1.0f, bool continuous = false, Animation *next = nullptr, sigc::slot callback = sigc::slot()); - Animation *GetNext() const { return m_next.Get(); } - void SetNext(Animation *next) { m_next.Reset(next); } - - float Update(float time); - - void Finish(); - - bool IsRunning() const { return m_running; } - bool IsCompleted() const { return m_completed; } - -private: - RefCountedPtr m_widget; - Type m_type; - Easing m_easing; - Target m_target; - float m_duration; - bool m_continuous; - RefCountedPtr m_next; - sigc::slot m_callback; - - void TargetPause(const float &pos); - void TargetOpacity(const float &pos); - void TargetPositionX(const float &pos); - void TargetPositionY(const float &pos); - void TargetPositionXRev(const float &pos); - void TargetPositionYRev(const float &pos); - - void SelectFunctions(); - ::Easing::Function::Type m_easingFunc; - float (*m_wrapFunc)(::Easing::Function::Type easingFunc, float t, float d); - sigc::slot m_targetFunc; - - // AnimationController needs to set the running flag when the anim starts - friend class AnimationController; - void Running() { m_running = true; } - - bool m_running; - bool m_completed; -}; - -class AnimationController { -public: - void Add(Animation *animation); - - void Update(); - -private: - std::list,Uint32>> m_animations; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Background.cpp b/src/ui/Background.cpp index a2afa607e..6a983f361 100644 --- a/src/ui/Background.cpp +++ b/src/ui/Background.cpp @@ -7,29 +7,29 @@ namespace UI { -Point Background::PreferredSize() -{ - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); - const Point borderSize(elem.borderWidth*2, elem.borderHeight*2); - if (!GetInnerWidget()) return borderSize; - Point preferredSize = SizeAdd(GetInnerWidget()->PreferredSize(), Point(elem.paddingX*2, elem.paddingY*2)); - preferredSize.x = std::max(preferredSize.x, borderSize.x); - preferredSize.y = std::max(preferredSize.y, borderSize.y); - return preferredSize; -} + Point Background::PreferredSize() + { + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); + const Point borderSize(elem.borderWidth * 2, elem.borderHeight * 2); + if (!GetInnerWidget()) return borderSize; + Point preferredSize = SizeAdd(GetInnerWidget()->PreferredSize(), Point(elem.paddingX * 2, elem.paddingY * 2)); + preferredSize.x = std::max(preferredSize.x, borderSize.x); + preferredSize.y = std::max(preferredSize.y, borderSize.y); + return preferredSize; + } -void Background::Layout() -{ - if (!GetInnerWidget()) return; - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); - SetWidgetDimensions(GetInnerWidget(), Point(elem.paddingX, elem.paddingY), GetSize()-Point(elem.paddingX*2, elem.paddingY*2)); - return GetInnerWidget()->Layout(); -} + void Background::Layout() + { + if (!GetInnerWidget()) return; + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); + SetWidgetDimensions(GetInnerWidget(), Point(elem.paddingX, elem.paddingY), GetSize() - Point(elem.paddingX * 2, elem.paddingY * 2)); + return GetInnerWidget()->Layout(); + } -void Background::Draw() -{ - GetContext()->GetSkin().DrawBackgroundNormal(Point(), GetSize()); - Single::Draw(); -} + void Background::Draw() + { + GetContext()->GetSkin().DrawBackgroundNormal(Point(), GetSize()); + Single::Draw(); + } -} +} // namespace UI diff --git a/src/ui/Background.h b/src/ui/Background.h index 4e91ef18a..ea6b2b93f 100644 --- a/src/ui/Background.h +++ b/src/ui/Background.h @@ -8,17 +8,18 @@ namespace UI { -class Background : public Single { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class Background : public Single { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); -protected: - friend class Context; - Background(Context *context) : Single(context) {} -}; + protected: + friend class Context; + Background(Context *context) : + Single(context) {} + }; -} +} // namespace UI #endif diff --git a/src/ui/Box.cpp b/src/ui/Box.cpp index d41a1451d..fc3916082 100644 --- a/src/ui/Box.cpp +++ b/src/ui/Box.cpp @@ -6,248 +6,245 @@ namespace UI { -static inline void GetComponentsForOrient(bool horiz, Point::Component &variableComponent, Point::Component &fixedComponent) -{ - if (horiz) { - variableComponent = Point::X; - fixedComponent = Point::Y; - } - else { - variableComponent = Point::Y; - fixedComponent = Point::X; - } -} - -Box::Box(Context *context, BoxOrientation orient, int spacing): - Container(context), - m_orient(orient), - m_spacing(context->GetScale() * spacing) -{} - -Point Box::PreferredSize() -{ - if (m_children.empty()) return Point(); - - Point::Component vc, fc; - GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); - - m_preferredSize = Point(0); - m_numVariable = 0; - - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - const Point contribSize = (*i).contribSize = (*i).widget->CalcLayoutContribution(); - - // if they're not contributing anything on the fixed axis then we need - // to defer their inclusion until we know the size of the fixed axis - // and can ask for their best size. otherwise we can assign the wrong - // amount of space on the variable axis if they would get aspect - // scaled down - if (contribSize[fc] == 0) - continue; - - // they've asked for as much as possible - if (contribSize[vc] == SIZE_EXPAND) { - // we'll need to be as big as possible too - m_preferredSize[vc] = SIZE_EXPAND; - - // count them for later - m_numVariable++; - } - - // they asked for a known amount - else { - - // if we still know our size then we can increase it sanely - if (m_preferredSize[vc] != SIZE_EXPAND) - // need a bit more - m_preferredSize[vc] += contribSize[vc]; - } - - // fixed axis should just be as large as our largest - m_preferredSize[fc] = std::max(m_preferredSize[fc], contribSize[fc]); - } - - // we have fixed size, so we can do the deferred ones now - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) + static inline void GetComponentsForOrient(bool horiz, Point::Component &variableComponent, Point::Component &fixedComponent) { - // already handled - if ((*i).contribSize[fc] != 0) - continue; - - // calculate final size usng its own variable size and the accumulated - // fixed size - Point availableSize; - availableSize[vc] = (*i).contribSize[vc]; - availableSize[fc] = m_preferredSize[fc]; - const Point contribSize = (*i).contribSize = (*i).widget->CalcSize(availableSize); - - // repeat of above, sigh - if (contribSize[vc] == SIZE_EXPAND) { - m_preferredSize[vc] = SIZE_EXPAND; - m_numVariable++; + if (horiz) { + variableComponent = Point::X; + fixedComponent = Point::Y; + } else { + variableComponent = Point::Y; + fixedComponent = Point::X; } - else { - if (m_preferredSize[vc] != SIZE_EXPAND) - m_preferredSize[vc] += contribSize[vc]; - } - m_preferredSize[fc] = std::max(m_preferredSize[fc], contribSize[fc]); } - // if there was no variable ones, and thus we're asking for a specific - // amount of space, add sufficient padding - if (m_numVariable == 0) - m_preferredSize[vc] += m_spacing*m_children.size(); + Box::Box(Context *context, BoxOrientation orient, int spacing) : + Container(context), + m_orient(orient), + m_spacing(context->GetScale() * spacing) + {} - return m_preferredSize; -} + Point Box::PreferredSize() + { + if (m_children.empty()) return Point(); -void Box::Layout() -{ - if (m_children.empty()) return; + Point::Component vc, fc; + GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); - PreferredSize(); + m_preferredSize = Point(0); + m_numVariable = 0; - const Point& boxSize = GetSize(); + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + const Point contribSize = (*i).contribSize = (*i).widget->CalcLayoutContribution(); - Point::Component vc, fc; - GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); + // if they're not contributing anything on the fixed axis then we need + // to defer their inclusion until we know the size of the fixed axis + // and can ask for their best size. otherwise we can assign the wrong + // amount of space on the variable axis if they would get aspect + // scaled down + if (contribSize[fc] == 0) + continue; - // fast path. we know the exact size that everything wants, so just - // loop and hand it out - if (m_numVariable == 0) { + // they've asked for as much as possible + if (contribSize[vc] == SIZE_EXPAND) { + // we'll need to be as big as possible too + m_preferredSize[vc] = SIZE_EXPAND; - // we got what we asked for so everyone can have what they want - if (boxSize[vc] >= m_preferredSize[vc]) { - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - (*i).size[fc] = boxSize[fc]; - (*i).size[vc] = (*i).contribSize[vc]; + // count them for later + m_numVariable++; } + + // they asked for a known amount + else { + + // if we still know our size then we can increase it sanely + if (m_preferredSize[vc] != SIZE_EXPAND) + // need a bit more + m_preferredSize[vc] += contribSize[vc]; + } + + // fixed axis should just be as large as our largest + m_preferredSize[fc] = std::max(m_preferredSize[fc], contribSize[fc]); } - // didn't get enough, so we have share it around - else { - // we can certainly afford to give everyone this much - int availSize = boxSize[vc] - (m_spacing * (m_children.size()-1)); - int minSize = availSize / m_children.size(); - int remaining = availSize; - int wantMore = 0; + // we have fixed size, so we can do the deferred ones now + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + // already handled + if ((*i).contribSize[fc] != 0) + continue; - // loop and hand it out - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - (*i).size[fc] = boxSize[fc]; - (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); - remaining -= (*i).size[vc]; + // calculate final size usng its own variable size and the accumulated + // fixed size + Point availableSize; + availableSize[vc] = (*i).contribSize[vc]; + availableSize[fc] = m_preferredSize[fc]; + const Point contribSize = (*i).contribSize = (*i).widget->CalcSize(availableSize); - // if this one didn't get us much as it wanted then count it - // if we have any left over we can give it some more - if ((*i).size[vc] < (*i).contribSize[vc]) - wantMore++; + // repeat of above, sigh + if (contribSize[vc] == SIZE_EXPAND) { + m_preferredSize[vc] = SIZE_EXPAND; + m_numVariable++; + } else { + if (m_preferredSize[vc] != SIZE_EXPAND) + m_preferredSize[vc] += contribSize[vc]; + } + m_preferredSize[fc] = std::max(m_preferredSize[fc], contribSize[fc]); + } + + // if there was no variable ones, and thus we're asking for a specific + // amount of space, add sufficient padding + if (m_numVariable == 0) + m_preferredSize[vc] += m_spacing * m_children.size(); + + return m_preferredSize; + } + + void Box::Layout() + { + if (m_children.empty()) return; + + PreferredSize(); + + const Point &boxSize = GetSize(); + + Point::Component vc, fc; + GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); + + // fast path. we know the exact size that everything wants, so just + // loop and hand it out + if (m_numVariable == 0) { + + // we got what we asked for so everyone can have what they want + if (boxSize[vc] >= m_preferredSize[vc]) { + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + (*i).size[fc] = boxSize[fc]; + (*i).size[vc] = (*i).contribSize[vc]; + } } - // if there's some remaining and not everyone got what they wanted, hand it out - assert(remaining >= 0); - if (remaining && wantMore) { - int extra = remaining / wantMore; + // didn't get enough, so we have share it around + else { + // we can certainly afford to give everyone this much + int availSize = boxSize[vc] - (m_spacing * (m_children.size() - 1)); + int minSize = availSize / m_children.size(); + int remaining = availSize; + int wantMore = 0; + + // loop and hand it out for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + (*i).size[fc] = boxSize[fc]; + (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); + remaining -= (*i).size[vc]; + + // if this one didn't get us much as it wanted then count it + // if we have any left over we can give it some more if ((*i).size[vc] < (*i).contribSize[vc]) - (*i).size[vc] += extra; + wantMore++; + } + + // if there's some remaining and not everyone got what they wanted, hand it out + assert(remaining >= 0); + if (remaining && wantMore) { + int extra = remaining / wantMore; + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + if ((*i).size[vc] < (*i).contribSize[vc]) + (*i).size[vc] += extra; + } } } } - } - // we have one or more children that have requested the maximum size possible - else { + // we have one or more children that have requested the maximum size possible + else { - int availSize = boxSize[vc] - (m_spacing * (m_children.size()-1)); - int remaining = availSize; + int availSize = boxSize[vc] - (m_spacing * (m_children.size() - 1)); + int remaining = availSize; - // fixed ones first - if (m_children.size() > m_numVariable) { - // distribute evenly among the fixed ones - int minSize = availSize / (m_children.size() - m_numVariable); + // fixed ones first + if (m_children.size() > m_numVariable) { + // distribute evenly among the fixed ones + int minSize = availSize / (m_children.size() - m_numVariable); - // loop and hand it out - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - // don't give any to expanding ones yet - if ((*i).contribSize[vc] == SIZE_EXPAND) - continue; + // loop and hand it out + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + // don't give any to expanding ones yet + if ((*i).contribSize[vc] == SIZE_EXPAND) + continue; - (*i).size[fc] = boxSize[fc]; - (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); - remaining -= (*i).size[vc]; + (*i).size[fc] = boxSize[fc]; + (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); + remaining -= (*i).size[vc]; + } + } + + // if there's any space remaining, distribute it among the expanding widgets + assert(remaining >= 0); + if (remaining) { + int extra = remaining / m_numVariable; + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + if ((*i).contribSize[vc] != SIZE_EXPAND) + continue; + + (*i).size[fc] = boxSize[fc]; + (*i).size[vc] = extra; + } } } - // if there's any space remaining, distribute it among the expanding widgets - assert(remaining >= 0); - if (remaining) { - int extra = remaining / m_numVariable; - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - if ((*i).contribSize[vc] != SIZE_EXPAND) - continue; + // now loop over them again and position + Point childPos(0); + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { + const Point actualSize((*i).widget->CalcSize((*i).size)); + SetWidgetDimensions((*i).widget, childPos, actualSize); + childPos[vc] += actualSize[vc] + m_spacing; + } - (*i).size[fc] = boxSize[fc]; - (*i).size[vc] = extra; + LayoutChildren(); + } + + Box *Box::PackStart(Widget *widget) + { + assert(widget); + AddWidget(widget); + m_children.push_front(Child(widget)); + return this; + } + + Box *Box::PackStart(const WidgetSet &set) + { + for (size_t i = 0; i < set.numWidgets; ++i) + PackStart(set.widgets[i]); + return this; + } + + Box *Box::PackEnd(Widget *widget) + { + assert(widget); + AddWidget(widget); + m_children.push_back(Child(widget)); + return this; + } + + Box *Box::PackEnd(const WidgetSet &set) + { + for (size_t i = 0; i < set.numWidgets; ++i) + PackEnd(set.widgets[i]); + return this; + } + + void Box::RemoveWidget(Widget *widget) + { + for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) + if ((*i).widget == widget) { + m_children.erase(i); + Container::RemoveWidget(widget); + return; } - } } - // now loop over them again and position - Point childPos(0); - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { - const Point actualSize((*i).widget->CalcSize((*i).size)); - SetWidgetDimensions((*i).widget, childPos, actualSize); - childPos[vc] += actualSize[vc] + m_spacing; + void Box::Clear() + { + m_children.clear(); + Container::RemoveAllWidgets(); } - LayoutChildren(); -} - -Box *Box::PackStart(Widget *widget) -{ - assert(widget); - AddWidget(widget); - m_children.push_front(Child(widget)); - return this; -} - -Box *Box::PackStart(const WidgetSet &set) -{ - for (size_t i = 0; i < set.numWidgets; ++i) - PackStart(set.widgets[i]); - return this; -} - -Box *Box::PackEnd(Widget *widget) -{ - assert(widget); - AddWidget(widget); - m_children.push_back(Child(widget)); - return this; -} - -Box *Box::PackEnd(const WidgetSet &set) -{ - for (size_t i = 0; i < set.numWidgets; ++i) - PackEnd(set.widgets[i]); - return this; -} - -void Box::RemoveWidget(Widget *widget) -{ - for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) - if ((*i).widget == widget) { - m_children.erase(i); - Container::RemoveWidget(widget); - return; - } -} - -void Box::Clear() -{ - m_children.clear(); - Container::RemoveAllWidgets(); -} - -} +} // namespace UI diff --git a/src/ui/Box.h b/src/ui/Box.h index b694a867b..beab428ba 100644 --- a/src/ui/Box.h +++ b/src/ui/Box.h @@ -8,60 +8,63 @@ namespace UI { -class Box : public Container { -protected: - enum BoxOrientation { - BOX_HORIZONTAL, - BOX_VERTICAL + class Box : public Container { + protected: + enum BoxOrientation { + BOX_HORIZONTAL, + BOX_VERTICAL + }; + + Box(Context *context, BoxOrientation orient, int spacing); + + public: + virtual Point PreferredSize(); + virtual void Layout(); + + Box *PackStart(Widget *child); + Box *PackStart(const WidgetSet &set); + Box *PackEnd(Widget *child); + Box *PackEnd(const WidgetSet &set); + + void Remove(Widget *child) { RemoveWidget(child); } + void Clear(); + + protected: + virtual void RemoveWidget(Widget *widget); + + private: + BoxOrientation m_orient; + int m_spacing; + + struct Child { + Child(Widget *_widget) : + widget(_widget) {} + Widget *widget; + Point contribSize; + Point size; + Point position; + }; + + std::list m_children; + + Point m_preferredSize; + Uint32 m_numVariable; }; - Box(Context *context, BoxOrientation orient, int spacing); - -public: - virtual Point PreferredSize(); - virtual void Layout(); - - Box *PackStart(Widget *child); - Box *PackStart(const WidgetSet &set); - Box *PackEnd(Widget *child); - Box *PackEnd(const WidgetSet &set); - - void Remove(Widget *child) { RemoveWidget(child); } - void Clear(); - -protected: - virtual void RemoveWidget(Widget *widget); - -private: - BoxOrientation m_orient; - int m_spacing; - - struct Child { - Child(Widget *_widget) : widget(_widget) {} - Widget *widget; - Point contribSize; - Point size; - Point position; + class VBox : public Box { + protected: + friend class Context; + VBox(Context *context, float spacing) : + Box(context, BOX_VERTICAL, spacing) {} }; - std::list m_children; + class HBox : public Box { + protected: + friend class Context; + HBox(Context *context, float spacing) : + Box(context, BOX_HORIZONTAL, spacing) {} + }; - Point m_preferredSize; - Uint32 m_numVariable; -}; - -class VBox: public Box { -protected: - friend class Context; - VBox(Context *context, float spacing): Box(context, BOX_VERTICAL, spacing) {} -}; - -class HBox: public Box { -protected: - friend class Context; - HBox(Context *context, float spacing): Box(context, BOX_HORIZONTAL, spacing) {} -}; - -} +} // namespace UI #endif diff --git a/src/ui/Button.cpp b/src/ui/Button.cpp index 630e27bf3..ac174e4af 100644 --- a/src/ui/Button.cpp +++ b/src/ui/Button.cpp @@ -7,66 +7,66 @@ namespace UI { -static inline void growToMinimum(Point &v, const int min) -{ - if (v.x < min || v.y < min) - v = Point(std::max(v.x,min),std::max(v.y,min)); -} - -Point Button::PreferredSize() -{ - // child's preferred size - Point preferredSize(Single::PreferredSize()); - - // grow to minimum size if necessary - growToMinimum(preferredSize, GetContext()->GetSkin().ButtonMinInnerSize()); - - // add padding - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().ButtonNormal()); - preferredSize = SizeAdd(preferredSize, Point(elem.paddingX*2, elem.paddingY*2)); - - // grow to border size if necessary - preferredSize.x = std::max(preferredSize.x, int(elem.borderWidth*2)); - preferredSize.y = std::max(preferredSize.y, int(elem.borderHeight*2)); - - return preferredSize; -} - -void Button::Layout() -{ - Widget *innerWidget = GetInnerWidget(); - - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().ButtonNormal()); - - if (!innerWidget) { - SetActiveArea(PreferredSize()); - return; + static inline void growToMinimum(Point &v, const int min) + { + if (v.x < min || v.y < min) + v = Point(std::max(v.x, min), std::max(v.y, min)); } - const Point innerSize = GetSize() - Point(elem.paddingX*2, elem.paddingY*2); - SetWidgetDimensions(innerWidget, Point(elem.paddingX, elem.paddingY), innerWidget->CalcSize(innerSize)); - innerWidget->Layout(); + Point Button::PreferredSize() + { + // child's preferred size + Point preferredSize(Single::PreferredSize()); - Point innerActiveArea(innerWidget->GetActiveArea()); - growToMinimum(innerActiveArea, GetContext()->GetSkin().ButtonMinInnerSize()); + // grow to minimum size if necessary + growToMinimum(preferredSize, GetContext()->GetSkin().ButtonMinInnerSize()); - SetActiveArea(innerActiveArea + Point(elem.paddingX*2, elem.paddingY*2)); -} + // add padding + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().ButtonNormal()); + preferredSize = SizeAdd(preferredSize, Point(elem.paddingX * 2, elem.paddingY * 2)); -void Button::Draw() -{ - if (IsDisabled()) - GetContext()->GetSkin().DrawButtonDisabled(GetActiveOffset(), GetActiveArea()); - else if (IsHidden()) - GetContext()->GetSkin().DrawButtonHidden(GetActiveOffset(), GetActiveArea()); - else if (IsMouseActive()) - GetContext()->GetSkin().DrawButtonActive(GetActiveOffset(), GetActiveArea()); - else if (IsMouseOver()) - GetContext()->GetSkin().DrawButtonHover(GetActiveOffset(), GetActiveArea()); - else - GetContext()->GetSkin().DrawButtonNormal(GetActiveOffset(), GetActiveArea()); + // grow to border size if necessary + preferredSize.x = std::max(preferredSize.x, int(elem.borderWidth * 2)); + preferredSize.y = std::max(preferredSize.y, int(elem.borderHeight * 2)); - Single::Draw(); -} + return preferredSize; + } -} + void Button::Layout() + { + Widget *innerWidget = GetInnerWidget(); + + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().ButtonNormal()); + + if (!innerWidget) { + SetActiveArea(PreferredSize()); + return; + } + + const Point innerSize = GetSize() - Point(elem.paddingX * 2, elem.paddingY * 2); + SetWidgetDimensions(innerWidget, Point(elem.paddingX, elem.paddingY), innerWidget->CalcSize(innerSize)); + innerWidget->Layout(); + + Point innerActiveArea(innerWidget->GetActiveArea()); + growToMinimum(innerActiveArea, GetContext()->GetSkin().ButtonMinInnerSize()); + + SetActiveArea(innerActiveArea + Point(elem.paddingX * 2, elem.paddingY * 2)); + } + + void Button::Draw() + { + if (IsDisabled()) + GetContext()->GetSkin().DrawButtonDisabled(GetActiveOffset(), GetActiveArea()); + else if (IsHidden()) + GetContext()->GetSkin().DrawButtonHidden(GetActiveOffset(), GetActiveArea()); + else if (IsMouseActive()) + GetContext()->GetSkin().DrawButtonActive(GetActiveOffset(), GetActiveArea()); + else if (IsMouseOver()) + GetContext()->GetSkin().DrawButtonHover(GetActiveOffset(), GetActiveArea()); + else + GetContext()->GetSkin().DrawButtonNormal(GetActiveOffset(), GetActiveArea()); + + Single::Draw(); + } + +} // namespace UI diff --git a/src/ui/Button.h b/src/ui/Button.h index f06f79219..43ef61bdc 100644 --- a/src/ui/Button.h +++ b/src/ui/Button.h @@ -8,17 +8,18 @@ namespace UI { -class Button: public Single { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class Button : public Single { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); -protected: - friend class Context; - Button(Context *context): Single(context) {} -}; + protected: + friend class Context; + Button(Context *context) : + Single(context) {} + }; -} +} // namespace UI #endif diff --git a/src/ui/CellSpec.cpp b/src/ui/CellSpec.cpp index 91f53e207..eb446b590 100644 --- a/src/ui/CellSpec.cpp +++ b/src/ui/CellSpec.cpp @@ -6,19 +6,20 @@ namespace UI { -CellSpec CellSpec::FromLuaTable(lua_State *l, int idx) { - const int table = lua_absindex(l, idx); - assert(lua_istable(l, table)); + CellSpec CellSpec::FromLuaTable(lua_State *l, int idx) + { + const int table = lua_absindex(l, idx); + assert(lua_istable(l, table)); - const int len = lua_rawlen(l, table); - std::vector cellPercent(len); - for (int i = 0; i < len; i++) { - lua_rawgeti(l, table, i+1); - cellPercent[i] = luaL_checknumber(l, -1); - lua_pop(l, 1); + const int len = lua_rawlen(l, table); + std::vector cellPercent(len); + for (int i = 0; i < len; i++) { + lua_rawgeti(l, table, i + 1); + cellPercent[i] = luaL_checknumber(l, -1); + lua_pop(l, 1); + } + + return CellSpec(cellPercent); } - return CellSpec(cellPercent); -} - -} +} // namespace UI diff --git a/src/ui/CellSpec.h b/src/ui/CellSpec.h index 7d3fca2ac..5a126a3be 100644 --- a/src/ui/CellSpec.h +++ b/src/ui/CellSpec.h @@ -4,75 +4,127 @@ #ifndef UI_CELLSPEC_H #define UI_CELLSPEC_H -#include #include +#include struct lua_State; namespace UI { -class CellSpec { -public: + class CellSpec { + public: + CellSpec(std::size_t n) : + numCells(n) + { + assert(n >= 1); + cellPercent.resize(n); + for (std::size_t i = 0; i < numCells; i++) + cellPercent[i] = 1.0f / n; + } - CellSpec(std::size_t n) : numCells(n) { - assert(n >= 1); - cellPercent.resize(n); - for (std::size_t i = 0; i < numCells; i++) cellPercent[i] = 1.0f/n; - } + inline CellSpec(float cp0, float cp1) : + numCells(2) + { + cellPercent.resize(2); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2) : + numCells(3) + { + cellPercent.resize(3); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2, float cp3) : + numCells(4) + { + cellPercent.resize(4); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + cellPercent[3] = cp3; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4) : + numCells(5) + { + cellPercent.resize(5); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + cellPercent[3] = cp3; + cellPercent[4] = cp4; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5) : + numCells(6) + { + cellPercent.resize(6); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + cellPercent[3] = cp3; + cellPercent[4] = cp4; + cellPercent[5] = cp5; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5, float cp6) : + numCells(7) + { + cellPercent.resize(7); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + cellPercent[3] = cp3; + cellPercent[4] = cp4; + cellPercent[5] = cp5; + cellPercent[6] = cp6; + NormaliseCells(); + } + inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5, float cp6, float cp7) : + numCells(8) + { + cellPercent.resize(8); + cellPercent[0] = cp0; + cellPercent[1] = cp1; + cellPercent[2] = cp2; + cellPercent[3] = cp3; + cellPercent[4] = cp4; + cellPercent[5] = cp5; + cellPercent[6] = cp6; + cellPercent[7] = cp7; + NormaliseCells(); + } - inline CellSpec(float cp0, float cp1) : numCells(2) { - cellPercent.resize(2); - cellPercent[0] = cp0; cellPercent[1] = cp1; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2) : numCells(3) { - cellPercent.resize(3); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2, float cp3) : numCells(4) { - cellPercent.resize(4); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; cellPercent[3] = cp3; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4) : numCells(5) { - cellPercent.resize(5); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; cellPercent[3] = cp3; cellPercent[4] = cp4; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5) : numCells(6) { - cellPercent.resize(6); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; cellPercent[3] = cp3; cellPercent[4] = cp4; cellPercent[5] = cp5; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5, float cp6) : numCells(7) { - cellPercent.resize(7); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; cellPercent[3] = cp3; cellPercent[4] = cp4; cellPercent[5] = cp5; cellPercent[6] = cp6; - NormaliseCells(); - } - inline CellSpec(float cp0, float cp1, float cp2, float cp3, float cp4, float cp5, float cp6, float cp7) : numCells(8) { - cellPercent.resize(8); - cellPercent[0] = cp0; cellPercent[1] = cp1; cellPercent[2] = cp2; cellPercent[3] = cp3; cellPercent[4] = cp4; cellPercent[5] = cp5; cellPercent[6] = cp6; cellPercent[7] = cp7; - NormaliseCells(); - } + inline CellSpec(const std::vector &cp) : + cellPercent(cp), + numCells(cp.size()) + { + NormaliseCells(); + } - inline CellSpec(const std::vector &cp) : cellPercent(cp), numCells(cp.size()) { - NormaliseCells(); - } + static CellSpec FromLuaTable(lua_State *l, int idx); - static CellSpec FromLuaTable(lua_State *l, int idx); + std::vector cellPercent; + std::size_t numCells; - std::vector cellPercent; - std::size_t numCells; + private: + void NormaliseCells() + { + float total = 0.0f; + for (std::size_t i = 0; i < numCells; ++i) { + total += cellPercent[i]; + } + for (std::size_t i = 0; i < numCells; ++i) { + cellPercent[i] /= total; + } + } + }; -private: - void NormaliseCells() { - float total = 0.0f; - for (std::size_t i = 0; i < numCells; ++i) { total += cellPercent[i]; } - for (std::size_t i = 0; i < numCells; ++i) { cellPercent[i] /= total; } - } -}; - -} +} // namespace UI #endif diff --git a/src/ui/CheckBox.cpp b/src/ui/CheckBox.cpp index d154e6ea7..9f9e06ea7 100644 --- a/src/ui/CheckBox.cpp +++ b/src/ui/CheckBox.cpp @@ -7,56 +7,56 @@ namespace UI { -Point CheckBox::PreferredSize() -{ - return GetContext()->GetSkin().CheckboxNormal().size; -} - -void CheckBox::Layout() -{ - SetActiveArea(PreferredSize()); -} - -void CheckBox::Draw() -{ - if (m_checked) { - if (IsDisabled()) - GetContext()->GetSkin().DrawCheckBoxCheckedDisabled(GetActiveOffset(), GetActiveArea()); - else if (IsMouseOver()) - GetContext()->GetSkin().DrawCheckBoxCheckedHover(GetActiveOffset(), GetActiveArea()); - else - GetContext()->GetSkin().DrawCheckBoxCheckedNormal(GetActiveOffset(), GetActiveArea()); - } else { - if (IsDisabled()) - GetContext()->GetSkin().DrawCheckBoxDisabled(GetActiveOffset(), GetActiveArea()); - else if (IsMouseOver()) - GetContext()->GetSkin().DrawCheckBoxHover(GetActiveOffset(), GetActiveArea()); - else - GetContext()->GetSkin().DrawCheckBoxNormal(GetActiveOffset(), GetActiveArea()); + Point CheckBox::PreferredSize() + { + return GetContext()->GetSkin().CheckboxNormal().size; } -} -void CheckBox::Toggle() -{ - m_checked = !m_checked; - onValueChanged.emit(m_checked); -} + void CheckBox::Layout() + { + SetActiveArea(PreferredSize()); + } -bool CheckBox::IsChecked() const -{ - return m_checked; -} + void CheckBox::Draw() + { + if (m_checked) { + if (IsDisabled()) + GetContext()->GetSkin().DrawCheckBoxCheckedDisabled(GetActiveOffset(), GetActiveArea()); + else if (IsMouseOver()) + GetContext()->GetSkin().DrawCheckBoxCheckedHover(GetActiveOffset(), GetActiveArea()); + else + GetContext()->GetSkin().DrawCheckBoxCheckedNormal(GetActiveOffset(), GetActiveArea()); + } else { + if (IsDisabled()) + GetContext()->GetSkin().DrawCheckBoxDisabled(GetActiveOffset(), GetActiveArea()); + else if (IsMouseOver()) + GetContext()->GetSkin().DrawCheckBoxHover(GetActiveOffset(), GetActiveArea()); + else + GetContext()->GetSkin().DrawCheckBoxNormal(GetActiveOffset(), GetActiveArea()); + } + } -void CheckBox::SetState(bool state) -{ - if (m_checked != state) { + void CheckBox::Toggle() + { + m_checked = !m_checked; + onValueChanged.emit(m_checked); + } + + bool CheckBox::IsChecked() const + { + return m_checked; + } + + void CheckBox::SetState(bool state) + { + if (m_checked != state) { + Toggle(); + } + } + + void CheckBox::HandleClick() + { Toggle(); } -} -void CheckBox::HandleClick() -{ - Toggle(); -} - -} +} // namespace UI diff --git a/src/ui/CheckBox.h b/src/ui/CheckBox.h index 128444cb6..1e6c5a30b 100644 --- a/src/ui/CheckBox.h +++ b/src/ui/CheckBox.h @@ -8,28 +8,30 @@ namespace UI { -class CheckBox: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class CheckBox : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - void Toggle(); - bool IsChecked() const; - void SetState(bool state); + void Toggle(); + bool IsChecked() const; + void SetState(bool state); - sigc::signal onValueChanged; + sigc::signal onValueChanged; -protected: - friend class Context; - CheckBox(Context *context): Widget(context), m_checked(false) {} + protected: + friend class Context; + CheckBox(Context *context) : + Widget(context), + m_checked(false) {} - void HandleClick(); + void HandleClick(); -private: - bool m_checked; -}; + private: + bool m_checked; + }; -} +} // namespace UI #endif diff --git a/src/ui/ColorBackground.cpp b/src/ui/ColorBackground.cpp index 0a5c3ce25..431d3d1cc 100644 --- a/src/ui/ColorBackground.cpp +++ b/src/ui/ColorBackground.cpp @@ -3,22 +3,22 @@ #include "ColorBackground.h" #include "Context.h" +#include "graphics/Material.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "graphics/Material.h" namespace UI { -ColorBackground::ColorBackground(Context *context, const Color &color) : - Single(context), - m_color(color) -{ -} + ColorBackground::ColorBackground(Context *context, const Color &color) : + Single(context), + m_color(color) + { + } -void ColorBackground::Draw() -{ - GetContext()->GetSkin().DrawRectColor(m_color, Point(), GetSize()); - Container::Draw(); -} + void ColorBackground::Draw() + { + GetContext()->GetSkin().DrawRectColor(m_color, Point(), GetSize()); + Container::Draw(); + } -} +} // namespace UI diff --git a/src/ui/ColorBackground.h b/src/ui/ColorBackground.h index 63f2f8063..ccd01a4de 100644 --- a/src/ui/ColorBackground.h +++ b/src/ui/ColorBackground.h @@ -4,26 +4,26 @@ #ifndef UI_COLORBACKGROUND_H #define UI_COLORBACKGROUND_H -#include "Single.h" #include "Color.h" +#include "Single.h" #include "graphics/Material.h" namespace UI { -class ColorBackground : public Single { -public: - virtual void Draw(); + class ColorBackground : public Single { + public: + virtual void Draw(); - void SetColor(const Color &color) { m_color = color; } + void SetColor(const Color &color) { m_color = color; } -protected: - friend class Context; - ColorBackground(Context *context, const Color &color); + protected: + friend class Context; + ColorBackground(Context *context, const Color &color); -private: - Color m_color; -}; + private: + Color m_color; + }; -} +} // namespace UI #endif diff --git a/src/ui/Container.cpp b/src/ui/Container.cpp index c014eee59..138f54311 100644 --- a/src/ui/Container.cpp +++ b/src/ui/Container.cpp @@ -3,171 +3,171 @@ #include "Container.h" #include "Context.h" -#include "matrix4x4.h" #include "graphics/Renderer.h" +#include "matrix4x4.h" namespace UI { -Container::~Container() -{ - for (std::vector< RefCountedPtr >::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) - (*i)->Detach(); -} - -void Container::Update() -{ - // widgets can add/remove other widgets during Update. that screws up the - // iterators when traversing the widget list. rather than try and detect - // it, we just take a copy of the list - std::vector< RefCountedPtr > widgets = m_widgets; - for (std::vector< RefCountedPtr >::iterator i = widgets.begin(); i != widgets.end(); ++i) - (*i)->Update(); -} - -void Container::Draw() -{ - Context *c = GetContext(); - - for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) - c->DrawWidget((*it).Get()); -} - -void Container::LayoutChildren() -{ - for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) - (*it)->Layout(); -} - -void Container::AddWidget(Widget *widget) -{ - if (widget->GetContainer()) - widget->GetContainer()->RemoveWidget(widget); - - std::vector< RefCountedPtr >::iterator i; - for (i = m_widgets.begin(); i != m_widgets.end(); ++i) - if ((*i).Get() == widget) break; - assert(i == m_widgets.end()); - - widget->Attach(this); - m_widgets.push_back(RefCountedPtr(widget)); - - GetContext()->RequestLayout(); -} - -void Container::RemoveWidget(Widget *widget) -{ - assert(widget->GetContainer() == this); - - std::vector< RefCountedPtr >::iterator i; - for (i = m_widgets.begin(); i != m_widgets.end(); ++i) - if ((*i).Get() == widget) break; - if (i == m_widgets.end()) - return; - - widget->Detach(); - m_widgets.erase(i); - - GetContext()->RequestLayout(); -} - -void Container::RemoveAllWidgets() -{ - for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) - (*it)->Detach(); - m_widgets.clear(); - GetContext()->RequestLayout(); -} - -void Container::Disable() -{ - DisableChildren(); - Widget::Disable(); -} - -void Container::Enable() -{ - EnableChildren(); - Widget::Enable(); -} - -void Container::NotifyVisible(bool visible) -{ - const bool wasVisible = IsVisible(); - Widget::NotifyVisible(visible); - if (wasVisible != visible) { - for (std::vector< RefCountedPtr >::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { - Widget *w = (*i).Get(); - w->NotifyVisible(visible); - } - } -} - -void Container::DisableChildren() -{ - for (std::vector< RefCountedPtr >::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { - Widget *w = (*i).Get(); - w->SetDisabled(true); - if (w->IsContainer()) { - static_cast(w)->DisableChildren(); - } - } -} - -void Container::EnableChildren() -{ - for (std::vector< RefCountedPtr >::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { - Widget *w = (*i).Get(); - w->SetDisabled(false); - if (w->IsContainer()) { - static_cast(w)->EnableChildren(); - } - } -} - -void Container::SetWidgetDimensions(Widget *widget, const Point &position, const Point &size) -{ - assert(widget->GetContainer() == this); - - widget->SetDimensions(position, size); -} - -Widget *Container::GetWidgetAt(const Point &pos) -{ - if (!Contains(pos)) return 0; - - for (auto end = m_widgets.rend(), it = m_widgets.rbegin(); it != end; ++it) { - const auto widget = *it; - const Point relpos = pos - widget->GetPosition() - widget->GetDrawOffset(); - if (widget->IsContainer()) { - Widget* w = static_cast(widget.Get())->GetWidgetAt(relpos); - if (w) return w; - } else if (widget->Contains(relpos)) - return widget.Get(); - } - - return this; -} - -void Container::CollectShortcuts(std::map &shortcuts) -{ + Container::~Container() { - const std::set &widgetShortcuts = GetShortcuts(); - if (!widgetShortcuts.empty()) - for (std::set::const_iterator j = widgetShortcuts.begin(); j != widgetShortcuts.end(); ++j) - shortcuts[*j] = this; + for (std::vector>::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) + (*i)->Detach(); } - for (auto end = m_widgets.rend(), it = m_widgets.rbegin(); it != end; ++it) { - const auto widget = *it; - if (widget->IsContainer()) - static_cast(widget.Get())->CollectShortcuts(shortcuts); - else { - const std::set &widgetShortcuts = widget->GetShortcuts(); + void Container::Update() + { + // widgets can add/remove other widgets during Update. that screws up the + // iterators when traversing the widget list. rather than try and detect + // it, we just take a copy of the list + std::vector> widgets = m_widgets; + for (std::vector>::iterator i = widgets.begin(); i != widgets.end(); ++i) + (*i)->Update(); + } + + void Container::Draw() + { + Context *c = GetContext(); + + for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) + c->DrawWidget((*it).Get()); + } + + void Container::LayoutChildren() + { + for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) + (*it)->Layout(); + } + + void Container::AddWidget(Widget *widget) + { + if (widget->GetContainer()) + widget->GetContainer()->RemoveWidget(widget); + + std::vector>::iterator i; + for (i = m_widgets.begin(); i != m_widgets.end(); ++i) + if ((*i).Get() == widget) break; + assert(i == m_widgets.end()); + + widget->Attach(this); + m_widgets.push_back(RefCountedPtr(widget)); + + GetContext()->RequestLayout(); + } + + void Container::RemoveWidget(Widget *widget) + { + assert(widget->GetContainer() == this); + + std::vector>::iterator i; + for (i = m_widgets.begin(); i != m_widgets.end(); ++i) + if ((*i).Get() == widget) break; + if (i == m_widgets.end()) + return; + + widget->Detach(); + m_widgets.erase(i); + + GetContext()->RequestLayout(); + } + + void Container::RemoveAllWidgets() + { + for (auto end = m_widgets.end(), it = m_widgets.begin(); it != end; ++it) + (*it)->Detach(); + m_widgets.clear(); + GetContext()->RequestLayout(); + } + + void Container::Disable() + { + DisableChildren(); + Widget::Disable(); + } + + void Container::Enable() + { + EnableChildren(); + Widget::Enable(); + } + + void Container::NotifyVisible(bool visible) + { + const bool wasVisible = IsVisible(); + Widget::NotifyVisible(visible); + if (wasVisible != visible) { + for (std::vector>::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { + Widget *w = (*i).Get(); + w->NotifyVisible(visible); + } + } + } + + void Container::DisableChildren() + { + for (std::vector>::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { + Widget *w = (*i).Get(); + w->SetDisabled(true); + if (w->IsContainer()) { + static_cast(w)->DisableChildren(); + } + } + } + + void Container::EnableChildren() + { + for (std::vector>::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { + Widget *w = (*i).Get(); + w->SetDisabled(false); + if (w->IsContainer()) { + static_cast(w)->EnableChildren(); + } + } + } + + void Container::SetWidgetDimensions(Widget *widget, const Point &position, const Point &size) + { + assert(widget->GetContainer() == this); + + widget->SetDimensions(position, size); + } + + Widget *Container::GetWidgetAt(const Point &pos) + { + if (!Contains(pos)) return 0; + + for (auto end = m_widgets.rend(), it = m_widgets.rbegin(); it != end; ++it) { + const auto widget = *it; + const Point relpos = pos - widget->GetPosition() - widget->GetDrawOffset(); + if (widget->IsContainer()) { + Widget *w = static_cast(widget.Get())->GetWidgetAt(relpos); + if (w) return w; + } else if (widget->Contains(relpos)) + return widget.Get(); + } + + return this; + } + + void Container::CollectShortcuts(std::map &shortcuts) + { + { + const std::set &widgetShortcuts = GetShortcuts(); if (!widgetShortcuts.empty()) for (std::set::const_iterator j = widgetShortcuts.begin(); j != widgetShortcuts.end(); ++j) - shortcuts[*j] = widget.Get(); + shortcuts[*j] = this; + } + + for (auto end = m_widgets.rend(), it = m_widgets.rbegin(); it != end; ++it) { + const auto widget = *it; + if (widget->IsContainer()) + static_cast(widget.Get())->CollectShortcuts(shortcuts); + else { + const std::set &widgetShortcuts = widget->GetShortcuts(); + if (!widgetShortcuts.empty()) + for (std::set::const_iterator j = widgetShortcuts.begin(); j != widgetShortcuts.end(); ++j) + shortcuts[*j] = widget.Get(); + } } } -} -} +} // namespace UI diff --git a/src/ui/Container.h b/src/ui/Container.h index 89e18d139..714975bac 100644 --- a/src/ui/Container.h +++ b/src/ui/Container.h @@ -4,8 +4,8 @@ #ifndef UI_CONTAINER_H #define UI_CONTAINER_H -#include "Widget.h" #include "IterationProxy.h" +#include "Widget.h" #include // Container is the base class for all UI containers. Containers must @@ -21,55 +21,55 @@ namespace UI { -class Container: public Widget { + class Container : public Widget { -protected: - // can't instantiate a base container directly - Container(Context *context) : Widget(context) {} + protected: + // can't instantiate a base container directly + Container(Context *context) : + Widget(context) {} -public: - virtual ~Container(); + public: + virtual ~Container(); - virtual void Layout() = 0; - virtual void Update(); - virtual void Draw(); + virtual void Layout() = 0; + virtual void Update(); + virtual void Draw(); - virtual bool IsContainer() const { return true; } + virtual bool IsContainer() const { return true; } - // widget at pos relative to this widget - virtual Widget *GetWidgetAt(const Point &pos); + // widget at pos relative to this widget + virtual Widget *GetWidgetAt(const Point &pos); - virtual void Disable(); - virtual void Enable(); + virtual void Disable(); + virtual void Enable(); - Uint32 GetNumWidgets() const { return static_cast(m_widgets.size()); } - IterationProxy > > GetWidgets() { return MakeIterationProxy(m_widgets); } - const IterationProxy > > GetWidgets() const { return MakeIterationProxy(m_widgets); } + Uint32 GetNumWidgets() const { return static_cast(m_widgets.size()); } + IterationProxy>> GetWidgets() { return MakeIterationProxy(m_widgets); } + const IterationProxy>> GetWidgets() const { return MakeIterationProxy(m_widgets); } -protected: - void LayoutChildren(); + protected: + void LayoutChildren(); - void AddWidget(Widget *); - virtual void RemoveWidget(Widget *); - void RemoveAllWidgets(); + void AddWidget(Widget *); + virtual void RemoveWidget(Widget *); + void RemoveAllWidgets(); - void SetWidgetDimensions(Widget *widget, const Point &position, const Point &size); + void SetWidgetDimensions(Widget *widget, const Point &position, const Point &size); -private: + private: + // EventDispatcher will call here on layout change to get the shortcuts + // for the children of this container + friend class EventDispatcher; + void CollectShortcuts(std::map &shortcuts); - // EventDispatcher will call here on layout change to get the shortcuts - // for the children of this container - friend class EventDispatcher; - void CollectShortcuts(std::map &shortcuts); + virtual void NotifyVisible(bool visible); - virtual void NotifyVisible(bool visible); + void EnableChildren(); + void DisableChildren(); - void EnableChildren(); - void DisableChildren(); + std::vector> m_widgets; + }; - std::vector< RefCountedPtr > m_widgets; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Context.cpp b/src/ui/Context.cpp index 2356452f9..feceb6263 100644 --- a/src/ui/Context.cpp +++ b/src/ui/Context.cpp @@ -3,274 +3,271 @@ #include "Context.h" #include "FileSystem.h" -#include "text/FontConfig.h" #include "Lua.h" -#include "FileSystem.h" +#include "text/FontConfig.h" #include namespace UI { -// minimum screen height for scaling. if the screen has fewer vertical pixels -// than this, certain draw elements will be scaled down -static const int SCALE_CUTOFF_HEIGHT = 768; + // minimum screen height for scaling. if the screen has fewer vertical pixels + // than this, certain draw elements will be scaled down + static const int SCALE_CUTOFF_HEIGHT = 768; -static const float FONT_SCALE[] = { - 0.7f, // XSMALL - 0.85f, // SMALL - 1.0f, // NORMAL - 1.4f, // LARGE - 1.8f, // XLARGE + static const float FONT_SCALE[] = { + 0.7f, // XSMALL + 0.85f, // SMALL + 1.0f, // NORMAL + 1.4f, // LARGE + 1.8f, // XLARGE - 0.7f, // HEADING_XSMALL - 0.85f, // HEADING_SMALL - 1.0f, // HEADING_NORMAL - 1.4f, // HEADING_LARGE - 1.8f, // HEADING_XLARGE + 0.7f, // HEADING_XSMALL + 0.85f, // HEADING_SMALL + 1.0f, // HEADING_NORMAL + 1.4f, // HEADING_LARGE + 1.8f, // HEADING_XLARGE - 0.7f, // MONO_XSMALL - 0.85f, // MONO_SMALL - 1.0f, // MONO_NORMAL - 1.4f, // MONO_LARGE - 1.8f // MONO_XLARGE -}; + 0.7f, // MONO_XSMALL + 0.85f, // MONO_SMALL + 1.0f, // MONO_NORMAL + 1.4f, // MONO_LARGE + 1.8f // MONO_XLARGE + }; -Context::Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height): - Context(lua, renderer, width, height, std::min(float(height)/SCALE_CUTOFF_HEIGHT, 1.0f)) -{} - -Context::Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height, float scale) : Container(this), - m_renderer(renderer), - m_width(width), - m_height(height), - m_scale(scale), - m_needsLayout(false), - m_mousePointer(nullptr), - m_mousePointerEnabled(true), - m_eventDispatcher(this), - m_skin("ui/Skin.ini", renderer, scale), - m_lua(lua) -{ - lua_State *l = m_lua->GetLuaState(); - lua_newtable(l); - m_templateStore = LuaRef(l, -1); - - SetSize(Point(m_width,m_height)); - m_visible = true; - - NewLayer(); - - // XXX should do point sizes, but we need display DPI first - // XXX TextureFont could load multiple sizes into the same object/atlas + Context::Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height) : + Context(lua, renderer, width, height, std::min(float(height) / SCALE_CUTOFF_HEIGHT, 1.0f)) + {} + Context::Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height, float scale) : + Container(this), + m_renderer(renderer), + m_width(width), + m_height(height), + m_scale(scale), + m_needsLayout(false), + m_mousePointer(nullptr), + m_mousePointerEnabled(true), + m_eventDispatcher(this), + m_skin("ui/Skin.ini", renderer, scale), + m_lua(lua) { - const Text::FontConfig config("UIFont"); - for (int i = FONT_SMALLEST; i <= FONT_LARGEST; i++) - m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i]*GetScale())); + lua_State *l = m_lua->GetLuaState(); + lua_newtable(l); + m_templateStore = LuaRef(l, -1); + + SetSize(Point(m_width, m_height)); + m_visible = true; + + NewLayer(); + + // XXX should do point sizes, but we need display DPI first + // XXX TextureFont could load multiple sizes into the same object/atlas + + { + const Text::FontConfig config("UIFont"); + for (int i = FONT_SMALLEST; i <= FONT_LARGEST; i++) + m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i] * GetScale())); + } + + { + const Text::FontConfig config("UIHeadingFont"); + for (int i = FONT_HEADING_SMALLEST; i <= FONT_HEADING_LARGEST; i++) + m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i] * GetScale())); + } + + { + const Text::FontConfig config("UIMonoFont"); + for (int i = FONT_MONO_SMALLEST; i <= FONT_MONO_LARGEST; i++) + m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i] * GetScale())); + } + + m_scissorStack.push(std::make_pair(Point(0, 0), Point(m_width, m_height))); } + Layer *Context::NewLayer() { - const Text::FontConfig config("UIHeadingFont"); - for (int i = FONT_HEADING_SMALLEST; i <= FONT_HEADING_LARGEST; i++) - m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i]*GetScale())); - } - - { - const Text::FontConfig config("UIMonoFont"); - for (int i = FONT_MONO_SMALLEST; i <= FONT_MONO_LARGEST; i++) - m_font[i] = RefCountedPtr(new Text::TextureFont(config, renderer, FONT_SCALE[i]*GetScale())); - } - - m_scissorStack.push(std::make_pair(Point(0,0), Point(m_width,m_height))); -} - -Layer *Context::NewLayer() -{ - Layer *layer = new Layer(this); - AddWidget(layer); - SetWidgetDimensions(layer, Point(0), Point(m_width, m_height)); - m_layers.push_back(layer); - m_needsLayout = true; - return layer; -} - -void Context::DropLayer() -{ - // dropping the last layer would be bad - if(m_layers.size() > 1) - { - RemoveWidget(m_layers.back()); - m_layers.pop_back(); + Layer *layer = new Layer(this); + AddWidget(layer); + SetWidgetDimensions(layer, Point(0), Point(m_width, m_height)); + m_layers.push_back(layer); m_needsLayout = true; + return layer; } -} -void Context::DropAllLayers() -{ - for (std::vector::iterator i = m_layers.begin(); i != m_layers.end(); ++i) - RemoveWidget(*i); - m_layers.clear(); - NewLayer(); - m_needsLayout = true; -} - -void Context::HandleKeyDown(const KeyboardEvent &event) { - if (event.keysym.sym == SDLK_ESCAPE) { - if (m_layers.size()>1) { - // go back to previous layer - DropLayer(); + void Context::DropLayer() + { + // dropping the last layer would be bad + if (m_layers.size() > 1) { + RemoveWidget(m_layers.back()); + m_layers.pop_back(); + m_needsLayout = true; } } -} -Widget *Context::GetWidgetAt(const Point &pos) -{ - return GetTopLayer()->GetWidgetAt(pos); -} + void Context::DropAllLayers() + { + for (std::vector::iterator i = m_layers.begin(); i != m_layers.end(); ++i) + RemoveWidget(*i); + m_layers.clear(); + NewLayer(); + m_needsLayout = true; + } -void Context::Layout() -{ - // some widgets (eg MultiLineText) can require two layout passes because we - // don't know their preferred size until after their first layout run. so - // then we have to do layout again to make sure everyone else gets it right - m_needsLayout = false; + void Context::HandleKeyDown(const KeyboardEvent &event) + { + if (event.keysym.sym == SDLK_ESCAPE) { + if (m_layers.size() > 1) { + // go back to previous layer + DropLayer(); + } + } + } + + Widget *Context::GetWidgetAt(const Point &pos) + { + return GetTopLayer()->GetWidgetAt(pos); + } + + void Context::Layout() + { + // some widgets (eg MultiLineText) can require two layout passes because we + // don't know their preferred size until after their first layout run. so + // then we have to do layout again to make sure everyone else gets it right + m_needsLayout = false; - LayoutChildren(); - if (m_needsLayout) LayoutChildren(); + if (m_needsLayout) + LayoutChildren(); - m_needsLayout = false; + m_needsLayout = false; - m_eventDispatcher.LayoutUpdated(); -} - -void Context::Update() -{ - m_animationController.Update(); - - if (m_needsLayout) - Layout(); - - if (m_mousePointer && m_mousePointerEnabled) - SetWidgetDimensions(m_mousePointer, m_eventDispatcher.GetMousePos()-m_mousePointer->GetHotspot(), m_mousePointer->PreferredSize()); - - Container::Update(); -} - -void Context::Draw() -{ - Graphics::Renderer *r = GetRenderer(); - r->ClearDepthBuffer(); - - // Ticket for the viewport mostly - Graphics::Renderer::StateTicket ticket(r); - r->SetViewport(0, 0, m_width, m_height); - - // reset renderer for each layer - for (std::vector::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { - r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1); - r->SetTransform(matrix4x4f::Identity()); - r->SetClearColor(Color::BLACK); - - DrawWidget(*i); - - r->SetScissor(false); + m_eventDispatcher.LayoutUpdated(); } - if (m_mousePointer && m_mousePointerEnabled) { - r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1); - r->SetTransform(matrix4x4f::Identity()); - r->SetClearColor(Color::BLACK); - DrawWidget(m_mousePointer); - r->SetScissor(false); - } -} + void Context::Update() + { + m_animationController.Update(); -Widget *Context::CallTemplate(const char *name, const LuaTable &args) -{ - return ScopedTable(m_templateStore).Call(name, args); -} + if (m_needsLayout) + Layout(); -Widget *Context::CallTemplate(const char *name) -{ - return CallTemplate(name, ScopedTable(m_lua->GetLuaState())); -} + if (m_mousePointer && m_mousePointerEnabled) + SetWidgetDimensions(m_mousePointer, m_eventDispatcher.GetMousePos() - m_mousePointer->GetHotspot(), m_mousePointer->PreferredSize()); -void Context::DrawWidget(Widget *w) -{ - const Point &pos = w->GetPosition(); - const Point &drawOffset = w->GetDrawOffset(); - const Point &size = w->GetSize(); - - const float &animX = w->GetAnimatedPositionX(); - const float &animY = w->GetAnimatedPositionY(); - - const bool isAnimating = fabs(animX) < 1.0f || fabs(animY) < 1.0f; - - Point finalPos; - if (isAnimating) { - const Point absPos = w->GetAbsolutePosition(); - - finalPos = Point( - animX < 0.0f ? m_width-(m_width-pos.x)*-animX : (pos.x+size.x)*animX-size.x-absPos.x*(1.0f-animX), - animY < 0.0f ? m_height-(m_height-pos.y)*-animY : (pos.y+size.y)*animY-size.y-absPos.y*(1.0f-animY) - ); - } - else - finalPos = w->GetPosition(); - - m_drawWidgetPosition += finalPos; - - Point newScissorPos, newScissorSize; - if (isAnimating) { - newScissorPos = m_drawWidgetPosition; - newScissorSize = size; - } - else { - const std::pair ¤tScissor(m_scissorStack.top()); - const Point ¤tScissorPos(currentScissor.first); - const Point ¤tScissorSize(currentScissor.second); - - newScissorPos = Point(std::max(m_drawWidgetPosition.x, currentScissorPos.x), std::max(m_drawWidgetPosition.y, currentScissorPos.y)); - - newScissorSize = Point( - Clamp(std::min(newScissorPos.x + size.x, currentScissorPos.x + currentScissorSize.x) - newScissorPos.x, 0, m_width), - Clamp(std::min(newScissorPos.y + size.y, currentScissorPos.y + currentScissorSize.y) - newScissorPos.y, 0, m_height)); + Container::Update(); } - m_scissorStack.push(std::make_pair(newScissorPos, newScissorSize)); + void Context::Draw() + { + Graphics::Renderer *r = GetRenderer(); + r->ClearDepthBuffer(); - m_renderer->SetScissor(true, vector2f(newScissorPos.x, m_height - newScissorPos.y - newScissorSize.y), vector2f(newScissorSize.x, newScissorSize.y)); + // Ticket for the viewport mostly + Graphics::Renderer::StateTicket ticket(r); + r->SetViewport(0, 0, m_width, m_height); - m_drawWidgetPosition += drawOffset; + // reset renderer for each layer + for (std::vector::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { + r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1); + r->SetTransform(matrix4x4f::Identity()); + r->SetClearColor(Color::BLACK); - m_renderer->SetTransform(matrix4x4f::Translation(m_drawWidgetPosition.x, m_drawWidgetPosition.y, 0)); + DrawWidget(*i); - float oldOpacity = m_opacityStack.empty() ? 1.0f : m_opacityStack.top(); - float opacity = oldOpacity * w->GetAnimatedOpacity(); - m_opacityStack.push(opacity); - m_skin.SetOpacity(opacity); + r->SetScissor(false); + } - w->Draw(); - - m_opacityStack.pop(); - m_scissorStack.pop(); - - m_drawWidgetPosition -= finalPos + drawOffset; -} - -void Context::SetMousePointer(const std::string &filename, const Point &hotspot) -{ - Point pos(0); - - if (m_mousePointer) { - pos = m_mousePointer->GetPosition() + m_mousePointer->GetHotspot(); - RemoveWidget(m_mousePointer); + if (m_mousePointer && m_mousePointerEnabled) { + r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1); + r->SetTransform(matrix4x4f::Identity()); + r->SetClearColor(Color::BLACK); + DrawWidget(m_mousePointer); + r->SetScissor(false); + } } - m_mousePointer = new MousePointer(this, filename, hotspot); + Widget *Context::CallTemplate(const char *name, const LuaTable &args) + { + return ScopedTable(m_templateStore).Call(name, args); + } - AddWidget(m_mousePointer); - SetWidgetDimensions(m_mousePointer, pos - m_mousePointer->GetHotspot(), m_mousePointer->PreferredSize()); -} + Widget *Context::CallTemplate(const char *name) + { + return CallTemplate(name, ScopedTable(m_lua->GetLuaState())); + } -} + void Context::DrawWidget(Widget *w) + { + const Point &pos = w->GetPosition(); + const Point &drawOffset = w->GetDrawOffset(); + const Point &size = w->GetSize(); + + const float &animX = w->GetAnimatedPositionX(); + const float &animY = w->GetAnimatedPositionY(); + + const bool isAnimating = fabs(animX) < 1.0f || fabs(animY) < 1.0f; + + Point finalPos; + if (isAnimating) { + const Point absPos = w->GetAbsolutePosition(); + + finalPos = Point( + animX < 0.0f ? m_width - (m_width - pos.x) * -animX : (pos.x + size.x) * animX - size.x - absPos.x * (1.0f - animX), + animY < 0.0f ? m_height - (m_height - pos.y) * -animY : (pos.y + size.y) * animY - size.y - absPos.y * (1.0f - animY)); + } else + finalPos = w->GetPosition(); + + m_drawWidgetPosition += finalPos; + + Point newScissorPos, newScissorSize; + if (isAnimating) { + newScissorPos = m_drawWidgetPosition; + newScissorSize = size; + } else { + const std::pair ¤tScissor(m_scissorStack.top()); + const Point ¤tScissorPos(currentScissor.first); + const Point ¤tScissorSize(currentScissor.second); + + newScissorPos = Point(std::max(m_drawWidgetPosition.x, currentScissorPos.x), std::max(m_drawWidgetPosition.y, currentScissorPos.y)); + + newScissorSize = Point( + Clamp(std::min(newScissorPos.x + size.x, currentScissorPos.x + currentScissorSize.x) - newScissorPos.x, 0, m_width), + Clamp(std::min(newScissorPos.y + size.y, currentScissorPos.y + currentScissorSize.y) - newScissorPos.y, 0, m_height)); + } + + m_scissorStack.push(std::make_pair(newScissorPos, newScissorSize)); + + m_renderer->SetScissor(true, vector2f(newScissorPos.x, m_height - newScissorPos.y - newScissorSize.y), vector2f(newScissorSize.x, newScissorSize.y)); + + m_drawWidgetPosition += drawOffset; + + m_renderer->SetTransform(matrix4x4f::Translation(m_drawWidgetPosition.x, m_drawWidgetPosition.y, 0)); + + float oldOpacity = m_opacityStack.empty() ? 1.0f : m_opacityStack.top(); + float opacity = oldOpacity * w->GetAnimatedOpacity(); + m_opacityStack.push(opacity); + m_skin.SetOpacity(opacity); + + w->Draw(); + + m_opacityStack.pop(); + m_scissorStack.pop(); + + m_drawWidgetPosition -= finalPos + drawOffset; + } + + void Context::SetMousePointer(const std::string &filename, const Point &hotspot) + { + Point pos(0); + + if (m_mousePointer) { + pos = m_mousePointer->GetPosition() + m_mousePointer->GetHotspot(); + RemoveWidget(m_mousePointer); + } + + m_mousePointer = new MousePointer(this, filename, hotspot); + + AddWidget(m_mousePointer); + SetWidgetDimensions(m_mousePointer, pos - m_mousePointer->GetHotspot(), m_mousePointer->PreferredSize()); + } + +} // namespace UI diff --git a/src/ui/Context.h b/src/ui/Context.h index aa073c899..ae7c71e14 100644 --- a/src/ui/Context.h +++ b/src/ui/Context.h @@ -7,38 +7,37 @@ #include "RefCounted.h" #include "text/TextureFont.h" -#include "EventDispatcher.h" #include "Animation.h" +#include "EventDispatcher.h" #include "Skin.h" -#include "Widget.h" #include "Layer.h" +#include "Widget.h" -#include "Margin.h" #include "Align.h" #include "Background.h" -#include "ColorBackground.h" -#include "Gradient.h" -#include "Expand.h" #include "Box.h" +#include "Button.h" +#include "CheckBox.h" +#include "ColorBackground.h" +#include "DropDown.h" +#include "Expand.h" +#include "Gauge.h" +#include "Gradient.h" #include "Grid.h" -#include "Scroller.h" #include "Icon.h" #include "Image.h" #include "Label.h" -#include "NumberLabel.h" -#include "MultiLineText.h" -#include "Button.h" -#include "CheckBox.h" -#include "Slider.h" #include "List.h" -#include "DropDown.h" -#include "TextEntry.h" -#include "SmallButton.h" -#include "Icon.h" -#include "Gauge.h" -#include "Table.h" +#include "Margin.h" +#include "MultiLineText.h" +#include "NumberLabel.h" #include "OverlayStack.h" +#include "Scroller.h" +#include "Slider.h" +#include "SmallButton.h" +#include "Table.h" +#include "TextEntry.h" #include "MousePointer.h" @@ -48,161 +47,163 @@ #include class LuaManager; -namespace Graphics { class Renderer; } +namespace Graphics { + class Renderer; +} namespace UI { -// The UI context is the top-level container, and covers the entire screen. -// Typically you will have one UI context per renderer context. Its slightly -// different to other containers internally to allow it to be a "live" widget -// without a parent container of its own. -// -// While it is a container, the context cannot accept arbitrary widgets. -// Instead it can hold one more Layers. Each Layer is a complete widget -// "stack", independent of other layers. Layers are rendered from oldest to -// newest, and only the top one receives input. -// -// The context holds resources that are shared by all widgets. Examples of such -// resources are fonts, default styles, textures and so on. New widgets are -// created from a context, and can access their context by calling their -// GetContext() method. -// -// It also holds an event dispatcher for distributing events to its widgets. + // The UI context is the top-level container, and covers the entire screen. + // Typically you will have one UI context per renderer context. Its slightly + // different to other containers internally to allow it to be a "live" widget + // without a parent container of its own. + // + // While it is a container, the context cannot accept arbitrary widgets. + // Instead it can hold one more Layers. Each Layer is a complete widget + // "stack", independent of other layers. Layers are rendered from oldest to + // newest, and only the top one receives input. + // + // The context holds resources that are shared by all widgets. Examples of such + // resources are fonts, default styles, textures and so on. New widgets are + // created from a context, and can access their context by calling their + // GetContext() method. + // + // It also holds an event dispatcher for distributing events to its widgets. -class Context : public Container { -public: - Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height); - Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height, float scale); + class Context : public Container { + public: + Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height); + Context(LuaManager *lua, Graphics::Renderer *renderer, int width, int height, float scale); - // general purpose containers - UI::HBox *HBox(float spacing = 0.0f) { return new UI::HBox(this, spacing); } - UI::VBox *VBox(float spacing = 0.0f) { return new UI::VBox(this, spacing); } - UI::Grid *Grid(const UI::CellSpec &rowSpec, const UI::CellSpec &colSpec) { return new UI::Grid(this, rowSpec, colSpec); } - UI::Table *Table() { return new UI::Table(this); } - UI::OverlayStack *OverlayStack() { return new UI::OverlayStack(this); } + // general purpose containers + UI::HBox *HBox(float spacing = 0.0f) { return new UI::HBox(this, spacing); } + UI::VBox *VBox(float spacing = 0.0f) { return new UI::VBox(this, spacing); } + UI::Grid *Grid(const UI::CellSpec &rowSpec, const UI::CellSpec &colSpec) { return new UI::Grid(this, rowSpec, colSpec); } + UI::Table *Table() { return new UI::Table(this); } + UI::OverlayStack *OverlayStack() { return new UI::OverlayStack(this); } - // single containers - UI::Background *Background() { return new UI::Background(this); } - UI::ColorBackground *ColorBackground(const Color &color) { return new UI::ColorBackground(this, color); } - UI::Margin *Margin(int margin, Margin::Direction direction = Margin::ALL) { return new UI::Margin(this, margin, direction); }; - UI::Align *Align(UI::Align::Direction direction) { return new UI::Align(this, direction); } - UI::Gradient *Gradient(const Color &beginColor, const Color &endColor, Gradient::Direction direction = Gradient::VERTICAL) { return new UI::Gradient(this, beginColor, endColor, direction); } - UI::Expand *Expand(UI::Expand::Direction direction = Expand::BOTH) { return new UI::Expand(this, direction); } - UI::Scroller *Scroller() { return new UI::Scroller(this); } + // single containers + UI::Background *Background() { return new UI::Background(this); } + UI::ColorBackground *ColorBackground(const Color &color) { return new UI::ColorBackground(this, color); } + UI::Margin *Margin(int margin, Margin::Direction direction = Margin::ALL) { return new UI::Margin(this, margin, direction); }; + UI::Align *Align(UI::Align::Direction direction) { return new UI::Align(this, direction); } + UI::Gradient *Gradient(const Color &beginColor, const Color &endColor, Gradient::Direction direction = Gradient::VERTICAL) { return new UI::Gradient(this, beginColor, endColor, direction); } + UI::Expand *Expand(UI::Expand::Direction direction = Expand::BOTH) { return new UI::Expand(this, direction); } + UI::Scroller *Scroller() { return new UI::Scroller(this); } - // visual elements - UI::Image *Image(const std::string &filename, Uint32 sizeControlFlags = 0) { return new UI::Image(this, filename, sizeControlFlags); } - UI::Label *Label(const std::string &text) { return new UI::Label(this, text); } - UI::NumberLabel *NumberLabel(NumberLabel::Format format = NumberLabel::FORMAT_NUMBER) { return new UI::NumberLabel(this, format); } - UI::Icon *Icon(const std::string &iconName) { return new UI::Icon(this, iconName); } + // visual elements + UI::Image *Image(const std::string &filename, Uint32 sizeControlFlags = 0) { return new UI::Image(this, filename, sizeControlFlags); } + UI::Label *Label(const std::string &text) { return new UI::Label(this, text); } + UI::NumberLabel *NumberLabel(NumberLabel::Format format = NumberLabel::FORMAT_NUMBER) { return new UI::NumberLabel(this, format); } + UI::Icon *Icon(const std::string &iconName) { return new UI::Icon(this, iconName); } - UI::MultiLineText *MultiLineText(const std::string &text) { return new UI::MultiLineText(this, text); } + UI::MultiLineText *MultiLineText(const std::string &text) { return new UI::MultiLineText(this, text); } - UI::Button *Button() { return new UI::Button(this); } - UI::SmallButton *SmallButton() { return new UI::SmallButton(this); } - UI::CheckBox *CheckBox() { return new UI::CheckBox(this); } + UI::Button *Button() { return new UI::Button(this); } + UI::SmallButton *SmallButton() { return new UI::SmallButton(this); } + UI::CheckBox *CheckBox() { return new UI::CheckBox(this); } - UI::HSlider *HSlider() { return new UI::HSlider(this); } - UI::VSlider *VSlider() { return new UI::VSlider(this); } + UI::HSlider *HSlider() { return new UI::HSlider(this); } + UI::VSlider *VSlider() { return new UI::VSlider(this); } - UI::List *List() { return new UI::List(this); } - UI::DropDown *DropDown() { return new UI::DropDown(this); } + UI::List *List() { return new UI::List(this); } + UI::DropDown *DropDown() { return new UI::DropDown(this); } - UI::Gauge *Gauge() { return new UI::Gauge(this); } + UI::Gauge *Gauge() { return new UI::Gauge(this); } - UI::TextEntry *TextEntry(const std::string &text = "") { return new UI::TextEntry(this, text); } + UI::TextEntry *TextEntry(const std::string &text = "") { return new UI::TextEntry(this, text); } - // layers feel like a stack - Layer *NewLayer(); - void DropLayer(); - void DropAllLayers(); - Layer *GetTopLayer() const { return m_layers.back(); } + // layers feel like a stack + Layer *NewLayer(); + void DropLayer(); + void DropAllLayers(); + Layer *GetTopLayer() const { return m_layers.back(); } - // only considers the current layer - virtual Widget *GetWidgetAt(const Point &pos); + // only considers the current layer + virtual Widget *GetWidgetAt(const Point &pos); - Widget *GetSelected() const { return m_eventDispatcher.GetSelected(); } - Widget *GetMouseActive() const { return m_eventDispatcher.GetMouseActive(); } + Widget *GetSelected() const { return m_eventDispatcher.GetSelected(); } + Widget *GetMouseActive() const { return m_eventDispatcher.GetMouseActive(); } - Point GetMousePos() const { return m_eventDispatcher.GetMousePos(); } + Point GetMousePos() const { return m_eventDispatcher.GetMousePos(); } - void SetMousePointer(const std::string &filename, const Point &hotspot); - void SetMousePointerEnabled(bool enabled) { m_mousePointerEnabled = enabled; } - // handler for keydown events - void HandleKeyDown(const KeyboardEvent &event); + void SetMousePointer(const std::string &filename, const Point &hotspot); + void SetMousePointerEnabled(bool enabled) { m_mousePointerEnabled = enabled; } + // handler for keydown events + void HandleKeyDown(const KeyboardEvent &event); - // event dispatch delegates - bool Dispatch(const Event &event) { return m_eventDispatcher.Dispatch(event); } - bool DispatchSDLEvent(const SDL_Event &event) { return m_eventDispatcher.DispatchSDLEvent(event); } + // event dispatch delegates + bool Dispatch(const Event &event) { return m_eventDispatcher.Dispatch(event); } + bool DispatchSDLEvent(const SDL_Event &event) { return m_eventDispatcher.DispatchSDLEvent(event); } - void RequestLayout() { m_needsLayout = true; } + void RequestLayout() { m_needsLayout = true; } - void SelectWidget(Widget *target) { m_eventDispatcher.SelectWidget(target); } - void DeselectWidget(Widget *target) { m_eventDispatcher.DeselectWidget(target); } + void SelectWidget(Widget *target) { m_eventDispatcher.SelectWidget(target); } + void DeselectWidget(Widget *target) { m_eventDispatcher.DeselectWidget(target); } - void DisableWidget(Widget *target) { m_eventDispatcher.DisableWidget(target); } - void EnableWidget(Widget *target) { m_eventDispatcher.EnableWidget(target); } + void DisableWidget(Widget *target) { m_eventDispatcher.DisableWidget(target); } + void EnableWidget(Widget *target) { m_eventDispatcher.EnableWidget(target); } - void ResetMouseActiveReceiver() { m_eventDispatcher.ResetMouseActiveReceiver(); } + void ResetMouseActiveReceiver() { m_eventDispatcher.ResetMouseActiveReceiver(); } - virtual void Layout(); - virtual void Update(); - virtual void Draw(); + virtual void Layout(); + virtual void Update(); + virtual void Draw(); - void Animate(Animation *animation) { m_animationController.Add(animation); } + void Animate(Animation *animation) { m_animationController.Add(animation); } - LuaRef GetTemplateStore() const { return m_templateStore; } - Widget *CallTemplate(const char *name, const LuaTable &args); - Widget *CallTemplate(const char *name); + LuaRef GetTemplateStore() const { return m_templateStore; } + Widget *CallTemplate(const char *name, const LuaTable &args); + Widget *CallTemplate(const char *name); - Graphics::Renderer *GetRenderer() const { return m_renderer; } - const Skin &GetSkin() const { return m_skin; } + Graphics::Renderer *GetRenderer() const { return m_renderer; } + const Skin &GetSkin() const { return m_skin; } - const float &GetScale() const { return m_scale; } + const float &GetScale() const { return m_scale; } - RefCountedPtr GetFont() const { return GetFont(Widget::FONT_NORMAL); } - RefCountedPtr GetFont(Widget::Font font) const { return m_font[font]; } + RefCountedPtr GetFont() const { return GetFont(Widget::FONT_NORMAL); } + RefCountedPtr GetFont(Widget::Font font) const { return m_font[font]; } - const Point &GetScissor() const { return m_scissorStack.top().second; } - const float &GetOpacity() const { return m_opacityStack.top(); } + const Point &GetScissor() const { return m_scissorStack.top().second; } + const float &GetOpacity() const { return m_opacityStack.top(); } -private: - virtual Point PreferredSize() { return Point(); } + private: + virtual Point PreferredSize() { return Point(); } - Graphics::Renderer *m_renderer; - int m_width; - int m_height; + Graphics::Renderer *m_renderer; + int m_width; + int m_height; - float m_scale; + float m_scale; - bool m_needsLayout; + bool m_needsLayout; - std::vector m_layers; + std::vector m_layers; - MousePointer *m_mousePointer; - bool m_mousePointerEnabled; + MousePointer *m_mousePointer; + bool m_mousePointerEnabled; - EventDispatcher m_eventDispatcher; - AnimationController m_animationController; - Skin m_skin; + EventDispatcher m_eventDispatcher; + AnimationController m_animationController; + Skin m_skin; - LuaManager *m_lua; + LuaManager *m_lua; - LuaRef m_templateStore; + LuaRef m_templateStore; - RefCountedPtr m_font[FONT_MAX]; + RefCountedPtr m_font[FONT_MAX]; - // Container will draw widgets through the Context to correctly accumulate - // positions and offsets - friend class Container; - void DrawWidget(Widget *w); + // Container will draw widgets through the Context to correctly accumulate + // positions and offsets + friend class Container; + void DrawWidget(Widget *w); - // support for DrawWidget() - Point m_drawWidgetPosition; - std::stack< std::pair > m_scissorStack; - std::stack m_opacityStack; -}; + // support for DrawWidget() + Point m_drawWidgetPosition; + std::stack> m_scissorStack; + std::stack m_opacityStack; + }; -} +} // namespace UI #endif diff --git a/src/ui/DropDown.cpp b/src/ui/DropDown.cpp index f0bdb685f..03a9b54a1 100644 --- a/src/ui/DropDown.cpp +++ b/src/ui/DropDown.cpp @@ -2,152 +2,152 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "DropDown.h" -#include "Context.h" #include "ColorBackground.h" +#include "Context.h" #include "text/TextureFont.h" namespace UI { -// XXX move to config, share with TabGroup -static const Color normalColor(128, 128, 128, 255); -static const Color hoverColor(204, 204, 204, 255); -static const Color activeColor(255, 255, 255, 255); + // XXX move to config, share with TabGroup + static const Color normalColor(128, 128, 128, 255); + static const Color hoverColor(204, 204, 204, 255); + static const Color activeColor(255, 255, 255, 255); -DropDown::DropDown(Context *context) : Container(context), m_popupWantToggle(false), m_popupActive(false) -{ - Context *c = GetContext(); - - m_popup.Reset(c->List()); - m_popup->onOptionSelected.connect(sigc::mem_fun(onOptionSelected, &sigc::signal::emit)); - m_popup->onClick.connect(sigc::mem_fun(this, &DropDown::HandlePopupClick)); - - m_container = c->Background(); - m_label = c->Label(""); - m_icon = c->Icon("ArrowDown"); - m_icon->SetColor(normalColor); - m_container->SetInnerWidget( - c->HBox(5)->PackEnd( - WidgetSet(c->Expand(UI::Expand::HORIZONTAL)->SetInnerWidget(m_label), m_icon) - ) - ); - - AddWidget(m_container); -} - -Point DropDown::PreferredSize() -{ - return m_container->PreferredSize(); -} - -void DropDown::Layout() -{ - SetWidgetDimensions(m_container, Point(), GetSize()); - m_container->Layout(); -} - -void DropDown::Update() -{ - if (m_popupWantToggle) { + DropDown::DropDown(Context *context) : + Container(context), + m_popupWantToggle(false), + m_popupActive(false) + { Context *c = GetContext(); - if (m_popupActive) { - m_contextClickCon.disconnect(); - m_label->SetText(m_popup->GetSelectedOption()); - c->DropLayer(); - m_popupActive = false; - m_icon->SetColor(IsMouseOver() ? hoverColor : normalColor); - } + m_popup.Reset(c->List()); + m_popup->onOptionSelected.connect(sigc::mem_fun(onOptionSelected, &sigc::signal::emit)); + m_popup->onClick.connect(sigc::mem_fun(this, &DropDown::HandlePopupClick)); - else { - const Point pos(GetAbsolutePosition() + Point(0, GetSize().y)); - m_popup->SetFont(GetFont()); - c->NewLayer()->SetInnerWidget(m_popup.Get(), pos, m_popup->PreferredSize()); - m_popupActive = true; - m_icon->SetColor(activeColor); - m_contextClickCon = c->onClick.connect(sigc::mem_fun(this, &DropDown::HandlePopupClick)); - } + m_container = c->Background(); + m_label = c->Label(""); + m_icon = c->Icon("ArrowDown"); + m_icon->SetColor(normalColor); + m_container->SetInnerWidget( + c->HBox(5)->PackEnd( + WidgetSet(c->Expand(UI::Expand::HORIZONTAL)->SetInnerWidget(m_label), m_icon))); - m_popupWantToggle = false; + AddWidget(m_container); } - Container::Update(); -} - -void DropDown::HandleClick() -{ - m_popupWantToggle = true; - Widget::HandleClick(); -} - -bool DropDown::HandlePopupClick() -{ - m_popupWantToggle = true; - return true; -} - -void DropDown::HandleMouseOver() -{ - m_icon->SetColor(m_popupActive ? activeColor : hoverColor); -} - -void DropDown::HandleMouseOut() -{ - m_icon->SetColor(m_popupActive ? activeColor : normalColor); -} - -DropDown *DropDown::AddOption(const std::string &text) -{ - float w, h; - GetContext()->GetFont(GetFont())->MeasureString(text.c_str(), w, h); - - m_popup->AddOption(text); - - m_label->SetText(m_popup->GetSelectedOption()); - - return this; -} - -bool DropDown::IsEmpty() const -{ - return m_popup->IsEmpty(); -} - -size_t DropDown::NumItems() const -{ - return m_popup->NumItems(); -} - -const std::string &DropDown::GetSelectedOption() const -{ - return m_popup->GetSelectedOption(); -} - -bool DropDown::SetSelectedOption(const std::string &option) -{ - if (m_popup->SetSelectedOption(option)) + Point DropDown::PreferredSize() { - m_label->SetText(option); + return m_container->PreferredSize(); + } + + void DropDown::Layout() + { + SetWidgetDimensions(m_container, Point(), GetSize()); + m_container->Layout(); + } + + void DropDown::Update() + { + if (m_popupWantToggle) { + Context *c = GetContext(); + + if (m_popupActive) { + m_contextClickCon.disconnect(); + m_label->SetText(m_popup->GetSelectedOption()); + c->DropLayer(); + m_popupActive = false; + m_icon->SetColor(IsMouseOver() ? hoverColor : normalColor); + } + + else { + const Point pos(GetAbsolutePosition() + Point(0, GetSize().y)); + m_popup->SetFont(GetFont()); + c->NewLayer()->SetInnerWidget(m_popup.Get(), pos, m_popup->PreferredSize()); + m_popupActive = true; + m_icon->SetColor(activeColor); + m_contextClickCon = c->onClick.connect(sigc::mem_fun(this, &DropDown::HandlePopupClick)); + } + + m_popupWantToggle = false; + } + + Container::Update(); + } + + void DropDown::HandleClick() + { + m_popupWantToggle = true; + Widget::HandleClick(); + } + + bool DropDown::HandlePopupClick() + { + m_popupWantToggle = true; return true; } - return false; -} -int DropDown::GetSelectedIndex() const -{ - return m_popup->GetSelectedIndex(); -} + void DropDown::HandleMouseOver() + { + m_icon->SetColor(m_popupActive ? activeColor : hoverColor); + } -void DropDown::SetSelectedIndex(const int index) -{ - m_popup->SetSelectedIndex(index); - m_label->SetText(m_popup->GetSelectedOption()); -} + void DropDown::HandleMouseOut() + { + m_icon->SetColor(m_popupActive ? activeColor : normalColor); + } -void DropDown::Clear() -{ - m_popup->Clear(); - if (m_popupActive) - m_popupWantToggle = true; -} + DropDown *DropDown::AddOption(const std::string &text) + { + float w, h; + GetContext()->GetFont(GetFont())->MeasureString(text.c_str(), w, h); -} + m_popup->AddOption(text); + + m_label->SetText(m_popup->GetSelectedOption()); + + return this; + } + + bool DropDown::IsEmpty() const + { + return m_popup->IsEmpty(); + } + + size_t DropDown::NumItems() const + { + return m_popup->NumItems(); + } + + const std::string &DropDown::GetSelectedOption() const + { + return m_popup->GetSelectedOption(); + } + + bool DropDown::SetSelectedOption(const std::string &option) + { + if (m_popup->SetSelectedOption(option)) { + m_label->SetText(option); + return true; + } + return false; + } + + int DropDown::GetSelectedIndex() const + { + return m_popup->GetSelectedIndex(); + } + + void DropDown::SetSelectedIndex(const int index) + { + m_popup->SetSelectedIndex(index); + m_label->SetText(m_popup->GetSelectedOption()); + } + + void DropDown::Clear() + { + m_popup->Clear(); + if (m_popupActive) + m_popupWantToggle = true; + } + +} // namespace UI diff --git a/src/ui/DropDown.h b/src/ui/DropDown.h index c66563193..9551244f7 100644 --- a/src/ui/DropDown.h +++ b/src/ui/DropDown.h @@ -8,52 +8,52 @@ namespace UI { -class Background; -class Label; -class Icon; -class List; + class Background; + class Label; + class Icon; + class List; -class DropDown : public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Update(); + class DropDown : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Update(); - DropDown *AddOption(const std::string &text); - void Clear(); + DropDown *AddOption(const std::string &text); + void Clear(); - size_t NumItems() const; - bool IsEmpty() const; + size_t NumItems() const; + bool IsEmpty() const; - const std::string &GetSelectedOption() const; - bool SetSelectedOption(const std::string &option); - int GetSelectedIndex() const; - void SetSelectedIndex(const int index); + const std::string &GetSelectedOption() const; + bool SetSelectedOption(const std::string &option); + int GetSelectedIndex() const; + void SetSelectedIndex(const int index); - sigc::signal onOptionSelected; + sigc::signal onOptionSelected; -protected: - friend class Context; - DropDown(Context *context); + protected: + friend class Context; + DropDown(Context *context); - void HandleClick(); - void HandleMouseOver(); - void HandleMouseOut(); + void HandleClick(); + void HandleMouseOver(); + void HandleMouseOut(); -private: - Background *m_container; - Label *m_label; - Icon *m_icon; + private: + Background *m_container; + Label *m_label; + Icon *m_icon; - bool HandlePopupClick(); + bool HandlePopupClick(); - RefCountedPtr m_popup; - bool m_popupWantToggle; - bool m_popupActive; + RefCountedPtr m_popup; + bool m_popupWantToggle; + bool m_popupActive; - sigc::connection m_contextClickCon; -}; + sigc::connection m_contextClickCon; + }; -} +} // namespace UI #endif diff --git a/src/ui/Event.cpp b/src/ui/Event.cpp index 1d1d14277..080764675 100644 --- a/src/ui/Event.cpp +++ b/src/ui/Event.cpp @@ -2,247 +2,247 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Event.h" -#include "LuaObject.h" #include "EnumStrings.h" +#include "LuaObject.h" namespace UI { -struct KeyMap { - const char *name; - SDL_Keycode sym; -}; -static const KeyMap keymap[] = { - { "backspace", SDLK_BACKSPACE }, - { "tab", SDLK_TAB }, - { "enter", SDLK_RETURN }, - { "pause", SDLK_PAUSE }, - { "esc", SDLK_ESCAPE }, - { "space", SDLK_SPACE }, - { "'", SDLK_QUOTE }, - { ",", SDLK_COMMA }, - { "-", SDLK_MINUS }, - { ".", SDLK_PERIOD }, - { "/", SDLK_SLASH }, - { "0", SDLK_0 }, - { "1", SDLK_1 }, - { "2", SDLK_2 }, - { "3", SDLK_3 }, - { "4", SDLK_4 }, - { "5", SDLK_5 }, - { "6", SDLK_6 }, - { "7", SDLK_7 }, - { "8", SDLK_8 }, - { "9", SDLK_9 }, - { ";", SDLK_SEMICOLON }, - { "=", SDLK_EQUALS }, - { "[", SDLK_LEFTBRACKET }, - { "\\", SDLK_BACKSLASH }, - { "]", SDLK_RIGHTBRACKET }, - { "`", SDLK_BACKQUOTE }, - { "a", SDLK_a }, - { "b", SDLK_b }, - { "c", SDLK_c }, - { "d", SDLK_d }, - { "e", SDLK_e }, - { "f", SDLK_f }, - { "g", SDLK_g }, - { "h", SDLK_h }, - { "i", SDLK_i }, - { "j", SDLK_j }, - { "k", SDLK_k }, - { "l", SDLK_l }, - { "m", SDLK_m }, - { "n", SDLK_n }, - { "o", SDLK_o }, - { "p", SDLK_p }, - { "q", SDLK_q }, - { "r", SDLK_r }, - { "s", SDLK_s }, - { "t", SDLK_t }, - { "u", SDLK_u }, - { "v", SDLK_v }, - { "w", SDLK_w }, - { "x", SDLK_x }, - { "y", SDLK_y }, - { "z", SDLK_z }, - { "delete", SDLK_DELETE }, - { "kp0", SDLK_KP_0 }, - { "kp1", SDLK_KP_1 }, - { "kp2", SDLK_KP_2 }, - { "kp3", SDLK_KP_3 }, - { "kp4", SDLK_KP_4 }, - { "kp5", SDLK_KP_5 }, - { "kp6", SDLK_KP_6 }, - { "kp7", SDLK_KP_7 }, - { "kp8", SDLK_KP_8 }, - { "kp9", SDLK_KP_9 }, - { "kp.", SDLK_KP_PERIOD }, - { "kp/", SDLK_KP_DIVIDE }, - { "kp*", SDLK_KP_MULTIPLY }, - { "kp-", SDLK_KP_MINUS }, - { "kp+", SDLK_KP_PLUS }, - { "kpenter", SDLK_KP_ENTER }, - { "up", SDLK_UP }, - { "down", SDLK_DOWN }, - { "right", SDLK_RIGHT }, - { "left", SDLK_LEFT }, - { "insert", SDLK_INSERT }, - { "home", SDLK_HOME }, - { "end", SDLK_END }, - { "pageup", SDLK_PAGEUP }, - { "pagedown", SDLK_PAGEDOWN }, - { "f1", SDLK_F1 }, - { "f2", SDLK_F2 }, - { "f3", SDLK_F3 }, - { "f4", SDLK_F4 }, - { "f5", SDLK_F5 }, - { "f6", SDLK_F6 }, - { "f7", SDLK_F7 }, - { "f8", SDLK_F8 }, - { "f9", SDLK_F9 }, - { "f10", SDLK_F10 }, - { "f11", SDLK_F11 }, - { "f12", SDLK_F12 }, - { "f13", SDLK_F13 }, - { "f14", SDLK_F14 }, - { "f15", SDLK_F15 }, - { "help", SDLK_HELP }, - { "printscreen", SDLK_PRINTSCREEN }, - { 0, 0 } -}; + struct KeyMap { + const char *name; + SDL_Keycode sym; + }; + static const KeyMap keymap[] = { + { "backspace", SDLK_BACKSPACE }, + { "tab", SDLK_TAB }, + { "enter", SDLK_RETURN }, + { "pause", SDLK_PAUSE }, + { "esc", SDLK_ESCAPE }, + { "space", SDLK_SPACE }, + { "'", SDLK_QUOTE }, + { ",", SDLK_COMMA }, + { "-", SDLK_MINUS }, + { ".", SDLK_PERIOD }, + { "/", SDLK_SLASH }, + { "0", SDLK_0 }, + { "1", SDLK_1 }, + { "2", SDLK_2 }, + { "3", SDLK_3 }, + { "4", SDLK_4 }, + { "5", SDLK_5 }, + { "6", SDLK_6 }, + { "7", SDLK_7 }, + { "8", SDLK_8 }, + { "9", SDLK_9 }, + { ";", SDLK_SEMICOLON }, + { "=", SDLK_EQUALS }, + { "[", SDLK_LEFTBRACKET }, + { "\\", SDLK_BACKSLASH }, + { "]", SDLK_RIGHTBRACKET }, + { "`", SDLK_BACKQUOTE }, + { "a", SDLK_a }, + { "b", SDLK_b }, + { "c", SDLK_c }, + { "d", SDLK_d }, + { "e", SDLK_e }, + { "f", SDLK_f }, + { "g", SDLK_g }, + { "h", SDLK_h }, + { "i", SDLK_i }, + { "j", SDLK_j }, + { "k", SDLK_k }, + { "l", SDLK_l }, + { "m", SDLK_m }, + { "n", SDLK_n }, + { "o", SDLK_o }, + { "p", SDLK_p }, + { "q", SDLK_q }, + { "r", SDLK_r }, + { "s", SDLK_s }, + { "t", SDLK_t }, + { "u", SDLK_u }, + { "v", SDLK_v }, + { "w", SDLK_w }, + { "x", SDLK_x }, + { "y", SDLK_y }, + { "z", SDLK_z }, + { "delete", SDLK_DELETE }, + { "kp0", SDLK_KP_0 }, + { "kp1", SDLK_KP_1 }, + { "kp2", SDLK_KP_2 }, + { "kp3", SDLK_KP_3 }, + { "kp4", SDLK_KP_4 }, + { "kp5", SDLK_KP_5 }, + { "kp6", SDLK_KP_6 }, + { "kp7", SDLK_KP_7 }, + { "kp8", SDLK_KP_8 }, + { "kp9", SDLK_KP_9 }, + { "kp.", SDLK_KP_PERIOD }, + { "kp/", SDLK_KP_DIVIDE }, + { "kp*", SDLK_KP_MULTIPLY }, + { "kp-", SDLK_KP_MINUS }, + { "kp+", SDLK_KP_PLUS }, + { "kpenter", SDLK_KP_ENTER }, + { "up", SDLK_UP }, + { "down", SDLK_DOWN }, + { "right", SDLK_RIGHT }, + { "left", SDLK_LEFT }, + { "insert", SDLK_INSERT }, + { "home", SDLK_HOME }, + { "end", SDLK_END }, + { "pageup", SDLK_PAGEUP }, + { "pagedown", SDLK_PAGEDOWN }, + { "f1", SDLK_F1 }, + { "f2", SDLK_F2 }, + { "f3", SDLK_F3 }, + { "f4", SDLK_F4 }, + { "f5", SDLK_F5 }, + { "f6", SDLK_F6 }, + { "f7", SDLK_F7 }, + { "f8", SDLK_F8 }, + { "f9", SDLK_F9 }, + { "f10", SDLK_F10 }, + { "f11", SDLK_F11 }, + { "f12", SDLK_F12 }, + { "f13", SDLK_F13 }, + { "f14", SDLK_F14 }, + { "f15", SDLK_F15 }, + { "help", SDLK_HELP }, + { "printscreen", SDLK_PRINTSCREEN }, + { 0, 0 } + }; -KeySym KeySym::FromString(const std::string &spec) -{ - static const std::string delim("+"); + KeySym KeySym::FromString(const std::string &spec) + { + static const std::string delim("+"); - SDL_Keycode sym = SDLK_UNKNOWN; - Uint32 mod = KMOD_NONE; + SDL_Keycode sym = SDLK_UNKNOWN; + Uint32 mod = KMOD_NONE; - size_t start = 0, end = 0; - while (end != std::string::npos) { - // get to the first non-delim char - start = spec.find_first_not_of(delim, end); + size_t start = 0, end = 0; + while (end != std::string::npos) { + // get to the first non-delim char + start = spec.find_first_not_of(delim, end); - // read the end, no more to do - if (start == std::string::npos) - break; + // read the end, no more to do + if (start == std::string::npos) + break; - // find the end - next delim or end of string - end = spec.find_first_of(delim, start); + // find the end - next delim or end of string + end = spec.find_first_of(delim, start); - // extract the fragment - const std::string token(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); + // extract the fragment + const std::string token(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); - if (token == "ctrl") - mod |= KMOD_CTRL; - else if (token == "shift") - mod |= KMOD_SHIFT; - else if (token == "alt") - mod |= KMOD_ALT; - else if (token == "meta") - mod |= KMOD_GUI; + if (token == "ctrl") + mod |= KMOD_CTRL; + else if (token == "shift") + mod |= KMOD_SHIFT; + else if (token == "alt") + mod |= KMOD_ALT; + else if (token == "meta") + mod |= KMOD_GUI; - else { - if (sym != SDLK_UNKNOWN) - Output("key spec '%s' has multiple keys, ignoring '%s'\n", spec.c_str(), token.c_str()); else { - for (const KeyMap *map = keymap; map->name; map++) - if (token == map->name) - sym = map->sym; - if (sym == SDLK_UNKNOWN) - Output("key spec '%s' has unkown token '%s', ignoring it\n", spec.c_str(), token.c_str()); + if (sym != SDLK_UNKNOWN) + Output("key spec '%s' has multiple keys, ignoring '%s'\n", spec.c_str(), token.c_str()); + else { + for (const KeyMap *map = keymap; map->name; map++) + if (token == map->name) + sym = map->sym; + if (sym == SDLK_UNKNOWN) + Output("key spec '%s' has unkown token '%s', ignoring it\n", spec.c_str(), token.c_str()); + } } } + + return KeySym(sym, SDL_Keymod(mod)); } - return KeySym(sym, SDL_Keymod(mod)); -} + static void _settable(lua_State *l, const char *key, const Point &value) + { + lua_pushstring(l, key); -static void _settable(lua_State *l, const char *key, const Point &value) -{ - lua_pushstring(l, key); + lua_newtable(l); + pi_lua_settable(l, "x", value.x); + pi_lua_settable(l, "y", value.y); - lua_newtable(l); - pi_lua_settable(l, "x", value.x); - pi_lua_settable(l, "y", value.y); + lua_rawset(l, -3); + } - lua_rawset(l, -3); -} + void KeyboardEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + pi_lua_settable(l, "action", EnumStrings::GetString("UIKeyboardAction", action)); + pi_lua_settable(l, "repeat", repeat); -void KeyboardEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); - pi_lua_settable(l, "action", EnumStrings::GetString("UIKeyboardAction", action)); - pi_lua_settable(l, "repeat", repeat); + // XXX expose sym and mod constants + } - // XXX expose sym and mod constants -} + void TextInputEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); -void TextInputEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + lua_pushvalue(l, unicode); + lua_setfield(l, -2, "unicode"); + } - lua_pushvalue(l, unicode); - lua_setfield(l, -2, "unicode"); -} + void MouseButtonEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); -void MouseButtonEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + _settable(l, "pos", pos); - _settable(l, "pos", pos); + pi_lua_settable(l, "action", EnumStrings::GetString("UIMouseButtonAction", action)); + pi_lua_settable(l, "button", EnumStrings::GetString("UIMouseButtonType", button)); + } - pi_lua_settable(l, "action", EnumStrings::GetString("UIMouseButtonAction", action)); - pi_lua_settable(l, "button", EnumStrings::GetString("UIMouseButtonType", button)); -} + void MouseMotionEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); -void MouseMotionEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + _settable(l, "pos", pos); + _settable(l, "rel", rel); + } - _settable(l, "pos", pos); - _settable(l, "rel", rel); -} + void MouseWheelEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); -void MouseWheelEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + _settable(l, "pos", pos); - _settable(l, "pos", pos); + pi_lua_settable(l, "direction", EnumStrings::GetString("UIMouseWheelDirection", direction)); + } - pi_lua_settable(l, "direction", EnumStrings::GetString("UIMouseWheelDirection", direction)); -} + void JoystickAxisMotionEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + pi_lua_settable(l, "joystick", joystick); + pi_lua_settable(l, "value", value); + pi_lua_settable(l, "axis", axis); + } -void JoystickAxisMotionEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); - pi_lua_settable(l, "joystick", joystick); - pi_lua_settable(l, "value", value); - pi_lua_settable(l, "axis", axis); -} + void JoystickHatMotionEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + pi_lua_settable(l, "joystick", joystick); + pi_lua_settable(l, "direction", EnumStrings::GetString("UIJoystickHatDirection", direction)); + pi_lua_settable(l, "hat", hat); + } -void JoystickHatMotionEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); - pi_lua_settable(l, "joystick", joystick); - pi_lua_settable(l, "direction", EnumStrings::GetString("UIJoystickHatDirection", direction)); - pi_lua_settable(l, "hat", hat); -} + void JoystickButtonEvent::ToLuaTable(lua_State *l) const + { + lua_newtable(l); + pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); + pi_lua_settable(l, "joystick", joystick); + pi_lua_settable(l, "action", EnumStrings::GetString("UIJoystickButtonAction", action)); + pi_lua_settable(l, "button", button); + } -void JoystickButtonEvent::ToLuaTable(lua_State *l) const -{ - lua_newtable(l); - pi_lua_settable(l, "type", EnumStrings::GetString("UIEventType", type)); - pi_lua_settable(l, "joystick", joystick); - pi_lua_settable(l, "action", EnumStrings::GetString("UIJoystickButtonAction", action)); - pi_lua_settable(l, "button", button); -} - -} +} // namespace UI diff --git a/src/ui/Event.h b/src/ui/Event.h index 6a995528e..9ab477e8f 100644 --- a/src/ui/Event.h +++ b/src/ui/Event.h @@ -4,197 +4,231 @@ #ifndef UI_EVENT_H #define UI_EVENT_H -#include "libs.h" #include "Point.h" +#include "libs.h" struct lua_State; namespace UI { -class Widget; + class Widget; -class NoEvent; -class KeyboardEvent; -class MouseButtonEvent; -class MouseMotionEvent; -class MouseWheelEvent; -class TextInputEvent; -class JoystickAxisMotionEvent; -class JoystickHatMotionEvent; -class JoystickButtonEvent; + class NoEvent; + class KeyboardEvent; + class MouseButtonEvent; + class MouseMotionEvent; + class MouseWheelEvent; + class TextInputEvent; + class JoystickAxisMotionEvent; + class JoystickHatMotionEvent; + class JoystickButtonEvent; -// base event. can't be instantiated directly -class Event { -public: - enum Type { // - KEYBOARD, - TEXT_INPUT, - MOUSE_BUTTON, - MOUSE_MOTION, - MOUSE_WHEEL, - JOYSTICK_AXIS_MOTION, - JOYSTICK_HAT_MOTION, - JOYSTICK_BUTTON - }; - const Type type; + // base event. can't be instantiated directly + class Event { + public: + enum Type { // + KEYBOARD, + TEXT_INPUT, + MOUSE_BUTTON, + MOUSE_MOTION, + MOUSE_WHEEL, + JOYSTICK_AXIS_MOTION, + JOYSTICK_HAT_MOTION, + JOYSTICK_BUTTON + }; + const Type type; - virtual void ToLuaTable(lua_State *l) const = 0; - virtual ~Event() {} -protected: - Event(Type _type) : type(_type) {} -}; + virtual void ToLuaTable(lua_State *l) const = 0; + virtual ~Event() {} -struct KeySym { - KeySym(const SDL_Keycode &_sym, const SDL_Keymod _mod, const Uint32 _unicode) : sym(_sym), mod(safe_mods(_mod)) {} - KeySym(const SDL_Keycode &_sym, const SDL_Keymod &_mod) : sym(_sym), mod(safe_mods(_mod)) {} - KeySym(const SDL_Keycode &_sym) : sym(_sym), mod(KMOD_NONE) {} - SDL_Keycode sym; - SDL_Keymod mod; - - static KeySym FromString(const std::string &spec); - - bool operator<(const KeySym &b) const { - return sym < b.sym || (sym == b.sym && mod < b.mod); - } - - bool operator==(const KeySym &b) const { - return sym == b.sym && mod == b.mod; - } - -private: - // mask off stuff like caps/numlock - static SDL_Keymod safe_mods(const SDL_Keymod m) { - return SDL_Keymod(Uint32(m) & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI)); - } -}; - -// data for various events -class KeyboardEvent : public Event { -public: - enum Action { // - KEY_DOWN, - KEY_UP, - }; - KeyboardEvent(Action _action, const KeySym &_keysym, bool _repeat) : Event(Event::KEYBOARD), action(_action), keysym(_keysym), repeat(_repeat) {} - const Action action; - const KeySym keysym; - const bool repeat; - - void ToLuaTable(lua_State *l) const; -}; - -class TextInputEvent : public Event { -public: - TextInputEvent(Uint32 _unicode) : Event(Event::TEXT_INPUT), unicode(_unicode) {} - const Uint32 unicode; - - void ToLuaTable(lua_State *l) const; -}; - -class MouseEvent : public Event { -public: - const Point pos; // relative to widget - -protected: - MouseEvent(Event::Type _type, const Point &_pos) : Event(_type), pos(_pos) {} -}; - -class MouseButtonEvent : public MouseEvent { -public: - enum Action { // - BUTTON_DOWN, - BUTTON_UP - }; - enum ButtonType { // - BUTTON_LEFT, - BUTTON_MIDDLE, - BUTTON_RIGHT - }; - MouseButtonEvent(Action _action, ButtonType _button, const Point &_pos) : MouseEvent(Event::MOUSE_BUTTON, _pos), action(_action), button(_button) {} - const Action action; - const ButtonType button; - - void ToLuaTable(lua_State *l) const; -}; - -class MouseMotionEvent : public MouseEvent { -public: - MouseMotionEvent(const Point &_pos, const Point &_rel) : MouseEvent(Event::MOUSE_MOTION, _pos), rel(_rel) {} - const Point rel; - - void ToLuaTable(lua_State *l) const; -}; - -class MouseWheelEvent : public MouseEvent { -public: - enum WheelDirection { // - WHEEL_UP, - WHEEL_DOWN - }; - MouseWheelEvent(WheelDirection _direction, const Point &_pos) : MouseEvent(Event::MOUSE_WHEEL, _pos), direction(_direction) {} - WheelDirection direction; - - void ToLuaTable(lua_State *l) const; -}; - -class JoystickEvent : public Event { -public: - const SDL_JoystickID joystick; - -protected: - JoystickEvent(Event::Type _type, SDL_JoystickID _joystick): Event(_type), joystick(_joystick) {} -}; - -class JoystickAxisMotionEvent : public JoystickEvent { -public: - const float value; // -1 to 1 - const int axis; - - JoystickAxisMotionEvent(SDL_JoystickID _joystick, float _value, int _axis): - JoystickEvent(Event::JOYSTICK_AXIS_MOTION, _joystick), value(_value), axis(_axis) {} - - void ToLuaTable(lua_State *l) const; -}; - -class JoystickHatMotionEvent : public JoystickEvent { -public: - enum JoystickHatDirection { // - HAT_CENTRE = SDL_HAT_CENTERED, - HAT_UP = SDL_HAT_UP, - HAT_RIGHT = SDL_HAT_RIGHT, - HAT_DOWN = SDL_HAT_DOWN, - HAT_LEFT = SDL_HAT_LEFT, - HAT_RIGHTUP = SDL_HAT_RIGHTUP, - HAT_RIGHTDOWN = SDL_HAT_RIGHTDOWN, - HAT_LEFTUP = SDL_HAT_LEFTUP, - HAT_LEFTDOWN = SDL_HAT_LEFTDOWN + protected: + Event(Type _type) : + type(_type) {} }; - const JoystickHatDirection direction; - const int hat; + struct KeySym { + KeySym(const SDL_Keycode &_sym, const SDL_Keymod _mod, const Uint32 _unicode) : + sym(_sym), + mod(safe_mods(_mod)) {} + KeySym(const SDL_Keycode &_sym, const SDL_Keymod &_mod) : + sym(_sym), + mod(safe_mods(_mod)) {} + KeySym(const SDL_Keycode &_sym) : + sym(_sym), + mod(KMOD_NONE) {} + SDL_Keycode sym; + SDL_Keymod mod; - JoystickHatMotionEvent(SDL_JoystickID _joystick, JoystickHatDirection _direction, int _hat): - JoystickEvent(Event::JOYSTICK_HAT_MOTION, _joystick), direction(_direction), hat(_hat) {} + static KeySym FromString(const std::string &spec); - void ToLuaTable(lua_State *l) const; -}; + bool operator<(const KeySym &b) const + { + return sym < b.sym || (sym == b.sym && mod < b.mod); + } -class JoystickButtonEvent : public JoystickEvent { -public: - enum Action { // - BUTTON_DOWN, - BUTTON_UP + bool operator==(const KeySym &b) const + { + return sym == b.sym && mod == b.mod; + } + + private: + // mask off stuff like caps/numlock + static SDL_Keymod safe_mods(const SDL_Keymod m) + { + return SDL_Keymod(Uint32(m) & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI)); + } }; - const Action action; - const int button; + // data for various events + class KeyboardEvent : public Event { + public: + enum Action { // + KEY_DOWN, + KEY_UP, + }; + KeyboardEvent(Action _action, const KeySym &_keysym, bool _repeat) : + Event(Event::KEYBOARD), + action(_action), + keysym(_keysym), + repeat(_repeat) {} + const Action action; + const KeySym keysym; + const bool repeat; - JoystickButtonEvent(SDL_JoystickID _joystick, Action _action, int _button): - JoystickEvent(Event::JOYSTICK_BUTTON, _joystick), action(_action), button(_button) {} + void ToLuaTable(lua_State *l) const; + }; - void ToLuaTable(lua_State *l) const; -}; + class TextInputEvent : public Event { + public: + TextInputEvent(Uint32 _unicode) : + Event(Event::TEXT_INPUT), + unicode(_unicode) {} + const Uint32 unicode; -} + void ToLuaTable(lua_State *l) const; + }; + + class MouseEvent : public Event { + public: + const Point pos; // relative to widget + + protected: + MouseEvent(Event::Type _type, const Point &_pos) : + Event(_type), + pos(_pos) {} + }; + + class MouseButtonEvent : public MouseEvent { + public: + enum Action { // + BUTTON_DOWN, + BUTTON_UP + }; + enum ButtonType { // + BUTTON_LEFT, + BUTTON_MIDDLE, + BUTTON_RIGHT + }; + MouseButtonEvent(Action _action, ButtonType _button, const Point &_pos) : + MouseEvent(Event::MOUSE_BUTTON, _pos), + action(_action), + button(_button) {} + const Action action; + const ButtonType button; + + void ToLuaTable(lua_State *l) const; + }; + + class MouseMotionEvent : public MouseEvent { + public: + MouseMotionEvent(const Point &_pos, const Point &_rel) : + MouseEvent(Event::MOUSE_MOTION, _pos), + rel(_rel) {} + const Point rel; + + void ToLuaTable(lua_State *l) const; + }; + + class MouseWheelEvent : public MouseEvent { + public: + enum WheelDirection { // + WHEEL_UP, + WHEEL_DOWN + }; + MouseWheelEvent(WheelDirection _direction, const Point &_pos) : + MouseEvent(Event::MOUSE_WHEEL, _pos), + direction(_direction) {} + WheelDirection direction; + + void ToLuaTable(lua_State *l) const; + }; + + class JoystickEvent : public Event { + public: + const SDL_JoystickID joystick; + + protected: + JoystickEvent(Event::Type _type, SDL_JoystickID _joystick) : + Event(_type), + joystick(_joystick) {} + }; + + class JoystickAxisMotionEvent : public JoystickEvent { + public: + const float value; // -1 to 1 + const int axis; + + JoystickAxisMotionEvent(SDL_JoystickID _joystick, float _value, int _axis) : + JoystickEvent(Event::JOYSTICK_AXIS_MOTION, _joystick), + value(_value), + axis(_axis) {} + + void ToLuaTable(lua_State *l) const; + }; + + class JoystickHatMotionEvent : public JoystickEvent { + public: + enum JoystickHatDirection { // + HAT_CENTRE = SDL_HAT_CENTERED, + HAT_UP = SDL_HAT_UP, + HAT_RIGHT = SDL_HAT_RIGHT, + HAT_DOWN = SDL_HAT_DOWN, + HAT_LEFT = SDL_HAT_LEFT, + HAT_RIGHTUP = SDL_HAT_RIGHTUP, + HAT_RIGHTDOWN = SDL_HAT_RIGHTDOWN, + HAT_LEFTUP = SDL_HAT_LEFTUP, + HAT_LEFTDOWN = SDL_HAT_LEFTDOWN + }; + + const JoystickHatDirection direction; + const int hat; + + JoystickHatMotionEvent(SDL_JoystickID _joystick, JoystickHatDirection _direction, int _hat) : + JoystickEvent(Event::JOYSTICK_HAT_MOTION, _joystick), + direction(_direction), + hat(_hat) {} + + void ToLuaTable(lua_State *l) const; + }; + + class JoystickButtonEvent : public JoystickEvent { + public: + enum Action { // + BUTTON_DOWN, + BUTTON_UP + }; + + const Action action; + const int button; + + JoystickButtonEvent(SDL_JoystickID _joystick, Action _action, int _button) : + JoystickEvent(Event::JOYSTICK_BUTTON, _joystick), + action(_action), + button(_button) {} + + void ToLuaTable(lua_State *l) const; + }; + +} // namespace UI #endif diff --git a/src/ui/EventDispatcher.cpp b/src/ui/EventDispatcher.cpp index a937bc370..90314d881 100644 --- a/src/ui/EventDispatcher.cpp +++ b/src/ui/EventDispatcher.cpp @@ -2,23 +2,23 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "EventDispatcher.h" -#include "Widget.h" #include "Container.h" +#include "Widget.h" #include "text/TextSupport.h" #include namespace UI { -static inline MouseButtonEvent::ButtonType MouseButtonFromSDLButton(Uint8 sdlButton) { - return - sdlButton == SDL_BUTTON_LEFT ? MouseButtonEvent::BUTTON_LEFT : - sdlButton == SDL_BUTTON_MIDDLE ? MouseButtonEvent::BUTTON_MIDDLE : - MouseButtonEvent::BUTTON_RIGHT; -} + static inline MouseButtonEvent::ButtonType MouseButtonFromSDLButton(Uint8 sdlButton) + { + return sdlButton == SDL_BUTTON_LEFT ? MouseButtonEvent::BUTTON_LEFT : + sdlButton == SDL_BUTTON_MIDDLE ? MouseButtonEvent::BUTTON_MIDDLE : + MouseButtonEvent::BUTTON_RIGHT; + } -bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event) -{ - switch (event.type) { + bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event) + { + switch (event.type) { case SDL_KEYDOWN: return Dispatch(KeyboardEvent(KeyboardEvent::KEY_DOWN, KeySym(event.key.keysym.sym, SDL_Keymod(event.key.keysym.mod)), event.key.repeat)); @@ -34,13 +34,13 @@ bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event) return Dispatch(MouseWheelEvent(event.wheel.y > 0 ? MouseWheelEvent::WHEEL_UP : MouseWheelEvent::WHEEL_DOWN, m_lastMousePosition)); case SDL_MOUSEBUTTONDOWN: - return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_DOWN, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y))); + return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_DOWN, MouseButtonFromSDLButton(event.button.button), Point(event.button.x, event.button.y))); case SDL_MOUSEBUTTONUP: - return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_UP, MouseButtonFromSDLButton(event.button.button), Point(event.button.x,event.button.y))); + return Dispatch(MouseButtonEvent(MouseButtonEvent::BUTTON_UP, MouseButtonFromSDLButton(event.button.button), Point(event.button.x, event.button.y))); case SDL_MOUSEMOTION: - return Dispatch(MouseMotionEvent(Point(event.motion.x,event.motion.y), Point(event.motion.xrel, event.motion.yrel))); + return Dispatch(MouseMotionEvent(Point(event.motion.x, event.motion.y), Point(event.motion.xrel, event.motion.yrel))); case SDL_JOYAXISMOTION: // SDL joystick axis value is documented to have the range -32768 to 32767 @@ -57,64 +57,63 @@ bool EventDispatcher::DispatchSDLEvent(const SDL_Event &event) case SDL_JOYBUTTONUP: return Dispatch(JoystickButtonEvent(event.jbutton.which, JoystickButtonEvent::BUTTON_UP, event.jbutton.button)); + } + + return false; } - return false; -} - -bool EventDispatcher::Dispatch(const Event &event) -{ - switch (event.type) { + bool EventDispatcher::Dispatch(const Event &event) + { + switch (event.type) { case Event::KEYBOARD: { - const KeyboardEvent keyEvent = static_cast(event); + const KeyboardEvent keyEvent = static_cast(event); switch (keyEvent.action) { - case KeyboardEvent::KEY_DOWN: + case KeyboardEvent::KEY_DOWN: - // all key events to the selected widget first - if (m_selected && m_selected->IsOnTopLayer()) - return m_selected->TriggerKeyDown(keyEvent); + // all key events to the selected widget first + if (m_selected && m_selected->IsOnTopLayer()) + return m_selected->TriggerKeyDown(keyEvent); - return m_baseContainer->TriggerKeyDown(keyEvent); + return m_baseContainer->TriggerKeyDown(keyEvent); - case KeyboardEvent::KEY_UP: { + case KeyboardEvent::KEY_UP: { - // all key events to the selected widget first - if (m_selected && m_selected->IsOnTopLayer()) - return m_selected->TriggerKeyUp(keyEvent); + // all key events to the selected widget first + if (m_selected && m_selected->IsOnTopLayer()) + return m_selected->TriggerKeyUp(keyEvent); - // any modifier coming in will be a specific key, eg left - // shift or right shift. shortcuts can't distinguish - // betwen the two, and so have both set in m_shortcuts. we - // can't just compare though, because the mods won't - // match. so we make a new keysym with a new mod that - // includes both of the type of key - Uint32 mod = Uint32(keyEvent.keysym.mod); - if (mod & KMOD_SHIFT) mod |= KMOD_SHIFT; - if (mod & KMOD_CTRL) mod |= KMOD_CTRL; - if (mod & KMOD_ALT) mod |= KMOD_ALT; - if (mod & KMOD_GUI) mod |= KMOD_GUI; - const KeySym shortcutSym(keyEvent.keysym.sym, SDL_Keymod(mod)); + // any modifier coming in will be a specific key, eg left + // shift or right shift. shortcuts can't distinguish + // betwen the two, and so have both set in m_shortcuts. we + // can't just compare though, because the mods won't + // match. so we make a new keysym with a new mod that + // includes both of the type of key + Uint32 mod = Uint32(keyEvent.keysym.mod); + if (mod & KMOD_SHIFT) mod |= KMOD_SHIFT; + if (mod & KMOD_CTRL) mod |= KMOD_CTRL; + if (mod & KMOD_ALT) mod |= KMOD_ALT; + if (mod & KMOD_GUI) mod |= KMOD_GUI; + const KeySym shortcutSym(keyEvent.keysym.sym, SDL_Keymod(mod)); - std::map::iterator i = m_shortcuts.find(shortcutSym); - if (i != m_shortcuts.end()) { - // DispatchSelect must happen before TriggerClick, so - // that Click handlers can override the selection - DispatchSelect((*i).second); - (*i).second->TriggerClick(); - return true; - } - - return m_baseContainer->TriggerKeyUp(keyEvent); + std::map::iterator i = m_shortcuts.find(shortcutSym); + if (i != m_shortcuts.end()) { + // DispatchSelect must happen before TriggerClick, so + // that Click handlers can override the selection + DispatchSelect((*i).second); + (*i).second->TriggerClick(); + return true; } + return m_baseContainer->TriggerKeyUp(keyEvent); + } } return false; } case Event::TEXT_INPUT: { - const TextInputEvent textInputEvent = static_cast(event); + const TextInputEvent textInputEvent = static_cast(event); // selected widgets get all the text input events if (m_selected && m_selected->IsOnTopLayer()) @@ -124,75 +123,75 @@ bool EventDispatcher::Dispatch(const Event &event) } case Event::MOUSE_BUTTON: { - const MouseButtonEvent mouseButtonEvent = static_cast(event); + const MouseButtonEvent mouseButtonEvent = static_cast(event); m_lastMousePosition = mouseButtonEvent.pos; RefCountedPtr target(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - if(!target) + if (!target) return false; switch (mouseButtonEvent.action) { - case MouseButtonEvent::BUTTON_DOWN: { + case MouseButtonEvent::BUTTON_DOWN: { - if (!target->IsOnTopLayer()) - return false; - - if (target->IsDisabled()) - return false; - - // activate widget and remember it - if (!m_mouseActiveReceiver) { - m_mouseActiveReceiver = target; - m_mouseActiveTrigger = mouseButtonEvent.button; - target->TriggerMouseActivate(); - } - - MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition()); - return target->TriggerMouseDown(translatedEvent); - } - - case MouseButtonEvent::BUTTON_UP: { - - // if there's an active widget, deactivate it - if (m_mouseActiveReceiver && m_mouseActiveTrigger == mouseButtonEvent.button) { - m_mouseActiveReceiver->TriggerMouseDeactivate(); - - // if we released over the active widget, then we clicked it - if (m_mouseActiveReceiver.Get() == target) { - // DispatchSelect must happen before TriggerClick, so - // that Click handlers can override the selection - DispatchSelect(m_mouseActiveReceiver.Get()); - m_mouseActiveReceiver->TriggerClick(); - } - - m_mouseActiveReceiver.Reset(); - - // send the straight up event too - bool ret = false; - if (!target->IsDisabled()) { - MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition()); - ret = target->TriggerMouseUp(translatedEvent); - } - - DispatchMouseOverOut(target.Get(), m_lastMousePosition); - - return ret; - } - - if (!target->IsOnTopLayer()) - return false; - - MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition-target->GetAbsolutePosition()); - return target->TriggerMouseUp(translatedEvent); - } - - default: + if (!target->IsOnTopLayer()) return false; + + if (target->IsDisabled()) + return false; + + // activate widget and remember it + if (!m_mouseActiveReceiver) { + m_mouseActiveReceiver = target; + m_mouseActiveTrigger = mouseButtonEvent.button; + target->TriggerMouseActivate(); + } + + MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition - target->GetAbsolutePosition()); + return target->TriggerMouseDown(translatedEvent); + } + + case MouseButtonEvent::BUTTON_UP: { + + // if there's an active widget, deactivate it + if (m_mouseActiveReceiver && m_mouseActiveTrigger == mouseButtonEvent.button) { + m_mouseActiveReceiver->TriggerMouseDeactivate(); + + // if we released over the active widget, then we clicked it + if (m_mouseActiveReceiver.Get() == target) { + // DispatchSelect must happen before TriggerClick, so + // that Click handlers can override the selection + DispatchSelect(m_mouseActiveReceiver.Get()); + m_mouseActiveReceiver->TriggerClick(); + } + + m_mouseActiveReceiver.Reset(); + + // send the straight up event too + bool ret = false; + if (!target->IsDisabled()) { + MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition - target->GetAbsolutePosition()); + ret = target->TriggerMouseUp(translatedEvent); + } + + DispatchMouseOverOut(target.Get(), m_lastMousePosition); + + return ret; + } + + if (!target->IsOnTopLayer()) + return false; + + MouseButtonEvent translatedEvent = MouseButtonEvent(mouseButtonEvent.action, mouseButtonEvent.button, m_lastMousePosition - target->GetAbsolutePosition()); + return target->TriggerMouseUp(translatedEvent); + } + + default: + return false; } } case Event::MOUSE_MOTION: { - const MouseMotionEvent mouseMotionEvent = static_cast(event); + const MouseMotionEvent mouseMotionEvent = static_cast(event); m_lastMousePosition = mouseMotionEvent.pos; // if there's a mouse-active widget, just send motion events directly into it @@ -200,18 +199,18 @@ bool EventDispatcher::Dispatch(const Event &event) if (!m_mouseActiveReceiver->IsOnTopLayer()) return false; - MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition-m_mouseActiveReceiver->GetAbsolutePosition(), mouseMotionEvent.rel); + MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition - m_mouseActiveReceiver->GetAbsolutePosition(), mouseMotionEvent.rel); return m_mouseActiveReceiver->TriggerMouseMove(translatedEvent); } // widget directly under the mouse RefCountedPtr target(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - if(!target) + if (!target) return false; bool ret = false; if (!target->IsDisabled() && target->IsOnTopLayer()) { - MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition-target->GetAbsolutePosition(), mouseMotionEvent.rel); + MouseMotionEvent translatedEvent = MouseMotionEvent(m_lastMousePosition - target->GetAbsolutePosition(), mouseMotionEvent.rel); ret = target->TriggerMouseMove(translatedEvent); } @@ -221,11 +220,11 @@ bool EventDispatcher::Dispatch(const Event &event) } case Event::MOUSE_WHEEL: { - const MouseWheelEvent mouseWheelEvent = static_cast(event); + const MouseWheelEvent mouseWheelEvent = static_cast(event); m_lastMousePosition = mouseWheelEvent.pos; RefCountedPtr target(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - if(!target) + if (!target) return false; if (!target->IsOnTopLayer()) return false; @@ -234,128 +233,128 @@ bool EventDispatcher::Dispatch(const Event &event) } case Event::JOYSTICK_AXIS_MOTION: - return m_baseContainer->TriggerJoystickAxisMove(static_cast(event)); + return m_baseContainer->TriggerJoystickAxisMove(static_cast(event)); case Event::JOYSTICK_HAT_MOTION: - return m_baseContainer->TriggerJoystickHatMove(static_cast(event)); + return m_baseContainer->TriggerJoystickHatMove(static_cast(event)); case Event::JOYSTICK_BUTTON: { - const JoystickButtonEvent &joyButtonEvent = static_cast(event); + const JoystickButtonEvent &joyButtonEvent = static_cast(event); switch (joyButtonEvent.action) { - case JoystickButtonEvent::BUTTON_DOWN: - return m_baseContainer->TriggerJoystickButtonDown(joyButtonEvent); - case JoystickButtonEvent::BUTTON_UP: - return m_baseContainer->TriggerJoystickButtonUp(joyButtonEvent); - default: assert(0); return false; + case JoystickButtonEvent::BUTTON_DOWN: + return m_baseContainer->TriggerJoystickButtonDown(joyButtonEvent); + case JoystickButtonEvent::BUTTON_UP: + return m_baseContainer->TriggerJoystickButtonUp(joyButtonEvent); + default: assert(0); return false; } } default: return false; - } - - return false; -} - -void EventDispatcher::DispatchMouseOverOut(Widget *target, const Point &mousePos) -{ - bool onTopLayer = target->IsOnTopLayer(); - - // do over/out handling for wherever the mouse is right now - if (target != m_lastMouseOverTarget.Get() || target->IsDisabled() || !onTopLayer) { - - if (m_lastMouseOverTarget) { - - // tell the old one that the mouse isn't over it anymore - m_lastMouseOverTarget->TriggerMouseOut(mousePos-m_lastMouseOverTarget->GetAbsolutePosition()); } - if (target->IsDisabled() || !onTopLayer) - m_lastMouseOverTarget.Reset(0); - else { - m_lastMouseOverTarget.Reset(target); - m_lastMouseOverTarget->TriggerMouseOver(mousePos-m_lastMouseOverTarget->GetAbsolutePosition()); + return false; + } + + void EventDispatcher::DispatchMouseOverOut(Widget *target, const Point &mousePos) + { + bool onTopLayer = target->IsOnTopLayer(); + + // do over/out handling for wherever the mouse is right now + if (target != m_lastMouseOverTarget.Get() || target->IsDisabled() || !onTopLayer) { + + if (m_lastMouseOverTarget) { + + // tell the old one that the mouse isn't over it anymore + m_lastMouseOverTarget->TriggerMouseOut(mousePos - m_lastMouseOverTarget->GetAbsolutePosition()); + } + + if (target->IsDisabled() || !onTopLayer) + m_lastMouseOverTarget.Reset(0); + else { + m_lastMouseOverTarget.Reset(target); + m_lastMouseOverTarget->TriggerMouseOver(mousePos - m_lastMouseOverTarget->GetAbsolutePosition()); + } } } -} -void EventDispatcher::DispatchSelect(Widget *target) -{ - if (m_selected) { - if (m_selected == target) - return; + void EventDispatcher::DispatchSelect(Widget *target) + { + if (m_selected) { + if (m_selected == target) + return; - m_selected->TriggerDeselect(); - } - - while (target) { - if (target->IsSelectable()) { - m_selected.Reset(target); - m_selected->TriggerSelect(); - return; + m_selected->TriggerDeselect(); } - target = target->GetContainer(); - } + while (target) { + if (target->IsSelectable()) { + m_selected.Reset(target); + m_selected->TriggerSelect(); + return; + } - m_selected.Reset(); -} + target = target->GetContainer(); + } -void EventDispatcher::SelectWidget(Widget *target) -{ - DispatchSelect(target); -} - -void EventDispatcher::DeselectWidget(Widget *target) -{ - if (!target->IsSelected()) - return; - DispatchSelect(0); -} - -void EventDispatcher::ResetMouseActiveReceiver() -{ - if (m_mouseActiveReceiver) { - m_mouseActiveReceiver->TriggerMouseDeactivate(); - m_mouseActiveReceiver.Reset(); - } -} - -void EventDispatcher::DisableWidget(Widget *target) -{ - DeselectWidget(target); - - if (m_mouseActiveReceiver && m_mouseActiveReceiver.Get() == target) { - ResetMouseActiveReceiver(); - } - - // if the mouse is over the target, then the mouse is also over all of the - // children. find the top one and deliver a MouseOut event to them all - if (target->IsMouseOver()) { - RefCountedPtr top(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - top->TriggerMouseOut(top->GetAbsolutePosition(), true, target); // stop at target - m_lastMouseOverTarget.Reset(0); - } -} - -void EventDispatcher::EnableWidget(Widget *target) -{ - RefCountedPtr top(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - DispatchMouseOverOut(top.Get(), m_lastMousePosition); -} - -void EventDispatcher::LayoutUpdated() -{ - if (m_selected && !m_selected->IsVisible()) m_selected.Reset(); + } - m_shortcuts.clear(); - m_baseContainer->CollectShortcuts(m_shortcuts); + void EventDispatcher::SelectWidget(Widget *target) + { + DispatchSelect(target); + } - RefCountedPtr target(m_baseContainer->GetWidgetAt(m_lastMousePosition)); - if(!target) - return; - DispatchMouseOverOut(target.Get(), m_lastMousePosition); -} + void EventDispatcher::DeselectWidget(Widget *target) + { + if (!target->IsSelected()) + return; + DispatchSelect(0); + } -} + void EventDispatcher::ResetMouseActiveReceiver() + { + if (m_mouseActiveReceiver) { + m_mouseActiveReceiver->TriggerMouseDeactivate(); + m_mouseActiveReceiver.Reset(); + } + } + + void EventDispatcher::DisableWidget(Widget *target) + { + DeselectWidget(target); + + if (m_mouseActiveReceiver && m_mouseActiveReceiver.Get() == target) { + ResetMouseActiveReceiver(); + } + + // if the mouse is over the target, then the mouse is also over all of the + // children. find the top one and deliver a MouseOut event to them all + if (target->IsMouseOver()) { + RefCountedPtr top(m_baseContainer->GetWidgetAt(m_lastMousePosition)); + top->TriggerMouseOut(top->GetAbsolutePosition(), true, target); // stop at target + m_lastMouseOverTarget.Reset(0); + } + } + + void EventDispatcher::EnableWidget(Widget *target) + { + RefCountedPtr top(m_baseContainer->GetWidgetAt(m_lastMousePosition)); + DispatchMouseOverOut(top.Get(), m_lastMousePosition); + } + + void EventDispatcher::LayoutUpdated() + { + if (m_selected && !m_selected->IsVisible()) + m_selected.Reset(); + + m_shortcuts.clear(); + m_baseContainer->CollectShortcuts(m_shortcuts); + + RefCountedPtr target(m_baseContainer->GetWidgetAt(m_lastMousePosition)); + if (!target) + return; + DispatchMouseOverOut(target.Get(), m_lastMousePosition); + } + +} // namespace UI diff --git a/src/ui/EventDispatcher.h b/src/ui/EventDispatcher.h index d5cbda545..dc7437bd8 100644 --- a/src/ui/EventDispatcher.h +++ b/src/ui/EventDispatcher.h @@ -9,51 +9,52 @@ namespace UI { -class Widget; -class Container; + class Widget; + class Container; -class EventDispatcher { -public: - EventDispatcher(Container *baseContainer) : - m_baseContainer(baseContainer), - m_mouseActiveReceiver(0), - m_lastMouseOverTarget(0) + class EventDispatcher { + public: + EventDispatcher(Container *baseContainer) : + m_baseContainer(baseContainer), + m_mouseActiveReceiver(0), + m_lastMouseOverTarget(0) {} - bool Dispatch(const Event &event); - bool DispatchSDLEvent(const SDL_Event &event); + bool Dispatch(const Event &event); + bool DispatchSDLEvent(const SDL_Event &event); - void LayoutUpdated(); + void LayoutUpdated(); - Widget *GetSelected() const { return m_selected.Get(); } - Widget *GetMouseActive() const { return m_mouseActiveReceiver.Get(); } + Widget *GetSelected() const { return m_selected.Get(); } + Widget *GetMouseActive() const { return m_mouseActiveReceiver.Get(); } - void SelectWidget(Widget *target); - void DeselectWidget(Widget *target); + void SelectWidget(Widget *target); + void DeselectWidget(Widget *target); - void DisableWidget(Widget *target); - void EnableWidget(Widget *target); + void DisableWidget(Widget *target); + void EnableWidget(Widget *target); - Point GetMousePos() const { return m_lastMousePosition; } + Point GetMousePos() const { return m_lastMousePosition; } - void ResetMouseActiveReceiver(); -private: - void DispatchMouseOverOut(Widget *target, const Point &mousePos); - void DispatchSelect(Widget *target); + void ResetMouseActiveReceiver(); - Container *m_baseContainer; + private: + void DispatchMouseOverOut(Widget *target, const Point &mousePos); + void DispatchSelect(Widget *target); - RefCountedPtr m_mouseActiveReceiver; - MouseButtonEvent::ButtonType m_mouseActiveTrigger; + Container *m_baseContainer; - RefCountedPtr m_lastMouseOverTarget; - Point m_lastMousePosition; + RefCountedPtr m_mouseActiveReceiver; + MouseButtonEvent::ButtonType m_mouseActiveTrigger; - RefCountedPtr m_selected; + RefCountedPtr m_lastMouseOverTarget; + Point m_lastMousePosition; - std::map m_shortcuts; -}; + RefCountedPtr m_selected; -} + std::map m_shortcuts; + }; + +} // namespace UI #endif diff --git a/src/ui/Expand.cpp b/src/ui/Expand.cpp index 42b834624..400e89138 100644 --- a/src/ui/Expand.cpp +++ b/src/ui/Expand.cpp @@ -5,11 +5,11 @@ namespace UI { -Point Expand::PreferredSize() -{ - const Point innerPreferredSize(GetInnerWidget() ? GetInnerWidget()->CalcLayoutContribution() : Point()); + Point Expand::PreferredSize() + { + const Point innerPreferredSize(GetInnerWidget() ? GetInnerWidget()->CalcLayoutContribution() : Point()); - switch (m_direction) { + switch (m_direction) { case BOTH: SetSizeControlFlags(EXPAND_WIDTH | EXPAND_HEIGHT); break; @@ -19,9 +19,9 @@ Point Expand::PreferredSize() case VERTICAL: SetSizeControlFlags(EXPAND_HEIGHT); break; + } + + return innerPreferredSize; } - return innerPreferredSize; -} - -} +} // namespace UI diff --git a/src/ui/Expand.h b/src/ui/Expand.h index 6b19a659c..f14e7b1c9 100644 --- a/src/ui/Expand.h +++ b/src/ui/Expand.h @@ -8,23 +8,25 @@ namespace UI { -class Expand : public Single { -public: - enum Direction { // - BOTH, - HORIZONTAL, - VERTICAL, + class Expand : public Single { + public: + enum Direction { // + BOTH, + HORIZONTAL, + VERTICAL, + }; + + virtual Point PreferredSize(); + + protected: + friend class Context; + Expand(Context *context, Direction direction) : + Single(context), + m_direction(direction) {} + + Direction m_direction; }; - virtual Point PreferredSize(); - -protected: - friend class Context; - Expand(Context *context, Direction direction) : Single(context), m_direction(direction) {} - - Direction m_direction; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Gauge.cpp b/src/ui/Gauge.cpp index 906f69529..cc84ab983 100644 --- a/src/ui/Gauge.cpp +++ b/src/ui/Gauge.cpp @@ -7,93 +7,94 @@ namespace UI { -Gauge::Gauge(Context *context) : Widget(context), - m_value(0.0f), - m_warningLevel(1.0f), - m_criticalLevel(1.0f), - m_levelAscending(true), - m_mult(1.0f), - m_style(NORMAL) -{ - RegisterBindPoint("value", sigc::mem_fun(this, &Gauge::BindValue)); - RegisterBindPoint("valuePercent", sigc::mem_fun(this, &Gauge::BindValuePercent)); -} + Gauge::Gauge(Context *context) : + Widget(context), + m_value(0.0f), + m_warningLevel(1.0f), + m_criticalLevel(1.0f), + m_levelAscending(true), + m_mult(1.0f), + m_style(NORMAL) + { + RegisterBindPoint("value", sigc::mem_fun(this, &Gauge::BindValue)); + RegisterBindPoint("valuePercent", sigc::mem_fun(this, &Gauge::BindValuePercent)); + } -Point Gauge::PreferredSize() -{ - SetSizeControlFlags(EXPAND_WIDTH); - return GetContext()->GetSkin().GaugeBackground().size; -} + Point Gauge::PreferredSize() + { + SetSizeControlFlags(EXPAND_WIDTH); + return GetContext()->GetSkin().GaugeBackground().size; + } -void Gauge::Layout() -{ - SetActiveArea(Point(GetSize().x, GetContext()->GetSkin().GaugeBackground().size.y)); -} + void Gauge::Layout() + { + SetActiveArea(Point(GetSize().x, GetContext()->GetSkin().GaugeBackground().size.y)); + } -Gauge *Gauge::SetUpperValue(float v) -{ - m_mult = 1/v; - UpdateStyle(); - return this; -} + Gauge *Gauge::SetUpperValue(float v) + { + m_mult = 1 / v; + UpdateStyle(); + return this; + } -Gauge *Gauge::SetWarningLevel(float v) -{ - m_warningLevel = Clamp(v*m_mult, 0.0f, 1.0f); - UpdateStyle(); - return this; -} + Gauge *Gauge::SetWarningLevel(float v) + { + m_warningLevel = Clamp(v * m_mult, 0.0f, 1.0f); + UpdateStyle(); + return this; + } -Gauge *Gauge::SetCriticalLevel(float v) -{ - m_criticalLevel = Clamp(v*m_mult, 0.0f, 1.0f); - UpdateStyle(); - return this; -} + Gauge *Gauge::SetCriticalLevel(float v) + { + m_criticalLevel = Clamp(v * m_mult, 0.0f, 1.0f); + UpdateStyle(); + return this; + } -Gauge *Gauge::SetLevelAscending(bool ascending) -{ - m_levelAscending = ascending; - UpdateStyle(); - return this; -} + Gauge *Gauge::SetLevelAscending(bool ascending) + { + m_levelAscending = ascending; + UpdateStyle(); + return this; + } -void Gauge::SetValue(float v) -{ - m_value = Clamp(v*m_mult, 0.0f, 1.0f); - UpdateStyle(); -} + void Gauge::SetValue(float v) + { + m_value = Clamp(v * m_mult, 0.0f, 1.0f); + UpdateStyle(); + } -void Gauge::UpdateStyle() -{ - if (m_levelAscending) - m_style = - m_value > m_criticalLevel && m_criticalLevel <= 1.0f ? CRITICAL : - m_value > m_warningLevel && m_warningLevel <= 1.0f ? WARNING : - NORMAL; - else - m_style = - m_value < m_criticalLevel && m_criticalLevel <= 1.0f ? CRITICAL : - m_value < m_warningLevel && m_warningLevel <= 1.0f ? WARNING : - NORMAL; -} + void Gauge::UpdateStyle() + { + if (m_levelAscending) + m_style = + m_value > m_criticalLevel && m_criticalLevel <= 1.0f ? CRITICAL : + m_value > m_warningLevel && m_warningLevel <= 1.0f ? WARNING : + NORMAL; + else + m_style = + m_value < m_criticalLevel && m_criticalLevel <= 1.0f ? CRITICAL : + m_value < m_warningLevel && m_warningLevel <= 1.0f ? WARNING : + NORMAL; + } -void Gauge::Draw() -{ - const Point activeOffset(GetActiveOffset()); - const Point activeArea(GetActiveArea()); + void Gauge::Draw() + { + const Point activeOffset(GetActiveOffset()); + const Point activeArea(GetActiveArea()); - Context *c = GetContext(); - const Skin &s = c->GetSkin(); + Context *c = GetContext(); + const Skin &s = c->GetSkin(); - s.DrawGaugeBackground(activeOffset, activeArea); + s.DrawGaugeBackground(activeOffset, activeArea); - if (m_value > 0.0f) { - s.DrawGaugeMask(activeOffset, activeArea); + if (m_value > 0.0f) { + s.DrawGaugeMask(activeOffset, activeArea); - const Point size(activeArea.x * m_value, activeArea.y); + const Point size(activeArea.x * m_value, activeArea.y); - switch (m_style) { + switch (m_style) { case NORMAL: s.DrawGaugeFillNormal(activeOffset, size); break; @@ -103,22 +104,22 @@ void Gauge::Draw() case CRITICAL: s.DrawGaugeFillCritical(activeOffset, size); break; + } } } -} -void Gauge::BindValue(PropertyMap &p, const std::string &k) -{ - double v = 0.0; - p.Get(k, v); - SetValue(v); -} + void Gauge::BindValue(PropertyMap &p, const std::string &k) + { + double v = 0.0; + p.Get(k, v); + SetValue(v); + } -void Gauge::BindValuePercent(PropertyMap &p, const std::string &k) -{ - double v = 0.0; - p.Get(k, v); - SetValue(Clamp(v, 0.0, 100.0)*0.01); -} + void Gauge::BindValuePercent(PropertyMap &p, const std::string &k) + { + double v = 0.0; + p.Get(k, v); + SetValue(Clamp(v, 0.0, 100.0) * 0.01); + } -} +} // namespace UI diff --git a/src/ui/Gauge.h b/src/ui/Gauge.h index 3bf03c436..467ac686d 100644 --- a/src/ui/Gauge.h +++ b/src/ui/Gauge.h @@ -8,46 +8,46 @@ namespace UI { -class Gauge: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class Gauge : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - float GetValue() const { return m_value/m_mult; } - void SetValue(float v); + float GetValue() const { return m_value / m_mult; } + void SetValue(float v); - Gauge *SetUpperValue(float v); + Gauge *SetUpperValue(float v); - Gauge *SetWarningLevel(float v); - Gauge *SetCriticalLevel(float v); - Gauge *SetLevelAscending(bool ascending); + Gauge *SetWarningLevel(float v); + Gauge *SetCriticalLevel(float v); + Gauge *SetLevelAscending(bool ascending); -protected: - friend class Context; - Gauge(Context *context); + protected: + friend class Context; + Gauge(Context *context); -private: - void UpdateStyle(); + private: + void UpdateStyle(); - void BindValue(PropertyMap &p, const std::string &k); - void BindValuePercent(PropertyMap &p, const std::string &k); + void BindValue(PropertyMap &p, const std::string &k); + void BindValuePercent(PropertyMap &p, const std::string &k); - float m_value; + float m_value; - float m_warningLevel; - float m_criticalLevel; - bool m_levelAscending; + float m_warningLevel; + float m_criticalLevel; + bool m_levelAscending; - float m_mult; + float m_mult; - enum { - NORMAL, - WARNING, - CRITICAL - } m_style; -}; + enum { + NORMAL, + WARNING, + CRITICAL + } m_style; + }; -} +} // namespace UI #endif diff --git a/src/ui/Gradient.cpp b/src/ui/Gradient.cpp index 9dd3f66e0..8b374716d 100644 --- a/src/ui/Gradient.cpp +++ b/src/ui/Gradient.cpp @@ -3,44 +3,47 @@ #include "Gradient.h" #include "Context.h" +#include "graphics/Material.h" #include "graphics/Renderer.h" #include "graphics/VertexArray.h" -#include "graphics/Material.h" namespace UI { -Gradient::Gradient(Context *context, const Color &beginColor, const Color &endColor, Direction direction) : - Single(context), m_beginColor(beginColor), m_endColor(endColor), m_direction(direction) -{ - Graphics::MaterialDescriptor desc; - desc.vertexColors = true; - m_material.Reset(GetContext()->GetRenderer()->CreateMaterial(desc)); -} - -void Gradient::Draw() -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - if (!m_quad) { - const Point &offset = GetActiveOffset(); - const Point &area = GetActiveArea(); - - const float x = offset.x; - const float y = offset.y; - const float sx = area.x; - const float sy = area.y; - - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE); - va.Add(vector3f(x, y, 0.0f), m_beginColor); - va.Add(vector3f(x, y + sy, 0.0f), m_direction == HORIZONTAL ? m_beginColor : m_endColor); - va.Add(vector3f(x + sx, y, 0.0f), m_direction == HORIZONTAL ? m_endColor : m_beginColor); - va.Add(vector3f(x + sx, y + sy, 0.0f), m_endColor); - - auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); - m_quad.reset(new Graphics::Drawables::TexturedQuad(r, m_material, va, renderState)); + Gradient::Gradient(Context *context, const Color &beginColor, const Color &endColor, Direction direction) : + Single(context), + m_beginColor(beginColor), + m_endColor(endColor), + m_direction(direction) + { + Graphics::MaterialDescriptor desc; + desc.vertexColors = true; + m_material.Reset(GetContext()->GetRenderer()->CreateMaterial(desc)); } - m_quad->Draw(r, Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, GetContext()->GetOpacity()*Color::WHITE.a)); - Container::Draw(); -} + void Gradient::Draw() + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + if (!m_quad) { + const Point &offset = GetActiveOffset(); + const Point &area = GetActiveArea(); -} + const float x = offset.x; + const float y = offset.y; + const float sx = area.x; + const float sy = area.y; + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE); + va.Add(vector3f(x, y, 0.0f), m_beginColor); + va.Add(vector3f(x, y + sy, 0.0f), m_direction == HORIZONTAL ? m_beginColor : m_endColor); + va.Add(vector3f(x + sx, y, 0.0f), m_direction == HORIZONTAL ? m_endColor : m_beginColor); + va.Add(vector3f(x + sx, y + sy, 0.0f), m_endColor); + + auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); + m_quad.reset(new Graphics::Drawables::TexturedQuad(r, m_material, va, renderState)); + } + m_quad->Draw(r, Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, GetContext()->GetOpacity() * Color::WHITE.a)); + + Container::Draw(); + } + +} // namespace UI diff --git a/src/ui/Gradient.h b/src/ui/Gradient.h index 6f592ba1a..c02eb6601 100644 --- a/src/ui/Gradient.h +++ b/src/ui/Gradient.h @@ -4,36 +4,35 @@ #ifndef UI_GRADIENT_H #define UI_GRADIENT_H -#include "Single.h" #include "Color.h" +#include "Single.h" #include "graphics/Drawables.h" #include "graphics/Material.h" namespace UI { -class Gradient : public Single { -public: + class Gradient : public Single { + public: + enum Direction { // + HORIZONTAL, + VERTICAL + }; - enum Direction { // - HORIZONTAL, - VERTICAL + virtual void Draw(); + + protected: + friend class Context; + Gradient(Context *context, const Color &beginColor, const Color &endColor, Direction direction); + + private: + Color m_beginColor; + Color m_endColor; + Direction m_direction; + + RefCountedPtr m_material; + std::unique_ptr m_quad; }; - virtual void Draw(); - -protected: - friend class Context; - Gradient(Context *context, const Color &beginColor, const Color &endColor, Direction direction); - -private: - Color m_beginColor; - Color m_endColor; - Direction m_direction; - - RefCountedPtr m_material; - std::unique_ptr m_quad; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Grid.cpp b/src/ui/Grid.cpp index 7e16f9453..9a3bc6e58 100644 --- a/src/ui/Grid.cpp +++ b/src/ui/Grid.cpp @@ -5,167 +5,168 @@ namespace UI { -Grid::Grid(Context *context, const CellSpec &rowSpec, const CellSpec &colSpec) : Container(context), - m_rowSpec(rowSpec), - m_colSpec(colSpec), - m_numRows(colSpec.numCells), - m_numCols(rowSpec.numCells), - m_widgets(m_rowSpec.numCells*m_colSpec.numCells) -{ - Clear(); -} - -Point Grid::PreferredSize() -{ - Point preferredSize; - - for (unsigned int rowNum = 0; rowNum < m_numRows; rowNum++) { - Point rowSize; - - for (unsigned int colNum = 0; colNum < m_numCols; colNum++) { - const unsigned int n = rowNum*m_numCols+colNum; - Widget *w = m_widgets[n]; - - Point childPreferredSize; - if (w) - childPreferredSize = w->CalcLayoutContribution(); - else - childPreferredSize = Point(SIZE_EXPAND); - - rowSize.x = SizeAdd(childPreferredSize.x, rowSize.x); - rowSize.y = std::max(childPreferredSize.y, rowSize.y); - } - - preferredSize.x = std::max(preferredSize.x, rowSize.x); - preferredSize.y = SizeAdd(preferredSize.y, rowSize.y); + Grid::Grid(Context *context, const CellSpec &rowSpec, const CellSpec &colSpec) : + Container(context), + m_rowSpec(rowSpec), + m_colSpec(colSpec), + m_numRows(colSpec.numCells), + m_numCols(rowSpec.numCells), + m_widgets(m_rowSpec.numCells * m_colSpec.numCells) + { + Clear(); } - return preferredSize; -} + Point Grid::PreferredSize() + { + Point preferredSize; -void Grid::Layout() -{ - const Point& size = GetSize(); + for (unsigned int rowNum = 0; rowNum < m_numRows; rowNum++) { + Point rowSize; - Point childPos, childSize; - for (unsigned int rowNum = 0; rowNum < m_numRows; rowNum++) { - childSize.y = m_colSpec.cellPercent[rowNum]*size.y; + for (unsigned int colNum = 0; colNum < m_numCols; colNum++) { + const unsigned int n = rowNum * m_numCols + colNum; + Widget *w = m_widgets[n]; - childPos.x = 0; - for (unsigned int colNum = 0; colNum < m_numCols; colNum++) { - childSize.x = m_rowSpec.cellPercent[colNum]*size.x; + Point childPreferredSize; + if (w) + childPreferredSize = w->CalcLayoutContribution(); + else + childPreferredSize = Point(SIZE_EXPAND); - const unsigned int n = rowNum*m_numCols+colNum; + rowSize.x = SizeAdd(childPreferredSize.x, rowSize.x); + rowSize.y = std::max(childPreferredSize.y, rowSize.y); + } + + preferredSize.x = std::max(preferredSize.x, rowSize.x); + preferredSize.y = SizeAdd(preferredSize.y, rowSize.y); + } + + return preferredSize; + } + + void Grid::Layout() + { + const Point &size = GetSize(); + + Point childPos, childSize; + for (unsigned int rowNum = 0; rowNum < m_numRows; rowNum++) { + childSize.y = m_colSpec.cellPercent[rowNum] * size.y; + + childPos.x = 0; + for (unsigned int colNum = 0; colNum < m_numCols; colNum++) { + childSize.x = m_rowSpec.cellPercent[colNum] * size.x; + + const unsigned int n = rowNum * m_numCols + colNum; + if (m_widgets[n]) + SetWidgetDimensions(m_widgets[n], childPos, m_widgets[n]->CalcSize(childSize)); + + childPos.x += childSize.x; + } + + childPos.y += childSize.y; + } + + LayoutChildren(); + } + + Grid *Grid::SetRow(unsigned int rowNum, const WidgetSet &set) + { + assert(set.numWidgets <= m_rowSpec.numCells); + assert(rowNum < m_numRows); + + for (unsigned int i = 0; i < set.numWidgets; i++) { + const unsigned int n = rowNum * m_numCols + i; if (m_widgets[n]) - SetWidgetDimensions(m_widgets[n], childPos, m_widgets[n]->CalcSize(childSize)); - - childPos.x += childSize.x; + RemoveWidget(m_widgets[n]); + m_widgets[n] = set.widgets[i]; + AddWidget(m_widgets[n]); } - childPos.y += childSize.y; + return this; } - LayoutChildren(); -} + Grid *Grid::SetColumn(unsigned int colNum, const WidgetSet &set) + { + assert(set.numWidgets <= m_colSpec.numCells); + assert(colNum < m_numCols); -Grid *Grid::SetRow(unsigned int rowNum, const WidgetSet &set) -{ - assert(set.numWidgets <= m_rowSpec.numCells); - assert(rowNum < m_numRows); + for (unsigned int i = 0; i < set.numWidgets; i++) { + const unsigned int n = i * m_numCols + colNum; + if (m_widgets[n]) + RemoveWidget(m_widgets[n]); + m_widgets[n] = set.widgets[i]; + AddWidget(m_widgets[n]); + } - for (unsigned int i = 0; i < set.numWidgets; i++) { - const unsigned int n = rowNum*m_numCols+i; + return this; + } + + Grid *Grid::SetCell(unsigned int colNum, unsigned int rowNum, Widget *widget) + { + assert(colNum < m_numCols); + assert(rowNum < m_numRows); + + const unsigned int n = rowNum * m_numCols + colNum; if (m_widgets[n]) RemoveWidget(m_widgets[n]); - m_widgets[n] = set.widgets[i]; + m_widgets[n] = widget; AddWidget(m_widgets[n]); + + return this; } - return this; -} + void Grid::ClearRow(unsigned int rowNum) + { + assert(rowNum < m_numRows); -Grid *Grid::SetColumn(unsigned int colNum, const WidgetSet &set) -{ - assert(set.numWidgets <= m_colSpec.numCells); - assert(colNum < m_numCols); + for (unsigned int i = 0; i < m_numCols; i++) { + const unsigned int n = rowNum * m_numCols + i; + if (m_widgets[n]) { + Container::RemoveWidget(m_widgets[n]); + m_widgets[n] = 0; + } + } + } - for (unsigned int i = 0; i < set.numWidgets; i++) { - const unsigned int n = i*m_numCols+colNum; + void Grid::ClearColumn(unsigned int colNum) + { + assert(colNum < m_numRows); + + for (unsigned int i = 0; i < m_numRows; i++) { + const unsigned int n = i * m_numCols + colNum; + if (m_widgets[n]) { + Container::RemoveWidget(m_widgets[n]); + m_widgets[n] = 0; + } + } + } + + void Grid::ClearCell(unsigned int colNum, unsigned int rowNum) + { + assert(colNum < m_numCols); + assert(rowNum < m_numRows); + + const unsigned int n = rowNum * m_numCols + colNum; if (m_widgets[n]) RemoveWidget(m_widgets[n]); - m_widgets[n] = set.widgets[i]; - AddWidget(m_widgets[n]); + m_widgets[n] = 0; } - return this; -} - -Grid *Grid::SetCell(unsigned int colNum, unsigned int rowNum, Widget *widget) -{ - assert(colNum < m_numCols); - assert(rowNum < m_numRows); - - const unsigned int n = rowNum*m_numCols+colNum; - if (m_widgets[n]) - RemoveWidget(m_widgets[n]); - m_widgets[n] = widget; - AddWidget(m_widgets[n]); - - return this; -} - -void Grid::ClearRow(unsigned int rowNum) -{ - assert(rowNum < m_numRows); - - for (unsigned int i = 0; i < m_numCols; i++) { - const unsigned int n = rowNum*m_numCols+i; - if (m_widgets[n]) { - Container::RemoveWidget(m_widgets[n]); - m_widgets[n] = 0; - } - } -} - -void Grid::ClearColumn(unsigned int colNum) -{ - assert(colNum < m_numRows); - - for (unsigned int i = 0; i < m_numRows; i++) { - const unsigned int n = i*m_numCols+colNum; - if (m_widgets[n]) { - Container::RemoveWidget(m_widgets[n]); - m_widgets[n] = 0; - } - } -} - -void Grid::ClearCell(unsigned int colNum, unsigned int rowNum) -{ - assert(colNum < m_numCols); - assert(rowNum < m_numRows); - - const unsigned int n = rowNum*m_numCols+colNum; - if (m_widgets[n]) - RemoveWidget(m_widgets[n]); - m_widgets[n] = 0; -} - -void Grid::Clear() -{ - for (unsigned int i = 0; i < m_numRows*m_numCols; i++) - m_widgets[i] = 0; - - Container::RemoveAllWidgets(); -} - -void Grid::RemoveWidget(Widget *widget) -{ - for (unsigned int i = 0; i < m_numRows*m_numCols; i++) - if (m_widgets[i] == widget) { - Container::RemoveWidget(widget); + void Grid::Clear() + { + for (unsigned int i = 0; i < m_numRows * m_numCols; i++) m_widgets[i] = 0; - } -} -} + Container::RemoveAllWidgets(); + } + + void Grid::RemoveWidget(Widget *widget) + { + for (unsigned int i = 0; i < m_numRows * m_numCols; i++) + if (m_widgets[i] == widget) { + Container::RemoveWidget(widget); + m_widgets[i] = 0; + } + } + +} // namespace UI diff --git a/src/ui/Grid.h b/src/ui/Grid.h index 96601b210..09e3dff7b 100644 --- a/src/ui/Grid.h +++ b/src/ui/Grid.h @@ -4,41 +4,41 @@ #ifndef UI_GRID_H #define UI_GRID_H -#include "Container.h" #include "CellSpec.h" +#include "Container.h" namespace UI { -class Grid : public Container { -protected: - friend class Context; - Grid(Context *context, const CellSpec &rowSpec, const CellSpec &colSpec); + class Grid : public Container { + protected: + friend class Context; + Grid(Context *context, const CellSpec &rowSpec, const CellSpec &colSpec); -public: - virtual Point PreferredSize(); - virtual void Layout(); + public: + virtual Point PreferredSize(); + virtual void Layout(); - Grid *SetRow(unsigned int rowNum, const WidgetSet &set); - Grid *SetColumn(unsigned int colNum, const WidgetSet &set); - Grid *SetCell(unsigned int colNum, unsigned int rowNum, Widget *widget); + Grid *SetRow(unsigned int rowNum, const WidgetSet &set); + Grid *SetColumn(unsigned int colNum, const WidgetSet &set); + Grid *SetCell(unsigned int colNum, unsigned int rowNum, Widget *widget); - void ClearRow(unsigned int rowNum); - void ClearColumn(unsigned int colNum); - void ClearCell(unsigned int colNum, unsigned int rowNum); - void Clear(); + void ClearRow(unsigned int rowNum); + void ClearColumn(unsigned int colNum); + void ClearCell(unsigned int colNum, unsigned int rowNum); + void Clear(); - unsigned int GetNumRows() const { return m_numRows; } - unsigned int GetNumCols() const { return m_numCols; } + unsigned int GetNumRows() const { return m_numRows; } + unsigned int GetNumCols() const { return m_numCols; } -protected: - virtual void RemoveWidget(Widget *); + protected: + virtual void RemoveWidget(Widget *); -private: - CellSpec m_rowSpec, m_colSpec; - unsigned int m_numRows, m_numCols; - std::vector m_widgets; -}; + private: + CellSpec m_rowSpec, m_colSpec; + unsigned int m_numRows, m_numCols; + std::vector m_widgets; + }; -} +} // namespace UI #endif diff --git a/src/ui/Icon.cpp b/src/ui/Icon.cpp index a85c38dcf..e22c39726 100644 --- a/src/ui/Icon.cpp +++ b/src/ui/Icon.cpp @@ -11,89 +11,90 @@ static const char FALLBACK_ICON[] = "Blank"; namespace UI { -IniConfig Icon::s_config; -RefCountedPtr Icon::s_texture; -vector2f Icon::s_texScale; -RefCountedPtr Icon::s_material; + IniConfig Icon::s_config; + RefCountedPtr Icon::s_texture; + vector2f Icon::s_texScale; + RefCountedPtr Icon::s_material; -// XXX copypasta'd from Skin.cpp. this whole texture atlas and rectangles and -// whatever should be abstracted out -static void SplitSpec(const std::string &spec, std::vector &output) -{ - static const std::string delim(","); + // XXX copypasta'd from Skin.cpp. this whole texture atlas and rectangles and + // whatever should be abstracted out + static void SplitSpec(const std::string &spec, std::vector &output) + { + static const std::string delim(","); - size_t i = 0, start = 0, end = 0; - while (end != std::string::npos) { - // get to the first non-delim char - start = spec.find_first_not_of(delim, end); + size_t i = 0, start = 0, end = 0; + while (end != std::string::npos) { + // get to the first non-delim char + start = spec.find_first_not_of(delim, end); - // read the end, no more to do - if (start == std::string::npos) - break; + // read the end, no more to do + if (start == std::string::npos) + break; - // find the end - next delim or end of string - end = spec.find_first_of(delim, start); + // find the end - next delim or end of string + end = spec.find_first_of(delim, start); - // extract the fragment and remember it - output[i++] = atoi(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str()); - } -} - -Icon::Icon(Context *context, const std::string &iconName): Widget(context), - m_color(Color::WHITE) -{ - if (!s_texture) { - s_config.Read(FileSystem::gameDataFiles, CONFIG_FILE); - - s_texture.Reset(Graphics::TextureBuilder::UI(s_config.String("TextureFile")).GetOrCreateTexture(GetContext()->GetRenderer(), "ui")); - - const Graphics::TextureDescriptor &texDesc = s_texture->GetDescriptor(); - s_texScale = vector2f(1.0f/texDesc.dataSize.x, 1.0f/texDesc.dataSize.y); - - Graphics::MaterialDescriptor matDesc; - matDesc.textures = 1; - s_material.Reset(GetContext()->GetRenderer()->CreateMaterial(matDesc)); - s_material->texture0 = s_texture.Get(); + // extract the fragment and remember it + output[i++] = atoi(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str()); + } } - std::string spec(s_config.String(iconName.c_str())); - if (spec.size() == 0) - spec = s_config.String(FALLBACK_ICON); - assert(spec.size() > 0); + Icon::Icon(Context *context, const std::string &iconName) : + Widget(context), + m_color(Color::WHITE) + { + if (!s_texture) { + s_config.Read(FileSystem::gameDataFiles, CONFIG_FILE); - std::vector v(2); - SplitSpec(spec, v); - m_texPos = Point(v[0], v[1]); -} + s_texture.Reset(Graphics::TextureBuilder::UI(s_config.String("TextureFile")).GetOrCreateTexture(GetContext()->GetRenderer(), "ui")); -Point Icon::PreferredSize() -{ - SetSizeControlFlags(NO_HEIGHT | PRESERVE_ASPECT); - return Point(48); -} + const Graphics::TextureDescriptor &texDesc = s_texture->GetDescriptor(); + s_texScale = vector2f(1.0f / texDesc.dataSize.x, 1.0f / texDesc.dataSize.y); -void Icon::Draw() -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - if (!m_quad) { - const Point &offset = GetActiveOffset(); - const Point &area = GetActiveArea(); + Graphics::MaterialDescriptor matDesc; + matDesc.textures = 1; + s_material.Reset(GetContext()->GetRenderer()->CreateMaterial(matDesc)); + s_material->texture0 = s_texture.Get(); + } - const float x = offset.x; - const float y = offset.y; - const float sx = area.x; - const float sy = area.y; + std::string spec(s_config.String(iconName.c_str())); + if (spec.size() == 0) + spec = s_config.String(FALLBACK_ICON); + assert(spec.size() > 0); - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(x, y, 0.0f), vector2f(s_texScale.x*(m_texPos.x), s_texScale.y*(m_texPos.y))); - va.Add(vector3f(x, y+sy, 0.0f), vector2f(s_texScale.x*(m_texPos.x), s_texScale.y*(m_texPos.y+48))); - va.Add(vector3f(x+sx, y, 0.0f), vector2f(s_texScale.x*(m_texPos.x+48), s_texScale.y*(m_texPos.y))); - va.Add(vector3f(x+sx, y+sy, 0.0f), vector2f(s_texScale.x*(m_texPos.x+48), s_texScale.y*(m_texPos.y+48))); - - auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); - m_quad.reset(new Graphics::Drawables::TexturedQuad(r, s_material, va, renderState)); + std::vector v(2); + SplitSpec(spec, v); + m_texPos = Point(v[0], v[1]); } - m_quad->Draw(r, Color(m_color.r, m_color.g, m_color.b, GetContext()->GetOpacity()*m_color.a)); -} -} + Point Icon::PreferredSize() + { + SetSizeControlFlags(NO_HEIGHT | PRESERVE_ASPECT); + return Point(48); + } + + void Icon::Draw() + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + if (!m_quad) { + const Point &offset = GetActiveOffset(); + const Point &area = GetActiveArea(); + + const float x = offset.x; + const float y = offset.y; + const float sx = area.x; + const float sy = area.y; + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + va.Add(vector3f(x, y, 0.0f), vector2f(s_texScale.x * (m_texPos.x), s_texScale.y * (m_texPos.y))); + va.Add(vector3f(x, y + sy, 0.0f), vector2f(s_texScale.x * (m_texPos.x), s_texScale.y * (m_texPos.y + 48))); + va.Add(vector3f(x + sx, y, 0.0f), vector2f(s_texScale.x * (m_texPos.x + 48), s_texScale.y * (m_texPos.y))); + va.Add(vector3f(x + sx, y + sy, 0.0f), vector2f(s_texScale.x * (m_texPos.x + 48), s_texScale.y * (m_texPos.y + 48))); + + auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); + m_quad.reset(new Graphics::Drawables::TexturedQuad(r, s_material, va, renderState)); + } + m_quad->Draw(r, Color(m_color.r, m_color.g, m_color.b, GetContext()->GetOpacity() * m_color.a)); + } + +} // namespace UI diff --git a/src/ui/Icon.h b/src/ui/Icon.h index 806e92366..d63d62ed9 100644 --- a/src/ui/Icon.h +++ b/src/ui/Icon.h @@ -4,40 +4,44 @@ #ifndef UI_ICON_H #define UI_ICON_H -#include "Widget.h" #include "IniConfig.h" #include "SmartPtr.h" -#include "vector2.h" +#include "Widget.h" #include "graphics/Drawables.h" #include "graphics/Material.h" #include "graphics/Texture.h" +#include "vector2.h" namespace UI { -class Icon: public Widget { -public: - virtual Point PreferredSize(); - virtual void Draw(); + class Icon : public Widget { + public: + virtual Point PreferredSize(); + virtual void Draw(); - Icon *SetColor(const Color &c) { m_color = c; return this; } + Icon *SetColor(const Color &c) + { + m_color = c; + return this; + } -protected: - friend class Context; - Icon(Context *context, const std::string &iconName); + protected: + friend class Context; + Icon(Context *context, const std::string &iconName); -private: - static IniConfig s_config; + private: + static IniConfig s_config; - static RefCountedPtr s_texture; - static vector2f s_texScale; + static RefCountedPtr s_texture; + static vector2f s_texScale; - static RefCountedPtr s_material; + static RefCountedPtr s_material; - Point m_texPos; - Color m_color; - std::unique_ptr m_quad; -}; + Point m_texPos; + Color m_color; + std::unique_ptr m_quad; + }; -} +} // namespace UI #endif diff --git a/src/ui/Image.cpp b/src/ui/Image.cpp index e8f6e2933..cd7bcea5c 100644 --- a/src/ui/Image.cpp +++ b/src/ui/Image.cpp @@ -7,130 +7,129 @@ namespace UI { -namespace { + namespace { -static Point CalcDisplayDimensions(const UI::Context *context, const Graphics::Texture *texture) -{ - const auto image_size = texture->GetDescriptor().GetOriginalSize(); - const float scale = context->GetScale(); - return Point(scale * image_size.x, scale * image_size.y); -} + static Point CalcDisplayDimensions(const UI::Context *context, const Graphics::Texture *texture) + { + const auto image_size = texture->GetDescriptor().GetOriginalSize(); + const float scale = context->GetScale(); + return Point(scale * image_size.x, scale * image_size.y); + } -} + } // namespace -Image::Image(Context *context, const std::string &filename, Uint32 sizeControlFlags): Widget(context) - , m_centre(0.0f, 0.0f) - , m_scale(1.0f) - , m_preserveAspect(false) - , m_needsRefresh(false) -{ - Graphics::TextureBuilder b = Graphics::TextureBuilder::UI(filename); - m_texture.Reset(b.GetOrCreateTexture(GetContext()->GetRenderer(), "ui")); + Image::Image(Context *context, const std::string &filename, Uint32 sizeControlFlags) : + Widget(context), + m_centre(0.0f, 0.0f), + m_scale(1.0f), + m_preserveAspect(false), + m_needsRefresh(false) + { + Graphics::TextureBuilder b = Graphics::TextureBuilder::UI(filename); + m_texture.Reset(b.GetOrCreateTexture(GetContext()->GetRenderer(), "ui")); - m_initialSize = CalcDisplayDimensions(GetContext(), m_texture.Get()); + m_initialSize = CalcDisplayDimensions(GetContext(), m_texture.Get()); - Graphics::MaterialDescriptor material_desc; - material_desc.textures = 1; - m_material.Reset(GetContext()->GetRenderer()->CreateMaterial(material_desc)); - m_material->texture0 = m_texture.Get(); + Graphics::MaterialDescriptor material_desc; + material_desc.textures = 1; + m_material.Reset(GetContext()->GetRenderer()->CreateMaterial(material_desc)); + m_material->texture0 = m_texture.Get(); - SetSizeControlFlags(sizeControlFlags); -} - -Point Image::PreferredSize() -{ - return m_initialSize; -} - -Image *Image::SetHeightLines(Uint32 lines) -{ - m_needsRefresh = true; - const Text::TextureFont *font = GetContext()->GetFont(GetFont()).Get(); - const float height = font->GetHeight() * lines; - - const vector2f sz = m_texture->GetDescriptor().GetOriginalSize(); - const float width = height * sz.x/sz.y; - - m_initialSize = UI::Point(width, height); - GetContext()->RequestLayout(); - return this; -} - -Image *Image::SetNaturalSize() -{ - m_needsRefresh = true; - m_initialSize = CalcDisplayDimensions(GetContext(), m_texture.Get()); - GetContext()->RequestLayout(); - return this; -} - -void Image::SetTransform(float scale, const vector2f ¢re) -{ - if (!is_equal_exact(m_scale, scale) || !m_centre.ExactlyEqual(centre)) { - m_needsRefresh = true; - m_scale = scale; - m_centre = centre; + SetSizeControlFlags(sizeControlFlags); } -} -void Image::SetPreserveAspect(bool preserve_aspect) -{ - m_needsRefresh = true; - m_preserveAspect = preserve_aspect; -} + Point Image::PreferredSize() + { + return m_initialSize; + } -void Image::Draw() -{ - Graphics::Renderer *r = GetContext()->GetRenderer(); - if (!m_quad || m_needsRefresh) { - m_needsRefresh = false; - const Point &offset = GetActiveOffset(); - const Point &area = GetActiveArea(); - const auto &descriptor = m_texture->GetDescriptor(); + Image *Image::SetHeightLines(Uint32 lines) + { + m_needsRefresh = true; + const Text::TextureFont *font = GetContext()->GetFont(GetFont()).Get(); + const float height = font->GetHeight() * lines; - const float half_sx = area.x*0.5f; - const float half_sy = area.y*0.5f; + const vector2f sz = m_texture->GetDescriptor().GetOriginalSize(); + const float width = height * sz.x / sz.y; - float cx = offset.x + half_sx; - float cy = offset.y + half_sy; - float rx, ry; + m_initialSize = UI::Point(width, height); + GetContext()->RequestLayout(); + return this; + } - if (m_preserveAspect) { - const vector2f sz = descriptor.GetOriginalSize(); - const float wantRatio = sz.x / sz.y; - const float haveRatio = float(area.x) / float(area.y); - if (wantRatio > haveRatio) { - // limited by width + Image *Image::SetNaturalSize() + { + m_needsRefresh = true; + m_initialSize = CalcDisplayDimensions(GetContext(), m_texture.Get()); + GetContext()->RequestLayout(); + return this; + } + + void Image::SetTransform(float scale, const vector2f ¢re) + { + if (!is_equal_exact(m_scale, scale) || !m_centre.ExactlyEqual(centre)) { + m_needsRefresh = true; + m_scale = scale; + m_centre = centre; + } + } + + void Image::SetPreserveAspect(bool preserve_aspect) + { + m_needsRefresh = true; + m_preserveAspect = preserve_aspect; + } + + void Image::Draw() + { + Graphics::Renderer *r = GetContext()->GetRenderer(); + if (!m_quad || m_needsRefresh) { + m_needsRefresh = false; + const Point &offset = GetActiveOffset(); + const Point &area = GetActiveArea(); + const auto &descriptor = m_texture->GetDescriptor(); + + const float half_sx = area.x * 0.5f; + const float half_sy = area.y * 0.5f; + + float cx = offset.x + half_sx; + float cy = offset.y + half_sy; + float rx, ry; + + if (m_preserveAspect) { + const vector2f sz = descriptor.GetOriginalSize(); + const float wantRatio = sz.x / sz.y; + const float haveRatio = float(area.x) / float(area.y); + if (wantRatio > haveRatio) { + // limited by width + rx = half_sx; + ry = half_sx / wantRatio; + } else { + // limited by height + rx = half_sy * wantRatio; + ry = half_sy; + } + } else { rx = half_sx; - ry = half_sx / wantRatio; - } - else { - // limited by height - rx = half_sy * wantRatio; ry = half_sy; } + + rx *= m_scale; + ry *= m_scale; + cx -= rx * m_centre.x; + cy -= ry * m_centre.y; + const vector2f texSize = descriptor.texSize; + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + va.Add(vector3f(cx - rx, cy - ry, 0.0f), vector2f(0.0f, 0.0f)); + va.Add(vector3f(cx - rx, cy + ry, 0.0f), vector2f(0.0f, texSize.y)); + va.Add(vector3f(cx + rx, cy - ry, 0.0f), vector2f(texSize.x, 0.0f)); + va.Add(vector3f(cx + rx, cy + ry, 0.0f), vector2f(texSize.x, texSize.y)); + + auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); + m_quad.reset(new Graphics::Drawables::TexturedQuad(r, m_material, va, renderState)); } - else { - rx = half_sx; - ry = half_sy; - } - - rx *= m_scale; - ry *= m_scale; - cx -= rx*m_centre.x; - cy -= ry*m_centre.y; - const vector2f texSize = descriptor.texSize; - - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(cx - rx, cy - ry, 0.0f), vector2f(0.0f, 0.0f)); - va.Add(vector3f(cx - rx, cy + ry, 0.0f), vector2f(0.0f, texSize.y)); - va.Add(vector3f(cx + rx, cy - ry, 0.0f), vector2f(texSize.x, 0.0f)); - va.Add(vector3f(cx + rx, cy + ry, 0.0f), vector2f(texSize.x, texSize.y)); - - auto renderState = GetContext()->GetSkin().GetAlphaBlendState(); - m_quad.reset(new Graphics::Drawables::TexturedQuad(r, m_material, va, renderState)); + m_quad->Draw(r, Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, GetContext()->GetOpacity() * Color::WHITE.a)); } - m_quad->Draw(r, Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, GetContext()->GetOpacity()*Color::WHITE.a)); -} -} +} // namespace UI diff --git a/src/ui/Image.h b/src/ui/Image.h index 33180b346..ae6fbae7d 100644 --- a/src/ui/Image.h +++ b/src/ui/Image.h @@ -4,8 +4,8 @@ #ifndef UI_IMAGE_H #define UI_IMAGE_H -#include "Widget.h" #include "SmartPtr.h" +#include "Widget.h" #include "graphics/Drawables.h" #include "graphics/Material.h" #include "graphics/Texture.h" @@ -13,52 +13,52 @@ namespace UI { -class Image: public Widget { -public: - virtual Point PreferredSize(); - virtual void Draw(); + class Image : public Widget { + public: + virtual Point PreferredSize(); + virtual void Draw(); - // SetHeightLines sets the widget's preferred size to fit the image to a - // specified number of text lines in the widget's current font. - Image *SetHeightLines(Uint32 lines); + // SetHeightLines sets the widget's preferred size to fit the image to a + // specified number of text lines in the widget's current font. + Image *SetHeightLines(Uint32 lines); - // SetNaturalSize sets the widget's preferred size to match the size of - // the image data. - Image *SetNaturalSize(); + // SetNaturalSize sets the widget's preferred size to match the size of + // the image data. + Image *SetNaturalSize(); - // SetTransform applies a uniform scaling and an offset operation to the - // image at display time (this can be used to zoom in on the image). - // Parameter `centre' specifies what point in the image to centre in the - // widget. This is specified in normalised image coordinates, so: - // 0,0 -- centre the image - // 1,1 -- centre on the bottom-right corner of the image - // -1,1 -- centre on the bottom-left corner of the image - void SetTransform(float scale, const vector2f ¢re); + // SetTransform applies a uniform scaling and an offset operation to the + // image at display time (this can be used to zoom in on the image). + // Parameter `centre' specifies what point in the image to centre in the + // widget. This is specified in normalised image coordinates, so: + // 0,0 -- centre the image + // 1,1 -- centre on the bottom-right corner of the image + // -1,1 -- centre on the bottom-left corner of the image + void SetTransform(float scale, const vector2f ¢re); - // SetPreserveAspect determines how the image content is scaled to fit the - // Image widget. If true, the image is scaled uniformly and centered; - // if false then the image is stretched to fill the whole Image widget. - // Note that this is separate from the widget's size control flags, which - // determines how the widget itself is sized within the available layout - // area. - void SetPreserveAspect(bool preserve_aspect); + // SetPreserveAspect determines how the image content is scaled to fit the + // Image widget. If true, the image is scaled uniformly and centered; + // if false then the image is stretched to fill the whole Image widget. + // Note that this is separate from the widget's size control flags, which + // determines how the widget itself is sized within the available layout + // area. + void SetPreserveAspect(bool preserve_aspect); -protected: - friend class Context; - Image(Context *context, const std::string &filename, Uint32 sizeControlFlags); + protected: + friend class Context; + Image(Context *context, const std::string &filename, Uint32 sizeControlFlags); -private: - RefCountedPtr m_texture; - RefCountedPtr m_material; - std::unique_ptr m_quad; - Point m_initialSize; + private: + RefCountedPtr m_texture; + RefCountedPtr m_material; + std::unique_ptr m_quad; + Point m_initialSize; - vector2f m_centre; - float m_scale; - bool m_preserveAspect; - bool m_needsRefresh; -}; + vector2f m_centre; + float m_scale; + bool m_preserveAspect; + bool m_needsRefresh; + }; -} +} // namespace UI #endif diff --git a/src/ui/Label.cpp b/src/ui/Label.cpp index 3504ea3fc..6215c50a7 100644 --- a/src/ui/Label.cpp +++ b/src/ui/Label.cpp @@ -3,86 +3,86 @@ #include "Label.h" #include "Context.h" -#include "text/TextureFont.h" #include "graphics/VertexArray.h" #include "graphics/VertexBuffer.h" +#include "text/TextureFont.h" namespace UI { -static const Color disabledColor(204, 204, 204, 255); + static const Color disabledColor(204, 204, 204, 255); -Label::Label(Context *context, const std::string &text) : Widget(context) -, m_bNeedsUpdating(true) -, m_bPrevDisabled(false) -, m_prevOpacity(-1.0f) -, m_text(text) -, m_color(Color::WHITE) -, m_font(GetContext()->GetFont(GetFont())) -{ - RegisterBindPoint("text", sigc::mem_fun(this, &Label::BindText)); -} - -Point Label::PreferredSize() -{ - if( m_font != GetContext()->GetFont(GetFont()) ) { - m_font = GetContext()->GetFont(GetFont()); - } - vector2f textSize; - m_font->MeasureString(m_text, textSize.x, textSize.y); - m_preferredSize = Point(ceilf(textSize.x), ceilf(textSize.y)); - return m_preferredSize; -} - -void Label::Layout() -{ - if (m_preferredSize == Point()) - PreferredSize(); - - const Point &size = GetSize(); - SetActiveArea(Point(std::min(m_preferredSize.x,size.x), std::min(m_preferredSize.y,size.y))); - - m_bNeedsUpdating = true; -} - -void Label::Draw() -{ - if (m_text.empty()) - return; - - const Color color(IsDisabled() ? disabledColor : m_color); - const float opacity = GetContext()->GetOpacity(); - const Color finalColor(color.r, color.g, color.b, color.a*opacity); - - if (m_bNeedsUpdating || m_font != GetContext()->GetFont(GetFont()) || !is_equal_exact(m_prevOpacity, opacity) || m_bPrevDisabled != IsDisabled()) + Label::Label(Context *context, const std::string &text) : + Widget(context), + m_bNeedsUpdating(true), + m_bPrevDisabled(false), + m_prevOpacity(-1.0f), + m_text(text), + m_color(Color::WHITE), + m_font(GetContext()->GetFont(GetFont())) { - m_font = GetContext()->GetFont(GetFont()); - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); - m_font->PopulateString(va, m_text, 0.0f, 0.0f, finalColor); - if(!m_vbuffer || m_vbuffer->GetCapacity() < va.GetNumVerts()) { - m_vbuffer.Reset( m_font->CreateVertexBuffer(va, false) ); // too frequent for static - } - m_vbuffer->Populate(va); - m_bNeedsUpdating = false; - m_bPrevDisabled = IsDisabled(); - m_prevOpacity = opacity; + RegisterBindPoint("text", sigc::mem_fun(this, &Label::BindText)); } - m_font->RenderBuffer( m_vbuffer.Get() ); -} + Point Label::PreferredSize() + { + if (m_font != GetContext()->GetFont(GetFont())) { + m_font = GetContext()->GetFont(GetFont()); + } + vector2f textSize; + m_font->MeasureString(m_text, textSize.x, textSize.y); + m_preferredSize = Point(ceilf(textSize.x), ceilf(textSize.y)); + return m_preferredSize; + } -Label *Label::SetText(const std::string &text) -{ - m_text = text; - GetContext()->RequestLayout(); - m_bNeedsUpdating = true; - return this; -} + void Label::Layout() + { + if (m_preferredSize == Point()) + PreferredSize(); -void Label::BindText(PropertyMap &p, const std::string &k) -{ - std::string text; - p.Get(k, text); - SetText(text); -} + const Point &size = GetSize(); + SetActiveArea(Point(std::min(m_preferredSize.x, size.x), std::min(m_preferredSize.y, size.y))); -} + m_bNeedsUpdating = true; + } + + void Label::Draw() + { + if (m_text.empty()) + return; + + const Color color(IsDisabled() ? disabledColor : m_color); + const float opacity = GetContext()->GetOpacity(); + const Color finalColor(color.r, color.g, color.b, color.a * opacity); + + if (m_bNeedsUpdating || m_font != GetContext()->GetFont(GetFont()) || !is_equal_exact(m_prevOpacity, opacity) || m_bPrevDisabled != IsDisabled()) { + m_font = GetContext()->GetFont(GetFont()); + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + m_font->PopulateString(va, m_text, 0.0f, 0.0f, finalColor); + if (!m_vbuffer || m_vbuffer->GetCapacity() < va.GetNumVerts()) { + m_vbuffer.Reset(m_font->CreateVertexBuffer(va, false)); // too frequent for static + } + m_vbuffer->Populate(va); + m_bNeedsUpdating = false; + m_bPrevDisabled = IsDisabled(); + m_prevOpacity = opacity; + } + + m_font->RenderBuffer(m_vbuffer.Get()); + } + + Label *Label::SetText(const std::string &text) + { + m_text = text; + GetContext()->RequestLayout(); + m_bNeedsUpdating = true; + return this; + } + + void Label::BindText(PropertyMap &p, const std::string &k) + { + std::string text; + p.Get(k, text); + SetText(text); + } + +} // namespace UI diff --git a/src/ui/Label.h b/src/ui/Label.h index edbcdad15..bca3c3d95 100644 --- a/src/ui/Label.h +++ b/src/ui/Label.h @@ -4,43 +4,47 @@ #ifndef UI_LABEL_H #define UI_LABEL_H -#include "Widget.h" #include "SmartPtr.h" -#include "text/TextureFont.h" +#include "Widget.h" #include "graphics/VertexBuffer.h" +#include "text/TextureFont.h" // single line of text namespace UI { -class Label: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class Label : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - Label *SetText(const std::string &text); - const std::string &GetText() const { return m_text; } + Label *SetText(const std::string &text); + const std::string &GetText() const { return m_text; } - Label *SetColor(const Color &c) { m_color = c; return this; } + Label *SetColor(const Color &c) + { + m_color = c; + return this; + } -protected: - friend class Context; - Label(Context *context, const std::string &text); + protected: + friend class Context; + Label(Context *context, const std::string &text); -private: - void BindText(PropertyMap &p, const std::string &k); + private: + void BindText(PropertyMap &p, const std::string &k); - bool m_bNeedsUpdating; - bool m_bPrevDisabled; - float m_prevOpacity; - std::string m_text; - Color m_color; - Point m_preferredSize; - RefCountedPtr m_font; - RefCountedPtr m_vbuffer; -}; + bool m_bNeedsUpdating; + bool m_bPrevDisabled; + float m_prevOpacity; + std::string m_text; + Color m_color; + Point m_preferredSize; + RefCountedPtr m_font; + RefCountedPtr m_vbuffer; + }; -} +} // namespace UI #endif diff --git a/src/ui/Layer.cpp b/src/ui/Layer.cpp index 0bc48f86e..77c8adbd3 100644 --- a/src/ui/Layer.cpp +++ b/src/ui/Layer.cpp @@ -6,32 +6,32 @@ namespace UI { -void Layer::Layout() -{ - LayoutChildren(); -} + void Layer::Layout() + { + LayoutChildren(); + } -Layer *Layer::SetInnerWidget(Widget *w, const Point &pos, const Point &size) -{ - assert(!w->GetContainer()); + Layer *Layer::SetInnerWidget(Widget *w, const Point &pos, const Point &size) + { + assert(!w->GetContainer()); - Container::RemoveAllWidgets(); - m_widget.Reset(w); + Container::RemoveAllWidgets(); + m_widget.Reset(w); - Container::AddWidget(w); - Container::SetWidgetDimensions(w, pos, size); + Container::AddWidget(w); + Container::SetWidgetDimensions(w, pos, size); - GetContext()->RequestLayout(); + GetContext()->RequestLayout(); - return this; -} + return this; + } -void Layer::RemoveInnerWidget() -{ - Container::RemoveAllWidgets(); - m_widget.Reset(0); + void Layer::RemoveInnerWidget() + { + Container::RemoveAllWidgets(); + m_widget.Reset(0); - GetContext()->RequestLayout(); -} + GetContext()->RequestLayout(); + } -} +} // namespace UI diff --git a/src/ui/Layer.h b/src/ui/Layer.h index 8291499e0..517bda859 100644 --- a/src/ui/Layer.h +++ b/src/ui/Layer.h @@ -8,24 +8,25 @@ namespace UI { -class Layer : public Container { -public: - virtual void Layout(); + class Layer : public Container { + public: + virtual void Layout(); - Layer *SetInnerWidget(Widget *w, const Point &pos, const Point &size); - Layer *SetInnerWidget(Widget *w) { return SetInnerWidget(w, GetPosition(), GetSize()); } - virtual void RemoveInnerWidget(); - Widget *GetInnerWidget() const { return m_widget.Get(); } + Layer *SetInnerWidget(Widget *w, const Point &pos, const Point &size); + Layer *SetInnerWidget(Widget *w) { return SetInnerWidget(w, GetPosition(), GetSize()); } + virtual void RemoveInnerWidget(); + Widget *GetInnerWidget() const { return m_widget.Get(); } -private: - virtual Point PreferredSize() { return Point(); } + private: + virtual Point PreferredSize() { return Point(); } - friend class Context; - Layer(Context *context) : Container(context) {} + friend class Context; + Layer(Context *context) : + Container(context) {} - RefCountedPtr m_widget; -}; + RefCountedPtr m_widget; + }; -} +} // namespace UI #endif diff --git a/src/ui/List.cpp b/src/ui/List.cpp index 88075d728..f6ec7a7d3 100644 --- a/src/ui/List.cpp +++ b/src/ui/List.cpp @@ -7,126 +7,128 @@ namespace UI { -List::List(Context *context) : Container(context), m_selected(-1) -{ - Context *c = GetContext(); - m_container = c->Background(); - m_container->SetInnerWidget(c->VBox()); - AddWidget(m_container); -} + List::List(Context *context) : + Container(context), + m_selected(-1) + { + Context *c = GetContext(); + m_container = c->Background(); + m_container->SetInnerWidget(c->VBox()); + AddWidget(m_container); + } -Point List::PreferredSize() { - return m_container->PreferredSize(); -} + Point List::PreferredSize() + { + return m_container->PreferredSize(); + } -void List::Layout() { - SetWidgetDimensions(m_container, Point(), GetSize()); - m_container->Layout(); -} + void List::Layout() + { + SetWidgetDimensions(m_container, Point(), GetSize()); + m_container->Layout(); + } -List *List::AddOption(const std::string &text) -{ - m_options.push_back(text); + List *List::AddOption(const std::string &text) + { + m_options.push_back(text); - Context *c = GetContext(); + Context *c = GetContext(); - VBox *vbox = static_cast(m_container->GetInnerWidget()); + VBox *vbox = static_cast(m_container->GetInnerWidget()); - int index = m_optionBackgrounds.size(); + int index = m_optionBackgrounds.size(); - ColorBackground *background = c->ColorBackground(m_selected == index ? c->GetSkin().GetSelectColor() : c->GetSkin().GetNormalColor()); - vbox->PackEnd(background->SetInnerWidget(c->Label(text))); + ColorBackground *background = c->ColorBackground(m_selected == index ? c->GetSkin().GetSelectColor() : c->GetSkin().GetNormalColor()); + vbox->PackEnd(background->SetInnerWidget(c->Label(text))); - background->onMouseOver.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionMouseOver), index)); - background->onMouseOut.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionMouseOut), index)); - background->onClick.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionClick), index)); + background->onMouseOver.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionMouseOver), index)); + background->onMouseOut.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionMouseOut), index)); + background->onClick.connect(sigc::bind(sigc::mem_fun(this, &List::HandleOptionClick), index)); - m_optionBackgrounds.push_back(background); + m_optionBackgrounds.push_back(background); - GetContext()->RequestLayout(); + GetContext()->RequestLayout(); - return this; -} + return this; + } -const std::string &List::GetSelectedOption() const -{ - static const std::string empty; - if (m_selected < 0) - return empty; - return m_options[m_selected]; -} + const std::string &List::GetSelectedOption() const + { + static const std::string empty; + if (m_selected < 0) + return empty; + return m_options[m_selected]; + } -bool List::SetSelectedOption(const std::string &option) -{ - std::vector::const_iterator it = std::find(m_options.begin(), m_options.end(), option); - if (it != m_options.end()) { - SetSelectedIndex(it - m_options.begin()); - return true; - } else { + bool List::SetSelectedOption(const std::string &option) + { + std::vector::const_iterator it = std::find(m_options.begin(), m_options.end(), option); + if (it != m_options.end()) { + SetSelectedIndex(it - m_options.begin()); + return true; + } else { + return false; + } + } + + int List::GetSelectedIndex() const + { + return m_selected; + } + + void List::SetSelectedIndex(const int index) + { + assert(!m_options.empty() || index < 0); + assert(index < int(m_options.size())); + + if (m_selected != index) { + if (m_selected >= 0) { + ColorBackground *const from = m_optionBackgrounds[m_selected]; + from->SetColor(from->IsMouseOver() ? GetContext()->GetSkin().GetHoverColor() : GetContext()->GetSkin().GetNormalColor()); + } + + if (index >= 0) { + ColorBackground *const to = m_optionBackgrounds[index]; + if (!to->IsMouseOver()) { + to->SetColor(GetContext()->GetSkin().GetSelectColor()); + } + } + + m_selected = index; + onOptionSelected.emit(index, index >= 0 ? m_options[index] : ""); + } + } + + void List::Clear() + { + m_options.clear(); + m_optionBackgrounds.clear(); + static_cast(m_container->GetInnerWidget())->Clear(); + m_selected = -1; + + GetContext()->RequestLayout(); + } + + bool List::HandleOptionMouseOver(int index) + { + m_optionBackgrounds[index]->SetColor(GetContext()->GetSkin().GetHoverColor()); return false; } -} -int List::GetSelectedIndex() const -{ - return m_selected; -} - -void List::SetSelectedIndex(const int index) -{ - assert(!m_options.empty() || index < 0); - assert(index < int(m_options.size())); - - if (m_selected != index) { - if (m_selected >= 0) { - ColorBackground * const from = m_optionBackgrounds[m_selected]; - from->SetColor(from->IsMouseOver() - ? GetContext()->GetSkin().GetHoverColor() - : GetContext()->GetSkin().GetNormalColor()); - } - - if (index >= 0) { - ColorBackground * const to = m_optionBackgrounds[index]; - if (!to->IsMouseOver()) { - to->SetColor(GetContext()->GetSkin().GetSelectColor()); - } - } - - m_selected = index; - onOptionSelected.emit(index, index >= 0 ? m_options[index] : ""); + bool List::HandleOptionMouseOut(int index) + { + m_optionBackgrounds[index]->SetColor(m_selected == index ? GetContext()->GetSkin().GetSelectColor() : GetContext()->GetSkin().GetNormalColor()); + return false; } -} -void List::Clear() -{ - m_options.clear(); - m_optionBackgrounds.clear(); - static_cast(m_container->GetInnerWidget())->Clear(); - m_selected = -1; + bool List::HandleOptionClick(int index) + { + if ((index != m_selected) && (m_selected >= 0)) + m_optionBackgrounds[m_selected]->SetColor(GetContext()->GetSkin().GetNormalColor()); + m_selected = index; + onOptionSelected.emit(index, m_options[index]); - GetContext()->RequestLayout(); -} + return false; + } -bool List::HandleOptionMouseOver(int index) -{ - m_optionBackgrounds[index]->SetColor(GetContext()->GetSkin().GetHoverColor()); - return false; -} - -bool List::HandleOptionMouseOut(int index) -{ - m_optionBackgrounds[index]->SetColor(m_selected == index ? GetContext()->GetSkin().GetSelectColor() : GetContext()->GetSkin().GetNormalColor()); - return false; -} - -bool List::HandleOptionClick(int index) -{ - if ((index != m_selected) && (m_selected >= 0)) - m_optionBackgrounds[m_selected]->SetColor(GetContext()->GetSkin().GetNormalColor()); - m_selected = index; - onOptionSelected.emit(index, m_options[index]); - - return false; -} - -} +} // namespace UI diff --git a/src/ui/List.h b/src/ui/List.h index 0732c0e2c..e92b53423 100644 --- a/src/ui/List.h +++ b/src/ui/List.h @@ -8,43 +8,43 @@ namespace UI { -class Background; -class ColorBackground; + class Background; + class ColorBackground; -class List : public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class List : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); - List *AddOption(const std::string &text); - void Clear(); + List *AddOption(const std::string &text); + void Clear(); - size_t NumItems() const { return m_options.size(); } - bool IsEmpty() const { return m_options.empty(); } + size_t NumItems() const { return m_options.size(); } + bool IsEmpty() const { return m_options.empty(); } - const std::string &GetSelectedOption() const; - bool SetSelectedOption(const std::string &option); - int GetSelectedIndex() const; - void SetSelectedIndex(const int index); + const std::string &GetSelectedOption() const; + bool SetSelectedOption(const std::string &option); + int GetSelectedIndex() const; + void SetSelectedIndex(const int index); - sigc::signal onOptionSelected; + sigc::signal onOptionSelected; -protected: - friend class Context; - List(Context *context); + protected: + friend class Context; + List(Context *context); -private: - std::vector m_options; - int m_selected; + private: + std::vector m_options; + int m_selected; - Background *m_container; - std::vector m_optionBackgrounds; + Background *m_container; + std::vector m_optionBackgrounds; - bool HandleOptionMouseOver(int index); - bool HandleOptionMouseOut(int index); - bool HandleOptionClick(int index); -}; + bool HandleOptionMouseOver(int index); + bool HandleOptionMouseOut(int index); + bool HandleOptionClick(int index); + }; -} +} // namespace UI #endif diff --git a/src/ui/Lua.cpp b/src/ui/Lua.cpp index 974472990..9f8b921fa 100644 --- a/src/ui/Lua.cpp +++ b/src/ui/Lua.cpp @@ -4,84 +4,84 @@ #include "Lua.h" namespace UI { -namespace Lua { + namespace Lua { -void Init() -{ - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); - LuaObject::RegisterClass(); + void Init() + { + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); + LuaObject::RegisterClass(); - LuaObject::RegisterClass(); -} + LuaObject::RegisterClass(); + } -UI::Widget *GetWidget(UI::Context *c, lua_State *l, int idx) -{ - UI::Widget *w = LuaObject::GetFromLua(idx); - if (w) return w; + UI::Widget *GetWidget(UI::Context *c, lua_State *l, int idx) + { + UI::Widget *w = LuaObject::GetFromLua(idx); + if (w) return w; - if (lua_istable(l, idx)) { - LUA_DEBUG_START(l); + if (lua_istable(l, idx)) { + LUA_DEBUG_START(l); - int table = lua_absindex(l, idx); - lua_pushlstring(l, "widget", 6); - lua_rawget(l, table); + int table = lua_absindex(l, idx); + lua_pushlstring(l, "widget", 6); + lua_rawget(l, table); - if (lua_isuserdata(l, -1)) - w = LuaObject::GetFromLua(-1); + if (lua_isuserdata(l, -1)) + w = LuaObject::GetFromLua(-1); - lua_pop(l, 1); - LUA_DEBUG_END(l, 0); + lua_pop(l, 1); + LUA_DEBUG_END(l, 0); - return w; - } + return w; + } - if (lua_isstring(l, idx)) - return c->Label(lua_tostring(l, idx)); + if (lua_isstring(l, idx)) + return c->Label(lua_tostring(l, idx)); - return 0; -} + return 0; + } -UI::Widget *CheckWidget(UI::Context *c, lua_State *l, int idx) -{ - UI::Widget *w = GetWidget(c, l, idx); - if (w) return w; + UI::Widget *CheckWidget(UI::Context *c, lua_State *l, int idx) + { + UI::Widget *w = GetWidget(c, l, idx); + if (w) return w; - // will fail and produce a standard error message - w = LuaObject::CheckFromLua(idx); + // will fail and produce a standard error message + w = LuaObject::CheckFromLua(idx); - return 0; -} + return 0; + } -} -} + } // namespace Lua +} // namespace UI diff --git a/src/ui/Lua.h b/src/ui/Lua.h index 428c3670d..ad078710b 100644 --- a/src/ui/Lua.h +++ b/src/ui/Lua.h @@ -4,20 +4,20 @@ #ifndef UI_LUA_H #define UI_LUA_H -#include "LuaObject.h" #include "Context.h" +#include "LuaObject.h" namespace UI { -namespace Lua { + namespace Lua { - void Init(); + void Init(); - // get widget from stack. handles table.widget and autoconstructs Labels - // from strings too - UI::Widget *GetWidget(UI::Context *c, lua_State *l, int idx); - UI::Widget *CheckWidget(UI::Context *c, lua_State *l, int idx); + // get widget from stack. handles table.widget and autoconstructs Labels + // from strings too + UI::Widget *GetWidget(UI::Context *c, lua_State *l, int idx); + UI::Widget *CheckWidget(UI::Context *c, lua_State *l, int idx); -} -} + } // namespace Lua +} // namespace UI #endif diff --git a/src/ui/LuaAlign.cpp b/src/ui/LuaAlign.cpp index dd27c5c3b..41fb7ddec 100644 --- a/src/ui/LuaAlign.cpp +++ b/src/ui/LuaAlign.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaAlign { -public: + class LuaAlign { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Align"; +template <> +const char *LuaObject::s_type = "UI.Align"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaAnimation.cpp b/src/ui/LuaAnimation.cpp index 829a3be82..e0322577c 100644 --- a/src/ui/LuaAnimation.cpp +++ b/src/ui/LuaAnimation.cpp @@ -6,44 +6,47 @@ namespace UI { -class LuaAnimation { -public: + class LuaAnimation { + public: + static int l_finish(lua_State *l) + { + Animation *a = LuaObject::CheckFromLua(1); + a->Finish(); + return 0; + } - static int l_finish(lua_State *l) { - Animation *a = LuaObject::CheckFromLua(1); - a->Finish(); - return 0; - } + static int l_attr_running(lua_State *l) + { + Animation *a = LuaObject::CheckFromLua(1); + lua_pushboolean(l, a->IsRunning()); + return 1; + } - static int l_attr_running(lua_State *l) { - Animation *a = LuaObject::CheckFromLua(1); - lua_pushboolean(l, a->IsRunning()); - return 1; - } + static int l_attr_completed(lua_State *l) + { + Animation *a = LuaObject::CheckFromLua(1); + lua_pushboolean(l, a->IsCompleted()); + return 1; + } + }; - static int l_attr_completed(lua_State *l) { - Animation *a = LuaObject::CheckFromLua(1); - lua_pushboolean(l, a->IsCompleted()); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Animation"; +template <> +const char *LuaObject::s_type = "UI.Animation"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { - { "Finish", LuaAnimation::l_finish }, + { "Finish", LuaAnimation::l_finish }, { nullptr, nullptr } }; static const luaL_Reg l_attrs[] = { - { "running", LuaAnimation::l_attr_running }, + { "running", LuaAnimation::l_attr_running }, { "completed", LuaAnimation::l_attr_completed }, { nullptr, nullptr } }; diff --git a/src/ui/LuaBackground.cpp b/src/ui/LuaBackground.cpp index d270c3b5f..56415106a 100644 --- a/src/ui/LuaBackground.cpp +++ b/src/ui/LuaBackground.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaBackground { -public: + class LuaBackground { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Background"; +template <> +const char *LuaObject::s_type = "UI.Background"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaBox.cpp b/src/ui/LuaBox.cpp index be015a70a..d66b939bb 100644 --- a/src/ui/LuaBox.cpp +++ b/src/ui/LuaBox.cpp @@ -7,87 +7,89 @@ namespace UI { -class LuaBox { -public: + class LuaBox { + public: + static int l_pack_start(lua_State *l) + { + UI::Box *b = LuaObject::CheckFromLua(1); + UI::Context *c = b->GetContext(); - static int l_pack_start(lua_State *l) { - UI::Box *b = LuaObject::CheckFromLua(1); - UI::Context *c = b->GetContext(); + if (lua_istable(l, 2)) { + UI::Widget *w = UI::Lua::GetWidget(c, l, 2); + if (w) + b->PackStart(w); + else + for (size_t i = lua_rawlen(l, 2); i > 0; i--) { + lua_rawgeti(l, 2, i); + b->PackStart(UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + } else + b->PackStart(UI::Lua::CheckWidget(c, l, 2)); - if (lua_istable(l, 2)) { - UI::Widget *w = UI::Lua::GetWidget(c, l, 2); - if (w) - b->PackStart(w); - else - for (size_t i = lua_rawlen(l, 2); i > 0; i--) { - lua_rawgeti(l, 2, i); - b->PackStart(UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } + lua_pushvalue(l, 1); + return 1; } - else - b->PackStart(UI::Lua::CheckWidget(c, l, 2)); - lua_pushvalue(l, 1); - return 1; - } + static int l_pack_end(lua_State *l) + { + UI::Box *b = LuaObject::CheckFromLua(1); + UI::Context *c = b->GetContext(); - static int l_pack_end(lua_State *l) { - UI::Box *b = LuaObject::CheckFromLua(1); - UI::Context *c = b->GetContext(); + if (lua_istable(l, 2)) { + UI::Widget *w = UI::Lua::GetWidget(c, l, 2); + if (w) + b->PackEnd(w); + else + for (size_t i = 0; i < lua_rawlen(l, 2); i++) { + lua_rawgeti(l, 2, i + 1); + b->PackEnd(UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + } else + b->PackEnd(UI::Lua::CheckWidget(c, l, 2)); - if (lua_istable(l, 2)) { - UI::Widget *w = UI::Lua::GetWidget(c, l, 2); - if (w) - b->PackEnd(w); - else - for (size_t i = 0; i < lua_rawlen(l, 2); i++) { - lua_rawgeti(l, 2, i+1); - b->PackEnd(UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } + lua_pushvalue(l, 1); + return 1; } - else - b->PackEnd(UI::Lua::CheckWidget(c, l, 2)); - lua_pushvalue(l, 1); - return 1; - } + static int l_remove(lua_State *l) + { + UI::Box *b = LuaObject::CheckFromLua(1); + UI::Context *c = b->GetContext(); + UI::Widget *w = UI::Lua::CheckWidget(c, l, 2); + b->Remove(w); + return 0; + } - static int l_remove(lua_State *l) { - UI::Box *b = LuaObject::CheckFromLua(1); - UI::Context *c = b->GetContext(); - UI::Widget *w = UI::Lua::CheckWidget(c, l, 2); - b->Remove(w); - return 0; - } + static int l_clear(lua_State *l) + { + UI::Box *b = LuaObject::CheckFromLua(1); + b->Clear(); + return 0; + } + }; - static int l_clear(lua_State *l) { - UI::Box *b = LuaObject::CheckFromLua(1); - b->Clear(); - return 0; - } + class LuaHBox; + class LuaVBox; -}; - -class LuaHBox; -class LuaVBox; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Box"; +template <> +const char *LuaObject::s_type = "UI.Box"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { { "PackStart", LuaBox::l_pack_start }, - { "PackEnd", LuaBox::l_pack_end }, - { "Remove", LuaBox::l_remove }, - { "Clear", LuaBox::l_clear }, + { "PackEnd", LuaBox::l_pack_end }, + { "Remove", LuaBox::l_remove }, + { "Clear", LuaBox::l_clear }, { 0, 0 } }; @@ -95,9 +97,11 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterPromotion(l_parent, s_type, LuaObject::DynamicCastPromotionTest); } -template <> const char *LuaObject::s_type = "UI.HBox"; +template <> +const char *LuaObject::s_type = "UI.HBox"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Box"; @@ -105,9 +109,11 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterPromotion(l_parent, s_type, LuaObject::DynamicCastPromotionTest); } -template <> const char *LuaObject::s_type = "UI.VBox"; +template <> +const char *LuaObject::s_type = "UI.VBox"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Box"; diff --git a/src/ui/LuaButton.cpp b/src/ui/LuaButton.cpp index b2a9cd5a0..f0a1d649b 100644 --- a/src/ui/LuaButton.cpp +++ b/src/ui/LuaButton.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaButton { -public: + class LuaButton { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Button"; +template <> +const char *LuaObject::s_type = "UI.Button"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaCheckBox.cpp b/src/ui/LuaCheckBox.cpp index 2717b5990..2d2a210e6 100644 --- a/src/ui/LuaCheckBox.cpp +++ b/src/ui/LuaCheckBox.cpp @@ -7,41 +7,47 @@ namespace UI { -class LuaCheckBox { -public: - static int l_toggle(lua_State *l) { - UI::CheckBox *c = LuaObject::CheckFromLua(1); - c->Toggle(); - return 1; - } + class LuaCheckBox { + public: + static int l_toggle(lua_State *l) + { + UI::CheckBox *c = LuaObject::CheckFromLua(1); + c->Toggle(); + return 1; + } - static int l_set_state(lua_State *l) { - UI::CheckBox *c = LuaObject::CheckFromLua(1); - luaL_checktype(l, 2, LUA_TBOOLEAN); - c->SetState(lua_toboolean(l, 2)); - return 1; - } + static int l_set_state(lua_State *l) + { + UI::CheckBox *c = LuaObject::CheckFromLua(1); + luaL_checktype(l, 2, LUA_TBOOLEAN); + c->SetState(lua_toboolean(l, 2)); + return 1; + } - static int l_attr_is_checked(lua_State *l) { - UI::CheckBox *c = LuaObject::CheckFromLua(1); - lua_pushboolean(l, c->IsChecked()); - return 1; - } + static int l_attr_is_checked(lua_State *l) + { + UI::CheckBox *c = LuaObject::CheckFromLua(1); + lua_pushboolean(l, c->IsChecked()); + return 1; + } - static int l_attr_on_value_changed(lua_State *l) { - UI::CheckBox *c = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, c->onValueChanged); - return 1; - } -}; + static int l_attr_on_value_changed(lua_State *l) + { + UI::CheckBox *c = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, c->onValueChanged); + return 1; + } + }; -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.CheckBox"; +template <> +const char *LuaObject::s_type = "UI.CheckBox"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; @@ -52,7 +58,7 @@ template <> void LuaObject::RegisterClass() }; static const luaL_Reg l_attrs[] = { { "isChecked", LuaCheckBox::l_attr_is_checked }, - { "onValueChanged", LuaCheckBox::l_attr_on_value_changed }, + { "onValueChanged", LuaCheckBox::l_attr_on_value_changed }, { 0, 0 } }; diff --git a/src/ui/LuaColorBackground.cpp b/src/ui/LuaColorBackground.cpp index 2f84c28e1..511c2f723 100644 --- a/src/ui/LuaColorBackground.cpp +++ b/src/ui/LuaColorBackground.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaColorBackground { -public: + class LuaColorBackground { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.ColorBackground"; +template <> +const char *LuaObject::s_type = "UI.ColorBackground"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaContainer.cpp b/src/ui/LuaContainer.cpp index df0d984ea..210006e45 100644 --- a/src/ui/LuaContainer.cpp +++ b/src/ui/LuaContainer.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaContainer { -public: + class LuaContainer { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Container"; +template <> +const char *LuaObject::s_type = "UI.Container"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; diff --git a/src/ui/LuaContext.cpp b/src/ui/LuaContext.cpp index 04853580e..e041f4ebc 100644 --- a/src/ui/LuaContext.cpp +++ b/src/ui/LuaContext.cpp @@ -2,432 +2,464 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Context.h" -#include "LuaObject.h" #include "LuaConstants.h" +#include "LuaObject.h" #include "LuaSignal.h" namespace UI { -class LuaContext { -public: + class LuaContext { + public: + static inline UI::Widget *_get_implicit_widget(lua_State *l, int idx) + { + UI::Context *c = LuaObject::GetFromLua(1); + assert(c); - static inline UI::Widget *_get_implicit_widget(lua_State *l, int idx) - { - UI::Context *c = LuaObject::GetFromLua(1); - assert(c); - - if (lua_isnoneornil(l, idx)) return 0; - return UI::Lua::GetWidget(c, l, idx); - } - - static inline void _implicit_set_inner_widget(lua_State *l, UI::Layer *layer, int idx) - { - UI::Widget *w = _get_implicit_widget(l, idx); - if (!w) return; - layer->SetInnerWidget(w); - } - - static inline void _implicit_set_inner_widget(lua_State *l, UI::Single *s, int idx) - { - UI::Widget *w = _get_implicit_widget(l, idx); - if (!w) return; - s->SetInnerWidget(w); - } - - static inline void _implicit_set_inner_widget(lua_State *l, UI::Scroller *s, int idx) - { - UI::Widget *w = _get_implicit_widget(l, idx); - if (!w) return; - s->SetInnerWidget(w); - } - - static inline Uint32 _unpack_flags(lua_State *l, int idx, const char *constants) { - int table = lua_absindex(l, idx); - - if (!lua_istable(l, table)) - return 0; - - LUA_DEBUG_START(l); - - Uint32 flags = 0; - - lua_pushnil(l); - while (lua_next(l, table)) { - flags |= static_cast(LuaConstants::GetConstantFromArg(l, constants, -1)); - lua_pop(l, 1); + if (lua_isnoneornil(l, idx)) return 0; + return UI::Lua::GetWidget(c, l, idx); } - LUA_DEBUG_END(l, 0); + static inline void _implicit_set_inner_widget(lua_State *l, UI::Layer *layer, int idx) + { + UI::Widget *w = _get_implicit_widget(l, idx); + if (!w) return; + layer->SetInnerWidget(w); + } - return flags; - } + static inline void _implicit_set_inner_widget(lua_State *l, UI::Single *s, int idx) + { + UI::Widget *w = _get_implicit_widget(l, idx); + if (!w) return; + s->SetInnerWidget(w); + } - static int l_hbox(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - if (lua_gettop(l) > 1) - LuaObject::PushToLua(c->HBox(luaL_checknumber(l, 2))); - else - LuaObject::PushToLua(c->HBox()); - return 1; - } + static inline void _implicit_set_inner_widget(lua_State *l, UI::Scroller *s, int idx) + { + UI::Widget *w = _get_implicit_widget(l, idx); + if (!w) return; + s->SetInnerWidget(w); + } - static int l_vbox(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - if (lua_gettop(l) > 1) - LuaObject::PushToLua(c->VBox(luaL_checknumber(l, 2))); - else - LuaObject::PushToLua(c->VBox()); - return 1; - } + static inline Uint32 _unpack_flags(lua_State *l, int idx, const char *constants) + { + int table = lua_absindex(l, idx); - static int l_grid(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); + if (!lua_istable(l, table)) + return 0; - UI::CellSpec rowSpec(1), colSpec(1); + LUA_DEBUG_START(l); - if (lua_istable(l, 2)) - rowSpec = UI::CellSpec::FromLuaTable(l, 2); - else - rowSpec = UI::CellSpec(luaL_checkinteger(l, 2)); + Uint32 flags = 0; - if (lua_istable(l, 3)) - colSpec = UI::CellSpec::FromLuaTable(l, 3); - else - colSpec = UI::CellSpec(luaL_checkinteger(l, 3)); - - LuaObject::PushToLua(c->Grid(rowSpec, colSpec)); - return 1; - } - - static int l_table(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->Table()); - return 1; - } - - static int l_background(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Background *b = c->Background(); - _implicit_set_inner_widget(l, b, 2); - LuaObject::PushToLua(b); - return 1; - } - - static int l_colorbackground(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - float r = luaL_checknumber(l, 2); - float g = luaL_checknumber(l, 3); - float b = luaL_checknumber(l, 4); - float a = luaL_checknumber(l, 5); - UI::ColorBackground *cb = c->ColorBackground(Color(r*255,g*255,b*255,a*255)); - _implicit_set_inner_widget(l, cb, 6); - LuaObject::PushToLua(cb); - return 1; - } - - static int l_gradient(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - Color beginColor = Color::FromLuaTable(l, 2); - Color endColor = Color::FromLuaTable(l, 3); - UI::Gradient::Direction direction = static_cast(LuaConstants::GetConstantFromArg(l, "UIGradientDirection", 4)); - UI::Gradient *g = c->Gradient(beginColor, endColor, direction); - _implicit_set_inner_widget(l, g, 4); - LuaObject::PushToLua(g); - return 1; - } - - static int l_expand(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Expand::Direction direction = UI::Expand::BOTH; - if (lua_gettop(l) > 1) - direction = static_cast(LuaConstants::GetConstantFromArg(l, "UIExpandDirection", 2)); - UI::Expand *e = c->Expand(direction); - _implicit_set_inner_widget(l, e, 3); - LuaObject::PushToLua(e); - return 1; - } - - static int l_margin(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - int margin = luaL_checkinteger(l, 2); - UI::Margin::Direction dir = UI::Margin::ALL; - if (lua_gettop(l) > 2) - dir = static_cast(LuaConstants::GetConstantFromArg(l, "UIMarginDirection", 3)); - UI::Margin *m = c->Margin(margin, dir); - _implicit_set_inner_widget(l, m, 4); - LuaObject::PushToLua(m); - return 1; - } - - static int l_align(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Align::Direction dir = static_cast(LuaConstants::GetConstantFromArg(l, "UIAlignDirection", 2)); - UI::Align *a = c->Align(dir); - _implicit_set_inner_widget(l, a, 3); - LuaObject::PushToLua(a); - return 1; - } - - static int l_overlay_stack(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::OverlayStack *s = c->OverlayStack(); - LuaObject::PushToLua(s); - return 1; - } - - static int l_scroller(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Scroller *s = c->Scroller(); - _implicit_set_inner_widget(l, s, 2); - LuaObject::PushToLua(s); - return 1; - } - - static int l_icon(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - const std::string iconName(luaL_checkstring(l, 2)); - LuaObject::PushToLua(c->Icon(iconName)); - return 1; - } - - static int l_image(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - const std::string filename(luaL_checkstring(l, 2)); - Uint32 sizeControlFlags = _unpack_flags(l, 3, "UISizeControl"); - LuaObject::PushToLua(c->Image(filename, sizeControlFlags)); - return 1; - } - - static int l_label(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->Label(luaL_checkstring(l, 2))); - return 1; - } - - static int l_numberlabel(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::NumberLabel::Format format = UI::NumberLabel::FORMAT_NUMBER; - if (lua_gettop(l) > 1) - format = static_cast(LuaConstants::GetConstantFromArg(l, "UINumberLabelFormat", 2)); - LuaObject::PushToLua(c->NumberLabel(format)); - return 1; - } - - static int l_multilinetext(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->MultiLineText(luaL_checkstring(l, 2))); - return 1; - } - - static int l_button(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Button *b = c->Button(); - _implicit_set_inner_widget(l, b, 2); - LuaObject::PushToLua(b); - return 1; - } - - static int l_checkbox(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->CheckBox()); - return 1; - } - - static int l_smallbutton(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->SmallButton()); - return 1; - } - - static int l_hslider(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->HSlider()); - return 1; - } - - static int l_vslider(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->VSlider()); - return 1; - } - - static int l_list(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->List()); - return 1; - } - - static int l_dropdown(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->DropDown()); - return 1; - } - - static int l_gauge(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->Gauge()); - return 1; - } - - static int l_textentry(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - std::string text; - if (lua_gettop(l) > 1) - text = luaL_checkstring(l, 2); - LuaObject::PushToLua(c->TextEntry(text)); - return 1; - } - - static int l_attr_templates(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - c->GetTemplateStore().PushCopyToStack(); - return 1; - } - - static int l_new_layer(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - Layer *layer = c->NewLayer(); - _implicit_set_inner_widget(l, layer, 2); - LuaObject::PushToLua(layer); - return 1; - } - - static int l_drop_layer(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - c->DropLayer(); - return 1; - } - - static int l_attr_layer(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(c->GetTopLayer()); - return 1; - } - - static int l_new_animation(lua_State *l) { - LUA_DEBUG_START(l); - - LuaObject::CheckFromLua(1); // sanity - - luaL_checktype(l, 2, LUA_TTABLE); - - lua_getfield(l, 2, "widget"); - UI::Widget *w = LuaObject::CheckFromLua(-1); - lua_pop(l, 1); - - lua_getfield(l, 2, "type"); - UI::Animation::Type type = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationType", -1)); - lua_pop(l, 1); - - lua_getfield(l, 2, "easing"); - UI::Animation::Easing easing = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationEasing", -1)); - lua_pop(l, 1); - - lua_getfield(l, 2, "target"); - UI::Animation::Target target = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationTarget", -1)); - lua_pop(l, 1); - - lua_getfield(l, 2, "duration"); - float duration = lua_isnil(l, -1) ? 1.0f : lua_tonumber(l, -1); - lua_pop(l, 1); - - lua_getfield(l, 2, "continuous"); - bool continuous = lua_isnil(l, -1) ? false : lua_toboolean(l, -1); - lua_pop(l, 1); - - lua_getfield(l, 2, "next"); - UI::Animation *next = nullptr; - if (!lua_isnil(l, -1)) { - if (lua_istable(l, -1)) { - lua_pushcfunction(l, l_new_animation); - lua_pushvalue(l, 1); - lua_pushvalue(l, -3); - lua_call(l, 2, 1); - next = LuaObject::CheckFromLua(-1); + lua_pushnil(l); + while (lua_next(l, table)) { + flags |= static_cast(LuaConstants::GetConstantFromArg(l, constants, -1)); lua_pop(l, 1); } + + LUA_DEBUG_END(l, 0); + + return flags; + } + + static int l_hbox(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + if (lua_gettop(l) > 1) + LuaObject::PushToLua(c->HBox(luaL_checknumber(l, 2))); else - next = LuaObject::CheckFromLua(-1); + LuaObject::PushToLua(c->HBox()); + return 1; } - lua_pop(l, 1); - lua_getfield(l, 2, "callback"); - sigc::slot callback = lua_isnil(l, -1) ? sigc::slot() : LuaSlot::Wrap(l, -1); - lua_pop(l, 1); + static int l_vbox(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + if (lua_gettop(l) > 1) + LuaObject::PushToLua(c->VBox(luaL_checknumber(l, 2))); + else + LuaObject::PushToLua(c->VBox()); + return 1; + } - Animation *a = new UI::Animation(w, type, easing, target, duration, continuous, next, callback); + static int l_grid(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(a); + UI::CellSpec rowSpec(1), colSpec(1); - LUA_DEBUG_END(l, 1); + if (lua_istable(l, 2)) + rowSpec = UI::CellSpec::FromLuaTable(l, 2); + else + rowSpec = UI::CellSpec(luaL_checkinteger(l, 2)); - return 1; - } + if (lua_istable(l, 3)) + colSpec = UI::CellSpec::FromLuaTable(l, 3); + else + colSpec = UI::CellSpec(luaL_checkinteger(l, 3)); - static int l_animate(lua_State *l) { - UI::Context *c = LuaObject::CheckFromLua(1); - UI::Animation *a; - if (lua_istable(l, 2)) { - l_new_animation(l); - a = LuaObject::CheckFromLua(-1); + LuaObject::PushToLua(c->Grid(rowSpec, colSpec)); + return 1; + } + + static int l_table(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->Table()); + return 1; + } + + static int l_background(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Background *b = c->Background(); + _implicit_set_inner_widget(l, b, 2); + LuaObject::PushToLua(b); + return 1; + } + + static int l_colorbackground(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + float r = luaL_checknumber(l, 2); + float g = luaL_checknumber(l, 3); + float b = luaL_checknumber(l, 4); + float a = luaL_checknumber(l, 5); + UI::ColorBackground *cb = c->ColorBackground(Color(r * 255, g * 255, b * 255, a * 255)); + _implicit_set_inner_widget(l, cb, 6); + LuaObject::PushToLua(cb); + return 1; + } + + static int l_gradient(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + Color beginColor = Color::FromLuaTable(l, 2); + Color endColor = Color::FromLuaTable(l, 3); + UI::Gradient::Direction direction = static_cast(LuaConstants::GetConstantFromArg(l, "UIGradientDirection", 4)); + UI::Gradient *g = c->Gradient(beginColor, endColor, direction); + _implicit_set_inner_widget(l, g, 4); + LuaObject::PushToLua(g); + return 1; + } + + static int l_expand(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Expand::Direction direction = UI::Expand::BOTH; + if (lua_gettop(l) > 1) + direction = static_cast(LuaConstants::GetConstantFromArg(l, "UIExpandDirection", 2)); + UI::Expand *e = c->Expand(direction); + _implicit_set_inner_widget(l, e, 3); + LuaObject::PushToLua(e); + return 1; + } + + static int l_margin(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + int margin = luaL_checkinteger(l, 2); + UI::Margin::Direction dir = UI::Margin::ALL; + if (lua_gettop(l) > 2) + dir = static_cast(LuaConstants::GetConstantFromArg(l, "UIMarginDirection", 3)); + UI::Margin *m = c->Margin(margin, dir); + _implicit_set_inner_widget(l, m, 4); + LuaObject::PushToLua(m); + return 1; + } + + static int l_align(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Align::Direction dir = static_cast(LuaConstants::GetConstantFromArg(l, "UIAlignDirection", 2)); + UI::Align *a = c->Align(dir); + _implicit_set_inner_widget(l, a, 3); + LuaObject::PushToLua(a); + return 1; + } + + static int l_overlay_stack(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::OverlayStack *s = c->OverlayStack(); + LuaObject::PushToLua(s); + return 1; + } + + static int l_scroller(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Scroller *s = c->Scroller(); + _implicit_set_inner_widget(l, s, 2); + LuaObject::PushToLua(s); + return 1; + } + + static int l_icon(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + const std::string iconName(luaL_checkstring(l, 2)); + LuaObject::PushToLua(c->Icon(iconName)); + return 1; + } + + static int l_image(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + const std::string filename(luaL_checkstring(l, 2)); + Uint32 sizeControlFlags = _unpack_flags(l, 3, "UISizeControl"); + LuaObject::PushToLua(c->Image(filename, sizeControlFlags)); + return 1; + } + + static int l_label(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->Label(luaL_checkstring(l, 2))); + return 1; + } + + static int l_numberlabel(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::NumberLabel::Format format = UI::NumberLabel::FORMAT_NUMBER; + if (lua_gettop(l) > 1) + format = static_cast(LuaConstants::GetConstantFromArg(l, "UINumberLabelFormat", 2)); + LuaObject::PushToLua(c->NumberLabel(format)); + return 1; + } + + static int l_multilinetext(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->MultiLineText(luaL_checkstring(l, 2))); + return 1; + } + + static int l_button(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Button *b = c->Button(); + _implicit_set_inner_widget(l, b, 2); + LuaObject::PushToLua(b); + return 1; + } + + static int l_checkbox(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->CheckBox()); + return 1; + } + + static int l_smallbutton(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->SmallButton()); + return 1; + } + + static int l_hslider(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->HSlider()); + return 1; + } + + static int l_vslider(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->VSlider()); + return 1; + } + + static int l_list(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->List()); + return 1; + } + + static int l_dropdown(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->DropDown()); + return 1; + } + + static int l_gauge(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->Gauge()); + return 1; + } + + static int l_textentry(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + std::string text; + if (lua_gettop(l) > 1) + text = luaL_checkstring(l, 2); + LuaObject::PushToLua(c->TextEntry(text)); + return 1; + } + + static int l_attr_templates(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + c->GetTemplateStore().PushCopyToStack(); + return 1; + } + + static int l_new_layer(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + Layer *layer = c->NewLayer(); + _implicit_set_inner_widget(l, layer, 2); + LuaObject::PushToLua(layer); + return 1; + } + + static int l_drop_layer(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + c->DropLayer(); + return 1; + } + + static int l_attr_layer(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(c->GetTopLayer()); + return 1; + } + + static int l_new_animation(lua_State *l) + { + LUA_DEBUG_START(l); + + LuaObject::CheckFromLua(1); // sanity + + luaL_checktype(l, 2, LUA_TTABLE); + + lua_getfield(l, 2, "widget"); + UI::Widget *w = LuaObject::CheckFromLua(-1); lua_pop(l, 1); - } - else - a = LuaObject::CheckFromLua(2); - c->Animate(a); - return 0; - } -}; -} + lua_getfield(l, 2, "type"); + UI::Animation::Type type = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationType", -1)); + lua_pop(l, 1); + + lua_getfield(l, 2, "easing"); + UI::Animation::Easing easing = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationEasing", -1)); + lua_pop(l, 1); + + lua_getfield(l, 2, "target"); + UI::Animation::Target target = static_cast(LuaConstants::GetConstantFromArg(l, "UIAnimationTarget", -1)); + lua_pop(l, 1); + + lua_getfield(l, 2, "duration"); + float duration = lua_isnil(l, -1) ? 1.0f : lua_tonumber(l, -1); + lua_pop(l, 1); + + lua_getfield(l, 2, "continuous"); + bool continuous = lua_isnil(l, -1) ? false : lua_toboolean(l, -1); + lua_pop(l, 1); + + lua_getfield(l, 2, "next"); + UI::Animation *next = nullptr; + if (!lua_isnil(l, -1)) { + if (lua_istable(l, -1)) { + lua_pushcfunction(l, l_new_animation); + lua_pushvalue(l, 1); + lua_pushvalue(l, -3); + lua_call(l, 2, 1); + next = LuaObject::CheckFromLua(-1); + lua_pop(l, 1); + } else + next = LuaObject::CheckFromLua(-1); + } + lua_pop(l, 1); + + lua_getfield(l, 2, "callback"); + sigc::slot callback = lua_isnil(l, -1) ? sigc::slot() : LuaSlot::Wrap(l, -1); + lua_pop(l, 1); + + Animation *a = new UI::Animation(w, type, easing, target, duration, continuous, next, callback); + + LuaObject::PushToLua(a); + + LUA_DEBUG_END(l, 1); + + return 1; + } + + static int l_animate(lua_State *l) + { + UI::Context *c = LuaObject::CheckFromLua(1); + UI::Animation *a; + if (lua_istable(l, 2)) { + l_new_animation(l); + a = LuaObject::CheckFromLua(-1); + lua_pop(l, 1); + } else + a = LuaObject::CheckFromLua(2); + c->Animate(a); + return 0; + } + }; + +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Context"; +template <> +const char *LuaObject::s_type = "UI.Context"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "HBox", LuaContext::l_hbox }, - { "VBox", LuaContext::l_vbox }, - { "Grid", LuaContext::l_grid }, - { "Table", LuaContext::l_table }, - { "Background", LuaContext::l_background }, + { "HBox", LuaContext::l_hbox }, + { "VBox", LuaContext::l_vbox }, + { "Grid", LuaContext::l_grid }, + { "Table", LuaContext::l_table }, + { "Background", LuaContext::l_background }, { "ColorBackground", LuaContext::l_colorbackground }, - { "Gradient", LuaContext::l_gradient }, - { "Expand", LuaContext::l_expand }, - { "Margin", LuaContext::l_margin }, - { "Align", LuaContext::l_align }, - { "OverlayStack", LuaContext::l_overlay_stack }, - { "Scroller", LuaContext::l_scroller }, - { "Icon", LuaContext::l_icon }, - { "Image", LuaContext::l_image }, - { "Label", LuaContext::l_label }, - { "MultiLineText", LuaContext::l_multilinetext }, - { "NumberLabel", LuaContext::l_numberlabel }, - { "Button", LuaContext::l_button }, - { "CheckBox", LuaContext::l_checkbox }, - { "SmallButton", LuaContext::l_smallbutton }, - { "HSlider", LuaContext::l_hslider }, - { "VSlider", LuaContext::l_vslider }, - { "List", LuaContext::l_list }, - { "DropDown", LuaContext::l_dropdown }, - { "Gauge", LuaContext::l_gauge }, - { "TextEntry", LuaContext::l_textentry }, + { "Gradient", LuaContext::l_gradient }, + { "Expand", LuaContext::l_expand }, + { "Margin", LuaContext::l_margin }, + { "Align", LuaContext::l_align }, + { "OverlayStack", LuaContext::l_overlay_stack }, + { "Scroller", LuaContext::l_scroller }, + { "Icon", LuaContext::l_icon }, + { "Image", LuaContext::l_image }, + { "Label", LuaContext::l_label }, + { "MultiLineText", LuaContext::l_multilinetext }, + { "NumberLabel", LuaContext::l_numberlabel }, + { "Button", LuaContext::l_button }, + { "CheckBox", LuaContext::l_checkbox }, + { "SmallButton", LuaContext::l_smallbutton }, + { "HSlider", LuaContext::l_hslider }, + { "VSlider", LuaContext::l_vslider }, + { "List", LuaContext::l_list }, + { "DropDown", LuaContext::l_dropdown }, + { "Gauge", LuaContext::l_gauge }, + { "TextEntry", LuaContext::l_textentry }, - { "NewLayer", LuaContext::l_new_layer }, - { "DropLayer", LuaContext::l_drop_layer }, + { "NewLayer", LuaContext::l_new_layer }, + { "DropLayer", LuaContext::l_drop_layer }, - { "NewAnimation", LuaContext::l_new_animation }, - { "Animate", LuaContext::l_animate }, + { "NewAnimation", LuaContext::l_new_animation }, + { "Animate", LuaContext::l_animate }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { { "templates", LuaContext::l_attr_templates }, - { "layer", LuaContext::l_attr_layer }, + { "layer", LuaContext::l_attr_layer }, { 0, 0 } }; diff --git a/src/ui/LuaDropDown.cpp b/src/ui/LuaDropDown.cpp index 8881dd24b..de54c8a39 100644 --- a/src/ui/LuaDropDown.cpp +++ b/src/ui/LuaDropDown.cpp @@ -6,86 +6,94 @@ #include "LuaSignal.h" namespace UI { -class LuaDropDown { -public: - static int l_add_option(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - dropDown->AddOption(luaL_checkstring(l, 2)); - lua_pushvalue(l, 1); - return 1; - } - - static int l_set_selected_option(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - size_t len; - const char *str = luaL_checklstring(l, 2, &len); - const bool success = dropDown->SetSelectedOption(std::string(str, len)); - if (!success) { - luaL_error(l, "UI.DropDown.SetSelectedOption: invalid option '%s' specified", str); + class LuaDropDown { + public: + static int l_add_option(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + dropDown->AddOption(luaL_checkstring(l, 2)); + lua_pushvalue(l, 1); + return 1; } - lua_pushvalue(l, 1); - return 1; - } - static int l_set_selected_index(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - const int index = luaL_checkinteger(l, 2); - if (index < 1 || size_t(index) > dropDown->NumItems()) { - luaL_error(l, "UI.DropDown.SetSelectedIndex: invalid index %d specified", index); + static int l_set_selected_option(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + size_t len; + const char *str = luaL_checklstring(l, 2, &len); + const bool success = dropDown->SetSelectedOption(std::string(str, len)); + if (!success) { + luaL_error(l, "UI.DropDown.SetSelectedOption: invalid option '%s' specified", str); + } + lua_pushvalue(l, 1); + return 1; } - dropDown->SetSelectedIndex(index - 1); - lua_pushvalue(l, 1); - return 1; - } - static int l_attr_selected_option(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - if (dropDown->IsEmpty()) { - lua_pushnil(l); - } else { - const std::string &selectedOption = dropDown->GetSelectedOption(); - lua_pushlstring(l, selectedOption.c_str(), selectedOption.size()); + static int l_set_selected_index(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + const int index = luaL_checkinteger(l, 2); + if (index < 1 || size_t(index) > dropDown->NumItems()) { + luaL_error(l, "UI.DropDown.SetSelectedIndex: invalid index %d specified", index); + } + dropDown->SetSelectedIndex(index - 1); + lua_pushvalue(l, 1); + return 1; } - return 1; - } - static int l_attr_selected_index(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - if (dropDown->IsEmpty()) { - lua_pushnil(l); - } else { - lua_pushinteger(l, dropDown->GetSelectedIndex() + 1); + static int l_attr_selected_option(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + if (dropDown->IsEmpty()) { + lua_pushnil(l); + } else { + const std::string &selectedOption = dropDown->GetSelectedOption(); + lua_pushlstring(l, selectedOption.c_str(), selectedOption.size()); + } + return 1; } - return 1; - } - static int l_attr_on_option_selected(lua_State *l) { - UI::DropDown *dropDown = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, dropDown->onOptionSelected); - return 1; - } -}; + static int l_attr_selected_index(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + if (dropDown->IsEmpty()) { + lua_pushnil(l); + } else { + lua_pushinteger(l, dropDown->GetSelectedIndex() + 1); + } + return 1; + } -} + static int l_attr_on_option_selected(lua_State *l) + { + UI::DropDown *dropDown = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, dropDown->onOptionSelected); + return 1; + } + }; + +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.DropDown"; +template <> +const char *LuaObject::s_type = "UI.DropDown"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; static const luaL_Reg l_methods[] = { - { "AddOption", LuaDropDown::l_add_option }, + { "AddOption", LuaDropDown::l_add_option }, { "SetSelectedOption", LuaDropDown::l_set_selected_option }, - { "SetSelectedIndex", LuaDropDown::l_set_selected_index }, + { "SetSelectedIndex", LuaDropDown::l_set_selected_index }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "selectedIndex", LuaDropDown::l_attr_selected_index }, - { "selectedOption", LuaDropDown::l_attr_selected_option }, + { "selectedIndex", LuaDropDown::l_attr_selected_index }, + { "selectedOption", LuaDropDown::l_attr_selected_option }, { "onOptionSelected", LuaDropDown::l_attr_on_option_selected }, { 0, 0 } }; diff --git a/src/ui/LuaExpand.cpp b/src/ui/LuaExpand.cpp index 733c69ad4..759931a43 100644 --- a/src/ui/LuaExpand.cpp +++ b/src/ui/LuaExpand.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaExpand { -public: + class LuaExpand { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Expand"; +template <> +const char *LuaObject::s_type = "UI.Expand"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaGauge.cpp b/src/ui/LuaGauge.cpp index f854d9e4b..e43cfa72d 100644 --- a/src/ui/LuaGauge.cpp +++ b/src/ui/LuaGauge.cpp @@ -6,66 +6,72 @@ namespace UI { -class LuaGauge { -public: + class LuaGauge { + public: + static int l_set_value(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + gauge->SetValue(luaL_checknumber(l, 2)); + return 0; + } - static int l_set_value(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - gauge->SetValue(luaL_checknumber(l, 2)); - return 0; - } + static int l_attr_value(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + lua_pushnumber(l, gauge->GetValue()); + return 1; + } - static int l_attr_value(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - lua_pushnumber(l, gauge->GetValue()); - return 1; - } + static int l_set_upper_value(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + gauge->SetUpperValue(luaL_checknumber(l, 2)); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_upper_value(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - gauge->SetUpperValue(luaL_checknumber(l, 2)); - lua_pushvalue(l, 1); - return 1; - } + static int l_set_warning_level(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + gauge->SetWarningLevel(luaL_checknumber(l, 2)); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_warning_level(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - gauge->SetWarningLevel(luaL_checknumber(l, 2)); - lua_pushvalue(l, 1); - return 1; - } + static int l_set_critical_level(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + gauge->SetCriticalLevel(luaL_checknumber(l, 2)); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_critical_level(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - gauge->SetCriticalLevel(luaL_checknumber(l, 2)); - lua_pushvalue(l, 1); - return 1; - } + static int l_set_level_ascending(lua_State *l) + { + UI::Gauge *gauge = LuaObject::CheckFromLua(1); + gauge->SetLevelAscending(lua_toboolean(l, 2)); + lua_pushvalue(l, 1); + return 1; + } + }; - static int l_set_level_ascending(lua_State *l) { - UI::Gauge *gauge = LuaObject::CheckFromLua(1); - gauge->SetLevelAscending(lua_toboolean(l, 2)); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Gauge"; +template <> +const char *LuaObject::s_type = "UI.Gauge"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; static const luaL_Reg l_methods[] = { - { "SetValue", &LuaGauge::l_set_value }, - { "SetUpperValue", &LuaGauge::l_set_upper_value }, - { "SetWarningLevel", &LuaGauge::l_set_warning_level }, - { "SetCriticalLevel", &LuaGauge::l_set_critical_level }, + { "SetValue", &LuaGauge::l_set_value }, + { "SetUpperValue", &LuaGauge::l_set_upper_value }, + { "SetWarningLevel", &LuaGauge::l_set_warning_level }, + { "SetCriticalLevel", &LuaGauge::l_set_critical_level }, { "SetLevelAscending", &LuaGauge::l_set_level_ascending }, { 0, 0 } }; diff --git a/src/ui/LuaGradient.cpp b/src/ui/LuaGradient.cpp index b5d5d9365..b83b36224 100644 --- a/src/ui/LuaGradient.cpp +++ b/src/ui/LuaGradient.cpp @@ -6,18 +6,19 @@ namespace UI { -class LuaGradient { -public: + class LuaGradient { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Gradient"; +template <> +const char *LuaObject::s_type = "UI.Gradient"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaGrid.cpp b/src/ui/LuaGrid.cpp index edb0c96e7..9ab323d16 100644 --- a/src/ui/LuaGrid.cpp +++ b/src/ui/LuaGrid.cpp @@ -6,129 +6,136 @@ namespace UI { -class LuaGrid { -public: + class LuaGrid { + public: + static int l_set_row(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + UI::Context *c = g->GetContext(); - static int l_set_row(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - UI::Context *c = g->GetContext(); + size_t rowNum = luaL_checkinteger(l, 2); + luaL_checktype(l, 3, LUA_TTABLE); - size_t rowNum = luaL_checkinteger(l, 2); - luaL_checktype(l, 3, LUA_TTABLE); + if (rowNum >= g->GetNumRows()) { + luaL_error(l, "no such row %d (max is %d)", rowNum, g->GetNumRows() - 1); + return 0; + } - if (rowNum >= g->GetNumRows()) { - luaL_error(l, "no such row %d (max is %d)", rowNum, g->GetNumRows()-1); + for (size_t i = 0; i < g->GetNumCols() && i < lua_rawlen(l, 3); i++) { + lua_rawgeti(l, 3, i + 1); + if (lua_isnil(l, -1)) + g->ClearCell(i, rowNum); + else + g->SetCell(i, rowNum, UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_column(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + UI::Context *c = g->GetContext(); + + size_t colNum = luaL_checkinteger(l, 2); + luaL_checktype(l, 3, LUA_TTABLE); + + if (colNum >= g->GetNumCols()) { + luaL_error(l, "no such column %d (max is %d)", colNum, g->GetNumCols() - 1); + return 0; + } + + for (size_t i = 0; i < g->GetNumRows() && i < lua_rawlen(l, 3); i++) { + lua_rawgeti(l, 3, i + 1); + if (lua_isnil(l, -1)) + g->ClearCell(colNum, i); + else + g->SetCell(colNum, i, UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_cell(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + UI::Context *c = g->GetContext(); + + size_t colNum = luaL_checkinteger(l, 2); + size_t rowNum = luaL_checkinteger(l, 3); + UI::Widget *w = UI::Lua::CheckWidget(c, l, 4); + + if (colNum >= g->GetNumCols()) { + luaL_error(l, "no such column %d (max is %d)", colNum, g->GetNumCols() - 1); + return 0; + } + if (rowNum >= g->GetNumRows()) { + luaL_error(l, "no such row %d (max is %d)", rowNum, g->GetNumRows() - 1); + return 0; + } + + g->SetCell(colNum, rowNum, w); + + lua_pushvalue(l, 1); + return 1; + } + + static int l_clear_row(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + g->ClearRow(luaL_checkinteger(l, 2)); return 0; } - for (size_t i = 0; i < g->GetNumCols() && i < lua_rawlen(l, 3); i++) { - lua_rawgeti(l, 3, i+1); - if (lua_isnil(l, -1)) - g->ClearCell(i, rowNum); - else - g->SetCell(i, rowNum, UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } - - lua_pushvalue(l, 1); - return 1; - } - - static int l_set_column(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - UI::Context *c = g->GetContext(); - - size_t colNum = luaL_checkinteger(l, 2); - luaL_checktype(l, 3, LUA_TTABLE); - - if (colNum >= g->GetNumCols()) { - luaL_error(l, "no such column %d (max is %d)", colNum, g->GetNumCols()-1); + static int l_clear_column(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + g->ClearColumn(luaL_checkinteger(l, 2)); return 0; } - for (size_t i = 0; i < g->GetNumRows() && i < lua_rawlen(l, 3); i++) { - lua_rawgeti(l, 3, i+1); - if (lua_isnil(l, -1)) - g->ClearCell(colNum, i); - else - g->SetCell(colNum, i, UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } - - lua_pushvalue(l, 1); - return 1; - } - - static int l_set_cell(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - UI::Context *c = g->GetContext(); - - size_t colNum = luaL_checkinteger(l, 2); - size_t rowNum = luaL_checkinteger(l, 3); - UI::Widget *w = UI::Lua::CheckWidget(c, l, 4); - - if (colNum >= g->GetNumCols()) { - luaL_error(l, "no such column %d (max is %d)", colNum, g->GetNumCols()-1); - return 0; - } - if (rowNum >= g->GetNumRows()) { - luaL_error(l, "no such row %d (max is %d)", rowNum, g->GetNumRows()-1); + static int l_clear_cell(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + unsigned int colNum = luaL_checkinteger(l, 2); + unsigned int rowNum = luaL_checkinteger(l, 3); + g->ClearCell(colNum, rowNum); return 0; } - g->SetCell(colNum, rowNum, w); + static int l_clear(lua_State *l) + { + UI::Grid *g = LuaObject::CheckFromLua(1); + g->Clear(); + return 0; + } + }; - lua_pushvalue(l, 1); - return 1; - } - - static int l_clear_row(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - g->ClearRow(luaL_checkinteger(l, 2)); - return 0; - } - - static int l_clear_column(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - g->ClearColumn(luaL_checkinteger(l, 2)); - return 0; - } - - static int l_clear_cell(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - unsigned int colNum = luaL_checkinteger(l, 2); - unsigned int rowNum = luaL_checkinteger(l, 3); - g->ClearCell(colNum, rowNum); - return 0; - } - - static int l_clear(lua_State *l) { - UI::Grid *g = LuaObject::CheckFromLua(1); - g->Clear(); - return 0; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Grid"; +template <> +const char *LuaObject::s_type = "UI.Grid"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "SetRow", LuaGrid::l_set_row }, - { "SetColumn", LuaGrid::l_set_column }, - { "SetCell", LuaGrid::l_set_cell }, + { "SetRow", LuaGrid::l_set_row }, + { "SetColumn", LuaGrid::l_set_column }, + { "SetCell", LuaGrid::l_set_cell }, - { "ClearRow", LuaGrid::l_clear_row }, + { "ClearRow", LuaGrid::l_clear_row }, { "ClearColumn", LuaGrid::l_clear_column }, - { "ClearCell", LuaGrid::l_clear_cell }, - { "Clear", LuaGrid::l_clear }, + { "ClearCell", LuaGrid::l_clear_cell }, + { "Clear", LuaGrid::l_clear }, { 0, 0 } }; diff --git a/src/ui/LuaIcon.cpp b/src/ui/LuaIcon.cpp index dce970129..690f92f8b 100644 --- a/src/ui/LuaIcon.cpp +++ b/src/ui/LuaIcon.cpp @@ -6,26 +6,27 @@ namespace UI { -class LuaIcon { -public: + class LuaIcon { + public: + static int l_set_color(lua_State *l) + { + UI::Icon *icon = LuaObject::CheckFromLua(1); + Color c = Color::FromLuaTable(l, 2); + icon->SetColor(c); + lua_pushvalue(l, 1); + return 1; + } + }; - static int l_set_color(lua_State *l) { - UI::Icon *icon = LuaObject::CheckFromLua(1); - Color c = Color::FromLuaTable(l, 2); - icon->SetColor(c); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Icon"; +template <> +const char *LuaObject::s_type = "UI.Icon"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; diff --git a/src/ui/LuaImage.cpp b/src/ui/LuaImage.cpp index 64bfa8ff9..92618fec0 100644 --- a/src/ui/LuaImage.cpp +++ b/src/ui/LuaImage.cpp @@ -6,26 +6,27 @@ namespace UI { -class LuaImage { -public: + class LuaImage { + public: + static int l_set_height_lines(lua_State *l) + { + Image *img = LuaObject::CheckFromLua(1); + Uint32 lines = luaL_checkinteger(l, 2); + img->SetHeightLines(lines); + lua_pushvalue(l, 1); + return 1; + } + }; - static int l_set_height_lines(lua_State *l) { - Image *img = LuaObject::CheckFromLua(1); - Uint32 lines = luaL_checkinteger(l, 2); - img->SetHeightLines(lines); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Image"; +template <> +const char *LuaObject::s_type = "UI.Image"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; diff --git a/src/ui/LuaLabel.cpp b/src/ui/LuaLabel.cpp index 32e88b3e8..d64316979 100644 --- a/src/ui/LuaLabel.cpp +++ b/src/ui/LuaLabel.cpp @@ -6,33 +6,35 @@ namespace UI { -class LuaLabel { -public: + class LuaLabel { + public: + static int l_set_text(lua_State *l) + { + UI::Label *label = LuaObject::CheckFromLua(1); + const std::string text(luaL_checkstring(l, 2)); + label->SetText(text); + return 0; + } - static int l_set_text(lua_State *l) { - UI::Label *label = LuaObject::CheckFromLua(1); - const std::string text(luaL_checkstring(l, 2)); - label->SetText(text); - return 0; - } + static int l_set_color(lua_State *l) + { + UI::Label *label = LuaObject::CheckFromLua(1); + Color c = Color::FromLuaTable(l, 2); + label->SetColor(c); + lua_pushvalue(l, 1); + return 1; + } + }; - static int l_set_color(lua_State *l) { - UI::Label *label = LuaObject::CheckFromLua(1); - Color c = Color::FromLuaTable(l, 2); - label->SetColor(c); - lua_pushvalue(l, 1); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Label"; +template <> +const char *LuaObject::s_type = "UI.Label"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; diff --git a/src/ui/LuaLayer.cpp b/src/ui/LuaLayer.cpp index 9455ee0a4..c0056aed4 100644 --- a/src/ui/LuaLayer.cpp +++ b/src/ui/LuaLayer.cpp @@ -6,43 +6,47 @@ namespace UI { -class LuaLayer { -public: + class LuaLayer { + public: + static int l_set_inner_widget(lua_State *l) + { + Layer *layer = LuaObject::CheckFromLua(1); + Context *c = layer->GetContext(); + Widget *w = UI::Lua::CheckWidget(c, l, 2); + layer->SetInnerWidget(w); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_inner_widget(lua_State *l) { - Layer *layer = LuaObject::CheckFromLua(1); - Context *c = layer->GetContext(); - Widget *w = UI::Lua::CheckWidget(c, l, 2); - layer->SetInnerWidget(w); - lua_pushvalue(l, 1); - return 1; - } + static int l_remove_inner_widget(lua_State *l) + { + Layer *layer = LuaObject::CheckFromLua(1); + layer->RemoveInnerWidget(); + return 0; + } - static int l_remove_inner_widget(lua_State *l) { - Layer *layer = LuaObject::CheckFromLua(1); - layer->RemoveInnerWidget(); - return 0; - } + static int l_attr_inner_widget(lua_State *l) + { + Layer *s = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(s->GetInnerWidget()); + return 1; + } + }; - static int l_attr_inner_widget(lua_State *l) { - Layer *s = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(s->GetInnerWidget()); - return 1; - } -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Layer"; +template <> +const char *LuaObject::s_type = "UI.Layer"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "SetInnerWidget", LuaLayer::l_set_inner_widget }, + { "SetInnerWidget", LuaLayer::l_set_inner_widget }, { "RemoveInnerWidget", LuaLayer::l_remove_inner_widget }, { 0, 0 } }; diff --git a/src/ui/LuaList.cpp b/src/ui/LuaList.cpp index f46683db7..0e3c760ec 100644 --- a/src/ui/LuaList.cpp +++ b/src/ui/LuaList.cpp @@ -7,88 +7,94 @@ namespace UI { -class LuaList { -public: - - static int l_add_option(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - list->AddOption(luaL_checkstring(l, 2)); - lua_pushvalue(l, 1); - return 1; - } - - static int l_set_selected_option(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - size_t len; - const char *str = luaL_checklstring(l, 2, &len); - const bool success = list->SetSelectedOption(std::string(str, len)); - if (!success) { - luaL_error(l, "UI.List.SetSelectedOption: invalid option '%s' specified", str); + class LuaList { + public: + static int l_add_option(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + list->AddOption(luaL_checkstring(l, 2)); + lua_pushvalue(l, 1); + return 1; } - lua_pushvalue(l, 1); - return 1; - } - static int l_set_selected_index(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - const int index = luaL_checkinteger(l, 2); - if (index < 1 || size_t(index) > list->NumItems()) { - luaL_error(l, "UI.List.SetSelectedIndex: invalid index %d specified", index); + static int l_set_selected_option(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + size_t len; + const char *str = luaL_checklstring(l, 2, &len); + const bool success = list->SetSelectedOption(std::string(str, len)); + if (!success) { + luaL_error(l, "UI.List.SetSelectedOption: invalid option '%s' specified", str); + } + lua_pushvalue(l, 1); + return 1; } - list->SetSelectedIndex(index - 1); - lua_pushvalue(l, 1); - return 1; - } - static int l_attr_selected_option(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - if (list->IsEmpty()) { - lua_pushnil(l); - } else { - const std::string &selectedOption = list->GetSelectedOption(); - lua_pushlstring(l, selectedOption.c_str(), selectedOption.size()); + static int l_set_selected_index(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + const int index = luaL_checkinteger(l, 2); + if (index < 1 || size_t(index) > list->NumItems()) { + luaL_error(l, "UI.List.SetSelectedIndex: invalid index %d specified", index); + } + list->SetSelectedIndex(index - 1); + lua_pushvalue(l, 1); + return 1; } - return 1; - } - static int l_attr_selected_index(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - if (list->IsEmpty()) { - lua_pushnil(l); - } else { - lua_pushinteger(l, list->GetSelectedIndex() + 1); + static int l_attr_selected_option(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + if (list->IsEmpty()) { + lua_pushnil(l); + } else { + const std::string &selectedOption = list->GetSelectedOption(); + lua_pushlstring(l, selectedOption.c_str(), selectedOption.size()); + } + return 1; } - return 1; - } - static int l_attr_on_option_selected(lua_State *l) { - UI::List *list = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, list->onOptionSelected); - return 1; - } + static int l_attr_selected_index(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + if (list->IsEmpty()) { + lua_pushnil(l); + } else { + lua_pushinteger(l, list->GetSelectedIndex() + 1); + } + return 1; + } -}; + static int l_attr_on_option_selected(lua_State *l) + { + UI::List *list = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, list->onOptionSelected); + return 1; + } + }; -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.List"; +template <> +const char *LuaObject::s_type = "UI.List"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "AddOption", LuaList::l_add_option }, + { "AddOption", LuaList::l_add_option }, { "SetSelectedOption", LuaList::l_set_selected_option }, - { "SetSelectedIndex", LuaList::l_set_selected_index }, + { "SetSelectedIndex", LuaList::l_set_selected_index }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "selectedIndex", LuaList::l_attr_selected_index }, - { "selectedOption", LuaList::l_attr_selected_option }, + { "selectedIndex", LuaList::l_attr_selected_index }, + { "selectedOption", LuaList::l_attr_selected_option }, { "onOptionSelected", LuaList::l_attr_on_option_selected }, { 0, 0 } }; diff --git a/src/ui/LuaMargin.cpp b/src/ui/LuaMargin.cpp index 857245842..88406b0e6 100644 --- a/src/ui/LuaMargin.cpp +++ b/src/ui/LuaMargin.cpp @@ -1,23 +1,24 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Margin.h" #include "LuaObject.h" +#include "Margin.h" namespace UI { -class LuaMargin { -public: + class LuaMargin { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Margin"; +template <> +const char *LuaObject::s_type = "UI.Margin"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Single"; diff --git a/src/ui/LuaMultiLineText.cpp b/src/ui/LuaMultiLineText.cpp index f5aac6e42..28395b80c 100644 --- a/src/ui/LuaMultiLineText.cpp +++ b/src/ui/LuaMultiLineText.cpp @@ -1,41 +1,44 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "MultiLineText.h" #include "LuaObject.h" +#include "MultiLineText.h" namespace UI { -class LuaMultiLineText { -public: + class LuaMultiLineText { + public: + static int l_set_text(lua_State *l) + { + UI::MultiLineText *mlt = LuaObject::CheckFromLua(1); + const std::string text(luaL_checkstring(l, 2)); + mlt->SetText(text); + return 0; + } - static int l_set_text(lua_State *l) { - UI::MultiLineText *mlt = LuaObject::CheckFromLua(1); - const std::string text(luaL_checkstring(l, 2)); - mlt->SetText(text); - return 0; - } + static int l_append_text(lua_State *l) + { + UI::MultiLineText *mlt = LuaObject::CheckFromLua(1); + const std::string text(luaL_checkstring(l, 2)); + mlt->AppendText(text); + return 0; + } + }; - static int l_append_text(lua_State *l) { - UI::MultiLineText *mlt = LuaObject::CheckFromLua(1); - const std::string text(luaL_checkstring(l, 2)); - mlt->AppendText(text); - return 0; - } -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.MultiLineText"; +template <> +const char *LuaObject::s_type = "UI.MultiLineText"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; static const luaL_Reg l_methods[] = { - { "SetText", &LuaMultiLineText::l_set_text }, + { "SetText", &LuaMultiLineText::l_set_text }, { "AppendText", &LuaMultiLineText::l_append_text }, { 0, 0 } }; diff --git a/src/ui/LuaNumberLabel.cpp b/src/ui/LuaNumberLabel.cpp index 11689759d..661f8304a 100644 --- a/src/ui/LuaNumberLabel.cpp +++ b/src/ui/LuaNumberLabel.cpp @@ -1,30 +1,31 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "NumberLabel.h" #include "LuaObject.h" +#include "NumberLabel.h" namespace UI { -class LuaNumberLabel { -public: + class LuaNumberLabel { + public: + static int l_set_value(lua_State *l) + { + UI::NumberLabel *label = LuaObject::CheckFromLua(1); + double v = luaL_checknumber(l, 2); + label->SetValue(v); + return 0; + } + }; - static int l_set_value(lua_State *l) { - UI::NumberLabel *label = LuaObject::CheckFromLua(1); - double v = luaL_checknumber(l, 2); - label->SetValue(v); - return 0; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.NumberLabel"; +template <> +const char *LuaObject::s_type = "UI.NumberLabel"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Label"; diff --git a/src/ui/LuaOverlayStack.cpp b/src/ui/LuaOverlayStack.cpp index 194505ac9..7a092bd75 100644 --- a/src/ui/LuaOverlayStack.cpp +++ b/src/ui/LuaOverlayStack.cpp @@ -1,43 +1,46 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "OverlayStack.h" #include "Lua.h" +#include "OverlayStack.h" namespace UI { -class LuaOverlayStack { -public: + class LuaOverlayStack { + public: + static int l_add_layer(lua_State *l) + { + OverlayStack *s = LuaObject::CheckFromLua(1); + Context *c = s->GetContext(); + Widget *w = UI::Lua::CheckWidget(c, l, 2); + s->AddLayer(w); + lua_pushvalue(l, 1); + return 1; + } - static int l_add_layer(lua_State *l) { - OverlayStack *s = LuaObject::CheckFromLua(1); - Context *c = s->GetContext(); - Widget *w = UI::Lua::CheckWidget(c, l, 2); - s->AddLayer(w); - lua_pushvalue(l, 1); - return 1; - } + static int l_clear(lua_State *l) + { + OverlayStack *s = LuaObject::CheckFromLua(1); + s->Clear(); + return 0; + } + }; - static int l_clear(lua_State *l) { - OverlayStack *s = LuaObject::CheckFromLua(1); - s->Clear(); - return 0; - } -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.OverlayStack"; +template <> +const char *LuaObject::s_type = "UI.OverlayStack"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "AddLayer", LuaOverlayStack::l_add_layer }, - { "Clear", LuaOverlayStack::l_clear }, + { "AddLayer", LuaOverlayStack::l_add_layer }, + { "Clear", LuaOverlayStack::l_clear }, { 0, 0 } }; diff --git a/src/ui/LuaScroller.cpp b/src/ui/LuaScroller.cpp index ab68c076d..f94e2bb4b 100644 --- a/src/ui/LuaScroller.cpp +++ b/src/ui/LuaScroller.cpp @@ -1,49 +1,52 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Scroller.h" #include "Lua.h" +#include "Scroller.h" namespace UI { -class LuaScroller { -public: + class LuaScroller { + public: + static int l_set_inner_widget(lua_State *l) + { + Scroller *s = LuaObject::CheckFromLua(1); + Context *c = s->GetContext(); + Widget *w = UI::Lua::CheckWidget(c, l, 2); + s->SetInnerWidget(w); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_inner_widget(lua_State *l) { - Scroller *s = LuaObject::CheckFromLua(1); - Context *c = s->GetContext(); - Widget *w = UI::Lua::CheckWidget(c, l, 2); - s->SetInnerWidget(w); - lua_pushvalue(l, 1); - return 1; - } + static int l_remove_inner_widget(lua_State *l) + { + Scroller *s = LuaObject::CheckFromLua(1); + s->RemoveInnerWidget(); + return 0; + } - static int l_remove_inner_widget(lua_State *l) { - Scroller *s = LuaObject::CheckFromLua(1); - s->RemoveInnerWidget(); - return 0; - } + static int l_attr_inner_widget(lua_State *l) + { + Scroller *s = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(s->GetInnerWidget()); + return 1; + } + }; - static int l_attr_inner_widget(lua_State *l) { - Scroller *s = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(s->GetInnerWidget()); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Scroller"; +template <> +const char *LuaObject::s_type = "UI.Scroller"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "SetInnerWidget", LuaScroller::l_set_inner_widget }, + { "SetInnerWidget", LuaScroller::l_set_inner_widget }, { "RemoveInnerWidget", LuaScroller::l_remove_inner_widget }, { 0, 0 } }; diff --git a/src/ui/LuaSignal.h b/src/ui/LuaSignal.h index 3783f74af..66a210ccb 100644 --- a/src/ui/LuaSignal.h +++ b/src/ui/LuaSignal.h @@ -4,186 +4,200 @@ #ifndef UI_LUASIGNAL_H #define UI_LUASIGNAL_H +#include "Event.h" #include "LuaPushPull.h" +#include "Widget.h" -inline void pi_lua_generic_push(lua_State * l, const UI::Event &value) { value.ToLuaTable(l); } +inline void pi_lua_generic_push(lua_State *l, const UI::Event &value) { value.ToLuaTable(l); } namespace UI { -class LuaSignalTrampolineBase { -protected: - static inline void _trampoline_start(lua_State *l, int idx) { - lua_getfield(l, LUA_REGISTRYINDEX, "PiUISignal"); - assert(lua_istable(l, -1)); + class LuaSignalTrampolineBase { + protected: + static inline void _trampoline_start(lua_State *l, int idx) + { + lua_getfield(l, LUA_REGISTRYINDEX, "PiUISignal"); + assert(lua_istable(l, -1)); - lua_rawgeti(l, -1, idx); - assert(lua_isfunction(l, -1)); - } + lua_rawgeti(l, -1, idx); + assert(lua_isfunction(l, -1)); + } - static inline bool _trampoline_end(lua_State *l, int nargs) { - pi_lua_protected_call(l, nargs, 1); - bool ret = lua_toboolean(l, -1); - lua_pop(l, 2); - return ret; - } -}; + static inline bool _trampoline_end(lua_State *l, int nargs) + { + pi_lua_protected_call(l, nargs, 1); + bool ret = lua_toboolean(l, -1); + lua_pop(l, 2); + return ret; + } + }; -template -class LuaSignalTrampoline : public LuaSignalTrampolineBase { -public: - static inline bool trampoline(T0 arg0, T1 arg1, lua_State *l, int idx) { - _trampoline_start(l, idx); - pi_lua_generic_push(l, arg0); - pi_lua_generic_push(l, arg1); - return _trampoline_end(l, 2); - } + template + class LuaSignalTrampoline : public LuaSignalTrampolineBase { + public: + static inline bool trampoline(T0 arg0, T1 arg1, lua_State *l, int idx) + { + _trampoline_start(l, idx); + pi_lua_generic_push(l, arg0); + pi_lua_generic_push(l, arg1); + return _trampoline_end(l, 2); + } - static inline void trampoline_void(T0 arg0, T1 arg1, lua_State *l, int idx) { - trampoline(arg0, arg1, l, idx); - } -}; + static inline void trampoline_void(T0 arg0, T1 arg1, lua_State *l, int idx) + { + trampoline(arg0, arg1, l, idx); + } + }; -template -class LuaSignalTrampoline : public LuaSignalTrampolineBase { -public: - static inline bool trampoline(T0 arg0, lua_State *l, int idx) { - _trampoline_start(l, idx); - pi_lua_generic_push(l, arg0); - return _trampoline_end(l, 1); - } + template + class LuaSignalTrampoline : public LuaSignalTrampolineBase { + public: + static inline bool trampoline(T0 arg0, lua_State *l, int idx) + { + _trampoline_start(l, idx); + pi_lua_generic_push(l, arg0); + return _trampoline_end(l, 1); + } - static inline void trampoline_void(T0 arg0, lua_State *l, int idx) { - trampoline(arg0, l, idx); - } -}; + static inline void trampoline_void(T0 arg0, lua_State *l, int idx) + { + trampoline(arg0, l, idx); + } + }; -template <> -class LuaSignalTrampoline : public LuaSignalTrampolineBase { -public: - static inline bool trampoline(lua_State *l, int idx) { - _trampoline_start(l, idx); - return _trampoline_end(l, 0); - } + template <> + class LuaSignalTrampoline : public LuaSignalTrampolineBase { + public: + static inline bool trampoline(lua_State *l, int idx) + { + _trampoline_start(l, idx); + return _trampoline_end(l, 0); + } - static inline void trampoline_void(lua_State *l, int idx) { - trampoline(l, idx); - } -}; + static inline void trampoline_void(lua_State *l, int idx) + { + trampoline(l, idx); + } + }; -class LuaSignalBase { -protected: - static inline void *connect_base(lua_State *l, int &idx) { - luaL_checktype(l, 1, LUA_TTABLE); - luaL_checktype(l, 2, LUA_TFUNCTION); + class LuaSignalBase { + protected: + static inline void *connect_base(lua_State *l, int &idx) + { + luaL_checktype(l, 1, LUA_TTABLE); + luaL_checktype(l, 2, LUA_TFUNCTION); - lua_pushstring(l, "__signal"); - lua_rawget(l, 1); - if (!lua_islightuserdata(l, -1)) { - luaL_error(l, "signal pointer not found"); + lua_pushstring(l, "__signal"); + lua_rawget(l, 1); + if (!lua_islightuserdata(l, -1)) { + luaL_error(l, "signal pointer not found"); + return 0; + } + void *signal = lua_touserdata(l, -1); + lua_pop(l, 1); + + lua_getfield(l, LUA_REGISTRYINDEX, "PiUISignal"); + if (lua_isnil(l, -1)) { + lua_newtable(l); + lua_pushvalue(l, -1); + lua_setfield(l, LUA_REGISTRYINDEX, "PiUISignal"); + } + + idx = lua_rawlen(l, -1) + 1; + lua_pushvalue(l, 2); + lua_rawseti(l, -2, idx); + + return signal; + } + }; + + template + class LuaSignal : public LuaSignalBase { + public: + typedef typename sigc::signal signal_type; + + static inline int l_connect(lua_State *l) + { + int idx; + if (signal_type *signal = static_cast(connect_base(l, idx))) + signal->connect(sigc::bind(sigc::ptr_fun(&LuaSignalTrampoline::trampoline_void), l, idx)); return 0; } - void *signal = lua_touserdata(l, -1); - lua_pop(l, 1); - lua_getfield(l, LUA_REGISTRYINDEX, "PiUISignal"); - if (lua_isnil(l, -1)) { + inline void Wrap(lua_State *l, signal_type &signal) + { lua_newtable(l); - lua_pushvalue(l, -1); - lua_setfield(l, LUA_REGISTRYINDEX, "PiUISignal"); + + lua_pushstring(l, "Connect"); + lua_pushcfunction(l, l_connect); + lua_rawset(l, -3); + + lua_pushstring(l, "__signal"); + lua_pushlightuserdata(l, &signal); + lua_rawset(l, -3); + } + }; + + template + class LuaSignalAccumulated : public LuaSignalBase { + public: + typedef typename sigc::signal::template accumulated signal_type; + + static inline int l_connect(lua_State *l) + { + int idx; + if (signal_type *signal = static_cast(connect_base(l, idx))) + signal->connect(sigc::bind(sigc::ptr_fun(&LuaSignalTrampoline::trampoline), l, idx)); + return 0; } - idx = lua_rawlen(l, -1)+1; - lua_pushvalue(l, 2); - lua_rawseti(l, -2, idx); + inline void Wrap(lua_State *l, signal_type &signal) + { + lua_newtable(l); - return signal; - } -}; + lua_pushstring(l, "Connect"); + lua_pushcfunction(l, l_connect); + lua_rawset(l, -3); -template -class LuaSignal : public LuaSignalBase { -public: + lua_pushstring(l, "__signal"); + lua_pushlightuserdata(l, &signal); + lua_rawset(l, -3); + } + }; - typedef typename sigc::signal signal_type; - - static inline int l_connect(lua_State *l) { - int idx; - if (signal_type *signal = static_cast(connect_base(l, idx))) - signal->connect(sigc::bind(sigc::ptr_fun(&LuaSignalTrampoline::trampoline_void), l, idx)); - return 0; - } - - inline void Wrap(lua_State *l, signal_type &signal) { - lua_newtable(l); - - lua_pushstring(l, "Connect"); - lua_pushcfunction(l, l_connect); - lua_rawset(l, -3); - - lua_pushstring(l, "__signal"); - lua_pushlightuserdata(l, &signal); - lua_rawset(l, -3); - } -}; - -template -class LuaSignalAccumulated : public LuaSignalBase { -public: - - typedef typename sigc::signal::template accumulated signal_type; - - static inline int l_connect(lua_State *l) { - int idx; - if (signal_type *signal = static_cast(connect_base(l, idx))) - signal->connect(sigc::bind(sigc::ptr_fun(&LuaSignalTrampoline::trampoline), l, idx)); - return 0; - } - - inline void Wrap(lua_State *l, signal_type &signal) { - lua_newtable(l); - - lua_pushstring(l, "Connect"); - lua_pushcfunction(l, l_connect); - lua_rawset(l, -3); - - lua_pushstring(l, "__signal"); - lua_pushlightuserdata(l, &signal); - lua_rawset(l, -3); - } -}; - - -class LuaSlot { -public: - static inline sigc::slot Wrap(lua_State *l, int idx) { - LUA_DEBUG_START(l); - idx = lua_absindex(l, idx); - lua_getfield(l, LUA_REGISTRYINDEX, "PiUISlot"); - if (lua_isnil(l, -1)) { + class LuaSlot { + public: + static inline sigc::slot Wrap(lua_State *l, int idx) + { + LUA_DEBUG_START(l); + idx = lua_absindex(l, idx); + lua_getfield(l, LUA_REGISTRYINDEX, "PiUISlot"); + if (lua_isnil(l, -1)) { + lua_pop(l, 1); + lua_newtable(l); + lua_pushvalue(l, -1); + lua_setfield(l, LUA_REGISTRYINDEX, "PiUISlot"); + } + lua_pushvalue(l, idx); + int ref = luaL_ref(l, -2); lua_pop(l, 1); - lua_newtable(l); - lua_pushvalue(l, -1); - lua_setfield(l, LUA_REGISTRYINDEX, "PiUISlot"); + LUA_DEBUG_END(l, 0); + return sigc::bind(sigc::ptr_fun(&trampoline), l, ref); } - lua_pushvalue(l, idx); - int ref = luaL_ref(l, -2); - lua_pop(l, 1); - LUA_DEBUG_END(l, 0); - return sigc::bind(sigc::ptr_fun(&trampoline), l, ref); - } -private: - static inline void trampoline(lua_State *l, int ref) { - LUA_DEBUG_START(l); - lua_getfield(l, LUA_REGISTRYINDEX, "PiUISlot"); - lua_rawgeti(l, -1, ref); - luaL_unref(l, -2, ref); - lua_call(l, 0, 0); - lua_pop(l, 1); - LUA_DEBUG_END(l, 0); - } -}; + private: + static inline void trampoline(lua_State *l, int ref) + { + LUA_DEBUG_START(l); + lua_getfield(l, LUA_REGISTRYINDEX, "PiUISlot"); + lua_rawgeti(l, -1, ref); + luaL_unref(l, -2, ref); + lua_call(l, 0, 0); + lua_pop(l, 1); + LUA_DEBUG_END(l, 0); + } + }; -} +} // namespace UI #endif diff --git a/src/ui/LuaSingle.cpp b/src/ui/LuaSingle.cpp index dc78821f0..89e9bbf14 100644 --- a/src/ui/LuaSingle.cpp +++ b/src/ui/LuaSingle.cpp @@ -1,48 +1,52 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Single.h" #include "Lua.h" +#include "Single.h" namespace UI { -class LuaSingle { -public: + class LuaSingle { + public: + static int l_set_inner_widget(lua_State *l) + { + Single *s = LuaObject::CheckFromLua(1); + Context *c = s->GetContext(); + Widget *w = UI::Lua::CheckWidget(c, l, 2); + s->SetInnerWidget(w); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_inner_widget(lua_State *l) { - Single *s = LuaObject::CheckFromLua(1); - Context *c = s->GetContext(); - Widget *w = UI::Lua::CheckWidget(c, l, 2); - s->SetInnerWidget(w); - lua_pushvalue(l, 1); - return 1; - } + static int l_remove_inner_widget(lua_State *l) + { + Single *s = LuaObject::CheckFromLua(1); + s->RemoveInnerWidget(); + return 0; + } - static int l_remove_inner_widget(lua_State *l) { - Single *s = LuaObject::CheckFromLua(1); - s->RemoveInnerWidget(); - return 0; - } + static int l_attr_inner_widget(lua_State *l) + { + Single *s = LuaObject::CheckFromLua(1); + LuaObject::PushToLua(s->GetInnerWidget()); + return 1; + } + }; - static int l_attr_inner_widget(lua_State *l) { - Single *s = LuaObject::CheckFromLua(1); - LuaObject::PushToLua(s->GetInnerWidget()); - return 1; - } -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Single"; +template <> +const char *LuaObject::s_type = "UI.Single"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "SetInnerWidget", LuaSingle::l_set_inner_widget }, + { "SetInnerWidget", LuaSingle::l_set_inner_widget }, { "RemoveInnerWidget", LuaSingle::l_remove_inner_widget }, { 0, 0 } }; diff --git a/src/ui/LuaSlider.cpp b/src/ui/LuaSlider.cpp index 7f5969e2a..6ac3ba7fb 100644 --- a/src/ui/LuaSlider.cpp +++ b/src/ui/LuaSlider.cpp @@ -1,68 +1,73 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Slider.h" #include "LuaObject.h" #include "LuaSignal.h" +#include "Slider.h" namespace UI { -class LuaSlider { -public: - - static int l_set_range(lua_State *l) { - UI::Slider *slider = LuaObject::CheckFromLua(1); - const float min = luaL_checknumber(l, 2); - const float max = luaL_checknumber(l, 3); - if (min >= max) { - return luaL_error(l, "Slider range minimum must be strictly less than the maximum"); + class LuaSlider { + public: + static int l_set_range(lua_State *l) + { + UI::Slider *slider = LuaObject::CheckFromLua(1); + const float min = luaL_checknumber(l, 2); + const float max = luaL_checknumber(l, 3); + if (min >= max) { + return luaL_error(l, "Slider range minimum must be strictly less than the maximum"); + } + slider->SetRange(min, max); + lua_settop(l, 1); + return 1; } - slider->SetRange(min, max); - lua_settop(l, 1); - return 1; - } - static int l_get_range(lua_State *l) { - UI::Slider *slider = LuaObject::CheckFromLua(1); - float min, max; - slider->GetRange(min, max); - lua_pushnumber(l, min); - lua_pushnumber(l, max); - return 2; - } + static int l_get_range(lua_State *l) + { + UI::Slider *slider = LuaObject::CheckFromLua(1); + float min, max; + slider->GetRange(min, max); + lua_pushnumber(l, min); + lua_pushnumber(l, max); + return 2; + } - static int l_set_value(lua_State *l) { - UI::Slider *slider = LuaObject::CheckFromLua(1); - const float v = luaL_checknumber(l, 2); - slider->SetValue(v); - lua_settop(l, 1); - return 1; - } + static int l_set_value(lua_State *l) + { + UI::Slider *slider = LuaObject::CheckFromLua(1); + const float v = luaL_checknumber(l, 2); + slider->SetValue(v); + lua_settop(l, 1); + return 1; + } - static int l_get_value(lua_State *l) { - UI::Slider *slider = LuaObject::CheckFromLua(1); - lua_pushnumber(l, slider->GetValue()); - return 1; - } + static int l_get_value(lua_State *l) + { + UI::Slider *slider = LuaObject::CheckFromLua(1); + lua_pushnumber(l, slider->GetValue()); + return 1; + } - static int l_attr_on_value_changed(lua_State *l) { - UI::Slider *slider = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, slider->onValueChanged); - return 1; - } + static int l_attr_on_value_changed(lua_State *l) + { + UI::Slider *slider = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, slider->onValueChanged); + return 1; + } + }; -}; + class LuaHSlider; + class LuaVSlider; -class LuaHSlider; -class LuaVSlider; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Slider"; +template <> +const char *LuaObject::s_type = "UI.Slider"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; @@ -76,7 +81,7 @@ template <> void LuaObject::RegisterClass() }; static const luaL_Reg l_attrs[] = { - { "onValueChanged", LuaSlider::l_attr_on_value_changed }, + { "onValueChanged", LuaSlider::l_attr_on_value_changed }, { 0, 0 } }; @@ -85,9 +90,11 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterPromotion(l_parent, s_type, LuaObject::DynamicCastPromotionTest); } -template <> const char *LuaObject::s_type = "UI.HSlider"; +template <> +const char *LuaObject::s_type = "UI.HSlider"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Slider"; @@ -95,9 +102,11 @@ template <> void LuaObject::RegisterClass() LuaObjectBase::RegisterPromotion(l_parent, s_type, LuaObject::DynamicCastPromotionTest); } -template <> const char *LuaObject::s_type = "UI.VSlider"; +template <> +const char *LuaObject::s_type = "UI.VSlider"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Slider"; diff --git a/src/ui/LuaSmallButton.cpp b/src/ui/LuaSmallButton.cpp index c7d613ee1..785357373 100644 --- a/src/ui/LuaSmallButton.cpp +++ b/src/ui/LuaSmallButton.cpp @@ -1,23 +1,24 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "SmallButton.h" #include "LuaObject.h" +#include "SmallButton.h" namespace UI { -class LuaSmallButton { -public: + class LuaSmallButton { + public: + }; -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.SmallButton"; +template <> +const char *LuaObject::s_type = "UI.SmallButton"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; diff --git a/src/ui/LuaTable.cpp b/src/ui/LuaTable.cpp index a01d6b953..9112f6ffa 100644 --- a/src/ui/LuaTable.cpp +++ b/src/ui/LuaTable.cpp @@ -1,190 +1,202 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Table.h" #include "Lua.h" #include "LuaConstants.h" #include "LuaSignal.h" +#include "Table.h" namespace UI { -class LuaTable { -public: + class LuaTable { + public: + static int l_set_heading_row(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + UI::Context *c = t->GetContext(); - static int l_set_heading_row(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - UI::Context *c = t->GetContext(); + std::vector widgets; - std::vector widgets; + if (lua_istable(l, 2)) { + UI::Widget *w = UI::Lua::GetWidget(c, l, 2); + if (w) + widgets.push_back(w); + else + for (size_t i = 0; i < lua_rawlen(l, 2); i++) { + lua_rawgeti(l, 2, i + 1); + widgets.push_back(UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + } else + widgets.push_back(UI::Lua::CheckWidget(c, l, 2)); - if (lua_istable(l, 2)) { - UI::Widget *w = UI::Lua::GetWidget(c, l, 2); - if (w) - widgets.push_back(w); - else - for (size_t i = 0; i < lua_rawlen(l, 2); i++) { - lua_rawgeti(l, 2, i+1); - widgets.push_back(UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } - } - else - widgets.push_back(UI::Lua::CheckWidget(c, l, 2)); + t->SetHeadingRow(WidgetSet(widgets)); - t->SetHeadingRow(WidgetSet(widgets)); - - lua_pushvalue(l, 1); - return 1; - } - - static void _add_row(Table *t, lua_State *l, int idx) { - idx = lua_absindex(l, idx); - - UI::Context *c = t->GetContext(); - - std::vector widgets; - - if (lua_istable(l, idx)) { - UI::Widget *w = UI::Lua::GetWidget(c, l, idx); - if (w) - widgets.push_back(w); - else - for (size_t i = 0; i < lua_rawlen(l, idx); i++) { - lua_rawgeti(l, idx, i+1); - widgets.push_back(UI::Lua::CheckWidget(c, l, -1)); - lua_pop(l, 1); - } - } - else - widgets.push_back(UI::Lua::CheckWidget(c, l, idx)); - - t->AddRow(WidgetSet(widgets)); - } - - static int l_add_row(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - _add_row(t, l, 2); - lua_pushvalue(l, 1); - return 1; - } - - static int l_add_rows(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - - luaL_checktype(l, 2, LUA_TTABLE); - - lua_pushnil(l); - while (lua_next(l, 2)) { - _add_row(t, l, -1); - lua_pop(l, 1); + lua_pushvalue(l, 1); + return 1; } - lua_pushvalue(l, 1); - return 1; - } + static void _add_row(Table *t, lua_State *l, int idx) + { + idx = lua_absindex(l, idx); - static int l_clear_rows(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - t->ClearRows(); - return 0; - } + UI::Context *c = t->GetContext(); - static int l_set_row_spacing(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - int spacing = luaL_checkinteger(l, 2); - t->SetRowSpacing(spacing); - lua_pushvalue(l, 1); - return 1; - } + std::vector widgets; - static int l_set_column_spacing(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - int spacing = luaL_checkinteger(l, 2); - t->SetColumnSpacing(spacing); - lua_pushvalue(l, 1); - return 1; - } + if (lua_istable(l, idx)) { + UI::Widget *w = UI::Lua::GetWidget(c, l, idx); + if (w) + widgets.push_back(w); + else + for (size_t i = 0; i < lua_rawlen(l, idx); i++) { + lua_rawgeti(l, idx, i + 1); + widgets.push_back(UI::Lua::CheckWidget(c, l, -1)); + lua_pop(l, 1); + } + } else + widgets.push_back(UI::Lua::CheckWidget(c, l, idx)); - static int l_set_row_alignment(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - UI::Table::RowAlignDirection dir = static_cast(LuaConstants::GetConstantFromArg(l, "UITableRowAlignDirection", 2)); - t->SetRowAlignment(dir); - lua_pushvalue(l, 1); - return 1; - } + t->AddRow(WidgetSet(widgets)); + } - static int l_set_column_alignment(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - UI::Table::ColumnAlignDirection dir = static_cast(LuaConstants::GetConstantFromArg(l, "UITableColumnAlignDirection", 2)); - t->SetColumnAlignment(dir); - lua_pushvalue(l, 1); - return 1; - } + static int l_add_row(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + _add_row(t, l, 2); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_heading_font(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - UI::Widget::Font font = static_cast(LuaConstants::GetConstantFromArg(l, "UIFont", 2)); - t->SetHeadingFont(font); - lua_pushvalue(l, 1); - return 1; - } + static int l_add_rows(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); - static int l_set_mouse_enabled(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - bool enabled = lua_toboolean(l, 2); - t->SetMouseEnabled(enabled); - lua_pushvalue(l, 1); - return 1; - } + luaL_checktype(l, 2, LUA_TTABLE); - static int l_attr_table_on_row_clicked(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, t->onRowClicked); - return 1; - } + lua_pushnil(l); + while (lua_next(l, 2)) { + _add_row(t, l, -1); + lua_pop(l, 1); + } - static int l_scroll_to_top(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - t->SetScrollPosition(0.0f); - return 0; - } + lua_pushvalue(l, 1); + return 1; + } - static int l_scroll_to_bottom(lua_State *l) { - UI::Table *t = LuaObject::CheckFromLua(1); - t->SetScrollPosition(1.0f); - return 0; - } + static int l_clear_rows(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + t->ClearRows(); + return 0; + } -}; + static int l_set_row_spacing(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + int spacing = luaL_checkinteger(l, 2); + t->SetRowSpacing(spacing); + lua_pushvalue(l, 1); + return 1; + } -} + static int l_set_column_spacing(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + int spacing = luaL_checkinteger(l, 2); + t->SetColumnSpacing(spacing); + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_row_alignment(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + UI::Table::RowAlignDirection dir = static_cast(LuaConstants::GetConstantFromArg(l, "UITableRowAlignDirection", 2)); + t->SetRowAlignment(dir); + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_column_alignment(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + UI::Table::ColumnAlignDirection dir = static_cast(LuaConstants::GetConstantFromArg(l, "UITableColumnAlignDirection", 2)); + t->SetColumnAlignment(dir); + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_heading_font(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + UI::Widget::Font font = static_cast(LuaConstants::GetConstantFromArg(l, "UIFont", 2)); + t->SetHeadingFont(font); + lua_pushvalue(l, 1); + return 1; + } + + static int l_set_mouse_enabled(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + bool enabled = lua_toboolean(l, 2); + t->SetMouseEnabled(enabled); + lua_pushvalue(l, 1); + return 1; + } + + static int l_attr_table_on_row_clicked(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, t->onRowClicked); + return 1; + } + + static int l_scroll_to_top(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + t->SetScrollPosition(0.0f); + return 0; + } + + static int l_scroll_to_bottom(lua_State *l) + { + UI::Table *t = LuaObject::CheckFromLua(1); + t->SetScrollPosition(1.0f); + return 0; + } + }; + +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Table"; +template <> +const char *LuaObject::s_type = "UI.Table"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Container"; static const luaL_Reg l_methods[] = { - { "SetHeadingRow", UI::LuaTable::l_set_heading_row }, - { "AddRow", UI::LuaTable::l_add_row }, - { "AddRows", UI::LuaTable::l_add_rows }, - { "ClearRows", UI::LuaTable::l_clear_rows }, - { "SetRowSpacing", UI::LuaTable::l_set_row_spacing }, - { "SetColumnSpacing", UI::LuaTable::l_set_column_spacing }, - { "SetRowAlignment", UI::LuaTable::l_set_row_alignment }, + { "SetHeadingRow", UI::LuaTable::l_set_heading_row }, + { "AddRow", UI::LuaTable::l_add_row }, + { "AddRows", UI::LuaTable::l_add_rows }, + { "ClearRows", UI::LuaTable::l_clear_rows }, + { "SetRowSpacing", UI::LuaTable::l_set_row_spacing }, + { "SetColumnSpacing", UI::LuaTable::l_set_column_spacing }, + { "SetRowAlignment", UI::LuaTable::l_set_row_alignment }, { "SetColumnAlignment", UI::LuaTable::l_set_column_alignment }, - { "SetHeadingFont", UI::LuaTable::l_set_heading_font }, - { "SetMouseEnabled", UI::LuaTable::l_set_mouse_enabled }, - { "ScrollToTop", UI::LuaTable::l_scroll_to_top }, - { "ScrollToBottom", UI::LuaTable::l_scroll_to_bottom }, + { "SetHeadingFont", UI::LuaTable::l_set_heading_font }, + { "SetMouseEnabled", UI::LuaTable::l_set_mouse_enabled }, + { "ScrollToTop", UI::LuaTable::l_scroll_to_top }, + { "ScrollToBottom", UI::LuaTable::l_scroll_to_bottom }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "onRowClicked", UI::LuaTable::l_attr_table_on_row_clicked }, + { "onRowClicked", UI::LuaTable::l_attr_table_on_row_clicked }, { 0, 0 } }; diff --git a/src/ui/LuaTextEntry.cpp b/src/ui/LuaTextEntry.cpp index 74b9e7f72..51bb7cfb4 100644 --- a/src/ui/LuaTextEntry.cpp +++ b/src/ui/LuaTextEntry.cpp @@ -1,66 +1,69 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "TextEntry.h" #include "LuaObject.h" -#include "LuaSignal.h" #include "LuaPushPull.h" +#include "LuaSignal.h" +#include "TextEntry.h" namespace UI { -class LuaTextEntry { -public: + class LuaTextEntry { + public: + static int l_set_text(lua_State *l) + { + TextEntry *te = LuaObject::CheckFromLua(1); + std::string new_text; + pi_lua_generic_pull(l, 2, new_text); + te->SetText(new_text); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_text(lua_State *l) - { - TextEntry *te = LuaObject::CheckFromLua(1); - std::string new_text; - pi_lua_generic_pull(l, 2, new_text); - te->SetText(new_text); - lua_pushvalue(l, 1); - return 1; - } + static int l_attr_text(lua_State *l) + { + TextEntry *te = LuaObject::CheckFromLua(1); + const std::string &text(te->GetText()); + lua_pushlstring(l, text.c_str(), text.size()); + return 1; + } - static int l_attr_text(lua_State *l) - { - TextEntry *te = LuaObject::CheckFromLua(1); - const std::string &text(te->GetText()); - lua_pushlstring(l, text.c_str(), text.size()); - return 1; - } + static int l_attr_on_change(lua_State *l) + { + UI::TextEntry *te = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, te->onChange); + return 1; + } - static int l_attr_on_change(lua_State *l) { - UI::TextEntry *te = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, te->onChange); - return 1; - } + static int l_attr_on_enter(lua_State *l) + { + UI::TextEntry *te = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, te->onEnter); + return 1; + } + }; - static int l_attr_on_enter(lua_State *l) { - UI::TextEntry *te = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, te->onEnter); - return 1; - } -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.TextEntry"; +template <> +const char *LuaObject::s_type = "UI.TextEntry"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const char *l_parent = "UI.Widget"; static const luaL_Reg l_methods[] = { - { "SetText", LuaTextEntry::l_set_text }, + { "SetText", LuaTextEntry::l_set_text }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { - { "text", LuaTextEntry::l_attr_text }, + { "text", LuaTextEntry::l_attr_text }, { "onChange", LuaTextEntry::l_attr_on_change }, - { "onEnter", LuaTextEntry::l_attr_on_enter }, + { "onEnter", LuaTextEntry::l_attr_on_enter }, { 0, 0 } }; diff --git a/src/ui/LuaWidget.cpp b/src/ui/LuaWidget.cpp index e3e785c2a..ee4fd7492 100644 --- a/src/ui/LuaWidget.cpp +++ b/src/ui/LuaWidget.cpp @@ -1,169 +1,186 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include "Widget.h" -#include "LuaObject.h" #include "LuaConstants.h" +#include "LuaObject.h" #include "LuaSignal.h" +#include "Widget.h" namespace UI { -class LuaWidget { -public: + class LuaWidget { + public: + static int l_set_font_size(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + UI::Widget::Font font = static_cast(LuaConstants::GetConstantFromArg(l, "UIFont", 2)); + w->SetFont(font); + lua_pushvalue(l, 1); + return 1; + } - static int l_set_font_size(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - UI::Widget::Font font = static_cast(LuaConstants::GetConstantFromArg(l, "UIFont", 2)); - w->SetFont(font); - lua_pushvalue(l, 1); - return 1; - } + static int l_disable(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + w->Disable(); + return 0; + } - static int l_disable(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - w->Disable(); - return 0; - } + static int l_hide(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + w->Hidden(); + return 0; + } - static int l_hide(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - w->Hidden(); - return 0; - } + static int l_enable(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + w->Enable(); + return 0; + } - static int l_enable(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - w->Enable(); - return 0; - } + static int l_add_shortcut(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + w->AddShortcut(UI::KeySym::FromString(luaL_checkstring(l, 2))); + return 0; + } + static int l_remove_shortcut(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + w->RemoveShortcut(UI::KeySym::FromString(luaL_checkstring(l, 2))); + return 0; + } - static int l_add_shortcut(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - w->AddShortcut(UI::KeySym::FromString(luaL_checkstring(l, 2))); - return 0; - } + static int l_bind(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + const std::string bindName(luaL_checkstring(l, 2)); + PropertiedObject *po = LuaObject::CheckFromLua(3); + const std::string propertyName(luaL_checkstring(l, 4)); + w->Bind(bindName, po, propertyName); + return 0; + } - static int l_remove_shortcut(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - w->RemoveShortcut(UI::KeySym::FromString(luaL_checkstring(l, 2))); - return 0; - } + static int l_attr_disabled(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + lua_pushboolean(l, w->IsDisabled()); + return 1; + } + static int l_attr_width(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + lua_pushnumber(l, w->GetSize().x); + return 1; + } - static int l_bind(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - const std::string bindName(luaL_checkstring(l, 2)); - PropertiedObject *po = LuaObject::CheckFromLua(3); - const std::string propertyName(luaL_checkstring(l, 4)); - w->Bind(bindName, po, propertyName); - return 0; - } + static int l_attr_height(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + lua_pushnumber(l, w->GetSize().y); + return 1; + } + static int l_attr_on_key_down(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onKeyDown); + return 1; + } - static int l_attr_disabled(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - lua_pushboolean(l, w->IsDisabled()); - return 1; - } + static int l_attr_on_key_up(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onKeyUp); + return 1; + } - static int l_attr_width(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - lua_pushnumber(l, w->GetSize().x); - return 1; - } + static int l_attr_on_text_input(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onTextInput); + return 1; + } - static int l_attr_height(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - lua_pushnumber(l, w->GetSize().y); - return 1; - } + static int l_attr_on_mouse_down(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onMouseDown); + return 1; + } + static int l_attr_on_mouse_up(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onMouseUp); + return 1; + } - static int l_attr_on_key_down(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onKeyDown); - return 1; - } + static int l_attr_on_mouse_move(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onMouseMove); + return 1; + } - static int l_attr_on_key_up(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onKeyUp); - return 1; - } + static int l_attr_on_mouse_wheel(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated().Wrap(l, w->onMouseWheel); + return 1; + } - static int l_attr_on_text_input(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onTextInput); - return 1; - } + static int l_attr_on_mouse_over(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated<>().Wrap(l, w->onMouseOver); + return 1; + } - static int l_attr_on_mouse_down(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onMouseDown); - return 1; - } + static int l_attr_on_mouse_out(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated<>().Wrap(l, w->onMouseOut); + return 1; + } - static int l_attr_on_mouse_up(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onMouseUp); - return 1; - } + static int l_attr_on_click(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignalAccumulated<>().Wrap(l, w->onClick); + return 1; + } - static int l_attr_on_mouse_move(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onMouseMove); - return 1; - } + static int l_attr_on_visibility_changed(lua_State *l) + { + UI::Widget *w = LuaObject::CheckFromLua(1); + LuaSignal().Wrap(l, w->onVisibilityChanged); + return 1; + } + }; - static int l_attr_on_mouse_wheel(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated().Wrap(l, w->onMouseWheel); - return 1; - } - - static int l_attr_on_mouse_over(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated<>().Wrap(l, w->onMouseOver); - return 1; - } - - static int l_attr_on_mouse_out(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated<>().Wrap(l, w->onMouseOut); - return 1; - } - - static int l_attr_on_click(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignalAccumulated<>().Wrap(l, w->onClick); - return 1; - } - - static int l_attr_on_visibility_changed(lua_State *l) { - UI::Widget *w = LuaObject::CheckFromLua(1); - LuaSignal().Wrap(l, w->onVisibilityChanged); - return 1; - } - -}; - -} +} // namespace UI using namespace UI; -template <> const char *LuaObject::s_type = "UI.Widget"; +template <> +const char *LuaObject::s_type = "UI.Widget"; -template <> void LuaObject::RegisterClass() +template <> +void LuaObject::RegisterClass() { static const luaL_Reg l_methods[] = { { "SetFont", LuaWidget::l_set_font_size }, - { "Disable", LuaWidget::l_disable }, - { "Hide", LuaWidget::l_hide }, - { "Enable", LuaWidget::l_enable }, + { "Disable", LuaWidget::l_disable }, + { "Hide", LuaWidget::l_hide }, + { "Enable", LuaWidget::l_enable }, - { "AddShortcut", LuaWidget::l_add_shortcut }, + { "AddShortcut", LuaWidget::l_add_shortcut }, { "RemoveShortcut", LuaWidget::l_remove_shortcut }, { "Bind", LuaWidget::l_bind }, @@ -172,20 +189,20 @@ template <> void LuaObject::RegisterClass() }; static const luaL_Reg l_attrs[] = { - { "disabled", LuaWidget::l_attr_disabled }, - { "width", LuaWidget::l_attr_width }, - { "height", LuaWidget::l_attr_height }, + { "disabled", LuaWidget::l_attr_disabled }, + { "width", LuaWidget::l_attr_width }, + { "height", LuaWidget::l_attr_height }, - { "onKeyDown", LuaWidget::l_attr_on_key_down }, - { "onKeyUp", LuaWidget::l_attr_on_key_up }, - { "onTextInput", LuaWidget::l_attr_on_text_input }, - { "onMouseDown", LuaWidget::l_attr_on_mouse_down }, - { "onMouseUp", LuaWidget::l_attr_on_mouse_up }, - { "onMouseMove", LuaWidget::l_attr_on_mouse_move }, - { "onMouseWheel", LuaWidget::l_attr_on_mouse_wheel }, - { "onMouseOver", LuaWidget::l_attr_on_mouse_over }, - { "onMouseOut", LuaWidget::l_attr_on_mouse_out }, - { "onClick", LuaWidget::l_attr_on_click }, + { "onKeyDown", LuaWidget::l_attr_on_key_down }, + { "onKeyUp", LuaWidget::l_attr_on_key_up }, + { "onTextInput", LuaWidget::l_attr_on_text_input }, + { "onMouseDown", LuaWidget::l_attr_on_mouse_down }, + { "onMouseUp", LuaWidget::l_attr_on_mouse_up }, + { "onMouseMove", LuaWidget::l_attr_on_mouse_move }, + { "onMouseWheel", LuaWidget::l_attr_on_mouse_wheel }, + { "onMouseOver", LuaWidget::l_attr_on_mouse_over }, + { "onMouseOut", LuaWidget::l_attr_on_mouse_out }, + { "onClick", LuaWidget::l_attr_on_click }, { "onVisibilityChanged", LuaWidget::l_attr_on_visibility_changed }, { 0, 0 } diff --git a/src/ui/Margin.cpp b/src/ui/Margin.cpp index 2a8f1f1f7..1df43817f 100644 --- a/src/ui/Margin.cpp +++ b/src/ui/Margin.cpp @@ -6,84 +6,85 @@ namespace UI { -Margin::Margin(Context *context, int margin, Direction direction): - Single(context), - m_margin(context->GetScale() * margin), - m_direction(direction) -{} + Margin::Margin(Context *context, int margin, Direction direction) : + Single(context), + m_margin(context->GetScale() * margin), + m_direction(direction) + {} -Point Margin::PreferredSize() -{ - Point extra; - switch (m_direction) { + Point Margin::PreferredSize() + { + Point extra; + switch (m_direction) { case ALL: - extra = Point(m_margin*2, m_margin*2); + extra = Point(m_margin * 2, m_margin * 2); break; case HORIZONTAL: - extra = Point(m_margin*2, 0); + extra = Point(m_margin * 2, 0); break; case VERTICAL: - extra = Point(0, m_margin*2); + extra = Point(0, m_margin * 2); break; - case LEFT: case RIGHT: + case LEFT: + case RIGHT: extra = Point(m_margin, 0); break; - case TOP: case BOTTOM: + case TOP: + case BOTTOM: extra = Point(0, m_margin); break; + } + if (!GetInnerWidget()) return extra; + return SizeAdd(GetInnerWidget()->CalcLayoutContribution(), extra); } - if (!GetInnerWidget()) return extra; - return SizeAdd(GetInnerWidget()->CalcLayoutContribution(), extra); -} -void Margin::Layout() -{ - if (!GetInnerWidget()) return; + void Margin::Layout() + { + if (!GetInnerWidget()) return; - const Point &size = GetSize(); + const Point &size = GetSize(); - Point innerPos, innerSize; - switch (m_direction) { + Point innerPos, innerSize; + switch (m_direction) { case ALL: innerPos = Point(m_margin); - innerSize = Point(std::max(size.x-m_margin*2,0), std::max(size.y-m_margin*2,0)); + innerSize = Point(std::max(size.x - m_margin * 2, 0), std::max(size.y - m_margin * 2, 0)); break; case HORIZONTAL: - innerPos = Point(m_margin,0); - innerSize = Point(std::max(size.x-m_margin*2,0), size.y); + innerPos = Point(m_margin, 0); + innerSize = Point(std::max(size.x - m_margin * 2, 0), size.y); break; case VERTICAL: - innerPos = Point(0,m_margin); - innerSize = Point(size.x, std::max(size.y-m_margin*2,0)); + innerPos = Point(0, m_margin); + innerSize = Point(size.x, std::max(size.y - m_margin * 2, 0)); break; case LEFT: - innerPos = Point(m_margin,0); - innerSize = Point(std::max(size.x-m_margin,0), size.y); + innerPos = Point(m_margin, 0); + innerSize = Point(std::max(size.x - m_margin, 0), size.y); break; case RIGHT: - innerPos = Point(0,0); - innerSize = Point(std::max(size.x-m_margin,0), size.y); + innerPos = Point(0, 0); + innerSize = Point(std::max(size.x - m_margin, 0), size.y); break; case TOP: - innerPos = Point(0,m_margin); - innerSize = Point(size.x, std::max(size.y-m_margin,0)); + innerPos = Point(0, m_margin); + innerSize = Point(size.x, std::max(size.y - m_margin, 0)); break; case BOTTOM: - innerPos = Point(0,0); - innerSize = Point(size.x, std::max(size.y-m_margin,0)); + innerPos = Point(0, 0); + innerSize = Point(size.x, std::max(size.y - m_margin, 0)); break; + } + + SetWidgetDimensions(GetInnerWidget(), innerPos, GetInnerWidget()->CalcSize(innerSize)); + + GetInnerWidget()->Layout(); } - - SetWidgetDimensions(GetInnerWidget(), innerPos, GetInnerWidget()->CalcSize(innerSize)); - - GetInnerWidget()->Layout(); -} - -} +} // namespace UI diff --git a/src/ui/Margin.h b/src/ui/Margin.h index 41c8e689e..977bcce1f 100644 --- a/src/ui/Margin.h +++ b/src/ui/Margin.h @@ -8,30 +8,30 @@ namespace UI { -class Margin : public Single { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class Margin : public Single { + public: + virtual Point PreferredSize(); + virtual void Layout(); - enum Direction { // - ALL, - HORIZONTAL, - VERTICAL, - LEFT, - RIGHT, - TOP, - BOTTOM + enum Direction { // + ALL, + HORIZONTAL, + VERTICAL, + LEFT, + RIGHT, + TOP, + BOTTOM + }; + + protected: + friend class Context; + Margin(Context *context, int margin, Direction direction); + + private: + int m_margin; + Direction m_direction; }; -protected: - friend class Context; - Margin(Context *context, int margin, Direction direction); - -private: - int m_margin; - Direction m_direction; -}; - -} +} // namespace UI #endif diff --git a/src/ui/MousePointer.h b/src/ui/MousePointer.h index 024d963a6..c4a869871 100644 --- a/src/ui/MousePointer.h +++ b/src/ui/MousePointer.h @@ -8,21 +8,21 @@ namespace UI { -class MousePointer: public Image { + class MousePointer : public Image { -protected: - friend class Context; - MousePointer(Context *context, const std::string &filename, const Point &hotspot) : - Image(context, filename, UI::Widget::PRESERVE_ASPECT), - m_hotspot(hotspot) - {} + protected: + friend class Context; + MousePointer(Context *context, const std::string &filename, const Point &hotspot) : + Image(context, filename, UI::Widget::PRESERVE_ASPECT), + m_hotspot(hotspot) + {} - const Point &GetHotspot() const { return m_hotspot; } + const Point &GetHotspot() const { return m_hotspot; } -private: - Point m_hotspot; -}; + private: + Point m_hotspot; + }; -} +} // namespace UI #endif diff --git a/src/ui/MultiLineText.cpp b/src/ui/MultiLineText.cpp index 1784f5f61..f2e49201e 100644 --- a/src/ui/MultiLineText.cpp +++ b/src/ui/MultiLineText.cpp @@ -7,57 +7,60 @@ namespace UI { -MultiLineText::MultiLineText(Context *context, const std::string &text) : Widget(context), m_text(text) -{ - m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); -} + MultiLineText::MultiLineText(Context *context, const std::string &text) : + Widget(context), + m_text(text) + { + m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); + } -Point MultiLineText::PreferredSize() -{ - if (m_preferredSize != Point()) - return m_preferredSize; + Point MultiLineText::PreferredSize() + { + if (m_preferredSize != Point()) + return m_preferredSize; - // 50-75 chars per line is ideal for general readability - // http://baymard.com/blog/line-length-readability - // - // we'll compute a size for about 75 chars wide. container may choose to - // override us, but if it gives us what we ask for this will make sure we - // get something readable - return m_layout->ComputeSize(Point(GetContext()->GetFont(GetFont())->GetGlyph(' ').advX * 75, 0)); -} + // 50-75 chars per line is ideal for general readability + // http://baymard.com/blog/line-length-readability + // + // we'll compute a size for about 75 chars wide. container may choose to + // override us, but if it gives us what we ask for this will make sure we + // get something readable + return m_layout->ComputeSize(Point(GetContext()->GetFont(GetFont())->GetGlyph(' ').advX * 75, 0)); + } -void MultiLineText::Layout() -{ - const Point newSize(m_layout->ComputeSize(GetSize())); - if (m_preferredSize != newSize) GetContext()->RequestLayout(); - m_preferredSize = newSize; - SetActiveArea(m_preferredSize); -} + void MultiLineText::Layout() + { + const Point newSize(m_layout->ComputeSize(GetSize())); + if (m_preferredSize != newSize) GetContext()->RequestLayout(); + m_preferredSize = newSize; + SetActiveArea(m_preferredSize); + } -void MultiLineText::Draw() -{ - m_layout->Draw(GetSize(), GetDrawOffset(), GetContext()->GetScissor(), Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, Color::WHITE.a*GetContext()->GetOpacity())); -} + void MultiLineText::Draw() + { + m_layout->Draw(GetSize(), GetDrawOffset(), GetContext()->GetScissor(), Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, Color::WHITE.a * GetContext()->GetOpacity())); + } -Widget *MultiLineText::SetFont(Font font) { - Widget::SetFont(font); - m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); - m_preferredSize = Point(); - return this; -} + Widget *MultiLineText::SetFont(Font font) + { + Widget::SetFont(font); + m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); + m_preferredSize = Point(); + return this; + } -MultiLineText *MultiLineText::SetText(const std::string &text) -{ - m_text = text; - m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); - m_preferredSize = Point(); - GetContext()->RequestLayout(); - return this; -} + MultiLineText *MultiLineText::SetText(const std::string &text) + { + m_text = text; + m_layout.reset(new TextLayout(GetContext()->GetFont(GetFont()), m_text)); + m_preferredSize = Point(); + GetContext()->RequestLayout(); + return this; + } -MultiLineText *MultiLineText::AppendText(const std::string &text) -{ - return SetText(m_text + text); -} + MultiLineText *MultiLineText::AppendText(const std::string &text) + { + return SetText(m_text + text); + } -} +} // namespace UI diff --git a/src/ui/MultiLineText.h b/src/ui/MultiLineText.h index 1ade5f9cd..5510b75d7 100644 --- a/src/ui/MultiLineText.h +++ b/src/ui/MultiLineText.h @@ -4,34 +4,34 @@ #ifndef UI_MULTILINETEXT_H #define UI_MULTILINETEXT_H -#include "Widget.h" #include "SmartPtr.h" +#include "Widget.h" namespace UI { -class TextLayout; + class TextLayout; -class MultiLineText: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class MultiLineText : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - virtual Widget *SetFont(Font font); + virtual Widget *SetFont(Font font); - MultiLineText *SetText(const std::string &text); - MultiLineText *AppendText(const std::string &text); + MultiLineText *SetText(const std::string &text); + MultiLineText *AppendText(const std::string &text); -protected: - friend class Context; - MultiLineText(Context *context, const std::string &text); + protected: + friend class Context; + MultiLineText(Context *context, const std::string &text); -private: - std::string m_text; - std::unique_ptr m_layout; - Point m_preferredSize; -}; + private: + std::string m_text; + std::unique_ptr m_layout; + Point m_preferredSize; + }; -} +} // namespace UI #endif diff --git a/src/ui/NumberLabel.cpp b/src/ui/NumberLabel.cpp index 75fd52a74..c94d37148 100644 --- a/src/ui/NumberLabel.cpp +++ b/src/ui/NumberLabel.cpp @@ -2,40 +2,40 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "NumberLabel.h" -#include "StringF.h" #include "Lang.h" +#include "StringF.h" #include "utils.h" namespace UI { -NumberLabel::NumberLabel(Context *context, Format format) : - Label(context, ""), - m_format(format) -{ - SetValue(0.0); + NumberLabel::NumberLabel(Context *context, Format format) : + Label(context, ""), + m_format(format) + { + SetValue(0.0); - RegisterBindPoint("value", sigc::mem_fun(this, &NumberLabel::BindValue)); - RegisterBindPoint("valuePercent", sigc::mem_fun(this, &NumberLabel::BindValuePercent)); -} + RegisterBindPoint("value", sigc::mem_fun(this, &NumberLabel::BindValue)); + RegisterBindPoint("valuePercent", sigc::mem_fun(this, &NumberLabel::BindValuePercent)); + } -NumberLabel *NumberLabel::SetValue(double v) -{ - m_value = v; - switch (m_format) { + NumberLabel *NumberLabel::SetValue(double v) + { + m_value = v; + switch (m_format) { case FORMAT_NUMBER_2DP: SetText(to_string(v, "f.2")); break; case FORMAT_INTEGER: - SetText(to_string(Uint32(v+0.5), "u")); + SetText(to_string(Uint32(v + 0.5), "u")); break; case FORMAT_PERCENT: - SetText(stringf("%0{f.2}%%", v*100.0)); + SetText(stringf("%0{f.2}%%", v * 100.0)); break; case FORMAT_PERCENT_INTEGER: - SetText(stringf("%0{u}%%", Uint32(v*100.0+0.5))); + SetText(stringf("%0{u}%%", Uint32(v * 100.0 + 0.5))); break; case FORMAT_MASS_TONNES: @@ -43,7 +43,7 @@ NumberLabel *NumberLabel::SetValue(double v) break; case FORMAT_MONEY: - SetText(format_money(Sint64(v*100))); + SetText(format_money(Sint64(v * 100))); break; case FORMAT_DISTANCE_M: @@ -58,23 +58,23 @@ NumberLabel *NumberLabel::SetValue(double v) case FORMAT_NUMBER: SetText(to_string(v, "f")); break; + } + + return this; } - return this; -} + void NumberLabel::BindValue(PropertyMap &p, const std::string &k) + { + double v = 0.0; + p.Get(k, v); + SetValue(v); + } -void NumberLabel::BindValue(PropertyMap &p, const std::string &k) -{ - double v = 0.0; - p.Get(k, v); - SetValue(v); -} + void NumberLabel::BindValuePercent(PropertyMap &p, const std::string &k) + { + double v = 0.0; + p.Get(k, v); + SetValue(Clamp(v, 0.0, 100.0) * 0.01); + } -void NumberLabel::BindValuePercent(PropertyMap &p, const std::string &k) -{ - double v = 0.0; - p.Get(k, v); - SetValue(Clamp(v, 0.0, 100.0)*0.01); -} - -} +} // namespace UI diff --git a/src/ui/NumberLabel.h b/src/ui/NumberLabel.h index 51c5cdf9a..7c3383e82 100644 --- a/src/ui/NumberLabel.h +++ b/src/ui/NumberLabel.h @@ -9,35 +9,35 @@ namespace UI { -class NumberLabel : public Label { -public: - enum Format { // - FORMAT_NUMBER, - FORMAT_NUMBER_2DP, - FORMAT_INTEGER, - FORMAT_PERCENT, - FORMAT_PERCENT_INTEGER, - FORMAT_MONEY, - FORMAT_MASS_TONNES, - FORMAT_DISTANCE_M, - FORMAT_DISTANCE_LY, + class NumberLabel : public Label { + public: + enum Format { // + FORMAT_NUMBER, + FORMAT_NUMBER_2DP, + FORMAT_INTEGER, + FORMAT_PERCENT, + FORMAT_PERCENT_INTEGER, + FORMAT_MONEY, + FORMAT_MASS_TONNES, + FORMAT_DISTANCE_M, + FORMAT_DISTANCE_LY, + }; + + NumberLabel *SetValue(double v); + double GetValue() const { return m_value; } + + protected: + friend class Context; + NumberLabel(Context *context, Format format); + + private: + void BindValue(PropertyMap &p, const std::string &k); + void BindValuePercent(PropertyMap &p, const std::string &k); + + Format m_format; + double m_value; }; - NumberLabel *SetValue(double v); - double GetValue() const { return m_value; } - -protected: - friend class Context; - NumberLabel(Context *context, Format format); - -private: - void BindValue(PropertyMap &p, const std::string &k); - void BindValuePercent(PropertyMap &p, const std::string &k); - - Format m_format; - double m_value; -}; - -} +} // namespace UI #endif diff --git a/src/ui/OverlayStack.cpp b/src/ui/OverlayStack.cpp index 441ab60f1..7f6968c30 100644 --- a/src/ui/OverlayStack.cpp +++ b/src/ui/OverlayStack.cpp @@ -2,33 +2,33 @@ namespace UI { -Point OverlayStack::PreferredSize() -{ - Point sz(0, 0); - for (auto it : Container::GetWidgets()) { - sz = Point::Max(sz, it->CalcLayoutContribution()); + Point OverlayStack::PreferredSize() + { + Point sz(0, 0); + for (auto it : Container::GetWidgets()) { + sz = Point::Max(sz, it->CalcLayoutContribution()); + } + return sz; } - return sz; -} -void OverlayStack::Layout() -{ - Point sz = GetSize(); - for (auto it : Container::GetWidgets()) { - SetWidgetDimensions(it.Get(), Point(), it->CalcSize(sz)); - it->Layout(); + void OverlayStack::Layout() + { + Point sz = GetSize(); + for (auto it : Container::GetWidgets()) { + SetWidgetDimensions(it.Get(), Point(), it->CalcSize(sz)); + it->Layout(); + } } -} -OverlayStack *OverlayStack::AddLayer(Widget *widget) -{ - AddWidget(widget); - return this; -} + OverlayStack *OverlayStack::AddLayer(Widget *widget) + { + AddWidget(widget); + return this; + } -void OverlayStack::Clear() -{ - RemoveAllWidgets(); -} + void OverlayStack::Clear() + { + RemoveAllWidgets(); + } -} +} // namespace UI diff --git a/src/ui/OverlayStack.h b/src/ui/OverlayStack.h index ec50e50a9..621373b28 100644 --- a/src/ui/OverlayStack.h +++ b/src/ui/OverlayStack.h @@ -8,20 +8,20 @@ namespace UI { -class OverlayStack : public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class OverlayStack : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); - OverlayStack *AddLayer(Widget *widget); - void Clear(); + OverlayStack *AddLayer(Widget *widget); + void Clear(); -protected: - friend class Context; - OverlayStack(Context *context) : Container(context) {} -}; - -} + protected: + friend class Context; + OverlayStack(Context *context) : + Container(context) {} + }; +} // namespace UI #endif diff --git a/src/ui/Point.h b/src/ui/Point.h index 1362cc680..2a51937ae 100644 --- a/src/ui/Point.h +++ b/src/ui/Point.h @@ -8,38 +8,66 @@ namespace UI { -class Point { -public: - int x, y; + class Point { + public: + int x, y; - Point() : x(0), y(0) {} - Point(int _x, int _y) : x(_x), y(_y) {} - explicit Point(int v) : x(v), y(v) {} - Point(const Point &p) : x(p.x), y(p.y) {} + Point() : + x(0), + y(0) {} + Point(int _x, int _y) : + x(_x), + y(_y) {} + explicit Point(int v) : + x(v), + y(v) {} + Point(const Point &p) : + x(p.x), + y(p.y) {} - Point operator+(const Point &v) const { return Point(x+v.x,y+v.y); } - Point operator-(const Point &v) const { return Point(x-v.x,y-v.y); } - Point &operator+=(const Point &v) { x+=v.x; y+=v.y; return *this; } - Point &operator-=(const Point &v) { x-=v.x; y-=v.y; return *this; } - Point &operator*=(const int &a) { x*=a; y*=a; return *this; } - Point operator-() const { return Point(-x,-y); } + Point operator+(const Point &v) const { return Point(x + v.x, y + v.y); } + Point operator-(const Point &v) const { return Point(x - v.x, y - v.y); } + Point &operator+=(const Point &v) + { + x += v.x; + y += v.y; + return *this; + } + Point &operator-=(const Point &v) + { + x -= v.x; + y -= v.y; + return *this; + } + Point &operator*=(const int &a) + { + x *= a; + y *= a; + return *this; + } + Point operator-() const { return Point(-x, -y); } - friend Point operator*(const Point &v, const int &a) { return Point(v.x*a, v.y*a); } - friend Point operator*(const int &a, const Point &v) { return v*a; } - friend Point operator/(const Point &v, const int &a) { return Point(v.x/a, v.y/a); } - friend bool operator==(const Point &a, const Point &b) { return a.x == b.x && a.y == b.y; } - friend bool operator!=(const Point &a, const Point &b) { return ! (a == b); } + friend Point operator*(const Point &v, const int &a) { return Point(v.x * a, v.y * a); } + friend Point operator*(const int &a, const Point &v) { return v * a; } + friend Point operator/(const Point &v, const int &a) { return Point(v.x / a, v.y / a); } + friend bool operator==(const Point &a, const Point &b) { return a.x == b.x && a.y == b.y; } + friend bool operator!=(const Point &a, const Point &b) { return !(a == b); } - enum Component { X, Y }; - const int &operator[](Component c) const { return c == X ? x : y; } - int &operator[](Component c) { return c == X ? x : y; } + enum Component { X, + Y }; + const int &operator[](Component c) const { return c == X ? x : y; } + int &operator[](Component c) { return c == X ? x : y; } - static Point Max(const Point &a, const Point &b) - { return Point(std::max(a.x, b.x), std::max(a.y, b.y)); } - static Point Min(const Point &a, const Point &b) - { return Point(std::min(a.x, b.x), std::min(a.y, b.y)); } -}; + static Point Max(const Point &a, const Point &b) + { + return Point(std::max(a.x, b.x), std::max(a.y, b.y)); + } + static Point Min(const Point &a, const Point &b) + { + return Point(std::min(a.x, b.x), std::min(a.y, b.y)); + } + }; -} +} // namespace UI #endif diff --git a/src/ui/Scroller.cpp b/src/ui/Scroller.cpp index 324cce8a6..61877937b 100644 --- a/src/ui/Scroller.cpp +++ b/src/ui/Scroller.cpp @@ -6,117 +6,118 @@ namespace UI { -Scroller::Scroller(Context *context) : Container(context), - m_innerWidget(0) -{ - m_slider.Reset(GetContext()->VSlider()); - m_slider->onValueChanged.connect(sigc::mem_fun(this, &Scroller::OnSliderScroll)); - m_slider->onMouseWheel.connect(sigc::mem_fun(this, &Scroller::OnMouseWheel)); - onMouseWheel.connect(sigc::mem_fun(this, &Scroller::OnMouseWheel)); -} + Scroller::Scroller(Context *context) : + Container(context), + m_innerWidget(0) + { + m_slider.Reset(GetContext()->VSlider()); + m_slider->onValueChanged.connect(sigc::mem_fun(this, &Scroller::OnSliderScroll)); + m_slider->onMouseWheel.connect(sigc::mem_fun(this, &Scroller::OnMouseWheel)); + onMouseWheel.connect(sigc::mem_fun(this, &Scroller::OnMouseWheel)); + } -Point Scroller::PreferredSize() -{ - const Point sliderSize = m_slider->GetContainer() ? m_slider->PreferredSize() : Point(0); - if (!m_innerWidget) - return sliderSize; + Point Scroller::PreferredSize() + { + const Point sliderSize = m_slider->GetContainer() ? m_slider->PreferredSize() : Point(0); + if (!m_innerWidget) + return sliderSize; - const Point innerWidgetSize = m_innerWidget->PreferredSize(); + const Point innerWidgetSize = m_innerWidget->PreferredSize(); - return Point(SizeAdd(innerWidgetSize.x, sliderSize.x), innerWidgetSize.y); -} + return Point(SizeAdd(innerWidgetSize.x, sliderSize.x), innerWidgetSize.y); + } -void Scroller::Layout() -{ - if (!m_innerWidget) return; + void Scroller::Layout() + { + if (!m_innerWidget) return; - const Point size(GetSize()); + const Point size(GetSize()); - const Point childPreferredSize = m_innerWidget->PreferredSize(); + const Point childPreferredSize = m_innerWidget->PreferredSize(); - // if the child can fit then we don't need the slider - if (childPreferredSize.y <= size.y) { + // if the child can fit then we don't need the slider + if (childPreferredSize.y <= size.y) { + if (m_slider->GetContainer()) + Container::RemoveWidget(m_slider.Get()); + + SetWidgetDimensions(m_innerWidget, Point(), size); + m_innerWidget->Layout(); + } + + else { + if (!m_slider->GetContainer()) + AddWidget(m_slider.Get()); + + const Point sliderSize = m_slider->PreferredSize(); + + SetWidgetDimensions(m_slider.Get(), Point(size.x - sliderSize.x, 0), Point(sliderSize.x, size.y)); + m_slider->Layout(); + + SetWidgetDimensions(m_innerWidget, Point(), Point(size.x - sliderSize.x, std::max(size.y, m_innerWidget->PreferredSize().y))); + m_innerWidget->Layout(); + + const float step = float(sliderSize.y) * 0.5f / float(childPreferredSize.y); + m_slider->SetStep(step); + + // reset the draw offset for new content + OnSliderScroll(m_slider->GetValue()); + } + } + + float Scroller::GetScrollPosition() const + { + return m_slider->GetValue(); + } + + void Scroller::SetScrollPosition(float v) + { + m_slider->SetValue(v); + } + + void Scroller::OnSliderScroll(float value) + { + if (!m_innerWidget) return; if (m_slider->GetContainer()) - Container::RemoveWidget(m_slider.Get()); - - SetWidgetDimensions(m_innerWidget, Point(), size); - m_innerWidget->Layout(); + m_innerWidget->SetDrawOffset(Point(0, -float(m_innerWidget->GetActiveArea().y - GetSize().y) * value)); + else + m_innerWidget->SetDrawOffset(Point()); } - else { - if (!m_slider->GetContainer()) - AddWidget(m_slider.Get()); - - const Point sliderSize = m_slider->PreferredSize(); - - SetWidgetDimensions(m_slider.Get(), Point(size.x-sliderSize.x, 0), Point(sliderSize.x, size.y)); - m_slider->Layout(); - - SetWidgetDimensions(m_innerWidget, Point(), Point(size.x-sliderSize.x, std::max(size.y, m_innerWidget->PreferredSize().y))); - m_innerWidget->Layout(); - - const float step = float(sliderSize.y) * 0.5f / float(childPreferredSize.y); - m_slider->SetStep(step); - - // reset the draw offset for new content - OnSliderScroll(m_slider->GetValue()); + bool Scroller::OnMouseWheel(const MouseWheelEvent &event) + { + if (event.direction == MouseWheelEvent::WHEEL_UP) + m_slider->StepUp(); + else + m_slider->StepDown(); + return true; } -} -float Scroller::GetScrollPosition() const -{ - return m_slider->GetValue(); -} + Scroller *Scroller::SetInnerWidget(Widget *widget) + { + assert(widget); -void Scroller::SetScrollPosition(float v) -{ - m_slider->SetValue(v); -} + if (m_innerWidget) + Container::RemoveWidget(m_innerWidget); -void Scroller::OnSliderScroll(float value) -{ - if (!m_innerWidget) return; - if (m_slider->GetContainer()) - m_innerWidget->SetDrawOffset(Point(0, -float(m_innerWidget->GetActiveArea().y-GetSize().y)*value)); - else - m_innerWidget->SetDrawOffset(Point()); -} + AddWidget(widget); + m_innerWidget = widget; -bool Scroller::OnMouseWheel(const MouseWheelEvent &event) -{ - if (event.direction == MouseWheelEvent::WHEEL_UP) - m_slider->StepUp(); - else - m_slider->StepDown(); - return true; -} - -Scroller *Scroller::SetInnerWidget(Widget *widget) -{ - assert(widget); - - if (m_innerWidget) - Container::RemoveWidget(m_innerWidget); - - AddWidget(widget); - m_innerWidget = widget; - - return this; -} - -void Scroller::RemoveInnerWidget() -{ - if (m_innerWidget) { - Container::RemoveWidget(m_innerWidget); - m_innerWidget = 0; + return this; } -} -void Scroller::RemoveWidget(Widget *widget) -{ - if (m_innerWidget != widget) - return; - RemoveInnerWidget(); -} + void Scroller::RemoveInnerWidget() + { + if (m_innerWidget) { + Container::RemoveWidget(m_innerWidget); + m_innerWidget = 0; + } + } -} + void Scroller::RemoveWidget(Widget *widget) + { + if (m_innerWidget != widget) + return; + RemoveInnerWidget(); + } + +} // namespace UI diff --git a/src/ui/Scroller.h b/src/ui/Scroller.h index fcd36cead..de7fd299c 100644 --- a/src/ui/Scroller.h +++ b/src/ui/Scroller.h @@ -8,35 +8,35 @@ namespace UI { -class HBox; -class VSlider; + class HBox; + class VSlider; -class Scroller : public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class Scroller : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); - Scroller *SetInnerWidget(Widget *widget); - void RemoveInnerWidget(); - Widget *GetInnerWidget() const { return m_innerWidget; } + Scroller *SetInnerWidget(Widget *widget); + void RemoveInnerWidget(); + Widget *GetInnerWidget() const { return m_innerWidget; } - float GetScrollPosition() const; - void SetScrollPosition(float v); + float GetScrollPosition() const; + void SetScrollPosition(float v); -protected: - friend class Context; - Scroller(Context *context); + protected: + friend class Context; + Scroller(Context *context); - virtual void RemoveWidget(Widget *widget); + virtual void RemoveWidget(Widget *widget); -private: - Widget *m_innerWidget; - RefCountedPtr m_slider; + private: + Widget *m_innerWidget; + RefCountedPtr m_slider; - void OnSliderScroll(float value); - bool OnMouseWheel(const MouseWheelEvent &event); -}; + void OnSliderScroll(float value); + bool OnMouseWheel(const MouseWheelEvent &event); + }; -} +} // namespace UI #endif diff --git a/src/ui/Single.cpp b/src/ui/Single.cpp index b81ff17fc..2f83fe771 100644 --- a/src/ui/Single.cpp +++ b/src/ui/Single.cpp @@ -6,50 +6,50 @@ namespace UI { -Point Single::PreferredSize() -{ - if (!m_innerWidget) return Point(); - return m_innerWidget->CalcLayoutContribution(); -} - -void Single::Layout() -{ - if (!m_innerWidget) return; - SetWidgetDimensions(m_innerWidget, Point(), m_innerWidget->CalcSize(GetSize())); - m_innerWidget->Layout(); -} - -Single *Single::SetInnerWidget(Widget *widget) -{ - assert(widget); - - if (m_innerWidget == widget) - return this; - - RemoveAllWidgets(); - - AddWidget(widget); - m_innerWidget = widget; - - GetContext()->RequestLayout(); - - return this; -} - -void Single::RemoveInnerWidget() -{ - if (m_innerWidget) { - Container::RemoveWidget(m_innerWidget); - m_innerWidget = 0; - GetContext()->RequestLayout(); + Point Single::PreferredSize() + { + if (!m_innerWidget) return Point(); + return m_innerWidget->CalcLayoutContribution(); } -} -void Single::RemoveWidget(Widget *widget) -{ - if (m_innerWidget != widget) - return; - RemoveInnerWidget(); -} + void Single::Layout() + { + if (!m_innerWidget) return; + SetWidgetDimensions(m_innerWidget, Point(), m_innerWidget->CalcSize(GetSize())); + m_innerWidget->Layout(); + } -} + Single *Single::SetInnerWidget(Widget *widget) + { + assert(widget); + + if (m_innerWidget == widget) + return this; + + RemoveAllWidgets(); + + AddWidget(widget); + m_innerWidget = widget; + + GetContext()->RequestLayout(); + + return this; + } + + void Single::RemoveInnerWidget() + { + if (m_innerWidget) { + Container::RemoveWidget(m_innerWidget); + m_innerWidget = 0; + GetContext()->RequestLayout(); + } + } + + void Single::RemoveWidget(Widget *widget) + { + if (m_innerWidget != widget) + return; + RemoveInnerWidget(); + } + +} // namespace UI diff --git a/src/ui/Single.h b/src/ui/Single.h index df3c30655..f2860baca 100644 --- a/src/ui/Single.h +++ b/src/ui/Single.h @@ -8,24 +8,26 @@ namespace UI { -class Single : public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); + class Single : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); - Single *SetInnerWidget(Widget *widget); - void RemoveInnerWidget(); - Widget *GetInnerWidget() const { return m_innerWidget; } + Single *SetInnerWidget(Widget *widget); + void RemoveInnerWidget(); + Widget *GetInnerWidget() const { return m_innerWidget; } -protected: - Single(Context *context) : Container(context), m_innerWidget(0) {} + protected: + Single(Context *context) : + Container(context), + m_innerWidget(0) {} - virtual void RemoveWidget(Widget *widget); + virtual void RemoveWidget(Widget *widget); -private: - Widget *m_innerWidget; -}; + private: + Widget *m_innerWidget; + }; -} +} // namespace UI #endif diff --git a/src/ui/Skin.cpp b/src/ui/Skin.cpp index af78bf586..0c1729374 100644 --- a/src/ui/Skin.cpp +++ b/src/ui/Skin.cpp @@ -2,251 +2,251 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "Skin.h" +#include "FileSystem.h" #include "IniConfig.h" #include "graphics/TextureBuilder.h" #include "graphics/VertexArray.h" -#include "FileSystem.h" #include "utils.h" namespace UI { -static const float SKIN_SIZE = 512.0f; + static const float SKIN_SIZE = 512.0f; -Skin::Skin(const std::string &filename, Graphics::Renderer *renderer, float scale) : - m_renderer(renderer), - m_scale(scale), - m_opacity(1.0f) -{ - IniConfig cfg; - // set defaults - cfg.SetInt("ButtonMinInnerSize", 16); - cfg.SetString("NormalColorRGBA", "0,0,0,0"); - cfg.SetString("HoverColorRGBA", "0,0,0,102"); - cfg.SetString("SelectColorRGBA", "0,0,0,153"); - // load - cfg.Read(FileSystem::gameDataFiles, filename); + Skin::Skin(const std::string &filename, Graphics::Renderer *renderer, float scale) : + m_renderer(renderer), + m_scale(scale), + m_opacity(1.0f) + { + IniConfig cfg; + // set defaults + cfg.SetInt("ButtonMinInnerSize", 16); + cfg.SetString("NormalColorRGBA", "0,0,0,0"); + cfg.SetString("HoverColorRGBA", "0,0,0,102"); + cfg.SetString("SelectColorRGBA", "0,0,0,153"); + // load + cfg.Read(FileSystem::gameDataFiles, filename); - m_texture.Reset(Graphics::TextureBuilder::UI(cfg.String("TextureFile")).GetOrCreateTexture(m_renderer, "ui")); + m_texture.Reset(Graphics::TextureBuilder::UI(cfg.String("TextureFile")).GetOrCreateTexture(m_renderer, "ui")); - Graphics::MaterialDescriptor desc; - desc.textures = 1; - m_textureMaterial.Reset(m_renderer->CreateMaterial(desc)); - m_textureMaterial->texture0 = m_texture.Get(); - m_textureMaterial->diffuse = Color::WHITE; + Graphics::MaterialDescriptor desc; + desc.textures = 1; + m_textureMaterial.Reset(m_renderer->CreateMaterial(desc)); + m_textureMaterial->texture0 = m_texture.Get(); + m_textureMaterial->diffuse = Color::WHITE; - desc.textures = 0; - m_colorMaterial.Reset(m_renderer->CreateMaterial(desc)); + desc.textures = 0; + m_colorMaterial.Reset(m_renderer->CreateMaterial(desc)); - Graphics::RenderStateDesc rsd; - rsd.blendMode = Graphics::BLEND_ALPHA; - rsd.depthWrite = false; - rsd.depthTest = false; - m_alphaBlendState = m_renderer->CreateRenderState(rsd); + Graphics::RenderStateDesc rsd; + rsd.blendMode = Graphics::BLEND_ALPHA; + rsd.depthWrite = false; + rsd.depthTest = false; + m_alphaBlendState = m_renderer->CreateRenderState(rsd); - rsd.blendMode = Graphics::BLEND_SET_ALPHA; - m_alphaSetState = m_renderer->CreateRenderState(rsd); + rsd.blendMode = Graphics::BLEND_SET_ALPHA; + m_alphaSetState = m_renderer->CreateRenderState(rsd); - rsd.blendMode = Graphics::BLEND_DEST_ALPHA; - m_alphaMaskState = m_renderer->CreateRenderState(rsd); + rsd.blendMode = Graphics::BLEND_DEST_ALPHA; + m_alphaMaskState = m_renderer->CreateRenderState(rsd); - m_backgroundNormal = LoadBorderedRectElement(cfg.String("BackgroundNormal")); - m_backgroundActive = LoadBorderedRectElement(cfg.String("BackgroundActive")); + m_backgroundNormal = LoadBorderedRectElement(cfg.String("BackgroundNormal")); + m_backgroundActive = LoadBorderedRectElement(cfg.String("BackgroundActive")); - m_buttonDisabled = LoadBorderedRectElement(cfg.String("ButtonDisabled")); - m_buttonNormal = LoadBorderedRectElement(cfg.String("ButtonNormal")); - m_buttonHover = LoadBorderedRectElement(cfg.String("ButtonHover")); - m_buttonActive = LoadBorderedRectElement(cfg.String("ButtonActive")); + m_buttonDisabled = LoadBorderedRectElement(cfg.String("ButtonDisabled")); + m_buttonNormal = LoadBorderedRectElement(cfg.String("ButtonNormal")); + m_buttonHover = LoadBorderedRectElement(cfg.String("ButtonHover")); + m_buttonActive = LoadBorderedRectElement(cfg.String("ButtonActive")); - m_buttonHidden = LoadSkinColor(cfg.String("NormalColorRGBA")); - m_smallButtonHidden = LoadSkinColor(cfg.String("NormalColorRGBA")); + m_buttonHidden = LoadSkinColor(cfg.String("NormalColorRGBA")); + m_smallButtonHidden = LoadSkinColor(cfg.String("NormalColorRGBA")); - m_smallButtonDisabled = LoadRectElement(cfg.String("SmallButtonDisabled")); - m_smallButtonNormal = LoadRectElement(cfg.String("SmallButtonNormal")); - m_smallButtonHover = LoadRectElement(cfg.String("SmallButtonHover")); - m_smallButtonActive = LoadRectElement(cfg.String("SmallButtonActive")); + m_smallButtonDisabled = LoadRectElement(cfg.String("SmallButtonDisabled")); + m_smallButtonNormal = LoadRectElement(cfg.String("SmallButtonNormal")); + m_smallButtonHover = LoadRectElement(cfg.String("SmallButtonHover")); + m_smallButtonActive = LoadRectElement(cfg.String("SmallButtonActive")); - m_checkboxDisabled = LoadRectElement(cfg.String("CheckboxDisabled")); - m_checkboxNormal = LoadRectElement(cfg.String("CheckboxNormal")); - m_checkboxHover = LoadRectElement(cfg.String("CheckboxHover")); - m_checkboxActive = LoadRectElement(cfg.String("CheckboxActive")); - m_checkboxCheckedDisabled = LoadRectElement(cfg.String("CheckboxCheckedDisabled")); - m_checkboxCheckedNormal = LoadRectElement(cfg.String("CheckboxCheckedNormal")); - m_checkboxCheckedHover = LoadRectElement(cfg.String("CheckboxCheckedHover")); - m_checkboxCheckedActive = LoadRectElement(cfg.String("CheckboxCheckedActive")); + m_checkboxDisabled = LoadRectElement(cfg.String("CheckboxDisabled")); + m_checkboxNormal = LoadRectElement(cfg.String("CheckboxNormal")); + m_checkboxHover = LoadRectElement(cfg.String("CheckboxHover")); + m_checkboxActive = LoadRectElement(cfg.String("CheckboxActive")); + m_checkboxCheckedDisabled = LoadRectElement(cfg.String("CheckboxCheckedDisabled")); + m_checkboxCheckedNormal = LoadRectElement(cfg.String("CheckboxCheckedNormal")); + m_checkboxCheckedHover = LoadRectElement(cfg.String("CheckboxCheckedHover")); + m_checkboxCheckedActive = LoadRectElement(cfg.String("CheckboxCheckedActive")); - m_sliderVerticalGutter = LoadEdgedRectElement(cfg.String("SliderVerticalGutter")); - m_sliderHorizontalGutter = LoadEdgedRectElement(cfg.String("SliderHorizontalGutter")); - m_sliderVerticalButtonNormal = LoadRectElement(cfg.String("SliderVerticalButtonNormal")); - m_sliderVerticalButtonHover = LoadRectElement(cfg.String("SliderVerticalButtonHover")); - m_sliderVerticalButtonActive = LoadRectElement(cfg.String("SliderVerticalButtonActive")); - m_sliderHorizontalButtonNormal = LoadRectElement(cfg.String("SliderHorizontalButtonNormal")); - m_sliderHorizontalButtonHover = LoadRectElement(cfg.String("SliderHorizontalButtonHover")); - m_sliderHorizontalButtonActive = LoadRectElement(cfg.String("SliderHorizontalButtonActive")); + m_sliderVerticalGutter = LoadEdgedRectElement(cfg.String("SliderVerticalGutter")); + m_sliderHorizontalGutter = LoadEdgedRectElement(cfg.String("SliderHorizontalGutter")); + m_sliderVerticalButtonNormal = LoadRectElement(cfg.String("SliderVerticalButtonNormal")); + m_sliderVerticalButtonHover = LoadRectElement(cfg.String("SliderVerticalButtonHover")); + m_sliderVerticalButtonActive = LoadRectElement(cfg.String("SliderVerticalButtonActive")); + m_sliderHorizontalButtonNormal = LoadRectElement(cfg.String("SliderHorizontalButtonNormal")); + m_sliderHorizontalButtonHover = LoadRectElement(cfg.String("SliderHorizontalButtonHover")); + m_sliderHorizontalButtonActive = LoadRectElement(cfg.String("SliderHorizontalButtonActive")); - m_gaugeBackground = LoadEdgedRectElement(cfg.String("GaugeBackground")); - m_gaugeMask = LoadEdgedRectElement(cfg.String("GaugeMask")); - m_gaugeFillNormal = LoadRectElement(cfg.String("GaugeFillNormal")); - m_gaugeFillWarning = LoadRectElement(cfg.String("GaugeFillWarning")); - m_gaugeFillCritical = LoadRectElement(cfg.String("GaugeFillCritical")); + m_gaugeBackground = LoadEdgedRectElement(cfg.String("GaugeBackground")); + m_gaugeMask = LoadEdgedRectElement(cfg.String("GaugeMask")); + m_gaugeFillNormal = LoadRectElement(cfg.String("GaugeFillNormal")); + m_gaugeFillWarning = LoadRectElement(cfg.String("GaugeFillWarning")); + m_gaugeFillCritical = LoadRectElement(cfg.String("GaugeFillCritical")); - m_buttonMinInnerSize = cfg.Int("ButtonMinInnerSize"); + m_buttonMinInnerSize = cfg.Int("ButtonMinInnerSize"); - m_normalColor = LoadSkinColor(cfg.String("NormalColorRGBA")); - m_hoverColor = LoadSkinColor(cfg.String("HoverColorRGBA")); - m_selectColor = LoadSkinColor(cfg.String("SelectColorRGBA")); -} + m_normalColor = LoadSkinColor(cfg.String("NormalColorRGBA")); + m_hoverColor = LoadSkinColor(cfg.String("HoverColorRGBA")); + m_selectColor = LoadSkinColor(cfg.String("SelectColorRGBA")); + } -Graphics::RenderState *Skin::GetRenderState(Graphics::BlendMode mode) const -{ - if (mode == Graphics::BLEND_SET_ALPHA) - return m_alphaSetState; - else if (mode == Graphics::BLEND_DEST_ALPHA) - return m_alphaMaskState; - else - return m_alphaBlendState; -} + Graphics::RenderState *Skin::GetRenderState(Graphics::BlendMode mode) const + { + if (mode == Graphics::BLEND_SET_ALPHA) + return m_alphaSetState; + else if (mode == Graphics::BLEND_DEST_ALPHA) + return m_alphaMaskState; + else + return m_alphaBlendState; + } -static inline vector2f scaled(const vector2f &v) -{ - return v * (1.0f / SKIN_SIZE); -} + static inline vector2f scaled(const vector2f &v) + { + return v * (1.0f / SKIN_SIZE); + } -void Skin::DrawRectElement(const RectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const -{ - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + void Skin::DrawRectElement(const RectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const + { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); - va.Add(vector3f(pos.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y))); + va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); + va.Add(vector3f(pos.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y))); - m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity*Color::WHITE.a); - m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); -} + m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity * Color::WHITE.a); + m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); + } -void Skin::DrawBorderedRectElement(const BorderedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const -{ - const float width = element.borderWidth; - const float height = element.borderHeight; + void Skin::DrawBorderedRectElement(const BorderedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const + { + const float width = element.borderWidth; + const float height = element.borderHeight; - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); - va.Add(vector3f(pos.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+height))); - va.Add(vector3f(pos.x+width, pos.y, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y))); - va.Add(vector3f(pos.x+width, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+height))); - va.Add(vector3f(pos.x+size.x-width, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y))); - va.Add(vector3f(pos.x+size.x-width, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+height))); - va.Add(vector3f(pos.x+size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y))); - va.Add(vector3f(pos.x+size.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+height))); + va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); + va.Add(vector3f(pos.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + height))); + va.Add(vector3f(pos.x + width, pos.y, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y))); + va.Add(vector3f(pos.x + width, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + height))); + va.Add(vector3f(pos.x + size.x - width, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y))); + va.Add(vector3f(pos.x + size.x - width, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + height))); + va.Add(vector3f(pos.x + size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y))); + va.Add(vector3f(pos.x + size.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + height))); - // degenerate triangles to join rows - va.Add(vector3f(pos.x+size.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+height))); - va.Add(vector3f(pos.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+height))); + // degenerate triangles to join rows + va.Add(vector3f(pos.x + size.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + height))); + va.Add(vector3f(pos.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + height))); - va.Add(vector3f(pos.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+height))); - va.Add(vector3f(pos.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+width, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+height))); - va.Add(vector3f(pos.x+width, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+size.x-width, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+height))); - va.Add(vector3f(pos.x+size.x-width, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+size.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+height))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y-height))); + va.Add(vector3f(pos.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + height))); + va.Add(vector3f(pos.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + width, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + height))); + va.Add(vector3f(pos.x + width, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + size.x - width, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + height))); + va.Add(vector3f(pos.x + size.x - width, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + size.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + height))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y - height))); - // degenerate triangles to join rows - va.Add(vector3f(pos.x+size.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y-height))); + // degenerate triangles to join rows + va.Add(vector3f(pos.x + size.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y - height))); - va.Add(vector3f(pos.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+width, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+width, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+size.x-width, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+size.x-width, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y))); + va.Add(vector3f(pos.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + width, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + width, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + size.x - width, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + size.x - width, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y))); - m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity*Color::WHITE.a); - m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); -} + m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity * Color::WHITE.a); + m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); + } -void Skin::DrawVerticalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const -{ - const float height = element.edgeWidth; + void Skin::DrawVerticalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const + { + const float height = element.edgeWidth; - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(pos.x+size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y))); - va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); - va.Add(vector3f(pos.x+size.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+height))); - va.Add(vector3f(pos.x, pos.y+height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+height))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x, pos.y+size.y-height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y-height))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y))); + va.Add(vector3f(pos.x + size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y))); + va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); + va.Add(vector3f(pos.x + size.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + height))); + va.Add(vector3f(pos.x, pos.y + height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + height))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x, pos.y + size.y - height, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y - height))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y))); - m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity*Color::WHITE.a); - m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); -} + m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity * Color::WHITE.a); + m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); + } -void Skin::DrawHorizontalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const -{ - const float width = element.edgeWidth; + void Skin::DrawHorizontalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode) const + { + const float width = element.edgeWidth; - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0); - va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); - va.Add(vector3f(pos.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+width, pos.y, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y))); - va.Add(vector3f(pos.x+width, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+width, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+size.x-width, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y))); - va.Add(vector3f(pos.x+size.x-width, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x-width, element.pos.y+element.size.y))); - va.Add(vector3f(pos.x+size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y))); - va.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f), scaled(vector2f(element.pos.x+element.size.x, element.pos.y+element.size.y))); + va.Add(vector3f(pos.x, pos.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y))); + va.Add(vector3f(pos.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + width, pos.y, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y))); + va.Add(vector3f(pos.x + width, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + width, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + size.x - width, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y))); + va.Add(vector3f(pos.x + size.x - width, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x - width, element.pos.y + element.size.y))); + va.Add(vector3f(pos.x + size.x, pos.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y))); + va.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f), scaled(vector2f(element.pos.x + element.size.x, element.pos.y + element.size.y))); - m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity*Color::WHITE.a); - m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); -} + m_textureMaterial->diffuse = Color(Color::WHITE.r, Color::WHITE.g, Color::WHITE.b, m_opacity * Color::WHITE.a); + m_renderer->DrawTriangles(&va, GetRenderState(blendMode), m_textureMaterial.Get(), Graphics::TRIANGLE_STRIP); + } -void Skin::DrawRectColor(const Color &col, const Point &pos, const Point &size) const -{ - Graphics::VertexArray va(Graphics::ATTRIB_POSITION); + void Skin::DrawRectColor(const Color &col, const Point &pos, const Point &size) const + { + Graphics::VertexArray va(Graphics::ATTRIB_POSITION); - va.Add(vector3f(pos.x, pos.y, 0.0f)); - va.Add(vector3f(pos.x, pos.y+size.y, 0.0f)); - va.Add(vector3f(pos.x+size.x, pos.y, 0.0f)); - va.Add(vector3f(pos.x+size.x, pos.y+size.y, 0.0f)); + va.Add(vector3f(pos.x, pos.y, 0.0f)); + va.Add(vector3f(pos.x, pos.y + size.y, 0.0f)); + va.Add(vector3f(pos.x + size.x, pos.y, 0.0f)); + va.Add(vector3f(pos.x + size.x, pos.y + size.y, 0.0f)); - m_colorMaterial->diffuse = Color(col.r, col.g, col.b, m_opacity*col.a); - m_renderer->DrawTriangles(&va, GetAlphaBlendState(), m_colorMaterial.Get(), Graphics::TRIANGLE_STRIP); -} + m_colorMaterial->diffuse = Color(col.r, col.g, col.b, m_opacity * col.a); + m_renderer->DrawTriangles(&va, GetAlphaBlendState(), m_colorMaterial.Get(), Graphics::TRIANGLE_STRIP); + } -Skin::RectElement Skin::LoadRectElement(const std::string &spec) -{ - std::vector v(4); - SplitSpec(spec, v); - return RectElement(v[0], v[1], v[2], v[3]); -} + Skin::RectElement Skin::LoadRectElement(const std::string &spec) + { + std::vector v(4); + SplitSpec(spec, v); + return RectElement(v[0], v[1], v[2], v[3]); + } -Skin::BorderedRectElement Skin::LoadBorderedRectElement(const std::string &spec) -{ - std::vector v(8); - SplitSpec(spec, v); - return BorderedRectElement(v[0], v[1], v[2], v[3], v[4]*m_scale, v[5]*m_scale, v[6]*m_scale, v[7]*m_scale); -} + Skin::BorderedRectElement Skin::LoadBorderedRectElement(const std::string &spec) + { + std::vector v(8); + SplitSpec(spec, v); + return BorderedRectElement(v[0], v[1], v[2], v[3], v[4] * m_scale, v[5] * m_scale, v[6] * m_scale, v[7] * m_scale); + } -Skin::EdgedRectElement Skin::LoadEdgedRectElement(const std::string &spec) -{ - std::vector v(5); - SplitSpec(spec, v); - return EdgedRectElement(v[0], v[1], v[2], v[3], v[4]); -} + Skin::EdgedRectElement Skin::LoadEdgedRectElement(const std::string &spec) + { + std::vector v(5); + SplitSpec(spec, v); + return EdgedRectElement(v[0], v[1], v[2], v[3], v[4]); + } -Color Skin::LoadSkinColor(const std::string &spec) -{ - std::vector v(4); - SplitSpec(spec, v); - return Color(v[0], v[1], v[2], v[3]); -} + Color Skin::LoadSkinColor(const std::string &spec) + { + std::vector v(4); + SplitSpec(spec, v); + return Color(v[0], v[1], v[2], v[3]); + } -} +} // namespace UI diff --git a/src/ui/Skin.h b/src/ui/Skin.h index 56bc1e219..5c79baac9 100644 --- a/src/ui/Skin.h +++ b/src/ui/Skin.h @@ -4,293 +4,340 @@ #ifndef UI_SKIN_H #define UI_SKIN_H -#include "libs.h" +#include "Point.h" #include "SmartPtr.h" -#include "graphics/Renderer.h" #include "graphics/Material.h" #include "graphics/RenderState.h" -#include "Point.h" +#include "graphics/Renderer.h" +#include "libs.h" #include namespace UI { -class Skin { -public: - Skin(const std::string &filename, Graphics::Renderer *renderer, float scale); + class Skin { + public: + Skin(const std::string &filename, Graphics::Renderer *renderer, float scale); - void SetOpacity(float o) { m_opacity = o; } + void SetOpacity(float o) { m_opacity = o; } - void DrawBackgroundNormal(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_backgroundNormal, pos, size); - } - void DrawBackgroundHover(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_backgroundActive, pos, size); - } - void DrawBackgroundActive(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_backgroundActive, pos, size); - } + void DrawBackgroundNormal(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_backgroundNormal, pos, size); + } + void DrawBackgroundHover(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_backgroundActive, pos, size); + } + void DrawBackgroundActive(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_backgroundActive, pos, size); + } - void DrawButtonDisabled(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_buttonDisabled, pos, size); - } - void DrawButtonNormal(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_buttonNormal, pos, size); - } - void DrawButtonHover(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_buttonHover, pos, size); - } - void DrawButtonActive(const Point &pos, const Point &size) const { - DrawBorderedRectElement(m_buttonActive, pos, size); - } + void DrawButtonDisabled(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_buttonDisabled, pos, size); + } + void DrawButtonNormal(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_buttonNormal, pos, size); + } + void DrawButtonHover(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_buttonHover, pos, size); + } + void DrawButtonActive(const Point &pos, const Point &size) const + { + DrawBorderedRectElement(m_buttonActive, pos, size); + } - void DrawButtonHidden(const Point &pos, const Point &size) const { - DrawRectColor(m_buttonHidden, pos, size); - } - void DrawSmallButtonHidden(const Point &pos, const Point &size) const { - DrawRectColor(m_smallButtonHidden, pos, size); - } + void DrawButtonHidden(const Point &pos, const Point &size) const + { + DrawRectColor(m_buttonHidden, pos, size); + } + void DrawSmallButtonHidden(const Point &pos, const Point &size) const + { + DrawRectColor(m_smallButtonHidden, pos, size); + } - void DrawSmallButtonDisabled(const Point &pos, const Point &size) const { - DrawRectElement(m_smallButtonDisabled, pos, size); - } - void DrawSmallButtonNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_smallButtonNormal, pos, size); - } - void DrawSmallButtonHover(const Point &pos, const Point &size) const { - DrawRectElement(m_smallButtonHover, pos, size); - } - void DrawSmallButtonActive(const Point &pos, const Point &size) const { - DrawRectElement(m_smallButtonActive, pos, size); - } + void DrawSmallButtonDisabled(const Point &pos, const Point &size) const + { + DrawRectElement(m_smallButtonDisabled, pos, size); + } + void DrawSmallButtonNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_smallButtonNormal, pos, size); + } + void DrawSmallButtonHover(const Point &pos, const Point &size) const + { + DrawRectElement(m_smallButtonHover, pos, size); + } + void DrawSmallButtonActive(const Point &pos, const Point &size) const + { + DrawRectElement(m_smallButtonActive, pos, size); + } - void DrawCheckBoxDisabled(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxDisabled, pos, size); - } - void DrawCheckBoxNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxNormal, pos, size); - } - void DrawCheckBoxHover(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxHover, pos, size); - } - void DrawCheckBoxActive(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxActive, pos, size); - } - void DrawCheckBoxCheckedDisabled(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxCheckedDisabled, pos, size); - } - void DrawCheckBoxCheckedNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxCheckedNormal, pos, size); - } - void DrawCheckBoxCheckedHover(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxCheckedHover, pos, size); - } - void DrawCheckBoxCheckedActive(const Point &pos, const Point &size) const { - DrawRectElement(m_checkboxCheckedActive, pos, size); - } + void DrawCheckBoxDisabled(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxDisabled, pos, size); + } + void DrawCheckBoxNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxNormal, pos, size); + } + void DrawCheckBoxHover(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxHover, pos, size); + } + void DrawCheckBoxActive(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxActive, pos, size); + } + void DrawCheckBoxCheckedDisabled(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxCheckedDisabled, pos, size); + } + void DrawCheckBoxCheckedNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxCheckedNormal, pos, size); + } + void DrawCheckBoxCheckedHover(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxCheckedHover, pos, size); + } + void DrawCheckBoxCheckedActive(const Point &pos, const Point &size) const + { + DrawRectElement(m_checkboxCheckedActive, pos, size); + } - void DrawSliderVerticalGutter(const Point &pos, const Point &size) const { - DrawVerticalEdgedRectElement(m_sliderVerticalGutter, pos, size); - } - void DrawSliderHorizontalGutter(const Point &pos, const Point &size) const { - DrawHorizontalEdgedRectElement(m_sliderHorizontalGutter, pos, size); - } - void DrawSliderVerticalButtonNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderVerticalButtonNormal, pos, size); - } - void DrawSliderVerticalButtonHover(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderVerticalButtonHover, pos, size); - } - void DrawSliderVerticalButtonActive(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderVerticalButtonActive, pos, size); - } - void DrawSliderHorizontalButtonNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderHorizontalButtonNormal, pos, size); - } - void DrawSliderHorizontalButtonHover(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderHorizontalButtonHover, pos, size); - } - void DrawSliderHorizontalButtonActive(const Point &pos, const Point &size) const { - DrawRectElement(m_sliderHorizontalButtonActive, pos, size); - } + void DrawSliderVerticalGutter(const Point &pos, const Point &size) const + { + DrawVerticalEdgedRectElement(m_sliderVerticalGutter, pos, size); + } + void DrawSliderHorizontalGutter(const Point &pos, const Point &size) const + { + DrawHorizontalEdgedRectElement(m_sliderHorizontalGutter, pos, size); + } + void DrawSliderVerticalButtonNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderVerticalButtonNormal, pos, size); + } + void DrawSliderVerticalButtonHover(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderVerticalButtonHover, pos, size); + } + void DrawSliderVerticalButtonActive(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderVerticalButtonActive, pos, size); + } + void DrawSliderHorizontalButtonNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderHorizontalButtonNormal, pos, size); + } + void DrawSliderHorizontalButtonHover(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderHorizontalButtonHover, pos, size); + } + void DrawSliderHorizontalButtonActive(const Point &pos, const Point &size) const + { + DrawRectElement(m_sliderHorizontalButtonActive, pos, size); + } - void DrawGaugeBackground(const Point &pos, const Point &size) const { - DrawHorizontalEdgedRectElement(m_gaugeBackground, pos, size); - } - void DrawGaugeMask(const Point &pos, const Point &size) const { - DrawHorizontalEdgedRectElement(m_gaugeMask, pos, size, Graphics::BLEND_SET_ALPHA); - } - void DrawGaugeFillNormal(const Point &pos, const Point &size) const { - DrawRectElement(m_gaugeFillNormal, pos, size, Graphics::BLEND_DEST_ALPHA); - } - void DrawGaugeFillWarning(const Point &pos, const Point &size) const { - DrawRectElement(m_gaugeFillWarning, pos, size, Graphics::BLEND_DEST_ALPHA); - } - void DrawGaugeFillCritical(const Point &pos, const Point &size) const { - DrawRectElement(m_gaugeFillCritical, pos, size, Graphics::BLEND_DEST_ALPHA); - } + void DrawGaugeBackground(const Point &pos, const Point &size) const + { + DrawHorizontalEdgedRectElement(m_gaugeBackground, pos, size); + } + void DrawGaugeMask(const Point &pos, const Point &size) const + { + DrawHorizontalEdgedRectElement(m_gaugeMask, pos, size, Graphics::BLEND_SET_ALPHA); + } + void DrawGaugeFillNormal(const Point &pos, const Point &size) const + { + DrawRectElement(m_gaugeFillNormal, pos, size, Graphics::BLEND_DEST_ALPHA); + } + void DrawGaugeFillWarning(const Point &pos, const Point &size) const + { + DrawRectElement(m_gaugeFillWarning, pos, size, Graphics::BLEND_DEST_ALPHA); + } + void DrawGaugeFillCritical(const Point &pos, const Point &size) const + { + DrawRectElement(m_gaugeFillCritical, pos, size, Graphics::BLEND_DEST_ALPHA); + } + void DrawRectColor(const Color &col, const Point &pos, const Point &size) const; + void DrawRectNormal(const Point &pos, const Point &size) const + { + DrawRectColor(m_normalColor, pos, size); + } + void DrawRectHover(const Point &pos, const Point &size) const + { + DrawRectColor(m_hoverColor, pos, size); + } + void DrawRectSelect(const Point &pos, const Point &size) const + { + DrawRectColor(m_selectColor, pos, size); + } - void DrawRectColor(const Color &col, const Point &pos, const Point &size) const; - void DrawRectNormal(const Point &pos, const Point &size) const { - DrawRectColor(m_normalColor, pos, size); - } - void DrawRectHover(const Point &pos, const Point &size) const { - DrawRectColor(m_hoverColor, pos, size); - } - void DrawRectSelect(const Point &pos, const Point &size) const { - DrawRectColor(m_selectColor, pos, size); - } + struct RectElement { + RectElement() {} + RectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h) : + pos(x, y), + size(w, h) {} + Point pos; + Point size; + }; + struct BorderedRectElement : public RectElement { + BorderedRectElement() : + borderWidth(0), + borderHeight(0), + paddingX(0), + paddingY(0) {} + BorderedRectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h, + unsigned int _borderWidth, unsigned int _borderHeight, unsigned int _paddingX, unsigned int _paddingY) : + RectElement(x, y, w, h), + borderWidth(_borderWidth), + borderHeight(_borderHeight), + paddingX(_paddingX), + paddingY(_paddingY) {} + unsigned int borderWidth; + unsigned int borderHeight; + unsigned int paddingX; + unsigned int paddingY; + }; - struct RectElement { - RectElement() {} - RectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h) : pos(x,y), size(w,h) {} - Point pos; - Point size; + struct EdgedRectElement : public RectElement { + EdgedRectElement() : + edgeWidth(0) {} + EdgedRectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int _edgeWidth) : + RectElement(x, y, w, h), + edgeWidth(_edgeWidth) {} + unsigned int edgeWidth; + }; + + const BorderedRectElement &BackgroundNormal() const { return m_backgroundNormal; } + const BorderedRectElement &BackgroundActive() const { return m_backgroundActive; } + + const BorderedRectElement &ButtonDisabled() const { return m_buttonDisabled; } + const BorderedRectElement &ButtonNormal() const { return m_buttonNormal; } + const BorderedRectElement &ButtonHover() const { return m_buttonHover; } + const BorderedRectElement &ButtonActive() const { return m_buttonActive; } + + const Color &ButtonHidden() const { return m_buttonHidden; } + const Color &SmallButtonHidden() const { return m_smallButtonHidden; } + + const RectElement &SmallButtonDisabled() const { return m_smallButtonDisabled; } + const RectElement &SmallButtonNormal() const { return m_smallButtonNormal; } + const RectElement &SmallButtonHover() const { return m_smallButtonHover; } + const RectElement &SmallButtonActive() const { return m_smallButtonActive; } + + const RectElement &CheckboxDisabled() const { return m_checkboxDisabled; } + const RectElement &CheckboxNormal() const { return m_checkboxNormal; } + const RectElement &CheckboxHover() const { return m_checkboxHover; } + const RectElement &CheckboxActive() const { return m_checkboxActive; } + const RectElement &CheckboxCheckedDisabled() const { return m_checkboxCheckedDisabled; } + const RectElement &CheckboxCheckedNormal() const { return m_checkboxCheckedNormal; } + const RectElement &CheckboxCheckedHover() const { return m_checkboxCheckedHover; } + const RectElement &CheckboxCheckedActive() const { return m_checkboxCheckedActive; } + + const EdgedRectElement &SliderVerticalGutter() const { return m_sliderVerticalGutter; } + const EdgedRectElement &SliderHorizontalGutter() const { return m_sliderHorizontalGutter; } + const RectElement &SliderVerticalButtonNormal() const { return m_sliderVerticalButtonNormal; } + const RectElement &SliderVerticalButtonHover() const { return m_sliderVerticalButtonHover; } + const RectElement &SliderVerticalButtonActive() const { return m_sliderVerticalButtonActive; } + const RectElement &SliderHorizontalButtonNormal() const { return m_sliderHorizontalButtonNormal; } + const RectElement &SliderHorizontalButtonHover() const { return m_sliderHorizontalButtonHover; } + const RectElement &SliderHorizontalButtonActive() const { return m_sliderHorizontalButtonActive; } + + const EdgedRectElement &GaugeBackground() const { return m_gaugeBackground; } + const EdgedRectElement &GaugeMask() const { return m_gaugeMask; } + const RectElement &GaugeFillNormal() const { return m_gaugeFillNormal; } + const RectElement &GaugeFillWarning() const { return m_gaugeFillWarning; } + const RectElement &GaugeFillCritical() const { return m_gaugeFillCritical; } + + unsigned int ButtonMinInnerSize() const { return m_buttonMinInnerSize; } + + Color GetNormalColor() const { return m_normalColor; } + Color GetHoverColor() const { return m_hoverColor; } + Color GetSelectColor() const { return m_selectColor; } + + Graphics::RenderState *GetAlphaBlendState() const { return m_alphaBlendState; } + Graphics::RenderState *GetRenderState(Graphics::BlendMode) const; + + private: + Graphics::Renderer *m_renderer; + + float m_scale; + + RefCountedPtr m_texture; + RefCountedPtr m_textureMaterial; + RefCountedPtr m_colorMaterial; + + float m_opacity; + + Graphics::RenderState *m_alphaBlendState; + Graphics::RenderState *m_alphaSetState; + Graphics::RenderState *m_alphaMaskState; + + void DrawRectElement(const RectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; + void DrawBorderedRectElement(const BorderedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; + void DrawVerticalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; + void DrawHorizontalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; + + RectElement LoadRectElement(const std::string &spec); + BorderedRectElement LoadBorderedRectElement(const std::string &spec); + EdgedRectElement LoadEdgedRectElement(const std::string &spec); + Color LoadSkinColor(const std::string &spec); + + BorderedRectElement m_backgroundNormal; + BorderedRectElement m_backgroundActive; + + BorderedRectElement m_buttonDisabled; + BorderedRectElement m_buttonNormal; + BorderedRectElement m_buttonHover; + BorderedRectElement m_buttonActive; + + // Used by Disable() button, to also hide border, and fill color + Color m_buttonHidden; + Color m_smallButtonHidden; + + RectElement m_smallButtonDisabled; + RectElement m_smallButtonNormal; + RectElement m_smallButtonHover; + RectElement m_smallButtonActive; + + RectElement m_checkboxDisabled; + RectElement m_checkboxNormal; + RectElement m_checkboxHover; + RectElement m_checkboxActive; + + RectElement m_checkboxCheckedDisabled; + RectElement m_checkboxCheckedNormal; + RectElement m_checkboxCheckedHover; + RectElement m_checkboxCheckedActive; + + EdgedRectElement m_sliderVerticalGutter; + EdgedRectElement m_sliderHorizontalGutter; + RectElement m_sliderVerticalButtonNormal; + RectElement m_sliderVerticalButtonHover; + RectElement m_sliderVerticalButtonActive; + RectElement m_sliderHorizontalButtonNormal; + RectElement m_sliderHorizontalButtonHover; + RectElement m_sliderHorizontalButtonActive; + + EdgedRectElement m_gaugeBackground; + EdgedRectElement m_gaugeMask; + RectElement m_gaugeFillNormal; + RectElement m_gaugeFillWarning; + RectElement m_gaugeFillCritical; + + unsigned int m_buttonMinInnerSize; + + Color m_normalColor; + Color m_hoverColor; + Color m_selectColor; }; - struct BorderedRectElement : public RectElement { - BorderedRectElement() : borderWidth(0), borderHeight(0), paddingX(0), paddingY(0) {} - BorderedRectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h, - unsigned int _borderWidth, unsigned int _borderHeight, unsigned int _paddingX, unsigned int _paddingY) : - RectElement(x, y, w, h), borderWidth(_borderWidth), borderHeight(_borderHeight), paddingX(_paddingX), paddingY(_paddingY) {} - unsigned int borderWidth; - unsigned int borderHeight; - unsigned int paddingX; - unsigned int paddingY; - }; - - struct EdgedRectElement : public RectElement { - EdgedRectElement() : edgeWidth(0) {} - EdgedRectElement(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int _edgeWidth) : - RectElement(x, y, w, h), edgeWidth(_edgeWidth) {} - unsigned int edgeWidth; - }; - - const BorderedRectElement &BackgroundNormal() const { return m_backgroundNormal; } - const BorderedRectElement &BackgroundActive() const { return m_backgroundActive; } - - const BorderedRectElement &ButtonDisabled() const { return m_buttonDisabled; } - const BorderedRectElement &ButtonNormal() const { return m_buttonNormal; } - const BorderedRectElement &ButtonHover() const { return m_buttonHover; } - const BorderedRectElement &ButtonActive() const { return m_buttonActive; } - - const Color &ButtonHidden() const { return m_buttonHidden; } - const Color &SmallButtonHidden() const { return m_smallButtonHidden; } - - const RectElement &SmallButtonDisabled() const { return m_smallButtonDisabled; } - const RectElement &SmallButtonNormal() const { return m_smallButtonNormal; } - const RectElement &SmallButtonHover() const { return m_smallButtonHover; } - const RectElement &SmallButtonActive() const { return m_smallButtonActive; } - - const RectElement &CheckboxDisabled() const { return m_checkboxDisabled; } - const RectElement &CheckboxNormal() const { return m_checkboxNormal; } - const RectElement &CheckboxHover() const { return m_checkboxHover; } - const RectElement &CheckboxActive() const { return m_checkboxActive; } - const RectElement &CheckboxCheckedDisabled() const { return m_checkboxCheckedDisabled; } - const RectElement &CheckboxCheckedNormal() const { return m_checkboxCheckedNormal; } - const RectElement &CheckboxCheckedHover() const { return m_checkboxCheckedHover; } - const RectElement &CheckboxCheckedActive() const { return m_checkboxCheckedActive; } - - const EdgedRectElement &SliderVerticalGutter() const { return m_sliderVerticalGutter; } - const EdgedRectElement &SliderHorizontalGutter() const { return m_sliderHorizontalGutter; } - const RectElement &SliderVerticalButtonNormal() const { return m_sliderVerticalButtonNormal; } - const RectElement &SliderVerticalButtonHover() const { return m_sliderVerticalButtonHover; } - const RectElement &SliderVerticalButtonActive() const { return m_sliderVerticalButtonActive; } - const RectElement &SliderHorizontalButtonNormal() const { return m_sliderHorizontalButtonNormal; } - const RectElement &SliderHorizontalButtonHover() const { return m_sliderHorizontalButtonHover; } - const RectElement &SliderHorizontalButtonActive() const { return m_sliderHorizontalButtonActive; } - - const EdgedRectElement &GaugeBackground() const { return m_gaugeBackground; } - const EdgedRectElement &GaugeMask() const { return m_gaugeMask; } - const RectElement &GaugeFillNormal() const { return m_gaugeFillNormal; } - const RectElement &GaugeFillWarning() const { return m_gaugeFillWarning; } - const RectElement &GaugeFillCritical() const { return m_gaugeFillCritical; } - - unsigned int ButtonMinInnerSize() const { return m_buttonMinInnerSize; } - - Color GetNormalColor() const { return m_normalColor; } - Color GetHoverColor() const { return m_hoverColor; } - Color GetSelectColor() const { return m_selectColor; } - - Graphics::RenderState *GetAlphaBlendState() const { return m_alphaBlendState; } - Graphics::RenderState *GetRenderState(Graphics::BlendMode) const; - -private: - Graphics::Renderer *m_renderer; - - float m_scale; - - RefCountedPtr m_texture; - RefCountedPtr m_textureMaterial; - RefCountedPtr m_colorMaterial; - - float m_opacity; - - Graphics::RenderState *m_alphaBlendState; - Graphics::RenderState *m_alphaSetState; - Graphics::RenderState *m_alphaMaskState; - - void DrawRectElement(const RectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; - void DrawBorderedRectElement(const BorderedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; - void DrawVerticalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; - void DrawHorizontalEdgedRectElement(const EdgedRectElement &element, const Point &pos, const Point &size, Graphics::BlendMode blendMode = Graphics::BLEND_ALPHA) const; - - RectElement LoadRectElement(const std::string &spec); - BorderedRectElement LoadBorderedRectElement(const std::string &spec); - EdgedRectElement LoadEdgedRectElement(const std::string &spec); - Color LoadSkinColor(const std::string &spec); - - BorderedRectElement m_backgroundNormal; - BorderedRectElement m_backgroundActive; - - BorderedRectElement m_buttonDisabled; - BorderedRectElement m_buttonNormal; - BorderedRectElement m_buttonHover; - BorderedRectElement m_buttonActive; - - // Used by Disable() button, to also hide border, and fill color - Color m_buttonHidden; - Color m_smallButtonHidden; - - RectElement m_smallButtonDisabled; - RectElement m_smallButtonNormal; - RectElement m_smallButtonHover; - RectElement m_smallButtonActive; - - RectElement m_checkboxDisabled; - RectElement m_checkboxNormal; - RectElement m_checkboxHover; - RectElement m_checkboxActive; - - RectElement m_checkboxCheckedDisabled; - RectElement m_checkboxCheckedNormal; - RectElement m_checkboxCheckedHover; - RectElement m_checkboxCheckedActive; - - EdgedRectElement m_sliderVerticalGutter; - EdgedRectElement m_sliderHorizontalGutter; - RectElement m_sliderVerticalButtonNormal; - RectElement m_sliderVerticalButtonHover; - RectElement m_sliderVerticalButtonActive; - RectElement m_sliderHorizontalButtonNormal; - RectElement m_sliderHorizontalButtonHover; - RectElement m_sliderHorizontalButtonActive; - - EdgedRectElement m_gaugeBackground; - EdgedRectElement m_gaugeMask; - RectElement m_gaugeFillNormal; - RectElement m_gaugeFillWarning; - RectElement m_gaugeFillCritical; - - unsigned int m_buttonMinInnerSize; - - Color m_normalColor; - Color m_hoverColor; - Color m_selectColor; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Slider.cpp b/src/ui/Slider.cpp index dffcf3dc0..f13c3312e 100644 --- a/src/ui/Slider.cpp +++ b/src/ui/Slider.cpp @@ -6,191 +6,189 @@ namespace UI { -Point Slider::PreferredSize() -{ - const Skin &skin = GetContext()->GetSkin(); - - if (m_orient == SLIDER_HORIZONTAL) { - SetSizeControlFlags(EXPAND_WIDTH); - return skin.SliderHorizontalButtonNormal().size; - } - - SetSizeControlFlags(EXPAND_HEIGHT); - return skin.SliderVerticalButtonNormal().size; -} - -void Slider::Layout() -{ - const Skin &skin = GetContext()->GetSkin(); - const Point &activeArea = GetActiveArea(); - - if (m_orient == SLIDER_HORIZONTAL) { - const Skin::EdgedRectElement &gutterRect = skin.SliderHorizontalGutter(); - m_gutterPos = Point(0, (activeArea.y-gutterRect.size.y)/2); - m_gutterSize = Point(activeArea.x, gutterRect.size.y); - } - else { - const Skin::EdgedRectElement &gutterRect = skin.SliderVerticalGutter(); - m_gutterPos = Point((activeArea.x-gutterRect.size.x)/2, 0); - m_gutterSize = Point(gutterRect.size.x, activeArea.y); - } - - UpdateButton(); - Widget::Layout(); -} - -void Slider::UpdateButton() -{ - const Skin &skin = GetContext()->GetSkin(); - - const Point activeArea(GetActiveArea()); - - const float normalisedValue = (m_value - m_rangeMin) / (m_rangeMax - m_rangeMin); - - if (m_orient == SLIDER_HORIZONTAL) { - const Skin::EdgedRectElement &gutterRect = skin.SliderHorizontalGutter(); - const Skin::RectElement &buttonRect = skin.SliderHorizontalButtonNormal(); - - m_buttonSize = Point(buttonRect.size.x, buttonRect.size.y); - m_buttonPos = Point(((activeArea.x-gutterRect.edgeWidth*2-buttonRect.size.x)*normalisedValue)+gutterRect.edgeWidth, (activeArea.y-buttonRect.size.y)/2); - } - - else { - const Skin::EdgedRectElement &gutterRect = skin.SliderVerticalGutter(); - const Skin::RectElement &buttonRect = skin.SliderVerticalButtonNormal(); - - m_buttonSize = Point(buttonRect.size.x, buttonRect.size.y); - m_buttonPos = Point((activeArea.x-buttonRect.size.x)/2, ((activeArea.y-gutterRect.edgeWidth*2-buttonRect.size.y)*normalisedValue)+gutterRect.edgeWidth); - } - - m_mouseOverButton = IsMouseOver() && PointInsideButton(m_lastMousePosition); -} - -void Slider::Draw() -{ - const Skin &skin = GetContext()->GetSkin(); - - if (m_orient == SLIDER_HORIZONTAL) { - skin.DrawSliderHorizontalGutter(m_gutterPos, m_gutterSize); - if (m_buttonDown && IsMouseActive()) - skin.DrawSliderHorizontalButtonActive(m_buttonPos, m_buttonSize); - else if (m_mouseOverButton) - skin.DrawSliderHorizontalButtonHover(m_buttonPos, m_buttonSize); - else - skin.DrawSliderHorizontalButtonNormal(m_buttonPos, m_buttonSize); - } - - else { - skin.DrawSliderVerticalGutter(m_gutterPos, m_gutterSize); - if (m_buttonDown && IsMouseActive()) - skin.DrawSliderVerticalButtonActive(m_buttonPos, m_buttonSize); - else if (m_mouseOverButton) - skin.DrawSliderVerticalButtonHover(m_buttonPos, m_buttonSize); - else - skin.DrawSliderVerticalButtonNormal(m_buttonPos, m_buttonSize); - } -} - -bool Slider::PointInsideButton(const Point &p) -{ - return p.x >= m_buttonPos.x && p.y >= m_buttonPos.y && p.x < m_buttonPos.x+m_buttonSize.x && p.y <= m_buttonPos.y+m_buttonSize.y; -} - -void Slider::SetValue(float v) -{ - m_value = Clamp(v, m_rangeMin, m_rangeMax); - onValueChanged.emit(m_value); - UpdateButton(); -} - -Slider *Slider::SetRange(float min, float max) -{ - assert(min < max); - if (!is_equal_exact(m_rangeMin, min) || !is_equal_exact(m_rangeMax, max)) { - m_rangeMin = min; - m_rangeMax = max; - m_value = Clamp(m_value, m_rangeMin, m_rangeMax); - onValueChanged.emit(m_value); - UpdateButton(); - } - return this; -} - -void Slider::HandleMouseDown(const MouseButtonEvent &event) -{ - m_buttonDown = PointInsideButton(event.pos); - - if (!m_buttonDown) { - float change = 0.0f; + Point Slider::PreferredSize() + { + const Skin &skin = GetContext()->GetSkin(); if (m_orient == SLIDER_HORIZONTAL) { - if (m_lastMousePosition.x < m_buttonPos.x) - change = -0.1f; - else - change = 0.1f; - } - else { - if (m_lastMousePosition.y < m_buttonPos.y) - change = -0.1f; - else - change = 0.1f; + SetSizeControlFlags(EXPAND_WIDTH); + return skin.SliderHorizontalButtonNormal().size; } - SetValue(GetValue()+change); + SetSizeControlFlags(EXPAND_HEIGHT); + return skin.SliderVerticalButtonNormal().size; } - Widget::HandleMouseDown(event); -} + void Slider::Layout() + { + const Skin &skin = GetContext()->GetSkin(); + const Point &activeArea = GetActiveArea(); -void Slider::HandleMouseUp(const MouseButtonEvent &event) -{ - m_buttonDown = false; - Widget::HandleMouseUp(event); -} + if (m_orient == SLIDER_HORIZONTAL) { + const Skin::EdgedRectElement &gutterRect = skin.SliderHorizontalGutter(); + m_gutterPos = Point(0, (activeArea.y - gutterRect.size.y) / 2); + m_gutterSize = Point(activeArea.x, gutterRect.size.y); + } else { + const Skin::EdgedRectElement &gutterRect = skin.SliderVerticalGutter(); + m_gutterPos = Point((activeArea.x - gutterRect.size.x) / 2, 0); + m_gutterSize = Point(gutterRect.size.x, activeArea.y); + } -void Slider::HandleMouseMove(const MouseMotionEvent &event) -{ - const Skin &skin = GetContext()->GetSkin(); + UpdateButton(); + Widget::Layout(); + } - if (m_buttonDown && IsMouseActive()) { + void Slider::UpdateButton() + { + const Skin &skin = GetContext()->GetSkin(); - float travel; + const Point activeArea(GetActiveArea()); + + const float normalisedValue = (m_value - m_rangeMin) / (m_rangeMax - m_rangeMin); if (m_orient == SLIDER_HORIZONTAL) { const Skin::EdgedRectElement &gutterRect = skin.SliderHorizontalGutter(); const Skin::RectElement &buttonRect = skin.SliderHorizontalButtonNormal(); - const int effectiveLength = GetActiveArea().x - gutterRect.edgeWidth*2 - buttonRect.size.x; - const int pos = Clamp(event.pos.x - int(gutterRect.edgeWidth) - buttonRect.size.x/2 - GetActiveOffset().x, 0, effectiveLength); - - travel = float(pos) / effectiveLength; + m_buttonSize = Point(buttonRect.size.x, buttonRect.size.y); + m_buttonPos = Point(((activeArea.x - gutterRect.edgeWidth * 2 - buttonRect.size.x) * normalisedValue) + gutterRect.edgeWidth, (activeArea.y - buttonRect.size.y) / 2); } else { const Skin::EdgedRectElement &gutterRect = skin.SliderVerticalGutter(); const Skin::RectElement &buttonRect = skin.SliderVerticalButtonNormal(); - const int effectiveLength = GetActiveArea().y - gutterRect.edgeWidth*2 - buttonRect.size.y; - const int pos = Clamp(event.pos.y - int(gutterRect.edgeWidth) - buttonRect.size.y/2 - GetActiveOffset().y, 0, effectiveLength); - - travel = float(pos) / effectiveLength; + m_buttonSize = Point(buttonRect.size.x, buttonRect.size.y); + m_buttonPos = Point((activeArea.x - buttonRect.size.x) / 2, ((activeArea.y - gutterRect.edgeWidth * 2 - buttonRect.size.y) * normalisedValue) + gutterRect.edgeWidth); } - SetValue(travel*(m_rangeMax - m_rangeMin) + m_rangeMin); + m_mouseOverButton = IsMouseOver() && PointInsideButton(m_lastMousePosition); } - else { - m_lastMousePosition = event.pos; - m_mouseOverButton = PointInsideButton(event.pos); + void Slider::Draw() + { + const Skin &skin = GetContext()->GetSkin(); + + if (m_orient == SLIDER_HORIZONTAL) { + skin.DrawSliderHorizontalGutter(m_gutterPos, m_gutterSize); + if (m_buttonDown && IsMouseActive()) + skin.DrawSliderHorizontalButtonActive(m_buttonPos, m_buttonSize); + else if (m_mouseOverButton) + skin.DrawSliderHorizontalButtonHover(m_buttonPos, m_buttonSize); + else + skin.DrawSliderHorizontalButtonNormal(m_buttonPos, m_buttonSize); + } + + else { + skin.DrawSliderVerticalGutter(m_gutterPos, m_gutterSize); + if (m_buttonDown && IsMouseActive()) + skin.DrawSliderVerticalButtonActive(m_buttonPos, m_buttonSize); + else if (m_mouseOverButton) + skin.DrawSliderVerticalButtonHover(m_buttonPos, m_buttonSize); + else + skin.DrawSliderVerticalButtonNormal(m_buttonPos, m_buttonSize); + } } - Widget::HandleMouseMove(event); -} + bool Slider::PointInsideButton(const Point &p) + { + return p.x >= m_buttonPos.x && p.y >= m_buttonPos.y && p.x < m_buttonPos.x + m_buttonSize.x && p.y <= m_buttonPos.y + m_buttonSize.y; + } -void Slider::HandleMouseOut() -{ - m_mouseOverButton = false; - Widget::HandleMouseOut(); -} + void Slider::SetValue(float v) + { + m_value = Clamp(v, m_rangeMin, m_rangeMax); + onValueChanged.emit(m_value); + UpdateButton(); + } -} + Slider *Slider::SetRange(float min, float max) + { + assert(min < max); + if (!is_equal_exact(m_rangeMin, min) || !is_equal_exact(m_rangeMax, max)) { + m_rangeMin = min; + m_rangeMax = max; + m_value = Clamp(m_value, m_rangeMin, m_rangeMax); + onValueChanged.emit(m_value); + UpdateButton(); + } + return this; + } + + void Slider::HandleMouseDown(const MouseButtonEvent &event) + { + m_buttonDown = PointInsideButton(event.pos); + + if (!m_buttonDown) { + float change = 0.0f; + + if (m_orient == SLIDER_HORIZONTAL) { + if (m_lastMousePosition.x < m_buttonPos.x) + change = -0.1f; + else + change = 0.1f; + } else { + if (m_lastMousePosition.y < m_buttonPos.y) + change = -0.1f; + else + change = 0.1f; + } + + SetValue(GetValue() + change); + } + + Widget::HandleMouseDown(event); + } + + void Slider::HandleMouseUp(const MouseButtonEvent &event) + { + m_buttonDown = false; + Widget::HandleMouseUp(event); + } + + void Slider::HandleMouseMove(const MouseMotionEvent &event) + { + const Skin &skin = GetContext()->GetSkin(); + + if (m_buttonDown && IsMouseActive()) { + + float travel; + + if (m_orient == SLIDER_HORIZONTAL) { + const Skin::EdgedRectElement &gutterRect = skin.SliderHorizontalGutter(); + const Skin::RectElement &buttonRect = skin.SliderHorizontalButtonNormal(); + + const int effectiveLength = GetActiveArea().x - gutterRect.edgeWidth * 2 - buttonRect.size.x; + const int pos = Clamp(event.pos.x - int(gutterRect.edgeWidth) - buttonRect.size.x / 2 - GetActiveOffset().x, 0, effectiveLength); + + travel = float(pos) / effectiveLength; + } + + else { + const Skin::EdgedRectElement &gutterRect = skin.SliderVerticalGutter(); + const Skin::RectElement &buttonRect = skin.SliderVerticalButtonNormal(); + + const int effectiveLength = GetActiveArea().y - gutterRect.edgeWidth * 2 - buttonRect.size.y; + const int pos = Clamp(event.pos.y - int(gutterRect.edgeWidth) - buttonRect.size.y / 2 - GetActiveOffset().y, 0, effectiveLength); + + travel = float(pos) / effectiveLength; + } + + SetValue(travel * (m_rangeMax - m_rangeMin) + m_rangeMin); + } + + else { + m_lastMousePosition = event.pos; + m_mouseOverButton = PointInsideButton(event.pos); + } + + Widget::HandleMouseMove(event); + } + + void Slider::HandleMouseOut() + { + m_mouseOverButton = false; + Widget::HandleMouseOut(); + } + +} // namespace UI diff --git a/src/ui/Slider.h b/src/ui/Slider.h index 1f8f57937..2a4c15299 100644 --- a/src/ui/Slider.h +++ b/src/ui/Slider.h @@ -8,68 +8,83 @@ namespace UI { -class Slider: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class Slider : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); - float GetValue() const { return m_value; } - void SetValue(float v); + float GetValue() const { return m_value; } + void SetValue(float v); - void GetRange(float &out_min, float &out_max) { out_min = m_rangeMin; out_max = m_rangeMax; } - Slider *SetRange(float min, float max); + void GetRange(float &out_min, float &out_max) + { + out_min = m_rangeMin; + out_max = m_rangeMax; + } + Slider *SetRange(float min, float max); - Slider *SetStep(float step) { m_step = step; return this; } - void StepUp() { SetValue(m_value - m_step); } - void StepDown() { SetValue(m_value + m_step); } + Slider *SetStep(float step) + { + m_step = step; + return this; + } + void StepUp() { SetValue(m_value - m_step); } + void StepDown() { SetValue(m_value + m_step); } - sigc::signal onValueChanged; + sigc::signal onValueChanged; -protected: - enum SliderOrientation { - SLIDER_HORIZONTAL, - SLIDER_VERTICAL + protected: + enum SliderOrientation { + SLIDER_HORIZONTAL, + SLIDER_VERTICAL + }; + + Slider(Context *context, SliderOrientation orient) : + Widget(context), + m_orient(orient), + m_rangeMin(0.0f), + m_rangeMax(1.0f), + m_step(0.1f), + m_value(0.0f), + m_buttonDown(false), + m_mouseOverButton(false) {} + + virtual void HandleMouseDown(const MouseButtonEvent &event); + virtual void HandleMouseUp(const MouseButtonEvent &event); + virtual void HandleMouseMove(const MouseMotionEvent &event); + virtual void HandleMouseOut(); + + private: + void UpdateButton(); + bool PointInsideButton(const Point &p); + + SliderOrientation m_orient; + float m_rangeMin; + float m_rangeMax; + float m_step; + float m_value; + Point m_gutterPos, m_gutterSize; + Point m_buttonPos, m_buttonSize; + Point m_lastMousePosition; + bool m_buttonDown; + bool m_mouseOverButton; }; - Slider(Context *context, SliderOrientation orient) : - Widget(context), m_orient(orient), - m_rangeMin(0.0f), m_rangeMax(1.0f), m_step(0.1f), m_value(0.0f), - m_buttonDown(false), m_mouseOverButton(false) {} + class HSlider : public Slider { + protected: + friend class Context; + HSlider(Context *context) : + Slider(context, SLIDER_HORIZONTAL) {} + }; - virtual void HandleMouseDown(const MouseButtonEvent &event); - virtual void HandleMouseUp(const MouseButtonEvent &event); - virtual void HandleMouseMove(const MouseMotionEvent &event); - virtual void HandleMouseOut(); + class VSlider : public Slider { + protected: + friend class Context; + VSlider(Context *context) : + Slider(context, SLIDER_VERTICAL) {} + }; -private: - void UpdateButton(); - bool PointInsideButton(const Point &p); - - SliderOrientation m_orient; - float m_rangeMin; - float m_rangeMax; - float m_step; - float m_value; - Point m_gutterPos, m_gutterSize; - Point m_buttonPos, m_buttonSize; - Point m_lastMousePosition; - bool m_buttonDown; - bool m_mouseOverButton; -}; - -class HSlider: public Slider { -protected: - friend class Context; - HSlider(Context *context) : Slider(context, SLIDER_HORIZONTAL) {} -}; - -class VSlider: public Slider { -protected: - friend class Context; - VSlider(Context *context) : Slider(context, SLIDER_VERTICAL) {} -}; - -} +} // namespace UI #endif diff --git a/src/ui/SmallButton.cpp b/src/ui/SmallButton.cpp index 2ee23ce8f..1c88f0904 100644 --- a/src/ui/SmallButton.cpp +++ b/src/ui/SmallButton.cpp @@ -7,28 +7,28 @@ namespace UI { -Point SmallButton::PreferredSize() -{ - return GetContext()->GetSkin().CheckboxNormal().size; -} + Point SmallButton::PreferredSize() + { + return GetContext()->GetSkin().CheckboxNormal().size; + } -void SmallButton::Layout() -{ - SetActiveArea(PreferredSize()); -} + void SmallButton::Layout() + { + SetActiveArea(PreferredSize()); + } -void SmallButton::Draw() -{ - if (IsDisabled()) - GetContext()->GetSkin().DrawSmallButtonDisabled(GetActiveOffset(), GetActiveArea()); - else if (IsHidden()) - GetContext()->GetSkin().DrawSmallButtonHidden(GetActiveOffset(), GetActiveArea()); - else if (IsMouseActive()) - GetContext()->GetSkin().DrawSmallButtonActive(GetActiveOffset(), GetActiveArea()); - else if (IsMouseOver()) - GetContext()->GetSkin().DrawSmallButtonHover(GetActiveOffset(), GetActiveArea()); - else - GetContext()->GetSkin().DrawSmallButtonNormal(GetActiveOffset(), GetActiveArea()); -} + void SmallButton::Draw() + { + if (IsDisabled()) + GetContext()->GetSkin().DrawSmallButtonDisabled(GetActiveOffset(), GetActiveArea()); + else if (IsHidden()) + GetContext()->GetSkin().DrawSmallButtonHidden(GetActiveOffset(), GetActiveArea()); + else if (IsMouseActive()) + GetContext()->GetSkin().DrawSmallButtonActive(GetActiveOffset(), GetActiveArea()); + else if (IsMouseOver()) + GetContext()->GetSkin().DrawSmallButtonHover(GetActiveOffset(), GetActiveArea()); + else + GetContext()->GetSkin().DrawSmallButtonNormal(GetActiveOffset(), GetActiveArea()); + } -} +} // namespace UI diff --git a/src/ui/SmallButton.h b/src/ui/SmallButton.h index 2295d128b..802d83157 100644 --- a/src/ui/SmallButton.h +++ b/src/ui/SmallButton.h @@ -8,17 +8,18 @@ namespace UI { -class SmallButton: public Widget { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Draw(); + class SmallButton : public Widget { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); -protected: - friend class Context; - SmallButton(Context *context): Widget(context) {} -}; + protected: + friend class Context; + SmallButton(Context *context) : + Widget(context) {} + }; -} +} // namespace UI #endif diff --git a/src/ui/Table.cpp b/src/ui/Table.cpp index 183f9aacb..49d5065c0 100644 --- a/src/ui/Table.cpp +++ b/src/ui/Table.cpp @@ -9,159 +9,161 @@ namespace UI { -void Table::LayoutAccumulator::AddRow(const std::vector &widgets) -{ - if (m_columnWidth.size() < widgets.size()) { - std::size_t i = m_columnWidth.size(); - m_columnWidth.resize(widgets.size()); - for (; i < widgets.size(); i++) - m_columnWidth[i] = 0; - } - - m_preferredWidth = 0; - for (std::size_t i = 0; i < m_columnWidth.size(); i++) { - if (i < widgets.size()) { - Widget *w = widgets[i]; - if (w) { - const Point size(w->CalcLayoutContribution()); - m_columnWidth[i] = std::max(m_columnWidth[i], size.x); - } + void Table::LayoutAccumulator::AddRow(const std::vector &widgets) + { + if (m_columnWidth.size() < widgets.size()) { + std::size_t i = m_columnWidth.size(); + m_columnWidth.resize(widgets.size()); + for (; i < widgets.size(); i++) + m_columnWidth[i] = 0; } - m_preferredWidth = SizeAdd(SizeAdd(m_preferredWidth, m_columnWidth[i]), m_columnSpacing); - } - m_preferredWidth = SizeAdd(m_preferredWidth, -m_columnSpacing); -} -void Table::LayoutAccumulator::Clear() -{ - m_columnWidth.clear(); - m_columnLeft.clear(); - m_preferredWidth = 0; -} - -void Table::LayoutAccumulator::ComputeForWidth(int availWidth) { - if (m_columnWidth.empty()) - return; - - if (m_preferredWidth == SIZE_EXPAND) { - int fixedSize = m_columnSpacing * (m_columnWidth.size()-1); - int numExpand = 0; - for (std::size_t i = 0; i < m_columnWidth.size(); i++) - if (m_columnWidth[i] == SIZE_EXPAND) - numExpand++; - else - fixedSize += m_columnWidth[i]; - assert(numExpand > 0); - int expandSize = (availWidth-fixedSize) / numExpand; - for (std::size_t i = 0; i < m_columnWidth.size(); i++) - if (m_columnWidth[i] == SIZE_EXPAND) - m_columnWidth[i] = expandSize; + m_preferredWidth = 0; + for (std::size_t i = 0; i < m_columnWidth.size(); i++) { + if (i < widgets.size()) { + Widget *w = widgets[i]; + if (w) { + const Point size(w->CalcLayoutContribution()); + m_columnWidth[i] = std::max(m_columnWidth[i], size.x); + } + } + m_preferredWidth = SizeAdd(SizeAdd(m_preferredWidth, m_columnWidth[i]), m_columnSpacing); + } + m_preferredWidth = SizeAdd(m_preferredWidth, -m_columnSpacing); } - m_columnLeft.resize(m_columnWidth.size()); + void Table::LayoutAccumulator::Clear() + { + m_columnWidth.clear(); + m_columnLeft.clear(); + m_preferredWidth = 0; + } - switch (m_columnAlignment) { + void Table::LayoutAccumulator::ComputeForWidth(int availWidth) + { + if (m_columnWidth.empty()) + return; + + if (m_preferredWidth == SIZE_EXPAND) { + int fixedSize = m_columnSpacing * (m_columnWidth.size() - 1); + int numExpand = 0; + for (std::size_t i = 0; i < m_columnWidth.size(); i++) + if (m_columnWidth[i] == SIZE_EXPAND) + numExpand++; + else + fixedSize += m_columnWidth[i]; + assert(numExpand > 0); + int expandSize = (availWidth - fixedSize) / numExpand; + for (std::size_t i = 0; i < m_columnWidth.size(); i++) + if (m_columnWidth[i] == SIZE_EXPAND) + m_columnWidth[i] = expandSize; + } + + m_columnLeft.resize(m_columnWidth.size()); + + switch (m_columnAlignment) { case COLUMN_LEFT: { m_columnLeft[0] = 0; if (m_columnWidth.size() > 1) for (std::size_t i = 1; i < m_columnWidth.size(); i++) - m_columnLeft[i] = m_columnLeft[i-1] + m_columnWidth[i-1] + m_columnSpacing; + m_columnLeft[i] = m_columnLeft[i - 1] + m_columnWidth[i - 1] + m_columnSpacing; break; } case COLUMN_CENTER: { - m_columnLeft[0] = (availWidth-m_preferredWidth)/2; + m_columnLeft[0] = (availWidth - m_preferredWidth) / 2; if (m_columnWidth.size() > 1) for (std::size_t i = 1; i < m_columnWidth.size(); i++) - m_columnLeft[i] = m_columnLeft[i-1] + m_columnWidth[i-1] + m_columnSpacing; + m_columnLeft[i] = m_columnLeft[i - 1] + m_columnWidth[i - 1] + m_columnSpacing; break; } case COLUMN_RIGHT: { m_columnLeft.back() = availWidth - m_columnWidth.back(); if (m_columnWidth.size() > 1) - for (int i = m_columnWidth.size()-2; i >= 0; i--) - m_columnLeft[i] = m_columnLeft[i+1] - m_columnSpacing - m_columnWidth[i]; + for (int i = m_columnWidth.size() - 2; i >= 0; i--) + m_columnLeft[i] = m_columnLeft[i + 1] - m_columnSpacing - m_columnWidth[i]; break; } case COLUMN_JUSTIFY: { m_columnLeft[0] = 0; if (m_columnWidth.size() > 1) { - int pad = availWidth > m_preferredWidth ? (availWidth-m_preferredWidth) / (m_columnWidth.size()-1) : 0; + int pad = availWidth > m_preferredWidth ? (availWidth - m_preferredWidth) / (m_columnWidth.size() - 1) : 0; for (std::size_t i = 1; i < m_columnWidth.size(); i++) - m_columnLeft[i] = m_columnLeft[i-1] + m_columnWidth[i-1] + m_columnSpacing + pad; + m_columnLeft[i] = m_columnLeft[i - 1] + m_columnWidth[i - 1] + m_columnSpacing + pad; } break; } - } -} - -Table::Inner::Inner(Context *context, LayoutAccumulator &layout) : Container(context), - m_layout(layout), - m_rowSpacing(0), - m_rowAlignment(ROW_TOP), - m_dirty(false), - m_mouseEnabled(false) -{ -} - -Point Table::Inner::PreferredSize() -{ - if (!m_dirty) - return m_preferredSize; - - if (m_layout.Empty()) { - m_preferredSize = Point(); - return m_preferredSize; - } - - m_preferredSize.x = m_layout.GetPreferredWidth(); - m_preferredSize.y = 0; - - m_rowHeight.resize(m_rows.size()); - - for (std::size_t i = 0; i < m_rows.size(); i++) { - const std::vector &row = m_rows[i]; - m_rowHeight[i] = 0; - for (std::size_t j = 0; j < row.size(); j++) { - Widget *w = row[j]; - if (!w) continue; - Point size(w->CalcLayoutContribution()); - m_rowHeight[i] = std::max(m_rowHeight[i], size.y); } - m_preferredSize.y += m_rowHeight[i]; } - if (!m_rows.empty() && m_rowSpacing) - m_preferredSize.y += (m_rows.size()-1)*m_rowSpacing; + Table::Inner::Inner(Context *context, LayoutAccumulator &layout) : + Container(context), + m_layout(layout), + m_rowSpacing(0), + m_rowAlignment(ROW_TOP), + m_dirty(false), + m_mouseEnabled(false) + { + } - m_dirty = false; - return m_preferredSize; -} + Point Table::Inner::PreferredSize() + { + if (!m_dirty) + return m_preferredSize; -void Table::Inner::Layout() -{ - if (m_dirty) - PreferredSize(); + if (m_layout.Empty()) { + m_preferredSize = Point(); + return m_preferredSize; + } - int rowTop = 0; + m_preferredSize.x = m_layout.GetPreferredWidth(); + m_preferredSize.y = 0; - const std::vector &colWidth = m_layout.ColumnWidth(); - const std::vector &colLeft = m_layout.ColumnLeft(); + m_rowHeight.resize(m_rows.size()); - for (std::size_t i = 0; i < m_rows.size(); i++) { - const std::vector &row = m_rows[i]; - for (std::size_t j = 0; j < row.size(); j++) { - Widget *w = row[j]; - if (!w) continue; + for (std::size_t i = 0; i < m_rows.size(); i++) { + const std::vector &row = m_rows[i]; + m_rowHeight[i] = 0; + for (std::size_t j = 0; j < row.size(); j++) { + Widget *w = row[j]; + if (!w) continue; + Point size(w->CalcLayoutContribution()); + m_rowHeight[i] = std::max(m_rowHeight[i], size.y); + } + m_preferredSize.y += m_rowHeight[i]; + } - const Point preferredSize(w->PreferredSize()); - int height = std::min(preferredSize.y, m_rowHeight[i]); + if (!m_rows.empty() && m_rowSpacing) + m_preferredSize.y += (m_rows.size() - 1) * m_rowSpacing; - int off = 0; - if (height != m_rowHeight[i]) { - switch (m_rowAlignment) { + m_dirty = false; + return m_preferredSize; + } + + void Table::Inner::Layout() + { + if (m_dirty) + PreferredSize(); + + int rowTop = 0; + + const std::vector &colWidth = m_layout.ColumnWidth(); + const std::vector &colLeft = m_layout.ColumnLeft(); + + for (std::size_t i = 0; i < m_rows.size(); i++) { + const std::vector &row = m_rows[i]; + for (std::size_t j = 0; j < row.size(); j++) { + Widget *w = row[j]; + if (!w) continue; + + const Point preferredSize(w->PreferredSize()); + int height = std::min(preferredSize.y, m_rowHeight[i]); + + int off = 0; + if (height != m_rowHeight[i]) { + switch (m_rowAlignment) { case ROW_CENTER: off = (m_rowHeight[i] - height) / 2; break; @@ -171,292 +173,298 @@ void Table::Inner::Layout() default: off = 0; break; + } } + + SetWidgetDimensions(w, Point(colLeft[j], rowTop + off), Point(colWidth[j], height)); } - SetWidgetDimensions(w, Point(colLeft[j], rowTop+off), Point(colWidth[j], height)); + rowTop += m_rowHeight[i] + m_rowSpacing; } - rowTop += m_rowHeight[i] + m_rowSpacing; + LayoutChildren(); } - LayoutChildren(); -} - -void Table::Inner::Draw() -{ - int row_top, row_bottom; - if (m_mouseEnabled && IsMouseOver() && RowUnderPoint(GetMousePos(), &row_top, &row_bottom) >= 0) { - GetContext()->GetSkin().DrawRectHover(Point(0, row_top), Point(GetSize().x, row_bottom - row_top)); - } - - Container::Draw(); -} - -void Table::Inner::AddRow(const std::vector &widgets) -{ - m_rows.push_back(widgets); - - Point rowSize; - for (std::size_t i = 0; i < widgets.size(); i++) { - if (!widgets[i]) continue; - AddWidget(widgets[i]); - } - - m_dirty = true; -} - -void Table::Inner::Clear() -{ - for (std::vector< std::vector >::const_iterator i = m_rows.begin(); i != m_rows.end(); ++i) { - for (std::size_t j = 0; j < (*i).size(); j++) { - if (!(*i)[j]) continue; - RemoveWidget((*i)[j]); + void Table::Inner::Draw() + { + int row_top, row_bottom; + if (m_mouseEnabled && IsMouseOver() && RowUnderPoint(GetMousePos(), &row_top, &row_bottom) >= 0) { + GetContext()->GetSkin().DrawRectHover(Point(0, row_top), Point(GetSize().x, row_bottom - row_top)); } + + Container::Draw(); } - m_rows.clear(); - m_preferredSize = Point(); + void Table::Inner::AddRow(const std::vector &widgets) + { + m_rows.push_back(widgets); - m_dirty = false; -} - -void Table::Inner::AccumulateLayout() -{ - for (std::vector< std::vector >::const_iterator i = m_rows.begin(); i != m_rows.end(); ++i) - m_layout.AddRow(*i); - - m_dirty = true; -} - -void Table::Inner::SetRowSpacing(int spacing) -{ - m_rowSpacing = spacing; - m_dirty = true; -} - -void Table::Inner::SetRowAlignment(RowAlignDirection dir) -{ - m_rowAlignment = dir; - m_dirty = true; -} - -void Table::Inner::HandleClick() -{ - if (m_mouseEnabled) { - int row = RowUnderPoint(GetMousePos()); - if (row >= 0) - onRowClicked.emit(row); - } - - Container::HandleClick(); -} - -int Table::Inner::RowUnderPoint(const Point &pt, int *out_row_top, int *out_row_bottom) const -{ - int start = 0, end = m_rows.size()-1, mid = 0; - while (start <= end) { - mid = start+((end-start)/2); - - const Widget *w = m_rows[mid][0]; - const int rowTop = w->GetPosition().y; - const int rowBottom = rowTop + w->GetSize().y; - - if (pt.y < rowTop) - end = mid-1; - else if (pt.y >= rowBottom) - start = mid+1; - else { - if (out_row_top) { *out_row_top = rowTop; } - if (out_row_bottom) { *out_row_bottom = rowBottom; } - return mid; + Point rowSize; + for (std::size_t i = 0; i < widgets.size(); i++) { + if (!widgets[i]) continue; + AddWidget(widgets[i]); } + + m_dirty = true; } - if (out_row_top) { *out_row_top = 0; } - if (out_row_bottom) { *out_row_bottom = 0; } - return -1; -} + void Table::Inner::Clear() + { + for (std::vector>::const_iterator i = m_rows.begin(); i != m_rows.end(); ++i) { + for (std::size_t j = 0; j < (*i).size(); j++) { + if (!(*i)[j]) continue; + RemoveWidget((*i)[j]); + } + } - -Table::Table(Context *context) : Container(context), - m_dirty(false) -{ - m_header.Reset(new Table::Inner(GetContext(), m_layout)); - AddWidget(m_header.Get()); - - m_body.Reset(new Table::Inner(GetContext(), m_layout)); - AddWidget(m_body.Get()); - - m_body->onRowClicked.connect(sigc::mem_fun(&onRowClicked, &sigc::signal::emit)); - - m_slider.Reset(GetContext()->VSlider()); - m_slider->onValueChanged.connect(sigc::mem_fun(this, &Table::OnScroll)); -} - -Point Table::PreferredSize() -{ - if (m_dirty) { - m_layout.Clear(); - - m_header->AccumulateLayout(); - m_body->AccumulateLayout(); + m_rows.clear(); + m_preferredSize = Point(); m_dirty = false; } - const Point sliderSize = m_slider->PreferredSize(); + void Table::Inner::AccumulateLayout() + { + for (std::vector>::const_iterator i = m_rows.begin(); i != m_rows.end(); ++i) + m_layout.AddRow(*i); - const Point headerPreferredSize = m_header->PreferredSize(); - const Point bodyPreferredSize = m_body->PreferredSize(); + m_dirty = true; + } - return Point(std::max(headerPreferredSize.x,bodyPreferredSize.x)+sliderSize.x, headerPreferredSize.y+bodyPreferredSize.y); -} + void Table::Inner::SetRowSpacing(int spacing) + { + m_rowSpacing = spacing; + m_dirty = true; + } -void Table::Layout() -{ - // always dirty because some widget within the table may have requested layout - m_dirty = true; + void Table::Inner::SetRowAlignment(RowAlignDirection dir) + { + m_rowAlignment = dir; + m_dirty = true; + } - PreferredSize(); - - Point size = GetSize(); - m_layout.ComputeForWidth(size.x); - - Point preferredSize(m_header->PreferredSize()); - SetWidgetDimensions(m_header.Get(), Point(), Point(size.x, preferredSize.y)); - int top = preferredSize.y; - size.y -= top; - - preferredSize = m_body->PreferredSize(); - if (preferredSize.y <= size.y) { - if (m_slider->GetContainer()) { - m_slider->SetValue(0); - m_onMouseWheelConn.disconnect(); - RemoveWidget(m_slider.Get()); + void Table::Inner::HandleClick() + { + if (m_mouseEnabled) { + int row = RowUnderPoint(GetMousePos()); + if (row >= 0) + onRowClicked.emit(row); } - } - else { - if (!m_slider->GetContainer()) - AddWidget(m_slider.Get()); - if (!m_onMouseWheelConn.connected()) - m_onMouseWheelConn = onMouseWheel.connect(sigc::mem_fun(this, &Table::OnMouseWheel)); - - const Point sliderSize(m_slider->PreferredSize().x, size.y); - const Point sliderPos(size.x-sliderSize.x, top); - SetWidgetDimensions(m_slider.Get(), sliderPos, sliderSize); - m_slider->Layout(); - - size.x = sliderPos.x; - - const float step = float(sliderSize.y) * 0.5f / float(preferredSize.y); - m_slider->SetStep(step); - - OnScroll(m_slider->GetValue()); + Container::HandleClick(); } - SetWidgetDimensions(m_body.Get(), Point(0, top), size); + int Table::Inner::RowUnderPoint(const Point &pt, int *out_row_top, int *out_row_bottom) const + { + int start = 0, end = m_rows.size() - 1, mid = 0; + while (start <= end) { + mid = start + ((end - start) / 2); - LayoutChildren(); -} + const Widget *w = m_rows[mid][0]; + const int rowTop = w->GetPosition().y; + const int rowBottom = rowTop + w->GetSize().y; -void Table::HandleInvisible() -{ - m_slider->SetValue(0); -} + if (pt.y < rowTop) + end = mid - 1; + else if (pt.y >= rowBottom) + start = mid + 1; + else { + if (out_row_top) { + *out_row_top = rowTop; + } + if (out_row_bottom) { + *out_row_bottom = rowBottom; + } + return mid; + } + } -Table *Table::SetHeadingRow(const WidgetSet &set) -{ - m_header->Clear(); - m_header->AddRow(set.widgets); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + if (out_row_top) { + *out_row_top = 0; + } + if (out_row_bottom) { + *out_row_bottom = 0; + } + return -1; + } -Table *Table::AddRow(const WidgetSet &set) -{ - m_body->AddRow(set.widgets); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + Table::Table(Context *context) : + Container(context), + m_dirty(false) + { + m_header.Reset(new Table::Inner(GetContext(), m_layout)); + AddWidget(m_header.Get()); -void Table::ClearRows() -{ - m_body->Clear(); - m_dirty = true; - GetContext()->RequestLayout(); -} + m_body.Reset(new Table::Inner(GetContext(), m_layout)); + AddWidget(m_body.Get()); -Table *Table::SetRowSpacing(int spacing) -{ - m_body->SetRowSpacing(GetContext()->GetScale() * spacing); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + m_body->onRowClicked.connect(sigc::mem_fun(&onRowClicked, &sigc::signal::emit)); -Table *Table::SetColumnSpacing(int spacing) -{ - m_layout.SetColumnSpacing(GetContext()->GetScale() * spacing); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + m_slider.Reset(GetContext()->VSlider()); + m_slider->onValueChanged.connect(sigc::mem_fun(this, &Table::OnScroll)); + } -Table *Table::SetRowAlignment(RowAlignDirection dir) -{ - m_body->SetRowAlignment(dir); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + Point Table::PreferredSize() + { + if (m_dirty) { + m_layout.Clear(); -Table *Table::SetColumnAlignment(ColumnAlignDirection mode) -{ - m_layout.SetColumnAlignment(mode); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + m_header->AccumulateLayout(); + m_body->AccumulateLayout(); -Table *Table::SetHeadingFont(Font font) -{ - m_header->SetFont(font); - m_dirty = true; - GetContext()->RequestLayout(); - return this; -} + m_dirty = false; + } -Table *Table::SetMouseEnabled(bool enabled) -{ - m_body->SetMouseEnabled(enabled); - return this; -} + const Point sliderSize = m_slider->PreferredSize(); + const Point headerPreferredSize = m_header->PreferredSize(); + const Point bodyPreferredSize = m_body->PreferredSize(); -void Table::OnScroll(float value) -{ - if (m_slider->GetContainer()) - m_body->SetDrawOffset(Point(0, -float(m_body->PreferredSize().y-(GetSize().y-m_header->PreferredSize().y))*value)); - else - m_body->SetDrawOffset(Point()); -} + return Point(std::max(headerPreferredSize.x, bodyPreferredSize.x) + sliderSize.x, headerPreferredSize.y + bodyPreferredSize.y); + } -bool Table::OnMouseWheel(const MouseWheelEvent &event) -{ - if (event.direction == MouseWheelEvent::WHEEL_UP) - m_slider->StepUp(); - else - m_slider->StepDown(); - return true; -} + void Table::Layout() + { + // always dirty because some widget within the table may have requested layout + m_dirty = true; -void Table::SetScrollPosition(float v) -{ - m_slider->SetValue(v); -} + PreferredSize(); -} + Point size = GetSize(); + m_layout.ComputeForWidth(size.x); + + Point preferredSize(m_header->PreferredSize()); + SetWidgetDimensions(m_header.Get(), Point(), Point(size.x, preferredSize.y)); + int top = preferredSize.y; + size.y -= top; + + preferredSize = m_body->PreferredSize(); + if (preferredSize.y <= size.y) { + if (m_slider->GetContainer()) { + m_slider->SetValue(0); + m_onMouseWheelConn.disconnect(); + RemoveWidget(m_slider.Get()); + } + } else { + if (!m_slider->GetContainer()) + AddWidget(m_slider.Get()); + + if (!m_onMouseWheelConn.connected()) + m_onMouseWheelConn = onMouseWheel.connect(sigc::mem_fun(this, &Table::OnMouseWheel)); + + const Point sliderSize(m_slider->PreferredSize().x, size.y); + const Point sliderPos(size.x - sliderSize.x, top); + SetWidgetDimensions(m_slider.Get(), sliderPos, sliderSize); + m_slider->Layout(); + + size.x = sliderPos.x; + + const float step = float(sliderSize.y) * 0.5f / float(preferredSize.y); + m_slider->SetStep(step); + + OnScroll(m_slider->GetValue()); + } + + SetWidgetDimensions(m_body.Get(), Point(0, top), size); + + LayoutChildren(); + } + + void Table::HandleInvisible() + { + m_slider->SetValue(0); + } + + Table *Table::SetHeadingRow(const WidgetSet &set) + { + m_header->Clear(); + m_header->AddRow(set.widgets); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::AddRow(const WidgetSet &set) + { + m_body->AddRow(set.widgets); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + void Table::ClearRows() + { + m_body->Clear(); + m_dirty = true; + GetContext()->RequestLayout(); + } + + Table *Table::SetRowSpacing(int spacing) + { + m_body->SetRowSpacing(GetContext()->GetScale() * spacing); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::SetColumnSpacing(int spacing) + { + m_layout.SetColumnSpacing(GetContext()->GetScale() * spacing); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::SetRowAlignment(RowAlignDirection dir) + { + m_body->SetRowAlignment(dir); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::SetColumnAlignment(ColumnAlignDirection mode) + { + m_layout.SetColumnAlignment(mode); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::SetHeadingFont(Font font) + { + m_header->SetFont(font); + m_dirty = true; + GetContext()->RequestLayout(); + return this; + } + + Table *Table::SetMouseEnabled(bool enabled) + { + m_body->SetMouseEnabled(enabled); + return this; + } + + void Table::OnScroll(float value) + { + if (m_slider->GetContainer()) + m_body->SetDrawOffset(Point(0, -float(m_body->PreferredSize().y - (GetSize().y - m_header->PreferredSize().y)) * value)); + else + m_body->SetDrawOffset(Point()); + } + + bool Table::OnMouseWheel(const MouseWheelEvent &event) + { + if (event.direction == MouseWheelEvent::WHEEL_UP) + m_slider->StepUp(); + else + m_slider->StepDown(); + return true; + } + + void Table::SetScrollPosition(float v) + { + m_slider->SetValue(v); + } + +} // namespace UI diff --git a/src/ui/Table.h b/src/ui/Table.h index d66613641..2a170847e 100644 --- a/src/ui/Table.h +++ b/src/ui/Table.h @@ -5,138 +5,138 @@ #define UI_TABLE_H #include "Container.h" -#include "Slider.h" #include "Event.h" +#include "Slider.h" namespace UI { -class Table: public Container { -protected: - friend class Context; - Table(Context *context); + class Table : public Container { + protected: + friend class Context; + Table(Context *context); -public: - virtual Point PreferredSize(); - virtual void Layout(); - - Table *SetHeadingRow(const WidgetSet &set); - Table *AddRow(const WidgetSet &set); - void ClearRows(); - - Table *SetRowSpacing(int spacing); - Table *SetColumnSpacing(int spacing); - - enum RowAlignDirection { // - ROW_TOP, - ROW_CENTER, - ROW_BOTTOM - }; - - enum ColumnAlignDirection { // - COLUMN_LEFT, - COLUMN_CENTER, - COLUMN_RIGHT, - COLUMN_JUSTIFY - }; - - Table *SetRowAlignment(RowAlignDirection dir); - Table *SetColumnAlignment(ColumnAlignDirection dir); - - Table *SetHeadingFont(Font font); - - Table *SetMouseEnabled(bool enabled); - - void SetScrollPosition(float v); - - sigc::signal onRowClicked; - -protected: - virtual void HandleInvisible(); - -private: - - class LayoutAccumulator { public: - LayoutAccumulator() : m_columnSpacing(0), m_preferredWidth(0), m_columnAlignment(COLUMN_LEFT) {} - - void AddRow(const std::vector &widgets); - void Clear(); - - bool Empty() const { return m_columnWidth.empty(); } - - void SetColumnSpacing(int spacing) { m_columnSpacing = spacing; } - void SetColumnAlignment(ColumnAlignDirection dir) { m_columnAlignment = dir; } - - void ComputeForWidth(int availWidth); - - int GetPreferredWidth() const { return m_preferredWidth; } - - const std::vector &ColumnWidth() const { return m_columnWidth; } - const std::vector &ColumnLeft() const { return m_columnLeft; } - - private: - std::vector m_columnWidth; - std::vector m_columnLeft; - int m_columnSpacing; - int m_preferredWidth; - ColumnAlignDirection m_columnAlignment; - }; - - - class Inner: public Container { - public: - Inner(Context *context, LayoutAccumulator &layout); - virtual Point PreferredSize(); virtual void Layout(); - virtual void Draw(); - void AddRow(const std::vector &widgets); - void Clear(); + Table *SetHeadingRow(const WidgetSet &set); + Table *AddRow(const WidgetSet &set); + void ClearRows(); - void AccumulateLayout(); + Table *SetRowSpacing(int spacing); + Table *SetColumnSpacing(int spacing); - void SetRowSpacing(int spacing); - void SetColumnSpacing(int spacing); + enum RowAlignDirection { // + ROW_TOP, + ROW_CENTER, + ROW_BOTTOM + }; - void SetRowAlignment(RowAlignDirection dir); + enum ColumnAlignDirection { // + COLUMN_LEFT, + COLUMN_CENTER, + COLUMN_RIGHT, + COLUMN_JUSTIFY + }; - void SetMouseEnabled(bool enabled) { m_mouseEnabled = enabled; } + Table *SetRowAlignment(RowAlignDirection dir); + Table *SetColumnAlignment(ColumnAlignDirection dir); - sigc::signal onRowClicked; + Table *SetHeadingFont(Font font); + + Table *SetMouseEnabled(bool enabled); + + void SetScrollPosition(float v); + + sigc::signal onRowClicked; protected: - virtual void HandleClick(); + virtual void HandleInvisible(); private: - int RowUnderPoint(const Point &pt, int *out_row_top = 0, int *out_row_bottom = 0) const; + class LayoutAccumulator { + public: + LayoutAccumulator() : + m_columnSpacing(0), + m_preferredWidth(0), + m_columnAlignment(COLUMN_LEFT) {} - LayoutAccumulator &m_layout; - std::vector< std::vector > m_rows; - std::vector m_rowHeight; - Point m_preferredSize; - int m_rowSpacing; - RowAlignDirection m_rowAlignment; + void AddRow(const std::vector &widgets); + void Clear(); + + bool Empty() const { return m_columnWidth.empty(); } + + void SetColumnSpacing(int spacing) { m_columnSpacing = spacing; } + void SetColumnAlignment(ColumnAlignDirection dir) { m_columnAlignment = dir; } + + void ComputeForWidth(int availWidth); + + int GetPreferredWidth() const { return m_preferredWidth; } + + const std::vector &ColumnWidth() const { return m_columnWidth; } + const std::vector &ColumnLeft() const { return m_columnLeft; } + + private: + std::vector m_columnWidth; + std::vector m_columnLeft; + int m_columnSpacing; + int m_preferredWidth; + ColumnAlignDirection m_columnAlignment; + }; + + class Inner : public Container { + public: + Inner(Context *context, LayoutAccumulator &layout); + + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Draw(); + + void AddRow(const std::vector &widgets); + void Clear(); + + void AccumulateLayout(); + + void SetRowSpacing(int spacing); + void SetColumnSpacing(int spacing); + + void SetRowAlignment(RowAlignDirection dir); + + void SetMouseEnabled(bool enabled) { m_mouseEnabled = enabled; } + + sigc::signal onRowClicked; + + protected: + virtual void HandleClick(); + + private: + int RowUnderPoint(const Point &pt, int *out_row_top = 0, int *out_row_bottom = 0) const; + + LayoutAccumulator &m_layout; + std::vector> m_rows; + std::vector m_rowHeight; + Point m_preferredSize; + int m_rowSpacing; + RowAlignDirection m_rowAlignment; + bool m_dirty; + + bool m_mouseEnabled; + }; + + LayoutAccumulator m_layout; bool m_dirty; - bool m_mouseEnabled; + RefCountedPtr m_header; + RefCountedPtr m_body; + + RefCountedPtr m_slider; + + sigc::connection m_onMouseWheelConn; + + void OnScroll(float value); + bool OnMouseWheel(const MouseWheelEvent &event); }; - LayoutAccumulator m_layout; - bool m_dirty; - - RefCountedPtr m_header; - RefCountedPtr m_body; - - RefCountedPtr m_slider; - - sigc::connection m_onMouseWheelConn; - - void OnScroll(float value); - bool OnMouseWheel(const MouseWheelEvent &event); -}; - -} +} // namespace UI #endif - diff --git a/src/ui/TextEntry.cpp b/src/ui/TextEntry.cpp index cd7d454dd..81eb4dd27 100644 --- a/src/ui/TextEntry.cpp +++ b/src/ui/TextEntry.cpp @@ -3,100 +3,101 @@ #include "TextEntry.h" #include "Context.h" -#include "text/TextureFont.h" #include "text/TextSupport.h" +#include "text/TextureFont.h" namespace UI { -TextEntry::TextEntry(Context *context, const std::string &text) : Container(context), - m_cursor(0) -{ - m_label = GetContext()->Label(text); - AddWidget(m_label); -} - -Point TextEntry::PreferredSize() -{ - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); - const Point borderSize(elem.borderWidth*2, elem.borderHeight*2); - Point preferredSize = SizeAdd(m_label->PreferredSize(), Point(elem.paddingX*2, elem.paddingY*2)); - preferredSize.x = std::max(preferredSize.x, borderSize.x); - preferredSize.y = std::max(preferredSize.y, borderSize.y); - return preferredSize; -} - -void TextEntry::Layout() -{ - const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); - - const Point &size = GetSize(); - - const Point innerPos(elem.paddingX, elem.paddingY); - const Point innerSize(size.x - elem.paddingX*2, size.y - elem.paddingY*2); - - SetWidgetDimensions(m_label, innerPos, innerSize); - - // XXX see ::Draw. after Container::Draw we're still translated to the - // label origin so we calculate the cursor from there - const float cursorBottom = m_label->GetSize().y; - const float cursorTop = cursorBottom - GetContext()->GetFont(GetFont())->GetHeight(); - - m_cursorVertices[0] = vector3f(0.0f, cursorTop, 0.0f); - m_cursorVertices[1] = vector3f(0.0f, cursorBottom, 0.0f); - - m_label->Layout(); -} - -void TextEntry::Update() -{ - float cursorLeft, cursorBaseline; - GetContext()->GetFont(GetFont())->MeasureCharacterPos(GetText().c_str(), m_cursor, cursorLeft, cursorBaseline); - m_cursorVertices[0].x = m_cursorVertices[1].x = cursorLeft + 0.5f; - - // offset such that the cursor is always visible - const Point offset(m_label->GetDrawOffset()); - const Point size(m_label->GetSize()); - - const int windowLeft = -offset.x; - const int windowRight = windowLeft + size.x; - - const int cursorPos = roundf(cursorLeft); - - if (cursorPos > windowRight) - m_label->SetDrawOffset(Point(-cursorPos+size.x-1, 0.0f)); - else if (cursorPos < windowLeft) - m_label->SetDrawOffset(Point(-cursorPos, 0.0f)); -} - -void TextEntry::Draw() -{ - if (IsSelected()) - GetContext()->GetSkin().DrawBackgroundActive(Point(), GetSize()); - else - GetContext()->GetSkin().DrawBackgroundNormal(Point(), GetSize()); - - Container::Draw(); - - if (IsSelected()) { - m_lines.SetData(2, &m_cursorVertices[0], Color::WHITE); - m_lines.Draw(GetContext()->GetRenderer(), GetContext()->GetSkin().GetAlphaBlendState()); + TextEntry::TextEntry(Context *context, const std::string &text) : + Container(context), + m_cursor(0) + { + m_label = GetContext()->Label(text); + AddWidget(m_label); } -} -TextEntry *TextEntry::SetText(const std::string &text) -{ - bool atEnd = m_label->GetText().size() == m_cursor; - m_label->SetText(text); - m_cursor = atEnd ? Uint32(text.size()) : Clamp(m_cursor, Uint32(0), Uint32(text.size())); - GetContext()->RequestLayout(); - return this; -} + Point TextEntry::PreferredSize() + { + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); + const Point borderSize(elem.borderWidth * 2, elem.borderHeight * 2); + Point preferredSize = SizeAdd(m_label->PreferredSize(), Point(elem.paddingX * 2, elem.paddingY * 2)); + preferredSize.x = std::max(preferredSize.x, borderSize.x); + preferredSize.y = std::max(preferredSize.y, borderSize.y); + return preferredSize; + } -void TextEntry::HandleKeyDown(const KeyboardEvent &event) -{ - std::string text(m_label->GetText()); + void TextEntry::Layout() + { + const Skin::BorderedRectElement &elem(GetContext()->GetSkin().BackgroundNormal()); - switch (event.keysym.sym) { + const Point &size = GetSize(); + + const Point innerPos(elem.paddingX, elem.paddingY); + const Point innerSize(size.x - elem.paddingX * 2, size.y - elem.paddingY * 2); + + SetWidgetDimensions(m_label, innerPos, innerSize); + + // XXX see ::Draw. after Container::Draw we're still translated to the + // label origin so we calculate the cursor from there + const float cursorBottom = m_label->GetSize().y; + const float cursorTop = cursorBottom - GetContext()->GetFont(GetFont())->GetHeight(); + + m_cursorVertices[0] = vector3f(0.0f, cursorTop, 0.0f); + m_cursorVertices[1] = vector3f(0.0f, cursorBottom, 0.0f); + + m_label->Layout(); + } + + void TextEntry::Update() + { + float cursorLeft, cursorBaseline; + GetContext()->GetFont(GetFont())->MeasureCharacterPos(GetText().c_str(), m_cursor, cursorLeft, cursorBaseline); + m_cursorVertices[0].x = m_cursorVertices[1].x = cursorLeft + 0.5f; + + // offset such that the cursor is always visible + const Point offset(m_label->GetDrawOffset()); + const Point size(m_label->GetSize()); + + const int windowLeft = -offset.x; + const int windowRight = windowLeft + size.x; + + const int cursorPos = roundf(cursorLeft); + + if (cursorPos > windowRight) + m_label->SetDrawOffset(Point(-cursorPos + size.x - 1, 0.0f)); + else if (cursorPos < windowLeft) + m_label->SetDrawOffset(Point(-cursorPos, 0.0f)); + } + + void TextEntry::Draw() + { + if (IsSelected()) + GetContext()->GetSkin().DrawBackgroundActive(Point(), GetSize()); + else + GetContext()->GetSkin().DrawBackgroundNormal(Point(), GetSize()); + + Container::Draw(); + + if (IsSelected()) { + m_lines.SetData(2, &m_cursorVertices[0], Color::WHITE); + m_lines.Draw(GetContext()->GetRenderer(), GetContext()->GetSkin().GetAlphaBlendState()); + } + } + + TextEntry *TextEntry::SetText(const std::string &text) + { + bool atEnd = m_label->GetText().size() == m_cursor; + m_label->SetText(text); + m_cursor = atEnd ? Uint32(text.size()) : Clamp(m_cursor, Uint32(0), Uint32(text.size())); + GetContext()->RequestLayout(); + return this; + } + + void TextEntry::HandleKeyDown(const KeyboardEvent &event) + { + std::string text(m_label->GetText()); + + switch (event.keysym.sym) { case SDLK_LEFT: if (m_cursor > 0) { const char *cstr = text.c_str(); @@ -148,57 +149,56 @@ void TextEntry::HandleKeyDown(const KeyboardEvent &event) default: if (event.keysym.mod & KMOD_CTRL) { switch (event.keysym.sym) { - case SDLK_u: - m_cursor = 0; - m_label->SetText(""); - onChange.emit(""); - break; + case SDLK_u: + m_cursor = 0; + m_label->SetText(""); + onChange.emit(""); + break; - case SDLK_w: { - size_t pos = text.find_last_not_of(' ', m_cursor); - if (pos != std::string::npos) pos = text.find_last_of(' ', pos); - m_cursor = static_cast(pos != std::string::npos ? pos+1 : 0); - text.erase(m_cursor); + case SDLK_w: { + size_t pos = text.find_last_not_of(' ', m_cursor); + if (pos != std::string::npos) pos = text.find_last_of(' ', pos); + m_cursor = static_cast(pos != std::string::npos ? pos + 1 : 0); + text.erase(m_cursor); + m_label->SetText(text); + onChange.emit(text); + break; + } + + case SDLK_v: { // XXX SDLK_PASTE? + if (SDL_HasClipboardText()) { + char *paste = SDL_GetClipboardText(); + size_t len = strlen(paste); // XXX strlen not utf8-aware + text.insert(m_cursor, paste, len); m_label->SetText(text); - onChange.emit(text); - break; + m_cursor += static_cast(len); + SDL_free(paste); } + } - case SDLK_v: { // XXX SDLK_PASTE? - if (SDL_HasClipboardText()) { - char *paste = SDL_GetClipboardText(); - size_t len = strlen(paste); // XXX strlen not utf8-aware - text.insert(m_cursor, paste, len); - m_label->SetText(text); - m_cursor += static_cast(len); - SDL_free(paste); - } - } - - default: - break; + default: + break; } } - + } } -} -void TextEntry::HandleTextInput(const TextInputEvent &event) -{ - // naively accept anything outside C0 and C1. probably safe enough for - // now, but needs revisiting if we one day support rtl, cjk, etc - if ((event.unicode > 0x1f && event.unicode < 0x7f) || event.unicode > 0x9f) { - char buf[4] = {}; - const int len = Text::utf8_encode_char(event.unicode, buf); + void TextEntry::HandleTextInput(const TextInputEvent &event) + { + // naively accept anything outside C0 and C1. probably safe enough for + // now, but needs revisiting if we one day support rtl, cjk, etc + if ((event.unicode > 0x1f && event.unicode < 0x7f) || event.unicode > 0x9f) { + char buf[4] = {}; + const int len = Text::utf8_encode_char(event.unicode, buf); - std::string text(m_label->GetText()); - text.insert(m_cursor, buf, len); - m_label->SetText(text); + std::string text(m_label->GetText()); + text.insert(m_cursor, buf, len); + m_label->SetText(text); - m_cursor += len; + m_cursor += len; - onChange.emit(text); + onChange.emit(text); + } } -} -} +} // namespace UI diff --git a/src/ui/TextEntry.h b/src/ui/TextEntry.h index c3ecb2876..75cb84218 100644 --- a/src/ui/TextEntry.h +++ b/src/ui/TextEntry.h @@ -10,36 +10,36 @@ namespace UI { -class TextEntry: public Container { -public: - virtual Point PreferredSize(); - virtual void Layout(); - virtual void Update(); - virtual void Draw(); + class TextEntry : public Container { + public: + virtual Point PreferredSize(); + virtual void Layout(); + virtual void Update(); + virtual void Draw(); - TextEntry *SetText(const std::string &text); - const std::string &GetText() const { return m_label->GetText(); } + TextEntry *SetText(const std::string &text); + const std::string &GetText() const { return m_label->GetText(); } - virtual bool IsSelectable() const { return true; } + virtual bool IsSelectable() const { return true; } - sigc::signal onChange; - sigc::signal onEnter; + sigc::signal onChange; + sigc::signal onEnter; -protected: - friend class Context; - TextEntry(Context *context, const std::string &text); + protected: + friend class Context; + TextEntry(Context *context, const std::string &text); - virtual void HandleKeyDown(const KeyboardEvent &event); - virtual void HandleTextInput(const TextInputEvent &event); + virtual void HandleKeyDown(const KeyboardEvent &event); + virtual void HandleTextInput(const TextInputEvent &event); -private: - Label *m_label; + private: + Label *m_label; - Uint32 m_cursor; - vector3f m_cursorVertices[2]; - Graphics::Drawables::Lines m_lines; -}; + Uint32 m_cursor; + vector3f m_cursorVertices[2]; + Graphics::Drawables::Lines m_lines; + }; -} +} // namespace UI #endif diff --git a/src/ui/TextLayout.cpp b/src/ui/TextLayout.cpp index d83e67343..eecc23ef1 100644 --- a/src/ui/TextLayout.cpp +++ b/src/ui/TextLayout.cpp @@ -2,144 +2,145 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "TextLayout.h" -#include "Widget.h" -#include "RefCounted.h" -#include "text/TextureFont.h" #include "Color.h" +#include "RefCounted.h" +#include "Widget.h" #include "graphics/VertexArray.h" #include "graphics/VertexBuffer.h" +#include "text/TextureFont.h" namespace UI { -TextLayout::TextLayout(const RefCountedPtr &font, const std::string &text) - : m_font(font), m_lastDrawPos(Point(INT_MIN, INT_MIN)), m_lastDrawSize(Point(INT_MIN, INT_MIN)), m_prevColor(Color::WHITE) -{ - if (!text.size()) - return; + TextLayout::TextLayout(const RefCountedPtr &font, const std::string &text) : + m_font(font), + m_lastDrawPos(Point(INT_MIN, INT_MIN)), + m_lastDrawSize(Point(INT_MIN, INT_MIN)), + m_prevColor(Color::WHITE) + { + if (!text.size()) + return; - // split text on space/newline into words - const std::string delim(" \n"); + // split text on space/newline into words + const std::string delim(" \n"); - size_t start = 0, end = 0; - while (end != std::string::npos) { + size_t start = 0, end = 0; + while (end != std::string::npos) { - // start where we left off last time - start = end; + // start where we left off last time + start = end; - // skip over delimeter chars - while (start < text.size() && delim.find_first_of(text[start]) != std::string::npos) { - // if we found a newline, push an empty "word". the layout will - // handle this specially - if (text[start] == '\n') - m_words.push_back(Word("")); + // skip over delimeter chars + while (start < text.size() && delim.find_first_of(text[start]) != std::string::npos) { + // if we found a newline, push an empty "word". the layout will + // handle this specially + if (text[start] == '\n') + m_words.push_back(Word("")); - // eat - start++; - } - - // reached the end, no more to do - if (start == text.size()) - break; - - // find the end - next delim or end of string - end = text.find_first_of(delim, start); - - // extract the word and remember it - std::string word = text.substr(start, (end == std::string::npos) ? std::string::npos : end - start); - m_words.push_back(Word(word)); - } -} - -Point TextLayout::ComputeSize(const Point &layoutSize) -{ - if (layoutSize == Point()) return Point(); - - if (layoutSize == m_lastRequested) - return m_lastSize; - - int spaceWidth = ceilf(m_font->GetGlyph(' ').advX); - int lineHeight = ceilf(m_font->GetHeight()); - - Point pos; - Point bounds; - - for (std::vector::iterator i = m_words.begin(); i != m_words.end(); ++i) { - - // newline. move to start of next line - if (!(*i).text.size()) { - pos = Point(0, std::max(bounds.y,pos.y+lineHeight)); - continue; - } - - vector2f _wordSize; - m_font->MeasureString((*i).text.c_str(), _wordSize.x, _wordSize.y); - Point wordSize(_wordSize.x, _wordSize.y); - - // we add the word to this line if: - // - we're at the start of the line; OR - // - the word does not go past the right edge of the box - bool wordAdded = false; - while (!wordAdded) { - if (pos.x == 0 || pos.x + wordSize.x <= layoutSize.x) { - (*i).pos = pos; - - // move to the end of the word - pos.x += wordSize.x; - bounds = Point(std::max(bounds.x,pos.x), std::max(bounds.y,pos.y+wordSize.y)); - - wordAdded = true; + // eat + start++; } - else - // retry at start of new line - pos = Point(0,std::max(bounds.y,pos.y+lineHeight)); - } + // reached the end, no more to do + if (start == text.size()) + break; - // add a space at the end of each word. its only used to set the start - // point for the next word if there is one. if there's not then no - // words are added so it won't push the bounds out - pos.x += spaceWidth; + // find the end - next delim or end of string + end = text.find_first_of(delim, start); + + // extract the word and remember it + std::string word = text.substr(start, (end == std::string::npos) ? std::string::npos : end - start); + m_words.push_back(Word(word)); + } } - m_lastRequested = layoutSize; - m_lastSize = bounds; - - return bounds; -} - -void TextLayout::Draw(const Point &layoutSize, const Point &drawPos, const Point &drawSize, const Color &color) -{ - // Has anything changed between passes - const bool bAnyNew = (layoutSize != m_lastRequested) || (m_lastDrawPos != drawPos) || (m_lastDrawSize != drawSize) || (m_prevColor != color); - if (bAnyNew) + Point TextLayout::ComputeSize(const Point &layoutSize) { - ComputeSize(layoutSize); - const int top = -drawPos.y - m_font->GetHeight(); - const int bottom = -drawPos.y + drawSize.y; + if (layoutSize == Point()) return Point(); - Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + if (layoutSize == m_lastRequested) + return m_lastSize; + + int spaceWidth = ceilf(m_font->GetGlyph(' ').advX); + int lineHeight = ceilf(m_font->GetHeight()); + + Point pos; + Point bounds; for (std::vector::iterator i = m_words.begin(); i != m_words.end(); ++i) { - if ((*i).pos.y >= top && (*i).pos.y < bottom) { - m_font->PopulateString(va, (*i).text, (*i).pos.x, (*i).pos.y, color); + + // newline. move to start of next line + if (!(*i).text.size()) { + pos = Point(0, std::max(bounds.y, pos.y + lineHeight)); + continue; + } + + vector2f _wordSize; + m_font->MeasureString((*i).text.c_str(), _wordSize.x, _wordSize.y); + Point wordSize(_wordSize.x, _wordSize.y); + + // we add the word to this line if: + // - we're at the start of the line; OR + // - the word does not go past the right edge of the box + bool wordAdded = false; + while (!wordAdded) { + if (pos.x == 0 || pos.x + wordSize.x <= layoutSize.x) { + (*i).pos = pos; + + // move to the end of the word + pos.x += wordSize.x; + bounds = Point(std::max(bounds.x, pos.x), std::max(bounds.y, pos.y + wordSize.y)); + + wordAdded = true; + } + + else + // retry at start of new line + pos = Point(0, std::max(bounds.y, pos.y + lineHeight)); + } + + // add a space at the end of each word. its only used to set the start + // point for the next word if there is one. if there's not then no + // words are added so it won't push the bounds out + pos.x += spaceWidth; + } + + m_lastRequested = layoutSize; + m_lastSize = bounds; + + return bounds; + } + + void TextLayout::Draw(const Point &layoutSize, const Point &drawPos, const Point &drawSize, const Color &color) + { + // Has anything changed between passes + const bool bAnyNew = (layoutSize != m_lastRequested) || (m_lastDrawPos != drawPos) || (m_lastDrawSize != drawSize) || (m_prevColor != color); + if (bAnyNew) { + ComputeSize(layoutSize); + const int top = -drawPos.y - m_font->GetHeight(); + const int bottom = -drawPos.y + drawSize.y; + + Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0); + + for (std::vector::iterator i = m_words.begin(); i != m_words.end(); ++i) { + if ((*i).pos.y >= top && (*i).pos.y < bottom) { + m_font->PopulateString(va, (*i).text, (*i).pos.x, (*i).pos.y, color); + } + } + + if (!m_vbuffer.Valid() || (m_vbuffer->GetCapacity() < va.GetNumVerts())) { + m_vbuffer.Reset(m_font->CreateVertexBuffer(va, true)); + } else if (!va.IsEmpty()) { + m_vbuffer->Populate(va); } } - if (!m_vbuffer.Valid() || (m_vbuffer->GetCapacity() < va.GetNumVerts())) { - m_vbuffer.Reset(m_font->CreateVertexBuffer(va, true)); - } - else if(!va.IsEmpty()) { - m_vbuffer->Populate(va); - } + m_font->RenderBuffer(m_vbuffer.Get()); + + // store current params + m_lastRequested = layoutSize; + m_lastDrawPos = drawPos; + m_lastDrawSize = drawSize; + m_prevColor = color; } - m_font->RenderBuffer( m_vbuffer.Get() ); - - // store current params - m_lastRequested = layoutSize; - m_lastDrawPos = drawPos; - m_lastDrawSize = drawSize; - m_prevColor = color; -} - -} +} // namespace UI diff --git a/src/ui/TextLayout.h b/src/ui/TextLayout.h index 34b5a847a..f4b8e789d 100644 --- a/src/ui/TextLayout.h +++ b/src/ui/TextLayout.h @@ -4,44 +4,50 @@ #ifndef UI_TEXTLAYOUT_H #define UI_TEXTLAYOUT_H +#include "Color.h" #include "Point.h" #include "RefCounted.h" -#include "Color.h" #include #include -namespace Text { class TextureFont; } -namespace Graphics { class Renderer; class VertexBuffer; } +namespace Text { + class TextureFont; +} +namespace Graphics { + class Renderer; + class VertexBuffer; +} // namespace Graphics namespace UI { -class TextLayout { -public: - TextLayout(const RefCountedPtr &font, const std::string &text); + class TextLayout { + public: + TextLayout(const RefCountedPtr &font, const std::string &text); - Point ComputeSize(const Point &layoutSize); + Point ComputeSize(const Point &layoutSize); - void Draw(const Point &layoutSize, const Point &drawPos, const Point &drawSize, const Color &color = Color::WHITE); + void Draw(const Point &layoutSize, const Point &drawPos, const Point &drawSize, const Color &color = Color::WHITE); -private: - struct Word { - Word(const std::string &_text) : text(_text) {} - std::string text; - Point pos; + private: + struct Word { + Word(const std::string &_text) : + text(_text) {} + std::string text; + Point pos; + }; + std::vector m_words; + + Point m_lastRequested; // the layout area we were asked to compute size for + Point m_lastSize; // and the resulting size + + RefCountedPtr m_font; + RefCountedPtr m_vbuffer; + + Point m_lastDrawPos; + Point m_lastDrawSize; + Color m_prevColor; }; - std::vector m_words; - Point m_lastRequested; // the layout area we were asked to compute size for - Point m_lastSize; // and the resulting size - - RefCountedPtr m_font; - RefCountedPtr m_vbuffer; - - Point m_lastDrawPos; - Point m_lastDrawSize; - Color m_prevColor; -}; - -} +} // namespace UI #endif diff --git a/src/ui/Widget.cpp b/src/ui/Widget.cpp index c6274edbc..aae7e60bc 100644 --- a/src/ui/Widget.cpp +++ b/src/ui/Widget.cpp @@ -7,366 +7,369 @@ namespace UI { -Widget::Widget(Context *context) : - m_context(context), - m_container(0), - m_position(0), - m_size(0), - m_sizeControlFlags(0), - m_drawOffset(0), - m_activeOffset(0), - m_activeArea(0), - m_font(FONT_INHERIT), - m_disabled(false), - m_hidden(false), - m_mouseOver(false), - m_visible(false), - m_animatedOpacity(1.0f), - m_animatedPositionX(1.0f), - m_animatedPositionY(1.0f) -{ - assert(m_context); -} - -Widget::~Widget() -{ - // a container owns its widgets. this ensures that only the container can - // delete the widget by requiring it to clear the widgets references - // before deletion - assert(!m_container); - - for (std::map::iterator i = m_binds.begin(); i != m_binds.end(); ++i) - (*i).second.disconnect(); -} - -Point Widget::GetAbsolutePosition() const -{ - if (!m_container) return Point() + m_drawOffset; - return m_container->GetAbsolutePosition() + m_position + m_drawOffset; -} - -Point Widget::GetMousePos() const -{ - return m_context->GetMousePos() - GetAbsolutePosition(); -} - -void Widget::Attach(Container *container) -{ - assert(container); - assert(m_context == container->GetContext()); - m_container = container; - - // we should never be visible while we're detached, and we should - // always be detached before being attached to something else - assert(!m_visible); - NotifyVisible(container->IsVisible()); -} - -void Widget::Detach() -{ - NotifyVisible(false); - m_container = 0; - m_position = Point(); - m_size = Point(); -} - -void Widget::SetDimensions(const Point &position, const Point &size) -{ - m_position = position; - SetSize(size); - SetActiveArea(size); -} - -void Widget::NotifyVisible(bool visible) -{ - if (m_visible != visible) { - m_visible = visible; - TriggerVisibilityChanged(); - if (m_visible) { HandleVisible(); } else { HandleInvisible(); } + Widget::Widget(Context *context) : + m_context(context), + m_container(0), + m_position(0), + m_size(0), + m_sizeControlFlags(0), + m_drawOffset(0), + m_activeOffset(0), + m_activeArea(0), + m_font(FONT_INHERIT), + m_disabled(false), + m_hidden(false), + m_mouseOver(false), + m_visible(false), + m_animatedOpacity(1.0f), + m_animatedPositionX(1.0f), + m_animatedPositionY(1.0f) + { + assert(m_context); } -} -void Widget::SetActiveArea(const Point &activeArea, const Point &activeOffset) -{ - m_activeArea = Point(Clamp(activeArea.x, 0, GetSize().x), Clamp(activeArea.y, 0, GetSize().y)); - m_activeOffset = activeOffset; -} + Widget::~Widget() + { + // a container owns its widgets. this ensures that only the container can + // delete the widget by requiring it to clear the widgets references + // before deletion + assert(!m_container); -Widget *Widget::SetFont(Font font) -{ - m_font = font; - GetContext()->RequestLayout(); - return this; -} - -Point Widget::CalcLayoutContribution() -{ - Point preferredSize = PreferredSize(); - const Uint32 flags = GetSizeControlFlags(); - - if (flags & NO_WIDTH) - preferredSize.x = 0; - if (flags & NO_HEIGHT) - preferredSize.y = 0; - - if (flags & EXPAND_WIDTH) - preferredSize.x = SIZE_EXPAND; - if (flags & EXPAND_HEIGHT) - preferredSize.y = SIZE_EXPAND; - - return preferredSize; -} - -Point Widget::CalcSize(const Point &avail) -{ - if (!(GetSizeControlFlags() & PRESERVE_ASPECT)) - return avail; - - const Point preferredSize = PreferredSize(); - - const float wantRatio = float(preferredSize.x) / float(preferredSize.y); - const float haveRatio = float(avail.x) / float(avail.y); - - if (wantRatio > haveRatio) { - // limited by width - return Point(avail.x, float(avail.x) / wantRatio); - } else { - // limited by height - return Point(float(avail.y) * wantRatio, avail.y); + for (std::map::iterator i = m_binds.begin(); i != m_binds.end(); ++i) + (*i).second.disconnect(); } -} -Widget::Font Widget::GetFont() const -{ - if (m_font == FONT_INHERIT) { - if (m_container) return m_container->GetFont(); - return FONT_NORMAL; + Point Widget::GetAbsolutePosition() const + { + if (!m_container) return Point() + m_drawOffset; + return m_container->GetAbsolutePosition() + m_position + m_drawOffset; } - return m_font; -} -bool Widget::IsMouseActive() const -{ - return (GetContext()->GetMouseActive() == this); -} - -bool Widget::IsSelected() const -{ - return (GetContext()->GetSelected() == this); -} - -bool Widget::IsOnTopLayer() const -{ - const Layer *topLayer = GetContext()->GetTopLayer(); - Widget *scan = GetContainer(); - while (scan) { - if (scan == topLayer) - return true; - scan = scan->GetContainer(); - } - return false; -} - -void Widget::Disable() -{ - SetDisabled(true); - GetContext()->DisableWidget(this); -} - -void Widget::Hidden() -{ - SetHidden(true); - GetContext()->DisableWidget(this); -} - -void Widget::Enable() -{ - SetDisabled(false); - SetHidden(false); - GetContext()->EnableWidget(this); -} - -bool Widget::TriggerKeyDown(const KeyboardEvent &event, bool handled) -{ - HandleKeyDown(event); - if (!handled) handled = onKeyDown.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerKeyDown(event, handled); - return handled; -} - -bool Widget::TriggerKeyUp(const KeyboardEvent &event, bool handled) -{ - HandleKeyUp(event); - if (!handled) handled = onKeyUp.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerKeyUp(event, handled); - return handled; -} - -bool Widget::TriggerTextInput(const TextInputEvent &event, bool handled) -{ - HandleTextInput(event); - if (!handled) handled = onTextInput.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerTextInput(event, handled); - return handled; -} - -bool Widget::TriggerMouseDown(const MouseButtonEvent &event, bool handled) -{ - HandleMouseDown(event); - if (!handled) handled = onMouseDown.emit(event); - if (GetContainer()) { - MouseButtonEvent translatedEvent = MouseButtonEvent(event.action, event.button, event.pos+GetPosition()); - handled = GetContainer()->TriggerMouseDown(translatedEvent, handled); + Point Widget::GetMousePos() const + { + return m_context->GetMousePos() - GetAbsolutePosition(); } - return handled; -} -bool Widget::TriggerMouseUp(const MouseButtonEvent &event, bool handled) -{ - HandleMouseUp(event); - if (!handled) handled = onMouseUp.emit(event); - if (GetContainer()) { - MouseButtonEvent translatedEvent = MouseButtonEvent(event.action, event.button, event.pos+GetPosition()); - handled = GetContainer()->TriggerMouseUp(translatedEvent, handled); + void Widget::Attach(Container *container) + { + assert(container); + assert(m_context == container->GetContext()); + m_container = container; + + // we should never be visible while we're detached, and we should + // always be detached before being attached to something else + assert(!m_visible); + NotifyVisible(container->IsVisible()); } - return handled; -} -bool Widget::TriggerMouseMove(const MouseMotionEvent &event, bool handled) -{ - HandleMouseMove(event); - if (!handled) handled = onMouseMove.emit(event); - if (GetContainer()) { - MouseMotionEvent translatedEvent = MouseMotionEvent(event.pos+GetPosition(), event.rel); - handled = GetContainer()->TriggerMouseMove(translatedEvent, handled); + void Widget::Detach() + { + NotifyVisible(false); + m_container = 0; + m_position = Point(); + m_size = Point(); } - return handled; -} -bool Widget::TriggerMouseWheel(const MouseWheelEvent &event, bool handled) -{ - HandleMouseWheel(event); - if (!handled) handled = onMouseWheel.emit(event); - if (GetContainer()) { - MouseWheelEvent translatedEvent = MouseWheelEvent(event.direction, event.pos+GetPosition()); - handled = GetContainer()->TriggerMouseWheel(translatedEvent, handled); + void Widget::SetDimensions(const Point &position, const Point &size) + { + m_position = position; + SetSize(size); + SetActiveArea(size); } - return handled; -} -bool Widget::TriggerJoystickButtonDown(const JoystickButtonEvent &event, bool handled) -{ - HandleJoystickButtonDown(event); - if (!handled) handled = onJoystickButtonDown.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerJoystickButtonDown(event, handled); - return handled; -} - -bool Widget::TriggerJoystickButtonUp(const JoystickButtonEvent &event, bool handled) -{ - HandleJoystickButtonUp(event); - if (!handled) handled = onJoystickButtonUp.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerJoystickButtonUp(event, handled); - return handled; -} - -bool Widget::TriggerJoystickAxisMove(const JoystickAxisMotionEvent &event, bool handled) -{ - HandleJoystickAxisMove(event); - if (!handled) handled = onJoystickAxisMove.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerJoystickAxisMove(event, handled); - return handled; -} - -bool Widget::TriggerJoystickHatMove(const JoystickHatMotionEvent &event, bool handled) -{ - HandleJoystickHatMove(event); - if (!handled) handled = onJoystickHatMove.emit(event); - if (GetContainer()) handled = GetContainer()->TriggerJoystickHatMove(event, handled); - return handled; -} - -bool Widget::TriggerMouseOver(const Point &pos, bool handled, Widget *stop) -{ - // only send external events on state change - if (!m_mouseOver) { - m_mouseOver = true; - HandleMouseOver(); - if (!handled) handled = onMouseOver.emit(); + void Widget::NotifyVisible(bool visible) + { + if (m_visible != visible) { + m_visible = visible; + TriggerVisibilityChanged(); + if (m_visible) { + HandleVisible(); + } else { + HandleInvisible(); + } + } } - if (stop == this) return handled; - if (GetContainer()) handled = GetContainer()->TriggerMouseOver(pos+GetPosition(), handled, stop); - return handled; -} -bool Widget::TriggerMouseOut(const Point &pos, bool handled, Widget *stop) -{ - // only send external events on state change - if (m_mouseOver) { - HandleMouseOut(); - if (!handled) handled = onMouseOut.emit(); - m_mouseOver = false; + void Widget::SetActiveArea(const Point &activeArea, const Point &activeOffset) + { + m_activeArea = Point(Clamp(activeArea.x, 0, GetSize().x), Clamp(activeArea.y, 0, GetSize().y)); + m_activeOffset = activeOffset; } - if (stop == this) return handled; - if (GetContainer()) handled = GetContainer()->TriggerMouseOut(pos+GetPosition(), handled, stop); - return handled; -} -bool Widget::TriggerClick(bool handled) -{ - HandleClick(); - if (!handled) handled = onClick.emit(); - if (GetContainer()) handled = GetContainer()->TriggerClick(handled); - return handled; -} - -void Widget::TriggerMouseActivate() -{ - HandleMouseActivate(); -} - -void Widget::TriggerMouseDeactivate() -{ - HandleMouseDeactivate(); -} - -void Widget::TriggerSelect() -{ - HandleSelect(); -} - -void Widget::TriggerDeselect() -{ - HandleDeselect(); -} - -void Widget::TriggerVisibilityChanged() -{ - onVisibilityChanged.emit(m_visible); -} - -void Widget::RegisterBindPoint(const std::string &bindName, sigc::slot method) -{ - m_bindPoints[bindName] = method; -} - -void Widget::Bind(const std::string &bindName, PropertiedObject *object, const std::string &propertyName) -{ - const auto bindPointIter = m_bindPoints.find(bindName); - if (bindPointIter == m_bindPoints.end()) - return; - - sigc::connection conn = object->Properties().Connect(propertyName, (*bindPointIter).second); - - const auto bindIter = m_binds.find(bindName); - if (bindIter != m_binds.end()) { - (*bindIter).second.disconnect(); - (*bindIter).second = conn; + Widget *Widget::SetFont(Font font) + { + m_font = font; + GetContext()->RequestLayout(); + return this; } - else - m_binds.insert(bindIter, std::make_pair(bindName, conn)); - (*bindPointIter).second(object->Properties(), propertyName); -} + Point Widget::CalcLayoutContribution() + { + Point preferredSize = PreferredSize(); + const Uint32 flags = GetSizeControlFlags(); -} + if (flags & NO_WIDTH) + preferredSize.x = 0; + if (flags & NO_HEIGHT) + preferredSize.y = 0; + + if (flags & EXPAND_WIDTH) + preferredSize.x = SIZE_EXPAND; + if (flags & EXPAND_HEIGHT) + preferredSize.y = SIZE_EXPAND; + + return preferredSize; + } + + Point Widget::CalcSize(const Point &avail) + { + if (!(GetSizeControlFlags() & PRESERVE_ASPECT)) + return avail; + + const Point preferredSize = PreferredSize(); + + const float wantRatio = float(preferredSize.x) / float(preferredSize.y); + const float haveRatio = float(avail.x) / float(avail.y); + + if (wantRatio > haveRatio) { + // limited by width + return Point(avail.x, float(avail.x) / wantRatio); + } else { + // limited by height + return Point(float(avail.y) * wantRatio, avail.y); + } + } + + Widget::Font Widget::GetFont() const + { + if (m_font == FONT_INHERIT) { + if (m_container) return m_container->GetFont(); + return FONT_NORMAL; + } + return m_font; + } + + bool Widget::IsMouseActive() const + { + return (GetContext()->GetMouseActive() == this); + } + + bool Widget::IsSelected() const + { + return (GetContext()->GetSelected() == this); + } + + bool Widget::IsOnTopLayer() const + { + const Layer *topLayer = GetContext()->GetTopLayer(); + Widget *scan = GetContainer(); + while (scan) { + if (scan == topLayer) + return true; + scan = scan->GetContainer(); + } + return false; + } + + void Widget::Disable() + { + SetDisabled(true); + GetContext()->DisableWidget(this); + } + + void Widget::Hidden() + { + SetHidden(true); + GetContext()->DisableWidget(this); + } + + void Widget::Enable() + { + SetDisabled(false); + SetHidden(false); + GetContext()->EnableWidget(this); + } + + bool Widget::TriggerKeyDown(const KeyboardEvent &event, bool handled) + { + HandleKeyDown(event); + if (!handled) handled = onKeyDown.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerKeyDown(event, handled); + return handled; + } + + bool Widget::TriggerKeyUp(const KeyboardEvent &event, bool handled) + { + HandleKeyUp(event); + if (!handled) handled = onKeyUp.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerKeyUp(event, handled); + return handled; + } + + bool Widget::TriggerTextInput(const TextInputEvent &event, bool handled) + { + HandleTextInput(event); + if (!handled) handled = onTextInput.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerTextInput(event, handled); + return handled; + } + + bool Widget::TriggerMouseDown(const MouseButtonEvent &event, bool handled) + { + HandleMouseDown(event); + if (!handled) handled = onMouseDown.emit(event); + if (GetContainer()) { + MouseButtonEvent translatedEvent = MouseButtonEvent(event.action, event.button, event.pos + GetPosition()); + handled = GetContainer()->TriggerMouseDown(translatedEvent, handled); + } + return handled; + } + + bool Widget::TriggerMouseUp(const MouseButtonEvent &event, bool handled) + { + HandleMouseUp(event); + if (!handled) handled = onMouseUp.emit(event); + if (GetContainer()) { + MouseButtonEvent translatedEvent = MouseButtonEvent(event.action, event.button, event.pos + GetPosition()); + handled = GetContainer()->TriggerMouseUp(translatedEvent, handled); + } + return handled; + } + + bool Widget::TriggerMouseMove(const MouseMotionEvent &event, bool handled) + { + HandleMouseMove(event); + if (!handled) handled = onMouseMove.emit(event); + if (GetContainer()) { + MouseMotionEvent translatedEvent = MouseMotionEvent(event.pos + GetPosition(), event.rel); + handled = GetContainer()->TriggerMouseMove(translatedEvent, handled); + } + return handled; + } + + bool Widget::TriggerMouseWheel(const MouseWheelEvent &event, bool handled) + { + HandleMouseWheel(event); + if (!handled) handled = onMouseWheel.emit(event); + if (GetContainer()) { + MouseWheelEvent translatedEvent = MouseWheelEvent(event.direction, event.pos + GetPosition()); + handled = GetContainer()->TriggerMouseWheel(translatedEvent, handled); + } + return handled; + } + + bool Widget::TriggerJoystickButtonDown(const JoystickButtonEvent &event, bool handled) + { + HandleJoystickButtonDown(event); + if (!handled) handled = onJoystickButtonDown.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerJoystickButtonDown(event, handled); + return handled; + } + + bool Widget::TriggerJoystickButtonUp(const JoystickButtonEvent &event, bool handled) + { + HandleJoystickButtonUp(event); + if (!handled) handled = onJoystickButtonUp.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerJoystickButtonUp(event, handled); + return handled; + } + + bool Widget::TriggerJoystickAxisMove(const JoystickAxisMotionEvent &event, bool handled) + { + HandleJoystickAxisMove(event); + if (!handled) handled = onJoystickAxisMove.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerJoystickAxisMove(event, handled); + return handled; + } + + bool Widget::TriggerJoystickHatMove(const JoystickHatMotionEvent &event, bool handled) + { + HandleJoystickHatMove(event); + if (!handled) handled = onJoystickHatMove.emit(event); + if (GetContainer()) handled = GetContainer()->TriggerJoystickHatMove(event, handled); + return handled; + } + + bool Widget::TriggerMouseOver(const Point &pos, bool handled, Widget *stop) + { + // only send external events on state change + if (!m_mouseOver) { + m_mouseOver = true; + HandleMouseOver(); + if (!handled) handled = onMouseOver.emit(); + } + if (stop == this) return handled; + if (GetContainer()) handled = GetContainer()->TriggerMouseOver(pos + GetPosition(), handled, stop); + return handled; + } + + bool Widget::TriggerMouseOut(const Point &pos, bool handled, Widget *stop) + { + // only send external events on state change + if (m_mouseOver) { + HandleMouseOut(); + if (!handled) handled = onMouseOut.emit(); + m_mouseOver = false; + } + if (stop == this) return handled; + if (GetContainer()) handled = GetContainer()->TriggerMouseOut(pos + GetPosition(), handled, stop); + return handled; + } + + bool Widget::TriggerClick(bool handled) + { + HandleClick(); + if (!handled) handled = onClick.emit(); + if (GetContainer()) handled = GetContainer()->TriggerClick(handled); + return handled; + } + + void Widget::TriggerMouseActivate() + { + HandleMouseActivate(); + } + + void Widget::TriggerMouseDeactivate() + { + HandleMouseDeactivate(); + } + + void Widget::TriggerSelect() + { + HandleSelect(); + } + + void Widget::TriggerDeselect() + { + HandleDeselect(); + } + + void Widget::TriggerVisibilityChanged() + { + onVisibilityChanged.emit(m_visible); + } + + void Widget::RegisterBindPoint(const std::string &bindName, sigc::slot method) + { + m_bindPoints[bindName] = method; + } + + void Widget::Bind(const std::string &bindName, PropertiedObject *object, const std::string &propertyName) + { + const auto bindPointIter = m_bindPoints.find(bindName); + if (bindPointIter == m_bindPoints.end()) + return; + + sigc::connection conn = object->Properties().Connect(propertyName, (*bindPointIter).second); + + const auto bindIter = m_binds.find(bindName); + if (bindIter != m_binds.end()) { + (*bindIter).second.disconnect(); + (*bindIter).second = conn; + } else + m_binds.insert(bindIter, std::make_pair(bindName, conn)); + + (*bindPointIter).second(object->Properties(), propertyName); + } + +} // namespace UI diff --git a/src/ui/Widget.h b/src/ui/Widget.h index fec19f60d..472247391 100644 --- a/src/ui/Widget.h +++ b/src/ui/Widget.h @@ -4,12 +4,12 @@ #ifndef UI_WIDGET_H #define UI_WIDGET_H -#include "libs.h" -#include "Point.h" #include "Event.h" +#include "Point.h" +#include "PropertiedObject.h" #include "RefCounted.h" #include "WidgetSet.h" -#include "PropertiedObject.h" +#include "libs.h" #include #include @@ -82,366 +82,365 @@ namespace UI { -class Context; -class Container; -class Layer; + class Context; + class Container; + class Layer; -class Widget : public RefCounted { -protected: - // can't instantiate a base widget directly - Widget(Context *context); + class Widget : public RefCounted { + protected: + // can't instantiate a base widget directly + Widget(Context *context); -public: - virtual ~Widget(); + public: + virtual ~Widget(); - virtual Point PreferredSize() { return Point(); } - virtual void Layout() {} - virtual void Update() {} - virtual void Draw() = 0; + virtual Point PreferredSize() { return Point(); } + virtual void Layout() {} + virtual void Update() {} + virtual void Draw() = 0; - // gui context - Context *GetContext() const { return m_context; } + // gui context + Context *GetContext() const { return m_context; } - // enclosing container - Container *GetContainer() const { return m_container; } + // enclosing container + Container *GetContainer() const { return m_container; } - // size allocated to widget by container - const Point &GetSize() const { return m_size; } + // size allocated to widget by container + const Point &GetSize() const { return m_size; } - // position relative to container - const Point &GetPosition() const { return m_position; } + // position relative to container + const Point &GetPosition() const { return m_position; } - // position relative to top container - Point GetAbsolutePosition() const; + // position relative to top container + Point GetAbsolutePosition() const; - // size control flags let a widget tell its container how it wants to be - // sized when it can't get its preferred size - Uint32 GetSizeControlFlags() const { return m_sizeControlFlags; } - enum SizeControl { // - NO_WIDTH = 0x01, // do not contribute preferred width to the layout - NO_HEIGHT = 0x02, // do not contribute preferred height to the layout - EXPAND_WIDTH = 0x04, // ignore preferred width, give me as much as possible - EXPAND_HEIGHT = 0x08, // ignore preferred height, give me as much as possible - PRESERVE_ASPECT = 0x10, // allocate same aspect ratio as preferred size - }; + // size control flags let a widget tell its container how it wants to be + // sized when it can't get its preferred size + Uint32 GetSizeControlFlags() const { return m_sizeControlFlags; } + enum SizeControl { // + NO_WIDTH = 0x01, // do not contribute preferred width to the layout + NO_HEIGHT = 0x02, // do not contribute preferred height to the layout + EXPAND_WIDTH = 0x04, // ignore preferred width, give me as much as possible + EXPAND_HEIGHT = 0x08, // ignore preferred height, give me as much as possible + PRESERVE_ASPECT = 0x10, // allocate same aspect ratio as preferred size + }; - // draw offset. used to move a widget "under" its visible area (scissor) - void SetDrawOffset(const Point &drawOffset) { m_drawOffset = drawOffset; } - const Point &GetDrawOffset() const { return m_drawOffset; } + // draw offset. used to move a widget "under" its visible area (scissor) + void SetDrawOffset(const Point &drawOffset) { m_drawOffset = drawOffset; } + const Point &GetDrawOffset() const { return m_drawOffset; } - // active area of the widget. the widget may only want to use part of its - // allocated space. drawing will be clipped to the active area, and events - // that fall outside of the active area will be ignored. if a widget - // doesn't set its active area it defaults to its allocated space. - const Point &GetActiveOffset() const { return m_activeOffset; } - const Point &GetActiveArea() const { return m_activeArea; } + // active area of the widget. the widget may only want to use part of its + // allocated space. drawing will be clipped to the active area, and events + // that fall outside of the active area will be ignored. if a widget + // doesn't set its active area it defaults to its allocated space. + const Point &GetActiveOffset() const { return m_activeOffset; } + const Point &GetActiveArea() const { return m_activeArea; } - // determine if a point is inside a widgets active area - bool Contains(const Point &point) const { - const Point min_corner = (m_activeOffset - m_drawOffset); - const Point max_corner = (min_corner + m_activeArea); - return (point.x >= min_corner.x && point.y >= min_corner.y && point.x < max_corner.x && point.y < max_corner.y); - } - - // calculate layout contribution based on preferred size and flags - Point CalcLayoutContribution(); - // calculate size based on available space, preferred size and flags - Point CalcSize(const Point &avail); - - // fast way to determine if the widget is a container - virtual bool IsContainer() const { return false; } - - // selectable widgets may receive keyboard focus - virtual bool IsSelectable() const { return false; } - - // disabled widgets do not receive input - virtual void Disable(); - virtual void Enable(); - virtual void Hidden(); - - bool IsDisabled() const { return m_disabled; } - - bool IsHidden() const { return m_hidden; } - - bool IsMouseOver() const { return m_mouseOver; } - - bool IsOnTopLayer() const; - - // register a key that, when pressed and not handled by any other widget, - // will cause a click event to be sent to this widget - void AddShortcut(const KeySym &keysym) { m_shortcuts.insert(keysym); } - void RemoveShortcut(const KeySym &keysym) { m_shortcuts.erase(keysym); } - - // font size. obviously used for text size but also sometimes used for - // general widget size (eg space size). might do nothing, depends on the - // widget - enum Font { // - FONT_XSMALL, - FONT_SMALL, - FONT_NORMAL, - FONT_LARGE, - FONT_XLARGE, - - FONT_HEADING_XSMALL, - FONT_HEADING_SMALL, - FONT_HEADING_NORMAL, - FONT_HEADING_LARGE, - FONT_HEADING_XLARGE, - - FONT_MONO_XSMALL, - FONT_MONO_SMALL, - FONT_MONO_NORMAL, - FONT_MONO_LARGE, - FONT_MONO_XLARGE, - - FONT_MAX, // - - FONT_INHERIT, - - FONT_SMALLEST = FONT_XSMALL, // - FONT_LARGEST = FONT_XLARGE, // - FONT_HEADING_SMALLEST = FONT_HEADING_XSMALL, // - FONT_HEADING_LARGEST = FONT_HEADING_XLARGE, // - FONT_MONO_SMALLEST = FONT_MONO_XSMALL, // - FONT_MONO_LARGEST = FONT_MONO_XLARGE, // - }; - - virtual Widget *SetFont(Font font); - Font GetFont() const; - - // bind an object property to a widget bind point - void Bind(const std::string &bindName, PropertiedObject *object, const std::string &propertyName); - - // this sigc accumulator calls all the handlers for an event. if any of - // them return true, it returns true (indicating the event was handled), - // otherwise it returns false - struct EventHandlerResultAccumulator { - typedef bool result_type; - template - result_type operator()(T first, T last) const { - bool result = false; - for (; first != last; ++first) - if (*first) result = true; - return result; + // determine if a point is inside a widgets active area + bool Contains(const Point &point) const + { + const Point min_corner = (m_activeOffset - m_drawOffset); + const Point max_corner = (min_corner + m_activeArea); + return (point.x >= min_corner.x && point.y >= min_corner.y && point.x < max_corner.x && point.y < max_corner.y); } + + // calculate layout contribution based on preferred size and flags + Point CalcLayoutContribution(); + // calculate size based on available space, preferred size and flags + Point CalcSize(const Point &avail); + + // fast way to determine if the widget is a container + virtual bool IsContainer() const { return false; } + + // selectable widgets may receive keyboard focus + virtual bool IsSelectable() const { return false; } + + // disabled widgets do not receive input + virtual void Disable(); + virtual void Enable(); + virtual void Hidden(); + + bool IsDisabled() const { return m_disabled; } + + bool IsHidden() const { return m_hidden; } + + bool IsMouseOver() const { return m_mouseOver; } + + bool IsOnTopLayer() const; + + // register a key that, when pressed and not handled by any other widget, + // will cause a click event to be sent to this widget + void AddShortcut(const KeySym &keysym) { m_shortcuts.insert(keysym); } + void RemoveShortcut(const KeySym &keysym) { m_shortcuts.erase(keysym); } + + // font size. obviously used for text size but also sometimes used for + // general widget size (eg space size). might do nothing, depends on the + // widget + enum Font { // + FONT_XSMALL, + FONT_SMALL, + FONT_NORMAL, + FONT_LARGE, + FONT_XLARGE, + + FONT_HEADING_XSMALL, + FONT_HEADING_SMALL, + FONT_HEADING_NORMAL, + FONT_HEADING_LARGE, + FONT_HEADING_XLARGE, + + FONT_MONO_XSMALL, + FONT_MONO_SMALL, + FONT_MONO_NORMAL, + FONT_MONO_LARGE, + FONT_MONO_XLARGE, + + FONT_MAX, // + + FONT_INHERIT, + + FONT_SMALLEST = FONT_XSMALL, // + FONT_LARGEST = FONT_XLARGE, // + FONT_HEADING_SMALLEST = FONT_HEADING_XSMALL, // + FONT_HEADING_LARGEST = FONT_HEADING_XLARGE, // + FONT_MONO_SMALLEST = FONT_MONO_XSMALL, // + FONT_MONO_LARGEST = FONT_MONO_XLARGE, // + }; + + virtual Widget *SetFont(Font font); + Font GetFont() const; + + // bind an object property to a widget bind point + void Bind(const std::string &bindName, PropertiedObject *object, const std::string &propertyName); + + // this sigc accumulator calls all the handlers for an event. if any of + // them return true, it returns true (indicating the event was handled), + // otherwise it returns false + struct EventHandlerResultAccumulator { + typedef bool result_type; + template + result_type operator()(T first, T last) const + { + bool result = false; + for (; first != last; ++first) + if (*first) result = true; + return result; + } + }; + + // raw key events + sigc::signal::accumulated onKeyDown; + sigc::signal::accumulated onKeyUp; + + // text input, full unicode codepoint + sigc::signal::accumulated onTextInput; + + // mouse button presses + sigc::signal::accumulated onMouseDown; + sigc::signal::accumulated onMouseUp; + + // mouse movement + sigc::signal::accumulated onMouseMove; + + // mouse wheel moving + sigc::signal::accumulated onMouseWheel; + + // joystick events + sigc::signal::accumulated onJoystickAxisMove; + sigc::signal::accumulated onJoystickHatMove; + sigc::signal::accumulated onJoystickButtonDown; + sigc::signal::accumulated onJoystickButtonUp; + + // mouse entering or exiting widget area + sigc::signal::accumulated onMouseOver; + sigc::signal::accumulated onMouseOut; + + // click - primary mouse button press/release over widget. also + // synthesised when keyboard shortcut is used + sigc::signal::accumulated onClick; + + // Widget events + sigc::signal onVisibilityChanged; + + protected: + // magic constant for PreferredSize to indicate "as much as possible" + static const int SIZE_EXPAND = INT_MAX; + + // safely add two sizes, preserving SIZE_EXPAND + static inline int SizeAdd(int a, int b) { return a == SIZE_EXPAND || b == SIZE_EXPAND ? SIZE_EXPAND : a + b; } + static inline Point SizeAdd(const Point &a, const Point &b) { return Point(SizeAdd(a.x, b.x), SizeAdd(a.y, b.y)); } + + // set size control flags. no flags by default + void SetSizeControlFlags(Uint32 flags) { m_sizeControlFlags = flags; } + + // set the active area. defaults to the size allocated by the container + void SetActiveArea(const Point &activeArea, const Point &activeOffset = Point()); + + // mouse active. if a widget is mouse-active, it receives all mouse events + // regardless of mouse position + bool IsMouseActive() const; + + bool IsSelected() const; + + Point GetMousePos() const; + + // indicates whether the widget is part of the visible tree of widgets + // (ie, its chain of parents links to a Context) + bool IsVisible() const { return m_visible; } + + void SetDisabled(bool disabled) { m_disabled = disabled; } + void SetHidden(bool hidden) { m_hidden = hidden; } + + // internal event handlers. override to handle events. unlike the external + // on* signals, every widget in the stack is guaranteed to receive a call + // - there's no facility for stopping propogation up the stack + // + // as such, if you need to respond to an event inside a widget always + // without worrying about it being blocked, you should override the + // Handle* method instead of attaching to the signal. + virtual void HandleKeyDown(const KeyboardEvent &event) {} + virtual void HandleKeyUp(const KeyboardEvent &event) {} + virtual void HandleMouseDown(const MouseButtonEvent &event) {} + virtual void HandleMouseUp(const MouseButtonEvent &event) {} + virtual void HandleMouseMove(const MouseMotionEvent &event) {} + virtual void HandleMouseWheel(const MouseWheelEvent &event) {} + virtual void HandleJoystickAxisMove(const JoystickAxisMotionEvent &event) {} + virtual void HandleJoystickHatMove(const JoystickHatMotionEvent &event) {} + virtual void HandleJoystickButtonDown(const JoystickButtonEvent &event) {} + virtual void HandleJoystickButtonUp(const JoystickButtonEvent &event) {} + + virtual void HandleClick() {} + + virtual void HandleMouseOver() {} + virtual void HandleMouseOut() {} + + // internal synthesized events to indicate that a widget is being mouse + // activated or deactivated. very much like MouseDown/MouseUp except you + // get a guarantee that you will get a MouseDeactivate() call for every + // MouseActivate(). mouse clicks trigger this + virtual void HandleMouseActivate() {} + virtual void HandleMouseDeactivate() {} + + // text input event, a full unicode codepoint + virtual void HandleTextInput(const TextInputEvent &event) {} + + // internal synthesized events fired when a widget is selected or + // deselected. on mousedown, a widget becomes the selected widget unless + // its IsSelectable method returns false. the previously-selected widget + // (if there was one) gets deselected + virtual void HandleSelect() {} + virtual void HandleDeselect() {} + + virtual void HandleVisible() {} + virtual void HandleInvisible() {} + + void RegisterBindPoint(const std::string &bindName, sigc::slot method); + + float GetAnimatedOpacity() const { return m_animatedOpacity; } + float GetAnimatedPositionX() const { return m_animatedPositionX; } + float GetAnimatedPositionY() const { return m_animatedPositionY; } + + private: + // EventDispatcher needs to give us events + friend class EventDispatcher; + + // event triggers. when called: + // - calls the corresponding Handle* method on this widget (always) + // - fires the corresponding on* signal on this widget (iff handled is false) + // - calls the container Trigger* method with the new handled value returned + // by the on* signal + // + // what this means in practic is that Handle* will be called for every + // widget from here to the root, whereas signals will only be fired as + // long as the signals continue to return false (unhandled). + bool TriggerKeyDown(const KeyboardEvent &event, bool handled = false); + bool TriggerKeyUp(const KeyboardEvent &event, bool handled = false); + bool TriggerTextInput(const TextInputEvent &event, bool handled = false); + bool TriggerMouseDown(const MouseButtonEvent &event, bool handled = false); + bool TriggerMouseUp(const MouseButtonEvent &event, bool handled = false); + bool TriggerMouseMove(const MouseMotionEvent &event, bool handled = false); + bool TriggerMouseWheel(const MouseWheelEvent &event, bool handled = false); + + bool TriggerJoystickButtonDown(const JoystickButtonEvent &event, bool handled = false); + bool TriggerJoystickButtonUp(const JoystickButtonEvent &event, bool handled = false); + bool TriggerJoystickAxisMove(const JoystickAxisMotionEvent &event, bool handled = false); + bool TriggerJoystickHatMove(const JoystickHatMotionEvent &event, bool handled = false); + + bool TriggerClick(bool handled = false); + + // stop is used during disable/enable to stop delivery at the given widget + bool TriggerMouseOver(const Point &pos, bool handled = false, Widget *stop = 0); + bool TriggerMouseOut(const Point &pos, bool handled = false, Widget *stop = 0); + + void TriggerMouseActivate(); + void TriggerMouseDeactivate(); + + void TriggerSelect(); + void TriggerDeselect(); + + void TriggerVisibilityChanged(); + + // let container set our attributes. none of them make any sense if + // we're not in a container + friend class Container; + + // things for the container to call to attach, detach and position the + // widget. it could modify our data directly but that's ugly + void Attach(Container *container); + void Detach(); + void SetDimensions(const Point &position, const Point &size); + virtual void NotifyVisible(bool visible); + + // called by Container::CollectShortcuts + const std::set &GetShortcuts() const { return m_shortcuts; } + + // Context is the top-level container and needs to set its own context + // and size directly + friend class Context; + void SetSize(const Point &size) + { + m_size = size; + SetActiveArea(size); + } + + // Animation needs to change our animation attributes + friend class Animation; + + void SetAnimatedOpacity(float opacity) { m_animatedOpacity = opacity; } + void SetAnimatedPositionX(float pos) { m_animatedPositionX = pos; } + void SetAnimatedPositionY(float pos) { m_animatedPositionY = pos; } + + Context *m_context; + Container *m_container; + + Point m_position; + Point m_size; + + Uint32 m_sizeControlFlags; + + Point m_drawOffset; + + Point m_activeOffset; + Point m_activeArea; + + Font m_font; + + bool m_disabled; + bool m_hidden; + + bool m_mouseOver; + bool m_visible; + + std::set m_shortcuts; + + std::map> m_bindPoints; + std::map m_binds; + + float m_animatedOpacity; + float m_animatedPositionX; + float m_animatedPositionY; }; - - // raw key events - sigc::signal::accumulated onKeyDown; - sigc::signal::accumulated onKeyUp; - - // text input, full unicode codepoint - sigc::signal::accumulated onTextInput; - - // mouse button presses - sigc::signal::accumulated onMouseDown; - sigc::signal::accumulated onMouseUp; - - // mouse movement - sigc::signal::accumulated onMouseMove; - - // mouse wheel moving - sigc::signal::accumulated onMouseWheel; - - // joystick events - sigc::signal::accumulated onJoystickAxisMove; - sigc::signal::accumulated onJoystickHatMove; - sigc::signal::accumulated onJoystickButtonDown; - sigc::signal::accumulated onJoystickButtonUp; - - // mouse entering or exiting widget area - sigc::signal::accumulated onMouseOver; - sigc::signal::accumulated onMouseOut; - - // click - primary mouse button press/release over widget. also - // synthesised when keyboard shortcut is used - sigc::signal::accumulated onClick; - - // Widget events - sigc::signal onVisibilityChanged; - -protected: - - // magic constant for PreferredSize to indicate "as much as possible" - static const int SIZE_EXPAND = INT_MAX; - - // safely add two sizes, preserving SIZE_EXPAND - static inline int SizeAdd(int a, int b) { return a == SIZE_EXPAND || b == SIZE_EXPAND ? SIZE_EXPAND : a+b; } - static inline Point SizeAdd(const Point &a, const Point &b) { return Point(SizeAdd(a.x,b.x), SizeAdd(a.y,b.y)); } - - // set size control flags. no flags by default - void SetSizeControlFlags(Uint32 flags) { m_sizeControlFlags = flags; } - - // set the active area. defaults to the size allocated by the container - void SetActiveArea(const Point &activeArea, const Point &activeOffset = Point()); - - // mouse active. if a widget is mouse-active, it receives all mouse events - // regardless of mouse position - bool IsMouseActive() const; - - bool IsSelected() const; - - Point GetMousePos() const; - - // indicates whether the widget is part of the visible tree of widgets - // (ie, its chain of parents links to a Context) - bool IsVisible() const { return m_visible; } - - void SetDisabled(bool disabled) { m_disabled = disabled; } - void SetHidden(bool hidden) { m_hidden = hidden; } - - // internal event handlers. override to handle events. unlike the external - // on* signals, every widget in the stack is guaranteed to receive a call - // - there's no facility for stopping propogation up the stack - // - // as such, if you need to respond to an event inside a widget always - // without worrying about it being blocked, you should override the - // Handle* method instead of attaching to the signal. - virtual void HandleKeyDown(const KeyboardEvent &event) {} - virtual void HandleKeyUp(const KeyboardEvent &event) {} - virtual void HandleMouseDown(const MouseButtonEvent &event) {} - virtual void HandleMouseUp(const MouseButtonEvent &event) {} - virtual void HandleMouseMove(const MouseMotionEvent &event) {} - virtual void HandleMouseWheel(const MouseWheelEvent &event) {} - virtual void HandleJoystickAxisMove(const JoystickAxisMotionEvent &event) {} - virtual void HandleJoystickHatMove(const JoystickHatMotionEvent &event) {} - virtual void HandleJoystickButtonDown(const JoystickButtonEvent &event) {} - virtual void HandleJoystickButtonUp(const JoystickButtonEvent &event) {} - - virtual void HandleClick() {} - - virtual void HandleMouseOver() {} - virtual void HandleMouseOut() {} - - // internal synthesized events to indicate that a widget is being mouse - // activated or deactivated. very much like MouseDown/MouseUp except you - // get a guarantee that you will get a MouseDeactivate() call for every - // MouseActivate(). mouse clicks trigger this - virtual void HandleMouseActivate() {} - virtual void HandleMouseDeactivate() {} - - // text input event, a full unicode codepoint - virtual void HandleTextInput(const TextInputEvent &event) {} - - // internal synthesized events fired when a widget is selected or - // deselected. on mousedown, a widget becomes the selected widget unless - // its IsSelectable method returns false. the previously-selected widget - // (if there was one) gets deselected - virtual void HandleSelect() {} - virtual void HandleDeselect() {} - - virtual void HandleVisible() {} - virtual void HandleInvisible() {} - - void RegisterBindPoint(const std::string &bindName, sigc::slot method); - - - float GetAnimatedOpacity() const { return m_animatedOpacity; } - float GetAnimatedPositionX() const { return m_animatedPositionX; } - float GetAnimatedPositionY() const { return m_animatedPositionY; } - -private: - - // EventDispatcher needs to give us events - friend class EventDispatcher; - - // event triggers. when called: - // - calls the corresponding Handle* method on this widget (always) - // - fires the corresponding on* signal on this widget (iff handled is false) - // - calls the container Trigger* method with the new handled value returned - // by the on* signal - // - // what this means in practic is that Handle* will be called for every - // widget from here to the root, whereas signals will only be fired as - // long as the signals continue to return false (unhandled). - bool TriggerKeyDown(const KeyboardEvent &event, bool handled = false); - bool TriggerKeyUp(const KeyboardEvent &event, bool handled = false); - bool TriggerTextInput(const TextInputEvent &event, bool handled = false); - bool TriggerMouseDown(const MouseButtonEvent &event, bool handled = false); - bool TriggerMouseUp(const MouseButtonEvent &event, bool handled = false); - bool TriggerMouseMove(const MouseMotionEvent &event, bool handled = false); - bool TriggerMouseWheel(const MouseWheelEvent &event, bool handled = false); - - bool TriggerJoystickButtonDown(const JoystickButtonEvent &event, bool handled = false); - bool TriggerJoystickButtonUp(const JoystickButtonEvent &event, bool handled = false); - bool TriggerJoystickAxisMove(const JoystickAxisMotionEvent &event, bool handled = false); - bool TriggerJoystickHatMove(const JoystickHatMotionEvent &event, bool handled = false); - - bool TriggerClick(bool handled = false); - - // stop is used during disable/enable to stop delivery at the given widget - bool TriggerMouseOver(const Point &pos, bool handled = false, Widget *stop = 0); - bool TriggerMouseOut(const Point &pos, bool handled = false, Widget *stop = 0); - - void TriggerMouseActivate(); - void TriggerMouseDeactivate(); - - void TriggerSelect(); - void TriggerDeselect(); - - void TriggerVisibilityChanged(); - - // let container set our attributes. none of them make any sense if - // we're not in a container - friend class Container; - - // things for the container to call to attach, detach and position the - // widget. it could modify our data directly but that's ugly - void Attach(Container *container); - void Detach(); - void SetDimensions(const Point &position, const Point &size); - virtual void NotifyVisible(bool visible); - - // called by Container::CollectShortcuts - const std::set &GetShortcuts() const { return m_shortcuts; } - - - // Context is the top-level container and needs to set its own context - // and size directly - friend class Context; - void SetSize(const Point &size) { m_size = size; SetActiveArea(size); } - - - // Animation needs to change our animation attributes - friend class Animation; - - void SetAnimatedOpacity(float opacity) { m_animatedOpacity = opacity; } - void SetAnimatedPositionX(float pos) { m_animatedPositionX = pos; } - void SetAnimatedPositionY(float pos) { m_animatedPositionY = pos; } - - - Context *m_context; - Container *m_container; - - Point m_position; - Point m_size; - - Uint32 m_sizeControlFlags; - - Point m_drawOffset; - - Point m_activeOffset; - Point m_activeArea; - - Font m_font; - - bool m_disabled; - bool m_hidden; - - bool m_mouseOver; - bool m_visible; - - std::set m_shortcuts; - - std::map< std::string,sigc::slot > m_bindPoints; - std::map< std::string,sigc::connection > m_binds; - - float m_animatedOpacity; - float m_animatedPositionX; - float m_animatedPositionY; -}; - -} +} // namespace UI #endif diff --git a/src/ui/WidgetSet.h b/src/ui/WidgetSet.h index c622ee742..dfc267c1d 100644 --- a/src/ui/WidgetSet.h +++ b/src/ui/WidgetSet.h @@ -10,53 +10,100 @@ struct lua_State; namespace UI { -class Widget; + class Widget; -// Widget set. This class is a convenience to help add multiple widgets to a -// container in a single call -class WidgetSet { -public: - inline WidgetSet() : numWidgets(0) { } + // Widget set. This class is a convenience to help add multiple widgets to a + // container in a single call + class WidgetSet { + public: + inline WidgetSet() : + numWidgets(0) {} - inline WidgetSet(Widget *w0) : numWidgets(1) { - widgets.resize(1); - widgets[0] = w0; - } - inline WidgetSet(Widget *w0, Widget *w1) : numWidgets(2) { - widgets.resize(2); - widgets[0] = w0; widgets[1] = w1; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2) : numWidgets(3) { - widgets.resize(3); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3) : numWidgets(4) { - widgets.resize(4); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; widgets[3] = w3; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4) : numWidgets(5) { - widgets.resize(5); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; widgets[3] = w3; widgets[4] = w4; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5) : numWidgets(6) { - widgets.resize(6); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; widgets[3] = w3; widgets[4] = w4; widgets[5] = w5; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5, Widget *w6) : numWidgets(7) { - widgets.resize(7); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; widgets[3] = w3; widgets[4] = w4; widgets[5] = w5; widgets[6] = w6; - } - inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5, Widget *w6, Widget *w7) : numWidgets(8) { - widgets.resize(8); - widgets[0] = w0; widgets[1] = w1; widgets[2] = w2; widgets[3] = w3; widgets[4] = w4; widgets[5] = w5; widgets[6] = w6; widgets[7] = w7; - } + inline WidgetSet(Widget *w0) : + numWidgets(1) + { + widgets.resize(1); + widgets[0] = w0; + } + inline WidgetSet(Widget *w0, Widget *w1) : + numWidgets(2) + { + widgets.resize(2); + widgets[0] = w0; + widgets[1] = w1; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2) : + numWidgets(3) + { + widgets.resize(3); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3) : + numWidgets(4) + { + widgets.resize(4); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + widgets[3] = w3; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4) : + numWidgets(5) + { + widgets.resize(5); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + widgets[3] = w3; + widgets[4] = w4; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5) : + numWidgets(6) + { + widgets.resize(6); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + widgets[3] = w3; + widgets[4] = w4; + widgets[5] = w5; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5, Widget *w6) : + numWidgets(7) + { + widgets.resize(7); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + widgets[3] = w3; + widgets[4] = w4; + widgets[5] = w5; + widgets[6] = w6; + } + inline WidgetSet(Widget *w0, Widget *w1, Widget *w2, Widget *w3, Widget *w4, Widget *w5, Widget *w6, Widget *w7) : + numWidgets(8) + { + widgets.resize(8); + widgets[0] = w0; + widgets[1] = w1; + widgets[2] = w2; + widgets[3] = w3; + widgets[4] = w4; + widgets[5] = w5; + widgets[6] = w6; + widgets[7] = w7; + } - inline WidgetSet(const std::vector &w) : widgets(w), numWidgets(w.size()) { } + inline WidgetSet(const std::vector &w) : + widgets(w), + numWidgets(w.size()) {} - std::vector widgets; - std::size_t numWidgets; -}; + std::vector widgets; + std::size_t numWidgets; + }; -} +} // namespace UI #endif diff --git a/src/uitest.cpp b/src/uitest.cpp index 780d4ca49..4383cb69d 100644 --- a/src/uitest.cpp +++ b/src/uitest.cpp @@ -1,19 +1,19 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include -#include "SDL.h" -#include "ui/Context.h" #include "FileSystem.h" +#include "Lua.h" +#include "OS.h" +#include "PropertiedObject.h" +#include "SDL.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" #include "graphics/opengl/RendererGL.h" -#include "Lua.h" -#include "PropertiedObject.h" -#include "OS.h" +#include "ui/Context.h" +#include #include -static const int WIDTH = 1024; +static const int WIDTH = 1024; static const int HEIGHT = 768; #if 0 @@ -141,21 +141,21 @@ int main(int argc, char **argv) RefCountedPtr c(new UI::Context(Lua::manager, r, WIDTH, HEIGHT)); - UI::Grid *g = c->Grid(3,3); + UI::Grid *g = c->Grid(3, 3); UI::Image *img[9]; for (int y = 0; y < 3; y++) for (int x = 0; x < 3; x++) { - int i = y*3+x; + int i = y * 3 + x; img[i] = c->Image("textures/background.jpg"); g->SetCell(x, y, img[i]); c->Animate( new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_POSITION_X, 0.0f, false, - new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_PAUSE, float(i)*0.2, false, - new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_LINEAR, UI::Animation::TARGET_POSITION_X, 0.2f, false, nullptr, sigc::bind(sigc::ptr_fun(&animation_callback), i))))); + new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_PAUSE, float(i) * 0.2, false, + new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_LINEAR, UI::Animation::TARGET_POSITION_X, 0.2f, false, nullptr, sigc::bind(sigc::ptr_fun(&animation_callback), i))))); c->Animate( new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_POSITION_Y, 0.0f, false, - new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_PAUSE, float(i)*0.2, false, - new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_LINEAR, UI::Animation::TARGET_POSITION_Y, 0.2f, false)))); + new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_ZERO, UI::Animation::TARGET_PAUSE, float(i) * 0.2, false, + new UI::Animation(img[i], UI::Animation::TYPE_IN, UI::Animation::EASING_LINEAR, UI::Animation::TARGET_POSITION_Y, 0.2f, false)))); } c->GetTopLayer()->SetInnerWidget(g); @@ -681,10 +681,10 @@ int main(int argc, char **argv) c->Draw(); r->SwapBuffers(); -// thing.Update(); + // thing.Update(); -// slider->SetValue(slider->GetValue() + 0.01); -// gauge->SetValue(gauge->GetValue() + 0.1); + // slider->SetValue(slider->GetValue() + 0.01); + // gauge->SetValue(gauge->GetValue() + 0.1); #if 0 if (++count == 400) { @@ -704,7 +704,6 @@ int main(int argc, char **argv) if (++count % 100 == 0) toggle_disabled_handler(target); #endif - } c.Reset(); diff --git a/src/utils.cpp b/src/utils.cpp index 036b5dd98..934f9c0ab 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -2,47 +2,49 @@ // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt #include "utils.h" -#include "libs.h" -#include "gameconsts.h" -#include "StringF.h" -#include "gui/Gui.h" -#include "Lang.h" -#include "FileSystem.h" #include "DateTime.h" +#include "FileSystem.h" +#include "Lang.h" #include "PngWriter.h" -#include +#include "StringF.h" +#include "gameconsts.h" +#include "gui/Gui.h" +#include "libs.h" #include #include +#include -std::string format_money(double cents, bool showCents){ - char *end; // for error checking +std::string format_money(double cents, bool showCents) +{ + char *end; // for error checking size_t groupDigits = strtol(Lang::NUMBER_GROUP_NUM, &end, 10); assert(*end == 0); - double money = showCents ? 0.01*cents : roundf(0.01*cents); + double money = showCents ? 0.01 * cents : roundf(0.01 * cents); const char *format = (money < 0) ? "-$%.2f" : "$%.2f"; char buf[64]; snprintf(buf, sizeof(buf), format, fabs(money)); std::string result(buf); - size_t pos = result.find_first_of('.'); // pos to decimal point + size_t pos = result.find_first_of('.'); // pos to decimal point - if(showCents) // replace decimal point + if (showCents) // replace decimal point result.replace(pos, 1, Lang::NUMBER_DECIMAL_POINT); - else // or just remove frac. part + else // or just remove frac. part result.erase(result.begin() + pos, result.end()); size_t groupMin = strtol(Lang::NUMBER_GROUP_MIN, &end, 10); assert(*end == 0); - if(groupDigits != 0 && fabs(money) >= groupMin){ + if (groupDigits != 0 && fabs(money) >= groupMin) { std::string groupSep = std::string(Lang::NUMBER_GROUP_SEP) == " " ? - "\u00a0" : Lang::NUMBER_GROUP_SEP; // space should be fixed space + "\u00a0" : + Lang::NUMBER_GROUP_SEP; // space should be fixed space - size_t skip = (money < 0) ? 2 : 1; // compensate for "$" or "-$" - while(pos - skip > groupDigits){ // insert thousand seperator + size_t skip = (money < 0) ? 2 : 1; // compensate for "$" or "-$" + while (pos - skip > groupDigits) { // insert thousand seperator pos = pos - groupDigits; result.insert(pos, groupSep); } @@ -50,7 +52,7 @@ std::string format_money(double cents, bool showCents){ return result; } -static const char * const MONTH_NAMES[] = { +static const char *const MONTH_NAMES[] = { Lang::MONTH_JAN, Lang::MONTH_FEB, Lang::MONTH_MAR, @@ -73,8 +75,8 @@ std::string format_date(double t) dt.GetTimeParts(&hour, &minute, &second); char buf[32]; - snprintf(buf, sizeof (buf), "%02d:%02d:%02d %d %s %d", - hour, minute, second, day, MONTH_NAMES[month - 1], year); + snprintf(buf, sizeof(buf), "%02d:%02d:%02d %d %s %d", + hour, minute, second, day, MONTH_NAMES[month - 1], year); return buf; } @@ -85,7 +87,7 @@ std::string format_date_only(double t) dt.GetDateParts(&year, &month, &day); char buf[16]; - snprintf(buf, sizeof (buf), "%d %s %d", day, MONTH_NAMES[month - 1], year); + snprintf(buf, sizeof(buf), "%d %s %d", day, MONTH_NAMES[month - 1], year); return buf; } @@ -152,16 +154,20 @@ void OpenGLDebugMsg(const char *format, ...) static unsigned int __indentationLevel = 0; void IndentIncrease() { __indentationLevel++; } -void IndentDecrease() { assert(__indentationLevel > 0); __indentationLevel--; } +void IndentDecrease() +{ + assert(__indentationLevel > 0); + __indentationLevel--; +} void IndentedOutput(const char *format, ...) { - std::string indentation (__indentationLevel, '\t'); + std::string indentation(__indentationLevel, '\t'); char buf[1024]; va_list ap; va_start(ap, format); strcpy(buf, indentation.c_str()); int indentationSize = indentation.size(); - vsnprintf(buf + indentationSize, sizeof(buf)-indentationSize, format, ap); + vsnprintf(buf + indentationSize, sizeof(buf) - indentationSize, format, ap); va_end(ap); fputs(buf, stderr); @@ -176,17 +182,17 @@ std::string format_duration(double seconds) int hours = (duration / 60 / 60) % 24; int days = (duration / 60 / 60 / 24) % 7; int weeks = (duration / 60 / 60 / 24 / 7); - if(weeks != 0) + if (weeks != 0) ss << weeks << Lang::UNIT_WEEKS; - if(days != 0) + if (days != 0) ss << days << Lang::UNIT_DAYS; - if(hours != 0) + if (hours != 0) ss << hours << Lang::UNIT_HOURS; - if(minutes != 0) + if (minutes != 0) ss << minutes << Lang::UNIT_MINUTES; // do not show seconds unless the largest unit shown is minutes - if(weeks == 0 && days == 0 && hours == 0) - if(minutes == 0 || secs != 0) + if (weeks == 0 && days == 0 && hours == 0) + if (minutes == 0 || secs != 0) ss << secs << Lang::UNIT_SECONDS; return ss.str(); } @@ -198,24 +204,23 @@ std::string format_distance(double dist, int precision) if (dist < 1e3) { ss.precision(0); ss << dist << " m"; - } - else { + } else { const float LY = 9.4607e15f; ss.precision(precision); if (dist < 1e6) - ss << (dist*1e-3) << " km"; - else if (dist < AU*0.01) - ss << (dist*1e-6) << " Mm"; - else if (dist < LY*0.1) - ss << (dist/AU) << " " << Lang::UNIT_AU; + ss << (dist * 1e-3) << " km"; + else if (dist < AU * 0.01) + ss << (dist * 1e-6) << " Mm"; + else if (dist < LY * 0.1) + ss << (dist / AU) << " " << Lang::UNIT_AU; else - ss << (dist/LY) << " " << Lang::UNIT_LY; + ss << (dist / LY) << " " << Lang::UNIT_LY; } return ss.str(); } -void write_screenshot(const Graphics::ScreendumpState &sd, const char* destFile) +void write_screenshot(const Graphics::ScreendumpState &sd, const char *destFile) { const std::string dir = "screenshots"; FileSystem::userFiles.MakeDirectory(dir); @@ -231,7 +236,7 @@ void write_screenshot(const Graphics::ScreendumpState &sd, const char* destFile) #define TOLOWER(c) (isupper(static_cast(c)) ? tolower(static_cast(c)) : (static_cast(c))) -const char *pi_strcasestr (const char *haystack, const char *needle) +const char *pi_strcasestr(const char *haystack, const char *needle) { if (!*needle) return haystack; @@ -262,7 +267,7 @@ const char *pi_strcasestr (const char *haystack, const char *needle) } } -std::vector SplitString(const std::string& source, const std::string& delim) +std::vector SplitString(const std::string &source, const std::string &delim) { bool stringSplitted = false; std::vector splitted; @@ -273,16 +278,13 @@ std::vector SplitString(const std::string& source, const std::strin size_t delimPos = source.find(delim, startPos); // if delim found - if (delimPos != std::string::npos) - { + if (delimPos != std::string::npos) { std::string element = source.substr(startPos, delimPos); splitted.push_back(element); // prepare next loop startPos = delimPos + delim.length(); - } - else - { + } else { // push tail and exit splitted.push_back(source.substr(startPos)); stringSplitted = true; @@ -297,15 +299,19 @@ std::vector SplitString(const std::string& source, const std::strin #ifndef USE_HEX_FLOATS union fu32 { fu32() {} - fu32(float fIn) : f(fIn) {} - fu32(uint32_t uIn) : u(uIn) {} + fu32(float fIn) : + f(fIn) {} + fu32(uint32_t uIn) : + u(uIn) {} float f; uint32_t u; }; union fu64 { fu64() {} - fu64(double dIn) : d(dIn) {} - fu64(uint64_t uIn) : u(uIn) {} + fu64(double dIn) : + d(dIn) {} + fu64(uint64_t uIn) : + u(uIn) {} double d; uint64_t u; }; @@ -351,13 +357,13 @@ void Vector3fToStr(const vector3f &val, char *out, size_t size) static_assert(sizeof(vector3f) == 12, "vector3f isn't 12 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%a,%a,%a", val.x, val.y, val.z); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu32 a(val.x); fu32 b(val.y); fu32 c(val.z); - const int amt = sprintf(out, "(%" PRIu32",%" PRIu32",%" PRIu32")", a.u, b.u, c.u); - assert(static_cast(amt)<=size); + const int amt = sprintf(out, "(%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", a.u, b.u, c.u); + assert(static_cast(amt) <= size); #endif } @@ -367,13 +373,13 @@ void Vector3dToStr(const vector3d &val, char *out, size_t size) static_assert(sizeof(vector3d) == 24, "vector3d isn't 24 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%la,%la,%la", val.x, val.y, val.z); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu64 a(val.x); fu64 b(val.y); fu64 c(val.z); - const int amt = sprintf(out, "(%" PRIu64",%" PRIu64",%" PRIu64")", a.u, b.u, c.u); - assert(static_cast(amt)<=size); + const int amt = sprintf(out, "(%" PRIu64 ",%" PRIu64 ",%" PRIu64 ")", a.u, b.u, c.u); + assert(static_cast(amt) <= size); #endif } @@ -383,19 +389,19 @@ void Matrix3x3fToStr(const matrix3x3f &val, char *out, size_t size) static_assert(sizeof(matrix3x3f) == 36, "matrix3x3f isn't 36 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%a,%a,%a,%a,%a,%a,%a,%a,%a", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8]); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu32 fuvals[9]; - for(int i=0; i<9; i++) + for (int i = 0; i < 9; i++) fuvals[i].f = val[i]; const int amt = sprintf(out, - "(%" PRIu32",%" PRIu32",%" PRIu32 - ",%" PRIu32",%" PRIu32",%" PRIu32 - ",%" PRIu32",%" PRIu32",%" PRIu32")", + "(%" PRIu32 ",%" PRIu32 ",%" PRIu32 + ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 + ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", fuvals[0].u, fuvals[1].u, fuvals[2].u, fuvals[3].u, fuvals[4].u, fuvals[5].u, fuvals[6].u, fuvals[7].u, fuvals[8].u); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #endif } @@ -405,19 +411,19 @@ void Matrix3x3dToStr(const matrix3x3d &val, char *out, size_t size) static_assert(sizeof(matrix3x3d) == 72, "matrix3x3d isn't 72 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%a,%a,%a,%a,%a,%a,%a,%a,%a", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8]); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu64 fuvals[9]; - for(int i=0; i<9; i++) + for (int i = 0; i < 9; i++) fuvals[i].d = val[i]; const int amt = sprintf(out, - "(%" PRIu64",%" PRIu64",%" PRIu64 - ",%" PRIu64",%" PRIu64",%" PRIu64 - ",%" PRIu64",%" PRIu64",%" PRIu64")", + "(%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ")", fuvals[0].u, fuvals[1].u, fuvals[2].u, fuvals[3].u, fuvals[4].u, fuvals[5].u, fuvals[6].u, fuvals[7].u, fuvals[8].u); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #endif } @@ -427,21 +433,21 @@ void Matrix4x4fToStr(const matrix4x4f &val, char *out, size_t size) static_assert(sizeof(matrix4x4f) == 64, "matrix4x4f isn't 64 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], val[12], val[13], val[14], val[15]); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu32 fuvals[16]; - for(int i=0; i<16; i++) + for (int i = 0; i < 16; i++) fuvals[i].f = val[i]; const int amt = sprintf(out, - "(%" PRIu32",%" PRIu32",%" PRIu32",%" PRIu32 - ",%" PRIu32",%" PRIu32",%" PRIu32",%" PRIu32 - ",%" PRIu32",%" PRIu32",%" PRIu32",%" PRIu32 - ",%" PRIu32",%" PRIu32",%" PRIu32",%" PRIu32")", + "(%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 + ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 + ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 + ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", fuvals[0].u, fuvals[1].u, fuvals[2].u, fuvals[3].u, fuvals[4].u, fuvals[5].u, fuvals[6].u, fuvals[7].u, fuvals[8].u, fuvals[9].u, fuvals[10].u, fuvals[11].u, fuvals[12].u, fuvals[13].u, fuvals[14].u, fuvals[15].u); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #endif } @@ -451,21 +457,21 @@ void Matrix4x4dToStr(const matrix4x4d &val, char *out, size_t size) static_assert(sizeof(matrix4x4d) == 128, "matrix4x4d isn't 128 bytes"); #ifdef USE_HEX_FLOATS const int amt = std::sprintf(out, "%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], val[12], val[13], val[14], val[15]); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #else fu64 fuvals[16]; - for(int i=0; i<16; i++) + for (int i = 0; i < 16; i++) fuvals[i].d = val[i]; const int amt = sprintf(out, - "(%" PRIu64",%" PRIu64",%" PRIu64",%" PRIu64 - ",%" PRIu64",%" PRIu64",%" PRIu64",%" PRIu64 - ",%" PRIu64",%" PRIu64",%" PRIu64",%" PRIu64 - ",%" PRIu64",%" PRIu64",%" PRIu64",%" PRIu64")", + "(%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ")", fuvals[0].u, fuvals[1].u, fuvals[2].u, fuvals[3].u, fuvals[4].u, fuvals[5].u, fuvals[6].u, fuvals[7].u, fuvals[8].u, fuvals[9].u, fuvals[10].u, fuvals[11].u, fuvals[12].u, fuvals[13].u, fuvals[14].u, fuvals[15].u); - assert(static_cast(amt)<=size); + assert(static_cast(amt) <= size); #endif } @@ -519,7 +525,7 @@ float StrToFloat(const std::string &str) static_assert(sizeof(float) == 4, "float isn't 4 bytes"); fu32 uval; const int amt = sscanf(str.c_str(), "%" SCNu32, &uval.u); - assert(amt==1); + assert(amt == 1); return uval.f; #endif } @@ -537,7 +543,7 @@ double StrToDouble(const std::string &str) static_assert(sizeof(long long) == sizeof(uint64_t), "long long isn't equal in size to uint64_t"); fu64 uval; const int amt = sscanf(str.c_str(), "%" SCNu64, &uval.u); - assert(amt==1); + assert(amt == 1); return uval.d; #endif } @@ -567,11 +573,11 @@ void StrToVector3f(const char *str, vector3f &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%a,%a,%a", &val.x, &val.y, &val.z); - assert(amt==3); + assert(amt == 3); #else - fu32 a,b,c; - const int amt = std::sscanf(str, "(%" SCNu32",%" SCNu32",%" SCNu32")", &a.u, &b.u, &c.u); - assert(amt==3); + fu32 a, b, c; + const int amt = std::sscanf(str, "(%" SCNu32 ",%" SCNu32 ",%" SCNu32 ")", &a.u, &b.u, &c.u); + assert(amt == 3); val.x = a.f; val.y = b.f; val.z = c.f; @@ -583,11 +589,11 @@ void StrToVector3d(const char *str, vector3d &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%la,%la,%la", &val.x, &val.y, &val.z); - assert(amt==3); + assert(amt == 3); #else - fu64 a,b,c; - const int amt = std::sscanf(str, "(%" SCNu64",%" SCNu64",%" SCNu64")", &a.u, &b.u, &c.u); - assert(amt==3); + fu64 a, b, c; + const int amt = std::sscanf(str, "(%" SCNu64 ",%" SCNu64 ",%" SCNu64 ")", &a.u, &b.u, &c.u); + assert(amt == 3); val.x = a.d; val.y = b.d; val.z = c.d; @@ -599,15 +605,15 @@ void StrToMatrix3x3f(const char *str, matrix3x3f &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%a,%a,%a,%a,%a,%a,%a,%a,%a", &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7], &val[8]); - assert(amt==9); + assert(amt == 9); #else fu32 fu[9]; - const int amt = std::sscanf(str, "(%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32")", + const int amt = std::sscanf(str, "(%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ")", &fu[0].u, &fu[1].u, &fu[2].u, &fu[3].u, &fu[4].u, &fu[5].u, &fu[6].u, &fu[7].u, &fu[8].u); - assert(amt==9); - for(int i=0; i<9; i++) + assert(amt == 9); + for (int i = 0; i < 9; i++) val[i] = fu[i].f; #endif } @@ -617,15 +623,15 @@ void StrToMatrix3x3d(const char *str, matrix3x3d &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%la,%la,%la,%la,%la,%la,%la,%la,%la", &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7], &val[8]); - assert(amt==9); + assert(amt == 9); #else fu64 fu[9]; - const int amt = std::sscanf(str, "(%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64")", + const int amt = std::sscanf(str, "(%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ")", &fu[0].u, &fu[1].u, &fu[2].u, &fu[3].u, &fu[4].u, &fu[5].u, &fu[6].u, &fu[7].u, &fu[8].u); - assert(amt==9); - for(int i=0; i<9; i++) + assert(amt == 9); + for (int i = 0; i < 9; i++) val[i] = fu[i].d; #endif } @@ -635,16 +641,16 @@ void StrToMatrix4x4f(const char *str, matrix4x4f &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a,%a", &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7], &val[8], &val[9], &val[10], &val[11], &val[12], &val[13], &val[14], &val[15]); - assert(amt==16); + assert(amt == 16); #else fu32 fu[16]; - const int amt = std::sscanf(str, "(%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32",%" SCNu32")", + const int amt = std::sscanf(str, "(%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ")", &fu[0].u, &fu[1].u, &fu[2].u, &fu[3].u, &fu[4].u, &fu[5].u, &fu[6].u, &fu[7].u, &fu[8].u, &fu[9].u, &fu[10].u, &fu[11].u, &fu[12].u, &fu[13].u, &fu[14].u, &fu[15].u); - assert(amt==16); - for(int i=0; i<16; i++) + assert(amt == 16); + for (int i = 0; i < 16; i++) val[i] = fu[i].f; #endif } @@ -654,16 +660,16 @@ void StrToMatrix4x4d(const char *str, matrix4x4d &val) PROFILE_SCOPED() #ifdef USE_HEX_FLOATS const int amt = std::sscanf(str, "%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la,%la", &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7], &val[8], &val[9], &val[10], &val[11], &val[12], &val[13], &val[14], &val[15]); - assert(amt==16); + assert(amt == 16); #else fu64 fu[16]; - const int amt = std::sscanf(str, "(%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64",%" SCNu64")", + const int amt = std::sscanf(str, "(%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ",%" SCNu64 ")", &fu[0].u, &fu[1].u, &fu[2].u, &fu[3].u, &fu[4].u, &fu[5].u, &fu[6].u, &fu[7].u, &fu[8].u, &fu[9].u, &fu[10].u, &fu[11].u, &fu[12].u, &fu[13].u, &fu[14].u, &fu[15].u); - assert(amt==16); - for(int i=0; i<16; i++) + assert(amt == 16); + for (int i = 0; i < 16; i++) val[i] = fu[i].d; #endif } @@ -689,22 +695,22 @@ void hexdump(const unsigned char *buf, int len) for (int i = 0; i < len; i += HEXDUMP_CHUNK) { Output("0x%06x ", i); - count = ((len-i) > HEXDUMP_CHUNK ? HEXDUMP_CHUNK : len-i); + count = ((len - i) > HEXDUMP_CHUNK ? HEXDUMP_CHUNK : len - i); for (int j = 0; j < count; j++) { - if (j == HEXDUMP_CHUNK/2) Output(" "); - Output("%02x ", buf[i+j]); + if (j == HEXDUMP_CHUNK / 2) Output(" "); + Output("%02x ", buf[i + j]); } for (int j = count; j < HEXDUMP_CHUNK; j++) { - if (j == HEXDUMP_CHUNK/2) Output(" "); + if (j == HEXDUMP_CHUNK / 2) Output(" "); Output(" "); } Output(" "); for (int j = 0; j < count; j++) - Output("%c", isprint(buf[i+j]) ? buf[i+j] : '.'); + Output("%c", isprint(buf[i + j]) ? buf[i + j] : '.'); Output("\n"); } diff --git a/src/utils.h b/src/utils.h index d9a9144d7..9fe6b1412 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,11 +8,11 @@ #define NOMINMAX #endif +#include "libs.h" +#include +#include #include #include -#include -#include -#include "libs.h" #ifndef __GNUC__ #define __attribute(x) @@ -28,19 +28,19 @@ #endif // align x to a. taken from the Linux kernel -#define ALIGN(x,a) __ALIGN_MASK(x,(a-1)) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) +#define ALIGN(x, a) __ALIGN_MASK(x, (a - 1)) +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -void Error(const char *format, ...) __attribute((format(printf,1,2))) __attribute((noreturn)); -void Warning(const char *format, ...) __attribute((format(printf,1,2))); -void Output(const char *format, ...) __attribute((format(printf,1,2))); -void OpenGLDebugMsg(const char *format, ...) __attribute((format(printf,1,2))); +void Error(const char *format, ...) __attribute((format(printf, 1, 2))) __attribute((noreturn)); +void Warning(const char *format, ...) __attribute((format(printf, 1, 2))); +void Output(const char *format, ...) __attribute((format(printf, 1, 2))); +void OpenGLDebugMsg(const char *format, ...) __attribute((format(printf, 1, 2))); /** * Works like Output, but adds indent before message. * Call IndentIncrease and IndentDecrease to control indent level. */ -void IndentedOutput(const char *format, ...) __attribute((format(printf,1,2))); +void IndentedOutput(const char *format, ...) __attribute((format(printf, 1, 2))); void IndentIncrease(); void IndentDecrease(); @@ -50,12 +50,14 @@ struct MsgTimer { MsgTimer() { mTimer.Start(); } ~MsgTimer() {} - void Mark(const char *identifier) { + void Mark(const char *identifier) + { mTimer.SoftStop(); const double lastTiming = mTimer.avgms(); mTimer.SoftReset(); Output("(%lf) avgms in %s\n", lastTiming, identifier); } + protected: Profiler::Timer mTimer; }; @@ -64,10 +66,9 @@ std::string string_join(std::vector &v, std::string sep); std::string format_date(double time); std::string format_date_only(double time); std::string format_distance(double dist, int precision = 2); -std::string format_money(double cents, bool showCents=true); +std::string format_money(double cents, bool showCents = true); std::string format_duration(double seconds); - static inline Sint64 isqrt(Sint64 a) { // replace with cast from sqrt below which is between x7.3 (win32, Debug) & x15 (x64, Release) times faster @@ -76,78 +77,92 @@ static inline Sint64 isqrt(Sint64 a) static inline Sint64 isqrt(fixed v) { - Sint64 ret=0; + Sint64 ret = 0; Sint64 s; Sint64 ret_sq = -v.v - 1; - for(s=62; s>=0; s-=2){ + for (s = 62; s >= 0; s -= 2) { Sint64 b; - ret+= ret; - b=ret_sq + ((2*ret+1)<= nt) && (memcmp(s+(ns-nt), t, nt) == 0); +inline bool ends_with(const char *s, size_t ns, const char *t, size_t nt) +{ + return (ns >= nt) && (memcmp(s + (ns - nt), t, nt) == 0); } -inline bool ends_with(const char *s, const char *t) { +inline bool ends_with(const char *s, const char *t) +{ return ends_with(s, strlen(s), t, strlen(t)); } -inline bool ends_with(const std::string &s, const char *t) { +inline bool ends_with(const std::string &s, const char *t) +{ return ends_with(s.c_str(), s.size(), t, strlen(t)); } -inline bool ends_with(const std::string &s, const std::string &t) { +inline bool ends_with(const std::string &s, const std::string &t) +{ return ends_with(s.c_str(), s.size(), t.c_str(), t.size()); } -inline bool ends_with_ci(const char *s, size_t ns, const char *t, size_t nt) { - if (ns &outp return i; } -std::vector SplitString(const std::string& source, const std::string& delim); +std::vector SplitString(const std::string &source, const std::string &delim); // 'Numeric type' to string conversions. std::string FloatToStr(float val); @@ -240,12 +255,12 @@ std::string DecimalToDegMinSec(float dec); // round & roundf. taken from http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/auxiliary/util/u_math.h static inline double round(double x) { - return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5); + return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5); } static inline float roundf(float x) { - return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f); + return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f); } #endif /* _MSC_VER < 1800 */ diff --git a/src/vector2.h b/src/vector2.h index 7bbf8c402..b2f32a3ea 100644 --- a/src/vector2.h +++ b/src/vector2.h @@ -12,51 +12,86 @@ template class vector2 { public: - T x,y; + T x, y; - vector2() : x(0.0f), y(0.0f) {} - vector2(T _x, T _y) : x(_x), y(_y) {} - explicit vector2(int v) : x(T(v)), y(T(v)) {} - explicit vector2(unsigned int v) : x(T(v)), y(T(v)) {} - explicit vector2(T v) : x(v), y(v) {} - vector2(const vector2 &v) : x(v.x), y(v.y) {} - explicit vector2(const T v[2]) : x(v[0]), y(v[1]) {} + vector2() : + x(0.0f), + y(0.0f) {} + vector2(T _x, T _y) : + x(_x), + y(_y) {} + explicit vector2(int v) : + x(T(v)), + y(T(v)) {} + explicit vector2(unsigned int v) : + x(T(v)), + y(T(v)) {} + explicit vector2(T v) : + x(v), + y(v) {} + vector2(const vector2 &v) : + x(v.x), + y(v.y) {} + explicit vector2(const T v[2]) : + x(v[0]), + y(v[1]) {} - vector2 operator+(const vector2 &v) const { return vector2(x+v.x,y+v.y); } - vector2 operator-(const vector2 &v) const { return vector2(x-v.x,y-v.y); } - vector2 &operator+=(const vector2 &v) { x+=v.x; y+=v.y; return *this; } - vector2 &operator-=(const vector2 &v) { x-=v.x; y-=v.y; return *this; } - vector2 &operator*=(const T &a) { x*=a; y*=a; return *this; } - vector2 operator-() const { return vector2(-x,-y); } + vector2 operator+(const vector2 &v) const { return vector2(x + v.x, y + v.y); } + vector2 operator-(const vector2 &v) const { return vector2(x - v.x, y - v.y); } + vector2 &operator+=(const vector2 &v) + { + x += v.x; + y += v.y; + return *this; + } + vector2 &operator-=(const vector2 &v) + { + x -= v.x; + y -= v.y; + return *this; + } + vector2 &operator*=(const T &a) + { + x *= a; + y *= a; + return *this; + } + vector2 operator-() const { return vector2(-x, -y); } - bool operator==(const vector2 &a) const { + bool operator==(const vector2 &a) const + { return is_equal_exact(a.x, x) && is_equal_exact(a.y, y); } - bool ExactlyEqual(const vector2 &a) const { + bool ExactlyEqual(const vector2 &a) const + { return is_equal_exact(a.x, x) && is_equal_exact(a.y, y); } - friend vector2 operator*(const vector2 &v, const T &a) { return vector2(v.x*a, v.y*a); } - friend vector2 operator*(const T &a, const vector2 &v) { return v*a; } + friend vector2 operator*(const vector2 &v, const T &a) { return vector2(v.x * a, v.y * a); } + friend vector2 operator*(const T &a, const vector2 &v) { return v * a; } friend vector2 operator/(const vector2 &v, const T &a) { return vector2(v.x / a, v.y / a); } friend bool operator<(const vector2 &va, const vector2 &vb) { return va.LengthSqr() < vb.LengthSqr(); } - - T Length() const { return sqrt(x*x + y*y); } - T LengthSqr() const { return x*x + y*y; } - vector2 Normalized() const { const T invlen = 1.0f / sqrt(x*x + y*y); return vector2(x*invlen, y*invlen); } - vector2 NormalizedSafe() const { - const T lenSqr = x*x + y*y; + T Length() const { return sqrt(x * x + y * y); } + T LengthSqr() const { return x * x + y * y; } + vector2 Normalized() const + { + const T invlen = 1.0f / sqrt(x * x + y * y); + return vector2(x * invlen, y * invlen); + } + vector2 NormalizedSafe() const + { + const T lenSqr = x * x + y * y; if (lenSqr < 1e-18) // sqrt(lenSqr) < 1e-9 - return vector2(1,0); + return vector2(1, 0); else { const T invlen = sqrt(lenSqr); - return vector2(x/invlen, y/invlen); + return vector2(x / invlen, y / invlen); } } }; -typedef vector2 vector2f; +typedef vector2 vector2f; typedef vector2 vector2d; #endif diff --git a/src/vector3.h b/src/vector3.h index bd05172e6..f8ffaf6f0 100644 --- a/src/vector3.h +++ b/src/vector3.h @@ -4,29 +4,36 @@ #ifndef _VECTOR3_H #define _VECTOR3_H -#include -#include #include "FloatComparison.h" #include "vector2.h" +#include +#include // Need this pragma due to operator[] implementation. #pragma pack(4) -template struct other_floating_type {}; -template <> struct other_floating_type { typedef double type; }; -template <> struct other_floating_type { typedef float type; }; +template +struct other_floating_type {}; +template <> +struct other_floating_type { + typedef double type; +}; +template <> +struct other_floating_type { + typedef float type; +}; template class vector3 { public: - T x,y,z; + T x, y, z; // Constructor definitions are outside class declaration to enforce that // only float and double versions are possible. vector3(); vector3(const vector3 &v); vector3(const vector2f &v, T t); - explicit vector3(const T vals[3]); + explicit vector3(const T vals[3]); explicit vector3(T val); vector3(T _x, T _y, T _z); @@ -34,58 +41,112 @@ public: explicit vector3(const vector3::type> &v); explicit vector3(const typename other_floating_type::type vals[3]); - const T& operator[](const size_t i) const { return (const_cast(&x))[i]; } - T& operator[](const size_t i) { return (&x)[i]; } + const T &operator[](const size_t i) const { return (const_cast(&x))[i]; } + T &operator[](const size_t i) { return (&x)[i]; } - vector3 operator+(const vector3 &a) const { return vector3 (a.x+x, a.y+y, a.z+z); } - vector3 &operator+=(const vector3 &a) { x+=a.x; y+=a.y; z+=a.z; return *this; } - vector3 &operator-=(const vector3 &a) { x-=a.x; y-=a.y; z-=a.z; return *this; } - vector3 &operator*=(const float a) { x*=a; y*=a; z*=a; return *this; } - vector3 &operator*=(const double a) { x*=a; y*=a; z*=a; return *this; } - vector3 &operator/=(const float a) { const T inva = T(1.0/a); x*=inva; y*=inva; z*=inva; return *this; } - vector3 &operator/=(const double a) { const T inva = T(1.0/a); x*=inva; y*=inva; z*=inva; return *this; } - vector3 operator-(const vector3 &a) const { return vector3(x-a.x, y-a.y, z-a.z); } + vector3 operator+(const vector3 &a) const { return vector3(a.x + x, a.y + y, a.z + z); } + vector3 &operator+=(const vector3 &a) + { + x += a.x; + y += a.y; + z += a.z; + return *this; + } + vector3 &operator-=(const vector3 &a) + { + x -= a.x; + y -= a.y; + z -= a.z; + return *this; + } + vector3 &operator*=(const float a) + { + x *= a; + y *= a; + z *= a; + return *this; + } + vector3 &operator*=(const double a) + { + x *= a; + y *= a; + z *= a; + return *this; + } + vector3 &operator/=(const float a) + { + const T inva = T(1.0 / a); + x *= inva; + y *= inva; + z *= inva; + return *this; + } + vector3 &operator/=(const double a) + { + const T inva = T(1.0 / a); + x *= inva; + y *= inva; + z *= inva; + return *this; + } + vector3 operator-(const vector3 &a) const { return vector3(x - a.x, y - a.y, z - a.z); } vector3 operator-() const { return vector3(-x, -y, -z); } - bool operator==(const vector3 &a) const { + bool operator==(const vector3 &a) const + { return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z); } - bool ExactlyEqual(const vector3 &a) const { + bool ExactlyEqual(const vector3 &a) const + { return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z); } friend vector3 operator+(const vector3 &a, const T &scalar) { return vector3(a.x + scalar, a.y + scalar, a.z + scalar); } - friend vector3 operator+(const T scalar, const vector3 &a) { return a+scalar; } + friend vector3 operator+(const T scalar, const vector3 &a) { return a + scalar; } friend vector3 operator-(const vector3 &a, const T &scalar) { return vector3(a.x - scalar, a.y - scalar, a.z - scalar); } friend vector3 operator-(const T scalar, const vector3 &a) { return a - scalar; } - friend vector3 operator*(const vector3 &a, const vector3 &b) { return vector3(T(a.x*b.x), T(a.y*b.y), T(a.z*b.z)); } - friend vector3 operator*(const vector3 &a, const T scalar) { return vector3(T(a.x*scalar), T(a.y*scalar), T(a.z*scalar)); } + friend vector3 operator*(const vector3 &a, const vector3 &b) { return vector3(T(a.x * b.x), T(a.y * b.y), T(a.z * b.z)); } + friend vector3 operator*(const vector3 &a, const T scalar) { return vector3(T(a.x * scalar), T(a.y * scalar), T(a.z * scalar)); } //friend vector3 operator*(const vector3 &a, const double scalar) { return vector3(T(a.x*scalar), T(a.y*scalar), T(a.z*scalar)); } - friend vector3 operator*(const T scalar, const vector3 &a) { return a*scalar; } + friend vector3 operator*(const T scalar, const vector3 &a) { return a * scalar; } //friend vector3 operator*(const double scalar, const vector3 &a) { return a*scalar; } - friend vector3 operator/(const vector3 &a, const float scalar) { const T inv = 1.0/scalar; return vector3(a.x*inv, a.y*inv, a.z*inv); } - friend vector3 operator/(const vector3 &a, const double scalar) { const T inv = 1.0/scalar; return vector3(a.x*inv, a.y*inv, a.z*inv); } + friend vector3 operator/(const vector3 &a, const float scalar) + { + const T inv = 1.0 / scalar; + return vector3(a.x * inv, a.y * inv, a.z * inv); + } + friend vector3 operator/(const vector3 &a, const double scalar) + { + const T inv = 1.0 / scalar; + return vector3(a.x * inv, a.y * inv, a.z * inv); + } - vector3 Cross(const vector3 &b) const { return vector3 (y*b.z - z*b.y, z*b.x - x*b.z, x*b.y - y*b.x); } - T Dot(const vector3 &b) const { return x*b.x + y*b.y + z*b.z; } - T Length() const { return sqrt (x*x + y*y + z*z); } - T LengthSqr() const { return x*x + y*y + z*z; } - vector3 Normalized() const { const T l = 1.0f / sqrt(x*x + y*y + z*z); return vector3(x*l, y*l, z*l); } - vector3 NormalizedSafe() const { - const T lenSqr = x*x + y*y + z*z; + vector3 Cross(const vector3 &b) const { return vector3(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); } + T Dot(const vector3 &b) const { return x * b.x + y * b.y + z * b.z; } + T Length() const { return sqrt(x * x + y * y + z * z); } + T LengthSqr() const { return x * x + y * y + z * z; } + vector3 Normalized() const + { + const T l = 1.0f / sqrt(x * x + y * y + z * z); + return vector3(x * l, y * l, z * l); + } + vector3 NormalizedSafe() const + { + const T lenSqr = x * x + y * y + z * z; if (lenSqr < 1e-18) // sqrt(lenSqr) < 1e-9 - return vector3(1,0,0); + return vector3(1, 0, 0); else { const T l = sqrt(lenSqr); - return vector3(x/l, y/l, z/l); + return vector3(x / l, y / l, z / l); } } void Print() const { printf("v(%f,%f,%f)\n", x, y, z); } /* Rotate this vector about point o, in axis defined by v. */ - void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang) { + void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang) + { vector3 t; T a = o.x; T b = o.y; @@ -93,74 +154,145 @@ public: T u = __v.x; T v = __v.y; T w = __v.z; - T cos_a = cos (ang); - T sin_a = sin (ang); - T inv_poo = 1.0f/(u*u+v*v+w*w); - t.x = a*(v*v+w*w)+u*(-b*v-c*w+u*x+v*y+w*z)+(-a*(v*v+w*w)+u*(b*v+c*w-v*y-w*z)+(v*v+w*w)*x)*cos_a+ - sqrtf (u*u+v*v+w*w)*(-c*v+b*w-w*y+v*z)*sin_a; + T cos_a = cos(ang); + T sin_a = sin(ang); + T inv_poo = 1.0f / (u * u + v * v + w * w); + t.x = a * (v * v + w * w) + u * (-b * v - c * w + u * x + v * y + w * z) + (-a * (v * v + w * w) + u * (b * v + c * w - v * y - w * z) + (v * v + w * w) * x) * cos_a + + sqrtf(u * u + v * v + w * w) * (-c * v + b * w - w * y + v * z) * sin_a; t.x *= inv_poo; - t.y = b*(u*u+w*w)+v*(-a*u-c*w+u*x+v*y+w*z)+(-b*(u*u+w*w)+v*(a*u+c*w-u*x-w*z)+(u*u+w*w)*y)*cos_a+ - sqrtf (u*u+v*v+w*w)*(-c*u-a*w+w*x-u*z)*sin_a; + t.y = b * (u * u + w * w) + v * (-a * u - c * w + u * x + v * y + w * z) + (-b * (u * u + w * w) + v * (a * u + c * w - u * x - w * z) + (u * u + w * w) * y) * cos_a + + sqrtf(u * u + v * v + w * w) * (-c * u - a * w + w * x - u * z) * sin_a; t.y *= inv_poo; - t.z = c*(u*u+v*v)+w*(-a*u+b*v+u*x+v*y+w*z)+(-c*(u*u+v*v)+w*(a*u+b*v-u*x-v*y)+(u*u+v*v)*z)*cos_a+ - sqrtf (u*u+v*v+w*w)*(-b*u+a*v-v*x+u*y)*sin_a; + t.z = c * (u * u + v * v) + w * (-a * u + b * v + u * x + v * y + w * z) + (-c * (u * u + v * v) + w * (a * u + b * v - u * x - v * y) + (u * u + v * v) * z) * cos_a + + sqrtf(u * u + v * v + w * w) * (-b * u + a * v - v * x + u * y) * sin_a; t.z *= inv_poo; *this = t; } /* Rotate this vector about origin, in axis defined by v. */ - void ArbRotate(const vector3 &__v, T ang) { + void ArbRotate(const vector3 &__v, T ang) + { vector3 t; T u = __v.x; T v = __v.y; T w = __v.z; T cos_a = cos(ang); T sin_a = sin(ang); - T inv_poo = 1.0f/(u*u+v*v+w*w); - t.x = u*(u*x+v*y+w*z)+(u*(-v*y-w*z)+(v*v+w*w)*x)*cos_a+ - sqrtf (u*u+v*v+w*w)*(-w*y+v*z)*sin_a; + T inv_poo = 1.0f / (u * u + v * v + w * w); + t.x = u * (u * x + v * y + w * z) + (u * (-v * y - w * z) + (v * v + w * w) * x) * cos_a + + sqrtf(u * u + v * v + w * w) * (-w * y + v * z) * sin_a; t.x *= inv_poo; - t.y = v*(u*x+v*y+w*z)+(v*(-u*x-w*z)+(u*u+w*w)*y)*cos_a+ - sqrtf (u*u+v*v+w*w)*(w*x-u*z)*sin_a; + t.y = v * (u * x + v * y + w * z) + (v * (-u * x - w * z) + (u * u + w * w) * y) * cos_a + + sqrtf(u * u + v * v + w * w) * (w * x - u * z) * sin_a; t.y *= inv_poo; - t.z = w*(u*x+v*y+w*z)+(w*(-u*x-v*y)+(u*u+v*v)*z)*cos_a+ - sqrtf (u*u+v*v+w*w)*(-v*x+u*y)*sin_a; + t.z = w * (u * x + v * y + w * z) + (w * (-u * x - v * y) + (u * u + v * v) * z) * cos_a + + sqrtf(u * u + v * v + w * w) * (-v * x + u * y) * sin_a; t.z *= inv_poo; *this = t; } - void xy(const vector2 &v2) { x = v2.x; y = v2.y; } - void xz(const vector2 &v2) { x = v2.x; z = v2.y; } - void yz(const vector2 &v2) { y = v2.x; z = v2.y; } + void xy(const vector2 &v2) + { + x = v2.x; + y = v2.y; + } + void xz(const vector2 &v2) + { + x = v2.x; + z = v2.y; + } + void yz(const vector2 &v2) + { + y = v2.x; + z = v2.y; + } - vector2 xy() { return vector2(x,y); } - vector2 xz() { return vector2(x,z); } - vector2 yz() { return vector2(y,z); } - vector2 yx() { return vector2(y,x); } - vector2 zx() { return vector2(z,x); } + vector2 xy() { return vector2(x, y); } + vector2 xz() { return vector2(x, z); } + vector2 yz() { return vector2(y, z); } + vector2 yx() { return vector2(y, x); } + vector2 zx() { return vector2(z, x); } }; // These are here in this manner to enforce that only float and double versions are possible. -template<> inline vector3::vector3() {} -template<> inline vector3::vector3() {} -template<> inline vector3::vector3(const vector3 &v): x(v.x), y(v.y), z(v.z) {} -template<> inline vector3::vector3(const vector2f &v, float t): x(v.x), y(v.y), z(t) {} -template<> inline vector3::vector3(const vector3 &v): x(float(v.x)), y(float(v.y)), z(float(v.z)) {} -template<> inline vector3::vector3(const vector3 &v): x(v.x), y(v.y), z(v.z) {} -template<> inline vector3::vector3(const vector3 &v): x(v.x), y(v.y), z(v.z) {} -template<> inline vector3::vector3(const vector2f &v, double t): x(v.x), y(v.y), z(t) {} -template<> inline vector3::vector3(float val): x(val), y(val), z(val) {} -template<> inline vector3::vector3(double val): x(val), y(val), z(val) {} -template<> inline vector3::vector3(float _x, float _y, float _z): x(_x), y(_y), z(_z) {} -template<> inline vector3::vector3(double _x, double _y, double _z): x(_x), y(_y), z(_z) {} -template<> inline vector3::vector3(const float vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) {} -template<> inline vector3::vector3(const double vals[3]): x(float(vals[0])), y(float(vals[1])), z(float(vals[2])) {} -template<> inline vector3::vector3(const float vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) {} -template<> inline vector3::vector3(const double vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) {} +template <> +inline vector3::vector3() {} +template <> +inline vector3::vector3() {} +template <> +inline vector3::vector3(const vector3 &v) : + x(v.x), + y(v.y), + z(v.z) {} +template <> +inline vector3::vector3(const vector2f &v, float t) : + x(v.x), + y(v.y), + z(t) {} +template <> +inline vector3::vector3(const vector3 &v) : + x(float(v.x)), + y(float(v.y)), + z(float(v.z)) {} +template <> +inline vector3::vector3(const vector3 &v) : + x(v.x), + y(v.y), + z(v.z) {} +template <> +inline vector3::vector3(const vector3 &v) : + x(v.x), + y(v.y), + z(v.z) {} +template <> +inline vector3::vector3(const vector2f &v, double t) : + x(v.x), + y(v.y), + z(t) {} +template <> +inline vector3::vector3(float val) : + x(val), + y(val), + z(val) {} +template <> +inline vector3::vector3(double val) : + x(val), + y(val), + z(val) {} +template <> +inline vector3::vector3(float _x, float _y, float _z) : + x(_x), + y(_y), + z(_z) {} +template <> +inline vector3::vector3(double _x, double _y, double _z) : + x(_x), + y(_y), + z(_z) {} +template <> +inline vector3::vector3(const float vals[3]) : + x(vals[0]), + y(vals[1]), + z(vals[2]) {} +template <> +inline vector3::vector3(const double vals[3]) : + x(float(vals[0])), + y(float(vals[1])), + z(float(vals[2])) {} +template <> +inline vector3::vector3(const float vals[3]) : + x(vals[0]), + y(vals[1]), + z(vals[2]) {} +template <> +inline vector3::vector3(const double vals[3]) : + x(vals[0]), + y(vals[1]), + z(vals[2]) {} #pragma pack() -typedef vector3 vector3f; +typedef vector3 vector3f; typedef vector3 vector3d; #endif /* _VECTOR3_H */ diff --git a/src/win32/FileSystemWin32.cpp b/src/win32/FileSystemWin32.cpp index 9da7ae219..04e1bbc0d 100644 --- a/src/win32/FileSystemWin32.cpp +++ b/src/win32/FileSystemWin32.cpp @@ -3,12 +3,12 @@ #include "Win32Setup.h" -#include "libs.h" #include "FileSystem.h" #include "TextUtils.h" +#include "libs.h" #include "utils.h" -#include #include +#include #include #define WIN32_LEAN_AND_MEAN @@ -22,9 +22,10 @@ namespace FileSystem { - static std::string absolute_path(const std::string &path) { + static std::string absolute_path(const std::string &path) + { std::wstring wpath = transcode_utf8_to_utf16(path); - wchar_t buf[MAX_PATH+1]; + wchar_t buf[MAX_PATH + 1]; DWORD len = GetFullPathNameW(wpath.c_str(), MAX_PATH, buf, 0); buf[len] = L'\0'; return transcode_utf16_to_utf8(buf, len); @@ -55,7 +56,7 @@ namespace FileSystem { static std::string FindDataDir() { HMODULE exemodule = GetModuleHandleW(0); - wchar_t buf[MAX_PATH+1]; + wchar_t buf[MAX_PATH + 1]; DWORD nchars = GetModuleFileNameW(exemodule, buf, MAX_PATH); if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // I gave you MAX_PATH, what more do you want!? @@ -79,7 +80,7 @@ namespace FileSystem { return data_path; } - FileSourceFS::FileSourceFS(const std::string &root, bool trusted): + FileSourceFS::FileSourceFS(const std::string &root, bool trusted) : FileSource((root == "/") ? "" : absolute_path(root), trusted) {} FileSourceFS::~FileSourceFS() {} @@ -101,7 +102,8 @@ namespace FileSystem { return ty; } - static Time::DateTime datetime_for_filetime(FILETIME filetime) { + static Time::DateTime datetime_for_filetime(FILETIME filetime) + { Time::DateTime dt; SYSTEMTIME systime, localtime; @@ -115,7 +117,8 @@ namespace FileSystem { return dt; } - static Time::DateTime file_modtime_for_handle(HANDLE hfile) { + static Time::DateTime file_modtime_for_handle(HANDLE hfile) + { assert(hfile != INVALID_HANDLE_VALUE); Time::DateTime modtime; @@ -161,7 +164,7 @@ namespace FileSystem { } size_t size = size_t(large_size.QuadPart); - char *data = static_cast(std::malloc(size)); + char *data = static_cast(std::malloc(size)); if (!data) { // XXX handling memory allocation failure gracefully is too hard right now Output("failed when allocating buffer for '%s'\n", fullpath.c_str()); @@ -215,7 +218,7 @@ namespace FileSystem { output.push_back(MakeFileInfo(JoinPath(dirpath, fname), ty, modtime)); } - if (! FindNextFileW(dirhandle, &findinfo)) { + if (!FindNextFileW(dirhandle, &findinfo)) { err = GetLastError(); } else err = ERROR_SUCCESS; @@ -262,21 +265,21 @@ namespace FileSystem { return make_directory_raw(wfullpath); } - static FILE* open_file_raw(const std::string &fullpath, const wchar_t *mode) + static FILE *open_file_raw(const std::string &fullpath, const wchar_t *mode) { const std::wstring wfullpath = transcode_utf8_to_utf16(fullpath); return _wfopen(wfullpath.c_str(), mode); } - FILE* FileSourceFS::OpenReadStream(const std::string &path) + FILE *FileSourceFS::OpenReadStream(const std::string &path) { const std::string fullpath = JoinPathBelow(GetRoot(), path); return open_file_raw(fullpath, L"rb"); } - FILE* FileSourceFS::OpenWriteStream(const std::string &path, int flags) + FILE *FileSourceFS::OpenWriteStream(const std::string &path, int flags) { const std::string fullpath = JoinPathBelow(GetRoot(), path); return open_file_raw(fullpath, (flags & WRITE_TEXT) ? L"w" : L"wb"); } -} +} // namespace FileSystem diff --git a/src/win32/OSWin32.cpp b/src/win32/OSWin32.cpp index e8815d9c5..43aa9c549 100644 --- a/src/win32/OSWin32.cpp +++ b/src/win32/OSWin32.cpp @@ -5,46 +5,43 @@ #define NOMINMAX #include "Win32Setup.h" -#include "OS.h" #include "FileSystem.h" +#include "OS.h" #include "TextUtils.h" #ifdef WITH_BREAKPAD #include "breakpad/exception_handler.h" #endif #include +#include #include #include #include -#include extern "C" { - // This is the quickest and easiest way to enable using the nVidia GPU on a Windows laptop with a dedicated nVidia GPU and Optimus tech. - // enable optimus! - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +// This is the quickest and easiest way to enable using the nVidia GPU on a Windows laptop with a dedicated nVidia GPU and Optimus tech. +// enable optimus! +__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - // AMD have one too!!! - __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +// AMD have one too!!! +__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } - #ifdef RegisterClass #undef RegisterClass #endif #ifdef WITH_BREAKPAD using namespace google_breakpad; -ExceptionHandler* exceptionHandler = nullptr; +ExceptionHandler *exceptionHandler = nullptr; #endif #ifdef _MSC_VER -#pragma warning(disable: 4996) +#pragma warning(disable : 4996) #endif -namespace OS -{ +namespace OS { // anonymous namespace - namespace - { + namespace { static const std::string s_NoOSIdentified("No OS Identified\n"); struct OSVersion { @@ -53,7 +50,7 @@ namespace OS const char *name; }; static const struct OSVersion osVersions[] = { - { 10,0, "Windows 10" }, + { 10, 0, "Windows 10" }, { 6, 3, "Windows 8.1" }, { 6, 2, "Windows 8" }, { 6, 1, "Windows 7" }, @@ -62,94 +59,94 @@ namespace OS { 5, 0, "Windows 2000" }, { 0, 0, nullptr } }; - }; + }; // namespace -// Notify Windows that the window may become unresponsive -void NotifyLoadBegin() -{ - // XXX MinGW doesn't know this function + // Notify Windows that the window may become unresponsive + void NotifyLoadBegin() + { + // XXX MinGW doesn't know this function #ifndef __MINGW32__ - // XXX Remove the following call when loading is moved to a background thread - DisableProcessWindowsGhosting(); // Prevent Windows from whiting out the screen for "not responding" + // XXX Remove the following call when loading is moved to a background thread + DisableProcessWindowsGhosting(); // Prevent Windows from whiting out the screen for "not responding" #endif -} - -// Since there's no way to re-enable Window ghosting, do nothing -void NotifyLoadEnd() -{ -} - -const char *GetIconFilename() -{ - // SDL doc says "Win32 icons must be 32x32". - return "icons/badge32-8b.png"; -} - -void RedirectStdio() -{ - std::string output_path = FileSystem::JoinPath(FileSystem::GetUserDir(), "output.txt"); - std::wstring woutput_path = transcode_utf8_to_utf16(output_path); - - FILE *f; - - f = _wfreopen(woutput_path.c_str(), L"w", stderr); - if (!f) { - Output("ERROR: Couldn't redirect output to '%s': %s\n", output_path.c_str(), strerror(errno)); - } else { - setvbuf(f, 0, _IOLBF, BUFSIZ); } -} -void EnableFPE() -{ - // clear any outstanding exceptions before enabling, otherwise they'll - // trip immediately + // Since there's no way to re-enable Window ghosting, do nothing + void NotifyLoadEnd() + { + } + + const char *GetIconFilename() + { + // SDL doc says "Win32 icons must be 32x32". + return "icons/badge32-8b.png"; + } + + void RedirectStdio() + { + std::string output_path = FileSystem::JoinPath(FileSystem::GetUserDir(), "output.txt"); + std::wstring woutput_path = transcode_utf8_to_utf16(output_path); + + FILE *f; + + f = _wfreopen(woutput_path.c_str(), L"w", stderr); + if (!f) { + Output("ERROR: Couldn't redirect output to '%s': %s\n", output_path.c_str(), strerror(errno)); + } else { + setvbuf(f, 0, _IOLBF, BUFSIZ); + } + } + + void EnableFPE() + { + // clear any outstanding exceptions before enabling, otherwise they'll + // trip immediately #ifdef _MCW_EM - _clearfp(); - _controlfp(_EM_INEXACT | _EM_UNDERFLOW, _MCW_EM); + _clearfp(); + _controlfp(_EM_INEXACT | _EM_UNDERFLOW, _MCW_EM); #endif -} + } -void DisableFPE() -{ + void DisableFPE() + { #ifdef _MCW_EM - _controlfp(_MCW_EM, _MCW_EM); + _controlfp(_MCW_EM, _MCW_EM); #endif -} + } -Uint64 HFTimerFreq() -{ - LARGE_INTEGER i; - QueryPerformanceFrequency(&i); - return i.QuadPart; -} + Uint64 HFTimerFreq() + { + LARGE_INTEGER i; + QueryPerformanceFrequency(&i); + return i.QuadPart; + } -Uint64 HFTimer() -{ - LARGE_INTEGER i; - QueryPerformanceCounter(&i); - return i.QuadPart; -} + Uint64 HFTimer() + { + LARGE_INTEGER i; + QueryPerformanceCounter(&i); + return i.QuadPart; + } -int GetNumCores() -{ - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; -} + int GetNumCores() + { + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + } -// get hardware information -const std::string GetHardwareInfo() -{ - SYSTEM_INFO siSysInfo; + // get hardware information + const std::string GetHardwareInfo() + { + SYSTEM_INFO siSysInfo; - // Copy the hardware information to the SYSTEM_INFO structure. - GetSystemInfo(&siSysInfo); + // Copy the hardware information to the SYSTEM_INFO structure. + GetSystemInfo(&siSysInfo); - // Display the contents of the SYSTEM_INFO structure. - char infoString[2048]; - snprintf(infoString, 2048, - "Hardware information: \n \ + // Display the contents of the SYSTEM_INFO structure. + char infoString[2048]; + snprintf(infoString, 2048, + "Hardware information: \n \ OEM ID: %u\n \ Number of processors: %u\n \ Page size: %u\n \ @@ -157,171 +154,166 @@ const std::string GetHardwareInfo() Minimum application address: %p\n \ Maximum application address: %p\n \ Active processor mask: %I64u\n\n", - siSysInfo.dwOemId, - siSysInfo.dwNumberOfProcessors, - siSysInfo.dwPageSize, - siSysInfo.dwProcessorType, - siSysInfo.lpMinimumApplicationAddress, - siSysInfo.lpMaximumApplicationAddress, - siSysInfo.dwActiveProcessorMask); + siSysInfo.dwOemId, + siSysInfo.dwNumberOfProcessors, + siSysInfo.dwPageSize, + siSysInfo.dwProcessorType, + siSysInfo.lpMinimumApplicationAddress, + siSysInfo.lpMaximumApplicationAddress, + siSysInfo.dwActiveProcessorMask); - return std::string(infoString); -} + return std::string(infoString); + } -// Define the RtlGetVersion function pointer -typedef void (WINAPI *RtlGetVersion) (OSVERSIONINFOEXW*); + // Define the RtlGetVersion function pointer + typedef void(WINAPI *RtlGetVersion)(OSVERSIONINFOEXW *); -// Due to the miserable way that Windows handles version reporting to programs -// we're forced to improvise to find out what OS we're REALLY running on. -// This works by loading the NTDLL.dll, finding the RtlGetVersion function and -// calling that to ask what Windows that _it_ thinks that it is running. -BOOL GetVersionHackNTDLL(OSVERSIONINFOEX* os) -{ - HMODULE hMod; - RtlGetVersion func = nullptr; + // Due to the miserable way that Windows handles version reporting to programs + // we're forced to improvise to find out what OS we're REALLY running on. + // This works by loading the NTDLL.dll, finding the RtlGetVersion function and + // calling that to ask what Windows that _it_ thinks that it is running. + BOOL GetVersionHackNTDLL(OSVERSIONINFOEX *os) + { + HMODULE hMod; + RtlGetVersion func = nullptr; #ifdef UNICODE - OSVERSIONINFOEXW* osw = os; + OSVERSIONINFOEXW *osw = os; #else - OSVERSIONINFOEXW o; - OSVERSIONINFOEXW* osw = &o; + OSVERSIONINFOEXW o; + OSVERSIONINFOEXW *osw = &o; #endif - hMod = LoadLibrary(TEXT("ntdll.dll")); - if (hMod) { - func = (RtlGetVersion)GetProcAddress(hMod, "RtlGetVersion"); - if (func == nullptr) { - FreeLibrary(hMod); + hMod = LoadLibrary(TEXT("ntdll.dll")); + if (hMod) { + func = (RtlGetVersion)GetProcAddress(hMod, "RtlGetVersion"); + if (func == nullptr) { + FreeLibrary(hMod); + return FALSE; + } + ZeroMemory(osw, sizeof(*osw)); + osw->dwOSVersionInfoSize = sizeof(*osw); + func(osw); +#ifndef UNICODE + os->dwBuildNumber = osw->dwBuildNumber; + os->dwMajorVersion = osw->dwMajorVersion; + os->dwMinorVersion = osw->dwMinorVersion; + os->dwPlatformId = osw->dwPlatformId; + os->dwOSVersionInfoSize = sizeof(*os); + DWORD sz = sizeof(os->szCSDVersion); + WCHAR *src = osw->szCSDVersion; + unsigned char *dtc = (unsigned char *)os->szCSDVersion; + while (*src) + *dtc++ = (unsigned char)*src++; + *dtc = '\0'; +#endif + osw->dwBuildNumber; + } else { return FALSE; } - ZeroMemory(osw, sizeof(*osw)); - osw->dwOSVersionInfoSize = sizeof(*osw); - func(osw); -#ifndef UNICODE - os->dwBuildNumber = osw->dwBuildNumber; - os->dwMajorVersion = osw->dwMajorVersion; - os->dwMinorVersion = osw->dwMinorVersion; - os->dwPlatformId = osw->dwPlatformId; - os->dwOSVersionInfoSize = sizeof(*os); - DWORD sz = sizeof(os->szCSDVersion); - WCHAR* src = osw->szCSDVersion; - unsigned char* dtc = (unsigned char*)os->szCSDVersion; - while(*src) - *dtc++ = (unsigned char)*src++; - *dtc = '\0'; -#endif - osw->dwBuildNumber; + FreeLibrary(hMod); + return TRUE; } - else + + const std::string GetOSInfoString() { - return FALSE; - } - FreeLibrary(hMod); - return TRUE; -} + const std::string hwInfo = GetHardwareInfo(); -const std::string GetOSInfoString() -{ - const std::string hwInfo = GetHardwareInfo(); + std::string name; - std::string name; - - OSVERSIONINFOEX os; - if (GetVersionHackNTDLL(&os) == TRUE) - { - for (const OSVersion *scan = osVersions; scan->name; scan++) { - if (os.dwMajorVersion >= scan->major && os.dwMinorVersion >= scan->minor) { - name = scan->name; - break; + OSVERSIONINFOEX os; + if (GetVersionHackNTDLL(&os) == TRUE) { + for (const OSVersion *scan = osVersions; scan->name; scan++) { + if (os.dwMajorVersion >= scan->major && os.dwMinorVersion >= scan->minor) { + name = scan->name; + break; + } } - } - char verString[256]; - snprintf(verString, sizeof(verString), " (%u, %u, Build %u)", os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber); - name += std::string(verString); - } - else - { - // fallback option - OSVERSIONINFOA osa; - osa.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - GetVersionExA(&osa); + char verString[256]; + snprintf(verString, sizeof(verString), " (%u, %u, Build %u)", os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber); + name += std::string(verString); + } else { + // fallback option + OSVERSIONINFOA osa; + osa.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + GetVersionExA(&osa); - for (const OSVersion *scan = osVersions; scan->name; scan++) { - if (osa.dwMajorVersion >= scan->major && osa.dwMinorVersion >= scan->minor) { - name = scan->name; - break; + for (const OSVersion *scan = osVersions; scan->name; scan++) { + if (osa.dwMajorVersion >= scan->major && osa.dwMinorVersion >= scan->minor) { + name = scan->name; + break; + } } + char verString[256]; + snprintf(verString, sizeof(verString), " (%u, %u, Build %u)", osa.dwMajorVersion, osa.dwMinorVersion, osa.dwBuildNumber); + name += std::string(verString); } - char verString[256]; - snprintf(verString, sizeof(verString), " (%u, %u, Build %u)", osa.dwMajorVersion, osa.dwMinorVersion, osa.dwBuildNumber); - name += std::string(verString); + + if (name.empty()) + return hwInfo + s_NoOSIdentified; + + return hwInfo + name; } - if (name.empty()) - return hwInfo + s_NoOSIdentified; - - return hwInfo + name; -} - #ifdef WITH_BREAKPAD -/////////////////////////////////////////////////////// Google Breakpad -bool FilterCallback(void* context, EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion) -{ - return true; -} + /////////////////////////////////////////////////////// Google Breakpad + bool FilterCallback(void *context, EXCEPTION_POINTERS *exinfo, + MDRawAssertionInfo *assertion) + { + return true; + } -bool MinidumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) -{ - std::wstring msg = L"Unhandled exception occured.\n"; - msg.append(L"Crash information dump was written to: \n "); - msg.append(transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot() + "\\crashdumps")); - msg.append(L"\nMini-dump id: \n "); - msg.append(minidump_id); - MessageBoxW(NULL, - msg.c_str(), L"Game crashed!", MB_OK | MB_ICONERROR); + bool MinidumpCallback(const wchar_t *dump_path, + const wchar_t *minidump_id, + void *context, + EXCEPTION_POINTERS *exinfo, + MDRawAssertionInfo *assertion, + bool succeeded) + { + std::wstring msg = L"Unhandled exception occured.\n"; + msg.append(L"Crash information dump was written to: \n "); + msg.append(transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot() + "\\crashdumps")); + msg.append(L"\nMini-dump id: \n "); + msg.append(minidump_id); + MessageBoxW(NULL, + msg.c_str(), L"Game crashed!", MB_OK | MB_ICONERROR); - return succeeded; -} + return succeeded; + } #endif -void EnableBreakpad() -{ + void EnableBreakpad() + { #ifdef WITH_BREAKPAD - CustomClientInfo cci; - cci.count = 0; - cci.entries = nullptr; - std::wstring dumps_path; - dumps_path = transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot()); - FileSystem::userFiles.MakeDirectory("crashdumps"); - dumps_path.append(L"\\crashdumps"); - exceptionHandler = new ExceptionHandler( - dumps_path, // Dump path - FilterCallback, // Filter callback - MinidumpCallback, // Minidumps callback - nullptr, // Callback context - ExceptionHandler::HandlerType::HANDLER_ALL, // Handler types - MINIDUMP_TYPE::MiniDumpWithDataSegs, - L"", // Minidump server pipe name - &cci); // Custom client information + CustomClientInfo cci; + cci.count = 0; + cci.entries = nullptr; + std::wstring dumps_path; + dumps_path = transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot()); + FileSystem::userFiles.MakeDirectory("crashdumps"); + dumps_path.append(L"\\crashdumps"); + exceptionHandler = new ExceptionHandler( + dumps_path, // Dump path + FilterCallback, // Filter callback + MinidumpCallback, // Minidumps callback + nullptr, // Callback context + ExceptionHandler::HandlerType::HANDLER_ALL, // Handler types + MINIDUMP_TYPE::MiniDumpWithDataSegs, + L"", // Minidump server pipe name + &cci); // Custom client information #endif -} + } -// Open the Explorer/Finder/etc -bool SupportsFolderBrowser() -{ - return true; -} + // Open the Explorer/Finder/etc + bool SupportsFolderBrowser() + { + return true; + } -void OpenUserFolderBrowser() -{ - std::wstring dumps_path; - dumps_path = transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot()); - ShellExecuteW(NULL, L"open", dumps_path.c_str(), NULL, NULL, SW_SHOWNORMAL); -} + void OpenUserFolderBrowser() + { + std::wstring dumps_path; + dumps_path = transcode_utf8_to_utf16(FileSystem::userFiles.GetRoot()); + ShellExecuteW(NULL, L"open", dumps_path.c_str(), NULL, NULL, SW_SHOWNORMAL); + } } // namespace OS diff --git a/src/win32/TextUtils.cpp b/src/win32/TextUtils.cpp index 0d0f5398a..d18a66db3 100644 --- a/src/win32/TextUtils.cpp +++ b/src/win32/TextUtils.cpp @@ -13,7 +13,10 @@ std::wstring transcode_utf8_to_utf16(const char *s, size_t nbytes) { std::wstring buf(nbytes, L'x'); int reqchars = MultiByteToWideChar(CP_UTF8, 0, s, nbytes, &buf[0], buf.size()); - if (!reqchars) { fprintf(stderr, "failed to transcode UTF-8 to UTF-16\n"); abort(); } + if (!reqchars) { + fprintf(stderr, "failed to transcode UTF-8 to UTF-16\n"); + abort(); + } buf.resize(reqchars); return buf; } @@ -27,7 +30,10 @@ std::string transcode_utf16_to_utf8(const wchar_t *s, size_t nchars) { std::string buf(nchars * 2, 'x'); int reqbytes = WideCharToMultiByte(CP_UTF8, 0, s, nchars, &buf[0], buf.size(), 0, 0); - if (!reqbytes) { fprintf(stderr, "failed to transcode UTF-16 to UTF-8\n"); abort(); } + if (!reqbytes) { + fprintf(stderr, "failed to transcode UTF-16 to UTF-8\n"); + abort(); + } buf.resize(reqbytes); return buf; } diff --git a/src/win32/Win32Setup.h b/src/win32/Win32Setup.h index 9ddffa74e..49881cdae 100644 --- a/src/win32/Win32Setup.h +++ b/src/win32/Win32Setup.h @@ -9,15 +9,15 @@ // and GetFileSizeEx requires Windows 2000 and IE5. We include w32api.h to get // the symbolic constants for these things. #ifdef __MINGW32__ -# include -# ifdef WINVER -# undef WINVER -# endif -# ifdef RegisterClass -# undef RegisterClass -# endif -# define WINVER Windows2000 -# define _WIN32_IE IE5 +#include +#ifdef WINVER +#undef WINVER +#endif +#ifdef RegisterClass +#undef RegisterClass +#endif +#define WINVER Windows2000 +#define _WIN32_IE IE5 #endif #endif diff --git a/src/win32/WinMath.cpp b/src/win32/WinMath.cpp index dbe08e56e..ed2ad0f7c 100644 --- a/src/win32/WinMath.cpp +++ b/src/win32/WinMath.cpp @@ -5,34 +5,32 @@ #include "Win32Setup.h" -#include "libs.h" #include "Pi.h" +#include "libs.h" #include -#include #include +#include #include #include "WinMath.h" // Note that the functions Gamma and LogGamma are mutually dependent. -double Gamma -( - double x // We require x > 0 +double Gamma( + double x // We require x > 0 ) { - if (x <= 0.0) - { + if (x <= 0.0) { std::stringstream os; - os << "Invalid input argument " << x << ". Argument must be positive."; - throw std::invalid_argument( os.str() ); + os << "Invalid input argument " << x << ". Argument must be positive."; + throw std::invalid_argument(os.str()); } - // Split the function domain into three intervals: - // (0, 0.001), [0.001, 12), and (12, infinity) + // Split the function domain into three intervals: + // (0, 0.001), [0.001, 12), and (12, infinity) - /////////////////////////////////////////////////////////////////////////// - // First interval: (0, 0.001) + /////////////////////////////////////////////////////////////////////////// + // First interval: (0, 0.001) // // For small x, 1/Gamma(x) has power series x + gamma x^2 - ... // So in this range, 1/Gamma(x) = x + gamma x^2 with error on the order of x^3. @@ -40,146 +38,133 @@ double Gamma const double gamma = 0.577215664901532860606512090; // Euler's gamma constant - if (x < 0.001) - return 1.0/(x*(1.0 + gamma*x)); + if (x < 0.001) + return 1.0 / (x * (1.0 + gamma * x)); - /////////////////////////////////////////////////////////////////////////// - // Second interval: [0.001, 12) + /////////////////////////////////////////////////////////////////////////// + // Second interval: [0.001, 12) - if (x < 12.0) - { - // The algorithm directly approximates gamma over (1,2) and uses - // reduction identities to reduce other arguments to this interval. + if (x < 12.0) { + // The algorithm directly approximates gamma over (1,2) and uses + // reduction identities to reduce other arguments to this interval. double y = x; - int n = 0; - bool arg_was_less_than_one = (y < 1.0); + int n = 0; + bool arg_was_less_than_one = (y < 1.0); - // Add or subtract integers as necessary to bring y into (1,2) - // Will correct for this below - if (arg_was_less_than_one) - { - y += 1.0; - } - else - { - n = static_cast (floor(y)) - 1; // will use n later - y -= n; - } + // Add or subtract integers as necessary to bring y into (1,2) + // Will correct for this below + if (arg_was_less_than_one) { + y += 1.0; + } else { + n = static_cast(floor(y)) - 1; // will use n later + y -= n; + } - // numerator coefficients for approximation over the interval (1,2) - static const double p[] = - { - -1.71618513886549492533811E+0, - 2.47656508055759199108314E+1, - -3.79804256470945635097577E+2, - 6.29331155312818442661052E+2, - 8.66966202790413211295064E+2, - -3.14512729688483675254357E+4, - -3.61444134186911729807069E+4, - 6.64561438202405440627855E+4 - }; + // numerator coefficients for approximation over the interval (1,2) + static const double p[] = + { + -1.71618513886549492533811E+0, + 2.47656508055759199108314E+1, + -3.79804256470945635097577E+2, + 6.29331155312818442661052E+2, + 8.66966202790413211295064E+2, + -3.14512729688483675254357E+4, + -3.61444134186911729807069E+4, + 6.64561438202405440627855E+4 + }; - // denominator coefficients for approximation over the interval (1,2) - static const double q[] = - { - -3.08402300119738975254353E+1, - 3.15350626979604161529144E+2, - -1.01515636749021914166146E+3, - -3.10777167157231109440444E+3, - 2.25381184209801510330112E+4, - 4.75584627752788110767815E+3, - -1.34659959864969306392456E+5, - -1.15132259675553483497211E+5 - }; + // denominator coefficients for approximation over the interval (1,2) + static const double q[] = + { + -3.08402300119738975254353E+1, + 3.15350626979604161529144E+2, + -1.01515636749021914166146E+3, + -3.10777167157231109440444E+3, + 2.25381184209801510330112E+4, + 4.75584627752788110767815E+3, + -1.34659959864969306392456E+5, + -1.15132259675553483497211E+5 + }; - double num = 0.0; - double den = 1.0; - int i; + double num = 0.0; + double den = 1.0; + int i; - double z = y - 1; - for (i = 0; i < 8; i++) - { - num = (num + p[i])*z; - den = den*z + q[i]; - } - double result = num/den + 1.0; + double z = y - 1; + for (i = 0; i < 8; i++) { + num = (num + p[i]) * z; + den = den * z + q[i]; + } + double result = num / den + 1.0; - // Apply correction if argument was not initially in (1,2) - if (arg_was_less_than_one) - { - // Use identity gamma(z) = gamma(z+1)/z - // The variable "result" now holds gamma of the original y + 1 - // Thus we use y-1 to get back the orginal y. - result /= (y-1.0); - } - else - { - // Use the identity gamma(z+n) = z*(z+1)* ... *(z+n-1)*gamma(z) - for (i = 0; i < n; i++) - result *= y++; - } + // Apply correction if argument was not initially in (1,2) + if (arg_was_less_than_one) { + // Use identity gamma(z) = gamma(z+1)/z + // The variable "result" now holds gamma of the original y + 1 + // Thus we use y-1 to get back the orginal y. + result /= (y - 1.0); + } else { + // Use the identity gamma(z+n) = z*(z+1)* ... *(z+n-1)*gamma(z) + for (i = 0; i < n; i++) + result *= y++; + } return result; - } - - /////////////////////////////////////////////////////////////////////////// - // Third interval: [12, infinity) - - if (x > 171.624) - { - // Correct answer too large to display. Force +infinity. - double temp = DBL_MAX; - return temp*2.0; - } - - return exp(LogGamma(x)); -} - -double LogGamma -( - double x // x must be positive -) -{ - if (x <= 0.0) - { - std::stringstream os; - os << "Invalid input argument " << x << ". Argument must be positive."; - throw std::invalid_argument( os.str() ); } - if (x < 12.0) - { - return log(fabs(Gamma(x))); - } + /////////////////////////////////////////////////////////////////////////// + // Third interval: [12, infinity) + + if (x > 171.624) { + // Correct answer too large to display. Force +infinity. + double temp = DBL_MAX; + return temp * 2.0; + } + + return exp(LogGamma(x)); +} + +double LogGamma( + double x // x must be positive +) +{ + if (x <= 0.0) { + std::stringstream os; + os << "Invalid input argument " << x << ". Argument must be positive."; + throw std::invalid_argument(os.str()); + } + + if (x < 12.0) { + return log(fabs(Gamma(x))); + } // Abramowitz and Stegun 6.1.41 - // Asymptotic series should be good to at least 11 or 12 figures - // For error analysis, see Whittiker and Watson - // A Course in Modern Analysis (1927), page 252 + // Asymptotic series should be good to at least 11 or 12 figures + // For error analysis, see Whittiker and Watson + // A Course in Modern Analysis (1927), page 252 - static const double c[8] = - { - 1.0/12.0, - -1.0/360.0, - 1.0/1260.0, - -1.0/1680.0, - 1.0/1188.0, - -691.0/360360.0, - 1.0/156.0, - -3617.0/122400.0 - }; - double z = 1.0/(x*x); - double sum = c[7]; - for (int i=6; i >= 0; i--) - { - sum *= z; - sum += c[i]; - } - double series = sum/x; + static const double c[8] = + { + 1.0 / 12.0, + -1.0 / 360.0, + 1.0 / 1260.0, + -1.0 / 1680.0, + 1.0 / 1188.0, + -691.0 / 360360.0, + 1.0 / 156.0, + -3617.0 / 122400.0 + }; + double z = 1.0 / (x * x); + double sum = c[7]; + for (int i = 6; i >= 0; i--) { + sum *= z; + sum += c[i]; + } + double series = sum / x; - static const double halfLogTwoPi = 0.91893853320467274178032973640562; - double logGamma = (x - 0.5)*log(x) - x + halfLogTwoPi + series; + static const double halfLogTwoPi = 0.91893853320467274178032973640562; + double logGamma = (x - 0.5) * log(x) - x + halfLogTwoPi + series; return logGamma; } @@ -187,27 +172,26 @@ double LogGamma void TestGamma() { - struct TestCase - { + struct TestCase { double input; double expected; }; TestCase test[] = - { - // Test near branches in code for (0, 0.001), [0.001, 12), (12, infinity) - {1e-20, 1e+20}, - {2.19824158876e-16, 4.5490905327e+15}, // 0.99*DBL_EPSILON - {2.24265050974e-16, 4.45900953205e+15}, // 1.01*DBL_EPSILON - {0.00099, 1009.52477271}, - {0.00100, 999.423772485}, - {0.00101, 989.522792258}, - {6.1, 142.451944066}, - {11.999, 39819417.4793}, - {12, 39916800.0}, - {12.001, 40014424.1571}, - {15.2, 149037380723.0} - }; + { + // Test near branches in code for (0, 0.001), [0.001, 12), (12, infinity) + { 1e-20, 1e+20 }, + { 2.19824158876e-16, 4.5490905327e+15 }, // 0.99*DBL_EPSILON + { 2.24265050974e-16, 4.45900953205e+15 }, // 1.01*DBL_EPSILON + { 0.00099, 1009.52477271 }, + { 0.00100, 999.423772485 }, + { 0.00101, 989.522792258 }, + { 6.1, 142.451944066 }, + { 11.999, 39819417.4793 }, + { 12, 39916800.0 }, + { 12.001, 40014424.1571 }, + { 15.2, 149037380723.0 } + }; size_t numTests = sizeof(test) / sizeof(TestCase); @@ -216,20 +200,17 @@ void TestGamma() size_t worst_absolute_error_case = 0; size_t worst_relative_error_case = 0; - for (size_t t = 0; t < numTests; t++) - { - double computed = Gamma( test[t].input ); + for (size_t t = 0; t < numTests; t++) { + double computed = Gamma(test[t].input); double absolute_error = fabs(computed - test[t].expected); double relative_error = absolute_error / test[t].expected; - if (absolute_error > worst_absolute_error) - { + if (absolute_error > worst_absolute_error) { worst_absolute_error = absolute_error; worst_absolute_error_case = t; } - if (relative_error > worst_relative_error) - { + if (relative_error > worst_relative_error) { worst_relative_error = absolute_error; worst_relative_error_case = t; } @@ -241,7 +222,7 @@ void TestGamma() std::cout << "Worst absolute error: " << fabs(Gamma(x) - y) << "\nGamma( " - << x + << x << ") computed as " << Gamma(x) << " but exact value is " @@ -253,8 +234,8 @@ void TestGamma() y = test[t].expected; std::cout << "Worst relative error: " << (Gamma(x) - y) / y - << "\nGamma( " - << x + << "\nGamma( " + << x << ") computed as " << Gamma(x) << " but exact value is " @@ -264,24 +245,23 @@ void TestGamma() void TestLogGamma() { - struct TestCase - { + struct TestCase { double input; double expected; }; TestCase test[] = - { - {1e-12, 27.6310211159}, - {0.9999, 5.77297915613e-05}, - {1.0001, -5.77133422205e-05}, - {3.1, 0.787375083274}, - {6.3, 5.30734288962}, - {11.9999, 17.5020635801}, - {12, 17.5023078459}, - {12.0001, 17.5025521125}, - {27.4, 62.5755868211} - }; + { + { 1e-12, 27.6310211159 }, + { 0.9999, 5.77297915613e-05 }, + { 1.0001, -5.77133422205e-05 }, + { 3.1, 0.787375083274 }, + { 6.3, 5.30734288962 }, + { 11.9999, 17.5020635801 }, + { 12, 17.5023078459 }, + { 12.0001, 17.5025521125 }, + { 27.4, 62.5755868211 } + }; size_t numTests = sizeof(test) / sizeof(TestCase); @@ -290,20 +270,17 @@ void TestLogGamma() size_t worst_absolute_error_case = 0; size_t worst_relative_error_case = 0; - for (size_t t = 0; t < numTests; t++) - { - double computed = LogGamma( test[t].input ); + for (size_t t = 0; t < numTests; t++) { + double computed = LogGamma(test[t].input); double absolute_error = fabs(computed - test[t].expected); double relative_error = absolute_error / test[t].expected; - if (absolute_error > worst_absolute_error) - { + if (absolute_error > worst_absolute_error) { worst_absolute_error = absolute_error; worst_absolute_error_case = t; } - if (relative_error > worst_relative_error) - { + if (relative_error > worst_relative_error) { worst_relative_error = absolute_error; worst_relative_error_case = t; } @@ -315,7 +292,7 @@ void TestLogGamma() std::cout << "Worst absolute error: " << fabs(LogGamma(x) - y) << "\nGamma( " - << x + << x << ") computed as " << LogGamma(x) << " but exact value is " @@ -327,8 +304,8 @@ void TestLogGamma() y = test[t].expected; std::cout << "Worst relative error: " << (LogGamma(x) - y) / y - << "\nGamma( " - << x + << "\nGamma( " + << x << ") computed as " << LogGamma(x) << " but exact value is " @@ -336,11 +313,12 @@ void TestLogGamma() << "\n"; } -#if defined(_MSC_VER) && (_MSC_VER<=1700) +#if defined(_MSC_VER) && (_MSC_VER <= 1700) // http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvc/thread/25c923af-a824-40f8-8fd4-e5574bc147af/ -double asinh(double value) { +double asinh(double value) +{ double returned; - if(value>0.0) + if (value > 0.0) returned = log(value + sqrt(value * value + 1.0)); else returned = -log(-value + sqrt(value * value + 1.0)); @@ -348,8 +326,8 @@ double asinh(double value) { } // http://stackoverflow.com/questions/15539116/atanh-arc-hyperbolic-tangent-function-missing-in-ms-visual-c -double atanh (double x) //implements: return (log(1+x) - log(1-x))/2 +double atanh(double x) //implements: return (log(1+x) - log(1-x))/2 { - return (LogOnePlusX(x) - LogOnePlusX(-x))/2.0; + return (LogOnePlusX(x) - LogOnePlusX(-x)) / 2.0; } #endif diff --git a/src/win32/WinMath.h b/src/win32/WinMath.h index dc45fbe21..9b3153cdf 100644 --- a/src/win32/WinMath.h +++ b/src/win32/WinMath.h @@ -10,13 +10,12 @@ double LogGamma(double); double Gamma(double); -#if defined(_MSC_VER) && (_MSC_VER<=1700) +#if defined(_MSC_VER) && (_MSC_VER <= 1700) // http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvc/thread/25c923af-a824-40f8-8fd4-e5574bc147af/ double asinh(double value); // http://stackoverflow.com/questions/15539116/atanh-arc-hyperbolic-tangent-function-missing-in-ms-visual-c -double atanh (double x); //implements: return (log(1+x) - log(1-x))/2 +double atanh(double x); //implements: return (log(1+x) - log(1-x))/2 #endif #endif - diff --git a/src/win32/msvc_bug.cpp b/src/win32/msvc_bug.cpp index 115116071..ec2fc289c 100644 --- a/src/win32/msvc_bug.cpp +++ b/src/win32/msvc_bug.cpp @@ -6,21 +6,27 @@ class V { public: - double x,y,z; + double x, y, z; - V() {}; - V(double _x, double _y, double _z): x(_x), y(_y), z(_z) {} - V(const V &v): x(v.x), y(v.y), z(v.z) {} + V(){}; + V(double _x, double _y, double _z) : + x(_x), + y(_y), + z(_z) {} + V(const V &v) : + x(v.x), + y(v.y), + z(v.z) {} - V operator+(const V a) const { return V(a.x+x, a.y+y, a.z+z); } - friend V operator*(const V a, const double s) { return V(a.x*s, a.y*s, a.z*s); } + V operator+(const V a) const { return V(a.x + x, a.y + y, a.z + z); } + friend V operator*(const V a, const double s) { return V(a.x * s, a.y * s, a.z * s); } }; struct M { virtual void z(int *m) const {} }; -struct S: public M { +struct S : public M { void bug(); }; @@ -31,7 +37,8 @@ struct C { volatile void *g_q; -void S::bug() { +void S::bug() +{ g_q = this; new C(this); if (this != g_q) { @@ -41,12 +48,13 @@ void S::bug() { } } -C::C(const S *s) { +C::C(const S *s) +{ int m; s->z(&m); V mx; - mx*5 + mx*6; + mx * 5 + mx * 6; } /* int main() { diff --git a/src/win32/pch.h b/src/win32/pch.h index e171128e6..6450bf84f 100644 --- a/src/win32/pch.h +++ b/src/win32/pch.h @@ -3,36 +3,55 @@ #include "libs.h" -#include "collider/collider.h" #include "collider/CollisionContact.h" #include "collider/CollisionSpace.h" #include "collider/Geom.h" #include "collider/GeomTree.h" +#include "collider/collider.h" #include "Aabb.h" #include "Body.h" #include "CargoBody.h" -#include "galaxy/Sector.h" -#include "galaxy/StarSystem.h" #include "DynamicBody.h" #include "Factions.h" #include "FileSystem.h" -#include "fixed.h" #include "Frame.h" -#include "gameconsts.h" -#include "GeoPatchContext.h" #include "GeoPatch.h" +#include "GeoPatchContext.h" #include "GeoSphere.h" +#include "Object.h" +#include "ObjectViewerView.h" +#include "Pi.h" +#include "Planet.h" +#include "Player.h" +#include "Random.h" +#include "SectorView.h" +#include "Sfx.h" +#include "Ship.h" +#include "ShipCpanel.h" +#include "ShipType.h" +#include "SmartPtr.h" +#include "Space.h" +#include "SpaceStation.h" +#include "Star.h" +#include "SystemInfoView.h" +#include "SystemView.h" +#include "View.h" +#include "WorldView.h" +#include "fixed.h" +#include "galaxy/Sector.h" +#include "galaxy/StarSystem.h" +#include "gameconsts.h" #include "gui/Gui.h" #include "gui/GuiAdjustment.h" #include "gui/GuiButton.h" #include "gui/GuiContainer.h" #include "gui/GuiEvents.h" #include "gui/GuiFixed.h" +#include "gui/GuiISelectable.h" #include "gui/GuiImage.h" #include "gui/GuiImageButton.h" #include "gui/GuiImageRadioButton.h" -#include "gui/GuiISelectable.h" #include "gui/GuiLabel.h" #include "gui/GuiLabelSet.h" #include "gui/GuiMeterBar.h" @@ -46,24 +65,5 @@ #include "gui/GuiVScrollBar.h" #include "gui/GuiVScrollPortal.h" #include "gui/GuiWidget.h" -#include "Random.h" -#include "Object.h" -#include "ObjectViewerView.h" #include "perlin.h" -#include "Pi.h" -#include "Planet.h" -#include "Player.h" -#include "SectorView.h" -#include "Sfx.h" -#include "Ship.h" -#include "ShipCpanel.h" -#include "ShipType.h" -#include "SmartPtr.h" -#include "Space.h" -#include "SpaceStation.h" -#include "Star.h" -#include "SystemInfoView.h" -#include "SystemView.h" #include "utils.h" -#include "View.h" -#include "WorldView.h" diff --git a/src/win32/perlintest.cpp b/src/win32/perlintest.cpp index e676be3fc..d700fd614 100644 --- a/src/win32/perlintest.cpp +++ b/src/win32/perlintest.cpp @@ -1,19 +1,19 @@ // Copyright © 2008-2019 Pioneer Developers. See AUTHORS.txt for details // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -#include -#include "Random.h" #include "perlin.h" -#include "vector3.h" +#include "Random.h" #include "matrix4x4.h" +#include "vector3.h" +#include #include double testfunc() { Random rng; double r = 0.0; - for (int i=0; i<1000; i++) - r += noise(1000.0*rng.Double(), 1000.0*rng.Double(), 1000.0*rng.Double()); + for (int i = 0; i < 1000; i++) + r += noise(1000.0 * rng.Double(), 1000.0 * rng.Double(), 1000.0 * rng.Double()); return r; } @@ -21,10 +21,10 @@ double testfunc2() { Random rng; double r = 0.0; - for (int i=0; i<1000; i++) { - r += 1000.0*rng.Double(); - r += 1000.0*rng.Double(); - r += 1000.0*rng.Double(); + for (int i = 0; i < 1000; i++) { + r += 1000.0 * rng.Double(); + r += 1000.0 * rng.Double(); + r += 1000.0 * rng.Double(); } return r; } @@ -52,7 +52,7 @@ int main(int argc, char **argv) r += testfunc(); t4 = ReadTSC(); - printf ("Times: %i, %i, %i: result %f\n", t2-t1, t3-t2, t4-t3, r); + printf("Times: %i, %i, %i: result %f\n", t2 - t1, t3 - t2, t4 - t3, r); t1 = ReadTSC(); r += testfunc2(); @@ -62,11 +62,10 @@ int main(int argc, char **argv) r += testfunc2(); t4 = ReadTSC(); - printf ("Times: %i, %i, %i: result %f\n", t2-t1, t3-t2, t4-t3, r); + printf("Times: %i, %i, %i: result %f\n", t2 - t1, t3 - t2, t4 - t3, r); getchar(); return 0; } #pragma optimize("", on) -