Support Overlays #2

Merged
jaby merged 48 commits from Overlay-The-Beginning_CDDrive into main 2023-04-22 09:38:32 +00:00
6 changed files with 173 additions and 164 deletions
Showing only changes of commit bbfa7a24c8 - Show all commits

View File

@ -22,11 +22,11 @@ namespace JabyEngine {
#endif
static void enable() {
GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::On));
GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On);
}
static void disable() {
GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::Off));
GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off);
}
};

View File

@ -47,124 +47,162 @@ namespace JabyEngine {
Off = 1
};
struct Command {
struct GP0 : public ComplexBitMap<uint32_t> {
static constexpr GP0 QuickFill(GPU::Color24 color) {
return {(0x02 << 24) | color.raw()};
}
static constexpr GP0 CPU2VRAM_Blitting() {
return {(0b101u << 29)};
}
static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
constexpr auto Command = BitRange<uint32_t>::from_to(24, 31);
constexpr auto Y = BitRange<uint32_t>::from_to(10, 18);
constexpr auto X = BitRange<uint32_t>::from_to(0, 9);
return {GP0::with(Command.with(code), Y.with(y), X.with(x))};
}
static constexpr GP0 DrawAreaTopLeft(uint16_t x, uint16_t y) {
return DrawAreaTemplate(0xE3, x, y);
}
static constexpr GP0 DrawAreaBottomRight(uint16_t x, uint16_t y) {
return DrawAreaTemplate(0xE4, x, y);
}
static constexpr GP0 TopLeftPosition(uint16_t x, uint16_t y) {
return {static_cast<uint32_t>((y << 16u) | x)};
}
static constexpr GP0 WidthHeight(uint16_t w, uint16_t h) {
return {static_cast<uint32_t>((h << 16u) | w)};
}
__declare_io_type(DisplayMode, uint32_t,
enum struct TVEncoding {
NTSC = 0,
PAL = 1,
};
struct GP1 : public ComplexBitMap<uint32_t> {
static constexpr auto HorizontalResolution368 = IOBitSet(6);
static constexpr auto VerticalInterlace = IOBitSet(5);
static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(4, 4);
static constexpr auto VideoMode = IOValueSet::from_to(3, 3);
static constexpr auto VerticalResolution = IOValueSet::from_to(2, 2);
static constexpr auto HorizontalResolution = IOValueSet::from_to(0, 1);
static constexpr Self PAL() {
return Self::from(
HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
VerticalResolution.with(GPU_IO::VerticalResolution::$240),
VideoMode.with(TVEncoding::PAL),
DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
);
}
static constexpr Self NTSC() {
return Self::from(
HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
VerticalResolution.with(GPU_IO::VerticalResolution::$240),
VideoMode.with(TVEncoding::NTSC),
DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
);
}
);
__declare_io_type(GP0, uint32_t,
);
__declare_io_type(GP1, uint32_t,
);
struct Command {
struct Helper {
static constexpr GP0_t DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
constexpr auto Command = IOValueSet::from_to(24, 31);
constexpr auto Y = IOValueSet::from_to(10, 18);
constexpr auto X = IOValueSet::from_to(0, 9);
return GP0_t::from(Command.with(code), Y.with(y), X.with(x));
}
static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) {
return ((cmd << 24) | value);
}
static constexpr GP1 Reset() {
return {0};
}
static constexpr GP1 ResetCMDBufer() {
return {construct_cmd(0x01, 0)};
}
static constexpr GP1 SetDisplayState(DisplayState state) {
return {construct_cmd(0x03, static_cast<uint32_t>(state))};
}
static constexpr GP1 DMADirection(DMADirection dir) {
return {construct_cmd(0x04, static_cast<uint32_t>(dir))};
}
static constexpr GP1 DisplayArea(uint16_t x, uint16_t y) {
constexpr auto X = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y = BitRange<uint32_t>::from_to(10, 18);
return {construct_cmd(0x05, ComplexBitMap<uint32_t>::with(X.with(x), Y.with(y)).raw)};
}
static constexpr GP1 HorizontalDisplayRange(uint32_t x1, uint32_t x2) {
constexpr auto X1 = BitRange<uint32_t>::from_to(0, 11);
constexpr auto X2 = BitRange<uint32_t>::from_to(12, 23);
return {construct_cmd(0x06, ComplexBitMap<uint32_t>::with(X1.with(x1), X2.with(x2)).raw)};
}
static constexpr GP1 VerticalDisplayRange(uint32_t y1, uint32_t y2) {
constexpr auto Y1 = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y2 = BitRange<uint32_t>::from_to(10, 19);
return {construct_cmd(0x07, ComplexBitMap<uint32_t>::with(Y1.with(y1), Y2.with(y2)).raw)};
}
static constexpr GP1 DisplayMode(uint32_t mode) {
return {construct_cmd(0x08, mode)};
}
};
static constexpr GP0_t QuickFill(GPU::Color24 color) {
return {(0x02 << 24) | color.raw()};
}
static constexpr GP0_t CPU2VRAM_Blitting() {
return {(0b101u << 29)};
}
static constexpr GP0_t DrawAreaTopLeft(uint16_t x, uint16_t y) {
return Helper::DrawAreaTemplate(0xE3, x, y);
}
static constexpr GP0_t DrawAreaBottomRight(uint16_t x, uint16_t y) {
return Helper::DrawAreaTemplate(0xE4, x, y);
}
static constexpr GP0_t TopLeftPosition(uint16_t x, uint16_t y) {
return {static_cast<uint32_t>((y << 16u) | x)};
}
static constexpr GP0_t WidthHeight(uint16_t w, uint16_t h) {
return {static_cast<uint32_t>((h << 16u) | w)};
}
static constexpr GP1_t Reset() {
return {0};
}
static constexpr GP1_t ResetCMDBufer() {
return {Helper::construct_cmd(0x01, 0)};
}
static constexpr GP1_t SetDisplayState(DisplayState state) {
return {Helper::construct_cmd(0x03, static_cast<uint32_t>(state))};
}
static constexpr GP1_t DMADirection(DMADirection dir) {
return {Helper::construct_cmd(0x04, static_cast<uint32_t>(dir))};
}
static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) {
constexpr auto X = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y = BitRange<uint32_t>::from_to(10, 18);
return {Helper::construct_cmd(0x05, ComplexBitMap<uint32_t>::with(X.with(x), Y.with(y)).raw)};
}
static constexpr GP1_t HorizontalDisplayRange(uint32_t x1, uint32_t x2) {
constexpr auto X1 = BitRange<uint32_t>::from_to(0, 11);
constexpr auto X2 = BitRange<uint32_t>::from_to(12, 23);
return {Helper::construct_cmd(0x06, ComplexBitMap<uint32_t>::with(X1.with(x1), X2.with(x2)).raw)};
}
static constexpr GP1_t VerticalDisplayRange(uint32_t y1, uint32_t y2) {
constexpr auto Y1 = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y2 = BitRange<uint32_t>::from_to(10, 19);
return {Helper::construct_cmd(0x07, ComplexBitMap<uint32_t>::with(Y1.with(y1), Y2.with(y2)).raw)};
}
static constexpr GP1_t DisplayMode(DisplayMode_t mode) {
return {Helper::construct_cmd(0x08, *mode)};
}
};
struct GPUStatusRegister : public ComplexBitMap<uint32_t> {
static constexpr auto DrawingOddLinesInterlaced = Bit<uint32_t>(31);
static constexpr auto DMADirectionValue = BitRange<DMADirection>::from_to(29, 30);
static constexpr auto DMAReady = Bit<uint32_t>(28);
static constexpr auto VRAMtoCPUtransferReay = Bit<uint32_t>(27);
static constexpr auto GP0ReadyForCMD = Bit<uint32_t>(26);
static constexpr auto FifoNotFull = Bit<uint32_t>(25); // Only for Fifo
static constexpr auto InterruptRequest = Bit<uint32_t>(24);
static constexpr auto DisplayDisabled = Bit<uint32_t>(23);
static constexpr auto VerticalInterlaceOn = Bit<uint32_t>(22);
static constexpr auto DisplayAreaColorDepth = BitRange<GPU_IO::DisplayAreaColorDepth>::from_to(21, 21);
static constexpr auto VideoModePal = Bit<uint32_t>(20);
static constexpr auto VerticalResolutionValue = BitRange<VerticalResolution>::from_to(19, 19);
static constexpr auto HorizontalResolutionValue = BitRange<HorizontalResolution>::from_to(17, 18);
static constexpr auto HorizontalResolution368 = Bit<uint32_t>(16);
static constexpr auto TexturesDisabled = Bit<uint32_t>(15);
static constexpr auto NotDrawingMaskedPixels = Bit<uint32_t>(12);
static constexpr auto MaskBitSetDuringDrawEnabled = Bit<uint32_t>(11);
static constexpr auto DrawingToDisplayAreadAllowed = Bit<uint32_t>(10);
static constexpr auto DitherEnabled = Bit<uint32_t>(9);
static constexpr auto TexturePageColorValue = BitRange<TexturePageColor>::from_to(7, 8);
static constexpr auto SemiTransparencyValue = BitRange<SemiTransparency>::from_to(5, 6);
static constexpr auto TexturePageY = BitRange<uint32_t>::from_to(4, 4); // N*256
static constexpr auto TexturePageX = BitRange<uint32_t>::from_to(0, 3); // N*64
__declare_io_type(GPUSTAT, uint32_t,
static constexpr auto DrawingOddLinesInterlaced = IOBitSet(31);
static constexpr auto DMADirectionValue = IOValueSet::from_to(29, 30);
static constexpr auto DMAReady = IOBitSet(28);
static constexpr auto VRAMtoCPUtransferReay = IOBitSet(27);
static constexpr auto GP0ReadyForCMD = IOBitSet(26);
static constexpr auto FifoNotFull = IOBitSet(25); // Only for Fifo
static constexpr auto InterruptRequest = IOBitSet(24);
static constexpr auto DisplayDisabled = IOBitSet(23);
static constexpr auto VerticalInterlaceOn = IOBitSet(22);
static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(21, 21);
static constexpr auto VideoModePal = IOBitSet(20);
static constexpr auto VerticalResolutionValue = IOValueSet::from_to(19, 19);
static constexpr auto HorizontalResolutionValue = IOValueSet::from_to(17, 18);
static constexpr auto HorizontalResolution368 = IOBitSet(16);
static constexpr auto TexturesDisabled = IOBitSet(15);
static constexpr auto NotDrawingMaskedPixels = IOBitSet(12);
static constexpr auto MaskBitSetDuringDrawEnabled = IOBitSet(11);
static constexpr auto DrawingToDisplayAreadAllowed = IOBitSet(10);
static constexpr auto DitherEnabled = IOBitSet(9);
static constexpr auto TexturePageColorValue = IOValueSet::from_to(7, 8);
static constexpr auto SemiTransparencyValue = IOValueSet::from_to(5, 6);
static constexpr auto TexturePageY = IOValueSet::from_to(4, 4); // N*256
static constexpr auto TexturePageX = IOValueSet::from_to(0, 3); // N*64
static constexpr auto VerticalResolution480 = Bit<uint32_t>(19);
static constexpr auto TexturePageY256 = Bit<uint32_t>(4);
};
static constexpr auto VerticalResolution480 = IOBitSet(19);
static constexpr auto TexturePageY256 = IOBitSet(4);
);
__declare_io_port_global(Command::GP0, GP0, 0x1F801810);
__declare_io_port_global(Command::GP1, GP1, 0x1F801814);
typedef volatile uint32_t GPUREAD_v;
__declare_io_port_global_const_simple(uint32_t, GPUREAD, 0x1F801810);
__declare_io_port_global_const(GPUStatusRegister, GPUSTAT, 0x1F801814);
__declare_new_io_port(GP0, 0x1F801810);
__declare_new_io_port(GP1, 0x1F801814);
__declare_new_const_io_port(GPUREAD, 0x1F801810);
__declare_new_const_io_port(GPUSTAT, 0x1F801814);
}
}
#endif //!__JABYENGINE_GPU_IO_HPP__

View File

@ -57,6 +57,9 @@ namespace JabyEngine {
#define __declare_new_io_port(name, adr) \
__declare_new_named_io_port(name, name, adr)
#define __declare_new_const_io_port(name, adr) \
__declare_new_named_io_port(const name, name, adr)
#define __declare_new_io_port_array(name, adr, size) \
static inline auto& name = reinterpret_cast<name##_v(&)[size]>(*reinterpret_cast<name##_v*>(adr))
@ -88,8 +91,9 @@ namespace JabyEngine {
return *this; \
} \
\
constexpr name##_io_base& set(const IOValueSet::IOValueSetPair<type>& value) { \
this->set(value.first, value.second); \
template<typename S> \
constexpr name##_io_base& set(const IOValueSet::IOValueSetPair<S>& value) { \
this->set(value.first, static_cast<type>(value.second)); \
return *this; \
} \
\

View File

@ -8,50 +8,18 @@ namespace JabyEngine {
namespace GPU {
namespace internal {
struct Screen {
struct Mode {
enum struct TVEncoding {
NTSC = 0,
PAL = 1,
};
static constexpr auto HorizontalResolution368 = Bit<uint32_t>(6);
static constexpr auto VerticalInterlace = Bit<uint32_t>(5);
static constexpr auto DisplayAreaColorDepth = BitRange<GPU_IO::DisplayAreaColorDepth>::from_to(4, 4);
static constexpr auto VideoMode = BitRange<TVEncoding>::from_to(3, 3);
static constexpr auto VerticalResolution = BitRange<GPU_IO::VerticalResolution>::from_to(2, 2);
static constexpr auto HorizontalResolution = BitRange<GPU_IO::HorizontalResolution>::from_to(0, 1);
static constexpr uint32_t PAL() {
return ComplexBitMap<uint32_t>::with(
Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240),
Mode::VideoMode.with(TVEncoding::PAL),
Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
).raw;
}
static constexpr uint32_t NTSC() {
return ComplexBitMap<uint32_t>::with(
Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240),
Mode::VideoMode.with(TVEncoding::NTSC),
Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
).raw;
}
};
static void configurate() {
static constexpr uint16_t FirstVisiblePixelH = 0x260;
#ifdef JABYENGINE_PAL
static constexpr uint16_t FirstVisiblePixelV = 0xA3;
GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::PAL()));
GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL());
GPU::Screen::set_offset(0, 0);
#else
static constexpr uint16_t FirstVisiblePixelV = 0x88;
GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::NTSC()));
GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC());
GPU::Screen::set_offset(0, 5); //< Random values
#endif
}
@ -60,22 +28,22 @@ namespace JabyEngine {
};
static void set_draw_area(uint16_t x, uint16_t y) {
GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaTopLeft(x, y));
GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)));
GPU_IO::GP0 = *GPU_IO::Command::DrawAreaTopLeft(x, y);
GPU_IO::GP0 = *GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height));
}
static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) {
GPU_IO::GP0.write(GPU_IO::Command::GP0::QuickFill(color));
GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(pos.x, pos.y));
GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height));
GPU_IO::GP0 = *GPU_IO::Command::QuickFill(color);
GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(pos.x, pos.y);
GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height);
}
static void reset_cmd_buffer() {
GPU_IO::GP1.write(GPU_IO::Command::GP1::ResetCMDBufer());
GPU_IO::GP1 = *GPU_IO::Command::ResetCMDBufer();
}
static void wait_ready_for_CMD() {
while(!GPU_IO::GPUSTAT.read().is(GPU_IO::GPUStatusRegister::GP0ReadyForCMD));
while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD));
}
namespace DMA {
@ -88,9 +56,8 @@ namespace JabyEngine {
}
namespace Receive {
static void prepare()
{
GPU_IO::GP1.write(GPU_IO::Command::GP1::DMADirection(GPU_IO::DMADirection::CPU2GPU));
static void prepare() {
GPU_IO::GP1 = *GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU);
reset_cmd_buffer();
}
@ -100,9 +67,9 @@ namespace JabyEngine {
static void set_dst(const PositionU16& position, const SizeU16& size) {
wait_ready_for_CMD();
GPU_IO::GP0.write(GPU_IO::Command::GP0::CPU2VRAM_Blitting());
GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(position.x, position.y));
GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height));
GPU_IO::GP0 = *GPU_IO::Command::CPU2VRAM_Blitting();
GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(position.x, position.y);
GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height);
}
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) {

View File

@ -49,7 +49,7 @@ namespace JabyEngine {
}
void setup() {
GPU_IO::GP1.write(GPU_IO::Command::GP1::Reset());
GPU_IO::GP1 = *GPU_IO::Command::Reset();
internal::Screen::configurate();
internal::Screen::exchange_buffer_and_display();

View File

@ -16,7 +16,7 @@ namespace JabyEngine {
void Screen :: exchange_buffer_and_display() {
GPU::internal::set_draw_area(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID));
PublicScreenClass::CurrentDisplayAreaID ^= 1;
GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)));
GPU_IO::GP1 = *GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID));
}
}
@ -25,13 +25,13 @@ namespace JabyEngine {
x += 78;
y += 43;
GPU_IO::GP1.write(GPU_IO::Command::GP1::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3));
GPU_IO::GP1.write(GPU_IO::Command::GP1::VerticalDisplayRange(y, y + Display::Height));
GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3);
GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height);
}
#else
void Screen :: set_offset(uint16_t x, uint16_t y) {
GP1.write(Command::GP1::HorizontalDisplayRange(x, (x + Display::Width*8)));
GP1.write(Command::GP1::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)));
GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8));
GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2));
}
#endif //USE_NO$PSX
}