summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-06-20 22:41:50 -0400
committerPaul Duncan <pabs@pablotron.org>2018-06-20 22:41:50 -0400
commitb9d24e00470c2538aa55e36833a7b89cdfcd9494 (patch)
tree8b18f51a46b0749e34a9f7a13434fdc347f22cca
parent7f7395f6a9429eb771fdc52742ee4d44ea0734ba (diff)
downloadgb-c-b9d24e00470c2538aa55e36833a7b89cdfcd9494.tar.bz2
gb-c-b9d24e00470c2538aa55e36833a7b89cdfcd9494.zip
populate gpu_draw()
-rw-r--r--ops.yaml77
1 files changed, 75 insertions, 2 deletions
diff --git a/ops.yaml b/ops.yaml
index 0b6a42e..30c0c64 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -7523,6 +7523,7 @@ templates:
#include "gb.h"
#define UNUSED(a) ((void) (a))
+ #define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define FLAG(ctx, f) (cpu_rb(ctx, RB_F) & (F_##f))
#define F_Z (1 << 7)
@@ -9387,8 +9388,80 @@ templates:
gpu_draw(
gb_t * const ctx
) {
- UNUSED(ctx);
- // TODO
+ struct {
+ uint8_t x, y, tile;
+ bool priority,
+ y_flip,
+ x_flip,
+ palette;
+ } objs[40];
+
+ // decode oam
+ for (int i = 0; i < 40; i++) {
+ objs[i].y = (ctx->mmu.oam[i * 4 + 0] + 16) & 0xFF;
+ objs[i].x = (ctx->mmu.oam[i * 4 + 1] + 8) & 0xFF;
+ objs[i].tile = ctx->mmu.oam[i * 4 + 2];
+
+ const uint8_t flags = ctx->mmu.oam[i * 4 + 3];
+ objs[i].priority = flags & (1 << 7);
+ objs[i].y_flip = flags & (1 << 6);
+ objs[i].x_flip = flags & (1 << 5);
+ objs[i].palette = flags & (1 << 4);
+ }
+
+ // draw sprites behind bg
+ for (int i = 0; i < 40; i++) {
+ if (
+ // sprite is below bg
+ objs[i].priority &&
+
+ // sprite is on screen
+ objs[i].y < 144 && objs[i].x < 160 &&
+
+ // sprite is on current line
+ ctx->gpu.line >= objs[i].y &&
+ ctx->gpu.line <= objs[i].y
+ ) {
+ const uint8_t max_j = MIN(8, 160 - objs[i].x);
+
+ for (uint8_t j = 0; j < max_j; j++) {
+ const uint32_t ofs = 3 * (objs[i].y * 160 + objs[i].x + j);
+
+ // TODO: draw sprite scanline
+ ctx->gpu.rgb[ofs + 0] = 0xff;
+ ctx->gpu.rgb[ofs + 1] = 0xff;
+ ctx->gpu.rgb[ofs + 2] = 0xff;
+ }
+ }
+ }
+
+ // TODO: draw background
+
+ // draw foreground sprites
+ for (int i = 0; i < 40; i++) {
+ if (
+ // sprite is above bg
+ !objs[i].priority &&
+
+ // sprite is on screen
+ objs[i].y < 144 && objs[i].x < 160 &&
+
+ // sprite is on current line
+ ctx->gpu.line >= objs[i].y &&
+ ctx->gpu.line <= objs[i].y
+ ) {
+ const uint8_t max_j = MIN(8, 160 - objs[i].x);
+
+ for (int j = 0; j < max_j; j++) {
+ const uint32_t ofs = 3 * (objs[i].y * 160 + objs[i].x + j);
+
+ // TODO: draw sprite scanline
+ ctx->gpu.rgb[ofs + 0] = 0xff;
+ ctx->gpu.rgb[ofs + 1] = 0xff;
+ ctx->gpu.rgb[ofs + 2] = 0xff;
+ }
+ }
+ }
}
static void