Port to C++
This commit is contained in:
parent
5541f9657f
commit
5aaf616f34
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,8 +1,10 @@
|
||||||
# Directories
|
# Directories
|
||||||
.dub
|
.dub
|
||||||
*/docs/
|
*/docs
|
||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
|
build
|
||||||
|
.kdev4/
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
*.so
|
*.so
|
||||||
|
@ -16,6 +18,8 @@
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
*.lst
|
*.lst
|
||||||
|
*.user
|
||||||
|
*.kdev4
|
||||||
docs.json
|
docs.json
|
||||||
__dummy.html
|
__dummy.html
|
||||||
dub.selections.json
|
dub.selections.json
|
||||||
|
|
7
compile.sh
Normal file
7
compile.sh
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ! -d build ]; then
|
||||||
|
meson build
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd build && meson compile
|
8
core/callback.hpp
Normal file
8
core/callback.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "logging/types.hpp"
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
typedef void (*LoggerCallback)(LoggingSeverity severity, std::string message);
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
name "core"
|
|
||||||
license "LGPL-3.0"
|
|
||||||
targetType "library"
|
|
||||||
targetName "hibiscore"
|
|
50
core/engine/engine.cpp
Normal file
50
core/engine/engine.cpp
Normal 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
31
core/engine/engine.hpp
Normal 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
3
core/enginever.in.hpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define HIBIS_VERSION "@version@"
|
9
core/graphics/drawable.hpp
Normal file
9
core/graphics/drawable.hpp
Normal 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
9
core/logging/types.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum LoggingSeverity {
|
||||||
|
Message,
|
||||||
|
Information,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
Fatal
|
||||||
|
};
|
39
core/math/types.hpp
Normal file
39
core/math/types.hpp
Normal 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
9
core/node/node.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
virtual void process(float delta) = 0;
|
||||||
|
virtual void physicsProcess(float delta) = 0;
|
||||||
|
};
|
||||||
|
}
|
28
core/renderer/renderer.hpp
Normal file
28
core/renderer/renderer.hpp
Normal 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
7
core/resources/image.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "resource.hpp"
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
class Image : Resource {};
|
||||||
|
}
|
5
core/resources/resource.hpp
Normal file
5
core/resources/resource.hpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
class Resource {};
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
module hibis.callback;
|
|
||||||
|
|
||||||
import hibis.logging.types;
|
|
||||||
|
|
||||||
alias LoggerCallback = void function(LoggingSeverity severity, string message);
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
module hibis.graphics.drawable;
|
|
||||||
import hibis.renderer.renderer;
|
|
||||||
|
|
||||||
abstract class Drawable {
|
|
||||||
public void draw(Renderer* renderer);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
module hibis.logging.types;
|
|
||||||
|
|
||||||
enum LoggingSeverity : ubyte {
|
|
||||||
Message = 0,
|
|
||||||
Information,
|
|
||||||
Warning,
|
|
||||||
Error,
|
|
||||||
Fatal
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,6 +0,0 @@
|
||||||
module hibis.node.node;
|
|
||||||
|
|
||||||
abstract class Node {
|
|
||||||
void process(float delta);
|
|
||||||
void physicsProcess(float delta);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
module hibis.resources.image;
|
|
||||||
|
|
||||||
import hibis.resources.resource;
|
|
||||||
|
|
||||||
abstract class Image : Resource {}
|
|
|
@ -1,3 +0,0 @@
|
||||||
module hibis.resources.resource;
|
|
||||||
|
|
||||||
abstract class Resource {}
|
|
12
dub.sdl
12
dub.sdl
|
@ -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
3
include/pragmautil.hpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// TODO: pragma
|
28
meson.build
Normal file
28
meson.build
Normal 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])
|
|
@ -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"
|
|
34
renderer/rsdl/resources/font.cpp
Normal file
34
renderer/rsdl/resources/font.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
renderer/rsdl/resources/font.hpp
Normal file
30
renderer/rsdl/resources/font.hpp
Normal 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
98
renderer/rsdl/rsdl.cpp
Normal 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
43
renderer/rsdl/rsdl.hpp
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
16
test/.gitignore
vendored
16
test/.gitignore
vendored
|
@ -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
89
test/app.cpp
Normal 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;
|
||||||
|
}
|
10
test/dub.sdl
10
test/dub.sdl
|
@ -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"
|
|
|
@ -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);
|
|
||||||
}
|
|
Loading…
Reference in a new issue