1 /*
2  * render2x2.c - 2x2 renderers
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 "render2x2.h"
30 #include "types.h"
31 #include <string.h>
32 
33 
34 /* 16 color 2x2 renderers */
35 
render_08_2x2_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_2x2_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 & 1) || doublescan) {
71             if ((y & 1) && 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) << 1);
103         }
104         if (y & 1) {
105             src += pitchs;
106         }
107         trg += pitcht;
108     }
109 }
110 
render_16_2x2_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_2x2_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 & 1) || doublescan) {
147             if ((y & 1) && 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 + 1) { /* copy 2 lines before */
178                 memcpy(trg, trg - pitcht * 2, ((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 & 1) {
208             src += pitchs;
209         }
210         trg += pitcht;
211     }
212 }
213 
render_24_2x2_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_2x2_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 & 1) || doublescan) {
239             if ((y & 1) && 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                     tmptrg[3] = tmptrg[0] = (uint8_t)color;
245                     color >>= 8;
246                     tmptrg[4] = tmptrg[1] = (uint8_t)color;
247                     color >>= 8;
248                     tmptrg[5] = tmptrg[2] = (uint8_t)color;
249                     tmptrg += 6;
250                 }
251                 if (wlast) {
252                     color = colortab[*tmpsrc];
253                     tmptrg[0] = (uint8_t)color;
254                     color >>= 8;
255                     tmptrg[1] = (uint8_t)color;
256                     color >>= 8;
257                     tmptrg[2] = (uint8_t)color;
258                 }
259             }
260         } else {
261             if (readable && y > yys + 1) { /* copy 2 lines before */
262                 memcpy(trg, trg - pitcht * 2, ((width << 1) + wlast) * 3);
263             } else {
264                 color = colortab[0];
265                 for (x = 0; x < width; x++) {
266                     tcolor = color;
267                     tmptrg[3] = tmptrg[0] = (uint8_t)tcolor;
268                     tcolor >>= 8;
269                     tmptrg[4] = tmptrg[1] = (uint8_t)tcolor;
270                     tcolor >>= 8;
271                     tmptrg[5] = tmptrg[2] = (uint8_t)tcolor;
272                     tmptrg += 6;
273                 }
274                 if (wlast) {
275                     tmptrg[0] = (uint8_t)color;
276                     color >>= 8;
277                     tmptrg[1] = (uint8_t)color;
278                     color >>= 8;
279                     tmptrg[2] = (uint8_t)color;
280                 }
281             }
282         }
283         if (y & 1) {
284             src += pitchs;
285         }
286         trg += pitcht;
287     }
288 }
289 
render_32_2x2_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)290 void render_32_2x2_04(const video_render_color_tables_t *color_tab,
291                       const uint8_t *src, uint8_t *trg,
292                       unsigned int width, const unsigned int height,
293                       const unsigned int xs, const unsigned int ys,
294                       const unsigned int xt, const unsigned int yt,
295                       const unsigned int pitchs, const unsigned int pitcht,
296                       const unsigned int doublescan, video_render_config_t *config)
297 {
298     const uint32_t *colortab = color_tab->physical_colors;
299     const uint8_t *tmpsrc;
300     uint32_t *tmptrg;
301     unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
302     register uint32_t color;
303     int readable = config->readable;
304 
305     src = src + pitchs * ys + xs;
306     trg = trg + pitcht * yt + (xt << 2);
307     yys = (ys << 1) | (yt & 1);
308     wfirst = xt & 1;
309     width -= wfirst;
310     wlast = width & 1;
311     width >>= 1;
312     if (width < 8) {
313         wstart = width;
314         wfast = 0;
315         wend = 0;
316     } else {
317         /* alignment: 8 pixels*/
318         wstart = (unsigned int)(8 - (vice_ptr_to_uint(trg) & 7));
319         wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
320         wend = (width - wstart) & 0x07; /* do not forget the rest*/
321     }
322     for (y = yys; y < (yys + height); y++) {
323         tmpsrc = src;
324         tmptrg = (uint32_t *)trg;
325         if (!(y & 1) || doublescan) {
326             if ((y & 1) && readable && y > yys) { /* copy previous line */
327                 memcpy(trg, trg - pitcht, ((width << 1) + wfirst + wlast) << 2);
328             } else {
329                 if (wfirst) {
330                     *tmptrg++ = colortab[*tmpsrc++];
331                 }
332                 for (x = 0; x < wstart; x++) {
333                     color = colortab[*tmpsrc++];
334                     *tmptrg++ = color;
335                     *tmptrg++ = color;
336                 }
337                 for (x = 0; x < wfast; x++) {
338                     color = colortab[tmpsrc[0]];
339                     tmptrg[0] = color;
340                     tmptrg[1] = color;
341                     color = colortab[tmpsrc[1]];
342                     tmptrg[2] = color;
343                     tmptrg[3] = color;
344                     color = colortab[tmpsrc[2]];
345                     tmptrg[4] = color;
346                     tmptrg[5] = color;
347                     color = colortab[tmpsrc[3]];
348                     tmptrg[6] = color;
349                     tmptrg[7] = color;
350                     color = colortab[tmpsrc[4]];
351                     tmptrg[8] = color;
352                     tmptrg[9] = color;
353                     color = colortab[tmpsrc[5]];
354                     tmptrg[10] = color;
355                     tmptrg[11] = color;
356                     color = colortab[tmpsrc[6]];
357                     tmptrg[12] = color;
358                     tmptrg[13] = color;
359                     color = colortab[tmpsrc[7]];
360                     tmptrg[14] = color;
361                     tmptrg[15] = color;
362                     tmpsrc += 8;
363                     tmptrg += 16;
364                 }
365                 for (x = 0; x < wend; x++) {
366                     color = colortab[*tmpsrc++];
367                     *tmptrg++ = color;
368                     *tmptrg++ = color;
369                 }
370                 if (wlast) {
371                     *tmptrg = colortab[*tmpsrc];
372                 }
373             }
374         } else {
375             if (readable && y > yys + 1) { /* copy 2 lines before */
376                 memcpy(trg, trg - pitcht * 2, ((width << 1) + wfirst + wlast) << 2);
377             } else {
378                 color = colortab[0];
379                 if (wfirst) {
380                     *tmptrg++ = color;
381                 }
382                 for (x = 0; x < wstart; x++) {
383                     *tmptrg++ = color;
384                     *tmptrg++ = color;
385                 }
386                 for (x = 0; x < wfast; x++) {
387                     tmptrg[0] = color;
388                     tmptrg[1] = color;
389                     tmptrg[2] = color;
390                     tmptrg[3] = color;
391                     tmptrg[4] = color;
392                     tmptrg[5] = color;
393                     tmptrg[6] = color;
394                     tmptrg[7] = color;
395                     tmptrg[8] = color;
396                     tmptrg[9] = color;
397                     tmptrg[10] = color;
398                     tmptrg[11] = color;
399                     tmptrg[12] = color;
400                     tmptrg[13] = color;
401                     tmptrg[14] = color;
402                     tmptrg[15] = color;
403                     tmptrg += 16;
404                 }
405                 for (x = 0; x < wend; x++) {
406                     *tmptrg++ = color;
407                     *tmptrg++ = color;
408                 }
409                 if (wlast) {
410                     *tmptrg = color;
411                 }
412             }
413         }
414         if (y & 1) {
415             src += pitchs;
416         }
417         trg += pitcht;
418     }
419 }
420 
421 /*****************************************************************************/
422 /*****************************************************************************/
423 
424 /* 256 color 2x2 renderers */
425 
426 #if 0
427 void render_08_2x2_08(const video_render_color_tables_t *color_tab,
428                       const uint8_t *src, uint8_t *trg,
429                       unsigned int width, const unsigned int height,
430                       const unsigned int xs, const unsigned int ys,
431                       const unsigned int xt, const unsigned int yt,
432                       const unsigned int pitchs, const unsigned int pitcht,
433                       const unsigned int doublescan)
434 {
435     const uint32_t *colortab = color_tab->physical_colors;
436     const uint8_t *pre;
437     const uint8_t *tmppre;
438     const uint8_t *tmpsrc;
439     uint16_t *tmptrg;
440     unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
441     register uint16_t color;
442 
443     src = src + pitchs * ys + xs;
444     trg = trg + pitcht * yt + xt;
445     yys = (ys << 1) | (yt & 1);
446     wfirst = xt & 1;
447     width -= wfirst;
448     wlast = width & 1;
449     width >>= 1;
450     if (width < 8) {
451         wstart = width;
452         wfast = 0;
453         wend = 0;
454     } else {
455         /* alignment: 8 pixels*/
456         wstart = (unsigned int)(8 - (vice_ptr_to_uint(trg) & 7));
457         wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
458         wend = (width - wstart) & 0x07; /* do not forget the rest*/
459     }
460     pre = src - pitchs - 1;
461     for (y = yys; y < (yys + height); y++) {
462         tmppre = pre;
463         tmpsrc = src;
464         tmptrg = (uint16_t *)trg;
465         if ((y & 1) || doublescan) {
466             if (wfirst) {
467                 *((uint8_t *)tmptrg) = (uint8_t)colortab[*tmpsrc++ | (*tmppre++ << 4)];
468                 tmptrg = (uint16_t *)(((uint8_t *)tmptrg) + 1);
469             }
470             for (x = 0; x < wstart; x++) {
471                 *tmptrg++ = (uint16_t)colortab[*tmpsrc++ | (*tmppre++ << 4)];
472             }
473             for (x = 0; x < wfast; x++) {
474                 tmptrg[0] = (uint16_t)colortab[tmpsrc[0] | (tmppre[0] << 4)];
475                 tmptrg[1] = (uint16_t)colortab[tmpsrc[1] | (tmppre[1] << 4)];
476                 tmptrg[2] = (uint16_t)colortab[tmpsrc[2] | (tmppre[2] << 4)];
477                 tmptrg[3] = (uint16_t)colortab[tmpsrc[3] | (tmppre[3] << 4)];
478                 tmptrg[4] = (uint16_t)colortab[tmpsrc[4] | (tmppre[4] << 4)];
479                 tmptrg[5] = (uint16_t)colortab[tmpsrc[5] | (tmppre[5] << 4)];
480                 tmptrg[6] = (uint16_t)colortab[tmpsrc[6] | (tmppre[6] << 4)];
481                 tmptrg[7] = (uint16_t)colortab[tmpsrc[7] | (tmppre[7] << 4)];
482                 tmpsrc += 8;
483                 tmppre += 8;
484                 tmptrg += 8;
485             }
486             for (x = 0; x < wend; x++) {
487                 *tmptrg++ = (uint16_t)colortab[*tmpsrc++ | (*tmppre++ << 4)];
488             }
489             if (wlast) {
490                 *((uint8_t *)tmptrg) = (uint8_t)colortab[*tmpsrc | (*tmppre << 4)];
491             }
492             if (y & 1) {
493                 pre = src - 1;
494                 src += pitchs;
495             }
496         } else {
497             color = (uint16_t)colortab[0];
498             if (wfirst) {
499                 *((uint8_t *)tmptrg) = (uint8_t)color;
500                 tmptrg = (uint16_t *)(((uint8_t *)tmptrg) + 1);
501             }
502             for (x = 0; x < wstart; x++) {
503                 *tmptrg++ = color;
504             }
505             for (x = 0; x < wfast; x++) {
506                 tmptrg[0] = color;
507                 tmptrg[1] = color;
508                 tmptrg[2] = color;
509                 tmptrg[3] = color;
510                 tmptrg[4] = color;
511                 tmptrg[5] = color;
512                 tmptrg[6] = color;
513                 tmptrg[7] = color;
514                 tmptrg += 8;
515             }
516             for (x = 0; x < wend; x++) {
517                 *tmptrg++ = color;
518             }
519             if (wlast) {
520                 *((uint8_t *)tmptrg) = (uint8_t)color;
521             }
522         }
523         trg += pitcht;
524     }
525 }
526 
527 void render_16_2x2_08(const video_render_color_tables_t *color_tab,
528                       const uint8_t *src, uint8_t *trg,
529                       unsigned int width, const unsigned int height,
530                       const unsigned int xs, const unsigned int ys,
531                       const unsigned int xt, const unsigned int yt,
532                       const unsigned int pitchs, const unsigned int pitcht,
533                       const unsigned int doublescan)
534 {
535     const uint32_t *colortab = color_tab->physical_colors;
536     const uint8_t *pre;
537     const uint8_t *tmppre;
538     const uint8_t *tmpsrc;
539     uint32_t *tmptrg;
540     unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
541     register uint32_t color;
542 
543     src = src + pitchs * ys + xs;
544     trg = trg + pitcht * yt + (xt << 1);
545     yys = (ys << 1) | (yt & 1);
546     wfirst = xt & 1;
547     width -= wfirst;
548     wlast = width & 1;
549     width >>= 1;
550     if (width < 8) {
551         wstart = width;
552         wfast = 0;
553         wend = 0;
554     } else {
555         /* alignment: 8 pixels*/
556         wstart = (unsigned int)(8 - (vice_ptr_to_uint(trg) & 7));
557         wfast = (width - wstart) >> 3; /* fast loop for 8 pixel segments*/
558         wend = (width - wstart) & 0x07; /* do not forget the rest*/
559     }
560     pre = src - pitchs - 1;
561     for (y = yys; y < (yys + height); y++) {
562         tmppre = pre;
563         tmpsrc = src;
564         tmptrg = (uint32_t *)trg;
565         if ((y & 1) || doublescan) {
566             if (wfirst) {
567                 *((uint16_t *)tmptrg) = (uint16_t)colortab[*tmpsrc++ | (*tmppre++ << 4)];
568                 tmptrg = (uint32_t *)(((uint16_t *)tmptrg) + 1);
569             }
570             for (x = 0; x < wstart; x++) {
571                 *tmptrg++ = colortab[*tmpsrc++ | (*tmppre++ << 4)];
572             }
573             for (x = 0; x < wfast; x++) {
574                 tmptrg[0] = colortab[tmpsrc[0] | (tmppre[0] << 4)];
575                 tmptrg[1] = colortab[tmpsrc[1] | (tmppre[1] << 4)];
576                 tmptrg[2] = colortab[tmpsrc[2] | (tmppre[2] << 4)];
577                 tmptrg[3] = colortab[tmpsrc[3] | (tmppre[3] << 4)];
578                 tmptrg[4] = colortab[tmpsrc[4] | (tmppre[4] << 4)];
579                 tmptrg[5] = colortab[tmpsrc[5] | (tmppre[5] << 4)];
580                 tmptrg[6] = colortab[tmpsrc[6] | (tmppre[6] << 4)];
581                 tmptrg[7] = colortab[tmpsrc[7] | (tmppre[7] << 4)];
582                 tmpsrc += 8;
583                 tmppre += 8;
584                 tmptrg += 8;
585             }
586             for (x = 0; x < wend; x++) {
587                 *tmptrg++ = colortab[*tmpsrc++ | (*tmppre++ << 4)];
588             }
589             if (wlast) {
590                 *((uint16_t *)tmptrg) = (uint16_t)colortab[*tmpsrc | (*tmppre << 4)];
591             }
592             if (y & 1) {
593                 pre = src - 1;
594                 src += pitchs;
595             }
596         } else {
597             color = colortab[0];
598             if (wfirst) {
599                 *((uint16_t *)tmptrg) = (uint16_t)color;
600                 tmptrg = (uint32_t *)(((uint16_t *)tmptrg) + 1);
601             }
602             for (x = 0; x < wstart; x++) {
603                 *tmptrg++ = color;
604             }
605             for (x = 0; x < wfast; x++) {
606                 tmptrg[0] = color;
607                 tmptrg[1] = color;
608                 tmptrg[2] = color;
609                 tmptrg[3] = color;
610                 tmptrg[4] = color;
611                 tmptrg[5] = color;
612                 tmptrg[6] = color;
613                 tmptrg[7] = color;
614                 tmptrg += 8;
615             }
616             for (x = 0; x < wend; x++) {
617                 *tmptrg++ = color;
618             }
619             if (wlast) {
620                 *((uint16_t *)tmptrg) = (uint16_t)color;
621             }
622         }
623         trg += pitcht;
624     }
625 }
626 
627 void render_24_2x2_08(const video_render_color_tables_t *color_tab,
628                       const uint8_t *src, uint8_t *trg,
629                       unsigned int width, const unsigned int height,
630                       const unsigned int xs, const unsigned int ys,
631                       const unsigned int xt, const unsigned int yt,
632                       const unsigned int pitchs, const unsigned int pitcht,
633                       const unsigned int doublescan)
634 {
635     const uint32_t *colortab = color_tab->physical_colors;
636     const uint8_t *pre;
637     const uint8_t *tmppre;
638     const uint8_t *tmpsrc;
639     uint8_t *tmptrg;
640     unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
641     register uint32_t color;
642     register uint32_t tcolor;
643 
644     src = src + pitchs * ys + xs;
645     trg = trg + pitcht * yt + (xt * 3);
646     yys = (ys << 1) | (yt & 1);
647     wfirst = xt & 1;
648     width -= wfirst;
649     wlast = width & 1;
650     width >>= 1;
651     if (width < 4) {
652         wstart = width;
653         wfast = 0;
654         wend = 0;
655     } else {
656         /* alignment: 4 pixels*/
657         wstart = (unsigned int)(4 - (vice_ptr_to_uint(trg) & 3));
658         wfast = (width - wstart) >> 2; /* fast loop for 4 pixel segments*/
659         wend = (width - wstart) & 0x03; /* do not forget the rest*/
660     }
661     pre = src - pitchs - 1;
662     for (y = yys; y < (yys + height); y++) {
663         tmppre = pre;
664         tmpsrc = src;
665         tmptrg = trg;
666         if ((y & 1) || doublescan) {
667             if (wfirst) {
668                 color = colortab[*tmpsrc++ | (*tmppre++ << 4)];
669                 *tmptrg++ = (uint8_t)color;
670                 color >>= 8;
671                 *tmptrg++ = (uint8_t)color;
672                 color >>= 8;
673                 *tmptrg++ = (uint8_t)color;
674             }
675             for (x = 0; x < wstart; x++) {
676                 color = colortab[*tmpsrc++ | (*tmppre++ << 4)];
677                 tcolor = color;
678                 tmptrg[0] = (uint8_t)color;
679                 color >>= 8;
680                 tmptrg[1] = (uint8_t)color;
681                 color >>= 8;
682                 tmptrg[2] = (uint8_t)color;
683                 tmptrg[3] = (uint8_t)tcolor;
684                 tcolor >>= 8;
685                 tmptrg[4] = (uint8_t)tcolor;
686                 tcolor >>= 8;
687                 tmptrg[5] = (uint8_t)tcolor;
688                 tmptrg += 6;
689             }
690             for (x = 0; x < wfast; x++) {
691                 color = colortab[tmpsrc[0] | (tmppre[0] << 4)];
692                 tcolor = color;
693                 tmptrg[0] = (uint8_t)color;
694                 color >>= 8;
695                 tmptrg[1] = (uint8_t)color;
696                 color >>= 8;
697                 tmptrg[2] = (uint8_t)color;
698                 tmptrg[3] = (uint8_t)tcolor;
699                 tcolor >>= 8;
700                 tmptrg[4] = (uint8_t)tcolor;
701                 tcolor >>= 8;
702                 tmptrg[5] = (uint8_t)tcolor;
703                 color = colortab[tmpsrc[1] | (tmppre[1] << 4)];
704                 tcolor = color;
705                 tmptrg[6] = (uint8_t)color;
706                 color >>= 8;
707                 tmptrg[7] = (uint8_t)color;
708                 color >>= 8;
709                 tmptrg[8] = (uint8_t)color;
710                 tmptrg[9] = (uint8_t)tcolor;
711                 tcolor >>= 8;
712                 tmptrg[10] = (uint8_t)tcolor;
713                 tcolor >>= 8;
714                 tmptrg[11] = (uint8_t)tcolor;
715                 color = colortab[tmpsrc[2] | (tmppre[2] << 4)];
716                 tcolor = color;
717                 tmptrg[12] = (uint8_t)color;
718                 color >>= 8;
719                 tmptrg[13] = (uint8_t)color;
720                 color >>= 8;
721                 tmptrg[14] = (uint8_t)color;
722                 tmptrg[15] = (uint8_t)tcolor;
723                 tcolor >>= 8;
724                 tmptrg[16] = (uint8_t)tcolor;
725                 tcolor >>= 8;
726                 tmptrg[17] = (uint8_t)tcolor;
727                 color = colortab[tmpsrc[3] | (tmppre[3] << 4)];
728                 tcolor = color;
729                 tmptrg[18] = (uint8_t)color;
730                 color >>= 8;
731                 tmptrg[19] = (uint8_t)color;
732                 color >>= 8;
733                 tmptrg[20] = (uint8_t)color;
734                 tmptrg[21] = (uint8_t)tcolor;
735                 tcolor >>= 8;
736                 tmptrg[22] = (uint8_t)tcolor;
737                 tcolor >>= 8;
738                 tmptrg[23] = (uint8_t)tcolor;
739                 tmpsrc += 4;
740                 tmppre += 4;
741                 tmptrg += 24;
742             }
743             for (x = 0; x < wend; x++) {
744                 color = colortab[*tmpsrc++ | (*tmppre++ << 4)];
745                 tcolor = color;
746                 tmptrg[0] = (uint8_t)color;
747                 color >>= 8;
748                 tmptrg[1] = (uint8_t)color;
749                 color >>= 8;
750                 tmptrg[2] = (uint8_t)color;
751                 tmptrg[3] = (uint8_t)tcolor;
752                 tcolor >>= 8;
753                 tmptrg[4] = (uint8_t)tcolor;
754                 tcolor >>= 8;
755                 tmptrg[5] = (uint8_t)tcolor;
756                 tmptrg += 6;
757             }
758             if (wlast) {
759                 color = colortab[*tmpsrc | (*tmppre << 4)];
760                 tmptrg[0] = (uint8_t)color;
761                 color >>= 8;
762                 tmptrg[1] = (uint8_t)color;
763                 color >>= 8;
764                 tmptrg[2] = (uint8_t)color;
765             }
766             if (y & 1) {
767                 pre = src - 1;
768                 src += pitchs;
769             }
770         } else {
771             if (wfirst) {
772                 *tmptrg++ = 0;
773                 *tmptrg++ = 0;
774                 *tmptrg++ = 0;
775             }
776             for (x = 0; x < wstart; x++) {
777                 tmptrg[0] = 0;
778                 tmptrg[1] = 0;
779                 tmptrg[2] = 0;
780                 tmptrg[3] = 0;
781                 tmptrg[4] = 0;
782                 tmptrg[5] = 0;
783                 tmptrg += 6;
784             }
785             for (x = 0; x < wfast; x++) {
786                 tmptrg[0] = 0;
787                 tmptrg[1] = 0;
788                 tmptrg[2] = 0;
789                 tmptrg[3] = 0;
790                 tmptrg[4] = 0;
791                 tmptrg[5] = 0;
792                 tmptrg[6] = 0;
793                 tmptrg[7] = 0;
794                 tmptrg[8] = 0;
795                 tmptrg[9] = 0;
796                 tmptrg[10] = 0;
797                 tmptrg[11] = 0;
798                 tmptrg[12] = 0;
799                 tmptrg[13] = 0;
800                 tmptrg[14] = 0;
801                 tmptrg[15] = 0;
802                 tmptrg[16] = 0;
803                 tmptrg[17] = 0;
804                 tmptrg[18] = 0;
805                 tmptrg[19] = 0;
806                 tmptrg[20] = 0;
807                 tmptrg[21] = 0;
808                 tmptrg[22] = 0;
809                 tmptrg[23] = 0;
810                 tmptrg += 24;
811             }
812             for (x = 0; x < wend; x++) {
813                 tmptrg[0] = 0;
814                 tmptrg[1] = 0;
815                 tmptrg[2] = 0;
816                 tmptrg[3] = 0;
817                 tmptrg[4] = 0;
818                 tmptrg[5] = 0;
819                 tmptrg += 6;
820             }
821             if (wlast) {
822                 tmptrg[0] = 0;
823                 tmptrg[1] = 0;
824                 tmptrg[2] = 0;
825             }
826         }
827         trg += pitcht;
828     }
829 }
830 
831 void render_32_2x2_08(const video_render_color_tables_t *color_tab,
832                       const uint8_t *src, uint8_t *trg,
833                       unsigned int width, const unsigned int height,
834                       const unsigned int xs, const unsigned int ys,
835                       const unsigned int xt, const unsigned int yt,
836                       const unsigned int pitchs, const unsigned int pitcht,
837                       const unsigned int doublescan)
838 {
839     const uint32_t *colortab = color_tab->physical_colors;
840     const uint8_t *pre;
841     const uint8_t *tmppre;
842     const uint8_t *tmpsrc;
843     uint32_t *tmptrg;
844     unsigned int x, y, wfirst, wstart, wfast, wend, wlast, yys;
845     register uint32_t color;
846 
847     src = src + pitchs * ys + xs;
848     trg = trg + pitcht * yt + (xt << 2);
849     yys = (ys << 1) | (yt & 1);
850     wfirst = xt & 1;
851     width -= wfirst;
852     wlast = width & 1;
853     width >>= 1;
854     if (width < 4) {
855         wstart = width;
856         wfast = 0;
857         wend = 0;
858     } else {
859         /* alignment: 4 pixels*/
860         wstart = (unsigned int)(4 - (vice_ptr_to_uint(trg) & 3));
861         wfast = (width - wstart) >> 2; /* fast loop for 4 pixel segments*/
862         wend = (width - wstart) & 0x03; /* do not forget the rest*/
863     }
864     pre = src - pitchs - 1;
865     for (y = yys; y < (yys + height); y++) {
866         tmppre = pre;
867         tmpsrc = src;
868         tmptrg = (uint32_t *)trg;
869         if ((y & 1) || doublescan) {
870             if (wfirst) {
871                 *tmptrg++ = colortab[*tmpsrc++ | (*tmppre++ << 4)];
872             }
873             for (x = 0; x < wstart; x++) {
874                 color = colortab[*tmpsrc++ | (*tmppre++ << 4)];
875                 *tmptrg++ = color;
876                 *tmptrg++ = color;
877             }
878             for (x = 0; x < wfast; x++) {
879                 color = colortab[tmpsrc[0] | (tmppre[0] << 4)];
880                 tmptrg[0] = color;
881                 tmptrg[1] = color;
882                 color = colortab[tmpsrc[1] | (tmppre[1] << 4)];
883                 tmptrg[2] = color;
884                 tmptrg[3] = color;
885                 color = colortab[tmpsrc[2] | (tmppre[2] << 4)];
886                 tmptrg[4] = color;
887                 tmptrg[5] = color;
888                 color = colortab[tmpsrc[3] | (tmppre[3] << 4)];
889                 tmptrg[6] = color;
890                 tmptrg[7] = color;
891                 tmpsrc += 4;
892                 tmppre += 4;
893                 tmptrg += 8;
894             }
895             for (x = 0; x < wend; x++) {
896                 color = colortab[*tmpsrc++ | (*tmppre++ << 4)];
897                 *tmptrg++ = color;
898                 *tmptrg++ = color;
899             }
900             if (wlast) {
901                 *tmptrg = colortab[*tmpsrc | (*tmppre << 4)];
902             }
903             if (y & 1) {
904                 pre = src - 1;
905                 src += pitchs;
906             }
907         } else {
908             color = colortab[0];
909             if (wfirst) {
910                 *tmptrg++ = color;
911             }
912             for (x = 0; x < wstart; x++) {
913                 *tmptrg++ = color;
914                 *tmptrg++ = color;
915             }
916             for (x = 0; x < wfast; x++) {
917                 tmptrg[0] = color;
918                 tmptrg[1] = color;
919                 tmptrg[2] = color;
920                 tmptrg[3] = color;
921                 tmptrg[4] = color;
922                 tmptrg[5] = color;
923                 tmptrg[6] = color;
924                 tmptrg[7] = color;
925                 tmptrg += 8;
926             }
927             for (x = 0; x < wend; x++) {
928                 *tmptrg++ = color;
929                 *tmptrg++ = color;
930             }
931             if (wlast) {
932                 *tmptrg = color;
933             }
934         }
935         trg += pitcht;
936     }
937 }
938 #endif
939