diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-19 12:13:29 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-19 12:13:29 +0200 |
commit | 9873680f9d24e30afc1962987fac2c3ad1612f7b (patch) | |
tree | 5135bd3bd1d0e41c8725d51c7a56c1b0a1e2f904 /src/uxn | |
parent | a2f89131491a4cf7914becfd98d277544d26579a (diff) | |
download | uxngba-9873680f9d24e30afc1962987fac2c3ad1612f7b.tar.gz uxngba-9873680f9d24e30afc1962987fac2c3ad1612f7b.zip |
Update screen rendering to use 2 backgrounds
Diffstat (limited to 'src/uxn')
-rw-r--r-- | src/uxn/devices/ppu.c | 224 | ||||
-rw-r--r-- | src/uxn/devices/ppu.h | 10 |
2 files changed, 101 insertions, 133 deletions
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c index 06d84bf..5894352 100644 --- a/src/uxn/devices/ppu.c +++ b/src/uxn/devices/ppu.c | |||
@@ -3,6 +3,8 @@ | |||
3 | /* | 3 | /* |
4 | Copyright (c) 2021 Devine Lu Linvega | 4 | Copyright (c) 2021 Devine Lu Linvega |
5 | Copyright (c) 2021 Andrew Alderwick | 5 | Copyright (c) 2021 Andrew Alderwick |
6 | Copyright (c) 2021 Adrian "asie" Siekierka | ||
7 | Copyright (c) 2021 Bad Diode | ||
6 | 8 | ||
7 | Permission to use, copy, modify, and distribute this software for any | 9 | Permission to use, copy, modify, and distribute this software for any |
8 | purpose with or without fee is hereby granted, provided that the above | 10 | purpose with or without fee is hereby granted, provided that the above |
@@ -13,149 +15,115 @@ WITH REGARD TO THIS SOFTWARE. | |||
13 | */ | 15 | */ |
14 | 16 | ||
15 | static Uint8 font[][8] = { | 17 | static Uint8 font[][8] = { |
16 | {0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c}, | 18 | {0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c}, |
17 | {0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, | 19 | {0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, |
18 | {0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe}, | 20 | {0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe}, |
19 | {0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02, 0x82, 0x7c}, | 21 | {0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02, 0x82, 0x7c}, |
20 | {0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04}, | 22 | {0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04}, |
21 | {0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02, 0x82, 0x7c}, | 23 | {0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02, 0x82, 0x7c}, |
22 | {0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c}, | 24 | {0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c}, |
23 | {0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, 0x02}, | 25 | {0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, 0x02}, |
24 | {0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c}, | 26 | {0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c}, |
25 | {0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02, 0x82, 0x7c}, | 27 | {0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02, 0x82, 0x7c}, |
26 | {0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e}, | 28 | {0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e}, |
27 | {0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc}, | 29 | {0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc}, |
28 | {0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c}, | 30 | {0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c}, |
29 | {0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc}, | 31 | {0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc}, |
30 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, | 32 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, |
31 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; | 33 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; |
32 | |||
33 | Uint8 | ||
34 | readpixel(Uint8 *sprite, Uint8 h, Uint8 v) | ||
35 | { | ||
36 | Uint8 ch1 = ((sprite[v] >> h) & 0x1); | ||
37 | Uint8 ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); | ||
38 | return ch1 + ch2; | ||
39 | } | ||
40 | 34 | ||
41 | void | 35 | void |
42 | clear(Ppu *p) | 36 | putcolors(Ppu *p, Uint8 *addr) { |
43 | { | 37 | int i; |
44 | int i, sz = p->height * p->width, rows = sz / 4; | 38 | for(i = 0; i < 4; ++i) { |
45 | for(i = 0; i < sz; ++i) | 39 | Uint8 |
46 | p->output[i] = p->colors[0]; | 40 | r = (*(addr + i / 2) >> (!(i % 2) << 2)) & 0x0f, |
47 | for(i = 0; i < rows; i++) { | 41 | g = (*(addr + 2 + i / 2) >> (!(i % 2) << 2)) & 0x0f, |
48 | p->fg[i] = 0; | 42 | b = (*(addr + 4 + i / 2) >> (!(i % 2) << 2)) & 0x0f; |
49 | p->bg[i] = 0; | 43 | PAL_BUFFER_BG[i] = rgb15( |
50 | } | 44 | (r << 1) | (r >> 3), |
45 | (g << 1) | (g >> 3), | ||
46 | (b << 1) | (b >> 3)); | ||
47 | } | ||
51 | } | 48 | } |
52 | 49 | ||
53 | void | 50 | void |
54 | putcolors(Ppu *p, Uint8 *addr) | 51 | putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color) { |
55 | { | 52 | if(x >= 30 * 8 || y >= 20 * 8) |
56 | int i; | 53 | return; |
57 | for(i = 0; i < 4; ++i) { | ||
58 | Uint8 | ||
59 | r = (*(addr + i / 2) >> (!(i % 2) << 2)) & 0x0f, | ||
60 | g = (*(addr + 2 + i / 2) >> (!(i % 2) << 2)) & 0x0f, | ||
61 | b = (*(addr + 4 + i / 2) >> (!(i % 2) << 2)) & 0x0f; | ||
62 | p->colors[i] = rgb15(r,g,b); | ||
63 | } | ||
64 | // p->colors[0] = COLOR_BLUE; | ||
65 | // p->colors[1] = COLOR_WHITE; | ||
66 | // p->colors[2] = COLOR_RED; | ||
67 | // p->colors[3] = COLOR_CYAN; | ||
68 | } | ||
69 | 54 | ||
70 | void | 55 | Uint32 pos = ((y & 7) + (((x >> 3) + (y >> 3) * 30) * 8)); |
71 | putpixel(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 color) | 56 | Uint32 shift = (x & 7) << 2; |
72 | { | 57 | layer[pos] = (layer[pos] & (~(0xF << shift))) | (color << shift); |
73 | Uint16 row = (y % 8) + ((x / 8 + y / 8 * p->hor) * 16), col = 7 - (x % 8); | ||
74 | if(x >= p->hor * 8 || y >= p->ver * 8 || row > (p->hor * p->ver * 16) - 8) | ||
75 | return; | ||
76 | if(color == 0 || color == 2) | ||
77 | layer[row] &= ~(1UL << col); | ||
78 | else | ||
79 | layer[row] |= 1UL << col; | ||
80 | if(color == 0 || color == 1) | ||
81 | layer[row + 8] &= ~(1UL << col); | ||
82 | else | ||
83 | layer[row + 8] |= 1UL << col; | ||
84 | } | 58 | } |
85 | 59 | ||
86 | void | 60 | void |
87 | puticn(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) | 61 | puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) { |
88 | { | 62 | Uint16 v, h; |
89 | Uint16 v, h; | 63 | for(v = 0; v < 8; v++) |
90 | for(v = 0; v < 8; v++) | 64 | for(h = 0; h < 8; h++) { |
91 | for(h = 0; h < 8; h++) { | 65 | Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); |
92 | Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); | 66 | if(ch1 == 1 || (color != 0x05 && color != 0x0a && color != 0x0f)) |
93 | if(ch1 == 1 || (color != 0x05 && color != 0x0a && color != 0x0f)) | 67 | putpixel(p, |
94 | putpixel(p, | 68 | layer, |
95 | layer, | 69 | x + (flipx ? 7 - h : h), |
96 | x + (flipx ? 7 - h : h), | 70 | y + (flipy ? 7 - v : v), |
97 | y + (flipy ? 7 - v : v), | 71 | ch1 ? color % 4 : color / 4); |
98 | ch1 ? color % 4 : color / 4); | 72 | } |
99 | } | ||
100 | } | 73 | } |
101 | 74 | ||
102 | void | 75 | void |
103 | putchr(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) | 76 | putchr(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) { |
104 | { | 77 | Uint16 v, h; |
105 | Uint16 v, h; | 78 | for(v = 0; v < 8; v++) |
106 | for(v = 0; v < 8; v++) | 79 | for(h = 0; h < 8; h++) { |
107 | for(h = 0; h < 8; h++) { | 80 | Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1) * color; |
108 | Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1) * color; | 81 | Uint8 ch2 = ((sprite[v + 8] >> (7 - h)) & 0x1) * color; |
109 | Uint8 ch2 = ((sprite[v + 8] >> (7 - h)) & 0x1) * color; | 82 | putpixel(p, |
110 | putpixel(p, | 83 | layer, |
111 | layer, | 84 | x + (flipx ? 7 - h : h), |
112 | x + (flipx ? 7 - h : h), | 85 | y + (flipy ? 7 - v : v), |
113 | y + (flipy ? 7 - v : v), | 86 | (((ch1 + ch2 * 2) + color / 4) & 0x3)); |
114 | (((ch1 + ch2 * 2) + color / 4) & 0x3)); | 87 | } |
115 | } | ||
116 | } | 88 | } |
117 | 89 | ||
118 | /* output */ | 90 | int |
91 | initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) { | ||
92 | p->hor = hor; | ||
93 | p->ver = ver; | ||
94 | p->pad = pad; | ||
95 | p->width = (8 * p->hor + p->pad * 2); | ||
96 | p->height = (8 * p->ver + p->pad * 2); | ||
119 | 97 | ||
120 | void | 98 | // Initialize display mode and bg palette. |
121 | drawpixel(Ppu *p, Uint16 x, Uint16 y, Uint8 color) | 99 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1; |
122 | { | ||
123 | if(x >= p->pad && x <= p->width - p->pad - 1 && y >= p->pad && y <= p->height - p->pad - 1) | ||
124 | FRAMEBUFFER[y][x] = p->colors[color]; | ||
125 | } | ||
126 | 100 | ||
127 | void | 101 | // Initialize backgrounds. |
128 | drawppu(Ppu *p) | 102 | u8 cb_fg = 0; |
129 | { | 103 | u8 sb_fg = 10; |
130 | Uint16 x, y; | 104 | u8 cb_bg = 2; |
131 | for(y = 0; y < p->ver; ++y) | 105 | u8 sb_bg = 26; |
132 | for(x = 0; x < p->hor; ++x) { | 106 | BG_CTRL(0) = BG_CHARBLOCK(cb_fg) | BG_SCREENBLOCK(sb_fg) | BG_PRIORITY(1); |
133 | Uint8 v, h; | 107 | BG_CTRL(1) = BG_CHARBLOCK(cb_bg) | BG_SCREENBLOCK(sb_bg) | BG_PRIORITY(2); |
134 | Uint16 key = (y * p->hor + x) * 16; | ||
135 | for(v = 0; v < 8; v++) | ||
136 | for(h = 0; h < 8; h++) { | ||
137 | Uint8 color = readpixel(&p->fg[key], h, v); | ||
138 | if(color == 0) | ||
139 | color = readpixel(&p->bg[key], h, v); | ||
140 | drawpixel(p, x * 8 + p->pad + 7 - h, y * 8 + p->pad + v, color); | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | 108 | ||
145 | int | 109 | // Clear tile memory. |
146 | initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) | 110 | p->fg = &TILE_MEM[cb_fg]; |
147 | { | 111 | p->bg = &TILE_MEM[cb_bg]; |
148 | p->hor = hor; | 112 | for (size_t i = 0; i < 30 * 20 * 8; ++i) { |
149 | p->ver = ver; | 113 | p->fg[i] = 0; |
150 | p->pad = pad; | 114 | p->bg[i] = 0; |
151 | p->width = (8 * p->hor + p->pad * 2); | 115 | } |
152 | p->height = (8 * p->ver + p->pad * 2); | 116 | |
153 | if(!(p->output = malloc(p->width * p->height * sizeof(Uint16)))) | 117 | // Initialize memory map. |
154 | return 0; | 118 | u16 *fg_mem = SCREENBLOCK_MEM[sb_fg]; |
155 | if(!(p->bg = malloc(p->width * p->height * sizeof(Uint8) / 4))) | 119 | u16 *bg_mem = SCREENBLOCK_MEM[sb_bg]; |
156 | return 0; | 120 | size_t k = 0; |
157 | if(!(p->fg = malloc(p->width * p->height * sizeof(Uint8) / 4))) | 121 | for (size_t j = 0; j < 20; ++j) { |
158 | return 0; | 122 | for (size_t i = 0; i < 30; ++i, ++k) { |
159 | clear(p); | 123 | fg_mem[i + j * 32] = k; |
160 | return 1; | 124 | bg_mem[i + j * 32] = k; |
125 | } | ||
126 | } | ||
127 | |||
128 | return 1; | ||
161 | } | 129 | } |
diff --git a/src/uxn/devices/ppu.h b/src/uxn/devices/ppu.h index 187d364..213dc75 100644 --- a/src/uxn/devices/ppu.h +++ b/src/uxn/devices/ppu.h | |||
@@ -7,6 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | Copyright (c) 2021 Devine Lu Linvega | 8 | Copyright (c) 2021 Devine Lu Linvega |
9 | Copyright (c) 2021 Andrew Alderwick | 9 | Copyright (c) 2021 Andrew Alderwick |
10 | Copyright (c) 2021 Bad Diode | ||
10 | 11 | ||
11 | Permission to use, copy, modify, and distribute this software for any | 12 | Permission to use, copy, modify, and distribute this software for any |
12 | purpose with or without fee is hereby granted, provided that the above | 13 | purpose with or without fee is hereby granted, provided that the above |
@@ -21,16 +22,15 @@ typedef unsigned short Uint16; | |||
21 | typedef unsigned int Uint32; | 22 | typedef unsigned int Uint32; |
22 | 23 | ||
23 | typedef struct Ppu { | 24 | typedef struct Ppu { |
24 | Uint8 *bg, *fg; | 25 | Uint32 *bg, *fg; |
25 | Uint16 hor, ver, pad, width, height; | 26 | Uint16 hor, ver, pad, width, height; |
26 | Uint16 *output, colors[4]; | ||
27 | } Ppu; | 27 | } Ppu; |
28 | 28 | ||
29 | int initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad); | 29 | int initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad); |
30 | void putcolors(Ppu *p, Uint8 *addr); | 30 | void putcolors(Ppu *p, Uint8 *addr); |
31 | void putpixel(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 color); | 31 | void putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color); |
32 | void puticn(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); | 32 | void puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
33 | void putchr(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); | 33 | void putchr(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
34 | void drawppu(Ppu *p); | 34 | void drawppu(Ppu *p); |
35 | void drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr); | 35 | void drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr); |
36 | #endif // UXNGBA_PPU_H | 36 | #endif // UXNGBA_PPU_H |