Port to C++

This commit is contained in:
Tulpen 2023-05-26 22:41:51 +01:00
parent 5541f9657f
commit 5aaf616f34
38 changed files with 536 additions and 459 deletions

8
.gitignore vendored
View file

@ -1,8 +1,10 @@
# Directories
.dub
*/docs/
*/docs
.vscode
.idea
build
.kdev4/
# Files
*.so
@ -16,6 +18,8 @@
*.o
*.obj
*.lst
*.user
*.kdev4
docs.json
__dummy.html
dub.selections.json
dub.selections.json

7
compile.sh Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
if [ ! -d build ]; then
meson build
fi
cd build && meson compile

8
core/callback.hpp Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <string>
#include "logging/types.hpp"
namespace hibis {
typedef void (*LoggerCallback)(LoggingSeverity severity, std::string message);
}

View file

@ -1,4 +0,0 @@
name "core"
license "LGPL-3.0"
targetType "library"
targetName "hibiscore"

50
core/engine/engine.cpp Normal file
View file

@ -0,0 +1,50 @@
#include "enginever.hpp"
#include "engine.hpp"
namespace hibis {
Engine::Engine(Renderer* renderer, LoggerCallback logger) {
this->renderer = renderer;
loggerCallback = logger;
previousProcessTick = 0.00001f;
previousPhysicsProcessTick = 0.00001f;
//watch.start();
this->loggerCallback(Information, "Started Hibis!");
}
Engine::~Engine() {
//watch.stop();
}
void Engine::runNodeProcesses() {
// TODO: fix delta then adapt for runNodePhysicsProcesses
//const float current = watch.peek.total!"msecs" / 1_000;
//float delta = (current - previousProcessTick);
for (Node* node : nodeList) {
node->physicsProcess(0.00f);
}
//this.previousProcessTick = watch.peek.total!"msecs" / 1_000;
}
void Engine::runNodePhysicsProcesses() {
// TODO: See above TODO
// Schade! Have the wrong function content while I figure out how std.datetime.watch works
//const float current = watch.peek.total!"msecs" / 1_000;
//float delta = (current - previousProcessTick);
for (Node* node : nodeList) {
node->physicsProcess(0.00f);
}
//this.previousPhysicsProcessTick = watch.peek.total!"msecs" / 1_000;
}
void Engine::drawNodes() {
// TODO
}
const char* Engine::getEngineVersion() { return HIBIS_VERSION; }
}

31
core/engine/engine.hpp Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include <vector>
#include "../renderer/renderer.hpp"
#include "../callback.hpp"
#include "../node/node.hpp"
namespace hibis {
class Engine {
public:
Engine(Renderer* renderer, LoggerCallback logger);
~Engine();
void runNodeProcesses();
void runNodePhysicsProcesses();
void drawNodes();
const char* getEngineVersion();
private:
Renderer* renderer;
//StopWatch watch;
float previousProcessTick;
float previousPhysicsProcessTick;
std::vector<Node*> nodeList;
LoggerCallback loggerCallback;
};
}

3
core/enginever.in.hpp Normal file
View file

@ -0,0 +1,3 @@
#pragma once
#define HIBIS_VERSION "@version@"

View file

@ -0,0 +1,9 @@
#pragma once
#include "../renderer/renderer.hpp"
namespace hibis {
class Drawable {
virtual void draw(Renderer* renderer) = 0;
};
}

9
core/logging/types.hpp Normal file
View file

@ -0,0 +1,9 @@
#pragma once
enum LoggingSeverity {
Message,
Information,
Warning,
Error,
Fatal
};

39
core/math/types.hpp Normal file
View file

@ -0,0 +1,39 @@
#pragma once
namespace hibis {
// Structs
// - Image
/// RGBA value struct. Value is between 0 and 255
struct Color {
unsigned char r, g, b, a;
};
// - 2D
/// Defines a point within a 2D space.
struct Point2D {
float x, y;
};
/// Defines a given area.
struct Rect {
float x, y, w, h;
};
/// Integer variation of Rect.
struct IntRect {
int x, y, w, h;
};
/// X and Y values using floats.
struct Vec2 {
float x, y;
};
/// X and Y values using integers.
struct IntVec2 {
int x, y;
};
// - Functions
// TODO: Functions
}

9
core/node/node.hpp Normal file
View file

@ -0,0 +1,9 @@
#pragma once
namespace hibis {
class Node {
public:
virtual void process(float delta) = 0;
virtual void physicsProcess(float delta) = 0;
};
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "../math/types.hpp"
#include "../resources/resource.hpp"
#include <string>
namespace hibis {
class Renderer {
public:
// Draw
virtual void clearScreen(Color col) = 0;
virtual void renderCurrent() = 0;
virtual void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) = 0;
// Pre and Post draw
virtual void preDraw() = 0;
virtual void postDraw() = 0;
// Update
virtual void update() = 0;
// Util
virtual void setWindowTitle(std::string title) = 0;
bool keepOpen = true;
};
}

7
core/resources/image.hpp Normal file
View file

@ -0,0 +1,7 @@
#pragma once
#include "resource.hpp"
namespace hibis {
class Image : Resource {};
}

View file

@ -0,0 +1,5 @@
#pragma once
namespace hibis {
class Resource {};
}

View file

@ -1,5 +0,0 @@
module hibis.callback;
import hibis.logging.types;
alias LoggerCallback = void function(LoggingSeverity severity, string message);

View file

@ -1,69 +0,0 @@
module hibis.core.engine;
import hibis.graphics.drawable;
import hibis.renderer.renderer;
import hibis.logging.types;
import hibis.callback;
import hibis.node.node;
import std.datetime.stopwatch;
import std.stdio;
import std.format;
class Engine {
this(Renderer renderer, LoggerCallback logger) {
this.renderer = renderer;
this.loggerCallback = logger;
previousProcessTick = 0.00001f;
previousPhysicsProcessTick = 0.00001f;
watch.start();
this.loggerCallback(LoggingSeverity.Information, "Started Hibis!");
}
~this() {
watch.stop();
}
void runNodeProcesses() {
// TODO: fix delta then adapt for runNodePhysicsProcesses
const float current = watch.peek.total!"msecs" / 1_000;
float delta = (current - previousProcessTick);
foreach (Node* node ; nodeList) {
node.process(delta);
}
this.previousProcessTick = watch.peek.total!"msecs" / 1_000;
}
void runNodePhysicsProcesses() {
// TODO: See above TODO
// Schade! Have the wrong function content while I figure out how std.datetime.watch works
const float current = watch.peek.total!"msecs" / 1_000;
float delta = (current - previousProcessTick);
foreach (Node* node ; nodeList) {
node.physicsProcess(delta);
}
this.previousPhysicsProcessTick = watch.peek.total!"msecs" / 1_000;
}
void drawNodes() {
foreach (Node* node; nodeList) {
if (Drawable* drawNode = cast(Drawable*) node) {
drawNode.draw(&renderer);
}
}
}
private Renderer renderer;
private StopWatch watch;
private float previousProcessTick;
private float previousPhysicsProcessTick;
private Node*[] nodeList;
private LoggerCallback loggerCallback;
}

View file

@ -1,6 +0,0 @@
module hibis.graphics.drawable;
import hibis.renderer.renderer;
abstract class Drawable {
public void draw(Renderer* renderer);
}

View file

@ -1,9 +0,0 @@
module hibis.logging.types;
enum LoggingSeverity : ubyte {
Message = 0,
Information,
Warning,
Error,
Fatal
}

View file

@ -1,37 +0,0 @@
module hibis.math.types;
// Structs
// - Image
/// RGBA value struct. Value is between 0 and 255
struct Color {
ubyte r, g, b, a;
}
// - 2D
/// Defines a point within a 2D space.
struct Point2D {
float x, y;
}
/// Defines a given area.
struct Rect {
float x, y, w, h;
}
/// Integer variation of Rect.
struct IntRect {
int x, y, w, h;
}
/// X and Y values using floats.
struct Vec2 {
float x, y;
}
/// X and Y values using integers.
struct IntVec2 {
int x, y;
}
// - Functions
// TODO: Functions

View file

@ -1,6 +0,0 @@
module hibis.node.node;
abstract class Node {
void process(float delta);
void physicsProcess(float delta);
}

View file

@ -1,24 +0,0 @@
module hibis.renderer.renderer;
import hibis.math.types;
import hibis.resources.resource;
abstract class Renderer {
// Draw
void clearScreen(Color col);
void renderCurrent();
void drawText(Resource resource, string text, IntVec2 pos, Color color);
// Pre and Post draw
void preDraw();
void postDraw();
// Update
void update();
// Util
void setWindowTitle(string title);
public bool keepOpen = true;
}

View file

@ -1,5 +0,0 @@
module hibis.resources.image;
import hibis.resources.resource;
abstract class Image : Resource {}

View file

@ -1,3 +0,0 @@
module hibis.resources.resource;
abstract class Resource {}

12
dub.sdl
View file

@ -1,12 +0,0 @@
name "hibis"
description "Game engine written in D"
authors "Tulpenkiste"
copyright "Copyright © 2023, Tulpenkiste"
license "LGPL-3.0"
targetType "none"
dependency "hibis:core" version="*"
dependency "hibis:rsdl" version="*"
dependency "hibis:test" version="*"
subPackage "core"
subPackage "renderer/rsdl"
subPackage "test"

3
include/pragmautil.hpp Normal file
View file

@ -0,0 +1,3 @@
#pragma once
// TODO: pragma

28
meson.build Normal file
View file

@ -0,0 +1,28 @@
project('hibis', 'cpp', version: '0.0.0' + (not get_option('buildtype').startswith('release') ? '-' + run_command('git', 'rev-parse', '--short', 'HEAD', check: true).stdout().strip() : ''),
license: 'LGPL-3.0-only', meson_version: '>=0.60.3', default_options: ['cpp_std=c++17'])
# Configure data
confdata = configuration_data()
confdata.set('version', meson.project_version())
configure_file(input: 'core/enginever.in.hpp', output: 'enginever.hpp', configuration: confdata)
# Include Directory
include_dirs = include_directories('./include')
# Files
libhibis_src_core = files('core/engine/engine.cpp')
libhibis_src = [libhibis_src_core]
libhibis_rsdl_src = files('renderer/rsdl/rsdl.cpp', 'renderer/rsdl/resources/font.cpp')
libhibis_test_src = files('test/app.cpp')
# Dependencies
libsdl2 = dependency('SDL2')
libsdl2_ttf = dependency('SDL2_ttf')
libfmt = dependency('fmt')
# Compile
libhibis = library('hibis', libhibis_src, include_directories: include_dirs)
libhibis_rsdl = library('hibis_rsdl', libhibis_rsdl_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libsdl2, libsdl2_ttf, libfmt])
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rsdl'], link_with: [libhibis, libhibis_rsdl], dependencies: [libsdl2, libsdl2_ttf, libfmt])

View file

@ -1,9 +0,0 @@
name "rsdl"
dependency "hibis:core" version=">=0.0.0"
dependency "bindbc-sdl" version="~>1.3.5"
versions "SDL_2_26" "SDL_TTF_2_20"
libs "SDL2" "SDL2_ttf"
targetType "library"
targetName "hibis_rsdl"
# Source paths so this can compile properly
sourcePaths "./" "../../core"

View file

@ -0,0 +1,34 @@
#include <iostream>
#include <string>
#include <fmt/format.h>
#include "font.hpp"
namespace hibis {
namespace rsdl {
Font::Font(std::string path, uint size) {
this->size = size;
this->path = path;
loadFont();
}
Font::~Font() {
TTF_CloseFont(loadedFont);
}
void Font::loadFont(bool reload) {
// If already loaded, close font
if (loadedFont != NULL) {
TTF_CloseFont(loadedFont);
loadedFont = NULL;
}
loadedFont = TTF_OpenFont(path.c_str(), size);
// Do the message
if (!didReload) {
std::cout << fmt::format((reload ? "Reloaded font from" : "Loaded font at") + (std::string)" {}", path) << std::endl;
didReload = reload;
}
}
}
}

View file

@ -0,0 +1,30 @@
#pragma once
#include <string>
#include <resources/resource.hpp>
#include <SDL2/SDL_ttf.h>
namespace hibis {
namespace rsdl {
class Font : public Resource {
public:
Font(std::string path, uint size);
~Font();
uint getFontSize() { return size; }
void setFontSize(uint newSize) { size = newSize; loadFont(true); }
TTF_Font* loadedFont = NULL;
private:
void loadFont(bool reload = false);
uint size;
std::string path;
bool didReload = false;
};
}
}

98
renderer/rsdl/rsdl.cpp Normal file
View file

@ -0,0 +1,98 @@
#include <SDL2/SDL_ttf.h>
#include <fmt/format.h>
#include "rsdl.hpp"
#include "resources/font.hpp"
#include <pragmautil.hpp>
namespace hibis {
namespace rsdl {
RSDL::RSDL(std::string title, IntVec2 size, LoggerCallback callback) {
logger = callback;
SDL_Init(SDL_INIT_VIDEO);
// Create window. `title` is cast to a char* here as tostd::stringz returns an immutable char* (causing an error)
window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
size.x, size.y, SDL_WINDOW_RESIZABLE);
if (window == NULL) {
logger(Fatal, fmt::format("Couldn't create window! what: {}", SDL_GetError()));
SDL_Quit();
exit(1);
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
logger(Fatal, fmt::format("Couldn't create renderer! what: {}", SDL_GetError()));
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
if (TTF_Init() != 0) {
logger(Fatal, fmt::format("Couldn't load SDL_TTF! what: %d", TTF_GetError()));
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
TTF_Quit();
exit(1);
}
}
RSDL::~RSDL() {
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
void RSDL::clearScreen(Color col) {
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
SDL_RenderClear(renderer);
}
void RSDL::renderCurrent() {
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer);
}
void RSDL::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {
if (Font* font = (Font*)resource) {
SDL_Surface* textSurface = TTF_RenderText_Solid(font->loadedFont, text.c_str(), SDL_Color {color.r, color.g, color.b, color.a });
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
int width = 0;
int height = 0;
TTF_SizeText(font->loadedFont, text.c_str(), &width, &height);
SDL_Rect textRect;
textRect.x = pos.x;
textRect.y = pos.y;
textRect.w = width;
textRect.h = height;
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
}
void RSDL::preDraw() {}
void RSDL::postDraw() {}
void RSDL::update() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) keepOpen = false;
}
}
void RSDL::setWindowTitle(std::string title) {}
}
}

43
renderer/rsdl/rsdl.hpp Normal file
View file

@ -0,0 +1,43 @@
#pragma once
#include <format>
#include <string>
#include <stdexcept>
#include <SDL2/SDL.h>
#include <callback.hpp>
#include <math/types.hpp>
#include <renderer/renderer.hpp>
namespace hibis {
namespace rsdl {
/** \class RSDL
* Renderer implementation using SDL2 Renderer for the Hibis game engine
*/
class RSDL : public Renderer {
public:
RSDL(std::string title, IntVec2 size, LoggerCallback callback);
~RSDL();
void clearScreen(Color col = Color {0, 0, 0, 1});
void renderCurrent();
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color);
void preDraw();
void postDraw();
void update();
void setWindowTitle(std::string title);
private:
SDL_Window* window;
SDL_Renderer* renderer;
LoggerCallback logger;
};
}
}

View file

@ -1,123 +0,0 @@
module hibis_rsdl.rsdl;
import hibis.resources.resource;
import hibis.callback;
import hibis.logging.types;
import hibis_rsdl.resources.font;
import bindbc.sdl;
import sdl_ttf;
import hibis.renderer.renderer;
import hibis.math.types;
import std.exception;
import std.format;
import std.stdio;
import std.string : toStringz;
import std.array : split;
/** \class RSDL
* Renderer implementation using SDL2 Renderer for the Hibis game engine
*/
class RSDL : Renderer {
this(string title, IntVec2 size, LoggerCallback callback) {
this.logger = callback;
const SDLSupport ret = loadSDL();
if(ret != sdlSupport) {
throw new Exception("Couldn't load SDL library!");
}
const SDLTTFSupport ttf = loadSDLTTF();
SDL_Init(SDL_INIT_VIDEO);
// Create window. `title` is cast to a char* here as toStringz returns an immutable char* (causing an error)
window = SDL_CreateWindow(cast(char*)toStringz(title), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
size.x, size.y, SDL_WINDOW_RESIZABLE);
if (window is null) {
string error = format("Couldn't create window! what: %d", SDL_GetError());
SDL_Quit();
throw new Exception(error);
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer is null) {
string error = format("Couldn't create renderer! what: %d", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
throw new Exception(error);
}
if (TTF_Init() != 0) {
logger(LoggingSeverity.Fatal, format("Couldn't load SDL_TTF! what: %d", TTF_GetError()));
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
TTF_Quit();
throw new Exception("");
}
}
~this() {
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
unloadSDLTTF();
unloadSDL();
}
override void clearScreen(Color col = Color(0, 0, 0, 1)) {
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
SDL_RenderClear(renderer);
}
override void renderCurrent() {
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer);
}
override void drawText(Resource resource, string text, IntVec2 pos, Color color) {
if (Font font = cast(Font)resource) {
SDL_Surface* textSurface = TTF_RenderText_Solid(font.loadedFont, cast(const(char)*)toStringz(text), SDL_Color(color.r, color.g, color.b, color.a));
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
int width = 0;
int height = 0;
TTF_SizeText(font.loadedFont, cast(const(char)*)toStringz(text), &width, &height);
SDL_Rect textRect;
textRect.x = pos.x;
textRect.y = pos.y;
textRect.w = width;
textRect.h = height;
SDL_RenderCopy(renderer, textTexture, null, &textRect);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
}
override void preDraw() {}
override void postDraw() {}
override void update() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) keepOpen = false;
}
}
override void setWindowTitle(string title) {}
private SDL_Window* window;
private SDL_Renderer* renderer;
private LoggerCallback logger;
}

View file

@ -1,51 +0,0 @@
module hibis_rsdl.resources.font;
import hibis.resources.resource;
import sdl_ttf;
import std.string : toStringz;
import std.stdio;
import std.format : format;
class Font : Resource {
this(string path, uint size) {
this.size = size;
this.path = path;
loadFont();
}
~this() {
TTF_CloseFont(loadedFont);
}
uint getFontSize() { return size; }
void setFontSize(uint newSize) {
size = newSize;
loadFont(true);
}
private void loadFont(bool reload = false) {
const char* nPath = cast(const(char)*)toStringz(path);
// If already loaded, close font
if (!(loadedFont is null)) {
TTF_CloseFont(loadedFont);
loadedFont = null;
}
loadedFont = TTF_OpenFont(nPath, size);
// Do the message
if (!didReload) {
writeln(format(reload ? "Reloaded font from '%s'" : "Loaded font at '%s'", path));
didReload = reload;
}
}
public TTF_Font* loadedFont = null;
private uint size;
private string path;
private bool didReload = false;
}

3
run.sh
View file

@ -1,3 +0,0 @@
#!/bin/bash
dub run hibis:test

16
test/.gitignore vendored
View file

@ -1,16 +0,0 @@
.dub
docs.json
__dummy.html
docs/
/test
test.so
test.dylib
test.dll
test.a
test.lib
test-test-*
*.exe
*.pdb
*.o
*.obj
*.lst

89
test/app.cpp Normal file
View file

@ -0,0 +1,89 @@
#include <logging/types.hpp>
#include <fmt/format.h>
#include <renderer/renderer.hpp>
#include <rsdl.hpp>
#include <resources/font.hpp>
#include <resources/font.hpp>
#include <string>
#include <iostream>
#include <chrono>
#include <thread>
#include <engine/engine.hpp>
using namespace hibis;
using namespace hibis::rsdl;
void logger(LoggingSeverity severity, std::string message) {
std::string sevString;
switch (severity) {
case Message:
sevString = "Message";
break;
case Information:
sevString = "Information";
break;
case Warning:
sevString = "Warning";
break;
case Error:
sevString = "Error";
break;
case Fatal:
sevString = "Fatal";
break;
}
std::cout << fmt::format("[{}]: {}", severity, message) << std::endl;
}
int main() {
RSDL renderer = RSDL("test", IntVec2 {800, 600}, &logger);
Engine engine = Engine(&renderer, &logger);
#ifdef _WIN32
Font font = Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
#else
Font font = Font("/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
#endif
unsigned char red = 0;
bool increaseRed = true;
bool increaseSize = true;
uint size = 16;
uint f = 0;
logger(Information, "Started Hibis test app! BEHOLD: Colours.");
while (renderer.keepOpen) {
engine.runNodeProcesses();
// Colour changing background!
if ((red == 255 && increaseRed) || (red == 0 && !increaseRed)) {
increaseRed = !increaseRed;
}
if (increaseRed) red += 1;
else red -= 1;
f++;
if (f == 16) {
f = 0;
if ((size == 64 && increaseSize) || (size == 16 && !increaseSize)) {
increaseSize = !increaseSize;
}
if (increaseSize) size += 2;
else size -= 2;
font.setFontSize(size);
}
// Clear screen then sleep for ~16ms
renderer.clearScreen(Color {red, 0, 0, 255});
renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
engine.drawNodes();
renderer.renderCurrent();
renderer.update();
std::this_thread::sleep_for(std::chrono::milliseconds(16));
}
return 0;
}

View file

@ -1,10 +0,0 @@
name "test"
description "Test of the Hibis game engine"
authors "Tulpenkiste"
copyright "Copyright © 2023, Tulpenkiste"
license "LGPL-3.0"
targetType "executable"
targetName "hibistest.exec"
dependency "hibis:core" version="*"
dependency "hibis:rsdl" version="*"
sourcePaths "./" "../core" "../renderer/rsdl"

View file

@ -1,65 +0,0 @@
import std.stdio;
import std.format;
import std.conv;
import hibis.core.engine;
import hibis.math.types;
import hibis.renderer.renderer;
import hibis.logging.types;
import hibis.callback;
import hibis_rsdl.rsdl;
import hibis_rsdl.resources.font;
import core.thread;
void logger(LoggingSeverity severity, string message) {
writeln(format("[%s]: %s", to!string(severity), message));
}
void main() {
Renderer renderer = new RSDL("test", IntVec2(800, 600), &logger);
Engine engine = new Engine(renderer, &logger);
version(windows) {
Font font = new Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
} else {
Font font = new Font("/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
}
ubyte red = 0;
bool increaseRed = true;
bool increaseSize = true;
uint size = 16;
uint f = 0;
logger(LoggingSeverity.Information, "Started Hibis test app! BEHOLD: Colours.");
while (renderer.keepOpen) {
engine.runNodeProcesses();
// Colour changing background!
if ((red == 255 && increaseRed) || (red == 0 && !increaseRed)) {
increaseRed = !increaseRed;
}
if (increaseRed) red += 1;
else red -= 1;
f++;
if (f == 16) {
f = 0;
if ((size == 64 && increaseSize) || (size == 16 && !increaseSize)) {
increaseSize = !increaseSize;
}
if (increaseSize) size += 2;
else size -= 2;
font.setFontSize(size);
}
// Clear screen then sleep for ~16ms
renderer.clearScreen(Color(red, 0, 0, 255));
renderer.drawText(font, "Testing Text", IntVec2(0, 0), Color(255, 255, 255, 255));
engine.drawNodes();
renderer.renderCurrent();
renderer.update();
Thread.sleep(16.msecs);
}
destroy(font);
}