1 /*
2 * OpenBOR - http://www.chronocrash.com
3 * -----------------------------------------------------------------------
4 * All rights reserved, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2014 OpenBOR Team
7 */
8
9 #include "globals.h"
10 #include "types.h"
11
12 //with remap, work only under 8bit pixel format
putscreenx8p16(s_screen * dest,s_screen * src,int x,int y,int key,unsigned short * remap,unsigned short (* blendfp)(unsigned short,unsigned short))13 void putscreenx8p16(s_screen *dest, s_screen *src, int x, int y, int key, unsigned short *remap, unsigned short(*blendfp)(unsigned short, unsigned short))
14 {
15 unsigned char *sp = src->data;
16 unsigned short *dp = (unsigned short *)dest->data;
17 int i;
18 int sw = src->width;
19 int sh = src->height;
20 int dw = dest->width;
21 int cw = sw, ch = sh;
22 int sox, soy;
23 int xmin = useclip ? clipx1 : 0,
24 xmax = useclip ? clipx2 : dest->width,
25 ymin = useclip ? clipy1 : 0,
26 ymax = useclip ? clipy2 : dest->height;
27
28 // Copy anything at all?
29 if(x >= xmax)
30 {
31 return;
32 }
33 if(sw + x <= xmin)
34 {
35 return;
36 }
37 if(y >= ymax)
38 {
39 return;
40 }
41 if(sh + y <= ymin)
42 {
43 return;
44 }
45
46 sox = 0;
47 soy = 0;
48
49 // Clip?
50 if(x < xmin)
51 {
52 sox = xmin - x;
53 cw -= sox;
54 }
55 if(y < ymin)
56 {
57 soy = ymin - y;
58 ch -= soy;
59 }
60
61 if(x + sw > xmax)
62 {
63 cw -= (x + sw) - xmax;
64 }
65 if(y + sh > ymax)
66 {
67 ch -= (y + sh) - ymax;
68 }
69
70 if(x < xmin)
71 {
72 x = xmin;
73 }
74 if(y < ymin)
75 {
76 y = ymin;
77 }
78
79 sp += (soy * sw + sox);
80 dp += (y * dw + x);
81
82
83 if(!remap)
84 {
85 remap = (unsigned short *)src->palette;
86 }
87
88 if(!remap)
89 {
90 return;
91 }
92
93 if(blendfp)
94 {
95 if(key)
96 {
97 // blend
98 do
99 {
100 i = cw - 1;
101 do
102 {
103 if(!sp[i])
104 {
105 continue;
106 }
107 dp[i] = blendfp(remap[sp[i]], dp[i]);
108 }
109 while(i--);
110 sp += sw;
111 dp += dw;
112 }
113 while(--ch);
114 }
115 else
116 {
117 // blend
118 do
119 {
120 i = cw - 1;
121 do
122 {
123 dp[i] = blendfp(remap[sp[i]], dp[i]);
124 }
125 while(i--);
126 sp += sw;
127 dp += dw;
128 }
129 while(--ch);
130 }
131 }
132 else
133 {
134 if(key)
135 {
136 // Copy data
137 do
138 {
139 i = cw - 1;
140 do
141 {
142 if(!sp[i])
143 {
144 continue;
145 }
146 dp[i] = remap[sp[i]];
147 }
148 while(i--);
149 sp += sw;
150 dp += dw;
151 }
152 while(--ch);
153 }
154 else
155 {
156 // Copy data
157 do
158 {
159 //u16pcpy(dp, sp, remap, cw);
160 i = cw - 1;
161 do
162 {
163 dp[i] = remap[sp[i]];
164 }
165 while(i--);
166 sp += sw;
167 dp += dw;
168 }
169 while(--ch);
170 }
171 }
172 }
173
174
blendscreen16(s_screen * dest,s_screen * src,int x,int y,int key,u16 (* blendfp)(u16,u16))175 void blendscreen16(s_screen *dest, s_screen *src, int x, int y, int key, u16(*blendfp)(u16, u16))
176 {
177 u16 *sp = (u16 *)src->data;
178 u16 *dp = (u16 *)dest->data;
179 int i;
180 int sw = src->width;
181 int sh = src->height;
182 int dw = dest->width;
183 int cw = sw, ch = sh;
184 int sox, soy;
185 int xmin = useclip ? clipx1 : 0,
186 xmax = useclip ? clipx2 : dest->width,
187 ymin = useclip ? clipy1 : 0,
188 ymax = useclip ? clipy2 : dest->height;
189
190 // Copy anything at all?
191 if(x >= xmax)
192 {
193 return;
194 }
195 if(sw + x <= xmin)
196 {
197 return;
198 }
199 if(y >= ymax)
200 {
201 return;
202 }
203 if(sh + y <= ymin)
204 {
205 return;
206 }
207
208 sox = 0;
209 soy = 0;
210
211 // Clip?
212 if(x < xmin)
213 {
214 sox = xmin - x;
215 cw -= sox;
216 }
217 if(y < ymin)
218 {
219 soy = ymin - y;
220 ch -= soy;
221 }
222
223 if(x + sw > xmax)
224 {
225 cw -= (x + sw) - xmax;
226 }
227 if(y + sh > ymax)
228 {
229 ch -= (y + sh) - ymax;
230 }
231
232 if(x < xmin)
233 {
234 x = xmin;
235 }
236 if(y < ymin)
237 {
238 y = ymin;
239 }
240
241 sp += (soy * sw + sox);
242 dp += (y * dw + x);
243
244 if(blendfp)
245 {
246 if(key)
247 {
248 // Copy data
249 do
250 {
251 i = cw - 1;
252 do
253 {
254 if(sp[i] == 0)
255 {
256 continue;
257 }
258 dp[i] = blendfp(sp[i], dp[i]);
259 }
260 while(i--);
261 sp += sw;
262 dp += dw;
263 }
264 while(--ch);
265 }
266 else
267 {
268 // Copy data
269 do
270 {
271 i = cw - 1;
272 do
273 {
274 dp[i] = blendfp(sp[i], dp[i]);
275 }
276 while(i--);
277 sp += sw;
278 dp += dw;
279 }
280 while(--ch);
281 }
282 }
283 else
284 {
285 if(key)
286 {
287 // Copy data
288 do
289 {
290 i = cw - 1;
291 do
292 {
293 if(sp[i] == 0)
294 {
295 continue;
296 }
297 dp[i] = sp[i];
298 }
299 while(i--);
300 sp += sw;
301 dp += dw;
302 }
303 while(--ch);
304 }
305 else
306 {
307 // Copy data
308 do
309 {
310 memcpy(dp, sp, cw << 1);
311 sp += sw;
312 dp += dw;
313 }
314 while(--ch);
315 }
316 }
317 }
318
319 // Scale screen
scalescreen16(s_screen * dest,s_screen * src)320 void scalescreen16(s_screen *dest, s_screen *src)
321 {
322 int sw, sh;
323 int dw, dh;
324 int dx, dy;
325 u16 *sp;
326 u16 *dp;
327 u16 *lineptr;
328 unsigned int xstep, ystep, xpos, ypos;
329 int pixelformat = src->pixelformat;
330
331 //if(dest->pixelformat!=pixelformat || pixelformat!=PIXEL_16) return;
332 if(dest->pixelformat != pixelformat)
333 {
334 return;
335 }
336
337 if(src == NULL || dest == NULL)
338 {
339 return;
340 }
341 sp = (u16 *)src->data;
342 dp = (u16 *)dest->data;
343
344 sw = src->width;
345 sh = src->height;
346 dw = dest->width;
347 dh = dest->height;
348
349 xstep = (sw << 16) / dw;
350 ystep = (sh << 16) / dh;
351
352 ypos = 0;
353 for(dy = 0; dy < dh; dy++)
354 {
355 lineptr = sp + ((ypos >> 16) * sw);
356 ypos += ystep;
357 xpos = 0;
358 for(dx = 0; dx < dw; dx++)
359 {
360 *dp = lineptr[xpos >> 16];
361 ++dp;
362 xpos += xstep;
363 }
364 }
365 }
366
367