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