Compare commits

..

1 commit

Author SHA1 Message Date
Rachael Alexanderson
9a068cf7c9
- version 1.10.0 2024-04-20 04:30:41 -04:00
186 changed files with 3055 additions and 4547 deletions

View file

@ -12,25 +12,28 @@ jobs:
config: config:
- name: Visual Studio 2022 - name: Visual Studio 2022
os: windows-2022 os: windows-2022
extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake
build_type: Release build_type: Release
- name: Visual Studio 2022 - name: Visual Studio 2022
os: windows-2022 os: windows-2022
extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake
build_type: Debug build_type: Debug
- name: Visual Studio 2019 - name: Visual Studio 2019
os: windows-2019 os: windows-2019
extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake
build_type: Release build_type: Release
- name: macOS - name: macOS
os: macos-14 os: macos-12
deps_cmdline: brew install libvpx deps_cmdline: brew install libvpx webp
build_type: Release build_type: Release
- name: macOS - name: macOS
os: macos-14 os: macos-12
extra_options: -G Xcode -DDYN_OPENAL=OFF extra_options: -G Xcode -DDYN_OPENAL=OFF
deps_cmdline: brew install libvpx deps_cmdline: brew install libvpx webp
build_type: Debug build_type: Debug
- name: Linux GCC 9 - name: Linux GCC 9
@ -68,9 +71,9 @@ jobs:
fi fi
mkdir build mkdir build
if [[ "${{ runner.os }}" == 'macOS' ]]; then if [[ "${{ runner.os }}" == 'macOS' ]]; then
export ZMUSIC_PACKAGE=zmusic-1.1.14-macos-arm.tar.xz export ZMUSIC_PACKAGE=zmusic-1.1.9-macos.tar.xz
elif [[ "${{ runner.os }}" == 'Linux' ]]; then elif [[ "${{ runner.os }}" == 'Linux' ]]; then
export ZMUSIC_PACKAGE=zmusic-1.1.14-linux.tar.xz export ZMUSIC_PACKAGE=zmusic-1.1.9-linux.tar.xz
fi fi
if [[ -n "${ZMUSIC_PACKAGE}" ]]; then if [[ -n "${ZMUSIC_PACKAGE}" ]]; then
cd build cd build
@ -78,6 +81,13 @@ jobs:
tar -xf "${ZMUSIC_PACKAGE}" tar -xf "${ZMUSIC_PACKAGE}"
fi fi
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
if: runner.os == 'Windows'
with:
vcpkgDirectory: '${{ github.workspace }}/build/vcpkg'
vcpkgGitCommitId: '2c401863dd54a640aeb26ed736c55489c079323b'
- name: Configure - name: Configure
shell: bash shell: bash
run: | run: |
@ -105,7 +115,7 @@ jobs:
- name: Upload Package - name: Upload Package
if: runner.os == 'Windows' # Remove to store packages of all targets if: runner.os == 'Windows' # Remove to store packages of all targets
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
path: build/package path: build/package
name: ${{ matrix.config.name }} ${{ matrix.config.build_type }} name: ${{ matrix.config.name }} ${{ matrix.config.build_type }}

View file

@ -321,7 +321,7 @@ else()
if ( UNIX ) if ( UNIX )
include(CheckSymbolExists) include(CheckSymbolExists)
check_symbol_exists( "fts_set" "sys/types.h;sys/stat.h;fts.h" HAVE_FTS ) check_symbol_exists( "fts_set" "fts.h" HAVE_FTS )
if ( NOT HAVE_FTS ) if ( NOT HAVE_FTS )
include ( FindPkgConfig ) include ( FindPkgConfig )
pkg_check_modules( MUSL_FTS musl-fts ) pkg_check_modules( MUSL_FTS musl-fts )
@ -343,7 +343,7 @@ else()
# If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc. # If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc.
set( ALL_C_FLAGS "-static-libgcc" ) set( ALL_C_FLAGS "-static-libgcc" )
endif() endif()
elseif( NOT MINGW AND NOT HAIKU ) elseif( NOT MINGW )
# Generic GCC/Clang requires position independent executable to be enabled explicitly # Generic GCC/Clang requires position independent executable to be enabled explicitly
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fPIE" ) set( ALL_C_FLAGS "${ALL_C_FLAGS} -fPIE" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie" ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie" )

Binary file not shown.

View file

@ -148,10 +148,9 @@ typedef enum EIntConfigKey_
zmusic_mod_autochip_scan_threshold, zmusic_mod_autochip_scan_threshold,
zmusic_snd_streambuffersize, zmusic_snd_streambuffersize,
zmusic_snd_mididevice, zmusic_snd_mididevice,
zmusic_snd_outputrate, zmusic_snd_outputrate,
zmusic_mod_preferredplayer,
NUM_ZMUSIC_INT_CONFIGS NUM_ZMUSIC_INT_CONFIGS
} EIntConfigKey; } EIntConfigKey;
@ -227,7 +226,7 @@ typedef struct ZMusicCallbacks_
{ {
// Callbacks the client can install to capture messages from the backends // Callbacks the client can install to capture messages from the backends
// or to provide sound font data. // or to provide sound font data.
void (*MessageFunc)(int severity, const char* msg); void (*MessageFunc)(int severity, const char* msg);
// The message callbacks are optional, without them the output goes to stdout. // The message callbacks are optional, without them the output goes to stdout.

View file

@ -188,11 +188,7 @@ if(WIN32)
add_definitions(-DUNICODE -D_UNICODE) add_definitions(-DUNICODE -D_UNICODE)
else() else()
set(ZVULKAN_SOURCES ${ZVULKAN_SOURCES} ${ZVULKAN_UNIX_SOURCES}) set(ZVULKAN_SOURCES ${ZVULKAN_SOURCES} ${ZVULKAN_UNIX_SOURCES})
if(NOT HAIKU) set(ZVULKAN_LIBS ${CMAKE_DL_LIBS} -ldl)
set(ZVULKAN_LIBS ${CMAKE_DL_LIBS} -ldl)
else()
set(ZVULKAN_LIBS ${CMAKE_DL_LIBS})
endif()
add_definitions(-DUNIX -D_UNIX) add_definitions(-DUNIX -D_UNIX)
add_link_options(-pthread) add_link_options(-pthread)
endif() endif()

View file

@ -41,7 +41,6 @@
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <list> #include <list>
#include <map> #include <map>
#include <set> #include <set>

View file

@ -120,9 +120,6 @@ include_directories(include include/zwidget src)
if(WIN32) if(WIN32)
set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_WIN32_SOURCES}) set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_WIN32_SOURCES})
add_definitions(-DUNICODE -D_UNICODE) add_definitions(-DUNICODE -D_UNICODE)
if(MINGW)
add_definitions(-DMINGW)
endif()
elseif(APPLE) elseif(APPLE)
set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_COCOA_SOURCES}) set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_COCOA_SOURCES})
set(ZWIDGET_LIBS ${CMAKE_DL_LIBS} -ldl) set(ZWIDGET_LIBS ${CMAKE_DL_LIBS} -ldl)
@ -130,11 +127,7 @@ elseif(APPLE)
add_link_options(-pthread) add_link_options(-pthread)
else() else()
set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_SDL2_SOURCES}) set(ZWIDGET_SOURCES ${ZWIDGET_SOURCES} ${ZWIDGET_SDL2_SOURCES})
if(NOT HAIKU) set(ZWIDGET_LIBS ${CMAKE_DL_LIBS} -ldl)
set(ZWIDGET_LIBS ${CMAKE_DL_LIBS} -ldl)
else()
set(ZWIDGET_LIBS ${CMAKE_DL_LIBS})
endif()
add_definitions(-DUNIX -D_UNIX) add_definitions(-DUNIX -D_UNIX)
add_link_options(-pthread) add_link_options(-pthread)
endif() endif()

View file

@ -1,4 +1,4 @@
#include <algorithm>
#include "widgets/lineedit/lineedit.h" #include "widgets/lineedit/lineedit.h"
#include "core/utf8reader.h" #include "core/utf8reader.h"
#include "core/colorf.h" #include "core/colorf.h"
@ -18,8 +18,6 @@ LineEdit::LineEdit(Widget* parent) : Widget(parent)
LineEdit::~LineEdit() LineEdit::~LineEdit()
{ {
delete timer;
delete scroll_timer;
} }
bool LineEdit::IsReadOnly() const bool LineEdit::IsReadOnly() const

View file

@ -288,8 +288,9 @@ void SDL2DisplayWindow::RunLoop()
{ {
SDL_Event event; SDL_Event event;
int result = SDL_WaitEvent(&event); int result = SDL_WaitEvent(&event);
if (result == 1) if (result == 0)
DispatchEvent(event); throw std::runtime_error(std::string("SDL_WaitEvent failed:") + SDL_GetError());
DispatchEvent(event);
} }
} }

View file

@ -28,26 +28,6 @@
#define RIDEV_INPUTSINK (0x100) #define RIDEV_INPUTSINK (0x100)
#endif #endif
#ifdef MINGW
// MinGW's library doesn't contain a thunk for DwmDefWindowProc, so we need to create our own
BOOL DwmDefWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult )
{
typedef BOOL(* dwmdwp)(HWND, UINT, WPARAM, LPARAM, LRESULT* );
BOOL result(FALSE);
HMODULE module = LoadLibrary( _T( "dwmapi.dll" ) );
if( module ) {
dwmdwp proc = reinterpret_cast<dwmdwp>( GetProcAddress( module, "DwmDefWindowProc" ) );
if( proc ) {
result = proc( hWnd, msg, wParam, lParam, plResult );
}
FreeLibrary(module);
}
return result;
}
#endif
static std::string from_utf16(const std::wstring& str) static std::string from_utf16(const std::wstring& str)
{ {
if (str.empty()) return {}; if (str.empty()) return {};
@ -81,7 +61,7 @@ Win32Window::Win32Window(DisplayWindowHost* windowHost) : WindowHost(windowHost)
Windows.push_front(this); Windows.push_front(this);
WindowsIterator = Windows.begin(); WindowsIterator = Windows.begin();
WNDCLASSEXW classdesc = {}; WNDCLASSEX classdesc = {};
classdesc.cbSize = sizeof(WNDCLASSEX); classdesc.cbSize = sizeof(WNDCLASSEX);
classdesc.hInstance = GetModuleHandle(0); classdesc.hInstance = GetModuleHandle(0);
classdesc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; classdesc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
@ -94,7 +74,7 @@ Win32Window::Win32Window(DisplayWindowHost* windowHost) : WindowHost(windowHost)
// WS_CAPTION shows the caption (yay! actually a flag that does what it says it does!) // WS_CAPTION shows the caption (yay! actually a flag that does what it says it does!)
// WS_SYSMENU shows the min/max/close buttons // WS_SYSMENU shows the min/max/close buttons
// WS_THICKFRAME makes the window resizable // WS_THICKFRAME makes the window resizable
CreateWindowExW(WS_EX_APPWINDOW | WS_EX_DLGMODALFRAME, L"ZWidgetWindow", L"", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 100, 100, 0, 0, GetModuleHandle(0), this); CreateWindowEx(WS_EX_APPWINDOW | WS_EX_DLGMODALFRAME, L"ZWidgetWindow", L"", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 100, 100, 0, 0, GetModuleHandle(0), this);
/* /*
RAWINPUTDEVICE rid; RAWINPUTDEVICE rid;
@ -148,8 +128,6 @@ void Win32Window::SetWindowFrame(const Rect& box)
void Win32Window::SetClientFrame(const Rect& box) void Win32Window::SetClientFrame(const Rect& box)
{ {
// This function is currently unused but needs to be disabled because it contains Windows API calls that were only added in Windows 10.
#if 0
double dpiscale = GetDpiScale(); double dpiscale = GetDpiScale();
RECT rect = {}; RECT rect = {};
@ -163,7 +141,6 @@ void Win32Window::SetClientFrame(const Rect& box)
AdjustWindowRectExForDpi(&rect, style, FALSE, exstyle, GetDpiForWindow(WindowHandle)); AdjustWindowRectExForDpi(&rect, style, FALSE, exstyle, GetDpiForWindow(WindowHandle));
SetWindowPos(WindowHandle, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); SetWindowPos(WindowHandle, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER);
#endif
} }
void Win32Window::Show() void Win32Window::Show()
@ -291,22 +268,9 @@ int Win32Window::GetPixelHeight() const
return box.bottom; return box.bottom;
} }
typedef UINT(WINAPI* GetDpiForWindow_t)(HWND);
double Win32Window::GetDpiScale() const double Win32Window::GetDpiScale() const
{ {
static GetDpiForWindow_t pGetDpiForWindow = nullptr; return GetDpiForWindow(WindowHandle) / 96.0;
static bool done = false;
if (!done)
{
HMODULE hMod = GetModuleHandleA("User32.dll");
if (hMod != nullptr) pGetDpiForWindow = reinterpret_cast<GetDpiForWindow_t>(GetProcAddress(hMod, "GetDpiForWindow"));
done = true;
}
if (pGetDpiForWindow)
return pGetDpiForWindow(WindowHandle) / 96.0;
else
return 1.0;
} }
std::string Win32Window::GetClipboardText() std::string Win32Window::GetClipboardText()
@ -407,7 +371,6 @@ void Win32Window::PresentBitmap(int width, int height, const uint32_t* pixels)
LRESULT Win32Window::OnWindowMessage(UINT msg, WPARAM wparam, LPARAM lparam) LRESULT Win32Window::OnWindowMessage(UINT msg, WPARAM wparam, LPARAM lparam)
{ {
LPARAM result = 0; LPARAM result = 0;
if (DwmDefWindowProc(WindowHandle, msg, wparam, lparam, &result)) if (DwmDefWindowProc(WindowHandle, msg, wparam, lparam, &result))
return result; return result;

View file

@ -2,7 +2,7 @@
#include "window/window.h" #include "window/window.h"
#include <stdexcept> #include <stdexcept>
#ifdef _WIN32 #ifdef WIN32
#include "win32/win32window.h" #include "win32/win32window.h"

View file

@ -13,5 +13,4 @@ add_library( bz2 STATIC
decompress.c decompress.c
huffman.c huffman.c
randtable.c ) randtable.c )
link_libraries("-static")
target_link_libraries( bz2 ) target_link_libraries( bz2 )

View file

@ -1067,7 +1067,6 @@ set (PCH_SOURCES
common/textures/multipatchtexturebuilder.cpp common/textures/multipatchtexturebuilder.cpp
common/textures/skyboxtexture.cpp common/textures/skyboxtexture.cpp
common/textures/animtexture.cpp common/textures/animtexture.cpp
common/textures/firetexture.cpp
common/textures/v_collection.cpp common/textures/v_collection.cpp
common/textures/formats/automaptexture.cpp common/textures/formats/automaptexture.cpp
common/textures/formats/brightmaptexture.cpp common/textures/formats/brightmaptexture.cpp

View file

@ -592,10 +592,6 @@ void DShape2D::OnDestroy() {
void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms) void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
{ {
// bail if shape is null (shouldn't happen but it might)
if (!shape)
ThrowAbortException(X_OTHER, "shape is null");
// [MK] bail out if vertex/coord array sizes are mismatched // [MK] bail out if vertex/coord array sizes are mismatched
if ( shape->mVertices.Size() != shape->mCoords.Size() ) if ( shape->mVertices.Size() != shape->mCoords.Size() )
ThrowAbortException(X_OTHER, "Mismatch in vertex/coord count: %u != %u", shape->mVertices.Size(), shape->mCoords.Size()); ThrowAbortException(X_OTHER, "Mismatch in vertex/coord count: %u != %u", shape->mVertices.Size(), shape->mCoords.Size());

View file

@ -380,7 +380,7 @@ void DrawText(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double
{ {
return; return;
} }
const char *txt = (parms.localize && string[0] == '$') ? GStrings.GetString(&string[1]) : string; const char *txt = (parms.localize && string[0] == '$') ? GStrings(&string[1]) : string;
DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms); DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms);
} }
@ -419,7 +419,7 @@ void DrawText(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double
{ {
return; return;
} }
const char *txt = (parms.localize && string[0] == '$') ? GStrings.GetString(&string[1]) : string.GetChars(); const char *txt = (parms.localize && string[0] == '$') ? GStrings(&string[1]) : string.GetChars();
DrawTextCommon(drawer, font, normalcolor, x, y, (uint8_t*)txt, parms); DrawTextCommon(drawer, font, normalcolor, x, y, (uint8_t*)txt, parms);
} }

View file

@ -43,8 +43,6 @@
#include "s_soundinternal.h" #include "s_soundinternal.h"
#include "i_time.h" #include "i_time.h"
EXTERN_CVAR(Bool, cl_capfps)
class FBurnTexture : public FTexture class FBurnTexture : public FTexture
{ {
TArray<uint32_t> WorkBuffer; TArray<uint32_t> WorkBuffer;
@ -165,8 +163,6 @@ protected:
public: public:
virtual ~Wiper(); virtual ~Wiper();
virtual bool Run(int ticks) = 0; virtual bool Run(int ticks) = 0;
virtual bool RunInterpolated(double ticks) { return true; };
virtual bool Interpolatable() { return false; }
virtual void SetTextures(FGameTexture* startscreen, FGameTexture* endscreen) virtual void SetTextures(FGameTexture* startscreen, FGameTexture* endscreen)
{ {
startScreen = startscreen; startScreen = startscreen;
@ -181,11 +177,9 @@ class Wiper_Crossfade : public Wiper
{ {
public: public:
bool Run(int ticks) override; bool Run(int ticks) override;
bool RunInterpolated(double ticks) override;
bool Interpolatable() override { return true; }
private: private:
float Clock = 0; int Clock = 0;
}; };
class Wiper_Melt : public Wiper class Wiper_Melt : public Wiper
@ -193,12 +187,10 @@ class Wiper_Melt : public Wiper
public: public:
Wiper_Melt(); Wiper_Melt();
bool Run(int ticks) override; bool Run(int ticks) override;
bool RunInterpolated(double ticks) override;
bool Interpolatable() override { return true; }
private: private:
enum { WIDTH = 320, HEIGHT = 200 }; enum { WIDTH = 320, HEIGHT = 200 };
double y[WIDTH]; int y[WIDTH];
}; };
class Wiper_Burn : public Wiper class Wiper_Burn : public Wiper
@ -276,23 +268,7 @@ bool Wiper_Crossfade::Run(int ticks)
Clock += ticks; Clock += ticks;
DrawTexture(twod, startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE); DrawTexture(twod, startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, DTA_Alpha, clamp(Clock / 32.f, 0.f, 1.f), TAG_DONE); DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, DTA_Alpha, clamp(Clock / 32.f, 0.f, 1.f), TAG_DONE);
return Clock >= 32.; return Clock >= 32;
}
//==========================================================================
//
// OpenGLFrameBuffer :: Wiper_Crossfade :: Run
//
// Fades the old screen into the new one over 32 ticks.
//
//==========================================================================
bool Wiper_Crossfade::RunInterpolated(double ticks)
{
Clock += ticks;
DrawTexture(twod, startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, DTA_Alpha, clamp(Clock / 32.f, 0.f, 1.f), TAG_DONE);
return Clock >= 32.;
} }
//========================================================================== //==========================================================================
@ -306,7 +282,7 @@ Wiper_Melt::Wiper_Melt()
y[0] = -(M_Random() & 15); y[0] = -(M_Random() & 15);
for (int i = 1; i < WIDTH; ++i) for (int i = 1; i < WIDTH; ++i)
{ {
y[i] = clamp(y[i-1] + (double)(M_Random() % 3) - 1., -15., 0.); y[i] = clamp(y[i-1] + (M_Random() % 3) - 1, -15, 0);
} }
} }
@ -331,25 +307,25 @@ bool Wiper_Melt::Run(int ticks)
{ {
if (y[i] < HEIGHT) if (y[i] < HEIGHT)
{ {
if (y[i] < 0.) if (y[i] < 0)
y[i] = y[i] + 1.; y[i]++;
else if (y[i] < 16.) else if (y[i] < 16)
y[i] += y[i] + 1.; y[i] += y[i] + 1;
else else
y[i] = min<double>(y[i] + 8., HEIGHT); y[i] = min<int>(y[i] + 8, HEIGHT);
done = false; done = false;
} }
if (ticks == 0) if (ticks == 0)
{ {
struct { struct {
int32_t x; int32_t x;
double y; int32_t y;
} dpt; } dpt;
struct { struct {
int32_t left; int32_t left;
double top; int32_t top;
int32_t right; int32_t right;
double bottom; int32_t bottom;
} rect; } rect;
// Only draw for the final tick. // Only draw for the final tick.
@ -357,7 +333,7 @@ bool Wiper_Melt::Run(int ticks)
int w = startScreen->GetTexelWidth(); int w = startScreen->GetTexelWidth();
int h = startScreen->GetTexelHeight(); int h = startScreen->GetTexelHeight();
dpt.x = i * w / WIDTH; dpt.x = i * w / WIDTH;
dpt.y = max(0., y[i] * (double)h / (double)HEIGHT); dpt.y = max(0, y[i] * h / HEIGHT);
rect.left = dpt.x; rect.left = dpt.x;
rect.top = 0; rect.top = 0;
rect.right = (i + 1) * w / WIDTH; rect.right = (i + 1) * w / WIDTH;
@ -372,77 +348,6 @@ bool Wiper_Melt::Run(int ticks)
return done; return done;
} }
//==========================================================================
//
// Wiper_Melt :: RunInterpolated
//
// Melts the old screen into the new one over 32 ticks (interpolated).
//
//==========================================================================
bool Wiper_Melt::RunInterpolated(double ticks)
{
bool done = false;
DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
// Copy the old screen in vertical strips on top of the new one.
while (ticks > 0.)
{
done = true;
for (int i = 0; i < WIDTH; i++)
{
if (y[i] < (double)HEIGHT)
{
if (ticks > 0. && ticks < 1.)
{
if (y[i] < 0)
y[i] += ticks;
else if (y[i] < 16)
y[i] += (y[i] + 1) * ticks;
else
y[i] = min<double>(y[i] + (8 * ticks), (double)HEIGHT);
}
else if (y[i] < 0.)
y[i] = y[i] + 1.;
else if (y[i] < 16.)
y[i] += y[i] + 1.;
else
y[i] = min<double>(y[i] + 8., HEIGHT);
done = false;
}
}
ticks -= 1.;
}
for (int i = 0; i < WIDTH; i++)
{
struct {
int32_t x;
double y;
} dpt;
struct {
int32_t left;
double top;
int32_t right;
double bottom;
} rect;
// Only draw for the final tick.
int w = startScreen->GetTexelWidth();
double h = startScreen->GetTexelHeight();
dpt.x = i * w / WIDTH;
dpt.y = max(0., y[i] * (double)h / (double)HEIGHT);
rect.left = dpt.x;
rect.top = 0;
rect.right = (i + 1) * w / WIDTH;
rect.bottom = h - dpt.y;
if (rect.bottom > rect.top)
{
DrawTexture(twod, startScreen, 0, dpt.y, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_ClipLeft, rect.left, DTA_ClipRight, rect.right, DTA_Masked, false, TAG_DONE);
}
}
return done;
}
//========================================================================== //==========================================================================
// //
// OpenGLFrameBuffer :: Wiper_Burn Constructor // OpenGLFrameBuffer :: Wiper_Burn Constructor
@ -518,7 +423,6 @@ void PerformWipe(FTexture* startimg, FTexture* endimg, int wipe_type, bool stops
{ {
// wipe update // wipe update
uint64_t wipestart, nowtime, diff; uint64_t wipestart, nowtime, diff;
double diff_frac;
bool done; bool done;
GSnd->SetSfxPaused(true, 1); GSnd->SetSfxPaused(true, 1);
@ -534,34 +438,20 @@ void PerformWipe(FTexture* startimg, FTexture* endimg, int wipe_type, bool stops
do do
{ {
if (wiper->Interpolatable() && !cl_capfps) do
{ {
I_WaitVBL(2);
nowtime = I_msTime(); nowtime = I_msTime();
diff_frac = (nowtime - wipestart) * 40. / 1000.; // Using 35 here feels too slow. diff = (nowtime - wipestart) * 40 / 1000; // Using 35 here feels too slow.
wipestart = nowtime; } while (diff < 1);
twod->Begin(screen->GetWidth(), screen->GetHeight()); wipestart = nowtime;
done = wiper->RunInterpolated(diff_frac); twod->Begin(screen->GetWidth(), screen->GetHeight());
if (overlaydrawer) overlaydrawer(); done = wiper->Run(1);
twod->End(); if (overlaydrawer) overlaydrawer();
screen->Update(); twod->End();
twod->OnFrameDone(); screen->Update();
} twod->OnFrameDone();
else
{
do
{
I_WaitVBL(2);
nowtime = I_msTime();
diff = (nowtime - wipestart) * 40 / 1000; // Using 35 here feels too slow.
} while (diff < 1);
wipestart = nowtime;
twod->Begin(screen->GetWidth(), screen->GetHeight());
done = wiper->Run(1);
if (overlaydrawer) overlaydrawer();
twod->End();
screen->Update();
twod->OnFrameDone();
}
} while (!done); } while (!done);
delete wiper; delete wiper;
I_FreezeTime(false); I_FreezeTime(false);

View file

@ -74,7 +74,6 @@ float relative_volume = 1.f;
float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function
MusicVolumeMap MusicVolumes; MusicVolumeMap MusicVolumes;
MidiDeviceMap MidiDevices; MidiDeviceMap MidiDevices;
TMap<int, int> ModPlayers;
static int DefaultFindMusic(const char* fn) static int DefaultFindMusic(const char* fn)
{ {
@ -94,7 +93,6 @@ EXTERN_CVAR(Float, fluid_gain)
CVAR(Bool, mus_calcgain, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song. CVAR(Bool, mus_calcgain, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song.
CVAR(Bool, mus_usereplaygain, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song. CVAR(Bool, mus_usereplaygain, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song.
CVAR(Int, mod_preferred_player, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)// toggle between libXMP and Dumb. Unlike other sound CVARs this is not directly mapped to ZMusic's config.
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
@ -132,24 +130,6 @@ static FileReader OpenMusic(const char* musicname)
return reader; return reader;
} }
bool MusicExists(const char* music_name)
{
if (music_name == nullptr)
return false;
if (FileExists(music_name))
return true;
else
{
int lumpnum;
lumpnum = mus_cb.FindMusic(music_name);
if (lumpnum == -1) lumpnum = fileSystem.CheckNumForName(music_name, FileSys::ns_music);
if (lumpnum != -1 && fileSystem.FileLength(lumpnum) != 0)
return true;
}
return false;
}
void S_SetMusicCallbacks(MusicCallbacks* cb) void S_SetMusicCallbacks(MusicCallbacks* cb)
{ {
mus_cb = *cb; mus_cb = *cb;
@ -771,7 +751,6 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force)
{ {
int lumpnum = mus_cb.FindMusic(musicname); int lumpnum = mus_cb.FindMusic(musicname);
MidiDeviceSetting* devp = MidiDevices.CheckKey(lumpnum); MidiDeviceSetting* devp = MidiDevices.CheckKey(lumpnum);
int* mplay = ModPlayers.CheckKey(lumpnum);
auto volp = MusicVolumes.CheckKey(lumpnum); auto volp = MusicVolumes.CheckKey(lumpnum);
if (volp) if (volp)
@ -784,12 +763,6 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force)
CheckReplayGain(musicname, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); CheckReplayGain(musicname, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : "");
} }
auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper.
int mod_player = mplay? *mplay : *mod_preferred_player;
int scratch;
// This config var is only effective when opening a music stream so there's no need for active synchronization. Setting it here is sufficient.
// Ideally this should have been a parameter to ZMusic_OpenSong, but that would have necessitated an API break.
ChangeMusicSettingInt(zmusic_mod_preferredplayer, mus_playing.handle, mod_player, &scratch);
mus_playing.handle = ZMusic_OpenSong(mreader, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); mus_playing.handle = ZMusic_OpenSong(mreader, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : "");
if (mus_playing.handle == nullptr) if (mus_playing.handle == nullptr)
{ {

View file

@ -45,9 +45,6 @@ bool S_StartMusic (const char *music_name);
// Start music using <music_name>, and set whether looping // Start music using <music_name>, and set whether looping
bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false); bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false);
// Check if <music_name> exists
bool MusicExists(const char* music_name);
void S_RestartMusic (); void S_RestartMusic ();
void S_MIDIDeviceChanged(int newdev); void S_MIDIDeviceChanged(int newdev);
@ -74,7 +71,6 @@ struct MidiDeviceSetting
typedef TMap<int, MidiDeviceSetting> MidiDeviceMap; typedef TMap<int, MidiDeviceSetting> MidiDeviceMap;
typedef TMap<int, float> MusicVolumeMap; typedef TMap<int, float> MusicVolumeMap;
extern TMap<int, int> ModPlayers;
extern MidiDeviceMap MidiDevices; extern MidiDeviceMap MidiDevices;
extern MusicVolumeMap MusicVolumes; extern MusicVolumeMap MusicVolumes;
extern MusicCallbacks mus_cb; extern MusicCallbacks mus_cb;

View file

@ -598,7 +598,6 @@ OpenALSoundRenderer::OpenALSoundRenderer()
ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect"); ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect");
ALC.SOFT_HRTF = !!alcIsExtensionPresent(Device, "ALC_SOFT_HRTF"); ALC.SOFT_HRTF = !!alcIsExtensionPresent(Device, "ALC_SOFT_HRTF");
ALC.SOFT_pause_device = !!alcIsExtensionPresent(Device, "ALC_SOFT_pause_device"); ALC.SOFT_pause_device = !!alcIsExtensionPresent(Device, "ALC_SOFT_pause_device");
ALC.SOFT_output_limiter = !!alcIsExtensionPresent(Device, "ALC_SOFT_output_limiter");
const ALCchar *current = NULL; const ALCchar *current = NULL;
if(alcIsExtensionPresent(Device, "ALC_ENUMERATE_ALL_EXT")) if(alcIsExtensionPresent(Device, "ALC_ENUMERATE_ALL_EXT"))
@ -635,11 +634,6 @@ OpenALSoundRenderer::OpenALSoundRenderer()
else else
attribs.Push(ALC_DONT_CARE_SOFT); attribs.Push(ALC_DONT_CARE_SOFT);
} }
if(ALC.SOFT_output_limiter)
{
attribs.Push(ALC_OUTPUT_LIMITER_SOFT);
attribs.Push(ALC_TRUE);
}
// Other attribs..? // Other attribs..?
attribs.Push(0); attribs.Push(0);

View file

@ -61,7 +61,7 @@ enum
{ {
DEFAULT_PITCH = 128, DEFAULT_PITCH = 128,
}; };
static FCRandom pr_soundpitch ("SoundPitch"); static FRandom pr_soundpitch ("SoundPitch");
SoundEngine* soundEngine; SoundEngine* soundEngine;
//========================================================================== //==========================================================================
@ -749,8 +749,9 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx)
{ {
auto sfxp = sfxdata.data(); auto sfxp = sfxdata.data();
int32_t dmxlen = LittleLong(((int32_t *)sfxp)[1]); int32_t dmxlen = LittleLong(((int32_t *)sfxp)[1]);
// If the sound is voc, use the custom loader. // If the sound is voc, use the custom loader.
if (size > 19 && memcmp (sfxp, "Creative Voice File", 19) == 0) if (memcmp (sfxp, "Creative Voice File", 19) == 0)
{ {
sfx->data = GSnd->LoadSoundVoc(sfxp, size); sfx->data = GSnd->LoadSoundVoc(sfxp, size);
} }

View file

@ -193,7 +193,7 @@ int FCommandLine::argc ()
return _argc; return _argc;
} }
const char *FCommandLine::operator[] (int i) char *FCommandLine::operator[] (int i)
{ {
if (_argv == NULL) if (_argv == NULL)
{ {

View file

@ -44,7 +44,7 @@ public:
FCommandLine (const char *commandline, bool no_escapes = false); FCommandLine (const char *commandline, bool no_escapes = false);
~FCommandLine (); ~FCommandLine ();
int argc (); int argc ();
const char *operator[] (int i); char *operator[] (int i);
const char *args () { return cmd; } const char *args () { return cmd; }
void Shift(); void Shift();

View file

@ -240,16 +240,6 @@ void* FBaseCVar::GetExtraDataPointer()
return m_ExtraDataPointer; return m_ExtraDataPointer;
} }
void FBaseCVar::SetExtraDataPointer2(void *pointer)
{
m_ExtraDataPointer2 = pointer;
}
void* FBaseCVar::GetExtraDataPointer2()
{
return m_ExtraDataPointer2;
}
const char *FBaseCVar::GetHumanString(int precision) const const char *FBaseCVar::GetHumanString(int precision) const
{ {
return GetGenericRep(CVAR_String).String; return GetGenericRep(CVAR_String).String;

View file

@ -222,10 +222,8 @@ public:
void ClearCallback(); void ClearCallback();
void SetExtraDataPointer(void *pointer); void SetExtraDataPointer(void *pointer);
void SetExtraDataPointer2(void *pointer);
void* GetExtraDataPointer(); void* GetExtraDataPointer();
void* GetExtraDataPointer2();
int pnum = -1; int pnum = -1;
FName userinfoName; FName userinfoName;
@ -261,8 +259,7 @@ private:
static inline bool m_UseCallback = false; static inline bool m_UseCallback = false;
static inline bool m_DoNoSet = false; static inline bool m_DoNoSet = false;
void *m_ExtraDataPointer = nullptr; void *m_ExtraDataPointer;
void *m_ExtraDataPointer2 = nullptr;
// These need to go away! // These need to go away!
friend FString C_GetMassCVarString (uint32_t filter, bool compact); friend FString C_GetMassCVarString (uint32_t filter, bool compact);
@ -278,8 +275,6 @@ private:
friend void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter); friend void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter);
friend void C_DeinitConsole(); friend void C_DeinitConsole();
friend void C_ListCVarsWithoutDescription(); friend void C_ListCVarsWithoutDescription();
friend class GLDefsParser;
}; };
// Returns a string with all cvars whose flags match filter. In compact mode, // Returns a string with all cvars whose flags match filter. In compact mode,

View file

@ -80,7 +80,7 @@ CCMD (print)
Printf ("print <name>: Print a string from the string table\n"); Printf ("print <name>: Print a string from the string table\n");
return; return;
} }
const char *str = GStrings.CheckString(argv[1]); const char *str = GStrings[argv[1]];
if (str == NULL) if (str == NULL)
{ {
Printf ("%s unknown\n", argv[1]); Printf ("%s unknown\n", argv[1]);
@ -304,7 +304,7 @@ CCMD(printlocalized)
return; return;
} }
} }
Printf("%s\n", GStrings.GetString(argv[1])); Printf("%s\n", GStrings(argv[1]));
} }
} }

View file

@ -4,15 +4,8 @@
#include "startupinfo.h" #include "startupinfo.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "gstrings.h" #include "gstrings.h"
#include "version.h"
static_assert(sizeof(void*) == 8, static_assert(sizeof(void*) == 8, "32 builds are not supported");
"Only LP64/LLP64 builds are officially supported. "
"Please do not attempt to build for other platforms; "
"even if the program succeeds in a MAP01 smoke test, "
"there are e.g. known visual artifacts "
"<https://forum.zdoom.org/viewtopic.php?f=7&t=75673> "
"that lead to a bad user experience.");
// Some global engine variables taken out of the backend code. // Some global engine variables taken out of the backend code.
FStartupScreen* StartWindow; FStartupScreen* StartWindow;
@ -30,7 +23,7 @@ bool pauseext;
FStartupInfo GameStartupInfo; FStartupInfo GameStartupInfo;
CVAR(Bool, queryiwad, QUERYIWADDEFAULT, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, queryiwad, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, vid_fps, false, 0) CVAR(Bool, vid_fps, false, 0)

View file

@ -31,6 +31,7 @@ struct SystemCallbacks
FString(*GetPlayerName)(int i); FString(*GetPlayerName)(int i);
bool (*DispatchEvent)(event_t* ev); bool (*DispatchEvent)(event_t* ev);
bool (*CheckGame)(const char* nm); bool (*CheckGame)(const char* nm);
int (*GetGender)();
void (*MenuClosed)(); void (*MenuClosed)();
bool (*CheckMenudefOption)(const char* opt); bool (*CheckMenudefOption)(const char* opt);
void (*ConsoleToggled)(int state); void (*ConsoleToggled)(int state);

View file

@ -132,8 +132,7 @@ enum
PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt
PRE_ALLFULL, // Sent from host to an unwanted guest PRE_ALLFULL, // Sent from host to an unwanted guest
PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt
PRE_GO, // Sent from host to guest to continue game startup PRE_GO // Sent from host to guest to continue game startup
PRE_IN_PROGRESS, // Sent from host to guest if the game has already started
}; };
// Set PreGamePacket.fake to this so that the game rejects any pregame packets // Set PreGamePacket.fake to this so that the game rejects any pregame packets
@ -270,8 +269,6 @@ void PacketSend (void)
// I_Error ("SendPacket error: %s",strerror(errno)); // I_Error ("SendPacket error: %s",strerror(errno));
} }
void PreSend(const void* buffer, int bufferlen, const sockaddr_in* to);
void SendConAck(int num_connected, int num_needed);
// //
// PacketGet // PacketGet
@ -306,7 +303,7 @@ void PacketGet (void)
GetPlayerName(node).GetChars()); GetPlayerName(node).GetChars());
} }
doomcom.data[0] = NCMD_EXIT; doomcom.data[0] = 0x80; // NCMD_EXIT
c = 1; c = 1;
} }
else if (err != WSAEWOULDBLOCK) else if (err != WSAEWOULDBLOCK)
@ -344,11 +341,10 @@ void PacketGet (void)
} }
else if (c > 0) else if (c > 0)
{ //The packet is not from any in-game node, so we might as well discard it. { //The packet is not from any in-game node, so we might as well discard it.
if (TransmitBuffer[0] == PRE_FAKE) // Don't show the message for disconnect notifications.
if (c != 2 || TransmitBuffer[0] != PRE_FAKE || TransmitBuffer[1] != PRE_DISCONNECT)
{ {
// If it's someone waiting in the lobby, let them know the game already started DPrintf(DMSG_WARNING, "Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port);
uint8_t msg[] = { PRE_FAKE, PRE_IN_PROGRESS };
PreSend(msg, 2, &fromaddress);
} }
doomcom.remotenode = -1; doomcom.remotenode = -1;
return; return;
@ -373,22 +369,7 @@ sockaddr_in *PreGet (void *buffer, int bufferlen, bool noabort)
int err = WSAGetLastError(); int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK || (noabort && err == WSAECONNRESET)) if (err == WSAEWOULDBLOCK || (noabort && err == WSAECONNRESET))
return NULL; // no packet return NULL; // no packet
I_Error ("PreGet: %s", neterror ());
if (doomcom.consoleplayer == 0)
{
int node = FindNode(&fromaddress);
I_NetMessage("Got unexpected disconnect.");
doomcom.numnodes--;
for (; node < doomcom.numnodes; ++node)
sendaddress[node] = sendaddress[node + 1];
// Let remaining guests know that somebody left.
SendConAck(doomcom.numnodes, doomcom.numplayers);
}
else
{
I_NetError("The host disbanded the game unexpectedly");
}
} }
return &fromaddress; return &fromaddress;
} }
@ -518,7 +499,7 @@ void SendAbort (void)
} }
} }
void SendConAck (int num_connected, int num_needed) static void SendConAck (int num_connected, int num_needed)
{ {
PreGamePacket packet; PreGamePacket packet;
@ -727,7 +708,7 @@ bool HostGame (int i)
doomcom.numnodes = 1; doomcom.numnodes = 1;
I_NetInit ("Hosting game", numplayers); I_NetInit ("Waiting for players", numplayers);
// Wait for numplayers-1 different connections // Wait for numplayers-1 different connections
if (!I_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers)) if (!I_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
@ -802,15 +783,13 @@ bool Guest_ContactHost (void *userdata)
} }
else if (packet.Message == PRE_DISCONNECT) else if (packet.Message == PRE_DISCONNECT)
{ {
I_NetError("The host cancelled the game."); doomcom.numnodes = 0;
I_FatalError ("The host cancelled the game.");
} }
else if (packet.Message == PRE_ALLFULL) else if (packet.Message == PRE_ALLFULL)
{ {
I_NetError("The game is full."); doomcom.numnodes = 0;
} I_FatalError ("The game is full.");
else if (packet.Message == PRE_IN_PROGRESS)
{
I_NetError("The game was already started.");
} }
} }
} }
@ -871,7 +850,7 @@ bool Guest_WaitForOthers (void *userdata)
return true; return true;
case PRE_DISCONNECT: case PRE_DISCONNECT:
I_NetError("The host cancelled the game."); I_FatalError ("The host cancelled the game.");
break; break;
} }
} }
@ -896,7 +875,6 @@ bool JoinGame (int i)
BuildAddress (&sendaddress[1], Args->GetArg(i+1)); BuildAddress (&sendaddress[1], Args->GetArg(i+1));
sendplayer[1] = 0; sendplayer[1] = 0;
doomcom.numnodes = 2; doomcom.numnodes = 2;
doomcom.consoleplayer = -1;
// Let host know we are here // Let host know we are here
@ -925,11 +903,11 @@ bool JoinGame (int i)
static int PrivateNetOf(in_addr in) static int PrivateNetOf(in_addr in)
{ {
int addr = ntohl(in.s_addr); int addr = ntohl(in.s_addr);
if ((addr & 0xFFFF0000) == 0xC0A80000) // 192.168.0.0 if ((addr & 0xFFFF0000) == 0xC0A80000) // 192.168.0.0
{ {
return 0xC0A80000; return 0xC0A80000;
} }
else if ((addr & 0xFFFF0000) >= 0xAC100000 && (addr & 0xFFFF0000) <= 0xAC1F0000) // 172.16.0.0 - 172.31.0.0 else if ((addr & 0xFFF00000) == 0xAC100000) // 172.16.0.0
{ {
return 0xAC100000; return 0xAC100000;
} }
@ -1068,13 +1046,6 @@ void I_NetMessage(const char* text, ...)
#endif #endif
} }
void I_NetError(const char* error)
{
doomcom.numnodes = 0;
StartWindow->NetClose();
I_FatalError("%s", error);
}
// todo: later these must be dispatched by the main menu, not the start screen. // todo: later these must be dispatched by the main menu, not the start screen.
void I_NetProgress(int val) void I_NetProgress(int val)
{ {

View file

@ -7,7 +7,6 @@
int I_InitNetwork (void); int I_InitNetwork (void);
void I_NetCmd (void); void I_NetCmd (void);
void I_NetMessage(const char*, ...); void I_NetMessage(const char*, ...);
void I_NetError(const char* error);
void I_NetProgress(int val); void I_NetProgress(int val);
void I_NetInit(const char* msg, int num); void I_NetInit(const char* msg, int num);
bool I_NetLoop(bool (*timer_callback)(void*), void* userdata); bool I_NetLoop(bool (*timer_callback)(void*), void* userdata);

View file

@ -2,7 +2,7 @@
#include "zstring.h" #include "zstring.h"
#if defined(__unix__) || defined(__HAIKU__) #ifdef __unix__
FString GetUserFile (const char *path); FString GetUserFile (const char *path);
#endif #endif
FString M_GetAppDataPath(bool create); FString M_GetAppDataPath(bool create);

View file

@ -120,30 +120,16 @@ bool M_LoadJoystickConfig(IJoystickConfig *joy)
{ {
return false; return false;
} }
assert(GameConfig);
value = GameConfig->GetValueForKey("Enabled"); value = GameConfig->GetValueForKey("Enabled");
if (value) if (value != NULL)
{ {
joy->SetEnabled((bool)atoi(value)); joy->SetEnabled((bool)atoi(value));
} }
if(joy->AllowsEnabledInBackground())
{
value = GameConfig->GetValueForKey("EnabledInBackground");
if (value)
{
joy->SetEnabledInBackground((bool)atoi(value));
}
}
value = GameConfig->GetValueForKey("Sensitivity"); value = GameConfig->GetValueForKey("Sensitivity");
if (value) if (value != NULL)
{ {
joy->SetSensitivity((float)atof(value)); joy->SetSensitivity((float)atof(value));
} }
numaxes = joy->GetNumAxes(); numaxes = joy->GetNumAxes();
for (int i = 0; i < numaxes; ++i) for (int i = 0; i < numaxes; ++i)
{ {
@ -151,21 +137,21 @@ bool M_LoadJoystickConfig(IJoystickConfig *joy)
mysnprintf(key + axislen, countof(key) - axislen, "deadzone"); mysnprintf(key + axislen, countof(key) - axislen, "deadzone");
value = GameConfig->GetValueForKey(key); value = GameConfig->GetValueForKey(key);
if (value) if (value != NULL)
{ {
joy->SetAxisDeadZone(i, (float)atof(value)); joy->SetAxisDeadZone(i, (float)atof(value));
} }
mysnprintf(key + axislen, countof(key) - axislen, "scale"); mysnprintf(key + axislen, countof(key) - axislen, "scale");
value = GameConfig->GetValueForKey(key); value = GameConfig->GetValueForKey(key);
if (value) if (value != NULL)
{ {
joy->SetAxisScale(i, (float)atof(value)); joy->SetAxisScale(i, (float)atof(value));
} }
mysnprintf(key + axislen, countof(key) - axislen, "map"); mysnprintf(key + axislen, countof(key) - axislen, "map");
value = GameConfig->GetValueForKey(key); value = GameConfig->GetValueForKey(key);
if (value) if (value != NULL)
{ {
EJoyAxis gameaxis = (EJoyAxis)atoi(value); EJoyAxis gameaxis = (EJoyAxis)atoi(value);
if (gameaxis < JOYAXIS_None || gameaxis >= NUM_JOYAXIS) if (gameaxis < JOYAXIS_None || gameaxis >= NUM_JOYAXIS)
@ -199,12 +185,6 @@ void M_SaveJoystickConfig(IJoystickConfig *joy)
{ {
GameConfig->SetValueForKey("Enabled", "0"); GameConfig->SetValueForKey("Enabled", "0");
} }
if (!joy->AllowsEnabledInBackground() && joy->GetEnabledInBackground())
{
GameConfig->SetValueForKey("EnabledInBackground", "1");
}
if (!joy->IsSensitivityDefault()) if (!joy->IsSensitivityDefault())
{ {
mysnprintf(value, countof(value), "%g", joy->GetSensitivity()); mysnprintf(value, countof(value), "%g", joy->GetSensitivity());

View file

@ -39,10 +39,6 @@ struct IJoystickConfig
virtual bool GetEnabled() = 0; virtual bool GetEnabled() = 0;
virtual void SetEnabled(bool enabled) = 0; virtual void SetEnabled(bool enabled) = 0;
virtual bool AllowsEnabledInBackground() = 0;
virtual bool GetEnabledInBackground() = 0;
virtual void SetEnabledInBackground(bool enabled) = 0;
// Used by the saver to not save properties that are at their defaults. // Used by the saver to not save properties that are at their defaults.
virtual bool IsSensitivityDefault() = 0; virtual bool IsSensitivityDefault() = 0;
virtual bool IsAxisDeadZoneDefault(int axis) = 0; virtual bool IsAxisDeadZoneDefault(int axis) = 0;

View file

@ -83,7 +83,7 @@ FRandom pr_exrandom("EX_Random");
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
FCRandom M_Random; FRandom M_Random;
// Global seed. This is modified predictably to initialize every RNG. // Global seed. This is modified predictably to initialize every RNG.
uint32_t rngseed; uint32_t rngseed;
@ -126,8 +126,8 @@ CCMD(rngseed)
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
FRandom *FRandom::RNGList, *FRandom::CRNGList; FRandom *FRandom::RNGList;
static TDeletingArray<FRandom *> NewRNGs, NewCRNGs; static TDeletingArray<FRandom *> NewRNGs;
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
@ -139,22 +139,14 @@ static TDeletingArray<FRandom *> NewRNGs, NewCRNGs;
// //
//========================================================================== //==========================================================================
FRandom::FRandom (bool client) FRandom::FRandom ()
: NameCRC (0), bClient(client) : NameCRC (0)
{ {
#ifndef NDEBUG #ifndef NDEBUG
Name = NULL; Name = NULL;
#endif #endif
if (bClient) Next = RNGList;
{ RNGList = this;
Next = CRNGList;
CRNGList = this;
}
else
{
Next = RNGList;
RNGList = this;
}
Init(0); Init(0);
} }
@ -166,7 +158,7 @@ FRandom::FRandom (bool client)
// //
//========================================================================== //==========================================================================
FRandom::FRandom (const char *name, bool client) : bClient(client) FRandom::FRandom (const char *name)
{ {
NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name)); NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name));
#ifndef NDEBUG #ifndef NDEBUG
@ -178,7 +170,7 @@ FRandom::FRandom (const char *name, bool client) : bClient(client)
#endif #endif
// Insert the RNG in the list, sorted by CRC // Insert the RNG in the list, sorted by CRC
FRandom **prev = (bClient ? &CRNGList : &RNGList), * probe = (bClient ? CRNGList : RNGList); FRandom **prev = &RNGList, *probe = RNGList;
while (probe != NULL && probe->NameCRC < NameCRC) while (probe != NULL && probe->NameCRC < NameCRC)
{ {
@ -213,8 +205,8 @@ FRandom::~FRandom ()
FRandom *last = NULL; FRandom *last = NULL;
prev = bClient ? &CRNGList : &RNGList; prev = &RNGList;
rng = bClient ? CRNGList : RNGList; rng = RNGList;
while (rng != NULL && rng != this) while (rng != NULL && rng != this)
{ {
@ -245,11 +237,6 @@ void FRandom::StaticClearRandom ()
{ {
rng->Init(rngseed); rng->Init(rngseed);
} }
for (FRandom* rng = FRandom::CRNGList; rng != NULL; rng = rng->Next)
{
rng->Init(rngseed);
}
} }
//========================================================================== //==========================================================================
@ -358,15 +345,15 @@ void FRandom::StaticReadRNGState(FSerializer &arc)
// //
//========================================================================== //==========================================================================
FRandom *FRandom::StaticFindRNG (const char *name, bool client) FRandom *FRandom::StaticFindRNG (const char *name)
{ {
uint32_t NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name)); uint32_t NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name));
// Use the default RNG if this one happens to have a CRC of 0. // Use the default RNG if this one happens to have a CRC of 0.
if (NameCRC == 0) return client ? &M_Random : &pr_exrandom; if (NameCRC == 0) return &pr_exrandom;
// Find the RNG in the list, sorted by CRC // Find the RNG in the list, sorted by CRC
FRandom **prev = (client ? &CRNGList : &RNGList), *probe = (client ? CRNGList : RNGList); FRandom **prev = &RNGList, *probe = RNGList;
while (probe != NULL && probe->NameCRC < NameCRC) while (probe != NULL && probe->NameCRC < NameCRC)
{ {
@ -377,32 +364,14 @@ FRandom *FRandom::StaticFindRNG (const char *name, bool client)
if (probe == NULL || probe->NameCRC != NameCRC) if (probe == NULL || probe->NameCRC != NameCRC)
{ {
// A matching RNG doesn't exist yet so create it. // A matching RNG doesn't exist yet so create it.
probe = new FRandom(name, client); probe = new FRandom(name);
// Store the new RNG for destruction when ZDoom quits. // Store the new RNG for destruction when ZDoom quits.
if (client) NewRNGs.Push(probe);
NewCRNGs.Push(probe);
else
NewRNGs.Push(probe);
} }
return probe; return probe;
} }
void FRandom::SaveRNGState(TArray<FRandom>& backups)
{
for (auto cur = RNGList; cur != nullptr; cur = cur->Next)
backups.Push(*cur);
}
void FRandom::RestoreRNGState(TArray<FRandom>& backups)
{
unsigned int i = 0u;
for (auto cur = RNGList; cur != nullptr; cur = cur->Next)
*cur = backups[i++];
backups.Clear();
}
//========================================================================== //==========================================================================
// //
// FRandom :: StaticPrintSeeds // FRandom :: StaticPrintSeeds

View file

@ -44,9 +44,9 @@ class FSerializer;
class FRandom : public SFMTObj class FRandom : public SFMTObj
{ {
public: public:
FRandom() : FRandom(false) {} FRandom ();
FRandom(const char* name) : FRandom(name, false) {} FRandom (const char *name);
~FRandom(); ~FRandom ();
int Seed() const int Seed() const
{ {
@ -170,34 +170,20 @@ public:
static void StaticClearRandom (); static void StaticClearRandom ();
static void StaticReadRNGState (FSerializer &arc); static void StaticReadRNGState (FSerializer &arc);
static void StaticWriteRNGState (FSerializer &file); static void StaticWriteRNGState (FSerializer &file);
static FRandom *StaticFindRNG(const char *name, bool client); static FRandom *StaticFindRNG(const char *name);
static void SaveRNGState(TArray<FRandom>& backups);
static void RestoreRNGState(TArray<FRandom>& backups);
#ifndef NDEBUG #ifndef NDEBUG
static void StaticPrintSeeds (); static void StaticPrintSeeds ();
#endif #endif
protected:
FRandom(bool client);
FRandom(const char* name, bool client);
private: private:
#ifndef NDEBUG #ifndef NDEBUG
const char *Name; const char *Name;
#endif #endif
FRandom *Next; FRandom *Next;
uint32_t NameCRC; uint32_t NameCRC;
bool bClient;
static FRandom *RNGList, *CRNGList; static FRandom *RNGList;
};
class FCRandom : public FRandom
{
public:
FCRandom() : FRandom(true) {}
FCRandom(const char* name) : FRandom(name, true) {}
}; };
extern uint32_t rngseed; // The starting seed (not part of state) extern uint32_t rngseed; // The starting seed (not part of state)
@ -207,6 +193,6 @@ extern bool use_staticrng;
// M_Random can be used for numbers that do not affect gameplay // M_Random can be used for numbers that do not affect gameplay
extern FCRandom M_Random; extern FRandom M_Random;
#endif #endif

View file

@ -41,12 +41,6 @@ xx(Random2)
xx(RandomPick) xx(RandomPick)
xx(FRandomPick) xx(FRandomPick)
xx(SetRandomSeed) xx(SetRandomSeed)
xx(CRandom)
xx(CFRandom)
xx(CRandom2)
xx(CRandomPick)
xx(CFRandomPick)
xx(CSetRandomSeed)
xx(BuiltinRandomSeed) xx(BuiltinRandomSeed)
xx(BuiltinNew) xx(BuiltinNew)
xx(GetClass) xx(GetClass)
@ -196,15 +190,9 @@ xx(TranslationID)
xx(Overlay) xx(Overlay)
xx(IsValid) xx(IsValid)
xx(IsNull) xx(IsNull)
xx(IsEmpty)
xx(IsFixed)
xx(IsKeep)
xx(Exists) xx(Exists)
xx(SetInvalid) xx(SetInvalid)
xx(SetNull) xx(SetNull)
xx(SetEmpty)
xx(SetFixed)
xx(SetKeep)
xx(Key) xx(Key)
xx(Index) xx(Index)
xx(Find) xx(Find)
@ -290,8 +278,6 @@ xx(BuiltinNameToClass)
xx(BuiltinClassCast) xx(BuiltinClassCast)
xx(BuiltinFunctionPtrCast) xx(BuiltinFunctionPtrCast)
xx(BuiltinFindTranslation) xx(BuiltinFindTranslation)
xx(HandleDeprecatedFlags)
xx(CheckDeprecatedFlags)
xx(ScreenJobRunner) xx(ScreenJobRunner)
xx(Action) xx(Action)

View file

@ -197,10 +197,7 @@ void FSerializer::Close()
} }
if (mErrors > 0) if (mErrors > 0)
{ {
if (mLumpName.IsNotEmpty()) I_Error("%d errors parsing JSON", mErrors);
I_Error("%d errors parsing JSON lump %s", mErrors, mLumpName.GetChars());
else
I_Error("%d errors parsing JSON", mErrors);
} }
} }
@ -334,28 +331,6 @@ bool FSerializer::HasObject(const char* name)
// //
//========================================================================== //==========================================================================
bool FSerializer::IsKeyNull(const char* name)
{
if (isReading())
{
auto val = r->FindKey(name);
if (val != nullptr)
{
if (val->IsNull())
{
return true;
}
}
}
return false;
}
//==========================================================================
//
//
//
//==========================================================================
void FSerializer::EndObject() void FSerializer::EndObject()
{ {
if (isWriting()) if (isWriting())

View file

@ -9,7 +9,6 @@
#include "palentry.h" #include "palentry.h"
#include "name.h" #include "name.h"
#include "dictionary.h" #include "dictionary.h"
#include "bonecomponents.h"
extern bool save_full; extern bool save_full;
@ -94,7 +93,6 @@ public:
void EndObject(); void EndObject();
bool HasKey(const char* name); bool HasKey(const char* name);
bool HasObject(const char* name); bool HasObject(const char* name);
bool IsKeyNull(const char* name);
bool BeginArray(const char *name); bool BeginArray(const char *name);
void EndArray(); void EndArray();
unsigned GetSize(const char *group); unsigned GetSize(const char *group);
@ -226,7 +224,6 @@ public:
int mErrors = 0; int mErrors = 0;
int mObjectErrors = 0; int mObjectErrors = 0;
FString mLumpName;
}; };
FSerializer& Serialize(FSerializer& arc, const char* key, char& value, char* defval); FSerializer& Serialize(FSerializer& arc, const char* key, char& value, char* defval);
@ -250,9 +247,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def); FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &mo, struct ModelOverride *def); FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &mo, struct ModelOverride *def);
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimModelOverride &mo, struct AnimModelOverride *def); FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimModelOverride &mo, struct AnimModelOverride *def);
FSerializer &Serialize(FSerializer &arc, const char *key, ModelAnim &ao, ModelAnim *def); FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &ao, struct AnimOverride *def);
FSerializer &Serialize(FSerializer &arc, const char *key, ModelAnimFrame &ao, ModelAnimFrame *def); FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
FSerializer &Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p); void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p);

View file

@ -55,7 +55,6 @@ public:
virtual void NetInit(const char *message, int num_players) {} virtual void NetInit(const char *message, int num_players) {}
virtual void NetProgress(int count) {} virtual void NetProgress(int count) {}
virtual void NetDone() {} virtual void NetDone() {}
virtual void NetClose() {}
virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) { return false; } virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) { return false; }
virtual void AppendStatusLine(const char* status) {} virtual void AppendStatusLine(const char* status) {}
virtual void LoadingStatus(const char* message, int colors) {} virtual void LoadingStatus(const char* message, int colors) {}
@ -75,7 +74,6 @@ public:
void NetProgress(int count); void NetProgress(int count);
void NetMessage(const char* format, ...); // cover for printf void NetMessage(const char* format, ...); // cover for printf
void NetDone(); void NetDone();
void NetClose();
bool NetLoop(bool (*timer_callback)(void*), void* userdata); bool NetLoop(bool (*timer_callback)(void*), void* userdata);
protected: protected:
int NetMaxPos, NetCurPos; int NetMaxPos, NetCurPos;

View file

@ -47,29 +47,29 @@
// //
//========================================================================== //==========================================================================
void FStringTable::LoadStrings (FileSys::FileSystem& fileSystem, const char *language) void FStringTable::LoadStrings (FileSys::FileSystem& fileSystem_, const char *language)
{ {
int lastlump, lump; int lastlump, lump;
fileSystem = &fileSystem_;
allStrings.Clear(); allStrings.Clear();
lastlump = 0; lastlump = 0;
while ((lump = fileSystem.FindLump("LMACROS", &lastlump)) != -1) while ((lump = fileSystem->FindLump("LMACROS", &lastlump)) != -1)
{ {
auto lumpdata = fileSystem.ReadFile(lump); readMacros(lump);
readMacros(lumpdata.string(), lumpdata.size());
} }
lastlump = 0; lastlump = 0;
while ((lump = fileSystem.FindLump ("LANGUAGE", &lastlump)) != -1) while ((lump = fileSystem->FindLump ("LANGUAGE", &lastlump)) != -1)
{ {
auto lumpdata = fileSystem.ReadFile(lump); auto lumpdata = fileSystem->ReadFile(lump);
auto filenum = fileSystem.GetFileContainer(lump);
if (!ParseLanguageCSV(filenum, lumpdata.string(), lumpdata.size())) if (!ParseLanguageCSV(lump, lumpdata.string(), lumpdata.size()))
LoadLanguage (filenum, lumpdata.string(), lumpdata.size()); LoadLanguage (lump, lumpdata.string(), lumpdata.size());
} }
UpdateLanguage(language); UpdateLanguage(language);
allMacros.Clear(); allMacros.Clear();
fileSystem = nullptr;
} }
@ -159,9 +159,10 @@ TArray<TArray<FString>> FStringTable::parseCSV(const char* buffer, size_t size)
// //
//========================================================================== //==========================================================================
bool FStringTable::readMacros(const char* buffer, size_t size) bool FStringTable::readMacros(int lumpnum)
{ {
auto data = parseCSV(buffer, size); auto lumpdata = fileSystem->ReadFile(lumpnum);
auto data = parseCSV(lumpdata.string(), lumpdata.size());
allMacros.Clear(); allMacros.Clear();
for (unsigned i = 1; i < data.Size(); i++) for (unsigned i = 1; i < data.Size(); i++)
@ -186,7 +187,7 @@ bool FStringTable::readMacros(const char* buffer, size_t size)
// //
//========================================================================== //==========================================================================
bool FStringTable::ParseLanguageCSV(int filenum, const char* buffer, size_t size) bool FStringTable::ParseLanguageCSV(int lumpnum, const char* buffer, size_t size)
{ {
if (size < 11) return false; if (size < 11) return false;
if (strnicmp(buffer, "default,", 8) && strnicmp(buffer, "identifier,", 11 )) return false; if (strnicmp(buffer, "default,", 8) && strnicmp(buffer, "identifier,", 11 )) return false;
@ -254,18 +255,17 @@ bool FStringTable::ParseLanguageCSV(int filenum, const char* buffer, size_t size
} }
} }
row[labelcol].StripLeftRight();
FName strName = row[labelcol].GetChars(); FName strName = row[labelcol].GetChars();
if (hasDefaultEntry) if (hasDefaultEntry)
{ {
DeleteForLabel(filenum, strName); DeleteForLabel(lumpnum, strName);
} }
for (auto &langentry : langrows) for (auto &langentry : langrows)
{ {
auto str = row[langentry.first]; auto str = row[langentry.first];
if (str.Len() > 0) if (str.Len() > 0)
{ {
InsertString(filenum, langentry.second, strName, str); InsertString(lumpnum, langentry.second, strName, str);
} }
else else
{ {
@ -409,10 +409,11 @@ void FStringTable::DeleteString(int langid, FName label)
// //
//========================================================================== //==========================================================================
void FStringTable::DeleteForLabel(int filenum, FName label) void FStringTable::DeleteForLabel(int lumpnum, FName label)
{ {
decltype(allStrings)::Iterator it(allStrings); decltype(allStrings)::Iterator it(allStrings);
decltype(allStrings)::Pair *pair; decltype(allStrings)::Pair *pair;
auto filenum = fileSystem->GetFileContainer(lumpnum);
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
@ -431,10 +432,10 @@ void FStringTable::DeleteForLabel(int filenum, FName label)
// //
//========================================================================== //==========================================================================
void FStringTable::InsertString(int filenum, int langid, FName label, const FString &string) void FStringTable::InsertString(int lumpnum, int langid, FName label, const FString &string)
{ {
const char *strlangid = (const char *)&langid; const char *strlangid = (const char *)&langid;
TableElement te = { filenum, { string, string, string, string } }; TableElement te = { fileSystem->GetFileContainer(lumpnum), { string, string, string, string } };
ptrdiff_t index; ptrdiff_t index;
while ((index = te.strings[0].IndexOf("@[")) >= 0) while ((index = te.strings[0].IndexOf("@[")) >= 0)
{ {
@ -578,33 +579,26 @@ bool FStringTable::exists(const char *name)
// //
//========================================================================== //==========================================================================
const char *FStringTable::CheckString(const char *name, uint32_t *langtable, int gender) const const char *FStringTable::GetString(const char *name, uint32_t *langtable, int gender) const
{ {
if (name == nullptr || *name == 0) if (name == nullptr || *name == 0)
{ {
return nullptr; return nullptr;
} }
if (gender == -1) gender = defaultgender; if (gender == -1 && sysCallbacks.GetGender) gender = sysCallbacks.GetGender();
if (gender < 0 || gender > 3) gender = 0; if (gender < 0 || gender > 3) gender = 0;
FName nm(name, true); FName nm(name, true);
if (nm != NAME_None) if (nm != NAME_None)
{ {
TableElement* bestItem = nullptr;
for (auto map : currentLanguageSet) for (auto map : currentLanguageSet)
{ {
auto item = map.second->CheckKey(nm); auto item = map.second->CheckKey(nm);
if (item) if (item)
{ {
if (bestItem && bestItem->filenum > item->filenum)
{
// prioritize content from later files, even if the language doesn't fully match.
// This is mainly for Dehacked content.
continue;
}
if (langtable) *langtable = map.first; if (langtable) *langtable = map.first;
auto c = item->strings[gender].GetChars(); auto c = item->strings[gender].GetChars();
if (c && *c == '$' && c[1] == '$') if (c && *c == '$' && c[1] == '$')
c = CheckString(c + 2, langtable, gender); return GetString(c + 2, langtable, gender);
return c; return c;
} }
} }
@ -614,7 +608,7 @@ const char *FStringTable::CheckString(const char *name, uint32_t *langtable, int
//========================================================================== //==========================================================================
// //
// Finds a string by name in a given language without attempting any substitution // Finds a string by name in a given language
// //
//========================================================================== //==========================================================================
@ -624,7 +618,7 @@ const char *FStringTable::GetLanguageString(const char *name, uint32_t langtable
{ {
return nullptr; return nullptr;
} }
if (gender == -1) gender = defaultgender; if (gender == -1 && sysCallbacks.GetGender) gender = sysCallbacks.GetGender();
if (gender < 0 || gender > 3) gender = 0; if (gender < 0 || gender > 3) gender = 0;
FName nm(name, true); FName nm(name, true);
if (nm != NAME_None) if (nm != NAME_None)
@ -661,9 +655,9 @@ bool FStringTable::MatchDefaultString(const char *name, const char *content) con
// //
//========================================================================== //==========================================================================
const char *FStringTable::GetString(const char *name) const const char *FStringTable::operator() (const char *name) const
{ {
const char *str = CheckString(name, nullptr); const char *str = operator[] (name);
return str ? str : name; return str ? str : name;
} }

View file

@ -95,29 +95,32 @@ public:
const char *GetLanguageString(const char *name, uint32_t langtable, int gender = -1) const; const char *GetLanguageString(const char *name, uint32_t langtable, int gender = -1) const;
bool MatchDefaultString(const char *name, const char *content) const; bool MatchDefaultString(const char *name, const char *content) const;
const char *CheckString(const char *name, uint32_t *langtable = nullptr, int gender = -1) const; const char *GetString(const char *name, uint32_t *langtable, int gender = -1) const;
const char* GetString(const char* name) const; const char *operator() (const char *name) const; // Never returns NULL
const char* GetString(const FString& name) const { return GetString(name.GetChars()); } const char* operator() (const FString& name) const { return operator()(name.GetChars()); }
const char *operator[] (const char *name) const
{
return GetString(name, nullptr);
}
bool exists(const char *name); bool exists(const char *name);
void InsertString(int filenum, int langid, FName label, const FString& string); void InsertString(int lumpnum, int langid, FName label, const FString& string);
void SetDefaultGender(int gender) { defaultgender = gender; }
private: private:
FileSys::FileSystem* fileSystem;
FString activeLanguage; FString activeLanguage;
StringMacroMap allMacros; StringMacroMap allMacros;
LangMap allStrings; LangMap allStrings;
TArray<std::pair<uint32_t, StringMap*>> currentLanguageSet; TArray<std::pair<uint32_t, StringMap*>> currentLanguageSet;
int defaultgender = 0;
void LoadLanguage (int lumpnum, const char* buffer, size_t size); void LoadLanguage (int lumpnum, const char* buffer, size_t size);
TArray<TArray<FString>> parseCSV(const char* buffer, size_t size); TArray<TArray<FString>> parseCSV(const char* buffer, size_t size);
bool ParseLanguageCSV(int filenum, const char* buffer, size_t size); bool ParseLanguageCSV(int lumpnum, const char* buffer, size_t size);
bool readMacros(const char* buffer, size_t size); bool readMacros(int lumpnum);
void DeleteString(int langid, FName label); void DeleteString(int langid, FName label);
void DeleteForLabel(int filenum, FName label); void DeleteForLabel(int lumpnum, FName label);
static size_t ProcessEscapes (char *str); static size_t ProcessEscapes (char *str);
public: public:
@ -135,7 +138,7 @@ public:
const char* localize(const char* str) const char* localize(const char* str)
{ {
return *str == '$' ? GetString(str + 1) : str; return *str == '$' ? operator()(str + 1) : str;
} }
}; };

View file

@ -42,8 +42,8 @@ public:
void SetMaxIwadNum(int x) { MaxIwadIndex = x; } void SetMaxIwadNum(int x) { MaxIwadIndex = x; }
bool InitSingleFile(const char *filename, FileSystemMessageFunc Printf = nullptr); bool InitSingleFile(const char *filename, FileSystemMessageFunc Printf = nullptr);
bool InitMultipleFiles (std::vector<std::string>& filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false); bool InitMultipleFiles (std::vector<std::string>& filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr);
void AddFile (const char *filename, FileReader *wadinfo, LumpFilterInfo* filter, FileSystemMessageFunc Printf); void AddFile (const char *filename, FileReader *wadinfo, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile);
int CheckIfResourceFileLoaded (const char *name) noexcept; int CheckIfResourceFileLoaded (const char *name) noexcept;
void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {} void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {}

View file

@ -31,6 +31,8 @@
** **
*/ */
namespace FileSys {
#ifdef _WIN32 #ifdef _WIN32
#ifndef _WINNT_ #ifndef _WINNT_
@ -38,8 +40,6 @@
#include <windows.h> #include <windows.h>
#endif #endif
namespace FileSys {
class FInternalCriticalSection class FInternalCriticalSection
{ {
public: public:
@ -82,8 +82,6 @@ void LeaveCriticalSection(FInternalCriticalSection *c)
#include <pthread.h> #include <pthread.h>
namespace FileSys {
class FInternalCriticalSection class FInternalCriticalSection
{ {
public: public:

View file

@ -106,7 +106,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy
if (mBasePath == nullptr) if (mBasePath == nullptr)
{ {
// extract the base path from the first entry to cover changes made in ScanDirectory. // extract the base path from the first entry to cover changes made in ScanDirectory.
auto full = entry.FilePath.rfind(entry.FilePathRel); auto full = entry.FilePath.find(entry.FilePathRel);
std::string path(entry.FilePath, 0, full); std::string path(entry.FilePath, 0, full);
mBasePath = stringpool->Strdup(path.c_str()); mBasePath = stringpool->Strdup(path.c_str());
} }
@ -132,7 +132,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy
// On Linux this is important because its file system is case sensitive, // On Linux this is important because its file system is case sensitive,
// but even on Windows the Unicode normalization is destructive // but even on Windows the Unicode normalization is destructive
// for some characters and cannot be used for file names. // for some characters and cannot be used for file names.
// Examples for this are the Turkish 'i's or the German Ăź. // Examples for this are the Turkish 'i's or the German Ăź.
SystemFilePath[count] = stringpool->Strdup(entry.FilePathRel.c_str()); SystemFilePath[count] = stringpool->Strdup(entry.FilePathRel.c_str());
// for internal access we use the normalized form of the relative path. // for internal access we use the normalized form of the relative path.
// this is fine because the paths that get compared against this will also be normalized. // this is fine because the paths that get compared against this will also be normalized.

View file

@ -238,7 +238,7 @@ bool FileSystem::InitSingleFile(const char* filename, FileSystemMessageFunc Prin
return InitMultipleFiles(filenames, nullptr, Printf); return InitMultipleFiles(filenames, nullptr, Printf);
} }
bool FileSystem::InitMultipleFiles (std::vector<std::string>& filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates) bool FileSystem::InitMultipleFiles (std::vector<std::string>& filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates, FILE* hashfile)
{ {
int numfiles; int numfiles;
@ -269,7 +269,7 @@ bool FileSystem::InitMultipleFiles (std::vector<std::string>& filenames, LumpFil
for(size_t i=0;i<filenames.size(); i++) for(size_t i=0;i<filenames.size(); i++)
{ {
AddFile(filenames[i].c_str(), nullptr, filter, Printf); AddFile(filenames[i].c_str(), nullptr, filter, Printf, hashfile);
if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/"); if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/");
std::string path = "filter/%s"; std::string path = "filter/%s";
@ -327,7 +327,7 @@ int FileSystem::AddFromBuffer(const char* name, char* data, int size, int id, in
// [RH] Removed reload hack // [RH] Removed reload hack
//========================================================================== //==========================================================================
void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInfo* filter, FileSystemMessageFunc Printf) void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile)
{ {
int startlump; int startlump;
bool isdir = false; bool isdir = false;
@ -396,10 +396,49 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf
path += ':'; path += ':';
path += resfile->getName(i); path += resfile->getName(i);
auto embedded = resfile->GetEntryReader(i, READER_CACHED); auto embedded = resfile->GetEntryReader(i, READER_CACHED);
AddFile(path.c_str(), &embedded, filter, Printf); AddFile(path.c_str(), &embedded, filter, Printf, hashfile);
} }
} }
if (hashfile)
{
uint8_t cksum[16];
char cksumout[33];
memset(cksumout, 0, sizeof(cksumout));
if (filereader.isOpen())
{
filereader.Seek(0, FileReader::SeekSet);
md5Hash(filereader, cksum);
for (size_t j = 0; j < sizeof(cksum); ++j)
{
snprintf(cksumout + (j * 2), 3, "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, hash: %s, size: %td\n", filename, cksumout, filereader.GetLength());
}
else
fprintf(hashfile, "file: %s, Directory structure\n", filename);
for (int i = 0; i < resfile->EntryCount(); i++)
{
int flags = resfile->GetEntryFlags(i);
if (!(flags & RESFF_EMBEDDED))
{
auto reader = resfile->GetEntryReader(i, READER_SHARED, 0);
md5Hash(filereader, cksum);
for (size_t j = 0; j < sizeof(cksum); ++j)
{
snprintf(cksumout + (j * 2), 3, "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %zu\n", filename, resfile->getName(i), cksumout, (uint64_t)resfile->Length(i));
}
}
}
return; return;
} }
} }

View file

@ -35,7 +35,6 @@
#include "fs_findfile.h" #include "fs_findfile.h"
#include <string.h> #include <string.h>
#include <vector> #include <vector>
#include <sys/stat.h>
#ifndef _WIN32 #ifndef _WIN32
@ -46,6 +45,8 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
#include <fnmatch.h> #include <fnmatch.h>
#include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#endif #endif

View file

@ -34,7 +34,6 @@
** **
*/ */
#include <algorithm>
#include <miniz.h> #include <miniz.h>
#include "resourcefile.h" #include "resourcefile.h"
#include "md5.hpp" #include "md5.hpp"
@ -46,7 +45,7 @@
#include "wildcards.hpp" #include "wildcards.hpp"
namespace FileSys { namespace FileSys {
// this is for restricting shared file readers to the main thread. // this is for restricting shared file readers to the main thread.
thread_local bool mainThread; thread_local bool mainThread;
void SetMainThread() void SetMainThread()
@ -162,7 +161,6 @@ static int nulPrintf(FSMessageLevel msg, const char* fmt, ...)
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{ {
if (!file.isOpen()) return nullptr;
if (Printf == nullptr) Printf = nulPrintf; if (Printf == nullptr) Printf = nulPrintf;
for(auto func : funcs) for(auto func : funcs)
{ {

View file

@ -271,12 +271,12 @@ bool CheckFontComplete(FFont* font)
{ {
// Also check if the SmallFont contains all characters this language needs. // Also check if the SmallFont contains all characters this language needs.
// If not, switch back to the original one. // If not, switch back to the original one.
return font->CanPrint(GStrings.CheckString("REQUIRED_CHARACTERS")); return font->CanPrint(GStrings["REQUIRED_CHARACTERS"]);
} }
void UpdateGenericUI(bool cvar) void UpdateGenericUI(bool cvar)
{ {
auto switchstr = GStrings.CheckString("USE_GENERIC_FONT"); auto switchstr = GStrings["USE_GENERIC_FONT"];
generic_ui = (cvar || (switchstr && strtoll(switchstr, nullptr, 0))); generic_ui = (cvar || (switchstr && strtoll(switchstr, nullptr, 0)));
if (!generic_ui) if (!generic_ui)
{ {
@ -311,7 +311,7 @@ void UpdateGenericUI(bool cvar)
} }
} }
// Turkish i crap. What a mess, just to save two code points... :( // Turkish i crap. What a mess, just to save two code points... :(
switchstr = GStrings.CheckString("REQUIRED_CHARACTERS"); switchstr = GStrings["REQUIRED_CHARACTERS"];
special_i = switchstr && strstr(switchstr, "\xc4\xb0") != nullptr; // capital dotted i (İ). special_i = switchstr && strstr(switchstr, "\xc4\xb0") != nullptr; // capital dotted i (İ).
if (special_i) if (special_i)
{ {

View file

@ -133,26 +133,6 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, SetEnabled)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(IJoystickConfig, AllowsEnabledInBackground)
{
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
ACTION_RETURN_BOOL(self->AllowsEnabledInBackground());
}
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetEnabledInBackground)
{
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
ACTION_RETURN_BOOL(self->GetEnabledInBackground());
}
DEFINE_ACTION_FUNCTION(IJoystickConfig, SetEnabledInBackground)
{
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
PARAM_BOOL(enabled);
self->SetEnabledInBackground(enabled);
return 0;
}
void UpdateJoystickMenu(IJoystickConfig *selected) void UpdateJoystickMenu(IJoystickConfig *selected)
{ {

View file

@ -51,7 +51,6 @@
CVAR(String, save_dir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(String, save_dir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
FString SavegameFolder; FString SavegameFolder;
CVAR(Int, save_sort_order, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
//============================================================================= //=============================================================================
// //
@ -85,7 +84,7 @@ int FSavegameManagerBase::RemoveSaveSlot(int index)
int listindex = SaveGames[0]->bNoDelete ? index - 1 : index; int listindex = SaveGames[0]->bNoDelete ? index - 1 : index;
if (listindex < 0) return index; if (listindex < 0) return index;
RemoveFile(SaveGames[index]->Filename.GetChars()); remove(SaveGames[index]->Filename.GetChars());
UnloadSaveData(); UnloadSaveData();
FSaveGameNode *file = SaveGames[index]; FSaveGameNode *file = SaveGames[index];
@ -137,19 +136,7 @@ int FSavegameManagerBase::InsertSaveNode(FSaveGameNode *node)
//if (SaveGames[0] == &NewSaveNode) i++; // To not insert above the "new savegame" dummy entry. //if (SaveGames[0] == &NewSaveNode) i++; // To not insert above the "new savegame" dummy entry.
for (; i < SaveGames.Size(); i++) for (; i < SaveGames.Size(); i++)
{ {
bool sortcmp = false; if (SaveGames[i]->bOldVersion || node->SaveTitle.CompareNoCase(SaveGames[i]->SaveTitle) <= 0)
switch(save_sort_order)
{
case 1:
sortcmp = node->CreationTime.CompareNoCase(SaveGames[i]->CreationTime) > 0;
break;
default:
case 0:
sortcmp = node->SaveTitle.CompareNoCase(SaveGames[i]->SaveTitle) <= 0;
break;
}
if (SaveGames[i]->bOldVersion || sortcmp)
{ {
break; break;
} }
@ -183,18 +170,12 @@ void FSavegameManagerBase::NotifyNewSave(const FString &file, const FString &tit
#endif #endif
{ {
node->SaveTitle = title; node->SaveTitle = title;
node->CreationTime = myasctime();
node->bOldVersion = false; node->bOldVersion = false;
node->bMissingWads = false; node->bMissingWads = false;
// refresh my game's position on the list (needed if time/name changed)
SaveGames.Delete(i);
int index = InsertSaveNode(node);
if (okForQuicksave) if (okForQuicksave)
{ {
if (quickSaveSlot == nullptr || quickSaveSlot == (FSaveGameNode*)1 || forceQuicksave) quickSaveSlot = node; if (quickSaveSlot == nullptr || quickSaveSlot == (FSaveGameNode*)1 || forceQuicksave) quickSaveSlot = node;
LastAccessed = LastSaved = index; LastAccessed = LastSaved = i;
} }
return; return;
} }
@ -202,7 +183,6 @@ void FSavegameManagerBase::NotifyNewSave(const FString &file, const FString &tit
auto node = new FSaveGameNode; auto node = new FSaveGameNode;
node->SaveTitle = title; node->SaveTitle = title;
node->CreationTime = myasctime();
node->Filename = file; node->Filename = file;
node->bOldVersion = false; node->bOldVersion = false;
node->bMissingWads = false; node->bMissingWads = false;
@ -294,7 +274,7 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, DoSave)
unsigned FSavegameManagerBase::ExtractSaveData(int index) unsigned FSavegameManagerBase::ExtractSaveData(int index)
{ {
std::unique_ptr<FResourceFile> resf; FResourceFile *resf;
FSaveGameNode *node; FSaveGameNode *node;
if (index == -1) if (index == -1)
@ -315,7 +295,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index)
(node = SaveGames[index]) && (node = SaveGames[index]) &&
!node->Filename.IsEmpty() && !node->Filename.IsEmpty() &&
!node->bOldVersion && !node->bOldVersion &&
( (resf.reset(FResourceFile::OpenResourceFile(node->Filename.GetChars(), true))), resf != nullptr)) (resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), true)) != nullptr)
{ {
auto info = resf->FindEntry("info.json"); auto info = resf->FindEntry("info.json");
if (info < 0) if (info < 0)
@ -336,8 +316,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index)
auto pic = resf->FindEntry("savepic.png"); auto pic = resf->FindEntry("savepic.png");
if (pic >= 0) if (pic >= 0)
{ {
// This must use READER_CACHED or it will lock the savegame file. FileReader picreader = resf->GetEntryReader(pic, FileSys::READER_NEW, FileSys::READERFLAG_SEEKABLE);
FileReader picreader = resf->GetEntryReader(pic, FileSys::READER_CACHED, FileSys::READERFLAG_SEEKABLE);
PNGHandle *png = M_VerifyPNG(picreader); PNGHandle *png = M_VerifyPNG(picreader);
if (png != nullptr) if (png != nullptr)
{ {
@ -350,6 +329,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index)
} }
} }
} }
delete resf;
} }
return index; return index;
} }
@ -490,7 +470,7 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, GetSavegame)
void FSavegameManagerBase::InsertNewSaveNode() void FSavegameManagerBase::InsertNewSaveNode()
{ {
NewSaveNode.SaveTitle = GStrings.GetString("NEWSAVE"); NewSaveNode.SaveTitle = GStrings("NEWSAVE");
NewSaveNode.bNoDelete = true; NewSaveNode.bNoDelete = true;
SaveGames.Insert(0, &NewSaveNode); SaveGames.Insert(0, &NewSaveNode);
} }

View file

@ -11,7 +11,6 @@ struct FSaveGameNode
{ {
FString SaveTitle; FString SaveTitle;
FString Filename; FString Filename;
FString CreationTime;
bool bOldVersion = false; bool bOldVersion = false;
bool bMissingWads = false; bool bMissingWads = false;
bool bNoDelete = false; bool bNoDelete = false;

View file

@ -4,8 +4,6 @@
#include "TRS.h" #include "TRS.h"
#include "matrix.h" #include "matrix.h"
#include <variant>
class DBoneComponents : public DObject class DBoneComponents : public DObject
{ {
@ -16,41 +14,3 @@ public:
DBoneComponents() = default; DBoneComponents() = default;
}; };
struct ModelAnimFrameInterp
{
float inter = -1.0f;
int frame1 = -1;
int frame2 = -1;
};
struct ModelAnimFramePrecalculatedIQM
{
TArray<TRS> precalcBones;
};
enum EModelAnimFlags
{
MODELANIM_NONE = 1 << 0, // no animation
MODELANIM_LOOP = 1 << 1, // animation loops, otherwise it stays on the last frame once it ends
};
struct ModelAnim
{
int firstFrame = 0;
int lastFrame = 0;
int loopFrame = 0;
float framerate = 0;
double startFrame = 0;
int flags = MODELANIM_NONE;
double startTic = 0; // when the current animation started (changing framerates counts as restarting) (or when animation starts if interpolating from previous animation)
double switchOffset = 0; // when the animation was changed -- where to interpolate the switch from
};
static_assert(sizeof(ModelAnim) == sizeof(double) * 6);
using ModelAnimFrame = std::variant<std::nullptr_t, ModelAnimFrameInterp, ModelAnimFramePrecalculatedIQM>;
double getCurrentFrame(const ModelAnim &anim, double tic, bool *looped);
void calcFrame(const ModelAnim &anim, double tic, ModelAnimFrameInterp &inter);
void calcFrames(const ModelAnim &curAnim, double tic, ModelAnimFrameInterp &to, float &inter);

View file

@ -9,8 +9,6 @@
#include "tarray.h" #include "tarray.h"
#include "name.h" #include "name.h"
#include "bonecomponents.h"
class DBoneComponents; class DBoneComponents;
class FModelRenderer; class FModelRenderer;
class FGameTexture; class FGameTexture;
@ -96,10 +94,7 @@ public:
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) = 0; virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) = 0;
virtual float getAspectFactor(float vscale) { return 1.f; } virtual float getAspectFactor(float vscale) { return 1.f; }
virtual const TArray<TRS>* AttachAnimationData() { return nullptr; }; virtual const TArray<TRS>* AttachAnimationData() { return nullptr; };
virtual const TArray<VSMatrix> CalculateBones(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const TArray<TRS>* animationData, DBoneComponents* bones, int index) { return {}; };
virtual ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) { return nullptr; };
virtual const TArray<VSMatrix> CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) { return {}; };
void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; } void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; }
IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; } IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; }

View file

@ -120,12 +120,7 @@ public:
void BuildVertexBuffer(FModelRenderer* renderer) override; void BuildVertexBuffer(FModelRenderer* renderer) override;
void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override; void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override;
const TArray<TRS>* AttachAnimationData() override; const TArray<TRS>* AttachAnimationData() override;
const TArray<VSMatrix> CalculateBones(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const TArray<TRS>* animationData, DBoneComponents* bones, int index) override;
ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) override;
const TArray<VSMatrix> CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) override;
ModelAnimFramePrecalculatedIQM CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData, DBoneComponents* bones, int index);
const TArray<VSMatrix> CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData, DBoneComponents* bones, int index);
private: private:
void LoadGeometry(); void LoadGeometry();

View file

@ -560,108 +560,7 @@ static TRS InterpolateBone(const TRS &from, const TRS &to, float t, float invt)
return bone; return bone;
} }
#include "printf.h" const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const TArray<TRS>* animationData, DBoneComponents* boneComponentData, int index)
ModelAnimFrame IQMModel::PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index)
{
if(inter <= 0)
{
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
}
else if(std::holds_alternative<ModelAnimFrameInterp>(from))
{
auto &from_interp = std::get<ModelAnimFrameInterp>(from);
return CalculateFrameIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index);
}
else if(std::holds_alternative<ModelAnimFramePrecalculatedIQM>(from))
{
return CalculateFrameIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData, bones, index);
}
else
{
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
}
}
const TArray<VSMatrix> IQMModel::CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index)
{
if(inter <= 0)
{
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
}
else if(std::holds_alternative<ModelAnimFrameInterp>(from))
{
auto &from_interp = std::get<ModelAnimFrameInterp>(from);
return CalculateBonesIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index);
}
else if(std::holds_alternative<ModelAnimFramePrecalculatedIQM>(from))
{
return CalculateBonesIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData, bones, index);
}
else
{
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
}
}
ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData, DBoneComponents* boneComponentData, int index)
{
ModelAnimFramePrecalculatedIQM out;
const TArray<TRS>& animationFrames = animationData ? *animationData : TRSData;
out.precalcBones.Resize(Joints.Size());
if (Joints.Size() > 0)
{
int numbones = Joints.SSize();
int offset1 = frame1 * numbones;
int offset2 = frame2 * numbones;
int offset1_1 = frame1_prev * numbones;
int offset2_1 = frame2_prev * numbones;
float invt = 1.0f - inter;
float invt1 = 1.0f - inter1_prev;
float invt2 = 1.0f - inter2_prev;
for (int i = 0; i < numbones; i++)
{
TRS prev;
if(precalculated)
{
prev = precalculated->precalcBones[i];
}
else
{
if(frame1 >= 0 && (frame1_prev >= 0 || inter1_prev < 0))
{
prev = inter1_prev <= 0 ? animationFrames[offset1 + i] : InterpolateBone(animationFrames[offset1_1 + i], animationFrames[offset1 + i], inter1_prev, invt1);
}
}
TRS next;
if(frame2 >= 0 && (frame2_prev >= 0 || inter2_prev < 0))
{
next = inter2_prev <= 0 ? animationFrames[offset2 + i] : InterpolateBone(animationFrames[offset2_1 + i], animationFrames[offset2 + i], inter2_prev, invt2);
}
if(frame1 >= 0 || inter < 0)
{
out.precalcBones[i] = inter < 0 ? animationFrames[offset1 + i] : InterpolateBone(prev, next , inter, invt);
}
}
}
return out;
}
const TArray<VSMatrix> IQMModel::CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData, DBoneComponents* boneComponentData, int index)
{ {
const TArray<TRS>& animationFrames = animationData ? *animationData : TRSData; const TArray<TRS>& animationFrames = animationData ? *animationData : TRSData;
if (Joints.Size() > 0) if (Joints.Size() > 0)
@ -698,16 +597,9 @@ const TArray<VSMatrix> IQMModel::CalculateBonesIQM(int frame1, int frame2, float
{ {
TRS prev; TRS prev;
if(precalculated) if(frame1 >= 0 && (frame1_prev >= 0 || inter1_prev < 0))
{ {
prev = precalculated->precalcBones[i]; prev = inter1_prev <= 0 ? animationFrames[offset1 + i] : InterpolateBone(animationFrames[offset1_1 + i], animationFrames[offset1 + i], inter1_prev, invt1);
}
else
{
if(frame1 >= 0 && (frame1_prev >= 0 || inter1_prev < 0))
{
prev = inter1_prev <= 0 ? animationFrames[offset1 + i] : InterpolateBone(animationFrames[offset1_1 + i], animationFrames[offset1 + i], inter1_prev, invt1);
}
} }
TRS next; TRS next;

View file

@ -73,9 +73,6 @@ struct FVoxelDef
int VoxeldefIndex; // Needed by GZDoom int VoxeldefIndex; // Needed by GZDoom
double Scale; double Scale;
DAngle AngleOffset;// added to actor's angle to compensate for wrong-facing voxels DAngle AngleOffset;// added to actor's angle to compensate for wrong-facing voxels
double xoffset;
double yoffset;
double zoffset;
bool PitchFromMomentum; bool PitchFromMomentum;
bool UseActorPitch; bool UseActorPitch;
bool UseActorRoll; bool UseActorRoll;

View file

@ -317,8 +317,6 @@ void DObject::Release()
void DObject::Destroy () void DObject::Destroy ()
{ {
RemoveFromNetwork();
// We cannot call the VM during shutdown because all the needed data has been or is in the process of being deleted. // We cannot call the VM during shutdown because all the needed data has been or is in the process of being deleted.
if (PClass::bVMOperational) if (PClass::bVMOperational)
{ {
@ -330,7 +328,6 @@ void DObject::Destroy ()
} }
OnDestroy(); OnDestroy();
ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe; ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;
GC::WriteBarrier(this);
} }
DEFINE_ACTION_FUNCTION(DObject, Destroy) DEFINE_ACTION_FUNCTION(DObject, Destroy)
@ -572,15 +569,8 @@ void DObject::Serialize(FSerializer &arc)
SerializeFlag("justspawned", OF_JustSpawned); SerializeFlag("justspawned", OF_JustSpawned);
SerializeFlag("spawned", OF_Spawned); SerializeFlag("spawned", OF_Spawned);
SerializeFlag("networked", OF_Networked);
ObjectFlags |= OF_SerialSuccess;
if (arc.isReading() && (ObjectFlags & OF_Networked)) ObjectFlags |= OF_SerialSuccess;
{
ClearNetworkID();
EnableNetworking(true);
}
} }
void DObject::CheckIfSerialized () const void DObject::CheckIfSerialized () const
@ -595,6 +585,7 @@ void DObject::CheckIfSerialized () const
} }
} }
DEFINE_ACTION_FUNCTION(DObject, MSTime) DEFINE_ACTION_FUNCTION(DObject, MSTime)
{ {
ACTION_RETURN_INT((uint32_t)I_msTime()); ACTION_RETURN_INT((uint32_t)I_msTime());
@ -623,165 +614,3 @@ void *DObject::ScriptVar(FName field, PType *type)
// This is only for internal use so I_Error is fine. // This is only for internal use so I_Error is fine.
I_Error("Variable %s not found in %s\n", field.GetChars(), cls->TypeName.GetChars()); I_Error("Variable %s not found in %s\n", field.GetChars(), cls->TypeName.GetChars());
} }
//==========================================================================
//
//
//
//==========================================================================
void NetworkEntityManager::InitializeNetworkEntities()
{
if (!s_netEntities.Size())
s_netEntities.AppendFill(nullptr, NetIDStart); // Allocate the first 0-8 slots for the world and clients.
}
// Clients need special handling since they always go in slots 1 - MAXPLAYERS.
void NetworkEntityManager::SetClientNetworkEntity(DObject* mo, const unsigned int playNum)
{
// If resurrecting, we need to swap the corpse's position with the new pawn's
// position so it's no longer considered the client's body.
const uint32_t id = ClientNetIDStart + playNum;
DObject* const oldBody = s_netEntities[id];
if (oldBody != nullptr)
{
if (oldBody == mo)
return;
const uint32_t curID = mo->GetNetworkID();
s_netEntities[curID] = oldBody;
oldBody->ClearNetworkID();
oldBody->SetNetworkID(curID);
mo->ClearNetworkID();
}
else
{
RemoveNetworkEntity(mo); // Free up its current id.
}
s_netEntities[id] = mo;
mo->SetNetworkID(id);
}
void NetworkEntityManager::AddNetworkEntity(DObject* const ent)
{
if (ent->IsNetworked())
return;
// Slot 0 is reserved for the world.
// Clients go in the first 1 - MAXPLAYERS slots
// Everything else is first come first serve.
uint32_t id = WorldNetID;
if (s_openNetIDs.Size())
{
s_openNetIDs.Pop(id);
s_netEntities[id] = ent;
}
else
{
id = s_netEntities.Push(ent);
}
ent->SetNetworkID(id);
}
void NetworkEntityManager::RemoveNetworkEntity(DObject* const ent)
{
if (!ent->IsNetworked())
return;
const uint32_t id = ent->GetNetworkID();
if (id == WorldNetID)
return;
assert(s_netEntities[id] == ent);
if (id >= NetIDStart)
s_openNetIDs.Push(id);
s_netEntities[id] = nullptr;
ent->ClearNetworkID();
}
DObject* NetworkEntityManager::GetNetworkEntity(const uint32_t id)
{
if (id == WorldNetID || id >= s_netEntities.Size())
return nullptr;
return s_netEntities[id];
}
//==========================================================================
//
//
//
//==========================================================================
void DObject::SetNetworkID(const uint32_t id)
{
if (!IsNetworked())
{
ObjectFlags |= OF_Networked;
_networkID = id;
}
}
void DObject::ClearNetworkID()
{
ObjectFlags &= ~OF_Networked;
_networkID = NetworkEntityManager::WorldNetID;
}
void DObject::EnableNetworking(const bool enable)
{
if (enable)
NetworkEntityManager::AddNetworkEntity(this);
else
NetworkEntityManager::RemoveNetworkEntity(this);
}
void DObject::RemoveFromNetwork()
{
NetworkEntityManager::RemoveNetworkEntity(this);
}
static unsigned int GetNetworkID(DObject* const self)
{
return self->GetNetworkID();
}
DEFINE_ACTION_FUNCTION_NATIVE(DObject, GetNetworkID, GetNetworkID)
{
PARAM_SELF_PROLOGUE(DObject);
ACTION_RETURN_INT(self->GetNetworkID());
}
static void EnableNetworking(DObject* const self, const bool enable)
{
self->EnableNetworking(enable);
}
DEFINE_ACTION_FUNCTION_NATIVE(DObject, EnableNetworking, EnableNetworking)
{
PARAM_SELF_PROLOGUE(DObject);
PARAM_BOOL(enable);
self->EnableNetworking(enable);
return 0;
}
static DObject* GetNetworkEntity(const unsigned int id)
{
return NetworkEntityManager::GetNetworkEntity(id);
}
DEFINE_ACTION_FUNCTION_NATIVE(DObject, GetNetworkEntity, GetNetworkEntity)
{
PARAM_PROLOGUE;
PARAM_UINT(id);
ACTION_RETURN_OBJECT(NetworkEntityManager::GetNetworkEntity(id));
}

View file

@ -351,18 +351,6 @@ protected:
friend T* Create(Args&&... args); friend T* Create(Args&&... args);
friend class JitCompiler; friend class JitCompiler;
private:
// This is intentionally left unserialized.
uint32_t _networkID;
public:
inline bool IsNetworked() const { return (ObjectFlags & OF_Networked); }
inline uint32_t GetNetworkID() const { return _networkID; }
void SetNetworkID(const uint32_t id);
void ClearNetworkID();
void RemoveFromNetwork();
virtual void EnableNetworking(const bool enable);
}; };
// This is the only method aside from calling CreateNew that should be used for creating DObjects // This is the only method aside from calling CreateNew that should be used for creating DObjects
@ -487,25 +475,4 @@ inline T *&DObject::PointerVar(FName field)
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle. return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
} }
class NetworkEntityManager
{
private:
inline static TArray<DObject*> s_netEntities = {};
inline static TArray<uint32_t> s_openNetIDs = {};
public:
NetworkEntityManager() = delete;
static constexpr uint32_t WorldNetID = 0u;
static constexpr uint32_t ClientNetIDStart = 1u;
inline static uint32_t NetIDStart;// = MAXPLAYERS + 1u;
static void InitializeNetworkEntities();
static void SetClientNetworkEntity(DObject* mo, const unsigned int playNum);
static void AddNetworkEntity(DObject* const ent);
static void RemoveNetworkEntity(DObject* const ent);
static DObject* GetNetworkEntity(const uint32_t id);
};
#endif //__DOBJECT_H__ #endif //__DOBJECT_H__

View file

@ -26,7 +26,6 @@ enum EObjectFlags
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk) OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
OF_Spawned = 1 << 12, // Thinker was spawned at all (some thinkers get deleted before spawning) OF_Spawned = 1 << 12, // Thinker was spawned at all (some thinkers get deleted before spawning)
OF_Released = 1 << 13, // Object was released from the GC system and should not be processed by GC function OF_Released = 1 << 13, // Object was released from the GC system and should not be processed by GC function
OF_Networked = 1 << 14, // Object has a unique network identifier that makes it synchronizable between all clients.
}; };
template<class T> class TObjPtr; template<class T> class TObjPtr;

View file

@ -107,10 +107,6 @@ public:
virtual bool GetEnabled(); virtual bool GetEnabled();
virtual void SetEnabled(bool enabled); virtual void SetEnabled(bool enabled);
bool AllowsEnabledInBackground() { return false; }
bool GetEnabledInBackground() { return false; }
void SetEnabledInBackground(bool enabled) {}
virtual void SetDefaultConfig(); virtual void SetDefaultConfig();
virtual FString GetIdentifier(); virtual FString GetIdentifier();

View file

@ -122,7 +122,7 @@ void I_ShowFatalError(const char *message)
} }
int I_PickIWad(WadStuff* const wads, const int numwads, const bool showwin, const int defaultiwad, int&, FString&) int I_PickIWad(WadStuff* const wads, const int numwads, const bool showwin, const int defaultiwad, int&)
{ {
if (!showwin) if (!showwin)
{ {

View file

@ -66,7 +66,6 @@ public:
void NetInit(const char* message, int playerCount); void NetInit(const char* message, int playerCount);
void NetProgress(int count); void NetProgress(int count);
void NetDone(); void NetDone();
void NetClose();
private: private:
NSWindow* m_window; NSWindow* m_window;

View file

@ -531,8 +531,3 @@ void FConsoleWindow::NetDone()
m_netAbortButton = nil; m_netAbortButton = nil;
} }
} }
void FConsoleWindow::NetClose()
{
// TODO: Implement this
}

View file

@ -110,11 +110,6 @@ void FBasicStartupScreen::NetDone()
FConsoleWindow::GetInstance().NetDone(); FConsoleWindow::GetInstance().NetDone();
} }
void FBasicStartupScreen::NetClose()
{
FConsoleWindow::GetInstance().NetClose();
}
bool FBasicStartupScreen::NetLoop(bool (*timerCallback)(void*), void* const userData) bool FBasicStartupScreen::NetLoop(bool (*timerCallback)(void*), void* const userData)
{ {
while (true) while (true)

View file

@ -38,7 +38,7 @@ void I_PrintStr (const char *str);
void I_SetIWADInfo (); void I_SetIWADInfo ();
// Pick from multiple IWADs to use // Pick from multiple IWADs to use
int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad, int&, FString &); int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad, int&);
// [RH] Checks the registry for Steam's install path, so we can scan its // [RH] Checks the registry for Steam's install path, so we can scan its
// directories for IWADs if the user purchased any through Steam. // directories for IWADs if the user purchased any through Steam.
@ -54,6 +54,17 @@ bool I_WriteIniFailed (const char* filename);
class FGameTexture; class FGameTexture;
bool I_SetCursor(FGameTexture *); bool I_SetCursor(FGameTexture *);
static inline char *strlwr(char *str)
{
char *ptr = str;
while(*ptr)
{
*ptr = tolower(*ptr);
++ptr;
}
return str;
}
inline int I_GetNumaNodeCount() { return 1; } inline int I_GetNumaNodeCount() { return 1; }
inline int I_GetNumaNodeThreadCount(int numaNode) { return std::max<int>(std::thread::hardware_concurrency(), 1); } inline int I_GetNumaNodeThreadCount(int numaNode) { return std::max<int>(std::thread::hardware_concurrency(), 1); }
inline void I_SetThreadNumaNode(std::thread &thread, int numaNode) { } inline void I_SetThreadNumaNode(std::thread &thread, int numaNode) { }

View file

@ -167,10 +167,6 @@ public:
Enabled = enabled; Enabled = enabled;
} }
bool AllowsEnabledInBackground() { return false; }
bool GetEnabledInBackground() { return false; }
void SetEnabledInBackground(bool enabled) {}
FString GetIdentifier() FString GetIdentifier()
{ {
char id[16]; char id[16];

View file

@ -298,7 +298,7 @@ void I_PrintStr(const char *cp)
if (StartWindow) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos); if (StartWindow) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos);
} }
int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags, FString &extraArgs) int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags)
{ {
if (!showwin) if (!showwin)
{ {
@ -308,7 +308,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int&
#ifdef __APPLE__ #ifdef __APPLE__
return I_PickIWad_Cocoa (wads, numwads, showwin, defaultiwad); return I_PickIWad_Cocoa (wads, numwads, showwin, defaultiwad);
#else #else
return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags, &extraArgs); return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags);
#endif #endif
} }

View file

@ -57,7 +57,6 @@ class FTTYStartupScreen : public FStartupScreen
void NetInit(const char *message, int num_players); void NetInit(const char *message, int num_players);
void NetProgress(int count); void NetProgress(int count);
void NetDone(); void NetDone();
void NetClose();
bool NetLoop(bool (*timer_callback)(void *), void *userdata); bool NetLoop(bool (*timer_callback)(void *), void *userdata);
protected: protected:
bool DidNetInit; bool DidNetInit;
@ -238,11 +237,6 @@ void FTTYStartupScreen::NetProgress(int count)
} }
} }
void FTTYStartupScreen::NetClose()
{
// TODO: Implement this
}
//=========================================================================== //===========================================================================
// //
// FTTYStartupScreen :: NetLoop // FTTYStartupScreen :: NetLoop

View file

@ -112,11 +112,7 @@ FString M_GetAppDataPath(bool create)
{ {
// Don't use GAME_DIR and such so that ZDoom and its child ports can // Don't use GAME_DIR and such so that ZDoom and its child ports can
// share the node cache. // share the node cache.
#if defined(__HAIKU__) FString path = NicePath("$HOME/.config/" GAMENAMELOWERCASE);
FString path = NicePath("$HOME/config/settings/" GAMENAME);
#else
FString path = NicePath("$HOME/.config/" GAMENAMELOWERCASE);
#endif
if (create) if (create)
{ {
CreatePath(path.GetChars()); CreatePath(path.GetChars());

View file

@ -183,10 +183,6 @@ public:
bool GetEnabled(); bool GetEnabled();
void SetEnabled(bool enabled); void SetEnabled(bool enabled);
bool AllowsEnabledInBackground() { return false; }
bool GetEnabledInBackground() { return false; }
void SetEnabledInBackground(bool enabled) {}
void SetDefaultConfig(); void SetDefaultConfig();
FString GetIdentifier(); FString GetIdentifier();

View file

@ -124,9 +124,6 @@ int BlockMouseMove;
static bool EventHandlerResultForNativeMouse; static bool EventHandlerResultForNativeMouse;
EXTERN_CVAR(Bool, i_pauseinbackground);
CVAR (Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
static void I_CheckGUICapture () static void I_CheckGUICapture ()
@ -484,8 +481,8 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break; break;
case WM_ACTIVATEAPP: case WM_ACTIVATEAPP:
AppActive = (wParam == TRUE); AppActive = wParam == TRUE;
if (wParam || !i_pauseinbackground) if (wParam)
{ {
SetPriorityClass (GetCurrentProcess (), INGAME_PRIORITY_CLASS); SetPriorityClass (GetCurrentProcess (), INGAME_PRIORITY_CLASS);
} }

View file

@ -134,39 +134,6 @@ void I_SetIWADInfo()
{ {
} }
//==========================================================================
//
// isConsoleApp()
//
// runtime detection to detect if this is a console subsystem app.
//
// the reason for doing this is because it is possible to edit a binary directly and change its subsystem
// type via hexedit so in order to gain flexibility it makes no sense to just compile out the unused code.
//
// we may plan to publish tools to allow users to do this manually on their own.
//
//==========================================================================
bool isConsoleApp()
{
static bool alreadychecked = false;
static bool returnvalue;
if (!alreadychecked)
{
DWORD pids[2];
DWORD num_pids = GetConsoleProcessList(pids, 2);
bool win32con_is_exclusive = (num_pids <= 1);
returnvalue = ((GetConsoleWindow() != NULL && !win32con_is_exclusive) || (GetStdHandle(STD_OUTPUT_HANDLE) != NULL));
alreadychecked = true;
}
//printf("isConsoleApp is %i\n", returnvalue);
return returnvalue;
}
//========================================================================== //==========================================================================
// //
// DoMain // DoMain
@ -191,22 +158,7 @@ int DoMain (HINSTANCE hInstance)
Args->AppendArg(FString(wargv[i])); Args->AppendArg(FString(wargv[i]));
} }
if (isConsoleApp()) if (Args->CheckParm("-stdout"))
{
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
DWORD mode;
if (GetConsoleMode(StdOut, &mode))
{
if (SetConsoleMode(StdOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
FancyStdOut = IsWindows10OrGreater(); // Windows 8.1 and lower do not understand ANSI formatting.
}
}
else if (Args->CheckParm("-stdout") || Args->CheckParm("-norun"))
{ {
// As a GUI application, we don't normally get a console when we start. // As a GUI application, we don't normally get a console when we start.
// If we were run from the shell and are on XP+, we can attach to its // If we were run from the shell and are on XP+, we can attach to its
@ -523,11 +475,6 @@ CUSTOM_CVAR(Bool, disablecrashlog, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
// //
//========================================================================== //==========================================================================
int wmain()
{
return wWinMain(GetModuleHandle(0), 0, GetCommandLineW(), SW_SHOW);
}
int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int nCmdShow) int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int nCmdShow)
{ {
g_hInst = hInstance; g_hInst = hInstance;

View file

@ -128,11 +128,6 @@ void MainWindow::HideNetStartPane()
NetStartWindow::HideNetStartPane(); NetStartWindow::HideNetStartPane();
} }
void MainWindow::CloseNetStartPane()
{
NetStartWindow::NetClose();
}
void MainWindow::SetNetStartProgress(int pos) void MainWindow::SetNetStartProgress(int pos)
{ {
NetStartWindow::SetNetStartProgress(pos); NetStartWindow::SetNetStartProgress(pos);

View file

@ -29,7 +29,6 @@ public:
void SetNetStartProgress(int pos); void SetNetStartProgress(int pos);
bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata); bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
void HideNetStartPane(); void HideNetStartPane();
void CloseNetStartPane();
void SetWindowTitle(const char* caption); void SetWindowTitle(const char* caption);

View file

@ -267,7 +267,7 @@ void I_CheckNativeMouse(bool preferNative, bool eventhandlerresult)
} }
else else
{ {
if (preferNative || !use_mouse) if ((GetForegroundWindow() != mainwindow.GetHandle()) || preferNative || !use_mouse)
{ {
want_native = true; want_native = true;
} }
@ -286,10 +286,6 @@ void I_CheckNativeMouse(bool preferNative, bool eventhandlerresult)
if (!want_native && eventhandlerresult) if (!want_native && eventhandlerresult)
want_native = true; want_native = true;
// The application should *never* grab the mouse cursor if its window doesn't have the focus.
if (GetForegroundWindow() != mainwindow.GetHandle())
want_native = true;
//Printf ("%d %d %d\n", wantNative, preferNative, NativeMouse); //Printf ("%d %d %d\n", wantNative, preferNative, NativeMouse);
if (want_native != NativeMouse) if (want_native != NativeMouse)

View file

@ -117,10 +117,6 @@ public:
bool GetEnabled(); bool GetEnabled();
void SetEnabled(bool enabled); void SetEnabled(bool enabled);
bool AllowsEnabledInBackground() { return false; }
bool GetEnabledInBackground() { return false; }
void SetEnabledInBackground(bool enabled) {}
void SetDefaultConfig(); void SetDefaultConfig();
FString GetIdentifier(); FString GetIdentifier();

View file

@ -102,7 +102,6 @@
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
void DestroyCustomCursor(); void DestroyCustomCursor();
bool isConsoleApp();
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -307,7 +306,6 @@ static void PrintToStdOut(const char *cpt, HANDLE StdOut)
else break; else break;
} }
} }
DWORD bytes_written; DWORD bytes_written;
WriteFile(StdOut, printData.GetChars(), (DWORD)printData.Len(), &bytes_written, NULL); WriteFile(StdOut, printData.GetChars(), (DWORD)printData.Len(), &bytes_written, NULL);
if (terminal) if (terminal)
@ -355,7 +353,7 @@ static void SetQueryIWad(HWND dialog)
// //
//========================================================================== //==========================================================================
int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags, FString &extraArgs) int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags)
{ {
int vkey; int vkey;
if (stricmp(queryiwad_key, "shift") == 0) if (stricmp(queryiwad_key, "shift") == 0)
@ -372,7 +370,7 @@ int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad, int&
} }
if (showwin || (vkey != 0 && GetAsyncKeyState(vkey))) if (showwin || (vkey != 0 && GetAsyncKeyState(vkey)))
{ {
return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags, &extraArgs); return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags);
} }
return defaultiwad; return defaultiwad;
} }

View file

@ -38,7 +38,7 @@ void I_PrintStr (const char *cp);
void I_SetIWADInfo (); void I_SetIWADInfo ();
// Pick from multiple IWADs to use // Pick from multiple IWADs to use
int I_PickIWad(WadStuff* wads, int numwads, bool queryiwad, int defaultiwad, int& autoloadflags, FString &extraArgs); int I_PickIWad(WadStuff* wads, int numwads, bool queryiwad, int defaultiwad, int& autoloadflags);
// The ini could not be saved at exit // The ini could not be saved at exit
bool I_WriteIniFailed (const char* filename); bool I_WriteIniFailed (const char* filename);

View file

@ -65,8 +65,6 @@
#endif #endif
#endif #endif
extern bool AppActive;
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state); typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state);
@ -107,10 +105,6 @@ public:
bool GetEnabled(); bool GetEnabled();
void SetEnabled(bool enabled); void SetEnabled(bool enabled);
bool AllowsEnabledInBackground() { return true; }
bool GetEnabledInBackground() { return EnabledInBackground; }
void SetEnabledInBackground(bool enabled) { EnabledInBackground = enabled; }
void SetDefaultConfig(); void SetDefaultConfig();
FString GetIdentifier(); FString GetIdentifier();
@ -148,7 +142,6 @@ protected:
int LastButtons; int LastButtons;
bool Connected; bool Connected;
bool Enabled; bool Enabled;
bool EnabledInBackground;
void Attached(); void Attached();
void Detached(); void Detached();
@ -751,10 +744,7 @@ void FXInputManager::ProcessInput()
{ {
for (int i = 0; i < XUSER_MAX_COUNT; ++i) for (int i = 0; i < XUSER_MAX_COUNT; ++i)
{ {
if(AppActive || Devices[i]->GetEnabledInBackground()) Devices[i]->ProcessInput();
{
Devices[i]->ProcessInput();
}
} }
} }

View file

@ -201,8 +201,3 @@ bool FBasicStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata
{ {
return mainwindow.RunMessageLoop(timer_callback, userdata); return mainwindow.RunMessageLoop(timer_callback, userdata);
} }
void FBasicStartupScreen::NetClose()
{
mainwindow.CloseNetStartPane();
}

View file

@ -76,7 +76,7 @@ static void CheckOpenGL(void)
{ {
if (opengl32dll == 0) if (opengl32dll == 0)
{ {
opengl32dll = LoadLibraryA("OpenGL32.DLL"); opengl32dll = LoadLibrary(L"OpenGL32.DLL");
if (opengl32dll != 0) if (opengl32dll != 0)
{ {
createcontext = (HGLRC(WINAPI*)(HDC)) GetProcAddress(opengl32dll, "wglCreateContext"); createcontext = (HGLRC(WINAPI*)(HDC)) GetProcAddress(opengl32dll, "wglCreateContext");
@ -134,7 +134,7 @@ static PROC WinGetProcAddress(const char *name)
#if defined(__APPLE__) #if defined(__APPLE__)
#define IntGetProcAddress(name) AppleGLGetProcAddress(name) #define IntGetProcAddress(name) AppleGLGetProcAddress(name)
#else #else
#if defined(__sgi) || defined(__sun) || defined(__unix__) || defined(__HAIKU__) #if defined(__sgi) || defined(__sun) || defined(__unix__)
void* SDL_GL_GetProcAddress(const char* proc); void* SDL_GL_GetProcAddress(const char* proc);
#define IntGetProcAddress(name) SDL_GL_GetProcAddress((const char*)name) #define IntGetProcAddress(name) SDL_GL_GetProcAddress((const char*)name)
//#define IntGetProcAddress(name) PosixGetProcAddress((const GLubyte*)name) //#define IntGetProcAddress(name) PosixGetProcAddress((const GLubyte*)name)

View file

@ -54,6 +54,3 @@ EXTERN_CVAR(Int, gl_shadowmap_filter)
EXTERN_CVAR(Bool, gl_brightfog) EXTERN_CVAR(Bool, gl_brightfog)
EXTERN_CVAR(Bool, gl_lightadditivesurfaces) EXTERN_CVAR(Bool, gl_lightadditivesurfaces)
EXTERN_CVAR(Bool, gl_notexturefill) EXTERN_CVAR(Bool, gl_notexturefill)
EXTERN_CVAR(Bool, r_radarclipper)
EXTERN_CVAR(Bool, r_dithertransparency)

View file

@ -25,7 +25,7 @@ enum ERenderEffect
EFF_SPHEREMAP, EFF_SPHEREMAP,
EFF_BURN, EFF_BURN,
EFF_STENCIL, EFF_STENCIL,
EFF_DITHERTRANS,
MAX_EFFECTS MAX_EFFECTS
}; };

View file

@ -299,7 +299,6 @@ const FEffectShader effectshaders[] =
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
{ "dithertrans", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define NO_ALPHATEST\n#define DITHERTRANS\n" },
}; };
int DFrameBuffer::GetShaderCount() int DFrameBuffer::GetShaderCount()

View file

@ -146,27 +146,11 @@ float VREyeInfo::getShift() const
return vr_swap_eyes ? -res : res; return vr_swap_eyes ? -res : res;
} }
VSMatrix VREyeInfo::GetProjection(float fov, float aspectRatio, float fovRatio, bool iso_ortho) const VSMatrix VREyeInfo::GetProjection(float fov, float aspectRatio, float fovRatio) const
{ {
VSMatrix result; VSMatrix result;
if (iso_ortho) // Orthographic projection for isometric viewpoint if (mShiftFactor == 0)
{
double zNear = -3.0/fovRatio; // screen->GetZNear();
double zFar = screen->GetZFar();
double fH = tan(DEG2RAD(fov) / 2) / fovRatio;
double fW = fH * aspectRatio * mScaleFactor;
double left = -fW;
double right = fW;
double bottom = -fH;
double top = fH;
VSMatrix fmat(1);
fmat.ortho((float)left, (float)right, (float)bottom, (float)top, (float)zNear, (float)zFar);
return fmat;
}
else if (mShiftFactor == 0)
{ {
float fovy = (float)(2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio))); float fovy = (float)(2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio)));
result.perspective(fovy, aspectRatio, screen->GetZNear(), screen->GetZFar()); result.perspective(fovy, aspectRatio, screen->GetZNear(), screen->GetZFar());

View file

@ -27,7 +27,7 @@ struct VREyeInfo
float mShiftFactor; float mShiftFactor;
float mScaleFactor; float mScaleFactor;
VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio, bool iso_ortho) const; VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const;
DVector3 GetViewShift(float yaw) const; DVector3 GetViewShift(float yaw) const;
private: private:
float getShift() const; float getShift() const;

View file

@ -50,7 +50,6 @@
//=========================================================================== //===========================================================================
CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE) CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
CVAR(Bool, hw_2dmip, true, CVAR_ARCHIVE)
void Draw2D(F2DDrawer* drawer, FRenderState& state) void Draw2D(F2DDrawer* drawer, FRenderState& state)
{ {
@ -72,8 +71,6 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int
state.EnableMultisampling(false); state.EnableMultisampling(false);
state.EnableLineSmooth(gl_aalines); state.EnableLineSmooth(gl_aalines);
bool cache_hw_2dmip = hw_2dmip; // cache cvar lookup so it's not done in a loop
auto &vertices = drawer->mVertices; auto &vertices = drawer->mVertices;
auto &indices = drawer->mIndices; auto &indices = drawer->mIndices;
auto &commands = drawer->mData; auto &commands = drawer->mData;
@ -183,7 +180,7 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int
auto flags = cmd.mTexture->GetUseType() >= ETextureType::Special? UF_None : cmd.mTexture->GetUseType() == ETextureType::FontChar? UF_Font : UF_Texture; auto flags = cmd.mTexture->GetUseType() >= ETextureType::Special? UF_None : cmd.mTexture->GetUseType() == ETextureType::FontChar? UF_Font : UF_Texture;
auto scaleflags = cmd.mFlags & F2DDrawer::DTF_Indexed ? CTF_Indexed : 0; auto scaleflags = cmd.mFlags & F2DDrawer::DTF_Indexed ? CTF_Indexed : 0;
state.SetMaterial(cmd.mTexture, flags, scaleflags, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : (cache_hw_2dmip ? CLAMP_XY : CLAMP_XY_NOMIP), cmd.mTranslationId, -1); state.SetMaterial(cmd.mTexture, flags, scaleflags, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1);
state.EnableTexture(true); state.EnableTexture(true);
// Canvas textures are stored upside down // Canvas textures are stored upside down

View file

@ -947,7 +947,6 @@ PPCustomShaderInstance::PPCustomShaderInstance(PostProcessShader *desc) : Desc(d
case PostProcessUniformType::Int: AddUniformField(offset, name, UniformType::Int, sizeof(int)); break; case PostProcessUniformType::Int: AddUniformField(offset, name, UniformType::Int, sizeof(int)); break;
case PostProcessUniformType::Vec2: AddUniformField(offset, name, UniformType::Vec2, sizeof(float) * 2); break; case PostProcessUniformType::Vec2: AddUniformField(offset, name, UniformType::Vec2, sizeof(float) * 2); break;
case PostProcessUniformType::Vec3: AddUniformField(offset, name, UniformType::Vec3, sizeof(float) * 3, sizeof(float) * 4); break; case PostProcessUniformType::Vec3: AddUniformField(offset, name, UniformType::Vec3, sizeof(float) * 3, sizeof(float) * 4); break;
case PostProcessUniformType::Vec4: AddUniformField(offset, name, UniformType::Vec4, sizeof(float) * 4); break;
default: break; default: break;
} }
} }
@ -1086,13 +1085,6 @@ void PPCustomShaderInstance::SetUniforms(PPRenderState *renderstate)
fValues[2] = (float)pair->Value.Values[2]; fValues[2] = (float)pair->Value.Values[2];
memcpy(dst, fValues, sizeof(float) * 3); memcpy(dst, fValues, sizeof(float) * 3);
break; break;
case PostProcessUniformType::Vec4:
fValues[0] = (float)pair->Value.Values[0];
fValues[1] = (float)pair->Value.Values[1];
fValues[2] = (float)pair->Value.Values[2];
fValues[3] = (float)pair->Value.Values[3];
memcpy(dst, fValues, sizeof(float) * 4);
break;
default: default:
break; break;
} }

View file

@ -116,31 +116,6 @@ DEFINE_ACTION_FUNCTION(_PPShader, SetUniform3f)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(_PPShader, SetUniform4f)
{
PARAM_PROLOGUE;
PARAM_STRING(shaderName);
PARAM_STRING(uniformName);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_FLOAT(w);
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Name == shaderName)
{
double *vec4 = shader.Uniforms[uniformName].Values;
vec4[0] = x;
vec4[1] = y;
vec4[2] = z;
vec4[3] = w;
}
}
return 0;
}
DEFINE_ACTION_FUNCTION(_PPShader, SetUniform1i) DEFINE_ACTION_FUNCTION(_PPShader, SetUniform1i)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;

View file

@ -9,8 +9,7 @@ enum class PostProcessUniformType
Int, Int,
Float, Float,
Vec2, Vec2,
Vec3, Vec3
Vec4
}; };
struct PostProcessUniformValue struct PostProcessUniformValue

View file

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
** **
** Copyright(C) 2017 Magnus Norddahl ** Copyright(C) 2017 Magnus Norddahl
** Copyright(C) 2017-2024 Rachael Alexanderson ** Copyright(C) 2017-2020 Rachael Alexanderson
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without ** Redistribution and use in source and binary forms, with or without
@ -98,33 +98,6 @@ namespace
{ {
return (uint32_t)((float)inheight * v_MinimumToFill(inwidth, inheight)); return (uint32_t)((float)inheight * v_MinimumToFill(inwidth, inheight));
} }
float v_MinimumToFill2(uint32_t inwidth, uint32_t inheight)
{
// sx = screen x dimension, sy = same for y
float sx = (float)inwidth * 1.2f, sy = (float)inheight;
static float lastsx = 0., lastsy = 0., result = 0.;
if (lastsx != sx || lastsy != sy)
{
if (sx <= 0. || sy <= 0.)
return 1.; // prevent x/0 error
// set absolute minimum scale to fill the entire screen but get as close to 640x400 as possible
float ssx = (float)(VID_MIN_UI_WIDTH) / 1.2f / sx, ssy = (float)(VID_MIN_UI_HEIGHT) / sy;
result = (ssx < ssy) ? ssy : ssx;
lastsx = sx;
lastsy = sy;
}
return result;
}
inline uint32_t v_mfillX2(uint32_t inwidth, uint32_t inheight)
{
return (uint32_t)((float)inwidth * v_MinimumToFill2(inwidth, inheight) * 1.2);
}
inline uint32_t v_mfillY2(uint32_t inwidth, uint32_t inheight)
{
return (uint32_t)((float)inheight * v_MinimumToFill2(inwidth, inheight));
}
inline void refresh_minimums() inline void refresh_minimums()
{ {
// specialUI is tracking a state where high-res console fonts are actually required, and // specialUI is tracking a state where high-res console fonts are actually required, and
@ -155,17 +128,16 @@ namespace
// the odd formatting of this struct definition is meant to resemble a table header. set your tab stops to 4 when editing this file. // the odd formatting of this struct definition is meant to resemble a table header. set your tab stops to 4 when editing this file.
struct v_ScaleTable struct v_ScaleTable
{ bool isValid; uint32_t(*GetScaledWidth)(uint32_t Width, uint32_t Height); uint32_t(*GetScaledHeight)(uint32_t Width, uint32_t Height); float pixelAspect; bool isCustom; }; { bool isValid; uint32_t(*GetScaledWidth)(uint32_t Width, uint32_t Height); uint32_t(*GetScaledHeight)(uint32_t Width, uint32_t Height); float pixelAspect; bool isCustom; };
v_ScaleTable vScaleTable[] = v_ScaleTable vScaleTable[] =
{ {
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, 1.0f, false }, // 0 - Native { true, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, 1.0f, false }, // 0 - Native
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX(Width, Height); }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY(Width, Height); }, 1.0f, false }, // 1 - Minimum Scale to Fill Entire Screen { true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX(Width, Height); }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY(Width, Height); }, 1.0f, false }, // 6 - Minimum Scale to Fill Entire Screen
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 640; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 400; }, 1.2f, false }, // 2 - 640x400 (formerly 320x200) { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 640; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 400; }, 1.2f, false }, // 2 - 640x400 (formerly 320x200)
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 960; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 600; }, 1.2f, false }, // 3 - 960x600 (formerly 640x400) { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 960; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 600; }, 1.2f, false }, // 3 - 960x600 (formerly 640x400)
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 1280; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 800; }, 1.2f, false }, // 4 - 1280x800 { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 1280; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 800; }, 1.2f, false }, // 4 - 1280x800
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customwidth; }, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customheight; }, 1.0f, true }, // 5 - Custom { true, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customwidth; }, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customheight; }, 1.0f, true }, // 5 - Custom
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 320; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 200; }, 1.2f, false }, // 6 - 320x200 { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 320; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 200; }, 1.2f, false }, // 7 - 320x200
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX2(Width, Height) * 1.2f; }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY2(Width, Height); }, 1.2f, false }, // 7 - Minimum Scale to Fill Entire Screen (1.2)
}; };
bool isOutOfBounds(int x) bool isOutOfBounds(int x)
{ {
@ -276,7 +248,7 @@ CCMD (vid_scaletoheight)
} }
} }
inline bool atob(const char* I) inline bool atob(char* I)
{ {
if (stricmp (I, "true") == 0 || stricmp (I, "1") == 0) if (stricmp (I, "true") == 0 || stricmp (I, "1") == 0)
return true; return true;

View file

@ -1842,12 +1842,6 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
{ {
goto basereturn; goto basereturn;
} }
else if (ctx.Version >= MakeVersion(4, 15, 0) && basex->ValueType == TypeNullPtr && (ValueType == TypeSpriteID || ValueType == TypeTextureID || ValueType == TypeTranslationID))
{
delete basex;
basex = new FxConstant(0, ScriptPosition);
goto basereturn;
}
else if (IsFloat()) else if (IsFloat())
{ {
FxExpression *x = new FxFloatCast(basex); FxExpression *x = new FxFloatCast(basex);
@ -2834,104 +2828,83 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
// Special case: Assignment to a bitfield. // Special case: Assignment to a bitfield.
IsBitWrite = Base->GetBitValue(); IsBitWrite = Base->GetBitValue();
if (IsBitWrite >= 0x10000)
{
// internal flags - need more here
IsBitWrite &= 0xffff;
}
return this; return this;
} }
ExpEmit FxAssign::Emit(VMFunctionBuilder *build) ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
{ {
if (IsBitWrite < 64) static const uint8_t loadops[] = { OP_LK, OP_LKF, OP_LKS, OP_LKP };
assert(Base->ValueType->GetRegType() == Right->ValueType->GetRegType());
ExpEmit pointer = Base->Emit(build);
Address = pointer;
ExpEmit result;
bool intconst = false;
int intconstval = 0;
if (Right->isConstant() && Right->ValueType->GetRegType() == REGT_INT)
{ {
static const uint8_t loadops[] = { OP_LK, OP_LKF, OP_LKS, OP_LKP }; intconst = true;
assert(Base->ValueType->GetRegType() == Right->ValueType->GetRegType()); intconstval = static_cast<FxConstant*>(Right)->GetValue().GetInt();
result.Konst = true;
result.RegType = REGT_INT;
}
else
{
result = Right->Emit(build);
}
assert(result.RegType <= REGT_TYPE);
ExpEmit pointer = Base->Emit(build); if (pointer.Target)
Address = pointer; {
if (result.Konst)
ExpEmit result;
bool intconst = false;
int intconstval = 0;
if (Right->isConstant() && Right->ValueType->GetRegType() == REGT_INT)
{ {
intconst = true; if (intconst) build->EmitLoadInt(pointer.RegNum, intconstval);
intconstval = static_cast<FxConstant*>(Right)->GetValue().GetInt(); else build->Emit(loadops[result.RegType], pointer.RegNum, result.RegNum);
result.Konst = true;
result.RegType = REGT_INT;
} }
else else
{ {
result = Right->Emit(build); build->Emit(Right->ValueType->GetMoveOp(), pointer.RegNum, result.RegNum);
}
assert(result.RegType <= REGT_TYPE);
if (pointer.Target)
{
if (result.Konst)
{
if (intconst) build->EmitLoadInt(pointer.RegNum, intconstval);
else build->Emit(loadops[result.RegType], pointer.RegNum, result.RegNum);
}
else
{
build->Emit(Right->ValueType->GetMoveOp(), pointer.RegNum, result.RegNum);
}
}
else
{
if (result.Konst)
{
ExpEmit temp(build, result.RegType);
if (intconst) build->EmitLoadInt(temp.RegNum, intconstval);
else build->Emit(loadops[result.RegType], temp.RegNum, result.RegNum);
result.Free(build);
result = temp;
}
if (IsBitWrite == -1)
{
build->Emit(Base->ValueType->GetStoreOp(), pointer.RegNum, result.RegNum, build->GetConstantInt(0));
}
else
{
build->Emit(OP_SBIT, pointer.RegNum, result.RegNum, 1 << IsBitWrite);
}
}
if (AddressRequested)
{
result.Free(build);
return pointer;
}
pointer.Free(build);
if (intconst)
{ //fix int constant return for assignment
return Right->Emit(build);
}
else
{
return result;
} }
} }
else else
{ {
VMFunction* callfunc; if (result.Konst)
auto sym = FindBuiltinFunction(NAME_HandleDeprecatedFlags); {
ExpEmit temp(build, result.RegType);
if (intconst) build->EmitLoadInt(temp.RegNum, intconstval);
else build->Emit(loadops[result.RegType], temp.RegNum, result.RegNum);
result.Free(build);
result = temp;
}
assert(sym); if (IsBitWrite == -1)
callfunc = sym->Variants[0].Implementation; {
build->Emit(Base->ValueType->GetStoreOp(), pointer.RegNum, result.RegNum, build->GetConstantInt(0));
}
else
{
build->Emit(OP_SBIT, pointer.RegNum, result.RegNum, 1 << IsBitWrite);
}
FunctionCallEmitter emitters(callfunc); }
emitters.AddParameter(build, Base);
emitters.AddParameter(build, Right); if (AddressRequested)
emitters.AddParameterIntConst(IsBitWrite - 64); {
return emitters.EmitCall(build); result.Free(build);
return pointer;
}
pointer.Free(build);
if(intconst)
{ //fix int constant return for assignment
return Right->Emit(build);
}
else
{
return result;
} }
} }
@ -2961,40 +2934,23 @@ FxExpression *FxAssignSelf::Resolve(FCompileContext &ctx)
ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build) ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build)
{ {
if (Assignment->IsBitWrite < 64) ExpEmit pointer = Assignment->Address; // FxAssign should have already emitted it
if (!pointer.Target)
{ {
ExpEmit pointer = Assignment->Address; // FxAssign should have already emitted it ExpEmit out(build, ValueType->GetRegType(), ValueType->GetRegCount());
if (!pointer.Target) if (Assignment->IsBitWrite != -1)
{ {
ExpEmit out(build, ValueType->GetRegType(), ValueType->GetRegCount()); build->Emit(OP_LBIT, out.RegNum, pointer.RegNum, 1 << Assignment->IsBitWrite);
if (Assignment->IsBitWrite == -1)
{
build->Emit(ValueType->GetLoadOp(), out.RegNum, pointer.RegNum, build->GetConstantInt(0));
}
else
{
build->Emit(OP_LBIT, out.RegNum, pointer.RegNum, 1 << Assignment->IsBitWrite);
}
return out;
} }
else else
{ {
return pointer; build->Emit(ValueType->GetLoadOp(), out.RegNum, pointer.RegNum, build->GetConstantInt(0));
} }
return out;
} }
else else
{ {
VMFunction* callfunc; return pointer;
auto sym = FindBuiltinFunction(NAME_CheckDeprecatedFlags);
assert(sym);
callfunc = sym->Variants[0].Implementation;
FunctionCallEmitter emitters(callfunc);
emitters.AddParameter(build, Assignment->Base);
emitters.AddParameterIntConst(Assignment->IsBitWrite - 64);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
} }
} }
@ -7772,73 +7728,56 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
ExpEmit FxStructMember::Emit(VMFunctionBuilder *build) ExpEmit FxStructMember::Emit(VMFunctionBuilder *build)
{ {
if (membervar->BitValue < 64 || AddressRequested) ExpEmit obj = classx->Emit(build);
assert(obj.RegType == REGT_POINTER);
if (obj.Konst)
{ {
ExpEmit obj = classx->Emit(build); // If the situation where we are dereferencing a constant
assert(obj.RegType == REGT_POINTER); // pointer is common, then it would probably be worthwhile
// to add new opcodes for those. But as of right now, I
// don't expect it to be a particularly common case.
ExpEmit newobj(build, REGT_POINTER);
build->Emit(OP_LKP, newobj.RegNum, obj.RegNum);
obj = newobj;
}
if (obj.Konst) if (membervar->Flags & VARF_Meta)
{ {
// If the situation where we are dereferencing a constant obj.Free(build);
// pointer is common, then it would probably be worthwhile ExpEmit meta(build, REGT_POINTER);
// to add new opcodes for those. But as of right now, I build->Emit(OP_META, meta.RegNum, obj.RegNum);
// don't expect it to be a particularly common case. obj = meta;
ExpEmit newobj(build, REGT_POINTER); }
build->Emit(OP_LKP, newobj.RegNum, obj.RegNum);
obj = newobj;
}
if (membervar->Flags & VARF_Meta) if (AddressRequested)
{
if (membervar->Offset == 0)
{ {
obj.Free(build); return obj;
ExpEmit meta(build, REGT_POINTER);
build->Emit(OP_META, meta.RegNum, obj.RegNum);
obj = meta;
}
if (AddressRequested)
{
if (membervar->Offset == 0)
{
return obj;
}
obj.Free(build);
ExpEmit out(build, REGT_POINTER);
build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, build->GetConstantInt((int)membervar->Offset));
return out;
}
int offsetreg = build->GetConstantInt((int)membervar->Offset);
ExpEmit loc(build, membervar->Type->GetRegType(), membervar->Type->GetRegCount());
if (membervar->BitValue == -1)
{
build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, obj.RegNum, offsetreg);
}
else
{
ExpEmit out(build, REGT_POINTER);
build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, offsetreg);
build->Emit(OP_LBIT, loc.RegNum, out.RegNum, 1 << membervar->BitValue);
out.Free(build);
} }
obj.Free(build); obj.Free(build);
return loc; ExpEmit out(build, REGT_POINTER);
build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, build->GetConstantInt((int)membervar->Offset));
return out;
}
int offsetreg = build->GetConstantInt((int)membervar->Offset);
ExpEmit loc(build, membervar->Type->GetRegType(), membervar->Type->GetRegCount());
if (membervar->BitValue == -1)
{
build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, obj.RegNum, offsetreg);
} }
else else
{ {
VMFunction* callfunc; ExpEmit out(build, REGT_POINTER);
auto sym = FindBuiltinFunction(NAME_CheckDeprecatedFlags); build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, offsetreg);
build->Emit(OP_LBIT, loc.RegNum, out.RegNum, 1 << membervar->BitValue);
assert(sym); out.Free(build);
callfunc = sym->Variants[0].Implementation;
FunctionCallEmitter emitters(callfunc);
emitters.AddParameter(build, classx);
emitters.AddParameterIntConst(membervar->BitValue - 64);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
} }
obj.Free(build);
return loc;
} }
@ -8274,12 +8213,8 @@ static bool CheckFunctionCompatiblity(FScriptPosition &ScriptPosition, PFunction
FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &&args, const FScriptPosition &pos) FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &&args, const FScriptPosition &pos)
: FxExpression(EFX_FunctionCall, pos) : FxExpression(EFX_FunctionCall, pos)
{ {
const bool isClient = methodname == NAME_CRandom || methodname == NAME_CFRandom
|| methodname == NAME_CRandomPick || methodname == NAME_CFRandomPick
|| methodname == NAME_CRandom2 || methodname == NAME_CSetRandomSeed;
MethodName = methodname; MethodName = methodname;
RNG = isClient ? &M_Random : &pr_exrandom; RNG = &pr_exrandom;
ArgList = std::move(args); ArgList = std::move(args);
if (rngname != NAME_None) if (rngname != NAME_None)
{ {
@ -8291,16 +8226,7 @@ FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &&
case NAME_FRandomPick: case NAME_FRandomPick:
case NAME_Random2: case NAME_Random2:
case NAME_SetRandomSeed: case NAME_SetRandomSeed:
RNG = FRandom::StaticFindRNG(rngname.GetChars(), false); RNG = FRandom::StaticFindRNG(rngname.GetChars());
break;
case NAME_CRandom:
case NAME_CFRandom:
case NAME_CRandomPick:
case NAME_CFRandomPick:
case NAME_CRandom2:
case NAME_CSetRandomSeed:
RNG = FRandom::StaticFindRNG(rngname.GetChars(), true);
break; break;
default: default:
@ -8517,7 +8443,6 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
case NAME_State: case NAME_State:
case NAME_SpriteID: case NAME_SpriteID:
case NAME_TextureID: case NAME_TextureID:
case NAME_TranslationID:
if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition)) if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition))
{ {
PType *type = PType *type =
@ -8567,22 +8492,13 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
} }
break; break;
case NAME_CSetRandomSeed:
if (CheckArgSize(NAME_CRandom, ArgList, 1, 1, ScriptPosition))
{
func = new FxRandomSeed(RNG, ArgList[0], ScriptPosition, ctx.FromDecorate);
ArgList[0] = nullptr;
}
break;
case NAME_Random: case NAME_Random:
case NAME_CRandom:
// allow calling Random without arguments to default to (0, 255) // allow calling Random without arguments to default to (0, 255)
if (ArgList.Size() == 0) if (ArgList.Size() == 0)
{ {
func = new FxRandom(RNG, new FxConstant(0, ScriptPosition), new FxConstant(255, ScriptPosition), ScriptPosition, ctx.FromDecorate); func = new FxRandom(RNG, new FxConstant(0, ScriptPosition), new FxConstant(255, ScriptPosition), ScriptPosition, ctx.FromDecorate);
} }
else if (CheckArgSize(MethodName, ArgList, 2, 2, ScriptPosition)) else if (CheckArgSize(NAME_Random, ArgList, 2, 2, ScriptPosition))
{ {
func = new FxRandom(RNG, ArgList[0], ArgList[1], ScriptPosition, ctx.FromDecorate); func = new FxRandom(RNG, ArgList[0], ArgList[1], ScriptPosition, ctx.FromDecorate);
ArgList[0] = ArgList[1] = nullptr; ArgList[0] = ArgList[1] = nullptr;
@ -8590,8 +8506,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
break; break;
case NAME_FRandom: case NAME_FRandom:
case NAME_CFRandom: if (CheckArgSize(NAME_FRandom, ArgList, 2, 2, ScriptPosition))
if (CheckArgSize(MethodName, ArgList, 2, 2, ScriptPosition))
{ {
func = new FxFRandom(RNG, ArgList[0], ArgList[1], ScriptPosition); func = new FxFRandom(RNG, ArgList[0], ArgList[1], ScriptPosition);
ArgList[0] = ArgList[1] = nullptr; ArgList[0] = ArgList[1] = nullptr;
@ -8600,17 +8515,14 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
case NAME_RandomPick: case NAME_RandomPick:
case NAME_FRandomPick: case NAME_FRandomPick:
case NAME_CRandomPick:
case NAME_CFRandomPick:
if (CheckArgSize(MethodName, ArgList, 1, -1, ScriptPosition)) if (CheckArgSize(MethodName, ArgList, 1, -1, ScriptPosition))
{ {
func = new FxRandomPick(RNG, ArgList, MethodName == NAME_FRandomPick || MethodName == NAME_CFRandomPick, ScriptPosition, ctx.FromDecorate); func = new FxRandomPick(RNG, ArgList, MethodName == NAME_FRandomPick, ScriptPosition, ctx.FromDecorate);
} }
break; break;
case NAME_Random2: case NAME_Random2:
case NAME_CRandom2: if (CheckArgSize(NAME_Random2, ArgList, 0, 1, ScriptPosition))
if (CheckArgSize(MethodName, ArgList, 0, 1, ScriptPosition))
{ {
func = new FxRandom2(RNG, ArgList.Size() == 0? nullptr : ArgList[0], ScriptPosition, ctx.FromDecorate); func = new FxRandom2(RNG, ArgList.Size() == 0? nullptr : ArgList[0], ScriptPosition, ctx.FromDecorate);
if (ArgList.Size() > 0) ArgList[0] = nullptr; if (ArgList.Size() > 0) ArgList[0] = nullptr;
@ -8883,24 +8795,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
return Self; return Self;
} }
} }
else if (ctx.Version >= MakeVersion(4, 15, 0) && Self->ValueType == TypeSound && MethodName == NAME_IsValid) else if (Self->ValueType == TypeTextureID)
{
if (ArgList.Size() > 0)
{
ScriptPosition.Message(MSG_ERROR, "Too many parameters in call to %s", MethodName.GetChars());
delete this;
return nullptr;
}
Self->ValueType = TypeSInt32; // treat as integer
FxExpression *x = new FxCompareRel('>', Self, new FxConstant(0, ScriptPosition));
Self = nullptr;
SAFE_RESOLVE(x, ctx);
delete this;
return x;
}
else if (Self->ValueType == TypeTextureID || (ctx.Version >= MakeVersion(4, 15, 0) && (Self->ValueType == TypeTranslationID)))
{ {
if (MethodName == NAME_IsValid || MethodName == NAME_IsNull || MethodName == NAME_Exists || MethodName == NAME_SetInvalid || MethodName == NAME_SetNull) if (MethodName == NAME_IsValid || MethodName == NAME_IsNull || MethodName == NAME_Exists || MethodName == NAME_SetInvalid || MethodName == NAME_SetNull)
{ {
@ -8943,67 +8838,6 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
} }
} }
else if (ctx.Version >= MakeVersion(4, 15, 0) && Self->ValueType == TypeSpriteID)
{
if (MethodName == NAME_IsValid || MethodName == NAME_IsEmpty || MethodName == NAME_IsFixed || MethodName == NAME_IsKeep
|| MethodName == NAME_Exists
|| MethodName == NAME_SetInvalid || MethodName == NAME_SetEmpty || MethodName == NAME_SetFixed || MethodName == NAME_SetKeep)
{
if (ArgList.Size() > 0)
{
ScriptPosition.Message(MSG_ERROR, "Too many parameters in call to %s", MethodName.GetChars());
delete this;
return nullptr;
}
// No need to create a dedicated node here, all builtins map directly to trivial operations.
Self->ValueType = TypeSInt32; // all builtins treat the texture index as integer.
FxExpression *x = nullptr;
switch (MethodName.GetIndex())
{
case NAME_IsValid:
x = new FxCompareRel(TK_Geq, Self, new FxConstant(0, ScriptPosition));
break;
case NAME_IsEmpty: // TNT1
x = new FxCompareEq(TK_Eq, Self, new FxConstant(0, ScriptPosition));
break;
case NAME_IsFixed: // "----"
x = new FxCompareEq(TK_Eq, Self, new FxConstant(1, ScriptPosition));
break;
case NAME_IsKeep: // "####"
x = new FxCompareEq(TK_Eq, Self, new FxConstant(2, ScriptPosition));
break;
case NAME_Exists:
x = new FxCompareRel(TK_Geq, Self, new FxConstant(3, ScriptPosition));
break;
case NAME_SetInvalid:
x = new FxAssign(Self, new FxConstant(-1, ScriptPosition));
break;
case NAME_SetEmpty: // TNT1
x = new FxAssign(Self, new FxConstant(0, ScriptPosition));
break;
case NAME_SetFixed: // "----"
x = new FxAssign(Self, new FxConstant(1, ScriptPosition));
break;
case NAME_SetKeep: // "####"
x = new FxAssign(Self, new FxConstant(2, ScriptPosition));
break;
}
Self = nullptr;
SAFE_RESOLVE(x, ctx);
if (MethodName == NAME_SetInvalid || MethodName == NAME_SetEmpty || MethodName == NAME_SetFixed || MethodName == NAME_SetKeep) x->ValueType = TypeVoid; // override the default type of the assignment operator.
delete this;
return x;
}
}
else if (Self->IsVector()) else if (Self->IsVector())
{ {
// handle builtins: Vectors got 5. // handle builtins: Vectors got 5.
@ -9078,7 +8912,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
} }
else else
{ {
if (PFunction **Override; (Override = static_cast<PDynArray*>(Self->ValueType)->FnOverrides.CheckKey(MethodName))) if (PFunction **Override; ctx.Version >= MakeVersion(4, 11, 0) && (Override = static_cast<PDynArray*>(Self->ValueType)->FnOverrides.CheckKey(MethodName)))
{ {
afd_override = *Override; afd_override = *Override;
} }
@ -9710,9 +9544,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
if(FnPtrCall) static_cast<VMScriptFunction*>(ctx.Function->Variants[0].Implementation)->blockJit = true; if(FnPtrCall) static_cast<VMScriptFunction*>(ctx.Function->Variants[0].Implementation)->blockJit = true;
unsigned implicit = Function->GetImplicitArgs(); int implicit = Function->GetImplicitArgs();
bool relaxed_named_arugments = (ctx.Version >= MakeVersion(4, 13));
if (!CheckAccessibility(ctx.Version)) if (!CheckAccessibility(ctx.Version))
{ {
@ -9744,128 +9576,21 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
CallingFunction = ctx.Function; CallingFunction = ctx.Function;
if (ArgList.Size() > 0) if (ArgList.Size() > 0)
{ {
if ((argtypes.Size() == 0) || (argtypes.Last() != nullptr && ArgList.Size() + implicit > argtypes.Size())) if (argtypes.Size() == 0)
{ {
ScriptPosition.Message(MSG_ERROR, "Too many arguments in call to %s", Function->SymbolName.GetChars()); ScriptPosition.Message(MSG_ERROR, "Too many arguments in call to %s", Function->SymbolName.GetChars());
delete this; delete this;
return nullptr; return nullptr;
} }
bool isvararg = (argtypes.Last() == nullptr);
{
TDeletingArray<FxExpression*> OrderedArgs;
const unsigned count = (argtypes.Size() - implicit) - isvararg;
OrderedArgs.Resize(count);
memset(OrderedArgs.Data(), 0, sizeof(FxExpression*) * count);
unsigned index = 0;
unsigned n = ArgList.Size();
for(unsigned i = 0; i < n; i++)
{
if(ArgList[i]->ExprType == EFX_NamedNode)
{
if(FnPtrCall)
{
ScriptPosition.Message(MSG_ERROR, "Named arguments not supported in function pointer calls");
delete this;
return nullptr;
}
else if((index >= count) && isvararg)
{
ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument in the varargs part of the parameter list.");
delete this;
return nullptr;
}
else
{
FName name = static_cast<FxNamedNode *>(ArgList[i])->name;
if(argnames[index + implicit] != name)
{
unsigned j;
for (j = 0; j < count; j++)
{
if (argnames[j + implicit] == name)
{
if(!relaxed_named_arugments && !(argflags[j + implicit] & VARF_Optional))
{
ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument here - not all required arguments have been passed.");
}
else if(!relaxed_named_arugments && j < index)
{
ScriptPosition.Message(MSG_ERROR, "Named argument %s comes before current position in argument list.", name.GetChars());
}
// i don't think this needs any further optimization?
// O(N^2) complexity technically but N isn't likely to be large,
// and the check itself is just an int comparison, so it should be fine
index = j;
break;
}
}
if(j == count)
{
ScriptPosition.Message(MSG_ERROR, "Named argument %s not found.", name.GetChars());
delete this;
return nullptr;
}
}
else if(!relaxed_named_arugments && !(argflags[index + implicit] & VARF_Optional))
{
ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument here - not all required arguments have been passed.");
}
}
}
if(index >= count)
{
if(isvararg)
{
OrderedArgs.Push(ArgList[i]);
ArgList[i] = nullptr;
index++;
}
else
{
ScriptPosition.Message(MSG_ERROR, "Too many arguments in call to %s", Function->SymbolName.GetChars());
delete this;
return nullptr;
}
}
else
{
if(ArgList[i]->ExprType == EFX_NamedNode)
{
auto * node = static_cast<FxNamedNode *>(ArgList[i]);
OrderedArgs[index] = node->value;
node->value = nullptr;
}
else
{
OrderedArgs[index] = ArgList[i];
}
ArgList[i] = nullptr;
index++;
}
}
ArgList = std::move(OrderedArgs);
}
bool foundvarargs = false; bool foundvarargs = false;
PType * type = nullptr; PType * type = nullptr;
int flag = 0; int flag = 0;
if (argtypes.Size() > 0 && argtypes.Last() != nullptr && ArgList.Size() + implicit > argtypes.Size())
int defaults_index = 0;
for(unsigned i = 0; i < implicit; i++)
{ {
defaults_index += argtypes[i]->GetRegCount(); ScriptPosition.Message(MSG_ERROR, "Too many arguments in call to %s", Function->SymbolName.GetChars());
delete this;
return nullptr;
} }
for (unsigned i = 0; i < ArgList.Size(); i++) for (unsigned i = 0; i < ArgList.Size(); i++)
@ -9883,45 +9608,94 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
} }
assert(type != nullptr); assert(type != nullptr);
if(!foundvarargs) if (ArgList[i]->ExprType == EFX_NamedNode)
{ {
if(ArgList[i] == nullptr) if(FnPtrCall)
{ {
if(!(flag & VARF_Optional)) ScriptPosition.Message(MSG_ERROR, "Named arguments not supported in function pointer calls");
delete this;
return nullptr;
}
if (!(flag & VARF_Optional))
{
ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument here - not all required arguments have been passed.");
delete this;
return nullptr;
}
if (foundvarargs)
{
ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument in the varargs part of the parameter list.");
delete this;
return nullptr;
}
unsigned j;
bool done = false;
FName name = static_cast<FxNamedNode *>(ArgList[i])->name;
for (j = 0; j < argnames.Size() - implicit; j++)
{
if (argnames[j + implicit] == name)
{ {
ScriptPosition.Message(MSG_ERROR, "Required argument %s has not been passed in call to %s", argnames[i + implicit].GetChars(), Function->SymbolName.GetChars()); if (j < i)
delete this;
return nullptr;
}
auto ntype = argtypes[i + implicit];
// If this is a reference argument, the pointer type must be undone because the code below expects the pointed type as value type.
if (argflags[i + implicit] & VARF_Ref)
{
assert(ntype->isPointer());
ntype = TypeNullPtr; // the default of a reference type can only be a null pointer
}
if (ntype->GetRegCount() == 1)
{
ArgList[i] = new FxConstant(ntype, (*defaults)[defaults_index], ScriptPosition);
}
else
{
// Vectors need special treatment because they are not normal constants
FxConstant *cs[4] = { nullptr };
for (int l = 0; l < ntype->GetRegCount(); l++)
{ {
cs[l] = new FxConstant(TypeFloat64, (*defaults)[l + defaults_index], ScriptPosition); ScriptPosition.Message(MSG_ERROR, "Named argument %s comes before current position in argument list.", name.GetChars());
delete this;
return nullptr;
} }
ArgList[i] = new FxVectorValue(cs[0], cs[1], cs[2], cs[3], ScriptPosition); // copy the original argument into the list
auto old = static_cast<FxNamedNode *>(ArgList[i]);
ArgList[i] = old->value;
old->value = nullptr;
delete old;
// now fill the gap with constants created from the default list so that we got a full list of arguments.
int insert = j - i;
int skipdefs = 0;
// Defaults contain multiple entries for pointers so we need to calculate how much additional defaults we need to skip
for (unsigned k = 0; k < i + implicit; k++)
{
skipdefs += argtypes[k]->GetRegCount() - 1;
}
for (int k = 0; k < insert; k++)
{
auto ntype = argtypes[i + k + implicit];
// If this is a reference argument, the pointer type must be undone because the code below expects the pointed type as value type.
if (argflags[i + k + implicit] & VARF_Ref)
{
assert(ntype->isPointer());
ntype = TypeNullPtr; // the default of a reference type can only be a null pointer
}
if (ntype->GetRegCount() == 1)
{
auto x = new FxConstant(ntype, (*defaults)[i + k + skipdefs + implicit], ScriptPosition);
ArgList.Insert(i + k, x);
}
else
{
// Vectors need special treatment because they are not normal constants
FxConstant *cs[4] = { nullptr };
for (int l = 0; l < ntype->GetRegCount(); l++)
{
cs[l] = new FxConstant(TypeFloat64, (*defaults)[l + i + k + skipdefs + implicit], ScriptPosition);
}
FxExpression *x = new FxVectorValue(cs[0], cs[1], cs[2], cs[3], ScriptPosition);
ArgList.Insert(i + k, x);
skipdefs += ntype->GetRegCount() - 1;
}
}
done = true;
break;
} }
} }
if (!done)
defaults_index += argtypes[i + implicit]->GetRegCount(); {
ScriptPosition.Message(MSG_ERROR, "Named argument %s not found.", name.GetChars());
delete this;
return nullptr;
}
// re-get the proper info for the inserted node.
type = argtypes[i + implicit];
flag = argflags[i + implicit];
} }
assert(ArgList[i]);
FxExpression *x = nullptr; FxExpression *x = nullptr;
if (foundvarargs && (Function->Variants[0].Flags & VARF_VarArg)) if (foundvarargs && (Function->Variants[0].Flags & VARF_VarArg))
{ {
@ -12751,15 +12525,6 @@ FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx)
if (ValueType->RegType == REGT_NIL && ValueType != TypeAuto) if (ValueType->RegType == REGT_NIL && ValueType != TypeAuto)
{ {
auto sfunc = static_cast<VMScriptFunction *>(ctx.Function->Variants[0].Implementation); auto sfunc = static_cast<VMScriptFunction *>(ctx.Function->Variants[0].Implementation);
const unsigned MAX_STACK_ALLOC = 512 * 1024; // Windows stack is 1 MB, but we cannot go up there without problems
if (uint64_t(ValueType->Size) + uint64_t(sfunc->ExtraSpace) > MAX_STACK_ALLOC)
{
ScriptPosition.Message(MSG_ERROR, "%s exceeds max. allowed size of 512kb for local variables at variable %s", sfunc->Name.GetChars(), Name.GetChars());
delete this;
return nullptr;
}
StackOffset = sfunc->AllocExtraStack(ValueType); StackOffset = sfunc->AllocExtraStack(ValueType);
if (Init != nullptr) if (Init != nullptr)

View file

@ -40,7 +40,6 @@
#include "filesystem.h" #include "filesystem.h"
CVAR(Bool, strictdecorate, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) CVAR(Bool, strictdecorate, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
CVAR(Bool, warningstoerrors, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
EXTERN_CVAR(Bool, vm_jit) EXTERN_CVAR(Bool, vm_jit)
EXTERN_CVAR(Bool, vm_jit_aot) EXTERN_CVAR(Bool, vm_jit_aot)
@ -880,18 +879,10 @@ void FFunctionBuildList::Build()
{ {
if (!item.Code->CheckReturn()) if (!item.Code->CheckReturn())
{ {
if (ctx.ReturnProto == nullptr || !ctx.ReturnProto->ReturnTypes.Size()) auto newcmpd = new FxCompoundStatement(item.Code->ScriptPosition);
{ newcmpd->Add(item.Code);
auto newcmpd = new FxCompoundStatement(item.Code->ScriptPosition); newcmpd->Add(new FxReturnStatement(nullptr, item.Code->ScriptPosition));
newcmpd->Add(item.Code); item.Code = newcmpd->Resolve(ctx);
newcmpd->Add(new FxReturnStatement(nullptr, item.Code->ScriptPosition));
item.Code = newcmpd->Resolve(ctx);
}
else
{
item.Code->ScriptPosition.Message(MSG_ERROR, "Missing return statement in %s", item.PrintableName.GetChars());
continue;
}
} }
item.Proto = ctx.ReturnProto; item.Proto = ctx.ReturnProto;

View file

@ -330,8 +330,7 @@ void PType::StaticInit()
TypeVoidPtr = NewPointer(TypeVoid, false); TypeVoidPtr = NewPointer(TypeVoid, false);
TypeRawFunction = new PPointer; TypeRawFunction = new PPointer;
TypeRawFunction->mDescriptiveName = "Raw Function Pointer"; TypeRawFunction->mDescriptiveName = "Raw Function Pointer";
TypeTable.AddType(TypeRawFunction, NAME_None);
TypeVMFunction = NewPointer(NewStruct("VMFunction", nullptr, true)); TypeVMFunction = NewPointer(NewStruct("VMFunction", nullptr, true));
TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value. TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value.
TypeStringStruct = NewStruct("Stringstruct", nullptr, true); TypeStringStruct = NewStruct("Stringstruct", nullptr, true);

View file

@ -2286,11 +2286,6 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
Error(arraysize, "Array size must be positive"); Error(arraysize, "Array size must be positive");
return TypeError; return TypeError;
} }
if (uint64_t(size) * baseType->Size > 0x7fffffff)
{
Error(arraysize, "Array size overflow. Total size must be less than 2GB");
return TypeError;
}
baseType = NewArray(baseType, size); baseType = NewArray(baseType, size);
} }

View file

@ -282,9 +282,9 @@ DEFINE_ACTION_FUNCTION(FStringStruct, DeleteLastCharacter)
static void LocalizeString(const FString &label, bool prefixed, FString *result) static void LocalizeString(const FString &label, bool prefixed, FString *result)
{ {
if (!prefixed) *result = GStrings.GetString(label); if (!prefixed) *result = GStrings(label);
else if (label[0] != '$') *result = label; else if (label[0] != '$') *result = label;
else *result = GStrings.GetString(&label[1]); else *result = GStrings(&label[1]);
} }
DEFINE_ACTION_FUNCTION_NATIVE(FStringTable, Localize, LocalizeString) DEFINE_ACTION_FUNCTION_NATIVE(FStringTable, Localize, LocalizeString)

View file

@ -670,7 +670,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetBottomAlignOffset, GetBottomAlignOffset)
static int StringWidth(FFont *font, const FString &str, int localize) static int StringWidth(FFont *font, const FString &str, int localize)
{ {
const char *txt = (localize && str[0] == '$') ? GStrings.GetString(&str[1]) : str.GetChars(); const char *txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars();
return font->StringWidth(txt); return font->StringWidth(txt);
} }
@ -684,7 +684,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, StringWidth, StringWidth)
static int GetMaxAscender(FFont* font, const FString& str, int localize) static int GetMaxAscender(FFont* font, const FString& str, int localize)
{ {
const char* txt = (localize && str[0] == '$') ? GStrings.GetString(&str[1]) : str.GetChars(); const char* txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars();
return font->GetMaxAscender(txt); return font->GetMaxAscender(txt);
} }
@ -698,7 +698,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetMaxAscender, GetMaxAscender)
static int CanPrint(FFont *font, const FString &str, int localize) static int CanPrint(FFont *font, const FString &str, int localize)
{ {
const char *txt = (localize && str[0] == '$') ? GStrings.GetString(&str[1]) : str.GetChars(); const char *txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars();
return font->CanPrint(txt); return font->CanPrint(txt);
} }
@ -770,26 +770,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetDisplayTopOffset, GetDisplayTopOffset)
ACTION_RETURN_FLOAT(GetDisplayTopOffset(self, code)); ACTION_RETURN_FLOAT(GetDisplayTopOffset(self, code));
} }
static int GetChar(FFont* font, int c)
{
int texc = 0;
auto getch = font->GetChar(c, CR_UNDEFINED, nullptr);
if (getch)
texc = getch->GetID().GetIndex();
return texc;
}
DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetChar, ::GetChar)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_INT(mchar);
if (numret > 0) ret[0].SetInt(::GetChar(self, mchar));
if (numret > 1) ret[1].SetInt(self->GetCharWidth(mchar));
return min(2, numret);
}
//========================================================================== //==========================================================================
// //
// file system // file system
@ -1162,17 +1142,6 @@ DEFINE_ACTION_FUNCTION(_Console, PrintfEx)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(_Console, DebugPrintf)
{
PARAM_PROLOGUE;
PARAM_INT(debugLevel);
PARAM_VA_POINTER(va_reginfo);
FString s = FStringFormat(VM_ARGS_NAMES, 1);
DPrintf(debugLevel, "%s\n", s.GetChars());
return 0;
}
static void StopAllSounds() static void StopAllSounds()
{ {
soundEngine->StopAllChannels(); soundEngine->StopAllChannels();
@ -1706,7 +1675,7 @@ DEFINE_ACTION_FUNCTION(DScriptScanner, ScriptError)
{ {
PARAM_SELF_PROLOGUE(DScriptScanner); PARAM_SELF_PROLOGUE(DScriptScanner);
FString s = FStringFormat(VM_ARGS_NAMES, 1); FString s = FStringFormat(VM_ARGS_NAMES);
self->wrapped.ScriptError("%s", s.GetChars()); self->wrapped.ScriptError("%s", s.GetChars());
return 0; return 0;
} }
@ -1715,7 +1684,7 @@ DEFINE_ACTION_FUNCTION(DScriptScanner, ScriptMessage)
{ {
PARAM_SELF_PROLOGUE(DScriptScanner); PARAM_SELF_PROLOGUE(DScriptScanner);
FString s = FStringFormat(VM_ARGS_NAMES, 1); FString s = FStringFormat(VM_ARGS_NAMES);
self->wrapped.ScriptMessage("%s", s.GetChars()); self->wrapped.ScriptMessage("%s", s.GetChars());
return 0; return 0;
} }

View file

@ -111,7 +111,7 @@ FEndoomScreen::FEndoomScreen(int loading_lump)
StartupBitmap.Create(80 * 8, 26 * 16); // line 26 is for our own 'press any key to quit' message. StartupBitmap.Create(80 * 8, 26 * 16); // line 26 is for our own 'press any key to quit' message.
DrawTextScreen(StartupBitmap, endoom_screen); DrawTextScreen(StartupBitmap, endoom_screen);
ClearBlock(StartupBitmap, {0, 0, 0, 255}, 0, 25*16, 640, 16); ClearBlock(StartupBitmap, {0, 0, 0, 255}, 0, 25*16, 640, 16);
DrawString(StartupBitmap, 0, 25, GStrings.GetString("TXT_QUITENDOOM"), { 128, 128, 128 ,255}, { 0, 0, 0, 255}); DrawString(StartupBitmap, 0, 25, GStrings("TXT_QUITENDOOM"), { 128, 128, 128 ,255}, { 0, 0, 0, 255});
lastUpdateTime = I_msTime(); lastUpdateTime = I_msTime();
// Does this screen need blinking? // Does this screen need blinking?

View file

@ -372,13 +372,6 @@ FStartScreen* GetGameStartScreen(int max_progress)
return nullptr; return nullptr;
} }
FStartScreen::~FStartScreen()
{
if (StartupTexture) delete StartupTexture;
if (HeaderTexture) delete HeaderTexture;
if (NetTexture) delete NetTexture;
}
//========================================================================== //==========================================================================
// //
// ST_Util_ClearBlock // ST_Util_ClearBlock
@ -614,7 +607,7 @@ bool FStartScreen::NetInit(const char* message, int numplayers)
{ {
NetMaxPos = numplayers; NetMaxPos = numplayers;
NetCurPos = 0; NetCurPos = 0;
NetMessageString.Format("%s %s", message, GStrings.GetString("TXT_NET_PRESSESC")); NetMessageString.Format("%s %s", message, GStrings("TXT_NET_PRESSESC"));
NetProgress(1); // You always know about yourself NetProgress(1); // You always know about yourself
return true; return true;
} }
@ -699,8 +692,8 @@ void FStartScreen::Render(bool force)
twod->OnFrameDone(); twod->OnFrameDone();
} }
auto newtime = I_msTime(); auto newtime = I_msTime();
if ((newtime - nowtime) * 2 > minwaittime) // slow down drawing the start screen if we're on a slow GPU! if ((newtime - nowtime) * 2.0 > minwaittime) // slow down drawing the start screen if we're on a slow GPU!
minwaittime = (newtime - nowtime) * 2; minwaittime = (newtime - nowtime) * 2.0;
} }
FImageSource* CreateStartScreenTexture(FBitmap& srcdata); FImageSource* CreateStartScreenTexture(FBitmap& srcdata);

View file

@ -70,7 +70,7 @@ protected:
FGameTexture* NetTexture = nullptr; FGameTexture* NetTexture = nullptr;
public: public:
FStartScreen(int maxp) { MaxPos = maxp; } FStartScreen(int maxp) { MaxPos = maxp; }
virtual ~FStartScreen(); virtual ~FStartScreen() = default;
void Render(bool force = false); void Render(bool force = false);
bool Progress(int); bool Progress(int);
void NetProgress(int count); void NetProgress(int count);

Some files were not shown because too many files have changed in this diff Show more