aboutsummaryrefslogtreecommitdiffstats
path: root/src/uxn/devices/ppu.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-19 12:13:29 +0200
committerBad Diode <bd@badd10de.dev>2021-05-19 12:13:29 +0200
commit9873680f9d24e30afc1962987fac2c3ad1612f7b (patch)
tree5135bd3bd1d0e41c8725d51c7a56c1b0a1e2f904 /src/uxn/devices/ppu.c
parenta2f89131491a4cf7914becfd98d277544d26579a (diff)
downloaduxngba-9873680f9d24e30afc1962987fac2c3ad1612f7b.tar.gz
uxngba-9873680f9d24e30afc1962987fac2c3ad1612f7b.zip
Update screen rendering to use 2 backgrounds
Diffstat (limited to 'src/uxn/devices/ppu.c')
-rw-r--r--src/uxn/devices/ppu.c224
1 files changed, 96 insertions, 128 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/*
4Copyright (c) 2021 Devine Lu Linvega 4Copyright (c) 2021 Devine Lu Linvega
5Copyright (c) 2021 Andrew Alderwick 5Copyright (c) 2021 Andrew Alderwick
6Copyright (c) 2021 Adrian "asie" Siekierka
7Copyright (c) 2021 Bad Diode
6 8
7Permission to use, copy, modify, and distribute this software for any 9Permission to use, copy, modify, and distribute this software for any
8purpose with or without fee is hereby granted, provided that the above 10purpose with or without fee is hereby granted, provided that the above
@@ -13,149 +15,115 @@ WITH REGARD TO THIS SOFTWARE.
13*/ 15*/
14 16
15static Uint8 font[][8] = { 17static 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
33Uint8
34readpixel(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
41void 35void
42clear(Ppu *p) 36putcolors(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
53void 50void
54putcolors(Ppu *p, Uint8 *addr) 51putpixel(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
70void 55 Uint32 pos = ((y & 7) + (((x >> 3) + (y >> 3) * 30) * 8));
71putpixel(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
86void 60void
87puticn(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) 61puticn(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
102void 75void
103putchr(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) 76putchr(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 */ 90int
91initppu(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
120void 98 // Initialize display mode and bg palette.
121drawpixel(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
127void 101 // Initialize backgrounds.
128drawppu(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
145int 109 // Clear tile memory.
146initppu(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}