1 /*
2  * sdl_darw.c  SDL draw to surface
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_draw.c,v 1.13 2003/01/25 01:34:50 chikama Exp $ */
22 
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <SDL/SDL.h>
29 #include <glib.h>
30 
31 #include "portab.h"
32 #include "system.h"
33 #include "sdl_core.h"
34 #include "sdl_private.h"
35 #include "font.h"
36 #include "ags.h"
37 #include "image.h"
38 #include "nact.h"
39 
40 static int fadestep[256] =
41 {0,1,3,4,6,7,9,10,12,14,15,17,18,20,21,23,25,26,28,29,31,32,34,36,37,39,40,
42  42,43,45,46,48,49,51,53,54,56,57,59,60,62,63,65,66,68,69,71,72,74,75,77,78,
43  80,81,83,84,86,87,89,90,92,93,95,96,97,99,100,102,103,105,106,108,109,110,
44  112,113,115,116,117,119,120,122,123,124,126,127,128,130,131,132,134,135,136,
45  138,139,140,142,143,144,146,147,148,149,151,152,153,155,156,157,158,159,161,
46  162,163,164,166,167,168,169,170,171,173,174,175,176,177,178,179,181,182,183,
47  184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,
48  203,204,205,206,207,208,209,210,211,211,212,213,214,215,216,217,217,218,219,
49  220,221,221,222,223,224,225,225,226,227,227,228,229,230,230,231,232,232,233,
50  234,234,235,235,236,237,237,238,238,239,239,240,241,241,242,242,243,243,244,
51  244,244,245,245,246,246,247,247,247,248,248,249,249,249,250,250,250,251,251,
52  251,251,252,252,252,252,253,253,253,253,254,254,254,254,254,254,255,255,255,
53  255,255,255,255,255,255,255,255,255,255,255};
54 
55 static SDL_Surface *s_fader;  /* fade in /out �� work surface */
56 
sdl_pal_check(void)57 static void sdl_pal_check(void) {
58 	if (nact->sys_pal_changed) {
59 		nact->sys_pal_changed = FALSE;
60 		sdl_setPallet(nact->sys_pal, 0, 256);
61 	}
62 }
63 
64 /* off-screen �λ����ΰ�� Main Window ��ž�� */
sdl_updateArea(MyRectangle * src,MyPoint * dst)65 void sdl_updateArea(MyRectangle *src, MyPoint *dst) {
66 	SDL_Rect rect_s, rect_d;
67 
68 	setRect(rect_s, src->x, src->y, src->width, src->height);
69 	setRect(rect_d, winoffset_x + dst->x, winoffset_y + dst->y, src->width, src->height);
70 
71 	SDL_BlitSurface(sdl_dib, &rect_s, sdl_display, &rect_d);
72 
73 	SDL_UpdateRect(sdl_display, winoffset_x + dst->x, winoffset_y + dst->y,
74 		       src->width, src->height);
75 }
76 
77 /* �����̹��� */
sdl_updateAll()78 static void sdl_updateAll() {
79 	SDL_Rect rect;
80 
81 	setRect(rect, winoffset_x, winoffset_y, view_w, view_h);
82 
83 	SDL_BlitSurface(sdl_dib, &sdl_view, sdl_display, &rect);
84 
85 	SDL_UpdateRect(sdl_display, 0, 0, 0, 0);
86 
87 }
88 
89 /* Color ��ʣ���Ļ��� */
sdl_setPallet(Pallet256 * pal,int src,int cnt)90 void sdl_setPallet(Pallet256 *pal, int src, int cnt) {
91 	int i;
92 
93 	for (i = 0; i < cnt; i++) {
94 		sdl_col[src + i].r = pal->red  [src + i];
95 		sdl_col[src + i].g = pal->green[src + i];
96 		sdl_col[src + i].b = pal->blue [src + i];
97 	}
98 
99 	if (sdl_dib->format->BitsPerPixel == 8) {
100 		SDL_SetColors(sdl_dib, sdl_col, src, cnt);
101 	}
102 }
103 
104 /* ��������� */
sdl_drawRectangle(int x,int y,int w,int h,int c)105 void sdl_drawRectangle(int x, int y, int w, int h, int c) {
106 	SDL_Rect rect;
107 
108 	sdl_pal_check();
109 
110 	if (c < 256 && sdl_dib->format->BitsPerPixel > 8)
111 		c = SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
112 
113 	setRect(rect,x,y,w,1);
114 	SDL_FillRect(sdl_dib, &rect, c);
115 
116 	setRect(rect,x,y,1,h);
117 	SDL_FillRect(sdl_dib, &rect, c);
118 
119 	setRect(rect,x,y+h-1,w,1);
120 	SDL_FillRect(sdl_dib, &rect, c);
121 
122 	setRect(rect,x+w-1,y,1,h);
123 	SDL_FillRect(sdl_dib, &rect, c);
124 }
125 
126 /* ����ɤ�Ĥ֤� */
sdl_fillRectangle(int x,int y,int w,int h,u_long c)127 void sdl_fillRectangle(int x, int y, int w, int h, u_long c) {
128 	SDL_Rect rect;
129 
130 	sdl_pal_check();
131 
132 	setRect(rect,x,y,w,h);
133 
134 	if (c < 256 && sdl_dib->format->BitsPerPixel > 8)
135 		c = SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
136 
137 	SDL_FillRect(sdl_dib, &rect, c);
138 }
139 
140 /* �ΰ襳�ԡ� */
sdl_copyArea(int sx,int sy,int w,int h,int dx,int dy)141 void sdl_copyArea(int sx,int sy, int w, int h, int dx, int dy) {
142 	SDL_Rect r_src, r_dst;
143 
144 	setRect(r_src, sx, sy, w, h);
145 	setRect(r_dst, dx, dy, w, h);
146 
147 	SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
148 }
149 
150 /*
151  * dib �˻���Υѥ�å� sp ��ȴ���ƥ��ԡ�
152  */
sdl_copyAreaSP(int sx,int sy,int w,int h,int dx,int dy,int sp)153 void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, int sp) {
154 	SDL_Rect r_src, r_dst;
155 
156 	sdl_pal_check();
157 
158 	if (sdl_dib->format->BitsPerPixel > 8 && sp < 256) {
159 		sp = SDL_MapRGB(sdl_dib->format,
160 				sdl_col[sp].r & 0xf8,
161 				sdl_col[sp].g & 0xfc,
162 				sdl_col[sp].b & 0xf8);
163 	}
164 
165 	SDL_SetColorKey(sdl_dib, SDL_SRCCOLORKEY, sp);
166 
167 	setRect(r_src, sx, sy, w, h);
168 	setRect(r_dst, dx, dy, w, h);
169 
170 	SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
171 	SDL_SetColorKey(sdl_dib, 0, 0);
172 }
173 
sdl_drawImage8_fromData(cgdata * cg,int dx,int dy,int w,int h)174 void sdl_drawImage8_fromData(cgdata *cg, int dx, int dy, int w, int h) {
175 	SDL_Surface *s;
176 	SDL_Rect r_src, r_dst;
177 
178 	s = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
179 
180 	SDL_LockSurface(s);
181 
182 #if 0  /* for broken cg */
183 	if (s->pitch == s->w) {
184 		memcpy(s->pixels, cg->pic, w * h);
185 	} else
186 #endif
187 	{
188 		int i = h;
189 		BYTE *p_src = (cg->pic + cg->data_offset), *p_dst = s->pixels;
190 
191 		while (i--) {
192 			memcpy(p_dst, p_src, w);
193 			p_dst += s->pitch;
194 			p_src += cg->width;
195 		}
196 	}
197 
198 	SDL_UnlockSurface(s);
199 
200 	sdl_pal_check();
201 
202 	if (sdl_dib->format->BitsPerPixel > 8 && cg->pal) {
203 		int i, i_st = 0, i_end = 256;
204 		SDL_Color *c = s->format->palette->colors;
205 		BYTE *r = cg->pal->red, *g = cg->pal->green, *b = cg->pal->blue;
206 
207 		if (cg->type == ALCG_VSP) {
208 			i_st  = (cg->vsp_bank << 4);
209 			i_end = i_st + 16;
210 			c += i_st;
211 		}
212 		for (i = i_st; i < i_end; i++) {
213 			c->r = *(r++);
214 			c->g = *(g++);
215 			c->b = *(b++);
216 			c++;
217 		}
218 	} else {
219 		memcpy(s->format->palette->colors, sdl_col, sizeof(SDL_Color) * 256);
220 	}
221 
222 	if (cg->spritecolor != -1) {
223 		SDL_SetColorKey(s, SDL_SRCCOLORKEY, cg->spritecolor);
224 	}
225 
226 	setRect(r_src,  0,  0, w, h);
227 	setRect(r_dst, dx, dy, w, h);
228 
229 	SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst);
230 	SDL_FreeSurface(s);
231 }
232 
233 /* ľ������ */
sdl_drawLine(int x1,int y1,int x2,int y2,u_long cl)234 void sdl_drawLine(int x1, int y1, int x2, int y2, u_long cl) {
235 
236 	sdl_pal_check();
237 
238 	if (sdl_dib->format->BitsPerPixel > 8 && cl < 256) {
239 		cl = SDL_MapRGB(sdl_dib->format,
240 				sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b);
241 	}
242 
243 	SDL_LockSurface(sdl_dib);
244 
245 	image_drawLine(sdl_dibinfo, x1, y1, x2, y2, cl);
246 
247 	SDL_UnlockSurface(sdl_dib);
248 
249 }
250 
surface2com(SDL_Surface * src)251 static agsurface_t* surface2com(SDL_Surface *src) {
252 	agsurface_t *dst = g_new(agsurface_t, 1);
253 
254 	dst->depth           = src->format->BitsPerPixel;
255 	dst->bytes_per_pixel = src->format->BytesPerPixel;
256 	dst->bytes_per_line  = src->pitch;
257 	dst->pixel   = src->pixels;
258 	dst->width  = src->w;
259 	dst->height = src->h;
260 
261 	return dst;
262 }
263 
com2surface(agsurface_t * src)264 static SDL_Surface *com2surface(agsurface_t *src) {
265 	SDL_Surface *s;
266 	int y;
267 	BYTE *sp, *dp;
268 
269 	s = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height, src->depth, 0, 0, 0, 0);
270 
271 	SDL_LockSurface(s);
272 
273 	sp = s->pixels;
274 	dp = src->pixel;
275 
276 	for (y = 0; y < src->height; y++) {
277 		memcpy(sp, dp, src->width);
278 		sp += s->pitch;
279 		dp += src->bytes_per_line;
280 	}
281 
282 	SDL_UnlockSurface(s);
283 	return s;
284 }
285 
com2alphasurface(agsurface_t * src,int cl)286 static SDL_Surface *com2alphasurface(agsurface_t *src, int cl) {
287 	SDL_Surface *s;
288 	int x,y;
289 	BYTE *sp, *dp;
290 	SDL_Rect r_src;
291 
292 	s = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height,
293 			     sdl_dib->format->BitsPerPixel <= 24 ? sdl_dib->format->BitsPerPixel+8:32,
294 			     sdl_dib->format->Rmask,sdl_dib->format->Gmask,
295 			     sdl_dib->format->Bmask,
296 			     sdl_dib->format->BitsPerPixel<24?0xFF0000:0xFF000000);
297 
298 	setRect(r_src, 0, 0, src->width, src->height);
299 	SDL_FillRect(s, &r_src,
300 		     SDL_MapRGB(sdl_dib->format, sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b));
301 
302 	SDL_LockSurface(s);
303 
304 	for (y = 0; y < src->height; y++) {
305 		sp = src->pixel + y * src->bytes_per_line;
306 		dp = s->pixels + y * s->pitch;
307 #ifndef WORDS_BIGENDIAN
308 		dp += s->format->BytesPerPixel -1;
309 #endif
310 
311 		for (x = 0; x < src->width; x++) {
312 			*dp =  R_ALPHA(*sp);
313 			sp++;
314 			dp += s->format->BytesPerPixel;
315 		}
316 	}
317 
318 	SDL_UnlockSurface(s);
319 	return s;
320 }
321 
322 
323 
324 /* msg is EUC */
sdl_drawString(int x,int y,char * msg,u_long col)325 int sdl_drawString(int x, int y, char *msg, u_long col) {
326 	int w;
327 
328 	sdl_pal_check();
329 
330 	if (sdl_font->self_drawable()) {
331 		w = sdl_font->draw_glyph(x, y, msg, col);
332 	} else {
333 		agsurface_t *glyph = sdl_font->get_glyph(msg);
334 		SDL_Rect r_src, r_dst;
335 
336 		if (glyph == NULL) return 0;
337 		setRect(r_src, 0, 0, glyph->width, glyph->height);
338 		setRect(r_dst, x, y, glyph->width, glyph->height);
339 		if (sdl_font->antialiase_on && sdl_dib->format->BitsPerPixel != 8) {
340 			SDL_Surface *src = com2alphasurface(glyph, col);
341 
342 			SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst);
343 			SDL_FreeSurface(src);
344 		} else {
345 			int i;
346 			SDL_Surface *src = com2surface(glyph);
347 			for (i = 1; i < 256; i++) {
348 				memcpy(src->format->palette->colors + i, &sdl_col[col],
349 				       sizeof(SDL_Color));
350 			}
351 			SDL_SetColorKey(src, SDL_SRCCOLORKEY, 0);
352 			SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst);
353 			SDL_FreeSurface(src);
354 		}
355 		w = glyph->width;
356 	}
357 
358 	return w;
359 }
360 
sdl_Mosaic(int sx,int sy,int w,int h,int dx,int dy,int slice)361 void sdl_Mosaic(int sx, int sy, int w, int h, int dx, int dy, int slice) {
362 
363 	SDL_LockSurface(sdl_dib);
364 
365 	image_Mosaic(sdl_dibinfo, sx, sy, w, h, dx, dy, slice);
366 
367 	SDL_UnlockSurface(sdl_dib);
368 }
369 
setBligtness(SDL_Surface * s,int val)370 static void setBligtness(SDL_Surface *s, int val) {
371 	int i;
372 	Pallet256 *pal = nact->sys_pal;
373 	Uint8 *r = pal->red, *g = pal->green, *b = pal->blue;
374 	SDL_Color *cl = sdl_col;
375 
376 	for (i = 0; i < 256; i++) {
377 		cl->r = (val * (*(r++))) / 255;
378 		cl->g = (val * (*(g++))) / 255;
379 		cl->b = (val * (*(b++))) / 255;
380 		cl++;
381 	}
382 	SDL_SetColors(s, sdl_col, 0, 256);
383 }
384 
setWhiteness(SDL_Surface * s,int val)385 static void setWhiteness(SDL_Surface *s, int val) {
386 	int i;
387 	Pallet256 *pal = nact->sys_pal;
388 	Uint8 *r = pal->red, *g = pal->green, *b = pal->blue;
389 	SDL_Color *cl = sdl_col;
390 
391 	for (i = 0; i < 256; i++) {
392 		cl->r = (((255- *r) * val) / 256) + *r; r++;
393 		cl->g = (((255- *g) * val) / 256) + *g; g++;
394 		cl->b = (((255- *b) * val) / 256) + *b; b++;
395 		cl++;
396 	}
397 	SDL_SetColors(s, sdl_col, 0, 256);
398 }
399 
fader_in(int n)400 static void fader_in(int n) {
401 	static agsurface_t *work, *disp;
402 
403 	if (n == 0) {
404 		SDL_Rect r_src, r_dst;
405 
406 		s_fader = SDL_AllocSurface(sdl_dib->flags, sdl_display->w, sdl_display->h,
407 					   sdl_display->format->BitsPerPixel, 0, 0, 0, 0);
408 
409 		if (sdl_display->format->BitsPerPixel == 8) {
410 			memcpy(s_fader->format->palette->colors,
411 			       sdl_display->format->palette->colors,
412 			       sizeof(SDL_Color) * 256);
413 		}
414 		setRect(r_src, view_x, view_y, view_w, view_h);
415 		setRect(r_dst, winoffset_x, winoffset_y, view_w, view_h);
416 		SDL_BlitSurface(sdl_dib, &r_src, s_fader, &r_dst);
417 
418 		work = surface2com(s_fader);
419 		disp = surface2com(sdl_display);
420 	}
421 
422 	if (n == 255) {
423 		SDL_FreeSurface(s_fader);
424 		sdl_updateAll();
425 		g_free(work);
426 		g_free(disp);
427 		return;
428 	}
429 
430 	SDL_LockSurface(s_fader);
431 	SDL_LockSurface(sdl_display);
432 
433 	image_fadeIn(work, disp, n / 16);
434 
435 	SDL_UnlockSurface(sdl_display);
436 	SDL_UnlockSurface(s_fader);
437 	SDL_UpdateRect(sdl_display,0,0,0,0);
438 }
439 
fader_out(int n,Uint32 c)440 static void fader_out(int n,Uint32 c) {
441 	static agsurface_t *disp;
442 
443 	if (n == 0) {
444 		disp = surface2com(sdl_display);
445 	}
446 
447 	if (n == 255) {
448 		SDL_FillRect(sdl_display, NULL, c);
449 		g_free(disp);
450 		return;
451 	}
452 
453 	SDL_LockSurface(sdl_display);
454 
455 	image_fadeOut(disp, (255 - n) / 16, c);
456 
457 	SDL_UnlockSurface(sdl_display);
458 
459 	SDL_UpdateRect(sdl_display,0,0,0,0);
460 }
461 
sdl_fade_blit(void)462 static __inline void sdl_fade_blit(void) {
463 	SDL_Rect r_dst;
464 	setRect(r_dst, winoffset_x, winoffset_y, view_w, view_h);
465 
466 	SDL_BlitSurface(sdl_dib, &sdl_view, sdl_display, &r_dst);
467 	SDL_UpdateRect(sdl_display, 0, 0, view_w, view_h);
468 }
469 
sdl_fadeIn(int step)470 void sdl_fadeIn(int step) {
471 	if (sdl_display->flags & SDL_HWPALETTE) {
472 		setBligtness(sdl_display, fadestep[step]);
473 	} else if (sdl_dib->format->BitsPerPixel == 8) {
474 		setBligtness(sdl_dib, fadestep[step]);
475 		sdl_fade_blit();
476 	} else {
477 		fader_in(step);
478 	}
479 }
480 
sdl_fadeOut(int step)481 void sdl_fadeOut(int step) {
482 	if (sdl_display->flags & SDL_HWPALETTE) {
483 		setBligtness(sdl_display, fadestep[255 - step]);
484 	} else if (sdl_dib->format->BitsPerPixel == 8) {
485 		setBligtness(sdl_dib, fadestep[255 - step]);
486 		sdl_fade_blit();
487 	} else {
488 		fader_out(step, SDL_MapRGB(sdl_display->format, 0, 0, 0));
489 	}
490 }
491 
sdl_whiteIn(int step)492 void sdl_whiteIn(int step) {
493 	if (sdl_display->flags & SDL_HWPALETTE) {
494 		setWhiteness(sdl_display, fadestep[step]);
495 	} else if (sdl_dib->format->BitsPerPixel == 8) {
496 		setWhiteness(sdl_dib, fadestep[255 - step]); /* ??? */
497 		sdl_fade_blit();
498 	} else {
499 		fader_in(step);
500 	}
501 }
502 
sdl_whiteOut(int step)503 void sdl_whiteOut(int step) {
504 	if (sdl_display->flags & SDL_HWPALETTE) {
505 		setWhiteness(sdl_display, fadestep[255 - step]);
506 	} else if (sdl_dib->format->BitsPerPixel == 8) {
507 		setWhiteness(sdl_dib, fadestep[step]); /* ??? */
508 		sdl_fade_blit();
509 	} else {
510 		fader_out(step, SDL_MapRGB(sdl_display->format, 255, 255, 255));
511 	}
512 }
513 
514 /*
515  * �����ϰϤ˥ѥ�å� col �� rate �γ��ǽŤͤ� CK1
516  */
sdl_wrapColor(int sx,int sy,int w,int h,int cl,int rate)517 void sdl_wrapColor(int sx, int sy, int w, int h, int cl, int rate) {
518 	SDL_Surface *s;
519 	SDL_Rect r_src,r_dst;
520 
521 	s = SDL_AllocSurface(SDL_SWSURFACE, w, h,
522 			     sdl_dib->format->BitsPerPixel, 0, 0, 0, 0);
523 
524 	if (s->format->BitsPerPixel == 8) {
525 		memcpy(s->format->palette->colors, sdl_dib->format->palette->colors,
526 		       sizeof(SDL_Color)*256);
527 	} else {
528 		cl = (cl < 256) ? SDL_MapRGB(sdl_dib->format, sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b) : cl;
529 	}
530 
531 	setRect(r_src, 0, 0, w, h);
532 	SDL_FillRect(s, &r_src, cl);
533 
534 	SDL_SetAlpha(s, RLEFLAG(SDL_SRCALPHA), R_ALPHA(rate));
535 	setRect(r_dst, sx, sy, w, h);
536 	SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst);
537 	SDL_FreeSurface(s);
538 }
539 
540 /* mask update �ޤ� */
sdl_maskupdate(int sx,int sy,int w,int h,int dx,int dy,int func,int step)541 void sdl_maskupdate(int sx, int sy, int w, int h, int dx, int dy, int func, int step) {
542 
543 	if (step == 256) {
544 		ags_copyArea(sx, sy, w, h, dx, dy);
545 		ags_updateArea(dx, dy, w, h);
546 	}
547 }
548