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