1 /*
2  * sdl_image.c  image��� for SDL
3  *
4  * Copyright (C) 2000-   Fumihiko Murata <fmurata@p1.tcnet.ne.jp>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20 */
21 /* $Id: sdl_image.c,v 1.23 2003/07/20 19:30:16 chikama Exp $ */
22 
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <SDL/SDL.h>
28 #include <glib.h>
29 
30 #include "portab.h"
31 #include "system.h"
32 #include "sdl_private.h"
33 #include "cg.h"
34 #include "nact.h"
35 #include "alpha_plane.h"
36 #include "image.h"
37 
38 static unsigned char shlv_tbl[256*256];
39 
40 /*
41  * dib��Ǥγ��硦�̾����ԡ�
42  */
sdl_scaledCopyArea(SDL_Surface * src,SDL_Surface * dst,int sx,int sy,int sw,int sh,int dx,int dy,int dw,int dh,int mirror)43 void sdl_scaledCopyArea(SDL_Surface *src, SDL_Surface *dst, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int mirror) {
44 	float    a1, a2, xd, yd;
45 	int      *row, *col;
46 	int      x, y;
47 	SDL_Surface *ss;
48 	SDL_Rect r_src, r_dst;
49 
50 	if (src == NULL) {
51 		src = sdl_dib;
52 	}
53 
54 	if (dst == NULL) {
55 		dst = sdl_dib;
56 	}
57 	ss = SDL_AllocSurface(SDL_ANYFORMAT, dw, dh, dst->format->BitsPerPixel, 0, 0, 0, 0);
58 
59 	SDL_LockSurface(ss);
60 
61 	if (dst->format->BitsPerPixel == 8) {
62 		memcpy(ss->format->palette->colors, dst->format->palette->colors,
63 		       sizeof(SDL_Color) * 256);
64 	}
65 
66 	a1  = (float)sw / (float)dw;
67 	a2  = (float)sh / (float)dh;
68 	// src width �� dst width ��Ʊ���Ȥ������꤬����Τ�+1
69 	row = g_new0(int, dw+1);
70 	// 1�����������ƽ�������ʤ��� col[dw-1]��col[dw]��Ʊ���ˤʤ�
71 	// ��ǽ�������롣
72 	col = g_new0(int, dh+1);
73 
74 	if(mirror & 1){
75 		/*�岼ȿž added by  tajiri@wizard*/
76 		for (yd = sh-a2, y = 0; y<dh; y++) {
77 			col[y] = yd; yd -= a2;
78 		}
79 	} else {
80 		for (yd = 0.0, y = 0; y < dh; y++) {
81 			col[y] = yd; yd += a2;
82 		}
83 	}
84 	if(mirror & 2){
85 		/*����ȿž added by  tajiri@wizard*/
86 		for (xd = sw-a1, x = 0; x <dw; x++) {
87 			row[x] = xd; xd -= a1;
88 		}
89 	} else {
90 		for (xd = 0.0, x = 0; x < dw; x++) {
91 			row[x] = xd; xd += a1;
92 		}
93 	}
94 
95 #define sccp(type) \
96 { \
97 	type *p_ss = src->pixels + sx * src->format->BytesPerPixel + sy * src->pitch;\
98 	type *p_dd = ss->pixels, *p_src, *p_dst;\
99 	int l=src->pitch/src->format->BytesPerPixel; \
100 	int m=ss->pitch/ss->format->BytesPerPixel; \
101 	for (y = 0; y < dh; y++) { \
102 		p_src = p_ss + col[y] * l; \
103 		p_dst = p_dd + y * m; \
104 		for (x = 0; x < dw ; x++) { \
105 			*(p_dst++) = *(p_src + *(row + x)); \
106 		} \
107 	} \
108 }
109 	switch(dst->format->BytesPerPixel) {
110 	case 1:
111 		sccp(BYTE);
112 		break;
113 	case 2:
114 		sccp(WORD);
115 		break;
116 	case 3: {
117 		BYTE *p_ss=(BYTE *)(src->pixels+sx*src->format->BytesPerPixel+sy*src->pitch);
118 		BYTE *p_src=p_ss,*p_dd=ss->pixels, *p_dst;
119 		for (y = 0; y < dh; y++) {
120 			p_src = p_ss + col[y] * src->pitch;
121 			p_dst = p_dd + y      * ss->pitch;
122 			for (x = 0; x < dw ; x++) {
123 				*(p_dst)   = *(p_src + (*(row + x))*3    );
124 				*(p_dst+1) = *(p_src + (*(row + x))*3 + 1);
125 				*(p_dst+2) = *(p_src + (*(row + x))*3 + 2);
126 				p_dst+=3;
127 			}
128 		}
129 		break;
130 	}
131 	case 4:
132 		sccp(Uint32);
133 		break;
134 	}
135 
136 	SDL_UnlockSurface(ss);
137 
138 	setRect(r_src,  0,  0, dw, dh);
139 	setRect(r_dst, dx, dy, dw, dh);
140 	SDL_BlitSurface(ss, &r_src, dst, &r_dst);
141 
142 	SDL_FreeSurface(ss);
143 
144 	g_free(row);
145 	g_free(col);
146 }
147 
sdl_zoom(int x,int y,int w,int h)148 void sdl_zoom(int x, int y, int w, int h) {
149 	sdl_scaledCopyArea(sdl_dib, sdl_display, x, y, w, h, 0, 0, view_w, view_h, 0);
150 	SDL_UpdateRect(sdl_display, 0, 0, view_w, view_h);
151 }
152 
153 
154 /*
155  * dib��16bitCG������
156  */
sdl_drawImage16_fromData(cgdata * cg,int dx,int dy,int w,int h)157 void sdl_drawImage16_fromData(cgdata *cg, int dx, int dy, int w, int h) {
158 	/* draw alpha pixel */
159 	SDL_Surface *s;
160 	SDL_Rect r_src,r_dst;
161 
162 	if (cg->alpha != NULL && cg->spritecolor != -1) {
163 		unsigned short *p_ds, *p_src = (WORD *)(cg->pic + cg->data_offset);
164 		unsigned short *p_dst;
165 		BYTE *a_src = cg->alpha;
166 		BYTE *adata = GETOFFSET_ALPHA(sdl_dibinfo, dx, dy);
167 		int x, y, l;
168 
169 #ifndef WORDS_BIGENDIAN
170 		s = SDL_AllocSurface(SDL_ANYFORMAT, w, h, 32,
171 				     0xf800, 0x07e0, 0x001f, 0xFF0000);
172 #else
173 		s = SDL_AllocSurface(SDL_ANYFORMAT,w, h, 32,
174 				     0xf800, 0x07e0, 0x001f, 0xFF000000);
175 #endif
176 #if 0
177 #ifdef HAVE_SDLRLE
178 		SDL_SetAlpha(s,RLEFLAG(SDL_SRCALPHA),0);
179 #endif
180 #endif
181 		SDL_LockSurface(s);
182 		p_ds = s->pixels;
183 		l = s->pitch/2;
184 		for (y = 0; y < h; y++) {
185 			p_dst = p_ds;
186 			memcpy(adata, a_src, w);
187 			for (x = 0; x < w; x++) {
188 #ifndef WORDS_BIGENDIAN
189 				*(p_dst++) = *(p_src++);
190 				*(p_dst++) = R_ALPHA(*(a_src++));
191 #else
192 				*(p_dst++) = R_ALPHA(*(a_src++));
193 				*(p_dst++) = *(p_src++);
194 #endif
195 			}
196 			p_ds  += l;
197 			adata += sdl_dibinfo->width;
198 		}
199 		SDL_UnlockSurface(s);
200 	} else {
201 		BYTE *p_dst;
202 		unsigned short *p_src = (WORD *)(cg->pic + cg->data_offset);
203 		int i, l = w * 2;
204 
205 		s = SDL_AllocSurface(SDL_ANYFORMAT, w, h, 16, 0, 0, 0, 0);
206 		SDL_LockSurface(s);
207 		p_dst = s->pixels;
208 		for (i = 0; i < h; i++) {
209 			memcpy(p_dst, p_src, l);
210 			p_dst += s->pitch;
211 			p_src += cg->width;
212 		}
213 		if (cg->alpha) {
214 			BYTE *a_src = cg->alpha;
215 			BYTE *adata = GETOFFSET_ALPHA(sdl_dibinfo, dx, dy);
216 
217 			for (i = 0; i < h; i++) {
218 				memcpy(adata, a_src, w);
219 				adata += sdl_dibinfo->width;
220 				a_src += cg->width;
221 			}
222 		}
223 		SDL_UnlockSurface(s);
224 	}
225 	setRect(r_src,  0,  0, w, h);
226 	setRect(r_dst, dx, dy, w, h);
227 	SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst);
228 	SDL_FreeSurface(s);
229 }
230 
231 /*
232  * 16bit���Ѥ� dib �λ����ΰ襳�ԡ� alpha�Ĥ�
233  */
sdl_shadow_init(void)234 void sdl_shadow_init(void) {
235 	int i, j;
236 	unsigned char *c = shlv_tbl;
237 
238 	for (i = 0; i < 255; i++) {
239 		for (j = 0; j < 256; j++) {
240 			*(c++) = (unsigned char)(R_ALPHA(i * j / 255));
241 		}
242 	}
243 }
244 
sdl_copyAreaSP16_shadow(int sx,int sy,int w,int h,int dx,int dy,int lv)245 void sdl_copyAreaSP16_shadow(int sx, int sy, int w, int h, int dx, int dy, int lv) {
246 	BYTE *adata = GETOFFSET_ALPHA(sdl_dibinfo, sx, sy);
247 	BYTE *p_src, *p_dst, *p_ds;
248 
249 	SDL_Surface *s = SDL_AllocSurface(SDL_ANYFORMAT, w, h, 32, sdl_dib->format->Rmask,
250 					  sdl_dib->format->Gmask, sdl_dib->format->Bmask,
251 					  0xFF000000);
252 	SDL_Rect r_src, r_dst;
253 	int x, y;
254 
255 	setRect(r_dst, sx, sy, w, h);
256 	setRect(r_src,  0,  0, w, h);
257 	SDL_BlitSurface(sdl_dib, &r_dst, s, &r_src);
258 
259 	SDL_LockSurface(s);
260 
261 #ifndef WORDS_BIGENDIAN
262 	p_ds = s->pixels + 3;
263 #else
264 	p_ds = s->pixels;
265 #endif
266 	switch(lv) {
267 	case 255:
268 		for (y = 0; y < h; y++) {
269 			p_src = adata;
270 			p_dst = p_ds;
271 			for (x = 0; x < w; x++) {
272 				*p_dst = R_ALPHA(*(p_src++));
273 				p_dst += 4;
274 			}
275 			adata += sdl_dibinfo->width;
276 			p_ds  += s->pitch;
277 		}
278 		break;
279 	default:
280 		{
281 			unsigned char *lvtbl = shlv_tbl + lv * 256;
282 			for (y = 0; y < h; y++) {
283 				p_src = adata;
284 				p_dst = p_ds;
285 				for (x = 0; x < w; x++) {
286 					*p_dst = lvtbl[(int)(*(p_src++))];
287 					p_dst += 4;
288 				}
289 				adata += sdl_dibinfo->width;
290 				p_ds += s->pitch;
291 			}
292 		}
293 		break;
294 	}
295 	SDL_UnlockSurface(s);
296 #if 0
297 #ifdef HAVE_SDLRLE
298 	SDL_SetAlpha(s, RLEFLAG(SDL_SRCALPHA), 0);
299 #endif
300 #endif
301 
302 	setRect(r_dst, dx, dy, w, h);
303 	SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst);
304 	SDL_FreeSurface(s);
305 }
306 
sdl_copyAreaSP16_alphaBlend(int sx,int sy,int w,int h,int dx,int dy,int lv)307 void sdl_copyAreaSP16_alphaBlend(int sx, int sy, int w, int h, int dx, int dy, int lv) {
308 	SDL_Rect r_src, r_dst;
309 
310 	setRect(r_src, sx, sy, w, h);
311 	setRect(r_dst, dx, dy, w, h);
312 	SDL_SetAlpha(sdl_dib, RLEFLAG(SDL_SRCALPHA), R_ALPHA(lv));
313 	SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
314 	SDL_SetAlpha(sdl_dib, 0, 0);
315 }
316 
317 #define copyAreaSP_level(fn, cn, v) void sdl_copyAreaSP16_##fn(int sx, int sy, int w, int h, int dx, int dy, int lv) { \
318 	SDL_Rect r_src,r_dst; \
319 	setRect(r_src, sx, sy, w, h); \
320 	setRect(r_dst, dx, dy, w, h); \
321 	SDL_SetAlpha(sdl_dib, RLEFLAG(SDL_SRCALPHA), v); \
322 	SDL_FillRect(sdl_dib, &r_dst, cn); \
323 	SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst); \
324 	SDL_SetAlpha(sdl_dib, 0, 0); \
325 }
326 
327 #ifdef HAVE_SDLRALPHA
328 copyAreaSP_level(alphaLevel, 0, lv);
329 copyAreaSP_level(whiteLevel, sdl_white, 255 - lv);
330 #else
331 copyAreaSP_level(alphaLevel, 0, 255 - lv);
332 copyAreaSP_level(whiteLevel, sdl_white, lv);
333 #endif
334 
sdl_copy_from_alpha(int sx,int sy,int w,int h,int dx,int dy,ALPHA_DIB_COPY_TYPE flag)335 void sdl_copy_from_alpha(int sx, int sy, int w, int h, int dx, int dy, ALPHA_DIB_COPY_TYPE flag) {
336 	SDL_LockSurface(sdl_dib);
337 	image_copy_from_alpha(nact->ags.dib, sx, sy, w, h, dx, dy, flag);
338 	SDL_UnlockSurface(sdl_dib);
339 }
340 
sdl_copy_to_alpha(int sx,int sy,int w,int h,int dx,int dy,ALPHA_DIB_COPY_TYPE flag)341 void sdl_copy_to_alpha(int sx, int sy, int w, int h, int dx, int dy, ALPHA_DIB_COPY_TYPE flag) {
342 	SDL_LockSurface(sdl_dib);
343 	image_copy_to_alpha(nact->ags.dib, sx, sy, w, h, dx, dy, flag);
344 	SDL_UnlockSurface(sdl_dib);
345 }
346 
347 /*
348  * dib �Υԥ������������
349  */
sdl_getPixel(int x,int y,Pallet * cell)350 void sdl_getPixel(int x, int y, Pallet *cell) {
351 	SDL_LockSurface(sdl_dib);
352 
353 	if (sdl_dib->format->BitsPerPixel == 8) {
354 		BYTE *rt = setOffset(sdl_dib, x, y);
355 		cell->pixel = *rt;
356 	} else {
357 		Uint32 cl=0;
358 		BYTE *p = setOffset(sdl_dib, x, y);
359 
360 		switch (sdl_dib->format->BytesPerPixel) {
361 		case 2:
362 			{
363 				unsigned short *pp = (unsigned short *)p;
364 				cl = *pp;
365 			}
366 			break;
367 		case 3:
368 #ifndef WORDS_BIGENDIAN
369 			cl = (p[2]<<16)+(p[1]<<8) + p[0];
370 #else
371 			cl = (p[0]<<16)+(p[1]<<8) + p[2];
372 #endif
373 			break;
374 		case 4:
375 			{
376 				Uint32 *pp = (Uint32 *)p;
377 				cl = *pp;
378 			}
379 			break;
380 		}
381 		SDL_GetRGB(cl, sdl_dib->format, &cell->r, &cell->g, &cell->b);
382 	}
383 
384 	SDL_UnlockSurface(sdl_dib);
385 }
386 
387 /*
388  * dib �����ΰ���ڤ�Ф�
389  */
sdl_saveRegion(int x,int y,int w,int h)390 SDL_Surface* sdl_saveRegion(int x, int y, int w, int h) {
391 	SDL_Surface *s;
392 	SDL_Rect r_src, r_dst;
393 
394 	s = SDL_AllocSurface(sdl_dib->flags, w, h, sdl_dib->format->BitsPerPixel,
395 			     sdl_dib->format->Rmask, sdl_dib->format->Gmask,
396 			     sdl_dib->format->Bmask, sdl_dib->format->Amask);
397 	if (sdl_dib->format->BitsPerPixel == 8)
398 		memcpy(s->format->palette->colors, sdl_dib->format->palette->colors,
399 		       sizeof(SDL_Color) * sdl_dib->format->palette->ncolors);
400 	setRect(r_src, x, y, w, h);
401 	setRect(r_dst, 0, 0, w, h);
402 	SDL_BlitSurface(sdl_dib, &r_src, s, &r_dst);
403 	return s;
404 }
405 
406 /*
407  * dib �˥����֤����ΰ�����
408  */
sdl_putRegion(SDL_Surface * src,int x,int y)409 void sdl_putRegion(SDL_Surface *src, int x, int y) {
410 	SDL_Rect r_src,r_dst;
411 
412 	setRect(r_src, 0, 0, src->w, src->h);
413 	setRect(r_dst, x, y, src->w, src->h);
414 
415 	SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst);
416 }
417 
418 /*
419  * dib �˥����֤����ΰ褫�饳�ԡ�
420  */
sdl_CopyRegion(SDL_Surface * src,int sx,int sy,int w,int h,int dx,int dy)421 void sdl_CopyRegion(SDL_Surface *src, int sx, int sy, int w,int h, int dx, int dy) {
422 	SDL_Rect r_src,r_dst;
423 
424 	setRect(r_src, sx, sy, w, h);
425 	setRect(r_dst, dx, dy, w, h);
426 
427 	SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst);
428 }
429 
430 /*
431  * dib �� dst������塢�����
432  */
sdl_restoreRegion(SDL_Surface * src,int x,int y)433 void sdl_restoreRegion(SDL_Surface *src, int x, int y) {
434 	sdl_putRegion(src, x ,y);
435 	SDL_FreeSurface(src);
436 }
437 
sdl_sync()438 void sdl_sync() {
439 	// imageXX����surface���ľ������ݤˡ�������lock/unlock��
440 	// �Ϥ��ޤʤ��Ȥ����ʤ�������ɡ�lock����Ф���ޤǥ��塼�����ä�
441 	// ���� SDL�����ν��������٤ƽ����ͽ�ۤ����Τ�Xsync��Ʊ�ͤ�
442 	// ���̤�����Ȼפ���������Unlock���Ƥ���Τ���Ʊ����imageXX�ν�����
443 	// ��SDL������̿�᤬�����ǽ���⤢�뤬��X11�ǤϤ��֤�����ס�
444 	SDL_LockSurface(sdl_dib);
445 	SDL_UnlockSurface(sdl_dib);
446 }
447