diff options
-rw-r--r-- | CHANGELOG.txt | 10 | ||||
-rw-r--r-- | README.html | 31 | ||||
-rw-r--r-- | agbx/GNUmakefile | 2 | ||||
-rw-r--r-- | agbx/include/agbx/gfx.h | 13 | ||||
-rw-r--r-- | agbx/source/bs/done.c | 2 | ||||
-rw-r--r-- | agbx/source/gfx/getpx.c | 19 | ||||
-rw-r--r-- | agbx/source/gfx/getvbnk.s | 2 | ||||
-rw-r--r-- | agbx/source/gfx/plot.c | 11 | ||||
-rw-r--r-- | agbx/source/gfx/rd.c | 24 | ||||
-rw-r--r-- | demo/GNUmakefile | 8 | ||||
-rw-r--r-- | demo/demo.c | 81 | ||||
-rw-r--r-- | demo/include/agbx-demo.h | 33 | ||||
-rw-r--r-- | demo/source/chgcol.c | 17 | ||||
-rw-r--r-- | demo/source/chkkeys.c | 64 | ||||
-rw-r--r-- | demo/source/initdat.c | 10 | ||||
-rw-r--r-- | demo/source/initgfx.c | 17 | ||||
-rw-r--r-- | demo/source/loop.c | 29 | ||||
-rw-r--r-- | demo/source/main.c | 18 |
18 files changed, 297 insertions, 94 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1fe72cf..31611c6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,13 @@ +# 4.0 + +* Restructure demo; +* Make flip and getvbnk return the address of the other bank; +* Add functions for getting the value of a pixel (getpx); +* Add functions for reading a colour value (rd); +* Remove return value from plot; +* Update readme; +* Fix plot5; + # 3.0 * Add function for getting the current video bank (getvbnk); diff --git a/README.html b/README.html index 3d94aef..9a2e405 100644 --- a/README.html +++ b/README.html @@ -2,6 +2,37 @@ <html> <h1>AGBx</h1> <p>Framework for development on the Game Boy Advance.</p> + <br /> + <p>Controls for the demo:</p> + <ul> + <li> + <p>A: Colour the current pixel;</p> + </li> + <li> + <p>+CONTROL PAD (UP): Move one pixel up on the canvas;</p> + </li> + <li> + <p>+CONTROL PAD (RIGHT): Move one pixel to the right on the canvas;</p> + </li> + <li> + <p>+CONTROL PAD (DOWN): Move one pixel down on the canvas;</p> + </li> + <li> + <p>+CONTROL PAD (LEFT): Move one pixel to the left on the canvas;</p> + </li> + <li> + <p>R: Rotate the palette counterclockwise;</p> + </li> + <li> + <p>L: Rotate the palette clockwise;</p> + </li> + <li> + <p>START: Exit the demo;</p> + </li> + <li> + <p>SELECT: Exit the demo (whilst indicating error);</p> + </li> + </ul> <h2>Building</h2> <p>As the Game Boy Advance uses an ARM (ARM7TDMI) processor, AGBx requires an ARM cross-compiler.</p> <p>For GCC, the appropriate package is <i>arm-none-eabi-gcc</i> on Arch Linux and <i>gcc-arm-none-eabi</i> on Debian. Clang supports supports cross-compilation by default, and this platform can be set via the <i>--target=arm-none-eabi</i> option.</p> diff --git a/agbx/GNUmakefile b/agbx/GNUmakefile index 0265379..afd8f50 100644 --- a/agbx/GNUmakefile +++ b/agbx/GNUmakefile @@ -43,8 +43,10 @@ OBJS := \ source/bs/set.o \ source/gfx/clrscrn.o \ source/gfx/flip.o \ + source/gfx/getpx.o \ source/gfx/getvbnk.o \ source/gfx/plot.o \ + source/gfx/rd.o \ source/gfx/setpx.o \ source/gfx/vsync.o \ source/key/getkeymap.o \ diff --git a/agbx/include/agbx/gfx.h b/agbx/include/agbx/gfx.h index 2da8974..beec93b 100644 --- a/agbx/include/agbx/gfx.h +++ b/agbx/include/agbx/gfx.h @@ -16,12 +16,19 @@ void agbx_vsync( void); void agbx_setpx1(agbx_i20 vaddr,agbx_i10 px,agbx_i8 col); void agbx_setpx2(agbx_i20 vaddr,agbx_i10 px,agbx_i10 col); +agbx_i8 agbx_getpx1(agbx_i20 vaddr,agbx_i10 px); +agbx_i10 agbx_getpx2(agbx_i20 vaddr,agbx_i10 px); + void agbx_clrscrn3(agbx_i10 col); void agbx_clrscrn4(agbx_i20 vaddr,agbx_i8 col); void agbx_clrscrn5(agbx_i20 vaddr,agbx_i10 col); -agbx_i10 agbx_plot3(agbx_i8 x,agbx_i8 y,agbx_i10 col); -agbx_i10 agbx_plot4(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y,agbx_i8 col); -agbx_i10 agbx_plot5(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y,agbx_i10 col); +void agbx_plot3(agbx_i8 x, agbx_i8 y,agbx_i10 col); +void agbx_plot4(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y, agbx_i8 col); +void agbx_plot5(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y, agbx_i10 col); + +agbx_i10 agbx_rd3(agbx_i8 x, agbx_i8 y); +agbx_i8 agbx_rd4(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y); +agbx_i10 agbx_rd5(agbx_i20 vaddr,agbx_i8 x,agbx_i8 y); #endif diff --git a/agbx/source/bs/done.c b/agbx/source/bs/done.c index 8e3726d..64130e3 100644 --- a/agbx/source/bs/done.c +++ b/agbx/source/bs/done.c @@ -18,7 +18,7 @@ void agbx_done(agbx_err const _err) { /* Display the barcode-like error message: */ agbx_set10(0x400'0000u,0x404u); agbx_set10(0x500'0000u,0x0u); - agbx_set10(0x500'0002u,0x19u); + agbx_set10(0x500'0002u,0b11111u); agbx_i8 err[0xBu]; for (agbx_i8 pos = 0x0u;pos != 0x8u;++pos) {err[pos] = (agbx_i8)_err >> pos & 0x1u;} err[0x8u] = 0x0u; diff --git a/agbx/source/gfx/getpx.c b/agbx/source/gfx/getpx.c new file mode 100644 index 0000000..5d24db4 --- /dev/null +++ b/agbx/source/gfx/getpx.c @@ -0,0 +1,19 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <agbx/priv.h> + +#include <agbx/gfx.h> + +agbx_i8 agbx_getpx1(agbx_i20 const _vaddr,agbx_i10 const _px) { + agbx_i20 const addr = _vaddr + _px; + return __agbx_get8(addr); +} + +agbx_i10 agbx_getpx2(agbx_i20 const _vaddr,agbx_i10 const _px) { + agbx_i20 const addr = _vaddr + _px * 0x2u; + return __agbx_get8(addr); +} diff --git a/agbx/source/gfx/getvbnk.s b/agbx/source/gfx/getvbnk.s index e04a127..6898266 100644 --- a/agbx/source/gfx/getvbnk.s +++ b/agbx/source/gfx/getvbnk.s @@ -35,7 +35,7 @@ __agbx_getvbnk: @ Takes the value of dispcnt in r1. movs r0,0b10000 tst r1,r0 - bne .vbnk1 + beq .vbnk1 .vbnk0: @ Return the address of the first video bank: diff --git a/agbx/source/gfx/plot.c b/agbx/source/gfx/plot.c index e23834c..a19a2f1 100644 --- a/agbx/source/gfx/plot.c +++ b/agbx/source/gfx/plot.c @@ -8,20 +8,17 @@ #include <agbx/gfx.h> -agbx_i10 agbx_plot3(agbx_i8 const _x,agbx_i8 const _y,agbx_i10 const _col) { +void agbx_plot3(agbx_i8 const _x,agbx_i8 const _y,agbx_i10 const _col) { agbx_i10 const px = _y * 0xF0u + _x; __agbx_setpx2(0x600'0000u,px,_col) - return px; } -agbx_i10 agbx_plot4(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y,agbx_i8 const _col) { +void agbx_plot4(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y,agbx_i8 const _col) { agbx_i10 const px = _y * 0xF0u + _x; agbx_setpx1(_vaddr,px,_col); - return px; } -agbx_i10 agbx_plot5(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y,agbx_i10 const _col) { - agbx_i10 const px = _y * 0xF0u + _x; +void agbx_plot5(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y,agbx_i10 const _col) { + agbx_i10 const px = _y * 0xA0u + _x; __agbx_setpx2(_vaddr,px,_col) - return px; } diff --git a/agbx/source/gfx/rd.c b/agbx/source/gfx/rd.c new file mode 100644 index 0000000..94dd676 --- /dev/null +++ b/agbx/source/gfx/rd.c @@ -0,0 +1,24 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <agbx/priv.h> + +#include <agbx/gfx.h> + +agbx_i10 agbx_rd3(agbx_i8 const _x,agbx_i8 const _y) { + agbx_i10 const px = _y * 0xF0u + _x; + return agbx_getpx2(0x600'0000u,px); +} + +agbx_i8 agbx_rd4(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y) { + agbx_i10 const px = _y * 0xF0u + _x; + return agbx_getpx1(_vaddr,px); +} + +agbx_i10 agbx_rd5(agbx_i20 const _vaddr,agbx_i8 const _x,agbx_i8 const _y) { + agbx_i10 const px = _y * 0xA0u + _x; + return agbx_getpx2(_vaddr,px); +} diff --git a/demo/GNUmakefile b/demo/GNUmakefile index 076b19f..aed29df 100644 --- a/demo/GNUmakefile +++ b/demo/GNUmakefile @@ -14,6 +14,7 @@ OBJCOPY := arm-none-eabi-objcopy CFLAGS := \ -I../agbx/include \ + -Iinclude \ -O3 \ -Wall \ -Wextra \ @@ -25,7 +26,12 @@ CFLAGS := \ # BINARIES OBJS := \ - demo.o + source/chkkeys.o \ + source/chgcol.o \ + source/initdat.o \ + source/initgfx.o \ + source/loop.o \ + source/main.o ROMHDR := hdr.o diff --git a/demo/demo.c b/demo/demo.c deleted file mode 100644 index 012e705..0000000 --- a/demo/demo.c +++ /dev/null @@ -1,81 +0,0 @@ -#include <agbx/key.h> -#include <agbx/gfx.h> - -agbx_err agbx_main(void) { - agbx_set10(0x500'0000u,0x0u); - agbx_set10(0x500'0002u,0x19u); - agbx_set10(0x500'0004u,0xFFFFu); - agbx_set10(0x400'0000u,0x404u); - agbx_clrscrn4(0x600'0000u,0x0u); - agbx_clrscrn4(0x600'A000u,0x0u); - agbx_i10 const cols[] = { - 0b11111u, - 0b1111100000u, - 0b111110000000000u, - }; - agbx_i8 col = 0x0u; - struct { - agbx_i8 x; - agbx_i8 y; - } pos = {.x = 0x0u,.y = 0x0u,}; - agbx_setpx1(0x600'0000u,0x0u,0x2u); - agbx_i20 vaddr = 0x600'0000u; - for (;;) { - agbx_vsync(); - agbx_keymap const keymap = agbx_getkeymap(); - if (agbx_chkkey(keymap,agbx_key_b)) { - return (agbx_err)(((agbx_i10)pos.x + (agbx_i10)pos.y)/0x2u); - } - if (agbx_chkkey(keymap,agbx_key_a)) { - return agbx_err_ok; - } - if (agbx_chkkey(keymap,agbx_key_l)) { - agbx_plot4(vaddr,pos.x,pos.y,0x1u); - vaddr = agbx_flip(); - agbx_plot4(vaddr,pos.x,pos.y,0x2u); - while (agbx_chkkey(agbx_getkeymap(),agbx_key_l)) {} - continue; - } - if (agbx_chkkey(keymap,agbx_key_r)) { - if (col == 0x2u) {col = 0x0u;} - else {++col;} - agbx_set10(0x500'0002u,cols[col]); - while (agbx_chkkey(agbx_getkeymap(),agbx_key_r)) {} - continue; - } - typeof (pos) const prevpos = pos; - agbx_key key = agbx_key_pade; - if (agbx_chkkey(keymap,key)) { - if (pos.x != 0xEFu) { - ++pos.x; - goto drw; - } - } - key = agbx_key_padn; - if (agbx_chkkey(keymap,key)) { - if (pos.y != 0x0u) { - --pos.y; - goto drw; - } - } - key = agbx_key_pads; - if (agbx_chkkey(keymap,key)) { - if (pos.y != 0x9Fu) { - ++pos.y; - goto drw; - } - } - key = agbx_key_padw; - if (agbx_chkkey(keymap,key)) { - if (pos.x != 0x0u) { - --pos.x; - goto drw; - } - } - continue; - drw:; - agbx_plot4(vaddr,prevpos.x,prevpos.y,0x1u); - agbx_plot4(vaddr,pos.x,pos.y,0x2u); - while (agbx_chkkey(agbx_getkeymap(),key)) {} - } -} diff --git a/demo/include/agbx-demo.h b/demo/include/agbx-demo.h new file mode 100644 index 0000000..2dc2313 --- /dev/null +++ b/demo/include/agbx-demo.h @@ -0,0 +1,33 @@ +#if !defined(agbxd_hdr) +#define agbxd_hdr + +#include <agbx/bs.h> + +typedef struct { + agbx_i8 x; + agbx_i8 y; +} agbxd_pos; + +typedef struct { + agbx_i8 col; + agbxd_pos pos; + agbx_i8 prevcol; + agbxd_pos prevpos; + agbx_i20 vaddr; +} agbxd_dat; + +typedef struct { + bool done; + bool err; + bool drw; + bool mv; +} agbxd_upd; + +agbxd_upd agbxd_chkkeys(agbxd_dat * dat); +void agbxd_chgcol( agbxd_dat * dat,agbx_i8 dir); +void agbxd_drw( agbxd_dat * dat); +void agbxd_initdat(agbxd_dat * dat); +void agbxd_initgfx(void); +bool agbxd_loop( agbxd_dat * dat); + +#endif diff --git a/demo/source/chgcol.c b/demo/source/chgcol.c new file mode 100644 index 0000000..cbd653e --- /dev/null +++ b/demo/source/chgcol.c @@ -0,0 +1,17 @@ +#include <agbx-demo.h> + +#include <agbx/gfx.h> + +void agbxd_chgcol(agbxd_dat * _dat,agbx_i8 const _dir) { + constexpr agbx_i8 maxcol = 0x7u; + agbx_i8 col = _dat->col; + if (!_dir) { + if (!col) {col = maxcol;} + else {--col;} + } + else { + if (col == maxcol) {col = 0x0u;} + else {++col;} + } + _dat->col = col; +} diff --git a/demo/source/chkkeys.c b/demo/source/chkkeys.c new file mode 100644 index 0000000..f117d09 --- /dev/null +++ b/demo/source/chkkeys.c @@ -0,0 +1,64 @@ +#include <agbx-demo.h> + +#include <agbx/key.h> +#include <agbx/gfx.h> + +#define agbxd_chk(_key) \ + curkey = _key; \ + if (agbx_chkkey(keymap,_key)) + +#define agbxd_wait() \ + while (agbx_chkkey(agbx_getkeymap(),curkey)) {} + +agbxd_upd agbxd_chkkeys(agbxd_dat * _dat) { + agbxd_upd upd = {}; + agbx_keymap const keymap = agbx_getkeymap(); + agbx_key curkey; + agbxd_chk(agbx_key_sel) { + upd.done = true; + upd.err = true; + return upd; + } + agbxd_chk(agbx_key_start) { + upd.done = true; + return upd; + } + agbxd_chk(agbx_key_l) { + agbxd_chgcol(_dat,0x0u); + agbxd_wait(); + } + agbxd_chk(agbx_key_r) { + agbxd_chgcol(_dat,0x1u); + agbxd_wait(); + } + agbxd_chk(agbx_key_pade) { + if (_dat->pos.x != 0xEFu) { + upd.mv = true; + ++_dat->pos.x; + agbxd_wait(); + } + } + agbxd_chk(agbx_key_padn) { + if (_dat->pos.y != 0x0u) { + upd.mv = true; + --_dat->pos.y; + agbxd_wait(); + } + } + agbxd_chk(agbx_key_pads) { + if (_dat->pos.y != 0x9Fu) { + upd.mv = true; + ++_dat->pos.y; + agbxd_wait(); + } + } + agbxd_chk(agbx_key_padw) { + if (_dat->pos.x != 0x0u) { + upd.mv = true; + --_dat->pos.x; + agbxd_wait(); + } + } + agbxd_chk(agbx_key_a) {upd.drw = true;} + return upd; +} diff --git a/demo/source/initdat.c b/demo/source/initdat.c new file mode 100644 index 0000000..c9bb7af --- /dev/null +++ b/demo/source/initdat.c @@ -0,0 +1,10 @@ +#include <agbx-demo.h> + +#include <agbx/gfx.h> + +void agbxd_initdat(agbxd_dat * const _dat) { + _dat->col = 0x2u; + _dat->pos.x = 0x0u; + _dat->pos.y = 0x0u; + _dat->vaddr = 0x600'0000u; +} diff --git a/demo/source/initgfx.c b/demo/source/initgfx.c new file mode 100644 index 0000000..474d5cd --- /dev/null +++ b/demo/source/initgfx.c @@ -0,0 +1,17 @@ +#include <agbx-demo.h> + +#include <agbx/gfx.h> + +void agbxd_initgfx(void) { + agbx_set10(0x500'0000u,0b0u); + agbx_set10(0x500'0002u,0b111111111111111u); + agbx_set10(0x500'0004u,0b11111u); + agbx_set10(0x500'0006u,0b1111111111u); + agbx_set10(0x500'0008u,0b1111100000u); + agbx_set10(0x500'000Au,0b111111111100000u); + agbx_set10(0x500'000Cu,0b111110000000000u); + agbx_set10(0x500'000Eu,0b111110000011111u); + agbx_set10(0x400'0000u,0x404u); + agbx_clrscrn4(0x600'0000u,0x0u); + agbx_clrscrn4(0x600'A000u,0x0u); +} diff --git a/demo/source/loop.c b/demo/source/loop.c new file mode 100644 index 0000000..003ac61 --- /dev/null +++ b/demo/source/loop.c @@ -0,0 +1,29 @@ +#include <agbx-demo.h> + +#include <agbx/key.h> +#include <agbx/gfx.h> + +bool agbxd_loop(agbxd_dat * const _dat) { + bool err = false; + _dat->prevcol = 0x0u; + agbx_plot4(_dat->vaddr,_dat->pos.x,_dat->pos.y,0x1u); + for (;;) { + _dat->prevpos = _dat->pos; + agbxd_upd const upd = agbxd_chkkeys(_dat); + if (upd.done) { + err = upd.err; + break; + } + agbx_vsync(); + if (upd.drw) { + _dat->prevcol = _dat->col; + if (upd.mv) {agbx_plot4(_dat->vaddr,_dat->pos.x,_dat->pos.y,_dat->col);} + } + if (upd.mv) { + agbx_plot4(_dat->vaddr,_dat->prevpos.x,_dat->prevpos.y,_dat->prevcol); + _dat->prevcol = agbx_rd4(_dat->vaddr,_dat->pos.x,_dat->pos.y); + agbx_plot4(_dat->vaddr,_dat->pos.x,_dat->pos.y,0x1u); + } + } + return err; +} diff --git a/demo/source/main.c b/demo/source/main.c new file mode 100644 index 0000000..fe75179 --- /dev/null +++ b/demo/source/main.c @@ -0,0 +1,18 @@ +#include <agbx-demo.h> + +#include <agbx/key.h> +#include <agbx/gfx.h> + +agbx_err agbx_main(void) { + agbxd_dat dat; + agbxd_initdat(&dat); + agbxd_initgfx(); + bool const err = agbxd_loop(&dat); + if (err) { + for (agbx_i10 px = 0x0u;px != 0x9600u;++px) { + agbx_setpx1(dat.vaddr,px,dat.col); + agbxd_chgcol(&dat,0x1u); + } + } + return err ? agbx_err_max : agbx_err_ok; +} |