summaryrefslogtreecommitdiff
path: root/source/util.hpp
diff options
context:
space:
mode:
authorDaniel Hader <[email protected]>2026-08-28 21:27:29 -0500
committerDaniel Hader <[email protected]>2026-08-28 21:27:29 -0500
commit0f383adcdc02cad8dfb435ce73c1fe1c0c4b5bd6 (patch)
tree917569ca76e2160595f071c0c07834e3244ff6cd /source/util.hpp
parent77e153f99cb279c1deb5b257fb54c7fdbdd4bc19 (diff)
sprite proof of concept and improved display control bit flaggingHEADmain
Diffstat (limited to 'source/util.hpp')
-rw-r--r--source/util.hpp127
1 files changed, 116 insertions, 11 deletions
diff --git a/source/util.hpp b/source/util.hpp
index 88a29ca..c034fe5 100644
--- a/source/util.hpp
+++ b/source/util.hpp
@@ -24,18 +24,40 @@ enum DisplayControlLayer : u16 {
BG1 = 0x0200,
BG2 = 0x0400,
BG3 = 0x0800,
- BG4 = 0x1000,
+ Obj = 0x1000,
};
-typedef u16 DisplayControlFlags;
+struct DisplayControlFlags {
+ u16 data;
-constexpr DisplayControlFlags operator|(DisplayControlMode mode, DisplayControlLayer layer) {
- return static_cast<DisplayControlFlags>(static_cast<u16>(mode) | static_cast<u16>(layer));
-}
+ enum Layer : u16 {
+ BG0 = 0x0100,
+ BG1 = 0x0200,
+ BG2 = 0x0400,
+ BG3 = 0x0800,
+ Obj = 0x1000,
+ };
+
+ constexpr DisplayControlFlags() : data(0) {}
+ constexpr DisplayControlFlags &set_mode(u16 mode) {
+ assert(mode < 6);
+ this->data = (this->data & ~0x0007) | mode;
+ return *this;
+ }
+ constexpr DisplayControlFlags &enable_layer(u16 layer) {
+ this->data |= layer;
+ return *this;
+ }
+ constexpr DisplayControlFlags &set_1d_object_mapping(u16 enabled) {
+ this->data = (this->data & ~0x0040) | ((!!enabled) << 6);
+ return *this;
+ }
+ constexpr operator u16() const { return data; }
+};
-static inline void set_display_control(DisplayControlMode mode, DisplayControlLayer layer) {
- static volatile DisplayControlFlags* const display_control = reinterpret_cast<DisplayControlFlags*>(0x04000000);
- *display_control = mode | layer;
+static inline void set_display_control(const DisplayControlFlags &flags) {
+ static volatile u16* const display_control = reinterpret_cast<volatile u16*>(0x04000000);
+ *display_control = flags;
}
enum BGControlColorMode : u16 {
@@ -134,9 +156,9 @@ struct ScreenEntry {
constexpr ScreenEntry() : data(0) {}
- constexpr ScreenEntry &set_tile_index(u16 tid) {
- assert(tid < 1024);
- this->data = (this->data & ~0x03ff) | tid;
+ constexpr ScreenEntry &set_tile_index(u16 index) {
+ assert(index < 1024);
+ this->data = (this->data & ~0x03ff) | index;
return *this;
}
@@ -161,6 +183,80 @@ struct ScreenEntry {
typedef ScreenEntry ScreenBlock[1024];
+struct ObjectAttributes {
+ u16 attr0, attr1, attr2, _fill;
+
+ enum ObjectMode : u16 {
+ ModeDefault = 0x0000,
+ ModeHidden = 0x0020,
+ ModeAffine = 0x0010,
+ ModeDouble = 0x0030,
+ };
+
+ enum GraphicsMode : u16 {
+ GraphicsDefault = 0x0000,
+ GraphicsBlend = 0x0400,
+ GraphicsWindow = 0x0800,
+ };
+
+ enum Size : u16 {
+ Size_8x8 = 0x0000,
+ Size_16x16 = 0x0001,
+ Size_32x32 = 0x0002,
+ Size_64x64 = 0x0003,
+ Size_16x8 = 0x0100,
+ Size_32x8 = 0x0101,
+ Size_32x16 = 0x0102,
+ Size_32x64 = 0x0103,
+ Size_8x16 = 0x0200,
+ Size_8x32 = 0x0201,
+ Size_16x32 = 0x0202,
+ Size_64x32 = 0x0203,
+ };
+
+ constexpr ObjectAttributes() : attr0(0), attr1(0), attr2(0), _fill(0) {}
+
+ constexpr ObjectAttributes &set_x(u16 x) {
+ assert(x < 256);
+ this->attr1 = (this->attr1 & ~0x000f) | x;
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_y(u16 y) {
+ assert(y < 256);
+ this->attr0 = (this->attr0 & ~0x000f) | y;
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_object_mode(ObjectMode mode) {
+ this->attr0 = (this->attr0 & ~0x0030) | mode;
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_graphics_mode(GraphicsMode mode) {
+ this->attr0 = (this->attr0 & ~0x00c0) | mode;
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_size(Size size) {
+ this->attr0 = (this->attr0 & ~0xc000) | ((size & 0x0300) << 6);
+ this->attr1 = (this->attr1 & ~0xc000) | ((size & 0x0003) << 14);
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_tile_index(u16 index) {
+ assert(index < 1024);
+ this->attr2 = (this->attr2 & ~0x003f) | index;
+ return *this;
+ }
+
+ constexpr ObjectAttributes &set_palette_bank(u16 bank) {
+ assert(bank < 16);
+ this->attr2 = (this->attr2 & ~0xf000) | (bank << 12);
+ return *this;
+ }
+};
+
template <typename T>
static inline void volatile_copy(volatile T* dst, const T* src) {
using U = std::conditional_t<(sizeof(T) % sizeof(u32) == 0) && (alignof(T) % alignof(u32) == 0), u32, u16>;
@@ -184,10 +280,19 @@ static inline void set_bg_palette(u32 bank, u32 index, const Color &color) {
volatile_copy(&banks[bank][index], &color);
}
+static inline void set_obj_palette(u32 bank, u32 index, const Color &color) {
+ volatile PaletteBank *const banks = reinterpret_cast<volatile PaletteBank*>(0x05000200);
+ volatile_copy(&banks[bank][index], &color);
+}
static inline void set_screen_entry(u32 block, u32 index, const ScreenEntry &entry) {
volatile ScreenBlock *const blocks = reinterpret_cast<volatile ScreenBlock*>(0x06000000);
volatile_copy(&blocks[block][index], &entry);
}
+static inline void set_obj_attributes(u32 index, const ObjectAttributes &attr) {
+ volatile ObjectAttributes *const attrs = reinterpret_cast<volatile ObjectAttributes*>(0x07000000);
+ volatile_copy(&attrs[index], &attr);
+}
+
#endif