1 /* -*- C++ -*-
2 *
3 * ONScripter_command.cpp - Command executer of 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 #if defined(LINUX) || defined(MACOSX) || defined(IOS)
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #elif defined(WIN32)
29 #include <direct.h>
30 #endif
31 #include "version.h"
32
33 #if defined(MACOSX) && (SDL_COMPILEDVERSION >= 1208)
34 #include <CoreFoundation/CoreFoundation.h>
35 #endif
36
37 extern SDL_TimerID timer_bgmfade_id;
38 extern "C" Uint32 SDLCALL bgmfadeCallback( Uint32 interval, void *param );
39 extern "C" void smpegCallback();
40 extern unsigned short convUTF162SJIS(unsigned short in);
41
42 #define CONTINUOUS_PLAY
43
yesnoboxCommand()44 int ONScripter::yesnoboxCommand()
45 {
46 bool yesno_flag = true;
47 if ( script_h.isName( "okcancelbox" ) ) yesno_flag = false;
48
49 script_h.readInt();
50 script_h.pushVariable();
51
52 script_h.readStr();
53 const char *mes1 = script_h.saveStringBuffer();
54 const char *mes2 = script_h.readStr();
55 ButtonLink *tmp_button_link = root_button_link.next;
56 root_button_link.next = NULL;
57 buildDialog(yesno_flag, mes1, mes2);
58
59 show_dialog_flag = true;
60 dirty_rect.add(dialog_info.pos);
61 flush(refreshMode());
62
63 while(1){
64 event_mode = WAIT_BUTTON_MODE;
65 waitEvent(-1);
66
67 if (current_button_state.button == -1 ||
68 current_button_state.button == 2){
69 script_h.setInt(&script_h.pushed_variable, 0);
70 break;
71 }
72 else if (current_button_state.button == 1){
73 script_h.setInt(&script_h.pushed_variable, 1);
74 break;
75 }
76 }
77
78 show_dialog_flag = false;
79 delete root_button_link.next->next;
80 delete root_button_link.next;
81 root_button_link.next = tmp_button_link;
82 dirty_rect.add(dialog_info.pos);
83 flush(refreshMode());
84
85 return RET_CONTINUE;
86 }
87
wavestopCommand()88 int ONScripter::wavestopCommand()
89 {
90 if ( wave_sample[MIX_WAVE_CHANNEL] ){
91 Mix_Pause( MIX_WAVE_CHANNEL );
92 Mix_FreeChunk( wave_sample[MIX_WAVE_CHANNEL] );
93 wave_sample[MIX_WAVE_CHANNEL] = NULL;
94 }
95 setStr( &wave_file_name, NULL );
96
97 return RET_CONTINUE;
98 }
99
waveCommand()100 int ONScripter::waveCommand()
101 {
102 wave_play_loop_flag = false;
103
104 if (script_h.isName( "waveloop" ))
105 wave_play_loop_flag = true;
106
107 wavestopCommand();
108
109 setStr(&wave_file_name, script_h.readStr());
110 playSound(wave_file_name, SOUND_CHUNK, wave_play_loop_flag, MIX_WAVE_CHANNEL);
111
112 return RET_CONTINUE;
113 }
114
waittimerCommand()115 int ONScripter::waittimerCommand()
116 {
117 int count = script_h.readInt() + internal_timer - SDL_GetTicks();
118 if (count < 0) count = 0;
119
120 event_mode = WAIT_TIMER_MODE;
121 waitEvent( count );
122
123 return RET_CONTINUE;
124 }
125
waitCommand()126 int ONScripter::waitCommand()
127 {
128 event_mode = WAIT_TIMER_MODE;
129 waitEvent( script_h.readInt() );
130
131 return RET_CONTINUE;
132 }
133
vspCommand()134 int ONScripter::vspCommand()
135 {
136 leaveTextDisplayMode();
137
138 bool vsp2_flag = false;
139 if (script_h.isName("vsp2")) vsp2_flag = true;
140
141 int no = script_h.readInt();
142 int v = script_h.readInt();
143
144 if (vsp2_flag){
145 sprite2_info[no].visible = (v==1)?true:false;
146 dirty_rect.add( sprite2_info[no].bounding_rect );
147 }
148 else{
149 sprite_info[no].visible = (v==1)?true:false;
150 dirty_rect.add( sprite_info[no].pos );
151 }
152
153 return RET_CONTINUE;
154 }
155
voicevolCommand()156 int ONScripter::voicevolCommand()
157 {
158 voice_volume = script_h.readInt();
159 if ( wave_sample[0] ) Mix_Volume( 0, voice_volume * MIX_MAX_VOLUME / 100 );
160
161 return RET_CONTINUE;
162 }
163
vCommand()164 int ONScripter::vCommand()
165 {
166 char buf[256];
167
168 sprintf(buf, RELATIVEPATH "wav%c%s.wav", DELIMITER, script_h.getStringBuffer()+1);
169 playSound(buf, SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
170
171 return RET_CONTINUE;
172 }
173
trapCommand()174 int ONScripter::trapCommand()
175 {
176 bool is_clicked = trap_mode & TRAP_CLICKED;
177
178 if ( script_h.isName( "lr_trap" ) ){
179 trap_mode = TRAP_LEFT_CLICK | TRAP_RIGHT_CLICK;
180 }
181 else if ( script_h.isName( "r_trap" ) ){
182 trap_mode = TRAP_RIGHT_CLICK;
183 }
184 else if ( script_h.isName( "trap" ) ){
185 trap_mode = TRAP_LEFT_CLICK;
186 }
187
188 if ( script_h.compareString("off") ){
189 script_h.readLabel();
190 trap_mode = TRAP_NONE;
191 return RET_CONTINUE;
192 }
193 else if ( script_h.compareString("stop") ){
194 script_h.readLabel();
195 trap_mode |= TRAP_STOP;
196 return RET_CONTINUE;
197 }
198 else if ( script_h.compareString("resume") ){
199 script_h.readLabel();
200 if (is_clicked) trapHandler();
201 return RET_CONTINUE;
202 }
203
204 const char *buf = script_h.readStr();
205 if ( buf[0] == '*' ){
206 setStr(&trap_dist, buf+1);
207 }
208 else{
209 printf("trapCommand: [%s] is not supported\n", buf );
210 }
211
212 return RET_CONTINUE;
213 }
214
transbtnCommand()215 int ONScripter::transbtnCommand()
216 {
217 transbtn_flag = true;
218
219 return RET_CONTINUE;
220 }
221
textspeeddefaultCommand()222 int ONScripter::textspeeddefaultCommand()
223 {
224 sentence_font.wait_time = -1;
225 return RET_CONTINUE;
226 }
227
textspeedCommand()228 int ONScripter::textspeedCommand()
229 {
230 sentence_font.wait_time = script_h.readInt();
231
232 return RET_CONTINUE;
233 }
234
textshowCommand()235 int ONScripter::textshowCommand()
236 {
237 dirty_rect.fill( screen_width, screen_height );
238 refresh_shadow_text_mode = REFRESH_NORMAL_MODE | REFRESH_SHADOW_MODE | REFRESH_TEXT_MODE;
239 flush(refreshMode());
240
241 return RET_CONTINUE;
242 }
243
textonCommand()244 int ONScripter::textonCommand()
245 {
246 if (windowchip_sprite_no >= 0)
247 sprite_info[windowchip_sprite_no].visible = true;
248
249 enterTextDisplayMode();
250
251 text_on_flag = true;
252
253 return RET_CONTINUE;
254 }
255
textoffCommand()256 int ONScripter::textoffCommand()
257 {
258 if (windowchip_sprite_no >= 0)
259 sprite_info[windowchip_sprite_no].visible = false;
260
261 leaveTextDisplayMode(true);
262
263 text_on_flag = false;
264
265 return RET_CONTINUE;
266 }
267
texthideCommand()268 int ONScripter::texthideCommand()
269 {
270 dirty_rect.fill( screen_width, screen_height );
271 refresh_shadow_text_mode = REFRESH_NORMAL_MODE | REFRESH_SHADOW_MODE;
272 flush(refreshMode());
273
274 return RET_CONTINUE;
275 }
276
textcolorCommand()277 int ONScripter::textcolorCommand()
278 {
279 readColor( &sentence_font.color, script_h.readStr() );
280
281 return RET_CONTINUE;
282 }
283
textclearCommand()284 int ONScripter::textclearCommand()
285 {
286 newPage();
287 return RET_CONTINUE;
288 }
289
texecCommand()290 int ONScripter::texecCommand()
291 {
292 if ( textgosub_clickstr_state == CLICK_NEWPAGE )
293 newPage();
294 else if ( textgosub_clickstr_state == (CLICK_WAIT|CLICK_EOL) ){
295 processEOT();
296 page_enter_status = 0;
297 }
298
299 saveon_flag = true;
300
301 return RET_CONTINUE;
302 }
303
tateyokoCommand()304 int ONScripter::tateyokoCommand()
305 {
306 sentence_font.setTateyokoMode( script_h.readInt() );
307
308 return RET_CONTINUE;
309 }
310
talCommand()311 int ONScripter::talCommand()
312 {
313 leaveTextDisplayMode();
314
315 char loc = script_h.readLabel()[0];
316 int no = -1, trans = 0;
317 if ( loc == 'l' ) no = 0;
318 else if ( loc == 'c' ) no = 1;
319 else if ( loc == 'r' ) no = 2;
320
321 if (no >= 0)
322 trans = script_h.readInt();
323
324 if (no >= 0){
325 tachi_info[ no ].trans = trans;
326 dirty_rect.add( tachi_info[ no ].pos );
327 }
328
329 EffectLink *el = parseEffect(true);
330 if (setEffect(el)) return RET_CONTINUE;
331 while (doEffect(el));
332
333 return RET_CONTINUE;
334 }
335
tablegotoCommand()336 int ONScripter::tablegotoCommand()
337 {
338 int count = 0;
339 int no = script_h.readInt();
340
341 while( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
342 const char *buf = script_h.readStr();
343 if ( count++ == no ){
344 setCurrentLabel( buf+1 );
345 break;
346 }
347 }
348
349 return RET_CONTINUE;
350 }
351
systemcallCommand()352 int ONScripter::systemcallCommand()
353 {
354 system_menu_mode = getSystemCallNo( script_h.readLabel() );
355
356 executeSystemCall();
357
358 return RET_CONTINUE;
359 }
360
strspCommand()361 int ONScripter::strspCommand()
362 {
363 leaveTextDisplayMode();
364
365 bool v = true;
366 if ( script_h.isName( "strsph" ) ) v = false;
367
368 int sprite_no = script_h.readInt();
369 AnimationInfo *ai = &sprite_info[sprite_no];
370 ai->font_size_xy[0] = -1;
371
372 if (ai->image_surface && ai->visible)
373 dirty_rect.add( ai->pos );
374
375 ai->removeTag();
376 setStr(&ai->file_name, script_h.readStr());
377 ai->orig_pos.x = script_h.readInt();
378 ai->orig_pos.y = script_h.readInt();
379 ai->scalePosXY( screen_ratio1, screen_ratio2 );
380
381 FontInfo fi;
382 fi.enc = &script_h.enc;
383 fi.is_newline_accepted = true;
384 fi.num_xy[0] = script_h.readInt();
385 fi.num_xy[1] = script_h.readInt();
386 fi.font_size_xy[0] = script_h.readInt();
387 fi.font_size_xy[1] = script_h.readInt();
388 fi.pitch_xy[0] = script_h.readInt() + fi.font_size_xy[0];
389 fi.pitch_xy[1] = script_h.readInt() + fi.font_size_xy[1];
390 fi.is_bold = script_h.readInt()?true:false;
391 fi.is_shadow = script_h.readInt()?true:false;
392
393 char *buffer = script_h.getNext();
394 while(script_h.getEndStatus() & ScriptHandler::END_COMMA){
395 ai->num_of_cells++;
396 script_h.readStr();
397 }
398 if (ai->num_of_cells == 0){
399 ai->num_of_cells = 1;
400 ai->color_list = new uchar3[ai->num_of_cells];
401 ai->color_list[0][0] = ai->color_list[0][1] = ai->color_list[0][2] = 0xff;
402 }
403 else{
404 ai->color_list = new uchar3[ai->num_of_cells];
405 script_h.setCurrent(buffer);
406 for (int i=0 ; i<ai->num_of_cells ; i++)
407 readColor(&ai->color_list[i], script_h.readStr());
408 }
409
410 ai->trans_mode = AnimationInfo::TRANS_STRING;
411 ai->trans = -1;
412 ai->visible = v;
413 ai->is_single_line = false;
414 ai->is_tight_region = false;
415 ai->is_ruby_drawable = sentence_font.rubyon_flag;
416 setupAnimationInfo(ai, &fi);
417 if ( ai->visible ) dirty_rect.add( ai->pos );
418
419 return RET_CONTINUE;
420 }
421
stopCommand()422 int ONScripter::stopCommand()
423 {
424 mp3stopCommand();
425 wavestopCommand();
426
427 return RET_CONTINUE;
428 }
429
sp_rgb_gradationCommand()430 int ONScripter::sp_rgb_gradationCommand()
431 {
432 int no = script_h.readInt();
433 int upper_r = script_h.readInt();
434 int upper_g = script_h.readInt();
435 int upper_b = script_h.readInt();
436 int lower_r = script_h.readInt();
437 int lower_g = script_h.readInt();
438 int lower_b = script_h.readInt();
439 ONSBuf key_r = script_h.readInt();
440 ONSBuf key_g = script_h.readInt();
441 ONSBuf key_b = script_h.readInt();
442 Uint32 alpha = script_h.readInt();
443
444 AnimationInfo *ai;
445 if (no == -1) ai = &sentence_font_info;
446 else ai = &sprite_info[no];
447 SDL_Surface *surface = ai->image_surface;
448 if (surface == NULL) return RET_CONTINUE;
449
450 SDL_PixelFormat *fmt = surface->format;
451
452 ONSBuf key_mask = (((key_r >> fmt->Rloss) << fmt->Rshift) |
453 ((key_g >> fmt->Gloss) << fmt->Gshift) |
454 ((key_b >> fmt->Bloss) << fmt->Bshift));
455 ONSBuf rgb_mask = fmt->Rmask | fmt->Gmask | fmt->Bmask;
456
457 SDL_LockSurface(surface);
458 // check upper and lower bound
459 int i, j;
460 int upper_bound=0, lower_bound=0;
461 bool is_key_found = false;
462 for (i=0 ; i<surface->h ; i++){
463 ONSBuf *buf = (ONSBuf *)surface->pixels + surface->w * i;
464 for (j=0 ; j<surface->w ; j++, buf++){
465 if ((*buf & rgb_mask) == key_mask){
466 if (is_key_found == false){
467 is_key_found = true;
468 upper_bound = lower_bound = i;
469 }
470 else{
471 lower_bound = i;
472 }
473 break;
474 }
475 }
476 }
477
478 // replace pixels of the key-color with the specified color in gradation
479 for (i=upper_bound ; i<=lower_bound ; i++){
480 ONSBuf *buf = (ONSBuf *)surface->pixels + surface->w * i;
481 #if defined(BPP16)
482 unsigned char *alphap = ai->alpha_buf + surface->w * i;
483 #else
484 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
485 unsigned char *alphap = (unsigned char *)buf + 3;
486 #else
487 unsigned char *alphap = (unsigned char *)buf;
488 #endif
489 #endif
490 Uint32 color = alpha << surface->format->Ashift;
491 if (upper_bound != lower_bound){
492 color |= (((lower_r - upper_r) * (i-upper_bound) / (lower_bound - upper_bound) + upper_r) >> fmt->Rloss) << fmt->Rshift;
493 color |= (((lower_g - upper_g) * (i-upper_bound) / (lower_bound - upper_bound) + upper_g) >> fmt->Gloss) << fmt->Gshift;
494 color |= (((lower_b - upper_b) * (i-upper_bound) / (lower_bound - upper_bound) + upper_b) >> fmt->Bloss) << fmt->Bshift;
495 }
496 else{
497 color |= (upper_r >> fmt->Rloss) << fmt->Rshift;
498 color |= (upper_g >> fmt->Gloss) << fmt->Gshift;
499 color |= (upper_b >> fmt->Bloss) << fmt->Bshift;
500 }
501
502 for (j=0 ; j<surface->w ; j++, buf++){
503 if ((*buf & rgb_mask) == key_mask){
504 *buf = color;
505 *alphap = alpha;
506 }
507 #if defined(BPP16)
508 alphap++;
509 #else
510 alphap += 4;
511 #endif
512 }
513 }
514
515 SDL_UnlockSurface(surface);
516
517 if ( ai->visible )
518 dirty_rect.add( ai->pos );
519
520 return RET_CONTINUE;
521 }
522
spstrCommand()523 int ONScripter::spstrCommand()
524 {
525 decodeExbtnControl( script_h.readStr() );
526
527 return RET_CONTINUE;
528 }
529
spreloadCommand()530 int ONScripter::spreloadCommand()
531 {
532 int no = script_h.readInt();
533 AnimationInfo *ai;
534 if (no == -1) ai = &sentence_font_info;
535 else ai = &sprite_info[no];
536
537 parseTaggedString( ai );
538 setupAnimationInfo( ai );
539
540 if ( ai->visible )
541 dirty_rect.add( ai->pos );
542
543 return RET_CONTINUE;
544 }
545
splitCommand()546 int ONScripter::splitCommand()
547 {
548 script_h.readStr();
549 const char *save_buf = script_h.saveStringBuffer();
550
551 char delimiter = script_h.readStr()[0];
552
553 char token256[256], *token=NULL;
554 while( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
555
556 unsigned int c=0;
557 while(save_buf[c] != delimiter && save_buf[c] != '\0')
558 c += script_h.enc.getBytes(save_buf[c]);
559
560 if (c < 256)
561 token = token256;
562 else
563 token = new char[c+1];
564
565 memcpy( token, save_buf, c );
566 token[c] = '\0';
567
568 script_h.readVariable();
569 if ( script_h.current_variable.type & ScriptHandler::VAR_INT ||
570 script_h.current_variable.type & ScriptHandler::VAR_ARRAY ){
571 script_h.setInt( &script_h.current_variable, atoi(token) );
572 }
573 else if ( script_h.current_variable.type & ScriptHandler::VAR_STR ){
574 setStr( &script_h.getVariableData(script_h.current_variable.var_no).str, token );
575 }
576
577 if (c >= 256) delete[] token;
578
579 save_buf += c;
580 if (save_buf[0] != '\0') save_buf++;
581 }
582
583 return RET_CONTINUE;
584 }
585
spclclkCommand()586 int ONScripter::spclclkCommand()
587 {
588 if ( !force_button_shortcut_flag )
589 spclclk_flag = true;
590 return RET_CONTINUE;
591 }
592
spbtnCommand()593 int ONScripter::spbtnCommand()
594 {
595 bool cellcheck_flag = false;
596
597 if ( script_h.isName( "cellcheckspbtn" ) )
598 cellcheck_flag = true;
599
600 int sprite_no = script_h.readInt();
601 int no = script_h.readInt();
602 if (no < 1 ||
603 sprite_no < 0 ||
604 sprite_no >= MAX_SPRITE_NUM ||
605 sprite_info[sprite_no].image_surface == NULL)
606 return RET_CONTINUE;
607
608 if ( cellcheck_flag ){
609 if ( sprite_info[ sprite_no ].num_of_cells < 2 ) return RET_CONTINUE;
610 }
611 else{
612 if ( sprite_info[ sprite_no ].num_of_cells == 0 ) return RET_CONTINUE;
613 }
614
615 ButtonLink *button = new ButtonLink();
616 root_button_link.insert( button );
617
618 button->button_type = ButtonLink::SPRITE_BUTTON;
619 button->sprite_no = sprite_no;
620 button->no = no;
621
622 if ( sprite_info[ sprite_no ].image_surface ||
623 sprite_info[ sprite_no ].trans_mode == AnimationInfo::TRANS_STRING )
624 button->image_rect = button->select_rect = sprite_info[ sprite_no ].pos;
625
626 return RET_CONTINUE;
627 }
628
skipoffCommand()629 int ONScripter::skipoffCommand()
630 {
631 skip_mode &= ~SKIP_NORMAL;
632
633 return RET_CONTINUE;
634 }
635
showlangjpCommand()636 int ONScripter::showlangjpCommand()
637 {
638 script_h.current_language = 1;
639
640 text_info.fill( 0, 0, 0, 0 );
641 flush(refreshMode(), &sentence_font_info.pos);
642
643 return RET_CONTINUE;
644 }
645
showlangenCommand()646 int ONScripter::showlangenCommand()
647 {
648 script_h.current_language = 0;
649
650 text_info.fill( 0, 0, 0, 0 );
651 flush(refreshMode(), &sentence_font_info.pos);
652
653 return RET_CONTINUE;
654 }
655
sevolCommand()656 int ONScripter::sevolCommand()
657 {
658 se_volume = script_h.readInt();
659
660 for ( int i=1 ; i<ONS_MIX_CHANNELS ; i++ )
661 if ( wave_sample[i] ) Mix_Volume( i, se_volume * MIX_MAX_VOLUME / 100 );
662
663 if ( wave_sample[MIX_LOOPBGM_CHANNEL0] ) Mix_Volume( MIX_LOOPBGM_CHANNEL0, se_volume * MIX_MAX_VOLUME / 100 );
664 if ( wave_sample[MIX_LOOPBGM_CHANNEL1] ) Mix_Volume( MIX_LOOPBGM_CHANNEL1, se_volume * MIX_MAX_VOLUME / 100 );
665
666 return RET_CONTINUE;
667 }
668
setwindowCore()669 void ONScripter::setwindowCore()
670 {
671 sentence_font.ttf_font[0] = NULL;
672 sentence_font.ttf_font[1] = NULL;
673 sentence_font.top_xy[0] = script_h.readInt();
674 sentence_font.top_xy[1] = script_h.readInt();
675 sentence_font.num_xy[0] = script_h.readInt();
676 sentence_font.num_xy[1] = script_h.readInt();
677 sentence_font.font_size_xy[0] = script_h.readInt();
678 sentence_font.font_size_xy[1] = script_h.readInt();
679 sentence_font.pitch_xy[0] = script_h.readInt() + sentence_font.font_size_xy[0];
680 sentence_font.pitch_xy[1] = script_h.readInt() + sentence_font.font_size_xy[1];
681 sentence_font.wait_time = script_h.readInt();
682 sentence_font.is_bold = script_h.readInt()?true:false;
683 sentence_font.is_shadow = script_h.readInt()?true:false;
684
685 const char *buf = script_h.readStr();
686 dirty_rect.add( sentence_font_info.pos );
687
688 AnimationInfo *ai = &sentence_font_info;
689 if ( buf[0] == '#' ){
690 sentence_font.is_transparent = true;
691 readColor( &sentence_font.window_color, buf );
692
693 ai->remove();
694 ai->orig_pos.x = script_h.readInt();
695 ai->orig_pos.y = script_h.readInt();
696 ai->orig_pos.w = script_h.readInt() - ai->orig_pos.x + 1;
697 ai->orig_pos.h = script_h.readInt() - ai->orig_pos.y + 1;
698 ai->scalePosXY( screen_ratio1, screen_ratio2 );
699 ai->scalePosWH( screen_ratio1, screen_ratio2 );
700 }
701 else{
702 if (buf[0] != 0){
703 ai->setImageName(buf);
704 parseTaggedString(ai);
705 setupAnimationInfo(ai);
706 }
707 ai->orig_pos.x = script_h.readInt();
708 ai->orig_pos.y = script_h.readInt();
709 if (script_h.getEndStatus() & ScriptHandler::END_COMMA)
710 script_h.readInt();
711 if (script_h.getEndStatus() & ScriptHandler::END_COMMA)
712 script_h.readInt();
713 ai->scalePosXY( screen_ratio1, screen_ratio2 );
714
715 sentence_font.is_transparent = false;
716 sentence_font.window_color[0] = sentence_font.window_color[1] = sentence_font.window_color[2] = 0xff;
717 }
718
719 sentence_font.old_xy[0] = sentence_font.x(false);
720 sentence_font.old_xy[1] = sentence_font.y(false);
721 }
722
setwindow3Command()723 int ONScripter::setwindow3Command()
724 {
725 setwindowCore();
726
727 clearCurrentPage();
728 indent_offset = 0;
729 line_enter_status = 0;
730 page_enter_status = 0;
731 display_mode = DISPLAY_MODE_NORMAL;
732 flush( refreshMode(), &sentence_font_info.pos );
733
734 return RET_CONTINUE;
735 }
736
setwindow2Command()737 int ONScripter::setwindow2Command()
738 {
739 const char *buf = script_h.readStr();
740 if ( buf[0] == '#' ){
741 sentence_font.is_transparent = true;
742 readColor( &sentence_font.window_color, buf );
743 sentence_font_info.remove();
744 }
745 else{
746 sentence_font.is_transparent = false;
747 sentence_font_info.setImageName( buf );
748 parseTaggedString( &sentence_font_info );
749 setupAnimationInfo( &sentence_font_info );
750 }
751 repaintCommand();
752
753 return RET_CONTINUE;
754 }
755
setwindowCommand()756 int ONScripter::setwindowCommand()
757 {
758 setwindowCore();
759
760 lookbackflushCommand();
761 indent_offset = 0;
762 line_enter_status = 0;
763 page_enter_status = 0;
764 display_mode = DISPLAY_MODE_NORMAL;
765 flush( refreshMode(), &sentence_font_info.pos );
766
767 return RET_CONTINUE;
768 }
769
setcursorCommand()770 int ONScripter::setcursorCommand()
771 {
772 bool abs_flag;
773
774 if ( script_h.isName( "abssetcursor" ) ){
775 abs_flag = true;
776 }
777 else{
778 abs_flag = false;
779 }
780
781 int no = script_h.readInt();
782 script_h.readStr();
783 const char* buf = script_h.saveStringBuffer();
784 int x = script_h.readInt();
785 int y = script_h.readInt();
786
787 loadCursor( no, buf, x, y, abs_flag );
788
789 return RET_CONTINUE;
790 }
791
selectCommand()792 int ONScripter::selectCommand()
793 {
794 enterTextDisplayMode();
795
796 int select_mode = SELECT_GOTO_MODE;
797 SelectLink *last_select_link;
798
799 if ( script_h.isName( "selnum" ) )
800 select_mode = SELECT_NUM_MODE;
801 else if ( script_h.isName( "selgosub" ) )
802 select_mode = SELECT_GOSUB_MODE;
803 else if ( script_h.isName( "select" ) )
804 select_mode = SELECT_GOTO_MODE;
805 else if ( script_h.isName( "csel" ) )
806 select_mode = SELECT_CSEL_MODE;
807
808 if ( select_mode == SELECT_NUM_MODE ){
809 script_h.readVariable();
810 script_h.pushVariable();
811 }
812
813 bool comma_flag = true;
814 if ( select_mode == SELECT_CSEL_MODE ){
815 if (saveon_flag && internal_saveon_flag) storeSaveFile();
816 saveon_flag = false;
817 }
818 shortcut_mouse_line = -1;
819
820 int xy[2];
821 xy[0] = sentence_font.xy[0];
822 xy[1] = sentence_font.xy[1];
823
824 if ( selectvoice_file_name[SELECTVOICE_OPEN] )
825 playSound(selectvoice_file_name[SELECTVOICE_OPEN],
826 SOUND_CHUNK, false, MIX_WAVE_CHANNEL );
827
828 last_select_link = &root_select_link;
829
830 while(1){
831 if ( script_h.getNext()[0] != 0x0a && comma_flag == true ){
832
833 const char *buf = script_h.readStr();
834 comma_flag = (script_h.getEndStatus() & ScriptHandler::END_COMMA);
835 if ( select_mode != SELECT_NUM_MODE && !comma_flag )
836 errorAndExit( "select: missing comma." );
837
838 // Text part
839 SelectLink *slink = new SelectLink();
840 setStr( &slink->text, buf );
841 //printf("Select text %s\n", slink->text);
842
843 // Label part
844 if (select_mode != SELECT_NUM_MODE){
845 script_h.readStr();
846 setStr( &slink->label, script_h.getStringBuffer()+1 );
847 //printf("Select label %s\n", slink->label );
848 }
849 last_select_link->next = slink;
850 last_select_link = last_select_link->next;
851
852 comma_flag = (script_h.getEndStatus() & ScriptHandler::END_COMMA);
853 //printf("2 comma %d %c %x\n", comma_flag, script_h.getCurrent()[0], script_h.getCurrent()[0]);
854 }
855 else if (script_h.getNext()[0] == 0x0a){
856 //printf("comma %d\n", comma_flag);
857 char *buf = script_h.getNext() + 1; // consume eol
858 while ( *buf == ' ' || *buf == '\t' ) buf++;
859
860 if (comma_flag && *buf == ',')
861 errorAndExit( "select: double comma." );
862
863 bool comma2_flag = false;
864 if (*buf == ','){
865 comma2_flag = true;
866 buf++;
867 while ( *buf == ' ' || *buf == '\t' ) buf++;
868 }
869 script_h.setCurrent(buf);
870
871 if (*buf == 0x0a){
872 comma_flag |= comma2_flag;
873 continue;
874 }
875
876 if (!comma_flag && !comma2_flag){
877 select_label_info.next_script = buf;
878 //printf("select: stop at the end of line\n");
879 break;
880 }
881
882 //printf("continue\n");
883 comma_flag = true;
884 }
885 else{ // if select ends at the middle of the line
886 select_label_info.next_script = script_h.getNext();
887 //printf("select: stop at the middle of the line\n");
888 break;
889 }
890 }
891
892 if ( select_mode != SELECT_CSEL_MODE ){
893 last_select_link = root_select_link.next;
894 int counter = 1;
895 while( last_select_link ){
896 if ( *last_select_link->text ){
897 ButtonLink *button = getSelectableSentence( last_select_link->text, &sentence_font );
898 root_button_link.insert( button );
899 button->no = counter;
900 }
901 counter++;
902 last_select_link = last_select_link->next;
903 }
904 }
905
906 if ( select_mode == SELECT_CSEL_MODE ){
907 setCurrentLabel( "customsel" );
908 return RET_CONTINUE;
909 }
910 automode_flag = false;
911 sentence_font.xy[0] = xy[0];
912 sentence_font.xy[1] = xy[1];
913
914 flush( refreshMode() );
915
916 refreshMouseOverButton();
917
918 event_mode = WAIT_TEXT_MODE | WAIT_BUTTON_MODE | WAIT_TIMER_MODE;
919 do{
920 skip_mode &= ~SKIP_NORMAL;
921 if (waitEvent(-1)) return RET_CONTINUE;
922 }
923 while(current_button_state.button <= 0 || skip_mode & SKIP_NORMAL);
924
925 if ( selectvoice_file_name[SELECTVOICE_SELECT] )
926 playSound(selectvoice_file_name[SELECTVOICE_SELECT],
927 SOUND_CHUNK, false, MIX_WAVE_CHANNEL );
928
929 deleteButtonLink();
930
931 int counter = 1;
932 last_select_link = root_select_link.next;
933 while ( last_select_link ){
934 if ( current_button_state.button == counter++ ) break;
935 last_select_link = last_select_link->next;
936 }
937
938 if ( select_mode == SELECT_GOTO_MODE ){
939 setCurrentLabel( last_select_link->label );
940 }
941 else if ( select_mode == SELECT_GOSUB_MODE ){
942 gosubReal( last_select_link->label, select_label_info.next_script );
943 }
944 else{ // selnum
945 script_h.setInt( &script_h.pushed_variable, current_button_state.button - 1 );
946 current_label_info = script_h.getLabelByAddress( select_label_info.next_script );
947 current_line = script_h.getLineByAddress( select_label_info.next_script );
948 script_h.setCurrent( select_label_info.next_script );
949 }
950 deleteSelectLink();
951
952 newPage();
953
954 return RET_CONTINUE;
955 }
956
savetimeCommand()957 int ONScripter::savetimeCommand()
958 {
959 int no = script_h.readInt();
960
961 SaveFileInfo info;
962 searchSaveFile( info, no );
963
964 script_h.readVariable();
965 if ( !info.valid ){
966 script_h.setInt( &script_h.current_variable, 0 );
967 for ( int i=0 ; i<3 ; i++ )
968 script_h.readVariable();
969 return RET_CONTINUE;
970 }
971
972 script_h.setInt( &script_h.current_variable, info.month );
973 script_h.readInt();
974 script_h.setInt( &script_h.current_variable, info.day );
975 script_h.readInt();
976 script_h.setInt( &script_h.current_variable, info.hour );
977 script_h.readInt();
978 script_h.setInt( &script_h.current_variable, info.minute );
979
980 return RET_CONTINUE;
981 }
982
savescreenshotCommand()983 int ONScripter::savescreenshotCommand()
984 {
985 if ( script_h.isName( "savescreenshot" ) ){
986 }
987 else if ( script_h.isName( "savescreenshot2" ) ){
988 }
989
990 SDL_Surface *surface = AnimationInfo::alloc32bitSurface( screenshot_w, screenshot_h, texture_format );
991 resizeSurface( screenshot_surface, surface );
992
993 const char *buf = script_h.readStr();
994 if (script_h.enc.getEncoding() == Encoding::CODE_UTF8){
995 char *dir = new char[strlen(archive_path) + strlen(buf) + 1];
996 sprintf(dir, "%s%s", archive_path, buf);
997 for (int i=strlen(dir)-1; i>=0; i--){
998 if (dir[i] == '/' || dir[i] == '\\'){
999 dir[i] = 0;
1000 #if defined(LINUX) || defined(MACOSX) || defined(IOS)
1001 mkdir(dir, 0755);
1002 #elif defined(WIN32)
1003 _mkdir(dir);
1004 #endif
1005 break;
1006 }
1007 }
1008 delete[] dir;
1009 }
1010
1011 FILE *fp = fopen(buf, "wb");
1012 if (fp){
1013 SDL_RWops *rwops = SDL_RWFromFP(fp, SDL_TRUE);
1014 SDL_SaveBMP_RW(surface, rwops, 1);
1015 }
1016 SDL_FreeSurface(surface);
1017
1018 return RET_CONTINUE;
1019 }
1020
savepointCommand()1021 int ONScripter::savepointCommand()
1022 {
1023 storeSaveFile();
1024
1025 return RET_CONTINUE;
1026 }
1027
saveonCommand()1028 int ONScripter::saveonCommand()
1029 {
1030 if (!autosaveoff_flag)
1031 saveon_flag = true;
1032
1033 return RET_CONTINUE;
1034 }
1035
saveoffCommand()1036 int ONScripter::saveoffCommand()
1037 {
1038 if (!autosaveoff_flag){
1039 if (saveon_flag && internal_saveon_flag) storeSaveFile();
1040
1041 saveon_flag = false;
1042 }
1043
1044 return RET_CONTINUE;
1045 }
1046
savegameCommand()1047 int ONScripter::savegameCommand()
1048 {
1049 bool savegame2_flag = false;
1050 if ( script_h.isName( "savegame2" ) )
1051 savegame2_flag = true;
1052
1053 int no = script_h.readInt();
1054
1055 const char* savestr = NULL;
1056 if (savegame2_flag)
1057 savestr = script_h.readStr();
1058
1059 if (saveon_flag && internal_saveon_flag) storeSaveFile();
1060 writeSaveFile( no, savestr );
1061
1062 return RET_CONTINUE;
1063 }
1064
savefileexistCommand()1065 int ONScripter::savefileexistCommand()
1066 {
1067 script_h.readInt();
1068 script_h.pushVariable();
1069 int no = script_h.readInt();
1070
1071 SaveFileInfo info;
1072 searchSaveFile( info, no );
1073
1074 script_h.setInt( &script_h.pushed_variable, (info.valid==true)?1:0 );
1075
1076 return RET_CONTINUE;
1077 }
1078
rndCommand()1079 int ONScripter::rndCommand()
1080 {
1081 int upper, lower;
1082
1083 if ( script_h.isName( "rnd2" ) ){
1084 script_h.readInt();
1085 script_h.pushVariable();
1086
1087 lower = script_h.readInt();
1088 upper = script_h.readInt();
1089 }
1090 else{
1091 script_h.readInt();
1092 script_h.pushVariable();
1093
1094 lower = 0;
1095 upper = script_h.readInt() - 1;
1096 }
1097
1098 script_h.setInt( &script_h.pushed_variable, lower + (int)( (double)(upper-lower+1)*rand()/(RAND_MAX+1.0)) );
1099
1100 return RET_CONTINUE;
1101 }
1102
rmodeCommand()1103 int ONScripter::rmodeCommand()
1104 {
1105 if ( script_h.readInt() == 1 ) rmode_flag = true;
1106 else rmode_flag = false;
1107
1108 return RET_CONTINUE;
1109 }
1110
resettimerCommand()1111 int ONScripter::resettimerCommand()
1112 {
1113 internal_timer = SDL_GetTicks();
1114
1115 return RET_CONTINUE;
1116 }
1117
resetCommand()1118 int ONScripter::resetCommand()
1119 {
1120 int fadeout = mp3fadeout_duration;
1121 mp3fadeout_duration = 0; //don't use fadeout during a reset
1122 resetSub();
1123 mp3fadeout_duration = fadeout;
1124
1125 start_page = current_page = &page_list[0];
1126 clearCurrentPage();
1127 flush( refreshMode(), &sentence_font_info.pos );
1128
1129 /* Initialize local variables */
1130 for (int i=0 ; i<script_h.global_variable_border ; i++)
1131 script_h.getVariableData(i).reset(false);
1132
1133 setCurrentLabel( "start" );
1134 storeSaveFile();
1135
1136 return RET_CONTINUE;
1137 }
1138
repaintCommand()1139 int ONScripter::repaintCommand()
1140 {
1141 dirty_rect.fill( screen_width, screen_height );
1142 flush( refreshMode() );
1143
1144 return RET_CONTINUE;
1145 }
1146
quakeCommand()1147 int ONScripter::quakeCommand()
1148 {
1149 int quake_type;
1150
1151 if ( script_h.isName( "quakey" ) ){
1152 quake_type = 0;
1153 }
1154 else if ( script_h.isName( "quakex" ) ){
1155 quake_type = 1;
1156 }
1157 else{
1158 quake_type = 2;
1159 }
1160
1161 tmp_effect.no = script_h.readInt();
1162 tmp_effect.duration = script_h.readInt();
1163 if ( tmp_effect.duration < tmp_effect.no * 4 ) tmp_effect.duration = tmp_effect.no * 4;
1164 tmp_effect.effect = MAX_EFFECT_NUM + quake_type;
1165
1166 dirty_rect.fill( screen_width, screen_height );
1167 SDL_BlitSurface( accumulation_surface, NULL, effect_dst_surface, NULL );
1168
1169 if (setEffect(&tmp_effect)) return RET_CONTINUE;
1170 while (doEffect(&tmp_effect));
1171
1172 return RET_CONTINUE;
1173 }
1174
puttextCommand()1175 int ONScripter::puttextCommand()
1176 {
1177 enterTextDisplayMode(false);
1178
1179 script_h.readStr();
1180
1181 string_buffer_offset = 0;
1182 if (script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR)
1183 string_buffer_offset = 1; // skip the heading `
1184
1185 int s = line_enter_status;
1186 while(processText());
1187 line_enter_status = s;
1188
1189 return RET_CONTINUE;
1190 }
1191
prnumclearCommand()1192 int ONScripter::prnumclearCommand()
1193 {
1194 for ( int i=0 ; i<MAX_PARAM_NUM ; i++ ) {
1195 if ( prnum_info[i] ) {
1196 dirty_rect.add( prnum_info[i]->pos );
1197 delete prnum_info[i];
1198 prnum_info[i] = NULL;
1199 }
1200 }
1201 return RET_CONTINUE;
1202 }
1203
prnumCommand()1204 int ONScripter::prnumCommand()
1205 {
1206 leaveTextDisplayMode();
1207
1208 int no = script_h.readInt();
1209 if (no < 0 || no >= MAX_PARAM_NUM){
1210 script_h.readInt();
1211 script_h.readInt();
1212 script_h.readInt();
1213 script_h.readInt();
1214 script_h.readInt();
1215 script_h.readStr();
1216 return RET_CONTINUE;
1217 }
1218
1219 if ( prnum_info[no] ){
1220 dirty_rect.add( prnum_info[no]->pos );
1221 delete prnum_info[no];
1222 }
1223 AnimationInfo *ai = prnum_info[no] = new AnimationInfo();
1224 ai->trans_mode = AnimationInfo::TRANS_STRING;
1225 ai->num_of_cells = 1;
1226 ai->setCell(0);
1227 ai->color_list = new uchar3[ ai->num_of_cells ];
1228
1229 ai->param = script_h.readInt();
1230 ai->orig_pos.x = script_h.readInt();
1231 ai->orig_pos.y = script_h.readInt();
1232 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1233 ai->font_size_xy[0] = script_h.readInt();
1234 ai->font_size_xy[1] = script_h.readInt();
1235 ai->font_pitch[0] = ai->font_size_xy[0];
1236 ai->font_pitch[1] = ai->font_size_xy[1];
1237
1238 const char *buf = script_h.readStr();
1239 readColor( &ai->color_list[0], buf );
1240
1241 char num_buf[7];
1242 script_h.getStringFromInteger( num_buf, ai->param, 3 );
1243 setStr( &ai->file_name, num_buf );
1244
1245 setupAnimationInfo( ai );
1246 dirty_rect.add( ai->pos );
1247
1248 return RET_CONTINUE;
1249 }
1250
printCommand()1251 int ONScripter::printCommand()
1252 {
1253 leaveTextDisplayMode();
1254
1255 EffectLink *el = parseEffect(true);
1256 if (setEffect(el)) return RET_CONTINUE;
1257 while (doEffect(el));
1258
1259 return RET_CONTINUE;
1260 }
1261
playstopCommand()1262 int ONScripter::playstopCommand()
1263 {
1264 stopBGM( false );
1265
1266 return RET_CONTINUE;
1267 }
1268
playCommand()1269 int ONScripter::playCommand()
1270 {
1271 bool loop_flag = true;
1272 if ( script_h.isName( "playonce" ) )
1273 loop_flag = false;
1274
1275 const char *buf = script_h.readStr();
1276 if ( buf[0] == '*' ){
1277 cd_play_loop_flag = loop_flag;
1278 int new_cd_track = atoi( buf + 1 );
1279 #ifdef CONTINUOUS_PLAY
1280 if ( current_cd_track != new_cd_track ) {
1281 #endif
1282 stopBGM( false );
1283 current_cd_track = new_cd_track;
1284 playCDAudio();
1285 #ifdef CONTINUOUS_PLAY
1286 }
1287 #endif
1288 }
1289 else{ // play MIDI
1290 stopBGM( false );
1291
1292 setStr(&midi_file_name, buf);
1293 midi_play_loop_flag = loop_flag;
1294 if (playSound(midi_file_name, SOUND_MIDI, midi_play_loop_flag) != SOUND_MIDI){
1295 fprintf(stderr, "can't play MIDI file %s\n", midi_file_name);
1296 }
1297 }
1298
1299 return RET_CONTINUE;
1300 }
1301
ofscopyCommand()1302 int ONScripter::ofscopyCommand()
1303 {
1304 #ifdef USE_SDL_RENDERER
1305 SDL_Surface *tmp_surface = AnimationInfo::alloc32bitSurface( screen_device_width, screen_device_height, texture_format );
1306 SDL_Rect rect = {(device_width -screen_device_width)/2,
1307 (device_height-screen_device_height)/2,
1308 screen_device_width, screen_device_height};
1309 SDL_LockSurface(tmp_surface);
1310 SDL_RenderReadPixels(renderer, &rect, tmp_surface->format->format, tmp_surface->pixels, tmp_surface->pitch);
1311 SDL_UnlockSurface(tmp_surface);
1312 resizeSurface( tmp_surface, accumulation_surface );
1313 SDL_FreeSurface(tmp_surface);
1314 #else
1315 SDL_BlitSurface(screen_surface, NULL, accumulation_surface, NULL);
1316 #endif
1317
1318 return RET_CONTINUE;
1319 }
1320
negaCommand()1321 int ONScripter::negaCommand()
1322 {
1323 nega_mode = script_h.readInt();
1324
1325 dirty_rect.fill( screen_width, screen_height );
1326
1327 return RET_CONTINUE;
1328 }
1329
nextcselCommand()1330 int ONScripter::nextcselCommand()
1331 {
1332 script_h.readInt();
1333
1334 if (last_nest_info != &root_nest_info &&
1335 last_nest_info->nest_mode == NestInfo::LABEL){
1336 char *buf = last_nest_info->next_script;
1337 while (*buf == ' ' || *buf == '\t' || *buf == 0x0a) buf++;
1338 if (strncmp( buf, "csel", 4) == 0)
1339 script_h.setInt( &script_h.current_variable, 1 );
1340 else
1341 script_h.setInt( &script_h.current_variable, 0 );
1342 }
1343 else
1344 script_h.setInt( &script_h.current_variable, 0 );
1345
1346 return RET_CONTINUE;
1347 }
1348
mspCommand()1349 int ONScripter::mspCommand()
1350 {
1351 leaveTextDisplayMode();
1352
1353 bool msp2_flag = false;
1354 if (script_h.isName("msp2")) msp2_flag = true;
1355
1356 int no = script_h.readInt();
1357 AnimationInfo *ai = NULL;
1358 if (msp2_flag) {
1359 ai = &sprite2_info[no];
1360 dirty_rect.add( ai->bounding_rect );
1361 }
1362 else{
1363 ai = &sprite_info[no];
1364 dirty_rect.add( ai->pos );
1365 }
1366
1367 ai->orig_pos.x += script_h.readInt();
1368 ai->orig_pos.y += script_h.readInt();
1369 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1370 if (msp2_flag){
1371 ai->scale_x += script_h.readInt();
1372 ai->scale_y += script_h.readInt();
1373 ai->rot += script_h.readInt();
1374 ai->calcAffineMatrix();
1375 dirty_rect.add( ai->bounding_rect );
1376 }
1377 else{
1378 dirty_rect.add( ai->pos );
1379 }
1380
1381 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
1382 if (ai->trans == -1)
1383 ai->trans = 255 + script_h.readInt();
1384 else
1385 ai->trans += script_h.readInt();
1386 if (ai->trans < 0) ai->trans = 0;
1387 else if (ai->trans > 255) ai->trans = 255;
1388 }
1389
1390 return RET_CONTINUE;
1391 }
1392
mpegplayCommand()1393 int ONScripter::mpegplayCommand()
1394 {
1395 script_h.readStr();
1396 const char *save_buf = script_h.saveStringBuffer();
1397
1398 bool click_flag = (script_h.readInt()==1)?true:false;
1399
1400 stopBGM( false );
1401 if (playMPEG( save_buf, click_flag )) endCommand();
1402
1403 repaintCommand();
1404
1405 return RET_CONTINUE;
1406 }
1407
mp3volCommand()1408 int ONScripter::mp3volCommand()
1409 {
1410 music_volume = script_h.readInt();
1411 Mix_VolumeMusic( music_volume * MIX_MAX_VOLUME / 100 );
1412
1413 return RET_CONTINUE;
1414 }
1415
mp3stopCommand()1416 int ONScripter::mp3stopCommand()
1417 {
1418 if (Mix_PlayingMusic() == 1 && timer_bgmfade_id && mp3fadeout_duration_internal > 0) // already in fadeout
1419 return RET_CONTINUE;
1420
1421 if (Mix_PlayingMusic() == 1 && mp3fadeout_duration > 0){
1422 // do a bgm fadeout
1423 Mix_HookMusicFinished( NULL );
1424 mp3fadeout_duration_internal = mp3fadeout_duration;
1425 mp3fade_start = SDL_GetTicks();
1426 timer_bgmfade_id = SDL_AddTimer(20, bgmfadeCallback, 0);
1427 setStr(&fadeout_music_file_name, music_file_name);
1428
1429 char *ext = NULL;
1430 if (music_file_name) ext = strrchr(music_file_name, '.');
1431 if (ext && (!strcmp(ext+1, "OGG") || !strcmp(ext+1, "ogg"))){
1432 // do not wait until fadout is finished when playing ogg
1433 event_mode = IDLE_EVENT_MODE;
1434 waitEvent(0);
1435 setStr( &music_file_name, NULL ); // to ensure not to play music during fadeout
1436
1437 return RET_CONTINUE;
1438 }
1439 else{
1440 // wait until fadout is finished when playing music other than ogg
1441 event_mode = WAIT_TIMER_MODE;
1442 waitEvent(-1);
1443 }
1444 }
1445
1446 stopBGM( false );
1447
1448 return RET_CONTINUE;
1449 }
1450
mp3fadeoutCommand()1451 int ONScripter::mp3fadeoutCommand()
1452 {
1453 mp3fadeout_duration = script_h.readInt();
1454
1455 return RET_CONTINUE;
1456 }
1457
mp3fadeinCommand()1458 int ONScripter::mp3fadeinCommand()
1459 {
1460 mp3fadein_duration = script_h.readInt();
1461
1462 return RET_CONTINUE;
1463 }
1464
mp3Command()1465 int ONScripter::mp3Command()
1466 {
1467 bool loop_flag = false;
1468 if ( script_h.isName( "mp3save" ) ){
1469 mp3save_flag = true;
1470 }
1471 else if ( script_h.isName( "bgmonce" ) ){
1472 mp3save_flag = false;
1473 }
1474 else if ( script_h.isName( "mp3loop" ) ||
1475 script_h.isName( "bgm" ) ){
1476 mp3save_flag = true;
1477 loop_flag = true;
1478 }
1479 else{
1480 mp3save_flag = false;
1481 }
1482
1483 mp3stopCommand();
1484 stopBGM( false );
1485
1486 music_play_loop_flag = loop_flag;
1487 music_loopback_offset = 0.0;
1488
1489 const char *buf = script_h.readStr();
1490 if (buf[0] != '\0'){
1491 if (buf[0]=='('){
1492 buf++;
1493 bool integer_flag = true;
1494 double decimal = 0.1;
1495 while (*buf != ')' && *buf != '\0'){
1496 if (*buf >= '0' && *buf <= '9'){
1497 if (integer_flag)
1498 music_loopback_offset = music_loopback_offset*10.0 + *buf - '0';
1499 else{
1500 music_loopback_offset += decimal*(*buf - '0');
1501 decimal *= 0.1;
1502 }
1503 }
1504 else if (*buf == '.')
1505 integer_flag = false;
1506 buf++;
1507 }
1508 if (*buf == ')') buf++;
1509 }
1510
1511 int tmp = music_volume;
1512 setStr(&music_file_name, buf);
1513
1514 if (mp3fadein_duration > 0)
1515 music_volume = 0;
1516
1517 playSound(music_file_name,
1518 SOUND_MUSIC | SOUND_MIDI | SOUND_CHUNK,
1519 music_play_loop_flag, MIX_BGM_CHANNEL);
1520
1521 music_volume = tmp;
1522
1523 if (mp3fadein_duration > 0) {
1524 // do a bgm fadein
1525 mp3fadein_duration_internal = mp3fadein_duration;
1526 mp3fade_start = SDL_GetTicks();
1527 timer_bgmfade_id = SDL_AddTimer(20, bgmfadeCallback,
1528 (void*)&timer_bgmfade_id);
1529
1530 char *ext = NULL;
1531 if (music_file_name) ext = strrchr(music_file_name, '.');
1532 if (ext && (!strcmp(ext+1, "OGG") || !strcmp(ext+1, "ogg"))){
1533 // do not wait until fadin is finished when playing ogg
1534 event_mode = IDLE_EVENT_MODE;
1535 waitEvent(0);
1536 }
1537 else{
1538 // wait until fadin is finished when playing music other than ogg
1539 event_mode = WAIT_TIMER_MODE;
1540 waitEvent(-1);
1541 }
1542 }
1543 }
1544
1545 return RET_CONTINUE;
1546 }
1547
movieCommand()1548 int ONScripter::movieCommand()
1549 {
1550 if (script_h.compareString("stop")){
1551 script_h.readLabel();
1552 fprintf(stderr, " [movie stop] is not supported yet!!\n");
1553 return RET_CONTINUE;
1554 }
1555
1556 script_h.readStr();
1557 const char *filename = script_h.saveStringBuffer();
1558
1559 bool click_flag = false;
1560 bool loop_flag = false;
1561 bool nosound_flag = false;
1562
1563 while (script_h.getEndStatus() & ScriptHandler::END_COMMA){
1564 if (script_h.compareString("pos")){ // not supported yet
1565 script_h.readLabel();
1566 script_h.readInt();
1567 script_h.readInt();
1568 script_h.readInt();
1569 script_h.readInt();
1570 fprintf(stderr, " [movie pos] is not supported yet!!\n");
1571 }
1572 else if (script_h.compareString("click")){
1573 script_h.readLabel();
1574 click_flag = true;
1575 }
1576 else if (script_h.compareString("loop")){
1577 script_h.readLabel();
1578 loop_flag = true;
1579 }
1580 else if (script_h.compareString("async")){ // not supported yet
1581 script_h.readLabel();
1582 fprintf(stderr, " [movie async] is not supported yet!!\n");
1583 }
1584 else if (script_h.compareString("nosound")){
1585 script_h.readLabel();
1586 nosound_flag = true;
1587 }
1588 else{
1589 script_h.readLabel();
1590 }
1591 }
1592
1593 if (!nosound_flag) stopBGM(false);
1594
1595 if (playMPEG(filename, click_flag, loop_flag, nosound_flag)) endCommand();
1596
1597 return RET_CONTINUE;
1598 }
1599
movemousecursorCommand()1600 int ONScripter::movemousecursorCommand()
1601 {
1602 int x = script_h.readInt() * screen_ratio1 / screen_ratio2;
1603 int y = script_h.readInt() * screen_ratio1 / screen_ratio2;
1604 x = x * screen_device_width / screen_width;
1605 y = y * screen_device_width / screen_width;
1606
1607 SDL_WarpMouse(x, y);
1608
1609 return RET_CONTINUE;
1610 }
1611
monocroCommand()1612 int ONScripter::monocroCommand()
1613 {
1614 if ( script_h.compareString( "off" ) ){
1615 script_h.readLabel();
1616 monocro_flag = false;
1617 }
1618 else{
1619 monocro_flag = true;
1620 readColor( &monocro_color, script_h.readStr() );
1621
1622 for (int i=0 ; i<256 ; i++){
1623 monocro_color_lut[i][0] = (monocro_color[0] * i) >> 8;
1624 monocro_color_lut[i][1] = (monocro_color[1] * i) >> 8;
1625 monocro_color_lut[i][2] = (monocro_color[2] * i) >> 8;
1626 }
1627 }
1628
1629 dirty_rect.fill( screen_width, screen_height );
1630
1631 return RET_CONTINUE;
1632 }
1633
menu_windowCommand()1634 int ONScripter::menu_windowCommand()
1635 {
1636 if ( fullscreen_mode ){
1637 #if !defined(PSP)
1638 if ( !SDL_WM_ToggleFullScreen( screen_surface ) ){
1639 screen_surface = SDL_SetVideoMode( screen_device_width, screen_device_height, screen_bpp, DEFAULT_VIDEO_SURFACE_FLAG );
1640 #ifdef ANDROID
1641 SDL_SetSurfaceBlendMode(screen_surface, SDL_BLENDMODE_NONE);
1642 #endif
1643 flushDirect( screen_rect, refreshMode() );
1644 }
1645 #endif
1646 fullscreen_mode = false;
1647 }
1648
1649 return RET_CONTINUE;
1650 }
1651
menu_fullCommand()1652 int ONScripter::menu_fullCommand()
1653 {
1654 if ( !fullscreen_mode ){
1655 #if !defined(PSP)
1656 if ( !SDL_WM_ToggleFullScreen( screen_surface ) ){
1657 screen_surface = SDL_SetVideoMode( screen_device_width, screen_device_height, screen_bpp, DEFAULT_VIDEO_SURFACE_FLAG|SDL_FULLSCREEN );
1658 #ifdef ANDROID
1659 SDL_SetSurfaceBlendMode(screen_surface, SDL_BLENDMODE_NONE);
1660 #endif
1661 flushDirect( screen_rect, refreshMode() );
1662 }
1663 #endif
1664 fullscreen_mode = true;
1665 }
1666
1667 return RET_CONTINUE;
1668 }
1669
menu_click_pageCommand()1670 int ONScripter::menu_click_pageCommand()
1671 {
1672 skip_mode |= SKIP_TO_EOP;
1673 return RET_CONTINUE;
1674 }
1675
menu_click_defCommand()1676 int ONScripter::menu_click_defCommand()
1677 {
1678 skip_mode &= ~SKIP_TO_EOP;
1679 return RET_CONTINUE;
1680 }
1681
menu_automodeCommand()1682 int ONScripter::menu_automodeCommand()
1683 {
1684 automode_flag = true;
1685 skip_mode &= ~SKIP_NORMAL;
1686 printf("menu_automode: change to automode\n");
1687
1688 return RET_CONTINUE;
1689 }
1690
lsp2Command()1691 int ONScripter::lsp2Command()
1692 {
1693 leaveTextDisplayMode();
1694
1695 bool v=true;
1696 if ( script_h.isName( "lsph2" ) ||
1697 script_h.isName( "lsph2add" ) ||
1698 script_h.isName( "lsph2sub" ))
1699 v = false;
1700
1701 int blend_mode = AnimationInfo::BLEND_NORMAL;
1702 if ( script_h.isName( "lsp2add" ) || script_h.isName( "lsph2add" ))
1703 blend_mode = AnimationInfo::BLEND_ADD;
1704 else if ( script_h.isName( "lsp2sub" ) || script_h.isName( "lsph2sub" ))
1705 blend_mode = AnimationInfo::BLEND_SUB;
1706
1707 int no = script_h.readInt();
1708 AnimationInfo *ai = &sprite2_info[no];
1709
1710 if (ai->image_surface && ai->visible)
1711 dirty_rect.add( ai->bounding_rect );
1712 ai->visible = v;
1713 ai->blending_mode = blend_mode;
1714
1715 const char *buf = script_h.readStr();
1716 ai->setImageName( buf );
1717
1718 ai->orig_pos.x = script_h.readInt();
1719 ai->orig_pos.y = script_h.readInt();
1720 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1721 ai->scale_x = script_h.readInt();
1722 ai->scale_y = script_h.readInt();
1723 ai->rot = script_h.readInt();
1724
1725 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA )
1726 ai->trans = script_h.readInt();
1727 else
1728 ai->trans = -1;
1729
1730 parseTaggedString( ai );
1731 setupAnimationInfo( ai );
1732 ai->calcAffineMatrix();
1733
1734 if ( ai->visible )
1735 dirty_rect.add( ai->bounding_rect );
1736
1737 return RET_CONTINUE;
1738 }
1739
lspCommand()1740 int ONScripter::lspCommand()
1741 {
1742 leaveTextDisplayMode();
1743
1744 bool v=true;
1745 if ( script_h.isName( "lsph" ) ) v = false;
1746
1747 int no = script_h.readInt();
1748 AnimationInfo *ai = &sprite_info[no];
1749
1750 if (ai->image_surface && ai->visible)
1751 dirty_rect.add( ai->pos );
1752 ai->visible = v;
1753
1754 const char *buf = script_h.readStr();
1755 if (buf[0] == '*'){ // layer
1756 int layer_num=0, c=1;
1757 while (buf[c] >= '0' && buf[c] <= '9')
1758 layer_num = layer_num*10 + buf[c++] - '0';
1759
1760 LayerInfo *li = &layer_info[layer_num];
1761 if (!li->str){
1762 fprintf(stderr, " lsp: layer %d is not configured.\n", layer_num);
1763 return RET_CONTINUE;
1764 }
1765
1766 int w=1, h=1;
1767 size_t len = strlen("wcmpg.dll");
1768 if (strlen(li->str) >= len &&
1769 strncmp(li->str+strlen(li->str)-len, "wcmpg.dll", len) == 0){
1770 printf("lsp: %d wcmpg.dll is enabled.\n", no);
1771 smpeg_info = ai;
1772 w = screen_width;
1773 h = screen_height;
1774 }
1775
1776 li->sprite_num = no;
1777 char filename[64];
1778 sprintf(filename, ":a/1,%d,0;>%d,%d,#000000", li->duration, w, h);
1779 ai->setImageName( filename );
1780 ai->orig_pos.x = 0;
1781 ai->orig_pos.y = 0;
1782 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1783
1784 ai->default_alpha = 0;
1785
1786 sprintf(filename, ":a;>%d,%d,#000000", w, h);
1787 effect_src_info.setImageName( filename );
1788 effect_src_info.orig_pos.x = 0;
1789 effect_src_info.orig_pos.y = 0;
1790 effect_src_info.scalePosXY( screen_ratio1, screen_ratio2 );
1791 effect_src_info.blending_mode = AnimationInfo::BLEND_ADD2;
1792 parseTaggedString( &effect_src_info );
1793 setupAnimationInfo( &effect_src_info );
1794 }
1795 else{
1796 ai->setImageName( buf );
1797 ai->orig_pos.x = script_h.readInt();
1798 ai->orig_pos.y = script_h.readInt();
1799 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1800
1801 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA )
1802 ai->trans = script_h.readInt();
1803 else
1804 ai->trans = -1;
1805 }
1806
1807 parseTaggedString( ai );
1808 setupAnimationInfo( ai );
1809
1810 if ( ai->visible ) dirty_rect.add( ai->pos );
1811
1812 return RET_CONTINUE;
1813 }
1814
loopbgmstopCommand()1815 int ONScripter::loopbgmstopCommand()
1816 {
1817 if ( wave_sample[MIX_LOOPBGM_CHANNEL0] ){
1818 Mix_Pause(MIX_LOOPBGM_CHANNEL0);
1819 Mix_FreeChunk( wave_sample[MIX_LOOPBGM_CHANNEL0] );
1820 wave_sample[MIX_LOOPBGM_CHANNEL0] = NULL;
1821 }
1822 if ( wave_sample[MIX_LOOPBGM_CHANNEL1] ){
1823 Mix_Pause(MIX_LOOPBGM_CHANNEL1);
1824 Mix_FreeChunk( wave_sample[MIX_LOOPBGM_CHANNEL1] );
1825 wave_sample[MIX_LOOPBGM_CHANNEL1] = NULL;
1826 }
1827 setStr(&loop_bgm_name[0], NULL);
1828
1829 return RET_CONTINUE;
1830 }
1831
loopbgmCommand()1832 int ONScripter::loopbgmCommand()
1833 {
1834 const char *buf = script_h.readStr();
1835 setStr( &loop_bgm_name[0], buf );
1836 buf = script_h.readStr();
1837 setStr( &loop_bgm_name[1], buf );
1838
1839 playSound(loop_bgm_name[1],
1840 SOUND_PRELOAD|SOUND_CHUNK, false, MIX_LOOPBGM_CHANNEL1);
1841 playSound(loop_bgm_name[0],
1842 SOUND_CHUNK, false, MIX_LOOPBGM_CHANNEL0);
1843
1844 return RET_CONTINUE;
1845 }
1846
lookbackflushCommand()1847 int ONScripter::lookbackflushCommand()
1848 {
1849 current_page = current_page->next;
1850 for ( int i=0 ; i<max_page_list-1 ; i++ ){
1851 current_page->text_count = 0;
1852 current_page = current_page->next;
1853 }
1854 clearCurrentPage();
1855 start_page = current_page;
1856
1857 return RET_CONTINUE;
1858 }
1859
lookbackbuttonCommand()1860 int ONScripter::lookbackbuttonCommand()
1861 {
1862 for ( int i=0 ; i<4 ; i++ ){
1863 const char *buf = script_h.readStr();
1864 setStr( &lookback_info[i].image_name, buf );
1865 parseTaggedString( &lookback_info[i] );
1866 setupAnimationInfo( &lookback_info[i] );
1867 }
1868 return RET_CONTINUE;
1869 }
1870
logspCommand()1871 int ONScripter::logspCommand()
1872 {
1873 leaveTextDisplayMode();
1874
1875 bool logsp2_flag = false;
1876
1877 if ( script_h.isName( "logsp2" ) )
1878 logsp2_flag = true;
1879
1880 int no = script_h.readInt();
1881 AnimationInfo *ai = &sprite_info[no];
1882
1883 if (ai->image_surface && ai->visible)
1884 dirty_rect.add( ai->pos );
1885 ai->remove();
1886 setStr( &ai->file_name, script_h.readStr() );
1887
1888 ai->orig_pos.x = script_h.readInt();
1889 ai->orig_pos.y = script_h.readInt();
1890 ai->scalePosXY( screen_ratio1, screen_ratio2 );
1891
1892 ai->trans_mode = AnimationInfo::TRANS_STRING;
1893 if (logsp2_flag){
1894 ai->font_size_xy[0] = script_h.readInt();
1895 ai->font_size_xy[1] = script_h.readInt();
1896 ai->font_pitch[0] = script_h.readInt() + ai->font_size_xy[0];
1897 ai->font_pitch[1] = script_h.readInt() + ai->font_size_xy[1];
1898 }
1899 else{
1900 ai->font_size_xy[0] = sentence_font.font_size_xy[0];
1901 ai->font_size_xy[1] = sentence_font.font_size_xy[1];
1902 ai->font_pitch[0] = sentence_font.pitch_xy[0];
1903 ai->font_pitch[1] = sentence_font.pitch_xy[1];
1904 }
1905
1906 char *current = script_h.getNext();
1907 int num = 0;
1908 while(script_h.getEndStatus() & ScriptHandler::END_COMMA){
1909 script_h.readStr();
1910 num++;
1911 }
1912
1913 script_h.setCurrent(current);
1914 if (num == 0){
1915 ai->num_of_cells = 1;
1916 ai->color_list = new uchar3[ ai->num_of_cells ];
1917 readColor( &ai->color_list[0], "#ffffff" );
1918 }
1919 else{
1920 ai->num_of_cells = num;
1921 ai->color_list = new uchar3[ ai->num_of_cells ];
1922 for (int i=0 ; i<num ; i++){
1923 readColor( &ai->color_list[i], script_h.readStr() );
1924 }
1925 }
1926
1927 ai->is_single_line = false;
1928 ai->is_tight_region = false;
1929 ai->is_ruby_drawable = sentence_font.rubyon_flag;
1930 sentence_font.is_newline_accepted = true;
1931 setupAnimationInfo( ai );
1932 sentence_font.is_newline_accepted = false;
1933 ai->visible = true;
1934 dirty_rect.add( ai->pos );
1935
1936 return RET_CONTINUE;
1937 }
1938
locateCommand()1939 int ONScripter::locateCommand()
1940 {
1941 int x = script_h.readInt();
1942 int y = script_h.readInt();
1943 sentence_font.setXY( x, y );
1944
1945 return RET_CONTINUE;
1946 }
1947
loadgameCommand()1948 int ONScripter::loadgameCommand()
1949 {
1950 int no = script_h.readInt();
1951
1952 int fadeout = mp3fadeout_duration;
1953 mp3fadeout_duration = 0; //don't use fadeout during a load
1954 if ( !loadSaveFile( no ) ){
1955 dirty_rect.fill( screen_width, screen_height );
1956 flush( refreshMode() );
1957
1958 saveon_flag = true;
1959 internal_saveon_flag = true;
1960 skip_mode &= ~SKIP_NORMAL;
1961 automode_flag = false;
1962 deleteButtonLink();
1963 deleteSelectLink();
1964 text_on_flag = false;
1965 indent_offset = 0;
1966 line_enter_status = 0;
1967 page_enter_status = 0;
1968 string_buffer_offset = 0;
1969 break_flag = false;
1970
1971 flushEvent();
1972
1973 #ifdef USE_LUA
1974 if (lua_handler.isCallbackEnabled(LUAHandler::LUA_LOAD)){
1975 if (lua_handler.callFunction(true, "load", &no))
1976 errorAndExit( lua_handler.error_str );
1977 }
1978 #endif
1979
1980 if (loadgosub_label)
1981 gosubReal( loadgosub_label, script_h.getCurrent() );
1982 }
1983
1984 mp3fadeout_duration = fadeout;
1985
1986 return RET_CONTINUE;
1987 }
1988
ldCommand()1989 int ONScripter::ldCommand()
1990 {
1991 leaveTextDisplayMode();
1992
1993 char loc = script_h.readLabel()[0];
1994 int no = -1;
1995 if (loc == 'l') no = 0;
1996 else if (loc == 'c') no = 1;
1997 else if (loc == 'r') no = 2;
1998
1999 const char *buf = NULL;
2000 if (no >= 0) buf = script_h.readStr();
2001
2002 if (no >= 0){
2003 AnimationInfo *ai = &tachi_info[no];
2004
2005 if (ai->image_surface) dirty_rect.add( ai->pos );
2006 ai->setImageName( buf );
2007 parseTaggedString( ai );
2008 setupAnimationInfo( ai );
2009
2010 if ( ai->image_surface ){
2011 ai->visible = true;
2012 ai->orig_pos.x = screen_width * (no+1) * screen_ratio2 / (4 * screen_ratio1) - ai->orig_pos.w / 2;
2013 ai->orig_pos.y = underline_value - ai->image_surface->h * screen_ratio2 / screen_ratio1;
2014 ai->scalePosXY( screen_ratio1, screen_ratio2 );
2015 dirty_rect.add( ai->pos );
2016 }
2017 }
2018
2019 EffectLink *el = parseEffect(true);
2020 if (setEffect(el)) return RET_CONTINUE;
2021 while (doEffect(el));
2022
2023 return RET_CONTINUE;
2024 }
2025 #if defined(USE_SMPEG)
smpeg_filter_callback(SDL_Overlay * dst,SDL_Overlay * src,SDL_Rect * region,SMPEG_FilterInfo * filter_info,void * data)2026 static void smpeg_filter_callback( SDL_Overlay * dst, SDL_Overlay * src, SDL_Rect * region, SMPEG_FilterInfo * filter_info, void * data )
2027 {
2028 if (dst){
2029 dst->w = 0;
2030 dst->h = 0;
2031 }
2032
2033 ONScripter *ons = (ONScripter*)data;
2034 AnimationInfo *ai = ons->getSMPEGInfo();
2035 if (!ai) return;
2036
2037 ai->convertFromYUV(src);
2038 ons->updateEffect();
2039 }
2040
smpeg_filter_destroy(struct SMPEG_Filter * filter)2041 static void smpeg_filter_destroy( struct SMPEG_Filter * filter )
2042 {
2043 }
2044 #endif
2045
layermessageCommand()2046 int ONScripter::layermessageCommand()
2047 {
2048 int no = script_h.readInt();
2049 const char *buf = script_h.readStr();
2050
2051 if (!layer_info[no].str) return RET_CONTINUE;
2052
2053 #if defined(USE_SMPEG)
2054 if (&sprite_info[layer_info[no].sprite_num] == smpeg_info){
2055 if (strncmp(buf, "open/",5) == 0){
2056 unsigned long length = script_h.cBR->getFileLength( buf+5 );
2057 if (length == 0){
2058 fprintf( stderr, " *** can't find file [%s] ***\n", buf+5 );
2059 return RET_CONTINUE;
2060 }
2061
2062 stopSMPEG();
2063
2064 layer_smpeg_buffer = new unsigned char[length];
2065 script_h.cBR->getFile( buf+5, layer_smpeg_buffer );
2066
2067 layer_smpeg_sample = SMPEG_new_rwops( SDL_RWFromMem( layer_smpeg_buffer, length ), NULL, 0 );
2068
2069 if ( SMPEG_error( layer_smpeg_sample ) ) return RET_CONTINUE;
2070
2071 SMPEG_enableaudio( layer_smpeg_sample, 0 );
2072 SMPEG_enablevideo( layer_smpeg_sample, 1 );
2073 #ifdef USE_SDL_RENDERER
2074 // workaround to set a non-NULL value in the second argument
2075 SMPEG_setdisplay( layer_smpeg_sample, accumulation_surface, NULL, NULL);
2076 #else
2077 SMPEG_setdisplay( layer_smpeg_sample, screen_surface, NULL, NULL);
2078 #endif
2079 }
2080 else if (strcmp(buf, "play") == 0){
2081 smpeg_info->visible = true;
2082 layer_smpeg_filter.data = this;
2083 layer_smpeg_filter.callback = smpeg_filter_callback;
2084 layer_smpeg_filter.destroy = smpeg_filter_destroy;
2085 SMPEG_filter( layer_smpeg_sample, &layer_smpeg_filter );
2086 SMPEG_loop( layer_smpeg_sample, layer_smpeg_loop_flag?1:0);
2087 SMPEG_renderFrame( layer_smpeg_sample, 1 );
2088 SMPEG_play( layer_smpeg_sample );
2089 }
2090 else if (strcmp(buf, "pause") == 0){
2091 if (layer_smpeg_sample)
2092 SMPEG_pause( layer_smpeg_sample );
2093 }
2094 else if (strcmp(buf, "close") == 0){
2095 smpeg_info->visible = false;
2096 stopSMPEG();
2097 }
2098 else if (strncmp(buf, "setloop/", 8) == 0){
2099 if (buf[8] == '1')
2100 layer_smpeg_loop_flag = true;
2101 else
2102 layer_smpeg_loop_flag = false;
2103 }
2104 }
2105 #endif
2106
2107 return RET_CONTINUE;
2108 }
2109
langjpCommand()2110 int ONScripter::langjpCommand()
2111 {
2112 current_read_language = 1;
2113
2114 return RET_CONTINUE;
2115 }
2116
langenCommand()2117 int ONScripter::langenCommand()
2118 {
2119 current_read_language = 0;
2120
2121 return RET_CONTINUE;
2122 }
2123
kinsokuCommand()2124 int ONScripter::kinsokuCommand()
2125 {
2126 if (script_h.compareString("on")){
2127 is_kinsoku = true;
2128 script_h.readLabel();
2129 }
2130 else if (script_h.compareString("off")){
2131 is_kinsoku = false;
2132 script_h.readLabel();
2133 }
2134
2135 return RET_CONTINUE;
2136 }
2137
jumpfCommand()2138 int ONScripter::jumpfCommand()
2139 {
2140 char *buf = script_h.getNext();
2141 while(*buf != '\0' && *buf != '~') buf++;
2142 if (*buf == '~') buf++;
2143
2144 script_h.setCurrent(buf);
2145 current_label_info = script_h.getLabelByAddress(buf);
2146 current_line = script_h.getLineByAddress(buf);
2147
2148 return RET_CONTINUE;
2149 }
2150
jumpbCommand()2151 int ONScripter::jumpbCommand()
2152 {
2153 script_h.setCurrent( last_tilde.next_script );
2154 current_label_info = script_h.getLabelByAddress( last_tilde.next_script );
2155 current_line = script_h.getLineByAddress( last_tilde.next_script );
2156
2157 return RET_CONTINUE;
2158 }
2159
ispageCommand()2160 int ONScripter::ispageCommand()
2161 {
2162 script_h.readInt();
2163
2164 if ( textgosub_clickstr_state == CLICK_NEWPAGE )
2165 script_h.setInt( &script_h.current_variable, 1 );
2166 else
2167 script_h.setInt( &script_h.current_variable, 0 );
2168
2169 return RET_CONTINUE;
2170 }
2171
isfullCommand()2172 int ONScripter::isfullCommand()
2173 {
2174 script_h.readInt();
2175 script_h.setInt( &script_h.current_variable, fullscreen_mode?1:0 );
2176
2177 return RET_CONTINUE;
2178 }
2179
isskipCommand()2180 int ONScripter::isskipCommand()
2181 {
2182 script_h.readInt();
2183
2184 if ( automode_flag )
2185 script_h.setInt( &script_h.current_variable, 2 );
2186 else if ( skip_mode & SKIP_NORMAL )
2187 script_h.setInt( &script_h.current_variable, 1 );
2188 else
2189 script_h.setInt( &script_h.current_variable, 0 );
2190
2191 return RET_CONTINUE;
2192 }
2193
isdownCommand()2194 int ONScripter::isdownCommand()
2195 {
2196 script_h.readInt();
2197
2198 if ( current_button_state.down_flag )
2199 script_h.setInt( &script_h.current_variable, 1 );
2200 else
2201 script_h.setInt( &script_h.current_variable, 0 );
2202
2203 return RET_CONTINUE;
2204 }
2205
inputCommand()2206 int ONScripter::inputCommand()
2207 {
2208 script_h.readStr();
2209
2210 if ( script_h.current_variable.type != ScriptHandler::VAR_STR )
2211 errorAndExit( "input: no string variable." );
2212 int no = script_h.current_variable.var_no;
2213
2214 script_h.readStr(); // description
2215 const char *buf = script_h.readStr(); // default value
2216 setStr( &script_h.getVariableData(no).str, buf );
2217
2218 printf( "*** inputCommand(): $%d is set to the default value: %s\n",
2219 no, buf );
2220 script_h.readInt(); // maxlen
2221 script_h.readInt(); // widechar flag
2222 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
2223 script_h.readInt(); // window width
2224 script_h.readInt(); // window height
2225 script_h.readInt(); // text box width
2226 script_h.readInt(); // text box height
2227 }
2228
2229 return RET_CONTINUE;
2230 }
2231
indentCommand()2232 int ONScripter::indentCommand()
2233 {
2234 indent_offset = script_h.readInt();
2235
2236 return RET_CONTINUE;
2237 }
2238
humanorderCommand()2239 int ONScripter::humanorderCommand()
2240 {
2241 leaveTextDisplayMode();
2242
2243 const char *buf = script_h.readStr();
2244 int i;
2245 for (i=0 ; i<3 ; i++){
2246 if (buf[i] == 'l') human_order[i] = 0;
2247 else if (buf[i] == 'c') human_order[i] = 1;
2248 else if (buf[i] == 'r') human_order[i] = 2;
2249 else human_order[i] = -1;
2250 }
2251
2252 for ( i=0 ; i<3 ; i++ )
2253 if (tachi_info[i].image_surface)
2254 dirty_rect.add( tachi_info[i].pos );
2255
2256 EffectLink *el = parseEffect(true);
2257 if (setEffect(el)) return RET_CONTINUE;
2258 while (doEffect(el));
2259
2260 return RET_CONTINUE;
2261 }
2262
getzxcCommand()2263 int ONScripter::getzxcCommand()
2264 {
2265 getzxc_flag = true;
2266
2267 return RET_CONTINUE;
2268 }
2269
getvoicevolCommand()2270 int ONScripter::getvoicevolCommand()
2271 {
2272 script_h.readInt();
2273 script_h.setInt( &script_h.current_variable, voice_volume );
2274 return RET_CONTINUE;
2275 }
2276
getversionCommand()2277 int ONScripter::getversionCommand()
2278 {
2279 script_h.readInt();
2280 script_h.setInt( &script_h.current_variable, NSC_VERSION );
2281
2282 return RET_CONTINUE;
2283 }
2284
gettimerCommand()2285 int ONScripter::gettimerCommand()
2286 {
2287 bool gettimer_flag=false;
2288
2289 if ( script_h.isName( "gettimer" ) ){
2290 gettimer_flag = true;
2291 }
2292 else if ( script_h.isName( "getbtntimer" ) ){
2293 }
2294
2295 script_h.readInt();
2296
2297 if ( gettimer_flag ){
2298 script_h.setInt( &script_h.current_variable, SDL_GetTicks() - internal_timer );
2299 }
2300 else{
2301 script_h.setInt( &script_h.current_variable, btnwait_time );
2302 }
2303
2304 return RET_CONTINUE;
2305 }
2306
gettextCommand()2307 int ONScripter::gettextCommand()
2308 {
2309 script_h.readStr();
2310 int no = script_h.current_variable.var_no;
2311
2312 char *buf = new char[ current_page->text_count + 1 ];
2313 int i, j;
2314 for ( i=0, j=0 ; i<current_page->text_count ; i++ ){
2315 if ( current_page->text[i] != 0x0a )
2316 buf[j++] = current_page->text[i];
2317 }
2318 buf[j] = '\0';
2319
2320 setStr( &script_h.getVariableData(no).str, buf );
2321 delete[] buf;
2322
2323 return RET_CONTINUE;
2324 }
2325
gettaglogCommand()2326 int ONScripter::gettaglogCommand()
2327 {
2328 script_h.readVariable();
2329 script_h.pushVariable();
2330
2331 int page_no = script_h.readInt();
2332
2333 Page *page = current_page;
2334 while(page != start_page && page_no > 0){
2335 page_no--;
2336 page = page->previous;
2337 }
2338
2339 if (page->tag)
2340 setStr(&script_h.getVariableData(script_h.pushed_variable.var_no).str, page->tag);
2341 else
2342 setStr(&script_h.getVariableData(script_h.pushed_variable.var_no).str, NULL);
2343
2344 return RET_CONTINUE;
2345 }
2346
gettagCommand()2347 int ONScripter::gettagCommand()
2348 {
2349 if ( !last_nest_info->previous || last_nest_info->nest_mode != NestInfo::LABEL )
2350 errorAndExit( "gettag: not in a subroutine, i.e. pretextgosub" );
2351
2352 char *buf = pretext_buf;
2353
2354 int n = script_h.enc.getBytes(buf[0]);
2355 unsigned short unicode1 = script_h.enc.getUTF16(buf);
2356 unsigned short unicode2 = script_h.enc.getUTF16("��", Encoding::CODE_CP932);
2357 if (buf[0] == '[')
2358 buf++;
2359 else if (zenkakko_flag && unicode1 == unicode2)
2360 buf += n;
2361 else
2362 buf = NULL;
2363
2364 int end_status;
2365 do{
2366 script_h.readVariable();
2367 end_status = script_h.getEndStatus();
2368 script_h.pushVariable();
2369
2370 if ( script_h.pushed_variable.type & ScriptHandler::VAR_INT ||
2371 script_h.pushed_variable.type & ScriptHandler::VAR_ARRAY ){
2372 if (buf)
2373 script_h.setInt( &script_h.pushed_variable, script_h.parseInt(&buf));
2374 else
2375 script_h.setInt( &script_h.pushed_variable, 0);
2376 }
2377 else if ( script_h.pushed_variable.type & ScriptHandler::VAR_STR ){
2378 if (buf){
2379 const char *buf_start = buf;
2380 unicode1 = script_h.enc.getUTF16(buf);
2381 unicode2 = script_h.enc.getUTF16("��", Encoding::CODE_CP932);
2382 while(*buf != '/' && *buf != 0 && *buf != ']' &&
2383 (!zenkakko_flag || unicode1 != unicode2)){
2384 buf += script_h.enc.getBytes(buf[0]);
2385 }
2386 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, buf_start, buf-buf_start );
2387 }
2388 else{
2389 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, NULL);
2390 }
2391 }
2392
2393 if (buf) pretext_buf = buf;
2394 if (buf && *buf == '/')
2395 buf++;
2396 else
2397 buf = NULL;
2398 }
2399 while(end_status & ScriptHandler::END_COMMA);
2400
2401 n = script_h.enc.getBytes(pretext_buf[0]);
2402 unicode1 = script_h.enc.getUTF16(pretext_buf);
2403 unicode2 = script_h.enc.getUTF16("��", Encoding::CODE_CP932);
2404 if (pretext_buf[0] == ']')
2405 pretext_buf++;
2406 else if (zenkakko_flag && unicode1 == unicode2)
2407 pretext_buf += n;
2408
2409 return RET_CONTINUE;
2410 }
2411
gettabCommand()2412 int ONScripter::gettabCommand()
2413 {
2414 gettab_flag = true;
2415
2416 return RET_CONTINUE;
2417 }
2418
getspsizeCommand()2419 int ONScripter::getspsizeCommand()
2420 {
2421 int no = script_h.readInt();
2422
2423 script_h.readVariable();
2424 script_h.setInt( &script_h.current_variable, sprite_info[no].orig_pos.w );
2425 script_h.readVariable();
2426 script_h.setInt( &script_h.current_variable, sprite_info[no].orig_pos.h );
2427 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
2428 script_h.readVariable();
2429 script_h.setInt( &script_h.current_variable, sprite_info[no].num_of_cells );
2430 }
2431
2432 return RET_CONTINUE;
2433 }
2434
getspposCommand()2435 int ONScripter::getspposCommand()
2436 {
2437 int no = script_h.readInt();
2438
2439 script_h.readVariable();
2440 script_h.setInt( &script_h.current_variable, sprite_info[no].orig_pos.x );
2441
2442 script_h.readVariable();
2443 script_h.setInt( &script_h.current_variable, sprite_info[no].orig_pos.y );
2444
2445 return RET_CONTINUE;
2446 }
2447
getspmodeCommand()2448 int ONScripter::getspmodeCommand()
2449 {
2450 script_h.readVariable();
2451 script_h.pushVariable();
2452
2453 int no = script_h.readInt();
2454 script_h.setInt( &script_h.pushed_variable, sprite_info[no].visible?1:0 );
2455
2456 return RET_CONTINUE;
2457 }
2458
getsevolCommand()2459 int ONScripter::getsevolCommand()
2460 {
2461 script_h.readInt();
2462 script_h.setInt( &script_h.current_variable, se_volume );
2463 return RET_CONTINUE;
2464 }
2465
getscreenshotCommand()2466 int ONScripter::getscreenshotCommand()
2467 {
2468 int w = script_h.readInt();
2469 if (disable_rescale_flag) w = w * screen_ratio1 / screen_ratio2;
2470 int h = script_h.readInt();
2471 if (disable_rescale_flag) h = h * screen_ratio1 / screen_ratio2;
2472 if ( w == 0 ) w = 1;
2473 if ( h == 0 ) h = 1;
2474
2475 screenshot_w = w;
2476 screenshot_h = h;
2477 #ifdef USE_SDL_RENDERER
2478 SDL_Rect rect = {(device_width -screen_device_width)/2,
2479 (device_height-screen_device_height)/2,
2480 screen_device_width, screen_device_height};
2481 SDL_LockSurface(screenshot_surface);
2482 SDL_RenderReadPixels(renderer, &rect, screenshot_surface->format->format, screenshot_surface->pixels, screenshot_surface->pitch);
2483 SDL_UnlockSurface(screenshot_surface);
2484 #else
2485 SDL_BlitSurface(screen_surface, NULL, screenshot_surface, NULL);
2486 #endif
2487
2488 return RET_CONTINUE;
2489 }
2490
getsavestrCommand()2491 int ONScripter::getsavestrCommand()
2492 {
2493 script_h.readVariable();
2494 if ( script_h.current_variable.type != ScriptHandler::VAR_STR )
2495 errorAndExit( "getsavestr: no string variable." );
2496
2497 script_h.pushVariable();
2498
2499 int no = script_h.readInt();
2500 char *buf = readSaveStrFromFile( no );
2501
2502 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, buf );
2503 if (buf) delete[] buf;
2504
2505 return RET_CONTINUE;
2506 }
2507
getreadlangCommand()2508 int ONScripter::getreadlangCommand()
2509 {
2510 script_h.readInt();
2511 script_h.setInt(&script_h.current_variable, current_read_language);
2512
2513 return RET_CONTINUE;
2514 }
2515
getpageupCommand()2516 int ONScripter::getpageupCommand()
2517 {
2518 getpageup_flag = true;
2519
2520 return RET_CONTINUE;
2521 }
2522
getpageCommand()2523 int ONScripter::getpageCommand()
2524 {
2525 getpageup_flag = true;
2526 getpagedown_flag = true;
2527
2528 return RET_CONTINUE;
2529 }
2530
getretCommand()2531 int ONScripter::getretCommand()
2532 {
2533 script_h.readVariable();
2534
2535 if ( script_h.current_variable.type == ScriptHandler::VAR_INT ||
2536 script_h.current_variable.type == ScriptHandler::VAR_ARRAY ){
2537 script_h.setInt( &script_h.current_variable, getret_int );
2538 }
2539 else if ( script_h.current_variable.type == ScriptHandler::VAR_STR ){
2540 int no = script_h.current_variable.var_no;
2541 setStr( &script_h.getVariableData(no).str, getret_str );
2542 }
2543 else errorAndExit( "getret: no variable." );
2544
2545 return RET_CONTINUE;
2546 }
2547
getregCommand()2548 int ONScripter::getregCommand()
2549 {
2550 script_h.readVariable();
2551
2552 if ( script_h.current_variable.type != ScriptHandler::VAR_STR )
2553 errorAndExit( "getreg: no string variable." );
2554 int no = script_h.current_variable.var_no;
2555
2556 const char *buf = script_h.readStr();
2557 char path[256], key[256];
2558 strcpy( path, buf );
2559 buf = script_h.readStr();
2560 strcpy( key, buf );
2561
2562 printf(" reading Registry file for [%s] %s\n", path, key );
2563
2564 FILE *fp;
2565 if ( ( fp = fopen( registry_file, "r" ) ) == NULL ){
2566 fprintf( stderr, "Cannot open file [%s]\n", registry_file );
2567 return RET_CONTINUE;
2568 }
2569
2570 char reg_buf[256], reg_buf2[256];
2571 bool found_flag = false;
2572 while( fgets( reg_buf, 256, fp) && !found_flag ){
2573 if ( reg_buf[0] == '[' ){
2574 unsigned int c=0;
2575 while ( reg_buf[c] != ']' && reg_buf[c] != '\0' ) c++;
2576 if ( !strncmp( reg_buf + 1, path, (c-1>strlen(path))?(c-1):strlen(path) ) ){
2577 while( fgets( reg_buf2, 256, fp) ){
2578
2579 script_h.pushCurrent( reg_buf2 );
2580 buf = script_h.readStr();
2581 if ( strncmp( buf,
2582 key,
2583 (strlen(buf)>strlen(key))?strlen(buf):strlen(key) ) ){
2584 script_h.popCurrent();
2585 continue;
2586 }
2587
2588 if ( !script_h.compareString("=") ){
2589 script_h.popCurrent();
2590 continue;
2591 }
2592 script_h.setCurrent(script_h.getNext()+1);
2593
2594 buf = script_h.readStr();
2595 setStr( &script_h.getVariableData(no).str, buf );
2596 script_h.popCurrent();
2597 printf(" $%d = %s\n", no, script_h.getVariableData(no).str );
2598 found_flag = true;
2599 break;
2600 }
2601 }
2602 }
2603 }
2604
2605 if ( !found_flag ) fprintf( stderr, " The key is not found.\n" );
2606 fclose(fp);
2607
2608 return RET_CONTINUE;
2609 }
2610
getmclickCommand()2611 int ONScripter::getmclickCommand()
2612 {
2613 getmclick_flag = true;
2614
2615 return RET_CONTINUE;
2616 }
2617
getmp3volCommand()2618 int ONScripter::getmp3volCommand()
2619 {
2620 script_h.readInt();
2621 script_h.setInt( &script_h.current_variable, music_volume );
2622 return RET_CONTINUE;
2623 }
2624
getmouseposCommand()2625 int ONScripter::getmouseposCommand()
2626 {
2627 script_h.readInt();
2628 script_h.setInt( &script_h.current_variable, current_button_state.x * screen_ratio2 / screen_ratio1 );
2629
2630 script_h.readInt();
2631 script_h.setInt( &script_h.current_variable, current_button_state.y * screen_ratio2 / screen_ratio1 );
2632
2633 return RET_CONTINUE;
2634 }
2635
getmouseoverCommand()2636 int ONScripter::getmouseoverCommand()
2637 {
2638 getmouseover_flag = true;
2639
2640 getmouseover_lower = script_h.readInt();
2641 getmouseover_upper = script_h.readInt();
2642
2643 return RET_CONTINUE;
2644 }
2645
getlogCommand()2646 int ONScripter::getlogCommand()
2647 {
2648 bool getlogtext_flag=false;
2649
2650 if ( script_h.isName( "getlogtext" ) )
2651 getlogtext_flag = true;
2652
2653 script_h.readVariable();
2654 script_h.pushVariable();
2655
2656 int page_no = script_h.readInt();
2657
2658 Page *page = current_page;
2659 while(page != start_page && page_no > 0){
2660 page_no--;
2661 page = page->previous;
2662 }
2663
2664 if (page_no > 0)
2665 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, NULL );
2666 else{
2667 char *buf = page->text;
2668 int count = page->text_count;
2669 if (getlogtext_flag){
2670 char *p = page->text;
2671 char *p2 = buf = new char[page->text_count];
2672 count = 0;
2673 for (int i=0 ; i<page->text_count ; i++){
2674 int n = script_h.enc.getBytes(*p);
2675 if (n >= 2){
2676 for (int j=0; j<n; j++)
2677 p2[count++] = *p++;
2678 i += n-1;
2679 }
2680 else if (*p != 0x0a)
2681 p2[count++] = *p++;
2682 else
2683 p++;
2684 }
2685 }
2686
2687 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, buf, count );
2688
2689 if (getlogtext_flag) delete[] buf;
2690 }
2691
2692 return RET_CONTINUE;
2693 }
2694
getinsertCommand()2695 int ONScripter::getinsertCommand()
2696 {
2697 getinsert_flag = true;
2698
2699 return RET_CONTINUE;
2700 }
2701
getfunctionCommand()2702 int ONScripter::getfunctionCommand()
2703 {
2704 getfunction_flag = true;
2705
2706 return RET_CONTINUE;
2707 }
2708
getenterCommand()2709 int ONScripter::getenterCommand()
2710 {
2711 if ( !force_button_shortcut_flag )
2712 getenter_flag = true;
2713
2714 return RET_CONTINUE;
2715 }
2716
getcursorpos2Command()2717 int ONScripter::getcursorpos2Command()
2718 {
2719 script_h.readInt();
2720 script_h.setInt( &script_h.current_variable, sentence_font.old_xy[0] );
2721
2722 script_h.readInt();
2723 script_h.setInt( &script_h.current_variable, sentence_font.old_xy[1] );
2724
2725 return RET_CONTINUE;
2726 }
2727
getcursorposCommand()2728 int ONScripter::getcursorposCommand()
2729 {
2730 FontInfo fi = sentence_font;
2731
2732 if ( fi.isEndOfLine() ){
2733 fi.newLine();
2734 for (int i=0 ; i<indent_offset ; i++)
2735 fi.advanceCharInHankaku(2);
2736 }
2737
2738 script_h.readInt();
2739 script_h.setInt( &script_h.current_variable, fi.x(false) );
2740
2741 script_h.readInt();
2742 script_h.setInt( &script_h.current_variable, fi.y(false) );
2743
2744 return RET_CONTINUE;
2745 }
2746
getcursorCommand()2747 int ONScripter::getcursorCommand()
2748 {
2749 if ( !force_button_shortcut_flag )
2750 getcursor_flag = true;
2751
2752 return RET_CONTINUE;
2753 }
2754
getcselstrCommand()2755 int ONScripter::getcselstrCommand()
2756 {
2757 script_h.readVariable();
2758 script_h.pushVariable();
2759
2760 int csel_no = script_h.readInt();
2761
2762 int counter = 0;
2763 SelectLink *link = root_select_link.next;
2764 while (link){
2765 if (csel_no == counter++) break;
2766 link = link->next;
2767 }
2768
2769 setStr(&script_h.getVariableData(script_h.pushed_variable.var_no).str, link?(link->text):NULL);
2770
2771 return RET_CONTINUE;
2772 }
2773
getcselnumCommand()2774 int ONScripter::getcselnumCommand()
2775 {
2776 int count = 0;
2777
2778 SelectLink *link = root_select_link.next;
2779 while ( link ) {
2780 count++;
2781 link = link->next;
2782 }
2783 script_h.readInt();
2784 script_h.setInt( &script_h.current_variable, count );
2785
2786 return RET_CONTINUE;
2787 }
2788
gameCommand()2789 int ONScripter::gameCommand()
2790 {
2791 if ( current_mode != DEFINE_MODE )
2792 errorAndExit( "game: not in the define section" );
2793
2794 int i;
2795 current_mode = NORMAL_MODE;
2796
2797 /* ---------------------------------------- */
2798 if ( !lookback_info[0].image_surface ){
2799 setStr( &lookback_info[0].image_name, DEFAULT_LOOKBACK_NAME0 );
2800 parseTaggedString( &lookback_info[0] );
2801 setupAnimationInfo( &lookback_info[0] );
2802 }
2803 if ( !lookback_info[1].image_surface ){
2804 setStr( &lookback_info[1].image_name, DEFAULT_LOOKBACK_NAME1 );
2805 parseTaggedString( &lookback_info[1] );
2806 setupAnimationInfo( &lookback_info[1] );
2807 }
2808 if ( !lookback_info[2].image_surface ){
2809 setStr( &lookback_info[2].image_name, DEFAULT_LOOKBACK_NAME2 );
2810 parseTaggedString( &lookback_info[2] );
2811 setupAnimationInfo( &lookback_info[2] );
2812 }
2813 if ( !lookback_info[3].image_surface ){
2814 setStr( &lookback_info[3].image_name, DEFAULT_LOOKBACK_NAME3 );
2815 parseTaggedString( &lookback_info[3] );
2816 setupAnimationInfo( &lookback_info[3] );
2817 }
2818
2819 /* ---------------------------------------- */
2820 /* Initialize text buffer */
2821 page_list = new Page[max_page_list];
2822 for ( i=0 ; i<max_page_list-1 ; i++ ){
2823 page_list[i].next = &page_list[i+1];
2824 page_list[i+1].previous = &page_list[i];
2825 }
2826 page_list[0].previous = &page_list[max_page_list-1];
2827 page_list[max_page_list-1].next = &page_list[0];
2828
2829 resetCommand();
2830
2831 loadCursor( 0, NULL, 0, 0 );
2832 loadCursor( 1, NULL, 0, 0 );
2833
2834 #ifdef USE_LUA
2835 lua_handler.loadInitScript();
2836 if (lua_handler.isCallbackEnabled(LUAHandler::LUA_RESET)){
2837 if (lua_handler.callFunction(true, "reset"))
2838 errorAndExit( lua_handler.error_str );
2839 }
2840 #endif
2841
2842 return RET_CONTINUE;
2843 }
2844
fileexistCommand()2845 int ONScripter::fileexistCommand()
2846 {
2847 script_h.readInt();
2848 script_h.pushVariable();
2849 const char *buf = script_h.readStr();
2850
2851 script_h.setInt( &script_h.pushed_variable, (script_h.cBR->getFileLength(buf)>0)?1:0 );
2852
2853 return RET_CONTINUE;
2854 }
2855
exec_dllCommand()2856 int ONScripter::exec_dllCommand()
2857 {
2858 const char *buf = script_h.readStr();
2859 char dll_name[256];
2860 unsigned int c=0, c2=0;
2861 while(buf[c] != '/' && buf[c] != 0x0){
2862 if (buf[c] == '\\'){
2863 c++;
2864 c2 = 0;
2865 continue;
2866 }
2867 dll_name[c2++] = buf[c++];
2868 }
2869 dll_name[c2] = '\0';
2870
2871 if (strcmp(dll_name, "fileutil.dll") == 0){
2872 if (strncmp(buf+c, "/mkdir", 6) == 0){
2873 c += 7;
2874 char *dir = new char[strlen(archive_path) + strlen(buf+c) + 1];
2875 sprintf(dir, "%s%s", archive_path, buf+c);
2876 #if defined(LINUX) || defined(MACOSX) || defined(IOS)
2877 mkdir(dir, 0755);
2878 #elif defined(WIN32)
2879 _mkdir(dir);
2880 #endif
2881 delete[] dir;
2882 }
2883 return RET_CONTINUE;
2884 }
2885
2886 FILE *fp;
2887 if ( ( fp = fopen( dll_file, "r" ) ) == NULL ){
2888 fprintf( stderr, "Cannot open file [%s] while reading %s\n", dll_file, dll_name );
2889 return RET_CONTINUE;
2890 }
2891
2892 char dll_buf[256], dll_buf2[256];
2893 bool found_flag = false;
2894 while( fgets( dll_buf, 256, fp) && !found_flag ){
2895 if ( dll_buf[0] == '[' ){
2896 c=0;
2897 while ( dll_buf[c] != ']' && dll_buf[c] != '\0' ) c++;
2898 if ( !strncmp( dll_buf + 1, dll_name, (c-1>strlen(dll_name))?(c-1):strlen(dll_name) ) ){
2899 found_flag = true;
2900 while( fgets( dll_buf2, 256, fp) ){
2901 c=0;
2902 while ( dll_buf2[c] == ' ' || dll_buf2[c] == '\t' ) c++;
2903 if ( !strncmp( &dll_buf2[c], "str", 3 ) ){
2904 c+=3;
2905 while ( dll_buf2[c] == ' ' || dll_buf2[c] == '\t' ) c++;
2906 if ( dll_buf2[c] != '=' ) continue;
2907 c++;
2908 while ( dll_buf2[c] != '"' ) c++;
2909 unsigned int c2 = ++c;
2910 while ( dll_buf2[c2] != '"' && dll_buf2[c2] != '\0' ) c2++;
2911 dll_buf2[c2] = '\0';
2912 setStr( &getret_str, &dll_buf2[c] );
2913 printf(" getret_str = %s\n", getret_str );
2914 }
2915 else if ( !strncmp( &dll_buf2[c], "ret", 3 ) ){
2916 c+=3;
2917 while ( dll_buf2[c] == ' ' || dll_buf2[c] == '\t' ) c++;
2918 if ( dll_buf2[c] != '=' ) continue;
2919 c++;
2920 while ( dll_buf2[c] == ' ' || dll_buf2[c] == '\t' ) c++;
2921 getret_int = atoi( &dll_buf2[c] );
2922 printf(" getret_int = %d\n", getret_int );
2923 }
2924 else if ( dll_buf2[c] == '[' )
2925 break;
2926 }
2927 }
2928 }
2929 }
2930
2931 if ( !found_flag ) fprintf( stderr, " The DLL is not found in %s.\n", dll_file );
2932 fclose( fp );
2933
2934 return RET_CONTINUE;
2935 }
2936
exbtnCommand()2937 int ONScripter::exbtnCommand()
2938 {
2939 int sprite_no=-1, no=0;
2940 ButtonLink *bl;
2941
2942 if ( script_h.isName( "exbtn_d" ) ||
2943 script_h.isName( "bdef" )){
2944 bl = &exbtn_d_button_link;
2945 for (int i=0 ; i<3 ; i++){
2946 if ( bl->exbtn_ctl[i] ){
2947 delete[] bl->exbtn_ctl[i];
2948 bl->exbtn_ctl[i] = NULL;
2949 }
2950 }
2951 }
2952 else{
2953 bool cellcheck_flag = false;
2954
2955 if ( script_h.isName( "cellcheckexbtn" ) )
2956 cellcheck_flag = true;
2957
2958 sprite_no = script_h.readInt();
2959 no = script_h.readInt();
2960
2961 if (no < 1 ||
2962 sprite_no < 0 ||
2963 sprite_no >= MAX_SPRITE_NUM ||
2964 sprite_info[sprite_no].image_surface == NULL ||
2965 ( cellcheck_flag && sprite_info[ sprite_no ].num_of_cells < 2) ||
2966 (!cellcheck_flag && sprite_info[ sprite_no ].num_of_cells == 0)){
2967 script_h.readStr();
2968 return RET_CONTINUE;
2969 }
2970
2971 bl = new ButtonLink();
2972 root_button_link.insert( bl );
2973 is_exbtn_enabled = true;
2974 }
2975
2976 const char *buf = script_h.readStr();
2977
2978 bl->button_type = ButtonLink::SPRITE_BUTTON;
2979 bl->sprite_no = sprite_no;
2980 bl->no = no;
2981 setStr( &bl->exbtn_ctl[1], buf );
2982
2983 if ( sprite_no >= 0 &&
2984 ( sprite_info[ sprite_no ].image_surface ||
2985 sprite_info[ sprite_no ].trans_mode == AnimationInfo::TRANS_STRING ) )
2986 bl->image_rect = bl->select_rect = sprite_info[ sprite_no ].pos;
2987
2988 return RET_CONTINUE;
2989 }
2990
erasetextwindowCommand()2991 int ONScripter::erasetextwindowCommand()
2992 {
2993 erase_text_window_mode = script_h.readInt();
2994
2995 return RET_CONTINUE;
2996 }
2997
endCommand()2998 int ONScripter::endCommand()
2999 {
3000 quit();
3001 stopSMPEG();
3002 exit(0);
3003 return RET_CONTINUE; // dummy
3004 }
3005
dwavestopCommand()3006 int ONScripter::dwavestopCommand()
3007 {
3008 int ch = script_h.readInt();
3009 if (ch < 0) ch = 0;
3010 else if (ch >= ONS_MIX_CHANNELS) ch = ONS_MIX_CHANNELS-1;
3011
3012 if ( wave_sample[ch] ){
3013 Mix_Pause( ch );
3014 Mix_FreeChunk( wave_sample[ch] );
3015 wave_sample[ch] = NULL;
3016 }
3017
3018 return RET_CONTINUE;
3019 }
3020
dwaveCommand()3021 int ONScripter::dwaveCommand()
3022 {
3023 int play_mode = WAVE_PLAY;
3024 bool loop_flag = false;
3025
3026 if ( script_h.isName( "dwaveloop" ) ){
3027 loop_flag = true;
3028 }
3029 else if ( script_h.isName( "dwaveload" ) ){
3030 play_mode = WAVE_PRELOAD;
3031 }
3032 else if ( script_h.isName( "dwaveplayloop" ) ){
3033 play_mode = WAVE_PLAY_LOADED;
3034 loop_flag = true;
3035 }
3036 else if ( script_h.isName( "dwaveplay" ) ){
3037 play_mode = WAVE_PLAY_LOADED;
3038 loop_flag = false;
3039 }
3040
3041 int ch = script_h.readInt();
3042 if (ch < 0) ch = 0;
3043 else if (ch >= ONS_MIX_CHANNELS) ch = ONS_MIX_CHANNELS-1;
3044
3045 if (play_mode == WAVE_PLAY_LOADED){
3046 Mix_PlayChannel(ch, wave_sample[ch], loop_flag?-1:0);
3047 }
3048 else{
3049 const char *buf = script_h.readStr();
3050 int fmt = SOUND_CHUNK;
3051 if (play_mode == WAVE_PRELOAD) fmt |= SOUND_PRELOAD;
3052 playSound(buf, fmt, loop_flag, ch);
3053 }
3054
3055 return RET_CONTINUE;
3056 }
3057
dvCommand()3058 int ONScripter::dvCommand()
3059 {
3060 char buf[256];
3061
3062 sprintf(buf, RELATIVEPATH "voice%c%s.wav", DELIMITER, script_h.getStringBuffer()+2);
3063 playSound(buf, SOUND_CHUNK, false, 0);
3064
3065 return RET_CONTINUE;
3066 }
3067
drawtextCommand()3068 int ONScripter::drawtextCommand()
3069 {
3070 SDL_Rect clip;
3071 clip.x = clip.y = 0;
3072 clip.w = accumulation_surface->w;
3073 clip.h = accumulation_surface->h;
3074 text_info.blendOnSurface( accumulation_surface, 0, 0, clip, layer_alpha_buf );
3075
3076 return RET_CONTINUE;
3077 }
3078
drawsp3Command()3079 int ONScripter::drawsp3Command()
3080 {
3081 int sprite_no = script_h.readInt();
3082 int cell_no = script_h.readInt();
3083 int alpha = script_h.readInt();
3084 int x = script_h.readInt() * screen_ratio1 / screen_ratio2;
3085 int y = script_h.readInt() * screen_ratio1 / screen_ratio2;
3086
3087 AnimationInfo *ai = &sprite_info[sprite_no];
3088 int old_cell_no = ai->current_cell;
3089 ai->setCell(cell_no);
3090
3091 ai->mat[0][0] = script_h.readInt();
3092 ai->mat[0][1] = script_h.readInt();
3093 ai->mat[1][0] = script_h.readInt();
3094 ai->mat[1][1] = script_h.readInt();
3095
3096 int denom = (ai->mat[0][0]*ai->mat[1][1]-ai->mat[0][1]*ai->mat[1][0])/1000;
3097 if (denom != 0){
3098 ai->inv_mat[0][0] = ai->mat[1][1] * 1000 / denom;
3099 ai->inv_mat[0][1] = -ai->mat[0][1] * 1000 / denom;
3100 ai->inv_mat[1][0] = -ai->mat[1][0] * 1000 / denom;
3101 ai->inv_mat[1][1] = ai->mat[0][0] * 1000 / denom;
3102 }
3103
3104 ai->blendOnSurface2( accumulation_surface, x, y, screen_rect, layer_alpha_buf, alpha );
3105 ai->setCell(old_cell_no);
3106
3107 return RET_CONTINUE;
3108 }
3109
drawsp2Command()3110 int ONScripter::drawsp2Command()
3111 {
3112 int sprite_no = script_h.readInt();
3113 int cell_no = script_h.readInt();
3114 int alpha = script_h.readInt();
3115
3116 AnimationInfo *ai = &sprite_info[sprite_no];
3117 ai->orig_pos.x = script_h.readInt();
3118 ai->orig_pos.y = script_h.readInt();
3119 ai->scalePosXY( screen_ratio1, screen_ratio2 );
3120 ai->scale_x = script_h.readInt();
3121 ai->scale_y = script_h.readInt();
3122 ai->rot = script_h.readInt();
3123 ai->calcAffineMatrix();
3124 ai->setCell(cell_no);
3125
3126 ai->blendOnSurface2( accumulation_surface, ai->pos.x, ai->pos.y, screen_rect, layer_alpha_buf, alpha );
3127
3128 return RET_CONTINUE;
3129 }
3130
drawspCommand()3131 int ONScripter::drawspCommand()
3132 {
3133 int sprite_no = script_h.readInt();
3134 int cell_no = script_h.readInt();
3135 int alpha = script_h.readInt();
3136 int x = script_h.readInt() * screen_ratio1 / screen_ratio2;
3137 int y = script_h.readInt() * screen_ratio1 / screen_ratio2;
3138
3139 AnimationInfo *ai = &sprite_info[sprite_no];
3140 int old_cell_no = ai->current_cell;
3141 ai->setCell(cell_no);
3142 SDL_Rect clip;
3143 clip.x = clip.y = 0;
3144 clip.w = accumulation_surface->w;
3145 clip.h = accumulation_surface->h;
3146 ai->blendOnSurface( accumulation_surface, x, y, clip, layer_alpha_buf, alpha );
3147 ai->setCell(old_cell_no);
3148
3149 return RET_CONTINUE;
3150 }
3151
drawfillCommand()3152 int ONScripter::drawfillCommand()
3153 {
3154 int r = script_h.readInt();
3155 int g = script_h.readInt();
3156 int b = script_h.readInt();
3157
3158 SDL_FillRect( accumulation_surface, NULL, SDL_MapRGBA( accumulation_surface->format, r, g, b, 0xff) );
3159
3160 return RET_CONTINUE;
3161 }
3162
drawclearCommand()3163 int ONScripter::drawclearCommand()
3164 {
3165 SDL_FillRect( accumulation_surface, NULL, SDL_MapRGBA( accumulation_surface->format, 0, 0, 0, 0xff) );
3166
3167 return RET_CONTINUE;
3168 }
3169
drawbgCommand()3170 int ONScripter::drawbgCommand()
3171 {
3172 SDL_Rect clip;
3173 clip.x = clip.y = 0;
3174 clip.w = accumulation_surface->w;
3175 clip.h = accumulation_surface->h;
3176 bg_info.blendOnSurface( accumulation_surface, bg_info.pos.x, bg_info.pos.y, clip, layer_alpha_buf );
3177
3178 return RET_CONTINUE;
3179 }
3180
drawbg2Command()3181 int ONScripter::drawbg2Command()
3182 {
3183 AnimationInfo bi = bg_info;
3184 bi.orig_pos.x = script_h.readInt();
3185 bi.orig_pos.y = script_h.readInt();
3186 bi.scalePosXY( screen_ratio1, screen_ratio2 );
3187 bi.scale_x = script_h.readInt();
3188 bi.scale_y = script_h.readInt();
3189 bi.rot = script_h.readInt();
3190 bi.calcAffineMatrix();
3191
3192 bi.blendOnSurface2( accumulation_surface, bi.pos.x, bi.pos.y, screen_rect, layer_alpha_buf, 255 );
3193
3194 return RET_CONTINUE;
3195 }
3196
drawCommand()3197 int ONScripter::drawCommand()
3198 {
3199 flushDirect( screen_rect, REFRESH_NONE_MODE );
3200 dirty_rect.clear();
3201
3202 return RET_CONTINUE;
3203 }
3204
delayCommand()3205 int ONScripter::delayCommand()
3206 {
3207 int val = script_h.readInt();
3208
3209 if (skip_mode & SKIP_NORMAL || ctrl_pressed_status)
3210 return RET_CONTINUE;
3211
3212 event_mode = WAIT_TIMER_MODE | WAIT_INPUT_MODE;
3213 waitEvent( val );
3214
3215 return RET_CONTINUE;
3216 }
3217
defineresetCommand()3218 int ONScripter::defineresetCommand()
3219 {
3220 saveGlovalData();
3221
3222 script_h.reset();
3223 ScriptParser::reset();
3224 reset();
3225
3226 setCurrentLabel( "define" );
3227
3228 if ( loadFileIOBuf( "gloval.sav" ) > 0 )
3229 readVariables( script_h.global_variable_border, script_h.variable_range );
3230
3231 #ifdef USE_LUA
3232 lua_handler.init(this, &script_h, screen_ratio1, screen_ratio2);
3233 #endif
3234
3235 current_mode = DEFINE_MODE;
3236
3237 return RET_CONTINUE;
3238 }
3239
cspCommand()3240 int ONScripter::cspCommand()
3241 {
3242 leaveTextDisplayMode();
3243
3244 bool csp2_flag = false;
3245 if (script_h.isName("csp2")) csp2_flag = true;
3246
3247 int no = script_h.readInt();
3248 AnimationInfo *si = NULL;
3249 int num = 0;
3250 if (csp2_flag) {
3251 num = MAX_SPRITE2_NUM;
3252 si = sprite2_info;
3253 }
3254 else{
3255 num = MAX_SPRITE_NUM;
3256 si = sprite_info;
3257 }
3258
3259 if ( no == -1 )
3260 for ( int i=0 ; i<num ; i++ ){
3261 if ( si[i].visible ){
3262 if (csp2_flag)
3263 dirty_rect.add( si[i].bounding_rect );
3264 else
3265 dirty_rect.add( si[i].pos );
3266 }
3267 if ( si[i].image_name ){
3268 si[i].orig_pos.x = -1000;
3269 si[i].orig_pos.y = -1000;
3270 si[i].scalePosXY( screen_ratio1, screen_ratio2 );
3271 }
3272 if (!csp2_flag) root_button_link.removeSprite(i);
3273 si[i].remove();
3274 }
3275 else if (no >= 0 && no < MAX_SPRITE_NUM){
3276 if ( si[no].visible ){
3277 if (csp2_flag)
3278 dirty_rect.add( si[no].bounding_rect );
3279 else
3280 dirty_rect.add( si[no].pos );
3281 }
3282 if (!csp2_flag) root_button_link.removeSprite(no);
3283 si[no].remove();
3284 }
3285
3286 return RET_CONTINUE;
3287 }
3288
cselgotoCommand()3289 int ONScripter::cselgotoCommand()
3290 {
3291 int csel_no = script_h.readInt();
3292
3293 int counter = 0;
3294 SelectLink *link = root_select_link.next;
3295 while( link ){
3296 if ( csel_no == counter++ ) break;
3297 link = link->next;
3298 }
3299 if ( !link ) errorAndExit( "cselgoto: no select link" );
3300
3301 setCurrentLabel( link->label );
3302
3303 deleteSelectLink();
3304 newPage();
3305
3306 return RET_CONTINUE;
3307 }
3308
cselbtnCommand()3309 int ONScripter::cselbtnCommand()
3310 {
3311 int csel_no = script_h.readInt();
3312 int button_no = script_h.readInt();
3313
3314 FontInfo csel_info = sentence_font;
3315 csel_info.rubyon_flag = false;
3316 csel_info.top_xy[0] = script_h.readInt();
3317 csel_info.top_xy[1] = script_h.readInt();
3318
3319 int counter = 0;
3320 SelectLink *link = root_select_link.next;
3321 while ( link ){
3322 if ( csel_no == counter++ ) break;
3323 link = link->next;
3324 }
3325 if ( link == NULL || link->text == NULL || *link->text == '\0' )
3326 return RET_CONTINUE;
3327
3328 openFont(&csel_info);
3329 csel_info.setLineArea(link->text);
3330 csel_info.clear();
3331 ButtonLink *button = getSelectableSentence( link->text, &csel_info );
3332 root_button_link.insert( button );
3333 button->no = button_no;
3334 button->sprite_no = csel_no;
3335
3336 sentence_font.ttf_font[0] = csel_info.ttf_font[0];
3337 sentence_font.ttf_font[1] = csel_info.ttf_font[1];
3338
3339 return RET_CONTINUE;
3340 }
3341
clickCommand()3342 int ONScripter::clickCommand()
3343 {
3344 bool lrclick_flag = false;
3345 if ( script_h.isName( "lrclick" ) ) lrclick_flag = true;
3346
3347 skip_mode &= ~SKIP_NORMAL;
3348
3349 event_mode = WAIT_TIMER_MODE | WAIT_INPUT_MODE;
3350 if (lrclick_flag) event_mode |= WAIT_RCLICK_MODE;
3351 waitEvent(-1);
3352
3353 if (lrclick_flag)
3354 getret_int = (current_button_state.button == -1)?0:1;
3355
3356 return RET_CONTINUE;
3357 }
3358
clCommand()3359 int ONScripter::clCommand()
3360 {
3361 leaveTextDisplayMode();
3362
3363 char loc = script_h.readLabel()[0];
3364
3365 if ( loc == 'l' || loc == 'a' ){
3366 dirty_rect.add( tachi_info[0].pos );
3367 tachi_info[0].remove();
3368 }
3369 if ( loc == 'c' || loc == 'a' ){
3370 dirty_rect.add( tachi_info[1].pos );
3371 tachi_info[1].remove();
3372 }
3373 if ( loc == 'r' || loc == 'a' ){
3374 dirty_rect.add( tachi_info[2].pos );
3375 tachi_info[2].remove();
3376 }
3377
3378 EffectLink *el = parseEffect(true);
3379 if (setEffect(el)) return RET_CONTINUE;
3380 while (doEffect(el));
3381
3382 return RET_CONTINUE;
3383 }
3384
chvolCommand()3385 int ONScripter::chvolCommand()
3386 {
3387 int ch = script_h.readInt();
3388 if (ch < 0) ch = 0;
3389 else if (ch >= ONS_MIX_CHANNELS) ch = ONS_MIX_CHANNELS-1;
3390
3391 int vol = script_h.readInt();
3392 if ( wave_sample[ch] ) Mix_Volume( ch, vol * MIX_MAX_VOLUME / 100 );
3393
3394 return RET_CONTINUE;
3395 }
3396
checkpageCommand()3397 int ONScripter::checkpageCommand()
3398 {
3399 script_h.readVariable();
3400 script_h.pushVariable();
3401
3402 if ( script_h.pushed_variable.type != ScriptHandler::VAR_INT &&
3403 script_h.pushed_variable.type != ScriptHandler::VAR_ARRAY )
3404 errorAndExit( "checkpage: no integer variable." );
3405
3406 int page_no = script_h.readInt();
3407
3408 Page *page = current_page;
3409 while(page != start_page && page_no > 0){
3410 page_no--;
3411 page = page->previous;
3412 }
3413
3414 if (page_no > 0)
3415 script_h.setInt( &script_h.pushed_variable, 0 );
3416 else
3417 script_h.setInt( &script_h.pushed_variable, 1 );
3418
3419 return RET_CONTINUE;
3420 }
3421
checkkeyCommand()3422 int ONScripter::checkkeyCommand()
3423 {
3424 script_h.readVariable();
3425 script_h.pushVariable();
3426 const char *str = script_h.readStr();
3427
3428 if (strcmp(current_button_state.str, str) == 0)
3429 script_h.setInt( &script_h.pushed_variable, 1 );
3430 else
3431 script_h.setInt( &script_h.pushed_variable, 0 );
3432
3433 return RET_CONTINUE;
3434 }
3435
cellCommand()3436 int ONScripter::cellCommand()
3437 {
3438 int sprite_no = script_h.readInt();
3439 int no = script_h.readInt();
3440
3441 sprite_info[sprite_no].setCell(no);
3442 dirty_rect.add( sprite_info[sprite_no].pos );
3443
3444 return RET_CONTINUE;
3445 }
3446
captionCommand()3447 int ONScripter::captionCommand()
3448 {
3449 const char* buf = script_h.readStr();
3450 size_t len = strlen(buf);
3451
3452 char *buf2 = new char[len*3+1];
3453 #if defined(MACOSX) && (SDL_COMPILEDVERSION >= 1208) /* convert sjis to utf-8 */
3454 DirectReader::convertFromSJISToUTF8(buf2, buf);
3455 #elif defined(LINUX) || (defined(WIN32) && defined(UTF8_CAPTION))
3456 #if defined(UTF8_CAPTION)
3457 if (script_h.enc.getEncoding() == Encoding::CODE_UTF8)
3458 strcpy(buf2, buf);
3459 else
3460 DirectReader::convertFromSJISToUTF8(buf2, buf);
3461 #else
3462 if (script_h.enc.getEncoding() == Encoding::CODE_UTF8){
3463 int c = 0;
3464 while(buf[0] != 0){
3465 int n = script_h.enc.getBytes(buf[0]);
3466 unsigned short unicode = script_h.enc.getUTF16(buf);
3467 if (n == 1){
3468 buf2[c++] = unicode;
3469 }
3470 else{
3471 unsigned short sjis = convUTF162SJIS(unicode);
3472 buf2[c++] = sjis >> 8;
3473 buf2[c++] = sjis & 0xff;
3474 }
3475 buf += n;
3476 }
3477 buf2[c] = 0;
3478 }
3479 else{
3480 strcpy(buf2, buf);
3481 }
3482 DirectReader::convertFromSJISToEUC(buf2);
3483 #endif
3484 #else
3485 strcpy(buf2, buf);
3486 #endif
3487
3488 setStr( &wm_title_string, buf2 );
3489 setStr( &wm_icon_string, buf2 );
3490 delete[] buf2;
3491
3492 SDL_WM_SetCaption( wm_title_string, wm_icon_string );
3493
3494 return RET_CONTINUE;
3495 }
3496
btnwaitCommand()3497 int ONScripter::btnwaitCommand()
3498 {
3499 bool del_flag=false, textbtn_flag=false;
3500 bool bexec_int_flag=false;
3501 bexec_flag = false;
3502
3503 if ( script_h.isName( "btnwait2" ) ){
3504 leaveTextDisplayMode();
3505 }
3506 else if ( script_h.isName( "btnwait" ) ){
3507 del_flag = true;
3508 leaveTextDisplayMode();
3509 }
3510 else if ( script_h.isName( "textbtnwait" ) ){
3511 textbtn_flag = true;
3512 }
3513 else if ( script_h.isName( "bexec" ) ){
3514 bexec_flag = true;
3515 }
3516
3517 if (bexec_flag){
3518 script_h.readStr();
3519 script_h.pushVariable();
3520 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
3521 bexec_int_flag = true;
3522 script_h.readInt();
3523 }
3524 getpageup_flag = true;
3525 getpagedown_flag = true;
3526 getmclick_flag = true;
3527 getfunction_flag = true;
3528 }
3529 else{
3530 script_h.readInt();
3531 }
3532
3533 ButtonLink *bl = root_button_link.next;
3534 while( bl ){
3535 bl->show_flag = 0;
3536 if ( bl->button_type == ButtonLink::SPRITE_BUTTON ){
3537 if ( bl->exbtn_ctl[0] ){
3538 SDL_Rect check_src_rect = bl->image_rect;
3539 SDL_Rect check_dst_rect = {0, 0, 0, 0};
3540 decodeExbtnControl( bl->exbtn_ctl[0], &check_src_rect, &check_dst_rect );
3541 }
3542 else{
3543 sprite_info[ bl->sprite_no ].visible = true;
3544 sprite_info[ bl->sprite_no ].setCell(0);
3545 }
3546 }
3547 else if ( bl->button_type == ButtonLink::TMP_SPRITE_BUTTON ){
3548 bl->show_flag = 1;
3549 sprite_info[ bl->sprite_no ].visible = true;
3550 sprite_info[ bl->sprite_no ].setCell(0);
3551 }
3552 else if ( bl->anim[1] != NULL ){
3553 bl->show_flag = 2;
3554 }
3555 dirty_rect.add( bl->image_rect );
3556 bl = bl->next;
3557 }
3558
3559 if (is_exbtn_enabled && exbtn_d_button_link.exbtn_ctl[1]){
3560 SDL_Rect check_src_rect = screen_rect;
3561 if (is_exbtn_enabled) decodeExbtnControl( exbtn_d_button_link.exbtn_ctl[1], &check_src_rect );
3562 }
3563
3564 if ((textbtn_flag || bexec_flag) &&
3565 (skip_mode & SKIP_NORMAL ||
3566 (skip_mode & SKIP_TO_EOP && (textgosub_clickstr_state & 0x03) == CLICK_WAIT) ||
3567 ctrl_pressed_status) ){
3568 waitEventSub(0); // for checking keyup event
3569 current_button_state.button = 0;
3570 if (bexec_flag) current_button_state.button = -1;
3571 if (skip_mode & SKIP_NORMAL ||
3572 (skip_mode & SKIP_TO_EOP && (textgosub_clickstr_state & 0x03) == CLICK_WAIT))
3573 sprintf(current_button_state.str, "SKIP");
3574 else
3575 sprintf(current_button_state.str, "CTRL");
3576 }
3577 else{
3578 shortcut_mouse_line = 0;
3579 skip_mode &= ~SKIP_NORMAL;
3580
3581 flush( refreshMode() );
3582
3583 event_mode = WAIT_BUTTON_MODE;
3584 refreshMouseOverButton();
3585
3586 int t = -1;
3587 if ( btntime_value >= 0 ){
3588 if ( btntime2_flag )
3589 event_mode |= WAIT_VOICE_MODE;
3590 t = btntime_value;
3591 //if ( usewheel_flag ) current_button_state.button = -5;
3592 //else current_button_state.button = -2;
3593 }
3594 internal_button_timer = SDL_GetTicks();
3595
3596 if ( textbtn_flag ){
3597 event_mode |= WAIT_INPUT_MODE;
3598 if ( btntime_value == -1 ){
3599 if ( automode_flag ){
3600 event_mode |= WAIT_VOICE_MODE;
3601 if ( automode_time < 0 ){
3602 if (t == -1 || t > -automode_time * num_chars_in_sentence)
3603 t = -automode_time * num_chars_in_sentence;
3604 }
3605 else{
3606 if (t == -1 || t > automode_time)
3607 t = automode_time;
3608 }
3609 //current_button_state.button = 0;
3610 }
3611 else if (autoclick_time > 0 &&
3612 (t == -1 || t > autoclick_time))
3613 t = autoclick_time;
3614 }
3615 }
3616
3617 event_mode |= WAIT_TIMER_MODE;
3618 waitEvent(t);
3619 skip_mode &= ~SKIP_TO_EOL;
3620 }
3621
3622 btnwait_time = SDL_GetTicks() - internal_button_timer;
3623 num_chars_in_sentence = 0;
3624
3625 if (bexec_flag){
3626 setStr( &script_h.getVariableData(script_h.pushed_variable.var_no).str, current_button_state.str );
3627 if (bexec_int_flag){
3628 if (current_button_state.button >= 0)
3629 script_h.setInt( &script_h.current_variable, current_button_state.button );
3630 else
3631 script_h.setInt( &script_h.current_variable, -1);
3632 }
3633 }
3634 else{
3635 script_h.setInt( &script_h.current_variable, current_button_state.button );
3636 }
3637
3638 if ( current_button_state.button >= 1 && del_flag ){
3639 deleteButtonLink();
3640 }
3641
3642 event_mode = IDLE_EVENT_MODE;
3643 disableGetButtonFlag();
3644
3645 bl = root_button_link.next;
3646 while( bl ){
3647 bl->show_flag = 0;
3648 bl = bl->next;
3649 }
3650
3651 return RET_CONTINUE;
3652 }
3653
btntimeCommand()3654 int ONScripter::btntimeCommand()
3655 {
3656 bool btime_flag = false;
3657 if ( script_h.isName( "btime" )){
3658 btime_flag = true;
3659 btntime2_flag = false;
3660 }
3661 else if ( script_h.isName( "btntime2" ) )
3662 btntime2_flag = true;
3663 else
3664 btntime2_flag = false;
3665
3666 btntime_value = script_h.readInt();
3667
3668 if ( btime_flag && script_h.getEndStatus() & ScriptHandler::END_COMMA )
3669 if (script_h.readInt() == 1) btntime2_flag = true;
3670
3671 return RET_CONTINUE;
3672 }
3673
btndownCommand()3674 int ONScripter::btndownCommand()
3675 {
3676 btndown_flag = (script_h.readInt()==1)?true:false;
3677
3678 return RET_CONTINUE;
3679 }
3680
btndefCommand()3681 int ONScripter::btndefCommand()
3682 {
3683 if (script_h.isName( "bclear" )){
3684 }
3685 else if (script_h.compareString("clear")){
3686 script_h.readLabel();
3687 }
3688 else{
3689 const char *buf = script_h.readStr();
3690
3691 btndef_info.remove();
3692
3693 if ( buf[0] != '\0' ){
3694 btndef_info.setImageName( buf );
3695 parseTaggedString( &btndef_info );
3696 btndef_info.trans_mode = AnimationInfo::TRANS_COPY;
3697 setupAnimationInfo( &btndef_info );
3698 SDL_SetAlpha( btndef_info.image_surface, DEFAULT_BLIT_FLAG, SDL_ALPHA_OPAQUE );
3699 }
3700 }
3701
3702 btntime_value = -1;
3703 transbtn_flag = false;
3704 deleteButtonLink();
3705
3706 disableGetButtonFlag();
3707
3708 return RET_CONTINUE;
3709 }
3710
btnCommand()3711 int ONScripter::btnCommand()
3712 {
3713 SDL_Rect src_rect;
3714
3715 ButtonLink *button = new ButtonLink();
3716
3717 button->no = script_h.readInt();
3718 button->image_rect.x = script_h.readInt() * screen_ratio1 / screen_ratio2;
3719 button->image_rect.y = script_h.readInt() * screen_ratio1 / screen_ratio2;
3720 button->image_rect.w = script_h.readInt() * screen_ratio1 / screen_ratio2;
3721 button->image_rect.h = script_h.readInt() * screen_ratio1 / screen_ratio2;
3722 button->select_rect = button->image_rect;
3723
3724 src_rect.x = script_h.readInt() * screen_ratio1 / screen_ratio2;
3725 src_rect.y = script_h.readInt() * screen_ratio1 / screen_ratio2;
3726 if (btndef_info.image_surface &&
3727 src_rect.x + button->image_rect.w > btndef_info.image_surface->w){
3728 button->image_rect.w = btndef_info.image_surface->w - src_rect.x;
3729 }
3730 if (btndef_info.image_surface &&
3731 src_rect.y + button->image_rect.h > btndef_info.image_surface->h){
3732 button->image_rect.h = btndef_info.image_surface->h - src_rect.y;
3733 }
3734 src_rect.w = button->image_rect.w;
3735 src_rect.h = button->image_rect.h;
3736
3737 AnimationInfo *ai = button->anim[0] = new AnimationInfo();
3738 ai->num_of_cells = 1;
3739 ai->trans_mode = AnimationInfo::TRANS_COPY;
3740 ai->pos.x = button->image_rect.x;
3741 ai->pos.y = button->image_rect.y;
3742 ai->allocImage( button->image_rect.w, button->image_rect.h, texture_format );
3743 ai->fill( 0, 0, 0, 0 );
3744 ai->copySurface( btndef_info.image_surface, &src_rect );
3745
3746 root_button_link.insert( button );
3747
3748 return RET_CONTINUE;
3749 }
3750
bspCommand()3751 int ONScripter::bspCommand()
3752 {
3753 int no = script_h.readInt();
3754 if (no < 0 || no >= MAX_SPRITE_NUM ||
3755 sprite_info[no].image_surface == NULL){
3756 for (int i=0 ; i<3 ; i++)
3757 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA )
3758 script_h.readStr();
3759 return RET_CONTINUE;
3760 }
3761
3762 ButtonLink *bl = new ButtonLink();
3763 root_button_link.insert( bl );
3764
3765 bl->button_type = ButtonLink::SPRITE_BUTTON;
3766 bl->sprite_no = no;
3767 bl->no = no;
3768
3769 if ( sprite_info[no].image_surface ||
3770 sprite_info[no].trans_mode == AnimationInfo::TRANS_STRING )
3771 bl->image_rect = bl->select_rect = sprite_info[no].pos;
3772
3773 for (int i=0 ; i<3 ; i++)
3774 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA )
3775 setStr( &bl->exbtn_ctl[i], script_h.readStr() );
3776
3777 return RET_CONTINUE;
3778 }
3779
brCommand()3780 int ONScripter::brCommand()
3781 {
3782 enterTextDisplayMode();
3783
3784 sentence_font.newLine();
3785 current_page->add( 0x0a );
3786
3787 return RET_CONTINUE;
3788 }
3789
bltCommand()3790 int ONScripter::bltCommand()
3791 {
3792 Sint16 dx,dy,sx,sy;
3793 Sint16 dw,dh,sw,sh;
3794
3795 dx = script_h.readInt() * screen_ratio1 / screen_ratio2;
3796 dy = script_h.readInt() * screen_ratio1 / screen_ratio2;
3797 dw = script_h.readInt() * screen_ratio1 / screen_ratio2;
3798 dh = script_h.readInt() * screen_ratio1 / screen_ratio2;
3799 sx = script_h.readInt() * screen_ratio1 / screen_ratio2;
3800 sy = script_h.readInt() * screen_ratio1 / screen_ratio2;
3801 sw = script_h.readInt() * screen_ratio1 / screen_ratio2;
3802 sh = script_h.readInt() * screen_ratio1 / screen_ratio2;
3803
3804 if (btndef_info.image_surface == NULL) return RET_CONTINUE;
3805 if (dw == 0 || dh == 0 || sw == 0 || sh == 0) return RET_CONTINUE;
3806
3807 if ( sw == dw && sw > 0 && sh == dh && sh > 0 ){
3808
3809 SDL_Rect src_rect = {sx,sy,(Uint16)sw,(Uint16)sh};
3810 SDL_Rect dst_rect = {dx,dy,(Uint16)dw,(Uint16)dh};
3811
3812 #ifdef USE_SDL_RENDERER
3813 dst_rect.x = dst_rect.x * screen_device_width / screen_width + (device_width -screen_device_width )/2;
3814 dst_rect.y = dst_rect.y * screen_device_width / screen_width + (device_height-screen_device_height)/2;
3815 dst_rect.w = dst_rect.w * screen_device_width / screen_width;
3816 dst_rect.h = dst_rect.h * screen_device_width / screen_width;
3817 SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, btndef_info.image_surface);
3818 SDL_RenderCopy(renderer, texture, &src_rect, &dst_rect);
3819 SDL_RenderPresent(renderer);
3820 SDL_DestroyTexture(texture);
3821 #else
3822 SDL_BlitSurface( btndef_info.image_surface, &src_rect, screen_surface, &dst_rect );
3823 SDL_UpdateRect( screen_surface, dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h );
3824 #endif
3825 dirty_rect.clear();
3826 }
3827 else{
3828 SDL_LockSurface(accumulation_surface);
3829 SDL_LockSurface(btndef_info.image_surface);
3830 ONSBuf *dst_buf = (ONSBuf*)accumulation_surface->pixels;
3831 ONSBuf *src_buf = (ONSBuf*)btndef_info.image_surface->pixels;
3832 #if defined(BPP16)
3833 int dst_width = accumulation_surface->pitch / 2;
3834 int src_width = btndef_info.image_surface->pitch / 2;
3835 #else
3836 int dst_width = accumulation_surface->pitch / 4;
3837 int src_width = btndef_info.image_surface->pitch / 4;
3838 #endif
3839
3840 int step_y = 1;
3841 if (dh < 0) step_y = -1;
3842
3843 int step_x = 1;
3844 if (dw < 0) step_x = -1;
3845
3846 dst_buf += dst_width*dy;
3847 for (int i=dy ; i!=dy+dh ; i+=step_y){
3848 if (i < 0 || i >= screen_height) continue;
3849 int y = sy+sh*(i-dy)/dh;
3850
3851 for (int j=dx ; j!=dx+dw ; j+=step_x){
3852 if (j < 0 || j >= screen_width) continue;
3853 int x = sx+sw*(j-dx)/dw;
3854
3855 if (x<0 || x>=btndef_info.image_surface->w ||
3856 y<0 || y>=btndef_info.image_surface->h)
3857 *(dst_buf+j) = 0;
3858 else
3859 *(dst_buf+j) = *(src_buf+y*src_width+x);
3860 }
3861 dst_buf += dst_width*step_y;
3862 }
3863 SDL_UnlockSurface(btndef_info.image_surface);
3864 SDL_UnlockSurface(accumulation_surface);
3865
3866 SDL_Rect dst_rect;
3867 if (dw >= 0){
3868 dst_rect.x = dx;
3869 dst_rect.w = dw;
3870 }
3871 else{
3872 dst_rect.x = dx+dw+1;
3873 dst_rect.w = -dw;
3874 }
3875 if (dh >= 0){
3876 dst_rect.y = dy;
3877 dst_rect.h = dh;
3878 }
3879 else{
3880 dst_rect.y = dy+dh+1;
3881 dst_rect.h = -dh;
3882 }
3883
3884 flushDirect( dst_rect, REFRESH_NONE_MODE );
3885 }
3886
3887 return RET_CONTINUE;
3888 }
3889
bgcopyCommand()3890 int ONScripter::bgcopyCommand()
3891 {
3892 ofscopyCommand();
3893
3894 setStr( &bg_info.file_name, "*bgcpy" );
3895 bg_info.num_of_cells = 1;
3896 bg_info.trans_mode = AnimationInfo::TRANS_COPY;
3897 bg_info.pos.x = 0;
3898 bg_info.pos.y = 0;
3899 bg_info.copySurface( accumulation_surface, NULL );
3900
3901 return RET_CONTINUE;
3902 }
3903
bgCommand()3904 int ONScripter::bgCommand()
3905 {
3906 leaveTextDisplayMode();
3907
3908 const char *buf;
3909 if (script_h.compareString("white")){
3910 buf = "white";
3911 script_h.readLabel();
3912 }
3913 else if (script_h.compareString("black")){
3914 buf = "black";
3915 script_h.readLabel();
3916 }
3917 else{
3918 buf = script_h.readStr();
3919 }
3920
3921 for ( int i=0 ; i<3 ; i++ )
3922 tachi_info[i].remove();
3923
3924 bg_info.remove();
3925 setStr( &bg_info.file_name, buf );
3926
3927 createBackground();
3928 dirty_rect.fill( screen_width, screen_height );
3929
3930 EffectLink *el = parseEffect(true);
3931 if (setEffect(el)) return RET_CONTINUE;
3932 while (doEffect(el));
3933
3934 return RET_CONTINUE;
3935 }
3936
bdownCommand()3937 int ONScripter::bdownCommand()
3938 {
3939 btndown_flag = true;
3940
3941 return RET_CONTINUE;
3942 }
3943
barclearCommand()3944 int ONScripter::barclearCommand()
3945 {
3946 for ( int i=0 ; i<MAX_PARAM_NUM ; i++ ) {
3947 if ( bar_info[i] ) {
3948 dirty_rect.add( bar_info[i]->pos );
3949 delete bar_info[i];
3950 bar_info[i] = NULL;
3951 }
3952 }
3953 return RET_CONTINUE;
3954 }
3955
barCommand()3956 int ONScripter::barCommand()
3957 {
3958 int no = script_h.readInt();
3959 AnimationInfo *ai = bar_info[no];
3960
3961 if ( ai ){
3962 dirty_rect.add( ai->pos );
3963 ai->remove();
3964 }
3965 else{
3966 ai = bar_info[no] = new AnimationInfo();
3967 }
3968
3969 ai->trans_mode = AnimationInfo::TRANS_COPY;
3970 ai->num_of_cells = 1;
3971 ai->setCell(0);
3972
3973 ai->param = script_h.readInt();
3974 ai->orig_pos.x = script_h.readInt();
3975 ai->orig_pos.y = script_h.readInt();
3976 ai->max_width = script_h.readInt();
3977 ai->orig_pos.w = 0;
3978 ai->orig_pos.h = script_h.readInt();
3979 ai->max_param = script_h.readInt();
3980
3981 ai->scalePosXY( screen_ratio1, screen_ratio2 );
3982
3983 const char *buf = script_h.readStr();
3984 readColor( &ai->color, buf );
3985
3986 int w = 0;
3987 if (ai->max_param != 0) w = ai->max_width * ai->param / ai->max_param;
3988 if (ai->max_width > 0 && w > 0) ai->orig_pos.w = w;
3989
3990 ai->scalePosWH( screen_ratio1, screen_ratio2 );
3991 ai->allocImage( ai->pos.w, ai->pos.h, texture_format );
3992 ai->fill( ai->color[0], ai->color[1], ai->color[2], 0xff );
3993 dirty_rect.add( ai->pos );
3994
3995 return RET_CONTINUE;
3996 }
3997
aviCommand()3998 int ONScripter::aviCommand()
3999 {
4000 script_h.readStr();
4001 const char *save_buf = script_h.saveStringBuffer();
4002
4003 bool click_flag = (script_h.readInt()==1)?true:false;
4004
4005 stopBGM( false );
4006 if (playAVI( save_buf, click_flag )) endCommand();
4007
4008 // should be commented out
4009 //repaintCommand();
4010
4011 return RET_CONTINUE;
4012 }
4013
automode_timeCommand()4014 int ONScripter::automode_timeCommand()
4015 {
4016 automode_time = script_h.readInt();
4017
4018 return RET_CONTINUE;
4019 }
4020
autoclickCommand()4021 int ONScripter::autoclickCommand()
4022 {
4023 autoclick_time = script_h.readInt();
4024
4025 return RET_CONTINUE;
4026 }
4027
amspCommand()4028 int ONScripter::amspCommand()
4029 {
4030 leaveTextDisplayMode();
4031
4032 bool amsp2_flag = false;
4033 if (script_h.isName("amsp2")) amsp2_flag = true;
4034
4035 int no = script_h.readInt();
4036 AnimationInfo *ai = NULL;
4037 if (amsp2_flag){
4038 ai = &sprite2_info[no];
4039 dirty_rect.add( ai->bounding_rect );
4040 }
4041 else{
4042 ai = &sprite_info[no];
4043 dirty_rect.add( ai->pos );
4044 }
4045
4046 ai->orig_pos.x = script_h.readInt();
4047 ai->orig_pos.y = script_h.readInt();
4048 ai->scalePosXY( screen_ratio1, screen_ratio2 );
4049 if (amsp2_flag){
4050 ai->scale_x = script_h.readInt();
4051 ai->scale_y = script_h.readInt();
4052 ai->rot = script_h.readInt();
4053 ai->calcAffineMatrix();
4054 dirty_rect.add( ai->bounding_rect );
4055 }
4056 else{
4057 dirty_rect.add( ai->pos );
4058 }
4059
4060 if ( script_h.getEndStatus() & ScriptHandler::END_COMMA ){
4061 ai->trans = script_h.readInt();
4062 if (ai->trans < 0) ai->trans = 0;
4063 else if (ai->trans > 255) ai->trans = 255;
4064 }
4065
4066 return RET_CONTINUE;
4067 }
4068
allsp2resumeCommand()4069 int ONScripter::allsp2resumeCommand()
4070 {
4071 all_sprite2_hide_flag = false;
4072
4073 for ( int i=0 ; i<MAX_SPRITE2_NUM ; i++ ){
4074 AnimationInfo &ai = sprite2_info[i];
4075 if (ai.image_surface && ai.visible)
4076 dirty_rect.add( ai.bounding_rect );
4077 }
4078 return RET_CONTINUE;
4079 }
4080
allspresumeCommand()4081 int ONScripter::allspresumeCommand()
4082 {
4083 all_sprite_hide_flag = false;
4084
4085 for ( int i=0 ; i<3 ; i++ ){
4086 AnimationInfo &ai = tachi_info[i];
4087 if (ai.image_surface && ai.visible)
4088 dirty_rect.add( ai.pos );
4089 }
4090
4091 for ( int i=0 ; i<MAX_SPRITE_NUM ; i++ ){
4092 AnimationInfo &ai = sprite_info[i];
4093 if (ai.image_surface && ai.visible)
4094 dirty_rect.add( ai.pos );
4095 }
4096
4097 return RET_CONTINUE;
4098 }
4099
allsp2hideCommand()4100 int ONScripter::allsp2hideCommand()
4101 {
4102 all_sprite2_hide_flag = true;
4103
4104 for ( int i=0 ; i<MAX_SPRITE2_NUM ; i++ ){
4105 AnimationInfo *ai = &sprite2_info[i];
4106 if (ai->image_surface && ai->visible)
4107 dirty_rect.add( ai->bounding_rect );
4108 }
4109 return RET_CONTINUE;
4110 }
4111
allsphideCommand()4112 int ONScripter::allsphideCommand()
4113 {
4114 all_sprite_hide_flag = true;
4115
4116 for ( int i=0 ; i<3 ; i++ ){
4117 AnimationInfo &ai = tachi_info[i];
4118 if (ai.image_surface && ai.visible)
4119 dirty_rect.add( ai.pos );
4120 }
4121
4122 for ( int i=0 ; i<MAX_SPRITE_NUM ; i++ ){
4123 AnimationInfo &ai = sprite_info[i];
4124 if (ai.image_surface && ai.visible)
4125 dirty_rect.add( ai.pos );
4126 }
4127
4128 return RET_CONTINUE;
4129 }
4130
NSDCallCommand(int texnum,const char * str1,int proc,const char * str2)4131 void ONScripter::NSDCallCommand(int texnum, const char *str1, int proc, const char *str2)
4132 {
4133 if (texnum < 0 || texnum >= MAX_TEXTURE_NUM) return;
4134
4135 NSDLoadCommand(texnum, str1);
4136
4137 if (proc == 1){ // deffontd.dll, Font
4138 FontInfo f_info = sentence_font;
4139 f_info.rubyon_flag = false;
4140 f_info.setTateyokoMode(0);
4141 f_info.top_xy[0] = f_info.top_xy[1] = 0;
4142 f_info.clear();
4143
4144 f_info.ttf_font[0] = NULL;
4145 f_info.ttf_font[1] = NULL;
4146
4147 RubyStruct rs_old = ruby_struct;
4148 ruby_struct.font_name = NULL;
4149
4150 const char *start[8];
4151 start[0] = str2;
4152 int i=0, num_param=1;
4153 while(str2[i] && num_param<8) if (str2[i++]==',') start[num_param++] = str2+i;
4154 switch(num_param){
4155 case 8: case 7:
4156 for (i=0 ; i<2 ; i++){
4157 int j=0;
4158 ruby_struct.font_size_xy[i] = 0;
4159 while(start[4+i][j]>='0' && start[4+i][j]<='9')
4160 ruby_struct.font_size_xy[i] = ruby_struct.font_size_xy[i]*10 + start[4+i][j++] - '0';
4161 }
4162 case 5:
4163 i=0;
4164 while(start[3][i] != ',' && start[3][i] != 0){
4165 if (start[3][i++] == 'r'){
4166 f_info.rubyon_flag = true;
4167 break;
4168 }
4169 }
4170 case 4: case 3:
4171 for (i=0 ; i<2 ; i++){
4172 int j=0;
4173 f_info.font_size_xy[i] = 0;
4174 while(start[i][j]>='0' && start[i][j]<='9')
4175 f_info.font_size_xy[i] = f_info.font_size_xy[i]*10 + start[i][j++] - '0';
4176 }
4177 f_info.font_size_xy[0] *= 2;
4178 f_info.pitch_xy[0] = f_info.font_size_xy[0];
4179 f_info.pitch_xy[1] = f_info.font_size_xy[1];
4180 }
4181 uchar3 color = {0xff, 0xff, 0xff};
4182 char *p = (char*)start[num_param-1], *p2 = (char*)start[num_param-1];
4183 while(*p){
4184 int n = script_h.enc.getBytes(*p);
4185 if (n >= 2){
4186 for (int i=0; i<n; i++)
4187 *p2++ = *p++;
4188 }
4189 else if (*p == '%'){
4190 p++;
4191 if (*p == '%' || *p == '(' || *p == ')') // fix me later
4192 *p2++ = *p++;
4193 else if (*p == '#'){
4194 readColor( &color, p );
4195 p += 7;
4196 }
4197 }
4198 else{
4199 *p2++ = *p++;
4200 }
4201 }
4202 *p2 = 0;
4203
4204 drawString(start[num_param-1], color, &f_info, false, NULL, NULL, &texture_info[texnum], false);
4205
4206 ruby_struct = rs_old;
4207 }
4208 }
4209
NSDDeleteCommand(int texnum)4210 void ONScripter::NSDDeleteCommand(int texnum)
4211 {
4212 if (texnum < 0 || texnum >= MAX_TEXTURE_NUM) return;
4213
4214 texture_info[texnum].remove();
4215 }
4216
NSDLoadCommand(int texnum,const char * str)4217 void ONScripter::NSDLoadCommand(int texnum, const char *str)
4218 {
4219 if (texnum < 0 || texnum >= MAX_TEXTURE_NUM) return;
4220
4221 AnimationInfo *ai = &texture_info[texnum];
4222 if (str[0] != '*'){
4223 ai->setImageName( str );
4224 ai->trans = -1;
4225 }
4226 else{
4227 int c=1, n=0, val[6]={0}; // val[6] = {width, height, R, G, B, alpha}
4228
4229 while(str[c] != 0 && n<6){
4230 if (str[c] >= '0' && str[c] <= '9')
4231 val[n] = val[n]*10 + str[c] - '0';
4232 if (str[c] == ',') n++;
4233 c++;
4234 }
4235
4236 char buf[32];
4237 sprintf(buf, ">%d,%d,#%02x%02x%02x", val[0], val[1], val[2], val[3], val[4]);
4238 ai->setImageName( buf );
4239 ai->default_alpha = val[5];
4240 }
4241
4242 ai->visible = true;
4243 parseTaggedString( ai );
4244 ai->trans_mode = AnimationInfo::TRANS_ALPHA;
4245 setupAnimationInfo( ai );
4246 }
4247
NSDPresentRectCommand(int x1,int y1,int x2,int y2)4248 void ONScripter::NSDPresentRectCommand(int x1, int y1, int x2, int y2)
4249 {
4250 SDL_Rect clip_src;
4251 clip_src.x = x1;
4252 clip_src.y = y1;
4253 clip_src.w = x2-x1+1;
4254 clip_src.h = y2-y1+1;
4255
4256 SDL_Rect clip;
4257 clip.x = clip.y = 0;
4258 clip.w = accumulation_surface->w;
4259 clip.h = accumulation_surface->h;
4260 if ( AnimationInfo::doClipping( &clip, &clip_src ) ) return;
4261
4262 for (int i=MAX_TEXTURE_NUM-1 ; i>0 ; i--)
4263 if (texture_info[i].image_surface && texture_info[i].visible)
4264 drawTaggedSurface( accumulation_surface, &texture_info[i], clip );
4265
4266 flushDirect(clip, REFRESH_NONE_MODE);
4267 }
4268
NSDSp2Command(int texnum,int dcx,int dcy,int sx,int sy,int w,int h,int xs,int ys,int rot,int alpha)4269 void ONScripter::NSDSp2Command(int texnum, int dcx, int dcy, int sx, int sy, int w, int h,
4270 int xs, int ys, int rot, int alpha)
4271 {
4272 if (texnum < 0 || texnum >= MAX_TEXTURE_NUM) return;
4273
4274 AnimationInfo *ai = &texture_info[texnum];
4275 ai->orig_pos.x = dcx;
4276 ai->orig_pos.y = dcy;
4277 ai->scalePosXY( screen_ratio1, screen_ratio2 );
4278 ai->scale_x = xs;
4279 ai->scale_y = ys;
4280 ai->rot = rot;
4281 ai->trans = alpha;
4282
4283 ai->affine_pos.x = sx*screen_ratio1/screen_ratio2;
4284 ai->affine_pos.y = sy*screen_ratio1/screen_ratio2;
4285 ai->affine_pos.w = w*screen_ratio1/screen_ratio2;
4286 ai->affine_pos.h = h*screen_ratio1/screen_ratio2;
4287 ai->calcAffineMatrix();
4288 ai->affine_flag = true;
4289 }
4290
NSDSetSpriteCommand(int spnum,int texnum,const char * tag)4291 void ONScripter::NSDSetSpriteCommand(int spnum, int texnum, const char *tag)
4292 {
4293 if (spnum < 0 || spnum >= MAX_SPRITE_NUM) return;
4294 if (texnum < 0 || texnum >= MAX_TEXTURE_NUM) return;
4295
4296 AnimationInfo *ais = &sprite_info[spnum];
4297 AnimationInfo *ait = &texture_info[texnum];
4298 *ais = *ait;
4299 ais->visible = true;
4300
4301 char buf[256];
4302 if (tag)
4303 sprintf(buf, "%s%s", tag, ait->file_name);
4304 else
4305 sprintf(buf, ":a;%s", ait->file_name);
4306 ais->setImageName(buf);
4307 parseTaggedString(ais);
4308
4309 if (ais->affine_flag){
4310 ais->orig_pos.x = ait->orig_pos.x;
4311 if (ait->num_of_cells > 0)
4312 ais->orig_pos.x -= ait->orig_pos.w/ait->num_of_cells/2;
4313 else
4314 ais->orig_pos.x -= ait->orig_pos.w/2;
4315 ais->orig_pos.y = ait->orig_pos.y - ait->orig_pos.h/2;
4316 ais->scalePosXY( screen_ratio1, screen_ratio2 );
4317 ais->affine_flag = false;
4318 }
4319 }
4320
stopSMPEG()4321 void ONScripter::stopSMPEG()
4322 {
4323 #if defined(USE_SMPEG)
4324 if (layer_smpeg_sample){
4325 SMPEG_stop( layer_smpeg_sample );
4326 SMPEG_delete( layer_smpeg_sample );
4327 layer_smpeg_sample = NULL;
4328 }
4329 if (layer_smpeg_buffer){
4330 delete[] layer_smpeg_buffer;
4331 layer_smpeg_buffer = NULL;
4332 }
4333 #endif
4334 }
4335