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