1 /* -*- C++ -*-
2 *
3 * ONScripter_rmenu.cpp - Right click menu handler of ONScripter
4 *
5 * Copyright (c) 2001-2020 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
26 #define DIALOG_W 241
27 #define DIALOG_H 167
28 #define DIALOG_HEADER 32
29 #define DIALOG_FOOTER 64
30 #define DIALOG_BUTTON_W 96
31 #define DIALOG_BUTTON_H 42
32
33 #if defined(ENABLE_1BYTE_CHAR) && defined(FORCE_1BYTE_CHAR)
34 #define MESSAGE_SAVE_EXIST "`%s%s Date %s/%s Time %s:%s"
35 #define MESSAGE_SAVE_EMPTY "`%s%s ------------------------"
36 #define MESSAGE_SAVE_CONFIRM "`Save in slot %s%s?"
37 #define MESSAGE_LOAD_CONFIRM "`Load from slot %s%s?"
38 #define MESSAGE_RESET_CONFIRM "`Return to Title Menu?"
39 #define MESSAGE_END_CONFIRM "`Quit?"
40 #define MESSAGE_YES "Yes"
41 #define MESSAGE_NO "No"
42 #define MESSAGE_OK "OK"
43 #define MESSAGE_CANCEL "Cancel"
44 #else
45 #define MESSAGE_SAVE_EXIST "%s%s�@%s��%s��%s��%s��"
46 #define MESSAGE_SAVE_EMPTY "%s%s�@�|�|�|�|�|�|�|�|�|�|�|�|"
47 #define MESSAGE_SAVE_CONFIRM "%s%s�ɃZ�[�u���܂��B��낵���ł����H"
48 #define MESSAGE_LOAD_CONFIRM "%s%s�����[�h���܂��B��낵���ł����H"
49 #define MESSAGE_RESET_CONFIRM "���Z�b�g���܂��B��낵���ł����H"
50 #define MESSAGE_END_CONFIRM "�I�����܂��B��낵���ł����H"
51 #define MESSAGE_YES "�͂�"
52 #define MESSAGE_NO "������"
53 #define MESSAGE_OK "�n�j"
54 #define MESSAGE_CANCEL "�L�����Z��"
55 #endif
56
57 #ifdef ANDROID
58 #include <stdarg.h>
osprintf(char * str,const char * format,...)59 static int osprintf(char *str, const char *format, ...)
60 {
61 str[0] = 0;
62 va_list list;
63 va_start( list, format );
64 while(*format){
65 if (format[0] == '%' && format[1] == 's'){
66 strcat(str, va_arg(list, char*));
67 format += 2;
68 }
69 else{
70 strncat(str, format++, 1);
71 }
72 }
73 va_end( list );
74 return strlen(str);
75 }
76 #define sprintf osprintf
77 #endif
78
enterSystemCall()79 void ONScripter::enterSystemCall()
80 {
81 shelter_button_link = root_button_link.next;
82 root_button_link.next = NULL;
83 shelter_select_link = root_select_link.next;
84 root_select_link.next = NULL;
85 shelter_event_mode = event_mode;
86 shelter_mouse_state.x = last_mouse_state.x;
87 shelter_mouse_state.y = last_mouse_state.y;
88 event_mode = IDLE_EVENT_MODE;
89 shelter_display_mode = display_mode;
90 display_mode = DISPLAY_MODE_TEXT;
91
92 shelter_refresh_shadow_text_mode = refresh_shadow_text_mode;
93 refresh_shadow_text_mode &= ~REFRESH_CURSOR_MODE;
94 stopAnimation( clickstr_state );
95 }
96
leaveSystemCall(bool restore_flag)97 void ONScripter::leaveSystemCall( bool restore_flag )
98 {
99 current_font = &sentence_font;
100 display_mode = shelter_display_mode;
101
102 if ( restore_flag ){
103
104 current_page = cached_page;
105 SDL_BlitSurface( backup_surface, NULL, text_info.image_surface, NULL );
106 root_button_link.next = shelter_button_link;
107 root_select_link.next = shelter_select_link;
108
109 event_mode = shelter_event_mode;
110 refresh_shadow_text_mode = shelter_refresh_shadow_text_mode;
111 if ( event_mode & WAIT_BUTTON_MODE ){
112 int x = shelter_mouse_state.x * screen_device_width / screen_width;
113 int y = shelter_mouse_state.y * screen_device_width / screen_width;
114 SDL_WarpMouse(x, y);
115 }
116 }
117 dirty_rect.fill( screen_width, screen_height );
118 flush( refreshMode() );
119
120 //printf("leaveSystemCall %d %d\n",event_mode, clickstr_state);
121
122 refreshMouseOverButton();
123
124 system_menu_mode = SYSTEM_NULL;
125 }
126
executeSystemCall()127 int ONScripter::executeSystemCall()
128 {
129 SDL_BlitSurface( text_info.image_surface, NULL, backup_surface, NULL );
130
131 enterSystemCall();
132
133 while(system_menu_mode != SYSTEM_NULL){
134 dirty_rect.fill( screen_width, screen_height );
135 switch(system_menu_mode){
136 case SYSTEM_SKIP:
137 executeSystemSkip();
138 return 2; // continue parsing text
139 break;
140 case SYSTEM_RESET:
141 if (executeSystemReset()) return 1; // stop parsing text
142 break;
143 case SYSTEM_SAVE:
144 executeSystemSave();
145 break;
146 case SYSTEM_LOAD:
147 if (executeSystemLoad()) return 1; // stop parsing text
148 break;
149 case SYSTEM_LOOKBACK:
150 executeSystemLookback();
151 break;
152 case SYSTEM_WINDOWERASE:
153 executeWindowErase();
154 break;
155 case SYSTEM_MENU:
156 executeSystemMenu();
157 break;
158 case SYSTEM_AUTOMODE:
159 executeSystemAutomode();
160 return 2; // continue parsing text
161 break;
162 case SYSTEM_END:
163 executeSystemEnd();
164 break;
165 default:
166 leaveSystemCall();
167 }
168 }
169
170 return 0;
171 }
172
executeSystemMenu()173 void ONScripter::executeSystemMenu()
174 {
175 current_font = &menu_font;
176
177 if ( menuselectvoice_file_name[MENUSELECTVOICE_OPEN] )
178 playSound(menuselectvoice_file_name[MENUSELECTVOICE_OPEN],
179 SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
180
181 text_info.fill( 0, 0, 0, 0 );
182 flush( refreshMode() );
183
184 menu_font.num_xy[0] = rmenu_link_width;
185 menu_font.num_xy[1] = rmenu_link_num;
186 menu_font.top_xy[0] = (screen_width * screen_ratio2 / screen_ratio1 - menu_font.num_xy[0] * menu_font.pitch_xy[0]) / 2;
187 menu_font.top_xy[1] = (screen_height * screen_ratio2 / screen_ratio1 - menu_font.num_xy[1] * menu_font.pitch_xy[1]) / 2;
188 menu_font.setXY(0, 0);
189
190 RMenuLink *link = root_rmenu_link.next;
191 int counter = 1;
192 while( link ){
193 ButtonLink *button = getSelectableSentence( link->label, &menu_font, false );
194 root_button_link.insert( button );
195 button->no = counter++;
196
197 link = link->next;
198 flush( refreshMode() );
199 }
200
201 flushEvent();
202 refreshMouseOverButton();
203
204 event_mode = WAIT_BUTTON_MODE;
205 do waitEventSub(-1);
206 while (current_button_state.button == 0);
207
208 deleteButtonLink();
209
210 if ( current_button_state.button == -1 ){
211 if ( menuselectvoice_file_name[MENUSELECTVOICE_CANCEL] )
212 playSound(menuselectvoice_file_name[MENUSELECTVOICE_CANCEL],
213 SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
214 leaveSystemCall();
215 return;
216 }
217
218 if ( menuselectvoice_file_name[MENUSELECTVOICE_CLICK] )
219 playSound(menuselectvoice_file_name[MENUSELECTVOICE_CLICK],
220 SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
221
222 link = root_rmenu_link.next;
223 counter = 1;
224 while ( link ){
225 if ( current_button_state.button == counter++ ){
226 system_menu_mode = link->system_call_no;
227 break;
228 }
229 link = link->next;
230 }
231 }
232
executeSystemSkip()233 void ONScripter::executeSystemSkip()
234 {
235 skip_mode |= SKIP_NORMAL;
236 leaveSystemCall();
237 }
238
executeSystemAutomode()239 void ONScripter::executeSystemAutomode()
240 {
241 automode_flag = true;
242 skip_mode &= ~SKIP_NORMAL;
243 printf("systemcall_automode: change to automode\n");
244 leaveSystemCall();
245 }
246
executeSystemReset()247 bool ONScripter::executeSystemReset()
248 {
249 if ( executeSystemYesNo( SYSTEM_RESET ) ){
250 resetCommand();
251 leaveSystemCall( false );
252
253 return true;
254 }
255
256 leaveSystemCall();
257
258 return false;
259 }
260
executeSystemEnd()261 void ONScripter::executeSystemEnd()
262 {
263 if ( executeSystemYesNo( SYSTEM_END ) )
264 endCommand();
265 else
266 leaveSystemCall();
267 }
268
executeWindowErase()269 void ONScripter::executeWindowErase()
270 {
271 if (windowchip_sprite_no >= 0)
272 sprite_info[windowchip_sprite_no].visible = false;
273
274 display_mode = DISPLAY_MODE_NORMAL;
275 flush(mode_saya_flag ? REFRESH_SAYA_MODE : REFRESH_NORMAL_MODE);
276
277 event_mode = WAIT_TIMER_MODE | WAIT_BUTTON_MODE;
278 waitEventSub(-1);
279
280 if (windowchip_sprite_no >= 0)
281 sprite_info[windowchip_sprite_no].visible = true;
282
283 leaveSystemCall();
284 }
285
executeSystemLoad()286 bool ONScripter::executeSystemLoad()
287 {
288 current_font = &menu_font;
289
290 text_info.fill( 0, 0, 0, 0 );
291
292 int n = script_h.enc.getNum((unsigned char*)save_item_name);
293 menu_font.num_xy[0] = (n+1)/2 + 2 + 13;
294 menu_font.num_xy[1] = num_save_file + 2;
295 menu_font.top_xy[0] = (screen_width * screen_ratio2 / screen_ratio1 - menu_font.num_xy[0] * menu_font.pitch_xy[0]) / 2;
296 menu_font.top_xy[1] = (screen_height * screen_ratio2 / screen_ratio1 - menu_font.num_xy[1] * menu_font.pitch_xy[1]) / 2;
297 int n2 = script_h.enc.getNum((unsigned char*)load_menu_name);
298 menu_font.setXY((menu_font.num_xy[0]*2 - n2)/4, 0);
299 uchar3 color = {0xff, 0xff, 0xff};
300 drawString( load_menu_name, color, &menu_font, true, accumulation_surface, NULL, &text_info );
301 menu_font.newLine();
302 menu_font.newLine();
303
304 flush( refreshMode() );
305
306 bool nofile_flag;
307 char *buffer = new char[menu_font.num_xy[0]*4 + 1];
308
309 SaveFileInfo save_file_info;
310 for ( unsigned int i=1 ; i<=num_save_file ; i++ ){
311 searchSaveFile( save_file_info, i );
312 menu_font.setXY((menu_font.num_xy[0]*2 - (n + 15*2)) / 4);
313
314 char *format_str = NULL;
315 if ( save_file_info.valid ){
316 setStr(&format_str, MESSAGE_SAVE_EXIST, -1, true);
317 sprintf(buffer, format_str,
318 save_item_name,
319 save_file_info.sjis_no,
320 save_file_info.sjis_month,
321 save_file_info.sjis_day,
322 save_file_info.sjis_hour,
323 save_file_info.sjis_minute);
324 nofile_flag = false;
325 }
326 else{
327 setStr(&format_str, MESSAGE_SAVE_EMPTY, -1, true);
328 sprintf(buffer, format_str,
329 save_item_name,
330 save_file_info.sjis_no);
331 nofile_flag = true;
332 }
333 if (format_str) delete[] format_str;
334 ButtonLink *button = getSelectableSentence( buffer, &menu_font, false, nofile_flag );
335 root_button_link.insert( button );
336 button->no = i;
337 flush( refreshMode() );
338 }
339 delete[] buffer;
340
341 refreshMouseOverButton();
342
343 event_mode = WAIT_BUTTON_MODE;
344 int file_no = 0;
345 while(1){
346 waitEventSub(-1);
347
348 if ( current_button_state.button > 0 ){
349 file_no = current_button_state.button;
350 searchSaveFile( save_file_info, file_no );
351 if ( !save_file_info.valid ) continue;
352 }
353
354 if (current_button_state.button != 0) break;
355 }
356
357 if ( current_button_state.button > 0 ){
358 deleteButtonLink();
359
360 if (executeSystemYesNo( SYSTEM_LOAD, file_no )){
361 current_font = &sentence_font;
362 system_menu_mode = 0; // for fadeout in mp3stopCommand()
363 if ( loadSaveFile( file_no ) )
364 return false;
365
366 leaveSystemCall( false );
367 saveon_flag = true;
368 internal_saveon_flag = true;
369 text_on_flag = false;
370 indent_offset = 0;
371 line_enter_status = 0;
372 page_enter_status = 0;
373 string_buffer_offset = 0;
374 break_flag = false;
375
376 flushEvent();
377
378 #ifdef USE_LUA
379 if (lua_handler.isCallbackEnabled(LUAHandler::LUA_LOAD)){
380 if (lua_handler.callFunction(true, "load", &file_no))
381 errorAndExit( lua_handler.error_str );
382 }
383 #endif
384
385 if (loadgosub_label)
386 gosubReal( loadgosub_label, script_h.getCurrent() );
387
388 return true;
389 }
390
391 return false;
392 }
393
394 deleteButtonLink();
395 leaveSystemCall();
396
397 return false;
398 }
399
executeSystemSave()400 void ONScripter::executeSystemSave()
401 {
402 current_font = &menu_font;
403
404 text_info.fill( 0, 0, 0, 0 );
405
406 int n = script_h.enc.getNum((unsigned char*)save_item_name);
407 menu_font.num_xy[0] = (n+1)/2 + 2 + 13;
408 menu_font.num_xy[1] = num_save_file + 2;
409 menu_font.top_xy[0] = (screen_width * screen_ratio2 / screen_ratio1 - menu_font.num_xy[0] * menu_font.pitch_xy[0]) / 2;
410 menu_font.top_xy[1] = (screen_height * screen_ratio2 / screen_ratio1 - menu_font.num_xy[1] * menu_font.pitch_xy[1]) / 2;
411 int n2 = script_h.enc.getNum((unsigned char*)save_menu_name);
412 menu_font.setXY((menu_font.num_xy[0]*2 - n2)/4, 0);
413 uchar3 color = {0xff, 0xff, 0xff};
414 drawString( save_menu_name, color, &menu_font, true, accumulation_surface, NULL, &text_info );
415 menu_font.newLine();
416 menu_font.newLine();
417
418 flush( refreshMode() );
419
420 bool nofile_flag;
421 char *buffer = new char[menu_font.num_xy[0]*4 + 1];
422
423 for ( unsigned int i=1 ; i<=num_save_file ; i++ ){
424 SaveFileInfo save_file_info;
425 searchSaveFile( save_file_info, i );
426 menu_font.setXY((menu_font.num_xy[0]*2 - (n + 15*2)) / 4);
427
428 char *format_str = NULL;
429 if ( save_file_info.valid ){
430 setStr(&format_str, MESSAGE_SAVE_EXIST, -1, true);
431 sprintf(buffer, format_str,
432 save_item_name,
433 save_file_info.sjis_no,
434 save_file_info.sjis_month,
435 save_file_info.sjis_day,
436 save_file_info.sjis_hour,
437 save_file_info.sjis_minute);
438 nofile_flag = false;
439 }
440 else{
441 setStr(&format_str, MESSAGE_SAVE_EMPTY, -1, true);
442 sprintf(buffer, format_str,
443 save_item_name,
444 save_file_info.sjis_no);
445 nofile_flag = true;
446 }
447 if (format_str) delete[] format_str;
448 ButtonLink *button = getSelectableSentence( buffer, &menu_font, false, nofile_flag );
449 root_button_link.insert( button );
450 button->no = i;
451 flush( refreshMode() );
452 }
453 delete[] buffer;
454
455 refreshMouseOverButton();
456
457 event_mode = WAIT_BUTTON_MODE;
458 do waitEventSub(-1);
459 while (current_button_state.button == 0);
460
461 deleteButtonLink();
462
463 if ( current_button_state.button > 0 ){
464 int file_no = current_button_state.button;
465 if (executeSystemYesNo( SYSTEM_SAVE, file_no )){
466 if (saveon_flag && internal_saveon_flag) storeSaveFile();
467 writeSaveFile( file_no );
468 leaveSystemCall();
469 }
470 return;
471 }
472
473 leaveSystemCall();
474 }
475
executeSystemYesNo(int caller,int file_no)476 bool ONScripter::executeSystemYesNo( int caller, int file_no )
477 {
478 current_font = &menu_font;
479
480 text_info.fill( 0, 0, 0, 0 );
481 dirty_rect.fill( screen_width, screen_height );
482
483 char name[128] = {'\0'};
484 char *format_str = NULL;
485 if ( caller == SYSTEM_SAVE ){
486 SaveFileInfo save_file_info;
487 searchSaveFile( save_file_info, file_no );
488 setStr(&format_str, MESSAGE_SAVE_CONFIRM, -1, true);
489 sprintf(name, format_str,
490 save_item_name,
491 save_file_info.sjis_no);
492 }
493 else if ( caller == SYSTEM_LOAD ){
494 SaveFileInfo save_file_info;
495 searchSaveFile( save_file_info, file_no );
496 setStr(&format_str, MESSAGE_LOAD_CONFIRM, -1, true);
497 sprintf(name, format_str,
498 save_item_name,
499 save_file_info.sjis_no);
500 }
501 else if ( caller == SYSTEM_RESET ){
502 setStr(&format_str, MESSAGE_RESET_CONFIRM, -1, true);
503 strcpy(name, format_str);
504 }
505 else if ( caller == SYSTEM_END ){
506 setStr(&format_str, MESSAGE_END_CONFIRM, -1, true);
507 strcpy(name, format_str);
508 }
509
510 int n = script_h.enc.getNum((unsigned char*)name);
511 menu_font.num_xy[0] = (n+1)/2;
512 menu_font.num_xy[1] = 3;
513 menu_font.top_xy[0] = (screen_width * screen_ratio2 / screen_ratio1 - menu_font.num_xy[0] * menu_font.pitch_xy[0]) / 2;
514 menu_font.top_xy[1] = (screen_height * screen_ratio2 / screen_ratio1 - menu_font.num_xy[1] * menu_font.pitch_xy[1]) / 2;
515 menu_font.setXY(0, 0);
516 uchar3 color = {0xff, 0xff, 0xff};
517 drawString( name, color, &menu_font, true, accumulation_surface, NULL, &text_info );
518
519 flush( refreshMode() );
520
521 int offset1 = n/5;
522 int offset2 = n/2 - offset1;
523 setStr(&format_str, MESSAGE_YES, -1, true);
524 strcpy(name, format_str);
525 menu_font.setXY(offset1-2, 2);
526 ButtonLink *button = getSelectableSentence( name, &menu_font, false );
527 root_button_link.insert( button );
528 button->no = 1;
529
530 setStr(&format_str, MESSAGE_NO, -1, true);
531 strcpy(name, format_str);
532 menu_font.setXY(offset2, 2);
533 button = getSelectableSentence( name, &menu_font, false );
534 root_button_link.insert( button );
535 button->no = 2;
536
537 if (format_str) delete[] format_str;
538
539 flush( refreshMode() );
540
541 refreshMouseOverButton();
542
543 event_mode = WAIT_BUTTON_MODE;
544 do waitEventSub(-1);
545 while (current_button_state.button == 0);
546
547 deleteButtonLink();
548
549 if ( current_button_state.button == 1 ){ // yes is selected
550 if ( menuselectvoice_file_name[MENUSELECTVOICE_YES] )
551 playSound(menuselectvoice_file_name[MENUSELECTVOICE_YES],
552 SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
553 return true;
554 }
555 else{
556 if ( menuselectvoice_file_name[MENUSELECTVOICE_NO] )
557 playSound(menuselectvoice_file_name[MENUSELECTVOICE_NO],
558 SOUND_CHUNK, false, MIX_WAVE_CHANNEL);
559 return false;
560 }
561 }
562
setupLookbackButton()563 void ONScripter::setupLookbackButton()
564 {
565 deleteButtonLink();
566
567 /* ---------------------------------------- */
568 /* Previous button check */
569 if ( (current_page->previous->text_count > 0 ) &&
570 current_page != start_page ){
571 ButtonLink *button = new ButtonLink();
572 root_button_link.insert( button );
573
574 button->no = 1;
575
576 if ( lookback_sp[0] >= 0 ){
577 button->button_type = ButtonLink::SPRITE_BUTTON;
578 button->sprite_no = lookback_sp[0];
579 AnimationInfo &si = sprite_info[ button->sprite_no ];
580 si.visible = true;
581 button->select_rect = si.pos;
582 button->image_rect = si.pos;
583 }
584 else{
585 button->button_type = ButtonLink::LOOKBACK_BUTTON;
586 button->select_rect = sentence_font_info.pos;
587 button->select_rect.h /= 3;
588 button->show_flag = 2;
589 button->anim[0] = &lookback_info[0];
590 button->anim[1] = &lookback_info[1];
591 button->image_rect.x = sentence_font_info.pos.x + sentence_font_info.pos.w - button->anim[0]->pos.w;
592 button->image_rect.y = sentence_font_info.pos.y;
593 button->image_rect.w = button->anim[0]->pos.w;
594 button->image_rect.h = button->anim[0]->pos.h;
595 button->anim[0]->pos.x = button->anim[1]->pos.x = button->image_rect.x;
596 button->anim[0]->pos.y = button->anim[1]->pos.y = button->image_rect.y;
597 }
598 }
599 else if (lookback_sp[0] >= 0){
600 sprite_info[ lookback_sp[0] ].visible = false;
601 }
602
603 /* ---------------------------------------- */
604 /* Next button check */
605 if ( current_page->next != cached_page ){
606 ButtonLink *button = new ButtonLink();
607 root_button_link.insert( button );
608
609 button->no = 2;
610
611 if ( lookback_sp[1] >= 0 ){
612 button->button_type = ButtonLink::SPRITE_BUTTON;
613 button->sprite_no = lookback_sp[1];
614 AnimationInfo &si = sprite_info[ button->sprite_no ];
615 si.visible = true;
616 button->select_rect = si.pos;
617 button->image_rect = si.pos;
618 }
619 else{
620 button->button_type = ButtonLink::LOOKBACK_BUTTON;
621 button->select_rect = sentence_font_info.pos;
622 button->select_rect.y += sentence_font_info.pos.h*2/3;
623 button->select_rect.h /= 3;
624 button->show_flag = 2;
625 button->anim[0] = &lookback_info[2];
626 button->anim[1] = &lookback_info[3];
627 button->image_rect.x = sentence_font_info.pos.x + sentence_font_info.pos.w - button->anim[0]->pos.w;
628 button->image_rect.y = sentence_font_info.pos.y + sentence_font_info.pos.h - button->anim[0]->pos.h;
629 button->image_rect.w = button->anim[0]->pos.w;
630 button->image_rect.h = button->anim[0]->pos.h;
631 button->anim[0]->pos.x = button->anim[1]->pos.x = button->image_rect.x;
632 button->anim[0]->pos.y = button->anim[1]->pos.y = button->image_rect.y;
633 }
634 }
635 else if (lookback_sp[1] >= 0){
636 sprite_info[ lookback_sp[1] ].visible = false;
637 }
638 }
639
executeSystemLookback()640 void ONScripter::executeSystemLookback()
641 {
642 int i;
643 uchar3 color;
644
645 current_font = &sentence_font;
646
647 current_page = current_page->previous;
648 if ( current_page->text_count == 0 ){
649 if ( lookback_sp[0] >= 0 )
650 sprite_info[ lookback_sp[0] ].visible = false;
651 if ( lookback_sp[1] >= 0 )
652 sprite_info[ lookback_sp[1] ].visible = false;
653 leaveSystemCall();
654 return;
655 }
656
657 while(1){
658 setupLookbackButton();
659 refreshMouseOverButton();
660
661 dirty_rect.fill( screen_width, screen_height );
662 flush( refreshMode() & ~REFRESH_TEXT_MODE);
663
664 for ( i=0 ; i<3 ; i++ ){
665 color[i] = sentence_font.color[i];
666 sentence_font.color[i] = lookback_color[i];
667 }
668 restoreTextBuffer(accumulation_surface);
669 for ( i=0 ; i<3 ; i++ ) sentence_font.color[i] = color[i];
670 flush( REFRESH_NONE_MODE );
671
672 event_mode = WAIT_BUTTON_MODE;
673 waitEventSub(-1);
674
675 if ( current_button_state.button == 0 ||
676 ( current_page == start_page &&
677 current_button_state.button == -2 ) ){
678 continue;
679 }
680 if ( current_button_state.button == -1 ||
681 ( current_button_state.button == -3 &&
682 current_page->next == cached_page ) ||
683 current_button_state.button <= -4 )
684 {
685 event_mode = IDLE_EVENT_MODE;
686 deleteButtonLink();
687 if ( lookback_sp[0] >= 0 )
688 sprite_info[ lookback_sp[0] ].visible = false;
689 if ( lookback_sp[1] >= 0 )
690 sprite_info[ lookback_sp[1] ].visible = false;
691 leaveSystemCall();
692 return;
693 }
694
695 if ( current_button_state.button == 1 ||
696 current_button_state.button == -2 ){
697 current_page = current_page->previous;
698 }
699 else
700 current_page = current_page->next;
701 }
702 }
703
buildDialog(bool yesno_flag,const char * mes1,const char * mes2)704 void ONScripter::buildDialog(bool yesno_flag, const char *mes1, const char *mes2)
705 {
706 SDL_PixelFormat *fmt = image_surface->format;
707 SDL_Surface *s = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_W, DIALOG_H,
708 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
709
710 SDL_Rect rect;
711 unsigned char col = 255;
712 SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, col, col, col, 0xff));
713
714 rect.x = 2; rect.y = DIALOG_HEADER;
715 rect.w = DIALOG_W-4; rect.h = DIALOG_H-rect.y-2;
716 col = 105;
717 SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));
718
719 rect.x++; rect.y++; rect.w-=2; rect.h-=2;
720 col = 255;
721 SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));
722
723 rect.h = DIALOG_FOOTER;
724 rect.y = DIALOG_H-3-rect.h;
725 col = 240;
726 SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));
727
728 SDL_Surface *s2 = s;
729 if (screen_ratio2 != screen_ratio1){
730 s2 = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_W*screen_ratio1/screen_ratio2, DIALOG_H*screen_ratio1/screen_ratio2,
731 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
732 resizeSurface(s, s2);
733 SDL_FreeSurface(s);
734 }
735
736 uchar3 col3={0, 0, 0};
737 dialog_font.top_xy[0] = 7;
738 dialog_font.top_xy[1] = DIALOG_HEADER+5;
739 dialog_font.num_xy[0] = (DIALOG_W-7*2)/dialog_font.pitch_xy[0];
740 dialog_font.num_xy[1] = 3;
741 dialog_font.clear();
742 drawString( mes1, col3, &dialog_font, false, s2, NULL, NULL );
743
744 dialog_font.top_xy[0] = 5;
745 dialog_font.top_xy[1] = (DIALOG_HEADER-dialog_font.font_size_xy[1])/2;
746 openFont(&dialog_font);
747 dialog_font.setLineArea(mes2);
748 dialog_font.clear();
749 drawString( mes2, col3, &dialog_font, false, s2, NULL, NULL );
750
751 dialog_info.deleteSurface();
752 dialog_info.num_of_cells = 1;
753 dialog_info.setImage(s2, texture_format);
754
755 dialog_info.pos.x = (screen_width - dialog_info.pos.w)/2;
756 dialog_info.pos.y = (screen_height - dialog_info.pos.h)/2;
757
758 // buttons
759 char* mes[2] = {NULL};
760 if (yesno_flag){
761 setStr(&mes[0], MESSAGE_YES, -1, true);
762 setStr(&mes[1], MESSAGE_NO, -1, true);
763 }
764 else{
765 setStr(&mes[0], MESSAGE_OK, -1, true);
766 setStr(&mes[1], MESSAGE_CANCEL, -1, true);
767 }
768
769 for (int i=0 ; i<2 ; i++){
770 SDL_Surface *bs = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_BUTTON_W*2, DIALOG_BUTTON_H,
771 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
772
773 for (int j=0 ; j<2 ; j++){
774 rect.x = DIALOG_BUTTON_W*j;
775 rect.y = 0;
776 rect.w = DIALOG_BUTTON_W; rect.h = DIALOG_BUTTON_H;
777
778 col = 105;
779 SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));
780
781 rect.w--; rect.h--;
782 col = 255;
783 SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));
784
785 rect.x++; rect.y++; rect.w--; rect.h--;
786 col = 227;
787 SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));
788
789 rect.x++; rect.y++; rect.w-=2; rect.h-=2;
790 col = 240;
791 if (j==1) col = 214;
792 SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));
793 }
794
795 SDL_Surface *bs2 = bs;
796 if (screen_ratio2 != screen_ratio1){
797 bs2 = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_BUTTON_W*2*screen_ratio1/screen_ratio2, DIALOG_BUTTON_H*screen_ratio1/screen_ratio2,
798 fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
799 resizeSurface(bs, bs2);
800 SDL_FreeSurface(bs);
801 }
802
803 for (int j=0 ; j<2 ; j++){
804 rect.x = DIALOG_BUTTON_W*j+2;
805 rect.y = 2;
806 rect.w = DIALOG_BUTTON_W-4; rect.h = DIALOG_BUTTON_H-4;
807
808 dialog_font.top_xy[0] = rect.x+(rect.w-dialog_font.pitch_xy[0]*strlen(mes[i])/2)/2;
809 dialog_font.top_xy[1] = rect.y+(rect.h-dialog_font.font_size_xy[1])/2;
810 openFont(&dialog_font);
811 dialog_font.setLineArea(mes[i]);
812 dialog_font.clear();
813 drawString( mes[i], col3, &dialog_font, false, bs2, NULL, NULL );
814 }
815
816 ButtonLink *btn = new ButtonLink();
817 btn->no = i+1;
818 btn->button_type = ButtonLink::TMP_SPRITE_BUTTON;
819 btn->anim[0] = new AnimationInfo();
820 btn->anim[0]->num_of_cells = 2;
821 btn->anim[0]->setImage(bs2, texture_format);
822 btn->show_flag = 1;
823
824 btn->anim[0]->pos.x = dialog_info.pos.x + (DIALOG_W-3-(DIALOG_BUTTON_W+8)*(2-i))*screen_ratio1/screen_ratio2;
825 btn->anim[0]->pos.y = dialog_info.pos.y + (DIALOG_H-3-(DIALOG_FOOTER+DIALOG_BUTTON_H)/2)*screen_ratio1/screen_ratio2;
826
827 btn->anim[0]->visible = true;
828 btn->select_rect = btn->image_rect = btn->anim[0]->pos;
829
830 root_button_link.insert( btn );
831 }
832
833 delete[] mes[0];
834 delete[] mes[1];
835 }
836