mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
V_ScaledWordWrap API changes
- The function is back to producing zone-allocated memory copies, like its precursor V_WordWrap
- The author of this commit got rid of that dependency originally because it seemed like a fair part of the API, and meant static buffers could be used in certain circumstances, but it was necessary to revert for the following change.
- Newlines can now be inserted mid-word, treating the width provided as ironclad except in the case of single characters wider than the region.
- This will be necessary for future work with the in-game chat.
- Reserves 8 characters at first, then Z_Reallocs double that every time it runs out.
This commit is contained in:
parent
4675a9b059
commit
9e4e996a5e
7 changed files with 93 additions and 57 deletions
|
|
@ -2283,12 +2283,11 @@ static void F_PreparePageText(char *pagetext)
|
|||
Z_Free(promptpagetext);
|
||||
if (pagetext && pagetext[0])
|
||||
{
|
||||
promptpagetext = Z_StrDup(pagetext);
|
||||
V_ScaledWordWrap(
|
||||
promptpagetext = V_ScaledWordWrap(
|
||||
(textx - textr)<<FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0, HU_FONT,
|
||||
promptpagetext
|
||||
pagetext
|
||||
);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1273,19 +1273,15 @@ boolean HU_Responder(event_t *ev)
|
|||
// Now a wrapper for the chat drawer.
|
||||
static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
{
|
||||
char *newstring = Z_StrDup(string);
|
||||
|
||||
fixed_t scale = (vid.width < 640) ? FRACUNIT : FRACUNIT/2;
|
||||
|
||||
V_ScaledWordWrap(
|
||||
return V_ScaledWordWrap(
|
||||
(w - x) << FRACBITS,
|
||||
scale, scale, scale,
|
||||
option,
|
||||
HU_FONT,
|
||||
newstring
|
||||
string
|
||||
);
|
||||
|
||||
return newstring;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1577,6 +1577,11 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
}
|
||||
}
|
||||
|
||||
if (message[0] == '\0')
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Valid sentence capitalisation handling.
|
||||
{
|
||||
// Finds the first : character, indicating the end of the prefix.
|
||||
|
|
@ -1604,15 +1609,13 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
}
|
||||
|
||||
// Finally, do a clean wordwrap!
|
||||
V_ScaledWordWrap(
|
||||
return V_ScaledWordWrap(
|
||||
DESCRIPTIONWIDTH << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0,
|
||||
HU_FONT,
|
||||
message
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
static boolean M_CheckUnlockConditions(player_t *player)
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
|||
return;
|
||||
|
||||
challengesmenu.currentunlock = unlockid;
|
||||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
||||
challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME);
|
||||
|
||||
|
|
@ -505,6 +507,8 @@ void M_ChallengesTick(void)
|
|||
M_UpdateUnlockablesAndExtraEmblems(true, true);
|
||||
|
||||
// Update shown description just in case..?
|
||||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
||||
|
||||
challengesmenu.unlockcount[CC_TALLY]++;
|
||||
|
|
@ -787,6 +791,8 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
// After movement has been determined, figure out the current selection.
|
||||
i = (challengesmenu.col * CHALLENGEGRIDHEIGHT) + challengesmenu.row;
|
||||
challengesmenu.currentunlock = (gamedata->challengegrid[i]);
|
||||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
||||
|
||||
challengesmenu.hilix = challengesmenu.col;
|
||||
|
|
|
|||
|
|
@ -33,15 +33,14 @@ void M_StartMessage(const char *header, const char *string, void (*routine)(INT3
|
|||
const UINT8 pid = 0;
|
||||
static char *message = NULL;
|
||||
Z_Free(message);
|
||||
message = Z_StrDup(string);
|
||||
DEBFILE(message);
|
||||
DEBFILE(string);
|
||||
|
||||
V_ScaledWordWrap(
|
||||
message = V_ScaledWordWrap(
|
||||
BASEVIDWIDTH << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0,
|
||||
HU_FONT,
|
||||
message
|
||||
string
|
||||
);
|
||||
|
||||
strncpy(menumessage.message, string, MAXMENUMESSAGE);
|
||||
|
|
|
|||
111
src/v_video.cpp
111
src/v_video.cpp
|
|
@ -2610,14 +2610,14 @@ fixed_t V_StringScaledWidth(
|
|||
}
|
||||
|
||||
// Modify a string to wordwrap at any given width.
|
||||
void V_ScaledWordWrap(
|
||||
char * V_ScaledWordWrap(
|
||||
fixed_t w,
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
char *newstring)
|
||||
const char *s)
|
||||
{
|
||||
INT32 hchw;/* half-width for centering */
|
||||
|
||||
|
|
@ -2675,11 +2675,19 @@ void V_ScaledWordWrap(
|
|||
cx = 0;
|
||||
right = 0;
|
||||
|
||||
size_t i = 0, start = 0;
|
||||
size_t reader = 0, writer = 0, startwriter = 0;
|
||||
fixed_t cxatstart = 0;
|
||||
|
||||
for (; ( c = newstring[i] ); ++i)
|
||||
size_t len = strlen(s) + 1;
|
||||
size_t potentialnewlines = 8;
|
||||
size_t sparenewlines = potentialnewlines;
|
||||
|
||||
char *newstring = static_cast<char *>(Z_Malloc(len + sparenewlines, PU_STATIC, NULL));
|
||||
|
||||
for (; ( c = s[reader] ); ++reader, ++writer)
|
||||
{
|
||||
newstring[writer] = s[reader];
|
||||
|
||||
right = 0;
|
||||
|
||||
switch (c)
|
||||
|
|
@ -2687,58 +2695,83 @@ void V_ScaledWordWrap(
|
|||
case '\n':
|
||||
cx = 0;
|
||||
cxatstart = 0;
|
||||
start = 0;
|
||||
startwriter = 0;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0x80 ))
|
||||
continue;
|
||||
|
||||
if (uppercase)
|
||||
;
|
||||
else
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
else if (V_CharacterValid(font, c - font->start) == false)
|
||||
{
|
||||
// Try the other case if it doesn't exist
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
c = tolower(c);
|
||||
}
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
if (uppercase)
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
}
|
||||
else if (V_CharacterValid(font, c - font->start) == false)
|
||||
{
|
||||
// Try the other case if it doesn't exist
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
c = tolower(c);
|
||||
}
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
}
|
||||
|
||||
c -= font->start;
|
||||
if (V_CharacterValid(font, c) == true)
|
||||
{
|
||||
cw = SHORT (font->font[c]->width) * dupx;
|
||||
c -= font->start;
|
||||
if (V_CharacterValid(font, c) == true)
|
||||
{
|
||||
cw = SHORT (font->font[c]->width) * dupx;
|
||||
|
||||
// How bunched dims work is by incrementing cx slightly less than a full character width.
|
||||
// This causes the next character to be drawn overlapping the previous.
|
||||
// We need to count the full width to get the rightmost edge of the string though.
|
||||
right = cx + (cw * scale);
|
||||
// How bunched dims work is by incrementing cx slightly less than a full character width.
|
||||
// This causes the next character to be drawn overlapping the previous.
|
||||
// We need to count the full width to get the rightmost edge of the string though.
|
||||
right = cx + (cw * scale);
|
||||
|
||||
(*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
cx += cw;
|
||||
}
|
||||
else
|
||||
{
|
||||
cx += fontspec.spacew;
|
||||
cxatstart = cx;
|
||||
start = i;
|
||||
(*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
cx += cw;
|
||||
}
|
||||
else
|
||||
{
|
||||
cx += fontspec.spacew;
|
||||
cxatstart = cx;
|
||||
startwriter = writer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start trying to wrap if presumed length exceeds the space we have on-screen.
|
||||
if (start != 0 && right > w)
|
||||
if (right && right > w)
|
||||
{
|
||||
newstring[start] = '\n';
|
||||
cx -= cxatstart;
|
||||
start = 0;
|
||||
if (startwriter != 0)
|
||||
{
|
||||
newstring[startwriter] = '\n';
|
||||
cx -= cxatstart;
|
||||
cxatstart = 0;
|
||||
startwriter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sparenewlines == 0)
|
||||
{
|
||||
sparenewlines = (potentialnewlines *= 2);
|
||||
newstring = static_cast<char *>(Z_Realloc(newstring, len + sparenewlines, PU_STATIC, NULL));
|
||||
}
|
||||
|
||||
sparenewlines--;
|
||||
len++;
|
||||
|
||||
newstring[writer++] = '\n'; // Over-write previous
|
||||
cx = cw; // Valid value in the only case right is currently set
|
||||
newstring[writer] = s[reader]; // Re-add
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newstring[writer] = '\0';
|
||||
|
||||
return newstring;
|
||||
}
|
||||
|
||||
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
|
|
|
|||
|
|
@ -293,14 +293,14 @@ fixed_t V_StringScaledWidth(
|
|||
int fontno,
|
||||
const char *s);
|
||||
|
||||
void V_ScaledWordWrap(
|
||||
char * V_ScaledWordWrap(
|
||||
fixed_t w,
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
char *newstring);
|
||||
const char *s);
|
||||
|
||||
// draw a string using the hu_font
|
||||
#define V_DrawString( x,y,option,string ) \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue