Removing named namespace from code base.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
#include <Controller/DebugCameraController.h>
|
#include <Controller/DebugCameraController.h>
|
||||||
|
|
||||||
#include <Controller/ControllerUtils.h>
|
#include <Controller/ControllerUtils.h>
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
@@ -24,10 +24,10 @@ void ActivateDebugController()
|
|||||||
{
|
{
|
||||||
Assert(gIsDebugCameraActive == false);
|
Assert(gIsDebugCameraActive == false);
|
||||||
|
|
||||||
Juliet::Camera* currentCam = Juliet::GetCurrentCamera();
|
Camera* currentCam = GetCurrentCamera();
|
||||||
gPreviousCameraIndex = currentCam->Index;
|
gPreviousCameraIndex = currentCam->Index;
|
||||||
|
|
||||||
Juliet::SetCurrentCamera(kDebugCamera);
|
SetCurrentCamera(kDebugCamera);
|
||||||
|
|
||||||
gIsDebugCameraActive = true;
|
gIsDebugCameraActive = true;
|
||||||
gFirstUpdate = true;
|
gFirstUpdate = true;
|
||||||
@@ -41,7 +41,7 @@ void DeactivateDebugController()
|
|||||||
|
|
||||||
gIsDebugCameraActive = false;
|
gIsDebugCameraActive = false;
|
||||||
|
|
||||||
Juliet::SetCurrentCamera(gPreviousCameraIndex);
|
SetCurrentCamera(gPreviousCameraIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDebugControllerActive()
|
bool IsDebugControllerActive()
|
||||||
@@ -51,26 +51,26 @@ bool IsDebugControllerActive()
|
|||||||
|
|
||||||
void UpdateDebugController(float dt)
|
void UpdateDebugController(float dt)
|
||||||
{
|
{
|
||||||
Juliet::Camera* currentCam = Juliet::GetCurrentCamera();
|
Camera* currentCam = GetCurrentCamera();
|
||||||
|
|
||||||
if (gFirstUpdate)
|
if (gFirstUpdate)
|
||||||
{
|
{
|
||||||
Juliet::Vector3 dir = Juliet::Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position;
|
Vector3 dir = Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position;
|
||||||
dir = Juliet::Normalize(dir);
|
dir = Normalize(dir);
|
||||||
gPitch = asinf(dir.z);
|
gPitch = asinf(dir.z);
|
||||||
gYaw = atan2f(dir.y, dir.x);
|
gYaw = atan2f(dir.y, dir.x);
|
||||||
gFirstUpdate = false;
|
gFirstUpdate = false;
|
||||||
|
|
||||||
Juliet::Vector3 forward;
|
Vector3 forward;
|
||||||
forward.x = cosf(gPitch) * cosf(gYaw);
|
forward.x = cosf(gPitch) * cosf(gYaw);
|
||||||
forward.y = cosf(gPitch) * sinf(gYaw);
|
forward.y = cosf(gPitch) * sinf(gYaw);
|
||||||
forward.z = sinf(gPitch);
|
forward.z = sinf(gPitch);
|
||||||
Juliet::Vector3 right = Juliet::Normalize(Juliet::Cross(Juliet::Vector3{ 0.0f, 0.0f, 1.0f }, forward));
|
Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
|
||||||
currentCam->Target = currentCam->Position + forward;
|
currentCam->Target = currentCam->Position + forward;
|
||||||
currentCam->Up = Juliet::Cross(forward, right);
|
currentCam->Up = Cross(forward, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRightMouseButtonDown = Juliet::IsMouseButtonDown(Juliet::MouseButton::Right);
|
bool isRightMouseButtonDown = IsMouseButtonDown(MouseButton::Right);
|
||||||
if (isRightMouseButtonDown && !gWasRightMouseButtonDown)
|
if (isRightMouseButtonDown && !gWasRightMouseButtonDown)
|
||||||
{
|
{
|
||||||
gIsFpsModeActive = !gIsFpsModeActive;
|
gIsFpsModeActive = !gIsFpsModeActive;
|
||||||
@@ -82,7 +82,7 @@ void UpdateDebugController(float dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Juliet::MousePosition mouseDelta = Juliet::GetMouseDelta();
|
MousePosition mouseDelta = GetMouseDelta();
|
||||||
|
|
||||||
float sensitivity = 0.005f;
|
float sensitivity = 0.005f;
|
||||||
gYaw += mouseDelta.X * sensitivity;
|
gYaw += mouseDelta.X * sensitivity;
|
||||||
@@ -91,52 +91,52 @@ void UpdateDebugController(float dt)
|
|||||||
gPitch = std::min(gPitch, 1.5f);
|
gPitch = std::min(gPitch, 1.5f);
|
||||||
gPitch = std::max(gPitch, -1.5f);
|
gPitch = std::max(gPitch, -1.5f);
|
||||||
|
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::Q))
|
if (IsKeyDown(ScanCode::Q))
|
||||||
{
|
{
|
||||||
gYaw -= 2.0f * dt;
|
gYaw -= 2.0f * dt;
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::E))
|
if (IsKeyDown(ScanCode::E))
|
||||||
{
|
{
|
||||||
gYaw += 2.0f * dt;
|
gYaw += 2.0f * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Juliet::Vector3 forward;
|
Vector3 forward;
|
||||||
forward.x = cosf(gPitch) * cosf(gYaw);
|
forward.x = cosf(gPitch) * cosf(gYaw);
|
||||||
forward.y = cosf(gPitch) * sinf(gYaw);
|
forward.y = cosf(gPitch) * sinf(gYaw);
|
||||||
forward.z = sinf(gPitch);
|
forward.z = sinf(gPitch);
|
||||||
|
|
||||||
Juliet::Vector3 right = Juliet::Normalize(Juliet::Cross(Juliet::Vector3{ 0.0f, 0.0f, 1.0f }, forward));
|
Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
|
||||||
Juliet::Vector3 defaultUp = Juliet::Cross(forward, right);
|
Vector3 defaultUp = Cross(forward, right);
|
||||||
|
|
||||||
static const float kMovementPerFrame = 10.f; // 10m/s
|
static const float kMovementPerFrame = 10.f; // 10m/s
|
||||||
|
|
||||||
float speedPerFrame = kMovementPerFrame;
|
float speedPerFrame = kMovementPerFrame;
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::LeftShift))
|
if (IsKeyDown(ScanCode::LeftShift))
|
||||||
{
|
{
|
||||||
speedPerFrame *= 10.f; // 100m/s
|
speedPerFrame *= 10.f; // 100m/s
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::W))
|
if (IsKeyDown(ScanCode::W))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::S))
|
if (IsKeyDown(ScanCode::S))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::D))
|
if (IsKeyDown(ScanCode::D))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position + right * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position + right * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::A))
|
if (IsKeyDown(ScanCode::A))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position - right * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position - right * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::Space))
|
if (IsKeyDown(ScanCode::Space))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
if (Juliet::IsKeyDown(Juliet::ScanCode::LeftControl))
|
if (IsKeyDown(ScanCode::LeftControl))
|
||||||
{
|
{
|
||||||
currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt);
|
currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt);
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ void UpdateDebugController(float dt)
|
|||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
void RenderImGuiDebugController(float dt)
|
void RenderImGuiDebugController(float dt)
|
||||||
{
|
{
|
||||||
Juliet::Camera* currentCam = Juliet::GetCurrentCamera();
|
Camera* currentCam = GetCurrentCamera();
|
||||||
|
|
||||||
ImGui::Text("Delta time: %f", dt);
|
ImGui::Text("Delta time: %f", dt);
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
#include <Debug/DebugTopBar.h>
|
#include <Debug/DebugTopBar.h>
|
||||||
|
|
||||||
#include <game.h>
|
#include <game.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
Juliet::String GetGameModeName(GameMode gameMode)
|
String GetGameModeName(GameMode gameMode)
|
||||||
{
|
{
|
||||||
using namespace Juliet;
|
|
||||||
switch (gameMode)
|
switch (gameMode)
|
||||||
{
|
{
|
||||||
case GameMode::Editor: return WrapString("Editor");
|
case GameMode::Editor: return WrapString("Editor");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
@@ -8,19 +8,19 @@
|
|||||||
|
|
||||||
#define DECLARE_ENTITY() \
|
#define DECLARE_ENTITY() \
|
||||||
Entity* Base; \
|
Entity* Base; \
|
||||||
static const Juliet::Class* Kind;
|
static const Class* Kind;
|
||||||
|
|
||||||
// Will register the class globally at launch
|
// Will register the class globally at launch
|
||||||
#define DEFINE_ENTITY(entity) \
|
#define DEFINE_ENTITY(entity) \
|
||||||
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
|
constexpr Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
|
||||||
const Juliet::Class* entity::Kind = &entityKind##entity;
|
const Class* entity::Kind = &entityKind##entity;
|
||||||
|
|
||||||
using DerivedType = void*;
|
using DerivedType = void*;
|
||||||
|
|
||||||
struct Entity final
|
struct Entity final
|
||||||
{
|
{
|
||||||
EntityID ID;
|
EntityID ID;
|
||||||
const Juliet::Class* Kind;
|
const Class* Kind;
|
||||||
DerivedType Derived;
|
DerivedType Derived;
|
||||||
float X, Y;
|
float X, Y;
|
||||||
index_t MeshInstance = indexMax;
|
index_t MeshInstance = indexMax;
|
||||||
@@ -28,7 +28,7 @@ struct Entity final
|
|||||||
|
|
||||||
template <typename EntityType>
|
template <typename EntityType>
|
||||||
concept EntityConcept = requires(EntityType entity) {
|
concept EntityConcept = requires(EntityType entity) {
|
||||||
requires std::same_as<decltype(entity.Kind), const Juliet::Class*>;
|
requires std::same_as<decltype(entity.Kind), const Class*>;
|
||||||
requires std::same_as<decltype(entity.Base), Entity*>;
|
requires std::same_as<decltype(entity.Base), Entity*>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ template <typename EntityType>
|
|||||||
EntityType* MakeEntity(EntityManager& manager, float x, float y)
|
EntityType* MakeEntity(EntityManager& manager, float x, float y)
|
||||||
{
|
{
|
||||||
auto* arena = manager.Arena;
|
auto* arena = manager.Arena;
|
||||||
EntityType* result = Juliet::ArenaPushStruct<EntityType>(arena);
|
EntityType* result = ArenaPushStruct<EntityType>(arena);
|
||||||
Entity base;
|
Entity base;
|
||||||
base.X = x;
|
base.X = x;
|
||||||
base.Y = y;
|
base.Y = y;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
#include <Entity/EntityManager.h>
|
#include <Entity/EntityManager.h>
|
||||||
|
|
||||||
#include <Entity/Entity.h>
|
#include <Entity/Entity.h>
|
||||||
#include <Graphics/MeshRenderer.h>
|
#include <Graphics/MeshRenderer.h>
|
||||||
|
|
||||||
EntityID EntityManager::ID = 0;
|
EntityID EntityManager::ID = 0;
|
||||||
|
|
||||||
void InitEntityManager(Juliet::NonNullPtr<World> world)
|
void InitEntityManager(NonNullPtr<World> world)
|
||||||
{
|
{
|
||||||
EntityManager* newManager = Juliet::ArenaPushStruct<EntityManager>(world->WorldArena);
|
EntityManager* newManager = ArenaPushStruct<EntityManager>(world->WorldArena);
|
||||||
world->EntityManager = newManager;
|
world->EntityManager = newManager;
|
||||||
|
|
||||||
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
|
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
|
||||||
|
|
||||||
newManager->Arena = Juliet::ArenaAllocate({ .Name = "Entity Arena" });
|
newManager->Arena = ArenaAllocate({ .Name = "Entity Arena" });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownEntityManager()
|
void ShutdownEntityManager()
|
||||||
@@ -22,7 +22,7 @@ void ShutdownEntityManager()
|
|||||||
|
|
||||||
EntityManager& GetEntityManager()
|
EntityManager& GetEntityManager()
|
||||||
{
|
{
|
||||||
Juliet::NonNullPtr entityManager = GetGameState()->World->EntityManager;
|
NonNullPtr entityManager = GetGameState()->World->EntityManager;
|
||||||
return *entityManager;
|
return *entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ void UpdateEntityManager(EntityManager& manager)
|
|||||||
{
|
{
|
||||||
if (ent.MeshInstance != indexMax)
|
if (ent.MeshInstance != indexMax)
|
||||||
{
|
{
|
||||||
Juliet::SetMeshInstanceTransform(ent.MeshInstance, Juliet::MatrixTranslation(ent.X, ent.Y, 0.0f));
|
SetMeshInstanceTransform(ent.MeshInstance, MatrixTranslation(ent.X, ent.Y, 0.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Container/Vector.h>
|
#include <Core/Container/Vector.h>
|
||||||
@@ -11,13 +11,13 @@ struct EntityManager
|
|||||||
{
|
{
|
||||||
static EntityID ID;
|
static EntityID ID;
|
||||||
|
|
||||||
Juliet::Arena* Arena;
|
Arena* Arena;
|
||||||
|
|
||||||
// TODO: Should be a pool
|
// TODO: Should be a pool
|
||||||
Juliet::VectorArena<Entity, 1024> Entities;
|
VectorArena<Entity, 1024> Entities;
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitEntityManager(Juliet::NonNullPtr<World> world);
|
void InitEntityManager(NonNullPtr<World> world);
|
||||||
void ShutdownEntityManager();
|
void ShutdownEntityManager();
|
||||||
EntityManager& GetEntityManager();
|
EntityManager& GetEntityManager();
|
||||||
void RegisterEntity(EntityManager& manager, Entity* entity);
|
void RegisterEntity(EntityManager& manager, Entity* entity);
|
||||||
|
|||||||
+2
-4
@@ -1,4 +1,4 @@
|
|||||||
#include <game.h>
|
#include <game.h>
|
||||||
|
|
||||||
#include <Controller/DebugCameraController.h>
|
#include <Controller/DebugCameraController.h>
|
||||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||||
@@ -31,14 +31,12 @@ extern "C" JULIET_API void __cdecl GameShutdown()
|
|||||||
{
|
{
|
||||||
printf("Shutting down game...\n");
|
printf("Shutting down game...\n");
|
||||||
|
|
||||||
using namespace Juliet;
|
|
||||||
|
|
||||||
ShutdownEntityManager();
|
ShutdownEntityManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_unused]] float deltaTime)
|
extern "C" JULIET_API void __cdecl GameUpdate(GameData* params, [[maybe_unused]] float deltaTime)
|
||||||
{
|
{
|
||||||
using namespace Juliet;
|
|
||||||
|
|
||||||
gGameState = params->GameState;
|
gGameState = params->GameState;
|
||||||
if (!gGameState)
|
if (!gGameState)
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Memory/MemoryArena.h>
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ struct EntityManager;
|
|||||||
|
|
||||||
struct World
|
struct World
|
||||||
{
|
{
|
||||||
Juliet::Arena* WorldArena;
|
Arena* WorldArena;
|
||||||
EntityManager* EntityManager;
|
EntityManager* EntityManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ enum class GameMode
|
|||||||
|
|
||||||
struct GameState
|
struct GameState
|
||||||
{
|
{
|
||||||
Juliet::Arena* TotalArena;
|
Arena* TotalArena;
|
||||||
|
|
||||||
World* World;
|
World* World;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Application/IApplication.h>
|
#include <Core/Application/IApplication.h>
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
enum class JulietInit_Flags : uint8;
|
||||||
{
|
|
||||||
enum class JulietInit_Flags : uint8;
|
|
||||||
|
|
||||||
struct Arena;
|
struct Arena;
|
||||||
extern JULIET_API void StartApplication(IApplication& app, JulietInit_Flags flags);
|
extern JULIET_API void StartApplication(IApplication& app, JulietInit_Flags flags);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Camera;
|
||||||
|
struct RenderPass;
|
||||||
|
struct CommandList;
|
||||||
|
struct Texture;
|
||||||
|
struct ColorTargetInfo;
|
||||||
|
struct DepthStencilTargetInfo;
|
||||||
|
struct Arena;
|
||||||
|
|
||||||
|
class IApplication
|
||||||
{
|
{
|
||||||
struct Camera;
|
public:
|
||||||
struct RenderPass;
|
virtual ~IApplication() = default;
|
||||||
struct CommandList;
|
virtual void Init(NonNullPtr<Arena> arena) = 0;
|
||||||
struct Texture;
|
virtual void Shutdown() = 0;
|
||||||
struct ColorTargetInfo;
|
virtual void Update(float deltaTime) = 0;
|
||||||
struct DepthStencilTargetInfo;
|
virtual bool IsRunning() = 0;
|
||||||
struct Arena;
|
|
||||||
|
|
||||||
class IApplication
|
// Accessors for Engine Systems
|
||||||
{
|
virtual struct Window* GetPlatformWindow() = 0;
|
||||||
public:
|
virtual struct GraphicsDevice* GetGraphicsDevice() = 0;
|
||||||
virtual ~IApplication() = default;
|
|
||||||
virtual void Init(NonNullPtr<Arena> arena) = 0;
|
|
||||||
virtual void Shutdown() = 0;
|
|
||||||
virtual void Update(float deltaTime) = 0;
|
|
||||||
virtual bool IsRunning() = 0;
|
|
||||||
|
|
||||||
// Accessors for Engine Systems
|
// Render Lifecycle (Engine-Managed Render Loop)
|
||||||
virtual struct Window* GetPlatformWindow() = 0;
|
virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
|
||||||
virtual struct GraphicsDevice* GetGraphicsDevice() = 0;
|
virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
|
||||||
|
};
|
||||||
// Render Lifecycle (Engine-Managed Render Loop)
|
|
||||||
virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
|
|
||||||
virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
|
|
||||||
};
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,58 +1,55 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
|
// From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
|
||||||
|
|
||||||
namespace Juliet
|
namespace details
|
||||||
{
|
{
|
||||||
namespace details
|
constexpr uint32_t crc32_tab[] = {
|
||||||
{
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
|
||||||
constexpr uint32_t crc32_tab[] = {
|
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
|
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
|
||||||
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
||||||
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
|
||||||
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
|
||||||
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
|
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
|
||||||
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
|
||||||
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
|
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
||||||
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
|
||||||
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
|
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
|
||||||
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
|
||||||
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
|
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
|
||||||
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
||||||
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
|
||||||
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
};
|
||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
consteval uint32 crc32(const char* str, size_t length)
|
consteval uint32 crc32(const char* str, size_t length)
|
||||||
|
{
|
||||||
|
const char* p = str;
|
||||||
|
uint32_t crc = ~0U;
|
||||||
|
while (length--)
|
||||||
{
|
{
|
||||||
const char* p = str;
|
crc = details::crc32_tab[(crc ^ static_cast<uint8>(*p++)) & 0xFF] ^ (crc >> 8);
|
||||||
uint32_t crc = ~0U;
|
|
||||||
while (length--)
|
|
||||||
{
|
|
||||||
crc = details::crc32_tab[(crc ^ static_cast<uint8>(*p++)) & 0xFF] ^ (crc >> 8);
|
|
||||||
}
|
|
||||||
return crc ^ ~0U;
|
|
||||||
}
|
}
|
||||||
|
return crc ^ ~0U;
|
||||||
|
}
|
||||||
|
|
||||||
consteval uint32 operator""_crc32(const char* str, size_t length)
|
consteval uint32 operator""_crc32(const char* str, size_t length)
|
||||||
{
|
{
|
||||||
return crc32(str, length);
|
return crc32(str, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
|
||||||
{
|
|
||||||
|
|
||||||
#define global static
|
#define global static
|
||||||
|
|
||||||
// 1. Stringify helpers
|
// 1. Stringify helpers
|
||||||
#define JULIET_STR(x) #x
|
#define JULIET_STR(x) #x
|
||||||
#define JULIET_TOSTRING(x) JULIET_STR(x)
|
#define JULIET_TOSTRING(x) JULIET_STR(x)
|
||||||
|
|
||||||
// 2. Define the pragma operator based on compiler
|
// 2. Define the pragma operator based on compiler
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#define JULIET_PRAGMA(x) _Pragma(#x)
|
#define JULIET_PRAGMA(x) _Pragma(#x)
|
||||||
#define JULIET_SUPPRESS_MSVC(id)
|
#define JULIET_SUPPRESS_MSVC(id)
|
||||||
@@ -27,7 +25,7 @@ namespace Juliet
|
|||||||
#define JULIET_SUPPRESS_CLANG(str)
|
#define JULIET_SUPPRESS_CLANG(str)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 3. The Agnostic "Push/Pop"
|
// 3. The Agnostic "Push/Pop"
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push)
|
#define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push)
|
||||||
#define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop)
|
#define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop)
|
||||||
@@ -40,10 +38,10 @@ namespace Juliet
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
// MSVC specific intrinsic
|
// MSVC specific intrinsic
|
||||||
#define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak())
|
#define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak())
|
||||||
#elif defined(__clang__) || defined(__GNUC__)
|
#elif defined(__clang__) || defined(__GNUC__)
|
||||||
// Clang/GCC specific intrinsic
|
// Clang/GCC specific intrinsic
|
||||||
#define JULIET_PLATFORM_BREAK() __builtin_trap()
|
#define JULIET_PLATFORM_BREAK() __builtin_trap()
|
||||||
#else
|
#else
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -52,40 +50,40 @@ namespace Juliet
|
|||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
#define JULIET_ASSERT_INTERNAL(expression, message) \
|
#define JULIET_ASSERT_INTERNAL(expression, message) \
|
||||||
JULIET_WARNING_PUSH \
|
JULIET_WARNING_PUSH \
|
||||||
JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \
|
JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \
|
||||||
JULIET_SUPPRESS_MSVC(4127) \
|
JULIET_SUPPRESS_MSVC(4127) \
|
||||||
JULIET_SUPPRESS_MSVC(4548) \
|
JULIET_SUPPRESS_MSVC(4548) \
|
||||||
{ \
|
{ \
|
||||||
if (!(expression)) [[unlikely]] \
|
if (!(expression)) [[unlikely]] \
|
||||||
{ \
|
{ \
|
||||||
Juliet::JulietAssert(#expression, message); \
|
JulietAssert(#expression, message); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
JULIET_WARNING_POP \
|
JULIET_WARNING_POP \
|
||||||
static_assert(true, "")
|
static_assert(true, "")
|
||||||
|
|
||||||
#define AssertHR(hr_expression, message) \
|
#define AssertHR(hr_expression, message) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
long hr_val = (hr_expression); \
|
long hr_val = (hr_expression); \
|
||||||
if (hr_val < 0) \
|
if (hr_val < 0) \
|
||||||
{ \
|
{ \
|
||||||
Juliet::JulietAssert(#hr_expression, message, std::source_location::current(), hr_val); \
|
JulietAssert(#hr_expression, message, std::source_location::current(), hr_val); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define GET_ASSERT_MACRO(_1, _2, NAME, ...) NAME
|
#define GET_ASSERT_MACRO(_1, _2, NAME, ...) NAME
|
||||||
#define Assert(...) GET_ASSERT_MACRO(__VA_ARGS__, JULIET_ASSERT_INTERNAL, JULIET_ASSERT_NO_MSG)(__VA_ARGS__)
|
#define Assert(...) GET_ASSERT_MACRO(__VA_ARGS__, JULIET_ASSERT_INTERNAL, JULIET_ASSERT_NO_MSG)(__VA_ARGS__)
|
||||||
#define JULIET_ASSERT_NO_MSG(expression) JULIET_ASSERT_INTERNAL(expression, "No additional information provided.")
|
#define JULIET_ASSERT_NO_MSG(expression) JULIET_ASSERT_INTERNAL(expression, "No additional information provided.")
|
||||||
|
|
||||||
#define Unimplemented() \
|
#define Unimplemented() \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
Juliet::JulietAssert("UNIMPLEMENTED", "This code path is not yet functional."); \
|
JulietAssert("UNIMPLEMENTED", "This code path is not yet functional."); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define Assert(...) ((void)0)
|
#define Assert(...) ((void)0)
|
||||||
@@ -93,85 +91,85 @@ namespace Juliet
|
|||||||
#define Unimplemented() ((void)0)
|
#define Unimplemented() ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JULIET_API extern void JulietAssert(const char* expression, const char* message,
|
JULIET_API extern void JulietAssert(const char* expression, const char* message,
|
||||||
std::source_location location = std::source_location::current(), long handleResult = 0);
|
std::source_location location = std::source_location::current(), long handleResult = 0);
|
||||||
|
|
||||||
#define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance))
|
#define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance))
|
||||||
#define ZeroArray(array) ZeroSize(sizeof((array)), (array))
|
#define ZeroArray(array) ZeroSize(sizeof((array)), (array))
|
||||||
#define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer)
|
#define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer)
|
||||||
inline void ZeroSize(size_t size, void* ptr)
|
inline void ZeroSize(size_t size, void* ptr)
|
||||||
|
{
|
||||||
|
auto Byte = (uint8*)ptr;
|
||||||
|
while (size--)
|
||||||
{
|
{
|
||||||
auto Byte = (uint8*)ptr;
|
*Byte++ = 0;
|
||||||
while (size--)
|
|
||||||
{
|
|
||||||
*Byte++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define Restrict __restrict
|
#define Restrict __restrict
|
||||||
|
|
||||||
template <class Function>
|
template <class Function>
|
||||||
class DeferredFunction
|
class DeferredFunction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit DeferredFunction(const Function& otherFct) noexcept
|
||||||
|
: Callback(otherFct)
|
||||||
{
|
{
|
||||||
public:
|
}
|
||||||
explicit DeferredFunction(const Function& otherFct) noexcept
|
explicit DeferredFunction(Function&& otherFct) noexcept
|
||||||
: Callback(otherFct)
|
: Callback(std::move(otherFct))
|
||||||
{
|
|
||||||
}
|
|
||||||
explicit DeferredFunction(Function&& otherFct) noexcept
|
|
||||||
: Callback(std::move(otherFct))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~DeferredFunction() noexcept { Callback(); }
|
|
||||||
|
|
||||||
DeferredFunction(const DeferredFunction&) = delete;
|
|
||||||
DeferredFunction(const DeferredFunction&&) = delete;
|
|
||||||
void operator=(const DeferredFunction&) = delete;
|
|
||||||
void operator=(DeferredFunction&&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Function Callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Function>
|
|
||||||
auto Defer(Function&& fct) noexcept
|
|
||||||
{
|
{
|
||||||
return DeferredFunction<std::decay_t<Function>>{ std::forward<Function>(fct) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsValid(ByteBuffer buffer)
|
~DeferredFunction() noexcept { Callback(); }
|
||||||
{
|
|
||||||
return buffer.Size > 0 && buffer.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern JULIET_API void Free(ByteBuffer& buffer);
|
DeferredFunction(const DeferredFunction&) = delete;
|
||||||
|
DeferredFunction(const DeferredFunction&&) = delete;
|
||||||
|
void operator=(const DeferredFunction&) = delete;
|
||||||
|
void operator=(DeferredFunction&&) = delete;
|
||||||
|
|
||||||
template <std::integral T>
|
private:
|
||||||
[[nodiscard]] constexpr T AlignPow2(T x, T alignment)
|
Function Callback;
|
||||||
{
|
};
|
||||||
// Safety Check:
|
|
||||||
Assert(std::has_single_bit(static_cast<size_t>(alignment)));
|
|
||||||
|
|
||||||
return (x + alignment - 1) & ~(alignment - 1);
|
template <class Function>
|
||||||
}
|
auto Defer(Function&& fct) noexcept
|
||||||
|
{
|
||||||
|
return DeferredFunction<std::decay_t<Function>>{ std::forward<Function>(fct) };
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
inline bool IsValid(ByteBuffer buffer)
|
||||||
inline void Swap(T* Restrict a, T* Restrict b)
|
{
|
||||||
{
|
return buffer.Size > 0 && buffer.Data;
|
||||||
T temp = std::move(*a);
|
}
|
||||||
*a = std::move(*b);
|
|
||||||
*b = std::move(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to another file dedicated to those
|
extern JULIET_API void Free(ByteBuffer& buffer);
|
||||||
|
|
||||||
|
template <std::integral T>
|
||||||
|
[[nodiscard]] constexpr T AlignPow2(T x, T alignment)
|
||||||
|
{
|
||||||
|
// Safety Check:
|
||||||
|
Assert(std::has_single_bit(static_cast<size_t>(alignment)));
|
||||||
|
|
||||||
|
return (x + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void Swap(T* Restrict a, T* Restrict b)
|
||||||
|
{
|
||||||
|
T temp = std::move(*a);
|
||||||
|
*a = std::move(*b);
|
||||||
|
*b = std::move(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to another file dedicated to those
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#define COMPILER_CLANG 1
|
#define COMPILER_CLANG 1
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define COMPILER_MSVC 1
|
#define COMPILER_MSVC 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Undef anything not defined
|
// Undef anything not defined
|
||||||
#if !defined(COMPILER_CLANG)
|
#if !defined(COMPILER_CLANG)
|
||||||
#define COMPILER_CLANG 0
|
#define COMPILER_CLANG 0
|
||||||
#endif
|
#endif
|
||||||
@@ -189,43 +187,42 @@ namespace Juliet
|
|||||||
#error AlignOf not defined for this compiler.
|
#error AlignOf not defined for this compiler.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] constexpr const char* GetTypeName()
|
[[nodiscard]] constexpr const char* GetTypeName()
|
||||||
{
|
{
|
||||||
#if COMPILER_CLANG
|
#if COMPILER_CLANG
|
||||||
return __PRETTY_FUNCTION__;
|
return __PRETTY_FUNCTION__;
|
||||||
#elif COMPILER_MSVC
|
#elif COMPILER_MSVC
|
||||||
return __FUNCSIG__;
|
return __FUNCSIG__;
|
||||||
#elif COMPILER_GCC
|
#elif COMPILER_GCC
|
||||||
return __PRETTY_FUNCTION__;
|
return __PRETTY_FUNCTION__;
|
||||||
#else
|
#else
|
||||||
return "UnknownType";
|
return "UnknownType";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16 safe_cast_uint16(uint32 value)
|
inline uint16 safe_cast_uint16(uint32 value)
|
||||||
{
|
{
|
||||||
Assert(value <= uint16Max);
|
Assert(value <= uint16Max);
|
||||||
uint16 result = (uint16)value;
|
uint16 result = (uint16)value;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32 bitmask1 = 0b0000'0001;
|
const uint32 bitmask1 = 0b0000'0001;
|
||||||
const uint32 bitmask2 = 0b0000'0011;
|
const uint32 bitmask2 = 0b0000'0011;
|
||||||
const uint32 bitmask3 = 0b0000'0111;
|
const uint32 bitmask3 = 0b0000'0111;
|
||||||
const uint32 bitmask4 = 0b0000'1111;
|
const uint32 bitmask4 = 0b0000'1111;
|
||||||
const uint32 bitmask5 = 0b0001'1111;
|
const uint32 bitmask5 = 0b0001'1111;
|
||||||
const uint32 bitmask6 = 0b0011'1111;
|
const uint32 bitmask6 = 0b0011'1111;
|
||||||
const uint32 bitmask7 = 0b0111'1111;
|
const uint32 bitmask7 = 0b0111'1111;
|
||||||
const uint32 bitmask8 = 0b1111'1111;
|
const uint32 bitmask8 = 0b1111'1111;
|
||||||
const uint32 bitmask9 = 0x0000'01ff;
|
const uint32 bitmask9 = 0x0000'01ff;
|
||||||
const uint32 bitmask10 = 0x0000'03ff;
|
const uint32 bitmask10 = 0x0000'03ff;
|
||||||
const uint32 bitmask11 = 0x0000'07ff;
|
const uint32 bitmask11 = 0x0000'07ff;
|
||||||
const uint32 bitmask12 = 0x0000'0fff;
|
const uint32 bitmask12 = 0x0000'0fff;
|
||||||
const uint32 bitmask13 = 0x0000'1fff;
|
const uint32 bitmask13 = 0x0000'1fff;
|
||||||
const uint32 bitmask14 = 0x0000'3fff;
|
const uint32 bitmask14 = 0x0000'3fff;
|
||||||
const uint32 bitmask15 = 0x0000'7fff;
|
const uint32 bitmask15 = 0x0000'7fff;
|
||||||
const uint32 bitmask16 = 0x0000'ffff;
|
const uint32 bitmask16 = 0x0000'ffff;
|
||||||
// ...
|
// ...
|
||||||
const uint32 bitmask32 = 0xffff'ffff;
|
const uint32 bitmask32 = 0xffff'ffff;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,89 +1,86 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
template <typename T>
|
||||||
|
concept IsEnum = std::is_enum_v<T>;
|
||||||
|
|
||||||
|
template <IsEnum E>
|
||||||
|
constexpr E operator~(E lhs) noexcept
|
||||||
{
|
{
|
||||||
template <typename T>
|
return static_cast<E>(~static_cast<std::underlying_type_t<E>>(lhs));
|
||||||
concept IsEnum = std::is_enum_v<T>;
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator~(E lhs) noexcept
|
constexpr E operator|(E lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<E>(~static_cast<std::underlying_type_t<E>>(lhs));
|
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) | static_cast<std::underlying_type_t<E>>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator|(E lhs, E rhs) noexcept
|
constexpr E& operator|=(E& lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) | static_cast<std::underlying_type_t<E>>(rhs));
|
return lhs = (lhs | rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E& operator|=(E& lhs, E rhs) noexcept
|
constexpr E operator&(E lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs = (lhs | rhs);
|
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) & static_cast<std::underlying_type_t<E>>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator&(E lhs, E rhs) noexcept
|
constexpr E& operator&=(E& lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) & static_cast<std::underlying_type_t<E>>(rhs));
|
return lhs = (lhs & rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E& operator&=(E& lhs, E rhs) noexcept
|
constexpr E operator^(E lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs = (lhs & rhs);
|
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) ^ static_cast<std::underlying_type_t<E>>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator^(E lhs, E rhs) noexcept
|
constexpr E& operator^=(E& lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) ^ static_cast<std::underlying_type_t<E>>(rhs));
|
return lhs = (lhs ^ rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E& operator^=(E& lhs, E rhs) noexcept
|
constexpr std::underlying_type_t<E> operator-(E lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs = (lhs ^ rhs);
|
using T = std::underlying_type_t<E>;
|
||||||
}
|
return static_cast<T>(static_cast<T>(lhs) - static_cast<T>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr std::underlying_type_t<E> operator-(E lhs, E rhs) noexcept
|
constexpr std::underlying_type_t<E> operator+(E lhs, E rhs) noexcept
|
||||||
{
|
{
|
||||||
using T = std::underlying_type_t<E>;
|
using T = std::underlying_type_t<E>;
|
||||||
return static_cast<T>(static_cast<T>(lhs) - static_cast<T>(rhs));
|
return static_cast<T>(static_cast<T>(lhs) + static_cast<T>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr std::underlying_type_t<E> operator+(E lhs, E rhs) noexcept
|
constexpr E operator-(E lhs, std::underlying_type_t<E> rhs) noexcept
|
||||||
{
|
{
|
||||||
using T = std::underlying_type_t<E>;
|
using T = std::underlying_type_t<E>;
|
||||||
return static_cast<T>(static_cast<T>(lhs) + static_cast<T>(rhs));
|
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) - rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator-(E lhs, std::underlying_type_t<E> rhs) noexcept
|
constexpr E operator+(E lhs, std::underlying_type_t<E> rhs) noexcept
|
||||||
{
|
{
|
||||||
using T = std::underlying_type_t<E>;
|
using T = std::underlying_type_t<E>;
|
||||||
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) - rhs));
|
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) + rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr E operator+(E lhs, std::underlying_type_t<E> rhs) noexcept
|
constexpr std::underlying_type_t<E> ToUnderlying(E enm) noexcept
|
||||||
{
|
{
|
||||||
using T = std::underlying_type_t<E>;
|
return static_cast<std::underlying_type_t<E>>(enm);
|
||||||
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) + rhs));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <IsEnum E>
|
template <IsEnum E>
|
||||||
constexpr std::underlying_type_t<E> ToUnderlying(E enm) noexcept
|
constexpr E ToEnum(std::underlying_type_t<E> value) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<std::underlying_type_t<E>>(enm);
|
return static_cast<E>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <IsEnum E>
|
|
||||||
constexpr E ToEnum(std::underlying_type_t<E> value) noexcept
|
|
||||||
{
|
|
||||||
return static_cast<E>(value);
|
|
||||||
}
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,113 +1,110 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
|
|
||||||
namespace Juliet
|
template <typename Type, typename OtherType>
|
||||||
|
concept NonNullPtr_Convertible = std::is_convertible_v<OtherType*, Type*>;
|
||||||
|
|
||||||
|
template <typename Type, typename OtherType>
|
||||||
|
concept NonNullPtr_SameType = std::is_same_v<OtherType*, Type*>;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class NonNullPtr
|
||||||
{
|
{
|
||||||
template <typename Type, typename OtherType>
|
public:
|
||||||
concept NonNullPtr_Convertible = std::is_convertible_v<OtherType*, Type*>;
|
constexpr NonNullPtr(Type* ptr)
|
||||||
|
: InternalPtr(ptr)
|
||||||
template <typename Type, typename OtherType>
|
|
||||||
concept NonNullPtr_SameType = std::is_same_v<OtherType*, Type*>;
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
class NonNullPtr
|
|
||||||
{
|
{
|
||||||
public:
|
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
|
||||||
constexpr NonNullPtr(Type* ptr)
|
}
|
||||||
: InternalPtr(ptr)
|
|
||||||
{
|
|
||||||
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherType>
|
template <typename OtherType>
|
||||||
requires NonNullPtr_Convertible<OtherType*, Type*>
|
requires NonNullPtr_Convertible<OtherType*, Type*>
|
||||||
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
|
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
|
||||||
: InternalPtr(otherPtr.Get())
|
: InternalPtr(otherPtr.Get())
|
||||||
{
|
{
|
||||||
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
|
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
|
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
|
||||||
{
|
{
|
||||||
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
|
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
|
||||||
InternalPtr = ptr;
|
InternalPtr = ptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OtherType>
|
template <typename OtherType>
|
||||||
requires NonNullPtr_Convertible<OtherType*, Type*>
|
requires NonNullPtr_Convertible<OtherType*, Type*>
|
||||||
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
|
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
|
||||||
{
|
{
|
||||||
InternalPtr = otherPtr.Get();
|
InternalPtr = otherPtr.Get();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
[[nodiscard]] constexpr operator Type*() const
|
[[nodiscard]] constexpr operator Type*() const
|
||||||
{
|
{
|
||||||
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
||||||
return InternalPtr;
|
return InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Type* Get() const
|
[[nodiscard]] constexpr Type* Get() const
|
||||||
{
|
{
|
||||||
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
||||||
return InternalPtr;
|
return InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Type& operator*() const
|
[[nodiscard]] constexpr Type& operator*() const
|
||||||
{
|
{
|
||||||
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
||||||
return *InternalPtr;
|
return *InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Type* operator->() const
|
[[nodiscard]] constexpr Type* operator->() const
|
||||||
{
|
{
|
||||||
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
||||||
return InternalPtr;
|
return InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
|
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
|
||||||
{
|
{
|
||||||
return InternalPtr == otherPtr.InternalPtr;
|
return InternalPtr == otherPtr.InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OtherType>
|
template <typename OtherType>
|
||||||
requires NonNullPtr_SameType<Type, OtherType>
|
requires NonNullPtr_SameType<Type, OtherType>
|
||||||
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
|
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
|
||||||
{
|
{
|
||||||
return InternalPtr == otherRawPtr;
|
return InternalPtr == otherRawPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OtherType>
|
template <typename OtherType>
|
||||||
requires NonNullPtr_SameType<Type, OtherType>
|
requires NonNullPtr_SameType<Type, OtherType>
|
||||||
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
|
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
|
||||||
{
|
{
|
||||||
return otherRawPtr == nonNullPtr.InternalPtr;
|
return otherRawPtr == nonNullPtr.InternalPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forbid assigning a nullptr at compile time
|
// Forbid assigning a nullptr at compile time
|
||||||
constexpr NonNullPtr(std::nullptr_t)
|
constexpr NonNullPtr(std::nullptr_t)
|
||||||
: InternalPtr(nullptr)
|
: InternalPtr(nullptr)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
|
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr NonNullPtr& operator=(std::nullptr_t)
|
[[nodiscard]] constexpr NonNullPtr& operator=(std::nullptr_t)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
|
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
|
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type* InternalPtr;
|
Type* InternalPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
NonNullPtr(T*) -> NonNullPtr<T>;
|
NonNullPtr(T*) -> NonNullPtr<T>;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
+137
-140
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Math/MathUtils.h>
|
#include <Core/Math/MathUtils.h>
|
||||||
@@ -14,170 +14,167 @@
|
|||||||
#undef RESTORE_GLOBAL
|
#undef RESTORE_GLOBAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Juliet
|
struct Arena;
|
||||||
{
|
|
||||||
struct Arena;
|
|
||||||
|
|
||||||
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
|
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
|
||||||
#define CStr(str) ((str).Str)
|
#define CStr(str) ((str).Str)
|
||||||
#define InplaceString(name, size) \
|
#define InplaceString(name, size) \
|
||||||
char name##_[size]; \
|
char name##_[size]; \
|
||||||
MemSet(name##_, 0, sizeof(uint32)); \
|
MemSet(name##_, 0, sizeof(uint32)); \
|
||||||
String name = { name##_, 0 }
|
String name = { name##_, 0 }
|
||||||
|
|
||||||
// Everything is Little Endian
|
// Everything is Little Endian
|
||||||
enum class StringEncoding : uint8
|
enum class StringEncoding : uint8
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
ASCII,
|
||||||
|
LATIN1,
|
||||||
|
UTF8,
|
||||||
|
UTF16,
|
||||||
|
UTF32,
|
||||||
|
UCS2,
|
||||||
|
UCS4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Represents a UTF-8 String.
|
||||||
|
// Not null terminated.
|
||||||
|
struct String8
|
||||||
|
{
|
||||||
|
char* Str;
|
||||||
|
size_t Size;
|
||||||
|
};
|
||||||
|
using String = String8;
|
||||||
|
|
||||||
|
struct String16
|
||||||
|
{
|
||||||
|
uint16* Str;
|
||||||
|
size_t Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StringBuffer : String
|
||||||
|
{
|
||||||
|
size_t Capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UnicodeDecode
|
||||||
|
{
|
||||||
|
uint32 Increment;
|
||||||
|
uint32 Codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32 kInvalidUTF8 = 0xFFFD;
|
||||||
|
|
||||||
|
inline size_t StringLength(String str)
|
||||||
|
{
|
||||||
|
return str.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t StringLength(const char* str)
|
||||||
|
{
|
||||||
|
size_t length = 0;
|
||||||
|
if (str)
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
while (*str)
|
||||||
ASCII,
|
|
||||||
LATIN1,
|
|
||||||
UTF8,
|
|
||||||
UTF16,
|
|
||||||
UTF32,
|
|
||||||
UCS2,
|
|
||||||
UCS4,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents a UTF-8 String.
|
|
||||||
// Not null terminated.
|
|
||||||
struct String8
|
|
||||||
{
|
|
||||||
char* Str;
|
|
||||||
size_t Size;
|
|
||||||
};
|
|
||||||
using String = String8;
|
|
||||||
|
|
||||||
struct String16
|
|
||||||
{
|
|
||||||
uint16* Str;
|
|
||||||
size_t Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StringBuffer : String
|
|
||||||
{
|
|
||||||
size_t Capacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UnicodeDecode
|
|
||||||
{
|
|
||||||
uint32 Increment;
|
|
||||||
uint32 Codepoint;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr uint32 kInvalidUTF8 = 0xFFFD;
|
|
||||||
|
|
||||||
inline size_t StringLength(String str)
|
|
||||||
{
|
|
||||||
return str.Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t StringLength(const char* str)
|
|
||||||
{
|
|
||||||
size_t length = 0;
|
|
||||||
if (str)
|
|
||||||
{
|
{
|
||||||
while (*str)
|
++length;
|
||||||
{
|
++str;
|
||||||
++length;
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsValid(String str)
|
return length;
|
||||||
{
|
}
|
||||||
return str.Size > 0 && str.Str != nullptr && *str.Str;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline String WrapString(const char* str)
|
inline bool IsValid(String str)
|
||||||
{
|
{
|
||||||
String result = {};
|
return str.Size > 0 && str.Str != nullptr && *str.Str;
|
||||||
result.Str = const_cast<char*>(str);
|
}
|
||||||
result.Size = str ? strlen(str) : 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline String FindChar(String str, char c)
|
inline String WrapString(const char* str)
|
||||||
|
{
|
||||||
|
String result = {};
|
||||||
|
result.Str = const_cast<char*>(str);
|
||||||
|
result.Size = str ? strlen(str) : 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline String FindChar(String str, char c)
|
||||||
|
{
|
||||||
|
String result = str;
|
||||||
|
while (result.Size)
|
||||||
{
|
{
|
||||||
String result = str;
|
if (*result.Str != c)
|
||||||
while (result.Size)
|
|
||||||
{
|
{
|
||||||
if (*result.Str != c)
|
++result.Str;
|
||||||
{
|
--result.Size;
|
||||||
++result.Str;
|
|
||||||
--result.Size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
else
|
||||||
}
|
|
||||||
|
|
||||||
inline bool ContainsChar(String str, char c)
|
|
||||||
{
|
|
||||||
return IsValid(FindChar(str, c));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return:
|
|
||||||
// - < 0 if str1 < str2
|
|
||||||
// - = 0 : Both strings are equals
|
|
||||||
// - > 0 if str1 > str2
|
|
||||||
inline int32 StringCompare(String str1, String str2)
|
|
||||||
{
|
|
||||||
size_t len1 = StringLength(str1);
|
|
||||||
size_t len2 = StringLength(str2);
|
|
||||||
size_t minLen = Min(len1, len2);
|
|
||||||
int32 result = MemCompare(CStr(str1), CStr(str2), minLen);
|
|
||||||
if (result == 0)
|
|
||||||
{
|
{
|
||||||
if (len1 > len2)
|
return result;
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (len1 < len2)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
JULIET_API uint32 StepUTF8(String& inStr);
|
inline bool ContainsChar(String str, char c)
|
||||||
JULIET_API String FindString(String strLeft, String strRight);
|
{
|
||||||
|
return IsValid(FindChar(str, c));
|
||||||
|
}
|
||||||
|
|
||||||
// Case insensitive compare. Supports ASCII only
|
// Return:
|
||||||
// TODO: Support UNICODE
|
// - < 0 if str1 < str2
|
||||||
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2);
|
// - = 0 : Both strings are equals
|
||||||
|
// - > 0 if str1 > str2
|
||||||
// Do not allocate anything, you must allocate your out buffer yourself
|
inline int32 StringCompare(String str1, String str2)
|
||||||
// TODO: Version taking arena that can allocate
|
{
|
||||||
// Do not take String type because we dont know the string encoding we are going from/to
|
size_t len1 = StringLength(str1);
|
||||||
// src and dst will be casted based on the encoding.
|
size_t len2 = StringLength(str2);
|
||||||
// size will correspond to the number of characters
|
size_t minLen = Min(len1, len2);
|
||||||
// Will convert \0 character if present.
|
int32 result = MemCompare(CStr(str1), CStr(str2), minLen);
|
||||||
extern JULIET_API bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst, bool nullTerminate);
|
if (result == 0)
|
||||||
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
|
|
||||||
|
|
||||||
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
|
|
||||||
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str);
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
|
|
||||||
{
|
{
|
||||||
std::string result = std::vformat(formatStr, std::make_format_args(args...));
|
if (len1 > len2)
|
||||||
return StringCopy(arena, WrapString(result.c_str()));
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (len1 < len2)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
JULIET_API uint32 StepUTF8(String& inStr);
|
||||||
|
JULIET_API String FindString(String strLeft, String strRight);
|
||||||
|
|
||||||
|
// Case insensitive compare. Supports ASCII only
|
||||||
|
// TODO: Support UNICODE
|
||||||
|
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2);
|
||||||
|
|
||||||
|
// Do not allocate anything, you must allocate your out buffer yourself
|
||||||
|
// TODO: Version taking arena that can allocate
|
||||||
|
// Do not take String type because we dont know the string encoding we are going from/to
|
||||||
|
// src and dst will be casted based on the encoding.
|
||||||
|
// size will correspond to the number of characters
|
||||||
|
// Will convert \0 character if present.
|
||||||
|
extern JULIET_API bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst, bool nullTerminate);
|
||||||
|
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
|
||||||
|
|
||||||
|
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
|
||||||
|
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str);
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
|
||||||
|
{
|
||||||
|
std::string result = std::vformat(formatStr, std::make_format_args(args...));
|
||||||
|
return StringCopy(arena, WrapString(result.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
#define juliet_snprintf snprintf
|
#define juliet_snprintf snprintf
|
||||||
} // namespace Juliet
|
|
||||||
|
|
||||||
#ifdef UNIT_TEST
|
#ifdef UNIT_TEST
|
||||||
namespace Juliet::UnitTest
|
namespace UnitTest
|
||||||
{
|
{
|
||||||
inline void TestFindChar()
|
inline void TestFindChar()
|
||||||
{
|
{
|
||||||
@@ -192,5 +189,5 @@ namespace Juliet::UnitTest
|
|||||||
Assert(FindChar(s2, 'f').Str - s2.Str == 5);
|
Assert(FindChar(s2, 'f').Str - s2.Str == 5);
|
||||||
Assert(FindChar(s3, '1').Str - s3.Str == 0);
|
Assert(FindChar(s3, '1').Str - s3.Str == 0);
|
||||||
}
|
}
|
||||||
} // namespace Juliet::UnitTest
|
} // namespace UnitTest
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,214 +1,211 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Memory/MemoryArena.h>
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
namespace Juliet
|
template <typename Type, size_t ReserveSize = 16>
|
||||||
|
struct VectorArena
|
||||||
{
|
{
|
||||||
template <typename Type, size_t ReserveSize = 16>
|
void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr))
|
||||||
struct VectorArena
|
|
||||||
{
|
{
|
||||||
void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr))
|
Assert(!Arena);
|
||||||
|
|
||||||
|
JULIET_DEBUG_ONLY(Name = name ? name : Name;)
|
||||||
|
|
||||||
|
DataFirst = DataLast = Data = nullptr;
|
||||||
|
Count = 0;
|
||||||
|
Capacity = 0;
|
||||||
|
Arena = arena;
|
||||||
|
|
||||||
|
Reserve(ReserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy()
|
||||||
|
{
|
||||||
|
DataFirst = DataLast = Data = nullptr;
|
||||||
|
Count = 0;
|
||||||
|
Capacity = 0;
|
||||||
|
Arena = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reserve(size_t newCapacity)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
Assert(newCapacity <= ReserveSize && "VectorArena capacity should be <= ReserveSize.");
|
||||||
|
|
||||||
|
if (Data == nullptr)
|
||||||
{
|
{
|
||||||
Assert(!Arena);
|
Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
|
||||||
|
Capacity = newCapacity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Unimplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JULIET_DEBUG_ONLY(Name = name ? name : Name;)
|
void Resize(size_t newCount)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
if (newCount == Count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DataFirst = DataLast = Data = nullptr;
|
if (Data == nullptr)
|
||||||
Count = 0;
|
{
|
||||||
Capacity = 0;
|
size_t initialCapacity = newCount > ReserveSize ? newCount : ReserveSize;
|
||||||
Arena = arena;
|
Reserve(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(newCount <= Capacity && "VectorArena capacity exceeded!");
|
||||||
|
Count = newCount;
|
||||||
|
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
DataFirst = Data;
|
||||||
|
DataLast = Data + Count - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DataFirst = DataLast = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBack(const Type* buffer, size_t amount)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
Assert(buffer || amount == 0);
|
||||||
|
|
||||||
|
if (amount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Data == nullptr)
|
||||||
|
{
|
||||||
|
size_t initialCapacity = amount > ReserveSize ? amount : ReserveSize;
|
||||||
|
Reserve(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(Count + amount <= Capacity && "VectorArena capacity exceeded!");
|
||||||
|
|
||||||
|
Type* dst = Data + Count;
|
||||||
|
MemCopy(dst, buffer, amount * sizeof(Type));
|
||||||
|
|
||||||
|
if (Count == 0)
|
||||||
|
{
|
||||||
|
DataFirst = dst;
|
||||||
|
}
|
||||||
|
DataLast = dst + amount - 1;
|
||||||
|
Count += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBack(const Type& value)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
|
||||||
|
if (Data == nullptr)
|
||||||
|
{
|
||||||
Reserve(ReserveSize);
|
Reserve(ReserveSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Destroy()
|
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
|
||||||
|
|
||||||
|
Type* entry = Data + Count;
|
||||||
|
*entry = value;
|
||||||
|
|
||||||
|
if (Count == 0)
|
||||||
{
|
{
|
||||||
DataFirst = DataLast = Data = nullptr;
|
DataFirst = entry;
|
||||||
Count = 0;
|
}
|
||||||
Capacity = 0;
|
DataLast = entry;
|
||||||
Arena = nullptr;
|
++Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBack(Type&& value)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
|
||||||
|
if (Data == nullptr)
|
||||||
|
{
|
||||||
|
Reserve(ReserveSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reserve(size_t newCapacity)
|
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
Assert(newCapacity <= ReserveSize && "VectorArena capacity should be <= ReserveSize.");
|
|
||||||
|
|
||||||
if (Data == nullptr)
|
Type* entry = Data + Count;
|
||||||
{
|
*entry = std::move(value);
|
||||||
Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
|
|
||||||
Capacity = newCapacity;
|
if (Count == 0)
|
||||||
}
|
{
|
||||||
else
|
DataFirst = entry;
|
||||||
{
|
}
|
||||||
Unimplemented();
|
DataLast = entry;
|
||||||
}
|
++Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAtFast(index_t index)
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
Assert(index < Count);
|
||||||
|
Assert(Count > 0);
|
||||||
|
|
||||||
|
Type* elementAdr = DataFirst + index;
|
||||||
|
|
||||||
|
// Swap DataLast and element
|
||||||
|
if (DataLast != elementAdr)
|
||||||
|
{
|
||||||
|
Swap(DataLast, elementAdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resize(size_t newCount)
|
--DataLast;
|
||||||
|
--Count;
|
||||||
|
|
||||||
|
if (Count == 0)
|
||||||
{
|
{
|
||||||
Assert(Arena);
|
|
||||||
if (newCount == Count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Data == nullptr)
|
|
||||||
{
|
|
||||||
size_t initialCapacity = newCount > ReserveSize ? newCount : ReserveSize;
|
|
||||||
Reserve(initialCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(newCount <= Capacity && "VectorArena capacity exceeded!");
|
|
||||||
Count = newCount;
|
|
||||||
|
|
||||||
if (Count > 0)
|
|
||||||
{
|
|
||||||
DataFirst = Data;
|
|
||||||
DataLast = Data + Count - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DataFirst = DataLast = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushBack(const Type* buffer, size_t amount)
|
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
Assert(buffer || amount == 0);
|
|
||||||
|
|
||||||
if (amount == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Data == nullptr)
|
|
||||||
{
|
|
||||||
size_t initialCapacity = amount > ReserveSize ? amount : ReserveSize;
|
|
||||||
Reserve(initialCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(Count + amount <= Capacity && "VectorArena capacity exceeded!");
|
|
||||||
|
|
||||||
Type* dst = Data + Count;
|
|
||||||
MemCopy(dst, buffer, amount * sizeof(Type));
|
|
||||||
|
|
||||||
if (Count == 0)
|
|
||||||
{
|
|
||||||
DataFirst = dst;
|
|
||||||
}
|
|
||||||
DataLast = dst + amount - 1;
|
|
||||||
Count += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushBack(const Type& value)
|
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
|
|
||||||
if (Data == nullptr)
|
|
||||||
{
|
|
||||||
Reserve(ReserveSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
|
|
||||||
|
|
||||||
Type* entry = Data + Count;
|
|
||||||
*entry = value;
|
|
||||||
|
|
||||||
if (Count == 0)
|
|
||||||
{
|
|
||||||
DataFirst = entry;
|
|
||||||
}
|
|
||||||
DataLast = entry;
|
|
||||||
++Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushBack(Type&& value)
|
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
|
|
||||||
if (Data == nullptr)
|
|
||||||
{
|
|
||||||
Reserve(ReserveSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
|
|
||||||
|
|
||||||
Type* entry = Data + Count;
|
|
||||||
*entry = std::move(value);
|
|
||||||
|
|
||||||
if (Count == 0)
|
|
||||||
{
|
|
||||||
DataFirst = entry;
|
|
||||||
}
|
|
||||||
DataLast = entry;
|
|
||||||
++Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveAtFast(index_t index)
|
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
Assert(index < Count);
|
|
||||||
Assert(Count > 0);
|
|
||||||
|
|
||||||
Type* elementAdr = DataFirst + index;
|
|
||||||
|
|
||||||
// Swap DataLast and element
|
|
||||||
if (DataLast != elementAdr)
|
|
||||||
{
|
|
||||||
Swap(DataLast, elementAdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
--DataLast;
|
|
||||||
--Count;
|
|
||||||
|
|
||||||
if (Count == 0)
|
|
||||||
{
|
|
||||||
DataFirst = DataLast = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
Assert(Arena);
|
|
||||||
|
|
||||||
DataFirst = DataLast = nullptr;
|
DataFirst = DataLast = nullptr;
|
||||||
Count = 0;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool IsEmpty() const { return Count == 0; }
|
void Clear()
|
||||||
|
{
|
||||||
|
Assert(Arena);
|
||||||
|
|
||||||
// C++ Accessors for loop supports and Index based access
|
DataFirst = DataLast = nullptr;
|
||||||
[[nodiscard]] Type& operator[](size_t index) { return DataFirst[index]; }
|
Count = 0;
|
||||||
[[nodiscard]] const Type& operator[](size_t index) const { return DataFirst[index]; }
|
}
|
||||||
|
|
||||||
[[nodiscard]] Type* begin() { return DataFirst; }
|
[[nodiscard]] bool IsEmpty() const { return Count == 0; }
|
||||||
[[nodiscard]] Type* end() { return DataFirst + Count; }
|
|
||||||
|
|
||||||
[[nodiscard]] const Type* begin() const { return DataFirst; }
|
// C++ Accessors for loop supports and Index based access
|
||||||
[[nodiscard]] const Type* end() const { return DataFirst + Count; }
|
[[nodiscard]] Type& operator[](size_t index) { return DataFirst[index]; }
|
||||||
|
[[nodiscard]] const Type& operator[](size_t index) const { return DataFirst[index]; }
|
||||||
|
|
||||||
[[nodiscard]] Type* First() { return DataFirst; }
|
[[nodiscard]] Type* begin() { return DataFirst; }
|
||||||
[[nodiscard]] Type* Front() { return DataFirst; }
|
[[nodiscard]] Type* end() { return DataFirst + Count; }
|
||||||
[[nodiscard]] Type* Last() { return DataLast; }
|
|
||||||
[[nodiscard]] Type* Back() { return DataLast; }
|
|
||||||
[[nodiscard]] Type* DataPtr() { return Data; }
|
|
||||||
[[nodiscard]] const Type* DataPtr() const { return Data; }
|
|
||||||
|
|
||||||
[[nodiscard]] size_t Size() const { return Count; }
|
[[nodiscard]] const Type* begin() const { return DataFirst; }
|
||||||
|
[[nodiscard]] const Type* end() const { return DataFirst + Count; }
|
||||||
|
|
||||||
Arena* Arena = nullptr;
|
[[nodiscard]] Type* First() { return DataFirst; }
|
||||||
Type* DataFirst = nullptr;
|
[[nodiscard]] Type* Front() { return DataFirst; }
|
||||||
Type* DataLast = nullptr;
|
[[nodiscard]] Type* Last() { return DataLast; }
|
||||||
Type* Data = nullptr;
|
[[nodiscard]] Type* Back() { return DataLast; }
|
||||||
size_t Count = 0;
|
[[nodiscard]] Type* DataPtr() { return Data; }
|
||||||
size_t Capacity = 0;
|
[[nodiscard]] const Type* DataPtr() const { return Data; }
|
||||||
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
|
|
||||||
};
|
[[nodiscard]] size_t Size() const { return Count; }
|
||||||
static_assert(std::is_standard_layout_v<VectorArena<int>>,
|
|
||||||
"VectorArena must have a standard layout to remain POD-like.");
|
Arena* Arena = nullptr;
|
||||||
static_assert(std::is_trivially_copyable_v<VectorArena<int>>,
|
Type* DataFirst = nullptr;
|
||||||
"VectorArena must be trivially copyable (no custom destructors/assignment).");
|
Type* DataLast = nullptr;
|
||||||
} // namespace Juliet
|
Type* Data = nullptr;
|
||||||
|
size_t Count = 0;
|
||||||
|
size_t Capacity = 0;
|
||||||
|
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
|
||||||
|
};
|
||||||
|
static_assert(std::is_standard_layout_v<VectorArena<int>>,
|
||||||
|
"VectorArena must have a standard layout to remain POD-like.");
|
||||||
|
static_assert(std::is_trivially_copyable_v<VectorArena<int>>,
|
||||||
|
"VectorArena must be trivially copyable (no custom destructors/assignment).");
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Window;
|
||||||
{
|
|
||||||
struct Window;
|
|
||||||
|
|
||||||
using WindowID = uint8;
|
using WindowID = uint8;
|
||||||
extern JULIET_API Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int flags = 0 /* unused */);
|
extern JULIET_API Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int flags = 0 /* unused */);
|
||||||
extern JULIET_API void DestroyPlatformWindow(NonNullPtr<Window> window);
|
extern JULIET_API void DestroyPlatformWindow(NonNullPtr<Window> window);
|
||||||
|
|
||||||
extern JULIET_API void ShowWindow(NonNullPtr<Window> window);
|
extern JULIET_API void ShowWindow(NonNullPtr<Window> window);
|
||||||
extern JULIET_API void HideWindow(NonNullPtr<Window> window);
|
extern JULIET_API void HideWindow(NonNullPtr<Window> window);
|
||||||
|
|
||||||
extern JULIET_API WindowID GetWindowID(NonNullPtr<Window> window);
|
extern JULIET_API WindowID GetWindowID(NonNullPtr<Window> window);
|
||||||
extern JULIET_API void SetWindowTitle(NonNullPtr<Window> window, String title);
|
extern JULIET_API void SetWindowTitle(NonNullPtr<Window> window, String title);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct DynamicLibrary;
|
||||||
{
|
|
||||||
struct DynamicLibrary;
|
|
||||||
|
|
||||||
extern JULIET_API DynamicLibrary* LoadDynamicLibrary(const char* filename);
|
extern JULIET_API DynamicLibrary* LoadDynamicLibrary(const char* filename);
|
||||||
extern JULIET_API FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName);
|
extern JULIET_API FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName);
|
||||||
extern JULIET_API void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib);
|
extern JULIET_API void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Display/Display.h>
|
#include <Core/HAL/Display/Display.h>
|
||||||
#include <Core/HAL/Keyboard/Keyboard.h>
|
#include <Core/HAL/Keyboard/Keyboard.h>
|
||||||
@@ -9,115 +9,112 @@
|
|||||||
// Handles all events from systems handling the Hardware
|
// Handles all events from systems handling the Hardware
|
||||||
// Very inspired by SDL3
|
// Very inspired by SDL3
|
||||||
|
|
||||||
namespace Juliet
|
enum class EventType : uint32
|
||||||
{
|
{
|
||||||
enum class EventType : uint32
|
None = 0,
|
||||||
{
|
First = None,
|
||||||
None = 0,
|
|
||||||
First = None,
|
|
||||||
|
|
||||||
// Application Events
|
// Application Events
|
||||||
// User querying an exit
|
// User querying an exit
|
||||||
Application_Exit = 100,
|
Application_Exit = 100,
|
||||||
// OS terminating the application
|
// OS terminating the application
|
||||||
Application_OS_Terminate,
|
Application_OS_Terminate,
|
||||||
Application_Begin = Application_Exit,
|
Application_Begin = Application_Exit,
|
||||||
Application_End = Application_OS_Terminate,
|
Application_End = Application_OS_Terminate,
|
||||||
|
|
||||||
// Window Events
|
// Window Events
|
||||||
Window_Close_Request = 200,
|
Window_Close_Request = 200,
|
||||||
Window_Begin = Window_Close_Request,
|
Window_Begin = Window_Close_Request,
|
||||||
Window_End = Window_Close_Request,
|
Window_End = Window_Close_Request,
|
||||||
|
|
||||||
// Keyboard Event
|
// Keyboard Event
|
||||||
Key_Down = 300,
|
Key_Down = 300,
|
||||||
Key_Up,
|
Key_Up,
|
||||||
Keyboard_Begin = Key_Down,
|
Keyboard_Begin = Key_Down,
|
||||||
Keyboard_End = Key_Up,
|
Keyboard_End = Key_Up,
|
||||||
|
|
||||||
// Mouse Event
|
// Mouse Event
|
||||||
Mouse_Move = 400,
|
Mouse_Move = 400,
|
||||||
Mouse_ButtonPressed,
|
Mouse_ButtonPressed,
|
||||||
Mouse_ButtonReleased,
|
Mouse_ButtonReleased,
|
||||||
|
|
||||||
Mouse_Begin = Mouse_Move,
|
Mouse_Begin = Mouse_Move,
|
||||||
Mouse_End = Mouse_ButtonReleased,
|
Mouse_End = Mouse_ButtonReleased,
|
||||||
|
|
||||||
Last // Get value from the previous one
|
Last // Get value from the previous one
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WindowEvent
|
struct WindowEvent
|
||||||
{
|
{
|
||||||
WindowID AssociatedWindowID;
|
WindowID AssociatedWindowID;
|
||||||
uint32 DataPadding[2]; // TODO : define how much data param we need
|
uint32 DataPadding[2]; // TODO : define how much data param we need
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KeyboardEvent
|
struct KeyboardEvent
|
||||||
{
|
{
|
||||||
KeyboardID AssociatedKeyboardID;
|
KeyboardID AssociatedKeyboardID;
|
||||||
WindowID WindowID;
|
WindowID WindowID;
|
||||||
Key Key;
|
Key Key;
|
||||||
KeyState KeyState;
|
KeyState KeyState;
|
||||||
KeyMod KeyModeState;
|
KeyMod KeyModeState;
|
||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// Mouse Events
|
// Mouse Events
|
||||||
// =====================================================
|
// =====================================================
|
||||||
struct MouseMovementEvent
|
struct MouseMovementEvent
|
||||||
{
|
{
|
||||||
MouseID AssociatedMouseID;
|
MouseID AssociatedMouseID;
|
||||||
WindowID WindowID;
|
WindowID WindowID;
|
||||||
float X;
|
float X;
|
||||||
float Y;
|
float Y;
|
||||||
float X_Displacement;
|
float X_Displacement;
|
||||||
float Y_Displacement;
|
float Y_Displacement;
|
||||||
MouseButton ButtonState;
|
MouseButton ButtonState;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MouseButtonEvent
|
struct MouseButtonEvent
|
||||||
{
|
{
|
||||||
MouseID AssociatedMouseID;
|
MouseID AssociatedMouseID;
|
||||||
WindowID WindowID;
|
WindowID WindowID;
|
||||||
float X;
|
float X;
|
||||||
float Y;
|
float Y;
|
||||||
MouseButton ButtonState;
|
MouseButton ButtonState;
|
||||||
bool IsPressed : 1;
|
bool IsPressed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tagged union representing ALL possible system events + a bit of data for custom event if needed
|
// Tagged union representing ALL possible system events + a bit of data for custom event if needed
|
||||||
union AllSystemEventUnion
|
union AllSystemEventUnion
|
||||||
{
|
{
|
||||||
WindowEvent Window;
|
WindowEvent Window;
|
||||||
KeyboardEvent Keyboard;
|
KeyboardEvent Keyboard;
|
||||||
MouseMovementEvent MouseMovement;
|
MouseMovementEvent MouseMovement;
|
||||||
MouseButtonEvent MouseButton;
|
MouseButtonEvent MouseButton;
|
||||||
uint8 Padding[128]; // Make sure that the union is fixed in size and big enough on all platforms.
|
uint8 Padding[128]; // Make sure that the union is fixed in size and big enough on all platforms.
|
||||||
};
|
};
|
||||||
// Make sure we do not bust the union size
|
// Make sure we do not bust the union size
|
||||||
static_assert(sizeof(AllSystemEventUnion) == sizeof(((AllSystemEventUnion*)nullptr)->Padding));
|
static_assert(sizeof(AllSystemEventUnion) == sizeof(((AllSystemEventUnion*)nullptr)->Padding));
|
||||||
|
|
||||||
struct SystemEvent
|
struct SystemEvent
|
||||||
{
|
{
|
||||||
EventType Type;
|
EventType Type;
|
||||||
uint64 Timestamp;
|
uint64 Timestamp;
|
||||||
AllSystemEventUnion Data;
|
AllSystemEventUnion Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Poll for any event, return false if no event is available.
|
// Poll for any event, return false if no event is available.
|
||||||
// Equivalent to WaitEvent(event, 0);
|
// Equivalent to WaitEvent(event, 0);
|
||||||
// Will not block
|
// Will not block
|
||||||
extern JULIET_API bool GetEvent(SystemEvent& event);
|
extern JULIET_API bool GetEvent(SystemEvent& event);
|
||||||
|
|
||||||
// TODO : use chrono to tag the timeout correctly with nanosec
|
// TODO : use chrono to tag the timeout correctly with nanosec
|
||||||
// timeout == -1 means wait for any event before pursuing
|
// timeout == -1 means wait for any event before pursuing
|
||||||
// timeout == 0 means checking once for the frame and getting out
|
// timeout == 0 means checking once for the frame and getting out
|
||||||
// timeout > 0 means wait until time is out
|
// timeout > 0 means wait until time is out
|
||||||
extern JULIET_API bool WaitEvent(SystemEvent& event, int32 timeoutInNS = -1);
|
extern JULIET_API bool WaitEvent(SystemEvent& event, int32 timeoutInNS = -1);
|
||||||
|
|
||||||
// Add an event onto the event queue.
|
// Add an event onto the event queue.
|
||||||
// TODO : support array of events
|
// TODO : support array of events
|
||||||
extern JULIET_API bool AddEvent(SystemEvent& event);
|
extern JULIET_API bool AddEvent(SystemEvent& event);
|
||||||
|
|
||||||
extern void Events_NewFrame(float deltaTime);
|
extern void Events_NewFrame(float deltaTime);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Returns the path to the application directory
|
||||||
{
|
[[nodiscard]] extern JULIET_API String GetBasePath();
|
||||||
// Returns the path to the application directory
|
|
||||||
[[nodiscard]] extern JULIET_API String GetBasePath();
|
|
||||||
|
|
||||||
// Returns the resolved base path to the compiled shaders directory.
|
// Returns the resolved base path to the compiled shaders directory.
|
||||||
// In dev, this resolves to ../../Assets/compiled/ relative to the exe.
|
// In dev, this resolves to ../../Assets/compiled/ relative to the exe.
|
||||||
// In shipping, this resolves to Assets/Shaders/ next to the exe.
|
// In shipping, this resolves to Assets/Shaders/ next to the exe.
|
||||||
[[nodiscard]] extern JULIET_API String GetAssetBasePath();
|
[[nodiscard]] extern JULIET_API String GetAssetBasePath();
|
||||||
|
|
||||||
// Builds a full path to an asset file given its filename (e.g. "Triangle.vert.dxil").
|
// Builds a full path to an asset file given its filename (e.g. "Triangle.vert.dxil").
|
||||||
// The caller owns the returned buffer and must free it.
|
// The caller owns the returned buffer and must free it.
|
||||||
[[nodiscard]] extern JULIET_API String GetAssetPath(NonNullPtr<Arena> arena, String filename);
|
[[nodiscard]] extern JULIET_API String GetAssetPath(NonNullPtr<Arena> arena, String filename);
|
||||||
|
|
||||||
[[nodiscard]] extern JULIET_API bool IsAbsolutePath(String path);
|
[[nodiscard]] extern JULIET_API bool IsAbsolutePath(String path);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,69 +1,66 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Opaque type
|
||||||
|
struct IOStream;
|
||||||
|
|
||||||
|
struct IOStreamDataPayload
|
||||||
{
|
{
|
||||||
// Opaque type
|
};
|
||||||
struct IOStream;
|
|
||||||
|
|
||||||
struct IOStreamDataPayload
|
enum class IOStreamStatus : uint8
|
||||||
{
|
{
|
||||||
};
|
Ready,
|
||||||
|
Error,
|
||||||
|
EndOfFile,
|
||||||
|
NotReady,
|
||||||
|
ReadOnly,
|
||||||
|
WriteOnly
|
||||||
|
};
|
||||||
|
|
||||||
enum class IOStreamStatus : uint8
|
enum class IOStreamSeekPivot : uint8
|
||||||
{
|
{
|
||||||
Ready,
|
Begin,
|
||||||
Error,
|
Current,
|
||||||
EndOfFile,
|
End,
|
||||||
NotReady,
|
Count
|
||||||
ReadOnly,
|
};
|
||||||
WriteOnly
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class IOStreamSeekPivot : uint8
|
// IOStream can be opened on a file or memory, or anything else.
|
||||||
{
|
// Use the interface to make it transparent to the user.
|
||||||
Begin,
|
struct IOStreamInterface
|
||||||
Current,
|
{
|
||||||
End,
|
uint32 Version;
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
// IOStream can be opened on a file or memory, or anything else.
|
int64 (*Size)(NonNullPtr<IOStreamDataPayload> data);
|
||||||
// Use the interface to make it transparent to the user.
|
|
||||||
struct IOStreamInterface
|
|
||||||
{
|
|
||||||
uint32 Version;
|
|
||||||
|
|
||||||
int64 (*Size)(NonNullPtr<IOStreamDataPayload> data);
|
int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot);
|
||||||
|
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status);
|
||||||
|
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status);
|
||||||
|
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status);
|
||||||
|
|
||||||
int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot);
|
bool (*Close)(NonNullPtr<IOStreamDataPayload> data);
|
||||||
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status);
|
};
|
||||||
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status);
|
|
||||||
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status);
|
|
||||||
|
|
||||||
bool (*Close)(NonNullPtr<IOStreamDataPayload> data);
|
extern JULIET_API IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode);
|
||||||
};
|
|
||||||
|
|
||||||
extern JULIET_API IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode);
|
// Let you use an interface to open any io. Is used internally by IOFromFile
|
||||||
|
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface,
|
||||||
|
NonNullPtr<IOStreamDataPayload> payload);
|
||||||
|
|
||||||
// Let you use an interface to open any io. Is used internally by IOFromFile
|
// Write formatted string into the stream.
|
||||||
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface,
|
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...);
|
||||||
NonNullPtr<IOStreamDataPayload> payload);
|
extern JULIET_API size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer);
|
||||||
|
|
||||||
// Write formatted string into the stream.
|
extern JULIET_API size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size);
|
||||||
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...);
|
extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot);
|
||||||
extern JULIET_API size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer);
|
|
||||||
|
|
||||||
extern JULIET_API size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size);
|
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream);
|
||||||
extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot);
|
|
||||||
|
|
||||||
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream);
|
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename);
|
||||||
|
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
|
||||||
|
|
||||||
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename);
|
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
|
||||||
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
|
|
||||||
|
|
||||||
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,193 +1,190 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout
|
||||||
|
// ScanCode reprensent US ASCII Keyboard
|
||||||
|
// WASD Scan codes are ZQSD in KeyCode for French keyboard
|
||||||
|
// We use the ASCII value of the generated character as value, when possible.
|
||||||
|
// Keys that do not produce a character are converted to an abritrary value high enough to not conflict
|
||||||
|
// Reference: https://www.asciitable.com/
|
||||||
|
// Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa299374(v=vs.60)
|
||||||
|
enum class KeyCode : uint32
|
||||||
{
|
{
|
||||||
// Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout
|
Unknown = 0x0, // 0
|
||||||
// ScanCode reprensent US ASCII Keyboard
|
Unsupported = 0x0, // 0
|
||||||
// WASD Scan codes are ZQSD in KeyCode for French keyboard
|
Return = 0X0Du, // '\r'
|
||||||
// We use the ASCII value of the generated character as value, when possible.
|
Escape = 0X1Bu, // '\X1B'
|
||||||
// Keys that do not produce a character are converted to an abritrary value high enough to not conflict
|
Backspace = 0X08u, // '\b'
|
||||||
// Reference: https://www.asciitable.com/
|
Tab = 0X09u, // '\t'
|
||||||
// Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa299374(v=vs.60)
|
Space = 0X20u, // ' '
|
||||||
enum class KeyCode : uint32
|
ExclamationPoint = 0X21u, // '!'
|
||||||
{
|
DoubleApostrophe = 0X22u, // '"'
|
||||||
Unknown = 0x0, // 0
|
Hash = 0X23u, // '#'
|
||||||
Unsupported = 0x0, // 0
|
Dollar = 0X24u, // '$'
|
||||||
Return = 0X0Du, // '\r'
|
Percent = 0X25u, // '%'
|
||||||
Escape = 0X1Bu, // '\X1B'
|
Ampersand = 0X26u, // '&'
|
||||||
Backspace = 0X08u, // '\b'
|
Apostrophe = 0X27u, // '\''
|
||||||
Tab = 0X09u, // '\t'
|
LeftParenthesis = 0X28u, // '('
|
||||||
Space = 0X20u, // ' '
|
RightParenthesis = 0X29u, // ')'
|
||||||
ExclamationPoint = 0X21u, // '!'
|
Asterisk = 0X2Au, // '*'
|
||||||
DoubleApostrophe = 0X22u, // '"'
|
Plus = 0X2Bu, // '+'
|
||||||
Hash = 0X23u, // '#'
|
Comma = 0X2Cu, // ','
|
||||||
Dollar = 0X24u, // '$'
|
Minus = 0X2Du, // '-'
|
||||||
Percent = 0X25u, // '%'
|
Period = 0X2Eu, // '.'
|
||||||
Ampersand = 0X26u, // '&'
|
Slash = 0X2Fu, // '/'
|
||||||
Apostrophe = 0X27u, // '\''
|
Num0 = 0X30u, // '0'
|
||||||
LeftParenthesis = 0X28u, // '('
|
Num1 = 0X31u, // '1'
|
||||||
RightParenthesis = 0X29u, // ')'
|
Num2 = 0X32u, // '2'
|
||||||
Asterisk = 0X2Au, // '*'
|
Num3 = 0X33u, // '3'
|
||||||
Plus = 0X2Bu, // '+'
|
Num4 = 0X34u, // '4'
|
||||||
Comma = 0X2Cu, // ','
|
Num5 = 0X35u, // '5'
|
||||||
Minus = 0X2Du, // '-'
|
Num6 = 0X36u, // '6'
|
||||||
Period = 0X2Eu, // '.'
|
Num7 = 0X37u, // '7'
|
||||||
Slash = 0X2Fu, // '/'
|
Num8 = 0X38u, // '8'
|
||||||
Num0 = 0X30u, // '0'
|
Num9 = 0X39u, // '9'
|
||||||
Num1 = 0X31u, // '1'
|
Colon = 0X3Au, // ':'
|
||||||
Num2 = 0X32u, // '2'
|
Semicolon = 0X3Bu, // ';'
|
||||||
Num3 = 0X33u, // '3'
|
LessThan = 0X3Cu, // '<'
|
||||||
Num4 = 0X34u, // '4'
|
Equals = 0X3Du, // '='
|
||||||
Num5 = 0X35u, // '5'
|
GreaterThan = 0X3Eu, // '>'
|
||||||
Num6 = 0X36u, // '6'
|
QuestionMark = 0X3Fu, // '?'
|
||||||
Num7 = 0X37u, // '7'
|
CommercialAt = 0x40u, // '@'
|
||||||
Num8 = 0X38u, // '8'
|
LeftBracket = 0X5Bu, // '['
|
||||||
Num9 = 0X39u, // '9'
|
Backslash = 0X5Cu, // '\\'
|
||||||
Colon = 0X3Au, // ':'
|
RightBracket = 0X5DU, // ']'
|
||||||
Semicolon = 0X3Bu, // ';'
|
Caret = 0X5Eu, // '^'
|
||||||
LessThan = 0X3Cu, // '<'
|
Underscore = 0X5Fu, // '_'
|
||||||
Equals = 0X3Du, // '='
|
GraveAccent = 0X60u, // '`'
|
||||||
GreaterThan = 0X3Eu, // '>'
|
A = 0x61u, // 'a'
|
||||||
QuestionMark = 0X3Fu, // '?'
|
B = 0x62u, // 'b'
|
||||||
CommercialAt = 0x40u, // '@'
|
C = 0x63u, // 'c'
|
||||||
LeftBracket = 0X5Bu, // '['
|
D = 0x64u, // 'd'
|
||||||
Backslash = 0X5Cu, // '\\'
|
E = 0x65u, // 'e'
|
||||||
RightBracket = 0X5DU, // ']'
|
F = 0x66u, // 'f'
|
||||||
Caret = 0X5Eu, // '^'
|
G = 0x67u, // 'g'
|
||||||
Underscore = 0X5Fu, // '_'
|
H = 0x68u, // 'h'
|
||||||
GraveAccent = 0X60u, // '`'
|
I = 0x69u, // 'i'
|
||||||
A = 0x61u, // 'a'
|
J = 0x6Au, // 'j'
|
||||||
B = 0x62u, // 'b'
|
K = 0x6Bu, // 'k'
|
||||||
C = 0x63u, // 'c'
|
L = 0x6CU, // 'l'
|
||||||
D = 0x64u, // 'd'
|
M = 0x6DU, // 'm'
|
||||||
E = 0x65u, // 'e'
|
N = 0x6Eu, // 'n'
|
||||||
F = 0x66u, // 'f'
|
O = 0x6Fu, // 'o'
|
||||||
G = 0x67u, // 'g'
|
P = 0x70u, // 'p'
|
||||||
H = 0x68u, // 'h'
|
Q = 0x71u, // 'q'
|
||||||
I = 0x69u, // 'i'
|
R = 0x72u, // 'r'
|
||||||
J = 0x6Au, // 'j'
|
S = 0x73u, // 's'
|
||||||
K = 0x6Bu, // 'k'
|
T = 0x74u, // 't'
|
||||||
L = 0x6CU, // 'l'
|
U = 0x75u, // 'y'
|
||||||
M = 0x6DU, // 'm'
|
V = 0x76u, // 'v'
|
||||||
N = 0x6Eu, // 'n'
|
W = 0x77u, // 'w'
|
||||||
O = 0x6Fu, // 'o'
|
X = 0x78u, // 'x'
|
||||||
P = 0x70u, // 'p'
|
Y = 0x79u, // 'y'
|
||||||
Q = 0x71u, // 'q'
|
Z = 0x7Au, // 'z'
|
||||||
R = 0x72u, // 'r'
|
LeftBrace = 0x7BU, // '{'
|
||||||
S = 0x73u, // 's'
|
Pipe = 0x7CU, // '|'
|
||||||
T = 0x74u, // 't'
|
RightBrace = 0x7DU, // '}'
|
||||||
U = 0x75u, // 'y'
|
Tilde = 0x7Eu, // '~'
|
||||||
V = 0x76u, // 'v'
|
Delete = 0x7Fu, // '\x7F'
|
||||||
W = 0x77u, // 'w'
|
PlusMinus = 0xb1u, // '\xB1'
|
||||||
X = 0x78u, // 'x'
|
|
||||||
Y = 0x79u, // 'y'
|
|
||||||
Z = 0x7Au, // 'z'
|
|
||||||
LeftBrace = 0x7BU, // '{'
|
|
||||||
Pipe = 0x7CU, // '|'
|
|
||||||
RightBrace = 0x7DU, // '}'
|
|
||||||
Tilde = 0x7Eu, // '~'
|
|
||||||
Delete = 0x7Fu, // '\x7F'
|
|
||||||
PlusMinus = 0xb1u, // '\xB1'
|
|
||||||
|
|
||||||
// Keys not producing a character
|
// Keys not producing a character
|
||||||
// Based on SDL Algo: ScanCode | 0x40000000
|
// Based on SDL Algo: ScanCode | 0x40000000
|
||||||
CapsLock = 0x40000039u,
|
CapsLock = 0x40000039u,
|
||||||
F1 = 0x4000003Au,
|
F1 = 0x4000003Au,
|
||||||
F2 = 0x4000003Bu,
|
F2 = 0x4000003Bu,
|
||||||
F3 = 0x4000003CU,
|
F3 = 0x4000003CU,
|
||||||
F4 = 0x4000003DU,
|
F4 = 0x4000003DU,
|
||||||
F5 = 0x4000003Eu,
|
F5 = 0x4000003Eu,
|
||||||
F6 = 0x4000003Fu,
|
F6 = 0x4000003Fu,
|
||||||
F7 = 0x40000040u,
|
F7 = 0x40000040u,
|
||||||
F8 = 0x40000041u,
|
F8 = 0x40000041u,
|
||||||
F9 = 0x40000042u,
|
F9 = 0x40000042u,
|
||||||
F10 = 0x40000043u,
|
F10 = 0x40000043u,
|
||||||
F11 = 0x40000044u,
|
F11 = 0x40000044u,
|
||||||
F12 = 0x40000045u,
|
F12 = 0x40000045u,
|
||||||
PrintScreen = 0x40000046u,
|
PrintScreen = 0x40000046u,
|
||||||
ScrollLock = 0x40000047u,
|
ScrollLock = 0x40000047u,
|
||||||
Pause = 0x40000048u,
|
Pause = 0x40000048u,
|
||||||
Insert = 0x40000049u,
|
Insert = 0x40000049u,
|
||||||
Home = 0x4000004Au,
|
Home = 0x4000004Au,
|
||||||
PageUp = 0x4000004Bu,
|
PageUp = 0x4000004Bu,
|
||||||
End = 0x4000004DU,
|
End = 0x4000004DU,
|
||||||
PageDown = 0x4000004Eu,
|
PageDown = 0x4000004Eu,
|
||||||
RightArrow = 0x4000004Fu,
|
RightArrow = 0x4000004Fu,
|
||||||
LeftArrow = 0x40000050u,
|
LeftArrow = 0x40000050u,
|
||||||
DownArrow = 0x40000051u,
|
DownArrow = 0x40000051u,
|
||||||
UpArrow = 0x40000052u,
|
UpArrow = 0x40000052u,
|
||||||
NumlockClear = 0x40000053u,
|
NumlockClear = 0x40000053u,
|
||||||
KeyPad_Divide = 0x40000054u,
|
KeyPad_Divide = 0x40000054u,
|
||||||
KeyPad_Multiply = 0x40000055u,
|
KeyPad_Multiply = 0x40000055u,
|
||||||
KeyPad_Minus = 0x40000056u,
|
KeyPad_Minus = 0x40000056u,
|
||||||
KeyPad_Plus = 0x40000057u,
|
KeyPad_Plus = 0x40000057u,
|
||||||
KeyPad_Enter = 0x40000058u,
|
KeyPad_Enter = 0x40000058u,
|
||||||
KeyPad_Num1 = 0x40000059u,
|
KeyPad_Num1 = 0x40000059u,
|
||||||
KeyPad_Num2 = 0x4000005Au,
|
KeyPad_Num2 = 0x4000005Au,
|
||||||
KeyPad_Num3 = 0x4000005Bu,
|
KeyPad_Num3 = 0x4000005Bu,
|
||||||
KeyPad_Num4 = 0x4000005Cu,
|
KeyPad_Num4 = 0x4000005Cu,
|
||||||
KeyPad_Num5 = 0x4000005Du,
|
KeyPad_Num5 = 0x4000005Du,
|
||||||
KeyPad_Num6 = 0x4000005Eu,
|
KeyPad_Num6 = 0x4000005Eu,
|
||||||
KeyPad_Num7 = 0x4000005Fu,
|
KeyPad_Num7 = 0x4000005Fu,
|
||||||
KeyPad_Num8 = 0x40000060u,
|
KeyPad_Num8 = 0x40000060u,
|
||||||
KeyPad_Num9 = 0x40000061u,
|
KeyPad_Num9 = 0x40000061u,
|
||||||
KeyPad_Num0 = 0x40000062u,
|
KeyPad_Num0 = 0x40000062u,
|
||||||
KeyPad_Period = 0x40000063u,
|
KeyPad_Period = 0x40000063u,
|
||||||
Power = 0x40000066u,
|
Power = 0x40000066u,
|
||||||
KeyPad_Equals = 0x40000067u,
|
KeyPad_Equals = 0x40000067u,
|
||||||
F13 = 0x40000068u,
|
F13 = 0x40000068u,
|
||||||
F14 = 0x40000069u,
|
F14 = 0x40000069u,
|
||||||
F15 = 0x4000006Au,
|
F15 = 0x4000006Au,
|
||||||
F16 = 0x4000006Bu,
|
F16 = 0x4000006Bu,
|
||||||
F17 = 0x4000006Cu,
|
F17 = 0x4000006Cu,
|
||||||
F18 = 0x4000006Du,
|
F18 = 0x4000006Du,
|
||||||
F19 = 0x4000006Eu,
|
F19 = 0x4000006Eu,
|
||||||
F20 = 0x4000006Fu,
|
F20 = 0x4000006Fu,
|
||||||
F21 = 0x40000070u,
|
F21 = 0x40000070u,
|
||||||
F22 = 0x40000071u,
|
F22 = 0x40000071u,
|
||||||
F23 = 0x40000072u,
|
F23 = 0x40000072u,
|
||||||
F24 = 0x40000073u,
|
F24 = 0x40000073u,
|
||||||
Mute = 0x4000007Fu,
|
Mute = 0x4000007Fu,
|
||||||
VolumeUp = 0x40000080u,
|
VolumeUp = 0x40000080u,
|
||||||
VolumeDown = 0x40000081u,
|
VolumeDown = 0x40000081u,
|
||||||
KeyPad_Comma = 0x40000085u,
|
KeyPad_Comma = 0x40000085u,
|
||||||
LeftControl = 0x400000E0u,
|
LeftControl = 0x400000E0u,
|
||||||
LeftShift = 0x400000E1u,
|
LeftShift = 0x400000E1u,
|
||||||
LeftAlt = 0x400000E2u,
|
LeftAlt = 0x400000E2u,
|
||||||
LeftOSCommand = 0x400000E3u,
|
LeftOSCommand = 0x400000E3u,
|
||||||
RightControl = 0x400000E4u,
|
RightControl = 0x400000E4u,
|
||||||
RightShift = 0x400000E5u,
|
RightShift = 0x400000E5u,
|
||||||
RightAlt = 0x400000E6u,
|
RightAlt = 0x400000E6u,
|
||||||
RightOSCommand = 0x400000E7u,
|
RightOSCommand = 0x400000E7u,
|
||||||
Sleep = 0x40000102u,
|
Sleep = 0x40000102u,
|
||||||
WakeUp = 0x40000103u,
|
WakeUp = 0x40000103u,
|
||||||
Media_NextTrack = 0x4000010Bu,
|
Media_NextTrack = 0x4000010Bu,
|
||||||
Media_PreviousTrack = 0x4000010Cu,
|
Media_PreviousTrack = 0x4000010Cu,
|
||||||
Media_Stop = 0x4000010Du,
|
Media_Stop = 0x4000010Du,
|
||||||
Media_Eject = 0x4000010Eu,
|
Media_Eject = 0x4000010Eu,
|
||||||
Media_PlayPause = 0x4000010Fu,
|
Media_PlayPause = 0x4000010Fu,
|
||||||
Media_Select = 0x40000110u,
|
Media_Select = 0x40000110u,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class KeyMod : uint16
|
enum class KeyMod : uint16
|
||||||
{
|
{
|
||||||
None = 0b0,
|
None = 0b0,
|
||||||
LeftShift = 0b0000'0000'0001u,
|
LeftShift = 0b0000'0000'0001u,
|
||||||
RightShift = 0b0000'0000'0010u,
|
RightShift = 0b0000'0000'0010u,
|
||||||
LeftControl = 0b0000'0000'0100u,
|
LeftControl = 0b0000'0000'0100u,
|
||||||
RightControl = 0b0000'0000'1000u,
|
RightControl = 0b0000'0000'1000u,
|
||||||
LeftAlt = 0b0000'0001'000u,
|
LeftAlt = 0b0000'0001'000u,
|
||||||
RightAlt = 0b0000'0010'0000u,
|
RightAlt = 0b0000'0010'0000u,
|
||||||
LeftOSCommand = 0b0000'0100'0000u,
|
LeftOSCommand = 0b0000'0100'0000u,
|
||||||
RightOSCommand = 0b0000'1000'0000u,
|
RightOSCommand = 0b0000'1000'0000u,
|
||||||
NumLock = 0b0001'0000'0000u,
|
NumLock = 0b0001'0000'0000u,
|
||||||
CapsLock = 0b0010'0000'0000u,
|
CapsLock = 0b0010'0000'0000u,
|
||||||
ScrollLock = 0b0100'0000'0000u,
|
ScrollLock = 0b0100'0000'0000u,
|
||||||
Control = LeftControl | RightControl,
|
Control = LeftControl | RightControl,
|
||||||
Shift = LeftShift | RightShift,
|
Shift = LeftShift | RightShift,
|
||||||
Alt = LeftAlt | RightAlt,
|
Alt = LeftAlt | RightAlt,
|
||||||
OSCommand = LeftOSCommand | RightOSCommand,
|
OSCommand = LeftOSCommand | RightOSCommand,
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,35 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Keyboard/KeyCode.h>
|
#include <Core/HAL/Keyboard/KeyCode.h>
|
||||||
#include <Core/HAL/Keyboard/ScanCode.h>
|
#include <Core/HAL/Keyboard/ScanCode.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
using KeyboardID = uint8;
|
||||||
|
|
||||||
|
enum class KeyPosition : bool
|
||||||
{
|
{
|
||||||
using KeyboardID = uint8;
|
Up = false,
|
||||||
|
Down = true
|
||||||
|
};
|
||||||
|
|
||||||
enum class KeyPosition : bool
|
struct KeyState
|
||||||
{
|
{
|
||||||
Up = false,
|
KeyPosition Position;
|
||||||
Down = true
|
float Time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KeyState
|
struct Key
|
||||||
{
|
{
|
||||||
KeyPosition Position;
|
ScanCode ScanCode;
|
||||||
float Time;
|
KeyCode KeyCode;
|
||||||
};
|
uint16 Raw;
|
||||||
|
};
|
||||||
|
|
||||||
struct Key
|
extern JULIET_API bool IsKeyDown(ScanCode scanCode);
|
||||||
{
|
extern JULIET_API bool IsKeyPressed(ScanCode scanCode);
|
||||||
ScanCode ScanCode;
|
|
||||||
KeyCode KeyCode;
|
|
||||||
uint16 Raw;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern JULIET_API bool IsKeyDown(ScanCode scanCode);
|
extern JULIET_API KeyMod GetKeyModState();
|
||||||
extern JULIET_API bool IsKeyPressed(ScanCode scanCode);
|
extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
|
||||||
|
|
||||||
extern JULIET_API KeyMod GetKeyModState();
|
|
||||||
extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,186 +1,183 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
// Follow the HID Usage page for USB
|
||||||
|
// https://usb.org/sites/default/files/hut1_5.pdf
|
||||||
|
// 0 to 256 Is dedicated to Keyboard Usage Page (0x07)
|
||||||
|
// 257 to 286 Is dedicated to Consumer Usage Page (0xC)
|
||||||
|
// 287 to 511 Is not implemented. Could be used for Mobile or Consoles
|
||||||
|
// ScanCode reprensent Physical Keys and Buttons
|
||||||
|
enum class ScanCode : uint16
|
||||||
{
|
{
|
||||||
// Follow the HID Usage page for USB
|
Unknown = 0,
|
||||||
// https://usb.org/sites/default/files/hut1_5.pdf
|
Unsupported = 0,
|
||||||
// 0 to 256 Is dedicated to Keyboard Usage Page (0x07)
|
|
||||||
// 257 to 286 Is dedicated to Consumer Usage Page (0xC)
|
|
||||||
// 287 to 511 Is not implemented. Could be used for Mobile or Consoles
|
|
||||||
// ScanCode reprensent Physical Keys and Buttons
|
|
||||||
enum class ScanCode : uint16
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
Unsupported = 0,
|
|
||||||
|
|
||||||
A = 4,
|
A = 4,
|
||||||
B = 5,
|
B = 5,
|
||||||
C = 6,
|
C = 6,
|
||||||
D = 7,
|
D = 7,
|
||||||
E = 8,
|
E = 8,
|
||||||
F = 9,
|
F = 9,
|
||||||
G = 10,
|
G = 10,
|
||||||
H = 11,
|
H = 11,
|
||||||
I = 12,
|
I = 12,
|
||||||
J = 13,
|
J = 13,
|
||||||
K = 14,
|
K = 14,
|
||||||
L = 15,
|
L = 15,
|
||||||
M = 16,
|
M = 16,
|
||||||
N = 17,
|
N = 17,
|
||||||
O = 18,
|
O = 18,
|
||||||
P = 19,
|
P = 19,
|
||||||
Q = 20,
|
Q = 20,
|
||||||
R = 21,
|
R = 21,
|
||||||
S = 22,
|
S = 22,
|
||||||
T = 23,
|
T = 23,
|
||||||
U = 24,
|
U = 24,
|
||||||
V = 25,
|
V = 25,
|
||||||
W = 26,
|
W = 26,
|
||||||
X = 27,
|
X = 27,
|
||||||
Y = 28,
|
Y = 28,
|
||||||
Z = 29,
|
Z = 29,
|
||||||
|
|
||||||
Num1 = 30,
|
Num1 = 30,
|
||||||
Num2 = 31,
|
Num2 = 31,
|
||||||
Num3 = 32,
|
Num3 = 32,
|
||||||
Num4 = 33,
|
Num4 = 33,
|
||||||
Num5 = 34,
|
Num5 = 34,
|
||||||
Num6 = 35,
|
Num6 = 35,
|
||||||
Num7 = 36,
|
Num7 = 36,
|
||||||
Num8 = 37,
|
Num8 = 37,
|
||||||
Num9 = 38,
|
Num9 = 38,
|
||||||
Num0 = 39,
|
Num0 = 39,
|
||||||
|
|
||||||
Return = 40,
|
Return = 40,
|
||||||
Escape = 41,
|
Escape = 41,
|
||||||
Backspace = 42,
|
Backspace = 42,
|
||||||
Tab = 43,
|
Tab = 43,
|
||||||
Space = 44,
|
Space = 44,
|
||||||
|
|
||||||
Minus = 45,
|
Minus = 45,
|
||||||
Equals = 46,
|
Equals = 46,
|
||||||
LeftBracket = 47,
|
LeftBracket = 47,
|
||||||
RightBracket = 48,
|
RightBracket = 48,
|
||||||
Backslash = 49,
|
Backslash = 49,
|
||||||
NonUSHash = 50, // Same as 49 but for ISO keyboards
|
NonUSHash = 50, // Same as 49 but for ISO keyboards
|
||||||
Semicolon = 51,
|
Semicolon = 51,
|
||||||
Apostrophe = 52,
|
Apostrophe = 52,
|
||||||
GraveAccent = 53,
|
GraveAccent = 53,
|
||||||
Comma = 54,
|
Comma = 54,
|
||||||
Period = 55,
|
Period = 55,
|
||||||
Slash = 56,
|
Slash = 56,
|
||||||
CapsLock = 57,
|
CapsLock = 57,
|
||||||
|
|
||||||
F1 = 58,
|
F1 = 58,
|
||||||
F2 = 59,
|
F2 = 59,
|
||||||
F3 = 60,
|
F3 = 60,
|
||||||
F4 = 61,
|
F4 = 61,
|
||||||
F5 = 62,
|
F5 = 62,
|
||||||
F6 = 63,
|
F6 = 63,
|
||||||
F7 = 64,
|
F7 = 64,
|
||||||
F8 = 65,
|
F8 = 65,
|
||||||
F9 = 66,
|
F9 = 66,
|
||||||
F10 = 67,
|
F10 = 67,
|
||||||
F11 = 68,
|
F11 = 68,
|
||||||
F12 = 69,
|
F12 = 69,
|
||||||
|
|
||||||
PrintScreen = 70,
|
PrintScreen = 70,
|
||||||
ScrollLock = 71,
|
ScrollLock = 71,
|
||||||
Pause = 72,
|
Pause = 72,
|
||||||
Insert = 73,
|
Insert = 73,
|
||||||
|
|
||||||
Home = 74,
|
Home = 74,
|
||||||
PageUp = 75,
|
PageUp = 75,
|
||||||
Delete = 76,
|
Delete = 76,
|
||||||
End = 77,
|
End = 77,
|
||||||
PageDown = 78,
|
PageDown = 78,
|
||||||
RightArrow = 79,
|
RightArrow = 79,
|
||||||
LeftArrow = 80,
|
LeftArrow = 80,
|
||||||
DownArrow = 81,
|
DownArrow = 81,
|
||||||
UpArrow = 82,
|
UpArrow = 82,
|
||||||
|
|
||||||
NumlockClear = 83, // Pc = Numlock / Mac = Clear
|
NumlockClear = 83, // Pc = Numlock / Mac = Clear
|
||||||
|
|
||||||
KeyPad_Divide = 84,
|
KeyPad_Divide = 84,
|
||||||
KeyPad_Multiply = 85,
|
KeyPad_Multiply = 85,
|
||||||
KeyPad_Minus = 86,
|
KeyPad_Minus = 86,
|
||||||
KeyPad_Plus = 87,
|
KeyPad_Plus = 87,
|
||||||
KeyPad_Enter = 88,
|
KeyPad_Enter = 88,
|
||||||
KeyPad_Num1 = 89,
|
KeyPad_Num1 = 89,
|
||||||
KeyPad_Num2 = 90,
|
KeyPad_Num2 = 90,
|
||||||
KeyPad_Num3 = 91,
|
KeyPad_Num3 = 91,
|
||||||
KeyPad_Num4 = 92,
|
KeyPad_Num4 = 92,
|
||||||
KeyPad_Num5 = 93,
|
KeyPad_Num5 = 93,
|
||||||
KeyPad_Num6 = 94,
|
KeyPad_Num6 = 94,
|
||||||
KeyPad_Num7 = 95,
|
KeyPad_Num7 = 95,
|
||||||
KeyPad_Num8 = 96,
|
KeyPad_Num8 = 96,
|
||||||
KeyPad_Num9 = 97,
|
KeyPad_Num9 = 97,
|
||||||
KeyPad_Num0 = 98,
|
KeyPad_Num0 = 98,
|
||||||
KeyPad_Period = 99,
|
KeyPad_Period = 99,
|
||||||
|
|
||||||
NonUSBackslash = 100, // ISO keyboards only
|
NonUSBackslash = 100, // ISO keyboards only
|
||||||
Power = 102, // Some mac have a Power key
|
Power = 102, // Some mac have a Power key
|
||||||
|
|
||||||
KeyPad_Equals = 103,
|
KeyPad_Equals = 103,
|
||||||
F13 = 104,
|
F13 = 104,
|
||||||
F14 = 105,
|
F14 = 105,
|
||||||
F15 = 106,
|
F15 = 106,
|
||||||
F16 = 107,
|
F16 = 107,
|
||||||
F17 = 108,
|
F17 = 108,
|
||||||
F18 = 109,
|
F18 = 109,
|
||||||
F19 = 110,
|
F19 = 110,
|
||||||
F20 = 111,
|
F20 = 111,
|
||||||
F21 = 112,
|
F21 = 112,
|
||||||
F22 = 113,
|
F22 = 113,
|
||||||
F23 = 114,
|
F23 = 114,
|
||||||
F24 = 115,
|
F24 = 115,
|
||||||
|
|
||||||
Mute = 127,
|
Mute = 127,
|
||||||
VolumeUp = 128,
|
VolumeUp = 128,
|
||||||
VolumeDown = 129,
|
VolumeDown = 129,
|
||||||
|
|
||||||
KeyPad_Comma = 133,
|
KeyPad_Comma = 133,
|
||||||
|
|
||||||
International1 = 135, // Mostly used on Asian keyboards
|
International1 = 135, // Mostly used on Asian keyboards
|
||||||
International2 = 136,
|
International2 = 136,
|
||||||
International3 = 137, // Yen Symbol
|
International3 = 137, // Yen Symbol
|
||||||
International4 = 138,
|
International4 = 138,
|
||||||
International5 = 139,
|
International5 = 139,
|
||||||
International6 = 140,
|
International6 = 140,
|
||||||
International7 = 141,
|
International7 = 141,
|
||||||
International8 = 142,
|
International8 = 142,
|
||||||
International9 = 143,
|
International9 = 143,
|
||||||
Lang1 = 144, // Hangul (Korean)
|
Lang1 = 144, // Hangul (Korean)
|
||||||
Lang2 = 145, // Hanja (Korean)
|
Lang2 = 145, // Hanja (Korean)
|
||||||
Lang3 = 146, // Katakana (Japanese)
|
Lang3 = 146, // Katakana (Japanese)
|
||||||
Lang4 = 147, // Hiragana (Japanese)
|
Lang4 = 147, // Hiragana (Japanese)
|
||||||
Lang5 = 148, // Zenkaku/Hankaku (Japanese)
|
Lang5 = 148, // Zenkaku/Hankaku (Japanese)
|
||||||
Lang6 = 149, // Unused
|
Lang6 = 149, // Unused
|
||||||
Lang7 = 150, // Unused
|
Lang7 = 150, // Unused
|
||||||
Lang8 = 151, // Unused
|
Lang8 = 151, // Unused
|
||||||
Lang9 = 152, // Unused
|
Lang9 = 152, // Unused
|
||||||
|
|
||||||
LeftControl = 224,
|
LeftControl = 224,
|
||||||
LeftShift = 225,
|
LeftShift = 225,
|
||||||
LeftAlt = 226, // Alt for PC, Option for Mac
|
LeftAlt = 226, // Alt for PC, Option for Mac
|
||||||
LeftOSCommand = 227, // Window key for PC, Command for Mac
|
LeftOSCommand = 227, // Window key for PC, Command for Mac
|
||||||
RightControl = 228,
|
RightControl = 228,
|
||||||
RightShift = 229,
|
RightShift = 229,
|
||||||
RightAlt = 230, // Alt Gr for PC, Option for Mac
|
RightAlt = 230, // Alt Gr for PC, Option for Mac
|
||||||
RightOSCommand = 231, // Window key for PC, Command for Mac
|
RightOSCommand = 231, // Window key for PC, Command for Mac
|
||||||
|
|
||||||
Sleep = 258,
|
Sleep = 258,
|
||||||
WakeUp = 259,
|
WakeUp = 259,
|
||||||
|
|
||||||
Media_NextTrack = 267,
|
Media_NextTrack = 267,
|
||||||
Media_PreviousTrack = 268,
|
Media_PreviousTrack = 268,
|
||||||
Media_Stop = 269,
|
Media_Stop = 269,
|
||||||
Media_Eject = 270,
|
Media_Eject = 270,
|
||||||
Media_PlayPause = 271,
|
Media_PlayPause = 271,
|
||||||
Media_Select = 272,
|
Media_Select = 272,
|
||||||
|
|
||||||
Reserved = 287,
|
Reserved = 287,
|
||||||
|
|
||||||
Count = 512
|
Count = 512
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
using MouseID = uint8;
|
||||||
|
|
||||||
|
enum class MouseButton : uint8
|
||||||
{
|
{
|
||||||
using MouseID = uint8;
|
None = 0,
|
||||||
|
Left = 1 << 0,
|
||||||
|
Right = 1 << 1,
|
||||||
|
Middle = 1 << 2,
|
||||||
|
Button1 = 1 << 3,
|
||||||
|
Button2 = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
enum class MouseButton : uint8
|
// TODO : Replace by Vector2f
|
||||||
{
|
struct MousePosition
|
||||||
None = 0,
|
{
|
||||||
Left = 1 << 0,
|
float X;
|
||||||
Right = 1 << 1,
|
float Y;
|
||||||
Middle = 1 << 2,
|
};
|
||||||
Button1 = 1 << 3,
|
|
||||||
Button2 = 1 << 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO : Replace by Vector2f
|
JULIET_API extern bool IsMouseButtonDown(MouseButton button);
|
||||||
struct MousePosition
|
JULIET_API extern MousePosition GetMousePosition();
|
||||||
{
|
JULIET_API extern MousePosition GetMouseDelta();
|
||||||
float X;
|
JULIET_API extern MouseButton GetMouseButtonState();
|
||||||
float Y;
|
|
||||||
};
|
|
||||||
|
|
||||||
JULIET_API extern bool IsMouseButtonDown(MouseButton button);
|
|
||||||
JULIET_API extern MousePosition GetMousePosition();
|
|
||||||
JULIET_API extern MousePosition GetMouseDelta();
|
|
||||||
JULIET_API extern MouseButton GetMouseButtonState();
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,49 +1,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Memory
|
||||||
{
|
{
|
||||||
namespace Memory
|
Byte* OS_Reserve(size_t size);
|
||||||
|
bool OS_Commit(Byte* ptr, size_t size);
|
||||||
|
void OS_Release(Byte* ptr, size_t size);
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
Type* OS_Reserve(size_t size)
|
||||||
{
|
{
|
||||||
Byte* OS_Reserve(size_t size);
|
return reinterpret_cast<Type*>(OS_Reserve(size));
|
||||||
bool OS_Commit(Byte* ptr, size_t size);
|
}
|
||||||
void OS_Release(Byte* ptr, size_t size);
|
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type* OS_Reserve(size_t size)
|
bool OS_Commit(Type* ptr, size_t size)
|
||||||
{
|
|
||||||
return reinterpret_cast<Type*>(OS_Reserve(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
bool OS_Commit(Type* ptr, size_t size)
|
|
||||||
{
|
|
||||||
return OS_Commit(reinterpret_cast<Byte*>(ptr), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
void OS_Release(Type* ptr, size_t size)
|
|
||||||
{
|
|
||||||
OS_Release(reinterpret_cast<Byte*>(ptr), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Memory
|
|
||||||
|
|
||||||
namespace Time
|
|
||||||
{
|
{
|
||||||
uint64 Timestamp();
|
return OS_Commit(reinterpret_cast<Byte*>(ptr), size);
|
||||||
void ComputeDeltaTime();
|
}
|
||||||
float GetDeltaTime();
|
|
||||||
uint64 GetFrameNumber();
|
|
||||||
} // namespace Time
|
|
||||||
|
|
||||||
namespace Debug
|
template <typename Type>
|
||||||
|
void OS_Release(Type* ptr, size_t size)
|
||||||
{
|
{
|
||||||
JULIET_API bool IsDebuggerPresent();
|
OS_Release(reinterpret_cast<Byte*>(ptr), size);
|
||||||
} // namespace Debug
|
}
|
||||||
|
|
||||||
using EntryPointFunc = int (*)(int, wchar_t**);
|
} // namespace Memory
|
||||||
JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
|
|
||||||
} // namespace Juliet
|
namespace Time
|
||||||
|
{
|
||||||
|
uint64 Timestamp();
|
||||||
|
void ComputeDeltaTime();
|
||||||
|
float GetDeltaTime();
|
||||||
|
uint64 GetFrameNumber();
|
||||||
|
} // namespace Time
|
||||||
|
|
||||||
|
namespace Debug
|
||||||
|
{
|
||||||
|
JULIET_API bool IsDebuggerPresent();
|
||||||
|
} // namespace Debug
|
||||||
|
|
||||||
|
using EntryPointFunc = int (*)(int, wchar_t**);
|
||||||
|
JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
|
||||||
|
|||||||
@@ -1,38 +1,35 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Fwd Declare
|
||||||
|
struct DynamicLibrary;
|
||||||
|
|
||||||
|
struct HotReloadCode
|
||||||
{
|
{
|
||||||
// Fwd Declare
|
String DLLFullPath;
|
||||||
struct DynamicLibrary;
|
String LockFullPath;
|
||||||
|
String TransientDLLName;
|
||||||
|
|
||||||
struct HotReloadCode
|
uint64 LastWriteTime;
|
||||||
{
|
|
||||||
String DLLFullPath;
|
|
||||||
String LockFullPath;
|
|
||||||
String TransientDLLName;
|
|
||||||
|
|
||||||
uint64 LastWriteTime;
|
DynamicLibrary* Dll;
|
||||||
|
|
||||||
DynamicLibrary* Dll;
|
void** Functions;
|
||||||
|
const char** FunctionNames;
|
||||||
|
uint32 FunctionCount;
|
||||||
|
|
||||||
void** Functions;
|
uint32 UniqueID;
|
||||||
const char** FunctionNames;
|
|
||||||
uint32 FunctionCount;
|
|
||||||
|
|
||||||
uint32 UniqueID;
|
bool IsValid : 1;
|
||||||
|
};
|
||||||
|
|
||||||
bool IsValid : 1;
|
extern JULIET_API void InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName,
|
||||||
};
|
String transientDllName, String lockFilename);
|
||||||
|
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
|
||||||
|
|
||||||
extern JULIET_API void InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName,
|
extern JULIET_API void LoadCode(HotReloadCode& code);
|
||||||
String transientDllName, String lockFilename);
|
extern JULIET_API void UnloadCode(HotReloadCode& code);
|
||||||
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
|
|
||||||
|
|
||||||
extern JULIET_API void LoadCode(HotReloadCode& code);
|
extern JULIET_API void ReloadCode(HotReloadCode& code);
|
||||||
extern JULIET_API void UnloadCode(HotReloadCode& code);
|
extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code);
|
||||||
|
|
||||||
extern JULIET_API void ReloadCode(HotReloadCode& code);
|
|
||||||
extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
@@ -7,25 +7,22 @@
|
|||||||
|
|
||||||
struct ImGuiContext;
|
struct ImGuiContext;
|
||||||
|
|
||||||
namespace Juliet
|
struct Window;
|
||||||
|
struct GraphicsDevice;
|
||||||
|
|
||||||
|
namespace ImGuiService
|
||||||
{
|
{
|
||||||
struct Window;
|
JULIET_API void Initialize(NonNullPtr<Window> window);
|
||||||
struct GraphicsDevice;
|
JULIET_API void Shutdown();
|
||||||
|
|
||||||
namespace ImGuiService
|
JULIET_API void NewFrame();
|
||||||
{
|
JULIET_API void Render();
|
||||||
JULIET_API void Initialize(NonNullPtr<Window> window);
|
|
||||||
JULIET_API void Shutdown();
|
|
||||||
|
|
||||||
JULIET_API void NewFrame();
|
JULIET_API bool IsInitialized();
|
||||||
JULIET_API void Render();
|
JULIET_API ImGuiContext* GetContext();
|
||||||
|
|
||||||
JULIET_API bool IsInitialized();
|
// Run internal unit tests
|
||||||
JULIET_API ImGuiContext* GetContext();
|
JULIET_API void RunTests();
|
||||||
|
} // namespace ImGuiService
|
||||||
// Run internal unit tests
|
|
||||||
JULIET_API void RunTests();
|
|
||||||
} // namespace ImGuiService
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|
||||||
#endif // JULIET_ENABLE_IMGUI
|
#endif // JULIET_ENABLE_IMGUI
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet::UnitTest
|
namespace UnitTest
|
||||||
{
|
{
|
||||||
void TestImGui();
|
void TestImGui();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
|
||||||
namespace Juliet
|
enum class JulietInit_Flags : uint8
|
||||||
{
|
{
|
||||||
enum class JulietInit_Flags : uint8
|
None = 0,
|
||||||
{
|
Display = 1 << 0,
|
||||||
None = 0,
|
Audio = 1 << 1,
|
||||||
Display = 1 << 0,
|
Count = Audio,
|
||||||
Audio = 1 << 1,
|
All = 0xFb
|
||||||
Count = Audio,
|
};
|
||||||
All = 0xFb
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Arena;
|
struct Arena;
|
||||||
|
|
||||||
struct GameData
|
struct GameData
|
||||||
{
|
{
|
||||||
struct GameState* GameState;
|
struct GameState* GameState;
|
||||||
Arena* ScratchArena;
|
Arena* ScratchArena;
|
||||||
};
|
};
|
||||||
|
|
||||||
void JulietInit(JulietInit_Flags flags);
|
void JulietInit(JulietInit_Flags flags);
|
||||||
void JulietShutdown();
|
void JulietShutdown();
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
@@ -9,21 +9,18 @@
|
|||||||
// TODO Juliet Containers + Allocators...
|
// TODO Juliet Containers + Allocators...
|
||||||
// TODO: Juliet chrono, because it prevents me from doing #define global static
|
// TODO: Juliet chrono, because it prevents me from doing #define global static
|
||||||
|
|
||||||
namespace Juliet
|
enum class LogLevel : uint8;
|
||||||
{
|
enum class LogCategory : uint8;
|
||||||
enum class LogLevel : uint8;
|
|
||||||
enum class LogCategory : uint8;
|
|
||||||
|
|
||||||
extern void JULIET_API InitializeLogManager();
|
extern void JULIET_API InitializeLogManager();
|
||||||
extern void JULIET_API ShutdownLogManager();
|
extern void JULIET_API ShutdownLogManager();
|
||||||
|
|
||||||
extern void JULIET_API LogScopeBegin();
|
extern void JULIET_API LogScopeBegin();
|
||||||
// TODO everything that happened in there to export them to file or something
|
// TODO everything that happened in there to export them to file or something
|
||||||
extern void JULIET_API LogScopeEnd();
|
extern void JULIET_API LogScopeEnd();
|
||||||
|
|
||||||
extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...);
|
extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...);
|
||||||
extern void JULIET_API LogDebug(LogCategory category, const char* fmt, ...);
|
extern void JULIET_API LogDebug(LogCategory category, const char* fmt, ...);
|
||||||
extern void JULIET_API LogMessage(LogCategory category, const char* fmt, ...);
|
extern void JULIET_API LogMessage(LogCategory category, const char* fmt, ...);
|
||||||
extern void JULIET_API LogWarning(LogCategory category, const char* fmt, ...);
|
extern void JULIET_API LogWarning(LogCategory category, const char* fmt, ...);
|
||||||
extern void JULIET_API LogError(LogCategory category, const char* fmt, ...);
|
extern void JULIET_API LogError(LogCategory category, const char* fmt, ...);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
enum class LogLevel : uint8
|
||||||
{
|
{
|
||||||
enum class LogLevel : uint8
|
Debug = 0,
|
||||||
{
|
Message = 1,
|
||||||
Debug = 0,
|
Warning = 2,
|
||||||
Message = 1,
|
Error = 3,
|
||||||
Warning = 2,
|
};
|
||||||
Error = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LogCategory : uint8
|
enum class LogCategory : uint8
|
||||||
{
|
{
|
||||||
Core = 0,
|
Core = 0,
|
||||||
Graphics = 1,
|
Graphics = 1,
|
||||||
Networking = 2,
|
Networking = 2,
|
||||||
Engine = 3,
|
Engine = 3,
|
||||||
Tool = 4,
|
Tool = 4,
|
||||||
Game = 5,
|
Game = 5,
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/OS/OS.h>
|
#include <Core/HAL/OS/OS.h>
|
||||||
|
|
||||||
@@ -12,12 +12,12 @@ extern int JulietMain(int, wchar_t**);
|
|||||||
#if UNICODE
|
#if UNICODE
|
||||||
int wmain(int argc, wchar_t** argv)
|
int wmain(int argc, wchar_t** argv)
|
||||||
{
|
{
|
||||||
return Juliet::Bootstrap(JulietMain, argc, argv);
|
return Bootstrap(JulietMain, argc, argv);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
return Juliet::Bootstrap(JulietMain, argc, argv);
|
return Bootstrap(JulietMain, argc, argv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||||||
(void)szCmdLine;
|
(void)szCmdLine;
|
||||||
(void)sw;
|
(void)sw;
|
||||||
|
|
||||||
return Juliet::Bootstrap(JulietMain, __argc, __wargv);
|
return Bootstrap(JulietMain, __argc, __wargv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,52 +1,49 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
extern JULIET_API float RoundF(float value);
|
||||||
|
|
||||||
|
inline int32 LRoundF(float value)
|
||||||
{
|
{
|
||||||
extern JULIET_API float RoundF(float value);
|
return static_cast<int32>(RoundF(value));
|
||||||
|
}
|
||||||
|
|
||||||
inline int32 LRoundF(float value)
|
template <typename Type>
|
||||||
{
|
constexpr Type Min(Type lhs, Type rhs)
|
||||||
return static_cast<int32>(RoundF(value));
|
{
|
||||||
}
|
return rhs < lhs ? rhs : lhs;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr Type Min(Type lhs, Type rhs)
|
constexpr Type Max(Type lhs, Type rhs)
|
||||||
{
|
{
|
||||||
return rhs < lhs ? rhs : lhs;
|
return lhs < rhs ? rhs : lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr Type Max(Type lhs, Type rhs)
|
constexpr Type ClampTop(Type value, Type X)
|
||||||
{
|
{
|
||||||
return lhs < rhs ? rhs : lhs;
|
return Min(value, X);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr Type ClampTop(Type value, Type X)
|
constexpr Type ClampBottom(Type value, Type X)
|
||||||
{
|
{
|
||||||
return Min(value, X);
|
return Max(value, X);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr Type ClampBottom(Type value, Type X)
|
constexpr Type Clamp(Type val, Type min, Type max)
|
||||||
|
{
|
||||||
|
if (val < min)
|
||||||
{
|
{
|
||||||
return Max(value, X);
|
return min;
|
||||||
}
|
}
|
||||||
|
if (val > max)
|
||||||
template <typename Type>
|
|
||||||
constexpr Type Clamp(Type val, Type min, Type max)
|
|
||||||
{
|
{
|
||||||
if (val < min)
|
return max;
|
||||||
{
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
if (val > max)
|
|
||||||
{
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
return val;
|
||||||
|
}
|
||||||
|
|||||||
+174
-177
@@ -1,194 +1,191 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Math/Vector.h>
|
#include <Core/Math/Vector.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Matrix
|
||||||
{
|
{
|
||||||
struct Matrix
|
float m[4][4];
|
||||||
{
|
};
|
||||||
float m[4][4];
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixIdentity()
|
[[nodiscard]] inline Matrix MatrixIdentity()
|
||||||
{
|
{
|
||||||
Matrix result = {};
|
Matrix result = {};
|
||||||
result.m[0][0] = 1.0f;
|
result.m[0][0] = 1.0f;
|
||||||
result.m[1][1] = 1.0f;
|
result.m[1][1] = 1.0f;
|
||||||
result.m[2][2] = 1.0f;
|
result.m[2][2] = 1.0f;
|
||||||
result.m[3][3] = 1.0f;
|
result.m[3][3] = 1.0f;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs)
|
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
Matrix result = {};
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
Matrix result = {};
|
for (int j = 0; j < 4; ++j)
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 4; ++j)
|
for (int k = 0; k < 4; ++k)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < 4; ++k)
|
result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
|
||||||
{
|
|
||||||
result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z)
|
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z)
|
||||||
|
{
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[0][3] = x;
|
||||||
|
result.m[1][3] = y;
|
||||||
|
result.m[2][3] = z;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[0][0] = x;
|
||||||
|
result.m[1][1] = y;
|
||||||
|
result.m[2][2] = z;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixRotationX(float radians)
|
||||||
|
{
|
||||||
|
float c = cosf(radians);
|
||||||
|
float s = sinf(radians);
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[1][1] = c;
|
||||||
|
result.m[1][2] = -s;
|
||||||
|
result.m[2][1] = s;
|
||||||
|
result.m[2][2] = c;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixRotationY(float radians)
|
||||||
|
{
|
||||||
|
float c = cosf(radians);
|
||||||
|
float s = sinf(radians);
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[0][0] = c;
|
||||||
|
result.m[0][2] = s;
|
||||||
|
result.m[2][0] = -s;
|
||||||
|
result.m[2][2] = c;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixRotationZ(float radians)
|
||||||
|
{
|
||||||
|
float c = cosf(radians);
|
||||||
|
float s = sinf(radians);
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[0][0] = c;
|
||||||
|
result.m[0][1] = -s;
|
||||||
|
result.m[1][0] = s;
|
||||||
|
result.m[1][1] = c;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MatrixTranslate(Matrix& m, const Vector3& v)
|
||||||
|
{
|
||||||
|
m.m[0][3] += v.x;
|
||||||
|
m.m[1][3] += v.y;
|
||||||
|
m.m[2][3] += v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z)
|
||||||
|
{
|
||||||
|
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
||||||
|
{
|
||||||
|
// Left-Handed convention
|
||||||
|
Vector3 zaxis = Normalize(target - eye); // Forward is +z
|
||||||
|
Vector3 xaxis = Normalize(Cross(up, zaxis));
|
||||||
|
Vector3 yaxis = Cross(zaxis, xaxis);
|
||||||
|
|
||||||
|
Matrix result = {};
|
||||||
|
// Row 0
|
||||||
|
result.m[0][0] = xaxis.x;
|
||||||
|
result.m[0][1] = xaxis.y;
|
||||||
|
result.m[0][2] = xaxis.z;
|
||||||
|
result.m[0][3] = -Dot(xaxis, eye);
|
||||||
|
|
||||||
|
// Row 1
|
||||||
|
result.m[1][0] = yaxis.x;
|
||||||
|
result.m[1][1] = yaxis.y;
|
||||||
|
result.m[1][2] = yaxis.z;
|
||||||
|
result.m[1][3] = -Dot(yaxis, eye);
|
||||||
|
|
||||||
|
// Row 2
|
||||||
|
result.m[2][0] = zaxis.x;
|
||||||
|
result.m[2][1] = zaxis.y;
|
||||||
|
result.m[2][2] = zaxis.z;
|
||||||
|
result.m[2][3] = -Dot(zaxis, eye);
|
||||||
|
|
||||||
|
// Row 3
|
||||||
|
result.m[3][3] = 1.0f;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
|
||||||
|
{
|
||||||
|
// Left-Handed Perspective
|
||||||
|
float yScale = 1.0f / tanf(fovY * 0.5f);
|
||||||
|
float xScale = yScale / aspectRatio;
|
||||||
|
|
||||||
|
Matrix result = {};
|
||||||
|
result.m[0][0] = xScale;
|
||||||
|
result.m[1][1] = yScale;
|
||||||
|
result.m[2][2] = farZ / (farZ - nearZ);
|
||||||
|
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
|
||||||
|
result.m[3][2] = 1.0f;
|
||||||
|
result.m[3][3] = 0.0f;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m)
|
||||||
|
{
|
||||||
|
Matrix out = {};
|
||||||
|
|
||||||
|
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3];
|
||||||
|
float m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
|
||||||
|
float m20 = m.m[2][0], m21 = m.m[2][1], m22 = m.m[2][2], m23 = m.m[2][3];
|
||||||
|
float m30 = m.m[3][0], m31 = m.m[3][1], m32 = m.m[3][2], m33 = m.m[3][3];
|
||||||
|
|
||||||
|
out.m[0][0] = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
|
||||||
|
out.m[1][0] = -m10 * m22 * m33 + m10 * m23 * m32 + m20 * m12 * m33 - m20 * m13 * m32 - m30 * m12 * m23 + m30 * m13 * m22;
|
||||||
|
out.m[2][0] = m10 * m21 * m33 - m10 * m23 * m31 - m20 * m11 * m33 + m20 * m13 * m31 + m30 * m11 * m23 - m30 * m13 * m21;
|
||||||
|
out.m[3][0] = -m10 * m21 * m32 + m10 * m22 * m31 + m20 * m11 * m32 - m20 * m12 * m31 - m30 * m11 * m22 + m30 * m12 * m21;
|
||||||
|
|
||||||
|
out.m[0][1] = -m01 * m22 * m33 + m01 * m23 * m32 + m21 * m02 * m33 - m21 * m03 * m32 - m31 * m02 * m23 + m31 * m03 * m22;
|
||||||
|
out.m[1][1] = m00 * m22 * m33 - m00 * m23 * m32 - m20 * m02 * m33 + m20 * m03 * m32 + m30 * m02 * m23 - m30 * m03 * m22;
|
||||||
|
out.m[2][1] = -m00 * m21 * m33 + m00 * m23 * m31 + m20 * m01 * m33 - m20 * m03 * m31 - m30 * m01 * m23 + m30 * m03 * m21;
|
||||||
|
out.m[3][1] = m00 * m21 * m32 - m00 * m22 * m31 - m20 * m01 * m32 + m20 * m02 * m31 + m30 * m01 * m22 - m30 * m02 * m21;
|
||||||
|
|
||||||
|
out.m[0][2] = m01 * m12 * m33 - m01 * m13 * m32 - m11 * m02 * m33 + m11 * m03 * m32 + m31 * m02 * m13 - m31 * m03 * m12;
|
||||||
|
out.m[1][2] = -m00 * m12 * m33 + m00 * m13 * m32 + m10 * m02 * m33 - m10 * m03 * m32 - m30 * m02 * m13 + m30 * m03 * m12;
|
||||||
|
out.m[2][2] = m00 * m11 * m33 - m00 * m13 * m31 - m10 * m01 * m33 + m10 * m03 * m31 + m30 * m01 * m13 - m30 * m03 * m11;
|
||||||
|
out.m[3][2] = -m00 * m11 * m32 + m00 * m12 * m31 + m10 * m01 * m32 - m10 * m02 * m31 - m30 * m01 * m12 + m30 * m02 * m11;
|
||||||
|
|
||||||
|
out.m[0][3] = -m01 * m12 * m23 + m01 * m13 * m22 + m11 * m02 * m23 - m11 * m03 * m22 - m21 * m02 * m13 + m21 * m03 * m12;
|
||||||
|
out.m[1][3] = m00 * m12 * m23 - m00 * m13 * m22 - m10 * m02 * m23 + m10 * m03 * m22 + m20 * m02 * m13 - m20 * m03 * m12;
|
||||||
|
out.m[2][3] = -m00 * m11 * m23 + m00 * m13 * m21 + m10 * m01 * m23 - m10 * m03 * m21 - m20 * m01 * m13 + m20 * m03 * m11;
|
||||||
|
out.m[3][3] = m00 * m11 * m22 - m00 * m12 * m21 - m10 * m01 * m22 + m10 * m02 * m21 + m20 * m01 * m12 - m20 * m02 * m11;
|
||||||
|
|
||||||
|
float det = m00 * out.m[0][0] + m01 * out.m[1][0] + m02 * out.m[2][0] + m03 * out.m[3][0];
|
||||||
|
|
||||||
|
if (det != 0.0f)
|
||||||
{
|
{
|
||||||
Matrix result = MatrixIdentity();
|
float invDet = 1.0f / det;
|
||||||
result.m[0][3] = x;
|
for (int r = 0; r < 4; ++r)
|
||||||
result.m[1][3] = y;
|
for (int c = 0; c < 4; ++c)
|
||||||
result.m[2][3] = z;
|
out.m[r][c] *= invDet;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z)
|
return out;
|
||||||
{
|
}
|
||||||
Matrix result = MatrixIdentity();
|
|
||||||
result.m[0][0] = x;
|
|
||||||
result.m[1][1] = y;
|
|
||||||
result.m[2][2] = z;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixRotationX(float radians)
|
|
||||||
{
|
|
||||||
float c = cosf(radians);
|
|
||||||
float s = sinf(radians);
|
|
||||||
Matrix result = MatrixIdentity();
|
|
||||||
result.m[1][1] = c;
|
|
||||||
result.m[1][2] = -s;
|
|
||||||
result.m[2][1] = s;
|
|
||||||
result.m[2][2] = c;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixRotationY(float radians)
|
|
||||||
{
|
|
||||||
float c = cosf(radians);
|
|
||||||
float s = sinf(radians);
|
|
||||||
Matrix result = MatrixIdentity();
|
|
||||||
result.m[0][0] = c;
|
|
||||||
result.m[0][2] = s;
|
|
||||||
result.m[2][0] = -s;
|
|
||||||
result.m[2][2] = c;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixRotationZ(float radians)
|
|
||||||
{
|
|
||||||
float c = cosf(radians);
|
|
||||||
float s = sinf(radians);
|
|
||||||
Matrix result = MatrixIdentity();
|
|
||||||
result.m[0][0] = c;
|
|
||||||
result.m[0][1] = -s;
|
|
||||||
result.m[1][0] = s;
|
|
||||||
result.m[1][1] = c;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MatrixTranslate(Matrix& m, const Vector3& v)
|
|
||||||
{
|
|
||||||
m.m[0][3] += v.x;
|
|
||||||
m.m[1][3] += v.y;
|
|
||||||
m.m[2][3] += v.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z)
|
|
||||||
{
|
|
||||||
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
|
||||||
{
|
|
||||||
// Left-Handed convention
|
|
||||||
Vector3 zaxis = Normalize(target - eye); // Forward is +z
|
|
||||||
Vector3 xaxis = Normalize(Cross(up, zaxis));
|
|
||||||
Vector3 yaxis = Cross(zaxis, xaxis);
|
|
||||||
|
|
||||||
Matrix result = {};
|
|
||||||
// Row 0
|
|
||||||
result.m[0][0] = xaxis.x;
|
|
||||||
result.m[0][1] = xaxis.y;
|
|
||||||
result.m[0][2] = xaxis.z;
|
|
||||||
result.m[0][3] = -Dot(xaxis, eye);
|
|
||||||
|
|
||||||
// Row 1
|
|
||||||
result.m[1][0] = yaxis.x;
|
|
||||||
result.m[1][1] = yaxis.y;
|
|
||||||
result.m[1][2] = yaxis.z;
|
|
||||||
result.m[1][3] = -Dot(yaxis, eye);
|
|
||||||
|
|
||||||
// Row 2
|
|
||||||
result.m[2][0] = zaxis.x;
|
|
||||||
result.m[2][1] = zaxis.y;
|
|
||||||
result.m[2][2] = zaxis.z;
|
|
||||||
result.m[2][3] = -Dot(zaxis, eye);
|
|
||||||
|
|
||||||
// Row 3
|
|
||||||
result.m[3][3] = 1.0f;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
|
|
||||||
{
|
|
||||||
// Left-Handed Perspective
|
|
||||||
float yScale = 1.0f / tanf(fovY * 0.5f);
|
|
||||||
float xScale = yScale / aspectRatio;
|
|
||||||
|
|
||||||
Matrix result = {};
|
|
||||||
result.m[0][0] = xScale;
|
|
||||||
result.m[1][1] = yScale;
|
|
||||||
result.m[2][2] = farZ / (farZ - nearZ);
|
|
||||||
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
|
|
||||||
result.m[3][2] = 1.0f;
|
|
||||||
result.m[3][3] = 0.0f;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m)
|
|
||||||
{
|
|
||||||
Matrix out = {};
|
|
||||||
|
|
||||||
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3];
|
|
||||||
float m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
|
|
||||||
float m20 = m.m[2][0], m21 = m.m[2][1], m22 = m.m[2][2], m23 = m.m[2][3];
|
|
||||||
float m30 = m.m[3][0], m31 = m.m[3][1], m32 = m.m[3][2], m33 = m.m[3][3];
|
|
||||||
|
|
||||||
out.m[0][0] = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
|
|
||||||
out.m[1][0] = -m10 * m22 * m33 + m10 * m23 * m32 + m20 * m12 * m33 - m20 * m13 * m32 - m30 * m12 * m23 + m30 * m13 * m22;
|
|
||||||
out.m[2][0] = m10 * m21 * m33 - m10 * m23 * m31 - m20 * m11 * m33 + m20 * m13 * m31 + m30 * m11 * m23 - m30 * m13 * m21;
|
|
||||||
out.m[3][0] = -m10 * m21 * m32 + m10 * m22 * m31 + m20 * m11 * m32 - m20 * m12 * m31 - m30 * m11 * m22 + m30 * m12 * m21;
|
|
||||||
|
|
||||||
out.m[0][1] = -m01 * m22 * m33 + m01 * m23 * m32 + m21 * m02 * m33 - m21 * m03 * m32 - m31 * m02 * m23 + m31 * m03 * m22;
|
|
||||||
out.m[1][1] = m00 * m22 * m33 - m00 * m23 * m32 - m20 * m02 * m33 + m20 * m03 * m32 + m30 * m02 * m23 - m30 * m03 * m22;
|
|
||||||
out.m[2][1] = -m00 * m21 * m33 + m00 * m23 * m31 + m20 * m01 * m33 - m20 * m03 * m31 - m30 * m01 * m23 + m30 * m03 * m21;
|
|
||||||
out.m[3][1] = m00 * m21 * m32 - m00 * m22 * m31 - m20 * m01 * m32 + m20 * m02 * m31 + m30 * m01 * m22 - m30 * m02 * m21;
|
|
||||||
|
|
||||||
out.m[0][2] = m01 * m12 * m33 - m01 * m13 * m32 - m11 * m02 * m33 + m11 * m03 * m32 + m31 * m02 * m13 - m31 * m03 * m12;
|
|
||||||
out.m[1][2] = -m00 * m12 * m33 + m00 * m13 * m32 + m10 * m02 * m33 - m10 * m03 * m32 - m30 * m02 * m13 + m30 * m03 * m12;
|
|
||||||
out.m[2][2] = m00 * m11 * m33 - m00 * m13 * m31 - m10 * m01 * m33 + m10 * m03 * m31 + m30 * m01 * m13 - m30 * m03 * m11;
|
|
||||||
out.m[3][2] = -m00 * m11 * m32 + m00 * m12 * m31 + m10 * m01 * m32 - m10 * m02 * m31 - m30 * m01 * m12 + m30 * m02 * m11;
|
|
||||||
|
|
||||||
out.m[0][3] = -m01 * m12 * m23 + m01 * m13 * m22 + m11 * m02 * m23 - m11 * m03 * m22 - m21 * m02 * m13 + m21 * m03 * m12;
|
|
||||||
out.m[1][3] = m00 * m12 * m23 - m00 * m13 * m22 - m10 * m02 * m23 + m10 * m03 * m22 + m20 * m02 * m13 - m20 * m03 * m12;
|
|
||||||
out.m[2][3] = -m00 * m11 * m23 + m00 * m13 * m21 + m10 * m01 * m23 - m10 * m03 * m21 - m20 * m01 * m13 + m20 * m03 * m11;
|
|
||||||
out.m[3][3] = m00 * m11 * m22 - m00 * m12 * m21 - m10 * m01 * m22 + m10 * m02 * m21 + m20 * m01 * m12 - m20 * m02 * m11;
|
|
||||||
|
|
||||||
float det = m00 * out.m[0][0] + m01 * out.m[1][0] + m02 * out.m[2][0] + m03 * out.m[3][0];
|
|
||||||
|
|
||||||
if (det != 0.0f)
|
|
||||||
{
|
|
||||||
float invDet = 1.0f / det;
|
|
||||||
for (int r = 0; r < 4; ++r)
|
|
||||||
for (int c = 0; c < 4; ++c)
|
|
||||||
out.m[r][c] *= invDet;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
struct Rectangle
|
||||||
{
|
{
|
||||||
struct Rectangle
|
int32 X;
|
||||||
{
|
int32 Y;
|
||||||
int32 X;
|
int32 Width;
|
||||||
int32 Y;
|
int32 Height;
|
||||||
int32 Width;
|
};
|
||||||
int32 Height;
|
|
||||||
};
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,39 +1,36 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Vector3
|
||||||
{
|
{
|
||||||
struct Vector3
|
float x, y, z;
|
||||||
{
|
|
||||||
float x, y, z;
|
|
||||||
|
|
||||||
Vector3 operator+(const Vector3& rhs) const { return { x + rhs.x, y + rhs.y, z + rhs.z }; }
|
Vector3 operator+(const Vector3& rhs) const { return { x + rhs.x, y + rhs.y, z + rhs.z }; }
|
||||||
Vector3 operator-(const Vector3& rhs) const { return { x - rhs.x, y - rhs.y, z - rhs.z }; }
|
Vector3 operator-(const Vector3& rhs) const { return { x - rhs.x, y - rhs.y, z - rhs.z }; }
|
||||||
Vector3 operator*(float s) const { return { x * s, y * s, z * s }; }
|
Vector3 operator*(float s) const { return { x * s, y * s, z * s }; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector4
|
struct Vector4
|
||||||
{
|
{
|
||||||
float x, y, z, w;
|
float x, y, z, w;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Vector3 Normalize(const Vector3& v)
|
inline Vector3 Normalize(const Vector3& v)
|
||||||
|
{
|
||||||
|
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||||
|
if (len > 0.0001f)
|
||||||
{
|
{
|
||||||
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
|
return { v.x / len, v.y / len, v.z / len };
|
||||||
if (len > 0.0001f)
|
|
||||||
{
|
|
||||||
return { v.x / len, v.y / len, v.z / len };
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
inline Vector3 Cross(const Vector3& a, const Vector3& b)
|
inline Vector3 Cross(const Vector3& a, const Vector3& b)
|
||||||
{
|
{
|
||||||
return { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x };
|
return { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float Dot(const Vector3& a, const Vector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
inline float Dot(const Vector3& a, const Vector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,31 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Uninitialized allocation
|
||||||
{
|
JULIET_API void* Malloc(size_t elem_size);
|
||||||
// Uninitialized allocation
|
// Initialized to 0 allocation
|
||||||
JULIET_API void* Malloc(size_t elem_size);
|
JULIET_API void* Calloc(size_t nb_elem, size_t elem_size);
|
||||||
// Initialized to 0 allocation
|
JULIET_API void* Realloc(void* memory, size_t newSize);
|
||||||
JULIET_API void* Calloc(size_t nb_elem, size_t elem_size);
|
|
||||||
JULIET_API void* Realloc(void* memory, size_t newSize);
|
|
||||||
|
|
||||||
// Free
|
// Free
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
void Free(Type* memory)
|
void Free(Type* memory)
|
||||||
|
{
|
||||||
|
Assert(memory);
|
||||||
|
::free(memory);
|
||||||
|
}
|
||||||
|
// Free and Set the ptr to nullptr
|
||||||
|
template <typename Type>
|
||||||
|
void SafeFree(Type*& memory)
|
||||||
|
{
|
||||||
|
if (memory)
|
||||||
{
|
{
|
||||||
Assert(memory);
|
|
||||||
::free(memory);
|
::free(memory);
|
||||||
|
memory = nullptr;
|
||||||
}
|
}
|
||||||
// Free and Set the ptr to nullptr
|
}
|
||||||
template <typename Type>
|
|
||||||
void SafeFree(Type*& memory)
|
|
||||||
{
|
|
||||||
if (memory)
|
|
||||||
{
|
|
||||||
::free(memory);
|
|
||||||
memory = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
@@ -10,122 +10,119 @@
|
|||||||
#include <Core/Memory/MemoryArenaDebug.h>
|
#include <Core/Memory/MemoryArenaDebug.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Juliet
|
constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64);
|
||||||
|
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64);
|
||||||
|
constexpr global uint64 k_ArenaHeaderSize = 128;
|
||||||
|
|
||||||
|
#if JULIET_DEBUG
|
||||||
|
struct ArenaDebugInfo;
|
||||||
|
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Arena
|
||||||
{
|
{
|
||||||
constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64);
|
Arena* Previous;
|
||||||
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64);
|
Arena* Current;
|
||||||
constexpr global uint64 k_ArenaHeaderSize = 128;
|
|
||||||
|
uint64 BasePosition;
|
||||||
|
uint64 Position;
|
||||||
|
uint64 Alignment;
|
||||||
|
|
||||||
|
uint64 CommitSize;
|
||||||
|
uint64 ReserveSize;
|
||||||
|
|
||||||
|
uint64 Committed;
|
||||||
|
uint64 Reserved;
|
||||||
|
|
||||||
|
Arena* FreeBlockLast;
|
||||||
|
|
||||||
|
JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
|
||||||
|
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
|
||||||
|
|
||||||
|
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
|
||||||
|
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
|
||||||
|
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
|
||||||
|
const char* Name;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
|
||||||
|
|
||||||
|
struct TempArena
|
||||||
|
{
|
||||||
|
Arena* Arena;
|
||||||
|
index_t Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArenaParams
|
||||||
|
{
|
||||||
|
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
|
||||||
|
uint64 CommitSize = g_Arena_Default_Commit_Size;
|
||||||
|
|
||||||
|
const char* Name;
|
||||||
|
|
||||||
|
// When false, will assert if a new block is reserved.
|
||||||
|
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params,
|
||||||
|
const std::source_location& loc = std::source_location::current());
|
||||||
|
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
|
||||||
|
|
||||||
|
// Raw Push, can be used but templated helpers exists below
|
||||||
|
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
|
||||||
|
bool shouldBeZeroed JULIET_DEBUG_PARAM(const char* tag));
|
||||||
|
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
|
||||||
|
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
|
||||||
|
JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
|
||||||
|
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
struct ArenaDebugInfo;
|
template <typename FirstDebugArg, typename... DebugArgs>
|
||||||
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args);
|
|
||||||
#endif
|
#endif
|
||||||
|
[[nodiscard]] inline void* ArenaPushSize(NonNullPtr<Arena> arena, size_t size, size_t align,
|
||||||
|
bool shouldBeZeroed JULIET_DEBUG_PARAM(FirstDebugArg&& firstDebugArg,
|
||||||
|
DebugArgs&&... debugArgs))
|
||||||
|
{
|
||||||
|
return ArenaPush(arena, size, align,
|
||||||
|
shouldBeZeroed JULIET_DEBUG_PARAM(
|
||||||
|
[&]() -> const char*
|
||||||
|
{
|
||||||
|
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
|
||||||
|
std::forward<DebugArgs>(debugArgs)...)
|
||||||
|
.Str;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
|
||||||
struct Arena
|
template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
||||||
{
|
[[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
||||||
Arena* Previous;
|
{
|
||||||
Arena* Current;
|
return static_cast<Type*>(
|
||||||
|
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type),
|
||||||
uint64 BasePosition;
|
true JULIET_DEBUG_PARAM(
|
||||||
uint64 Position;
|
[&]() -> const char*
|
||||||
uint64 Alignment;
|
{
|
||||||
|
if constexpr (sizeof...(DebugArgs) > 0)
|
||||||
uint64 CommitSize;
|
|
||||||
uint64 ReserveSize;
|
|
||||||
|
|
||||||
uint64 Committed;
|
|
||||||
uint64 Reserved;
|
|
||||||
|
|
||||||
Arena* FreeBlockLast;
|
|
||||||
|
|
||||||
JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
|
|
||||||
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
|
|
||||||
|
|
||||||
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
|
|
||||||
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
|
|
||||||
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
|
|
||||||
const char* Name;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
|
|
||||||
|
|
||||||
struct TempArena
|
|
||||||
{
|
|
||||||
Arena* Arena;
|
|
||||||
index_t Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ArenaParams
|
|
||||||
{
|
|
||||||
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
|
|
||||||
uint64 CommitSize = g_Arena_Default_Commit_Size;
|
|
||||||
|
|
||||||
const char* Name;
|
|
||||||
|
|
||||||
// When false, will assert if a new block is reserved.
|
|
||||||
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params,
|
|
||||||
const std::source_location& loc = std::source_location::current());
|
|
||||||
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
|
|
||||||
|
|
||||||
// Raw Push, can be used but templated helpers exists below
|
|
||||||
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
|
|
||||||
bool shouldBeZeroed JULIET_DEBUG_PARAM(const char* tag));
|
|
||||||
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
|
|
||||||
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
|
|
||||||
JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
|
|
||||||
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
|
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
|
||||||
template <typename FirstDebugArg, typename... DebugArgs>
|
|
||||||
#endif
|
|
||||||
[[nodiscard]] inline void* ArenaPushSize(NonNullPtr<Arena> arena, size_t size, size_t align,
|
|
||||||
bool shouldBeZeroed JULIET_DEBUG_PARAM(FirstDebugArg&& firstDebugArg,
|
|
||||||
DebugArgs&&... debugArgs))
|
|
||||||
{
|
|
||||||
return ArenaPush(arena, size, align,
|
|
||||||
shouldBeZeroed JULIET_DEBUG_PARAM(
|
|
||||||
[&]() -> const char*
|
|
||||||
{
|
|
||||||
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
|
|
||||||
std::forward<DebugArgs>(debugArgs)...)
|
|
||||||
.Str;
|
|
||||||
}()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
|
||||||
[[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
|
||||||
{
|
|
||||||
return static_cast<Type*>(
|
|
||||||
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type),
|
|
||||||
true JULIET_DEBUG_PARAM(
|
|
||||||
[&]() -> const char*
|
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(DebugArgs) > 0)
|
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
||||||
{
|
}
|
||||||
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
return GetTypeName<Type>();
|
||||||
}
|
}())));
|
||||||
return GetTypeName<Type>();
|
}
|
||||||
}())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type, bool shouldZero = true JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
template <typename Type, bool shouldZero = true JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
||||||
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
||||||
{
|
{
|
||||||
return static_cast<Type*>(
|
return static_cast<Type*>(
|
||||||
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
|
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
|
||||||
shouldZero JULIET_DEBUG_PARAM(
|
shouldZero JULIET_DEBUG_PARAM(
|
||||||
[&]() -> const char*
|
[&]() -> const char*
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(DebugArgs) > 0)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(DebugArgs) > 0)
|
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
||||||
{
|
}
|
||||||
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
return GetTypeName<Type>();
|
||||||
}
|
}())));
|
||||||
return GetTypeName<Type>();
|
}
|
||||||
}())));
|
|
||||||
}
|
|
||||||
|
|
||||||
TempArena ArenaTempBegin(NonNullPtr<Arena> arena);
|
TempArena ArenaTempBegin(NonNullPtr<Arena> arena);
|
||||||
void ArenaTempEnd(TempArena temp);
|
void ArenaTempEnd(TempArena temp);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
@@ -7,46 +7,43 @@
|
|||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
|
|
||||||
namespace Juliet
|
struct Arena;
|
||||||
|
struct MemoryBlock;
|
||||||
|
|
||||||
|
// Arena (Struct)
|
||||||
|
struct ArenaDebugInfo
|
||||||
{
|
{
|
||||||
struct Arena;
|
const char* Tag;
|
||||||
struct MemoryBlock;
|
size_t Offset;
|
||||||
|
size_t Size;
|
||||||
|
ArenaDebugInfo* Next;
|
||||||
|
};
|
||||||
|
|
||||||
// Arena (Struct)
|
// MemoryArena (Pool-based)
|
||||||
struct ArenaDebugInfo
|
struct ArenaAllocation
|
||||||
{
|
{
|
||||||
const char* Tag;
|
size_t Offset;
|
||||||
size_t Offset;
|
size_t Size;
|
||||||
size_t Size;
|
String Tag;
|
||||||
ArenaDebugInfo* Next;
|
ArenaAllocation* Next;
|
||||||
};
|
};
|
||||||
|
|
||||||
// MemoryArena (Pool-based)
|
// Arena (Struct)
|
||||||
struct ArenaAllocation
|
void DebugRegisterArena(NonNullPtr<Arena> arena);
|
||||||
{
|
void DebugUnregisterArena(NonNullPtr<Arena> arena);
|
||||||
size_t Offset;
|
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name);
|
||||||
size_t Size;
|
bool IsDebugInfoArena(const Arena* arena); // To prevent recursion
|
||||||
String Tag;
|
void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
|
||||||
ArenaAllocation* Next;
|
void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
|
||||||
};
|
void DebugArenaPopTo(Arena* block, size_t newPosition);
|
||||||
|
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
|
||||||
|
|
||||||
// Arena (Struct)
|
// MemoryArena (Pool-based)
|
||||||
void DebugRegisterArena(NonNullPtr<Arena> arena);
|
void DebugFreeArenaAllocations(MemoryBlock* blk);
|
||||||
void DebugUnregisterArena(NonNullPtr<Arena> arena);
|
void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
|
||||||
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name);
|
void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
|
||||||
bool IsDebugInfoArena(const Arena* arena); // To prevent recursion
|
|
||||||
void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
|
|
||||||
void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
|
|
||||||
void DebugArenaPopTo(Arena* block, size_t newPosition);
|
|
||||||
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
|
|
||||||
|
|
||||||
// MemoryArena (Pool-based)
|
JULIET_API Arena* GetDebugInfoArena();
|
||||||
void DebugFreeArenaAllocations(MemoryBlock* blk);
|
|
||||||
void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
|
|
||||||
void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
|
|
||||||
|
|
||||||
JULIET_API Arena* GetDebugInfoArena();
|
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,78 +1,75 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
|
||||||
#define ArraySize(array) (sizeof(array) / sizeof(array[0]))
|
#define ArraySize(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
namespace Juliet
|
inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size)
|
||||||
{
|
{
|
||||||
inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size)
|
auto left = static_cast<const unsigned char*>(leftValue);
|
||||||
|
auto right = static_cast<const unsigned char*>(rightValue);
|
||||||
|
while (size && *left == *right)
|
||||||
{
|
{
|
||||||
auto left = static_cast<const unsigned char*>(leftValue);
|
++left;
|
||||||
auto right = static_cast<const unsigned char*>(rightValue);
|
++right;
|
||||||
while (size && *left == *right)
|
--size;
|
||||||
{
|
}
|
||||||
++left;
|
return size ? *left - *right : 0;
|
||||||
++right;
|
}
|
||||||
--size;
|
|
||||||
}
|
// Single linked list
|
||||||
return size ? *left - *right : 0;
|
void SingleLinkedListPushNext(auto*& stackTop, auto* node)
|
||||||
|
{
|
||||||
|
node->Next = stackTop;
|
||||||
|
stackTop = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLinkedListPushPrevious(auto*& stackTop, auto* node)
|
||||||
|
{
|
||||||
|
node->Previous = stackTop;
|
||||||
|
stackTop = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLinkedListPopNext(auto*& stackTop)
|
||||||
|
{
|
||||||
|
stackTop = stackTop->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double linked list
|
||||||
|
template <typename QueueType, typename QueueTypeNode>
|
||||||
|
void Enqueue(QueueType& queue, QueueTypeNode* node)
|
||||||
|
{
|
||||||
|
if (queue.First == nullptr)
|
||||||
|
{
|
||||||
|
queue.First = queue.Last = node;
|
||||||
|
node->Next = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queue.Last->Next = node, queue.Last = node;
|
||||||
|
node->Next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single linked list
|
queue.Nodecount += 1;
|
||||||
void SingleLinkedListPushNext(auto*& stackTop, auto* node)
|
}
|
||||||
{
|
|
||||||
node->Next = stackTop;
|
|
||||||
stackTop = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleLinkedListPushPrevious(auto*& stackTop, auto* node)
|
template <typename QueueType>
|
||||||
{
|
struct QueueNode
|
||||||
node->Previous = stackTop;
|
{
|
||||||
stackTop = node;
|
QueueType* Next;
|
||||||
}
|
};
|
||||||
|
|
||||||
void SingleLinkedListPopNext(auto*& stackTop)
|
|
||||||
{
|
|
||||||
stackTop = stackTop->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Double linked list
|
|
||||||
template <typename QueueType, typename QueueTypeNode>
|
|
||||||
void Enqueue(QueueType& queue, QueueTypeNode* node)
|
|
||||||
{
|
|
||||||
if (queue.First == nullptr)
|
|
||||||
{
|
|
||||||
queue.First = queue.Last = node;
|
|
||||||
node->Next = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue.Last->Next = node, queue.Last = node;
|
|
||||||
node->Next = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.Nodecount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename QueueType>
|
|
||||||
struct QueueNode
|
|
||||||
{
|
|
||||||
QueueType* Next;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DECLARE_QUEUE(type) \
|
#define DECLARE_QUEUE(type) \
|
||||||
struct type##Queue \
|
struct type##Queue \
|
||||||
{ \
|
{ \
|
||||||
type* First; \
|
type* First; \
|
||||||
type* Last; \
|
type* Last; \
|
||||||
size_t Nodecount; \
|
size_t Nodecount; \
|
||||||
size_t Size; \
|
size_t Size; \
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: homemade versions
|
// TODO: homemade versions
|
||||||
#define MemSet memset
|
#define MemSet memset
|
||||||
#define MemCopy memcpy
|
#define MemCopy memcpy
|
||||||
|
|
||||||
#define MemoryZero(dst, size) MemSet(dst, 0, size)
|
#define MemoryZero(dst, size) MemSet(dst, 0, size)
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
|
||||||
namespace Juliet
|
// TODO : Do something better.
|
||||||
{
|
constexpr uint32 kLocalhost = (127 << 3) | (0 << 2) | (0 << 1) | 1;
|
||||||
// TODO : Do something better.
|
constexpr uint32 kAnyIp = 0;
|
||||||
constexpr uint32 kLocalhost = (127 << 3) | (0 << 2) | (0 << 1) | 1;
|
constexpr uint32 kBroadcastIp = (255 << 3) | (255 << 2) | (255 << 1) | 255;
|
||||||
constexpr uint32 kAnyIp = 0;
|
|
||||||
constexpr uint32 kBroadcastIp = (255 << 3) | (255 << 2) | (255 << 1) | 255;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,36 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Container/Vector.h>
|
#include <Core/Container/Vector.h>
|
||||||
|
|
||||||
namespace Juliet
|
class NetworkPacket
|
||||||
{
|
{
|
||||||
class NetworkPacket
|
public:
|
||||||
{
|
NetworkPacket();
|
||||||
public:
|
NetworkPacket(Arena& arena);
|
||||||
NetworkPacket();
|
virtual ~NetworkPacket();
|
||||||
NetworkPacket(Arena& arena);
|
NetworkPacket(NetworkPacket&);
|
||||||
virtual ~NetworkPacket();
|
NetworkPacket& operator=(const NetworkPacket&);
|
||||||
NetworkPacket(NetworkPacket&);
|
NetworkPacket(NetworkPacket&&) noexcept;
|
||||||
NetworkPacket& operator=(const NetworkPacket&);
|
NetworkPacket& operator=(NetworkPacket&&) noexcept;
|
||||||
NetworkPacket(NetworkPacket&&) noexcept;
|
|
||||||
NetworkPacket& operator=(NetworkPacket&&) noexcept;
|
|
||||||
|
|
||||||
void Create(Arena& arena);
|
void Create(Arena& arena);
|
||||||
|
|
||||||
[[nodiscard]] ByteBuffer GetRawData();
|
[[nodiscard]] ByteBuffer GetRawData();
|
||||||
|
|
||||||
// Pack
|
// Pack
|
||||||
NetworkPacket& operator<<(uint32 value);
|
NetworkPacket& operator<<(uint32 value);
|
||||||
NetworkPacket& operator<<(char* data);
|
NetworkPacket& operator<<(char* data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Append(ByteBuffer buffer);
|
void Append(ByteBuffer buffer);
|
||||||
|
|
||||||
friend class TcpSocket;
|
friend class TcpSocket;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VectorArena<Byte, 4096> Data;
|
VectorArena<Byte, 4096> Data;
|
||||||
size_t PartialSendIndex = 0;
|
size_t PartialSendIndex = 0;
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,56 +1,53 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Networking/SocketHandle.h>
|
#include <Core/Networking/SocketHandle.h>
|
||||||
|
|
||||||
namespace Juliet
|
class Socket
|
||||||
{
|
{
|
||||||
class Socket
|
public:
|
||||||
|
virtual ~Socket();
|
||||||
|
|
||||||
|
Socket(Socket&& other) noexcept;
|
||||||
|
Socket& operator=(Socket&& socket) noexcept;
|
||||||
|
|
||||||
|
Socket(const Socket&) = delete;
|
||||||
|
Socket& operator=(const Socket&) = delete;
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
enum class Status : uint8
|
||||||
{
|
{
|
||||||
public:
|
Done,
|
||||||
virtual ~Socket();
|
Partial,
|
||||||
|
Ready,
|
||||||
Socket(Socket&& other) noexcept;
|
NotReady,
|
||||||
Socket& operator=(Socket&& socket) noexcept;
|
Disconnected,
|
||||||
|
Error
|
||||||
Socket(const Socket&) = delete;
|
|
||||||
Socket& operator=(const Socket&) = delete;
|
|
||||||
|
|
||||||
bool IsValid() const;
|
|
||||||
|
|
||||||
enum class Status : uint8
|
|
||||||
{
|
|
||||||
Done,
|
|
||||||
Partial,
|
|
||||||
Ready,
|
|
||||||
NotReady,
|
|
||||||
Disconnected,
|
|
||||||
Error
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
enum class Protocol : uint8
|
|
||||||
{
|
|
||||||
TCP,
|
|
||||||
UDP
|
|
||||||
};
|
|
||||||
|
|
||||||
// To store the result of a send/receive on the socket
|
|
||||||
struct RequestStatus
|
|
||||||
{
|
|
||||||
Status Status = Status::Done;
|
|
||||||
size_t Length = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit Socket(Protocol protocol);
|
|
||||||
|
|
||||||
SocketHandle GetHandle() const { return Handle; }
|
|
||||||
|
|
||||||
void Create();
|
|
||||||
void CreateFromHandle(SocketHandle handle);
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SocketHandle Handle;
|
|
||||||
Protocol ProtocolType;
|
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
protected:
|
||||||
|
enum class Protocol : uint8
|
||||||
|
{
|
||||||
|
TCP,
|
||||||
|
UDP
|
||||||
|
};
|
||||||
|
|
||||||
|
// To store the result of a send/receive on the socket
|
||||||
|
struct RequestStatus
|
||||||
|
{
|
||||||
|
Status Status = Status::Done;
|
||||||
|
size_t Length = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit Socket(Protocol protocol);
|
||||||
|
|
||||||
|
SocketHandle GetHandle() const { return Handle; }
|
||||||
|
|
||||||
|
void Create();
|
||||||
|
void CreateFromHandle(SocketHandle handle);
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SocketHandle Handle;
|
||||||
|
Protocol ProtocolType;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if JULIET_WIN32
|
#if JULIET_WIN32
|
||||||
#include <basetsd.h>
|
#include <basetsd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Juliet
|
|
||||||
{
|
|
||||||
#if JULIET_WIN32
|
#if JULIET_WIN32
|
||||||
using SocketHandle = UINT_PTR;
|
using SocketHandle = UINT_PTR;
|
||||||
#else
|
#else
|
||||||
using SocketHandle = int;
|
using SocketHandle = int;
|
||||||
#endif
|
#endif
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Networking/IPAddress.h>
|
#include <Core/Networking/IPAddress.h>
|
||||||
#include <Core/Networking/Socket.h>
|
#include <Core/Networking/Socket.h>
|
||||||
#include <Core/Networking/TcpSocket.h>
|
#include <Core/Networking/TcpSocket.h>
|
||||||
|
|
||||||
namespace Juliet
|
class TcpListener : public Socket
|
||||||
{
|
{
|
||||||
class TcpListener : public Socket
|
public:
|
||||||
{
|
TcpListener();
|
||||||
public:
|
|
||||||
TcpListener();
|
|
||||||
|
|
||||||
TcpListener(const TcpListener&) = delete;
|
TcpListener(const TcpListener&) = delete;
|
||||||
TcpListener& operator=(const TcpListener&) = delete;
|
TcpListener& operator=(const TcpListener&) = delete;
|
||||||
|
|
||||||
Status Listen(uint16 port, uint32 address = kAnyIp);
|
Status Listen(uint16 port, uint32 address = kAnyIp);
|
||||||
Status Accept(TcpSocket& socket);
|
Status Accept(TcpSocket& socket);
|
||||||
void Close();
|
void Close();
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Networking/Socket.h>
|
#include <Core/Networking/Socket.h>
|
||||||
|
|
||||||
namespace Juliet
|
class NetworkPacket;
|
||||||
|
|
||||||
|
class TcpSocket : public Socket
|
||||||
{
|
{
|
||||||
class NetworkPacket;
|
public:
|
||||||
|
TcpSocket();
|
||||||
|
|
||||||
class TcpSocket : public Socket
|
TcpSocket(const TcpSocket&) = delete;
|
||||||
{
|
TcpSocket& operator=(const TcpSocket&) = delete;
|
||||||
public:
|
|
||||||
TcpSocket();
|
|
||||||
|
|
||||||
TcpSocket(const TcpSocket&) = delete;
|
RequestStatus Send(NetworkPacket& packet);
|
||||||
TcpSocket& operator=(const TcpSocket&) = delete;
|
RequestStatus Send(ByteBuffer buffer);
|
||||||
|
Status Receive(NetworkPacket& outPacket);
|
||||||
|
|
||||||
RequestStatus Send(NetworkPacket& packet);
|
private:
|
||||||
RequestStatus Send(ByteBuffer buffer);
|
friend class TcpListener;
|
||||||
Status Receive(NetworkPacket& outPacket);
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
friend class TcpListener;
|
|
||||||
};
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
using Mutex = std::mutex;
|
||||||
{
|
using LockGuard = std::lock_guard<Mutex>;
|
||||||
using Mutex = std::mutex;
|
|
||||||
using LockGuard = std::lock_guard<Mutex>;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
|
|
||||||
namespace Juliet
|
uint32 thread_id();
|
||||||
|
|
||||||
|
void set_thread_name(String name);
|
||||||
|
|
||||||
|
// TODO : Proper wait
|
||||||
|
inline void wait_ms(int milliseconds)
|
||||||
{
|
{
|
||||||
uint32 thread_id();
|
clock_t start_time = clock();
|
||||||
|
while (clock() < start_time + milliseconds)
|
||||||
void set_thread_name(String name);
|
|
||||||
|
|
||||||
// TODO : Proper wait
|
|
||||||
inline void wait_ms(int milliseconds)
|
|
||||||
{
|
{
|
||||||
clock_t start_time = clock();
|
|
||||||
while (clock() < start_time + milliseconds)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
}
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Memory/MemoryArena.h>
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct thread_context
|
||||||
{
|
{
|
||||||
struct thread_context
|
Arena* ScratchArenas[2];
|
||||||
{
|
|
||||||
Arena* ScratchArenas[2];
|
|
||||||
|
|
||||||
char ThreadName[64];
|
char ThreadName[64];
|
||||||
uint8 ThreadNameSize;
|
uint8 ThreadNameSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_context* thread_context_alloc();
|
thread_context* thread_context_alloc();
|
||||||
void thread_context_release(NonNullPtr<thread_context> ctx);
|
void thread_context_release(NonNullPtr<thread_context> ctx);
|
||||||
void thread_context_select(NonNullPtr<thread_context> ctx);
|
void thread_context_select(NonNullPtr<thread_context> ctx);
|
||||||
thread_context* thread_context_current();
|
thread_context* thread_context_current();
|
||||||
|
|
||||||
Arena* thread_context_get_scratch(Arena** conflicts, size_t count);
|
Arena* thread_context_get_scratch(Arena** conflicts, size_t count);
|
||||||
TempArena scratch_begin(Arena** conflicts, size_t count);
|
TempArena scratch_begin(Arena** conflicts, size_t count);
|
||||||
void scratch_end(TempArena scratch);
|
void scratch_end(TempArena scratch);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Graphics/MeshRenderer.h>
|
#include <Graphics/MeshRenderer.h>
|
||||||
|
|
||||||
namespace Juliet
|
JULIET_API extern MeshAssetID LoadMesh(String filename);
|
||||||
{
|
|
||||||
JULIET_API extern MeshAssetID LoadMesh(String filename);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,33 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CRC32.h>
|
#include <Core/Common/CRC32.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Class
|
||||||
{
|
{
|
||||||
struct Class
|
uint32 CRC;
|
||||||
|
#if JULIET_DEBUG
|
||||||
|
// TODO: string struct may be
|
||||||
|
const char* Name;
|
||||||
|
size_t Name_Length;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
consteval Class(const char* className, size_t name_length)
|
||||||
{
|
{
|
||||||
uint32 CRC;
|
CRC = crc32(className, name_length);
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
// TODO: string struct may be
|
// TODO: string struct may be
|
||||||
const char* Name;
|
Name = className;
|
||||||
size_t Name_Length;
|
Name_Length = name_length;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
consteval Class(const char* className, size_t name_length)
|
|
||||||
{
|
|
||||||
CRC = crc32(className, name_length);
|
|
||||||
#if JULIET_DEBUG
|
|
||||||
// TODO: string struct may be
|
|
||||||
Name = className;
|
|
||||||
Name_Length = name_length;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename type>
|
|
||||||
bool IsA(Class& cls)
|
|
||||||
{
|
|
||||||
return cls.CRC == type::StaticClass->CRC;
|
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
};
|
||||||
|
|
||||||
|
template <typename type>
|
||||||
|
bool IsA(Class& cls)
|
||||||
|
{
|
||||||
|
return cls.CRC == type::StaticClass->CRC;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
|
|
||||||
namespace Juliet::Debug
|
namespace Debug
|
||||||
{
|
{
|
||||||
JULIET_API void DebugDrawMemoryArena();
|
JULIET_API void DebugDrawMemoryArena();
|
||||||
} // namespace Juliet::Debug
|
} // namespace Debug
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Application/IApplication.h>
|
#include <Core/Application/IApplication.h>
|
||||||
|
|
||||||
namespace Juliet
|
enum class JulietInit_Flags : uint8;
|
||||||
|
|
||||||
|
struct Engine
|
||||||
{
|
{
|
||||||
enum class JulietInit_Flags : uint8;
|
IApplication* Application = nullptr;
|
||||||
|
Arena* PlatformArena = nullptr;
|
||||||
|
Arena* AssetArena = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct Engine
|
void InitializeEngine(JulietInit_Flags flags);
|
||||||
{
|
void ShutdownEngine();
|
||||||
IApplication* Application = nullptr;
|
|
||||||
Arena* PlatformArena = nullptr;
|
|
||||||
Arena* AssetArena = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
void InitializeEngine(JulietInit_Flags flags);
|
void LoadApplication(IApplication& app);
|
||||||
void ShutdownEngine();
|
void UnloadApplication();
|
||||||
|
|
||||||
void LoadApplication(IApplication& app);
|
void RunEngine();
|
||||||
void UnloadApplication();
|
|
||||||
|
|
||||||
void RunEngine();
|
extern Arena* GetPlatformArena();
|
||||||
|
|
||||||
extern Arena* GetPlatformArena();
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,38 +1,35 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Math/Matrix.h>
|
#include <Core/Math/Matrix.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Camera
|
||||||
{
|
{
|
||||||
struct Camera
|
index_t Index;
|
||||||
{
|
Vector3 Position;
|
||||||
index_t Index;
|
Vector3 Target;
|
||||||
Vector3 Position;
|
Vector3 Up;
|
||||||
Vector3 Target;
|
float FOV; // In radians
|
||||||
Vector3 Up;
|
float AspectRatio;
|
||||||
float FOV; // In radians
|
float NearPlane;
|
||||||
float AspectRatio;
|
float FarPlane;
|
||||||
float NearPlane;
|
};
|
||||||
float FarPlane;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline Matrix Camera_GetViewMatrix(const Camera& cam)
|
inline Matrix Camera_GetViewMatrix(const Camera& cam)
|
||||||
{
|
{
|
||||||
return LookAt(cam.Position, cam.Target, cam.Up);
|
return LookAt(cam.Position, cam.Target, cam.Up);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix Camera_GetProjectionMatrix(const Camera& cam)
|
inline Matrix Camera_GetProjectionMatrix(const Camera& cam)
|
||||||
{
|
{
|
||||||
return PerspectiveFov(cam.FOV, cam.AspectRatio, cam.NearPlane, cam.FarPlane);
|
return PerspectiveFov(cam.FOV, cam.AspectRatio, cam.NearPlane, cam.FarPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix Camera_GetViewProjectionMatrix(const Camera& cam)
|
inline Matrix Camera_GetViewProjectionMatrix(const Camera& cam)
|
||||||
{
|
{
|
||||||
return Camera_GetProjectionMatrix(cam) * Camera_GetViewMatrix(cam);
|
return Camera_GetProjectionMatrix(cam) * Camera_GetViewMatrix(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
JULIET_API extern void ReserveCamera(size_t amount);
|
JULIET_API extern void ReserveCamera(size_t amount);
|
||||||
JULIET_API extern Camera* GetCurrentCamera();
|
JULIET_API extern Camera* GetCurrentCamera();
|
||||||
JULIET_API extern void SetCurrentCamera(index_t index);
|
JULIET_API extern void SetCurrentCamera(index_t index);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
template <typename Type>
|
||||||
|
struct ColorType
|
||||||
{
|
{
|
||||||
template <typename Type>
|
Type R;
|
||||||
struct ColorType
|
Type G;
|
||||||
{
|
Type B;
|
||||||
Type R;
|
Type A;
|
||||||
Type G;
|
};
|
||||||
Type B;
|
|
||||||
Type A;
|
|
||||||
};
|
|
||||||
|
|
||||||
using FColor = ColorType<float>;
|
using FColor = ColorType<float>;
|
||||||
using Color = ColorType<uint8>;
|
using Color = ColorType<uint8>;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Math/Vector.h>
|
#include <Core/Math/Vector.h>
|
||||||
#include <Graphics/Camera.h>
|
#include <Graphics/Camera.h>
|
||||||
@@ -6,12 +6,9 @@
|
|||||||
#include <Graphics/Graphics.h>
|
#include <Graphics/Graphics.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
extern JULIET_API void DebugDisplay_Initialize(NonNullPtr<Arena> arena, GraphicsDevice* device);
|
||||||
{
|
extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device);
|
||||||
extern JULIET_API void DebugDisplay_Initialize(NonNullPtr<Arena> arena, GraphicsDevice* device);
|
extern JULIET_API void DebugDisplay_DrawLine(const Vector3& start, const Vector3& end, const FColor& color, bool overlay);
|
||||||
extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device);
|
extern JULIET_API void DebugDisplay_DrawSphere(const Vector3& center, float radius, const FColor& color, bool overlay);
|
||||||
extern JULIET_API void DebugDisplay_DrawLine(const Vector3& start, const Vector3& end, const FColor& color, bool overlay);
|
extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList);
|
||||||
extern JULIET_API void DebugDisplay_DrawSphere(const Vector3& center, float radius, const FColor& color, bool overlay);
|
extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera& camera);
|
||||||
extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList);
|
|
||||||
extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera& camera);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
+134
-137
@@ -12,166 +12,163 @@
|
|||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
// Graphics Interface
|
// Graphics Interface
|
||||||
namespace Juliet
|
// Opaque types
|
||||||
|
struct CommandList;
|
||||||
|
struct GraphicsDevice;
|
||||||
|
struct Fence;
|
||||||
|
|
||||||
|
// Parameters of an indirect draw command
|
||||||
|
struct IndirectDrawCommand
|
||||||
{
|
{
|
||||||
// Opaque types
|
uint32 VertexCount; // Number of vertices to draw
|
||||||
struct CommandList;
|
uint32 InstanceCount; // Number of instanced to draw
|
||||||
struct GraphicsDevice;
|
uint32 FirstVertex; // Index of the first vertex to draw
|
||||||
struct Fence;
|
uint32 FirstInstance; // ID of the first instance to draw
|
||||||
|
};
|
||||||
|
|
||||||
// Parameters of an indirect draw command
|
// Parameters of an INDEXED indirect draw command
|
||||||
struct IndirectDrawCommand
|
struct IndexedIndirectDrawCommand
|
||||||
{
|
{
|
||||||
uint32 VertexCount; // Number of vertices to draw
|
uint32 VertexCount; // Number of vertices to draw
|
||||||
uint32 InstanceCount; // Number of instanced to draw
|
uint32 InstanceCount; // Number of instanced to draw
|
||||||
uint32 FirstVertex; // Index of the first vertex to draw
|
uint32 FirstIndex; // Base Index within the index buffer
|
||||||
uint32 FirstInstance; // ID of the first instance to draw
|
int32 VertexOffset; // Offset the vertex index into the buffer
|
||||||
};
|
uint32 FirstInstance; // ID of the first instance to draw
|
||||||
|
};
|
||||||
|
|
||||||
// Parameters of an INDEXED indirect draw command
|
// Parameters of an INDEXED Indirect Dispatch Command
|
||||||
struct IndexedIndirectDrawCommand
|
struct IndirectDispatchCommand
|
||||||
{
|
{
|
||||||
uint32 VertexCount; // Number of vertices to draw
|
uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X
|
||||||
uint32 InstanceCount; // Number of instanced to draw
|
uint32 Y_WorkGroupCount; // Number of Workgroup to dispatch on dimension Y
|
||||||
uint32 FirstIndex; // Base Index within the index buffer
|
uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z
|
||||||
int32 VertexOffset; // Offset the vertex index into the buffer
|
};
|
||||||
uint32 FirstInstance; // ID of the first instance to draw
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parameters of an INDEXED Indirect Dispatch Command
|
enum class QueueType : uint8
|
||||||
struct IndirectDispatchCommand
|
{
|
||||||
{
|
Graphics = 0,
|
||||||
uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X
|
Compute,
|
||||||
uint32 Y_WorkGroupCount; // Number of Workgroup to dispatch on dimension Y
|
Copy,
|
||||||
uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class QueueType : uint8
|
enum class IndexFormat : uint8
|
||||||
{
|
{
|
||||||
Graphics = 0,
|
UInt16,
|
||||||
Compute,
|
UInt32
|
||||||
Copy,
|
};
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class IndexFormat : uint8
|
enum struct SwapChainComposition : uint8
|
||||||
{
|
{
|
||||||
UInt16,
|
SDR,
|
||||||
UInt32
|
SDR_LINEAR,
|
||||||
};
|
HDR_EXTENDED_LINEAR,
|
||||||
|
HDR10_ST2084
|
||||||
|
};
|
||||||
|
|
||||||
enum struct SwapChainComposition : uint8
|
// PresentMode from highest to lowest latency
|
||||||
{
|
// Vsync prevents tearing. Enqueue ready images.
|
||||||
SDR,
|
// Mailbox prevents tearing. When image is ready, replace any pending image
|
||||||
SDR_LINEAR,
|
// Immediate replace current image as soon as possible. Can cause tearing
|
||||||
HDR_EXTENDED_LINEAR,
|
enum struct PresentMode : uint8
|
||||||
HDR10_ST2084
|
{
|
||||||
};
|
VSync,
|
||||||
|
Mailbox,
|
||||||
|
Immediate
|
||||||
|
};
|
||||||
|
|
||||||
// PresentMode from highest to lowest latency
|
struct GraphicsViewPort
|
||||||
// Vsync prevents tearing. Enqueue ready images.
|
{
|
||||||
// Mailbox prevents tearing. When image is ready, replace any pending image
|
float X;
|
||||||
// Immediate replace current image as soon as possible. Can cause tearing
|
float Y;
|
||||||
enum struct PresentMode : uint8
|
float Width;
|
||||||
{
|
float Height;
|
||||||
VSync,
|
float MinDepth;
|
||||||
Mailbox,
|
float MaxDepth;
|
||||||
Immediate
|
};
|
||||||
};
|
|
||||||
|
|
||||||
struct GraphicsViewPort
|
extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config);
|
||||||
{
|
extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device);
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
float Width;
|
|
||||||
float Height;
|
|
||||||
float MinDepth;
|
|
||||||
float MaxDepth;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config);
|
// Attach To Window
|
||||||
extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device);
|
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
|
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
|
|
||||||
// Attach To Window
|
// SwapChain
|
||||||
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window,
|
||||||
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
Texture** swapChainTexture);
|
||||||
|
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList,
|
||||||
|
NonNullPtr<Window> window, Texture** swapChainTexture);
|
||||||
|
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
|
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
|
|
||||||
// SwapChain
|
// Textures
|
||||||
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window,
|
extern JULIET_API Texture* CreateTexture(NonNullPtr<GraphicsDevice> device, const TextureCreateInfo& createInfo);
|
||||||
Texture** swapChainTexture);
|
extern JULIET_API void DestroyTexture(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
|
||||||
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList,
|
|
||||||
NonNullPtr<Window> window, Texture** swapChainTexture);
|
|
||||||
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
|
||||||
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
|
||||||
|
|
||||||
// Textures
|
// Command List
|
||||||
extern JULIET_API Texture* CreateTexture(NonNullPtr<GraphicsDevice> device, const TextureCreateInfo& createInfo);
|
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
|
||||||
extern JULIET_API void DestroyTexture(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
|
extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList);
|
||||||
|
|
||||||
// Command List
|
// RenderPass
|
||||||
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
|
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo,
|
||||||
extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList);
|
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
|
||||||
|
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList,
|
||||||
|
NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount,
|
||||||
|
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
|
||||||
|
extern JULIET_API void EndRenderPass(NonNullPtr<RenderPass> renderPass);
|
||||||
|
|
||||||
// RenderPass
|
extern JULIET_API void SetGraphicsViewPort(NonNullPtr<RenderPass> renderPass, const GraphicsViewPort& viewPort);
|
||||||
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo,
|
extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const struct Rectangle& rectangle);
|
||||||
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
|
extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants);
|
||||||
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList,
|
extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference);
|
||||||
NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount,
|
|
||||||
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
|
|
||||||
extern JULIET_API void EndRenderPass(NonNullPtr<RenderPass> renderPass);
|
|
||||||
|
|
||||||
extern JULIET_API void SetGraphicsViewPort(NonNullPtr<RenderPass> renderPass, const GraphicsViewPort& viewPort);
|
extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
||||||
extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const Rectangle& rectangle);
|
extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances,
|
||||||
extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants);
|
uint32 firstVertex, uint32 firstInstance);
|
||||||
extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference);
|
extern JULIET_API void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances,
|
||||||
|
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
|
||||||
|
|
||||||
extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
extern JULIET_API void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer,
|
||||||
extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances,
|
IndexFormat format, size_t indexCount, index_t offset);
|
||||||
uint32 firstVertex, uint32 firstInstance);
|
|
||||||
extern JULIET_API void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances,
|
|
||||||
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
|
|
||||||
|
|
||||||
extern JULIET_API void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer,
|
extern JULIET_API void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage,
|
||||||
IndexFormat format, size_t indexCount, index_t offset);
|
uint32 rootParameterIndex, uint32 numConstants, const void* constants);
|
||||||
|
|
||||||
extern JULIET_API void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage,
|
// Fences
|
||||||
uint32 rootParameterIndex, uint32 numConstants, const void* constants);
|
extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device);
|
||||||
|
|
||||||
// Fences
|
// Shaders
|
||||||
extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device);
|
extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo);
|
||||||
|
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader);
|
||||||
|
|
||||||
// Shaders
|
// Pipelines
|
||||||
extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo);
|
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
|
||||||
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader);
|
const GraphicsPipelineCreateInfo& createInfo);
|
||||||
|
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
||||||
// Pipelines
|
|
||||||
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
|
|
||||||
const GraphicsPipelineCreateInfo& createInfo);
|
|
||||||
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
// Allows updating the graphics pipeline shaders. Can update either one or both shaders.
|
// Allows updating the graphics pipeline shaders. Can update either one or both shaders.
|
||||||
extern JULIET_API bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline,
|
extern JULIET_API bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline,
|
||||||
Shader* optional_vertexShader, Shader* optional_fragmentShader);
|
Shader* optional_vertexShader, Shader* optional_fragmentShader);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Buffers
|
// Buffers
|
||||||
extern JULIET_API GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo);
|
extern JULIET_API GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo);
|
||||||
extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device,
|
extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device,
|
||||||
const TransferBufferCreateInfo& createInfo);
|
const TransferBufferCreateInfo& createInfo);
|
||||||
extern JULIET_API void* MapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
extern JULIET_API void* MapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
extern JULIET_API void UnmapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
extern JULIET_API void UnmapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
extern JULIET_API void* MapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
extern JULIET_API void* MapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||||
extern JULIET_API void UnmapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
extern JULIET_API void UnmapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||||
extern JULIET_API void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
extern JULIET_API void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||||
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset = 0,
|
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset = 0,
|
||||||
size_t srcOffset = 0);
|
size_t srcOffset = 0);
|
||||||
extern JULIET_API void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst,
|
extern JULIET_API void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst,
|
||||||
NonNullPtr<GraphicsTransferBuffer> src);
|
NonNullPtr<GraphicsTransferBuffer> src);
|
||||||
|
|
||||||
extern JULIET_API void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
|
extern JULIET_API void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
|
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
|
||||||
|
|
||||||
extern JULIET_API void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
extern JULIET_API void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
extern JULIET_API void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
extern JULIET_API void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,36 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
enum class BufferUsage : uint8
|
||||||
{
|
{
|
||||||
enum class BufferUsage : uint8
|
None = 0,
|
||||||
{
|
IndexBuffer = 1 << 0,
|
||||||
None = 0,
|
ConstantBuffer = 1 << 1,
|
||||||
IndexBuffer = 1 << 0,
|
StructuredBuffer = 1 << 2,
|
||||||
ConstantBuffer = 1 << 1,
|
};
|
||||||
StructuredBuffer = 1 << 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TransferBufferUsage : uint8
|
enum class TransferBufferUsage : uint8
|
||||||
{
|
{
|
||||||
Download,
|
Download,
|
||||||
Upload
|
Upload
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferCreateInfo
|
struct BufferCreateInfo
|
||||||
{
|
{
|
||||||
size_t Size;
|
size_t Size;
|
||||||
size_t Stride;
|
size_t Stride;
|
||||||
BufferUsage Usage;
|
BufferUsage Usage;
|
||||||
bool IsDynamic;
|
bool IsDynamic;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransferBufferCreateInfo
|
struct TransferBufferCreateInfo
|
||||||
{
|
{
|
||||||
size_t Size;
|
size_t Size;
|
||||||
TransferBufferUsage Usage;
|
TransferBufferUsage Usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Opaque
|
// Opaque
|
||||||
struct GraphicsBuffer;
|
struct GraphicsBuffer;
|
||||||
struct GraphicsTransferBuffer;
|
struct GraphicsTransferBuffer;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -10,17 +10,14 @@
|
|||||||
#define ALLOW_SHADER_HOT_RELOAD 0
|
#define ALLOW_SHADER_HOT_RELOAD 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Juliet
|
enum class GraphicsDriverType : uint8
|
||||||
{
|
{
|
||||||
enum class DriverType : uint8
|
Any = 0,
|
||||||
{
|
DX12 = 1,
|
||||||
Any = 0,
|
};
|
||||||
DX12 = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GraphicsConfig
|
struct GraphicsConfig
|
||||||
{
|
{
|
||||||
DriverType PreferredDriver = DriverType::DX12;
|
GraphicsDriverType PreferredDriver = GraphicsDriverType::DX12;
|
||||||
bool EnableDebug;
|
bool EnableDebug;
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,225 +1,222 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Graphics/Shader.h>
|
#include <Graphics/Shader.h>
|
||||||
#include <Graphics/Texture.h>
|
#include <Graphics/Texture.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Forward Declare
|
||||||
|
struct ColorTargetDescription;
|
||||||
|
|
||||||
|
enum class FillMode : uint8
|
||||||
{
|
{
|
||||||
// Forward Declare
|
Solid,
|
||||||
struct ColorTargetDescription;
|
Wireframe,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
enum class FillMode : uint8
|
enum class CullMode : uint8
|
||||||
{
|
{
|
||||||
Solid,
|
None,
|
||||||
Wireframe,
|
Front,
|
||||||
Count
|
Back,
|
||||||
};
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
enum class CullMode : uint8
|
enum class FrontFace : uint8
|
||||||
{
|
{
|
||||||
None,
|
CounterClockwise,
|
||||||
Front,
|
Clockwise,
|
||||||
Back,
|
Count
|
||||||
Count
|
};
|
||||||
};
|
|
||||||
|
|
||||||
enum class FrontFace : uint8
|
enum class PrimitiveType : uint8
|
||||||
{
|
{
|
||||||
CounterClockwise,
|
TriangleList,
|
||||||
Clockwise,
|
TriangleStrip,
|
||||||
Count
|
LineList,
|
||||||
};
|
LineStrip,
|
||||||
|
PointList,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
enum class PrimitiveType : uint8
|
struct RasterizerState
|
||||||
{
|
{
|
||||||
TriangleList,
|
FillMode FillMode;
|
||||||
TriangleStrip,
|
CullMode CullMode;
|
||||||
LineList,
|
FrontFace FrontFace;
|
||||||
LineStrip,
|
|
||||||
PointList,
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RasterizerState
|
float DepthBiasConstantFactor; // How much depth value is added to each fragment
|
||||||
{
|
float DepthBiasClamp; // Maximum depth bias
|
||||||
FillMode FillMode;
|
float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope
|
||||||
CullMode CullMode;
|
bool EnableDepthBias; // Bias fragment depth values
|
||||||
FrontFace FrontFace;
|
bool EnableDepthClip; // True to clip, false to clamp
|
||||||
|
};
|
||||||
|
|
||||||
float DepthBiasConstantFactor; // How much depth value is added to each fragment
|
enum class VertexInputRate : uint8
|
||||||
float DepthBiasClamp; // Maximum depth bias
|
{
|
||||||
float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope
|
Vertex, // Use vertex index
|
||||||
bool EnableDepthBias; // Bias fragment depth values
|
Instance, // Use instance index
|
||||||
bool EnableDepthClip; // True to clip, false to clamp
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class VertexInputRate : uint8
|
struct VertexBufferDescription
|
||||||
{
|
{
|
||||||
Vertex, // Use vertex index
|
uint32 Slot; // Binding Slot
|
||||||
Instance, // Use instance index
|
uint32 PitchInBytes; // Pitch between two elements
|
||||||
Count
|
VertexInputRate InputRate;
|
||||||
};
|
uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1
|
||||||
|
};
|
||||||
|
|
||||||
struct VertexBufferDescription
|
enum class VertexElementFormat : uint8
|
||||||
{
|
{
|
||||||
uint32 Slot; // Binding Slot
|
Invalid,
|
||||||
uint32 PitchInBytes; // Pitch between two elements
|
|
||||||
VertexInputRate InputRate;
|
|
||||||
uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class VertexElementFormat : uint8
|
/* 32-bit Signed Integers */
|
||||||
{
|
Int,
|
||||||
Invalid,
|
Int2,
|
||||||
|
Int3,
|
||||||
|
Int4,
|
||||||
|
|
||||||
/* 32-bit Signed Integers */
|
/* 32-bit Unsigned Integers */
|
||||||
Int,
|
UInt,
|
||||||
Int2,
|
UInt2,
|
||||||
Int3,
|
UInt3,
|
||||||
Int4,
|
UInt4,
|
||||||
|
|
||||||
/* 32-bit Unsigned Integers */
|
/* 32-bit Floats */
|
||||||
UInt,
|
Float,
|
||||||
UInt2,
|
Float2,
|
||||||
UInt3,
|
Float3,
|
||||||
UInt4,
|
Float4,
|
||||||
|
|
||||||
/* 32-bit Floats */
|
/* 8-bit Signed Integers */
|
||||||
Float,
|
Byte2,
|
||||||
Float2,
|
Byte4,
|
||||||
Float3,
|
|
||||||
Float4,
|
|
||||||
|
|
||||||
/* 8-bit Signed Integers */
|
/* 8-bit Unsigned Integers */
|
||||||
Byte2,
|
UByte2,
|
||||||
Byte4,
|
UByte4,
|
||||||
|
|
||||||
/* 8-bit Unsigned Integers */
|
/* 8-bit Signed Normalized */
|
||||||
UByte2,
|
Byte2_Norm,
|
||||||
UByte4,
|
Byte4_Norm,
|
||||||
|
|
||||||
/* 8-bit Signed Normalized */
|
/* 8-bit Unsigned Normalized */
|
||||||
Byte2_Norm,
|
UByte2_Norm,
|
||||||
Byte4_Norm,
|
UByte4_Norm,
|
||||||
|
|
||||||
/* 8-bit Unsigned Normalized */
|
/* 16-bit Signed Integers */
|
||||||
UByte2_Norm,
|
Short2,
|
||||||
UByte4_Norm,
|
Short4,
|
||||||
|
|
||||||
/* 16-bit Signed Integers */
|
/* 16-bit Unsigned Integers */
|
||||||
Short2,
|
UShort2,
|
||||||
Short4,
|
UShort4,
|
||||||
|
|
||||||
/* 16-bit Unsigned Integers */
|
/* 16-bit Signed Normalized */
|
||||||
UShort2,
|
Short2_Norm,
|
||||||
UShort4,
|
Short4_Norm,
|
||||||
|
|
||||||
/* 16-bit Signed Normalized */
|
/* 16-bit Unsigned Normalized */
|
||||||
Short2_Norm,
|
UShort2_Norm,
|
||||||
Short4_Norm,
|
UShort4_Norm,
|
||||||
|
|
||||||
/* 16-bit Unsigned Normalized */
|
/* 16-bit Floats */
|
||||||
UShort2_Norm,
|
Half2,
|
||||||
UShort4_Norm,
|
Half4,
|
||||||
|
|
||||||
/* 16-bit Floats */
|
//
|
||||||
Half2,
|
Count
|
||||||
Half4,
|
};
|
||||||
|
|
||||||
//
|
struct VertexAttribute
|
||||||
Count
|
{
|
||||||
};
|
uint32 Location; // Shader input location index
|
||||||
|
uint32 BufferSlot; // Binding slot of associated vertex buffer
|
||||||
|
VertexElementFormat Format; // Size and type of attribute
|
||||||
|
uint32 Offset; // Offset of this attribute relative to the start of the vertex element
|
||||||
|
};
|
||||||
|
|
||||||
struct VertexAttribute
|
struct VertexInputState
|
||||||
{
|
{
|
||||||
uint32 Location; // Shader input location index
|
const VertexBufferDescription* VertexBufferDescriptions;
|
||||||
uint32 BufferSlot; // Binding slot of associated vertex buffer
|
uint32 NumVertexBufferDescriptions;
|
||||||
VertexElementFormat Format; // Size and type of attribute
|
const VertexAttribute* VertexAttributes;
|
||||||
uint32 Offset; // Offset of this attribute relative to the start of the vertex element
|
uint32 NumVertexAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexInputState
|
struct GraphicsPipelineTargetInfo
|
||||||
{
|
{
|
||||||
const VertexBufferDescription* VertexBufferDescriptions;
|
const ColorTargetDescription* ColorTargetDescriptions;
|
||||||
uint32 NumVertexBufferDescriptions;
|
size_t NumColorTargets;
|
||||||
const VertexAttribute* VertexAttributes;
|
TextureFormat DepthStencilFormat;
|
||||||
uint32 NumVertexAttributes;
|
bool HasDepthStencilTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GraphicsPipelineTargetInfo
|
enum class CompareOperation : uint8
|
||||||
{
|
{
|
||||||
const ColorTargetDescription* ColorTargetDescriptions;
|
Invalid,
|
||||||
size_t NumColorTargets;
|
Never, // The comparison always evaluates false.
|
||||||
TextureFormat DepthStencilFormat;
|
Less, // The comparison evaluates reference < test.
|
||||||
bool HasDepthStencilTarget;
|
Equal, // The comparison evaluates reference == test.
|
||||||
};
|
LessOrEqual, // The comparison evaluates reference <= test.
|
||||||
|
Greater, // The comparison evaluates reference > test.
|
||||||
|
NotEqual, // The comparison evaluates reference != test.
|
||||||
|
GreaterOrEqual, // The comparison evalutes reference >= test.
|
||||||
|
Always, // The comparison always evaluates true.
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
enum class CompareOperation : uint8
|
enum class StencilOperation : uint8
|
||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
Never, // The comparison always evaluates false.
|
Keep, // Keeps the current value.
|
||||||
Less, // The comparison evaluates reference < test.
|
Zero, // Sets the value to 0.
|
||||||
Equal, // The comparison evaluates reference == test.
|
Replace, // Sets the value to reference.
|
||||||
LessOrEqual, // The comparison evaluates reference <= test.
|
IncrementAndClamp, // Increments the current value and clamps to the maximum value.
|
||||||
Greater, // The comparison evaluates reference > test.
|
DecrementAndClamp, // Decrements the current value and clamps to 0.
|
||||||
NotEqual, // The comparison evaluates reference != test.
|
Invert, // Bitwise-inverts the current value.
|
||||||
GreaterOrEqual, // The comparison evalutes reference >= test.
|
IncrementAndWrap, // Increments the current value and wraps back to 0.
|
||||||
Always, // The comparison always evaluates true.
|
DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
|
||||||
Count
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class StencilOperation : uint8
|
struct StencilOperationState
|
||||||
{
|
{
|
||||||
Invalid,
|
StencilOperation FailOperation; // The action performed on samples that fail the stencil test.
|
||||||
Keep, // Keeps the current value.
|
StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests.
|
||||||
Zero, // Sets the value to 0.
|
StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test.
|
||||||
Replace, // Sets the value to reference.
|
StencilOperation CompareOperation; // The comparison operator used in the stencil test.
|
||||||
IncrementAndClamp, // Increments the current value and clamps to the maximum value.
|
};
|
||||||
DecrementAndClamp, // Decrements the current value and clamps to 0.
|
|
||||||
Invert, // Bitwise-inverts the current value.
|
|
||||||
IncrementAndWrap, // Increments the current value and wraps back to 0.
|
|
||||||
DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StencilOperationState
|
struct DepthStencilState
|
||||||
{
|
{
|
||||||
StencilOperation FailOperation; // The action performed on samples that fail the stencil test.
|
CompareOperation CompareOperation; // The comparison operator used for depth testing.
|
||||||
StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests.
|
StencilOperationState BackStencilState; // The stencil op state for back-facing triangles.
|
||||||
StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test.
|
StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles.
|
||||||
StencilOperation CompareOperation; // The comparison operator used in the stencil test.
|
uint8 CompareMask; // Selects the bits of the stencil values participating in the stencil test.
|
||||||
};
|
uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
|
||||||
|
bool EnableDepthTest : 1; // true enables the depth test.
|
||||||
|
bool EnableDepthWrite : 1; // true enables depth writes. Depth writes are always disabled when enable_depth_test is false.
|
||||||
|
bool EnableStencilTest : 1; // true enables the stencil test.
|
||||||
|
};
|
||||||
|
|
||||||
struct DepthStencilState
|
struct MultisampleState
|
||||||
{
|
{
|
||||||
CompareOperation CompareOperation; // The comparison operator used for depth testing.
|
TextureSampleCount SampleCount;
|
||||||
StencilOperationState BackStencilState; // The stencil op state for back-facing triangles.
|
uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF
|
||||||
StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles.
|
bool EnableMask;
|
||||||
uint8 CompareMask; // Selects the bits of the stencil values participating in the stencil test.
|
};
|
||||||
uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
|
|
||||||
bool EnableDepthTest : 1; // true enables the depth test.
|
|
||||||
bool EnableDepthWrite : 1; // true enables depth writes. Depth writes are always disabled when enable_depth_test is false.
|
|
||||||
bool EnableStencilTest : 1; // true enables the stencil test.
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MultisampleState
|
struct GraphicsPipelineCreateInfo
|
||||||
{
|
{
|
||||||
TextureSampleCount SampleCount;
|
Shader* VertexShader;
|
||||||
uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF
|
Shader* FragmentShader;
|
||||||
bool EnableMask;
|
PrimitiveType PrimitiveType;
|
||||||
};
|
GraphicsPipelineTargetInfo TargetInfo;
|
||||||
|
RasterizerState RasterizerState;
|
||||||
|
MultisampleState MultisampleState;
|
||||||
|
VertexInputState VertexInputState;
|
||||||
|
DepthStencilState DepthStencilState;
|
||||||
|
};
|
||||||
|
|
||||||
struct GraphicsPipelineCreateInfo
|
// Opaque type
|
||||||
{
|
struct GraphicsPipeline;
|
||||||
Shader* VertexShader;
|
|
||||||
Shader* FragmentShader;
|
|
||||||
PrimitiveType PrimitiveType;
|
|
||||||
GraphicsPipelineTargetInfo TargetInfo;
|
|
||||||
RasterizerState RasterizerState;
|
|
||||||
MultisampleState MultisampleState;
|
|
||||||
VertexInputState VertexInputState;
|
|
||||||
DepthStencilState DepthStencilState;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Opaque type
|
|
||||||
struct GraphicsPipeline;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Graphics/Graphics.h>
|
#include <Graphics/Graphics.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
extern bool ImGuiRenderer_Initialize(GraphicsDevice* device);
|
||||||
{
|
extern void ImGuiRenderer_Shutdown(GraphicsDevice* device);
|
||||||
extern bool ImGuiRenderer_Initialize(GraphicsDevice* device);
|
extern void ImGuiRenderer_NewFrame();
|
||||||
extern void ImGuiRenderer_Shutdown(GraphicsDevice* device);
|
extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass);
|
||||||
extern void ImGuiRenderer_NewFrame();
|
|
||||||
extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
#include <Core/Math/Vector.h>
|
#include <Core/Math/Vector.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct PointLight
|
||||||
{
|
{
|
||||||
struct PointLight
|
Vector3 Position;
|
||||||
{
|
float Radius;
|
||||||
Vector3 Position;
|
Vector3 Color;
|
||||||
float Radius;
|
float Intensity;
|
||||||
Vector3 Color;
|
};
|
||||||
float Intensity;
|
|
||||||
};
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
@@ -7,34 +7,31 @@
|
|||||||
#include <Core/Math/Vector.h>
|
#include <Core/Math/Vector.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Arena;
|
||||||
|
struct Vertex;
|
||||||
|
|
||||||
|
using MeshAssetID = index_t;
|
||||||
|
using MaterialAssetID = index_t;
|
||||||
|
using MeshInstanceID = index_t;
|
||||||
|
|
||||||
|
struct MeshAsset
|
||||||
{
|
{
|
||||||
struct Arena;
|
String Name;
|
||||||
struct Vertex;
|
size_t VertexCount;
|
||||||
|
size_t IndexCount;
|
||||||
|
|
||||||
using MeshAssetID = index_t;
|
index_t VertexOffset;
|
||||||
using MaterialAssetID = index_t;
|
index_t IndexOffset;
|
||||||
using MeshInstanceID = index_t;
|
};
|
||||||
|
|
||||||
struct MeshAsset
|
struct MaterialAsset
|
||||||
{
|
{
|
||||||
String Name;
|
Vector4 AlbedoColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
size_t VertexCount;
|
};
|
||||||
size_t IndexCount;
|
|
||||||
|
|
||||||
index_t VertexOffset;
|
struct MeshInstance
|
||||||
index_t IndexOffset;
|
{
|
||||||
};
|
MeshAssetID MeshAsset;
|
||||||
|
MaterialAssetID MaterialAsset;
|
||||||
struct MaterialAsset
|
Matrix Transform = MatrixIdentity();
|
||||||
{
|
};
|
||||||
Vector4 AlbedoColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MeshInstance
|
|
||||||
{
|
|
||||||
MeshAssetID MeshAsset;
|
|
||||||
MaterialAssetID MaterialAsset;
|
|
||||||
Matrix Transform = MatrixIdentity();
|
|
||||||
};
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Container/Vector.h>
|
#include <Core/Container/Vector.h>
|
||||||
#include <Core/Math/Matrix.h>
|
#include <Core/Math/Matrix.h>
|
||||||
@@ -9,52 +9,49 @@
|
|||||||
#include <Graphics/Mesh.h>
|
#include <Graphics/Mesh.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct GraphicsTransferBuffer;
|
||||||
{
|
struct RenderPass;
|
||||||
struct GraphicsTransferBuffer;
|
struct CommandList;
|
||||||
struct RenderPass;
|
struct GraphicsBuffer;
|
||||||
struct CommandList;
|
struct Window;
|
||||||
struct GraphicsBuffer;
|
struct GraphicsPipeline;
|
||||||
struct Window;
|
struct GraphicsDevice;
|
||||||
struct GraphicsPipeline;
|
using LightID = index_t;
|
||||||
struct GraphicsDevice;
|
|
||||||
using LightID = index_t;
|
|
||||||
|
|
||||||
constexpr size_t kGeometryPage = Megabytes(64);
|
constexpr size_t kGeometryPage = Megabytes(64);
|
||||||
constexpr size_t kIndexPage = Megabytes(32);
|
constexpr size_t kIndexPage = Megabytes(32);
|
||||||
constexpr size_t kDefaultMeshNumber = 500;
|
constexpr size_t kDefaultMeshNumber = 500;
|
||||||
constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page
|
constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page
|
||||||
constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page
|
constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page
|
||||||
constexpr size_t kDefaultLightCount = 1024;
|
constexpr size_t kDefaultLightCount = 1024;
|
||||||
|
|
||||||
JULIET_API void InitializeMeshRenderer(NonNullPtr<Arena> assetArena, NonNullPtr<Arena> instanceArena);
|
JULIET_API void InitializeMeshRenderer(NonNullPtr<Arena> assetArena, NonNullPtr<Arena> instanceArena);
|
||||||
[[nodiscard]] JULIET_API bool InitializeMeshRendererGraphics(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
[[nodiscard]] JULIET_API bool InitializeMeshRendererGraphics(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
JULIET_API void ShutdownMeshRendererGraphics();
|
JULIET_API void ShutdownMeshRendererGraphics();
|
||||||
JULIET_API void ShutdownMeshRenderer();
|
JULIET_API void ShutdownMeshRenderer();
|
||||||
JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList);
|
JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList);
|
||||||
JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
|
JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
|
||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
[[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light);
|
[[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light);
|
||||||
JULIET_API void SetPointLightPosition(LightID id, const Vector3& position);
|
JULIET_API void SetPointLightPosition(LightID id, const Vector3& position);
|
||||||
JULIET_API void SetPointLightColor(LightID id, const Vector3& color);
|
JULIET_API void SetPointLightColor(LightID id, const Vector3& color);
|
||||||
JULIET_API void SetPointLightRadius(LightID id, float radius);
|
JULIET_API void SetPointLightRadius(LightID id, float radius);
|
||||||
JULIET_API void SetPointLightIntensity(LightID id, float intensity);
|
JULIET_API void SetPointLightIntensity(LightID id, float intensity);
|
||||||
JULIET_API void ClearPointLights();
|
JULIET_API void ClearPointLights();
|
||||||
JULIET_API void SetGlobalLight(const Vector3& direction, const Vector3& color, float ambientIntensity);
|
JULIET_API void SetGlobalLight(const Vector3& direction, const Vector3& color, float ambientIntensity);
|
||||||
|
|
||||||
// Assets & Instances
|
// Assets & Instances
|
||||||
[[nodiscard]] JULIET_API MeshAssetID GetOrCreateMeshAsset(String name);
|
[[nodiscard]] JULIET_API MeshAssetID GetOrCreateMeshAsset(String name);
|
||||||
[[nodiscard]] JULIET_API MeshInstanceID CreateMeshInstance(MeshAssetID meshAsset, MaterialAssetID materialAsset, const Matrix& transform);
|
[[nodiscard]] JULIET_API MeshInstanceID CreateMeshInstance(MeshAssetID meshAsset, MaterialAssetID materialAsset, const Matrix& transform);
|
||||||
JULIET_API void SetMeshInstanceTransform(MeshInstanceID id, const Matrix& transform);
|
JULIET_API void SetMeshInstanceTransform(MeshInstanceID id, const Matrix& transform);
|
||||||
|
|
||||||
// Primitives
|
// Primitives
|
||||||
JULIET_API MeshAssetID GetCubePrimitiveMeshAssetID();
|
JULIET_API MeshAssetID GetCubePrimitiveMeshAssetID();
|
||||||
JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID();
|
JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID();
|
||||||
JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID();
|
JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID();
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
JULIET_API void ReloadMeshRendererShaders();
|
JULIET_API void ReloadMeshRendererShaders();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Math/Matrix.h>
|
#include <Core/Math/Matrix.h>
|
||||||
#include <Core/Math/Vector.h>
|
#include <Core/Math/Vector.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct PushData
|
||||||
{
|
{
|
||||||
struct PushData
|
Matrix ViewProjection;
|
||||||
{
|
uint32 MeshIndex;
|
||||||
Matrix ViewProjection;
|
uint32 TransformsBufferIndex;
|
||||||
uint32 MeshIndex;
|
uint32 BufferIndex;
|
||||||
uint32 TransformsBufferIndex;
|
uint32 TextureIndex;
|
||||||
uint32 BufferIndex;
|
uint32 VertexOffset;
|
||||||
uint32 TextureIndex;
|
uint32 LightBufferIndex;
|
||||||
uint32 VertexOffset;
|
uint32 ActiveLightCount;
|
||||||
uint32 LightBufferIndex;
|
float GlobalAmbientIntensity;
|
||||||
uint32 ActiveLightCount;
|
|
||||||
float GlobalAmbientIntensity;
|
|
||||||
|
|
||||||
Vector3 GlobalLightDirection;
|
Vector3 GlobalLightDirection;
|
||||||
uint32 Pad1;
|
uint32 Pad1;
|
||||||
|
|
||||||
Vector3 GlobalLightColor;
|
Vector3 GlobalLightColor;
|
||||||
uint32 Pad2;
|
uint32 Pad2;
|
||||||
|
|
||||||
float Scale[2];
|
float Scale[2];
|
||||||
float Translate[2];
|
float Translate[2];
|
||||||
|
|
||||||
Vector4 MeshAlbedo;
|
Vector4 MeshAlbedo;
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,115 +1,112 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Graphics/Colors.h>
|
#include <Graphics/Colors.h>
|
||||||
#include <Graphics/Texture.h>
|
#include <Graphics/Texture.h>
|
||||||
|
|
||||||
namespace Juliet
|
enum struct LoadOperation : uint8
|
||||||
{
|
{
|
||||||
enum struct LoadOperation : uint8
|
Load, // Load the texture from memory (preserve)
|
||||||
|
Clear, // Clear the texture
|
||||||
|
Ignore // Ignore the content of the texture (undefined)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct StoreOperation : uint8
|
||||||
|
{
|
||||||
|
Store, // Store the result of the render pass into memory
|
||||||
|
Ignore, // Whatever is generated is ignored (undefined)
|
||||||
|
Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content
|
||||||
|
ResolveAndStore // Same but store the MipMap content to memory
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorTargetInfo
|
||||||
|
{
|
||||||
|
Texture* TargetTexture;
|
||||||
|
uint32 MipLevel;
|
||||||
|
union
|
||||||
{
|
{
|
||||||
Load, // Load the texture from memory (preserve)
|
uint32 DepthPlane;
|
||||||
Clear, // Clear the texture
|
uint32 LayerIndex;
|
||||||
Ignore // Ignore the content of the texture (undefined)
|
|
||||||
};
|
};
|
||||||
|
bool CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD)
|
||||||
|
|
||||||
enum struct StoreOperation : uint8
|
Texture* ResolveTexture;
|
||||||
{
|
uint32 ResolveMipLevel;
|
||||||
Store, // Store the result of the render pass into memory
|
uint32 ResolveLayerIndex;
|
||||||
Ignore, // Whatever is generated is ignored (undefined)
|
bool CycleResolveTexture;
|
||||||
Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content
|
|
||||||
ResolveAndStore // Same but store the MipMap content to memory
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ColorTargetInfo
|
FColor ClearColor;
|
||||||
{
|
LoadOperation LoadOperation;
|
||||||
Texture* TargetTexture;
|
StoreOperation StoreOperation;
|
||||||
uint32 MipLevel;
|
};
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32 DepthPlane;
|
|
||||||
uint32 LayerIndex;
|
|
||||||
};
|
|
||||||
bool CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD)
|
|
||||||
|
|
||||||
Texture* ResolveTexture;
|
struct DepthStencilTargetInfo
|
||||||
uint32 ResolveMipLevel;
|
{
|
||||||
uint32 ResolveLayerIndex;
|
Texture* TargetTexture;
|
||||||
bool CycleResolveTexture;
|
uint32 MipLevel;
|
||||||
|
uint32 LayerIndex;
|
||||||
|
|
||||||
FColor ClearColor;
|
float ClearDepth;
|
||||||
LoadOperation LoadOperation;
|
uint8 ClearStencil;
|
||||||
StoreOperation StoreOperation;
|
LoadOperation LoadOperation;
|
||||||
};
|
StoreOperation StoreOperation;
|
||||||
|
};
|
||||||
|
|
||||||
struct DepthStencilTargetInfo
|
enum class BlendFactor : uint8
|
||||||
{
|
{
|
||||||
Texture* TargetTexture;
|
Invalid,
|
||||||
uint32 MipLevel;
|
Zero,
|
||||||
uint32 LayerIndex;
|
One,
|
||||||
|
Src_Color,
|
||||||
|
One_Minus_Src_Color,
|
||||||
|
Dst_Color,
|
||||||
|
One_Minus_Dst_Color,
|
||||||
|
Src_Alpha,
|
||||||
|
One_Minus_Src_Alpha,
|
||||||
|
Dst_Alpha,
|
||||||
|
One_Minus_Dst_Alpha,
|
||||||
|
Constant_Color,
|
||||||
|
One_MINUS_Constant_Color,
|
||||||
|
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
float ClearDepth;
|
enum class BlendOperation : uint8
|
||||||
uint8 ClearStencil;
|
{
|
||||||
LoadOperation LoadOperation;
|
Invalid,
|
||||||
StoreOperation StoreOperation;
|
Add, // (source * source_factor) + (destination * destination_factor)
|
||||||
};
|
Subtract, // (source * source_factor) - (destination * destination_factor)
|
||||||
|
ReverseSubtract, // (destination * destination_factor) - (source * source_factor)
|
||||||
|
Min, // min(source, destination)
|
||||||
|
Max, // max(source, destination)
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
enum class BlendFactor : uint8
|
enum class ColorComponentFlags : uint8
|
||||||
{
|
{
|
||||||
Invalid,
|
R = 1u << 0,
|
||||||
Zero,
|
G = 1u << 1,
|
||||||
One,
|
B = 1u << 2,
|
||||||
Src_Color,
|
A = 1u << 3
|
||||||
One_Minus_Src_Color,
|
};
|
||||||
Dst_Color,
|
|
||||||
One_Minus_Dst_Color,
|
|
||||||
Src_Alpha,
|
|
||||||
One_Minus_Src_Alpha,
|
|
||||||
Dst_Alpha,
|
|
||||||
One_Minus_Dst_Alpha,
|
|
||||||
Constant_Color,
|
|
||||||
One_MINUS_Constant_Color,
|
|
||||||
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BlendOperation : uint8
|
struct ColorTargetBlendState
|
||||||
{
|
{
|
||||||
Invalid,
|
BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
|
||||||
Add, // (source * source_factor) + (destination * destination_factor)
|
BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
|
||||||
Subtract, // (source * source_factor) - (destination * destination_factor)
|
BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
|
||||||
ReverseSubtract, // (destination * destination_factor) - (source * source_factor)
|
BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
|
||||||
Min, // min(source, destination)
|
BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
|
||||||
Max, // max(source, destination)
|
BlendOperation AlphaBlendOperation; // The blend operation for the alpha component.
|
||||||
Count
|
ColorComponentFlags ColorWriteMask; // A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.
|
||||||
};
|
bool EnableBlend : 1; // Whether blending is enabled for the color target.
|
||||||
|
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled.
|
||||||
|
};
|
||||||
|
|
||||||
enum class ColorComponentFlags : uint8
|
struct ColorTargetDescription
|
||||||
{
|
{
|
||||||
R = 1u << 0,
|
TextureFormat Format;
|
||||||
G = 1u << 1,
|
ColorTargetBlendState BlendState;
|
||||||
B = 1u << 2,
|
};
|
||||||
A = 1u << 3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ColorTargetBlendState
|
// Opaque Type
|
||||||
{
|
struct RenderPass;
|
||||||
BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
|
|
||||||
BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
|
|
||||||
BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
|
|
||||||
BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
|
|
||||||
BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
|
|
||||||
BlendOperation AlphaBlendOperation; // The blend operation for the alpha component.
|
|
||||||
ColorComponentFlags ColorWriteMask; // A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.
|
|
||||||
bool EnableBlend : 1; // Whether blending is enabled for the color target.
|
|
||||||
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled.
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ColorTargetDescription
|
|
||||||
{
|
|
||||||
TextureFormat Format;
|
|
||||||
ColorTargetBlendState BlendState;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Opaque Type
|
|
||||||
struct RenderPass;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Opaque type
|
||||||
|
struct Shader;
|
||||||
|
|
||||||
|
enum class ShaderStage : uint8
|
||||||
{
|
{
|
||||||
// Opaque type
|
Vertex,
|
||||||
struct Shader;
|
Fragment,
|
||||||
|
Compute
|
||||||
|
};
|
||||||
|
|
||||||
enum class ShaderStage : uint8
|
struct ShaderCreateInfo
|
||||||
{
|
{
|
||||||
Vertex,
|
ShaderStage Stage;
|
||||||
Fragment,
|
String EntryPoint;
|
||||||
Compute
|
};
|
||||||
};
|
|
||||||
|
|
||||||
struct ShaderCreateInfo
|
|
||||||
{
|
|
||||||
ShaderStage Stage;
|
|
||||||
String EntryPoint;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
@@ -6,26 +6,23 @@
|
|||||||
#include <Core/Math/Matrix.h>
|
#include <Core/Math/Matrix.h>
|
||||||
#include <Graphics/GraphicsConfig.h>
|
#include <Graphics/GraphicsConfig.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct RenderPass;
|
||||||
|
struct CommandList;
|
||||||
|
struct Window;
|
||||||
|
struct GraphicsPipeline;
|
||||||
|
struct GraphicsDevice;
|
||||||
|
|
||||||
|
struct SkyboxRenderer
|
||||||
{
|
{
|
||||||
struct RenderPass;
|
GraphicsDevice* Device;
|
||||||
struct CommandList;
|
GraphicsPipeline* Pipeline;
|
||||||
struct Window;
|
};
|
||||||
struct GraphicsPipeline;
|
|
||||||
struct GraphicsDevice;
|
|
||||||
|
|
||||||
struct SkyboxRenderer
|
[[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||||
{
|
JULIET_API void ShutdownSkyboxRenderer();
|
||||||
GraphicsDevice* Device;
|
JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
|
||||||
GraphicsPipeline* Pipeline;
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
|
||||||
JULIET_API void ShutdownSkyboxRenderer();
|
|
||||||
JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
|
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
JULIET_API void ReloadSkyboxShaders();
|
JULIET_API void ReloadSkyboxShaders();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
+176
-179
@@ -1,183 +1,180 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
enum struct TextureFormat : uint8
|
||||||
{
|
{
|
||||||
enum struct TextureFormat : uint8
|
Invalid,
|
||||||
|
|
||||||
|
/* Unsigned Normalized Float Color Formats */
|
||||||
|
A8_UNORM,
|
||||||
|
R8_UNORM,
|
||||||
|
R8G8_UNORM,
|
||||||
|
R8G8B8A8_UNORM,
|
||||||
|
R16_UNORM,
|
||||||
|
R16G16_UNORM,
|
||||||
|
R16G16B16A16_UNORM,
|
||||||
|
R10G10B10A2_UNORM,
|
||||||
|
B5G6R5_UNORM,
|
||||||
|
B5G5R5A1_UNORM,
|
||||||
|
B4G4R4A4_UNORM,
|
||||||
|
B8G8R8A8_UNORM,
|
||||||
|
/* Compressed Unsigned Normalized Float Color Formats */
|
||||||
|
BC1_RGBA_UNORM,
|
||||||
|
BC2_RGBA_UNORM,
|
||||||
|
BC3_RGBA_UNORM,
|
||||||
|
BC4_R_UNORM,
|
||||||
|
BC5_RG_UNORM,
|
||||||
|
BC7_RGBA_UNORM,
|
||||||
|
/* Compressed Signed Float Color Formats */
|
||||||
|
BC6H_RGB_FLOAT,
|
||||||
|
/* Compressed Unsigned Float Color Formats */
|
||||||
|
BC6H_RGB_UFLOAT,
|
||||||
|
/* Signed Normalized Float Color Formats */
|
||||||
|
R8_SNORM,
|
||||||
|
R8G8_SNORM,
|
||||||
|
R8G8B8A8_SNORM,
|
||||||
|
R16_SNORM,
|
||||||
|
R16G16_SNORM,
|
||||||
|
R16G16B16A16_SNORM,
|
||||||
|
/* Signed Float Color Formats */
|
||||||
|
R16_FLOAT,
|
||||||
|
R16G16_FLOAT,
|
||||||
|
R16G16B16A16_FLOAT,
|
||||||
|
R32_FLOAT,
|
||||||
|
R32G32_FLOAT,
|
||||||
|
R32G32B32A32_FLOAT,
|
||||||
|
/* Unsigned Float Color Formats */
|
||||||
|
R11G11B10_UFLOAT,
|
||||||
|
/* Unsigned Integer Color Formats */
|
||||||
|
R8_UINT,
|
||||||
|
R8G8_UINT,
|
||||||
|
R8G8B8A8_UINT,
|
||||||
|
R16_UINT,
|
||||||
|
R16G16_UINT,
|
||||||
|
R16G16B16A16_UINT,
|
||||||
|
R32_UINT,
|
||||||
|
R32G32_UINT,
|
||||||
|
R32G32B32A32_UINT,
|
||||||
|
/* Signed Integer Color Formats */
|
||||||
|
R8_INT,
|
||||||
|
R8G8_INT,
|
||||||
|
R8G8B8A8_INT,
|
||||||
|
R16_INT,
|
||||||
|
R16G16_INT,
|
||||||
|
R16G16B16A16_INT,
|
||||||
|
R32_INT,
|
||||||
|
R32G32_INT,
|
||||||
|
R32G32B32A32_INT,
|
||||||
|
/* SRGB Unsigned Normalized Color Formats */
|
||||||
|
R8G8B8A8_UNORM_SRGB,
|
||||||
|
B8G8R8A8_UNORM_SRGB,
|
||||||
|
/* Compressed SRGB Unsigned Normalized Color Formats */
|
||||||
|
BC1_RGBA_UNORM_SRGB,
|
||||||
|
BC2_RGBA_UNORM_SRGB,
|
||||||
|
BC3_RGBA_UNORM_SRGB,
|
||||||
|
BC7_RGBA_UNORM_SRGB,
|
||||||
|
/* Depth Formats */
|
||||||
|
D16_UNORM,
|
||||||
|
D24_UNORM,
|
||||||
|
D32_FLOAT,
|
||||||
|
D24_UNORM_S8_UINT,
|
||||||
|
D32_FLOAT_S8_UINT,
|
||||||
|
/* Compressed ASTC Normalized Float Color Formats*/
|
||||||
|
ASTC_4x4_UNORM,
|
||||||
|
ASTC_5x4_UNORM,
|
||||||
|
ASTC_5x5_UNORM,
|
||||||
|
ASTC_6x5_UNORM,
|
||||||
|
ASTC_6x6_UNORM,
|
||||||
|
ASTC_8x5_UNORM,
|
||||||
|
ASTC_8x6_UNORM,
|
||||||
|
ASTC_8x8_UNORM,
|
||||||
|
ASTC_10x5_UNORM,
|
||||||
|
ASTC_10x6_UNORM,
|
||||||
|
ASTC_10x8_UNORM,
|
||||||
|
ASTC_10x10_UNORM,
|
||||||
|
ASTC_12x10_UNORM,
|
||||||
|
ASTC_12x12_UNORM,
|
||||||
|
/* Compressed SRGB ASTC Normalized Float Color Formats*/
|
||||||
|
ASTC_4x4_UNORM_SRGB,
|
||||||
|
ASTC_5x4_UNORM_SRGB,
|
||||||
|
ASTC_5x5_UNORM_SRGB,
|
||||||
|
ASTC_6x5_UNORM_SRGB,
|
||||||
|
ASTC_6x6_UNORM_SRGB,
|
||||||
|
ASTC_8x5_UNORM_SRGB,
|
||||||
|
ASTC_8x6_UNORM_SRGB,
|
||||||
|
ASTC_8x8_UNORM_SRGB,
|
||||||
|
ASTC_10x5_UNORM_SRGB,
|
||||||
|
ASTC_10x6_UNORM_SRGB,
|
||||||
|
ASTC_10x8_UNORM_SRGB,
|
||||||
|
ASTC_10x10_UNORM_SRGB,
|
||||||
|
ASTC_12x10_UNORM_SRGB,
|
||||||
|
ASTC_12x12_UNORM_SRGB,
|
||||||
|
/* Compressed ASTC Signed Float Color Formats*/
|
||||||
|
ASTC_4x4_FLOAT,
|
||||||
|
ASTC_5x4_FLOAT,
|
||||||
|
ASTC_5x5_FLOAT,
|
||||||
|
ASTC_6x5_FLOAT,
|
||||||
|
ASTC_6x6_FLOAT,
|
||||||
|
ASTC_8x5_FLOAT,
|
||||||
|
ASTC_8x6_FLOAT,
|
||||||
|
ASTC_8x8_FLOAT,
|
||||||
|
ASTC_10x5_FLOAT,
|
||||||
|
ASTC_10x6_FLOAT,
|
||||||
|
ASTC_10x8_FLOAT,
|
||||||
|
ASTC_10x10_FLOAT,
|
||||||
|
ASTC_12x10_FLOAT,
|
||||||
|
ASTC_12x12_FLOAT,
|
||||||
|
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct TextureUsageFlag : uint8
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Sampler = 1 << 0, // Textures supports sampling
|
||||||
|
ColorTarget = 1 << 1, // Texture is color render target
|
||||||
|
DepthStencilTarget = 1 << 2, // Texture is depth stencil target
|
||||||
|
GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage
|
||||||
|
ComputeStorageRead = 1 << 4, // Support Storage read at compute stage
|
||||||
|
ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage
|
||||||
|
ComputeStorageSimultaneousReadWrite =
|
||||||
|
1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct TextureType : uint8
|
||||||
|
{
|
||||||
|
Texture_2D,
|
||||||
|
Texture_2DArray,
|
||||||
|
Texture_3D,
|
||||||
|
Texture_3DArray,
|
||||||
|
Texture_Cube,
|
||||||
|
Texture_CubeArray,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct TextureSampleCount : uint8
|
||||||
|
{
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Four,
|
||||||
|
Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create Information structs
|
||||||
|
struct TextureCreateInfo
|
||||||
|
{
|
||||||
|
TextureType Type;
|
||||||
|
TextureFormat Format;
|
||||||
|
TextureUsageFlag Flags;
|
||||||
|
TextureSampleCount SampleCount;
|
||||||
|
|
||||||
|
uint32 Width;
|
||||||
|
uint32 Height;
|
||||||
|
union
|
||||||
{
|
{
|
||||||
Invalid,
|
uint32 LayerCount;
|
||||||
|
uint32 DepthPlane;
|
||||||
|
}; // LayerCount is used in 2d array textures and Depth for 3d textures
|
||||||
|
uint32 MipLevelCount;
|
||||||
|
};
|
||||||
|
|
||||||
/* Unsigned Normalized Float Color Formats */
|
// Opaque Type
|
||||||
A8_UNORM,
|
struct Texture;
|
||||||
R8_UNORM,
|
|
||||||
R8G8_UNORM,
|
|
||||||
R8G8B8A8_UNORM,
|
|
||||||
R16_UNORM,
|
|
||||||
R16G16_UNORM,
|
|
||||||
R16G16B16A16_UNORM,
|
|
||||||
R10G10B10A2_UNORM,
|
|
||||||
B5G6R5_UNORM,
|
|
||||||
B5G5R5A1_UNORM,
|
|
||||||
B4G4R4A4_UNORM,
|
|
||||||
B8G8R8A8_UNORM,
|
|
||||||
/* Compressed Unsigned Normalized Float Color Formats */
|
|
||||||
BC1_RGBA_UNORM,
|
|
||||||
BC2_RGBA_UNORM,
|
|
||||||
BC3_RGBA_UNORM,
|
|
||||||
BC4_R_UNORM,
|
|
||||||
BC5_RG_UNORM,
|
|
||||||
BC7_RGBA_UNORM,
|
|
||||||
/* Compressed Signed Float Color Formats */
|
|
||||||
BC6H_RGB_FLOAT,
|
|
||||||
/* Compressed Unsigned Float Color Formats */
|
|
||||||
BC6H_RGB_UFLOAT,
|
|
||||||
/* Signed Normalized Float Color Formats */
|
|
||||||
R8_SNORM,
|
|
||||||
R8G8_SNORM,
|
|
||||||
R8G8B8A8_SNORM,
|
|
||||||
R16_SNORM,
|
|
||||||
R16G16_SNORM,
|
|
||||||
R16G16B16A16_SNORM,
|
|
||||||
/* Signed Float Color Formats */
|
|
||||||
R16_FLOAT,
|
|
||||||
R16G16_FLOAT,
|
|
||||||
R16G16B16A16_FLOAT,
|
|
||||||
R32_FLOAT,
|
|
||||||
R32G32_FLOAT,
|
|
||||||
R32G32B32A32_FLOAT,
|
|
||||||
/* Unsigned Float Color Formats */
|
|
||||||
R11G11B10_UFLOAT,
|
|
||||||
/* Unsigned Integer Color Formats */
|
|
||||||
R8_UINT,
|
|
||||||
R8G8_UINT,
|
|
||||||
R8G8B8A8_UINT,
|
|
||||||
R16_UINT,
|
|
||||||
R16G16_UINT,
|
|
||||||
R16G16B16A16_UINT,
|
|
||||||
R32_UINT,
|
|
||||||
R32G32_UINT,
|
|
||||||
R32G32B32A32_UINT,
|
|
||||||
/* Signed Integer Color Formats */
|
|
||||||
R8_INT,
|
|
||||||
R8G8_INT,
|
|
||||||
R8G8B8A8_INT,
|
|
||||||
R16_INT,
|
|
||||||
R16G16_INT,
|
|
||||||
R16G16B16A16_INT,
|
|
||||||
R32_INT,
|
|
||||||
R32G32_INT,
|
|
||||||
R32G32B32A32_INT,
|
|
||||||
/* SRGB Unsigned Normalized Color Formats */
|
|
||||||
R8G8B8A8_UNORM_SRGB,
|
|
||||||
B8G8R8A8_UNORM_SRGB,
|
|
||||||
/* Compressed SRGB Unsigned Normalized Color Formats */
|
|
||||||
BC1_RGBA_UNORM_SRGB,
|
|
||||||
BC2_RGBA_UNORM_SRGB,
|
|
||||||
BC3_RGBA_UNORM_SRGB,
|
|
||||||
BC7_RGBA_UNORM_SRGB,
|
|
||||||
/* Depth Formats */
|
|
||||||
D16_UNORM,
|
|
||||||
D24_UNORM,
|
|
||||||
D32_FLOAT,
|
|
||||||
D24_UNORM_S8_UINT,
|
|
||||||
D32_FLOAT_S8_UINT,
|
|
||||||
/* Compressed ASTC Normalized Float Color Formats*/
|
|
||||||
ASTC_4x4_UNORM,
|
|
||||||
ASTC_5x4_UNORM,
|
|
||||||
ASTC_5x5_UNORM,
|
|
||||||
ASTC_6x5_UNORM,
|
|
||||||
ASTC_6x6_UNORM,
|
|
||||||
ASTC_8x5_UNORM,
|
|
||||||
ASTC_8x6_UNORM,
|
|
||||||
ASTC_8x8_UNORM,
|
|
||||||
ASTC_10x5_UNORM,
|
|
||||||
ASTC_10x6_UNORM,
|
|
||||||
ASTC_10x8_UNORM,
|
|
||||||
ASTC_10x10_UNORM,
|
|
||||||
ASTC_12x10_UNORM,
|
|
||||||
ASTC_12x12_UNORM,
|
|
||||||
/* Compressed SRGB ASTC Normalized Float Color Formats*/
|
|
||||||
ASTC_4x4_UNORM_SRGB,
|
|
||||||
ASTC_5x4_UNORM_SRGB,
|
|
||||||
ASTC_5x5_UNORM_SRGB,
|
|
||||||
ASTC_6x5_UNORM_SRGB,
|
|
||||||
ASTC_6x6_UNORM_SRGB,
|
|
||||||
ASTC_8x5_UNORM_SRGB,
|
|
||||||
ASTC_8x6_UNORM_SRGB,
|
|
||||||
ASTC_8x8_UNORM_SRGB,
|
|
||||||
ASTC_10x5_UNORM_SRGB,
|
|
||||||
ASTC_10x6_UNORM_SRGB,
|
|
||||||
ASTC_10x8_UNORM_SRGB,
|
|
||||||
ASTC_10x10_UNORM_SRGB,
|
|
||||||
ASTC_12x10_UNORM_SRGB,
|
|
||||||
ASTC_12x12_UNORM_SRGB,
|
|
||||||
/* Compressed ASTC Signed Float Color Formats*/
|
|
||||||
ASTC_4x4_FLOAT,
|
|
||||||
ASTC_5x4_FLOAT,
|
|
||||||
ASTC_5x5_FLOAT,
|
|
||||||
ASTC_6x5_FLOAT,
|
|
||||||
ASTC_6x6_FLOAT,
|
|
||||||
ASTC_8x5_FLOAT,
|
|
||||||
ASTC_8x6_FLOAT,
|
|
||||||
ASTC_8x8_FLOAT,
|
|
||||||
ASTC_10x5_FLOAT,
|
|
||||||
ASTC_10x6_FLOAT,
|
|
||||||
ASTC_10x8_FLOAT,
|
|
||||||
ASTC_10x10_FLOAT,
|
|
||||||
ASTC_12x10_FLOAT,
|
|
||||||
ASTC_12x12_FLOAT,
|
|
||||||
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
enum struct TextureUsageFlag : uint8
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Sampler = 1 << 0, // Textures supports sampling
|
|
||||||
ColorTarget = 1 << 1, // Texture is color render target
|
|
||||||
DepthStencilTarget = 1 << 2, // Texture is depth stencil target
|
|
||||||
GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage
|
|
||||||
ComputeStorageRead = 1 << 4, // Support Storage read at compute stage
|
|
||||||
ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage
|
|
||||||
ComputeStorageSimultaneousReadWrite =
|
|
||||||
1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
|
|
||||||
};
|
|
||||||
|
|
||||||
enum struct TextureType : uint8
|
|
||||||
{
|
|
||||||
Texture_2D,
|
|
||||||
Texture_2DArray,
|
|
||||||
Texture_3D,
|
|
||||||
Texture_3DArray,
|
|
||||||
Texture_Cube,
|
|
||||||
Texture_CubeArray,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum struct TextureSampleCount : uint8
|
|
||||||
{
|
|
||||||
One,
|
|
||||||
Two,
|
|
||||||
Four,
|
|
||||||
Eight,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create Information structs
|
|
||||||
struct TextureCreateInfo
|
|
||||||
{
|
|
||||||
TextureType Type;
|
|
||||||
TextureFormat Format;
|
|
||||||
TextureUsageFlag Flags;
|
|
||||||
TextureSampleCount SampleCount;
|
|
||||||
|
|
||||||
uint32 Width;
|
|
||||||
uint32 Height;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32 LayerCount;
|
|
||||||
uint32 DepthPlane;
|
|
||||||
}; // LayerCount is used in 2d array textures and Depth for 3d textures
|
|
||||||
uint32 MipLevelCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Opaque Type
|
|
||||||
struct Texture;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
struct Vertex
|
||||||
{
|
{
|
||||||
struct Vertex
|
float Position[3];
|
||||||
{
|
float Normal[3];
|
||||||
float Position[3];
|
float Color[4];
|
||||||
float Normal[3];
|
};
|
||||||
float Color[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
using Index = uint16;
|
using Index = uint16;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
#include <Core/Application/ApplicationManager.h>
|
#include <Core/Application/ApplicationManager.h>
|
||||||
#include <Core/JulietInit.h>
|
#include <Core/JulietInit.h>
|
||||||
|
|
||||||
#include <Engine/Engine.h>
|
#include <Engine/Engine.h>
|
||||||
|
|
||||||
namespace Juliet
|
void StartApplication(IApplication& app, JulietInit_Flags flags)
|
||||||
{
|
{
|
||||||
void StartApplication(IApplication& app, JulietInit_Flags flags)
|
InitializeEngine(flags);
|
||||||
{
|
|
||||||
InitializeEngine(flags);
|
|
||||||
|
|
||||||
LoadApplication(app);
|
LoadApplication(app);
|
||||||
|
|
||||||
RunEngine();
|
RunEngine();
|
||||||
|
|
||||||
UnloadApplication();
|
UnloadApplication();
|
||||||
|
|
||||||
ShutdownEngine();
|
ShutdownEngine();
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,38 +1,35 @@
|
|||||||
#include <Core/Logging/LogManager.h>
|
#include <Core/Logging/LogManager.h>
|
||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
|
|
||||||
#include <comdef.h> // For _com_error to decode HRESULTs
|
#include <comdef.h> // For _com_error to decode HRESULTs
|
||||||
#include <intrin.h> // For __debugbreak
|
#include <intrin.h> // For __debugbreak
|
||||||
|
|
||||||
namespace Juliet
|
void JulietAssert(const char* expression, const char* message, std::source_location location, long handleResult)
|
||||||
{
|
{
|
||||||
void JulietAssert(const char* expression, const char* message, std::source_location location, long handleResult)
|
Log(LogLevel::Error, LogCategory::Core, "--- ASSERTION FAILED ---");
|
||||||
|
Log(LogLevel::Error, LogCategory::Core, "Expression: %s", expression);
|
||||||
|
Log(LogLevel::Error, LogCategory::Core, "Message: %s", message);
|
||||||
|
Log(LogLevel::Error, LogCategory::Core, "Location: %s(%u): %s", location.file_name(), location.line(),
|
||||||
|
location.function_name());
|
||||||
|
|
||||||
|
if (handleResult < 0)
|
||||||
{
|
{
|
||||||
Log(LogLevel::Error, LogCategory::Core, "--- ASSERTION FAILED ---");
|
_com_error err(handleResult);
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Expression: %s", expression);
|
// Using %ls because ErrorMessage() returns a wide string (wchar_t*)
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Message: %s", message);
|
Log(LogLevel::Error, LogCategory::Graphics, "HRESULT: 0x%08X (%ls)", handleResult, err.ErrorMessage());
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Location: %s(%u): %s", location.file_name(), location.line(),
|
|
||||||
location.function_name());
|
|
||||||
|
|
||||||
if (handleResult < 0)
|
|
||||||
{
|
|
||||||
_com_error err(handleResult);
|
|
||||||
// Using %ls because ErrorMessage() returns a wide string (wchar_t*)
|
|
||||||
Log(LogLevel::Error, LogCategory::Graphics, "HRESULT: 0x%08X (%ls)", handleResult, err.ErrorMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(LogLevel::Error, LogCategory::Core, "-------------------------");
|
|
||||||
|
|
||||||
JULIET_PLATFORM_BREAK();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Free(ByteBuffer& buffer)
|
Log(LogLevel::Error, LogCategory::Core, "-------------------------");
|
||||||
|
|
||||||
|
JULIET_PLATFORM_BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free(ByteBuffer& buffer)
|
||||||
|
{
|
||||||
|
if (buffer.Data)
|
||||||
{
|
{
|
||||||
if (buffer.Data)
|
Free(buffer.Data);
|
||||||
{
|
|
||||||
Free(buffer.Data);
|
|
||||||
}
|
|
||||||
buffer = {};
|
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
buffer = {};
|
||||||
|
}
|
||||||
|
|||||||
+572
-575
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,2 @@
|
|||||||
#include <Core/Container/Vector.h>
|
#include <Core/Container/Vector.h>
|
||||||
|
|
||||||
namespace Juliet
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,162 +1,159 @@
|
|||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/HAL/Display/Display_cpp.h>
|
#include <Core/HAL/Display/Display_cpp.h>
|
||||||
#include <Core/HAL/Display/DisplayDevice.h>
|
#include <Core/HAL/Display/DisplayDevice.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
#include <Core/Memory/MemoryArena.h>
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace
|
||||||
{
|
{
|
||||||
namespace
|
DisplayDevice* g_CurrentDisplayDevice = nullptr;
|
||||||
|
|
||||||
|
void DestroyPlatformWindow(index_t windowIndex);
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace Internal::Display
|
||||||
|
{
|
||||||
|
// TODO : IfDef new factories that are not compatible
|
||||||
|
constexpr DisplayDeviceFactory* Factories[] = { &Win32DisplayDeviceFactory, nullptr };
|
||||||
|
} // namespace Internal::Display
|
||||||
|
|
||||||
|
void InitializeDisplaySystem()
|
||||||
|
{
|
||||||
|
Assert(!g_CurrentDisplayDevice);
|
||||||
|
|
||||||
|
Arena* arena = ArenaAllocate({ .Name = "Display System" });
|
||||||
|
|
||||||
|
DisplayDevice* candidateDevice = nullptr;
|
||||||
|
DisplayDeviceFactory* candidateFactory = nullptr;
|
||||||
|
for (DisplayDeviceFactory* factory : Internal::Display::Factories)
|
||||||
{
|
{
|
||||||
DisplayDevice* g_CurrentDisplayDevice = nullptr;
|
if (factory)
|
||||||
|
|
||||||
void DestroyPlatformWindow(index_t windowIndex);
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace Internal::Display
|
|
||||||
{
|
|
||||||
// TODO : IfDef new factories that are not compatible
|
|
||||||
constexpr DisplayDeviceFactory* Factories[] = { &Win32DisplayDeviceFactory, nullptr };
|
|
||||||
} // namespace Internal::Display
|
|
||||||
|
|
||||||
void InitializeDisplaySystem()
|
|
||||||
{
|
|
||||||
Assert(!g_CurrentDisplayDevice);
|
|
||||||
|
|
||||||
Arena* arena = ArenaAllocate({ .Name = "Display System" });
|
|
||||||
|
|
||||||
DisplayDevice* candidateDevice = nullptr;
|
|
||||||
DisplayDeviceFactory* candidateFactory = nullptr;
|
|
||||||
for (DisplayDeviceFactory* factory : Internal::Display::Factories)
|
|
||||||
{
|
{
|
||||||
if (factory)
|
candidateDevice = factory->CreateDevice(arena);
|
||||||
|
if (candidateDevice)
|
||||||
{
|
{
|
||||||
candidateDevice = factory->CreateDevice(arena);
|
candidateFactory = factory;
|
||||||
if (candidateDevice)
|
|
||||||
{
|
|
||||||
candidateFactory = factory;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : handle error instead of crashing
|
|
||||||
Assert(candidateDevice);
|
|
||||||
|
|
||||||
g_CurrentDisplayDevice = candidateDevice;
|
|
||||||
g_CurrentDisplayDevice->Arena = arena;
|
|
||||||
g_CurrentDisplayDevice->Name = candidateFactory->Name;
|
|
||||||
|
|
||||||
if (!g_CurrentDisplayDevice->Initialize(g_CurrentDisplayDevice))
|
|
||||||
{
|
|
||||||
ShutdownDisplaySystem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShutdownDisplaySystem()
|
|
||||||
{
|
|
||||||
if (!g_CurrentDisplayDevice)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy all Windows that are still alive
|
|
||||||
for (index_t idx = g_CurrentDisplayDevice->Windows.Size(); idx-- > 0;)
|
|
||||||
{
|
|
||||||
DestroyPlatformWindow(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_CurrentDisplayDevice->Shutdown(g_CurrentDisplayDevice);
|
|
||||||
// Free anything that was freed by the shutdown and then free the display
|
|
||||||
// no op for now
|
|
||||||
g_CurrentDisplayDevice->Free(g_CurrentDisplayDevice);
|
|
||||||
|
|
||||||
ArenaRelease(g_CurrentDisplayDevice->Arena);
|
|
||||||
g_CurrentDisplayDevice = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int /*flags*/ /* = 0 unused */)
|
|
||||||
{
|
|
||||||
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
|
|
||||||
|
|
||||||
Window window = {};
|
|
||||||
window.Arena = ArenaAllocate({ .Name = "Window" });
|
|
||||||
window.Width = width;
|
|
||||||
window.Height = height;
|
|
||||||
|
|
||||||
window.Title = StringCopy(window.Arena, WrapString(title));
|
|
||||||
|
|
||||||
g_CurrentDisplayDevice->Windows.PushBack(window);
|
|
||||||
|
|
||||||
auto* pWindow = g_CurrentDisplayDevice->Windows.Last();
|
|
||||||
if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, pWindow))
|
|
||||||
{
|
|
||||||
ArenaRelease(window.Arena);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : make SHOW optional on creation with a flag
|
|
||||||
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, pWindow);
|
|
||||||
|
|
||||||
return pWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void DestroyPlatformWindow(index_t windowIndex)
|
|
||||||
{
|
|
||||||
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
|
|
||||||
Window* window = &windows[windowIndex];
|
|
||||||
|
|
||||||
HideWindow(window);
|
|
||||||
|
|
||||||
g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window);
|
|
||||||
|
|
||||||
ArenaClear(window->Arena);
|
|
||||||
ArenaRelease(window->Arena);
|
|
||||||
|
|
||||||
windows.RemoveAtFast(windowIndex);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void DestroyPlatformWindow(NonNullPtr<Window> window)
|
|
||||||
{
|
|
||||||
// Find and destroy
|
|
||||||
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
|
|
||||||
for (index_t idx = windows.Size(); idx-- > 0;)
|
|
||||||
{
|
|
||||||
Window& windowRef = windows[idx];
|
|
||||||
if (windowRef.ID == window->ID)
|
|
||||||
{
|
|
||||||
DestroyPlatformWindow(idx);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowWindow(NonNullPtr<Window> window)
|
// TODO : handle error instead of crashing
|
||||||
|
Assert(candidateDevice);
|
||||||
|
|
||||||
|
g_CurrentDisplayDevice = candidateDevice;
|
||||||
|
g_CurrentDisplayDevice->Arena = arena;
|
||||||
|
g_CurrentDisplayDevice->Name = candidateFactory->Name;
|
||||||
|
|
||||||
|
if (!g_CurrentDisplayDevice->Initialize(g_CurrentDisplayDevice))
|
||||||
{
|
{
|
||||||
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, window);
|
ShutdownDisplaySystem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutdownDisplaySystem()
|
||||||
|
{
|
||||||
|
if (!g_CurrentDisplayDevice)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HideWindow(NonNullPtr<Window> window)
|
// Destroy all Windows that are still alive
|
||||||
|
for (index_t idx = g_CurrentDisplayDevice->Windows.Size(); idx-- > 0;)
|
||||||
{
|
{
|
||||||
g_CurrentDisplayDevice->HideWindow(g_CurrentDisplayDevice, window);
|
DestroyPlatformWindow(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowID GetWindowID(NonNullPtr<Window> window)
|
g_CurrentDisplayDevice->Shutdown(g_CurrentDisplayDevice);
|
||||||
|
// Free anything that was freed by the shutdown and then free the display
|
||||||
|
// no op for now
|
||||||
|
g_CurrentDisplayDevice->Free(g_CurrentDisplayDevice);
|
||||||
|
|
||||||
|
ArenaRelease(g_CurrentDisplayDevice->Arena);
|
||||||
|
g_CurrentDisplayDevice = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int /*flags*/ /* = 0 unused */)
|
||||||
|
{
|
||||||
|
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
|
||||||
|
|
||||||
|
Window window = {};
|
||||||
|
window.Arena = ArenaAllocate({ .Name = "Window" });
|
||||||
|
window.Width = width;
|
||||||
|
window.Height = height;
|
||||||
|
|
||||||
|
window.Title = StringCopy(window.Arena, WrapString(title));
|
||||||
|
|
||||||
|
g_CurrentDisplayDevice->Windows.PushBack(window);
|
||||||
|
|
||||||
|
auto* pWindow = g_CurrentDisplayDevice->Windows.Last();
|
||||||
|
if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, pWindow))
|
||||||
{
|
{
|
||||||
return window->ID;
|
ArenaRelease(window.Arena);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindowTitle(NonNullPtr<Window> window, String title)
|
// TODO : make SHOW optional on creation with a flag
|
||||||
{
|
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, pWindow);
|
||||||
g_CurrentDisplayDevice->SetWindowTitle(g_CurrentDisplayDevice, window, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display Device Utils. Not exposed in the API
|
return pWindow;
|
||||||
DisplayDevice* GetDisplayDevice()
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void DestroyPlatformWindow(index_t windowIndex)
|
||||||
{
|
{
|
||||||
return g_CurrentDisplayDevice;
|
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
|
||||||
|
Window* window = &windows[windowIndex];
|
||||||
|
|
||||||
|
HideWindow(window);
|
||||||
|
|
||||||
|
g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window);
|
||||||
|
|
||||||
|
ArenaClear(window->Arena);
|
||||||
|
ArenaRelease(window->Arena);
|
||||||
|
|
||||||
|
windows.RemoveAtFast(windowIndex);
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
} // namespace
|
||||||
|
|
||||||
|
void DestroyPlatformWindow(NonNullPtr<Window> window)
|
||||||
|
{
|
||||||
|
// Find and destroy
|
||||||
|
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
|
||||||
|
for (index_t idx = windows.Size(); idx-- > 0;)
|
||||||
|
{
|
||||||
|
Window& windowRef = windows[idx];
|
||||||
|
if (windowRef.ID == window->ID)
|
||||||
|
{
|
||||||
|
DestroyPlatformWindow(idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowWindow(NonNullPtr<Window> window)
|
||||||
|
{
|
||||||
|
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HideWindow(NonNullPtr<Window> window)
|
||||||
|
{
|
||||||
|
g_CurrentDisplayDevice->HideWindow(g_CurrentDisplayDevice, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowID GetWindowID(NonNullPtr<Window> window)
|
||||||
|
{
|
||||||
|
return window->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWindowTitle(NonNullPtr<Window> window, String title)
|
||||||
|
{
|
||||||
|
g_CurrentDisplayDevice->SetWindowTitle(g_CurrentDisplayDevice, window, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display Device Utils. Not exposed in the API
|
||||||
|
DisplayDevice* GetDisplayDevice()
|
||||||
|
{
|
||||||
|
return g_CurrentDisplayDevice;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,47 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Container/Vector.h>
|
#include <Core/Container/Vector.h>
|
||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Driver to the display device.
|
||||||
|
// Functions ptr will be set by the chosen factory
|
||||||
|
// Acts as a singleton after Initialize has been called and is freed in Shutdown.
|
||||||
|
struct DisplayDevice
|
||||||
{
|
{
|
||||||
// Driver to the display device.
|
Arena* Arena;
|
||||||
// Functions ptr will be set by the chosen factory
|
|
||||||
// Acts as a singleton after Initialize has been called and is freed in Shutdown.
|
|
||||||
struct DisplayDevice
|
|
||||||
{
|
|
||||||
Arena* Arena;
|
|
||||||
|
|
||||||
const char* Name = "Unknown";
|
const char* Name = "Unknown";
|
||||||
|
|
||||||
// Initialize all subsystems needed for the device to works
|
// Initialize all subsystems needed for the device to works
|
||||||
bool (*Initialize)(NonNullPtr<DisplayDevice> self);
|
bool (*Initialize)(NonNullPtr<DisplayDevice> self);
|
||||||
void (*Shutdown)(NonNullPtr<DisplayDevice> self);
|
void (*Shutdown)(NonNullPtr<DisplayDevice> self);
|
||||||
void (*Free)(NonNullPtr<DisplayDevice> self);
|
void (*Free)(NonNullPtr<DisplayDevice> self);
|
||||||
|
|
||||||
// Window management
|
// Window management
|
||||||
bool (*CreatePlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
bool (*CreatePlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
void (*DestroyPlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
void (*DestroyPlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
void (*ShowWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
void (*ShowWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
void (*HideWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
void (*HideWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
void (*SetWindowTitle)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
|
void (*SetWindowTitle)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
void (*PumpEvents)(NonNullPtr<DisplayDevice> self);
|
void (*PumpEvents)(NonNullPtr<DisplayDevice> self);
|
||||||
|
|
||||||
VectorArena<Window> Windows;
|
VectorArena<Window> Windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisplayDeviceFactory
|
struct DisplayDeviceFactory
|
||||||
{
|
{
|
||||||
const char* Name = "Unknown";
|
const char* Name = "Unknown";
|
||||||
DisplayDevice* (*CreateDevice)(Arena* arena);
|
DisplayDevice* (*CreateDevice)(Arena* arena);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO : Support more platforms
|
// TODO : Support more platforms
|
||||||
extern DisplayDeviceFactory Win32DisplayDeviceFactory;
|
extern DisplayDeviceFactory Win32DisplayDeviceFactory;
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
extern DisplayDevice* GetDisplayDevice();
|
extern DisplayDevice* GetDisplayDevice();
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
void InitializeDisplaySystem();
|
||||||
{
|
void ShutdownDisplaySystem();
|
||||||
void InitializeDisplaySystem();
|
|
||||||
void ShutdownDisplaySystem();
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <Core/HAL/Display/DisplayDevice.h>
|
#include <Core/HAL/Display/DisplayDevice.h>
|
||||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -43,10 +43,7 @@ namespace Juliet::Win32
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|
||||||
// Factory cannot be in an anonymous/unknown namespace
|
// Factory cannot be in an anonymous/unknown namespace
|
||||||
namespace Juliet
|
DisplayDeviceFactory Win32DisplayDeviceFactory = { .Name = "Win32", .CreateDevice = Win32::CreateDevice };
|
||||||
{
|
|
||||||
DisplayDeviceFactory Win32DisplayDeviceFactory = { .Name = "Win32", .CreateDevice = Win32::CreateDevice };
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <Core/Common/EnumUtils.h>
|
#include <Core/Common/EnumUtils.h>
|
||||||
#include <Core/HAL/Display/DisplayDevice.h>
|
#include <Core/HAL/Display/DisplayDevice.h>
|
||||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -276,4 +276,4 @@ namespace Juliet::Win32
|
|||||||
|
|
||||||
return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
|
return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/HAL/Win32.h>
|
#include <Core/HAL/Win32.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct DisplayDevice;
|
||||||
{
|
|
||||||
struct DisplayDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
extern void PumpEvents(NonNullPtr<DisplayDevice> self);
|
extern void PumpEvents(NonNullPtr<DisplayDevice> self);
|
||||||
extern LRESULT CALLBACK Win32MainWindowCallback(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam);
|
extern LRESULT CALLBACK Win32MainWindowCallback(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam);
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
#include <Core/Memory/MemoryArena.h>
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -101,4 +101,4 @@ namespace Juliet::Win32
|
|||||||
auto& win32State = static_cast<Window32State&>(*window->State);
|
auto& win32State = static_cast<Window32State&>(*window->State);
|
||||||
SetWindowTextA(win32State.Handle, CStr(title));
|
SetWindowTextA(win32State.Handle, CStr(title));
|
||||||
}
|
}
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
#include <Core/HAL/Win32.h>
|
#include <Core/HAL/Win32.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct DisplayDevice;
|
||||||
{
|
struct Window;
|
||||||
struct DisplayDevice;
|
|
||||||
struct Window;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
// TODO : Evaluate if its worth the burden of casting to Window32State all the time
|
// TODO : Evaluate if its worth the burden of casting to Window32State all the time
|
||||||
struct Window32State : WindowState
|
struct Window32State : WindowState
|
||||||
@@ -26,4 +23,4 @@ namespace Juliet::Win32
|
|||||||
extern void ShowWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
extern void ShowWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
extern void HideWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
extern void HideWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
|
||||||
extern void SetWindowTitle(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
|
extern void SetWindowTitle(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Core/HAL/Display/Display.h>
|
#include <Core/HAL/Display/Display.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Window;
|
||||||
|
struct WindowState
|
||||||
{
|
{
|
||||||
struct Window;
|
Window* Window;
|
||||||
struct WindowState
|
};
|
||||||
{
|
|
||||||
Window* Window;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Window
|
struct Window
|
||||||
{
|
{
|
||||||
WindowID ID;
|
WindowID ID;
|
||||||
WindowState* State;
|
WindowState* State;
|
||||||
Arena* Arena;
|
Arena* Arena;
|
||||||
|
|
||||||
int32 Width;
|
int32 Width;
|
||||||
int32 Height;
|
int32 Height;
|
||||||
String Title;
|
String Title;
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,44 +1,41 @@
|
|||||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||||
#include <Core/HAL/Win32.h>
|
#include <Core/HAL/Win32.h>
|
||||||
#include <Core/Logging/LogManager.h>
|
#include <Core/Logging/LogManager.h>
|
||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
|
|
||||||
namespace Juliet
|
DynamicLibrary* LoadDynamicLibrary(const char* filename)
|
||||||
{
|
{
|
||||||
DynamicLibrary* LoadDynamicLibrary(const char* filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
if (!filename)
|
Log(LogLevel::Error, LogCategory::Core, "Library filename is invalid (empty)");
|
||||||
{
|
return nullptr;
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Library filename is invalid (empty)");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE handle = LoadLibraryA(filename);
|
|
||||||
|
|
||||||
// Generate an error message if all loads failed
|
|
||||||
if (!handle)
|
|
||||||
{
|
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", filename);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<DynamicLibrary*>(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName)
|
HMODULE handle = LoadLibraryA(filename);
|
||||||
|
|
||||||
|
// Generate an error message if all loads failed
|
||||||
|
if (!handle)
|
||||||
{
|
{
|
||||||
|
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", filename);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<DynamicLibrary*>(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName)
|
||||||
|
{
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4191) // Disable "unsafe conversion from FARPROC"
|
#pragma warning(disable: 4191) // Disable "unsafe conversion from FARPROC"
|
||||||
auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName));
|
auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName));
|
||||||
if (!function)
|
if (!function)
|
||||||
{
|
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
|
|
||||||
}
|
|
||||||
return function;
|
|
||||||
#pragma warning(pop)
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib)
|
|
||||||
{
|
{
|
||||||
FreeLibrary(reinterpret_cast<HMODULE>(lib.Get()));
|
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
return function;
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib)
|
||||||
|
{
|
||||||
|
FreeLibrary(reinterpret_cast<HMODULE>(lib.Get()));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,165 +1,162 @@
|
|||||||
#include <Core/Common/EnumUtils.h>
|
#include <Core/Common/EnumUtils.h>
|
||||||
#include <Core/HAL/Event/Keyboard_Private.h>
|
#include <Core/HAL/Event/Keyboard_Private.h>
|
||||||
#include <Core/HAL/Event/KeyboardMapping.h>
|
#include <Core/HAL/Event/KeyboardMapping.h>
|
||||||
#include <Core/HAL/Event/SystemEvent.h>
|
#include <Core/HAL/Event/SystemEvent.h>
|
||||||
|
|
||||||
namespace Juliet
|
constexpr KeyboardID kGlobalKeyboardID = 0;
|
||||||
|
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
constexpr KeyboardID kGlobalKeyboardID = 0;
|
struct KeyboardState
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
{
|
||||||
struct KeyboardState
|
KeyState KeyState[ToUnderlying(ScanCode::Count)];
|
||||||
|
KeyMod KeyModState;
|
||||||
|
} KeyboardState;
|
||||||
|
|
||||||
|
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyPosition keyPosition)
|
||||||
|
{
|
||||||
|
Assert(key.KeyCode == KeyCode::Unknown); // At this point Keycode is not yet extracted
|
||||||
|
|
||||||
|
auto& keyboardState = KeyboardState; // Needed because MSVC debugger ignores variable in anonymouse namespace
|
||||||
|
|
||||||
|
auto type = EventType::None;
|
||||||
|
const bool isKeyDown = keyPosition == KeyPosition::Down;
|
||||||
|
if (isKeyDown)
|
||||||
{
|
{
|
||||||
KeyState KeyState[ToUnderlying(ScanCode::Count)];
|
type = EventType::Key_Down;
|
||||||
KeyMod KeyModState;
|
}
|
||||||
} KeyboardState;
|
else
|
||||||
|
|
||||||
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyPosition keyPosition)
|
|
||||||
{
|
{
|
||||||
Assert(key.KeyCode == KeyCode::Unknown); // At this point Keycode is not yet extracted
|
type = EventType::Key_Up;
|
||||||
|
}
|
||||||
|
|
||||||
auto& keyboardState = KeyboardState; // Needed because MSVC debugger ignores variable in anonymouse namespace
|
bool isKeyRepeat = false;
|
||||||
|
if (key.ScanCode > ScanCode::Unknown && key.ScanCode < ScanCode::Count)
|
||||||
|
{
|
||||||
|
auto& currentKeyState = keyboardState.KeyState[ToUnderlying(key.ScanCode)];
|
||||||
|
|
||||||
auto type = EventType::None;
|
// If state didn't change, this is a key repeat
|
||||||
const bool isKeyDown = keyPosition == KeyPosition::Down;
|
|
||||||
if (isKeyDown)
|
if (isKeyDown)
|
||||||
{
|
{
|
||||||
type = EventType::Key_Down;
|
if (currentKeyState.Position == KeyPosition::Down)
|
||||||
|
{
|
||||||
|
isKeyRepeat = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = EventType::Key_Up;
|
if (currentKeyState.Position == KeyPosition::Up)
|
||||||
}
|
|
||||||
|
|
||||||
bool isKeyRepeat = false;
|
|
||||||
if (key.ScanCode > ScanCode::Unknown && key.ScanCode < ScanCode::Count)
|
|
||||||
{
|
|
||||||
auto& currentKeyState = keyboardState.KeyState[ToUnderlying(key.ScanCode)];
|
|
||||||
|
|
||||||
// If state didn't change, this is a key repeat
|
|
||||||
if (isKeyDown)
|
|
||||||
{
|
{
|
||||||
if (currentKeyState.Position == KeyPosition::Down)
|
return false;
|
||||||
{
|
|
||||||
isKeyRepeat = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (currentKeyState.Position == KeyPosition::Up)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentKeyState.Position = keyPosition;
|
|
||||||
key.KeyCode = GetKeyCodeFromScanCode(key.ScanCode, keyboardState.KeyModState);
|
|
||||||
}
|
|
||||||
else if (key.Raw == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isKeyRepeat)
|
currentKeyState.Position = keyPosition;
|
||||||
{
|
key.KeyCode = GetKeyCodeFromScanCode(key.ScanCode, keyboardState.KeyModState);
|
||||||
KeyMod newModifier = {};
|
}
|
||||||
|
else if (key.Raw == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isKeyRepeat)
|
||||||
|
{
|
||||||
|
KeyMod newModifier = {};
|
||||||
|
|
||||||
|
switch (key.KeyCode)
|
||||||
|
{
|
||||||
|
case KeyCode::LeftControl: newModifier = KeyMod::LeftControl; break;
|
||||||
|
case KeyCode::RightControl: newModifier = KeyMod::RightControl; break;
|
||||||
|
case KeyCode::LeftShift: newModifier = KeyMod::LeftShift; break;
|
||||||
|
case KeyCode::RightShift: newModifier = KeyMod::RightShift; break;
|
||||||
|
case KeyCode::LeftAlt: newModifier = KeyMod::LeftAlt; break;
|
||||||
|
case KeyCode::RightAlt: newModifier = KeyMod::RightAlt; break;
|
||||||
|
case KeyCode::LeftOSCommand: newModifier = KeyMod::LeftOSCommand; break;
|
||||||
|
case KeyCode::RightOSCommand: newModifier = KeyMod::RightOSCommand; break;
|
||||||
|
default: newModifier = KeyMod::None; break;
|
||||||
|
}
|
||||||
|
if (type == EventType::Key_Down)
|
||||||
|
{
|
||||||
switch (key.KeyCode)
|
switch (key.KeyCode)
|
||||||
{
|
{
|
||||||
case KeyCode::LeftControl: newModifier = KeyMod::LeftControl; break;
|
case KeyCode::NumlockClear: newModifier ^= KeyMod::NumLock; break;
|
||||||
case KeyCode::RightControl: newModifier = KeyMod::RightControl; break;
|
case KeyCode::CapsLock: newModifier ^= KeyMod::CapsLock; break;
|
||||||
case KeyCode::LeftShift: newModifier = KeyMod::LeftShift; break;
|
case KeyCode::ScrollLock: newModifier ^= KeyMod::ScrollLock; break;
|
||||||
case KeyCode::RightShift: newModifier = KeyMod::RightShift; break;
|
default: keyboardState.KeyModState |= newModifier;
|
||||||
case KeyCode::LeftAlt: newModifier = KeyMod::LeftAlt; break;
|
|
||||||
case KeyCode::RightAlt: newModifier = KeyMod::RightAlt; break;
|
|
||||||
case KeyCode::LeftOSCommand: newModifier = KeyMod::LeftOSCommand; break;
|
|
||||||
case KeyCode::RightOSCommand: newModifier = KeyMod::RightOSCommand; break;
|
|
||||||
default: newModifier = KeyMod::None; break;
|
|
||||||
}
|
|
||||||
if (type == EventType::Key_Down)
|
|
||||||
{
|
|
||||||
switch (key.KeyCode)
|
|
||||||
{
|
|
||||||
case KeyCode::NumlockClear: newModifier ^= KeyMod::NumLock; break;
|
|
||||||
case KeyCode::CapsLock: newModifier ^= KeyMod::CapsLock; break;
|
|
||||||
case KeyCode::ScrollLock: newModifier ^= KeyMod::ScrollLock; break;
|
|
||||||
default: keyboardState.KeyModState |= newModifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove from any keymod not pressed from the modifier
|
|
||||||
keyboardState.KeyModState &= ~newModifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemEvent evt;
|
|
||||||
evt.Timestamp = timestamp;
|
|
||||||
evt.Type = type;
|
|
||||||
evt.Data.Keyboard.AssociatedKeyboardID = kGlobalKeyboardID;
|
|
||||||
evt.Data.Keyboard.Key = key;
|
|
||||||
evt.Data.Keyboard.KeyState = { keyPosition, 0.0f };
|
|
||||||
evt.Data.Keyboard.KeyModeState = keyboardState.KeyModState;
|
|
||||||
|
|
||||||
bool evtPosted = AddEvent(evt);
|
|
||||||
|
|
||||||
return evtPosted;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition)
|
|
||||||
{
|
|
||||||
return SendKeyboardKey_Internal(timestamp, ID, key, keyPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateKeyboardstate(float deltaTime)
|
|
||||||
{
|
|
||||||
for (KeyState& state : KeyboardState.KeyState)
|
|
||||||
{
|
|
||||||
if (state.Position == KeyPosition::Down)
|
|
||||||
{
|
|
||||||
if (state.Time < 0.0f)
|
|
||||||
{
|
|
||||||
state.Time = 0.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.Time += deltaTime;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.Time = -1.0f;
|
// Remove from any keymod not pressed from the modifier
|
||||||
|
keyboardState.KeyModState &= ~newModifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool IsKeyDown(ScanCode scanCode)
|
SystemEvent evt;
|
||||||
|
evt.Timestamp = timestamp;
|
||||||
|
evt.Type = type;
|
||||||
|
evt.Data.Keyboard.AssociatedKeyboardID = kGlobalKeyboardID;
|
||||||
|
evt.Data.Keyboard.Key = key;
|
||||||
|
evt.Data.Keyboard.KeyState = { keyPosition, 0.0f };
|
||||||
|
evt.Data.Keyboard.KeyModeState = keyboardState.KeyModState;
|
||||||
|
|
||||||
|
bool evtPosted = AddEvent(evt);
|
||||||
|
|
||||||
|
return evtPosted;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition)
|
||||||
|
{
|
||||||
|
return SendKeyboardKey_Internal(timestamp, ID, key, keyPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateKeyboardstate(float deltaTime)
|
||||||
|
{
|
||||||
|
for (KeyState& state : KeyboardState.KeyState)
|
||||||
{
|
{
|
||||||
return KeyboardState.KeyState[ToUnderlying(scanCode)].Position == KeyPosition::Down;
|
if (state.Position == KeyPosition::Down)
|
||||||
|
{
|
||||||
|
if (state.Time < 0.0f)
|
||||||
|
{
|
||||||
|
state.Time = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.Time += deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.Time = -1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsKeyPressed(ScanCode scanCode)
|
bool IsKeyDown(ScanCode scanCode)
|
||||||
{
|
{
|
||||||
auto& keyState = KeyboardState.KeyState[ToUnderlying(scanCode)];
|
return KeyboardState.KeyState[ToUnderlying(scanCode)].Position == KeyPosition::Down;
|
||||||
return keyState.Position == KeyPosition::Down && keyState.Time == 0.0f;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
KeyMod GetKeyModState()
|
bool IsKeyPressed(ScanCode scanCode)
|
||||||
{
|
{
|
||||||
auto& keyboardState = KeyboardState;
|
auto& keyState = KeyboardState.KeyState[ToUnderlying(scanCode)];
|
||||||
return keyboardState.KeyModState;
|
return keyState.Position == KeyPosition::Down && keyState.Time == 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState)
|
KeyMod GetKeyModState()
|
||||||
{
|
{
|
||||||
return GetKeyCodeFromDefaultMapping(scanCode, keyModState);
|
auto& keyboardState = KeyboardState;
|
||||||
}
|
return keyboardState.KeyModState;
|
||||||
|
}
|
||||||
|
|
||||||
static_assert(sizeof(KeyPosition) == sizeof(bool));
|
KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState)
|
||||||
static_assert(ToUnderlying(KeyPosition::Down) == true);
|
{
|
||||||
static_assert(ToUnderlying(KeyPosition::Up) == false);
|
return GetKeyCodeFromDefaultMapping(scanCode, keyModState);
|
||||||
static_assert(sizeof(ScanCode) == sizeof(uint16));
|
}
|
||||||
static_assert(ToUnderlying(ScanCode::Count) == 512);
|
|
||||||
} // namespace Juliet
|
static_assert(sizeof(KeyPosition) == sizeof(bool));
|
||||||
|
static_assert(ToUnderlying(KeyPosition::Down) == true);
|
||||||
|
static_assert(ToUnderlying(KeyPosition::Up) == false);
|
||||||
|
static_assert(sizeof(ScanCode) == sizeof(uint16));
|
||||||
|
static_assert(ToUnderlying(ScanCode::Count) == 512);
|
||||||
|
|||||||
@@ -1,204 +1,201 @@
|
|||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
#include <Core/Common/EnumUtils.h>
|
#include <Core/Common/EnumUtils.h>
|
||||||
#include <Core/HAL/Event/KeyboardMapping.h>
|
#include <Core/HAL/Event/KeyboardMapping.h>
|
||||||
#include <Core/HAL/Keyboard/KeyCode.h>
|
#include <Core/HAL/Keyboard/KeyCode.h>
|
||||||
#include <Core/HAL/Keyboard/ScanCode.h>
|
#include <Core/HAL/Keyboard/ScanCode.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace
|
||||||
{
|
{
|
||||||
namespace
|
// clang-format off
|
||||||
|
KeyCode UnshiftedDefaultSymbols[] = {
|
||||||
|
KeyCode::Num1,
|
||||||
|
KeyCode::Num2,
|
||||||
|
KeyCode::Num3,
|
||||||
|
KeyCode::Num4,
|
||||||
|
KeyCode::Num5,
|
||||||
|
KeyCode::Num6,
|
||||||
|
KeyCode::Num7,
|
||||||
|
KeyCode::Num8,
|
||||||
|
KeyCode::Num9,
|
||||||
|
KeyCode::Num0,
|
||||||
|
KeyCode::Return,
|
||||||
|
KeyCode::Escape,
|
||||||
|
KeyCode::Backspace,
|
||||||
|
KeyCode::Tab,
|
||||||
|
KeyCode::Space,
|
||||||
|
KeyCode::Minus,
|
||||||
|
KeyCode::Equals,
|
||||||
|
KeyCode::LeftBracket,
|
||||||
|
KeyCode::RightBracket,
|
||||||
|
KeyCode::Backslash,
|
||||||
|
KeyCode::Hash,
|
||||||
|
KeyCode::Semicolon,
|
||||||
|
KeyCode::Apostrophe,
|
||||||
|
KeyCode::GraveAccent,
|
||||||
|
KeyCode::Comma,
|
||||||
|
KeyCode::Period,
|
||||||
|
KeyCode::Slash,
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyCode ShiftedDefaultSymbols[] = {
|
||||||
|
KeyCode::ExclamationPoint,
|
||||||
|
KeyCode::CommercialAt,
|
||||||
|
KeyCode::Hash,
|
||||||
|
KeyCode::Dollar,
|
||||||
|
KeyCode::Percent,
|
||||||
|
KeyCode::Caret,
|
||||||
|
KeyCode::Ampersand,
|
||||||
|
KeyCode::Asterisk,
|
||||||
|
KeyCode::LeftParenthesis,
|
||||||
|
KeyCode::RightParenthesis,
|
||||||
|
KeyCode::Return,
|
||||||
|
KeyCode::Escape,
|
||||||
|
KeyCode::Backspace,
|
||||||
|
KeyCode::Tab,
|
||||||
|
KeyCode::Space,
|
||||||
|
KeyCode::Underscore,
|
||||||
|
KeyCode::Plus,
|
||||||
|
KeyCode::LeftBrace,
|
||||||
|
KeyCode::RightBrace,
|
||||||
|
KeyCode::Pipe,
|
||||||
|
KeyCode::Hash,
|
||||||
|
KeyCode::Colon,
|
||||||
|
KeyCode::DoubleApostrophe,
|
||||||
|
KeyCode::Tilde,
|
||||||
|
KeyCode::LessThan,
|
||||||
|
KeyCode::GreaterThan,
|
||||||
|
KeyCode::QuestionMark,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
KeyCode GetNonPrintableKeys(ScanCode scanCode)
|
||||||
{
|
{
|
||||||
// clang-format off
|
switch (scanCode)
|
||||||
KeyCode UnshiftedDefaultSymbols[] = {
|
|
||||||
KeyCode::Num1,
|
|
||||||
KeyCode::Num2,
|
|
||||||
KeyCode::Num3,
|
|
||||||
KeyCode::Num4,
|
|
||||||
KeyCode::Num5,
|
|
||||||
KeyCode::Num6,
|
|
||||||
KeyCode::Num7,
|
|
||||||
KeyCode::Num8,
|
|
||||||
KeyCode::Num9,
|
|
||||||
KeyCode::Num0,
|
|
||||||
KeyCode::Return,
|
|
||||||
KeyCode::Escape,
|
|
||||||
KeyCode::Backspace,
|
|
||||||
KeyCode::Tab,
|
|
||||||
KeyCode::Space,
|
|
||||||
KeyCode::Minus,
|
|
||||||
KeyCode::Equals,
|
|
||||||
KeyCode::LeftBracket,
|
|
||||||
KeyCode::RightBracket,
|
|
||||||
KeyCode::Backslash,
|
|
||||||
KeyCode::Hash,
|
|
||||||
KeyCode::Semicolon,
|
|
||||||
KeyCode::Apostrophe,
|
|
||||||
KeyCode::GraveAccent,
|
|
||||||
KeyCode::Comma,
|
|
||||||
KeyCode::Period,
|
|
||||||
KeyCode::Slash,
|
|
||||||
};
|
|
||||||
|
|
||||||
KeyCode ShiftedDefaultSymbols[] = {
|
|
||||||
KeyCode::ExclamationPoint,
|
|
||||||
KeyCode::CommercialAt,
|
|
||||||
KeyCode::Hash,
|
|
||||||
KeyCode::Dollar,
|
|
||||||
KeyCode::Percent,
|
|
||||||
KeyCode::Caret,
|
|
||||||
KeyCode::Ampersand,
|
|
||||||
KeyCode::Asterisk,
|
|
||||||
KeyCode::LeftParenthesis,
|
|
||||||
KeyCode::RightParenthesis,
|
|
||||||
KeyCode::Return,
|
|
||||||
KeyCode::Escape,
|
|
||||||
KeyCode::Backspace,
|
|
||||||
KeyCode::Tab,
|
|
||||||
KeyCode::Space,
|
|
||||||
KeyCode::Underscore,
|
|
||||||
KeyCode::Plus,
|
|
||||||
KeyCode::LeftBrace,
|
|
||||||
KeyCode::RightBrace,
|
|
||||||
KeyCode::Pipe,
|
|
||||||
KeyCode::Hash,
|
|
||||||
KeyCode::Colon,
|
|
||||||
KeyCode::DoubleApostrophe,
|
|
||||||
KeyCode::Tilde,
|
|
||||||
KeyCode::LessThan,
|
|
||||||
KeyCode::GreaterThan,
|
|
||||||
KeyCode::QuestionMark,
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
KeyCode GetNonPrintableKeys(ScanCode scanCode)
|
|
||||||
{
|
{
|
||||||
switch (scanCode)
|
case ScanCode::Delete: return KeyCode::Delete;
|
||||||
{
|
case ScanCode::CapsLock: return KeyCode::CapsLock;
|
||||||
case ScanCode::Delete: return KeyCode::Delete;
|
case ScanCode::F1: return KeyCode::F1;
|
||||||
case ScanCode::CapsLock: return KeyCode::CapsLock;
|
case ScanCode::F2: return KeyCode::F2;
|
||||||
case ScanCode::F1: return KeyCode::F1;
|
case ScanCode::F3: return KeyCode::F3;
|
||||||
case ScanCode::F2: return KeyCode::F2;
|
case ScanCode::F4: return KeyCode::F4;
|
||||||
case ScanCode::F3: return KeyCode::F3;
|
case ScanCode::F5: return KeyCode::F5;
|
||||||
case ScanCode::F4: return KeyCode::F4;
|
case ScanCode::F6: return KeyCode::F6;
|
||||||
case ScanCode::F5: return KeyCode::F5;
|
case ScanCode::F7: return KeyCode::F7;
|
||||||
case ScanCode::F6: return KeyCode::F6;
|
case ScanCode::F8: return KeyCode::F8;
|
||||||
case ScanCode::F7: return KeyCode::F7;
|
case ScanCode::F9: return KeyCode::F9;
|
||||||
case ScanCode::F8: return KeyCode::F8;
|
case ScanCode::F10: return KeyCode::F10;
|
||||||
case ScanCode::F9: return KeyCode::F9;
|
case ScanCode::F11: return KeyCode::F11;
|
||||||
case ScanCode::F10: return KeyCode::F10;
|
case ScanCode::F12: return KeyCode::F12;
|
||||||
case ScanCode::F11: return KeyCode::F11;
|
case ScanCode::PrintScreen: return KeyCode::PrintScreen;
|
||||||
case ScanCode::F12: return KeyCode::F12;
|
case ScanCode::ScrollLock: return KeyCode::ScrollLock;
|
||||||
case ScanCode::PrintScreen: return KeyCode::PrintScreen;
|
case ScanCode::Pause: return KeyCode::Pause;
|
||||||
case ScanCode::ScrollLock: return KeyCode::ScrollLock;
|
case ScanCode::Insert: return KeyCode::Insert;
|
||||||
case ScanCode::Pause: return KeyCode::Pause;
|
case ScanCode::Home: return KeyCode::Home;
|
||||||
case ScanCode::Insert: return KeyCode::Insert;
|
case ScanCode::PageUp: return KeyCode::PageUp;
|
||||||
case ScanCode::Home: return KeyCode::Home;
|
case ScanCode::End: return KeyCode::End;
|
||||||
case ScanCode::PageUp: return KeyCode::PageUp;
|
case ScanCode::PageDown: return KeyCode::PageDown;
|
||||||
case ScanCode::End: return KeyCode::End;
|
case ScanCode::RightArrow: return KeyCode::RightArrow;
|
||||||
case ScanCode::PageDown: return KeyCode::PageDown;
|
case ScanCode::LeftArrow: return KeyCode::LeftArrow;
|
||||||
case ScanCode::RightArrow: return KeyCode::RightArrow;
|
case ScanCode::DownArrow: return KeyCode::DownArrow;
|
||||||
case ScanCode::LeftArrow: return KeyCode::LeftArrow;
|
case ScanCode::UpArrow: return KeyCode::UpArrow;
|
||||||
case ScanCode::DownArrow: return KeyCode::DownArrow;
|
case ScanCode::NumlockClear: return KeyCode::NumlockClear;
|
||||||
case ScanCode::UpArrow: return KeyCode::UpArrow;
|
case ScanCode::KeyPad_Divide: return KeyCode::KeyPad_Divide;
|
||||||
case ScanCode::NumlockClear: return KeyCode::NumlockClear;
|
case ScanCode::KeyPad_Multiply: return KeyCode::KeyPad_Multiply;
|
||||||
case ScanCode::KeyPad_Divide: return KeyCode::KeyPad_Divide;
|
case ScanCode::KeyPad_Minus: return KeyCode::KeyPad_Minus;
|
||||||
case ScanCode::KeyPad_Multiply: return KeyCode::KeyPad_Multiply;
|
case ScanCode::KeyPad_Plus: return KeyCode::KeyPad_Plus;
|
||||||
case ScanCode::KeyPad_Minus: return KeyCode::KeyPad_Minus;
|
case ScanCode::KeyPad_Enter: return KeyCode::KeyPad_Enter;
|
||||||
case ScanCode::KeyPad_Plus: return KeyCode::KeyPad_Plus;
|
case ScanCode::KeyPad_Num1: return KeyCode::KeyPad_Num1;
|
||||||
case ScanCode::KeyPad_Enter: return KeyCode::KeyPad_Enter;
|
case ScanCode::KeyPad_Num2: return KeyCode::KeyPad_Num2;
|
||||||
case ScanCode::KeyPad_Num1: return KeyCode::KeyPad_Num1;
|
case ScanCode::KeyPad_Num3: return KeyCode::KeyPad_Num3;
|
||||||
case ScanCode::KeyPad_Num2: return KeyCode::KeyPad_Num2;
|
case ScanCode::KeyPad_Num4: return KeyCode::KeyPad_Num4;
|
||||||
case ScanCode::KeyPad_Num3: return KeyCode::KeyPad_Num3;
|
case ScanCode::KeyPad_Num5: return KeyCode::KeyPad_Num5;
|
||||||
case ScanCode::KeyPad_Num4: return KeyCode::KeyPad_Num4;
|
case ScanCode::KeyPad_Num6: return KeyCode::KeyPad_Num6;
|
||||||
case ScanCode::KeyPad_Num5: return KeyCode::KeyPad_Num5;
|
case ScanCode::KeyPad_Num7: return KeyCode::KeyPad_Num7;
|
||||||
case ScanCode::KeyPad_Num6: return KeyCode::KeyPad_Num6;
|
case ScanCode::KeyPad_Num8: return KeyCode::KeyPad_Num8;
|
||||||
case ScanCode::KeyPad_Num7: return KeyCode::KeyPad_Num7;
|
case ScanCode::KeyPad_Num9: return KeyCode::KeyPad_Num9;
|
||||||
case ScanCode::KeyPad_Num8: return KeyCode::KeyPad_Num8;
|
case ScanCode::KeyPad_Num0: return KeyCode::KeyPad_Num0;
|
||||||
case ScanCode::KeyPad_Num9: return KeyCode::KeyPad_Num9;
|
case ScanCode::KeyPad_Period: return KeyCode::KeyPad_Period;
|
||||||
case ScanCode::KeyPad_Num0: return KeyCode::KeyPad_Num0;
|
case ScanCode::Power: return KeyCode::Power;
|
||||||
case ScanCode::KeyPad_Period: return KeyCode::KeyPad_Period;
|
case ScanCode::KeyPad_Equals: return KeyCode::KeyPad_Equals;
|
||||||
case ScanCode::Power: return KeyCode::Power;
|
case ScanCode::F13: return KeyCode::F13;
|
||||||
case ScanCode::KeyPad_Equals: return KeyCode::KeyPad_Equals;
|
case ScanCode::F14: return KeyCode::F14;
|
||||||
case ScanCode::F13: return KeyCode::F13;
|
case ScanCode::F15: return KeyCode::F15;
|
||||||
case ScanCode::F14: return KeyCode::F14;
|
case ScanCode::F16: return KeyCode::F16;
|
||||||
case ScanCode::F15: return KeyCode::F15;
|
case ScanCode::F17: return KeyCode::F17;
|
||||||
case ScanCode::F16: return KeyCode::F16;
|
case ScanCode::F18: return KeyCode::F18;
|
||||||
case ScanCode::F17: return KeyCode::F17;
|
case ScanCode::F19: return KeyCode::F19;
|
||||||
case ScanCode::F18: return KeyCode::F18;
|
case ScanCode::F20: return KeyCode::F20;
|
||||||
case ScanCode::F19: return KeyCode::F19;
|
case ScanCode::F21: return KeyCode::F21;
|
||||||
case ScanCode::F20: return KeyCode::F20;
|
case ScanCode::F22: return KeyCode::F22;
|
||||||
case ScanCode::F21: return KeyCode::F21;
|
case ScanCode::F23: return KeyCode::F23;
|
||||||
case ScanCode::F22: return KeyCode::F22;
|
case ScanCode::F24: return KeyCode::F24;
|
||||||
case ScanCode::F23: return KeyCode::F23;
|
case ScanCode::Mute: return KeyCode::Mute;
|
||||||
case ScanCode::F24: return KeyCode::F24;
|
case ScanCode::VolumeUp: return KeyCode::VolumeUp;
|
||||||
case ScanCode::Mute: return KeyCode::Mute;
|
case ScanCode::VolumeDown: return KeyCode::VolumeDown;
|
||||||
case ScanCode::VolumeUp: return KeyCode::VolumeUp;
|
case ScanCode::KeyPad_Comma: return KeyCode::KeyPad_Comma;
|
||||||
case ScanCode::VolumeDown: return KeyCode::VolumeDown;
|
case ScanCode::LeftControl: return KeyCode::LeftControl;
|
||||||
case ScanCode::KeyPad_Comma: return KeyCode::KeyPad_Comma;
|
case ScanCode::LeftShift: return KeyCode::LeftShift;
|
||||||
case ScanCode::LeftControl: return KeyCode::LeftControl;
|
case ScanCode::LeftAlt: return KeyCode::LeftAlt;
|
||||||
case ScanCode::LeftShift: return KeyCode::LeftShift;
|
case ScanCode::LeftOSCommand: return KeyCode::LeftOSCommand;
|
||||||
case ScanCode::LeftAlt: return KeyCode::LeftAlt;
|
case ScanCode::RightControl: return KeyCode::RightControl;
|
||||||
case ScanCode::LeftOSCommand: return KeyCode::LeftOSCommand;
|
case ScanCode::RightShift: return KeyCode::RightShift;
|
||||||
case ScanCode::RightControl: return KeyCode::RightControl;
|
case ScanCode::RightAlt: return KeyCode::RightAlt;
|
||||||
case ScanCode::RightShift: return KeyCode::RightShift;
|
case ScanCode::RightOSCommand: return KeyCode::RightOSCommand;
|
||||||
case ScanCode::RightAlt: return KeyCode::RightAlt;
|
case ScanCode::Sleep: return KeyCode::Sleep;
|
||||||
case ScanCode::RightOSCommand: return KeyCode::RightOSCommand;
|
case ScanCode::WakeUp: return KeyCode::WakeUp;
|
||||||
case ScanCode::Sleep: return KeyCode::Sleep;
|
case ScanCode::Media_NextTrack: return KeyCode::Media_NextTrack;
|
||||||
case ScanCode::WakeUp: return KeyCode::WakeUp;
|
case ScanCode::Media_PreviousTrack: return KeyCode::Media_PreviousTrack;
|
||||||
case ScanCode::Media_NextTrack: return KeyCode::Media_NextTrack;
|
case ScanCode::Media_Stop: return KeyCode::Media_Stop;
|
||||||
case ScanCode::Media_PreviousTrack: return KeyCode::Media_PreviousTrack;
|
case ScanCode::Media_Eject: return KeyCode::Media_Eject;
|
||||||
case ScanCode::Media_Stop: return KeyCode::Media_Stop;
|
case ScanCode::Media_PlayPause: return KeyCode::Media_PlayPause;
|
||||||
case ScanCode::Media_Eject: return KeyCode::Media_Eject;
|
case ScanCode::Media_Select: return KeyCode::Media_Select;
|
||||||
case ScanCode::Media_PlayPause: return KeyCode::Media_PlayPause;
|
default: return KeyCode::Unknown;
|
||||||
case ScanCode::Media_Select: return KeyCode::Media_Select;
|
|
||||||
default: return KeyCode::Unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace
|
|
||||||
|
|
||||||
KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState)
|
|
||||||
{
|
|
||||||
if (scanCode <= ScanCode::Unknown || scanCode > ScanCode::Count)
|
|
||||||
{
|
|
||||||
Assert(false , "Unsupported KeyCode (out of bounds)");
|
|
||||||
return KeyCode::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scanCode < ScanCode::A)
|
|
||||||
{
|
|
||||||
return KeyCode::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles A-Z characters
|
|
||||||
if (scanCode <= ScanCode::Z)
|
|
||||||
{
|
|
||||||
const auto index = scanCode - ScanCode::A;
|
|
||||||
bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
|
|
||||||
if ((keyModState & KeyMod::CapsLock) != KeyMod::None)
|
|
||||||
{
|
|
||||||
isShiftPressed = !isShiftPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isShiftPressed)
|
|
||||||
{
|
|
||||||
return ToEnum<KeyCode>(static_cast<uint32>('A') + index);
|
|
||||||
}
|
|
||||||
return ToEnum<KeyCode>(static_cast<uint32>('a') + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles Num1 to Num0
|
|
||||||
if (scanCode <= ScanCode::Num0)
|
|
||||||
{
|
|
||||||
const auto index = scanCode - ScanCode::Num1;
|
|
||||||
const bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
|
|
||||||
if (isShiftPressed)
|
|
||||||
{
|
|
||||||
return ShiftedDefaultSymbols[index];
|
|
||||||
}
|
|
||||||
return UnshiftedDefaultSymbols[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle everything else (characters that do not convert to ASCII code)
|
|
||||||
return GetNonPrintableKeys(scanCode);
|
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
} // namespace
|
||||||
|
|
||||||
|
KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState)
|
||||||
|
{
|
||||||
|
if (scanCode <= ScanCode::Unknown || scanCode > ScanCode::Count)
|
||||||
|
{
|
||||||
|
Assert(false , "Unsupported KeyCode (out of bounds)");
|
||||||
|
return KeyCode::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scanCode < ScanCode::A)
|
||||||
|
{
|
||||||
|
return KeyCode::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles A-Z characters
|
||||||
|
if (scanCode <= ScanCode::Z)
|
||||||
|
{
|
||||||
|
const auto index = scanCode - ScanCode::A;
|
||||||
|
bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
|
||||||
|
if ((keyModState & KeyMod::CapsLock) != KeyMod::None)
|
||||||
|
{
|
||||||
|
isShiftPressed = !isShiftPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isShiftPressed)
|
||||||
|
{
|
||||||
|
return ToEnum<KeyCode>(static_cast<uint32>('A') + index);
|
||||||
|
}
|
||||||
|
return ToEnum<KeyCode>(static_cast<uint32>('a') + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles Num1 to Num0
|
||||||
|
if (scanCode <= ScanCode::Num0)
|
||||||
|
{
|
||||||
|
const auto index = scanCode - ScanCode::Num1;
|
||||||
|
const bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
|
||||||
|
if (isShiftPressed)
|
||||||
|
{
|
||||||
|
return ShiftedDefaultSymbols[index];
|
||||||
|
}
|
||||||
|
return UnshiftedDefaultSymbols[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle everything else (characters that do not convert to ASCII code)
|
||||||
|
return GetNonPrintableKeys(scanCode);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Keyboard/KeyCode.h>
|
#include <Core/HAL/Keyboard/KeyCode.h>
|
||||||
#include <Core/HAL/Keyboard/ScanCode.h>
|
#include <Core/HAL/Keyboard/ScanCode.h>
|
||||||
|
|
||||||
namespace Juliet
|
// Transforms ScanCode into KeyCode using the default US ASCII Mapping
|
||||||
{
|
extern KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState);
|
||||||
// Transforms ScanCode into KeyCode using the default US ASCII Mapping
|
|
||||||
extern KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState);
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Keyboard/Keyboard.h>
|
#include <Core/HAL/Keyboard/Keyboard.h>
|
||||||
#include <Core/HAL/Keyboard/KeyCode.h>
|
#include <Core/HAL/Keyboard/KeyCode.h>
|
||||||
|
|
||||||
namespace Juliet
|
extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition);
|
||||||
{
|
extern void UpdateKeyboardstate(float deltaTime);
|
||||||
extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition);
|
|
||||||
extern void UpdateKeyboardstate(float deltaTime);
|
|
||||||
|
|
||||||
extern const KeyboardID kGlobalKeyboardID;
|
extern const KeyboardID kGlobalKeyboardID;
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
+116
-119
@@ -1,158 +1,155 @@
|
|||||||
#include <Core/Common/EnumUtils.h>
|
#include <Core/Common/EnumUtils.h>
|
||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
#include <Core/HAL/Event/Mouse_Private.h>
|
#include <Core/HAL/Event/Mouse_Private.h>
|
||||||
#include <Core/HAL/Event/SystemEvent.h>
|
#include <Core/HAL/Event/SystemEvent.h>
|
||||||
#include <Core/HAL/Mouse/Mouse.h>
|
#include <Core/HAL/Mouse/Mouse.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace
|
||||||
{
|
{
|
||||||
namespace
|
Mouse MouseState;
|
||||||
|
|
||||||
|
void ConstraintMousePositionToWindow(Mouse& mouseState, Window* window, float& x, float& y)
|
||||||
{
|
{
|
||||||
Mouse MouseState;
|
float x_min = 0.f, x_max = (float)(window->Width - 1);
|
||||||
|
float y_min = 0.f, y_max = (float)(window->Height - 1);
|
||||||
|
|
||||||
void ConstraintMousePositionToWindow(Mouse& mouseState, Window* window, float& x, float& y)
|
if (x >= (x_max + 1))
|
||||||
{
|
{
|
||||||
float x_min = 0.f, x_max = (float)(window->Width - 1);
|
x = std::max(x_max, mouseState.X_Previous);
|
||||||
float y_min = 0.f, y_max = (float)(window->Height - 1);
|
|
||||||
|
|
||||||
if (x >= (x_max + 1))
|
|
||||||
{
|
|
||||||
x = std::max(x_max, mouseState.X_Previous);
|
|
||||||
}
|
|
||||||
x = std::max(x, x_min);
|
|
||||||
|
|
||||||
if (y >= (y_max + 1))
|
|
||||||
{
|
|
||||||
y = std::max(y_max, mouseState.Y_Previous);
|
|
||||||
}
|
|
||||||
y = std::max(y, y_min);
|
|
||||||
}
|
}
|
||||||
|
x = std::max(x, x_min);
|
||||||
|
|
||||||
void SendMouseMotion_Internal(uint64 timestamp, Window* window, MouseID mouseID, float x, float y)
|
if (y >= (y_max + 1))
|
||||||
{
|
{
|
||||||
auto& mouseState = GetMouseState();
|
y = std::max(y_max, mouseState.Y_Previous);
|
||||||
float xDisplacement = 0.0f;
|
|
||||||
float yDisplacement = 0.0f;
|
|
||||||
|
|
||||||
ConstraintMousePositionToWindow(mouseState, window, x, y);
|
|
||||||
|
|
||||||
if (mouseState.HasPosition)
|
|
||||||
{
|
|
||||||
xDisplacement = x - mouseState.X_Previous;
|
|
||||||
yDisplacement = y - mouseState.Y_Previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouseState.HasPosition && xDisplacement == 0.0f && yDisplacement == 0.0f)
|
|
||||||
{
|
|
||||||
// Skip it because state didnt change
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mouseState.X = x;
|
|
||||||
mouseState.Y = y;
|
|
||||||
mouseState.HasPosition = true;
|
|
||||||
|
|
||||||
mouseState.X_Previous = x;
|
|
||||||
mouseState.Y_Previous = y;
|
|
||||||
|
|
||||||
mouseState.DeltaX += xDisplacement;
|
|
||||||
mouseState.DeltaY += yDisplacement;
|
|
||||||
|
|
||||||
SystemEvent evt;
|
|
||||||
evt.Type = EventType::Mouse_Move;
|
|
||||||
evt.Timestamp = timestamp;
|
|
||||||
evt.Data.MouseMovement.WindowID = window->ID;
|
|
||||||
evt.Data.MouseMovement.AssociatedMouseID = mouseID;
|
|
||||||
evt.Data.MouseMovement.X = x;
|
|
||||||
evt.Data.MouseMovement.Y = y;
|
|
||||||
evt.Data.MouseMovement.X_Displacement = xDisplacement;
|
|
||||||
evt.Data.MouseMovement.Y_Displacement = yDisplacement;
|
|
||||||
evt.Data.MouseMovement.ButtonState = mouseState.ButtonState;
|
|
||||||
AddEvent(evt);
|
|
||||||
}
|
}
|
||||||
|
y = std::max(y, y_min);
|
||||||
} // namespace
|
|
||||||
|
|
||||||
constexpr MouseID kGlobalMouseID = 0;
|
|
||||||
|
|
||||||
Mouse& GetMouseState()
|
|
||||||
{
|
|
||||||
return MouseState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y)
|
void SendMouseMotion_Internal(uint64 timestamp, Window* window, MouseID mouseID, float x, float y)
|
||||||
{
|
{
|
||||||
// TODO : Update Mouse focus and send Mouse Enter / Mouse Leave event
|
auto& mouseState = GetMouseState();
|
||||||
|
float xDisplacement = 0.0f;
|
||||||
|
float yDisplacement = 0.0f;
|
||||||
|
|
||||||
SendMouseMotion_Internal(timestamp, window, ID, x, y);
|
ConstraintMousePositionToWindow(mouseState, window, x, y);
|
||||||
}
|
|
||||||
|
|
||||||
void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed)
|
if (mouseState.HasPosition)
|
||||||
{
|
|
||||||
Mouse& mouseState = GetMouseState();
|
|
||||||
MouseButton flags = mouseState.ButtonState;
|
|
||||||
|
|
||||||
auto type = EventType::None;
|
|
||||||
if (pressed)
|
|
||||||
{
|
{
|
||||||
type = EventType::Mouse_ButtonPressed;
|
xDisplacement = x - mouseState.X_Previous;
|
||||||
flags |= button;
|
yDisplacement = y - mouseState.Y_Previous;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
type = EventType::Mouse_ButtonReleased;
|
|
||||||
flags = flags & ~button;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags == mouseState.ButtonState)
|
if (mouseState.HasPosition && xDisplacement == 0.0f && yDisplacement == 0.0f)
|
||||||
{
|
{
|
||||||
|
// Skip it because state didnt change
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseState.ButtonState = flags;
|
mouseState.X = x;
|
||||||
|
mouseState.Y = y;
|
||||||
|
mouseState.HasPosition = true;
|
||||||
|
|
||||||
|
mouseState.X_Previous = x;
|
||||||
|
mouseState.Y_Previous = y;
|
||||||
|
|
||||||
|
mouseState.DeltaX += xDisplacement;
|
||||||
|
mouseState.DeltaY += yDisplacement;
|
||||||
|
|
||||||
// TODO : Send Event!
|
|
||||||
SystemEvent evt;
|
SystemEvent evt;
|
||||||
evt.Timestamp = timestamp;
|
evt.Type = EventType::Mouse_Move;
|
||||||
evt.Type = type;
|
evt.Timestamp = timestamp;
|
||||||
evt.Data.MouseButton.AssociatedMouseID = mouseID;
|
evt.Data.MouseMovement.WindowID = window->ID;
|
||||||
evt.Data.MouseButton.WindowID = window->ID;
|
evt.Data.MouseMovement.AssociatedMouseID = mouseID;
|
||||||
evt.Data.MouseButton.ButtonState = button;
|
evt.Data.MouseMovement.X = x;
|
||||||
evt.Data.MouseButton.X = mouseState.X;
|
evt.Data.MouseMovement.Y = y;
|
||||||
evt.Data.MouseButton.Y = mouseState.Y;
|
evt.Data.MouseMovement.X_Displacement = xDisplacement;
|
||||||
evt.Data.MouseButton.IsPressed = pressed;
|
evt.Data.MouseMovement.Y_Displacement = yDisplacement;
|
||||||
|
evt.Data.MouseMovement.ButtonState = mouseState.ButtonState;
|
||||||
AddEvent(evt);
|
AddEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMouseButtonDown(MouseButton button)
|
} // namespace
|
||||||
|
|
||||||
|
constexpr MouseID kGlobalMouseID = 0;
|
||||||
|
|
||||||
|
Mouse& GetMouseState()
|
||||||
|
{
|
||||||
|
return MouseState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y)
|
||||||
|
{
|
||||||
|
// TODO : Update Mouse focus and send Mouse Enter / Mouse Leave event
|
||||||
|
|
||||||
|
SendMouseMotion_Internal(timestamp, window, ID, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed)
|
||||||
|
{
|
||||||
|
Mouse& mouseState = GetMouseState();
|
||||||
|
MouseButton flags = mouseState.ButtonState;
|
||||||
|
|
||||||
|
auto type = EventType::None;
|
||||||
|
if (pressed)
|
||||||
{
|
{
|
||||||
auto& mouseState = GetMouseState();
|
type = EventType::Mouse_ButtonPressed;
|
||||||
return (mouseState.ButtonState & button) != MouseButton::None;
|
flags |= button;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = EventType::Mouse_ButtonReleased;
|
||||||
|
flags = flags & ~button;
|
||||||
}
|
}
|
||||||
|
|
||||||
MousePosition GetMousePosition()
|
if (flags == mouseState.ButtonState)
|
||||||
{
|
{
|
||||||
auto& mouseState = GetMouseState();
|
return;
|
||||||
return { .X = mouseState.X, .Y = mouseState.Y };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MousePosition GetMouseDelta()
|
mouseState.ButtonState = flags;
|
||||||
{
|
|
||||||
auto& mouseState = GetMouseState();
|
|
||||||
return { .X = mouseState.DeltaX, .Y = mouseState.DeltaY };
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseButton GetMouseButtonState()
|
// TODO : Send Event!
|
||||||
{
|
SystemEvent evt;
|
||||||
const auto& mouseState = GetMouseState();
|
evt.Timestamp = timestamp;
|
||||||
return mouseState.ButtonState;
|
evt.Type = type;
|
||||||
}
|
evt.Data.MouseButton.AssociatedMouseID = mouseID;
|
||||||
|
evt.Data.MouseButton.WindowID = window->ID;
|
||||||
|
evt.Data.MouseButton.ButtonState = button;
|
||||||
|
evt.Data.MouseButton.X = mouseState.X;
|
||||||
|
evt.Data.MouseButton.Y = mouseState.Y;
|
||||||
|
evt.Data.MouseButton.IsPressed = pressed;
|
||||||
|
AddEvent(evt);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateMouseState()
|
bool IsMouseButtonDown(MouseButton button)
|
||||||
{
|
{
|
||||||
auto& mouseState = GetMouseState();
|
auto& mouseState = GetMouseState();
|
||||||
mouseState.DeltaX = 0.0f;
|
return (mouseState.ButtonState & button) != MouseButton::None;
|
||||||
mouseState.DeltaY = 0.0f;
|
}
|
||||||
}
|
|
||||||
|
MousePosition GetMousePosition()
|
||||||
|
{
|
||||||
|
auto& mouseState = GetMouseState();
|
||||||
|
return { .X = mouseState.X, .Y = mouseState.Y };
|
||||||
|
}
|
||||||
|
|
||||||
|
MousePosition GetMouseDelta()
|
||||||
|
{
|
||||||
|
auto& mouseState = GetMouseState();
|
||||||
|
return { .X = mouseState.DeltaX, .Y = mouseState.DeltaY };
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseButton GetMouseButtonState()
|
||||||
|
{
|
||||||
|
const auto& mouseState = GetMouseState();
|
||||||
|
return mouseState.ButtonState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateMouseState()
|
||||||
|
{
|
||||||
|
auto& mouseState = GetMouseState();
|
||||||
|
mouseState.DeltaX = 0.0f;
|
||||||
|
mouseState.DeltaY = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Mouse/Mouse.h>
|
#include <Core/HAL/Mouse/Mouse.h>
|
||||||
|
|
||||||
namespace Juliet
|
struct Window;
|
||||||
|
|
||||||
|
struct Mouse
|
||||||
{
|
{
|
||||||
struct Window;
|
float X;
|
||||||
|
float Y;
|
||||||
|
|
||||||
struct Mouse
|
float X_Previous;
|
||||||
{
|
float Y_Previous;
|
||||||
float X;
|
|
||||||
float Y;
|
|
||||||
|
|
||||||
float X_Previous;
|
float DeltaX;
|
||||||
float Y_Previous;
|
float DeltaY;
|
||||||
|
|
||||||
float DeltaX;
|
MouseButton ButtonState;
|
||||||
float DeltaY;
|
|
||||||
|
|
||||||
MouseButton ButtonState;
|
bool HasPosition : 1;
|
||||||
|
};
|
||||||
|
|
||||||
bool HasPosition : 1;
|
Mouse& GetMouseState();
|
||||||
};
|
|
||||||
|
|
||||||
Mouse& GetMouseState();
|
extern void UpdateMouseState();
|
||||||
|
extern void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y);
|
||||||
|
extern void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed);
|
||||||
|
|
||||||
extern void UpdateMouseState();
|
extern const MouseID kGlobalMouseID;
|
||||||
extern void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y);
|
|
||||||
extern void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed);
|
|
||||||
|
|
||||||
extern const MouseID kGlobalMouseID;
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <Core/HAL/Display/DisplayDevice.h>
|
#include <Core/HAL/Display/DisplayDevice.h>
|
||||||
#include <Core/HAL/Event/SystemEvent.h>
|
#include <Core/HAL/Event/SystemEvent.h>
|
||||||
|
|
||||||
#include <Core/HAL/Event/Keyboard_Private.h>
|
#include <Core/HAL/Event/Keyboard_Private.h>
|
||||||
@@ -9,92 +9,89 @@
|
|||||||
|
|
||||||
#pragma pop_macro("global")
|
#pragma pop_macro("global")
|
||||||
|
|
||||||
namespace Juliet
|
namespace
|
||||||
{
|
{
|
||||||
namespace
|
// TODO : make my own queue / using vector
|
||||||
|
std::queue<SystemEvent> eventQueue;
|
||||||
|
|
||||||
|
// Update all systems event loops and gather events into the main queue
|
||||||
|
void PumpEvents()
|
||||||
{
|
{
|
||||||
// TODO : make my own queue / using vector
|
if (DisplayDevice* displayDevice = GetDisplayDevice())
|
||||||
std::queue<SystemEvent> eventQueue;
|
|
||||||
|
|
||||||
// Update all systems event loops and gather events into the main queue
|
|
||||||
void PumpEvents()
|
|
||||||
{
|
{
|
||||||
if (DisplayDevice* displayDevice = GetDisplayDevice())
|
displayDevice->PumpEvents(displayDevice);
|
||||||
{
|
|
||||||
displayDevice->PumpEvents(displayDevice);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddEvent_Internal(const SystemEvent& event)
|
|
||||||
{
|
|
||||||
auto& newEvent = eventQueue.emplace();
|
|
||||||
newEvent = event;
|
|
||||||
|
|
||||||
// TODO : Logs
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool GetEvent(SystemEvent& event)
|
|
||||||
{
|
|
||||||
return WaitEvent(event, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitEvent(SystemEvent& event, int32 timeoutInNS /* = -1 */)
|
bool AddEvent_Internal(const SystemEvent& event)
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
auto& newEvent = eventQueue.emplace();
|
||||||
|
newEvent = event;
|
||||||
|
|
||||||
// Handle the "Infinite Wait" and "Timed Wait" logic
|
// TODO : Logs
|
||||||
const bool isInfinite = (timeoutInNS < 0);
|
|
||||||
const nanoseconds timeout(timeoutInNS);
|
|
||||||
const auto startTime = steady_clock::now();
|
|
||||||
|
|
||||||
while (true)
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool GetEvent(SystemEvent& event)
|
||||||
|
{
|
||||||
|
return WaitEvent(event, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitEvent(SystemEvent& event, int32 timeoutInNS /* = -1 */)
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
// Handle the "Infinite Wait" and "Timed Wait" logic
|
||||||
|
const bool isInfinite = (timeoutInNS < 0);
|
||||||
|
const nanoseconds timeout(timeoutInNS);
|
||||||
|
const auto startTime = steady_clock::now();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
PumpEvents();
|
||||||
|
|
||||||
|
if (!eventQueue.empty())
|
||||||
{
|
{
|
||||||
PumpEvents();
|
event = eventQueue.front();
|
||||||
|
eventQueue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!eventQueue.empty())
|
// If timeout is 0, we only check once (PumpEvents already ran)
|
||||||
{
|
if (timeoutInNS == 0)
|
||||||
event = eventQueue.front();
|
{
|
||||||
eventQueue.pop();
|
break;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If timeout is 0, we only check once (PumpEvents already ran)
|
// Check if we have exceeded our time limit
|
||||||
if (timeoutInNS == 0)
|
if (!isInfinite)
|
||||||
|
{
|
||||||
|
auto elapsed = steady_clock::now() - startTime;
|
||||||
|
if (elapsed >= timeout)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have exceeded our time limit
|
|
||||||
if (!isInfinite)
|
|
||||||
{
|
|
||||||
auto elapsed = steady_clock::now() - startTime;
|
|
||||||
if (elapsed >= timeout)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddEvent(SystemEvent& event)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddEvent(SystemEvent& event)
|
||||||
|
{
|
||||||
|
if (event.Timestamp == 0)
|
||||||
{
|
{
|
||||||
if (event.Timestamp == 0)
|
event.Timestamp = 1; // TODO : Clock::Now();
|
||||||
{
|
|
||||||
event.Timestamp = 1; // TODO : Clock::Now();
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddEvent_Internal(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events_NewFrame(float deltaTime)
|
return AddEvent_Internal(event);
|
||||||
{
|
}
|
||||||
UpdateKeyboardstate(deltaTime);
|
|
||||||
UpdateMouseState();
|
void Events_NewFrame(float deltaTime)
|
||||||
}
|
{
|
||||||
|
UpdateKeyboardstate(deltaTime);
|
||||||
|
UpdateMouseState();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Core/HAL/Keyboard/ScanCode.h>
|
#include <Core/HAL/Keyboard/ScanCode.h>
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
// Conversion table from Win32 scan code to HID Usage Page (see Keyboard.h)
|
// Conversion table from Win32 scan code to HID Usage Page (see Keyboard.h)
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag
|
// https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag
|
||||||
@@ -267,4 +267,4 @@ namespace Juliet::Win32
|
|||||||
|
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
} // namespace Juliet::Win32
|
} // namespace Win32
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
#include <Core/HAL/Display/Window.h>
|
#include <Core/HAL/Display/Window.h>
|
||||||
#include <Core/HAL/Event/SystemEvent.h>
|
#include <Core/HAL/Event/SystemEvent.h>
|
||||||
#include <Core/HAL/Event/WindowEvent.h>
|
#include <Core/HAL/Event/WindowEvent.h>
|
||||||
|
|
||||||
namespace Juliet
|
bool SendWindowEvent(Window* window, EventType type)
|
||||||
{
|
{
|
||||||
bool SendWindowEvent(Window* window, EventType type)
|
Assert(window);
|
||||||
{
|
|
||||||
Assert(window);
|
|
||||||
|
|
||||||
SystemEvent evt;
|
SystemEvent evt;
|
||||||
evt.Timestamp = 0;
|
evt.Timestamp = 0;
|
||||||
evt.Type = type;
|
evt.Type = type;
|
||||||
evt.Data.Window.AssociatedWindowID = window->ID;
|
evt.Data.Window.AssociatedWindowID = window->ID;
|
||||||
|
|
||||||
bool evtPosted = AddEvent(evt);
|
bool evtPosted = AddEvent(evt);
|
||||||
|
|
||||||
return evtPosted;
|
return evtPosted;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
struct Window;
|
||||||
{
|
enum class EventType : uint32;
|
||||||
struct Window;
|
|
||||||
enum class EventType : uint32;
|
|
||||||
|
|
||||||
extern bool SendWindowEvent(Window* window, EventType type);
|
extern bool SendWindowEvent(Window* window, EventType type);
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||||
@@ -9,93 +9,90 @@
|
|||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace
|
||||||
{
|
{
|
||||||
namespace
|
String CachedBasePath = {};
|
||||||
{
|
String CachedAssetBasePath = {};
|
||||||
String CachedBasePath = {};
|
|
||||||
String CachedAssetBasePath = {};
|
|
||||||
|
|
||||||
bool DirectoryExists(const char* path)
|
bool DirectoryExists(const char* path)
|
||||||
|
{
|
||||||
|
Assert(path);
|
||||||
|
DWORD attributes = GetFileAttributesA(path);
|
||||||
|
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
String GetBasePath()
|
||||||
|
{
|
||||||
|
Assert(IsValid(CachedBasePath));
|
||||||
|
return CachedBasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
String GetAssetBasePath()
|
||||||
|
{
|
||||||
|
Assert(IsValid(CachedAssetBasePath));
|
||||||
|
return CachedAssetBasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] String GetAssetPath(NonNullPtr<Arena> arena, String filename)
|
||||||
|
{
|
||||||
|
Assert(IsValid(CachedAssetBasePath));
|
||||||
|
Assert(IsValid(filename));
|
||||||
|
|
||||||
|
size_t totalSize = CachedAssetBasePath.Size + filename.Size + 1;
|
||||||
|
char* buffer = ArenaPushArray<char>(arena, totalSize);
|
||||||
|
Assert(buffer);
|
||||||
|
|
||||||
|
juliet_snprintf(buffer, totalSize, "%s%s", CStr(CachedAssetBasePath), CStr(filename));
|
||||||
|
return { buffer, totalSize - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsAbsolutePath(String path)
|
||||||
|
{
|
||||||
|
if (!IsValid(path))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Platform::IsAbsolutePath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitFilesystem(NonNullPtr<Arena> arena)
|
||||||
|
{
|
||||||
|
CachedBasePath = Platform::GetBasePath(arena);
|
||||||
|
|
||||||
|
String basePath = GetBasePath();
|
||||||
|
Assert(IsValid(basePath));
|
||||||
|
|
||||||
|
// Probe candidate paths for compiled shader directory
|
||||||
|
// 1. Shipping layout: Assets/Shaders/ next to the exe
|
||||||
|
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
|
||||||
|
constexpr const char* kCandidates[] = { "Assets/Shaders/", "../../Assets/compiled/" };
|
||||||
|
|
||||||
|
for (const char* candidate : kCandidates)
|
||||||
|
{
|
||||||
|
char probePath[512];
|
||||||
|
juliet_snprintf(probePath, sizeof(probePath), "%s%s", CStr(basePath), candidate);
|
||||||
|
|
||||||
|
if (DirectoryExists(probePath))
|
||||||
{
|
{
|
||||||
Assert(path);
|
size_t len = strlen(probePath);
|
||||||
DWORD attributes = GetFileAttributesA(path);
|
if (char* buffer = ArenaPushArray<char>(arena, len + 1 JULIET_DEBUG_PARAM("CachedAssetBasePath")))
|
||||||
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
String GetBasePath()
|
|
||||||
{
|
|
||||||
Assert(IsValid(CachedBasePath));
|
|
||||||
return CachedBasePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
String GetAssetBasePath()
|
|
||||||
{
|
|
||||||
Assert(IsValid(CachedAssetBasePath));
|
|
||||||
return CachedAssetBasePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] String GetAssetPath(NonNullPtr<Arena> arena, String filename)
|
|
||||||
{
|
|
||||||
Assert(IsValid(CachedAssetBasePath));
|
|
||||||
Assert(IsValid(filename));
|
|
||||||
|
|
||||||
size_t totalSize = CachedAssetBasePath.Size + filename.Size + 1;
|
|
||||||
char* buffer = ArenaPushArray<char>(arena, totalSize);
|
|
||||||
Assert(buffer);
|
|
||||||
|
|
||||||
juliet_snprintf(buffer, totalSize, "%s%s", CStr(CachedAssetBasePath), CStr(filename));
|
|
||||||
return { buffer, totalSize - 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsAbsolutePath(String path)
|
|
||||||
{
|
|
||||||
if (!IsValid(path))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Platform::IsAbsolutePath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitFilesystem(NonNullPtr<Arena> arena)
|
|
||||||
{
|
|
||||||
CachedBasePath = Platform::GetBasePath(arena);
|
|
||||||
|
|
||||||
String basePath = GetBasePath();
|
|
||||||
Assert(IsValid(basePath));
|
|
||||||
|
|
||||||
// Probe candidate paths for compiled shader directory
|
|
||||||
// 1. Shipping layout: Assets/Shaders/ next to the exe
|
|
||||||
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
|
|
||||||
constexpr const char* kCandidates[] = { "Assets/Shaders/", "../../Assets/compiled/" };
|
|
||||||
|
|
||||||
for (const char* candidate : kCandidates)
|
|
||||||
{
|
|
||||||
char probePath[512];
|
|
||||||
juliet_snprintf(probePath, sizeof(probePath), "%s%s", CStr(basePath), candidate);
|
|
||||||
|
|
||||||
if (DirectoryExists(probePath))
|
|
||||||
{
|
{
|
||||||
size_t len = strlen(probePath);
|
juliet_snprintf(buffer, len + 1, "%s", probePath);
|
||||||
if (char* buffer = ArenaPushArray<char>(arena, len + 1 JULIET_DEBUG_PARAM("CachedAssetBasePath")))
|
CachedAssetBasePath = { buffer, len };
|
||||||
{
|
Log(LogLevel::Message, LogCategory::Core, "Asset base path: %s", buffer);
|
||||||
juliet_snprintf(buffer, len + 1, "%s", probePath);
|
|
||||||
CachedAssetBasePath = { buffer, len };
|
|
||||||
Log(LogLevel::Message, LogCategory::Core, "Asset base path: %s", buffer);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LogLevel::Error, LogCategory::Core, "Filesystem: Could not find Assets/compiled/ directory!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownFilesystem()
|
Log(LogLevel::Error, LogCategory::Core, "Filesystem: Could not find Assets/compiled/ directory!");
|
||||||
{
|
}
|
||||||
CachedBasePath.Size = 0;
|
|
||||||
CachedBasePath.Str = nullptr;
|
void ShutdownFilesystem()
|
||||||
CachedAssetBasePath.Size = 0;
|
{
|
||||||
CachedAssetBasePath.Str = nullptr;
|
CachedBasePath.Size = 0;
|
||||||
}
|
CachedBasePath.Str = nullptr;
|
||||||
} // namespace Juliet
|
CachedAssetBasePath.Size = 0;
|
||||||
|
CachedAssetBasePath.Str = nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet::Platform
|
namespace Platform
|
||||||
{
|
{
|
||||||
extern String GetBasePath(NonNullPtr<Arena> arena);
|
extern String GetBasePath(NonNullPtr<Arena> arena);
|
||||||
extern bool IsAbsolutePath(String path);
|
extern bool IsAbsolutePath(String path);
|
||||||
} // namespace Juliet::Platform
|
} // namespace Platform
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Juliet
|
extern void InitFilesystem(NonNullPtr<Arena> arena);
|
||||||
{
|
extern void ShutdownFilesystem();
|
||||||
extern void InitFilesystem(NonNullPtr<Arena> arena);
|
|
||||||
extern void ShutdownFilesystem();
|
|
||||||
} // namespace Juliet
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#include <Core/Common/String.h>
|
#include <Core/Common/String.h>
|
||||||
#include <Core/HAL/Filesystem/Filesystem_Platform.h>
|
#include <Core/HAL/Filesystem/Filesystem_Platform.h>
|
||||||
#include <Core/HAL/Win32.h>
|
#include <Core/HAL/Win32.h>
|
||||||
#include <Core/Logging/LogManager.h>
|
#include <Core/Logging/LogManager.h>
|
||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
|
|
||||||
namespace Juliet::Platform
|
namespace Platform
|
||||||
{
|
{
|
||||||
String GetBasePath(NonNullPtr<Arena> arena)
|
String GetBasePath(NonNullPtr<Arena> arena)
|
||||||
{
|
{
|
||||||
@@ -91,4 +91,4 @@ namespace Juliet::Platform
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace Juliet::Platform
|
} // namespace Platform
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user