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