mirror of
https://github.com/ZDoom/Raze.git
synced 2025-04-23 00:11:03 +00:00
Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
9a068cf7c9 |
186 changed files with 3055 additions and 4547 deletions
24
.github/workflows/continuous_integration.yml
vendored
24
.github/workflows/continuous_integration.yml
vendored
|
@ -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 }}
|
||||||
|
|
|
@ -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" )
|
||||||
|
|
BIN
bin/windows/zmusic/arm64/zmusiclite.dll
Normal file
BIN
bin/windows/zmusic/arm64/zmusiclite.dll
Normal file
Binary file not shown.
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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]));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -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]; }
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -531,8 +531,3 @@ void FConsoleWindow::NetDone()
|
||||||
m_netAbortButton = nil;
|
m_netAbortButton = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FConsoleWindow::NetClose()
|
|
||||||
{
|
|
||||||
// TODO: Implement this
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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) { }
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ enum ERenderEffect
|
||||||
EFF_SPHEREMAP,
|
EFF_SPHEREMAP,
|
||||||
EFF_BURN,
|
EFF_BURN,
|
||||||
EFF_STENCIL,
|
EFF_STENCIL,
|
||||||
EFF_DITHERTRANS,
|
|
||||||
MAX_EFFECTS
|
MAX_EFFECTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -9,8 +9,7 @@ enum class PostProcessUniformType
|
||||||
Int,
|
Int,
|
||||||
Float,
|
Float,
|
||||||
Vec2,
|
Vec2,
|
||||||
Vec3,
|
Vec3
|
||||||
Vec4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PostProcessUniformValue
|
struct PostProcessUniformValue
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue