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