Introduce new timer based on vsync
This commit is contained in:
parent
ac4d788c4c
commit
e707fae349
|
@ -2,23 +2,40 @@
|
||||||
#include "assets.hpp"
|
#include "assets.hpp"
|
||||||
#include <PSX/GPU/gpu_primitives.hpp>
|
#include <PSX/GPU/gpu_primitives.hpp>
|
||||||
#include <PSX/GPU/gpu.hpp>
|
#include <PSX/GPU/gpu.hpp>
|
||||||
|
#include <PSX/Timer/frame_timer.hpp>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace JabyEngine;
|
using namespace JabyEngine;
|
||||||
|
|
||||||
|
static SimpleTimer<uint8_t> timer;
|
||||||
|
|
||||||
static void setup() {
|
static void setup() {
|
||||||
Assets::load_for_main();
|
Assets::load_for_main();
|
||||||
FontWriter::setup();
|
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() {
|
void main() {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!");
|
update();
|
||||||
FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:");
|
render();
|
||||||
|
|
||||||
GPU::swap_buffers_vsync(1);
|
|
||||||
FontWriter::render();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,11 +16,13 @@ namespace JabyEngine {
|
||||||
namespace GPU {
|
namespace GPU {
|
||||||
struct Display {
|
struct Display {
|
||||||
#ifdef JABYENGINE_PAL
|
#ifdef JABYENGINE_PAL
|
||||||
static constexpr size_t Width = 320;
|
static constexpr size_t Width = 320;
|
||||||
static constexpr size_t Height = 256;
|
static constexpr size_t Height = 256;
|
||||||
|
static constexpr uint32_t frames_per_sec = 50;
|
||||||
#else
|
#else
|
||||||
static constexpr size_t Width = 320;
|
static constexpr size_t Width = 320;
|
||||||
static constexpr size_t Height = 240;
|
static constexpr size_t Height = 240;
|
||||||
|
static constexpr uint32_t frames_per_sec = 50;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t current_id;
|
static uint8_t current_id;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef __JABYENGINE_FRAME_TIME_HELPER_HPP__
|
||||||
|
#define __JABYENGINE_FRAME_TIME_HELPER_HPP__
|
||||||
|
#include <PSX/GPU/gpu.hpp>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
namespace JabyEngine {
|
||||||
|
static constexpr double ms_per_frame = 1000.0/static_cast<double>(GPU::Display::frames_per_sec);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static constexpr T ms_to_vsync_ticks(T time_ms) {
|
||||||
|
return static_cast<T>(static_cast<double>(time_ms)/ms_per_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t operator ""_ms(unsigned long long time) {
|
||||||
|
return static_cast<uint32_t>(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__
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef __JABYENGINE_FRAME_TIMER_HPP__
|
||||||
|
#define __JABYENGINE_FRAME_TIMER_HPP__
|
||||||
|
#include "frame_time_helper.hpp"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace JabyEngine {
|
||||||
|
class MasterTime {
|
||||||
|
private:
|
||||||
|
static uint32_t value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static uint32_t read() {
|
||||||
|
return reinterpret_cast<volatile uint32_t&>(MasterTime::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T read_as() {
|
||||||
|
return static_cast<T>(MasterTime::read());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SimpleTimer {
|
||||||
|
protected:
|
||||||
|
T value = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr SimpleTimer() = default;
|
||||||
|
|
||||||
|
bool is_expired_for(T time) const {
|
||||||
|
return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
this->value = MasterTime::read_as<T>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class IntervalTimer : public SimpleTimer<T> {
|
||||||
|
private:
|
||||||
|
T interval = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr IntervalTimer() = default;
|
||||||
|
constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_interval(T interval) {
|
||||||
|
this->interval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_expired() const {
|
||||||
|
return SimpleTimer<T>::is_expired_for(this->interval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //!__JABYENGINE_FRAME_TIMER_HPP__
|
|
@ -1,4 +1,8 @@
|
||||||
#include "../../internal-include/GPU/gpu_internal.hpp"
|
#include "../../internal-include/GPU/gpu_internal.hpp"
|
||||||
|
// We need to access the master time
|
||||||
|
#define private public
|
||||||
|
#include <PSX/Timer/frame_timer.hpp>
|
||||||
|
#undef private
|
||||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||||
#include <PSX/System/syscalls.h>
|
#include <PSX/System/syscalls.h>
|
||||||
|
|
||||||
|
@ -7,12 +11,12 @@ namespace JabyEngine {
|
||||||
uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0
|
uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
static uint8_t vsync_count = 0;
|
|
||||||
|
|
||||||
static InterruptVerifierResult interrupt_verifier();
|
static InterruptVerifierResult interrupt_verifier();
|
||||||
static void interrupt_handler(uint32_t);
|
static void interrupt_handler(uint32_t);
|
||||||
|
|
||||||
InterrupCallback callback = {
|
static uint8_t vsync_counter = 0;
|
||||||
|
|
||||||
|
InterrupCallback callback = {
|
||||||
.next = nullptr,
|
.next = nullptr,
|
||||||
.handler_function = reinterpret_cast<InterruptHandler>(interrupt_handler),
|
.handler_function = reinterpret_cast<InterruptHandler>(interrupt_handler),
|
||||||
.verifier_function = interrupt_verifier
|
.verifier_function = interrupt_verifier
|
||||||
|
@ -29,9 +33,8 @@ namespace JabyEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interrupt_handler(uint32_t) {
|
static void interrupt_handler(uint32_t) {
|
||||||
if(vsync_count != 0xFF) {
|
vsync_counter++;
|
||||||
vsync_count++;
|
MasterTime::value++;
|
||||||
}
|
|
||||||
|
|
||||||
Interrupt::ack_irq(Interrupt::VBlank);
|
Interrupt::ack_irq(Interrupt::VBlank);
|
||||||
__syscall_ReturnFromException();
|
__syscall_ReturnFromException();
|
||||||
|
@ -47,14 +50,10 @@ namespace JabyEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_vsync(uint8_t syncs) {
|
void wait_vsync(uint8_t syncs) {
|
||||||
volatile uint8_t& vsync_count = reinterpret_cast<volatile uint8_t&>(internal::vsync_count);
|
volatile auto& vsync_count = reinterpret_cast<volatile uint8_t&>(vsync_counter);
|
||||||
|
const uint8_t dst_value = vsync_count + syncs;
|
||||||
|
|
||||||
if(internal::vsync_count >= syncs) {
|
while(vsync_count != dst_value);
|
||||||
syncs = internal::vsync_count + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(vsync_count < syncs);
|
|
||||||
vsync_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const uint32_t* data, size_t words) {
|
void render(const uint32_t* data, size_t words) {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include <PSX/Timer/frame_timer.hpp>
|
||||||
|
|
||||||
|
namespace JabyEngine {
|
||||||
|
uint32_t MasterTime :: value = 0;
|
||||||
|
}
|
Loading…
Reference in New Issue