1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14
15 #include <stdio.h>
16 #include "ac/dialog.h"
17 #include "ac/common.h"
18 #include "ac/character.h"
19 #include "ac/characterinfo.h"
20 #include "ac/dialogtopic.h"
21 #include "ac/display.h"
22 #include "ac/draw.h"
23 #include "ac/gamestate.h"
24 #include "ac/gamesetupstruct.h"
25 #include "ac/global_character.h"
26 #include "ac/global_dialog.h"
27 #include "ac/global_display.h"
28 #include "ac/global_game.h"
29 #include "ac/global_gui.h"
30 #include "ac/global_room.h"
31 #include "ac/global_translation.h"
32 #include "ac/keycode.h"
33 #include "ac/overlay.h"
34 #include "ac/mouse.h"
35 #include "ac/parser.h"
36 #include "ac/record.h"
37 #include "ac/string.h"
38 #include "ac/dynobj/scriptdialogoptionsrendering.h"
39 #include "ac/dynobj/scriptdrawingsurface.h"
40 #include "ac/system.h"
41 #include "font/fonts.h"
42 #include "script/cc_instance.h"
43 #include "gui/guimain.h"
44 #include "gui/guitextbox.h"
45 #include "main/game_run.h"
46 #include "media/audio/audio.h"
47 #include "platform/base/agsplatformdriver.h"
48 #include "script/script.h"
49 #include "ac/spritecache.h"
50 #include "gfx/ddb.h"
51 #include "gfx/gfx_util.h"
52 #include "gfx/graphicsdriver.h"
53
54 using namespace AGS::Common;
55
56 extern GameSetupStruct game;
57 extern GameState play;
58 extern ccInstance *dialogScriptsInst;
59 extern int in_new_room;
60 extern CharacterInfo*playerchar;
61 extern SpriteCache spriteset;
62 extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
63 extern volatile int timerloop;
64 extern AGSPlatformDriver *platform;
65 extern int cur_mode,cur_cursor;
66 extern Bitmap *virtual_screen;
67 extern IGraphicsDriver *gfxDriver;
68
69 DialogTopic *dialog;
70 ScriptDialogOptionsRendering ccDialogOptionsRendering;
71 ScriptDrawingSurface* dialogOptionsRenderingSurface;
72
73 int said_speech_line; // used while in dialog to track whether screen needs updating
74
75 // Old dialog support
76 std::vector< stdtr1compat::shared_ptr<unsigned char> > old_dialog_scripts;
77 std::vector<String> old_speech_lines;
78
79 int said_text = 0;
80 int longestline = 0;
81
82
83
84
Dialog_Start(ScriptDialog * sd)85 void Dialog_Start(ScriptDialog *sd) {
86 RunDialog(sd->id);
87 }
88
89 #define CHOSE_TEXTPARSER -3053
90 #define SAYCHOSEN_USEFLAG 1
91 #define SAYCHOSEN_YES 2
92 #define SAYCHOSEN_NO 3
93
Dialog_DisplayOptions(ScriptDialog * sd,int sayChosenOption)94 int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption)
95 {
96 if ((sayChosenOption < 1) || (sayChosenOption > 3))
97 quit("!Dialog.DisplayOptions: invalid parameter passed");
98
99 int chose = show_dialog_options(sd->id, sayChosenOption, (game.options[OPT_RUNGAMEDLGOPTS] != 0));
100 if (chose != CHOSE_TEXTPARSER)
101 {
102 chose++;
103 }
104 return chose;
105 }
106
Dialog_SetOptionState(ScriptDialog * sd,int option,int newState)107 void Dialog_SetOptionState(ScriptDialog *sd, int option, int newState) {
108 SetDialogOption(sd->id, option, newState);
109 }
110
Dialog_GetOptionState(ScriptDialog * sd,int option)111 int Dialog_GetOptionState(ScriptDialog *sd, int option) {
112 return GetDialogOption(sd->id, option);
113 }
114
Dialog_HasOptionBeenChosen(ScriptDialog * sd,int option)115 int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option)
116 {
117 if ((option < 1) || (option > dialog[sd->id].numoptions))
118 quit("!Dialog.HasOptionBeenChosen: Invalid option number specified");
119 option--;
120
121 if (dialog[sd->id].optionflags[option] & DFLG_HASBEENCHOSEN)
122 return 1;
123 return 0;
124 }
125
Dialog_SetHasOptionBeenChosen(ScriptDialog * sd,int option,bool chosen)126 void Dialog_SetHasOptionBeenChosen(ScriptDialog *sd, int option, bool chosen)
127 {
128 if (option < 1 || option > dialog[sd->id].numoptions)
129 {
130 quit("!Dialog.HasOptionBeenChosen: Invalid option number specified");
131 }
132 option--;
133 if (chosen)
134 {
135 dialog[sd->id].optionflags[option] |= DFLG_HASBEENCHOSEN;
136 }
137 else
138 {
139 dialog[sd->id].optionflags[option] &= ~DFLG_HASBEENCHOSEN;
140 }
141 }
142
Dialog_GetOptionCount(ScriptDialog * sd)143 int Dialog_GetOptionCount(ScriptDialog *sd)
144 {
145 return dialog[sd->id].numoptions;
146 }
147
Dialog_GetShowTextParser(ScriptDialog * sd)148 int Dialog_GetShowTextParser(ScriptDialog *sd)
149 {
150 return (dialog[sd->id].topicFlags & DTFLG_SHOWPARSER) ? 1 : 0;
151 }
152
Dialog_GetOptionText(ScriptDialog * sd,int option)153 const char* Dialog_GetOptionText(ScriptDialog *sd, int option)
154 {
155 if ((option < 1) || (option > dialog[sd->id].numoptions))
156 quit("!Dialog.GetOptionText: Invalid option number specified");
157
158 option--;
159
160 return CreateNewScriptString(get_translation(dialog[sd->id].optionnames[option]));
161 }
162
Dialog_GetID(ScriptDialog * sd)163 int Dialog_GetID(ScriptDialog *sd) {
164 return sd->id;
165 }
166
167 //=============================================================================
168
169 #define RUN_DIALOG_STAY -1
170 #define RUN_DIALOG_STOP_DIALOG -2
171 #define RUN_DIALOG_GOTO_PREVIOUS -4
172 // dialog manager stuff
173
get_dialog_script_parameters(unsigned char * & script,unsigned short * param1,unsigned short * param2)174 void get_dialog_script_parameters(unsigned char* &script, unsigned short* param1, unsigned short* param2)
175 {
176 script++;
177 *param1 = *script;
178 script++;
179 *param1 += *script * 256;
180 script++;
181
182 if (param2)
183 {
184 *param2 = *script;
185 script++;
186 *param2 += *script * 256;
187 script++;
188 }
189 }
190
run_dialog_script(DialogTopic * dtpp,int dialogID,int offse,int optionIndex)191 int run_dialog_script(DialogTopic*dtpp, int dialogID, int offse, int optionIndex) {
192 said_speech_line = 0;
193 int result = RUN_DIALOG_STAY;
194
195 if (dialogScriptsInst)
196 {
197 char funcName[100];
198 sprintf(funcName, "_run_dialog%d", dialogID);
199 dialogScriptsInst->RunTextScriptIParam(funcName, RuntimeScriptValue().SetInt32(optionIndex));
200 result = dialogScriptsInst->returnValue;
201 }
202 else
203 {
204 // old dialog format
205 if (offse == -1)
206 return result;
207
208 unsigned char* script = old_dialog_scripts[dialogID].get() + offse;
209
210 unsigned short param1 = 0;
211 unsigned short param2 = 0;
212 bool script_running = true;
213
214 while (script_running)
215 {
216 switch (*script)
217 {
218 case DCMD_SAY:
219 get_dialog_script_parameters(script, ¶m1, ¶m2);
220
221 if (param1 == DCHAR_PLAYER)
222 param1 = game.playercharacter;
223
224 if (param1 == DCHAR_NARRATOR)
225 Display(get_translation(old_speech_lines[param2]));
226 else
227 DisplaySpeech(get_translation(old_speech_lines[param2]), param1);
228
229 said_speech_line = 1;
230 break;
231
232 case DCMD_OPTOFF:
233 get_dialog_script_parameters(script, ¶m1, NULL);
234 SetDialogOption(dialogID, param1 + 1, 0, true);
235 break;
236
237 case DCMD_OPTON:
238 get_dialog_script_parameters(script, ¶m1, NULL);
239 SetDialogOption(dialogID, param1 + 1, DFLG_ON, true);
240 break;
241
242 case DCMD_RETURN:
243 script_running = false;
244 break;
245
246 case DCMD_STOPDIALOG:
247 result = RUN_DIALOG_STOP_DIALOG;
248 script_running = false;
249 break;
250
251 case DCMD_OPTOFFFOREVER:
252 get_dialog_script_parameters(script, ¶m1, NULL);
253 SetDialogOption(dialogID, param1 + 1, DFLG_OFFPERM, true);
254 break;
255
256 case DCMD_RUNTEXTSCRIPT:
257 get_dialog_script_parameters(script, ¶m1, NULL);
258 result = run_dialog_request(param1);
259 script_running = (result == RUN_DIALOG_STAY);
260 break;
261
262 case DCMD_GOTODIALOG:
263 get_dialog_script_parameters(script, ¶m1, NULL);
264 result = param1;
265 script_running = false;
266 break;
267
268 case DCMD_PLAYSOUND:
269 get_dialog_script_parameters(script, ¶m1, NULL);
270 play_sound(param1);
271 break;
272
273 case DCMD_ADDINV:
274 get_dialog_script_parameters(script, ¶m1, NULL);
275 add_inventory(param1);
276 break;
277
278 case DCMD_SETSPCHVIEW:
279 get_dialog_script_parameters(script, ¶m1, ¶m2);
280 SetCharacterSpeechView(param1, param2);
281 break;
282
283 case DCMD_NEWROOM:
284 get_dialog_script_parameters(script, ¶m1, NULL);
285 NewRoom(param1);
286 in_new_room = 1;
287 result = RUN_DIALOG_STOP_DIALOG;
288 script_running = false;
289 break;
290
291 case DCMD_SETGLOBALINT:
292 get_dialog_script_parameters(script, ¶m1, ¶m2);
293 SetGlobalInt(param1, param2);
294 break;
295
296 case DCMD_GIVESCORE:
297 get_dialog_script_parameters(script, ¶m1, NULL);
298 GiveScore(param1);
299 break;
300
301 case DCMD_GOTOPREVIOUS:
302 result = RUN_DIALOG_GOTO_PREVIOUS;
303 script_running = false;
304 break;
305
306 case DCMD_LOSEINV:
307 get_dialog_script_parameters(script, ¶m1, NULL);
308 lose_inventory(param1);
309 break;
310
311 case DCMD_ENDSCRIPT:
312 result = RUN_DIALOG_STOP_DIALOG;
313 script_running = false;
314 break;
315 }
316 }
317 }
318
319 if (in_new_room > 0)
320 return RUN_DIALOG_STOP_DIALOG;
321
322 if (said_speech_line > 0) {
323 // the line below fixes the problem with the close-up face remaining on the
324 // screen after they finish talking; however, it makes the dialog options
325 // area flicker when going between topics.
326 DisableInterface();
327 UpdateGameOnce(); // redraw the screen to make sure it looks right
328 EnableInterface();
329 // if we're not about to abort the dialog, switch back to arrow
330 if (result != RUN_DIALOG_STOP_DIALOG)
331 set_mouse_cursor(CURS_ARROW);
332 }
333
334 return result;
335 }
336
write_dialog_options(Bitmap * ds,bool ds_has_alpha,int dlgxp,int curyp,int numdisp,int mouseison,int areawid,int bullet_wid,int usingfont,DialogTopic * dtop,char * disporder,short * dispyp,int linespacing,int utextcol,int padding)337 int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, int numdisp, int mouseison, int areawid,
338 int bullet_wid, int usingfont, DialogTopic*dtop, char*disporder, short*dispyp,
339 int linespacing, int utextcol, int padding) {
340 int ww;
341
342 color_t text_color;
343 for (ww=0;ww<numdisp;ww++) {
344
345 if ((dtop->optionflags[disporder[ww]] & DFLG_HASBEENCHOSEN) &&
346 (play.read_dialog_option_colour >= 0)) {
347 // 'read' colour
348 text_color = ds->GetCompatibleColor(play.read_dialog_option_colour);
349 }
350 else {
351 // 'unread' colour
352 text_color = ds->GetCompatibleColor(playerchar->talkcolor);
353 }
354
355 if (mouseison==ww) {
356 if (text_color == ds->GetCompatibleColor(utextcol))
357 text_color = ds->GetCompatibleColor(13); // the normal colour is the same as highlight col
358 else text_color = ds->GetCompatibleColor(utextcol);
359 }
360
361 break_up_text_into_lines(areawid-(2*padding+2+bullet_wid),usingfont,get_translation(dtop->optionnames[disporder[ww]]));
362 dispyp[ww]=curyp;
363 if (game.dialog_bullet > 0)
364 {
365 draw_gui_sprite_v330(ds, game.dialog_bullet, dlgxp, curyp, ds_has_alpha);
366 }
367 int cc;
368 if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) {
369 char tempbfr[20];
370 int actualpicwid = 0;
371 if (game.dialog_bullet > 0)
372 actualpicwid = spritewidth[game.dialog_bullet]+3;
373
374 sprintf (tempbfr, "%d.", ww + 1);
375 wouttext_outline (ds, dlgxp + actualpicwid, curyp, usingfont, text_color, tempbfr);
376 }
377 for (cc=0;cc<numlines;cc++) {
378 wouttext_outline(ds, dlgxp+((cc==0) ? 0 : 9)+bullet_wid, curyp, usingfont, text_color, lines[cc]);
379 curyp+=linespacing;
380 }
381 if (ww < numdisp-1)
382 curyp += multiply_up_coordinate(game.options[OPT_DIALOGGAP]);
383 }
384 return curyp;
385 }
386
387
388
389 #define GET_OPTIONS_HEIGHT {\
390 needheight = 0;\
391 for (int i = 0; i < numdisp; ++i) {\
392 break_up_text_into_lines(areawid-(2*padding+2+bullet_wid),usingfont,get_translation(dtop->optionnames[disporder[i]]));\
393 needheight += getheightoflines(usingfont, numlines) + multiply_up_coordinate(game.options[OPT_DIALOGGAP]);\
394 }\
395 if (parserInput) needheight += parserInput->hit + multiply_up_coordinate(game.options[OPT_DIALOGGAP]);\
396 }
397
398
draw_gui_for_dialog_options(Bitmap * ds,GUIMain * guib,int dlgxp,int dlgyp)399 void draw_gui_for_dialog_options(Bitmap *ds, GUIMain *guib, int dlgxp, int dlgyp) {
400 if (guib->BgColor != 0) {
401 color_t draw_color = ds->GetCompatibleColor(guib->BgColor);
402 ds->FillRect(Rect(dlgxp, dlgyp, dlgxp + guib->Width, dlgyp + guib->Height), draw_color);
403 }
404 if (guib->BgImage > 0)
405 GfxUtil::DrawSpriteWithTransparency(ds, spriteset[guib->BgImage], dlgxp, dlgyp);
406 }
407
get_custom_dialog_options_dimensions(int dlgnum)408 bool get_custom_dialog_options_dimensions(int dlgnum)
409 {
410 ccDialogOptionsRendering.Reset();
411 ccDialogOptionsRendering.dialogID = dlgnum;
412
413 getDialogOptionsDimensionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
414 run_function_on_non_blocking_thread(&getDialogOptionsDimensionsFunc);
415
416 if ((ccDialogOptionsRendering.width > 0) &&
417 (ccDialogOptionsRendering.height > 0))
418 {
419 return true;
420 }
421 return false;
422 }
423
424 #define MAX_TOPIC_HISTORY 50
425 #define DLG_OPTION_PARSER 99
426
427 struct DialogOptions
428 {
429 int dlgnum;
430 bool runGameLoopsInBackground;
431
432 int dlgxp;
433 int dlgyp;
434 int dialog_abs_x; // absolute dialog position on screen
435 int padding;
436 int usingfont;
437 int lineheight;
438 int linespacing;
439 int curswas;
440 int bullet_wid;
441 int needheight;
442 IDriverDependantBitmap *ddb;
443 Bitmap *subBitmap;
444 GUITextBox *parserInput;
445 DialogTopic*dtop;
446
447 char disporder[MAXTOPICOPTIONS];
448 short dispyp[MAXTOPICOPTIONS];
449
450 int numdisp;
451 int chose;
452
453 Bitmap *tempScrn;
454 int parserActivated;
455
456 int curyp;
457 bool wantRefresh;
458 bool usingCustomRendering;
459 int orixp;
460 int oriyp;
461 int areawid;
462 int is_textwindow;
463 int dirtyx;
464 int dirtyy;
465 int dirtywidth;
466 int dirtyheight;
467
468 int mouseison;
469 int mousewason;
470
471 int forecol;
472
473 void Prepare(int _dlgnum, bool _runGameLoopsInBackground);
474 void Show();
475 void Redraw();
476 bool Run();
477 void Close();
478 };
479
Prepare(int _dlgnum,bool _runGameLoopsInBackground)480 void DialogOptions::Prepare(int _dlgnum, bool _runGameLoopsInBackground)
481 {
482 dlgnum = _dlgnum;
483 runGameLoopsInBackground = _runGameLoopsInBackground;
484
485 dlgyp = get_fixed_pixel_size(160);
486 usingfont=FONT_NORMAL;
487 lineheight = getfontheight_outlined(usingfont);
488 linespacing = getfontspacing_outlined(usingfont);
489 curswas=cur_cursor;
490 bullet_wid = 0;
491 ddb = NULL;
492 subBitmap = NULL;
493 parserInput = NULL;
494 dtop = NULL;
495
496 if ((dlgnum < 0) || (dlgnum >= game.numdialog))
497 quit("!RunDialog: invalid dialog number specified");
498
499 can_run_delayed_command();
500
501 play.in_conversation ++;
502
503 update_polled_stuff_if_runtime();
504
505 if (game.dialog_bullet > 0)
506 bullet_wid = spritewidth[game.dialog_bullet]+3;
507
508 // numbered options, leave space for the numbers
509 if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering)
510 bullet_wid += wgettextwidth_compensate("9. ", usingfont);
511
512 said_text = 0;
513
514 update_polled_stuff_if_runtime();
515
516 tempScrn = BitmapHelper::CreateBitmap(BitmapHelper::GetScreenBitmap()->GetWidth(), BitmapHelper::GetScreenBitmap()->GetHeight(), game.GetColorDepth());
517
518 set_mouse_cursor(CURS_ARROW);
519
520 dtop=&dialog[dlgnum];
521
522 chose=-1;
523 numdisp=0;
524
525 parserActivated = 0;
526 if ((dtop->topicFlags & DTFLG_SHOWPARSER) && (play.disable_dialog_parser == 0)) {
527 parserInput = new GUITextBox();
528 parserInput->hit = lineheight + get_fixed_pixel_size(4);
529 parserInput->exflags = 0;
530 parserInput->font = usingfont;
531 }
532
533 numdisp=0;
534 for (int i = 0; i < dtop->numoptions; ++i) {
535 if ((dtop->optionflags[i] & DFLG_ON)==0) continue;
536 ensure_text_valid_for_font(dtop->optionnames[i], usingfont);
537 disporder[numdisp]=i;
538 numdisp++;
539 }
540 }
541
Show()542 void DialogOptions::Show()
543 {
544 if (numdisp<1) quit("!DoDialog: all options have been turned off");
545 // Don't display the options if there is only one and the parser
546 // is not enabled.
547 if (!((numdisp > 1) || (parserInput != NULL) || (play.show_single_dialog_option)))
548 {
549 chose = disporder[0]; // only one choice, so select it
550 return;
551 }
552
553 SetVirtualScreen(virtual_screen);
554
555 is_textwindow = 0;
556 forecol = play.dialog_options_highlight_color;
557
558 mouseison=-1;
559 mousewason=-10;
560 dirtyx = 0;
561 dirtyy = 0;
562 dirtywidth = virtual_screen->GetWidth();
563 dirtyheight = virtual_screen->GetHeight();
564 usingCustomRendering = false;
565
566
567 dlgxp = 1;
568 if (get_custom_dialog_options_dimensions(dlgnum))
569 {
570 usingCustomRendering = true;
571 dirtyx = multiply_up_coordinate(ccDialogOptionsRendering.x);
572 dirtyy = multiply_up_coordinate(ccDialogOptionsRendering.y);
573 dirtywidth = multiply_up_coordinate(ccDialogOptionsRendering.width);
574 dirtyheight = multiply_up_coordinate(ccDialogOptionsRendering.height);
575 dialog_abs_x = dirtyx;
576 }
577 else if (game.options[OPT_DIALOGIFACE] > 0)
578 {
579 GUIMain*guib=&guis[game.options[OPT_DIALOGIFACE]];
580 if (guib->IsTextWindow()) {
581 // text-window, so do the QFG4-style speech options
582 is_textwindow = 1;
583 forecol = guib->FgColor;
584 }
585 else {
586 dlgxp = guib->X;
587 dlgyp = guib->Y;
588
589 dirtyx = dlgxp;
590 dirtyy = dlgyp;
591 dirtywidth = guib->Width;
592 dirtyheight = guib->Height;
593 dialog_abs_x = guib->X;
594
595 areawid=guib->Width - 5;
596 padding = TEXTWINDOW_PADDING_DEFAULT;
597
598 GET_OPTIONS_HEIGHT
599
600 if (game.options[OPT_DIALOGUPWARDS]) {
601 // They want the options upwards from the bottom
602 dlgyp = (guib->Y + guib->Height) - needheight;
603 }
604
605 }
606 }
607 else {
608 //dlgyp=(play.viewport.GetHeight()-numdisp*txthit)-1;
609 areawid=play.viewport.GetWidth()-5;
610 padding = TEXTWINDOW_PADDING_DEFAULT;
611 GET_OPTIONS_HEIGHT
612 dlgyp = play.viewport.GetHeight() - needheight;
613
614 dirtyx = 0;
615 dirtyy = dlgyp - 1;
616 dirtywidth = play.viewport.GetWidth();
617 dirtyheight = play.viewport.GetHeight() - dirtyy;
618 dialog_abs_x = 0;
619 }
620 if (!is_textwindow)
621 areawid -= multiply_up_coordinate(play.dialog_options_x) * 2;
622
623 orixp = dlgxp;
624 oriyp = dlgyp;
625 wantRefresh = false;
626 mouseison=-10;
627
628 update_polled_stuff_if_runtime();
629 //->Blit(virtual_screen, tempScrn, 0, 0, 0, 0, screen->GetWidth(), screen->GetHeight());
630 if (!play.mouse_cursor_hidden)
631 domouse(1);
632 update_polled_stuff_if_runtime();
633
634 Redraw();
635 while(Run());
636
637 if (!play.mouse_cursor_hidden)
638 domouse(2);
639 }
640
Redraw()641 void DialogOptions::Redraw()
642 {
643 wantRefresh = true;
644
645 if (usingCustomRendering)
646 {
647 tempScrn = recycle_bitmap(tempScrn, game.GetColorDepth(),
648 multiply_up_coordinate(ccDialogOptionsRendering.width),
649 multiply_up_coordinate(ccDialogOptionsRendering.height));
650 }
651
652 tempScrn->ClearTransparent();
653 Bitmap *ds = SetVirtualScreen(tempScrn);
654
655 dlgxp = orixp;
656 dlgyp = oriyp;
657 // lengthy drawing to screen, so lock it for speed
658 //acquire_screen();
659
660 bool options_surface_has_alpha = false;
661
662 if (usingCustomRendering)
663 {
664 ccDialogOptionsRendering.surfaceToRenderTo = dialogOptionsRenderingSurface;
665 ccDialogOptionsRendering.surfaceAccessed = false;
666 dialogOptionsRenderingSurface->linkedBitmapOnly = tempScrn;
667 dialogOptionsRenderingSurface->hasAlphaChannel = ccDialogOptionsRendering.hasAlphaChannel;
668 options_surface_has_alpha = dialogOptionsRenderingSurface->hasAlphaChannel != 0;
669
670 renderDialogOptionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
671 run_function_on_non_blocking_thread(&renderDialogOptionsFunc);
672
673 if (!ccDialogOptionsRendering.surfaceAccessed)
674 quit("!dialog_options_get_dimensions was implemented, but no dialog_options_render function drew anything to the surface");
675
676 if (parserInput)
677 {
678 parserInput->x = multiply_up_coordinate(ccDialogOptionsRendering.parserTextboxX);
679 curyp = multiply_up_coordinate(ccDialogOptionsRendering.parserTextboxY);
680 areawid = multiply_up_coordinate(ccDialogOptionsRendering.parserTextboxWidth);
681 if (areawid == 0)
682 areawid = tempScrn->GetWidth();
683 }
684 ccDialogOptionsRendering.needRepaint = false;
685 }
686 else if (is_textwindow) {
687 // text window behind the options
688 areawid = multiply_up_coordinate(play.max_dialogoption_width);
689 int biggest = 0;
690 padding = guis[game.options[OPT_DIALOGIFACE]].Padding;
691 for (int i = 0; i < numdisp; ++i) {
692 break_up_text_into_lines(areawid-((2*padding+2)+bullet_wid),usingfont,get_translation(dtop->optionnames[disporder[i]]));
693 if (longestline > biggest)
694 biggest = longestline;
695 }
696 if (biggest < areawid - ((2*padding+6)+bullet_wid))
697 areawid = biggest + ((2*padding+6)+bullet_wid);
698
699 if (areawid < multiply_up_coordinate(play.min_dialogoption_width)) {
700 areawid = multiply_up_coordinate(play.min_dialogoption_width);
701 if (play.min_dialogoption_width > play.max_dialogoption_width)
702 quit("!game.min_dialogoption_width is larger than game.max_dialogoption_width");
703 }
704
705 GET_OPTIONS_HEIGHT
706
707 int savedwid = areawid;
708 int txoffs=0,tyoffs=0,yspos = play.viewport.GetHeight()/2-(2*padding+needheight)/2;
709 int xspos = play.viewport.GetWidth()/2 - areawid/2;
710 // shift window to the right if QG4-style full-screen pic
711 if ((game.options[OPT_SPEECHTYPE] == 3) && (said_text > 0))
712 xspos = (play.viewport.GetWidth() - areawid) - get_fixed_pixel_size(10);
713
714 // needs to draw the right text window, not the default
715 push_screen(ds);
716 Bitmap *text_window_ds = ds;
717 draw_text_window(&text_window_ds, false, &txoffs,&tyoffs,&xspos,&yspos,&areawid,NULL,needheight, game.options[OPT_DIALOGIFACE]);
718 options_surface_has_alpha = guis[game.options[OPT_DIALOGIFACE]].HasAlphaChannel();
719 ds = pop_screen();
720 // snice draw_text_window incrases the width, restore it
721 areawid = savedwid;
722 //wnormscreen();
723
724 dirtyx = xspos;
725 dirtyy = yspos;
726 dirtywidth = text_window_ds->GetWidth();
727 dirtyheight = text_window_ds->GetHeight();
728 dialog_abs_x = txoffs + xspos;
729
730 GfxUtil::DrawSpriteWithTransparency(ds, text_window_ds, xspos, yspos);
731 delete text_window_ds;
732
733 // Ignore the dialog_options_x/y offsets when using a text window
734 txoffs += xspos;
735 tyoffs += yspos;
736 dlgyp = tyoffs;
737 curyp = write_dialog_options(ds, options_surface_has_alpha, txoffs,tyoffs,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding);
738 if (parserInput)
739 parserInput->x = txoffs;
740 }
741 else {
742
743 if (wantRefresh) {
744 // redraw the black background so that anti-alias
745 // fonts don't re-alias themselves
746 if (game.options[OPT_DIALOGIFACE] == 0) {
747 color_t draw_color = ds->GetCompatibleColor(16);
748 ds->FillRect(Rect(0,dlgyp-1,play.viewport.GetWidth()-1,play.viewport.GetHeight()-1), draw_color);
749 }
750 else {
751 GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]];
752 if (!guib->IsTextWindow())
753 draw_gui_for_dialog_options(ds, guib, dlgxp, dlgyp);
754 }
755 }
756
757 dirtyx = 0;
758 dirtywidth = play.viewport.GetWidth();
759
760 if (game.options[OPT_DIALOGIFACE] > 0)
761 {
762 // the whole GUI area should be marked dirty in order
763 // to ensure it gets drawn
764 GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]];
765 dirtyheight = guib->Height;
766 dirtyy = dlgyp;
767 options_surface_has_alpha = guib->HasAlphaChannel();
768 }
769 else
770 {
771 dirtyy = dlgyp - 1;
772 dirtyheight = needheight + 1;
773 options_surface_has_alpha = false;
774 }
775
776 dlgxp += multiply_up_coordinate(play.dialog_options_x);
777 dlgyp += multiply_up_coordinate(play.dialog_options_y);
778
779 // if they use a negative dialog_options_y, make sure the
780 // area gets marked as dirty
781 if (dlgyp < dirtyy)
782 dirtyy = dlgyp;
783
784 //curyp = dlgyp + 1;
785 curyp = dlgyp;
786 curyp = write_dialog_options(ds, options_surface_has_alpha, dlgxp,curyp,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding);
787
788 /*if (curyp > play.viewport.GetHeight()) {
789 dlgyp = play.viewport.GetHeight() - (curyp - dlgyp);
790 ds->FillRect(Rect(0,dlgyp-1,play.viewport.GetWidth()-1,play.viewport.GetHeight()-1);
791 goto redraw_options;
792 }*/
793 if (parserInput)
794 parserInput->x = dlgxp;
795 }
796
797 if (parserInput) {
798 // Set up the text box, if present
799 parserInput->y = curyp + multiply_up_coordinate(game.options[OPT_DIALOGGAP]);
800 parserInput->wid = areawid - get_fixed_pixel_size(10);
801 parserInput->textcol = playerchar->talkcolor;
802 if (mouseison == DLG_OPTION_PARSER)
803 parserInput->textcol = forecol;
804
805 if (game.dialog_bullet) // the parser X will get moved in a second
806 {
807 draw_gui_sprite_v330(ds, game.dialog_bullet, parserInput->x, parserInput->y, options_surface_has_alpha);
808 }
809
810 parserInput->wid -= bullet_wid;
811 parserInput->x += bullet_wid;
812
813 parserInput->Draw(ds);
814 parserInput->activated = 0;
815 }
816
817 wantRefresh = false;
818 ds = SetVirtualScreen(virtual_screen);
819
820 update_polled_stuff_if_runtime();
821
822 subBitmap = recycle_bitmap(subBitmap, tempScrn->GetColorDepth(), dirtywidth, dirtyheight);
823 subBitmap = ReplaceBitmapWithSupportedFormat(subBitmap);
824
825 update_polled_stuff_if_runtime();
826
827 if (usingCustomRendering)
828 {
829 subBitmap->Blit(tempScrn, 0, 0, 0, 0, tempScrn->GetWidth(), tempScrn->GetHeight());
830 invalidate_rect(dirtyx, dirtyy, dirtyx + subBitmap->GetWidth(), dirtyy + subBitmap->GetHeight());
831 }
832 else
833 {
834 subBitmap->Blit(tempScrn, dirtyx, dirtyy, 0, 0, dirtywidth, dirtyheight);
835 }
836
837 if ((ddb != NULL) &&
838 ((ddb->GetWidth() != dirtywidth) ||
839 (ddb->GetHeight() != dirtyheight)))
840 {
841 gfxDriver->DestroyDDB(ddb);
842 ddb = NULL;
843 }
844
845 if (ddb == NULL)
846 ddb = gfxDriver->CreateDDBFromBitmap(subBitmap, options_surface_has_alpha, false);
847 else
848 gfxDriver->UpdateDDBFromBitmap(ddb, subBitmap, options_surface_has_alpha);
849
850 if (runGameLoopsInBackground)
851 {
852 render_graphics(ddb, dirtyx, dirtyy);
853 }
854 }
855
Run()856 bool DialogOptions::Run()
857 {
858 const bool new_custom_render = usingCustomRendering && game.options[OPT_DIALOGOPTIONSAPI] >= 0;
859
860 if (runGameLoopsInBackground)
861 {
862 play.disabled_user_interface++;
863 UpdateGameOnce(false, ddb, dirtyx, dirtyy);
864 play.disabled_user_interface--;
865 }
866 else
867 {
868 timerloop = 0;
869 NEXT_ITERATION();
870
871 render_graphics(ddb, dirtyx, dirtyy);
872
873 update_polled_audio_and_crossfade();
874 }
875
876 if (new_custom_render)
877 {
878 runDialogOptionRepExecFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
879 run_function_on_non_blocking_thread(&runDialogOptionRepExecFunc);
880 }
881
882 int gkey;
883 if (run_service_key_controls(gkey)) {
884 if (parserInput) {
885 wantRefresh = true;
886 // type into the parser
887 if ((gkey == 361) || ((gkey == ' ') && (strlen(parserInput->text) == 0))) {
888 // write previous contents into textbox (F3 or Space when box is empty)
889 for (unsigned int i = strlen(parserInput->text); i < strlen(play.lastParserEntry); i++) {
890 parserInput->KeyPress(play.lastParserEntry[i]);
891 }
892 //domouse(2);
893 Redraw();
894 return true; // continue running loop
895 }
896 else if ((gkey >= 32) || (gkey == 13) || (gkey == 8)) {
897 parserInput->KeyPress(gkey);
898 if (!parserInput->activated) {
899 //domouse(2);
900 Redraw();
901 return true; // continue running loop
902 }
903 }
904 }
905 else if (new_custom_render)
906 {
907 runDialogOptionKeyPressHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
908 runDialogOptionKeyPressHandlerFunc.params[1].SetInt32(GetKeyForKeyPressCb(gkey));
909 run_function_on_non_blocking_thread(&runDialogOptionKeyPressHandlerFunc);
910 }
911 // Allow selection of options by keyboard shortcuts
912 else if (game.options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly &&
913 gkey >= '1' && gkey <= '9')
914 {
915 gkey -= '1';
916 if (gkey < numdisp) {
917 chose = disporder[gkey];
918 return false; // end dialog options running loop
919 }
920 }
921 }
922 mousewason=mouseison;
923 mouseison=-1;
924 if (new_custom_render); // do not automatically detect option under mouse
925 else if (usingCustomRendering)
926 {
927 if ((mousex >= dirtyx) && (mousey >= dirtyy) &&
928 (mousex < dirtyx + tempScrn->GetWidth()) &&
929 (mousey < dirtyy + tempScrn->GetHeight()))
930 {
931 getDialogOptionUnderCursorFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
932 run_function_on_non_blocking_thread(&getDialogOptionUnderCursorFunc);
933
934 if (!getDialogOptionUnderCursorFunc.atLeastOneImplementationExists)
935 quit("!The script function dialog_options_get_active is not implemented. It must be present to use a custom dialogue system.");
936
937 mouseison = ccDialogOptionsRendering.activeOptionID;
938 }
939 else
940 {
941 ccDialogOptionsRendering.activeOptionID = -1;
942 }
943 }
944 else if (mousex >= dialog_abs_x && mousex < (dialog_abs_x + areawid) &&
945 mousey >= dlgyp && mousey < curyp)
946 {
947 mouseison=numdisp-1;
948 for (int i = 0; i < numdisp; ++i) {
949 if (mousey < dispyp[i]) { mouseison=i-1; break; }
950 }
951 if ((mouseison<0) | (mouseison>=numdisp)) mouseison=-1;
952 }
953
954 if (parserInput != NULL) {
955 int relativeMousey = mousey;
956 if (usingCustomRendering)
957 relativeMousey -= dirtyy;
958
959 if ((relativeMousey > parserInput->y) &&
960 (relativeMousey < parserInput->y + parserInput->hit))
961 mouseison = DLG_OPTION_PARSER;
962
963 if (parserInput->activated)
964 parserActivated = 1;
965 }
966
967 int mouseButtonPressed = mgetbutton();
968
969 if (mouseButtonPressed != NONE)
970 {
971 if (mouseison < 0 && !new_custom_render)
972 {
973 if (usingCustomRendering)
974 {
975 runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
976 runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1);
977 run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc);
978
979 if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists)
980 {
981 Redraw();
982 return true; // continue running loop
983 }
984 }
985 return true; // continue running loop
986 }
987 if (mouseison == DLG_OPTION_PARSER) {
988 // they clicked the text box
989 parserActivated = 1;
990 }
991 else if (new_custom_render)
992 {
993 runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
994 runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1);
995 run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc);
996 }
997 else if (usingCustomRendering)
998 {
999 chose = mouseison;
1000 return false; // end dialog options running loop
1001 }
1002 else {
1003 chose=disporder[mouseison];
1004 return false; // end dialog options running loop
1005 }
1006 }
1007
1008 if (usingCustomRendering)
1009 {
1010 int mouseWheelTurn = check_mouse_wheel();
1011 if (mouseWheelTurn != 0)
1012 {
1013 runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering);
1014 runDialogOptionMouseClickHandlerFunc.params[1].SetInt32((mouseWheelTurn < 0) ? 9 : 8);
1015 run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc);
1016
1017 if (!new_custom_render)
1018 {
1019 if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists)
1020 Redraw();
1021 return true; // continue running loop
1022 }
1023 }
1024 }
1025
1026 if (parserActivated) {
1027 // They have selected a custom parser-based option
1028 if (parserInput->text[0] != 0) {
1029 chose = DLG_OPTION_PARSER;
1030 return false; // end dialog options running loop
1031 }
1032 else {
1033 parserActivated = 0;
1034 parserInput->activated = 0;
1035 }
1036 }
1037 if (mousewason != mouseison) {
1038 //domouse(2);
1039 Redraw();
1040 return true; // continue running loop
1041 }
1042 if (new_custom_render)
1043 {
1044 if (ccDialogOptionsRendering.chosenOptionID >= 0)
1045 {
1046 chose = ccDialogOptionsRendering.chosenOptionID;
1047 ccDialogOptionsRendering.chosenOptionID = -1;
1048 return false; // end dialog options running loop
1049 }
1050 if (ccDialogOptionsRendering.needRepaint)
1051 {
1052 Redraw();
1053 return true; // continue running loop
1054 }
1055 }
1056 update_polled_stuff_if_runtime();
1057 if (play.fast_forward == 0) WaitForNextFrame();
1058 return true; // continue running loop
1059 }
1060
Close()1061 void DialogOptions::Close()
1062 {
1063 clear_input_buffer();
1064 //leave_real_screen();
1065 construct_virtual_screen(true);
1066
1067 if (parserActivated)
1068 {
1069 strcpy (play.lastParserEntry, parserInput->text);
1070 ParseText (parserInput->text);
1071 chose = CHOSE_TEXTPARSER;
1072 }
1073
1074 if (parserInput) {
1075 delete parserInput;
1076 parserInput = NULL;
1077 }
1078
1079 if (ddb != NULL)
1080 gfxDriver->DestroyDDB(ddb);
1081 delete subBitmap;
1082
1083 set_mouse_cursor(curswas);
1084 // In case it's the QFG4 style dialog, remove the black screen
1085 play.in_conversation--;
1086 remove_screen_overlay(OVER_COMPLETE);
1087
1088 delete tempScrn;
1089 }
1090
1091 DialogOptions DlgOpt;
1092
show_dialog_options(int _dlgnum,int sayChosenOption,bool _runGameLoopsInBackground)1093 int show_dialog_options(int _dlgnum, int sayChosenOption, bool _runGameLoopsInBackground)
1094 {
1095 DlgOpt.Prepare(_dlgnum, _runGameLoopsInBackground);
1096 DlgOpt.Show();
1097 DlgOpt.Close();
1098
1099 int dialog_choice = DlgOpt.chose;
1100 if (dialog_choice != CHOSE_TEXTPARSER)
1101 {
1102 DialogTopic *dialog_topic = DlgOpt.dtop;
1103 int &option_flags = dialog_topic->optionflags[dialog_choice];
1104 const char *option_name = DlgOpt.dtop->optionnames[dialog_choice];
1105
1106 option_flags |= DFLG_HASBEENCHOSEN;
1107 bool sayTheOption = false;
1108 if (sayChosenOption == SAYCHOSEN_YES)
1109 {
1110 sayTheOption = true;
1111 }
1112 else if (sayChosenOption == SAYCHOSEN_USEFLAG)
1113 {
1114 sayTheOption = ((option_flags & DFLG_NOREPEAT) == 0);
1115 }
1116
1117 if (sayTheOption)
1118 DisplaySpeech(get_translation(option_name), game.playercharacter);
1119 }
1120
1121 return dialog_choice;
1122 }
1123
do_conversation(int dlgnum)1124 void do_conversation(int dlgnum)
1125 {
1126 EndSkippingUntilCharStops();
1127
1128 // AGS 2.x always makes the mouse cursor visible when displaying a dialog.
1129 if (loaded_game_file_version <= kGameVersion_272)
1130 play.mouse_cursor_hidden = 0;
1131
1132 int dlgnum_was = dlgnum;
1133 int previousTopics[MAX_TOPIC_HISTORY];
1134 int numPrevTopics = 0;
1135 DialogTopic *dtop = &dialog[dlgnum];
1136
1137 // run the startup script
1138 int tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0);
1139 if ((tocar == RUN_DIALOG_STOP_DIALOG) ||
1140 (tocar == RUN_DIALOG_GOTO_PREVIOUS))
1141 {
1142 // 'stop' or 'goto-previous' from first startup script
1143 remove_screen_overlay(OVER_COMPLETE);
1144 play.in_conversation--;
1145 return;
1146 }
1147 else if (tocar >= 0)
1148 dlgnum = tocar;
1149
1150 while (dlgnum >= 0)
1151 {
1152 if (dlgnum >= game.numdialog)
1153 quit("!RunDialog: invalid dialog number specified");
1154
1155 dtop = &dialog[dlgnum];
1156
1157 if (dlgnum != dlgnum_was)
1158 {
1159 // dialog topic changed, so play the startup
1160 // script for the new topic
1161 tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0);
1162 dlgnum_was = dlgnum;
1163 if (tocar == RUN_DIALOG_GOTO_PREVIOUS) {
1164 if (numPrevTopics < 1) {
1165 // goto-previous on first topic -- end dialog
1166 tocar = RUN_DIALOG_STOP_DIALOG;
1167 }
1168 else {
1169 tocar = previousTopics[numPrevTopics - 1];
1170 numPrevTopics--;
1171 }
1172 }
1173 if (tocar == RUN_DIALOG_STOP_DIALOG)
1174 break;
1175 else if (tocar >= 0) {
1176 // save the old topic number in the history
1177 if (numPrevTopics < MAX_TOPIC_HISTORY) {
1178 previousTopics[numPrevTopics] = dlgnum;
1179 numPrevTopics++;
1180 }
1181 dlgnum = tocar;
1182 continue;
1183 }
1184 }
1185
1186 int chose = show_dialog_options(dlgnum, SAYCHOSEN_USEFLAG, (game.options[OPT_RUNGAMEDLGOPTS] != 0));
1187
1188 if (chose == CHOSE_TEXTPARSER)
1189 {
1190 said_speech_line = 0;
1191
1192 tocar = run_dialog_request(dlgnum);
1193
1194 if (said_speech_line > 0) {
1195 // fix the problem with the close-up face remaining on screen
1196 DisableInterface();
1197 UpdateGameOnce(); // redraw the screen to make sure it looks right
1198 EnableInterface();
1199 set_mouse_cursor(CURS_ARROW);
1200 }
1201 }
1202 else
1203 {
1204 tocar = run_dialog_script(dtop, dlgnum, dtop->entrypoints[chose], chose + 1);
1205 }
1206
1207 if (tocar == RUN_DIALOG_GOTO_PREVIOUS) {
1208 if (numPrevTopics < 1) {
1209 tocar = RUN_DIALOG_STOP_DIALOG;
1210 }
1211 else {
1212 tocar = previousTopics[numPrevTopics - 1];
1213 numPrevTopics--;
1214 }
1215 }
1216 if (tocar == RUN_DIALOG_STOP_DIALOG) break;
1217 else if (tocar >= 0) {
1218 // save the old topic number in the history
1219 if (numPrevTopics < MAX_TOPIC_HISTORY) {
1220 previousTopics[numPrevTopics] = dlgnum;
1221 numPrevTopics++;
1222 }
1223 dlgnum = tocar;
1224 }
1225
1226 }
1227
1228 }
1229
1230 // end dialog manager
1231
1232
1233 //=============================================================================
1234 //
1235 // Script API Functions
1236 //
1237 //=============================================================================
1238
1239 #include "debug/out.h"
1240 #include "script/script_api.h"
1241 #include "script/script_runtime.h"
1242 #include "ac/dynobj/scriptstring.h"
1243
1244 extern ScriptString myScriptStringImpl;
1245
1246 // int (ScriptDialog *sd)
Sc_Dialog_GetID(void * self,const RuntimeScriptValue * params,int32_t param_count)1247 RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count)
1248 {
1249 API_OBJCALL_INT(ScriptDialog, Dialog_GetID);
1250 }
1251
1252 // int (ScriptDialog *sd)
Sc_Dialog_GetOptionCount(void * self,const RuntimeScriptValue * params,int32_t param_count)1253 RuntimeScriptValue Sc_Dialog_GetOptionCount(void *self, const RuntimeScriptValue *params, int32_t param_count)
1254 {
1255 API_OBJCALL_INT(ScriptDialog, Dialog_GetOptionCount);
1256 }
1257
1258 // int (ScriptDialog *sd)
Sc_Dialog_GetShowTextParser(void * self,const RuntimeScriptValue * params,int32_t param_count)1259 RuntimeScriptValue Sc_Dialog_GetShowTextParser(void *self, const RuntimeScriptValue *params, int32_t param_count)
1260 {
1261 API_OBJCALL_INT(ScriptDialog, Dialog_GetShowTextParser);
1262 }
1263
1264 // int (ScriptDialog *sd, int sayChosenOption)
Sc_Dialog_DisplayOptions(void * self,const RuntimeScriptValue * params,int32_t param_count)1265 RuntimeScriptValue Sc_Dialog_DisplayOptions(void *self, const RuntimeScriptValue *params, int32_t param_count)
1266 {
1267 API_OBJCALL_INT_PINT(ScriptDialog, Dialog_DisplayOptions);
1268 }
1269
1270 // int (ScriptDialog *sd, int option)
Sc_Dialog_GetOptionState(void * self,const RuntimeScriptValue * params,int32_t param_count)1271 RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count)
1272 {
1273 API_OBJCALL_INT_PINT(ScriptDialog, Dialog_GetOptionState);
1274 }
1275
1276 // const char* (ScriptDialog *sd, int option)
Sc_Dialog_GetOptionText(void * self,const RuntimeScriptValue * params,int32_t param_count)1277 RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count)
1278 {
1279 API_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText);
1280 }
1281
1282 // int (ScriptDialog *sd, int option)
Sc_Dialog_HasOptionBeenChosen(void * self,const RuntimeScriptValue * params,int32_t param_count)1283 RuntimeScriptValue Sc_Dialog_HasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count)
1284 {
1285 API_OBJCALL_INT_PINT(ScriptDialog, Dialog_HasOptionBeenChosen);
1286 }
1287
Sc_Dialog_SetHasOptionBeenChosen(void * self,const RuntimeScriptValue * params,int32_t param_count)1288 RuntimeScriptValue Sc_Dialog_SetHasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count)
1289 {
1290 API_OBJCALL_VOID_PINT_PBOOL(ScriptDialog, Dialog_SetHasOptionBeenChosen);
1291 }
1292
1293 // void (ScriptDialog *sd, int option, int newState)
Sc_Dialog_SetOptionState(void * self,const RuntimeScriptValue * params,int32_t param_count)1294 RuntimeScriptValue Sc_Dialog_SetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count)
1295 {
1296 API_OBJCALL_VOID_PINT2(ScriptDialog, Dialog_SetOptionState);
1297 }
1298
1299 // void (ScriptDialog *sd)
Sc_Dialog_Start(void * self,const RuntimeScriptValue * params,int32_t param_count)1300 RuntimeScriptValue Sc_Dialog_Start(void *self, const RuntimeScriptValue *params, int32_t param_count)
1301 {
1302 API_OBJCALL_VOID(ScriptDialog, Dialog_Start);
1303 }
1304
RegisterDialogAPI()1305 void RegisterDialogAPI()
1306 {
1307 ccAddExternalObjectFunction("Dialog::get_ID", Sc_Dialog_GetID);
1308 ccAddExternalObjectFunction("Dialog::get_OptionCount", Sc_Dialog_GetOptionCount);
1309 ccAddExternalObjectFunction("Dialog::get_ShowTextParser", Sc_Dialog_GetShowTextParser);
1310 ccAddExternalObjectFunction("Dialog::DisplayOptions^1", Sc_Dialog_DisplayOptions);
1311 ccAddExternalObjectFunction("Dialog::GetOptionState^1", Sc_Dialog_GetOptionState);
1312 ccAddExternalObjectFunction("Dialog::GetOptionText^1", Sc_Dialog_GetOptionText);
1313 ccAddExternalObjectFunction("Dialog::HasOptionBeenChosen^1", Sc_Dialog_HasOptionBeenChosen);
1314 ccAddExternalObjectFunction("Dialog::SetHasOptionBeenChosen^2", Sc_Dialog_SetHasOptionBeenChosen);
1315 ccAddExternalObjectFunction("Dialog::SetOptionState^2", Sc_Dialog_SetOptionState);
1316 ccAddExternalObjectFunction("Dialog::Start^0", Sc_Dialog_Start);
1317
1318 /* ----------------------- Registering unsafe exports for plugins -----------------------*/
1319
1320 ccAddExternalFunctionForPlugin("Dialog::get_ID", (void*)Dialog_GetID);
1321 ccAddExternalFunctionForPlugin("Dialog::get_OptionCount", (void*)Dialog_GetOptionCount);
1322 ccAddExternalFunctionForPlugin("Dialog::get_ShowTextParser", (void*)Dialog_GetShowTextParser);
1323 ccAddExternalFunctionForPlugin("Dialog::DisplayOptions^1", (void*)Dialog_DisplayOptions);
1324 ccAddExternalFunctionForPlugin("Dialog::GetOptionState^1", (void*)Dialog_GetOptionState);
1325 ccAddExternalFunctionForPlugin("Dialog::GetOptionText^1", (void*)Dialog_GetOptionText);
1326 ccAddExternalFunctionForPlugin("Dialog::HasOptionBeenChosen^1", (void*)Dialog_HasOptionBeenChosen);
1327 ccAddExternalFunctionForPlugin("Dialog::SetOptionState^2", (void*)Dialog_SetOptionState);
1328 ccAddExternalFunctionForPlugin("Dialog::Start^0", (void*)Dialog_Start);
1329 }
1330