Compare commits

..
11 Commits
375 changed files with 18995 additions and 107008 deletions

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
CompileFlags:
Add:
- --driver-mode=cl
- -Wno-unknown-pragmas
- -Wno-unused-command-line-argument
Remove:
- /Yu*
- /Yc*
- /Fp*
- /MP
- /Zi
- /Gw
- /Gy
- /Bt+
- /EHa-
Diagnostics:
UnusedIncludes: None
InlayHints:
Enabled: Yes
ParameterNames: Yes
DeducedTypes: Yes
+4
View File
@@ -56,3 +56,7 @@ launch_*.txt
*.log *.log
misc/agent_error.log misc/agent_error.log
misc/agent_output_ship.log misc/agent_output_ship.log
# Clangd
compile_commands.json
.cache/
+2
View File
@@ -0,0 +1,2 @@
; Paul
1
+3
View File
@@ -3,4 +3,7 @@
<LLVMInstallDir>C:\Program Files\LLVM</LLVMInstallDir> <LLVMInstallDir>C:\Program Files\LLVM</LLVMInstallDir>
<LLVMToolsVersion>19.1.0</LLVMToolsVersion> <LLVMToolsVersion>19.1.0</LLVMToolsVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Natvis Include="$(MSBuildThisFileDirectory)Natvis\*.natvis" />
</ItemGroup>
</Project> </Project>
+4 -2
View File
@@ -1,4 +1,6 @@
#pragma once #pragma once
constexpr index_t kPlayCamera = 0; #include <Juliet.h>
constexpr index_t kDebugCamera = 1;
#define kPlayCamera ((index_t)0)
#define kDebugCamera ((index_t)1)
+163
View File
@@ -0,0 +1,163 @@
#include <Controller/DebugCameraController.h>
#include <Controller/ControllerUtils.h>
#include <Core/Common/CoreUtils.h>
#include <Core/HAL/Keyboard/Keyboard.h>
#include <Core/HAL/Mouse/Mouse.h>
#include <Core/Memory/MemoryArena.h>
#include <Graphics/Camera.h>
#include <dcimgui.h>
#include <math.h>
global bool8 gIsDebugCameraActive = false;
global index_t gPreviousCameraIndex = 0;
global float gPitch = 0.0f;
global float gYaw = 0.0f;
global bool8 gFirstUpdate = true;
global bool8 gIsFpsModeActive = false;
global bool8 gWasRightMouseButtonDown = false;
void ActivateDebugController(void)
{
Assert(gIsDebugCameraActive == false);
Camera* currentCam = GetCurrentCamera();
gPreviousCameraIndex = currentCam->Index;
SetCurrentCamera(kDebugCamera);
gIsDebugCameraActive = true;
gFirstUpdate = true;
gIsFpsModeActive = false;
gWasRightMouseButtonDown = false;
}
void DeactivateDebugController(void)
{
Assert(gIsDebugCameraActive);
gIsDebugCameraActive = false;
SetCurrentCamera(gPreviousCameraIndex);
}
bool8 IsDebugControllerActive(void)
{
return gIsDebugCameraActive;
}
void UpdateDebugController(float dt)
{
Camera* currentCam = GetCurrentCamera();
if (gFirstUpdate)
{
Vector3 origin = { 0.0f, 0.0f, 0.0f };
Vector3 dir = Vector3Sub(origin, currentCam->Position);
dir = Normalize(dir);
gPitch = asinf(dir.z);
gYaw = atan2f(dir.y, dir.x);
gFirstUpdate = false;
Vector3 forward = { cosf(gPitch) * cosf(gYaw), cosf(gPitch) * sinf(gYaw), sinf(gPitch) };
Vector3 worldUp = { 0.0f, 0.0f, 1.0f };
Vector3 right = Normalize(Cross(worldUp, forward));
currentCam->Target = Vector3Add(currentCam->Position, forward);
currentCam->Up = Cross(forward, right);
}
bool8 isRightMouseButtonDown = IsMouseButtonDown(MouseButton_Right);
if (isRightMouseButtonDown && !gWasRightMouseButtonDown)
{
gIsFpsModeActive = !gIsFpsModeActive;
}
gWasRightMouseButtonDown = isRightMouseButtonDown;
if (gIsFpsModeActive)
{
MousePosition mouseDelta = GetMouseDelta();
float sensitivity = 0.005f;
gYaw += (float)mouseDelta.X * sensitivity;
gPitch -= (float)mouseDelta.Y * sensitivity;
gPitch = Min(gPitch, 1.5f);
gPitch = Max(gPitch, -1.5f);
if (IsKeyDown(ScanCode_Q))
{
gYaw -= 2.0f * dt;
}
if (IsKeyDown(ScanCode_E))
{
gYaw += 2.0f * dt;
}
Vector3 forward = { cosf(gPitch) * cosf(gYaw), cosf(gPitch) * sinf(gYaw), sinf(gPitch) };
Vector3 worldUp = { 0.0f, 0.0f, 1.0f };
Vector3 right = Normalize(Cross(worldUp, forward));
Vector3 defaultUp = Cross(forward, right);
const float kMovementPerFrame = 10.f; // 10m/s
float speedPerFrame = kMovementPerFrame;
if (IsKeyDown(ScanCode_LeftShift))
{
speedPerFrame *= 10.f; // 100m/s
}
if (IsKeyDown(ScanCode_W))
{
currentCam->Position = Vector3Add(currentCam->Position, Vector3Scale(forward, speedPerFrame * dt));
}
if (IsKeyDown(ScanCode_S))
{
currentCam->Position = Vector3Sub(currentCam->Position, Vector3Scale(forward, speedPerFrame * dt));
}
if (IsKeyDown(ScanCode_D))
{
currentCam->Position = Vector3Add(currentCam->Position, Vector3Scale(right, speedPerFrame * dt));
}
if (IsKeyDown(ScanCode_A))
{
currentCam->Position = Vector3Sub(currentCam->Position, Vector3Scale(right, speedPerFrame * dt));
}
if (IsKeyDown(ScanCode_Space))
{
currentCam->Position = Vector3Add(currentCam->Position, Vector3Scale(defaultUp, speedPerFrame * dt));
}
if (IsKeyDown(ScanCode_LeftControl))
{
currentCam->Position = Vector3Sub(currentCam->Position, Vector3Scale(defaultUp, speedPerFrame * dt));
}
currentCam->Target = Vector3Add(currentCam->Position, forward);
currentCam->Up = defaultUp;
}
}
#if JULIET_DEBUG
void RenderImGuiDebugController(float dt)
{
Camera* currentCam = GetCurrentCamera();
ImGui_Text("Delta time: %f", (double)dt);
ImGui_Text("Camera:");
ImGui_Indent();
ImGui_BulletText("Index: %zu", (size_t)currentCam->Index);
ImGui_BulletText("Position: (%.3f, %.3f, %.3f)", (double)currentCam->Position.x, (double)currentCam->Position.y,
(double)currentCam->Position.z);
ImGui_BulletText("Target: (%.3f, %.3f, %.3f)", (double)currentCam->Target.x, (double)currentCam->Target.y,
(double)currentCam->Target.z);
ImGui_BulletText("Up: (%.3f, %.3f, %.3f)", (double)currentCam->Up.x, (double)currentCam->Up.y,
(double)currentCam->Up.z);
ImGui_BulletText("FOV: %.3f rad", (double)currentCam->FOV);
ImGui_BulletText("AspectRatio: %.3f", (double)currentCam->AspectRatio);
ImGui_BulletText("NearPlane: %.3f", (double)currentCam->NearPlane);
ImGui_BulletText("FarPlane: %.3f", (double)currentCam->FarPlane);
ImGui_BulletText("Pitch: %.3f, Yaw: %.3f", (double)gPitch, (double)gYaw);
ImGui_BulletText("FPS Mode: %s", gIsFpsModeActive ? "Active" : "Inactive");
ImGui_Unindent();
}
#endif
-170
View File
@@ -1,170 +0,0 @@
#include <Controller/DebugCameraController.h>
#include <Controller/ControllerUtils.h>
#include <Core/Common/CoreUtils.h>
#include <Core/HAL/Keyboard/Keyboard.h>
#include <Core/HAL/Mouse/Mouse.h>
#include <Graphics/Camera.h>
#include <imgui.h>
namespace
{
bool gIsDebugCameraActive = false;
index_t gPreviousCameraIndex = 0;
float gPitch = 0.0f;
float gYaw = 0.0f;
bool gFirstUpdate = true;
bool gIsFpsModeActive = false;
bool gWasRightMouseButtonDown = false;
} // namespace
void ActivateDebugController()
{
Assert(gIsDebugCameraActive == false);
Camera* currentCam = GetCurrentCamera();
gPreviousCameraIndex = currentCam->Index;
SetCurrentCamera(kDebugCamera);
gIsDebugCameraActive = true;
gFirstUpdate = true;
gIsFpsModeActive = false;
gWasRightMouseButtonDown = false;
}
void DeactivateDebugController()
{
Assert(gIsDebugCameraActive);
gIsDebugCameraActive = false;
SetCurrentCamera(gPreviousCameraIndex);
}
bool IsDebugControllerActive()
{
return gIsDebugCameraActive;
}
void UpdateDebugController(float dt)
{
Camera* currentCam = GetCurrentCamera();
if (gFirstUpdate)
{
Vector3 dir = Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position;
dir = Normalize(dir);
gPitch = asinf(dir.z);
gYaw = atan2f(dir.y, dir.x);
gFirstUpdate = false;
Vector3 forward;
forward.x = cosf(gPitch) * cosf(gYaw);
forward.y = cosf(gPitch) * sinf(gYaw);
forward.z = sinf(gPitch);
Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
currentCam->Target = currentCam->Position + forward;
currentCam->Up = Cross(forward, right);
}
bool isRightMouseButtonDown = IsMouseButtonDown(MouseButton::Right);
if (isRightMouseButtonDown && !gWasRightMouseButtonDown)
{
gIsFpsModeActive = !gIsFpsModeActive;
}
gWasRightMouseButtonDown = isRightMouseButtonDown;
if (!gIsFpsModeActive)
{
return;
}
MousePosition mouseDelta = GetMouseDelta();
float sensitivity = 0.005f;
gYaw += mouseDelta.X * sensitivity;
gPitch -= mouseDelta.Y * sensitivity;
gPitch = std::min(gPitch, 1.5f);
gPitch = std::max(gPitch, -1.5f);
if (IsKeyDown(ScanCode::Q))
{
gYaw -= 2.0f * dt;
}
if (IsKeyDown(ScanCode::E))
{
gYaw += 2.0f * dt;
}
Vector3 forward;
forward.x = cosf(gPitch) * cosf(gYaw);
forward.y = cosf(gPitch) * sinf(gYaw);
forward.z = sinf(gPitch);
Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
Vector3 defaultUp = Cross(forward, right);
static const float kMovementPerFrame = 10.f; // 10m/s
float speedPerFrame = kMovementPerFrame;
if (IsKeyDown(ScanCode::LeftShift))
{
speedPerFrame *= 10.f; // 100m/s
}
if (IsKeyDown(ScanCode::W))
{
currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt);
}
if (IsKeyDown(ScanCode::S))
{
currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt);
}
if (IsKeyDown(ScanCode::D))
{
currentCam->Position = currentCam->Position + right * (speedPerFrame * dt);
}
if (IsKeyDown(ScanCode::A))
{
currentCam->Position = currentCam->Position - right * (speedPerFrame * dt);
}
if (IsKeyDown(ScanCode::Space))
{
currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt);
}
if (IsKeyDown(ScanCode::LeftControl))
{
currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt);
}
currentCam->Target = currentCam->Position + forward;
currentCam->Up = defaultUp;
}
#if JULIET_DEBUG
void RenderImGuiDebugController(float dt)
{
Camera* currentCam = GetCurrentCamera();
ImGui::Text("Delta time: %f", dt);
ImGui::Text("Camera:");
ImGui::Indent();
ImGui::BulletText("Index: %zu", (size_t)currentCam->Index);
ImGui::BulletText("Position: (%.3f, %.3f, %.3f)", currentCam->Position.x, currentCam->Position.y,
currentCam->Position.z);
ImGui::BulletText("Target: (%.3f, %.3f, %.3f)", currentCam->Target.x, currentCam->Target.y, currentCam->Target.z);
ImGui::BulletText("Up: (%.3f, %.3f, %.3f)", currentCam->Up.x, currentCam->Up.y, currentCam->Up.z);
ImGui::BulletText("FOV: %.3f rad", currentCam->FOV);
ImGui::BulletText("AspectRatio: %.3f", currentCam->AspectRatio);
ImGui::BulletText("NearPlane: %.3f", currentCam->NearPlane);
ImGui::BulletText("FarPlane: %.3f", currentCam->FarPlane);
ImGui::BulletText("Pitch: %.3f, Yaw: %.3f", gPitch, gYaw);
ImGui::BulletText("FPS Mode: %s", gIsFpsModeActive ? "Active" : "Inactive");
ImGui::Unindent();
}
#endif
+6 -4
View File
@@ -1,11 +1,13 @@
#pragma once #pragma once
#include <Juliet.h>
// TODO : Should support Debug/Profile/Release properly. // TODO : Should support Debug/Profile/Release properly.
// I think debug profile should have this controller but not release // I think debug profile should have this controller but not release
void ActivateDebugController(); void ActivateDebugController(void);
void DeactivateDebugController(); void DeactivateDebugController(void);
bool IsDebugControllerActive(); bool8 IsDebugControllerActive(void);
void UpdateDebugController(float dt); void UpdateDebugController(float dt);
#if JULIET_DEBUG #if JULIET_DEBUG
void RenderImGuiDebugController(float dt); void RenderImGuiDebugController(float dt);
+140
View File
@@ -0,0 +1,140 @@
#include <Data/World.h>
#include <Core/Common/CoreUtils.h>
#include <Core/Common/serialization.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Thread/ThreadContext.h>
#include <Entity/EntityManager.h>
#include <Graphics/MeshRenderer.h>
#ifdef JULIET_ENABLE_IMGUI
#include <dcimgui.h>
#endif
void InitWorld(World* world, Arena* arena)
{
Assert(world != NULL);
Assert(arena != NULL);
world->WorldArena = arena;
}
void ShutdownWorld(World* world)
{
Assert(world != NULL);
world->WorldArena = NULL;
}
void AddToWorld(World* world, Entity* entity)
{
(void)world;
(void)entity;
}
void RemoveWorldEntity(World* world, size_t index)
{
(void)world;
(void)index;
}
void SerializeWorld(Archive* ar, World* world, String filename)
{
(void)world;
Assert(ar != NULL);
Assert(IsValidString(filename));
EntityManager* entityManager = GetEntityManager();
if (ar->loading)
{
// Load
ByteBuffer fileBuffer = LoadFile(ar->arena, filename);
// TEST SERIALIZATION
ParsedArchive archive = tokenize_archive(ar->arena, fileBuffer);
#if JULIET_DEBUG
audit_unconsumed_properties(&archive, ConstString("World"));
#else
(void)archive;
#endif
}
else
{
// Save
IOStream* stream = IOFromFile(ar->arena, filename, WrapString("wb"));
index_t beginPos = ArenaPos(ar->arena);
// Headers
WorldFileHeader* header = ArenaPushStruct(ar->arena, WorldFileHeader);
header->Magic = kWorldMagic;
// TODO : Move to a one file per entity model
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
typed_entity_array* type = &entityManager->by_type[i];
serialize_elem(ar, type->count);
if (type->count > 0 && type->array != NULL)
{
EntityTemplate* element = type->array;
uint8* rawElement = (uint8*)element;
size_t stride = element->base->derived_kind->size_of;
for (index_t idx = 0; idx < type->count; ++idx)
{
Entity* entity = ((EntityTemplate*)(rawElement + (idx * stride)))->base;
serialize_entity(ar, entity);
}
}
}
// Write
index_t endPos = ArenaPos(ar->arena);
ByteBuffer writeBuffer = { .Data = (Byte*)header, .Size = endPos - beginPos };
size_t written = IOWrite(stream, writeBuffer);
Assert(writeBuffer.Size == written);
IOClose(stream);
}
}
bool8 LoadWorld(World* world, String filename)
{
(void)world;
Assert(IsValidString(filename));
return true;
}
#ifdef JULIET_EDITOR
void RenderWorldEditorUI(World* world)
{
Assert(world != NULL);
if (ImGui_Begin("World Editor", NULL, ImGuiWindowFlags_None))
{
TempArena temp = scratch_begin(NULL, 0);
static char worldFilePath[256] = "/world.bin";
ImGui_InputText("World File", worldFilePath, sizeof(worldFilePath));
Path path = GetAssetPath(temp.Arena, AssetType_JAsset, WrapString(worldFilePath));
if (ImGui_Button("Save World"))
{
Archive data = { .arena = temp.Arena, .loading = false };
SerializeWorld(&data, world, path.FullPath);
}
ImGui_SameLine(0.0f, -1.0f);
if (ImGui_Button("Load World"))
{
Archive data = { .arena = temp.Arena, .loading = true };
SerializeWorld(&data, world, path.FullPath);
}
scratch_end(temp);
}
ImGui_End();
}
#endif
-322
View File
@@ -1,322 +0,0 @@
#include <Data/World.h>
#include <Core/Common/CoreUtils.h>
#include <Core/Common/serialization.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Thread/ThreadContext.h>
#include <Entity/EntityManager.h>
#include <Graphics/MeshRenderer.h>
#ifdef JULIET_ENABLE_IMGUI
#include <imgui.h>
#endif
void InitWorld(NonNullPtr<World> world, NonNullPtr<Arena> arena)
{
world->WorldArena = arena.Get();
}
void ShutdownWorld(NonNullPtr<World> world)
{
world->WorldArena = nullptr;
}
void AddToWorld(NonNullPtr<World> /*world*/, NonNullPtr<Entity> /*entity*/)
{
// RegisterEntity(*world->EntityManager, entity.Get());
}
void RemoveWorldEntity(World& /*world*/, size_t /*index*/) {}
void Serialize(Archive& ar, World& /*world*/, String filename)
{
Assert(IsValid(filename));
auto& entityManager = GetEntityManager();
if (ar.loading)
{
// Load
ByteBuffer fileBuffer = LoadFile(ar.arena, filename);
// TEST SERIALIZATION
ParsedArchive archive = tokenize_archive(ar.arena, fileBuffer);
// ArchivePropertyNode* property = find_property(&archive, "Position"_crc32);
audit_unconsumed_properties(&archive, ConstString("World"));
// if (fileBuffer.Size >= sizeof(WorldFileHeader))
// {
// ar.base_ptr = fileBuffer.Data;
//
// WorldFileHeader header;
// serialize_elem(ar, header);
// Assert(header.Magic == kWorldMagic);
//
// for (typed_entity_array& type : entityManager.by_type)
// {
// serialize_elem(ar, type.count);
//
// if (type.count > 0)
// {
//
// // Unserialize the base entity to get informations
// Entity entity;
// // serialize(ar, &entity);
// }
// }
// }
}
else
{
// Save
IOStream* stream = IOFromFile(ar.arena, filename, WrapString("wb"));
index_t beginPos = ArenaPos(ar.arena);
// Headers
auto* header = ArenaPushStruct<WorldFileHeader>(ar.arena);
header->Magic = kWorldMagic;
ar.base_ptr = header;
// TODO : Move to a one file per entity model
for (typed_entity_array& type : entityManager.by_type)
{
serialize_elem(ar, type.count);
auto* element = type.array;
uint8* rawElement = reinterpret_cast<uint8*>(element);
size_t stride = element->base->derived_kind->size_of;
for (index_t idx = 0; idx < type.count; ++idx)
{
// Todo : utils
// Get base entity from type
Entity* entity = reinterpret_cast<EntityTemplate*>(rawElement + (idx * stride))->base;
serialize(ar, entity);
}
}
// Write
index_t endPos = ArenaPos(ar.arena);
ByteBuffer writeBuffer = { .Data = reinterpret_cast<Byte*>(header), .Size = endPos - beginPos };
size_t written = IOWrite(stream, writeBuffer);
Assert(writeBuffer.Size == written);
IOClose(stream);
}
//
// uint32 entityCount = static_cast<uint32>(world.Entities.Size());
// size_t totalBytes = sizeof(WorldFileHeader) + static_cast<size_t>(entityCount) * sizeof(WorldEntityDiskRecord);
//
// ArenaParams tempParams = { .ReserveSize = Megabytes(1), .Name = "WorldSaveArena" };
// Arena* tempArena = ArenaAllocate(tempParams);
// if (!tempArena)
// {
// LogError(LogCategory::Game, "SaveWorld: Failed to allocate memory for saving world.");
// return false;
// }
//
// auto deferRelease = Defer([&]() { ArenaRelease(tempArena); });
//
// uint8* bufferData = ArenaPushArray<uint8, false>(tempArena, totalBytes);
// if (!bufferData)
// {
// LogError(LogCategory::Game, "SaveWorld: Failed to allocate buffer in arena.");
// return false;
// }
//
// auto* header = reinterpret_cast<WorldFileHeader*>(bufferData);
// header->Magic = kWorldMagic;
// header->Version = kWorldVersion;
// header->EntityCount = entityCount;
// header->Reserved = 0;
//
// auto* records = reinterpret_cast<WorldEntityDiskRecord*>(bufferData + sizeof(WorldFileHeader));
// for (size_t i = 0; i < entityCount; ++i)
// {
// const Entity& ent = world.Entities[i];
// records[i].X = ent.X;
// records[i].Y = ent.Y;
// records[i].Z = ent.Z;
// }
//
// IOStream* stream = IOFromFile(tempArena, filename, WrapString("wb"));
// if (!stream)
// {
// LogError(LogCategory::Game, "SaveWorld: Failed to open file for writing: %s", CStr(filename));
// return false;
// }
//
// ByteBuffer writeBuffer = { .Data = reinterpret_cast<Byte*>(bufferData), .Size = totalBytes };
//
// size_t written = IOWrite(stream, writeBuffer);
// IOClose(stream);
//
// if (written != totalBytes)
// {
// LogError(LogCategory::Game, "SaveWorld: Failed to write complete world data to %s (wrote %zu / %zu bytes)",
// CStr(filename), written, totalBytes);
// return false;
// }
//
// LogMessage(LogCategory::Game, "World successfully saved to %s (%u entities)", CStr(filename), entityCount);
// return true;
}
[[nodiscard]] bool LoadWorld(World& /*world*/, String filename)
{
Assert(IsValid(filename));
// Assert(world.WorldArena != nullptr);
//
// TempArena loadArena = scratch_begin(nullptr, 0);
//
// ByteBuffer fileBuffer = LoadFile(loadArena.Arena, filename);
// if (fileBuffer.Data && fileBuffer.Size < sizeof(WorldFileHeader))
// {
// const WorldFileHeader* header = reinterpret_cast<const WorldFileHeader*>(fileBuffer.Data);
// const bool invalidMagicNum = header->Magic != kWorldMagic;
// const bool invalidVersion = header->Version != kWorldVersion;
// if (invalidMagicNum)
// {
// LogError(LogCategory::Game, "LoadWorld: Invalid magic in world file: %s (expected 0x%08X, got 0x%08X)",
// CStr(filename), kWorldMagic, header->Magic);
// }
//
// if (invalidVersion)
// {
// LogError(LogCategory::Game, "LoadWorld: Unsupported world file version: %u in %s", header->Version, CStr(filename));
// }
//
// size_t expectedSize = sizeof(WorldFileHeader) + static_cast<size_t>(header->EntityCount) * sizeof(WorldEntityDiskRecord);
// const bool invalidSize = fileBuffer.Size < expectedSize;
// if (invalidSize)
// {
// LogError(LogCategory::Game, "LoadWorld: Corrupted file %s: size %zu < expected %zu for %u entities",
// CStr(filename), fileBuffer.Size, expectedSize, header->EntityCount);
// }
//
// if (!invalidMagicNum && !invalidVersion && !invalidSize)
// {
//
// // world.Entities.Clear();
// //
// // const auto* records = reinterpret_cast<const WorldEntityDiskRecord*>(
// // reinterpret_cast<const uint8*>(fileBuffer.Data) + sizeof(WorldFileHeader));
// //
// // for (uint32 i = 0; i < header->EntityCount; ++i)
// // {
// // Entity ent;
// // (void)AddWorldEntity(world, records[i].X, records[i].Y, records[i].Z);
// // }
//
// LogMessage(LogCategory::Game, "World successfully loaded from %s (%u entities)", CStr(filename), header->EntityCount);
// }
// }
// else
// {
// LogError(LogCategory::Game, "LoadWorld: Failed to read world file or file is too small: %s", CStr(filename));
// }
//
// scratch_end(loadArena);
return true;
}
#ifdef JULIET_EDITOR
void RenderWorldEditorUI(World& world)
{
if (ImGui::Begin("World Editor"))
{
TempArena temp = scratch_begin(nullptr, 0);
static char worldFilePath[256] = "/world.bin";
ImGui::InputText("World File", worldFilePath, sizeof(worldFilePath));
String path = GetAssetPath(temp.Arena, AssetType::JAsset, ConstString(worldFilePath));
if (ImGui::Button("Save World"))
{
Archive data = { .arena = temp.Arena, .loading = false };
Serialize(data, world, path);
}
ImGui::SameLine();
if (ImGui::Button("Load World"))
{
Archive data{ .arena = temp.Arena, .loading = true };
Serialize(data, world, path);
}
scratch_end(temp);
// ImGui::SameLine();
// if (ImGui::Button("Clear All"))
// {
// ClearWorld(world);
// }
//
// ImGui::Separator();
//
// if (ImGui::Button("Add Entity"))
// {
// (void)AddWorldEntity(world, 0.0f, 0.0f, 0.0f);
// }
//
// ImGui::Text("Entity Count: %zu", world.Entities.Size());
// ImGui::Separator();
//
// static int selectedEntity = -1;
// if (selectedEntity >= static_cast<int>(world.Entities.Size()))
// {
// selectedEntity = -1;
// }
//
// ImGui::BeginChild("EntityList", ImVec2(180, 200), true);
// for (size_t i = 0; i < world.Entities.Size(); ++i)
// {
// char label[64];
// snprintf(label, sizeof(label), "Entity #%zu (ID: %llu)", i, world.Entities[i].ID);
// if (ImGui::Selectable(label, selectedEntity == static_cast<int>(i)))
// {
// selectedEntity = static_cast<int>(i);
// }
// }
// ImGui::EndChild();
//
// ImGui::SameLine();
//
// ImGui::BeginChild("EntityInspector", ImVec2(0, 200), true);
// if (selectedEntity >= 0 && selectedEntity < static_cast<int>(world.Entities.Size()))
// {
// Entity& ent = world.Entities[static_cast<size_t>(selectedEntity)];
// ImGui::Text("Selected: Entity #%d", selectedEntity);
// ImGui::Text("ID: %llu", ent.ID);
//
// float pos[3] = { ent.X, ent.Y, ent.Z };
// if (ImGui::DragFloat3("Position", pos, 0.1f))
// {
// ent.X = pos[0];
// ent.Y = pos[1];
// ent.Z = pos[2];
// UpdateWorld(world);
// }
//
// if (ImGui::Button("Delete Entity"))
// {
// RemoveWorldEntity(world, static_cast<size_t>(selectedEntity));
// selectedEntity = -1;
// UpdateWorld(world);
// }
// }
// else
// {
// ImGui::Text("Select an entity to edit its properties.");
// }
// ImGui::EndChild();
}
ImGui::End();
}
#endif
+15 -14
View File
@@ -1,38 +1,39 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
#include <Entity/Entity.h> #include <Entity/Entity.h>
struct Archive; typedef struct Archive Archive;
struct EntityManager; typedef struct EntityManager EntityManager;
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct WorldFileHeader WorldFileHeader;
struct WorldFileHeader struct WorldFileHeader
{ {
uint32 Magic = 0x444C574A; // 'JWLD' in little-endian uint32 Magic; // 0x444C574A ('JWLD' in little-endian)
}; };
#pragma pack(pop) #pragma pack(pop)
constexpr uint32 kWorldMagic = 0x444C574A; // 'JWLD' #define kWorldMagic ((uint32)0x444C574A) // 'JWLD'
constexpr uint32 kWorldVersion = 1; #define kWorldVersion ((uint32)1)
typedef struct World World;
struct World struct World
{ {
Arena* WorldArena = nullptr; Arena* WorldArena;
EntityManager* EntityManager = nullptr; EntityManager* EntityManager;
}; };
void InitWorld(NonNullPtr<World> world, NonNullPtr<Arena> arena); void InitWorld(World* world, Arena* arena);
void ShutdownWorld(NonNullPtr<World> world); void ShutdownWorld(World* world);
void AddToWorld(NonNullPtr<World> world, NonNullPtr<Entity> entity); void AddToWorld(World* world, Entity* entity);
void RemoveWorldEntity(World& world, size_t index); void RemoveWorldEntity(World* world, size_t index);
void Serialize(Archive& data, World& world, String filename); void SerializeWorld(Archive* data, World* world, String filename);
#if JULIET_EDITOR #if JULIET_EDITOR
void RenderWorldEditorUI(World& world); void RenderWorldEditorUI(World* world);
#endif #endif
+63
View File
@@ -0,0 +1,63 @@
#include <Debug/DebugTopBar.h>
#if JULIET_DEBUG
#include <game.h>
#include <dcimgui.h>
#include <stdio.h>
internal String GetGameModeName(GameMode gameMode)
{
String result = WrapString("Unknown ERROR");
if (gameMode == GameMode_Editor)
{
result = WrapString("Editor");
}
else if (gameMode == GameMode_Play)
{
result = WrapString("Play");
}
else if (gameMode == GameMode_Debug)
{
result = WrapString("Debug");
}
return result;
}
void DrawTopBar(void)
{
GameState* gameState = GetGameState();
ImVec2_c viewportPos = ImGui_GetMainViewportPos();
ImVec2_c viewportSize = ImGui_GetMainViewportSize();
ImGui_SetNextWindowPos(viewportPos);
ImVec2_c barSize = { viewportSize.x, 10.0f };
ImGui_SetNextWindowSize(barSize);
ImGuiWindowFlags_c flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoNav;
ImVec4_c bgCol = { 0.0f, 0.0f, 0.0f, 0.6f };
ImVec2_c padding = { 10.0f, 5.0f };
ImGui_PushStyleColor(ImGuiCol_WindowBg, bgCol);
ImGui_PushStyleVarVec2(ImGuiStyleVar_WindowPadding, padding);
if (ImGui_Begin("TopBarOverlay", NULL, flags))
{
ImGui_Text("Game Mode: %s", CStr(GetGameModeName(gameState->Mode)));
float framerate = ImGuiIO_GetFramerate();
char fps_text[32];
snprintf(fps_text, sizeof(fps_text), "FPS: %.1f (%.2f ms)", (double)framerate, (double)(1000.0f / framerate));
float text_width = ImGui_CalcTextSize(fps_text, NULL).x;
ImGui_SameLine(viewportSize.x - text_width - 15.0f, -1.0f); // 15px right padding
// Render FPS text
ImGui_Text("%s", fps_text);
}
ImGui_End();
ImGui_PopStyleVar(1);
ImGui_PopStyleColor(1);
}
#endif
-49
View File
@@ -1,49 +0,0 @@
#include <Debug/DebugTopBar.h>
#include <game.h>
#include <imgui.h>
namespace
{
String GetGameModeName(GameMode gameMode)
{
switch (gameMode)
{
case GameMode::Editor: return WrapString("Editor");
case GameMode::Play: return WrapString("Play");
case GameMode::Debug: return WrapString("Debug");
default: return WrapString("Unknown ERROR");
}
}
} // namespace
void DrawTopBar()
{
auto* gameState = GetGameState();
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, 10.0f));
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.6f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 5.0f));
if (ImGui::Begin("TopBarOverlay", nullptr, flags))
{
ImGui::Text("Game Mode: %s", CStr(GetGameModeName(gameState->Mode)));
char fps_text[32];
snprintf(fps_text, sizeof(fps_text), "FPS: %.1f (%.2f ms)", ImGui::GetIO().Framerate, 1000.0f / ImGui::GetIO().Framerate);
float text_width = ImGui::CalcTextSize(fps_text).x;
ImGui::SameLine(viewport->Size.x - text_width - 15.0f); // 15px right padding
// Render FPS text
ImGui::Text("%s", fps_text);
}
ImGui::End();
ImGui::PopStyleVar();
ImGui::PopStyleColor();
}
+3 -1
View File
@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <Juliet.h>
#if JULIET_DEBUG #if JULIET_DEBUG
void DrawTopBar(); void DrawTopBar(void);
#endif #endif
+115
View File
@@ -0,0 +1,115 @@
#include <Entity/Entity.h>
#include <Core/Common/serialization.h>
#include <Core/Memory/Utils.h>
#include <stdlib.h>
void serialize_entity(Archive* ar, Entity* entity)
{
Assert(ar != NULL);
Assert(entity != NULL);
// Entity fields
serialize_class(ar, ClassKind(Entity), entity);
// Derived fields
if (entity->derived_kind != NULL && entity->derived != NULL)
{
serialize_class(ar, entity->derived_kind, entity->derived);
}
}
internal void init_Entity(void* payload)
{
Assert(payload != NULL);
Entity* entity = (Entity*)payload;
MemZeroStruct(entity);
}
internal void serialize_Entity(Archive* ar, uint16 version, void* payload)
{
(void)version;
Assert(ar != NULL);
Assert(payload != NULL);
Entity* entity = (Entity*)payload;
SERIALIZE_U64(ar, id, &entity->ID);
SERIALIZE_VEC4(ar, position, &entity->position);
}
DEFINE_CLASS_VERSIONED(Entity, 1, NULL)
String format_entity_id(Arena* arena, EntityID entity_id)
{
Assert(arena != NULL);
// Format:
// U = UserID
// LC = Local Entity Counter
// UU_LCLCLCLCLCLCLC
uint8 user_id = get_user_id(entity_id);
uint64 counter = get_local_counter(entity_id);
const size_t kBufferSize = 18;
char* buffer = ArenaPushArray(arena, char, kBufferSize);
Assert(buffer != NULL);
juliet_snprintf(buffer, kBufferSize, "%02X_%014llX", (unsigned int)user_id, (unsigned long long)counter);
String result = { .Str = buffer, .Size = kBufferSize - 1 };
return result;
}
bool8 parse_entity_id(String str, EntityID* out_id)
{
Assert(out_id != NULL);
bool8 result = false;
*out_id = kInvalid_entity_id;
if (!(str.Size != 17 || str.Str == NULL || str.Str[2] != '_'))
{
char user_hex[3] = { str.Str[0], str.Str[1], '\0' };
char* end = user_hex;
uint8 user_id = (uint8)strtoul(user_hex, &end, 16);
if (end != user_hex && user_id != kInvalid_user_id)
{
char* counter_hex = str.Str + 3;
end = counter_hex;
uint64 counter = strtoull(counter_hex, &end, 16);
if (end != counter_hex && counter < kEntityID_user_id_mask)
{
*out_id = make_entity_id(user_id, counter);
result = true;
}
}
}
return result;
}
const Class* resolve_entity_class(uint8 kind, uint32 crc)
{
Assert(kind <= ENTITY(Count));
const Class* class_ptr = kEntity_type_class_ptr[kind];
Assert(class_ptr != NULL);
Assert(class_get_crc(class_ptr) == crc);
return class_ptr;
}
const Class* find_class_by_name(String name)
{
Assert(IsValidString(name));
const Class* result = NULL;
const uint32 name_crc = crc32_bytes(name.Str, name.Size);
for (uint8 kind = 0; kind < ENTITY(Count); ++kind)
{
const Class* class_ptr = resolve_entity_class(kind, name_crc);
if (class_ptr != NULL)
{
result = class_ptr;
break;
}
}
return result;
}
-50
View File
@@ -1,50 +0,0 @@
#include <Entity/Entity.h>
#include <Core/Common/serialization.h>
void serialize(Archive& ar, NonNullPtr<Entity> entity)
{
// Entity fields
serialize(ar, Entity::kind, entity.Get());
// Derived fields
if (entity->derived_kind != nullptr && entity->derived != nullptr)
{
serialize(ar, entity->derived_kind, entity->derived);
}
}
DEFINE_CLASS_VERSIONED(Entity, 1, nullptr)
internal void serialize(Archive& ar, uint16 /*version*/, Entity& entity)
{
SERIALIZE(ar, id, entity.ID);
SERIALIZE(ar, position, entity.position);
}
const Class* resolve_entity_class(uint8 kind, uint32 crc)
{
Assert(kind <= ENTITY(Count));
NonNullPtr<const Class> class_ptr = kEntity_type_class_ptr[kind];
Assert(class_ptr->CRC == crc);
return class_ptr.Get();
}
const Class* find_class_by_name(String name)
{
Assert(IsValid(name));
const Class* result = nullptr;
const uint32 name_crc = crc32(name.Str, name.Size);
for (uint8 kind = 0; kind < ENTITY(Count); ++kind)
{
const Class* class_ptr = resolve_entity_class(kind, name_crc);
if (class_ptr != nullptr)
{
result = class_ptr;
break;
}
}
return result;
}
+67 -38
View File
@@ -6,66 +6,95 @@
#include <Entity/entity_common.h> #include <Entity/entity_common.h>
#include <Entity/EntityManager.h> #include <Entity/EntityManager.h>
struct Entity final typedef struct Entity Entity;
struct Entity
{ {
DECLARE_CLASS() EntityID ID;
const Class* derived_kind;
EntityID ID = 0; DerivedType derived;
const Class* derived_kind = nullptr; Vector4 position;
DerivedType derived = nullptr; bool8 is_dirty;
Vector4 position = {};
bool is_dirty = false;
}; };
DECLARE_CLASS(Entity)
// Can reinterpret cast to this to have the offset of Base and Kind for any entity // Can cast to this to have the offset of base for any entity
typedef struct EntityTemplate EntityTemplate;
struct EntityTemplate struct EntityTemplate
{ {
DECLARE_ENTITY(); DECLARE_ENTITY()
}; };
// static inline EntityID make_entity_id(uint8 user_id, uint64 local_counter)
template <typename EntityType>
concept EntityConcept = requires(EntityType entity) {
{ EntityType::kind } -> std::convertible_to<const Class*>;
requires std::same_as<decltype(entity.base), Entity*>;
};
template <typename EntityType>
requires EntityConcept<EntityType>
[[nodiscard]] bool IsA(const Entity* entity)
{ {
Assert(entity != nullptr); Assert(user_id != kInvalid_user_id);
return entity->derived_kind == EntityType::kind; Assert((local_counter & kEntityID_user_id_mask) == kInvalid_entity_id);
EntityID result = ((EntityID)user_id << kEntityID_user_id_shift) | (local_counter & kEntityID_user_id_mask);
return result;
} }
template <typename EntityType> static inline uint8 get_user_id(EntityID entity_id)
requires EntityConcept<EntityType>
[[nodiscard]] EntityType* MakeEntity(EntityManager& manager, float x, float y, float z)
{ {
Entity* base_ptr = allocate_entity(manager, EntityType::kind); return (uint8)((entity_id & kEntityID_user_id_mask) >> kEntityID_user_id_shift);
Assert(base_ptr); }
base_ptr->ID = EntityManager::ID++; static inline uint64 get_local_counter(EntityID entity_id)
{
return (uint64)entity_id & ~kEntityID_user_id_mask;
}
static inline bool8 is_entity_id_valid(EntityID entity_id)
{
bool8 result = (entity_id != kInvalid_entity_id);
return result;
}
static inline bool8 IsEntityA(const Entity* entity, const Class* kind)
{
Assert(entity != NULL);
return entity->derived_kind == kind;
}
#define IsEntityOfType(entity_ptr, EntityType) IsEntityA((entity_ptr), ClassKind(EntityType))
static inline void* make_entity_by_class(EntityManager* manager, const Class* kind, float x, float y, float z)
{
Assert(manager != NULL);
Assert(kind != NULL);
Entity* base_ptr = allocate_entity(manager, kind);
Assert(base_ptr != NULL);
base_ptr->ID = g_entity_manager_id++;
base_ptr->position.x = x; base_ptr->position.x = x;
base_ptr->position.y = y; base_ptr->position.y = y;
base_ptr->position.z = z; base_ptr->position.z = z;
base_ptr->position.w = 1.0f; base_ptr->position.w = 1.0f;
return (EntityType*)base_ptr->derived; return base_ptr->derived;
} }
template <typename EntityType> #define MakeEntity(EntityType, manager_ptr, x, y, z) \
requires EntityConcept<EntityType> ((EntityType*)make_entity_by_class((manager_ptr), ClassKind(EntityType), (x), (y), (z)))
[[nodiscard]] EntityType* DownCast(Entity* entity)
static inline void* down_cast_entity(Entity* entity, const Class* kind)
{ {
Assert(entity != nullptr); Assert(entity != NULL);
Assert(IsA<EntityType>(entity)); Assert(IsEntityA(entity, kind));
return static_cast<EntityType*>(entity->derived); return entity->derived;
} }
void serialize(Archive& ar, NonNullPtr<Entity> entity); #define DownCastEntity(EntityType, entity_ptr) ((EntityType*)down_cast_entity((entity_ptr), ClassKind(EntityType)))
[[nodiscard]] const Class* find_class_by_name(String name); void serialize_entity(Archive* ar, Entity* entity);
[[nodiscard]] const Class* resolve_entity_class(uint8 kind, uint32 crc); JULIET_API uint8 get_local_user_id(void);
JULIET_API String format_entity_id(Arena* arena, EntityID id);
JULIET_API bool8 parse_entity_id(String str, EntityID* outId);
const Class* find_class_by_name(String name);
const Class* resolve_entity_class(uint8 kind, uint32 crc);
+190
View File
@@ -0,0 +1,190 @@
#include <Entity/EntityManager.h>
#include <Core/Common/serialization.h>
#include <Core/Memory/Utils.h>
#include <Data/World.h>
#include <Engine/user.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
#include <Graphics/MeshRenderer.h>
EntityID g_entity_manager_id = 0;
void InitEntityManager(World* world)
{
Assert(world != NULL);
EntityManager* newManager = ArenaPushStruct(world->WorldArena, EntityManager);
newManager->next_local_counter = 1ULL;
world->EntityManager = newManager;
VectorArenaCreate(&newManager->Entities, Entity, world->WorldArena, 100000 JULIET_DEBUG_PARAM("Entities"));
ArenaParams by_type_params = { .ReserveSize = Kilobytes(1),
.CommitSize = Kilobytes(1),
.Name = "" JULIET_DEBUG_ONLY(, .DoNotReserveMore = true) };
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
by_type_params.Name = kEntity_type_names[i];
newManager->by_type[i].arena = ArenaAllocate(by_type_params);
newManager->by_type[i].array = NULL;
newManager->by_type[i].count = 0;
}
}
void ShutdownEntityManager(void)
{
EntityManager* manager = GetEntityManager();
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
ArenaRelease(manager->by_type[i].arena);
}
vector_arena_destroy(&manager->Entities);
}
EntityManager* GetEntityManager(void)
{
EntityManager* entityManager = GetGameState()->World->EntityManager;
Assert(entityManager != NULL);
return entityManager;
}
EntityID generate_next_entity_id(EntityManager* manager)
{
Assert(manager != NULL);
UserID user = get_local_user_id();
Assert(user != kInvalid_user_id);
Assert(manager->next_local_counter != kEntityID_user_id_mask);
EntityID new_id = make_entity_id(user, manager->next_local_counter);
manager->next_local_counter += 1ULL;
return new_id;
}
EntityTemplate* RegisterEntity(EntityManager* manager, Entity* base, DerivedType entity)
{
Assert(manager != NULL);
Assert(base != NULL);
base->ID = g_entity_manager_id++;
base->derived = entity;
VectorArenaPushPtr(Entity, &manager->Entities, base);
EntityTemplate* ptr = (EntityTemplate*)ArenaPushSize(
manager->by_type[base->derived_kind->kind].arena, base->derived_kind->size_of, base->derived_kind->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[base->derived_kind->kind]));
MemCopy(ptr, entity, base->derived_kind->size_of);
manager->by_type[base->derived_kind->kind].count += 1;
ptr->base = VectorArenaBack(Entity, &manager->Entities);
if (manager->by_type[base->derived_kind->kind].array == NULL)
{
manager->by_type[base->derived_kind->kind].array = ptr;
}
return ptr;
}
Entity* allocate_entity(EntityManager* manager, const Class* derived_type_class)
{
Assert(manager != NULL);
Assert(derived_type_class != NULL);
Assert(derived_type_class->kind < ENTITY(Count));
Assert(derived_type_class->size_of >= sizeof(EntityTemplate));
Assert(derived_type_class->alignment > 0);
Assert(derived_type_class->initialize_fct != NULL);
Entity base_template = { 0 };
base_template.derived_kind = derived_type_class;
base_template.is_dirty = true;
VectorArenaPushPtr(Entity, &manager->Entities, &base_template);
Entity* base_ptr = VectorArenaBack(Entity, &manager->Entities);
Assert(base_ptr != NULL);
typed_entity_array* typed_array = &manager->by_type[derived_type_class->kind];
Assert(typed_array->arena != NULL);
void* derived = ArenaPushSize(typed_array->arena, derived_type_class->size_of, derived_type_class->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[derived_type_class->kind]));
Assert(derived != NULL);
derived_type_class->initialize_fct(derived);
EntityTemplate* derived_template = (EntityTemplate*)derived;
base_ptr->derived = derived;
derived_template->base = base_ptr;
if (typed_array->array == NULL)
{
typed_array->array = derived_template;
}
typed_array->count += 1;
return base_ptr;
}
void UpdateEntityManager(EntityManager* manager)
{
Assert(manager != NULL);
// Todo : inert by definition dont move, but this is for test
typed_entity_array* by_type = &manager->by_type[ENTITY(Inert)];
for (index_t i = 0; i < by_type->count; ++i)
{
Inert* inert = ((Inert*)by_type->array) + i;
if (inert->MeshInstance != indexMax)
{
Matrix transform =
MatrixTranslation(inert->base->position.x, inert->base->position.y, inert->base->position.z);
SetMeshInstanceTransform(inert->MeshInstance, &transform);
}
}
}
Entity* deserialize_entity(Archive* ar, EntityManager* manager)
{
Assert(ar != NULL);
Assert(manager != NULL);
Assert(ar->loading);
String class_name = { 0 };
SERIALIZE_STR(ar, Class, &class_name);
const Class* class_ptr = find_class_by_name(class_name);
Assert(class_ptr != NULL);
Entity* entity_base = allocate_entity(manager, class_ptr);
Assert(entity_base != NULL);
serialize_entity(ar, entity_base);
if (entity_base->ID >= g_entity_manager_id)
{
g_entity_manager_id = entity_base->ID + 1;
}
entity_base->is_dirty = false;
return entity_base;
}
void update_local_counter(EntityManager* manager, EntityID entity_id)
{
Assert(manager != NULL);
uint8 user_id = get_local_user_id();
if (get_user_id(entity_id) == user_id)
{
uint64 counter = get_local_counter(entity_id);
if (counter >= manager->next_local_counter)
{
manager->next_local_counter = counter + 1ULL;
}
}
}
-145
View File
@@ -1,145 +0,0 @@
#include <Entity/EntityManager.h>
#include <Core/Common/EnumUtils.h>
#include <Core/Common/serialization.h>
#include <Data/World.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
#include <Graphics/MeshRenderer.h>
EntityID EntityManager::ID = 0;
void InitEntityManager(NonNullPtr<World> world)
{
EntityManager* newManager = ArenaPushStruct<EntityManager>(world->WorldArena);
world->EntityManager = newManager;
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
ArenaParams by_type_params{ .ReserveSize = Kilobytes(1),
.CommitSize = Kilobytes(1),
.Name = "" JULIET_DEBUG_ONLY(, .CanReserveMore = false) };
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
by_type_params.Name = kEntity_type_names[i];
newManager->by_type[i].arena = ArenaAllocate(by_type_params);
newManager->by_type[i].array = nullptr;
}
}
void ShutdownEntityManager()
{
auto& manager = GetEntityManager();
for (typed_entity_array& type : manager.by_type)
{
ArenaRelease(type.arena);
}
manager.Entities.Destroy();
}
EntityManager& GetEntityManager()
{
NonNullPtr entityManager = GetGameState()->World->EntityManager;
return *entityManager;
}
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity)
{
base->ID = EntityManager::ID++;
base->derived = entity;
manager.Entities.PushBack(*base);
auto* ptr = (EntityTemplate*)ArenaPushSize(manager.by_type[base->derived_kind->kind].arena,
base->derived_kind->size_of, base->derived_kind->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[base->derived_kind->kind]));
MemCopy(ptr, entity, base->derived_kind->size_of);
manager.by_type[base->derived_kind->kind].count += 1;
ptr->base = manager.Entities.Back();
if (manager.by_type[base->derived_kind->kind].array == nullptr)
{
manager.by_type[base->derived_kind->kind].array = ptr;
}
return ptr;
}
Entity* allocate_entity(EntityManager& manager, NonNullPtr<const Class> derived_type_class)
{
Assert(derived_type_class->kind < ENTITY(Count));
Assert(derived_type_class->size_of >= sizeof(EntityTemplate));
Assert(derived_type_class->alignment > 0);
Assert(derived_type_class->initialize_fct);
Entity base_template = {};
base_template.derived_kind = derived_type_class;
base_template.is_dirty = true;
manager.Entities.PushBack(base_template);
Entity* base_ptr = manager.Entities.Back();
Assert(base_ptr);
typed_entity_array& typed_array = manager.by_type[derived_type_class->kind];
Assert(typed_array.arena);
void* derived = ArenaPushSize(typed_array.arena, derived_type_class->size_of, derived_type_class->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[derived_type_class->kind]));
Assert(derived);
derived_type_class->initialize_fct(derived);
auto* derived_template = (EntityTemplate*)derived;
base_ptr->derived = derived;
derived_template->base = base_ptr;
if (typed_array.array == nullptr)
{
typed_array.array = derived_template;
}
typed_array.count += 1;
return base_ptr;
}
void UpdateEntityManager(EntityManager& manager)
{
// Todo : inert by definition dont move, but this is for test
auto& by_type = manager.by_type[ENTITY(Inert)];
for (index_t i = 0; i < by_type.count; ++i)
{
Inert* inert = reinterpret_cast<Inert*>(by_type.array) + i;
if (inert->MeshInstance != indexMax)
{
SetMeshInstanceTransform(inert->MeshInstance,
MatrixTranslation(inert->base->position.x, inert->base->position.y,
inert->base->position.z));
}
}
}
Entity* deserialize_entity(Archive& ar, EntityManager& manager)
{
Assert(ar.loading);
String class_name;
SERIALIZE(ar, Class, class_name);
NonNullPtr<const Class> class_ptr = find_class_by_name(class_name);
NonNullPtr<Entity> entity_base = allocate_entity(manager, class_ptr);
serialize(ar, entity_base);
if (entity_base->ID >= EntityManager::ID)
{
EntityManager::ID = entity_base->ID + 1;
}
entity_base->is_dirty = false;
return entity_base;
}
+20 -14
View File
@@ -3,11 +3,13 @@
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <Entity/entity_common.h> #include <Entity/entity_common.h>
struct World; typedef struct World World;
struct EntityTemplate; typedef struct EntityTemplate EntityTemplate;
struct Entity; typedef struct Entity Entity;
struct Class; typedef struct Class Class;
typedef struct Archive Archive;
typedef struct typed_entity_array typed_entity_array;
struct typed_entity_array struct typed_entity_array
{ {
Arena* arena; Arena* arena;
@@ -15,20 +17,24 @@ struct typed_entity_array
size_t count; size_t count;
}; };
typedef struct EntityManager EntityManager;
struct EntityManager struct EntityManager
{ {
static EntityID ID; uint64 next_local_counter;
// TODO: Should be a pool // TODO: Should be a pool
VectorArena<Entity, 100'000> Entities; VectorArena Entities;
typed_entity_array by_type[ENTITY(Count)]; typed_entity_array by_type[Entity_Type_Count];
}; };
void InitEntityManager(NonNullPtr<World> world); extern EntityID g_entity_manager_id;
void ShutdownEntityManager();
EntityManager& GetEntityManager(); void InitEntityManager(World* world);
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity); void ShutdownEntityManager(void);
[[nodiscard]] Entity* allocate_entity(EntityManager& manager, NonNullPtr<const Class> derived_type_class); EntityManager* GetEntityManager(void);
void UpdateEntityManager(EntityManager& manager); EntityTemplate* RegisterEntity(EntityManager* manager, Entity* base, DerivedType entity);
[[nodisacrd]] Entity* deserialize_entity(Archive& archive, EntityManager& manager); Entity* allocate_entity(EntityManager* manager, const Class* derived_type_class);
void UpdateEntityManager(EntityManager* manager);
Entity* deserialize_entity(Archive* archive, EntityManager* manager);
void update_local_counter(EntityManager* manager, EntityID entity_id);
@@ -5,17 +5,16 @@
// clang-format off // clang-format off
#define AS_STR(name) #name #define AS_STR(name) #name
const char* kEntity_type_names[] = { const char* kEntity_type_names[] = {
ENTITY_TYPE_LIST(AS_STR) ENTITY_TYPE_LIST(AS_STR)
"Count" "Count"
}; };
#undef AS_STR #undef AS_STR
#define AS_CLASS(name) name::kind #define AS_CLASS(name) &class_kind_##name
const Class* kEntity_type_class_ptr[] const Class* kEntity_type_class_ptr[] = {
{
ENTITY_TYPE_LIST(AS_CLASS) ENTITY_TYPE_LIST(AS_CLASS)
nullptr NULL
}; };
#undef AS_CLASS #undef AS_CLASS
// clang-format on // clang-format on
+27 -19
View File
@@ -1,40 +1,48 @@
#pragma once #pragma once
#include <Core/Common/EnumUtils.h>
#include <Engine/Class.h> #include <Engine/Class.h>
struct Class; typedef void* DerivedType;
using DerivedType = void*; typedef uint64 EntityID;
using EntityID = uint64_t;
#define kInvalid_user_id ((uint8)0U)
#define kInvalid_entity_id ((EntityID)0ULL)
#define kEntityID_user_id_shift ((EntityID)56ULL)
#define kEntityID_user_id_mask ((EntityID)0xFF00000000000000ULL)
// clang-format off // clang-format off
#define ENTITY_TYPE_LIST(X) X(Inert), #define ENTITY_TYPE_LIST(X) X(Inert),
#define AS_ENUM(name) name typedef uint8 Entity_Type;
enum class Entity_Type : uint8 #define AS_ENUM(name) Entity_Type_##name
enum
{ {
ENTITY_TYPE_LIST(AS_ENUM) ENTITY_TYPE_LIST(AS_ENUM)
Count Entity_Type_Count
}; };
#undef AS_ENUM #undef AS_ENUM
extern const char* kEntity_type_names[]; extern const char* kEntity_type_names[];
extern const Class* kEntity_type_class_ptr[]; extern const Class* kEntity_type_class_ptr[];
#define ENTITY(kind) ToUnderlying(Entity_Type::kind) #define ENTITY(kind) ((uint8)Entity_Type_##kind)
// clang-format on // clang-format on
struct Entity; typedef struct Entity Entity;
#define DECLARE_ENTITY() \ #define DECLARE_ENTITY() Entity* base;
Entity* base; \
DECLARE_CLASS()
#define DEFINE_ENTITY_VERSIONED(entity, version) \ #define DEFINE_ENTITY_VERSIONED(entity, version_num) \
constexpr Class entityKind##entity = \ const Class class_kind_##entity = { \
MakeClass(ConstString(#entity), (uint8)Entity_Type::entity, (version), &class_kind_Entity, sizeof(entity), \ .Name = ConstString(#entity), \
alignof(entity), (&initialize_thunk<entity>), (&serialize_thunk<entity>)); \ .kind = (uint8)Entity_Type_##entity, \
Class* entity::kind = const_cast<Class*>(&entityKind##entity); .version = (version_num), \
.base_class = &class_kind_Entity, \
.initialize_fct = init_##entity, \
.serialize_fct = serialize_##entity, \
.size_of = sizeof(entity), \
.alignment = AlignOf(entity) \
};
// Note: Needed by every classes see define above // Note: Needed by every entity class (see define above)
extern const Class class_kind_Entity; extern const Class class_kind_Entity;
+22
View File
@@ -0,0 +1,22 @@
#include <Entity/entity_types.h>
#include <Core/Common/serialization.h>
internal void init_Inert(void* payload)
{
Assert(payload != NULL);
Inert* inert = (Inert*)payload;
inert->base = NULL;
inert->MeshInstance = indexMax;
}
internal void serialize_Inert(Archive* ar, uint16 version, void* payload)
{
(void)version;
Assert(ar != NULL);
Assert(payload != NULL);
Inert* inert = (Inert*)payload;
SERIALIZE_U64(ar, MeshInstance, &inert->MeshInstance);
}
DEFINE_ENTITY_VERSIONED(Inert, 1)
-9
View File
@@ -1,9 +0,0 @@
#include <Entity/entity_types.h>
#include <Core/Common/serialization.h>
DEFINE_ENTITY_VERSIONED(Inert, 1)
internal void serialize(Archive& ar, uint16 /*version*/, Inert& inert)
{
SERIALIZE(ar, MeshInstance, inert.MeshInstance);
}
+3 -1
View File
@@ -2,9 +2,11 @@
#include <Entity/entity_common.h> #include <Entity/entity_common.h>
typedef struct Inert Inert;
struct Inert struct Inert
{ {
DECLARE_ENTITY() DECLARE_ENTITY()
index_t MeshInstance = indexMax; index_t MeshInstance;
}; };
DECLARE_CLASS(Inert)
+171
View File
@@ -0,0 +1,171 @@
#include <UnitTest/WorldUnitTest.h>
#if JULIET_DEBUG
#include <Core/Common/CoreUtils.h>
#include <Core/Common/serialization.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Memory/MemoryArena.h>
#include <Core/Thread/ThreadContext.h>
#include <Data/World.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
internal void TestEntityAllocationAndWiring(void)
{
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] Running TestEntityAllocationAndWiring...");
TempArena tempArena = scratch_begin(NULL, 0);
GameState* gameState = GetGameState();
World testWorld = { 0 };
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager* manager = testWorld.EntityManager;
// 1. Allocate Inert Entity via allocate_entity
Entity* base_entity = allocate_entity(manager, ClassKind(Inert));
Assert(base_entity != NULL);
Assert(base_entity->ID == 0); // Pure memory allocator leaves ID unassigned (0) until MakeEntity or deserialization
base_entity->ID = ++g_entity_manager_id;
Assert(base_entity->ID > 0);
Assert(base_entity->derived_kind == ClassKind(Inert));
Assert(base_entity->derived != NULL);
Assert(base_entity->is_dirty == true);
// 2. Validate mutual back-pointer wiring
EntityTemplate* derived = (EntityTemplate*)base_entity->derived;
Assert(derived->base == base_entity);
// 3. DownCast verification
Inert* inert = DownCastEntity(Inert, base_entity);
Assert(inert != NULL);
Assert(inert->base == base_entity);
// 4. Validate typed array tracking
typed_entity_array* inert_array = &manager->by_type[ENTITY(Inert)];
Assert(inert_array->count == 1);
Assert(inert_array->array == derived);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = NULL;
scratch_end(tempArena);
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] PASSED: TestEntityAllocationAndWiring");
}
internal void TestInPlaceDeserialization(void)
{
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] Running TestInPlaceDeserialization...");
TempArena tempArena = scratch_begin(NULL, 0);
GameState* gameState = GetGameState();
World testWorld = { 0 };
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager* manager = testWorld.EntityManager;
// 1. In-memory .jasset text fixture (no streams or files needed)
String asset_content = ConstString("; Class\n"
"Inert\n"
"; version\n"
"1\n"
"; class_version\n"
"1\n"
"; id\n"
"42\n"
"; position\n"
"12.5 -44.0 108.2 1.0\n"
"; MeshInstance\n"
"42\n");
ByteBuffer buffer = { .Data = (Byte*)asset_content.Str, .Size = asset_content.Size };
// 2. Tokenize into Archive
Archive load_ar = { 0 };
load_ar.arena = tempArena.Arena;
load_ar.loading = true;
load_ar.base = tokenize_archive(tempArena.Arena, buffer);
// 3. Deserialize in-place
Entity* loaded_base = deserialize_entity(&load_ar, manager);
// 4. Verify in-place allocations and values
Assert(loaded_base != NULL);
Assert(loaded_base->ID == 42);
Assert(g_entity_manager_id > 42); // Generator counter advanced past loaded ID
Assert(loaded_base->position.x == 12.5f);
Assert(loaded_base->position.y == -44.0f);
Assert(loaded_base->position.z == 108.2f);
Assert(loaded_base->is_dirty == false);
Inert* loaded_inert = DownCastEntity(Inert, loaded_base);
Assert(loaded_inert != NULL);
Assert(loaded_inert->base == loaded_base);
Assert(loaded_inert->MeshInstance == 42);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = NULL;
scratch_end(tempArena);
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] PASSED: TestInPlaceDeserialization");
}
internal void TestDirtyTrackingLifecycle(void)
{
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] Running TestDirtyTrackingLifecycle...");
TempArena tempArena = scratch_begin(NULL, 0);
GameState* gameState = GetGameState();
World testWorld = { 0 };
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager* manager = testWorld.EntityManager;
Entity* entity = allocate_entity(manager, ClassKind(Inert));
Assert(entity->is_dirty == true);
// TODO : proper save and mutation
// Simulate save
entity->is_dirty = false;
Assert(entity->is_dirty == false);
// Simulate mutation
entity->position.x += 1.0f;
entity->is_dirty = true;
Assert(entity->is_dirty == true);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = NULL;
scratch_end(tempArena);
Log(LogLevel_Message, LogCategory_Game, "[UnitTest] PASSED: TestDirtyTrackingLifecycle");
}
void UnitTest_WorldUnitTest(void)
{
Log(LogLevel_Message, LogCategory_Game, "==================================================");
Log(LogLevel_Message, LogCategory_Game, "Starting Entity Allocation & Lifecycle Unit Tests");
Log(LogLevel_Message, LogCategory_Game, "==================================================");
TestEntityAllocationAndWiring();
TestInPlaceDeserialization();
// TestSwapAndPopPointerFixup(); // Deferred to Entity_Removal_Brainstorm.md
TestDirtyTrackingLifecycle();
Log(LogLevel_Message, LogCategory_Game, "==================================================");
Log(LogLevel_Message, LogCategory_Game, "All Entity Lifecycle Unit Tests PASSED Successfully");
Log(LogLevel_Message, LogCategory_Game, "==================================================");
}
#endif
-173
View File
@@ -1,173 +0,0 @@
#include <UnitTest/WorldUnitTest.h>
#if JULIET_DEBUG
#include <Core/Common/CoreUtils.h>
#include <Core/Common/serialization.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Memory/MemoryArena.h>
#include <Core/Thread/ThreadContext.h>
#include <Data/World.h>
#include <Entity/entity_types.h>
#include <game.h>
namespace UnitTest
{
internal void TestEntityAllocationAndWiring()
{
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] Running TestEntityAllocationAndWiring...");
TempArena tempArena = scratch_begin(nullptr, 0);
GameState* gameState = GetGameState();
World testWorld{};
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager& manager = *testWorld.EntityManager;
// 1. Allocate Inert Entity via AllocateEntity
Entity* base_entity = allocate_entity(manager, Inert::kind);
Assert(base_entity != nullptr);
Assert(base_entity->ID == 0); // Pure memory allocator leaves ID unassigned (0) until MakeEntity or deserialization
base_entity->ID = ++EntityManager::ID;
Assert(base_entity->ID > 0);
Assert(base_entity->derived_kind == Inert::kind);
Assert(base_entity->derived != nullptr);
Assert(base_entity->is_dirty == true);
// 2. Validate mutual back-pointer wiring
auto* derived = reinterpret_cast<EntityTemplate*>(base_entity->derived);
Assert(derived->base == base_entity);
// 3. DownCast verification
Inert* inert = DownCast<Inert>(base_entity);
Assert(inert != nullptr);
Assert(inert->base == base_entity);
// 4. Validate typed array tracking
typed_entity_array& inert_array = manager.by_type[ENTITY(Inert)];
Assert(inert_array.count == 1);
Assert(inert_array.array == derived);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = nullptr;
scratch_end(tempArena);
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] PASSED: TestEntityAllocationAndWiring");
}
internal void TestInPlaceDeserialization()
{
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] Running TestInPlaceDeserialization...");
TempArena tempArena = scratch_begin(nullptr, 0);
GameState* gameState = GetGameState();
World testWorld{};
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager& manager = *testWorld.EntityManager;
// 1. In-memory .jasset text fixture (no streams or files needed)
String asset_content = ConstString("; Class\n"
"Inert\n"
"; version\n"
"1\n"
"; class_version\n"
"1\n"
"; id\n"
"42\n"
"; position\n"
"12.5 -44.0 108.2 1.0\n"
"; MeshInstance\n"
"42\n");
ByteBuffer buffer = { .Data = reinterpret_cast<Byte*>(asset_content.Str), .Size = asset_content.Size };
// 2. Tokenize into Archive
Archive load_ar = {};
load_ar.arena = tempArena.Arena;
load_ar.loading = true;
load_ar.base = tokenize_archive(tempArena.Arena, buffer);
// 3. Deserialize in-place
Entity* loaded_base = deserialize_entity(load_ar, manager);
// 4. Verify in-place allocations and values
Assert(loaded_base != nullptr);
Assert(loaded_base->ID == 42);
Assert(EntityManager::ID > 42); // Generator counter advanced past loaded ID
Assert(loaded_base->position.x == 12.5f);
Assert(loaded_base->position.y == -44.0f);
Assert(loaded_base->position.z == 108.2f);
Assert(loaded_base->is_dirty == false);
Inert* loaded_inert = DownCast<Inert>(loaded_base);
Assert(loaded_inert != nullptr);
Assert(loaded_inert->base == loaded_base);
Assert(loaded_inert->MeshInstance == 42);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = nullptr;
scratch_end(tempArena);
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] PASSED: TestInPlaceDeserialization");
}
internal void TestDirtyTrackingLifecycle()
{
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] Running TestDirtyTrackingLifecycle...");
TempArena tempArena = scratch_begin(nullptr, 0);
GameState* gameState = GetGameState();
World testWorld{};
gameState->World = &testWorld;
InitWorld(&testWorld, tempArena.Arena);
InitEntityManager(&testWorld);
EntityManager& manager = *testWorld.EntityManager;
Entity* entity = allocate_entity(manager, Inert::kind);
Assert(entity->is_dirty == true);
// TODO : proper save and mutation
// Simulate save
entity->is_dirty = false;
Assert(entity->is_dirty == false);
// Simulate mutation
entity->position.x += 1.0f;
entity->is_dirty = true;
Assert(entity->is_dirty == true);
ShutdownEntityManager();
ShutdownWorld(&testWorld);
gameState->World = nullptr;
scratch_end(tempArena);
Log(LogLevel::Message, LogCategory::Game, "[UnitTest] PASSED: TestDirtyTrackingLifecycle");
}
void WorldUnitTest()
{
Log(LogLevel::Message, LogCategory::Game, "==================================================");
Log(LogLevel::Message, LogCategory::Game, "Starting Entity Allocation & Lifecycle Unit Tests");
Log(LogLevel::Message, LogCategory::Game, "==================================================");
TestEntityAllocationAndWiring();
TestInPlaceDeserialization();
// TestSwapAndPopPointerFixup(); // Deferred to Entity_Removal_Brainstorm.md
TestDirtyTrackingLifecycle();
Log(LogLevel::Message, LogCategory::Game, "==================================================");
Log(LogLevel::Message, LogCategory::Game, "All Entity Lifecycle Unit Tests PASSED Successfully");
Log(LogLevel::Message, LogCategory::Game, "==================================================");
}
} // namespace UnitTest
#endif
+1 -4
View File
@@ -4,9 +4,6 @@
#if JULIET_DEBUG #if JULIET_DEBUG
namespace UnitTest void UnitTest_WorldUnitTest(void);
{
void WorldUnitTest();
} // namespace UnitTest
#endif #endif
+48 -42
View File
@@ -13,28 +13,26 @@
#include <Entity/EntityManager.h> #include <Entity/EntityManager.h>
#include <Graphics/Camera.h> #include <Graphics/Camera.h>
#include <Graphics/MeshRenderer.h> #include <Graphics/MeshRenderer.h>
#include <imgui.h> #include <dcimgui.h>
#include <stdio.h>
#if JULIET_DEBUG #if JULIET_DEBUG
#include <Debug/DebugTopBar.h> #include <Debug/DebugTopBar.h>
#include <UnitTest/WorldUnitTest.h> #include <UnitTest/WorldUnitTest.h>
#endif #endif
namespace global GameState* gGameState = NULL;
{
GameState* gGameState = nullptr;
}
GameState* GetGameState() GameState* GetGameState(void)
{ {
return gGameState; return gGameState;
} }
extern "C" JULIET_API void __cdecl GameShutdown() JULIET_API void __cdecl GameShutdown(void)
{ {
printf("Shutting down game...\n"); printf("Shutting down game...\n");
if (gGameState && gGameState->World) if (gGameState != NULL && gGameState->World != NULL)
{ {
ShutdownWorld(gGameState->World); ShutdownWorld(gGameState->World);
} }
@@ -42,47 +40,55 @@ extern "C" JULIET_API void __cdecl GameShutdown()
ShutdownEntityManager(); ShutdownEntityManager();
} }
extern "C" JULIET_API void __cdecl GameUpdate(GameData* params, [[maybe_unused]] float deltaTime) JULIET_API void __cdecl GameUpdate(GameData* params, float deltaTime)
{ {
Assert(params != NULL);
gGameState = params->GameState; gGameState = params->GameState;
if (!gGameState) if (gGameState == NULL)
{ {
Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "Game Total Arena" }); ArenaParams gameStateParams = { .ReserveSize = Megabytes(1), .Name = "Game Total Arena" };
auto* gameState = ArenaPushStruct<GameState>(gameStateArena); Arena* gameStateArena = ArenaAllocate(gameStateParams);
GameState* gameState = ArenaPushStruct(gameStateArena, GameState);
gGameState = params->GameState = gameState; gGameState = params->GameState = gameState;
gameState->TotalArena = gameStateArena; gameState->TotalArena = gameStateArena;
gameState->Mode = GameMode_Editor;
gameState->TotalTime = 0.0f; gameState->TotalTime = 0.0f;
gameState->Score = 0; gameState->Score = 0;
printf("Game Arena Allocated: %p\n", static_cast<void*>(gameState)); printf("Game Arena Allocated: %p\n", (void*)gameState);
// Reserve cameras. Lets go with 4 for now // Reserve cameras. Lets go with 4 for now
ReserveCamera(4); ReserveCamera(4);
#if JULIET_DEBUG #if JULIET_DEBUG
UnitTest::WorldUnitTest(); UnitTest_WorldUnitTest();
#endif #endif
// Bootstrap world // Bootstrap world
auto* worldArena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "World Arena" }); ArenaParams worldParams = { .ReserveSize = Megabytes(1), .Name = "World Arena" };
World* world = ArenaPushStruct<World>(worldArena JULIET_DEBUG_PARAM("World")); Arena* worldArena = ArenaAllocate(worldParams);
gameState->World = world; World* world = ArenaPushStructTag(worldArena, World, "World");
gameState->World = world;
InitWorld(gameState->World, worldArena); InitWorld(gameState->World, worldArena);
// Entity Use case // Entity Use case
InitEntityManager(gameState->World); InitEntityManager(gameState->World);
auto& manager = GetEntityManager(); EntityManager* manager = GetEntityManager();
NonNullPtr mesh = MakeEntity<Inert>(manager, 1.f, 2.f, 0.f); Inert* mesh = MakeEntity(Inert, manager, 1.f, 2.f, 0.f);
Assert(mesh != NULL);
MeshAssetID cubeAsset = GetCubePrimitiveMeshAssetID(); MeshAssetID cubeAsset = GetCubePrimitiveMeshAssetID();
MeshInstanceID meshInst = CreateMeshInstance(cubeAsset, 0, MatrixIdentity()); Matrix identity = MatrixIdentity();
MeshInstanceID meshInst = CreateMeshInstance(cubeAsset, 0, &identity);
mesh->MeshInstance = meshInst; mesh->MeshInstance = meshInst;
NonNullPtr mesh2 = MakeEntity<Inert>(manager, 4.f, 0.f, 2.f); Inert* mesh2 = MakeEntity(Inert, manager, 4.f, 0.f, 2.f);
Assert(mesh2 != NULL);
MeshInstanceID meshInst2 = CreateMeshInstance(cubeAsset, 0, MatrixIdentity()); MeshInstanceID meshInst2 = CreateMeshInstance(cubeAsset, 0, &identity);
mesh2->MeshInstance = meshInst2; mesh2->MeshInstance = meshInst2;
// Summer at 2pm lighting // Summer at 2pm lighting
@@ -97,64 +103,64 @@ extern "C" JULIET_API void __cdecl GameUpdate(GameData* params, [[maybe_unused]]
#endif #endif
GameMode previousFrameMode = gGameState->Mode; GameMode previousFrameMode = gGameState->Mode;
if (IsKeyPressed(ScanCode::F1)) if (IsKeyPressed(ScanCode_F1))
{ {
if (previousFrameMode == GameMode::Play) if (previousFrameMode == GameMode_Play)
{ {
gGameState->Mode = GameMode::Debug; gGameState->Mode = GameMode_Debug;
} }
else if (previousFrameMode == GameMode::Debug) else if (previousFrameMode == GameMode_Debug)
{ {
gGameState->Mode = GameMode::Play; gGameState->Mode = GameMode_Play;
} }
} }
if (gGameState->Mode == GameMode::Editor) if (gGameState->Mode == GameMode_Editor)
{ {
if (IsKeyPressed(ScanCode::F5)) if (IsKeyPressed(ScanCode_F5))
{ {
gGameState->Mode = GameMode::Play; gGameState->Mode = GameMode_Play;
} }
#if JULIET_EDITOR #if JULIET_EDITOR
RenderWorldEditorUI(*gGameState->World); RenderWorldEditorUI(gGameState->World);
#endif #endif
} }
if (gGameState->Mode == GameMode::Play) if (gGameState->Mode == GameMode_Play)
{ {
if (IsKeyPressed(ScanCode::Escape)) if (IsKeyPressed(ScanCode_Escape))
{ {
gGameState->Mode = GameMode::Editor; gGameState->Mode = GameMode_Editor;
} }
// update game // update game
} }
auto& manager = GetEntityManager(); EntityManager* manager = GetEntityManager();
UpdateEntityManager(manager); UpdateEntityManager(manager);
if (gGameState->Mode == GameMode::Debug) if (gGameState->Mode == GameMode_Debug)
{ {
if (previousFrameMode == GameMode::Play) if (previousFrameMode == GameMode_Play)
{ {
ActivateDebugController(); ActivateDebugController();
} }
if (IsKeyPressed(ScanCode::Escape)) if (IsKeyPressed(ScanCode_Escape))
{ {
gGameState->Mode = GameMode::Editor; gGameState->Mode = GameMode_Editor;
} }
UpdateDebugController(deltaTime); UpdateDebugController(deltaTime);
#if JULIET_DEBUG #if JULIET_DEBUG
ImGui::Begin("Debug"); ImGui_Begin("Debug", NULL, ImGuiWindowFlags_None);
RenderImGuiDebugController(deltaTime); RenderImGuiDebugController(deltaTime);
ImGui::End(); ImGui_End();
#endif #endif
} }
if (gGameState->Mode != GameMode::Debug && previousFrameMode == GameMode::Debug) if (gGameState->Mode != GameMode_Debug && previousFrameMode == GameMode_Debug)
{ {
DeactivateDebugController(); DeactivateDebugController();
} }
+13 -11
View File
@@ -3,25 +3,27 @@
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
#include <Data/World.h> #include <Data/World.h>
struct EntityManager; typedef struct EntityManager EntityManager;
enum class GameMode typedef uint32 GameMode;
enum
{ {
Editor, GameMode_Editor = 0,
Play, GameMode_Play,
Debug GameMode_Debug
}; };
typedef struct GameState GameState;
struct GameState struct GameState
{ {
Arena* TotalArena = nullptr; Arena* TotalArena;
World* World = nullptr; World* World;
GameMode Mode = GameMode::Editor; GameMode Mode;
float TotalTime = 0.0f; float TotalTime;
int Score = 0; int Score;
}; };
[[nodiscard]] extern GameState* GetGameState(); extern GameState* GetGameState(void);
-658
View File
@@ -1,658 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="src">
</Filter>
<Filter Include="src\Core">
</Filter>
<Filter Include="src\Core\Application">
</Filter>
<Filter Include="src\Core\Common">
</Filter>
<Filter Include="src\Core\Container">
</Filter>
<Filter Include="src\Core\HAL">
</Filter>
<Filter Include="src\Core\HAL\Display">
</Filter>
<Filter Include="src\Core\HAL\Display\Win32">
</Filter>
<Filter Include="src\Core\HAL\DynLib">
</Filter>
<Filter Include="src\Core\HAL\DynLib\Win32">
</Filter>
<Filter Include="src\Core\HAL\Event">
</Filter>
<Filter Include="src\Core\HAL\Filesystem">
</Filter>
<Filter Include="src\Core\HAL\Filesystem\Win32">
</Filter>
<Filter Include="src\Core\HAL\IO">
</Filter>
<Filter Include="src\Core\HAL\IO\Win32">
</Filter>
<Filter Include="src\Core\HAL\OS">
</Filter>
<Filter Include="src\Core\HAL\OS\Win32">
</Filter>
<Filter Include="src\Core\HotReload">
</Filter>
<Filter Include="src\Core\HotReload\Win32">
</Filter>
<Filter Include="src\Core\ImGui">
</Filter>
<Filter Include="src\Core\Logging">
</Filter>
<Filter Include="src\Core\Math">
</Filter>
<Filter Include="src\Core\Memory">
</Filter>
<Filter Include="src\Core\Networking">
</Filter>
<Filter Include="src\Core\Networking\Win32">
</Filter>
<Filter Include="src\Engine">
</Filter>
<Filter Include="src\Engine\Debug">
</Filter>
<Filter Include="src\Graphics">
</Filter>
<Filter Include="src\Graphics\D3D12">
</Filter>
<Filter Include="src\Graphics\D3D12\AgilitySDK">
</Filter>
<Filter Include="src\Graphics\D3D12\AgilitySDK\d3dx12">
</Filter>
<Filter Include="src\UnitTest">
</Filter>
<Filter Include="src\UnitTest\Container">
</Filter>
<Filter Include="include">
</Filter>
<Filter Include="include\Core">
</Filter>
<Filter Include="include\Core\Application">
</Filter>
<Filter Include="include\Core\Common">
</Filter>
<Filter Include="include\Core\Container">
</Filter>
<Filter Include="include\Core\HAL">
</Filter>
<Filter Include="include\Core\HAL\Display">
</Filter>
<Filter Include="include\Core\HAL\DynLib">
</Filter>
<Filter Include="include\Core\HAL\Event">
</Filter>
<Filter Include="include\Core\HAL\Filesystem">
</Filter>
<Filter Include="include\Core\HAL\IO">
</Filter>
<Filter Include="include\Core\HAL\Keyboard">
</Filter>
<Filter Include="include\Core\HAL\Mouse">
</Filter>
<Filter Include="include\Core\HAL\OS">
</Filter>
<Filter Include="include\Core\HotReload">
</Filter>
<Filter Include="include\Core\ImGui">
</Filter>
<Filter Include="include\Core\Logging">
</Filter>
<Filter Include="include\Core\Math">
</Filter>
<Filter Include="include\Core\Memory">
</Filter>
<Filter Include="include\Core\Networking">
</Filter>
<Filter Include="include\Core\Thread">
</Filter>
<Filter Include="include\Engine">
</Filter>
<Filter Include="include\Engine\Debug">
</Filter>
<Filter Include="include\Graphics">
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Core\Application\ApplicationManager.cpp">
<Filter>src\Core\Application</Filter>
</ClCompile>
<ClCompile Include="src\Core\Common\CoreUtils.cpp">
<Filter>src\Core\Common</Filter>
</ClCompile>
<ClCompile Include="src\Core\Common\String.cpp">
<Filter>src\Core\Common</Filter>
</ClCompile>
<ClCompile Include="src\Core\Container\Vector.cpp">
<Filter>src\Core\Container</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Display\Display.cpp">
<Filter>src\Core\HAL\Display</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayDevice.cpp">
<Filter>src\Core\HAL\Display\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.cpp">
<Filter>src\Core\HAL\Display\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Display\Win32\Win32Window.cpp">
<Filter>src\Core\HAL\Display\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\DynLib\Win32\DynamicLibrary.cpp">
<Filter>src\Core\HAL\DynLib\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Event\Keyboard.cpp">
<Filter>src\Core\HAL\Event</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Event\KeyboardMapping.cpp">
<Filter>src\Core\HAL\Event</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Event\Mouse.cpp">
<Filter>src\Core\HAL\Event</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Event\SystemEvent.cpp">
<Filter>src\Core\HAL\Event</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Event\WindowEvent.cpp">
<Filter>src\Core\HAL\Event</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Filesystem\Filesystem.cpp">
<Filter>src\Core\HAL\Filesystem</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\Filesystem\Win32\Win32Filesystem.cpp">
<Filter>src\Core\HAL\Filesystem\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\IO\IOStream.cpp">
<Filter>src\Core\HAL\IO</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\IO\Win32\Win32IOStream.cpp">
<Filter>src\Core\HAL\IO\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\OS\OS.cpp">
<Filter>src\Core\HAL\OS</Filter>
</ClCompile>
<ClCompile Include="src\Core\HAL\OS\Win32\Win32OS.cpp">
<Filter>src\Core\HAL\OS\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\HotReload\HotReload.cpp">
<Filter>src\Core\HotReload</Filter>
</ClCompile>
<ClCompile Include="src\Core\HotReload\Win32\Win32HotReload.cpp">
<Filter>src\Core\HotReload\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\ImGui\ImGuiService.cpp">
<Filter>src\Core\ImGui</Filter>
</ClCompile>
<ClCompile Include="src\Core\ImGui\ImGuiTests.cpp">
<Filter>src\Core\ImGui</Filter>
</ClCompile>
<ClCompile Include="src\Core\Juliet.cpp">
<Filter>src\Core</Filter>
</ClCompile>
<ClCompile Include="src\Core\Logging\LogManager.cpp">
<Filter>src\Core\Logging</Filter>
</ClCompile>
<ClCompile Include="src\Core\Math\MathRound.cpp">
<Filter>src\Core\Math</Filter>
</ClCompile>
<ClCompile Include="src\Core\Memory\Allocator.cpp">
<Filter>src\Core\Memory</Filter>
</ClCompile>
<ClCompile Include="src\Core\Memory\MemoryArena.cpp">
<Filter>src\Core\Memory</Filter>
</ClCompile>
<ClCompile Include="src\Core\Memory\MemoryArenaDebug.cpp">
<Filter>src\Core\Memory</Filter>
</ClCompile>
<ClCompile Include="src\Core\Memory\MemoryArenaTests.cpp">
<Filter>src\Core\Memory</Filter>
</ClCompile>
<ClCompile Include="src\Core\Memory\ScratchArena.cpp">
<Filter>src\Core\Memory</Filter>
</ClCompile>
<ClCompile Include="src\Core\Networking\NetworkPacket.cpp">
<Filter>src\Core\Networking</Filter>
</ClCompile>
<ClCompile Include="src\Core\Networking\Socket.cpp">
<Filter>src\Core\Networking</Filter>
</ClCompile>
<ClCompile Include="src\Core\Networking\TcpListener.cpp">
<Filter>src\Core\Networking</Filter>
</ClCompile>
<ClCompile Include="src\Core\Networking\TcpSocket.cpp">
<Filter>src\Core\Networking</Filter>
</ClCompile>
<ClCompile Include="src\Core\Networking\Win32\Win32SocketPlatformImpl.cpp">
<Filter>src\Core\Networking\Win32</Filter>
</ClCompile>
<ClCompile Include="src\Core\PCH.cpp">
<Filter>src\Core</Filter>
</ClCompile>
<ClCompile Include="src\Engine\Debug\MemoryDebugger.cpp">
<Filter>src\Engine\Debug</Filter>
</ClCompile>
<ClCompile Include="src\Engine\Engine.cpp">
<Filter>src\Engine</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.cpp">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Buffer.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12CommandList.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12DescriptorHeap.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsDevice.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12InternalTests.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12SwapChain.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Synchronization.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Texture.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\D3D12\D3D12Utils.cpp">
<Filter>src\Graphics\D3D12</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\DebugDisplayRenderer.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Graphics.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\ImGuiRenderer.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Mesh.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MeshRenderer.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\SkyboxRenderer.cpp">
<Filter>src\Graphics</Filter>
</ClCompile>
<ClCompile Include="src\UnitTest\Container\VectorUnitTest.cpp">
<Filter>src\UnitTest\Container</Filter>
</ClCompile>
<ClCompile Include="src\UnitTest\RunUnitTests.cpp">
<Filter>src\UnitTest</Filter>
</ClCompile>
<ClInclude Include="include\Core\Application\ApplicationManager.h">
<Filter>include\Core\Application</Filter>
</ClInclude>
<ClInclude Include="include\Core\Application\IApplication.h">
<Filter>include\Core\Application</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\CoreTypes.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\CoreUtils.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\CRC32.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\EnumUtils.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonNullPtr.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\String.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Container\Vector.h">
<Filter>include\Core\Container</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Display\Display.h">
<Filter>include\Core\HAL\Display</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\DynLib\DynamicLibrary.h">
<Filter>include\Core\HAL\DynLib</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Event\SystemEvent.h">
<Filter>include\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Filesystem\Filesystem.h">
<Filter>include\Core\HAL\Filesystem</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\IO\IOStream.h">
<Filter>include\Core\HAL\IO</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Keyboard\Keyboard.h">
<Filter>include\Core\HAL\Keyboard</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Keyboard\KeyCode.h">
<Filter>include\Core\HAL\Keyboard</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Keyboard\ScanCode.h">
<Filter>include\Core\HAL\Keyboard</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\Mouse\Mouse.h">
<Filter>include\Core\HAL\Mouse</Filter>
</ClInclude>
<ClInclude Include="include\Core\HAL\OS\OS.h">
<Filter>include\Core\HAL\OS</Filter>
</ClInclude>
<ClInclude Include="include\Core\HotReload\HotReload.h">
<Filter>include\Core\HotReload</Filter>
</ClInclude>
<ClInclude Include="include\Core\ImGui\ImGuiService.h">
<Filter>include\Core\ImGui</Filter>
</ClInclude>
<ClInclude Include="include\Core\ImGui\ImGuiTests.h">
<Filter>include\Core\ImGui</Filter>
</ClInclude>
<ClInclude Include="include\Core\JulietInit.h">
<Filter>include\Core</Filter>
</ClInclude>
<ClInclude Include="include\Core\Logging\LogManager.h">
<Filter>include\Core\Logging</Filter>
</ClInclude>
<ClInclude Include="include\Core\Logging\LogTypes.h">
<Filter>include\Core\Logging</Filter>
</ClInclude>
<ClInclude Include="include\Core\Main.h">
<Filter>include\Core</Filter>
</ClInclude>
<ClInclude Include="include\Core\Math\MathUtils.h">
<Filter>include\Core\Math</Filter>
</ClInclude>
<ClInclude Include="include\Core\Math\Matrix.h">
<Filter>include\Core\Math</Filter>
</ClInclude>
<ClInclude Include="include\Core\Math\Shape.h">
<Filter>include\Core\Math</Filter>
</ClInclude>
<ClInclude Include="include\Core\Math\Vector.h">
<Filter>include\Core\Math</Filter>
</ClInclude>
<ClInclude Include="include\Core\Memory\Allocator.h">
<Filter>include\Core\Memory</Filter>
</ClInclude>
<ClInclude Include="include\Core\Memory\MemoryArena.h">
<Filter>include\Core\Memory</Filter>
</ClInclude>
<ClInclude Include="include\Core\Memory\MemoryArenaDebug.h">
<Filter>include\Core\Memory</Filter>
</ClInclude>
<ClInclude Include="include\Core\Memory\ScratchArena.h">
<Filter>include\Core\Memory</Filter>
</ClInclude>
<ClInclude Include="include\Core\Memory\Utils.h">
<Filter>include\Core\Memory</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\IPAddress.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\NetworkPacket.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\Socket.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\SocketHandle.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\TcpListener.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\Networking\TcpSocket.h">
<Filter>include\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="include\Core\PCH.h">
<Filter>include\Core</Filter>
</ClInclude>
<ClInclude Include="include\Core\Thread\Mutex.h">
<Filter>include\Core\Thread</Filter>
</ClInclude>
<ClInclude Include="include\Core\Thread\Thread.h">
<Filter>include\Core\Thread</Filter>
</ClInclude>
<ClInclude Include="include\Engine\Class.h">
<Filter>include\Engine</Filter>
</ClInclude>
<ClInclude Include="include\Engine\Debug\MemoryDebugger.h">
<Filter>include\Engine\Debug</Filter>
</ClInclude>
<ClInclude Include="include\Engine\Engine.h">
<Filter>include\Engine</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Camera.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Colors.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\DebugDisplay.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Graphics.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\GraphicsBuffer.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\GraphicsConfig.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\GraphicsPipeline.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\ImGuiRenderer.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Lighting.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Mesh.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\MeshRenderer.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\PushConstants.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\RenderPass.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Shader.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\SkyboxRenderer.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\Texture.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Graphics\VertexData.h">
<Filter>include\Graphics</Filter>
</ClInclude>
<ClInclude Include="include\Juliet.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Display\DisplayDevice.h">
<Filter>src\Core\HAL\Display</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Display\Display_Private.h">
<Filter>src\Core\HAL\Display</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.h">
<Filter>src\Core\HAL\Display\Win32</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Display\Win32\Win32Window.h">
<Filter>src\Core\HAL\Display\Win32</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Display\Window.h">
<Filter>src\Core\HAL\Display</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Event\KeyboardMapping.h">
<Filter>src\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Event\Keyboard_Private.h">
<Filter>src\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Event\Mouse_Private.h">
<Filter>src\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Event\Win32ScanCode.h">
<Filter>src\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Event\WindowEvent.h">
<Filter>src\Core\HAL\Event</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Platform.h">
<Filter>src\Core\HAL\Filesystem</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Private.h">
<Filter>src\Core\HAL\Filesystem</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\IO\IOStream_Private.h">
<Filter>src\Core\HAL\IO</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\OS\OS_Private.h">
<Filter>src\Core\HAL\OS</Filter>
</ClInclude>
<ClInclude Include="src\Core\HAL\Win32.h">
<Filter>src\Core\HAL</Filter>
</ClInclude>
<ClInclude Include="src\Core\Math\Math_Private.h">
<Filter>src\Core\Math</Filter>
</ClInclude>
<ClInclude Include="src\Core\Networking\SocketPlatformImpl.h">
<Filter>src\Core\Networking</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12compatibility.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12sdklayers.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12shader.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12video.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dcommon.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_barriers.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_check_feature_support.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_core.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_default.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_pipeline_state_stream.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_render_pass.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_resource_helpers.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_root_signature.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_state_object.h">
<Filter>src\Graphics\D3D12\AgilitySDK\d3dx12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.h">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Buffer.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12CommandList.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Common.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12DescriptorHeap.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12GraphicsDevice.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12GraphicsPipeline.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Includes.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12InternalTests.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Shader.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12SwapChain.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Synchronization.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Texture.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\D3D12Utils.h">
<Filter>src\Graphics\D3D12</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\GraphicsDevice.h">
<Filter>src\Graphics</Filter>
</ClInclude>
<ClInclude Include="src\UnitTest\VectorTestHelper.h">
<Filter>src\UnitTest</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\D3D12TokenizedProgramFormat.hpp">
<Filter>src\Graphics\D3D12\AgilitySDK</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -1,9 +0,0 @@
#pragma once
#include <Core/Application/IApplication.h>
#include <Juliet.h>
enum class JulietInit_Flags : uint8;
struct Arena;
extern JULIET_API void StartApplication(IApplication& app, JulietInit_Flags flags);
@@ -1,29 +0,0 @@
#pragma once
#include <Core/Common/NonNullPtr.h>
struct Camera;
struct RenderPass;
struct CommandList;
struct Texture;
struct ColorTargetInfo;
struct DepthStencilTargetInfo;
struct Arena;
class IApplication
{
public:
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
virtual struct Window* GetPlatformWindow() = 0;
virtual struct GraphicsDevice* GetGraphicsDevice() = 0;
// Render Lifecycle (Engine-Managed Render Loop)
virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
};
+41 -43
View File
@@ -1,62 +1,60 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
// From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c // From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
namespace details global const uint32 g_crc32_tab[256] = {
{ 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u, 0x0edb8832u,
constexpr uint32_t crc32_tab[] = { 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u, 0x1db71064u, 0x6ab020f2u,
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u, 0x136c9856u, 0x646ba8c0u, 0xfd62f97au,
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u, 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu, 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u,
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u, 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0xcfba9599u, 0xb8bda50fu, 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xb6662d3du, 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u, 0x6b6b51f4u,
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u, 0x65b0d9c6u, 0x12b7e950u,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u, 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu, 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u, 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u,
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x206f85b3u, 0xb966d409u, 0xce61e49fu, 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0xb7bd5c3bu, 0xc0ba6cadu, 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u,
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0x73dc1683u, 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u, 0xfed41b76u,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u, 0xd6d6a3e8u, 0xa1d1937eu,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu, 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u, 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu, 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du, 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0x72076785u, 0x05005713u, 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u,
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x0bdbdf21u, 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u, 0xa00ae278u,
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu, 0xaed16a4au, 0xd9d65adcu,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u, 0xbdbdf21cu, 0xcabac28au, 0x53b39330u,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu, 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, };
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
}
constexpr uint32 crc32(const char* str, size_t length) static inline uint32 crc32_bytes(const char* str, size_t length)
{ {
Assert(str && length > 0); Assert(str != NULL && length > 0);
const char* p = str; const char* p = str;
uint32_t crc = ~0U; uint32 crc = ~0U;
while (length--) while (length--)
{ {
crc = details::crc32_tab[(crc ^ static_cast<uint8>(*p++)) & 0xFF] ^ (crc >> 8); crc = g_crc32_tab[(crc ^ (uint8)(*p++)) & 0xFFu] ^ (crc >> 8);
} }
return crc ^ ~0U; return crc ^ ~0U;
} }
constexpr uint32 crc32(String str) static inline uint32 crc32_str(String str)
{ {
return crc32(str.Str, str.Size); return crc32_bytes(str.Str, str.Size);
} }
consteval uint32 operator""_crc32(const char* str, size_t length) static inline uint32 crc32_cstr(const char* str)
{ {
return crc32(str, length); return crc32_bytes(str, StringLengthCStr(str));
} }
+49 -46
View File
@@ -1,65 +1,68 @@
#pragma once #pragma once
using uint8 = uint8_t; #include <limits.h>
using uint16 = uint16_t; #include <stddef.h>
using uint32 = uint32_t; #include <stdint.h>
using uint64 = uint64_t;
using int8 = int8_t; typedef uint8_t uint8;
using int16 = int16_t; typedef uint16_t uint16;
using int32 = int32_t; typedef uint32_t uint32;
using int64 = int64_t; typedef uint64_t uint64;
using Byte = std::byte; typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
using size_t = std::size_t; typedef uint8 bool8;
using index_t = size_t; typedef uint16 bool16;
typedef uint32 bool32;
typedef uint64 bool64;
#ifndef __cplusplus
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif
typedef uint8 Byte;
typedef size_t index_t;
typedef struct ByteBuffer ByteBuffer;
struct ByteBuffer struct ByteBuffer
{ {
Byte* Data; Byte* Data;
size_t Size; size_t Size;
}; };
using ptrdiff_t = decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr)); typedef void (*FunctionPtr)(void);
using FunctionPtr = auto (*)(void) -> void; #define uint8Max ((uint8)0xFFu)
#define uint16Max ((uint16)0xFFFFu)
#define uint32Max ((uint32)0xFFFFFFFFu)
#define uint64Max ((uint64)0xFFFFFFFFFFFFFFFFull)
// Limits #define int8Max ((int8)0x7F)
template <typename Type> #define int16Max ((int16)0x7FFF)
consteval Type MaxValueOf() #define int32Max ((int32)0x7FFFFFFF)
{ #define int64Max ((int64)0x7FFFFFFFFFFFFFFFll)
return std::numeric_limits<Type>::max();
}
constexpr uint8 uint8Max = MaxValueOf<uint8>();
constexpr uint16 uint16Max = MaxValueOf<uint16>();
constexpr uint32 uint32Max = MaxValueOf<uint32>();
constexpr uint64 uint64Max = MaxValueOf<uint64>();
constexpr int8 int8Max = MaxValueOf<int8>(); #define indexMax ((index_t)SIZE_MAX)
constexpr int16 int16Max = MaxValueOf<int16>();
constexpr int32 int32Max = MaxValueOf<int32>();
constexpr int64 int64Max = MaxValueOf<int64>();
constexpr index_t indexMax = MaxValueOf<index_t>(); #define uint8Min ((uint8)0u)
#define uint16Min ((uint16)0u)
#define uint32Min ((uint32)0u)
#define uint64Min ((uint64)0ull)
template <typename Type> #define int8Min ((int8)(-128))
consteval Type MinValueOf() #define int16Min ((int16)(-32768))
{ #define int32Min ((int32)(-2147483647 - 1))
return std::numeric_limits<Type>::lowest(); #define int64Min ((int64)(-9223372036854775807ll - 1ll))
}
constexpr uint8 uint8Min = MinValueOf<uint8>(); #define indexMin ((index_t)0u)
constexpr uint16 uint16Min = MinValueOf<uint16>();
constexpr uint32 uint32Min = MinValueOf<uint32>();
constexpr uint64 uint64Min = MinValueOf<uint64>();
constexpr int8 int8Min = MinValueOf<int8>(); #define Kilobytes(value) ((uint64)(value) * 1024ull)
constexpr int16 int16Min = MinValueOf<int16>(); #define Megabytes(value) (Kilobytes(value) * 1024ull)
constexpr int32 int32Min = MinValueOf<int32>();
constexpr int64 int64Min = MinValueOf<int64>();
constexpr index_t indexMin = MinValueOf<index_t>();
#define Kilobytes(value) value * 1024
#define Megabytes(value) Kilobytes(value) * 1024
+68 -103
View File
@@ -1,22 +1,27 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#include <Core/Common/CoreTypes.h>
#define global static #define global static
#define internal static #define internal static
#define Glue_(A, B) A##B
#define Glue(A, B) Glue_(A, B)
#define StaticAssert(C, ID) global uint8 Glue(ID, __LINE__)[(C) ? 1 : -1]
// 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)
#define JULIET_SUPPRESS_CLANG(str) JULIET_PRAGMA(clang diagnostic ignored str) #define JULIET_SUPPRESS_CLANG(str) JULIET_PRAGMA(clang diagnostic ignored str)
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define JULIET_PRAGMA(x) __pragma(x) #define JULIET_PRAGMA(x) __pragma(x)
#define JULIET_SUPPRESS_MSVC(id) JULIET_PRAGMA(warning(disable : id)) #define JULIET_SUPPRESS_MSVC(id) JULIET_PRAGMA(warning(disable : id))
#define JULIET_SUPPRESS_CLANG(str) #define JULIET_SUPPRESS_CLANG(str)
#else #else
#define JULIET_PRAGMA(x) #define JULIET_PRAGMA(x)
@@ -27,20 +32,18 @@
// 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)
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define JULIET_WARNING_PUSH JULIET_PRAGMA(warning(push)) #define JULIET_WARNING_PUSH JULIET_PRAGMA(warning(push))
#define JULIET_WARNING_POP JULIET_PRAGMA(warning(pop)) #define JULIET_WARNING_POP JULIET_PRAGMA(warning(pop))
#else #else
#define JULIET_WARNING_PUSH #define JULIET_WARNING_PUSH
#define JULIET_WARNING_POP #define JULIET_WARNING_POP
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
// 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
#define JULIET_PLATFORM_BREAK() __builtin_trap() #define JULIET_PLATFORM_BREAK() __builtin_trap()
#else #else
#include <signal.h> #include <signal.h>
@@ -49,18 +52,14 @@
#if JULIET_DEBUG #if JULIET_DEBUG
#define JULIET_ASSERT_INTERNAL(expression, message) \ #define JULIET_ASSERT_INTERNAL(expression, message) \
JULIET_WARNING_PUSH \ do \
JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \
JULIET_SUPPRESS_MSVC(4127) \
JULIET_SUPPRESS_MSVC(4548) \
{ \ { \
if (!(expression)) [[unlikely]] \ if (!(expression)) \
{ \ { \
JulietAssert(#expression, message); \ JulietAssert(#expression, message, __FILE__, __func__, (uint32)__LINE__, 0); \
} \ } \
} \ } \
JULIET_WARNING_POP \ while (0)
static_assert(true, "")
#define AssertHR(hr_expression, message) \ #define AssertHR(hr_expression, message) \
do \ do \
@@ -68,7 +67,7 @@
long hr_val = (hr_expression); \ long hr_val = (hr_expression); \
if (hr_val < 0) \ if (hr_val < 0) \
{ \ { \
JulietAssert(#hr_expression, message, std::source_location::current(), hr_val); \ JulietAssert(#hr_expression, message, __FILE__, __func__, (uint32)__LINE__, hr_val); \
} \ } \
} \ } \
while (0) while (0)
@@ -80,95 +79,70 @@
#define Unimplemented() \ #define Unimplemented() \
do \ do \
{ \ { \
JulietAssert("UNIMPLEMENTED", "This code path is not yet functional."); \ JulietAssert("UNIMPLEMENTED", "This code path is not yet functional.", __FILE__, __func__, (uint32)__LINE__, 0); \
} \ } \
while (0) while (0)
#else #else
#define Assert(...) ((void)0) #define Assert(...) ((void)0)
#define AssertHR(hr_expression, message) ((void)(hr_expression)) #define AssertHR(hr_expression, message) ((void)(hr_expression))
#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, const char* file, const char* function,
std::source_location location = std::source_location::current(), long handleResult = 0); uint32 line, long handle_result);
#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)
static inline void ZeroSize(size_t size, void* ptr)
{ {
auto Byte = (uint8*)ptr; uint8* byte_ptr = (uint8*)ptr;
while (size--) while (size--)
{ {
*Byte++ = 0; *byte_ptr++ = 0;
} }
} }
#define Restrict __restrict #define Restrict __restrict
template <class Function> static inline bool8 IsValidByteBuffer(ByteBuffer buffer)
class DeferredFunction
{ {
public: return (buffer.Size > 0 && buffer.Data != NULL);
explicit DeferredFunction(const Function& otherFct) noexcept
: Callback(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) extern JULIET_API void FreeByteBuffer(ByteBuffer* buffer);
static inline bool8 IsPow2(uint64 x)
{ {
return buffer.Size > 0 && buffer.Data; return (x != 0) && ((x & (x - 1)) == 0);
} }
extern JULIET_API void Free(ByteBuffer& buffer); static inline uint64 AlignPow2(uint64 x, uint64 alignment)
template <std::integral T>
[[nodiscard]] constexpr T AlignPow2(T x, T alignment)
{ {
// Safety Check: Assert(IsPow2(alignment));
Assert(std::has_single_bit(static_cast<size_t>(alignment)));
return (x + alignment - 1) & ~(alignment - 1); return (x + alignment - 1) & ~(alignment - 1);
} }
template <typename T> static inline void SwapMemory(void* Restrict a, void* Restrict b, size_t elem_size)
inline void Swap(T* Restrict a, T* Restrict b)
{ {
T temp = std::move(*a); uint8* pa = (uint8*)a;
*a = std::move(*b); uint8* pb = (uint8*)b;
*b = std::move(temp); for (size_t i = 0; i < elem_size; ++i)
{
uint8 tmp = pa[i];
pa[i] = pb[i];
pb[i] = tmp;
}
} }
// 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
#if !defined(COMPILER_CLANG) #if !defined(COMPILER_CLANG)
#define COMPILER_CLANG 0 #define COMPILER_CLANG 0
#endif #endif
@@ -186,42 +160,33 @@ inline void Swap(T* Restrict a, T* Restrict b)
#error AlignOf not defined for this compiler. #error AlignOf not defined for this compiler.
#endif #endif
template <typename T> #if COMPILER_MSVC || (COMPILER_CLANG && defined(_MSC_VER))
[[nodiscard]] constexpr const char* GetTypeName() #define ThreadLocal __declspec(thread)
{
#if COMPILER_CLANG
return __PRETTY_FUNCTION__;
#elif COMPILER_MSVC
return __FUNCSIG__;
#elif COMPILER_GCC
return __PRETTY_FUNCTION__;
#else #else
return "UnknownType"; #define ThreadLocal __thread
#endif #endif
}
inline uint16 safe_cast_uint16(uint32 value) static 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; #define bitmask1 0x00000001u
const uint32 bitmask2 = 0b0000'0011; #define bitmask2 0x00000003u
const uint32 bitmask3 = 0b0000'0111; #define bitmask3 0x00000007u
const uint32 bitmask4 = 0b0000'1111; #define bitmask4 0x0000000fu
const uint32 bitmask5 = 0b0001'1111; #define bitmask5 0x0000001fu
const uint32 bitmask6 = 0b0011'1111; #define bitmask6 0x0000003fu
const uint32 bitmask7 = 0b0111'1111; #define bitmask7 0x0000007fu
const uint32 bitmask8 = 0b1111'1111; #define bitmask8 0x000000ffu
const uint32 bitmask9 = 0x0000'01ff; #define bitmask9 0x000001ffu
const uint32 bitmask10 = 0x0000'03ff; #define bitmask10 0x000003ffu
const uint32 bitmask11 = 0x0000'07ff; #define bitmask11 0x000007ffu
const uint32 bitmask12 = 0x0000'0fff; #define bitmask12 0x00000fffu
const uint32 bitmask13 = 0x0000'1fff; #define bitmask13 0x00001fffu
const uint32 bitmask14 = 0x0000'3fff; #define bitmask14 0x00003fffu
const uint32 bitmask15 = 0x0000'7fff; #define bitmask15 0x00007fffu
const uint32 bitmask16 = 0x0000'ffff; #define bitmask16 0x0000ffffu
// ... #define bitmask32 0xffffffffu
const uint32 bitmask32 = 0xffff'ffff;
-86
View File
@@ -1,86 +0,0 @@
#pragma once
template <typename T>
concept IsEnum = std::is_enum_v<T>;
template <IsEnum E>
constexpr E operator~(E lhs) noexcept
{
return static_cast<E>(~static_cast<std::underlying_type_t<E>>(lhs));
}
template <IsEnum E>
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));
}
template <IsEnum E>
constexpr E& operator|=(E& lhs, E rhs) noexcept
{
return lhs = (lhs | rhs);
}
template <IsEnum E>
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));
}
template <IsEnum E>
constexpr E& operator&=(E& lhs, E rhs) noexcept
{
return lhs = (lhs & rhs);
}
template <IsEnum E>
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));
}
template <IsEnum E>
constexpr E& operator^=(E& lhs, E rhs) noexcept
{
return lhs = (lhs ^ rhs);
}
template <IsEnum E>
constexpr std::underlying_type_t<E> operator-(E lhs, E rhs) noexcept
{
using T = std::underlying_type_t<E>;
return static_cast<T>(static_cast<T>(lhs) - static_cast<T>(rhs));
}
template <IsEnum E>
constexpr std::underlying_type_t<E> operator+(E lhs, E rhs) noexcept
{
using T = std::underlying_type_t<E>;
return static_cast<T>(static_cast<T>(lhs) + static_cast<T>(rhs));
}
template <IsEnum E>
constexpr E operator-(E lhs, std::underlying_type_t<E> rhs) noexcept
{
using T = std::underlying_type_t<E>;
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) - rhs));
}
template <IsEnum E>
constexpr E operator+(E lhs, std::underlying_type_t<E> rhs) noexcept
{
using T = std::underlying_type_t<E>;
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) + rhs));
}
template <IsEnum E>
constexpr std::underlying_type_t<E> ToUnderlying(E enm) noexcept
{
return static_cast<std::underlying_type_t<E>>(enm);
}
template <IsEnum E>
constexpr E ToEnum(std::underlying_type_t<E> value) noexcept
{
return static_cast<E>(value);
}
-110
View File
@@ -1,110 +0,0 @@
#pragma once
#include <Core/Common/CoreUtils.h>
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
{
public:
constexpr NonNullPtr(Type* ptr)
: InternalPtr(ptr)
{
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
}
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
: InternalPtr(otherPtr.Get())
{
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
}
// Assignment
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
{
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
InternalPtr = ptr;
return *this;
}
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
{
InternalPtr = otherPtr.Get();
return *this;
}
// Accessors
[[nodiscard]] constexpr operator Type*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
[[nodiscard]] constexpr Type* Get() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
[[nodiscard]] constexpr Type& operator*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return *InternalPtr;
}
[[nodiscard]] constexpr Type* operator->() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
// Comparisons
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
{
return InternalPtr == otherPtr.InternalPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
{
return InternalPtr == otherRawPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
{
return otherRawPtr == nonNullPtr.InternalPtr;
}
// Forbid assigning a nullptr at compile time
constexpr NonNullPtr(std::nullptr_t)
: InternalPtr(nullptr)
{
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
}
[[nodiscard]] constexpr NonNullPtr& operator=(std::nullptr_t)
{
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
return *this;
}
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
private:
Type* InternalPtr;
};
template <typename T>
NonNullPtr(T*) -> NonNullPtr<T>;
+76 -86
View File
@@ -1,78 +1,84 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/CoreUtils.h>
#include <Core/Math/MathUtils.h> #include <Core/Math/MathUtils.h>
#include <Core/Memory/Utils.h> #include <Core/Memory/Utils.h>
#ifdef global typedef struct Arena Arena;
#undef global
#define RESTORE_GLOBAL
#endif
#ifdef RESTORE_GLOBAL #define ConstString(str) ((String){ (char*)(str), sizeof(str) - 1 })
#define global static #define ConstStringInit(str) { (char*)(str), sizeof(str) - 1 }
#undef RESTORE_GLOBAL #define CStr(str) ((str).Str)
#endif
struct Arena;
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
#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 typedef uint8 StringEncoding;
enum
{ {
Unknown = 0, StringEncoding_Unknown = 0,
ASCII, StringEncoding_ASCII,
LATIN1, StringEncoding_LATIN1,
UTF8, StringEncoding_UTF8,
UTF16, StringEncoding_UTF16,
UTF32, StringEncoding_UTF32,
UCS2, StringEncoding_UCS2,
UCS4, StringEncoding_UCS4,
}; };
// Represents a UTF-8 String. // Represents a UTF-8 String.
// Not null terminated. // Not null terminated.
typedef struct String8 String8;
struct String8 struct String8
{ {
char* Str; char* Str;
size_t Size; size_t Size;
}; };
using String = String8; typedef String8 String;
typedef struct String16 String16;
struct String16 struct String16
{ {
uint16* Str; uint16* Str;
size_t Size; size_t Size;
}; };
struct StringBuffer : String typedef struct StringBuffer StringBuffer;
struct StringBuffer
{ {
union
{
String8 str8;
struct
{
char* Str;
size_t Size;
};
};
size_t Capacity; size_t Capacity;
}; };
typedef struct UnicodeDecode UnicodeDecode;
struct UnicodeDecode struct UnicodeDecode
{ {
uint32 Increment; uint32 Increment;
uint32 Codepoint; uint32 Codepoint;
}; };
constexpr uint32 kInvalidUTF8 = 0xFFFD; #define kInvalidUTF8 ((uint32)0xFFFDu)
inline size_t StringLength(String str) static inline size_t StringLength(String str)
{ {
return str.Size; return str.Size;
} }
inline size_t StringLength(const char* str) static inline size_t StringLengthCStr(const char* str)
{ {
size_t length = 0; size_t length = 0;
if (str) if (str != NULL)
{ {
while (*str) while (*str)
{ {
@@ -84,47 +90,46 @@ inline size_t StringLength(const char* str)
return length; return length;
} }
inline bool IsValid(String str) static inline bool8 IsValidString(String str)
{ {
return str.Size > 0 && str.Str != nullptr && *str.Str; return (str.Size > 0 && str.Str != NULL && *str.Str != '\0');
} }
inline String WrapString(const char* str) static inline String WrapString(const char* str)
{ {
String result = {}; String result = { 0 };
result.Str = const_cast<char*>(str); result.Str = (char*)str;
result.Size = str ? strlen(str) : 0; result.Size = (str != NULL) ? strlen(str) : 0;
return result; return result;
} }
inline String FindChar(String str, char c) static inline String FindChar(String str, char c)
{ {
String result = str; String result = { 0 };
while (result.Size) String cursor = str;
while (cursor.Size > 0)
{ {
if (*result.Str != c) if (*cursor.Str == c)
{ {
++result.Str; result = cursor;
--result.Size; break;
}
else
{
return result;
} }
++cursor.Str;
--cursor.Size;
} }
return {}; return result;
} }
inline bool ContainsChar(String str, char c) static inline bool8 ContainsChar(String str, char c)
{ {
return IsValid(FindChar(str, c)); return IsValidString(FindChar(str, c));
} }
// Return: // Return:
// - < 0 if str1 < str2 // - < 0 if str1 < str2
// - = 0 : Both strings are equals // - = 0 : Both strings are equals
// - > 0 if str1 > str2 // - > 0 if str1 > str2
inline int32 StringCompare(String str1, String str2) static inline int32 StringCompare(String str1, String str2)
{ {
size_t len1 = StringLength(str1); size_t len1 = StringLength(str1);
size_t len2 = StringLength(str2); size_t len2 = StringLength(str2);
@@ -134,62 +139,47 @@ inline int32 StringCompare(String str1, String str2)
{ {
if (len1 > len2) if (len1 > len2)
{ {
return 1; result = 1;
} }
if (len1 < len2) else if (len1 < len2)
{ {
return -1; result = -1;
} }
return 0;
} }
return result; return result;
} }
JULIET_API uint32 StepUTF8(String& inStr); JULIET_API uint32 StepUTF8(String* inStr);
JULIET_API String FindString(String strLeft, String strRight); JULIET_API String FindString(String strLeft, String strRight);
// Case insensitive compare. Supports ASCII only // Case insensitive compare. Supports ASCII only
// TODO: Support UNICODE
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2); extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2);
// Do not allocate anything, you must allocate your out buffer yourself extern JULIET_API bool8 ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer* dst, bool8 nullTerminate);
// TODO: Version taking arena that can allocate extern JULIET_API bool8 ConvertStringByName(String from, String to, String src, StringBuffer* dst, bool8 nullTerminate);
// 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 String StringCopy(Arena* arena, String str);
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str); JULIET_API String16 str16_from_8(Arena* arena, String8 str);
String trim_whitespace(String str); String trim_whitespace(String str);
template <typename... Args> JULIET_API String StringFormatV(Arena* arena, const char* formatStr, va_list args);
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args) JULIET_API String StringFormat(Arena* arena, const char* formatStr, ...);
{
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
#ifdef UNIT_TEST #ifdef UNIT_TEST
namespace UnitTest static inline void UnitTest_TestFindChar(void)
{ {
inline void TestFindChar() String s1 = ConstString("");
{ String s2 = ConstString("abcdefabcdef");
String s1 = ConstString(""); String s3 = ConstString("11111111111111111111");
String s2 = ConstString("abcdefabcdef");
String s3 = ConstString("11111111111111111111");
Assert(FindChar(s1, 'x').Str == nullptr); Assert(FindChar(s1, 'x').Str == NULL);
Assert(FindChar(s2, 'y').Str == nullptr); Assert(FindChar(s2, 'y').Str == NULL);
Assert(FindChar(s2, 'a').Str - s2.Str == 0); Assert(FindChar(s2, 'a').Str - s2.Str == 0);
Assert(FindChar(s2, 'd').Str - s2.Str == 3); Assert(FindChar(s2, 'd').Str - s2.Str == 3);
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 UnitTest
#endif #endif
+70 -93
View File
@@ -2,125 +2,102 @@
#include <Juliet.h> #include <Juliet.h>
#include <Core/Common/CRC32.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/IO/IOStream.h> #include <Core/HAL/IO/IOStream.h>
#include <Core/Math/Vector.h>
// .jasset typedef struct IOStream IOStream;
// AssetFile ::= { CommentLine | EmptyLine | PropertyDeclaration } ; typedef struct Arena Arena;
// CommentLine ::= ( "#" | "//" ) { Character } LineEnding ; typedef struct ArchivePropertyNode ArchivePropertyNode;
// EmptyLine ::= { Whitespace } LineEnding ; typedef struct ParsedArchive ParsedArchive;
// PropertyDeclaration ::= KeyHeader LineEnding ValueBlock ; typedef struct Archive Archive;
// KeyHeader ::= ";" { Whitespace } Identifier ;
// ValueBlock ::= { ValueLine LineEnding } ;
// ValueLine ::= { Whitespace } ValueString { Whitespace } ;
// LineEnding ::= "\r\n" | "\n" ;
// Identifier ::= [a-zA-Z_][a-zA-Z0-9_]* ;
struct Vector4;
struct IOStream;
struct Arena;
struct ArchivePropertyNode struct ArchivePropertyNode
{ {
String key; String key;
String value; String value;
uint32 key_crc; uint32 key_crc;
bool consumed; bool8 consumed;
}; };
struct ParsedArchive struct ParsedArchive
{ {
ArchivePropertyNode* nodes = nullptr; ArchivePropertyNode* nodes;
uint32 property_count = 0; uint32 property_count;
}; };
struct Archive struct Archive
{ {
Arena* arena; Arena* arena;
bool loading; bool8 loading;
ParsedArchive base = {}; ParsedArchive base;
IOStream* stream = nullptr; IOStream* stream;
// to remove void* base_ptr;
void* base_ptr = nullptr; index_t offset;
index_t offset = 0;
}; };
JULIET_API void serialize(Archive& ar, void* data, size_t size); JULIET_API void serialize_bytes(Archive* ar, void* data, size_t size);
#define serialize_elem(ar, val) serialize((ar), &(val), sizeof(val)) #define serialize_elem(ar, val) serialize_bytes((ar), &(val), sizeof(val))
JULIET_API ParsedArchive tokenize_archive(NonNullPtr<Arena> arena, ByteBuffer file_buffer); JULIET_API ParsedArchive tokenize_archive(Arena* arena, ByteBuffer file_buffer);
JULIET_API ArchivePropertyNode* find_property(NonNullPtr<ParsedArchive> archive, uint32 property_crc); JULIET_API ArchivePropertyNode* find_property(ParsedArchive* archive, uint32 property_crc);
JULIET_API void write_property_header(Archive& archive, String property_name); JULIET_API void write_property_header(Archive* archive, String property_name);
JULIET_API bool read_prop(Archive& ar, String value_raw, String& value); JULIET_API bool8 read_prop_str(Archive* ar, String value_raw, String* value);
JULIET_API void write(NonNullPtr<IOStream> stream, String value); JULIET_API void write_str(IOStream* stream, String value);
JULIET_API bool read(const char* buffer, float& value, const char** end = nullptr); JULIET_API bool8 read_f32(const char* buffer, float* value, const char** end);
JULIET_API void write(NonNullPtr<IOStream> stream, float value); JULIET_API void write_f32(IOStream* stream, float value);
JULIET_API bool read(const char* buffer, int8& value); JULIET_API bool8 read_i8(const char* buffer, int8* value);
JULIET_API void write(NonNullPtr<IOStream> stream, int8 value); JULIET_API void write_i8(IOStream* stream, int8 value);
JULIET_API bool read(const char* buffer, int16& value); JULIET_API bool8 read_i16(const char* buffer, int16* value);
JULIET_API void write(NonNullPtr<IOStream> stream, int16 value); JULIET_API void write_i16(IOStream* stream, int16 value);
JULIET_API bool read(const char* buffer, int32& value); JULIET_API bool8 read_i32(const char* buffer, int32* value);
JULIET_API void write(NonNullPtr<IOStream> stream, int32 value); JULIET_API void write_i32(IOStream* stream, int32 value);
JULIET_API bool read(const char* buffer, int64& value); JULIET_API bool8 read_i64(const char* buffer, int64* value);
JULIET_API void write(NonNullPtr<IOStream> stream, int64 value); JULIET_API void write_i64(IOStream* stream, int64 value);
JULIET_API bool read(const char* buffer, uint8& value); JULIET_API bool8 read_u8(const char* buffer, uint8* value);
JULIET_API void write(NonNullPtr<IOStream> stream, uint8 value); JULIET_API void write_u8(IOStream* stream, uint8 value);
JULIET_API bool read(const char* buffer, uint16& value); JULIET_API bool8 read_u16(const char* buffer, uint16* value);
JULIET_API void write(NonNullPtr<IOStream> stream, uint16 value); JULIET_API void write_u16(IOStream* stream, uint16 value);
JULIET_API bool read(const char* buffer, uint32& value); JULIET_API bool8 read_u32(const char* buffer, uint32* value);
JULIET_API void write(NonNullPtr<IOStream> stream, uint32 value); JULIET_API void write_u32(IOStream* stream, uint32 value);
JULIET_API bool read(const char* buffer, uint64& value); JULIET_API bool8 read_u64(const char* buffer, uint64* value);
JULIET_API void write(NonNullPtr<IOStream> stream, uint64 value); JULIET_API void write_u64(IOStream* stream, uint64 value);
JULIET_API bool read(const char* buffer, bool& value); JULIET_API bool8 read_b8(const char* buffer, bool8* value);
JULIET_API void write(NonNullPtr<IOStream> stream, bool value); JULIET_API void write_b8(IOStream* stream, bool8 value);
JULIET_API bool read(const char* buffer, Vector4& value); JULIET_API bool8 read_vec4(const char* buffer, Vector4* value);
JULIET_API void write(NonNullPtr<IOStream> stream, Vector4 value); JULIET_API void write_vec4(IOStream* stream, Vector4 value);
// For primitives not needing archive nor allocation JULIET_API bool8 serialize_str(Archive* ar, String property_name, String* value);
template <typename Type> JULIET_API bool8 serialize_f32(Archive* ar, String property_name, float* value);
bool read_prop(Archive& /*ar*/, String value_raw, Type& value) JULIET_API bool8 serialize_i8(Archive* ar, String property_name, int8* value);
{ JULIET_API bool8 serialize_i16(Archive* ar, String property_name, int16* value);
char buffer[64]; JULIET_API bool8 serialize_i32(Archive* ar, String property_name, int32* value);
size_t cpy_size = Min(value_raw.Size, sizeof(buffer) - 1); JULIET_API bool8 serialize_i64(Archive* ar, String property_name, int64* value);
MemCopy(buffer, value_raw.Str, cpy_size); JULIET_API bool8 serialize_u8(Archive* ar, String property_name, uint8* value);
buffer[cpy_size] = '\0'; JULIET_API bool8 serialize_u16(Archive* ar, String property_name, uint16* value);
JULIET_API bool8 serialize_u32(Archive* ar, String property_name, uint32* value);
JULIET_API bool8 serialize_u64(Archive* ar, String property_name, uint64* value);
JULIET_API bool8 serialize_b8(Archive* ar, String property_name, bool8* value);
JULIET_API bool8 serialize_vec4(Archive* ar, String property_name, Vector4* value);
return read(buffer, value); #define SERIALIZE_STR(ar, name, var_ptr) serialize_str((ar), ConstString(#name), (var_ptr))
} #define SERIALIZE_F32(ar, name, var_ptr) serialize_f32((ar), ConstString(#name), (var_ptr))
#define SERIALIZE_I8(ar, name, var_ptr) serialize_i8((ar), ConstString(#name), (var_ptr))
#define SERIALIZE(ar, name, var) serialize((ar), ConstString(#name), #name##_crc32, (var)) #define SERIALIZE_I16(ar, name, var_ptr) serialize_i16((ar), ConstString(#name), (var_ptr))
#define SERIALIZE_SIMPLE(ar, var) SERIALIZE(ar, var, var) #define SERIALIZE_I32(ar, name, var_ptr) serialize_i32((ar), ConstString(#name), (var_ptr))
#define SERIALIZE_I64(ar, name, var_ptr) serialize_i64((ar), ConstString(#name), (var_ptr))
template <typename Type> #define SERIALIZE_U8(ar, name, var_ptr) serialize_u8((ar), ConstString(#name), (var_ptr))
bool serialize(Archive& ar, String property_name, uint32 property_crc, Type& value) #define SERIALIZE_U16(ar, name, var_ptr) serialize_u16((ar), ConstString(#name), (var_ptr))
{ #define SERIALIZE_U32(ar, name, var_ptr) serialize_u32((ar), ConstString(#name), (var_ptr))
Assert(IsValid(property_name)); #define SERIALIZE_U64(ar, name, var_ptr) serialize_u64((ar), ConstString(#name), (var_ptr))
#define SERIALIZE_B8(ar, name, var_ptr) serialize_b8((ar), ConstString(#name), (var_ptr))
bool result = false; #define SERIALIZE_BOOL(ar, name, var_ptr) serialize_b8((ar), ConstString(#name), (var_ptr))
if (ar.loading) #define SERIALIZE_VEC4(ar, name, var_ptr) serialize_vec4((ar), ConstString(#name), (var_ptr))
{
if (auto* prop = find_property(&ar.base, property_crc))
{
if (read_prop(ar, prop->value, value))
{
result = true;
}
}
}
else
{
// Save
write_property_header(ar, property_name);
write(ar.stream, value);
result = true;
}
return result;
}
#if JULIET_DEBUG #if JULIET_DEBUG
JULIET_API void audit_unconsumed_properties(NonNullPtr<ParsedArchive> archive, String context_name); JULIET_API void audit_unconsumed_properties(ParsedArchive* archive, String context_name);
#endif #endif
+225 -204
View File
@@ -1,211 +1,232 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/CoreUtils.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
#include <Core/Memory/Utils.h>
template <typename Type, size_t ReserveSize = 16> typedef struct VectorArena VectorArena;
struct VectorArena struct VectorArena
{ {
void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr)) Arena* Arena;
void* DataFirst;
void* DataLast;
void* Data;
union
{ {
Assert(!Arena); size_t Count;
size_t Size;
JULIET_DEBUG_ONLY(Name = name ? name : Name;) };
size_t Capacity;
DataFirst = DataLast = Data = nullptr; size_t ElemSize;
Count = 0; size_t ElemAlign;
Capacity = 0; size_t ReserveSize;
Arena = arena; JULIET_DEBUG_ONLY(const char* Name;)
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)
{
Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
Capacity = newCapacity;
}
else
{
Unimplemented();
}
}
void Resize(size_t newCount)
{
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;
Count = 0;
}
[[nodiscard]] bool IsEmpty() const { return Count == 0; }
// C++ Accessors for loop supports and Index based access
[[nodiscard]] Type& operator[](size_t index) { return DataFirst[index]; }
[[nodiscard]] const Type& operator[](size_t index) const { return DataFirst[index]; }
[[nodiscard]] Type* begin() { return DataFirst; }
[[nodiscard]] Type* end() { return DataFirst + Count; }
[[nodiscard]] const Type* begin() const { return DataFirst; }
[[nodiscard]] const Type* end() const { return DataFirst + Count; }
[[nodiscard]] Type* First() { return DataFirst; }
[[nodiscard]] Type* Front() { return DataFirst; }
[[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; }
Arena* Arena = nullptr;
Type* DataFirst = nullptr;
Type* DataLast = nullptr;
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."); #define kDefaultVectorReserveSize ((size_t)16)
static_assert(std::is_trivially_copyable_v<VectorArena<int>>, #define kVectorArenaDefaultReserveSize ((size_t)16)
"VectorArena must be trivially copyable (no custom destructors/assignment).");
static inline void vector_arena_reserve(VectorArena* vec, size_t new_capacity)
{
Assert(vec != NULL);
Assert(vec->Arena != NULL);
Assert(new_capacity <= vec->ReserveSize && "VectorArena capacity should be <= ReserveSize.");
if (vec->Data == NULL)
{
vec->Data = ArenaPush(vec->Arena, new_capacity * vec->ElemSize, Max(8ull, (uint64)vec->ElemAlign),
true JULIET_DEBUG_PARAM(vec->Name));
vec->Capacity = new_capacity;
}
else
{
Unimplemented();
}
}
static inline void vector_arena_create(VectorArena* vec, Arena* arena, size_t elem_size, size_t elem_align,
size_t reserve_size JULIET_DEBUG_PARAM(const char* name))
{
Assert(vec != NULL);
Assert(arena != NULL);
Assert(vec->Arena == NULL);
Assert(elem_size > 0);
JULIET_DEBUG_ONLY(vec->Name = (name != NULL) ? name : "VectorArena";)
vec->DataFirst = NULL;
vec->DataLast = NULL;
vec->Data = NULL;
vec->Count = 0;
vec->Capacity = 0;
vec->ElemSize = elem_size;
vec->ElemAlign = elem_align;
vec->ReserveSize = (reserve_size > 0) ? reserve_size : 16;
vec->Arena = arena;
vector_arena_reserve(vec, vec->ReserveSize);
}
static inline void vector_arena_destroy(VectorArena* vec)
{
Assert(vec != NULL);
vec->DataFirst = NULL;
vec->DataLast = NULL;
vec->Data = NULL;
vec->Count = 0;
vec->Capacity = 0;
vec->Arena = NULL;
}
static inline void* vector_arena_begin(VectorArena* vec)
{
Assert(vec != NULL);
return vec->DataFirst;
}
static inline const void* vector_arena_begin_const(const VectorArena* vec)
{
Assert(vec != NULL);
return vec->DataFirst;
}
static inline void* vector_arena_end(VectorArena* vec)
{
Assert(vec != NULL);
void* result = NULL;
if (vec->DataFirst != NULL)
{
result = (Byte*)vec->DataFirst + (vec->Count * vec->ElemSize);
}
return result;
}
static inline const void* vector_arena_end_const(const VectorArena* vec)
{
Assert(vec != NULL);
const void* result = NULL;
if (vec->DataFirst != NULL)
{
result = (const Byte*)vec->DataFirst + (vec->Count * vec->ElemSize);
}
return result;
}
static inline void vector_arena_resize(VectorArena* vec, size_t new_size)
{
Assert(vec != NULL);
Assert(new_size <= vec->Capacity);
vec->Count = new_size;
if (vec->Count > 0)
{
vec->DataFirst = vec->Data;
vec->DataLast = (Byte*)vec->Data + ((vec->Count - 1) * vec->ElemSize);
}
else
{
vec->DataFirst = NULL;
vec->DataLast = NULL;
}
}
static inline void vector_arena_push_buffer(VectorArena* vec, const void* buffer, size_t amount)
{
Assert(vec != NULL);
Assert(buffer != NULL);
Assert(amount > 0);
Assert(vec->Count + amount <= vec->Capacity && "VectorArena capacity exceeded!");
Byte* dest = (Byte*)vec->Data + (vec->Count * vec->ElemSize);
MemCopy(dest, buffer, amount * vec->ElemSize);
if (vec->DataFirst == NULL)
{
vec->DataFirst = vec->Data;
}
vec->Count += amount;
vec->DataLast = (Byte*)vec->Data + ((vec->Count - 1) * vec->ElemSize);
}
#define vector_arena_push_array vector_arena_push_buffer
static inline void vector_arena_push_elem(VectorArena* vec, const void* value_ptr)
{
Assert(vec != NULL);
Assert(value_ptr != NULL);
Assert(vec->Count + 1 <= vec->Capacity && "VectorArena capacity exceeded!");
Byte* dest = (Byte*)vec->Data + (vec->Count * vec->ElemSize);
MemCopy(dest, value_ptr, vec->ElemSize);
if (vec->DataFirst == NULL)
{
vec->DataFirst = vec->Data;
}
vec->Count += 1;
vec->DataLast = dest;
}
static inline void vector_arena_remove_at_fast(VectorArena* vec, index_t index)
{
Assert(vec != NULL);
Assert(index < vec->Count);
size_t last_idx = vec->Count - 1;
if (index != last_idx)
{
Byte* dst = (Byte*)vec->DataFirst + (index * vec->ElemSize);
Byte* src = (Byte*)vec->DataFirst + (last_idx * vec->ElemSize);
MemCopy(dst, src, vec->ElemSize);
}
vec->Count -= 1;
if (vec->Count == 0)
{
vec->DataFirst = NULL;
vec->DataLast = NULL;
}
else
{
vec->DataLast = (Byte*)vec->DataFirst + ((vec->Count - 1) * vec->ElemSize);
}
}
static inline void vector_arena_clear(VectorArena* vec)
{
Assert(vec != NULL);
vec->DataFirst = NULL;
vec->DataLast = NULL;
vec->Count = 0;
}
static inline bool8 vector_arena_is_empty(const VectorArena* vec)
{
Assert(vec != NULL);
return vec->Count == 0;
}
static inline size_t vector_arena_size(const VectorArena* vec)
{
Assert(vec != NULL);
return vec->Count;
}
#define VectorArenaCreate(vec, Type, arena, ...) \
vector_arena_create((vec), (arena), sizeof(Type), AlignOf(Type), __VA_ARGS__)
#define VectorArenaAt(Type, vec, idx) (((Type*)((vec)->DataFirst))[idx])
#define VectorArenaData(Type, vec) ((Type*)((vec)->Data))
#define VectorArenaBegin(Type, vec) ((Type*)((vec)->DataFirst))
#define VectorArenaEnd(Type, vec) (((vec)->DataFirst != NULL) ? (((Type*)((vec)->DataFirst)) + (vec)->Count) : NULL)
#define VectorArenaLast(Type, vec) ((Type*)((vec)->DataLast))
#define VectorArenaBack(Type, vec) ((Type*)((vec)->DataLast))
#define VectorArenaPushPtr(Type, vec, ptr) vector_arena_push_elem((vec), (ptr))
#define VectorArenaPushVal(Type, vec, val) \
do \
{ \
Type _vec_tmp_val = (val); \
vector_arena_push_elem((vec), &_vec_tmp_val); \
} \
while (0)
+10 -10
View File
@@ -1,16 +1,16 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
struct Window; typedef struct Window Window;
using WindowID = uint8; typedef uint8 WindowID;
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 ShowWindow(NonNullPtr<Window> window); extern JULIET_API Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int flags);
extern JULIET_API void HideWindow(NonNullPtr<Window> window); extern JULIET_API void DestroyPlatformWindow(Window* window);
extern JULIET_API WindowID GetWindowID(NonNullPtr<Window> window); extern JULIET_API void ShowPlatformWindow(Window* window);
extern JULIET_API void SetWindowTitle(NonNullPtr<Window> window, String title); extern JULIET_API void HidePlatformWindow(Window* window);
extern JULIET_API WindowID GetWindowID(Window* window);
extern JULIET_API void SetWindowTitle(Window* window, String title);
@@ -1,9 +1,10 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h>
struct DynamicLibrary; typedef struct DynamicLibrary 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(DynamicLibrary* lib, const char* functionName);
extern JULIET_API void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib); extern JULIET_API void UnloadDynamicLibrary(DynamicLibrary* lib);
+38 -51
View File
@@ -1,53 +1,57 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h>
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/HAL/Keyboard/Keyboard.h> #include <Core/HAL/Keyboard/Keyboard.h>
#include <Core/HAL/Keyboard/KeyCode.h> #include <Core/HAL/Keyboard/KeyCode.h>
#include <Core/HAL/Mouse/Mouse.h> #include <Core/HAL/Mouse/Mouse.h>
#include <Juliet.h> #include <Juliet.h>
// Handles all events from systems handling the Hardware typedef uint32 EventType;
// Very inspired by SDL3 enum
enum class EventType : uint32
{ {
None = 0, EventType_None = 0,
First = None, EventType_First = EventType_None,
// Application Events // Application Events
// User querying an exit EventType_Application_Exit = 100,
Application_Exit = 100, EventType_Application_OS_Terminate = 101,
// OS terminating the application EventType_Application_Begin = EventType_Application_Exit,
Application_OS_Terminate, EventType_Application_End = EventType_Application_OS_Terminate,
Application_Begin = Application_Exit,
Application_End = Application_OS_Terminate,
// Window Events // Window Events
Window_Close_Request = 200, EventType_Window_Close_Request = 200,
Window_Begin = Window_Close_Request, EventType_Window_Begin = EventType_Window_Close_Request,
Window_End = Window_Close_Request, EventType_Window_End = EventType_Window_Close_Request,
// Keyboard Event // Keyboard Event
Key_Down = 300, EventType_Key_Down = 300,
Key_Up, EventType_Key_Up = 301,
Keyboard_Begin = Key_Down, EventType_Keyboard_Begin = EventType_Key_Down,
Keyboard_End = Key_Up, EventType_Keyboard_End = EventType_Key_Up,
// Mouse Event // Mouse Event
Mouse_Move = 400, EventType_Mouse_Move = 400,
Mouse_ButtonPressed, EventType_Mouse_ButtonPressed = 401,
Mouse_ButtonReleased, EventType_Mouse_ButtonReleased = 402,
Mouse_Begin = Mouse_Move, EventType_Mouse_Begin = EventType_Mouse_Move,
Mouse_End = Mouse_ButtonReleased, EventType_Mouse_End = EventType_Mouse_ButtonReleased,
Last // Get value from the previous one EventType_Last
}; };
typedef struct WindowEvent WindowEvent;
typedef struct KeyboardEvent KeyboardEvent;
typedef struct MouseMovementEvent MouseMovementEvent;
typedef struct MouseButtonEvent MouseButtonEvent;
typedef union AllSystemEventUnion AllSystemEventUnion;
typedef struct SystemEvent SystemEvent;
struct WindowEvent struct WindowEvent
{ {
WindowID AssociatedWindowID; WindowID AssociatedWindowID;
uint32 DataPadding[2]; // TODO : define how much data param we need uint32 DataPadding[2];
}; };
struct KeyboardEvent struct KeyboardEvent
@@ -59,9 +63,6 @@ struct KeyboardEvent
KeyMod KeyModeState; KeyMod KeyModeState;
}; };
// =====================================================
// Mouse Events
// =====================================================
struct MouseMovementEvent struct MouseMovementEvent
{ {
MouseID AssociatedMouseID; MouseID AssociatedMouseID;
@@ -80,20 +81,18 @@ struct MouseButtonEvent
float X; float X;
float Y; float Y;
MouseButton ButtonState; MouseButton ButtonState;
bool IsPressed : 1; bool8 IsPressed;
}; };
// 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 we do not bust the union size StaticAssert(sizeof(AllSystemEventUnion) == 128, SystemEventUnionSizeCheck);
static_assert(sizeof(AllSystemEventUnion) == sizeof(((AllSystemEventUnion*)nullptr)->Padding));
struct SystemEvent struct SystemEvent
{ {
@@ -102,19 +101,7 @@ struct SystemEvent
AllSystemEventUnion Data; AllSystemEventUnion Data;
}; };
// Poll for any event, return false if no event is available. extern JULIET_API bool8 GetEvent(SystemEvent* event);
// Equivalent to WaitEvent(event, 0); extern JULIET_API bool8 WaitEvent(SystemEvent* event, int32 timeoutInNS);
// Will not block extern JULIET_API bool8 AddEvent(SystemEvent* event);
extern JULIET_API bool GetEvent(SystemEvent& event); extern void Events_NewFrame(float deltaTime);
// TODO : use chrono to tag the timeout correctly with nanosec
// timeout == -1 means wait for any event before pursuing
// timeout == 0 means checking once for the frame and getting out
// timeout > 0 means wait until time is out
extern JULIET_API bool WaitEvent(SystemEvent& event, int32 timeoutInNS = -1);
// Add an event onto the event queue.
// TODO : support array of events
extern JULIET_API bool AddEvent(SystemEvent& event);
extern void Events_NewFrame(float deltaTime);
+31 -10
View File
@@ -1,23 +1,44 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
enum class AssetType typedef uint32 AssetType;
enum
{ {
JAsset, AssetType_JAsset = 0,
Shader, AssetType_Shader = 1,
Config, AssetType_Config = 2,
}; };
typedef struct Path Path;
struct Path
{
String Directories;
String FullPath;
};
JULIET_API bool8 IsValidPath(Path path);
// Returns the path to the application directory // Returns the path to the application directory
JULIET_API String GetBasePath(); JULIET_API Path GetBasePath(void);
// Path to the /Assets/ folder // Path to the /Assets/ folder
JULIET_API String GetAssetBasePath(); JULIET_API Path GetAssetBasePath(void);
// 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").
JULIET_API String GetAssetPath(NonNullPtr<Arena> arena, AssetType type, String filename); JULIET_API Path GetAssetPath(Arena* arena, AssetType type, String filename);
JULIET_API bool IsAbsolutePath(String path); JULIET_API bool8 IsAbsolutePath(String path);
JULIET_API String CleanPath(NonNullPtr<Arena> arena, String path); JULIET_API Path fs_create_clean_path(Arena* arena, String path);
JULIET_API bool8 fs_create_directory(String path, bool8 recursive);
JULIET_API bool8 fs_path_exists(String path);
JULIET_API bool8 fs_move_file(Path old_path, Path new_path);
JULIET_API bool8 fs_delete_file(String path);
typedef void (*fs_iterate_director_callback)(Path path, bool8 is_director, void* user_payload);
JULIET_API void fs_iterate_directory(Path directory_path, String extension, void* user_payload, fs_iterate_director_callback callback);
+39 -36
View File
@@ -1,66 +1,69 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Juliet.h> #include <Juliet.h>
// Opaque type // Opaque type
struct IOStream; typedef struct IOStream IOStream;
typedef struct IOStreamDataPayload IOStreamDataPayload;
struct IOStreamDataPayload struct IOStreamDataPayload
{ {
uint8 unused;
}; };
enum class IOStreamStatus : uint8 typedef uint8 IOStreamStatus;
enum
{ {
Ready, IOStreamStatus_Ready = 0,
Error, IOStreamStatus_Error,
EndOfFile, IOStreamStatus_EndOfFile,
NotReady, IOStreamStatus_NotReady,
ReadOnly, IOStreamStatus_ReadOnly,
WriteOnly IOStreamStatus_WriteOnly
}; };
enum class IOStreamSeekPivot : uint8 typedef uint8 IOStreamSeekPivot;
enum
{ {
Begin, IOStreamSeekPivot_Begin = 0,
Current, IOStreamSeekPivot_Current,
End, IOStreamSeekPivot_End,
Count IOStreamSeekPivot_Count
}; };
// IOStream can be opened on a file or memory, or anything else. typedef struct IOStreamInterface IOStreamInterface;
// Use the interface to make it transparent to the user.
struct IOStreamInterface struct IOStreamInterface
{ {
uint32 Version; uint32 Version;
int64 (*Size)(NonNullPtr<IOStreamDataPayload> data); int64 (*Size)(IOStreamDataPayload* data);
int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot); int64 (*Seek)(IOStreamDataPayload* data, int64 offset, IOStreamSeekPivot pivot);
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status); size_t (*Read)(IOStreamDataPayload* data, void* outBuffer, size_t size, IOStreamStatus* status);
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status); size_t (*Write)(IOStreamDataPayload* data, ByteBuffer inBuffer, IOStreamStatus* status);
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status); bool8 (*Flush)(IOStreamDataPayload* data, IOStreamStatus* status);
bool (*Close)(NonNullPtr<IOStreamDataPayload> data); bool8 (*Close)(IOStreamDataPayload* data);
}; };
extern JULIET_API IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode); extern JULIET_API IOStream* IOFromFile(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(Arena* arena, const IOStreamInterface* streamInterface,
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface, IOStreamDataPayload* payload);
NonNullPtr<IOStreamDataPayload> payload);
// Write formatted string into the stream. JULIET_API size_t IOPrintf(IOStream* stream, const char* format, ...);
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...); JULIET_API size_t IOWrite(IOStream* stream, ByteBuffer inBuffer);
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); JULIET_API size_t IORead(IOStream* stream, void* ptr, size_t size);
extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot); JULIET_API int64 IOSeek(IOStream* stream, int64 offset, IOStreamSeekPivot pivot);
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream); JULIET_API int64 IOSize(IOStream* stream);
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename); JULIET_API ByteBuffer LoadFile(Arena* arena, String filename);
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone); JULIET_API ByteBuffer LoadFileFromStream(Arena* arena, IOStream* stream, bool8 closeStreamWhenDone);
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream); JULIET_API size_t IO_atomic_file_write(Path filepath, ByteBuffer file_content);
JULIET_API bool8 IOClose(IOStream* stream);
+176 -181
View File
@@ -1,188 +1,183 @@
#pragma once #pragma once
// Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout #include <Core/Common/CoreTypes.h>
// ScanCode reprensent US ASCII Keyboard
// WASD Scan codes are ZQSD in KeyCode for French keyboard typedef uint32 KeyCode;
// We use the ASCII value of the generated character as value, when possible. enum
// 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
{ {
Unknown = 0x0, // 0 KeyCode_Unknown = 0x0u,
Unsupported = 0x0, // 0 KeyCode_Unsupported = 0x0u,
Return = 0X0Du, // '\r' KeyCode_Return = 0x0Du,
Escape = 0X1Bu, // '\X1B' KeyCode_Escape = 0x1Bu,
Backspace = 0X08u, // '\b' KeyCode_Backspace = 0x08u,
Tab = 0X09u, // '\t' KeyCode_Tab = 0x09u,
Space = 0X20u, // ' ' KeyCode_Space = 0x20u,
ExclamationPoint = 0X21u, // '!' KeyCode_ExclamationPoint = 0x21u,
DoubleApostrophe = 0X22u, // '"' KeyCode_DoubleApostrophe = 0x22u,
Hash = 0X23u, // '#' KeyCode_Hash = 0x23u,
Dollar = 0X24u, // '$' KeyCode_Dollar = 0x24u,
Percent = 0X25u, // '%' KeyCode_Percent = 0x25u,
Ampersand = 0X26u, // '&' KeyCode_Ampersand = 0x26u,
Apostrophe = 0X27u, // '\'' KeyCode_Apostrophe = 0x27u,
LeftParenthesis = 0X28u, // '(' KeyCode_LeftParenthesis = 0x28u,
RightParenthesis = 0X29u, // ')' KeyCode_RightParenthesis = 0x29u,
Asterisk = 0X2Au, // '*' KeyCode_Asterisk = 0x2Au,
Plus = 0X2Bu, // '+' KeyCode_Plus = 0x2Bu,
Comma = 0X2Cu, // ',' KeyCode_Comma = 0x2Cu,
Minus = 0X2Du, // '-' KeyCode_Minus = 0x2Du,
Period = 0X2Eu, // '.' KeyCode_Period = 0x2Eu,
Slash = 0X2Fu, // '/' KeyCode_Slash = 0x2Fu,
Num0 = 0X30u, // '0' KeyCode_Num0 = 0x30u,
Num1 = 0X31u, // '1' KeyCode_Num1 = 0x31u,
Num2 = 0X32u, // '2' KeyCode_Num2 = 0x32u,
Num3 = 0X33u, // '3' KeyCode_Num3 = 0x33u,
Num4 = 0X34u, // '4' KeyCode_Num4 = 0x34u,
Num5 = 0X35u, // '5' KeyCode_Num5 = 0x35u,
Num6 = 0X36u, // '6' KeyCode_Num6 = 0x36u,
Num7 = 0X37u, // '7' KeyCode_Num7 = 0x37u,
Num8 = 0X38u, // '8' KeyCode_Num8 = 0x38u,
Num9 = 0X39u, // '9' KeyCode_Num9 = 0x39u,
Colon = 0X3Au, // ':' KeyCode_Colon = 0x3Au,
Semicolon = 0X3Bu, // ';' KeyCode_Semicolon = 0x3Bu,
LessThan = 0X3Cu, // '<' KeyCode_LessThan = 0x3Cu,
Equals = 0X3Du, // '=' KeyCode_Equals = 0x3Du,
GreaterThan = 0X3Eu, // '>' KeyCode_GreaterThan = 0x3Eu,
QuestionMark = 0X3Fu, // '?' KeyCode_QuestionMark = 0x3Fu,
CommercialAt = 0x40u, // '@' KeyCode_CommercialAt = 0x40u,
LeftBracket = 0X5Bu, // '[' KeyCode_LeftBracket = 0x5Bu,
Backslash = 0X5Cu, // '\\' KeyCode_Backslash = 0x5Cu,
RightBracket = 0X5DU, // ']' KeyCode_RightBracket = 0x5Du,
Caret = 0X5Eu, // '^' KeyCode_Caret = 0x5Eu,
Underscore = 0X5Fu, // '_' KeyCode_Underscore = 0x5Fu,
GraveAccent = 0X60u, // '`' KeyCode_GraveAccent = 0x60u,
A = 0x61u, // 'a' KeyCode_A = 0x61u,
B = 0x62u, // 'b' KeyCode_B = 0x62u,
C = 0x63u, // 'c' KeyCode_C = 0x63u,
D = 0x64u, // 'd' KeyCode_D = 0x64u,
E = 0x65u, // 'e' KeyCode_E = 0x65u,
F = 0x66u, // 'f' KeyCode_F = 0x66u,
G = 0x67u, // 'g' KeyCode_G = 0x67u,
H = 0x68u, // 'h' KeyCode_H = 0x68u,
I = 0x69u, // 'i' KeyCode_I = 0x69u,
J = 0x6Au, // 'j' KeyCode_J = 0x6Au,
K = 0x6Bu, // 'k' KeyCode_K = 0x6Bu,
L = 0x6CU, // 'l' KeyCode_L = 0x6Cu,
M = 0x6DU, // 'm' KeyCode_M = 0x6Du,
N = 0x6Eu, // 'n' KeyCode_N = 0x6Eu,
O = 0x6Fu, // 'o' KeyCode_O = 0x6Fu,
P = 0x70u, // 'p' KeyCode_P = 0x70u,
Q = 0x71u, // 'q' KeyCode_Q = 0x71u,
R = 0x72u, // 'r' KeyCode_R = 0x72u,
S = 0x73u, // 's' KeyCode_S = 0x73u,
T = 0x74u, // 't' KeyCode_T = 0x74u,
U = 0x75u, // 'y' KeyCode_U = 0x75u,
V = 0x76u, // 'v' KeyCode_V = 0x76u,
W = 0x77u, // 'w' KeyCode_W = 0x77u,
X = 0x78u, // 'x' KeyCode_X = 0x78u,
Y = 0x79u, // 'y' KeyCode_Y = 0x79u,
Z = 0x7Au, // 'z' KeyCode_Z = 0x7Au,
LeftBrace = 0x7BU, // '{' KeyCode_LeftBrace = 0x7Bu,
Pipe = 0x7CU, // '|' KeyCode_Pipe = 0x7Cu,
RightBrace = 0x7DU, // '}' KeyCode_RightBrace = 0x7Du,
Tilde = 0x7Eu, // '~' KeyCode_Tilde = 0x7Eu,
Delete = 0x7Fu, // '\x7F' KeyCode_Delete = 0x7Fu,
PlusMinus = 0xb1u, // '\xB1' KeyCode_PlusMinus = 0xb1u,
// Keys not producing a character KeyCode_CapsLock = 0x40000039u,
// Based on SDL Algo: ScanCode | 0x40000000 KeyCode_F1 = 0x4000003Au,
CapsLock = 0x40000039u, KeyCode_F2 = 0x4000003Bu,
F1 = 0x4000003Au, KeyCode_F3 = 0x4000003Cu,
F2 = 0x4000003Bu, KeyCode_F4 = 0x4000003Du,
F3 = 0x4000003CU, KeyCode_F5 = 0x4000003Eu,
F4 = 0x4000003DU, KeyCode_F6 = 0x4000003Fu,
F5 = 0x4000003Eu, KeyCode_F7 = 0x40000040u,
F6 = 0x4000003Fu, KeyCode_F8 = 0x40000041u,
F7 = 0x40000040u, KeyCode_F9 = 0x40000042u,
F8 = 0x40000041u, KeyCode_F10 = 0x40000043u,
F9 = 0x40000042u, KeyCode_F11 = 0x40000044u,
F10 = 0x40000043u, KeyCode_F12 = 0x40000045u,
F11 = 0x40000044u, KeyCode_PrintScreen = 0x40000046u,
F12 = 0x40000045u, KeyCode_ScrollLock = 0x40000047u,
PrintScreen = 0x40000046u, KeyCode_Pause = 0x40000048u,
ScrollLock = 0x40000047u, KeyCode_Insert = 0x40000049u,
Pause = 0x40000048u, KeyCode_Home = 0x4000004Au,
Insert = 0x40000049u, KeyCode_PageUp = 0x4000004Bu,
Home = 0x4000004Au, KeyCode_End = 0x4000004Du,
PageUp = 0x4000004Bu, KeyCode_PageDown = 0x4000004Eu,
End = 0x4000004DU, KeyCode_RightArrow = 0x4000004Fu,
PageDown = 0x4000004Eu, KeyCode_LeftArrow = 0x40000050u,
RightArrow = 0x4000004Fu, KeyCode_DownArrow = 0x40000051u,
LeftArrow = 0x40000050u, KeyCode_UpArrow = 0x40000052u,
DownArrow = 0x40000051u, KeyCode_NumlockClear = 0x40000053u,
UpArrow = 0x40000052u, KeyCode_KeyPad_Divide = 0x40000054u,
NumlockClear = 0x40000053u, KeyCode_KeyPad_Multiply = 0x40000055u,
KeyPad_Divide = 0x40000054u, KeyCode_KeyPad_Minus = 0x40000056u,
KeyPad_Multiply = 0x40000055u, KeyCode_KeyPad_Plus = 0x40000057u,
KeyPad_Minus = 0x40000056u, KeyCode_KeyPad_Enter = 0x40000058u,
KeyPad_Plus = 0x40000057u, KeyCode_KeyPad_Num1 = 0x40000059u,
KeyPad_Enter = 0x40000058u, KeyCode_KeyPad_Num2 = 0x4000005Au,
KeyPad_Num1 = 0x40000059u, KeyCode_KeyPad_Num3 = 0x4000005Bu,
KeyPad_Num2 = 0x4000005Au, KeyCode_KeyPad_Num4 = 0x4000005Cu,
KeyPad_Num3 = 0x4000005Bu, KeyCode_KeyPad_Num5 = 0x4000005Du,
KeyPad_Num4 = 0x4000005Cu, KeyCode_KeyPad_Num6 = 0x4000005Eu,
KeyPad_Num5 = 0x4000005Du, KeyCode_KeyPad_Num7 = 0x4000005Fu,
KeyPad_Num6 = 0x4000005Eu, KeyCode_KeyPad_Num8 = 0x40000060u,
KeyPad_Num7 = 0x4000005Fu, KeyCode_KeyPad_Num9 = 0x40000061u,
KeyPad_Num8 = 0x40000060u, KeyCode_KeyPad_Num0 = 0x40000062u,
KeyPad_Num9 = 0x40000061u, KeyCode_KeyPad_Period = 0x40000063u,
KeyPad_Num0 = 0x40000062u, KeyCode_Power = 0x40000066u,
KeyPad_Period = 0x40000063u, KeyCode_KeyPad_Equals = 0x40000067u,
Power = 0x40000066u, KeyCode_F13 = 0x40000068u,
KeyPad_Equals = 0x40000067u, KeyCode_F14 = 0x40000069u,
F13 = 0x40000068u, KeyCode_F15 = 0x4000006Au,
F14 = 0x40000069u, KeyCode_F16 = 0x4000006Bu,
F15 = 0x4000006Au, KeyCode_F17 = 0x4000006Cu,
F16 = 0x4000006Bu, KeyCode_F18 = 0x4000006Du,
F17 = 0x4000006Cu, KeyCode_F19 = 0x4000006Eu,
F18 = 0x4000006Du, KeyCode_F20 = 0x4000006Fu,
F19 = 0x4000006Eu, KeyCode_F21 = 0x40000070u,
F20 = 0x4000006Fu, KeyCode_F22 = 0x40000071u,
F21 = 0x40000070u, KeyCode_F23 = 0x40000072u,
F22 = 0x40000071u, KeyCode_F24 = 0x40000073u,
F23 = 0x40000072u, KeyCode_Mute = 0x4000007Fu,
F24 = 0x40000073u, KeyCode_VolumeUp = 0x40000080u,
Mute = 0x4000007Fu, KeyCode_VolumeDown = 0x40000081u,
VolumeUp = 0x40000080u, KeyCode_KeyPad_Comma = 0x40000085u,
VolumeDown = 0x40000081u, KeyCode_LeftControl = 0x400000E0u,
KeyPad_Comma = 0x40000085u, KeyCode_LeftShift = 0x400000E1u,
LeftControl = 0x400000E0u, KeyCode_LeftAlt = 0x400000E2u,
LeftShift = 0x400000E1u, KeyCode_LeftOSCommand = 0x400000E3u,
LeftAlt = 0x400000E2u, KeyCode_RightControl = 0x400000E4u,
LeftOSCommand = 0x400000E3u, KeyCode_RightShift = 0x400000E5u,
RightControl = 0x400000E4u, KeyCode_RightAlt = 0x400000E6u,
RightShift = 0x400000E5u, KeyCode_RightOSCommand = 0x400000E7u,
RightAlt = 0x400000E6u, KeyCode_Sleep = 0x40000102u,
RightOSCommand = 0x400000E7u, KeyCode_WakeUp = 0x40000103u,
Sleep = 0x40000102u, KeyCode_Media_NextTrack = 0x4000010Bu,
WakeUp = 0x40000103u, KeyCode_Media_PreviousTrack = 0x4000010Cu,
Media_NextTrack = 0x4000010Bu, KeyCode_Media_Stop = 0x4000010Du,
Media_PreviousTrack = 0x4000010Cu, KeyCode_Media_Eject = 0x4000010Eu,
Media_Stop = 0x4000010Du, KeyCode_Media_PlayPause = 0x4000010Fu,
Media_Eject = 0x4000010Eu, KeyCode_Media_Select = 0x40000110u,
Media_PlayPause = 0x4000010Fu,
Media_Select = 0x40000110u,
}; };
enum class KeyMod : uint16 typedef uint16 KeyMod;
enum
{ {
None = 0b0, KeyMod_None = 0x0000u,
LeftShift = 0b0000'0000'0001u, KeyMod_LeftShift = 0x0001u,
RightShift = 0b0000'0000'0010u, KeyMod_RightShift = 0x0002u,
LeftControl = 0b0000'0000'0100u, KeyMod_LeftControl = 0x0004u,
RightControl = 0b0000'0000'1000u, KeyMod_RightControl = 0x0008u,
LeftAlt = 0b0000'0001'000u, KeyMod_LeftAlt = 0x0010u,
RightAlt = 0b0000'0010'0000u, KeyMod_RightAlt = 0x0020u,
LeftOSCommand = 0b0000'0100'0000u, KeyMod_LeftOSCommand = 0x0040u,
RightOSCommand = 0b0000'1000'0000u, KeyMod_RightOSCommand = 0x0080u,
NumLock = 0b0001'0000'0000u, KeyMod_NumLock = 0x0100u,
CapsLock = 0b0010'0000'0000u, KeyMod_CapsLock = 0x0200u,
ScrollLock = 0b0100'0000'0000u, KeyMod_ScrollLock = 0x0400u,
Control = LeftControl | RightControl, KeyMod_Control = KeyMod_LeftControl | KeyMod_RightControl,
Shift = LeftShift | RightShift, KeyMod_Shift = KeyMod_LeftShift | KeyMod_RightShift,
Alt = LeftAlt | RightAlt, KeyMod_Alt = KeyMod_LeftAlt | KeyMod_RightAlt,
OSCommand = LeftOSCommand | RightOSCommand, KeyMod_OSCommand = KeyMod_LeftOSCommand | KeyMod_RightOSCommand,
}; };
+11 -8
View File
@@ -1,23 +1,26 @@
#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>
using KeyboardID = uint8; typedef uint8 KeyboardID;
enum class KeyPosition : bool typedef bool8 KeyPosition;
enum
{ {
Up = false, KeyPosition_Up = false,
Down = true KeyPosition_Down = true
}; };
typedef struct KeyState KeyState;
struct KeyState struct KeyState
{ {
KeyPosition Position; KeyPosition Position;
float Time; float Time;
}; };
typedef struct Key Key;
struct Key struct Key
{ {
ScanCode ScanCode; ScanCode ScanCode;
@@ -25,8 +28,8 @@ struct Key
uint16 Raw; uint16 Raw;
}; };
extern JULIET_API bool IsKeyDown(ScanCode scanCode); extern JULIET_API bool8 IsKeyDown(ScanCode scanCode);
extern JULIET_API bool IsKeyPressed(ScanCode scanCode); extern JULIET_API bool8 IsKeyPressed(ScanCode scanCode);
extern JULIET_API KeyMod GetKeyModState(); extern JULIET_API KeyMod GetKeyModState(void);
extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState); extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
+158 -161
View File
@@ -1,183 +1,180 @@
#pragma once #pragma once
// Follow the HID Usage page for USB #include <Core/Common/CoreTypes.h>
// https://usb.org/sites/default/files/hut1_5.pdf
// 0 to 256 Is dedicated to Keyboard Usage Page (0x07) typedef uint16 ScanCode;
// 257 to 286 Is dedicated to Consumer Usage Page (0xC) enum
// 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, ScanCode_Unknown = 0,
Unsupported = 0, ScanCode_Unsupported = 0,
A = 4, ScanCode_A = 4,
B = 5, ScanCode_B = 5,
C = 6, ScanCode_C = 6,
D = 7, ScanCode_D = 7,
E = 8, ScanCode_E = 8,
F = 9, ScanCode_F = 9,
G = 10, ScanCode_G = 10,
H = 11, ScanCode_H = 11,
I = 12, ScanCode_I = 12,
J = 13, ScanCode_J = 13,
K = 14, ScanCode_K = 14,
L = 15, ScanCode_L = 15,
M = 16, ScanCode_M = 16,
N = 17, ScanCode_N = 17,
O = 18, ScanCode_O = 18,
P = 19, ScanCode_P = 19,
Q = 20, ScanCode_Q = 20,
R = 21, ScanCode_R = 21,
S = 22, ScanCode_S = 22,
T = 23, ScanCode_T = 23,
U = 24, ScanCode_U = 24,
V = 25, ScanCode_V = 25,
W = 26, ScanCode_W = 26,
X = 27, ScanCode_X = 27,
Y = 28, ScanCode_Y = 28,
Z = 29, ScanCode_Z = 29,
Num1 = 30, ScanCode_Num1 = 30,
Num2 = 31, ScanCode_Num2 = 31,
Num3 = 32, ScanCode_Num3 = 32,
Num4 = 33, ScanCode_Num4 = 33,
Num5 = 34, ScanCode_Num5 = 34,
Num6 = 35, ScanCode_Num6 = 35,
Num7 = 36, ScanCode_Num7 = 36,
Num8 = 37, ScanCode_Num8 = 37,
Num9 = 38, ScanCode_Num9 = 38,
Num0 = 39, ScanCode_Num0 = 39,
Return = 40, ScanCode_Return = 40,
Escape = 41, ScanCode_Escape = 41,
Backspace = 42, ScanCode_Backspace = 42,
Tab = 43, ScanCode_Tab = 43,
Space = 44, ScanCode_Space = 44,
Minus = 45, ScanCode_Minus = 45,
Equals = 46, ScanCode_Equals = 46,
LeftBracket = 47, ScanCode_LeftBracket = 47,
RightBracket = 48, ScanCode_RightBracket = 48,
Backslash = 49, ScanCode_Backslash = 49,
NonUSHash = 50, // Same as 49 but for ISO keyboards ScanCode_NonUSHash = 50,
Semicolon = 51, ScanCode_Semicolon = 51,
Apostrophe = 52, ScanCode_Apostrophe = 52,
GraveAccent = 53, ScanCode_GraveAccent = 53,
Comma = 54, ScanCode_Comma = 54,
Period = 55, ScanCode_Period = 55,
Slash = 56, ScanCode_Slash = 56,
CapsLock = 57, ScanCode_CapsLock = 57,
F1 = 58, ScanCode_F1 = 58,
F2 = 59, ScanCode_F2 = 59,
F3 = 60, ScanCode_F3 = 60,
F4 = 61, ScanCode_F4 = 61,
F5 = 62, ScanCode_F5 = 62,
F6 = 63, ScanCode_F6 = 63,
F7 = 64, ScanCode_F7 = 64,
F8 = 65, ScanCode_F8 = 65,
F9 = 66, ScanCode_F9 = 66,
F10 = 67, ScanCode_F10 = 67,
F11 = 68, ScanCode_F11 = 68,
F12 = 69, ScanCode_F12 = 69,
PrintScreen = 70, ScanCode_PrintScreen = 70,
ScrollLock = 71, ScanCode_ScrollLock = 71,
Pause = 72, ScanCode_Pause = 72,
Insert = 73, ScanCode_Insert = 73,
Home = 74, ScanCode_Home = 74,
PageUp = 75, ScanCode_PageUp = 75,
Delete = 76, ScanCode_Delete = 76,
End = 77, ScanCode_End = 77,
PageDown = 78, ScanCode_PageDown = 78,
RightArrow = 79, ScanCode_RightArrow = 79,
LeftArrow = 80, ScanCode_LeftArrow = 80,
DownArrow = 81, ScanCode_DownArrow = 81,
UpArrow = 82, ScanCode_UpArrow = 82,
NumlockClear = 83, // Pc = Numlock / Mac = Clear ScanCode_NumlockClear = 83,
KeyPad_Divide = 84, ScanCode_KeyPad_Divide = 84,
KeyPad_Multiply = 85, ScanCode_KeyPad_Multiply = 85,
KeyPad_Minus = 86, ScanCode_KeyPad_Minus = 86,
KeyPad_Plus = 87, ScanCode_KeyPad_Plus = 87,
KeyPad_Enter = 88, ScanCode_KeyPad_Enter = 88,
KeyPad_Num1 = 89, ScanCode_KeyPad_Num1 = 89,
KeyPad_Num2 = 90, ScanCode_KeyPad_Num2 = 90,
KeyPad_Num3 = 91, ScanCode_KeyPad_Num3 = 91,
KeyPad_Num4 = 92, ScanCode_KeyPad_Num4 = 92,
KeyPad_Num5 = 93, ScanCode_KeyPad_Num5 = 93,
KeyPad_Num6 = 94, ScanCode_KeyPad_Num6 = 94,
KeyPad_Num7 = 95, ScanCode_KeyPad_Num7 = 95,
KeyPad_Num8 = 96, ScanCode_KeyPad_Num8 = 96,
KeyPad_Num9 = 97, ScanCode_KeyPad_Num9 = 97,
KeyPad_Num0 = 98, ScanCode_KeyPad_Num0 = 98,
KeyPad_Period = 99, ScanCode_KeyPad_Period = 99,
NonUSBackslash = 100, // ISO keyboards only ScanCode_NonUSBackslash = 100,
Power = 102, // Some mac have a Power key ScanCode_Power = 102,
KeyPad_Equals = 103, ScanCode_KeyPad_Equals = 103,
F13 = 104, ScanCode_F13 = 104,
F14 = 105, ScanCode_F14 = 105,
F15 = 106, ScanCode_F15 = 106,
F16 = 107, ScanCode_F16 = 107,
F17 = 108, ScanCode_F17 = 108,
F18 = 109, ScanCode_F18 = 109,
F19 = 110, ScanCode_F19 = 110,
F20 = 111, ScanCode_F20 = 111,
F21 = 112, ScanCode_F21 = 112,
F22 = 113, ScanCode_F22 = 113,
F23 = 114, ScanCode_F23 = 114,
F24 = 115, ScanCode_F24 = 115,
Mute = 127, ScanCode_Mute = 127,
VolumeUp = 128, ScanCode_VolumeUp = 128,
VolumeDown = 129, ScanCode_VolumeDown = 129,
KeyPad_Comma = 133, ScanCode_KeyPad_Comma = 133,
International1 = 135, // Mostly used on Asian keyboards ScanCode_International1 = 135,
International2 = 136, ScanCode_International2 = 136,
International3 = 137, // Yen Symbol ScanCode_International3 = 137,
International4 = 138, ScanCode_International4 = 138,
International5 = 139, ScanCode_International5 = 139,
International6 = 140, ScanCode_International6 = 140,
International7 = 141, ScanCode_International7 = 141,
International8 = 142, ScanCode_International8 = 142,
International9 = 143, ScanCode_International9 = 143,
Lang1 = 144, // Hangul (Korean) ScanCode_Lang1 = 144,
Lang2 = 145, // Hanja (Korean) ScanCode_Lang2 = 145,
Lang3 = 146, // Katakana (Japanese) ScanCode_Lang3 = 146,
Lang4 = 147, // Hiragana (Japanese) ScanCode_Lang4 = 147,
Lang5 = 148, // Zenkaku/Hankaku (Japanese) ScanCode_Lang5 = 148,
Lang6 = 149, // Unused ScanCode_Lang6 = 149,
Lang7 = 150, // Unused ScanCode_Lang7 = 150,
Lang8 = 151, // Unused ScanCode_Lang8 = 151,
Lang9 = 152, // Unused ScanCode_Lang9 = 152,
LeftControl = 224, ScanCode_LeftControl = 224,
LeftShift = 225, ScanCode_LeftShift = 225,
LeftAlt = 226, // Alt for PC, Option for Mac ScanCode_LeftAlt = 226,
LeftOSCommand = 227, // Window key for PC, Command for Mac ScanCode_LeftOSCommand = 227,
RightControl = 228, ScanCode_RightControl = 228,
RightShift = 229, ScanCode_RightShift = 229,
RightAlt = 230, // Alt Gr for PC, Option for Mac ScanCode_RightAlt = 230,
RightOSCommand = 231, // Window key for PC, Command for Mac ScanCode_RightOSCommand = 231,
Sleep = 258, ScanCode_Sleep = 258,
WakeUp = 259, ScanCode_WakeUp = 259,
Media_NextTrack = 267, ScanCode_Media_NextTrack = 267,
Media_PreviousTrack = 268, ScanCode_Media_PreviousTrack = 268,
Media_Stop = 269, ScanCode_Media_Stop = 269,
Media_Eject = 270, ScanCode_Media_Eject = 270,
Media_PlayPause = 271, ScanCode_Media_PlayPause = 271,
Media_Select = 272, ScanCode_Media_Select = 272,
Reserved = 287, ScanCode_Reserved = 287,
Count = 512 ScanCode_Count = 512
}; };
+18 -14
View File
@@ -1,25 +1,29 @@
#pragma once #pragma once
using MouseID = uint8; #include <Core/Common/CoreTypes.h>
#include <Juliet.h>
enum class MouseButton : uint8 typedef uint8 MouseID;
typedef uint8 MouseButton;
enum
{ {
None = 0, MouseButton_None = 0,
Left = 1 << 0, MouseButton_Left = 1 << 0,
Right = 1 << 1, MouseButton_Right = 1 << 1,
Middle = 1 << 2, MouseButton_Middle = 1 << 2,
Button1 = 1 << 3, MouseButton_Button1 = 1 << 3,
Button2 = 1 << 4, MouseButton_Button2 = 1 << 4,
}; };
// TODO : Replace by Vector2f typedef struct MousePosition MousePosition;
struct MousePosition struct MousePosition
{ {
float X; float X;
float Y; float Y;
}; };
JULIET_API extern bool IsMouseButtonDown(MouseButton button); JULIET_API extern bool8 IsMouseButtonDown(MouseButton button);
JULIET_API extern MousePosition GetMousePosition(); JULIET_API extern MousePosition GetMousePosition(void);
JULIET_API extern MousePosition GetMouseDelta(); JULIET_API extern MousePosition GetMouseDelta(void);
JULIET_API extern MouseButton GetMouseButtonState(); JULIET_API extern MouseButton GetMouseButtonState(void);
+13 -42
View File
@@ -1,52 +1,23 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
namespace Memory Byte* OS_Reserve(size_t size);
{ bool8 OS_Commit(void* ptr, size_t size);
Byte* OS_Reserve(size_t size); void OS_Release(void* ptr, size_t size);
bool OS_Commit(Byte* ptr, size_t size);
void OS_Release(Byte* ptr, size_t size);
template <typename Type> uint64 Time_Timestamp(void);
Type* OS_Reserve(size_t size) void Time_ComputeDeltaTime(void);
{ float Time_GetDeltaTime(void);
return reinterpret_cast<Type*>(OS_Reserve(size)); uint64 Time_GetFrameNumber(void);
}
template <typename Type> JULIET_API bool8 Debug_IsDebuggerPresent(void);
bool OS_Commit(Type* ptr, size_t size)
{
return OS_Commit(reinterpret_cast<Byte*>(ptr), size);
}
template <typename Type> String os_get_env_var(Arena* arena, String name);
void OS_Release(Type* ptr, size_t size) void os_set_env_var(String name, String value);
{
OS_Release(reinterpret_cast<Byte*>(ptr), size);
}
} // namespace Memory String os_get_username(Arena* arena);
namespace Time typedef int (*EntryPointFunc)(int, wchar_t**);
{
uint64 Timestamp();
void ComputeDeltaTime();
float GetDeltaTime();
uint64 GetFrameNumber();
} // namespace Time
namespace Debug
{
JULIET_API bool IsDebuggerPresent();
} // namespace Debug
String os_get_env_var(NonNullPtr<Arena> arena, const String& name);
void os_set_env_var(const String& name, const String& value);
String os_get_username(NonNullPtr<Arena> arena);
using EntryPointFunc = int (*)(int, wchar_t**);
JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv); JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
+11 -11
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
// Fwd Declare typedef struct DynamicLibrary DynamicLibrary;
struct DynamicLibrary; typedef struct HotReloadCode HotReloadCode;
struct HotReloadCode struct HotReloadCode
{ {
@@ -21,15 +21,15 @@ struct HotReloadCode
uint32 UniqueID; uint32 UniqueID;
bool IsValid : 1; bool8 IsValid;
}; };
extern JULIET_API void InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName, extern JULIET_API void InitHotReloadCode(Arena* arena, HotReloadCode* code, String dllName,
String transientDllName, String lockFilename); String transientDllName, String lockFilename);
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code); extern JULIET_API void ShutdownHotReloadCode(HotReloadCode* code);
extern JULIET_API void LoadCode(HotReloadCode& code); extern JULIET_API void LoadCode(HotReloadCode* code);
extern JULIET_API void UnloadCode(HotReloadCode& code); extern JULIET_API void UnloadCode(HotReloadCode* code);
extern JULIET_API void ReloadCode(HotReloadCode& code); extern JULIET_API void ReloadCode(HotReloadCode* code);
extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code); extern JULIET_API bool8 ShouldReloadCode(const HotReloadCode* code);
+14 -17
View File
@@ -1,27 +1,24 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h>
#ifdef JULIET_ENABLE_IMGUI #ifdef JULIET_ENABLE_IMGUI
struct ImGuiContext; typedef struct ImGuiContext ImGuiContext;
typedef struct Window Window;
typedef struct GraphicsDevice GraphicsDevice;
struct Window; JULIET_API void ImGuiService_Initialize(Window* window);
struct GraphicsDevice; JULIET_API void ImGuiService_Shutdown(void);
namespace ImGuiService JULIET_API void ImGuiService_NewFrame(void);
{ JULIET_API void ImGuiService_Render(void);
JULIET_API void Initialize(NonNullPtr<Window> window);
JULIET_API void Shutdown();
JULIET_API void NewFrame(); JULIET_API bool8 ImGuiService_IsInitialized(void);
JULIET_API void Render(); JULIET_API ImGuiContext* ImGuiService_GetContext(void);
JULIET_API bool IsInitialized(); // Run internal unit tests
JULIET_API ImGuiContext* GetContext(); JULIET_API void ImGuiService_RunTests(void);
// Run internal unit tests
JULIET_API void RunTests();
} // namespace ImGuiService
#endif // JULIET_ENABLE_IMGUI #endif // JULIET_ENABLE_IMGUI
+2 -9
View File
@@ -1,12 +1,5 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/HAL/Display/Window.h>
#include <Graphics/GraphicsDevice.h>
#include <Juliet.h> #include <Juliet.h>
namespace UnitTest void UnitTest_TestImGui(void);
{
void TestImGui();
}
+16 -11
View File
@@ -1,21 +1,26 @@
#pragma once #pragma once
enum class JulietInit_Flags : uint8 #include <Core/Common/CoreTypes.h>
typedef uint8 JulietInit_Flags;
enum
{ {
None = 0, JulietInit_Flags_None = 0,
Display = 1 << 0, JulietInit_Flags_Display = 1 << 0,
Audio = 1 << 1, JulietInit_Flags_Audio = 1 << 1,
Count = Audio, JulietInit_Flags_Count = JulietInit_Flags_Audio,
All = 0xFb JulietInit_Flags_All = 0xFbu
}; };
struct Arena; typedef struct Arena Arena;
typedef struct GameState GameState;
typedef struct GameData GameData;
struct GameData struct GameData
{ {
struct GameState* GameState; GameState* GameState;
Arena* ScratchArena; Arena* ScratchArena;
}; };
void JulietInit(JulietInit_Flags flags); void JulietInit(JulietInit_Flags flags);
void JulietShutdown(); void JulietShutdown(void);
+6 -14
View File
@@ -1,21 +1,13 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Logging/LogTypes.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
// TODO : Juliet strings extern void JULIET_API InitializeLogManager(void);
// TODO Juliet Containers + Allocators... extern void JULIET_API ShutdownLogManager(void);
// TODO: Juliet chrono, because it prevents me from doing #define global static
enum class LogLevel : uint8; extern void JULIET_API LogScopeBegin(void);
enum class LogCategory : uint8; extern void JULIET_API LogScopeEnd(void);
extern void JULIET_API InitializeLogManager();
extern void JULIET_API ShutdownLogManager();
extern void JULIET_API LogScopeBegin();
// TODO everything that happened in there to export them to file or something
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, ...);
+17 -13
View File
@@ -1,19 +1,23 @@
#pragma once #pragma once
enum class LogLevel : uint8 #include <Core/Common/CoreTypes.h>
typedef uint8 LogLevel;
enum
{ {
Debug = 0, LogLevel_Debug = 0,
Message = 1, LogLevel_Message = 1,
Warning = 2, LogLevel_Warning = 2,
Error = 3, LogLevel_Error = 3,
}; };
enum class LogCategory : uint8 typedef uint8 LogCategory;
enum
{ {
Core = 0, LogCategory_Core = 0,
Graphics = 1, LogCategory_Graphics = 1,
Networking = 2, LogCategory_Networking = 2,
Engine = 3, LogCategory_Engine = 3,
Tool = 4, LogCategory_Tool = 4,
Game = 5, LogCategory_Game = 5,
}; };
+3 -6
View File
@@ -1,8 +1,8 @@
#pragma once #pragma once
#include <Core/HAL/OS/OS.h> #include <Core/HAL/OS/OS.h>
extern int JulietMain(int, wchar_t**); extern int JulietMain(int argc, wchar_t** argv);
#if JULIET_WIN32 #if JULIET_WIN32
#ifndef WINAPI #ifndef WINAPI
@@ -17,12 +17,10 @@ int wmain(int argc, wchar_t** argv)
#else #else
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
return Bootstrap(JulietMain, argc, argv); return Bootstrap(JulietMain, argc, (wchar_t**)argv);
} }
#endif #endif
extern "C" {
typedef struct HINSTANCE__* HINSTANCE; typedef struct HINSTANCE__* HINSTANCE;
typedef char* LPSTR; typedef char* LPSTR;
typedef wchar_t* PWSTR; typedef wchar_t* PWSTR;
@@ -40,7 +38,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
return Bootstrap(JulietMain, __argc, __wargv); return Bootstrap(JulietMain, __argc, __wargv);
} }
}
#else #else
#error "Only windows main is implemented" #error "Only windows main is implemented"
#endif #endif
+11 -40
View File
@@ -1,46 +1,17 @@
#pragma once #pragma once
#include <Juliet.h>
#include <Core/Common/CoreTypes.h>
extern JULIET_API float RoundF(float value); extern JULIET_API float RoundF(float value);
inline int32 LRoundF(float value) static inline int32 LRoundF(float value)
{ {
return static_cast<int32>(RoundF(value)); return (int32)RoundF(value);
} }
template <typename Type> #define Min(lhs, rhs) (((rhs) < (lhs)) ? (rhs) : (lhs))
constexpr Type Min(Type lhs, Type rhs) #define Max(lhs, rhs) (((lhs) < (rhs)) ? (rhs) : (lhs))
{ #define ClampTop(value, X) Min((value), (X))
return rhs < lhs ? rhs : lhs; #define ClampBottom(value, X) Max((value), (X))
} #define Clamp(val, min_v, max_v) (((val) < (min_v)) ? (min_v) : (((val) > (max_v)) ? (max_v) : (val)))
template <typename Type>
constexpr Type Max(Type lhs, Type rhs)
{
return lhs < rhs ? rhs : lhs;
}
template <typename Type>
constexpr Type ClampTop(Type value, Type X)
{
return Min(value, X);
}
template <typename Type>
constexpr Type ClampBottom(Type value, Type X)
{
return Max(value, X);
}
template <typename Type>
constexpr Type Clamp(Type val, Type min, Type max)
{
if (val < min)
{
return min;
}
if (val > max)
{
return max;
}
return val;
}
+54 -49
View File
@@ -1,16 +1,17 @@
#pragma once #pragma once
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <math.h> #include <math.h>
typedef struct Matrix Matrix;
struct Matrix struct Matrix
{ {
float m[4][4]; float m[4][4];
}; };
[[nodiscard]] inline Matrix MatrixIdentity() static inline Matrix MatrixIdentity(void)
{ {
Matrix result = {}; Matrix result = { 0 };
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;
@@ -18,9 +19,9 @@ struct Matrix
return result; return result;
} }
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs) static inline Matrix MatrixMultiply(Matrix lhs, Matrix rhs)
{ {
Matrix result = {}; Matrix result = { 0 };
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
@@ -34,80 +35,80 @@ struct Matrix
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z) static inline Matrix MatrixTranslation(float x, float y, float z)
{ {
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
result.m[0][3] = x; result.m[0][3] = x;
result.m[1][3] = y; result.m[1][3] = y;
result.m[2][3] = z; result.m[2][3] = z;
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z) static inline Matrix MatrixScale(float x, float y, float z)
{ {
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
result.m[0][0] = x; result.m[0][0] = x;
result.m[1][1] = y; result.m[1][1] = y;
result.m[2][2] = z; result.m[2][2] = z;
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixRotationX(float radians) static inline Matrix MatrixRotationX(float radians)
{ {
float c = cosf(radians); float c = cosf(radians);
float s = sinf(radians); float s = sinf(radians);
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
result.m[1][1] = c; result.m[1][1] = c;
result.m[1][2] = -s; result.m[1][2] = -s;
result.m[2][1] = s; result.m[2][1] = s;
result.m[2][2] = c; result.m[2][2] = c;
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixRotationY(float radians) static inline Matrix MatrixRotationY(float radians)
{ {
float c = cosf(radians); float c = cosf(radians);
float s = sinf(radians); float s = sinf(radians);
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
result.m[0][0] = c; result.m[0][0] = c;
result.m[0][2] = s; result.m[0][2] = s;
result.m[2][0] = -s; result.m[2][0] = -s;
result.m[2][2] = c; result.m[2][2] = c;
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixRotationZ(float radians) static inline Matrix MatrixRotationZ(float radians)
{ {
float c = cosf(radians); float c = cosf(radians);
float s = sinf(radians); float s = sinf(radians);
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
result.m[0][0] = c; result.m[0][0] = c;
result.m[0][1] = -s; result.m[0][1] = -s;
result.m[1][0] = s; result.m[1][0] = s;
result.m[1][1] = c; result.m[1][1] = c;
return result; return result;
} }
inline void MatrixTranslate(Matrix& m, const Vector3& v) static inline void MatrixTranslate(Matrix* m, Vector3 v)
{ {
m.m[0][3] += v.x; m->m[0][3] += v.x;
m.m[1][3] += v.y; m->m[1][3] += v.y;
m.m[2][3] += v.z; m->m[2][3] += v.z;
} }
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z) static inline Matrix MatrixRotation(float x, float y, float z)
{ {
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z); return MatrixMultiply(MatrixMultiply(MatrixRotationX(x), MatrixRotationY(y)), MatrixRotationZ(z));
} }
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up) static inline Matrix LookAt(Vector3 eye, Vector3 target, Vector3 up)
{ {
// Left-Handed convention // Left-Handed convention
Vector3 zaxis = Normalize(target - eye); // Forward is +z Vector3 zaxis = Normalize(Vector3Sub(target, eye)); // Forward is +z
Vector3 xaxis = Normalize(Cross(up, zaxis)); Vector3 xaxis = Normalize(Cross(up, zaxis));
Vector3 yaxis = Cross(zaxis, xaxis); Vector3 yaxis = Cross(zaxis, xaxis);
Matrix result = {}; Matrix result = { 0 };
// Row 0 // Row 0
result.m[0][0] = xaxis.x; result.m[0][0] = xaxis.x;
result.m[0][1] = xaxis.y; result.m[0][1] = xaxis.y;
@@ -132,25 +133,25 @@ inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& u
return result; return result;
} }
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ) static inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
{ {
// Left-Handed Perspective // Left-Handed Perspective
float yScale = 1.0f / tanf(fovY * 0.5f); float yScale = 1.0f / tanf(fovY * 0.5f);
float xScale = yScale / aspectRatio; float xScale = yScale / aspectRatio;
Matrix result = {}; Matrix result = { 0 };
result.m[0][0] = xScale; result.m[0][0] = xScale;
result.m[1][1] = yScale; result.m[1][1] = yScale;
result.m[2][2] = farZ / (farZ - nearZ); result.m[2][2] = farZ / (farZ - nearZ);
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ); result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
result.m[3][2] = 1.0f; result.m[3][2] = 1.0f;
result.m[3][3] = 0.0f; result.m[3][3] = 0.0f;
return result; return result;
} }
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m) static inline Matrix MatrixInverse(Matrix m)
{ {
Matrix out = {}; Matrix out = { 0 };
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3]; 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 m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
@@ -183,8 +184,12 @@ inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float f
{ {
float invDet = 1.0f / det; float invDet = 1.0f / det;
for (int r = 0; r < 4; ++r) for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 4; ++c) for (int c = 0; c < 4; ++c)
{
out.m[r][c] *= invDet; out.m[r][c] *= invDet;
}
}
} }
return out; return out;
+7 -2
View File
@@ -1,6 +1,11 @@
#pragma once #pragma once
struct Rectangle #include <Core/Common/CoreTypes.h>
#define Rectangle JulietRectangle
typedef struct JulietRectangle JulietRectangle;
struct JulietRectangle
{ {
int32 X; int32 X;
int32 Y; int32 Y;
+41 -17
View File
@@ -1,38 +1,62 @@
#pragma once #pragma once
#include <math.h>
typedef struct Vector3 Vector3;
struct Vector3 struct Vector3
{ {
float x, y, z; float x;
float y;
Vector3 operator+(const Vector3& rhs) const { return { x + rhs.x, y + rhs.y, z + rhs.z }; } float 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 }; }
}; };
typedef struct Vector4 Vector4;
struct Vector4 struct Vector4
{ {
float x = 0.f; float x;
float y = 0.f; float y;
float z = 0.f; float z;
float w = 0.f; float w;
}; };
inline Vector3 Normalize(const Vector3& v) static inline Vector3 Vector3Add(Vector3 lhs, Vector3 rhs)
{ {
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); Vector3 res = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z };
return res;
}
static inline Vector3 Vector3Sub(Vector3 lhs, Vector3 rhs)
{
Vector3 res = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z };
return res;
}
static inline Vector3 Vector3Scale(Vector3 v, float s)
{
Vector3 res = { v.x * s, v.y * s, v.z * s };
return res;
}
static inline Vector3 Normalize(Vector3 v)
{
Vector3 result = v;
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
if (len > 0.0001f) if (len > 0.0001f)
{ {
return { v.x / len, v.y / len, v.z / len }; result.x = v.x / len;
result.y = v.y / len;
result.z = v.z / len;
} }
return v; return result;
} }
inline Vector3 Cross(const Vector3& a, const Vector3& b) static inline Vector3 Cross(Vector3 a, 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 }; Vector3 res = { 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 res;
} }
inline float Dot(const Vector3& a, const Vector3& b) static inline float Dot(Vector3 a, Vector3 b)
{ {
return a.x * b.x + a.y * b.y + a.z * b.z; return a.x * b.x + a.y * b.y + a.z * b.z;
} }
+16 -16
View File
@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <stdlib.h>
// Uninitialized allocation // Uninitialized allocation
JULIET_API void* Malloc(size_t elem_size); JULIET_API void* Malloc(size_t elem_size);
@@ -9,20 +10,19 @@ JULIET_API void* Malloc(size_t elem_size);
JULIET_API void* Calloc(size_t nb_elem, size_t elem_size); JULIET_API void* Calloc(size_t nb_elem, size_t elem_size);
JULIET_API void* Realloc(void* memory, size_t newSize); JULIET_API void* Realloc(void* memory, size_t newSize);
// Free static inline void FreeMemory(void* memory)
template <typename Type>
void Free(Type* memory)
{ {
Assert(memory); Assert(memory != NULL);
::free(memory); free(memory);
}
// Free and Set the ptr to nullptr
template <typename Type>
void SafeFree(Type*& memory)
{
if (memory)
{
::free(memory);
memory = nullptr;
}
} }
#define SafeFree(memory_ptr) \
do \
{ \
if ((memory_ptr) != NULL) \
{ \
free((void*)(memory_ptr)); \
(memory_ptr) = NULL; \
} \
} \
while (0)
+51 -73
View File
@@ -1,21 +1,19 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#if JULIET_DEBUG #if JULIET_DEBUG
#include <Core/Memory/MemoryArenaDebug.h> #include <Core/Memory/MemoryArenaDebug.h>
#endif #endif
constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64); #define g_Arena_Default_Reserve_Size Megabytes(64)
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64); #define g_Arena_Default_Commit_Size Kilobytes(64)
constexpr global uint64 k_ArenaHeaderSize = 128; #define k_ArenaHeaderSize ((uint64)128)
#if JULIET_DEBUG typedef struct Arena Arena;
struct ArenaDebugInfo; typedef struct TempArena TempArena;
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args); typedef struct ArenaParams ArenaParams;
#endif
struct Arena struct Arena
{ {
@@ -35,14 +33,14 @@ struct Arena
Arena* FreeBlockLast; Arena* FreeBlockLast;
JULIET_DEBUG_ONLY(uint16 LostNodeCount;) JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;) JULIET_DEBUG_ONLY(bool8 CanReserveMore;)
JULIET_DEBUG_ONLY(Arena* GlobalNext;) JULIET_DEBUG_ONLY(Arena* GlobalNext;)
JULIET_DEBUG_ONLY(Arena* GlobalPrev;) JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;) JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
const char* Name; const char* Name;
}; };
static_assert(sizeof(Arena) <= k_ArenaHeaderSize); StaticAssert(sizeof(Arena) <= k_ArenaHeaderSize, ArenaHeaderSizeCheck);
struct TempArena struct TempArena
{ {
@@ -52,74 +50,54 @@ struct TempArena
struct ArenaParams struct ArenaParams
{ {
uint64 ReserveSize = g_Arena_Default_Reserve_Size; uint64 ReserveSize;
uint64 CommitSize = g_Arena_Default_Commit_Size; uint64 CommitSize;
const char* Name; const char* Name;
JULIET_DEBUG_ONLY(bool8 DoNotReserveMore;)
// 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, JULIET_API Arena* ArenaAllocateImpl(ArenaParams params, const char* file, uint32 line);
const std::source_location& loc = std::source_location::current()); #define ArenaAllocate(...) ArenaAllocateImpl(__VA_ARGS__, __FILE__, (uint32)__LINE__)
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
// Raw Push, can be used but templated helpers exists below JULIET_API void ArenaRelease(Arena* arena);
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_PARAM(const char* tag)); // Raw Push, can be used or macros below
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position); JULIET_API void* ArenaPush(Arena* arena, size_t size, size_t align,
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount); bool8 shouldBeZeroed JULIET_DEBUG_PARAM(const char* tag));
JULIET_API void ArenaClear(NonNullPtr<Arena> arena); JULIET_API void ArenaPopTo(Arena* arena, size_t position);
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena); JULIET_API void ArenaPop(Arena* arena, size_t amount);
JULIET_API void ArenaClear(Arena* arena);
JULIET_API size_t ArenaPos(Arena* arena);
#if JULIET_DEBUG #if JULIET_DEBUG
template <typename FirstDebugArg, typename... DebugArgs> #define ArenaPushSize(...) ArenaPush(__VA_ARGS__)
#define ArenaPushStruct(arena, Type) \
((Type*)ArenaPush((arena), sizeof(Type), AlignOf(Type), true, #Type))
#define ArenaPushStructTag(arena, Type, tag) \
((Type*)ArenaPush((arena), sizeof(Type), AlignOf(Type), true, (tag)))
#define ArenaPushArray(arena, Type, count) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), true, #Type))
#define ArenaPushArrayTag(arena, Type, count, tag) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), true, (tag)))
#define ArenaPushArrayNoZero(arena, Type, count) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), false, #Type))
#define ArenaPushArrayNoZeroTag(arena, Type, count, tag) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), false, (tag)))
#else
#define ArenaPushSize(...) ArenaPush(__VA_ARGS__)
#define ArenaPushStruct(arena, Type) \
((Type*)ArenaPush((arena), sizeof(Type), AlignOf(Type), true))
#define ArenaPushStructTag(arena, Type, tag) \
((Type*)ArenaPush((arena), sizeof(Type), AlignOf(Type), true))
#define ArenaPushArray(arena, Type, count) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), true))
#define ArenaPushArrayTag(arena, Type, count, tag) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), true))
#define ArenaPushArrayNoZero(arena, Type, count) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), false))
#define ArenaPushArrayNoZeroTag(arena, Type, count, tag) \
((Type*)ArenaPush((arena), sizeof(Type) * (size_t)(count), Max(8ull, (uint64)AlignOf(Type)), false))
#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;
}()));
}
template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)> TempArena ArenaTempBegin(Arena* arena);
[[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 GetTypeName<Type>();
}())));
}
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))
{
return static_cast<Type*>(
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
shouldZero JULIET_DEBUG_PARAM(
[&]() -> const char*
{
if constexpr (sizeof...(DebugArgs) > 0)
{
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
}
return GetTypeName<Type>();
}())));
}
TempArena ArenaTempBegin(NonNullPtr<Arena> arena);
void ArenaTempEnd(TempArena temp); void ArenaTempEnd(TempArena temp);
+15 -18
View File
@@ -1,12 +1,13 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#if JULIET_DEBUG #if JULIET_DEBUG
struct Arena; typedef struct Arena Arena;
struct MemoryBlock; typedef struct MemoryBlock MemoryBlock;
typedef struct ArenaDebugInfo ArenaDebugInfo;
typedef struct ArenaAllocation ArenaAllocation;
// Arena (Struct) // Arena (Struct)
struct ArenaDebugInfo struct ArenaDebugInfo
@@ -27,20 +28,16 @@ struct ArenaAllocation
}; };
// Arena (Struct) // Arena (Struct)
void DebugRegisterArena(NonNullPtr<Arena> arena); void DebugRegisterArena(Arena* arena);
void DebugUnregisterArena(NonNullPtr<Arena> arena); void DebugUnregisterArena(Arena* arena);
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name); void DebugArenaSetDebugName(Arena* arena, const char* name);
bool IsDebugInfoArena(const Arena* arena); // To prevent recursion bool8 IsDebugInfoArena(const Arena* arena); // To prevent recursion
void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset); void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
void DebugArenaPopTo(Arena* block, size_t newPosition); void DebugArenaPopTo(Arena* block, size_t newPosition);
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag); void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
// MemoryArena (Pool-based) JULIET_API Arena* GetDebugInfoArena(void);
void DebugFreeArenaAllocations(MemoryBlock* blk); JULIET_API Arena* GetGlobalArenaListHead(void);
void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
JULIET_API Arena* GetDebugInfoArena();
#endif #endif
+53 -49
View File
@@ -1,63 +1,68 @@
#pragma once #pragma once
#define ArraySize(array) (sizeof(array) / sizeof(array[0])) #include <Core/Common/CoreTypes.h>
#include <string.h>
inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size) #define ArraySize(array) (sizeof(array) / sizeof((array)[0]))
static inline int32 MemCompare(const void* left_value, const void* right_value, size_t size)
{ {
auto left = static_cast<const unsigned char*>(leftValue); const unsigned char* left = (const unsigned char*)left_value;
auto right = static_cast<const unsigned char*>(rightValue); const unsigned char* right = (const unsigned char*)right_value;
while (size && *left == *right) while (size && *left == *right)
{ {
++left; ++left;
++right; ++right;
--size; --size;
} }
return size ? *left - *right : 0; return size ? ((int32)(*left) - (int32)(*right)) : 0;
} }
// Single linked list // Single linked list macros
void SingleLinkedListPushNext(auto*& stackTop, auto* node) #define SingleLinkedListPushNext(stackTop, node) \
{ do \
node->Next = stackTop; { \
stackTop = node; (node)->Next = (stackTop); \
} (stackTop) = (node); \
} \
while (0)
void SingleLinkedListPushPrevious(auto*& stackTop, auto* node) #define SingleLinkedListPushPrevious(stackTop, node) \
{ do \
node->Previous = stackTop; { \
stackTop = node; (node)->Previous = (stackTop); \
} (stackTop) = (node); \
} \
while (0)
void SingleLinkedListPopNext(auto*& stackTop) #define SingleLinkedListPopNext(stackTop) \
{ do \
stackTop = stackTop->Next; { \
} (stackTop) = (stackTop)->Next; \
} \
while (0)
// Double linked list // Double linked list queue macro
template <typename QueueType, typename QueueTypeNode> #define Enqueue(queue, node) \
void Enqueue(QueueType& queue, QueueTypeNode* node) do \
{ { \
if (queue.First == nullptr) if ((queue).First == NULL) \
{ { \
queue.First = queue.Last = node; (queue).First = (queue).Last = (node); \
node->Next = nullptr; (node)->Next = NULL; \
} } \
else else \
{ { \
queue.Last->Next = node, queue.Last = node; (queue).Last->Next = (node); \
node->Next = nullptr; (queue).Last = (node); \
} (node)->Next = NULL; \
} \
queue.Nodecount += 1; (queue).Nodecount += 1; \
} } \
while (0)
template <typename QueueType>
struct QueueNode
{
QueueType* Next;
};
#define DECLARE_QUEUE(type) \ #define DECLARE_QUEUE(type) \
typedef struct type##Queue type##Queue; \
struct type##Queue \ struct type##Queue \
{ \ { \
type* First; \ type* First; \
@@ -66,8 +71,7 @@ struct QueueNode
size_t Size; \ size_t Size; \
}; };
// TODO: homemade versions #define MemSet memset
#define MemSet memset #define MemCopy memcpy
#define MemCopy memcpy #define MemoryZero(dst, size) MemSet((dst), 0, (size))
#define MemZeroStruct(ptr) MemoryZero((ptr), sizeof(*(ptr)))
#define MemoryZero(dst, size) MemSet(dst, 0, size)
@@ -1,6 +0,0 @@
#pragma once
// TODO : Do something better.
constexpr uint32 kLocalhost = (127 << 3) | (0 << 2) | (0 << 1) | 1;
constexpr uint32 kAnyIp = 0;
constexpr uint32 kBroadcastIp = (255 << 3) | (255 << 2) | (255 << 1) | 255;
@@ -1,32 +0,0 @@
#pragma once
#include <Core/Container/Vector.h>
class NetworkPacket
{
public:
NetworkPacket();
NetworkPacket(Arena& arena);
virtual ~NetworkPacket();
NetworkPacket(NetworkPacket&);
NetworkPacket& operator=(const NetworkPacket&);
NetworkPacket(NetworkPacket&&) noexcept;
NetworkPacket& operator=(NetworkPacket&&) noexcept;
void Create(Arena& arena);
[[nodiscard]] ByteBuffer GetRawData();
// Pack
NetworkPacket& operator<<(uint32 value);
NetworkPacket& operator<<(char* data);
protected:
void Append(ByteBuffer buffer);
friend class TcpSocket;
private:
VectorArena<Byte, 4096> Data;
size_t PartialSendIndex = 0;
};
-53
View File
@@ -1,53 +0,0 @@
#pragma once
#include <Core/Networking/SocketHandle.h>
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
{
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;
};
@@ -1,11 +0,0 @@
#pragma once
#if JULIET_WIN32
#include <basetsd.h>
#endif
#if JULIET_WIN32
using SocketHandle = UINT_PTR;
#else
using SocketHandle = int;
#endif
@@ -1,18 +0,0 @@
#pragma once
#include <Core/Networking/IPAddress.h>
#include <Core/Networking/Socket.h>
#include <Core/Networking/TcpSocket.h>
class TcpListener : public Socket
{
public:
TcpListener();
TcpListener(const TcpListener&) = delete;
TcpListener& operator=(const TcpListener&) = delete;
Status Listen(uint16 port, uint32 address = kAnyIp);
Status Accept(TcpSocket& socket);
void Close();
};
@@ -1,21 +0,0 @@
#pragma once
#include <Core/Networking/Socket.h>
class NetworkPacket;
class TcpSocket : public Socket
{
public:
TcpSocket();
TcpSocket(const TcpSocket&) = delete;
TcpSocket& operator=(const TcpSocket&) = delete;
RequestStatus Send(NetworkPacket& packet);
RequestStatus Send(ByteBuffer buffer);
Status Receive(NetworkPacket& outPacket);
private:
friend class TcpListener;
};
+14 -29
View File
@@ -1,33 +1,18 @@
#pragma once #pragma once
#include <algorithm> #include <assert.h>
#include <bit> #include <float.h>
#include <cassert> #include <inttypes.h>
#include <cfloat> #include <limits.h>
#include <chrono> #include <math.h>
#include <cinttypes> #include <stdarg.h>
#include <cmath> #include <stddef.h>
#include <concepts> #include <stdint.h>
#include <cstdarg> #include <stdio.h>
#include <cstddef> #include <stdlib.h>
#include <cstdint> #include <string.h>
#include <cstdio> #include <time.h>
#include <cstdlib> #include <wchar.h>
#include <cstring>
#include <format>
#include <forward_list>
#include <ios>
#include <iosfwd>
#include <limits>
#include <list>
#include <memory>
#include <mutex>
#include <queue>
#include <source_location>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
#include <Juliet.h> #include <Juliet.h>
-4
View File
@@ -1,4 +0,0 @@
#pragma once
using Mutex = std::mutex;
using LockGuard = std::lock_guard<Mutex>;
+4 -4
View File
@@ -1,13 +1,13 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <time.h>
uint32 thread_id(); uint32 thread_id(void);
void set_thread_name(String name); void set_thread_name(String name);
// TODO : Proper wait static inline void wait_ms(int milliseconds)
inline void wait_ms(int milliseconds)
{ {
clock_t start_time = clock(); clock_t start_time = clock();
while (clock() < start_time + milliseconds) while (clock() < start_time + milliseconds)
+6 -5
View File
@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
typedef struct thread_context thread_context;
struct thread_context struct thread_context
{ {
Arena* ScratchArenas[2]; Arena* ScratchArenas[2];
@@ -10,10 +11,10 @@ struct thread_context
uint8 ThreadNameSize; uint8 ThreadNameSize;
}; };
thread_context* thread_context_alloc(); thread_context* thread_context_alloc(void);
void thread_context_release(NonNullPtr<thread_context> ctx); void thread_context_release(thread_context* ctx);
void thread_context_select(NonNullPtr<thread_context> ctx); void thread_context_select(thread_context* ctx);
thread_context* thread_context_current(); thread_context* thread_context_current(void);
Arena* thread_context_get_scratch(Arena** conflicts, size_t count); Arena* thread_context_get_scratch(Arena** conflicts, size_t count);
JULIET_API TempArena scratch_begin(Arena** conflicts, size_t count); JULIET_API TempArena scratch_begin(Arena** conflicts, size_t count);
+1 -1
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Graphics/MeshRenderer.h> #include <Graphics/MeshRenderer.h>
+25 -54
View File
@@ -5,31 +5,15 @@
#include <Core/Common/CRC32.h> #include <Core/Common/CRC32.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
struct Archive; typedef struct Archive Archive;
typedef struct Class Class;
using serialize_fct_type = void(Archive&, uint16 version, void* payload); typedef void (*serialize_fct_ptr)(Archive* ar, uint16 version, void* payload);
using serialize_fct_ptr = serialize_fct_type*; typedef void (*initialize_fct_ptr)(void* payload);
using initialize_fct_type = void(void* payload);
using initialize_fct_ptr = initialize_fct_type*;
template <typename Type>
void serialize_thunk(Archive& ar, uint16 version, void* payload)
{
Assert(payload);
serialize(ar, version, *((Type*)payload));
}
template <typename Type>
void initialize_thunk(void* payload)
{
auto& typed_val = *(Type*)payload;
typed_val = {};
}
struct Class struct Class
{ {
uint32 CRC; String Name;
uint8 kind; uint8 kind;
uint16 version; uint16 version;
const Class* base_class; const Class* base_class;
@@ -37,45 +21,32 @@ struct Class
serialize_fct_ptr serialize_fct; serialize_fct_ptr serialize_fct;
size_t size_of; size_t size_of;
size_t alignment; size_t alignment;
#if JULIET_DEBUG
String Name;
#endif
}; };
#define DECLARE_CLASS() static Class* kind; #define DECLARE_CLASS(cls) extern const Class class_kind_##cls;
#define DEFINE_CLASS_VERSIONED(cls, version, base_class) \ #define DEFINE_CLASS_VERSIONED(cls, version_num, base_class_ptr) \
constexpr Class class_kind_##cls = MakeClass(ConstString(#cls), 0, (version), (base_class), sizeof(cls), \ const Class class_kind_##cls = { \
alignof(cls), (&initialize_thunk<cls>), (&serialize_thunk<cls>)); \ .Name = ConstString(#cls), \
Class* cls::kind = const_cast<Class*>(&class_kind_##cls); .kind = 0, \
.version = (version_num), \
.base_class = (base_class_ptr), \
.initialize_fct = init_##cls, \
.serialize_fct = serialize_##cls, \
.size_of = sizeof(cls), \
.alignment = AlignOf(cls) \
};
consteval Class MakeClass(String name, uint8 kind, uint16 version, const Class* base_class, size_t size, size_t align, #define ClassKind(cls) (&class_kind_##cls)
initialize_fct_ptr init_fct, serialize_fct_ptr serde_fct)
static inline uint32 class_get_crc(const Class* cls)
{ {
Class cls = {}; Assert(cls != NULL);
cls.CRC = crc32(name.Str, name.Size); return crc32_str(cls->Name);
cls.kind = kind;
cls.version = version;
cls.base_class = base_class;
cls.size_of = size;
cls.alignment = align;
cls.initialize_fct = init_fct;
cls.serialize_fct = serde_fct;
#if JULIET_DEBUG
cls.Name = name;
#endif
return cls;
} }
bool IsA(const Class& query, const Class* target); JULIET_API bool8 IsA(const Class* query, const Class* target);
template <typename type> #define IsClassA(cls_ptr, target_type) IsA((cls_ptr), ClassKind(target_type))
bool IsA(const Class& cls)
{
return IsA(cls, type::kind);
}
JULIET_API void serialize(Archive& ar, NonNullPtr<const Class> cls, void* instance); JULIET_API void serialize_class(Archive* ar, const Class* cls, void* instance);
+2 -5
View File
@@ -1,12 +1,9 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#if JULIET_DEBUG #if JULIET_DEBUG
namespace Debug JULIET_API void Debug_DebugDrawMemoryArena(void);
{
JULIET_API void DebugDrawMemoryArena();
} // namespace Debug
#endif #endif
+29 -16
View File
@@ -1,22 +1,35 @@
#pragma once #pragma once
#include <Core/Application/IApplication.h> #include <Core/JulietInit.h>
#include <Core/Memory/MemoryArena.h>
#include <Graphics/Graphics.h>
#include <Graphics/RenderPass.h>
enum class JulietInit_Flags : uint8; typedef struct ApplicationCallbacks ApplicationCallbacks;
struct ApplicationCallbacks
struct Engine
{ {
IApplication* Application = nullptr; void (*Init)(Arena* platformArena);
Arena* PlatformArena = nullptr; void (*Shutdown)(void);
Arena* AssetArena = nullptr; void (*Update)(float deltaTime);
bool8 (*IsRunning)(void);
Window* (*GetPlatformWindow)(void);
GraphicsDevice* (*GetGraphicsDevice)(void);
ColorTargetInfo (*GetColorTargetInfo)(Texture* swapchainTexture);
DepthStencilTargetInfo* (*GetDepthTargetInfo)(void);
}; };
void InitializeEngine(JulietInit_Flags flags); typedef struct Engine Engine;
void ShutdownEngine(); struct Engine
{
ApplicationCallbacks Application;
Arena* PlatformArena;
Arena* AssetArena;
};
void LoadApplication(IApplication& app); JULIET_API void StartApplication(ApplicationCallbacks app, JulietInit_Flags flags);
void UnloadApplication(); JULIET_API void InitializeEngine(JulietInit_Flags flags);
JULIET_API void ShutdownEngine(void);
void RunEngine(); JULIET_API void LoadApplication(ApplicationCallbacks app);
JULIET_API void UnloadApplication(void);
extern Arena* GetPlatformArena(); JULIET_API void RunEngine(void);
JULIET_API Arena* GetPlatformArena(void);
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <Juliet.h>
typedef uint8 UserID;
void initialize_user_system(void);
void shutdown_user_system(void);
JULIET_API uint8 get_local_user_id(void);
+15 -8
View File
@@ -1,8 +1,10 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h>
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Juliet.h> #include <Juliet.h>
typedef struct Camera Camera;
struct Camera struct Camera
{ {
index_t Index; index_t Index;
@@ -15,21 +17,26 @@ struct Camera
float FarPlane; float FarPlane;
}; };
inline Matrix Camera_GetViewMatrix(const Camera& cam) static inline Matrix Camera_GetViewMatrix(const Camera* cam)
{ {
return LookAt(cam.Position, cam.Target, cam.Up); Assert(cam != NULL);
return LookAt(cam->Position, cam->Target, cam->Up);
} }
inline Matrix Camera_GetProjectionMatrix(const Camera& cam) static inline Matrix Camera_GetProjectionMatrix(const Camera* cam)
{ {
return PerspectiveFov(cam.FOV, cam.AspectRatio, cam.NearPlane, cam.FarPlane); Assert(cam != NULL);
return PerspectiveFov(cam->FOV, cam->AspectRatio, cam->NearPlane, cam->FarPlane);
} }
inline Matrix Camera_GetViewProjectionMatrix(const Camera& cam) static inline Matrix Camera_GetViewProjectionMatrix(const Camera* cam)
{ {
return Camera_GetProjectionMatrix(cam) * Camera_GetViewMatrix(cam); Assert(cam != NULL);
Matrix proj = Camera_GetProjectionMatrix(cam);
Matrix view = Camera_GetViewMatrix(cam);
return MatrixMultiply(proj, view);
} }
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(void);
JULIET_API extern void SetCurrentCamera(index_t index); JULIET_API extern void SetCurrentCamera(index_t index);
+17 -9
View File
@@ -1,13 +1,21 @@
#pragma once #pragma once
template <typename Type> #include <Core/Common/CoreTypes.h>
struct ColorType
typedef struct FColor FColor;
struct FColor
{ {
Type R; float R;
Type G; float G;
Type B; float B;
Type A; float A;
}; };
using FColor = ColorType<float>; typedef struct Color Color;
using Color = ColorType<uint8>; struct Color
{
uint8 R;
uint8 G;
uint8 B;
uint8 A;
};
+5 -5
View File
@@ -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,9 +6,9 @@
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Juliet.h> #include <Juliet.h>
extern JULIET_API void DebugDisplay_Initialize(NonNullPtr<Arena> arena, GraphicsDevice* device); extern JULIET_API void DebugDisplay_Initialize(Arena* arena, GraphicsDevice* device);
extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device); extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device);
extern JULIET_API void DebugDisplay_DrawLine(const Vector3& start, const Vector3& end, const FColor& color, bool overlay); extern JULIET_API void DebugDisplay_DrawLine(Vector3 start, Vector3 end, FColor color, bool8 overlay);
extern JULIET_API void DebugDisplay_DrawSphere(const Vector3& center, float radius, const FColor& color, bool overlay); extern JULIET_API void DebugDisplay_DrawSphere(Vector3 center, float radius, FColor color, bool8 overlay);
extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList); extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList);
extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera& camera); extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera* camera);
+79 -74
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/Math/Shape.h> #include <Core/Math/Shape.h>
@@ -13,11 +12,12 @@
// Graphics Interface // Graphics Interface
// Opaque types // Opaque types
struct CommandList; typedef struct CommandList CommandList;
struct GraphicsDevice; typedef struct GraphicsDevice GraphicsDevice;
struct Fence; typedef struct Fence Fence;
// Parameters of an indirect draw command // Parameters of an indirect draw command
typedef struct IndirectDrawCommand IndirectDrawCommand;
struct IndirectDrawCommand struct IndirectDrawCommand
{ {
uint32 VertexCount; // Number of vertices to draw uint32 VertexCount; // Number of vertices to draw
@@ -27,6 +27,7 @@ struct IndirectDrawCommand
}; };
// Parameters of an INDEXED indirect draw command // Parameters of an INDEXED indirect draw command
typedef struct IndexedIndirectDrawCommand IndexedIndirectDrawCommand;
struct IndexedIndirectDrawCommand struct IndexedIndirectDrawCommand
{ {
uint32 VertexCount; // Number of vertices to draw uint32 VertexCount; // Number of vertices to draw
@@ -37,6 +38,7 @@ struct IndexedIndirectDrawCommand
}; };
// Parameters of an INDEXED Indirect Dispatch Command // Parameters of an INDEXED Indirect Dispatch Command
typedef struct IndirectDispatchCommand IndirectDispatchCommand;
struct IndirectDispatchCommand struct IndirectDispatchCommand
{ {
uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X
@@ -44,39 +46,44 @@ struct IndirectDispatchCommand
uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z
}; };
enum class QueueType : uint8 typedef uint8 QueueType;
enum QueueType_Enum
{ {
Graphics = 0, QueueType_Graphics = 0,
Compute, QueueType_Compute,
Copy, QueueType_Copy,
Count QueueType_Count
}; };
enum class IndexFormat : uint8 typedef uint8 IndexFormat;
enum IndexFormat_Enum
{ {
UInt16, IndexFormat_UInt16,
UInt32 IndexFormat_UInt32
}; };
enum struct SwapChainComposition : uint8 typedef uint8 SwapChainComposition;
enum SwapChainComposition_Enum
{ {
SDR, SwapChainComposition_SDR,
SDR_LINEAR, SwapChainComposition_SDR_LINEAR,
HDR_EXTENDED_LINEAR, SwapChainComposition_HDR_EXTENDED_LINEAR,
HDR10_ST2084 SwapChainComposition_HDR10_ST2084
}; };
// PresentMode from highest to lowest latency // PresentMode from highest to lowest latency
// Vsync prevents tearing. Enqueue ready images. // Vsync prevents tearing. Enqueue ready images.
// Mailbox prevents tearing. When image is ready, replace any pending image // Mailbox prevents tearing. When image is ready, replace any pending image
// Immediate replace current image as soon as possible. Can cause tearing // Immediate replace current image as soon as possible. Can cause tearing
enum struct PresentMode : uint8 typedef uint8 PresentMode;
enum PresentMode_Enum
{ {
VSync, PresentMode_VSync,
Mailbox, PresentMode_Mailbox,
Immediate PresentMode_Immediate
}; };
typedef struct GraphicsViewPort GraphicsViewPort;
struct GraphicsViewPort struct GraphicsViewPort
{ {
float X; float X;
@@ -88,87 +95,85 @@ struct GraphicsViewPort
}; };
extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config); extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config);
extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device); extern JULIET_API void DestroyGraphicsDevice(GraphicsDevice* device);
// Attach To Window // Attach To Window
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); extern JULIET_API bool8 AttachToWindow(GraphicsDevice* device, Window* window);
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); extern JULIET_API void DetachFromWindow(GraphicsDevice* device, Window* window);
// SwapChain // SwapChain
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, extern JULIET_API bool8 AcquireSwapChainTexture(CommandList* commandList, Window* window, Texture** swapChainTexture);
Texture** swapChainTexture); extern JULIET_API bool8 WaitAndAcquireSwapChainTexture(CommandList* commandList, Window* window, Texture** swapChainTexture);
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList, extern JULIET_API bool8 WaitForSwapchain(GraphicsDevice* device, Window* window);
NonNullPtr<Window> window, Texture** swapChainTexture); extern JULIET_API TextureFormat GetSwapChainTextureFormat(GraphicsDevice* device, Window* window);
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// Textures // Textures
extern JULIET_API Texture* CreateTexture(NonNullPtr<GraphicsDevice> device, const TextureCreateInfo& createInfo); extern JULIET_API Texture* CreateTexture(GraphicsDevice* device, const TextureCreateInfo* createInfo);
extern JULIET_API void DestroyTexture(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture); extern JULIET_API void DestroyTexture(GraphicsDevice* device, Texture* texture);
// Command List // Command List
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics); extern JULIET_API CommandList* AcquireCommandList(GraphicsDevice* device, QueueType queueType);
extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList); extern JULIET_API void SubmitCommandLists(CommandList* commandList);
// RenderPass // RenderPass
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo, extern JULIET_API RenderPass* BeginRenderPass(CommandList* commandList, const ColorTargetInfo* colorTargetInfo,
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr); DepthStencilTargetInfo* depthStencilTargetInfo);
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, extern JULIET_API RenderPass* BeginRenderPassTargets(CommandList* commandList,
NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount, const ColorTargetInfo* colorTargetInfos, uint32 colorTargetInfoCount,
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr); DepthStencilTargetInfo* depthStencilTargetInfo);
extern JULIET_API void EndRenderPass(NonNullPtr<RenderPass> renderPass); extern JULIET_API void EndRenderPass(RenderPass* renderPass);
extern JULIET_API void SetGraphicsViewPort(NonNullPtr<RenderPass> renderPass, const GraphicsViewPort& viewPort); extern JULIET_API void SetGraphicsViewPort(RenderPass* renderPass, const GraphicsViewPort* viewPort);
extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const struct Rectangle& rectangle); extern JULIET_API void SetScissorRect(RenderPass* renderPass, const struct Rectangle* rectangle);
extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants); extern JULIET_API void SetBlendConstants(RenderPass* renderPass, FColor blendConstants);
extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference); extern JULIET_API void SetStencilReference(RenderPass* renderPass, uint8 reference);
extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline); extern JULIET_API void BindGraphicsPipeline(RenderPass* renderPass, GraphicsPipeline* graphicsPipeline);
extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances, extern JULIET_API void DrawPrimitives(RenderPass* renderPass, uint32 numVertices, uint32 numInstances,
uint32 firstVertex, uint32 firstInstance); uint32 firstVertex, uint32 firstInstance);
extern JULIET_API void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances, extern JULIET_API void DrawIndexedPrimitives(RenderPass* renderPass, uint32 numIndices, uint32 numInstances,
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance); uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
extern JULIET_API void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, extern JULIET_API void SetIndexBuffer(CommandList* commandList, GraphicsBuffer* buffer,
IndexFormat format, size_t indexCount, index_t offset); IndexFormat format, size_t indexCount, index_t offset);
extern JULIET_API void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, extern JULIET_API void SetPushConstants(CommandList* commandList, ShaderStage stage,
uint32 rootParameterIndex, uint32 numConstants, const void* constants); uint32 rootParameterIndex, uint32 numConstants, const void* constants);
// Fences // Fences
extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device); extern JULIET_API bool8 WaitUntilGPUIsIdle(GraphicsDevice* device);
// Shaders // Shaders
extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo); extern JULIET_API Shader* CreateShader(GraphicsDevice* device, String filename, ShaderCreateInfo* shaderCreateInfo);
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader); extern JULIET_API void DestroyShader(GraphicsDevice* device, Shader* shader);
// Pipelines // Pipelines
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device, extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(GraphicsDevice* device,
const GraphicsPipelineCreateInfo& createInfo); const GraphicsPipelineCreateInfo* createInfo);
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline); extern JULIET_API void DestroyGraphicsPipeline(GraphicsDevice* device, 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 bool8 UpdateGraphicsPipelineShaders(GraphicsDevice* device, 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(GraphicsDevice* device, const BufferCreateInfo* createInfo);
extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(GraphicsDevice* device,
const TransferBufferCreateInfo& createInfo); const TransferBufferCreateInfo* createInfo);
extern JULIET_API void* MapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void* MapGraphicsBuffer(GraphicsDevice* device, GraphicsBuffer* buffer);
extern JULIET_API void UnmapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void UnmapGraphicsBuffer(GraphicsDevice* device, GraphicsBuffer* buffer);
extern JULIET_API void* MapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void* MapGraphicsTransferBuffer(GraphicsDevice* device, GraphicsTransferBuffer* buffer);
extern JULIET_API void UnmapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void UnmapGraphicsTransferBuffer(GraphicsDevice* device, GraphicsTransferBuffer* buffer);
extern JULIET_API void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst, extern JULIET_API void CopyBuffer(CommandList* commandList, GraphicsBuffer* dst,
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset = 0, GraphicsTransferBuffer* src, size_t size, size_t dstOffset,
size_t srcOffset = 0); size_t srcOffset);
extern JULIET_API void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst, extern JULIET_API void CopyBufferToTexture(CommandList* commandList, Texture* dst,
NonNullPtr<GraphicsTransferBuffer> src); GraphicsTransferBuffer* src);
extern JULIET_API void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void TransitionBufferToReadable(CommandList* commandList, GraphicsBuffer* buffer);
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API uint32 GetBufferDescriptorIndex(GraphicsDevice* device, GraphicsBuffer* buffer);
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture); extern JULIET_API uint32 GetTextureDescriptorIndex(GraphicsDevice* device, Texture* texture);
extern JULIET_API void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void DestroyGraphicsBuffer(GraphicsDevice* device, GraphicsBuffer* buffer);
extern JULIET_API void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void DestroyGraphicsTransferBuffer(GraphicsDevice* device, GraphicsTransferBuffer* buffer);
+18 -12
View File
@@ -1,27 +1,33 @@
#pragma once #pragma once
enum class BufferUsage : uint8 #include <Core/Common/CoreTypes.h>
typedef uint8 BufferUsage;
enum BufferUsage_Enum
{ {
None = 0, BufferUsage_None = 0,
IndexBuffer = 1 << 0, BufferUsage_IndexBuffer = 1 << 0,
ConstantBuffer = 1 << 1, BufferUsage_ConstantBuffer = 1 << 1,
StructuredBuffer = 1 << 2, BufferUsage_StructuredBuffer = 1 << 2,
}; };
enum class TransferBufferUsage : uint8 typedef uint8 TransferBufferUsage;
enum TransferBufferUsage_Enum
{ {
Download, TransferBufferUsage_Download,
Upload TransferBufferUsage_Upload
}; };
typedef struct BufferCreateInfo BufferCreateInfo;
struct BufferCreateInfo struct BufferCreateInfo
{ {
size_t Size; size_t Size;
size_t Stride; size_t Stride;
BufferUsage Usage; BufferUsage Usage;
bool IsDynamic; bool8 IsDynamic;
}; };
typedef struct TransferBufferCreateInfo TransferBufferCreateInfo;
struct TransferBufferCreateInfo struct TransferBufferCreateInfo
{ {
size_t Size; size_t Size;
@@ -29,5 +35,5 @@ struct TransferBufferCreateInfo
}; };
// Opaque // Opaque
struct GraphicsBuffer; typedef struct GraphicsBuffer GraphicsBuffer;
struct GraphicsTransferBuffer; typedef struct GraphicsTransferBuffer GraphicsTransferBuffer;
+9 -5
View File
@@ -1,19 +1,23 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h>
#if JULIET_DEBUG #if JULIET_DEBUG
#define ALLOW_SHADER_HOT_RELOAD 1 #define ALLOW_SHADER_HOT_RELOAD 1
#else #else
#define ALLOW_SHADER_HOT_RELOAD 0 #define ALLOW_SHADER_HOT_RELOAD 0
#endif #endif
enum class GraphicsDriverType : uint8 typedef uint8 GraphicsDriverType;
enum GraphicsDriverType_Enum
{ {
Any = 0, GraphicsDriverType_Any = 0,
DX12 = 1, GraphicsDriverType_DX12 = 1,
}; };
typedef struct GraphicsConfig GraphicsConfig;
struct GraphicsConfig struct GraphicsConfig
{ {
GraphicsDriverType PreferredDriver = GraphicsDriverType::DX12; GraphicsDriverType PreferredDriver;
bool EnableDebug; bool8 EnableDebug;
}; };
+112 -96
View File
@@ -1,42 +1,47 @@
#pragma once #pragma once
#include <Graphics/Shader.h> #include <Graphics/Shader.h>
#include <Graphics/Texture.h> #include <Graphics/Texture.h>
// Forward Declare // Forward Declare
struct ColorTargetDescription; typedef struct ColorTargetDescription ColorTargetDescription;
enum class FillMode : uint8 typedef uint8 FillMode;
enum FillMode_Enum
{ {
Solid, FillMode_Solid,
Wireframe, FillMode_Wireframe,
Count FillMode_Count
}; };
enum class CullMode : uint8 typedef uint8 CullMode;
enum CullMode_Enum
{ {
None, CullMode_None,
Front, CullMode_Front,
Back, CullMode_Back,
Count CullMode_Count
}; };
enum class FrontFace : uint8 typedef uint8 FrontFace;
enum FrontFace_Enum
{ {
CounterClockwise, FrontFace_CounterClockwise,
Clockwise, FrontFace_Clockwise,
Count FrontFace_Count
}; };
enum class PrimitiveType : uint8 typedef uint8 PrimitiveType;
enum PrimitiveType_Enum
{ {
TriangleList, PrimitiveType_TriangleList,
TriangleStrip, PrimitiveType_TriangleStrip,
LineList, PrimitiveType_LineList,
LineStrip, PrimitiveType_LineStrip,
PointList, PrimitiveType_PointList,
Count PrimitiveType_Count
}; };
typedef struct RasterizerState RasterizerState;
struct RasterizerState struct RasterizerState
{ {
FillMode FillMode; FillMode FillMode;
@@ -46,87 +51,90 @@ struct RasterizerState
float DepthBiasConstantFactor; // How much depth value is added to each fragment float DepthBiasConstantFactor; // How much depth value is added to each fragment
float DepthBiasClamp; // Maximum depth bias float DepthBiasClamp; // Maximum depth bias
float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope
bool EnableDepthBias; // Bias fragment depth values bool8 EnableDepthBias; // Bias fragment depth values
bool EnableDepthClip; // True to clip, false to clamp bool8 EnableDepthClip; // True to clip, false to clamp
}; };
enum class VertexInputRate : uint8 typedef uint8 VertexInputRate;
enum VertexInputRate_Enum
{ {
Vertex, // Use vertex index VertexInputRate_Vertex, // Use vertex index
Instance, // Use instance index VertexInputRate_Instance, // Use instance index
Count VertexInputRate_Count
}; };
typedef struct VertexBufferDescription VertexBufferDescription;
struct VertexBufferDescription struct VertexBufferDescription
{ {
uint32 Slot; // Binding Slot uint32 Slot; // Binding Slot
uint32 PitchInBytes; // Pitch between two elements uint32 PitchInBytes; // Pitch between two elements
VertexInputRate InputRate; VertexInputRate InputRate;
uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1 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 typedef uint8 VertexElementFormat;
enum VertexElementFormat_Enum
{ {
Invalid, VertexElementFormat_Invalid,
/* 32-bit Signed Integers */ /* 32-bit Signed Integers */
Int, VertexElementFormat_Int,
Int2, VertexElementFormat_Int2,
Int3, VertexElementFormat_Int3,
Int4, VertexElementFormat_Int4,
/* 32-bit Unsigned Integers */ /* 32-bit Unsigned Integers */
UInt, VertexElementFormat_UInt,
UInt2, VertexElementFormat_UInt2,
UInt3, VertexElementFormat_UInt3,
UInt4, VertexElementFormat_UInt4,
/* 32-bit Floats */ /* 32-bit Floats */
Float, VertexElementFormat_Float,
Float2, VertexElementFormat_Float2,
Float3, VertexElementFormat_Float3,
Float4, VertexElementFormat_Float4,
/* 8-bit Signed Integers */ /* 8-bit Signed Integers */
Byte2, VertexElementFormat_Byte2,
Byte4, VertexElementFormat_Byte4,
/* 8-bit Unsigned Integers */ /* 8-bit Unsigned Integers */
UByte2, VertexElementFormat_UByte2,
UByte4, VertexElementFormat_UByte4,
/* 8-bit Signed Normalized */ /* 8-bit Signed Normalized */
Byte2_Norm, VertexElementFormat_Byte2_Norm,
Byte4_Norm, VertexElementFormat_Byte4_Norm,
/* 8-bit Unsigned Normalized */ /* 8-bit Unsigned Normalized */
UByte2_Norm, VertexElementFormat_UByte2_Norm,
UByte4_Norm, VertexElementFormat_UByte4_Norm,
/* 16-bit Signed Integers */ /* 16-bit Signed Integers */
Short2, VertexElementFormat_Short2,
Short4, VertexElementFormat_Short4,
/* 16-bit Unsigned Integers */ /* 16-bit Unsigned Integers */
UShort2, VertexElementFormat_UShort2,
UShort4, VertexElementFormat_UShort4,
/* 16-bit Signed Normalized */ /* 16-bit Signed Normalized */
Short2_Norm, VertexElementFormat_Short2_Norm,
Short4_Norm, VertexElementFormat_Short4_Norm,
/* 16-bit Unsigned Normalized */ /* 16-bit Unsigned Normalized */
UShort2_Norm, VertexElementFormat_UShort2_Norm,
UShort4_Norm, VertexElementFormat_UShort4_Norm,
/* 16-bit Floats */ /* 16-bit Floats */
Half2, VertexElementFormat_Half2,
Half4, VertexElementFormat_Half4,
// VertexElementFormat_Count
Count
}; };
typedef struct VertexAttribute VertexAttribute;
struct VertexAttribute struct VertexAttribute
{ {
uint32 Location; // Shader input location index uint32 Location; // Shader input location index
@@ -135,6 +143,7 @@ struct VertexAttribute
uint32 Offset; // Offset of this attribute relative to the start of the vertex element uint32 Offset; // Offset of this attribute relative to the start of the vertex element
}; };
typedef struct VertexInputState VertexInputState;
struct VertexInputState struct VertexInputState
{ {
const VertexBufferDescription* VertexBufferDescriptions; const VertexBufferDescription* VertexBufferDescriptions;
@@ -143,69 +152,76 @@ struct VertexInputState
uint32 NumVertexAttributes; uint32 NumVertexAttributes;
}; };
typedef struct GraphicsPipelineTargetInfo GraphicsPipelineTargetInfo;
struct GraphicsPipelineTargetInfo struct GraphicsPipelineTargetInfo
{ {
const ColorTargetDescription* ColorTargetDescriptions; const ColorTargetDescription* ColorTargetDescriptions;
size_t NumColorTargets; size_t NumColorTargets;
TextureFormat DepthStencilFormat; TextureFormat DepthStencilFormat;
bool HasDepthStencilTarget; bool8 HasDepthStencilTarget;
}; };
enum class CompareOperation : uint8 typedef uint8 CompareOperation;
enum CompareOperation_Enum
{ {
Invalid, CompareOperation_Invalid,
Never, // The comparison always evaluates false. CompareOperation_Never, // The comparison always evaluates false.
Less, // The comparison evaluates reference < test. CompareOperation_Less, // The comparison evaluates reference < test.
Equal, // The comparison evaluates reference == test. CompareOperation_Equal, // The comparison evaluates reference == test.
LessOrEqual, // The comparison evaluates reference <= test. CompareOperation_LessOrEqual, // The comparison evaluates reference <= test.
Greater, // The comparison evaluates reference > test. CompareOperation_Greater, // The comparison evaluates reference > test.
NotEqual, // The comparison evaluates reference != test. CompareOperation_NotEqual, // The comparison evaluates reference != test.
GreaterOrEqual, // The comparison evalutes reference >= test. CompareOperation_GreaterOrEqual, // The comparison evalutes reference >= test.
Always, // The comparison always evaluates true. CompareOperation_Always, // The comparison always evaluates true.
Count CompareOperation_Count
}; };
enum class StencilOperation : uint8 typedef uint8 StencilOperation;
enum StencilOperation_Enum
{ {
Invalid, StencilOperation_Invalid,
Keep, // Keeps the current value. StencilOperation_Keep, // Keeps the current value.
Zero, // Sets the value to 0. StencilOperation_Zero, // Sets the value to 0.
Replace, // Sets the value to reference. StencilOperation_Replace, // Sets the value to reference.
IncrementAndClamp, // Increments the current value and clamps to the maximum value. StencilOperation_IncrementAndClamp, // Increments the current value and clamps to the maximum value.
DecrementAndClamp, // Decrements the current value and clamps to 0. StencilOperation_DecrementAndClamp, // Decrements the current value and clamps to 0.
Invert, // Bitwise-inverts the current value. StencilOperation_Invert, // Bitwise-inverts the current value.
IncrementAndWrap, // Increments the current value and wraps back to 0. StencilOperation_IncrementAndWrap, // Increments the current value and wraps back to 0.
DecrementAndWrap, // Decrements the current value and wraps to the maximum value. StencilOperation_DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
Count StencilOperation_Count
}; };
typedef struct StencilOperationState StencilOperationState;
struct StencilOperationState struct StencilOperationState
{ {
StencilOperation FailOperation; // The action performed on samples that fail the stencil test. StencilOperation FailOperation; // The action performed on samples that fail the stencil test.
StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests. StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests.
StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test. StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test.
StencilOperation CompareOperation; // The comparison operator used in the stencil test. StencilOperation CompareOperation; // The comparison operator used in the stencil test.
}; };
typedef struct DepthStencilState DepthStencilState;
struct DepthStencilState struct DepthStencilState
{ {
CompareOperation CompareOperation; // The comparison operator used for depth testing. CompareOperation CompareOperation; // The comparison operator used for depth testing.
StencilOperationState BackStencilState; // The stencil op state for back-facing triangles. StencilOperationState BackStencilState; // The stencil op state for back-facing triangles.
StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles. StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles.
uint8 CompareMask; // Selects the bits of the stencil values participating 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. uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
bool EnableDepthTest : 1; // true enables the depth test. bool8 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. bool8 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. bool8 EnableStencilTest : 1; // true enables the stencil test.
}; };
typedef struct MultisampleState MultisampleState;
struct MultisampleState struct MultisampleState
{ {
TextureSampleCount SampleCount; TextureSampleCount SampleCount;
uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF
bool EnableMask; bool8 EnableMask;
}; };
typedef struct GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo;
struct GraphicsPipelineCreateInfo struct GraphicsPipelineCreateInfo
{ {
Shader* VertexShader; Shader* VertexShader;
@@ -219,4 +235,4 @@ struct GraphicsPipelineCreateInfo
}; };
// Opaque type // Opaque type
struct GraphicsPipeline; typedef struct GraphicsPipeline GraphicsPipeline;
+3 -3
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Juliet.h> #include <Juliet.h>
extern bool ImGuiRenderer_Initialize(GraphicsDevice* device); extern bool8 ImGuiRenderer_Initialize(GraphicsDevice* device);
extern void ImGuiRenderer_Shutdown(GraphicsDevice* device); extern void ImGuiRenderer_Shutdown(GraphicsDevice* device);
extern void ImGuiRenderer_NewFrame(); extern void ImGuiRenderer_NewFrame(void);
extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass); extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass);
+3 -2
View File
@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <Juliet.h>
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <Juliet.h>
typedef struct PointLight PointLight;
struct PointLight struct PointLight
{ {
Vector3 Position; Vector3 Position;
+11 -9
View File
@@ -1,17 +1,17 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
struct Arena; typedef struct Arena Arena;
struct Vertex; typedef struct Vertex Vertex;
using MeshAssetID = index_t; typedef index_t MeshAssetID;
using MaterialAssetID = index_t; typedef index_t MaterialAssetID;
using MeshInstanceID = index_t; typedef index_t MeshInstanceID;
typedef struct MeshAsset MeshAsset;
struct MeshAsset struct MeshAsset
{ {
String Name; String Name;
@@ -22,14 +22,16 @@ struct MeshAsset
index_t IndexOffset; index_t IndexOffset;
}; };
typedef struct MaterialAsset MaterialAsset;
struct MaterialAsset struct MaterialAsset
{ {
Vector4 AlbedoColor = { 1.0f, 1.0f, 1.0f, 1.0f }; Vector4 AlbedoColor;
}; };
typedef struct MeshInstance MeshInstance;
struct MeshInstance struct MeshInstance
{ {
MeshAssetID MeshAsset; MeshAssetID MeshAsset;
MaterialAssetID MaterialAsset; MaterialAssetID MaterialAsset;
Matrix Transform = MatrixIdentity(); Matrix Transform;
}; };
+36 -37
View File
@@ -1,57 +1,56 @@
#pragma once #pragma once
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
#include <Graphics/Lighting.h> #include <Graphics/Lighting.h>
#include <Graphics/Mesh.h>
#include <Graphics/PushConstants.h> #include <Graphics/PushConstants.h>
#include <Graphics/VertexData.h> #include <Graphics/VertexData.h>
#include <Graphics/Mesh.h>
#include <Juliet.h> #include <Juliet.h>
struct GraphicsTransferBuffer; typedef struct GraphicsTransferBuffer GraphicsTransferBuffer;
struct RenderPass; typedef struct RenderPass RenderPass;
struct CommandList; typedef struct CommandList CommandList;
struct GraphicsBuffer; typedef struct GraphicsBuffer GraphicsBuffer;
struct Window; typedef struct Window Window;
struct GraphicsPipeline; typedef struct GraphicsPipeline GraphicsPipeline;
struct GraphicsDevice; typedef struct GraphicsDevice GraphicsDevice;
using LightID = index_t; typedef index_t LightID;
constexpr size_t kGeometryPage = Megabytes(64); #define kGeometryPage Megabytes(64)
constexpr size_t kIndexPage = Megabytes(32); #define kIndexPage Megabytes(32)
constexpr size_t kDefaultMeshNumber = 500; #define kDefaultMeshNumber ((size_t)500)
constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page #define kDefaultVertexCount ((size_t)2000000)
constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page #define kDefaultIndexCount ((size_t)16000000)
constexpr size_t kDefaultLightCount = 1024; #define kDefaultLightCount ((size_t)1024)
JULIET_API void InitializeMeshRenderer(NonNullPtr<Arena> assetArena, NonNullPtr<Arena> instanceArena); JULIET_API void InitializeMeshRenderer(Arena* assetArena, Arena* instanceArena);
[[nodiscard]] JULIET_API bool InitializeMeshRendererGraphics(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); JULIET_API bool8 InitializeMeshRendererGraphics(GraphicsDevice* device, Window* window);
JULIET_API void ShutdownMeshRendererGraphics(); JULIET_API void ShutdownMeshRendererGraphics(void);
JULIET_API void ShutdownMeshRenderer(); JULIET_API void ShutdownMeshRenderer(void);
JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList); JULIET_API void LoadMeshesOnGPU(CommandList* cmdList);
JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection); JULIET_API void RenderMeshes(CommandList* cmdList, RenderPass* pass, const Matrix* viewProjection);
// Lights // Lights
[[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light); JULIET_API LightID AddPointLight(const PointLight* light);
JULIET_API void SetPointLightPosition(LightID id, const Vector3& position); JULIET_API void SetPointLightPosition(LightID id, Vector3 position);
JULIET_API void SetPointLightColor(LightID id, const Vector3& color); JULIET_API void SetPointLightColor(LightID id, 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(void);
JULIET_API void SetGlobalLight(const Vector3& direction, const Vector3& color, float ambientIntensity); JULIET_API void SetGlobalLight(Vector3 direction, Vector3 color, float ambientIntensity);
// Assets & Instances // Assets & Instances
[[nodiscard]] JULIET_API MeshAssetID GetOrCreateMeshAsset(String name); JULIET_API MeshAssetID GetOrCreateMeshAsset(String name);
[[nodiscard]] JULIET_API MeshInstanceID CreateMeshInstance(MeshAssetID meshAsset, MaterialAssetID materialAsset, const Matrix& transform); 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(void);
JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID(); JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID(void);
JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID(); JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID(void);
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
JULIET_API void ReloadMeshRendererShaders(); JULIET_API void ReloadMeshRendererShaders(void);
#endif #endif
+6 -5
View File
@@ -1,9 +1,10 @@
#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>
typedef struct PushData PushData;
struct PushData struct PushData
{ {
Matrix ViewProjection; Matrix ViewProjection;
@@ -21,9 +22,9 @@ struct PushData
Vector3 GlobalLightColor; Vector3 GlobalLightColor;
uint32 Pad2; uint32 Pad2;
float Scale[2]; float Scale[2];
float Translate[2]; float Translate[2];
Vector4 MeshAlbedo; Vector4 MeshAlbedo;
}; };
+63 -54
View File
@@ -1,23 +1,26 @@
#pragma once #pragma once
#include <Graphics/Colors.h> #include <Graphics/Colors.h>
#include <Graphics/Texture.h> #include <Graphics/Texture.h>
enum struct LoadOperation : uint8 typedef uint8 LoadOperation;
enum LoadOperation_Enum
{ {
Load, // Load the texture from memory (preserve) LoadOperation_Load, // Load the texture from memory (preserve)
Clear, // Clear the texture LoadOperation_Clear, // Clear the texture
Ignore // Ignore the content of the texture (undefined) LoadOperation_Ignore // Ignore the content of the texture (undefined)
}; };
enum struct StoreOperation : uint8 typedef uint8 StoreOperation;
enum StoreOperation_Enum
{ {
Store, // Store the result of the render pass into memory StoreOperation_Store, // Store the result of the render pass into memory
Ignore, // Whatever is generated is ignored (undefined) StoreOperation_Ignore, // Whatever is generated is ignored (undefined)
Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content StoreOperation_Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content
ResolveAndStore // Same but store the MipMap content to memory StoreOperation_ResolveAndStore // Same but store the MipMap content to memory
}; };
typedef struct ColorTargetInfo ColorTargetInfo;
struct ColorTargetInfo struct ColorTargetInfo
{ {
Texture* TargetTexture; Texture* TargetTexture;
@@ -27,81 +30,87 @@ struct ColorTargetInfo
uint32 DepthPlane; uint32 DepthPlane;
uint32 LayerIndex; uint32 LayerIndex;
}; };
bool CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD) bool8 CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD)
Texture* ResolveTexture; Texture* ResolveTexture;
uint32 ResolveMipLevel; uint32 ResolveMipLevel;
uint32 ResolveLayerIndex; uint32 ResolveLayerIndex;
bool CycleResolveTexture; bool8 CycleResolveTexture;
FColor ClearColor; FColor ClearColor;
LoadOperation LoadOperation; LoadOperation LoadOperation;
StoreOperation StoreOperation; StoreOperation StoreOperation;
}; };
typedef struct DepthStencilTargetInfo DepthStencilTargetInfo;
struct DepthStencilTargetInfo struct DepthStencilTargetInfo
{ {
Texture* TargetTexture; Texture* TargetTexture;
uint32 MipLevel; uint32 MipLevel;
uint32 LayerIndex; uint32 LayerIndex;
float ClearDepth; float ClearDepth;
uint8 ClearStencil; uint8 ClearStencil;
LoadOperation LoadOperation; LoadOperation LoadOperation;
StoreOperation StoreOperation; StoreOperation StoreOperation;
}; };
enum class BlendFactor : uint8 typedef uint8 BlendFactor;
enum BlendFactor_Enum
{ {
Invalid, BlendFactor_Invalid,
Zero, BlendFactor_Zero,
One, BlendFactor_One,
Src_Color, BlendFactor_Src_Color,
One_Minus_Src_Color, BlendFactor_One_Minus_Src_Color,
Dst_Color, BlendFactor_Dst_Color,
One_Minus_Dst_Color, BlendFactor_One_Minus_Dst_Color,
Src_Alpha, BlendFactor_Src_Alpha,
One_Minus_Src_Alpha, BlendFactor_One_Minus_Src_Alpha,
Dst_Alpha, BlendFactor_Dst_Alpha,
One_Minus_Dst_Alpha, BlendFactor_One_Minus_Dst_Alpha,
Constant_Color, BlendFactor_Constant_Color,
One_MINUS_Constant_Color, BlendFactor_One_MINUS_Constant_Color,
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha) BlendFactor_Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
Count BlendFactor_Count
}; };
enum class BlendOperation : uint8 typedef uint8 BlendOperation;
enum BlendOperation_Enum
{ {
Invalid, BlendOperation_Invalid,
Add, // (source * source_factor) + (destination * destination_factor) BlendOperation_Add, // (source * source_factor) + (destination * destination_factor)
Subtract, // (source * source_factor) - (destination * destination_factor) BlendOperation_Subtract, // (source * source_factor) - (destination * destination_factor)
ReverseSubtract, // (destination * destination_factor) - (source * source_factor) BlendOperation_ReverseSubtract, // (destination * destination_factor) - (source * source_factor)
Min, // min(source, destination) BlendOperation_Min, // min(source, destination)
Max, // max(source, destination) BlendOperation_Max, // max(source, destination)
Count BlendOperation_Count
}; };
enum class ColorComponentFlags : uint8 typedef uint8 ColorComponentFlags;
enum ColorComponentFlags_Enum
{ {
R = 1u << 0, ColorComponentFlags_R = 1u << 0,
G = 1u << 1, ColorComponentFlags_G = 1u << 1,
B = 1u << 2, ColorComponentFlags_B = 1u << 2,
A = 1u << 3 ColorComponentFlags_A = 1u << 3
}; };
typedef struct ColorTargetBlendState ColorTargetBlendState;
struct ColorTargetBlendState struct ColorTargetBlendState
{ {
BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value. BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value. BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
BlendOperation ColorBlendOperation; // The blend operation for the RGB components. BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha. BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha. BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
BlendOperation AlphaBlendOperation; // The blend operation for the alpha component. 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. 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. bool8 EnableBlend : 1; // Whether blending is enabled for the color target.
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled. bool8 EnableColorWriteMask : 1; // Whether the color write mask is enabled.
}; };
typedef struct ColorTargetDescription ColorTargetDescription;
struct ColorTargetDescription struct ColorTargetDescription
{ {
TextureFormat Format; TextureFormat Format;
@@ -109,4 +118,4 @@ struct ColorTargetDescription
}; };
// Opaque Type // Opaque Type
struct RenderPass; typedef struct RenderPass RenderPass;
+8 -7
View File
@@ -1,20 +1,21 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
// Opaque type // Opaque type
struct Shader; typedef struct Shader Shader;
enum class ShaderStage : uint8 typedef uint8 ShaderStage;
enum ShaderStage_Enum
{ {
Vertex, ShaderStage_Vertex,
Fragment, ShaderStage_Fragment,
Compute ShaderStage_Compute
}; };
typedef struct ShaderCreateInfo ShaderCreateInfo;
struct ShaderCreateInfo struct ShaderCreateInfo
{ {
ShaderStage Stage; ShaderStage Stage;
String EntryPoint; String EntryPoint;
}; };
+11 -12
View File
@@ -1,28 +1,27 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#include <Core/Common/NonNullPtr.h>
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
struct RenderPass; typedef struct RenderPass RenderPass;
struct CommandList; typedef struct CommandList CommandList;
struct Window; typedef struct Window Window;
struct GraphicsPipeline; typedef struct GraphicsPipeline GraphicsPipeline;
struct GraphicsDevice; typedef struct GraphicsDevice GraphicsDevice;
typedef struct SkyboxRenderer SkyboxRenderer;
struct SkyboxRenderer struct SkyboxRenderer
{ {
GraphicsDevice* Device; GraphicsDevice* Device;
GraphicsPipeline* Pipeline; GraphicsPipeline* Pipeline;
}; };
[[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); JULIET_API bool8 InitializeSkyboxRenderer(GraphicsDevice* device, Window* window);
JULIET_API void ShutdownSkyboxRenderer(); JULIET_API void ShutdownSkyboxRenderer(void);
JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection); JULIET_API void RenderSkybox(CommandList* cmdList, RenderPass* pass, const Matrix* viewProjection);
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
JULIET_API void ReloadSkyboxShaders(); JULIET_API void ReloadSkyboxShaders(void);
#endif #endif
+137 -131
View File
@@ -1,164 +1,170 @@
#pragma once #pragma once
enum struct TextureFormat : uint8 #include <Core/Common/CoreTypes.h>
typedef uint8 TextureFormat;
enum TextureFormat_Enum
{ {
Invalid, TextureFormat_Invalid,
/* Unsigned Normalized Float Color Formats */ /* Unsigned Normalized Float Color Formats */
A8_UNORM, TextureFormat_A8_UNORM,
R8_UNORM, TextureFormat_R8_UNORM,
R8G8_UNORM, TextureFormat_R8G8_UNORM,
R8G8B8A8_UNORM, TextureFormat_R8G8B8A8_UNORM,
R16_UNORM, TextureFormat_R16_UNORM,
R16G16_UNORM, TextureFormat_R16G16_UNORM,
R16G16B16A16_UNORM, TextureFormat_R16G16B16A16_UNORM,
R10G10B10A2_UNORM, TextureFormat_R10G10B10A2_UNORM,
B5G6R5_UNORM, TextureFormat_B5G6R5_UNORM,
B5G5R5A1_UNORM, TextureFormat_B5G5R5A1_UNORM,
B4G4R4A4_UNORM, TextureFormat_B4G4R4A4_UNORM,
B8G8R8A8_UNORM, TextureFormat_B8G8R8A8_UNORM,
/* Compressed Unsigned Normalized Float Color Formats */ /* Compressed Unsigned Normalized Float Color Formats */
BC1_RGBA_UNORM, TextureFormat_BC1_RGBA_UNORM,
BC2_RGBA_UNORM, TextureFormat_BC2_RGBA_UNORM,
BC3_RGBA_UNORM, TextureFormat_BC3_RGBA_UNORM,
BC4_R_UNORM, TextureFormat_BC4_R_UNORM,
BC5_RG_UNORM, TextureFormat_BC5_RG_UNORM,
BC7_RGBA_UNORM, TextureFormat_BC7_RGBA_UNORM,
/* Compressed Signed Float Color Formats */ /* Compressed Signed Float Color Formats */
BC6H_RGB_FLOAT, TextureFormat_BC6H_RGB_FLOAT,
/* Compressed Unsigned Float Color Formats */ /* Compressed Unsigned Float Color Formats */
BC6H_RGB_UFLOAT, TextureFormat_BC6H_RGB_UFLOAT,
/* Signed Normalized Float Color Formats */ /* Signed Normalized Float Color Formats */
R8_SNORM, TextureFormat_R8_SNORM,
R8G8_SNORM, TextureFormat_R8G8_SNORM,
R8G8B8A8_SNORM, TextureFormat_R8G8B8A8_SNORM,
R16_SNORM, TextureFormat_R16_SNORM,
R16G16_SNORM, TextureFormat_R16G16_SNORM,
R16G16B16A16_SNORM, TextureFormat_R16G16B16A16_SNORM,
/* Signed Float Color Formats */ /* Signed Float Color Formats */
R16_FLOAT, TextureFormat_R16_FLOAT,
R16G16_FLOAT, TextureFormat_R16G16_FLOAT,
R16G16B16A16_FLOAT, TextureFormat_R16G16B16A16_FLOAT,
R32_FLOAT, TextureFormat_R32_FLOAT,
R32G32_FLOAT, TextureFormat_R32G32_FLOAT,
R32G32B32A32_FLOAT, TextureFormat_R32G32B32A32_FLOAT,
/* Unsigned Float Color Formats */ /* Unsigned Float Color Formats */
R11G11B10_UFLOAT, TextureFormat_R11G11B10_UFLOAT,
/* Unsigned Integer Color Formats */ /* Unsigned Integer Color Formats */
R8_UINT, TextureFormat_R8_UINT,
R8G8_UINT, TextureFormat_R8G8_UINT,
R8G8B8A8_UINT, TextureFormat_R8G8B8A8_UINT,
R16_UINT, TextureFormat_R16_UINT,
R16G16_UINT, TextureFormat_R16G16_UINT,
R16G16B16A16_UINT, TextureFormat_R16G16B16A16_UINT,
R32_UINT, TextureFormat_R32_UINT,
R32G32_UINT, TextureFormat_R32G32_UINT,
R32G32B32A32_UINT, TextureFormat_R32G32B32A32_UINT,
/* Signed Integer Color Formats */ /* Signed Integer Color Formats */
R8_INT, TextureFormat_R8_INT,
R8G8_INT, TextureFormat_R8G8_INT,
R8G8B8A8_INT, TextureFormat_R8G8B8A8_INT,
R16_INT, TextureFormat_R16_INT,
R16G16_INT, TextureFormat_R16G16_INT,
R16G16B16A16_INT, TextureFormat_R16G16B16A16_INT,
R32_INT, TextureFormat_R32_INT,
R32G32_INT, TextureFormat_R32G32_INT,
R32G32B32A32_INT, TextureFormat_R32G32B32A32_INT,
/* SRGB Unsigned Normalized Color Formats */ /* SRGB Unsigned Normalized Color Formats */
R8G8B8A8_UNORM_SRGB, TextureFormat_R8G8B8A8_UNORM_SRGB,
B8G8R8A8_UNORM_SRGB, TextureFormat_B8G8R8A8_UNORM_SRGB,
/* Compressed SRGB Unsigned Normalized Color Formats */ /* Compressed SRGB Unsigned Normalized Color Formats */
BC1_RGBA_UNORM_SRGB, TextureFormat_BC1_RGBA_UNORM_SRGB,
BC2_RGBA_UNORM_SRGB, TextureFormat_BC2_RGBA_UNORM_SRGB,
BC3_RGBA_UNORM_SRGB, TextureFormat_BC3_RGBA_UNORM_SRGB,
BC7_RGBA_UNORM_SRGB, TextureFormat_BC7_RGBA_UNORM_SRGB,
/* Depth Formats */ /* Depth Formats */
D16_UNORM, TextureFormat_D16_UNORM,
D24_UNORM, TextureFormat_D24_UNORM,
D32_FLOAT, TextureFormat_D32_FLOAT,
D24_UNORM_S8_UINT, TextureFormat_D24_UNORM_S8_UINT,
D32_FLOAT_S8_UINT, TextureFormat_D32_FLOAT_S8_UINT,
/* Compressed ASTC Normalized Float Color Formats*/ /* Compressed ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM, TextureFormat_ASTC_4x4_UNORM,
ASTC_5x4_UNORM, TextureFormat_ASTC_5x4_UNORM,
ASTC_5x5_UNORM, TextureFormat_ASTC_5x5_UNORM,
ASTC_6x5_UNORM, TextureFormat_ASTC_6x5_UNORM,
ASTC_6x6_UNORM, TextureFormat_ASTC_6x6_UNORM,
ASTC_8x5_UNORM, TextureFormat_ASTC_8x5_UNORM,
ASTC_8x6_UNORM, TextureFormat_ASTC_8x6_UNORM,
ASTC_8x8_UNORM, TextureFormat_ASTC_8x8_UNORM,
ASTC_10x5_UNORM, TextureFormat_ASTC_10x5_UNORM,
ASTC_10x6_UNORM, TextureFormat_ASTC_10x6_UNORM,
ASTC_10x8_UNORM, TextureFormat_ASTC_10x8_UNORM,
ASTC_10x10_UNORM, TextureFormat_ASTC_10x10_UNORM,
ASTC_12x10_UNORM, TextureFormat_ASTC_12x10_UNORM,
ASTC_12x12_UNORM, TextureFormat_ASTC_12x12_UNORM,
/* Compressed SRGB ASTC Normalized Float Color Formats*/ /* Compressed SRGB ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM_SRGB, TextureFormat_ASTC_4x4_UNORM_SRGB,
ASTC_5x4_UNORM_SRGB, TextureFormat_ASTC_5x4_UNORM_SRGB,
ASTC_5x5_UNORM_SRGB, TextureFormat_ASTC_5x5_UNORM_SRGB,
ASTC_6x5_UNORM_SRGB, TextureFormat_ASTC_6x5_UNORM_SRGB,
ASTC_6x6_UNORM_SRGB, TextureFormat_ASTC_6x6_UNORM_SRGB,
ASTC_8x5_UNORM_SRGB, TextureFormat_ASTC_8x5_UNORM_SRGB,
ASTC_8x6_UNORM_SRGB, TextureFormat_ASTC_8x6_UNORM_SRGB,
ASTC_8x8_UNORM_SRGB, TextureFormat_ASTC_8x8_UNORM_SRGB,
ASTC_10x5_UNORM_SRGB, TextureFormat_ASTC_10x5_UNORM_SRGB,
ASTC_10x6_UNORM_SRGB, TextureFormat_ASTC_10x6_UNORM_SRGB,
ASTC_10x8_UNORM_SRGB, TextureFormat_ASTC_10x8_UNORM_SRGB,
ASTC_10x10_UNORM_SRGB, TextureFormat_ASTC_10x10_UNORM_SRGB,
ASTC_12x10_UNORM_SRGB, TextureFormat_ASTC_12x10_UNORM_SRGB,
ASTC_12x12_UNORM_SRGB, TextureFormat_ASTC_12x12_UNORM_SRGB,
/* Compressed ASTC Signed Float Color Formats*/ /* Compressed ASTC Signed Float Color Formats*/
ASTC_4x4_FLOAT, TextureFormat_ASTC_4x4_FLOAT,
ASTC_5x4_FLOAT, TextureFormat_ASTC_5x4_FLOAT,
ASTC_5x5_FLOAT, TextureFormat_ASTC_5x5_FLOAT,
ASTC_6x5_FLOAT, TextureFormat_ASTC_6x5_FLOAT,
ASTC_6x6_FLOAT, TextureFormat_ASTC_6x6_FLOAT,
ASTC_8x5_FLOAT, TextureFormat_ASTC_8x5_FLOAT,
ASTC_8x6_FLOAT, TextureFormat_ASTC_8x6_FLOAT,
ASTC_8x8_FLOAT, TextureFormat_ASTC_8x8_FLOAT,
ASTC_10x5_FLOAT, TextureFormat_ASTC_10x5_FLOAT,
ASTC_10x6_FLOAT, TextureFormat_ASTC_10x6_FLOAT,
ASTC_10x8_FLOAT, TextureFormat_ASTC_10x8_FLOAT,
ASTC_10x10_FLOAT, TextureFormat_ASTC_10x10_FLOAT,
ASTC_12x10_FLOAT, TextureFormat_ASTC_12x10_FLOAT,
ASTC_12x12_FLOAT, TextureFormat_ASTC_12x12_FLOAT,
Count TextureFormat_Count
}; };
enum struct TextureUsageFlag : uint8 typedef uint8 TextureUsageFlag;
enum TextureUsageFlag_Enum
{ {
None = 0, TextureUsageFlag_None = 0,
Sampler = 1 << 0, // Textures supports sampling TextureUsageFlag_Sampler = 1 << 0,
ColorTarget = 1 << 1, // Texture is color render target TextureUsageFlag_ColorTarget = 1 << 1,
DepthStencilTarget = 1 << 2, // Texture is depth stencil target TextureUsageFlag_DepthStencilTarget = 1 << 2,
GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage TextureUsageFlag_GraphicsStorageRead = 1 << 3,
ComputeStorageRead = 1 << 4, // Support Storage read at compute stage TextureUsageFlag_ComputeStorageRead = 1 << 4,
ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage TextureUsageFlag_ComputeStorageWrite = 1 << 5,
ComputeStorageSimultaneousReadWrite = TextureUsageFlag_ComputeStorageSimultaneousReadWrite = 1 << 6,
1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
}; };
enum struct TextureType : uint8 typedef uint8 TextureType;
enum TextureType_Enum
{ {
Texture_2D, TextureType_2D,
Texture_2DArray, TextureType_2DArray,
Texture_3D, TextureType_3D,
Texture_3DArray, TextureType_3DArray,
Texture_Cube, TextureType_Cube,
Texture_CubeArray, TextureType_CubeArray,
}; };
enum struct TextureSampleCount : uint8 typedef uint8 TextureSampleCount;
enum TextureSampleCount_Enum
{ {
One, TextureSampleCount_One,
Two, TextureSampleCount_Two,
Four, TextureSampleCount_Four,
Eight, TextureSampleCount_Eight,
}; };
// Create Information structs // Create Information structs
typedef struct TextureCreateInfo TextureCreateInfo;
struct TextureCreateInfo struct TextureCreateInfo
{ {
TextureType Type; TextureType Type;
@@ -177,4 +183,4 @@ struct TextureCreateInfo
}; };
// Opaque Type // Opaque Type
struct Texture; typedef struct Texture Texture;
+5 -2
View File
@@ -1,5 +1,8 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h>
typedef struct Vertex Vertex;
struct Vertex struct Vertex
{ {
float Position[3]; float Position[3];
@@ -7,4 +10,4 @@ struct Vertex
float Color[4]; float Color[4];
}; };
using Index = uint16; typedef uint16 Index;
+1 -1
View File
@@ -15,7 +15,7 @@
#define JULIET_API #define JULIET_API
# endif # endif
# else # else
# define JULIET_API (void) // Only Win32 is supported for now # define JULIET_API
# endif # endif
#endif #endif
@@ -1,17 +0,0 @@
#include <Core/Application/ApplicationManager.h>
#include <Core/JulietInit.h>
#include <Engine/Engine.h>
void StartApplication(IApplication& app, JulietInit_Flags flags)
{
InitializeEngine(flags);
LoadApplication(app);
RunEngine();
UnloadApplication();
ShutdownEngine();
}
Loaded 100 of 375 files, more files were not shown because too many files have changed in this diff. Show more