Bottom-mounted Dialogue

Makes the drawer more complicated, but the benefit for most circumstances is significant.
In non-splitscreen contexts, pushes V_SLIDEIN|V_SNAPTOBOTTOM HUD elements upwards when the Dialogue is open.
This commit is contained in:
toaster 2023-12-01 16:44:11 +00:00
parent 00fdae8b52
commit d0117bc222
4 changed files with 77 additions and 44 deletions

View file

@ -278,6 +278,15 @@ void Dialogue::Tick(void)
} }
} }
INT32 Dialogue::SlideAmount(fixed_t multiplier)
{
if (slide == 0)
return 0;
if (slide == FRACUNIT)
return multiplier;
return Easing_OutCubic(slide, 0, multiplier);
}
void Dialogue::Draw(void) void Dialogue::Draw(void)
{ {
if (slide == 0) if (slide == 0)
@ -287,12 +296,14 @@ void Dialogue::Draw(void)
const UINT8 bgcol = 1, darkcol = 235; const UINT8 bgcol = 1, darkcol = 235;
INT32 speakernameedge = 6; const fixed_t height = 78 * FRACUNIT;
INT32 speakernameedge = -6;
srb2::Draw drawer = srb2::Draw drawer =
srb2::Draw( srb2::Draw(
0, FixedToFloat(Easing_OutCubic(slide, -78 * FRACUNIT, 0)) BASEVIDWIDTH, BASEVIDHEIGHT - FixedToFloat(SlideAmount(height) - height)
).flags(V_SNAPTOTOP); ).flags(V_SNAPTOBOTTOM);
// TODO -- hack, change when dialogue is made per-player/netsynced // TODO -- hack, change when dialogue is made per-player/netsynced
UINT32 speakerbgflags = (players[consoleplayer].nocontrol == 0 && P_LevelIsFrozen() == false) UINT32 speakerbgflags = (players[consoleplayer].nocontrol == 0 && P_LevelIsFrozen() == false)
@ -300,26 +311,29 @@ void Dialogue::Draw(void)
: 0; : 0;
drawer drawer
.flags(speakerbgflags) .flags(speakerbgflags|V_VFLIP|V_FLIP)
.patch("TUTDIAGA"); .patch("TUTDIAGA");
drawer.patch("TUTDIAGB"); drawer
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGB");
if (portrait != nullptr) if (portrait != nullptr)
{ {
drawer.patch("TUTDIAGC"); drawer
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGC");
drawer drawer
.xy(10, 41) .xy(-10-32, -41-32)
.colormap(portraitColormap) .colormap(portraitColormap)
.patch(portrait); .patch(portrait);
speakernameedge += 39; // 45 speakernameedge -= 39; // -45
} }
const char *speakername = speaker.c_str(); const char *speakername = speaker.c_str();
INT32 rightmostedge = 142;
const INT32 arrowstep = 8; // width of TUTDIAGD const INT32 arrowstep = 8; // width of TUTDIAGD
if (speakername && speaker[0]) if (speakername && speaker[0])
@ -327,19 +341,20 @@ void Dialogue::Draw(void)
INT32 speakernamewidth = V_StringWidth(speakername, 0); INT32 speakernamewidth = V_StringWidth(speakername, 0);
INT32 existingborder = (portrait == nullptr ? -4 : 3); INT32 existingborder = (portrait == nullptr ? -4 : 3);
const INT32 speakernamewidthoffset = (speakernamewidth + (arrowstep - existingborder) - 1) % arrowstep; INT32 speakernamewidthoffset = (speakernamewidth + (arrowstep - existingborder) - 1) % arrowstep;
if (speakernamewidthoffset) if (speakernamewidthoffset)
{ {
speakernamewidth += (arrowstep - speakernamewidthoffset); speakernamewidthoffset = (arrowstep - speakernamewidthoffset);
speakernamewidth += speakernamewidthoffset;
} }
if (portrait == nullptr) if (portrait == nullptr)
{ {
speakernameedge += 3; speakernameedge -= 3;
speakernamewidth += 3; speakernamewidth += 3;
existingborder += 2; existingborder += 2;
drawer drawer
.xy(speakernameedge - 2, 36) .xy(speakernameedge, -36)
.width(2) .width(2)
.height(3+11) .height(3+11)
.fill(bgcol); .fill(bgcol);
@ -348,59 +363,63 @@ void Dialogue::Draw(void)
if (speakernamewidth > existingborder) if (speakernamewidth > existingborder)
{ {
drawer drawer
.x(speakernameedge + existingborder) .x(speakernameedge - speakernamewidth)
.width(speakernamewidth - existingborder) .width(speakernamewidth - existingborder)
.y(36) .y(-36-3)
.height(3) .height(3)
.fill(bgcol); .fill(bgcol);
drawer drawer
.x(speakernameedge + existingborder) .x(speakernameedge - speakernamewidth)
.width(speakernamewidth - existingborder) .width(speakernamewidth - existingborder)
.y(38) .y(-38-11)
.height(11) .height(11)
.fill(darkcol); .fill(darkcol);
} }
speakernameedge -= speakernamewidth;
drawer drawer
.xy(speakernameedge, 39) .xy(speakernamewidthoffset + speakernameedge, -39-9)
.font(srb2::Draw::Font::kConsole) .font(srb2::Draw::Font::kConsole)
.text(speakername); .text(speakername);
speakernameedge += speakernamewidth; speakernameedge -= 5;
drawer drawer
.xy(speakernameedge + 5, 36) .xy(speakernameedge, -36)
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGD"); .patch("TUTDIAGD");
drawer drawer
.xy(speakernameedge, 36) .xy(speakernameedge, -36-3-11)
.width(5) .width(5)
.height(3+11) .height(3+11)
.fill(bgcol); .fill(bgcol);
drawer drawer
.xy(speakernameedge, 36) .xy(speakernameedge + 5, -36)
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGF"); .patch("TUTDIAGF");
speakernameedge += (5+arrowstep);
} }
while (speakernameedge < rightmostedge) while (speakernameedge > -142) // the left-most edge
{ {
drawer speakernameedge -= arrowstep;
.xy(speakernameedge, 36)
.patch("TUTDIAGD");
speakernameedge += arrowstep; drawer
.xy(speakernameedge, -36)
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGD");
} }
drawer drawer
.xy(speakernameedge, 36) .xy(speakernameedge - arrowstep, -36)
.flags(V_VFLIP|V_FLIP)
.patch("TUTDIAGE"); .patch("TUTDIAGE");
drawer drawer
.xy(10, 3) .xy(10 - BASEVIDWIDTH, -3-32)
.font(srb2::Draw::Font::kConsole) .font(srb2::Draw::Font::kConsole)
.text( text.c_str() ); .text( text.c_str() );
@ -409,16 +428,13 @@ void Dialogue::Draw(void)
if (TextDone()) if (TextDone())
{ {
drawer drawer
.xy(304, 7) .xy(-14, -7-5)
.patch("TUTDIAG2"); .patch("TUTDIAG2");
} }
K_drawButton( drawer
FloatToFixed(drawer.x() + 303), .xy(17-14 - BASEVIDWIDTH, -39-16)
FloatToFixed(drawer.y() + 39), .button(srb2::Draw::Button::z, Held());
V_SNAPTOTOP,
kp_button_z[0], Held()
);
} }
} }
@ -459,3 +475,8 @@ void K_TickDialogue(void)
{ {
g_dialogue.Tick(); g_dialogue.Tick();
} }
INT32 K_GetDialogueSlide(fixed_t multiplier)
{
return g_dialogue.SlideAmount(multiplier);
}

View file

@ -26,6 +26,7 @@ void K_DrawDialogue(void);
void K_TickDialogue(void); void K_TickDialogue(void);
boolean K_DialogueFreeze(void); boolean K_DialogueFreeze(void);
INT32 K_GetDialogueSlide(fixed_t multiplier);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -78,6 +78,8 @@ public:
void Tick(void); void Tick(void);
void Draw(void); void Draw(void);
INT32 SlideAmount(fixed_t multiplier);
void Dismiss(void); void Dismiss(void);
void Unset(void); void Unset(void);
}; };

View file

@ -28,6 +28,7 @@
#include "r_draw.h" #include "r_draw.h"
#include "console.h" #include "console.h"
#include "r_fps.h" #include "r_fps.h"
#include "k_dialogue.h" // K_GetDialogueSlide
#include "i_video.h" // rendermode #include "i_video.h" // rendermode
#include "z_zone.h" #include "z_zone.h"
@ -516,18 +517,26 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
INT32 baseheight = BASEVIDHEIGHT * dupy; INT32 baseheight = BASEVIDHEIGHT * dupy;
SINT8 player = R_GetViewNumber(); SINT8 player = R_GetViewNumber();
if (options & V_SPLITSCREEN) if (r_splitscreen > 0)
{ {
if (r_splitscreen > 0) if (options & V_SPLITSCREEN)
{ {
screenheight /= 2; screenheight /= 2;
baseheight /= 2; baseheight /= 2;
}
if (r_splitscreen > 1) if (r_splitscreen > 1)
{
screenwidth /= 2;
basewidth /= 2;
}
}
}
else if ((options & (V_SLIDEIN|V_SNAPTOBOTTOM)) == (V_SLIDEIN|V_SNAPTOBOTTOM))
{
INT32 slide = K_GetDialogueSlide(51 * FRACUNIT);
if (slide)
{ {
screenwidth /= 2; *y -= FixedMul(slide, dupy);
basewidth /= 2;
} }
} }