├── Meow.png ├── Banner.png ├── Banner.psd ├── .gitignore ├── examples ├── Ui │ ├── Banner.png │ ├── Font.png │ ├── bin │ │ ├── Debug-x64 │ │ │ ├── Ui.exe │ │ │ ├── Ui.ilk │ │ │ └── Ui.pdb │ │ └── Release-x64 │ │ │ ├── Ui.exe │ │ │ └── Ui.pdb │ ├── Ui.vcxproj │ └── menu.cpp ├── Anim │ ├── bin │ │ ├── Debug-x64 │ │ │ ├── Anim.exe │ │ │ ├── Anim.ilk │ │ │ └── Anim.pdb │ │ └── Debug-Win32 │ │ │ ├── Anim.exe │ │ │ ├── Anim.ilk │ │ │ └── Anim.pdb │ ├── anim.cpp │ └── Anim.vcxproj └── Boid │ ├── bin │ ├── Debug-x64 │ │ ├── Boid.exe │ │ ├── Boid.ilk │ │ └── Boid.pdb │ ├── Debug-Win32 │ │ ├── Boid.exe │ │ ├── Boid.ilk │ │ └── Boid.pdb │ ├── Release-x64 │ │ ├── Boid.exe │ │ └── Boid.pdb │ └── Release-Win32 │ │ ├── Boid.exe │ │ └── Boid.pdb │ ├── boids.cpp │ └── Boid.vcxproj ├── bin └── Windows │ ├── Debug-x64 │ ├── CppGame.idb │ ├── CppGame.lib │ └── CppGame.pdb │ ├── Debug-Win32 │ ├── CppGame.idb │ ├── CppGame.lib │ └── CppGame.pdb │ ├── Release-Win32 │ ├── CppGame.lib │ └── CppGame.pdb │ └── Release-x64 │ ├── CppGame.lib │ └── CppGame.pdb ├── Readme.md ├── CppGame.sln ├── src ├── CppGameCore.h └── CppGame.h ├── LICENSE ├── Meow.svg └── CppGame.vcxproj /Meow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/Meow.png -------------------------------------------------------------------------------- /Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/Banner.png -------------------------------------------------------------------------------- /Banner.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/Banner.psd -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | Intermediates/ 3 | *.vcxproj.filters 4 | *.vcxproj.user 5 | -------------------------------------------------------------------------------- /examples/Ui/Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/Banner.png -------------------------------------------------------------------------------- /examples/Ui/Font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/Font.png -------------------------------------------------------------------------------- /examples/Ui/bin/Debug-x64/Ui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/bin/Debug-x64/Ui.exe -------------------------------------------------------------------------------- /examples/Ui/bin/Debug-x64/Ui.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/bin/Debug-x64/Ui.ilk -------------------------------------------------------------------------------- /examples/Ui/bin/Debug-x64/Ui.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/bin/Debug-x64/Ui.pdb -------------------------------------------------------------------------------- /bin/Windows/Debug-x64/CppGame.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-x64/CppGame.idb -------------------------------------------------------------------------------- /bin/Windows/Debug-x64/CppGame.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-x64/CppGame.lib -------------------------------------------------------------------------------- /bin/Windows/Debug-x64/CppGame.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-x64/CppGame.pdb -------------------------------------------------------------------------------- /examples/Ui/bin/Release-x64/Ui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/bin/Release-x64/Ui.exe -------------------------------------------------------------------------------- /examples/Ui/bin/Release-x64/Ui.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Ui/bin/Release-x64/Ui.pdb -------------------------------------------------------------------------------- /bin/Windows/Debug-Win32/CppGame.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-Win32/CppGame.idb -------------------------------------------------------------------------------- /bin/Windows/Debug-Win32/CppGame.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-Win32/CppGame.lib -------------------------------------------------------------------------------- /bin/Windows/Debug-Win32/CppGame.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Debug-Win32/CppGame.pdb -------------------------------------------------------------------------------- /bin/Windows/Release-Win32/CppGame.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Release-Win32/CppGame.lib -------------------------------------------------------------------------------- /bin/Windows/Release-Win32/CppGame.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Release-Win32/CppGame.pdb -------------------------------------------------------------------------------- /bin/Windows/Release-x64/CppGame.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Release-x64/CppGame.lib -------------------------------------------------------------------------------- /bin/Windows/Release-x64/CppGame.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/bin/Windows/Release-x64/CppGame.pdb -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-x64/Anim.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-x64/Anim.exe -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-x64/Anim.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-x64/Anim.ilk -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-x64/Anim.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-x64/Anim.pdb -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-x64/Boid.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-x64/Boid.exe -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-x64/Boid.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-x64/Boid.ilk -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-x64/Boid.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-x64/Boid.pdb -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-Win32/Anim.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-Win32/Anim.exe -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-Win32/Anim.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-Win32/Anim.ilk -------------------------------------------------------------------------------- /examples/Anim/bin/Debug-Win32/Anim.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Anim/bin/Debug-Win32/Anim.pdb -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-Win32/Boid.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-Win32/Boid.exe -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-Win32/Boid.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-Win32/Boid.ilk -------------------------------------------------------------------------------- /examples/Boid/bin/Debug-Win32/Boid.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Debug-Win32/Boid.pdb -------------------------------------------------------------------------------- /examples/Boid/bin/Release-x64/Boid.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Release-x64/Boid.exe -------------------------------------------------------------------------------- /examples/Boid/bin/Release-x64/Boid.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Release-x64/Boid.pdb -------------------------------------------------------------------------------- /examples/Boid/bin/Release-Win32/Boid.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Release-Win32/Boid.exe -------------------------------------------------------------------------------- /examples/Boid/bin/Release-Win32/Boid.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishzero/CppGame/HEAD/examples/Boid/bin/Release-Win32/Boid.pdb -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # CppGame 2 | This is a simple library for rendering and simulation in 2D. CppGame also has a nice banner. 3 | ![CppGameBanner](Banner.png) 4 | 5 | # Usage 6 | 7 | ## Using Source 8 | 9 | * Just include the source code (`src/CppGame.cpp`) and put the header files (`CppGame.h` and `CppGameCore.h`) in your project 10 | * Include the `CppGame.h` in your code and that's it!! 11 | 12 | ## Using Static Library 13 | 14 | * The build in libraries are found in `bin` directory 15 | * Statically link the library and copy the header files (`CppGame.h` and `CppGameCore.h`) in your project 16 | * Include the `CppGame.h` in your code and that's it!! 17 | 18 | # Skeleton Code 19 | This will help you getting started 20 | ```cpp 21 | #include "CppGame.h" 22 | 23 | // The `Platform` structs holds various data such as Window Size, Input, User Pointer 24 | // User can use `Platform::Scratch` as a scratch buffer for temporary allocation, every frame 25 | // the scratch buffer will be automatically be reset 26 | // The default allocation of scratch is 32 Megabytes 27 | 28 | struct MyData { 29 | float x, y; 30 | }; 31 | 32 | void FixedUpdate(Platform *p, float dt) { 33 | // This is fixed timestep simulation function (framerate independent) 34 | // Perform critical simulations here 35 | // Simulations performed will be consistent 36 | } 37 | 38 | void UpdateAndRender(Platform *p, float dt, float alpha) { 39 | // This function is not framerate independent, so the simulations done in this function will not be consistent 40 | // Exit if Escape is pressed 41 | if (KeyIsPressed(p, KeyEscape)) { 42 | PlatformQuit(p); 43 | } 44 | 45 | // Mouse: p->Mouse.Position 46 | // Mouse Button: ButtonIsDown, ButtonIsPressed, etc 47 | // For more details check `CppGame.h` header file 48 | 49 | // Clear the background with this color, 50 | // this is not immediate function, the actual clearing call will be done later 51 | SetClearColor(.2f, .2f, .2f, 1); 52 | 53 | BeginScene2D(0, p->RenderTargetWidth, 0, p->RenderTargetHeight); 54 | 55 | // DrawLine, DrawQuad, DrawRect, etc (check `CppGame.h` header file for all functions available) 56 | 57 | EndScene2D(); 58 | } 59 | 60 | // This function gets called by the Library so that you can set up the library 61 | CppGameCall void CppGameInitialize(Platform *platform, int argc, char **argv) { 62 | platform->Name = "Example Program"; // set your program name 63 | platform->FixedUpdate = FixedUpdate; // the given function will be called during simulation loop for fixed update 64 | platform->UpdateAndRender = UpdateAndRender; // the given function will be called during simulation loop for framerate dependent update 65 | 66 | // you can also set callback for function that gets called when window is resized 67 | // platform->OnWindowResize = MyResizeCallback 68 | 69 | // you can alloc your required data here and set it to the user pointer 70 | MyData *data = (MyData *)platform->Alloc(sizeof(MyData)); 71 | // initialize with default values 72 | data->x = 0; 73 | data->y = 1; 74 | 75 | // Set the user pointer so other functions can access the data 76 | platform->UserPointer = data; 77 | } 78 | ``` 79 | 80 | # Documentation 81 | Currently the written documentation is not available, but you can check out the list of structs and 82 | functions available in `CppGame.h` file 83 | -------------------------------------------------------------------------------- /examples/Anim/anim.cpp: -------------------------------------------------------------------------------- 1 | #include "CppGame.h" 2 | #include 3 | 4 | namespace CppAnim { 5 | 6 | struct CurveEquation { 7 | virtual float F(float x) = 0; 8 | }; 9 | 10 | struct Animation { 11 | float Time = 0.0f; 12 | float Factor = 1; 13 | float Delta = 1; 14 | Vec4 Colors[3] = { }; 15 | }; 16 | 17 | void UpdateAnimation(Animation *anim, float dt) { 18 | anim->Time += dt * anim->Factor; 19 | anim->Time = Clamp(0, 1, anim->Time); 20 | } 21 | 22 | void ReverseAnimation(Animation *anim) { 23 | anim->Factor *= -1; 24 | } 25 | 26 | void Animate(Animation *anim, float x0, float x1, CurveEquation *a, CurveEquation *b) { 27 | float py[3], y[3]; 28 | 29 | float px = x0; 30 | 31 | py[0] = a->F(px); 32 | py[1] = b->F(px); 33 | py[2] = Lerp(py[0], py[1], SmoothStep(0.0f, 1.0f, anim->Time)); 34 | 35 | for (float x = px + anim->Delta; x < x1; x += anim->Delta) { 36 | y[0] = a->F(x); 37 | y[1] = b->F(x); 38 | y[2] = Lerp(y[0], y[1], SmoothStep(0.0f, 1.0f, anim->Time)); 39 | 40 | DrawLine(Vec2(px, py[0]), Vec2(x, y[0]), anim->Colors[0]); 41 | DrawLine(Vec2(px, py[1]), Vec2(x, y[1]), anim->Colors[1]); 42 | DrawLine(Vec2(px, py[2]), Vec2(x, y[2]), anim->Colors[2]); 43 | 44 | px = x; 45 | py[0] = y[0]; 46 | py[1] = y[1]; 47 | py[2] = y[2]; 48 | } 49 | } 50 | 51 | // 52 | // 53 | // 54 | 55 | struct Bezier2 : public CurveEquation { 56 | float Strength = 1; 57 | virtual float F(float x) override { 58 | return -2 * Square(Strength * x) * (Strength * x) + 3 * Square(Strength * x); 59 | } 60 | }; 61 | 62 | struct SinWave : public CurveEquation { 63 | float Amplitude = 1; 64 | float Frequency = 1; 65 | virtual float F(float x) override { 66 | return Amplitude * Sin(Frequency * x); 67 | } 68 | }; 69 | 70 | static Animation g_Animation; 71 | static Bezier2 g_Bezier2; 72 | static SinWave g_SinWave; 73 | 74 | void FixedUpdate(Platform *p, float dt) { 75 | UpdateAnimation(&g_Animation, dt); 76 | } 77 | 78 | void UpdateAndRender(Platform *p, float dt, float alpha) { 79 | if (KeyIsPressed(p, Key_Escape)) { 80 | PlatformQuit(p); 81 | } 82 | 83 | if (KeyIsPressed(p, Key_Space)) { 84 | ReverseAnimation(&g_Animation); 85 | } 86 | 87 | SetThickness(0.5f); 88 | SetClearColor(.2f, .2f, .2f, 1); 89 | 90 | float half_w = 100 * p->AspectRatio, half_h = 100; 91 | 92 | BeginScene2D(-half_w, half_w, -half_h, half_h); 93 | // Co-ordinates 94 | DrawLine(Vec2(-ceilf(half_w), 0), Vec2(ceilf(half_w), 0), Vec4(1, 0, 0, 1)); 95 | DrawLine(Vec2(0, -ceilf(half_h)), Vec2(0, ceilf(half_h)), Vec4(0, 1, 0, 1)); 96 | // Curves 97 | Animate(&g_Animation, -ceilf(half_w), ceilf(half_w), &g_Bezier2, &g_SinWave); 98 | 99 | EndScene2D(); 100 | } 101 | 102 | bool OnLoad(Platform *p) { 103 | g_Animation.Time = 0; 104 | g_Animation.Factor = 0.4f; 105 | g_Animation.Delta = 0.1f; 106 | g_Animation.Colors[0] = Vec4(1, 1, 0, 0.5f); 107 | g_Animation.Colors[1] = Vec4(1, 0, 1, 0.5f); 108 | g_Animation.Colors[2] = Vec4(0, 1, 1, 1.0f); 109 | 110 | g_Bezier2.Strength = 0.07f; 111 | g_SinWave.Amplitude = 50; 112 | g_SinWave.Frequency = 0.1f; 113 | 114 | return true; 115 | } 116 | 117 | } 118 | 119 | #if !defined(CPP_EXAMPLE_MENU) 120 | 121 | CppGameCall void CppGameInitialize(Platform *platform, int argc, char **argv) { 122 | platform->Name = "Anim"; 123 | platform->OnLoad = CppAnim::OnLoad; 124 | platform->FixedUpdate = CppAnim::FixedUpdate; 125 | platform->UpdateAndRender = CppAnim::UpdateAndRender; 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /CppGame.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31205.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppGame", "CppGame.vcxproj", "{3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Boid", "examples\Boid\Boid.vcxproj", "{1E081D40-B766-42CB-9ED8-02A37BD159A8}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Anim", "examples\Anim\Anim.vcxproj", "{49573744-0E7A-4D4B-8D65-A24148BD180A}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ui", "examples\Ui\Ui.vcxproj", "{1509A626-90C3-41DE-B135-5C28774E1F29}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Debug|x64.ActiveCfg = Debug|x64 23 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Debug|x64.Build.0 = Debug|x64 24 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Debug|x86.ActiveCfg = Debug|Win32 25 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Debug|x86.Build.0 = Debug|Win32 26 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Release|x64.ActiveCfg = Release|x64 27 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Release|x64.Build.0 = Release|x64 28 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Release|x86.ActiveCfg = Release|Win32 29 | {3AB9FFBE-DBE7-4D21-80E6-BE2CDCF0C01F}.Release|x86.Build.0 = Release|Win32 30 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Debug|x64.ActiveCfg = Debug|x64 31 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Debug|x64.Build.0 = Debug|x64 32 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Debug|x86.ActiveCfg = Debug|Win32 33 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Debug|x86.Build.0 = Debug|Win32 34 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Release|x64.ActiveCfg = Release|x64 35 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Release|x64.Build.0 = Release|x64 36 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Release|x86.ActiveCfg = Release|Win32 37 | {1E081D40-B766-42CB-9ED8-02A37BD159A8}.Release|x86.Build.0 = Release|Win32 38 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Debug|x64.ActiveCfg = Debug|x64 39 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Debug|x64.Build.0 = Debug|x64 40 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Debug|x86.ActiveCfg = Debug|Win32 41 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Debug|x86.Build.0 = Debug|Win32 42 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Release|x64.ActiveCfg = Release|x64 43 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Release|x64.Build.0 = Release|x64 44 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Release|x86.ActiveCfg = Release|Win32 45 | {49573744-0E7A-4D4B-8D65-A24148BD180A}.Release|x86.Build.0 = Release|Win32 46 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Debug|x64.ActiveCfg = Debug|x64 47 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Debug|x64.Build.0 = Debug|x64 48 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Debug|x86.ActiveCfg = Debug|Win32 49 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Debug|x86.Build.0 = Debug|Win32 50 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Release|x64.ActiveCfg = Release|x64 51 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Release|x64.Build.0 = Release|x64 52 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Release|x86.ActiveCfg = Release|Win32 53 | {1509A626-90C3-41DE-B135-5C28774E1F29}.Release|x86.Build.0 = Release|Win32 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {E156D895-64CB-475D-A7CC-FC84CC67FCD1} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /examples/Boid/boids.cpp: -------------------------------------------------------------------------------- 1 | #include "CppGame.h" 2 | #include 3 | #include 4 | 5 | namespace CppBoid { 6 | 7 | const uint32_t MAX_BOIDS = 200; 8 | 9 | struct Boid { 10 | Vec2 Position; 11 | Vec2 Velocity; 12 | }; 13 | 14 | struct CircularObstable { 15 | Vec2 Position; 16 | float Radius; 17 | }; 18 | 19 | static Boid *boids; 20 | static CircularObstable obstacles[5]; 21 | 22 | void FixedUpdate(Platform *p, float dt) { 23 | float view_distance = 30; 24 | float field_of_view = DegreesToRadians(120); 25 | 26 | float cohesion = 0.1f; 27 | float separation = 0.7f; 28 | float alignment = 0.5f; 29 | 30 | float RenderTargetWidth = p->RenderTargetWidth; 31 | float RenderTargetHeight = p->RenderTargetHeight; 32 | 33 | for (uint32_t i = 0; i < MAX_BOIDS; ++i) { 34 | auto boid = boids + i; 35 | 36 | Vec2 center(0); 37 | Vec2 separate(0); 38 | Vec2 velocity(0); 39 | uint32_t neighbours = 0; 40 | 41 | for (uint32_t j = 0; j < MAX_BOIDS; ++j) { 42 | if (i == j) continue; 43 | auto another = boids + j; 44 | 45 | if (Length(boid->Position - another->Position) <= view_distance && 46 | AngleBetween(NormalizeChecked(boid->Velocity), 47 | NormalizeChecked(another->Position - boid->Position)) <= field_of_view) { 48 | neighbours += 1; 49 | center += another->Position; 50 | velocity += another->Velocity; 51 | if (Length(boid->Position - another->Position) <= 20) { 52 | separate -= (another->Position - boid->Position); 53 | } 54 | } 55 | } 56 | 57 | if (neighbours) { 58 | center /= (float)neighbours; 59 | velocity /= (float)neighbours; 60 | boid->Velocity += (center - boid->Position) * cohesion + (velocity - boid->Velocity) * alignment; 61 | } 62 | 63 | boid->Velocity += separate * separation; 64 | 65 | float drag = 1; 66 | boid->Velocity *= Pow(0.5f, drag * dt); 67 | boid->Position += boid->Velocity * dt; 68 | 69 | //TODO: Do proper collision 70 | for (uint32_t index = 0; index < ArrayCount(obstacles); ++index) { 71 | if (LengthSq(boid->Position - obstacles[index].Position) <= Square(obstacles[index].Radius)) { 72 | float t = obstacles[index].Radius / Length(boid->Position - obstacles[index].Position); 73 | Vec2 tang = obstacles[index].Position - boid->Position; 74 | Vec2 norm = NormalizeChecked(Vec2(-tang.y, tang.x)); 75 | boid->Position -= t * NormalizeChecked(tang); 76 | boid->Velocity = Reflect(boid->Velocity, norm); 77 | } 78 | } 79 | 80 | //TODO: Do proper collision 81 | if (boid->Position.x <= 0) { 82 | boid->Velocity.x *= -1; 83 | boid->Position.x = 0; 84 | } 85 | if (boid->Position.x >= RenderTargetWidth) { 86 | boid->Velocity.x *= -1; 87 | boid->Position.x = RenderTargetWidth; 88 | } 89 | if (boid->Position.y <= 0) { 90 | boid->Velocity.y *= -1; 91 | boid->Position.y = 0; 92 | } 93 | if (boid->Position.y >= RenderTargetHeight) { 94 | boid->Velocity.y *= -1; 95 | boid->Position.y = RenderTargetHeight; 96 | } 97 | } 98 | } 99 | 100 | void UpdateAndRender(Platform *p, float dt, float alpha) { 101 | if (KeyIsPressed(p, Key_Escape)) { 102 | PlatformQuit(p); 103 | } 104 | 105 | SetClearColor(.2f, .2f, .2f, 1); 106 | 107 | BeginScene2D(0, p->RenderTargetWidth, 0, p->RenderTargetHeight); 108 | 109 | Vec2 a(-1, -1); 110 | Vec2 b(-1, 1); 111 | Vec2 c(1.2f, 0); 112 | 113 | for (uint32_t index = 0; index < MAX_BOIDS; ++index) { 114 | auto boid = boids + index; 115 | float angle = ArcTan2(boid->Velocity.y, boid->Velocity.x); 116 | Mat2 rot = RotationMat2(angle); 117 | Vec2 ta = rot * (a * 5) + boid->Position; 118 | Vec2 tb = rot * (b * 5) + boid->Position; 119 | Vec2 tc = rot * (c * 5) + boid->Position; 120 | DrawTriangle(ta, tb, tc, Vec4(0, 1, 1, 1)); 121 | } 122 | 123 | for (uint32_t index = 0; index < ArrayCount(obstacles); ++index) 124 | DrawCircle(obstacles[index].Position, obstacles[index].Radius, Vec4(1)); 125 | 126 | EndScene2D(); 127 | } 128 | 129 | void PlaceObstacles(Platform *platform, uint32_t rw, uint32_t rh) { 130 | float w = (float)rw; 131 | float h = (float)rh; 132 | 133 | obstacles[0].Position = 0.5f * Vec2(w, h); 134 | obstacles[0].Radius = 50; 135 | obstacles[1].Position = 0.25f * Vec2(w, h); 136 | obstacles[1].Radius = 55; 137 | obstacles[2].Position = 0.75f * Vec2(w, h); 138 | obstacles[2].Radius = 55; 139 | 140 | obstacles[3].Position = Vec2(0.25f * w, 0.75f * h); 141 | obstacles[3].Radius = 55; 142 | obstacles[4].Position = Vec2(0.75f * w, 0.25f * h); 143 | obstacles[4].Radius = 55; 144 | } 145 | 146 | bool OnLoad(Platform *platform) { 147 | srand((uint32_t)time(0)); 148 | 149 | boids = (Boid *)platform->Alloc(sizeof(Boid) * MAX_BOIDS); 150 | 151 | float w = platform->RenderTargetWidth; 152 | float h = platform->RenderTargetHeight; 153 | 154 | for (uint32_t index = 0; index < MAX_BOIDS; ++index) { 155 | auto b = boids + index; 156 | b->Position = Vec2(w * (float)((float)rand() / (float)RAND_MAX), (float)h * (float)((float)rand() / (float)RAND_MAX)); 157 | b->Velocity = Vec2(0); 158 | } 159 | 160 | PlaceObstacles(platform, (uint32_t)platform->RenderTargetWidth, (uint32_t)platform->RenderTargetHeight); 161 | 162 | // Get the boids out of obstacles 163 | for (uint32_t i = 0; i < MAX_BOIDS; ++i) { 164 | auto boid = boids + i; 165 | for (uint32_t index = 0; index < ArrayCount(obstacles); ++index) { 166 | if (LengthSq(boid->Position - obstacles[index].Position) <= Square(obstacles[index].Radius)) { 167 | float t = obstacles[index].Radius / Length(boid->Position - obstacles[index].Position); 168 | Vec2 tang = obstacles[index].Position - boid->Position; 169 | Vec2 norm = NormalizeChecked(Vec2(-tang.y, tang.x)); 170 | boid->Position -= t * NormalizeChecked(tang); 171 | } 172 | } 173 | } 174 | 175 | return true; 176 | } 177 | 178 | } 179 | 180 | #if !defined(CPP_EXAMPLE_MENU) 181 | 182 | CppGameCall void CppGameInitialize(Platform *platform, int argc, char **argv) { 183 | platform->Name = "Boids"; 184 | platform->OnLoad = CppBoid::OnLoad; 185 | platform->OnWindowResize = CppBoid::PlaceObstacles; 186 | platform->FixedUpdate = CppBoid::FixedUpdate; 187 | platform->UpdateAndRender = CppBoid::UpdateAndRender; 188 | } 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /src/CppGameCore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if defined(__clang__) || defined(__ibmxl__) 6 | #define COMPILER_CLANG 1 7 | #elif defined(_MSC_VER) 8 | #define COMPILER_MSVC 1 9 | #elif defined(__GNUC__) 10 | #define COMPILER_GCC 1 11 | #elif defined(__MINGW32__) || defined(__MINGW64__) 12 | #define COMPILER_MINGW 1 13 | #elif defined(__INTEL_COMPILER) 14 | #define COMPILER_INTEL 1 15 | #else 16 | #error Missing Compiler detection 17 | #endif 18 | 19 | #if !defined(COMPILER_CLANG) 20 | #define COMPILER_CLANG 0 21 | #endif 22 | #if !defined(COMPILER_MSVC) 23 | #define COMPILER_MSVC 0 24 | #endif 25 | #if !defined(COMPILER_GCC) 26 | #define COMPILER_GCC 0 27 | #endif 28 | #if !defined(COMPILER_INTEL) 29 | #define COMPILER_INTEL 0 30 | #endif 31 | 32 | #if defined(__ANDROID__) || defined(__ANDROID_API__) 33 | #define OS_ANDROID 1 34 | #elif defined(__gnu_linux__) || defined(__linux__) || defined(linux) || defined(__linux) 35 | #define OS_LINUX 1 36 | #elif defined(macintosh) || defined(Macintosh) 37 | #define OS_MAC 1 38 | #elif defined(__APPLE__) && defined(__MACH__) 39 | #defined OS_MAC 1 40 | #elif defined(__APPLE__) 41 | #define OS_IOS 1 42 | #elif defined(_WIN64) || defined(_WIN32) 43 | #define OS_WINDOWS 1 44 | #else 45 | #error Missing Operating System Detection 46 | #endif 47 | 48 | #if !defined(OS_ANDRIOD) 49 | #define OS_ANDRIOD 0 50 | #endif 51 | #if !defined(OS_LINUX) 52 | #define OS_LINUX 0 53 | #endif 54 | #if !defined(OS_MAC) 55 | #define OS_MAC 0 56 | #endif 57 | #if !defined(OS_IOS) 58 | #define OS_IOS 0 59 | #endif 60 | #if !defined(OS_WINDOWS) 61 | #define OS_WINDOWS 0 62 | #endif 63 | 64 | #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) 65 | #define ARCH_X64 1 66 | #elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_X86_) 67 | #define ARCH_X86 1 68 | #elif defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARMT) 69 | #define ARCH_ARM 1 70 | #elif defined(__aarch64__) 71 | #define ARCH_ARM64 1 72 | #else 73 | #error Missing Architecture Identification 74 | #endif 75 | 76 | #if !defined(ARCH_X64) 77 | #define ARCH_X64 0 78 | #endif 79 | #if !defined(ARCH_X86) 80 | #define ARCH_X86 0 81 | #endif 82 | #if !defined(ARCH_ARM) 83 | #define ARCH_ARM 0 84 | #endif 85 | #if !defined(ARCH_ARM64) 86 | #define ARCH_ARM64 0 87 | #endif 88 | 89 | #if defined(__GNUC__) 90 | #define __PROCEDURE__ __FUNCTION__ 91 | #elif defined(__DMC__) && (__DMC__ >= 0x810) 92 | #define __PROCEDURE__ __PRETTY_PROCEDURE__ 93 | #elif defined(__FUNCSIG__) 94 | #define __PROCEDURE__ __FUNCSIG__ 95 | #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) 96 | #define __PROCEDURE__ __PROCEDURE__ 97 | #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) 98 | #define __PROCEDURE__ __FUNC__ 99 | #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) 100 | #define __PROCEDURE__ __func__ 101 | #elif defined(__cplusplus) && (__cplusplus >= 201103) 102 | #define __PROCEDURE__ __func__ 103 | #elif defined(_MSC_VER) 104 | #define __PROCEDURE__ __FUNCSIG__ 105 | #else 106 | #define __PROCEDURE__ "_unknown_" 107 | #endif 108 | 109 | #if defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) 110 | #include // raise() 111 | #endif 112 | 113 | #if defined(_MSC_VER) 114 | #define TriggerBreakpoint() __debugbreak() 115 | #elif ((!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)))) 116 | #define TriggerBreakpoint() __asm__ __volatile__("int $3\n\t") 117 | #elif defined(__386__) && defined(__WATCOMC__) 118 | #define TriggerBreakpoint() _asm { int 0x03} 119 | #elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) 120 | #define TriggerBreakpoint() raise(SIGTRAP) 121 | #else 122 | #define TriggerBreakpoint() ((int *)0) = 0 123 | #endif 124 | 125 | #define Unimplemented() TriggerBreakpoint() 126 | #define Unreachable() TriggerBreakpoint() 127 | #define NoDefaultCase() \ 128 | default: \ 129 | TriggerBreakpoint(); \ 130 | break 131 | 132 | #if !defined(BUILD_DEBUG) && !defined(BUILD_INTERNAL) && !defined(BUILD_RELEASE) 133 | #if defined(_DEBUG) || defined(DEBUG) 134 | #define BUILD_DEBUG 135 | #elif defined(NDEBUG) 136 | #define BUILD_RELEASE 137 | #else 138 | #define BUILD_DEBUG 139 | #endif 140 | #endif 141 | 142 | #if !defined(ASSERTION_HANDLED) 143 | #define AssertHandle(file, line, proc) TriggerBreakpoint() 144 | #else 145 | void AssertHandle(const char *file, int line, const char *proc); 146 | #endif 147 | 148 | #if defined(BUILD_DEBUG) 149 | #define DebugTriggerbreakpoint TriggerBreakpoint 150 | #define Assert(x) \ 151 | do { \ 152 | if (!(x)) AssertHandle(__FILE__, __LINE__, __PROCEDURE__); \ 153 | } while (0) 154 | #else 155 | #define DebugTriggerbreakpoint() 156 | #define Assert(x) \ 157 | do { \ 158 | 0; \ 159 | } while (0) 160 | #endif 161 | 162 | // 163 | // 164 | // 165 | 166 | #if !defined(PRODUCT_NAME) 167 | #define PRODUCT_NAME "Kuro" 168 | #endif 169 | 170 | // 171 | // 172 | // 173 | 174 | #define ArrayCount(a) (sizeof(a) / sizeof((a)[0])) 175 | #define Minimum(a, b) (((a) < (b)) ? (a) : (b)) 176 | #define Maximum(a, b) (((a) > (b)) ? (a) : (b)) 177 | #define Clamp(a, b, v) Minimum(b, Maximum(a, v)) 178 | 179 | #if defined(__cplusplus) 180 | #define _ConcatInternal(x, y) x##y 181 | #define _Concat(x, y) _ConcatInternal(x, y) 182 | 183 | template 184 | struct ExitScope { 185 | T lambda; 186 | ExitScope(T lambda): lambda(lambda) { } 187 | ~ExitScope() { lambda(); } 188 | }; 189 | struct ExitScopeHelp { 190 | template 191 | ExitScope operator+(T t) { 192 | return t; 193 | } 194 | }; 195 | #define Defer const auto &_Concat(defer__, __LINE__) = ExitScopeHelp() + [&]() 196 | 197 | struct String { 198 | uint8_t *Data; 199 | int64_t Length; 200 | 201 | constexpr String(): Data(0), Length(0) { } 202 | template 203 | constexpr String(const char(&a)[_Length]) : Data((uint8_t *)a), Length(_Length - 1) { } 204 | constexpr String(const uint8_t *_Data, int64_t _Length) : Data((uint8_t *)_Data), Length(_Length) { } 205 | constexpr String(const char *_Data, int64_t _Length) : Data((uint8_t *)_Data), Length(_Length) { } 206 | const uint8_t &operator[](const int64_t index) const { 207 | Assert(index < Length); 208 | return Data[index]; 209 | } 210 | uint8_t &operator[](const int64_t index) { 211 | Assert(index < Length); 212 | return Data[index]; 213 | } 214 | }; 215 | 216 | #else 217 | 218 | tyedef struct String { 219 | uint8_t *Data; 220 | int64_t Length; 221 | } String; 222 | #define StringLiteral(lit) (String) { lit, (int64_t)(sizeof(lit) - 1) } 223 | 224 | #endif 225 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Meow.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 18 | 22 | 26 | 27 | 35 | 36 | 38 | 39 | 41 | image/svg+xml 42 | 44 | 45 | 46 | 47 | 48 | 50 | 54 | 58 | 62 | 66 | 70 | 77 | 81 | 85 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /CppGame.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {3ab9ffbe-dbe7-4d21-80e6-be2cdcf0c01f} 25 | CppGame 26 | 10.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)bin\Windows\$(Configuration)-$(Platform)\ 76 | $(SolutionDir)bin\Intermediates\Windows\$(Configuration)-$(Platform)\ 77 | 78 | 79 | false 80 | $(SolutionDir)bin\Windows\$(Configuration)-$(Platform)\ 81 | $(SolutionDir)bin\Intermediates\Windows\$(Configuration)-$(Platform)\ 82 | 83 | 84 | true 85 | $(SolutionDir)bin\Windows\$(Configuration)-$(Platform)\ 86 | $(SolutionDir)bin\Intermediates\Windows\$(Configuration)-$(Platform)\ 87 | 88 | 89 | false 90 | $(SolutionDir)bin\Windows\$(Configuration)-$(Platform)\ 91 | $(SolutionDir)bin\Intermediates\Windows\$(Configuration)-$(Platform)\ 92 | 93 | 94 | 95 | Level3 96 | true 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | 100 | 101 | Console 102 | true 103 | 104 | 105 | 106 | 107 | Level3 108 | true 109 | true 110 | true 111 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | true 113 | 114 | 115 | Console 116 | true 117 | true 118 | true 119 | 120 | 121 | 122 | 123 | Level3 124 | true 125 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 126 | true 127 | 128 | 129 | Console 130 | true 131 | 132 | 133 | 134 | 135 | Level3 136 | true 137 | true 138 | true 139 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 140 | true 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /examples/Ui/Ui.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {1509a626-90c3-41de-b135-5c28774e1f29} 25 | Ui 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 76 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 77 | 78 | 79 | false 80 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 81 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 82 | 83 | 84 | true 85 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 86 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 87 | 88 | 89 | false 90 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 91 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 92 | 93 | 94 | 95 | Level3 96 | true 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)src\; 100 | 101 | 102 | Console 103 | true 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | true 114 | $(SolutionDir)src\; 115 | 116 | 117 | Console 118 | true 119 | true 120 | true 121 | 122 | 123 | 124 | 125 | Level3 126 | true 127 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | true 129 | $(SolutionDir)src\; 130 | 131 | 132 | Console 133 | true 134 | 135 | 136 | 137 | 138 | Level3 139 | true 140 | true 141 | true 142 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | $(SolutionDir)src\; 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | {3ab9ffbe-dbe7-4d21-80e6-be2cdcf0c01f} 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /examples/Anim/Anim.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {49573744-0e7a-4d4b-8d65-a24148bd180a} 25 | Anim 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 76 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 77 | 78 | 79 | false 80 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 81 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 82 | 83 | 84 | true 85 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 86 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 87 | 88 | 89 | false 90 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 91 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 92 | 93 | 94 | 95 | Level3 96 | true 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)src\; 100 | 101 | 102 | Console 103 | true 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | true 114 | $(SolutionDir)src\; 115 | 116 | 117 | Console 118 | true 119 | true 120 | true 121 | 122 | 123 | 124 | 125 | Level3 126 | true 127 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | true 129 | $(SolutionDir)src\; 130 | 131 | 132 | Console 133 | true 134 | 135 | 136 | 137 | 138 | Level3 139 | true 140 | true 141 | true 142 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | $(SolutionDir)src\; 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | {3ab9ffbe-dbe7-4d21-80e6-be2cdcf0c01f} 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /examples/Boid/Boid.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {1e081d40-b766-42cb-9ed8-02a37bd159a8} 25 | Boid 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 76 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 77 | 78 | 79 | false 80 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 81 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 82 | 83 | 84 | true 85 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 86 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 87 | 88 | 89 | false 90 | $(ProjectDir)bin\$(Configuration)-$(Platform)\ 91 | $(ProjectDir)bin\Intermediates\$(Configuration)-$(Platform)\ 92 | 93 | 94 | 95 | Level3 96 | true 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)src\;%(AdditionalIncludeDirectories) 100 | 101 | 102 | Console 103 | true 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | true 114 | $(SolutionDir)src\;%(AdditionalIncludeDirectories) 115 | 116 | 117 | Console 118 | true 119 | true 120 | true 121 | 122 | 123 | 124 | 125 | Level3 126 | true 127 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | true 129 | $(SolutionDir)src\;%(AdditionalIncludeDirectories) 130 | 131 | 132 | Console 133 | true 134 | 135 | 136 | 137 | 138 | Level3 139 | true 140 | true 141 | true 142 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | $(SolutionDir)src\;%(AdditionalIncludeDirectories) 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | {3ab9ffbe-dbe7-4d21-80e6-be2cdcf0c01f} 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /examples/Ui/menu.cpp: -------------------------------------------------------------------------------- 1 | #include "CppGame.h" 2 | #include 3 | 4 | #define CPP_EXAMPLE_MENU 5 | #include "../Boid/boids.cpp" 6 | #include "../Anim/anim.cpp" 7 | 8 | #include 9 | #include 10 | 11 | namespace CppUi { 12 | 13 | static uint32_t g_Banner; 14 | static float g_BannerWidth; 15 | static float g_BannerHeight; 16 | 17 | constexpr float BANNER_OFFSET_Y = 50; 18 | 19 | static Vec2 g_BannerPos; 20 | static Vec2 g_BannerDim; 21 | static Vec2 g_BannerTargetPos; 22 | static Vec2 g_BannerTargetDim; 23 | static float g_BannerMovementTime; 24 | 25 | enum DispState { 26 | DispState_Menu, 27 | DispState_Boid, 28 | DispState_Anim, 29 | 30 | _DispState_Count 31 | }; 32 | 33 | static DispState g_DispState = DispState_Menu; 34 | static float g_DispStateTransition = 0; 35 | static float g_DispStateDir = 1; 36 | 37 | void ResetBannerPosDimMid(float w, float h) { 38 | g_BannerPos = Lerp(g_BannerPos, g_BannerTargetPos, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 39 | g_BannerDim = Lerp(g_BannerDim, g_BannerTargetDim, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 40 | 41 | g_BannerMovementTime = 0; 42 | 43 | g_BannerTargetDim = 0.4f * Vec2(g_BannerWidth, g_BannerHeight); 44 | g_BannerTargetPos.x = 0.5f * (w - g_BannerTargetDim.x); 45 | g_BannerTargetPos.y = h < g_BannerTargetDim.y ? 0.0f : BANNER_OFFSET_Y; 46 | } 47 | 48 | void ResetBannerPosDimTopLeft() { 49 | g_BannerPos = Lerp(g_BannerPos, g_BannerTargetPos, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 50 | g_BannerDim = Lerp(g_BannerDim, g_BannerTargetDim, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 51 | 52 | g_BannerMovementTime = 0; 53 | 54 | g_BannerTargetDim = 0.15f * Vec2(g_BannerWidth, g_BannerHeight); 55 | g_BannerTargetPos.x = 5; 56 | g_BannerTargetPos.y = 5; 57 | } 58 | 59 | typedef void(*OnUiButtonPressed)(struct UiButton *); 60 | 61 | struct UiButton { 62 | bool Active; 63 | float ActiveTime; 64 | String Label; 65 | float Size; 66 | Vec4 BackColor; 67 | Vec4 TextColor; 68 | Vec4 HoveredColor; 69 | float HoveredTime; 70 | OnUiButtonPressed OnPressed; 71 | struct UiContext * Context; 72 | UiButton * Next; 73 | }; 74 | 75 | struct UiContext { 76 | float MaxWidth; 77 | float PaddingY; 78 | 79 | UiButton *Hot; 80 | UiButton *Active; 81 | 82 | UiButton *Root; 83 | UiButton *Last; 84 | 85 | Platform *P; 86 | }; 87 | 88 | static UiContext g_Ui; 89 | static UiButton *g_Buttons[_DispState_Count]; 90 | 91 | UiButton *AddUiButton(String label, float size = 1) { 92 | UiButton *button = (UiButton *)g_Ui.P->Alloc(sizeof(UiButton)); 93 | 94 | button->Active = true; 95 | button->ActiveTime = 1; 96 | button->Label = label; 97 | button->Size = size; 98 | button->TextColor = Vec4(1); 99 | button->BackColor = Vec4(0.2f, 0.2f, 0.0f, 1); 100 | button->HoveredColor = Vec4(0.5f, 0.5f, 0.0f, 1); 101 | button->HoveredTime = 0; 102 | button->OnPressed = [](UiButton *) { }; 103 | button->Context = &g_Ui; 104 | button->Next = nullptr; 105 | 106 | if (g_Ui.Last) { 107 | g_Ui.Last->Next = button; 108 | g_Ui.Last = button; 109 | } else { 110 | g_Ui.Root = g_Ui.Last = button; 111 | } 112 | 113 | return button; 114 | } 115 | 116 | bool PointInsideRect(Vec2 p, Rect rect) { 117 | return p.x >= rect.Min.x && p.x <= rect.Max.x && p.y >= rect.Min.y && p.y <= rect.Max.y; 118 | } 119 | 120 | void UiUpdate(float dt) { 121 | g_Ui.MaxWidth = 0; 122 | 123 | for (UiButton *b = g_Ui.Root; b; b = b->Next) { 124 | if (b->Active) { 125 | b->ActiveTime += 4 * dt; 126 | b->ActiveTime = Clamp(0, 1, b->ActiveTime); 127 | 128 | float w = CalculateText(b->Label, b->Size); 129 | g_Ui.MaxWidth = Maximum(g_Ui.MaxWidth, w); 130 | 131 | if (g_Ui.Active == b) { 132 | b->OnPressed(b); 133 | g_Ui.Active = nullptr; 134 | } else if (g_Ui.Hot == b && ButtonIsPressed(g_Ui.P, Button_Left)) { 135 | g_Ui.Active = b; 136 | } 137 | 138 | if (b == g_Ui.Hot) { 139 | b->HoveredTime += 3 * dt; 140 | b->HoveredTime = Clamp(0, 1, b->HoveredTime); 141 | } else { 142 | b->HoveredTime -= 3 * dt; 143 | b->HoveredTime = Clamp(0, 1, b->HoveredTime); 144 | } 145 | } else { 146 | b->ActiveTime -= 3 * dt; 147 | b->ActiveTime = Clamp(0, 1, b->ActiveTime); 148 | } 149 | } 150 | } 151 | 152 | void UiRender(Vec2 p) { 153 | Vec2 cursor = g_Ui.P->Mouse.Position; 154 | 155 | g_Ui.Hot = nullptr; 156 | 157 | for (UiButton *b = g_Ui.Root; b; b = b->Next) { 158 | float alpha = SmoothStep(0.0f, 1.0f, b->ActiveTime); 159 | Vec2 dim = Vec2(g_Ui.MaxWidth, GetFontScale(b->Size)); 160 | 161 | float t = SmoothStep(0.0f, 1.0f, b->HoveredTime); 162 | Vec2 d = 8 * Vec2(SmoothStep(0.0f, 1.0f, b->HoveredTime), 0); 163 | Vec4 color = Lerp(b->BackColor, b->HoveredColor, t); 164 | color.w *= alpha; 165 | 166 | DrawRect(p - d, alpha * (dim + 2 * d), color); 167 | DrawRectOutline(p - d - Vec2(1), alpha * (dim + 2 * d + Vec2(2)), Vec4(0, 0, 0, alpha)); 168 | 169 | float w = CalculateText(b->Label, b->Size); 170 | float h = CalculateMaxHeight(b->Label, b->Size); 171 | 172 | DrawText(b->Label, p + 0.5f * Vec2(g_Ui.MaxWidth - w, GetFontScale(b->Size) - h), 173 | Vec4(b->TextColor.xyz, b->TextColor.w * alpha), alpha * b->Size); 174 | 175 | if (b->Active) { 176 | if (g_Ui.Active == nullptr && PointInsideRect(cursor, Rect(p, p + dim))) { 177 | g_Ui.Hot = b; 178 | } 179 | } 180 | 181 | p.y += alpha * (dim.y + g_Ui.PaddingY); 182 | } 183 | } 184 | 185 | void SwitchDispState(DispState state, float w, float h) { 186 | switch (state) { 187 | case DispState_Boid: 188 | case DispState_Anim: 189 | { 190 | g_DispStateTransition = 1; 191 | g_DispStateDir = -0.5f; 192 | 193 | g_DispState = state; 194 | ResetBannerPosDimTopLeft(); 195 | 196 | g_Buttons[DispState_Menu]->Active = true; 197 | g_Buttons[DispState_Anim]->Active = false; 198 | g_Buttons[DispState_Boid]->Active = false; 199 | } break; 200 | 201 | case DispState_Menu: 202 | { 203 | g_DispStateTransition = 0; 204 | g_DispStateDir = 1.4f; 205 | 206 | ResetBannerPosDimMid(w, h); 207 | 208 | g_Buttons[DispState_Menu]->Active = false; 209 | g_Buttons[DispState_Anim]->Active = true; 210 | g_Buttons[DispState_Boid]->Active = true; 211 | } break; 212 | } 213 | } 214 | 215 | bool OnLoad(Platform *p) { 216 | if (!CppBoid::OnLoad(p)) return false; 217 | if (!CppAnim::OnLoad(p)) return false; 218 | 219 | uint32_t channels = 0; 220 | uint32_t w, h; 221 | g_Banner = CreateTextureFromFile(p, "Banner.png", &w, &h, &channels); 222 | g_BannerWidth = (float)w; 223 | g_BannerHeight = (float)h; 224 | 225 | ResetBannerPosDimMid(p->RenderTargetWidth, p->RenderTargetHeight); 226 | g_BannerDim = g_BannerTargetDim; 227 | g_BannerPos = g_BannerTargetPos; 228 | 229 | g_Ui.P = p; 230 | g_Ui.PaddingY = 8; 231 | 232 | g_Buttons[DispState_Boid] = AddUiButton("Boid"); 233 | g_Buttons[DispState_Anim] = AddUiButton("Anim"); 234 | g_Buttons[DispState_Menu] = AddUiButton("Back", 0.4f); 235 | 236 | g_Buttons[DispState_Boid]->OnPressed = [](UiButton *button) { 237 | SwitchDispState(DispState_Boid, button->Context->P->RenderTargetWidth, button->Context->P->RenderTargetHeight); 238 | }; 239 | g_Buttons[DispState_Anim]->OnPressed = [](UiButton *button) { 240 | SwitchDispState(DispState_Anim, button->Context->P->RenderTargetWidth, button->Context->P->RenderTargetHeight); 241 | }; 242 | g_Buttons[DispState_Menu]->OnPressed = [](UiButton *button) { 243 | SwitchDispState(DispState_Menu, button->Context->P->RenderTargetWidth, button->Context->P->RenderTargetHeight); 244 | }; 245 | 246 | SwitchDispState(DispState_Menu, p->RenderTargetWidth, p->RenderTargetHeight); 247 | 248 | return true; 249 | } 250 | 251 | void OnResize(Platform *p, uint32_t w, uint32_t h) { 252 | CppBoid::PlaceObstacles(p, w, h); 253 | if (g_DispState == DispState_Menu) 254 | ResetBannerPosDimMid(p->RenderTargetWidth, p->RenderTargetHeight); 255 | else 256 | ResetBannerPosDimTopLeft(); 257 | } 258 | 259 | void FixedUpdate(Platform *p, float dt) { 260 | switch (g_DispState) { 261 | case DispState_Menu: 262 | { 263 | 264 | } break; 265 | 266 | case DispState_Boid: 267 | { 268 | CppBoid::FixedUpdate(p, dt); 269 | } break; 270 | 271 | case DispState_Anim: 272 | { 273 | CppAnim::FixedUpdate(p, dt); 274 | } break; 275 | } 276 | 277 | g_DispStateTransition += dt * g_DispStateDir; 278 | 279 | if (g_DispStateTransition > 1) 280 | g_DispState = DispState_Menu; 281 | 282 | g_DispStateTransition = Clamp(0, 1, g_DispStateTransition); 283 | 284 | g_BannerMovementTime += 2 * dt; 285 | g_BannerMovementTime = Clamp(0, 1, g_BannerMovementTime); 286 | } 287 | 288 | void UpdateAndRender(Platform *p, float dt, float alpha) { 289 | if (KeyIsPressed(p, Key_Escape)) { 290 | PlatformQuit(p); 291 | } 292 | 293 | if (KeyIsPressed(p, Key_0)) { 294 | SwitchDispState(DispState_Menu, p->RenderTargetWidth, p->RenderTargetHeight); 295 | } 296 | if (KeyIsPressed(p, Key_1)) { 297 | SwitchDispState(DispState_Boid, p->RenderTargetWidth, p->RenderTargetHeight); 298 | } 299 | if (KeyIsPressed(p, Key_2)) { 300 | SwitchDispState(DispState_Anim, p->RenderTargetWidth, p->RenderTargetHeight); 301 | } 302 | 303 | switch (g_DispState) { 304 | case DispState_Menu: 305 | { 306 | 307 | } break; 308 | 309 | case DispState_Boid: 310 | { 311 | CppBoid::UpdateAndRender(p, dt, alpha); 312 | } break; 313 | 314 | case DispState_Anim: 315 | { 316 | CppAnim::UpdateAndRender(p, dt, alpha); 317 | } break; 318 | } 319 | 320 | UiUpdate(dt); 321 | 322 | auto banner_disp_pos = Lerp(g_BannerPos, g_BannerTargetPos, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 323 | auto banner_disp_dim = Lerp(g_BannerDim, g_BannerTargetDim, SmoothStep(0.0f, 1.0f, g_BannerMovementTime)); 324 | 325 | Vec4 clear_color(0.1f, 0.1f, 0.1f, 1); 326 | SetClearColor(clear_color); 327 | 328 | BeginScene2D(0, p->RenderTargetWidth, 0, p->RenderTargetHeight); 329 | 330 | clear_color.w *= SmoothStep(0.0f, 1.0f, g_DispStateTransition); 331 | DrawRect(Vec2(0), Vec2(p->RenderTargetWidth, p->RenderTargetHeight), Rect(0, 0, 1, 1), clear_color); 332 | 333 | SetTexture(g_Banner); 334 | 335 | if (PointInsideRect(p->Mouse.Position, Rect(banner_disp_pos, banner_disp_pos + banner_disp_dim))) { 336 | constexpr uint32_t SPLITS = 10; 337 | 338 | Vec2 a, b, c, d; 339 | float ds = 1.0f / (float)SPLITS; 340 | float ta = 0, tb = ds; 341 | 342 | Vec2 pos = banner_disp_pos; 343 | Vec2 dim = Vec2(ds * banner_disp_dim.x, banner_disp_dim.y); 344 | 345 | for (uint32_t split = 0; split < SPLITS; ++split) { 346 | a = pos; 347 | b = a; 348 | b.y += dim.y; 349 | c = a + dim; 350 | d = a; 351 | d.x += dim.x; 352 | 353 | float amp = 5; 354 | float freq = 0.05f; 355 | 356 | a.y += amp * Map01(-1.0f, 1.0f, Sin(freq * p->Time.Time * a.x)); 357 | b.y += amp * Map01(-1.0f, 1.0f, Sin(freq * p->Time.Time * b.x)); 358 | c.y += amp * Map01(-1.0f, 1.0f, Sin(freq * p->Time.Time * c.x)); 359 | d.y += amp * Map01(-1.0f, 1.0f, Sin(freq * p->Time.Time * d.x)); 360 | 361 | DrawQuad(a, b, c, d, Vec2(ta, 0), Vec2(ta, 1), Vec2(tb, 1), Vec2(tb, 0), Vec4(1)); 362 | 363 | ta = tb; 364 | tb += ds; 365 | 366 | pos.x += dim.x; 367 | } 368 | 369 | } else { 370 | DrawRect(banner_disp_pos, banner_disp_dim, Rect(0, 0, 1, 1), Vec4(1)); 371 | } 372 | 373 | 374 | SetTexture(0); 375 | 376 | Vec2 ui_pos; 377 | ui_pos.y = banner_disp_pos.y + banner_disp_dim.y + 5; 378 | ui_pos.x = banner_disp_pos.x + 0.5f * (banner_disp_dim.x - g_Ui.MaxWidth); 379 | UiRender(ui_pos); 380 | 381 | EndScene2D(); 382 | } 383 | 384 | } 385 | 386 | CppGameCall void CppGameInitialize(Platform *platform, int argc, char **argv) { 387 | platform->Name = "Ui Example"; 388 | platform->OnLoad = CppUi::OnLoad; 389 | platform->OnWindowResize = CppUi::OnResize; 390 | platform->FixedUpdate = CppUi::FixedUpdate; 391 | platform->UpdateAndRender = CppUi::UpdateAndRender; 392 | } 393 | -------------------------------------------------------------------------------- /src/CppGame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CppGameCore.h" 3 | #include 4 | #include 5 | 6 | constexpr float PI = 3.1415926535f; 7 | constexpr float PI_INVERSE = 1.0f / PI; 8 | constexpr float TAU = PI / 2; 9 | constexpr float REAL_EPSILON = FLT_EPSILON; 10 | constexpr float REAL_MAX = FLT_MAX; 11 | constexpr float REAL_MIN = FLT_MIN; 12 | constexpr float REAL_INFINITY = INFINITY; 13 | 14 | union Vec2 { 15 | struct { 16 | float x, y; 17 | }; 18 | float m[2]; 19 | Vec2() { } 20 | Vec2(float a): x(a), y(a) { } 21 | Vec2(float a, float b): x(a), y(b) { } 22 | float &operator()(uint32_t index) { 23 | Assert(index < 2); 24 | return ((float *)this)[index]; 25 | } 26 | }; 27 | 28 | union Vec3 { 29 | struct { 30 | float x, y, z; 31 | }; 32 | struct { 33 | Vec2 xy; 34 | float _z; 35 | }; 36 | struct { 37 | float _x; 38 | Vec2 yz; 39 | }; 40 | float m[3]; 41 | Vec3() { } 42 | Vec3(float a): x(a), y(a), z(a) { } 43 | Vec3(float a, float b, float c): x(a), y(b), z(c) { } 44 | Vec3(Vec2 ab, float c): xy(ab), _z(c) { } 45 | Vec3(float a, Vec2 cd): _x(a), yz(cd) { } 46 | float &operator()(uint32_t index) { 47 | Assert(index < 3); 48 | return ((float *)this)[index]; 49 | } 50 | }; 51 | 52 | union Vec4 { 53 | struct { 54 | float x, y, z, w; 55 | }; 56 | struct { 57 | Vec2 xy, zw; 58 | }; 59 | struct { 60 | Vec3 xyz; 61 | float _w; 62 | }; 63 | struct { 64 | float _x; 65 | Vec3 yzw; 66 | }; 67 | float m[4]; 68 | Vec4() { } 69 | Vec4(float a): x(a), y(a), z(a), w(a) { } 70 | Vec4(float a, float b, float c, float d): x(a), y(b), z(c), w(d) { } 71 | Vec4(Vec2 ab, Vec2 cd): xy(ab), zw(cd) { } 72 | Vec4(Vec3 abc, float d): xyz(abc), _w(d) { } 73 | Vec4(float a, Vec3 bcd): _x(a), yzw(bcd) { } 74 | float &operator()(uint32_t index) { 75 | Assert(index < 4); 76 | return ((float *)this)[index]; 77 | } 78 | }; 79 | 80 | union Mat2 { 81 | Vec2 rows[2]; 82 | float m[4]; 83 | float m2[2][2]; 84 | Mat2() { } 85 | float &operator()(uint32_t i, uint32_t j) { 86 | Assert(i < 2 && j < 2); 87 | return m2[i][j]; 88 | } 89 | }; 90 | 91 | union Mat3 { 92 | Vec3 rows[3]; 93 | float m[9]; 94 | float m2[3][3]; 95 | Mat3() { } 96 | float &operator()(uint32_t i, uint32_t j) { 97 | Assert(i < 3 && j < 3); 98 | return m2[i][j]; 99 | } 100 | }; 101 | 102 | union Mat4 { 103 | Vec4 rows[4]; 104 | float m[16]; 105 | float m2[4][4]; 106 | inline Mat4() { } 107 | inline float &operator()(uint32_t i, uint32_t j) { 108 | Assert(i < 4 && j < 4); 109 | return m2[i][j]; 110 | } 111 | }; 112 | 113 | union Quat { 114 | float m[4]; 115 | struct { 116 | float x, y, z, w; 117 | }; 118 | struct { 119 | float i, j, k, real; 120 | }; 121 | struct { 122 | Vec4 v4; 123 | }; 124 | Quat() { } 125 | Quat(Vec4 v): v4(v) { } 126 | Quat(float b, float c, float d, float a) { 127 | m[0] = b; 128 | m[1] = c; 129 | m[2] = d; 130 | m[3] = a; 131 | } 132 | float &operator()(uint32_t index) { 133 | Assert(index < 4); 134 | return ((float *)this)[index]; 135 | } 136 | }; 137 | 138 | #define ExpandVec2(v) (v).x, (v).y 139 | #define ExpandVec3(v) (v).x, (v).y, (v).z 140 | #define ExpandVec4(v) (v).x, (v).y, (v).z, (v).w 141 | 142 | #define DegreesToRadians(deg) ((deg) * (PI / 180)) 143 | #define RadiansToDegrees(rad) ((rad) * (180 / PI)) 144 | 145 | #define Absolute(x) fabsf(x) 146 | #define Sin(x) sinf(x) 147 | #define Cos(x) cosf(x) 148 | #define Tan(x) tanf(x) 149 | #define ArcSin(x) asinf(x) 150 | #define ArcCos(x) acosf(x) 151 | #define ArcTan2(y, x) atan2f(y, x) 152 | #define SquareRoot(x) sqrtf(x) 153 | #define Pow(x, y) powf(x, y) 154 | #define CopySign(x, y) copysignf(x, y) 155 | #define Mod(x, y) fmodf(x, y) 156 | #define Square(x) ((x) * (x)) 157 | 158 | inline Vec2 Arm(float angle) { return Vec2(Cos(angle), Sin(angle)); } 159 | inline Vec2 ArmInverse(float angle) { return Vec2(Sin(angle), Cos(angle)); } 160 | 161 | inline Vec2 MinimumVec(Vec2 a, Vec2 b) { return Vec2{ Minimum(a.x, b.x), Minimum(a.y, b.y) }; } 162 | inline Vec2 MaximumVec(Vec2 a, Vec2 b) { return Vec2{ Maximum(a.x, b.x), Maximum(a.y, b.y) }; } 163 | inline Vec3 MinimumVec(Vec3 a, Vec3 b) { return Vec3{ Minimum(a.x, b.x), Minimum(a.y, b.y), Minimum(a.z, b.z) }; } 164 | inline Vec3 MaximumVec(Vec3 a, Vec3 b) { return Vec3{ Maximum(a.x, b.x), Maximum(a.y, b.y), Maximum(a.z, b.z) }; } 165 | inline Vec4 MinimumVec(Vec4 a, Vec4 b) { return Vec4{ Minimum(a.x, b.x), Minimum(a.y, b.y), Minimum(a.z, b.z), Minimum(a.w, b.w) }; } 166 | inline Vec4 MaximumVec(Vec4 a, Vec4 b) { return Vec4{ Maximum(a.x, b.x), Maximum(a.y, b.y), Maximum(a.z, b.z), Maximum(a.w, b.w) }; } 167 | 168 | inline bool IsNull(Vec2 a) { return Absolute(a.x) < REAL_EPSILON && Absolute(a.y) < REAL_EPSILON; } 169 | inline bool IsNull(Vec3 a) { return Absolute(a.x) < REAL_EPSILON && Absolute(a.y) < REAL_EPSILON && Absolute(a.z) < REAL_EPSILON; } 170 | inline bool IsNull(Vec4 a) { return Absolute(a.x) < REAL_EPSILON && Absolute(a.y) < REAL_EPSILON && Absolute(a.z) < REAL_EPSILON && Absolute(a.w) < REAL_EPSILON; } 171 | 172 | inline Vec2 operator+(Vec2 a, Vec2 b) { return Vec2(a.x + b.x, a.y + b.y); } 173 | inline Vec3 operator+(Vec3 a, Vec3 b) { return Vec3(a.x + b.x, a.y + b.y, a.z + b.z); } 174 | inline Vec4 operator+(Vec4 a, Vec4 b) { return Vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); } 175 | inline Vec2 operator-(Vec2 a, Vec2 b) { return Vec2(a.x - b.x, a.y - b.y); } 176 | inline Vec3 operator-(Vec3 a, Vec3 b) { return Vec3(a.x - b.x, a.y - b.y, a.z - b.z); } 177 | inline Vec4 operator-(Vec4 a, Vec4 b) { return Vec4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); } 178 | inline Vec2 operator*(float s, Vec2 v) { return Vec2(s * v.x, s * v.y); } 179 | inline Vec2 operator*(Vec2 v, float s) { return s * v; } 180 | inline Vec3 operator*(float s, Vec3 v) { return Vec3(s * v.x, s * v.y, s * v.z); } 181 | inline Vec3 operator*(Vec3 v, float s) { return s * v; } 182 | inline Vec4 operator*(float s, Vec4 v) { return Vec4(s * v.x, s * v.y, s * v.z, s * v.w); } 183 | inline Vec4 operator*(Vec4 v, float s) { return s * v; } 184 | inline Vec2 operator/(Vec2 v, float s) { 185 | s = 1.0f / s; 186 | return Vec2(v.x * s, v.y * s); 187 | } 188 | inline Vec3 operator/(Vec3 v, float s) { 189 | s = 1.0f / s; 190 | return Vec3(v.x * s, v.y * s, v.z * s); 191 | } 192 | inline Vec4 operator/(Vec4 v, float s) { return v * 1.0f / s; } 193 | inline Vec2 operator*(Vec2 l, Vec2 r) { return Vec2(l.x * r.x, l.y * r.y); } 194 | inline Vec3 operator*(Vec3 l, Vec3 r) { return Vec3(l.x * r.x, l.y * r.y, l.z * r.z); } 195 | inline Vec4 operator*(Vec4 l, Vec4 r) { return Vec4(l.x * r.x, l.y * r.y, l.z * r.z, l.w * r.w); } 196 | inline Vec2 operator/(Vec2 l, Vec2 r) { return Vec2(l.x / r.x, l.y / r.y); } 197 | inline Vec3 operator/(Vec3 l, Vec3 r) { return Vec3(l.x / r.x, l.y / r.y, l.z / r.z); } 198 | inline Vec4 operator/(Vec4 l, Vec4 r) { return Vec4(l.x / r.x, l.y / r.y, l.z / r.z, l.w / r.w); } 199 | 200 | inline Vec2 operator-(const Vec2 &v) { return Vec2(-v.x, -v.y); } 201 | inline Vec3 operator-(const Vec3 &v) { return Vec3(-v.x, -v.y, -v.z); } 202 | inline Vec4 operator-(const Vec4 &v) { return Vec4(-v.x, -v.y, -v.z, -v.w); } 203 | inline Vec2 &operator+=(Vec2 &a, Vec2 b) { 204 | a = a + b; 205 | return a; 206 | } 207 | inline Vec3 &operator+=(Vec3 &a, Vec3 b) { 208 | a = a + b; 209 | return a; 210 | } 211 | inline Vec4 &operator+=(Vec4 &a, Vec4 b) { 212 | a = a + b; 213 | return a; 214 | } 215 | inline Vec2 &operator-=(Vec2 &a, Vec2 b) { 216 | a = a - b; 217 | return a; 218 | } 219 | inline Vec3 &operator-=(Vec3 &a, Vec3 b) { 220 | a = a - b; 221 | return a; 222 | } 223 | inline Vec4 &operator-=(Vec4 &a, Vec4 b) { 224 | a = a - b; 225 | return a; 226 | } 227 | inline Vec2 &operator*=(Vec2 &t, float s) { 228 | t = t * s; 229 | return t; 230 | } 231 | inline Vec3 &operator*=(Vec3 &t, float s) { 232 | t = t * s; 233 | return t; 234 | } 235 | inline Vec4 &operator*=(Vec4 &t, float s) { 236 | t = t * s; 237 | return t; 238 | } 239 | inline Vec2 &operator/=(Vec2 &t, float s) { 240 | t = t / s; 241 | return t; 242 | } 243 | inline Vec3 &operator/=(Vec3 &t, float s) { 244 | t = t / s; 245 | return t; 246 | } 247 | inline Vec4 &operator/=(Vec4 &t, float s) { 248 | t = t / s; 249 | return t; 250 | } 251 | inline Vec2 &operator*=(Vec2 &t, Vec2 s) { 252 | t = t * s; 253 | return t; 254 | } 255 | inline Vec3 &operator*=(Vec3 &t, Vec3 s) { 256 | t = t * s; 257 | return t; 258 | } 259 | inline Vec4 &operator*=(Vec4 &t, Vec4 s) { 260 | t = t * s; 261 | return t; 262 | } 263 | inline Vec2 &operator/=(Vec2 &t, Vec2 s) { 264 | t = t / s; 265 | return t; 266 | } 267 | inline Vec3 &operator/=(Vec3 &t, Vec3 s) { 268 | t = t / s; 269 | return t; 270 | } 271 | inline Vec4 &operator/=(Vec4 &t, Vec4 s) { 272 | t = t / s; 273 | return t; 274 | } 275 | 276 | inline float DotProduct(Vec2 a, Vec2 b) { return a.x * b.x + a.y * b.y; } 277 | inline float DotProduct(Vec3 a, Vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } 278 | inline float DotProduct(Vec4 a, Vec4 b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } 279 | inline float Determinant(Vec2 a, Vec2 b) { return (a.x * b.y) - (a.y * b.x); } 280 | inline Vec3 CrossProduct(Vec2 a, Vec2 b) { 281 | Vec3 res; 282 | res.x = 0; 283 | res.y = 0; 284 | res.z = (a.x * b.y) - (a.y * b.x); 285 | return res; 286 | } 287 | inline Vec3 CrossProduct(Vec3 a, Vec3 b) { 288 | Vec3 res; 289 | res.x = (a.y * b.z) - (a.z * b.y); 290 | res.y = (a.z * b.x) - (a.x * b.z); 291 | res.z = (a.x * b.y) - (a.y * b.x); 292 | return res; 293 | } 294 | inline Vec2 TripleProduct(Vec2 a, Vec2 b, Vec2 c) { 295 | float det = Determinant(a, b); 296 | Vec2 res; 297 | res.x = -c.y * det; 298 | res.y = c.x * det; 299 | return res; 300 | } 301 | inline Vec3 TripleProduct(Vec3 a, Vec3 b, Vec3 c) { return CrossProduct(CrossProduct(a, b), c); } 302 | 303 | inline float LengthSq(Vec2 v) { return DotProduct(v, v); } 304 | inline float LengthSq(Vec3 v) { return DotProduct(v, v); } 305 | inline float LengthSq(Vec4 v) { return DotProduct(v, v); } 306 | inline float Length(Vec2 v) { return SquareRoot(DotProduct(v, v)); } 307 | inline float Length(Vec3 v) { return SquareRoot(DotProduct(v, v)); } 308 | inline float Length(Vec4 v) { return SquareRoot(DotProduct(v, v)); } 309 | inline float Distance(float a, float b) { return b - a; } 310 | inline float Distance(Vec2 a, Vec2 b) { return Length(b - a); } 311 | inline float Distance(Vec3 a, Vec3 b) { return Length(b - a); } 312 | inline float Distance(Vec4 a, Vec4 b) { return Length(b - a); } 313 | 314 | inline Vec2 NormalizeChecked(Vec2 v) { 315 | Vec2 res = {}; 316 | float len = Length(v); 317 | if (len != 0) res = v / len; 318 | return res; 319 | } 320 | inline Vec3 NormalizeChecked(Vec3 v) { 321 | Vec3 res = {}; 322 | float len = Length(v); 323 | if (len != 0) res = v / len; 324 | return res; 325 | } 326 | inline Vec4 NormalizeChecked(Vec4 v) { 327 | Vec4 res = {}; 328 | float len = Length(v); 329 | if (len != 0) res = v * (1.0f / len); 330 | return res; 331 | } 332 | inline Vec2 Normalize(Vec2 v) { 333 | Vec2 res = {}; 334 | float len = Length(v); 335 | Assert(len != 0); 336 | res = v / len; 337 | return res; 338 | } 339 | inline Vec3 Normalize(Vec3 v) { 340 | Vec3 res = {}; 341 | float len = Length(v); 342 | Assert(len != 0); 343 | res = v / len; 344 | return res; 345 | } 346 | inline Vec4 Normalize(Vec4 v) { 347 | Vec4 res = {}; 348 | float len = Length(v); 349 | Assert(len != 0); 350 | res = v * (1.0f / len); 351 | return res; 352 | } 353 | 354 | inline float AngleBetween(Vec2 a, Vec2 b) { 355 | float dot = Clamp(-1.0f, 1.0f, DotProduct(a, b)); 356 | return Cos(dot); 357 | } 358 | inline float AngleBetween(Vec3 a, Vec3 b) { 359 | float dot = Clamp(-1.0f, 1.0f, DotProduct(a, b)); 360 | return Cos(dot); 361 | } 362 | inline float AngleBetweenNormalized(Vec2 a, Vec2 b) { 363 | a = Normalize(a); 364 | b = Normalize(b); 365 | return AngleBetween(a, b); 366 | } 367 | inline float AngleBetweenNormalized(Vec3 a, Vec3 b) { 368 | a = Normalize(a); 369 | b = Normalize(b); 370 | return AngleBetween(a, b); 371 | } 372 | inline float SignedAngleBetween(Vec2 a, Vec2 b) { 373 | float dot = Clamp(-1.0f, 1.0f, DotProduct(a, b)); 374 | float angle = Cos(dot); 375 | float cross = a.x * b.y - a.y * b.x; 376 | if (cross < 0) { 377 | angle = -angle; 378 | } 379 | return angle; 380 | } 381 | inline float SignedAngleBetween(Vec3 a, Vec3 b, Vec3 n) { 382 | float dot = Clamp(-1.0f, 1.0f, DotProduct(a, b)); 383 | float angle = Cos(dot); 384 | Vec3 cross = CrossProduct(a, b); 385 | if (DotProduct(n, cross) < 0) { 386 | angle = -angle; 387 | } 388 | return angle; 389 | } 390 | inline float SignedAngleBetweenNormalized(Vec2 a, Vec2 b) { 391 | a = Normalize(a); 392 | b = Normalize(b); 393 | return SignedAngleBetween(a, b); 394 | } 395 | inline float SignedAngleBetweenNormalized(Vec3 a, Vec3 b, Vec3 n) { 396 | a = Normalize(a); 397 | b = Normalize(b); 398 | n = Normalize(n); 399 | return SignedAngleBetween(a, b, n); 400 | } 401 | 402 | inline Vec2 ClampVec(Vec2 min, Vec2 max, Vec2 v) { 403 | v.x = Clamp(min.x, max.x, v.x); 404 | v.y = Clamp(min.y, max.y, v.y); 405 | return v; 406 | } 407 | inline Vec3 ClampVec(Vec3 min, Vec3 max, Vec3 v) { 408 | v.x = Clamp(min.x, max.x, v.x); 409 | v.y = Clamp(min.y, max.y, v.y); 410 | v.z = Clamp(min.z, max.z, v.z); 411 | return v; 412 | } 413 | inline Vec4 ClampVec(Vec4 min, Vec4 max, Vec4 v) { 414 | v.x = Clamp(min.x, max.x, v.x); 415 | v.y = Clamp(min.y, max.y, v.y); 416 | v.z = Clamp(min.z, max.z, v.z); 417 | v.w = Clamp(min.w, max.w, v.w); 418 | return v; 419 | } 420 | 421 | Mat2 IdentityMat2(); 422 | float Determinant(const Mat2 &mat); 423 | Mat2 Inverse(const Mat2 &mat); 424 | Mat2 Transpose(const Mat2 &m); 425 | Mat3 IdentityMat3(); 426 | float Determinant(const Mat3 &mat); 427 | Mat3 Inverse(const Mat3 &mat); 428 | Mat3 Transpose(const Mat3 &m); 429 | Mat4 IdentityMat4(); 430 | float Determinant(const Mat4 &mat); 431 | Mat4 Inverse(const Mat4 &mat); 432 | Mat4 Transpose(const Mat4 &m); 433 | 434 | Mat2 operator*(const Mat2 &left, const Mat2 &right); 435 | Vec2 operator*(const Mat2 &mat, Vec2 vec); 436 | Vec2 operator*(Vec2 vec, const Mat2 &mat); 437 | Mat3 operator*(const Mat3 &left, const Mat3 &right); 438 | Vec3 operator*(const Mat3 &mat, Vec3 vec); 439 | Mat4 operator*(const Mat4 &left, const Mat4 &right); 440 | Vec4 operator*(const Mat4 &mat, Vec4 vec); 441 | 442 | inline Mat2 &operator*=(Mat2 &t, Mat2 &o) { 443 | t = t * o; 444 | return t; 445 | } 446 | inline Mat3 &operator*=(Mat3 &t, Mat3 &o) { 447 | t = t * o; 448 | return t; 449 | } 450 | inline Mat4 &operator*=(Mat4 &t, Mat4 &o) { 451 | t = t * o; 452 | return t; 453 | } 454 | 455 | // 456 | // 457 | // 458 | 459 | Mat2 ScalarMat2(float x, float y); 460 | Mat2 ScalarMat2(Vec2 s); 461 | Mat2 RotationMat2(float angle); 462 | Mat3 ScalarMat3(float S_1, float S_2); 463 | Mat3 ScalarMat3(Vec2 s); 464 | Mat3 TranslationMat3(float T_x, float T_y); 465 | Mat3 TranslationMat3(Vec2 t); 466 | Mat3 RotationMat3(float angle); 467 | Mat3 LookAt(Vec2 from, Vec2 to, Vec2 forward); 468 | Mat4 LookAtDirection(Vec3 dir, Vec3 world_up); 469 | Mat4 ScalarMat4(float S_1, float S_2, float S_3); 470 | Mat4 ScalarMat4(Vec3 s); 471 | Mat4 TranslationMat4(float T_x, float T_y, float T_z); 472 | Mat4 TranslationMat4(Vec3 t); 473 | Mat4 RotationX(float angle); 474 | Mat4 RotationY(float angle); 475 | Mat4 RotationZ(float angle); 476 | Mat4 RotationMat4(float x, float y, float z, float angle); 477 | Mat4 RotationMat4(Vec3 axis, float angle); 478 | Mat4 LookAt(Vec3 from, Vec3 to, Vec3 world_up); 479 | Mat4 OrthographicProjection(float l, float r, float t, float b, float n, float f); 480 | Mat4 PerspectiveProjection(float fov, float aspect_ratio, float n, float f); 481 | Vec3 GetRight(const Mat4 &m); 482 | Vec3 GetUp(const Mat4 &m); 483 | Vec3 GetForward(const Mat4 &m); 484 | Mat2 ToMat2(const Mat3 &mat); 485 | Mat3 ToMat3(const Mat2 &mat); 486 | Mat3 ToMat3(const Mat4 &mat); 487 | Mat4 ToMat4(const Mat3 &mat); 488 | 489 | inline Quat operator-(Quat &q) { return Quat(-q.v4); } 490 | inline Quat operator-(Quat r1, Quat r2) { return Quat(r1.v4 - r2.v4); } 491 | inline Quat operator+(Quat r1, Quat r2) { return Quat(r1.v4 + r2.v4); } 492 | inline Quat operator*(Quat q, float s) { return Quat(q.v4 * s); } 493 | inline Quat operator*(float s, Quat q) { return Quat(q.v4 * s); } 494 | 495 | Quat IdentityQuat(); 496 | float DotProduct(Quat q1, Quat q2); 497 | float Length(Quat q); 498 | Quat Normalize(Quat q); 499 | Quat Conjugate(Quat q); 500 | Quat operator*(Quat q1, Quat q2); 501 | Vec3 Rotate(Quat q, Vec3 v); 502 | inline Vec3 operator*(Quat q, Vec3 v) { Rotate(q, v); } 503 | Quat QuatFromAngleAxis(Vec3 axis, float angle); 504 | Quat QuatFromAngleAxisNormalized(Vec3 axis, float angle); 505 | void GetAngleAxis(Quat q, float *angle, Vec3 *axis); 506 | Vec3 GetAxis(Quat q); 507 | float GetAngle(Quat q); 508 | Quat QuatFromMat4(const Mat4 &m); 509 | Quat QuatFromMat4Nomalized(const Mat4 &m); 510 | Mat4 GetMat4(Quat q); 511 | Vec3 GetForward(Quat q); 512 | Vec3 GetRight(Quat q); 513 | Vec3 GetUp(Quat q); 514 | Quat QuatFromEulerAngles(float pitch, float yaw, float roll); 515 | Quat QuatFromEulerAngles(Vec3 euler); 516 | Vec3 GetEulerAngles(Quat q); 517 | Quat QuatBetween(Vec3 from, Vec3 to); 518 | Quat QuatBetween(Quat a, Quat b); 519 | Quat QuatLookAt(Vec3 from, Vec3 to, Vec3 world_forward); 520 | 521 | Vec3 LinearToSrgb(Vec3 color); 522 | Vec4 LinearToSrgb(Vec4 color); 523 | Vec3 LinearToSrgb(Vec3 color, float gamma); 524 | Vec4 LinearToSrgb(Vec4 color, float gamma); 525 | Vec3 SrgbToLinear(Vec3 color); 526 | Vec4 SrgbToLinear(Vec4 color); 527 | Vec3 SrgbToLinear(Vec3 color, float gamma); 528 | Vec4 SrgbToLinear(Vec4 color, float gamma); 529 | 530 | Vec3 HsvToRgb(Vec3 c); 531 | Vec3 RgbToHsv(Vec3 c); 532 | Vec4 HsvToRgb(Vec4 c); 533 | Vec4 RgbToHsv(Vec4 c); 534 | 535 | template 536 | Type Lerp(Type from, Type to, float t) { 537 | return (1 - t) * from + t * to; 538 | } 539 | 540 | template 541 | Type BezierQuadratic(Type a, Type b, Type c, float t) { 542 | float mt = 1 - t; 543 | float w1 = mt * mt; 544 | float w2 = 2 * mt * t; 545 | float w3 = t * t; 546 | return w1 * a + w2 * b + w3 * c; 547 | } 548 | 549 | template 550 | Type BezeriCubic(Type a, Type b, Type c, Type d, float t) { 551 | float mt = 1.0f - t; 552 | float w1 = mt * mt * mt; 553 | float w2 = 3 * mt * mt * t; 554 | float w3 = 3 * mt * t * t; 555 | float w4 = t * t * t; 556 | return w1 * a + w2 * b + w3 * c + w4 * d; 557 | } 558 | 559 | template 560 | Type Slerp(Type from, Type to, float angle, float t) { 561 | float s = Sin(angle); 562 | float ts = Sin(angle * t); 563 | float mts = Sin(angle * (1 - t)); 564 | return (mts * from + ts * to) * (1.0f / s); 565 | } 566 | 567 | Mat2 Lerp(const Mat2 &from, const Mat2 &to, float t); 568 | Mat3 Lerp(const Mat3 &from, const Mat3 &to, float t); 569 | Mat4 Lerp(const Mat4 &from, const Mat4 &to, float t); 570 | Vec2 Slerp(Vec2 from, Vec2 to, float t); 571 | Vec3 Slerp(Vec3 from, Vec3 to, float t); 572 | Quat Slerp(Quat from, Quat to, float t); 573 | float Step(float edge, float val); 574 | Vec2 Step(Vec2 edge, Vec2 val); 575 | Vec3 Step(Vec3 edge, Vec3 val); 576 | Vec4 Step(Vec4 edge, Vec4 val); 577 | Quat Step(Quat edge, Quat val); 578 | 579 | template 580 | float SmoothStepZeroChecked(T a, T b, T v) { 581 | float div_distance = Distance(a, b); 582 | if (div_distance) { 583 | auto x = Clamp(0.0f, 1.0f, Distance(a, v) / div_distance); 584 | return x * x * (3 - 2 * x); 585 | } 586 | return 1; 587 | } 588 | 589 | template 590 | float SmoothStep(T a, T b, T v) { 591 | auto x = Clamp(0.0f, 1.0f, Distance(a, v) / Distance(a, b)); 592 | return x * x * (3 - 2 * x); 593 | } 594 | 595 | float InverseSmoothStep(float x); 596 | 597 | template 598 | T MapRange(T in_a, T in_b, T out_a, T out_b, T v) { 599 | return (out_b - out_a) / (in_b - in_a) * (v - in_a) + out_a; 600 | } 601 | template 602 | T Map01(T in_a, T in_b, T v) { 603 | return MapRange(in_a, in_b, T(0), T(1), v); 604 | } 605 | 606 | Vec2 MoveTowards(Vec2 from, Vec2 to, float factor); 607 | Vec3 MoveTowards(Vec3 from, Vec3 to, float factor); 608 | Vec4 MoveTowards(Vec4 from, Vec4 to, float factor); 609 | Vec2 RotateAround(Vec2 point, Vec2 center, float angle); 610 | Quat RotateTowards(Quat from, Quat to, float max_angle); 611 | Vec2 Reflect(Vec2 d, Vec2 n); 612 | 613 | union UintColor { 614 | struct { 615 | uint8_t r, g, b, a; 616 | }; 617 | uint8_t channels[4]; 618 | 619 | UintColor() { } 620 | UintColor(uint8_t x, uint8_t y, uint8_t z, uint8_t w): r(x), g(y), b(z), a(w) { } 621 | }; 622 | 623 | UintColor Vec4ToUintColor(Vec4 v); 624 | UintColor Vec3ToUintColor(Vec3 v); 625 | Vec4 UintColorToVec4(UintColor c); 626 | Vec3 UintColorToVec3(UintColor c); 627 | 628 | struct Rect { 629 | Vec2 Min; 630 | Vec2 Max; 631 | 632 | Rect() { } 633 | Rect(Vec2 min, Vec2 max): Min(min), Max(max) { } 634 | Rect(float min_x, float min_y, float max_x, float max_y): Min(min_x, min_y), Max(max_x, max_y) { } 635 | }; 636 | 637 | // 638 | // 639 | // 640 | 641 | #pragma once 642 | 643 | #define KiloBytes(n) ((n)*1024u) 644 | #define MegaBytes(n) (KiloBytes(n) * 1024u) 645 | #define GigaBytes(n) (MegaBytes(n) * 1024u) 646 | 647 | struct Arena { 648 | uint8_t *Current; 649 | uint8_t *Memory; 650 | uint8_t *Max; 651 | }; 652 | 653 | Arena CreateArena(uint8_t *ptr, size_t size); 654 | void ResetArena(Arena *arena); 655 | 656 | size_t AllocatedMemory(Arena *arena); 657 | size_t UsedMemory(Arena *arena); 658 | size_t LeftMemory(Arena *arena); 659 | 660 | void *BeginTemporaryMemory(Arena *arena); 661 | void EndTemporaryMemory(Arena *arena, void *ptr); 662 | 663 | uint8_t *Align(uint8_t *location, size_t alignment); 664 | size_t Align(size_t location, size_t alignment); 665 | 666 | void *PushSize(Arena *arena, size_t size); 667 | void *PushSizeAligned(Arena *arena, size_t size, uint32_t alignment); 668 | 669 | #define PushType(arena, type) (type *)PushSize(arena, sizeof(type)) 670 | #define PushArray(arena, type, count) (type *)PushSize(arena, sizeof(type) * count) 671 | #define PushArrayAligned(arena, type, count, alignment) (type *)PushSizeAligned(arena, sizeof(type) * count, alignment) 672 | 673 | void *operator new(size_t size, Arena *arena) noexcept; 674 | 675 | // 676 | // 677 | // 678 | 679 | struct CodepointRange { 680 | uint32_t *Buffer; // NOTE: Must be arranged ascending order 681 | uint32_t First; 682 | uint32_t Count; 683 | }; 684 | 685 | struct GlyphInfo { 686 | Rect TexCoord; 687 | Vec2 Bearing; 688 | float Advance; 689 | Vec2 Dimension; 690 | }; 691 | 692 | struct GlyphRange { 693 | CodepointRange Codepoint; 694 | GlyphInfo *Info; 695 | }; 696 | 697 | struct Font { 698 | float Size; 699 | float Ascender; 700 | float Descender; 701 | uint32_t Texture; 702 | GlyphRange *Range; 703 | uint32_t RangeCount; 704 | }; 705 | 706 | // 707 | // 708 | // 709 | 710 | static constexpr int DEFAULT_CIRCLE_SEGMENTS = 48; 711 | static constexpr int DEFAULT_BEZIER_SEGMENTS = 48; 712 | 713 | void SetDefaultTexture(uint32_t texture); 714 | uint32_t GetDefaultTexture(); 715 | 716 | void SetClearColor(float r, float g, float b, float a); 717 | void SetClearColor(Vec4 color); 718 | Vec4 GetClearColor(); 719 | void SetThickness(float thickness); 720 | void SetTexture(uint32_t texture); 721 | uint32_t PushTexture(uint32_t texture); 722 | void PopTexture(uint32_t texture); 723 | 724 | void SetClipRect(Rect clip_rect); 725 | Rect PushClipRect(Rect clip_rect); 726 | void PopClipRect(Rect clip_rect); 727 | void BeginScene2D(const Mat4 &view); 728 | void BeginScene2D(float left, float right, float bottom, float top); 729 | void EndScene2D(); 730 | 731 | void DrawTriangle(Vec2 va, Vec2 vb, Vec2 vc, Vec2 ta, Vec2 tb, Vec2 tc, Vec4 ca, Vec4 cb, Vec4 cc); 732 | void DrawTriangle(Vec2 a, Vec2 b, Vec2 c, Vec2 ta, Vec2 tb, Vec2 tc, Vec4 col); 733 | void DrawTriangle(Vec2 a, Vec2 b, Vec2 c, Vec4 color); 734 | 735 | void DrawQuad(Vec2 a, Vec2 b, Vec2 c, Vec2 d, Vec2 uv_a, Vec2 uv_b, Vec2 uv_c, Vec2 uv_d, Vec4 color); 736 | void DrawQuad(Vec2 a, Vec2 b, Vec2 c, Vec2 d, Vec4 color); 737 | void DrawQuad(Vec2 a, Vec2 b, Vec2 c, Vec2 d, Rect rect, Vec4 color); 738 | 739 | void DrawRect(Vec2 pos, Vec2 dim, Vec2 uv_a, Vec2 uv_b, Vec2 uv_c, Vec2 uv_d, Vec4 color); 740 | void DrawRect(Vec2 pos, Vec2 dim, Vec4 color); 741 | void DrawRect(Vec2 pos, Vec2 dim, Rect rect, Vec4 color); 742 | 743 | void DrawRectRotated(Vec2 pos, Vec2 dim, float angle, Vec2 uv_a, Vec2 uv_b, Vec2 uv_c, Vec2 uv_d, Vec4 color); 744 | void DrawRectRotated(Vec2 pos, Vec2 dim, float angle, Vec4 color); 745 | void DrawRectRotated(Vec2 pos, Vec2 dim, float angle, Rect rect, Vec4 color); 746 | 747 | void DrawRectCentered(Vec2 pos, Vec2 dim, Vec2 uv_a, Vec2 uv_b, Vec2 uv_c, Vec2 uv_d, Vec4 color); 748 | void DrawRectCentered(Vec2 pos, Vec2 dim, Vec4 color); 749 | void DrawRectCentered(Vec2 pos, Vec2 dim, Rect rect, Vec4 color); 750 | 751 | void DrawRectCenteredRotated(Vec2 pos, Vec2 dim, float angle, Vec2 uv_a, Vec2 uv_b, Vec2 uv_c, Vec2 uv_d, Vec4 color); 752 | void DrawRectCenteredRotated(Vec2 pos, Vec2 dim, float angle, Vec4 color); 753 | void DrawRectCenteredRotated(Vec2 pos, Vec2 dim, float angle, Rect rect, Vec4 color); 754 | 755 | void DrawEllipse(Vec2 pos, float radius_a, float radius_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 756 | 757 | void DrawCircle(Vec2 pos, float radius, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 758 | 759 | void DrawPie(Vec2 pos, float radius_a, float radius_b, float theta_a, float theta_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 760 | void DrawPie(Vec2 pos, float radius, float theta_a, float theta_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 761 | 762 | void DrawPiePart(Vec2 pos, float radius_a_min, float radius_b_min, float radius_a_max, float radius_b_max, float theta_a, float theta_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 763 | void DrawPiePart(Vec2 pos, float radius_min, float radius_max, float theta_a, float theta_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 764 | 765 | void DrawLine(Vec2 a, Vec2 b, Vec4 color); 766 | 767 | void DrawBezierQuadratic(Vec2 a, Vec2 b, Vec2 c, Vec4 color, int segments = DEFAULT_BEZIER_SEGMENTS); 768 | void DrawBezierCubic(Vec2 a, Vec2 b, Vec2 c, Vec2 d, Vec4 color, int segments = DEFAULT_BEZIER_SEGMENTS); 769 | 770 | void DrawPolygon(const Vec2 *vertices, uint32_t count, Vec4 color); 771 | 772 | void DrawTriangleOutline(Vec2 a, Vec2 b, Vec2 c, Vec4 color); 773 | 774 | void DrawQuadOutline(Vec2 a, Vec2 b, Vec2 c, Vec2 d, Vec4 color); 775 | 776 | void DrawRectOutline(Vec2 pos, Vec2 dim, Vec4 color); 777 | 778 | void DrawRectCenteredOutline(Vec2 pos, Vec2 dim, Vec4 color); 779 | 780 | void DrawEllipseOutline(Vec2 position, float radius_a, float radius_b, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 781 | 782 | void DrawCircleOutline(Vec2 position, float radius, Vec4 color, int segments = DEFAULT_CIRCLE_SEGMENTS); 783 | 784 | void DrawArcOutline(Vec2 position, float radius_a, float radius_b, float theta_a, float theta_b, Vec4 color, bool closed = true, int segments = DEFAULT_CIRCLE_SEGMENTS); 785 | void DrawArcOutline(Vec2 position, float radius, float theta_a, float theta_b, Vec4 color, bool closed = true, int segments = DEFAULT_CIRCLE_SEGMENTS); 786 | 787 | void DrawPolygonOutline(const Vec2 *vertices, uint32_t count, Vec4 color); 788 | 789 | float GetFontScale(float size = 1); 790 | float CalculateMaxHeight(String text, float size = 1); 791 | float CalculateMaxHeight(String text, float size, Font *font); 792 | float CalculateText(String text, float size, Font *font); 793 | float CalculateText(String text, float size = 1); 794 | void DrawText(String text, Vec2 position, Vec4 color, float size, Font *font); 795 | void DrawText(String text, Vec2 position, Vec4 color, float size = 1); 796 | 797 | uint8_t* LoadPNGFile(struct Platform* p, const char* img_path, unsigned* width, unsigned* height, unsigned* no_of_channels, unsigned* bit_depth); 798 | 799 | // decode png file from the supplied stream 800 | // Size allocated by this and above function will exactly be width * height * no_of_channels * (bit_depth/8) bytes 801 | uint8_t* LoadPNGFromMemory(Platform* p, uint8_t* raw_image_data, uint32_t total_len, uint32_t* width, uint32_t* height, uint32_t* no_of_channels, uint32_t* bit_depth); 802 | 803 | String ReadEntireFile(Platform *p, const char *file); 804 | 805 | uint32_t CreateTexture(uint8_t *pixels, uint32_t width, uint32_t height, uint32_t channels); 806 | uint32_t CreateTextureFromPNG(Platform *platform, uint8_t *png, uint32_t size, uint32_t *w, uint32_t *h, uint32_t *channels); 807 | uint32_t CreateTextureFromFile(Platform *platform, const char *file, uint32_t *w, uint32_t *h, uint32_t *channels); 808 | void DestroyTexture(uint32_t tex); 809 | 810 | // 811 | // 812 | // 813 | 814 | enum Key : uint32_t { 815 | Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G, Key_H, Key_I, Key_J, Key_K, Key_L, Key_M, 816 | Key_N, Key_O, Key_P, Key_Q, Key_R, Key_S, Key_T, Key_U, Key_V, Key_W, Key_X, Key_Y, Key_Z, 817 | Key_0, Key_1, Key_2, Key_3, Key_4, Key_5, Key_6, Key_7, Key_8, Key_9, 818 | Key_Return, Key_Escape, Key_BackSpace, Key_Tab, Key_Space, Key_Shift, Key_Ctrl, 819 | Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11, Key_F12, 820 | Key_PrintScreen, Key_Insert, Key_Home, Key_PageUp, Key_PageDown, Key_Delete, Key_End, 821 | Key_Right, Key_Left, Key_Down, Key_Up, 822 | Key_Divide, Key_Multiply, Key_Minus, Key_Plus, Key_Period, Key_BackTick, 823 | Key_Pad0, Key_Pad1, Key_Pad2, Key_Pad3, Key_Pad4, 824 | Key_Pad5, Key_Pad6, Key_Pad7, Key_Pad8, Key_Pad9, 825 | 826 | _Key_Count 827 | }; 828 | 829 | enum Button { 830 | Button_Left, 831 | Button_Middle, 832 | Button_Right, 833 | 834 | _Button_Count 835 | }; 836 | 837 | struct MouseState { 838 | Vec2 Position; 839 | Vec2 Delta; 840 | Vec2 Scroll; 841 | bool IsDown[_Button_Count]; 842 | bool EndedDown[_Key_Count]; 843 | bool EndedUp[_Key_Count]; 844 | uint32_t Transitions[_Button_Count]; 845 | uint32_t DoubleClick[_Button_Count]; 846 | }; 847 | 848 | struct KeyboardState { 849 | bool IsDown[_Key_Count]; 850 | bool EndedDown[_Key_Count]; 851 | bool EndedUp[_Key_Count]; 852 | uint32_t Repeat[_Key_Count]; 853 | uint32_t Transitions[_Key_Count]; 854 | }; 855 | 856 | struct Timestep { 857 | float FixedDeltaTime; 858 | float Time; 859 | float DeltaTime; 860 | float RealTime; 861 | float RealDeltaTime; 862 | float SimulationSpeedFactor; 863 | }; 864 | 865 | typedef void *(*PlatformAlloc)(size_t size); 866 | typedef void *(*PlatformRealloc)(void *ptr, size_t size); 867 | typedef void (*PlatformFree)(void *ptr); 868 | typedef void (*PlatformOnWindowResize)(struct Platform *, uint32_t w, uint32_t h); 869 | typedef bool (*PlatformOnLoad)(struct Platform *); 870 | typedef void (*PlatformOnQuit)(struct Platform *); 871 | typedef void (*PlatformFixedUpdate)(struct Platform *, float dt); 872 | typedef void (*PlatformUpdateAndRender)(struct Platform *, float dt, float alpha); 873 | typedef void (*PlatformLog)(const char *fmt, ...); 874 | typedef void (*PlatformLogError)(const char *fmt, ...); 875 | typedef void (*PlatformFatalError)(const char *messge); 876 | 877 | struct Platform { 878 | Arena Scratch; 879 | 880 | PlatformAlloc Alloc; 881 | PlatformRealloc Realloc; 882 | PlatformFree Free; 883 | void *UserPointer; 884 | 885 | KeyboardState Keyboard; 886 | MouseState Mouse; 887 | 888 | PlatformLog Log; 889 | PlatformLogError LogError; 890 | PlatformFatalError FatalError; 891 | 892 | float RenderTargetWidth; 893 | float RenderTargetHeight; 894 | float AspectRatio; 895 | 896 | Timestep Time; 897 | PlatformOnLoad OnLoad; 898 | PlatformOnQuit OnQuit; 899 | PlatformFixedUpdate FixedUpdate; 900 | PlatformUpdateAndRender UpdateAndRender; 901 | PlatformOnWindowResize OnWindowResize; 902 | 903 | const char *Name; 904 | bool Running; 905 | }; 906 | 907 | inline void PlatformQuit(Platform *p) { p->Running = false; } 908 | 909 | inline bool KeyIsDown(Platform *p, Key k) { return p->Keyboard.IsDown[k]; } 910 | inline bool KeyIsPressed(Platform *p, Key k) { return p->Keyboard.EndedDown[k]; } 911 | inline bool KeyIsReleased(Platform *p, Key k) { return !p->Keyboard.EndedUp[k]; } 912 | inline bool ButtonIsDown(Platform *p, Button b) { return p->Mouse.IsDown[b]; } 913 | inline bool ButtonIsPressed(Platform *p, Button b) { return p->Mouse.EndedDown[b]; } 914 | inline bool ButtonIsReleased(Platform *p, Button b) { return p->Mouse.EndedUp[b]; } 915 | 916 | #if !defined(CppGameCall) 917 | #define CppGameCall extern "C" 918 | #endif 919 | 920 | CppGameCall void CppGameInitialize(Platform * platform, int argc, char **argv); 921 | --------------------------------------------------------------------------------