diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-20 15:44:10 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-20 15:44:10 +0200 |
commit | b117f5a58045769c0a65f77967fa3a2aefde721e (patch) | |
tree | 1e7ff19d06873e94e09d74341259e194e7411311 /src | |
parent | 3daf0d136cf0074cc371591892db179567e971eb (diff) | |
download | uxngba-b117f5a58045769c0a65f77967fa3a2aefde721e.tar.gz uxngba-b117f5a58045769c0a65f77967fa3a2aefde721e.zip |
Replace puticn with optimized version
Diffstat (limited to 'src')
-rw-r--r-- | src/uxn/devices/ppu.c | 177 |
1 files changed, 158 insertions, 19 deletions
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c index d9208a5..3865e95 100644 --- a/src/uxn/devices/ppu.c +++ b/src/uxn/devices/ppu.c | |||
@@ -32,6 +32,116 @@ static Uint8 font[][8] = { | |||
32 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, | 32 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, |
33 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; | 33 | {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; |
34 | 34 | ||
35 | static Uint32 unpack_icon_lut[256] = { | ||
36 | 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, | ||
37 | 0x00000101, 0x00000110, 0x00000111, 0x00001000, 0x00001001, | ||
38 | 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, | ||
39 | 0x00001111, 0x00010000, 0x00010001, 0x00010010, 0x00010011, | ||
40 | 0x00010100, 0x00010101, 0x00010110, 0x00010111, 0x00011000, | ||
41 | 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, | ||
42 | 0x00011110, 0x00011111, 0x00100000, 0x00100001, 0x00100010, | ||
43 | 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111, | ||
44 | 0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, | ||
45 | 0x00101101, 0x00101110, 0x00101111, 0x00110000, 0x00110001, | ||
46 | 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, | ||
47 | 0x00110111, 0x00111000, 0x00111001, 0x00111010, 0x00111011, | ||
48 | 0x00111100, 0x00111101, 0x00111110, 0x00111111, 0x01000000, | ||
49 | 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, | ||
50 | 0x01000110, 0x01000111, 0x01001000, 0x01001001, 0x01001010, | ||
51 | 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111, | ||
52 | 0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, | ||
53 | 0x01010101, 0x01010110, 0x01010111, 0x01011000, 0x01011001, | ||
54 | 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, | ||
55 | 0x01011111, 0x01100000, 0x01100001, 0x01100010, 0x01100011, | ||
56 | 0x01100100, 0x01100101, 0x01100110, 0x01100111, 0x01101000, | ||
57 | 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, | ||
58 | 0x01101110, 0x01101111, 0x01110000, 0x01110001, 0x01110010, | ||
59 | 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111, | ||
60 | 0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, | ||
61 | 0x01111101, 0x01111110, 0x01111111, 0x10000000, 0x10000001, | ||
62 | 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, | ||
63 | 0x10000111, 0x10001000, 0x10001001, 0x10001010, 0x10001011, | ||
64 | 0x10001100, 0x10001101, 0x10001110, 0x10001111, 0x10010000, | ||
65 | 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, | ||
66 | 0x10010110, 0x10010111, 0x10011000, 0x10011001, 0x10011010, | ||
67 | 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111, | ||
68 | 0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, | ||
69 | 0x10100101, 0x10100110, 0x10100111, 0x10101000, 0x10101001, | ||
70 | 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, | ||
71 | 0x10101111, 0x10110000, 0x10110001, 0x10110010, 0x10110011, | ||
72 | 0x10110100, 0x10110101, 0x10110110, 0x10110111, 0x10111000, | ||
73 | 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, | ||
74 | 0x10111110, 0x10111111, 0x11000000, 0x11000001, 0x11000010, | ||
75 | 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111, | ||
76 | 0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, | ||
77 | 0x11001101, 0x11001110, 0x11001111, 0x11010000, 0x11010001, | ||
78 | 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, | ||
79 | 0x11010111, 0x11011000, 0x11011001, 0x11011010, 0x11011011, | ||
80 | 0x11011100, 0x11011101, 0x11011110, 0x11011111, 0x11100000, | ||
81 | 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, | ||
82 | 0x11100110, 0x11100111, 0x11101000, 0x11101001, 0x11101010, | ||
83 | 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111, | ||
84 | 0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, | ||
85 | 0x11110101, 0x11110110, 0x11110111, 0x11111000, 0x11111001, | ||
86 | 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, | ||
87 | 0x11111111 | ||
88 | }; | ||
89 | |||
90 | static Uint32 unpack_icon_lut_flipx[256] = { | ||
91 | 0x00000000, 0x10000000, 0x01000000, 0x11000000, 0x00100000, | ||
92 | 0x10100000, 0x01100000, 0x11100000, 0x00010000, 0x10010000, | ||
93 | 0x01010000, 0x11010000, 0x00110000, 0x10110000, 0x01110000, | ||
94 | 0x11110000, 0x00001000, 0x10001000, 0x01001000, 0x11001000, | ||
95 | 0x00101000, 0x10101000, 0x01101000, 0x11101000, 0x00011000, | ||
96 | 0x10011000, 0x01011000, 0x11011000, 0x00111000, 0x10111000, | ||
97 | 0x01111000, 0x11111000, 0x00000100, 0x10000100, 0x01000100, | ||
98 | 0x11000100, 0x00100100, 0x10100100, 0x01100100, 0x11100100, | ||
99 | 0x00010100, 0x10010100, 0x01010100, 0x11010100, 0x00110100, | ||
100 | 0x10110100, 0x01110100, 0x11110100, 0x00001100, 0x10001100, | ||
101 | 0x01001100, 0x11001100, 0x00101100, 0x10101100, 0x01101100, | ||
102 | 0x11101100, 0x00011100, 0x10011100, 0x01011100, 0x11011100, | ||
103 | 0x00111100, 0x10111100, 0x01111100, 0x11111100, 0x00000010, | ||
104 | 0x10000010, 0x01000010, 0x11000010, 0x00100010, 0x10100010, | ||
105 | 0x01100010, 0x11100010, 0x00010010, 0x10010010, 0x01010010, | ||
106 | 0x11010010, 0x00110010, 0x10110010, 0x01110010, 0x11110010, | ||
107 | 0x00001010, 0x10001010, 0x01001010, 0x11001010, 0x00101010, | ||
108 | 0x10101010, 0x01101010, 0x11101010, 0x00011010, 0x10011010, | ||
109 | 0x01011010, 0x11011010, 0x00111010, 0x10111010, 0x01111010, | ||
110 | 0x11111010, 0x00000110, 0x10000110, 0x01000110, 0x11000110, | ||
111 | 0x00100110, 0x10100110, 0x01100110, 0x11100110, 0x00010110, | ||
112 | 0x10010110, 0x01010110, 0x11010110, 0x00110110, 0x10110110, | ||
113 | 0x01110110, 0x11110110, 0x00001110, 0x10001110, 0x01001110, | ||
114 | 0x11001110, 0x00101110, 0x10101110, 0x01101110, 0x11101110, | ||
115 | 0x00011110, 0x10011110, 0x01011110, 0x11011110, 0x00111110, | ||
116 | 0x10111110, 0x01111110, 0x11111110, 0x00000001, 0x10000001, | ||
117 | 0x01000001, 0x11000001, 0x00100001, 0x10100001, 0x01100001, | ||
118 | 0x11100001, 0x00010001, 0x10010001, 0x01010001, 0x11010001, | ||
119 | 0x00110001, 0x10110001, 0x01110001, 0x11110001, 0x00001001, | ||
120 | 0x10001001, 0x01001001, 0x11001001, 0x00101001, 0x10101001, | ||
121 | 0x01101001, 0x11101001, 0x00011001, 0x10011001, 0x01011001, | ||
122 | 0x11011001, 0x00111001, 0x10111001, 0x01111001, 0x11111001, | ||
123 | 0x00000101, 0x10000101, 0x01000101, 0x11000101, 0x00100101, | ||
124 | 0x10100101, 0x01100101, 0x11100101, 0x00010101, 0x10010101, | ||
125 | 0x01010101, 0x11010101, 0x00110101, 0x10110101, 0x01110101, | ||
126 | 0x11110101, 0x00001101, 0x10001101, 0x01001101, 0x11001101, | ||
127 | 0x00101101, 0x10101101, 0x01101101, 0x11101101, 0x00011101, | ||
128 | 0x10011101, 0x01011101, 0x11011101, 0x00111101, 0x10111101, | ||
129 | 0x01111101, 0x11111101, 0x00000011, 0x10000011, 0x01000011, | ||
130 | 0x11000011, 0x00100011, 0x10100011, 0x01100011, 0x11100011, | ||
131 | 0x00010011, 0x10010011, 0x01010011, 0x11010011, 0x00110011, | ||
132 | 0x10110011, 0x01110011, 0x11110011, 0x00001011, 0x10001011, | ||
133 | 0x01001011, 0x11001011, 0x00101011, 0x10101011, 0x01101011, | ||
134 | 0x11101011, 0x00011011, 0x10011011, 0x01011011, 0x11011011, | ||
135 | 0x00111011, 0x10111011, 0x01111011, 0x11111011, 0x00000111, | ||
136 | 0x10000111, 0x01000111, 0x11000111, 0x00100111, 0x10100111, | ||
137 | 0x01100111, 0x11100111, 0x00010111, 0x10010111, 0x01010111, | ||
138 | 0x11010111, 0x00110111, 0x10110111, 0x01110111, 0x11110111, | ||
139 | 0x00001111, 0x10001111, 0x01001111, 0x11001111, 0x00101111, | ||
140 | 0x10101111, 0x01101111, 0x11101111, 0x00011111, 0x10011111, | ||
141 | 0x01011111, 0x11011111, 0x00111111, 0x10111111, 0x01111111, | ||
142 | 0x11111111 | ||
143 | }; | ||
144 | |||
35 | u32 *backbuffer_bg0; | 145 | u32 *backbuffer_bg0; |
36 | u32 *backbuffer_bg1; | 146 | u32 *backbuffer_bg1; |
37 | static u8 dirty_tiles[20][30] = {0}; | 147 | static u8 dirty_tiles[20][30] = {0}; |
@@ -53,32 +163,61 @@ putcolors(Ppu *p, Uint8 *addr) { | |||
53 | 163 | ||
54 | void | 164 | void |
55 | putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color) { | 165 | putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color) { |
56 | Uint32 pos = ((y & 7) + (((x >> 3) + (y >> 3) * 30) * 8)); | 166 | size_t tile_x = x / 8; |
57 | Uint32 shift = (x & 7) << 2; | 167 | size_t tile_y = y / 8; |
168 | size_t start_col = x % 8; | ||
169 | size_t start_row = y % 8; | ||
170 | Uint32 pos = (start_row + ((tile_x + tile_y * 30) * 8)); | ||
171 | Uint32 shift = start_col * 4; | ||
58 | layer[pos] = (layer[pos] & (~(0xF << shift))) | (color << shift); | 172 | layer[pos] = (layer[pos] & (~(0xF << shift))) | (color << shift); |
59 | dirty_tiles[y >> 3][x >> 3] = 1; | 173 | dirty_tiles[tile_y][tile_x] = 1; |
60 | } | 174 | } |
61 | 175 | ||
62 | void | 176 | void |
63 | puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, | 177 | puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, |
64 | Uint8 flipx, Uint8 flipy) { | 178 | Uint8 flipx, Uint8 flipy) { |
65 | Uint16 v, h; | 179 | size_t tile_x = x / 8; |
66 | for(v = 0; v < 8; v++) { | 180 | size_t tile_y = y / 8; |
67 | for(h = 0; h < 8; h++) { | 181 | size_t start_col = x % 8; |
68 | Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); | 182 | size_t start_row = y % 8; |
69 | // if(ch1 == 1 || (color != 0x05 && color != 0x0a && color != 0x0f)) | 183 | Uint32 pos = (start_row + ((tile_x + tile_y * 30) * 8)); |
70 | // putpixel(p, | 184 | Uint32 shift_left = start_col * 4; |
71 | // layer, | 185 | Uint32 shift_right = (8 - start_col) * 4; |
72 | // x + (flipx ? 7 - h : h), | 186 | Uint32 *layer_ptr = &layer[pos]; |
73 | // y + (flipy ? 7 - v : v), | 187 | if (flipy) flipy = 7; |
74 | // ch1 ? color % 4 : color / 4); | 188 | |
75 | // TODO: Add flip options directly to the screenblock? | 189 | Uint32 *lut = flipx ? unpack_icon_lut : unpack_icon_lut_flipx; |
76 | putpixel(p, | 190 | |
77 | layer, | 191 | // There are 4 possible cases: |
78 | x + h, | 192 | // 1. The sprite is exactly at the tile boundary. We can just copy the |
79 | y + v, | 193 | // tile directly to memory. |
80 | ch1 ? color & 0x3 : color >> 2); | 194 | // 2. The sprite covers 2 tiles horizontally. |
195 | // 3. The sprite covers 2 tiles vertically. | ||
196 | // 4. The sprite covers 4 tiles. | ||
197 | if (start_row == 0 && start_col == 0) { | ||
198 | for (size_t i = 0; i < 8; ++i) { | ||
199 | layer_ptr[i] = lut[sprite[i ^ flipy]] * color; | ||
200 | } | ||
201 | dirty_tiles[tile_y][tile_x] = 1; | ||
202 | } else { | ||
203 | u32 row_mask = 0xFFFFFFFF << shift_left; | ||
204 | for (size_t i = 0; i < (8 - start_row); ++i) { | ||
205 | u32 sprite_row = lut[sprite[i ^ flipy]] * color; | ||
206 | layer_ptr[0] = (layer_ptr[0] & ~row_mask) | (sprite_row << shift_left); | ||
207 | layer_ptr[8] = (layer_ptr[8] & row_mask) | (sprite_row >> shift_right); | ||
208 | layer_ptr++; | ||
209 | } | ||
210 | layer_ptr += 8 * 29; | ||
211 | for (size_t i = (8 - start_row); i < 8; ++i) { | ||
212 | u32 sprite_row = lut[sprite[i ^ flipy]] * color; | ||
213 | layer_ptr[0] = (layer_ptr[0] & ~row_mask) | (sprite_row << shift_left); | ||
214 | layer_ptr[8] = (layer_ptr[8] & row_mask) | (sprite_row >> shift_right); | ||
215 | layer_ptr++; | ||
81 | } | 216 | } |
217 | dirty_tiles[tile_y][tile_x] = 1; | ||
218 | dirty_tiles[tile_y][tile_x + 1] = 1; | ||
219 | dirty_tiles[tile_y + 1][tile_x] = 1; | ||
220 | dirty_tiles[tile_y + 1][tile_x + 1] = 1; | ||
82 | } | 221 | } |
83 | } | 222 | } |
84 | 223 | ||