Fix inconsistent EOL
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CDDA {
|
||||
struct TrackList {
|
||||
uint8_t first_track;
|
||||
uint8_t last_track;
|
||||
|
||||
static constexpr TrackList empty() {
|
||||
return TrackList{.first_track = 0, .last_track = 0};
|
||||
}
|
||||
};
|
||||
|
||||
TrackList get_tracks();
|
||||
|
||||
void play(uint8_t track);
|
||||
void stop();
|
||||
|
||||
void push_play();
|
||||
void pop_play();
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CDDA {
|
||||
struct TrackList {
|
||||
uint8_t first_track;
|
||||
uint8_t last_track;
|
||||
|
||||
static constexpr TrackList empty() {
|
||||
return TrackList{.first_track = 0, .last_track = 0};
|
||||
}
|
||||
};
|
||||
|
||||
TrackList get_tracks();
|
||||
|
||||
void play(uint8_t track);
|
||||
void stop();
|
||||
|
||||
void push_play();
|
||||
void pop_play();
|
||||
}
|
||||
}
|
@@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include "../AutoLBA/auto_lba.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CDXA {
|
||||
void play(const volatile AutoLBAEntry* lba, uint8_t rel_lba_idx, uint8_t channel, bool double_speed);
|
||||
void stop();
|
||||
|
||||
void set_channel(uint8_t channel);
|
||||
|
||||
void push_play();
|
||||
void pop_play();
|
||||
}
|
||||
#pragma once
|
||||
#include "../AutoLBA/auto_lba.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CDXA {
|
||||
void play(const volatile AutoLBAEntry* lba, uint8_t rel_lba_idx, uint8_t channel, bool double_speed);
|
||||
void stop();
|
||||
|
||||
void set_channel(uint8_t channel);
|
||||
|
||||
void push_play();
|
||||
void pop_play();
|
||||
}
|
||||
}
|
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
// Taken from boost endian
|
||||
|
||||
static constexpr uint8_t read_be(uint8_t x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
static constexpr uint16_t read_be(uint16_t x) {
|
||||
return (x << 8) | (x >> 8);
|
||||
}
|
||||
|
||||
static constexpr uint32_t read_be(uint32_t x) {
|
||||
const uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
// Taken from boost endian
|
||||
|
||||
static constexpr uint8_t read_be(uint8_t x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
static constexpr uint16_t read_be(uint16_t x) {
|
||||
return (x << 8) | (x >> 8);
|
||||
}
|
||||
|
||||
static constexpr uint32_t read_be(uint32_t x) {
|
||||
const uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
}
|
||||
}
|
@@ -1,61 +1,61 @@
|
||||
#pragma once
|
||||
#include "array_range.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
template<typename T>
|
||||
class CircularBuffer {
|
||||
private:
|
||||
T* start_adr = nullptr;
|
||||
T* end_adr = nullptr;
|
||||
T* read_adr = nullptr;
|
||||
T* write_adr = nullptr;
|
||||
|
||||
T* increment(T* cur_element) const {
|
||||
cur_element += 1;
|
||||
if(cur_element == this->end_adr) {
|
||||
return this->start_adr;
|
||||
}
|
||||
|
||||
return cur_element;
|
||||
}
|
||||
|
||||
public:
|
||||
CircularBuffer() = default;
|
||||
|
||||
T* setup(T* buffer_start_adr, size_t elements) {
|
||||
this->start_adr = buffer_start_adr;
|
||||
this->end_adr = &buffer_start_adr[elements];
|
||||
|
||||
this->read_adr = this->start_adr;
|
||||
this->write_adr = this->start_adr;
|
||||
return this->end_adr;
|
||||
}
|
||||
|
||||
T* allocate() {
|
||||
T* cur_adr = this->write_adr;
|
||||
T* next_adr = CircularBuffer::increment(cur_adr);
|
||||
if(next_adr == this->read_adr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
else {
|
||||
this->write_adr = next_adr;
|
||||
return cur_adr;
|
||||
}
|
||||
}
|
||||
|
||||
T* get_next() const {
|
||||
return this->read_adr;
|
||||
}
|
||||
|
||||
void pop() {
|
||||
if(CircularBuffer::has_data()) {
|
||||
this->read_adr = CircularBuffer::increment(this->read_adr);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool has_data() const {
|
||||
return (this->read_adr != this->write_adr);
|
||||
}
|
||||
};
|
||||
#pragma once
|
||||
#include "array_range.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
template<typename T>
|
||||
class CircularBuffer {
|
||||
private:
|
||||
T* start_adr = nullptr;
|
||||
T* end_adr = nullptr;
|
||||
T* read_adr = nullptr;
|
||||
T* write_adr = nullptr;
|
||||
|
||||
T* increment(T* cur_element) const {
|
||||
cur_element += 1;
|
||||
if(cur_element == this->end_adr) {
|
||||
return this->start_adr;
|
||||
}
|
||||
|
||||
return cur_element;
|
||||
}
|
||||
|
||||
public:
|
||||
CircularBuffer() = default;
|
||||
|
||||
T* setup(T* buffer_start_adr, size_t elements) {
|
||||
this->start_adr = buffer_start_adr;
|
||||
this->end_adr = &buffer_start_adr[elements];
|
||||
|
||||
this->read_adr = this->start_adr;
|
||||
this->write_adr = this->start_adr;
|
||||
return this->end_adr;
|
||||
}
|
||||
|
||||
T* allocate() {
|
||||
T* cur_adr = this->write_adr;
|
||||
T* next_adr = CircularBuffer::increment(cur_adr);
|
||||
if(next_adr == this->read_adr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
else {
|
||||
this->write_adr = next_adr;
|
||||
return cur_adr;
|
||||
}
|
||||
}
|
||||
|
||||
T* get_next() const {
|
||||
return this->read_adr;
|
||||
}
|
||||
|
||||
void pop() {
|
||||
if(CircularBuffer::has_data()) {
|
||||
this->read_adr = CircularBuffer::increment(this->read_adr);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool has_data() const {
|
||||
return (this->read_adr != this->write_adr);
|
||||
}
|
||||
};
|
||||
}
|
@@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
|
||||
namespace JabyEngine {
|
||||
template<typename T>
|
||||
static inline void dump_to_stdoutln(const T& object) {
|
||||
const uint8_t* raw_ptr = reinterpret_cast<const uint8_t*>(&object);
|
||||
|
||||
for(size_t raw_pos = 0; raw_pos < sizeof(T); raw_pos++) {
|
||||
printf("[%02X]", raw_ptr[raw_pos]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
|
||||
namespace JabyEngine {
|
||||
template<typename T>
|
||||
static inline void dump_to_stdoutln(const T& object) {
|
||||
const uint8_t* raw_ptr = reinterpret_cast<const uint8_t*>(&object);
|
||||
|
||||
for(size_t raw_pos = 0; raw_pos < sizeof(T); raw_pos++) {
|
||||
printf("[%02X]", raw_ptr[raw_pos]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "../../stdint.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
uint16_t unaligned_lhu(const uint8_t* adr) {
|
||||
return (static_cast<uint16_t>(adr[0]) | static_cast<uint16_t>(adr[1]) << 8);
|
||||
}
|
||||
#pragma once
|
||||
#include "../../stdint.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
uint16_t unaligned_lhu(const uint8_t* adr) {
|
||||
return (static_cast<uint16_t>(adr[0]) | static_cast<uint16_t>(adr[1]) << 8);
|
||||
}
|
||||
}
|
@@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
#include <stddef.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
using word_t = uint32_t;
|
||||
|
||||
static constexpr size_t bytes_to_words(size_t bytes) {
|
||||
return bytes/sizeof(word_t);
|
||||
}
|
||||
|
||||
static constexpr size_t words_to_bytes(size_t words) {
|
||||
return words*sizeof(word_t);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma once
|
||||
#include <stddef.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
using word_t = uint32_t;
|
||||
|
||||
static constexpr size_t bytes_to_words(size_t bytes) {
|
||||
return bytes/sizeof(word_t);
|
||||
}
|
||||
|
||||
static constexpr size_t words_to_bytes(size_t words) {
|
||||
return words*sizeof(word_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,73 +1,73 @@
|
||||
#pragma once
|
||||
#include "../../Auxiliary/types.hpp"
|
||||
#include "../cd_file_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
class State {
|
||||
public:
|
||||
struct Reserved {
|
||||
uint32_t reserved[8];
|
||||
};
|
||||
|
||||
struct CDDataProcessor;
|
||||
|
||||
template<typename T>
|
||||
using GenericProcessRoutine = Progress (*)(CDDataProcessor&, T&);
|
||||
|
||||
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
||||
|
||||
struct CDDataProcessor {
|
||||
ProcessRoutine process_routine = nullptr;
|
||||
const uint8_t* data_adr = nullptr;
|
||||
size_t data_bytes = 0ull;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline CDDataProcessor from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) {
|
||||
return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T simple_read_r() {
|
||||
static constexpr size_t T_SIZE = sizeof(T);
|
||||
|
||||
T value = *reinterpret_cast<const T*>(this->data_adr);
|
||||
CDDataProcessor::processed(T_SIZE);
|
||||
return value;
|
||||
}
|
||||
|
||||
constexpr void processed(size_t bytes) {
|
||||
this->data_adr += bytes;
|
||||
this->data_bytes -= bytes;
|
||||
}
|
||||
|
||||
constexpr void skip(size_t bytes) {
|
||||
CDDataProcessor::processed(bytes);
|
||||
}
|
||||
};
|
||||
|
||||
CDDataProcessor data_proc;
|
||||
Reserved reserved;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline State from(const T& state, const uint32_t* data_adr, GenericProcessRoutine<T> process_routine) {
|
||||
return {CDDataProcessor::from(process_routine, reinterpret_cast<const uint8_t*>(data_adr)), *reinterpret_cast<const Reserved*>(&state)};
|
||||
static_assert(sizeof(T) <= sizeof(Reserved));
|
||||
}
|
||||
|
||||
public:
|
||||
Progress process(size_t bytes_ready) {
|
||||
this->data_proc.data_bytes += bytes_ready;
|
||||
return (*this->data_proc.process_routine)(this->data_proc, this->reserved);
|
||||
}
|
||||
};
|
||||
|
||||
// The nothing state
|
||||
State create(const uint32_t* data_adr, const Nothing& nothing);
|
||||
State create(const uint32_t* data_adr, const SimpleTIM& file);
|
||||
State create(const uint32_t* data_adr, const TIM& file);
|
||||
State create(const uint32_t* data_adr, const VAG& file);
|
||||
|
||||
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload);
|
||||
}
|
||||
#pragma once
|
||||
#include "../../Auxiliary/types.hpp"
|
||||
#include "../cd_file_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
class State {
|
||||
public:
|
||||
struct Reserved {
|
||||
uint32_t reserved[8];
|
||||
};
|
||||
|
||||
struct CDDataProcessor;
|
||||
|
||||
template<typename T>
|
||||
using GenericProcessRoutine = Progress (*)(CDDataProcessor&, T&);
|
||||
|
||||
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
||||
|
||||
struct CDDataProcessor {
|
||||
ProcessRoutine process_routine = nullptr;
|
||||
const uint8_t* data_adr = nullptr;
|
||||
size_t data_bytes = 0ull;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline CDDataProcessor from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) {
|
||||
return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T simple_read_r() {
|
||||
static constexpr size_t T_SIZE = sizeof(T);
|
||||
|
||||
T value = *reinterpret_cast<const T*>(this->data_adr);
|
||||
CDDataProcessor::processed(T_SIZE);
|
||||
return value;
|
||||
}
|
||||
|
||||
constexpr void processed(size_t bytes) {
|
||||
this->data_adr += bytes;
|
||||
this->data_bytes -= bytes;
|
||||
}
|
||||
|
||||
constexpr void skip(size_t bytes) {
|
||||
CDDataProcessor::processed(bytes);
|
||||
}
|
||||
};
|
||||
|
||||
CDDataProcessor data_proc;
|
||||
Reserved reserved;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline State from(const T& state, const uint32_t* data_adr, GenericProcessRoutine<T> process_routine) {
|
||||
return {CDDataProcessor::from(process_routine, reinterpret_cast<const uint8_t*>(data_adr)), *reinterpret_cast<const Reserved*>(&state)};
|
||||
static_assert(sizeof(T) <= sizeof(Reserved));
|
||||
}
|
||||
|
||||
public:
|
||||
Progress process(size_t bytes_ready) {
|
||||
this->data_proc.data_bytes += bytes_ready;
|
||||
return (*this->data_proc.process_routine)(this->data_proc, this->reserved);
|
||||
}
|
||||
};
|
||||
|
||||
// The nothing state
|
||||
State create(const uint32_t* data_adr, const Nothing& nothing);
|
||||
State create(const uint32_t* data_adr, const SimpleTIM& file);
|
||||
State create(const uint32_t* data_adr, const TIM& file);
|
||||
State create(const uint32_t* data_adr, const VAG& file);
|
||||
|
||||
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload);
|
||||
}
|
||||
}
|
@@ -1,62 +1,62 @@
|
||||
#pragma once
|
||||
#include "Processor/file_processor.hpp"
|
||||
#include "cd_file_types.hpp"
|
||||
#include <limits.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
namespace Helper {
|
||||
template<typename T>
|
||||
static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::CDDataProcessor& data_proc, T& state) {
|
||||
data_proc.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine);
|
||||
return process_routine(data_proc, state);
|
||||
}
|
||||
|
||||
namespace DMA {
|
||||
struct WordsReady {
|
||||
uint32_t words_to_use;
|
||||
bool is_last;
|
||||
|
||||
static constexpr WordsReady calculate(const State::CDDataProcessor& data_proc, size_t words_left) {
|
||||
const auto config_data_words = (data_proc.data_bytes/sizeof(uint32_t));
|
||||
const auto words_to_use = (config_data_words > words_left) ? words_left : config_data_words;
|
||||
|
||||
return {
|
||||
.words_to_use = words_to_use,
|
||||
.is_last = words_to_use == words_left
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static size_t send_words(size_t words_to_send, bool send_all) {
|
||||
auto blocks_to_send = words_to_send/16;
|
||||
while(blocks_to_send > 0) {
|
||||
const auto block_send = (blocks_to_send > UI16_MAX) ? UI16_MAX : blocks_to_send;
|
||||
|
||||
// Send data!
|
||||
T::wait();
|
||||
T::Receive::start(blocks_to_send);
|
||||
blocks_to_send -= block_send;
|
||||
}
|
||||
|
||||
if(send_all) {
|
||||
const auto last_words_to_send = (words_to_send & 0b1111);
|
||||
if(last_words_to_send > 0) {
|
||||
T::wait();
|
||||
T::Receive::start(1, last_words_to_send);
|
||||
}
|
||||
|
||||
T::wait();
|
||||
T::end();
|
||||
return words_to_send;
|
||||
}
|
||||
|
||||
else {
|
||||
return (words_to_send & ~0b1111);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include "Processor/file_processor.hpp"
|
||||
#include "cd_file_types.hpp"
|
||||
#include <limits.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
namespace Helper {
|
||||
template<typename T>
|
||||
static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::CDDataProcessor& data_proc, T& state) {
|
||||
data_proc.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine);
|
||||
return process_routine(data_proc, state);
|
||||
}
|
||||
|
||||
namespace DMA {
|
||||
struct WordsReady {
|
||||
uint32_t words_to_use;
|
||||
bool is_last;
|
||||
|
||||
static constexpr WordsReady calculate(const State::CDDataProcessor& data_proc, size_t words_left) {
|
||||
const auto config_data_words = (data_proc.data_bytes/sizeof(uint32_t));
|
||||
const auto words_to_use = (config_data_words > words_left) ? words_left : config_data_words;
|
||||
|
||||
return {
|
||||
.words_to_use = words_to_use,
|
||||
.is_last = words_to_use == words_left
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static size_t send_words(size_t words_to_send, bool send_all) {
|
||||
auto blocks_to_send = words_to_send/16;
|
||||
while(blocks_to_send > 0) {
|
||||
const auto block_send = (blocks_to_send > UI16_MAX) ? UI16_MAX : blocks_to_send;
|
||||
|
||||
// Send data!
|
||||
T::wait();
|
||||
T::Receive::start(blocks_to_send);
|
||||
blocks_to_send -= block_send;
|
||||
}
|
||||
|
||||
if(send_all) {
|
||||
const auto last_words_to_send = (words_to_send & 0b1111);
|
||||
if(last_words_to_send > 0) {
|
||||
T::wait();
|
||||
T::Receive::start(1, last_words_to_send);
|
||||
}
|
||||
|
||||
T::wait();
|
||||
T::end();
|
||||
return words_to_send;
|
||||
}
|
||||
|
||||
else {
|
||||
return (words_to_send & ~0b1111);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,52 +1,52 @@
|
||||
#pragma once
|
||||
#include "../../System/IOPorts/gpu_io.hpp"
|
||||
#include "linked_elements.hpp"
|
||||
#include "primitive_support_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU {
|
||||
struct TexPage : public internal::LinkedElementCreator<TexPage> {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 value;
|
||||
|
||||
static constexpr TexPage create(const PositionU16& tex_pos, TextureColorMode tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) {
|
||||
return TexPage{.value = GPU_IO_Values::GP0::TexPage(tex_pos, transparency, tex_color, dither, false)};
|
||||
}
|
||||
};
|
||||
|
||||
struct CPU2VRAM {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 cmd;
|
||||
GPU_IO_Values::GP0 pos;
|
||||
GPU_IO_Values::GP0 size;
|
||||
|
||||
static constexpr CPU2VRAM create(const AreaU16& dst) {
|
||||
return CPU2VRAM{
|
||||
.cmd = GPU_IO_Values::GP0::CPU2VRAMBlitting(),
|
||||
.pos = GPU_IO_Values::GP0::PostionTopLeft(dst.position),
|
||||
.size = GPU_IO_Values::GP0::WidthHeight(dst.size)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct VRAM2VRAM {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 cmd;
|
||||
GPU_IO_Values::GP0 src_pos;
|
||||
GPU_IO_Values::GP0 dst_pos;
|
||||
GPU_IO_Values::GP0 size;
|
||||
|
||||
static constexpr VRAM2VRAM create(const AreaU16& src, const PositionU16& dst) {
|
||||
return VRAM2VRAM{
|
||||
.cmd = GPU_IO_Values::GP0::VRAM2VRAMBlitting(),
|
||||
.src_pos = GPU_IO_Values::GP0::PostionTopLeft(src.position),
|
||||
.dst_pos = GPU_IO_Values::GP0::PostionTopLeft(dst),
|
||||
.size = GPU_IO_Values::GP0::WidthHeight(src.size)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "../../System/IOPorts/gpu_io.hpp"
|
||||
#include "linked_elements.hpp"
|
||||
#include "primitive_support_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU {
|
||||
struct TexPage : public internal::LinkedElementCreator<TexPage> {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 value;
|
||||
|
||||
static constexpr TexPage create(const PositionU16& tex_pos, TextureColorMode tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) {
|
||||
return TexPage{.value = GPU_IO_Values::GP0::TexPage(tex_pos, transparency, tex_color, dither, false)};
|
||||
}
|
||||
};
|
||||
|
||||
struct CPU2VRAM {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 cmd;
|
||||
GPU_IO_Values::GP0 pos;
|
||||
GPU_IO_Values::GP0 size;
|
||||
|
||||
static constexpr CPU2VRAM create(const AreaU16& dst) {
|
||||
return CPU2VRAM{
|
||||
.cmd = GPU_IO_Values::GP0::CPU2VRAMBlitting(),
|
||||
.pos = GPU_IO_Values::GP0::PostionTopLeft(dst.position),
|
||||
.size = GPU_IO_Values::GP0::WidthHeight(dst.size)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct VRAM2VRAM {
|
||||
static constexpr bool is_render_primitive = true;
|
||||
|
||||
GPU_IO_Values::GP0 cmd;
|
||||
GPU_IO_Values::GP0 src_pos;
|
||||
GPU_IO_Values::GP0 dst_pos;
|
||||
GPU_IO_Values::GP0 size;
|
||||
|
||||
static constexpr VRAM2VRAM create(const AreaU16& src, const PositionU16& dst) {
|
||||
return VRAM2VRAM{
|
||||
.cmd = GPU_IO_Values::GP0::VRAM2VRAMBlitting(),
|
||||
.src_pos = GPU_IO_Values::GP0::PostionTopLeft(src.position),
|
||||
.dst_pos = GPU_IO_Values::GP0::PostionTopLeft(dst),
|
||||
.size = GPU_IO_Values::GP0::WidthHeight(src.size)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,35 +1,35 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_config.hpp"
|
||||
#include "gpu_primitives.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU {
|
||||
struct BIOS_Font {
|
||||
// This size is by Hardware limitation
|
||||
static constexpr auto Size = SizeU16::create(16, 16);
|
||||
|
||||
static constexpr auto TextureLoadPos = Configuration::BIOSFont::texture_load_pos();
|
||||
static constexpr auto CLUTLoadPos = Configuration::BIOSFont::CLUT_load_pos();
|
||||
|
||||
static constexpr TexPage get_tex_page() {
|
||||
return TexPage::create(BIOS_Font::TextureLoadPos, GPU::TextureColorMode::clut4);
|
||||
}
|
||||
|
||||
static constexpr TPage get_tpage() {
|
||||
return TPage::create(TextureLoadPos.x, TextureLoadPos.y, SemiTransparency::B_add_F, TextureColorMode::clut4);
|
||||
}
|
||||
|
||||
static constexpr PageOffset get_offset_page() {
|
||||
return PageOffset::create(BIOS_Font::CLUTLoadPos.x & 0x3F, BIOS_Font::CLUTLoadPos.y & 0xFF);
|
||||
}
|
||||
|
||||
static constexpr PageClut get_page_clut() {
|
||||
return PageClut::create(BIOS_Font::CLUTLoadPos);
|
||||
}
|
||||
|
||||
static constexpr OffsetPageWithClut get_offset_page_with_clut() {
|
||||
return OffsetPageWithClut::create(BIOS_Font::get_offset_page(), BIOS_Font::get_page_clut());
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_config.hpp"
|
||||
#include "gpu_primitives.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU {
|
||||
struct BIOS_Font {
|
||||
// This size is by Hardware limitation
|
||||
static constexpr auto Size = SizeU16::create(16, 16);
|
||||
|
||||
static constexpr auto TextureLoadPos = Configuration::BIOSFont::texture_load_pos();
|
||||
static constexpr auto CLUTLoadPos = Configuration::BIOSFont::CLUT_load_pos();
|
||||
|
||||
static constexpr TexPage get_tex_page() {
|
||||
return TexPage::create(BIOS_Font::TextureLoadPos, GPU::TextureColorMode::clut4);
|
||||
}
|
||||
|
||||
static constexpr TPage get_tpage() {
|
||||
return TPage::create(TextureLoadPos.x, TextureLoadPos.y, SemiTransparency::B_add_F, TextureColorMode::clut4);
|
||||
}
|
||||
|
||||
static constexpr PageOffset get_offset_page() {
|
||||
return PageOffset::create(BIOS_Font::CLUTLoadPos.x & 0x3F, BIOS_Font::CLUTLoadPos.y & 0xFF);
|
||||
}
|
||||
|
||||
static constexpr PageClut get_page_clut() {
|
||||
return PageClut::create(BIOS_Font::CLUTLoadPos);
|
||||
}
|
||||
|
||||
static constexpr OffsetPageWithClut get_offset_page_with_clut() {
|
||||
return OffsetPageWithClut::create(BIOS_Font::get_offset_page(), BIOS_Font::get_page_clut());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,349 +1,349 @@
|
||||
#pragma once
|
||||
#include "gpu_primitives.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Make {
|
||||
template<typename T, typename...ARGS>
|
||||
static constexpr T creator_template(const ARGS&...args) {
|
||||
return T::create(args...);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeI8 SizeI8() {
|
||||
return creator_template<GPU::SizeI8>(0_i8, 0_i8);
|
||||
}
|
||||
static constexpr GPU::SizeI8 SizeI8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::SizeI8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeU8 SizeU8() {
|
||||
return creator_template<GPU::SizeU8>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::SizeU8 SizeU8(uint8_t x, uint8_t y) {
|
||||
return creator_template<GPU::SizeU8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeI16 SizeI16() {
|
||||
return creator_template<GPU::SizeI16>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::SizeI16 SizeI16(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::SizeI16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeU16 SizeU16() {
|
||||
return creator_template<GPU::SizeU16>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::SizeU16 SizeU16(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::SizeU16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionI8 PositionI8() {
|
||||
return creator_template<GPU::PositionI8>(0_i8, 0_i8);
|
||||
}
|
||||
static constexpr GPU::PositionI8 PositionI8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::PositionI8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionU8 PositionU8() {
|
||||
return creator_template<GPU::PositionU8>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::PositionU8 PositionU8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::PositionU8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionI16 PositionI16() {
|
||||
return creator_template<GPU::PositionI16>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::PositionI16 PositionI16(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::PositionI16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionU16 PositionU16() {
|
||||
return creator_template<GPU::PositionU16>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::PositionU16 PositionU16(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::PositionU16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::Vertex Vertex() {
|
||||
return creator_template<GPU::Vertex>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::Vertex Vertex(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::Vertex>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::AreaI16 AreaI16() {
|
||||
return creator_template<GPU::AreaI16>(0, 0, 0, 0);
|
||||
}
|
||||
static constexpr GPU::AreaI16 AreaI16(int16_t x, int16_t y, int16_t w, int16_t h) {
|
||||
return creator_template<GPU::AreaI16>(x, y, w, h);
|
||||
}
|
||||
static constexpr GPU::AreaI16 AreaI16(GPU::PositionI16 pos, GPU::SizeI16 size) {
|
||||
return creator_template<GPU::AreaI16>(pos, size);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::AreaU16 AreaU16() {
|
||||
return creator_template<GPU::AreaU16>(0, 0, 0, 0);
|
||||
}
|
||||
static constexpr GPU::AreaU16 AreaU16(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
return creator_template<GPU::AreaU16>(x, y, w, h);
|
||||
}
|
||||
static constexpr GPU::AreaU16 AreaU16(GPU::PositionU16 pos, GPU::SizeU16 size) {
|
||||
return creator_template<GPU::AreaU16>(pos, size);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PageOffset PageOffset() {
|
||||
return creator_template<GPU::PageOffset>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::PageOffset PageOffset(uint8_t u, uint8_t v) {
|
||||
return creator_template<GPU::PageOffset>(u, v);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PageClut PageClut() {
|
||||
return creator_template<GPU::PageClut>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::PageClut PageClut(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::PageClut>(x, y);
|
||||
}
|
||||
static constexpr GPU::PageClut PageClut(const GPU::PositionU16& clut_pos) {
|
||||
return creator_template<GPU::PageClut>(clut_pos);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TPage TPage() {
|
||||
return creator_template<GPU::TPage>(0_u16, 0_u16, GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4);
|
||||
}
|
||||
static constexpr GPU::TPage TPage(uint16_t x, uint16_t y, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
|
||||
return creator_template<GPU::TPage>(x, y, transparency, clut_color);
|
||||
}
|
||||
static constexpr GPU::TPage TPage(const GPU::PositionU16& tex_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
|
||||
return creator_template<GPU::TPage>(tex_pos, transparency, clut_color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TexPage TexPage() {
|
||||
return creator_template<GPU::TexPage>(PositionU16(), GPU::TextureColorMode::clut4, GPU::SemiTransparency::B_Half_add_F_Half, false);
|
||||
}
|
||||
static constexpr GPU::TexPage TexPage(const GPU::PositionU16& tex_pos, GPU::TextureColorMode tex_color, GPU::SemiTransparency transparency = GPU::SemiTransparency::B_Half_add_F_Half, bool dither = false) {
|
||||
return creator_template<GPU::TexPage>(tex_pos, tex_color, transparency, dither);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut() {
|
||||
return creator_template<GPU::OffsetPageWithClut>(PageOffset(), PageClut());
|
||||
}
|
||||
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut(GPU::PageOffset tex_offset, GPU::PageClut clut) {
|
||||
return creator_template<GPU::OffsetPageWithClut>(tex_offset, clut);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::VertexColor VertexColor() {
|
||||
return creator_template<GPU::VertexColor>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
static constexpr GPU::VertexColor VertexColor(GPU::Vertex pos, GPU::Color24 color) {
|
||||
return creator_template<GPU::VertexColor>(pos, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::ColorVertex ColorVertex() {
|
||||
return creator_template<GPU::ColorVertex>(GPU::Color24::Black(), Vertex());
|
||||
}
|
||||
static constexpr GPU::ColorVertex ColorVertex(GPU::Color24 color, GPU::Vertex pos) {
|
||||
return creator_template<GPU::ColorVertex>(color, pos);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::LINE_F_SINGLE LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const GPU::Vertex& end_point) {
|
||||
return GPU::LINE_F::create(color, start_point, end_point);
|
||||
}
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr GPU::LINE_F_MULTI<sizeof...(ARGS) + 1> LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const ARGS&...rest) {
|
||||
return GPU::LINE_F::create(color, start_point, rest...);
|
||||
}
|
||||
|
||||
static constexpr GPU::LINE_G_SINGLE LINE_G(const GPU::ColorVertex& start_point, const GPU::ColorVertex& end_point) {
|
||||
return GPU::LINE_G::create(start_point, end_point);
|
||||
}
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr GPU::LINE_G_MULTI<sizeof...(ARGS) + 1> LINE_G(const GPU::ColorVertex& start_point, const ARGS&...rest) {
|
||||
return GPU::LINE_G::create(start_point, rest...);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
// ###################################################################
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::POLY_F3 POLY_F3(const GPU::Vertex (&verticies)[3], GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F3>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT3>(verticies, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::POLY_FT3::VertexEx (&vertices_ex)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_FT3>(vertices_ex, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G3 POLY_G3(const GPU::Vertex (&verticies)[3], const GPU::Color24 (&color)[3]) {
|
||||
return creator_template<GPU::POLY_G3>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G3 POLY_G3(const GPU::VertexColor (&verticies_ex)[3]) {
|
||||
return creator_template<GPU::POLY_G3>(verticies_ex);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], const GPU::Color24 (&color)[3], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT3>(verticies, tex_offset, color, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::POLY_GT3::VertexEx (&verticies_ex)[3], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT3>(verticies_ex, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_F4 POLY_F4(const GPU::Vertex (&verticies)[4], GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F4>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_F4 POLY_F4(const GPU::AreaI16& area, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F4>(area, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_FT4>(verticies, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::POLY_FT4::VertexEx (&vertices_ex)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::Vertex (&verticies)[4], const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::VertexColor (&verticies_ex)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(verticies_ex);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::AreaI16& area, const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(area, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], const GPU::Color24 (&color)[4], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT4>(verticies, tex_offset, color, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::POLY_GT4::VertexEx (&verticies_ex)[4], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT4>(verticies_ex, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_GT4>(area, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TILE_1 TILE_1() {
|
||||
return creator_template<GPU::TILE_1>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_1 TILE_1(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_1>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_8 TILE_8() {
|
||||
return creator_template<GPU::TILE_8>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_8 TILE_8(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_8>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_16 TILE_16() {
|
||||
return creator_template<GPU::TILE_16>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_16 TILE_16(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_16>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE TILE() {
|
||||
return creator_template<GPU::TILE>(AreaI16(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE TILE(const GPU::AreaI16& area, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE>(area, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SPRT_1 SPRT_1() {
|
||||
return creator_template<GPU::SPRT_1>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_1 SPRT_1(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_1>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_8 SPRT_8() {
|
||||
return creator_template<GPU::SPRT_8>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_8 SPRT_8(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_8>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_16 SPRT_16() {
|
||||
return creator_template<GPU::SPRT_16>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_16 SPRT_16(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_16>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT SPRT() {
|
||||
return creator_template<GPU::SPRT>(AreaI16(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT SPRT(const GPU::AreaI16& area, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT>(area, tex_offset_w_clut, color);
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include "gpu_primitives.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Make {
|
||||
template<typename T, typename...ARGS>
|
||||
static constexpr T creator_template(const ARGS&...args) {
|
||||
return T::create(args...);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeI8 SizeI8() {
|
||||
return creator_template<GPU::SizeI8>(0_i8, 0_i8);
|
||||
}
|
||||
static constexpr GPU::SizeI8 SizeI8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::SizeI8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeU8 SizeU8() {
|
||||
return creator_template<GPU::SizeU8>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::SizeU8 SizeU8(uint8_t x, uint8_t y) {
|
||||
return creator_template<GPU::SizeU8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeI16 SizeI16() {
|
||||
return creator_template<GPU::SizeI16>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::SizeI16 SizeI16(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::SizeI16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SizeU16 SizeU16() {
|
||||
return creator_template<GPU::SizeU16>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::SizeU16 SizeU16(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::SizeU16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionI8 PositionI8() {
|
||||
return creator_template<GPU::PositionI8>(0_i8, 0_i8);
|
||||
}
|
||||
static constexpr GPU::PositionI8 PositionI8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::PositionI8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionU8 PositionU8() {
|
||||
return creator_template<GPU::PositionU8>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::PositionU8 PositionU8(int8_t x, int8_t y) {
|
||||
return creator_template<GPU::PositionU8>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionI16 PositionI16() {
|
||||
return creator_template<GPU::PositionI16>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::PositionI16 PositionI16(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::PositionI16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PositionU16 PositionU16() {
|
||||
return creator_template<GPU::PositionU16>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::PositionU16 PositionU16(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::PositionU16>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::Vertex Vertex() {
|
||||
return creator_template<GPU::Vertex>(0_i16, 0_i16);
|
||||
}
|
||||
static constexpr GPU::Vertex Vertex(int16_t x, int16_t y) {
|
||||
return creator_template<GPU::Vertex>(x, y);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::AreaI16 AreaI16() {
|
||||
return creator_template<GPU::AreaI16>(0, 0, 0, 0);
|
||||
}
|
||||
static constexpr GPU::AreaI16 AreaI16(int16_t x, int16_t y, int16_t w, int16_t h) {
|
||||
return creator_template<GPU::AreaI16>(x, y, w, h);
|
||||
}
|
||||
static constexpr GPU::AreaI16 AreaI16(GPU::PositionI16 pos, GPU::SizeI16 size) {
|
||||
return creator_template<GPU::AreaI16>(pos, size);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::AreaU16 AreaU16() {
|
||||
return creator_template<GPU::AreaU16>(0, 0, 0, 0);
|
||||
}
|
||||
static constexpr GPU::AreaU16 AreaU16(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
return creator_template<GPU::AreaU16>(x, y, w, h);
|
||||
}
|
||||
static constexpr GPU::AreaU16 AreaU16(GPU::PositionU16 pos, GPU::SizeU16 size) {
|
||||
return creator_template<GPU::AreaU16>(pos, size);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PageOffset PageOffset() {
|
||||
return creator_template<GPU::PageOffset>(0_u8, 0_u8);
|
||||
}
|
||||
static constexpr GPU::PageOffset PageOffset(uint8_t u, uint8_t v) {
|
||||
return creator_template<GPU::PageOffset>(u, v);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::PageClut PageClut() {
|
||||
return creator_template<GPU::PageClut>(0_u16, 0_u16);
|
||||
}
|
||||
static constexpr GPU::PageClut PageClut(uint16_t x, uint16_t y) {
|
||||
return creator_template<GPU::PageClut>(x, y);
|
||||
}
|
||||
static constexpr GPU::PageClut PageClut(const GPU::PositionU16& clut_pos) {
|
||||
return creator_template<GPU::PageClut>(clut_pos);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TPage TPage() {
|
||||
return creator_template<GPU::TPage>(0_u16, 0_u16, GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4);
|
||||
}
|
||||
static constexpr GPU::TPage TPage(uint16_t x, uint16_t y, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
|
||||
return creator_template<GPU::TPage>(x, y, transparency, clut_color);
|
||||
}
|
||||
static constexpr GPU::TPage TPage(const GPU::PositionU16& tex_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
|
||||
return creator_template<GPU::TPage>(tex_pos, transparency, clut_color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TexPage TexPage() {
|
||||
return creator_template<GPU::TexPage>(PositionU16(), GPU::TextureColorMode::clut4, GPU::SemiTransparency::B_Half_add_F_Half, false);
|
||||
}
|
||||
static constexpr GPU::TexPage TexPage(const GPU::PositionU16& tex_pos, GPU::TextureColorMode tex_color, GPU::SemiTransparency transparency = GPU::SemiTransparency::B_Half_add_F_Half, bool dither = false) {
|
||||
return creator_template<GPU::TexPage>(tex_pos, tex_color, transparency, dither);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut() {
|
||||
return creator_template<GPU::OffsetPageWithClut>(PageOffset(), PageClut());
|
||||
}
|
||||
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut(GPU::PageOffset tex_offset, GPU::PageClut clut) {
|
||||
return creator_template<GPU::OffsetPageWithClut>(tex_offset, clut);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::VertexColor VertexColor() {
|
||||
return creator_template<GPU::VertexColor>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
static constexpr GPU::VertexColor VertexColor(GPU::Vertex pos, GPU::Color24 color) {
|
||||
return creator_template<GPU::VertexColor>(pos, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::ColorVertex ColorVertex() {
|
||||
return creator_template<GPU::ColorVertex>(GPU::Color24::Black(), Vertex());
|
||||
}
|
||||
static constexpr GPU::ColorVertex ColorVertex(GPU::Color24 color, GPU::Vertex pos) {
|
||||
return creator_template<GPU::ColorVertex>(color, pos);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::LINE_F_SINGLE LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const GPU::Vertex& end_point) {
|
||||
return GPU::LINE_F::create(color, start_point, end_point);
|
||||
}
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr GPU::LINE_F_MULTI<sizeof...(ARGS) + 1> LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const ARGS&...rest) {
|
||||
return GPU::LINE_F::create(color, start_point, rest...);
|
||||
}
|
||||
|
||||
static constexpr GPU::LINE_G_SINGLE LINE_G(const GPU::ColorVertex& start_point, const GPU::ColorVertex& end_point) {
|
||||
return GPU::LINE_G::create(start_point, end_point);
|
||||
}
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr GPU::LINE_G_MULTI<sizeof...(ARGS) + 1> LINE_G(const GPU::ColorVertex& start_point, const ARGS&...rest) {
|
||||
return GPU::LINE_G::create(start_point, rest...);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
// ###################################################################
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::POLY_F3 POLY_F3(const GPU::Vertex (&verticies)[3], GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F3>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT3>(verticies, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::POLY_FT3::VertexEx (&vertices_ex)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_FT3>(vertices_ex, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G3 POLY_G3(const GPU::Vertex (&verticies)[3], const GPU::Color24 (&color)[3]) {
|
||||
return creator_template<GPU::POLY_G3>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G3 POLY_G3(const GPU::VertexColor (&verticies_ex)[3]) {
|
||||
return creator_template<GPU::POLY_G3>(verticies_ex);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], const GPU::Color24 (&color)[3], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT3>(verticies, tex_offset, color, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::POLY_GT3::VertexEx (&verticies_ex)[3], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT3>(verticies_ex, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_F4 POLY_F4(const GPU::Vertex (&verticies)[4], GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F4>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_F4 POLY_F4(const GPU::AreaI16& area, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_F4>(area, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
|
||||
return creator_template<GPU::POLY_FT4>(verticies, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::POLY_FT4::VertexEx (&vertices_ex)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::Vertex (&verticies)[4], const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(verticies, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::VertexColor (&verticies_ex)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(verticies_ex);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_G4 POLY_G4(const GPU::AreaI16& area, const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_G4>(area, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], const GPU::Color24 (&color)[4], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT4>(verticies, tex_offset, color, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::POLY_GT4::VertexEx (&verticies_ex)[4], GPU::TPage tpage, GPU::PageClut clut) {
|
||||
return creator_template<GPU::POLY_GT4>(verticies_ex, tpage, clut);
|
||||
}
|
||||
|
||||
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, const GPU::Color24 (&color)[4]) {
|
||||
return creator_template<GPU::POLY_GT4>(area, tex_offset, tpage, clut, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::TILE_1 TILE_1() {
|
||||
return creator_template<GPU::TILE_1>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_1 TILE_1(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_1>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_8 TILE_8() {
|
||||
return creator_template<GPU::TILE_8>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_8 TILE_8(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_8>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_16 TILE_16() {
|
||||
return creator_template<GPU::TILE_16>(Vertex(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE_16 TILE_16(const GPU::Vertex& position, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE_16>(position, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE TILE() {
|
||||
return creator_template<GPU::TILE>(AreaI16(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::TILE TILE(const GPU::AreaI16& area, const GPU::Color24& color) {
|
||||
return creator_template<GPU::TILE>(area, color);
|
||||
}
|
||||
|
||||
// ###################################################################
|
||||
|
||||
static constexpr GPU::SPRT_1 SPRT_1() {
|
||||
return creator_template<GPU::SPRT_1>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_1 SPRT_1(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_1>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_8 SPRT_8() {
|
||||
return creator_template<GPU::SPRT_8>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_8 SPRT_8(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_8>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_16 SPRT_16() {
|
||||
return creator_template<GPU::SPRT_16>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT_16 SPRT_16(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT_16>(position, tex_offset_w_clut, color);
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT SPRT() {
|
||||
return creator_template<GPU::SPRT>(AreaI16(), OffsetPageWithClut(), GPU::Color24::Black());
|
||||
}
|
||||
|
||||
static constexpr GPU::SPRT SPRT(const GPU::AreaI16& area, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
|
||||
return creator_template<GPU::SPRT>(area, tex_offset_w_clut, color);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,241 +1,241 @@
|
||||
#pragma once
|
||||
#include "gte_instruction.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
static constexpr auto StackSize = 16;
|
||||
|
||||
/*
|
||||
matrix: first input
|
||||
|
||||
Sets the 3x3 constant rotation matrix and the parallel transfer vector from input
|
||||
*/
|
||||
void set_matrix(const MATRIX& matrix);
|
||||
|
||||
/*
|
||||
returns: current matrix
|
||||
|
||||
Gets the current 3x3 constant rotation matrix and the parallel transfer vector
|
||||
*/
|
||||
MATRIX get_matrix();
|
||||
|
||||
/*
|
||||
RotTrans
|
||||
|
||||
Perform coordinate transformation using a rotation matrix
|
||||
input: Input vector
|
||||
output: Output vector
|
||||
flag: flag output
|
||||
*/
|
||||
static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) {
|
||||
ldv0(input);
|
||||
rt();
|
||||
stlvnl(output);
|
||||
stflg(flag);
|
||||
}
|
||||
|
||||
/*
|
||||
ScaleMatrix
|
||||
|
||||
m: Pointer to matrix (input/output)
|
||||
v: Pointer to scale vector (input)
|
||||
|
||||
result: m
|
||||
Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096
|
||||
*/
|
||||
static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) {
|
||||
static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) {
|
||||
ldir0(value); // lwc2 r8, v.x
|
||||
ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2)
|
||||
gpf12(); // gte_gpf12
|
||||
stclmv(matrix, row); // store matrix row
|
||||
};
|
||||
|
||||
multiply_matrix_row(v.x, m, 0);
|
||||
multiply_matrix_row(v.y, m, 1);
|
||||
multiply_matrix_row(v.z, m, 2);
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
SetRotMatrix
|
||||
|
||||
Sets a 3x3 matrix m as a constant rotation matrix.
|
||||
matrix: The rotation matrix to set
|
||||
*/
|
||||
static void set_rot_matrix(const ROTMATRIX& matrix) {
|
||||
__asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
GetRotMatrix
|
||||
|
||||
Writes the current 3x3 constant rotation matrix to matrix
|
||||
(This doesn't require us to use memory clobber)
|
||||
*/
|
||||
static void get_rot_matrix(ROTMATRIX &matrix) {
|
||||
__asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
SetTransMatrix
|
||||
|
||||
Sets a constant parallel transfer vector specified by m
|
||||
*/
|
||||
static void set_trans_vector(const TRANSFERVECTOR& vector) {
|
||||
__asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
GetTransMatrix
|
||||
|
||||
Writes the current constant parallel transfer vector to matrix
|
||||
(This doesn't require us to use memory clobber)
|
||||
*/
|
||||
static void get_trans_vector(TRANSFERVECTOR& vector) {
|
||||
__asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
ApplyMatrix
|
||||
m0: Matrix to apply
|
||||
v0: Vector to apply to
|
||||
v1: Result
|
||||
returns: result
|
||||
|
||||
Applies the matrix to the vector
|
||||
The function destroys the constant rotation matrix and transfer vector
|
||||
*/
|
||||
static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) {
|
||||
set_matrix(m0);
|
||||
|
||||
JabyEngine::GTE::ldv0(v0);
|
||||
JabyEngine::GTE::rt();
|
||||
JabyEngine::GTE::stsv(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/*
|
||||
Same as apply_matrix but works on Vertex
|
||||
*/
|
||||
static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) {
|
||||
set_matrix(m0);
|
||||
|
||||
JabyEngine::GTE::ldgv0(v0);
|
||||
JabyEngine::GTE::rt();
|
||||
JabyEngine::GTE::stgv(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/*
|
||||
MulMatrix0
|
||||
|
||||
m0: first input
|
||||
m1: second input
|
||||
result: result of multiplication
|
||||
returns: result
|
||||
|
||||
Multiplies two matrices m0 and m1.
|
||||
The function destroys the constant rotation matrix
|
||||
*/
|
||||
ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result);
|
||||
|
||||
/*
|
||||
CompMatrix
|
||||
|
||||
m0: first input
|
||||
m1: second input
|
||||
result: result of computing m0 and m1
|
||||
return: returns result
|
||||
*/
|
||||
static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) {
|
||||
multiply_matrix(m0.rotation, m1.rotation, result.rotation);
|
||||
set_trans_vector(m0.transfer);
|
||||
GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer));
|
||||
GTE::rt();
|
||||
GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
matrix: optional input
|
||||
|
||||
Pushes the current matrix (rotation and parallel) to an internal stack
|
||||
Optional: replaces current matrix (rotation and parallel) with input
|
||||
*/
|
||||
void push_matrix();
|
||||
void push_matrix_and_set(const MATRIX& matrix);
|
||||
|
||||
/*
|
||||
Restores the previous stored matrix (rotation and parallel)
|
||||
*/
|
||||
MATRIX get_and_pop_matrix();
|
||||
void pop_matrix();
|
||||
|
||||
/*
|
||||
SetGeomOffset(ofx,ofy)
|
||||
|
||||
Load GTE-offset.
|
||||
*/
|
||||
static void set_geom_offset(int32_t off_x, int32_t off_y) {
|
||||
__asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
}
|
||||
|
||||
/*
|
||||
SetGeomScreen(h)
|
||||
|
||||
Load distance from viewpoint to screen.
|
||||
*/
|
||||
static void set_geom_screen(int32_t h) {
|
||||
__asm__ volatile("ctc2 %0, $26" :: "r"(h));
|
||||
}
|
||||
|
||||
// Implementations for the MATRIX struct
|
||||
inline MATRIX& MATRIX :: comp(const MATRIX& matrix) {
|
||||
return comp_matrix(matrix, *this, *this);
|
||||
}
|
||||
|
||||
inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const {
|
||||
return apply_matrix(*this, vertex, vertex);
|
||||
}
|
||||
|
||||
inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const {
|
||||
GPU::Vertex result;
|
||||
|
||||
apply_matrix(*this, vertex, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include "gte_instruction.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
static constexpr auto StackSize = 16;
|
||||
|
||||
/*
|
||||
matrix: first input
|
||||
|
||||
Sets the 3x3 constant rotation matrix and the parallel transfer vector from input
|
||||
*/
|
||||
void set_matrix(const MATRIX& matrix);
|
||||
|
||||
/*
|
||||
returns: current matrix
|
||||
|
||||
Gets the current 3x3 constant rotation matrix and the parallel transfer vector
|
||||
*/
|
||||
MATRIX get_matrix();
|
||||
|
||||
/*
|
||||
RotTrans
|
||||
|
||||
Perform coordinate transformation using a rotation matrix
|
||||
input: Input vector
|
||||
output: Output vector
|
||||
flag: flag output
|
||||
*/
|
||||
static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) {
|
||||
ldv0(input);
|
||||
rt();
|
||||
stlvnl(output);
|
||||
stflg(flag);
|
||||
}
|
||||
|
||||
/*
|
||||
ScaleMatrix
|
||||
|
||||
m: Pointer to matrix (input/output)
|
||||
v: Pointer to scale vector (input)
|
||||
|
||||
result: m
|
||||
Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096
|
||||
*/
|
||||
static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) {
|
||||
static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) {
|
||||
ldir0(value); // lwc2 r8, v.x
|
||||
ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2)
|
||||
gpf12(); // gte_gpf12
|
||||
stclmv(matrix, row); // store matrix row
|
||||
};
|
||||
|
||||
multiply_matrix_row(v.x, m, 0);
|
||||
multiply_matrix_row(v.y, m, 1);
|
||||
multiply_matrix_row(v.z, m, 2);
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
SetRotMatrix
|
||||
|
||||
Sets a 3x3 matrix m as a constant rotation matrix.
|
||||
matrix: The rotation matrix to set
|
||||
*/
|
||||
static void set_rot_matrix(const ROTMATRIX& matrix) {
|
||||
__asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
GetRotMatrix
|
||||
|
||||
Writes the current 3x3 constant rotation matrix to matrix
|
||||
(This doesn't require us to use memory clobber)
|
||||
*/
|
||||
static void get_rot_matrix(ROTMATRIX &matrix) {
|
||||
__asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
SetTransMatrix
|
||||
|
||||
Sets a constant parallel transfer vector specified by m
|
||||
*/
|
||||
static void set_trans_vector(const TRANSFERVECTOR& vector) {
|
||||
__asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
GetTransMatrix
|
||||
|
||||
Writes the current constant parallel transfer vector to matrix
|
||||
(This doesn't require us to use memory clobber)
|
||||
*/
|
||||
static void get_trans_vector(TRANSFERVECTOR& vector) {
|
||||
__asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
/*
|
||||
ApplyMatrix
|
||||
m0: Matrix to apply
|
||||
v0: Vector to apply to
|
||||
v1: Result
|
||||
returns: result
|
||||
|
||||
Applies the matrix to the vector
|
||||
The function destroys the constant rotation matrix and transfer vector
|
||||
*/
|
||||
static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) {
|
||||
set_matrix(m0);
|
||||
|
||||
JabyEngine::GTE::ldv0(v0);
|
||||
JabyEngine::GTE::rt();
|
||||
JabyEngine::GTE::stsv(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/*
|
||||
Same as apply_matrix but works on Vertex
|
||||
*/
|
||||
static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) {
|
||||
set_matrix(m0);
|
||||
|
||||
JabyEngine::GTE::ldgv0(v0);
|
||||
JabyEngine::GTE::rt();
|
||||
JabyEngine::GTE::stgv(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/*
|
||||
MulMatrix0
|
||||
|
||||
m0: first input
|
||||
m1: second input
|
||||
result: result of multiplication
|
||||
returns: result
|
||||
|
||||
Multiplies two matrices m0 and m1.
|
||||
The function destroys the constant rotation matrix
|
||||
*/
|
||||
ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result);
|
||||
|
||||
/*
|
||||
CompMatrix
|
||||
|
||||
m0: first input
|
||||
m1: second input
|
||||
result: result of computing m0 and m1
|
||||
return: returns result
|
||||
*/
|
||||
static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) {
|
||||
multiply_matrix(m0.rotation, m1.rotation, result.rotation);
|
||||
set_trans_vector(m0.transfer);
|
||||
GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer));
|
||||
GTE::rt();
|
||||
GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
matrix: optional input
|
||||
|
||||
Pushes the current matrix (rotation and parallel) to an internal stack
|
||||
Optional: replaces current matrix (rotation and parallel) with input
|
||||
*/
|
||||
void push_matrix();
|
||||
void push_matrix_and_set(const MATRIX& matrix);
|
||||
|
||||
/*
|
||||
Restores the previous stored matrix (rotation and parallel)
|
||||
*/
|
||||
MATRIX get_and_pop_matrix();
|
||||
void pop_matrix();
|
||||
|
||||
/*
|
||||
SetGeomOffset(ofx,ofy)
|
||||
|
||||
Load GTE-offset.
|
||||
*/
|
||||
static void set_geom_offset(int32_t off_x, int32_t off_y) {
|
||||
__asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
__asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13");
|
||||
}
|
||||
|
||||
/*
|
||||
SetGeomScreen(h)
|
||||
|
||||
Load distance from viewpoint to screen.
|
||||
*/
|
||||
static void set_geom_screen(int32_t h) {
|
||||
__asm__ volatile("ctc2 %0, $26" :: "r"(h));
|
||||
}
|
||||
|
||||
// Implementations for the MATRIX struct
|
||||
inline MATRIX& MATRIX :: comp(const MATRIX& matrix) {
|
||||
return comp_matrix(matrix, *this, *this);
|
||||
}
|
||||
|
||||
inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const {
|
||||
return apply_matrix(*this, vertex, vertex);
|
||||
}
|
||||
|
||||
inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const {
|
||||
GPU::Vertex result;
|
||||
|
||||
apply_matrix(*this, vertex, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,137 +1,137 @@
|
||||
#pragma once
|
||||
#include "gte_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
// Load vertex or normal to vertex register 0
|
||||
static __always_inline void ldv0(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load vertex or normal to vertex register 1
|
||||
static __always_inline void ldv1(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load vertex or normal to vertex register 2
|
||||
static __always_inline void ldv2(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load int32_t to ir0 register (for multiplying usually)
|
||||
static __always_inline void ldir0(const int32_t& value) {
|
||||
__asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value));
|
||||
}
|
||||
|
||||
// Load LS 16 bits of VECTOR to 16 bit universal vector.
|
||||
static __always_inline void ldlv0(const VECTOR& vector) {
|
||||
__asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
}
|
||||
|
||||
// Loads a GPU VERTEX type
|
||||
static __always_inline void ldgv0(const GPU::Vertex& vertex) {
|
||||
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex));
|
||||
__asm__ volatile("lwc2 $1, 0" :: "r"(&vertex));
|
||||
}
|
||||
|
||||
// Load column vector of MATRIX to universal register
|
||||
static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) {
|
||||
__asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
// Store flag
|
||||
static __always_inline void stflg(int32_t& flag) {
|
||||
__asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory");
|
||||
__asm__ volatile("nop" :: "r"(&flag) : "$12", "memory");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory");
|
||||
}
|
||||
|
||||
// Store MATRIX column from 16 bit universal register
|
||||
static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
// Store VECTOR from 32 bit universal register
|
||||
static __always_inline void stlvnl(VECTOR& out_vector) {
|
||||
__asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory");
|
||||
__asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory");
|
||||
__asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory");
|
||||
}
|
||||
|
||||
// Modify to store in VERTEX?
|
||||
// Store SVECTOR from 16 bit universal register
|
||||
static __always_inline void stsv(SVECTOR& out_vector) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
// Stores result into a GPU Vertex type
|
||||
static __always_inline void stgv(GPU::Vertex& out_vertex) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
Kernel of RotTrans
|
||||
(Transfer vector)+(Rotation Matrix)*(vertex register 0)
|
||||
*/
|
||||
static __always_inline void rt() {
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x0480012");
|
||||
}
|
||||
|
||||
/*
|
||||
Variation of gte_rt
|
||||
(Rotation Matrix)*(vertex register 0).
|
||||
*/
|
||||
static __always_inline void rtv0() {
|
||||
__asm__ volatile("nop;");
|
||||
__asm__ volatile("nop;");
|
||||
__asm__ volatile("cop2 0x0486012;");
|
||||
}
|
||||
|
||||
/*
|
||||
Variation of gte_rt
|
||||
(Rotation Matrix)*(16 bit universal vector)
|
||||
*/
|
||||
static __always_inline void rtir() {
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x049E012");
|
||||
}
|
||||
|
||||
/*
|
||||
Last half of LoadAverage12.
|
||||
*/
|
||||
static __always_inline void gpf12(){
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x0198003D");
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include "gte_types.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
// Load vertex or normal to vertex register 0
|
||||
static __always_inline void ldv0(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load vertex or normal to vertex register 1
|
||||
static __always_inline void ldv1(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load vertex or normal to vertex register 2
|
||||
static __always_inline void ldv2(const SVECTOR& vector) {
|
||||
__asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector));
|
||||
__asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector));
|
||||
}
|
||||
|
||||
// Load int32_t to ir0 register (for multiplying usually)
|
||||
static __always_inline void ldir0(const int32_t& value) {
|
||||
__asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value));
|
||||
}
|
||||
|
||||
// Load LS 16 bits of VECTOR to 16 bit universal vector.
|
||||
static __always_inline void ldlv0(const VECTOR& vector) {
|
||||
__asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13");
|
||||
__asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13");
|
||||
}
|
||||
|
||||
// Loads a GPU VERTEX type
|
||||
static __always_inline void ldgv0(const GPU::Vertex& vertex) {
|
||||
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex));
|
||||
__asm__ volatile("lwc2 $1, 0" :: "r"(&vertex));
|
||||
}
|
||||
|
||||
// Load column vector of MATRIX to universal register
|
||||
static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) {
|
||||
__asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
__asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
|
||||
}
|
||||
|
||||
// Store flag
|
||||
static __always_inline void stflg(int32_t& flag) {
|
||||
__asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory");
|
||||
__asm__ volatile("nop" :: "r"(&flag) : "$12", "memory");
|
||||
__asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory");
|
||||
}
|
||||
|
||||
// Store MATRIX column from 16 bit universal register
|
||||
static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
// Store VECTOR from 32 bit universal register
|
||||
static __always_inline void stlvnl(VECTOR& out_vector) {
|
||||
__asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory");
|
||||
__asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory");
|
||||
__asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory");
|
||||
}
|
||||
|
||||
// Modify to store in VERTEX?
|
||||
// Store SVECTOR from 16 bit universal register
|
||||
static __always_inline void stsv(SVECTOR& out_vector) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
// Stores result into a GPU Vertex type
|
||||
static __always_inline void stgv(GPU::Vertex& out_vertex) {
|
||||
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
Kernel of RotTrans
|
||||
(Transfer vector)+(Rotation Matrix)*(vertex register 0)
|
||||
*/
|
||||
static __always_inline void rt() {
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x0480012");
|
||||
}
|
||||
|
||||
/*
|
||||
Variation of gte_rt
|
||||
(Rotation Matrix)*(vertex register 0).
|
||||
*/
|
||||
static __always_inline void rtv0() {
|
||||
__asm__ volatile("nop;");
|
||||
__asm__ volatile("nop;");
|
||||
__asm__ volatile("cop2 0x0486012;");
|
||||
}
|
||||
|
||||
/*
|
||||
Variation of gte_rt
|
||||
(Rotation Matrix)*(16 bit universal vector)
|
||||
*/
|
||||
static __always_inline void rtir() {
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x049E012");
|
||||
}
|
||||
|
||||
/*
|
||||
Last half of LoadAverage12.
|
||||
*/
|
||||
static __always_inline void gpf12(){
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("nop");
|
||||
__asm__ volatile("cop2 0x0198003D");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,138 +1,138 @@
|
||||
#pragma once
|
||||
#include "../GPU/Primitives/primitive_poly_types.hpp"
|
||||
#include "../GPU/gpu_types.hpp"
|
||||
#include "../../math.hpp"
|
||||
#include "../../stdio.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
struct VECTOR {
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
T pad;
|
||||
|
||||
static constexpr VECTOR create() {
|
||||
return VECTOR::create(0, 0, 0);
|
||||
}
|
||||
|
||||
static constexpr VECTOR create(T x, T y, T z) {
|
||||
return VECTOR{.x = x, .y = y, .z = z, .pad = 0};
|
||||
}
|
||||
|
||||
static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) {
|
||||
return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)};
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
static constexpr VECTOR from(const GPU::Position<S>& pos) {
|
||||
return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0);
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
constexpr S to() const {
|
||||
return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y));
|
||||
}
|
||||
};
|
||||
}
|
||||
using VECTOR = internal::VECTOR<int32_t>;
|
||||
using SVECTOR = internal::VECTOR<int16_t>;
|
||||
|
||||
struct ROTMATRIX {
|
||||
int16_t matrix[3][3];
|
||||
|
||||
static constexpr ROTMATRIX identity() {
|
||||
return ROTMATRIX{.matrix = {
|
||||
{static_cast<int16_t>(gte_float::one()), 0, 0},
|
||||
{0, static_cast<int16_t>(gte_float::one()), 0},
|
||||
{0, 0, static_cast<int16_t>(gte_float::one())}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr ROTMATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return ROTMATRIX{.matrix = {
|
||||
{static_cast<int16_t>(sx), 0, 0},
|
||||
{0, static_cast<int16_t>(sy), 0},
|
||||
{0, 0, static_cast<int16_t>(sz)}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static ROTMATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg);
|
||||
};
|
||||
|
||||
struct TRANSFERVECTOR : public VECTOR {
|
||||
static constexpr TRANSFERVECTOR identity() {
|
||||
return TRANSFERVECTOR::translated();
|
||||
}
|
||||
|
||||
static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return TRANSFERVECTOR{{.x = x, .y = y, .z = z}};
|
||||
}
|
||||
};
|
||||
|
||||
struct MATRIX {
|
||||
ROTMATRIX rotation;
|
||||
TRANSFERVECTOR transfer;
|
||||
|
||||
static constexpr MATRIX identity() {
|
||||
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)};
|
||||
}
|
||||
|
||||
static constexpr MATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return MATRIX{.rotation = ROTMATRIX::scaled(sx, sy, sz), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static MATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
|
||||
return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) {
|
||||
new_matrix.comp(matrix);
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
void dump() const {
|
||||
printf("---\n");
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[0][0], this->rotation.matrix[0][1], this->rotation.matrix[0][2]);
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[1][0], this->rotation.matrix[1][1], this->rotation.matrix[1][2]);
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[2][0], this->rotation.matrix[2][1], this->rotation.matrix[2][2]);
|
||||
printf("~~~\n");
|
||||
printf("|%i|%i|%i|\n", this->transfer.x, this->transfer.y, this->transfer.z);
|
||||
printf("---\n");
|
||||
}
|
||||
|
||||
MATRIX& comp(const MATRIX& matrix);
|
||||
MATRIX& translate(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return MATRIX::comp(MATRIX::translated(x, y, z));
|
||||
}
|
||||
|
||||
MATRIX& scale(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return MATRIX::comp(MATRIX::scaled(sx, sy, sz));
|
||||
}
|
||||
|
||||
MATRIX& rotate(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
|
||||
return MATRIX::comp(MATRIX::rotated(x, y, z));
|
||||
}
|
||||
|
||||
GPU::Vertex& apply_to(GPU::Vertex& vertex) const;
|
||||
GPU::Vertex apply_to(const GPU::Vertex& vertex) const;
|
||||
|
||||
template<typename T>
|
||||
T& apply_to_area(T& poly, const GPU::AreaI16& area) const {
|
||||
poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area));
|
||||
poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area));
|
||||
poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area));
|
||||
poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area));
|
||||
return poly;
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "../GPU/Primitives/primitive_poly_types.hpp"
|
||||
#include "../GPU/gpu_types.hpp"
|
||||
#include "../../math.hpp"
|
||||
#include "../../stdio.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GTE {
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
struct VECTOR {
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
T pad;
|
||||
|
||||
static constexpr VECTOR create() {
|
||||
return VECTOR::create(0, 0, 0);
|
||||
}
|
||||
|
||||
static constexpr VECTOR create(T x, T y, T z) {
|
||||
return VECTOR{.x = x, .y = y, .z = z, .pad = 0};
|
||||
}
|
||||
|
||||
static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) {
|
||||
return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)};
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
static constexpr VECTOR from(const GPU::Position<S>& pos) {
|
||||
return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0);
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
constexpr S to() const {
|
||||
return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y));
|
||||
}
|
||||
};
|
||||
}
|
||||
using VECTOR = internal::VECTOR<int32_t>;
|
||||
using SVECTOR = internal::VECTOR<int16_t>;
|
||||
|
||||
struct ROTMATRIX {
|
||||
int16_t matrix[3][3];
|
||||
|
||||
static constexpr ROTMATRIX identity() {
|
||||
return ROTMATRIX{.matrix = {
|
||||
{static_cast<int16_t>(gte_float::one()), 0, 0},
|
||||
{0, static_cast<int16_t>(gte_float::one()), 0},
|
||||
{0, 0, static_cast<int16_t>(gte_float::one())}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr ROTMATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return ROTMATRIX{.matrix = {
|
||||
{static_cast<int16_t>(sx), 0, 0},
|
||||
{0, static_cast<int16_t>(sy), 0},
|
||||
{0, 0, static_cast<int16_t>(sz)}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static ROTMATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg);
|
||||
};
|
||||
|
||||
struct TRANSFERVECTOR : public VECTOR {
|
||||
static constexpr TRANSFERVECTOR identity() {
|
||||
return TRANSFERVECTOR::translated();
|
||||
}
|
||||
|
||||
static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return TRANSFERVECTOR{{.x = x, .y = y, .z = z}};
|
||||
}
|
||||
};
|
||||
|
||||
struct MATRIX {
|
||||
ROTMATRIX rotation;
|
||||
TRANSFERVECTOR transfer;
|
||||
|
||||
static constexpr MATRIX identity() {
|
||||
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)};
|
||||
}
|
||||
|
||||
static constexpr MATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return MATRIX{.rotation = ROTMATRIX::scaled(sx, sy, sz), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static MATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
|
||||
return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()};
|
||||
}
|
||||
|
||||
static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) {
|
||||
new_matrix.comp(matrix);
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
void dump() const {
|
||||
printf("---\n");
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[0][0], this->rotation.matrix[0][1], this->rotation.matrix[0][2]);
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[1][0], this->rotation.matrix[1][1], this->rotation.matrix[1][2]);
|
||||
printf("|%i|%i|%i|\n", this->rotation.matrix[2][0], this->rotation.matrix[2][1], this->rotation.matrix[2][2]);
|
||||
printf("~~~\n");
|
||||
printf("|%i|%i|%i|\n", this->transfer.x, this->transfer.y, this->transfer.z);
|
||||
printf("---\n");
|
||||
}
|
||||
|
||||
MATRIX& comp(const MATRIX& matrix);
|
||||
MATRIX& translate(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
|
||||
return MATRIX::comp(MATRIX::translated(x, y, z));
|
||||
}
|
||||
|
||||
MATRIX& scale(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
|
||||
return MATRIX::comp(MATRIX::scaled(sx, sy, sz));
|
||||
}
|
||||
|
||||
MATRIX& rotate(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
|
||||
return MATRIX::comp(MATRIX::rotated(x, y, z));
|
||||
}
|
||||
|
||||
GPU::Vertex& apply_to(GPU::Vertex& vertex) const;
|
||||
GPU::Vertex apply_to(const GPU::Vertex& vertex) const;
|
||||
|
||||
template<typename T>
|
||||
T& apply_to_area(T& poly, const GPU::AreaI16& area) const {
|
||||
poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area));
|
||||
poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area));
|
||||
poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area));
|
||||
poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area));
|
||||
return poly;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,107 +1,107 @@
|
||||
#pragma once
|
||||
#include "../GPU/gpu_types.hpp"
|
||||
#include "raw_controller.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
class GenericController : public RawController {
|
||||
public:
|
||||
struct Rumble {
|
||||
static constexpr uint8_t LargeMotorThreshold = 0x60;
|
||||
};
|
||||
|
||||
enum struct Button : uint16_t {
|
||||
L2 = static_cast<uint16_t>(GenericButton::D0),
|
||||
R2 = static_cast<uint16_t>(GenericButton::D1),
|
||||
L1 = static_cast<uint16_t>(GenericButton::D2),
|
||||
R1 = static_cast<uint16_t>(GenericButton::D3),
|
||||
Triangle = static_cast<uint16_t>(GenericButton::D4),
|
||||
Circle = static_cast<uint16_t>(GenericButton::D5),
|
||||
Cross = static_cast<uint16_t>(GenericButton::D6),
|
||||
Square = static_cast<uint16_t>(GenericButton::D7),
|
||||
SEL = static_cast<uint16_t>(GenericButton::D8),
|
||||
ST = static_cast<uint16_t>(GenericButton::D11),
|
||||
Up = static_cast<uint16_t>(GenericButton::D12),
|
||||
Right = static_cast<uint16_t>(GenericButton::D13),
|
||||
Down = static_cast<uint16_t>(GenericButton::D14),
|
||||
Left = static_cast<uint16_t>(GenericButton::D15)
|
||||
};
|
||||
|
||||
void set_digital_rumble() {
|
||||
RawController::header.rumble0 = 0x1;
|
||||
RawController::header.rumble1 = 0x7F;
|
||||
}
|
||||
|
||||
void set_analog_rumble(uint8_t largeMotor, bool smallMotor) {
|
||||
RawController::header.rumble0 = smallMotor ? 0x1 : 0x0;
|
||||
RawController::header.rumble1 = largeMotor;
|
||||
}
|
||||
|
||||
void stopRumble() {
|
||||
RawController::header.rumble0 = 0x0;
|
||||
RawController::header.rumble1 = 0x0;
|
||||
}
|
||||
|
||||
bool is_small_rumble() const {
|
||||
return static_cast<bool>(RawController::header.rumble0);
|
||||
}
|
||||
|
||||
uint8_t get_large_rumble() const {
|
||||
return RawController::header.rumble1;
|
||||
}
|
||||
|
||||
bool is_connected() const {
|
||||
return RawController::header.state != RawController::State::Disconnected;
|
||||
}
|
||||
|
||||
bool is_useable() const {
|
||||
const auto type = RawController::get_type();
|
||||
return ((RawController::header.state == RawController::State::Stable) && (type == ControllerType::Controller || type == ControllerType::DualShock));
|
||||
}
|
||||
};
|
||||
|
||||
class AnalogeController : public GenericController {
|
||||
public:
|
||||
enum struct Button : uint16_t {
|
||||
L2 = static_cast<uint16_t>(GenericButton::D0),
|
||||
R2 = static_cast<uint16_t>(GenericButton::D1),
|
||||
L1 = static_cast<uint16_t>(GenericButton::D2),
|
||||
R1 = static_cast<uint16_t>(GenericButton::D3),
|
||||
Triangle = static_cast<uint16_t>(GenericButton::D4),
|
||||
Circle = static_cast<uint16_t>(GenericButton::D5),
|
||||
Cross = static_cast<uint16_t>(GenericButton::D6),
|
||||
Square = static_cast<uint16_t>(GenericButton::D7),
|
||||
SEL = static_cast<uint16_t>(GenericButton::D8),
|
||||
L3 = static_cast<uint16_t>(GenericButton::D9),
|
||||
R3 = static_cast<uint16_t>(GenericButton::D10),
|
||||
ST = static_cast<uint16_t>(GenericButton::D11),
|
||||
Up = static_cast<uint16_t>(GenericButton::D12),
|
||||
Right = static_cast<uint16_t>(GenericButton::D13),
|
||||
Down = static_cast<uint16_t>(GenericButton::D14),
|
||||
Left = static_cast<uint16_t>(GenericButton::D15)
|
||||
};
|
||||
|
||||
private:
|
||||
uint8_t read_special_byte(size_t idx) const {
|
||||
return reinterpret_cast<const uint8_t(&)[4]>(this->special)[idx];
|
||||
}
|
||||
|
||||
public:
|
||||
GPU::PositionI16 get_right_stick_pos() const {
|
||||
const uint8_t joy_x = AnalogeController::read_special_byte(0);
|
||||
const uint8_t joy_y = AnalogeController::read_special_byte(1);
|
||||
|
||||
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
|
||||
}
|
||||
|
||||
GPU::PositionI16 get_left_stick_pos() const {
|
||||
const uint8_t joy_x = AnalogeController::read_special_byte(2);
|
||||
const uint8_t joy_y = AnalogeController::read_special_byte(3);
|
||||
|
||||
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
|
||||
}
|
||||
};
|
||||
|
||||
using GenericButtonState = GenericController::ButtonState;
|
||||
}
|
||||
#pragma once
|
||||
#include "../GPU/gpu_types.hpp"
|
||||
#include "raw_controller.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
class GenericController : public RawController {
|
||||
public:
|
||||
struct Rumble {
|
||||
static constexpr uint8_t LargeMotorThreshold = 0x60;
|
||||
};
|
||||
|
||||
enum struct Button : uint16_t {
|
||||
L2 = static_cast<uint16_t>(GenericButton::D0),
|
||||
R2 = static_cast<uint16_t>(GenericButton::D1),
|
||||
L1 = static_cast<uint16_t>(GenericButton::D2),
|
||||
R1 = static_cast<uint16_t>(GenericButton::D3),
|
||||
Triangle = static_cast<uint16_t>(GenericButton::D4),
|
||||
Circle = static_cast<uint16_t>(GenericButton::D5),
|
||||
Cross = static_cast<uint16_t>(GenericButton::D6),
|
||||
Square = static_cast<uint16_t>(GenericButton::D7),
|
||||
SEL = static_cast<uint16_t>(GenericButton::D8),
|
||||
ST = static_cast<uint16_t>(GenericButton::D11),
|
||||
Up = static_cast<uint16_t>(GenericButton::D12),
|
||||
Right = static_cast<uint16_t>(GenericButton::D13),
|
||||
Down = static_cast<uint16_t>(GenericButton::D14),
|
||||
Left = static_cast<uint16_t>(GenericButton::D15)
|
||||
};
|
||||
|
||||
void set_digital_rumble() {
|
||||
RawController::header.rumble0 = 0x1;
|
||||
RawController::header.rumble1 = 0x7F;
|
||||
}
|
||||
|
||||
void set_analog_rumble(uint8_t largeMotor, bool smallMotor) {
|
||||
RawController::header.rumble0 = smallMotor ? 0x1 : 0x0;
|
||||
RawController::header.rumble1 = largeMotor;
|
||||
}
|
||||
|
||||
void stopRumble() {
|
||||
RawController::header.rumble0 = 0x0;
|
||||
RawController::header.rumble1 = 0x0;
|
||||
}
|
||||
|
||||
bool is_small_rumble() const {
|
||||
return static_cast<bool>(RawController::header.rumble0);
|
||||
}
|
||||
|
||||
uint8_t get_large_rumble() const {
|
||||
return RawController::header.rumble1;
|
||||
}
|
||||
|
||||
bool is_connected() const {
|
||||
return RawController::header.state != RawController::State::Disconnected;
|
||||
}
|
||||
|
||||
bool is_useable() const {
|
||||
const auto type = RawController::get_type();
|
||||
return ((RawController::header.state == RawController::State::Stable) && (type == ControllerType::Controller || type == ControllerType::DualShock));
|
||||
}
|
||||
};
|
||||
|
||||
class AnalogeController : public GenericController {
|
||||
public:
|
||||
enum struct Button : uint16_t {
|
||||
L2 = static_cast<uint16_t>(GenericButton::D0),
|
||||
R2 = static_cast<uint16_t>(GenericButton::D1),
|
||||
L1 = static_cast<uint16_t>(GenericButton::D2),
|
||||
R1 = static_cast<uint16_t>(GenericButton::D3),
|
||||
Triangle = static_cast<uint16_t>(GenericButton::D4),
|
||||
Circle = static_cast<uint16_t>(GenericButton::D5),
|
||||
Cross = static_cast<uint16_t>(GenericButton::D6),
|
||||
Square = static_cast<uint16_t>(GenericButton::D7),
|
||||
SEL = static_cast<uint16_t>(GenericButton::D8),
|
||||
L3 = static_cast<uint16_t>(GenericButton::D9),
|
||||
R3 = static_cast<uint16_t>(GenericButton::D10),
|
||||
ST = static_cast<uint16_t>(GenericButton::D11),
|
||||
Up = static_cast<uint16_t>(GenericButton::D12),
|
||||
Right = static_cast<uint16_t>(GenericButton::D13),
|
||||
Down = static_cast<uint16_t>(GenericButton::D14),
|
||||
Left = static_cast<uint16_t>(GenericButton::D15)
|
||||
};
|
||||
|
||||
private:
|
||||
uint8_t read_special_byte(size_t idx) const {
|
||||
return reinterpret_cast<const uint8_t(&)[4]>(this->special)[idx];
|
||||
}
|
||||
|
||||
public:
|
||||
GPU::PositionI16 get_right_stick_pos() const {
|
||||
const uint8_t joy_x = AnalogeController::read_special_byte(0);
|
||||
const uint8_t joy_y = AnalogeController::read_special_byte(1);
|
||||
|
||||
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
|
||||
}
|
||||
|
||||
GPU::PositionI16 get_left_stick_pos() const {
|
||||
const uint8_t joy_x = AnalogeController::read_special_byte(2);
|
||||
const uint8_t joy_y = AnalogeController::read_special_byte(3);
|
||||
|
||||
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
|
||||
}
|
||||
};
|
||||
|
||||
using GenericButtonState = GenericController::ButtonState;
|
||||
}
|
||||
}
|
@@ -1,24 +1,24 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_config.hpp"
|
||||
#include "controller.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
static constexpr uint32_t PortCount = Configuration::Periphery::include_portB() ? 2 : 1;
|
||||
static constexpr uint32_t DeviceCount = Configuration::Periphery::use_multi_tap() ? 4 : 1;
|
||||
|
||||
extern RawController controller[PortCount][DeviceCount];
|
||||
|
||||
void query_controller();
|
||||
|
||||
template<typename T>
|
||||
inline T& get_controller_as(size_t port, size_t device) {
|
||||
return *reinterpret_cast<T*>(&controller[port][device]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T& get_primary_controller_as() {
|
||||
return get_controller_as<T>(0, 0);
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_config.hpp"
|
||||
#include "controller.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
static constexpr uint32_t PortCount = Configuration::Periphery::include_portB() ? 2 : 1;
|
||||
static constexpr uint32_t DeviceCount = Configuration::Periphery::use_multi_tap() ? 4 : 1;
|
||||
|
||||
extern RawController controller[PortCount][DeviceCount];
|
||||
|
||||
void query_controller();
|
||||
|
||||
template<typename T>
|
||||
inline T& get_controller_as(size_t port, size_t device) {
|
||||
return *reinterpret_cast<T*>(&controller[port][device]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T& get_primary_controller_as() {
|
||||
return get_controller_as<T>(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,137 +1,137 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
enum struct ControllerType : uint8_t {
|
||||
Unkown = 0x0,
|
||||
Mouse = 0x1,
|
||||
NegCon = 0x2,
|
||||
HyperBlaster = 0x3, // Konami Lightgun
|
||||
Controller = 0x4,
|
||||
ArcadeFlightStick = 0x5,
|
||||
GCon = 0x6,
|
||||
DualShock = 0x7,
|
||||
MultiTap = 0x8
|
||||
};
|
||||
|
||||
enum struct GenericButton : uint16_t {
|
||||
D8 = (1 << 0),
|
||||
D9 = (1 << 1),
|
||||
D10 = (1 << 2),
|
||||
D11 = (1 << 3),
|
||||
D12 = (1 << 4),
|
||||
D13 = (1 << 5),
|
||||
D14 = (1 << 6),
|
||||
D15 = (1 << 7),
|
||||
D0 = (1 << 8),
|
||||
D1 = (1 << 9),
|
||||
D2 = (1 << 10),
|
||||
D3 = (1 << 11),
|
||||
D4 = (1 << 12),
|
||||
D5 = (1 << 13),
|
||||
D6 = (1 << 14),
|
||||
D7 = (1 << 15)
|
||||
};
|
||||
|
||||
struct LED {
|
||||
enum struct State : uint8_t {
|
||||
Off = 0x0,
|
||||
On = 0x1
|
||||
};
|
||||
|
||||
enum struct Lock {
|
||||
Off = 0x2,
|
||||
On = 0x3
|
||||
};
|
||||
};
|
||||
|
||||
class RawController {
|
||||
public:
|
||||
enum struct State : uint8_t
|
||||
{
|
||||
Disconnected = 0,
|
||||
EnterConfigMode = (1 << 0),
|
||||
LockAnalog = (1 << 1),
|
||||
UnlockRumble = (1 << 2),
|
||||
ExitConfigMode = (1 << 3),
|
||||
Stable = (1 << 4)
|
||||
};
|
||||
|
||||
protected:
|
||||
struct Header {
|
||||
uint8_t type;
|
||||
State state;
|
||||
uint8_t rumble0;
|
||||
uint8_t rumble1;
|
||||
|
||||
void clear() {
|
||||
this->type = 0;
|
||||
this->state = State::Disconnected;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
class ButtonState {
|
||||
private:
|
||||
uint16_t oldState;
|
||||
uint16_t currentState;
|
||||
|
||||
static bool is_down(uint16_t data, uint16_t button) {
|
||||
return ((data & button) == 0);
|
||||
}
|
||||
|
||||
void exchange_state() {
|
||||
this->oldState = this->currentState;
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
bool is_down(T button) const {
|
||||
return ButtonState::is_down(this->currentState, static_cast<uint16_t>(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool was_down(T button) const {
|
||||
return ButtonState::is_down(this->oldState, static_cast<uint16_t>(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool went_down(T button) const {
|
||||
return (!ButtonState::was_down(button) && ButtonState::is_down(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool went_up(T button) const {
|
||||
return (ButtonState::was_down(button) && !ButtonState::is_down(button));
|
||||
}
|
||||
|
||||
friend class RawController;
|
||||
friend struct ControllerHelper;
|
||||
friend void query_controller();
|
||||
};
|
||||
|
||||
Header header;
|
||||
ButtonState button;
|
||||
uint32_t special;
|
||||
|
||||
public:
|
||||
ControllerType get_type() const {
|
||||
return static_cast<ControllerType>((this->header.type >> 4));
|
||||
}
|
||||
|
||||
ButtonState get_button_state() const {
|
||||
return this->button;
|
||||
}
|
||||
|
||||
//For debugging only
|
||||
uint8_t get_raw_type() const {
|
||||
return this->header.type;
|
||||
}
|
||||
|
||||
uint16_t get_raw_button_state() const {
|
||||
return this->button.currentState;
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery {
|
||||
enum struct ControllerType : uint8_t {
|
||||
Unkown = 0x0,
|
||||
Mouse = 0x1,
|
||||
NegCon = 0x2,
|
||||
HyperBlaster = 0x3, // Konami Lightgun
|
||||
Controller = 0x4,
|
||||
ArcadeFlightStick = 0x5,
|
||||
GCon = 0x6,
|
||||
DualShock = 0x7,
|
||||
MultiTap = 0x8
|
||||
};
|
||||
|
||||
enum struct GenericButton : uint16_t {
|
||||
D8 = (1 << 0),
|
||||
D9 = (1 << 1),
|
||||
D10 = (1 << 2),
|
||||
D11 = (1 << 3),
|
||||
D12 = (1 << 4),
|
||||
D13 = (1 << 5),
|
||||
D14 = (1 << 6),
|
||||
D15 = (1 << 7),
|
||||
D0 = (1 << 8),
|
||||
D1 = (1 << 9),
|
||||
D2 = (1 << 10),
|
||||
D3 = (1 << 11),
|
||||
D4 = (1 << 12),
|
||||
D5 = (1 << 13),
|
||||
D6 = (1 << 14),
|
||||
D7 = (1 << 15)
|
||||
};
|
||||
|
||||
struct LED {
|
||||
enum struct State : uint8_t {
|
||||
Off = 0x0,
|
||||
On = 0x1
|
||||
};
|
||||
|
||||
enum struct Lock {
|
||||
Off = 0x2,
|
||||
On = 0x3
|
||||
};
|
||||
};
|
||||
|
||||
class RawController {
|
||||
public:
|
||||
enum struct State : uint8_t
|
||||
{
|
||||
Disconnected = 0,
|
||||
EnterConfigMode = (1 << 0),
|
||||
LockAnalog = (1 << 1),
|
||||
UnlockRumble = (1 << 2),
|
||||
ExitConfigMode = (1 << 3),
|
||||
Stable = (1 << 4)
|
||||
};
|
||||
|
||||
protected:
|
||||
struct Header {
|
||||
uint8_t type;
|
||||
State state;
|
||||
uint8_t rumble0;
|
||||
uint8_t rumble1;
|
||||
|
||||
void clear() {
|
||||
this->type = 0;
|
||||
this->state = State::Disconnected;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
class ButtonState {
|
||||
private:
|
||||
uint16_t oldState;
|
||||
uint16_t currentState;
|
||||
|
||||
static bool is_down(uint16_t data, uint16_t button) {
|
||||
return ((data & button) == 0);
|
||||
}
|
||||
|
||||
void exchange_state() {
|
||||
this->oldState = this->currentState;
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
bool is_down(T button) const {
|
||||
return ButtonState::is_down(this->currentState, static_cast<uint16_t>(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool was_down(T button) const {
|
||||
return ButtonState::is_down(this->oldState, static_cast<uint16_t>(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool went_down(T button) const {
|
||||
return (!ButtonState::was_down(button) && ButtonState::is_down(button));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool went_up(T button) const {
|
||||
return (ButtonState::was_down(button) && !ButtonState::is_down(button));
|
||||
}
|
||||
|
||||
friend class RawController;
|
||||
friend struct ControllerHelper;
|
||||
friend void query_controller();
|
||||
};
|
||||
|
||||
Header header;
|
||||
ButtonState button;
|
||||
uint32_t special;
|
||||
|
||||
public:
|
||||
ControllerType get_type() const {
|
||||
return static_cast<ControllerType>((this->header.type >> 4));
|
||||
}
|
||||
|
||||
ButtonState get_button_state() const {
|
||||
return this->button;
|
||||
}
|
||||
|
||||
//For debugging only
|
||||
uint8_t get_raw_type() const {
|
||||
return this->header.type;
|
||||
}
|
||||
|
||||
uint16_t get_raw_button_state() const {
|
||||
return this->button.currentState;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,51 +1,51 @@
|
||||
#pragma once
|
||||
#include "../System/IOPorts/spu_io.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace SPU {
|
||||
using SPU_IO_Values::operator""_vol;
|
||||
|
||||
using SRAMAdr = SPU_IO_Values::SRAMAdr;
|
||||
using SimpleVolume = SPU_IO_Values::SimpleVolume;
|
||||
using SweepVolume = SPU_IO_Values::SweepVolume;
|
||||
|
||||
struct Voice {
|
||||
size_t get_id() const {
|
||||
return reinterpret_cast<size_t>(this);
|
||||
}
|
||||
|
||||
SRAMAdr allocate(size_t size);
|
||||
SRAMAdr allocate(SPU_IO_Values::SampleRate frequency, size_t size);
|
||||
void deallocate();
|
||||
|
||||
void set_sample_rate(SPU_IO_Values::SampleRate frequency) {
|
||||
SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency);
|
||||
}
|
||||
|
||||
void set_volume(SimpleVolume left, SimpleVolume right) {
|
||||
SPU_IO::Voice[Voice::get_id()].volumeLeft.write(SweepVolume::create(left));
|
||||
SPU_IO::Voice[Voice::get_id()].volumeRight.write(SweepVolume::create(right));
|
||||
}
|
||||
|
||||
void play() {
|
||||
SPU_IO::Key::On.write(SPU_IO_Values::KeyOn::for_specific(Voice::get_id()));
|
||||
}
|
||||
|
||||
void play_if_end() {
|
||||
if(Voice::is_end()) {
|
||||
Voice::play();
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
SPU_IO::Key::Off.write(SPU_IO_Values::KeyOff::for_specific(Voice::get_id()));
|
||||
}
|
||||
|
||||
bool is_end() const {
|
||||
return SPU_IO::Voice[Voice::get_id()].adsr_volume.read() == SimpleVolume::mute();
|
||||
}
|
||||
};
|
||||
|
||||
static auto& voice = __declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0);
|
||||
}
|
||||
#pragma once
|
||||
#include "../System/IOPorts/spu_io.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace SPU {
|
||||
using SPU_IO_Values::operator""_vol;
|
||||
|
||||
using SRAMAdr = SPU_IO_Values::SRAMAdr;
|
||||
using SimpleVolume = SPU_IO_Values::SimpleVolume;
|
||||
using SweepVolume = SPU_IO_Values::SweepVolume;
|
||||
|
||||
struct Voice {
|
||||
size_t get_id() const {
|
||||
return reinterpret_cast<size_t>(this);
|
||||
}
|
||||
|
||||
SRAMAdr allocate(size_t size);
|
||||
SRAMAdr allocate(SPU_IO_Values::SampleRate frequency, size_t size);
|
||||
void deallocate();
|
||||
|
||||
void set_sample_rate(SPU_IO_Values::SampleRate frequency) {
|
||||
SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency);
|
||||
}
|
||||
|
||||
void set_volume(SimpleVolume left, SimpleVolume right) {
|
||||
SPU_IO::Voice[Voice::get_id()].volumeLeft.write(SweepVolume::create(left));
|
||||
SPU_IO::Voice[Voice::get_id()].volumeRight.write(SweepVolume::create(right));
|
||||
}
|
||||
|
||||
void play() {
|
||||
SPU_IO::Key::On.write(SPU_IO_Values::KeyOn::for_specific(Voice::get_id()));
|
||||
}
|
||||
|
||||
void play_if_end() {
|
||||
if(Voice::is_end()) {
|
||||
Voice::play();
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
SPU_IO::Key::Off.write(SPU_IO_Values::KeyOff::for_specific(Voice::get_id()));
|
||||
}
|
||||
|
||||
bool is_end() const {
|
||||
return SPU_IO::Voice[Voice::get_id()].adsr_volume.read() == SimpleVolume::mute();
|
||||
}
|
||||
};
|
||||
|
||||
static auto& voice = __declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0);
|
||||
}
|
||||
}
|
@@ -1,106 +1,106 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CD_IO_Values {
|
||||
__declare_io_struct(AudioVolumeApply, uint8_t) {
|
||||
static constexpr auto Mute = Bit(0);
|
||||
static constexpr auto ApplyChanges = Bit(5);
|
||||
};
|
||||
|
||||
struct CDDAVolume {
|
||||
using Type = uint8_t;
|
||||
|
||||
static constexpr uint8_t Off = 0x0;
|
||||
static constexpr uint8_t Default = 0x80;
|
||||
static constexpr uint8_t Max = 0xFF;
|
||||
};
|
||||
|
||||
__declare_io_struct(CommandFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(DataFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(DataFifo16, uint16_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(InterruptEnable, uint8_t) {
|
||||
static constexpr auto InterruptTypValue = BitRange::from_to(0, 2);
|
||||
static constexpr auto InterruptExtended = BitRange::from_to(0, 4);
|
||||
static constexpr auto UnknownIRQ = Bit(3);
|
||||
static constexpr auto CommandStartIRQ = Bit(4);
|
||||
};
|
||||
using InterruptFlag = InterruptEnable;
|
||||
|
||||
__declare_io_struct(IndexStatus, uint8_t) {
|
||||
static constexpr auto PortIndex = BitRange::from_to(0, 1);
|
||||
static constexpr auto HasXAFifoData = Bit(2);
|
||||
static constexpr auto IsParameterFifoEmpty = Bit(3);
|
||||
static constexpr auto HasParameterFifoSpace = Bit(4);
|
||||
static constexpr auto HasResponseFifoData = Bit(5);
|
||||
static constexpr auto HasDataFifoData = Bit(6);
|
||||
static constexpr auto IsTransmissionBusy = Bit(7);
|
||||
};
|
||||
|
||||
__declare_io_struct(LeftCD2LeftSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(LeftCD2RightSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Mode, uint8_t) {
|
||||
static constexpr auto DoubleSpeed = Bit(7);
|
||||
static constexpr auto SingleSpeed = !DoubleSpeed;
|
||||
static constexpr auto XADPCM = Bit(6);
|
||||
static constexpr auto WholeSector = Bit(5);
|
||||
static constexpr auto DataSector = !WholeSector;
|
||||
static constexpr auto UseXAFilter = Bit(3);
|
||||
static constexpr auto AudioPlayIRQ = Bit(2);
|
||||
static constexpr auto AutoPauseTrack = Bit(1);
|
||||
static constexpr auto CDDA = Bit(0);
|
||||
|
||||
operator uint8_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ParameterFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Request, uint8_t) {
|
||||
static constexpr auto WantCommandStartIRQ = Bit(5);
|
||||
static constexpr auto WantData = Bit(7);
|
||||
|
||||
static Request want_data() {
|
||||
return Request{static_cast<uint8_t>(Request::WantData)};
|
||||
}
|
||||
|
||||
static Request reset() {
|
||||
return Request{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ResponseFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(RightCD2LeftSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(RightCD2RightSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(SoundMapCoding, uint8_t) {
|
||||
static constexpr auto Stereo = Bit(0);
|
||||
static constexpr auto Mono = !Stereo;
|
||||
static constexpr auto SampleRate_18900hz = Bit(2);
|
||||
static constexpr auto SampleRate_37800hz = !SampleRate_18900hz;
|
||||
static constexpr auto BitsPerSample8 = Bit(4);
|
||||
static constexpr auto BitsPerSample4 = !BitsPerSample8;
|
||||
static constexpr auto Emphasis = Bit(6);
|
||||
};
|
||||
|
||||
__declare_io_struct(SoundMapDataOut, uint8_t) {
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace CD_IO_Values {
|
||||
__declare_io_struct(AudioVolumeApply, uint8_t) {
|
||||
static constexpr auto Mute = Bit(0);
|
||||
static constexpr auto ApplyChanges = Bit(5);
|
||||
};
|
||||
|
||||
struct CDDAVolume {
|
||||
using Type = uint8_t;
|
||||
|
||||
static constexpr uint8_t Off = 0x0;
|
||||
static constexpr uint8_t Default = 0x80;
|
||||
static constexpr uint8_t Max = 0xFF;
|
||||
};
|
||||
|
||||
__declare_io_struct(CommandFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(DataFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(DataFifo16, uint16_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(InterruptEnable, uint8_t) {
|
||||
static constexpr auto InterruptTypValue = BitRange::from_to(0, 2);
|
||||
static constexpr auto InterruptExtended = BitRange::from_to(0, 4);
|
||||
static constexpr auto UnknownIRQ = Bit(3);
|
||||
static constexpr auto CommandStartIRQ = Bit(4);
|
||||
};
|
||||
using InterruptFlag = InterruptEnable;
|
||||
|
||||
__declare_io_struct(IndexStatus, uint8_t) {
|
||||
static constexpr auto PortIndex = BitRange::from_to(0, 1);
|
||||
static constexpr auto HasXAFifoData = Bit(2);
|
||||
static constexpr auto IsParameterFifoEmpty = Bit(3);
|
||||
static constexpr auto HasParameterFifoSpace = Bit(4);
|
||||
static constexpr auto HasResponseFifoData = Bit(5);
|
||||
static constexpr auto HasDataFifoData = Bit(6);
|
||||
static constexpr auto IsTransmissionBusy = Bit(7);
|
||||
};
|
||||
|
||||
__declare_io_struct(LeftCD2LeftSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(LeftCD2RightSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Mode, uint8_t) {
|
||||
static constexpr auto DoubleSpeed = Bit(7);
|
||||
static constexpr auto SingleSpeed = !DoubleSpeed;
|
||||
static constexpr auto XADPCM = Bit(6);
|
||||
static constexpr auto WholeSector = Bit(5);
|
||||
static constexpr auto DataSector = !WholeSector;
|
||||
static constexpr auto UseXAFilter = Bit(3);
|
||||
static constexpr auto AudioPlayIRQ = Bit(2);
|
||||
static constexpr auto AutoPauseTrack = Bit(1);
|
||||
static constexpr auto CDDA = Bit(0);
|
||||
|
||||
operator uint8_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ParameterFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Request, uint8_t) {
|
||||
static constexpr auto WantCommandStartIRQ = Bit(5);
|
||||
static constexpr auto WantData = Bit(7);
|
||||
|
||||
static Request want_data() {
|
||||
return Request{static_cast<uint8_t>(Request::WantData)};
|
||||
}
|
||||
|
||||
static Request reset() {
|
||||
return Request{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ResponseFifo, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(RightCD2LeftSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(RightCD2RightSPU, CDDAVolume::Type) {
|
||||
};
|
||||
|
||||
__declare_io_struct(SoundMapCoding, uint8_t) {
|
||||
static constexpr auto Stereo = Bit(0);
|
||||
static constexpr auto Mono = !Stereo;
|
||||
static constexpr auto SampleRate_18900hz = Bit(2);
|
||||
static constexpr auto SampleRate_37800hz = !SampleRate_18900hz;
|
||||
static constexpr auto BitsPerSample8 = Bit(4);
|
||||
static constexpr auto BitsPerSample4 = !BitsPerSample8;
|
||||
static constexpr auto Emphasis = Bit(6);
|
||||
};
|
||||
|
||||
__declare_io_struct(SoundMapDataOut, uint8_t) {
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,152 +1,152 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace DMA_IO_Values {
|
||||
using Priority = uint32_t;
|
||||
static constexpr Priority HighestPriority = 0;
|
||||
static constexpr Priority LowestPriority = 7;
|
||||
|
||||
__declare_io_struct(BCR, uint32_t) {
|
||||
struct SyncMode0 {
|
||||
static constexpr auto NumberOfWords = BitRange::from_to(0, 15);
|
||||
static constexpr auto CD_OneBlock = Bit(16);
|
||||
|
||||
static constexpr BCR for_cd(size_t words) {
|
||||
return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words));
|
||||
}
|
||||
};
|
||||
|
||||
struct SyncMode1 {
|
||||
static constexpr auto BlockSize = BitRange::from_to(0, 15);
|
||||
static constexpr auto BlockAmount = BitRange::from_to(16, 31);
|
||||
};
|
||||
|
||||
struct SyncMode2 {
|
||||
static constexpr BCR for_gpu_cmd() {
|
||||
return {0};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
__declare_io_struct(CHCHR, uint32_t) {
|
||||
enum SyncMode_t {
|
||||
Sync0 = 0, //Start immediately,
|
||||
Sync1 = 1, //Sync blocks to DMA requests
|
||||
Sync2 = 2, //Linked List
|
||||
};
|
||||
|
||||
static constexpr auto ManualStart = Bit(28);
|
||||
|
||||
static constexpr auto Start = Bit(24);
|
||||
static constexpr auto Busy = Start;
|
||||
|
||||
static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22);
|
||||
static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18);
|
||||
|
||||
static constexpr auto SyncMode = BitRange::from_to(9, 10);
|
||||
static constexpr auto UseSyncMode0 = SyncMode.with(Sync0);
|
||||
static constexpr auto UseSyncMode1 = SyncMode.with(Sync1);
|
||||
static constexpr auto UseSyncMode2 = SyncMode.with(Sync2);
|
||||
|
||||
static constexpr auto UseChopping = Bit(8);
|
||||
|
||||
static constexpr auto MemoryAdrDecreaseBy4 = Bit(1);
|
||||
static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4;
|
||||
|
||||
static constexpr auto FromMainRAM = Bit(0);
|
||||
static constexpr auto ToMainRAM = !FromMainRAM;
|
||||
|
||||
static constexpr CHCHR StartMDECin() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartMDECout() {
|
||||
return CHCHR{0x01000200};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartGPUReceive() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartGPULinked() {
|
||||
return CHCHR{0x01000401};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartCDROM() {
|
||||
return CHCHR{0x11000000};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartSPUReceive() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartOTC() {
|
||||
return CHCHR{0x11000002};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(DICR, uint32_t) {
|
||||
static constexpr auto MasterEnable = Bit(31);
|
||||
static constexpr auto Flags = BitRange::from_to(24, 30);
|
||||
static constexpr auto MasterEnableDPCR = Bit(23);
|
||||
static constexpr auto EnableDPCR = BitRange::from_to(16, 22);
|
||||
static constexpr auto ForceIRQ = Bit(15);
|
||||
|
||||
static constexpr DICR empty() {
|
||||
return DICR{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(DPCR, uint32_t) {
|
||||
struct DMASetting {
|
||||
uint16_t master_bit;
|
||||
|
||||
static constexpr DMASetting create(uint16_t master_bit) {
|
||||
return DMASetting{master_bit};
|
||||
}
|
||||
|
||||
constexpr BitRange::RangeValuePair<uint32_t> turn_on(uint8_t priority) const {
|
||||
return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast<uint32_t>(0b1000 + (priority & 0b111)));
|
||||
}
|
||||
|
||||
constexpr ClearBit turn_off() const {
|
||||
return ClearBit(this->master_bit);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr const auto OTC = DMASetting(27);
|
||||
static constexpr const auto PIO = DMASetting(23);
|
||||
static constexpr const auto SPU = DMASetting(19);
|
||||
static constexpr const auto CDROM = DMASetting(15);
|
||||
static constexpr const auto GPU = DMASetting(11);
|
||||
static constexpr const auto MDEC_Out = DMASetting(7);
|
||||
static constexpr const auto MDEC_In = DMASetting(3);
|
||||
|
||||
static constexpr auto OTCEnabled = Bit(27);
|
||||
static constexpr auto OTCPriority = BitRange::from_to(24, 26);
|
||||
|
||||
static constexpr auto PIOEnabled = Bit(23);
|
||||
static constexpr auto PIOPriority = BitRange::from_to(20, 22);
|
||||
|
||||
static constexpr auto SPUEnabled = Bit(19);
|
||||
static constexpr auto SPUPriority = BitRange::from_to(16, 18);
|
||||
|
||||
static constexpr auto CDROMEnabled = Bit(15);
|
||||
static constexpr auto CDROMPriority = BitRange::from_to(12, 14);
|
||||
|
||||
static constexpr auto GPUEnabled = Bit(11);
|
||||
static constexpr auto GPUPriority = BitRange::from_to(8, 10);
|
||||
|
||||
static constexpr auto MDECoutEnabled = Bit(7);
|
||||
static constexpr auto MDECoutPriority = BitRange::from_to(4, 6);
|
||||
|
||||
static constexpr auto MDECinEnabled = Bit(3);
|
||||
static constexpr auto MDECinPriority = BitRange::from_to(0, 2);
|
||||
};
|
||||
|
||||
__declare_io_struct(MADR, uint32_t) {
|
||||
static constexpr auto MemoryAdr = BitRange::from_to(0, 23);
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace DMA_IO_Values {
|
||||
using Priority = uint32_t;
|
||||
static constexpr Priority HighestPriority = 0;
|
||||
static constexpr Priority LowestPriority = 7;
|
||||
|
||||
__declare_io_struct(BCR, uint32_t) {
|
||||
struct SyncMode0 {
|
||||
static constexpr auto NumberOfWords = BitRange::from_to(0, 15);
|
||||
static constexpr auto CD_OneBlock = Bit(16);
|
||||
|
||||
static constexpr BCR for_cd(size_t words) {
|
||||
return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words));
|
||||
}
|
||||
};
|
||||
|
||||
struct SyncMode1 {
|
||||
static constexpr auto BlockSize = BitRange::from_to(0, 15);
|
||||
static constexpr auto BlockAmount = BitRange::from_to(16, 31);
|
||||
};
|
||||
|
||||
struct SyncMode2 {
|
||||
static constexpr BCR for_gpu_cmd() {
|
||||
return {0};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
__declare_io_struct(CHCHR, uint32_t) {
|
||||
enum SyncMode_t {
|
||||
Sync0 = 0, //Start immediately,
|
||||
Sync1 = 1, //Sync blocks to DMA requests
|
||||
Sync2 = 2, //Linked List
|
||||
};
|
||||
|
||||
static constexpr auto ManualStart = Bit(28);
|
||||
|
||||
static constexpr auto Start = Bit(24);
|
||||
static constexpr auto Busy = Start;
|
||||
|
||||
static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22);
|
||||
static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18);
|
||||
|
||||
static constexpr auto SyncMode = BitRange::from_to(9, 10);
|
||||
static constexpr auto UseSyncMode0 = SyncMode.with(Sync0);
|
||||
static constexpr auto UseSyncMode1 = SyncMode.with(Sync1);
|
||||
static constexpr auto UseSyncMode2 = SyncMode.with(Sync2);
|
||||
|
||||
static constexpr auto UseChopping = Bit(8);
|
||||
|
||||
static constexpr auto MemoryAdrDecreaseBy4 = Bit(1);
|
||||
static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4;
|
||||
|
||||
static constexpr auto FromMainRAM = Bit(0);
|
||||
static constexpr auto ToMainRAM = !FromMainRAM;
|
||||
|
||||
static constexpr CHCHR StartMDECin() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartMDECout() {
|
||||
return CHCHR{0x01000200};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartGPUReceive() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartGPULinked() {
|
||||
return CHCHR{0x01000401};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartCDROM() {
|
||||
return CHCHR{0x11000000};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartSPUReceive() {
|
||||
return CHCHR{0x01000201};
|
||||
}
|
||||
|
||||
static constexpr CHCHR StartOTC() {
|
||||
return CHCHR{0x11000002};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(DICR, uint32_t) {
|
||||
static constexpr auto MasterEnable = Bit(31);
|
||||
static constexpr auto Flags = BitRange::from_to(24, 30);
|
||||
static constexpr auto MasterEnableDPCR = Bit(23);
|
||||
static constexpr auto EnableDPCR = BitRange::from_to(16, 22);
|
||||
static constexpr auto ForceIRQ = Bit(15);
|
||||
|
||||
static constexpr DICR empty() {
|
||||
return DICR{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(DPCR, uint32_t) {
|
||||
struct DMASetting {
|
||||
uint16_t master_bit;
|
||||
|
||||
static constexpr DMASetting create(uint16_t master_bit) {
|
||||
return DMASetting{master_bit};
|
||||
}
|
||||
|
||||
constexpr BitRange::RangeValuePair<uint32_t> turn_on(uint8_t priority) const {
|
||||
return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast<uint32_t>(0b1000 + (priority & 0b111)));
|
||||
}
|
||||
|
||||
constexpr ClearBit turn_off() const {
|
||||
return ClearBit(this->master_bit);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr const auto OTC = DMASetting(27);
|
||||
static constexpr const auto PIO = DMASetting(23);
|
||||
static constexpr const auto SPU = DMASetting(19);
|
||||
static constexpr const auto CDROM = DMASetting(15);
|
||||
static constexpr const auto GPU = DMASetting(11);
|
||||
static constexpr const auto MDEC_Out = DMASetting(7);
|
||||
static constexpr const auto MDEC_In = DMASetting(3);
|
||||
|
||||
static constexpr auto OTCEnabled = Bit(27);
|
||||
static constexpr auto OTCPriority = BitRange::from_to(24, 26);
|
||||
|
||||
static constexpr auto PIOEnabled = Bit(23);
|
||||
static constexpr auto PIOPriority = BitRange::from_to(20, 22);
|
||||
|
||||
static constexpr auto SPUEnabled = Bit(19);
|
||||
static constexpr auto SPUPriority = BitRange::from_to(16, 18);
|
||||
|
||||
static constexpr auto CDROMEnabled = Bit(15);
|
||||
static constexpr auto CDROMPriority = BitRange::from_to(12, 14);
|
||||
|
||||
static constexpr auto GPUEnabled = Bit(11);
|
||||
static constexpr auto GPUPriority = BitRange::from_to(8, 10);
|
||||
|
||||
static constexpr auto MDECoutEnabled = Bit(7);
|
||||
static constexpr auto MDECoutPriority = BitRange::from_to(4, 6);
|
||||
|
||||
static constexpr auto MDECinEnabled = Bit(3);
|
||||
static constexpr auto MDECinPriority = BitRange::from_to(0, 2);
|
||||
};
|
||||
|
||||
__declare_io_struct(MADR, uint32_t) {
|
||||
static constexpr auto MemoryAdr = BitRange::from_to(0, 23);
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,220 +1,220 @@
|
||||
#pragma once
|
||||
#include "../../../GPU/gpu_types.hpp"
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU_IO_Values {
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
static constexpr T construct_cmd(uint32_t cmd, uint32_t value) {
|
||||
return T::from(T::ID.with(cmd), T::Value.with(value));
|
||||
}
|
||||
}
|
||||
|
||||
__declare_io_struct(DisplayMode, uint32_t) {
|
||||
enum AreaColorDepth {
|
||||
$15bit = 0,
|
||||
$24bit = 1,
|
||||
};
|
||||
|
||||
enum State {
|
||||
On = 0,
|
||||
Off = 1
|
||||
};
|
||||
|
||||
enum HorizontalResolution {
|
||||
$256 = 0,
|
||||
$320 = 1,
|
||||
$512 = 2,
|
||||
$640 = 3,
|
||||
};
|
||||
|
||||
enum struct TVEncoding {
|
||||
NTSC = 0,
|
||||
PAL = 1,
|
||||
};
|
||||
|
||||
enum VerticalResolution {
|
||||
$240 = 0,
|
||||
$480 = 1
|
||||
};
|
||||
|
||||
static constexpr auto HorizontalResolution368 = Bit(6);
|
||||
static constexpr auto VerticalInterlace = Bit(5);
|
||||
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4);
|
||||
static constexpr auto VideoMode = BitRange::from_to(3, 3);
|
||||
static constexpr auto VerticalResolution = BitRange::from_to(2, 2);
|
||||
static constexpr auto HorizontalResolution = BitRange::from_to(0, 1);
|
||||
|
||||
static constexpr DisplayMode PAL() {
|
||||
return DisplayMode::from(
|
||||
HorizontalResolution.with(HorizontalResolution::$320),
|
||||
VerticalResolution.with(VerticalResolution::$240),
|
||||
VideoMode.with(TVEncoding::PAL),
|
||||
DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr DisplayMode NTSC() {
|
||||
return DisplayMode::from(
|
||||
HorizontalResolution.with(HorizontalResolution::$320),
|
||||
VerticalResolution.with(VerticalResolution::$240),
|
||||
VideoMode.with(TVEncoding::NTSC),
|
||||
DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(GPUREAD, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(GPUSTAT, uint32_t) {
|
||||
enum DMADirection {
|
||||
Off = 0,
|
||||
Fifo = 1,
|
||||
CPU2GPU = 2,
|
||||
GPU2CPU = 3,
|
||||
};
|
||||
|
||||
static constexpr auto DrawingOddLinesInterlaced = Bit(31);
|
||||
static constexpr auto DMADirectionValue = BitRange::from_to(29, 30);
|
||||
static constexpr auto DMAReady = Bit(28);
|
||||
static constexpr auto VRAMtoCPUtransferReay = Bit(27);
|
||||
static constexpr auto GP0ReadyForCMD = Bit(26);
|
||||
static constexpr auto FifoNotFull = Bit(25); // Only for Fifo
|
||||
static constexpr auto InterruptRequest = Bit(24);
|
||||
static constexpr auto DisplayDisabled = Bit(23);
|
||||
static constexpr auto VerticalInterlaceOn = Bit(22);
|
||||
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21);
|
||||
static constexpr auto VideoModePal = Bit(20);
|
||||
static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19);
|
||||
static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18);
|
||||
static constexpr auto HorizontalResolution368 = Bit(16);
|
||||
static constexpr auto TexturesDisabled = Bit(15);
|
||||
static constexpr auto NotDrawingMaskedPixels = Bit(12);
|
||||
static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11);
|
||||
static constexpr auto DrawingToDisplayAreadAllowed = Bit(10);
|
||||
static constexpr auto DitherEnabled = Bit(9);
|
||||
static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8);
|
||||
static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6);
|
||||
static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256
|
||||
static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64
|
||||
|
||||
static constexpr auto VerticalResolution480 = Bit(19);
|
||||
static constexpr auto TexturePageY256 = Bit(4);
|
||||
};
|
||||
|
||||
__declare_io_struct(GP0, uint32_t) {
|
||||
static constexpr auto ID = BitRange::from_to(24, 31);
|
||||
static constexpr auto Value = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
|
||||
constexpr auto Command = BitRange::from_to(24, 31);
|
||||
constexpr auto Y = BitRange::from_to(10, 18);
|
||||
constexpr auto X = BitRange::from_to(0, 9);
|
||||
|
||||
return internal::construct_cmd<GP0>(code, Y.as_value(static_cast<uint32_t>(y)) | X.as_value(static_cast<uint32_t>(x)));
|
||||
}
|
||||
|
||||
static constexpr GP0 ClearCache() {
|
||||
return internal::construct_cmd<GP0>(0x01, 0x0);
|
||||
}
|
||||
|
||||
static constexpr GP0 QuickFill(GPU::Color24 color) {
|
||||
return internal::construct_cmd<GP0>(0x02, color.raw());
|
||||
}
|
||||
|
||||
static constexpr GP0 VRAM2VRAMBlitting() {
|
||||
return internal::construct_cmd<GP0>(0x80, 0);
|
||||
}
|
||||
|
||||
static constexpr GP0 CPU2VRAMBlitting() {
|
||||
return internal::construct_cmd<GP0>(0xA0, 0);
|
||||
}
|
||||
|
||||
static constexpr GP0 TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) {
|
||||
constexpr auto TexXRange = BitRange::from_to(0, 3);
|
||||
constexpr auto TexYRange = BitRange::from_to(4, 4);
|
||||
constexpr auto TransparencyRange = BitRange::from_to(5, 6);
|
||||
constexpr auto TextureColorRange = BitRange::from_to(7, 8);
|
||||
constexpr auto DitherBit = BitRange::from_to(9, 9);
|
||||
constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10);
|
||||
|
||||
return internal::construct_cmd<GP0>(0xE1,
|
||||
TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) |
|
||||
TransparencyRange.as_value(static_cast<uint32_t>(transparency)) | TextureColorRange.as_value(static_cast<uint32_t>(tex_color)) |
|
||||
DitherBit.as_value(static_cast<uint32_t>(dither)) | DrawOnDisplayAreaBit.as_value(static_cast<uint32_t>(draw_on_display_area))
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawAreaTopLeft(const GPU::PositionU16& position) {
|
||||
return GP0::DrawAreaTemplate(0xE3, position.x, position.y);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawAreaBottomRight(const GPU::PositionU16& position) {
|
||||
return GP0::DrawAreaTemplate(0xE4, position.x, position.y);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawOffset(const GPU::PositionI16& offset) {
|
||||
constexpr auto X = BitRange::from_to(0, 10);
|
||||
constexpr auto Y = BitRange::from_to(11, 21);
|
||||
|
||||
return internal::construct_cmd<GPU_IO_Values::GP0>(0xE5, X.as_value(static_cast<int32_t>(offset.x)) | Y.as_value(static_cast<int32_t>(offset.y)));
|
||||
}
|
||||
|
||||
static constexpr GP0 PostionTopLeft(const GPU::PositionU16& position) {
|
||||
return GP0{(static_cast<uint32_t>(position.y) << 16u) | position.x};
|
||||
}
|
||||
|
||||
static constexpr GP0 WidthHeight(const GPU::SizeU16& size) {
|
||||
return GP0{(static_cast<uint32_t>(size.height) << 16u) | size.width};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(GP1, uint32_t) {
|
||||
static constexpr auto ID = BitRange::from_to(24, 31);
|
||||
static constexpr auto Value = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr GP1 Reset() {
|
||||
return GP1{0};
|
||||
}
|
||||
|
||||
static constexpr GP1 ResetCMDBuffer() {
|
||||
return internal::construct_cmd<GP1>(0x01, 0);
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayState(DisplayMode::State state) {
|
||||
return internal::construct_cmd<GP1>(0x03, static_cast<uint32_t>(state));
|
||||
}
|
||||
|
||||
static constexpr GP1 DMADirection(GPUSTAT::DMADirection dir) {
|
||||
return internal::construct_cmd<GP1>(0x04, dir);
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayArea(const GPU::PositionU16& position) {
|
||||
constexpr auto X = BitRange::from_to(0, 9);
|
||||
constexpr auto Y = BitRange::from_to(10, 18);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x05, X.as_value(static_cast<uint32_t>(position.x)) | Y.as_value(static_cast<uint32_t>(position.y)));
|
||||
}
|
||||
|
||||
static constexpr GP1 HorizontalDisplayRange(uint16_t x1, uint16_t x2) {
|
||||
constexpr auto X1 = BitRange::from_to(0, 11);
|
||||
constexpr auto X2 = BitRange::from_to(12, 23);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x06, X1.as_value(static_cast<uint32_t>(x1)) | X2.as_value(static_cast<uint32_t>(x2)));
|
||||
}
|
||||
|
||||
static constexpr GP1 VerticalDisplayRange(uint16_t y1, uint16_t y2) {
|
||||
constexpr auto Y1 = BitRange::from_to(0, 9);
|
||||
constexpr auto Y2 = BitRange::from_to(10, 19);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x07, Y1.as_value(static_cast<uint32_t>(y1)) | Y2.as_value(static_cast<uint32_t>(y2)));
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayMode(GPU_IO_Values::DisplayMode mode) {
|
||||
return internal::construct_cmd<GP1>(0x08, mode.raw);
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "../../../GPU/gpu_types.hpp"
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace GPU_IO_Values {
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
static constexpr T construct_cmd(uint32_t cmd, uint32_t value) {
|
||||
return T::from(T::ID.with(cmd), T::Value.with(value));
|
||||
}
|
||||
}
|
||||
|
||||
__declare_io_struct(DisplayMode, uint32_t) {
|
||||
enum AreaColorDepth {
|
||||
$15bit = 0,
|
||||
$24bit = 1,
|
||||
};
|
||||
|
||||
enum State {
|
||||
On = 0,
|
||||
Off = 1
|
||||
};
|
||||
|
||||
enum HorizontalResolution {
|
||||
$256 = 0,
|
||||
$320 = 1,
|
||||
$512 = 2,
|
||||
$640 = 3,
|
||||
};
|
||||
|
||||
enum struct TVEncoding {
|
||||
NTSC = 0,
|
||||
PAL = 1,
|
||||
};
|
||||
|
||||
enum VerticalResolution {
|
||||
$240 = 0,
|
||||
$480 = 1
|
||||
};
|
||||
|
||||
static constexpr auto HorizontalResolution368 = Bit(6);
|
||||
static constexpr auto VerticalInterlace = Bit(5);
|
||||
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4);
|
||||
static constexpr auto VideoMode = BitRange::from_to(3, 3);
|
||||
static constexpr auto VerticalResolution = BitRange::from_to(2, 2);
|
||||
static constexpr auto HorizontalResolution = BitRange::from_to(0, 1);
|
||||
|
||||
static constexpr DisplayMode PAL() {
|
||||
return DisplayMode::from(
|
||||
HorizontalResolution.with(HorizontalResolution::$320),
|
||||
VerticalResolution.with(VerticalResolution::$240),
|
||||
VideoMode.with(TVEncoding::PAL),
|
||||
DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr DisplayMode NTSC() {
|
||||
return DisplayMode::from(
|
||||
HorizontalResolution.with(HorizontalResolution::$320),
|
||||
VerticalResolution.with(VerticalResolution::$240),
|
||||
VideoMode.with(TVEncoding::NTSC),
|
||||
DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(GPUREAD, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(GPUSTAT, uint32_t) {
|
||||
enum DMADirection {
|
||||
Off = 0,
|
||||
Fifo = 1,
|
||||
CPU2GPU = 2,
|
||||
GPU2CPU = 3,
|
||||
};
|
||||
|
||||
static constexpr auto DrawingOddLinesInterlaced = Bit(31);
|
||||
static constexpr auto DMADirectionValue = BitRange::from_to(29, 30);
|
||||
static constexpr auto DMAReady = Bit(28);
|
||||
static constexpr auto VRAMtoCPUtransferReay = Bit(27);
|
||||
static constexpr auto GP0ReadyForCMD = Bit(26);
|
||||
static constexpr auto FifoNotFull = Bit(25); // Only for Fifo
|
||||
static constexpr auto InterruptRequest = Bit(24);
|
||||
static constexpr auto DisplayDisabled = Bit(23);
|
||||
static constexpr auto VerticalInterlaceOn = Bit(22);
|
||||
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21);
|
||||
static constexpr auto VideoModePal = Bit(20);
|
||||
static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19);
|
||||
static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18);
|
||||
static constexpr auto HorizontalResolution368 = Bit(16);
|
||||
static constexpr auto TexturesDisabled = Bit(15);
|
||||
static constexpr auto NotDrawingMaskedPixels = Bit(12);
|
||||
static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11);
|
||||
static constexpr auto DrawingToDisplayAreadAllowed = Bit(10);
|
||||
static constexpr auto DitherEnabled = Bit(9);
|
||||
static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8);
|
||||
static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6);
|
||||
static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256
|
||||
static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64
|
||||
|
||||
static constexpr auto VerticalResolution480 = Bit(19);
|
||||
static constexpr auto TexturePageY256 = Bit(4);
|
||||
};
|
||||
|
||||
__declare_io_struct(GP0, uint32_t) {
|
||||
static constexpr auto ID = BitRange::from_to(24, 31);
|
||||
static constexpr auto Value = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
|
||||
constexpr auto Command = BitRange::from_to(24, 31);
|
||||
constexpr auto Y = BitRange::from_to(10, 18);
|
||||
constexpr auto X = BitRange::from_to(0, 9);
|
||||
|
||||
return internal::construct_cmd<GP0>(code, Y.as_value(static_cast<uint32_t>(y)) | X.as_value(static_cast<uint32_t>(x)));
|
||||
}
|
||||
|
||||
static constexpr GP0 ClearCache() {
|
||||
return internal::construct_cmd<GP0>(0x01, 0x0);
|
||||
}
|
||||
|
||||
static constexpr GP0 QuickFill(GPU::Color24 color) {
|
||||
return internal::construct_cmd<GP0>(0x02, color.raw());
|
||||
}
|
||||
|
||||
static constexpr GP0 VRAM2VRAMBlitting() {
|
||||
return internal::construct_cmd<GP0>(0x80, 0);
|
||||
}
|
||||
|
||||
static constexpr GP0 CPU2VRAMBlitting() {
|
||||
return internal::construct_cmd<GP0>(0xA0, 0);
|
||||
}
|
||||
|
||||
static constexpr GP0 TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) {
|
||||
constexpr auto TexXRange = BitRange::from_to(0, 3);
|
||||
constexpr auto TexYRange = BitRange::from_to(4, 4);
|
||||
constexpr auto TransparencyRange = BitRange::from_to(5, 6);
|
||||
constexpr auto TextureColorRange = BitRange::from_to(7, 8);
|
||||
constexpr auto DitherBit = BitRange::from_to(9, 9);
|
||||
constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10);
|
||||
|
||||
return internal::construct_cmd<GP0>(0xE1,
|
||||
TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) |
|
||||
TransparencyRange.as_value(static_cast<uint32_t>(transparency)) | TextureColorRange.as_value(static_cast<uint32_t>(tex_color)) |
|
||||
DitherBit.as_value(static_cast<uint32_t>(dither)) | DrawOnDisplayAreaBit.as_value(static_cast<uint32_t>(draw_on_display_area))
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawAreaTopLeft(const GPU::PositionU16& position) {
|
||||
return GP0::DrawAreaTemplate(0xE3, position.x, position.y);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawAreaBottomRight(const GPU::PositionU16& position) {
|
||||
return GP0::DrawAreaTemplate(0xE4, position.x, position.y);
|
||||
}
|
||||
|
||||
static constexpr GP0 DrawOffset(const GPU::PositionI16& offset) {
|
||||
constexpr auto X = BitRange::from_to(0, 10);
|
||||
constexpr auto Y = BitRange::from_to(11, 21);
|
||||
|
||||
return internal::construct_cmd<GPU_IO_Values::GP0>(0xE5, X.as_value(static_cast<int32_t>(offset.x)) | Y.as_value(static_cast<int32_t>(offset.y)));
|
||||
}
|
||||
|
||||
static constexpr GP0 PostionTopLeft(const GPU::PositionU16& position) {
|
||||
return GP0{(static_cast<uint32_t>(position.y) << 16u) | position.x};
|
||||
}
|
||||
|
||||
static constexpr GP0 WidthHeight(const GPU::SizeU16& size) {
|
||||
return GP0{(static_cast<uint32_t>(size.height) << 16u) | size.width};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(GP1, uint32_t) {
|
||||
static constexpr auto ID = BitRange::from_to(24, 31);
|
||||
static constexpr auto Value = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr GP1 Reset() {
|
||||
return GP1{0};
|
||||
}
|
||||
|
||||
static constexpr GP1 ResetCMDBuffer() {
|
||||
return internal::construct_cmd<GP1>(0x01, 0);
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayState(DisplayMode::State state) {
|
||||
return internal::construct_cmd<GP1>(0x03, static_cast<uint32_t>(state));
|
||||
}
|
||||
|
||||
static constexpr GP1 DMADirection(GPUSTAT::DMADirection dir) {
|
||||
return internal::construct_cmd<GP1>(0x04, dir);
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayArea(const GPU::PositionU16& position) {
|
||||
constexpr auto X = BitRange::from_to(0, 9);
|
||||
constexpr auto Y = BitRange::from_to(10, 18);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x05, X.as_value(static_cast<uint32_t>(position.x)) | Y.as_value(static_cast<uint32_t>(position.y)));
|
||||
}
|
||||
|
||||
static constexpr GP1 HorizontalDisplayRange(uint16_t x1, uint16_t x2) {
|
||||
constexpr auto X1 = BitRange::from_to(0, 11);
|
||||
constexpr auto X2 = BitRange::from_to(12, 23);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x06, X1.as_value(static_cast<uint32_t>(x1)) | X2.as_value(static_cast<uint32_t>(x2)));
|
||||
}
|
||||
|
||||
static constexpr GP1 VerticalDisplayRange(uint16_t y1, uint16_t y2) {
|
||||
constexpr auto Y1 = BitRange::from_to(0, 9);
|
||||
constexpr auto Y2 = BitRange::from_to(10, 19);
|
||||
|
||||
return internal::construct_cmd<GP1>(0x07, Y1.as_value(static_cast<uint32_t>(y1)) | Y2.as_value(static_cast<uint32_t>(y2)));
|
||||
}
|
||||
|
||||
static constexpr GP1 DisplayMode(GPU_IO_Values::DisplayMode mode) {
|
||||
return internal::construct_cmd<GP1>(0x08, mode.raw);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Interrupt_IO_Values {
|
||||
__declare_io_struct(Mask, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Status, uint32_t) {
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Interrupt_IO_Values {
|
||||
__declare_io_struct(Mask, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Status, uint32_t) {
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,118 +1,118 @@
|
||||
#pragma once
|
||||
#include "../../../Auxiliary/types.hpp"
|
||||
#include "../../../Auxiliary/bits.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace IOAdress {
|
||||
constexpr uintptr_t patch_adr(uintptr_t adr) {
|
||||
constexpr uintptr_t Mask = 0xF0000000;
|
||||
constexpr uintptr_t Base = 0x10000000; // We might want to change this later to 0xB0000000 for caching and stuff (More research needed)
|
||||
|
||||
return (Base + (adr & ~Mask));
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename T, typename S>
|
||||
struct IOValue {
|
||||
typedef S UnderlyingType;
|
||||
|
||||
UnderlyingType raw;
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr T from(const ARGS&...args) {
|
||||
return T{0}.set(args...);
|
||||
}
|
||||
|
||||
constexpr T& set(Bit bit) {
|
||||
this->raw = bit::set(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& set(ClearBit bit) {
|
||||
this->raw = bit::set(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& set_range(const BitRange& bits, UnderlyingType value) {
|
||||
this->raw = bit::value::set_normalized(this->raw, bits, value);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr T& set(const BitRange::RangeValuePair<U>& value) {
|
||||
this->raw = bit::value::set_normalized(this->raw, value);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
template<typename U, typename...ARGS>
|
||||
constexpr T& set(const U& head, const ARGS&...tail) {
|
||||
return this->set(head).set(tail...);
|
||||
}
|
||||
|
||||
constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const {
|
||||
return bit::value::get_normalized(this->raw, bits.pos, bits.length);
|
||||
}
|
||||
|
||||
constexpr T& clear(Bit bit) {
|
||||
this->raw = bit::clear(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr bool is_set(Bit bit) const {
|
||||
return bit::is_set(this->raw, bit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct IOPort {
|
||||
using Value = T;
|
||||
T value;
|
||||
|
||||
T read() const {
|
||||
return {const_cast<const volatile IOPort<T>*>(this)->value.raw};
|
||||
}
|
||||
|
||||
void write(T value) {
|
||||
const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct IOPort<uint32_t>;
|
||||
|
||||
template<typename T>
|
||||
struct IOPort32 {
|
||||
union ValueHelper {
|
||||
struct {
|
||||
uint16_t low;
|
||||
uint16_t high;
|
||||
};
|
||||
T value;
|
||||
};
|
||||
using Value = T;
|
||||
T value;
|
||||
|
||||
T read() const {
|
||||
const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(this);
|
||||
const volatile auto* cv_this = const_cast<volatile decltype(cast_this)>(cast_this);
|
||||
|
||||
return ValueHelper{.low = cv_this->value.low, .high = cv_this->value.high}.value;
|
||||
}
|
||||
|
||||
void write(T value) {
|
||||
const auto new_value = ValueHelper{.value = value};
|
||||
auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this);
|
||||
volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this);
|
||||
|
||||
v_this->value.low = new_value.low;
|
||||
v_this->value.high = new_value.high;
|
||||
}
|
||||
};
|
||||
|
||||
#define __declare_io_struct(name, type) struct name : public ::JabyEngine::internal::IOValue<struct name, type>
|
||||
#define __declare_io_port(type, adr) *reinterpret_cast<type*>(adr)
|
||||
#define __declare_io_value(type, adr) __declare_io_port(type, adr)
|
||||
#define __declare_io_port_array(type, size, adr) reinterpret_cast<type(&)[size]>(*reinterpret_cast<type*>(adr))
|
||||
#pragma once
|
||||
#include "../../../Auxiliary/types.hpp"
|
||||
#include "../../../Auxiliary/bits.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace IOAdress {
|
||||
constexpr uintptr_t patch_adr(uintptr_t adr) {
|
||||
constexpr uintptr_t Mask = 0xF0000000;
|
||||
constexpr uintptr_t Base = 0x10000000; // We might want to change this later to 0xB0000000 for caching and stuff (More research needed)
|
||||
|
||||
return (Base + (adr & ~Mask));
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename T, typename S>
|
||||
struct IOValue {
|
||||
typedef S UnderlyingType;
|
||||
|
||||
UnderlyingType raw;
|
||||
|
||||
template<typename...ARGS>
|
||||
static constexpr T from(const ARGS&...args) {
|
||||
return T{0}.set(args...);
|
||||
}
|
||||
|
||||
constexpr T& set(Bit bit) {
|
||||
this->raw = bit::set(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& set(ClearBit bit) {
|
||||
this->raw = bit::set(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& set_range(const BitRange& bits, UnderlyingType value) {
|
||||
this->raw = bit::value::set_normalized(this->raw, bits, value);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr T& set(const BitRange::RangeValuePair<U>& value) {
|
||||
this->raw = bit::value::set_normalized(this->raw, value);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
template<typename U, typename...ARGS>
|
||||
constexpr T& set(const U& head, const ARGS&...tail) {
|
||||
return this->set(head).set(tail...);
|
||||
}
|
||||
|
||||
constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const {
|
||||
return bit::value::get_normalized(this->raw, bits.pos, bits.length);
|
||||
}
|
||||
|
||||
constexpr T& clear(Bit bit) {
|
||||
this->raw = bit::clear(this->raw, bit);
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr bool is_set(Bit bit) const {
|
||||
return bit::is_set(this->raw, bit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct IOPort {
|
||||
using Value = T;
|
||||
T value;
|
||||
|
||||
T read() const {
|
||||
return {const_cast<const volatile IOPort<T>*>(this)->value.raw};
|
||||
}
|
||||
|
||||
void write(T value) {
|
||||
const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct IOPort<uint32_t>;
|
||||
|
||||
template<typename T>
|
||||
struct IOPort32 {
|
||||
union ValueHelper {
|
||||
struct {
|
||||
uint16_t low;
|
||||
uint16_t high;
|
||||
};
|
||||
T value;
|
||||
};
|
||||
using Value = T;
|
||||
T value;
|
||||
|
||||
T read() const {
|
||||
const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(this);
|
||||
const volatile auto* cv_this = const_cast<volatile decltype(cast_this)>(cast_this);
|
||||
|
||||
return ValueHelper{.low = cv_this->value.low, .high = cv_this->value.high}.value;
|
||||
}
|
||||
|
||||
void write(T value) {
|
||||
const auto new_value = ValueHelper{.value = value};
|
||||
auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this);
|
||||
volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this);
|
||||
|
||||
v_this->value.low = new_value.low;
|
||||
v_this->value.high = new_value.high;
|
||||
}
|
||||
};
|
||||
|
||||
#define __declare_io_struct(name, type) struct name : public ::JabyEngine::internal::IOValue<struct name, type>
|
||||
#define __declare_io_port(type, adr) *reinterpret_cast<type*>(adr)
|
||||
#define __declare_io_value(type, adr) __declare_io_port(type, adr)
|
||||
#define __declare_io_port_array(type, size, adr) reinterpret_cast<type(&)[size]>(*reinterpret_cast<type*>(adr))
|
||||
}
|
@@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Memory_IO_Values {
|
||||
__declare_io_struct(CD_DELAY, uint32_t) {
|
||||
static constexpr CD_DELAY create() {
|
||||
return CD_DELAY{0x20943};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(COM_DELAY, uint32_t) {
|
||||
static constexpr COM_DELAY create() {
|
||||
return COM_DELAY{0x1325};
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Memory_IO_Values {
|
||||
__declare_io_struct(CD_DELAY, uint32_t) {
|
||||
static constexpr CD_DELAY create() {
|
||||
return CD_DELAY{0x20943};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(COM_DELAY, uint32_t) {
|
||||
static constexpr COM_DELAY create() {
|
||||
return COM_DELAY{0x1325};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,52 +1,52 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery_IO_Values {
|
||||
__declare_io_struct(JOY_BAUD, uint16_t) {
|
||||
static constexpr JOY_BAUD create() {
|
||||
return JOY_BAUD{0x0088};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_CTRL, uint16_t) {
|
||||
static constexpr auto TXEnable = Bit(0);
|
||||
static constexpr auto SelectJoy = Bit(1);
|
||||
static constexpr auto ACK = Bit(4);
|
||||
static constexpr auto ACKIrqEnable = Bit(12);
|
||||
static constexpr auto PortBSelected = Bit(13);
|
||||
static constexpr auto PortASelected = !PortBSelected;
|
||||
|
||||
static constexpr JOY_CTRL create_for(uint16_t port) {
|
||||
return JOY_CTRL{static_cast<uint16_t>(port << PortBSelected)}.set(TXEnable, SelectJoy, ACKIrqEnable);
|
||||
}
|
||||
|
||||
static constexpr JOY_CTRL close() {
|
||||
return JOY_CTRL{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_MODE, uint16_t) {
|
||||
static constexpr JOY_MODE create() {
|
||||
return JOY_MODE{0x000D};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_RX_DATA, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_STAT, uint32_t) {
|
||||
static constexpr auto TXReadyStart = Bit(0);
|
||||
static constexpr auto RXFifoNonEmpty = Bit(1);
|
||||
static constexpr auto TXReadyFinished = Bit(2);
|
||||
static constexpr auto RXParityError = Bit(3);
|
||||
static constexpr auto ACKIrqLow = Bit(7);
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_TX_DATA, uint32_t) {
|
||||
static constexpr JOY_TX_DATA create(uint8_t byte) {
|
||||
return JOY_TX_DATA{byte};
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery_IO_Values {
|
||||
__declare_io_struct(JOY_BAUD, uint16_t) {
|
||||
static constexpr JOY_BAUD create() {
|
||||
return JOY_BAUD{0x0088};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_CTRL, uint16_t) {
|
||||
static constexpr auto TXEnable = Bit(0);
|
||||
static constexpr auto SelectJoy = Bit(1);
|
||||
static constexpr auto ACK = Bit(4);
|
||||
static constexpr auto ACKIrqEnable = Bit(12);
|
||||
static constexpr auto PortBSelected = Bit(13);
|
||||
static constexpr auto PortASelected = !PortBSelected;
|
||||
|
||||
static constexpr JOY_CTRL create_for(uint16_t port) {
|
||||
return JOY_CTRL{static_cast<uint16_t>(port << PortBSelected)}.set(TXEnable, SelectJoy, ACKIrqEnable);
|
||||
}
|
||||
|
||||
static constexpr JOY_CTRL close() {
|
||||
return JOY_CTRL{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_MODE, uint16_t) {
|
||||
static constexpr JOY_MODE create() {
|
||||
return JOY_MODE{0x000D};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_RX_DATA, uint8_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_STAT, uint32_t) {
|
||||
static constexpr auto TXReadyStart = Bit(0);
|
||||
static constexpr auto RXFifoNonEmpty = Bit(1);
|
||||
static constexpr auto TXReadyFinished = Bit(2);
|
||||
static constexpr auto RXParityError = Bit(3);
|
||||
static constexpr auto ACKIrqLow = Bit(7);
|
||||
};
|
||||
|
||||
__declare_io_struct(JOY_TX_DATA, uint32_t) {
|
||||
static constexpr JOY_TX_DATA create(uint8_t byte) {
|
||||
return JOY_TX_DATA{byte};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,215 +1,215 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
#include <limits.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace SPU_IO_Values {
|
||||
namespace MemoryMap {
|
||||
static constexpr uintptr_t ADPCM = 0x01000;
|
||||
static constexpr uintptr_t End = 0x7FFFF;
|
||||
}
|
||||
|
||||
__declare_io_struct(AD, uint16_t) {
|
||||
static constexpr auto AttackMode = Bit(15);
|
||||
static constexpr auto AttackShift = BitRange::from_to(10, 14);
|
||||
static constexpr auto AttackStep = BitRange::from_to(8, 9);
|
||||
static constexpr auto DecayShift = BitRange::from_to(4, 7);
|
||||
static constexpr auto SustainLevel = BitRange::from_to(0, 3);
|
||||
|
||||
static constexpr AD none() {
|
||||
return AD{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ControlRegister, uint16_t) {
|
||||
enum RAMTransferMode {
|
||||
Stop = 0,
|
||||
ManualWrite = 1,
|
||||
DMAWrite = 2,
|
||||
DMARead = 3
|
||||
};
|
||||
|
||||
static constexpr auto Enable = Bit(15);
|
||||
static constexpr auto Unmute = Bit(14);
|
||||
static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13);
|
||||
static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9);
|
||||
static constexpr auto ReverbMasterEnable = Bit(7);
|
||||
static constexpr auto IRQ9Enable = Bit(6);
|
||||
static constexpr auto TransferMode = BitRange::from_to(4, 5);
|
||||
static constexpr auto ExternalAudioReverb = Bit(3);
|
||||
static constexpr auto CDAudioReverb = Bit(2);
|
||||
static constexpr auto ExternalAudioEnable = Bit(1);
|
||||
static constexpr auto CDAudioEnable = Bit(0);
|
||||
};
|
||||
|
||||
__declare_io_struct(DataTransferControl, uint16_t) {
|
||||
static constexpr DataTransferControl NormalTransferMode() {
|
||||
return DataTransferControl{0x0004};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(Echo, uint32_t) {
|
||||
static constexpr auto EchoBits = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr Echo AllOff() {
|
||||
return Echo{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyOff, uint32_t) {
|
||||
static constexpr KeyOff for_specific(uint32_t id) {
|
||||
return KeyOff{1u << id};
|
||||
}
|
||||
|
||||
static constexpr KeyOff all() {
|
||||
return KeyOff{UI32_MAX};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyOn, uint32_t) {
|
||||
static constexpr KeyOn for_specific(uint32_t id) {
|
||||
return KeyOn{1u << id};
|
||||
}
|
||||
|
||||
static constexpr KeyOn all() {
|
||||
return KeyOn{UI32_MAX};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyStatus, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Noise, uint16_t) {
|
||||
static constexpr auto NoiseBits = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr Noise AllOff() {
|
||||
return Noise{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(PitchModulation, uint32_t) {
|
||||
static constexpr auto EnableBits = BitRange::from_to(1, 23);
|
||||
|
||||
static constexpr PitchModulation AllOff() {
|
||||
return PitchModulation{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SampleRate, uint16_t) {
|
||||
static constexpr SampleRate stop() {
|
||||
return SampleRate{0};
|
||||
}
|
||||
|
||||
static constexpr SampleRate from_HZ(uint32_t freq) {
|
||||
constexpr uint32_t Base1024Hz = static_cast<uint32_t>((4096.0/44100.0)*1024.0);
|
||||
return SampleRate{static_cast<uint16_t>((freq >> 10)*Base1024Hz)};
|
||||
}
|
||||
|
||||
static constexpr SampleRate from_HZ(double freq) {
|
||||
//4096 == 44100Hz
|
||||
constexpr double Base = (4096.0 / 44100.0);
|
||||
return SampleRate{static_cast<uint16_t>((freq*Base))};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SimpleVolume, int16_t) {
|
||||
static constexpr auto MaxVolume = I16_MAX;
|
||||
|
||||
static constexpr SimpleVolume mute() {
|
||||
return SimpleVolume{0};
|
||||
}
|
||||
|
||||
constexpr operator int16_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr SimpleVolume operator""_vol(long double fraction) {
|
||||
return {static_cast<int16_t>(static_cast<long double>(SimpleVolume::MaxVolume)*fraction)};
|
||||
}
|
||||
|
||||
__declare_io_struct(SR, uint16_t) {
|
||||
static constexpr auto SustainMode = Bit(31 - 16);
|
||||
static constexpr auto SustainDirection = Bit(30 - 16);
|
||||
static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16));
|
||||
static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16));
|
||||
static constexpr auto ReleaseMode = Bit(21 - 16);
|
||||
static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16));
|
||||
|
||||
static constexpr SR none() {
|
||||
return SR{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SRAMAdr, uint16_t) {
|
||||
static constexpr SRAMAdr null() {
|
||||
return SRAMAdr{0x0};
|
||||
}
|
||||
|
||||
static constexpr SRAMAdr adpcm_start() {
|
||||
return SRAMAdr{MemoryMap::ADPCM};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(StatusRegister, uint16_t) {
|
||||
enum CapureBufferHalf {
|
||||
First = 0,
|
||||
Second = 1
|
||||
};
|
||||
|
||||
static constexpr auto Unused = BitRange::from_to(12, 15);
|
||||
static constexpr auto CaputreBufferHalf = Bit(11);
|
||||
static constexpr auto TransferBusy = Bit(10);
|
||||
static constexpr auto IsDMARead = Bit(9);
|
||||
static constexpr auto isDMAWrite = Bit(8);
|
||||
static constexpr auto isDMA = Bit(7);
|
||||
static constexpr auto isIRQ = Bit(6);
|
||||
// Copies of ControlRegister
|
||||
static constexpr auto TransferMode = BitRange::from_to(4, 5);
|
||||
static constexpr auto ExternalAudioReverb = Bit(3);
|
||||
static constexpr auto CDAudioReverb = Bit(2);
|
||||
static constexpr auto ExternalAudioEnable = Bit(1);
|
||||
static constexpr auto CDAudioEnable = Bit(0);
|
||||
};
|
||||
|
||||
__declare_io_struct(SweepVolume, int16_t) {
|
||||
struct VolumeMode {
|
||||
static constexpr auto MaxVolume = (I16_MAX >> 1);
|
||||
static constexpr auto EnableSweep = Bit(15);
|
||||
static constexpr auto Enable = !EnableSweep;
|
||||
static constexpr auto Volume = BitRange::from_to(0, 14);
|
||||
};
|
||||
|
||||
struct SweepMode {
|
||||
enum Mode {
|
||||
Linear = 0,
|
||||
Exponential = 1,
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
Increase = 0,
|
||||
Decrease = 1,
|
||||
};
|
||||
|
||||
enum Phase {
|
||||
Posititve = 0,
|
||||
Negative = 1,
|
||||
};
|
||||
|
||||
static constexpr auto Mode = Bit(14);
|
||||
static constexpr auto Direction = Bit(13);
|
||||
static constexpr auto Phase = Bit(12);
|
||||
static constexpr auto Shift = BitRange::from_to(2, 6);
|
||||
static constexpr auto Step = BitRange::from_to(0, 1);
|
||||
};
|
||||
|
||||
static constexpr SweepVolume create(SimpleVolume volume) {
|
||||
return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1));
|
||||
}
|
||||
|
||||
static constexpr SweepVolume mute() {
|
||||
return SweepVolume{0};
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
#include <limits.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace SPU_IO_Values {
|
||||
namespace MemoryMap {
|
||||
static constexpr uintptr_t ADPCM = 0x01000;
|
||||
static constexpr uintptr_t End = 0x7FFFF;
|
||||
}
|
||||
|
||||
__declare_io_struct(AD, uint16_t) {
|
||||
static constexpr auto AttackMode = Bit(15);
|
||||
static constexpr auto AttackShift = BitRange::from_to(10, 14);
|
||||
static constexpr auto AttackStep = BitRange::from_to(8, 9);
|
||||
static constexpr auto DecayShift = BitRange::from_to(4, 7);
|
||||
static constexpr auto SustainLevel = BitRange::from_to(0, 3);
|
||||
|
||||
static constexpr AD none() {
|
||||
return AD{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(ControlRegister, uint16_t) {
|
||||
enum RAMTransferMode {
|
||||
Stop = 0,
|
||||
ManualWrite = 1,
|
||||
DMAWrite = 2,
|
||||
DMARead = 3
|
||||
};
|
||||
|
||||
static constexpr auto Enable = Bit(15);
|
||||
static constexpr auto Unmute = Bit(14);
|
||||
static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13);
|
||||
static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9);
|
||||
static constexpr auto ReverbMasterEnable = Bit(7);
|
||||
static constexpr auto IRQ9Enable = Bit(6);
|
||||
static constexpr auto TransferMode = BitRange::from_to(4, 5);
|
||||
static constexpr auto ExternalAudioReverb = Bit(3);
|
||||
static constexpr auto CDAudioReverb = Bit(2);
|
||||
static constexpr auto ExternalAudioEnable = Bit(1);
|
||||
static constexpr auto CDAudioEnable = Bit(0);
|
||||
};
|
||||
|
||||
__declare_io_struct(DataTransferControl, uint16_t) {
|
||||
static constexpr DataTransferControl NormalTransferMode() {
|
||||
return DataTransferControl{0x0004};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(Echo, uint32_t) {
|
||||
static constexpr auto EchoBits = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr Echo AllOff() {
|
||||
return Echo{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyOff, uint32_t) {
|
||||
static constexpr KeyOff for_specific(uint32_t id) {
|
||||
return KeyOff{1u << id};
|
||||
}
|
||||
|
||||
static constexpr KeyOff all() {
|
||||
return KeyOff{UI32_MAX};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyOn, uint32_t) {
|
||||
static constexpr KeyOn for_specific(uint32_t id) {
|
||||
return KeyOn{1u << id};
|
||||
}
|
||||
|
||||
static constexpr KeyOn all() {
|
||||
return KeyOn{UI32_MAX};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(KeyStatus, uint32_t) {
|
||||
};
|
||||
|
||||
__declare_io_struct(Noise, uint16_t) {
|
||||
static constexpr auto NoiseBits = BitRange::from_to(0, 23);
|
||||
|
||||
static constexpr Noise AllOff() {
|
||||
return Noise{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(PitchModulation, uint32_t) {
|
||||
static constexpr auto EnableBits = BitRange::from_to(1, 23);
|
||||
|
||||
static constexpr PitchModulation AllOff() {
|
||||
return PitchModulation{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SampleRate, uint16_t) {
|
||||
static constexpr SampleRate stop() {
|
||||
return SampleRate{0};
|
||||
}
|
||||
|
||||
static constexpr SampleRate from_HZ(uint32_t freq) {
|
||||
constexpr uint32_t Base1024Hz = static_cast<uint32_t>((4096.0/44100.0)*1024.0);
|
||||
return SampleRate{static_cast<uint16_t>((freq >> 10)*Base1024Hz)};
|
||||
}
|
||||
|
||||
static constexpr SampleRate from_HZ(double freq) {
|
||||
//4096 == 44100Hz
|
||||
constexpr double Base = (4096.0 / 44100.0);
|
||||
return SampleRate{static_cast<uint16_t>((freq*Base))};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SimpleVolume, int16_t) {
|
||||
static constexpr auto MaxVolume = I16_MAX;
|
||||
|
||||
static constexpr SimpleVolume mute() {
|
||||
return SimpleVolume{0};
|
||||
}
|
||||
|
||||
constexpr operator int16_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr SimpleVolume operator""_vol(long double fraction) {
|
||||
return {static_cast<int16_t>(static_cast<long double>(SimpleVolume::MaxVolume)*fraction)};
|
||||
}
|
||||
|
||||
__declare_io_struct(SR, uint16_t) {
|
||||
static constexpr auto SustainMode = Bit(31 - 16);
|
||||
static constexpr auto SustainDirection = Bit(30 - 16);
|
||||
static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16));
|
||||
static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16));
|
||||
static constexpr auto ReleaseMode = Bit(21 - 16);
|
||||
static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16));
|
||||
|
||||
static constexpr SR none() {
|
||||
return SR{0};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(SRAMAdr, uint16_t) {
|
||||
static constexpr SRAMAdr null() {
|
||||
return SRAMAdr{0x0};
|
||||
}
|
||||
|
||||
static constexpr SRAMAdr adpcm_start() {
|
||||
return SRAMAdr{MemoryMap::ADPCM};
|
||||
}
|
||||
};
|
||||
|
||||
__declare_io_struct(StatusRegister, uint16_t) {
|
||||
enum CapureBufferHalf {
|
||||
First = 0,
|
||||
Second = 1
|
||||
};
|
||||
|
||||
static constexpr auto Unused = BitRange::from_to(12, 15);
|
||||
static constexpr auto CaputreBufferHalf = Bit(11);
|
||||
static constexpr auto TransferBusy = Bit(10);
|
||||
static constexpr auto IsDMARead = Bit(9);
|
||||
static constexpr auto isDMAWrite = Bit(8);
|
||||
static constexpr auto isDMA = Bit(7);
|
||||
static constexpr auto isIRQ = Bit(6);
|
||||
// Copies of ControlRegister
|
||||
static constexpr auto TransferMode = BitRange::from_to(4, 5);
|
||||
static constexpr auto ExternalAudioReverb = Bit(3);
|
||||
static constexpr auto CDAudioReverb = Bit(2);
|
||||
static constexpr auto ExternalAudioEnable = Bit(1);
|
||||
static constexpr auto CDAudioEnable = Bit(0);
|
||||
};
|
||||
|
||||
__declare_io_struct(SweepVolume, int16_t) {
|
||||
struct VolumeMode {
|
||||
static constexpr auto MaxVolume = (I16_MAX >> 1);
|
||||
static constexpr auto EnableSweep = Bit(15);
|
||||
static constexpr auto Enable = !EnableSweep;
|
||||
static constexpr auto Volume = BitRange::from_to(0, 14);
|
||||
};
|
||||
|
||||
struct SweepMode {
|
||||
enum Mode {
|
||||
Linear = 0,
|
||||
Exponential = 1,
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
Increase = 0,
|
||||
Decrease = 1,
|
||||
};
|
||||
|
||||
enum Phase {
|
||||
Posititve = 0,
|
||||
Negative = 1,
|
||||
};
|
||||
|
||||
static constexpr auto Mode = Bit(14);
|
||||
static constexpr auto Direction = Bit(13);
|
||||
static constexpr auto Phase = Bit(12);
|
||||
static constexpr auto Shift = BitRange::from_to(2, 6);
|
||||
static constexpr auto Step = BitRange::from_to(0, 1);
|
||||
};
|
||||
|
||||
static constexpr SweepVolume create(SimpleVolume volume) {
|
||||
return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1));
|
||||
}
|
||||
|
||||
static constexpr SweepVolume mute() {
|
||||
return SweepVolume{0};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,31 +1,31 @@
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Timer_IO_Values {
|
||||
__declare_io_struct(CounterMode, uint32_t) {
|
||||
static constexpr auto SyncEnable = Bit(0);
|
||||
static constexpr auto FreeRun = !SyncEnable;
|
||||
static constexpr auto SyncMode = BitRange::from_to(1, 2);
|
||||
static constexpr auto ResetAfterTarget = Bit(3);
|
||||
static constexpr auto IRQAtTarget = Bit(4);
|
||||
static constexpr auto IRQAtMax = Bit(5);
|
||||
static constexpr auto IRQEveryTime = Bit(6);
|
||||
static constexpr auto IRQOneShot = !IRQEveryTime;
|
||||
static constexpr auto IRQToggle = Bit(7);
|
||||
static constexpr auto IRQPulse = !IRQToggle;
|
||||
static constexpr auto ClockSource = BitRange::from_to(8, 9);
|
||||
static constexpr auto HasIRQRequest = Bit(10);
|
||||
static constexpr auto IsTargetReached = Bit(11);
|
||||
static constexpr auto IsMaxReached = Bit(12);
|
||||
};
|
||||
|
||||
__declare_io_struct(CounterTarget, uint32_t) {
|
||||
static constexpr auto CounterTargetValue = BitRange::from_to(0, 15);
|
||||
};
|
||||
|
||||
__declare_io_struct(CounterValue, uint32_t) {
|
||||
static constexpr auto Value = BitRange::from_to(0, 15);
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "ioport.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Timer_IO_Values {
|
||||
__declare_io_struct(CounterMode, uint32_t) {
|
||||
static constexpr auto SyncEnable = Bit(0);
|
||||
static constexpr auto FreeRun = !SyncEnable;
|
||||
static constexpr auto SyncMode = BitRange::from_to(1, 2);
|
||||
static constexpr auto ResetAfterTarget = Bit(3);
|
||||
static constexpr auto IRQAtTarget = Bit(4);
|
||||
static constexpr auto IRQAtMax = Bit(5);
|
||||
static constexpr auto IRQEveryTime = Bit(6);
|
||||
static constexpr auto IRQOneShot = !IRQEveryTime;
|
||||
static constexpr auto IRQToggle = Bit(7);
|
||||
static constexpr auto IRQPulse = !IRQToggle;
|
||||
static constexpr auto ClockSource = BitRange::from_to(8, 9);
|
||||
static constexpr auto HasIRQRequest = Bit(10);
|
||||
static constexpr auto IsTargetReached = Bit(11);
|
||||
static constexpr auto IsMaxReached = Bit(12);
|
||||
};
|
||||
|
||||
__declare_io_struct(CounterTarget, uint32_t) {
|
||||
static constexpr auto CounterTargetValue = BitRange::from_to(0, 15);
|
||||
};
|
||||
|
||||
__declare_io_struct(CounterValue, uint32_t) {
|
||||
static constexpr auto Value = BitRange::from_to(0, 15);
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,41 +1,41 @@
|
||||
#pragma once
|
||||
#include "IOValues/interrupt_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
using Status_IO = IOPort<Interrupt_IO_Values::Status>;
|
||||
using Mask_IO = IOPort<Interrupt_IO_Values::Mask>;
|
||||
|
||||
struct Interrupt {
|
||||
static constexpr auto VBlank = Bit(0);
|
||||
static constexpr auto GPU = Bit(1);
|
||||
static constexpr auto CDROM = Bit(2);
|
||||
static constexpr auto DMA = Bit(3);
|
||||
static constexpr auto Timer0 = Bit(4);
|
||||
static constexpr auto Timer1 = Bit(5);
|
||||
static constexpr auto Timer2 = Bit(6);
|
||||
static constexpr auto Periphery = Bit(7);
|
||||
static constexpr auto SIO = Bit(8);
|
||||
static constexpr auto SPU = Bit(9);
|
||||
static constexpr auto Controller = Bit(10);
|
||||
static constexpr auto LightPen = Controller;
|
||||
|
||||
static inline auto& Status = __declare_io_port(Status_IO, 0x1F801070);
|
||||
static inline auto& Mask = __declare_io_port(Mask_IO, 0x1F801074);
|
||||
|
||||
static bool is_irq(Bit irq) {
|
||||
return Status.read().is_set(irq);
|
||||
}
|
||||
|
||||
static void ack_irq(Bit irq) {
|
||||
Status.write({bit::clear<uint32_t>(0b11111111111, irq)});
|
||||
}
|
||||
|
||||
static void disable_irq(Bit irq) {
|
||||
Mask.write(Mask.read().clear(irq));
|
||||
}
|
||||
|
||||
static void enable_irq(Bit irq) {
|
||||
Mask.write(Mask.read().set(irq));
|
||||
}
|
||||
};
|
||||
#pragma once
|
||||
#include "IOValues/interrupt_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
using Status_IO = IOPort<Interrupt_IO_Values::Status>;
|
||||
using Mask_IO = IOPort<Interrupt_IO_Values::Mask>;
|
||||
|
||||
struct Interrupt {
|
||||
static constexpr auto VBlank = Bit(0);
|
||||
static constexpr auto GPU = Bit(1);
|
||||
static constexpr auto CDROM = Bit(2);
|
||||
static constexpr auto DMA = Bit(3);
|
||||
static constexpr auto Timer0 = Bit(4);
|
||||
static constexpr auto Timer1 = Bit(5);
|
||||
static constexpr auto Timer2 = Bit(6);
|
||||
static constexpr auto Periphery = Bit(7);
|
||||
static constexpr auto SIO = Bit(8);
|
||||
static constexpr auto SPU = Bit(9);
|
||||
static constexpr auto Controller = Bit(10);
|
||||
static constexpr auto LightPen = Controller;
|
||||
|
||||
static inline auto& Status = __declare_io_port(Status_IO, 0x1F801070);
|
||||
static inline auto& Mask = __declare_io_port(Mask_IO, 0x1F801074);
|
||||
|
||||
static bool is_irq(Bit irq) {
|
||||
return Status.read().is_set(irq);
|
||||
}
|
||||
|
||||
static void ack_irq(Bit irq) {
|
||||
Status.write({bit::clear<uint32_t>(0b11111111111, irq)});
|
||||
}
|
||||
|
||||
static void disable_irq(Bit irq) {
|
||||
Mask.write(Mask.read().clear(irq));
|
||||
}
|
||||
|
||||
static void enable_irq(Bit irq) {
|
||||
Mask.write(Mask.read().set(irq));
|
||||
}
|
||||
};
|
||||
}
|
@@ -1,29 +1,29 @@
|
||||
#pragma once
|
||||
#include "IOValues/periphery_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery_IO {
|
||||
struct JOY_STAT_IO : public IOPort<Periphery_IO_Values::JOY_STAT> {
|
||||
inline bool has_response() const {
|
||||
return this->read().is_set(Periphery_IO_Values::JOY_STAT::RXFifoNonEmpty);
|
||||
}
|
||||
|
||||
inline bool is_ready_transfer() const {
|
||||
return this->read().is_set(Periphery_IO_Values::JOY_STAT::TXReadyFinished);
|
||||
}
|
||||
};
|
||||
|
||||
using JOY_BAUD_IO = IOPort<Periphery_IO_Values::JOY_BAUD>;
|
||||
using JOY_CTRL_IO = IOPort<Periphery_IO_Values::JOY_CTRL>;
|
||||
using JOY_MODE_IO = IOPort<Periphery_IO_Values::JOY_MODE>;
|
||||
using JOY_RX_DATA_IO = IOPort<Periphery_IO_Values::JOY_RX_DATA>;
|
||||
using JOY_TX_DATA_IO = IOPort<Periphery_IO_Values::JOY_TX_DATA>;
|
||||
|
||||
static auto& JOY_TX_DATA = __declare_io_port(JOY_TX_DATA_IO, 0x1F801040);
|
||||
static const auto& JOY_RX_DATA = __declare_io_port(JOY_RX_DATA_IO, 0x1F801040);
|
||||
static const auto& JOY_STAT = __declare_io_port(JOY_STAT_IO, 0x1F801044);
|
||||
static auto& JOY_MODE = __declare_io_port(JOY_MODE_IO, 0x1F801048);
|
||||
static auto& JOY_CTRL = __declare_io_port(JOY_CTRL_IO, 0x1F80104A);
|
||||
static auto& JOY_BAUD = __declare_io_port(JOY_BAUD_IO, 0x1F80104E);
|
||||
}
|
||||
#pragma once
|
||||
#include "IOValues/periphery_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Periphery_IO {
|
||||
struct JOY_STAT_IO : public IOPort<Periphery_IO_Values::JOY_STAT> {
|
||||
inline bool has_response() const {
|
||||
return this->read().is_set(Periphery_IO_Values::JOY_STAT::RXFifoNonEmpty);
|
||||
}
|
||||
|
||||
inline bool is_ready_transfer() const {
|
||||
return this->read().is_set(Periphery_IO_Values::JOY_STAT::TXReadyFinished);
|
||||
}
|
||||
};
|
||||
|
||||
using JOY_BAUD_IO = IOPort<Periphery_IO_Values::JOY_BAUD>;
|
||||
using JOY_CTRL_IO = IOPort<Periphery_IO_Values::JOY_CTRL>;
|
||||
using JOY_MODE_IO = IOPort<Periphery_IO_Values::JOY_MODE>;
|
||||
using JOY_RX_DATA_IO = IOPort<Periphery_IO_Values::JOY_RX_DATA>;
|
||||
using JOY_TX_DATA_IO = IOPort<Periphery_IO_Values::JOY_TX_DATA>;
|
||||
|
||||
static auto& JOY_TX_DATA = __declare_io_port(JOY_TX_DATA_IO, 0x1F801040);
|
||||
static const auto& JOY_RX_DATA = __declare_io_port(JOY_RX_DATA_IO, 0x1F801040);
|
||||
static const auto& JOY_STAT = __declare_io_port(JOY_STAT_IO, 0x1F801044);
|
||||
static auto& JOY_MODE = __declare_io_port(JOY_MODE_IO, 0x1F801048);
|
||||
static auto& JOY_CTRL = __declare_io_port(JOY_CTRL_IO, 0x1F80104A);
|
||||
static auto& JOY_BAUD = __declare_io_port(JOY_BAUD_IO, 0x1F80104E);
|
||||
}
|
||||
}
|
@@ -1,89 +1,89 @@
|
||||
#pragma once
|
||||
#include "IOValues/timer_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Timer_IO {
|
||||
using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>;
|
||||
using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>;
|
||||
using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Counter {
|
||||
CounterValue_IO value;
|
||||
CounterMode_IO mode;
|
||||
CounterTarget_IO target;
|
||||
uint32_t unused;
|
||||
|
||||
inline uint16_t get_current_value() const {
|
||||
return this->value.read().get(Timer_IO_Values::CounterValue::Value);
|
||||
}
|
||||
|
||||
inline void set_target_value(uint16_t value) {
|
||||
this->target.write(Timer_IO_Values::CounterTarget{0}.set_range(Timer_IO_Values::CounterTarget::CounterTargetValue, value));
|
||||
}
|
||||
|
||||
inline void set_mode(Timer_IO_Values::CounterMode mode) {
|
||||
this->mode.write(mode);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Counter0 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Zero_At_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto Pause_During_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Pause_Until_Hblank_Then_Freerun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto Dot_Clock = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
|
||||
struct Counter1 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Pause_During_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto Zero_At_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Pause_Until_Vblank_Then_FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto Hblank = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
|
||||
struct Counter2 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Stop_Counter = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto FreeRun_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static constexpr uintptr_t counter_base_adr(size_t ID) {
|
||||
return (0x1F801100 + (ID*0x10));
|
||||
}
|
||||
|
||||
static auto& Counter0 = __declare_io_value(struct Counter0, counter_base_adr(0));
|
||||
static auto& Counter1 = __declare_io_value(struct Counter1, counter_base_adr(1));
|
||||
static auto& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2));
|
||||
}
|
||||
#pragma once
|
||||
#include "IOValues/timer_io_values.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Timer_IO {
|
||||
using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>;
|
||||
using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>;
|
||||
using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Counter {
|
||||
CounterValue_IO value;
|
||||
CounterMode_IO mode;
|
||||
CounterTarget_IO target;
|
||||
uint32_t unused;
|
||||
|
||||
inline uint16_t get_current_value() const {
|
||||
return this->value.read().get(Timer_IO_Values::CounterValue::Value);
|
||||
}
|
||||
|
||||
inline void set_target_value(uint16_t value) {
|
||||
this->target.write(Timer_IO_Values::CounterTarget{0}.set_range(Timer_IO_Values::CounterTarget::CounterTargetValue, value));
|
||||
}
|
||||
|
||||
inline void set_mode(Timer_IO_Values::CounterMode mode) {
|
||||
this->mode.write(mode);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Counter0 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Zero_At_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto Pause_During_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Pause_Until_Hblank_Then_Freerun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto Dot_Clock = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
|
||||
struct Counter1 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Pause_During_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto Zero_At_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Pause_Until_Vblank_Then_FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto Hblank = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
|
||||
struct Counter2 : public Counter {
|
||||
struct SyncMode {
|
||||
static constexpr auto Stop_Counter = Timer_IO_Values::CounterMode::SyncMode.with(0u);
|
||||
static constexpr auto FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(1u);
|
||||
static constexpr auto FreeRun_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u);
|
||||
static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u);
|
||||
};
|
||||
|
||||
struct Source {
|
||||
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
|
||||
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(1u);
|
||||
static constexpr auto System_Clock_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u);
|
||||
static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static constexpr uintptr_t counter_base_adr(size_t ID) {
|
||||
return (0x1F801100 + (ID*0x10));
|
||||
}
|
||||
|
||||
static auto& Counter0 = __declare_io_value(struct Counter0, counter_base_adr(0));
|
||||
static auto& Counter1 = __declare_io_value(struct Counter1, counter_base_adr(1));
|
||||
static auto& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2));
|
||||
}
|
||||
}
|
@@ -1,20 +1,20 @@
|
||||
#pragma once
|
||||
#include "syscalls.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Callback {
|
||||
struct [[deprecated("Currently not supported")]] VSyncCallback {
|
||||
using Function = void (*)();
|
||||
|
||||
static Function callback;
|
||||
|
||||
static void install(Function function) {
|
||||
VSyncCallback::callback = function;
|
||||
}
|
||||
|
||||
static void uninstall() {
|
||||
VSyncCallback::install(nullptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
#include "syscalls.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace Callback {
|
||||
struct [[deprecated("Currently not supported")]] VSyncCallback {
|
||||
using Function = void (*)();
|
||||
|
||||
static Function callback;
|
||||
|
||||
static void install(Function function) {
|
||||
VSyncCallback::callback = function;
|
||||
}
|
||||
|
||||
static void uninstall() {
|
||||
VSyncCallback::install(nullptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,293 +1,293 @@
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
/*
|
||||
R0 zr Constant Zero
|
||||
R1 at Reserved for the assembler
|
||||
R2-R3 v0-v1 Values for results and expression evaluation
|
||||
R4-R7 a0-a3 Arguments
|
||||
R8-R15 t0-t7 Temporaries (not preserved across call)
|
||||
R16-R23 s0-s7 Saved (preserved across call)
|
||||
R24-R25 t8-t9 More temporaries (not preserved across call)
|
||||
R26-R27 k0-k1 Reserved for OS Kernel
|
||||
R28 gp Global Pointer
|
||||
R29 sp Stack Pointer
|
||||
R30 fp Frame Pointer
|
||||
R31 ra Return address (set by function call)
|
||||
*/
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace BIOS {
|
||||
struct Version {
|
||||
enum Type {
|
||||
Unkown,
|
||||
Devboard,
|
||||
PS1,
|
||||
PS2,
|
||||
PS3,
|
||||
PSCompatible, // internal usage only
|
||||
No$psx,
|
||||
XEBRA
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint16_t year;
|
||||
} date;
|
||||
Type type;
|
||||
const char* kernel_maker;
|
||||
const char* version_str;
|
||||
const char* gui_version;
|
||||
const char* copyright;
|
||||
};
|
||||
|
||||
extern const Version version;
|
||||
}
|
||||
|
||||
struct TCB {
|
||||
uint32_t status;
|
||||
uint32_t unused;
|
||||
uint32_t reg[32];
|
||||
uint32_t epc;
|
||||
uint32_t hi;
|
||||
uint32_t lo;
|
||||
uint32_t sr;
|
||||
uint32_t cause;
|
||||
uint32_t unused2[9];
|
||||
};
|
||||
|
||||
struct PCB {
|
||||
TCB* current_tcb;
|
||||
};
|
||||
|
||||
struct ToT {
|
||||
using ExCB = void;
|
||||
using EvCB = void;
|
||||
using FCB = void;
|
||||
|
||||
ExCB* exception_chain;
|
||||
uint32_t exception_chain_size;
|
||||
PCB* processes;
|
||||
uint32_t processes_size;
|
||||
TCB* threads;
|
||||
uint32_t threads_size;
|
||||
uint32_t reserved_0;
|
||||
uint32_t reserved_1;
|
||||
EvCB* events;
|
||||
uint32_t events_size;
|
||||
uint32_t reserved_2;
|
||||
uint32_t reserved_3;
|
||||
uint32_t reserved_4;
|
||||
uint32_t reserved_5;
|
||||
uint32_t reserved_6;
|
||||
uint32_t reserved_7;
|
||||
FCB* files;
|
||||
uint32_t files_size;
|
||||
uint32_t reserved_8;
|
||||
uint32_t reserved_9;
|
||||
};
|
||||
|
||||
extern ToT table_of_tables;
|
||||
|
||||
namespace SysCall {
|
||||
static constexpr const uint32_t Table_A = 0xA0;
|
||||
static constexpr const uint32_t Table_B = 0xB0;
|
||||
static constexpr const uint32_t Table_C = 0xC0;
|
||||
|
||||
enum struct Priority {
|
||||
CdromDmaIrq = 0,
|
||||
CdromIoIrq = 0,
|
||||
SyscallException = 0,
|
||||
|
||||
CardSpecificIrq = 1,
|
||||
VblankIrq = 1,
|
||||
Timer2Irq = 1,
|
||||
Timer1Irq = 1,
|
||||
Timer0Irq = 1,
|
||||
|
||||
PadCardIrq = 2,
|
||||
|
||||
DefInt = 3
|
||||
};
|
||||
|
||||
enum InterruptVerifierResult {
|
||||
SkipHandler = 0,
|
||||
ExecuteHandler = 1
|
||||
};
|
||||
|
||||
typedef InterruptVerifierResult (*InterruptVerifier)();
|
||||
typedef void (*InterruptHandler)(uint32_t);
|
||||
using ThreadHandle = uint32_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct InterruptCallback {
|
||||
struct InterruptCallback* next;
|
||||
InterruptHandler handler_function;
|
||||
InterruptVerifier verifier_function;
|
||||
uint32_t notUsed;
|
||||
|
||||
static constexpr InterruptCallback from(InterruptVerifier verifier, InterruptHandler handler) {
|
||||
return InterruptCallback{nullptr, handler, verifier, 0};
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table)
|
||||
|
||||
static __always_inline uint32_t* get_gp() {
|
||||
uint32_t* gp;
|
||||
__asm__("sw $gp, %0" : "=m"(gp));
|
||||
return gp;
|
||||
}
|
||||
|
||||
static __always_inline void DequeueCdIntr() {
|
||||
register uint32_t FuncID asm("t1") = 0xa3;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_A, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void FlushCache() {
|
||||
register uint32_t FuncID asm("t1") = 0x44;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_A, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void* memcpy(void *dst, const void *src, size_t len) {
|
||||
register uint32_t FuncID asm("t1") = 0x2A;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len);
|
||||
}
|
||||
|
||||
static __always_inline ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) {
|
||||
register uint32_t FuncID asm("t1") = 0x0E;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp);
|
||||
}
|
||||
|
||||
static __always_inline void [[noreturn]] ChangeThread(ThreadHandle handle) {
|
||||
register uint32_t FuncID asm("t1") = 0x10;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(ThreadHandle))(handle);
|
||||
}
|
||||
|
||||
static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) {
|
||||
register uint32_t FuncID asm("t1") = 0x12;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize);
|
||||
}
|
||||
|
||||
static __always_inline void StartPad() {
|
||||
register uint32_t FuncID asm("t1") = 0x13;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void StopPad() {
|
||||
register uint32_t FuncID asm("t1") = 0x14;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void ChangeClearPad(int32_t _reserved) {
|
||||
register uint32_t FuncID asm("t1") = 0x5B;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(int32_t))(_reserved);
|
||||
}
|
||||
|
||||
static __always_inline void [[noreturn]] ReturnFromException() {
|
||||
register uint32_t FuncID asm("t1") = 0x17;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void SetDefaultExitFromException() {
|
||||
register uint32_t FuncID asm("t1") = 0x18;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline int SysEnqIntRP(Priority prio, InterruptCallback* interElm) {
|
||||
register uint32_t FuncID asm("t1") = 0x02;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
|
||||
}
|
||||
|
||||
static __always_inline int SysDeqIntRP(Priority prio, InterruptCallback *interElm) {
|
||||
register uint32_t FuncID asm("t1") = 0x03;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
|
||||
}
|
||||
|
||||
static __always_inline uint32_t EnterCriticalSection() {
|
||||
register uint32_t FuncID asm("a0") = 0x01;
|
||||
register uint32_t returnValue asm("v0");
|
||||
|
||||
__asm__ volatile("syscall" : "=r"(returnValue) : "r"(FuncID) : "memory");
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static __always_inline void ExitCriticalSection() {
|
||||
register uint32_t FuncID asm("a0") = 0x02;
|
||||
|
||||
__asm__ volatile("syscall" :: "r"(FuncID) : "memory");
|
||||
}
|
||||
|
||||
static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) {
|
||||
register uint32_t FuncID asm("t1") = 0x07;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
__syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec);
|
||||
}
|
||||
|
||||
static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) {
|
||||
register uint32_t FuncID asm("t1") = 0x08;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler);
|
||||
}
|
||||
|
||||
static __always_inline int CloseEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x09;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline int32_t TestEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x0B;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline int32_t EnableEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x0C;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline const uint16_t* Krom2RawAdd(uint16_t sjis_code) {
|
||||
register uint32_t FuncID asm("t1") = 0x51;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, const uint16_t* (*)(uint16_t))(sjis_code);
|
||||
}
|
||||
|
||||
void printf(const char* txt, ...);
|
||||
}
|
||||
#pragma once
|
||||
#include "../jabyengine_defines.hpp"
|
||||
|
||||
/*
|
||||
R0 zr Constant Zero
|
||||
R1 at Reserved for the assembler
|
||||
R2-R3 v0-v1 Values for results and expression evaluation
|
||||
R4-R7 a0-a3 Arguments
|
||||
R8-R15 t0-t7 Temporaries (not preserved across call)
|
||||
R16-R23 s0-s7 Saved (preserved across call)
|
||||
R24-R25 t8-t9 More temporaries (not preserved across call)
|
||||
R26-R27 k0-k1 Reserved for OS Kernel
|
||||
R28 gp Global Pointer
|
||||
R29 sp Stack Pointer
|
||||
R30 fp Frame Pointer
|
||||
R31 ra Return address (set by function call)
|
||||
*/
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace BIOS {
|
||||
struct Version {
|
||||
enum Type {
|
||||
Unkown,
|
||||
Devboard,
|
||||
PS1,
|
||||
PS2,
|
||||
PS3,
|
||||
PSCompatible, // internal usage only
|
||||
No$psx,
|
||||
XEBRA
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint16_t year;
|
||||
} date;
|
||||
Type type;
|
||||
const char* kernel_maker;
|
||||
const char* version_str;
|
||||
const char* gui_version;
|
||||
const char* copyright;
|
||||
};
|
||||
|
||||
extern const Version version;
|
||||
}
|
||||
|
||||
struct TCB {
|
||||
uint32_t status;
|
||||
uint32_t unused;
|
||||
uint32_t reg[32];
|
||||
uint32_t epc;
|
||||
uint32_t hi;
|
||||
uint32_t lo;
|
||||
uint32_t sr;
|
||||
uint32_t cause;
|
||||
uint32_t unused2[9];
|
||||
};
|
||||
|
||||
struct PCB {
|
||||
TCB* current_tcb;
|
||||
};
|
||||
|
||||
struct ToT {
|
||||
using ExCB = void;
|
||||
using EvCB = void;
|
||||
using FCB = void;
|
||||
|
||||
ExCB* exception_chain;
|
||||
uint32_t exception_chain_size;
|
||||
PCB* processes;
|
||||
uint32_t processes_size;
|
||||
TCB* threads;
|
||||
uint32_t threads_size;
|
||||
uint32_t reserved_0;
|
||||
uint32_t reserved_1;
|
||||
EvCB* events;
|
||||
uint32_t events_size;
|
||||
uint32_t reserved_2;
|
||||
uint32_t reserved_3;
|
||||
uint32_t reserved_4;
|
||||
uint32_t reserved_5;
|
||||
uint32_t reserved_6;
|
||||
uint32_t reserved_7;
|
||||
FCB* files;
|
||||
uint32_t files_size;
|
||||
uint32_t reserved_8;
|
||||
uint32_t reserved_9;
|
||||
};
|
||||
|
||||
extern ToT table_of_tables;
|
||||
|
||||
namespace SysCall {
|
||||
static constexpr const uint32_t Table_A = 0xA0;
|
||||
static constexpr const uint32_t Table_B = 0xB0;
|
||||
static constexpr const uint32_t Table_C = 0xC0;
|
||||
|
||||
enum struct Priority {
|
||||
CdromDmaIrq = 0,
|
||||
CdromIoIrq = 0,
|
||||
SyscallException = 0,
|
||||
|
||||
CardSpecificIrq = 1,
|
||||
VblankIrq = 1,
|
||||
Timer2Irq = 1,
|
||||
Timer1Irq = 1,
|
||||
Timer0Irq = 1,
|
||||
|
||||
PadCardIrq = 2,
|
||||
|
||||
DefInt = 3
|
||||
};
|
||||
|
||||
enum InterruptVerifierResult {
|
||||
SkipHandler = 0,
|
||||
ExecuteHandler = 1
|
||||
};
|
||||
|
||||
typedef InterruptVerifierResult (*InterruptVerifier)();
|
||||
typedef void (*InterruptHandler)(uint32_t);
|
||||
using ThreadHandle = uint32_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct InterruptCallback {
|
||||
struct InterruptCallback* next;
|
||||
InterruptHandler handler_function;
|
||||
InterruptVerifier verifier_function;
|
||||
uint32_t notUsed;
|
||||
|
||||
static constexpr InterruptCallback from(InterruptVerifier verifier, InterruptHandler handler) {
|
||||
return InterruptCallback{nullptr, handler, verifier, 0};
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table)
|
||||
|
||||
static __always_inline uint32_t* get_gp() {
|
||||
uint32_t* gp;
|
||||
__asm__("sw $gp, %0" : "=m"(gp));
|
||||
return gp;
|
||||
}
|
||||
|
||||
static __always_inline void DequeueCdIntr() {
|
||||
register uint32_t FuncID asm("t1") = 0xa3;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_A, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void FlushCache() {
|
||||
register uint32_t FuncID asm("t1") = 0x44;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_A, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void* memcpy(void *dst, const void *src, size_t len) {
|
||||
register uint32_t FuncID asm("t1") = 0x2A;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len);
|
||||
}
|
||||
|
||||
static __always_inline ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) {
|
||||
register uint32_t FuncID asm("t1") = 0x0E;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp);
|
||||
}
|
||||
|
||||
static __always_inline void [[noreturn]] ChangeThread(ThreadHandle handle) {
|
||||
register uint32_t FuncID asm("t1") = 0x10;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(ThreadHandle))(handle);
|
||||
}
|
||||
|
||||
static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) {
|
||||
register uint32_t FuncID asm("t1") = 0x12;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize);
|
||||
}
|
||||
|
||||
static __always_inline void StartPad() {
|
||||
register uint32_t FuncID asm("t1") = 0x13;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void StopPad() {
|
||||
register uint32_t FuncID asm("t1") = 0x14;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void ChangeClearPad(int32_t _reserved) {
|
||||
register uint32_t FuncID asm("t1") = 0x5B;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)(int32_t))(_reserved);
|
||||
}
|
||||
|
||||
static __always_inline void [[noreturn]] ReturnFromException() {
|
||||
register uint32_t FuncID asm("t1") = 0x17;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline void SetDefaultExitFromException() {
|
||||
register uint32_t FuncID asm("t1") = 0x18;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
__syscall_function_cast(Table_B, void(*)())();
|
||||
}
|
||||
|
||||
static __always_inline int SysEnqIntRP(Priority prio, InterruptCallback* interElm) {
|
||||
register uint32_t FuncID asm("t1") = 0x02;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
|
||||
}
|
||||
|
||||
static __always_inline int SysDeqIntRP(Priority prio, InterruptCallback *interElm) {
|
||||
register uint32_t FuncID asm("t1") = 0x03;
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
|
||||
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
|
||||
}
|
||||
|
||||
static __always_inline uint32_t EnterCriticalSection() {
|
||||
register uint32_t FuncID asm("a0") = 0x01;
|
||||
register uint32_t returnValue asm("v0");
|
||||
|
||||
__asm__ volatile("syscall" : "=r"(returnValue) : "r"(FuncID) : "memory");
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static __always_inline void ExitCriticalSection() {
|
||||
register uint32_t FuncID asm("a0") = 0x02;
|
||||
|
||||
__asm__ volatile("syscall" :: "r"(FuncID) : "memory");
|
||||
}
|
||||
|
||||
static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) {
|
||||
register uint32_t FuncID asm("t1") = 0x07;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
__syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec);
|
||||
}
|
||||
|
||||
static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) {
|
||||
register uint32_t FuncID asm("t1") = 0x08;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler);
|
||||
}
|
||||
|
||||
static __always_inline int CloseEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x09;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline int32_t TestEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x0B;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline int32_t EnableEvent(uint32_t event) {
|
||||
register uint32_t FuncID asm("t1") = 0x0C;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
||||
}
|
||||
|
||||
static __always_inline const uint16_t* Krom2RawAdd(uint16_t sjis_code) {
|
||||
register uint32_t FuncID asm("t1") = 0x51;
|
||||
|
||||
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
||||
return __syscall_function_cast(Table_B, const uint16_t* (*)(uint16_t))(sjis_code);
|
||||
}
|
||||
|
||||
void printf(const char* txt, ...);
|
||||
}
|
||||
}
|
@@ -1,74 +1,74 @@
|
||||
#ifndef __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#define __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#include "frame_time_helper.hpp"
|
||||
#include <stdint.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
class MasterTime {
|
||||
__friends:
|
||||
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;
|
||||
|
||||
static SimpleTimer create() {
|
||||
SimpleTimer timer;
|
||||
|
||||
timer.reset();
|
||||
return timer;
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
static constexpr IntervalTimer create(T interval) {
|
||||
IntervalTimer timer;
|
||||
|
||||
static_cast<SimpleTimer<T>&>(timer) = SimpleTimer<T>::create();
|
||||
timer.interval = interval;
|
||||
return timer;
|
||||
}
|
||||
|
||||
void set_interval(T interval) {
|
||||
this->interval = interval;
|
||||
}
|
||||
|
||||
bool is_expired() const {
|
||||
return SimpleTimer<T>::is_expired_for(this->interval);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#define __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#include "frame_time_helper.hpp"
|
||||
#include <stdint.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
class MasterTime {
|
||||
__friends:
|
||||
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;
|
||||
|
||||
static SimpleTimer create() {
|
||||
SimpleTimer timer;
|
||||
|
||||
timer.reset();
|
||||
return timer;
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
static constexpr IntervalTimer create(T interval) {
|
||||
IntervalTimer timer;
|
||||
|
||||
static_cast<SimpleTimer<T>&>(timer) = SimpleTimer<T>::create();
|
||||
timer.interval = interval;
|
||||
return timer;
|
||||
}
|
||||
|
||||
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,81 +1,81 @@
|
||||
#ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__
|
||||
#define __JABYENGINE_HIGH_RES_TIMER_HPP__
|
||||
#include "../jabyengine_defines.hpp"
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/IOPorts/timer_io.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
struct CPUTicks {
|
||||
static constexpr double Frequency_Hz = 33868800.0;
|
||||
static constexpr double Frequency_Hz_Div8 = (Frequency_Hz/8.0);
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_ns(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>((time/CPU_Frequency_Hz)*1000.0*1000.0*1000.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_us(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>(((time*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_ms(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>(((time*1000.0*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
|
||||
}
|
||||
};
|
||||
|
||||
class HighResTime {
|
||||
public:
|
||||
class TimeStamp {
|
||||
private:
|
||||
uint16_t counter_10ms_value;
|
||||
uint16_t fraction;
|
||||
|
||||
constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) {
|
||||
}
|
||||
|
||||
constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) {
|
||||
return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100);
|
||||
}
|
||||
|
||||
constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) {
|
||||
return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms);
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr size_t microseconds_to(const TimeStamp& end) const {
|
||||
return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction));
|
||||
}
|
||||
|
||||
constexpr size_t milliseconds_to(const TimeStamp& end) const {
|
||||
return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction));
|
||||
}
|
||||
friend class HighResTime;
|
||||
};
|
||||
|
||||
__friends:
|
||||
static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us<uint16_t>(CPUTicks::Frequency_Hz_Div8, 100.0);
|
||||
static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 1.0);
|
||||
static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 10.0);
|
||||
|
||||
static volatile uint16_t global_counter_10ms;
|
||||
|
||||
public:
|
||||
HighResTime() = delete;
|
||||
~HighResTime() = delete;
|
||||
|
||||
static void enable() {
|
||||
Interrupt::enable_irq(Interrupt::Timer2);
|
||||
}
|
||||
|
||||
static void disable() {
|
||||
Interrupt::disable_irq(Interrupt::Timer2);
|
||||
}
|
||||
|
||||
static TimeStamp get_time_stamp() {
|
||||
return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value());
|
||||
}
|
||||
};
|
||||
}
|
||||
#ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__
|
||||
#define __JABYENGINE_HIGH_RES_TIMER_HPP__
|
||||
#include "../jabyengine_defines.hpp"
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/IOPorts/timer_io.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
struct CPUTicks {
|
||||
static constexpr double Frequency_Hz = 33868800.0;
|
||||
static constexpr double Frequency_Hz_Div8 = (Frequency_Hz/8.0);
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_ns(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>((time/CPU_Frequency_Hz)*1000.0*1000.0*1000.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_us(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>(((time*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr T ticks_per_ms(double CPU_Frequency_Hz, double time = 1.0) {
|
||||
return static_cast<T>(((time*1000.0*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
|
||||
}
|
||||
};
|
||||
|
||||
class HighResTime {
|
||||
public:
|
||||
class TimeStamp {
|
||||
private:
|
||||
uint16_t counter_10ms_value;
|
||||
uint16_t fraction;
|
||||
|
||||
constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) {
|
||||
}
|
||||
|
||||
constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) {
|
||||
return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100);
|
||||
}
|
||||
|
||||
constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) {
|
||||
return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms);
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr size_t microseconds_to(const TimeStamp& end) const {
|
||||
return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction));
|
||||
}
|
||||
|
||||
constexpr size_t milliseconds_to(const TimeStamp& end) const {
|
||||
return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction));
|
||||
}
|
||||
friend class HighResTime;
|
||||
};
|
||||
|
||||
__friends:
|
||||
static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us<uint16_t>(CPUTicks::Frequency_Hz_Div8, 100.0);
|
||||
static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 1.0);
|
||||
static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 10.0);
|
||||
|
||||
static volatile uint16_t global_counter_10ms;
|
||||
|
||||
public:
|
||||
HighResTime() = delete;
|
||||
~HighResTime() = delete;
|
||||
|
||||
static void enable() {
|
||||
Interrupt::enable_irq(Interrupt::Timer2);
|
||||
}
|
||||
|
||||
static void disable() {
|
||||
Interrupt::disable_irq(Interrupt::Timer2);
|
||||
}
|
||||
|
||||
static TimeStamp get_time_stamp() {
|
||||
return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value());
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__
|
@@ -1,37 +1,37 @@
|
||||
#pragma once
|
||||
#include <PSX/GPU/gpu_types.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
struct DefaultConfiguration {
|
||||
struct BIOSFont {
|
||||
static constexpr GPU::PositionU16 texture_load_pos() {
|
||||
return GPU::PositionU16::create(320, 256);
|
||||
}
|
||||
|
||||
static constexpr GPU::PositionU16 CLUT_load_pos() {
|
||||
return GPU::PositionU16::create(320, 511);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr auto DisplayDefaultOffset = GPU::PositionI16::create(0, 0);
|
||||
|
||||
struct Periphery {
|
||||
static constexpr bool include_portB() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr bool use_multi_tap(){
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#if __has_include(<jabyengine_custom_config.hpp>)
|
||||
#include <jabyengine_custom_config.hpp>
|
||||
using Configuration = CustomConfiguration;
|
||||
#else
|
||||
using Configuration = DefaultConfiguration;
|
||||
#define __SUPPORT_PS3__
|
||||
#define __DEBUG_SPU_MMU__
|
||||
#endif // has jabyengine_custom_config
|
||||
#pragma once
|
||||
#include <PSX/GPU/gpu_types.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
struct DefaultConfiguration {
|
||||
struct BIOSFont {
|
||||
static constexpr GPU::PositionU16 texture_load_pos() {
|
||||
return GPU::PositionU16::create(320, 256);
|
||||
}
|
||||
|
||||
static constexpr GPU::PositionU16 CLUT_load_pos() {
|
||||
return GPU::PositionU16::create(320, 511);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr auto DisplayDefaultOffset = GPU::PositionI16::create(0, 0);
|
||||
|
||||
struct Periphery {
|
||||
static constexpr bool include_portB() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr bool use_multi_tap(){
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#if __has_include(<jabyengine_custom_config.hpp>)
|
||||
#include <jabyengine_custom_config.hpp>
|
||||
using Configuration = CustomConfiguration;
|
||||
#else
|
||||
using Configuration = DefaultConfiguration;
|
||||
#define __SUPPORT_PS3__
|
||||
#define __DEBUG_SPU_MMU__
|
||||
#endif // has jabyengine_custom_config
|
||||
}
|
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
#include "Auxiliary/literals.hpp"
|
||||
#include <stddef.hpp>
|
||||
|
||||
#define __used __attribute__((used))
|
||||
#define __no_align __attribute__((packed))
|
||||
#define __no_inline __attribute__((noinline))
|
||||
#define __no_return __attribute__((noreturn))
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __section(name) __attribute__((section(name)))
|
||||
#define __collect(...) __VA_ARGS__
|
||||
|
||||
#ifndef __friends
|
||||
#define __friends private
|
||||
#pragma once
|
||||
#include "Auxiliary/literals.hpp"
|
||||
#include <stddef.hpp>
|
||||
|
||||
#define __used __attribute__((used))
|
||||
#define __no_align __attribute__((packed))
|
||||
#define __no_inline __attribute__((noinline))
|
||||
#define __no_return __attribute__((noreturn))
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __section(name) __attribute__((section(name)))
|
||||
#define __collect(...) __VA_ARGS__
|
||||
|
||||
#ifndef __friends
|
||||
#define __friends private
|
||||
#endif //!__friends
|
154
include/math.hpp
154
include/math.hpp
@@ -1,78 +1,78 @@
|
||||
#pragma once
|
||||
#include "stdint.hpp"
|
||||
|
||||
namespace math {
|
||||
template<typename T>
|
||||
struct raw_math {
|
||||
constexpr T operator-() const {
|
||||
return T{.raw = static_cast<decltype(T::raw)>(-(static_cast<const T&>(*this).raw))};
|
||||
}
|
||||
|
||||
constexpr T operator+(const T& obj) const {
|
||||
return T{.raw = static_cast<const T&>(*this).raw + obj.raw};
|
||||
}
|
||||
|
||||
constexpr T operator-(const T& b) const {}
|
||||
|
||||
constexpr T& operator+=(const T& obj) {
|
||||
static_cast<T&>(*this).raw += obj.raw;
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& operator-=(const T& obj) {
|
||||
static_cast<T&>(*this).raw -= obj.raw;
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct deg_t : public math::raw_math<deg_t> {
|
||||
static constexpr auto full_circle = 32768;
|
||||
static constexpr auto one_degree = full_circle/360;
|
||||
static constexpr auto one_tenth_degree = full_circle/3600;
|
||||
|
||||
int16_t raw;
|
||||
|
||||
static constexpr deg_t zero() {
|
||||
return deg_t{.raw = 0};
|
||||
}
|
||||
|
||||
static constexpr deg_t from_degree(int32_t deg) {
|
||||
return deg_t{.raw = static_cast<int16_t>(deg*one_degree)};
|
||||
}
|
||||
|
||||
static constexpr deg_t from_tenth_degree(int32_t deg10) {
|
||||
return deg_t{.raw = static_cast<int16_t>(deg10*one_tenth_degree)};
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr deg_t operator""_deg(long double degree) {
|
||||
return deg_t::from_tenth_degree((degree*10.0));
|
||||
}
|
||||
|
||||
struct gte_float : public math::raw_math<gte_float> {
|
||||
int32_t raw;
|
||||
|
||||
static constexpr gte_float from_double(double value) {
|
||||
return gte_float{.raw = static_cast<int32_t>(4096.0*value)};
|
||||
}
|
||||
|
||||
static constexpr gte_float one() {
|
||||
return gte_float::from_double(1.0);
|
||||
}
|
||||
|
||||
constexpr explicit operator int32_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
|
||||
constexpr explicit operator int16_t() const {
|
||||
return static_cast<int16_t>(this->raw);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr gte_float operator""_gf(long double value) {
|
||||
return gte_float::from_double(value);
|
||||
}
|
||||
|
||||
gte_float sin(deg_t value);
|
||||
#pragma once
|
||||
#include "stdint.hpp"
|
||||
|
||||
namespace math {
|
||||
template<typename T>
|
||||
struct raw_math {
|
||||
constexpr T operator-() const {
|
||||
return T{.raw = static_cast<decltype(T::raw)>(-(static_cast<const T&>(*this).raw))};
|
||||
}
|
||||
|
||||
constexpr T operator+(const T& obj) const {
|
||||
return T{.raw = static_cast<const T&>(*this).raw + obj.raw};
|
||||
}
|
||||
|
||||
constexpr T operator-(const T& b) const {}
|
||||
|
||||
constexpr T& operator+=(const T& obj) {
|
||||
static_cast<T&>(*this).raw += obj.raw;
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
constexpr T& operator-=(const T& obj) {
|
||||
static_cast<T&>(*this).raw -= obj.raw;
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct deg_t : public math::raw_math<deg_t> {
|
||||
static constexpr auto full_circle = 32768;
|
||||
static constexpr auto one_degree = full_circle/360;
|
||||
static constexpr auto one_tenth_degree = full_circle/3600;
|
||||
|
||||
int16_t raw;
|
||||
|
||||
static constexpr deg_t zero() {
|
||||
return deg_t{.raw = 0};
|
||||
}
|
||||
|
||||
static constexpr deg_t from_degree(int32_t deg) {
|
||||
return deg_t{.raw = static_cast<int16_t>(deg*one_degree)};
|
||||
}
|
||||
|
||||
static constexpr deg_t from_tenth_degree(int32_t deg10) {
|
||||
return deg_t{.raw = static_cast<int16_t>(deg10*one_tenth_degree)};
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr deg_t operator""_deg(long double degree) {
|
||||
return deg_t::from_tenth_degree((degree*10.0));
|
||||
}
|
||||
|
||||
struct gte_float : public math::raw_math<gte_float> {
|
||||
int32_t raw;
|
||||
|
||||
static constexpr gte_float from_double(double value) {
|
||||
return gte_float{.raw = static_cast<int32_t>(4096.0*value)};
|
||||
}
|
||||
|
||||
static constexpr gte_float one() {
|
||||
return gte_float::from_double(1.0);
|
||||
}
|
||||
|
||||
constexpr explicit operator int32_t() const {
|
||||
return this->raw;
|
||||
}
|
||||
|
||||
constexpr explicit operator int16_t() const {
|
||||
return static_cast<int16_t>(this->raw);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr gte_float operator""_gf(long double value) {
|
||||
return gte_float::from_double(value);
|
||||
}
|
||||
|
||||
gte_float sin(deg_t value);
|
||||
gte_float cos(deg_t value);
|
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
using va_list = __builtin_va_list;
|
||||
#define va_start __builtin_va_start
|
||||
#define va_end __builtin_va_end
|
||||
#define next_arg __builtin_next_arg
|
||||
#pragma once
|
||||
|
||||
using va_list = __builtin_va_list;
|
||||
#define va_start __builtin_va_start
|
||||
#define va_end __builtin_va_end
|
||||
#define next_arg __builtin_next_arg
|
||||
#define va_arg __builtin_va_arg
|
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#include "PSX/jabyengine_defines.hpp"
|
||||
|
||||
#pragma once
|
||||
#include "PSX/jabyengine_defines.hpp"
|
||||
|
||||
int printf(const char* txt, ...) asm("_ZN10JabyEngine7SysCall6printfEPKcz");
|
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
#include "PSX/jabyengine_defines.hpp"
|
||||
|
||||
int strncmp(const char* s1, const char* s2, size_t n);
|
||||
size_t strlen(const char* str);
|
||||
|
||||
extern "C" {
|
||||
// Needs to be provided for GCC optimizations
|
||||
void* memset(void* dest, int val, size_t len);
|
||||
#pragma once
|
||||
#include "PSX/jabyengine_defines.hpp"
|
||||
|
||||
int strncmp(const char* s1, const char* s2, size_t n);
|
||||
size_t strlen(const char* str);
|
||||
|
||||
extern "C" {
|
||||
// Needs to be provided for GCC optimizations
|
||||
void* memset(void* dest, int val, size_t len);
|
||||
}
|
Reference in New Issue
Block a user