ScriptUserObject* Screen_ScreenToRoomPoint(int scrx, int scry) { VpPoint vpt = play.ScreenToRoom(scrx, scry); if (vpt.second < 0) return NULL; return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); }
// Pass yy = -1 to find Y co-ord automatically // allowShrink = 0 for none, 1 for leftwards, 2 for rightwards // pass blocking=2 to create permanent overlay int _display_main(int xx,int yy,int wii,const char*text,int blocking,int usingfont,int asspch, int isThought, int allowShrink, bool overlayPositionFixed) { const bool use_speech_textwindow = (asspch < 0) && (game.options[OPT_SPEECHTYPE] >= 2); const bool use_thought_gui = (isThought) && (game.options[OPT_THOUGHTGUI] > 0); bool alphaChannel = false; char todis[STD_BUFFER_SIZE]; snprintf(todis, STD_BUFFER_SIZE - 1, "%s", text); int usingGui = -1; if (use_speech_textwindow) usingGui = play.speech_textwindow_gui; else if (use_thought_gui) usingGui = game.options[OPT_THOUGHTGUI]; int padding = get_textwindow_padding(usingGui); int paddingScaled = padding; int paddingDoubledScaled = padding * 2; // Just in case screen size does is not neatly divisible by 320x200 ensure_text_valid_for_font(todis, usingfont); break_up_text_into_lines(wii-2*padding,usingfont,todis); disp.lineheight = getfontheight_outlined(usingfont); disp.linespacing= getfontspacing_outlined(usingfont); disp.fulltxtheight = getheightoflines(usingfont, numlines); // if it's a normal message box and the game was being skipped, // ensure that the screen is up to date before the message box // is drawn on top of it if ((play.skip_until_char_stops >= 0) && (blocking == 1)) render_graphics(); EndSkippingUntilCharStops(); if (topBar.wantIt) { // ensure that the window is wide enough to display // any top bar text int topBarWid = wgettextwidth_compensate(topBar.text, topBar.font); topBarWid += (play.top_bar_borderwidth + 2) * 2; if (longestline < topBarWid) longestline = topBarWid; // the top bar should behave like DisplaySpeech wrt blocking blocking = 0; } if (asspch > 0) { // update the all_buttons_disabled variable in advance // of the adjust_x/y_for_guis calls play.disabled_user_interface++; update_gui_disabled_status(); play.disabled_user_interface--; } const Rect &ui_view = play.GetUIViewport(); if (xx == OVR_AUTOPLACE) ; // centre text in middle of screen else if (yy<0) yy= ui_view.GetHeight()/2-disp.fulltxtheight/2-padding; // speech, so it wants to be above the character's head else if (asspch > 0) { yy-=disp.fulltxtheight; if (yy < 5) yy=5; yy = adjust_y_for_guis (yy); } if (longestline < wii - paddingDoubledScaled) { // shrink the width of the dialog box to fit the text int oldWid = wii; //if ((asspch >= 0) || (allowShrink > 0)) // If it's not speech, or a shrink is allowed, then shrink it if ((asspch == 0) || (allowShrink > 0)) wii = longestline + paddingDoubledScaled; // shift the dialog box right to align it, if necessary if ((allowShrink == 2) && (xx >= 0)) xx += (oldWid - wii); } if (xx<-1) { xx=(-xx)-wii/2; if (xx < 0) xx = 0; xx = adjust_x_for_guis (xx, yy); if (xx + wii >= ui_view.GetWidth()) xx = (ui_view.GetWidth() - wii) - 5; } else if (xx<0) xx= ui_view.GetWidth()/2-wii/2; int ee, extraHeight = paddingDoubledScaled; color_t text_color = MakeColor(15); if (blocking < 2) remove_screen_overlay(OVER_TEXTMSG); Bitmap *text_window_ds = BitmapHelper::CreateTransparentBitmap((wii > 0) ? wii : 2, disp.fulltxtheight + extraHeight, game.GetColorDepth()); // inform draw_text_window to free the old bitmap const bool wantFreeScreenop = true; if ((strlen (todis) < 1) || (strcmp (todis, " ") == 0) || (wii == 0)) ; // if it's an empty speech line, don't draw anything else if (asspch) { //text_color = ds->GetCompatibleColor(12); int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2; int drawBackground = 0; if (use_speech_textwindow) { drawBackground = 1; } else if (use_thought_gui) { // make it treat it as drawing inside a window now if (asspch > 0) asspch = -asspch; drawBackground = 1; } if (drawBackground) { draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &xx, &yy, &wii, &text_color, 0, usingGui); if (usingGui > 0) { alphaChannel = guis[usingGui].HasAlphaChannel(); } } else if ((ShouldAntiAliasText()) && (game.GetColorDepth() >= 24)) alphaChannel = true; for (ee=0;ee<numlines;ee++) { //int ttxp=wii/2 - wgettextwidth_compensate(lines[ee], usingfont)/2; int ttyp=ttxtop+ee*disp.linespacing; // asspch < 0 means that it's inside a text box so don't // centre the text if (asspch < 0) { if ((usingGui >= 0) && ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor); else text_color = text_window_ds->GetCompatibleColor(-asspch); wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, lines[ee], play.text_align); } else { text_color = text_window_ds->GetCompatibleColor(asspch); //wouttext_outline(ttxp,ttyp,usingfont,lines[ee]); wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, lines[ee], play.speech_text_align); } } } else { int xoffs,yoffs, oriwid = wii - padding * 2; draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs,&yoffs,&xx,&yy,&wii,&text_color); if (game.options[OPT_TWCUSTOM] > 0) { alphaChannel = guis[game.options[OPT_TWCUSTOM]].HasAlphaChannel(); } adjust_y_coordinate_for_text(&yoffs, usingfont); for (ee=0;ee<numlines;ee++) wouttext_aligned (text_window_ds, xoffs, yoffs + ee * disp.linespacing, oriwid, usingfont, text_color, lines[ee], play.text_align); } int ovrtype = OVER_TEXTMSG; if (blocking == 2) ovrtype=OVER_CUSTOM; else if (blocking >= OVER_CUSTOM) ovrtype=blocking; int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, alphaChannel); // we should not delete text_window_ds here, because it is now owned by Overlay if (blocking>=2) { return screenover[nse].type; } if (blocking) { if (play.fast_forward) { remove_screen_overlay(OVER_TEXTMSG); play.messagetime=-1; return 0; } /* wputblock(xx,yy,screenop,1); remove_screen_overlay(OVER_TEXTMSG);*/ if (!play.mouse_cursor_hidden) ags_domouse(DOMOUSE_ENABLE); // play.skip_display has same values as SetSkipSpeech: // 0 = click mouse or key to skip // 1 = key only // 2 = can't skip at all // 3 = only on keypress, no auto timer // 4 = mouse only int countdown = GetTextDisplayTime (todis); int skip_setting = user_to_internal_skip_speech((SkipSpeechStyle)play.skip_display); while (1) { /* if (!play.mouse_cursor_hidden) ags_domouse(DOMOUSE_UPDATE); write_screen();*/ update_audio_system_on_game_loop(); render_graphics(); if (ags_mgetbutton()>NONE) { // If we're allowed, skip with mouse if (skip_setting & SKIP_MOUSECLICK) break; } int kp; if (run_service_key_controls(kp)) { // let them press ESC to skip the cutscene check_skip_cutscene_keypress (kp); if (play.fast_forward) break; if (skip_setting & SKIP_KEYPRESS) break; } PollUntilNextFrame(); countdown--; if (play.speech_has_voice) { // extend life of text if the voice hasn't finished yet if (channel_is_playing(SCHAN_SPEECH) && (play.fast_forward == 0)) { if (countdown <= 1) countdown = 1; } else // if the voice has finished, remove the speech countdown = 0; } if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER)) { play.ignore_user_input_until_time = AGS_Clock::now() + std::chrono::milliseconds(play.ignore_user_input_after_text_timeout_ms); break; } // if skipping cutscene, don't get stuck on No Auto Remove // text boxes if ((countdown < 1) && (play.fast_forward)) break; } if (!play.mouse_cursor_hidden) ags_domouse(DOMOUSE_DISABLE); remove_screen_overlay(OVER_TEXTMSG); construct_virtual_screen(true); } else { // if the speech does not time out, but we are skipping a cutscene, // allow it to time out if ((play.messagetime < 0) && (play.fast_forward)) play.messagetime = 2; if (!overlayPositionFixed) { screenover[nse].positionRelativeToScreen = false; VpPoint vpt = play.ScreenToRoom(screenover[nse].x, screenover[nse].y, false); screenover[nse].x = vpt.first.X; screenover[nse].y = vpt.first.Y; } GameLoopUntilEvent(UNTIL_NOOVERLAY,0); } play.messagetime=-1; return 0; }