This commit is contained in:
YourWishes committed 2026-11-07 16:17:36 -06:00
1 parent 12dade2ef6
commit 1dcb97b2f0
44 files changed
-2301

No files matched your search

-52
View File
@@ -1,52 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
find_package(glm REQUIRED)
find_package(libzip REQUIRED)
# Libs
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
m
glm
zip
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
main.cpp
)
# Subdirs
add_subdirectory(assert)
add_subdirectory(asset)
add_subdirectory(console)
add_subdirectory(display)
add_subdirectory(engine)
add_subdirectory(input)
add_subdirectory(rpg)
add_subdirectory(time)
# Platform-specific settings
if(DAWN_TARGET_SYSTEM STREQUAL "linux")
target_compile_definitions(${DAWN_TARGET_NAME}
PRIVATE
DAWN_SDL2=1
DAWN_SDL2_GAMEPAD=1
)
elseif(DAWN_TARGET_SYSTEM STREQUAL "psp")
target_compile_definitions(${DAWN_TARGET_NAME}
PRIVATE
DAWN_SDL2=1
DAWN_SDL2_GAMEPAD=1
)
endif()
-85
View File
@@ -1,85 +0,0 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "Assert.hpp"
#ifndef ASSERTIONS_FAKED
void assertTrueImpl(
const char_t *file,
const int32_t line,
const bool_t x,
const char_t *message
) {
if(x != true) {
fprintf(
stderr,
"Assertion Failed in %s:%i\n\n%s\n",
file,
line,
message
);
abort();
}
}
void assertFalseImpl(
const char_t *file,
const int32_t line,
bool_t x,
const char_t *message
) {
assertTrueImpl(file, line, !x, message);
}
void assertUnreachableImpl(
const char_t *file,
const int32_t line,
const char_t *message
) {
assertTrueImpl(file, line, false, message);
}
void assertNotNullImpl(
const char_t *file,
const int32_t line,
const void *pointer,
const char_t *message
) {
assertTrueImpl(
file,
line,
pointer != NULL && pointer != nullptr,
message
);
// Ensure we can touch it
volatile char_t temp;
temp = *((char_t*)pointer);
}
void assertNullImpl(
const char_t *file,
const int32_t line,
const void *pointer,
const char_t *message
) {
assertTrueImpl(
file,
line,
pointer == NULL,
message
);
}
void assertDeprecatedImpl(
const char_t *file,
const int32_t line,
const char_t *message
) {
assertUnreachableImpl(file, line, message);
}
#endif
-143
View File
@@ -1,143 +0,0 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.hpp"
#ifndef ASSERTIONS_FAKED
/**
* Assert a given value to be true.
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param x Value to assert as true.
* @param message Message to throw against assertion failure.
*/
void assertTrueImpl(
const char_t *file,
const int32_t line,
const bool_t x,
const char_t *message
);
/**
* Asserts a given statement to be false.
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param x Value to assert as false.
* @param message Message to throw against assertion failure.
*/
void assertFalseImpl(
const char_t *file,
const int32_t line,
const bool_t x,
const char_t *message
);
/**
* Asserts that a given line of code is unreachable. Essentially a forced
* assertion failure, good for "edge cases"
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param message Message to throw against assertion failure.
*/
void assertUnreachableImpl(
const char_t *file,
const int32_t line,
const char_t *message
);
/**
* Assert a given pointer to not point to a null pointer.
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param pointer Pointer to assert is not a null pointer.
* @param message Message to throw against assertion failure.
*/
void assertNotNullImpl(
const char_t *file,
const int32_t line,
const void *pointer,
const char_t *message
);
/**
* Asserts a given pointer to be a nullptr.
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param pointer Pointer to assert is nullptr.
* @param message Message to throw against assertion failure.
*/
void assertNullImpl(
const char_t *file,
const int32_t line,
const void *pointer,
const char_t *message
);
/**
* Asserts a function as being deprecated.
*
* @param file File that the assertion is being made from.
* @param line Line that the assertion is being made from.
* @param message Message to throw against assertion failure.
*/
void assertDeprecatedImpl(
const char_t *file,
const int32_t line,
const char_t *message
);
void assertMemoryRangeMatchesImpl(
const char_t *file,
const int32_t line,
const void *start,
const void *end,
const size_t size,
const char_t *message
);
#define assertTrue(x, message) \
assertTrueImpl(__FILE__, __LINE__, x, message)
#define assertFalse(x, message) \
assertFalseImpl(__FILE__, __LINE__, x, message)
#define assertUnreachable(message) \
assertUnreachableImpl(__FILE__, __LINE__, message)
#define assertNotNull(pointer, message) \
assertNotNullImpl(__FILE__, __LINE__, pointer, message)
#define assertNull(pointer, message) \
assertNullImpl(__FILE__, __LINE__, pointer, message)
#define assertDeprecated(message) \
assertDeprecatedImpl(__FILE__, __LINE__, message)
#define assertStrLenMax(str, len, message) \
assertTrue(strlen(str) < len, message)
#define assertStrLenMin(str, len, message) \
assertTrue(strlen(str) >= len, message)
#else
// If assertions are faked, we define the macros to do nothing.
#define assertTrue(x, message) ((void)0)
#define assertFalse(x, message) ((void)0)
#define assertUnreachable(message) ((void)0)
#define assertNotNull(pointer, message) ((void)0)
#define assertNull(pointer, message) ((void)0)
#define assertDeprecated(message) ((void)0)
#define assertStrLenMax(str, len, message) ((void)0)
#define assertStrLenMin(str, len, message) ((void)0)
#endif
-10
View File
@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Assert.cpp
)
-16
View File
@@ -1,16 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Asset.hpp"
using namespace Dawn;
Asset::Asset(const std::string &filename) :
filename(filename)
{
}
Asset::~Asset() {
}
-19
View File
@@ -1,19 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include <zip.h>
namespace Dawn {
struct Asset {
private:
std::string filename;
public:
Asset(const std::string &filename);
~Asset();
};
}
-21
View File
@@ -1,21 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "AssetManager.hpp"
using namespace Dawn;
AssetManager::AssetManager() :
zip(nullptr)
{
// Find the zip file.
}
AssetManager::~AssetManager() {
if(zip) {
zip_close(zip);
zip = nullptr;
}
}
-25
View File
@@ -1,25 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Asset.hpp"
namespace Dawn {
struct AssetManager {
private:
zip_t *zip;
public:
/**
* Constructor for the Asset manager.
*/
AssetManager();
/**
* Destructor for the Asset manager.
*/
~AssetManager();
};
}
-11
View File
@@ -1,11 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Asset.cpp
AssetManager.cpp
)
-10
View File
@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Console.cpp
)
-167
View File
@@ -1,167 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Console.hpp"
#include "assert/Assert.hpp"
using namespace Dawn;
Console::Console(void) :
commands(),
variables(),
buffer()
{
this->registerCommand("echo", [](auto console, auto args) {
if(args.size() == 0) {
console.print("Usage: echo <message>");
return;
}
console.print("%s", args[0].c_str());
});
}
void Console::registerCommand(
const std::string &cmd,
const std::function<void(Console&, const std::vector<std::string>&)> &cb
) {
assertTrue(cmd.length() > 0, "cmd length must be > 0");
assertTrue(cb != nullptr, "callback must not be null");
this->commands[cmd] = cb;
}
template<typename T>
void Console::registerVariable(
const std::string &var,
const std::function<T()> &getter,
const std::function<void(const T &)> &setter
) {
assertTrue(var.length() > 0, "var length must be > 0");
assertTrue(getter != nullptr, "getter must not be null");
assertTrue(setter != nullptr, "setter must not be null");
this->variables[var] = std::make_pair(getter, setter);
}
void Console::update() {
enum class ParseState { FIND_CMD, FIND_ARG, COMMAND, ARG, ARG_QUOTED };
for (const auto &cmd : buffer) {
std::string cmdName;
std::vector<std::string> args;
ParseState state = ParseState::FIND_CMD;
std::string buff;
for(size_t i = 0; i < cmd.length(); i++) {
char_t c = cmd[i];
switch(state) {
case ParseState::FIND_CMD:
if(isspace(c)) continue;
state = ParseState::COMMAND;
buff += c;
break;
case ParseState::FIND_ARG:
if(isspace(c)) continue;
if(c == '\"') {
state = ParseState::ARG_QUOTED;
break;
}
state = ParseState::ARG;
buff += c;
break;
case ParseState::COMMAND:
if(isspace(c)) {
cmdName = buff;
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
case ParseState::ARG:
if(isspace(c)) {
args.push_back(buff);
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
case ParseState::ARG_QUOTED:
if(c == '\"') {
args.push_back(buff);
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
}
}
if(buff.length() > 0) {
if(state == ParseState::COMMAND) {
cmdName = buff;
} else {
args.push_back(buff);
}
}
// Find command
auto itCmd = commands.find(cmdName);
if(itCmd == commands.end()) {
// Find variable
auto itVar = variables.find(cmdName);
if(itVar == variables.end()) {
std::cout << "Console: Unknown command or variable '" << cmdName << "'" << std::endl;
continue;
}
// Variable get/set
printf("Console: Variable '%s' ", cmdName.c_str());
continue;
}
itCmd->second(*this, args);
}
buffer.clear();
}
void Console::exec(const std::string &str) {
// Split strings by command seperator
std::istringstream iss(str);
std::string token;
while(std::getline(iss, token, COMMAND_SEPARATOR)) {
// Seperate by newlines too
std::istringstream lineIss(token);
std::string lineToken;
while(std::getline(lineIss, lineToken)) {
if(lineToken.length() == 0) continue;
buffer.push_back(lineToken);
}
}
}
void Console::print(const char_t *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
printf("\n");
va_end(args);
}
void Console::print(std::string str) {
this->print("%s", str.c_str());
}
Console::~Console(void) {
}
-88
View File
@@ -1,88 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct Console {
private:
std::map<
std::string,
std::function<void(Console&, const std::vector<std::string>&)>
> commands;
std::map<std::string, std::pair<
std::function<std::any()>, std::function<void(std::any&)>
>> variables;
std::vector<std::string> buffer;
public:
static constexpr char_t COMMAND_SEPARATOR = ';';
/**
* Constructs the console.
*/
Console(void);
/**
* Registers a command with the console.
*
* @param cmd The command string.
* @param cb The callback function for the command.
*/
void registerCommand(
const std::string &cmd,
const std::function<void(Console&, const std::vector<std::string>&)> &cb
);
/**
* Registers a variable with the console.
*
* @param var The variable name.
* @param getter The getter function for the variable.
* @param setter The setter function for the variable.
*/
template<typename T>
void registerVariable(
const std::string &var,
const std::function<T()> &getter,
const std::function<void(const T &)> &setter
);
/**
* Updates the console state, this will exec the command buffer.
*/
void update();
/**
* Executes a command string.
*
* @param str The command string to execute.
*/
void exec(const std::string &str);
/**
* Prints a formatted string to the console output.
*
* @param fmt The format string.
* @param ... The format arguments.
*/
void print(const char_t *fmt, ...);
/**
* Prints a string to the console output.
*
* @param str The string to print.
*/
void print(std::string str);
/**
* Destructs the console.
*/
~Console(void);
};
}
-14
View File
@@ -1,14 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Display.cpp
)
# Subdirs
add_subdirectory(color)
add_subdirectory(mesh)
-145
View File
@@ -1,145 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Display.hpp"
#include "engine/Engine.hpp"
using namespace Dawn;
MeshVertex vertices[3] = {
{ {255, 0, 0, 255}, glm::vec2(0.5f, 1.0f), glm::vec3(0.0f, 0.5f, 0.0f) },
{ {0, 255, 0, 255}, glm::vec2(0.0f, 0.0f), glm::vec3(-0.5f, -0.5f, 0.0f) },
{ {0, 0, 255, 255}, glm::vec2(1.0f, 0.0f), glm::vec3(0.5f, -0.5f, 0.0f) }
};
Display::Display(Engine &engine) :
#if DAWN_SDL2
glContext(nullptr),
window(nullptr),
#endif
engine(engine),
mesh(3, PrimitiveType::TRIANGLES, vertices)
{
#if DAWN_SDL2
uint32_t flags = SDL_INIT_VIDEO;
#if DAWN_SDL2_GAMEPAD
flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK;
#endif
if(SDL_Init(flags) != 0) {
throw "Failed to initialize SDL2";
}
// Set OpenGL Attributes
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Create window
this->window = SDL_CreateWindow(
"Dawn",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
DEFAULT_WIDTH,
DEFAULT_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI |
SDL_WINDOW_SHOWN
);
if(!this->window) {
throw "Failed to create SDL2 window";
}
// Create OpenGL context
this->glContext = SDL_GL_CreateContext(this->window);
if(!this->glContext) {
throw "Failed to create OpenGL context";
}
// Setup GL
SDL_GL_SetSwapInterval(1);// Enable vsync
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);// PSP defaults this on?
glShadeModel(GL_SMOOTH);// Fixes color on PSP?
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnableClientState(GL_COLOR_ARRAY);// TODO: every frame on PSP?
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
#else
#error "No display platform defined"
#endif
}
void Display::update(void) {
#if DAWN_SDL2
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: {
engine.console.exec("exit");
break;
}
case SDL_WINDOWEVENT: {
switch(event.window.event) {
case SDL_WINDOWEVENT_CLOSE: {
engine.console.exec("exit");
break;
}
default: {
break;
}
}
break;
}
default: {
break;
}
}
}
// SDL_GL_MakeCurrent(this->window, this->glContext);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(
Color4F::CORNFLOWER_BLUE.r,
Color4F::CORNFLOWER_BLUE.g,
Color4F::CORNFLOWER_BLUE.b,
Color4F::CORNFLOWER_BLUE.a
);
mesh.draw(0, -1);
// glViewport(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
printf("OpenGL error: %d\n", err);
}
SDL_GL_SwapWindow(this->window);
#endif
}
Display::~Display(void) {
#if DAWN_SDL2
if(this->glContext) {
SDL_GL_DeleteContext(this->glContext);
this->glContext = nullptr;
}
if(this->window) {
SDL_DestroyWindow(this->window);
this->window = nullptr;
}
SDL_Quit();
#endif
}
-45
View File
@@ -1,45 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "display/mesh/Mesh.hpp"
namespace Dawn {
struct Engine;
struct Display {
private:
Engine &engine;
#if DAWN_SDL2
SDL_Window* window;
SDL_GLContext glContext;
#endif
public:
static constexpr uint32_t DEFAULT_WIDTH = 800;
static constexpr uint32_t DEFAULT_HEIGHT = 600;
Mesh mesh;
/**
* Display constructor
*
* @param engine The engine instance.
*/
Display(Engine &engine);
/**
* Update the display (swap buffers, etc.)
*/
void update(void);
/**
* Display destructor
*/
~Display(void);
};
}
-13
View File
@@ -1,13 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Color3B.cpp
Color4B.cpp
Color3F.cpp
Color4F.cpp
)
-10
View File
@@ -1,10 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Color3B.hpp"
#include "Color3F.hpp"
#include "Color4B.hpp"
#include "Color4F.hpp"
-32
View File
@@ -1,32 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
using namespace Dawn;
Color3B::Color3B(
const uint8_t r,
const uint8_t g,
const uint8_t b
) : r(r), g(g), b(b) {
// Constructor body (if needed)
}
Color3B Color3B::toColor3B(void) const {
return Color3B(r, g, b);
}
Color4B Color3B::toColor4B(void) const {
return Color4B(r, g, b, 255);
}
Color3F Color3B::toColor3F(void) const {
return Color3F(r / 255.0f, g / 255.0f, b / 255.0f);
}
Color4F Color3B::toColor4F(void) const {
return Color4F(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
}
-65
View File
@@ -1,65 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct Color4B;
struct Color3F;
struct Color4F;
#pragma pack(push, 1)
struct Color3B {
public:
union {
struct {
uint8_t r;
uint8_t g;
uint8_t b;
};
uint8_t rgb[3];
};
/**
* Color (RGB, byte) constructor
*
* @param r Red channel (0-255)
* @param g Green channel (0-255)
* @param b Blue channel (0-255)
*/
Color3B(const uint8_t r, const uint8_t g, const uint8_t b);
/**
* Color (RGB, byte) constructor from array
*
* @param rgb Array of 3 bytes: {r, g, b}
*/
Color3B(const uint8_t rgb[3]);
/**
* Gets this color as a 3-channel byte color.
*/
Color3B toColor3B(void) const;
/**
* Gets this color as a 4-channel byte color. Alpha is set to 255.
*/
Color4B toColor4B(void) const;
/**
* Gets this color as a 3-channel float color. (0-1 range)
*/
Color3F toColor3F(void) const;
/**
* Gets this color as a 4-channel float color. (0-1 range), Alpha is set
* to 1.0f
*/
Color4F toColor4F(void) const;
};
#pragma pack(pop)
}
-46
View File
@@ -1,46 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
using namespace Dawn;
Color3F::Color3F(
const float_t r,
const float_t g,
const float_t b
) : r(r), g(g), b(b) {
}
Color3F::Color3F(
const float_t rgb[3]
) : r(rgb[0]), g(rgb[1]), b(rgb[2]) {
}
Color3B Color3F::toColor3B(void) const {
return Color3B(
static_cast<uint8_t>(r * 255.0f),
static_cast<uint8_t>(g * 255.0f),
static_cast<uint8_t>(b * 255.0f)
);
}
Color4B Color3F::toColor4B(void) const {
return Color4B(
static_cast<uint8_t>(r * 255.0f),
static_cast<uint8_t>(g * 255.0f),
static_cast<uint8_t>(b * 255.0f),
255
);
}
Color3F Color3F::toColor3F(void) const {
return Color3F(r, g, b);
}
Color4F Color3F::toColor4F(void) const {
return Color4F(r, g, b, 1.0f);
}
-64
View File
@@ -1,64 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct Color3B;
struct Color4B;
struct Color4F;
#pragma pack(push, 1)
struct Color3F {
public:
union {
struct {
float_t r;
float_t g;
float_t b;
};
float_t rgb[3];
};
/**
* Color (RGB, float) constructor
*
* @param r Red channel (0.0-1.0)
* @param g Green channel (0.0-1.0)
* @param b Blue channel (0.0-1.0)
*/
Color3F(const float_t r, const float_t g, const float_t b);
/**
* Color (RGB, float) constructor from array
*
* @param rgb Array of 3 float_t: {r, g, b}
*/
Color3F(const float_t rgb[3]);
/**
* Gets this color as a 3-channel byte color.
*/
Color3B toColor3B(void) const;
/**
* Gets this color as a 4-channel byte color. Alpha is set to 255.
*/
Color4B toColor4B(void) const;
/**
* Gets this color as a 3-channel float_t color.
*/
Color3F toColor3F(void) const;
/**
* Gets this color as a 4-channel float_t color. Alpha is set to 1.0f
*/
Color4F toColor4F(void) const;
};
#pragma pack(pop)
}
-34
View File
@@ -1,34 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
using namespace Dawn;
const Color4B Color4B::WHITE = Color4B(0xFF, 0xFF, 0xFF, 0xFF);
const Color4B Color4B::BLACK = Color4B(0x00, 0x00, 0x00, 0xFF);
const Color4B Color4B::RED = Color4B(0xFF, 0x00, 0x00, 0xFF);
const Color4B Color4B::GREEN = Color4B(0x00, 0xFF, 0x00, 0xFF);
const Color4B Color4B::BLUE = Color4B(0x00, 0x00, 0xFF, 0xFF);
const Color4B Color4B::YELLOW = Color4B(0xFF, 0xFF, 0x00, 0xFF);
const Color4B Color4B::CYAN = Color4B(0x00, 0xFF, 0xFF, 0xFF);
const Color4B Color4B::MAGENTA = Color4B(0xFF, 0x00, 0xFF, 0xFF);
const Color4B Color4B::TRANSPARENT = Color4B(0x00, 0x00, 0x00, 0x00);
const Color4B Color4B::CORNFLOWER_BLUE = Color4B(0x64, 0x95, 0xED, 0xFF);
Color4B::Color4B(
const uint8_t r,
const uint8_t g,
const uint8_t b,
const uint8_t a
) : r(r), g(g), b(b), a(a) {
// Constructor body (if needed)
}
Color4B::Color4B(
const uint8_t rgba[4]
) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {
// Constructor body (if needed)
}
-61
View File
@@ -1,61 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct Color3B;
struct Color3F;
struct Color4F;
#pragma pack(push, 1)
struct Color4B {
static const Color4B WHITE;
static const Color4B BLACK;
static const Color4B RED;
static const Color4B GREEN;
static const Color4B BLUE;
static const Color4B YELLOW;
static const Color4B CYAN;
static const Color4B MAGENTA;
static const Color4B TRANSPARENT;
static const Color4B CORNFLOWER_BLUE;
union {
struct {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
uint8_t rgba[4];
};
/**
* Color (RGBA, byte) constructor
*
* @param r Red channel (0-255)
* @param g Green channel (0-255)
* @param b Blue channel (0-255)
* @param a Alpha channel (0-255)
*/
Color4B(
const uint8_t r,
const uint8_t g,
const uint8_t b,
const uint8_t a
);
/**
* Color (RGBA, byte) constructor from array
*
* @param rgba Array of 4 bytes: {r, g, b, a}
*/
Color4B(const uint8_t rgba[4]);
};
#pragma pack(pop)
}
-57
View File
@@ -1,57 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
using namespace Dawn;
const Color4F Color4F::WHITE = Color4F(1.0f, 1.0f, 1.0f, 1.0f);
const Color4F Color4F::BLACK = Color4F(0.0f, 0.0f, 0.0f, 1.0f);
const Color4F Color4F::RED = Color4F(1.0f, 0.0f, 0.0f, 1.0f);
const Color4F Color4F::GREEN = Color4F(0.0f, 1.0f, 0.0f, 1.0f);
const Color4F Color4F::BLUE = Color4F(0.0f, 0.0f, 1.0f, 1.0f);
const Color4F Color4F::YELLOW = Color4F(1.0f, 1.0f, 0.0f, 1.0f);
const Color4F Color4F::CYAN = Color4F(0.0f, 1.0f, 1.0f, 1.0f);
const Color4F Color4F::MAGENTA = Color4F(1.0f, 0.0f, 1.0f, 1.0f);
const Color4F Color4F::TRANSPARENT = Color4F(0.0f, 0.0f, 0.0f, 0.0f);
const Color4F Color4F::CORNFLOWER_BLUE = Color4F(0.39f, 0.58f, 0.93f, 1.0f);
Color4F::Color4F(
const float_t r,
const float_t g,
const float_t b,
const float_t a
) : r(r), g(g), b(b), a(a) {
}
Color4F::Color4F(
const float_t rgba[4]
) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {
}
Color3B Color4F::toColor3B(void) const {
return Color3B(
static_cast<uint8_t>(r * 255.0f),
static_cast<uint8_t>(g * 255.0f),
static_cast<uint8_t>(b * 255.0f)
);
}
Color3F Color4F::toColor3F(void) const {
return Color3F(r, g, b);
}
Color4B Color4F::toColor4B(void) const {
return Color4B(
static_cast<uint8_t>(r * 255.0f),
static_cast<uint8_t>(g * 255.0f),
static_cast<uint8_t>(b * 255.0f),
static_cast<uint8_t>(a * 255.0f)
);
}
Color4F Color4F::toColor4F(void) const {
return Color4F(r, g, b, a);
}
-84
View File
@@ -1,84 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Color3F.hpp"
namespace Dawn {
struct Color3B;
struct Color3F;
struct Color4B;
#pragma pack(push, 1)
struct Color4F {
public:
static const Color4F WHITE;
static const Color4F BLACK;
static const Color4F RED;
static const Color4F GREEN;
static const Color4F BLUE;
static const Color4F YELLOW;
static const Color4F CYAN;
static const Color4F MAGENTA;
static const Color4F TRANSPARENT;
static const Color4F CORNFLOWER_BLUE;
union {
struct {
float_t r;
float_t g;
float_t b;
float_t a;
};
float_t rgba[4];
};
/**
* Color (RGBA, float) constructor
*
* @param r Red channel (0.0-1.0)
* @param g Green channel (0.0-1.0)
* @param b Blue channel (0.0-1.0)
* @param a Alpha channel (0.0-1.0)
*/
Color4F(
const float_t r,
const float_t g,
const float_t b,
const float_t a
);
/**
* Color (RGBA, float) constructor from array
*
* @param rgba Array of 4 float_t: {r, g, b, a}
*/
Color4F(const float_t rgba[4]);
/**
* Gets this color as a 3-channel byte color.
*
* @return Color3B representation of this color (alpha is discarded)
*/
Color3B toColor3B(void) const;
/**
* Gets this color as a 3-channel float color. (alpha is discarded)
*/
Color3F toColor3F(void) const;
/**
* Gets this color as a 4-channel byte color.
*/
Color4B toColor4B(void) const;
/**
* Gets this color as a 4-channel float_t color.
*/
Color4F toColor4F(void) const;
};
#pragma pack(pop)
}
-10
View File
@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Mesh.cpp
)
-73
View File
@@ -1,73 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Mesh.hpp"
#include "assert/Assert.hpp"
using namespace Dawn;
Mesh::Mesh(
const int32_t vertexCount,
const PrimitiveType primitiveType,
const MeshVertex *vertices
) :
vertexCount(vertexCount),
primitiveType(primitiveType),
vertices(vertices)
{
}
void Mesh::draw(
int32_t vertexOffset,
int32_t vertexCount
) const {
const int32_t offset = vertexOffset == -1 ? 0 : vertexOffset;
const int32_t count = vertexCount == -1 ? this->vertexCount : vertexCount;
assertNotNull(this->vertices, "Mesh cannot be NULL");
assertTrue(offset >= 0, "Vertex offset must be non-negative");
assertTrue(count >= 0, "Vertex count must be non-negative");
assertTrue(
offset + count <= this->vertexCount,
"Vertex offset + count must not exceed vertex count"
);
#if DAWN_SDL2
// PSP style pointer legacy OpenGL
const GLsizei stride = sizeof(MeshVertex);
glColorPointer(
4,
GL_UNSIGNED_BYTE,
stride,
(const GLvoid*)&this->vertices[offset].color[0]
);
glTexCoordPointer(
2,
GL_FLOAT,
stride,
(const GLvoid*)&this->vertices[offset].uv[0]
);
glVertexPointer(
3,
GL_FLOAT,
stride,
(const GLvoid*)&this->vertices[offset].position[0]
);
glDrawArrays(
static_cast<GLenum>(this->primitiveType),
0,
count
);
#endif
}
Mesh::~Mesh() {
}
-57
View File
@@ -1,57 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "PrimitiveType.hpp"
#include "display/color/Color.hpp"
namespace Dawn {
#pragma pack(push, 1)
struct MeshVertex {
#if DAWN_SDL2
uint8_t color[4];
glm::vec2 uv;
glm::vec3 position;
#endif
};
#pragma pack(pop)
struct Mesh {
private:
const int32_t vertexCount;
const PrimitiveType primitiveType;
const MeshVertex *vertices;
public:
/**
* Mesh constructor
*
* @param vertexCount The number of vertices in the mesh
* @param primitiveType The type of primitive to render
* @param vertices The vertex data
*/
Mesh(
const int32_t vertexCount,
const PrimitiveType primitiveType,
const MeshVertex *vertices
);
/**
* Draw this mesh.
*
* @param vertexOffset The offset to start drawing from (default: 0)
* @param vertexCount The number of vertices to draw (default: all)
*/
void draw(
int32_t vertexOffset = 0,
int32_t vertexCount = -1
) const;
/**
* Destructs the mesh.
*/
~Mesh();
};
}
-17
View File
@@ -1,17 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
enum class PrimitiveType {
#if DAWN_SDL2
TRIANGLES = GL_TRIANGLES,
LINES = GL_LINES,
POINTS = GL_POINTS,
#endif
};
}
-10
View File
@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Engine.cpp
)
-33
View File
@@ -1,33 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Engine.hpp"
using namespace Dawn;
Engine::Engine() :
time(),
console(),
display(*this),
input(*this)
{
console.registerCommand("exit", [this](auto console, auto args) {
this->exitRequested = true;
});
}
bool_t Engine::isExitRequested() const {
return this->exitRequested;
}
void Engine::update(void) {
time.update();
input.update();
console.update();
display.update();
}
Engine::~Engine() {
}
-49
View File
@@ -1,49 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "time/Time.hpp"
#include "console/Console.hpp"
#include "display/Display.hpp"
#include "input/Input.hpp"
#include "asset/AssetManager.hpp"
namespace Dawn {
struct Engine {
private:
static Engine* instance;
bool_t exitRequested = false;
public:
Time time;
Console console;
Display display;
Input input;
AssetManager assetManager;
/**
* Constructor for the Dawn engine.
*/
Engine();
/**
* Check if an exit has been requested.
*
* @return True if an exit has been requested, false otherwise.
*/
bool_t isExitRequested() const;
/**
* Update the engine state.
*/
void update(void);
/**
* Destructor for the Dawn engine.
*/
~Engine();
};
}
-12
View File
@@ -1,12 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Input.cpp
InputButton.cpp
InputBind.cpp
)
-243
View File
@@ -1,243 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Input.hpp"
#include "assert/Assert.hpp"
#include "engine/Engine.hpp"
using namespace Dawn;
Input::Input(Engine &engine) :
engine(engine),
states({}),
buttons({})
{
engine.console.registerCommand("bind", [this](auto console, auto args) {
if(args.size() == 0) {
this->engine.console.print("Usage: bind <input> [command]");
return;
}
// Find input by name.
auto itButton = this->buttons.begin();
while(itButton != this->buttons.end()) {
if(itButton->getName() == args[0]) break;
++itButton;
}
if(itButton == this->buttons.end()) {
this->engine.console.print("No such input: %s", args[0].c_str());
return;
}
// Is there a second arg?
if(args.size() == 1) {
auto bind = itButton->getBind();
if(bind) {
console.print(bind->getName());
} else {
console.print(itButton->getCommand());
}
return;
}
// Is there a bind for the arg?
auto itBind = InputBind::ALL_BINDS.begin();
while(itBind != InputBind::ALL_BINDS.end()) {
if(strcasecmp((*itBind)->getName().c_str(),args[1].c_str()) == 0) break;
++itBind;
}
// This is a bind?
if(itBind != InputBind::ALL_BINDS.end()) {
itButton->setBind(const_cast<InputBind*>(*itBind));
return;
}
// This is a command then.
itButton->setCommand(args[1]);
});
#if DAWN_SDL2
buttons.push_back(InputButton("esc", InputButtonType::KEY, { .scancode = SDL_SCANCODE_ESCAPE }));
buttons.push_back(InputButton("1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_1 }));
buttons.push_back(InputButton("2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_2 }));
buttons.push_back(InputButton("3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_3 }));
buttons.push_back(InputButton("4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_4 }));
buttons.push_back(InputButton("5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_5 }));
buttons.push_back(InputButton("6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_6 }));
buttons.push_back(InputButton("7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_7 }));
buttons.push_back(InputButton("8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_8 }));
buttons.push_back(InputButton("9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_9 }));
buttons.push_back(InputButton("0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_0 }));
buttons.push_back(InputButton("-", InputButtonType::KEY, { .scancode = SDL_SCANCODE_MINUS }));
buttons.push_back(InputButton("backspace", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSPACE }));
buttons.push_back(InputButton("tab", InputButtonType::KEY, { .scancode = SDL_SCANCODE_TAB }));
buttons.push_back(InputButton("q", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Q }));
buttons.push_back(InputButton("w", InputButtonType::KEY, { .scancode = SDL_SCANCODE_W }));
buttons.push_back(InputButton("e", InputButtonType::KEY, { .scancode = SDL_SCANCODE_E }));
buttons.push_back(InputButton("r", InputButtonType::KEY, { .scancode = SDL_SCANCODE_R }));
buttons.push_back(InputButton("t", InputButtonType::KEY, { .scancode = SDL_SCANCODE_T }));
buttons.push_back(InputButton("y", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Y }));
buttons.push_back(InputButton("u", InputButtonType::KEY, { .scancode = SDL_SCANCODE_U }));
buttons.push_back(InputButton("i", InputButtonType::KEY, { .scancode = SDL_SCANCODE_I }));
buttons.push_back(InputButton("o", InputButtonType::KEY, { .scancode = SDL_SCANCODE_O }));
buttons.push_back(InputButton("p", InputButtonType::KEY, { .scancode = SDL_SCANCODE_P }));
buttons.push_back(InputButton("[", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFTBRACKET }));
buttons.push_back(InputButton("]", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHTBRACKET }));
buttons.push_back(InputButton("enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RETURN }));
buttons.push_back(InputButton("a", InputButtonType::KEY, { .scancode = SDL_SCANCODE_A }));
buttons.push_back(InputButton("s", InputButtonType::KEY, { .scancode = SDL_SCANCODE_S }));
buttons.push_back(InputButton("d", InputButtonType::KEY, { .scancode = SDL_SCANCODE_D }));
buttons.push_back(InputButton("f", InputButtonType:: KEY, { .scancode = SDL_SCANCODE_F }));
buttons.push_back(InputButton("g", InputButtonType::KEY, { .scancode = SDL_SCANCODE_G }));
buttons.push_back(InputButton("h", InputButtonType::KEY, { .scancode = SDL_SCANCODE_H }));
buttons.push_back(InputButton("j", InputButtonType::KEY, { .scancode = SDL_SCANCODE_J }));
buttons.push_back(InputButton("k", InputButtonType::KEY, { .scancode = SDL_SCANCODE_K }));
buttons.push_back(InputButton("l", InputButtonType::KEY, { .scancode = SDL_SCANCODE_L }));
buttons.push_back(InputButton(";", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SEMICOLON }));
buttons.push_back(InputButton("'", InputButtonType::KEY, { .scancode = SDL_SCANCODE_APOSTROPHE }));
buttons.push_back(InputButton("`", InputButtonType::KEY, { .scancode = SDL_SCANCODE_GRAVE }));
buttons.push_back(InputButton("\\", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSLASH }));
buttons.push_back(InputButton("z", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Z }));
buttons.push_back(InputButton("x", InputButtonType::KEY, { .scancode = SDL_SCANCODE_X }));
buttons.push_back(InputButton("c", InputButtonType::KEY, { .scancode = SDL_SCANCODE_C }));
buttons.push_back(InputButton("v", InputButtonType::KEY, { .scancode = SDL_SCANCODE_V }));
buttons.push_back(InputButton("b", InputButtonType::KEY, { .scancode = SDL_SCANCODE_B }));
buttons.push_back(InputButton("n", InputButtonType::KEY, { .scancode = SDL_SCANCODE_N }));
buttons.push_back(InputButton("m", InputButtonType::KEY, { .scancode = SDL_SCANCODE_M }));
buttons.push_back(InputButton(",", InputButtonType::KEY, { .scancode = SDL_SCANCODE_COMMA }));
buttons.push_back(InputButton(".", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PERIOD }));
buttons.push_back(InputButton("/", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SLASH }));
buttons.push_back(InputButton("space", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SPACE }));
buttons.push_back(InputButton("capslock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_CAPSLOCK }));
buttons.push_back(InputButton("f1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F1 }));
buttons.push_back(InputButton("f2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F2 }));
buttons.push_back(InputButton("f3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F3 }));
buttons.push_back(InputButton("f4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F4 }));
buttons.push_back(InputButton("f5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F5 }));
buttons.push_back(InputButton("f6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F6 }));
buttons.push_back(InputButton("f7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F7 }));
buttons.push_back(InputButton("f8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F8 }));
buttons.push_back(InputButton("f9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F9 }));
buttons.push_back(InputButton("f10", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F10 }));
buttons.push_back(InputButton("f11", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F11 }));
buttons.push_back(InputButton("f12", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F12 }));
buttons.push_back(InputButton("printscreen", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PRINTSCREEN }));
buttons.push_back(InputButton("scrolllock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SCROLLLOCK }));
buttons.push_back(InputButton("pause", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAUSE }));
buttons.push_back(InputButton("insert", InputButtonType::KEY, { .scancode = SDL_SCANCODE_INSERT }));
buttons.push_back(InputButton("home", InputButtonType::KEY, { .scancode = SDL_SCANCODE_HOME }));
buttons.push_back(InputButton("end", InputButtonType::KEY, { .scancode = SDL_SCANCODE_END }));
buttons.push_back(InputButton("pageup", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEUP }));
buttons.push_back(InputButton("pagedown", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEDOWN }));
buttons.push_back(InputButton("delete", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DELETE }));
buttons.push_back(InputButton("right", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHT }));
buttons.push_back(InputButton("left", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFT }));
buttons.push_back(InputButton("down", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DOWN }));
buttons.push_back(InputButton("up", InputButtonType::KEY, { .scancode = SDL_SCANCODE_UP }));
buttons.push_back(InputButton("numlock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_NUMLOCKCLEAR }));
buttons.push_back(InputButton("kp_divide", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_DIVIDE }));
buttons.push_back(InputButton("kp_multiply", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MULTIPLY }));
buttons.push_back(InputButton("kp_minus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MINUS }));
buttons.push_back(InputButton("kp_plus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PLUS }));
buttons.push_back(InputButton("kp_enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_ENTER }));
buttons.push_back(InputButton("kp_1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_1 }));
buttons.push_back(InputButton("kp_2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_2 }));
buttons.push_back(InputButton("kp_3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_3 }));
buttons.push_back(InputButton("kp_4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_4 }));
buttons.push_back(InputButton("kp_5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_5 }));
buttons.push_back(InputButton("kp_6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_6 }));
buttons.push_back(InputButton("kp_7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_7 }));
buttons.push_back(InputButton("kp_8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_8 }));
buttons.push_back(InputButton("kp_9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_9 }));
buttons.push_back(InputButton("kp_0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_0 }));
buttons.push_back(InputButton("kp_period", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PERIOD }));
buttons.push_back(InputButton("ctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LCTRL }));
buttons.push_back(InputButton("shift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LSHIFT }));
buttons.push_back(InputButton("alt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LALT }));
buttons.push_back(InputButton("rctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RCTRL }));
buttons.push_back(InputButton("rshift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RSHIFT }));
buttons.push_back(InputButton("ralt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RALT }));
#endif
}
float_t Input::getCurrent(const InputBind *bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
auto it = states.find(bind);
if(it != states.end()) return it->second.current;
return 0.0f;
}
float_t Input::getPrevious(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
auto it = states.find(bind);
if(it != states.end()) return it->second.previous;
return 0.0f;
}
float_t Input::getWhen(const InputBind *bind) const {
auto it = states.find(bind);
if(it != states.end()) return it->second.when;
return 0.0f;
}
bool_t Input::isDown(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getCurrent(bind) != 0.0f;
}
bool_t Input::isUp(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getCurrent(bind) == 0.0f;
}
bool_t Input::wasPressed(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getPrevious(bind) == 0.0f && this->getCurrent(bind) != 0.0f;
}
bool_t Input::wasReleased(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getPrevious(bind) != 0.0f && this->getCurrent(bind) == 0.0f;
}
void Input::update(void) {
// Reset all input bind states
for(auto &state : this->states) {
state.second.previous = state.second.current;
state.second.current = 0.0f;
}
// Update button states.
auto itButton = this->buttons.begin();
while(itButton != this->buttons.end()) {
itButton->update();
if(itButton->getCurrent() != 0.0f) {
// Exec command if actuated this tick.
auto cmd = itButton->getCommand();
if(itButton->getPrevious() == 0.0f && cmd.length() > 0) {
engine.console.exec(cmd);
} else {
// If bound to an input, update the bind state.
auto bind = itButton->getBind();
if(bind != nullptr) {
states[bind].when = engine.time.time;
states[bind].current = fmaxf(
states[bind].current, itButton->getCurrent()
);
}
}
}
++itButton;
}
}
Input::~Input(void) {
}
-98
View File
@@ -1,98 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "InputButton.hpp"
namespace Dawn {
struct InputBindState {
float_t current;
float_t previous;
float_t when;
};
struct Engine;
struct Input {
private:
std::map<const InputBind*, InputBindState> states;
std::vector<InputButton> buttons;
Engine &engine;
public:
/**
* Initializes the input manager.
*
* @param engine The engine instance.
*/
Input(Engine &engine);
/**
* Returns the current state of the input bind.
*
* @param bind The input bind to check.
* @return The current state of the input bind.
*/
float_t getCurrent(const InputBind* bind) const;
/**
* Returns the previous state of the input bind.
*
* @param bind The input bind to check.
* @return The previous state of the input bind.
*/
float_t getPrevious(const InputBind* bind) const;
/**
* Returns the time when the input last changed states.
*
* @param bind The input bind to check.
* @return The time when the input last changed states.
*/
float_t getWhen(const InputBind* bind) const;
/**
* Returns true if the input bind is currently down.
*
* @param bind The input bind to check.
* @return True if the input bind is currently down.
*/
bool_t isDown(const InputBind* bind) const;
/**
* Returns true if the input bind is currently up.
*
* @param bind The input bind to check.
* @return True if the input bind is currently up.
*/
bool_t isUp(const InputBind* bind) const;
/**
* Returns true if the input bind was pressed this frame.
*
* @param bind The input bind to check.
* @return True if the input bind was pressed this frame.
*/
bool_t wasPressed(const InputBind* bind) const;
/**
* Returns true if the input bind was released this frame.
*
* @param bind The input bind to check.
* @return True if the input bind was released this frame.
*/
bool_t wasReleased(const InputBind* bind) const;
/**
* Updates the input manager.
*/
void update(void);
/**
* Cleans up the input manager.
*/
~Input(void);
};
}
-26
View File
@@ -1,26 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "InputBind.hpp"
using namespace Dawn;
std::vector<const InputBind*> InputBind::ALL_BINDS;
const InputBind InputBind::UP("UP");
const InputBind InputBind::DOWN("DOWN");
const InputBind InputBind::LEFT("LEFT");
const InputBind InputBind::RIGHT("RIGHT");
const InputBind InputBind::ACCEPT("ACCEPT");
const InputBind InputBind::CANCEL("CANCEL");
InputBind::InputBind(const std::string &name) : name(name) {
ALL_BINDS.push_back(this);
}
std::string InputBind::getName() const {
return this->name;
}
-35
View File
@@ -1,35 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct InputBind {
public:
const std::string name;
static std::vector<const InputBind*> ALL_BINDS;
static const InputBind UP;
static const InputBind DOWN;
static const InputBind LEFT;
static const InputBind RIGHT;
static const InputBind ACCEPT;
static const InputBind CANCEL;
/**
* Returns the name of the input bind.
*
* @return The name of the input bind.
*/
std::string getName() const;
private:
/**
* Private only constructor for an InputBind.
*/
InputBind(const std::string &name);
};
}
-90
View File
@@ -1,90 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "InputButton.hpp"
#include "engine/Engine.hpp"
#include "assert/Assert.hpp"
using namespace Dawn;
InputButton::InputButton(
const std::string &name,
const InputButtonType buttonType,
const InputButtonData data
) :
name(name),
buttonType(buttonType),
data(data),
command(""),
bind(nullptr),
current(0.0f),
previous(0.0f)
{
}
void InputButton::update() {
previous = current;
switch(this->buttonType) {
case InputButtonType::KEY: {
#if DAWN_SDL2
const uint8_t *state = SDL_GetKeyboardState(NULL);
current = state[this->data.scancode] ? 1.0f : 0.0f;
#else
#error "No input platform defined"
#endif
break;
}
case InputButtonType::BUTTON: {
current = 0.0f;
break;
}
case InputButtonType::AXIS: {
current = 0.0f;
break;
}
default: {
assertUnreachable("Unknown input button type");
}
}
}
float_t InputButton::getCurrent(void) const {
return this->current;
}
float_t InputButton::getPrevious(void) const {
return this->previous;
}
std::string InputButton::getName(void) const {
return this->name;
}
InputButtonType InputButton::getType(void) const {
return this->buttonType;
}
std::string InputButton::getCommand(void) const {
return this->command;
}
InputBind * InputButton::getBind(void) const {
return this->bind;
}
void InputButton::setBind(const InputBind *bind) {
this->bind = const_cast<InputBind*>(bind);
this->command.clear();
}
void InputButton::setCommand(const std::string &command) {
this->command = command;
this->bind = nullptr;
}
-111
View File
@@ -1,111 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "InputBind.hpp"
namespace Dawn {
enum class InputButtonType {
BUTTON,
AXIS,
KEY
};
union InputButtonData {
#if DAWN_SDL2
SDL_Scancode scancode;
#endif
};
struct InputButton {
private:
const std::string name;
const InputButtonType buttonType;
const InputButtonData data;
std::string command;
InputBind *bind;
float_t previous;
float_t current;
public:
/**
* Constructor for an InputButton. An input button is basically any
* physical input on any device, such as a keyboard key, mouse button,
* gamepad button, or gamepad axis.
*
* @param name Human name for the input, used by the console for binding.
* @param buttonType The type of input button.
* @param data Data used to initialize the button, usually a scancode.
*/
InputButton(
const std::string &name,
const InputButtonType buttonType,
const InputButtonData data
);
/**
* Updates the state of the input button.
*/
void update();
/**
* Returns the current state of the input button.
*
* @return The current state of the input button.
*/
float_t getCurrent() const;
/**
* Returns the previous state of the input button.
*
* @return The previous state of the input button.
*/
float_t getPrevious() const;
/**
* Returns the human name of the input button.
*
* @return The human name of the input button.
*/
std::string getName(void) const;
/**
* Returns the type of the input button.
*
* @return The type of the input button.
*/
InputButtonType getType(void) const;
/**
* Command executed by the input button when pressed.
*
* @return The command that is executed when the input button is pressed.
*/
std::string getCommand(void) const;
/**
* Returns the input bind associated with this button, or NULL if none.
*
* @return The input bind associated with this button, or NULL if none.
*/
InputBind * getBind(void) const;
/**
* Sets the input bind for a button.
*
* @param bind The input bind to associate with this button.
*/
void setBind(const InputBind *bind);
/**
* Sets the command to be executed when the button is pressed.
*
* @param command The command to execute when the button is pressed.
*/
void setCommand(const std::string &command);
};
}
-23
View File
@@ -1,23 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "dawn.hpp"
#include "engine/Engine.hpp"
using namespace Dawn;
int main(int argc, char **argv) {
std::shared_ptr<Engine> engine = std::make_shared<Engine>();
engine->console.exec("bind w up");
while(!engine->isExitRequested()) {
engine->update();
}
engine = nullptr;
return 0;
}
-11
View File
@@ -1,11 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
)
# Subdirs
-10
View File
@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Time.cpp
)
-41
View File
@@ -1,41 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Time.hpp"
#include "assert/Assert.hpp"
using namespace Dawn;
Time::Time(void) :
delta(Time::FIXED_STEP),
time(0.0f),
fixedDelta(Time::FIXED_STEP),
fixedTime(0.0f),
isFixedUpdate(false)
{
}
void Time::update(void) {
float_t delta;
#if DAWN_SDL2
delta = (float_t)SDL_GetTicks() / 1000.0f - this->time;
#else
#error "No time platform defined"
#endif
this->delta = delta;
assertTrue(this->delta >= 0.0f, "Delta time is negative");
this->time += delta;
this->isFixedUpdate = this->time - this->fixedTime >= Time::FIXED_STEP;
if (this->isFixedUpdate) {
this->fixedDelta = Time::FIXED_STEP;
this->fixedTime += this->fixedDelta;
} else {
this->fixedDelta = 0.0f;
this->fixedTime += this->fixedDelta;
}
}
-35
View File
@@ -1,35 +0,0 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct Time {
private:
bool_t isFixedUpdate;
public:
static constexpr float_t FIXED_STEP = 1.0f / 60.0f;
#if TIME_FIXED
static const float_t FIXED_PLATFORM_STEP = TIME_PLATFORM_STEP;
#endif
float_t delta;
float_t time;
float_t fixedDelta;
float_t fixedTime;
/**
* The time in seconds since the application started.
*/
Time(void);
/**
* Update the time values.
*/
void update(void);
};
}