- various engine updates from Raze.

* removed refreshFreq variable and related code. This only got into the backend because of stupid interpolation code in some of the Build games which has long been removed.
* save FixedBitArrays as base64 in savegames.
* allow indirections in the string table - by prefixing the language string with '$$' the remaining text is interpreted as another string label to resolve.
* constexpr in palette code, also replacing #defines with enums.
This commit is contained in:
Christoph Oelckers 2020-09-27 10:17:58 +02:00
parent c65f707a20
commit 96ceb11af0
21 changed files with 209 additions and 51 deletions

View file

@ -1091,6 +1091,7 @@ set (PCH_SOURCES
common/utility/zstrformat.cpp
common/utility/name.cpp
common/utility/r_memory.cpp
common/thirdparty/base64.cpp
common/thirdparty/md5.cpp
common/thirdparty/superfasthash.cpp
common/filesystem/filesystem.cpp

View file

@ -262,7 +262,7 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
double scaley = parms.scaley * parms.patchscaley;
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
parms.celly *= scaley;
parms.celly = int (parms.celly * scaley);
bool palettetrans = (normalcolor == CR_UNDEFINED && parms.TranslationId != 0);

View file

@ -41,6 +41,7 @@
#include "utf8.h"
#include "m_joy.h"
#include "vm.h"
#include "gamestate.h"
bool G_Responder(event_t* ev);
@ -69,6 +70,8 @@ void D_ProcessEvents (void)
continue;
if (ev->type == EV_DeviceChange)
UpdateJoystickMenu(I_UpdateDeviceList());
if (gamestate == GS_INTRO)
continue;
if (C_Responder (ev))
continue; // console ate the event
if (M_Responder (ev))

View file

@ -6,4 +6,4 @@ void I_PutInClipboard (const char *str);
FString I_GetFromClipboard (bool use_primary_selection);
void I_SetMouseCapture();
void I_ReleaseMouseCapture();
void I_GetEvent();

View file

@ -2,7 +2,6 @@
// Some global engine variables taken out of the backend code.
SystemCallbacks *sysCallbacks;
double refreshfreq;
FString endoomName;
bool batchrun;
float menuBlurAmount;

View file

@ -18,6 +18,7 @@ struct SystemCallbacks
IntRect(*GetSceneRect)();
FString(*GetLocationDescription)();
void (*MenuDim)();
FString(*GetPlayerName)(int i);
};
extern SystemCallbacks *sysCallbacks;

View file

@ -1074,4 +1074,5 @@ xx(PlayerColors)
xx(PlayerSkin)
xx(NewPlayerMenu)
xx(AltHud)
xx(GameScreen)

View file

@ -36,6 +36,7 @@ struct FRemapTable
bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL
bool TwodOnly = false; // Only used for 2D rendering
bool ForFont = false; // Mark font translations because they may require different handling than the ones for sprites-
bool NoTransparency = false; // This palette has no transparent index and must be excluded from all treatment for that.
private:
};
@ -58,19 +59,22 @@ private:
};
#define TRANSLATION_SHIFT 16
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
enum
{
TRANSLATION_SHIFT = 16,
TRANSLATION_MASK = ((1 << TRANSLATION_SHIFT) - 1),
TRANSLATIONTYPE_MASK = (255 << TRANSLATION_SHIFT)
};
inline uint32_t TRANSLATION(uint8_t a, uint32_t b)
inline constexpr uint32_t TRANSLATION(uint8_t a, uint32_t b)
{
return (a << TRANSLATION_SHIFT) | b;
}
inline int GetTranslationType(uint32_t trans)
inline constexpr int GetTranslationType(uint32_t trans)
{
return (trans & TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
}
inline int GetTranslationIndex(uint32_t trans)
inline constexpr int GetTranslationIndex(uint32_t trans)
{
return (trans & TRANSLATION_MASK);
}

View file

@ -61,7 +61,7 @@ enum
PRINT_TYPES = 1023, // Bitmask.
PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer
PRINT_NOLOG = 2048, // Flag - do not print to log file
PRINT_NOTIFY = 4096, // Flag - add to notify buffer
PRINT_NOTIFY = 4096, // Flag - add to game-native notify display - messages without this only go to the generic notification buffer.
};
enum

View file

@ -54,6 +54,7 @@
#include "engineerrors.h"
#include "textures.h"
#include "texturemanager.h"
#include "base64.h"
extern DObject *WP_NOCHANGE;
bool save_full = false; // for testing. Should be removed afterward.
@ -772,6 +773,31 @@ error:
return buff;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &FSerializer::SerializeMemory(const char *key, void* mem, size_t length)
{
if (isWriting())
{
auto array = base64_encode((const uint8_t*)mem, length);
AddString(key, (const char*)array.Data());
}
else
{
auto cp = GetString(key);
if (key)
{
base64_decode(mem, length, cp);
}
}
return *this;
}
//==========================================================================
//
//

View file

@ -95,6 +95,7 @@ public:
virtual FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def);
// This is only needed by the type system.
virtual FSerializer& StatePointer(const char* key, void* ptraddr, bool *res);
FSerializer& SerializeMemory(const char* key, void* mem, size_t length);
FSerializer &StringPtr(const char *key, const char *&charptr); // This only retrieves the address but creates no permanent copy of the string unlike the regular char* serializer.
FSerializer &AddString(const char *key, const char *charptr);
@ -219,7 +220,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value,
{
if (arc.isWriting())
{
if (value.Size() == 0) return arc; // do not save empty arrays
if (value.Size() == 0 && key) return arc; // do not save empty arrays
}
bool res = arc.BeginArray(key);
if (arc.isReading())

View file

@ -575,7 +575,10 @@ const char *FStringTable::GetString(const char *name, uint32_t *langtable, int g
if (item)
{
if (langtable) *langtable = map.first;
return item->strings[gender].GetChars();
auto c = item->strings[gender].GetChars();
if (c && *c == '$' && c[1] == '$')
return GetString(c + 2, langtable, gender);
return c;
}
}
}

View file

@ -110,6 +110,8 @@ public:
bool exists(const char *name);
void SetCallbacks(StringtableCallbacks* cb) { callbacks = cb; }
void InsertString(int lumpnum, int langid, FName label, const FString& string);
private:
FString activeLanguage;
@ -124,7 +126,6 @@ private:
bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray<uint8_t> &buffer);
bool readMacros(int lumpnum);
void InsertString(int lumpnum, int langid, FName label, const FString &string);
void DeleteString(int langid, FName label);
void DeleteForLabel(int lumpnum, FName label);

View file

@ -75,7 +75,6 @@
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern double refreshfreq;
extern IVideo *Video;
EXTERN_CVAR (Int, vid_adapter)
@ -451,19 +450,6 @@ SDLVideo::SDLVideo ()
Priv::CreateWindow(SDL_WINDOW_HIDDEN);
}
#endif
// Get refresh rate for current display.
SDL_DisplayMode display;
if(SDL_GetCurrentDisplayMode(vid_adapter, &display) == 0)
{
refreshfreq = display.refresh_rate;
}
else
{
fprintf(stderr, "Failed to get refresh rate: %s\n", SDL_GetError());
return;
}
}
SDLVideo::~SDLVideo ()

View file

@ -58,7 +58,6 @@ extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
void GetRefreshRate(HWND hWnd);
EXTERN_CVAR(Int, vid_defwidth)
EXTERN_CVAR(Int, vid_defheight)
@ -339,7 +338,6 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen, bool initialcall)
}
m_Fullscreen = fullscreen;
SetSize(GetClientWidth(), GetClientHeight());
GetRefreshRate(Window);
}
//==========================================================================

View file

@ -109,7 +109,7 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : Syst
//
//==========================================================================
EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, gl_control_tear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
vid_vsync.Callback();
}

View file

@ -135,8 +135,7 @@ LPDIRECTINPUT g_pdi3;
extern bool AppActive;
int SessionState = 0;
int BlockMouseMove;
extern double refreshfreq;
int BlockMouseMove;
static bool EventHandlerResultForNativeMouse;
@ -345,22 +344,6 @@ bool CallHook(FInputDevice *device, HWND hWnd, UINT message, WPARAM wParam, LPAR
return device->WndProcHook(hWnd, message, wParam, lParam, result);
}
void GetRefreshRate(HWND hWnd)
{
HMONITOR moni = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFOEXA moninf;
moninf.cbSize = sizeof(moninf);
if (GetMonitorInfoA(moni, (LPMONITORINFO)&moninf))
{
DEVMODEA dm;
dm.dmSize = sizeof(DEVMODEA);
if (EnumDisplaySettingsA(moninf.szDevice, ENUM_CURRENT_SETTINGS, &dm))
{
refreshfreq = dm.dmDisplayFrequency;
}
}
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result;
@ -446,7 +429,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_SETFOCUS:
GetRefreshRate(hWnd);
I_CheckNativeMouse (false, EventHandlerResultForNativeMouse); // This cannot call the event handler. Doing it from here is unsafe.
break;
@ -491,8 +473,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_DISPLAYCHANGE:
GetRefreshRate(hWnd);
// fall through
case WM_STYLECHANGED:
return DefWindowProc(hWnd, message, wParam, lParam);

View file

@ -277,6 +277,8 @@ void FKeyboard::PostKeyEvent(int key, INTBOOL down, bool foreground)
}
ev.data1 = key;
ev.data2 = Convert[key];
ev.data3 = 0;
if (CheckKey(DIK_LSHIFT) || CheckKey(DIK_RSHIFT)) ev.data3 |= 1;
D_PostEvent(&ev);
}

139
src/common/thirdparty/base64.cpp vendored Normal file
View file

@ -0,0 +1,139 @@
/*
base64.cpp and base64.h
base64 encoding and decoding with C++.
Version: 1.01.00
Copyright (C) 2004-2017 René Nyffenegger
Copyright (C) 2020 Christoph Oelckers
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
Addapted by Christoph Oelckers to FSerializer's needs where std::string is not a good container.
*/
#include <stdint.h>
#include "base64.h"
static const char *base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
inline int base64toindex(int c)
{
if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return -1;
}
static inline bool is_base64(unsigned char c) {
return base64toindex(c) >= 0;
}
TArray<uint8_t> base64_encode(unsigned char const* bytes_to_encode, size_t in_len) {
TArray<uint8_t> reta((in_len+5)/6 + 6);
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
reta.Push(base64_chars[char_array_4[i]]);
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++)
reta.Push(base64_chars[char_array_4[j]]);
while((i++ < 3))
reta.Push('=');
reta.Push(0);
}
return reta;
}
void base64_decode(void *memory, size_t maxlen, const char *encoded_string) {
size_t in_len = strlen(encoded_string);
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
uint8_t* dest = (uint8_t*)memory;
uint8_t* end = dest + maxlen;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64toindex(char_array_4[i]) & 0xff;
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
*dest++ = char_array_3[i];
if (dest >= end) return;
i = 0;
}
}
if (i) {
for (j = 0; j < i; j++)
char_array_4[j] = base64toindex(char_array_4[j]) & 0xff;
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
for (j = 0; (j < i - 1); j++)
{
*dest++ = char_array_3[j];
if (dest >= end) return;
}
}
while (dest < end) *dest++ = 0;
}

12
src/common/thirdparty/base64.h vendored Normal file
View file

@ -0,0 +1,12 @@
//
// base64 encoding and decoding with C++.
// Version: 1.01.00
//
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
TArray<uint8_t> base64_encode(unsigned char const* bytes_to_encode, size_t in_len);
void base64_decode(void* memory, size_t len, const char* encoded_string);
#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */

View file

@ -13,6 +13,7 @@ enum gamestate_t : int
GS_HIDECONSOLE, // [RH] The menu just did something that should hide fs console
GS_STARTUP, // [RH] Console is fullscreen, and game is just starting
GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN
GS_INTRO,
GS_FORCEWIPE = -1,
GS_FORCEWIPEFADE = -2,