1 /* -*- C++ -*-
2 *
3 * PonscripterLabel_image.cpp - Image processing in Ponscripter
4 *
5 * Copyright (c) 2001-2008 Ogapee (original ONScripter, of which this
6 * is a fork).
7 *
8 * ogapee@aqua.dti2.ne.jp
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA
24 */
25
26 #include "PonscripterLabel.h"
27 #include <cstdio>
28
29 #include "graphics_common.h"
30
loadImage(const pstring & filename,bool * has_alpha,bool twox,bool isflipped)31 SDL_Surface *PonscripterLabel::loadImage(const pstring& filename,
32 bool *has_alpha, bool twox, bool isflipped)
33 {
34 if (!filename) return NULL;
35
36 if (lastRenderEvent < RENDER_EVENT_LOAD_IMAGE) { lastRenderEvent = RENDER_EVENT_LOAD_IMAGE; }
37
38 SDL_Surface *tmp = NULL, *tmpb = NULL;
39 int location = BaseReader::ARCHIVE_TYPE_NONE;
40
41 CBStringList filenames = filename.split("&", 4);
42
43 if (filenames[0][0] == '>')
44 tmp = createRectangleSurface(filenames[0]);
45 else
46 tmp = createSurfaceFromFile(filenames[0], &location);
47
48 if (tmp == NULL) return NULL;
49
50 bool has_colorkey = false;
51
52 if ( has_alpha ){
53 *has_alpha = (tmp->format->Amask != 0);
54 if (!(*has_alpha) && (tmp->flags & SDL_TRUE)){
55 has_colorkey = true;
56 if (tmp->format->palette){
57 //palette will be converted to RGBA, so don't do colorkey check
58 has_colorkey = false;
59 }
60 *has_alpha = true;
61 }
62 }
63
64 SDL_Surface *ret = SDL_ConvertSurface( tmp, image_surface->format, SDL_SWSURFACE );
65 SDL_FreeSurface( tmp );
66
67 SDL_Rect subimage_rect;
68 CBStringList fileparts;
69 pstring sub_filename;
70
71 int num_images = filenames.size();
72 if (num_images > 1) {
73 for (int x = 1; x < num_images; x++) {
74 sub_filename = filenames[x];
75 fileparts = sub_filename.split(",", 3);
76 tmp = createSurfaceFromFile(fileparts[2], &location);
77 tmpb = SDL_ConvertSurface( tmp, image_surface->format, SDL_SWSURFACE );
78 subimage_rect.x = fileparts[0];
79 subimage_rect.y = fileparts[1];
80 subimage_rect.w = tmpb->w;
81 subimage_rect.h = tmpb->h;
82 SDL_BlitScaled(tmpb, NULL, ret, &subimage_rect);
83 SDL_FreeSurface( tmp );
84 SDL_FreeSurface( tmpb );
85 }
86 }
87
88 // Hack to detect when a PNG image is likely to have an old-style
89 // mask. We assume that an old-style mask is intended if the
90 // image either has no alpha channel, or the alpha channel it has
91 // is completely opaque. This behaviour can be overridden with
92 // the --force-png-alpha and --force-png-nscmask command-line
93 // options.
94 if (has_alpha && *has_alpha) {
95 if (png_mask_type == PNG_MASK_USE_NSCRIPTER)
96 *has_alpha = false;
97 else if (png_mask_type == PNG_MASK_AUTODETECT) {
98 SDL_LockSurface(ret);
99 const Uint32 aval = *(Uint32*)ret->pixels & ret->format->Amask;
100 if (aval != ret->format->Amask) goto breakalpha;
101 *has_alpha = false;
102 for (int y=0; y<ret->h; ++y) {
103 Uint32* pixbuf = (Uint32*)((char*)ret->pixels + y * ret->pitch);
104 for (int x=ret->w; x>0; --x, ++pixbuf) {
105 // Resolving ambiguity per Tatu's patch, 20081118.
106 // I note that this technically changes the meaning of the
107 // code, since != is higher-precedence than &, but this
108 // version is obviously what I intended when I wrote this.
109 // Has this been broken all along? :/ -- Haeleth
110 if ((*pixbuf & ret->format->Amask) != aval) {
111 *has_alpha = true;
112 goto breakalpha;
113 }
114 }
115 }
116 breakalpha:
117 if (!*has_alpha && has_colorkey) {
118 // has a colorkey, so run a match against rgb values
119 const Uint32 aval = SDL_TRUE & ~(ret->format->Amask);
120 if (aval == (*(Uint32*)ret->pixels & ~(ret->format->Amask)))
121 goto breakkey;
122 *has_alpha = false;
123 for (int y=0; y<ret->h; ++y) {
124 Uint32* pixbuf = (Uint32*)((char*)ret->pixels + y * ret->pitch);
125 for (int x=ret->w; x>0; --x, ++pixbuf) {
126 if ((*pixbuf & ~(ret->format->Amask)) == aval) {
127 *has_alpha = true;
128 goto breakkey;
129 }
130 }
131 }
132 }
133 breakkey:
134 SDL_UnlockSurface(ret);
135 }
136 }
137
138
139 if (isflipped) {
140 SDL_Surface *retf = SDL_CreateRGBSurface(0, ret->w, ret->h, BPP, RMASK, GMASK, BMASK, AMASK);
141 Uint32* sourcepix;
142 Uint32* destpix;
143 for (int y=0; y<ret->h; ++y) {
144 sourcepix = (Uint32*)((char*)ret->pixels + y * ret->pitch);
145 destpix = (Uint32*)((char*)retf->pixels + (y + 1) * ret->pitch);
146 destpix--;
147 for (int x = 0; x < ret->w; x++, sourcepix++, destpix--) {
148 *destpix = *sourcepix;
149 }
150 }
151 // swap pointer to new surface
152 SDL_FreeSurface( ret );
153 ret = retf;
154 }
155
156 if (res_multiplier != 1) {
157 int multiplier = twox ? 1 : res_multiplier;
158 SDL_Surface *retb = SDL_CreateRGBSurface(0, ret->w * multiplier, ret->h * multiplier, BPP, RMASK, GMASK, BMASK, AMASK);
159 SDL_BlitScaled(ret, NULL, retb, NULL);
160
161 SDL_FreeSurface( ret );
162 return retb;
163 } else {
164 return ret;
165 }
166
167 }
168
createRectangleSurface(const char * filename)169 SDL_Surface *PonscripterLabel::createRectangleSurface(const char* filename)
170 {
171 int c=1, w=0, h=0;
172 while (filename[c] != 0x0a && filename[c] != 0x00){
173 if (filename[c] >= '0' && filename[c] <= '9')
174 w = w*10 + filename[c]-'0';
175 if (filename[c] == ','){
176 c++;
177 break;
178 }
179 c++;
180 }
181
182 while (filename[c] != 0x0a && filename[c] != 0x00){
183 if (filename[c] >= '0' && filename[c] <= '9')
184 h = h*10 + filename[c]-'0';
185 if (filename[c] == ','){
186 c++;
187 break;
188 }
189 c++;
190 }
191
192 while (filename[c] == ' ' || filename[c] == '\t') c++;
193 int n=0, c2 = c;
194 while(filename[c] == '#'){
195 //rgb_t col = readColour((const char *)filename + c);
196 n++;
197 c += 7;
198 while (filename[c] == ' ' || filename[c] == '\t') c++;
199 }
200
201 SDL_PixelFormat *fmt = image_surface->format;
202 SDL_Surface *tmp = SDL_CreateRGBSurface(0, w, h,
203 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask);
204
205 c = c2;
206 for (int i=0 ; i<n ; i++){
207 rgb_t col = readColour(filename + c);
208 c += 7;
209 while (filename[c] == ' ' || filename[c] == '\t') c++;
210
211 SDL_Rect rect;
212 rect.x = w*i/n;
213 rect.y = 0;
214 rect.w = w*(i+1)/n - rect.x;
215 if (i == n-1) rect.w = w - rect.x;
216 rect.h = h;
217 SDL_FillRect(tmp, &rect, SDL_MapRGBA( accumulation_surface->format, col.r, col.g, col.b, 0xff));
218 }
219
220 return tmp;
221 }
222
createSurfaceFromFile(const pstring & filename,int * location)223 SDL_Surface *PonscripterLabel::createSurfaceFromFile(const pstring& filename,
224 int *location)
225 {
226 pstring alt_filename= "";
227 unsigned long length = script_h.cBR->getFileLength( filename );
228
229 if (length == 0) {
230 alt_filename = script_h.save_path + filename;
231 alt_filename.findreplace("\\", DELIMITER);
232 FILE* fp = std::fopen(alt_filename, "rb");
233 if (fp) {
234 fseek(fp, 0, SEEK_END);
235 length = ftell(fp);
236 fclose(fp);
237 }
238 }
239
240 if ( length == 0 ){
241 //don't complain about missing cursors
242 if ((filename != DEFAULT_LOOKBACK_NAME0) &&
243 (filename != DEFAULT_LOOKBACK_NAME1) &&
244 (filename != DEFAULT_LOOKBACK_NAME2) &&
245 (filename != DEFAULT_LOOKBACK_NAME3) &&
246 (filename != DEFAULT_CURSOR0) &&
247 (filename != DEFAULT_CURSOR1))
248 fprintf(stderr, " *** can't find file [%s] ***\n",
249 (const char*) filename);
250 return NULL;
251 }
252 if (filelog_flag) script_h.file_log.add(filename);
253
254 pstring dat = "";
255 if (!alt_filename) {
256 dat = script_h.cBR->getFile(filename, location);
257 }
258 else {
259 dat = script_h.cBR->getFile(alt_filename, location);
260 if ((unsigned)dat.slen != length)
261 fprintf(stderr, "Warning: error reading from %s\n",
262 (const char*)alt_filename);
263 }
264
265 SDL_Surface* tmp = IMG_Load_RW(rwops(dat), 1);
266 if (!tmp && file_extension(filename).caselessEqual("jpg")) {
267 fprintf(stderr, " *** force-loading a JPEG image [%s]\n",
268 (const char*) filename);
269 SDL_RWops* src = rwops(dat);
270 tmp = IMG_LoadJPG_RW(src);
271 SDL_RWclose(src);
272 }
273
274 if (!tmp)
275 fprintf(stderr, " *** can't load file [%s]: %s ***\n",
276 (const char*)filename, IMG_GetError());
277
278 return tmp;
279 }
280
281
282 // alphaMaskBlend
283 // dst: accumulation_surface
284 // src1: effect_src_surface
285 // src2: effect_dst_surface
alphaMaskBlend(SDL_Surface * mask_surface,int trans_mode,Uint32 mask_value,SDL_Rect * clip,SDL_Surface * src1,SDL_Surface * src2,SDL_Surface * dst)286 void PonscripterLabel::alphaMaskBlend(SDL_Surface *mask_surface, int trans_mode,
287 Uint32 mask_value, SDL_Rect *clip,
288 SDL_Surface *src1, SDL_Surface *src2,
289 SDL_Surface *dst)
290 {
291 SDL_Rect rect = {0, 0, screen_width, screen_height};
292
293 if (src1 == NULL)
294 src1 = effect_src_surface;
295 if (src2 == NULL)
296 src2 = effect_dst_surface;
297 if (dst == NULL)
298 dst = accumulation_surface;
299
300 /* ---------------------------------------- */
301 /* clipping */
302 if ( clip ){
303 if ( AnimationInfo::doClipping( &rect, clip ) ) return;
304 }
305
306 /* ---------------------------------------- */
307
308 SDL_LockSurface( src1 );
309 SDL_LockSurface( src2 );
310 SDL_LockSurface( dst );
311 if ( mask_surface ) SDL_LockSurface( mask_surface );
312
313 ONSBuf *src1_buffer = (ONSBuf *)src1->pixels + src1->w * rect.y + rect.x;
314 ONSBuf *src2_buffer = (ONSBuf *)src2->pixels + src2->w * rect.y + rect.x;
315 ONSBuf *dst_buffer = (ONSBuf *)dst->pixels + dst->w * rect.y + rect.x;
316
317 const int rwidth = screen_width - rect.w;
318 SDL_PixelFormat *fmt = dst->format;
319 Uint32 overflow_mask = 0xffffffff;
320 if ( trans_mode != ALPHA_BLEND_FADE_MASK )
321 overflow_mask = ~fmt->Bmask;
322
323 mask_value >>= fmt->Bloss;
324
325 if (( trans_mode == ALPHA_BLEND_FADE_MASK || trans_mode == ALPHA_BLEND_CROSSFADE_MASK ) && mask_surface) {
326 bool accelerated_ok = sizeof(ONSBuf) == 4 && fmt->Bmask == 0xff;
327 if (accelerated_ok) {
328 bool ok = AnimationInfo::gfx.alphaMaskBlend(dst, src1, src2, mask_surface, rect, mask_value);
329 accelerated_ok &= ok;
330 }
331 if (!accelerated_ok) {
332 int mask_off_base_y = rect.y % mask_surface->h;
333 int mask_off_base_x = rect.x % mask_surface->w;
334 for ( int i=0, my=mask_off_base_y ; i<rect.h ; i++, my++ ) {
335 if (my >= mask_surface->h) { my = 0; }
336 ONSBuf *mask_buffer = (ONSBuf *)mask_surface->pixels + mask_surface->w * my;
337 int offset=rect.x;
338 for ( int j=rect.w, mx=mask_off_base_x ; j ; j--, mx++ ) {
339 if (mx >= mask_surface->w) { mx = 0; }
340 Uint32 mask2 = 0;
341 Uint32 mask = *(mask_buffer + mx) & fmt->Bmask;
342 if ( mask_value > mask ){
343 mask2 = mask_value - mask;
344 if ( mask2 & overflow_mask ) mask2 = fmt->Bmask;
345 }
346 #ifndef BPP16
347 Uint32 mask1 = mask2 ^ fmt->Bmask;
348 #endif
349 BLEND_MASK_PIXEL();
350 ++dst_buffer, ++src1_buffer, ++src2_buffer, ++offset;
351 }
352 src1_buffer += rwidth;
353 src2_buffer += rwidth;
354 dst_buffer += rwidth;
355 }
356 }
357 }
358 else{ // ALPHA_BLEND_CONST
359 if (sizeof(ONSBuf) == 4) {
360 AnimationInfo::gfx.alphaMaskBlendConst(dst, src1, src2, rect, mask_value);
361 }
362 else {
363 Uint32 mask2 = mask_value & fmt->Bmask;
364 #ifndef BPP16
365 Uint32 mask1 = mask2 ^ fmt->Bmask;
366 #endif
367 for ( int i=rect.h ; i ; i-- ) {
368 for ( int j=rect.w ; j ; j-- ){
369 BLEND_MASK_PIXEL();
370 ++dst_buffer, ++src1_buffer, ++src2_buffer;
371 }
372 src1_buffer += rwidth;
373 src2_buffer += rwidth;
374 dst_buffer += rwidth;
375 }
376 }
377 }
378
379 if ( mask_surface ) SDL_UnlockSurface( mask_surface );
380 SDL_UnlockSurface( dst );
381 SDL_UnlockSurface( src2 );
382 SDL_UnlockSurface( src1 );
383 }
384
385
386 // alphaBlendText
387 // dst: ONSBuf surface (accumulation_surface)
388 // txt: 8bit surface (TTF_RenderGlyph_Shaded())
alphaBlendText(SDL_Surface * dst_surface,SDL_Rect dst_rect,SDL_Surface * txt_surface,SDL_Color & color,SDL_Rect * clip,bool rotate_flag)389 void PonscripterLabel::alphaBlendText(SDL_Surface *dst_surface, SDL_Rect dst_rect,
390 SDL_Surface *txt_surface, SDL_Color &color,
391 SDL_Rect *clip, bool rotate_flag)
392 {
393 int x2=0, y2=0;
394 SDL_Rect clipped_rect;
395
396 /* ---------------------------------------- */
397 /* 1st clipping */
398 if ( clip ){
399 if ( AnimationInfo::doClipping( &dst_rect, clip, &clipped_rect ) ) return;
400
401 x2 += clipped_rect.x;
402 y2 += clipped_rect.y;
403 }
404
405 /* ---------------------------------------- */
406 /* 2nd clipping */
407 SDL_Rect clip_rect = {0, 0, dst_surface->w, dst_surface->h};
408 if ( AnimationInfo::doClipping( &dst_rect, &clip_rect, &clipped_rect ) ) return;
409
410 x2 += clipped_rect.x;
411 y2 += clipped_rect.y;
412
413 /* ---------------------------------------- */
414
415 SDL_LockSurface( dst_surface );
416 SDL_LockSurface( txt_surface );
417
418 #ifdef BPP16
419 Uint32 src_color = ((color.r >> RLOSS) << RSHIFT) |
420 ((color.g >> GLOSS) << GSHIFT) |
421 (color.b >> BLOSS);
422 src_color = (src_color | src_color << 16) & BLENDMASK;
423 #else
424 Uint32 src_color1 = color.r << RSHIFT | color.b;
425 Uint32 src_color2 = color.g << GSHIFT;
426 #endif
427
428 ONSBuf *dst_buffer = (ONSBuf *)dst_surface->pixels +
429 dst_surface->w * dst_rect.y + dst_rect.x;
430
431 if (!rotate_flag){
432 unsigned char *src_buffer = (unsigned char*)txt_surface->pixels +
433 txt_surface->pitch * y2 + x2;
434 for ( int i=dst_rect.h ; i>0 ; i-- ){
435 for ( int j=dst_rect.w ; j>0 ; j--, dst_buffer++, src_buffer++ ){
436 BLEND_PIXEL8();
437 }
438 dst_buffer += dst_surface->w - dst_rect.w;
439 src_buffer += txt_surface->pitch - dst_rect.w;
440 }
441 }
442 else{
443 for ( int i=0 ; i<dst_rect.h ; i++ ){
444 unsigned char *src_buffer = (unsigned char*)txt_surface->pixels + txt_surface->pitch*(txt_surface->h - x2 - 1) + y2 + i;
445 for ( int j=dst_rect.w ; j>0 ; j--, dst_buffer++ ){
446 BLEND_PIXEL8();
447 src_buffer -= txt_surface->pitch;
448 }
449 dst_buffer += dst_surface->w - dst_rect.w;
450 }
451 }
452
453 SDL_UnlockSurface( txt_surface );
454 SDL_UnlockSurface( dst_surface );
455 }
456
457
makeNegaSurface(SDL_Surface * surface,SDL_Rect & clip)458 void PonscripterLabel::makeNegaSurface( SDL_Surface *surface, SDL_Rect &clip )
459 {
460 SDL_LockSurface( surface );
461 ONSBuf *buf = (ONSBuf *)surface->pixels + clip.y * surface->w + clip.x;
462
463 ONSBuf mask = surface->format->Rmask | surface->format->Gmask | surface->format->Bmask;
464 for ( int i=clip.h ; i>0 ; i-- ){
465 for ( int j=clip.w ; j>0 ; j-- )
466 *buf++ ^= mask;
467 buf += surface->w - clip.w;
468 }
469
470 SDL_UnlockSurface( surface );
471 }
472
473
makeMonochromeSurface(SDL_Surface * surface,SDL_Rect & clip)474 void PonscripterLabel::makeMonochromeSurface( SDL_Surface *surface, SDL_Rect &clip )
475 {
476 SDL_LockSurface( surface );
477 ONSBuf *buffer = (ONSBuf *)surface->pixels + clip.y * surface->w + clip.x;
478
479 for ( int i=clip.h ; i>0 ; i-- ){
480 for ( int j=clip.w ; j>0 ; j--, buffer++ ){
481 //Mion: NScr seems to use more "equal" 85/86/85 RGB blending, instead
482 // of the 77/151/28 that onscr used to have. Using 85/86/85 now,
483 // might add a parameter to "monocro" to allow choosing 77/151/28
484 MONOCRO_PIXEL();
485 }
486 buffer += surface->w - clip.w;
487 }
488
489 SDL_UnlockSurface( surface );
490 }
491
492
493 void
refreshSurface(SDL_Surface * surface,SDL_Rect * clip_src,int refresh_mode)494 PonscripterLabel::refreshSurface(SDL_Surface* surface, SDL_Rect* clip_src,
495 int refresh_mode)
496 {
497 if (refresh_mode == REFRESH_NONE_MODE) return;
498
499 SDL_Rect clip = { 0, 0, surface->w, surface->h };
500 if (clip_src && AnimationInfo::doClipping(&clip, clip_src)) return;
501
502 int i, top;
503 SDL_BlitSurface( bg_info.image_surface, &clip, surface, &clip );
504
505 if (!all_sprite_hide_flag) {
506 if (z_order < 10 && refresh_mode & REFRESH_SAYA_MODE)
507 top = 9;
508 else
509 top = z_order;
510
511 for (i = MAX_SPRITE_NUM - 1; i > top; --i) {
512 if (sprite_info[i].image_surface && sprite_info[i].showing())
513 drawTaggedSurface(surface, &sprite_info[i], clip);
514 }
515 }
516
517 for (i = 0; i < 3; ++i) {
518 if (human_order[2 - i] >= 0 &&
519 tachi_info[human_order[2 - i]].image_surface)
520 drawTaggedSurface(surface, &tachi_info[human_order[2 - i]], clip);
521 }
522
523 if (windowback_flag) {
524 if (nega_mode == 1) makeNegaSurface(surface, clip);
525 if (monocro_flag) makeMonochromeSurface(surface, clip);
526 if (nega_mode == 2) makeNegaSurface(surface, clip);
527
528 if (!all_sprite2_hide_flag) {
529 for (i = MAX_SPRITE2_NUM - 1; i >= 0; --i) {
530 if (sprite2_info[i].image_surface && sprite2_info[i].showing())
531 drawTaggedSurface(surface, &sprite2_info[i], clip);
532 }
533 }
534
535 if (refresh_mode & REFRESH_SHADOW_MODE)
536 shadowTextDisplay(surface, clip);
537 if (refresh_mode & REFRESH_TEXT_MODE)
538 text_info.blendOnSurface(surface, 0, 0, clip);
539 }
540
541 if (!all_sprite_hide_flag) {
542 if (refresh_mode & REFRESH_SAYA_MODE)
543 top = 10;
544 else
545 top = 0;
546 for (i = z_order; i >= top; --i) {
547 if (sprite_info[i].image_surface && sprite_info[i].showing())
548 drawTaggedSurface(surface, &sprite_info[i], clip);
549 }
550 }
551
552 if (!windowback_flag) {
553 //Mion - ogapee2008
554 if (!all_sprite2_hide_flag) {
555 for (i = MAX_SPRITE2_NUM - 1; i >= 0; --i) {
556 if (sprite2_info[i].image_surface && sprite2_info[i].showing())
557 drawTaggedSurface(surface, &sprite2_info[i], clip);
558 }
559 }
560 if (nega_mode == 1) makeNegaSurface(surface, clip);
561 if (monocro_flag) makeMonochromeSurface(surface, clip);
562 if (nega_mode == 2) makeNegaSurface(surface, clip);
563 }
564
565 if (!(refresh_mode & REFRESH_SAYA_MODE)) {
566 for (i = 0; i < MAX_PARAM_NUM; ++i)
567 if (bar_info[i])
568 drawTaggedSurface(surface, bar_info[i], clip);
569 for (i = 0; i < MAX_PARAM_NUM; ++i)
570 if (prnum_info[i])
571 drawTaggedSurface(surface, prnum_info[i], clip);
572 }
573
574 if (!windowback_flag) {
575 if (refresh_mode & REFRESH_SHADOW_MODE)
576 shadowTextDisplay(surface, clip);
577 if (refresh_mode & REFRESH_TEXT_MODE)
578 text_info.blendOnSurface(surface, 0, 0, clip);
579 }
580
581 if (refresh_mode & REFRESH_CURSOR_MODE && !textgosub_label) {
582 if (clickstr_state == CLICK_WAIT)
583 drawTaggedSurface(surface, &cursor_info[CURSOR_WAIT_NO], clip);
584 else if (clickstr_state == CLICK_NEWPAGE)
585 drawTaggedSurface(surface, &cursor_info[CURSOR_NEWPAGE_NO], clip);
586 }
587
588 for (ButtonElt::iterator it = buttons.begin(); it != buttons.end(); ++it)
589 if (it->second.show_flag > 0)
590 drawTaggedSurface(surface, it->second.anim[it->second.show_flag - 1], clip);
591 }
592
593
refreshSprite(int sprite_no,bool active_flag,int cell_no,SDL_Rect * check_src_rect,SDL_Rect * check_dst_rect)594 void PonscripterLabel::refreshSprite(int sprite_no, bool active_flag,
595 int cell_no, SDL_Rect* check_src_rect,
596 SDL_Rect* check_dst_rect)
597 {
598 if ((sprite_info[sprite_no].image_name ||
599 ((sprite_info[sprite_no].trans_mode == AnimationInfo::TRANS_STRING) &&
600 sprite_info[sprite_no].file_name)) &&
601 ((sprite_info[sprite_no].showing() != active_flag) ||
602 (cell_no >= 0 && sprite_info[sprite_no].current_cell != cell_no) ||
603 AnimationInfo::doClipping(check_src_rect,&sprite_info[sprite_no].pos) == 0 ||
604 AnimationInfo::doClipping(check_dst_rect,&sprite_info[sprite_no].pos) == 0))
605 {
606 if (cell_no >= 0) sprite_info[sprite_no].setCell(cell_no);
607 sprite_info[sprite_no].visible(active_flag);
608 dirty_rect.add(sprite_info[sprite_no].pos);
609 }
610 }
611
612
createBackground()613 void PonscripterLabel::createBackground()
614 {
615 bg_info.num_of_cells = 1;
616 bg_info.trans_mode = AnimationInfo::TRANS_COPY;
617 bg_info.pos.x = 0;
618 bg_info.pos.y = 0;
619 bg_info.allocImage(screen_width,screen_height);
620
621 if (bg_info.file_name == "white") {
622 bg_info.color.set(0xff);
623 }
624 else if (bg_info.file_name == "black") {
625 bg_info.color.set(0x00);
626 }
627 else if (bg_info.file_name[0] == '#') {
628 bg_info.color = readColour(bg_info.file_name);
629 }
630 else {
631 AnimationInfo anim;
632 anim.image_name = bg_info.file_name;
633 parseTaggedString(&anim);
634 anim.trans_mode = AnimationInfo::TRANS_COPY;
635 setupAnimationInfo(&anim);
636 bg_info.fill(0, 0, 0, 0xff);
637 if (anim.image_surface){
638 SDL_Rect src_rect = {0, 0, anim.image_surface->w, anim.image_surface->h};
639 SDL_Rect dst_rect = {0, 0, screen_width, screen_height};
640 if (screen_width >= anim.image_surface->w){
641 dst_rect.x = (screen_width - anim.image_surface->w) / 2;
642 }
643 else{
644 src_rect.x = (anim.image_surface->w - screen_width) / 2;
645 src_rect.w = screen_width;
646 }
647 if (screen_height >= anim.image_surface->h){
648 dst_rect.y = (screen_height - anim.image_surface->h) / 2;
649 }
650 else{
651 src_rect.y = (anim.image_surface->h - screen_height) / 2;
652 src_rect.h = screen_height;
653 }
654 bg_info.copySurface(anim.image_surface, &src_rect, &dst_rect);
655 }
656 return;
657 }
658
659 bg_info.fill(bg_info.color, 0xff);
660 }
661