diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/main.cpp | 29 | ||||
| -rw-r--r-- | source/util.hpp | 127 |
2 files changed, 144 insertions, 12 deletions
diff --git a/source/main.cpp b/source/main.cpp index 21d1c26..116094c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -8,6 +8,7 @@ void bad_vsync() { } int main() { + // background control auto bg_flags = BGControlFlags() .set_charblock_base(0) .set_screenblock_base(28) @@ -16,6 +17,7 @@ int main() { set_bg_control(0, bg_flags); set_bg_offsets(0, 0, 0); + // background tiles const Tile4 tiles[2] = { {{0x11111111, 0x01111111, 0x01111111, 0x01111111, 0x01111111, 0x01111111, 0x01111111, 0x00000001}}, {{0x00000000, 0x00100100, 0x01100110, 0x00011000, 0x00011000, 0x01100110, 0x00100100, 0x00000000}}, @@ -24,11 +26,13 @@ int main() { set_tile(0, 0, tiles[0]); set_tile(0, 1, tiles[1]); + // background tiles set_bg_palette(0, 1, Color::from_rgb(31, 0, 0)); set_bg_palette(1, 1, Color::from_rgb( 0, 31, 0)); set_bg_palette(2, 1, Color::from_rgb( 0, 0, 31)); set_bg_palette(3, 1, Color::from_rgb(16, 16, 16)); + // background screen entries for (int i = 0; i < 4; i++) { for (int j = 0; j < 32*32; j++) { auto screen_entry = ScreenEntry() @@ -38,7 +42,30 @@ int main() { } } - set_display_control(Mode0, BG0); + // object palettes + set_obj_palette(0, 1, Color::from_rgb(0, 0, 0)); + set_obj_palette(0, 2, Color::from_rgb(31, 31, 0)); + + // object attributes + auto obj_attr = ObjectAttributes() + .set_size(ObjectAttributes::Size_16x16) + .set_tile_index(0) + .set_palette_bank(0) + .set_x(50).set_y(50); + + set_obj_attributes(0, obj_attr); + + Tile4 obj_tile = {0x01230123, 0x01230123, 0x01230123, 0x01230123, 0x01230123, 0x01230123, 0x01230123, 0x01230123}; + for (u32 i = 0; i < 4; i++) { + set_tile(4, i, obj_tile); + } + + auto display_control_flags = DisplayControlFlags() + .set_mode(0) + .enable_layer(BG0) + .enable_layer(Obj) + .set_1d_object_mapping(1); + set_display_control(display_control_flags); s16 x = 0, y = 0; while (1) { 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 |
