diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 1f8d9abc..f29aee5e 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -2,23 +2,40 @@ #include "assets.hpp" #include #include +#include #include using namespace JabyEngine; +static SimpleTimer timer; + static void setup() { Assets::load_for_main(); FontWriter::setup(); + + timer.reset(); +} + +static void update() { + const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!"); + FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:"); + + if(timer.is_expired_for(1000_ms)) { + printf("Dino\n"); + timer.reset(); + } +} + +static void render() { + GPU::swap_buffers_vsync(1); + FontWriter::render(); } void main() { setup(); while(true) { - const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!"); - FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:"); - - GPU::swap_buffers_vsync(1); - FontWriter::render(); + update(); + render(); } } \ No newline at end of file diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 2bc00fff..0381425c 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -16,11 +16,13 @@ namespace JabyEngine { namespace GPU { struct Display { #ifdef JABYENGINE_PAL - static constexpr size_t Width = 320; - static constexpr size_t Height = 256; + static constexpr size_t Width = 320; + static constexpr size_t Height = 256; + static constexpr uint32_t frames_per_sec = 50; #else - static constexpr size_t Width = 320; - static constexpr size_t Height = 240; + static constexpr size_t Width = 320; + static constexpr size_t Height = 240; + static constexpr uint32_t frames_per_sec = 50; #endif static uint8_t current_id; diff --git a/include/PSX/Timer/frame_time_helper.hpp b/include/PSX/Timer/frame_time_helper.hpp new file mode 100644 index 00000000..d6c32913 --- /dev/null +++ b/include/PSX/Timer/frame_time_helper.hpp @@ -0,0 +1,25 @@ +#ifndef __JABYENGINE_FRAME_TIME_HELPER_HPP__ +#define __JABYENGINE_FRAME_TIME_HELPER_HPP__ +#include +#include + +namespace JabyEngine { + static constexpr double ms_per_frame = 1000.0/static_cast(GPU::Display::frames_per_sec); + + template + static constexpr T ms_to_vsync_ticks(T time_ms) { + return static_cast(static_cast(time_ms)/ms_per_frame); + } + + static constexpr uint32_t operator ""_ms(unsigned long long time) { + return static_cast(ms_to_vsync_ticks(time)); + } + + static constexpr size_t max_ms_time_u8 = UI8_MAX*ms_per_frame; + static constexpr size_t max_ms_time_u16 = UI16_MAX*ms_per_frame; + static constexpr size_t max_ms_time_u32 = UI32_MAX; + + #undef literal_operator_template +} +using JabyEngine::operator""_ms; +#endif //!__JABYENGINE_FRAME_TIME_HELPER_HPP__ \ No newline at end of file diff --git a/include/PSX/Timer/frame_timer.hpp b/include/PSX/Timer/frame_timer.hpp new file mode 100644 index 00000000..251f644f --- /dev/null +++ b/include/PSX/Timer/frame_timer.hpp @@ -0,0 +1,59 @@ +#ifndef __JABYENGINE_FRAME_TIMER_HPP__ +#define __JABYENGINE_FRAME_TIMER_HPP__ +#include "frame_time_helper.hpp" +#include + +namespace JabyEngine { + class MasterTime { + private: + static uint32_t value; + + public: + static uint32_t read() { + return reinterpret_cast(MasterTime::value); + } + + template + static T read_as() { + return static_cast(MasterTime::read()); + } + }; + + template + class SimpleTimer { + protected: + T value = 0; + + public: + constexpr SimpleTimer() = default; + + bool is_expired_for(T time) const { + return static_cast((MasterTime::read_as() - this->value)) >= time; + } + + void reset() { + this->value = MasterTime::read_as(); + } + }; + + template + class IntervalTimer : public SimpleTimer { + private: + T interval = 0; + + public: + constexpr IntervalTimer() = default; + constexpr IntervalTimer(T interval) : SimpleTimer(), interval(interval) { + } + + void set_interval(T interval) { + this->interval = interval; + } + + bool is_expired() const { + return SimpleTimer::is_expired_for(this->interval); + } + }; +} + +#endif //!__JABYENGINE_FRAME_TIMER_HPP__ \ No newline at end of file diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index fd2f7578..8d1a6a24 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,4 +1,8 @@ #include "../../internal-include/GPU/gpu_internal.hpp" +// We need to access the master time +#define private public +#include +#undef private #include #include @@ -7,12 +11,12 @@ namespace JabyEngine { uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 namespace internal { - static uint8_t vsync_count = 0; - static InterruptVerifierResult interrupt_verifier(); static void interrupt_handler(uint32_t); - InterrupCallback callback = { + static uint8_t vsync_counter = 0; + + InterrupCallback callback = { .next = nullptr, .handler_function = reinterpret_cast(interrupt_handler), .verifier_function = interrupt_verifier @@ -29,9 +33,8 @@ namespace JabyEngine { } static void interrupt_handler(uint32_t) { - if(vsync_count != 0xFF) { - vsync_count++; - } + vsync_counter++; + MasterTime::value++; Interrupt::ack_irq(Interrupt::VBlank); __syscall_ReturnFromException(); @@ -47,14 +50,10 @@ namespace JabyEngine { } void wait_vsync(uint8_t syncs) { - volatile uint8_t& vsync_count = reinterpret_cast(internal::vsync_count); + volatile auto& vsync_count = reinterpret_cast(vsync_counter); + const uint8_t dst_value = vsync_count + syncs; - if(internal::vsync_count >= syncs) { - syncs = internal::vsync_count + 1; - } - - while(vsync_count < syncs); - vsync_count = 0; + while(vsync_count != dst_value); } void render(const uint32_t* data, size_t words) { diff --git a/src/Library/src/Timer/frame_timer.cpp b/src/Library/src/Timer/frame_timer.cpp new file mode 100644 index 00000000..1c085633 --- /dev/null +++ b/src/Library/src/Timer/frame_timer.cpp @@ -0,0 +1,5 @@ +#include + +namespace JabyEngine { + uint32_t MasterTime :: value = 0; +} \ No newline at end of file