@@ -12,7 +12,8 @@ set(assets | |||
assets/tiles/grass.png | |||
assets/tiles/air.png | |||
assets/tiles/stone.png | |||
assets/tiles/dirt.png) | |||
assets/tiles/dirt.png | |||
assets/tiles/tree-trunk.png) | |||
foreach(a ${assets}) | |||
configure_file("${a}" "${a}" COPYONLY) | |||
endforeach(a) |
@@ -12,7 +12,7 @@ public: | |||
}; | |||
WGDefault(Swan::World &world): | |||
tGrass_(world.getTileID("core::grass")), tDirt_(world.getTileID("core::dirt")), | |||
tGrass_(world.getTileID("core::tree-trunk")), tDirt_(world.getTileID("core::dirt")), | |||
tStone_(world.getTileID("core::stone")), tAir_(world.getTileID("core::air")) {} | |||
void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override; |
@@ -11,6 +11,7 @@ extern "C" void mod_init(Swan::Mod &mod) { | |||
mod.registerImage({ "stone", "tiles/stone.png" }); | |||
mod.registerImage({ "dirt", "tiles/dirt.png" }); | |||
mod.registerImage({ "grass", "tiles/grass.png" }); | |||
mod.registerImage({ "tree-trunk", "tiles/tree-trunk.png" }); | |||
mod.registerImage({ "player-running", "entities/player-running.png", 64 }); | |||
mod.registerImage({ "player-still", "entities/player-still.png", 64 }); | |||
@@ -34,6 +35,11 @@ extern "C" void mod_init(Swan::Mod &mod) { | |||
.image = "core::grass", | |||
.dropped_item = "core::dirt", | |||
}); | |||
mod.registerTile({ | |||
.name = "tree-trunk", | |||
.image = "core::tree-trunk", | |||
.dropped_item = "core::tree-trunk", | |||
}); | |||
mod.registerItem({ | |||
.name = "stone", | |||
@@ -47,6 +53,10 @@ extern "C" void mod_init(Swan::Mod &mod) { | |||
.name = "grass", | |||
.image = "core::grass", | |||
}); | |||
mod.registerItem({ | |||
.name = "tree-trunk", | |||
.image = "core::tree-trunk", | |||
}); | |||
mod.registerWorldGen("default", std::make_unique<WGDefault::Factory>()); | |||
@@ -9,6 +9,7 @@ add_library(libswan SHARED | |||
src/ItemStack.cc | |||
src/Mod.cc | |||
src/OS.cc | |||
src/PerfCounter.cc | |||
src/Resource.cc | |||
src/SRF.cc | |||
src/Tile.cc |
@@ -1,31 +1,37 @@ | |||
namespace Swan { | |||
#include "util.h" | |||
#include <array> | |||
namespace Swan { | |||
class PerfCounter { | |||
public: | |||
template<typename T = double, size_t size = 64> | |||
class Counter { | |||
public: | |||
void count(double val) { | |||
latest_ = val; | |||
if (count_ >= 60) { | |||
sum_ -= avg(); | |||
sum_ += val; | |||
} else { | |||
sum_ += val; | |||
count_ += 1; | |||
} | |||
void count(T val) { | |||
buf_[idx_] = val; | |||
idx_ = (idx_ + 1) % size; | |||
} | |||
double avg() { return sum_ / count_; } | |||
double latest() { return latest_; } | |||
// Fill a buffer with data, in the order they were written | |||
template<typename DestT = T> | |||
void fill(std::array<DestT, size> &buf) { | |||
size_t r = idx_; | |||
size_t w = 0; | |||
do { | |||
buf[w++] = (DestT)buf_[r]; | |||
r = (r + 1) % size; | |||
} while (r != idx_); | |||
} | |||
private: | |||
double latest_ = 0; | |||
double sum_ = 0; | |||
int count_ = 0; | |||
T buf_[size] = {}; | |||
size_t idx_ = 0; | |||
}; | |||
void render(); | |||
void countFrameTime(double secs) { frame_time_.count(secs); } | |||
void countGameUpdate(double secs) { game_update_.count(secs); } | |||
void countGameTick(double secs) { game_tick_.count(secs); } | |||
@@ -35,13 +41,13 @@ public: | |||
void countMemoryUsage(double bytes) { memory_usage_.count(bytes); } | |||
private: | |||
Counter frame_time_; | |||
Counter game_update_; | |||
Counter game_tick_; | |||
Counter game_draw_; | |||
Counter game_updates_per_frame_; | |||
Counter render_present_; | |||
Counter memory_usage_; | |||
Counter<> frame_time_; | |||
Counter<> game_update_; | |||
Counter<> game_tick_; | |||
Counter<> game_draw_; | |||
Counter<> game_updates_per_frame_; | |||
Counter<> render_present_; | |||
Counter<> memory_usage_; | |||
}; | |||
} |
@@ -26,6 +26,12 @@ public: | |||
info << "Using renderer: " << rinfo_.name; | |||
} | |||
Vec2 getPixSize() { | |||
int w, h; | |||
SDL_GetWindowSize(window_, &w, &h); | |||
return Vec2((float)w / scale_, (float)h / scale_); | |||
} | |||
Vec2 getSize() { | |||
int w, h; | |||
SDL_GetWindowSize(window_, &w, &h); |
@@ -5,6 +5,7 @@ | |||
#include <memory> | |||
#include <chrono> | |||
#include <type_traits> | |||
#include <stddef.h> | |||
namespace Swan { | |||
@@ -1 +1,22 @@ | |||
#include "PerfCounter.h" | |||
#include <imgui.h> | |||
#include "util.h" | |||
namespace Swan { | |||
void PerfCounter::render() { | |||
Deferred win([]{ ImGui::End(); }); | |||
if (!ImGui::Begin("Perf Stats")) | |||
return; | |||
ImGui::PushItemWidth(ImGui::GetFontSize() * -12); | |||
ImGui::Text("Hello World"); | |||
std::array<float, 64> buf; | |||
frame_time_.fill(buf); | |||
ImGui::PlotLines("Frame Time", buf.data(), 64); | |||
} | |||
} |
@@ -47,6 +47,7 @@ int sdlButtonToImGuiButton(uint8_t button) { | |||
int main(int argc, char **argv) { | |||
uint32_t winflags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; | |||
uint32_t renderflags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; | |||
float gui_scale = 2; | |||
for (int i = 1; i < argc; ++i) { | |||
if (strcmp(argv[i], "--lodpi") == 0) { | |||
@@ -77,7 +78,7 @@ int main(int argc, char **argv) { | |||
SDL_CreateWindow( | |||
"Project: SWAN", | |||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, | |||
640, 480, winflags), | |||
(int)(640 * gui_scale), (int)(480 * gui_scale), winflags), | |||
SDL_DestroyWindow); | |||
// Load and display application icon | |||
@@ -92,14 +93,15 @@ int main(int argc, char **argv) { | |||
SDL_DestroyRenderer); | |||
sdlassert(renderer, "Could not create renderer"); | |||
Win win(window.get(), renderer.get(), 2); | |||
Win win(window.get(), renderer.get(), gui_scale); | |||
// Init ImGUI and ImGUI_SDL | |||
IMGUI_CHECKVERSION(); | |||
ImGui::CreateContext(); | |||
auto imgui = makeDeferred([] { ImGui::DestroyContext(); }); | |||
ImGuiSDL::Initialize(renderer.get(), 640, 480); | |||
ImGuiSDL::Initialize(renderer.get(), (int)win.getPixSize().x, (int)win.getPixSize().y); | |||
auto imgui_sdl = makeDeferred([] { ImGuiSDL::Deinitialize(); }); | |||
info << "Initialized with window size " << win.getPixSize(); | |||
// ImGuiIO is to glue SDL and ImGUI together | |||
ImGuiIO& imgui_io = ImGui::GetIO(); | |||
@@ -234,18 +236,21 @@ int main(int argc, char **argv) { | |||
// ImGUI | |||
imgui_io.DeltaTime = dt; | |||
ImGui::NewFrame(); | |||
ImGui::ShowDemoWindow(); | |||
RTClock draw_clock; | |||
game.draw(); | |||
pcounter.countGameDraw(draw_clock.duration()); | |||
pcounter.countFrameTime(total_frame_clock.duration()); | |||
pcounter.render(); | |||
// Render ImGUI | |||
ImGui::Render(); | |||
ImGuiSDL::Render(ImGui::GetDrawData()); | |||
// ImGuiSDL changes renderer draw color... | |||
SDL_SetRenderDrawColor(renderer.get(), 0, 0, 0, 255); | |||
RTClock present_clock; | |||
SDL_RenderPresent(renderer.get()); | |||
pcounter.countRenderPresent(present_clock.duration()); |