mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-13 05:41:10 +00:00
Merge remote-tracking branch 'origin/master' into polybackend
This commit is contained in:
commit
bb47230f79
126 changed files with 2186 additions and 1293 deletions
|
@ -6,37 +6,23 @@ branches:
|
|||
|
||||
clone_depth: 10
|
||||
|
||||
image:
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2015
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- GENERATOR: "Visual Studio 14 2015"
|
||||
CONFIGURATION: Release
|
||||
TOOLSET: v140_xp
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
|
||||
- GENERATOR: "Visual Studio 14 2015 Win64"
|
||||
CONFIGURATION: Release
|
||||
TOOLSET: v140
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
|
||||
- GENERATOR: "Visual Studio 15 2017"
|
||||
CONFIGURATION: Release
|
||||
TOOLSET: v141_xp
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
|
||||
- GENERATOR: "Visual Studio 15 2017 Win64"
|
||||
CONFIGURATION: Release
|
||||
TOOLSET: v141
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
|
||||
- GENERATOR: "Visual Studio 15 2017 Win64"
|
||||
CONFIGURATION: Debug
|
||||
TOOLSET: v141
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
|
||||
- ARCH: x64
|
||||
- ARCH: Win32
|
||||
|
||||
build_script:
|
||||
- md build
|
||||
- cd build
|
||||
- cmake -G "%GENERATOR%" -T "%TOOLSET%" -DPK3_QUIET_ZIPDIR=YES ..
|
||||
- cmake --build . --config "%CONFIGURATION%" -- -maxcpucount -verbosity:minimal
|
||||
- cmake -A %ARCH% -DPK3_QUIET_ZIPDIR=YES ..
|
||||
- cmake --build . --config Release -- -maxcpucount -verbosity:minimal
|
||||
|
||||
after_build:
|
||||
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\
|
||||
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\Release\
|
||||
- 7z a ..\gzdoom.zip "%OUTPUT_DIR%gzdoom.exe" "%OUTPUT_DIR%*.pk3"
|
||||
|
||||
artifacts:
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,3 +24,4 @@
|
|||
/build_vc2017-32
|
||||
/build2
|
||||
/build_vc2019-64
|
||||
/build_vc2019-32
|
||||
|
|
|
@ -240,6 +240,20 @@ else()
|
|||
set( ALL_C_FLAGS "-ffp-contract=off" )
|
||||
endif()
|
||||
|
||||
if ( UNIX )
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists( "fts_set" "fts.h" HAVE_FTS )
|
||||
if ( NOT HAVE_FTS )
|
||||
include ( FindPkgConfig )
|
||||
pkg_check_modules( MUSL_FTS musl-fts )
|
||||
if ( MUSL_FTS_FOUND )
|
||||
set ( ALL_C_FLAGS "${ALL_C_FLAGS} ${MUSL_FTS_LDFLAGS}" )
|
||||
else ( MUSL_FTS_FOUND )
|
||||
message (ERROR "fts_* functions not found in the system" )
|
||||
endif ( MUSL_FTS_FOUND )
|
||||
endif ( NOT HAVE_FTS )
|
||||
endif ( UNIX )
|
||||
|
||||
set( REL_C_FLAGS "" )
|
||||
set( DEB_C_FLAGS "" )
|
||||
|
||||
|
@ -310,6 +324,19 @@ else()
|
|||
set( ZLIB_LIBRARY z )
|
||||
endif()
|
||||
|
||||
if( HAVE_VM_JIT AND UNIX )
|
||||
check_symbol_exists( "backtrace" "execinfo.h" HAVE_BACKTRACE )
|
||||
if( NOT HAVE_BACKTRACE )
|
||||
set( CMAKE_REQUIRED_FLAGS "-lexecinfo" )
|
||||
check_symbol_exists( "backtrace" "execinfo.h" HAVE_LIBEXECINFO )
|
||||
if( HAVE_LIBEXECINFO )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -lexecinfo" )
|
||||
else( HAVE_LIBEXECINFO )
|
||||
set( HAVE_VM_JIT NO )
|
||||
endif( HAVE_LIBEXECINFO )
|
||||
endif( NOT HAVE_BACKTRACE )
|
||||
endif( HAVE_VM_JIT AND UNIX )
|
||||
|
||||
if( ${HAVE_VM_JIT} )
|
||||
if( ASMJIT_FOUND AND NOT FORCE_INTERNAL_ASMJIT )
|
||||
message( STATUS "Using system asmjit, includes found at ${ASMJIT_INCLUDE_DIR}" )
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
Some software in this archive may be from the book _Methods and
|
||||
Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
International, 1989) or from the Cephes Mathematical Library, a
|
||||
commercial product. In either event, it is copyrighted by the author.
|
||||
What you see here may be used freely but it comes with no support or
|
||||
guarantee.
|
||||
|
||||
Stephen L. Moshier
|
||||
moshier@na-net.ornl.gov
|
||||
|
|
@ -1291,6 +1291,7 @@ set (PCH_SOURCES
|
|||
utility/nodebuilder/nodebuild_utility.cpp
|
||||
utility/sc_man.cpp
|
||||
utility/stats.cpp
|
||||
utility/atterm.cpp
|
||||
utility/cmdlib.cpp
|
||||
utility/colormatcher.cpp
|
||||
utility/configfile.cpp
|
||||
|
@ -1451,10 +1452,9 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
# Need to enable intrinsics for these files.
|
||||
if( SSE_MATTERS )
|
||||
set_source_files_properties(
|
||||
gl/system/gl_swframebuffer.cpp
|
||||
polyrenderer/poly_all.cpp
|
||||
swrenderer/r_all.cpp
|
||||
x86.cpp
|
||||
rendering/polyrenderer/poly_all.cpp
|
||||
rendering/swrenderer/r_all.cpp
|
||||
utility/x86.cpp
|
||||
PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" )
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -74,7 +74,7 @@ extern bool insave;
|
|||
|
||||
CVAR (Bool, sv_cheats, false, CVAR_SERVERINFO | CVAR_LATCH)
|
||||
CVAR (Bool, sv_unlimited_pickup, false, CVAR_SERVERINFO)
|
||||
CVAR (Bool, cl_blockcheats, false, 0)
|
||||
CVAR (Int, cl_blockcheats, 0, 0)
|
||||
|
||||
CCMD (toggleconsole)
|
||||
{
|
||||
|
@ -88,9 +88,9 @@ bool CheckCheatmode (bool printmsg)
|
|||
if (printmsg) Printf ("sv_cheats must be true to enable this command.\n");
|
||||
return true;
|
||||
}
|
||||
else if (cl_blockcheats)
|
||||
else if (cl_blockcheats != 0)
|
||||
{
|
||||
if (printmsg) Printf ("cl_blockcheats is turned on and disabled this command.\n");
|
||||
if (printmsg && cl_blockcheats == 1) Printf ("cl_blockcheats is turned on and disabled this command.\n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -123,6 +123,8 @@ void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth)
|
|||
{
|
||||
if (formatfont != mLastFont || displaywidth != mLastDisplayWidth || mBufferWasCleared)
|
||||
{
|
||||
if (mBufferWasCleared)
|
||||
mLastLineNeedsUpdate = false;
|
||||
m_BrokenConsoleText.Clear();
|
||||
mBrokenStart.Clear();
|
||||
mBrokenStart.Push(0);
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
#include "i_system.h"
|
||||
#include "g_cvars.h"
|
||||
#include "r_data/r_vanillatrans.h"
|
||||
#include "atterm.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "types.h"
|
||||
#include "scriptutil.h"
|
||||
#include "i_system.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -302,6 +302,11 @@ inline float DEG2RAD(float deg)
|
|||
return deg * float(M_PI / 180.0);
|
||||
}
|
||||
|
||||
inline double DEG2RAD(double deg)
|
||||
{
|
||||
return deg * (M_PI / 180.0);
|
||||
}
|
||||
|
||||
inline float RAD2DEG(float deg)
|
||||
{
|
||||
return deg * float(180. / M_PI);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "vm.h"
|
||||
#include "i_system.h"
|
||||
#include "utf8.h"
|
||||
#include "atterm.h"
|
||||
|
||||
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
||||
enum
|
||||
|
|
|
@ -802,7 +802,9 @@ void DBaseStatusBar::CallTick()
|
|||
void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer)
|
||||
{
|
||||
DHUDMessageBase *old = NULL;
|
||||
TObjPtr<DHUDMessageBase *>*prev;
|
||||
DObject* pointing;
|
||||
TObjPtr<DHUDMessageBase *>*prevp;
|
||||
DHUDMessageBase* prev;
|
||||
|
||||
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
||||
if (old != NULL)
|
||||
|
@ -816,20 +818,25 @@ void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer
|
|||
layer = HUDMSGLayer_Default;
|
||||
}
|
||||
|
||||
prev = &Messages[layer];
|
||||
pointing = this;
|
||||
prevp = &Messages[layer];
|
||||
prev = *prevp;
|
||||
|
||||
// The ID serves as a priority, where lower numbers appear in front of
|
||||
// higher numbers. (i.e. The list is sorted in descending order, since
|
||||
// it gets drawn back to front.)
|
||||
while (*prev != NULL && (*prev)->SBarID > id)
|
||||
while (prev != NULL && prev->SBarID > id)
|
||||
{
|
||||
prev = &(*prev)->Next;
|
||||
pointing = prev;
|
||||
prevp = &prev->Next;
|
||||
prev = *prevp;
|
||||
}
|
||||
|
||||
msg->Next = *prev;
|
||||
msg->Next = prev;
|
||||
msg->SBarID = id;
|
||||
*prev = msg;
|
||||
GC::WriteBarrier(msg);
|
||||
*prevp = msg;
|
||||
GC::WriteBarrier(msg, prev);
|
||||
GC::WriteBarrier(pointing, msg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -843,15 +850,18 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
|
|||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
DObject* pointing = this;
|
||||
TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
|
||||
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
pointing = probe;
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
GC::WriteBarrier(pointing, probe->Next);
|
||||
*prev = probe->Next;
|
||||
probe->Next = nullptr;
|
||||
return probe;
|
||||
|
@ -864,16 +874,19 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
|
|||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DObject* pointing = this;
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
|
||||
|
||||
while (probe && probe->SBarID != id)
|
||||
{
|
||||
pointing = probe;
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
GC::WriteBarrier(pointing, probe->Next);
|
||||
*prev = probe->Next;
|
||||
probe->Next = nullptr;
|
||||
return probe;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "i_system.h"
|
||||
#include "atterm.h"
|
||||
|
||||
static TArray<cluster_info_t> wadclusterinfos;
|
||||
TArray<level_info_t> wadlevelinfos;
|
||||
|
|
|
@ -49,7 +49,7 @@ static void SetDoom2Wad()
|
|||
{
|
||||
if (Doom2Wad == -1)
|
||||
{
|
||||
FString iwad = Wads.GetWadFullName(1);
|
||||
FString iwad = Wads.GetWadFullName(Wads.GetIwadNum());
|
||||
iwad.ToLower();
|
||||
if (iwad.IndexOf("plutonia") >= 0) Doom2Wad = 1;
|
||||
else if (iwad.IndexOf("tnt") >= 0) Doom2Wad = 2;
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "st_start.h"
|
||||
#include "m_misc.h"
|
||||
#include "doomerrors.h"
|
||||
#include "atterm.h"
|
||||
|
||||
#include "i_net.h"
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
#include "gameconfigfile.h"
|
||||
#include "gstrings.h"
|
||||
#include "atterm.h"
|
||||
|
||||
FGameConfigFile *GameConfig;
|
||||
|
||||
|
|
|
@ -767,6 +767,11 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id)
|
|||
|
||||
static bool P_CheckV4Nodes(MapData *map)
|
||||
{
|
||||
if (map->Size(ML_NODES) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char header[8];
|
||||
|
||||
map->Read(ML_NODES, header, 8);
|
||||
|
|
|
@ -510,8 +510,6 @@ void MapLoader::ParseReplies (const char *name, int pos, FStrifeDialogueReply **
|
|||
{
|
||||
FStringf label("$TXT_RPLY%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->Reply).GetChars());
|
||||
reply->Reply = GStrings.exists(label.GetChars() + 1)? label : FString(rsp->Reply);
|
||||
|
||||
reply->Reply = label;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "gstrings.h"
|
||||
#include "teaminfo.h"
|
||||
#include "r_data/sprites.h"
|
||||
#include "atterm.h"
|
||||
|
||||
|
||||
void ClearSaveGames();
|
||||
|
@ -135,6 +136,7 @@ DEFINE_ACTION_FUNCTION(FOptionValues, GetText)
|
|||
|
||||
void DeinitMenus()
|
||||
{
|
||||
M_ClearMenus();
|
||||
{
|
||||
FOptionMap::Iterator it(OptionValues);
|
||||
|
||||
|
@ -148,7 +150,6 @@ void DeinitMenus()
|
|||
}
|
||||
MenuDescriptors.Clear();
|
||||
OptionValues.Clear();
|
||||
CurrentMenu = nullptr;
|
||||
savegameManager.ClearSaveGames();
|
||||
}
|
||||
|
||||
|
|
|
@ -4819,7 +4819,10 @@ void AActor::OnDestroy ()
|
|||
// note that this differs from ThingSpawned in that you can actually override OnDestroy to avoid calling the hook.
|
||||
// but you can't really do that without utterly breaking the game, so it's ok.
|
||||
// note: if OnDestroy is ever made optional, E_WorldThingDestroyed should still be called for ANY thing.
|
||||
if (Level != nullptr)
|
||||
{
|
||||
Level->localEventManager->WorldThingDestroyed(this);
|
||||
}
|
||||
|
||||
DeleteAttachedLights();
|
||||
ClearRenderSectorList();
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "i_system.h"
|
||||
#include "v_video.h"
|
||||
#include "fragglescript/t_script.h"
|
||||
#include "atterm.h"
|
||||
|
||||
extern AActor *SpawnMapThing (int index, FMapThing *mthing, int position);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "m_joy.h"
|
||||
#include "templates.h"
|
||||
#include "v_text.h"
|
||||
#include "atterm.h"
|
||||
|
||||
|
||||
EXTERN_CVAR(Bool, joy_axespolling)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "i_common.h"
|
||||
#include "s_sound.h"
|
||||
#include "atterm.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
|
@ -61,60 +62,6 @@ EXTERN_CVAR(Bool, vid_vsync )
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// The maximum number of functions that can be registered with atterm.
|
||||
const size_t MAX_TERMS = 64;
|
||||
|
||||
void (*TermFuncs[MAX_TERMS])();
|
||||
const char *TermNames[MAX_TERMS];
|
||||
size_t NumTerms;
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
// Expose this for i_main_except.cpp
|
||||
void call_terms()
|
||||
{
|
||||
while (NumTerms > 0)
|
||||
{
|
||||
TermFuncs[--NumTerms]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addterm(void (*func)(), const char *name)
|
||||
{
|
||||
// Make sure this function wasn't already registered.
|
||||
|
||||
for (size_t i = 0; i < NumTerms; ++i)
|
||||
{
|
||||
if (TermFuncs[i] == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumTerms == MAX_TERMS)
|
||||
{
|
||||
func();
|
||||
I_FatalError("Too many exit functions registered.");
|
||||
}
|
||||
|
||||
TermNames[NumTerms] = name;
|
||||
TermFuncs[NumTerms] = func;
|
||||
|
||||
++NumTerms;
|
||||
}
|
||||
|
||||
void popterm()
|
||||
{
|
||||
if (NumTerms)
|
||||
{
|
||||
--NumTerms;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mac_I_FatalError(const char* const message)
|
||||
{
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
|
||||
#include "doomerrors.h"
|
||||
#include "vm.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// Import some functions from i_main.mm
|
||||
void call_terms();
|
||||
void Mac_I_FatalError(const char* const message);
|
||||
void OriginalMainTry(int argc, char** argv);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "v_text.h"
|
||||
#include "x86.h"
|
||||
#include "cmdlib.h"
|
||||
#include "atterm.h"
|
||||
|
||||
|
||||
EXTERN_CVAR(String, language)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "v_text.h"
|
||||
#include "version.h"
|
||||
#include "doomerrors.h"
|
||||
#include "atterm.h"
|
||||
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
|
|
|
@ -89,10 +89,6 @@ void I_Quit (void);
|
|||
|
||||
void I_Tactile (int on, int off, int total);
|
||||
|
||||
void addterm (void (*func)(void), const char *name);
|
||||
#define atterm(t) addterm (t, #t)
|
||||
void popterm ();
|
||||
|
||||
void I_DebugPrint (const char *cp);
|
||||
|
||||
// Print a console string
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "m_argv.h"
|
||||
#include "doomerrors.h"
|
||||
#include "swrenderer/r_swrenderer.h"
|
||||
#include "atterm.h"
|
||||
|
||||
IVideo *Video;
|
||||
|
||||
|
|
|
@ -306,55 +306,84 @@ void MessagePump (const SDL_Event &sev)
|
|||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEMOTION:
|
||||
if (!GUICapture || sev.button.button == 4 || sev.button.button == 5)
|
||||
{
|
||||
if(sev.type != SDL_MOUSEMOTION)
|
||||
if (!GUICapture)
|
||||
{
|
||||
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
/* These button mappings work with my Gentoo system using the
|
||||
* evdev driver and a Logitech MX510 mouse. Whether or not they
|
||||
* carry over to other Linux systems, I have no idea, but I sure
|
||||
* hope so. (Though buttons 11 and 12 are kind of useless, since
|
||||
* they also trigger buttons 4 and 5.)
|
||||
*/
|
||||
|
||||
switch (sev.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break;
|
||||
case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break;
|
||||
case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break;
|
||||
case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here.
|
||||
case 9: event.data1 = KEY_MOUSE5; break;
|
||||
case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist
|
||||
case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break;
|
||||
case 6: event.data1 = KEY_MOUSE8; break;
|
||||
case SDL_BUTTON_X1: event.data1 = KEY_MOUSE4; break;
|
||||
case SDL_BUTTON_X2: event.data1 = KEY_MOUSE5; break;
|
||||
case 6: event.data1 = KEY_MOUSE6; break;
|
||||
case 7: event.data1 = KEY_MOUSE7; break;
|
||||
case 8: event.data1 = KEY_MOUSE8; break;
|
||||
default: printf("SDL mouse button %s %d\n",
|
||||
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
|
||||
}
|
||||
|
||||
if (event.data1 != 0)
|
||||
{
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sev.type == SDL_MOUSEMOTION || (sev.button.button >= 1 && sev.button.button <= 3))
|
||||
else if ((sev.button.button >= SDL_BUTTON_LEFT && sev.button.button <= SDL_BUTTON_X2))
|
||||
{
|
||||
int x, y;
|
||||
SDL_GetMouseState (&x, &y);
|
||||
SDL_GetMouseState(&x, &y);
|
||||
|
||||
event.type = EV_GUI_Event;
|
||||
event.data1 = x;
|
||||
event.data2 = y;
|
||||
|
||||
screen->ScaleCoordsFromWindow(event.data1, event.data2);
|
||||
|
||||
event.type = EV_GUI_Event;
|
||||
if(sev.type == SDL_MOUSEMOTION)
|
||||
event.subtype = EV_GUI_MouseMove;
|
||||
if (sev.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
switch(sev.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT: event.subtype = EV_GUI_LButtonDown; break;
|
||||
case SDL_BUTTON_MIDDLE: event.subtype = EV_GUI_MButtonDown; break;
|
||||
case SDL_BUTTON_RIGHT: event.subtype = EV_GUI_RButtonDown; break;
|
||||
case SDL_BUTTON_X1: event.subtype = EV_GUI_BackButtonDown; break;
|
||||
case SDL_BUTTON_X2: event.subtype = EV_GUI_FwdButtonDown; break;
|
||||
default: assert(false); event.subtype = EV_GUI_None; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp;
|
||||
event.subtype += (sev.button.button - 1) * 3;
|
||||
switch(sev.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT: event.subtype = EV_GUI_LButtonUp; break;
|
||||
case SDL_BUTTON_MIDDLE: event.subtype = EV_GUI_MButtonUp; break;
|
||||
case SDL_BUTTON_RIGHT: event.subtype = EV_GUI_RButtonUp; break;
|
||||
case SDL_BUTTON_X1: event.subtype = EV_GUI_BackButtonUp; break;
|
||||
case SDL_BUTTON_X2: event.subtype = EV_GUI_FwdButtonUp; break;
|
||||
default: assert(false); event.subtype = EV_GUI_None; break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((kmod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((kmod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (GUICapture)
|
||||
{
|
||||
event.data1 = sev.motion.x;
|
||||
event.data2 = sev.motion.y;
|
||||
|
||||
screen->ScaleCoordsFromWindow(event.data1, event.data2);
|
||||
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = EV_GUI_MouseMove;
|
||||
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
|
@ -369,11 +398,17 @@ void MessagePump (const SDL_Event &sev)
|
|||
if (GUICapture)
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
|
||||
if (sev.wheel.y == 0)
|
||||
event.subtype = sev.wheel.x > 0 ? EV_GUI_WheelRight : EV_GUI_WheelLeft;
|
||||
else
|
||||
event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown;
|
||||
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((kmod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((kmod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "doomerrors.h"
|
||||
#include "i_system.h"
|
||||
#include "g_game.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -89,47 +90,9 @@ FArgs *Args;
|
|||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static void (*TermFuncs[MAX_TERMS]) ();
|
||||
static const char *TermNames[MAX_TERMS];
|
||||
static int NumTerms;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
void addterm (void (*func) (), const char *name)
|
||||
{
|
||||
// Make sure this function wasn't already registered.
|
||||
for (int i = 0; i < NumTerms; ++i)
|
||||
{
|
||||
if (TermFuncs[i] == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NumTerms == MAX_TERMS)
|
||||
{
|
||||
func ();
|
||||
I_FatalError (
|
||||
"Too many exit functions registered.\n"
|
||||
"Increase MAX_TERMS in i_main.cpp");
|
||||
}
|
||||
TermNames[NumTerms] = name;
|
||||
TermFuncs[NumTerms++] = func;
|
||||
}
|
||||
|
||||
void popterm ()
|
||||
{
|
||||
if (NumTerms)
|
||||
NumTerms--;
|
||||
}
|
||||
|
||||
void call_terms ()
|
||||
{
|
||||
while (NumTerms > 0)
|
||||
{
|
||||
// printf ("term %d - %s\n", NumTerms, TermNames[NumTerms-1]);
|
||||
TermFuncs[--NumTerms] ();
|
||||
}
|
||||
}
|
||||
|
||||
static void NewFailure ()
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "d_net.h"
|
||||
#include "g_game.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "atterm.h"
|
||||
|
||||
#include "gameconfigfile.h"
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "i_system.h"
|
||||
#include "c_cvars.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -388,7 +388,7 @@ void FOBJModel::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
side + j * 3 + // Current surface and previous triangles
|
||||
surfaces[i].vbStart; // Previous surfaces
|
||||
|
||||
OBJFaceSide &curSide = surfaces[i].tris[j].sides[side];
|
||||
OBJFaceSide &curSide = surfaces[i].tris[j].sides[2 - side];
|
||||
|
||||
int vidx = curSide.vertref;
|
||||
int uvidx = (curSide.uvref >= 0 && (unsigned int)curSide.uvref < uvs.Size()) ? curSide.uvref : 0;
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "actorinlines.h"
|
||||
#include "g_game.h"
|
||||
#include "i_system.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
|
|
|
@ -35,13 +35,61 @@
|
|||
|
||||
EXTERN_CVAR(Float, transsouls)
|
||||
|
||||
IMPLEMENT_CLASS(DShape2DTransform, false, false)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Clear)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
self->transform.Identity();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Rotate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(angle);
|
||||
self->transform = DMatrix3x3::Rotate2D(DEG2RAD(angle)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Scale)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->transform = DMatrix3x3::Scale2D(DVector2(x, y)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Translate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->transform = DMatrix3x3::Translate2D(DVector2(x, y)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(DShape2D, false, false)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2D, SetTransform)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2D);
|
||||
PARAM_OBJECT(transform, DShape2DTransform);
|
||||
self->transform = transform->transform;
|
||||
self->dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2D, Clear)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2D);
|
||||
PARAM_INT(which);
|
||||
if ( which&C_Verts ) self->mVertices.Clear();
|
||||
if ( which&C_Verts )
|
||||
{
|
||||
self->mVertices.Clear();
|
||||
self->dirty = true;
|
||||
}
|
||||
if ( which&C_Coords ) self->mCoords.Clear();
|
||||
if ( which&C_Indices ) self->mIndices.Clear();
|
||||
return 0;
|
||||
|
@ -53,6 +101,7 @@ DEFINE_ACTION_FUNCTION(DShape2D, PushVertex)
|
|||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->mVertices.Push(DVector2(x,y));
|
||||
self->dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -380,13 +429,22 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
|||
if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive)
|
||||
dg.mTranslation = parms.remap;
|
||||
|
||||
if (shape->dirty) {
|
||||
if (shape->mVertices.Size() != shape->mTransformedVertices.Size())
|
||||
shape->mTransformedVertices.Resize(shape->mVertices.Size());
|
||||
for (int i = 0; i < dg.mVertCount; i++) {
|
||||
shape->mTransformedVertices[i] = (shape->transform * DVector3(shape->mVertices[i], 1.0)).XY();
|
||||
}
|
||||
shape->dirty = false;
|
||||
}
|
||||
|
||||
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
|
||||
for ( int i=0; i<dg.mVertCount; i++ )
|
||||
{
|
||||
if ( shape->mVertices[i].X < minx ) minx = shape->mVertices[i].X;
|
||||
if ( shape->mVertices[i].Y < miny ) miny = shape->mVertices[i].Y;
|
||||
if ( shape->mVertices[i].X > maxx ) maxx = shape->mVertices[i].X;
|
||||
if ( shape->mVertices[i].Y > maxy ) maxy = shape->mVertices[i].Y;
|
||||
if ( shape->mTransformedVertices[i].X < minx ) minx = shape->mTransformedVertices[i].X;
|
||||
if ( shape->mTransformedVertices[i].Y < miny ) miny = shape->mTransformedVertices[i].Y;
|
||||
if ( shape->mTransformedVertices[i].X > maxx ) maxx = shape->mTransformedVertices[i].X;
|
||||
if ( shape->mTransformedVertices[i].Y > maxy ) maxy = shape->mTransformedVertices[i].Y;
|
||||
}
|
||||
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
||||
{
|
||||
|
@ -402,7 +460,7 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
|||
dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
|
||||
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
for ( int i=0; i<dg.mVertCount; i++ )
|
||||
ptr[i].Set(shape->mVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||
ptr[i].Set(shape->mTransformedVertices[i].X, shape->mTransformedVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += shape->mIndices.Size();
|
||||
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
||||
|
@ -485,10 +543,10 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0);
|
||||
}
|
||||
poly.mIndexIndex = mIndices.Size();
|
||||
poly.mIndexCount += (npoints - 2) * 3;
|
||||
|
||||
if (indices == nullptr || indexcount == 0)
|
||||
{
|
||||
poly.mIndexCount += (npoints - 2) * 3;
|
||||
for (int i = 2; i < npoints; ++i)
|
||||
{
|
||||
AddIndices(poly.mVertIndex, 3, 0, i - 1, i);
|
||||
|
@ -496,10 +554,11 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
}
|
||||
else
|
||||
{
|
||||
poly.mIndexCount += (int)indexcount;
|
||||
int addr = mIndices.Reserve(indexcount);
|
||||
for (size_t i = 0; i < indexcount; i++)
|
||||
{
|
||||
mIndices[addr + i] = addr + indices[i];
|
||||
mIndices[addr + i] = poly.mVertIndex + indices[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,18 @@
|
|||
|
||||
struct DrawParms;
|
||||
|
||||
class DShape2DTransform : public DObject
|
||||
{
|
||||
|
||||
DECLARE_CLASS(DShape2DTransform, DObject)
|
||||
public:
|
||||
DShape2DTransform()
|
||||
{
|
||||
transform.Identity();
|
||||
}
|
||||
DMatrix3x3 transform;
|
||||
};
|
||||
|
||||
// intermediate struct for shape drawing
|
||||
|
||||
enum EClearWhich
|
||||
|
@ -23,9 +35,21 @@ class DShape2D : public DObject
|
|||
|
||||
DECLARE_CLASS(DShape2D,DObject)
|
||||
public:
|
||||
DShape2D()
|
||||
{
|
||||
transform.Identity();
|
||||
}
|
||||
|
||||
TArray<int> mIndices;
|
||||
TArray<DVector2> mVertices;
|
||||
TArray<DVector2> mCoords;
|
||||
|
||||
DMatrix3x3 transform;
|
||||
|
||||
// dirty stores whether we need to re-apply the transformation
|
||||
// otherwise it uses the cached values
|
||||
bool dirty = true;
|
||||
TArray<DVector2> mTransformedVertices;
|
||||
};
|
||||
|
||||
class F2DDrawer
|
||||
|
|
|
@ -235,7 +235,8 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
|
|||
}
|
||||
mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
|
||||
mPresentShader->Uniforms->Offset = { 0.0f, 0.0f };
|
||||
mPresentShader->Uniforms.Set();
|
||||
mPresentShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresentShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
#include <random>
|
||||
|
||||
CVAR(Int, gl_multisample, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
|
@ -955,7 +956,7 @@ void GLPPRenderState::Draw()
|
|||
if (!shader->Uniforms)
|
||||
shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false, false));
|
||||
shader->Uniforms->SetData(Uniforms.Data.Size(), Uniforms.Data.Data());
|
||||
shader->Uniforms->BindBase();
|
||||
static_cast<GLDataBuffer*>(shader->Uniforms.get())->BindBase();
|
||||
}
|
||||
|
||||
// Set shader
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "r_videoscale.h"
|
||||
#include "r_data/models/models.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
@ -191,12 +192,17 @@ void FGLRenderer::UpdateShadowMap()
|
|||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLightList)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mNodesBuffer)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLinesBuffer)->BindBase();
|
||||
|
||||
mBuffers->BindShadowMapFB();
|
||||
|
||||
mShadowMapShader->Bind();
|
||||
mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality;
|
||||
mShadowMapShader->Uniforms->NodesCount = screen->mShadowMap.NodesCount();
|
||||
mShadowMapShader->Uniforms.Set();
|
||||
mShadowMapShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mShadowMapShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
glViewport(0, 0, gl_shadowmap_quality, 1024);
|
||||
RenderScreenQuad();
|
||||
|
|
|
@ -27,7 +27,7 @@ class FGLRenderBuffers;
|
|||
class FGL2DDrawer;
|
||||
class FHardwareTexture;
|
||||
class SWSceneDrawer;
|
||||
class GLViewpointBuffer;
|
||||
class HWViewpointBuffer;
|
||||
struct FRenderViewpoint;
|
||||
|
||||
namespace OpenGLRenderer
|
||||
|
|
|
@ -189,9 +189,21 @@ bool FGLRenderState::ApplyShader()
|
|||
matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index);
|
||||
}
|
||||
|
||||
auto index = screen->mLights->BindUBO(mLightIndex);
|
||||
activeShader->muLightIndex.Set(index);
|
||||
int index = mLightIndex;
|
||||
// Mess alert for crappy AncientGL!
|
||||
if (!screen->mLights->GetBufferType() && index >= 0)
|
||||
{
|
||||
size_t start, size;
|
||||
index = screen->mLights->GetBinding(index, &start, &size);
|
||||
|
||||
if (start != mLastMappedLightIndex)
|
||||
{
|
||||
mLastMappedLightIndex = start;
|
||||
static_cast<GLDataBuffer*>(screen->mLights->GetBuffer())->BindRange(nullptr, start, size);
|
||||
}
|
||||
}
|
||||
|
||||
activeShader->muLightIndex.Set(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ class FGLRenderState : public FRenderState
|
|||
int lastClamp = 0;
|
||||
int lastTranslation = 0;
|
||||
int maxBoundMaterial = -1;
|
||||
size_t mLastMappedLightIndex = SIZE_MAX;
|
||||
|
||||
IVertexBuffer *mCurrentVertexBuffer;
|
||||
int mCurrentVertexOffsets[2]; // one per binding point
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
#include "menu/menu.h"
|
||||
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
|
@ -174,7 +175,8 @@ void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
|
|||
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
||||
};
|
||||
shader.Uniforms->Offset = { 0.0f, 0.0f };
|
||||
shader.Uniforms.Set();
|
||||
shader.Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(shader.Uniforms.GetBuffer())->BindBase();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -198,7 +200,8 @@ void FGLRenderer::PresentColumnInterleaved()
|
|||
int windowHOffset = 0;
|
||||
|
||||
mPresent3dColumnShader->Uniforms->WindowPositionParity = windowHOffset;
|
||||
mPresent3dColumnShader->Uniforms.Set();
|
||||
mPresent3dColumnShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dColumnShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
@ -225,7 +228,8 @@ void FGLRenderer::PresentRowInterleaved()
|
|||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2;
|
||||
|
||||
mPresent3dRowShader->Uniforms.Set();
|
||||
mPresent3dRowShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dRowShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
@ -256,7 +260,8 @@ void FGLRenderer::PresentCheckerInterleaved()
|
|||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2; // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
|
||||
mPresent3dCheckerShader->Uniforms.Set();
|
||||
mPresent3dCheckerShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dCheckerShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
|
|
@ -210,9 +210,8 @@ void GLVertexBuffer::Bind(int *offsets)
|
|||
}
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindRange(size_t start, size_t length)
|
||||
void GLDataBuffer::BindRange(FRenderState *state, size_t start, size_t length)
|
||||
{
|
||||
if (mUseType == GL_UNIFORM_BUFFER) // SSBO's cannot be rebound.
|
||||
glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@ class GLDataBuffer : public IDataBuffer, public GLBuffer
|
|||
int mBindingPoint;
|
||||
public:
|
||||
GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(is_ssbo? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER), mBindingPoint(bindingpoint) {}
|
||||
void BindRange(size_t start, size_t length) override;
|
||||
void BindBase() override;
|
||||
void BindRange(FRenderState* state, size_t start, size_t length);
|
||||
void BindBase();
|
||||
};
|
||||
|
||||
}
|
|
@ -126,7 +126,7 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
glslversion = gl.glslversion;
|
||||
uniformblockalignment = gl.uniformblockalignment;
|
||||
maxuniformblock = gl.maxuniformblock;
|
||||
gl_vendorstring = gl.vendorstring;
|
||||
vendorstring = gl.vendorstring;
|
||||
|
||||
if (first)
|
||||
{
|
||||
|
@ -154,12 +154,14 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new GLViewpointBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
|
||||
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
|
||||
|
||||
mDebug = std::make_shared<FGLDebug>();
|
||||
mDebug->Update();
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ void gl_LoadExtensions()
|
|||
|
||||
// Mesa implements shader storage only for fragment shaders.
|
||||
// Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects.
|
||||
int v;
|
||||
int v = 0;
|
||||
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
|
||||
if (v == 0)
|
||||
gl.flags &= ~RFL_SHADER_STORAGE_BUFFER;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
class FRenderState;
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
|
@ -76,7 +78,6 @@ class IDataBuffer : virtual public IBuffer
|
|||
{
|
||||
// Can be either uniform or shader storage buffer, depending on its needs.
|
||||
public:
|
||||
virtual void BindRange(size_t start, size_t length) = 0;
|
||||
virtual void BindBase() = 0;
|
||||
virtual void BindRange(FRenderState *state, size_t start, size_t length) = 0;
|
||||
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough
|
||||
|
||||
GLViewpointBuffer::GLViewpointBuffer()
|
||||
HWViewpointBuffer::HWViewpointBuffer()
|
||||
{
|
||||
mBufferSize = INITIAL_BUFFER_SIZE;
|
||||
mBlockAlign = ((sizeof(HWViewpointUniforms) / screen->uniformblockalignment) + 1) * screen->uniformblockalignment;
|
||||
|
@ -45,13 +45,13 @@ GLViewpointBuffer::GLViewpointBuffer()
|
|||
mClipPlaneInfo.Push(0);
|
||||
}
|
||||
|
||||
GLViewpointBuffer::~GLViewpointBuffer()
|
||||
HWViewpointBuffer::~HWViewpointBuffer()
|
||||
{
|
||||
delete mBuffer;
|
||||
}
|
||||
|
||||
|
||||
void GLViewpointBuffer::CheckSize()
|
||||
void HWViewpointBuffer::CheckSize()
|
||||
{
|
||||
if (mUploadIndex >= mBufferSize)
|
||||
{
|
||||
|
@ -62,18 +62,18 @@ void GLViewpointBuffer::CheckSize()
|
|||
}
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::Bind(FRenderState &di, unsigned int index)
|
||||
int HWViewpointBuffer::Bind(FRenderState &di, unsigned int index)
|
||||
{
|
||||
if (index != mLastMappedIndex)
|
||||
{
|
||||
mLastMappedIndex = index;
|
||||
mBuffer->BindRange(index * mBlockAlign, mBlockAlign);
|
||||
mBuffer->BindRange(&di, index * mBlockAlign, mBlockAlign);
|
||||
di.EnableClipDistance(0, mClipPlaneInfo[index]);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
||||
void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
||||
{
|
||||
if (width != m2DWidth || height != m2DHeight)
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ void GLViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
|||
Bind(di, 0);
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
||||
int HWViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
||||
{
|
||||
CheckSize();
|
||||
mBuffer->Map();
|
||||
|
@ -102,7 +102,7 @@ int GLViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
|||
return Bind(di, mUploadIndex++);
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Clear()
|
||||
void HWViewpointBuffer::Clear()
|
||||
{
|
||||
// Index 0 is reserved for the 2D projection.
|
||||
mUploadIndex = 1;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
struct HWViewpointUniforms;
|
||||
class FRenderState;
|
||||
|
||||
class GLViewpointBuffer
|
||||
class HWViewpointBuffer
|
||||
{
|
||||
IDataBuffer *mBuffer;
|
||||
|
||||
|
@ -24,8 +24,8 @@ class GLViewpointBuffer
|
|||
|
||||
public:
|
||||
|
||||
GLViewpointBuffer();
|
||||
~GLViewpointBuffer();
|
||||
HWViewpointBuffer();
|
||||
~HWViewpointBuffer();
|
||||
void Clear();
|
||||
int Bind(FRenderState &di, unsigned int index);
|
||||
void Set2D(FRenderState &di, int width, int height);
|
||||
|
|
|
@ -126,14 +126,16 @@ public:
|
|||
mBuffer = screen->CreateDataBuffer(bindingpoint, false, false);
|
||||
}
|
||||
|
||||
void Set(bool bind = true)
|
||||
void SetData()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
mBuffer->SetData(sizeof(T), &Values);
|
||||
}
|
||||
|
||||
// Let's hope this can be done better when things have moved further ahead.
|
||||
// This really is not the best place to add something that depends on API behavior.
|
||||
if (bind) mBuffer->BindBase();
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
// OpenGL needs to mess around with this in ways that should not be part of the interface.
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
T *operator->() { return &Values; }
|
||||
|
|
|
@ -44,7 +44,7 @@ FLightBuffer::FLightBuffer()
|
|||
// Hack alert: On Intel's GL driver SSBO's perform quite worse than UBOs.
|
||||
// We only want to disable using SSBOs for lights but not disable the feature entirely.
|
||||
// Note that using an uniform buffer here will limit the number of lights per surface so it isn't done for NVidia and AMD.
|
||||
if (screen->IsVulkan() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->gl_vendorstring, "Intel")))
|
||||
if (screen->IsVulkan() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
|
||||
{
|
||||
mBufferType = true;
|
||||
mBlockAlign = 0;
|
||||
|
@ -74,7 +74,6 @@ FLightBuffer::~FLightBuffer()
|
|||
void FLightBuffer::Clear()
|
||||
{
|
||||
mIndex = 0;
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
}
|
||||
|
||||
int FLightBuffer::UploadLights(FDynLightData &data)
|
||||
|
@ -127,16 +126,13 @@ int FLightBuffer::UploadLights(FDynLightData &data)
|
|||
}
|
||||
}
|
||||
|
||||
int FLightBuffer::DoBindUBO(unsigned int index)
|
||||
int FLightBuffer::GetBinding(unsigned int index, size_t* pOffset, size_t* pSize)
|
||||
{
|
||||
// this function will only get called if a uniform buffer is used. For a shader storage buffer we only need to bind the buffer once at the start.
|
||||
unsigned int offset = (index / mBlockAlign) * mBlockAlign;
|
||||
|
||||
if (offset != mLastMappedIndex)
|
||||
{
|
||||
mLastMappedIndex = offset;
|
||||
mBuffer->BindRange(offset * ELEMENT_SIZE, mBlockSize * ELEMENT_SIZE);
|
||||
}
|
||||
*pOffset = offset * ELEMENT_SIZE;
|
||||
*pSize = mBlockSize * ELEMENT_SIZE;
|
||||
return (index - offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ class FLightBuffer
|
|||
|
||||
bool mBufferType;
|
||||
std::atomic<unsigned int> mIndex;
|
||||
unsigned int mLastMappedIndex;
|
||||
unsigned int mBlockAlign;
|
||||
unsigned int mBlockSize;
|
||||
unsigned int mBufferSize;
|
||||
|
@ -34,32 +33,12 @@ public:
|
|||
void Unmap() { mBuffer->Unmap(); }
|
||||
unsigned int GetBlockSize() const { return mBlockSize; }
|
||||
bool GetBufferType() const { return mBufferType; }
|
||||
int GetBinding(unsigned int index, size_t* pOffset, size_t* pSize);
|
||||
|
||||
int DoBindUBO(unsigned int index);
|
||||
|
||||
int ShaderIndex(unsigned int index) const
|
||||
// OpenGL needs the buffer to mess around with the binding.
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
if (mBlockAlign == 0) return index;
|
||||
// This must match the math in BindUBO.
|
||||
unsigned int offset = (index / mBlockAlign) * mBlockAlign;
|
||||
return int(index-offset);
|
||||
}
|
||||
|
||||
// Only relevant for OpenGL, so this does not need access to the render state.
|
||||
int BindUBO(int index)
|
||||
{
|
||||
if (!mBufferType && index > -1)
|
||||
{
|
||||
index = DoBindUBO(index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// The parameter is a reminder for Vulkan.
|
||||
void BindBase()
|
||||
{
|
||||
mBuffer->BindBase();
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -176,9 +176,6 @@ bool IShadowMap::PerformUpdate()
|
|||
UpdateCycles.Clock();
|
||||
UploadAABBTree();
|
||||
UploadLights();
|
||||
mLightList->BindBase();
|
||||
mNodesBuffer->BindBase();
|
||||
mLinesBuffer->BindBase();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -65,6 +65,8 @@ protected:
|
|||
IShadowMap &operator=(IShadowMap &) = delete;
|
||||
|
||||
// OpenGL storage buffer with the list of lights in the shadow map texture
|
||||
// These buffers need to be accessed by the OpenGL backend directly so that they can be bound.
|
||||
public:
|
||||
IDataBuffer *mLightList = nullptr;
|
||||
|
||||
// OpenGL storage buffers for the AABB tree
|
||||
|
|
|
@ -468,7 +468,6 @@ void HWDrawInfo::RenderScene(FRenderState &state)
|
|||
|
||||
state.SetDepthMask(true);
|
||||
|
||||
screen->mLights->BindBase();
|
||||
state.EnableFog(true);
|
||||
state.SetRenderStyle(STYLE_Source);
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "templates.h"
|
||||
#include "r_utility.h"
|
||||
#include "r_renderer.h"
|
||||
#include "atterm.h"
|
||||
#include <atomic>
|
||||
|
||||
FDynamicColormap NormalLight;
|
||||
|
|
|
@ -35,7 +35,7 @@ void VkPostprocess::SetActiveRenderTarget()
|
|||
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
fb->GetRenderState()->SetRenderTarget(buffers->PipelineImage[mCurrentPipelineImage].View.get(), nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
}
|
||||
|
||||
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
@ -402,6 +402,18 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
}
|
||||
}
|
||||
|
||||
VkPPTexture::~VkPPTexture()
|
||||
{
|
||||
if (auto fb = GetVulkanFrameBuffer())
|
||||
{
|
||||
if (TexImage.Image) fb->FrameDeleteList.Images.push_back(std::move(TexImage.Image));
|
||||
if (TexImage.View) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.View));
|
||||
if (TexImage.DepthOnlyView) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.DepthOnlyView));
|
||||
if (TexImage.PPFramebuffer) fb->FrameDeleteList.Framebuffers.push_back(std::move(TexImage.PPFramebuffer));
|
||||
if (Staging) fb->FrameDeleteList.Buffers.push_back(std::move(Staging));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VkPPShader::VkPPShader(PPShader *shader)
|
||||
|
@ -585,6 +597,7 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
VkTextureImage *tex = GetTexture(output.Type, output.Texture);
|
||||
|
||||
VkImageView view;
|
||||
std::unique_ptr<VulkanFramebuffer> *framebufferptr = nullptr;
|
||||
int w, h;
|
||||
if (tex)
|
||||
{
|
||||
|
@ -597,15 +610,17 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
view = tex->View->view;
|
||||
w = tex->Image->width;
|
||||
h = tex->Image->height;
|
||||
framebufferptr = &tex->PPFramebuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
view = fb->swapChain->swapChainImageViews[fb->presentImageIndex];
|
||||
framebufferptr = &fb->swapChain->framebuffers[fb->presentImageIndex];
|
||||
w = fb->swapChain->actualExtent.width;
|
||||
h = fb->swapChain->actualExtent.height;
|
||||
}
|
||||
|
||||
auto &framebuffer = passSetup->Framebuffers[view];
|
||||
auto &framebuffer = *framebufferptr;
|
||||
if (!framebuffer)
|
||||
{
|
||||
FramebufferBuilder builder;
|
||||
|
|
|
@ -88,6 +88,7 @@ class VkPPTexture : public PPTextureBackend
|
|||
{
|
||||
public:
|
||||
VkPPTexture(PPTexture *texture);
|
||||
~VkPPTexture();
|
||||
|
||||
VkTextureImage TexImage;
|
||||
std::unique_ptr<VulkanBuffer> Staging;
|
||||
|
@ -103,7 +104,6 @@ public:
|
|||
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
|
||||
std::unique_ptr<VulkanRenderPass> RenderPass;
|
||||
std::unique_ptr<VulkanPipeline> Pipeline;
|
||||
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffers;
|
||||
|
||||
private:
|
||||
void CreateDescriptorLayout(const VkPPRenderPassKey &key);
|
||||
|
|
|
@ -59,7 +59,6 @@ public:
|
|||
VkRenderPassKey PassKey;
|
||||
std::unique_ptr<VulkanRenderPass> RenderPasses[8];
|
||||
std::map<VkPipelineKey, std::unique_ptr<VulkanPipeline>> Pipelines;
|
||||
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffer;
|
||||
|
||||
private:
|
||||
std::unique_ptr<VulkanRenderPass> CreateRenderPass(int clearTargets);
|
||||
|
|
|
@ -528,11 +528,11 @@ void VkRenderState::EnableDrawBuffers(int count)
|
|||
}
|
||||
}
|
||||
|
||||
void VkRenderState::SetRenderTarget(VulkanImageView *view, VulkanImageView *depthStencilView, int width, int height, VkFormat format, VkSampleCountFlagBits samples)
|
||||
void VkRenderState::SetRenderTarget(VkTextureImage *image, VulkanImageView *depthStencilView, int width, int height, VkFormat format, VkSampleCountFlagBits samples)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
mRenderTarget.View = view;
|
||||
mRenderTarget.Image = image;
|
||||
mRenderTarget.DepthStencil = depthStencilView;
|
||||
mRenderTarget.Width = width;
|
||||
mRenderTarget.Height = height;
|
||||
|
@ -552,14 +552,14 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
|
|||
|
||||
mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key);
|
||||
|
||||
auto &framebuffer = mPassSetup->Framebuffer[mRenderTarget.View->view];
|
||||
auto &framebuffer = mRenderTarget.Image->RSFramebuffers[key];
|
||||
if (!framebuffer)
|
||||
{
|
||||
auto buffers = fb->GetBuffers();
|
||||
FramebufferBuilder builder;
|
||||
builder.setRenderPass(mPassSetup->GetRenderPass(0));
|
||||
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
||||
builder.addAttachment(mRenderTarget.View);
|
||||
builder.addAttachment(mRenderTarget.Image->View.get());
|
||||
if (key.DrawBuffers > 1)
|
||||
builder.addAttachment(buffers->SceneFog.View.get());
|
||||
if (key.DrawBuffers > 2)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
class VkRenderPassSetup;
|
||||
class VkTextureImage;
|
||||
|
||||
class VkRenderState : public FRenderState
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ public:
|
|||
void EnableDrawBuffers(int count) override;
|
||||
|
||||
void BeginFrame();
|
||||
void SetRenderTarget(VulkanImageView *view, VulkanImageView *depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void SetRenderTarget(VkTextureImage *image, VulkanImageView *depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void Bind(int bindingpoint, uint32_t offset);
|
||||
void EndRenderPass();
|
||||
void EndFrame();
|
||||
|
@ -112,7 +113,7 @@ protected:
|
|||
|
||||
struct RenderTarget
|
||||
{
|
||||
VulkanImageView *View = nullptr;
|
||||
VkTextureImage *Image = nullptr;
|
||||
VulkanImageView *DepthStencil = nullptr;
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
|
|
|
@ -204,12 +204,9 @@ void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t s
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VKDataBuffer::BindRange(size_t start, size_t length)
|
||||
|
||||
void VKDataBuffer::BindRange(FRenderState* state, size_t start, size_t length)
|
||||
{
|
||||
GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, (uint32_t)start);
|
||||
static_cast<VkRenderState*>(state)->Bind(bindingpoint, (uint32_t)start);
|
||||
}
|
||||
|
||||
void VKDataBuffer::BindBase()
|
||||
{
|
||||
GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, 0);
|
||||
}
|
||||
|
|
|
@ -68,8 +68,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void BindRange(size_t start, size_t length) override;
|
||||
void BindBase() override;
|
||||
void BindRange(FRenderState *state, size_t start, size_t length) override;
|
||||
|
||||
int bindingpoint;
|
||||
};
|
||||
|
|
|
@ -128,7 +128,14 @@ void VulkanFrameBuffer::InitializeState()
|
|||
first = false;
|
||||
}
|
||||
|
||||
gl_vendorstring = "Vulkan";
|
||||
switch (device->PhysicalDevice.Properties.vendorID)
|
||||
{
|
||||
case 0x1002: vendorstring = "AMD"; break;
|
||||
case 0x10DE: vendorstring = "NVIDIA"; break;
|
||||
case 0x8086: vendorstring = "Intel"; break;
|
||||
default: vendorstring = "Unknown"; break;
|
||||
}
|
||||
|
||||
hwcaps = RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE;
|
||||
glslversion = 4.50f;
|
||||
uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment;
|
||||
|
@ -145,7 +152,7 @@ void VulkanFrameBuffer::InitializeState()
|
|||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new GLViewpointBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
|
||||
CreateFanToTrisIndexBuffer();
|
||||
|
@ -199,6 +206,7 @@ void VulkanFrameBuffer::DeleteFrameObjects()
|
|||
{
|
||||
FrameDeleteList.Images.clear();
|
||||
FrameDeleteList.ImageViews.clear();
|
||||
FrameDeleteList.Framebuffers.clear();
|
||||
FrameDeleteList.Buffers.clear();
|
||||
FrameDeleteList.Descriptors.clear();
|
||||
FrameDeleteList.DescriptorPools.clear();
|
||||
|
@ -444,7 +452,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
|||
|
||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||
{
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
bool useSSAO = (gl_ssao != 0);
|
||||
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
||||
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
||||
|
@ -514,7 +522,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
barrier0.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier0.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(image->View.get(), depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
|
@ -530,7 +538,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
barrier1.addImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier1.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
|
||||
tex->SetUpdated(true);
|
||||
}
|
||||
|
@ -709,11 +717,12 @@ void VulkanFrameBuffer::UpdatePalette()
|
|||
|
||||
FTexture *VulkanFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
SetViewportRects(nullptr);
|
||||
|
||||
auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1);
|
||||
auto systex = static_cast<VkHardwareTexture*>(tex->GetSystemTexture());
|
||||
|
||||
systex->CreateWipeTexture(viewport.width, viewport.height, "WipeStartScreen");
|
||||
systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeStartScreen");
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
@ -724,11 +733,10 @@ FTexture *VulkanFrameBuffer::WipeEndScreen()
|
|||
Draw2D();
|
||||
Clear2D();
|
||||
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1);
|
||||
auto systex = static_cast<VkHardwareTexture*>(tex->GetSystemTexture());
|
||||
|
||||
systex->CreateWipeTexture(viewport.width, viewport.height, "WipeEndScreen");
|
||||
systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeEndScreen");
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
public:
|
||||
std::vector<std::unique_ptr<VulkanImage>> Images;
|
||||
std::vector<std::unique_ptr<VulkanImageView>> ImageViews;
|
||||
std::vector<std::unique_ptr<VulkanFramebuffer>> Framebuffers;
|
||||
std::vector<std::unique_ptr<VulkanBuffer>> Buffers;
|
||||
std::vector<std::unique_ptr<VulkanDescriptorSet>> Descriptors;
|
||||
std::vector<std::unique_ptr<VulkanDescriptorPool>> DescriptorPools;
|
||||
|
|
|
@ -207,6 +207,7 @@ bool VulkanSwapChain::CreateSwapChain(VkSwapchainKHR oldSwapChain)
|
|||
|
||||
void VulkanSwapChain::CreateViews()
|
||||
{
|
||||
framebuffers.resize(swapChainImages.size());
|
||||
swapChainImageViews.reserve(swapChainImages.size());
|
||||
for (size_t i = 0; i < swapChainImages.size(); i++)
|
||||
{
|
||||
|
@ -335,6 +336,7 @@ void VulkanSwapChain::GetImages()
|
|||
|
||||
void VulkanSwapChain::ReleaseViews()
|
||||
{
|
||||
framebuffers.clear();
|
||||
for (auto &view : swapChainImageViews)
|
||||
{
|
||||
vkDestroyImageView(device->device, view, nullptr);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
class VulkanSemaphore;
|
||||
class VulkanFence;
|
||||
class VulkanFramebuffer;
|
||||
|
||||
class VulkanSwapChain
|
||||
{
|
||||
|
@ -22,6 +23,7 @@ public:
|
|||
|
||||
std::vector<VkImage> swapChainImages;
|
||||
std::vector<VkImageView> swapChainImageViews;
|
||||
std::vector<std::unique_ptr<VulkanFramebuffer>> framebuffers;
|
||||
|
||||
VkExtent2D actualExtent;
|
||||
|
||||
|
|
|
@ -72,8 +72,10 @@ void VkHardwareTexture::Reset()
|
|||
auto &deleteList = fb->FrameDeleteList;
|
||||
if (mImage.Image) deleteList.Images.push_back(std::move(mImage.Image));
|
||||
if (mImage.View) deleteList.ImageViews.push_back(std::move(mImage.View));
|
||||
for (auto &it : mImage.RSFramebuffers) deleteList.Framebuffers.push_back(std::move(it.second));
|
||||
if (mDepthStencil.Image) deleteList.Images.push_back(std::move(mDepthStencil.Image));
|
||||
if (mDepthStencil.View) deleteList.ImageViews.push_back(std::move(mDepthStencil.View));
|
||||
for (auto &it : mDepthStencil.RSFramebuffers) deleteList.Framebuffers.push_back(std::move(it.second));
|
||||
mImage.reset();
|
||||
mDepthStencil.reset();
|
||||
}
|
||||
|
@ -374,5 +376,33 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
|
|||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName(name);
|
||||
|
||||
if (fb->GetBuffers()->GetWidth() > 0 && fb->GetBuffers()->GetHeight() > 0)
|
||||
{
|
||||
fb->GetPostprocess()->BlitCurrentToImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// hwrenderer asked image data from a frame buffer that was never written into. Let's give it that..
|
||||
// (ideally the hwrenderer wouldn't do this, but the calling code is too complex for me to fix)
|
||||
|
||||
VkImageTransition transition0;
|
||||
transition0.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
transition0.execute(fb->GetTransferCommands());
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
range.layerCount = 1;
|
||||
range.levelCount = 1;
|
||||
|
||||
VkClearColorValue value = {};
|
||||
value.float32[0] = 0.0f;
|
||||
value.float32[1] = 0.0f;
|
||||
value.float32[2] = 0.0f;
|
||||
value.float32[3] = 1.0f;
|
||||
fb->GetTransferCommands()->clearColorImage(mImage.Image->image, mImage.Layout, &value, 1, &range);
|
||||
|
||||
VkImageTransition transition1;
|
||||
transition1.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
transition1.execute(fb->GetTransferCommands());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "vulkan/system/vk_objects.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
#include "vulkan/renderer/vk_renderpass.h"
|
||||
|
||||
class VkTextureImage
|
||||
{
|
||||
|
@ -23,6 +24,8 @@ public:
|
|||
std::unique_ptr<VulkanImageView> DepthOnlyView;
|
||||
VkImageLayout Layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkImageAspectFlags AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
std::unique_ptr<VulkanFramebuffer> PPFramebuffer;
|
||||
std::map<VkRenderPassKey, std::unique_ptr<VulkanFramebuffer>> RSFramebuffers;
|
||||
};
|
||||
|
||||
class VkImageTransition
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "r_data/sprites.h"
|
||||
#include "vm.h"
|
||||
#include "i_system.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "vm.h"
|
||||
#include "dobject.h"
|
||||
#include "menu/menu.h"
|
||||
#include "atterm.h"
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "vm.h"
|
||||
#include "g_game.h"
|
||||
#include "atterm.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -82,6 +82,8 @@ static const FLOP FxFlops[] =
|
|||
{ NAME_CosH, FLOP_COSH, [](double v) { return g_cosh(v); } },
|
||||
{ NAME_SinH, FLOP_SINH, [](double v) { return g_sinh(v); } },
|
||||
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
||||
|
||||
{ NAME_Round, FLOP_ROUND, [](double v) { return round(v); } },
|
||||
};
|
||||
|
||||
|
||||
|
@ -4835,7 +4837,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
|
|||
// If this is a local variable we need another register for the result.
|
||||
if (trueop.Fixed)
|
||||
{
|
||||
out = ExpEmit(build, trueop.RegType);
|
||||
out = ExpEmit(build, trueop.RegType, trueop.RegCount);
|
||||
build->Emit(truex->ValueType->GetMoveOp(), out.RegNum, trueop.RegNum, 0);
|
||||
}
|
||||
else out = trueop;
|
||||
|
@ -6126,19 +6128,16 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
|||
if ((vsym->Flags & VARF_Deprecated))
|
||||
{
|
||||
if (sym->mVersion <= ctx.Version)
|
||||
{
|
||||
if (!(ctx.Function->Variants[0].Flags & VARF_Deprecated) && Wads.GetLumpFile(ctx.Lump) == 0)
|
||||
{
|
||||
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated global variable %s - deprecated since %d.%d.%d", sym->SymbolName.GetChars(), vsym->mVersion.major, vsym->mVersion.minor, vsym->mVersion.revision);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow use of deprecated symbols in deprecated functions of the internal code. This is meant to allow deprecated code to remain as it was,
|
||||
// even if it depends on some deprecated symbol.
|
||||
// The main motivation here is to keep the deprecated static functions accessing the global level variable as they were.
|
||||
// Print these only if debug output is active and at the highest verbosity level.
|
||||
ScriptPosition.Message(MSG_DEBUGMSG, TEXTCOLOR_BLUE "Accessing deprecated global variable %s - deprecated since %d.%d.%d", sym->SymbolName.GetChars(), vsym->mVersion.major, vsym->mVersion.minor, vsym->mVersion.revision);
|
||||
}
|
||||
const bool internal = (ctx.Function->Variants[0].Flags & VARF_Deprecated) && Wads.GetLumpFile(ctx.Lump) == 0;
|
||||
|
||||
ScriptPosition.Message(internal ? MSG_DEBUGMSG : MSG_WARNING,
|
||||
"%sAccessing deprecated global variable %s - deprecated since %d.%d.%d", internal ? TEXTCOLOR_BLUE : "",
|
||||
sym->SymbolName.GetChars(), vsym->mVersion.major, vsym->mVersion.minor, vsym->mVersion.revision);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7425,7 +7424,6 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||
|
||||
arrayvar.Free(build);
|
||||
start = ExpEmit(build, REGT_POINTER);
|
||||
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
||||
|
||||
|
@ -7445,18 +7443,18 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
arraymemberbase->membervar = origmembervar;
|
||||
arraymemberbase->AddressRequested = origaddrreq;
|
||||
Array->ValueType = origvaluetype;
|
||||
|
||||
arrayvar.Free(build);
|
||||
}
|
||||
else if (Array->ExprType == EFX_ArrayElement && Array->isStaticArray())
|
||||
{
|
||||
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||
bound = ExpEmit(build, REGT_INT);
|
||||
build->Emit(OP_LW, bound.RegNum, arrayvar.RegNum, build->GetConstantInt(myoffsetof(FArray, Count)));
|
||||
|
||||
arrayvar.Free(build);
|
||||
start = ExpEmit(build, REGT_POINTER);
|
||||
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
||||
|
||||
bound = ExpEmit(build, REGT_INT);
|
||||
build->Emit(OP_LW, bound.RegNum, arrayvar.RegNum, build->GetConstantInt(sizeof(void*)));
|
||||
|
||||
nestedarray = true;
|
||||
}
|
||||
else start = arrayvar;
|
||||
|
@ -7514,7 +7512,7 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
else
|
||||
{
|
||||
ExpEmit indexv(index->Emit(build));
|
||||
if (SizeAddr != ~0u)
|
||||
if (SizeAddr != ~0u || nestedarray)
|
||||
{
|
||||
build->Emit(OP_BOUND_R, indexv.RegNum, bound.RegNum);
|
||||
bound.Free(build);
|
||||
|
@ -11352,8 +11350,59 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
if (RegNum == -1)
|
||||
{
|
||||
if (!(VarFlags & VARF_Out)) RegNum = build->Registers[ValueType->GetRegType()].Get(RegCount);
|
||||
else RegNum = build->Registers[REGT_POINTER].Get(1);
|
||||
if (!(VarFlags & VARF_Out))
|
||||
{
|
||||
const int regType = ValueType->GetRegType();
|
||||
assert(regType <= REGT_TYPE);
|
||||
|
||||
auto& registers = build->Registers[regType];
|
||||
RegNum = registers.Get(RegCount);
|
||||
|
||||
// Check for reused registers and clean them if needed
|
||||
bool useDirtyRegisters = false;
|
||||
|
||||
for (int reg = RegNum, end = RegNum + RegCount; reg < end; ++reg)
|
||||
{
|
||||
if (!registers.IsDirty(reg))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
useDirtyRegisters = true;
|
||||
|
||||
switch (regType)
|
||||
{
|
||||
case REGT_INT:
|
||||
build->Emit(OP_LI, reg, 0, 0);
|
||||
break;
|
||||
|
||||
case REGT_FLOAT:
|
||||
build->Emit(OP_LKF, reg, build->GetConstantFloat(0.0));
|
||||
break;
|
||||
|
||||
case REGT_STRING:
|
||||
build->Emit(OP_LKS, reg, build->GetConstantString(nullptr));
|
||||
break;
|
||||
|
||||
case REGT_POINTER:
|
||||
build->Emit(OP_LKP, reg, build->GetConstantAddress(nullptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (useDirtyRegisters)
|
||||
{
|
||||
ScriptPosition.Message(MSG_DEBUGMSG, "Implicit initialization of variable %s", Name.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RegNum = build->Registers[REGT_POINTER].Get(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -783,7 +783,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_Obj, Find, ArrayFind<FDynArray_Obj COMMA
|
|||
|
||||
int ObjArrayPush(FDynArray_Obj *self, DObject *obj)
|
||||
{
|
||||
if (self == nullptr) NullParam("\"self\"");
|
||||
GC::WriteBarrier(obj);
|
||||
return self->Push(obj);
|
||||
}
|
||||
|
@ -812,7 +811,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_Obj, Delete, ArrayDelete<FDynArray_Obj>)
|
|||
|
||||
void ObjArrayInsert(FDynArray_Obj *self,int index, DObject *obj)
|
||||
{
|
||||
if (self == nullptr) NullParam("\"self\"");
|
||||
GC::WriteBarrier(obj);
|
||||
self->Insert(index, obj);
|
||||
}
|
||||
|
|
|
@ -367,6 +367,7 @@ void VMFunctionBuilder::ParamChange(int delta)
|
|||
VMFunctionBuilder::RegAvailability::RegAvailability()
|
||||
{
|
||||
memset(Used, 0, sizeof(Used));
|
||||
memset(Dirty, 0, sizeof(Dirty));
|
||||
MostUsed = 0;
|
||||
}
|
||||
|
||||
|
@ -493,16 +494,19 @@ void VMFunctionBuilder::RegAvailability::Return(int reg, int count)
|
|||
// because for that case it pushes the self pointer a second time without reallocating, so it gets freed twice.
|
||||
//assert((Used[firstword] & mask) == mask);
|
||||
Used[firstword] &= ~mask;
|
||||
Dirty[firstword] |= mask;
|
||||
}
|
||||
else
|
||||
{ // Range is in two words.
|
||||
partialmask = mask << firstbit;
|
||||
assert((Used[firstword] & partialmask) == partialmask);
|
||||
Used[firstword] &= ~partialmask;
|
||||
Dirty[firstword] |= partialmask;
|
||||
|
||||
partialmask = mask >> (32 - firstbit);
|
||||
assert((Used[firstword + 1] & partialmask) == partialmask);
|
||||
Used[firstword + 1] &= ~partialmask;
|
||||
Dirty[firstword + 1] |= partialmask;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,16 @@ public:
|
|||
void Return(int reg, int count);
|
||||
bool Reuse(int regnum);
|
||||
|
||||
bool IsDirty(int reg) const
|
||||
{
|
||||
const int firstword = reg / 32;
|
||||
const int firstbit = reg & 31;
|
||||
return Dirty[firstword] & (1 << firstbit);
|
||||
}
|
||||
|
||||
private:
|
||||
VM_UWORD Used[256/32]; // Bitmap of used registers (bit set means reg is used)
|
||||
VM_UWORD Dirty[256/32];
|
||||
int MostUsed;
|
||||
|
||||
friend class VMFunctionBuilder;
|
||||
|
|
|
@ -181,6 +181,8 @@ static const char *const FlopNames[] =
|
|||
"cosh",
|
||||
"sinh",
|
||||
"tanh",
|
||||
|
||||
"round",
|
||||
};
|
||||
|
||||
static int print_reg(FILE *out, int col, int arg, int mode, int immshift, const VMScriptFunction *func);
|
||||
|
|
|
@ -1148,6 +1148,7 @@ static void ParseActor(FScanner &sc, PNamespace *ns)
|
|||
bag.Namespace = ns;
|
||||
bag.Version = { 2, 0, 0 };
|
||||
bag.fromDecorate = true;
|
||||
bag.ScriptPosition = sc;
|
||||
info = ParseActorHeader(sc, &bag);
|
||||
sc.MustGetToken('{');
|
||||
while (sc.MustGetAnyToken(), sc.TokenType != '}')
|
||||
|
|
|
@ -323,6 +323,28 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
I_Error("Native direct member function calls not implemented\n");
|
||||
}
|
||||
|
||||
if (target->ImplicitArgs > 0)
|
||||
{
|
||||
auto label = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
|
||||
assert(ParamOpcodes.Size() > 0);
|
||||
const VMOP *param = ParamOpcodes[0];
|
||||
const int bc = param->i16u;
|
||||
asmjit::X86Gp *reg = nullptr;
|
||||
|
||||
switch (param->a & REGT_TYPE)
|
||||
{
|
||||
case REGT_STRING: reg = ®S[bc]; break;
|
||||
case REGT_POINTER: reg = ®A[bc]; break;
|
||||
default:
|
||||
I_Error("Unexpected register type for self pointer\n");
|
||||
break;
|
||||
}
|
||||
|
||||
cc.test(*reg, *reg);
|
||||
cc.jz(label);
|
||||
}
|
||||
|
||||
asmjit::CBNode *cursorBefore = cc.getCursor();
|
||||
auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature());
|
||||
call->setInlineComment(target->PrintableName.GetChars());
|
||||
|
|
|
@ -985,6 +985,7 @@ void JitCompiler::EmitFLOP()
|
|||
case FLOP_COSH: func = g_cosh; break;
|
||||
case FLOP_SINH: func = g_sinh; break;
|
||||
case FLOP_TANH: func = g_tanh; break;
|
||||
case FLOP_ROUND: func = round; break;
|
||||
}
|
||||
|
||||
auto result = newResultXmmSd();
|
||||
|
|
|
@ -1741,6 +1741,8 @@ static double DoFLOP(int flop, double v)
|
|||
case FLOP_COSH: return g_cosh(v);
|
||||
case FLOP_SINH: return g_sinh(v);
|
||||
case FLOP_TANH: return g_tanh(v);
|
||||
|
||||
case FLOP_ROUND: return round(v);
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
|
@ -101,6 +101,8 @@ enum
|
|||
FLOP_COSH,
|
||||
FLOP_SINH,
|
||||
FLOP_TANH,
|
||||
|
||||
FLOP_ROUND,
|
||||
};
|
||||
|
||||
// Cast operations
|
||||
|
|
|
@ -1353,7 +1353,7 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
|||
// This is a global variable.
|
||||
if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32;
|
||||
PField *f = Create<PField>(name->Name, thisfieldtype, varflags | VARF_Native | VARF_Static, fd->FieldOffset, fd->BitValue);
|
||||
if (f->Flags & (ZCC_Version | ZCC_Deprecated))
|
||||
if (field->Flags & (ZCC_Version | ZCC_Deprecated))
|
||||
{
|
||||
f->mVersion = field->Version;
|
||||
}
|
||||
|
|
|
@ -933,7 +933,8 @@ void pre_resample(Sample * sp)
|
|||
return;
|
||||
}
|
||||
|
||||
dest = newdata = (sample_t *)safe_malloc((int32_t)(newlen >> (FRACTION_BITS - 1)) + 2);
|
||||
// [EP] Fix the bad allocation count.
|
||||
dest = newdata = (sample_t *)safe_malloc(((int32_t)(newlen >> (FRACTION_BITS - 1)) + 2)*sizeof(sample_t));
|
||||
dest[newlen >> FRACTION_BITS] = 0;
|
||||
|
||||
*dest++ = src[0];
|
||||
|
|
97
src/utility/atterm.cpp
Normal file
97
src/utility/atterm.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
** attern.cpp
|
||||
** Termination handling
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2007 Randy Heit
|
||||
** Copyright 2019 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include "tarray.h"
|
||||
#include "atterm.h"
|
||||
|
||||
static TArray<std::pair<void (*)(void), const char *>> TermFuncs;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// atterm
|
||||
//
|
||||
// Our own atexit because atexit can be problematic under Linux, though I
|
||||
// forget the circumstances that cause trouble.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void addterm(void (*func)(), const char *name)
|
||||
{
|
||||
// Make sure this function wasn't already registered.
|
||||
|
||||
for (auto &term : TermFuncs)
|
||||
{
|
||||
if (term.first == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
TermFuncs.Push(std::make_pair(func, name));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// call_terms
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void call_terms()
|
||||
{
|
||||
for(int i = TermFuncs.Size()-1; i >= 0; i--)
|
||||
{
|
||||
TermFuncs[i].first();
|
||||
}
|
||||
TermFuncs.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// popterm
|
||||
//
|
||||
// Removes the most recently register atterm function.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void popterm()
|
||||
{
|
||||
if (TermFuncs.Size() > 0)
|
||||
{
|
||||
TermFuncs.Pop();
|
||||
}
|
||||
}
|
||||
|
6
src/utility/atterm.h
Normal file
6
src/utility/atterm.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
void addterm (void (*func)(void), const char *name);
|
||||
#define atterm(t) addterm (t, #t)
|
||||
void popterm ();
|
||||
void call_terms();
|
|
@ -86,6 +86,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1984, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mconf.h"
|
||||
|
|
|
@ -70,6 +70,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1984, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.3: March, 1995
|
||||
Copyright 1984, 1995 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mconf.h"
|
||||
|
|
|
@ -42,6 +42,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1985, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mconf.h"
|
||||
|
|
|
@ -57,6 +57,31 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.2: January, 1991
|
||||
Copyright 1984, 1991 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
|
||||
*/
|
||||
|
||||
|
|
|
@ -57,6 +57,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.3: March, 1995
|
||||
Copyright 1984, 1995 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1984, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mconf.h"
|
||||
|
|
|
@ -44,6 +44,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1984, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mconf.h"
|
||||
|
|
|
@ -59,6 +59,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.3: June, 1995
|
||||
Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,31 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.0: April, 1987
|
||||
Copyright 1984, 1987 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
|
||||
*/
|
||||
|
||||
|
|
|
@ -46,6 +46,31 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.1: December, 1988
|
||||
Copyright 1984, 1987, 1988 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
|
||||
*/
|
||||
|
||||
|
|
|
@ -49,6 +49,30 @@
|
|||
/*
|
||||
Cephes Math Library Release 2.8: June, 2000
|
||||
Copyright 1984, 1995, 2000 by Stephen L. Moshier
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the <ORGANIZATION> nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue