mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-11 18:50:46 +00:00
Add qstrdim and screentext, powerful new functions for HUD text.
git-svn-id: https://svn.eduke32.com/eduke32@3833 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
4375a3c261
commit
ced47cf9fc
9 changed files with 1257 additions and 3 deletions
|
@ -594,6 +594,9 @@ static inline uint16_t system_15bit_rand(void) { return ((uint16_t)rand())&0x7ff
|
|||
# define Bstrtoul strtoul
|
||||
# define Bstrtod strtod
|
||||
# define Bstrstr strstr
|
||||
# define Bislower islower
|
||||
# define Bisupper isupper
|
||||
# define Bisdigit isdigit
|
||||
# define Btoupper toupper
|
||||
# define Btolower tolower
|
||||
# define Bmemcpy memcpy
|
||||
|
|
|
@ -335,6 +335,810 @@ void P_SetGamePalette(DukePlayer_t *player, uint8_t palid, int32_t set)
|
|||
setbrightness(ud.brightness>>2, palid, set);
|
||||
}
|
||||
|
||||
// get the string length until the next '\n'
|
||||
int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter)
|
||||
{
|
||||
int32_t length = 0;
|
||||
|
||||
while (*text != '\n' && text != end)
|
||||
{
|
||||
++length;
|
||||
|
||||
text += iter;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int32_t G_GetStringNumLines(const char *text, const char *end, const int32_t iter)
|
||||
{
|
||||
int32_t count = 1;
|
||||
|
||||
while (text != end)
|
||||
{
|
||||
if (*text == '\n')
|
||||
++count;
|
||||
text += iter;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
// Note: Neither of these care about TEXT_LINEWRAP. This is intended.
|
||||
|
||||
// This function requires you to Bfree() the returned char*.
|
||||
char* G_GetSubString(const char *text, const char *end, const int32_t iter, const int32_t length)
|
||||
{
|
||||
char *line = (char*)Bmalloc((length+1) * sizeof(char));
|
||||
int32_t counter = 0;
|
||||
|
||||
while (counter < length && text != end)
|
||||
{
|
||||
line[counter] = *text;
|
||||
|
||||
text += iter;
|
||||
++counter;
|
||||
}
|
||||
|
||||
line[++counter] = '\0';
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
// assign the character's tilenum
|
||||
int32_t G_GetStringTile(int32_t font, char *t, int32_t f)
|
||||
{
|
||||
if (f & TEXT_DIGITALNUMBER)
|
||||
return *t - '0' + font; // copied from digitalnumber
|
||||
else if (f & (TEXT_BIGALPHANUM|TEXT_GRAYFONT))
|
||||
{
|
||||
int32_t offset = (f & TEXT_GRAYFONT) ? 26 : 0;
|
||||
|
||||
if (*t >= '0' && *t <= '9')
|
||||
return *t - '0' + font + ((f & TEXT_GRAYFONT) ? 26 : -10);
|
||||
else if (*t >= 'a' && *t <= 'z')
|
||||
return *t - 'a' + font + ((f & TEXT_GRAYFONT) ? -26 : 26);
|
||||
else if (*t >= 'A' && *t <= 'Z')
|
||||
return *t - 'A' + font;
|
||||
else switch (*t)
|
||||
{
|
||||
case '_':
|
||||
case '-':
|
||||
return font - (11 + offset);
|
||||
break;
|
||||
case '.':
|
||||
return font + (BIGPERIOD - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case ',':
|
||||
return font + (BIGCOMMA - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case '!':
|
||||
return font + (BIGX_ - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case '?':
|
||||
return font + (BIGQ - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case ';':
|
||||
return font + (BIGSEMI - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case ':':
|
||||
return font + (BIGCOLIN - (BIGALPHANUM + offset));
|
||||
break;
|
||||
case '\\':
|
||||
case '/':
|
||||
return font + (68 - offset); // 3008-2940
|
||||
break;
|
||||
case '%':
|
||||
return font + (69 - offset); // 3009-2940
|
||||
break;
|
||||
case '`':
|
||||
case '\"': // could be better hacked in
|
||||
case '\'':
|
||||
return font + (BIGAPPOS - (BIGALPHANUM + offset));
|
||||
break;
|
||||
default: // unknown character
|
||||
*t = ' '; // whitespace-ize
|
||||
return font;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return *t - '!' + font; // uses ASCII order
|
||||
}
|
||||
|
||||
// qstrdim
|
||||
vec2_t G_ScreenTextSize(const int32_t font,
|
||||
int32_t x, int32_t y, const int32_t z, const int32_t blockangle,
|
||||
const char *str, const int32_t o,
|
||||
int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween,
|
||||
const int32_t f,
|
||||
int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
||||
{
|
||||
vec2_t size = { 0, 0, }; // eventually the return value
|
||||
vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string
|
||||
vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line
|
||||
vec2_t offset = { 0, 0, }; // temporary; holds the last movement made in both directions
|
||||
|
||||
int32_t tile;
|
||||
char t;
|
||||
|
||||
// set the start and end points depending on direction
|
||||
int32_t iter = (f & TEXT_BACKWARDS) ? -1 : 1; // iteration direction
|
||||
|
||||
const char *end;
|
||||
const char *text;
|
||||
|
||||
UNREFERENCED_PARAMETER(x1);
|
||||
UNREFERENCED_PARAMETER(y1);
|
||||
UNREFERENCED_PARAMETER(x2);
|
||||
UNREFERENCED_PARAMETER(y2);
|
||||
|
||||
if (str == NULL)
|
||||
return size;
|
||||
|
||||
end = (f & TEXT_BACKWARDS) ? str-1 : Bstrchr(str,'\0');
|
||||
text = (f & TEXT_BACKWARDS) ? Bstrchr(str,'\0')-1 : str;
|
||||
|
||||
// optimization: justification in both directions
|
||||
if ((f & TEXT_XJUSTIFY) && (f & TEXT_YJUSTIFY))
|
||||
{
|
||||
size.x = xbetween;
|
||||
size.y = ybetween;
|
||||
return size;
|
||||
}
|
||||
|
||||
// for best results, we promote 320x200 coordinates to full precision before any math
|
||||
if (!(o & ROTATESPRITE_FULL16))
|
||||
{
|
||||
x <<= 16;
|
||||
y <<= 16;
|
||||
xspace <<= 16;
|
||||
yline <<= 16;
|
||||
xbetween <<= 16;
|
||||
ybetween <<= 16;
|
||||
}
|
||||
// coordinate values should be shifted left by 16
|
||||
|
||||
// handle zooming where applicable
|
||||
xspace = scale(xspace, z, 65536);
|
||||
yline = scale(yline, z, 65536);
|
||||
xbetween = scale(xbetween, z, 65536);
|
||||
ybetween = scale(ybetween, z, 65536);
|
||||
// size/width/height/spacing/offset values should be multiplied or scaled by $z, zoom (since 100% is 65536, the same as 1<<16)
|
||||
|
||||
// loop through the string
|
||||
while ((t = *text) && text != end)
|
||||
{
|
||||
// handle escape sequences
|
||||
if (t == '^' && Bisdigit(*(text+iter)) && !(f & TEXT_LITERALESCAPE))
|
||||
{
|
||||
text += iter + iter;
|
||||
if (Bisdigit(*text))
|
||||
text += iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle case bits
|
||||
if (f & TEXT_UPPERCASE)
|
||||
{
|
||||
if (f & TEXT_INVERTCASE) // optimization...?
|
||||
{ // v^ important that these two ifs remain separate due to the else below
|
||||
if (Bisupper(t))
|
||||
t = Btolower(t);
|
||||
}
|
||||
else if (Bislower(t))
|
||||
t = Btoupper(t);
|
||||
}
|
||||
else if (f & TEXT_INVERTCASE)
|
||||
{
|
||||
if (Bisupper(t))
|
||||
t = Btolower(t);
|
||||
else if (Bislower(t))
|
||||
t = Btoupper(t);
|
||||
}
|
||||
|
||||
// translate the character to a tilenum
|
||||
tile = G_GetStringTile(font, &t, f);
|
||||
|
||||
// reset this here because we haven't printed anything yet this loop
|
||||
extent.x = 0;
|
||||
|
||||
// reset this here because the act of printing something on this line means that we include the margin above in the total size
|
||||
offset.y = 0;
|
||||
|
||||
// handle each character itself in the context of screen drawing
|
||||
switch (t)
|
||||
{
|
||||
case '\t':
|
||||
case ' ':
|
||||
// width
|
||||
extent.x = xspace;
|
||||
|
||||
if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE))
|
||||
{
|
||||
char space = '.'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILESPACE)
|
||||
space = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &space, f);
|
||||
|
||||
extent.x += (tilesizx[tile] * z);
|
||||
}
|
||||
|
||||
// prepare the height // near-CODEDUP the other two near-CODEDUPs for this section
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
if (t == '\t')
|
||||
extent.x <<= 2; // *= 4
|
||||
|
||||
break;
|
||||
|
||||
case '\n': // near-CODEDUP "if (wrap)"
|
||||
// save the position
|
||||
pos.x -= offset.x;
|
||||
SetIfGreater(&size.x, pos.x);
|
||||
|
||||
// reset the position
|
||||
pos.x = 0;
|
||||
|
||||
// prepare the height
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
// move down the line height
|
||||
if (!(f & TEXT_YOFFSETZERO))
|
||||
pos.y += extent.y;
|
||||
|
||||
// reset the current height
|
||||
extent.y = 0;
|
||||
|
||||
// line spacing
|
||||
offset.y = (f & TEXT_YJUSTIFY) ? 0 : ybetween; // ternary to prevent overflow
|
||||
pos.y += offset.y;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// width
|
||||
extent.x = tilesizx[tile] * z;
|
||||
|
||||
// obnoxious hardcoded functionality from gametext
|
||||
if ((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9')
|
||||
{
|
||||
char numeral = '0'; // this is subject to change as an implementation detail
|
||||
extent.x = (tilesizx[G_GetStringTile(font, &numeral, f)]-1) * z;
|
||||
}
|
||||
|
||||
// height
|
||||
SetIfGreater(&extent.y, (tilesizy[tile] * z));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// incrementing the coordinate counters
|
||||
offset.x = 0;
|
||||
|
||||
// advance the x coordinate
|
||||
if (!(f & TEXT_XOFFSETZERO))
|
||||
offset.x += extent.x;
|
||||
|
||||
// account for text spacing
|
||||
if (!((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9') // this "if" line ONLY == replicating hardcoded stuff
|
||||
&& !(f & TEXT_XJUSTIFY)) // to prevent overflow
|
||||
offset.x += xbetween;
|
||||
|
||||
// line wrapping
|
||||
if ((f & TEXT_LINEWRAP) && !(f & TEXT_XRIGHT) && !(f & TEXT_XCENTER) && blockangle % 512 == 0)
|
||||
{
|
||||
int32_t wrap = 0;
|
||||
const int32_t ang = blockangle % 2048;
|
||||
|
||||
// this is the only place in qstrdim where angle actually affects direction, but only in the wrapping measurement
|
||||
switch (ang)
|
||||
{
|
||||
case 0:
|
||||
wrap = (x + (pos.x + offset.x) > (320<<16)); // ((x2 - USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 512:
|
||||
wrap = (y + (pos.x + offset.x) > (200<<16)); // ((y2 - USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 1024:
|
||||
wrap = (x - (pos.x + offset.x) < 0); // ((x1 + USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 1536:
|
||||
wrap = (y - (pos.x + offset.x) < 0); // ((y1 + USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
}
|
||||
if (wrap) // near-CODEDUP "case '\n':"
|
||||
{
|
||||
// save the position
|
||||
SetIfGreater(&size.x, pos.x);
|
||||
|
||||
// reset the position
|
||||
pos.x = 0;
|
||||
|
||||
// prepare the height
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
// move down the line height
|
||||
if (!(f & TEXT_YOFFSETZERO))
|
||||
pos.y += extent.y;
|
||||
|
||||
// reset the current height
|
||||
extent.y = 0;
|
||||
|
||||
// line spacing
|
||||
offset.y = (f & TEXT_YJUSTIFY) ? 0 : ybetween; // ternary to prevent overflow
|
||||
pos.y += offset.y;
|
||||
}
|
||||
else
|
||||
pos.x += offset.x;
|
||||
}
|
||||
else
|
||||
pos.x += offset.x;
|
||||
|
||||
// save some trouble with calculation
|
||||
if (!(f & TEXT_XOFFSETZERO))
|
||||
offset.x -= extent.x;
|
||||
|
||||
// iterate to the next character in the string
|
||||
text += iter;
|
||||
}
|
||||
|
||||
// calculate final size
|
||||
pos.x -= offset.x;
|
||||
if (f & TEXT_XOFFSETZERO)
|
||||
pos.x += extent.x;
|
||||
pos.y -= offset.y;
|
||||
pos.y += extent.y;
|
||||
|
||||
SetIfGreater(&size.x, pos.x);
|
||||
SetIfGreater(&size.y, pos.y);
|
||||
|
||||
// justification where only one of the two directions is set, so we have to iterate
|
||||
if (f & TEXT_XJUSTIFY)
|
||||
size.x = xbetween;
|
||||
if (f & TEXT_YJUSTIFY)
|
||||
size.y = ybetween;
|
||||
|
||||
// return values in the same manner we receive them
|
||||
if (!(o & ROTATESPRITE_FULL16))
|
||||
{
|
||||
size.x >>= 16;
|
||||
size.y >>= 16;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, const int32_t magnitude)
|
||||
{
|
||||
coords->x += scale(magnitude, unitDirection->x, 16384);
|
||||
coords->y += scale(magnitude, unitDirection->y, 16384);
|
||||
}
|
||||
|
||||
// screentext
|
||||
vec2_t G_ScreenText(const int32_t font,
|
||||
int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const int32_t charangle,
|
||||
const char *str, const int32_t shade, int32_t pal, int32_t o, const int32_t alpha,
|
||||
int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f,
|
||||
const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2)
|
||||
{
|
||||
vec2_t size = { 0, 0, }; // eventually the return value
|
||||
vec2_t origin = { 0, 0, }; // where to start, depending on the alignment
|
||||
vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string
|
||||
vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line
|
||||
const vec2_t Xdirection = { sintable[(blockangle+512)&2047], sintable[blockangle&2047], };
|
||||
const vec2_t Ydirection = { sintable[(blockangle+1024)&2047], sintable[(blockangle+512)&2047], };
|
||||
|
||||
int32_t tile;
|
||||
char t;
|
||||
|
||||
// set the start and end points depending on direction
|
||||
int32_t iter = (f & TEXT_BACKWARDS) ? -1 : 1; // iteration direction
|
||||
|
||||
const char *end;
|
||||
const char *text;
|
||||
|
||||
if (str == NULL)
|
||||
return size;
|
||||
|
||||
end = (f & TEXT_BACKWARDS) ? str-1 : Bstrchr(str,'\0');
|
||||
text = (f & TEXT_BACKWARDS) ? Bstrchr(str,'\0')-1 : str;
|
||||
|
||||
// for best results, we promote 320x200 coordinates to full precision before any math
|
||||
if (!(o & ROTATESPRITE_FULL16))
|
||||
{
|
||||
x <<= 16;
|
||||
y <<= 16;
|
||||
xspace <<= 16;
|
||||
yline <<= 16;
|
||||
xbetween <<= 16;
|
||||
ybetween <<= 16;
|
||||
}
|
||||
// coordinate values should be shifted left by 16
|
||||
|
||||
// eliminate conflicts, necessary here to get the correct size value
|
||||
// especially given justification's special handling in G_ScreenTextSize()
|
||||
if ((f & TEXT_XRIGHT) || (f & TEXT_XCENTER) || (f & TEXT_XJUSTIFY) || (f & TEXT_YJUSTIFY) || blockangle % 512 != 0)
|
||||
o &= ~TEXT_LINEWRAP;
|
||||
|
||||
// size is the return value, and we need it for alignment
|
||||
size = G_ScreenTextSize(font, x, y, z, blockangle, str, o | ROTATESPRITE_FULL16, xspace, yline, (f & TEXT_XJUSTIFY) ? 0 : xbetween, (f & TEXT_YJUSTIFY) ? 0 : ybetween, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY), x1, y1, x2, y2);
|
||||
|
||||
// handle zooming where applicable
|
||||
xspace = scale(xspace, z, 65536);
|
||||
yline = scale(yline, z, 65536);
|
||||
xbetween = scale(xbetween, z, 65536);
|
||||
ybetween = scale(ybetween, z, 65536);
|
||||
// size/width/height/spacing/offset values should be multiplied or scaled by $z, zoom (since 100% is 65536, the same as 1<<16)
|
||||
|
||||
// alignment
|
||||
// near-CODEDUP "case '\n':"
|
||||
{
|
||||
int32_t lines = G_GetStringNumLines(text, end, iter);
|
||||
|
||||
if ((f & TEXT_XJUSTIFY) || (f & TEXT_XRIGHT) || (f & TEXT_XCENTER))
|
||||
{
|
||||
const int32_t length = G_GetStringLineLength(text, end, iter);
|
||||
|
||||
int32_t linewidth = size.x;
|
||||
|
||||
if (lines != 1)
|
||||
{
|
||||
char *line = G_GetSubString(text, end, iter, length);
|
||||
|
||||
linewidth = G_ScreenTextSize(font, x, y, z, blockangle, line, o | ROTATESPRITE_FULL16, xspace, yline, 0, 0, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY|TEXT_BACKWARDS), x1, y1, x2, y2).x;
|
||||
|
||||
Bfree(line);
|
||||
}
|
||||
|
||||
if (f & TEXT_XJUSTIFY)
|
||||
{
|
||||
size.x = xbetween;
|
||||
|
||||
xbetween = (length == 1) ? 0 : ((xbetween - linewidth) / (length - 1));
|
||||
|
||||
linewidth = size.x;
|
||||
}
|
||||
|
||||
if (f & TEXT_XRIGHT)
|
||||
origin.x = -linewidth;
|
||||
else if (f & TEXT_XCENTER)
|
||||
origin.x = -(linewidth / 2);
|
||||
}
|
||||
|
||||
if (f & TEXT_YJUSTIFY)
|
||||
{
|
||||
const int32_t tempswap = ybetween;
|
||||
ybetween = (lines == 1) ? 0 : ((ybetween - size.y) / (lines - 1));
|
||||
size.y = tempswap;
|
||||
}
|
||||
|
||||
if (f & TEXT_YBOTTOM)
|
||||
origin.y = -size.y;
|
||||
else if (f & TEXT_YCENTER)
|
||||
origin.y = -(size.y / 2);
|
||||
}
|
||||
|
||||
// loop through the string
|
||||
while ((t = *text) && text != end)
|
||||
{
|
||||
int32_t orientation = o;
|
||||
int32_t angle = blockangle + charangle;
|
||||
|
||||
// handle escape sequences
|
||||
if (t == '^' && Bisdigit(*(text+iter)) && !(f & TEXT_LITERALESCAPE))
|
||||
{
|
||||
char smallbuf[4];
|
||||
|
||||
text += iter;
|
||||
smallbuf[0] = *text;
|
||||
|
||||
text += iter;
|
||||
if (Bisdigit(*text))
|
||||
{
|
||||
smallbuf[1] = *text;
|
||||
smallbuf[2] = '\0';
|
||||
text += iter;
|
||||
}
|
||||
else
|
||||
smallbuf[1] = '\0';
|
||||
|
||||
if (!(f & TEXT_IGNOREESCAPE))
|
||||
pal = Batoi(smallbuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle case bits
|
||||
if (f & TEXT_UPPERCASE)
|
||||
{
|
||||
if (f & TEXT_INVERTCASE) // optimization...?
|
||||
{ // v^ important that these two ifs remain separate due to the else below
|
||||
if (Bisupper(t))
|
||||
t = Btolower(t);
|
||||
}
|
||||
else if (Bislower(t))
|
||||
t = Btoupper(t);
|
||||
}
|
||||
else if (f & TEXT_INVERTCASE)
|
||||
{
|
||||
if (Bisupper(t))
|
||||
t = Btolower(t);
|
||||
else if (Bislower(t))
|
||||
t = Btoupper(t);
|
||||
}
|
||||
|
||||
// translate the character to a tilenum
|
||||
tile = G_GetStringTile(font, &t, f);
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case '\t':
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\x7F':
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
vec2_t location = { x, y, };
|
||||
|
||||
G_AddCoordsFromRotation(&location, &Xdirection, origin.x);
|
||||
G_AddCoordsFromRotation(&location, &Ydirection, origin.y);
|
||||
|
||||
G_AddCoordsFromRotation(&location, &Xdirection, pos.x);
|
||||
G_AddCoordsFromRotation(&location, &Ydirection, pos.y);
|
||||
|
||||
rotatesprite_(location.x, location.y, z, angle, tile, shade, pal, 2|orientation, alpha, x1, y1, x2, y2);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// reset this here because we haven't printed anything yet this loop
|
||||
extent.x = 0;
|
||||
|
||||
// handle each character itself in the context of screen drawing
|
||||
switch (t)
|
||||
{
|
||||
case '\t':
|
||||
case ' ':
|
||||
// width
|
||||
extent.x = xspace;
|
||||
|
||||
if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE))
|
||||
{
|
||||
char space = '.'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILESPACE)
|
||||
space = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &space, f);
|
||||
|
||||
extent.x += (tilesizx[tile] * z);
|
||||
}
|
||||
|
||||
// prepare the height // near-CODEDUP the other two near-CODEDUPs for this section
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
if (t == '\t')
|
||||
extent.x <<= 2; // *= 4
|
||||
|
||||
break;
|
||||
|
||||
case '\n': // near-CODEDUP "if (wrap)"
|
||||
// reset the position
|
||||
pos.x = 0;
|
||||
|
||||
// prepare the height
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
// move down the line height
|
||||
if (!(f & TEXT_YOFFSETZERO))
|
||||
pos.y += extent.y;
|
||||
|
||||
// reset the current height
|
||||
extent.y = 0;
|
||||
|
||||
// line spacing
|
||||
pos.y += ybetween;
|
||||
|
||||
// near-CODEDUP "alignments"
|
||||
if ((f & TEXT_XJUSTIFY) || (f & TEXT_XRIGHT) || (f & TEXT_XCENTER))
|
||||
{
|
||||
const int32_t length = G_GetStringLineLength(text, end, iter);
|
||||
|
||||
char *line = G_GetSubString(text, end, iter, length);
|
||||
|
||||
int32_t linewidth = G_ScreenTextSize(font, x, y, z, blockangle, line, o | ROTATESPRITE_FULL16, xspace, yline, 0, 0, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY|TEXT_BACKWARDS), x1, y1, x2, y2).x;
|
||||
|
||||
Bfree(line);
|
||||
|
||||
if (f & TEXT_XJUSTIFY)
|
||||
{
|
||||
xbetween = (length == 1) ? 0 : ((xbetween - linewidth) / (length - 1));
|
||||
|
||||
linewidth = size.x;
|
||||
}
|
||||
|
||||
if (f & TEXT_XRIGHT)
|
||||
origin.x = -linewidth;
|
||||
else if (f & TEXT_XCENTER)
|
||||
origin.x = -(linewidth / 2);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// width
|
||||
extent.x = tilesizx[tile] * z;
|
||||
|
||||
// obnoxious hardcoded functionality from gametext
|
||||
if ((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9')
|
||||
{
|
||||
char numeral = '0'; // this is subject to change as an implementation detail
|
||||
extent.x = (tilesizx[G_GetStringTile(font, &numeral, f)]-1) * z;
|
||||
}
|
||||
|
||||
// height
|
||||
SetIfGreater(&extent.y, (tilesizy[tile] * z));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// incrementing the coordinate counters
|
||||
{
|
||||
int32_t xoffset = 0;
|
||||
|
||||
// advance the x coordinate
|
||||
if (!(f & TEXT_XOFFSETZERO))
|
||||
xoffset += extent.x;
|
||||
|
||||
// account for text spacing
|
||||
if (!((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9')) // this "if" line ONLY == replicating hardcoded stuff
|
||||
xoffset += xbetween;
|
||||
|
||||
// line wrapping
|
||||
if (f & TEXT_LINEWRAP)
|
||||
{
|
||||
int32_t wrap = 0;
|
||||
const int32_t ang = blockangle % 2048;
|
||||
|
||||
// it's safe to make some assumptions and not go through G_AddCoordsFromRotation() since we limit to four directions
|
||||
switch (ang)
|
||||
{
|
||||
case 0:
|
||||
wrap = (x + (pos.x + xoffset) > (320<<16)); // ((x2 - USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 512:
|
||||
wrap = (y + (pos.x + xoffset) > (200<<16)); // ((y2 - USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 1024:
|
||||
wrap = (x - (pos.x + xoffset) < 0); // ((x1 + USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
case 1536:
|
||||
wrap = (y - (pos.x + xoffset) < 0); // ((y1 + USERQUOTE_RIGHTOFFSET)<<16)
|
||||
break;
|
||||
}
|
||||
if (wrap) // near-CODEDUP "case '\n':"
|
||||
{
|
||||
// reset the position
|
||||
pos.x = 0;
|
||||
|
||||
// prepare the height
|
||||
{
|
||||
int32_t tempyextent = yline;
|
||||
|
||||
if (f & (TEXT_INTERNALLINE|TEXT_TILELINE))
|
||||
{
|
||||
char line = 'A'; // this is subject to change as an implementation detail
|
||||
if (f & TEXT_TILELINE)
|
||||
line = '\x7F'; // tile after '~'
|
||||
tile = G_GetStringTile(font, &line, f);
|
||||
|
||||
tempyextent += tilesizy[tile] * z;
|
||||
}
|
||||
|
||||
SetIfGreater(&extent.y, tempyextent);
|
||||
}
|
||||
|
||||
// move down the line height
|
||||
if (!(f & TEXT_YOFFSETZERO))
|
||||
pos.y += extent.y;
|
||||
|
||||
// reset the current height
|
||||
extent.y = 0;
|
||||
|
||||
// line spacing
|
||||
pos.y += ybetween;
|
||||
}
|
||||
else
|
||||
pos.x += xoffset;
|
||||
}
|
||||
else
|
||||
pos.x += xoffset;
|
||||
}
|
||||
|
||||
// iterate to the next character in the string
|
||||
text += iter;
|
||||
}
|
||||
|
||||
// return values in the same manner we receive them
|
||||
if (!(o & ROTATESPRITE_FULL16))
|
||||
{
|
||||
size.x >>= 16;
|
||||
size.y >>= 16;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// flags
|
||||
// 4: small font, wrap strings?
|
||||
|
|
|
@ -74,6 +74,31 @@ typedef enum basepal_ {
|
|||
BASEPALCOUNT
|
||||
} basepal_t;
|
||||
|
||||
enum ScreenTextFlags_t {
|
||||
TEXT_XRIGHT = 0x00000001,
|
||||
TEXT_XCENTER = 0x00000002,
|
||||
TEXT_YBOTTOM = 0x00000004,
|
||||
TEXT_YCENTER = 0x00000008,
|
||||
TEXT_INTERNALSPACE = 0x00000010,
|
||||
TEXT_TILESPACE = 0x00000020,
|
||||
TEXT_INTERNALLINE = 0x00000040,
|
||||
TEXT_TILELINE = 0x00000080,
|
||||
TEXT_XOFFSETZERO = 0x00000100,
|
||||
TEXT_XJUSTIFY = 0x00000200,
|
||||
TEXT_YOFFSETZERO = 0x00000400,
|
||||
TEXT_YJUSTIFY = 0x00000800,
|
||||
TEXT_LINEWRAP = 0x00001000,
|
||||
TEXT_UPPERCASE = 0x00002000,
|
||||
TEXT_INVERTCASE = 0x00004000,
|
||||
TEXT_IGNOREESCAPE = 0x00008000,
|
||||
TEXT_LITERALESCAPE = 0x00010000,
|
||||
TEXT_BACKWARDS = 0x00020000,
|
||||
TEXT_GAMETEXTNUMHACK = 0x00040000,
|
||||
TEXT_DIGITALNUMBER = 0x00080000,
|
||||
TEXT_BIGALPHANUM = 0x00100000,
|
||||
TEXT_GRAYFONT = 0x00200000,
|
||||
};
|
||||
|
||||
void A_DeleteSprite(int32_t s);
|
||||
|
||||
static inline int32_t G_GetLogoFlags(void)
|
||||
|
@ -336,6 +361,15 @@ void M32RunScript(const char *s);
|
|||
void P_DoQuote(int32_t q,DukePlayer_t *p);
|
||||
extern int32_t textsc(int32_t sc);
|
||||
void P_SetGamePalette(DukePlayer_t *player,uint8_t palid,int32_t set);
|
||||
|
||||
extern int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter);
|
||||
extern int32_t G_GetStringNumLines(const char *text, const char *end, const int32_t iter);
|
||||
extern char* G_GetSubString(const char *text, const char *end, const int32_t iter, const int32_t length);
|
||||
extern int32_t G_GetStringTile(int32_t font, char *t, int32_t f);
|
||||
extern vec2_t G_ScreenTextSize(const int32_t font, int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const char *str, const int32_t o, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2);
|
||||
extern void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, const int32_t magnitude);
|
||||
extern vec2_t G_ScreenText(const int32_t font, int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const int32_t charangle, const char *str, const int32_t shade, int32_t pal, int32_t o, const int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
||||
|
||||
int32_t app_main(int32_t argc,const char **argv);
|
||||
void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step);
|
||||
//void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile);
|
||||
|
|
|
@ -35,4 +35,12 @@ EXTERN_INLINE void G_SetStatusBarScale(int32_t sc)
|
|||
G_UpdateScreenArea();
|
||||
}
|
||||
|
||||
// the point of this is to prevent re-running a function or calculation passed to potentialValue
|
||||
// without making a new variable under each individual circumstance
|
||||
EXTERN_INLINE void SetIfGreater(int32_t *variable, int32_t potentialValue)
|
||||
{
|
||||
if (potentialValue > *variable)
|
||||
*variable = potentialValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
EXTERN_INLINE_HEADER void G_SetStatusBarScale(int32_t sc);
|
||||
|
||||
EXTERN_INLINE_HEADER void SetIfGreater(int32_t *variable, int32_t potentialValue);
|
||||
|
||||
#ifndef DISABLE_INLINING
|
||||
#include "game_inline.c"
|
||||
#endif
|
||||
|
|
|
@ -91,10 +91,8 @@ static struct { uint32_t keyw; uint32_t date; } g_keywdate[] =
|
|||
{ CON_ECHO, 20120304 },
|
||||
{ CON_SHOWVIEWUNBIASED, 20120331 },
|
||||
{ CON_ROTATESPRITEA, 20130324 },
|
||||
{ CON_SHADETO, 20130522 },
|
||||
{ CON_ENDOFLEVEL, 20130522 },
|
||||
{ CON_IFPLAYERSL, 20130522 },
|
||||
{ CON_ACTIVATE, 20130522 },
|
||||
{ CON_SCREENTEXT, 20130529 },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -589,6 +587,8 @@ const char *keyw[] =
|
|||
"endoflevel", // 366
|
||||
"ifplayersl", // 367
|
||||
"activate", // 368
|
||||
"qstrdim", // 369
|
||||
"screentext", // 370
|
||||
"<null>"
|
||||
};
|
||||
#endif
|
||||
|
@ -4754,6 +4754,7 @@ static int32_t C_ParseCommand(int32_t loop)
|
|||
case CON_GAMETEXTZ:
|
||||
case CON_DIGITALNUMBER:
|
||||
case CON_DIGITALNUMBERZ:
|
||||
case CON_SCREENTEXT:
|
||||
if (g_parsingEventPtr == NULL && g_processingState == 0)
|
||||
{
|
||||
C_ReportError(ERROR_EVENTONLY);
|
||||
|
@ -4762,6 +4763,8 @@ static int32_t C_ParseCommand(int32_t loop)
|
|||
|
||||
switch (tw)
|
||||
{
|
||||
case CON_SCREENTEXT:
|
||||
C_GetManyVars(8);
|
||||
case CON_GAMETEXTZ:
|
||||
case CON_DIGITALNUMBERZ:
|
||||
C_GetManyVars(1);
|
||||
|
@ -5052,6 +5055,11 @@ repeatcase:
|
|||
C_GetNextVarType(GAMEVAR_READONLY);
|
||||
C_GetNextVar();
|
||||
continue;
|
||||
case CON_QSTRDIM:
|
||||
C_GetNextVarType(GAMEVAR_READONLY);
|
||||
C_GetNextVarType(GAMEVAR_READONLY);
|
||||
C_GetManyVars(16);
|
||||
continue;
|
||||
case CON_HEADSPRITESTAT:
|
||||
case CON_PREVSPRITESTAT:
|
||||
case CON_NEXTSPRITESTAT:
|
||||
|
|
|
@ -941,6 +941,8 @@ enum ScriptKeywords_t
|
|||
CON_ENDOFLEVEL, // 366
|
||||
CON_IFPLAYERSL, // 367
|
||||
CON_ACTIVATE, // 368
|
||||
CON_QSTRDIM, // 369
|
||||
CON_SCREENTEXT, // 370
|
||||
CON_END
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1809,6 +1809,41 @@ skip_check:
|
|||
continue;
|
||||
}
|
||||
|
||||
case CON_QSTRDIM:
|
||||
insptr++;
|
||||
{
|
||||
vec2_t dim = { 0, 0, };
|
||||
|
||||
int32_t w=*insptr++;
|
||||
int32_t h=*insptr++;
|
||||
|
||||
int32_t tilenum = Gv_GetVarX(*insptr++);
|
||||
int32_t x=Gv_GetVarX(*insptr++), y=Gv_GetVarX(*insptr++), z = Gv_GetVarX(*insptr++);
|
||||
int32_t blockangle=Gv_GetVarX(*insptr++);
|
||||
int32_t q=Gv_GetVarX(*insptr++);
|
||||
int32_t orientation=Gv_GetVarX(*insptr++);
|
||||
int32_t xspace=Gv_GetVarX(*insptr++), yline=Gv_GetVarX(*insptr++);
|
||||
int32_t xbetween=Gv_GetVarX(*insptr++), ybetween=Gv_GetVarX(*insptr++);
|
||||
int32_t f=Gv_GetVarX(*insptr++);
|
||||
int32_t x1=Gv_GetVarX(*insptr++), y1=Gv_GetVarX(*insptr++);
|
||||
int32_t x2=Gv_GetVarX(*insptr++), y2=Gv_GetVarX(*insptr++);
|
||||
|
||||
orientation &= (ROTATESPRITE_MAX-1);
|
||||
|
||||
if (tilenum < 0 || tilenum+255 >= MAXTILES)
|
||||
CON_ERRPRINTF("invalid base tilenum %d\n", tilenum);
|
||||
else if ((unsigned)q >= MAXQUOTES)
|
||||
CON_ERRPRINTF("invalid quote ID %d\n", q);
|
||||
else if ((ScriptQuotes[q] == NULL))
|
||||
CON_ERRPRINTF("null quote %d\n", q);
|
||||
else
|
||||
dim = G_ScreenTextSize(tilenum,x,y,z,blockangle,ScriptQuotes[q],orientation,xspace,yline,xbetween,ybetween,f,x1,y1,x2,y2);
|
||||
|
||||
Gv_SetVarX(w,dim.x);
|
||||
Gv_SetVarX(h,dim.y);
|
||||
continue;
|
||||
}
|
||||
|
||||
case CON_HEADSPRITESTAT:
|
||||
insptr++;
|
||||
{
|
||||
|
@ -2760,6 +2795,46 @@ nullquote:
|
|||
continue;
|
||||
}
|
||||
|
||||
case CON_SCREENTEXT:
|
||||
insptr++;
|
||||
{
|
||||
int32_t tilenum = Gv_GetVarX(*insptr++);
|
||||
int32_t x=Gv_GetVarX(*insptr++), y=Gv_GetVarX(*insptr++), z = Gv_GetVarX(*insptr++);
|
||||
int32_t blockangle=Gv_GetVarX(*insptr++), charangle=Gv_GetVarX(*insptr++);
|
||||
int32_t q=Gv_GetVarX(*insptr++);
|
||||
int32_t shade=Gv_GetVarX(*insptr++), pal=Gv_GetVarX(*insptr++);
|
||||
int32_t orientation=Gv_GetVarX(*insptr++);
|
||||
int32_t alpha=Gv_GetVarX(*insptr++);
|
||||
int32_t xspace=Gv_GetVarX(*insptr++), yline=Gv_GetVarX(*insptr++);
|
||||
int32_t xbetween=Gv_GetVarX(*insptr++), ybetween=Gv_GetVarX(*insptr++);
|
||||
int32_t f=Gv_GetVarX(*insptr++);
|
||||
int32_t x1=Gv_GetVarX(*insptr++), y1=Gv_GetVarX(*insptr++);
|
||||
int32_t x2=Gv_GetVarX(*insptr++), y2=Gv_GetVarX(*insptr++);
|
||||
|
||||
if (tilenum < 0 || tilenum+255 >= MAXTILES)
|
||||
{
|
||||
CON_ERRPRINTF("invalid base tilenum %d\n", tilenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((unsigned)q >= MAXQUOTES)
|
||||
{
|
||||
CON_ERRPRINTF("invalid quote ID %d\n", q);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ScriptQuotes[q] == NULL))
|
||||
{
|
||||
CON_ERRPRINTF("null quote %d\n", q);
|
||||
continue;
|
||||
}
|
||||
|
||||
orientation &= (ROTATESPRITE_MAX-1);
|
||||
|
||||
G_ScreenText(tilenum,x,y,z,blockangle,charangle,ScriptQuotes[q],shade,pal,orientation,alpha,xspace,yline,xbetween,ybetween,f,x1,y1,x2,y2);
|
||||
continue;
|
||||
}
|
||||
|
||||
case CON_ANGOFF:
|
||||
insptr++;
|
||||
spriteext[vm.g_i].angoff=*insptr++;
|
||||
|
|
318
polymer/eduke32/source/lunatic/test/screentext.con
Normal file
318
polymer/eduke32/source/lunatic/test/screentext.con
Normal file
|
@ -0,0 +1,318 @@
|
|||
// ScreenText Test
|
||||
|
||||
/*
|
||||
This is half a test and half a demonstration.
|
||||
For example, some of the spacing and offset stuff could be replaced with tests of other things, like the backwards bit, line wrapping, and space lengths.
|
||||
Also, if/when Lunatic adds support for \n characters.
|
||||
*/
|
||||
|
||||
definequote 999
|
||||
|
||||
definequote 1000 AbCdEfGhIjKlM
|
||||
definequote 1001 nOpQrStUvWxYz
|
||||
|
||||
definequote 1010 X1234567890-.!?;:'\ / %
|
||||
|
||||
definequote 1020 ^2R^8G^1B^7Y
|
||||
|
||||
definequote 1337 1337
|
||||
|
||||
definequote 2000 Left
|
||||
definequote 2001 Center
|
||||
definequote 2002 Right
|
||||
|
||||
definequote 2003 Top
|
||||
definequote 2004 Center
|
||||
definequote 2005 Bottom
|
||||
|
||||
definequote 3000 Spacing
|
||||
definequote 3001 X-Offset
|
||||
definequote 3002 %d: UiUiUiUiUi
|
||||
definequote 3003 Justification
|
||||
|
||||
definequote 4000 Normal: aBcDeF
|
||||
definequote 4001 Upper: aBcDeF
|
||||
definequote 4002 Lower: aBcDeF
|
||||
definequote 4003 Inverted: aBcDeF
|
||||
|
||||
definequote 5000 Rotate
|
||||
definequote 5001 Top, Left:
|
||||
definequote 5002 Center, Center:
|
||||
definequote 5003 Bottom, Right:
|
||||
|
||||
gamevar font STARTALPHANUM 0
|
||||
gamevar x 0 0
|
||||
gamevar y 0 0
|
||||
gamevar z 65536 0
|
||||
gamevar blockangle 0 0
|
||||
gamevar charangle 0 0
|
||||
gamevar q 1000 0
|
||||
gamevar shade 0 0
|
||||
gamevar pal 0 0
|
||||
gamevar o 16 0
|
||||
gamevar alpha 0 0
|
||||
gamevar xspace 5 0
|
||||
gamevar yline 8 0
|
||||
gamevar xbetween 0 0
|
||||
gamevar ybetween 0 0
|
||||
gamevar f 0 0
|
||||
gamevar x1 0 0
|
||||
gamevar y1 0 0
|
||||
gamevar x2 0 0
|
||||
gamevar y2 0 0
|
||||
|
||||
gamevar temp 0 0
|
||||
|
||||
state resetbounds
|
||||
setvarvar x1 windowx1
|
||||
setvarvar y1 windowy1
|
||||
setvarvar x2 windowx2
|
||||
setvarvar y2 windowy2
|
||||
ends
|
||||
|
||||
onevent EVENT_ENTERLEVEL
|
||||
state resetbounds
|
||||
endevent
|
||||
|
||||
define TEXT_XRIGHT 0x00000001
|
||||
define TEXT_XCENTER 0x00000002
|
||||
define TEXT_YBOTTOM 0x00000004
|
||||
define TEXT_YCENTER 0x00000008
|
||||
define TEXT_INTERNALSPACE 0x00000010
|
||||
define TEXT_TILESPACE 0x00000020
|
||||
define TEXT_INTERNALLINE 0x00000040
|
||||
define TEXT_TILELINE 0x00000080
|
||||
define TEXT_XOFFSETZERO 0x00000100
|
||||
define TEXT_XJUSTIFY 0x00000200
|
||||
define TEXT_YOFFSETZERO 0x00000400
|
||||
define TEXT_YJUSTIFY 0x00000800
|
||||
define TEXT_LINEWRAP 0x00001000
|
||||
define TEXT_UPPERCASE 0x00002000
|
||||
define TEXT_INVERTCASE 0x00004000
|
||||
define TEXT_IGNOREESCAPE 0x00008000
|
||||
define TEXT_LITERALESCAPE 0x00010000
|
||||
define TEXT_BACKWARDS 0x00020000
|
||||
define TEXT_GAMETEXTNUMHACK 0x00040000
|
||||
define TEXT_DIGITALNUMBER 0x00080000
|
||||
define TEXT_BIGALPHANUM 0x00100000
|
||||
define TEXT_GRAYFONT 0x00200000
|
||||
|
||||
state increment_line
|
||||
ifvarg q 0
|
||||
screentext font x y z blockangle charangle q shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar y 8
|
||||
ends
|
||||
|
||||
state increment_line_test
|
||||
ifvarg q 0
|
||||
{
|
||||
qsprintf 999 q temp
|
||||
screentext font x y z blockangle charangle 999 shade pal o alpha xspace yline temp ybetween f x1 y1 x2 y2
|
||||
}
|
||||
addvar temp 1
|
||||
addvar y 8
|
||||
ends
|
||||
|
||||
onevent EVENT_DISPLAYREST
|
||||
state resetbounds
|
||||
|
||||
// screentext font x y z blockangle charangle q shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
// spacing
|
||||
setvar f 0
|
||||
setvar x 35
|
||||
setvar y 3
|
||||
setvar pal 0
|
||||
|
||||
setvar temp 0
|
||||
setvar q 3000
|
||||
state increment_line_test
|
||||
|
||||
setvar temp -3
|
||||
setvar q 3002
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
|
||||
// justification
|
||||
setvar f 0
|
||||
orvar f TEXT_XCENTER
|
||||
orvar f TEXT_XJUSTIFY
|
||||
screentext font 160 y z blockangle charangle 3003 shade 12 o alpha xspace yline 320 ybetween f x1 y1 x2 y2
|
||||
addvar y 8
|
||||
setvar f 0
|
||||
|
||||
// x-offset
|
||||
setvar temp 0
|
||||
setvar q 3001
|
||||
state increment_line_test
|
||||
|
||||
orvar f TEXT_XOFFSETZERO
|
||||
setvar temp 5
|
||||
setvar q 3002
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
state increment_line_test
|
||||
|
||||
addvar y 4
|
||||
|
||||
// case
|
||||
setvar f 0
|
||||
setvar q 4000
|
||||
setvar pal 23
|
||||
state increment_line
|
||||
setvar q 4001
|
||||
orvar f TEXT_UPPERCASE
|
||||
state increment_line
|
||||
setvar q 4002
|
||||
orvar f TEXT_INVERTCASE
|
||||
state increment_line
|
||||
setvar q 4003
|
||||
xorvar f TEXT_UPPERCASE
|
||||
state increment_line
|
||||
|
||||
// divider line
|
||||
rotatespritea 240 65 32768 512 WINDOWBORDER1 0 2 0 85 x1 y1 x2 y2
|
||||
|
||||
setvar pal 12
|
||||
|
||||
// x-alignment
|
||||
setvar f 0
|
||||
setvar x 220
|
||||
screentext font x 127 z blockangle charangle 2000 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
orvar f TEXT_XCENTER
|
||||
screentext font x 137 z blockangle charangle 2001 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
xorvar f TEXT_XCENTER
|
||||
orvar f TEXT_XRIGHT
|
||||
screentext font x 147 z blockangle charangle 2002 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
rotatespritea x 132 32768 0 WINDOWBORDER2 127 0 0 85 x1 y1 x2 y2
|
||||
|
||||
// y-alignment
|
||||
setvar f TEXT_UPPERCASE
|
||||
screentext font 180 162 z blockangle charangle 2003 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
orvar f TEXT_YCENTER
|
||||
screentext font 208 162 z blockangle charangle 2004 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
xorvar f TEXT_YCENTER
|
||||
orvar f TEXT_YBOTTOM
|
||||
screentext font 260 162 z blockangle charangle 2005 shade pal o alpha xspace yline 0 ybetween f x1 y1 x2 y2
|
||||
rotatespritea 240 163 32768 512 WINDOWBORDER1 127 0 0 85 x1 y1 x2 y2
|
||||
|
||||
setvar pal 0
|
||||
|
||||
// bluefont vs. redfont XOFFSETZERO comparison
|
||||
setvar f 0
|
||||
orvar f TEXT_XOFFSETZERO
|
||||
screentext font 0 175 65536 blockangle charangle 1010 shade pal o alpha xspace yline 13 ybetween f x1 y1 x2 y2
|
||||
orvar f TEXT_BIGALPHANUM
|
||||
orvar f TEXT_YBOTTOM
|
||||
screentext BIGALPHANUM 0 200 z blockangle charangle 1010 shade pal o alpha xspace yline 13 ybetween f x1 y1 x2 y2
|
||||
|
||||
// block rotation
|
||||
setvar y 2
|
||||
screentext MINIFONT 170 y z blockangle charangle 5001 shade 10 o alpha 2 yline 1 ybetween 0 x1 y1 x2 y2
|
||||
screentext MINIFONT 237 y z blockangle charangle 5002 shade 14 o alpha 2 yline 1 ybetween TEXT_XCENTER x1 y1 x2 y2
|
||||
screentext MINIFONT 317 y z blockangle charangle 5003 shade 16 o alpha 2 yline 1 ybetween TEXT_XRIGHT x1 y1 x2 y2
|
||||
|
||||
setvar f 0
|
||||
setvar x 175
|
||||
setvar y 12
|
||||
setvar pal 10
|
||||
setvar blockangle 0
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
setvar blockangle -256
|
||||
setvar x 245
|
||||
setvar y 40
|
||||
setvar f 0
|
||||
setvar pal 14
|
||||
orvar f TEXT_XCENTER
|
||||
orvar f TEXT_YCENTER
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
setvar blockangle -512
|
||||
setvar x 317
|
||||
setvar y 19
|
||||
setvar f 0
|
||||
setvar pal 16
|
||||
orvar f TEXT_XRIGHT
|
||||
orvar f TEXT_YBOTTOM
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar blockangle 128
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
setvar pal 15
|
||||
|
||||
// character rotation
|
||||
setvar blockangle 0
|
||||
setvar charangle 256
|
||||
setvar f 0
|
||||
setvar x 175
|
||||
setvar y 78
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar charangle 256
|
||||
addvar y 13
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar charangle 256
|
||||
addvar y 13
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
addvar charangle 256
|
||||
addvar y 13
|
||||
screentext font x y z blockangle charangle 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
setvar charangle 0
|
||||
|
||||
setvar x 225
|
||||
setvar y 78
|
||||
screentext font x y z 128 -128 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z 256 -256 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z 384 -384 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z 512 -512 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
setvar x 312
|
||||
setvar y 90
|
||||
orvar f TEXT_XRIGHT
|
||||
orvar f TEXT_YCENTER
|
||||
screentext font x y z -128 128 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z -256 256 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z -384 384 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
screentext font x y z -512 512 5000 shade pal o alpha xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
|
||||
// alpha, sideways, and escape colors
|
||||
setvar pal 13
|
||||
setvar blockangle 0
|
||||
setvar f 0
|
||||
orvar f TEXT_XCENTER
|
||||
screentext font 0 100 z 1536 charangle 1020 shade pal o 0 xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
orvar f TEXT_IGNOREESCAPE
|
||||
screentext font 10 100 z 1536 charangle 1020 shade pal o 85 xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
orvar f TEXT_LITERALESCAPE
|
||||
screentext font 20 100 z 1536 charangle 1020 shade pal o 170 xspace yline xbetween ybetween f x1 y1 x2 y2
|
||||
endevent
|
Loading…
Reference in a new issue