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 dh = dest->height;
23 	int cw = sw, ch = sh;
24 	int sox, soy;
25 
26 	// Copy anything at all?
27 	if(x >= dw) return;
28 	if(sw+x <= 0) return;
29 	if(y >= dh) return;
30 	if(sh+y <= 0) return;
31 
32 	if(!remap) remap = (u32*)src->palette;
33 
34 	if(!remap) return;
35 
36 	sox = 0;
37 	soy = 0;
38 
39 	// Clip?
40 	if(x<0) {sox = -x; cw += x;}
41 	if(y<0) {soy = -y; ch += y;}
42 
43 	if(x+sw > dw) cw -= (x+sw) - dw;
44 	if(y+sh > dh) ch -= (y+sh) - dh;
45 
46 	if(x<0) x = 0;
47 	if(y<0) y = 0;
48 
49 	sp += (soy*sw + sox);
50 	dp += (y*dw + x);
51 
52 	if(blendfp)
53 	{
54 		if(key) // color key, should be slower
55 		{
56 		    // blend
57 			do{
58 				i=cw-1;
59 				do
60 				{
61 				   if(sp[i])continue;
62 				   dp[i] = blendfp(remap[sp[i]], dp[i]);
63 				}while(i--);
64 				sp += sw;
65 				dp += dw;
66 			}while(--ch);
67 		}
68 		else // without colorkey
69 		{
70 		    // blend
71 			do{
72 				i=cw-1;
73 				do
74 				{
75 				   dp[i] = blendfp(remap[sp[i]], dp[i]);
76 				}while(i--);
77 				sp += sw;
78 				dp += dw;
79 			}while(--ch);
80 		}
81 	}
82 	else //without blend
83 	{
84 		if(key) // with color key
85 		{
86 			// Copy data
87 			do{
88 				i=cw-1;
89 				do
90 				{
91 				   if(!sp[i])continue;
92 				   dp[i] = remap[sp[i]];
93 				}while(i--);
94 				sp += sw;
95 				dp += dw;
96 			}while(--ch);
97 		}
98 		else // without colorkey
99 		{
100 			// Copy data
101 			do{
102 				u32pcpy(dp, sp, remap, cw);
103 				sp += sw;
104 				dp += dw;
105 			}while(--ch);
106 		}
107 	}
108 }
109 
110 //32 to 32
blendscreen32(s_screen * dest,s_screen * src,int x,int y,int key,u32 (* blendfp)(u32,u32))111 void blendscreen32(s_screen * dest, s_screen * src, int x, int y, int key, u32(*blendfp)(u32, u32))
112 {
113 	u32 *sp = (u32*)src->data;
114 	u32 *dp = (u32*)dest->data;
115 	int i;
116 	int sw = src->width;
117 	int sh = src->height;
118 	int dw = dest->width;
119 	int dh = dest->height;
120 	int cw = sw, ch = sh;
121 	int sox, soy;
122 
123 	// Copy anything at all?
124 	if(x >= dw) return;
125 	if(sw+x <= 0) return;
126 	if(y >= dh) return;
127 	if(sh+y <= 0) return;
128 
129 	sox = 0;
130 	soy = 0;
131 
132 	// Clip?
133 	if(x<0) {sox = -x; cw += x;}
134 	if(y<0) {soy = -y; ch += y;}
135 
136 	if(x+sw > dw) cw -= (x+sw) - dw;
137 	if(y+sh > dh) ch -= (y+sh) - dh;
138 
139 	if(x<0) x = 0;
140 	if(y<0) y = 0;
141 
142 	sp += (soy*sw + sox);
143 	dp += (y*dw + x);
144 
145 	if(blendfp)
146 	{
147 		if(key) // with colour key
148 		{
149 			// Copy data
150 			do{
151 				i=cw-1;
152 				do
153 				{
154 				   if(sp[i]==0) continue;
155 				   dp[i] = blendfp(sp[i], dp[i]);
156 				}while(i--);
157 				sp += sw;
158 				dp += dw;
159 			}while(--ch);
160 		}
161 		else //without colour key
162 		{
163 			// Copy data
164 			do{
165 				i=cw-1;
166 				do
167 				{
168 				   dp[i] = blendfp(sp[i], dp[i]);
169 				}while(i--);
170 				sp += sw;
171 				dp += dw;
172 			}while(--ch);
173 		}
174 	}
175 	else // without blend
176 	{
177 		if(key) // with colour key
178 		{
179 			// Copy data
180 			do{
181 				i=cw-1;
182 				do
183 				{
184 				   if(sp[i]==0) continue;
185 				   dp[i] = sp[i];
186 				}while(i--);
187 				sp += sw;
188 				dp += dw;
189 			}while(--ch);
190 		}
191 		else //without colour key
192 		{
193 			// Copy data
194 			do{
195 				memcpy(dp, sp, cw<<2);
196 				sp += sw;
197 				dp += dw;
198 			}while(--ch);
199 		}
200 	}
201 
202 }
203 
204 // Scale screen
scalescreen32(s_screen * dest,s_screen * src)205 void scalescreen32(s_screen * dest, s_screen * src)
206 {
207 	int sw, sh;
208 	int dw, dh;
209 	int dx, dy;
210 	u32 *sp;
211 	u32 *dp;
212 	u32 *lineptr;
213 	unsigned int xstep, ystep, xpos, ypos;
214 	int pixelformat = src->pixelformat;
215 
216 	//if(dest->pixelformat!=pixelformat || pixelformat!=PIXEL_16) return;
217 	if(dest->pixelformat!=pixelformat) return;
218 
219 	if(src==NULL || dest==NULL) return;
220 	sp = (u32*)src->data;
221 	dp = (u32*)dest->data;
222 
223 	sw = src->width;
224 	sh = src->height;
225 	dw = dest->width;
226 	dh = dest->height;
227 
228 	xstep = (sw<<16) / dw;
229 	ystep = (sh<<16) / dh;
230 
231 	ypos = 0;
232 	for(dy=0; dy<dh; dy++)
233 	{
234 		lineptr = sp + ((ypos>>16) * sw);
235 		ypos += ystep;
236 		xpos = 0;
237 		for(dx=0; dx<dw; dx++)
238 		{
239 			*dp = lineptr[xpos>>16];
240 			++dp;
241 			xpos += xstep;
242 		}
243 	}
244 }
245