├── .clang-format ├── .github └── workflows │ ├── build_doc.yaml │ └── build_windows.yaml ├── .gitignore ├── CMakeLists.txt ├── COPYRIGHT.txt ├── README.md ├── artwork ├── AUTHORS.md ├── AppIcon.png └── LuaSTG.svg ├── cmake ├── External.cmake ├── GenerateVersionHeader.cmake └── Platform.cmake ├── doc ├── graph │ ├── api │ │ └── overview.drawio │ └── guide │ │ ├── history.drawio │ │ └── subsystem │ │ ├── architecture.drawio │ │ ├── audiosystem.drawio │ │ └── vfssystem.drawio ├── package.json ├── src │ ├── .vuepress │ │ ├── components │ │ │ └── .gitkeep │ │ ├── config.js │ │ ├── enhanceApp.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── hero.svg │ │ │ └── logo.png │ │ └── styles │ │ │ ├── index.styl │ │ │ └── palette.styl │ ├── api │ │ ├── AdvancedAPI │ │ │ └── Overview.md │ │ ├── LegacyAPI │ │ │ ├── BuiltinConsts.md │ │ │ ├── BuiltinMethods.md │ │ │ └── BuiltinTypes.md │ │ ├── README.md │ │ └── asset │ │ │ └── overview.svg │ ├── guide │ │ ├── Cmdline.md │ │ ├── Compile.md │ │ ├── Console.md │ │ ├── History.md │ │ ├── README.md │ │ ├── Subsystem │ │ │ ├── Architecture.md │ │ │ ├── AssetSystem.md │ │ │ ├── AudioSystem.md │ │ │ ├── RenderSystem.md │ │ │ ├── ScriptSystem.md │ │ │ ├── VfsSystem.md │ │ │ └── asset │ │ │ │ ├── architecture.svg │ │ │ │ ├── audiosystem1.svg │ │ │ │ ├── audiosystem2.svg │ │ │ │ └── vfssystem.svg │ │ └── asset │ │ │ ├── console.png │ │ │ └── history.svg │ ├── i18n │ │ └── en │ │ │ ├── api │ │ │ └── README.md │ │ │ ├── guide │ │ │ └── README.md │ │ │ └── index.md │ └── index.md └── yarn.lock ├── include └── lstg │ ├── Core │ ├── AppBase.hpp │ ├── CircularQueue.hpp │ ├── ECS │ │ ├── Archetype.hpp │ │ ├── Chunk.hpp │ │ ├── ComponentDescriptor.hpp │ │ ├── Entity.hpp │ │ └── World.hpp │ ├── Encoding │ │ ├── Base64.hpp │ │ ├── Convert.hpp │ │ ├── EncodingError.hpp │ │ └── Unicode.hpp │ ├── Exception.hpp │ ├── Flag.hpp │ ├── Hash.hpp │ ├── IntrusiveHeap.hpp │ ├── IntrusiveList.hpp │ ├── IntrusiveSkipList.hpp │ ├── JniUtils.hpp │ ├── LRUCache.hpp │ ├── Logging.hpp │ ├── Math │ │ ├── Collider2D │ │ │ ├── ColliderShape.hpp │ │ │ └── IntersectCheck.hpp │ │ ├── Decibel.hpp │ │ ├── Randomizer.hpp │ │ ├── Rectangle.hpp │ │ └── VectorHelper.hpp │ ├── Pal.hpp │ ├── PreciseSleeper.hpp │ ├── Result.hpp │ ├── Span.hpp │ ├── Subsystem │ │ ├── Asset │ │ │ ├── Asset.hpp │ │ │ ├── AssetError.hpp │ │ │ ├── AssetLoader.hpp │ │ │ ├── AssetPool.hpp │ │ │ ├── BasicTexture2DAsset.hpp │ │ │ ├── BasicTexture2DAssetFactory.hpp │ │ │ ├── BasicTexture2DAssetLoader.hpp │ │ │ └── IAssetFactory.hpp │ │ ├── AssetSystem.hpp │ │ ├── Audio │ │ │ ├── AudioEngine.hpp │ │ │ ├── BusChannel.hpp │ │ │ ├── IDspPlugin.hpp │ │ │ ├── ISoundData.hpp │ │ │ ├── ISoundDecoder.hpp │ │ │ ├── SampleBuffer.hpp │ │ │ ├── SampleView.hpp │ │ │ └── SoundSource.hpp │ │ ├── AudioSystem.hpp │ │ ├── DebugGUI │ │ │ ├── ConsoleWindow.hpp │ │ │ ├── FrameTimeMonitor.hpp │ │ │ ├── MiniStatusWindow.hpp │ │ │ ├── MixerWindow.hpp │ │ │ ├── ProgressWindow.hpp │ │ │ └── Window.hpp │ │ ├── DebugGUISystem.hpp │ │ ├── EventBusSystem.hpp │ │ ├── GameController │ │ │ ├── Buttons.hpp │ │ │ └── ScanCodeMapping.hpp │ │ ├── GameControllerSystem.hpp │ │ ├── ISubsystem.hpp │ │ ├── ProfileSystem.hpp │ │ ├── Render │ │ │ ├── Camera.hpp │ │ │ ├── ColorRGBA32.hpp │ │ │ ├── ConstantBuffer.hpp │ │ │ ├── Drawing2D │ │ │ │ ├── CommandBuffer.hpp │ │ │ │ ├── CommandExecutor.hpp │ │ │ │ ├── FreeList.hpp │ │ │ │ ├── Particle.hpp │ │ │ │ ├── ParticleConfig.hpp │ │ │ │ ├── ParticleEmitter.hpp │ │ │ │ ├── ParticlePool.hpp │ │ │ │ ├── Sprite.hpp │ │ │ │ ├── SpriteDrawing.hpp │ │ │ │ ├── TextDrawing.hpp │ │ │ │ └── Texture2D.hpp │ │ │ ├── EffectFactory.hpp │ │ │ ├── Font │ │ │ │ ├── DynamicFontGlyphAtlas.hpp │ │ │ │ ├── FixedPoint.hpp │ │ │ │ ├── FontCollection.hpp │ │ │ │ ├── FontGlyphRasterParam.hpp │ │ │ │ ├── FontSize.hpp │ │ │ │ ├── IFontFace.hpp │ │ │ │ ├── IFontFactory.hpp │ │ │ │ └── ITextShaper.hpp │ │ │ ├── GraphDef │ │ │ │ ├── ConstantBufferDefinition.hpp │ │ │ │ ├── ConstantBufferValueType.hpp │ │ │ │ ├── DefinitionError.hpp │ │ │ │ ├── EffectDefinition.hpp │ │ │ │ ├── EffectPassDefinition.hpp │ │ │ │ ├── EffectPassGroupDefinition.hpp │ │ │ │ ├── MeshDefinition.hpp │ │ │ │ ├── ShaderDefinition.hpp │ │ │ │ ├── ShaderTextureDefinition.hpp │ │ │ │ └── ShaderVertexLayoutDefinition.hpp │ │ │ ├── GraphicsDefinitionCache.hpp │ │ │ ├── Material.hpp │ │ │ ├── Mesh.hpp │ │ │ ├── RenderDevice.hpp │ │ │ ├── RenderEvent.hpp │ │ │ ├── Texture.hpp │ │ │ └── Texture2DData.hpp │ │ ├── RenderSystem.hpp │ │ ├── Script │ │ │ ├── AutoBridgeHint.hpp │ │ │ ├── LuaClassRegister.hpp │ │ │ ├── LuaError.hpp │ │ │ ├── LuaModuleRegister.hpp │ │ │ ├── LuaPush.hpp │ │ │ ├── LuaRead.hpp │ │ │ ├── LuaReference.hpp │ │ │ ├── LuaStack.hpp │ │ │ ├── LuaState.hpp │ │ │ ├── SandBox.hpp │ │ │ └── Unpack.hpp │ │ ├── ScriptSystem.hpp │ │ ├── SubsystemContainer.hpp │ │ ├── SubsystemEvent.hpp │ │ ├── VFS │ │ │ ├── AndroidAssetFileSystem.hpp │ │ │ ├── AndroidAssetStream.hpp │ │ │ ├── BufferViewStream.hpp │ │ │ ├── ContainerStream.hpp │ │ │ ├── DeflateStream.hpp │ │ │ ├── FileStream.hpp │ │ │ ├── IFileSystem.hpp │ │ │ ├── IStream.hpp │ │ │ ├── InflateStream.hpp │ │ │ ├── LocalFileSystem.hpp │ │ │ ├── OverlayFileSystem.hpp │ │ │ ├── Path.hpp │ │ │ ├── RootFileSystem.hpp │ │ │ ├── WindowedStream.hpp │ │ │ └── ZipArchiveFileSystem.hpp │ │ ├── VirtualFileSystem.hpp │ │ └── WindowSystem.hpp │ ├── Text │ │ ├── CmdlineParser.hpp │ │ ├── IniParsingError.hpp │ │ ├── IniSaxParser.hpp │ │ └── JsonHelper.hpp │ ├── ThreadPool.hpp │ └── Timer.hpp │ └── v2 │ ├── Asset │ ├── EffectAsset.hpp │ ├── EffectAssetFactory.hpp │ ├── EffectAssetLoader.hpp │ ├── HgeFontAsset.hpp │ ├── HgeFontAssetFactory.hpp │ ├── HgeFontAssetLoader.hpp │ ├── HgeParticleAsset.hpp │ ├── HgeParticleAssetFactory.hpp │ ├── HgeParticleAssetLoader.hpp │ ├── MusicAsset.hpp │ ├── MusicAssetFactory.hpp │ ├── MusicAssetLoader.hpp │ ├── SoundAsset.hpp │ ├── SoundAssetFactory.hpp │ ├── SoundAssetLoader.hpp │ ├── SpriteAsset.hpp │ ├── SpriteAssetFactory.hpp │ ├── SpriteAssetLoader.hpp │ ├── SpriteSequenceAsset.hpp │ ├── SpriteSequenceAssetFactory.hpp │ ├── SpriteSequenceAssetLoader.hpp │ ├── TextureAsset.hpp │ ├── TextureAssetFactory.hpp │ ├── TextureAssetLoader.hpp │ ├── TrueTypeFontAsset.hpp │ ├── TrueTypeFontAssetFactory.hpp │ └── TrueTypeFontAssetLoader.hpp │ ├── AssetNaming.hpp │ ├── AssetPools.hpp │ ├── BlendMode.hpp │ ├── Bridge │ ├── AssetManagerModule.hpp │ ├── AudioModule.hpp │ ├── BuiltInModules.hpp │ ├── GameObjectModule.hpp │ ├── Helper.hpp │ ├── InputModule.hpp │ ├── LSTGBentLaserData.hpp │ ├── LSTGColor.hpp │ ├── LSTGRandomizer.hpp │ ├── LfsBridgeModule.hpp │ ├── MathModule.hpp │ ├── MiscModule.hpp │ ├── RenderModule.hpp │ └── SystemModule.hpp │ ├── DebugGUI │ └── PerformanceMonitor.hpp │ ├── GameApp.hpp │ ├── GamePlay │ ├── BentLaser.hpp │ ├── Components │ │ ├── Collider.hpp │ │ ├── LifeTime.hpp │ │ ├── Movement.hpp │ │ ├── Renderer.hpp │ │ ├── Script.hpp │ │ └── Transform.hpp │ ├── GameWorld.hpp │ └── ScriptObjectPool.hpp │ └── MathAlias.hpp ├── src ├── Core │ ├── AppBase.cpp │ ├── CMakeLists.txt │ ├── ECS │ │ ├── Archetype.cpp │ │ ├── Chunk.cpp │ │ ├── Entity.cpp │ │ └── World.cpp │ ├── Encoding │ │ ├── Base64.cpp │ │ ├── EncodingError.cpp │ │ └── Unicode.cpp │ ├── JniUtils.cpp │ ├── Logging.cpp │ ├── Pal.cpp │ ├── PreciseSleeper.cpp │ ├── Subsystem │ │ ├── Asset │ │ │ ├── Asset.cpp │ │ │ ├── AssetError.cpp │ │ │ ├── AssetLoader.cpp │ │ │ ├── AssetPool.cpp │ │ │ ├── BasicTexture2DAsset.cpp │ │ │ ├── BasicTexture2DAssetFactory.cpp │ │ │ ├── BasicTexture2DAssetLoader.cpp │ │ │ └── detail │ │ │ │ └── WeakPtrTraits.hpp │ │ ├── AssetSystem.cpp │ │ ├── Audio │ │ │ ├── AudioEngine.cpp │ │ │ ├── BusChannel.cpp │ │ │ ├── DspPlugins │ │ │ │ ├── Filter.cpp │ │ │ │ ├── Filter.hpp │ │ │ │ ├── Limiter.cpp │ │ │ │ ├── Limiter.hpp │ │ │ │ ├── Reverb.cpp │ │ │ │ └── Reverb.hpp │ │ │ ├── MemorySoundData.cpp │ │ │ ├── MemorySoundData.hpp │ │ │ ├── NullSoundDecoder.cpp │ │ │ ├── NullSoundDecoder.hpp │ │ │ ├── SDLSoundDecoder.cpp │ │ │ ├── SDLSoundDecoder.hpp │ │ │ ├── SampleView.cpp │ │ │ ├── StreamSoundData.cpp │ │ │ ├── StreamSoundData.hpp │ │ │ └── detail │ │ │ │ ├── ALHandler.cpp │ │ │ │ ├── ALHandler.hpp │ │ │ │ ├── AudioDevice.cpp │ │ │ │ ├── AudioDevice.hpp │ │ │ │ ├── AudioEngineError.cpp │ │ │ │ ├── AudioEngineError.hpp │ │ │ │ ├── SDLSoundError.cpp │ │ │ │ ├── SDLSoundError.hpp │ │ │ │ └── StaticTopologicalSorter.hpp │ │ ├── AudioSystem.cpp │ │ ├── DebugGUI │ │ │ ├── ConsoleWindow.cpp │ │ │ ├── FrameTimeMonitor.cpp │ │ │ ├── MiniStatusWindow.cpp │ │ │ ├── MixerWindow.cpp │ │ │ ├── ProgressWindow.cpp │ │ │ ├── Window.cpp │ │ │ └── detail │ │ │ │ ├── ImGuiRenderer.cpp │ │ │ │ └── ImGuiRenderer.hpp │ │ ├── DebugGUISystem.cpp │ │ ├── EventBusSystem.cpp │ │ ├── GameController │ │ │ ├── Buttons.cpp │ │ │ └── ScanCodeMapping.cpp │ │ ├── GameControllerSystem.cpp │ │ ├── ISubsystem.cpp │ │ ├── ProfileSystem.cpp │ │ ├── Render │ │ │ ├── Camera.cpp │ │ │ ├── ConstantBuffer.cpp │ │ │ ├── Drawing2D │ │ │ │ ├── CommandBuffer.cpp │ │ │ │ ├── CommandExecutor.cpp │ │ │ │ ├── Particle.cpp │ │ │ │ ├── ParticleConfig.cpp │ │ │ │ ├── ParticleEmitter.cpp │ │ │ │ ├── ParticlePool.cpp │ │ │ │ ├── Sprite.cpp │ │ │ │ ├── TextDrawing.cpp │ │ │ │ └── Texture2D.cpp │ │ │ ├── EffectFactory.cpp │ │ │ ├── Font │ │ │ │ ├── DynamicFontGlyphAtlas.cpp │ │ │ │ ├── FontCollection.cpp │ │ │ │ ├── FreeTypeFontFace.cpp │ │ │ │ ├── FreeTypeFontFace.hpp │ │ │ │ ├── FreeTypeFontFactory.cpp │ │ │ │ ├── FreeTypeFontFactory.hpp │ │ │ │ ├── HarfBuzzTextShaper.cpp │ │ │ │ ├── HarfBuzzTextShaper.hpp │ │ │ │ ├── HgeFontFace.cpp │ │ │ │ ├── HgeFontFace.hpp │ │ │ │ ├── HgeFontFactory.cpp │ │ │ │ ├── HgeFontFactory.hpp │ │ │ │ ├── IFontFactory.cpp │ │ │ │ ├── ITextShaper.cpp │ │ │ │ └── detail │ │ │ │ │ ├── CommonDefines.hpp │ │ │ │ │ ├── FreeTypeError.cpp │ │ │ │ │ ├── FreeTypeError.hpp │ │ │ │ │ ├── FreeTypeObject.cpp │ │ │ │ │ ├── FreeTypeObject.hpp │ │ │ │ │ ├── FreeTypeStream.cpp │ │ │ │ │ ├── FreeTypeStream.hpp │ │ │ │ │ ├── HarfBuzzBridge.cpp │ │ │ │ │ ├── HarfBuzzBridge.hpp │ │ │ │ │ ├── Helper.cpp │ │ │ │ │ ├── Helper.hpp │ │ │ │ │ ├── HgeFontLoadError.cpp │ │ │ │ │ └── HgeFontLoadError.hpp │ │ │ ├── GraphDef │ │ │ │ ├── ConstantBufferDefinition.cpp │ │ │ │ ├── ConstantBufferValueType.cpp │ │ │ │ ├── DefinitionError.cpp │ │ │ │ ├── EffectDefinition.cpp │ │ │ │ ├── EffectPassDefinition.cpp │ │ │ │ ├── EffectPassGroupDefinition.cpp │ │ │ │ ├── MeshDefinition.cpp │ │ │ │ ├── ShaderDefinition.cpp │ │ │ │ ├── ShaderTextureDefinition.cpp │ │ │ │ ├── ShaderVertexLayoutDefinition.cpp │ │ │ │ └── detail │ │ │ │ │ ├── NameCheck.hpp │ │ │ │ │ └── ToDiligent.hpp │ │ │ ├── Material.cpp │ │ │ ├── Mesh.cpp │ │ │ ├── RenderDevice.cpp │ │ │ ├── Texture.cpp │ │ │ ├── Texture2DData.cpp │ │ │ └── detail │ │ │ │ ├── ClearHelper.cpp │ │ │ │ ├── ClearHelper.hpp │ │ │ │ ├── DiligentFileStream.cpp │ │ │ │ ├── DiligentFileStream.hpp │ │ │ │ ├── DiligentShaderSourceInputStreamFactory.cpp │ │ │ │ ├── DiligentShaderSourceInputStreamFactory.hpp │ │ │ │ ├── GammaCorrectHelper.cpp │ │ │ │ ├── GammaCorrectHelper.hpp │ │ │ │ ├── LuaEffectBuilder │ │ │ │ ├── BuilderModule.cpp │ │ │ │ ├── BuilderModule.hpp │ │ │ │ ├── ConstantBufferBuilder.cpp │ │ │ │ ├── ConstantBufferBuilder.hpp │ │ │ │ ├── EffectBuilder.cpp │ │ │ │ ├── EffectBuilder.hpp │ │ │ │ ├── EffectPassBuilder.cpp │ │ │ │ ├── EffectPassBuilder.hpp │ │ │ │ ├── EffectPassGroupBuilder.cpp │ │ │ │ ├── EffectPassGroupBuilder.hpp │ │ │ │ ├── Helper.hpp │ │ │ │ ├── ShaderBuilder.cpp │ │ │ │ ├── ShaderBuilder.hpp │ │ │ │ ├── TextureVariableBuilder.cpp │ │ │ │ ├── TextureVariableBuilder.hpp │ │ │ │ ├── VertexLayoutBuilder.cpp │ │ │ │ └── VertexLayoutBuilder.hpp │ │ │ │ ├── RenderDevice │ │ │ │ ├── Emscripten │ │ │ │ │ ├── GLView.cpp │ │ │ │ │ └── GLView.hpp │ │ │ │ ├── Linux │ │ │ │ │ ├── GLContext.cpp │ │ │ │ │ └── GLContext.hpp │ │ │ │ ├── OSX │ │ │ │ │ ├── GLView.hpp │ │ │ │ │ ├── GLView.mm │ │ │ │ │ ├── MetalView.hpp │ │ │ │ │ └── MetalView.mm │ │ │ │ ├── RenderDeviceD3D11.cpp │ │ │ │ ├── RenderDeviceD3D11.hpp │ │ │ │ ├── RenderDeviceD3D12.cpp │ │ │ │ ├── RenderDeviceD3D12.hpp │ │ │ │ ├── RenderDeviceGL.cpp │ │ │ │ ├── RenderDeviceGL.hpp │ │ │ │ ├── RenderDeviceVulkan.cpp │ │ │ │ └── RenderDeviceVulkan.hpp │ │ │ │ ├── ScreenCaptureHelper.cpp │ │ │ │ ├── ScreenCaptureHelper.hpp │ │ │ │ ├── Texture2DDataImpl.cpp │ │ │ │ ├── Texture2DDataImpl.hpp │ │ │ │ └── Texture2DFormats.hpp │ │ ├── RenderSystem.cpp │ │ ├── Script │ │ │ ├── LuaError.cpp │ │ │ ├── LuaStack.cpp │ │ │ ├── SandBox.cpp │ │ │ └── detail │ │ │ │ ├── LuaCompatLayer.cpp │ │ │ │ └── LuaCompatLayer.hpp │ │ ├── ScriptSystem.cpp │ │ ├── SubsystemContainer.cpp │ │ ├── SubsystemEvent.cpp │ │ ├── VFS │ │ │ ├── AndroidAssetFileSystem.cpp │ │ │ ├── AndroidAssetStream.cpp │ │ │ ├── DeflateStream.cpp │ │ │ ├── FileStream.cpp │ │ │ ├── IStream.cpp │ │ │ ├── InflateStream.cpp │ │ │ ├── LocalFileSystem.cpp │ │ │ ├── OverlayFileSystem.cpp │ │ │ ├── Path.cpp │ │ │ ├── RootFileSystem.cpp │ │ │ ├── WindowedStream.cpp │ │ │ ├── ZipArchiveFileSystem.cpp │ │ │ └── detail │ │ │ │ ├── ZLibError.cpp │ │ │ │ ├── ZLibError.hpp │ │ │ │ ├── ZStream.cpp │ │ │ │ ├── ZStream.hpp │ │ │ │ ├── ZipFile.cpp │ │ │ │ ├── ZipFile.hpp │ │ │ │ ├── ZipFileReadError.cpp │ │ │ │ ├── ZipFileReadError.hpp │ │ │ │ ├── ZipPkDecryptStream.cpp │ │ │ │ ├── ZipPkDecryptStream.hpp │ │ │ │ └── ZipStructs.hpp │ │ ├── VirtualFileSystem.cpp │ │ └── WindowSystem.cpp │ ├── Text │ │ ├── CmdlineParser.cpp │ │ ├── IniParsingError.cpp │ │ └── IniSaxParser.cpp │ ├── Timer.cpp │ └── detail │ │ ├── EmFileDownloader.cpp │ │ ├── EmFileDownloader.hpp │ │ ├── HttpHelper.cpp │ │ ├── HttpHelper.hpp │ │ ├── IcuCharacterIteratorBridge.cpp │ │ ├── IcuCharacterIteratorBridge.hpp │ │ ├── IcuError.cpp │ │ ├── IcuError.hpp │ │ ├── IcuService.cpp │ │ ├── IcuService.hpp │ │ ├── SDLHelper.cpp │ │ ├── SDLHelper.hpp │ │ └── STBBuild.cpp └── v2 │ ├── Asset │ ├── EffectAsset.cpp │ ├── EffectAssetFactory.cpp │ ├── EffectAssetLoader.cpp │ ├── HgeFontAsset.cpp │ ├── HgeFontAssetFactory.cpp │ ├── HgeFontAssetLoader.cpp │ ├── HgeParticleAsset.cpp │ ├── HgeParticleAssetFactory.cpp │ ├── HgeParticleAssetLoader.cpp │ ├── MusicAsset.cpp │ ├── MusicAssetFactory.cpp │ ├── MusicAssetLoader.cpp │ ├── SoundAsset.cpp │ ├── SoundAssetFactory.cpp │ ├── SoundAssetLoader.cpp │ ├── SpriteAsset.cpp │ ├── SpriteAssetFactory.cpp │ ├── SpriteAssetLoader.cpp │ ├── SpriteSequenceAsset.cpp │ ├── SpriteSequenceAssetFactory.cpp │ ├── SpriteSequenceAssetLoader.cpp │ ├── TextureAsset.cpp │ ├── TextureAssetFactory.cpp │ ├── TextureAssetLoader.cpp │ ├── TrueTypeFontAsset.cpp │ ├── TrueTypeFontAssetFactory.cpp │ └── TrueTypeFontAssetLoader.cpp │ ├── AssetNaming.cpp │ ├── AssetPools.cpp │ ├── BlendMode.cpp │ ├── Bridge │ ├── AssetManagerModule.cpp │ ├── AudioModule.cpp │ ├── GameObjectModule.cpp │ ├── InputModule.cpp │ ├── LSTGBentLaserData.cpp │ ├── LSTGColor.cpp │ ├── LSTGRandomizer.cpp │ ├── LfsBridgeModule.cpp │ ├── MathModule.cpp │ ├── MiscModule.cpp │ ├── RenderModule.cpp │ ├── SystemModule.cpp │ └── detail │ │ ├── Helper.cpp │ │ └── Helper.hpp │ ├── CMakeLists.txt │ ├── DebugGUI │ └── PerformanceMonitor.cpp │ ├── GameApp.cpp │ ├── GamePlay │ ├── BentLaser.cpp │ ├── Components │ │ ├── Collider.cpp │ │ ├── LifeTime.cpp │ │ ├── Movement.cpp │ │ ├── Renderer.cpp │ │ ├── Script.cpp │ │ └── Transform.cpp │ ├── GameWorld.cpp │ └── ScriptObjectPool.cpp │ ├── LuaSTGPlus2.ico │ ├── LuaSTGPlus2.rc │ ├── Main.cpp │ ├── ScriptObjectAttributes.json │ ├── Version.hpp.in │ ├── detail │ └── KeyMapping.hpp │ └── resource.h └── tool ├── BinaryToCode ├── BinaryToCode.py └── CMakeLists.txt ├── LuaAutoBridgeTool ├── CMakeLists.txt └── LuaAutoBridgeTool.py ├── PerfectHashTool ├── CMakeLists.txt └── PerfectHashTool.py └── WebShellApp ├── Main.html └── SimpleServer.py /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: Microsoft 3 | ColumnLimit: 140 4 | 5 | # Custom rules 6 | DerivePointerAlignment: false 7 | PointerAlignment: Left 8 | AlwaysBreakTemplateDeclarations: Yes 9 | IndentCaseLabels: true 10 | NamespaceIndentation: All 11 | AccessModifierOffset: -4 12 | AlignEscapedNewlines: Left 13 | 14 | # Only sort headers in each include block 15 | SortIncludes: true 16 | IncludeBlocks: Preserve 17 | IndentPPDirectives: AfterHash 18 | -------------------------------------------------------------------------------- /.github/workflows/build_doc.yaml: -------------------------------------------------------------------------------- 1 | name: Build Documents 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | paths: 7 | - ".github/workflows/build_doc.yaml" 8 | - "doc/**.md" 9 | - "doc/**.svg" 10 | - "doc/**.png" 11 | - "doc/package.json" 12 | repository_dispatch: 13 | types: [ update ] 14 | 15 | jobs: 16 | build_doc: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 21 | - name: Check out 22 | uses: actions/checkout@v2 23 | with: 24 | submodules: recursive 25 | 26 | # Switch to nodejs 27 | - name: Switch nodejs 28 | uses: actions/setup-node@v1 29 | with: 30 | node-version: 18.x 31 | 32 | # https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported 33 | - name: Build static pages 34 | run: | 35 | export NODE_OPTIONS=--openssl-legacy-provider 36 | cd doc 37 | yarn install 38 | yarn run build 39 | 40 | - name: Deploy 41 | uses: peaceiris/actions-gh-pages@v3 42 | with: 43 | deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} 44 | external_repository: LuaSTG/LuaSTG.github.io 45 | publish_dir: ./doc/src/.vuepress/dist 46 | publish_branch: master 47 | cname: luastg.com 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![LuaSTGPlus](./artwork/LuaSTG.svg) 2 | 3 | **A Cross-Platform Danmaku Game Engine.** 4 | 5 | ![Architectures](https://img.shields.io/badge/arch-x86%5F64%20%7C%20arm64%20%7C%20wasm-blue) 6 | ![Platforms](https://img.shields.io/badge/platform-linux%20%7C%20win%20%7C%20osx%20%7C%20html5%20%7C%20android-lightgrey) 7 | ![License](https://img.shields.io/badge/license-MIT-green) 8 | ![Stars](https://img.shields.io/github/stars/9chu/luastgplus?style=social) 9 | ![Forks](https://img.shields.io/github/forks/9chu/luastgplus?style=social) 10 | 11 | [![Build Windows](https://github.com/9chu/LuaSTGPlus/actions/workflows/build_windows.yaml/badge.svg)](https://nightly.link/9chu/LuaSTGPlus/workflows/build_windows.yaml/master) 12 | 13 | **Working in progress** 14 | 15 | See **[documentation](https://luastg.github.io)** for more details. 16 | -------------------------------------------------------------------------------- /artwork/AUTHORS.md: -------------------------------------------------------------------------------- 1 | | 文件名 | 作者 | 许可协议 | 2 | |--------------|------------------------------------------------|---------------------------------------------------------------------| 3 | | AppIcon.png | [Kiasela](https://www.pixiv.net/users/7278743) | ![CC BY-NC-SA](https://licensebuttons.net/l/by-nc-sa/3.0/88x31.png) | 4 | | LuaSTG.svg | [Kiasela](https://www.pixiv.net/users/7278743) | ![CC BY-NC-SA](https://licensebuttons.net/l/by-nc-sa/3.0/88x31.png) | 5 | 6 | 许可协议以`COPYRIGHT.txt`中所标注为准。 7 | -------------------------------------------------------------------------------- /artwork/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/artwork/AppIcon.png -------------------------------------------------------------------------------- /cmake/GenerateVersionHeader.cmake: -------------------------------------------------------------------------------- 1 | if(GIT_EXECUTABLE) 2 | get_filename_component(SRC_DIR ${SRC} DIRECTORY) 3 | # Generate a git-describe version string from Git repository tags 4 | execute_process( 5 | COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --match "v*" 6 | WORKING_DIRECTORY ${SRC_DIR} 7 | OUTPUT_VARIABLE GIT_DESCRIBE_VERSION 8 | RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE 9 | OUTPUT_STRIP_TRAILING_WHITESPACE) 10 | if(NOT GIT_DESCRIBE_ERROR_CODE) 11 | set(LSTG_VERSION ${GIT_DESCRIBE_VERSION}) 12 | endif() 13 | endif() 14 | 15 | # Final fallback: Just use a bogus version string that is semantically older 16 | # than anything else and spit out a warning to the developer. 17 | if(NOT DEFINED LSTG_VERSION) 18 | set(LSTG_VERSION v0.0.0-unknown) 19 | message(WARNING "Failed to determine LSTG_VERSION from Git tags. Using default version \"${LSTG_VERSION}\".") 20 | endif() 21 | 22 | configure_file(${SRC} ${DST} @ONLY) 23 | -------------------------------------------------------------------------------- /doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "luastgplus-docs", 3 | "version": "0.0.1", 4 | "description": "A Cross-Platform Danmaku Game Engine", 5 | "main": "index.js", 6 | "authors": { 7 | "name": "9chu", 8 | "email": "1871361697@qq.com" 9 | }, 10 | "repository": "https://github.com/9chu/LuaSTGPlus", 11 | "scripts": { 12 | "dev": "vuepress dev src", 13 | "build": "vuepress build src" 14 | }, 15 | "license": "SEE LICENSE IN ../COPYRIGHT.txt", 16 | "devDependencies": { 17 | "vuepress": "^1.5.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /doc/src/.vuepress/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/doc/src/.vuepress/components/.gitkeep -------------------------------------------------------------------------------- /doc/src/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Client app enhancement file. 3 | * 4 | * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements 5 | */ 6 | 7 | export default ({ 8 | Vue, // the version of Vue being used in the VuePress app 9 | options, // the options for the root Vue instance 10 | router, // the router instance for the app 11 | siteData // site metadata 12 | }) => { 13 | // ...apply enhancements for the site. 14 | } 15 | -------------------------------------------------------------------------------- /doc/src/.vuepress/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/doc/src/.vuepress/public/favicon.ico -------------------------------------------------------------------------------- /doc/src/.vuepress/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/doc/src/.vuepress/public/logo.png -------------------------------------------------------------------------------- /doc/src/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom Styles here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/config/#index-styl 5 | */ 6 | 7 | .home .hero img 8 | max-width 450px!important 9 | -------------------------------------------------------------------------------- /doc/src/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom palette here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/zh/config/#palette-styl 5 | */ 6 | 7 | $accentColor = rgb(14,109,234) 8 | $textColor = #2c3e50 9 | $borderColor = #eaecef 10 | $codeBgColor = #282c34 11 | -------------------------------------------------------------------------------- /doc/src/api/AdvancedAPI/Overview.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 3 | **Advanced API 尚在开发中。** 4 | 5 | **TODO** 6 | -------------------------------------------------------------------------------- /doc/src/api/LegacyAPI/BuiltinConsts.md: -------------------------------------------------------------------------------- 1 | # 内建常量 2 | 3 | 所有内建方法均位于全局`lstg`模块中。 4 | 5 | ## args 6 | 7 | 保存命令行参数。 8 | 9 | 详见[命令行](../../guide/Cmdline.md)。 10 | 11 | - 签名:`args: table` 12 | -------------------------------------------------------------------------------- /doc/src/api/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 3 | LSTGPlus 提供两套 API,分为`Legacy API`和`Advanced API`。 4 | 5 | 其中,`Legacy API`包含所有 LSTG 中出现的老 API。`Advanced API`提供了核心引擎中更加底层的扩展功能支持。 6 | 7 | 为了方便描述,我们采取类似 typescript 的语法对接口类型进行说明。 8 | 9 | ## 程序生命周期 10 | 11 | ![生命周期](./asset/overview.svg) 12 | 13 | ## 全局回调方法 14 | 15 | ### GameInit 16 | 17 | 在游戏框架初始化完毕后,游戏循环启动前调用。 18 | 19 | - 签名:`GameInit()` 20 | 21 | ### FocusLoseFunc 22 | 23 | 在渲染窗口失去焦点时调用。 24 | 25 | - 签名:`FocusLoseFunc()` 26 | 27 | ### FocusGainFunc 28 | 29 | 在渲染窗口获得焦点时调用。 30 | 31 | - 签名:`FocusGainFunc` 32 | 33 | ### FrameFunc 34 | 35 | 帧处理函数,每帧被调用来处理逻辑。 36 | 37 | - 签名:`FrameFunc(): boolean` 38 | - 返回值:true 用于终止循环,退出程序。 39 | 40 | ### RenderFunc 41 | 42 | 渲染处理函数,每帧被调用时用来渲染场景。 43 | 44 | - 签名:`RenderFunc()` 45 | -------------------------------------------------------------------------------- /doc/src/guide/Console.md: -------------------------------------------------------------------------------- 1 | # 调试控制台 2 | 3 | 当运行在`开发模式`下,可以通过`~`键唤出调试控制台。 4 | 5 | ![控制台](./asset/console.png) 6 | 7 | 调试控制台可以显示当前的日志信息。如果系统打印出 Error 级别日志,调试控制台也会自动弹出。 8 | 9 | 你可以在调试控制台的命令行中执行任意 Lua 语句,同时控制台会显示语句的返回值。 10 | 11 | 通过在日志文本框中单击鼠标右键还可以切出其他子项调试窗口。 12 | -------------------------------------------------------------------------------- /doc/src/guide/Subsystem/Architecture.md: -------------------------------------------------------------------------------- 1 | # 架构 2 | 3 | **LuaSTGPlus**由多个子系统构成,大体架构如下: 4 | 5 | ![架构图](./asset/architecture.svg) 6 | 7 | 需要注意,**LuaSTGPlus**的引擎部分仅提供 2D 游戏所需的图形/音频/输入/文件系统等基础功能,若要实现完整的 STG 游戏则依赖 data 层中的脚本逻辑和游戏素材,以及编辑器的加持。 8 | -------------------------------------------------------------------------------- /doc/src/guide/Subsystem/RenderSystem.md: -------------------------------------------------------------------------------- 1 | # 渲染子系统 2 | 3 | *TODO* 4 | 5 | - luastg/luastg+使用笛卡尔坐标系(右正上正)作为窗口坐标系,且以屏幕左下角作为原点,Viewport、鼠标消息将以此作为基准。 6 | - luastg/luastg+不开启Z-Buffer进行深度剔除,通过排序手动完成这一工作。 7 | 8 | ## 混合选项 9 | 10 | | 取值 | 说明 | 11 | | --------- | ---------------------------------------- | 12 | | | 默认值,=mul+alpha | 13 | | mul+add | 顶点颜色使用乘法,目标混合使用加法 | 14 | | mul+alpha | (默认)顶点颜色使用乘法,目标混合使用alpha混合 | 15 | | mul+sub | 顶点颜色使用乘法,结果=图像上的颜色-屏幕上的颜色 | 16 | | mul+rev | 顶点颜色使用乘法,结果=屏幕上的颜色-图像上的颜色 | 17 | | add+add | 顶点颜色使用加法,目标混合使用加法 | 18 | | add+alpha | 顶点颜色使用加法,目标混合使用alpha混合 | 19 | | add+sub | 顶点颜色使用加法,结果=图像上的颜色-屏幕上的颜色 | 20 | | add+rev | 顶点颜色使用加法,结果=屏幕上的颜色-图像上的颜色 | 21 | -------------------------------------------------------------------------------- /doc/src/guide/Subsystem/ScriptSystem.md: -------------------------------------------------------------------------------- 1 | # 脚本子系统 2 | 3 | LuaSTGPlus 采用 luajit/lua51 作为脚本虚拟机,故语言/库标准基于 lua5.1。 4 | 5 | 脚本中字符串类型采用`UTF-8`编码,换言之所有脚本以`UTF-8`进行编码。 6 | 7 | ## 标准库调整 8 | 9 | 出于跨平台考虑,为了保证各平台行为一致,相比较标准的 lua,我们对库进行了一定调整: 10 | 11 | - 不允许启动外部进程 12 | - os.execute 被禁止 13 | - io.popen 被禁止 14 | - 标准库函数的 I/O 操作将基于虚拟文件系统进行 15 | - os.remove 16 | - os.rename 17 | - os.tmpname 18 | - io.* 19 | - loadfile 20 | - dofile 21 | - require 22 | - require 现在不允许动态加载外部二进制库 23 | - print 除去输出到 stdout,还会转发到日志系统 24 | - 拉平 luajit/lua51 的差异 25 | - luajit 26 | - 关闭 FFI 支持 27 | - lua 28 | - 引入 bit 库 29 | - 默认引入下述第三方库 30 | - cjson 31 | - lfs(基于 VFS 的兼容实现) 32 | 33 | ## 沙箱与热更新机制 34 | 35 | ### 沙箱模式 36 | 37 | 为了方便快速开发迭代,我们在 LuaSTGPlus 中引入了沙箱和热更新机制。 38 | 39 | 在沙箱模式下,**脚本文件会形成独立的执行环境**,在脚本文件中定义的任意全局方法将仅存在于该文件的环境中,例如: 40 | 41 | ```lua 42 | -- 1.lua 43 | function foo() end 44 | print(type(foo)) -- function 45 | 46 | -- 2.lua 47 | print(type(foo)) -- nil 48 | ``` 49 | 50 | 如果你希望将方法定义到全局环境中,需要显式进行定义: 51 | 52 | ```lua 53 | -- 1.lua 54 | function _G.foo() end 55 | print(type(foo)) -- function 56 | 57 | -- 2.lua 58 | print(type(foo)) -- function 59 | ``` 60 | 61 | 使用`import`方法来以沙箱模式加载脚本文件。 62 | 63 | ```lua 64 | a = import("1.lua") 65 | ``` 66 | 67 | 此时,`import`的返回值即为脚本的执行环境。通过这一方法可以访问其他脚本中所定义的值。 68 | 69 | 需要注意,脚本文件会在第一次`import`时被执行,往后相同文件不会再被加载,而是直接返回之前创建的执行环境。 70 | 71 | 综上,相比较`require`加载,区别如下: 72 | 73 | - 方法默认定义在脚本独立的环境中而不是全局环境中 74 | - `require`返回脚本执行结果,`import`返回脚本执行环境 75 | 76 | ::: warning 77 | `require`和`import`为两套独立机制,互相不干扰,但是不推荐混合使用。 78 | ::: 79 | 80 | ### 热更新机制 81 | 82 | 我们在沙箱模式基础上建立起热更新机制。 83 | 84 | 脚本子系统会在帧更新期间自动检查脚本文件是否发生过修改,如果发生过修改,脚本子系统会自动重新加载文件并执行。 85 | 86 | 通过这种机制,脚本中定义的方法将得以重新覆盖原始定义,从而达到热更新的效果。 87 | 88 | 需要注意的是,脚本在重新执行时,原有的执行环境不会被清空,因此可以通过判空的方式检查原有变量是否存在。 89 | 90 | 此外,热更新仅在**开发模式**下生效。 91 | -------------------------------------------------------------------------------- /doc/src/guide/Subsystem/VfsSystem.md: -------------------------------------------------------------------------------- 1 | # 文件子系统 2 | 3 | 为了在各种平台上执行,屏蔽各系统文件系统区别,同时支持在不同场景下的文件存取,我们在 LuaSTGPlus 中引入了虚拟文件系统的概念。 4 | 5 | - 特点 6 | - 根路径为`/` 7 | - 以`/`作为分隔符(`\`会被自动转换为`/`) 8 | - 大小写敏感 9 | 10 | ## 内建路径 11 | 12 | 虚拟文件系统定义有两个固定的路径: 13 | 14 | - / 15 | - storage/ 16 | - assets/ 17 | 18 | 其中`/storage/`用于指向用户数据存储目录,`/assets/`用于指向资产目录。 19 | 20 | ### 用户数据存储目录 21 | 22 | 用户数据存储目录用于屏蔽各个系统下`UserData`文件夹的差异。 23 | 24 | 构建时的`LSTG_APP_NAME`定义将会影响这一目录的实际位置。 25 | 26 | - 各平台用户数据实际存储路径 27 | - Windows:`%APPDATA%\Roaming\lstgplus\default\` 28 | - Linux: `~/.local/share/lstgplus/default/` 29 | - MacOS: `~/Library/Application Support/lstgplus/default/` 30 | 31 | 代码可以在用户数据存储目录中进行读写操作。 32 | 33 | ### 资产目录 34 | 35 | 资产目录的构成相对用户数据存储目录复杂。 36 | 37 | 资产目录由层叠文件系统构成,访问会依次经由各个文件系统进行,当上一个文件系统不存在对应文件时,会继续调用下一个文件系统进行操作,直到遍历完成所有层叠的文件系统。 38 | 39 | ![层叠文件系统](./asset/vfssystem.svg) 40 | 41 | 层叠文件系统在当前实现中由 Zip 文件系统构成,对应`LoadPack`方法加载的若干 Zip 文件构成的虚拟文件系统。越先加载的 Zip 数据包会越晚参与层叠文件系统的访问,换言之,当加载文件时,会优先搜索最近加载的 Zip 数据包。 42 | 43 | 除此以外,层叠文件系统最后尾会加入一个本地文件系统,注意到`LoadPack`方法本质也是在虚拟文件系统上进行的访问,因此在没有加载任何 Zip 数据包时,`LoadPack`会从本地文件系统中打开 Zip 数据包并进行数据加载。与此同时,在开发模式下,通过这一机制可以规避打包 Zip 的麻烦,直接在本地文件系统中进行开发。 44 | 45 | 需要注意,在**开发模式**中,该本地文件系统会映射到当前程序的工作路径;而在**发布模式**中,则始终映射到程序的执行目录下。 46 | -------------------------------------------------------------------------------- /doc/src/guide/asset/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/doc/src/guide/asset/console.png -------------------------------------------------------------------------------- /doc/src/i18n/en/api/README.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | *Translating in progress.* 4 | -------------------------------------------------------------------------------- /doc/src/i18n/en/guide/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | *Translating in progress.* 4 | -------------------------------------------------------------------------------- /doc/src/i18n/en/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /hero.svg 4 | heroText: 5 | tagline: A Tiny Cross-Platform Danmaku Game Engine 6 | actionText: START → 7 | actionLink: guide/ 8 | features: 9 | - title: Multi-platform 10 | details: Linux/MacOS/Windows/HTML5 11 | - title: Fast and Efficient 12 | details: LuaJIT/Hot-reload supported 13 | - title: Multiple graphics API 14 | details: OpenGL/Vulkan/D3D11/D3D12 15 | footer: Made by 9chu with ❤️ 16 | --- 17 | -------------------------------------------------------------------------------- /doc/src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /hero.svg 4 | heroText: 5 | tagline: 一个小巧的跨平台弹幕射击游戏引擎 6 | actionText: 开始 → 7 | actionLink: /guide/ 8 | features: 9 | - title: 跨平台支持 10 | details: Linux/MacOS/Windows/HTML5 11 | - title: 快速且高效 12 | details: LuaJIT/热重载支持 13 | - title: 多图形API支持 14 | details: OpenGL/Vulkan/D3D11/D3D12 15 | footer: Made by 9chu with ❤️ 16 | --- 17 | -------------------------------------------------------------------------------- /include/lstg/Core/Encoding/EncodingError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2021/11/18 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Encoding 12 | { 13 | /** 14 | * 编码异常错误码 15 | */ 16 | enum class EncodingError 17 | { 18 | DecodingFailure = 1, 19 | EncodingFailure = 2, 20 | }; 21 | 22 | /** 23 | * 错误分类声明 24 | */ 25 | class EncodingErrorCategory : public std::error_category 26 | { 27 | public: 28 | static const EncodingErrorCategory& GetInstance() noexcept; 29 | 30 | public: 31 | const char* name() const noexcept override; 32 | std::string message(int ev) const override; 33 | }; 34 | 35 | inline std::error_code make_error_code(EncodingError err) noexcept 36 | { 37 | return {static_cast(err), EncodingErrorCategory::GetInstance()}; 38 | } 39 | } 40 | 41 | template <> 42 | struct std::is_error_code_enum : true_type {}; 43 | -------------------------------------------------------------------------------- /include/lstg/Core/Exception.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/2/16 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg 12 | { 13 | /** 14 | * 记录异常抛出位置 15 | */ 16 | struct ExceptionSourceLocation 17 | { 18 | const char* FileName = nullptr; 19 | const char* FunctionName = nullptr; 20 | int Line = 0; 21 | }; 22 | 23 | /** 24 | * 异常基类 25 | * 在 LSTGPlus 中,异常仅在构造函数等场合中使用,其他地方使用 Result 机制进行错误码返回,以方便与 Lua 之间的交互。 26 | */ 27 | class Exception : 28 | public std::runtime_error 29 | { 30 | public: 31 | template 32 | Exception(ExceptionSourceLocation loc, TArgs&&... args) 33 | : std::runtime_error(fmt::format(std::forward(args)...)), m_stLocation(loc) 34 | { 35 | } 36 | 37 | public: 38 | /** 39 | * 获取异常抛出位置 40 | */ 41 | [[nodiscard]] const ExceptionSourceLocation& GetLocation() const noexcept { return m_stLocation; } 42 | 43 | private: 44 | ExceptionSourceLocation m_stLocation; 45 | }; 46 | } // namespace lstg 47 | 48 | #define LSTG_DEFINE_EXCEPTION(TAG) \ 49 | class TAG : \ 50 | public lstg::Exception \ 51 | { \ 52 | using Exception::Exception; \ 53 | } 54 | 55 | #define LSTG_THROW(TAG, ...) \ 56 | throw TAG(lstg::ExceptionSourceLocation{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) 57 | -------------------------------------------------------------------------------- /include/lstg/Core/JniUtils.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2023/8/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "Result.hpp" 11 | 12 | struct AAssetManager; 13 | 14 | struct _JNIEnv; 15 | struct _jobject; 16 | 17 | namespace lstg 18 | { 19 | namespace JniUtils 20 | { 21 | /** 22 | * JObject 全局引用 23 | */ 24 | class JObjectReference 25 | { 26 | public: 27 | /** 28 | * 构造空的 JObject 引用 29 | */ 30 | JObjectReference() = default; 31 | 32 | /** 33 | * 从 JNIEnv 和 JObject 构造引用 34 | * @param env JNIEnv 35 | * @param object JObject,必须是全局引用 36 | */ 37 | JObjectReference(_JNIEnv* env, _jobject* object); 38 | 39 | JObjectReference(const JObjectReference&) = delete; 40 | JObjectReference(JObjectReference&& rhs) noexcept; 41 | ~JObjectReference(); 42 | 43 | JObjectReference& operator=(const JObjectReference&) = delete; 44 | JObjectReference& operator=(JObjectReference&& rhs) noexcept; 45 | 46 | /** 47 | * 用于检查是否为非空 48 | */ 49 | operator bool() const noexcept; 50 | 51 | /** 52 | * 解引用 53 | */ 54 | _jobject* operator*() const noexcept; 55 | 56 | public: 57 | /** 58 | * 对象置空 59 | */ 60 | void Reset() noexcept; 61 | 62 | private: 63 | _JNIEnv* m_pEnv = nullptr; 64 | _jobject* m_pObject = nullptr; 65 | }; 66 | } // namespace JniUtils 67 | } // namespace lstg 68 | -------------------------------------------------------------------------------- /include/lstg/Core/Math/Collider2D/ColliderShape.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Math::Collider2D 12 | { 13 | template 14 | struct OBBShape 15 | { 16 | glm::vec<2, T, glm::defaultp> HalfSize { 0, 0 }; 17 | }; 18 | 19 | template 20 | struct CircleShape 21 | { 22 | T Radius = static_cast(0); 23 | }; 24 | 25 | template 26 | struct EllipseShape 27 | { 28 | T A = static_cast(0); // 半长轴 29 | T B = static_cast(0); // 半短轴 30 | }; 31 | 32 | template 33 | using ColliderShape = std::variant, CircleShape, EllipseShape>; 34 | } 35 | -------------------------------------------------------------------------------- /include/lstg/Core/Math/Decibel.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/18 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Math 12 | { 13 | template 14 | inline T LinearToDecibel(T linear) noexcept 15 | { 16 | assert(linear > static_cast(0)); 17 | // https://en.wikipedia.org/wiki/Neper 18 | return ::log(linear) * static_cast(8.6858896380650365530225783783321); 19 | } 20 | 21 | template 22 | inline T DecibelToLinear(T decibel) noexcept 23 | { 24 | return ::exp(decibel * static_cast(0.11512925464970228420089957273422)); 25 | } 26 | 27 | template 28 | inline T LinearToDecibelSafe(T linear) noexcept 29 | { 30 | assert(linear >= static_cast(0)); 31 | linear += static_cast(0.0000000001); // -200 dB 32 | return ::log(linear) * static_cast(8.6858896380650365530225783783321); 33 | } 34 | 35 | template 36 | inline T DecibelToLinearSafe(T decibel) noexcept 37 | { 38 | if (decibel <= static_cast(-200)) 39 | return static_cast(0); 40 | auto linear = ::exp(decibel * static_cast(0.11512925464970228420089957273422)); 41 | if (linear <= static_cast(0.0000000001)) 42 | return static_cast(0); 43 | return linear - static_cast(0.0000000001); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /include/lstg/Core/Pal.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg 11 | { 12 | namespace Pal 13 | { 14 | /** 15 | * 获取用户数据存储文件夹地址 16 | * @note 方法会自动创建用户数据存储目录 17 | */ 18 | std::filesystem::path GetUserStorageDirectory() noexcept; 19 | 20 | /** 21 | * 关键性终止 22 | * 弹出对话框提示消息并终止程序运行。 23 | * @param msg 消息 24 | * @param abort 是否立即退出 25 | */ 26 | void FatalError(const char* msg, bool abort=true) noexcept; 27 | 28 | /** 29 | * 获取当前单调时钟时间 30 | */ 31 | uint64_t GetCurrentTick() noexcept; 32 | 33 | /** 34 | * 获取当前单调时钟频率 35 | */ 36 | uint64_t GetTickFrequency() noexcept; 37 | } 38 | } // namespace lstg 39 | -------------------------------------------------------------------------------- /include/lstg/Core/PreciseSleeper.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/2/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg 11 | { 12 | /** 13 | * 高精度睡眠器 14 | */ 15 | class PreciseSleeper 16 | { 17 | public: 18 | PreciseSleeper(); 19 | PreciseSleeper(const PreciseSleeper&) = delete; 20 | ~PreciseSleeper(); 21 | 22 | public: 23 | /** 24 | * 获取时钟源频率 25 | */ 26 | [[nodiscard]] double GetFrequency() const noexcept { return m_dFreq; } 27 | 28 | /** 29 | * 睡眠 30 | * @param seconds 时间(秒) 31 | */ 32 | void Sleep(double seconds) noexcept; 33 | 34 | private: 35 | const double m_dFreq; 36 | double m_dEstimate = 5e-3; 37 | double m_dMean = 5e-3; 38 | double m_dM2 = 0.0; 39 | double m_dCount = 1.0; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Asset/AssetError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Asset 11 | { 12 | /** 13 | * 资产系统错误代码 14 | */ 15 | enum class AssetError 16 | { 17 | Ok = 0, 18 | AssetAlreadyExists = 1, 19 | AssetNotFound = 2, 20 | MissingRequiredArgument = 3, 21 | LoadingCancelled = 4, 22 | AssetFactoryAlreadyRegistered = 5, 23 | AssetFactoryNotRegistered = 6, 24 | InvalidState = 7, 25 | DependentAssetNotFound = 8, 26 | }; 27 | 28 | /** 29 | * 资产系统错误代码分类 30 | */ 31 | class AssetErrorCategory : public std::error_category 32 | { 33 | public: 34 | static const AssetErrorCategory& GetInstance() noexcept; 35 | 36 | public: 37 | const char* name() const noexcept override; 38 | std::string message(int ev) const override; 39 | }; 40 | 41 | inline std::error_code make_error_code(AssetError ec) noexcept 42 | { 43 | return { static_cast(ec), AssetErrorCategory::GetInstance() }; 44 | } 45 | } 46 | 47 | namespace std 48 | { 49 | template <> 50 | struct is_error_code_enum : true_type {}; 51 | } 52 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Asset/BasicTexture2DAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/4/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "IAssetFactory.hpp" 9 | 10 | namespace lstg::Subsystem::Asset 11 | { 12 | /** 13 | * 纹理资产工厂 14 | */ 15 | class BasicTexture2DAssetFactory : 16 | public IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(AssetSystem& assetSystem, AssetPoolPtr pool, std::string_view name, 22 | const nlohmann::json& arguments, IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Asset/BasicTexture2DAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "AssetLoader.hpp" 10 | #include "../Render/Texture2DData.hpp" 11 | #include "../VFS/IStream.hpp" 12 | #include "../VFS/IFileSystem.hpp" 13 | 14 | namespace lstg::Subsystem::Asset 15 | { 16 | /** 17 | * 纹理资产加载器 18 | */ 19 | class BasicTexture2DAssetLoader : 20 | public AssetLoader 21 | { 22 | public: 23 | BasicTexture2DAssetLoader(AssetPtr asset, bool mipmapEnabled); 24 | 25 | public: // AssetLoader 26 | Result PreLoad() noexcept override; 27 | Result AsyncLoad() noexcept override; 28 | Result PostLoad() noexcept override; 29 | void Update() noexcept override; 30 | #if LSTG_ASSET_HOT_RELOAD 31 | bool SupportHotReload() const noexcept override; 32 | bool CheckIsOutdated() const noexcept override; 33 | void PrepareToReload() noexcept override; 34 | #endif 35 | 36 | private: 37 | // 资源属性 38 | const bool m_bMipmaps = false; 39 | 40 | // 状态 41 | VFS::StreamPtr m_pSourceStream; // PreLoad 时加载 42 | #if LSTG_ASSET_HOT_RELOAD 43 | VFS::FileAttribute m_stSourceAttribute; 44 | #endif 45 | std::optional m_stTextureData; // AsyncLoad 时加载 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Audio/ISoundData.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "ISoundDecoder.hpp" 9 | #include 10 | 11 | namespace lstg::Subsystem::Audio 12 | { 13 | /** 14 | * 音频源 15 | */ 16 | class ISoundData 17 | { 18 | public: 19 | ISoundData() noexcept = default; 20 | virtual ~ISoundData() noexcept = default; 21 | 22 | public: 23 | /** 24 | * 创建解码器 25 | * 解码器使用音频数据进行解码,解码器直接互相独立互不干扰。 26 | */ 27 | virtual Result CreateDecoder() noexcept = 0; 28 | }; 29 | 30 | using SoundDataPtr = std::shared_ptr; 31 | 32 | /** 33 | * 创建内存音频数据 34 | * @param stream 流 35 | * @return 音频数据 36 | */ 37 | Result CreateMemorySoundData(VFS::StreamPtr stream) noexcept; 38 | 39 | /** 40 | * 创建流音频数据 41 | * @param stream 流 42 | * @return 音频数据 43 | */ 44 | Result CreateStreamSoundData(VFS::StreamPtr stream) noexcept; 45 | } 46 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Audio/ISoundDecoder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "../../Result.hpp" 10 | #include "SampleView.hpp" 11 | 12 | namespace lstg::Subsystem::Audio 13 | { 14 | /** 15 | * 音频解码器 16 | * 音频解码器负责将音频数据进行解码。 17 | * 内部统一使用 44100Hz 双通道 32bit float PCM 数据。 18 | */ 19 | class ISoundDecoder 20 | { 21 | public: 22 | static const unsigned kChannels = 2; 23 | static const unsigned kSampleRate = 44100; 24 | 25 | public: 26 | ISoundDecoder() = default; 27 | virtual ~ISoundDecoder() noexcept = default; 28 | 29 | public: 30 | /** 31 | * 填充缓冲区 32 | * @param output 输出缓冲区 33 | * @return 产生的采样个数 34 | */ 35 | virtual Result Decode(SampleView output) noexcept = 0; 36 | 37 | /** 38 | * 获取时间 39 | * @return 毫秒 40 | */ 41 | virtual Result GetDuration() noexcept = 0; 42 | 43 | /** 44 | * 转到指定时间 45 | * @param timeMs 时间(毫秒) 46 | */ 47 | virtual Result Seek(uint32_t timeMs) noexcept = 0; 48 | 49 | /** 50 | * 重置解码状态 51 | */ 52 | virtual Result Reset() noexcept = 0; 53 | }; 54 | 55 | using SoundDecoderPtr = std::shared_ptr; 56 | } 57 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/DebugGUI/FrameTimeMonitor.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "Window.hpp" 10 | 11 | namespace lstg::Subsystem::DebugGUI 12 | { 13 | /** 14 | * 帧时间监控窗口 15 | */ 16 | class FrameTimeMonitor : 17 | public Window 18 | { 19 | public: 20 | FrameTimeMonitor(); 21 | 22 | protected: // 需要实现 23 | virtual void OnPrepareWindow() noexcept override; 24 | virtual void OnUpdate(double elapsedTime) noexcept override; 25 | virtual void OnRender() noexcept override; 26 | 27 | private: 28 | struct FrameTime 29 | { 30 | double Total = 0.; 31 | 32 | #ifdef LSTG_DEVELOPMENT 33 | double EventDispatchTimeStack = 0.; 34 | double UpdateTimeStack = 0.; 35 | double RenderTimeStack = 0.; 36 | double AudioUpdateTime = 0.; 37 | #endif 38 | }; 39 | 40 | std::vector m_stFrames; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/DebugGUI/MiniStatusWindow.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "Window.hpp" 10 | #include "../ProfileSystem.hpp" 11 | 12 | namespace lstg::Subsystem::DebugGUI 13 | { 14 | /** 15 | * 迷你状态窗口 16 | */ 17 | class MiniStatusWindow : 18 | public Window 19 | { 20 | public: 21 | MiniStatusWindow(); 22 | 23 | public: 24 | /** 25 | * 增加显示的计数器 26 | * @param label 标签 27 | * @param counterType 计数器类型 28 | * @param counterName 计数器名称 29 | * @return 是否成功 30 | */ 31 | Result AddCounter(std::string label, PerformanceCounterTypes counterType, std::string counterName) noexcept; 32 | 33 | protected: // Window 34 | void OnPrepareWindow() noexcept override; 35 | void OnRender() noexcept override; 36 | 37 | private: 38 | struct DrawCounters 39 | { 40 | std::string Label; 41 | PerformanceCounterTypes CounterType; 42 | std::string CounterName; 43 | }; 44 | 45 | std::vector m_stCounters; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/DebugGUI/MixerWindow.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/18 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "../../Result.hpp" 11 | #include "Window.hpp" 12 | 13 | namespace lstg::Subsystem::DebugGUI 14 | { 15 | /** 16 | * 混音器窗口 17 | */ 18 | class MixerWindow : 19 | public Window 20 | { 21 | public: 22 | MixerWindow(); 23 | 24 | protected: // Window 25 | void OnPrepareWindow() noexcept override; 26 | void OnRender() noexcept override; 27 | 28 | private: 29 | Result MakeKeysFromMapOptions(const std::map& options) noexcept; 30 | 31 | private: 32 | std::vector m_stTmpOptions; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/DebugGUI/ProgressWindow.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "Window.hpp" 10 | #include "../../Result.hpp" 11 | 12 | namespace lstg::Subsystem::DebugGUI 13 | { 14 | /** 15 | * 进度窗口 16 | */ 17 | class ProgressWindow : 18 | public Window 19 | { 20 | public: 21 | ProgressWindow(); 22 | 23 | public: 24 | /** 25 | * 设置百分比 26 | */ 27 | void SetPercent(float percent) noexcept { m_fPercent = percent; } 28 | 29 | /** 30 | * 设置说明文本 31 | */ 32 | Result SetHintText(std::string_view text) noexcept; 33 | 34 | protected: // Window 35 | void OnPrepareWindow() noexcept override; 36 | void OnRender() noexcept override; 37 | 38 | private: 39 | float m_fPercent = 0; 40 | std::string m_stHintText; 41 | }; 42 | } 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/EventBusSystem.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/6/7 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "ISubsystem.hpp" 11 | #include "../Result.hpp" 12 | 13 | namespace lstg::Subsystem 14 | { 15 | /** 16 | * 事件总线 17 | */ 18 | class EventBusSystem : 19 | public ISubsystem 20 | { 21 | public: 22 | EventBusSystem(SubsystemContainer& container); 23 | EventBusSystem(const EventBusSystem&) = delete; 24 | EventBusSystem(EventBusSystem&&)noexcept = delete; 25 | 26 | public: 27 | /** 28 | * 触发事件 29 | * @param event 事件 30 | */ 31 | Result EmitEvent(SubsystemEvent event) noexcept; 32 | 33 | /** 34 | * 读取事件 35 | * @return 事件 36 | */ 37 | std::optional PollEvent() noexcept; 38 | 39 | private: 40 | std::deque m_stEventQueue; 41 | }; 42 | 43 | using EventBusSystemPtr = std::shared_ptr; 44 | } 45 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/GameController/Buttons.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/25 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | 9 | namespace lstg::Subsystem::GameController 10 | { 11 | /** 12 | * 控制器按钮 13 | */ 14 | enum class Buttons 15 | { 16 | A = 0, 17 | B, 18 | X, 19 | Y, 20 | Back, 21 | Guide, 22 | Start, 23 | LeftStick, 24 | RightStick, 25 | LeftShoulder, 26 | RightShoulder, 27 | DPadUp, 28 | DPadDown, 29 | DPadLeft, 30 | DPadRight, 31 | Misc1, 32 | Paddle1, 33 | Paddle2, 34 | Paddle3, 35 | Paddle4, 36 | TouchPad, 37 | Count_, 38 | }; 39 | 40 | const char* ToString(Buttons button) noexcept; 41 | } 42 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/ISubsystem.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/6 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "SubsystemEvent.hpp" 10 | 11 | namespace lstg::Subsystem 12 | { 13 | class SubsystemContainer; 14 | 15 | /** 16 | * 子系统基类 17 | */ 18 | class ISubsystem 19 | { 20 | public: 21 | ISubsystem() = default; 22 | virtual ~ISubsystem() noexcept = default; 23 | 24 | public: 25 | /** 26 | * 更新系统 27 | * 默认无行为。 28 | * @param elapsedTime 距离上次调用的流逝时间(秒) 29 | */ 30 | virtual void OnUpdate(double elapsedTime) noexcept; 31 | 32 | /** 33 | * 用户渲染操作之前 34 | * @param elapsedTime 距离上次调用的流逝时间(秒) 35 | */ 36 | virtual void OnBeforeRender(double elapsedTime) noexcept; 37 | 38 | /** 39 | * 用户渲染操作之后 40 | * @param elapsedTime 距离上次调用的流逝时间(秒) 41 | */ 42 | virtual void OnAfterRender(double elapsedTime) noexcept; 43 | 44 | /** 45 | * 触发事件 46 | * 默认无行为。 47 | * @param event 事件 48 | */ 49 | virtual void OnEvent(SubsystemEvent& event) noexcept; 50 | }; 51 | 52 | using SubsystemPtr = std::shared_ptr; 53 | } 54 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/Drawing2D/Particle.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/7 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "../ColorRGBA32.hpp" 11 | 12 | namespace lstg::Subsystem::Render::Drawing2D 13 | { 14 | /** 15 | * 粒子对象 16 | */ 17 | struct Particle 18 | { 19 | float Age = 0.f; ///< @brief 存活时间 20 | float AliveTime = 0.f; ///< @brief 总生存时间 21 | glm::vec2 Location { 0.f, 0.f }; ///< @brief 位置 22 | glm::vec2 Velocity { 0.f, 0.f }; ///< @brief 速度 23 | float Gravity = 0.f; ///< @brief 重力 24 | float RadialAcceleration = 0.f; ///< @brief 线加速度 25 | float TangentialAcceleration = 0.f; ///< @brief 角加速度 26 | float Spin = 0.f; ///< @brief 自旋 27 | float SpinDelta = 0.f; ///< @brief 自旋增量 28 | float Size = 0.f; ///< @brief 大小 29 | float SizeDelta = 0.f; ///< @brief 大小增量 30 | glm::vec4 Color { 0.f, 0.f, 0.f, 0.f }; ///< @brief 颜色 31 | glm::vec4 ColorDelta { 0.f, 0.f, 0.f, 0.f }; ///< @brief 颜色增量 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/Drawing2D/Texture2D.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "../Texture.hpp" 9 | 10 | namespace lstg::Subsystem::Render::Drawing2D 11 | { 12 | /** 13 | * 2D 纹理 14 | */ 15 | class Texture2D 16 | { 17 | public: 18 | /** 19 | * 获取纹理对象 20 | */ 21 | const TexturePtr& GetUnderlayTexture() const noexcept; 22 | 23 | /** 24 | * 设置纹理对象 25 | * @param tex 纹理 26 | */ 27 | void SetUnderlayTexture(TexturePtr tex) noexcept; 28 | 29 | /** 30 | * 获取 PPU 31 | */ 32 | [[nodiscard]] float GetPixelPerUnit() const noexcept; 33 | 34 | /** 35 | * 设置 PPU 36 | * @param ppu Pixel Per Unit 37 | */ 38 | void SetPixelPerUnit(float ppu) noexcept; 39 | 40 | /** 41 | * 获得宽度 42 | * = 实际像素宽度 / PPU 43 | * @note 当纹理为 nullptr 时,返回默认空白纹理的大小 44 | */ 45 | [[nodiscard]] float GetWidth() const noexcept; 46 | 47 | /** 48 | * 获取高度 49 | * = 实际像素高度 / PPU 50 | * @note 当纹理为 nullptr 时,返回默认空白纹理的大小 51 | */ 52 | [[nodiscard]] float GetHeight() const noexcept; 53 | 54 | private: 55 | TexturePtr m_pTexture; 56 | float m_fPPU = 1.f; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/Font/FontCollection.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "../../../LRUCache.hpp" 10 | #include "IFontFace.hpp" 11 | 12 | namespace lstg::Subsystem::Render::Font 13 | { 14 | static const size_t kCharFontMappingCacheSize = 1024; 15 | 16 | /** 17 | * 字体集合 18 | */ 19 | class FontCollection 20 | { 21 | public: 22 | FontCollection(FontFacePtr primaryFont) noexcept; 23 | FontCollection(const FontCollection& org) = default; 24 | FontCollection(FontCollection&& org) noexcept = default; 25 | 26 | FontCollection& operator=(const FontCollection& rhs) = default; 27 | FontCollection& operator=(FontCollection&& rhs) noexcept = default; 28 | 29 | public: 30 | /** 31 | * 为指定的字符选定字体 32 | * @param ch 字符 33 | * @return <字体指针, 字形ID, 缩放> 34 | */ 35 | std::tuple ChooseFontForChar(char32_t ch) const noexcept; 36 | 37 | /** 38 | * 添加备选字体 39 | * 先添加的字体会先被选中。 40 | * @param face 字体 41 | * @param scale 缩放,用于调整不同字体的大小(相对于主字体) 42 | */ 43 | void AppendFallbackFont(FontFacePtr face, float scale = 1.f); 44 | 45 | private: 46 | FontFacePtr m_pPrimaryFont; 47 | std::vector> m_stFallbackFont; 48 | mutable LRUCache, kCharFontMappingCacheSize> m_pCharToFontCache; 49 | }; 50 | 51 | using FontCollectionPtr = std::shared_ptr; 52 | } 53 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/Font/FontGlyphRasterParam.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/29 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "FontSize.hpp" 10 | 11 | namespace lstg::Subsystem::Render::Font 12 | { 13 | /** 14 | * 字形内部ID 15 | */ 16 | using FontGlyphId = uint32_t; 17 | 18 | /** 19 | * 字形光栅化参数 20 | */ 21 | struct FontGlyphRasterParam 22 | { 23 | FontSize Size; ///< @brief 字体大小 24 | uint32_t Flags = 0; ///< @brief 光栅化参数,透传、内部使用,例如用于存储 FT_LOAD_* 25 | 26 | bool operator==(const FontGlyphRasterParam& rhs) const noexcept 27 | { 28 | return Size == rhs.Size && Flags == rhs.Flags; 29 | } 30 | 31 | bool operator!=(const FontGlyphRasterParam& rhs) const noexcept 32 | { 33 | return !operator==(rhs); 34 | } 35 | }; 36 | } 37 | 38 | template <> 39 | struct std::hash 40 | { 41 | std::size_t operator()(const lstg::Subsystem::Render::Font::FontGlyphRasterParam& s) const noexcept 42 | { 43 | auto h1 = std::hash{}(s.Size); 44 | auto h2 = std::hash{}(s.Flags); 45 | return h1 ^ h2; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/Font/FontSize.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::Font 11 | { 12 | /** 13 | * 带缩放字体大小 14 | */ 15 | struct FontSize 16 | { 17 | int32_t Size = 0; // 字体大小,DPI变换前 18 | float Scale = 0.f; // 额外的缩放量 19 | 20 | bool operator==(const FontSize& rhs) const noexcept 21 | { 22 | return Size == rhs.Size && Scale == rhs.Scale; 23 | } 24 | 25 | bool operator!=(const FontSize& rhs) const noexcept 26 | { 27 | return !operator==(rhs); 28 | } 29 | }; 30 | } 31 | 32 | template <> 33 | struct std::hash 34 | { 35 | std::size_t operator()(const lstg::Subsystem::Render::Font::FontSize& s) const noexcept 36 | { 37 | auto h1 = std::hash{}(s.Size); 38 | auto h2 = std::hash{}(s.Scale); 39 | return h1 ^ h2; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/GraphDef/DefinitionError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/24 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::GraphDef 11 | { 12 | /** 13 | * 定义相关错误 14 | */ 15 | enum class DefinitionError 16 | { 17 | Ok = 0, 18 | InvalidIdentifier = 1, 19 | SymbolAlreadyDefined = 2, 20 | SlotAlreadyDefined = 3, 21 | SymbolNotFound = 4, 22 | SymbolTypeMismatched = 5, 23 | ShaderCompileError = 6, 24 | CreatePRSError = 7, 25 | CreateSRBError = 8, 26 | }; 27 | 28 | /** 29 | * 定义相关错误分类 30 | */ 31 | class DefinitionErrorCategory : 32 | public std::error_category 33 | { 34 | public: 35 | static const DefinitionErrorCategory& GetInstance() noexcept; 36 | 37 | public: 38 | const char* name() const noexcept override; 39 | 40 | std::string message(int ev) const override; 41 | }; 42 | 43 | inline std::error_code make_error_code(DefinitionError ec) noexcept 44 | { 45 | return { static_cast(ec), DefinitionErrorCategory::GetInstance() }; 46 | } 47 | } 48 | 49 | namespace std 50 | { 51 | template <> 52 | struct is_error_code_enum : true_type {}; 53 | } 54 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Render/RenderEvent.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2023/8/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "RenderDevice.hpp" 10 | 11 | namespace lstg::Subsystem::Render 12 | { 13 | /** 14 | * 渲染事件类型 15 | */ 16 | enum class RenderEventTypes 17 | { 18 | None, 19 | SwapBufferResized, 20 | }; 21 | 22 | /** 23 | * 渲染系统事件 24 | */ 25 | struct RenderEvent 26 | { 27 | struct SwapBufferResizeArgs 28 | { 29 | uint32_t Width; 30 | uint32_t Height; 31 | }; 32 | 33 | RenderEventTypes Type = RenderEventTypes::None; 34 | 35 | union { 36 | SwapBufferResizeArgs SwapBufferResize; 37 | }; 38 | }; 39 | } // lstg::Subsystem::Render 40 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Script/AutoBridgeHint.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/4 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | 9 | #define LSTG_CLASS(...) 10 | #define LSTG_METHOD(...) 11 | #define LSTG_GETTER(...) 12 | #define LSTG_SETTER(...) 13 | #define LSTG_PROPERTY(...) 14 | 15 | #define LSTG_MODULE(...) 16 | 17 | #define LSTG_ENUM(...) 18 | #define LSTG_FIELD(...) 19 | 20 | #define LSTG_AUTO_BRIDGE_HINT 0 21 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/Script/LuaState.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/3 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "LuaStack.hpp" 9 | 10 | namespace lstg::Subsystem::Script 11 | { 12 | /** 13 | * Lua 状态封装 14 | */ 15 | class LuaState : 16 | public LuaStack 17 | { 18 | public: 19 | LuaState() 20 | : LuaStack(luaL_newstate()) 21 | { 22 | if (!m_pState) 23 | throw std::system_error(make_error_code(std::errc::not_enough_memory)); 24 | 25 | // lua5.1 没有 LUA_RIDX_MAINTHREAD,这里放置自己到 [REG]_mainthread 供 LuaReference 使用 26 | lua_pushthread(m_pState); 27 | lua_setfield(m_pState, LUA_REGISTRYINDEX, "_mainthread"); 28 | } 29 | 30 | LuaState(const LuaState&) = delete; 31 | 32 | ~LuaState() noexcept 33 | { 34 | if (m_pState) 35 | lua_close(m_pState); 36 | } 37 | 38 | public: 39 | /** 40 | * 加载标准库 41 | */ 42 | void OpenStandardLibrary() 43 | { 44 | luaL_openlibs(m_pState); 45 | } 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/VFS/AndroidAssetFileSystem.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2023/8/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "IFileSystem.hpp" 9 | 10 | struct AAssetManager; 11 | 12 | namespace lstg::Subsystem::VFS 13 | { 14 | /** 15 | * 安卓 Asset 文件系统 16 | */ 17 | class AndroidAssetFileSystem : 18 | public IFileSystem 19 | { 20 | public: 21 | /** 22 | * 构造文件系统 23 | * @param assetManager 安卓 AssetManager 对象,由外部确保指针有效 24 | * @param prefix Asset 目录前缀,默认为空 25 | */ 26 | AndroidAssetFileSystem(AAssetManager* assetManager, const char* prefix="") noexcept; 27 | 28 | public: // IFileSystem 29 | Result CreateDirectory(Path path) noexcept override; 30 | Result Remove(Path path) noexcept override; 31 | Result Rename(Path from, Path to) noexcept override; 32 | Result GetFileAttribute(Path path) noexcept override; 33 | Result VisitDirectory(Path path) noexcept override; 34 | Result OpenFile(Path path, FileAccessMode access, FileOpenFlags flags) noexcept override; 35 | const std::string& GetUserData() const noexcept override; 36 | void SetUserData(std::string ud) noexcept override; 37 | 38 | private: 39 | std::string MakeAssetPath(const Path& path) const; 40 | 41 | private: 42 | std::string m_stUserData; 43 | AAssetManager* m_pAssetManager = nullptr; 44 | std::string m_stPathPrefix; 45 | }; 46 | } // namespace lstg::Subsystem::VFS 47 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/VFS/LocalFileSystem.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "IFileSystem.hpp" 10 | 11 | namespace lstg::Subsystem::VFS 12 | { 13 | /** 14 | * 本地文件系统 15 | */ 16 | class LocalFileSystem : 17 | public IFileSystem 18 | { 19 | public: 20 | /** 21 | * 构造文件系统 22 | * @param root 根路径 23 | */ 24 | LocalFileSystem(std::filesystem::path root) noexcept; 25 | 26 | public: // IFileSystem 27 | Result CreateDirectory(Path path) noexcept override; 28 | Result Remove(Path path) noexcept override; 29 | Result Rename(Path from, Path to) noexcept override; 30 | Result GetFileAttribute(Path path) noexcept override; 31 | Result VisitDirectory(Path path) noexcept override; 32 | Result OpenFile(Path path, FileAccessMode access, FileOpenFlags flags) noexcept override; 33 | const std::string& GetUserData() const noexcept override; 34 | void SetUserData(std::string ud) noexcept override; 35 | 36 | private: 37 | std::filesystem::path MakeLocalPath(const Path& path) const; 38 | 39 | private: 40 | std::string m_stUserData; 41 | std::filesystem::path m_stRoot; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /include/lstg/Core/Subsystem/VFS/WindowedStream.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "IStream.hpp" 9 | 10 | namespace lstg::Subsystem::VFS 11 | { 12 | /** 13 | * Stream 窗口 14 | * 在父 Stream 限定一个区域进行 I/O 操作。 15 | * 需要注意,操作在父 Stream 进行时会影响读写位置。 16 | */ 17 | class WindowedStream : 18 | public IStream 19 | { 20 | public: 21 | /** 22 | * 从当前位置开始,建立长度不超过 maxLength 的子数据流。 23 | * @param underlay 底层数据流 24 | * @param maxLength 最大长度,需要保证 GetPosition() + maxLength <= GetLength() 25 | */ 26 | WindowedStream(StreamPtr underlay, uint64_t maxLength) noexcept; 27 | virtual ~WindowedStream() noexcept = default; 28 | 29 | public: // IStream 30 | bool IsReadable() const noexcept override; 31 | bool IsWriteable() const noexcept override; 32 | bool IsSeekable() const noexcept override; 33 | Result GetLength() const noexcept override; 34 | Result SetLength(uint64_t length) noexcept override; 35 | Result GetPosition() const noexcept override; 36 | Result Seek(int64_t offset, StreamSeekOrigins origin) noexcept override; 37 | Result IsEof() const noexcept override; 38 | Result Flush() noexcept override; 39 | Result Read(uint8_t* buffer, size_t length) noexcept override; 40 | Result Write(const uint8_t* buffer, size_t length) noexcept override; 41 | Result Clone() const noexcept override; 42 | 43 | private: 44 | StreamPtr m_pUnderlay; 45 | uint64_t m_ullMaxLength = 0; 46 | uint64_t m_ullLength = 0; 47 | uint64_t m_ullPosition = 0; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /include/lstg/Core/Text/IniParsingError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Text 11 | { 12 | /** 13 | * Ini 解析错误 14 | */ 15 | enum class IniParsingError 16 | { 17 | Ok = 0, 18 | SectionNotClosed = 1, 19 | UnexpectedCharacter = 2, 20 | }; 21 | 22 | /** 23 | * Ini 解析错误代码分类 24 | */ 25 | class IniParsingErrorCategory : public std::error_category 26 | { 27 | public: 28 | static const IniParsingErrorCategory& GetInstance() noexcept; 29 | 30 | public: 31 | const char* name() const noexcept override; 32 | std::string message(int ev) const override; 33 | }; 34 | 35 | inline std::error_code make_error_code(IniParsingError ec) noexcept 36 | { 37 | return { static_cast(ec), IniParsingErrorCategory::GetInstance() }; 38 | } 39 | } 40 | 41 | template <> 42 | struct std::is_error_code_enum : true_type {}; 43 | -------------------------------------------------------------------------------- /include/lstg/Core/Text/IniSaxParser.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/3 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "../Flag.hpp" 11 | #include "../Result.hpp" 12 | 13 | namespace lstg::Text 14 | { 15 | /** 16 | * Ini Sax 解析监听器 17 | */ 18 | class IIniSaxListener 19 | { 20 | public: 21 | /** 22 | * 开始处理 INI 节 23 | * @param name 节名称 24 | */ 25 | virtual Result OnSectionBegin(std::string_view name) noexcept = 0; 26 | 27 | /** 28 | * 结束处理 INI 节 29 | */ 30 | virtual Result OnSectionEnd() noexcept = 0; 31 | 32 | /** 33 | * 处理 INI 键值对 34 | * @param key 键 35 | * @param value 值 36 | */ 37 | virtual Result OnValue(std::string_view key, std::string_view value) noexcept = 0; 38 | }; 39 | 40 | /** 41 | * INI 解析参数 42 | */ 43 | LSTG_FLAG_BEGIN(IniParsingFlags) 44 | IgnoreSectionLeadingSpaces = 1, 45 | IgnoreSectionTailingSpaces = 2, 46 | IgnoreKeyLeadingSpaces = 4, 47 | IgnoreKeyTailingSpaces = 8, 48 | IgnoreValueLeadingSpaces = 16, 49 | IgnoreValueTailingSpaces = 32, 50 | RemoveCommentInValue = 64, 51 | UnixStyleComment = 128, 52 | LSTG_FLAG_END(IniParsingFlags) 53 | 54 | /** 55 | * INI Sax 解析器 56 | */ 57 | class IniSaxParser 58 | { 59 | public: 60 | /** 61 | * 解析 62 | * @param content 内容 63 | * @param listener 监听器 64 | * @param flags 解析参数 65 | */ 66 | static Result Parse(std::string_view content, IIniSaxListener* listener, IniParsingFlags flags) noexcept; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/EffectAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * FX 资产工厂 14 | */ 15 | class EffectAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 22 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/EffectAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Asset 12 | { 13 | /** 14 | * FX 加载器 15 | */ 16 | class EffectAssetLoader : 17 | public Subsystem::Asset::AssetLoader 18 | { 19 | public: 20 | EffectAssetLoader(Subsystem::Asset::AssetPtr asset); 21 | 22 | public: // AssetLoader 23 | Result PreLoad() noexcept override; 24 | Result AsyncLoad() noexcept override; 25 | Result PostLoad() noexcept override; 26 | void Update() noexcept override; 27 | 28 | #if LSTG_ASSET_HOT_RELOAD 29 | bool SupportHotReload() const noexcept override; 30 | bool CheckIsOutdated() const noexcept override; 31 | void PrepareToReload() noexcept override; 32 | #endif 33 | 34 | private: 35 | #if LSTG_ASSET_HOT_RELOAD 36 | Subsystem::VFS::FileAttribute m_stSourceAttribute; 37 | #endif 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/HgeFontAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Asset 12 | { 13 | /** 14 | * HGE 字体资产工厂 15 | */ 16 | class HgeFontAssetFactory : 17 | public Subsystem::Asset::IAssetFactory 18 | { 19 | public: 20 | HgeFontAssetFactory(); 21 | 22 | public: // IAssetFactory 23 | std::string_view GetAssetTypeName() const noexcept override; 24 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 25 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 26 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 27 | 28 | private: 29 | Subsystem::Render::Font::FontFactoryPtr m_pHGEFontFactory; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/HgeParticleAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * HGE 粒子资产工厂 14 | */ 15 | class HgeParticleAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: 19 | HgeParticleAssetFactory() = default; 20 | 21 | public: // IAssetFactory 22 | std::string_view GetAssetTypeName() const noexcept override; 23 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 24 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 25 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/HgeParticleAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Asset 13 | { 14 | /** 15 | * HGE 粒子系统加载器 16 | */ 17 | class HgeParticleAssetLoader : 18 | public Subsystem::Asset::AssetLoader 19 | { 20 | public: 21 | HgeParticleAssetLoader(Subsystem::Asset::AssetPtr asset, 22 | std::optional emitDirectionOverride); 23 | 24 | public: // AssetLoader 25 | Result PreLoad() noexcept override; 26 | Result AsyncLoad() noexcept override; 27 | Result PostLoad() noexcept override; 28 | void Update() noexcept override; 29 | 30 | #if LSTG_ASSET_HOT_RELOAD 31 | bool SupportHotReload() const noexcept override; 32 | bool CheckIsOutdated() const noexcept override; 33 | void PrepareToReload() noexcept override; 34 | #endif 35 | 36 | private: 37 | std::optional m_stEmitDirectionOverride; 38 | 39 | // 状态 40 | Subsystem::Render::Drawing2D::ParticleConfig m_stParticleConfig; 41 | #if LSTG_ASSET_HOT_RELOAD 42 | uint32_t m_uLoadedSpriteVersion = 0; 43 | Subsystem::VFS::FileAttribute m_stSourceAttribute; 44 | #endif 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/MusicAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 音乐资产工厂 14 | */ 15 | class MusicAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 22 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/MusicAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Asset 13 | { 14 | /** 15 | * 音乐资源加载器 16 | */ 17 | class MusicAssetLoader : 18 | public Subsystem::Asset::AssetLoader 19 | { 20 | public: 21 | MusicAssetLoader(Subsystem::Asset::AssetPtr asset); 22 | 23 | public: // AssetLoader 24 | Result PreLoad() noexcept override; 25 | Result AsyncLoad() noexcept override; 26 | Result PostLoad() noexcept override; 27 | void Update() noexcept override; 28 | 29 | #if LSTG_ASSET_HOT_RELOAD 30 | bool SupportHotReload() const noexcept override; 31 | bool CheckIsOutdated() const noexcept override; 32 | void PrepareToReload() noexcept override; 33 | #endif 34 | 35 | private: 36 | // 状态 37 | #if LSTG_ASSET_HOT_RELOAD 38 | Subsystem::VFS::FileAttribute m_stSourceAttribute; 39 | #endif 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SoundAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 音频资产工厂 14 | */ 15 | class SoundAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 22 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SoundAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Asset 13 | { 14 | /** 15 | * 音频资源加载器 16 | */ 17 | class SoundAssetLoader : 18 | public Subsystem::Asset::AssetLoader 19 | { 20 | public: 21 | SoundAssetLoader(Subsystem::Asset::AssetPtr asset); 22 | 23 | public: // AssetLoader 24 | Result PreLoad() noexcept override; 25 | Result AsyncLoad() noexcept override; 26 | Result PostLoad() noexcept override; 27 | void Update() noexcept override; 28 | 29 | #if LSTG_ASSET_HOT_RELOAD 30 | bool SupportHotReload() const noexcept override; 31 | bool CheckIsOutdated() const noexcept override; 32 | void PrepareToReload() noexcept override; 33 | #endif 34 | 35 | private: 36 | // 状态 37 | Subsystem::VFS::StreamPtr m_pSourceStream; // PreLoad 时加载 38 | #if LSTG_ASSET_HOT_RELOAD 39 | Subsystem::VFS::FileAttribute m_stSourceAttribute; 40 | #endif 41 | Subsystem::Audio::SoundDataPtr m_pSoundData; // AsyncLoad 时加载 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SpriteAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 精灵资产工厂 14 | */ 15 | class SpriteAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 22 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SpriteAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 精灵资产加载器 14 | */ 15 | class SpriteAssetLoader : 16 | public Subsystem::Asset::AssetLoader 17 | { 18 | public: 19 | SpriteAssetLoader(Subsystem::Asset::AssetPtr asset); 20 | 21 | public: // AssetLoader 22 | Result PreLoad() noexcept override; 23 | Result AsyncLoad() noexcept override; 24 | Result PostLoad() noexcept override; 25 | void Update() noexcept override; 26 | 27 | #if LSTG_ASSET_HOT_RELOAD 28 | bool SupportHotReload() const noexcept override; 29 | bool CheckIsOutdated() const noexcept override; 30 | void PrepareToReload() noexcept override; 31 | #endif 32 | 33 | private: 34 | #if LSTG_ASSET_HOT_RELOAD 35 | uint32_t m_uLastTextureVersion = 0; 36 | #endif 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SpriteSequenceAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/8 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 精灵序列动画资产工厂 14 | */ 15 | class SpriteSequenceAssetFactory : 16 | public Subsystem::Asset::IAssetFactory 17 | { 18 | public: // IAssetFactory 19 | std::string_view GetAssetTypeName() const noexcept override; 20 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 21 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 22 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/SpriteSequenceAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/8 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 精灵资产加载器 14 | */ 15 | class SpriteSequenceAssetLoader : 16 | public Subsystem::Asset::AssetLoader 17 | { 18 | public: 19 | SpriteSequenceAssetLoader(Subsystem::Asset::AssetPtr asset); 20 | 21 | public: // AssetLoader 22 | Result PreLoad() noexcept override; 23 | Result AsyncLoad() noexcept override; 24 | Result PostLoad() noexcept override; 25 | void Update() noexcept override; 26 | 27 | #if LSTG_ASSET_HOT_RELOAD 28 | bool SupportHotReload() const noexcept override; 29 | bool CheckIsOutdated() const noexcept override; 30 | void PrepareToReload() noexcept override; 31 | #endif 32 | 33 | private: 34 | #if LSTG_ASSET_HOT_RELOAD 35 | uint32_t m_uLastTextureVersion = 0; 36 | #endif 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/TextureAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/30 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Asset 12 | { 13 | class TextureAsset; 14 | 15 | /** 16 | * 纹理资产工厂 17 | */ 18 | class TextureAssetFactory : 19 | public Subsystem::Asset::IAssetFactory 20 | { 21 | public: // IAssetFactory 22 | std::string_view GetAssetTypeName() const noexcept override; 23 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 24 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 25 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 26 | 27 | public: 28 | /** 29 | * 调整所有 RT 大小 30 | * @param width 宽度 31 | * @param height 高度 32 | */ 33 | void ResizeRenderTarget(uint32_t width, uint32_t height) noexcept; 34 | 35 | private: 36 | Result CreateViews(uint32_t width, uint32_t height) noexcept; 37 | 38 | private: 39 | // 我们在这里保存所有的 RT,当渲染大小发生变化时主动调整 RT 的大小和渲染系统对齐 40 | // 考虑到 RT 的数量不会很多,因此这里采取惰性释放的方式释放内存 41 | std::vector> m_stRenderTargets; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/TextureAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/30 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Asset 11 | { 12 | /** 13 | * 纹理资产加载器 14 | */ 15 | class TextureAssetLoader : 16 | public Subsystem::Asset::AssetLoader 17 | { 18 | public: 19 | TextureAssetLoader(Subsystem::Asset::AssetPtr asset); 20 | 21 | public: // AssetLoader 22 | Result PreLoad() noexcept override; 23 | Result AsyncLoad() noexcept override; 24 | Result PostLoad() noexcept override; 25 | void Update() noexcept override; 26 | 27 | #if LSTG_ASSET_HOT_RELOAD 28 | bool SupportHotReload() const noexcept override; 29 | bool CheckIsOutdated() const noexcept override; 30 | void PrepareToReload() noexcept override; 31 | #endif 32 | 33 | private: 34 | #if LSTG_ASSET_HOT_RELOAD 35 | uint32_t m_uLastTextureVersion = 0; 36 | #endif 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/TrueTypeFontAssetFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/10 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Asset 12 | { 13 | /** 14 | * TrueType 字体资产工厂 15 | */ 16 | class TrueTypeFontAssetFactory : 17 | public Subsystem::Asset::IAssetFactory 18 | { 19 | public: 20 | TrueTypeFontAssetFactory(); 21 | 22 | public: // IAssetFactory 23 | std::string_view GetAssetTypeName() const noexcept override; 24 | Subsystem::Asset::AssetTypeId GetAssetTypeId() const noexcept override; 25 | Result CreateAsset(Subsystem::AssetSystem& assetSystem, Subsystem::Asset::AssetPoolPtr pool, 26 | std::string_view name, const nlohmann::json& arguments, Subsystem::Asset::IAssetDependencyResolver* resolver) noexcept override; 27 | 28 | private: 29 | Subsystem::Render::Font::FontFactoryPtr m_pTTFFontFactory; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /include/lstg/v2/Asset/TrueTypeFontAssetLoader.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/10 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Asset 13 | { 14 | /** 15 | * TrueType 字体加载器 16 | */ 17 | class TrueTypeFontAssetLoader : 18 | public Subsystem::Asset::AssetLoader 19 | { 20 | public: 21 | TrueTypeFontAssetLoader(Subsystem::Asset::AssetPtr asset, Subsystem::Render::Font::FontFactoryPtr factory); 22 | 23 | public: // AssetLoader 24 | Result PreLoad() noexcept override; 25 | Result AsyncLoad() noexcept override; 26 | Result PostLoad() noexcept override; 27 | void Update() noexcept override; 28 | 29 | #if LSTG_ASSET_HOT_RELOAD 30 | bool SupportHotReload() const noexcept override; 31 | bool CheckIsOutdated() const noexcept override; 32 | void PrepareToReload() noexcept override; 33 | #endif 34 | 35 | private: 36 | Subsystem::Render::Font::FontFactoryPtr m_pFontFactory; 37 | 38 | // 状态 39 | Subsystem::Render::Font::FontFacePtr m_pLoadedFontFace; 40 | #if LSTG_ASSET_HOT_RELOAD 41 | Subsystem::VFS::FileAttribute m_stSourceAttribute; 42 | #endif 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /include/lstg/v2/AssetNaming.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/5 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2 13 | { 14 | /** 15 | * 资产类型 16 | */ 17 | enum class AssetTypes 18 | { 19 | Texture = 1, 20 | Image = 2, 21 | Animation = 3, 22 | Music = 4, 23 | Sound = 5, 24 | Particle = 6, 25 | TexturedFont = 7, 26 | TrueTypeFont = 8, 27 | Effect = 9, 28 | }; 29 | 30 | /** 31 | * 转换资产类型到前缀 32 | * @param t 资产类型 33 | * @return 前缀 34 | */ 35 | const char* AssetTypeToPrefix(AssetTypes t) noexcept; 36 | 37 | /** 38 | * 检查资产名是否与类型匹配 39 | * @param name 名称 40 | * @param t 类型 41 | * @return 是否匹配 42 | */ 43 | bool IsAssetNameMatchType(std::string_view name, AssetTypes t) noexcept; 44 | 45 | /** 46 | * 构造完整的资产名 47 | * @param t 资产类型 48 | * @param name 名称 49 | * @return 完整资产名 50 | */ 51 | std::string MakeFullAssetName(AssetTypes t, std::string_view name); 52 | 53 | /** 54 | * 构造完整的资产名(原地) 55 | * @param out 输出缓冲区 56 | * @param t 资产类型 57 | * @param name 名称 58 | */ 59 | Result MakeFullAssetName(std::string& out, AssetTypes t, std::string_view name) noexcept; 60 | 61 | /** 62 | * 解出资产名 63 | * @param name 完整资产名 64 | * @return 脚本系统中所用资产名 65 | */ 66 | std::string ExtractAssetName(std::string_view name); 67 | } 68 | -------------------------------------------------------------------------------- /include/lstg/v2/BlendMode.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/31 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2 12 | { 13 | /** 14 | * 颜色混合模式 15 | */ 16 | using ColorBlendMode = Subsystem::Render::Drawing2D::ColorBlendMode; 17 | 18 | /** 19 | * 顶点颜色混合模式 20 | */ 21 | enum VertexColorBlendMode 22 | { 23 | Additive, 24 | Multiply, 25 | }; 26 | 27 | /** 28 | * 混合模式 29 | */ 30 | struct BlendMode 31 | { 32 | ColorBlendMode ColorBlend = ColorBlendMode::Alpha; 33 | VertexColorBlendMode VertexColorBlend = VertexColorBlendMode::Multiply; 34 | 35 | BlendMode() = default; 36 | BlendMode(std::string_view str) noexcept; 37 | 38 | /** 39 | * 转到字符串 40 | * @param m 混合模式 41 | * @return 混合模式字符串 42 | */ 43 | const char* ToString() noexcept; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/BuiltInModules.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "AssetManagerModule.hpp" 9 | #include "AudioModule.hpp" 10 | #include "GameObjectModule.hpp" 11 | #include "InputModule.hpp" 12 | #include "MathModule.hpp" 13 | #include "MiscModule.hpp" 14 | #include "RenderModule.hpp" 15 | 16 | namespace lstg::v2::Bridge 17 | { 18 | void InitBuiltInModule(Subsystem::Script::LuaStack& stack); 19 | } 20 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/Helper.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/21 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "../GameApp.hpp" 9 | 10 | namespace lstg::v2::Bridge 11 | { 12 | /** 13 | * 获取全局 APP 对象 14 | */ 15 | inline GameApp& GetApp() noexcept 16 | { 17 | return *static_cast(&GameApp::GetInstance()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/InputModule.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Bridge 12 | { 13 | /** 14 | * 输入模块 15 | */ 16 | LSTG_MODULE(lstg, GLOBAL) 17 | class InputModule 18 | { 19 | public: 20 | template 21 | using Unpack = Subsystem::Script::Unpack; 22 | 23 | public: 24 | /** 25 | * 检查按键是否被按下 26 | * @note 手柄输入被映射到 0x92~0xB1 和 0xDF~0xFE(共2个手柄、32个按键)的位置上 27 | * @param vkCode 被检查的按键 28 | * @return 是否按下 29 | */ 30 | LSTG_METHOD() 31 | static bool GetKeyState(int32_t vkCode); 32 | 33 | /** 34 | * 获取最后一次被输入的按键 35 | */ 36 | LSTG_METHOD() 37 | static int32_t GetLastKey(); 38 | 39 | /** 40 | * 获取最后一次被输入的字符 41 | * 对于 Unicode 字符总是转换到 UTF-8 编码。 42 | */ 43 | LSTG_METHOD() 44 | static const char* GetLastChar(); 45 | 46 | /** 47 | * 获取鼠标位置 48 | * 以窗口左下角为坐标原点。 49 | * @return X, Y 50 | */ 51 | LSTG_METHOD() 52 | static Unpack GetMousePosition(); 53 | 54 | /** 55 | * 获取鼠标按键是否被按下 56 | * @param button 按钮(0: 左键,1: 中键,2: 右键) 57 | * @return 是否被按下 58 | */ 59 | LSTG_METHOD() 60 | static bool GetMouseState(int32_t button); 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/LSTGColor.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/3/4 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Bridge 13 | { 14 | /** 15 | * 颜色类 16 | */ 17 | LSTG_CLASS() 18 | class LSTGColor : 19 | public Subsystem::Render::ColorRGBA32 20 | { 21 | public: 22 | using Subsystem::Render::ColorRGBA32::ColorRGBA32; 23 | 24 | LSTGColor(const Subsystem::Render::ColorRGBA32& org) 25 | : Subsystem::Render::ColorRGBA32(org) {} 26 | 27 | public: 28 | LSTG_METHOD(__eq) 29 | static bool Equals(const LSTGColor& lhs, const LSTGColor& rhs) noexcept; 30 | 31 | LSTG_METHOD(__add) 32 | static LSTGColor Add(const LSTGColor& lhs, const LSTGColor& rhs) noexcept; 33 | 34 | LSTG_METHOD(__sub) 35 | static LSTGColor Substract(const LSTGColor& lhs, const LSTGColor& rhs) noexcept; 36 | 37 | LSTG_METHOD(__mul) 38 | static LSTGColor Multiply(std::variant lhs, std::variant rhs) noexcept; 39 | 40 | LSTG_METHOD(ARGB) 41 | Subsystem::Script::Unpack ToARGB() const noexcept; 42 | 43 | LSTG_METHOD(__tostring) 44 | std::string ToString() const; 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/LSTGRandomizer.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/3/4 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2::Bridge 13 | { 14 | /** 15 | * 随机数发生器 16 | */ 17 | LSTG_CLASS() 18 | class LSTGRandomizer : 19 | public Math::Randomizer 20 | { 21 | public: 22 | /** 23 | * 设置随机数种子 24 | * @param v 种子 25 | */ 26 | LSTG_METHOD() 27 | void Seed(uint32_t v) noexcept; 28 | 29 | /** 30 | * 获取随机数种子 31 | * @return 种子 32 | */ 33 | LSTG_METHOD() 34 | uint32_t GetSeed() const noexcept; 35 | 36 | /** 37 | * 返回 [low, upper] 上的整数随机数 38 | * @note 有效数字只有 float 级别,不适用于大整数 39 | * @param low 下界 40 | * @param upper 上界 41 | * @return 随机数 42 | */ 43 | LSTG_METHOD() 44 | int32_t Int(int32_t low, int32_t upper) noexcept; 45 | 46 | /** 47 | * 返回 [low, upper) 上的浮点随机数 48 | * @note 满足 float 级别的精度 49 | * @param low 下界 50 | * @param upper 上界 51 | * @return 随机数 52 | */ 53 | LSTG_METHOD() 54 | double Float(double low, double upper) noexcept; 55 | 56 | /** 57 | * 返回 -1 或 +1 58 | * @return 随机数 59 | */ 60 | LSTG_METHOD() 61 | int32_t Sign() noexcept; 62 | 63 | /** 64 | * 对象转字符串表示 65 | */ 66 | LSTG_METHOD(__tostring) 67 | std::string ToString() const; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /include/lstg/v2/Bridge/MathModule.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::Bridge 12 | { 13 | /** 14 | * 数学模块 15 | */ 16 | LSTG_MODULE(lstg, GLOBAL) 17 | class MathModule 18 | { 19 | public: 20 | static constexpr double kPI = 3.14159265358979323846; 21 | static constexpr double kRadian2Degree = (180.0 / kPI); 22 | static constexpr double kDegree2Radian = (1.0 / kRadian2Degree); 23 | 24 | LSTG_METHOD(sin) 25 | static double Sin(double v) noexcept; 26 | 27 | LSTG_METHOD(cos) 28 | static double Cos(double v) noexcept; 29 | 30 | LSTG_METHOD(asin) 31 | static double ASin(double v) noexcept; 32 | 33 | LSTG_METHOD(acos) 34 | static double ACos(double v) noexcept; 35 | 36 | LSTG_METHOD(tan) 37 | static double Tan(double v) noexcept; 38 | 39 | LSTG_METHOD(atan) 40 | static double ATan(double v) noexcept; 41 | 42 | LSTG_METHOD(atan2) 43 | static double ATan2(double y, double x) noexcept; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /include/lstg/v2/DebugGUI/PerformanceMonitor.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace lstg::v2::DebugGUI 15 | { 16 | /** 17 | * 性能监控窗口 18 | */ 19 | class PerformanceMonitor : 20 | public Subsystem::DebugGUI::Window 21 | { 22 | public: 23 | PerformanceMonitor(); 24 | 25 | public: 26 | /** 27 | * 增加监控指标 28 | * @param group 组 29 | * @param chart 图表 30 | * @param serial 系列 31 | * @param metrics 指标名 32 | */ 33 | Result AddInstrument(std::string_view group, std::string_view chart, std::string_view serial, 34 | std::string_view metrics) noexcept; 35 | 36 | protected: // 需要实现 37 | void OnPrepareWindow() noexcept override; 38 | void OnUpdate(double elapsedTime) noexcept override; 39 | void OnRender() noexcept override; 40 | 41 | private: 42 | struct ChartSerial 43 | { 44 | std::string Name; 45 | std::string Metrics; 46 | std::vector Data; 47 | }; 48 | 49 | struct Chart 50 | { 51 | std::vector Series; 52 | }; 53 | 54 | using ChartContainer = std::map>; 55 | using GroupContainer = std::map>; 56 | 57 | GroupContainer m_stGroups; 58 | std::vector m_stGroupSelects; 59 | std::string m_stCurrentSelectedGroup; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /include/lstg/v2/GamePlay/BentLaser.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/7 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include "ScriptObjectPool.hpp" 10 | #include "../MathAlias.hpp" 11 | #include "../BlendMode.hpp" 12 | 13 | namespace lstg::v2::GamePlay 14 | { 15 | /** 16 | * 曲线激光 17 | * 18 | * lstg 中的曲线激光对象,由于脱离 GamePlay 存在,使用上较为不便。 19 | * 将在未来版本中移除。 20 | */ 21 | class BentLaser 22 | { 23 | struct LaserNode 24 | { 25 | Vec2 Location; 26 | double HalfWidth = 0.; 27 | }; 28 | 29 | enum { 30 | kMaxLaserNodes = 512 31 | }; 32 | 33 | public: 34 | bool Update(ScriptObjectId id, int32_t length, double width) noexcept; 35 | void Release() noexcept; 36 | bool Render(const char* textureName, BlendMode blend, Subsystem::Render::ColorRGBA32 c, Math::UVRectangle textureRect, 37 | double scale) const noexcept; 38 | bool CollisionCheck(double x, double y, double rot, double a, double b, bool rect) const noexcept; 39 | bool BoundCheck() const noexcept; 40 | 41 | private: 42 | CircularQueue m_stQueue; 43 | double m_dLength = 0.; // 记录激光长度 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /include/lstg/v2/GamePlay/Components/Movement.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "../../MathAlias.hpp" 9 | 10 | namespace lstg::v2::GamePlay::Components 11 | { 12 | /** 13 | * 简单移动 14 | */ 15 | struct Movement 16 | { 17 | /** 18 | * 角速度 19 | */ 20 | double AngularVelocity = 0; 21 | 22 | /** 23 | * 线速度 24 | */ 25 | Vec2 Velocity { 0, 0 }; 26 | 27 | /** 28 | * 加速度 29 | */ 30 | Vec2 AccelVelocity { 0, 0 }; 31 | 32 | /** 33 | * 自动转向 34 | */ 35 | bool RotateToSpeedDirection = false; 36 | 37 | void Reset() noexcept; 38 | }; 39 | 40 | constexpr uint32_t GetComponentId(Movement*) noexcept 41 | { 42 | return 3u; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /include/lstg/v2/GamePlay/Components/Script.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::v2::GamePlay 12 | { 13 | class ScriptObjectPool; 14 | } 15 | 16 | namespace lstg::v2::GamePlay::Components 17 | { 18 | /** 19 | * 脚本组件 20 | */ 21 | struct Script 22 | { 23 | /** 24 | * 在脚本系统中关联对象的 ID 25 | */ 26 | uint32_t ScriptObjectId = 0; 27 | 28 | /** 29 | * 脚本对象池 30 | */ 31 | ScriptObjectPool* Pool = nullptr; 32 | 33 | void Reset() noexcept; 34 | }; 35 | 36 | constexpr uint32_t GetComponentId(Script*) noexcept 37 | { 38 | return 8u; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /include/lstg/v2/GamePlay/Components/Transform.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/24 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "../../MathAlias.hpp" 9 | 10 | namespace lstg::v2::GamePlay::Components 11 | { 12 | /** 13 | * 变换组件 14 | */ 15 | struct Transform 16 | { 17 | /** 18 | * 坐标 19 | */ 20 | Vec2 Location { 0., 0. }; 21 | 22 | /** 23 | * 上一帧坐标 24 | */ 25 | Vec2 LastLocation { 0., 0. }; 26 | 27 | /** 28 | * 距离上一帧的坐标差量 29 | */ 30 | Vec2 LocationDelta { 0., 0. }; 31 | 32 | /** 33 | * 旋转量 34 | */ 35 | double Rotation = 0; 36 | 37 | void Reset() noexcept; 38 | }; 39 | 40 | constexpr uint32_t GetComponentId(Transform*) noexcept 41 | { 42 | return 0u; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /include/lstg/v2/MathAlias.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/31 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::v2 13 | { 14 | // 这里定义 GamePlay 所用的数据结构 15 | using Vec2 = glm::vec<2, double, glm::defaultp>; 16 | using WorldRectangle = Math::Rectangle; 17 | using ColliderShape = Math::Collider2D::ColliderShape; 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/Encoding/EncodingError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/3 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Encoding; 12 | 13 | const EncodingErrorCategory& EncodingErrorCategory::GetInstance() noexcept 14 | { 15 | static EncodingErrorCategory kInstance; 16 | return kInstance; 17 | } 18 | 19 | const char* EncodingErrorCategory::name() const noexcept 20 | { 21 | return "EncodingError"; 22 | } 23 | 24 | std::string EncodingErrorCategory::message(int ev) const 25 | { 26 | switch (static_cast(ev)) 27 | { 28 | case EncodingError::DecodingFailure: 29 | return "Decoding failure"; 30 | case EncodingError::EncodingFailure: 31 | return "Encoding failure"; 32 | default: 33 | return ""; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Core/JniUtils.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2023/8/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #ifdef LSTG_PLATFORM_ANDROID 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | using namespace std; 17 | using namespace lstg; 18 | 19 | // 20 | 21 | JniUtils::JObjectReference::JObjectReference(JNIEnv* env, jobject object) 22 | : m_pEnv(env), m_pObject(object) 23 | { 24 | assert(env && object); 25 | } 26 | 27 | JniUtils::JObjectReference::JObjectReference(JObjectReference&& rhs) noexcept 28 | : m_pEnv(rhs.m_pEnv), m_pObject(rhs.m_pObject) 29 | { 30 | assert((!m_pEnv && !m_pObject) || (m_pEnv && m_pObject)); 31 | rhs.m_pObject = nullptr; 32 | } 33 | 34 | JniUtils::JObjectReference::~JObjectReference() 35 | { 36 | Reset(); 37 | } 38 | 39 | JniUtils::JObjectReference& JniUtils::JObjectReference::operator=(JObjectReference&& rhs) noexcept 40 | { 41 | if (this == &rhs) 42 | return *this; 43 | 44 | Reset(); 45 | 46 | m_pEnv = rhs.m_pEnv; 47 | m_pObject = rhs.m_pObject; 48 | rhs.m_pEnv = nullptr; 49 | rhs.m_pObject = nullptr; 50 | 51 | return *this; 52 | } 53 | 54 | JniUtils::JObjectReference::operator bool() const noexcept 55 | { 56 | return m_pObject != nullptr; 57 | } 58 | 59 | jobject JniUtils::JObjectReference::operator*() const noexcept 60 | { 61 | return m_pObject; 62 | } 63 | 64 | void JniUtils::JObjectReference::Reset() noexcept 65 | { 66 | if (m_pObject) 67 | m_pEnv->DeleteGlobalRef(m_pObject); 68 | 69 | m_pEnv = nullptr; 70 | m_pObject = nullptr; 71 | } 72 | 73 | // 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/Core/Pal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include "detail/SDLHelper.hpp" 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | 14 | std::filesystem::path Pal::GetUserStorageDirectory() noexcept 15 | { 16 | try 17 | { 18 | detail::SDLMemoryPtr appDirectory(SDL_GetPrefPath("lstgplus", LSTG_APP_NAME)); 19 | if (appDirectory) 20 | return appDirectory.get(); 21 | else 22 | return filesystem::current_path(); 23 | } 24 | catch (...) 25 | { 26 | return {}; 27 | } 28 | } 29 | 30 | void Pal::FatalError(const char* msg, bool abort) noexcept 31 | { 32 | // 在终端显示错误 33 | ::fprintf(stderr, "FATAL ERROR: %s", msg); 34 | 35 | // 弹出对话框,忽略返回值 36 | // FIXME: 设置 parent window 37 | ::SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "LuaSTGPlus: Fatal Error", msg, nullptr); 38 | 39 | // 终止 40 | if (abort) 41 | ::abort(); 42 | } 43 | 44 | uint64_t Pal::GetCurrentTick() noexcept 45 | { 46 | return ::SDL_GetPerformanceCounter(); 47 | } 48 | 49 | uint64_t Pal::GetTickFrequency() noexcept 50 | { 51 | return ::SDL_GetPerformanceFrequency(); 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Asset/Asset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include "detail/WeakPtrTraits.hpp" 11 | 12 | using namespace std; 13 | using namespace lstg; 14 | using namespace lstg::Subsystem::Asset; 15 | 16 | Asset::Asset(std::string name) 17 | : m_stName(std::move(name)) 18 | { 19 | } 20 | 21 | Asset::~Asset() noexcept 22 | { 23 | assert(m_uId == kEmptyAssetId && detail::IsWeakPtrUninitialized(m_pPool)); 24 | } 25 | 26 | bool Asset::IsWildAsset() const noexcept 27 | { 28 | return detail::IsWeakPtrUninitialized(m_pPool); 29 | } 30 | 31 | void Asset::SetState(AssetStates s) noexcept 32 | { 33 | // 限制状态转换 34 | #if !LSTG_ASSET_HOT_RELOAD 35 | assert((m_iState == AssetStates::Uninitialized && (s == AssetStates::Loaded || s == AssetStates::Error)) || 36 | (m_iState == AssetStates::Loaded && s == AssetStates::Error) || 37 | (m_iState == AssetStates::Error && s == AssetStates::Error)); 38 | #else 39 | // 热更新的情况下,不允许出现已经加载的资源转换到错误状态 40 | assert(!(m_iState == AssetStates::Loaded && (s == AssetStates::Error || s == AssetStates::Uninitialized))); 41 | #endif 42 | m_iState = s; 43 | } 44 | 45 | #if LSTG_ASSET_HOT_RELOAD 46 | void Asset::UpdateVersion() noexcept 47 | { 48 | ++m_uVersion; 49 | } 50 | #endif 51 | 52 | void Asset::OnRemove() noexcept 53 | { 54 | } 55 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Asset/AssetError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Asset; 12 | 13 | // 14 | 15 | const AssetErrorCategory& AssetErrorCategory::GetInstance() noexcept 16 | { 17 | static const AssetErrorCategory kInstance; 18 | return kInstance; 19 | } 20 | 21 | const char* AssetErrorCategory::name() const noexcept 22 | { 23 | return "AssetError"; 24 | } 25 | 26 | std::string AssetErrorCategory::message(int ev) const 27 | { 28 | switch (static_cast(ev)) 29 | { 30 | case AssetError::Ok: 31 | return "ok"; 32 | case AssetError::AssetAlreadyExists: 33 | return "asset already exists"; 34 | case AssetError::AssetNotFound: 35 | return "asset not found"; 36 | case AssetError::MissingRequiredArgument: 37 | return "required argument is missing"; 38 | case AssetError::LoadingCancelled: 39 | return "loading task is cancelled"; 40 | case AssetError::AssetFactoryAlreadyRegistered: 41 | return "asset factory is already registered"; 42 | case AssetError::AssetFactoryNotRegistered: 43 | return "asset factory is not registered for this type"; 44 | case AssetError::InvalidState: 45 | return "invalid state"; 46 | case AssetError::DependentAssetNotFound: 47 | return "dependent asset not found"; 48 | default: 49 | return ""; 50 | } 51 | } 52 | 53 | // 54 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Asset/AssetLoader.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Asset; 12 | 13 | AssetLoader::AssetLoader(AssetPtr asset) 14 | : m_pAsset(std::move(asset)) 15 | { 16 | m_iState.store(AssetLoadingStates::Uninitialized, std::memory_order_release); 17 | } 18 | 19 | AssetLoadingStates AssetLoader::GetState() const noexcept 20 | { 21 | return m_iState.load(std::memory_order_acquire); 22 | } 23 | 24 | bool AssetLoader::IsLock() const noexcept 25 | { 26 | return m_bLocked; 27 | } 28 | 29 | void AssetLoader::SetLock(bool v) noexcept 30 | { 31 | m_bLocked = v; 32 | } 33 | 34 | void AssetLoader::SetState(AssetLoadingStates state) noexcept 35 | { 36 | m_iState.store(state, std::memory_order_release); 37 | } 38 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Asset/detail/WeakPtrTraits.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/5/14 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Asset::detail 11 | { 12 | // https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned 13 | template 14 | bool IsWeakPtrUninitialized(const std::weak_ptr& weak) noexcept 15 | { 16 | using wt = std::weak_ptr; 17 | return !weak.owner_before(wt{}) && !wt{}.owner_before(weak); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/BusChannel.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/3 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Audio; 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/DspPlugins/Limiter.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Audio::DspPlugins 11 | { 12 | /** 13 | * 压限器 14 | */ 15 | class Limiter : 16 | public IDspPlugin 17 | { 18 | public: 19 | static const char* GetNameStatic() noexcept; 20 | 21 | public: 22 | Limiter(); 23 | 24 | public: // IDspPlugin 25 | const char* GetName() const noexcept override; 26 | size_t GetParameterCount() const noexcept override; 27 | const DspPluginParameterInfo& GetParameterInfo(size_t index) const noexcept override; 28 | Result GetSliderParameter(std::string_view id) const noexcept override; 29 | Result SetSliderParameter(std::string_view id, float value) noexcept override; 30 | Result GetEnumParameter(std::string_view id) const noexcept override; 31 | Result SetEnumParameter(std::string_view id, int32_t value) noexcept override; 32 | void Process(SampleView<2> samples) noexcept override; 33 | 34 | private: 35 | std::atomic m_fCeilingDb; 36 | std::atomic m_fThresholdDb; 37 | std::atomic m_fSoftClipDb; 38 | std::atomic m_fSoftClipRatio; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/MemorySoundData.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include "SDLSoundDecoder.hpp" 12 | 13 | namespace lstg::Subsystem::Audio 14 | { 15 | /** 16 | * 内存 PCM 数据源 17 | */ 18 | class MemorySoundData : 19 | public ISoundData, 20 | public std::enable_shared_from_this 21 | { 22 | public: 23 | /** 24 | * 从音频文件构造 PCM 数据 25 | * @param stream 音频文件 26 | */ 27 | MemorySoundData(VFS::StreamPtr stream); 28 | 29 | public: // ISoundData 30 | Result CreateDecoder() noexcept override; 31 | 32 | private: 33 | std::vector m_stPCMData[ISoundDecoder::kChannels]; 34 | SampleView m_stPCMDataView; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/NullSoundDecoder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "NullSoundDecoder.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Audio; 12 | 13 | NullSoundDecoder::NullSoundDecoder(std::shared_ptr> pcmData) 14 | : m_pPCMData(std::move(pcmData)) 15 | { 16 | assert(m_pPCMData); 17 | } 18 | 19 | Result NullSoundDecoder::Decode(SampleView output) noexcept 20 | { 21 | assert(m_uPosition <= m_pPCMData->GetSampleCount()); 22 | auto restSamples = m_pPCMData->GetSampleCount() - m_uPosition; 23 | auto readSamples = std::min(restSamples, output.GetSampleCount()); 24 | for (size_t i = 0; i < kChannels; ++i) 25 | ::memcpy(&output[i][0], &m_pPCMData->operator[](i)[m_uPosition], readSamples * sizeof(float)); 26 | m_uPosition += readSamples; 27 | return readSamples; 28 | } 29 | 30 | Result NullSoundDecoder::GetDuration() noexcept 31 | { 32 | // 采样转时间 33 | return static_cast((m_pPCMData->GetSampleCount() * 1000) / ISoundDecoder::kSampleRate); 34 | } 35 | 36 | Result NullSoundDecoder::Seek(uint32_t timeMs) noexcept 37 | { 38 | // 时间转采样 39 | auto samples = std::min(m_pPCMData->GetSampleCount(), timeMs * ISoundDecoder::kSampleRate / 1000); 40 | m_uPosition = samples; 41 | return {}; 42 | } 43 | 44 | Result NullSoundDecoder::Reset() noexcept 45 | { 46 | m_uPosition = 0; 47 | return {}; 48 | } 49 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/NullSoundDecoder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Audio 11 | { 12 | /** 13 | * 空音频解码器 14 | * 用于直接推送原始 PCM 数据。 15 | */ 16 | class NullSoundDecoder : 17 | public ISoundDecoder 18 | { 19 | public: 20 | /** 21 | * 构造空解码器 22 | * @param pcmData PCM数据(必须满足 44100Hz 采样率) 23 | */ 24 | NullSoundDecoder(std::shared_ptr> pcmData); 25 | 26 | public: // ISoundDecoder 27 | Result Decode(SampleView output) noexcept; 28 | Result GetDuration() noexcept; 29 | Result Seek(uint32_t timeMs) noexcept; 30 | Result Reset() noexcept; 31 | 32 | private: 33 | std::shared_ptr> m_pPCMData; 34 | size_t m_uPosition = 0; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/SDLSoundDecoder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | 12 | namespace lstg::Subsystem::Audio 13 | { 14 | /** 15 | * SDL_Sound 解码器 16 | */ 17 | class SDLSoundDecoder : 18 | public ISoundDecoder 19 | { 20 | public: 21 | /** 22 | * 从流构造 Decoder 23 | * @param stream 流 24 | */ 25 | SDLSoundDecoder(VFS::StreamPtr stream); 26 | SDLSoundDecoder(const SDLSoundDecoder&) = delete; 27 | SDLSoundDecoder(SDLSoundDecoder&&) noexcept = delete; 28 | ~SDLSoundDecoder(); 29 | 30 | public: // ISoundDecoder 31 | Result Decode(SampleView output) noexcept override; 32 | Result GetDuration() noexcept override; 33 | Result Seek(uint32_t timeMs) noexcept override; 34 | Result Reset() noexcept override; 35 | 36 | private: 37 | VFS::StreamPtr m_pStream; 38 | Sound_Sample* m_pSample = nullptr; 39 | size_t m_uRestSamples = 0; // 在 m_pSample 中剩余未读取的采样数 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/StreamSoundData.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "StreamSoundData.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Audio; 12 | 13 | StreamSoundData::StreamSoundData(VFS::StreamPtr stream) 14 | : m_pStream(std::move(stream)) 15 | { 16 | } 17 | 18 | Result StreamSoundData::CreateDecoder() noexcept 19 | { 20 | try 21 | { 22 | // 由于 SoundDecoder 在单独线程处理,且需要保证互不干扰,此时需要 Clone Stream 23 | auto clone = m_pStream->Clone(); 24 | if (!clone) 25 | return clone.GetError(); 26 | return make_shared(std::move(*clone)); 27 | } 28 | catch (...) 29 | { 30 | return make_error_code(errc::not_enough_memory); 31 | } 32 | } 33 | 34 | Result Subsystem::Audio::CreateStreamSoundData(VFS::StreamPtr stream) noexcept 35 | { 36 | try 37 | { 38 | assert(stream); 39 | 40 | auto seekableStream = ConvertToSeekableStream(std::move(stream)); 41 | if (!seekableStream) 42 | return seekableStream.GetError(); 43 | 44 | return make_shared(std::move(*seekableStream)); 45 | } 46 | catch (const std::system_error& ex) 47 | { 48 | return ex.code(); 49 | } 50 | catch (...) 51 | { 52 | return make_error_code(errc::not_enough_memory); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/StreamSoundData.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include "SDLSoundDecoder.hpp" 12 | 13 | namespace lstg::Subsystem::Audio 14 | { 15 | /** 16 | * 流 PCM 数据源 17 | */ 18 | class StreamSoundData : 19 | public ISoundData 20 | { 21 | public: 22 | /** 23 | * 从文件构造 24 | * @param stream 音频文件 25 | */ 26 | StreamSoundData(VFS::StreamPtr stream); 27 | 28 | public: // ISoundData 29 | Result CreateDecoder() noexcept override; 30 | 31 | private: 32 | VFS::StreamPtr m_pStream; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/ALHandler.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "ALHandler.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Audio::detail; 12 | 13 | // 14 | 15 | void ALDeviceHandleCloser::operator()(ALCdevice* p) noexcept 16 | { 17 | if (p) 18 | ::alcCloseDevice(p); 19 | } 20 | 21 | // 22 | 23 | // 24 | 25 | void ALContextHandleCloser::operator()(ALCcontext* p) noexcept 26 | { 27 | if (p) 28 | ::alcDestroyContext(p); 29 | } 30 | 31 | // 32 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/ALHandler.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | #ifdef LSTG_PLATFORM_EMSCRIPTEN 11 | #include 12 | #include 13 | #else 14 | #include 15 | #include 16 | #endif 17 | 18 | namespace lstg::Subsystem::Audio::detail 19 | { 20 | /** 21 | * OpenAL 设备句柄析构器 22 | */ 23 | struct ALDeviceHandleCloser 24 | { 25 | void operator()(ALCdevice* p) noexcept; 26 | }; 27 | 28 | using ALDeviceHandler = std::unique_ptr; 29 | 30 | /** 31 | * OpenAL 上下文句柄析构器 32 | */ 33 | struct ALContextHandleCloser 34 | { 35 | void operator()(ALCcontext* p) noexcept; 36 | }; 37 | 38 | using ALContextHandler = std::unique_ptr; 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/AudioDevice.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/18 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include "ALHandler.hpp" 12 | 13 | namespace lstg::Subsystem::Audio::detail 14 | { 15 | LSTG_DEFINE_EXCEPTION(AudioDeviceInitializeFailedException); 16 | 17 | /** 18 | * 音频设备 19 | */ 20 | class AudioDevice 21 | { 22 | public: 23 | AudioDevice(); 24 | ~AudioDevice(); 25 | 26 | public: 27 | /** 28 | * 启动 Buffering 29 | */ 30 | void Start() noexcept; 31 | 32 | /** 33 | * 暂停 Buffering 34 | */ 35 | void Pause() noexcept; 36 | 37 | /** 38 | * 设置流回调 39 | * @param cb 回调 40 | */ 41 | void SetStreamingCallback(std::function()> cb) noexcept { m_stStreamingCallback = std::move(cb); } 42 | 43 | /** 44 | * 更新状态 45 | * @return 更新的 Buffer 数 46 | */ 47 | size_t Update() noexcept; 48 | 49 | private: 50 | enum { 51 | #ifdef LSTG_PLATFORM_EMSCRIPTEN 52 | kMainBufferCount = 5, 53 | #else 54 | kMainBufferCount = 3, // 一个缓冲区1024采样,共计3072采样,在44100Hz下预计产生70ms延迟,可以容忍的计算时间为46ms 55 | #endif 56 | }; 57 | 58 | ALDeviceHandler m_pDevice; 59 | ALContextHandler m_pContext; 60 | ALuint m_uMainSourceHandle = 0; 61 | ALuint m_stMainBuffers[kMainBufferCount] = { 0, 0, 0 }; 62 | 63 | bool m_bPlaying = false; 64 | std::function()> m_stStreamingCallback; 65 | std::vector m_stSampleBuffer; 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/AudioEngineError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "AudioEngineError.hpp" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::Audio::detail; 14 | 15 | const AudioEngineErrorCategory& AudioEngineErrorCategory::GetInstance() noexcept 16 | { 17 | static const AudioEngineErrorCategory kInstance; 18 | return kInstance; 19 | } 20 | 21 | const char* AudioEngineErrorCategory::name() const noexcept 22 | { 23 | return "AudioEngineError"; 24 | } 25 | 26 | std::string AudioEngineErrorCategory::message(int ev) const 27 | { 28 | switch (static_cast(ev)) 29 | { 30 | case AudioEngineErrorCodes::Ok: 31 | return "Ok"; 32 | default: 33 | assert(false); 34 | return ""; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/AudioEngineError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Audio::detail 11 | { 12 | /** 13 | * 音频引擎错误码 14 | */ 15 | enum class AudioEngineErrorCodes 16 | { 17 | Ok = 0, 18 | BusChannelCircularSendingDetected = 1, 19 | NoSoundSourceAvailable = 2, 20 | SoundSourceAlreadyDisposed = 3, 21 | }; 22 | 23 | /** 24 | * 音频引擎错误代码分类 25 | */ 26 | class AudioEngineErrorCategory : 27 | public std::error_category 28 | { 29 | public: 30 | static const AudioEngineErrorCategory& GetInstance() noexcept; 31 | 32 | public: 33 | const char* name() const noexcept override; 34 | std::string message(int ev) const override; 35 | }; 36 | 37 | inline std::error_code make_error_code(AudioEngineErrorCodes ec) noexcept 38 | { 39 | return { static_cast(ec), AudioEngineErrorCategory::GetInstance() }; 40 | } 41 | } 42 | 43 | template <> 44 | struct std::is_error_code_enum : std::true_type {}; 45 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Audio/detail/SDLSoundError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/13 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Audio::detail 11 | { 12 | /** 13 | * SDL_Sound 错误码 14 | */ 15 | enum class SDLSoundErrorCodes 16 | { 17 | Ok = 0, 18 | Unknown, 19 | IsInitialized, 20 | NotInitialized, 21 | InvalidArgument, 22 | OutOfMemory, 23 | NotSupported, 24 | UnsupportedFormat, 25 | NotHandle, 26 | NoSuchFile, 27 | PastEOF, 28 | IOError, 29 | CompressionError, 30 | PrevError, 31 | PrevEOF, 32 | NotSeekable, 33 | }; 34 | 35 | /** 36 | * SDL_Sound 错误代码分类 37 | */ 38 | class SDLSoundErrorCategory : 39 | public std::error_category 40 | { 41 | public: 42 | static const SDLSoundErrorCategory& GetInstance() noexcept; 43 | 44 | public: 45 | const char* name() const noexcept override; 46 | std::string message(int ev) const override; 47 | }; 48 | 49 | inline std::error_code make_error_code(SDLSoundErrorCodes ec) noexcept 50 | { 51 | return { static_cast(ec), SDLSoundErrorCategory::GetInstance() }; 52 | } 53 | 54 | /** 55 | * 从错误字符串构造错误码 56 | * @param str 字符串 57 | * @return 错误码 58 | */ 59 | SDLSoundErrorCodes FromErrorString(const char* str) noexcept; 60 | } 61 | 62 | template <> 63 | struct std::is_error_code_enum : std::true_type {}; 64 | -------------------------------------------------------------------------------- /src/Core/Subsystem/AudioSystem.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include "Audio/DspPlugins/Limiter.hpp" 10 | #include "Audio/DspPlugins/Filter.hpp" 11 | #include "Audio/DspPlugins/Reverb.hpp" 12 | 13 | using namespace std; 14 | using namespace lstg; 15 | using namespace lstg::Subsystem; 16 | 17 | AudioSystem::AudioSystem(SubsystemContainer& container) 18 | { 19 | // 初始化音频引擎 20 | m_pEngine = make_unique(); 21 | 22 | // 注册自带的 DSP 插件 23 | RegisterDspPlugin(); 24 | RegisterDspPlugin(); 25 | RegisterDspPlugin(); 26 | } 27 | 28 | AudioSystem::~AudioSystem() 29 | { 30 | } 31 | 32 | Result AudioSystem::CreateDspPlugin(std::string_view name) noexcept 33 | { 34 | auto it = m_stDspPluginFactory.find(name); 35 | if (it == m_stDspPluginFactory.end()) 36 | return make_error_code(errc::no_such_file_or_directory); 37 | try 38 | { 39 | assert(it->second); 40 | return it->second(); 41 | } 42 | catch (...) 43 | { 44 | return make_error_code(errc::not_enough_memory); 45 | } 46 | } 47 | 48 | void AudioSystem::OnUpdate(double elapsedTime) noexcept 49 | { 50 | m_pEngine->Update(elapsedTime); 51 | } 52 | -------------------------------------------------------------------------------- /src/Core/Subsystem/DebugGUI/ProgressWindow.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::DebugGUI; 14 | 15 | static const DebugWindowFlags kWindowStyle = 16 | DebugWindowFlags::AlwaysAutoResize | 17 | DebugWindowFlags::NoFocusOnAppearing | 18 | DebugWindowFlags::NoInputs | 19 | DebugWindowFlags::NoNav | 20 | DebugWindowFlags::NoMove | 21 | DebugWindowFlags::NoSavedSettings | 22 | DebugWindowFlags::NoTitleBar | 23 | DebugWindowFlags::NoBackground; 24 | 25 | ProgressWindow::ProgressWindow() 26 | : Window("ProgressWindow", "ProgressWindow", kWindowStyle) 27 | { 28 | } 29 | 30 | Result ProgressWindow::SetHintText(std::string_view text) noexcept 31 | { 32 | try 33 | { 34 | m_stHintText = text; 35 | } 36 | catch (...) // bad_alloc 37 | { 38 | return make_error_code(errc::not_enough_memory); 39 | } 40 | return {}; 41 | } 42 | 43 | void ProgressWindow::OnPrepareWindow() noexcept 44 | { 45 | auto sz = ImGui::GetIO().DisplaySize; 46 | ImGui::SetNextWindowPos(ImVec2{sz.x * 0.5f, sz.y * 0.75f}, 0, ImVec2{0.5f, 0.f}); 47 | } 48 | 49 | void ProgressWindow::OnRender() noexcept 50 | { 51 | ImGui::Text("%s", m_stHintText.c_str()); 52 | ImGui::Spacing(); 53 | ImGui::ProgressBar(m_fPercent); 54 | } 55 | -------------------------------------------------------------------------------- /src/Core/Subsystem/DebugGUI/Window.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::DebugGUI; 14 | 15 | Window::Window(const char* name, const char* title, DebugWindowFlags flags) 16 | : m_stName(name), m_stTitle(title), m_uFlags(flags) 17 | { 18 | } 19 | 20 | void Window::Update(double elapsedTime) noexcept 21 | { 22 | OnUpdate(elapsedTime); 23 | } 24 | 25 | void Window::Render() noexcept 26 | { 27 | if (!m_bVisible) 28 | return; 29 | 30 | OnPrepareWindow(); 31 | 32 | if (!ImGui::Begin(m_stTitle.c_str(), &m_bVisible, static_cast(m_uFlags))) 33 | { 34 | ImGui::End(); 35 | return; 36 | } 37 | OnRender(); 38 | ImGui::End(); 39 | } 40 | 41 | void Window::OnPrepareWindow() noexcept 42 | { 43 | } 44 | 45 | void Window::OnUpdate(double elapsedTime) noexcept 46 | { 47 | static_cast(elapsedTime); 48 | } 49 | 50 | void Window::OnRender() noexcept 51 | { 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Subsystem/EventBusSystem.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/6/7 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem; 14 | 15 | LSTG_DEF_LOG_CATEGORY(EventBusSystem); 16 | 17 | EventBusSystem::EventBusSystem(SubsystemContainer& container) 18 | { 19 | } 20 | 21 | Result EventBusSystem::EmitEvent(SubsystemEvent event) noexcept 22 | { 23 | try 24 | { 25 | m_stEventQueue.push_back(std::move(event)); 26 | return {}; 27 | } 28 | catch (...) 29 | { 30 | LSTG_LOG_ERROR_CAT(EventBusSystem, "Push event fail, out of memory"); 31 | return make_error_code(std::errc::not_enough_memory); 32 | } 33 | } 34 | 35 | std::optional EventBusSystem::PollEvent() noexcept 36 | { 37 | if (m_stEventQueue.empty()) 38 | return {}; 39 | auto front = std::move(m_stEventQueue.front()); 40 | m_stEventQueue.pop_front(); 41 | return front; 42 | } 43 | -------------------------------------------------------------------------------- /src/Core/Subsystem/ISubsystem.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/6 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem; 12 | 13 | void ISubsystem::OnUpdate(double elapsedTime) noexcept 14 | { 15 | static_cast(elapsedTime); 16 | } 17 | 18 | void ISubsystem::OnBeforeRender(double elapsedTime) noexcept 19 | { 20 | static_cast(elapsedTime); 21 | } 22 | 23 | void ISubsystem::OnAfterRender(double elapsedTime) noexcept 24 | { 25 | static_cast(elapsedTime); 26 | } 27 | 28 | void ISubsystem::OnEvent(SubsystemEvent& event) noexcept 29 | { 30 | static_cast(event); 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Camera.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace lstg; 14 | using namespace lstg::Subsystem::Render; 15 | 16 | // 17 | 18 | Camera::Camera() 19 | : m_stViewMatrix(glm::identity()), m_stProjectMatrix(glm::identity()), 20 | m_stProjectViewMatrix(glm::identity()) 21 | { 22 | } 23 | 24 | void Camera::SetViewMatrix(const glm::mat4x4& mat) noexcept 25 | { 26 | m_stViewMatrix = mat; 27 | m_stProjectViewMatrix.reset(); 28 | m_bStateDirty = true; 29 | } 30 | 31 | void Camera::SetProjectMatrix(const glm::mat4x4& mat) noexcept 32 | { 33 | m_stProjectMatrix = mat; 34 | m_stProjectViewMatrix.reset(); 35 | m_bStateDirty = true; 36 | } 37 | 38 | const glm::mat4x4& Camera::GetProjectViewMatrix() const noexcept 39 | { 40 | if (!m_stProjectViewMatrix) 41 | m_stProjectViewMatrix = m_stProjectMatrix * m_stViewMatrix; 42 | return *m_stProjectViewMatrix; 43 | } 44 | 45 | void Camera::SetViewport(Viewport vp) noexcept 46 | { 47 | m_stViewport = vp; 48 | m_bStateDirty = true; 49 | } 50 | 51 | void Camera::SetOutputViews(const OutputViews& views) noexcept 52 | { 53 | m_stOutputViews = views; 54 | m_bStateDirty = true; 55 | } 56 | 57 | // 58 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Drawing2D/Particle.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/7 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::Drawing2D; 12 | 13 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Drawing2D/Texture2D.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::Render::Drawing2D; 14 | 15 | using namespace lstg::Subsystem::Render; 16 | 17 | const TexturePtr& Texture2D::GetUnderlayTexture() const noexcept 18 | { 19 | return m_pTexture; 20 | } 21 | 22 | void Texture2D::SetUnderlayTexture(TexturePtr tex) noexcept 23 | { 24 | m_pTexture = std::move(tex); 25 | } 26 | 27 | float Texture2D::GetPixelPerUnit() const noexcept 28 | { 29 | return m_fPPU; 30 | } 31 | 32 | void Texture2D::SetPixelPerUnit(float ppu) noexcept 33 | { 34 | m_fPPU = ppu; 35 | } 36 | 37 | float Texture2D::GetWidth() const noexcept 38 | { 39 | float width = m_pTexture ? static_cast(m_pTexture->GetWidth()) : RenderSystem::GetDefaultTexture2DSize().x; 40 | return width / m_fPPU; 41 | } 42 | 43 | float Texture2D::GetHeight() const noexcept 44 | { 45 | float height = m_pTexture ? static_cast(m_pTexture->GetHeight()) : RenderSystem::GetDefaultTexture2DSize().y; 46 | return height / m_fPPU; 47 | } 48 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/FreeTypeFontFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "detail/FreeTypeObject.hpp" 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::Font 12 | { 13 | /** 14 | * FreeType 字体工厂 15 | */ 16 | class FreeTypeFontFactory : 17 | public IFontFactory 18 | { 19 | public: 20 | FreeTypeFontFactory(); 21 | 22 | public: // IFontFactory 23 | Result CreateFontFace(VFS::StreamPtr stream, IFontDependencyLoader* dependencyLoader, int faceIndex) noexcept override; 24 | Result EnumFontFace(std::vector& out, VFS::StreamPtr stream) noexcept override; 25 | 26 | private: 27 | detail::FreeTypeObject::LibraryPtr m_pLibrary; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/HgeFontFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/3 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::Font 11 | { 12 | /** 13 | * HGE 纹理化字体工厂 14 | */ 15 | class HgeFontFactory : 16 | public IFontFactory 17 | { 18 | public: // IFontFactory 19 | Result CreateFontFace(VFS::StreamPtr stream, IFontDependencyLoader* dependencyLoader, int faceIndex) noexcept override; 20 | Result EnumFontFace(std::vector& out, VFS::StreamPtr stream) noexcept override; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/IFontFactory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/30 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include "FreeTypeFontFactory.hpp" 10 | #include "HgeFontFactory.hpp" 11 | 12 | using namespace std; 13 | using namespace lstg; 14 | using namespace lstg::Subsystem::Render::Font; 15 | 16 | FontFactoryPtr lstg::Subsystem::Render::Font::CreateFreeTypeFactory() 17 | { 18 | return static_pointer_cast(make_shared()); 19 | } 20 | 21 | FontFactoryPtr lstg::Subsystem::Render::Font::CreateHgeFontFactory() 22 | { 23 | return static_pointer_cast(make_shared()); 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/ITextShaper.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/30 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include "HarfBuzzTextShaper.hpp" 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::Render::Font; 14 | 15 | TextShaperPtr lstg::Subsystem::Render::Font::CreateHarfBuzzTextShaper() 16 | { 17 | return static_pointer_cast(make_shared()); 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/CommonDefines.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::Font::detail 12 | { 13 | /** 14 | * 渲染DPI 15 | */ 16 | static const int32_t kFontRenderDPI = 72; 17 | 18 | /** 19 | * 无效字符代换码点 20 | */ 21 | static const char32_t kInvalidCharCodePoint = U'\uFFFD'; 22 | 23 | /** 24 | * 不同字体大小缓存个数 25 | */ 26 | static const size_t kFontSizeCacheSize = 16; 27 | 28 | /** 29 | * 字形数据缓存个数 30 | */ 31 | static const size_t kGlyphCacheCount = 1024; 32 | 33 | /** 34 | * Kerning 数据缓存个数 35 | */ 36 | static const size_t kKerningCacheCount = 1024; 37 | 38 | /** 39 | * 前进量数据缓存个数 40 | */ 41 | static const size_t kAdvanceCacheCount = 1024; 42 | } 43 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/FreeTypeError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "FreeTypeError.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::Font::detail; 12 | 13 | const FreeTypeErrorCategory& FreeTypeErrorCategory::GetInstance() noexcept 14 | { 15 | static const FreeTypeErrorCategory kInstance; 16 | return kInstance; 17 | } 18 | 19 | const char* FreeTypeErrorCategory::name() const noexcept 20 | { 21 | return "FreeTypeError"; 22 | } 23 | 24 | std::string FreeTypeErrorCategory::message(int ev) const 25 | { 26 | auto p = ::FT_Error_String(static_cast(ev)); 27 | return p ? p : ""; 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/FreeTypeError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::Font::detail 12 | { 13 | // 见 FT_Error 14 | enum class FreeTypeError : int32_t {}; 15 | 16 | /** 17 | * FreeType 错误代码分类 18 | */ 19 | class FreeTypeErrorCategory : 20 | public std::error_category 21 | { 22 | public: 23 | static const FreeTypeErrorCategory& GetInstance() noexcept; 24 | 25 | public: 26 | const char* name() const noexcept override; 27 | std::string message(int ev) const override; 28 | }; 29 | 30 | inline std::error_code make_error_code(FreeTypeError ec) noexcept 31 | { 32 | return { static_cast(ec), lstg::Subsystem::Render::Font::detail::FreeTypeErrorCategory::GetInstance() }; 33 | } 34 | } 35 | 36 | template <> 37 | struct std::is_error_code_enum : std::true_type {}; 38 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/FreeTypeStream.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::Font::detail 12 | { 13 | /** 14 | * FreeType 流 15 | */ 16 | struct FreeTypeStream : 17 | public FT_StreamRec 18 | { 19 | static unsigned long OnRead(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) noexcept; 20 | static void OnClose(FT_Stream stream) noexcept; 21 | 22 | VFS::StreamPtr Stream; 23 | 24 | FreeTypeStream(VFS::StreamPtr s); 25 | void RefreshPosition() noexcept; 26 | }; 27 | 28 | using FreeTypeStreamPtr = std::unique_ptr; 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/HarfBuzzBridge.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::Font::detail 12 | { 13 | /** 14 | * HarfBuzz 封装 15 | */ 16 | class HarfBuzzBridge 17 | { 18 | public: 19 | /** 20 | * HarfBuzz 对象删除器 21 | * @tparam T 22 | * @tparam TDeleter 23 | */ 24 | template 25 | struct ObjectDeleter 26 | { 27 | void operator()(T* face) 28 | { 29 | TDeleter(face); 30 | } 31 | }; 32 | 33 | using BufferPtr = std::unique_ptr<::hb_buffer_t, ObjectDeleter<::hb_buffer_t, ::hb_buffer_destroy>>; 34 | using FacePtr = std::unique_ptr<::hb_face_t, ObjectDeleter<::hb_face_t, ::hb_face_destroy>>; 35 | using FontPtr = std::unique_ptr<::hb_font_t, ObjectDeleter<::hb_font_t, ::hb_font_destroy>>; 36 | using FontFuncsPtr = std::unique_ptr<::hb_font_funcs_t, ObjectDeleter<::hb_font_funcs_t, ::hb_font_funcs_destroy>>; 37 | 38 | /** 39 | * 创建 HarfBuzz 缓冲区 40 | */ 41 | static Result CreateBuffer() noexcept; 42 | 43 | /** 44 | * 创建 HarfBuzz 字体面 45 | * @param face 字体 46 | */ 47 | static Result CreateFace(FontFacePtr face) noexcept; 48 | 49 | /** 50 | * 创建 HarfBuzz 字体 51 | * @param face 字体 52 | * @param param 光栅化参数 53 | */ 54 | static Result CreateFont(FacePtr face, FontGlyphRasterParam param) noexcept; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/Helper.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "Helper.hpp" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::Render::Font::detail; 14 | 15 | constexpr const uint16_t kHighSurrogateStart = 0xD800u; 16 | constexpr const uint16_t kHighSurrogateEnd = 0xDBFFu; 17 | constexpr const uint16_t kLowSurrogateStart = 0xDC00u; 18 | constexpr const uint16_t kLowSurrogateEnd = 0xDFFFu; 19 | 20 | bool Helper::IsHighSurrogate(uint32_t codePoint) noexcept 21 | { 22 | return codePoint >= kHighSurrogateStart && codePoint <= kHighSurrogateEnd; 23 | } 24 | 25 | bool Helper::IsLowSurrogate(uint32_t codePoint) noexcept 26 | { 27 | return codePoint >= kLowSurrogateStart && codePoint <= kLowSurrogateEnd; 28 | } 29 | 30 | uint32_t Helper::EncodeSurrogate(uint16_t highSurrogate, uint16_t lowSurrogate) noexcept 31 | { 32 | return ((highSurrogate - kHighSurrogateStart) << 10) + (lowSurrogate - kLowSurrogateStart) + 0x10000; 33 | } 34 | 35 | bool Helper::IsRenderAsWhitespace(char32_t codePoint) noexcept 36 | { 37 | return u_isWhitespace(codePoint) || 38 | codePoint == U'\u200B' || // Zero Width Space 39 | codePoint == U'\u2009' || // Thin Space 40 | codePoint == U'\u202F'; // Narrow No-break Space 41 | } 42 | 43 | bool Helper::IsControlCharacter(char32_t codePoint) noexcept 44 | { 45 | return u_isISOControl(codePoint); 46 | } 47 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/Helper.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::Font::detail 11 | { 12 | /** 13 | * 辅助类 14 | */ 15 | class Helper 16 | { 17 | public: 18 | /** 19 | * 是否是 UTF-16 代理对的高半区 20 | * @param codePoint 码点 21 | */ 22 | static bool IsHighSurrogate(uint32_t codePoint) noexcept; 23 | 24 | /** 25 | * 是否是 UTF-16 代理对的低半区 26 | * @param codePoint 码点 27 | */ 28 | static bool IsLowSurrogate(uint32_t codePoint) noexcept; 29 | 30 | /** 31 | * 编码 UTF-16 代理对到 UTF-32 32 | * @param highSurrogate 高半区 33 | * @param lowSurrogate 低半区 34 | */ 35 | static uint32_t EncodeSurrogate(uint16_t highSurrogate, uint16_t lowSurrogate) noexcept; 36 | 37 | /** 38 | * 是否渲染为空白符 39 | * @param codePoint 码点 40 | */ 41 | static bool IsRenderAsWhitespace(char32_t codePoint) noexcept; 42 | 43 | /** 44 | * 是否是控制字符 45 | * @param codePoint 码点 46 | */ 47 | static bool IsControlCharacter(char32_t codePoint) noexcept; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/HgeFontLoadError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "HgeFontLoadError.hpp" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Subsystem::Render::Font::detail; 14 | 15 | const HgeFontLoadErrorCategory& HgeFontLoadErrorCategory::GetInstance() noexcept 16 | { 17 | static HgeFontLoadErrorCategory kInstance; 18 | return kInstance; 19 | } 20 | 21 | const char* HgeFontLoadErrorCategory::name() const noexcept 22 | { 23 | return "HgeFontLoadError"; 24 | } 25 | 26 | std::string HgeFontLoadErrorCategory::message(int ev) const 27 | { 28 | switch (static_cast(ev)) 29 | { 30 | case HgeFontLoadError::Ok: 31 | return "ok"; 32 | case HgeFontLoadError::DuplicatedFontSection: 33 | return "duplicated font section"; 34 | case HgeFontLoadError::DuplicatedBitmap: 35 | return "duplicated bitmap"; 36 | case HgeFontLoadError::UnexpectedCharacter: 37 | return "unexpected character"; 38 | case HgeFontLoadError::Utf8DecodeError: 39 | return "unicode decoding error"; 40 | case HgeFontLoadError::InvalidValue: 41 | return "invalid value"; 42 | case HgeFontLoadError::MissingBitmap: 43 | return "missing bitmap"; 44 | default: 45 | assert(false); 46 | return ""; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/Font/detail/HgeFontLoadError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::Font::detail 11 | { 12 | /** 13 | * HGE 字体加载错误 14 | */ 15 | enum class HgeFontLoadError 16 | { 17 | Ok = 0, 18 | DuplicatedFontSection = 1, 19 | DuplicatedBitmap = 2, 20 | UnexpectedCharacter = 3, 21 | Utf8DecodeError = 4, 22 | InvalidValue = 5, 23 | MissingBitmap = 6, 24 | }; 25 | 26 | /** 27 | * HGE 字体加载错误代码分类 28 | */ 29 | class HgeFontLoadErrorCategory : public std::error_category 30 | { 31 | public: 32 | static const HgeFontLoadErrorCategory& GetInstance() noexcept; 33 | 34 | public: 35 | const char* name() const noexcept override; 36 | std::string message(int ev) const override; 37 | }; 38 | 39 | inline std::error_code make_error_code(HgeFontLoadError ec) noexcept 40 | { 41 | return { static_cast(ec), HgeFontLoadErrorCategory::GetInstance() }; 42 | } 43 | } 44 | 45 | template <> 46 | struct std::is_error_code_enum : std::true_type {}; 47 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/GraphDef/DefinitionError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/24 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::GraphDef; 12 | 13 | const DefinitionErrorCategory& DefinitionErrorCategory::GetInstance() noexcept 14 | { 15 | static const DefinitionErrorCategory kInstance; 16 | return kInstance; 17 | } 18 | 19 | const char* DefinitionErrorCategory::name() const noexcept 20 | { 21 | return "DefinitionError"; 22 | } 23 | 24 | std::string DefinitionErrorCategory::message(int ev) const 25 | { 26 | switch (static_cast(ev)) 27 | { 28 | case DefinitionError::Ok: 29 | return "ok"; 30 | case DefinitionError::InvalidIdentifier: 31 | return "invalid identifier"; 32 | case DefinitionError::SymbolAlreadyDefined: 33 | return "symbol already defined"; 34 | case DefinitionError::SlotAlreadyDefined: 35 | return "slot already defined"; 36 | case DefinitionError::SymbolNotFound: 37 | return "symbol not found"; 38 | case DefinitionError::SymbolTypeMismatched: 39 | return "symbol type mismatched"; 40 | case DefinitionError::ShaderCompileError: 41 | return "fail to compile shader"; 42 | case DefinitionError::CreatePRSError: 43 | return "fail to create PRS"; 44 | case DefinitionError::CreateSRBError: 45 | return "fail to create SRB"; 46 | default: 47 | return ""; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/GraphDef/detail/NameCheck.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/4/5 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::GraphDef::detail 11 | { 12 | /** 13 | * 是否是有效的标识符 14 | * @param name 名字 15 | * @return 是否有效 16 | */ 17 | inline bool IsValidIdentifier(std::string_view name) noexcept 18 | { 19 | enum { 20 | STATE_IDENTIFIER_START, 21 | STATE_IDENTIFIER, 22 | } state = STATE_IDENTIFIER_START; 23 | 24 | for (size_t i = 0; i <= name.size(); ++i) 25 | { 26 | char ch = (i >= name.size()) ? '\0' : name[i]; 27 | switch (state) 28 | { 29 | case STATE_IDENTIFIER_START: 30 | if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ch == '_') 31 | state = STATE_IDENTIFIER; 32 | else 33 | return false; 34 | break; 35 | case STATE_IDENTIFIER: 36 | if (ch == '\0') 37 | break; 38 | if (!(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_')) 39 | return false; 40 | break; 41 | } 42 | } 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/ClearHelper.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/1 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace lstg::Subsystem::Render::detail 15 | { 16 | LSTG_DEFINE_EXCEPTION(ClearHelperInitializeFailedException); 17 | 18 | /** 19 | * 用于实现 Viewport 内的 Clear 操作 20 | */ 21 | class ClearHelper 22 | { 23 | public: 24 | ClearHelper(RenderDevice* device); 25 | 26 | public: 27 | /** 28 | * 仅清除颜色 29 | * @param color 颜色 30 | */ 31 | void ClearColor(ColorRGBA32 color) noexcept; 32 | 33 | /** 34 | * 仅清除深度信息 35 | * @param depth 深度 36 | */ 37 | void ClearDepth(float depth) noexcept; 38 | 39 | /** 40 | * 清除颜色和深度 41 | * @param color 颜色 42 | * @param depth 深度 43 | */ 44 | void ClearDepthColor(ColorRGBA32 color, float depth) noexcept; 45 | 46 | private: 47 | RenderDevice* m_pDevice = nullptr; 48 | 49 | Diligent::RefCntAutoPtr m_pColorDepthClearPSO; // 清理颜色+深度信息 50 | Diligent::RefCntAutoPtr m_pColorOnlyClearPSO; // 只清理颜色信息 51 | Diligent::RefCntAutoPtr m_pDepthOnlyClearPSO; // 只清理深度信息 52 | Diligent::RefCntAutoPtr m_pVertexBuffer; 53 | Diligent::RefCntAutoPtr m_pIndexBuffer; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/DiligentFileStream.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/4/7 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace lstg::Subsystem::Render::detail 14 | { 15 | /** 16 | * Diligent FileStream -> IStream 桥接 17 | */ 18 | class DiligentFileStream : 19 | public Diligent::ObjectBase 20 | { 21 | public: 22 | static Diligent::RefCntAutoPtr Create(Subsystem::VFS::StreamPtr stream); 23 | 24 | public: 25 | DiligentFileStream(Diligent::IReferenceCounters* refCounters, Subsystem::VFS::StreamPtr stream); 26 | 27 | public: 28 | void DILIGENT_CALL_TYPE QueryInterface(const Diligent::INTERFACE_ID& iid, IObject** interface) override; 29 | bool DILIGENT_CALL_TYPE Read(void* data, size_t bufferSize) override; 30 | void DILIGENT_CALL_TYPE ReadBlob(Diligent::IDataBlob* data) override; 31 | bool DILIGENT_CALL_TYPE Write(const void* data, size_t size) override; 32 | size_t DILIGENT_CALL_TYPE GetSize() override; 33 | bool DILIGENT_CALL_TYPE IsValid() override; 34 | 35 | private: 36 | Subsystem::VFS::StreamPtr m_pStream; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/DiligentShaderSourceInputStreamFactory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/4/7 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include "DiligentFileStream.hpp" 11 | 12 | namespace lstg::Subsystem::Render::detail 13 | { 14 | /** 15 | * Diligent::ShaderSourceInputStreamFactory 实现 16 | */ 17 | class DiligentShaderSourceInputStreamFactory : 18 | public Diligent::ObjectBase 19 | { 20 | public: 21 | static Diligent::RefCntAutoPtr Create(Subsystem::VirtualFileSystem& vfs); 22 | 23 | public: 24 | DiligentShaderSourceInputStreamFactory(Diligent::IReferenceCounters* refCounters, Subsystem::VirtualFileSystem& vfs); 25 | 26 | public: 27 | /** 28 | * 设置包含文件搜索基准路径 29 | */ 30 | void SetFileSearchBase(std::string_view base) { m_stFileSearchBase = base; } 31 | 32 | public: // Diligent::IShaderSourceInputStreamFactory 33 | void DILIGENT_CALL_TYPE QueryInterface(const Diligent::INTERFACE_ID& iid, IObject** interface) override; 34 | void DILIGENT_CALL_TYPE CreateInputStream(const char* name, Diligent::IFileStream** stream) override; 35 | void DILIGENT_CALL_TYPE CreateInputStream2(const char* name, Diligent::CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS flags, 36 | Diligent::IFileStream** stream) override; 37 | 38 | private: 39 | Subsystem::VirtualFileSystem& m_stFileSystem; 40 | std::string m_stFileSearchBase; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/EffectBuilder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/19 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "EffectBuilder.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::detail::LuaEffectBuilder; 12 | 13 | using AbsIndex = Subsystem::Script::LuaStack::AbsIndex; 14 | 15 | AbsIndex EffectBuilder::AddPassGroup(Script::LuaStack& stack, EffectPassGroupWrapper* wrapper) 16 | { 17 | assert(wrapper); 18 | auto ret = m_stDefinition.AddGroup(wrapper->Get()); 19 | stack.ThrowIfError(ret); 20 | LSTG_SCRIPT_RETURN_SELF; 21 | } 22 | 23 | EffectWrapper EffectBuilder::Build(Script::LuaStack& stack) 24 | { 25 | if (m_stDefinition.GetGroups().empty()) 26 | stack.Error("At least one pass group must be defined"); 27 | return { make_shared(m_stDefinition) }; 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/EffectBuilder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "Helper.hpp" 9 | #include 10 | #include "EffectPassGroupBuilder.hpp" 11 | 12 | namespace lstg::Subsystem::Render::detail::LuaEffectBuilder 13 | { 14 | /** 15 | * Effect 包装类 16 | */ 17 | LSTG_CLASS() 18 | using EffectWrapper = ScriptObjectWrapper; 19 | 20 | /** 21 | * Effect 构造器 22 | */ 23 | LSTG_CLASS() 24 | class EffectBuilder 25 | { 26 | public: 27 | EffectBuilder() = default; 28 | 29 | public: 30 | LSTG_METHOD(passGroup) 31 | Script::LuaStack::AbsIndex AddPassGroup(Script::LuaStack& stack, EffectPassGroupWrapper* group); 32 | 33 | LSTG_METHOD(build) 34 | EffectWrapper Build(Script::LuaStack& stack); 35 | 36 | private: 37 | GraphDef::EffectDefinition m_stDefinition; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/EffectPassGroupBuilder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/19 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "EffectPassGroupBuilder.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::detail::LuaEffectBuilder; 12 | 13 | using AbsIndex = Subsystem::Script::LuaStack::AbsIndex; 14 | 15 | EffectPassGroupBuilder::EffectPassGroupBuilder(std::string_view name) 16 | { 17 | m_stDefinition.SetName(string{name}); 18 | } 19 | 20 | AbsIndex EffectPassGroupBuilder::SetTag(std::string_view key, std::string_view value) 21 | { 22 | m_stDefinition.SetTag(key, value); 23 | LSTG_SCRIPT_RETURN_SELF; 24 | } 25 | 26 | AbsIndex EffectPassGroupBuilder::AddPass(Script::LuaStack& stack, EffectPassWrapper* wrapper) 27 | { 28 | assert(wrapper); 29 | auto ret = m_stDefinition.AddPass(wrapper->Get()); 30 | stack.ThrowIfError(ret); 31 | LSTG_SCRIPT_RETURN_SELF; 32 | } 33 | 34 | EffectPassGroupWrapper EffectPassGroupBuilder::Build(Script::LuaStack& stack) 35 | { 36 | if (m_stDefinition.GetPasses().empty()) 37 | stack.Error("At least one pass must be defined"); 38 | return { make_shared(m_stDefinition) }; 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/EffectPassGroupBuilder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/19 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "Helper.hpp" 9 | #include 10 | #include "EffectPassBuilder.hpp" 11 | 12 | namespace lstg::Subsystem::Render::detail::LuaEffectBuilder 13 | { 14 | /** 15 | * EffectPassGroup 包装类 16 | */ 17 | LSTG_CLASS() 18 | using EffectPassGroupWrapper = ScriptObjectWrapper; 19 | 20 | /** 21 | * EffectPassGroup 构造器 22 | */ 23 | LSTG_CLASS() 24 | class EffectPassGroupBuilder 25 | { 26 | public: 27 | EffectPassGroupBuilder(std::string_view name); 28 | 29 | public: 30 | LSTG_METHOD(tag) 31 | Script::LuaStack::AbsIndex SetTag(std::string_view key, std::string_view value); 32 | 33 | LSTG_METHOD(pass) 34 | Script::LuaStack::AbsIndex AddPass(Script::LuaStack& stack, EffectPassWrapper* wrapper); 35 | 36 | LSTG_METHOD(build) 37 | EffectPassGroupWrapper Build(Script::LuaStack& stack); 38 | 39 | private: 40 | GraphDef::EffectPassGroupDefinition m_stDefinition; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/ShaderBuilder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "Helper.hpp" 9 | #include 10 | #include "ConstantBufferBuilder.hpp" 11 | #include "TextureVariableBuilder.hpp" 12 | #include "VertexLayoutBuilder.hpp" 13 | 14 | namespace lstg::Subsystem::Render::detail::LuaEffectBuilder 15 | { 16 | /** 17 | * Shader 包装类 18 | */ 19 | LSTG_CLASS() 20 | using ShaderWrapper = ScriptObjectWrapper; 21 | 22 | /** 23 | * Shader 构造器 24 | */ 25 | LSTG_CLASS() 26 | class ShaderBuilder 27 | { 28 | public: 29 | ShaderBuilder(GraphDef::ShaderDefinition::ShaderTypes t); 30 | 31 | GraphDef::ShaderDefinition& operator*() noexcept { return m_stDefinition; } 32 | 33 | public: 34 | LSTG_METHOD(name) 35 | Script::LuaStack::AbsIndex SetName(const char* name); 36 | 37 | LSTG_METHOD(entry) 38 | Script::LuaStack::AbsIndex SetEntry(const char* name); 39 | 40 | LSTG_METHOD(use) 41 | Script::LuaStack::AbsIndex Use(Script::LuaStack& stack, std::variant resource); 42 | 43 | LSTG_METHOD(vertexLayout) 44 | Script::LuaStack::AbsIndex SetVertexLayout(Script::LuaStack& stack, VertexLayoutWrapper* vertexLayout); 45 | 46 | LSTG_METHOD(build) 47 | ShaderWrapper Build(Script::LuaStack& stack); 48 | 49 | private: 50 | GraphDef::ShaderDefinition m_stDefinition; 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/VertexLayoutBuilder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "VertexLayoutBuilder.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Render::detail::LuaEffectBuilder; 12 | 13 | using AbsIndex = Subsystem::Script::LuaStack::AbsIndex; 14 | 15 | AbsIndex VertexLayoutBuilder::AddSlot(Script::LuaStack& stack, uint32_t index, 16 | GraphDef::ShaderVertexLayoutDefinition::ElementSemanticNames name, uint8_t semanticId, std::optional normalized) 17 | { 18 | auto ret = m_stDefinition.AddSlot(index, {name, semanticId}, normalized ? *normalized : true); 19 | stack.ThrowIfError(ret); 20 | LSTG_SCRIPT_RETURN_SELF; 21 | } 22 | 23 | VertexLayoutWrapper VertexLayoutBuilder::Build() 24 | { 25 | return { make_shared(m_stDefinition) }; 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/LuaEffectBuilder/VertexLayoutBuilder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include "Helper.hpp" 9 | #include 10 | 11 | namespace lstg::Subsystem::Render::detail::LuaEffectBuilder 12 | { 13 | /** 14 | * ConstantBuffer 包装器 15 | */ 16 | LSTG_CLASS() 17 | using VertexLayoutWrapper = ScriptObjectWrapper; 18 | 19 | /** 20 | * VertexLayout 构造器 21 | */ 22 | LSTG_CLASS() 23 | class VertexLayoutBuilder 24 | { 25 | public: 26 | VertexLayoutBuilder() = default; 27 | 28 | public: 29 | LSTG_METHOD(slot) 30 | Script::LuaStack::AbsIndex AddSlot(Script::LuaStack& stack, uint32_t index, 31 | GraphDef::ShaderVertexLayoutDefinition::ElementSemanticNames name, uint8_t semanticId, std::optional normalized); 32 | 33 | LSTG_METHOD(build) 34 | VertexLayoutWrapper Build(); 35 | 36 | private: 37 | GraphDef::ShaderVertexLayoutDefinition m_stDefinition; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/Emscripten/GLView.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/10 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | 9 | namespace lstg::Subsystem::Render::detail::RenderDevice::Emscripten 10 | { 11 | /** 12 | * Emscripten 下 WebGL 视图 13 | * 用于创建 GLContext 14 | */ 15 | class GLView 16 | { 17 | public: 18 | GLView(const char* canvasId); 19 | ~GLView(); 20 | 21 | public: 22 | const char* GetView() const noexcept { return m_pCanvasId; } 23 | void Present() noexcept; 24 | 25 | private: 26 | const char* m_pCanvasId; 27 | int m_hContextHandle = 0; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/Linux/GLContext.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/8/20 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Render::detail::RenderDevice::Linux 11 | { 12 | /** 13 | * GL 上下文 14 | */ 15 | class GLContext 16 | { 17 | public: 18 | GLContext(/* _XDisplay */void* display, uint32_t windowId); 19 | ~GLContext(); 20 | 21 | private: 22 | void* m_pDisplay = nullptr; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/OSX/GLView.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | 9 | #ifdef __OBJC__ 10 | @class NSView; 11 | @class NSWindow; 12 | @class NSOpenGLView; 13 | @class NSOpenGLContext; 14 | #else 15 | typedef struct _NSView NSView; 16 | typedef struct _NSWindow NSWindow; 17 | typedef struct _NSOpenGLView NSOpenGLView; 18 | typedef struct _NSOpenGLContext NSOpenGLContext; 19 | #endif 20 | 21 | namespace lstg::Subsystem::Render::detail::RenderDevice::OSX 22 | { 23 | /** 24 | * GL 视图 25 | */ 26 | class GLView 27 | { 28 | public: 29 | GLView(/* NSWindow* */ void* nsWindow, bool highDpi); 30 | ~GLView(); 31 | 32 | public: 33 | [[nodiscard]] NSOpenGLView* GetView() const noexcept { return m_pGLView; } 34 | void Present() const noexcept; 35 | 36 | private: 37 | NSOpenGLView* m_pGLView = nullptr; 38 | NSOpenGLContext* m_pGLContext = nullptr; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/OSX/MetalView.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | 9 | #ifdef __OBJC__ 10 | @class NSView; 11 | @class NSWindow; 12 | @class CAMetalLayer; 13 | #else 14 | typedef struct _NSView NSView; 15 | typedef struct _NSWindow NSWindow; 16 | typedef struct _CAMetalLayer CAMetalLayer; 17 | #endif 18 | 19 | namespace lstg::Subsystem::Render::detail::RenderDevice::OSX 20 | { 21 | /** 22 | * GL 视图 23 | */ 24 | class MetalView 25 | { 26 | public: 27 | MetalView(/* NSWindow* */ void* nsWindow, bool highDpi); 28 | ~MetalView(); 29 | 30 | public: 31 | [[nodiscard]] NSView* GetView() const noexcept { return m_pMetalView; } 32 | [[nodiscard]] CAMetalLayer* GetLayer() const noexcept { return m_pMetalLayer; } 33 | 34 | private: 35 | NSView* m_pMetalView = nullptr; // 仅持有指针 36 | CAMetalLayer* m_pMetalLayer = nullptr; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/RenderDeviceD3D11.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/6 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace lstg::Subsystem::Render::detail::RenderDevice 16 | { 17 | /** 18 | * D3D11 渲染设备 19 | */ 20 | class RenderDeviceD3D11 : 21 | public Render::RenderDevice 22 | { 23 | public: 24 | RenderDeviceD3D11(WindowSystem* window); 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/RenderDeviceD3D12.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/6 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace lstg::Subsystem::Render::detail::RenderDevice 16 | { 17 | /** 18 | * D3D12 渲染设备 19 | */ 20 | class RenderDeviceD3D12 : 21 | public Render::RenderDevice 22 | { 23 | public: 24 | RenderDeviceD3D12(WindowSystem* window); 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/RenderDeviceGL.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/8 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "OSX/GLView.hpp" 15 | #include "Emscripten/GLView.hpp" 16 | #include "Linux/GLContext.hpp" 17 | 18 | namespace lstg::Subsystem::Render::detail::RenderDevice 19 | { 20 | /** 21 | * OpenGL 渲染设备 22 | */ 23 | class RenderDeviceGL : 24 | public Render::RenderDevice 25 | { 26 | public: 27 | RenderDeviceGL(WindowSystem* window); 28 | 29 | protected: // RenderDevice 30 | bool IsVerticalSyncEnabled() const noexcept override; 31 | void SetVerticalSyncEnabled(bool enable) noexcept override; 32 | void Present() noexcept override; 33 | 34 | private: 35 | #ifdef LSTG_PLATFORM_MACOS 36 | std::unique_ptr m_stView; 37 | #endif 38 | #ifdef LSTG_PLATFORM_EMSCRIPTEN 39 | std::unique_ptr m_stView; 40 | #endif 41 | #ifdef LSTG_PLATFORM_LINUX 42 | std::unique_ptr m_stContext; 43 | #endif 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Render/detail/RenderDevice/RenderDeviceVulkan.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "OSX/MetalView.hpp" 15 | 16 | namespace lstg::Subsystem::Render::detail::RenderDevice 17 | { 18 | /** 19 | * Vulkan 渲染设备 20 | */ 21 | class RenderDeviceVulkan : 22 | public Render::RenderDevice 23 | { 24 | public: 25 | RenderDeviceVulkan(WindowSystem* window); 26 | ~RenderDeviceVulkan(); 27 | 28 | private: 29 | #ifdef LSTG_PLATFORM_MACOS 30 | // Diligent 使用 Metal 模拟 Vulkan,原生 Metal 支持需要商用许可 31 | std::unique_ptr m_stView; 32 | #endif 33 | #ifdef LSTG_PLATFORM_LINUX 34 | #ifdef LSTG_X11_ENABLE 35 | void* m_pXCBConnection = nullptr; 36 | #endif 37 | #endif 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Script/LuaStack.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/3/6 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::Script; 12 | 13 | int lstg::Subsystem::Script::detail::PCallErrorHandler(lua_State* L) 14 | { 15 | // see lua.c: traceback 16 | if (!lua_isstring(L, 1)) 17 | return 1; 18 | lua_getfield(L, LUA_GLOBALSINDEX, "debug"); 19 | if (!lua_istable(L, -1)) 20 | { 21 | lua_pop(L, 1); 22 | return 1; 23 | } 24 | lua_getfield(L, -1, "traceback"); 25 | if (!lua_isfunction(L, -1)) 26 | { 27 | lua_pop(L, 2); 28 | return 1; 29 | } 30 | lua_pushvalue(L, 1); 31 | lua_pushinteger(L, 2); 32 | lua_call(L, 2, 1); 33 | return 1; 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Subsystem/Script/detail/LuaCompatLayer.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::Script::detail 11 | { 12 | /** 13 | * Lua 兼容层 14 | */ 15 | class LuaCompatLayer 16 | { 17 | public: 18 | /** 19 | * 注册兼容层 20 | * @param state 状态机 21 | */ 22 | static void Register(LuaState& state); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/IStream.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/10 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace lstg; 14 | using namespace lstg::Subsystem::VFS; 15 | 16 | Result Subsystem::VFS::ConvertToSeekableStream(Subsystem::VFS::StreamPtr stream) noexcept 17 | { 18 | // 如果本身就是可以 Seek 的,就忽略 19 | if (stream->IsSeekable()) 20 | return stream; 21 | 22 | // 预分配 23 | Subsystem::VFS::MemoryStreamPtr ret; 24 | try 25 | { 26 | ret = make_shared(); 27 | auto length = stream->GetLength(); 28 | if (length) 29 | ret->Reserve(*length); 30 | } 31 | catch (...) 32 | { 33 | return make_error_code(errc::not_enough_memory); 34 | } 35 | 36 | // 从当前位置开始读取所有的内容 37 | const size_t kChunkSize = 16 * 1024; 38 | size_t readLength = 0; 39 | auto& container = ret->GetContainer(); 40 | while (true) 41 | { 42 | // 分配 kChunkSize 个数据 43 | try 44 | { 45 | container.resize(readLength + kChunkSize); 46 | } 47 | catch (...) 48 | { 49 | return make_error_code(errc::not_enough_memory); 50 | } 51 | 52 | // 读取数据 53 | auto cnt = stream->Read(container.data() + readLength, kChunkSize); 54 | if (!cnt) 55 | return cnt.GetError(); 56 | 57 | // 缩小实际大小 58 | if (*cnt) 59 | { 60 | readLength += *cnt; 61 | container.resize(readLength); 62 | } 63 | if (*cnt < kChunkSize) 64 | break; 65 | } 66 | return ret; 67 | } 68 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZLibError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "ZLibError.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::Subsystem::VFS::detail; 12 | 13 | const ZLibErrorCategory& ZLibErrorCategory::GetInstance() noexcept 14 | { 15 | static const ZLibErrorCategory kCategory; 16 | return kCategory; 17 | } 18 | 19 | const char* ZLibErrorCategory::name() const noexcept 20 | { 21 | return "ZLibError"; 22 | } 23 | 24 | std::string ZLibErrorCategory::message(int ev) const 25 | { 26 | switch (static_cast(ev)) 27 | { 28 | case ZLibError::Ok: 29 | return "ok"; 30 | case ZLibError::StreamEnd: 31 | return "end of stream reached"; 32 | case ZLibError::NeedDict: 33 | return "preset dictionary required"; 34 | case ZLibError::GeneralError: 35 | return "i/o error occur"; 36 | case ZLibError::StreamError: 37 | return "invalid stream or parameters"; 38 | case ZLibError::DataError: 39 | return "invalid data"; 40 | case ZLibError::MemoryError: 41 | return "no available memory"; 42 | case ZLibError::BufferError: 43 | return "additional buffers are required"; 44 | case ZLibError::VersionError: 45 | return "version mismatched"; 46 | default: 47 | return ""; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZLibError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::VFS::detail 11 | { 12 | /** 13 | * ZLIB 错误 14 | */ 15 | enum class ZLibError 16 | { 17 | Ok = 0, 18 | StreamEnd = 1, // Z_STREAM_END 19 | NeedDict = 2, // Z_NEED_DICT 20 | GeneralError = -1, // Z_ERRNO 21 | StreamError = -2, // Z_STREAM_ERROR 22 | DataError = -3, // Z_DATA_ERROR 23 | MemoryError = -4, // Z_MEM_ERROR 24 | BufferError = -5, // Z_BUF_ERROR 25 | VersionError = -6, // Z_VERSION_ERROR 26 | }; 27 | 28 | /** 29 | * ZLIB 错误分类 30 | */ 31 | class ZLibErrorCategory : 32 | public std::error_category 33 | { 34 | public: 35 | static const ZLibErrorCategory& GetInstance() noexcept; 36 | 37 | public: 38 | const char* name() const noexcept override; 39 | std::string message(int ev) const override; 40 | }; 41 | 42 | inline std::error_code make_error_code(ZLibError ec) noexcept 43 | { 44 | return { static_cast(ec), ZLibErrorCategory::GetInstance() }; 45 | } 46 | } 47 | 48 | namespace std 49 | { 50 | template <> 51 | struct is_error_code_enum : true_type {}; 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZStream.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "ZStream.hpp" 8 | 9 | #include 10 | #include 11 | #include "ZLibError.hpp" 12 | 13 | using namespace std; 14 | using namespace lstg; 15 | using namespace lstg::Subsystem::VFS::detail; 16 | 17 | ZStream::ZStream(DeflateInitTag, int compressionLevel) 18 | : m_bDeflateStream(true) 19 | { 20 | ::memset(&m_stZStream, 0, sizeof(m_stZStream)); 21 | auto ret = ::deflateInit(&m_stZStream, compressionLevel); 22 | if (ret != Z_OK) 23 | throw system_error(make_error_code(static_cast(ret))); 24 | } 25 | 26 | ZStream::ZStream(InflateInitTag, bool rawDeflateData) 27 | : m_bDeflateStream(false) 28 | { 29 | ::memset(&m_stZStream, 0, sizeof(m_stZStream)); 30 | auto ret = ::inflateInit2(&m_stZStream, rawDeflateData ? -MAX_WBITS : MAX_WBITS); 31 | if (ret != Z_OK) 32 | throw system_error(make_error_code(static_cast(ret))); 33 | } 34 | 35 | ZStream::ZStream(const ZStream& org) 36 | : m_bDeflateStream(org.m_bDeflateStream) 37 | { 38 | int ret; 39 | if (m_bDeflateStream) 40 | ret = ::deflateCopy(&m_stZStream, const_cast(&(org.m_stZStream))); 41 | else 42 | ret = ::inflateCopy(&m_stZStream, const_cast(&(org.m_stZStream))); 43 | if (ret != Z_OK) 44 | throw system_error(make_error_code(static_cast(ret))); 45 | } 46 | 47 | ZStream::~ZStream() 48 | { 49 | int ok = 0; 50 | if (m_bDeflateStream) 51 | ok = ::deflateEnd(&m_stZStream); 52 | else 53 | ok = ::inflateEnd(&m_stZStream); 54 | static_cast(ok); 55 | assert(ok == Z_OK); 56 | } 57 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZStream.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace lstg::Subsystem::VFS::detail 14 | { 15 | struct DeflateInitTag {}; 16 | struct InflateInitTag {}; 17 | 18 | class ZStream 19 | { 20 | public: 21 | ZStream(DeflateInitTag, int compressionLevel = Z_DEFAULT_COMPRESSION); 22 | ZStream(InflateInitTag, bool rawDeflateData = false); 23 | 24 | ZStream(const ZStream& org); 25 | ZStream(ZStream&&) = delete; 26 | ZStream& operator=(ZStream&&) = delete; 27 | 28 | ~ZStream(); 29 | 30 | public: 31 | const ::z_stream* operator*() const noexcept { return &m_stZStream; } 32 | ::z_stream* operator*() noexcept { return &m_stZStream; } 33 | 34 | const ::z_stream* operator->() const noexcept { return &m_stZStream; } 35 | ::z_stream* operator->() noexcept { return &m_stZStream; } 36 | 37 | private: 38 | bool m_bDeflateStream = false; 39 | ::z_stream m_stZStream{}; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZipFileReadError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/2/26 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::VFS::detail 11 | { 12 | /** 13 | * ZIP 读错误 14 | */ 15 | enum class ZipFileReadError 16 | { 17 | Ok = 0, 18 | EOCDNotFound, 19 | UnexpectedEndOfStream, 20 | BadEOCDSignature, 21 | BadEOCD64Signature, 22 | BadEOCD64LocatorSignature, 23 | BadEOCDSize, 24 | MultiDiskFormatNotSupported, 25 | CDOffsetTooBig, 26 | CDSizeTooBig, 27 | BadCDFileHeaderSignature, 28 | CDLocationInvalid, 29 | BadLocalFileHeaderSignature, 30 | DataDescriptorNotSupported, 31 | CompressedPatchedDataNotSupported, 32 | StrongEncryptionNotSupported, 33 | CentralDirectoryEncryptionNotSupported, 34 | CompressionMethodNotSupported, 35 | BadCDEntrySize, 36 | MissingZip64ExtraField, 37 | BadPassword, 38 | DuplicatedFile, 39 | }; 40 | 41 | /** 42 | * ZIP 读错误分类 43 | */ 44 | class ZipFileReadErrorCategory : 45 | public std::error_category 46 | { 47 | public: 48 | static const ZipFileReadErrorCategory& GetInstance() noexcept; 49 | 50 | public: 51 | const char* name() const noexcept override; 52 | std::string message(int ev) const override; 53 | }; 54 | 55 | inline std::error_code make_error_code(ZipFileReadError ec) noexcept 56 | { 57 | return { static_cast(ec), ZipFileReadErrorCategory::GetInstance() }; 58 | } 59 | } 60 | 61 | namespace std 62 | { 63 | template <> 64 | struct is_error_code_enum : true_type {}; 65 | } 66 | -------------------------------------------------------------------------------- /src/Core/Subsystem/VFS/detail/ZipPkDecryptStream.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/2/28 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::Subsystem::VFS::detail 11 | { 12 | class ZipPkDecryptStream : 13 | public IStream 14 | { 15 | public: 16 | ZipPkDecryptStream(StreamPtr underlayStream, std::string_view password, uint16_t verify); 17 | ZipPkDecryptStream(const ZipPkDecryptStream& org); 18 | 19 | public: // IStream 20 | bool IsReadable() const noexcept override; 21 | bool IsWriteable() const noexcept override; 22 | bool IsSeekable() const noexcept override; 23 | Result GetLength() const noexcept override; 24 | Result SetLength(uint64_t length) noexcept override; 25 | Result GetPosition() const noexcept override; 26 | Result Seek(int64_t offset, StreamSeekOrigins origin) noexcept override; 27 | Result IsEof() const noexcept override; 28 | Result Flush() noexcept override; 29 | Result Read(uint8_t* buffer, size_t length) noexcept override; 30 | Result Write(const uint8_t* buffer, size_t length) noexcept override; 31 | Result Clone() const noexcept override; 32 | 33 | private: 34 | void PkCryptUpdateKeys(uint8_t c) noexcept; 35 | uint8_t DecodeByte(uint8_t c) noexcept; 36 | 37 | private: 38 | StreamPtr m_pUnderlayStream; 39 | uint32_t m_uKeys[3] = {0, 0, 0}; 40 | uint8_t m_uVerify1 = 0; 41 | uint8_t m_uVerify2 = 0; 42 | uint64_t m_uReadCount = 0; 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/Core/Text/IniParsingError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/9 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::Text; 14 | 15 | const IniParsingErrorCategory& IniParsingErrorCategory::GetInstance() noexcept 16 | { 17 | static IniParsingErrorCategory kInstance; 18 | return kInstance; 19 | } 20 | 21 | const char* IniParsingErrorCategory::name() const noexcept 22 | { 23 | return "IniParsingError"; 24 | } 25 | 26 | std::string IniParsingErrorCategory::message(int ev) const 27 | { 28 | switch (static_cast(ev)) 29 | { 30 | case IniParsingError::Ok: 31 | return "ok"; 32 | case IniParsingError::SectionNotClosed: 33 | return "section not closed"; 34 | case IniParsingError::UnexpectedCharacter: 35 | return "unexpected character"; 36 | default: 37 | assert(false); 38 | return ""; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/detail/IcuCharacterIteratorBridge.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "IcuCharacterIteratorBridge.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::detail; 12 | 13 | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IcuCharacterIteratorBridge) 14 | 15 | IcuCharacterIteratorBridge::IcuCharacterIteratorBridge(std::u16string_view view) noexcept 16 | : m_stView(view) 17 | { 18 | setText(reinterpret_cast(view.data()), view.length()); 19 | } 20 | 21 | IcuCharacterIteratorBridge::IcuCharacterIteratorBridge(const IcuCharacterIteratorBridge& org) noexcept 22 | : icu::UCharCharacterIterator(org), m_stView(org.m_stView) 23 | { 24 | setText(reinterpret_cast(m_stView.data()), m_stView.length()); 25 | } 26 | 27 | icu::UCharCharacterIterator* IcuCharacterIteratorBridge::clone() const 28 | { 29 | return new IcuCharacterIteratorBridge(*this); 30 | } 31 | -------------------------------------------------------------------------------- /src/Core/detail/IcuCharacterIteratorBridge.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/27 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace lstg::detail 14 | { 15 | /** 16 | * ICU 字符迭代器封装 17 | */ 18 | class IcuCharacterIteratorBridge : 19 | public icu::UCharCharacterIterator 20 | { 21 | public: 22 | static UClassID getStaticClassID(); 23 | 24 | public: 25 | explicit IcuCharacterIteratorBridge(std::u16string_view view) noexcept; 26 | 27 | // Non-copyable 28 | IcuCharacterIteratorBridge& operator=(const IcuCharacterIteratorBridge&) = delete; 29 | 30 | protected: 31 | IcuCharacterIteratorBridge(const IcuCharacterIteratorBridge& org) noexcept; 32 | 33 | public: // icu::UCharCharacterIterator 34 | [[nodiscard]] UClassID getDynamicClassID() const override; 35 | [[nodiscard]] icu::UCharCharacterIterator* clone() const override; 36 | 37 | private: 38 | std::u16string_view m_stView; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/detail/IcuError.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "IcuError.hpp" 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::detail; 12 | 13 | const IcuErrorCategory& IcuErrorCategory::GetInstance() noexcept 14 | { 15 | static const IcuErrorCategory kInstance; 16 | return kInstance; 17 | } 18 | 19 | const char* IcuErrorCategory::name() const noexcept 20 | { 21 | return "IcuError"; 22 | } 23 | 24 | std::string IcuErrorCategory::message(int ev) const 25 | { 26 | return ::u_errorName(static_cast(ev)); 27 | } 28 | -------------------------------------------------------------------------------- /src/Core/detail/IcuError.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | namespace lstg::detail 12 | { 13 | /** 14 | * ICU 错误代码分类 15 | */ 16 | class IcuErrorCategory : 17 | public std::error_category 18 | { 19 | public: 20 | static const IcuErrorCategory& GetInstance() noexcept; 21 | 22 | public: 23 | const char* name() const noexcept override; 24 | std::string message(int ev) const override; 25 | }; 26 | } 27 | 28 | inline std::error_code make_error_code(UErrorCode ec) noexcept 29 | { 30 | return { static_cast(ec), lstg::detail::IcuErrorCategory::GetInstance() }; 31 | } 32 | 33 | template <> 34 | struct std::is_error_code_enum : std::true_type {}; 35 | -------------------------------------------------------------------------------- /src/Core/detail/IcuService.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/6/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace lstg::detail 15 | { 16 | struct IcuBidiDeleter 17 | { 18 | void operator()(UBiDi* bidi) noexcept; 19 | }; 20 | 21 | using IcuBidiPtr = std::unique_ptr; 22 | using IcuBreakIteratorPtr = std::unique_ptr; 23 | 24 | /** 25 | * ICU 服务单例 26 | * 用于初始化 ICU 数据文件。 27 | */ 28 | class IcuService 29 | { 30 | public: 31 | static IcuService& GetInstance() noexcept; 32 | 33 | protected: 34 | IcuService() noexcept; 35 | IcuService(const IcuService&) = delete; 36 | IcuService(IcuService&&) noexcept = delete; 37 | 38 | public: 39 | /** 40 | * 创建 BiDi 对象 41 | */ 42 | Result CreateBidi() noexcept; 43 | 44 | /** 45 | * 创建 Grapheme 分段器 46 | */ 47 | Result CreateGraphemeBreakIterator() noexcept; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/detail/STBBuild.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/4/11 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #define STB_IMAGE_IMPLEMENTATION 8 | #include 9 | #undef STB_IMAGE_IMPLEMENTATION 10 | 11 | #define STB_IMAGE_WRITE_IMPLEMENTATION 12 | #include 13 | #undef STB_IMAGE_WRITE_IMPLEMENTATION 14 | -------------------------------------------------------------------------------- /src/v2/Asset/EffectAsset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/16 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::v2::Asset; 14 | 15 | Subsystem::Asset::AssetTypeId EffectAsset::GetAssetTypeIdStatic() noexcept 16 | { 17 | const auto& uniqueTypeName = Subsystem::Script::detail::GetUniqueTypeName(); 18 | return uniqueTypeName.Id; 19 | } 20 | 21 | EffectAsset::EffectAsset(std::string name, std::string path) 22 | : Subsystem::Asset::Asset(std::move(name)), m_stPath(std::move(path)) 23 | { 24 | } 25 | 26 | Subsystem::Asset::AssetTypeId EffectAsset::GetAssetTypeId() const noexcept 27 | { 28 | return GetAssetTypeIdStatic(); 29 | } 30 | 31 | void EffectAsset::UpdateResource(Subsystem::Render::GraphDef::ImmutableEffectDefinitionPtr def, Subsystem::Render::MaterialPtr mat) noexcept 32 | { 33 | assert(def && mat); 34 | m_pEffectDef = std::move(def); 35 | m_pDefaultMaterial = std::move(mat); 36 | 37 | #if LSTG_ASSET_HOT_RELOAD 38 | UpdateVersion(); 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /src/v2/Asset/HgeParticleAsset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/15 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::v2::Asset; 12 | 13 | Subsystem::Asset::AssetTypeId HgeParticleAsset::GetAssetTypeIdStatic() noexcept 14 | { 15 | const auto& uniqueTypeName = Subsystem::Script::detail::GetUniqueTypeName(); 16 | return uniqueTypeName.Id; 17 | } 18 | 19 | HgeParticleAsset::HgeParticleAsset(std::string name, std::string path, SpriteAssetPtr spriteAsset, ColliderShape colliderShape) 20 | : Subsystem::Asset::Asset(std::move(name)), m_stPath(std::move(path)), m_pSpriteAsset(std::move(spriteAsset)), 21 | m_stColliderShape(colliderShape) 22 | { 23 | assert(m_pSpriteAsset); 24 | } 25 | 26 | Subsystem::Asset::AssetTypeId HgeParticleAsset::GetAssetTypeId() const noexcept 27 | { 28 | return GetAssetTypeIdStatic(); 29 | } 30 | 31 | void HgeParticleAsset::UpdateResource(const Subsystem::Render::Drawing2D::ParticleConfig& config) noexcept 32 | { 33 | m_stParticleConfig = config; 34 | m_stParticleConfig.ParticleSprite = &m_pSpriteAsset->GetDrawingSprite(); 35 | 36 | #if LSTG_ASSET_HOT_RELOAD 37 | UpdateVersion(); 38 | #endif 39 | } 40 | -------------------------------------------------------------------------------- /src/v2/Asset/MusicAsset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace lstg; 15 | using namespace lstg::v2::Asset; 16 | 17 | Subsystem::Asset::AssetTypeId MusicAsset::GetAssetTypeIdStatic() noexcept 18 | { 19 | const auto& uniqueTypeName = Subsystem::Script::detail::GetUniqueTypeName(); 20 | return uniqueTypeName.Id; 21 | } 22 | 23 | MusicAsset::MusicAsset(std::string name, std::string path, MusicLoopRange loopRange) 24 | : Subsystem::Asset::Asset(std::move(name)), m_stPath(std::move(path)), m_stMusicLoopRange(loopRange) 25 | { 26 | } 27 | 28 | Subsystem::Asset::AssetTypeId MusicAsset::GetAssetTypeId() const noexcept 29 | { 30 | return GetAssetTypeIdStatic(); 31 | } 32 | 33 | void MusicAsset::OnRemove() noexcept 34 | { 35 | // 特殊处理:当被播放的音频删除时,从音频引擎中剔除 36 | if (m_stSourceInstance) 37 | { 38 | auto& audioSystem = *AppBase::GetInstance().GetSubsystem(); 39 | audioSystem.GetEngine().SourceDelete(*m_stSourceInstance); 40 | m_stSourceInstance = {}; 41 | } 42 | } 43 | 44 | void MusicAsset::UpdateResource(Subsystem::Audio::SoundDataPtr data) noexcept 45 | { 46 | assert(data); 47 | m_pSoundData = std::move(data); 48 | 49 | #if LSTG_ASSET_HOT_RELOAD 50 | UpdateVersion(); 51 | #endif 52 | } 53 | -------------------------------------------------------------------------------- /src/v2/Asset/SoundAsset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/9/17 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace lstg; 15 | using namespace lstg::v2::Asset; 16 | 17 | Subsystem::Asset::AssetTypeId SoundAsset::GetAssetTypeIdStatic() noexcept 18 | { 19 | const auto& uniqueTypeName = Subsystem::Script::detail::GetUniqueTypeName(); 20 | return uniqueTypeName.Id; 21 | } 22 | 23 | SoundAsset::SoundAsset(std::string name, std::string path) 24 | : Subsystem::Asset::Asset(std::move(name)), m_stPath(std::move(path)) 25 | { 26 | } 27 | 28 | Subsystem::Asset::AssetTypeId SoundAsset::GetAssetTypeId() const noexcept 29 | { 30 | return GetAssetTypeIdStatic(); 31 | } 32 | 33 | void SoundAsset::OnRemove() noexcept 34 | { 35 | // 特殊处理:当被播放的音频删除时,从音频引擎中剔除 36 | if (m_stSourceInstance) 37 | { 38 | auto& audioSystem = *AppBase::GetInstance().GetSubsystem(); 39 | audioSystem.GetEngine().SourceDelete(*m_stSourceInstance); 40 | m_stSourceInstance = {}; 41 | } 42 | } 43 | 44 | void SoundAsset::UpdateResource(Subsystem::Audio::SoundDataPtr data) noexcept 45 | { 46 | assert(data); 47 | m_pSoundData = std::move(data); 48 | 49 | #if LSTG_ASSET_HOT_RELOAD 50 | UpdateVersion(); 51 | #endif 52 | } 53 | -------------------------------------------------------------------------------- /src/v2/Asset/TrueTypeFontAsset.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/10 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::v2::Asset; 14 | 15 | Subsystem::Asset::AssetTypeId TrueTypeFontAsset::GetAssetTypeIdStatic() noexcept 16 | { 17 | const auto& uniqueTypeName = Subsystem::Script::detail::GetUniqueTypeName(); 18 | return uniqueTypeName.Id; 19 | } 20 | 21 | TrueTypeFontAsset::TrueTypeFontAsset(std::string name, std::string path, uint32_t fontSize) 22 | : Subsystem::Asset::Asset(std::move(name)), m_stPath(std::move(path)), m_uFontSize(fontSize) 23 | { 24 | } 25 | 26 | Subsystem::Asset::AssetTypeId TrueTypeFontAsset::GetAssetTypeId() const noexcept 27 | { 28 | return GetAssetTypeIdStatic(); 29 | } 30 | 31 | void TrueTypeFontAsset::UpdateResource(Subsystem::Render::Font::FontFacePtr fontFace, 32 | Subsystem::Render::Font::FontCollectionPtr fontCollection) noexcept 33 | { 34 | m_pFontFace = std::move(fontFace); 35 | m_pFontCollection = std::move(fontCollection); 36 | 37 | #if LSTG_ASSET_HOT_RELOAD 38 | UpdateVersion(); 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /src/v2/Bridge/InputModule.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include "detail/Helper.hpp" 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::v2::Bridge; 14 | 15 | bool InputModule::GetKeyState(int32_t vkCode) 16 | { 17 | auto& app = detail::GetGlobalApp(); 18 | return app.IsKeyDown(vkCode); 19 | } 20 | 21 | int32_t InputModule::GetLastKey() 22 | { 23 | auto& app = detail::GetGlobalApp(); 24 | return app.GetLastInputKeyCode(); 25 | } 26 | 27 | const char* InputModule::GetLastChar() 28 | { 29 | auto& app = detail::GetGlobalApp(); 30 | return app.GetLastInputChar().c_str(); 31 | } 32 | 33 | Subsystem::Script::Unpack InputModule::GetMousePosition() 34 | { 35 | auto& app = detail::GetGlobalApp(); 36 | auto pos = app.GetMousePosition(); 37 | return { pos.x, pos.y }; 38 | } 39 | 40 | bool InputModule::GetMouseState(int32_t button) 41 | { 42 | auto& app = detail::GetGlobalApp(); 43 | MouseButtons transButton = MouseButtons::MAX; 44 | switch (button) 45 | { 46 | case 0: 47 | transButton = MouseButtons::Left; 48 | break; 49 | case 1: 50 | transButton = MouseButtons::Middle; 51 | break; 52 | case 2: 53 | transButton = MouseButtons::Right; 54 | break; 55 | default: 56 | return false; 57 | } 58 | return app.IsMouseButtonDown(transButton); 59 | } 60 | -------------------------------------------------------------------------------- /src/v2/Bridge/LSTGColor.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/3/4 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::v2::Bridge; 12 | 13 | // 14 | 15 | bool LSTGColor::Equals(const LSTGColor& lhs, const LSTGColor& rhs) noexcept 16 | { 17 | return lhs == rhs; 18 | } 19 | 20 | LSTGColor LSTGColor::Add(const LSTGColor& lhs, const LSTGColor& rhs) noexcept 21 | { 22 | return {lhs + rhs}; 23 | } 24 | 25 | LSTGColor LSTGColor::Substract(const LSTGColor& lhs, const LSTGColor& rhs) noexcept 26 | { 27 | return {lhs - rhs}; 28 | } 29 | 30 | LSTGColor LSTGColor::Multiply(std::variant lhs, std::variant rhs) noexcept 31 | { 32 | if (lhs.index() == 0) 33 | { 34 | assert(rhs.index() == 1); 35 | auto f = std::get<0>(lhs); 36 | auto p = std::get<1>(rhs); 37 | assert(p); 38 | return LSTGColor{f * *p}; 39 | } 40 | if (rhs.index() == 0) 41 | { 42 | assert(lhs.index() == 1); 43 | auto f = std::get<0>(rhs); 44 | auto p = std::get<1>(lhs); 45 | assert(p); 46 | return LSTGColor{*p * f}; 47 | } 48 | return LSTGColor {*std::get<1>(lhs) * *std::get<1>(rhs)}; 49 | } 50 | 51 | Subsystem::Script::Unpack LSTGColor::ToARGB() const noexcept 52 | { 53 | return { ColorRGBA32::a(), ColorRGBA32::r(), ColorRGBA32::g(), ColorRGBA32::b() }; 54 | } 55 | 56 | std::string LSTGColor::ToString() const 57 | { 58 | return fmt::format("lstg.Color({},{},{},{})", ColorRGBA32::a(), ColorRGBA32::r(), ColorRGBA32::g(), ColorRGBA32::b()); 59 | } 60 | 61 | // 62 | -------------------------------------------------------------------------------- /src/v2/Bridge/LSTGRandomizer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/3/5 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::v2::Bridge; 12 | 13 | void LSTGRandomizer::Seed(uint32_t v) noexcept 14 | { 15 | Randomizer::SetSeed(v); 16 | } 17 | 18 | uint32_t LSTGRandomizer::GetSeed() const noexcept 19 | { 20 | return Randomizer::GetSeed(); 21 | } 22 | 23 | int32_t LSTGRandomizer::Int(int32_t low, int32_t upper) noexcept 24 | { 25 | if (low >= upper) 26 | return upper; 27 | 28 | auto range = static_cast(upper - low + 1); 29 | // m_stRandomizer.Next(range) // Next采用丢弃采样策略,可能会比较慢 30 | // 使用 float 会造成取值范围不能覆盖 int32_t,各有利弊 31 | auto ret = static_cast(::floor(Randomizer::NextFloat() * range + static_cast(low))); 32 | assert(low <= ret && ret <= upper); 33 | return ret; 34 | } 35 | 36 | double LSTGRandomizer::Float(double low, double upper) noexcept 37 | { 38 | if (low >= upper) 39 | return upper; 40 | 41 | auto range = static_cast(upper - low); 42 | auto ret = (Randomizer::NextFloat() * range) + low; 43 | assert(low <= ret && ret < upper); 44 | return ret; 45 | } 46 | 47 | int32_t LSTGRandomizer::Sign() noexcept 48 | { 49 | auto r = Randomizer::Next(); 50 | return static_cast((r & 1u) * 2u) - 1; 51 | } 52 | 53 | std::string LSTGRandomizer::ToString() const 54 | { 55 | return "lstgRandomizer"; 56 | } 57 | -------------------------------------------------------------------------------- /src/v2/Bridge/MathModule.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/4/17 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::v2::Bridge; 14 | 15 | double MathModule::Sin(double v) noexcept 16 | { 17 | return ::sin(v * kDegree2Radian); 18 | } 19 | 20 | double MathModule::Cos(double v) noexcept 21 | { 22 | return ::cos(v * kDegree2Radian); 23 | } 24 | 25 | double MathModule::ASin(double v) noexcept 26 | { 27 | return ::asin(v) * kRadian2Degree; 28 | } 29 | 30 | double MathModule::ACos(double v) noexcept 31 | { 32 | return ::acos(v) * kRadian2Degree; 33 | } 34 | 35 | double MathModule::Tan(double v) noexcept 36 | { 37 | return ::tan(v * kDegree2Radian); 38 | } 39 | 40 | double MathModule::ATan(double v) noexcept 41 | { 42 | return ::atan(v) * kRadian2Degree; 43 | } 44 | 45 | double MathModule::ATan2(double y, double x) noexcept 46 | { 47 | return ::atan2(y, x) * kRadian2Degree; 48 | } 49 | -------------------------------------------------------------------------------- /src/v2/Bridge/detail/Helper.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/6/5 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include "Helper.hpp" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg::v2::Bridge; 13 | using namespace lstg::v2::Bridge::detail; 14 | 15 | std::string detail::ResolveAbsoluteOrRelativePath(Subsystem::Script::LuaStack& stack, std::string_view path) noexcept 16 | { 17 | // 检查是否采取相对加载规则 18 | if (path.length() >= 2 && path[0] == '.' && path[1] == '/') 19 | { 20 | auto scriptPath = stack.GetTopLevelScriptPath(); 21 | if (scriptPath[0] != '\0') 22 | { 23 | Subsystem::VFS::Path p(scriptPath); 24 | Subsystem::VFS::Path file(string_view{path.data() + 2, path.length() - 2}); 25 | return (p.GetParent() / file).ToString(); 26 | } 27 | } 28 | // 默认 fallback 到全路径 29 | if (path[0] != '/') 30 | return fmt::format("/{}", path); // 强制增加一个 '/' 31 | return string{path}; 32 | } 33 | -------------------------------------------------------------------------------- /src/v2/Bridge/detail/Helper.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/5/15 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #pragma once 8 | #include 9 | 10 | namespace lstg::v2::Bridge::detail 11 | { 12 | /** 13 | * 获取全局 APP 对象 14 | */ 15 | inline GameApp& GetGlobalApp() noexcept 16 | { 17 | return *static_cast(&GameApp::GetInstance()); 18 | } 19 | 20 | /** 21 | * 解析绝对路径或相对路径 22 | * 23 | * 为了方便资源组织,且为了考虑兼容性,我们允许采取特殊的方式标记一个相对路径: 24 | * data/asset/1.png -> 绝对路径 /data/asset/1.png 25 | * ./asset/1.png -> 相对于脚本路径,若脚本位于 /data/1.lua,则解析为 /data/asset/1.png 26 | * 27 | * @param path 路径 28 | * @return 解析结果 29 | */ 30 | std::string ResolveAbsoluteOrRelativePath(Subsystem::Script::LuaStack& stack, std::string_view path) noexcept; 31 | } 32 | 33 | #define LSTG_LOG_DEPRECATED(MODULE, METHOD) \ 34 | do \ 35 | { \ 36 | static bool kPrinted = false; \ 37 | if (!kPrinted) \ 38 | { \ 39 | LSTG_LOG_WARN_CAT(MODULE, #METHOD " is deprecated and has no effect anymore"); \ 40 | kPrinted = true; \ 41 | } \ 42 | } while (false) 43 | -------------------------------------------------------------------------------- /src/v2/GamePlay/Components/Movement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::v2::GamePlay::Components; 12 | 13 | void Movement::Reset() noexcept 14 | { 15 | AngularVelocity = 0.; 16 | Velocity = { 0., 0. }; 17 | AccelVelocity = { 0., 0. }; 18 | RotateToSpeedDirection = false; 19 | } 20 | -------------------------------------------------------------------------------- /src/v2/GamePlay/Components/Script.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace lstg; 13 | using namespace lstg::v2::GamePlay::Components; 14 | 15 | void Script::Reset() noexcept 16 | { 17 | if (Pool) 18 | Pool->Free(Pool->GetState(), ScriptObjectId); 19 | ScriptObjectId = 0; 20 | Pool = nullptr; 21 | } 22 | -------------------------------------------------------------------------------- /src/v2/GamePlay/Components/Transform.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @date 2022/7/26 4 | * @author 9chu 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | using namespace std; 10 | using namespace lstg; 11 | using namespace lstg::v2::GamePlay::Components; 12 | 13 | void Transform::Reset() noexcept 14 | { 15 | Location = { 0., 0. }; 16 | LastLocation = { 0., 0. }; 17 | LocationDelta = { 0., 0. }; 18 | Rotation = 0.; 19 | } 20 | -------------------------------------------------------------------------------- /src/v2/LuaSTGPlus2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9chu/LuaSTGPlus/43bd3e33074384472e17e260745e4f0a1f170493/src/v2/LuaSTGPlus2.ico -------------------------------------------------------------------------------- /src/v2/Main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author 9chu 4 | * @date 2022/2/14 5 | * 此文件为 LuaSTGPlus 项目的一部分,版权与许可声明详见 COPYRIGHT.txt。 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // 版本信息 15 | #include 16 | 17 | using namespace std; 18 | using namespace lstg; 19 | using namespace lstg::v2; 20 | 21 | SDLMAIN_DECLSPEC int main(int argc, char* argv[]) 22 | { 23 | // 初始化命令行参数 24 | auto cargv = const_cast(argv); 25 | AppBase::ParseCmdline(argc, cargv); 26 | 27 | // 强制日志系统初始化 28 | Logging::GetInstance(); 29 | #ifdef LSTG_DEVELOPMENT 30 | LSTG_LOG_INFO("Version: {} (Development mode)", LSTG_VERSION); 31 | #else 32 | LSTG_LOG_INFO("Version: {} (Shipping mode)", LSTG_VERSION); 33 | #endif 34 | 35 | // 初始化 GameApp 36 | #ifdef LSTG_PLATFORM_EMSCRIPTEN 37 | static std::unique_ptr app; // 防止退出 main 后被析构 38 | #else 39 | std::unique_ptr app; 40 | #endif 41 | try 42 | { 43 | app = std::make_unique(argc, cargv); 44 | 45 | // 启动 46 | app->Run(); 47 | } 48 | catch (const std::exception& ex) 49 | { 50 | Pal::FatalError(ex.what(), false); 51 | return 1; 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /src/v2/ScriptObjectAttributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "enum_name": "ScriptObjectAttributes", 3 | "hasher_name": "TranslateScriptObjectAttributes", 4 | "enums": { 5 | "X": 1, 6 | "Y": 2, 7 | "DeltaX": 3, 8 | "DeltaY": 4, 9 | "Rotation": 5, 10 | "AngularVelocity": 6, 11 | "Timer": 7, 12 | "VelocityX": 8, 13 | "VelocityY": 9, 14 | "AccelVelocityX": 10, 15 | "AccelVelocityY": 11, 16 | "Layer": 12, 17 | "Group": 13, 18 | "Invisible": 14, 19 | "BoundaryCheck": 15, 20 | "TrackDirection": 16, 21 | "CollisionCheck": 17, 22 | "Status": 18, 23 | "ScaleX": 19, 24 | "ScaleY": 20, 25 | "Class": 21, 26 | "ColliderX": 22, 27 | "ColliderY": 23, 28 | "RectangleCollider": 24, 29 | "Image": 25, 30 | "Animation": 26 31 | }, 32 | "keys": { 33 | "x": "X", 34 | "y": "Y", 35 | "dx": "DeltaX", 36 | "dy": "DeltaY", 37 | "rot": "Rotation", 38 | "omiga": "AngularVelocity", 39 | "omega": "AngularVelocity", 40 | "timer": "Timer", 41 | "vx": "VelocityX", 42 | "vy": "VelocityY", 43 | "ax": "AccelVelocityX", 44 | "ay": "AccelVelocityY", 45 | "layer": "Layer", 46 | "group": "Group", 47 | "hide": "Invisible", 48 | "bound": "BoundaryCheck", 49 | "navi": "TrackDirection", 50 | "colli": "CollisionCheck", 51 | "status": "Status", 52 | "hscale": "ScaleX", 53 | "vscale": "ScaleY", 54 | "class": "Class", 55 | "a": "ColliderX", 56 | "b": "ColliderY", 57 | "rect": "RectangleCollider", 58 | "img": "Image", 59 | "ani": "Animation" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/v2/Version.hpp.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define LSTG_VERSION "@LSTG_VERSION@" 3 | -------------------------------------------------------------------------------- /src/v2/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // 3 | #define IDI_APPICON 101 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1000 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /tool/BinaryToCode/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function(lstg_binary_to_code) 2 | find_package(Python3 COMPONENTS Interpreter) 3 | 4 | if(NOT Python3_Interpreter_FOUND) 5 | message(FATAL "Python3 is required to build this project") 6 | endif() 7 | 8 | set(ONE_VALUE_ARGS INPUT NAME OUTPUT) 9 | cmake_parse_arguments(BINARY_TO_CODE "" "${ONE_VALUE_ARGS}" "" ${ARGN}) 10 | 11 | set(COMMAND_LINE --i "${BINARY_TO_CODE_INPUT}" -n "${BINARY_TO_CODE_NAME}" -o "${BINARY_TO_CODE_OUTPUT}") 12 | 13 | get_filename_component(BINARY_TO_CODE_TOOL_SOURCE_DIR "${CMAKE_CURRENT_FUNCTION_LIST_FILE}" DIRECTORY CACHE) 14 | 15 | add_custom_command( 16 | OUTPUT "${BINARY_TO_CODE_OUTPUT}" 17 | COMMAND ${Python3_EXECUTABLE} "${BINARY_TO_CODE_TOOL_SOURCE_DIR}/BinaryToCode.py" ${COMMAND_LINE} 18 | DEPENDS ${BINARY_TO_CODE_INPUT} "${BINARY_TO_CODE_TOOL_SOURCE_DIR}/BinaryToCode.py" 19 | COMMENT "Running binary to code tool" VERBATIM) 20 | 21 | set_source_files_properties("${BINARY_TO_CODE_OUTPUT}" PROPERTIES GENERATED TRUE) 22 | endfunction() 23 | -------------------------------------------------------------------------------- /tool/LuaAutoBridgeTool/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function(lstg_gen_auto_bridge_cpp) 2 | find_package(Python3 COMPONENTS Interpreter) 3 | 4 | if(NOT Python3_Interpreter_FOUND) 5 | message(FATAL "Python3 is required to build this project") 6 | endif() 7 | 8 | set(ONE_VALUE_ARGS OUTPUT NAME BASE) 9 | set(MULTI_VALUE_ARGS NAMESPACE FILES) 10 | cmake_parse_arguments(BRIDGE_CPP "" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) 11 | 12 | set(COMMAND_LINE --output "${BRIDGE_CPP_OUTPUT}" --name "${BRIDGE_CPP_NAME}" --file ${BRIDGE_CPP_FILES}) 13 | if(DEFINED BRIDGE_CPP_BASE) 14 | list(APPEND COMMAND_LINE --base "${BRIDGE_CPP_BASE}") 15 | endif() 16 | if(DEFINED BRIDGE_CPP_NAMESPACE) 17 | list(APPEND COMMAND_LINE --namespace ${BRIDGE_CPP_NAMESPACE}) 18 | endif() 19 | 20 | # message(STATUS ${COMMAND_LINE}) 21 | 22 | get_filename_component(LUA_AUTO_BRIDGE_TOOL_SOURCE_DIR "${CMAKE_CURRENT_FUNCTION_LIST_FILE}" DIRECTORY CACHE) 23 | 24 | add_custom_command( 25 | OUTPUT "${BRIDGE_CPP_OUTPUT}" 26 | COMMAND ${Python3_EXECUTABLE} "${LUA_AUTO_BRIDGE_TOOL_SOURCE_DIR}/LuaAutoBridgeTool.py" ${COMMAND_LINE} 27 | DEPENDS ${BRIDGE_CPP_FILES} "${LUA_AUTO_BRIDGE_TOOL_SOURCE_DIR}/LuaAutoBridgeTool.py" 28 | COMMENT "Running auto bridge tool" VERBATIM ) 29 | 30 | set_source_files_properties("${BRIDGE_CPP_OUTPUT}" PROPERTIES GENERATED TRUE) 31 | endfunction() 32 | -------------------------------------------------------------------------------- /tool/PerfectHashTool/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function(lstg_gen_perfect_hasher) 2 | find_package(Python3 COMPONENTS Interpreter) 3 | 4 | if(NOT Python3_Interpreter_FOUND) 5 | message(FATAL "Python3 is required to build this project") 6 | endif() 7 | 8 | set(ONE_VALUE_ARGS DECL OUT_HEADER OUT_SOURCE) 9 | cmake_parse_arguments(HPERF "" "${ONE_VALUE_ARGS}" "" ${ARGN}) 10 | 11 | set(COMMAND_LINE --define "${HPERF_DECL}" --header "${HPERF_OUT_HEADER}" --source "${HPERF_OUT_SOURCE}") 12 | 13 | # message(STATUS ${COMMAND_LINE}) 14 | 15 | get_filename_component(PREFECT_HASH_TOOL_SOURCE_DIR "${CMAKE_CURRENT_FUNCTION_LIST_FILE}" DIRECTORY CACHE) 16 | 17 | add_custom_command( 18 | OUTPUT "${HPERF_OUT_HEADER}" "${HPERF_OUT_SOURCE}" 19 | COMMAND ${Python3_EXECUTABLE} "${PREFECT_HASH_TOOL_SOURCE_DIR}/PerfectHashTool.py" ${COMMAND_LINE} 20 | DEPENDS ${HPERF_DECL} "${PREFECT_HASH_TOOL_SOURCE_DIR}/PerfectHashTool.py" 21 | COMMENT "Running perfect hash tool" VERBATIM ) 22 | 23 | set_source_files_properties("${HPERF_OUT_HEADER}" PROPERTIES GENERATED TRUE) 24 | set_source_files_properties("${HPERF_OUT_SOURCE}" PROPERTIES GENERATED TRUE) 25 | endfunction() 26 | -------------------------------------------------------------------------------- /tool/WebShellApp/Main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LuaSTGPlus 7 | 8 | 9 | 10 | 11 | 12 | 13 | 45 | 46 | 47 | 48 | 49 | 50 | --------------------------------------------------------------------------------