From 37e72d68fe6fbbdc211a6ef2b7756877e31e8061 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 15 Apr 2021 17:24:25 +0200 Subject: Add initial Mode4 tests, copied from the TONC tutorial --- src/main.c | 59 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main.c b/src/main.c index 1596ba4..cbfa2a7 100644 --- a/src/main.c +++ b/src/main.c @@ -61,6 +61,7 @@ typedef u16 Color; typedef Color Scanline[SCREEN_WIDTH]; #define FRAMEBUFFER ((Scanline*)MEM_VRAM) #define SCREEN_BUFFER ((vu16*) MEM_VRAM) +#define PAL_BUFFER ((vu16*) MEM_PAL) // // Colors. @@ -227,39 +228,41 @@ wait_vsync() { // Main functions. // -int main(void) { - set_display_mode(DISP_MODE_3 | DISP_BG2); +// In Mode4 the buffer is of 8 bytes per pixel instead of 16. We can't write the +// color directly, instead the color is stored in the palette memory at +// `MEM_PAL`. Note that in this mode MEM_PAL[0] is the background color. This +// plotter takes an index to a color stored in MEM_PAL[col_index]. Because the +// GBA needs to meet memory alignment requirements, we can't write a u8 into +// memory, instead we need to read a u16 word, mask and or the corresponding +// bits and wave the updated u16. +static inline void +put_pixel_m4(int x, int y, u8 col_index) { + int buffer_index = (y * SCREEN_WIDTH + x) / 2; + u16 *destination = &SCREEN_BUFFER[buffer_index]; + int odd = x & 0x1; + if(odd) { + *destination= (*destination & 0xFF) | (col_index << 8); + } else { + *destination= (*destination & ~0xFF) | col_index; + } +} - // Draw a grid pattern. - for (int j = 30; j < SCREEN_HEIGHT - 30; j += 8) { - for (int i = 30; i < 50; i += 8) { - draw_rect(i, j, 0 + i + 8, j + 8, COLOR_RED); +static inline void +draw_fill_rect_m4(int x0, int y0, int x1, int y1, u8 col_index) { + int ix, iy; + for(iy = y0; iy < y1; iy++) { + for(ix = x0; ix < x1; ix++) { + put_pixel_m4(ix, iy, col_index); } } +} - // Draw the text line. - for (int i = 0; i < SCREEN_WIDTH; i += 8) { - draw_fill_rect(i, 7, 0 + i + 7, 16, COLOR_RED); - } - put_text(8, 8, COLOR_BLACK, "Testing other patterns"); +int main(void) { + set_display_mode(DISP_MODE_4 | DISP_BG2); - // Test line drawings. - draw_fill_rect(69, 29, SCREEN_WIDTH - 69, SCREEN_HEIGHT - 29, COLOR_BLACK); - int step = 10; - for (int k = 0; k < (SCREEN_WIDTH - 70 - 70) / step; k++) { - int x0 = 70; - int y0 = 30 + k * step; - int x1 = x0 + k * step + step; - int y1 = SCREEN_HEIGHT - 30; - draw_line(x0, y0, x1, y1, COLOR_BLUE); - } - for (int k = 0; k < (SCREEN_WIDTH - 70 - 70) / step; k++) { - int x0 = 70 + k * step; - int y0 = 30; - int x1 = SCREEN_WIDTH - 70; - int y1 = y0 + k * step + step; - draw_line(x0, y0, x1, y1, COLOR_RED); - } + PAL_BUFFER[1] = COLOR_RED; + PAL_BUFFER[2] = COLOR_BLUE; + draw_fill_rect_m4(0, 0, 20, 20, 1); while(true) { wait_vsync(); -- cgit v1.2.1