1 /*
2 * render2x4.c - 2x4 renderers
3 *
4 * Written by
5 * groepaz <groepaz@gmx.net> based on the renderers written by
6 * John Selck <graham@cruise.de>
7 *
8 * This file is part of VICE, the Versatile Commodore Emulator.
9 * See README for copyright notice.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 * 02111-1307 USA.
25 *
26 */
27
28 #include "vice.h"
29
30 #include "render2x4.h"
31 #include "types.h"
32 #include <string.h>
33
34 /* 16 color 2x2 renderers */
35
render_08_2x4_04(const video_render_color_tables_t * color_tab,const uint8_t * src,uint8_t * trg,unsigned int width,const unsigned int height,const unsigned int xs,const unsigned int ys,const unsigned int xt,const unsigned int yt,const unsigned int pitchs,const unsigned int pitcht,const unsigned int doublescan,video_render_config_t * config)36 void render_08_2x4_04(const video_render_color_tables_t *color_tab,
37 const uint8_t *src, uint8_t *trg,
38 unsigned int width, const unsigned int height,
39 const unsigned int xs, const unsigned int ys,
40 const unsigned int xt, const unsigned int yt,
41 const unsigned int pitchs, const unsigned int pitcht,
42 const unsigned int doublescan, video_render_config_t *config)
43 {
44 const uint32_t *colortab = color_tab->physical_colors;
45 const uint8_t *tmpsrc;
46 uint16_t *tmptrg;
47 unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
48 int readable = config->readable;
49
50 src = src + pitchs * ys + xs;
51 trg = trg + pitcht * yt + xt;
52 yys = (ys << 1) | (yt & 1);
53 wfirst = xt & 1;
54 width -= wfirst;
55 wlast = width & 1;
56 width >>= 1;
57 if (width < 8) {
58 wstart = width;
59 wfast = 0;
60 wend = 0;
61 } else {
62 /* alignment: 8 pixels*/
63 wstart = (unsigned int)(8 - (vice_ptr_to_uint(trg) & 7));
64 wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
65 wend = (width - wstart) & 0x07; /* do not forget the rest*/
66 }
67 for (y = yys; y < (yys + height); y++) {
68 tmpsrc = src;
69 tmptrg = (uint16_t *)trg;
70 if (!(y & 2) || doublescan) {
71 if ((y & 3) && readable && y > yys) { /* copy previous line */
72 memcpy(trg, trg - pitcht, (width << 1) + wfirst + wlast);
73 } else {
74 if (wfirst) {
75 *((uint8_t *)tmptrg) = (uint8_t)colortab[*tmpsrc++];
76 tmptrg = (uint16_t *)(((uint8_t *)tmptrg) + 1);
77 }
78 for (x = 0; x < wstart; x++) {
79 *tmptrg++ = (uint16_t)colortab[*tmpsrc++];
80 }
81 for (x = 0; x < wfast; x++) {
82 tmptrg[0] = (uint16_t)colortab[tmpsrc[0]];
83 tmptrg[1] = (uint16_t)colortab[tmpsrc[1]];
84 tmptrg[2] = (uint16_t)colortab[tmpsrc[2]];
85 tmptrg[3] = (uint16_t)colortab[tmpsrc[3]];
86 tmptrg[4] = (uint16_t)colortab[tmpsrc[4]];
87 tmptrg[5] = (uint16_t)colortab[tmpsrc[5]];
88 tmptrg[6] = (uint16_t)colortab[tmpsrc[6]];
89 tmptrg[7] = (uint16_t)colortab[tmpsrc[7]];
90 tmpsrc += 8;
91 tmptrg += 8;
92 }
93 for (x = 0; x < wend; x++) {
94 *tmptrg++ = (uint16_t)colortab[*tmpsrc++];
95 }
96 if (wlast) {
97 *((uint8_t *)tmptrg) = (uint8_t)colortab[*tmpsrc];
98 tmptrg = (uint16_t *)(((uint8_t *)tmptrg) + 1);
99 }
100 }
101 } else {
102 memset(trg, (uint8_t)colortab[0], (width << 1) + wfirst + wlast);
103 }
104 if ((y & 3) == 3) {
105 src += pitchs;
106 }
107 trg += pitcht;
108 }
109 }
110
render_16_2x4_04(const video_render_color_tables_t * color_tab,const uint8_t * src,uint8_t * trg,unsigned int width,const unsigned int height,const unsigned int xs,const unsigned int ys,const unsigned int xt,const unsigned int yt,const unsigned int pitchs,const unsigned int pitcht,const unsigned int doublescan,video_render_config_t * config)111 void render_16_2x4_04(const video_render_color_tables_t *color_tab,
112 const uint8_t *src, uint8_t *trg,
113 unsigned int width, const unsigned int height,
114 const unsigned int xs, const unsigned int ys,
115 const unsigned int xt, const unsigned int yt,
116 const unsigned int pitchs, const unsigned int pitcht,
117 const unsigned int doublescan, video_render_config_t *config)
118 {
119 const uint32_t *colortab = color_tab->physical_colors;
120 const uint8_t *tmpsrc;
121 uint32_t *tmptrg;
122 unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
123 uint32_t color;
124 int readable = config->readable;
125
126 src = src + pitchs * ys + xs;
127 trg = trg + pitcht * yt + (xt << 1);
128 yys = (ys << 1) | (yt & 1);
129 wfirst = xt & 1;
130 width -= wfirst;
131 wlast = width & 1;
132 width >>= 1;
133 if (width < 8) {
134 wstart = width;
135 wfast = 0;
136 wend = 0;
137 } else {
138 /* alignment: 8 pixels*/
139 wstart = (unsigned int)(8 - (vice_ptr_to_int(trg) & 7));
140 wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
141 wend = (width - wstart) & 0x07; /* do not forget the rest*/
142 }
143 for (y = yys; y < (yys + height); y++) {
144 tmpsrc = src;
145 tmptrg = (uint32_t *)trg;
146 if (!(y & 2) || doublescan) {
147 if ((y & 3) && readable && y > yys) { /* copy previous line */
148 memcpy(trg, trg - pitcht, ((width << 1) + wfirst + wlast) << 1);
149 } else {
150 if (wfirst) {
151 *((uint16_t *)tmptrg) = (uint16_t)colortab[*tmpsrc++];
152 tmptrg = (uint32_t *)(((uint16_t *)tmptrg) + 1);
153 }
154 for (x = 0; x < wstart; x++) {
155 *tmptrg++ = colortab[*tmpsrc++];
156 }
157 for (x = 0; x < wfast; x++) {
158 tmptrg[0] = colortab[tmpsrc[0]];
159 tmptrg[1] = colortab[tmpsrc[1]];
160 tmptrg[2] = colortab[tmpsrc[2]];
161 tmptrg[3] = colortab[tmpsrc[3]];
162 tmptrg[4] = colortab[tmpsrc[4]];
163 tmptrg[5] = colortab[tmpsrc[5]];
164 tmptrg[6] = colortab[tmpsrc[6]];
165 tmptrg[7] = colortab[tmpsrc[7]];
166 tmpsrc += 8;
167 tmptrg += 8;
168 }
169 for (x = 0; x < wend; x++) {
170 *tmptrg++ = colortab[*tmpsrc++];
171 }
172 if (wlast) {
173 *((uint16_t *)tmptrg) = (uint16_t)colortab[*tmpsrc];
174 }
175 }
176 } else {
177 if (readable && y > yys + 3) { /* copy 4 lines before */
178 memcpy(trg, trg - pitcht * 4, ((width << 1) + wfirst + wlast) << 1);
179 } else {
180 color = colortab[0];
181 if (wfirst) {
182 *((uint16_t *)tmptrg) = (uint16_t)color;
183 tmptrg = (uint32_t *)(((uint16_t *)tmptrg) + 1);
184 }
185 for (x = 0; x < wstart; x++) {
186 *tmptrg++ = color;
187 }
188 for (x = 0; x < wfast; x++) {
189 tmptrg[0] = color;
190 tmptrg[1] = color;
191 tmptrg[2] = color;
192 tmptrg[3] = color;
193 tmptrg[4] = color;
194 tmptrg[5] = color;
195 tmptrg[6] = color;
196 tmptrg[7] = color;
197 tmptrg += 8;
198 }
199 for (x = 0; x < wend; x++) {
200 *tmptrg++ = color;
201 }
202 if (wlast) {
203 *((uint16_t *)tmptrg) = (uint16_t)color;
204 }
205 }
206 }
207 if ((y & 3) == 3) {
208 src += pitchs;
209 }
210 trg += pitcht;
211 }
212 }
213
render_24_2x4_04(const video_render_color_tables_t * color_tab,const uint8_t * src,uint8_t * trg,unsigned int width,const unsigned int height,const unsigned int xs,const unsigned int ys,const unsigned int xt,const unsigned int yt,const unsigned int pitchs,const unsigned int pitcht,const unsigned int doublescan,video_render_config_t * config)214 void render_24_2x4_04(const video_render_color_tables_t *color_tab,
215 const uint8_t *src, uint8_t *trg,
216 unsigned int width, const unsigned int height,
217 const unsigned int xs, const unsigned int ys,
218 const unsigned int xt, const unsigned int yt,
219 const unsigned int pitchs, const unsigned int pitcht,
220 const unsigned int doublescan, video_render_config_t *config)
221 {
222 const uint32_t *colortab = color_tab->physical_colors;
223 const uint8_t *tmpsrc;
224 uint8_t *tmptrg;
225 unsigned int x, y, wlast, yys;
226 register uint32_t color;
227 register uint32_t tcolor;
228 int readable = config->readable;
229
230 src = src + pitchs * ys + xs;
231 trg = trg + pitcht * yt + (xt * 3);
232 yys = (ys << 1) | (yt & 1);
233 wlast = width & 1;
234 width >>= 1;
235 for (y = yys; y < (yys + height); y++) {
236 tmpsrc = src;
237 tmptrg = trg;
238 if (!(y & 2) || doublescan) {
239 if ((y & 3) && readable && y > yys) { /* copy previous line */
240 memcpy(trg, trg - pitcht, ((width << 1) + wlast) * 3);
241 } else {
242 for (x = 0; x < width; x++) {
243 color = colortab[*tmpsrc++];
244 tcolor = color;
245 tmptrg[3] = tmptrg[0] = (uint8_t)color;
246 color >>= 8;
247 tmptrg[4] = tmptrg[1] = (uint8_t)color;
248 color >>= 8;
249 tmptrg[5] = tmptrg[2] = (uint8_t)color;
250 tmptrg += 6;
251 }
252 if (wlast) {
253 color = colortab[*tmpsrc];
254 tmptrg[0] = (uint8_t)color;
255 color >>= 8;
256 tmptrg[1] = (uint8_t)color;
257 color >>= 8;
258 tmptrg[2] = (uint8_t)color;
259 }
260 }
261 } else {
262 if (readable && y > yys + 3) { /* copy 4 lines before */
263 memcpy(trg, trg - pitcht * 4, ((width << 1) + wlast) * 3);
264 } else {
265 color = colortab[0];
266 for (x = 0; x < width; x++) {
267 tcolor = color;
268 tmptrg[3] = tmptrg[0] = (uint8_t)tcolor;
269 tcolor >>= 8;
270 tmptrg[4] = tmptrg[1] = (uint8_t)tcolor;
271 tcolor >>= 8;
272 tmptrg[5] = tmptrg[2] = (uint8_t)tcolor;
273 tmptrg += 6;
274 }
275 if (wlast) {
276 tmptrg[0] = (uint8_t)color;
277 color >>= 8;
278 tmptrg[1] = (uint8_t)color;
279 color >>= 8;
280 tmptrg[2] = (uint8_t)color;
281 }
282 }
283 }
284 if ((y & 3) == 3) {
285 src += pitchs;
286 }
287 trg += pitcht;
288 }
289 }
290
render_32_2x4_04(const video_render_color_tables_t * color_tab,const uint8_t * src,uint8_t * trg,unsigned int width,const unsigned int height,const unsigned int xs,const unsigned int ys,const unsigned int xt,const unsigned int yt,const unsigned int pitchs,const unsigned int pitcht,const unsigned int doublescan,video_render_config_t * config)291 void render_32_2x4_04(const video_render_color_tables_t *color_tab,
292 const uint8_t *src, uint8_t *trg,
293 unsigned int width, const unsigned int height,
294 const unsigned int xs, const unsigned int ys,
295 const unsigned int xt, const unsigned int yt,
296 const unsigned int pitchs, const unsigned int pitcht,
297 const unsigned int doublescan, video_render_config_t *config)
298 {
299 const uint32_t *colortab = color_tab->physical_colors;
300 const uint8_t *tmpsrc;
301 uint32_t *tmptrg;
302 unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
303 register uint32_t color;
304 int readable = config->readable;
305
306 src = src + pitchs * ys + xs;
307 trg = trg + pitcht * yt + (xt << 2);
308 yys = (ys << 1) | (yt & 1);
309 wfirst = xt & 1;
310 width -= wfirst;
311 wlast = width & 1;
312 width >>= 1;
313 if (width < 8) {
314 wstart = width;
315 wfast = 0;
316 wend = 0;
317 } else {
318 /* alignment: 8 pixels*/
319 wstart = (unsigned int)(8 - (vice_ptr_to_uint(trg) & 7));
320 wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
321 wend = (width - wstart) & 0x07; /* do not forget the rest*/
322 }
323 for (y = yys; y < (yys + height); y++) {
324 tmpsrc = src;
325 tmptrg = (uint32_t *)trg;
326 if (!(y & 2) || doublescan) {
327 if ((y & 3) && readable && y > yys) { /* copy previous line */
328 memcpy(trg, trg - pitcht, ((width << 1) + wfirst + wlast) << 2);
329 } else {
330 if (wfirst) {
331 *tmptrg++ = colortab[*tmpsrc++];
332 }
333 for (x = 0; x < wstart; x++) {
334 color = colortab[*tmpsrc++];
335 *tmptrg++ = color;
336 *tmptrg++ = color;
337 }
338 for (x = 0; x < wfast; x++) {
339 color = colortab[tmpsrc[0]];
340 tmptrg[0] = color;
341 tmptrg[1] = color;
342 color = colortab[tmpsrc[1]];
343 tmptrg[2] = color;
344 tmptrg[3] = color;
345 color = colortab[tmpsrc[2]];
346 tmptrg[4] = color;
347 tmptrg[5] = color;
348 color = colortab[tmpsrc[3]];
349 tmptrg[6] = color;
350 tmptrg[7] = color;
351 color = colortab[tmpsrc[4]];
352 tmptrg[8] = color;
353 tmptrg[9] = color;
354 color = colortab[tmpsrc[5]];
355 tmptrg[10] = color;
356 tmptrg[11] = color;
357 color = colortab[tmpsrc[6]];
358 tmptrg[12] = color;
359 tmptrg[13] = color;
360 color = colortab[tmpsrc[7]];
361 tmptrg[14] = color;
362 tmptrg[15] = color;
363 tmpsrc += 8;
364 tmptrg += 16;
365 }
366 for (x = 0; x < wend; x++) {
367 color = colortab[*tmpsrc++];
368 *tmptrg++ = color;
369 *tmptrg++ = color;
370 }
371 if (wlast) {
372 *tmptrg = colortab[*tmpsrc];
373 }
374 }
375 } else {
376 if (readable && y > yys + 3) { /* copy 4 lines before */
377 memcpy(trg, trg - pitcht * 4, ((width << 1) + wfirst + wlast) << 2);
378 } else {
379 color = colortab[0];
380 if (wfirst) {
381 *tmptrg++ = color;
382 }
383 for (x = 0; x < wstart; x++) {
384 *tmptrg++ = color;
385 *tmptrg++ = color;
386 }
387 for (x = 0; x < wfast; x++) {
388 tmptrg[0] = color;
389 tmptrg[1] = color;
390 tmptrg[2] = color;
391 tmptrg[3] = color;
392 tmptrg[4] = color;
393 tmptrg[5] = color;
394 tmptrg[6] = color;
395 tmptrg[7] = color;
396 tmptrg[8] = color;
397 tmptrg[9] = color;
398 tmptrg[10] = color;
399 tmptrg[11] = color;
400 tmptrg[12] = color;
401 tmptrg[13] = color;
402 tmptrg[14] = color;
403 tmptrg[15] = color;
404 tmptrg += 16;
405 }
406 for (x = 0; x < wend; x++) {
407 *tmptrg++ = color;
408 *tmptrg++ = color;
409 }
410 if (wlast) {
411 *tmptrg = color;
412 }
413 }
414 }
415 if ((y & 3) == 3) {
416 src += pitchs;
417 }
418 trg += pitcht;
419 }
420 }
421