1 /*
2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * All rights reserved, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2011 OpenBOR Team
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include "types.h"
12
13 //with remap, work only under 8bit pixel format
putscreenx8p32(s_screen * dest,s_screen * src,int x,int y,int key,u32 * remap,u32 (* blendfp)(u32,u32))14 void putscreenx8p32(s_screen *dest, s_screen *src, int x, int y, int key, u32 *remap, u32(*blendfp)(u32, u32))
15 {
16 unsigned char *sp = src->data;
17 u32 *dp = (u32 *)dest->data;
18 int i;
19 int sw = src->width;
20 int sh = src->height;
21 int dw = dest->width;
22 int cw = sw, ch = sh;
23 int sox, soy;
24 int xmin = useclip ? clipx1 : 0,
25 xmax = useclip ? clipx2 : dest->width,
26 ymin = useclip ? clipy1 : 0,
27 ymax = useclip ? clipy2 : dest->height;
28
29 // Copy anything at all?
30 if(x >= xmax)
31 {
32 return;
33 }
34 if(sw + x <= xmin)
35 {
36 return;
37 }
38 if(y >= ymax)
39 {
40 return;
41 }
42 if(sh + y <= ymin)
43 {
44 return;
45 }
46
47 sox = 0;
48 soy = 0;
49
50 // Clip?
51 if(x < xmin)
52 {
53 sox = xmin - x;
54 cw -= sox;
55 }
56 if(y < ymin)
57 {
58 soy = ymin - y;
59 ch -= soy;
60 }
61
62 if(x + sw > xmax)
63 {
64 cw -= (x + sw) - xmax;
65 }
66 if(y + sh > ymax)
67 {
68 ch -= (y + sh) - ymax;
69 }
70
71 if(x < xmin)
72 {
73 x = xmin;
74 }
75 if(y < ymin)
76 {
77 y = ymin;
78 }
79
80 sp += (soy * sw + sox);
81 dp += (y * dw + x);
82
83 if(!remap)
84 {
85 remap = (u32 *)src->palette;
86 }
87
88 if(!remap)
89 {
90 return;
91 }
92
93 if(blendfp)
94 {
95 if(key) // color key, should be slower
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 // without colorkey
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 //without blend
133 {
134 if(key) // with color 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 // without colorkey
155 {
156 // Copy data
157 do
158 {
159 //u32pcpy(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 //32 to 32
blendscreen32(s_screen * dest,s_screen * src,int x,int y,int key,u32 (* blendfp)(u32,u32))175 void blendscreen32(s_screen *dest, s_screen *src, int x, int y, int key, u32(*blendfp)(u32, u32))
176 {
177 u32 *sp = (u32 *)src->data;
178 u32 *dp = (u32 *)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) // with colour 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 //without colour key
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 // without blend
284 {
285 if(key) // with colour 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 //without colour key
306 {
307 // Copy data
308 do
309 {
310 memcpy(dp, sp, cw << 2);
311 sp += sw;
312 dp += dw;
313 }
314 while(--ch);
315 }
316 }
317
318 }
319
320 // Scale screen
scalescreen32(s_screen * dest,s_screen * src)321 void scalescreen32(s_screen *dest, s_screen *src)
322 {
323 int sw, sh;
324 int dw, dh;
325 int dx, dy;
326 u32 *sp;
327 u32 *dp;
328 u32 *lineptr;
329 unsigned int xstep, ystep, xpos, ypos;
330 int pixelformat = src->pixelformat;
331
332 //if(dest->pixelformat!=pixelformat || pixelformat!=PIXEL_16) return;
333 if(dest->pixelformat != pixelformat)
334 {
335 return;
336 }
337
338 if(src == NULL || dest == NULL)
339 {
340 return;
341 }
342 sp = (u32 *)src->data;
343 dp = (u32 *)dest->data;
344
345 sw = src->width;
346 sh = src->height;
347 dw = dest->width;
348 dh = dest->height;
349
350 xstep = (sw << 16) / dw;
351 ystep = (sh << 16) / dh;
352
353 ypos = 0;
354 for(dy = 0; dy < dh; dy++)
355 {
356 lineptr = sp + ((ypos >> 16) * sw);
357 ypos += ystep;
358 xpos = 0;
359 for(dx = 0; dx < dw; dx++)
360 {
361 *dp = lineptr[xpos >> 16];
362 ++dp;
363 xpos += xstep;
364 }
365 }
366 }
367