@@ -778,7 +778,7 @@ int Character_GetHasExplicitTint(CharacterInfo *ch)
778
778
}
779
779
780
780
void Character_Say (CharacterInfo *chaa, const char *text) {
781
- _DisplaySpeechCore (chaa->index_id , text);
781
+ DisplaySpeechCore (chaa->index_id , text);
782
782
}
783
783
784
784
void Character_SayAt (CharacterInfo *chaa, int x, int y, int width, const char *texx) {
@@ -1035,7 +1035,7 @@ void Character_Tint(CharacterInfo *chaa, int red, int green, int blue, int opaci
1035
1035
}
1036
1036
1037
1037
void Character_Think (CharacterInfo *chaa, const char *text) {
1038
- _DisplayThoughtCore (chaa->index_id , text);
1038
+ DisplayThoughtCore (chaa->index_id , text);
1039
1039
}
1040
1040
1041
1041
void Character_UnlockView (CharacterInfo *chaa) {
@@ -2493,7 +2493,7 @@ int check_click_on_character(int xx,int yy,int mood) {
2493
2493
return 0 ;
2494
2494
}
2495
2495
2496
- void _DisplaySpeechCore (int chid, const char *displbuf) {
2496
+ void DisplaySpeechCore (int chid, const char *displbuf) {
2497
2497
if (displbuf[0 ] == 0 ) {
2498
2498
// no text, just update the current character who's speaking
2499
2499
// this allows the portrait side to be switched with an empty
@@ -2511,30 +2511,25 @@ void _DisplaySpeechCore(int chid, const char *displbuf) {
2511
2511
DisplaySpeech (displbuf, chid);
2512
2512
}
2513
2513
2514
- void _DisplayThoughtCore (int chid, const char *displbuf) {
2514
+ void DisplayThoughtCore (int chid, const char *displbuf) {
2515
2515
// adjust timing of text (so that DisplayThought("%s", str) pauses
2516
2516
// for the length of the string not 2 frames)
2517
2517
int len = (int )strlen (displbuf);
2518
2518
if (len > source_text_length + 3 )
2519
2519
source_text_length = len;
2520
2520
2521
- int xpp = -1 , ypp = -1 , width = -1 ;
2522
-
2521
+ int width = -1 ;
2523
2522
if ((game.options [OPT_SPEECHTYPE] == 0 ) || (game.chars [chid].thinkview <= 0 )) {
2524
2523
// lucasarts-style, so we want a speech bubble actually above
2525
2524
// their head (or if they have no think anim in Sierra-style)
2526
2525
width = data_to_game_coord (play.speech_bubble_width );
2527
- xpp = play.RoomToScreenX (data_to_game_coord (game.chars [chid].x )) - width / 2 ;
2528
- if (xpp < 0 )
2529
- xpp = 0 ;
2530
- // -1 will automatically put it above the char's head
2531
- ypp = -1 ;
2532
2526
}
2533
2527
2534
- _displayspeech (displbuf, chid, xpp, ypp , width, 1 );
2528
+ display_speech (displbuf, chid, - 1 , - 1 , width, true /* auto-pos */ , true /* is thought */ );
2535
2529
}
2536
2530
2537
- void _displayspeech (const char *texx, int aschar, int xx, int yy, int widd, int isThought) {
2531
+ void display_speech (const char *texx, int aschar, int xx, int yy, int widd, bool auto_position, bool is_thought)
2532
+ {
2538
2533
if (!is_valid_character (aschar))
2539
2534
quit (" !DisplaySpeech: invalid character" );
2540
2535
@@ -2592,29 +2587,32 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2592
2587
}
2593
2588
2594
2589
DisplayTextStyle disp_style = kDisplayTextStyle_Overchar ;
2590
+ // If the character is in this room, then default to aligning the speech
2591
+ // to the character position; but if it's not then center the speech on screen
2592
+ DisplayTextPosition disp_pos = auto_position ?
2593
+ get_textpos_from_scriptcoords (xx, yy, (speakingChar->room == displayed_room)) :
2594
+ kDisplayTextPos_Normal ;
2595
2595
const color_t text_color = speakingChar->talkcolor ;
2596
2596
2597
- Rect ui_view = play.GetUIViewport ();
2598
2597
DisplayTextShrink allow_shrink = kDisplayTextShrink_None ;
2598
+ bool align_hcenter = false ; // whether to align text by centering over position
2599
+
2600
+ const Rect ui_view = play.GetUIViewport ();
2599
2601
int bwidth = widd;
2600
2602
if (bwidth < 0 )
2601
2603
bwidth = ui_view.GetWidth ()/2 + ui_view.GetWidth ()/4 ;
2602
2604
2603
2605
set_our_eip (151 );
2604
2606
2605
2607
int useview = speakingChar->talkview ;
2606
- if (isThought) {
2608
+ if (is_thought)
2609
+ {
2607
2610
useview = speakingChar->thinkview ;
2608
2611
// view 0 is not valid for think views
2609
2612
if (useview == 0 )
2610
2613
useview = -1 ;
2611
2614
// speech bubble can shrink to fit
2612
2615
allow_shrink = kDisplayTextShrink_Left ;
2613
- if (speakingChar->room != displayed_room) {
2614
- // not in room, centre it
2615
- xx = -1 ;
2616
- yy = -1 ;
2617
- }
2618
2616
}
2619
2617
2620
2618
if (useview >= game.numviews )
@@ -2633,7 +2631,7 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2633
2631
stop_character_idling (speakingChar);
2634
2632
}
2635
2633
2636
- int tdxp = xx,tdyp = yy;
2634
+ int tdxp = xx, tdyp = yy;
2637
2635
int oldview=-1 , oldloop = -1 ;
2638
2636
int ovr_type = 0 ;
2639
2637
text_lips_offset = 0 ;
@@ -2685,17 +2683,16 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2685
2683
tdxp = view->RoomToScreen (data_to_game_coord (speakingChar->x ), 0 ).first .X ;
2686
2684
if (tdxp < 2 )
2687
2685
tdxp = 2 ;
2688
- // tell it to centre it (passing negative x coord further will be treated as a alignment instruction)
2689
- // FIXME: this is unreliable and bug prone, use a separate argument for alignment!
2690
- tdxp = -tdxp;
2686
+ // tell it to align it by center
2687
+ align_hcenter = auto_position && (xx < 0 );
2691
2688
2692
2689
if (tdyp < 0 )
2693
2690
{
2694
2691
int sppic = views[speakingChar->view ].loops [speakingChar->loop ].frames [0 ].pic ;
2695
2692
int height = (charextra[aschar].height < 1 ) ? game.SpriteInfos [sppic].Height : charextra[aschar].height ;
2696
2693
tdyp = view->RoomToScreen (0 , data_to_game_coord (charextra[aschar].GetEffectiveY (speakingChar)) - height).first .Y
2697
2694
- get_fixed_pixel_size (5 );
2698
- if (isThought ) // if it's a thought, lift it a bit further up
2695
+ if (is_thought ) // if it's a thought, lift it a bit further up
2699
2696
tdyp -= get_fixed_pixel_size (10 );
2700
2697
}
2701
2698
if (tdyp < 5 )
@@ -2705,6 +2702,7 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2705
2702
2706
2703
if ((useview >= 0 ) && (game.options [OPT_SPEECHTYPE] > 0 )) {
2707
2704
// Sierra-style close-up portrait
2705
+ disp_pos = kDisplayTextPos_Normal ;
2708
2706
2709
2707
if (play.swap_portrait_lastchar != aschar) {
2710
2708
// if the portraits are set to Alternate, OR they are
@@ -2900,10 +2898,10 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2900
2898
facetalkloop = 0 ;
2901
2899
facetalkframe = 0 ;
2902
2900
facetalkwait = viptr->loops [0 ].frames [0 ].speed + GetCharacterSpeechAnimationDelay (speakingChar);
2903
- facetalkrepeat = (isThought ) ? 0 : 1 ;
2901
+ facetalkrepeat = (is_thought ) ? 0 : 1 ;
2904
2902
facetalkBlinkLoop = 0 ;
2905
2903
facetalkAllowBlink = 1 ;
2906
- if ((isThought ) && (speakingChar->flags & CHF_NOBLINKANDTHINK))
2904
+ if ((is_thought ) && (speakingChar->flags & CHF_NOBLINKANDTHINK))
2907
2905
facetalkAllowBlink = 0 ;
2908
2906
facetalkchar = &game.chars [aschar];
2909
2907
if (facetalkchar->blinktimer < 0 )
@@ -2921,7 +2919,7 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2921
2919
oldview = speakingChar->view ;
2922
2920
oldloop = speakingChar->loop ;
2923
2921
2924
- speakingChar->set_animating (!isThought , // only repeat if speech, not thought
2922
+ speakingChar->set_animating (!is_thought , // only repeat if speech, not thought
2925
2923
true , // always forwards
2926
2924
GetCharacterSpeechAnimationDelay (speakingChar));
2927
2925
@@ -2953,33 +2951,32 @@ void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int i
2953
2951
if ((relx < ui_view.GetWidth () / 4 ) || (relx > ui_view.GetWidth () - (ui_view.GetWidth () / 4 )))
2954
2952
bwidth -= ui_view.GetWidth () / 5 ;
2955
2953
}
2956
- /* this causes the text to bob up and down as they talk
2957
- tdxp = OVR_AUTOPLACE;
2958
- tdyp = aschar;*/
2959
- if (!isThought) // set up the lip sync if not thinking
2954
+ if (!is_thought) // set up the lip sync if not thinking
2960
2955
char_speaking_anim = aschar;
2961
-
2962
2956
}
2963
2957
}
2964
2958
else
2959
+ {
2960
+ // If the character is in another room, then center the speech on screen
2965
2961
allow_shrink = kDisplayTextShrink_Left ;
2962
+ }
2966
2963
2967
2964
// If initial argument was NOT requiring a autoposition,
2968
2965
// but further calculation set it to be centered, then make it so here
2969
- // (note : this assumes that a valid width is also passed)
2970
- if ((xx >= 0 ) && (tdxp < 0 ) )
2966
+ // (NOTE : this assumes that a valid width is also passed)
2967
+ if ((xx >= 0 ) && align_hcenter )
2971
2968
tdxp -= widd / 2 ;
2972
2969
2973
2970
// if they used DisplaySpeechAt, then use the supplied width
2974
- if ((widd > 0 ) && (isThought == 0 ))
2971
+ if ((widd > 0 ) && (!is_thought ))
2975
2972
allow_shrink = kDisplayTextShrink_None ;
2976
2973
2977
- if (isThought )
2974
+ if (is_thought )
2978
2975
char_thinking = aschar;
2979
2976
2980
2977
set_our_eip (155 );
2981
2978
display_main (tdxp, tdyp, bwidth, texx, nullptr , kDisplayText_Speech , 0 /* no overid */ ,
2982
- DisplayTextLooks (disp_style, isThought , allow_shrink), FONT_SPEECH, text_color, overlayPositionFixed);
2979
+ DisplayTextLooks (disp_style, disp_pos , allow_shrink, is_thought ), FONT_SPEECH, text_color, overlayPositionFixed);
2983
2980
set_our_eip (156 );
2984
2981
if ((play.in_conversation > 0 ) && (game.options [OPT_SPEECHTYPE] == 3 ))
2985
2982
closeupface = nullptr ;
@@ -3023,8 +3020,9 @@ int get_character_currently_talking() {
3023
3020
return -1 ;
3024
3021
}
3025
3022
3026
- void DisplaySpeech (const char *texx, int aschar) {
3027
- _displayspeech (texx, aschar, -1 , -1 , -1 , 0 );
3023
+ void DisplaySpeech (const char *texx, int aschar)
3024
+ {
3025
+ display_speech (texx, aschar, -1 , -1 , -1 , true /* auto-pos*/ , false /* not thought */ );
3028
3026
}
3029
3027
3030
3028
// Calculate which frame of the loop to use for this character of
0 commit comments