1 /*
2  *  Copyright (C) 2002-2021  The DOSBox Team
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 
20 //TODO:
21 //Maybe just do the cache checking back into the simple scalers so they can
22 //just handle it all in one go, but this seems to work well enough for now
23 
24 #include "dosbox.h"
25 #include "render.h"
26 #include <string.h>
27 
28 Bit8u Scaler_Aspect[SCALER_MAXHEIGHT];
29 Bit16u Scaler_ChangedLines[SCALER_MAXHEIGHT];
30 Bitu Scaler_ChangedLineIndex;
31 
32 static union {
33 	 //The +1 is a at least for the normal scalers not needed. (-1 is enough)
34 	Bit32u b32 [SCALER_MAX_MUL_HEIGHT + 1][SCALER_MAXLINE_WIDTH];
35 	Bit16u b16 [SCALER_MAX_MUL_HEIGHT + 1][SCALER_MAXLINE_WIDTH];
36 	Bit8u   b8 [SCALER_MAX_MUL_HEIGHT + 1][SCALER_MAXLINE_WIDTH];
37 } scalerWriteCache;
38 //scalerFrameCache_t scalerFrameCache;
39 scalerSourceCache_t scalerSourceCache;
40 #if RENDER_USE_ADVANCED_SCALERS>1
41 scalerChangeCache_t scalerChangeCache;
42 #endif
43 
44 #define _conc2(A,B) A ## B
45 #define _conc3(A,B,C) A ## B ## C
46 #define _conc4(A,B,C,D) A ## B ## C ## D
47 #define _conc5(A,B,C,D,E) A ## B ## C ## D ## E
48 #define _conc7(A,B,C,D,E,F,G) A ## B ## C ## D ## E ## F ## G
49 
50 #define conc2(A,B) _conc2(A,B)
51 #define conc3(A,B,C) _conc3(A,B,C)
52 #define conc4(A,B,C,D) _conc4(A,B,C,D)
53 #define conc2d(A,B) _conc3(A,_,B)
54 #define conc3d(A,B,C) _conc5(A,_,B,_,C)
55 #define conc4d(A,B,C,D) _conc7(A,_,B,_,C,_,D)
56 
BituMove(void * _dst,const void * _src,Bitu size)57 static inline void BituMove( void *_dst, const void * _src, Bitu size) {
58 	Bitu * dst=(Bitu *)(_dst);
59 	const Bitu * src=(Bitu *)(_src);
60 	size/=sizeof(Bitu);
61 	for (Bitu x=0; x<size;x++)
62 		dst[x] = src[x];
63 }
64 
ScalerAddLines(Bitu changed,Bitu count)65 static inline void ScalerAddLines( Bitu changed, Bitu count ) {
66 	if ((Scaler_ChangedLineIndex & 1) == changed ) {
67 		Scaler_ChangedLines[Scaler_ChangedLineIndex] += count;
68 	} else {
69 		Scaler_ChangedLines[++Scaler_ChangedLineIndex] = count;
70 	}
71 	render.scale.outWrite += render.scale.outPitch * count;
72 }
73 
74 
75 #define BituMove2(_DST,_SRC,_SIZE)			\
76 {											\
77 	Bitu bsize=(_SIZE)/sizeof(Bitu);		\
78 	Bitu * bdst=(Bitu *)(_DST);				\
79 	Bitu * bsrc=(Bitu *)(_SRC);				\
80 	while (bsize--) *bdst++=*bsrc++;		\
81 }
82 
83 #define interp_w2(P0,P1,W0,W1)															\
84 	((((P0&redblueMask)*W0+(P1&redblueMask)*W1)/(W0+W1)) & redblueMask) |	\
85 	((((P0&  greenMask)*W0+(P1&  greenMask)*W1)/(W0+W1)) & greenMask)
86 #define interp_w3(P0,P1,P2,W0,W1,W2)														\
87 	((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2)/(W0+W1+W2)) & redblueMask) |	\
88 	((((P0&  greenMask)*W0+(P1&  greenMask)*W1+(P2&  greenMask)*W2)/(W0+W1+W2)) & greenMask)
89 #define interp_w4(P0,P1,P2,P3,W0,W1,W2,W3)														\
90 	((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2+(P3&redblueMask)*W3)/(W0+W1+W2+W3)) & redblueMask) |	\
91 	((((P0&  greenMask)*W0+(P1&  greenMask)*W1+(P2&  greenMask)*W2+(P3&  greenMask)*W3)/(W0+W1+W2+W3)) & greenMask)
92 
93 
94 #define CC scalerChangeCache
95 
96 /* Include the different rendering routines */
97 #define SBPP 8
98 #define DBPP 8
99 #include "render_templates.h"
100 #undef DBPP
101 #define DBPP 15
102 #include "render_templates.h"
103 #undef DBPP
104 #define DBPP 16
105 #include "render_templates.h"
106 #undef DBPP
107 #define DBPP 32
108 #include "render_templates.h"
109 #undef SBPP
110 #undef DBPP
111 
112 /* SBPP 9 is a special case with palette check support */
113 #define SBPP 9
114 #define DBPP 8
115 #include "render_templates.h"
116 #undef DBPP
117 #define DBPP 15
118 #include "render_templates.h"
119 #undef DBPP
120 #define DBPP 16
121 #include "render_templates.h"
122 #undef DBPP
123 #define DBPP 32
124 #include "render_templates.h"
125 #undef SBPP
126 #undef DBPP
127 
128 #define SBPP 15
129 #define DBPP 15
130 #include "render_templates.h"
131 #undef DBPP
132 #define DBPP 16
133 #include "render_templates.h"
134 #undef DBPP
135 #define DBPP 32
136 #include "render_templates.h"
137 #undef SBPP
138 #undef DBPP
139 
140 #define SBPP 16
141 #define DBPP 15
142 #include "render_templates.h"
143 #undef DBPP
144 #define DBPP 16
145 #include "render_templates.h"
146 #undef DBPP
147 #define DBPP 32
148 #include "render_templates.h"
149 #undef SBPP
150 #undef DBPP
151 
152 #define SBPP 24
153 #define DBPP 15
154 #include "render_templates.h"
155 #undef DBPP
156 #define DBPP 16
157 #include "render_templates.h"
158 #undef DBPP
159 #define DBPP 32
160 #include "render_templates.h"
161 #undef SBPP
162 #undef DBPP
163 
164 #define SBPP 32
165 #define DBPP 15
166 #include "render_templates.h"
167 #undef DBPP
168 #define DBPP 16
169 #include "render_templates.h"
170 #undef DBPP
171 #define DBPP 32
172 #include "render_templates.h"
173 #undef SBPP
174 #undef DBPP
175 
176 
177 #if RENDER_USE_ADVANCED_SCALERS>1
178 ScalerLineBlock_t ScalerCache = {
179 {	Cache_8_8,	Cache_8_15 ,	Cache_8_16 ,	Cache_8_32 },
180 {	        0,	Cache_15_15,	Cache_15_16,	Cache_15_32},
181 {	        0,	Cache_16_15,	Cache_16_16,	Cache_16_32},
182 {	        0,	Cache_24_15,	Cache_24_16,	Cache_24_32},
183 {	        0,	Cache_32_15,	Cache_32_16,	Cache_32_32},
184 {	Cache_8_8,	Cache_9_15 ,	Cache_9_16 ,	Cache_9_32 }
185 };
186 #endif
187 
188 ScalerSimpleBlock_t ScaleNormal1x = {
189 	"Normal",
190 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
191 	1,1,{
192 {	Normal1x_8_8_L,		Normal1x_8_15_L ,	Normal1x_8_16_L ,	Normal1x_8_32_L },
193 {	             0,		Normal1x_15_15_L,	Normal1x_15_16_L,	Normal1x_15_32_L},
194 {	             0,		Normal1x_16_15_L,	Normal1x_16_16_L,	Normal1x_16_32_L},
195 {	             0,		Normal1x_24_15_L,	Normal1x_24_16_L,	Normal1x_24_32_L},
196 {	             0,		Normal1x_32_15_L,	Normal1x_32_16_L,	Normal1x_32_32_L},
197 {	Normal1x_8_8_L,		Normal1x_9_15_L ,	Normal1x_9_16_L ,	Normal1x_9_32_L }
198 },{
199 {	Normal1x_8_8_R,		Normal1x_8_15_R ,	Normal1x_8_16_R ,	Normal1x_8_32_R },
200 {	             0,		Normal1x_15_15_R,	Normal1x_15_16_R,	Normal1x_15_32_R},
201 {	             0,		Normal1x_16_15_R,	Normal1x_16_16_R,	Normal1x_16_32_R},
202 {	             0,		Normal1x_24_15_R,	Normal1x_24_16_R,	Normal1x_24_32_R},
203 {	             0,		Normal1x_32_15_R,	Normal1x_32_16_R,	Normal1x_32_32_R},
204 {	Normal1x_8_8_R,		Normal1x_9_15_R ,	Normal1x_9_16_R ,	Normal1x_9_32_R }
205 }};
206 
207 ScalerSimpleBlock_t ScaleNormalDw = {
208 	"Normal",
209 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
210 	2,1,{
211 {	NormalDw_8_8_L,		NormalDw_8_15_L ,	NormalDw_8_16_L ,	NormalDw_8_32_L },
212 {	             0,		NormalDw_15_15_L,	NormalDw_15_16_L,	NormalDw_15_32_L},
213 {	             0,		NormalDw_16_15_L,	NormalDw_16_16_L,	NormalDw_16_32_L},
214 {	             0,		NormalDw_24_15_L,	NormalDw_24_16_L,	NormalDw_24_32_L},
215 {	             0,		NormalDw_32_15_L,	NormalDw_32_16_L,	NormalDw_32_32_L},
216 {	NormalDw_8_8_L,		NormalDw_9_15_L ,	NormalDw_9_16_L ,	NormalDw_9_32_L }
217 },{
218 {	NormalDw_8_8_R,		NormalDw_8_15_R ,	NormalDw_8_16_R ,	NormalDw_8_32_R },
219 {	             0,		NormalDw_15_15_R,	NormalDw_15_16_R,	NormalDw_15_32_R},
220 {	             0,		NormalDw_16_15_R,	NormalDw_16_16_R,	NormalDw_16_32_R},
221 {	             0,		NormalDw_24_15_R,	NormalDw_24_16_R,	NormalDw_24_32_R},
222 {	             0,		NormalDw_32_15_R,	NormalDw_32_16_R,	NormalDw_32_32_R},
223 {	NormalDw_8_8_R,		NormalDw_9_15_R ,	NormalDw_9_16_R ,	NormalDw_9_32_R }
224 }};
225 
226 ScalerSimpleBlock_t ScaleNormalDh = {
227 	"Normal",
228 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
229 	1,2,{
230 {	NormalDh_8_8_L,		NormalDh_8_15_L ,	NormalDh_8_16_L ,	NormalDh_8_32_L },
231 {	             0,		NormalDh_15_15_L,	NormalDh_15_16_L,	NormalDh_15_32_L},
232 {	             0,		NormalDh_16_15_L,	NormalDh_16_16_L,	NormalDh_16_32_L},
233 {	             0,		NormalDh_24_15_L,	NormalDh_24_16_L,	NormalDh_24_32_L},
234 {	             0,		NormalDh_32_15_L,	NormalDh_32_16_L,	NormalDh_32_32_L},
235 {	NormalDh_8_8_L,		NormalDh_9_15_L ,	NormalDh_9_16_L ,	NormalDh_9_32_L }
236 },{
237 {	NormalDh_8_8_R,		NormalDh_8_15_R ,	NormalDh_8_16_R ,	NormalDh_8_32_R },
238 {	             0,		NormalDh_15_15_R,	NormalDh_15_16_R,	NormalDh_15_32_R},
239 {	             0,		NormalDh_16_15_R,	NormalDh_16_16_R,	NormalDh_16_32_R},
240 {	             0,		NormalDh_24_15_R,	NormalDh_24_16_R,	NormalDh_24_32_R},
241 {	             0,		NormalDh_32_15_R,	NormalDh_32_16_R,	NormalDh_32_32_R},
242 {	NormalDh_8_8_R,		NormalDh_9_15_R ,	NormalDh_9_16_R ,	NormalDh_9_32_R }
243 }};
244 
245 ScalerSimpleBlock_t ScaleNormal2x = {
246 	"Normal2x",
247 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
248 	2,2,{
249 {	Normal2x_8_8_L,		Normal2x_8_15_L,	Normal2x_8_16_L,	Normal2x_8_32_L },
250 {	             0,		Normal2x_15_15_L,	Normal2x_15_16_L,	Normal2x_15_32_L},
251 {	             0,		Normal2x_16_15_L,	Normal2x_16_16_L,	Normal2x_16_32_L},
252 {	             0,		Normal2x_24_15_L,	Normal2x_24_16_L,	Normal2x_24_32_L},
253 {	             0,		Normal2x_32_15_L,	Normal2x_32_16_L,	Normal2x_32_32_L},
254 {	Normal2x_8_8_L,		Normal2x_9_15_L ,	Normal2x_9_16_L,	Normal2x_9_32_L }
255 },{
256 {	Normal2x_8_8_R,		Normal2x_8_15_R ,	Normal2x_8_16_R,	Normal2x_8_32_R },
257 {	             0,		Normal2x_15_15_R,	Normal2x_15_16_R,	Normal2x_15_32_R},
258 {	             0,		Normal2x_16_15_R,	Normal2x_16_16_R,	Normal2x_16_32_R},
259 {	             0,		Normal2x_24_15_R,	Normal2x_24_16_R,	Normal2x_24_32_R},
260 {	             0,		Normal2x_32_15_R,	Normal2x_32_16_R,	Normal2x_32_32_R},
261 {	Normal2x_8_8_R,		Normal2x_9_15_R ,	Normal2x_9_16_R,	Normal2x_9_32_R },
262 }};
263 
264 ScalerSimpleBlock_t ScaleNormal3x = {
265 	"Normal3x",
266 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
267 	3,3,{
268 {	Normal3x_8_8_L,		Normal3x_8_15_L ,	Normal3x_8_16_L ,	Normal3x_8_32_L },
269 {	             0,		Normal3x_15_15_L,	Normal3x_15_16_L,	Normal3x_15_32_L},
270 {	             0,		Normal3x_16_15_L,	Normal3x_16_16_L,	Normal3x_16_32_L},
271 {	             0,		Normal3x_24_15_L,	Normal3x_24_16_L,	Normal3x_24_32_L},
272 {	             0,		Normal3x_32_15_L,	Normal3x_32_16_L,	Normal3x_32_32_L},
273 {	Normal3x_8_8_L,		Normal3x_9_15_L ,	Normal3x_9_16_L ,	Normal3x_9_32_L }
274 },{
275 {	Normal3x_8_8_R,		Normal3x_8_15_R ,	Normal3x_8_16_R ,	Normal3x_8_32_R },
276 {	             0,		Normal3x_15_15_R,	Normal3x_15_16_R,	Normal3x_15_32_R},
277 {	             0,		Normal3x_16_15_R,	Normal3x_16_16_R,	Normal3x_16_32_R},
278 {	             0,		Normal3x_24_15_R,	Normal3x_24_16_R,	Normal3x_24_32_R},
279 {	             0,		Normal3x_32_15_R,	Normal3x_32_16_R,	Normal3x_32_32_R},
280 {	Normal3x_8_8_R,		Normal3x_9_15_R ,	Normal3x_9_16_R ,	Normal3x_9_32_R }
281 }};
282 
283 #if RENDER_USE_ADVANCED_SCALERS>0
284 ScalerSimpleBlock_t ScaleTV2x = {
285 	"TV2x",
286 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
287 	2,2,{
288 {	0,		TV2x_8_15_L ,	TV2x_8_16_L ,	TV2x_8_32_L },
289 {	0,		TV2x_15_15_L,	TV2x_15_16_L,	TV2x_15_32_L},
290 {	0,		TV2x_16_15_L,	TV2x_16_16_L,	TV2x_16_32_L},
291 {	0,		TV2x_24_15_L,	TV2x_24_16_L,	TV2x_24_32_L},
292 {	0,		TV2x_32_15_L,	TV2x_32_16_L,	TV2x_32_32_L},
293 {	0,		TV2x_9_15_L ,	TV2x_9_16_L ,	TV2x_9_32_L }
294 },{
295 {	0,		TV2x_8_15_R ,	TV2x_8_16_R ,	TV2x_8_32_R },
296 {	0,		TV2x_15_15_R,	TV2x_15_16_R,	TV2x_15_32_R},
297 {	0,		TV2x_16_15_R,	TV2x_16_16_R,	TV2x_16_32_R},
298 {	0,		TV2x_24_15_R,	TV2x_24_16_R,	TV2x_24_32_R},
299 {	0,		TV2x_32_15_R,	TV2x_32_16_R,	TV2x_32_32_R},
300 {	0,		TV2x_9_15_R ,	TV2x_9_16_R ,	TV2x_9_32_R }
301 }};
302 
303 ScalerSimpleBlock_t ScaleTV3x = {
304 	"TV3x",
305 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
306 	3,3,{
307 {	0,		TV3x_8_15_L ,	TV3x_8_16_L ,	TV3x_8_32_L },
308 {	0,		TV3x_15_15_L,	TV3x_15_16_L,	TV3x_15_32_L},
309 {	0,		TV3x_16_15_L,	TV3x_16_16_L,	TV3x_16_32_L},
310 {	0,		TV3x_24_15_L,	TV3x_24_16_L,	TV3x_24_32_L},
311 {	0,		TV3x_32_15_L,	TV3x_32_16_L,	TV3x_32_32_L},
312 {	0,		TV3x_9_15_L ,	TV3x_9_16_L ,	TV3x_9_32_L }
313 },{
314 {	0,		TV3x_8_15_R ,	TV3x_8_16_R ,	TV3x_8_32_R },
315 {	0,		TV3x_15_15_R,	TV3x_15_16_R,	TV3x_15_32_R},
316 {	0,		TV3x_16_15_R,	TV3x_16_16_R,	TV3x_16_32_R},
317 {	0,		TV3x_24_15_R,	TV3x_24_16_R,	TV3x_24_32_R},
318 {	0,		TV3x_32_15_R,	TV3x_32_16_R,	TV3x_32_32_R},
319 {	0,		TV3x_9_15_R ,	TV3x_9_16_R ,	TV3x_9_32_R }
320 }};
321 
322 ScalerSimpleBlock_t ScaleScan2x = {
323 	"Scan2x",
324 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
325 	2,2,{
326 {	0,		Scan2x_8_15_L ,	Scan2x_8_16_L ,	Scan2x_8_32_L },
327 {	0,		Scan2x_15_15_L,	Scan2x_15_16_L,	Scan2x_15_32_L},
328 {	0,		Scan2x_16_15_L,	Scan2x_16_16_L,	Scan2x_16_32_L},
329 {	0,		Scan2x_24_15_L,	Scan2x_24_16_L,	Scan2x_24_32_L},
330 {	0,		Scan2x_32_15_L,	Scan2x_32_16_L,	Scan2x_32_32_L},
331 {	0,		Scan2x_9_15_L ,	Scan2x_9_16_L ,	Scan2x_9_32_L }
332 },{
333 {	0,		Scan2x_8_15_R ,	Scan2x_8_16_R ,	Scan2x_8_32_R },
334 {	0,		Scan2x_15_15_R,	Scan2x_15_16_R,	Scan2x_15_32_R},
335 {	0,		Scan2x_16_15_R,	Scan2x_16_16_R,	Scan2x_16_32_R},
336 {	0,		Scan2x_24_15_R,	Scan2x_24_16_R,	Scan2x_24_32_R},
337 {	0,		Scan2x_32_15_R,	Scan2x_32_16_R,	Scan2x_32_32_R},
338 {	0,		Scan2x_9_15_R ,	Scan2x_9_16_R ,	Scan2x_9_32_R }
339 }};
340 
341 ScalerSimpleBlock_t ScaleScan3x = {
342 	"Scan3x",
343 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
344 	3,3,{
345 {	0,		Scan3x_8_15_L ,	Scan3x_8_16_L ,	Scan3x_8_32_L },
346 {	0,		Scan3x_15_15_L,	Scan3x_15_16_L,	Scan3x_15_32_L},
347 {	0,		Scan3x_16_15_L,	Scan3x_16_16_L,	Scan3x_16_32_L},
348 {	0,		Scan3x_24_15_L,	Scan3x_24_16_L,	Scan3x_24_32_L},
349 {	0,		Scan3x_32_15_L,	Scan3x_32_16_L,	Scan3x_32_32_L},
350 {	0,		Scan3x_9_15_L ,	Scan3x_9_16_L ,	Scan3x_9_32_L },
351 },{
352 {	0,		Scan3x_8_15_R ,	Scan3x_8_16_R ,	Scan3x_8_32_R },
353 {	0,		Scan3x_15_15_R,	Scan3x_15_16_R,	Scan3x_15_32_R},
354 {	0,		Scan3x_16_15_R,	Scan3x_16_16_R,	Scan3x_16_32_R},
355 {	0,		Scan3x_24_15_R,	Scan3x_24_16_R,	Scan3x_24_32_R},
356 {	0,		Scan3x_32_15_R,	Scan3x_32_16_R,	Scan3x_32_32_R},
357 {	0,		Scan3x_9_15_R ,	Scan3x_9_16_R ,	Scan3x_9_32_R }
358 }};
359 
360 ScalerSimpleBlock_t ScaleRGB2x = {
361 	"RGB2x",
362 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
363 	2,2,{
364 {	0,		RGB2x_8_15_L ,	RGB2x_8_16_L ,	RGB2x_8_32_L },
365 {	0,		RGB2x_15_15_L,	RGB2x_15_16_L,	RGB2x_15_32_L},
366 {	0,		RGB2x_16_15_L,	RGB2x_16_16_L,	RGB2x_16_32_L},
367 {	0,		RGB2x_24_15_L,	RGB2x_24_16_L,	RGB2x_24_32_L},
368 {	0,		RGB2x_32_15_L,	RGB2x_32_16_L,	RGB2x_32_32_L},
369 {	0,		RGB2x_9_15_L ,	RGB2x_9_16_L ,	RGB2x_9_32_L }
370 },{
371 {	0,		RGB2x_8_15_R ,	RGB2x_8_16_R ,	RGB2x_8_32_R },
372 {	0,		RGB2x_15_15_R,	RGB2x_15_16_R,	RGB2x_15_32_R},
373 {	0,		RGB2x_16_15_R,	RGB2x_16_16_R,	RGB2x_16_32_R},
374 {	0,		RGB2x_24_15_R,	RGB2x_24_16_R,	RGB2x_24_32_R},
375 {	0,		RGB2x_32_15_R,	RGB2x_32_16_R,	RGB2x_32_32_R},
376 {	0,		RGB2x_9_15_R ,	RGB2x_9_16_R ,	RGB2x_9_32_R }
377 }};
378 
379 ScalerSimpleBlock_t ScaleRGB3x = {
380 	"RGB3x",
381 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
382 	3,3,{
383 {	0,		RGB3x_8_15_L ,	RGB3x_8_16_L ,	RGB3x_8_32_L },
384 {	0,		RGB3x_15_15_L,	RGB3x_15_16_L,	RGB3x_15_32_L},
385 {	0,		RGB3x_16_15_L,	RGB3x_16_16_L,	RGB3x_16_32_L},
386 {	0,		RGB3x_24_15_L,	RGB3x_24_16_L,	RGB3x_24_32_L},
387 {	0,		RGB3x_32_15_L,	RGB3x_32_16_L,	RGB3x_32_32_L},
388 {	0,		RGB3x_9_15_L ,	RGB3x_9_16_L ,	RGB3x_9_32_L }
389 },{
390 {	0,		RGB3x_8_15_R ,	RGB3x_8_16_R ,	RGB3x_8_32_R },
391 {	0,		RGB3x_15_15_R,	RGB3x_15_16_R,	RGB3x_15_32_R},
392 {	0,		RGB3x_16_15_R,	RGB3x_16_16_R,	RGB3x_16_32_R},
393 {	0,		RGB3x_24_15_R,	RGB3x_24_16_R,	RGB3x_24_32_R},
394 {	0,		RGB3x_32_15_R,	RGB3x_32_16_R,	RGB3x_32_32_R},
395 {	0,		RGB3x_9_15_R ,	RGB3x_9_16_R ,	RGB3x_9_32_R }
396 }};
397 #endif
398 
399 
400 /* Complex scalers */
401 
402 #if RENDER_USE_ADVANCED_SCALERS>2
403 ScalerComplexBlock_t ScaleAdvMame2x ={
404 	"AdvMame2x",
405 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
406 	2,2,
407 {	AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L},
408 {	AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R}
409 };
410 
411 ScalerComplexBlock_t ScaleAdvMame3x = {
412 	"AdvMame3x",
413 	GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
414 	3,3,
415 {	AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L},
416 {	AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R}
417 };
418 
419 /* These need specific 15bpp versions */
420 ScalerComplexBlock_t ScaleHQ2x ={
421 	"HQ2x",
422 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
423 	2,2,
424 {	0,HQ2x_16_L,HQ2x_16_L,HQ2x_32_L},
425 {	0,HQ2x_16_R,HQ2x_16_R,HQ2x_32_R}
426 };
427 
428 ScalerComplexBlock_t ScaleHQ3x ={
429 	"HQ3x",
430 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
431 	3,3,
432 {	0,HQ3x_16_L,HQ3x_16_L,HQ3x_32_L},
433 {	0,HQ3x_16_R,HQ3x_16_R,HQ3x_32_R}
434 };
435 
436 ScalerComplexBlock_t ScaleSuper2xSaI ={
437 	"Super2xSaI",
438 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
439 	2,2,
440 {	0,Super2xSaI_16_L,Super2xSaI_16_L,Super2xSaI_32_L},
441 {	0,Super2xSaI_16_R,Super2xSaI_16_R,Super2xSaI_32_R}
442 };
443 
444 ScalerComplexBlock_t Scale2xSaI ={
445 	"2xSaI",
446 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
447 	2,2,
448 {	0,_2xSaI_16_L,_2xSaI_16_L,_2xSaI_32_L},
449 {	0,_2xSaI_16_R,_2xSaI_16_R,_2xSaI_32_R}
450 };
451 
452 ScalerComplexBlock_t ScaleSuperEagle ={
453 	"SuperEagle",
454 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
455 	2,2,
456 {	0,SuperEagle_16_L,SuperEagle_16_L,SuperEagle_32_L},
457 {	0,SuperEagle_16_R,SuperEagle_16_R,SuperEagle_32_R}
458 };
459 
460 ScalerComplexBlock_t ScaleAdvInterp2x = {
461 	"AdvInterp2x",
462 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
463 	2,2,
464 {	0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L},
465 {	0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R}
466 };
467 
468 ScalerComplexBlock_t ScaleAdvInterp3x = {
469 	"AdvInterp3x",
470 	GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_RGBONLY,
471 	3,3,
472 {	0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L},
473 {	0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R}
474 };
475 
476 #endif
477