- consolidation of screentext code

This commit is contained in:
Christoph Oelckers 2020-03-05 00:58:38 +01:00
parent b88eeea9a2
commit f59bfa1224
23 changed files with 964 additions and 2642 deletions

View file

@ -705,6 +705,7 @@ set (PCH_SOURCES
common/2d/v_draw.cpp common/2d/v_draw.cpp
common/2d/v_drawtext.cpp common/2d/v_drawtext.cpp
common/2d/renderstyle.cpp common/2d/renderstyle.cpp
common/2d/screentext.cpp
common/fonts/font.cpp common/fonts/font.cpp
common/fonts/hexfont.cpp common/fonts/hexfont.cpp

View file

@ -63,7 +63,7 @@ set( PCH_SOURCES
src/replace.cpp src/replace.cpp
src/resource.cpp src/resource.cpp
src/screen.cpp src/screen.cpp
src/screentext.cpp src/text.cpp
src/sectorfx.cpp src/sectorfx.cpp
src/seq.cpp src/seq.cpp
src/sfx.cpp src/sfx.cpp

View file

@ -99,6 +99,7 @@ struct GameInterface : ::GameInterface
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override; void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override;
void QuitToTitle() override; void QuitToTitle() override;
FString GetCoordString() override; FString GetCoordString() override;
int GetStringTile(int font, const char* t, int f) override;
GameStats getStats() override; GameStats getStats() override;
}; };

View file

@ -478,10 +478,6 @@ enum searchpathtypes_t {
SEARCHPATH_REMOVE = 1<<0, SEARCHPATH_REMOVE = 1<<0,
}; };
#define NEG_ALPHA_TO_BLEND(alpha, blend, orientation) do { \
if (alpha < 0) { blend = -alpha; alpha = 0; orientation |= RS_TRANS1; } \
} while (0)
extern int loaddefinitions_game(const char *fn, int32_t preload); extern int loaddefinitions_game(const char *fn, int32_t preload);
extern void G_ExtInit(void); extern void G_ExtInit(void);

View file

@ -1,96 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_BLD_NS
#define USERQUOTE_LEFTOFFSET 5
#define USERQUOTE_RIGHTOFFSET 14
extern int32_t minitext_lowercase;
extern int32_t minitext_yofs;
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,
};
//extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
//extern void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f);
//extern void captionmenutext(int32_t x, int32_t y, char const *t);
//extern vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f);
//extern void gametext_simple(int32_t x, int32_t y, const char *t);
//#define mpgametext_x (5<<16)
//extern vec2_t mpgametext(int32_t x, int32_t y, char const * t, int32_t s, int32_t o, int32_t a, int32_t f);
//extern vec2_t mpgametextsize(char const * t, int32_t f);
//extern int32_t textsc(int32_t sc);
//
//#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
//#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
//#define menutext(x, y, t) menutext_((x), (y), 0, (t), 10|16, 0)
//#define menutext_centeralign(x, y, t) menutext_((x), (y), 0, (t), 10|16, TEXT_XCENTER|TEXT_YCENTER)
//#define menutext_center(y, t) menutext_(160<<16, (y)<<16, 0, (t), 10|16, TEXT_XCENTER)
//#define gametext(x, y, t) gametext_simple((x)<<16, (y)<<16, (t))
//#define gametext_widenumber(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 1024, 0, TEXT_GAMETEXTNUMHACK)
//#define gametext_number(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_GAMETEXTNUMHACK)
//#define gametext_pal(x, y, t, p) gametext_((x)<<16, (y)<<16, (t), 0, (p), 0, 0, 0)
//#define gametext_center(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
//#define gametext_center_number(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER|TEXT_GAMETEXTNUMHACK)
//#define gametext_center_shade(y, t, s) gametext_(160<<16, (y)<<16, (t), (s), MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
//#define gametext_center_shade_pal(y, t, s, p) gametext_(160<<16, (y)<<16, (t), (s), (p), 0, 0, TEXT_XCENTER)
//
//extern void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
// int32_t s, int32_t p, int32_t o,
// int32_t x1, int32_t y1, int32_t x2, int32_t y2,
// int32_t z, int32_t a);
//
extern int32_t G_GetStringLineLength(const char *text, const char *end, int32_t iter);
extern int32_t G_GetStringNumLines(const char *text, const char *end, int32_t iter);
extern char* G_GetSubString(const char *text, const char *end, int32_t iter, int32_t length);
extern int32_t G_GetStringTile(int32_t font, char *t, int32_t f);
extern vec2_t G_ScreenTextSize(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, const char *str, int32_t o, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, int32_t magnitude);
extern vec2_t G_ScreenText(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
END_BLD_NS

44
source/blood/src/text.cpp Normal file
View file

@ -0,0 +1,44 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "compat.h"
#include "blood.h"
#include "common_game.h"
#include "screentext.h"
BEGIN_BLD_NS
// assign the character's tilenum
int GameInterface::GetStringTile(int font, const char *t, int f)
{
if (f & TEXT_DIGITALNUMBER)
return *t - '0' + font; // copied from digitalnumber
else
return *t - ' ' + font; // uses ASCII order
}
END_BLD_NS

33
source/blood/src/text.h Normal file
View file

@ -0,0 +1,33 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
#include "screentext.h"
BEGIN_BLD_NS
extern int32_t minitext_lowercase;
extern int32_t minitext_yofs;
END_BLD_NS

View file

@ -138,6 +138,7 @@ struct GameInterface
virtual void QuitToTitle() {} virtual void QuitToTitle() {}
virtual void SetAmbience(bool on) {} virtual void SetAmbience(bool on) {}
virtual FString GetCoordString() { return "'stat coord' not implemented"; } virtual FString GetCoordString() { return "'stat coord' not implemented"; }
virtual int GetStringTile(int font, const char* t, int f) { return -1; }
}; };

View file

@ -358,6 +358,10 @@ typedef struct {
#define SPREXT_TSPRACCESS 16 #define SPREXT_TSPRACCESS 16
#define SPREXT_TEMPINVISIBLE 32 #define SPREXT_TEMPINVISIBLE 32
#define NEG_ALPHA_TO_BLEND(alpha, blend, orientation) do { \
if ((alpha) < 0) { (blend) = -(alpha); (alpha) = 0; (orientation) |= RS_TRANS1; } \
} while (0)
// using the clipdist field // using the clipdist field
enum enum
{ {

View file

@ -1,8 +1,9 @@
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/* /*
Copyright (C) 2016 EDuke32 developers and contributors Copyright (C) 2016 EDuke32 developers and contributors
Copyright (C) 2019 Christoph Oelckers
This file is part of EDuke32. This file is part of Raze.
EDuke32 is free software; you can redistribute it and/or EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2 modify it under the terms of the GNU General Public License version 2
@ -18,15 +19,16 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "compat.h"
#include "blood.h"
#include "common_game.h"
#include "screentext.h" #include "screentext.h"
#include "build.h"
BEGIN_BLD_NS static inline void SetIfGreater(int32_t *variable, int32_t potentialValue)
{
if (potentialValue > *variable)
*variable = potentialValue;
}
// get the string length until the next '\n' // get the string length until the next '\n'
int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter) int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter)
@ -77,17 +79,11 @@ char* G_GetSubString(const char *text, const char *end, const int32_t iter, cons
return line; 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
return *t - ' ' + font; // uses ASCII order
}
#define NUMHACKACTIVE ((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9') #define NUMHACKACTIVE ((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9')
#define USERQUOTE_RIGHTOFFSET 14
// qstrdim // qstrdim
vec2_t G_ScreenTextSize(const int32_t font, vec2_t G_ScreenTextSize(const int32_t font,
int32_t x, int32_t y, const int32_t z, const int32_t blockangle, int32_t x, int32_t y, const int32_t z, const int32_t blockangle,
@ -175,7 +171,7 @@ vec2_t G_ScreenTextSize(const int32_t font,
} }
// translate the character to a tilenum // translate the character to a tilenum
tile = G_GetStringTile(font, &t, f); tile = gi->GetStringTile(font, &t, f);
// reset this here because we haven't printed anything yet this loop // reset this here because we haven't printed anything yet this loop
extent.x = 0; extent.x = 0;
@ -193,10 +189,10 @@ vec2_t G_ScreenTextSize(const int32_t font,
if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE)) if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE))
{ {
char space = ' '; // this is subject to change as an implementation detail char space = '.'; // this is subject to change as an implementation detail
if (f & TEXT_TILESPACE) if (f & TEXT_TILESPACE)
space = '\x7F'; // tile after '~' space = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &space, f); tile = gi->GetStringTile(font, &space, f);
extent.x += (tilesiz[tile].x * z); extent.x += (tilesiz[tile].x * z);
} }
@ -210,7 +206,7 @@ vec2_t G_ScreenTextSize(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -243,7 +239,7 @@ vec2_t G_ScreenTextSize(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -268,11 +264,10 @@ vec2_t G_ScreenTextSize(const int32_t font,
// width // width
extent.x = tilesiz[tile].x * z; extent.x = tilesiz[tile].x * z;
// obnoxious hardcoded functionality from gametext
if (NUMHACKACTIVE) if (NUMHACKACTIVE)
{ {
char numeral = '0'; // this is subject to change as an implementation detail char numeral = '0'; // this is subject to change as an implementation detail
extent.x = (tilesiz[G_GetStringTile(font, &numeral, f)].x-1) * z; extent.x = (tilesiz[gi->GetStringTile(font, &numeral, f)].x-1) * z;
} }
// height // height
@ -289,7 +284,7 @@ vec2_t G_ScreenTextSize(const int32_t font,
offset.x += extent.x; offset.x += extent.x;
// account for text spacing // account for text spacing
if (!NUMHACKACTIVE // this "if" line ONLY == replicating hardcoded stuff if (!NUMHACKACTIVE
&& t != '\n' && t != '\n'
&& !(f & TEXT_XJUSTIFY)) // to prevent overflow && !(f & TEXT_XJUSTIFY)) // to prevent overflow
offset.x += xbetween; offset.x += xbetween;
@ -333,7 +328,7 @@ vec2_t G_ScreenTextSize(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -416,6 +411,7 @@ vec2_t G_ScreenText(const int32_t font,
vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line 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 Xdirection = { sintable[(blockangle+512)&2047], sintable[blockangle&2047], };
const vec2_t Ydirection = { sintable[(blockangle+1024)&2047], sintable[(blockangle+512)&2047], }; const vec2_t Ydirection = { sintable[(blockangle+1024)&2047], sintable[(blockangle+512)&2047], };
const int32_t z2 = (f & TEXT_RRMENUTEXTHACK) ? 26214 : z;
int32_t blendidx=0, tile; int32_t blendidx=0, tile;
char t; char t;
@ -563,7 +559,7 @@ vec2_t G_ScreenText(const int32_t font,
} }
// translate the character to a tilenum // translate the character to a tilenum
tile = G_GetStringTile(font, &t, f); tile = gi->GetStringTile(font, &t, f);
switch (t) switch (t)
{ {
@ -583,7 +579,7 @@ vec2_t G_ScreenText(const int32_t font,
G_AddCoordsFromRotation(&location, &Xdirection, pos.x); G_AddCoordsFromRotation(&location, &Xdirection, pos.x);
G_AddCoordsFromRotation(&location, &Ydirection, pos.y); G_AddCoordsFromRotation(&location, &Ydirection, pos.y);
rotatesprite_(location.x, location.y, z, angle, tile, shade, pal, orientation, alpha, blendidx, x1, y1, x2, y2); rotatesprite_(location.x, location.y, z2, angle, tile, shade, pal, orientation, alpha, blendidx, x1, y1, x2, y2);
break; break;
} }
@ -602,10 +598,10 @@ vec2_t G_ScreenText(const int32_t font,
if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE)) if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE))
{ {
char space = ' '; // this is subject to change as an implementation detail char space = '.'; // this is subject to change as an implementation detail
if (f & TEXT_TILESPACE) if (f & TEXT_TILESPACE)
space = '\x7F'; // tile after '~' space = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &space, f); tile = gi->GetStringTile(font, &space, f);
extent.x += (tilesiz[tile].x * z); extent.x += (tilesiz[tile].x * z);
} }
@ -619,7 +615,7 @@ vec2_t G_ScreenText(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -647,7 +643,7 @@ vec2_t G_ScreenText(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -695,11 +691,10 @@ vec2_t G_ScreenText(const int32_t font,
// width // width
extent.x = tilesiz[tile].x * z; extent.x = tilesiz[tile].x * z;
// obnoxious hardcoded functionality from gametext
if (NUMHACKACTIVE) if (NUMHACKACTIVE)
{ {
char numeral = '0'; // this is subject to change as an implementation detail char numeral = '0'; // this is subject to change as an implementation detail
extent.x = (tilesiz[G_GetStringTile(font, &numeral, f)].x-1) * z; extent.x = (tilesiz[gi->GetStringTile(font, &numeral, f)].x-1) * z;
} }
// height // height
@ -717,7 +712,7 @@ vec2_t G_ScreenText(const int32_t font,
xoffset += extent.x; xoffset += extent.x;
// account for text spacing // account for text spacing
if (!NUMHACKACTIVE // this "if" line ONLY == replicating hardcoded stuff if (!NUMHACKACTIVE
&& t != '\n') && t != '\n')
xoffset += xbetween; xoffset += xbetween;
@ -757,7 +752,7 @@ vec2_t G_ScreenText(const int32_t font,
char line = 'A'; // this is subject to change as an implementation detail char line = 'A'; // this is subject to change as an implementation detail
if (f & TEXT_TILELINE) if (f & TEXT_TILELINE)
line = '\x7F'; // tile after '~' line = '\x7F'; // tile after '~'
tile = G_GetStringTile(font, &line, f); tile = gi->GetStringTile(font, &line, f);
tempyextent += tilesiz[tile].y * z; tempyextent += tilesiz[tile].y * z;
} }
@ -830,7 +825,3 @@ vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy,
return size; return size;
} }
END_BLD_NS

View file

@ -22,15 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once #pragma once
#include "menus.h" #include "compat.h"
BEGIN_RR_NS
#define MAXUSERQUOTES 6
extern int32_t user_quote_time[MAXUSERQUOTES];
extern int32_t minitext_lowercase;
extern int32_t minitext_yofs;
enum ScreenTextFlags_t { enum ScreenTextFlags_t {
TEXT_XRIGHT = 0x00000001, TEXT_XRIGHT = 0x00000001,
@ -58,42 +50,10 @@ enum ScreenTextFlags_t {
TEXT_RRMENUTEXTHACK = 0x00400000, TEXT_RRMENUTEXTHACK = 0x00400000,
}; };
extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
extern void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f);
extern void captionmenutext(int32_t x, int32_t y, char const *t);
extern vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f);
extern void gametext_simple(int32_t x, int32_t y, const char *t);
#define mpgametext_x (5<<16)
extern vec2_t mpgametext(int32_t x, int32_t y, char const * t, int32_t s, int32_t o, int32_t a, int32_t f);
extern vec2_t mpgametextsize(char const * t, int32_t f);
extern int32_t textsc(int32_t sc);
#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
#define menutext(x, y, t) menutext_((x)<<16, (y)<<16, 0, (t), 10|16, 0)
#define menutext_centeralign(x, y, t) menutext_((x), (y), 0, (t), 10|16, TEXT_XCENTER|TEXT_YCENTER)
#define menutext_center(y, t) menutext_(160<<16, (y)<<16, 0, (t), 10|16, TEXT_XCENTER)
#define gametext(x, y, t) gametext_simple((x)<<16, (y)<<16, (t))
#define gametext_widenumber(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 1024, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_number(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_pal(x, y, t, p) gametext_((x)<<16, (y)<<16, (t), 0, (p), 0, 0, 0)
#define gametext_center(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_number(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER|TEXT_GAMETEXTNUMHACK)
#define gametext_center_shade(y, t, s) gametext_(160<<16, (y)<<16, (t), (s), MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_shade_pal(y, t, s, p) gametext_(160<<16, (y)<<16, (t), (s), (p), 0, 0, TEXT_XCENTER)
extern void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t s, int32_t p, int32_t o,
int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a);
extern int32_t G_GetStringLineLength(const char *text, const char *end, int32_t iter); extern int32_t G_GetStringLineLength(const char *text, const char *end, int32_t iter);
extern int32_t G_GetStringNumLines(const char *text, const char *end, int32_t iter); extern int32_t G_GetStringNumLines(const char *text, const char *end, int32_t iter);
extern char* G_GetSubString(const char *text, const char *end, int32_t iter, int32_t length); extern char* G_GetSubString(const char *text, const char *end, int32_t iter, int32_t length);
extern int32_t G_GetStringTile(int32_t font, char *t, int32_t f);
extern vec2_t G_ScreenTextSize(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, const char *str, int32_t o, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2); extern vec2_t G_ScreenTextSize(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, const char *str, int32_t o, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, int32_t magnitude); extern void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, int32_t magnitude);
extern vec2_t G_ScreenText(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2); extern vec2_t G_ScreenText(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2); extern vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
END_RR_NS

View file

@ -24,7 +24,7 @@ set( PCH_SOURCES
src/savegame.cpp src/savegame.cpp
src/sbar.cpp src/sbar.cpp
src/screens.cpp src/screens.cpp
src/screentext.cpp src/text.cpp
src/sector.cpp src/sector.cpp
src/sounds.cpp src/sounds.cpp
src/soundsdyn.cpp src/soundsdyn.cpp

View file

@ -122,10 +122,10 @@ EDUKE32_STATIC_ASSERT(7 <= MAXTILES-MAXUSERTILES);
#include "player.h" #include "player.h"
#include "quotes.h" #include "quotes.h"
#include "rts.h" #include "rts.h"
#include "screentext.h"
#include "sector.h" #include "sector.h"
#include "sounds.h" #include "sounds.h"
#include "soundsdyn.h" #include "soundsdyn.h"
#include "text.h"
BEGIN_DUKE_NS BEGIN_DUKE_NS
@ -171,6 +171,7 @@ struct GameInterface : ::GameInterface
void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override;
void QuitToTitle() override; void QuitToTitle() override;
FString GetCoordString() override; FString GetCoordString() override;
int GetStringTile(int font, const char* t, int f) override;
}; };

View file

@ -43,16 +43,7 @@ BEGIN_DUKE_NS
// Compile game-side legacy Room over Room code? // Compile game-side legacy Room over Room code?
#define LEGACY_ROR 1 #define LEGACY_ROR 1
#define USERQUOTE_LEFTOFFSET 5
#define USERQUOTE_RIGHTOFFSET 14
#if defined(GEKKO) || defined(__OPENDINGUX__)
# define VIEWSCREENFACTOR 0
#elif defined(__ANDROID__)
# define VIEWSCREENFACTOR 1
#else
# define VIEWSCREENFACTOR 2 # define VIEWSCREENFACTOR 2
#endif
enum GametypeFlags_t { enum GametypeFlags_t {
GAMETYPE_COOP = 0x00000001, GAMETYPE_COOP = 0x00000001,
@ -288,10 +279,6 @@ void G_UpdatePlayerFromMenu(void);
void P_DoQuote(int32_t q,DukePlayer_t *p); void P_DoQuote(int32_t q,DukePlayer_t *p);
void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, ESetPalFlags flags); void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, ESetPalFlags flags);
#define NEG_ALPHA_TO_BLEND(alpha, blend, orientation) do { \
if (alpha < 0) { blend = -alpha; alpha = 0; orientation |= RS_TRANS1; } \
} while (0)
// Cstat protection mask for (currently) spawned MASKWALL* sprites. // Cstat protection mask for (currently) spawned MASKWALL* sprites.
// TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()? // TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()?
// 2048+(32+16)+8+4 // 2048+(32+16)+8+4
@ -447,8 +434,6 @@ static inline int G_GetMusicIdx(const char *str)
} }
EXTERN_INLINE_HEADER void SetIfGreater(int32_t *variable, int32_t potentialValue);
#endif #endif
@ -474,14 +459,6 @@ static inline int G_GetViewscreenSizeShift(T const * spr)
#if defined game_c_ || !defined DISABLE_INLINING #if defined game_c_ || !defined DISABLE_INLINING
// 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 #endif
#endif #endif

File diff suppressed because it is too large Load diff

401
source/duke3d/src/text.cpp Normal file
View file

@ -0,0 +1,401 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "compat.h"
#include "sbar.h"
#include "menus.h"
#include "gstrings.h"
#include "quotemgr.h"
#include "c_dispatch.h"
BEGIN_DUKE_NS
// assign the character's tilenum
int GameInterface::GetStringTile(int font, const char* t, int 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
fallthrough__;
case '\t':
case ' ':
case '\n':
case '\x7F':
return font;
break;
}
}
else
return *t - '!' + font; // uses ASCII order
}
void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t s, int32_t p, int32_t o,
int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a)
{
int32_t f = TEXT_GAMETEXTNUMHACK;
if (t == NULL)
return;
if (!(o & ROTATESPRITE_FULL16))
{
x <<= 16;
y <<= 16;
}
if (x == (160<<16))
f |= TEXT_XCENTER;
G_ScreenText(tile, x, y, z, 0, 0, t, s, p, 2|o|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, x1, y1, x2, y2);
}
vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, s, p, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
void gametext_simple(int32_t x, int32_t y, const char *t)
{
G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametext(int32_t x, int32_t y, const char *t, int32_t s, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, textsc(MF_Bluefont.zoom), 0, 0, t, s, MF_Bluefont.pal, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametextsize(const char *t, int32_t f)
{
return G_ScreenTextSize(MF_Bluefont.tilenum, 0, 0, textsc(MF_Bluefont.zoom), 0, t, 2|8|16|ROTATESPRITE_FULL16, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
// minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords,
// (sb&ROTATESPRITE_MAX) only.
int32_t minitext_yofs = 0;
int32_t minitext_lowercase = 0;
int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb)
{
vec2_t dim;
int32_t z = MF_Minifont.zoom;
if (t == NULL)
{
OSD_Printf("minitext: NULL text!\n");
return 0;
}
if (!(sb & ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;
}
if (sb & ROTATESPRITE_MAX)
{
x = sbarx16(x);
y = minitext_yofs+sbary16(y);
z = sbarsc(z);
}
sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN;
dim = G_ScreenText(MF_Minifont.tilenum, x, y, z, 0, 0, t, s, p, sb|ROTATESPRITE_FULL16, 0, MF_Minifont.emptychar.x, MF_Minifont.emptychar.y, MF_Minifont.between.x, MF_Minifont.between.y, MF_Minifont.textflags, 0, 0, xdim-1, ydim-1);
x += dim.x;
if (!(sb & ROTATESPRITE_FULL16))
x >>= 16;
return x;
}
void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f)
{
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, s, MF_Redfont.pal, o|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, f|MF_Redfont.textflags|TEXT_LITERALESCAPE, 0, 0, xdim-1, ydim-1);
}
void captionmenutext(int32_t x, int32_t y, char const *t)
{
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, 0, ud.menutitle_pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, MF_Redfont.textflags|TEXT_LITERALESCAPE|TEXT_XCENTER|TEXT_YCENTER, 0, 0, xdim-1, ydim-1);
}
int32_t user_quote_time[MAXUSERQUOTES];
static char user_quote[MAXUSERQUOTES][178];
void G_AddUserQuote(const char *daquote)
{
int32_t i;
if (hud_messages == 0) return;
Printf(PRINT_MEDIUM | PRINT_NOTIFY, "%s\n", daquote);
if (hud_messages == 1)
{
for (i = MAXUSERQUOTES - 1; i > 0; i--)
{
Bstrcpy(user_quote[i], user_quote[i - 1]);
user_quote_time[i] = user_quote_time[i - 1];
}
Bstrcpy(user_quote[0], daquote);
user_quote_time[0] = hud_messagetime;
pub = NUMPAGES;
}
}
int32_t textsc(int32_t sc)
{
return scale(sc, hud_textscale, 400);
}
#define FTAOPAQUETIME 30
// alpha increments of 8 --> 256 / 8 = 32 --> round up to power of 2 --> 32 --> divide by 2 --> 16 alphatabs required
static inline int32_t textsh(uint32_t t)
{
return (hud_glowingquotes && ((videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15) || t >= FTAOPAQUETIME))
? sintable[(t << 7) & 2047] >> 11
: (sintable[(FTAOPAQUETIME << 7) & 2047] >> 11);
}
// orientation flags depending on time that a quote has still to be displayed
static inline int32_t texto(int32_t t)
{
if (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15 || t > 4)
return 0;
if (t > 2)
return 1;
return 1|32;
}
static inline int32_t texta(int32_t t)
{
if (videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15)
return 0;
return 255 - clamp(t<<3, 0, 255);
}
static FORCE_INLINE int32_t text_ypos(void)
{
if (hud_position == 1 && ud.screen_size == 4 && ud.althud == 1)
return 32<<16;
#ifdef GEKKO
return 16<<16;
#elif defined EDUKE32_TOUCH_DEVICES
return 24<<16;
#else
return 1<<16;
#endif
}
static FString text_quote; // To put text into the quote display that does not come from the quote array. (Is it really necessary to implement everything as a hack??? :( )
// this handles both multiplayer and item pickup message type text
// both are passed on to gametext
void G_PrintGameQuotes(int32_t snum)
{
auto const ps = g_player[snum].ps;
const int32_t reserved_quote = (ps->ftq >= QUOTE_RESERVED && ps->ftq <= QUOTE_RESERVED3);
// NOTE: QUOTE_RESERVED4 is not included.
int32_t const ybase = (fragbarheight()<<16) + text_ypos();
int32_t height = 0;
int32_t k = ps->fta;
// primary quote
do
{
if (k <= 1)
break;
int32_t y = ybase;
if (reserved_quote)
{
#ifdef SPLITSCREEN_MOD_HACKS
if (!g_fakeMultiMode)
y = 140<<16;
else
y = 70<<16;
#else
y = 140<<16;
#endif
}
int32_t pal = 0;
int32_t x = 160<<16;
#ifdef SPLITSCREEN_MOD_HACKS
if (g_fakeMultiMode)
{
pal = g_player[snum].pcolor;
const int32_t sidebyside = ud.screen_size != 0;
if (sidebyside)
x = snum == 1 ? 240<<16 : 80<<16;
else if (snum == 1)
y += 100<<16;
}
#endif
if (text_quote.IsNotEmpty() && ps->ftq == -32768) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16);
else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16);
}
while (0);
// userquotes
int32_t y = ybase;
if (k > 1 && !reserved_quote)
y += k <= 8 ? (height * (k-1))>>3 : height;
for (int i = 0; i < MAXUSERQUOTES; i++)
{
k = user_quote_time[i];
if (k <= 0)
continue;
// int32_t const sh = hud_glowingquotes ? sintable[((totalclock+(i<<2))<<5)&2047]>>11 : 0;
height = mpgametext(mpgametext_x, y, user_quote[i], textsh(k), texto(k), texta(k), TEXT_LINEWRAP).y + textsc(1<<16);
y += k <= 4 ? (height * (k-1))>>2 : height;
}
}
void P_DoQuote(int32_t q, DukePlayer_t *p)
{
int32_t cq = 0;
if (hud_messages == 0 || q < 0 || !(p->gm & MODE_GAME))
return;
if (q & MAXQUOTES)
{
cq = 1;
q &= ~MAXQUOTES;
}
if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p->ftq != q)
{
auto qu = quoteMgr.GetQuote(q);
if (p == g_player[screenpeek].ps && qu[0] != '\0')
Printf((cq? PRINT_LOW : PRINT_MEDIUM) | PRINT_NOTIFY, "%s\n", qu);
}
if (hud_messages == 1)
{
p->ftq = q;
p->fta = 100;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
void GameInterface::DoPrintMessage(int prio, const char* t)
{
auto p = g_player[myconnectindex].ps; // text quotes always belong to the local player.
int32_t cq = 0;
if (hud_messages == 0 || !(p->gm & MODE_GAME))
return;
if (p->fta > 0)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p == g_player[screenpeek].ps)
Printf(prio | PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t);
if (hud_messages == 1)
{
p->fta = 100;
p->ftq = -32768;
text_quote = t;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
END_DUKE_NS

View file

@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once #pragma once
#include "screentext.h"
#include "menus.h" #include "menus.h"
BEGIN_DUKE_NS BEGIN_DUKE_NS
@ -33,29 +34,7 @@ extern int32_t user_quote_time[MAXUSERQUOTES];
extern int32_t minitext_lowercase; extern int32_t minitext_lowercase;
extern int32_t minitext_yofs; extern int32_t minitext_yofs;
enum ScreenTextFlags_t { enum {
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,
}; };
extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb); extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
@ -87,13 +66,4 @@ extern void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a); int32_t z, int32_t a);
extern int32_t G_GetStringLineLength(const char *text, const char *end, int32_t iter);
extern int32_t G_GetStringNumLines(const char *text, const char *end, int32_t iter);
extern char* G_GetSubString(const char *text, const char *end, int32_t iter, int32_t length);
extern int32_t G_GetStringTile(int32_t font, char *t, int32_t f);
extern vec2_t G_ScreenTextSize(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, const char *str, int32_t o, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, int32_t magnitude);
extern vec2_t G_ScreenText(int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
extern vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, int32_t font, int32_t x, int32_t y, int32_t z, int32_t blockangle, int32_t charangle, const char *str, int32_t shade, int32_t pal, int32_t o, int32_t alpha, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, int32_t f, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
END_DUKE_NS END_DUKE_NS

View file

@ -21,7 +21,7 @@ set( PCH_SOURCES
src/savegame.cpp src/savegame.cpp
src/sbar.cpp src/sbar.cpp
src/screens.cpp src/screens.cpp
src/screentext.cpp src/text.cpp
src/sector.cpp src/sector.cpp
src/sounds.cpp src/sounds.cpp
src/soundsdyn.cpp src/soundsdyn.cpp

View file

@ -125,7 +125,7 @@ END_RR_NS
#include "player.h" #include "player.h"
#include "quotes.h" #include "quotes.h"
#include "rts.h" #include "rts.h"
#include "screentext.h" #include "text.h"
#include "sector.h" #include "sector.h"
#include "sounds.h" #include "sounds.h"
#include "soundsdyn.h" #include "soundsdyn.h"
@ -171,6 +171,7 @@ struct GameInterface : ::GameInterface
void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override;
void QuitToTitle() override; void QuitToTitle() override;
FString GetCoordString() override; FString GetCoordString() override;
int GetStringTile(int font, const char* t, int f) override;
}; };
END_RR_NS END_RR_NS

View file

@ -40,16 +40,7 @@ BEGIN_RR_NS
// Compile game-side legacy Room over Room code? // Compile game-side legacy Room over Room code?
#define LEGACY_ROR 1 #define LEGACY_ROR 1
#define USERQUOTE_LEFTOFFSET 5
#define USERQUOTE_RIGHTOFFSET 14
#if defined(GEKKO) || defined(__OPENDINGUX__)
# define VIEWSCREENFACTOR 0
#elif defined(__ANDROID__)
# define VIEWSCREENFACTOR 1
#else
# define VIEWSCREENFACTOR 2 # define VIEWSCREENFACTOR 2
#endif
enum GametypeFlags_t { enum GametypeFlags_t {
GAMETYPE_COOP = 0x00000001, GAMETYPE_COOP = 0x00000001,
@ -285,10 +276,6 @@ void G_OffMotorcycle(DukePlayer_t *pPlayer);
void G_OnBoat(DukePlayer_t *pPlayer, int spriteNum); void G_OnBoat(DukePlayer_t *pPlayer, int spriteNum);
void G_OffBoat(DukePlayer_t *pPlayer); void G_OffBoat(DukePlayer_t *pPlayer);
#define NEG_ALPHA_TO_BLEND(alpha, blend, orientation) do { \
if (alpha < 0) { blend = -alpha; alpha = 0; orientation |= RS_TRANS1; } \
} while (0)
// Cstat protection mask for (currently) spawned MASKWALL* sprites. // Cstat protection mask for (currently) spawned MASKWALL* sprites.
// TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()? // TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()?
// 2048+(32+16)+8+4 // 2048+(32+16)+8+4

File diff suppressed because it is too large Load diff

377
source/rr/src/text.cpp Normal file
View file

@ -0,0 +1,377 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "compat.h"
#include "sbar.h"
#include "menus.h"
#include "gstrings.h"
BEGIN_RR_NS
// assign the character's tilenum
int GameInterface::GetStringTile(int font, const char* t, int 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
fallthrough__;
case '\t':
case ' ':
case '\n':
case '\x7F':
return font;
break;
}
}
else
return *t - '!' + font; // uses ASCII order
}
vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, s, p, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
void gametext_simple(int32_t x, int32_t y, const char *t)
{
G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametext(int32_t x, int32_t y, const char *t, int32_t s, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, textsc(MF_Bluefont.zoom), 0, 0, t, s, MF_Bluefont.pal, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametextsize(const char *t, int32_t f)
{
return G_ScreenTextSize(MF_Bluefont.tilenum, 0, 0, textsc(MF_Bluefont.zoom), 0, t, 2|8|16|ROTATESPRITE_FULL16, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
// minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords,
// (sb&ROTATESPRITE_MAX) only.
int32_t minitext_yofs = 0;
int32_t minitext_lowercase = 0;
int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb)
{
vec2_t dim;
int32_t z = MF_Minifont.zoom;
if (t == NULL)
{
OSD_Printf("minitext: NULL text!\n");
return 0;
}
if (!(sb & ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;
}
if (sb & ROTATESPRITE_MAX)
{
if (sb & RS_ALIGN_R)
x = sbarxr16(x);
else
x = sbarx16(x);
y = minitext_yofs+sbary16(y);
z = sbarsc(z);
}
sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN;
dim = G_ScreenText(MF_Minifont.tilenum, x, y, z, 0, 0, t, s, p, sb|ROTATESPRITE_FULL16, 0, MF_Minifont.emptychar.x, MF_Minifont.emptychar.y, MF_Minifont.between.x, MF_Minifont.between.y, MF_Minifont.textflags, 0, 0, xdim-1, ydim-1);
x += dim.x;
if (!(sb & ROTATESPRITE_FULL16))
x >>= 16;
return x;
}
void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f)
{
if (RR) f |= TEXT_RRMENUTEXTHACK;
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, s, MF_Redfont.pal, o|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, f|MF_Redfont.textflags|TEXT_LITERALESCAPE, 0, 0, xdim-1, ydim-1);
}
void captionmenutext(int32_t x, int32_t y, char const *t)
{
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, 0, ud.menutitle_pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, MF_Redfont.textflags|TEXT_LITERALESCAPE|TEXT_XCENTER|TEXT_YCENTER, 0, 0, xdim-1, ydim-1);
}
int32_t user_quote_time[MAXUSERQUOTES];
static char user_quote[MAXUSERQUOTES][178];
void G_AddUserQuote(const char* daquote)
{
int32_t i;
if (hud_messages == 0) return;
Printf(PRINT_MEDIUM | PRINT_NOTIFY, "%s\n", daquote);
if (hud_messages == 1)
{
for (i = MAXUSERQUOTES - 1; i > 0; i--)
{
Bstrcpy(user_quote[i], user_quote[i - 1]);
user_quote_time[i] = user_quote_time[i - 1];
}
Bstrcpy(user_quote[0], daquote);
user_quote_time[0] = hud_messagetime;
pub = NUMPAGES;
}
}
int32_t textsc(int32_t sc)
{
return scale(sc, hud_textscale, 400);
}
#define FTAOPAQUETIME 30
// alpha increments of 8 --> 256 / 8 = 32 --> round up to power of 2 --> 32 --> divide by 2 --> 16 alphatabs required
static inline int32_t textsh(uint32_t t)
{
return (hud_glowingquotes && ((videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15) || t >= FTAOPAQUETIME))
? sintable[(t << 7) & 2047] >> 11
: (sintable[(FTAOPAQUETIME << 7) & 2047] >> 11);
}
// orientation flags depending on time that a quote has still to be displayed
static inline int32_t texto(int32_t t)
{
if (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15 || t > 4)
return 0;
if (t > 2)
return 1;
return 1|32;
}
static inline int32_t texta(int32_t t)
{
if (videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15)
return 0;
return 255 - clamp(t<<3, 0, 255);
}
static FORCE_INLINE int32_t text_ypos(void)
{
if (hud_position == 1 && ud.screen_size == 4 && ud.althud == 1)
return 32<<16;
#ifdef GEKKO
return 16<<16;
#elif defined EDUKE32_TOUCH_DEVICES
return 24<<16;
#else
return 1<<16;
#endif
}
static FString text_quote; // To put text into the quote display that does not come from the quote array. (Is it really necessary to implement everything as a hack??? :( )
// this handles both multiplayer and item pickup message type text
// both are passed on to gametext
void G_PrintGameQuotes(int32_t snum)
{
const DukePlayer_t *const ps = g_player[snum].ps;
const int32_t reserved_quote = (ps->ftq >= QUOTE_RESERVED && ps->ftq <= QUOTE_RESERVED3);
// NOTE: QUOTE_RESERVED4 is not included.
int32_t const ybase = (fragbarheight()<<16) + text_ypos();
int32_t height = 0;
int32_t k = ps->fta;
// primary quote
do
{
if (k <= 1)
break;
int32_t y = ybase;
if (reserved_quote)
{
#ifdef SPLITSCREEN_MOD_HACKS
if (!g_fakeMultiMode)
y = 140<<16;
else
y = 70<<16;
#else
y = 140<<16;
#endif
}
int32_t pal = 0;
int32_t x = 160<<16;
#ifdef SPLITSCREEN_MOD_HACKS
if (g_fakeMultiMode)
{
pal = g_player[snum].pcolor;
const int32_t sidebyside = ud.screen_size != 0;
if (sidebyside)
x = snum == 1 ? 240<<16 : 80<<16;
else if (snum == 1)
y += 100<<16;
}
#endif
if (text_quote.IsNotEmpty() && ps->ftq == -32768) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16);
else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16);
}
while (0);
// userquotes
int32_t y = ybase;
if (k > 1 && !reserved_quote)
y += k <= 8 ? (height * (k-1))>>3 : height;
for (size_t i = MAXUSERQUOTES-1; i < MAXUSERQUOTES; --i)
{
k = user_quote_time[i];
if (k <= 0)
continue;
// int32_t const sh = hud_glowingquotes ? sintable[((totalclock+(i<<2))<<5)&2047]>>11 : 0;
height = mpgametext(mpgametext_x, y, user_quote[i], textsh(k), texto(k), texta(k), TEXT_LINEWRAP).y + textsc(1<<16);
y += k <= 4 ? (height * (k-1))>>2 : height;
}
}
void P_DoQuote(int32_t q, DukePlayer_t *p)
{
int32_t cq = 0;
if (hud_messages == 0 || q < 0 || !(p->gm & MODE_GAME))
return;
if (q & MAXQUOTES)
{
cq = 1;
q &= ~MAXQUOTES;
}
if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p->ftq != q)
{
auto qu = quoteMgr.GetQuote(q);
if (p == g_player[screenpeek].ps && qu[0] != '\0')
Printf((cq ? PRINT_LOW : PRINT_MEDIUM) | PRINT_NOTIFY, "%s\n", qu);
}
if (hud_messages == 1)
{
p->ftq = q;
p->fta = 100;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
void GameInterface::DoPrintMessage(int prio, const char* t)
{
auto p = g_player[myconnectindex].ps; // text quotes always belong to the local player.
int32_t cq = 0;
if (hud_messages == 0 || !(p->gm & MODE_GAME))
return;
if (p->fta > 0)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p == g_player[screenpeek].ps)
Printf(prio|PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t);
if (hud_messages == 1)
{
p->fta = 100;
p->ftq = -32768;
text_quote = t;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
END_RR_NS

62
source/rr/src/text.h Normal file
View file

@ -0,0 +1,62 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
#include "menus.h"
#include "screentext.h"
BEGIN_RR_NS
#define MAXUSERQUOTES 6
extern int32_t user_quote_time[MAXUSERQUOTES];
extern int32_t minitext_lowercase;
extern int32_t minitext_yofs;
extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
extern void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f);
extern void captionmenutext(int32_t x, int32_t y, char const *t);
extern vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f);
extern void gametext_simple(int32_t x, int32_t y, const char *t);
#define mpgametext_x (5<<16)
extern vec2_t mpgametext(int32_t x, int32_t y, char const * t, int32_t s, int32_t o, int32_t a, int32_t f);
extern vec2_t mpgametextsize(char const * t, int32_t f);
extern int32_t textsc(int32_t sc);
#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
#define menutext(x, y, t) menutext_((x)<<16, (y)<<16, 0, (t), 10|16, 0)
#define menutext_centeralign(x, y, t) menutext_((x), (y), 0, (t), 10|16, TEXT_XCENTER|TEXT_YCENTER)
#define menutext_center(y, t) menutext_(160<<16, (y)<<16, 0, (t), 10|16, TEXT_XCENTER)
#define gametext(x, y, t) gametext_simple((x)<<16, (y)<<16, (t))
#define gametext_widenumber(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 1024, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_number(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_pal(x, y, t, p) gametext_((x)<<16, (y)<<16, (t), 0, (p), 0, 0, 0)
#define gametext_center(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_number(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER|TEXT_GAMETEXTNUMHACK)
#define gametext_center_shade(y, t, s) gametext_(160<<16, (y)<<16, (t), (s), MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_shade_pal(y, t, s, p) gametext_(160<<16, (y)<<16, (t), (s), (p), 0, 0, TEXT_XCENTER)
END_RR_NS