1 /* -*- C++ -*-
2 *
3 * ONScripter_image.cpp - Image processing in ONScripter
4 *
5 * Copyright (c) 2001-2019 Ogapee. All rights reserved.
6 *
7 * ogapee@aqua.dti2.ne.jp
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "ONScripter.h"
25 #include <new>
26 #include "resize_image.h"
27
loadImage(char * filename,bool is_flipped,bool * has_alpha,int * location,unsigned char * alpha)28 SDL_Surface *ONScripter::loadImage(char *filename, bool is_flipped, bool *has_alpha, int *location, unsigned char *alpha)
29 {
30 if (!filename) return NULL;
31
32 SDL_Surface *tmp = NULL;
33 if (location) *location = BaseReader::ARCHIVE_TYPE_NONE;
34
35 if (filename[0] == '>')
36 tmp = createRectangleSurface(filename, has_alpha, alpha);
37 else
38 tmp = createSurfaceFromFile(filename, has_alpha, location);
39 if (tmp == NULL) return NULL;
40
41 if (is_flipped){
42 SDL_PixelFormat *fmt = tmp->format;
43 SDL_Surface *tmp2 = SDL_CreateRGBSurface(SDL_SWSURFACE, tmp->w, tmp->h,
44 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask);
45 for (int y=0; y<tmp->h; ++y) {
46 Uint32 *src = (Uint32 *)tmp->pixels + tmp->w * y;
47 Uint32 *dst = (Uint32 *)tmp2->pixels + tmp2->w * (y + 1) - 1;
48 for (int x=0; x<tmp->w; x++)
49 *dst-- = *src++;
50 }
51 SDL_FreeSurface(tmp);
52 tmp = tmp2;
53 }
54
55 SDL_Surface *ret;
56 if((tmp->w * tmp->format->BytesPerPixel == tmp->pitch) &&
57 (tmp->format->BitsPerPixel == image_surface->format->BitsPerPixel) &&
58 (tmp->format->Rmask == image_surface->format->Rmask) &&
59 (tmp->format->Gmask == image_surface->format->Gmask) &&
60 (tmp->format->Bmask == image_surface->format->Bmask) &&
61 (tmp->format->Amask == image_surface->format->Amask)){
62 ret = tmp;
63 }
64 else{
65 ret = SDL_ConvertSurface(tmp, image_surface->format, SDL_SWSURFACE);
66 SDL_FreeSurface(tmp);
67 }
68
69 return ret;
70 }
71
createRectangleSurface(char * filename,bool * has_alpha,unsigned char * alpha)72 SDL_Surface *ONScripter::createRectangleSurface(char *filename, bool *has_alpha, unsigned char *alpha)
73 {
74 int c=1, w=0, h=0;
75 bool decimal_flag = false;
76 while (filename[c] != 0x0a && filename[c] != 0x00){
77 if (!decimal_flag && filename[c] >= '0' && filename[c] <= '9')
78 w = w*10 + filename[c]-'0';
79 if (filename[c] == '.') decimal_flag = true;
80 if (filename[c] == ','){
81 c++;
82 break;
83 }
84 c++;
85 }
86
87 decimal_flag = false;
88 while (filename[c] != 0x0a && filename[c] != 0x00){
89 if (!decimal_flag && filename[c] >= '0' && filename[c] <= '9')
90 h = h*10 + filename[c]-'0';
91 if (filename[c] == '.') decimal_flag = true;
92 if (filename[c] == ','){
93 c++;
94 break;
95 }
96 c++;
97 }
98
99 while (filename[c] == ' ' || filename[c] == '\t') c++;
100 int n=0, c2 = c;
101 while(filename[c] == '#'){
102 uchar3 col;
103 readColor(&col, filename+c);
104 n++;
105 c += 7;
106 while (filename[c] == ' ' || filename[c] == '\t') c++;
107 }
108
109 SDL_PixelFormat *fmt = image_surface->format;
110 SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
111 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask);
112
113 c = c2;
114 for (int i=0 ; i<n ; i++){
115 uchar3 col;
116 readColor(&col, filename+c);
117 c += 7;
118 while (filename[c] == ' ' || filename[c] == '\t') c++;
119
120 SDL_Rect rect;
121 rect.x = w*i/n;
122 rect.y = 0;
123 rect.w = w*(i+1)/n - rect.x;
124 if (i == n-1) rect.w = w - rect.x;
125 rect.h = h;
126 SDL_FillRect(tmp, &rect, SDL_MapRGBA( tmp->format, col[0], col[1], col[2], alpha?*alpha:0xff));
127 }
128
129 if (has_alpha){
130 if (fmt->Amask)
131 *has_alpha = true;
132 else
133 *has_alpha = false;
134 }
135
136 return tmp;
137 }
138
createSurfaceFromFile(char * filename,bool * has_alpha,int * location)139 SDL_Surface *ONScripter::createSurfaceFromFile(char *filename, bool *has_alpha, int *location)
140 {
141 unsigned long length = script_h.cBR->getFileLength( filename );
142
143 if (length == 0){
144 fprintf( stderr, " *** can't find file [%s] ***\n", filename );
145 return NULL;
146 }
147
148 if (filelog_flag)
149 script_h.findAndAddLog(script_h.log_info[ScriptHandler::FILE_LOG], filename, true);
150 //printf(" ... loading %s length %ld\n", filename, length );
151
152 mean_size_of_loaded_images += length*6/5; // reserve 20% larger size
153 num_loaded_images++;
154 if (tmp_image_buf_length < mean_size_of_loaded_images/num_loaded_images){
155 tmp_image_buf_length = mean_size_of_loaded_images/num_loaded_images;
156 if (tmp_image_buf) delete[] tmp_image_buf;
157 tmp_image_buf = NULL;
158 }
159
160 unsigned char *buffer = NULL;
161 if (length > tmp_image_buf_length){
162 buffer = new(std::nothrow) unsigned char[length];
163 if (buffer == NULL){
164 fprintf( stderr, "failed to load [%s] because file size [%lu] is too large.\n", filename, length);
165 return NULL;
166 }
167 }
168 else{
169 if (!tmp_image_buf) tmp_image_buf = new unsigned char[tmp_image_buf_length];
170 buffer = tmp_image_buf;
171 }
172
173 script_h.cBR->getFile(filename, buffer, location);
174 char *ext = strrchr(filename, '.');
175
176 SDL_RWops *src = SDL_RWFromMem(buffer, length);
177 int is_png = IMG_isPNG(src);
178
179 SDL_Surface *tmp = IMG_Load_RW(src, 0);
180 if (!tmp && ext && (!strcmp(ext+1, "JPG") || !strcmp(ext+1, "jpg"))){
181 fprintf(stderr, " *** force-loading a JPG image [%s]\n", filename);
182 tmp = IMG_LoadJPG_RW(src);
183 }
184
185 if (tmp && has_alpha){
186 if (tmp->format->Amask || is_png)
187 *has_alpha = true;
188 else
189 *has_alpha = false;
190 }
191
192 SDL_RWclose(src);
193
194 if (buffer != tmp_image_buf) delete[] buffer;
195
196 if (!tmp)
197 fprintf( stderr, " *** can't load file [%s] %s ***\n", filename, IMG_GetError() );
198
199 return tmp;
200 }
201
202 // resize 32bit surface to 32bit surface
resizeSurface(SDL_Surface * src,SDL_Surface * dst)203 int ONScripter::resizeSurface( SDL_Surface *src, SDL_Surface *dst )
204 {
205 SDL_LockSurface( dst );
206 SDL_LockSurface( src );
207 Uint32 *src_buffer = (Uint32 *)src->pixels;
208 Uint32 *dst_buffer = (Uint32 *)dst->pixels;
209
210 /* size of tmp_buffer must be larger than 16 bytes */
211 size_t len = src->w * (src->h+1) * 4 + 4;
212 if (resize_buffer_size < len){
213 delete[] resize_buffer;
214 resize_buffer = new unsigned char[len];
215 resize_buffer_size = len;
216 }
217 resizeImage( (unsigned char*)dst_buffer, dst->w, dst->h, dst->w * 4,
218 (unsigned char*)src_buffer, src->w, src->h, src->w * 4,
219 4, resize_buffer, src->w * 4, false );
220
221 SDL_UnlockSurface( src );
222 SDL_UnlockSurface( dst );
223
224 return 0;
225 }
226
227 #if defined(BPP16)
228 #define BLEND_PIXEL_MASK()\
229 {\
230 Uint32 s1 = (*src1_buffer | *src1_buffer << 16) & 0x07e0f81f;\
231 Uint32 s2 = (*src2_buffer | *src2_buffer << 16) & 0x07e0f81f;\
232 Uint32 d = (s1 + ((s2 - s1) * alpha >> 5)) & 0x07e0f81f;\
233 *dst_buffer = d | d >> 16;\
234 }
235 #else
236 #define BLEND_PIXEL_MASK()\
237 {\
238 Uint32 s1 = *src1_buffer & 0xff00ff;\
239 Uint32 d1 = (s1 + ((((*src2_buffer & 0xff00ff) - s1) * alpha) >> 8));\
240 s1 = *src1_buffer & 0x00ff00;\
241 Uint32 d2 = (s1 + ((((*src2_buffer & 0x00ff00) - s1) * alpha) >> 8));\
242 *dst_buffer = (d1 & 0xff00ff) | (d2 & 0x00ff00);\
243 }
244 // Originally, the above looks like this.
245 // mask1 = mask2 ^ 0xff;
246 // Uint32 mask_rb = (((*src1_buffer & 0xff00ff) * mask1 +
247 // (*src2_buffer & 0xff00ff) * mask2) >> 8) & 0xff00ff;
248 // Uint32 mask_g = (((*src1_buffer & 0x00ff00) * mask1 +
249 // (*src2_buffer & 0x00ff00) * mask2) >> 8) & 0x00ff00;
250 #endif
251
252 // alphaBlend
253 // dst: accumulation_surface
254 // src1: effect_src_surface
255 // src2: effect_dst_surface
alphaBlend(SDL_Surface * mask_surface,int trans_mode,Uint32 mask_value,SDL_Rect * clip)256 void ONScripter::alphaBlend( SDL_Surface *mask_surface,
257 int trans_mode, Uint32 mask_value, SDL_Rect *clip )
258 {
259 SDL_Rect rect = screen_rect;
260 int i, j;
261
262 /* ---------------------------------------- */
263 /* clipping */
264 if ( clip ){
265 if ( AnimationInfo::doClipping( &rect, clip ) ) return;
266 }
267
268 /* ---------------------------------------- */
269
270 SDL_LockSurface( effect_src_surface );
271 SDL_LockSurface( effect_dst_surface );
272 if (accumulation_surface != effect_dst_surface)
273 SDL_LockSurface( accumulation_surface );
274 if ( mask_surface ) SDL_LockSurface( mask_surface );
275
276 ONSBuf *src1_buffer = (ONSBuf *)effect_src_surface->pixels + effect_src_surface->w * rect.y + rect.x;
277 ONSBuf *src2_buffer = (ONSBuf *)effect_dst_surface->pixels + effect_dst_surface->w * rect.y + rect.x;
278 ONSBuf *dst_buffer = (ONSBuf *)accumulation_surface->pixels + accumulation_surface->w * rect.y + rect.x;
279
280 SDL_PixelFormat *fmt = accumulation_surface->format;
281 Uint32 lowest_mask;
282 Uint8 lowest_loss;
283 if (fmt->Rmask < fmt->Bmask){
284 lowest_mask = fmt->Rmask; // ABGR8888
285 lowest_loss = fmt->Rloss;
286 }
287 else{
288 lowest_mask = fmt->Bmask; // ARGB8888 or RGB565
289 lowest_loss = fmt->Bloss;
290 }
291
292 Uint32 overflow_mask;
293 if ( trans_mode == ALPHA_BLEND_FADE_MASK )
294 overflow_mask = 0xffffffff;
295 else
296 overflow_mask = ~lowest_mask;
297
298 mask_value >>= lowest_loss;
299
300 if ( (trans_mode == ALPHA_BLEND_FADE_MASK ||
301 trans_mode == ALPHA_BLEND_CROSSFADE_MASK) && mask_surface ){
302 for ( i=0; i<rect.h ; i++ ) {
303 ONSBuf *mask_buffer = (ONSBuf *)mask_surface->pixels + mask_surface->w * ((rect.y+i)%mask_surface->h);
304
305 int j2 = rect.x;
306 for ( j=0 ; j<rect.w ; j++ ){
307 Uint32 alpha = 0;
308 Uint32 mask = *(mask_buffer + j2) & lowest_mask;
309 if ( mask_value > mask ){
310 alpha = mask_value - mask;
311 if ( alpha & overflow_mask ) alpha = lowest_mask;
312 }
313 alpha++;
314 BLEND_PIXEL_MASK();
315 src1_buffer++; src2_buffer++; dst_buffer++;
316
317 if (j2 >= mask_surface->w) j2 = 0;
318 else j2++;
319 }
320 src1_buffer += screen_width - rect.w;
321 src2_buffer += screen_width - rect.w;
322 dst_buffer += screen_width - rect.w;
323 }
324 }else{ // ALPHA_BLEND_CONST
325 Uint32 alpha = (mask_value & lowest_mask) + 1;
326
327 for ( i=0; i<rect.h ; i++ ) {
328 for ( j=rect.w ; j!=0 ; j-- ){
329 BLEND_PIXEL_MASK();
330 src1_buffer++; src2_buffer++; dst_buffer++;
331 }
332 src1_buffer += screen_width - rect.w;
333 src2_buffer += screen_width - rect.w;
334 dst_buffer += screen_width - rect.w;
335 }
336 }
337
338 if ( mask_surface ) SDL_UnlockSurface( mask_surface );
339 if (accumulation_surface != effect_dst_surface)
340 SDL_UnlockSurface( accumulation_surface );
341 SDL_UnlockSurface( effect_dst_surface );
342 SDL_UnlockSurface( effect_src_surface );
343 }
344
345 #define BLEND_PIXEL_TEXT_BPP16()\
346 {\
347 Uint32 sa = (*src_buffer + 1) >> 3;\
348 if (sa != 0){\
349 Uint32 d = (*dst_buffer | *dst_buffer << 16) & 0x07e0f81f;\
350 d = (d + (((src_color - d) * sa) >> 5)) & 0x07e0f81f;\
351 *dst_buffer = d | d >> 16;\
352 }\
353 }
354
355 #define BLEND_PIXEL_TEXT()\
356 {\
357 Uint32 sa = *src_buffer;\
358 if (sa == 255){\
359 *dst_buffer = src_color3;\
360 }\
361 else if (sa != 0){\
362 sa++;\
363 Uint32 d = *dst_buffer & 0xff00ff;\
364 Uint32 d1 = (d + (((src_color1 - d) * sa) >> 8));\
365 d = *dst_buffer & 0x00ff00;\
366 Uint32 d2 = (d + (((src_color2 - d) * sa) >> 8));\
367 *dst_buffer = (d1 & 0xff00ff) | (d2 & 0x00ff00) | 0xff000000;\
368 }\
369 }
370
371 // alphaBlendText
372 // dst: ONSBuf surface (accumulation_surface)
373 // src: 8bit surface (TTF_RenderGlyph_Shaded())
alphaBlendText(SDL_Surface * dst_surface,SDL_Rect dst_rect,SDL_Surface * src_surface,SDL_Color & color,SDL_Rect * clip,bool rotate_flag)374 void ONScripter::alphaBlendText( SDL_Surface *dst_surface, SDL_Rect dst_rect,
375 SDL_Surface *src_surface, SDL_Color &color, SDL_Rect *clip, bool rotate_flag )
376 {
377 int x2=0, y2=0;
378 SDL_Rect clipped_rect;
379
380 /* ---------------------------------------- */
381 /* 1st clipping */
382 if ( clip ){
383 if ( AnimationInfo::doClipping( &dst_rect, clip, &clipped_rect ) ) return;
384
385 x2 += clipped_rect.x;
386 y2 += clipped_rect.y;
387 }
388
389 /* ---------------------------------------- */
390 /* 2nd clipping */
391 SDL_Rect clip_rect;
392 clip_rect.x = clip_rect.y = 0;
393 clip_rect.w = dst_surface->w;
394 clip_rect.h = dst_surface->h;
395 if ( AnimationInfo::doClipping( &dst_rect, &clip_rect, &clipped_rect ) ) return;
396
397 x2 += clipped_rect.x;
398 y2 += clipped_rect.y;
399
400 /* ---------------------------------------- */
401
402 SDL_LockSurface( dst_surface );
403 SDL_LockSurface( src_surface );
404
405 SDL_PixelFormat *fmt = dst_surface->format;
406
407 if (fmt->BitsPerPixel == 16){
408 Uint32 src_color = (((color.r >> fmt->Rloss) << fmt->Rshift) |
409 ((color.g >> fmt->Gloss) << fmt->Gshift) |
410 ((color.b >> fmt->Bloss) << fmt->Bshift));
411 src_color = (src_color | src_color << 16) & 0x07e0f81f;
412
413 Uint16 *dst_buffer = (Uint16*)dst_surface->pixels + dst_surface->w * dst_rect.y + dst_rect.x;
414
415 if (!rotate_flag){
416 unsigned char *src_buffer = (unsigned char*)src_surface->pixels + src_surface->pitch * y2 + x2;
417 for ( int i=0 ; i<dst_rect.h ; i++ ){
418 for ( int j=dst_rect.w ; j!=0 ; j-- ){
419 BLEND_PIXEL_TEXT_BPP16();
420 src_buffer++;
421 dst_buffer++;
422 }
423 src_buffer += src_surface->pitch - dst_rect.w;
424 dst_buffer += dst_surface->w - dst_rect.w;
425 }
426 }
427 else{
428 for ( int i=0 ; i<dst_rect.h ; i++ ){
429 unsigned char *src_buffer = (unsigned char*)src_surface->pixels + src_surface->pitch*(src_surface->h - x2 - 1) + y2 + i;
430 for ( int j=dst_rect.w ; j!=0 ; j-- ){
431 BLEND_PIXEL_TEXT_BPP16();
432 src_buffer -= src_surface->pitch;
433 dst_buffer++;
434 }
435 dst_buffer += dst_surface->w - dst_rect.w;
436 }
437 }
438 }
439 else{
440 Uint32 src_color1 = (color.r << fmt->Rshift) | (color.b << fmt->Bshift);
441 Uint32 src_color2 = (color.g << fmt->Gshift);
442 Uint32 src_color3 = (0xff << fmt->Ashift) | src_color1 | src_color2;
443
444 Uint32 *dst_buffer = (Uint32*)dst_surface->pixels + dst_surface->w * dst_rect.y + dst_rect.x;
445
446 if (!rotate_flag){
447 unsigned char *src_buffer = (unsigned char*)src_surface->pixels + src_surface->pitch * y2 + x2;
448 for ( int i=0 ; i<dst_rect.h ; i++ ){
449 for ( int j=dst_rect.w ; j!=0 ; j-- ){
450 BLEND_PIXEL_TEXT();
451 src_buffer++;
452 dst_buffer++;
453 }
454 src_buffer += src_surface->pitch - dst_rect.w;
455 dst_buffer += dst_surface->w - dst_rect.w;
456 }
457 }
458 else{
459 for ( int i=0 ; i<dst_rect.h ; i++ ){
460 unsigned char *src_buffer = (unsigned char*)src_surface->pixels + src_surface->pitch*(src_surface->h - x2 - 1) + y2 + i;
461 for ( int j=dst_rect.w ; j!=0 ; j-- ){
462 BLEND_PIXEL_TEXT();
463 src_buffer -= src_surface->pitch;
464 dst_buffer++;
465 }
466 dst_buffer += dst_surface->w - dst_rect.w;
467 }
468 }
469 }
470
471 SDL_UnlockSurface( src_surface );
472 SDL_UnlockSurface( dst_surface );
473 }
474
makeNegaSurface(SDL_Surface * surface,SDL_Rect & clip)475 void ONScripter::makeNegaSurface( SDL_Surface *surface, SDL_Rect &clip )
476 {
477 SDL_LockSurface( surface );
478 ONSBuf *buf = (ONSBuf *)surface->pixels + clip.y * surface->w + clip.x;
479
480 ONSBuf mask = surface->format->Rmask | surface->format->Gmask | surface->format->Bmask;
481 for ( int i=clip.y ; i<clip.y + clip.h ; i++ ){
482 for ( int j=clip.x ; j<clip.x + clip.w ; j++ )
483 *buf++ ^= mask;
484 buf += surface->w - clip.w;
485 }
486
487 SDL_UnlockSurface( surface );
488 }
489
makeMonochromeSurface(SDL_Surface * surface,SDL_Rect & clip)490 void ONScripter::makeMonochromeSurface( SDL_Surface *surface, SDL_Rect &clip )
491 {
492 SDL_LockSurface( surface );
493 ONSBuf *buf = (ONSBuf *)surface->pixels + clip.y * surface->w + clip.x, c;
494
495 SDL_PixelFormat *fmt = surface->format;
496 for ( int i=clip.y ; i<clip.y + clip.h ; i++ ){
497 for ( int j=clip.x ; j<clip.x + clip.w ; j++ ){
498 c = ((((*buf & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss) * 77 +
499 (((*buf & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss) * 151 +
500 (((*buf & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss) * 28 ) >> 8;
501 *buf++ = ((monocro_color_lut[c][0] >> fmt->Rloss) << surface->format->Rshift |
502 (monocro_color_lut[c][1] >> fmt->Gloss) << surface->format->Gshift |
503 (monocro_color_lut[c][2] >> fmt->Bloss) << surface->format->Bshift);
504 }
505 buf += surface->w - clip.w;
506 }
507
508 SDL_UnlockSurface( surface );
509 }
510
511 #define FILL_LAYER_ALPHA_BUF()\
512 {\
513 for (int y=clip.y; y<clip.y+clip.h; y++){\
514 unsigned char *p = layer_alpha_buf + screen_width*y + clip.x;\
515 for (int x=clip.w; x>0; --x) *p++ = 0xff;\
516 }\
517 }
518
refreshSurface(SDL_Surface * surface,SDL_Rect * clip_src,int refresh_mode)519 void ONScripter::refreshSurface( SDL_Surface *surface, SDL_Rect *clip_src, int refresh_mode )
520 {
521 if (refresh_mode == REFRESH_NONE_MODE) return;
522
523 SDL_Rect clip;
524 clip.x = clip.y = 0;
525 clip.w = surface->w;
526 clip.h = surface->h;
527 if (clip_src) if ( AnimationInfo::doClipping( &clip, clip_src ) ) return;
528
529 int i, top;
530 SDL_BlitSurface( bg_info.image_surface, &clip, surface, &clip );
531
532 if ( !all_sprite_hide_flag ){
533 if ( z_order < 10 && refresh_mode & REFRESH_SAYA_MODE )
534 top = 9;
535 else
536 top = z_order;
537 for ( i=MAX_SPRITE_NUM-1 ; i>top ; i-- ){
538 if ( sprite_info[i].image_surface && sprite_info[i].visible ){
539 drawTaggedSurface( surface, &sprite_info[i], clip );
540 if (smpeg_info == &sprite_info[i])
541 FILL_LAYER_ALPHA_BUF();
542 }
543 }
544 }
545
546 if ( !all_sprite_hide_flag ){
547 for ( i=0 ; i<3 ; i++ ){
548 if (human_order[2-i] >= 0 && tachi_info[human_order[2-i]].image_surface)
549 drawTaggedSurface( surface, &tachi_info[human_order[2-i]], clip );
550 }
551 }
552
553 if ( windowback_flag ){
554 if ( nega_mode == 1 ) makeNegaSurface( surface, clip );
555 if ( monocro_flag ) makeMonochromeSurface( surface, clip );
556 if ( nega_mode == 2 ) makeNegaSurface( surface, clip );
557
558 if (!all_sprite2_hide_flag){
559 for ( i=MAX_SPRITE2_NUM-1 ; i>=0 ; i-- ){
560 if ( sprite2_info[i].image_surface && sprite2_info[i].visible ){
561 drawTaggedSurface( surface, &sprite2_info[i], clip );
562 if (smpeg_info == &sprite2_info[i])
563 FILL_LAYER_ALPHA_BUF();
564 }
565 }
566 }
567
568 if (refresh_mode & REFRESH_SHADOW_MODE)
569 shadowTextDisplay( surface, clip );
570 if (refresh_mode & REFRESH_TEXT_MODE)
571 text_info.blendOnSurface( surface, 0, 0, clip, layer_alpha_buf );
572 }
573
574 if ( !all_sprite_hide_flag ){
575 if ( refresh_mode & REFRESH_SAYA_MODE )
576 top = 10;
577 else
578 top = 0;
579 for ( i=z_order ; i>=top ; i-- ){
580 if ( sprite_info[i].image_surface && sprite_info[i].visible ){
581 drawTaggedSurface( surface, &sprite_info[i], clip );
582 if (smpeg_info == &sprite_info[i])
583 FILL_LAYER_ALPHA_BUF();
584 }
585 }
586 }
587
588 if ( !windowback_flag ){
589 if (!all_sprite2_hide_flag){
590 for ( i=MAX_SPRITE2_NUM-1 ; i>=0 ; i-- ){
591 if ( sprite2_info[i].image_surface && sprite2_info[i].visible ){
592 drawTaggedSurface( surface, &sprite2_info[i], clip );
593 if (smpeg_info == &sprite2_info[i])
594 FILL_LAYER_ALPHA_BUF();
595 }
596 }
597 }
598
599 if ( nega_mode == 1 ) makeNegaSurface( surface, clip );
600 if ( monocro_flag ) makeMonochromeSurface( surface, clip );
601 if ( nega_mode == 2 ) makeNegaSurface( surface, clip );
602 }
603
604 if ( !( refresh_mode & REFRESH_SAYA_MODE ) ){
605 for ( i=0 ; i<MAX_PARAM_NUM ; i++ ){
606 if ( bar_info[i] )
607 drawTaggedSurface( surface, bar_info[i], clip );
608 }
609 for ( i=0 ; i<MAX_PARAM_NUM ; i++ ){
610 if ( prnum_info[i] )
611 drawTaggedSurface( surface, prnum_info[i], clip );
612 }
613 }
614
615 if ( !windowback_flag ){
616 if (refresh_mode & REFRESH_SHADOW_MODE)
617 shadowTextDisplay( surface, clip );
618 if (refresh_mode & REFRESH_TEXT_MODE)
619 text_info.blendOnSurface( surface, 0, 0, clip, layer_alpha_buf );
620 }
621
622 if ( refresh_mode & REFRESH_CURSOR_MODE && !textgosub_label ){
623 if ( clickstr_state == CLICK_WAIT )
624 drawTaggedSurface( surface, &cursor_info[0], clip );
625 else if ( clickstr_state == CLICK_NEWPAGE )
626 drawTaggedSurface( surface, &cursor_info[1], clip );
627 }
628
629 if (show_dialog_flag)
630 drawTaggedSurface( surface, &dialog_info, clip );
631
632 ButtonLink *bl = root_button_link.next;
633 while( bl ){
634 if (bl->show_flag > 0)
635 drawTaggedSurface( surface, bl->anim[bl->show_flag-1], clip );
636 bl = bl->next;
637 }
638 }
639
refreshSprite(int sprite_no,bool active_flag,int cell_no,SDL_Rect * check_src_rect,SDL_Rect * check_dst_rect)640 void ONScripter::refreshSprite( int sprite_no, bool active_flag, int cell_no,
641 SDL_Rect *check_src_rect, SDL_Rect *check_dst_rect )
642 {
643 if ( sprite_info[sprite_no].image_surface &&
644 ( sprite_info[ sprite_no ].visible != active_flag ||
645 (cell_no >= 0 && sprite_info[ sprite_no ].current_cell != cell_no ) ||
646 AnimationInfo::doClipping(check_src_rect, &sprite_info[ sprite_no ].pos) == 0 ||
647 AnimationInfo::doClipping(check_dst_rect, &sprite_info[ sprite_no ].pos) == 0) )
648 {
649 if ( cell_no >= 0 )
650 sprite_info[ sprite_no ].setCell(cell_no);
651
652 sprite_info[ sprite_no ].visible = active_flag;
653
654 dirty_rect.add( sprite_info[ sprite_no ].pos );
655 }
656 }
657
createBackground()658 void ONScripter::createBackground()
659 {
660 bg_info.num_of_cells = 1;
661 bg_info.trans_mode = AnimationInfo::TRANS_COPY;
662 bg_info.pos.x = 0;
663 bg_info.pos.y = 0;
664 bg_info.allocImage( screen_width, screen_height, texture_format );
665
666 if ( !strcmp( bg_info.file_name, "white" ) ){
667 bg_info.color[0] = bg_info.color[1] = bg_info.color[2] = 0xff;
668 }
669 else if ( !strcmp( bg_info.file_name, "black" ) ||
670 !strcmp( bg_info.file_name, "*bgcpy" ) ){
671 bg_info.color[0] = bg_info.color[1] = bg_info.color[2] = 0x00;
672 }
673 else if ( bg_info.file_name[0] == '#' ){
674 readColor( &bg_info.color, bg_info.file_name );
675 }
676 else{
677 AnimationInfo anim;
678 setStr( &anim.image_name, bg_info.file_name );
679 parseTaggedString( &anim );
680 anim.trans_mode = AnimationInfo::TRANS_COPY;
681 setupAnimationInfo( &anim );
682
683 bg_info.fill(0, 0, 0, 0xff);
684 if (anim.image_surface){
685 SDL_Rect src_rect;
686 src_rect.x = src_rect.y = 0;
687 src_rect.w = anim.image_surface->w;
688 src_rect.h = anim.image_surface->h;
689 SDL_Rect dst_rect = {0, 0};
690 if (screen_width >= anim.image_surface->w){
691 dst_rect.x = (screen_width - anim.image_surface->w) / 2;
692 }
693 else{
694 src_rect.x = (anim.image_surface->w - screen_width) / 2;
695 src_rect.w = screen_width;
696 }
697
698 if (screen_height >= anim.image_surface->h){
699 dst_rect.y = (screen_height - anim.image_surface->h) / 2;
700 }
701 else{
702 src_rect.y = (anim.image_surface->h - screen_height) / 2;
703 src_rect.h = screen_height;
704 }
705 bg_info.copySurface(anim.image_surface, &src_rect, &dst_rect);
706 }
707 return;
708 }
709
710 bg_info.fill(bg_info.color[0], bg_info.color[1], bg_info.color[2], 0xff);
711 }
712