From cdeaac7c0cb4c9dc25652498604fa6e39bcfd077 Mon Sep 17 00:00:00 2001 From: kotofyt Date: Sun, 29 Jun 2025 01:21:55 +0300 Subject: [PATCH] introduces ios support? still needs metal --- Entitlemenets.plist | 9 + build.c | 55 --- build.cpp | 30 +- engine/__build.c | 75 --- engine/__build.cpp | 31 +- engine/brush.cpp | 56 ++- engine/console.cpp | 53 +- engine/engine.cpp | 8 +- engine/filesystem.cpp | 47 +- engine/gamemode.cpp | 22 +- engine/input.cpp | 130 ++++- engine/level.cpp | 3 + engine/mesh.cpp | 0 engine/physics.cpp | 32 +- engine/server.cpp | 18 +- engine/vk_external_functions.cpp | 6 + engine/vk_helper.h | 22 +- engine/vk_mesh.cpp | 423 ---------------- engine/vk_postprocessing.cpp | 144 ------ engine/vk_video.cpp | 430 ++++++++++++++--- {public => engine}/vk_video.h | 1 + engine/vk_videosdl.cpp | 28 +- fgui/__build.c | 37 -- fpc/fpc.dSYM/Contents/Info.plist | 20 + fpc/fpc.dSYM/Contents/Resources/DWARF/fpc | Bin 0 -> 144200 bytes .../Resources/Relocations/x86_64/fpc.yml | 5 + fpc/library/c.cpp | 24 +- fpc/library/helper.cpp | 9 + fpc/library/ld.cpp | 18 +- fpc/library/target.cpp | 44 ++ fpc/main.cpp | 11 +- fpc/public/target.h | 6 + funnyassets/__build.c | 39 -- funnyassets/__build.cpp | 23 +- funnyassets/maps/test_map.fmap | Bin 17537710 -> 17537709 bytes funnyassets/raw_maps/dust.map | 2 +- game/client/__build.c | 35 -- game/client/__build.cpp | 17 +- game/client/milmoba/player.cpp | 10 + game/server/__build.c | 36 -- game/server/__build.cpp | 17 +- game/server/milmoba/player.cpp | 160 +++--- .../funnygame.xcodeproj/project.pbxproj | 336 +++++++++++++ .../contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 13928 bytes .../xcschemes/xcschememanagement.plist | 14 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 ++ .../funnygame/Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../funnygame/Base.lproj/Main.storyboard | 24 + ios_deploy/funnygame/funnygame/Info.plist | 25 + .../funnygame/funnygame/SceneDelegate.h | 15 + .../funnygame/funnygame/SceneDelegate.m | 57 +++ ios_deploy/funnygame/funnygame/Untitled.swift | 0 .../funnygame/funnygame/ViewController.h | 14 + ios_deploy/funnygame/funnygame/main.m | 18 + launcher/__build.c | 35 -- launcher/__build.cpp | 17 +- launcher/launcher.cpp | 22 +- public/baseentity.h | 3 +- public/brush.h | 3 +- public/console.h | 5 + public/input.h | 21 +- public/math3d.h | 5 + public/mesh.h | 31 ++ public/physics.h | 26 +- public/rendering.h | 455 +++++++++++++++--- public/tier0/lib.h | 6 + public/tier0/platform.h | 2 +- public/tier1/commandline.h | 2 +- rapier/__build.c | 29 -- rapier/__build.cpp | 5 +- rapier/px.rs | 8 +- tier0/__build.c | 42 -- tier0/__build.cpp | 17 +- tier0/platform.cpp | 24 +- tier1/__build.c | 42 -- tier1/commandline.cpp | 2 +- 79 files changed, 2176 insertions(+), 1349 deletions(-) create mode 100644 Entitlemenets.plist delete mode 100644 build.c delete mode 100644 engine/__build.c create mode 100644 engine/mesh.cpp delete mode 100644 engine/vk_mesh.cpp delete mode 100644 engine/vk_postprocessing.cpp rename {public => engine}/vk_video.h (98%) delete mode 100644 fgui/__build.c create mode 100644 fpc/fpc.dSYM/Contents/Info.plist create mode 100644 fpc/fpc.dSYM/Contents/Resources/DWARF/fpc create mode 100644 fpc/fpc.dSYM/Contents/Resources/Relocations/x86_64/fpc.yml delete mode 100644 funnyassets/__build.c delete mode 100644 game/client/__build.c delete mode 100644 game/server/__build.c create mode 100644 ios_deploy/funnygame/funnygame.xcodeproj/project.pbxproj create mode 100644 ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 ios_deploy/funnygame/funnygame/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 ios_deploy/funnygame/funnygame/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 ios_deploy/funnygame/funnygame/Assets.xcassets/Contents.json create mode 100644 ios_deploy/funnygame/funnygame/Base.lproj/LaunchScreen.storyboard create mode 100644 ios_deploy/funnygame/funnygame/Base.lproj/Main.storyboard create mode 100644 ios_deploy/funnygame/funnygame/Info.plist create mode 100644 ios_deploy/funnygame/funnygame/SceneDelegate.h create mode 100644 ios_deploy/funnygame/funnygame/SceneDelegate.m create mode 100644 ios_deploy/funnygame/funnygame/Untitled.swift create mode 100644 ios_deploy/funnygame/funnygame/ViewController.h create mode 100644 ios_deploy/funnygame/funnygame/main.m delete mode 100644 launcher/__build.c create mode 100644 public/mesh.h delete mode 100644 rapier/__build.c delete mode 100644 tier0/__build.c delete mode 100644 tier1/__build.c diff --git a/Entitlemenets.plist b/Entitlemenets.plist new file mode 100644 index 0000000..2eba670 --- /dev/null +++ b/Entitlemenets.plist @@ -0,0 +1,9 @@ + + + + + + aps-environment + development + + diff --git a/build.c b/build.c deleted file mode 100644 index aafbd1a..0000000 --- a/build.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "god/build.h" -#include "god/utils.h" - -#define GAME_NAME "funnygame" - -char* include_dirs[] = { - "public", - "external/cglm/include", - "external/Vulkan-Headers/include", - "external/VulkanMemoryAllocator/include", - "external/stb", - NULL, -}; - -#include "tier0/__build.c" -#include "tier1/__build.c" - -#include "fgui/__build.c" -#include "rapier/__build.c" -#include "engine/__build.c" -#include "game/server/__build.c" -#include "game/client/__build.c" - -#include "launcher/__build.c" -#include "funnyassets/__build.c" - - -int build(struct build_data b) { - trace = 1; - makedir("build/"GAME_NAME"/game/" GAME_NAME); - makedir("build/"GAME_NAME"/game/" GAME_NAME "/bin"); - makedir("build/"GAME_NAME"/game/bin/"); - tier0_build(b); - tier1_build(b); - fgui_build(b); - rapier_build(b); - engine_build(b); - launcher_build(b); - - server_build(b); - client_build(b); - - if (step("noassets")) - { - assets_build(b); - } - mv("build", "tools"); - - if (step("run")!=STEP_FAILED) - { - struct run_project rp = run_new("build/"GAME_NAME"/game/bin/"GAME_NAME); - run_run(&rp); - } - return 0; -}; diff --git a/build.cpp b/build.cpp index 423faa7..34e6012 100644 --- a/build.cpp +++ b/build.cpp @@ -1,5 +1,6 @@ +#include "target.h" #include "tier1/utlstring.h" -#include "tier1/utlstring.h" +#include "helper.h" CUtlVector all_IncludeDirectories = { "public", @@ -7,17 +8,34 @@ CUtlVector all_IncludeDirectories = { "external/Vulkan-Headers/include", "external/VulkanMemoryAllocator/include", "external/stb", + "external/SDL/include", }; + +auto szTarget = Target_t::DefaultTarget().GetTriplet(); +auto szOutputDir = CUtlString("build/funnygame/%s/game",szTarget.GetString()); + +bool bStaticBuild = false; + +extern "C" void Preinit() +{ + if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_IOS) + bStaticBuild = true; +}; + +CUtlString tier0_lib; +CUtlString engine_lib; +CUtlString server_lib; +CUtlString client_lib; #include "tier0/__build.cpp" #include "tier1/__build.cpp" -#include "rapier/__build.cpp" -#include "engine/__build.cpp" - -#include "launcher/__build.cpp" - #include "game/server/__build.cpp" #include "game/client/__build.cpp" +#include "rapier/__build.cpp" +#include "engine/__build.cpp" + #include "funnyassets/__build.cpp" + +#include "launcher/__build.cpp" diff --git a/engine/__build.c b/engine/__build.c deleted file mode 100644 index e52584e..0000000 --- a/engine/__build.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "god/build.h" -#include "god/c.h" -#include "god/ld.h" -#include "god/utils.h" - -char *engine_lib; -char *engine_implib; -void engine_build(struct build_data b) -{ - char *szVideoFile = "engine/vk_videosdl.cpp"; - char* files[] = { - "engine/console.cpp", - "engine/filesystem.cpp", - "engine/server.cpp", - "engine/engine.cpp", - - /* rendering */ - "engine/vk_video.cpp", - "engine/vk_mesh.cpp", - szVideoFile, - - /* entities */ - "engine/baseentity.cpp", - "engine/level.cpp", - "engine/brush.cpp", - - /* server */ - "engine/sv_worldspawn.cpp", - "engine/sv_light.cpp", - - /* client */ - "engine/cl_worldspawn.cpp", - "engine/cl_light.cpp", - NULL, - }; - - - struct project p = { - .b = &b, - .files = files, - .name = "engine", - }; - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - }); - add_item(&o.files, tier1_lib); - add_item(&o.files, rapierLib); - - char *szVulkan = (char*)1; - char *szws2 = (char*)1; - if (b.kernel==BUILD_KERNEL_WINDOWS) - { - szVulkan="vulkan-1"; - szws2="ws2_32"; - } - if (b.kernel==BUILD_KERNEL_LINUX) - { - szVulkan="vulkan"; - } - - char* libs[] = { - "c", - "SDL3", - szVulkan, - NULL, - }; - - engine_lib = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_DYNAMIC, - .libs = libs, - }); - mv("build/"GAME_NAME"/game/bin",engine_lib); -} diff --git a/engine/__build.cpp b/engine/__build.cpp index b9337d3..88c59cf 100644 --- a/engine/__build.cpp +++ b/engine/__build.cpp @@ -29,8 +29,6 @@ CUtlVector engine_CompiledFiles = { /* rendering */ "engine/vk_videosdl.cpp", "engine/vk_video.cpp", - "engine/vk_mesh.cpp", - "engine/vk_postprocessing.cpp", /* io */ "engine/input.cpp", @@ -40,11 +38,14 @@ CUtlVector engine_CompiledFiles = { CUtlVector engine_Libraries = { "c", "SDL3", - "vulkan", }; int engine_build() { + if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_DARWIN) + engine_Libraries.AppendTail("MoltenVK"); + if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_LINUX) + engine_Libraries.AppendTail("vulkan"); CCProject compileProject = {}; CLDProject ldProject = {}; @@ -53,19 +54,27 @@ int engine_build() compileProject.includeDirectories = all_IncludeDirectories; compileProject.bFPIC = true; ldProject = compileProject.Compile(); - ldProject.linkType = ELINK_DYNAMIC_LIBRARY; ldProject.libraries = engine_Libraries; - ldProject.objects.AppendTail((CObject){tier1_lib}); - ldProject.objects.AppendTail((CObject){rapier_lib}); + if (bStaticBuild) + ldProject.linkType = ELINK_STATIC_LIBRARY; + else + { + ldProject.objects.AppendTail((CObject){tier1_lib}); + ldProject.objects.AppendTail((CObject){rapier_lib}); + ldProject.linkType = ELINK_DYNAMIC_LIBRARY; + } CUtlString outputProject = ldProject.Link(); + + if (!bStaticBuild) + { + IFileSystem2::MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString())); + IFileSystem2::CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), outputProject); + } else { + engine_lib = outputProject; + } - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::MakeDirectory(CUtlString("build/%s/game/bin",szGameName)); - IFileSystem2::CopyFile(CUtlString("build/%s/game/bin",szGameName), outputProject); return 0; diff --git a/engine/brush.cpp b/engine/brush.cpp index 5924f4b..fbc4740 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -30,7 +30,7 @@ void CBrushEntity::Spawn() } /* use them */ px_collider_params params = {}; - params.friction = 0.6; + params.friction = 0.0; m_collider = px_trimesh((Point*)triangles.GetMemory(), triangles.GetSize(), (uint32_t(*)[3])indicies.GetMemory(), indicies.GetSize()/3 ,params); px_fixedbody(px, m_collider); }; @@ -65,10 +65,11 @@ void C_BrushEntity::Spawn() float uv[2]; }; - pAlbedo = ITextureManager::LoadTexture("textures/bricks.png"); CBrushEntity* pBrushEntity = (CBrushEntity*)pEntity; uint32_t numVertices = 15*pBrushEntity->m_mesh.GetSize(); + vertexBuffer = IRenderer::CreateVertexBuffer(numVertices*4); + Vertex_t *pTriangles = (Vertex_t*)vertexBuffer->Map(); uint32_t i = 0; for (auto &triangle: pBrushEntity->m_mesh) @@ -91,10 +92,6 @@ void C_BrushEntity::Spawn() i+=3; } vertexBuffer->Unmap(); - - mesh = IMeshRenderer::CreateMesh(); - mesh->SetVertexBuffer(vertexBuffer); - }; void C_BrushEntity::Destroy() @@ -103,7 +100,6 @@ void C_BrushEntity::Destroy() } void C_BrushEntity::Think( float fDelta ) { - material.m.albedo = ITextureManager::GetTexture(pAlbedo); mat4 matrix; glm_mat4_zero(matrix); for (int i = 0; i < 9; i++) { @@ -113,8 +109,48 @@ void C_BrushEntity::Think( float fDelta ) matrix[3][0] = pEntity->m_position[0]; matrix[3][1] = pEntity->m_position[1]; matrix[3][2] = pEntity->m_position[2]; - mesh->SetMatrix(matrix); - mesh->SetMaterial(&material); - mesh->Draw(); +}; + +IGraphicsPipeline *g_BrushPipeline; + +class CBrushRendering: public IRenderingPipelineStep +{ +public: + virtual void Init() override; + virtual void Frame( float fDelta ) override; + virtual void Deinit() override; +private: +}; +DECLARE_MESH_RENDERING_STAGE(CBrushRendering, brush_rasterizer); + +CUtlVector g_BrushVertices; + +void CBrushRendering::Init() +{ + V_printf("cool\n"); + IRenderer::CreateGraphicsPipeline( + { + {"shaders/brush_vert.spv", SHADER_TYPE_VERTEX}, + {"shaders/brush_frag.spv", SHADER_TYPE_FRAGMENT}, + }, + {}, 64, + {EImageFormat::IMAGE_FORMAT_R8G8B8A8} + ); }; +void CBrushRendering::Frame( float fDelta ) +{ + V_printf("cooll\n"); + IRenderer::ResetState(); + IRenderer::SetDepthMode(DEPTH_MODE_LESS_EQUAL); + IRenderer::BindPipeline(g_BrushPipeline); + for (auto &vertices: g_BrushVertices) + { + IRenderer::Draw(vertices, 0); + } +}; + +void CBrushRendering::Deinit() +{ + +}; diff --git a/engine/console.cpp b/engine/console.cpp index 760fc79..7ac92c8 100644 --- a/engine/console.cpp +++ b/engine/console.cpp @@ -1,4 +1,5 @@ #include "console.h" +#include "filesystem.h" #include "tier1/utlstring.h" #include "tier1/utlvector.h" @@ -64,33 +65,43 @@ void IConsole::Execute2( CUtlVector &args ) (cmd->GetCallback())(args.GetSize(), strbuffer); } +void IConsole::Execute( void ) +{ + CUtlVector> commands = ParseCommandLine(g_commandBuffer); + g_commandBuffer = 0; + for (auto &command: commands) + { + IConsole::Execute2(command); + } +} + //----------------------------------------------------------------------------- // Parses command buffer. //----------------------------------------------------------------------------- -void IConsole::Execute( void ) -{ +CUtlVector> IConsole::ParseCommandLine( CUtlString psz ) +{ CUtlVector arguments; + CUtlVector> commands; CUtlString szArgument; bool bIsQuote = false; - for (auto &c: (CUtlVector&)g_commandBuffer) + for ( auto &c: (CUtlVector&)psz ) { - if (c == '\"') + if ( c == '\"' ) { bIsQuote = !bIsQuote; continue; } - if (c == ';' || c == '\n' || c == '\0') + if ( c == ';' || c == '\n' ) { if (bIsQuote) { - if (c != '\0') - szArgument.AppendTail(c); continue; } if (szArgument != 0) arguments.AppendTail(szArgument); - IConsole::Execute2(arguments); + if ( arguments.GetSize() > 0 ) + commands.AppendTail(arguments); szArgument = 0; arguments = {}; continue; @@ -110,7 +121,11 @@ void IConsole::Execute( void ) } szArgument.AppendTail(c); }; - g_commandBuffer = 0; + if (szArgument != 0) + arguments.AppendTail(szArgument); + if ( arguments.GetSize() > 0 ) + commands.AppendTail(arguments); + return commands; } void IConsole::AddCommand( const char *psz ) @@ -232,3 +247,23 @@ ConCommandFn ConCommand::GetCallback( void ) { return m_callback; } + + + +void IConsole_Exec( int argc, char **argv) +{ + if (argc != 2) + return; + + FileHandle_t f = IFileSystem::Open(argv[1], IFILE_READ); + if (!f) + return; + CUtlBuffer b(IFileSystem::Size(f)+1); + IFileSystem::Read(f, b, b.GetSize()); + b[IFileSystem::Size(f)] = 0; + IConsole::AddCommand(b); + IConsole::AddCommand(";"); + IConsole::Execute(); +} + +ConCommand IConsole_ExecCmd("exec", IConsole_Exec); diff --git a/engine/engine.cpp b/engine/engine.cpp index 1a742c6..0ce9f7c 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -54,7 +54,7 @@ void IEngine_Signal(int sig) break; }; IEngine::Shutdown(); - _exit(0); + Plat_Exit(0); }; //----------------------------------------------------------------------------- @@ -88,8 +88,14 @@ void IEngine::Init() IVideo::Init(); IInput::Init(); + IInput::SetMouseMode(MOUSE_MODE_GAME); } + IServer::LoadGame("funnygame"); + + IConsole::AddCommand("exec default.cfg;"); + IConsole::Execute(); + }; //----------------------------------------------------------------------------- diff --git a/engine/filesystem.cpp b/engine/filesystem.cpp index d827eb0..d898fce 100644 --- a/engine/filesystem.cpp +++ b/engine/filesystem.cpp @@ -44,6 +44,10 @@ public: static void AddFile( const char *psz ); }; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- void IFileSystem::InitFilesystem() { fs_basedir = ICommandLine::ParamValue("-basedir"); @@ -59,6 +63,10 @@ void IFileSystem::InitFilesystem() AddGameDirectory(fs_gamedir); } + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- void CFileSystem::AddFile( const char *psz ) { CUtlString extension = Plat_GetExtension(psz); @@ -68,6 +76,9 @@ void CFileSystem::AddFile( const char *psz ) }; } +//----------------------------------------------------------------------------- +// Adds directory which can contain pack files +//----------------------------------------------------------------------------- void IFileSystem::AddGameDirectory( const char *psz ) { FileDirectory_t dir = {}; @@ -81,6 +92,10 @@ void IFileSystem::AddGameDirectory( const char *psz ) }; }; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- bool IFileSystem::LoadPackFile( const char *szFilename ) { Pack_t pack = {}; @@ -109,10 +124,6 @@ bool IFileSystem::LoadPackFile( const char *szFilename ) pack.handle = f; pack.files = CUtlVector(nNumFiles); V_memcpy(pack.files.GetData(),pDirs, header.size); - for (auto &i: pack.files) - { - V_printf(" LOADED %s\n",i.name); - } V_free(pDirs); nNumFiles = header.size/sizeof(PackDirectory_t); @@ -124,10 +135,19 @@ bool IFileSystem::LoadPackFile( const char *szFilename ) return true; } + +//----------------------------------------------------------------------------- +// Creates path +//----------------------------------------------------------------------------- void IFileSystem::CreatePath( const char *szPath ) { } + +//----------------------------------------------------------------------------- +// Opens file +// If it is located in a pack then it can only be read +//----------------------------------------------------------------------------- FileHandle_t IFileSystem::Open( const char *szFilename, EFileOptions options ) { if (options == IFILE_READ) @@ -172,6 +192,9 @@ FileHandle_t IFileSystem::Open( const char *szFilename, EFileOptions options ) return 0; } +//----------------------------------------------------------------------------- +// Closes file +//----------------------------------------------------------------------------- void IFileSystem::Close( FileHandle_t file ) { /* close only fs files */ @@ -182,10 +205,18 @@ void IFileSystem::Close( FileHandle_t file ) delete file; } + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- size_t IFileSystem::Size( FileHandle_t file ) { return file->nSize; } + +//----------------------------------------------------------------------------- +// Reads nSize bytes of file +//----------------------------------------------------------------------------- size_t IFileSystem::Read( FileHandle_t file, void *pOutput, size_t nSize) { if (file->file) @@ -200,10 +231,18 @@ size_t IFileSystem::Read( FileHandle_t file, void *pOutput, size_t nSize) return readsize; } + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- size_t IFileSystem::ReadLine( FileHandle_t file, void *pOutput, size_t nSize) { } + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- size_t IFileSystem::Write( FileHandle_t file, void *pInput, size_t nSize) { diff --git a/engine/gamemode.cpp b/engine/gamemode.cpp index 973e07c..7d8f39b 100644 --- a/engine/gamemode.cpp +++ b/engine/gamemode.cpp @@ -4,6 +4,9 @@ CGameMode *pCurrentMode = NULL; +//----------------------------------------------------------------------------- +// Round begin handler +//----------------------------------------------------------------------------- void CGameMode::RoundBegin( void ) { size_t i = 0; @@ -24,22 +27,33 @@ void CGameMode::RoundBegin( void ) } } +//----------------------------------------------------------------------------- +// Round end handler +//----------------------------------------------------------------------------- void CGameMode::RoundEnd( void ) { } - +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- void IGameModeManager::Init( void ) { } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- void IGameModeManager::Frame( void ) { } +//----------------------------------------------------------------------------- +// Sets gamemode +//----------------------------------------------------------------------------- void IGameModeManager::StartGameMode(CGameMode *pGameMode) { if (pCurrentMode) @@ -49,11 +63,17 @@ void IGameModeManager::StartGameMode(CGameMode *pGameMode) pCurrentMode->RoundBegin(); } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- CGameMode *IGameModeManager::GetCurrentMode( void ) { return pCurrentMode; } +//----------------------------------------------------------------------------- +// Restarts the gamemode +//----------------------------------------------------------------------------- void IGameModeManager::RestartCurrentMode( void ) { if (!pCurrentMode) diff --git a/engine/input.cpp b/engine/input.cpp index 05580b5..a98713c 100644 --- a/engine/input.cpp +++ b/engine/input.cpp @@ -1,52 +1,166 @@ #include "input.h" #include "console.h" #include "tier0/lib.h" +#include "tier1/commandline.h" +#include "math3d.h" -char g_PressedKeys[256]; -float g_fXAxisEvent[256]; -float g_fYAxisEvent[256]; +char g_PressedKeys[KEY_NUM_KEYS]; +float g_fAxisValues[AXIS_NUM_AXIS]; CUtlString g_bindings[256]; +struct KeyName_t { + const char *szName; + EInputKey key; +}; + +KeyName_t keys[] = { + {"TAB",KEY_TAB}, + {"ENTER",KEY_ENTER}, + {"ESCAPE",KEY_ESCAPE}, + {"SPACE",KEY_SPACE}, + {"A",KEY_A}, + {"B",KEY_B}, + {"C",KEY_C}, + {"D",KEY_D}, + {"E",KEY_E}, + {"F",KEY_F}, + {"G",KEY_G}, + {"H",KEY_H}, + {"I",KEY_I}, + {"J",KEY_J}, + {"K",KEY_K}, + {"L",KEY_L}, + {"M",KEY_M}, + {"N",KEY_N}, + {"O",KEY_O}, + {"P",KEY_P}, + {"Q",KEY_Q}, + {"R",KEY_R}, + {"S",KEY_S}, + {"T",KEY_T}, + {"U",KEY_U}, + {"V",KEY_V}, + {"W",KEY_W}, + {"X",KEY_X}, + {"Y",KEY_Y}, + {"Z",KEY_Z}, +}; + +//----------------------------------------------------------------------------- +// Converts string (eg. tab, mouse0, w, 0) to keycode +//----------------------------------------------------------------------------- +EInputKey IInput_StringToKey( char *psz ) +{ + for (uint32_t i = 0; im_pCollider, matrix, params); }; + +void CPxRigidKinematicPosition::SetPosition( px_vec3 position ) +{ + px_setposition(px, m_pRigidBody, position); +}; px_vec3 CPxRigidKinematicPosition::GetPosition( void ) { return px_getposition(px, m_pRigidBody); diff --git a/engine/server.cpp b/engine/server.cpp index 4db0682..368246c 100644 --- a/engine/server.cpp +++ b/engine/server.cpp @@ -12,6 +12,10 @@ void *g_serverdll; ConVar g_tickrate("tickrate","64",FCVAR_PROTECTED); float g_fAccumulator = 0; +//----------------------------------------------------------------------------- +// Loads game and client libraries if linking dynamically, otherwise it runs +// IGame_Load compiled statically. +//----------------------------------------------------------------------------- void IServer::LoadGame( const char *psz ) { #ifdef __WIN32__ @@ -21,6 +25,10 @@ void IServer::LoadGame( const char *psz ) g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/libserver.so", psz)); Plat_LoadLibrary(CUtlString("%s/bin/libclient.so", psz)); +#endif +#ifdef __APPLE__ + g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/libserver.dysim", psz)); + Plat_LoadLibrary(CUtlString("%s/bin/libclient.dysim", psz)); #endif void (*GameLoadfn)() = (void(*)())Plat_GetProc(g_serverdll, "IGame_Load"); if (!GameLoadfn) @@ -28,6 +36,9 @@ void IServer::LoadGame( const char *psz ) GameLoadfn(); }; +//----------------------------------------------------------------------------- +// Updates server and client state. +//----------------------------------------------------------------------------- void IServer::Think( float fDelta ) { g_fAccumulator += fDelta; @@ -37,8 +48,8 @@ void IServer::Think( float fDelta ) while(g_fAccumulator>=fTickrate) { IInput::Frame(); - IConsole::AddCommand("+forward;"); IConsole::Execute(); + g_fAccumulator-=fTickrate; for (auto &entity: g_entities) { @@ -52,3 +63,8 @@ void IServer::Think( float fDelta ) entity->pClientEntity->Think(fDelta); } }; + +void IGame_Exit( int argc, char **argv ) { + Plat_Exit(0); +} +ConCommand ExitCmd("exit", IGame_Exit, 0); diff --git a/engine/vk_external_functions.cpp b/engine/vk_external_functions.cpp index aaea4f6..7fed027 100644 --- a/engine/vk_external_functions.cpp +++ b/engine/vk_external_functions.cpp @@ -8,3 +8,9 @@ VK_DEVICE_FUNCTION(vkCmdSetColorBlendEnableEXT); VK_DEVICE_FUNCTION(vkCmdSetColorBlendEquationEXT); VK_DEVICE_FUNCTION(vkCmdSetColorWriteMaskEXT); VK_DEVICE_FUNCTION(vkCmdSetLogicOpEXT); +VK_DEVICE_FUNCTION(vkCmdTraceRaysKHR); +VK_DEVICE_FUNCTION(vkCreateAccelerationStructureKHR); +VK_DEVICE_FUNCTION(vkDestroyAccelerationStructureKHR); +VK_DEVICE_FUNCTION(vkGetAccelerationStructureBuildSizesKHR); +VK_DEVICE_FUNCTION(vkCmdBuildAccelerationStructuresKHR); +VK_DEVICE_FUNCTION(vkCreateRayTracingPipelinesKHR); diff --git a/engine/vk_helper.h b/engine/vk_helper.h index e39f1d6..fd95842 100644 --- a/engine/vk_helper.h +++ b/engine/vk_helper.h @@ -14,8 +14,7 @@ #include "vk_external_functions.cpp" #undef VK_DEVICE_FUNCTION - -class CVertexBuffer: public IVertexBuffer +class CVkBuffer: public IBuffer { public: void *Map() override; @@ -24,17 +23,14 @@ public: void *m_pAllocated = NULL; }; -class CIndexBuffer: public IIndexBuffer +class CVkImage: public IImage { public: - void *Map() override; - void Unmap() override; - vk_buffer_t m_buffer; - void *m_pAllocated; + vk_image2d_t m_image; }; -class CTexture: public ITexture +class CVkTexture: public ITexture { public: vk_image2d_t image; @@ -65,8 +61,6 @@ extern uint32_t g_nWindowWidth; extern uint32_t g_nWindowHeight; extern VkSampler g_invalidTextureSampler; -extern IMaterial *g_pDefaultMaterial; -extern IMaterial *g_pCurrentMaterial; extern CUtlVector g_textures; @@ -77,7 +71,7 @@ struct CameraProjection { extern vk_buffer_t g_cameraProperties; extern CameraProjection *g_cameraDataMap; -extern vk_image2d_t g_meshDepth; -extern vk_image2d_t g_meshDepthMSAA; -extern vk_image2d_t g_meshColor; -extern vk_image2d_t g_meshColorMSAA; +extern IImage *g_meshDepth; +extern IImage *g_meshDepthMSAA; +extern IImage *g_meshColor; +extern IImage *g_meshColorMSAA; diff --git a/engine/vk_mesh.cpp b/engine/vk_mesh.cpp deleted file mode 100644 index db48d8a..0000000 --- a/engine/vk_mesh.cpp +++ /dev/null @@ -1,423 +0,0 @@ -#include "filesystem.h" -#include "rendering.h" -#include "tier1/utlvector.h" -#include "vk_helper.h" -#include "vulkan/vulkan_core.h" -#include "math3d.h" - - -vk_tripipeline_t g_meshPipeline = {}; - -VkDescriptorPool g_meshDescriptorPool; -VkDescriptorSet g_meshDescriptorSet; - -VkSampler g_meshSampler; - - -abstract_class CMesh: public IMesh -{ -public: - CMesh(); - void SetPosition( vec3 position ) override; - void SetRotationEuler( vec3 angle ) override; - void SetRotationQuat( vec4 quaternion) override; - void SetMatrix( mat4 matrix ) override; - void SetScale( vec3 scale ) override; - - void SetVertexBuffer( IVertexBuffer *pBuffer ) override; - void SetIndexBuffer( IIndexBuffer *pBuffer ) override; - void SetMaterial( IMaterial *pMaterial ) override; - void Draw() override; - - Material_t m_material; - CVertexBuffer *m_pVertexBuffer = NULL; - CIndexBuffer *m_pIndexBuffer = NULL; - mat4 m_matrix; -}; - -CMesh::CMesh() -{ - glm_mat4_identity(m_matrix); -}; - -void CMesh::SetPosition( vec3 position ) -{ - m_matrix[0][3] = position[0]; - m_matrix[1][3] = position[1]; - m_matrix[2][3] = position[2]; -} - -void CMesh::SetRotationEuler( vec3 angle ) -{ - -} - -void CMesh::SetRotationQuat( vec4 quaternion) -{ - -} - -void CMesh::SetMatrix( mat4 matrix ) -{ - memcpy(m_matrix,matrix,64); -} - -void CMesh::SetScale( vec3 scale ) -{ - -} - -void CMesh::SetVertexBuffer( IVertexBuffer *pBuffer ) -{ - m_pVertexBuffer = (CVertexBuffer*)pBuffer; -} - -void CMesh::SetIndexBuffer( IIndexBuffer *pBuffer ) -{ - m_pIndexBuffer = (CIndexBuffer*)pBuffer; -} - -void CMesh::SetMaterial( IMaterial *pMaterial ) -{ - if (pMaterial == 0) - return; - m_material = pMaterial->m; -} - -CUtlVector g_drawnMeshes; - -void CMesh::Draw() -{ - g_drawnMeshes.AppendTail(*this); -} - -void IMeshRenderer::Init() -{ - CUtlVector shaders(2); - for (auto &shader: shaders) - { - shader.m_shaderModule = NULL; - } - shaders[0].Create("gfx/mesh_vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaders[1].Create("gfx/mesh_frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - CUtlVector bindings(2); - bindings[0] = {}; - bindings[0].binding = 0; - bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - bindings[0].descriptorCount = 1; - bindings[1] = {}; - bindings[1].binding = 1; - bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - bindings[1].descriptorCount = 1024; - CUtlVector formats(1); - formats[0] = VK_FORMAT_R16G16B16A16_SFLOAT; - g_meshPipeline.Create(shaders, bindings, 76, formats); - shaders[1].Destroy(); - shaders[0].Destroy(); - - CUtlVector pools; - for (auto &binding: bindings) - { - VkDescriptorPoolSize dps = {}; - dps.type = binding.descriptorType; - dps.descriptorCount = binding.descriptorCount; - pools.AppendTail(dps); - } - - VkDescriptorPoolCreateInfo poolInfo = {}; - poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.poolSizeCount = pools.GetSize(); - poolInfo.pPoolSizes = pools.GetData(); - poolInfo.maxSets = 1; - vkCreateDescriptorPool(g_vkDevice, &poolInfo, NULL, &g_meshDescriptorPool); - - VkDescriptorSetAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - allocInfo.descriptorPool = g_meshDescriptorPool; - allocInfo.descriptorSetCount = 1; - allocInfo.pSetLayouts = &g_meshPipeline.m_descriptorSetLayout; - vkAllocateDescriptorSets(g_vkDevice, &allocInfo, &g_meshDescriptorSet); - - - VkPhysicalDeviceProperties properties{}; - vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &properties); - VkSamplerCreateInfo samplerInfo{}; - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.anisotropyEnable = VK_FALSE; - samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy; - samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; - samplerInfo.unnormalizedCoordinates = VK_FALSE; - samplerInfo.compareEnable = VK_FALSE; - samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; - samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerInfo.mipLodBias = 0.0f; - samplerInfo.minLod = 0.0f; - samplerInfo.maxLod = 0.0f; - vkCreateSampler(g_vkDevice, &samplerInfo, nullptr, &g_meshSampler); -} - -void IMeshRenderer_PrepassNoMSAA() -{ - -}; - -void IMeshRenderer_Prepass() -{ - -}; - -void IMeshRenderer_EdgeDetection() -{ - -}; - -void IMeshRenderer_Light() -{ - -}; - -void IMeshRenderer_Combine() -{ - -}; - -void IMeshRenderer::Frame( float fDelta ) -{ - CUtlVector writes(2); - for (auto &write: writes) - { - write = {}; - write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write.dstSet = g_meshDescriptorSet; - write.dstArrayElement = 0; - } - - VkDescriptorBufferInfo bufferInfo = {}; - bufferInfo.buffer = g_cameraProperties.m_buffer; - bufferInfo.offset = 0; - bufferInfo.range = g_cameraProperties.m_nSize; - writes[0].dstBinding = 0; - writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - writes[0].descriptorCount = 1; - writes[0].pBufferInfo = &bufferInfo; - - CUtlVector textures; - textures.Reserve(g_textures.GetSize()); - for (ITexture *t: g_textures) - { - CTexture *texture = (CTexture*)t; - VkDescriptorImageInfo image = {}; - image.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - image.imageView = texture->image.m_imageView; - image.sampler = g_meshSampler; - textures.AppendTail(image); - }; - textures[0].sampler = g_invalidTextureSampler; - writes[1].dstBinding = 1; - writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writes[1].descriptorCount = textures.GetSize(); - writes[1].pImageInfo = textures.GetData(); - vkUpdateDescriptorSets(g_vkDevice, writes.GetSize(), writes.GetData(), 0, NULL); - - - VkImageMemoryBarrier barriers[4] = { - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .image = g_meshColor.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - }, - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .image = g_meshColorMSAA.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - }, - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - .image = g_meshDepth.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1} - }, - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - .image = g_meshDepthMSAA.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1} - }, - }; - vkCmdPipelineBarrier(g_vkCommandBuffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - 0, 0, NULL, 0, NULL, 4, barriers); - - VkRenderingAttachmentInfo colorAttachment = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = g_meshColorMSAA.m_imageView, - .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT, - .resolveImageView = g_meshColor.m_imageView, - .resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .clearValue = {.color = {0.0f, 0.0f, 0.0f, 1.0f}}, - }; - VkRenderingAttachmentInfo depthAttachment = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = g_meshDepthMSAA.m_imageView, - .imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - .resolveMode = VK_RESOLVE_MODE_MIN_BIT, - .resolveImageView = g_meshDepth.m_imageView, - .resolveImageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .clearValue = {.depthStencil = {.depth = 1}}, - }; - - VkRenderingInfo renderInfo = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = {{0, 0}, {g_nWindowWidth, g_nWindowHeight}}, - .layerCount = 1, - .colorAttachmentCount = 1, - .pColorAttachments = &colorAttachment, - .pDepthAttachment = &depthAttachment, - }; - vkCmdBeginRendering(g_vkCommandBuffer, &renderInfo); - - vkCmdSetRasterizerDiscardEnable(g_vkCommandBuffer, VK_FALSE); - vkCmdSetDepthBiasEnable(g_vkCommandBuffer, VK_FALSE); - _vkCmdSetPolygonModeEXT(g_vkCommandBuffer, VK_POLYGON_MODE_FILL); - vkCmdSetCullMode(g_vkCommandBuffer, VK_CULL_MODE_BACK_BIT); - vkCmdSetFrontFace(g_vkCommandBuffer, VK_FRONT_FACE_COUNTER_CLOCKWISE); - - vkCmdSetDepthTestEnable(g_vkCommandBuffer, VK_TRUE); - vkCmdSetDepthWriteEnable(g_vkCommandBuffer, VK_TRUE); - vkCmdSetDepthCompareOp(g_vkCommandBuffer, VK_COMPARE_OP_LESS); - vkCmdSetStencilTestEnable(g_vkCommandBuffer, VK_FALSE); - - _vkCmdSetRasterizationSamplesEXT(g_vkCommandBuffer, VK_SAMPLE_COUNT_4_BIT); - VkSampleMask sampleMask = 0xFFFFFFFF; - _vkCmdSetSampleMaskEXT(g_vkCommandBuffer, VK_SAMPLE_COUNT_4_BIT, &sampleMask); - _vkCmdSetAlphaToCoverageEnableEXT(g_vkCommandBuffer, VK_FALSE); - - VkViewport viewport = {0, 0, (float)g_nWindowWidth, (float)g_nWindowHeight, 0.0f, 1.0f}; - VkRect2D scissor = {{0, 0}, {g_nWindowWidth, g_nWindowHeight}}; - vkCmdSetViewportWithCount(g_vkCommandBuffer, 1, &viewport); - vkCmdSetScissorWithCount(g_vkCommandBuffer, 1, &scissor); - - vkCmdSetPrimitiveTopology(g_vkCommandBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - vkCmdSetPrimitiveRestartEnable(g_vkCommandBuffer, VK_FALSE); - - VkVertexInputBindingDescription2EXT binding = { - .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, - .binding = 0, - .stride = 20, - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - .divisor = 1, - }; - VkVertexInputAttributeDescription2EXT attributes[2] = { - { - VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, - NULL, - 0, 0, - VK_FORMAT_R32G32B32_SFLOAT, - 0 - }, - { - VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, - NULL, - 1, 0, - VK_FORMAT_R32G32_SFLOAT, - 12 - } - }; - _vkCmdSetVertexInputEXT(g_vkCommandBuffer, 1, &binding, 2, attributes); - - VkBool32 blendEnable = VK_FALSE; - VkColorBlendEquationEXT blendEquation = { - VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_OP_ADD, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD - }; - VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - _vkCmdSetColorBlendEnableEXT(g_vkCommandBuffer, 0, 1, &blendEnable); - _vkCmdSetColorBlendEquationEXT(g_vkCommandBuffer, 0, 1, &blendEquation); - _vkCmdSetColorWriteMaskEXT(g_vkCommandBuffer, 0, 1, &writeMask); - - vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_meshPipeline.m_pipeline); - vkCmdBindDescriptorSets(g_vkCommandBuffer,VK_PIPELINE_BIND_POINT_GRAPHICS, g_meshPipeline.m_layout, 0, 1, &g_meshDescriptorSet, 0, NULL); - for (auto &mesh: g_drawnMeshes) - { - VkDeviceSize offset = 0; - uint32_t textureID = mesh.m_material.albedo; - vkCmdPushConstants(g_vkCommandBuffer, g_meshPipeline.m_layout, VK_SHADER_STAGE_ALL, 0, 64, &mesh.m_matrix); - vkCmdPushConstants(g_vkCommandBuffer, g_meshPipeline.m_layout, VK_SHADER_STAGE_ALL, 64, 4, &textureID); - vkCmdBindVertexBuffers(g_vkCommandBuffer, 0, 1, &mesh.m_pVertexBuffer->m_buffer.m_buffer, &offset); - if (mesh.m_pIndexBuffer) - { - vkCmdBindIndexBuffer( - g_vkCommandBuffer, - mesh.m_pIndexBuffer->m_buffer.m_buffer, - 0, - VK_INDEX_TYPE_UINT32 - ); - vkCmdDrawIndexed(g_vkCommandBuffer, mesh.m_pIndexBuffer->m_buffer.m_nSize/4, 1, 0, 0, 0); - } - else - { - vkCmdDraw(g_vkCommandBuffer, mesh.m_pVertexBuffer->m_buffer.m_nSize/20,1,0,0); - } - } - vkCmdEndRendering(g_vkCommandBuffer); - - VkImageMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = g_meshColor.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - }; - - vkCmdPipelineBarrier(g_vkCommandBuffer, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, NULL, 0, NULL, 1, &barrier); - - g_drawnMeshes = CUtlVector(); - -} - - -IMesh *IMeshRenderer::CreateMesh() -{ - CMesh *mesh = new CMesh; - return mesh; -} - -void IMeshRenderer::Destroy( IMesh *pModel ) -{ - -} - diff --git a/engine/vk_postprocessing.cpp b/engine/vk_postprocessing.cpp deleted file mode 100644 index 7e65a23..0000000 --- a/engine/vk_postprocessing.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "rendering.h" -#include "vk_helper.h" -#include "vk_video.h" -#include "vulkan/vulkan_core.h" - -vk_shader_t post_agxShader = {}; -vk_comppipeline_t post_agxPipeline = {}; -VkDescriptorPool post_descriptorPool; -VkDescriptorSet post_descriptorSet; - -void IPostProcessRenderer::Init() -{ - post_agxShader.Create("gfx/agx_comp.spv", VK_SHADER_STAGE_COMPUTE_BIT); - CUtlVector bindings = { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, - } - }; - post_agxPipeline.Create(post_agxShader, bindings, 0); - - CUtlVector pools; - for (auto &binding: bindings) - { - VkDescriptorPoolSize dps = {}; - dps.type = binding.descriptorType; - dps.descriptorCount = binding.descriptorCount; - pools.AppendTail(dps); - } - - VkDescriptorPoolCreateInfo poolInfo = {}; - poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.poolSizeCount = pools.GetSize(); - poolInfo.pPoolSizes = pools.GetData(); - poolInfo.maxSets = 1; - vkCreateDescriptorPool(g_vkDevice, &poolInfo, NULL, &post_descriptorPool); - - VkDescriptorSetAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - allocInfo.descriptorPool = post_descriptorPool; - allocInfo.descriptorSetCount = 1; - allocInfo.pSetLayouts = &post_agxPipeline.m_descriptorSetLayout; - vkAllocateDescriptorSets(g_vkDevice, &allocInfo, &post_descriptorSet); - -} - -void IPostProcessRenderer::Frame(float fDelta) -{ - - CUtlVector barriers = { - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - .image = g_meshColor.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - }, - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = g_swapchainImage, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - } - }; - - vkCmdPipelineBarrier(g_vkCommandBuffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - 0, 0, NULL, 0, NULL, barriers.GetSize(), barriers.GetData()); - - CUtlVector writes(2); - for (auto &write: writes) - { - write = {}; - write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write.dstSet = post_descriptorSet; - write.dstArrayElement = 0; - } - - VkDescriptorImageInfo dii1 = { - .imageView = g_meshColor.m_imageView, - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - .sampler = NULL, - }; - VkDescriptorImageInfo dii2 = { - .imageView = g_swapchainImageView, - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .sampler = NULL, - }; - - writes[0].dstBinding = 0; - writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - writes[0].descriptorCount = 1; - writes[0].pImageInfo = &dii1; - writes[1].dstBinding = 1; - writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - writes[1].descriptorCount = 1; - writes[1].pImageInfo = &dii2; - vkUpdateDescriptorSets(g_vkDevice, writes.GetSize(), writes.GetData(), 0, NULL); - - vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, post_agxPipeline.m_pipeline); - vkCmdBindDescriptorSets(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, post_agxPipeline.m_layout, 0, 1, &post_descriptorSet, 0, 0); - vkCmdDispatch(g_vkCommandBuffer, (g_nWindowWidth+31)/32, (g_nWindowHeight+31)/32, 1); - - barriers = { - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = g_meshColor.m_image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - }, - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - .image = g_swapchainImage, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} - } - }; - - vkCmdPipelineBarrier(g_vkCommandBuffer, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, NULL, 0, NULL, barriers.GetSize(), barriers.GetData()); - -} diff --git a/engine/vk_video.cpp b/engine/vk_video.cpp index b4a8844..be0f21e 100644 --- a/engine/vk_video.cpp +++ b/engine/vk_video.cpp @@ -9,6 +9,19 @@ #include "vulkan/vulkan_core.h" #define STB_IMAGE_IMPLEMENTATION + +#if defined(__APPLE__) && defined(__MACH__) +#include "TargetConditionals.h" +#if TARGET_OS_IPHONE +// iOS +#define STBI_NO_THREAD_LOCALS +#else +// macOS +#endif +#else +// Other platforms +#define STBI_THREAD_LOCAL thread_local +#endif #include "stb_image.h" #define VULKAN_RENDERING_IMPLEMENTATION @@ -21,13 +34,58 @@ CameraProjection *g_cameraDataMap; mat4 g_cameraView; -IMaterial *g_pDefaultMaterial; -IMaterial *g_pCurrentMaterial; +IImage *g_meshDepth; +IImage *g_meshDepthMSAA; +IImage *g_meshColor; +IImage *g_meshColorMSAA; +class CVkGraphicsPipeline: public IGraphicsPipeline +{ +public: + vk_tripipeline_t m_pipeline; +}; -vk_image2d_t g_meshDepth; -vk_image2d_t g_meshDepthMSAA; -vk_image2d_t g_meshColor; -vk_image2d_t g_meshColorMSAA; +class CVkComputePipeline: public IComputePipeline +{ +public: + vk_comppipeline_t m_pipeline; +}; + +class CVkRayTracingPipeline: public IRayTracingPipeline +{ +public: +}; + +VkFormat IRenderer_FormatToVk( EImageFormat format ) +{ + switch (format) + { + case IMAGE_FORMAT_R8G8B8A8: return VK_FORMAT_R8G8B8A8_UNORM; + case IMAGE_FORMAT_R16G16B16A16: return VK_FORMAT_R16G16B16A16_UNORM; + case IMAGE_FORMAT_DEPTH: return VK_FORMAT_D32_SFLOAT; + default: return VK_FORMAT_R8G8B8A8_UNORM; + } +}; + +VkAttachmentLoadOp IRenderer_LoadOpVk( EAttachmentLoadMode mode ) +{ + switch (mode) + { + case ATTACHMENT_LOAD_MODE_DONT_CARE: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; + case ATTACHMENT_LOAD_MODE_CLEAR: return VK_ATTACHMENT_LOAD_OP_CLEAR; + case ATTACHMENT_LOAD_MODE_LOAD: return VK_ATTACHMENT_LOAD_OP_LOAD; + default: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } +} + +VkAttachmentStoreOp IRenderer_StoreOpVk( EAttachmentStoreMode mode ) +{ + switch (mode) + { + case ATTACHMENT_STORE_MODE_DONT_CARE: return VK_ATTACHMENT_STORE_OP_DONT_CARE; + case ATTACHMENT_STORE_MODE_STORE: return VK_ATTACHMENT_STORE_OP_STORE; + default: return VK_ATTACHMENT_STORE_OP_DONT_CARE; + } +} void IVulkan::Init() { @@ -65,15 +123,25 @@ void IVulkan::Init() g_cameraProperties.Create(sizeof(CameraProjection), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); g_cameraDataMap = (CameraProjection*)g_cameraProperties.Map(0, 64); - g_meshDepth.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT); - g_meshDepthMSAA.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT); - g_meshColor.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_SAMPLE_COUNT_1_BIT); - g_meshColorMSAA.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT); + g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 1); + g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 4); + g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 1); + g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 4); glm_mat4_identity(g_cameraView); - - IMeshRenderer::Init(); - IPostProcessRenderer::Init(); }; +void IVulkan::CreatePipelines() +{ + for (auto &step: g_StepPrepass) + step.pPipeline->Init(); + for (auto &step: g_StepMeshRendering) + step.pPipeline->Init(); + for (auto &step: g_StepShading) + step.pPipeline->Init(); + for (auto &step: g_StepPostProcessing) + step.pPipeline->Init(); + for (auto &step: g_StepUI) + step.pPipeline->Init(); +} void IVulkan::Frame() { @@ -87,19 +155,42 @@ void IVulkan::Frame() if (g_bConfigNotify) { - g_meshDepth.Destroy(); - g_meshDepthMSAA.Destroy(); - g_meshColor.Destroy(); - g_meshColorMSAA.Destroy(); - - g_meshDepth.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT); - g_meshDepthMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT); - g_meshColor.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_SAMPLE_COUNT_1_BIT); - g_meshColorMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT); + IRenderer::DestroyImage(g_meshDepth); + IRenderer::DestroyImage(g_meshDepthMSAA); + IRenderer::DestroyImage(g_meshColor); + IRenderer::DestroyImage(g_meshColorMSAA); + g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1); + g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4); + g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1); + g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4); } - IMeshRenderer::Frame(0); - IPostProcessRenderer::Frame(0); + for (auto &step: g_StepPrepass) + step.pPipeline->Frame(0); + IRenderer::Begin(g_nWindowWidth, g_nWindowHeight, + { + { + g_meshColor, + g_meshColorMSAA, + ATTACHMENT_LOAD_MODE_DONT_CARE, + ATTACHMENT_STORE_MODE_STORE, + } + }, + { + g_meshDepth, + g_meshDepthMSAA, + ATTACHMENT_LOAD_MODE_DONT_CARE, + ATTACHMENT_STORE_MODE_STORE, + }); + for (auto &step: g_StepMeshRendering) + step.pPipeline->Frame(0); + IRenderer::End(); + for (auto &step: g_StepShading) + step.pPipeline->Frame(0); + for (auto &step: g_StepPostProcessing) + step.pPipeline->Frame(0); + for (auto &step: g_StepUI) + step.pPipeline->Frame(0); }; void vk_shader_t::Create( const char *szPath, VkShaderStageFlagBits shaderStage ) @@ -384,27 +475,13 @@ void vk_image2d_t::Destroy() void CopyTo(struct vk_image2d_t *image); void CopyTo(struct vk_buffer_t *buffer); -void *CVertexBuffer::Map() +void *CVkBuffer::Map() { if (!m_pAllocated) m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize); return m_pAllocated; }; -void CVertexBuffer::Unmap() -{ - if (!m_pAllocated) - return; - m_buffer.Unmap(); - m_pAllocated = 0; -}; - -void *CIndexBuffer::Map() -{ - if (!m_pAllocated) - m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize); - return m_pAllocated; -}; -void CIndexBuffer::Unmap() +void CVkBuffer::Unmap() { if (!m_pAllocated) return; @@ -415,21 +492,9 @@ void CIndexBuffer::Unmap() CUtlVector g_textures; CUtlVector g_newtextures; -uint32_t ITextureManager::GetTexture(ITexture *pTexture) -{ - uint32_t i = 0; - for (ITexture *texture: g_textures) - { - if (texture == pTexture) - return i; - i++; - }; - return 0; -} - ITexture *ITextureManager::LoadTexture( void *pData, uint32_t X, uint32_t Y, uint32_t numChannels ) { - CTexture *pTexture = new CTexture; + CVkTexture *pTexture = new CVkTexture; *pTexture = {}; VkDeviceSize imageSize = X*Y*4; vk_buffer_t gpu_buffer = {}; @@ -562,28 +627,265 @@ ITexture *ITextureManager::LoadTexture( const char *szName ) return pTexture; }; -IMaterial *IRenderer::LoadMaterial( const char *szMaterial ) -{ - FileHandle_t file = IFileSystem::Open(szMaterial, IFILE_READ); - IMaterial *pMaterial = new IMaterial; - if (!file) - { - return g_pDefaultMaterial; - } - IFileSystem::Close(file); +IStorageBuffer *IRenderer::CreateStorageBuffer( uint32_t uSize ) +{ + CVkBuffer *pBuffer = new CVkBuffer(); + pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + return pBuffer; } + +IUniformBuffer *IRenderer::CreateUniformBuffer( uint32_t uSize ) +{ + CVkBuffer *pBuffer = new CVkBuffer(); + pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + return pBuffer; +} + + IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize ) { - CVertexBuffer *pBuffer = new CVertexBuffer(); + CVkBuffer *pBuffer = new CVkBuffer(); pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); return pBuffer; } IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize ) { - CIndexBuffer *pBuffer = new CIndexBuffer(); + CVkBuffer *pBuffer = new CVkBuffer(); pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); return pBuffer; } + +IImage *IRenderer::CreateImage( EImageFormat format, uint32_t usage, uint32_t nWidth, uint32_t nHeight, uint32_t nSamples ) +{ + VkFormat vkformat; + VkImageUsageFlags vkusage; + CVkImage *pImage = new CVkImage(); + VkSampleCountFlagBits samples; + switch (format) + { + case IMAGE_FORMAT_R8G8B8A8: vkformat = VK_FORMAT_R8G8B8A8_UNORM; break; + case IMAGE_FORMAT_R16G16B16A16: vkformat = VK_FORMAT_R16G16B16A16_UNORM; break; + case IMAGE_FORMAT_DEPTH: vkformat = VK_FORMAT_D32_SFLOAT; break; + default: return 0; + }; + + if (usage&IMAGE_USAGE_COLOR_ATTACHMENT) vkusage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if (usage&IMAGE_USAGE_DEPTH_ATTACHMENT) vkusage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (usage&IMAGE_USAGE_STORAGE) vkusage |= VK_IMAGE_USAGE_STORAGE_BIT; + + switch (nSamples) + { + case 1: samples = VK_SAMPLE_COUNT_1_BIT; break; + case 4: samples = VK_SAMPLE_COUNT_4_BIT; break; + default: samples = VK_SAMPLE_COUNT_1_BIT; break; + } + pImage->m_image.Create(nWidth, nHeight, vkformat, vkusage, samples); + return pImage; +}; +void IRenderer::DestroyBuffer( IBuffer *pBuffer ) +{ + CVkBuffer *pVkBuffer = (CVkBuffer*)pBuffer; + if (pVkBuffer) + pVkBuffer->m_buffer.Destroy(); +} + +void IRenderer::DestroyImage( IImage *pImage ) +{ + CVkImage *pVkImage = (CVkImage*)pImage; + if (pVkImage) + pVkImage->m_image.Destroy(); +} + + + +void IRenderer::SetConstants( uint32_t nSize, uint32_t nOffset, void *pData ) +{ + +} + +void IRenderer::Barrier( EBarrierStage stageIn, uint32_t stageOut, CUtlVector buffers, CUtlVector images ) +{ + +} + +void IRenderer::BindData( uint32_t binding, IBuffer *pBuffer, IImage* pImage) +{ + +} + + + +void IRenderer::BindPipeline( IPipeline *pPipeline ) +{ + if (!pPipeline) + return; + if (pPipeline->type == PIPELINE_TYPE_RASTERIZATION) + { + CVkGraphicsPipeline *pVkPipeline = (CVkGraphicsPipeline*)pPipeline; + vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkPipeline->m_pipeline.m_pipeline); + } +} + + +void IRenderer::Begin( uint32_t nWidth, uint32_t nHeight, CUtlVector attachments, RenderingDepthAttachment_t depth ) +{ + CUtlVector colorAttachments = {}; + VkRenderingAttachmentInfo depthAttachment = {}; + for (auto &attachment: attachments) + { + VkRenderingAttachmentInfo vkattachment = {}; + vkattachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + CVkImage *pImage = (CVkImage*)attachment.pTemporary; + CVkImage *pTemporary = (CVkImage*)attachment.pTemporary; + if (attachment.pTemporary) + { + vkattachment.imageView = pTemporary->m_image.m_imageView; + vkattachment.resolveImageView = pImage->m_image.m_imageView; + vkattachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + vkattachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } else + { + vkattachment.imageView = pImage->m_image.m_imageView; + vkattachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + vkattachment.loadOp = IRenderer_LoadOpVk(attachment.loadMode); + vkattachment.storeOp = IRenderer_StoreOpVk(attachment.storeMode); + colorAttachments.AppendTail(vkattachment); + } + depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + CVkImage *pDepthImage = (CVkImage*)depth.pTemporary; + CVkImage *pDepthTemporary = (CVkImage*)depth.pTemporary; + if (depth.pTemporary) + { + depthAttachment.imageView = pDepthTemporary->m_image.m_imageView; + depthAttachment.resolveImageView = pDepthImage->m_image.m_imageView; + depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + depthAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + } else + { + depthAttachment.imageView = pDepthImage->m_image.m_imageView; + depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + } + depthAttachment.loadOp = IRenderer_LoadOpVk(depth.loadMode); + depthAttachment.storeOp = IRenderer_StoreOpVk(depth.storeMode); + + VkRenderingInfo renderInfo = { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .renderArea = {{0, 0}, {nWidth, nHeight}}, + .layerCount = 1, + .colorAttachmentCount = (uint32_t)colorAttachments.GetSize(), + .pColorAttachments = colorAttachments.GetData(), + .pDepthAttachment = &depthAttachment, + }; + vkCmdBeginRendering(g_vkCommandBuffer, &renderInfo); +} + +void IRenderer::ResetState() +{ + +} + +void IRenderer::SetDepthMode( EDepthMode mode ) +{ + +} + +void IRenderer::Draw( IVertexBuffer *pVertex, IIndexBuffer *pIndex ) +{ + +} + +void IRenderer::End() +{ + vkCmdEndRendering(g_vkCommandBuffer); +} + + + +IGraphicsPipeline *IRenderer::CreateGraphicsPipeline( + CUtlVector shaders, + CUtlVector inputs, + uint32_t nConstantsSize, + CUtlVector outputFormats +) +{ + CVkGraphicsPipeline *pipeline = new CVkGraphicsPipeline; + pipeline->type = PIPELINE_TYPE_RASTERIZATION; + CUtlVector vkshaders(shaders.GetSize()); + CUtlVector vkbindings(inputs.GetSize()); + CUtlVector vkformats(outputFormats.GetSize()); + + for ( uint32_t i = 0; i < vkshaders.GetSize(); i++ ) + { + VkShaderStageFlagBits flags; + if (shaders[i].type == SHADER_TYPE_VERTEX) flags = VK_SHADER_STAGE_VERTEX_BIT; + if (shaders[i].type == SHADER_TYPE_FRAGMENT) flags = VK_SHADER_STAGE_FRAGMENT_BIT; + vkshaders[i].Create(shaders[i].szPath, flags); + } + for ( uint32_t i = 0; i < vkbindings.GetSize(); i++ ) + { + vkbindings[i].binding = inputs[i].binding; + vkbindings[i].descriptorCount = 1; + if (inputs[i].type == SHADER_INPUT_TYPE_IMAGE) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + if (inputs[i].type == SHADER_INPUT_TYPE_UNIFORM_BUFFER) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + if (inputs[i].type == SHADER_INPUT_TYPE_STORAGE_BUFFER) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + if (inputs[i].type == SHADER_INPUT_TYPE_TLAS) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; + if (inputs[i].type == SHADER_INPUT_TYPE_TEXTURES) + { + vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + vkbindings[i].descriptorCount = 1024; + } + } + for ( uint32_t i = 0; i < vkformats.GetSize(); i++ ) + { + vkformats[i] = IRenderer_FormatToVk(outputFormats[i]); + } + pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, vkformats); + return 0; +}; + + +CUtlVector g_StepPrepass; +CUtlVector g_StepMeshRendering; +CUtlVector g_StepShading; +CUtlVector g_StepPostProcessing; +CUtlVector g_StepUI; + +CRenderingStep::CRenderingStep() +{ + +} + +CRenderingStep::CRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + +} + +CPrepassRenderingStep::CPrepassRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + g_StepPrepass.AppendTail({pfn(), szStepName}); +} + +CMeshRenderingStep::CMeshRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + g_StepMeshRendering.AppendTail({pfn(), szStepName}); +} + +CShadingRenderingStep::CShadingRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + g_StepShading.AppendTail({pfn(), szStepName}); +} + +CPostProcessingRenderingStep::CPostProcessingRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + g_StepPostProcessing.AppendTail({pfn(), szStepName}); +} + +CUIRenderingStep::CUIRenderingStep(const char *szStepName, CreateRenderStepFn pfn) +{ + g_StepUI.AppendTail({pfn(), szStepName}); +} + diff --git a/public/vk_video.h b/engine/vk_video.h similarity index 98% rename from public/vk_video.h rename to engine/vk_video.h index 3d5c37a..e0dc5b2 100644 --- a/public/vk_video.h +++ b/engine/vk_video.h @@ -97,6 +97,7 @@ interface IVulkan { public: static void Init(); + static void CreatePipelines(); static void Frame(); static void Deinit(); }; diff --git a/engine/vk_videosdl.cpp b/engine/vk_videosdl.cpp index 1e368fd..c50f9e3 100644 --- a/engine/vk_videosdl.cpp +++ b/engine/vk_videosdl.cpp @@ -189,6 +189,8 @@ EInputKey ISDL_KeyName(SDL_Keycode key) { switch(key) { + case SDLK_ESCAPE: return KEY_ESCAPE; + case SDLK_1: return KEY_1; case SDLK_2: return KEY_2; case SDLK_3: return KEY_3; @@ -380,7 +382,19 @@ void IVideo::Init() IVideo_SwapchainInit(); IVulkan::Init(); +} +void IInput::SetMouseMode( EMouseMode mode ) +{ + switch (mode) + { + case MOUSE_MODE_GAME: + SDL_SetWindowRelativeMouseMode(g_window, true); + return; + default: + SDL_SetWindowRelativeMouseMode(g_window, false); + return; + } } void IVideo_HandleEvents() @@ -389,6 +403,7 @@ void IVideo_HandleEvents() while (SDL_PollEvent(&event)) { SDL_KeyboardEvent *key = &event.key; + SDL_MouseMotionEvent *motion = &event.motion; switch (event.type) { case SDL_EVENT_WINDOW_RESIZED: @@ -398,16 +413,25 @@ void IVideo_HandleEvents() break; case SDL_EVENT_KEY_DOWN: if (!key->repeat) - IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP); + IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN); break; case SDL_EVENT_KEY_UP: key = &event.key; - SDL_Log("Key Up: %s", SDL_GetKeyName(key->key)); + if (!key->repeat) + IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP); + break; + case SDL_EVENT_MOUSE_MOTION: + IInput::AxisEvent(AXIS_MOUSE_X, motion->yrel*0.022); + IInput::AxisEvent(AXIS_MOUSE_Y, -motion->xrel*0.022); break; } }; }; +void IVideo::CreatePipelines( ) +{ + IVulkan::CreatePipelines(); +}; void IVideo::Frame( float fDelta ) { diff --git a/fgui/__build.c b/fgui/__build.c deleted file mode 100644 index 57bce9e..0000000 --- a/fgui/__build.c +++ /dev/null @@ -1,37 +0,0 @@ - - -char* fgui_lib = 0; -void fgui_build(struct build_data b) -{ - char* files[] = { - "fgui/fgui.cpp", - NULL, - }; - struct C_Macro macros[] = { - (struct C_Macro){"TIER0_IMPLEMENTATION","1"}, - NULL, - }; - - - struct project p = { - .b = &b, - .files = files, - .name = "fgui", - }; - - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - .macros = macros, - }); - char* libs[] = { - "c", - NULL, - }; - - fgui_lib = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_STATIC, - .libs = libs, - }); -} \ No newline at end of file diff --git a/fpc/fpc.dSYM/Contents/Info.plist b/fpc/fpc.dSYM/Contents/Info.plist new file mode 100644 index 0000000..76f7ffc --- /dev/null +++ b/fpc/fpc.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.fpc + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/fpc/fpc.dSYM/Contents/Resources/DWARF/fpc b/fpc/fpc.dSYM/Contents/Resources/DWARF/fpc new file mode 100644 index 0000000000000000000000000000000000000000..05d28ef4167f00ed292c74ad09a2090111c44541 GIT binary patch literal 144200 zcmeFa33yf2)i-|5+4r2>2_XR#LWBzf4vByR zj=`x`Eyj6*inB$l(N;xUTeLRXsx>OMwpQguYpbp8|F`yD>rS}|yzg7v@Be+x^W^Nk zhQ0RM^Iq%hv+vKp`uOiDmSro;veNLMivNrKc<^6egxUE2$Iv^~>hBc2bIG*9OOO5Y z)%}VXZ)?7;mgV3de-8eM-^#SCG9nJPti8i5t2d&v@n2ChPl9C1U0VMnxSqaDl zkmPJcCKVNnO3D|-6LtEQc$`2kBJ_{4>c5JLaLvXr0|*l3?ScLzFZ1Rok1ravET7dF z3szLD3$I_gE`myw*K)s+H-IXd|6>Nrc0Sit06W>!Jltly{Kj#WcMYqiTXQ(x-Y|ckNt z)LU#jQ1LIozxrcQ8)`h{LI<)t=~KPel*v15(k=zKKy_<3_mW*%=^)3Vx_ zx0tx_$L+dzvH?j>tSpkV0vSP{lcy~>&M?t4WE;MN%w1+kv)?x`%|oOg&AIf4`mb5K zetE^Jm31`+PA>0-Q#Cs#R}MP}L|)a}s=DPh>)Pq}!r4Z@=59v73-@&(h|v*w%a*Mr zRAPCTUvA`8226tG7+;*= zw?|i=Ke}EL+luXFi+)v0m#(eZ(7wC_DviA5+-V0i9hp2#nmV&Y{VrH$Z(?w_qDITpT2D5 zopZF&@26keozCZm>p#!`)WCmg;6F9+pBng24g9AD{uwnud-wr%qt({S>}&flTn{6j zR`?=@8}kfY%5XEoXE5Bt@MR2_4L1C@GhE5=lMH7LG4!_?ZX9ahzcbu6+`zq{1nFlT zW#9saGe;Zvc!rA^K7-*(hOsTx>6;n8li?PI_c7eY@E;gHh=L<(bwveH{-H4j9t$`F zgkpy0FkH{@8O-0va3jNQlT7-n8Ma_gko=zsKg0jUaMKh+_h2MY{(Bhi&9F7y(DNA% zF+5G+8HT=);Yx-#Fx<%ScNlJF_;H3?7=DT2HikcDICG|v-`i*OD`2>U;d+K^8E$5{ ziQyK8_cCmi7Bko;pq%#!t|p0Jc;3AhEHd>nc?jWw=jG+!)*-j zXV{u$wO?`ODy;e!m{%5dh%M&5G_?^$Bt&lzrGcn}RqB+{o~68E#{^3+!Xv9!)0wScaP!UdHf# zp<{lg{&0}tYd|MBw8Nyom-!p-HSjMP-ovof75tuMi9fSD!{gY$na6M$!^beZg5l#C z-pKH23}4Lf8isFTcnib37`}#K>v5ysT?}V4yqDo&3`>4<8Gf1Rr!m~d@G6EsWB43~ zrM%ZOEaln7u$O7-qlMw#4DV-H>f`f-^w~c!`b&AnF+76P&t-TD!>2JU<=M!vl;>iG zPh|e<8Lnpd$9qkF8yG&o@OFkjXZR+DeNPzv`xy>0{4B$H4F8hhVun9txQyYyGF-`U z2K;r@f9e^|Ww?=HsqZF+r9QIZkE8WT>SGwgQoeBvOa07dSmZ5ZSn6jZ!(%!B>lr?d zV9dF`{U*Of1gF7`%J6!Ivl+gg;Sj^O0`3Y$3$jf52N}-nZr~p>970Itd6nU&o(BGa z;bu<%8N+Q1+mJ)@5B4zpT^TN5`9l~kX8v&u?`L?fz?mlfB8KIC(YF~s$n=#$uQB{* zOM2eVH8I@G`^6g>F4$rCA7a=F8Td7Zn{o~OnZN@K97MUOd~M7>hT+gaLtnsfCc|ek ze30ceFW(7OhWK6@A*DsX>8pUQA$F9R=PxS8`? z#c(~tTN!R*_-=;V7=D`JmO(~dE5l_Bf6Q*`n;Us#)XFe zYN1ay@Lqk5XOPd5CIG2FPo!0!m1%l8k4%Z@Vip=dXf*F4I=$1&VE(!eVi zZejZQ3>S0%yHn`gzg}XvAjhQtl;KLI_vmf%3vvG{WY}VOKErLCel^3HkYi&$xJ+Q~ zk9RX%%=8uwTUI02*KZlFUuM#$_o4hDXoP`BGn|=k;4+4rx%}&dpXt{z9OC+WhT(%; zKWz-RG5_BgE?_tZ<)r+ZPc`{XXSnR!20nw~P?dpqFuaHP9~HRT(BEaah3US2rhePz z8u|=|n@bJ6p5dkw415Q}mCXN&z*iW0H;iNIAH|m$cqYSpE;sO*3};?q;9U$KX(F?^cvHyHYb3|nUy_+|}5UmpL@F}#Q2j~T9H{rX^D zrScUpJcr>-p3l}Y+;+Z^el3&m8G=@W5-qRUA$n@_p z+;pBv{{+L848O~8CYL`Q^So{!rcY#e|74TCn&D=KFK4)HilINraEReg8E)hGAu!m; z-^1{5hAT&!^m7?5V0azFp}B^BC&L!QZ!+A(O!D^3Gw@7?D|vj>F>G=FyMf_G9uGfact4MyPb57;+p?@I^m~$D z%y6-Wu^GZ2(H9XMuq=6BU%~Lk*9^Um;p-Vbhu~Bs+;8aH35KBJsRq81`HPwVI}BGc zd>g~{4ByZ23Wn*;Y)FbP68w0Qv!G_( z%FR_vSJg~kUt3#40;35#VlWaas#oE4eMNQEs#Q3jw08B%x~gzZvK(g=iH02rL=jlk zju;|3$CkZJ7d}ZLL5LP2F-1gF(!AnicE}Ntksy3#gwRpas9qg%L}VlgA9p-zxeASr z>MC1UP|?1sp?s97NSG?BH*Tz0zG}_Vs#O&ms@CeWT1Y!S~=He*W`lS`e>jNuQ zb<60DdVY0%eT?jd`s7qZ@9{Hcl&xKJI(lEU)nXMjz0)M3zPT`5cnqBmTUoVg<>s2T zI5V;?d_1%-iOGWda$M3#hQQ99$yr8_Q7s~<*wm4Bi1MKmnw~N)qQ78F%4A9;FXH$a z6(>|xuU%6SrUEAEe=!UZ^&;6ubn7JBh-OJUNo+}DG&lm@h}_r~i_tbxNrg#;#d1ap zept@KWg4xJ!-KR z^l^1Hh2she3krA;9znvRm)0y_S=TOQoVI0!g)^qFU%6`8!f@5{nwTk-=H0?%^KM58 zXb#p1;wRhHRV(WfW?7zn%I0*qrhyV|h}iL~(?qI0X>-Pl?U*GZB~kuix(msVD%YX> zsFYawaSaz|1nzUAB9*tQ^V_Q8+j-*an-BG^ID>}*-kr$_U1RJYFd_5ed=Or+Au1*5;5#)ZD zZWk{w+73x8ErB^{?$PBsVJ1$t15U~uGc`!BhX3dxp^VP+wngS~kb4)wT_;#4W_Q}SyPd8>UNdgpX-WUebjA?UWLeE^eHXd3~Q@wuex|JIuOlzu^&0V>4ZPnUM%y?4W zs#x6OirTd`;9gv@8Xg?VYH`Kd8je;hDJ+a`f!FCdtZ?k{C3V<5*HkQAxx5bMJXOun zOKGDVv4JDY^4Pg6>&}R?jm`X3STL==zNT*3?3$`&CD=BS4EAUxVd$8=sA}b^PSb0K zWa$^wtX{LBM&}>vHm zZdV&|3roy00DKZ5m?o17(Q84h-NKp5`WCx#R4t6IjIsFY4e&0t&$D{N0>c&YMIZ_CfrnJ z(#1M%6+SYxJ5JJ(-f<}+rd4vqBg^g)DU+PL13e|rj40cG?Mi-jL5|Nl6H9Tkr-Ot2_&}qVtq@P#$)G}vg1~6C^2h599L0CTt&yvz=x*r+het@fut2R)n}C9E6UZ; z88m@KQ)jGMUl*31kc?q*)vEO|vv531p;_fPA6{bPS&p57okX}MM!AxeWo5}&$4y(d ztP@G&Xdk2tq<0(h3ghw_e;huV=G4-uijF6b!op4K!ZoXl3XA5SRfnyTepj|BTH;ui zF*DZGZ;J9@5J#-5cv)jks5+x2j?pw#Jl9ygZHlt-k{Qo*^uiTu)~{NIJ=>bq^-!0Z zD|xQtNIOzDjwQJ<9kV|ufvdJ^RrPvoYimxxhG*?2J@|P{9X@&D7&?54_@(af{L%R& zId9z3^*<<0T>2v`PF#}1=oeYi{`;y$k{*#(5$?k%l(1C&_ti=ea74-_q&b|5wCw%2 z`z5WaN2UxI52wNZNP#2G|FGHrPjWxP%&SY{SD&PVDn`L$k6*C9uC8Y77zA;vOZ;{| z@}jmwesKI#k}Mo!43x-w(n1(aP!JOszx2 zOlULJ#?WT3Sr;~(?Pz0W*3?$5UlmV|zCkM*Bbj3jqZyi)vUMyd%6Tj^Fky~a&yyJg zV_^0kp3A(TIy_%w$F@xNbe&`!VJ0JL&cY&7)d>mWroWDrjbrOf+c?IE1|6xJoVyc! zBNJnXszx|E(K5nwI0f4?cA{I1A=9CDF+82<7sGWp4U@5UqGQ6`-JzZde4Xf;zveXS&54jp?8ZLU=^wgnCOlo5t?k6YZ-xSm%-)u8K=S4k5EQ zi;VW_;j;riUJBl7vojWQrvuI^w+8+>Wu6JE&gT zlN_7cXm74Q_Mkz1 z!jG&E4XwZe3>qEsqZ15P#hSC~mXRNtT;DK_v7A~J>o$u4MDa3EU<=WK%K!ZRrw0C) zHEsrG4P` zf`rtlkQuH~^F5tu&Qv7J&_wW6| z?q^$HoPXh$K-wSeEbcq;JDKNf`eMbCFZRy*z)`qj?(JtXzuI&DPrO*Y^Wx}ps>U>(L>X;gS&|%6H$Vd-}h>Iu5tIql&yrkJnSytz4(#=|MhzMPtNFd(oe1=q;JJ@EAyI0&D!$t z^4Bg~^lG>33AyIATc%9?^8E*<4!rN9Pl{fhb~_=Tzu`{{j~cRY!z~5(-`eyatR;hQ2n>xpJyq(@DH@o)DUcg`LTB^FqaZQht&jpeE zRoiy`X%B#Tl2GMiKTvaQH<;$+L%0`qQ_8&!uIFuWmABk=PIdcuY5v6Of{?93%Lh%v{bZ3Ju(Tf%psb^x5ZfS^=Nj~pHnchX2vM_}VL*3+* zy8ZXM1(RGqW(#i)8i+avs&)mc9Cbg*w8{$Cza#;X@{;SQ4SU^Gm0s?4G0ALiju$AE zNlU&!MV6l-OFJ!~MwB|ZwTxyo`8*WFThPCHrai0k_U}YCbI^s#-Qj51eCkTb!+RZ# z6_qUCrXuk}NZd8;&u$PJ#7uWIXW~OYOkFf*J`E;hzg;qyZ&^Wl5hN#V+v{$w=M3yl zW$)to3)~(g4qdL?9Z~Cs_F^tJ#TuDzrqMSc7?XSZX_UUSupYper0Me+gfx|o@tJA$ z4umwtIO&bpvQ4|IOP;uMvt|4sI%#@6%XfndfZRoV|e(U!NdIt#a<)a z+jw}tqu8eu`-&c}heswJDShcNlpbT~F%=IVO@#j0hN&Ht$4>Z1>crRyS}WMp0n0r#9A}Y50cUEOf3oI`Z{2$S91&cf>dtj2Dxpbe zRu;546gX8x?}-ppnr%we)4AHFVs%xkc2c)f;aWG%QyGUmwRR`w5Y=^;r_RJ|ldihb zoPuK3m!rI@-%hVdEu&gcJ;MI0+##R2-Mqc(bbr3e+UKU`1DazN;jmh{6SJP`9ro06 zND3k54k>jW!&6UDtBmC_~cGu`83 zwg~dQCpexk6}&s9g44YnC|0R%D5;IgzUXG?f*1w=KdX&B_~wx{A7I+izZ-2B@S122 zKxewyQx&x;H|+G{)ocJK@TuofIe|3vKF=#vkDphI@vdI7OVM1VZeS8t8`Imc@T8Th zN6w=uHK1O$BePnih_ciGnpM!ruaX*ViqZzzZisTp#0-|Y7mc+8Gt3q@8{Peoo2?zDAVf3l5^y=x~?e;}psZEeKNB2q8LO&p=6sN?LVoQTA#Xl@6g{EVX24hxS z5w1@KjBCQYdou0Mh)(ETj=qK{U|| zh7^%k7A5@@q)bd1XwQgAQ6DA00&;2sxhYEiCCE-%;0aMjZWe$#zXmBXm~Kb&rF-f( zXg*9e>Q=N9jh!|tGIr#S0i=9i=c$KbIhOq8p1Pr77g|gG4$1qY(Xd6tQ|}{p=m~L) zRI}Vf04X1}lX8`j^66ov$o&S8LXDM4&D|dp2!>3`-j1>k;p0`Fc&Kk5S)xWsBumw2 zUZ6<|)67Km7Wy15R+U0&iKTRfdY-!Vye)2)`VD$MMi90td9|*y7ua%4W~$9DMXfhu zCcygjE_jqTN!@(j0RrE%OV_(SwxY9c_0)}E!NT^g9of#y-E!#q)Yz$Ms?Lvg#il(NK2%1GO7Y;0SkD5eJ-y}EBn}EXa1y?y$%*EhBJz){pfwEz$ z!Ss)9iS#sysdf-@S(#WKDteKQ@w4vrcg-U?(>dbKG;`xA$RoG^$<&y zi=o|mZYuz_3u(x}NGVmXp%TkHwHugIh^tin0z9bJ`+>o%5tfRRYXQ_Vkebd?)eq0D z_0)5)VyTT+cNZT8&TN^AeY_=Z2q_BCrf9o-H?UW? zH}$R{?fd8GZGV7d($;MYbu`F>au1q5^>aw-4oT=}SXPJV2x@YKH<9`j^j_krJ?EBV z(tE`*lOEkRN8X`U?6W$y7sys1o1s&CVZdf=&n>bNY_bv@vK$;T6`ZR2k$~&&qat!DU4ak*>$h6OvqRQ9<&5!afMi zhNe2qK1ePu!NL$A!}JOCie1hGSO9zVo}T6dSj#C}(5Y6q&gCG}LibkuA|=-uKyj?| zy|B6tK)N)nXiZT&R_;Im(-dOD5=2}_?RAGwa?@aL#PG`f2jCq;i|%J`Z}dcLjeNCO z)Oifbr3qjfWxK=D_M*c_w{UXh45<0G>q~ngaI++o+gMQOESiR&aC>5QiIm%i0g=mk99|LM(k_sSWF52(`loc}y zX3ZX#yUv@gy&koUN=H z8bpybvNE35`6|#X%rfF)w;L@&RP8q$ZSk~kcFQ5x#rV{}WZ}nN$(v1+^gnswKVQ!# zoh^+9Nmg z-i}sSa?m*sfvTRQM+-fkqsPzi@V!GZT7P}yuk(?=F1r5u$Y1A@zs@6nolE{YANlK2 z$Y19pe_aas>r%*HmqPwJKl$tYI`R~t$KpyU=11RsjOCaCRk60kuVAXIl$bJDl6=6_J=ff zX&m+uo6$GgarjRJ|BHCM&iN>v^Xbk|(8A~iPJRz};CfH3@YkyBeQwAZ+TA_IbB6VB z``_&5!1+@HLf?IEe&TDi|dwbhy$!b06H#Y&`z z)**8s=}2`tlAeyFS*T4XS<=&ylq(?_M-U!ZKUhxlcUO5RLm06zVhCDw0H9T!c1Y#b zs?+uvLU*?d@hVh+19z}G4ex6R(bM~oDu8^Ew|D_(a(A`J8EcC-QtsmRrO@&l-^b)$ zZVc)+y&3d}13#0suz)X#0`Y(Ahiic*Ve8>|wd%xHHF}bHqFvuS<@F`5 zvjlsM_0kA(^Aol@lWn(enllN`>8BgeYo4(V!3M+ld8z?DGS7p%3FGC5Ah~{u!{FZF zsV5rzt$?2coPu#euloYn`Y4Q-?v(hk2LC<`qZch0Vcts^KO(}`5641RPrZhhSY04wAl&aXSmE5D5eSLjYrwF0AM(@T!y#9x0{|V* zKgYGnGjcHJYsC zFf6;Xn!s4AhD=gRTH~MLCbgtor;I+G4C82vrVsD zYM(4Wx#0eY^0P{~ev@r_Lqbfl=`D_@CEfJG!=^oE@4%@Rz$ObWAG{07^G-$w{Aak| z4vG#bcoBnF?XgR?T+5HCR@2Z=1O8BCC?Chg=9z=2&ZO=_ZWglCO3X{LmPA^tnb0Q0 zBsC@%`=edRXZdfbG5Ik8Um$UdBR?x(DDkyr&F0#Qj``TysuZ%+R&0$l3NcBIG{@8a zEj1!Pe}DnkW~|I=|1Rw2=Fz5Pzj5InQag%^scFuCg2dZ6~9FywG%I0 z%rLnTuLH0I{0=Khz@K01q?(CQu1!U6`sN(KY48E#l!^8Mhj2Iq&fav4V>k*kX&j$~ zRp_5+7{UhY8HOce%H4@=C_ho*OH(hS&AttH&B^2`VP}rqXo;#xW?&!EQ|R* zObGuugjYlOX)(T_N+EwEhG$z;`oG2Sl*@NfH~$^KF+9e#I8dba!Oz=iQpgS4eGdmphD8s}Vfh;@lD8s;$t4BNN81l;|mdT4K8!gCE<*VKKGJ|922bP=xLX4+Il9lI;}S}NTDMy^Lc&1Axyly z-GO6J^pa>YHlg}OhMV>VMb+9`yoyqpFpHn?)EexY(MjMOPNA)89d@eSYgOGoxMy)N z#8a!WdG;ZO2%R=l17SB_=JrqN)~XJy-*FAtwd(MYTY2c-iBT)kd>>@m6YeNhh19kc7q7$^#>1!c4}20+K|8K z_QI=~bng&Z#CQWH7V&V^zf@bqN|B-O-F(#!FOctDE)%u<-VHikJ14)~g$`PWug>Lu zWbkxslgXvZU^=W#CKoD$w_}@3Zea#f5}Qo!qz5(8CTm{EeL;0};HD+Y(QYH&CNxXs z(Ln%baF32U(_-D3Mw-sF5S?k1?o2&k9#Q{TfELdWBiNz?0Kgqm`L$}nK9yezLU%U< zB-202z+IsGhw^Un)B@@O#B_jq-gw>fdi?^8?=M&L^qHhF=%FV-1nMxXPS71WETflXVEWa2saiMDkbrr^GBT#e5q#YPPfee?7Ccw>Fw$DV^II`=fc8hKSv_ z9TYk3-ml9KDs{Yz{inTOm){ORZTzd=V#)RG-{7ulAl_7&*XsW^@48&NopcA($TxC- z6P|U8Z_EGp_|@gNztEqOt?=?wV1}Hy!egP6yUE+{EAREgk&O4%!;i?TPRl=?X-)L3 z!_BNe8_-_$Q3J8OCVg+Mz3SSHPR?$h_OFve-6dbTOTKhB-k0u@FWn3u()*7wutd_SGW_tWWnKWa3@x4mOBglD}k-p=-c|EeqIUvCO# z{w6q7=fZ?KKqsnkG|!oYGX~3X`T(zz$&WnI?RP3HsGV*`IUI0!t4vcVfBVrK6+MJr zAL{p(VKEZqXDg5~j^!m%TcT<8fjDPm4>w~y_6M~z|Kk{MVc5<1zJ@XR6I|-4`OXxZ z2wmZ4&+^n9yc=-T(YvsO;PiRGe?XNssbjF233)#PGb*Ssj5Nk!eas{`^bTRmJxVI(uEPlf7gGyLbX zpnM$OQ`4Y4=%T#ZyqB_zsxLn#0`;GPu?79{E`s!bvcVL9oTpsTPrwF8k$z-BdO8>gVy>5E2g?1Z)j5cEU9pKV{0h|r8SE0gIAR*9hCBR6i+?g0Og5Cv`5t= zZB+R^)w1nXFF|>n=PT4Z-T^oU2WJ<(*S{(Ok$Dxiw>Tlj-%o6jO=7_^7L~+tSr(^GC8zt(!k4}NBMNHD|T&zkwqL@-st_{;&7+EC^!N$NGC@ zX8>rILOYgZU*ts3036-vZiTid>LEOQbP&Kt2LXKa`rk*}7+z7KU;j3|$~QEE26^gRF+{xcJS_&qiGfpNz>D$fFOu{j zPn`l4v{+A7Iyg4wSIAH81b~wY$Sl`WsW>L#sgtodbydT|h|sH49jR5rYw09i(8CGY z#aQ-J70x;Mb|S9N6JUX(wGN9nVjV{y87j=cex?!|gHRZmn{7c{dMuJ^2KF|rSqDr$ zI0Fv2L4S~rIFLdkwL*&`3c-^#A5sW`9TvO}DcB(dy%nA+)BFXks%$5i;DZR_!%FM} zNlGC}fd=rF&C@RdXzli?g^*MhD|!(S^Nr{+F`{V$nyQX&RdY!6(JZ=DV~=T7rG!0( zvBzudv90QO!XC@m*%~`8s>ZAsHOi6eoLDtZ0irY(u>^?YV-cqUF&hY+X`X;A@J_l! z=P*%MS4k}Ex4}vXuud|pGc@aD%{n8NwGym^z}xsKVT`6-*usVpMbN4P0Ih2JAvL8| zP2Xn-|45S7n)M`9x)OZQ3k7_ku(v%oA9@lCZ;W28gKHv`VqqQEQz2`{0 z!wFNA2KdX6^$?CJq#&l9uAX`jGH}S@=N4wR2apZi!~1Ekx`$G9qqvSDatIL|h(N4W z#}pB9CJV#oeqvVY6~LL~0RBFyuGFjGM6?{1CO+VxHx@Wzk+;)@VRj!xWdhl%V@i{= z=?m9hur@IV2jOSzj_Ss-51?8}EKUMp%Dkh&nS`4JJWSMd%!&5a)G3r&hsxJVM=|8{UbJClD@4+4|8qYI+cM0a#q zl+>}was)hkgonQQOgL(=KT3NCR!w@^R`e&Ve(5;-OdrAp@D+BC^|Zv(Y4|Qp@MtKY zy8s;<_5h5x5pECq_Qn~Dq1FTegK$b{C{Bmd8TwzkfnRYFKg?v7F#;Up@t$R`mZ*>2 znJ6)!ABO2obOw2%^_>7cB03Qw_5;MW^CKr|JwrtrVOD49<>bWucM zkdyeN<@cO1e*RS@lAq8;iM}}p!N30O$u68d@gM$+ME?C#6h4{PKz>db&OzkDUJtJGuO>^#7BcTz&+&gHA5LvHi_-@&f*aZ}?IoM>iwgyi$n&rf!~jCHK`N z8^MAE8h7>ewJH#fboRzXChqR>Ty4VTs6QAtddzhhnf#N?7!5?k{^JxFQjVGrmj>Pg zz*_K|tsN|#s~c+7$5!M*5BW7`v|O^qs5vS**9z}i64>=AU@)pI<5rLVUv5Ri)yd8~FSjT!gb>pGvF6nI`ij zqwW)OUtIknkOJoA%?+>}i4lkHaXND} zlGW>EnPEgIS*9dg6O-&#N=A(EO!UysBel8~=jiC@)L6)%k92SvicVTJLG_?^d+?V# zl(7%@6hH!DAOYt$;n`AW)Z*(QI&f783G{_iH~n#rmH8}MO+AN91d zoC@6sw#v=!60cQzHr)UkzzhOAe_aweSbM@KB3pOX{s1r*#+>* z>P(DR7A1>T36-%JMT}|^VZ!mNk^^og)#Y6DH$H=f7x3_c!UqbE5`Neo$i=kf(|E6o z#(dU7Yd!^U8Qj|NBI@?kuh9ke{Jr$Xml?Y3!G#bJx_;TMee)y?&5n29 z@Xi~bBDFk*`-||IMLgM$7NAb)ZpBWpb|{VY~fc;QGN@e}&ApHOQGKOs?G zK^f@dD%_+dWzZhORQ4DW;|FC!h z4Nna)kgSy_*JPxc?=jiE9+TbOvDwjglHkz^e-)eX4wLXrl#NaY_|%(Hg4+${El_UP zl(&QeUn14V+cBBZ^+XZ9S0gjXjj8lHU?49Bvj!N*!3yT7ceFydHpE+@PaBZ%cVmR_ zj1^7}Q=CZ9j{WzMkcQp&$XgA7BCQ-DL@N-75Y{5xCk)-0pl6%|$cCnzn~cjIGU)p_ zo^>W++Sq{XZldh)y6yvHmx=6dr0f7tq?IFtXa(XB!dis;grPeTP_$-Geb?06@4)z7 zU8DGX1JfSX5QRP2cc20)19Iuh5K$p!*!yr11eU}n%{+D;2~*hWkq?h%vTGZ5;s&QM zLVPf2M$s-;wP6y&N2t2TJGe>^%|x@{RrG})7KSjz#^PH)6KxVyf$dB+XNl_X;f;&i ziEFnx%5+%Q?!hQ;$Ns<2y^&m#xOR)9)I|SZC6khFWE-RDl5J%7#E}y>vcvGgn_iC} z=yW41o7lr%KoeR(8(G@J+L3eoiuSc?89itZ`)@nPFPql=QX#lf25+wi(YNj7xyIo! zyth^xY7tks;Rh$=yQ}qj2Iv#U{jLV>C zb9koa!dC!V7A}PZ371U~X^kdzXHuOe!5vN{Y)T;;r}A|w9MMNAd|*!`>^4E7%kJoQ zTgN+I5X+8SqCwBWj8= zv}4^)uSL zJlN2RK{-i6y5~i$#yhPNq)4ZYKni`Mi&J^&c%O(Re!7-4MSr_Xvf#?c(8o>y+%0%H zhEIBl!*ZkYBQPiFPwpVTkzu*N_c}wi7K-}T#-A7VYv-AjbXV0_iTm}gSSu_j@5`UZR$g=gT0Lz6m6b*A{lUH{2trNS>)fS%0s%mHRd%n^QurTlU=CyZMCCl_o= zdF1xXZcMjAM&4A0iy6L=;Wmcx&P@Nw?UBP6mYX66Gc0#Q3SI7j?9TK|bR=r(42I>- zM}Z5NF8pN-OMTWSz)cDAE(*SpD--f{<)MX{^Wu@seic>Ps%IT;7u~@mfUrRrCI;U?Q^RcmV4t4F`O9a z17FtLy`_K49cH4x+*>BF+*LN51p{m|w2*LN)0>xw%Wq zFL!m}#$x>^7j%6oFkho3{Bm!Wj6b;{OUAq0izTq!h9&hY_g}rn^5xd5Aq*FzAk>Q<Gx$;Ela?J^vUH{3=CNlrX^(4YCSCXI_^q<^5 zBK<*b7?J)^hKY}=M#@*uu=Ix}hDH9K1b9EgXK;RU>Bo}}Bc{iy-NPcq1gYe6}4!5!X za>s(u2og<;9BErBk#B1nF6LxH51dkG{zxr;#ZlgkH0zT7t; z>E(_AkuTr-&*JeT-_aK`EZ>&Pc(Ufk_oooULN89BS28T)uZ>|DfAWQO7Uw75Bujsl zkB|p({mNIz9gW8)A;+;c&6n{g-{Ss*`>T9@D)k|soXUDCpO?z`k}pZ8asKkPsEn^l z{z6mqZDd%+S2M%X9xV(@{%s78WBuf7NGYFu06B#7moFV9y?oy&{aHR@l>FqoMd6pP z6)$6X@=2krH}buo%%}2YoV2fe3@7a=AFxS#$|q&gUh)l@lt(@pllqcomGCCrerMK5 z`^g7U8${nzP58P}(L5cHDNZ?;-1_eBu$&4<$npEoo2rd_&}C)*8CBXBorNp7jh1e-p#fp7MQ!w5NQ$ zAnhrK{G~nRRKK*RoWqy)<6n;FNP0OtQ$m9Rf5qDkzw}Qz zKO+58PJD=bIp!h#wdIod`f6hs3xfWWvlSH#%Sj5+M~*p&KJw;Y^pRKnqK~|s7kw)E zeZ1%+@5iM+<(;_bBd@L&^5ot2Qr1^qSWA7&8*1T~SJG17oGcRTLd>zgb*qeD zc{_VFcTjP9N`Dvsru295Vdk;K(7mRI;ReZ}+Gk-l@az7>y&zT%kM z%>AVd1)`{o2k}ykQmkM?&<`;AGQ}?={uuGYEMvO(S;W5~eires+=&iB`HFv~HfUh+ zuZUko{3+r`5&y}Lk(l%le@I&|lV1EG;s+7`hxk3j-ywbu@o$J^H5x<4_ zE5aD?q`&wptdN0=Io!fw8;9bT5PyXDA;kZXInbmRe?tMoWgOOX*u%zhrj1g`~%__5PyL90mS|nyFYWdk$Vn@ zC!nKJK3`)%Q@98ZYDcmA#oiY?U+nv9jxzjmD|kBF`6qHHcD~s6V%Lj3FLu1x?+;hi~TNkyV&bur;B|)Bj4~}%wZdcVy_ot0wDR795!>~68Q^BhyJVo!@5J!qnl_dJJUPm3Kb_OsZ{VlRuGEcS63 z+qLx^HgULz!~GnJz5Bsbldm=1gktB0W*E4V!$uC9Ic(vujYF|t#cmaQRqRx;PsJ`3 zdsOVuMI|Obu|viF6uVRGO|dh@z7)GMILo9LyHe~)u_MKP6uVLE#fN8`bYd_5?RW!= zz4)_I1AoHdxo}`m{}KDq!bDDRh{IwID>-cAQ0&2$6Ab^1c_tLQQ0zgm14lxro=4{! zzHgP8@HGy_-V-}d>^rgR#Gb2UJFJnzW)538Y~yhCA|w9*hhndZohJ5~*kxjmi5({P zR~{VBR3Bo09bj1Ouk*?ceJ6*3Qw%KjnAl-re~H~C_LkULcXPdrVSWFIJgL6Ku4+Ej z$Q3)Pg<-Lq>IIb#GVm5=Jr~nkJvHGmK#{? zn7=bTV1>b7%AwdbV$X;ja}CcUVyB3GB6i8FvyGe`>rGgBmI?3KXhN}9#7+_WMC=l= zM=~1>e*uSO9E!cMhvEGk`Wp@Z2^=5P@MR8V zzc2fI+26~)UiR~{kC*+s?Au?v)X0^6d);LQzJkO4mm662@v?uHeY@<}WuGqlbJ>^6 zeq8q9vj3KSx9qq7aE8fe(<&3*%wY(Q3mWI2a=)6e$-oZ-N8?cT-^=bc_^O*sm<!=}23%*t-5k#Pu7O)Q?7{gTWdX_Z|u@o}+ zymZg@ck!nBtJi0kKfkOzp z+gEyYC0j7XmrfFW)+cz{i+fr@s9&CC1)Cud$+6GRx&zTJme1*-S+cEHso=e>S3d;a zqF>9SlzprmrFMLHR$nWJk|N%ARzEA}k0$=cS^Z5sP3_o!)&MKlQV_3p>^m#R8W=`A z!{>t-U=E%YvW71=)W;+Sl7oU@r8lg$jBjYqY> z*_6g)Q)aSpQqaGU%^<7lD@0Jx`o2~b*TsrFtD3M@S3g<3&_XjA6)x*ut4vzi;aSLr%U?RR?p%#$k4;Gn7rbRt1@HrBW zaSPJvzNem9I`4EBRo=@To9*-JgGbK*;MH5fV@$*!Ja)duWCq8XNcZ6QQ#B?SoIthc z)%Uala}b$mPw^(D_yZ>+KG~k&O-XSA)re2E$9ctmyBl@3Y|quEa@OVu+ zaa^$UT}Vw?P#m0-f$o#Cu+a+q9+>d@DHL0fWEHZ)w$Zb&j*r zdjQ$DtdDzQQ{d6yf~Nol9<_oCTXn=2T=ZKV@q#CPq9gv`;xBY0Gk9_a1{)Fu%T226 z;3+ix0*{7*OH8C7c&dpM2TwDRvf#Il)jXBKZ!gr56~T&X9jOmidO8vgR+-4g;L@Mz zyv_+$uhS$H?s;IArR4;OQj=N|pn9maCkB24czJqGfLd)u>H;0E?2;3pc0E0{H1K!O z&&bFLkmyyZCkLqGthOfwvH;h0HTX5Dv-`O9nVGr4GimT-4zhx4srEASaP!DiFs|#C z6PSfCoVqYDAK`j?GJa3NA2=29v$`AF#?%>sGXQVuVU*mQIhFu`jiqU<@jYL|D0(*_Yc+)(@bEp;@_C*jL(4FQN*j z$=+c**|9uV*;m_6@Ar|v@LXeGYdd}Z9KmGi(&t`hf5&$E{w<2uI_F+*f7f>UwL{-P z-2G$FB+tsdk+=sWqR}ch*&$z-fmDg#vx7Tr(%CoD3Z6TQA|?I-H`_i`*nKqZQM{Xp zo01a(wMN9OJ;H%H(}hKfhi*ZG__CP%8j(Y{5~>%Ys9Z*H=r+5-mmSA> zJ21W5Gv0v~_4Q%AZc!unPQv$%#m7j$3vKJ`Z-`dtZZy7cfI#=4k$pKa39a0F?fYzB zu4y}6lH6VPZreA|w67`K_wD;_-=LUeT#!BX1GX=(9X|I#`ytym0uwtYtoCiEO?(Y`Y#6O&W!^Y#n2ebPnRz0hO)vxHFu1yDP zKGi{eS{6w;bFdE9j@QAu1v&_yp@a3?bg*{0`4e=oWsVNEZr8!K+jMZj!#cR|M>@FZRUKUXp$@kHO$V1` z!ks@X?Xo-_Ts}(&SDdPYE5kat>N`5P`c4WmZ+$=qw>_m423{YM?# z^Q8{%b$U~}T>%~J4(j0h{dI8v5FI=)S_cn~)4@a2bntMg4jx^ogU3$O!Q(YL_(7cx zo;XVfPd4h{hud}V)KxlYxlsqt?AF1L9@W8*pGJT_@^cK<6zU^+yU=ga^@DJEgiC)4 zxV%HeqGR;%eqlTIaH|oC?ZwxE$@0BszYM}r*oFSm-bZ3b*n>3rA&^gMwa-Ujs4s&` z+hotzjk=gM(t&3ca()etXC8*tl*pDxY)G-rC9G-Tv)?_V-9q^9*`?$s>W!h|OfZh>| z48Q{lrEdW1^Ix@7`dus)dhs2eZaTzsTI743iOlb^LyP=`SOxrrDlCR@hmsEV;_Vp${>N^Jzr^?IdO4_1*DnGD&m+M|)jm+$(#heB)k6aR00xQ4U zR889insrn^m~p0iQXi*0hFV7%Rl47(`I^DE`4`Dl=@p}j-i(nFzqNhmXtjEjAUQDQ zQ0qLSR(_Ct4EEyBDeKW`iCLfZJKGvf6TLOE=P=FKFMzLWKWdlvhqf!h4-P8UmlKJaYAtOhdKKe9>A3YUM8&NO`9QNY3sYr(si&Ri} zkEVVFYPnsFxd8Qy4nXxx`nEC zv|tPw=Jw)pFix}QwqyJp+fv$#W{jmaLnbRw;#nq>jH7269Hvrx9@j!3gzev-Y;Sns z7j|GI;(x}qljJ!Jj0f-+J2lh$5;k057ND=}z~bJZEDZkDt^yobWCj0bVkh~G7*Y^#)~#5j7>4N$w?oVMM$e?hm(Fx zglrXE<)n|-U=(-s)lQcIMb|iib9L=?#n#zM58`>uvDZ3*%Z&=hUgrd!W;MU#1g@l- z;;Ovf`K}XqJf`Mva01)4_&Ny5(hnM&M!~QazYfoF>6`EzuMw>p6xWc_5t zB)rWDT${*uyA!xRQYKTaMRz!X8#Hb*_Fks-^n8~-9k6$&n29}y~Z1yMo)al;`&4!y5L$6^nMYO-~Whdlx8Mp**ks^*P zha6cefN``Vi#&g?^anHiRt_9l6gRC&2spAdqE$HH$kK>|v?{}qMXo=cJoGaMo<%sa zH2Etchki~dII=X#7ZSmt{Z4}eM^+5yE5N{!mB{$21J@)RSsJfjy%FX?a z^O)^S_#-wNb`Eh{6WzyczwL|&zT=R(&PZ$Q)zjo>U(aF9`)dleAPjJQKM;2_f+4{F3Swt|C9C(r#I+Cs5| z>`9{Le(3zzR_q|tn9%RhItmW5NG4p}e{f!~)m_gZm7QbKe&qboQTLd(HkgmmBII+ITbeIJb*lQheqKSfKaT|dr)N5kTm4in)2jX1rt?NrO1>9w>(#pZ1b{=KSxxWSYy%92W!UY zp#FFroViQ~Yd7j(-3}du@72NjAL(F2n-0#R<9)-@HvUBio6?68w7HiK&K{zJb0+BE z+^IS^Z;=ifDs<3zx(?3Yq=PM&=wRzU9c+6~2N!&%g9{y)fWy)*>ZXH>hw5PaL>*i* zUk8^}>)`SWb#TQEI=J#79bDC_gR4KF;QtOU*`F}8rcfWr`v=8zAEQ`05%P$TPNO)z ze+X2H<pYcfU2@M1W<5ZO)EdfSUF?_5Bz zNzS=QSso=Oo9kl4^%OZ$-GNN)#Wg8#);u3qEaH0~ub*fwA)Dp^;MjL@;_?%JK48W;= zLfVVTf%I#z8~ZAS8e?keG)>C(!?S=oizTJe+eLfv7?27K2?ka=Qc-C>$5gK;_^AP7 z6~a=nGUC{*sp;4NK>|4#b0VZ}l<(v&Uuu$-b!*579BS!?KwYf*z_zlfb~7@t+t9^~ z6u3N6;4&_7*K@#wRI^dw-n!XgjIzJ$Q)K+eLQ`VsuA6aWHw=F$6+rdBa%~)q%Jl|T zSH0t$+?|XCH2UC&Ls~IDPwv5#;m<}W!!@NiXpCTM)P7JV_cSKIRrr?SLqir) zLvk6%=rU$qZXLFay(WN%%Q%+HI62!ik2UcVBmJB=Y@9WKcxyy&OrB8vAc{Ema+Ns# z`k>IDW}p;%uTa-S8YYVxW<=jfnmUrGSGJ?}!&HE@rJ$~9QVC;s1bdZMfcn-B^@{|_ z1B}b$LZV)kK+VXBx=a+iOh$(2Qzv`zBS`SI!m@RgcD|FE)KZ>`@pYJZM(%c~XM7zh z*4LpNy{pI=SZe6-b*PB1V-WeIkqEvHCBBZ4d8Q=`;hX#Dok&6YQWX^p4&!Mro(I}c zdulty-oUc27xjW6_h`nmz*uf?GmP+Ta0zfxkY3r1XG4i+W2hNVyO5}--8Uj#XFYA$ zAT9Al5U*B$kMv#|Q&cC{C})(Oi>3{Sg#aB7f$`eT81nyZ^h+nL`B>OR5If}_?*T}#CORmF zH;*Qq^o4k``#=v;<37;QB61(lur`%C$hZ%5TD{H{k^4Z4-wh#I`k_r0{dh==e-O`c z>5t<%UMGxjvil&Sohg-0#O?!K|MW2K16}p>Fzy3g;q-`eA4IWH_d!g;i2ERhkK6~5 zGMQ@C?gNcGXPC5}o_y2K2OM=DXck>TgpY9_BqWQv4>a>nNvM(c3Zf~LSi29jJl!nD zeL%3Ky$0G@Kpp{d1f=Ud5AA;Rp2zHdBHL?g5qeCl4Sk(5HuOdeJ)eB-unSYz9t9iv zJF1E%k1naIIATMe6LN7x#~uMWAsoYTaYScg0hkcQ5gm$Vjl_eF=wL5o5XHoRBRVdQ z=tMa55givtbTsC-BZ-BM=(sqd6T?JDbg(;$<)R}x*diH}?oX7XIiiEjQWS5F=wQzj zi=rbsF6?xjhfb}lTOZMJvp$6$hGvfFxO_y1xUF0|qT^=A^3V|-xA!riN-8>{#UFHxc%Cp>4=WoKL$f`taRX6)MC~mqO`#3bhH;Oq>dm52V8nBN;ClAqK9rAH#@<1Yo=&%m?I5dh%Xav(? z9rAI+aN@8I`8X08>97v@I5b|jjuA|Ub;!pN#m7je!#d>SAfh>}Lp}}z(P16(aYPcD z!#Yl`X+_PX59^4J!z81_I^^SsB;$h6VIA^uB;fU79cRd&pg;`G9M*A$8gyZ#I`m;3 zXPD_VT9U3@eOSktuwM%y?#N*sXG#n*>V`td|X4S0H z<`KJ{a}jOra&J+O*=c3OE|^>K8-QsGVldX=+mQL~I`h_I&V0@Eq?vC5I*Vv=nG@E^ zy(1>`^EBp8ojI}FIRY(l!9jw`}gZhtjaHcnhIM?>k!MZUz2+!5Q`WhW<*rJ28 zF4e)t>vXW`UL9sy)Ir0ab`G+E{}O_n)LlVwiRWSP@6S>`lNmN`w6Wlqy%nbR~` z<}^)~IZcygPSa$W(==J;G)`G+E{}O_n)LlVwiRWSP@6S>`lNmYk;P zkI|Guqa$x9#c0H&Q!Jebc|=I3(UDg|R2`#-_7jkIV8%M&?^Zs~n|Y72X5OppnfEDY z<}L+08gFkjc{j)zGrte={UGmAj-}BL0Nr!ugFrt7^uvOFMEO#>&3qK-$MF9+NI!tU zy-Lk|LitR}C&AKp<_|%73M@EGKC=bnXOwT|v&xdCD6#2a8jY(V&ZU82_9(+9(it`{eK5vb1j%E(52O1I32;=kC$wMzH zvmR)2Pa=n2A{5pGjmiOvr_rA%y&lAH{uCIj2Z@X?E3+PGyj~BC;GYp5>p>JBBmL*f ztOrE2Li?5Rc^l{zW!8g8LM!)GMLzGB!EEGNxxY|RpSMZ&nlkG_BpDavm&&XM3HV(6 zau%%e&muAnd+zIm9%|5ek?P2OLy^yWI1pSSUAeix!Yt=ZXe%N#amV_+N!^IgJD)@m z#v1f%MLuuJA!iIF8T6(ipZ8?MbBN6v^p+x@H*F#`N7i)0TDfmy0(GXuWQP4e`bdA@ zZ`82VekJedyb7o3!oRWBw|Yhdt&L=RVn@J?0wmx^Tc_t`P?`!g$Pe^4#~(lHxJ{gs8ditEk6Z zV?qbew&XF7WWtU0fg+Fj=a?((9Fz99>UT=rV|t3ge24~B_nHRP>AwQImHT@_-$#Wt zNwW<44`^q#>o3qFR^dS(sffosq62D?lBd%+&3g+eQr^X5@E=v)?+GAuI>qvcD^G*n zFzf?8Mp@R!%9oLsiDpe9R9+v7X<-ygCqf<((y6i2#}SocdHO-%aCU}HNXPcV`$T6u`bse^OSC2bmepAqbwLcC>8Tu4o(}`uL_x6sd&ho=unPXofN8XBgiL&uAJR3E8bGVR=pecOGh z8MMIIIU}LCHT?plG_gx0X7zC|^`(3Lf|vQq!RZaKf|vWwqF9bEc!lo@iiP}xuJkqe zyj&8UGn7P??(kjZ^9EA3rC0l|@p*$NYNgXNovN$9?^++N50oU{UdS3ByFRR;E#Lpg z-IvElRbBDF$-J2fWJofQ47*8S*taAg1Z4{l1VN>MxO7QF5+EfcF$GC!DrSo_*EKTy*bc~(xd z?aU7n>=s+*2NO(6DEn4h=7%_Z&K{fQ2l+}gG%IH>p$7>1dQ;9hx7jp5Gy|b>#D$x4 zyG`?hg_`nZ5jTG?++ou=?n0uH@3d*`Rh4|iM_Flm?43c<)YwaY&)Ca|vo#0CUPkvWCJ!cZ_JgX=F=~_%oP9|8oQv}z>2vXn z534@Mc)rfLaCe3aj|JLdb~ z&>fTfo{q_g4>bomCL_LLgmg>}p7SSH$MjPka-MT_OvYqCuR5lQM0Lz#u8t{T|7^d2 zjww|on7?qxloI9e(lKA;j!BvIWf7z5m@je1?8F7_B)IR(PRBH9KsTb`Vd^NcPmr(B z=Xmsc#g2VPFN6-0FGgH3e!UIdE~N=w@l|xuSUp||~-eJDAi z7ZZQAKSr-k?vd*&dfom6Ovyb9d_`~A)RB{Wo$o99n|OP#@D=@Cyr*2_%YM^7ZYM*@ zcncN>(er49ko}hZww;`*P&7JO+3(oz+R0F$F_)nJVZUc5V?uOLIq%yi?Bs4To)Oxb z{7)*))Hf z@MTq7;(Dhz;MEd>5P!!goEd72srcn z9HQoI3^?;VW3o2|WS%#XsFK+naOQaldr4qRz`svwOE6mlG|x++a(Ed|wh?+iW!9HP zjA}U99-w*tCqTFp+;>O7%=0D<==T&nOnoIb2_Zs7c=X#Dh@C|*gbtH0MqDv|r6C~Y z3JfQ^0+{jZiH$`ND!h?i$rsy2KH`lLOPF3`^ctQ*5Bf?Pq^?2T)E%7tFAc26YFsvp zuRF`ao^}8_DSTrc2Kncg1*$RJfV%i4-_4-XwrNu!sWY#+hm!sgobQ73$yW-r6wUV* z7LL4H91>D{=smCxzB{m6B;tqxahmfMgFt-_A6=h1t~dldEh-1os`i1OimT@ zn;?h!UlG{hEx=i6OSo9B4E!=+4MT~oz6vgVtXfIwWIx(B|LTA>o)Bz`0{={>Uyd)o z7BBBXyNfT)lgqCQSQ8H+M!Xzdetp0yq@kF;L6_eUu%^&90$!S7CZp*0;5zHZfHgH@ z4eBhZTLUM6|BHzGgdWu8b57k2Acy+j9AEo`GA1$k5s*7{Xb$||MJr=B2*~lSApA1a%qud4T_P9$T$BQCg0P7+;2XU={RI^ zq$v#2Y*i84=ITc{?J!$>gYNIz3gh@%+bTa2@lddWv4n0l6odV(qyS%iCr%S-Gpe>1$ zIj$aoee>soG{ETz>NF%TJT$Awnur;PmCE+(O9-9ZSjdoi$3APaPFO;pDz} z!XOcdhXbF=#D^)2CLqcS9Zq7sdf}Ar%s3N_zio>#{%}%c!_AmT_)LVQ4ktx6(ySvW z98QXC+GsfPHzY;2>@=@@I4N?Qkr1Ux$qLh)!xx+)xBD>pvm_zu6H1YNTeJ`%;Dl1- z4igXKqC6Smf>Y#xiP25ikrcV-Ux>*OuR`ohirlx>6R!}|38l!bBp4@@B738x*0gZB zsq+|8`SO}i7JfLL)VUx^NIIR=d9)$Z>7>qM`PISUbW#_(+!R^EB}W=#3)h+=yCh9DbmCRP7gYl6uFX%nI3X3DMPL`Iar)aipaGlSHL|< z5xLgn;@g`PxyIy43KZv(BG)l418rC8jEAOhcf9L!Ns+_M!UaTlI+qlYYfW*%a4sn# z*P58QjD(833V1^l80V5AjVwB-2CnJXm~k|)=WMLa*IOBn1t`vb84J zz~66Edd3st+uS+h_klYp#3kJ_o)o?<12g^*pt|q3JvZa2z!OB>QIPR;;6?K7oRslQ z;NRriH9h0mKm@}>ze{Il{86OrK0o76fgyyud~wEeBJYZtjOPO*33pX}#<9Re@?E_= zO-)w#awN1z;Ke|Czn^8iB$>j+$d`o`7bC+@BMs8< zD6LlbHP1VrP?Ay(e?}A%EKQPqR5oJJ>6Jjgx#1|NjxcE!%o5H8rRS@G2&Jbp6}{hb z{65(p2$M#Hb)l?s3G*k+cawl44JRu?c@xU|PbQYRmKffnyIHT{zkHLCkmqrH&DQ^d z@lF!7Fab24{fOFFexjG~Z|QM69=svp@6_k}AGs77e!8Uf_w$fMzNF>H*{^XIKspo} zeq7QbzqCz4-~bpS^oE2V3JpdSa*$@9A9@)M&KnYb=wF!p4CGtcv?1Y#{)JI9jbPf4 z@Z$iJixV3Xer!m@Gt!2H9|xEi&x48xrVR=F&z%eJl1>{EejH$;K(Zm>#{njJqYVi^ zHd&28*^uz(M8K?=ctgUkE@??H+K}+$0FwzOCBz#N{#Xkyvsgn!_T(WsRheA(#IRETDek-IdVNp!mO_H!Xbb!qZ@x-=s$(;Vp1j5t8?;!GlS zX%5b35~)iw`8P!7Gl|rt8AWxWdIHWQQkQmd;!GlS>3BvulSo~f@m!-Kn9d|pmv-2xNMx-=2xOd@q@d80Fl)TK>8Ig{wmk-B3hK9i`sv;?CwiPWV{FqIKHlSo}U4$o&2 z{rww}02fWpB>D#k`Vo|nYGGtR%s)`t3QOX`Ov9o#wJ8Rakv-Wa!*4@ZX})M( zXWL44w(nwR=Pm5)dV-xxUuEaAPuRIUqnu=3(U+WvoXLyGnY@Uc$&1LDyoj91i^!S0 zh@8ob$eFx|oXLyGnY@Uc$&1LDyoj91i^!S0h@8ob$eFx|oXLyGnY@Uc$&1LDyoj91 zi^!S0h@8ob$eFx|oXLyGnY@Uc$&2VSdH13o$>Dx+qN*&~KAjI`XSA1&C&a=&3oN-)4@1j1aSQ9Gv&DwOP7+ zqVhhrHcQ7C-p3}hbS4tjt7sqFcgH&JJ`$Gpv3>hw@)iv3WBcxsF`2_}2D_C*``Ety zlv!UEF-8SV``Eq%V}NicnD?=jSvr#jRhD5|I>oXPBGeBL+RPqCFN6-0FUG##p%!A( zh(NwDRX~_tWBf|X{D9m4sde{ig{wTonmy7e?z+nE0XZ$!I^B3cJ{u03_36J^9!Mmh?5|H_e zh}dHbZ1K_jC2yYvWd1S%vBwtJ@AKyzLJ=vZod43UkXn*Tu+M1^2=kW-CMA^pML_1S zIDF2Rw87K=QY63?#>)AM&;tbhs40$|uW8?B;1dov7jDisfd_s5(_*M8Ulwu89$SEx zjxHoB`P%@Qyi}EZ#K&1_b8J~k($v^Oe$Uv#h+55ov4s)q7$IW|2haHqrKHD}ZA8ua z9(!kcY++1xV^B<9nn={xvOegHEfRJ^aAVN7PijFhn}Rg9NMUh!8ALV{dOu~>mqmK(yfdopH?57WOiVjzs|b`69v9ti!oTDmicOYn#ciCm0PF{VbvGK`A-c~pEwM#V`O z6^Bw8r*`@qlEOow85OT_M#UyQDyE(dHjIi}X;kD7HN0En)4Jn{fv8O_s9mItn?bGK9bb+^GDPwbP~W&bcw3z0%$+Rx4WeEVM@@|m0TD9`c6_vv zw4q&Z;{bG}eEWBvDx>D|j?dqnMpdencj2euH?tx(r5%o?MaG8(6N8u7)k2|ZJXLZFh`KpWtTASX^WP{PP)84oGBS)%Nx>*VMA<_jab6xA1HKA}mp!tB0?!#95h0$my0 z^CK;tx(Z3Z((fO}T7tqHX>GM&{AF8=xqXmONW315nZA#_nTglUhc}$Q0AnAGKUy~* z-bm{aK|wbk-jroHpqmeG8E9TvHy^&uNQiC#$qLga9P8%8x8JCFg`{=!;eCC*1nB0& zcbIsXIZCOZ+r!}lCPp`5M^gBnRTxe=p>D#?r0{(`@D&nIP`df>tt1$_`S9LoKG^i_ z;Z9>{iOTbeOfJyRcPfYylJxVPMjJBe=R1w%R|g0Ed@AYZ!)v(oc9P`qZanGsaCn#G z23q>?qbg%pCxtJgl9GaEEq(ZqtK_ds3U6caA5dQS!3!6De8S>S;#m;>9M7>F&~TEL zK70eG-N{gt1F@DqZ5@|CJxEI*ZsMY+2WjcUS8{>VL$vg1qNR7R(9(xROYaJ}Cn+pi zdKcf`r0_K+Pg1PV(uc2O+{5^+lS-mIS>Z?VuC?^x!_2}3M0nEDheb;t7YthZuxRO- zxg+|GL=;YgH$;J) z8DM63>*Y+Z-uIfI=zX8dh2A$C(;L>^R-GR^*&*B~zBYI-zI(}_S9+D1)m~x zpAP)>Ck(BXH1AjR=%Hwdj?2Y-#Cg@{IXwNAS+*mWVoo!7y? zLecassQ)c;t>D@6SALcIl-w_?5e_SOviwDUDM~^>smzG$GzV7jjM&2nIVH!z%`GS< z-%Vt53yM(>8o}A>7LswF`-X&e%f+C`G3rgPfEhrOE--0R! zvt-SC3rd3NTTmvLlu)+51r>)^x1e?ynZmAaK?(Y>DGqfD>M@6#3s>EOdJlC6>r)`| z3SMq2xsX=ax0t@wa9b%zx0O!CTQD0(<&OLNqLPC-*>qbe2(8;Nyhe!}B?5&Jt?^40 zF0FA#B8k?RywPu#I$C2!q!EL<({4D7)|fHWA|0)P^*q~HF)89@6qSTFiSw!<{jRhlGV>gdzjRWAW|Z%la|!Cd;|YyG4@P7(cais+A1 zM1Pzj`r}m5AE%1`I92q=siHqlUDAIAl&7hcW7%0cot>)l*r{H~PR)9DF1mr8+Jo%W zJ<~=i&?5SzX1>nmTsYZe?fP73?(L#LoJ= z+1YS}osIuvXH#?)#jtq*JC}@RXG;+~TYt>XwrX~^Z)9iZ)$Htgn4L?XW9PE>*}1&q z#U$*C?&M^M{y0PQ#~GqO&Jg`^hUkwoM1Pzi`r{1IA7_aEI79Tu8KOVV5dCq6=#Mi* zf1Dxu;|$RsXNdkdL-fZPqCd_M{c(oqk26GnoFV$-4ACEFi2gW3^v4;ZKhDtl<4@2P zL)1)S-=Nim`9ZiC;leb)$1>31LhR$|;4i);Uw9yJ(`dn=CJecks+I;vd^7>JeP;R> zGzY0O)8tp<%u&9V%7|*s0lg0+Rx?7*OmlG0z0^yH>baN77;`VxM520{+)I6wyOe~L zd#N&a3r6mx$`s4te-CzjFO@Ru%Ob|8pygg_6A~(sC^2?}(r8rQS(wgo@oqJ{Cs4FcD%zIQzQ5>+oB>V7pbV6K@Je zXlUqW(aO%Y&b~QFhH9;x4t`s4GzYoL`L1P9-?a?NT}!Tfeb+LWN{dja)N3HX3Maui z$65xjZ~iMC;oNVIypBd+!B=|yEkP@t!qA65jtNJo@xZ?r`i{=LMC~286~|p7ohczZCI$^Ps+f_DakQ6DcNtn7WkyMn>4@}^Mxg9n1aZf;c0-N9c4gWY*r zWG3OXCiyyXQmy`Lk?=`L>TU3Lyp8woOrmU9BlhBr{|n=upf!Rf6};TJ?x1>MT@G|I zd800ZEPVx(3duXYcCT|Uj%(||tfp7;t7b2YV@Bu`7xbT4j9ASfNmIid`8~rNBYvbgFw8OHXN-_xj)QxyfG#Gg=L#re%oR`* zi5lkQ3aAWo5>~E&N-YRRu7FBmad;Wecz zL61DK7Cmw-_sH>q%@V5cD&3CjJ6+QvV$aS{Lx=*3gavIouS4+jOT#CgtD+ z{sND`Z3m?cV7@Ar|4_T-&koCw_;B!%pjApAlS4Z7XGsr2(yYTRa;dJ7yaejQzYRWV zvN4IvAZ;9n{fwwbT2RwP(Hx1OgdUAAA+5q50qPq^gMm@HfJAa@PWU7@u{;9Bysn*Q1L<|(o+EnY%s3@8rhnR0q z^`wc!B(hN1bsMCJqB-6|B`rBpyE%$x$3kUyN73w9sO$l)EE?=YI3Gkz+(lHG=31AG@5A{7=Tj82tv=g#f5j~O?E@qFKJgb|8n#hCb1dA#N~ZNsTp#mk(kPGzTU zqTWoo`Ayr>$Go!UH|;hfA-WnQD@=1eYkt#izgqJONo#)7_VxA>p!rR^ z!^FePQPzb)^P6_S#ONmMNJ_isVXUQOQ9v=P5Id97?#sZ3Lp(uge$#Fx!O;As?TxY) z4yUry$I$4?!>x?D(E6qqL*Cv+ly;5DlN2kozG>Gn?jSzKq=G0<*!9G_*7~L$W)?0W!jslFO|-so!Jzd` z6Rj^ZTj(MZQ8)l^hyp|Fo7TwkxLTm~O>34~XsPw(HE@_#-n^>k<-3)N;n#hl_jgLO zyLv1Z;QIgUr(;U_G6c=;~*XtbA#Uds$gPgNs^L zl3y~SbgqmTuQ{-+WW+Q^$g+}yXa7DZmPMF6o5iXD*8RVP zcjjNk6Xj~rZ;m>5?>d({_g{!psdLF2eH{;d2$&Hc6N6Ic8V;k*Wz4qq#Ihb1F3Cix zi%F|q2RDu0g3f6m{<9NQcDlRp%17Hc{&45q0iAK-Hl{ zo%@x+L^=0LolDi@&Yn`|wm^$I*M%l|TAdq@W_2zn(5Q2%IKAJSUUlxRRNQJ{Airl| zV8k7o0|Nsi{y-^E>Rb+P)VWOlGm-f?FbxchqFPb?NvU&PoJyS=Y8jOV%)!CIZ` z;9b(SI+uu!I#=GbI@bi$>RhQsX7Z?WC74#{nqVp;TAdq*SL)nrkN}l=O1m~uD(K^; zIFyM}X*Dc~3ssSbJyVSWZq{~DpRdXOlPtogAw@kSouP(jr--7-2uxj`J-CXDO zH$tzOUim9_mj0HVsz0(*{W?1}pR;pO*?Z-~t1a|7rW2d2pon^b&S$-8eD{f(D z<*(UUb(EcppJ!+FJM64E!Oq%m*;$u-GsV!@g`M?%*x4|WosAcq*tzT{>|DN%ohvRS=l>6Loqt5j3Q1yL?srOtX`GbN0; z-RllYu32{+CQ*cu3q(o7DTb`a7(o|^l14lWe-^RH1tPWXAdcuU!pa4rqzSIbjG9a} zo+Cbrp=~wU3X-MNWaL-v=qT?7Fk+47fSQaE+ZiEhG7j!hlU+$vkD81zMonfSk(hEs zO?EZ9h%ZaRikeJnS1_U`lS<(5H-cSGnEUrrW+iA;(4r>07U^&&*sUfrX;2+8Onoc1 z0U<(L@E~2;W%NSmF!^Haqa|FJ`fTiOqVg;GV(g=e2tP>#^2PW;uh`QMl35$|C2_<@ z%gwecr4ubIRi%*MQz?w-tT|9AjL2eyR0;>rc@s--y`&X%B(P|N_ig(b^n2p z9NtNA-xD~RtNv`uqyfc9!Nc^S6(i+Ms23jn{uzwL=!MW>^2LZN#;^4Cmhu}kiht4h z+?m8isMxvWV`1bA6Cp-~Fs;_Zbwnj!j34w$CvfOck2Z4mhaK_5@H@abhN-6QqMDK; zH{@3}CA$iYn5j9i%45VlM#wPC!HtnSCjX4c#>gF`78}9Z$eoK*8M%vR)JE|? z)<*6eyi2+^az{kR$ep}tBX=gCHgXpQvt-Tk7`c;Rk14}cCYY2^wl;DXhgU}K#u=Ha zL5h((K`%AMp^V(sI^0~i%E;XXs41KS2hlwYQ*zBPyqrW4#_Ib4fBsPnS*scGA%Ff| zLI`5B`hMhm{t-uX2Vt!oF`nm&OpNCxlkq$no08dh9{WeG#DmS3btLm; zREHhKd>MPS`Lavsdw%k_uxdxX=r@5G&gTP9Et)LBI}hir$+}k-cdu zh!njyosxP9(&Wo}n^MbmfW=34fZ1n-DI;v7utP*=N^BH%5F3RzUk1xfVxy39(m`w# zvR7;rvRB(E?0}229g)cBt5oJ}qp$;P6f%lZCN>H?;6joMMK%gM;0xM8v5mqG-6({h zt;w$;$;2Sm3fYHri?u>(72dV^rrqvI;cZHcniR;dI;>0zjBr~kWW*;NL?#6eZmbnD znVXccR>-LLjbLr9(8Z~&6~;4aYlV#GNkIf_YlRNpC0$!9B%))jP~Nn)LK9G1D{Mj$ zq0T9Y$6BET)7A=2Fe#yIZLKg4udEeP9g9pgE{U~5L0i-cL?a;93IjkWZZ2G9t*{C; z<;x;&{`41Xg)Ss2S*#GMN^s>6q2gWe9&3teT_NjZ&U<0Wz z4j;67@tBV&R(~2qE1|gn_TX247PL-LFNc=>Cup5V%gwX?8?@&6Q|+gG9NV##?*(X) zf{345`F?=r7kH1ZJi*>!{Ur^DR(>9|CeRcLMR8!V1UQ87%Fg0h-7)$`z6@?h<;ZmP z>t>LLCd>YJ1<0G88l!0sgGSq&wExZD`x85i0Jm>`6ZjTj6B;70$@wUWnAow9N&7)s z9!E-vG3iN=ZbT_b#7`g;2`7V$yy%)3jxgItV7u7EW=-tWjY-KpENiDBJq-!g&{Ro! z45Uq4Cu-@>fu@tr!y(W5L(_!$N5tG`wPxP$VrIoXf2s^hml=LNn5~qrg72USNYZ(0 zVSFSg2O^4BqWN~j-2ZjZD)|dU!C#NR-YlilV5yz2p?bsq_clLmXvlw!(wB++*C_c? zyA**3p=S58%IMQ8HDf)Z1jBUIOptt^A{l9BqUfI8;el7j@BSy*2L~oN4vqc+QVi| z>>+h@0Hj@pG=btB)bnkQ_gRoSM81h{eM5Qyk7WH5&aD3hJ9{e88q&KzQ$xK#{k8@5 z6bai8)Q7(d4n_v0j;2t=L$c5kA$bZ>zmKO5${xzp1)y3fjiI;-9+D#wH-bECeJFl~ z*GD40i9~M*`L^nar*p)8$Fb+GII*)1H>m*b#6(cThT;_0E(e#l}Se~=XpMdwC^`~{3#+hQC#Oj7*~7`I>N zX%QrlQcbHFPpXHvO!d$a)U|x`C!d0YCD(cy2Z>2^uq1asQkeK)3C+Bzd6h!P4Myi+ zN&b96dj9%!WM|In5ybsLgNb_%6lIau;KXajsN86ve>N*En1;i-JksZz2*w3v>; zZK1Dl#P-6LuQspB6sD07{RAXf(_0V468%|kbE@hk|J;5n898csTN1%sF-b&@L%qzqzm+0#P| zVsf$5LkwbaVbjCv+njVuk}`$>)u7JiMri+gZVwyZjv9du-#`SB~HOJq#;lX&< zhpr-rnS~38@GgUx{qQOk&cPgmn9STjRFSs|-Vg<5gP1Ijs|AOyU=Wku6a7&ytI_EL zEzF;4^rgfaHP)kvMvXt@UWMS4xA5>OtOo~9PVX}{{VcrCOv4+XMIBS^9 z$JQ{Z=ENH2Z%7_n!+er_Yz^}``Pdrf*W`<{hM9rEL9Ai2Jhq0}i*RfWb0GQRtYI>r z*Ba&?BsBa8q)W@9^jP6%J?~L2ZwhOL|3MVCbIEOveM0%(8-|Zw2&FqxLWV9Ws?HnG z3t{Ne_+jXhHZ^!FLpC+|E1Ne(NGr;p-@IF5eV5@q5qDKc?mEA47EZ+F?#3{T6dn&) zRuis~gf2s@+Qy}9h(Pxh=+x)cy)NBXfDBuHe;4GkVN3c`;{^vG1-h>Q?jVz2+87~l z2bmFC_eK9}%!oxCq?!NKn1i$KD*&Y(lP@AN>%Ia|+A->4BbanwFnr_YgzhVV^KkKu zr27iM3LfKma1g~M48 zvhFKz+AmOdzAWNa8zKQRY)Q!tuwl!5n$SB*ff3gd zg4nFS*M_e31x9|2`e%;lO@y^_NT(K<;ED{|68r;5GO5thZi7l%ROsv_6*?)-e|bOR znD_0dtdQ1se6sX~Y*N8v*1-?{}uH=9G<+&pv?F4X-k@as@?6fV@` zzXlWK-1AYmP*18E6*Z@skHUp|wLsHRxKM8wn&in*xX>x_Xg&(Z2}J$e;G;2tiqq)B zc}$?AaL$;p582dX0{J~-0waEyRN8xBpFu_zt=qMbG32}Hn3K!^qGZNsU$x*n#071WDii3~B z1qMp1VM$!Ld=xHl+FBMu+~z1;V1f%NH=Dy$#eo<-F*r{5`PIUu2 zHBIbXw4a^YN7<=+m7V%e*lFnaYm%~T06WWb*;#QqJ1fs&XVr!5TwKA<>NV`F*}%@) ztJzt1D?5#Mv$Os%I~)GQ&c>AAPz;;;v9ozJJC_u(vt=GTTYtgMwzceRznq<&x3jbB zX?8CC8#|YM&d%lCA0(Mq3?wI0?lx!2-R4ZW+ngzPn=|EZbEe#F&Xl{&nR2%|Q|>lr z%H8Hnx!as6cbhZiZgZyGZO)Xt&6#qyIaBU7XUg5?Ou5^fDR-MQeYpHfPG+=1jTUoT=|N{|W6WL~SIt9Ze?855mO=7p9Rvc9K}wM-O%O4O=fTVyD&^ zM|?b!wrRv}3{5%MdLaXu zU~1r}Ly9!;$Km;qVxYfF_l72i6axbUJ;xLWA5shqJP!yZi3^txDF#kkj+(+Bk5OJu z4;=C(`*<-($u*0?pO7fR$RWkRaEc+Tgo5;?LyCbBOW@BUHaVoI7K6kQts$%&QVdLR zMTS)a?((9StHyK0$3@g;FYiXOR4*sLrUvxtPI~UM^w946f9!V8jfrR04;W?kr|-DYL#TVpP3c%;1g%!ku8Z8C;VFbUNx* zu|8l94ZwrWCyt;OLWjv0W8al%pra&`}>f>6m&o(u%*vW&SW_CftDB4Yy9k zW|MDzavH=0Uz`9{Dr^a0`?v_REw;qAuDvc~C9^31?oDg4d)$Ep@zyRjeS0v)-hFUw z5WBuT72ln->)VT7&bmHiRr-e22RO)<)i;E!KD1&+_~RF22e~g5(6G%Q)28#q?*-`7 z4BlfGzaOA6m3D+LKEd8$yG6*>i*F3ch>ei=H#XiXUS&caT4h2WT%|(plaMD@B4j>| z=J*YJK#Fs-+sI16_VCWr|%o+B|tNseus&NnWK~n(oClxFfqCbJCf4x zxe_sP+TDbmN$L0X#gaRopfuCzw~}CJrqlOEslSqDIx>a^Xdba;*oJ00QV=C1X{IBi z4Vg64k+J;h;GmiAOxJe zr#Er2(}OhA=~r@L(?c}VUF15jgN0@~U9JPW0`5slm+QbTzP(B5*O)v>u|hMQejVc; z#rKO;5ar1VKY@3xnNB~U)va|}e{y|y^OaA4@hkyBLRvOUj&nKfiAK5qsk%9=f zBUZ2Kb9FZC;;b3{5b)VhH3gxDTKroGgcoWk@1-bm`Dv3gc{1lMQW%Z)KHA#7DO?M8Y&1il);M{Dv0&83q@+EAZBNS zk^<(xWeG;JAEB9(XrhJ+Dm9c~NDUS2=H?+aRIqy~_;n~!Lj`**H<&2rp4Cvno~s=+ zr-=^#?5+oYhdYf?@JJBC{HbRxpgB9E#v<^#?63PN<>Cz}>fFJ6jjAv+ZJbwqM51&OPkxdXk+>|H{r~pRsd!^f8io zML%->|M+*7bI_DR)J9^PskQKfa52J#uL3SsODyc82Wy~)TdRDumKzncfcbv3US&>3 z!C*Cu9v*FOBQ=hO80l<$r4-Esv%7cYnDS;tE(?qQzf$Lm`?TPe6L{7v4D7 zpx6p{j`K=Zz=xYxWd+Bv`C~Urv>Q#b2i}{YVmzp1c?l3*dwl3*d$<7Qp${ z!8sPdx#TWI5)yu**-T`&H^hna;7i1028;Bmnm3*gKgMn{u~!V!2w z6qqf5vplXAu>el*iH;@w6@AwF4uC(_!4rLNv~B%1$^Ki?M@g1%jLVND-yWZR(D$a# zKJMF+WH%-4PqGgtJ)2}7OS(E_H-{b#*+)a)h3v-UKZNaL;X69n2RnV!$!<*DlWHGK zeJssBmiAe?-5A*&v6~}rM(pE}Z#vtJUB2&PH)h|K{T&8_2^X*LgWaf^j-4xv)wGT#*MD3%|ucCHi*Y~^HC%eAV%|71kH{I={-LL9l zH}`n7hkdli>pkq_JwEJdH}-nAw|%VlOIh~utWUD+#_Y?p?dI$^vhCy9+xpl|eZK8u zH}?HBW?knl0pzr&oqf7Jslu-LWs=>T^m~|{^ndTS8|}wz`n>yd$**@C&wa!*g46>$v zBz1r9Y#;B;<+s0!eXz?nREXDS*v%QwXV}Lwc4yknnNLvBy+uX0)fC;cQTtf*k*@a9 zuK(+0H}<~1x82l-SZ>#1-a$+nMXzey!@Nsir=vp>f^nDb$deKO~&K6Z1T zNBY=D`}~he?dHCAbKgh$+DH4o6SGgocJ#BG`W^0PAMJNlf4jN=BmM28{om|wAMgK7 zf4gzOo`LqkfzJ-Kj}83aK)Z3!%Y*FWgT5bRHx9mju-!cP@gerHAy*H#n}`27*FK*6 zX|COvw>!^n&bu$qKAQLEJo|Xwi~08P{B5J`rct+#whxYeY_xrB^k<{(#xd89vG%$v zudi+0;j@43gLcRlLz7Li?@fBtZ~0Jc-v{i*;PpYfIrvo2J{J5wXg7u)3)#m)|Di^^ zo9gXQvVAo9&1Cy{@;AwLV~0bX?4zAt>trAAbV;h+l)9f9@`tJR$<)iz?54E+Y4*Xi z!&GJepeo}!xSZ=>_%*B+fBY3eRi|&K+rxI z{F)lY=7`-C*+C6pe`ot(=Vv?H$2xNdd6hcI7V023QVdU01%E&le1N*e^AzC+QTt@{ ze_idyZnt%}4|ac~r+u{N3q9@QJzwl)AMds86l;aMEzPp6qsjJPlh^mPd}rC#y&?PA z&|kCc&$2$vv3zIS){c;UTj_27g0OB0m`kT-G-1iVhhS|2&U|-?8-)H%Lma*n(4j&0(LpB$*(V3> z7;HBUzKYtw^TX|9!*`Fcn@2n`!ag?Qtr7Og5nFTZrrb~S?8f}-^X=yRC-d!N`5)xl zC-V=Cv=5GaW2Ak270?Qu7NPPX-Jl6}Je`xJX?ct2FMskU`b zl6{^3I@|K4*;cd9zBTDy6m`07ed@DM`kR1{*jAzaR?1O%5F#E&4 zr%@dl#Imr#^5JIAI(x70W#CXRzs|Lf=6;-OpUl0NI@P;*_Q|~U`F2zOo%!~`{Ku$3 zKg+ipM_xM;vH1G+=o0Yv*s!|C$Lo63c1`cvvqz+7=U`n|T-zJ&Bk!bc{vM~LoSrfx zePVa$1_M@-K|nd+yu-azsH1>6w(^>w`Qc{YztvhQYHY?VHCVG(n)9%RL~tq zc|@i}!7ou_rIE&g`RYn)3a7`i(uP~^gi)mF5(tLMd_Ib;a}L6dL0nzB_(rEt#FmxO z$wXU#*G$sYMguIrtKte!nqZBXLqpTro$x6sg6*M2$!pIp5H}8S_exlZzH_@$A@)vE z@k^jnhU0sdyyLo0?4FOPvM2$gASHXaud0WamgAsir0W2EMj(J6*J=93Q?YPQ=iKy5 zQYq^{7O~+>H96aSh-6^0MUi(y2@TRUSJs74RXxrCaXafH9!@T>u{VNAbQ^ENF* z%Fra;Dm8PVLzmK>Olcg~eUz&DDK^qZO_Ksx*3^N>crSFGB6mBbHZm=ftMv>m&q*j1 z$n;*I7Nij43?~!1xt!^sbb-!vl7UM(@j^-DSshg!(0_HE?e48rsIqf(5NbJ;^VvG* z-h};#8WYt$l>Id|mF3x`l_gb+vX_TwjW#^3^o;y4@dmv+n<&Dn8+wlC+!$%K7 za~e@!QC^!nVrlu(;iWY-)(8?%QCd=ufOR9zFRd;sA6`;ZGh#}0RegC?ecgzu<;%(| zt82<@N6fA)sb5%KyR>e^StX_C%sqd2jY7D1=1!ey$aQ5)EX7IQ5%a4n8(+!tSPnT7cVWTtgJ4zs^(U#D#z=>+VXO%=B)Ci@Yj|L zt)i;l$%Rek`YvMEj$GOeV(q_U{Cwz_s&Lsh9& zw`v;7qom%dtf*5QMJp=mEyPgYP$xlVfi$(Ec20R|18Qd(60mA^N&RALVMS%RRaQ}J zp_FS^T4goX!iLJq;u@k+_yr9MJpxQFidLXvsGhCL5*_R0lF}vhwI!wHDoAxn*{q5M zwIvW-Q@0AqTVR6Eu0;WJX3njubn%r{H!MJkmX#E9W{Qg!G*nd9qeL8x@)g&YEV35W z6jv`?SXW+eEi}GrG{A+G)ys=ZY8L^@ORU=RMa6X`%gW_V6~z=(Wn$m0?LXPmWfM^kP&s%5ZOod!5&JE(2!dAYD&t=D$rUOx3IEg zQJvzeE+sOg*0WS;Up4iMQ7~o2OB?FTS5U*Nt|_^wp}e>Sz8Gx}!G&xU*OymTQfr~6 zfk$y!`7&~rqQ8<`RasHBggjJ`a2hJg$XO&#t>Q*6M+dAaN6SS}_e-h!WkE%4{bDzQ zO94R^pj?*JQQ!rYOEgllOp&2r;8fPtpzg_ck@yffWmNYt{fZhKnGXVG!A)21oFg|L zIg=W%K#4lykW+r87Qyn6XE$A5O>XL!p_P?daH_~fYjZQ}SKYdtMuiNQR@J+C4Mvqk z9F2+xC^g{bjcBN^tgEj@L*cP%%DMHGbNSU;ih`*xv5GG|J1^Hk=jCExF0U$^S5i?~ zG<#+#4fN`@O;)tq#Db=y)wu-GYn!Ys1QkdM3hRrOI_W7yO~l7Hr+g_!0#5i+%Xw*y zkrSpF6D6xaWKhJKt!1=hF}_QI7A>=kKR!<4nuQr>alLSfKc1^}+3Zr#Y0@jHuddCe zF(P|#ORhOmVe`vN!8N0_$Q_1iQV8QH_=N2K@!?D67R{MCx7b88KAxfcBCao;jPWfP zs>(eKIV~6d1#6<^ExDJt;=uZm>la?%5^vgt@H<2&~TQv!NYB) zZ85q(BogClp^1gK7+OtS~TjrWqw_)H34-D8sJoPcWHj)YlUeph7VyP zUjnAlbINImkv>7b1UzHFQ(n7FGm$p|SH+5=rKT1B_@~4%Gp=PbOUt}U6VBxp79Zr) z1?5=SAq(tUGwP)?C6Yc80~;9ev?wDOH9fOBw^Yt;305eR8x}4sua!=P23x~rh=yB8 zE60-h@-i+jYPE4eq$$TEIkRIEu%kayWsx+btu3~^Jn+rI@>KD<-ng_|k?yL%wxrXL zg%xmh?Mi75;%_rSYW$-5Y9(%6pEG}mp*6a@=3C(wQY!(LtJqVs zR3kI0D(WjrDp3Qqv~*N;UWesWg+t-xsv;E^=UEG?t1G$KU6bjQe3V`N;tH(H^kij* zuqkiyq;THvZ5I6W)VK;EMCH?kDIazT8UoNP+gBNlcg3G z)bvgZYjQEyFQi8WJu3NumW1M~ucpN`JMy|vUKd*U+TrCmXqAemQfQURZ7^=7Ra-(M z96w9tW0pT~)km-Xz%5xopDO4y^d-rUV*aRHRF3aHR9M~0x_TsDIScB_OKMT~7uE3x z&V?gO7Sv5Hs4CAZ$j!^mEw}KB??ig=v-rZ1$gIP#VgouxjY`6~-3{wR}gF}+;Z zOKn=e^Ou=sGYfk2tp`eRWjQ{2iO;;SO!LN{0On17Fu22!G?5}-h~||;I#doy#D%U1 z$#3GL7ZV-5II-z4EY1WnZ%$Mu7-EukZN8HXhJpzV9%|Z{AC1p^UzAoaU5fUF@4#}= zhLA3ywq$8t{6a5#@C0XAQN0%H-MFRPT$$B9>wtK!*)ze_av|noQwzEu5T@32tqF6j z+AuUGPM3?PtyHzSxZ`xUxw->KTgy9;UF*B}0asDgA|V0QyC8@!dG}f_L11S_caO%1 zQxoFl$qb&CVC{xLX7Ppv)|7@?R?;9+?-~z$1$tRmMvElT{b1mqoE?QgC5iQ|@u9cC>yXJCQ z7_V1mOp$SL7REsy=JMT`yfITS&DNK@n2IW9&n~rEpc916owB&RbjfTQRQbExc}>L3 zeDg~x8{{M1d2PvDP*_%`#6r)b{4Lq?@?>x_tghDt+_}uhYd|y}=cOg<*l872Isy2G zH*YOD3-B=_(N~a?g}oNEy`}WP+N2nZn?>b$@bFh3dGJ-2$2xBm8w-pZpLluKR*y2( z-C9#O65=Gcy}m_XZF_-B42f2_z?-oQX`{|*xd+Mkf!1NhcL6akEvcyDDY|-j6{&Pt z#UiW!mi=JLWT@fG=0fFOp0J-#r;@Ok)r)F$$z#BT0vX@ZEhJJM%$$o=OnjG{Aqf{@ zMWZORvra?{B1Ag_%k<$1-M(09ME3-XPvp2M#n@7+tuC%lFlJ0SXTdL^i{s@@;w+9) zED5sLY64A||C?NyKrM1qG!I>+ynbeRZB==tHLq~a8AbDoXBN#lyJ%MNtQlvYdwv}5 zycuUtJ?Ff+aoDMab3lkg&NyeTrNmE}eXb_LTU>b7)X}5dh#4abM!Vk&3+GIk4i**s zoEj+1D^~HYpk|v|H2K^!^vj&0Sw)3&i;CyYE-ISZ0*Spht7yu6*^acP%!j^l#yMvf z7mRiMV_p8dJO`gQ#_{KmbonoU#M!frOn8;lu>}?p)Emiiy^Zp`LAFE7&-J_^E*EWz zRfHL2$voP0Dnhl)EG{~~Xv(?s3MbD())+DMg0le@o8RJ_Ed*-qmDVwcqCFfmf(r_{FWd6En3Hrz{W? zF3!Ee%;y9RvTaE;b0vRI{6H5m%=|^sZqf2dF*4C7g*Vmu^TL^dp>Kv>4&Ov)VG76g zb)qj1S0`5M*VdNc-q_luY@Y26)BX<=Z#ZwWYG3-=`@!Oki9TNPJRdKf@@eZE#w*Ba zw27C2iMd<(Z1FO?n{m4WwBwt{lgq@PK5;CjvC9HXtxZp*Qy68~L?Oq5j;994M&_2* zR@BtvAP22>aJZvti5FAHbW5D6vu0VdYs+aNMJ;xU4o2rs>aZ5YVyX^{#L~)!vht}o zjzN2w6`&~8G-g{cZT5^Ji=I=g1yjoxG%T`8^;C>gMB0lyj5RTg!ABOQ7E4Fvqt&BB z&mVb4c@=F6(bpI;!XXV-9RjpM!BW|z-*}edJPNI-xO1M($3reWyFiok&~7CbmGS8% zb&FjwxUi6}3rE&yP_!+PWm;)X1GF2iH4$=BpqcV=@hLP9RZ>~5ww2Wj<=4eEy}GVm z!XSR<#mhBvYWc#FhDwLg^X}H=c~<^$iwPNH)l$A4n!VQfThXQ^44{`02~>2g^S37g z*ODNy2GAqk#oZp^dAV&aA3UNpFXz;?@uQRw9^ST=4j#rf77i`=T3I%D_`IXLkP;=Z zttEp;pfmQm7pw_cT93`GP4cb*Jc3$ZDtOrR+>GUQ+>Y+JxPH;f?BAx@pQpEvR3=@IL01?^yO&rIu5fKWbXI9tQK zY3$@(reXax=I9YHN=q75CmCyW3@yIG5{zuEaknz`Bw%l2*ldmahlRTa!NfzROSFsk zhXv~)u$2=sF0q=kmBG@*+160$VryfdjN@u$m~?S@yJBng-_{W666SOk_W+rIp|yD2 z-NHLKx`eboG`g7dz^I!yRIj`ys$0dnXsmGzg?dJd!BbO3iI%vFx}s~>$m!y5_qgc_ zGrBpwwAv<#WVEo;6i3 zgz4jgm0;DZTE#H}K2}a22;y7m{$@}pQN!xPHb&T3Y;6dsXpYv8(sqa7Xc>&|VYsns zEz^hCF%CP!I0c!d4!6gL8ST&}ucTx4t%Ve7i#REXO193|%GN{}hIlEXNOOoKJ~`-b zCP$vdyJWiMPP{Id_DnsAd0QF6TQIjV?Ih;?A;GR`B=MAE#JV_tNT{AfTA6N)NX^&E zWMlZ+nraMF8xxI(r65#zI?@G%>??l$Zm*^9uD zaA%UvKk!DTa~M<&x>&*_`m{AWyRHdETMym(nVQkJ}Z<$Pwgc;(d&I{qpQ*gPdAP)pq5$(*Ww~! z5xeNR3`~>>ceuS#>OJs;jnK=g55u;DRZDfZ1y@2%Q6v=QW^6M~H{%b)XiDOTV$@}r zxDUBv)Dj((4(h@$Pch7X*!&a+q^5f)20)q-P1@6 zN5ZJRtZmk2qnK4wu`UA?3N$kNK{IyiJ?5GQ~6!r}7Tih7_L z7FalRi%XyILRtggPpsl+B}n>$p1!4t$eFgFgyeA~3u~(DpyF1^I$tm7N7Uk8Zh0-A zP(itPR}7vaHN}!}w=OYj;=Q`WyyoydwsTcZGFxs(yYt!BZnUck+DMA2 zrG%3krNCWXiB}NB)s6+YJK>2nI$n-M%`M?_k>clxzHXJH;=s+5irVU`rF2_Ap(H*3 zwwiGhSL+;FMts|Ed&ywZOX+G=xRK!&o_N~fNj`z5zZGtEsuQC-Po~O_guE(+*oejD zmAFjIQ|hAP#n^$yflf@~^eurA0o%RGDunBMg1n2^2!ovdBz4-XQT+8m4;q6AQ(#_5 ztTlr^zvuD|AxIjyjU*v<`P59@r96?-hx`8p zvzFXO?54Z6Cw5bM?P8|bb-yfCU6L*3P#g5zmYPCVbqGtRjpJ(>1>lfT_F^4@*CvUz zpKSzaMG2ZXgkG2>8le)VNiWe7-PQ6&;aZ2aCl4<6cIKe%lNNEQZ*wUZm+&?gbzaUk zmUk@~TUqFN8QWO$c^TVU{CPR`G9vEV%Tqp@M|!P>QmhxQP7h=abYblxSeSyMfpj z>8ia!+Pxt52J<$#R@S55AnjZvdjloVUpocUmJZu1MmN=VB~&vfUdnj|yBm0W_}j6p zZqYPaoF{QgKs62bH0EgboJ&FpwIhib6L*zFobG&0@oyP_1QjRu_q> zdO4AB_HQZV2iUYUPog!_od9n+nj9n)AIIC~YAKHQhof$Lt>hKg_EIU1H&N7yS|ci& zFSf-mkrMK%&n58cszGq9HuyZg3&rb6^RANOde=cbX?BT<$IJTEU8|X$(DFj zYRPBDBv?hnIKiim)HngF7v3*0tD29Kv?#ciQd=vH1e|dNQ4dXOc|8{fETGWgYz$^o z%a>KaN+Q1G=HgLEmNTwNCBxt_+78Gii<*FDz<$7=051dH0K5Y@0r(W~IUtMx5kNmc zK41c%5HKBZKH#T-UjWtuwg7elt^(W$fXQd;VZft+#{sZ8Z2b`cJHyuB0UrRq1tcXQ z4nQA3f52eC7{Hl;9|0}^ECH+pYy|8A+zhxI@F?I(z#joG1KtFj0DKJi9N@#BL}UQ6 z0K)+VfN6j;0doL929yJ;0LuaE0XqO!0h$4K0v-dr26z*20`LjobHKNNfQ^5A1Hgo` z)e8Wl;?@vA0iXyl2T%%F0%!m<0=5BQqS=D^W@|6tF2F;8#{tg({t9>-@EPDMKr$+> z3t1Be33ILM;(*WlJiUAdXTEHg2rGQ%ihX9WQo&o#|@Lxa|{0GNKzy!cg0IL8S z0k;4S0G0UjV)Zd=K!U ze|7|P0(1uS0`vt81{4BH0P6wNj}HN!0-ON+3vd$fH2}u0ttg-mU^rkDU@TxfU@Bl1 z;75S@fFA=&02P25zzV=Rz-GWMz?Fa-0DA#<1MUMH0z3+M0`M&0FM!to#{vHUd;s_q z@HM~(yS*I%X@DF+Kfqu>E?^3P?EcOI%mJJaC8~{88cnk0qAOb7ervRn{ zE(ELwYys>8JOFqB@H*gIKnEDG9t0Q#m&<8LQumn&8*atWc_#Yq&E74~H)&cGV z90j}x_!r=NK%^J?17H|nJYY7U3~&+P62NtUy?}#&!+@s%F9MDOJ_LLT2=>N20O$kA z1xx_U0$d0v12h130Ga_013m;~or3-X*aUb0@DD(jEVL;=CEzN+QNX_dnc3)TfS&;_ z0o()l8=zwj+6SN%Pz|UDtOeWxcnOf&2l4>R0s8=t0sal>)fZ;80lNTq0GhfVTlB0kG01ywE#MZw z^MLOFgNGsyfc1d=fENH?0!|qQe!vpI4!{AxF~ENT-G-x$00sf_0I=(B{TQ$Va1`({ zAZG-Om;=fHy8sUY-UVdm!k9eZT)@u(6@ZHX7XvN@+z5CK@GRgzfbRjr^DJv3;3B|g zzzu*~0Cxi(1AGMNk&k&7PzSgX@D$)Apxa3F2S5p6GhiR!Ilza2lu_s}fZ2eH04o7o z0apW>0lx)&0667T%bE$e7;p#RVZd8}4x=$X0IC2R05=2f1$+Sb8qjMD+8kgqU_PK6 zPywg{)BtJ$%K;k!y8+h&?g2aocmePqKt=)L02Bch0WJsp7VtMfa4h};0B{aq1>hFI z{ea&CUITmq$UF`811JU50X71D33w3jHlWk#=nH`5fI9#O01p5j1UwA*E#L{jGl1s+ zuK?Zzya)IY@G0Ocz_$Q<9Of24Dj);U4UhvE1jq%928;tt0n7pv19kv@19%S*7?1P- z#sMY)Y5{iu4gd}U9s>Lh@GRg3z{`M-0nrH0FHvcK4UJ_gl5ngdcy#~ zP!uy7CO{VKg3E9ViZ-DAKy~N_(_u3lgJ8 zgFf&oY=Xn^CzNW;`WDh)1$+;8Ay*UH36zAVp*Oq^-+-qnZ3a@{C3pwEgJ3iIIy?(w zU?uE_nC7epp#e03HqZkGz)%PzU7AcL|H4@Rm#EtC?pa=S znHv2k4fnU(kr(++^c<3Dr! z-v#>@M^`@jhX>IYPK_16Co@QwaLK{wbx8qksZUjsTce=^S=Q)i2ikej?MoA=pg#?fA?7a zlqT%|uEdIeWvTXh?6LC0|I!%U7uWuUBY@lc@4fVN*nj=00%y2o@OE%&<=@{>TWT@A z`}DPML{r`KtySIHV;KnbuP2<@J2~JDw|eH^58r#eFkjva@ju=)>^?)^)=PtV5o=G~ zXv;`P=Dofg{QEmz;>w$B-RC%o;om#V>t%I2hk8w{d#G2->QFC!wa=JCy^A(_IeNEl zac?IoPTU~OD`cZL-#g)Z^Gez17txb@MT`pfzuznSALspIqGOi%eT3DuTD2<$NRTL_ z`^C73(WU5OfoU1Ne<+K9R}|?Y5a#jvU^BD82>88V1EhtpB`4x zOV+s~dgkiIqo@C&9cBsfBI|lTG8aTYmpJ&z!=4Zs3r(B0YgVCZg$nxqWf;o?M+>vo zEyEsywZh;&tUuCNb1r3#w2^fT_bALD=y`o|TM=^~G9ToJf)Ij2Kyds=y!||aC<+M> zhLTVUh%TlqB!WIlP$eJ>F>D=TSdz!EJdRf(*Cc$Kw0@GkRWWcL13+BK- zU>>{)3t>blI0>iVG@ONV5dHkh!3DSsSKvC_hUn)m2VM_*BJe{HazP%5e)4lHyFomJ z;6W%1`h!w^iXw}H>d2Z<3u;4Ms1LGDG==8S z0$M^F(5D@;J#>UF&=tBt59kejAr+p7zr#S#X9#jA40q4<=a?fQ9c23$3*+Hsm;{qy z8t5|vISXEcxsVBqUUtRLy1Et0lUYK4tX2iwTzxB)0 zdjGVX_+7IPpZ=xQw3LNcQ&v3uw-GC*dVVpY`6d_Im%1mR2is_vq;A&z6l`yj14?@{7NJD0A=w2d4DcvheV_ zZapin8}PvFR&5j3581Hy*3kYbAHTo)*6Gt#m*yJw>-*K0jmTej!}gYk&&=50=Jmwg z!(N%xaBJxaStF{YK09;r#Va$*o@=xyXa1^2vd>hh69JbtC*o9SV{U_&sKkw0p9!U9k;REN+Tp8w+%s=sTa>;|)$I4du zbI^@R!L+=kI(Enk7Wyz!^-%SOS)I=;>(G4Umd%gHf4U=m!-dk6pzE64ar@q4)tu3|a#ba%@cWiyRcHE8+rzbyk zXlGihj@zdVd+cP5*^h54@<)}edE;6)UDWSuZ@xRrOC0~Q+{WKm?7P~+vwTjAv|=Bx zEm?Q`kcU3%v426`n?IHPw9kRcw@)8Dzu?h8R?g4{GfIt^yC!mKW4VI0Qc}uY&MKaL zp~IaPf6TvlU;Z5#&n9(Tx$=6a6_azHuaWQXjj#RVg&(^eT3dbclG?xS?tJ)>fs=E0 z8TQVcBa!1b)(qKED9;xM8}FW7zE{y~U+v}-y?3)Od8*84+pk%zrVnMtq+RY@q3ft& z1rlG%vu}B~*S}qTcwqdp15@6Auc^KJGs zTk;%VH{{Zwb_FJnuh?SRoGW`DetF)p-@n+^KI?{%A7r?4{&I+iQ2p%1X<p6W5S%9U}SH0x7l^k>7{-)K0uZ1a@4Kb#sp>Bfe4Hk4cX zXUemw$L8e(Jf-_T9LjPEteIE;(e-66uPHOX-XG&ePFX&u%&zU%zdrtH(f;$6Pds0I z;jyyk%AV|cwsnDz`p$fGbnTRhyXVwcm)N!Z$wiCa}R%+F^K<)cIpXL0tZo{sjS+`ENzBK4UsU1TyHZCh)xax)l4d>+> z8sG2d%9YO+``d{5y&hX#ws*pi#_O^#Jh%FKdhQC}+-&;G_Cn7G%J=Fr_Uyqu4Guop zeCzkG?D_8G_3TMSi->$Z7c4Axy6u+k`O+?(NIZ4xC;ar! z?H|0*w!yJsl|!{ox9N~oa8c=hZrD)tllI}5#~v)vqTiVhW{pT`e`Z!*#k9z;9S?ga*U$^ z3glm3Ff)D5v}t3*f80$Lm6vomf3RI7->^oBtG>8gZg1PB8OPhT{ITFK^J|XzDtB7m zsz0{b-XULy8}p|=Sv2n58&9O3ec^KdL%ySp2S0Xl`b)FEU66WhcE-Xci}u`HUgA}6 zpP!reeebt?cb3h$RCUs*+DR>^jXOA|N)NAh+qz$x#jblU^|k#ASAI~*_j%V|3I9l+ zkUXJE?|d(Id*D)V>cod{j3`-paK^QUpKfe-d*-MHh5Nl$b#saJlk0v^rr)WOeP4WT z&gLf*|F-^*(oORn?l~#rjjYoDoc?P0Ug;HU{i}KQ$IY@|-QVV!iql5qYmhZ@=Gk9I zR#?67>eeEUq!lkX?uawDZGruZ4@`Nv&hvk~(0X$2%1K{8P&rS##4jFg)3jjH?bCtX zbzcars|?6T5sgxib-CXnaA5ZT7N3Ju! z4c}4d-Ggr~ELQN#FBX4!K4WZ)hcffG*ziU|=bE=#-bpLDBzK8gYwz3HXmGWvoo1Cz z-gD)>m+QX#dC|-X+uLVVDW94C%kmO!0y}?Mc4kgm-iDoqm-%W*|3lR-HH&Q&*q`-7 z?j6a=bN9D-=+uL?&d+;h@Q=ZL=W`FK{$1zJ=|AWGHu>(ZYJK8HZ^_DaH0|K|S{;M& z-KNj#S?hY{{_Kxe9ax-}vv~1}owt^B9b4t{?CwkJ6yN&MsZ9?A#y1<@eci-|Z(gnQ z>-up2t#=My>Xd(C%cqh{?wp(cOV=wOH@sc6=z~8bu4-TB(e)|g6ZhUYl5u?d1kcJJ z`nTPF?&q>6FO*A}f3e1_Zp|jGx%yj$J^2@o`C-+c=lg}TYhADUOzNI~-?Yx&CY`)= zl=5|uu1~sC`5H(^DP6Mkv$AK&zA0U$bmOv7Eh%nwi_)LUjwyShY=W{K%MLA@xpbkj zqsoROJGbno(uGQ|FFy+TN66MCTc>R1vZqStD_;QVV5Jk3EnYTD*{o#qtAmt1UG^T? zXXOtd+n{W=@=1`-f_xFAN0j|rI#KEHWn-0XOTG@Wl}OhsU84LoWUH4gOZHFM5M(oy zzlMAwP{B<_`-R5mH;M&;)syNrAnv~HC@fb^rXZ^%|6{iy61vS-MS zA^VH`F=Ve?!2Qy{%2p=(vg~NGwe+Bl9=KrlKn__ z7U{X=qamA+bkMSq%TM5$I`kFNB0G_MLuB`tjY>9N>E&hTJVJTOMkN1(h}YT?WE+?M zUAAi3S7g_bjY~Rm`He`AE!&0sZRATL8>H;#@}ZHxi2P<`!;lS1c01W}z=9ag%1+2mw*mEVnQgR+;% zH$nD0`4hZU-1)zC*Gj$d^X8 zT=~(+?k~TE+B_>8Xg%spJ~Hwzl6^>aZ`mNCwnObCSP~>{Rj>ksaiD%1*vZ^7;9d=Vhb24=LM>d?sXnlAWa+>634g zY>D#qkj+xIborOarY9SttDtLq^kq* z$aXHflkBqcFO$t#zF)F=4nWFJOFlTVgj|l zyPEvF$qu_xHYC4)P_bt(qcM5cjyO$;6)e< zlVK*zgT;^q@4+Vc6mEfsv`U{L-9=+)1)V@T0_g_c0qN(|Ca=OD;H6%2Lp(eM4WK!+ zgRkHl_zvU?c?N!m8}KItDbIZHAXJB^p$W7G`9h9?S6~Lb4vSz5d=9(d033mzp|+2{ z32mSY^oHl*1xSYpFdbflH$m-oHM|d7;2PWkKlPah3PKSm35iezYC?U`SUVU-!U9+Z zYv4233EzUBddmZap*WO*ijV|#AQ@UhN9X~mkOBXI1+Wa(zz6UVd;z;bW6e=G4Hw}W z+yOuRIu8_tB2W?%p$gQ5`p^v8LRaVm17H|TgE{a9yajvU5O`u~?@#~=Lvbhr6=5m7 z1M46McECP30cYV7+=Lj$r&!1jg&+Y+Lnr77{b2}WKo3PKSm35iezYC?Tz24g@znKR&ZSOhB|8#cl@xD2--mht34C1z=7Gk{EO-w#!Kbht_Cg)T?__8R9ia!L!eAH)nxCh@ESL{VU?r@D&9D`Az&2L zDuR4A>p(KdU$Y~~S91xhgtf34w!#kh9^`|07B0a}(7+W7`C$}{hp8|dmcUBb1fRlo z*b8xt(FLF}w1Q616Z*pt7zN{DD$IsVSPJjJI>>=-@HHHQ({K^4!5#23-sgcwK>Lhx zP#J1KJ!lGTpbPYd=ivoNhY9dG?1BSu1b&7vb6Pp54o^c9XbqjA7d!_;Aq`%JX)p&g zcOQVua0@)lJ8@6|3PW)y0~KK^%!W)@3h%%=$boI}HSC8U;S`*QD{vbe=CuOQ5;{T; zNQJ>L5+=h;miGIS`acL5l?P!ypKzn@$vT#D_6dE=s5QdeZG5# zq0qgAkeRU*!DAJYwP8gxVT>e0YRWpE7}Xk_3n zor$D+YB1sI`brvVOlIZ42!yWBX7Y^5bb__bdBmSr9X2!Kcg%f0-wGyzn9Pu~oGA2s zZ3+SDD^SG9z~d(TNFZYFj|7J&*z0XgI3ed@8Xot1V>KBd)0nJ~P7ekz$-4Hsv%|y_ z320D=$qdKsV}Q>Ld*cZvGweL642EM55m;t8u%1Sk8TNl*gio%enc-mbk|w~o5;g*F zCL=K6&tibfjKp@J&y%Yuq>@aek$CcOshAO06U@cE#T7uv>1J~pc!WoE*Hns}>z-6o zf?>}ABndoj6Ik3PaF|Wt&o+TuZ2~{D2^?k<*u^F=pye_p?yZd=Anzm_o>n&Gbej>r z9Y**)WQKfKH6mEoh=A4(N~p#UWvY^`0_P+-<~&f$R$=gpZ30dc<~6Q+`%u)}t{SF9 zYMK%W-c(DD_-2{59ek6m52pbQp-Aru8>CM~r1L+N>4>*5AyT&b(Evj83gNaS8Hj;K z1hmN^pc6&}?`L^TxmPg4*VT$NdvTf-EA7RNRvbj=iOQy#g`8S8ua4$Tu6x^>JcXQ! z=6cBUIcqmn(ll3|FftMxKoxVp6C~j@_uyz1b|m;=f)Ni=<(xfXMO)JVBEAW3oQbyS z28NoZ9rAQGVLGvelwT+KrmEcWl~5%|f*Lds8{GoTumu-fZo&+CJ~fTUalW$M&3BM| z5XM)gJ(?y)B}}#to2IKiYBL$}9WZlP=8 z%=O?Qn{NLODq9WnEzV0 z+uSP$I&-`3f8M=*DnaK?V3yjs;~S=S?!<1f^{y$MxK`Lq`wH7QgKEay|30^ag z#!fc%9LO>u_^!DvjR~Px?IkipL2XSlLxE=zJQhLe-a*ORnrg{y0YZI3XGo^#U~C2QFp=bLY3 ztX5-$<@w%Jvd^d80{3|~AQX=Jvhtg3L~xTDlM}14hJyP{gRkSuPl*wR^MtL3=-3?G z;f_oTC>FwUd~VuyFstiaEfeW2VR~&O@U}@y#Fr<*Tn|n&Ju>3#vCju2SK( z>v2PEIG(3%NAP!2?j!zQW`yX;P0ihocN(2hp{lua_f<8kNNf>19?QXn z+8A!f<8ii;1*h9aW@b?yS!*AW!j9a%VIQe%AF*W-asFlME96PDY4f$RW$y9V*nO!c zXhv3BH)dicv0;-aZ&i~MGfTVW#$bNL<}1TQYgQJ-t_1}N{=+81p(MHZl@Y$HR&1lW zbIS=UvTZ`lB&>TY+H*5w=(e3EAHJDx8#!R=#0l0?o*mx=J2RQ0=5BAIZI;p7gIjIa zioI^DHg=f3-xQLn_Oz*#kdtky*l`Yc6l~mgM)*z`;eUiOqcOKKBG}Q0KyO=+!P~ZR zd25))8FF5?)$FV9HWtm1q|77t2IX&qX?!71Yx}(aBby>;3inaqb9oHWz?7};TU(4v z6YR6`w%&u$j#0@@D~{=H5x;h6JZxHvGWVLvRLI%P5TQWbc53Ei&b{s2q)C&*d2oOY z-c+8#QSBj3lhpU_Z07Bw?i_K>nr3H~hO`Dvi`=8}ghvM?n6py|ovN;prd15llI6D_$01%33%!MdNWeP|qym{0)ro z-F#FRgU7>qkm1pGC(}0w&@JLn@QNLp+_^hiRUzLQy9)H3cWc&bGw!_Ww%3KWbp!^R znhtsP+E!y0JOn?~_RBGvPa=-SPfBZ*DJC=hQZHJ!BAzrNc-nNqprRqWTD2p}TcJYd z>=AkzVz(8)ntm7ZwYCZIZnJI1k#>XIOe2uYWt)4zUFrDjbCKYA0;K}{M{G%(0fqbB zRjCu4YMu)@+TogwhY-&%2 z1gfUGt;8xSfUsY`fK+;m*p_CNe%koFVG1@JXm5gudC3OYhuDa0Cqp#>hE2Hsb}IC+ zZ;%nrN%hol>|PUmuu%yUyqO}1WwD-!c#qn?t@(-iX`uu~0w3!^yIki?a~cg(QyGQ7 z(l+rgP1`mLDlYzP&;Dr}ye4QK7+{2%rd4;Q_XX2w#(Za2n-M3stt;=_wrtICOqxC0 zZSJ<(;`&n~PuMXNPdN5V)8_q4C@$LkTSoZ0k~>QDDcU^ih*-0LbKAoN6G!D>B3}`= z$t30Kd&M^JU?Mae59x1W-ZVt18p-%wq^kG($VH6I==Qc5molt2tt7} z3L)fkcR8jFD-8X@7wP%Hj%jA*QoE65PxUhTD7 z(dAohMz)aOE@OSZcErs0CWVN6^a)PQNTwZGy5foVrP}-iFPiFzL^patyD3YG`;mNS zCiyNH;dQ8_%p@mCYv3e*G4r5;y_%49&m?g}I1NVTc_nVl0-6FTRCF}4#%*9Ads zHkBataY^-VJ?9RjzGqCiMS|+?TsM1WG(f%~#P^+v!wJq)VL856ZDG0VSI0xTbB-OvG&H+C&spHsjkf6AXI3tfXKYT* z+J$q^1ltA8`j_(bl-2FwxW|leDjMN`+=y5!0z=K2SDlm*_6yZ6!;P)F;Oqo_8*x`! zk-%uv)pG@3lG2Xwcc~SGwQ%1%a$IZ8g)f?+hsam>~*Eyt{F*zngnOjp;Q|Qp3uG!p|v2Qi)m&d=YAWz zr--ctGf(JyjkubRWlc~j$J<<(Wj5dY^)>-iig70>duiTtlDx5$>oIfayTG9uUrv%! zi_Ui19QsRB;up+eYqb1UK^CP{t&2SMh!ynPQI*;hI;kC0F zqlPUNGjS_Hg9r%A3bFa+zFc@{u}_a6AKzh}&l4kF)Www(0-M#=qRAKg-77)5c%RjbDp@!ZQjs z6__@YNHcdKW3>s^x%!dX`E7T7V*7>N2fNjyp~Q9?Ee1)Wb|G$(i9uQkB2c&H%nm*w z=WE;i+`-4{KL4$pi}&=U-*CT~V2M9gmQfUMNf0e|J;u z;W!y;iNBDkV5gCd|FDf;h9t)192@`hHvZNoekTyHDss^3A`zo`kQFf%Grbq)bO#%DlUq+2<(TFhm9H!W7)S;bXt%*PZl}XTp z_{*qDLcZ%}cnx`Psk(FGWAhN6jQ%0G#KR!Ar(8}Jw(SCVQvrRrA5n@PUDvL0-;SI%~eA+LPbr*ONoe(!h_^$Ba6^# VmWx_NA>0|qC)E(=) args; V_printf(" CC %s\n", file.GetString()); - CUtlString szTarget = ""; - if (m_target.cpu == TARGET_CPU_AMD64) - { - if (m_target.kernel == TARGET_KERNEL_WINDOWS) - { - szTarget = "x86_64-pc-windows-gnu"; - } - if (m_target.kernel == TARGET_KERNEL_LINUX) - { - szTarget = "x86_64-unknown-linux-gnu"; - } - if (m_target.kernel == TARGET_KERNEL_DARWIN) - { - szTarget = "x86_64-apple-darwin"; - } - }; + CUtlString szTarget = m_target.GetTriplet(); CUtlString szOutputFile = CUtlString("%s/%s/cc/%u_%s/%s/%s.o",FPC_TEMPORAL_DIRNAME, szTarget.GetString(), hash, m_szName.GetString(), IFileSystem2::BuildDirectory(), file.GetString()); CUtlString szOutputDir; @@ -63,6 +48,13 @@ CLDProject CCProject::Compile() args.AppendTail("-isysroot"); args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"); } + if (m_target.kernel == TARGET_KERNEL_IOS) + { + args.AppendTail("-isysroot"); + args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"); + args.AppendTail("-miphoneos-version-min=18.0 "); + args.AppendTail("-fembed-bitcode"); + } if (bFPIC) args.AppendTail("-fPIC"); if (bFPIE) diff --git a/fpc/library/helper.cpp b/fpc/library/helper.cpp index 74cff96..ca9d2a8 100644 --- a/fpc/library/helper.cpp +++ b/fpc/library/helper.cpp @@ -6,6 +6,9 @@ #include "unistd.h" #include "libgen.h" #include "sys/stat.h" +#ifdef __APPLE__ +#include +#endif unsigned int g_hashState = 102851263; unsigned int CProject::GenerateProjectHash( void ) @@ -23,7 +26,13 @@ unsigned int CProject::GenerateProjectHash( void ) }; static char path[1024]; +#ifdef __linux__ static ssize_t pathSize = readlink("/proc/self/exe", path, sizeof(path) - 1); +#endif +#ifdef __APPLE__ +static uint32_t pathSize = sizeof(path); +int pathResult = _NSGetExecutablePath(path, &pathSize); +#endif char *szPathDir = dirname(path); char *szBuildDir = 0; char *IFileSystem2::OwnDirectory() diff --git a/fpc/library/ld.cpp b/fpc/library/ld.cpp index 3516c08..fa41923 100644 --- a/fpc/library/ld.cpp +++ b/fpc/library/ld.cpp @@ -22,7 +22,9 @@ CUtlString CLDProject::Link( void ) szFileName = CUtlString("lib%s.so", m_szName.GetString()); break; } - CUtlString szOutputFile = CUtlString("%s/ld/%u_%s/%s",FPC_TEMPORAL_DIRNAME, hash, m_szName.GetString(), szFileName.GetString()); + + CUtlString szTarget = m_target.GetTriplet(); + CUtlString szOutputFile = CUtlString("%s/%s/ld/%u_%s/%s",FPC_TEMPORAL_DIRNAME, szTarget.GetString(), hash, m_szName.GetString(), szFileName.GetString()); CUtlString szOutputDir = szOutputFile; szOutputDir = dirname(szOutputDir); IFileSystem2::MakeDirectory(szOutputDir); @@ -65,7 +67,21 @@ CUtlString CLDProject::Link( void ) args = { "-o", szOutputFile, + "-target", + m_target.GetTriplet(), }; + if (m_target.kernel == TARGET_KERNEL_DARWIN) + { + args.AppendTail("-isysroot"); + args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"); + } + if (m_target.kernel == TARGET_KERNEL_IOS) + { + args.AppendTail("-isysroot"); + args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"); + args.AppendTail("-miphoneos-version-min=18.0 "); + args.AppendTail("-fembed-bitcode"); + } if (m_target.kernel == TARGET_KERNEL_LINUX) { args.AppendTail("-rdynamic"); diff --git a/fpc/library/target.cpp b/fpc/library/target.cpp index 148db6e..b3700c7 100644 --- a/fpc/library/target.cpp +++ b/fpc/library/target.cpp @@ -2,6 +2,44 @@ #include "tier1/commandline.h" #include "tier1/utlstring.h" + +CUtlString Target_t::GetTriplet() +{ + CUtlString triplet = ""; + + if ( cpu == TARGET_CPU_AMD64 ) + triplet.AppendTail("x86_64"); + if ( cpu == TARGET_CPU_AARCH64 ) + triplet.AppendTail("aarch64"); + triplet.AppendTail("-"); + if ( kernel == TARGET_KERNEL_WINDOWS ) + triplet.AppendTail("pc-windows-gnu"); + if ( kernel == TARGET_KERNEL_LINUX ) + triplet.AppendTail("unknown-linux-gnu"); + if ( kernel == TARGET_KERNEL_DARWIN ) + triplet.AppendTail("apple-darwin"); + if ( kernel == TARGET_KERNEL_IOS ) + triplet.AppendTail("apple-ios"); + + + return triplet; +} +Target_t Target_t::HostTarget() +{ + ETargetKernel kernel = +#if defined(__linux__) + TARGET_KERNEL_LINUX +#elif defined(__APPLE__) + TARGET_KERNEL_DARWIN +#endif + ; + ETargetCPU cpu = TARGET_CPU_AMD64; + return { + .kernel = kernel, + .cpu = cpu, + .optimization = TARGET_DEBUG, + }; +}; Target_t Target_t::DefaultTarget() { CUtlString szDevice = ICommandLine::ParamValue("-device"); @@ -16,6 +54,10 @@ Target_t Target_t::DefaultTarget() #endif ; ETargetCPU cpu = TARGET_CPU_AMD64; + if ( szArch == "x86_64" ) + cpu = TARGET_CPU_AMD64; + else if ( szArch == "aarch64" ) + cpu = TARGET_CPU_AARCH64; if ( szOS == "windows" ) kernel = TARGET_KERNEL_WINDOWS; @@ -23,6 +65,8 @@ Target_t Target_t::DefaultTarget() kernel = TARGET_KERNEL_LINUX; else if ( szOS == "macos" ) kernel = TARGET_KERNEL_DARWIN; + else if ( szOS == "ios" ) + kernel = TARGET_KERNEL_IOS; else if ( szOS != 0 ) V_printf("Unknown OS: %s\n", szOS.GetString()); diff --git a/fpc/main.cpp b/fpc/main.cpp index 0cbe758..b3435fb 100644 --- a/fpc/main.cpp +++ b/fpc/main.cpp @@ -1,6 +1,7 @@ #include "public/c.h" #include "public/helper.h" #include "public/ld.h" +#include "public/target.h" #include "tier0/platform.h" #include "tier1/commandline.h" #include "c.h" @@ -20,10 +21,18 @@ int build() compileScriptProject.files = {"build.cpp"}; compileScriptProject.includeDirectories = {CUtlString("%s/public",IFileSystem2::OwnDirectory()),CUtlString("%s/public", IFileSystem2::BuildDirectory()), CUtlString("%s/../public",IFileSystem2::OwnDirectory()),CUtlString("%s/../public", IFileSystem2::BuildDirectory())}; compileScriptProject.bFPIC = true; + compileScriptProject.m_target = Target_t::HostTarget(); CLDProject linkScriptProject = compileScriptProject.Compile(); linkScriptProject.linkType = ELINK_DYNAMIC_LIBRARY; + linkScriptProject.m_target = Target_t::HostTarget(); CUtlString script = linkScriptProject.Link(); void *scriptDLL = Plat_LoadLibrary(script); + + auto PreinitFn = (void(*)())Plat_GetProc(scriptDLL, "Preinit"); + V_printf("%p\n",PreinitFn); + if (PreinitFn) + PreinitFn(); + for (auto &build: BuildStages()) { build->m_pMainFn(); @@ -46,7 +55,7 @@ void IEngine_Signal(int sig) default: break; }; - _exit(0); + Plat_Exit(0); }; int main(int c, char **v) diff --git a/fpc/public/target.h b/fpc/public/target.h index 36973af..52a6f1a 100644 --- a/fpc/public/target.h +++ b/fpc/public/target.h @@ -1,17 +1,21 @@ #ifndef TARGET_T #define TARGET_T +#include "tier1/utlstring.h" + enum ETargetKernel { TARGET_KERNEL_LINUX, TARGET_KERNEL_WINDOWS, TARGET_KERNEL_DARWIN, + TARGET_KERNEL_IOS, }; enum ETargetCPU { TARGET_CPU_AMD64, TARGET_CPU_I386, + TARGET_CPU_AARCH64, }; enum ETargetOptimization @@ -26,6 +30,8 @@ struct Target_t ETargetKernel kernel; ETargetCPU cpu; ETargetOptimization optimization; + CUtlString GetTriplet(); + static Target_t HostTarget(); static Target_t DefaultTarget(); }; diff --git a/funnyassets/__build.c b/funnyassets/__build.c deleted file mode 100644 index 3bdbdf8..0000000 --- a/funnyassets/__build.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "god/build.h" -#include "god/slang.h" -#include "god/utils.h" -#include "god/common.h" - -void build_shader(char *name, enum slang_stage stage) -{ - struct slang_settings shadercc = { - .entry = string_clone("funnyassets/gfx_shaders/%s.slang", name), - .stage = stage, - .output_type = SLANG_OUTPUT_SPIRV, - }; - char *file = slang_compile(shadercc); - mv(string_clone("funnyassets/_rtt/gfx/%s.spv",name),file); -}; - -void makepak(struct build_data b, char *name) -{ - struct run_project rp = run_new("python"); - run_add_arg(&rp, "tools/makepak64.py"); - run_add_arg(&rp, string_clone("funnyassets/_%s",name)); - run_add_arg(&rp, string_clone("build/"GAME_NAME"/game/"GAME_NAME"/%s.pak", name)); - run_run(&rp); -}; - -void assets_build(struct build_data b) -{ - remove("funnyassets/_rtt"); - makedir("funnyassets/_rtt/gfx"); - build_shader("brush_frag", SLANG_STAGE_FRAGMENT); - build_shader("brush_vert", SLANG_STAGE_VERTEX); - build_shader("mesh_frag", SLANG_STAGE_FRAGMENT); - build_shader("mesh_vert", SLANG_STAGE_VERTEX); - mv("funnyassets/_rtt/","funnyassets/maps"); - mv("funnyassets/_rtt/","funnyassets/gfx"); - mv("funnyassets/_rtt/","funnyassets/textures"); - mv("funnyassets/_rtt/","funnyassets/materials"); - makepak(b, "rtt"); -} diff --git a/funnyassets/__build.cpp b/funnyassets/__build.cpp index f9a04dc..afda0ee 100644 --- a/funnyassets/__build.cpp +++ b/funnyassets/__build.cpp @@ -7,15 +7,12 @@ void build_shader( const char *szName ) { - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::MakeDirectory(CUtlString("build/%s/assets/gfx",szGameName)); + IFileSystem2::MakeDirectory(CUtlString("build/funnygame/assets/gfx")); CUtlVector slang_args = { CUtlString("funnyassets/gfx_shaders/%s.slang", szName), "-o", - CUtlString("build/%s/assets/gfx/%s.spv", szGameName, szName), + CUtlString("build/funnygame/assets/gfx/%s.spv", szName), }; IRunner::Run("slangc", slang_args); @@ -25,21 +22,19 @@ void build_shader( const char *szName ) int assets_build() { IFileSystem2::CopyDirectory("build", "tools"); - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::CopyDirectory(CUtlString("build/%s/assets",szGameName), "funnyassets/maps"); - IFileSystem2::CopyDirectory(CUtlString("build/%s/assets",szGameName), "funnyassets/gfx"); - IFileSystem2::CopyDirectory(CUtlString("build/%s/assets",szGameName), "funnyassets/textures"); - IFileSystem2::CopyDirectory(CUtlString("build/%s/assets",szGameName), "funnyassets/materials"); + + IFileSystem2::CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/maps"); + IFileSystem2::CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/gfx"); + IFileSystem2::CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/textures"); + IFileSystem2::CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/materials"); build_shader("mesh_frag"); build_shader("mesh_vert"); build_shader("agx_comp"); build_shader("mesh_edge_detection_comp"); CUtlVector python_args = { "build/tools/makepak64.py", - CUtlString("build/%s/assets", szGameName), - CUtlString("build/%s/game/%s/%s.pak", szGameName, szGameName, "rtt"), + CUtlString("build/funnygame/assets"), + CUtlString("%s/funnygame/%s.pak", szOutputDir.GetString(), "rtt"), }; IRunner::Run("python", python_args); return 0; diff --git a/funnyassets/maps/test_map.fmap b/funnyassets/maps/test_map.fmap index 26aacd90afb400f017b4bf57634b240558f93319..e1625917729f6dc1563f696542c55351a15b330a 100644 GIT binary patch delta 559 zcmWN=2bhQj002<`SvTyFUG|=tg;chXy=Tal(U27CmG#>*JDYQ7o=s-<-U`{Yh!9Qh z`(AuPd}Q47Lj@uvmPAs?Bo`@4v=}L*luBx8q?Jy38D#W=Oft(Nt8B8%;YBaWDVN;x z$Sa@x3MiwLTODty ztDgGa)<8pzG}c5@%{13SORcolMqBN)*Fi_`=%lkQ-qlq%-SyB@FTM5gp1%6&Z-DoG z;6oo7=wpL?Vz5trW{9DN`P>)y(pQEXVWd$;3ym?>IO9z)(Ik^iG1WBFeQk!BW|?h{ zx#s!Cd=(cK%{}-1 z?tzE?@W^9N{OPG@{_?kf{Oi9FK^O#KL=Ywp!X!bMGzgOgVe%l148o`&j1IQO1hF$B HN+-2ueus)s-?CU z)KOPG^}XmNFMGwS8fd7I#+rCdQ_VEj!s}XkLo2Pl=`C%v)lPeF>);(7y{nV=bk;>z z-E{Z99(wAfw-5BuS3ms?@S%YQ8El9oANkl&3^UvaBaJfJCqkbZ<1?QdYn<^Wm}rv8 zzVM}FU-{Y;Q+;Ea>1LQ|mf7Z*Yo7VOmEt?8(k!shB8x5Yy>v@0v)m6>SSiCQKU!^# zpRBdcdK+xC$!1&pY^!ay+hM0&cKgL1d;RJ+zuRZO1OD)*gAO_Dh@*}m_position[0]; diff --git a/game/server/__build.c b/game/server/__build.c deleted file mode 100644 index 6d326e4..0000000 --- a/game/server/__build.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "god/build.h" -#include "god/c.h" -#include "god/ld.h" -#include "libgen.h" - -char* server_dll = 0; -void server_build(struct build_data b) -{ - char* files[] = { - "game/server/game.cpp", - "game/server/baseplayer.cpp", - NULL, - }; - - struct project p = { - .b = &b, - .files = files, - .name = "server", - }; - - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - }); - char* libs[] = { - "c", - NULL, - }; - - server_dll = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_DYNAMIC, - .libs = libs, - }); - mv("build/"GAME_NAME"/game/"GAME_NAME"/bin/libserver.so",server_dll); -} diff --git a/game/server/__build.cpp b/game/server/__build.cpp index 432ceab..d8256a0 100644 --- a/game/server/__build.cpp +++ b/game/server/__build.cpp @@ -19,15 +19,20 @@ int server_build() compileProject.includeDirectories = all_IncludeDirectories; compileProject.bFPIC = true; ldProject = compileProject.Compile(); - ldProject.linkType = ELINK_DYNAMIC_LIBRARY; + if (bStaticBuild) + ldProject.linkType = ELINK_STATIC_LIBRARY; + else + ldProject.linkType = ELINK_DYNAMIC_LIBRARY; CUtlString outputProject = ldProject.Link(); - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::MakeDirectory(CUtlString("build/%s/game/%s/bin",szGameName, szGameName)); - IFileSystem2::CopyFile(CUtlString("build/%s/game/%s/bin",szGameName,szGameName), outputProject); + if (!bStaticBuild) + { + IFileSystem2::MakeDirectory(CUtlString("%s/funnygame/bin",szOutputDir.GetString())); + IFileSystem2::CopyFile(CUtlString("%s/funnygame/bin", szOutputDir.GetString()), outputProject); + } else { + server_lib = outputProject; + } return 0; }; diff --git a/game/server/milmoba/player.cpp b/game/server/milmoba/player.cpp index 69038f1..21382b5 100644 --- a/game/server/milmoba/player.cpp +++ b/game/server/milmoba/player.cpp @@ -1,14 +1,20 @@ #include "baseentity.h" #include "baseplayer.h" -#include "cglm/mat4.h" -#include "cglm/util.h" +#include "cglm/io.h" #include "cglm/vec2.h" #include "cglm/vec3.h" #include "console.h" #include "engine.h" +#include "input.h" +#include "math3d.h" #include "physics.h" #include "physics_gen.h" +#define STEP_SIZE 0.3f +#define PLAYER_WIDTH 0.5f +#define PLAYER_HEIGHT 1.8f +#define EPSILON 0.0005f + class CMOBAPlayer: public CBasePlayer { public: @@ -18,9 +24,15 @@ public: virtual void ReadParameter( const char *szName, const char *szValue ) override; virtual void Think( float fDelta ) override; - void AirAccelerate(); - void Accelerate( float fDelta, vec2 wishDir, float fWishSpeed, float fAcceleration ); - void Move( float fDelta ); + void Accelerate( void ); + void AirAccelerate( void ); + int ClipVelocity( vec3 in, vec3 normal, vec3 &out, float fOverbounce ); + void FlyMove( void ); + void GroundMove( void ); + void AirMove( void ); + void CategorizePosition( void ); + void Friction( void ); + void PlayerMove( void ); bool bIsForward = 0; @@ -33,14 +45,25 @@ public: bool bIsProning = 0; bool bIsFiring = 0; bool bIsFiring2 = 0; + float fStamina; + + float m_fDelta = 0; float fPitch = 0; float fYaw = 0; - vec3 m_velocity; + enum { + PLAYER_GROUNDED, + PLAYER_FLYING, + } m_playerState; + vec3 m_velocity = {0,0,0}; + vec3 m_prevVelocity = {0,0,0}; + + vec2 forward = {}; + vec2 right = {}; CPxBoxMesh mesh; - CPxRigidBody rigidbody; + CPxRigidKinematicPosition rigidbody; }; void CMOBAPlayer::Precache() @@ -50,26 +73,7 @@ void CMOBAPlayer::Precache() void CMOBAPlayer::Spawn() { - mesh.m_fRadius[0] = 0.3; - mesh.m_fRadius[1] = 0.3; - mesh.m_fRadius[2] = 0.8; - mesh.Spawn(); - px_matrix m = {}; - m.m[0] = 1; - m.m[5] = 1; - m.m[10] = 1; - m.m[15] = 1; - m.m[12] = m_position[0]; - m.m[13] = m_position[1]; - m.m[14] = m_position[2]; - rigidbody.Spawn(&mesh, m, { - .gravity_scale = 1, - .continous = true, - .lockrotx = 1, - .lockroty = 1, - .lockrotz = 1, - .dominance = 127, - }); + }; @@ -83,68 +87,84 @@ void CMOBAPlayer::Destroy() } -void CMOBAPlayer::AirAccelerate() +void CMOBAPlayer::AirAccelerate( void ) +{ + m_velocity[2] -= 9.8 * m_fDelta; +} + +void CMOBAPlayer::Accelerate( void ) +{ + vec2 wishdir = {(float)bIsForward-bIsBack, (float)bIsLeft-bIsRight}; + vec3 velocityDifference; + vec3 acceleration; + glm_vec2_rotate(wishdir, fYaw, wishdir); + glm_vec2_normalize(wishdir); + for ( int i = 0; i < 2; i++ ) + m_velocity[i] += (wishdir[i]*6 - m_velocity[i]) * m_fDelta/0.25; +} + +void CMOBAPlayer::Friction( void ) +{ + +}; + +void CMOBAPlayer::FlyMove( void ) { } -void CMOBAPlayer::Accelerate( float fDelta, vec2 wishDir, float fWishSpeed, float fAcceleration ) +void CMOBAPlayer::GroundMove( void ) { - float fCurrentSpeed = glm_vec2_dot(wishDir, m_velocity); - float fAddSpeed = fWishSpeed - fCurrentSpeed; - if ( fAddSpeed < 0 ) - return; - float fAccelSpeed = fAcceleration*fDelta*fWishSpeed; - if ( fAccelSpeed > fAddSpeed ) - fAccelSpeed = fAddSpeed; - glm_vec2_scale(wishDir, fAccelSpeed, m_velocity); + m_velocity[2] = 0; + Accelerate(); } -void CMOBAPlayer::Move( float fDelta ) +void CMOBAPlayer::CategorizePosition( void ) { - vec2 forward = {(float)bIsForward-(float)bIsBack,0}; - vec2 right = {0,(float)bIsLeft-(float)bIsRight}; - vec2 wishDir; - float fWishSpeed; + px_vec3 p; + px_cast_result r; + p.m[0] = m_position[0]; + p.m[1] = m_position[1]; + p.m[2] = m_position[2]; + r = px_box_cast(px, PLAYER_WIDTH/2, PLAYER_WIDTH/2, PLAYER_HEIGHT/2, p, (px_vec3){}, (px_vec3){0,0,-0.01}, 1); - glm_vec2_rotate(forward, fYaw, forward); - glm_vec2_rotate(forward, fYaw, forward); - glm_vec2_add(forward, right, wishDir); - fWishSpeed = glm_vec2_distance(wishDir, (vec3){0,0,0}); - - if (fWishSpeed != 0) + if (r.hit) { - glm_vec2_divs(wishDir, fWishSpeed, wishDir); - fWishSpeed = 10; + m_playerState = PLAYER_GROUNDED; } else { - glm_vec2_zero(wishDir); + m_playerState = PLAYER_FLYING; } - - Accelerate(fDelta, wishDir, fWishSpeed, 5.5); } +void CMOBAPlayer::PlayerMove( void ) +{ + CategorizePosition(); + + GroundMove(); + + vec3 velocity; + for ( int i = 0; i < 3; i++ ) + velocity[i] = (m_prevVelocity[i] + m_velocity[i]) * 0.5; + + for ( int i = 0; i < 3; i++ ) + m_position[i] += velocity[i] * m_fDelta; + + for ( int i = 0; i < 3; i++ ) + m_prevVelocity[i] = m_velocity[i]; + + CategorizePosition(); +} void CMOBAPlayer::Think( float fDelta ) { - m_position[0] = rigidbody.GetPosition().m[0]; - m_position[1] = rigidbody.GetPosition().m[1]; - m_position[2] = rigidbody.GetPosition().m[2]; - px_vec3 v = rigidbody.GetVelocity(); - px_vec3 p = rigidbody.GetPosition(); + float x = g_fAxisValues[AXIS_MOUSE_X]; + float y = g_fAxisValues[AXIS_MOUSE_Y]; + fPitch = glm_rad(x); + fYaw = glm_rad(y); - for (int i = 0; i < 3; i++) - m_velocity[i] = v.m[i]; + m_fDelta = fDelta; - px_cast_result r = px_box_cast(px, 0.3,0.3,0.01, {p.m[0],p.m[1],p.m[2]-0.79f}, {0,0,0}, {0,0,-1}, 1); - if (r.hit) - { - Move(fDelta); - } - - for (int i = 0; i < 3; i++) - v.m[i] = m_velocity[i]; - - rigidbody.SetVelocity(v); + PlayerMove(); }; void PlayerForward(int argc, char **argv) {if (g_localClient.pBasePlayer) ((CMOBAPlayer*)g_localClient.pBasePlayer)->bIsForward = true;}; diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/project.pbxproj b/ios_deploy/funnygame/funnygame.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8007e26 --- /dev/null +++ b/ios_deploy/funnygame/funnygame.xcodeproj/project.pbxproj @@ -0,0 +1,336 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXFileReference section */ + 24CCF9852E1065A100A06964 /* funnygame.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = funnygame.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 24CCF99C2E1065A300A06964 /* Exceptions for "funnygame" folder in "funnygame" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 24CCF9842E1065A100A06964 /* funnygame */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 24CCF9872E1065A100A06964 /* funnygame */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 24CCF99C2E1065A300A06964 /* Exceptions for "funnygame" folder in "funnygame" target */, + ); + path = funnygame; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 24CCF9822E1065A100A06964 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 24CCF97C2E1065A100A06964 = { + isa = PBXGroup; + children = ( + 24CCF9872E1065A100A06964 /* funnygame */, + 24CCF9862E1065A100A06964 /* Products */, + ); + sourceTree = ""; + }; + 24CCF9862E1065A100A06964 /* Products */ = { + isa = PBXGroup; + children = ( + 24CCF9852E1065A100A06964 /* funnygame.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 24CCF9842E1065A100A06964 /* funnygame */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24CCF99D2E1065A300A06964 /* Build configuration list for PBXNativeTarget "funnygame" */; + buildPhases = ( + 24CCF9812E1065A100A06964 /* Sources */, + 24CCF9822E1065A100A06964 /* Frameworks */, + 24CCF9832E1065A100A06964 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 24CCF9872E1065A100A06964 /* funnygame */, + ); + name = funnygame; + packageProductDependencies = ( + ); + productName = funnygame; + productReference = 24CCF9852E1065A100A06964 /* funnygame.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 24CCF97D2E1065A100A06964 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1620; + TargetAttributes = { + 24CCF9842E1065A100A06964 = { + CreatedOnToolsVersion = 16.2; + }; + }; + }; + buildConfigurationList = 24CCF9802E1065A100A06964 /* Build configuration list for PBXProject "funnygame" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 24CCF97C2E1065A100A06964; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 24CCF9862E1065A100A06964 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 24CCF9842E1065A100A06964 /* funnygame */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 24CCF9832E1065A100A06964 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 24CCF9812E1065A100A06964 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 24CCF99E2E1065A300A06964 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QU3M3RV4XD; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = funnygame/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = kotofyt.funnygame; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 24CCF99F2E1065A300A06964 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QU3M3RV4XD; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = funnygame/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = kotofyt.funnygame; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 24CCF9A02E1065A300A06964 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 24CCF9A12E1065A300A06964 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 24CCF9802E1065A100A06964 /* Build configuration list for PBXProject "funnygame" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24CCF9A02E1065A300A06964 /* Debug */, + 24CCF9A12E1065A300A06964 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24CCF99D2E1065A300A06964 /* Build configuration list for PBXNativeTarget "funnygame" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24CCF99E2E1065A300A06964 /* Debug */, + 24CCF99F2E1065A300A06964 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 24CCF97D2E1065A100A06964 /* Project object */; +} diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate b/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..8007b5746876dbd719b2aa3ad5dec1e7d7001738 GIT binary patch literal 13928 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 A1ONa4 literal 0 HcmV?d00001 diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcschemes/xcschememanagement.plist b/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..ba92000 --- /dev/null +++ b/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + funnygame.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/ios_deploy/funnygame/funnygame/Assets.xcassets/AccentColor.colorset/Contents.json b/ios_deploy/funnygame/funnygame/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios_deploy/funnygame/funnygame/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios_deploy/funnygame/funnygame/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios_deploy/funnygame/funnygame/Assets.xcassets/Contents.json b/ios_deploy/funnygame/funnygame/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios_deploy/funnygame/funnygame/Base.lproj/LaunchScreen.storyboard b/ios_deploy/funnygame/funnygame/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios_deploy/funnygame/funnygame/Base.lproj/Main.storyboard b/ios_deploy/funnygame/funnygame/Base.lproj/Main.storyboard new file mode 100644 index 0000000..808a21c --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios_deploy/funnygame/funnygame/Info.plist b/ios_deploy/funnygame/funnygame/Info.plist new file mode 100644 index 0000000..81ed29b --- /dev/null +++ b/ios_deploy/funnygame/funnygame/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/ios_deploy/funnygame/funnygame/SceneDelegate.h b/ios_deploy/funnygame/funnygame/SceneDelegate.h new file mode 100644 index 0000000..cbd6b0b --- /dev/null +++ b/ios_deploy/funnygame/funnygame/SceneDelegate.h @@ -0,0 +1,15 @@ +// +// SceneDelegate.h +// funnygame +// +// Created by kotofyt on 28.06.2025. +// + +#import + +@interface SceneDelegate : UIResponder + +@property (strong, nonatomic) UIWindow * window; + +@end + diff --git a/ios_deploy/funnygame/funnygame/SceneDelegate.m b/ios_deploy/funnygame/funnygame/SceneDelegate.m new file mode 100644 index 0000000..80724c8 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/SceneDelegate.m @@ -0,0 +1,57 @@ +// +// SceneDelegate.m +// funnygame +// +// Created by kotofyt on 28.06.2025. +// + +#import "SceneDelegate.h" + +@interface SceneDelegate () + +@end + +@implementation SceneDelegate + + +- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). +} + + +- (void)sceneDidDisconnect:(UIScene *)scene { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). +} + + +- (void)sceneDidBecomeActive:(UIScene *)scene { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. +} + + +- (void)sceneWillResignActive:(UIScene *)scene { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). +} + + +- (void)sceneWillEnterForeground:(UIScene *)scene { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. +} + + +- (void)sceneDidEnterBackground:(UIScene *)scene { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. +} + + +@end diff --git a/ios_deploy/funnygame/funnygame/Untitled.swift b/ios_deploy/funnygame/funnygame/Untitled.swift new file mode 100644 index 0000000..e69de29 diff --git a/ios_deploy/funnygame/funnygame/ViewController.h b/ios_deploy/funnygame/funnygame/ViewController.h new file mode 100644 index 0000000..ab3d6ff --- /dev/null +++ b/ios_deploy/funnygame/funnygame/ViewController.h @@ -0,0 +1,14 @@ +// +// ViewController.h +// funnygame +// +// Created by kotofyt on 28.06.2025. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/ios_deploy/funnygame/funnygame/main.m b/ios_deploy/funnygame/funnygame/main.m new file mode 100644 index 0000000..a86a6b6 --- /dev/null +++ b/ios_deploy/funnygame/funnygame/main.m @@ -0,0 +1,18 @@ +// +// main.m +// funnygame +// +// Created by kotofyt on 28.06.2025. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + NSString * appDelegateClassName; + @autoreleasepool { + // Setup code that might create autoreleased objects goes here. + appDelegateClassName = NSStringFromClass([AppDelegate class]); + } + return UIApplicationMain(argc, argv, nil, appDelegateClassName); +} diff --git a/launcher/__build.c b/launcher/__build.c deleted file mode 100644 index 83c4bb2..0000000 --- a/launcher/__build.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "god/c.h" -#include "god/ld.h" -#include "god/utils.h" - -void launcher_build(struct build_data b) -{ - char* files[] = { - "launcher/launcher.cpp", - NULL, - }; - - - struct project p = { - .b = &b, - .files = files, - .name = "launcher", - }; - - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - }); - - char* libs[] = { - "c", - NULL, - }; - - char* launcher_dll = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_EXECUTABLE, - .libs = libs, - }); - mv("build/"GAME_NAME"/game/bin/"GAME_NAME,launcher_dll); -} diff --git a/launcher/__build.cpp b/launcher/__build.cpp index 4c69166..d8dfda3 100644 --- a/launcher/__build.cpp +++ b/launcher/__build.cpp @@ -19,12 +19,19 @@ int launcher_build() ldProject = compileProject.Compile(); ldProject.linkType = ELINK_EXECUTABLE; + if (bStaticBuild) + { + ldProject.objects.AppendTail((CObject){tier0_lib}); + ldProject.objects.AppendTail((CObject){tier1_lib}); + ldProject.objects.AppendTail((CObject){rapier_lib}); + ldProject.objects.AppendTail((CObject){engine_lib}); + ldProject.objects.AppendTail((CObject){server_lib}); + ldProject.objects.AppendTail((CObject){client_lib}); + }; + CUtlString outputProject = ldProject.Link(); - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::MakeDirectory(CUtlString("build/%s/game/bin",szGameName)); - IFileSystem2::CopyFile(CUtlString("build/%s/game/bin/%s", szGameName, szGameName), outputProject); + IFileSystem2::MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString())); + IFileSystem2::CopyFile(CUtlString("%s/bin/funnygame", szOutputDir.GetString()), outputProject); return 0; }; diff --git a/launcher/launcher.cpp b/launcher/launcher.cpp index 9ff8f50..93d8e5b 100644 --- a/launcher/launcher.cpp +++ b/launcher/launcher.cpp @@ -3,6 +3,9 @@ #include "unistd.h" #include "dlfcn.h" #include "libgen.h" +#ifdef __APPLE__ +#include +#endif #define MAX_PATH 4096 @@ -16,26 +19,33 @@ typedef void (*EngineMainFn)(int argc, char** argv); EngineMainFn pEngineMain; int main( int argc, char **argv ) { +#ifdef __linux__ readlink("/proc/self/exe",szLauncherPath, MAX_PATH); dirname(szLauncherPath); snprintf(szEnginePath, MAX_PATH, "%s/libengine.so", szLauncherPath); snprintf(szTier0Path, MAX_PATH, "%s/libtier0.so", szLauncherPath); - printf("%s\n",szEnginePath); - printf("%s\n",szTier0Path); +#endif +#ifdef __APPLE__ + uint32_t pathSize = sizeof(szLauncherPath); + int pathResult = _NSGetExecutablePath(szLauncherPath, &pathSize); + printf("%s\n",szLauncherPath); + char *szLauncherPath2 = dirname(szLauncherPath); + printf("%s\n",szLauncherPath2); + snprintf(szEnginePath, MAX_PATH, "%s/libengine.dylib", szLauncherPath2); + snprintf(szTier0Path, MAX_PATH, "%s/libtier0.dylib", szLauncherPath2); +#endif pTier0Lib = dlopen(szTier0Path, RTLD_NOW | RTLD_GLOBAL); if ( !pTier0Lib ) { - printf("Failed to open libtier0.so\n"); + printf("Failed to open libtier0\n"); printf("\t%s\n",dlerror()); } pEngineLib = dlopen(szEnginePath, RTLD_NOW | RTLD_GLOBAL); if ( !pEngineLib ) { - printf("Failed to open libengine.so\n"); + printf("Failed to open libengine\n"); printf("\t%s\n",dlerror()); } - printf("\t%p\n",pTier0Lib); - printf("\t%p\n",pEngineLib); pEngineMain = (EngineMainFn)dlsym(pEngineLib, "FunnyMain"); if ( !pEngineMain ) { printf("Symbol not found: FunnyMain\n"); diff --git a/public/baseentity.h b/public/baseentity.h index c68afa2..383fae8 100644 --- a/public/baseentity.h +++ b/public/baseentity.h @@ -61,8 +61,7 @@ CEntityRegistry __entity_##name##_registry(#name, #class, __entity_alloc_##name) //----------------------------------------------------------------------------- // Base client entity class. -// It recieves pure server data, which has to be interpolated by the client to -// get smoother image. +// It uses server data directly. //----------------------------------------------------------------------------- class C_BaseEntity { diff --git a/public/brush.h b/public/brush.h index ad8cecd..a4eb0e6 100644 --- a/public/brush.h +++ b/public/brush.h @@ -5,6 +5,7 @@ #include "rendering.h" #include "baseentity.h" #include "physics.h" +#include "mesh.h" //----------------------------------------------------------------------------- // Basic triangle structure which is used in brush entities. @@ -51,8 +52,6 @@ private: IVertexBuffer *vertexBuffer; IIndexBuffer *indexBuffer; IMesh *mesh; - IMaterial material; - ITexture *pAlbedo; }; #endif diff --git a/public/console.h b/public/console.h index 635b0ac..47324d8 100644 --- a/public/console.h +++ b/public/console.h @@ -13,15 +13,20 @@ typedef void(*ConCommandFn)(int argc, char **argv); interface IConsole { public: + // Variables static void RegisterVar( ConVar *cvar ); static void UnRegisterVar( ConVar *cvar ); static ConVar *FindVar( const char *pName ); + // Commands static void RegisterCommand( ConCommand *cvar ); static void UnRegisterCommand( ConCommand *cvar ); static ConCommand *FindCommand( const char *pName ); + // Command buffer static void Execute( void ); + static CUtlVector> ParseCommandLine( CUtlString psz ); + static void AddCommand( const char *psz ); static void InsertCommand( const char *psz ); private: diff --git a/public/input.h b/public/input.h index d87fcd1..8d0ba8e 100644 --- a/public/input.h +++ b/public/input.h @@ -3,6 +3,11 @@ #include "tier0/platform.h" +//----------------------------------------------------------------------------- +// Keys include mouse buttons and gamepad buttons as well. +// KEY_NONE and AXIS_NONE are garbage, so don't rely on them +//----------------------------------------------------------------------------- + enum EKeyEventType { KEY_EVENT_TYPE_DOWN, @@ -81,13 +86,24 @@ enum EInputKey KEY_X, KEY_Y, KEY_Z, + KEY_MAX, + KEY_NUM_KEYS = KEY_MAX - 1, }; enum EInputAxis { + AXIS_NONE, AXIS_MOUSE_X, AXIS_MOUSE_Y, AXIS_MOUSE_SCROLL, + AXIS_MAX, + AXIS_NUM_AXIS = AXIS_MAX - 1, +}; + +enum EMouseMode +{ + MOUSE_MODE_GAME, + MOUSE_MODE_MENU,F }; interface IInput @@ -95,9 +111,12 @@ interface IInput public: static void Init( void ); static void KeyEvent( EInputKey key, EKeyEventType event ); - static void AxisEvent( unsigned char axis, float fX, float fY ); + static void AxisEvent( EInputAxis axis, float fValue ); + static void SetMouseMode( EMouseMode mode ); static void Frame( void ); static void Deinit( void ); }; +extern float g_fAxisValues[AXIS_NUM_AXIS]; + #endif diff --git a/public/math3d.h b/public/math3d.h index 9cfa670..6ea4a2a 100644 --- a/public/math3d.h +++ b/public/math3d.h @@ -4,5 +4,10 @@ #include "tier0/minmax_off.h" #include "cglm/cglm.h" #include "cglm/affine.h" +#include "cglm/mat4.h" +#include "cglm/mat3.h" +#include "cglm/mat2.h" #include "tier0/minmax.h" + +#define PX_GLM_VEC3(v) (px_vec3){v[0], v[1], v[2]} #endif diff --git a/public/mesh.h b/public/mesh.h new file mode 100644 index 0000000..0311fe0 --- /dev/null +++ b/public/mesh.h @@ -0,0 +1,31 @@ +#include "rendering.h" + +//---------------------------------------------------------------------------- +// Mesh handler for the rendering +//---------------------------------------------------------------------------- +abstract_class IMesh +{ +public: + virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0; + virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) = 0; + + virtual void SetPosition( vec3 position ) = 0; + virtual void SetRotationEuler( vec3 angle ) = 0; + virtual void SetRotationQuat( vec4 quaternion) = 0; + virtual void SetMatrix( mat4 matrix ) = 0; + virtual void SetScale( vec3 scale ) = 0; + + virtual void Draw() = 0; +}; + +interface IMeshRendering: public IRenderingPipelineStep +{ +public: + virtual IMesh *CreateMesh(); +}; + +interface IModelManager +{ +public: + virtual void LoadModel( const char *szPath ); +}; diff --git a/public/physics.h b/public/physics.h index 2b4696e..deb5b86 100644 --- a/public/physics.h +++ b/public/physics.h @@ -4,6 +4,7 @@ #include "tier0/lib.h" #include "stdint.h" #include "tier1/utlvector.h" +#include "math3d.h" typedef void Collider; @@ -23,10 +24,25 @@ typedef struct u128 { extern funnyphysics *px; +struct PxCastResult_t +{ + bool bHit; + float fTime; + vec3 position; + vec3 normal; + vec3 normal2; +}; + +interface IPxWorld +{ +public: + static PxCastResult_t BoxCast( vec3 size, vec3 origin, vec3 destination, vec3 rotation = (vec3){0,0,0} ); +}; + class CPxCollider { public: - virtual void Spawn( float fFriction = 0.5 ) = 0; + virtual void Spawn( float fFriction = 0.0 ) = 0; virtual void Destroy( void ); Collider *m_pCollider; }; @@ -34,7 +50,7 @@ public: class CPxBallMesh: public CPxCollider { public: - virtual void Spawn( float fFriction = 0.5 ) override; + virtual void Spawn( float fFriction = 0.0 ) override; virtual void Destroy( void ) override; float m_fRadius; }; @@ -42,7 +58,7 @@ public: class CPxBoxMesh: public CPxCollider { public: - virtual void Spawn( float fFriction = 0.5 ) override; + virtual void Spawn( float fFriction = 0.0 ) override; virtual void Destroy( void ) override; float m_fRadius[3]; }; @@ -50,7 +66,7 @@ public: class CPxTriangleMesh: public CPxCollider { public: - virtual void Spawn( float fFriction = 0.5 ) override; + virtual void Spawn( float fFriction = 0.0 ) override; virtual void Destroy( void ) override; }; @@ -58,6 +74,8 @@ class CPxRigidKinematicPosition { public: void Spawn( CPxCollider *pCollider, px_matrix matrix, px_rigidbody_params params ); + void SetPosition( px_vec3 position ); + void SetPositionTeleport( px_vec3 position ); px_vec3 GetPosition( void ); px_matrix GetMatrix ( void ); void Destroy( void ); diff --git a/public/rendering.h b/public/rendering.h index 85add33..66c7281 100644 --- a/public/rendering.h +++ b/public/rendering.h @@ -5,109 +5,234 @@ #include "tier0/platform.h" #include "tier1/utlbuffer.h" #include "baseentity.h" +#include "tier1/utlstring.h" #include "tier1/utlvector.h" extern mat4 g_cameraView; + +enum EImageFormat +{ + IMAGE_FORMAT_R8, + IMAGE_FORMAT_R8G8, + IMAGE_FORMAT_R8G8B8, + IMAGE_FORMAT_R8G8B8A8, + IMAGE_FORMAT_R16, + IMAGE_FORMAT_R16G16, + IMAGE_FORMAT_R16G16B16, + IMAGE_FORMAT_R16G16B16A16, + IMAGE_FORMAT_R32, + IMAGE_FORMAT_R32G32, + IMAGE_FORMAT_R32G32B32, + IMAGE_FORMAT_R32G32B32A32, + IMAGE_FORMAT_DEPTH, + + IMAGE_FORMAT_RENDERING = IMAGE_FORMAT_R8G8B8A8, +}; + +enum EImageUsage +{ + IMAGE_USAGE_COLOR_ATTACHMENT = 0x1, + IMAGE_USAGE_DEPTH_ATTACHMENT = 0x2, + IMAGE_USAGE_STORAGE = 0x4, +}; + +enum EVertexFormat +{ + VERTEX_FORMAT_X16, + VERTEX_FORMAT_X16Y16, + VERTEX_FORMAT_X16Y16Z16, + VERTEX_FORMAT_X16Y16Z16W16, + VERTEX_FORMAT_X32, + VERTEX_FORMAT_X32Y32, + VERTEX_FORMAT_X32Y32Z32, + VERTEX_FORMAT_X32Y32Z32W32, +}; + +enum EMSAAMode +{ + MSAA_MODE_DISABLED, + MSAA_MODE_MIN, + MSAA_MODE_MAX, + MSAA_MODE_AVERAGE, +}; + +enum EDepthMode +{ + DEPTH_MODE_DISABLED, + DEPTH_MODE_EQUAL, + DEPTH_MODE_NOT_EQUAL, + DEPTH_MODE_LESS, + DEPTH_MODE_LESS_EQUAL, + DEPTH_MODE_GREATER, + DEPTH_MODE_GREATER_EQUAL, +}; + +enum EShaderInputType +{ + SHADER_INPUT_TYPE_STORAGE_BUFFER, + SHADER_INPUT_TYPE_UNIFORM_BUFFER, + SHADER_INPUT_TYPE_IMAGE, + SHADER_INPUT_TYPE_TLAS, + + // All available textures are binded + SHADER_INPUT_TYPE_TEXTURES, +}; + +enum EShaderType +{ + SHADER_TYPE_VERTEX, + SHADER_TYPE_GEOMETRY, + SHADER_TYPE_FRAGMENT, + SHADER_TYPE_COMPUTE, + SHADER_TYPE_RAY_GEN, + SHADER_TYPE_CLOSEST_HIT, + SHADER_TYPE_MISS, + SHADER_TYPE_INTERSECTION, + SHADER_TYPE_ANY_HIT, +}; + +enum EBarrierMemoryPermissions +{ + BARRIER_MEMORY_PERMISSIONS_VERTEX_BUFFER_READ = 0x1, + BARRIER_MEMORY_PERMISSIONS_INDEX_BUFFER_READ = 0x2, + BARRIER_MEMORY_PERMISSIONS_UNIFORM_BUFFER_READ = 0x4, + BARRIER_MEMORY_PERMISSIONS_SHADER_READ = 0x8, + BARRIER_MEMORY_PERMISSIONS_SHADER_WRITE = 0x10, + BARRIER_MEMORY_PERMISSIONS_COLOR_READ = 0x20, + BARRIER_MEMORY_PERMISSIONS_COLOR_WRITE = 0x40, + BARRIER_MEMORY_PERMISSIONS_DEPTH_READ = 0x80, + BARRIER_MEMORY_PERMISSIONS_DEPTH_WRITE = 0x100, + BARRIER_MEMORY_PERMISSIONS_COPY_READ = 0x200, + BARRIER_MEMORY_PERMISSIONS_COPY_WRITE = 0x400, +}; +enum EBarrierStage +{ + BARRIER_STAGE_TOP, + BARRIER_STAGE_VERTEX_INPUT, + BARRIER_STAGE_VERTEX_SHADER, + BARRIER_STAGE_GEOMETRY_SHADER, + BARRIER_STAGE_FRAGMENT_SHADER, + BARRIER_STAGE_COMPUTE_SHADER, + BARRIER_STAGE_RAY_TRACING_SHADER, + BARRIER_STAGE_BOTTOM, +}; + +enum EAttachmentLoadMode +{ + ATTACHMENT_LOAD_MODE_DONT_CARE, + ATTACHMENT_LOAD_MODE_CLEAR, + ATTACHMENT_LOAD_MODE_LOAD, +}; + +enum EAttachmentStoreMode +{ + ATTACHMENT_STORE_MODE_DONT_CARE, + ATTACHMENT_STORE_MODE_STORE, +}; + +enum EPipelineType +{ + PIPELINE_TYPE_RASTERIZATION, + PIPELINE_TYPE_COMPUTE, + PIPELINE_TYPE_RAY_TRACING, +}; + + + interface IVideo { public: static void Init(); + static void CreatePipelines( void ); static void Frame( float fDelta ); }; -abstract_class IVertexBuffer +abstract_class IBuffer { public: virtual void *Map() = 0; virtual void Unmap() = 0; }; -abstract_class IIndexBuffer +typedef IBuffer IStorageBuffer; +typedef IBuffer IUniformBuffer; +typedef IBuffer IVertexBuffer; +typedef IBuffer IIndexBuffer; + +abstract_class IImage { public: - virtual void *Map() = 0; - virtual void Unmap() = 0; -}; - -enum EMaterialType -{ - IMATERIAL_ERROR = 0, - IMATERIAL_PBR = 1, - IMATERIAL_FULLBRIGHT = 2, -}; - -struct MaterialProperties_t -{ - - EMaterialType type; - - vec3 albedoColor; - - const char *szAlbedoTexture; - const char *szNormalsTexture; - const char *szRoughnessTexture; - const char *szMetalnessTexture; - - vec2 uvScaling; -}; - - -struct Material_t -{ - uint32_t shader; - uint32_t albedo; - uint32_t normal; - uint32_t roughness; - uint32_t metalness; - vec3 albedoColor; -}; - -abstract_class IMaterial -{ -public: - Material_t m; -}; - -interface IRenderer -{ -public: - - static IVertexBuffer *CreateVertexBuffer( uint32_t uSize ); - static IIndexBuffer *CreateIndexBuffer( uint32_t uSize ); - - static IMaterial *LoadMaterial( const char *szName ); - static void SetMaterial( IMaterial *pMaterial ); + EImageFormat format; }; //---------------------------------------------------------------------------- -// Mesh handler for the rendering +// Bottom level acceleration structure for ray tracing. //---------------------------------------------------------------------------- -abstract_class IMesh +abstract_class IBLAS { public: - virtual void SetPosition( vec3 position ) = 0; - virtual void SetRotationEuler( vec3 angle ) = 0; - virtual void SetRotationQuat( vec4 quaternion) = 0; - virtual void SetMatrix( mat4 matrix ) = 0; - virtual void SetScale( vec3 scale ) = 0; - - virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0; - virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) = 0; - virtual void SetMaterial( IMaterial *pMaterial ) = 0; - virtual void Draw() = 0; + virtual void Build() = 0; + virtual void Update() = 0; }; -interface IMeshRenderer + + +//---------------------------------------------------------------------------- +// Bottom level acceleration structure with triangle geometry. +//---------------------------------------------------------------------------- +abstract_class IBLASMesh: public IBLAS { public: - static void Init(); - static void Frame( float fDelta ); - - static IMesh *CreateMesh(); - static void Destroy( IMesh *pModel ); + virtual void SetMesh( IVertexBuffer *pVertex, IIndexBuffer *pIndex ) = 0; }; +//---------------------------------------------------------------------------- +// Bottom level acceleration structure with AABB geometry. +//---------------------------------------------------------------------------- +abstract_class IBLASAABB: public IBLAS +{ +public: + virtual void SetBoundaries( vec4 size ); +}; + +//---------------------------------------------------------------------------- +// Top level acceleration structure for handling worlds +//---------------------------------------------------------------------------- +abstract_class ITLAS +{ +public: + virtual void AddInstance( IBLAS *pBLAS, mat4 matrix, uint32_t data ) = 0; + virtual void ResetInstances() = 0; +}; + + +struct ShaderInput_t +{ + EShaderInputType type; + uint32_t binding; +}; + +struct Shader_t +{ + const char *szPath; + EShaderType type; +}; + +abstract_class IPipeline +{ +public: + EPipelineType type; +}; +typedef IPipeline IGraphicsPipeline; +typedef IPipeline IComputePipeline; +typedef IPipeline IRayTracingPipeline; + + + +//---------------------------------------------------------------------------- +// Texture handle +//---------------------------------------------------------------------------- abstract_class ITexture { public: @@ -115,19 +240,195 @@ public: uint32_t id; }; +//---------------------------------------------------------------------------- +// Manages loaded textures +//---------------------------------------------------------------------------- interface ITextureManager { public: - static uint32_t GetTexture(ITexture *pTexture); + static uint32_t GetTextureID(ITexture *pTexture); static ITexture *LoadTexture( void *pData, uint32_t X, uint32_t Y, uint32_t numChannels ); static ITexture *LoadTexture( const char *szName ); }; -interface IPostProcessRenderer +struct BufferBarrier_t { -public: - static void Init(); - static void Frame( float fDelta ); + EBarrierMemoryPermissions in; + EBarrierMemoryPermissions out; + IBuffer *pBuffer; +}; +struct ImageBarrier_t +{ + EBarrierMemoryPermissions in; + EBarrierMemoryPermissions out; + IBuffer *pBuffer; }; +struct VertexAttribute_t +{ + uint32_t offset; + uint32_t binding; + EVertexFormat format; +}; + +struct RenderingColorAttachment_t +{ + IImage *pOutput; + IImage *pTemporary; + EAttachmentLoadMode loadMode; + EAttachmentStoreMode storeMode; + EMSAAMode msaaMode; + vec4 clearColor; +}; + +struct RenderingDepthAttachment_t +{ + IImage *pOutput; + IImage *pTemporary; + EAttachmentLoadMode loadMode; + EAttachmentStoreMode storeMode; + EMSAAMode msaaMode; + float clearValue; +}; + + +//---------------------------------------------------------------------------- +// Manages all buffers and pipelines. +// It is meant to be used in render pipelines +//---------------------------------------------------------------------------- +interface IRenderer +{ +public: + + static IStorageBuffer *CreateStorageBuffer( uint32_t uSize ); + static IUniformBuffer *CreateUniformBuffer( uint32_t uSize ); + static IVertexBuffer *CreateVertexBuffer( uint32_t uSize ); + static IIndexBuffer *CreateIndexBuffer( uint32_t uSize ); + static IImage *CreateImage( EImageFormat format, uint32_t usage, uint32_t nWidth, uint32_t nHeight, uint32_t nSamples = 1 ); + + static void DestroyBuffer( IBuffer *pBuffer ); + static void DestroyImage( IImage *pImage ); + + static void SetConstants( uint32_t nSize, uint32_t nOffset, void *pData ); + static void Barrier( EBarrierStage stageIn, uint32_t stageOut, CUtlVector buffers, CUtlVector images ); + static void BindData( uint32_t binding, IBuffer *pBuffer, IImage* pImage); + static void BindPipeline( IPipeline *pPipeline ); + + + static void Begin( uint32_t nWidth, uint32_t nHeight, CUtlVector attachments, RenderingDepthAttachment_t depth ); + static void ResetState(); + static void SetDepthMode( EDepthMode mode ); + static void Draw( IVertexBuffer *pVertex, IIndexBuffer *pIndex ); + static void Dispatch( uint32_t x, uint32_t y, uint32_t z ); + static void TraceRays( uint32_t x, uint32_t y, uint32_t z ); + static void End(); + + static IGraphicsPipeline *CreateGraphicsPipeline( + CUtlVector shaders, + CUtlVector inputs, + uint32_t nConstantsSize, + CUtlVector outputFormats + ); + static IComputePipeline *CreateComputePipeline( + Shader_t szShader, + CUtlVector inputs, + uint32_t nConstantsSize + ); + + static IRayTracingPipeline *CreateRayTracingPipeline( + CUtlVector shaders, + CUtlVector inputs, + uint32_t nConstantsSize + ); +}; + +abstract_class IRenderingPipelineStep +{ +public: + virtual void Init() = 0; + virtual void Frame( float fDelta ) = 0; + virtual void Deinit() = 0; +}; + +struct RenderingStep_t +{ + IRenderingPipelineStep *pPipeline; + const char *szName; +}; + +extern CUtlVector g_StepPrepass; +extern CUtlVector g_StepMeshRendering; +extern CUtlVector g_StepShading; +extern CUtlVector g_StepPostProcessing; +extern CUtlVector g_StepUI; + + +typedef IRenderingPipelineStep*(*CreateRenderStepFn)(); +class CRenderingStep +{ +public: + CRenderingStep(); + CRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; + +class CPrepassRenderingStep: public CRenderingStep +{ +public: + CPrepassRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; +class CMeshRenderingStep: public CRenderingStep +{ +public: + CMeshRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; + +class CShadingRenderingStep: public CRenderingStep +{ +public: + CShadingRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; + +class CPostProcessingRenderingStep: public CRenderingStep +{ +public: + CPostProcessingRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; + +class CUIRenderingStep: public CRenderingStep +{ +public: + CUIRenderingStep(const char *szStepName, CreateRenderStepFn pfn); +}; + +#define DECLARE_MESH_PREPASS_STAGE(class, name) \ +IRenderingPipelineStep *__rendering_stage_##name() \ +{ \ + return new class; \ +}; \ +CPrepassRenderingStep __renering_##name##_registry(#name, __rendering_stage_##name); +#define DECLARE_MESH_RENDERING_STAGE(class, name) \ +IRenderingPipelineStep *__rendering_stage_##name() \ +{ \ + return new class; \ +}; \ +CMeshRenderingStep __renering_##name##_registry(#name, __rendering_stage_##name); +#define DECLARE_MESH_SHADING_STAGE(class, name) \ +IRenderingPipelineStep *__rendering_stage_##name() \ +{ \ + return new class; \ +}; \ +CShadingRenderingStep __renering_##name##_registry(#name, __rendering_stage_##name); +#define DECLARE_POST_PROCESSING_STAGE(class, name) \ +IRenderingPipelineStep *__rendering_stage_##name() \ +{ \ + return new class; \ +}; \ +CPostProcessingRenderingStep __renering_##name##_registry(#name, __rendering_stage_##name); +#define DECLARE_UI_RENDERING_STAGE(class, name) \ +IRenderingPipelineStep *__rendering_stage_##name() \ +{ \ + return new class; \ +}; \ +CUIRenderingStep __renering_##name##_registry(#name, __rendering_stage_##name); + #endif diff --git a/public/tier0/lib.h b/public/tier0/lib.h index ea3dcfc..268ffea 100644 --- a/public/tier0/lib.h +++ b/public/tier0/lib.h @@ -44,6 +44,12 @@ #define V_strtok strtok #define V_strxfrm strxfrm +#ifdef __WIN32__ +#define V_stricmp stricmp +#else +#define V_stricmp strcasecmp +#endif + //----------------------------------------------------------------------------- // stdio.h //----------------------------------------------------------------------------- diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 32cf75a..53c895a 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -57,6 +57,6 @@ PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz ); PLATFORM_INTERFACE void Plat_UnloadLibrary( void *psz ); PLATFORM_INTERFACE double Plat_GetTime( void ); - +PLATFORM_INTERFACE void Plat_Exit( int status ); #endif diff --git a/public/tier1/commandline.h b/public/tier1/commandline.h index c6dd892..5b85624 100644 --- a/public/tier1/commandline.h +++ b/public/tier1/commandline.h @@ -9,7 +9,7 @@ interface ICommandLine public: static void CreateCommandLine( int argc, char **argv ); - static bool CheckParam( char *psz ); + static bool CheckParam( const char *psz ); static char *ParamValue( const char* psz ); static void AddParam( char *psz ); diff --git a/rapier/__build.c b/rapier/__build.c deleted file mode 100644 index 531dbf7..0000000 --- a/rapier/__build.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "god/build.h" -#include "god/c.h" -#include "god/ld.h" -#include "god/utils.h" - -char *rapierLib = NULL; -void rapier_build(struct build_data b) -{ - struct run_project cargo_build = run_new("cargo"); - cargo_build.wd = "rapier"; - run_add_arg(&cargo_build, "build"); - run_add_arg(&cargo_build, "--release"); - if (b.kernel == BUILD_KERNEL_LINUX) - { - run_add_arg(&cargo_build, "--target"); - run_add_arg(&cargo_build, "x86_64-unknown-linux-gnu"); - rapierLib = "rapier/target/x86_64-unknown-linux-gnu/release/librapier_rtt.a"; - } - run_run(&cargo_build); - struct run_project cbindgen = run_new("cbindgen"); - cbindgen.wd = "rapier"; - run_add_arg(&cbindgen, "--config"); - run_add_arg(&cbindgen, "cbindgen.toml"); - run_add_arg(&cbindgen, "--crate"); - run_add_arg(&cbindgen, "rapier_rtt"); - run_add_arg(&cbindgen, "--output"); - run_add_arg(&cbindgen, "../public/physics_gen.h"); - run_run(&cbindgen); -} diff --git a/rapier/__build.cpp b/rapier/__build.cpp index 56f8029..f760d90 100644 --- a/rapier/__build.cpp +++ b/rapier/__build.cpp @@ -7,11 +7,13 @@ CUtlString rapier_lib; int rapier_build() { + rapier_lib = CUtlString("rapier/target/%s/release/librapier_rtt.a",szTarget.GetString()); + V_printf("%s\n",rapier_lib.GetString()); CUtlVector cargo_args = { "build", "--release", "--target", - "x86_64-unknown-linux-gnu" + szTarget }; IRunner::Run("cargo", "rapier", cargo_args); @@ -24,7 +26,6 @@ int rapier_build() "../public/physics_gen.h", }; IRunner::Run("cbindgen", "rapier", cbindgen_args); - rapier_lib = "rapier/target/x86_64-unknown-linux-gnu/release/librapier_rtt.a"; return 0; }; diff --git a/rapier/px.rs b/rapier/px.rs index b868a4b..5abdb53 100644 --- a/rapier/px.rs +++ b/rapier/px.rs @@ -161,6 +161,7 @@ pub unsafe extern "C" fn px_kinematic_position_body(px_world: *mut funnyphysics, .dominance_group(params.dominance) .linear_damping(0.0) .angular_damping(0.0) + .ccd_enabled(params.continous == 1) .build(); let body = px.rigid_body_set.insert(rigid_body); px.collider_set.insert_with_parent(c.clone(),body,&mut px.rigid_body_set); @@ -284,7 +285,12 @@ pub unsafe extern "C" fn px_box_cast(px_world: *mut funnyphysics, x:f32,y:f32,z: &px.rigid_body_set, &px.collider_set, &shape_pos, &shape_vel, &c, options, filter ) { res.time=hit.time_of_impact; + res.normal1.m[0] = hit.normal1.x; + res.normal1.m[1] = hit.normal1.y; + res.normal1.m[2] = hit.normal1.z; res.hit = 1; + } else { + res.time = time; } - res + res } diff --git a/tier0/__build.c b/tier0/__build.c deleted file mode 100644 index 64c8893..0000000 --- a/tier0/__build.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "god/build.h" -#include "god/c.h" -#include "god/ld.h" - -char* tier0_lib = 0; -void tier0_build(struct build_data b) -{ - char* files[] = { - "tier0/mem.cpp", - "tier0/platform.cpp", - "tier0/lib.cpp", - NULL, - }; - struct C_Macro macros[] = { - (struct C_Macro){"TIER0_IMPLEMENTATION","1"}, - NULL, - }; - - - struct project p = { - .b = &b, - .files = files, - .name = "tier0", - }; - - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - .macros = macros, - }); - char* libs[] = { - "c", - NULL, - }; - - tier0_lib = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_DYNAMIC, - .libs = libs, - }); - mv("build/"GAME_NAME"/game/bin/libtier0.so",tier0_lib); -} diff --git a/tier0/__build.cpp b/tier0/__build.cpp index a523025..abc2e55 100644 --- a/tier0/__build.cpp +++ b/tier0/__build.cpp @@ -20,15 +20,20 @@ int tier0_build() compileProject.includeDirectories = all_IncludeDirectories; compileProject.bFPIC = true; ldProject = compileProject.Compile(); - ldProject.linkType = ELINK_DYNAMIC_LIBRARY; + if (bStaticBuild) + ldProject.linkType = ELINK_STATIC_LIBRARY; + else + ldProject.linkType = ELINK_DYNAMIC_LIBRARY; CUtlString outputProject = ldProject.Link(); - const char *szGameName = ICommandLine::ParamValue("-game"); - if (szGameName == NULL) - szGameName = "funnygame"; - IFileSystem2::MakeDirectory(CUtlString("build/%s/game/bin",szGameName)); - IFileSystem2::CopyFile(CUtlString("build/%s/game/bin",szGameName), outputProject); + if (!bStaticBuild) + { + IFileSystem2::MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString())); + IFileSystem2::CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), outputProject); + } else { + tier0_lib = outputProject; + } return 0; }; diff --git a/tier0/platform.cpp b/tier0/platform.cpp index 6f32473..2cdf916 100644 --- a/tier0/platform.cpp +++ b/tier0/platform.cpp @@ -10,6 +10,9 @@ #include "dlfcn.h" #include "execinfo.h" #endif +#ifdef __APPLE__ +#include "dlfcn.h" +#endif #ifdef __WIN32__ #include "windows.h" #include "dbghelp.h" @@ -22,7 +25,7 @@ PLATFORM_INTERFACE void Plat_FatalErrorFunc(const char* szFormat, ...) va_end(list); fflush(stdout); raise(SIGTRAP); - _exit(1); + Plat_Exit(1); } PLATFORM_INTERFACE void Plat_ListDirRecursive(const char* szPath, ListDirCallbackFn file, ListDirCallbackFn dir) @@ -163,6 +166,12 @@ PLATFORM_INTERFACE void *Plat_LoadLibrary( const char *psz ) V_printf("Failed to open %s\n\t%s\n", psz, dlerror()); return lib; #endif +#ifdef __APPLE__ + void *lib = dlopen(psz, RTLD_GLOBAL | RTLD_NOW); + if (!lib) + V_printf("Failed to open %s\n\t%s\n", psz, dlerror()); + return lib; +#endif #ifdef __WIN32__ return LoadLibraryA(psz); #endif @@ -172,6 +181,9 @@ PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz ) #ifdef __linux__ return dlsym(lib, psz); #endif +#ifdef __APPLE__ + return dlsym(lib, psz); +#endif #ifdef __WIN32__ return (void*)GetProcAddress((HMODULE)lib, psz); #endif @@ -194,3 +206,13 @@ PLATFORM_INTERFACE double Plat_GetTime( void ) return (tp.tv_sec-s_starttime)+tp.tv_nsec/1e9; } + +PLATFORM_INTERFACE void Plat_Exit( int status ) +{ +#ifdef __linux__ + _exit(status); +#endif +#ifdef __APPLE__ + _exit(status); +#endif +}; diff --git a/tier1/__build.c b/tier1/__build.c deleted file mode 100644 index a39dcfa..0000000 --- a/tier1/__build.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "god/c.h" -#include "god/ld.h" - -char* tier1_lib = 0; -void tier1_build(struct build_data b) -{ - char* files[] = { - "tier1/commandline.cpp", - "tier1/utlbuffer.cpp", - "tier1/utlmap.cpp", - "tier1/utlstring.cpp", - "tier1/utlvector.cpp", - NULL, - }; - struct C_Macro macros[] = { - (struct C_Macro){"TIER0_IMPLEMENTATION","1"}, - NULL, - }; - - - struct project p = { - .b = &b, - .files = files, - .name = "tier1", - }; - - struct project o = C_compile(p, (struct C_settings){ - .generation_flags = C_GENERATION_FLAGS_PIC, - .compile_flags = C_COMPILE_FLAGS_WALL, - .include_dirs = include_dirs, - .macros = macros, - }); - char* libs[] = { - "c", - NULL, - }; - - tier1_lib = ld_link_project(o, (struct link_settings){ - .type = LINK_TYPE_STATIC, - .libs = libs, - }); -} \ No newline at end of file diff --git a/tier1/commandline.cpp b/tier1/commandline.cpp index 39c950d..a70fde2 100644 --- a/tier1/commandline.cpp +++ b/tier1/commandline.cpp @@ -8,7 +8,7 @@ void ICommandLine::CreateCommandLine( int argc, char **argv ) cl_params.AppendTail(argv,argc); } -bool ICommandLine::CheckParam( char *psz ) +bool ICommandLine::CheckParam( const char *psz ) { for (auto szParam: cl_params) { if (!V_strcmp(szParam, psz))