mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-22 08:51:28 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
acad5caa4c
449 changed files with 59313 additions and 1204 deletions
|
@ -1125,6 +1125,7 @@ set (PCH_SOURCES
|
||||||
gamedata/fonts/singlepicfont.cpp
|
gamedata/fonts/singlepicfont.cpp
|
||||||
gamedata/fonts/specialfont.cpp
|
gamedata/fonts/specialfont.cpp
|
||||||
gamedata/fonts/font.cpp
|
gamedata/fonts/font.cpp
|
||||||
|
gamedata/fonts/hexfont.cpp
|
||||||
gamedata/fonts/v_font.cpp
|
gamedata/fonts/v_font.cpp
|
||||||
gamedata/fonts/v_text.cpp
|
gamedata/fonts/v_text.cpp
|
||||||
gamedata/p_xlat.cpp
|
gamedata/p_xlat.cpp
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "i_time.h"
|
#include "i_time.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "v_text.h"
|
||||||
|
|
||||||
const char *KeyNames[NUM_KEYS] =
|
const char *KeyNames[NUM_KEYS] =
|
||||||
{
|
{
|
||||||
|
@ -297,7 +298,7 @@ void C_NameKeys (char *str, int first, int second)
|
||||||
c++;
|
c++;
|
||||||
strcpy (str, KeyName (first));
|
strcpy (str, KeyName (first));
|
||||||
if (second)
|
if (second)
|
||||||
strcat (str, " or ");
|
strcat (str, TEXTCOLOR_BLACK ", " TEXTCOLOR_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (second)
|
if (second)
|
||||||
|
|
|
@ -1199,7 +1199,7 @@ static void PrintSecretString(const char *string, bool thislevel)
|
||||||
else colstr = TEXTCOLOR_GREEN;
|
else colstr = TEXTCOLOR_GREEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto brok = V_BreakLines(ConFont, screen->GetWidth()*95/100, string);
|
auto brok = V_BreakLines(CurrentConsoleFont, screen->GetWidth()*95/100, string);
|
||||||
|
|
||||||
for (auto &line : brok)
|
for (auto &line : brok)
|
||||||
{
|
{
|
||||||
|
@ -1243,10 +1243,12 @@ CCMD(secret)
|
||||||
FString levelname;
|
FString levelname;
|
||||||
level_info_t *info = FindLevelInfo(mapname);
|
level_info_t *info = FindLevelInfo(mapname);
|
||||||
const char *ln = !(info->flags & LEVEL_LOOKUPLEVELNAME)? info->LevelName.GetChars() : GStrings[info->LevelName.GetChars()];
|
const char *ln = !(info->flags & LEVEL_LOOKUPLEVELNAME)? info->LevelName.GetChars() : GStrings[info->LevelName.GetChars()];
|
||||||
levelname.Format("%s - %s\n", mapname, ln);
|
levelname.Format("%s - %s", mapname, ln);
|
||||||
size_t llen = levelname.Len() - 1;
|
Printf(TEXTCOLOR_YELLOW "%s\n", levelname.GetChars());
|
||||||
|
size_t llen = levelname.Len();
|
||||||
|
levelname = "";
|
||||||
for(size_t ii=0; ii<llen; ii++) levelname += '-';
|
for(size_t ii=0; ii<llen; ii++) levelname += '-';
|
||||||
Printf(TEXTCOLOR_YELLOW"%s\n", levelname.GetChars());
|
Printf(TEXTCOLOR_YELLOW "%s\n", levelname.GetChars());
|
||||||
foundsome = true;
|
foundsome = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
@ -77,6 +79,9 @@ CUSTOM_CVAR(Int, con_buffersize, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
if (self >= 0 && self < 128) self = 128;
|
if (self >= 0 && self < 128) self = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CVAR(Bool, con_consolefont, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
CVAR(Bool, con_midconsolefont, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
FConsoleBuffer *conbuffer;
|
FConsoleBuffer *conbuffer;
|
||||||
|
|
||||||
static void C_TabComplete (bool goForward);
|
static void C_TabComplete (bool goForward);
|
||||||
|
@ -126,13 +131,6 @@ static GameAtExit *ExitCmdList;
|
||||||
|
|
||||||
EXTERN_CVAR (Bool, show_messages)
|
EXTERN_CVAR (Bool, show_messages)
|
||||||
|
|
||||||
static unsigned int TickerAt, TickerMax;
|
|
||||||
static bool TickerPercent;
|
|
||||||
static const char *TickerLabel;
|
|
||||||
|
|
||||||
static bool TickerVisible;
|
|
||||||
static bool ConsoleDrawing;
|
|
||||||
|
|
||||||
// Buffer for AddToConsole()
|
// Buffer for AddToConsole()
|
||||||
static char *work = NULL;
|
static char *work = NULL;
|
||||||
static int worklen = 0;
|
static int worklen = 0;
|
||||||
|
@ -169,13 +167,13 @@ struct History
|
||||||
struct FCommandBuffer
|
struct FCommandBuffer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
FString Text; // The actual command line text
|
std::u32string Text;
|
||||||
unsigned CursorPos = 0;
|
unsigned CursorPos = 0;
|
||||||
unsigned StartPos = 0; // First character to display
|
unsigned StartPos = 0; // First character to display
|
||||||
unsigned CursorPosChars = 0;
|
unsigned CursorPosCells = 0;
|
||||||
unsigned StartPosChars = 0;
|
unsigned StartPosCells = 0;
|
||||||
|
|
||||||
FString YankBuffer; // Deleted text buffer
|
std::u32string YankBuffer; // Deleted text buffer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool AppendToYankBuffer = false; // Append consecutive deletes to buffer
|
bool AppendToYankBuffer = false; // Append consecutive deletes to buffer
|
||||||
|
@ -191,37 +189,39 @@ public:
|
||||||
|
|
||||||
FString GetText() const
|
FString GetText() const
|
||||||
{
|
{
|
||||||
return Text;
|
FString build;
|
||||||
|
for (auto chr : Text) build.AppendCharacter(chr);
|
||||||
|
return build;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextLength() const
|
size_t TextLength() const
|
||||||
{
|
{
|
||||||
return Text.Len();
|
return Text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(int x, int y, int scale, bool cursor)
|
void Draw(int x, int y, int scale, bool cursor)
|
||||||
{
|
{
|
||||||
if (scale == 1)
|
if (scale == 1)
|
||||||
{
|
{
|
||||||
screen->DrawChar(ConFont, CR_ORANGE, x, y, '\x1c', TAG_DONE);
|
screen->DrawChar(CurrentConsoleFont, CR_ORANGE, x, y, '\x1c', TAG_DONE);
|
||||||
screen->DrawText(ConFont, CR_ORANGE, x + ConFont->GetCharWidth(0x1c), y,
|
screen->DrawText(CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y,
|
||||||
&Text[StartPos], TAG_DONE);
|
&Text[StartPos], TAG_DONE);
|
||||||
|
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
screen->DrawChar(ConFont, CR_YELLOW,
|
screen->DrawChar(CurrentConsoleFont, CR_YELLOW,
|
||||||
x + ConFont->GetCharWidth(0x1c) + (CursorPosChars - StartPosChars) * ConFont->GetCharWidth(0xb),
|
x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb),
|
||||||
y, '\xb', TAG_DONE);
|
y, '\xb', TAG_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawChar(ConFont, CR_ORANGE, x, y, '\x1c',
|
screen->DrawChar(CurrentConsoleFont, CR_ORANGE, x, y, '\x1c',
|
||||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
screen->DrawText(ConFont, CR_ORANGE, x + ConFont->GetCharWidth(0x1c), y,
|
screen->DrawText(CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y,
|
||||||
&Text[StartPos],
|
&Text[StartPos],
|
||||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||||
|
@ -229,8 +229,8 @@ public:
|
||||||
|
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
screen->DrawChar(ConFont, CR_YELLOW,
|
screen->DrawChar(CurrentConsoleFont, CR_YELLOW,
|
||||||
x + ConFont->GetCharWidth(0x1c) + (CursorPosChars - StartPosChars) * ConFont->GetCharWidth(0xb),
|
x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb),
|
||||||
y, '\xb',
|
y, '\xb',
|
||||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||||
|
@ -239,72 +239,99 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned BytesForChars(unsigned chars)
|
unsigned CalcCellSize(unsigned length)
|
||||||
{
|
{
|
||||||
unsigned bytes = 0;
|
unsigned cellcount = 0;
|
||||||
while (chars > 0)
|
for (unsigned i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
if ((Text[bytes++] & 0xc0) != 0x80) chars--;
|
int w;
|
||||||
|
NewConsoleFont->GetChar(Text[i], CR_UNTRANSLATED, &w);
|
||||||
|
cellcount += w / 9;
|
||||||
}
|
}
|
||||||
return bytes;
|
return cellcount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned CharsForCells(unsigned cellin, bool *overflow)
|
||||||
|
{
|
||||||
|
unsigned chars = 0;
|
||||||
|
int cells = cellin;
|
||||||
|
while (cells > 0)
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
NewConsoleFont->GetChar(Text[chars++], CR_UNTRANSLATED, &w);
|
||||||
|
cells -= w / 9;
|
||||||
|
}
|
||||||
|
*overflow = (cells < 0);
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MakeStartPosGood()
|
void MakeStartPosGood()
|
||||||
{
|
{
|
||||||
int n = StartPosChars;
|
// Make sure both values point to something valid.
|
||||||
|
if (CursorPos > Text.length()) CursorPos = (unsigned)Text.length();
|
||||||
|
if (StartPos > Text.length()) StartPos = (unsigned)Text.length();
|
||||||
|
|
||||||
|
CursorPosCells = CalcCellSize(CursorPos);
|
||||||
|
StartPosCells = CalcCellSize(StartPos);
|
||||||
|
unsigned LengthCells = CalcCellSize((unsigned)Text.length());
|
||||||
|
|
||||||
|
int n = StartPosCells;
|
||||||
unsigned cols = ConCols / active_con_scale();
|
unsigned cols = ConCols / active_con_scale();
|
||||||
|
|
||||||
if (StartPosChars >= Text.CharacterCount())
|
if (StartPosCells >= LengthCells)
|
||||||
{ // Start of visible line is beyond end of line
|
{ // Start of visible line is beyond end of line
|
||||||
n = CursorPosChars - cols + 2;
|
n = CursorPosCells - cols + 2;
|
||||||
}
|
}
|
||||||
if ((CursorPosChars - StartPosChars) >= cols - 2)
|
if ((CursorPosCells - StartPosCells) >= cols - 2)
|
||||||
{ // The cursor is beyond the visible part of the line
|
{ // The cursor is beyond the visible part of the line
|
||||||
n = CursorPosChars - cols + 2;
|
n = CursorPosCells - cols + 2;
|
||||||
}
|
}
|
||||||
if (StartPosChars > CursorPosChars)
|
if (StartPosCells > CursorPosCells)
|
||||||
{ // The cursor is in front of the visible part of the line
|
{ // The cursor is in front of the visible part of the line
|
||||||
n = CursorPosChars;
|
n = CursorPosCells;
|
||||||
|
}
|
||||||
|
StartPosCells = MAX(0, n);
|
||||||
|
bool overflow;
|
||||||
|
StartPos = CharsForCells(StartPosCells, &overflow);
|
||||||
|
if (overflow)
|
||||||
|
{
|
||||||
|
// We ended up in the middle of a double cell character, so set the start to the following character.
|
||||||
|
StartPosCells++;
|
||||||
|
StartPos = CharsForCells(StartPosCells, &overflow);
|
||||||
}
|
}
|
||||||
StartPosChars = MAX(0, n);
|
|
||||||
StartPos = BytesForChars(StartPosChars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CursorStart()
|
void CursorStart()
|
||||||
{
|
{
|
||||||
CursorPos = 0;
|
CursorPos = 0;
|
||||||
StartPos = 0;
|
StartPos = 0;
|
||||||
CursorPosChars = 0;
|
CursorPosCells = 0;
|
||||||
StartPosChars = 0;
|
StartPosCells = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CursorEnd()
|
void CursorEnd()
|
||||||
{
|
{
|
||||||
CursorPos = (unsigned)Text.Len();
|
CursorPos = (unsigned)Text.length();
|
||||||
CursorPosChars = (unsigned)Text.CharacterCount();
|
|
||||||
StartPosChars = 0;
|
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MoveCursorLeft()
|
void MoveCursorLeft()
|
||||||
{
|
{
|
||||||
CursorPosChars--;
|
CursorPos--;
|
||||||
do CursorPos--;
|
|
||||||
while ((Text[CursorPos] & 0xc0) == 0x80); // Step back to the last non-continuation byte.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveCursorRight()
|
void MoveCursorRight()
|
||||||
{
|
{
|
||||||
CursorPosChars++;
|
CursorPos++;
|
||||||
do CursorPos++;
|
|
||||||
while ((Text[CursorPos] & 0xc0) == 0x80); // Step back to the last non-continuation byte.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void CursorLeft()
|
void CursorLeft()
|
||||||
{
|
{
|
||||||
if (CursorPosChars > 0)
|
if (CursorPos > 0)
|
||||||
{
|
{
|
||||||
MoveCursorLeft();
|
MoveCursorLeft();
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
|
@ -313,7 +340,7 @@ public:
|
||||||
|
|
||||||
void CursorRight()
|
void CursorRight()
|
||||||
{
|
{
|
||||||
if (CursorPosChars < Text.CharacterCount())
|
if (CursorPos < Text.length())
|
||||||
{
|
{
|
||||||
MoveCursorRight();
|
MoveCursorRight();
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
|
@ -322,20 +349,20 @@ public:
|
||||||
|
|
||||||
void CursorWordLeft()
|
void CursorWordLeft()
|
||||||
{
|
{
|
||||||
if (CursorPosChars > 0)
|
if (CursorPos > 0)
|
||||||
{
|
{
|
||||||
do MoveCursorLeft();
|
do MoveCursorLeft();
|
||||||
while (CursorPosChars > 0 && Text[CursorPos - 1] != ' ');
|
while (CursorPos > 0 && Text[CursorPos - 1] != ' ');
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CursorWordRight()
|
void CursorWordRight()
|
||||||
{
|
{
|
||||||
if (CursorPosChars < Text.CharacterCount())
|
if (CursorPos < Text.length())
|
||||||
{
|
{
|
||||||
do MoveCursorRight();
|
do MoveCursorRight();
|
||||||
while (CursorPosChars < Text.CharacterCount() && Text[CursorPos] != ' ');
|
while (CursorPos < Text.length() && Text[CursorPos] != ' ');
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,22 +371,17 @@ public:
|
||||||
{
|
{
|
||||||
if (CursorPos > 0)
|
if (CursorPos > 0)
|
||||||
{
|
{
|
||||||
auto now = CursorPos;
|
|
||||||
MoveCursorLeft();
|
MoveCursorLeft();
|
||||||
Text.Remove(CursorPos, now - CursorPos);
|
Text.erase(CursorPos, 1);
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteRight()
|
void DeleteRight()
|
||||||
{
|
{
|
||||||
if (CursorPosChars < Text.CharacterCount())
|
if (CursorPos < Text.length())
|
||||||
{
|
{
|
||||||
auto now = CursorPos;
|
Text.erase(CursorPos, 1);
|
||||||
MoveCursorRight();
|
|
||||||
Text.Remove(now, CursorPos - now);
|
|
||||||
CursorPos = now;
|
|
||||||
CursorPosChars--;
|
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,11 +395,11 @@ public:
|
||||||
CursorWordLeft();
|
CursorWordLeft();
|
||||||
|
|
||||||
if (AppendToYankBuffer) {
|
if (AppendToYankBuffer) {
|
||||||
YankBuffer = FString(&Text[CursorPos], now - CursorPos) + YankBuffer;
|
YankBuffer = Text.substr(CursorPos, now - CursorPos) + YankBuffer;
|
||||||
} else {
|
} else {
|
||||||
YankBuffer = FString(&Text[CursorPos], now - CursorPos);
|
YankBuffer = Text.substr(CursorPos, now - CursorPos);
|
||||||
}
|
}
|
||||||
Text.Remove(CursorPos, now - CursorPos);
|
Text.erase(CursorPos, now - CursorPos);
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,47 +409,41 @@ public:
|
||||||
if (CursorPos > 0)
|
if (CursorPos > 0)
|
||||||
{
|
{
|
||||||
if (AppendToYankBuffer) {
|
if (AppendToYankBuffer) {
|
||||||
YankBuffer = FString(&Text[0], CursorPos) + YankBuffer;
|
YankBuffer = Text.substr(0, CursorPos) + YankBuffer;
|
||||||
} else {
|
} else {
|
||||||
YankBuffer = FString(&Text[0], CursorPos);
|
YankBuffer = Text.substr(0, CursorPos);
|
||||||
}
|
}
|
||||||
Text.Remove(0, CursorPos);
|
Text.erase(0, CursorPos);
|
||||||
CursorStart();
|
CursorStart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteLineRight()
|
void DeleteLineRight()
|
||||||
{
|
{
|
||||||
if (CursorPos < Text.Len())
|
if (CursorPos < Text.length())
|
||||||
{
|
{
|
||||||
if (AppendToYankBuffer) {
|
if (AppendToYankBuffer) {
|
||||||
YankBuffer += FString(&Text[CursorPos], Text.Len() - CursorPos);
|
YankBuffer += Text.substr(CursorPos, Text.length() - CursorPos);
|
||||||
} else {
|
} else {
|
||||||
YankBuffer = FString(&Text[CursorPos], Text.Len() - CursorPos);
|
YankBuffer = Text.substr(CursorPos, Text.length() - CursorPos);
|
||||||
}
|
}
|
||||||
Text.Truncate(CursorPos);
|
Text.resize(CursorPos);
|
||||||
CursorEnd();
|
CursorEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddChar(int character)
|
void AddChar(int character)
|
||||||
{
|
{
|
||||||
int size;
|
if (Text.length() == 0)
|
||||||
auto encoded = MakeUTF8(character, &size);
|
|
||||||
if (*encoded != 0)
|
|
||||||
{
|
{
|
||||||
if (Text.IsEmpty())
|
Text += character;
|
||||||
{
|
|
||||||
Text = encoded;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Text.Insert(CursorPos, (char*)encoded);
|
|
||||||
}
|
|
||||||
CursorPos += size;
|
|
||||||
CursorPosChars++;
|
|
||||||
MakeStartPosGood();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Text.insert(CursorPos, 1, character);
|
||||||
|
}
|
||||||
|
CursorPos++;
|
||||||
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddString(FString clip)
|
void AddString(FString clip)
|
||||||
|
@ -436,35 +452,52 @@ public:
|
||||||
{
|
{
|
||||||
// Only paste the first line.
|
// Only paste the first line.
|
||||||
long brk = clip.IndexOfAny("\r\n\b");
|
long brk = clip.IndexOfAny("\r\n\b");
|
||||||
|
std::u32string build;
|
||||||
if (brk >= 0)
|
if (brk >= 0)
|
||||||
{
|
{
|
||||||
clip.Truncate(brk);
|
clip.Truncate(brk);
|
||||||
clip = MakeUTF8(clip.GetChars()); // Make sure that we actually have UTF-8 text.
|
|
||||||
}
|
}
|
||||||
if (Text.IsEmpty())
|
auto strp = (const uint8_t*)clip.GetChars();
|
||||||
|
while (auto chr = GetCharFromString(strp)) build += chr;
|
||||||
|
|
||||||
|
if (Text.length() == 0)
|
||||||
{
|
{
|
||||||
Text = clip;
|
Text = build;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Text.Insert(CursorPos, clip);
|
Text.insert(CursorPos, build);
|
||||||
}
|
}
|
||||||
CursorPos += (unsigned)clip.Len();
|
CursorPos += (unsigned)build.length();
|
||||||
CursorPosChars += (unsigned)clip.CharacterCount();
|
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetString(const FString &str)
|
void SetString(const FString &str)
|
||||||
{
|
{
|
||||||
Text = MakeUTF8(str);
|
Text.clear();
|
||||||
|
auto strp = (const uint8_t*)str.GetChars();
|
||||||
|
while (auto chr = GetCharFromString(strp)) Text += chr;
|
||||||
|
|
||||||
CursorEnd();
|
CursorEnd();
|
||||||
MakeStartPosGood();
|
MakeStartPosGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddYankBuffer()
|
void AddYankBuffer()
|
||||||
{
|
{
|
||||||
AddString(YankBuffer);
|
if (YankBuffer.length() > 0)
|
||||||
|
{
|
||||||
|
if (Text.length() == 0)
|
||||||
|
{
|
||||||
|
Text = YankBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Text.insert(CursorPos, YankBuffer);
|
||||||
|
}
|
||||||
|
CursorPos += (unsigned)YankBuffer.length();
|
||||||
|
MakeStartPosGood();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static FCommandBuffer CmdLine;
|
static FCommandBuffer CmdLine;
|
||||||
|
@ -551,47 +584,10 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE)
|
||||||
setmsgcolor (PRINTLEVELS+1, self);
|
setmsgcolor (PRINTLEVELS+1, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TextQueue
|
EColorRange C_GetDefaultFontColor()
|
||||||
{
|
{
|
||||||
TextQueue (bool notify, int printlevel, const char *text)
|
// Ideally this should analyze the SmallFont and pick a matching color.
|
||||||
: Next(NULL), bNotify(notify), PrintLevel(printlevel), Text(text)
|
return gameinfo.gametype == GAME_Doom ? CR_RED : gameinfo.gametype == GAME_Chex ? CR_GREEN : gameinfo.gametype == GAME_Strife ? CR_GOLD : CR_GRAY;
|
||||||
{
|
|
||||||
}
|
|
||||||
TextQueue *Next;
|
|
||||||
bool bNotify;
|
|
||||||
int PrintLevel;
|
|
||||||
FString Text;
|
|
||||||
};
|
|
||||||
|
|
||||||
TextQueue *EnqueuedText, **EnqueuedTextTail = &EnqueuedText;
|
|
||||||
|
|
||||||
void EnqueueConsoleText (bool notify, int printlevel, const char *text)
|
|
||||||
{
|
|
||||||
TextQueue *queued = new TextQueue (notify, printlevel, text);
|
|
||||||
*EnqueuedTextTail = queued;
|
|
||||||
EnqueuedTextTail = &queued->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DequeueConsoleText ()
|
|
||||||
{
|
|
||||||
TextQueue *queued = EnqueuedText;
|
|
||||||
|
|
||||||
while (queued != NULL)
|
|
||||||
{
|
|
||||||
TextQueue *next = queued->Next;
|
|
||||||
if (queued->bNotify)
|
|
||||||
{
|
|
||||||
NotifyStrings.AddString(queued->PrintLevel, queued->Text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddToConsole (queued->PrintLevel, queued->Text);
|
|
||||||
}
|
|
||||||
delete queued;
|
|
||||||
queued = next;
|
|
||||||
}
|
|
||||||
EnqueuedText = NULL;
|
|
||||||
EnqueuedTextTail = &EnqueuedText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void C_InitConback()
|
void C_InitConback()
|
||||||
|
@ -616,10 +612,10 @@ void C_InitConsole (int width, int height, bool ingame)
|
||||||
int cwidth, cheight;
|
int cwidth, cheight;
|
||||||
|
|
||||||
vidactive = ingame;
|
vidactive = ingame;
|
||||||
if (ConFont != NULL)
|
if (CurrentConsoleFont != NULL)
|
||||||
{
|
{
|
||||||
cwidth = ConFont->GetCharWidth ('M');
|
cwidth = CurrentConsoleFont->GetCharWidth ('M');
|
||||||
cheight = ConFont->GetHeight();
|
cheight = CurrentConsoleFont->GetHeight();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -786,22 +782,18 @@ void FNotifyBuffer::AddString(int printlevel, FString source)
|
||||||
con_notifylines == 0)
|
con_notifylines == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ConsoleDrawing)
|
width = DisplayWidth / active_con_scaletext(con_consolefont);
|
||||||
{
|
|
||||||
EnqueueConsoleText (true, printlevel, source);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
width = DisplayWidth / active_con_scaletext();
|
FFont *font = *con_consolefont ? NewSmallFont : SmallFont;
|
||||||
|
|
||||||
if (AddType == APPENDLINE && Text.Size() > 0 && Text[Text.Size() - 1].PrintLevel == printlevel)
|
if (AddType == APPENDLINE && Text.Size() > 0 && Text[Text.Size() - 1].PrintLevel == printlevel)
|
||||||
{
|
{
|
||||||
FString str = Text[Text.Size() - 1].Text + source;
|
FString str = Text[Text.Size() - 1].Text + source;
|
||||||
lines = V_BreakLines (SmallFont, width, str);
|
lines = V_BreakLines (font, width, str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lines = V_BreakLines (SmallFont, width, source);
|
lines = V_BreakLines (font, width, source);
|
||||||
if (AddType == APPENDLINE)
|
if (AddType == APPENDLINE)
|
||||||
{
|
{
|
||||||
AddType = NEWLINE;
|
AddType = NEWLINE;
|
||||||
|
@ -845,11 +837,51 @@ void FNotifyBuffer::AddString(int printlevel, FString source)
|
||||||
|
|
||||||
void AddToConsole (int printlevel, const char *text)
|
void AddToConsole (int printlevel, const char *text)
|
||||||
{
|
{
|
||||||
conbuffer->AddText(printlevel, MakeUTF8(text), Logfile);
|
conbuffer->AddText(printlevel, MakeUTF8(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrintString (int printlevel, const char *outline)
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void WriteLineToLog(FILE *LogFile, const char *outline)
|
||||||
{
|
{
|
||||||
|
// Strip out any color escape sequences before writing to the log file
|
||||||
|
TArray<char> copy(strlen(outline) + 1);
|
||||||
|
const char * srcp = outline;
|
||||||
|
char * dstp = copy.Data();
|
||||||
|
|
||||||
|
while (*srcp != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*srcp != TEXTCOLOR_ESCAPE)
|
||||||
|
{
|
||||||
|
*dstp++ = *srcp++;
|
||||||
|
}
|
||||||
|
else if (srcp[1] == '[')
|
||||||
|
{
|
||||||
|
srcp += 2;
|
||||||
|
while (*srcp != ']' && *srcp != 0) srcp++;
|
||||||
|
if (*srcp == ']') srcp++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (srcp[1] != 0) srcp += 2;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dstp = 0;
|
||||||
|
|
||||||
|
fputs(copy.Data(), LogFile);
|
||||||
|
fflush(LogFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PrintString (int iprintlevel, const char *outline)
|
||||||
|
{
|
||||||
|
int printlevel = iprintlevel & PRINT_TYPES;
|
||||||
if (printlevel < msglevel || *outline == '\0')
|
if (printlevel < msglevel || *outline == '\0')
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -864,16 +896,15 @@ int PrintString (int printlevel, const char *outline)
|
||||||
{
|
{
|
||||||
I_PrintStr(outline);
|
I_PrintStr(outline);
|
||||||
|
|
||||||
conbuffer->AddText(printlevel, outline, Logfile);
|
conbuffer->AddText(printlevel, outline);
|
||||||
if (vidactive && screen && SmallFont)
|
if (vidactive && screen && SmallFont && !(iprintlevel & PRINT_NONOTIFY))
|
||||||
{
|
{
|
||||||
NotifyStrings.AddString(printlevel, outline);
|
NotifyStrings.AddString(printlevel, outline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Logfile != nullptr)
|
if (Logfile != nullptr && !(iprintlevel & PRINT_NOLOG))
|
||||||
{
|
{
|
||||||
fputs(outline, Logfile);
|
WriteLineToLog(Logfile, outline);
|
||||||
fflush(Logfile);
|
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1067,8 @@ void FNotifyBuffer::Draw()
|
||||||
line = Top;
|
line = Top;
|
||||||
canskip = true;
|
canskip = true;
|
||||||
|
|
||||||
lineadv = SmallFont->GetHeight ();
|
FFont *font = *con_consolefont ? NewSmallFont : SmallFont;
|
||||||
|
lineadv = font->GetHeight ();
|
||||||
|
|
||||||
for (unsigned i = 0; i < Text.Size(); ++ i)
|
for (unsigned i = 0; i < Text.Size(); ++ i)
|
||||||
{
|
{
|
||||||
|
@ -1058,15 +1090,19 @@ void FNotifyBuffer::Draw()
|
||||||
else
|
else
|
||||||
color = PrintColors[notify.PrintLevel];
|
color = PrintColors[notify.PrintLevel];
|
||||||
|
|
||||||
int scale = active_con_scaletext();
|
if (color == CR_UNTRANSLATED && *con_consolefont)
|
||||||
|
{
|
||||||
|
color = C_GetDefaultFontColor();
|
||||||
|
}
|
||||||
|
int scale = active_con_scaletext(con_consolefont);
|
||||||
if (!center)
|
if (!center)
|
||||||
screen->DrawText (SmallFont, color, 0, line, notify.Text,
|
screen->DrawText (font, color, 0, line, notify.Text,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
DTA_Alpha, alpha, TAG_DONE);
|
DTA_Alpha, alpha, TAG_DONE);
|
||||||
else
|
else
|
||||||
screen->DrawText (SmallFont, color, (screen->GetWidth() -
|
screen->DrawText (font, color, (screen->GetWidth() -
|
||||||
SmallFont->StringWidth (notify.Text) * scale) / 2 / scale,
|
SmallFont->StringWidth (notify.Text) * scale) / 2 / scale,
|
||||||
line, notify.Text,
|
line, notify.Text,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||||
|
@ -1092,19 +1128,6 @@ void FNotifyBuffer::Draw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C_InitTicker (const char *label, unsigned int max, bool showpercent)
|
|
||||||
{
|
|
||||||
TickerPercent = showpercent;
|
|
||||||
TickerMax = max;
|
|
||||||
TickerLabel = label;
|
|
||||||
TickerAt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_SetTicker (unsigned int at, bool forceUpdate)
|
|
||||||
{
|
|
||||||
TickerAt = at > TickerMax ? TickerMax : at;
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_DrawConsole ()
|
void C_DrawConsole ()
|
||||||
{
|
{
|
||||||
static int oldbottom = 0;
|
static int oldbottom = 0;
|
||||||
|
@ -1113,15 +1136,15 @@ void C_DrawConsole ()
|
||||||
int textScale = active_con_scale();
|
int textScale = active_con_scale();
|
||||||
|
|
||||||
left = LEFTMARGIN;
|
left = LEFTMARGIN;
|
||||||
lines = (ConBottom/textScale-ConFont->GetHeight()*2)/ConFont->GetHeight();
|
lines = (ConBottom/textScale-CurrentConsoleFont->GetHeight()*2)/CurrentConsoleFont->GetHeight();
|
||||||
if (-ConFont->GetHeight() + lines*ConFont->GetHeight() > ConBottom/textScale - ConFont->GetHeight()*7/2)
|
if (-CurrentConsoleFont->GetHeight() + lines*CurrentConsoleFont->GetHeight() > ConBottom/textScale - CurrentConsoleFont->GetHeight()*7/2)
|
||||||
{
|
{
|
||||||
offset = -ConFont->GetHeight()/2;
|
offset = -CurrentConsoleFont->GetHeight()/2;
|
||||||
lines--;
|
lines--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = -ConFont->GetHeight();
|
offset = -CurrentConsoleFont->GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
oldbottom = ConBottom;
|
oldbottom = ConBottom;
|
||||||
|
@ -1153,71 +1176,19 @@ void C_DrawConsole ()
|
||||||
if (ConBottom >= 12)
|
if (ConBottom >= 12)
|
||||||
{
|
{
|
||||||
if (textScale == 1)
|
if (textScale == 1)
|
||||||
screen->DrawText (ConFont, CR_ORANGE, SCREENWIDTH - 8 -
|
screen->DrawText (CurrentConsoleFont, CR_ORANGE, SCREENWIDTH - 8 -
|
||||||
ConFont->StringWidth (GetVersionString()),
|
CurrentConsoleFont->StringWidth (GetVersionString()),
|
||||||
ConBottom / textScale - ConFont->GetHeight() - 4,
|
ConBottom / textScale - CurrentConsoleFont->GetHeight() - 4,
|
||||||
GetVersionString(), TAG_DONE);
|
GetVersionString(), TAG_DONE);
|
||||||
else
|
else
|
||||||
screen->DrawText(ConFont, CR_ORANGE, SCREENWIDTH / textScale - 8 -
|
screen->DrawText(CurrentConsoleFont, CR_ORANGE, SCREENWIDTH / textScale - 8 -
|
||||||
ConFont->StringWidth(GetVersionString()),
|
CurrentConsoleFont->StringWidth(GetVersionString()),
|
||||||
ConBottom / textScale - ConFont->GetHeight() - 4,
|
ConBottom / textScale - CurrentConsoleFont->GetHeight() - 4,
|
||||||
GetVersionString(),
|
GetVersionString(),
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
if (TickerMax)
|
|
||||||
{
|
|
||||||
char tickstr[256];
|
|
||||||
const int tickerY = ConBottom / textScale - ConFont->GetHeight() - 4;
|
|
||||||
size_t i;
|
|
||||||
int tickend = ConCols / textScale - SCREENWIDTH / textScale / 90 - 6;
|
|
||||||
int tickbegin = 0;
|
|
||||||
|
|
||||||
if (TickerLabel)
|
|
||||||
{
|
|
||||||
tickbegin = (int)strlen (TickerLabel) + 2;
|
|
||||||
mysnprintf (tickstr, countof(tickstr), "%s: ", TickerLabel);
|
|
||||||
}
|
|
||||||
if (tickend > 256 - ConFont->GetCharWidth(0x12))
|
|
||||||
tickend = 256 - ConFont->GetCharWidth(0x12);
|
|
||||||
tickstr[tickbegin] = 0x10;
|
|
||||||
memset (tickstr + tickbegin + 1, 0x11, tickend - tickbegin);
|
|
||||||
tickstr[tickend + 1] = 0x12;
|
|
||||||
tickstr[tickend + 2] = ' ';
|
|
||||||
if (TickerPercent)
|
|
||||||
{
|
|
||||||
mysnprintf (tickstr + tickend + 3, countof(tickstr) - tickend - 3,
|
|
||||||
"%d%%", Scale (TickerAt, 100, TickerMax));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tickstr[tickend+3] = 0;
|
|
||||||
}
|
|
||||||
if (textScale == 1)
|
|
||||||
screen->DrawText (ConFont, CR_BROWN, LEFTMARGIN, tickerY, tickstr, TAG_DONE);
|
|
||||||
else
|
|
||||||
screen->DrawText (ConFont, CR_BROWN, LEFTMARGIN, tickerY, tickstr,
|
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
|
||||||
|
|
||||||
// Draw the marker
|
|
||||||
i = LEFTMARGIN+5+tickbegin*8 + Scale (TickerAt, (int32_t)(tickend - tickbegin)*8, TickerMax);
|
|
||||||
if (textScale == 1)
|
|
||||||
screen->DrawChar (ConFont, CR_ORANGE, (int)i, tickerY, 0x13, TAG_DONE);
|
|
||||||
else
|
|
||||||
screen->DrawChar(ConFont, CR_ORANGE, (int)i, tickerY, 0x13,
|
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
|
||||||
|
|
||||||
TickerVisible = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TickerVisible = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1230,46 +1201,42 @@ void C_DrawConsole ()
|
||||||
if (lines > 0)
|
if (lines > 0)
|
||||||
{
|
{
|
||||||
// No more enqueuing because adding new text to the console won't touch the actual print data.
|
// No more enqueuing because adding new text to the console won't touch the actual print data.
|
||||||
conbuffer->FormatText(ConFont, ConWidth / textScale);
|
conbuffer->FormatText(CurrentConsoleFont, ConWidth / textScale);
|
||||||
unsigned int consolelines = conbuffer->GetFormattedLineCount();
|
unsigned int consolelines = conbuffer->GetFormattedLineCount();
|
||||||
FBrokenLines *blines = conbuffer->GetLines();
|
FBrokenLines *blines = conbuffer->GetLines();
|
||||||
FBrokenLines *printline = blines + consolelines - 1 - RowAdjust;
|
FBrokenLines *printline = blines + consolelines - 1 - RowAdjust;
|
||||||
|
|
||||||
int bottomline = ConBottom / textScale - ConFont->GetHeight()*2 - 4;
|
int bottomline = ConBottom / textScale - CurrentConsoleFont->GetHeight()*2 - 4;
|
||||||
|
|
||||||
ConsoleDrawing = true;
|
|
||||||
|
|
||||||
for(FBrokenLines *p = printline; p >= blines && lines > 0; p--, lines--)
|
for(FBrokenLines *p = printline; p >= blines && lines > 0; p--, lines--)
|
||||||
{
|
{
|
||||||
if (textScale == 1)
|
if (textScale == 1)
|
||||||
{
|
{
|
||||||
screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), p->Text, TAG_DONE);
|
screen->DrawText(CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, TAG_DONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), p->Text,
|
screen->DrawText(CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleDrawing = false;
|
|
||||||
|
|
||||||
if (ConBottom >= 20)
|
if (ConBottom >= 20)
|
||||||
{
|
{
|
||||||
if (gamestate != GS_STARTUP)
|
if (gamestate != GS_STARTUP)
|
||||||
{
|
{
|
||||||
CmdLine.Draw(left, bottomline, textScale, cursoron);
|
CmdLine.Draw(left, bottomline, textScale, cursoron);
|
||||||
}
|
}
|
||||||
if (RowAdjust && ConBottom >= ConFont->GetHeight()*7/2)
|
if (RowAdjust && ConBottom >= CurrentConsoleFont->GetHeight()*7/2)
|
||||||
{
|
{
|
||||||
// Indicate that the view has been scrolled up (10)
|
// Indicate that the view has been scrolled up (10)
|
||||||
// and if we can scroll no further (12)
|
// and if we can scroll no further (12)
|
||||||
if (textScale == 1)
|
if (textScale == 1)
|
||||||
screen->DrawChar (ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE);
|
screen->DrawChar (CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE);
|
||||||
else
|
else
|
||||||
screen->DrawChar(ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10,
|
screen->DrawChar(CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
@ -1294,7 +1261,6 @@ void C_FullConsole ()
|
||||||
primaryLevel->Music = "";
|
primaryLevel->Music = "";
|
||||||
S_Start ();
|
S_Start ();
|
||||||
P_FreeLevelData ();
|
P_FreeLevelData ();
|
||||||
V_SetBlend (0,0,0,0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1405,7 +1371,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
||||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||||
{ // Scroll console buffer up one page
|
{ // Scroll console buffer up one page
|
||||||
RowAdjust += (SCREENHEIGHT-4)/active_con_scale() /
|
RowAdjust += (SCREENHEIGHT-4)/active_con_scale() /
|
||||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? ConFont->GetHeight() : ConFont->GetHeight()*2) - 3;
|
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3;
|
||||||
}
|
}
|
||||||
else if (RowAdjust < conbuffer->GetFormattedLineCount())
|
else if (RowAdjust < conbuffer->GetFormattedLineCount())
|
||||||
{ // Scroll console buffer up
|
{ // Scroll console buffer up
|
||||||
|
@ -1428,7 +1394,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
||||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||||
{ // Scroll console buffer down one page
|
{ // Scroll console buffer down one page
|
||||||
const int scrollamt = (SCREENHEIGHT-4)/active_con_scale() /
|
const int scrollamt = (SCREENHEIGHT-4)/active_con_scale() /
|
||||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? ConFont->GetHeight() : ConFont->GetHeight()*2) - 3;
|
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3;
|
||||||
if (RowAdjust < scrollamt)
|
if (RowAdjust < scrollamt)
|
||||||
{
|
{
|
||||||
RowAdjust = 0;
|
RowAdjust = 0;
|
||||||
|
@ -1776,45 +1742,30 @@ CCMD (echo)
|
||||||
|
|
||||||
/* Printing in the middle of the screen */
|
/* Printing in the middle of the screen */
|
||||||
|
|
||||||
CVAR (Float, con_midtime, 3.f, CVAR_ARCHIVE)
|
CVAR(Float, con_midtime, 3.f, CVAR_ARCHIVE)
|
||||||
|
|
||||||
static const char bar1[] = TEXTCOLOR_RED "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
const char *console_bar = "----------------------------------------";
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_TAN "\n";
|
|
||||||
static const char bar2[] = TEXTCOLOR_RED "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_GREEN "\n";
|
|
||||||
static const char bar3[] = TEXTCOLOR_RED "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_NORMAL "\n";
|
|
||||||
|
|
||||||
void C_MidPrint (FFont *font, const char *msg)
|
void C_MidPrint (FFont *font, const char *msg, bool bold)
|
||||||
{
|
{
|
||||||
if (StatusBar == NULL || screen == NULL)
|
if (StatusBar == nullptr || screen == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (msg != NULL)
|
if (msg != nullptr)
|
||||||
{
|
{
|
||||||
AddToConsole (-1, bar1);
|
auto color = (EColorRange)PrintColors[bold? PRINTLEVELS+1 : PRINTLEVELS];
|
||||||
AddToConsole (-1, msg);
|
Printf(PRINT_NONOTIFY, TEXTCOLOR_ESCAPESTR "%c%s\n%s\n%s\n", color, console_bar, msg, console_bar);
|
||||||
AddToConsole (-1, bar3);
|
|
||||||
|
bool altscale = false;
|
||||||
|
if (font == nullptr)
|
||||||
|
{
|
||||||
|
altscale = con_midconsolefont;
|
||||||
|
font = altscale ? NewSmallFont : SmallFont;
|
||||||
|
if (altscale && color == CR_UNTRANSLATED) color = C_GetDefaultFontColor();
|
||||||
|
}
|
||||||
|
|
||||||
StatusBar->AttachMessage (Create<DHUDMessage>(font, msg, 1.5f, 0.375f, 0, 0,
|
StatusBar->AttachMessage (Create<DHUDMessage>(font, msg, 1.5f, 0.375f, 0, 0,
|
||||||
(EColorRange)PrintColors[PRINTLEVELS], con_midtime), MAKE_ID('C','N','T','R'));
|
color, con_midtime, altscale), MAKE_ID('C','N','T','R'));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusBar->DetachMessage (MAKE_ID('C','N','T','R'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_MidPrintBold (FFont *font, const char *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
{
|
|
||||||
AddToConsole (-1, bar2);
|
|
||||||
AddToConsole (-1, msg);
|
|
||||||
AddToConsole (-1, bar3);
|
|
||||||
|
|
||||||
StatusBar->AttachMessage (Create<DHUDMessage> (font, msg, 1.5f, 0.375f, 0, 0,
|
|
||||||
(EColorRange)PrintColors[PRINTLEVELS+1], con_midtime), MAKE_ID('C','N','T','R'));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1825,13 +1776,12 @@ void C_MidPrintBold (FFont *font, const char *msg)
|
||||||
DEFINE_ACTION_FUNCTION(_Console, MidPrint)
|
DEFINE_ACTION_FUNCTION(_Console, MidPrint)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_POINTER_NOT_NULL(fnt, FFont);
|
PARAM_POINTER(fnt, FFont);
|
||||||
PARAM_STRING(text);
|
PARAM_STRING(text);
|
||||||
PARAM_BOOL(bold);
|
PARAM_BOOL(bold);
|
||||||
|
|
||||||
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
|
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
|
||||||
if (!bold) C_MidPrint(fnt, txt);
|
C_MidPrint(fnt, txt, bold);
|
||||||
else C_MidPrintBold(fnt, txt);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,10 @@ typedef enum cstate_t
|
||||||
}
|
}
|
||||||
constate_e;
|
constate_e;
|
||||||
|
|
||||||
#define PRINTLEVELS 5
|
enum
|
||||||
|
{
|
||||||
|
PRINTLEVELS = 5
|
||||||
|
};
|
||||||
extern int PrintColors[PRINTLEVELS + 2];
|
extern int PrintColors[PRINTLEVELS + 2];
|
||||||
|
|
||||||
extern constate_e ConsoleState;
|
extern constate_e ConsoleState;
|
||||||
|
@ -74,12 +77,8 @@ void C_HideConsole (void);
|
||||||
void C_AdjustBottom (void);
|
void C_AdjustBottom (void);
|
||||||
void C_FlushDisplay (void);
|
void C_FlushDisplay (void);
|
||||||
|
|
||||||
void C_InitTicker (const char *label, unsigned int max, bool showpercent=true);
|
|
||||||
void C_SetTicker (unsigned int at, bool forceUpdate=false);
|
|
||||||
|
|
||||||
class FFont;
|
class FFont;
|
||||||
void C_MidPrint (FFont *font, const char *message);
|
void C_MidPrint (FFont *font, const char *message, bool bold = false);
|
||||||
void C_MidPrintBold (FFont *font, const char *message);
|
|
||||||
|
|
||||||
bool C_Responder (event_t *ev);
|
bool C_Responder (event_t *ev);
|
||||||
|
|
||||||
|
@ -87,4 +86,6 @@ void C_AddTabCommand (const char *name);
|
||||||
void C_RemoveTabCommand (const char *name);
|
void C_RemoveTabCommand (const char *name);
|
||||||
void C_ClearTabCommands(); // Removes all tab commands
|
void C_ClearTabCommands(); // Removes all tab commands
|
||||||
|
|
||||||
|
extern const char *console_bar;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,33 +55,6 @@ FConsoleBuffer::FConsoleBuffer()
|
||||||
mBrokenStart.Push(0);
|
mBrokenStart.Push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FConsoleBuffer::~FConsoleBuffer()
|
|
||||||
{
|
|
||||||
FreeBrokenText();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FConsoleBuffer::FreeBrokenText(unsigned start, unsigned end)
|
|
||||||
{
|
|
||||||
if (end > m_BrokenConsoleText.Size()) end = m_BrokenConsoleText.Size();
|
|
||||||
for (unsigned i = start; i < end; i++)
|
|
||||||
{
|
|
||||||
m_BrokenConsoleText[i].Clear();
|
|
||||||
m_BrokenConsoleText[i].ShrinkToFit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Adds a new line of text to the console
|
// Adds a new line of text to the console
|
||||||
|
@ -95,7 +68,7 @@ void FConsoleBuffer::FreeBrokenText(unsigned start, unsigned end)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FConsoleBuffer::AddText(int printlevel, const char *text, FILE *logfile)
|
void FConsoleBuffer::AddText(int printlevel, const char *text)
|
||||||
{
|
{
|
||||||
FString build = TEXTCOLOR_TAN;
|
FString build = TEXTCOLOR_TAN;
|
||||||
|
|
||||||
|
@ -135,117 +108,9 @@ void FConsoleBuffer::AddText(int printlevel, const char *text, FILE *logfile)
|
||||||
mAddType = APPENDLINE;
|
mAddType = APPENDLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't bother about linefeeds etc. inside the text, we'll let the formatter sort this out later.
|
// don't bother with linefeeds etc. inside the text, we'll let the formatter sort this out later.
|
||||||
build.AppendCStrPart(text, textsize);
|
build.AppendCStrPart(text, textsize);
|
||||||
mConsoleText.Push(build);
|
mConsoleText.Push(build);
|
||||||
if (logfile != NULL) WriteLineToLog(logfile, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FConsoleBuffer::WriteLineToLog(FILE *LogFile, const char *outline)
|
|
||||||
{
|
|
||||||
// Strip out any color escape sequences before writing to the log file
|
|
||||||
TArray<char> copy(strlen(outline)+1);
|
|
||||||
const char * srcp = outline;
|
|
||||||
char * dstp = copy.Data();
|
|
||||||
|
|
||||||
while (*srcp != 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*srcp != TEXTCOLOR_ESCAPE)
|
|
||||||
{
|
|
||||||
switch (*srcp)
|
|
||||||
{
|
|
||||||
case '\35':
|
|
||||||
*dstp++ = '<';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\36':
|
|
||||||
*dstp++ = '-';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\37':
|
|
||||||
*dstp++ = '>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
*dstp++=*srcp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
srcp++;
|
|
||||||
}
|
|
||||||
else if (srcp[1] == '[')
|
|
||||||
{
|
|
||||||
srcp+=2;
|
|
||||||
while (*srcp != ']' && *srcp != 0) srcp++;
|
|
||||||
if (*srcp == ']') srcp++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (srcp[1]!=0) srcp+=2;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*dstp=0;
|
|
||||||
|
|
||||||
fputs (copy.Data(), LogFile);
|
|
||||||
fflush (LogFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FConsoleBuffer::WriteContentToLog(FILE *LogFile)
|
|
||||||
{
|
|
||||||
if (LogFile != NULL)
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < mConsoleText.Size(); i++)
|
|
||||||
{
|
|
||||||
WriteLineToLog(LogFile, mConsoleText[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// ensures that the following text is not appended to the current line.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FConsoleBuffer::Linefeed(FILE *Logfile)
|
|
||||||
{
|
|
||||||
if (mAddType != NEWLINE && Logfile != NULL) fputc('\n', Logfile);
|
|
||||||
mAddType = NEWLINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static const char bar1[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_TAN "\n";
|
|
||||||
static const char bar2[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_GREEN "\n";
|
|
||||||
static const char bar3[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_NORMAL "\n";
|
|
||||||
|
|
||||||
void FConsoleBuffer::AddMidText(const char *string, bool bold, FILE *Logfile)
|
|
||||||
{
|
|
||||||
Linefeed(Logfile);
|
|
||||||
AddText (-1, bold? bar2 : bar1, Logfile);
|
|
||||||
AddText (-1, string, Logfile);
|
|
||||||
Linefeed(Logfile);
|
|
||||||
AddText(-1, bar3, Logfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -258,7 +123,6 @@ void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth)
|
||||||
{
|
{
|
||||||
if (formatfont != mLastFont || displaywidth != mLastDisplayWidth || mBufferWasCleared)
|
if (formatfont != mLastFont || displaywidth != mLastDisplayWidth || mBufferWasCleared)
|
||||||
{
|
{
|
||||||
FreeBrokenText();
|
|
||||||
m_BrokenConsoleText.Clear();
|
m_BrokenConsoleText.Clear();
|
||||||
mBrokenStart.Clear();
|
mBrokenStart.Clear();
|
||||||
mBrokenStart.Push(0);
|
mBrokenStart.Push(0);
|
||||||
|
|
|
@ -61,19 +61,12 @@ class FConsoleBuffer
|
||||||
int mLastDisplayWidth;
|
int mLastDisplayWidth;
|
||||||
bool mLastLineNeedsUpdate;
|
bool mLastLineNeedsUpdate;
|
||||||
|
|
||||||
void WriteLineToLog(FILE *LogFile, const char *outline);
|
|
||||||
void FreeBrokenText(unsigned int start = 0, unsigned int end = INT_MAX);
|
|
||||||
|
|
||||||
void Linefeed(FILE *Logfile);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FConsoleBuffer();
|
FConsoleBuffer();
|
||||||
~FConsoleBuffer();
|
void AddText(int printlevel, const char *string);
|
||||||
void AddText(int printlevel, const char *string, FILE *logfile = NULL);
|
|
||||||
void AddMidText(const char *string, bool bold, FILE *logfile);
|
|
||||||
void FormatText(FFont *formatfont, int displaywidth);
|
void FormatText(FFont *formatfont, int displaywidth);
|
||||||
void ResizeBuffer(unsigned newsize);
|
void ResizeBuffer(unsigned newsize);
|
||||||
void WriteContentToLog(FILE *logfile);
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
mBufferWasCleared = true;
|
mBufferWasCleared = true;
|
||||||
|
|
|
@ -563,7 +563,7 @@ void C_DoCommand (const char *cmd, int keynum)
|
||||||
const char *beg;
|
const char *beg;
|
||||||
|
|
||||||
// Skip any beginning whitespace
|
// Skip any beginning whitespace
|
||||||
while (*cmd && *cmd <= ' ')
|
while (*cmd > 0 && *cmd <= ' ')
|
||||||
cmd++;
|
cmd++;
|
||||||
|
|
||||||
// Find end of the command name
|
// Find end of the command name
|
||||||
|
@ -575,7 +575,7 @@ void C_DoCommand (const char *cmd, int keynum)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
beg = cmd;
|
beg = cmd;
|
||||||
for (end = cmd+1; *end > ' '; ++end)
|
for (end = cmd+1; *end > ' ' || *end < 0; ++end)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ void AddCommandString (const char *text, int keynum)
|
||||||
more = 0;
|
more = 0;
|
||||||
}
|
}
|
||||||
// Intercept wait commands here. Note: wait must be lowercase
|
// Intercept wait commands here. Note: wait must be lowercase
|
||||||
while (*cmd && *cmd <= ' ')
|
while (*cmd > 0 && *cmd <= ' ')
|
||||||
cmd++;
|
cmd++;
|
||||||
if (*cmd)
|
if (*cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
#include "gstrings.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -233,16 +234,16 @@ void CT_PasteChat(const char *clip)
|
||||||
|
|
||||||
void CT_Drawer (void)
|
void CT_Drawer (void)
|
||||||
{
|
{
|
||||||
FFont *displayfont = ConFont;
|
FFont *displayfont = NewConsoleFont;
|
||||||
if (chatmodeon)
|
if (chatmodeon)
|
||||||
{
|
{
|
||||||
static const char *prompt = "Say: ";
|
FStringf prompt("%s ", GStrings("TXT_SAY"));
|
||||||
int x, scalex, y, promptwidth;
|
int x, scalex, y, promptwidth;
|
||||||
|
|
||||||
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
y = (viewactive || gamestate != GS_LEVEL) ? -displayfont->GetHeight()-2 : -displayfont->GetHeight() - 22;
|
||||||
|
|
||||||
scalex = 1;
|
scalex = 1;
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(true);
|
||||||
int screen_width = SCREENWIDTH / scale;
|
int screen_width = SCREENWIDTH / scale;
|
||||||
int screen_height= SCREENHEIGHT / scale;
|
int screen_height= SCREENHEIGHT / scale;
|
||||||
int st_y = StatusBar->GetTopOfStatusbar() / scale;
|
int st_y = StatusBar->GetTopOfStatusbar() / scale;
|
||||||
|
@ -264,7 +265,7 @@ void CT_Drawer (void)
|
||||||
}
|
}
|
||||||
printstr += displayfont->GetCursor();
|
printstr += displayfont->GetCursor();
|
||||||
|
|
||||||
screen->DrawText (displayfont, CR_GREEN, 0, y, prompt,
|
screen->DrawText (displayfont, CR_GREEN, 0, y, prompt.GetChars(),
|
||||||
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
||||||
screen->DrawText (displayfont, CR_GREY, promptwidth, y, printstr,
|
screen->DrawText (displayfont, CR_GREY, promptwidth, y, printstr,
|
||||||
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
|
@ -790,7 +790,7 @@ void D_Display ()
|
||||||
screen->DrawBlend(viewsec);
|
screen->DrawBlend(viewsec);
|
||||||
if (automapactive)
|
if (automapactive)
|
||||||
{
|
{
|
||||||
primaryLevel->automap->Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
primaryLevel->automap->Drawer ((hud_althud && viewheight == SCREENHEIGHT) ? viewheight : StatusBar->GetTopOfStatusbar());
|
||||||
}
|
}
|
||||||
|
|
||||||
// for timing the statusbar code.
|
// for timing the statusbar code.
|
||||||
|
@ -1247,7 +1247,6 @@ void D_DoAdvanceDemo (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
V_SetBlend (0,0,0,0);
|
|
||||||
players[consoleplayer].playerstate = PST_LIVE; // not reborn
|
players[consoleplayer].playerstate = PST_LIVE; // not reborn
|
||||||
usergame = false; // no save / end game here
|
usergame = false; // no save / end game here
|
||||||
paused = 0;
|
paused = 0;
|
||||||
|
@ -1293,6 +1292,7 @@ void D_DoAdvanceDemo (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
singledemo = false;
|
||||||
G_DeferedPlayDemo (demoname);
|
G_DeferedPlayDemo (demoname);
|
||||||
demosequence = 2;
|
demosequence = 2;
|
||||||
break;
|
break;
|
||||||
|
@ -2635,6 +2635,7 @@ void D_DoomMain (void)
|
||||||
|
|
||||||
V_Init2();
|
V_Init2();
|
||||||
UpdateJoystickMenu(NULL);
|
UpdateJoystickMenu(NULL);
|
||||||
|
UpdateVRModes();
|
||||||
|
|
||||||
v = Args->CheckValue ("-loadgame");
|
v = Args->CheckValue ("-loadgame");
|
||||||
if (v)
|
if (v)
|
||||||
|
@ -2697,8 +2698,6 @@ void D_DoomMain (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// let the renderer reinitialize some stuff if needed
|
|
||||||
screen->InitPalette();
|
|
||||||
// These calls from inside V_Init2 are still necessary
|
// These calls from inside V_Init2 are still necessary
|
||||||
C_NewModeAdjust();
|
C_NewModeAdjust();
|
||||||
D_StartTitle (); // start up intro loop
|
D_StartTitle (); // start up intro loop
|
||||||
|
|
|
@ -2169,7 +2169,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
||||||
|
|
||||||
case DEM_CENTERPRINT:
|
case DEM_CENTERPRINT:
|
||||||
s = ReadString (stream);
|
s = ReadString (stream);
|
||||||
C_MidPrint (SmallFont, s);
|
C_MidPrint (nullptr, s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEM_UINFCHANGED:
|
case DEM_UINFCHANGED:
|
||||||
|
|
|
@ -250,7 +250,8 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
|
||||||
}
|
}
|
||||||
int GetGender() const
|
int GetGender() const
|
||||||
{
|
{
|
||||||
return *static_cast<FIntCVar *>(*CheckKey(NAME_Gender));
|
auto cvar = CheckKey(NAME_Gender);
|
||||||
|
return cvar ? *static_cast<FIntCVar *>(*cvar) : 0;
|
||||||
}
|
}
|
||||||
bool GetNoAutostartMap() const
|
bool GetNoAutostartMap() const
|
||||||
{
|
{
|
||||||
|
@ -280,7 +281,8 @@ class player_t
|
||||||
public:
|
public:
|
||||||
player_t() = default;
|
player_t() = default;
|
||||||
~player_t();
|
~player_t();
|
||||||
player_t &operator= (const player_t &p);
|
player_t &operator= (const player_t &p) = delete;
|
||||||
|
void CopyFrom(player_t &src, bool copyPSP);
|
||||||
|
|
||||||
void Serialize(FSerializer &arc);
|
void Serialize(FSerializer &arc);
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
|
|
|
@ -89,7 +89,10 @@ enum
|
||||||
PRINT_CHAT, // chat messages
|
PRINT_CHAT, // chat messages
|
||||||
PRINT_TEAMCHAT, // chat messages from a teammate
|
PRINT_TEAMCHAT, // chat messages from a teammate
|
||||||
PRINT_LOG, // only to logfile
|
PRINT_LOG, // only to logfile
|
||||||
PRINT_BOLD = 200 // What Printf_Bold used
|
PRINT_BOLD = 200, // What Printf_Bold used
|
||||||
|
PRINT_TYPES = 1023, // Bitmask.
|
||||||
|
PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer
|
||||||
|
PRINT_NOLOG = 2048, // Flag - do not print to log file
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -573,7 +573,7 @@ void FParser::SF_Include(void)
|
||||||
|
|
||||||
void FParser::SF_Input(void)
|
void FParser::SF_Input(void)
|
||||||
{
|
{
|
||||||
Printf(PRINT_BOLD,"input() function not available in doom\n");
|
Printf(PRINT_BOLD,"input() function not available in Doom\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -623,7 +623,7 @@ void FParser::SF_Tip(void)
|
||||||
if (t_argc>0 && Script->trigger &&
|
if (t_argc>0 && Script->trigger &&
|
||||||
Script->trigger->CheckLocalView())
|
Script->trigger->CheckLocalView())
|
||||||
{
|
{
|
||||||
C_MidPrint(SmallFont, GetFormatString(0).GetChars());
|
C_MidPrint(nullptr, GetFormatString(0).GetChars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ void FParser::SF_TimedTip(void)
|
||||||
{
|
{
|
||||||
float saved = con_midtime;
|
float saved = con_midtime;
|
||||||
con_midtime = intvalue(t_argv[0])/100.0f;
|
con_midtime = intvalue(t_argv[0])/100.0f;
|
||||||
C_MidPrint(SmallFont, GetFormatString(1).GetChars());
|
C_MidPrint(nullptr, GetFormatString(1).GetChars());
|
||||||
con_midtime=saved;
|
con_midtime=saved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ void FParser::SF_PlayerTip(void)
|
||||||
int plnum = T_GetPlayerNum(t_argv[0]);
|
int plnum = T_GetPlayerNum(t_argv[0]);
|
||||||
if (plnum!=-1 && Level->Players[plnum]->mo->CheckLocalView())
|
if (plnum!=-1 && Level->Players[plnum]->mo->CheckLocalView())
|
||||||
{
|
{
|
||||||
C_MidPrint(SmallFont, GetFormatString(1).GetChars());
|
C_MidPrint(nullptr, GetFormatString(1).GetChars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,9 @@ CVAR(Int, developer, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
// [RH] Feature control cvars
|
// [RH] Feature control cvars
|
||||||
CVAR(Bool, var_friction, true, CVAR_SERVERINFO);
|
CVAR(Bool, var_friction, true, CVAR_SERVERINFO);
|
||||||
|
|
||||||
|
// Option Search
|
||||||
|
CVAR(Bool, os_isanyof, true, CVAR_ARCHIVE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,9 +132,8 @@ CUSTOM_CVAR(Float, teamdamage, 0.f, CVAR_SERVERINFO | CVAR_NOINITCALL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(String, language, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL)
|
CUSTOM_CVAR(String, language, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
SetLanguageIDs();
|
|
||||||
GStrings.UpdateLanguage();
|
GStrings.UpdateLanguage();
|
||||||
for (auto Level : AllLevels())
|
for (auto Level : AllLevels())
|
||||||
{
|
{
|
||||||
|
@ -139,4 +141,3 @@ CUSTOM_CVAR(String, language, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL)
|
||||||
if (Level->info != nullptr) Level->LevelName = Level->info->LookupLevelName();
|
if (Level->info != nullptr) Level->LevelName = Level->info->LookupLevelName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "c_functions.h"
|
#include "c_functions.h"
|
||||||
|
#include "gstrings.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -404,3 +405,22 @@ CCMD(listsnapshots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CCMD(printlocalized)
|
||||||
|
{
|
||||||
|
if (argv.argc() > 1)
|
||||||
|
{
|
||||||
|
if (argv.argc() > 2)
|
||||||
|
{
|
||||||
|
FString lang = argv[2];
|
||||||
|
lang.ToLower();
|
||||||
|
if (lang.Len() >= 2)
|
||||||
|
{
|
||||||
|
Printf("%s\n", GStrings.GetLanguageString(argv[1], MAKE_ID(lang[0], lang[1], lang[2], 0)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Printf("%s\n", GStrings(argv[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ CVAR (Bool, storesavepic, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR (Bool, longsavemessages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR (Bool, longsavemessages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR (String, save_dir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
CVAR (String, save_dir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||||
CVAR (Bool, cl_waitforsave, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR (Bool, cl_waitforsave, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
|
CVAR (Bool, enablescriptscreenshot, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
EXTERN_CVAR (Float, con_midtime);
|
EXTERN_CVAR (Float, con_midtime);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -755,10 +756,15 @@ static int LookAdjust(int look)
|
||||||
if (players[consoleplayer].playerstate != PST_DEAD && // No adjustment while dead.
|
if (players[consoleplayer].playerstate != PST_DEAD && // No adjustment while dead.
|
||||||
players[consoleplayer].ReadyWeapon != NULL) // No adjustment if no weapon.
|
players[consoleplayer].ReadyWeapon != NULL) // No adjustment if no weapon.
|
||||||
{
|
{
|
||||||
auto scale = players[consoleplayer].ReadyWeapon->FloatVar(NAME_FOVScale);
|
auto FOVScale = players[consoleplayer].ReadyWeapon->FloatVar(NAME_FOVScale);
|
||||||
if (scale > 0) // No adjustment if it is non-positive.
|
auto LookScale = players[consoleplayer].ReadyWeapon->FloatVar(NAME_LookScale);
|
||||||
|
if (FOVScale > 0) // No adjustment if it is non-positive.
|
||||||
{
|
{
|
||||||
look = int(look * scale);
|
look = int(look * FOVScale);
|
||||||
|
}
|
||||||
|
if (LookScale > 0) // No adjustment if it is non-positive.
|
||||||
|
{
|
||||||
|
look = int(look * LookScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return look;
|
return look;
|
||||||
|
@ -1715,7 +1721,7 @@ void G_DoPlayerPop(int playernum)
|
||||||
players[playernum].DestroyPSprites();
|
players[playernum].DestroyPSprites();
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_ScreenShot (char *filename)
|
void G_ScreenShot (const char *filename)
|
||||||
{
|
{
|
||||||
shotfile = filename;
|
shotfile = filename;
|
||||||
gameaction = ga_screenshot;
|
gameaction = ga_screenshot;
|
||||||
|
@ -2048,7 +2054,7 @@ void G_DoAutoSave ()
|
||||||
}
|
}
|
||||||
|
|
||||||
readableTime = myasctime ();
|
readableTime = myasctime ();
|
||||||
description.Format("Autosave %.12s", readableTime + 4);
|
description.Format("Autosave %s", readableTime);
|
||||||
G_DoSaveGame (false, file, description);
|
G_DoSaveGame (false, file, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2071,14 +2077,9 @@ static void PutSaveWads (FSerializer &arc)
|
||||||
|
|
||||||
static void PutSaveComment (FSerializer &arc)
|
static void PutSaveComment (FSerializer &arc)
|
||||||
{
|
{
|
||||||
const char *readableTime;
|
|
||||||
int levelTime;
|
int levelTime;
|
||||||
|
|
||||||
// Get the current date and time
|
FString comment = myasctime();
|
||||||
readableTime = myasctime ();
|
|
||||||
|
|
||||||
FString comment;
|
|
||||||
comment.Format("%.10s%.5s%.9s", readableTime, &readableTime[19], &readableTime[10]);
|
|
||||||
|
|
||||||
arc.AddString("Creation Time", comment);
|
arc.AddString("Creation Time", comment);
|
||||||
|
|
||||||
|
@ -2094,6 +2095,56 @@ static void PutSaveComment (FSerializer &arc)
|
||||||
arc.AddString("Comment", comment);
|
arc.AddString("Comment", comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown)
|
||||||
|
{
|
||||||
|
PalEntry palette[256];
|
||||||
|
PalEntry modulateColor;
|
||||||
|
auto blend = screen->CalcBlend(viewsector, &modulateColor);
|
||||||
|
int pixelsize = 1;
|
||||||
|
// Apply the screen blend, because the renderer does not provide this.
|
||||||
|
if (ssformat == SS_RGB)
|
||||||
|
{
|
||||||
|
int numbytes = width * height * 3;
|
||||||
|
pixelsize = 3;
|
||||||
|
if (modulateColor != 0xffffffff)
|
||||||
|
{
|
||||||
|
float r = modulateColor.r / 255.f;
|
||||||
|
float g = modulateColor.g / 255.f;
|
||||||
|
float b = modulateColor.b / 255.f;
|
||||||
|
for (int i = 0; i < numbytes; i += 3)
|
||||||
|
{
|
||||||
|
scr[i] = uint8_t(scr[i] * r);
|
||||||
|
scr[i + 1] = uint8_t(scr[i + 1] * g);
|
||||||
|
scr[i + 2] = uint8_t(scr[i + 2] * b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float iblendfac = 1.f - blend.W;
|
||||||
|
blend.X *= blend.W;
|
||||||
|
blend.Y *= blend.W;
|
||||||
|
blend.Z *= blend.W;
|
||||||
|
for (int i = 0; i < numbytes; i += 3)
|
||||||
|
{
|
||||||
|
scr[i] = uint8_t(scr[i] * iblendfac + blend.X);
|
||||||
|
scr[i + 1] = uint8_t(scr[i + 1] * iblendfac + blend.Y);
|
||||||
|
scr[i + 2] = uint8_t(scr[i + 2] * iblendfac + blend.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Apply the screen blend to the palette. The colormap related parts get skipped here because these are already part of the image.
|
||||||
|
DoBlending(GPalette.BaseColors, palette, 256, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z), uint8_t(blend.W*255));
|
||||||
|
}
|
||||||
|
|
||||||
|
int pitch = width * pixelsize;
|
||||||
|
if (upsidedown)
|
||||||
|
{
|
||||||
|
scr += ((height - 1) * width * pixelsize);
|
||||||
|
pitch *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_CreatePNG(file, scr, ssformat == SS_PAL? palette : nullptr, ssformat, width, height, pitch, Gamma);
|
||||||
|
}
|
||||||
|
|
||||||
static void PutSavePic (FileWriter *file, int width, int height)
|
static void PutSavePic (FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
if (width <= 0 || height <= 0 || !storesavepic)
|
if (width <= 0 || height <= 0 || !storesavepic)
|
||||||
|
@ -2676,7 +2727,7 @@ void G_DoPlayDemo (void)
|
||||||
}
|
}
|
||||||
demo_p = demobuffer;
|
demo_p = demobuffer;
|
||||||
|
|
||||||
Printf ("Playing demo %s\n", defdemoname.GetChars());
|
if (singledemo) Printf ("Playing demo %s\n", defdemoname.GetChars());
|
||||||
|
|
||||||
C_BackupCVars (); // [RH] Save cvars that might be affected by demo
|
C_BackupCVars (); // [RH] Save cvars that might be affected by demo
|
||||||
|
|
||||||
|
@ -2693,7 +2744,7 @@ void G_DoPlayDemo (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Printf (PRINT_BOLD, "%s", eek);
|
//Printf (PRINT_BOLD, "%s", eek);
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2876,6 +2927,26 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, StartSlideshow)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FLevelLocals, MakeScreenShot)
|
||||||
|
{
|
||||||
|
if (enablescriptscreenshot)
|
||||||
|
{
|
||||||
|
G_ScreenShot("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_MakeAutoSave()
|
||||||
|
{
|
||||||
|
gameaction = ga_autosave;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FLevelLocals, MakeAutoSave)
|
||||||
|
{
|
||||||
|
G_MakeAutoSave();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_GLOBAL(players)
|
DEFINE_GLOBAL(players)
|
||||||
DEFINE_GLOBAL(playeringame)
|
DEFINE_GLOBAL(playeringame)
|
||||||
DEFINE_GLOBAL(PlayerClasses)
|
DEFINE_GLOBAL(PlayerClasses)
|
||||||
|
|
|
@ -95,7 +95,7 @@ bool G_CheckDemoStatus (void);
|
||||||
void G_Ticker (void);
|
void G_Ticker (void);
|
||||||
bool G_Responder (event_t* ev);
|
bool G_Responder (event_t* ev);
|
||||||
|
|
||||||
void G_ScreenShot (char *filename);
|
void G_ScreenShot (const char* filename);
|
||||||
void G_StartSlideshow(FLevelLocals *Level, FName whichone);
|
void G_StartSlideshow(FLevelLocals *Level, FName whichone);
|
||||||
|
|
||||||
FString G_BuildSaveName (const char *prefix, int slot);
|
FString G_BuildSaveName (const char *prefix, int slot);
|
||||||
|
|
|
@ -1062,12 +1062,8 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
|
||||||
if (isPrimaryLevel())
|
if (isPrimaryLevel())
|
||||||
{
|
{
|
||||||
FString mapname = nextmapname;
|
FString mapname = nextmapname;
|
||||||
mapname.ToLower();
|
mapname.ToUpper();
|
||||||
Printf(
|
Printf("\n%s\n\n" TEXTCOLOR_BOLD "%s - %s\n\n", console_bar, mapname.GetChars(), LevelName.GetChars());
|
||||||
"\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"
|
|
||||||
TEXTCOLOR_BOLD "%s - %s\n\n",
|
|
||||||
mapname.GetChars(), LevelName.GetChars());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the sky map.
|
// Set the sky map.
|
||||||
|
@ -2142,9 +2138,9 @@ int IsPointInMap(FLevelLocals *Level, double x, double y, double z)
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subsector->numlines; i++)
|
for (uint32_t i = 0; i < subsector->numlines; i++)
|
||||||
{
|
{
|
||||||
// Skip single sided lines.
|
// Skip double sided lines.
|
||||||
seg_t *seg = subsector->firstline + i;
|
seg_t *seg = subsector->firstline + i;
|
||||||
if (seg->backsector != nullptr) continue;
|
if (seg->backsector != nullptr || seg->linedef == nullptr) continue;
|
||||||
|
|
||||||
divline_t dline;
|
divline_t dline;
|
||||||
P_MakeDivline(seg->linedef, &dline);
|
P_MakeDivline(seg->linedef, &dline);
|
||||||
|
|
|
@ -128,7 +128,7 @@ void DHUDMessageBase::CallDraw(int bottom, int visibility)
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
||||||
EColorRange textColor, float holdTime)
|
EColorRange textColor, float holdTime, bool altscale)
|
||||||
{
|
{
|
||||||
if (hudwidth == 0 || hudheight == 0)
|
if (hudwidth == 0 || hudheight == 0)
|
||||||
{
|
{
|
||||||
|
@ -139,6 +139,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
||||||
// for x range [0.0, 1.0]: Positions center of box
|
// for x range [0.0, 1.0]: Positions center of box
|
||||||
// for x range [1.0, 2.0]: Positions center of box, and centers text inside it
|
// for x range [1.0, 2.0]: Positions center of box, and centers text inside it
|
||||||
HUDWidth = HUDHeight = 0;
|
HUDWidth = HUDHeight = 0;
|
||||||
|
AltScale = altscale;
|
||||||
if (fabs (x) > 2.f)
|
if (fabs (x) > 2.f)
|
||||||
{
|
{
|
||||||
CenterX = true;
|
CenterX = true;
|
||||||
|
@ -319,7 +320,7 @@ void DHUDMessage::ResetText (const char *text)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = SCREENWIDTH / active_con_scaletext();
|
width = SCREENWIDTH / active_con_scaletext(AltScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lines = V_BreakLines (Font, NoWrap ? INT_MAX : width, (uint8_t *)text);
|
Lines = V_BreakLines (Font, NoWrap ? INT_MAX : width, (uint8_t *)text);
|
||||||
|
@ -379,7 +380,7 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
||||||
xscale = yscale = 1;
|
xscale = yscale = 1;
|
||||||
if (HUDWidth == 0)
|
if (HUDWidth == 0)
|
||||||
{
|
{
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(AltScale);
|
||||||
screen_width /= scale;
|
screen_width /= scale;
|
||||||
screen_height /= scale;
|
screen_height /= scale;
|
||||||
bottom /= scale;
|
bottom /= scale;
|
||||||
|
@ -483,7 +484,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
||||||
{
|
{
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(AltScale);
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH / scale,
|
DTA_VirtualWidth, SCREENWIDTH / scale,
|
||||||
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
||||||
|
@ -576,7 +577,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
||||||
float trans = float(Alpha * -(Tics - FadeOutTics) / FadeOutTics);
|
float trans = float(Alpha * -(Tics - FadeOutTics) / FadeOutTics);
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(AltScale);
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH / scale,
|
DTA_VirtualWidth, SCREENWIDTH / scale,
|
||||||
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
||||||
|
@ -665,7 +666,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
||||||
float trans = float(Alpha * Tics / FadeInTics);
|
float trans = float(Alpha * Tics / FadeInTics);
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(AltScale);
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH / scale,
|
DTA_VirtualWidth, SCREENWIDTH / scale,
|
||||||
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
||||||
|
@ -741,7 +742,7 @@ void DHUDMessageTypeOnFadeOut::Serialize(FSerializer &arc)
|
||||||
|
|
||||||
bool DHUDMessageTypeOnFadeOut::Tick ()
|
bool DHUDMessageTypeOnFadeOut::Tick ()
|
||||||
{
|
{
|
||||||
if (LineLen > 0 && !Super::Tick ())
|
if (!Super::Tick ())
|
||||||
{
|
{
|
||||||
if (State == 3)
|
if (State == 3)
|
||||||
{
|
{
|
||||||
|
@ -836,7 +837,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
||||||
{
|
{
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
int scale = active_con_scaletext();
|
int scale = active_con_scaletext(AltScale);
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH / scale,
|
DTA_VirtualWidth, SCREENWIDTH / scale,
|
||||||
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
DTA_VirtualHeight, SCREENHEIGHT / scale,
|
||||||
|
|
|
@ -84,7 +84,7 @@ class DHUDMessage : public DHUDMessageBase
|
||||||
DECLARE_CLASS (DHUDMessage, DHUDMessageBase)
|
DECLARE_CLASS (DHUDMessage, DHUDMessageBase)
|
||||||
public:
|
public:
|
||||||
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
||||||
EColorRange textColor, float holdTime);
|
EColorRange textColor, float holdTime, bool altscale = false);
|
||||||
virtual void OnDestroy () override;
|
virtual void OnDestroy () override;
|
||||||
|
|
||||||
virtual void Serialize(FSerializer &arc);
|
virtual void Serialize(FSerializer &arc);
|
||||||
|
@ -140,6 +140,7 @@ protected:
|
||||||
int ClipX, ClipY, ClipWidth, ClipHeight, WrapWidth; // in HUD coords
|
int ClipX, ClipY, ClipWidth, ClipHeight, WrapWidth; // in HUD coords
|
||||||
int ClipLeft, ClipTop, ClipRight, ClipBot; // in screen coords
|
int ClipLeft, ClipTop, ClipRight, ClipBot; // in screen coords
|
||||||
bool HandleAspect;
|
bool HandleAspect;
|
||||||
|
bool AltScale;
|
||||||
EColorRange TextColor;
|
EColorRange TextColor;
|
||||||
FFont *Font;
|
FFont *Font;
|
||||||
FRenderStyle Style;
|
FRenderStyle Style;
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
CVAR(Int,hud_althudscale, 0, CVAR_ARCHIVE) // Scale the hud to 640x400?
|
CVAR(Int,hud_althudscale, 0, CVAR_ARCHIVE) // Scale the hud to 640x400?
|
||||||
CVAR(Bool,hud_althud, false, CVAR_ARCHIVE) // Enable/Disable the alternate HUD
|
CVAR(Bool,hud_althud, false, CVAR_ARCHIVE) // Enable/Disable the alternate HUD
|
||||||
|
|
||||||
|
CVAR(Bool, hud_althudfont, false, CVAR_ARCHIVE) // Enable/Disable the alternate HUD
|
||||||
// These are intentionally not the same as in the automap!
|
// These are intentionally not the same as in the automap!
|
||||||
CVAR (Bool, hud_showsecrets, true,CVAR_ARCHIVE); // Show secrets on HUD
|
CVAR (Bool, hud_showsecrets, true,CVAR_ARCHIVE); // Show secrets on HUD
|
||||||
CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD
|
CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ static void PrintMessage (const char *str)
|
||||||
{
|
{
|
||||||
str = GStrings(str+1);
|
str = GStrings(str+1);
|
||||||
}
|
}
|
||||||
C_MidPrint (SmallFont, str);
|
C_MidPrint (nullptr, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -751,12 +751,24 @@ int FFont::GetCharCode(int code, bool needpic) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code = originalcode;
|
||||||
if (myislower(code))
|
if (myislower(code))
|
||||||
{
|
{
|
||||||
int upper = upperforlower[code];
|
int upper = upperforlower[code];
|
||||||
// Stripping accents did not help - now try uppercase for lowercase
|
// Stripping accents did not help - now try uppercase for lowercase
|
||||||
if (upper != code) return GetCharCode(upper, needpic);
|
if (upper != code) return GetCharCode(upper, needpic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same for the uppercase character. Since we restart at the accented version this must go through the entire thing again.
|
||||||
|
while ((newcode = stripaccent(code)) != code)
|
||||||
|
{
|
||||||
|
code = newcode;
|
||||||
|
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr))
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
397
src/gamedata/fonts/hexfont.cpp
Normal file
397
src/gamedata/fonts/hexfont.cpp
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
/*
|
||||||
|
** bdffont.cpp
|
||||||
|
** Management for the VGA consolefont
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2019 Christoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "doomerrors.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "v_font.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include "sc_man.h"
|
||||||
|
|
||||||
|
#include "fontinternals.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct HexDataSource
|
||||||
|
{
|
||||||
|
int FirstChar = INT_MAX, LastChar = INT_MIN;
|
||||||
|
TArray<uint8_t> glyphdata;
|
||||||
|
unsigned glyphmap[65536] = {};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// parse a HEX font
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void ParseDefinition(int lumpnum)
|
||||||
|
{
|
||||||
|
FScanner sc;
|
||||||
|
|
||||||
|
sc.OpenLumpNum(lumpnum);
|
||||||
|
sc.SetCMode(true);
|
||||||
|
glyphdata.Push(0); // ensure that index 0 can be used as 'not present'.
|
||||||
|
while (sc.GetString())
|
||||||
|
{
|
||||||
|
int codepoint = (int)strtoull(sc.String, nullptr, 16);
|
||||||
|
sc.MustGetStringName(":");
|
||||||
|
sc.MustGetString();
|
||||||
|
if (codepoint >= 0 && codepoint < 65536 && !sc.Compare("00000000000000000000000000000000")) // don't set up empty glyphs.
|
||||||
|
{
|
||||||
|
unsigned size = (unsigned)strlen(sc.String);
|
||||||
|
unsigned offset = glyphdata.Reserve(size / 2 + 1);
|
||||||
|
glyphmap[codepoint] = offset;
|
||||||
|
glyphdata[offset++] = size / 2;
|
||||||
|
for (unsigned i = 0; i < size; i += 2)
|
||||||
|
{
|
||||||
|
char hex[] = { sc.String[i], sc.String[i + 1], 0 };
|
||||||
|
glyphdata[offset++] = (uint8_t)strtoull(hex, nullptr, 16);
|
||||||
|
}
|
||||||
|
if (codepoint < FirstChar) FirstChar = codepoint;
|
||||||
|
if (codepoint > LastChar) LastChar = codepoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static HexDataSource hexdata;
|
||||||
|
|
||||||
|
// This is a font character that reads RLE compressed data.
|
||||||
|
class FHexFontChar : public FImageSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height);
|
||||||
|
|
||||||
|
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int SourceWidth;
|
||||||
|
const uint8_t *SourceData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFontChar :: FHexFontChar
|
||||||
|
//
|
||||||
|
// Used by HEX fonts.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int height)
|
||||||
|
: SourceData (sourcedata)
|
||||||
|
{
|
||||||
|
SourceWidth = swidth;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
LeftOffset = 0;
|
||||||
|
TopOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFontChar :: Get8BitPixels
|
||||||
|
//
|
||||||
|
// The render style has no relevance here.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
TArray<uint8_t> FHexFontChar::CreatePalettedPixels(int)
|
||||||
|
{
|
||||||
|
int destSize = Width * Height;
|
||||||
|
TArray<uint8_t> Pixels(destSize, true);
|
||||||
|
uint8_t *dest_p = Pixels.Data();
|
||||||
|
const uint8_t *src_p = SourceData;
|
||||||
|
|
||||||
|
memset(dest_p, 0, destSize);
|
||||||
|
for (int y = 0; y < Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < SourceWidth; x++)
|
||||||
|
{
|
||||||
|
int byte = *src_p++;
|
||||||
|
uint8_t *pixelstart = dest_p + 8 * x * Height + y;
|
||||||
|
for (int bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (128 >> bit))
|
||||||
|
{
|
||||||
|
pixelstart[bit*Height] = y+2;
|
||||||
|
// Add a shadow at the bottom right, similar to the old console font.
|
||||||
|
if (y != Height - 1)
|
||||||
|
{
|
||||||
|
pixelstart[bit*Height + Height + 1] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FHexFontChar2 : public FHexFontChar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height);
|
||||||
|
|
||||||
|
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFontChar :: FHexFontChar
|
||||||
|
//
|
||||||
|
// Used by HEX fonts.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FHexFontChar2::FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height)
|
||||||
|
: FHexFontChar(sourcedata, swidth, width, height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFontChar :: Get8BitPixels
|
||||||
|
//
|
||||||
|
// The render style has no relevance here.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
TArray<uint8_t> FHexFontChar2::CreatePalettedPixels(int)
|
||||||
|
{
|
||||||
|
int destSize = Width * Height;
|
||||||
|
TArray<uint8_t> Pixels(destSize, true);
|
||||||
|
uint8_t *dest_p = Pixels.Data();
|
||||||
|
|
||||||
|
auto drawLayer = [&](int ix, int iy, int color)
|
||||||
|
{
|
||||||
|
const uint8_t *src_p = SourceData;
|
||||||
|
for (int y = 0; y < Height-2; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < SourceWidth; x++)
|
||||||
|
{
|
||||||
|
int byte = *src_p++;
|
||||||
|
uint8_t *pixelstart = dest_p + (ix + 8 * x) * Height + (iy+y);
|
||||||
|
for (int bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (128 >> bit))
|
||||||
|
{
|
||||||
|
pixelstart[bit*Height] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
memset(dest_p, 0, destSize);
|
||||||
|
|
||||||
|
const int darkcolor = 3;
|
||||||
|
const int brightcolor = 14;
|
||||||
|
for (int xx=0;xx<3;xx++) for (int yy=0;yy<3;yy++) if (xx !=1 || yy != 1)
|
||||||
|
drawLayer(xx, yy, darkcolor);
|
||||||
|
drawLayer(1, 1, brightcolor);
|
||||||
|
|
||||||
|
return Pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FHexFont : public FFont
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFont :: FHexFont
|
||||||
|
//
|
||||||
|
// Loads a HEX font
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FHexFont (const char *fontname, int lump)
|
||||||
|
: FFont(lump)
|
||||||
|
{
|
||||||
|
assert(lump >= 0);
|
||||||
|
|
||||||
|
FontName = fontname;
|
||||||
|
|
||||||
|
FirstChar = hexdata.FirstChar;
|
||||||
|
LastChar = hexdata.LastChar;
|
||||||
|
|
||||||
|
Next = FirstFont;
|
||||||
|
FirstFont = this;
|
||||||
|
FontHeight = 16;
|
||||||
|
SpaceWidth = 9;
|
||||||
|
GlobalKerning = 0;
|
||||||
|
translateUntranslated = true;
|
||||||
|
|
||||||
|
LoadTranslations();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFont :: LoadTranslations
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void LoadTranslations()
|
||||||
|
{
|
||||||
|
const int spacing = 9;
|
||||||
|
double luminosity[256];
|
||||||
|
|
||||||
|
memset (PatchRemap, 0, 256);
|
||||||
|
for (int i = 0; i < 18; i++)
|
||||||
|
{
|
||||||
|
// Create a gradient similar to the old console font.
|
||||||
|
PatchRemap[i] = i;
|
||||||
|
luminosity[i] = i == 1? 0.01 : 0.5 + (i-2) * (0.5 / 17.);
|
||||||
|
}
|
||||||
|
ActiveColors = 18;
|
||||||
|
|
||||||
|
Chars.Resize(LastChar - FirstChar + 1);
|
||||||
|
for (int i = FirstChar; i <= LastChar; i++)
|
||||||
|
{
|
||||||
|
if (hexdata.glyphmap[i] > 0)
|
||||||
|
{
|
||||||
|
auto offset = hexdata.glyphmap[i];
|
||||||
|
int size = hexdata.glyphdata[offset] / 16;
|
||||||
|
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16));
|
||||||
|
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||||
|
Chars[i - FirstChar].XMove = size * spacing;
|
||||||
|
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
||||||
|
}
|
||||||
|
else Chars[i - FirstChar].XMove = spacing;
|
||||||
|
|
||||||
|
}
|
||||||
|
BuildTranslations (luminosity, nullptr, &TranslationParms[1][0], ActiveColors, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FHexFont2 : public FFont
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFont :: FHexFont
|
||||||
|
//
|
||||||
|
// Loads a HEX font
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FHexFont2(const char *fontname, int lump)
|
||||||
|
: FFont(lump)
|
||||||
|
{
|
||||||
|
assert(lump >= 0);
|
||||||
|
|
||||||
|
FontName = fontname;
|
||||||
|
|
||||||
|
FirstChar = hexdata.FirstChar;
|
||||||
|
LastChar = hexdata.LastChar;
|
||||||
|
|
||||||
|
Next = FirstFont;
|
||||||
|
FirstFont = this;
|
||||||
|
FontHeight = 18;
|
||||||
|
SpaceWidth = 10;
|
||||||
|
GlobalKerning = -1;
|
||||||
|
translateUntranslated = true;
|
||||||
|
|
||||||
|
LoadTranslations();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FHexFont :: LoadTranslations
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void LoadTranslations()
|
||||||
|
{
|
||||||
|
const int spacing = 9;
|
||||||
|
double luminosity[256];
|
||||||
|
|
||||||
|
memset(PatchRemap, 0, 256);
|
||||||
|
for (int i = 0; i < 18; i++)
|
||||||
|
{
|
||||||
|
// Create a gradient similar to the old console font.
|
||||||
|
PatchRemap[i] = i;
|
||||||
|
luminosity[i] = i / 17.;
|
||||||
|
}
|
||||||
|
ActiveColors = 18;
|
||||||
|
|
||||||
|
Chars.Resize(LastChar - FirstChar + 1);
|
||||||
|
for (int i = FirstChar; i <= LastChar; i++)
|
||||||
|
{
|
||||||
|
if (hexdata.glyphmap[i] > 0)
|
||||||
|
{
|
||||||
|
auto offset = hexdata.glyphmap[i];
|
||||||
|
int size = hexdata.glyphdata[offset] / 16;
|
||||||
|
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18));
|
||||||
|
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||||
|
Chars[i - FirstChar].XMove = size * spacing;
|
||||||
|
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
||||||
|
}
|
||||||
|
else Chars[i - FirstChar].XMove = spacing;
|
||||||
|
|
||||||
|
}
|
||||||
|
BuildTranslations(luminosity, nullptr, &TranslationParms[0][0], ActiveColors, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FFont *CreateHexLumpFont (const char *fontname, int lump)
|
||||||
|
{
|
||||||
|
if (hexdata.FirstChar == INT_MAX) hexdata.ParseDefinition(lump);
|
||||||
|
return new FHexFont(fontname, lump);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FFont *CreateHexLumpFont2(const char *fontname, int lump)
|
||||||
|
{
|
||||||
|
if (hexdata.FirstChar == INT_MAX) hexdata.ParseDefinition(lump);
|
||||||
|
return new FHexFont2(fontname, lump);
|
||||||
|
}
|
|
@ -122,6 +122,7 @@ static const uint16_t loweruppercase[] = {
|
||||||
0x0078,0x0058,
|
0x0078,0x0058,
|
||||||
0x0079,0x0059,
|
0x0079,0x0059,
|
||||||
0x007A,0x005A,
|
0x007A,0x005A,
|
||||||
|
0x00DF,0x1E9E,
|
||||||
0x00E0,0x00C0,
|
0x00E0,0x00C0,
|
||||||
0x00E1,0x00C1,
|
0x00E1,0x00C1,
|
||||||
0x00E2,0x00C2,
|
0x00E2,0x00C2,
|
||||||
|
@ -838,8 +839,17 @@ int stripaccent(int code)
|
||||||
}
|
}
|
||||||
else if (code >= 0x100 && code < 0x180)
|
else if (code >= 0x100 && code < 0x180)
|
||||||
{
|
{
|
||||||
static const char accentless[] = "AaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnNnOoOoOoOoRrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZz ";
|
// For the double-accented Hungarian letters it makes more sense to first map them to the very similar looking Umlauts.
|
||||||
return accentless[code -0x100];
|
// (And screw the crappy specs here that do not allow UTF-8 multibyte characters here.)
|
||||||
|
if (code == 0x150) code = 0xd6;
|
||||||
|
else if (code == 0x151) code = 0xf6;
|
||||||
|
else if (code == 0x170) code = 0xdc;
|
||||||
|
else if (code == 0x171) code = 0xfc;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const char accentless[] = "AaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnNnOoOoOoOoRrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZz ";
|
||||||
|
return accentless[code - 0x100];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (code >= 0x200 && code < 0x21c)
|
else if (code >= 0x200 && code < 0x21c)
|
||||||
{
|
{
|
||||||
|
@ -847,6 +857,11 @@ int stripaccent(int code)
|
||||||
static const uint16_t u200map[] = {0xc4, 0xe4, 0xc2, 0xe2, 0xcb, 0xeb, 0xca, 0xea, 0xcf, 0xef, 0xce, 0xee, 0xd6, 0xf6, 0xd4, 0xe4, 'R', 'r', 'R', 'r', 0xdc, 0xfc, 0xdb, 0xfb, 0x15e, 0x15f, 0x162, 0x163};
|
static const uint16_t u200map[] = {0xc4, 0xe4, 0xc2, 0xe2, 0xcb, 0xeb, 0xca, 0xea, 0xcf, 0xef, 0xce, 0xee, 0xd6, 0xf6, 0xd4, 0xe4, 'R', 'r', 'R', 'r', 0xdc, 0xfc, 0xdb, 0xfb, 0x15e, 0x15f, 0x162, 0x163};
|
||||||
return u200map[code - 0x200];
|
return u200map[code - 0x200];
|
||||||
}
|
}
|
||||||
|
else if (code == 0x201d)
|
||||||
|
{
|
||||||
|
// Map the typographic upper quotation mark to the generic form
|
||||||
|
code = '"';
|
||||||
|
}
|
||||||
|
|
||||||
// skip the rest of Latin characters because none of them are relevant for modern languages.
|
// skip the rest of Latin characters because none of them are relevant for modern languages.
|
||||||
|
|
||||||
|
@ -855,7 +870,8 @@ int stripaccent(int code)
|
||||||
|
|
||||||
FFont *V_GetFont(const char *name, const char *fontlumpname)
|
FFont *V_GetFont(const char *name, const char *fontlumpname)
|
||||||
{
|
{
|
||||||
if (!stricmp(name, "CONFONT")) name = "ConsoleFont"; // several mods have used the name CONFONT directly and effectively duplicated the font.
|
if (!stricmp(name, "DBIGFONT")) name = "BigFont"; // several mods have used the name CONFONT directly and effectively duplicated the font.
|
||||||
|
else if (!stricmp(name, "CONFONT")) name = "ConsoleFont"; // several mods have used the name CONFONT directly and effectively duplicated the font.
|
||||||
FFont *font = FFont::FindFont (name);
|
FFont *font = FFont::FindFont (name);
|
||||||
if (font == nullptr)
|
if (font == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1432,6 +1448,15 @@ void V_InitFonts()
|
||||||
InitLowerUpper();
|
InitLowerUpper();
|
||||||
V_InitCustomFonts();
|
V_InitCustomFonts();
|
||||||
|
|
||||||
|
FFont *CreateHexLumpFont(const char *fontname, int lump);
|
||||||
|
FFont *CreateHexLumpFont2(const char *fontname, int lump);
|
||||||
|
|
||||||
|
auto lump = Wads.CheckNumForFullName("newconsolefont.hex", 0); // This is always loaded from gzdoom.pk3 to prevent overriding it with incomplete replacements.
|
||||||
|
if (lump == -1) I_FatalError("newconsolefont.hex not found"); // This font is needed - do not start up without it.
|
||||||
|
NewConsoleFont = CreateHexLumpFont("NewConsoleFont", lump);
|
||||||
|
NewSmallFont = CreateHexLumpFont2("NewSmallFont", lump);
|
||||||
|
CurrentConsoleFont = NewConsoleFont;
|
||||||
|
|
||||||
// load the heads-up font
|
// load the heads-up font
|
||||||
if (!(SmallFont = V_GetFont("SmallFont", "SMALLFNT")))
|
if (!(SmallFont = V_GetFont("SmallFont", "SMALLFNT")))
|
||||||
{
|
{
|
||||||
|
@ -1517,6 +1542,6 @@ void V_ClearFonts()
|
||||||
delete FFont::FirstFont;
|
delete FFont::FirstFont;
|
||||||
}
|
}
|
||||||
FFont::FirstFont = nullptr;
|
FFont::FirstFont = nullptr;
|
||||||
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr;
|
CurrentConsoleFont = NewSmallFont = NewConsoleFont = SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont;
|
extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont;
|
||||||
|
|
||||||
void V_InitFonts();
|
void V_InitFonts();
|
||||||
void V_ClearFonts();
|
void V_ClearFonts();
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
@ -74,6 +75,9 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
||||||
bool lastWasSpace = false;
|
bool lastWasSpace = false;
|
||||||
int kerning = font->GetDefaultKerning ();
|
int kerning = font->GetDefaultKerning ();
|
||||||
|
|
||||||
|
// The real isspace is a bit too badly defined, so use our own one
|
||||||
|
auto myisspace = [](int ch) { return ch == '\t' || ch == '\r' || ch == '\n' || ch == ' '; };
|
||||||
|
|
||||||
w = 0;
|
w = 0;
|
||||||
|
|
||||||
while ( (c = GetCharFromString(string)) )
|
while ( (c = GetCharFromString(string)) )
|
||||||
|
@ -103,7 +107,7 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iswspace(c))
|
if (myisspace(c))
|
||||||
{
|
{
|
||||||
if (!lastWasSpace)
|
if (!lastWasSpace)
|
||||||
{
|
{
|
||||||
|
@ -136,12 +140,12 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
||||||
start = space;
|
start = space;
|
||||||
space = NULL;
|
space = NULL;
|
||||||
|
|
||||||
while (*start && iswspace (*start) && *start != '\n')
|
while (*start && myisspace (*start) && *start != '\n')
|
||||||
start++;
|
start++;
|
||||||
if (*start == '\n')
|
if (*start == '\n')
|
||||||
start++;
|
start++;
|
||||||
else
|
else
|
||||||
while (*start && iswspace (*start))
|
while (*start && myisspace (*start))
|
||||||
start++;
|
start++;
|
||||||
string = start;
|
string = start;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +163,7 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
||||||
while (s < string)
|
while (s < string)
|
||||||
{
|
{
|
||||||
// If there is any non-white space in the remainder of the string, add it.
|
// If there is any non-white space in the remainder of the string, add it.
|
||||||
if (!iswspace (*s++))
|
if (!myisspace (*s++))
|
||||||
{
|
{
|
||||||
auto i = Lines.Reserve(1);
|
auto i = Lines.Reserve(1);
|
||||||
breakit (&Lines[i], font, start, string, linecolor);
|
breakit (&Lines[i], font, start, string, linecolor);
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct FBrokenLines
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXTCOLOR_ESCAPE '\034'
|
#define TEXTCOLOR_ESCAPE '\034'
|
||||||
|
#define TEXTCOLOR_ESCAPESTR "\034"
|
||||||
|
|
||||||
#define TEXTCOLOR_BRICK "\034A"
|
#define TEXTCOLOR_BRICK "\034A"
|
||||||
#define TEXTCOLOR_TAN "\034B"
|
#define TEXTCOLOR_TAN "\034B"
|
||||||
|
@ -85,6 +86,4 @@ inline TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const char
|
||||||
inline TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false)
|
inline TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false)
|
||||||
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor); }
|
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor); }
|
||||||
|
|
||||||
int GetCharFromString(const uint8_t *&string);
|
|
||||||
|
|
||||||
#endif //__V_TEXT_H__
|
#endif //__V_TEXT_H__
|
||||||
|
|
|
@ -2019,7 +2019,7 @@ void FMapInfoParser::ParseEpisodeInfo ()
|
||||||
{
|
{
|
||||||
ParseAssign();
|
ParseAssign();
|
||||||
sc.MustGetString ();
|
sc.MustGetString ();
|
||||||
name = sc.String;
|
name = strbin1(sc.String);
|
||||||
}
|
}
|
||||||
else if (sc.Compare ("picname"))
|
else if (sc.Compare ("picname"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -214,7 +214,7 @@ void FMapInfoParser::ParseSkill ()
|
||||||
{
|
{
|
||||||
ParseAssign();
|
ParseAssign();
|
||||||
sc.MustGetString ();
|
sc.MustGetString ();
|
||||||
skill.MenuName = sc.String;
|
skill.MenuName = strbin1(sc.String);
|
||||||
}
|
}
|
||||||
else if (sc.Compare("PlayerClassName"))
|
else if (sc.Compare("PlayerClassName"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -397,6 +397,7 @@ void FMapInfoParser::ParseGameInfo()
|
||||||
GAMEINFOKEY_BOOL(dontcrunchcorpses, "dontcrunchcorpses")
|
GAMEINFOKEY_BOOL(dontcrunchcorpses, "dontcrunchcorpses")
|
||||||
GAMEINFOKEY_BOOL(correctprintbold, "correctprintbold")
|
GAMEINFOKEY_BOOL(correctprintbold, "correctprintbold")
|
||||||
GAMEINFOKEY_BOOL(forcetextinmenus, "forcetextinmenus")
|
GAMEINFOKEY_BOOL(forcetextinmenus, "forcetextinmenus")
|
||||||
|
GAMEINFOKEY_BOOL(forcenogfxsubstitution, "forcenogfxsubstitution")
|
||||||
GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter")
|
GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter")
|
||||||
GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast")
|
GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast")
|
||||||
GAMEINFOKEY_COLOR(dimcolor, "dimcolor")
|
GAMEINFOKEY_COLOR(dimcolor, "dimcolor")
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct gameinfo_t
|
||||||
bool dontcrunchcorpses;
|
bool dontcrunchcorpses;
|
||||||
bool correctprintbold;
|
bool correctprintbold;
|
||||||
bool forcetextinmenus;
|
bool forcetextinmenus;
|
||||||
|
bool forcenogfxsubstitution;
|
||||||
TArray<FName> creditPages;
|
TArray<FName> creditPages;
|
||||||
TArray<FName> finalePages;
|
TArray<FName> finalePages;
|
||||||
TArray<FName> infoPages;
|
TArray<FName> infoPages;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
|
|
@ -464,7 +464,7 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level)
|
||||||
section.ToUpper();
|
section.ToUpper();
|
||||||
|
|
||||||
const char *ep_name = StartEpisode->mEpisodeName;
|
const char *ep_name = StartEpisode->mEpisodeName;
|
||||||
if (*ep_name == '$') ep_name = GStrings[ep_name+1];
|
if (*ep_name == '$') ep_name = GStrings(ep_name+1);
|
||||||
FStatistics *sl = GetStatisticsList(EpisodeStatistics, section, ep_name);
|
FStatistics *sl = GetStatisticsList(EpisodeStatistics, section, ep_name);
|
||||||
|
|
||||||
int statvals[6] = {0,0,0,0,0,0};
|
int statvals[6] = {0,0,0,0,0,0};
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "xlsxread/xlsxio_read.h"
|
#include "xlsxread/xlsxio_read.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(String, language)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -63,7 +64,6 @@ void FStringTable::LoadStrings ()
|
||||||
if (!LoadLanguageFromSpreadsheet(lump))
|
if (!LoadLanguageFromSpreadsheet(lump))
|
||||||
LoadLanguage (lump);
|
LoadLanguage (lump);
|
||||||
}
|
}
|
||||||
SetLanguageIDs();
|
|
||||||
UpdateLanguage();
|
UpdateLanguage();
|
||||||
allMacros.Clear();
|
allMacros.Clear();
|
||||||
}
|
}
|
||||||
|
@ -150,13 +150,15 @@ bool FStringTable::readSheetIntoTable(xlsxioreader reader, const char *sheetname
|
||||||
int column = 0;
|
int column = 0;
|
||||||
char *value;
|
char *value;
|
||||||
table.Reserve(1);
|
table.Reserve(1);
|
||||||
|
auto myisspace = [](int ch) { return ch == '\t' || ch == '\r' || ch == '\n' || ch == ' '; };
|
||||||
|
|
||||||
while ((value = xlsxioread_sheet_next_cell(sheet)) != nullptr)
|
while ((value = xlsxioread_sheet_next_cell(sheet)) != nullptr)
|
||||||
{
|
{
|
||||||
auto vcopy = value;
|
auto vcopy = value;
|
||||||
if (table.Size() <= (unsigned)row) table.Reserve(1);
|
if (table.Size() <= (unsigned)row) table.Reserve(1);
|
||||||
while (*vcopy && iswspace((unsigned char)*vcopy)) vcopy++; // skip over leaading whitespace;
|
while (*vcopy && myisspace((unsigned char)*vcopy)) vcopy++; // skip over leaading whitespace;
|
||||||
auto vend = vcopy + strlen(vcopy);
|
auto vend = vcopy + strlen(vcopy);
|
||||||
while (vend > vcopy && iswspace((unsigned char)vend[-1])) *--vend = 0; // skip over trailing whitespace
|
while (vend > vcopy && myisspace((unsigned char)vend[-1])) *--vend = 0; // skip over trailing whitespace
|
||||||
ProcessEscapes(vcopy);
|
ProcessEscapes(vcopy);
|
||||||
table[row].Push(vcopy);
|
table[row].Push(vcopy);
|
||||||
column++;
|
column++;
|
||||||
|
@ -354,7 +356,7 @@ void FStringTable::InsertString(int langid, FName label, const FString &string)
|
||||||
Printf("Bad macro in %s : %s\n", strlangid, label.GetChars());
|
Printf("Bad macro in %s : %s\n", strlangid, label.GetChars());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FString macroname(string.GetChars() + index + 2, endindex - index - 2);
|
FString macroname(te.strings[0].GetChars() + index + 2, endindex - index - 2);
|
||||||
FStringf lookupstr("%s/%s", strlangid, macroname.GetChars());
|
FStringf lookupstr("%s/%s", strlangid, macroname.GetChars());
|
||||||
FStringf replacee("@[%s]", macroname.GetChars());
|
FStringf replacee("@[%s]", macroname.GetChars());
|
||||||
FName lookupname(lookupstr, true);
|
FName lookupname(lookupstr, true);
|
||||||
|
@ -376,6 +378,12 @@ void FStringTable::InsertString(int langid, FName label, const FString &string)
|
||||||
|
|
||||||
void FStringTable::UpdateLanguage()
|
void FStringTable::UpdateLanguage()
|
||||||
{
|
{
|
||||||
|
size_t langlen = strlen(language);
|
||||||
|
|
||||||
|
int LanguageID = (langlen < 2 || langlen > 3) ?
|
||||||
|
MAKE_ID('e', 'n', 'u', '\0') :
|
||||||
|
MAKE_ID(language[0], language[1], language[2], '\0');
|
||||||
|
|
||||||
currentLanguageSet.Clear();
|
currentLanguageSet.Clear();
|
||||||
|
|
||||||
auto checkone = [&](uint32_t lang_id)
|
auto checkone = [&](uint32_t lang_id)
|
||||||
|
@ -387,11 +395,8 @@ void FStringTable::UpdateLanguage()
|
||||||
|
|
||||||
checkone(dehacked_table);
|
checkone(dehacked_table);
|
||||||
checkone(global_table);
|
checkone(global_table);
|
||||||
for (int i = 0; i < 4; ++i)
|
checkone(LanguageID);
|
||||||
{
|
checkone(LanguageID & MAKE_ID(0xff, 0xff, 0, 0));
|
||||||
checkone(LanguageIDs[i]);
|
|
||||||
checkone(LanguageIDs[i] & MAKE_ID(0xff, 0xff, 0, 0));
|
|
||||||
}
|
|
||||||
checkone(default_table);
|
checkone(default_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ TArray<uint8_t> FImageSource::GetPalettedPixels(int conversion)
|
||||||
int FImageSource::CopyPixels(FBitmap *bmp, int conversion)
|
int FImageSource::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source.
|
if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source.
|
||||||
PalEntry *palette = screen->GetPalette();
|
PalEntry *palette = GPalette.BaseColors;
|
||||||
for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values
|
for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values
|
||||||
auto ppix = CreatePalettedPixels(conversion);
|
auto ppix = CreatePalettedPixels(conversion);
|
||||||
bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr);
|
bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr);
|
||||||
|
|
|
@ -403,9 +403,11 @@ FTexture *FTextureManager::FindTexture(const char *texname, ETextureType usetype
|
||||||
// 3: Only replace if the string is not the default and the graphic comes from the IWAD. Never replace a localized graphic.
|
// 3: Only replace if the string is not the default and the graphic comes from the IWAD. Never replace a localized graphic.
|
||||||
// 4: Like 1, but lets localized graphics pass.
|
// 4: Like 1, but lets localized graphics pass.
|
||||||
//
|
//
|
||||||
|
// The default is 3, which only replaces known content with non-default texts.
|
||||||
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, cl_localizationmode,0, CVAR_ARCHIVE)
|
CUSTOM_CVAR(Int, cl_gfxlocalization, 3, CVAR_ARCHIVE)
|
||||||
{
|
{
|
||||||
if (self < 0 || self > 4) self = 0;
|
if (self < 0 || self > 4) self = 0;
|
||||||
}
|
}
|
||||||
|
@ -421,8 +423,8 @@ bool FTextureManager::OkForLocalization(FTextureID texnum, const char *substitut
|
||||||
if (!texnum.isValid()) return false;
|
if (!texnum.isValid()) return false;
|
||||||
|
|
||||||
// First the unconditional settings, 0='never' and 1='always'.
|
// First the unconditional settings, 0='never' and 1='always'.
|
||||||
if (cl_localizationmode == 1 || gameinfo.forcetextinmenus) return false;
|
if (cl_gfxlocalization == 1 || gameinfo.forcetextinmenus) return false;
|
||||||
if (cl_localizationmode == 0) return true;
|
if (cl_gfxlocalization == 0 || gameinfo.forcenogfxsubstitution) return true;
|
||||||
|
|
||||||
uint32_t langtable = 0;
|
uint32_t langtable = 0;
|
||||||
if (*substitute == '$') substitute = GStrings.GetString(substitute+1, &langtable);
|
if (*substitute == '$') substitute = GStrings.GetString(substitute+1, &langtable);
|
||||||
|
@ -433,11 +435,11 @@ bool FTextureManager::OkForLocalization(FTextureID texnum, const char *substitut
|
||||||
if (localizedTex != texnum.GetIndex()) return true; // Do not substitute a localized variant of the graphics patch.
|
if (localizedTex != texnum.GetIndex()) return true; // Do not substitute a localized variant of the graphics patch.
|
||||||
|
|
||||||
// For mode 4 we are done now.
|
// For mode 4 we are done now.
|
||||||
if (cl_localizationmode == 4) return false;
|
if (cl_gfxlocalization == 4) return false;
|
||||||
|
|
||||||
// Mode 2 and 3 must reject any text replacement from the default language tables.
|
// Mode 2 and 3 must reject any text replacement from the default language tables.
|
||||||
if ((langtable & MAKE_ID(255,0,0,0)) == MAKE_ID('*', 0, 0, 0)) return true; // Do not substitute if the string comes from the default table.
|
if ((langtable & MAKE_ID(255,0,0,0)) == MAKE_ID('*', 0, 0, 0)) return true; // Do not substitute if the string comes from the default table.
|
||||||
if (cl_localizationmode == 2) return false;
|
if (cl_gfxlocalization == 2) return false;
|
||||||
|
|
||||||
// Mode 3 must also reject substitutions for non-IWAD content.
|
// Mode 3 must also reject substitutions for non-IWAD content.
|
||||||
int file = Wads.GetLumpFile(Textures[texnum.GetIndex()].Texture->SourceLump);
|
int file = Wads.GetLumpFile(Textures[texnum.GetIndex()].Texture->SourceLump);
|
||||||
|
@ -1300,17 +1302,20 @@ int FTextureManager::PalCheck(int tex)
|
||||||
// FTextureManager :: PalCheck
|
// FTextureManager :: PalCheck
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
EXTERN_CVAR(String, language)
|
||||||
|
|
||||||
int FTextureManager::ResolveLocalizedTexture(int tex)
|
int FTextureManager::ResolveLocalizedTexture(int tex)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 4; i++)
|
size_t langlen = strlen(language);
|
||||||
{
|
int lang = (langlen < 2 || langlen > 3) ?
|
||||||
uint32_t lang = LanguageIDs[i];
|
MAKE_ID('e', 'n', 'u', '\0') :
|
||||||
uint64_t index = (uint64_t(lang) << 32) + tex;
|
MAKE_ID(language[0], language[1], language[2], '\0');
|
||||||
if (auto pTex = LocalizedTextures.CheckKey(index)) return *pTex;
|
|
||||||
index = (uint64_t(lang & MAKE_ID(255, 255, 0, 0)) << 32) + tex;
|
uint64_t index = (uint64_t(lang) << 32) + tex;
|
||||||
if (auto pTex = LocalizedTextures.CheckKey(index)) return *pTex;
|
if (auto pTex = LocalizedTextures.CheckKey(index)) return *pTex;
|
||||||
}
|
index = (uint64_t(lang & MAKE_ID(255, 255, 0, 0)) << 32) + tex;
|
||||||
|
if (auto pTex = LocalizedTextures.CheckKey(index)) return *pTex;
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
FName MakeEndPic(const char *string);
|
FName MakeEndPic(const char *string);
|
||||||
|
|
||||||
|
@ -231,7 +232,7 @@ static int ParseStandardProperty(FScanner &scanner, UMapEntry *mape)
|
||||||
// add the given episode
|
// add the given episode
|
||||||
FEpisode epi;
|
FEpisode epi;
|
||||||
|
|
||||||
epi.mEpisodeName = split[1];
|
epi.mEpisodeName = strbin1(split[1]);
|
||||||
epi.mEpisodeMap = mape->MapName;
|
epi.mEpisodeMap = mape->MapName;
|
||||||
epi.mPicName = split[0];
|
epi.mPicName = split[0];
|
||||||
epi.mShortcut = split[2][0];
|
epi.mShortcut = split[2][0];
|
||||||
|
|
|
@ -211,7 +211,6 @@ int DIntermissionScreenFader::Responder (event_t *ev)
|
||||||
{
|
{
|
||||||
if (ev->type == EV_KeyDown)
|
if (ev->type == EV_KeyDown)
|
||||||
{
|
{
|
||||||
V_SetBlend(0,0,0,0);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return Super::Responder(ev);
|
return Super::Responder(ev);
|
||||||
|
@ -848,11 +847,11 @@ void DIntermissionController::OnDestroy ()
|
||||||
|
|
||||||
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
|
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
DIntermissionController::CurrentIntermission->Destroy();
|
DIntermissionController::CurrentIntermission->Destroy();
|
||||||
}
|
}
|
||||||
V_SetBlend (0,0,0,0);
|
|
||||||
S_StopAllChannels ();
|
S_StopAllChannels ();
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
gamestate = GS_FINALE;
|
gamestate = GS_FINALE;
|
||||||
|
@ -894,6 +893,7 @@ void F_StartIntermission(FName seq, uint8_t state)
|
||||||
|
|
||||||
bool F_Responder (event_t* ev)
|
bool F_Responder (event_t* ev)
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
return DIntermissionController::CurrentIntermission->Responder(ev);
|
return DIntermissionController::CurrentIntermission->Responder(ev);
|
||||||
|
@ -909,6 +909,7 @@ bool F_Responder (event_t* ev)
|
||||||
|
|
||||||
void F_Ticker ()
|
void F_Ticker ()
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
DIntermissionController::CurrentIntermission->Ticker();
|
DIntermissionController::CurrentIntermission->Ticker();
|
||||||
|
@ -923,6 +924,7 @@ void F_Ticker ()
|
||||||
|
|
||||||
void F_Drawer ()
|
void F_Drawer ()
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
DIntermissionController::CurrentIntermission->Drawer();
|
DIntermissionController::CurrentIntermission->Drawer();
|
||||||
|
@ -938,6 +940,7 @@ void F_Drawer ()
|
||||||
|
|
||||||
void F_EndFinale ()
|
void F_EndFinale ()
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
DIntermissionController::CurrentIntermission->Destroy();
|
DIntermissionController::CurrentIntermission->Destroy();
|
||||||
|
@ -953,6 +956,7 @@ void F_EndFinale ()
|
||||||
|
|
||||||
void F_AdvanceIntermission()
|
void F_AdvanceIntermission()
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
if (DIntermissionController::CurrentIntermission != NULL)
|
if (DIntermissionController::CurrentIntermission != NULL)
|
||||||
{
|
{
|
||||||
DIntermissionController::CurrentIntermission->mAdvance = true;
|
DIntermissionController::CurrentIntermission->mAdvance = true;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include "intermission/intermission.h"
|
#include "intermission/intermission.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
|
|
@ -612,12 +612,6 @@ void M_ScreenShot (const char *filename)
|
||||||
auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma);
|
auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma);
|
||||||
if (buffer.Size() > 0)
|
if (buffer.Size() > 0)
|
||||||
{
|
{
|
||||||
PalEntry palette[256];
|
|
||||||
|
|
||||||
if (color_type == SS_PAL)
|
|
||||||
{
|
|
||||||
screen->GetFlashedPalette(palette);
|
|
||||||
}
|
|
||||||
file = FileWriter::Open(autoname);
|
file = FileWriter::Open(autoname);
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
|
@ -626,12 +620,12 @@ void M_ScreenShot (const char *filename)
|
||||||
}
|
}
|
||||||
if (writepcx)
|
if (writepcx)
|
||||||
{
|
{
|
||||||
WritePCXfile(file, buffer.Data(), palette, color_type,
|
WritePCXfile(file, buffer.Data(), nullptr, color_type,
|
||||||
screen->GetWidth(), screen->GetHeight(), pitch);
|
screen->GetWidth(), screen->GetHeight(), pitch);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WritePNGfile(file, buffer.Data(), palette, color_type,
|
WritePNGfile(file, buffer.Data(), nullptr, color_type,
|
||||||
screen->GetWidth(), screen->GetHeight(), pitch, gamma);
|
screen->GetWidth(), screen->GetHeight(), pitch, gamma);
|
||||||
}
|
}
|
||||||
delete file;
|
delete file;
|
||||||
|
|
|
@ -478,8 +478,7 @@ unsigned FSavegameManager::ExtractSaveData(int index)
|
||||||
comment = time;
|
comment = time;
|
||||||
if (time.Len() > 0) comment += "\n";
|
if (time.Len() > 0) comment += "\n";
|
||||||
comment += pcomment;
|
comment += pcomment;
|
||||||
|
SaveCommentString = comment;
|
||||||
SaveComment = V_BreakLines(SmallFont, WindowSize, comment.GetChars());
|
|
||||||
|
|
||||||
// Extract pic
|
// Extract pic
|
||||||
FResourceLump *pic = resf->FindLump("savepic.png");
|
FResourceLump *pic = resf->FindLump("savepic.png");
|
||||||
|
@ -533,9 +532,8 @@ void FSavegameManager::UnloadSaveData()
|
||||||
{
|
{
|
||||||
delete SavePic;
|
delete SavePic;
|
||||||
}
|
}
|
||||||
SaveComment.Clear();
|
|
||||||
SaveComment.ShrinkToFit();
|
|
||||||
|
|
||||||
|
SaveCommentString = "";
|
||||||
SavePic = nullptr;
|
SavePic = nullptr;
|
||||||
SavePicData.Clear();
|
SavePicData.Clear();
|
||||||
}
|
}
|
||||||
|
@ -592,46 +590,6 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, DrawSavePic)
|
||||||
ACTION_RETURN_BOOL(self->DrawSavePic(x, y, w, h));
|
ACTION_RETURN_BOOL(self->DrawSavePic(x, y, w, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void FSavegameManager::DrawSaveComment(FFont *font, int cr, int x, int y, int scalefactor)
|
|
||||||
{
|
|
||||||
int sx = CleanXfac;
|
|
||||||
int sy = CleanYfac;
|
|
||||||
|
|
||||||
CleanXfac = CleanYfac = scalefactor;
|
|
||||||
|
|
||||||
int maxlines = screen->GetHeight()>400?10:screen->GetHeight()>240?7:screen->GetHeight()>200?8:5;
|
|
||||||
if (SmallFont->GetHeight() > 9) maxlines--; // not Doom
|
|
||||||
// I'm not sure why SaveComment would go nullptr in this loop, but I got
|
|
||||||
// a crash report where it was nullptr when i reached 1, so now I check
|
|
||||||
// for that.
|
|
||||||
for (int i = 0; i < maxlines && (unsigned)i < SaveComment.Size(); ++i)
|
|
||||||
{
|
|
||||||
screen->DrawText(font, cr, x, y + font->GetHeight() * i * scalefactor, SaveComment[i].Text, DTA_CleanNoMove, true, TAG_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
CleanXfac = sx;
|
|
||||||
CleanYfac = sy;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FSavegameManager, DrawSaveComment)
|
|
||||||
{
|
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager);
|
|
||||||
PARAM_POINTER(fnt, FFont);
|
|
||||||
PARAM_INT(cr);
|
|
||||||
PARAM_INT(x);
|
|
||||||
PARAM_INT(y);
|
|
||||||
PARAM_INT(fac);
|
|
||||||
self->DrawSaveComment(fnt, cr, x, y, fac);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -642,9 +600,7 @@ void FSavegameManager::SetFileInfo(int Selected)
|
||||||
{
|
{
|
||||||
if (!SaveGames[Selected]->Filename.IsEmpty())
|
if (!SaveGames[Selected]->Filename.IsEmpty())
|
||||||
{
|
{
|
||||||
FString work;
|
SaveCommentString.Format("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars());
|
||||||
work.Format("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars());
|
|
||||||
SaveComment = V_BreakLines(SmallFont, WindowSize, work);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,4 +709,5 @@ DEFINE_FIELD(FSaveGameNode, bNoDelete);
|
||||||
|
|
||||||
DEFINE_FIELD(FSavegameManager, WindowSize);
|
DEFINE_FIELD(FSavegameManager, WindowSize);
|
||||||
DEFINE_FIELD(FSavegameManager, quickSaveSlot);
|
DEFINE_FIELD(FSavegameManager, quickSaveSlot);
|
||||||
|
DEFINE_FIELD(FSavegameManager, SaveCommentString);
|
||||||
|
|
||||||
|
|
|
@ -405,7 +405,7 @@ DEFINE_ACTION_FUNCTION(DMenu, ActivateMenu)
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
EXTERN_CVAR(Int, cl_localizationmode)
|
EXTERN_CVAR(Int, cl_gfxlocalization)
|
||||||
|
|
||||||
|
|
||||||
void M_SetMenu(FName menu, int param)
|
void M_SetMenu(FName menu, int param)
|
||||||
|
@ -420,7 +420,7 @@ void M_SetMenu(FName menu, int param)
|
||||||
{
|
{
|
||||||
menu = NAME_MainmenuTextOnly;
|
menu = NAME_MainmenuTextOnly;
|
||||||
}
|
}
|
||||||
else
|
else if (cl_gfxlocalization != 0 && !gameinfo.forcenogfxsubstitution)
|
||||||
{
|
{
|
||||||
// For these games we must check up-front if they get localized because in that case another template must be used.
|
// For these games we must check up-front if they get localized because in that case another template must be used.
|
||||||
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Mainmenu);
|
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Mainmenu);
|
||||||
|
@ -429,7 +429,7 @@ void M_SetMenu(FName menu, int param)
|
||||||
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
|
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
|
||||||
{
|
{
|
||||||
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
|
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
|
||||||
if (ld->mFromEngine && cl_localizationmode != 0)
|
if (ld->mFromEngine)
|
||||||
{
|
{
|
||||||
// This assumes that replacing one graphic will replace all of them.
|
// This assumes that replacing one graphic will replace all of them.
|
||||||
// So this only checks the "New game" entry for localization capability.
|
// So this only checks the "New game" entry for localization capability.
|
||||||
|
|
|
@ -74,10 +74,10 @@ private:
|
||||||
int LastAccessed = -1;
|
int LastAccessed = -1;
|
||||||
TArray<char> SavePicData;
|
TArray<char> SavePicData;
|
||||||
FTexture *SavePic = nullptr;
|
FTexture *SavePic = nullptr;
|
||||||
TArray<FBrokenLines> SaveComment;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int WindowSize = 0;
|
int WindowSize = 0;
|
||||||
|
FString SaveCommentString;
|
||||||
FSaveGameNode *quickSaveSlot = nullptr;
|
FSaveGameNode *quickSaveSlot = nullptr;
|
||||||
~FSavegameManager();
|
~FSavegameManager();
|
||||||
|
|
||||||
|
@ -363,4 +363,6 @@ DMenuItemBase * CreateListMenuItemPatch(double x, double y, int height, int hotk
|
||||||
DMenuItemBase * CreateListMenuItemText(double x, double y, int height, int hotkey, const char *text, FFont *font, PalEntry color1, PalEntry color2, FName command, int param);
|
DMenuItemBase * CreateListMenuItemText(double x, double y, int height, int hotkey, const char *text, FFont *font, PalEntry color1, PalEntry color2, FName command, int param);
|
||||||
DMenuItemBase * CreateOptionMenuItemCommand(const char *label, FName cmd, bool centered = false);
|
DMenuItemBase * CreateOptionMenuItemCommand(const char *label, FName cmd, bool centered = false);
|
||||||
|
|
||||||
|
void UpdateVRModes(bool considerQuadBuffered=true);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1724,3 +1724,31 @@ fail:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
EXTERN_CVAR(Bool, vr_enable_quadbuffered)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void UpdateVRModes(bool considerQuadBuffered)
|
||||||
|
{
|
||||||
|
FOptionValues ** pVRModes = OptionValues.CheckKey("VRMode");
|
||||||
|
if (pVRModes == nullptr) return;
|
||||||
|
|
||||||
|
TArray<FOptionValues::Pair> & vals = (*pVRModes)->mValues;
|
||||||
|
TArray<FOptionValues::Pair> filteredValues;
|
||||||
|
int cnt = vals.Size();
|
||||||
|
for (int i = 0; i < cnt; ++i) {
|
||||||
|
auto const & mode = vals[i];
|
||||||
|
if (mode.Value == 7) { // Quad-buffered stereo
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (!vr_enable_quadbuffered) continue;
|
||||||
|
#else
|
||||||
|
continue; // Remove quad-buffered option on Mac and Linux
|
||||||
|
#endif
|
||||||
|
if (!considerQuadBuffered) continue; // Probably no compatible screen mode was found
|
||||||
|
}
|
||||||
|
filteredValues.Push(mode);
|
||||||
|
}
|
||||||
|
vals = filteredValues;
|
||||||
|
}
|
||||||
|
|
|
@ -536,8 +536,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern FILE *Logfile;
|
|
||||||
|
|
||||||
FRandom pr_acs ("ACS");
|
FRandom pr_acs ("ACS");
|
||||||
|
|
||||||
// I imagine this much stack space is probably overkill, but it could
|
// I imagine this much stack space is probably overkill, but it could
|
||||||
|
@ -705,7 +703,7 @@ protected:
|
||||||
TObjPtr<AActor*> activator;
|
TObjPtr<AActor*> activator;
|
||||||
line_t *activationline;
|
line_t *activationline;
|
||||||
bool backSide;
|
bool backSide;
|
||||||
FFont *activefont;
|
FFont *activefont = nullptr;
|
||||||
int hudwidth, hudheight;
|
int hudwidth, hudheight;
|
||||||
int ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight;
|
int ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight;
|
||||||
int WrapWidth;
|
int WrapWidth;
|
||||||
|
@ -774,7 +772,7 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DLevelScript();
|
DLevelScript() = default;
|
||||||
|
|
||||||
friend class DACSThinker;
|
friend class DACSThinker;
|
||||||
};
|
};
|
||||||
|
@ -3506,11 +3504,6 @@ void DLevelScript::Serialize(FSerializer &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DLevelScript::DLevelScript ()
|
|
||||||
{
|
|
||||||
activefont = SmallFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DLevelScript::Unlink ()
|
void DLevelScript::Unlink ()
|
||||||
{
|
{
|
||||||
DACSThinker *controller = Level->ACSThinker;
|
DACSThinker *controller = Level->ACSThinker;
|
||||||
|
@ -3924,10 +3917,6 @@ void DLevelScript::DoSetFont (int fontnum)
|
||||||
{
|
{
|
||||||
const char *fontname = Level->Behaviors.LookupString (fontnum);
|
const char *fontname = Level->Behaviors.LookupString (fontnum);
|
||||||
activefont = V_GetFont (fontname);
|
activefont = V_GetFont (fontname);
|
||||||
if (activefont == NULL)
|
|
||||||
{
|
|
||||||
activefont = SmallFont;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DLevelScript::DoSetMaster (AActor *self, AActor *master)
|
int DLevelScript::DoSetMaster (AActor *self, AActor *master)
|
||||||
|
@ -8623,10 +8612,7 @@ scriptwait:
|
||||||
if (pcd == PCD_ENDPRINTBOLD || screen == NULL ||
|
if (pcd == PCD_ENDPRINTBOLD || screen == NULL ||
|
||||||
screen->CheckLocalView())
|
screen->CheckLocalView())
|
||||||
{
|
{
|
||||||
if (pcd == PCD_ENDPRINTBOLD && (gameinfo.correctprintbold || (Level->flags2 & LEVEL2_HEXENHACK)))
|
C_MidPrint (activefont, work, pcd == PCD_ENDPRINTBOLD && (gameinfo.correctprintbold || (Level->flags2 & LEVEL2_HEXENHACK)));
|
||||||
C_MidPrintBold(activefont, work);
|
|
||||||
else
|
|
||||||
C_MidPrint (activefont, work);
|
|
||||||
}
|
}
|
||||||
STRINGBUILDER_FINISH(work);
|
STRINGBUILDER_FINISH(work);
|
||||||
}
|
}
|
||||||
|
@ -8676,17 +8662,18 @@ scriptwait:
|
||||||
color = CLAMPCOLOR(Stack[optstart-4]);
|
color = CLAMPCOLOR(Stack[optstart-4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFont *font = activefont ? activefont : SmallFont;
|
||||||
switch (type & 0xFF)
|
switch (type & 0xFF)
|
||||||
{
|
{
|
||||||
default: // normal
|
default: // normal
|
||||||
alpha = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 1.f;
|
alpha = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 1.f;
|
||||||
msg = Create<DHUDMessage> (activefont, work, x, y, hudwidth, hudheight, color, holdTime);
|
msg = Create<DHUDMessage> (font, work, x, y, hudwidth, hudheight, color, holdTime);
|
||||||
break;
|
break;
|
||||||
case 1: // fade out
|
case 1: // fade out
|
||||||
{
|
{
|
||||||
float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f;
|
float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f;
|
||||||
alpha = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 1.f;
|
alpha = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 1.f;
|
||||||
msg = Create<DHUDMessageFadeOut> (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime);
|
msg = Create<DHUDMessageFadeOut> (font, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // type on, then fade out
|
case 2: // type on, then fade out
|
||||||
|
@ -8694,7 +8681,7 @@ scriptwait:
|
||||||
float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f;
|
float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f;
|
||||||
float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f;
|
float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f;
|
||||||
alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart+2]) : 1.f;
|
alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart+2]) : 1.f;
|
||||||
msg = Create<DHUDMessageTypeOnFadeOut> (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime);
|
msg = Create<DHUDMessageTypeOnFadeOut> (font, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // fade in, then fade out
|
case 3: // fade in, then fade out
|
||||||
|
@ -8702,7 +8689,7 @@ scriptwait:
|
||||||
float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f;
|
float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f;
|
||||||
float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f;
|
float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f;
|
||||||
alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart + 2]) : 1.f;
|
alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart + 2]) : 1.f;
|
||||||
msg = Create<DHUDMessageFadeInOut> (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime);
|
msg = Create<DHUDMessageFadeInOut> (font, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8728,17 +8715,8 @@ scriptwait:
|
||||||
(type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT);
|
(type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT);
|
||||||
if (type & HUDMSG_LOG)
|
if (type & HUDMSG_LOG)
|
||||||
{
|
{
|
||||||
static const char bar[] = TEXTCOLOR_ORANGE "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
int consolecolor = color >= CR_BRICK && color <= CR_YELLOW ? color + 'A' : '-';
|
||||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_NORMAL "\n";
|
Printf(PRINT_NONOTIFY, "\n" TEXTCOLOR_ESCAPESTR "%c%s\n%s\n%s\n", consolecolor, console_bar, work.GetChars(), console_bar);
|
||||||
char consolecolor[3];
|
|
||||||
|
|
||||||
consolecolor[0] = '\x1c';
|
|
||||||
consolecolor[1] = color >= CR_BRICK && color <= CR_YELLOW ? color + 'A' : '-';
|
|
||||||
consolecolor[2] = '\0';
|
|
||||||
AddToConsole (-1, bar);
|
|
||||||
AddToConsole (-1, consolecolor);
|
|
||||||
AddToConsole (-1, work);
|
|
||||||
AddToConsole (-1, bar);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10286,7 +10264,6 @@ DLevelScript::DLevelScript (FLevelLocals *l, AActor *who, line_t *where, int num
|
||||||
activator = who;
|
activator = who;
|
||||||
activationline = where;
|
activationline = where;
|
||||||
backSide = flags & ACS_BACKSIDE;
|
backSide = flags & ACS_BACKSIDE;
|
||||||
activefont = SmallFont;
|
|
||||||
hudwidth = hudheight = 0;
|
hudwidth = hudheight = 0;
|
||||||
ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0;
|
ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0;
|
||||||
HandleAspect = true;
|
HandleAspect = true;
|
||||||
|
|
|
@ -1309,7 +1309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Print)
|
||||||
con_midtime = float(time);
|
con_midtime = float(time);
|
||||||
}
|
}
|
||||||
FString formatted = strbin1(text);
|
FString formatted = strbin1(text);
|
||||||
C_MidPrint(font != NULL ? font : SmallFont, formatted.GetChars());
|
C_MidPrint(font, formatted.GetChars());
|
||||||
con_midtime = saved;
|
con_midtime = saved;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1341,7 +1341,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PrintBold)
|
||||||
con_midtime = float(time);
|
con_midtime = float(time);
|
||||||
}
|
}
|
||||||
FString formatted = strbin1(text);
|
FString formatted = strbin1(text);
|
||||||
C_MidPrintBold(font != NULL ? font : SmallFont, formatted.GetChars());
|
C_MidPrint(font, formatted.GetChars(), true);
|
||||||
con_midtime = saved;
|
con_midtime = saved;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -695,8 +695,7 @@ static void TerminalResponse (const char *str)
|
||||||
|
|
||||||
if (StatusBar != NULL)
|
if (StatusBar != NULL)
|
||||||
{
|
{
|
||||||
AddToConsole(-1, str);
|
Printf(PRINT_NONOTIFY, "%s\n", str);
|
||||||
AddToConsole(-1, "\n");
|
|
||||||
// The message is positioned a bit above the menu choices, because
|
// The message is positioned a bit above the menu choices, because
|
||||||
// merchants can tell you something like this but continue to show
|
// merchants can tell you something like this but continue to show
|
||||||
// their dialogue screen. I think most other conversations use this
|
// their dialogue screen. I think most other conversations use this
|
||||||
|
|
|
@ -98,7 +98,7 @@ CVAR(Int, sv_smartaim, 0, CVAR_ARCHIVE | CVAR_SERVERINFO)
|
||||||
CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE)
|
CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE)
|
||||||
|
|
||||||
static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 * posforwindowcheck = NULL);
|
static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 * posforwindowcheck = NULL);
|
||||||
static void SpawnShootDecal(AActor *t1, const FTraceResults &trace);
|
static void SpawnShootDecal(AActor *t1, AActor *defaults, const FTraceResults &trace);
|
||||||
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff);
|
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff);
|
||||||
|
|
||||||
static FRandom pr_tracebleed("TraceBleed");
|
static FRandom pr_tracebleed("TraceBleed");
|
||||||
|
@ -4566,20 +4566,20 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
{
|
{
|
||||||
// [ZK] If puff has FORCEDECAL set, do not use the weapon's decal
|
// [ZK] If puff has FORCEDECAL set, do not use the weapon's decal
|
||||||
if (puffDefaults->flags7 & MF7_FORCEDECAL && puff != NULL && puff->DecalGenerator)
|
if (puffDefaults->flags7 & MF7_FORCEDECAL && puff != NULL && puff->DecalGenerator)
|
||||||
SpawnShootDecal(puff, trace);
|
SpawnShootDecal(puff, puff, trace);
|
||||||
else
|
else
|
||||||
SpawnShootDecal(t1, trace);
|
SpawnShootDecal(t1, t1, trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else, look if the bulletpuff has a decal defined.
|
// Else, look if the bulletpuff has a decal defined.
|
||||||
else if (puff != NULL && puff->DecalGenerator)
|
else if (puff != NULL && puff->DecalGenerator)
|
||||||
{
|
{
|
||||||
SpawnShootDecal(puff, trace);
|
SpawnShootDecal(puff, puff, trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpawnShootDecal(t1, trace);
|
SpawnShootDecal(t1, t1, trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (puff != NULL &&
|
else if (puff != NULL &&
|
||||||
|
@ -5266,9 +5266,9 @@ void P_RailAttack(FRailParams *p)
|
||||||
puff->Destroy();
|
puff->Destroy();
|
||||||
}
|
}
|
||||||
if (puffDefaults != nullptr && puffDefaults->flags7 & MF7_FORCEDECAL && puffDefaults->DecalGenerator)
|
if (puffDefaults != nullptr && puffDefaults->flags7 & MF7_FORCEDECAL && puffDefaults->DecalGenerator)
|
||||||
SpawnShootDecal(puffDefaults, trace);
|
SpawnShootDecal(source, puffDefaults, trace);
|
||||||
else
|
else
|
||||||
SpawnShootDecal(source, trace);
|
SpawnShootDecal(source, source, trace);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (trace.HitType == TRACE_HitFloor || trace.HitType == TRACE_HitCeiling)
|
if (trace.HitType == TRACE_HitFloor || trace.HitType == TRACE_HitCeiling)
|
||||||
|
@ -6744,19 +6744,19 @@ bool P_ChangeSector(sector_t *sector, int crunch, double amt, int floorOrCeil, b
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
|
void SpawnShootDecal(AActor *t1, AActor *defaults, const FTraceResults &trace)
|
||||||
{
|
{
|
||||||
FDecalBase *decalbase = NULL;
|
FDecalBase *decalbase = nullptr;
|
||||||
|
|
||||||
if (t1->player != NULL && t1->player->ReadyWeapon != NULL)
|
if (defaults->player != nullptr && defaults->player->ReadyWeapon != nullptr)
|
||||||
{
|
{
|
||||||
decalbase = t1->player->ReadyWeapon->DecalGenerator;
|
decalbase = defaults->player->ReadyWeapon->DecalGenerator;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decalbase = t1->DecalGenerator;
|
decalbase = defaults->DecalGenerator;
|
||||||
}
|
}
|
||||||
if (decalbase != NULL)
|
if (decalbase != nullptr)
|
||||||
{
|
{
|
||||||
DImpactDecal::StaticCreate(t1->Level, decalbase->GetDecal(),
|
DImpactDecal::StaticCreate(t1->Level, decalbase->GetDecal(),
|
||||||
trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor);
|
trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor);
|
||||||
|
|
|
@ -813,8 +813,7 @@ void FLevelLocals::CopyPlayer(player_t *dst, player_t *src, const char *name)
|
||||||
bool attackdown = dst->attackdown;
|
bool attackdown = dst->attackdown;
|
||||||
bool usedown = dst->usedown;
|
bool usedown = dst->usedown;
|
||||||
|
|
||||||
|
dst->CopyFrom(*src, true); // To avoid memory leaks at this point the userinfo in src must be empty which is taken care of by the TransferFrom call above.
|
||||||
*dst = *src; // To avoid memory leaks at this point the userinfo in src must be empty which is taken care of by the TransferFrom call above.
|
|
||||||
|
|
||||||
dst->cheats |= chasecam;
|
dst->cheats |= chasecam;
|
||||||
|
|
||||||
|
@ -857,9 +856,6 @@ void FLevelLocals::CopyPlayer(player_t *dst, player_t *src, const char *name)
|
||||||
pspr = pspr->Next;
|
pspr = pspr->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't let the psprites be destroyed when src is destroyed.
|
|
||||||
src->psprites = nullptr;
|
|
||||||
|
|
||||||
// These 2 variables may not be overwritten.
|
// These 2 variables may not be overwritten.
|
||||||
dst->attackdown = attackdown;
|
dst->attackdown = attackdown;
|
||||||
dst->usedown = usedown;
|
dst->usedown = usedown;
|
||||||
|
|
|
@ -592,12 +592,12 @@ void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool pl
|
||||||
{
|
{
|
||||||
if (printmessage)
|
if (printmessage)
|
||||||
{
|
{
|
||||||
if (!showsecretsector || sectornum < 0) C_MidPrint(SmallFont, GStrings["SECRETMESSAGE"]);
|
if (!showsecretsector || sectornum < 0) C_MidPrint(nullptr, GStrings["SECRETMESSAGE"]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString s = GStrings["SECRETMESSAGE"];
|
FString s = GStrings["SECRETMESSAGE"];
|
||||||
s.AppendFormat(" (Sector %d)", sectornum);
|
s.AppendFormat(" (Sector %d)", sectornum);
|
||||||
C_MidPrint(SmallFont, s);
|
C_MidPrint(nullptr, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM);
|
if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM);
|
||||||
|
|
|
@ -259,7 +259,7 @@ player_t::~player_t()
|
||||||
DestroyPSprites();
|
DestroyPSprites();
|
||||||
}
|
}
|
||||||
|
|
||||||
player_t &player_t::operator=(const player_t &p)
|
void player_t::CopyFrom(player_t &p, bool copyPSP)
|
||||||
{
|
{
|
||||||
mo = p.mo;
|
mo = p.mo;
|
||||||
playerstate = p.playerstate;
|
playerstate = p.playerstate;
|
||||||
|
@ -312,7 +312,6 @@ player_t &player_t::operator=(const player_t &p)
|
||||||
extralight = p.extralight;
|
extralight = p.extralight;
|
||||||
fixedcolormap = p.fixedcolormap;
|
fixedcolormap = p.fixedcolormap;
|
||||||
fixedlightlevel = p.fixedlightlevel;
|
fixedlightlevel = p.fixedlightlevel;
|
||||||
psprites = p.psprites;
|
|
||||||
morphTics = p.morphTics;
|
morphTics = p.morphTics;
|
||||||
MorphedPlayerClass = p.MorphedPlayerClass;
|
MorphedPlayerClass = p.MorphedPlayerClass;
|
||||||
MorphStyle = p.MorphStyle;
|
MorphStyle = p.MorphStyle;
|
||||||
|
@ -346,7 +345,12 @@ player_t &player_t::operator=(const player_t &p)
|
||||||
ConversationFaceTalker = p.ConversationFaceTalker;
|
ConversationFaceTalker = p.ConversationFaceTalker;
|
||||||
MUSINFOactor = p.MUSINFOactor;
|
MUSINFOactor = p.MUSINFOactor;
|
||||||
MUSINFOtics = p.MUSINFOtics;
|
MUSINFOtics = p.MUSINFOtics;
|
||||||
return *this;
|
if (copyPSP)
|
||||||
|
{
|
||||||
|
// This needs to transfer ownership completely.
|
||||||
|
psprites = p.psprites;
|
||||||
|
p.psprites = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t player_t::PropagateMark()
|
size_t player_t::PropagateMark()
|
||||||
|
@ -422,9 +426,7 @@ void player_t::SetLogText (const char *text)
|
||||||
if (mo && mo->CheckLocalView())
|
if (mo && mo->CheckLocalView())
|
||||||
{
|
{
|
||||||
// Print log text to console
|
// Print log text to console
|
||||||
AddToConsole(-1, TEXTCOLOR_GOLD);
|
Printf(PRINT_NONOTIFY, TEXTCOLOR_GOLD "%s\n", LogText[0] == '$' ? GStrings(text + 1) : text);
|
||||||
AddToConsole(-1, LogText[0] == '$'? GStrings(text+1) : text );
|
|
||||||
AddToConsole(-1, "\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1369,7 +1371,7 @@ void P_PredictPlayer (player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save original values for restoration later
|
// Save original values for restoration later
|
||||||
PredictionPlayerBackup = *player;
|
PredictionPlayerBackup.CopyFrom(*player, false);
|
||||||
|
|
||||||
auto act = player->mo;
|
auto act = player->mo;
|
||||||
PredictionActor = player->mo;
|
PredictionActor = player->mo;
|
||||||
|
@ -1494,7 +1496,7 @@ void P_UnPredictPlayer ()
|
||||||
int inventorytics = player->inventorytics;
|
int inventorytics = player->inventorytics;
|
||||||
const bool settings_controller = player->settings_controller;
|
const bool settings_controller = player->settings_controller;
|
||||||
|
|
||||||
*player = PredictionPlayerBackup;
|
player->CopyFrom(PredictionPlayerBackup, false);
|
||||||
|
|
||||||
player->settings_controller = settings_controller;
|
player->settings_controller = settings_controller;
|
||||||
// Restore the camera instead of using the backup's copy, because spynext/prev
|
// Restore the camera instead of using the backup's copy, because spynext/prev
|
||||||
|
|
|
@ -68,21 +68,6 @@ ticcmd_t* I_BaseTiccmd()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// SetLanguageIDs
|
|
||||||
//
|
|
||||||
void SetLanguageIDs()
|
|
||||||
{
|
|
||||||
size_t langlen = strlen(language);
|
|
||||||
|
|
||||||
uint32_t lang = (langlen < 2 || langlen > 3)
|
|
||||||
? MAKE_ID('e', 'n', 'u', '\0')
|
|
||||||
: MAKE_ID(language[0], language[1], language[2], '\0');
|
|
||||||
|
|
||||||
LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double PerfToSec, PerfToMillisec;
|
double PerfToSec, PerfToMillisec;
|
||||||
|
|
||||||
static void CalculateCPUSpeed()
|
static void CalculateCPUSpeed()
|
||||||
|
@ -180,7 +165,7 @@ void I_Error (const char *error, ...)
|
||||||
|
|
||||||
va_start(argptr, error);
|
va_start(argptr, error);
|
||||||
|
|
||||||
vsprintf (errortext, error, argptr);
|
myvsnprintf (errortext, MAX_ERRORTEXT, error, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
throw CRecoverableError(errortext);
|
throw CRecoverableError(errortext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,8 +294,6 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void*, const bool fullscreen)
|
||||||
, m_hiDPI(false)
|
, m_hiDPI(false)
|
||||||
, m_window(CreateWindow(STYLE_MASK_WINDOWED))
|
, m_window(CreateWindow(STYLE_MASK_WINDOWED))
|
||||||
{
|
{
|
||||||
SetFlash(0, 0);
|
|
||||||
|
|
||||||
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat();
|
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat();
|
||||||
|
|
||||||
if (nil == pixelFormat)
|
if (nil == pixelFormat)
|
||||||
|
|
|
@ -45,16 +45,6 @@ struct WadStuff;
|
||||||
#define SHARE_DIR "/usr/local/share/"
|
#define SHARE_DIR "/usr/local/share/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Index values into the LanguageIDs array
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
LANGIDX_UserPreferred,
|
|
||||||
LANGIDX_UserDefault,
|
|
||||||
LANGIDX_SysPreferred,
|
|
||||||
LANGIDX_SysDefault
|
|
||||||
};
|
|
||||||
extern uint32_t LanguageIDs[4];
|
|
||||||
extern void SetLanguageIDs ();
|
|
||||||
|
|
||||||
// Called by DoomMain.
|
// Called by DoomMain.
|
||||||
void I_Init (void);
|
void I_Init (void);
|
||||||
|
|
|
@ -149,11 +149,11 @@ void I_SetFPSLimit(int limit)
|
||||||
{
|
{
|
||||||
FPSLimitTimerEnabled = true;
|
FPSLimitTimerEnabled = true;
|
||||||
if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1)
|
if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1)
|
||||||
Printf(DMSG_WARNING, "Failed to create FPS limitter event\n");
|
Printf(DMSG_WARNING, "Failed to create FPS limiter event\n");
|
||||||
itimerspec period = { {0, 0}, {0, 0} };
|
itimerspec period = { {0, 0}, {0, 0} };
|
||||||
period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit;
|
period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit;
|
||||||
if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1)
|
if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1)
|
||||||
Printf(DMSG_WARNING, "Failed to set FPS limitter timer\n");
|
Printf(DMSG_WARNING, "Failed to set FPS limiter timer\n");
|
||||||
DPrintf(DMSG_NOTIFY, "FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000);
|
DPrintf(DMSG_NOTIFY, "FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,20 +92,6 @@ void I_EndRead(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// SetLanguageIDs
|
|
||||||
//
|
|
||||||
void SetLanguageIDs ()
|
|
||||||
{
|
|
||||||
size_t langlen = strlen(language);
|
|
||||||
|
|
||||||
uint32_t lang = (langlen < 2 || langlen > 3) ?
|
|
||||||
MAKE_ID('e','n','u','\0') :
|
|
||||||
MAKE_ID(language[0],language[1],language[2],'\0');
|
|
||||||
|
|
||||||
LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// I_Init
|
// I_Init
|
||||||
//
|
//
|
||||||
|
@ -229,7 +215,7 @@ void I_Error (const char *error, ...)
|
||||||
|
|
||||||
va_start(argptr, error);
|
va_start(argptr, error);
|
||||||
|
|
||||||
vsprintf (errortext, error, argptr);
|
myvsnprintf (errortext, MAX_ERRORTEXT, error, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
throw CRecoverableError(errortext);
|
throw CRecoverableError(errortext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
|
|
|
@ -223,9 +223,9 @@ void R_SetWindow (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, int wind
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewwindow.WidescreenRatio = ActiveRatio(fullWidth, fullHeight);
|
viewwindow.WidescreenRatio = ActiveRatio(fullWidth, fullHeight);
|
||||||
|
DrawFSHUD = (windowSize == 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawFSHUD = (windowSize == 11);
|
|
||||||
|
|
||||||
// [RH] Sky height fix for screens not 200 (or 240) pixels tall
|
// [RH] Sky height fix for screens not 200 (or 240) pixels tall
|
||||||
R_InitSkyMap ();
|
R_InitSkyMap ();
|
||||||
|
|
|
@ -87,6 +87,28 @@ int GetUIScale(int altval)
|
||||||
return MAX(1,MIN(scaleval, max));
|
return MAX(1,MIN(scaleval, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The new console font is twice as high, so the scaling calculation must factor that in.
|
||||||
|
int GetConScale(int altval)
|
||||||
|
{
|
||||||
|
int scaleval;
|
||||||
|
if (altval > 0) scaleval = altval;
|
||||||
|
else if (uiscale == 0)
|
||||||
|
{
|
||||||
|
// Default should try to scale to 640x400
|
||||||
|
int vscale = screen->GetHeight() / 800;
|
||||||
|
int hscale = screen->GetWidth() / 1280;
|
||||||
|
scaleval = clamp(vscale, 1, hscale);
|
||||||
|
}
|
||||||
|
else scaleval = uiscale / 2;
|
||||||
|
|
||||||
|
// block scales that result in something larger than the current screen.
|
||||||
|
int vmax = screen->GetHeight() / 400;
|
||||||
|
int hmax = screen->GetWidth() / 640;
|
||||||
|
int max = MAX(vmax, hmax);
|
||||||
|
return MAX(1, MIN(scaleval, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// [RH] Stretch values to make a 320x200 image best fit the screen
|
// [RH] Stretch values to make a 320x200 image best fit the screen
|
||||||
// without using fractional steppings
|
// without using fractional steppings
|
||||||
int CleanXfac, CleanYfac;
|
int CleanXfac, CleanYfac;
|
||||||
|
@ -1351,12 +1373,13 @@ void DFrameBuffer::DrawBorder (FTextureID picnum, int x1, int y1, int x2, int y2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Draws a blend over the entire view
|
// Draws a blend over the entire view
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
|
||||||
|
FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector, PalEntry *modulateColor)
|
||||||
{
|
{
|
||||||
float blend[4] = { 0,0,0,0 };
|
float blend[4] = { 0,0,0,0 };
|
||||||
PalEntry blendv = 0;
|
PalEntry blendv = 0;
|
||||||
|
@ -1366,6 +1389,8 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
player_t *player = nullptr;
|
player_t *player = nullptr;
|
||||||
bool fullbright = false;
|
bool fullbright = false;
|
||||||
|
|
||||||
|
if (modulateColor) *modulateColor = 0xffffffff;
|
||||||
|
|
||||||
if (players[consoleplayer].camera != nullptr)
|
if (players[consoleplayer].camera != nullptr)
|
||||||
{
|
{
|
||||||
player = players[consoleplayer].camera->player;
|
player = players[consoleplayer].camera->player;
|
||||||
|
@ -1376,7 +1401,7 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
// don't draw sector based blends when any fullbright screen effect is active.
|
// don't draw sector based blends when any fullbright screen effect is active.
|
||||||
if (!fullbright)
|
if (!fullbright)
|
||||||
{
|
{
|
||||||
const auto &vpp = r_viewpoint.Pos;
|
const auto &vpp = r_viewpoint.Pos;
|
||||||
if (!viewsector->e->XFloor.ffloors.Size())
|
if (!viewsector->e->XFloor.ffloors.Size())
|
||||||
{
|
{
|
||||||
if (viewsector->GetHeightSec())
|
if (viewsector->GetHeightSec())
|
||||||
|
@ -1427,7 +1452,7 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
// black multiplicative blends are ignored
|
// black multiplicative blends are ignored
|
||||||
if (extra_red || extra_green || extra_blue)
|
if (extra_red || extra_green || extra_blue)
|
||||||
{
|
{
|
||||||
screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]);
|
if (modulateColor) *modulateColor = blendv;
|
||||||
}
|
}
|
||||||
blendv = 0;
|
blendv = 0;
|
||||||
}
|
}
|
||||||
|
@ -1452,7 +1477,7 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
if (in->IsKindOf(torchtype))
|
if (in->IsKindOf(torchtype))
|
||||||
{
|
{
|
||||||
// The software renderer already bakes the torch flickering into its output, so this must be omitted here.
|
// The software renderer already bakes the torch flickering into its output, so this must be omitted here.
|
||||||
float r = vid_rendermode < 4? 1.f : (0.8f + (7 - player->fixedlightlevel) / 70.0f);
|
float r = vid_rendermode < 4 ? 1.f : (0.8f + (7 - player->fixedlightlevel) / 70.0f);
|
||||||
if (r > 1.0f) r = 1.0f;
|
if (r > 1.0f) r = 1.0f;
|
||||||
int rr = (int)(r * 255);
|
int rr = (int)(r * 255);
|
||||||
int b = rr;
|
int b = rr;
|
||||||
|
@ -1467,9 +1492,9 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (color != 0xffffffff)
|
if (modulateColor)
|
||||||
{
|
{
|
||||||
screen->Dim(color, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]);
|
*modulateColor = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1488,8 +1513,26 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
const float br = clamp(blend[0] * 255.f, 0.f, 255.f);
|
const float br = clamp(blend[0] * 255.f, 0.f, 255.f);
|
||||||
const float bg = clamp(blend[1] * 255.f, 0.f, 255.f);
|
const float bg = clamp(blend[1] * 255.f, 0.f, 255.f);
|
||||||
const float bb = clamp(blend[2] * 255.f, 0.f, 255.f);
|
const float bb = clamp(blend[2] * 255.f, 0.f, 255.f);
|
||||||
const PalEntry bcolor(255, uint8_t(br), uint8_t(bg), uint8_t(bb));
|
return { br, bg, bb, blend[3] };
|
||||||
screen->Dim(bcolor, blend[3], 0, 0, screen->GetWidth(), screen->GetHeight());
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Draws a blend over the entire view
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void DFrameBuffer::DrawBlend(sector_t * viewsector)
|
||||||
|
{
|
||||||
|
PalEntry modulateColor;
|
||||||
|
auto blend = CalcBlend(viewsector, &modulateColor);
|
||||||
|
if (modulateColor != 0xffffffff)
|
||||||
|
{
|
||||||
|
Dim(modulateColor, 1, 0, 0, GetWidth(), GetHeight(), &LegacyRenderStyles[STYLE_Multiply]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z));
|
||||||
|
Dim(bcolor, blend.W, 0, 0, GetWidth(), GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
@ -248,10 +249,14 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawChar)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms)
|
// This is only needed as a dummy. The code using wide strings does not need color control.
|
||||||
|
EColorRange V_ParseFontColor(const char32_t *&color_value, int normalcolor, int boldcolor) { return CR_UNTRANSLATED; }
|
||||||
|
|
||||||
|
template<class chartype>
|
||||||
|
void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const chartype *string, DrawParms &parms)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
const uint8_t *ch;
|
const chartype *ch;
|
||||||
int c;
|
int c;
|
||||||
double cx;
|
double cx;
|
||||||
double cy;
|
double cy;
|
||||||
|
@ -274,13 +279,13 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
|
||||||
|
|
||||||
kerning = font->GetDefaultKerning();
|
kerning = font->GetDefaultKerning();
|
||||||
|
|
||||||
ch = (const uint8_t *)string;
|
ch = string;
|
||||||
cx = x;
|
cx = x;
|
||||||
cy = y;
|
cy = y;
|
||||||
|
|
||||||
|
|
||||||
auto currentcolor = normalcolor;
|
auto currentcolor = normalcolor;
|
||||||
while ((const char *)ch - string < parms.maxstrlen)
|
while (ch - string < parms.maxstrlen)
|
||||||
{
|
{
|
||||||
c = GetCharFromString(ch);
|
c = GetCharFromString(ch);
|
||||||
if (!c)
|
if (!c)
|
||||||
|
@ -327,6 +332,24 @@ void DFrameBuffer::DrawText(FFont *font, int normalcolor, double x, double y, co
|
||||||
Va_List tags;
|
Va_List tags;
|
||||||
DrawParms parms;
|
DrawParms parms;
|
||||||
|
|
||||||
|
if (font == NULL || string == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(tags.list, tag_first);
|
||||||
|
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
|
||||||
|
va_end(tags.list);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DrawTextCommon(font, normalcolor, x, y, (const uint8_t*)string, parms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFrameBuffer::DrawText(FFont *font, int normalcolor, double x, double y, const char32_t *string, int tag_first, ...)
|
||||||
|
{
|
||||||
|
Va_List tags;
|
||||||
|
DrawParms parms;
|
||||||
|
|
||||||
if (font == NULL || string == NULL)
|
if (font == NULL || string == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -353,13 +376,13 @@ void DFrameBuffer::DrawText(FFont *font, int normalcolor, double x, double y, co
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DrawTextCommon(font, normalcolor, x, y, string, parms);
|
DrawTextCommon(font, normalcolor, x, y, (const uint8_t*)string, parms);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_Screen, DrawText)
|
DEFINE_ACTION_FUNCTION(_Screen, DrawText)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_POINTER(font, FFont);
|
PARAM_POINTER_NOT_NULL(font, FFont);
|
||||||
PARAM_INT(cr);
|
PARAM_INT(cr);
|
||||||
PARAM_FLOAT(x);
|
PARAM_FLOAT(x);
|
||||||
PARAM_FLOAT(y);
|
PARAM_FLOAT(y);
|
||||||
|
|
|
@ -121,20 +121,11 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
|
||||||
mBuffers->UpdateEffectTextures();
|
mBuffers->UpdateEffectTextures();
|
||||||
|
|
||||||
auto vrmode = VRMode::GetVRMode(true);
|
auto vrmode = VRMode::GetVRMode(true);
|
||||||
if (vrmode->mEyeCount == 1)
|
int eyeCount = vrmode->mEyeCount;
|
||||||
|
for (int i = 0; i < eyeCount; ++i)
|
||||||
{
|
{
|
||||||
mBuffers->RenderEffect("BlurScene");
|
mBuffers->RenderEffect("BlurScene");
|
||||||
}
|
if (eyeCount - i > 1) mBuffers->NextEye(eyeCount);
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
|
|
||||||
{
|
|
||||||
FGLDebug::PushGroup("EyeBlur");
|
|
||||||
mBuffers->BlitFromEyeTexture(eye_ix);
|
|
||||||
mBuffers->RenderEffect("BlurScene");
|
|
||||||
mBuffers->BlitToEyeTexture(eye_ix);
|
|
||||||
FGLDebug::PopGroup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,13 +150,12 @@ void FGLRenderer::Flush()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Render 2D to eye textures
|
// Render 2D to eye textures
|
||||||
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
|
int eyeCount = vrmode->mEyeCount;
|
||||||
|
for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix)
|
||||||
{
|
{
|
||||||
FGLDebug::PushGroup("Eye2D");
|
|
||||||
mBuffers->BlitFromEyeTexture(eye_ix);
|
|
||||||
screen->Draw2D();
|
screen->Draw2D();
|
||||||
mBuffers->BlitToEyeTexture(eye_ix);
|
if (eyeCount - eye_ix > 1)
|
||||||
FGLDebug::PopGroup();
|
mBuffers->NextEye(eyeCount);
|
||||||
}
|
}
|
||||||
screen->Clear2D();
|
screen->Clear2D();
|
||||||
|
|
||||||
|
|
|
@ -532,7 +532,7 @@ void FGLRenderBuffers::BlitSceneToTexture()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FGLRenderBuffers::BlitToEyeTexture(int eye)
|
void FGLRenderBuffers::BlitToEyeTexture(int eye, bool allowInvalidate)
|
||||||
{
|
{
|
||||||
CreateEyeBuffers(eye);
|
CreateEyeBuffers(eye);
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye)
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle);
|
||||||
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
|
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0 && allowInvalidate)
|
||||||
{
|
{
|
||||||
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
|
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
|
||||||
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
|
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
|
||||||
|
@ -552,7 +552,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye)
|
||||||
|
|
||||||
void FGLRenderBuffers::BlitFromEyeTexture(int eye)
|
void FGLRenderBuffers::BlitFromEyeTexture(int eye)
|
||||||
{
|
{
|
||||||
CreateEyeBuffers(eye);
|
if (mEyeFBs.Size() <= unsigned(eye)) return;
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mEyeFBs[eye].handle);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, mEyeFBs[eye].handle);
|
||||||
|
@ -1002,4 +1002,17 @@ void FGLRenderBuffers::RenderEffect(const FString &name)
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
// Store the current stereo 3D eye buffer, and Load the next one
|
||||||
|
|
||||||
|
int FGLRenderBuffers::NextEye(int eyeCount)
|
||||||
|
{
|
||||||
|
int nextEye = (mCurrentEye + 1) % eyeCount;
|
||||||
|
if (nextEye == mCurrentEye) return mCurrentEye;
|
||||||
|
BlitToEyeTexture(mCurrentEye);
|
||||||
|
mCurrentEye = nextEye;
|
||||||
|
BlitFromEyeTexture(mCurrentEye);
|
||||||
|
return mCurrentEye;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OpenGLRenderer
|
|
@ -87,9 +87,11 @@ public:
|
||||||
|
|
||||||
void BindOutputFB();
|
void BindOutputFB();
|
||||||
|
|
||||||
void BlitToEyeTexture(int eye);
|
void BlitToEyeTexture(int eye, bool allowInvalidate=true);
|
||||||
void BlitFromEyeTexture(int eye);
|
void BlitFromEyeTexture(int eye);
|
||||||
void BindEyeTexture(int eye, int texunit);
|
void BindEyeTexture(int eye, int texunit);
|
||||||
|
int NextEye(int eyeCount);
|
||||||
|
int & CurrentEye() { return mCurrentEye; }
|
||||||
|
|
||||||
void BindDitherTexture(int texunit);
|
void BindDitherTexture(int texunit);
|
||||||
|
|
||||||
|
@ -156,6 +158,7 @@ private:
|
||||||
// Eye buffers
|
// Eye buffers
|
||||||
TArray<PPGLTexture> mEyeTextures;
|
TArray<PPGLTexture> mEyeTextures;
|
||||||
TArray<PPGLFrameBuffer> mEyeFBs;
|
TArray<PPGLFrameBuffer> mEyeFBs;
|
||||||
|
int mCurrentEye = 0;
|
||||||
|
|
||||||
// Shadow map texture
|
// Shadow map texture
|
||||||
PPGLTexture mShadowMapTexture;
|
PPGLTexture mShadowMapTexture;
|
||||||
|
|
|
@ -67,6 +67,8 @@ EXTERN_CVAR(Bool, cl_capfps)
|
||||||
|
|
||||||
extern bool NoInterpolateView;
|
extern bool NoInterpolateView;
|
||||||
|
|
||||||
|
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
||||||
|
|
||||||
namespace OpenGLRenderer
|
namespace OpenGLRenderer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -370,9 +372,11 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
|
||||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3);
|
int numpixels = width * height;
|
||||||
|
uint8_t * scr = (uint8_t *)M_Malloc(numpixels * 3);
|
||||||
glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr);
|
glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr);
|
||||||
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
|
|
||||||
|
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true);
|
||||||
M_Free(scr);
|
M_Free(scr);
|
||||||
|
|
||||||
// Switch back the screen render buffers
|
// Switch back the screen render buffers
|
||||||
|
|
|
@ -138,7 +138,7 @@ bool FGLRenderState::ApplyShader()
|
||||||
activeShader->muLightIndex.Set(-1);
|
activeShader->muLightIndex.Set(-1);
|
||||||
activeShader->muClipSplit.Set(mClipSplit);
|
activeShader->muClipSplit.Set(mClipSplit);
|
||||||
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
||||||
activeShader->muAddColor.Set(mAddColor); // Can this be done without a shader?
|
activeShader->muAddColor.Set(mAddColor);
|
||||||
|
|
||||||
if (mGlowEnabled)
|
if (mGlowEnabled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,12 +111,12 @@ void FGLRenderer::DrawScene(HWDrawInfo *di, int drawmode)
|
||||||
if (vp.camera != nullptr)
|
if (vp.camera != nullptr)
|
||||||
{
|
{
|
||||||
ActorRenderFlags savedflags = vp.camera->renderflags;
|
ActorRenderFlags savedflags = vp.camera->renderflags;
|
||||||
di->CreateScene();
|
di->CreateScene(drawmode == DM_MAINVIEW);
|
||||||
vp.camera->renderflags = savedflags;
|
vp.camera->renderflags = savedflags;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
di->CreateScene();
|
di->CreateScene(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
|
@ -163,9 +163,11 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
|
||||||
// Render (potentially) multiple views for stereo 3d
|
// Render (potentially) multiple views for stereo 3d
|
||||||
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
|
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
|
||||||
auto vrmode = VRMode::GetVRMode(mainview && toscreen);
|
auto vrmode = VRMode::GetVRMode(mainview && toscreen);
|
||||||
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
|
const int eyeCount = vrmode->mEyeCount;
|
||||||
|
mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed
|
||||||
|
for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix)
|
||||||
{
|
{
|
||||||
const auto &eye = vrmode->mEyes[eye_ix];
|
const auto &eye = vrmode->mEyes[mBuffers->CurrentEye()];
|
||||||
screen->SetViewportRects(bounds);
|
screen->SetViewportRects(bounds);
|
||||||
|
|
||||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||||
|
@ -218,8 +220,8 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
|
||||||
PostProcess.Unclock();
|
PostProcess.Unclock();
|
||||||
}
|
}
|
||||||
di->EndDrawInfo();
|
di->EndDrawInfo();
|
||||||
if (vrmode->mEyeCount > 1)
|
if (eyeCount - eye_ix > 1)
|
||||||
mBuffers->BlitToEyeTexture(eye_ix);
|
mBuffers->NextEye(eyeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mainvp.sector;
|
return mainvp.sector;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "gl/system/gl_framebuffer.h"
|
#include "gl/system/gl_framebuffer.h"
|
||||||
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_present3dRowshader.h"
|
#include "hwrenderer/postprocessing/hw_present3dRowshader.h"
|
||||||
|
#include "menu/menu.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, vr_mode)
|
EXTERN_CVAR(Int, vr_mode)
|
||||||
EXTERN_CVAR(Float, vid_saturation)
|
EXTERN_CVAR(Float, vid_saturation)
|
||||||
|
@ -283,6 +284,8 @@ bool FGLRenderer::QuadStereoCheckInitialRenderContextState()
|
||||||
// Now check whether this context supports hardware stereo
|
// Now check whether this context supports hardware stereo
|
||||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||||
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||||
|
if (! bQuadStereoSupported)
|
||||||
|
UpdateVRModes(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bQuadStereoSupported;
|
return bQuadStereoSupported;
|
||||||
|
@ -324,6 +327,12 @@ void FGLRenderer::PresentQuadStereo()
|
||||||
|
|
||||||
void FGLRenderer::PresentStereo()
|
void FGLRenderer::PresentStereo()
|
||||||
{
|
{
|
||||||
|
auto vrmode = VRMode::GetVRMode(true);
|
||||||
|
const int eyeCount = vrmode->mEyeCount;
|
||||||
|
// Don't invalidate the bound framebuffer (..., false)
|
||||||
|
if (eyeCount > 1)
|
||||||
|
mBuffers->BlitToEyeTexture(mBuffers->CurrentEye(), false);
|
||||||
|
|
||||||
switch (vr_mode)
|
switch (vr_mode)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -58,6 +58,7 @@ void GLViewpointBuffer::CheckSize()
|
||||||
mBufferSize *= 2;
|
mBufferSize *= 2;
|
||||||
mByteSize *= 2;
|
mByteSize *= 2;
|
||||||
mBuffer->Resize(mByteSize);
|
mBuffer->Resize(mByteSize);
|
||||||
|
m2DHeight = m2DWidth = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
void BindBase()
|
void BindBase()
|
||||||
{
|
{
|
||||||
mBuffer->BindBase();
|
mBuffer->BindBase();
|
||||||
|
mLastMappedIndex = UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -796,7 +796,7 @@ void HWDrawInfo::RenderBSPNode (void *node)
|
||||||
DoSubsector ((subsector_t *)((uint8_t *)node - 1));
|
DoSubsector ((subsector_t *)((uint8_t *)node - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWDrawInfo::RenderBSP(void *node)
|
void HWDrawInfo::RenderBSP(void *node, bool drawpsprites)
|
||||||
{
|
{
|
||||||
Bsp.Clock();
|
Bsp.Clock();
|
||||||
|
|
||||||
|
@ -829,6 +829,6 @@ void HWDrawInfo::RenderBSP(void *node)
|
||||||
// Process all the sprites on the current portal's back side which touch the portal.
|
// Process all the sprites on the current portal's back side which touch the portal.
|
||||||
if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this);
|
if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this);
|
||||||
|
|
||||||
|
if (drawpsprites)
|
||||||
PreparePlayerSprites(Viewpoint.sector, in_area);
|
PreparePlayerSprites(Viewpoint.sector, in_area);
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,7 @@ GLDecal *HWDrawInfo::AddDecal(bool onmirror)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void HWDrawInfo::CreateScene()
|
void HWDrawInfo::CreateScene(bool drawpsprites)
|
||||||
{
|
{
|
||||||
const auto &vp = Viewpoint;
|
const auto &vp = Viewpoint;
|
||||||
angle_t a1 = FrustumAngle();
|
angle_t a1 = FrustumAngle();
|
||||||
|
@ -436,7 +436,7 @@ void HWDrawInfo::CreateScene()
|
||||||
screen->mVertexData->Map();
|
screen->mVertexData->Map();
|
||||||
screen->mLights->Map();
|
screen->mLights->Map();
|
||||||
|
|
||||||
RenderBSP(Level->HeadNode());
|
RenderBSP(Level->HeadNode(), drawpsprites);
|
||||||
|
|
||||||
// And now the crappy hacks that have to be done to avoid rendering anomalies.
|
// And now the crappy hacks that have to be done to avoid rendering anomalies.
|
||||||
// These cannot be multithreaded when the time comes because all these depend
|
// These cannot be multithreaded when the time comes because all these depend
|
||||||
|
|
|
@ -237,7 +237,7 @@ public:
|
||||||
|
|
||||||
HWPortal * FindPortal(const void * src);
|
HWPortal * FindPortal(const void * src);
|
||||||
void RenderBSPNode(void *node);
|
void RenderBSPNode(void *node);
|
||||||
void RenderBSP(void *node);
|
void RenderBSP(void *node, bool drawpsprites);
|
||||||
|
|
||||||
static HWDrawInfo *StartDrawInfo(FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
static HWDrawInfo *StartDrawInfo(FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||||
void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||||
|
@ -246,7 +246,7 @@ public:
|
||||||
void SetViewArea();
|
void SetViewArea();
|
||||||
int SetFullbrightFlags(player_t *player);
|
int SetFullbrightFlags(player_t *player);
|
||||||
|
|
||||||
void CreateScene();
|
void CreateScene(bool drawpsprites);
|
||||||
void RenderScene(FRenderState &state);
|
void RenderScene(FRenderState &state);
|
||||||
void RenderTranslucent(FRenderState &state);
|
void RenderTranslucent(FRenderState &state);
|
||||||
void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil);
|
void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil);
|
||||||
|
|
|
@ -155,7 +155,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||||
{
|
{
|
||||||
state.SetTextureMode(TM_FIXEDCOLORMAP);
|
state.SetTextureMode(TM_FIXEDCOLORMAP);
|
||||||
state.SetObjectColor(cmd.mSpecialColormap[0]);
|
state.SetObjectColor(cmd.mSpecialColormap[0]);
|
||||||
state.SetObjectColor2(cmd.mSpecialColormap[1]);
|
state.SetAddColor(cmd.mSpecialColormap[1]);
|
||||||
}
|
}
|
||||||
state.SetFog(cmd.mColor1, 0);
|
state.SetFog(cmd.mColor1, 0);
|
||||||
state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
|
state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
|
||||||
|
|
|
@ -68,7 +68,7 @@ void PolyRenderer::RenderView(player_t *player, DCanvas *target, void *videobuff
|
||||||
RenderTarget = target;
|
RenderTarget = target;
|
||||||
RenderToCanvas = false;
|
RenderToCanvas = false;
|
||||||
|
|
||||||
RenderActorView(player->mo, false);
|
RenderActorView(player->mo, true, false);
|
||||||
|
|
||||||
Threads.MainThread()->FlushDrawQueue();
|
Threads.MainThread()->FlushDrawQueue();
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int
|
||||||
viewactive = true;
|
viewactive = true;
|
||||||
|
|
||||||
// Render:
|
// Render:
|
||||||
RenderActorView(actor, dontmaplines);
|
RenderActorView(actor, false, dontmaplines);
|
||||||
Threads.MainThread()->FlushDrawQueue();
|
Threads.MainThread()->FlushDrawQueue();
|
||||||
DrawerThreads::WaitForWorkers();
|
DrawerThreads::WaitForWorkers();
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int
|
||||||
RenderTarget = savedRenderTarget;
|
RenderTarget = savedRenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
void PolyRenderer::RenderActorView(AActor *actor, bool drawpsprites, bool dontmaplines)
|
||||||
{
|
{
|
||||||
PolyTotalBatches = 0;
|
PolyTotalBatches = 0;
|
||||||
PolyTotalTriangles = 0;
|
PolyTotalTriangles = 0;
|
||||||
|
@ -181,7 +181,9 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
||||||
mainViewpoint.StencilValue = GetNextStencilValue();
|
mainViewpoint.StencilValue = GetNextStencilValue();
|
||||||
Scene.CurrentViewpoint = &mainViewpoint;
|
Scene.CurrentViewpoint = &mainViewpoint;
|
||||||
Scene.Render(&mainViewpoint);
|
Scene.Render(&mainViewpoint);
|
||||||
PlayerSprites.Render(Threads.MainThread());
|
if (drawpsprites)
|
||||||
|
PlayerSprites.Render(Threads.MainThread());
|
||||||
|
|
||||||
Scene.CurrentViewpoint = nullptr;
|
Scene.CurrentViewpoint = nullptr;
|
||||||
|
|
||||||
if (Viewpoint.camera)
|
if (Viewpoint.camera)
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
FLevelLocals *Level;
|
FLevelLocals *Level;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderActorView(AActor *actor, bool dontmaplines);
|
void RenderActorView(AActor *actor, bool drawpsprites, bool dontmaplines);
|
||||||
void SetSceneViewport();
|
void SetSceneViewport();
|
||||||
|
|
||||||
RenderPolyPlayerSprites PlayerSprites;
|
RenderPolyPlayerSprites PlayerSprites;
|
||||||
|
|
|
@ -208,10 +208,11 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
||||||
|
|
||||||
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
DCanvas pic(width, height, false);
|
DCanvas pic(width, height, false);
|
||||||
PalEntry palette[256];
|
|
||||||
|
|
||||||
// Take a snapshot of the player's view
|
// Take a snapshot of the player's view
|
||||||
if (V_IsPolyRenderer())
|
if (V_IsPolyRenderer())
|
||||||
|
@ -230,8 +231,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
|
||||||
r_viewpoint = mScene.MainThread()->Viewport->viewpoint;
|
r_viewpoint = mScene.MainThread()->Viewport->viewpoint;
|
||||||
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
|
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
|
||||||
}
|
}
|
||||||
screen->GetFlashedPalette (palette);
|
DoWriteSavePic(file, SS_PAL, pic.GetPixels(), width, height, r_viewpoint.sector, false);
|
||||||
M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSoftwareRenderer::DrawRemainingPlayerSprites()
|
void FSoftwareRenderer::DrawRemainingPlayerSprites()
|
||||||
|
|
|
@ -129,7 +129,7 @@ namespace swrenderer
|
||||||
DrawerThreads::ResetDebugDrawPos();
|
DrawerThreads::ResetDebugDrawPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderActorView(player->mo);
|
RenderActorView(player->mo, true, false);
|
||||||
|
|
||||||
auto copyqueue = std::make_shared<DrawerCommandQueue>(MainThread()->FrameMemory.get());
|
auto copyqueue = std::make_shared<DrawerCommandQueue>(MainThread()->FrameMemory.get());
|
||||||
copyqueue->Push<MemcpyCommand>(videobuffer, target->GetPixels(), target->GetWidth(), target->GetHeight(), target->GetPitch(), target->IsBgra() ? 4 : 1);
|
copyqueue->Push<MemcpyCommand>(videobuffer, target->GetPixels(), target->GetWidth(), target->GetHeight(), target->GetPitch(), target->IsBgra() ? 4 : 1);
|
||||||
|
@ -140,7 +140,7 @@ namespace swrenderer
|
||||||
DrawerWaitCycles.Unclock();
|
DrawerWaitCycles.Unclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
|
void RenderScene::RenderActorView(AActor *actor, bool renderPlayerSprites, bool dontmaplines)
|
||||||
{
|
{
|
||||||
WallCycles.Reset();
|
WallCycles.Reset();
|
||||||
PlaneCycles.Reset();
|
PlaneCycles.Reset();
|
||||||
|
@ -180,7 +180,8 @@ namespace swrenderer
|
||||||
if (r_modelscene)
|
if (r_modelscene)
|
||||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||||
|
|
||||||
RenderPSprites();
|
if (renderPlayerSprites)
|
||||||
|
RenderPSprites();
|
||||||
|
|
||||||
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +385,7 @@ namespace swrenderer
|
||||||
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
||||||
|
|
||||||
// Render:
|
// Render:
|
||||||
RenderActorView(actor, dontmaplines);
|
RenderActorView(actor, false, dontmaplines);
|
||||||
DrawerWaitCycles.Clock();
|
DrawerWaitCycles.Clock();
|
||||||
DrawerThreads::WaitForWorkers();
|
DrawerThreads::WaitForWorkers();
|
||||||
DrawerWaitCycles.Unclock();
|
DrawerWaitCycles.Unclock();
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace swrenderer
|
||||||
RenderThread *MainThread() { return Threads.front().get(); }
|
RenderThread *MainThread() { return Threads.front().get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderActorView(AActor *actor, bool dontmaplines = false);
|
void RenderActorView(AActor *actor,bool renderplayersprite, bool dontmaplines);
|
||||||
void RenderThreadSlices();
|
void RenderThreadSlices();
|
||||||
void RenderThreadSlice(RenderThread *thread);
|
void RenderThreadSlice(RenderThread *thread);
|
||||||
void RenderPSprites();
|
void RenderPSprites();
|
||||||
|
|
|
@ -183,21 +183,21 @@ void S_NoiseDebug (void)
|
||||||
int y, color;
|
int y, color;
|
||||||
|
|
||||||
y = 32 * CleanYfac;
|
y = 32 * CleanYfac;
|
||||||
screen->DrawText (SmallFont, CR_YELLOW, 0, y, "*** SOUND DEBUG INFO ***", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_YELLOW, 0, y, "*** SOUND DEBUG INFO ***", TAG_DONE);
|
||||||
y += 8;
|
y += NewConsoleFont->GetHeight();
|
||||||
|
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 0, y, "name", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 0, y, "name", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 70, y, "x", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 70, y, "x", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 120, y, "y", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 120, y, "y", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 170, y, "z", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 170, y, "z", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 220, y, "vol", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 220, y, "vol", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 260, y, "dist", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 260, y, "dist", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 300, y, "chan", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 300, y, "chan", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 340, y, "pri", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 340, y, "pri", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 380, y, "flags", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 380, y, "flags", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 460, y, "aud", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 460, y, "aud", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 520, y, "pos", TAG_DONE);
|
screen->DrawText (NewConsoleFont, CR_GOLD, 520, y, "pos", TAG_DONE);
|
||||||
y += 8;
|
y += NewConsoleFont->GetHeight();
|
||||||
|
|
||||||
if (Channels == NULL)
|
if (Channels == NULL)
|
||||||
{
|
{
|
||||||
|
@ -220,52 +220,52 @@ void S_NoiseDebug (void)
|
||||||
// Name
|
// Name
|
||||||
Wads.GetLumpName (temp, S_sfx[chan->SoundID].lumpnum);
|
Wads.GetLumpName (temp, S_sfx[chan->SoundID].lumpnum);
|
||||||
temp[8] = 0;
|
temp[8] = 0;
|
||||||
screen->DrawText (SmallFont, color, 0, y, temp, TAG_DONE);
|
screen->DrawText (NewConsoleFont, color, 0, y, temp, TAG_DONE);
|
||||||
|
|
||||||
if (!(chan->ChanFlags & CHAN_IS3D))
|
if (!(chan->ChanFlags & CHAN_IS3D))
|
||||||
{
|
{
|
||||||
screen->DrawText(SmallFont, color, 70, y, "---", TAG_DONE); // X
|
screen->DrawText(NewConsoleFont, color, 70, y, "---", TAG_DONE); // X
|
||||||
screen->DrawText(SmallFont, color, 120, y, "---", TAG_DONE); // Y
|
screen->DrawText(NewConsoleFont, color, 120, y, "---", TAG_DONE); // Y
|
||||||
screen->DrawText(SmallFont, color, 170, y, "---", TAG_DONE); // Z
|
screen->DrawText(NewConsoleFont, color, 170, y, "---", TAG_DONE); // Z
|
||||||
screen->DrawText(SmallFont, color, 260, y, "---", TAG_DONE); // Distance
|
screen->DrawText(NewConsoleFont, color, 260, y, "---", TAG_DONE); // Distance
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// X coordinate
|
// X coordinate
|
||||||
mysnprintf(temp, countof(temp), "%.0f", origin.X);
|
mysnprintf(temp, countof(temp), "%.0f", origin.X);
|
||||||
screen->DrawText(SmallFont, color, 70, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 70, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Y coordinate
|
// Y coordinate
|
||||||
mysnprintf(temp, countof(temp), "%.0f", origin.Z);
|
mysnprintf(temp, countof(temp), "%.0f", origin.Z);
|
||||||
screen->DrawText(SmallFont, color, 120, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 120, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Z coordinate
|
// Z coordinate
|
||||||
mysnprintf(temp, countof(temp), "%.0f", origin.Y);
|
mysnprintf(temp, countof(temp), "%.0f", origin.Y);
|
||||||
screen->DrawText(SmallFont, color, 170, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 170, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Distance
|
// Distance
|
||||||
if (chan->DistanceScale > 0)
|
if (chan->DistanceScale > 0)
|
||||||
{
|
{
|
||||||
mysnprintf(temp, countof(temp), "%.0f", (origin - listener).Length());
|
mysnprintf(temp, countof(temp), "%.0f", (origin - listener).Length());
|
||||||
screen->DrawText(SmallFont, color, 260, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 260, y, temp, TAG_DONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText(SmallFont, color, 260, y, "---", TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 260, y, "---", TAG_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
mysnprintf(temp, countof(temp), "%.2g", chan->Volume);
|
mysnprintf(temp, countof(temp), "%.2g", chan->Volume);
|
||||||
screen->DrawText(SmallFont, color, 220, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 220, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Channel
|
// Channel
|
||||||
mysnprintf(temp, countof(temp), "%d", chan->EntChannel);
|
mysnprintf(temp, countof(temp), "%d", chan->EntChannel);
|
||||||
screen->DrawText(SmallFont, color, 300, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 300, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Priority
|
// Priority
|
||||||
mysnprintf(temp, countof(temp), "%d", chan->Priority);
|
mysnprintf(temp, countof(temp), "%d", chan->Priority);
|
||||||
screen->DrawText(SmallFont, color, 340, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 340, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
mysnprintf(temp, countof(temp), "%s3%sZ%sU%sM%sN%sA%sL%sE%sV",
|
mysnprintf(temp, countof(temp), "%s3%sZ%sU%sM%sN%sA%sL%sE%sV",
|
||||||
|
@ -278,18 +278,18 @@ void S_NoiseDebug (void)
|
||||||
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
||||||
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
||||||
(chan->ChanFlags & CHAN_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK);
|
(chan->ChanFlags & CHAN_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK);
|
||||||
screen->DrawText(SmallFont, color, 380, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 380, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Audibility
|
// Audibility
|
||||||
mysnprintf(temp, countof(temp), "%.4f", GSnd->GetAudibility(chan));
|
mysnprintf(temp, countof(temp), "%.4f", GSnd->GetAudibility(chan));
|
||||||
screen->DrawText(SmallFont, color, 460, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 460, y, temp, TAG_DONE);
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
mysnprintf(temp, countof(temp), "%u", GSnd->GetPosition(chan));
|
mysnprintf(temp, countof(temp), "%u", GSnd->GetPosition(chan));
|
||||||
screen->DrawText(SmallFont, color, 520, y, temp, TAG_DONE);
|
screen->DrawText(NewConsoleFont, color, 520, y, temp, TAG_DONE);
|
||||||
|
|
||||||
|
|
||||||
y += 8;
|
y += NewConsoleFont->GetHeight();
|
||||||
if (chan->PrevChan == &Channels)
|
if (chan->PrevChan == &Channels)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7343,6 +7343,10 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
|
||||||
auto parentfield = static_cast<FxMemberBase *>(Array)->membervar;
|
auto parentfield = static_cast<FxMemberBase *>(Array)->membervar;
|
||||||
SizeAddr = parentfield->Offset + sizeof(void*);
|
SizeAddr = parentfield->Offset + sizeof(void*);
|
||||||
}
|
}
|
||||||
|
else if (Array->ExprType == EFX_ArrayElement)
|
||||||
|
{
|
||||||
|
SizeAddr = ~0u;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Invalid resizable array");
|
ScriptPosition.Message(MSG_ERROR, "Invalid resizable array");
|
||||||
|
@ -7415,7 +7419,8 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit arrayvar = Array->Emit(build);
|
ExpEmit arrayvar = Array->Emit(build);
|
||||||
ExpEmit start;
|
ExpEmit start;
|
||||||
ExpEmit bound;
|
ExpEmit bound;
|
||||||
|
bool nestedarray = false;
|
||||||
|
|
||||||
if (SizeAddr != ~0u)
|
if (SizeAddr != ~0u)
|
||||||
{
|
{
|
||||||
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||||
|
@ -7425,20 +7430,44 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
||||||
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
||||||
|
|
||||||
auto f = Create<PField>(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr);
|
auto f = Create<PField>(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr);
|
||||||
static_cast<FxMemberBase *>(Array)->membervar = f;
|
auto arraymemberbase = static_cast<FxMemberBase *>(Array);
|
||||||
static_cast<FxMemberBase *>(Array)->AddressRequested = false;
|
|
||||||
|
auto origmembervar = arraymemberbase->membervar;
|
||||||
|
auto origaddrreq = arraymemberbase->AddressRequested;
|
||||||
|
auto origvaluetype = Array->ValueType;
|
||||||
|
|
||||||
|
arraymemberbase->membervar = f;
|
||||||
|
arraymemberbase->AddressRequested = false;
|
||||||
Array->ValueType = TypeUInt32;
|
Array->ValueType = TypeUInt32;
|
||||||
|
|
||||||
bound = Array->Emit(build);
|
bound = Array->Emit(build);
|
||||||
|
|
||||||
|
arraymemberbase->membervar = origmembervar;
|
||||||
|
arraymemberbase->AddressRequested = origaddrreq;
|
||||||
|
Array->ValueType = origvaluetype;
|
||||||
|
}
|
||||||
|
else if (Array->ExprType == EFX_ArrayElement && Array->isStaticArray())
|
||||||
|
{
|
||||||
|
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||||
|
|
||||||
|
arrayvar.Free(build);
|
||||||
|
start = ExpEmit(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
||||||
|
|
||||||
|
bound = ExpEmit(build, REGT_INT);
|
||||||
|
build->Emit(OP_LW, bound.RegNum, arrayvar.RegNum, build->GetConstantInt(sizeof(void*)));
|
||||||
|
|
||||||
|
nestedarray = true;
|
||||||
}
|
}
|
||||||
else start = arrayvar;
|
else start = arrayvar;
|
||||||
|
|
||||||
if (index->isConstant())
|
if (index->isConstant())
|
||||||
{
|
{
|
||||||
unsigned indexval = static_cast<FxConstant *>(index)->GetValue().GetInt();
|
unsigned indexval = static_cast<FxConstant *>(index)->GetValue().GetInt();
|
||||||
assert(SizeAddr != ~0u || (indexval < arraytype->ElementCount && "Array index out of bounds"));
|
assert(SizeAddr != ~0u || nestedarray || (indexval < arraytype->ElementCount && "Array index out of bounds"));
|
||||||
|
|
||||||
// For resizable arrays we even need to check the bounds if if the index is constant because they are not known at compile time.
|
// For resizable arrays we even need to check the bounds if if the index is constant because they are not known at compile time.
|
||||||
if (SizeAddr != ~0u)
|
if (SizeAddr != ~0u || nestedarray)
|
||||||
{
|
{
|
||||||
ExpEmit indexreg(build, REGT_INT);
|
ExpEmit indexreg(build, REGT_INT);
|
||||||
build->EmitLoadInt(indexreg.RegNum, indexval);
|
build->EmitLoadInt(indexreg.RegNum, indexval);
|
||||||
|
|
|
@ -2147,19 +2147,14 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon
|
||||||
{
|
{
|
||||||
if (arc.isWriting())
|
if (arc.isWriting())
|
||||||
{
|
{
|
||||||
FName n = font->GetName();
|
FName n = font? font->GetName() : NAME_None;
|
||||||
return arc(key, n);
|
return arc(key, n);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FName n = NAME_None;
|
FName n = NAME_None;
|
||||||
arc(key, n);
|
arc(key, n);
|
||||||
font = V_GetFont(n);
|
font = n == NAME_None? nullptr : V_GetFont(n);
|
||||||
if (font == nullptr)
|
|
||||||
{
|
|
||||||
Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n.GetChars());
|
|
||||||
font = SmallFont;
|
|
||||||
}
|
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -828,7 +828,7 @@ void cmsg(int type, int verbosity_level, const char *fmt, ...)
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsprintf(buf, fmt, args);
|
myvsnprintf(buf, sizeof buf, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
I_DebugPrint(buf);
|
I_DebugPrint(buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -426,6 +426,7 @@ void FormatGUID (char *buffer, size_t buffsize, const GUID &guid)
|
||||||
|
|
||||||
const char *myasctime ()
|
const char *myasctime ()
|
||||||
{
|
{
|
||||||
|
static char readabletime[50];
|
||||||
time_t clock;
|
time_t clock;
|
||||||
struct tm *lt;
|
struct tm *lt;
|
||||||
|
|
||||||
|
@ -433,11 +434,12 @@ const char *myasctime ()
|
||||||
lt = localtime (&clock);
|
lt = localtime (&clock);
|
||||||
if (lt != NULL)
|
if (lt != NULL)
|
||||||
{
|
{
|
||||||
return asctime (lt);
|
strftime(readabletime, 50, "%F %T", lt);
|
||||||
|
return readabletime;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "Pre Jan 01 00:00:00 1970\n";
|
return "Unknown\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1029,6 +1029,7 @@ xx(Kickback)
|
||||||
xx(MinSelAmmo1)
|
xx(MinSelAmmo1)
|
||||||
xx(bDehAmmo)
|
xx(bDehAmmo)
|
||||||
xx(FOVScale)
|
xx(FOVScale)
|
||||||
|
xx(LookScale)
|
||||||
xx(YAdjust)
|
xx(YAdjust)
|
||||||
xx(Crosshair)
|
xx(Crosshair)
|
||||||
xx(WeaponFlags)
|
xx(WeaponFlags)
|
||||||
|
|
|
@ -87,7 +87,7 @@ void FStat::PrintStat ()
|
||||||
{
|
{
|
||||||
int textScale = active_con_scale();
|
int textScale = active_con_scale();
|
||||||
|
|
||||||
int fontheight = ConFont->GetHeight() + 1;
|
int fontheight = NewConsoleFont->GetHeight() + 1;
|
||||||
int y = SCREENHEIGHT / textScale;
|
int y = SCREENHEIGHT / textScale;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ void FStat::PrintStat ()
|
||||||
// Count number of linefeeds but ignore terminating ones.
|
// Count number of linefeeds but ignore terminating ones.
|
||||||
if (stattext[i] == '\n') y -= fontheight;
|
if (stattext[i] == '\n') y -= fontheight;
|
||||||
}
|
}
|
||||||
screen->DrawText(ConFont, CR_GREEN, 5 / textScale, y, stattext,
|
screen->DrawText(NewConsoleFont, CR_GREEN, 5 / textScale, y, stattext,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
DTA_KeepRatio, true, TAG_DONE);
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
int utf8_encode(int32_t codepoint, uint8_t *buffer, int *size);
|
int utf8_encode(int32_t codepoint, uint8_t *buffer, int *size);
|
||||||
int utf8_decode(const uint8_t *src, int *size);
|
int utf8_decode(const uint8_t *src, int *size);
|
||||||
int GetCharFromString(const uint8_t *&string);
|
int GetCharFromString(const uint8_t *&string);
|
||||||
|
inline int GetCharFromString(const char32_t *&string)
|
||||||
|
{
|
||||||
|
return *string++;
|
||||||
|
}
|
||||||
const char *MakeUTF8(const char *outline, int *numchars = nullptr); // returns a pointer to a static buffer, assuming that its caller will immediately process the result.
|
const char *MakeUTF8(const char *outline, int *numchars = nullptr); // returns a pointer to a static buffer, assuming that its caller will immediately process the result.
|
||||||
const char *MakeUTF8(int codepoint, int *psize = nullptr);
|
const char *MakeUTF8(int codepoint, int *psize = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ zip_file_t *zip_fopen(zip_t *zipfile, const char *filename)
|
||||||
if (!zipfile || !filename) return NULL;
|
if (!zipfile || !filename) return NULL;
|
||||||
auto lump = zipfile->FindLump(filename);
|
auto lump = zipfile->FindLump(filename);
|
||||||
if (!lump) return NULL;
|
if (!lump) return NULL;
|
||||||
return new FileReader(std::move(lump->NewReader()));
|
return new FileReader(lump->NewReader());
|
||||||
}
|
}
|
||||||
|
|
||||||
void zip_fclose(zip_file_t *zippedfile)
|
void zip_fclose(zip_file_t *zippedfile)
|
||||||
|
|
|
@ -393,8 +393,8 @@ size_t FString::CharacterCount() const
|
||||||
|
|
||||||
int FString::GetNextCharacter(int &position) const
|
int FString::GetNextCharacter(int &position) const
|
||||||
{
|
{
|
||||||
const uint8_t *cp = (const uint8_t*)Chars;
|
const uint8_t *cp = (const uint8_t*)Chars + position;
|
||||||
const uint8_t *cpread = cp + position;
|
const uint8_t *cpread = cp;
|
||||||
int chr = GetCharFromString(cpread);
|
int chr = GetCharFromString(cpread);
|
||||||
position += int(cpread - cp);
|
position += int(cpread - cp);
|
||||||
return chr;
|
return chr;
|
||||||
|
@ -828,12 +828,12 @@ void FString::StripLeftRight ()
|
||||||
if (max == 0) return;
|
if (max == 0) return;
|
||||||
for (i = 0; i < max; ++i)
|
for (i = 0; i < max; ++i)
|
||||||
{
|
{
|
||||||
if (!isspace((unsigned char)Chars[i]))
|
if (Chars[i] < 0 || !isspace((unsigned char)Chars[i]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (j = max - 1; j >= i; --j)
|
for (j = max - 1; j >= i; --j)
|
||||||
{
|
{
|
||||||
if (!isspace((unsigned char)Chars[j]))
|
if (Chars[i] < 0 || !isspace((unsigned char)Chars[j]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == 0 && j == max - 1)
|
if (i == 0 && j == max - 1)
|
||||||
|
|
|
@ -202,11 +202,6 @@ void DFrameBuffer::DrawRateStuff ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void DFrameBuffer::GetFlashedPalette(PalEntry pal[256])
|
|
||||||
{
|
|
||||||
DoBlending(SourcePalette, pal, 256, Flash.r, Flash.g, Flash.b, Flash.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DFrameBuffer::Update()
|
void DFrameBuffer::Update()
|
||||||
{
|
{
|
||||||
CheckBench();
|
CheckBench();
|
||||||
|
@ -225,24 +220,6 @@ void DFrameBuffer::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PalEntry *DFrameBuffer::GetPalette()
|
|
||||||
{
|
|
||||||
return SourcePalette;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DFrameBuffer::SetFlash(PalEntry rgb, int amount)
|
|
||||||
{
|
|
||||||
Flash = PalEntry(amount, rgb.r, rgb.g, rgb.b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DFrameBuffer::GetFlash(PalEntry &rgb, int &amount)
|
|
||||||
{
|
|
||||||
rgb = Flash;
|
|
||||||
rgb.a = 0;
|
|
||||||
amount = Flash.a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DFrameBuffer::SetClearColor(int color)
|
void DFrameBuffer::SetClearColor(int color)
|
||||||
{
|
{
|
||||||
PalEntry pe = GPalette.BaseColors[color];
|
PalEntry pe = GPalette.BaseColors[color];
|
||||||
|
@ -293,18 +270,6 @@ FTexture *DFrameBuffer::WipeEndScreen()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// DFrameBuffer :: InitPalette
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void DFrameBuffer::InitPalette()
|
|
||||||
{
|
|
||||||
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
|
||||||
UpdatePalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DFrameBuffer :: GetCaps
|
// DFrameBuffer :: GetCaps
|
||||||
|
|
|
@ -443,29 +443,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void V_SetBlend (int blendr, int blendg, int blendb, int blenda)
|
|
||||||
{
|
|
||||||
// Don't do anything if the new blend is the same as the old
|
|
||||||
if (((blenda|BlendA) == 0) ||
|
|
||||||
(blendr == BlendR &&
|
|
||||||
blendg == BlendG &&
|
|
||||||
blendb == BlendB &&
|
|
||||||
blenda == BlendA))
|
|
||||||
return;
|
|
||||||
|
|
||||||
V_ForceBlend (blendr, blendg, blendb, blenda);
|
|
||||||
}
|
|
||||||
|
|
||||||
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda)
|
|
||||||
{
|
|
||||||
BlendR = blendr;
|
|
||||||
BlendG = blendg;
|
|
||||||
BlendB = blendb;
|
|
||||||
BlendA = blenda;
|
|
||||||
|
|
||||||
screen->SetFlash (PalEntry (BlendR, BlendG, BlendB), BlendA);
|
|
||||||
}
|
|
||||||
|
|
||||||
CCMD (testblend)
|
CCMD (testblend)
|
||||||
{
|
{
|
||||||
FString colorstring;
|
FString colorstring;
|
||||||
|
|
|
@ -77,23 +77,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
|
||||||
void ReadPalette(int lumpnum, uint8_t *buffer);
|
void ReadPalette(int lumpnum, uint8_t *buffer);
|
||||||
void InitPalette ();
|
void InitPalette ();
|
||||||
|
|
||||||
// V_SetBlend()
|
|
||||||
// input: blendr: red component of blend
|
|
||||||
// blendg: green component of blend
|
|
||||||
// blendb: blue component of blend
|
|
||||||
// blenda: alpha component of blend
|
|
||||||
//
|
|
||||||
// Applies the blend to all palettes with PALETTEF_BLEND flag
|
|
||||||
void V_SetBlend (int blendr, int blendg, int blendb, int blenda);
|
|
||||||
|
|
||||||
// V_ForceBlend()
|
|
||||||
//
|
|
||||||
// Normally, V_SetBlend() does nothing if the new blend is the
|
|
||||||
// same as the old. This function will perform the blending
|
|
||||||
// even if the blend hasn't changed.
|
|
||||||
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda);
|
|
||||||
|
|
||||||
|
|
||||||
EXTERN_CVAR (Int, paletteflash)
|
EXTERN_CVAR (Int, paletteflash)
|
||||||
enum PaletteFlashFlags
|
enum PaletteFlashFlags
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,7 +145,7 @@ public:
|
||||||
|
|
||||||
int DisplayWidth, DisplayHeight;
|
int DisplayWidth, DisplayHeight;
|
||||||
|
|
||||||
FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont;
|
FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont;
|
||||||
|
|
||||||
uint32_t Col2RGB8[65][256];
|
uint32_t Col2RGB8[65][256];
|
||||||
uint32_t *Col2RGB8_LessPrecision[65];
|
uint32_t *Col2RGB8_LessPrecision[65];
|
||||||
|
@ -539,13 +539,10 @@ CCMD(clean)
|
||||||
|
|
||||||
|
|
||||||
void V_UpdateModeSize (int width, int height)
|
void V_UpdateModeSize (int width, int height)
|
||||||
{
|
{
|
||||||
int cx1, cx2;
|
// This calculates the menu scale.
|
||||||
V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2);
|
// The optimal scale will always be to fit a virtual 640 pixel wide display onto the screen.
|
||||||
|
// Exceptions are made for a few ranges where the available virtual width is > 480.
|
||||||
CleanWidth = width / CleanXfac;
|
|
||||||
CleanHeight = height / CleanYfac;
|
|
||||||
assert(CleanWidth >= 320 && CleanHeight >= 200);
|
|
||||||
|
|
||||||
int w = screen->GetWidth();
|
int w = screen->GetWidth();
|
||||||
int factor;
|
int factor;
|
||||||
|
@ -554,7 +551,11 @@ void V_UpdateModeSize (int width, int height)
|
||||||
else if (w >= 1600 && w < 1920) factor = 3;
|
else if (w >= 1600 && w < 1920) factor = 3;
|
||||||
else factor = w / 640;
|
else factor = w / 640;
|
||||||
|
|
||||||
CleanXfac_1 = CleanYfac_1 = factor;
|
CleanXfac = CleanYfac = factor;
|
||||||
|
CleanWidth = width / CleanXfac;
|
||||||
|
CleanHeight = height / CleanYfac;
|
||||||
|
|
||||||
|
CleanYfac_1 = CleanXfac_1 = MAX(1, int (CleanXfac * 0.7));
|
||||||
CleanWidth_1 = width / CleanXfac_1;
|
CleanWidth_1 = width / CleanXfac_1;
|
||||||
CleanHeight_1 = height / CleanYfac_1;
|
CleanHeight_1 = height / CleanYfac_1;
|
||||||
|
|
||||||
|
@ -581,52 +582,8 @@ void V_OutputResized (int width, int height)
|
||||||
|
|
||||||
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)
|
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)
|
||||||
{
|
{
|
||||||
float ratio;
|
if (designheight < 240 && realheight >= 480) designheight = 240;
|
||||||
int cwidth;
|
*cleanx = *cleany = std::min(realwidth / designwidth, realheight / designheight);
|
||||||
int cheight;
|
|
||||||
int cx1, cy1, cx2, cy2;
|
|
||||||
|
|
||||||
// For larger screems always use at least a 16:9 ratio for clean factor calculation, even if the actual ratio is narrower.
|
|
||||||
if (realwidth > 1280 && (double)realwidth / realheight < 16./9)
|
|
||||||
{
|
|
||||||
realheight = realwidth * 9 / 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
ratio = ActiveRatio(realwidth, realheight);
|
|
||||||
if (AspectTallerThanWide(ratio))
|
|
||||||
{
|
|
||||||
cwidth = realwidth;
|
|
||||||
cheight = realheight * AspectMultiplier(ratio) / 48;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cwidth = realwidth * AspectMultiplier(ratio) / 48;
|
|
||||||
cheight = realheight;
|
|
||||||
}
|
|
||||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
|
||||||
// between CleanXfac and CleanYfac.
|
|
||||||
cx1 = MAX(cwidth / designwidth, 1);
|
|
||||||
cy1 = MAX(cheight / designheight, 1);
|
|
||||||
cx2 = MAX(realwidth / designwidth, 1);
|
|
||||||
cy2 = MAX(realheight / designheight, 1);
|
|
||||||
if (abs(cx1 - cy1) <= abs(cx2 - cy2) || MAX(cx1, cx2) >= 4)
|
|
||||||
{ // e.g. 640x360 looks better with this.
|
|
||||||
*cleanx = cx1;
|
|
||||||
*cleany = cy1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // e.g. 720x480 looks better with this.
|
|
||||||
*cleanx = cx2;
|
|
||||||
*cleany = cy2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*cleanx < *cleany)
|
|
||||||
*cleany = *cleanx;
|
|
||||||
else
|
|
||||||
*cleanx = *cleany;
|
|
||||||
|
|
||||||
if (_cx1 != NULL) *_cx1 = cx1;
|
|
||||||
if (_cx2 != NULL) *_cx2 = cx2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IVideo::SetResolution ()
|
bool IVideo::SetResolution ()
|
||||||
|
@ -696,9 +653,6 @@ void V_Init (bool restart)
|
||||||
// Update screen palette when restarting
|
// Update screen palette when restarting
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PalEntry *palette = screen->GetPalette ();
|
|
||||||
for (int i = 0; i < 256; ++i)
|
|
||||||
*palette++ = GPalette.BaseColors[i];
|
|
||||||
screen->UpdatePalette();
|
screen->UpdatePalette();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,6 +907,8 @@ DEFINE_GLOBAL(SmallFont)
|
||||||
DEFINE_GLOBAL(SmallFont2)
|
DEFINE_GLOBAL(SmallFont2)
|
||||||
DEFINE_GLOBAL(BigFont)
|
DEFINE_GLOBAL(BigFont)
|
||||||
DEFINE_GLOBAL(ConFont)
|
DEFINE_GLOBAL(ConFont)
|
||||||
|
DEFINE_GLOBAL(NewConsoleFont)
|
||||||
|
DEFINE_GLOBAL(NewSmallFont)
|
||||||
DEFINE_GLOBAL(IntermissionFont)
|
DEFINE_GLOBAL(IntermissionFont)
|
||||||
DEFINE_GLOBAL(CleanXfac)
|
DEFINE_GLOBAL(CleanXfac)
|
||||||
DEFINE_GLOBAL(CleanYfac)
|
DEFINE_GLOBAL(CleanYfac)
|
||||||
|
|
|
@ -343,7 +343,8 @@ protected:
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const;
|
bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const;
|
||||||
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);
|
template<class T>
|
||||||
|
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const T *string, DrawParms &parms);
|
||||||
|
|
||||||
F2DDrawer m2DDrawer;
|
F2DDrawer m2DDrawer;
|
||||||
private:
|
private:
|
||||||
|
@ -352,16 +353,12 @@ private:
|
||||||
protected:
|
protected:
|
||||||
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
|
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
|
||||||
|
|
||||||
PalEntry Flash; // Only needed to support some cruft in the interface that only makes sense for the software renderer
|
|
||||||
PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Hardware render state that needs to be exposed to the API independent part of the renderer. For ease of access this is stored in the base class.
|
// Hardware render state that needs to be exposed to the API independent part of the renderer. For ease of access this is stored in the base class.
|
||||||
int hwcaps = 0; // Capability flags
|
int hwcaps = 0; // Capability flags
|
||||||
float glslversion = 0; // This is here so that the differences between old OpenGL and new OpenGL/Vulkan can be handled by platform independent code.
|
float glslversion = 0; // This is here so that the differences between old OpenGL and new OpenGL/Vulkan can be handled by platform independent code.
|
||||||
int instack[2] = { 0,0 }; // this is globally maintained state for portal recursion avoidance.
|
int instack[2] = { 0,0 }; // this is globally maintained state for portal recursion avoidance.
|
||||||
int stencilValue = 0; // Global stencil test value
|
int stencilValue = 0; // Global stencil test value
|
||||||
bool enable_quadbuffered = false; // Quad-buffered stereo available?
|
|
||||||
unsigned int uniformblockalignment = 256; // Hardware dependent uniform buffer alignment.
|
unsigned int uniformblockalignment = 256; // Hardware dependent uniform buffer alignment.
|
||||||
unsigned int maxuniformblock = 65536;
|
unsigned int maxuniformblock = 65536;
|
||||||
const char *gl_vendorstring; // On OpenGL (not Vulkan) we have to account for some issues with Intel.
|
const char *gl_vendorstring; // On OpenGL (not Vulkan) we have to account for some issues with Intel.
|
||||||
|
@ -405,26 +402,12 @@ public:
|
||||||
// Make the surface visible.
|
// Make the surface visible.
|
||||||
virtual void Update ();
|
virtual void Update ();
|
||||||
|
|
||||||
// Return a pointer to 256 palette entries that can be written to.
|
|
||||||
PalEntry *GetPalette ();
|
|
||||||
|
|
||||||
// Stores the palette with flash blended in into 256 dwords
|
// Stores the palette with flash blended in into 256 dwords
|
||||||
void GetFlashedPalette (PalEntry palette[256]);
|
|
||||||
|
|
||||||
// Mark the palette as changed. It will be updated on the next Update().
|
// Mark the palette as changed. It will be updated on the next Update().
|
||||||
virtual void UpdatePalette() {}
|
virtual void UpdatePalette() {}
|
||||||
|
|
||||||
virtual void SetGamma() {}
|
virtual void SetGamma() {}
|
||||||
|
|
||||||
// Sets a color flash. RGB is the color, and amount is 0-256, with 256
|
|
||||||
// being all flash and 0 being no flash. Returns false if the hardware
|
|
||||||
// does not support this. (Always true for now, since palettes can always
|
|
||||||
// be flashed.)
|
|
||||||
bool SetFlash (PalEntry rgb, int amount);
|
|
||||||
|
|
||||||
// Converse of SetFlash
|
|
||||||
void GetFlash (PalEntry &rgb, int &amount);
|
|
||||||
|
|
||||||
// Returns true if running fullscreen.
|
// Returns true if running fullscreen.
|
||||||
virtual bool IsFullscreen () = 0;
|
virtual bool IsFullscreen () = 0;
|
||||||
virtual void ToggleFullscreen(bool yes) {}
|
virtual void ToggleFullscreen(bool yes) {}
|
||||||
|
@ -476,7 +459,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report a game restart
|
// Report a game restart
|
||||||
void InitPalette();
|
|
||||||
void SetClearColor(int color);
|
void SetClearColor(int color);
|
||||||
virtual uint32_t GetCaps();
|
virtual uint32_t GetCaps();
|
||||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
||||||
|
@ -503,6 +485,7 @@ public:
|
||||||
// Dim part of the canvas
|
// Dim part of the canvas
|
||||||
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
|
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
|
||||||
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
|
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
|
||||||
|
FVector4 CalcBlend(sector_t * viewsector, PalEntry *modulateColor);
|
||||||
void DrawBlend(sector_t * viewsector);
|
void DrawBlend(sector_t * viewsector);
|
||||||
|
|
||||||
// Fill an area with a texture
|
// Fill an area with a texture
|
||||||
|
@ -547,6 +530,7 @@ public:
|
||||||
void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args);
|
void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args);
|
||||||
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...);
|
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...);
|
||||||
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args);
|
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args);
|
||||||
|
void DrawText(FFont *font, int normalcolor, double x, double y, const char32_t *string, int tag_first, ...);
|
||||||
|
|
||||||
void DrawFrame(int left, int top, int width, int height);
|
void DrawFrame(int left, int top, int width, int height);
|
||||||
void DrawBorder(FTextureID, int x1, int y1, int x2, int y2);
|
void DrawBorder(FTextureID, int x1, int y1, int x2, int y2);
|
||||||
|
@ -627,20 +611,52 @@ bool AspectTallerThanWide(float aspect);
|
||||||
void ScaleWithAspect(int &w, int &h, int Width, int Height);
|
void ScaleWithAspect(int &w, int &h, int Width, int Height);
|
||||||
|
|
||||||
int GetUIScale(int altval);
|
int GetUIScale(int altval);
|
||||||
|
int GetConScale(int altval);
|
||||||
|
|
||||||
EXTERN_CVAR(Int, uiscale);
|
EXTERN_CVAR(Int, uiscale);
|
||||||
EXTERN_CVAR(Int, con_scaletext);
|
EXTERN_CVAR(Int, con_scaletext);
|
||||||
EXTERN_CVAR(Int, con_scale);
|
EXTERN_CVAR(Int, con_scale);
|
||||||
|
|
||||||
inline int active_con_scaletext()
|
inline int active_con_scaletext(bool newconfont = false)
|
||||||
{
|
{
|
||||||
return GetUIScale(con_scaletext);
|
return newconfont? GetConScale(con_scaletext) : GetUIScale(con_scaletext);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int active_con_scale()
|
inline int active_con_scale()
|
||||||
{
|
{
|
||||||
return GetUIScale(con_scale);
|
return GetConScale(con_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ScaleOverrider
|
||||||
|
{
|
||||||
|
int savedxfac, savedyfac, savedwidth, savedheight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// This is to allow certain elements to use an optimal fullscreen scale which for the menu would be too large.
|
||||||
|
// The old code contained far too much mess to compensate for the menus which negatively affected everything else.
|
||||||
|
// However, for compatibility reasons the currently used variables cannot be changed so they have to be overridden temporarily.
|
||||||
|
// This class provides a safe interface for this because it ensures that the values get restored afterward.
|
||||||
|
// Currently, the intermission and the level summary screen use this.
|
||||||
|
ScaleOverrider()
|
||||||
|
{
|
||||||
|
savedxfac = CleanXfac;
|
||||||
|
savedyfac = CleanYfac;
|
||||||
|
savedwidth = CleanWidth;
|
||||||
|
savedheight = CleanHeight;
|
||||||
|
V_CalcCleanFacs(320, 200, screen->GetWidth(), screen->GetHeight(), &CleanXfac, &CleanYfac);
|
||||||
|
CleanWidth = screen->GetWidth() / CleanXfac;
|
||||||
|
CleanHeight = screen->GetHeight() / CleanYfac;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScaleOverrider()
|
||||||
|
{
|
||||||
|
CleanXfac = savedxfac;
|
||||||
|
CleanYfac = savedyfac;
|
||||||
|
CleanWidth = savedwidth;
|
||||||
|
CleanHeight = savedheight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // __V_VIDEO_H__
|
#endif // __V_VIDEO_H__
|
||||||
|
|
|
@ -701,6 +701,7 @@ void WI_Ticker()
|
||||||
{
|
{
|
||||||
if (WI_Screen)
|
if (WI_Screen)
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
|
||||||
{
|
{
|
||||||
VMValue self = WI_Screen;
|
VMValue self = WI_Screen;
|
||||||
|
@ -720,6 +721,7 @@ void WI_Drawer()
|
||||||
{
|
{
|
||||||
if (WI_Screen)
|
if (WI_Screen)
|
||||||
{
|
{
|
||||||
|
ScaleOverrider s;
|
||||||
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
|
||||||
{
|
{
|
||||||
VMValue self = WI_Screen;
|
VMValue self = WI_Screen;
|
||||||
|
@ -761,13 +763,13 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V_SetBlend(0, 0, 0, 0);
|
|
||||||
S_StopAllChannels();
|
S_StopAllChannels();
|
||||||
for (auto Level : AllLevels())
|
for (auto Level : AllLevels())
|
||||||
{
|
{
|
||||||
SN_StopAllSequences(Level);
|
SN_StopAllSequences(Level);
|
||||||
}
|
}
|
||||||
WI_Screen = cls->CreateNew();
|
WI_Screen = cls->CreateNew();
|
||||||
|
ScaleOverrider s;
|
||||||
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start)
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start)
|
||||||
{
|
{
|
||||||
VMValue val[2] = { WI_Screen, wbstartstruct };
|
VMValue val[2] = { WI_Screen, wbstartstruct };
|
||||||
|
|
|
@ -56,14 +56,6 @@ extern HWND Window;
|
||||||
|
|
||||||
PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
|
PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
|
||||||
|
|
||||||
// For broadest GL compatibility, require user to explicitly enable quad-buffered stereo mode.
|
|
||||||
// Setting vr_enable_quadbuffered_stereo does not automatically invoke quad-buffered stereo,
|
|
||||||
// but makes it possible for subsequent "vr_mode 7" to invoke quad-buffered stereo
|
|
||||||
CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
|
||||||
{
|
|
||||||
Printf("You must restart " GAMENAME " to switch quad stereo mode\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Windows framebuffer
|
// Windows framebuffer
|
||||||
|
@ -111,7 +103,6 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : Syst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReleaseDC(Window, hDC);
|
ReleaseDC(Window, hDC);
|
||||||
enable_quadbuffered = vr_enable_quadbuffered;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -433,7 +433,7 @@ void Writef (HANDLE file, const char *format, ...)
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
len = vsprintf (buffer, format, args);
|
len = myvsnprintf (buffer, sizeof buffer, format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
WriteFile (file, buffer, len, &len, NULL);
|
WriteFile (file, buffer, len, &len, NULL);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue