mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Merge remote-tracking branch 'gzdoom_upstream/master' into lightmath
# Conflicts: # src/gl/renderer/gl_renderbuffers.cpp # src/gl/renderer/gl_renderbuffers.h # src/gl/renderer/gl_renderer.h # src/gl/scene/gl_scene.cpp # wadsrc/static/language.enu # wadsrc/static/menudef.z
This commit is contained in:
commit
f6bede8374
75 changed files with 4532 additions and 1016 deletions
BIN
docs/licenses/xBRZ.jpg
Normal file
BIN
docs/licenses/xBRZ.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
|
@ -115,49 +115,59 @@ if( WIN32 )
|
||||||
set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib )
|
set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib )
|
||||||
set( NASM_NAMES nasmw nasm )
|
set( NASM_NAMES nasmw nasm )
|
||||||
|
|
||||||
find_path( D3D_INCLUDE_DIR d3d9.h
|
if( NOT MSVC )
|
||||||
PATHS ENV DXSDK_DIR
|
find_path( D3D_INCLUDE_DIR d3d9.h
|
||||||
PATH_SUFFIXES Include )
|
PATHS ENV DXSDK_DIR
|
||||||
if( NOT D3D_INCLUDE_DIR )
|
PATH_SUFFIXES Include )
|
||||||
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
if( NOT D3D_INCLUDE_DIR )
|
||||||
else()
|
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
||||||
include_directories( ${D3D_INCLUDE_DIR} )
|
else()
|
||||||
endif()
|
include_directories( ${D3D_INCLUDE_DIR} )
|
||||||
|
endif()
|
||||||
|
|
||||||
find_path( XINPUT_INCLUDE_DIR xinput.h
|
find_path( XINPUT_INCLUDE_DIR xinput.h
|
||||||
PATHS ENV DXSDK_DIR
|
PATHS ENV DXSDK_DIR
|
||||||
PATH_SUFFIXES Include )
|
PATH_SUFFIXES Include )
|
||||||
if( NOT XINPUT_INCLUDE_DIR )
|
if( NOT XINPUT_INCLUDE_DIR )
|
||||||
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
||||||
add_definitions( -DNO_XINPUT )
|
add_definitions( -DNO_XINPUT )
|
||||||
|
else()
|
||||||
|
include_directories( ${XINPUT_INCLUDE_DIR} )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_library( DX_dxguid_LIBRARY dxguid
|
||||||
|
PATHS ENV DXSDK_DIR
|
||||||
|
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||||
|
find_library( DX_dinput8_LIBRARY dinput8
|
||||||
|
PATHS ENV DXSDK_DIR
|
||||||
|
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||||
|
|
||||||
|
set( DX_LIBS_FOUND YES )
|
||||||
|
if( NOT DX_dxguid_LIBRARY )
|
||||||
|
set( DX_LIBS_FOUND NO )
|
||||||
|
endif()
|
||||||
|
if( NOT DX_dinput8_LIBRARY )
|
||||||
|
set( DX_LIBS_FOUND NO )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if( NOT DX_LIBS_FOUND )
|
||||||
|
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set( DX_LIBS
|
||||||
|
"${DX_dxguid_LIBRARY}"
|
||||||
|
"${DX_dinput8_LIBRARY}"
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
include_directories( ${XINPUT_INCLUDE_DIR} )
|
set( DX_LIBS
|
||||||
|
dxguid
|
||||||
|
dinput8
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_library( DX_dxguid_LIBRARY dxguid
|
set( ZDOOM_LIBS ${DX_LIBS}
|
||||||
PATHS ENV DXSDK_DIR
|
|
||||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
|
||||||
find_library( DX_dinput8_LIBRARY dinput8
|
|
||||||
PATHS ENV DXSDK_DIR
|
|
||||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
|
||||||
|
|
||||||
set( DX_LIBS_FOUND YES )
|
|
||||||
if( NOT DX_dxguid_LIBRARY )
|
|
||||||
set( DX_LIBS_FOUND NO )
|
|
||||||
endif()
|
|
||||||
if( NOT DX_dinput8_LIBRARY )
|
|
||||||
set( DX_LIBS_FOUND NO )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if( NOT DX_LIBS_FOUND )
|
|
||||||
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set( ZDOOM_LIBS
|
|
||||||
wsock32
|
wsock32
|
||||||
winmm
|
winmm
|
||||||
"${DX_dxguid_LIBRARY}"
|
|
||||||
"${DX_dinput8_LIBRARY}"
|
|
||||||
ole32
|
ole32
|
||||||
user32
|
user32
|
||||||
gdi32
|
gdi32
|
||||||
|
@ -660,6 +670,7 @@ set( PLAT_WIN32_SOURCES
|
||||||
win32/i_main.cpp
|
win32/i_main.cpp
|
||||||
win32/i_movie.cpp
|
win32/i_movie.cpp
|
||||||
win32/i_system.cpp
|
win32/i_system.cpp
|
||||||
|
win32/i_specialpaths.cpp
|
||||||
win32/st_start.cpp
|
win32/st_start.cpp
|
||||||
win32/win32gliface.cpp
|
win32/win32gliface.cpp
|
||||||
win32/win32video.cpp )
|
win32/win32video.cpp )
|
||||||
|
@ -679,8 +690,11 @@ set( PLAT_SDL_SOURCES
|
||||||
posix/sdl/sdlvideo.cpp
|
posix/sdl/sdlvideo.cpp
|
||||||
posix/sdl/sdlglvideo.cpp
|
posix/sdl/sdlglvideo.cpp
|
||||||
posix/sdl/st_start.cpp )
|
posix/sdl/st_start.cpp )
|
||||||
|
set( PLAT_UNIX_SOURCES
|
||||||
|
posix/unix/i_specialpaths.cpp )
|
||||||
set( PLAT_OSX_SOURCES
|
set( PLAT_OSX_SOURCES
|
||||||
posix/osx/iwadpicker_cocoa.mm
|
posix/osx/iwadpicker_cocoa.mm
|
||||||
|
posix/osx/i_specialpaths.mm
|
||||||
posix/osx/zdoom.icns )
|
posix/osx/zdoom.icns )
|
||||||
set( PLAT_COCOA_SOURCES
|
set( PLAT_COCOA_SOURCES
|
||||||
posix/cocoa/critsec.cpp
|
posix/cocoa/critsec.cpp
|
||||||
|
@ -697,7 +711,7 @@ set( PLAT_COCOA_SOURCES
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
set( SYSTEM_SOURCES_DIR win32 )
|
set( SYSTEM_SOURCES_DIR win32 )
|
||||||
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
||||||
set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} )
|
set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} ${PLAT_UNIX_SOURCES} )
|
||||||
|
|
||||||
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
# CMake is not set up to compile and link rc files with GCC. :(
|
# CMake is not set up to compile and link rc files with GCC. :(
|
||||||
|
@ -712,12 +726,12 @@ elseif( APPLE )
|
||||||
if( OSX_COCOA_BACKEND )
|
if( OSX_COCOA_BACKEND )
|
||||||
set( SYSTEM_SOURCES_DIR posix posix/cocoa )
|
set( SYSTEM_SOURCES_DIR posix posix/cocoa )
|
||||||
set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} )
|
||||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} )
|
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_UNIX_SOURCES} )
|
||||||
else()
|
else()
|
||||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||||
set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} )
|
||||||
set( PLAT_OSX_SOURCES ${PLAT_OSX_SOURCES} posix/sdl/i_system.mm )
|
set( PLAT_OSX_SOURCES ${PLAT_OSX_SOURCES} posix/sdl/i_system.mm )
|
||||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} )
|
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ${PLAT_UNIX_SOURCES} )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} "${FMOD_LIBRARY}" )
|
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} "${FMOD_LIBRARY}" )
|
||||||
|
@ -727,7 +741,7 @@ elseif( APPLE )
|
||||||
set_source_files_properties( posix/osx/iwadpicker_cocoa.mm PROPERTIES COMPILE_FLAGS -fobjc-exceptions )
|
set_source_files_properties( posix/osx/iwadpicker_cocoa.mm PROPERTIES COMPILE_FLAGS -fobjc-exceptions )
|
||||||
else()
|
else()
|
||||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||||
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_UNIX_SOURCES} )
|
||||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} )
|
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -849,6 +863,7 @@ file( GLOB HEADER_FILES
|
||||||
gl/dynlights/*.h
|
gl/dynlights/*.h
|
||||||
gl/hqnx/*.h
|
gl/hqnx/*.h
|
||||||
gl/hqnx_asm/*.h
|
gl/hqnx_asm/*.h
|
||||||
|
gl/xbr/*.h
|
||||||
gl/models/*.h
|
gl/models/*.h
|
||||||
gl/renderer/*.h
|
gl/renderer/*.h
|
||||||
gl/scene/*.h
|
gl/scene/*.h
|
||||||
|
@ -1072,6 +1087,8 @@ set( FASTMATH_SOURCES
|
||||||
gl/hqnx/hq2x.cpp
|
gl/hqnx/hq2x.cpp
|
||||||
gl/hqnx/hq3x.cpp
|
gl/hqnx/hq3x.cpp
|
||||||
gl/hqnx/hq4x.cpp
|
gl/hqnx/hq4x.cpp
|
||||||
|
gl/xbr/xbrz.cpp
|
||||||
|
gl/xbr/xbrz_old.cpp
|
||||||
gl/textures/gl_hwtexture.cpp
|
gl/textures/gl_hwtexture.cpp
|
||||||
gl/textures/gl_texture.cpp
|
gl/textures/gl_texture.cpp
|
||||||
gl/textures/gl_material.cpp
|
gl/textures/gl_material.cpp
|
||||||
|
@ -1385,7 +1402,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
${FASTMATH_SOURCES}
|
${FASTMATH_SOURCES}
|
||||||
${PCH_SOURCES}
|
${PCH_SOURCES}
|
||||||
x86.cpp
|
x86.cpp
|
||||||
m_specialpaths.cpp
|
|
||||||
strnatcmp.c
|
strnatcmp.c
|
||||||
zstring.cpp
|
zstring.cpp
|
||||||
math/asin.c
|
math/asin.c
|
||||||
|
@ -1543,7 +1559,8 @@ source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/
|
||||||
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
|
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
|
||||||
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")
|
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")
|
||||||
source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+")
|
source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+")
|
||||||
source_group("OpenGL Renderer\\HQ Resize Assembly version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
|
source_group("OpenGL Renderer\\HQ Resize MMX version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
|
||||||
|
source_group("OpenGL Renderer\\XBRZ" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
|
||||||
source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+")
|
source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+")
|
||||||
source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
|
source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
|
||||||
source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+")
|
source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+")
|
||||||
|
@ -1562,6 +1579,7 @@ source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r
|
||||||
source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
|
source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
|
||||||
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")
|
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")
|
||||||
source_group("OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+")
|
source_group("OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+")
|
||||||
|
source_group("Unix Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/unix/.+")
|
||||||
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
|
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
|
||||||
source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
|
source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
|
||||||
source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+")
|
source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+")
|
||||||
|
|
|
@ -283,7 +283,7 @@ enum ActorFlag4
|
||||||
enum ActorFlag5
|
enum ActorFlag5
|
||||||
{
|
{
|
||||||
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
|
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
|
||||||
/* FREE SLOT 0x00000002*/
|
MF5_GETOWNER = 0x00000002,
|
||||||
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
||||||
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
|
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
|
||||||
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
|
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
|
||||||
|
|
|
@ -159,12 +159,37 @@ static int HistSize;
|
||||||
|
|
||||||
CVAR (Float, con_notifytime, 3.f, CVAR_ARCHIVE)
|
CVAR (Float, con_notifytime, 3.f, CVAR_ARCHIVE)
|
||||||
CVAR (Bool, con_centernotify, false, CVAR_ARCHIVE)
|
CVAR (Bool, con_centernotify, false, CVAR_ARCHIVE)
|
||||||
CUSTOM_CVAR (Int, con_scaletext, 0, CVAR_ARCHIVE) // Scale notify text at high resolutions?
|
CUSTOM_CVAR (Int, con_scaletext, 1, CVAR_ARCHIVE) // Scale notify text at high resolutions?
|
||||||
{
|
{
|
||||||
if (self < 0) self = 0;
|
if (self < 0) self = 0;
|
||||||
if (self > 3) self = 3;
|
if (self > 3) self = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Int, con_scale, 0, CVAR_ARCHIVE)
|
||||||
|
{
|
||||||
|
if (self < 0) self = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int active_con_scale()
|
||||||
|
{
|
||||||
|
if (con_scale == 0)
|
||||||
|
return uiscale;
|
||||||
|
else
|
||||||
|
return con_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
int active_con_scaletext()
|
||||||
|
{
|
||||||
|
switch (con_scaletext)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: return 1;
|
||||||
|
case 1: return uiscale;
|
||||||
|
case 2: return 2;
|
||||||
|
case 3: return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE)
|
CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE)
|
||||||
{
|
{
|
||||||
if (self < 0.f) self = 0.f;
|
if (self < 0.f) self = 0.f;
|
||||||
|
@ -493,13 +518,13 @@ void C_AddNotifyString (int printlevel, const char *source)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (con_scaletext)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
default:
|
width = DisplayWidth / CleanXfac;
|
||||||
case 0: width = DisplayWidth; break;
|
}
|
||||||
case 1: width = DisplayWidth / CleanXfac; break;
|
else
|
||||||
case 2: width = DisplayWidth / 2; break;
|
{
|
||||||
case 3: width = DisplayWidth / 4; break;
|
width = DisplayWidth / active_con_scaletext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel)
|
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel)
|
||||||
|
@ -721,7 +746,7 @@ static void C_DrawNotifyText ()
|
||||||
canskip = true;
|
canskip = true;
|
||||||
|
|
||||||
lineadv = SmallFont->GetHeight ();
|
lineadv = SmallFont->GetHeight ();
|
||||||
if (con_scaletext == 1)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
lineadv *= CleanYfac;
|
lineadv *= CleanYfac;
|
||||||
}
|
}
|
||||||
|
@ -755,7 +780,7 @@ static void C_DrawNotifyText ()
|
||||||
else
|
else
|
||||||
color = PrintColors[NotifyStrings[i].PrintLevel];
|
color = PrintColors[NotifyStrings[i].PrintLevel];
|
||||||
|
|
||||||
if (con_scaletext == 1)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
if (!center)
|
if (!center)
|
||||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||||
|
@ -766,7 +791,7 @@ static void C_DrawNotifyText ()
|
||||||
line, NotifyStrings[i].Text, DTA_CleanNoMove, true,
|
line, NotifyStrings[i].Text, DTA_CleanNoMove, true,
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
DTA_AlphaF, alpha, TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 0)
|
else if (active_con_scaletext() == 1)
|
||||||
{
|
{
|
||||||
if (!center)
|
if (!center)
|
||||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||||
|
@ -777,37 +802,20 @@ static void C_DrawNotifyText ()
|
||||||
line, NotifyStrings[i].Text,
|
line, NotifyStrings[i].Text,
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
DTA_AlphaF, alpha, TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
|
||||||
{
|
|
||||||
if (!center)
|
|
||||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
|
||||||
DTA_VirtualWidth, screen->GetWidth() / 4,
|
|
||||||
DTA_VirtualHeight, screen->GetHeight() / 4,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
|
||||||
else
|
|
||||||
screen->DrawText (SmallFont, color, (screen->GetWidth() / 4 -
|
|
||||||
SmallFont->StringWidth (NotifyStrings[i].Text))/4,
|
|
||||||
line, NotifyStrings[i].Text,
|
|
||||||
DTA_VirtualWidth, screen->GetWidth() / 4,
|
|
||||||
DTA_VirtualHeight, screen->GetHeight() / 4,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!center)
|
if (!center)
|
||||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
DTA_AlphaF, alpha, TAG_DONE);
|
||||||
else
|
else
|
||||||
screen->DrawText (SmallFont, color, (screen->GetWidth() / 2 -
|
screen->DrawText (SmallFont, color, (screen->GetWidth() / active_con_scaletext() -
|
||||||
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
|
SmallFont->StringWidth (NotifyStrings[i].Text))/ active_con_scaletext(),
|
||||||
line, NotifyStrings[i].Text,
|
line, NotifyStrings[i].Text,
|
||||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
DTA_AlphaF, alpha, TAG_DONE);
|
DTA_AlphaF, alpha, TAG_DONE);
|
||||||
}
|
}
|
||||||
|
@ -851,9 +859,13 @@ void C_DrawConsole (bool hw2d)
|
||||||
static int oldbottom = 0;
|
static int oldbottom = 0;
|
||||||
int lines, left, offset;
|
int lines, left, offset;
|
||||||
|
|
||||||
|
int textScale = active_con_scale();
|
||||||
|
if (textScale == 0)
|
||||||
|
textScale = CleanXfac;
|
||||||
|
|
||||||
left = LEFTMARGIN;
|
left = LEFTMARGIN;
|
||||||
lines = (ConBottom-ConFont->GetHeight()*2)/ConFont->GetHeight();
|
lines = (ConBottom/textScale-ConFont->GetHeight()*2)/ConFont->GetHeight();
|
||||||
if (-ConFont->GetHeight() + lines*ConFont->GetHeight() > ConBottom - ConFont->GetHeight()*7/2)
|
if (-ConFont->GetHeight() + lines*ConFont->GetHeight() > ConBottom/textScale - ConFont->GetHeight()*7/2)
|
||||||
{
|
{
|
||||||
offset = -ConFont->GetHeight()/2;
|
offset = -ConFont->GetHeight()/2;
|
||||||
lines--;
|
lines--;
|
||||||
|
@ -899,16 +911,26 @@ void C_DrawConsole (bool hw2d)
|
||||||
|
|
||||||
if (ConBottom >= 12)
|
if (ConBottom >= 12)
|
||||||
{
|
{
|
||||||
screen->DrawText (ConFont, CR_ORANGE, SCREENWIDTH - 8 -
|
if (textScale == 1)
|
||||||
ConFont->StringWidth (GetVersionString()),
|
screen->DrawText (ConFont, CR_ORANGE, SCREENWIDTH - 8 -
|
||||||
ConBottom - ConFont->GetHeight() - 4,
|
ConFont->StringWidth (GetVersionString()),
|
||||||
GetVersionString(), TAG_DONE);
|
ConBottom / textScale - ConFont->GetHeight() - 4,
|
||||||
|
GetVersionString(), TAG_DONE);
|
||||||
|
else
|
||||||
|
screen->DrawText(ConFont, CR_ORANGE, SCREENWIDTH / textScale - 8 -
|
||||||
|
ConFont->StringWidth(GetVersionString()),
|
||||||
|
ConBottom / textScale - ConFont->GetHeight() - 4,
|
||||||
|
GetVersionString(),
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
if (TickerMax)
|
if (TickerMax)
|
||||||
{
|
{
|
||||||
char tickstr[256];
|
char tickstr[256];
|
||||||
const int tickerY = ConBottom - ConFont->GetHeight() - 4;
|
const int tickerY = ConBottom / textScale - ConFont->GetHeight() - 4;
|
||||||
size_t i;
|
size_t i;
|
||||||
int tickend = ConCols - SCREENWIDTH / 90 - 6;
|
int tickend = ConCols / textScale - SCREENWIDTH / textScale / 90 - 6;
|
||||||
int tickbegin = 0;
|
int tickbegin = 0;
|
||||||
|
|
||||||
if (TickerLabel)
|
if (TickerLabel)
|
||||||
|
@ -931,11 +953,23 @@ void C_DrawConsole (bool hw2d)
|
||||||
{
|
{
|
||||||
tickstr[tickend+3] = 0;
|
tickstr[tickend+3] = 0;
|
||||||
}
|
}
|
||||||
screen->DrawText (ConFont, CR_BROWN, LEFTMARGIN, tickerY, tickstr, TAG_DONE);
|
if (textScale == 1)
|
||||||
|
screen->DrawText (ConFont, CR_BROWN, LEFTMARGIN, tickerY, tickstr, TAG_DONE);
|
||||||
|
else
|
||||||
|
screen->DrawText (ConFont, CR_BROWN, LEFTMARGIN, tickerY, tickstr,
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
// Draw the marker
|
// Draw the marker
|
||||||
i = LEFTMARGIN+5+tickbegin*8 + Scale (TickerAt, (SDWORD)(tickend - tickbegin)*8, TickerMax);
|
i = LEFTMARGIN+5+tickbegin*8 + Scale (TickerAt, (SDWORD)(tickend - tickbegin)*8, TickerMax);
|
||||||
screen->DrawChar (ConFont, CR_ORANGE, (int)i, tickerY, 0x13, TAG_DONE);
|
if (textScale == 1)
|
||||||
|
screen->DrawChar (ConFont, CR_ORANGE, (int)i, tickerY, 0x13, TAG_DONE);
|
||||||
|
else
|
||||||
|
screen->DrawChar(ConFont, CR_ORANGE, (int)i, tickerY, 0x13,
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
TickerVisible = true;
|
TickerVisible = true;
|
||||||
}
|
}
|
||||||
|
@ -971,18 +1005,28 @@ void C_DrawConsole (bool hw2d)
|
||||||
if (lines > 0)
|
if (lines > 0)
|
||||||
{
|
{
|
||||||
// No more enqueuing because adding new text to the console won't touch the actual print data.
|
// No more enqueuing because adding new text to the console won't touch the actual print data.
|
||||||
conbuffer->FormatText(ConFont, ConWidth);
|
conbuffer->FormatText(ConFont, ConWidth / textScale);
|
||||||
unsigned int consolelines = conbuffer->GetFormattedLineCount();
|
unsigned int consolelines = conbuffer->GetFormattedLineCount();
|
||||||
FBrokenLines **blines = conbuffer->GetLines();
|
FBrokenLines **blines = conbuffer->GetLines();
|
||||||
FBrokenLines **printline = blines + consolelines - 1 - RowAdjust;
|
FBrokenLines **printline = blines + consolelines - 1 - RowAdjust;
|
||||||
|
|
||||||
int bottomline = ConBottom - ConFont->GetHeight()*2 - 4;
|
int bottomline = ConBottom / textScale - ConFont->GetHeight()*2 - 4;
|
||||||
|
|
||||||
ConsoleDrawing = true;
|
ConsoleDrawing = true;
|
||||||
|
|
||||||
for(FBrokenLines **p = printline; p >= blines && lines > 0; p--, lines--)
|
for(FBrokenLines **p = printline; p >= blines && lines > 0; p--, lines--)
|
||||||
{
|
{
|
||||||
screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text, TAG_DONE);
|
if (textScale == 1)
|
||||||
|
{
|
||||||
|
screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text, TAG_DONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text,
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleDrawing = false;
|
ConsoleDrawing = false;
|
||||||
|
@ -997,21 +1041,52 @@ void C_DrawConsole (bool hw2d)
|
||||||
FString command((char *)&CmdLine[2+CmdLine[259]]);
|
FString command((char *)&CmdLine[2+CmdLine[259]]);
|
||||||
int cursorpos = CmdLine[1] - CmdLine[259];
|
int cursorpos = CmdLine[1] - CmdLine[259];
|
||||||
|
|
||||||
screen->DrawChar (ConFont, CR_ORANGE, left, bottomline, '\x1c', TAG_DONE);
|
if (textScale == 1)
|
||||||
screen->DrawText (ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline,
|
|
||||||
command, TAG_DONE);
|
|
||||||
|
|
||||||
if (cursoron)
|
|
||||||
{
|
{
|
||||||
screen->DrawChar (ConFont, CR_YELLOW, left + ConFont->GetCharWidth(0x1c) + cursorpos * ConFont->GetCharWidth(0xb),
|
screen->DrawChar(ConFont, CR_ORANGE, left, bottomline, '\x1c', TAG_DONE);
|
||||||
bottomline, '\xb', TAG_DONE);
|
screen->DrawText(ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline,
|
||||||
|
command, TAG_DONE);
|
||||||
|
|
||||||
|
if (cursoron)
|
||||||
|
{
|
||||||
|
screen->DrawChar(ConFont, CR_YELLOW, left + ConFont->GetCharWidth(0x1c) + cursorpos * ConFont->GetCharWidth(0xb),
|
||||||
|
bottomline, '\xb', TAG_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->DrawChar(ConFont, CR_ORANGE, left, bottomline, '\x1c',
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
|
screen->DrawText(ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline,
|
||||||
|
command,
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
|
if (cursoron)
|
||||||
|
{
|
||||||
|
screen->DrawChar(ConFont, CR_YELLOW, left + ConFont->GetCharWidth(0x1c) + cursorpos * ConFont->GetCharWidth(0xb),
|
||||||
|
bottomline, '\xb',
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (RowAdjust && ConBottom >= ConFont->GetHeight()*7/2)
|
if (RowAdjust && ConBottom >= ConFont->GetHeight()*7/2)
|
||||||
{
|
{
|
||||||
// Indicate that the view has been scrolled up (10)
|
// Indicate that the view has been scrolled up (10)
|
||||||
// and if we can scroll no further (12)
|
// and if we can scroll no further (12)
|
||||||
screen->DrawChar (ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE);
|
if (textScale == 1)
|
||||||
|
screen->DrawChar (ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE);
|
||||||
|
else
|
||||||
|
screen->DrawChar(ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10,
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ EXTERN_CVAR (Bool, sb_cooperative_enable)
|
||||||
EXTERN_CVAR (Bool, sb_deathmatch_enable)
|
EXTERN_CVAR (Bool, sb_deathmatch_enable)
|
||||||
EXTERN_CVAR (Bool, sb_teamdeathmatch_enable)
|
EXTERN_CVAR (Bool, sb_teamdeathmatch_enable)
|
||||||
|
|
||||||
|
int active_con_scaletext();
|
||||||
|
|
||||||
// Public data
|
// Public data
|
||||||
|
|
||||||
void CT_Init ();
|
void CT_Init ();
|
||||||
|
@ -224,7 +226,7 @@ void CT_Drawer (void)
|
||||||
int i, x, scalex, y, promptwidth;
|
int i, x, scalex, y, promptwidth;
|
||||||
|
|
||||||
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
||||||
if (con_scaletext == 1)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
scalex = CleanXfac;
|
scalex = CleanXfac;
|
||||||
y *= CleanYfac;
|
y *= CleanYfac;
|
||||||
|
@ -235,25 +237,17 @@ void CT_Drawer (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int screen_width, screen_height, st_y;
|
int screen_width, screen_height, st_y;
|
||||||
switch (con_scaletext)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
screen_width = SCREENWIDTH;
|
screen_width = SCREENWIDTH;
|
||||||
screen_height = SCREENHEIGHT;
|
screen_height = SCREENHEIGHT;
|
||||||
st_y = ST_Y;
|
st_y = ST_Y;
|
||||||
break;
|
}
|
||||||
case 2:
|
else
|
||||||
screen_width = SCREENWIDTH / 2;
|
{
|
||||||
screen_height = SCREENHEIGHT / 2;
|
screen_width = SCREENWIDTH / active_con_scaletext();
|
||||||
st_y = ST_Y / 2;
|
screen_height = SCREENHEIGHT / active_con_scaletext();
|
||||||
break;
|
st_y = ST_Y / active_con_scaletext();
|
||||||
case 3:
|
|
||||||
screen_width = SCREENWIDTH / 4;
|
|
||||||
screen_height = SCREENHEIGHT / 4;
|
|
||||||
st_y = ST_Y / 4;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
||||||
|
@ -280,10 +274,10 @@ void CT_Drawer (void)
|
||||||
// draw the prompt, text, and cursor
|
// draw the prompt, text, and cursor
|
||||||
ChatQueue[len] = SmallFont->GetCursor();
|
ChatQueue[len] = SmallFont->GetCursor();
|
||||||
ChatQueue[len+1] = '\0';
|
ChatQueue[len+1] = '\0';
|
||||||
if (con_scaletext < 2)
|
if (active_con_scaletext() < 2)
|
||||||
{
|
{
|
||||||
screen->DrawText (SmallFont, CR_GREEN, 0, y, prompt, DTA_CleanNoMove, *con_scaletext, TAG_DONE);
|
screen->DrawText (SmallFont, CR_GREEN, 0, y, prompt, DTA_CleanNoMove, active_con_scaletext() == 0, TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GREY, promptwidth, y, (char *)(ChatQueue + i), DTA_CleanNoMove, *con_scaletext, TAG_DONE);
|
screen->DrawText (SmallFont, CR_GREY, promptwidth, y, (char *)(ChatQueue + i), DTA_CleanNoMove, active_con_scaletext() == 0, TAG_DONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,8 +166,14 @@ void AFastProjectile::Effect()
|
||||||
if (trail != NULL)
|
if (trail != NULL)
|
||||||
{
|
{
|
||||||
AActor *act = Spawn (trail, PosAtZ(hitz), ALLOW_REPLACE);
|
AActor *act = Spawn (trail, PosAtZ(hitz), ALLOW_REPLACE);
|
||||||
if (act != NULL)
|
if (act != nullptr)
|
||||||
{
|
{
|
||||||
|
if ((flags5 & MF5_GETOWNER) && (target != nullptr))
|
||||||
|
act->target = target;
|
||||||
|
else
|
||||||
|
act->target = this;
|
||||||
|
|
||||||
|
act->Angles.Pitch = Angles.Pitch;
|
||||||
act->Angles.Yaw = Angles.Yaw;
|
act->Angles.Yaw = Angles.Yaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ double DEarthquake::GetModWave(double waveMultiplier) const
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
double DEarthquake::GetModIntensity(double intensity) const
|
double DEarthquake::GetModIntensity(double intensity, bool fake) const
|
||||||
{
|
{
|
||||||
assert(m_CountdownStart >= m_Countdown);
|
assert(m_CountdownStart >= m_Countdown);
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ double DEarthquake::GetModIntensity(double intensity) const
|
||||||
}
|
}
|
||||||
scalar = (scalar > divider) ? divider : scalar;
|
scalar = (scalar > divider) ? divider : scalar;
|
||||||
|
|
||||||
if (m_Flags & QF_FULLINTENSITY)
|
if (!fake && (m_Flags & QF_FULLINTENSITY))
|
||||||
{
|
{
|
||||||
scalar *= 2;
|
scalar *= 2;
|
||||||
}
|
}
|
||||||
|
@ -273,64 +273,69 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
|
||||||
DEarthquake *quake;
|
DEarthquake *quake;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
while ( (quake = iterator.Next()) != NULL)
|
while ( (quake = iterator.Next()) != nullptr)
|
||||||
{
|
{
|
||||||
if (quake->m_Spot != NULL)
|
if (quake->m_Spot != nullptr)
|
||||||
{
|
{
|
||||||
double dist = quake->m_Spot->Distance2D (victim, true);
|
const double dist = quake->m_Spot->Distance2D(victim, true);
|
||||||
if (dist < quake->m_TremorRadius)
|
if (dist < quake->m_TremorRadius)
|
||||||
{
|
{
|
||||||
const double falloff = quake->GetFalloff(dist);
|
|
||||||
const double rfalloff = (quake->m_RollIntensity != 0) ? falloff : 0.;
|
|
||||||
++count;
|
++count;
|
||||||
double x = quake->GetModIntensity(quake->m_Intensity.X);
|
const double falloff = quake->GetFalloff(dist);
|
||||||
double y = quake->GetModIntensity(quake->m_Intensity.Y);
|
const double r = quake->GetModIntensity(quake->m_RollIntensity);
|
||||||
double z = quake->GetModIntensity(quake->m_Intensity.Z);
|
const double strength = quake->GetModIntensity(1.0, true);
|
||||||
double r = quake->GetModIntensity(quake->m_RollIntensity);
|
DVector3 intensity;
|
||||||
|
intensity.X = quake->GetModIntensity(quake->m_Intensity.X);
|
||||||
|
intensity.Y = quake->GetModIntensity(quake->m_Intensity.Y);
|
||||||
|
intensity.Z = quake->GetModIntensity(quake->m_Intensity.Z);
|
||||||
|
|
||||||
if (!(quake->m_Flags & QF_WAVE))
|
if (!(quake->m_Flags & QF_WAVE))
|
||||||
{
|
{
|
||||||
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||||
jiggers.RFalloff = MAX(rfalloff, jiggers.RFalloff);
|
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity) * jiggers.Falloff;
|
||||||
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity);
|
|
||||||
|
intensity *= jiggers.Falloff;
|
||||||
if (quake->m_Flags & QF_RELATIVE)
|
if (quake->m_Flags & QF_RELATIVE)
|
||||||
{
|
{
|
||||||
jiggers.RelIntensity.X = MAX(x, jiggers.RelIntensity.X);
|
jiggers.RelIntensity.X = MAX(intensity.X, jiggers.RelIntensity.X);
|
||||||
jiggers.RelIntensity.Y = MAX(y, jiggers.RelIntensity.Y);
|
jiggers.RelIntensity.Y = MAX(intensity.Y, jiggers.RelIntensity.Y);
|
||||||
jiggers.RelIntensity.Z = MAX(z, jiggers.RelIntensity.Z);
|
jiggers.RelIntensity.Z = MAX(intensity.Z, jiggers.RelIntensity.Z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jiggers.Intensity.X = MAX(x, jiggers.Intensity.X);
|
jiggers.Intensity.X = MAX(intensity.X, jiggers.Intensity.X);
|
||||||
jiggers.Intensity.Y = MAX(y, jiggers.Intensity.Y);
|
jiggers.Intensity.Y = MAX(intensity.Y, jiggers.Intensity.Y);
|
||||||
jiggers.Intensity.Z = MAX(z, jiggers.Intensity.Z);
|
jiggers.Intensity.Z = MAX(intensity.Z, jiggers.Intensity.Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jiggers.WFalloff = MAX(falloff, jiggers.WFalloff);
|
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||||
jiggers.RWFalloff = MAX(rfalloff, jiggers.RWFalloff);
|
jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave) * jiggers.Falloff * strength;
|
||||||
jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave);
|
|
||||||
double mx = x * quake->GetModWave(quake->m_WaveSpeed.X);
|
|
||||||
double my = y * quake->GetModWave(quake->m_WaveSpeed.Y);
|
intensity.X *= quake->GetModWave(quake->m_WaveSpeed.X);
|
||||||
double mz = z * quake->GetModWave(quake->m_WaveSpeed.Z);
|
intensity.Y *= quake->GetModWave(quake->m_WaveSpeed.Y);
|
||||||
|
intensity.Z *= quake->GetModWave(quake->m_WaveSpeed.Z);
|
||||||
|
intensity *= strength * jiggers.Falloff;
|
||||||
|
|
||||||
// [RH] This only gives effect to the last sine quake. I would
|
// [RH] This only gives effect to the last sine quake. I would
|
||||||
// prefer if some way was found to make multiples coexist
|
// prefer if some way was found to make multiples coexist
|
||||||
// peacefully, but just summing them together is undesirable
|
// peacefully, but just summing them together is undesirable
|
||||||
// because they could cancel each other out depending on their
|
// because they could cancel each other out depending on their
|
||||||
// relative phases.
|
// relative phases.
|
||||||
|
|
||||||
|
// [MC] Now does so. And they stack rather well. I'm a little
|
||||||
|
// surprised at how easy it was.
|
||||||
|
|
||||||
|
|
||||||
if (quake->m_Flags & QF_RELATIVE)
|
if (quake->m_Flags & QF_RELATIVE)
|
||||||
{
|
{
|
||||||
jiggers.RelOffset.X = mx;
|
jiggers.RelOffset += intensity;
|
||||||
jiggers.RelOffset.Y = my;
|
|
||||||
jiggers.RelOffset.Z = mz;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jiggers.Offset.X = mx;
|
jiggers.Offset += intensity;
|
||||||
jiggers.Offset.Y = my;
|
|
||||||
jiggers.Offset.Z = mz;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ struct FQuakeJiggers
|
||||||
DVector3 RelIntensity;
|
DVector3 RelIntensity;
|
||||||
DVector3 Offset;
|
DVector3 Offset;
|
||||||
DVector3 RelOffset;
|
DVector3 RelOffset;
|
||||||
double Falloff, WFalloff, RFalloff, RWFalloff;
|
double Falloff;
|
||||||
double RollIntensity, RollWave;
|
double RollIntensity, RollWave;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,8 +180,7 @@ public:
|
||||||
int m_Highpoint, m_MiniCount;
|
int m_Highpoint, m_MiniCount;
|
||||||
double m_RollIntensity, m_RollWave;
|
double m_RollIntensity, m_RollWave;
|
||||||
|
|
||||||
|
double GetModIntensity(double intensity, bool fake = false) const;
|
||||||
double GetModIntensity(double intensity) const;
|
|
||||||
double GetModWave(double waveMultiplier) const;
|
double GetModWave(double waveMultiplier) const;
|
||||||
double GetFalloff(double dist) const;
|
double GetFalloff(double dist) const;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Int, con_scaletext)
|
EXTERN_CVAR(Int, con_scaletext)
|
||||||
|
int active_con_scaletext();
|
||||||
|
|
||||||
IMPLEMENT_POINTY_CLASS (DHUDMessage)
|
IMPLEMENT_POINTY_CLASS (DHUDMessage)
|
||||||
DECLARE_POINTER(Next)
|
DECLARE_POINTER(Next)
|
||||||
|
@ -260,13 +261,10 @@ void DHUDMessage::ResetText (const char *text)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (con_scaletext)
|
switch (active_con_scaletext())
|
||||||
{
|
{
|
||||||
default:
|
case 0: width = SCREENWIDTH / CleanXfac; break;
|
||||||
case 0: width = SCREENWIDTH; break;
|
default: width = SCREENWIDTH / active_con_scaletext(); break;
|
||||||
case 1: width = SCREENWIDTH / CleanXfac; break;
|
|
||||||
case 2: width = SCREENWIDTH / 2; break;
|
|
||||||
case 3: width = SCREENWIDTH / 4; break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +330,7 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
||||||
|
|
||||||
int screen_width = SCREENWIDTH;
|
int screen_width = SCREENWIDTH;
|
||||||
int screen_height = SCREENHEIGHT;
|
int screen_height = SCREENHEIGHT;
|
||||||
if (HUDWidth == 0 && con_scaletext==1)
|
if (HUDWidth == 0 && active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
clean = true;
|
clean = true;
|
||||||
xscale = CleanXfac;
|
xscale = CleanXfac;
|
||||||
|
@ -341,17 +339,11 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xscale = yscale = 1;
|
xscale = yscale = 1;
|
||||||
if (HUDWidth==0 && con_scaletext==2)
|
if (HUDWidth == 0)
|
||||||
{
|
{
|
||||||
screen_width/=2;
|
screen_width /= active_con_scaletext();
|
||||||
screen_height/=2;
|
screen_height /= active_con_scaletext();
|
||||||
bottom/=2;
|
bottom /= active_con_scaletext();
|
||||||
}
|
|
||||||
else if (HUDWidth==0 && con_scaletext==3)
|
|
||||||
{
|
|
||||||
screen_width/=4;
|
|
||||||
screen_height/=4;
|
|
||||||
bottom/=4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +445,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
||||||
{
|
{
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
if (con_scaletext <= 1)
|
if (active_con_scaletext() <= 1)
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_CleanNoMove, clean,
|
DTA_CleanNoMove, clean,
|
||||||
|
@ -461,21 +453,11 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
|
||||||
{
|
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
|
||||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
|
||||||
DTA_AlphaF, Alpha,
|
|
||||||
DTA_RenderStyle, Style,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||||
DTA_AlphaF, Alpha,
|
DTA_AlphaF, Alpha,
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
|
@ -566,7 +548,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
||||||
float trans = float(Alpha * -(Tics - FadeOutTics) / FadeOutTics);
|
float trans = float(Alpha * -(Tics - FadeOutTics) / FadeOutTics);
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
if (con_scaletext <= 1)
|
if (active_con_scaletext() <= 1)
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_CleanNoMove, clean,
|
DTA_CleanNoMove, clean,
|
||||||
|
@ -574,21 +556,11 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
|
||||||
{
|
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
|
||||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
|
||||||
DTA_AlphaF, trans,
|
|
||||||
DTA_RenderStyle, Style,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||||
DTA_AlphaF, trans,
|
DTA_AlphaF, trans,
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
|
@ -676,7 +648,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
||||||
float trans = float(Alpha * Tics / FadeInTics);
|
float trans = float(Alpha * Tics / FadeInTics);
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
if (con_scaletext <= 1)
|
if (active_con_scaletext() <= 1)
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_CleanNoMove, clean,
|
DTA_CleanNoMove, clean,
|
||||||
|
@ -684,21 +656,11 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
|
||||||
{
|
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
|
||||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
|
||||||
DTA_AlphaF, trans,
|
|
||||||
DTA_RenderStyle, Style,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||||
DTA_AlphaF, trans,
|
DTA_AlphaF, trans,
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
|
@ -864,7 +826,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
||||||
{
|
{
|
||||||
if (hudheight == 0)
|
if (hudheight == 0)
|
||||||
{
|
{
|
||||||
if (con_scaletext <= 1)
|
if (active_con_scaletext() <= 1)
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_CleanNoMove, clean,
|
DTA_CleanNoMove, clean,
|
||||||
|
@ -873,22 +835,11 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
||||||
DTA_RenderStyle, Style,
|
DTA_RenderStyle, Style,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
|
||||||
{
|
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
|
||||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
|
||||||
DTA_KeepRatio, true,
|
|
||||||
DTA_TextLen, LineVisible,
|
|
||||||
DTA_AlphaF, Alpha,
|
|
||||||
DTA_RenderStyle, Style,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
DTA_TextLen, LineVisible,
|
DTA_TextLen, LineVisible,
|
||||||
DTA_AlphaF, Alpha,
|
DTA_AlphaF, Alpha,
|
||||||
|
|
|
@ -1013,7 +1013,15 @@ public:
|
||||||
void ScreenSizeChanged()
|
void ScreenSizeChanged()
|
||||||
{
|
{
|
||||||
Super::ScreenSizeChanged();
|
Super::ScreenSizeChanged();
|
||||||
V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY);
|
if (uiscale > 0)
|
||||||
|
{
|
||||||
|
script->cleanX = uiscale;
|
||||||
|
script->cleanY = uiscale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw (EHudState state)
|
void Draw (EHudState state)
|
||||||
|
|
|
@ -3464,6 +3464,78 @@ class CommandIfWaterLevel : public SBarInfoNegatableFlowControl
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class CommandIfCVarInt : public SBarInfoNegatableFlowControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandIfCVarInt(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
|
||||||
|
equalcomp(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
|
||||||
|
{
|
||||||
|
if(!sc.CheckToken(TK_StringConst))
|
||||||
|
{
|
||||||
|
sc.MustGetToken(TK_Identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvarname = sc.String;
|
||||||
|
cvar = FindCVar(cvarname, nullptr);
|
||||||
|
|
||||||
|
if (cvar != nullptr)
|
||||||
|
{
|
||||||
|
ECVarType cvartype = cvar->GetRealType();
|
||||||
|
|
||||||
|
if (cvartype == CVAR_Bool || cvartype == CVAR_Int)
|
||||||
|
{
|
||||||
|
sc.MustGetToken(',');
|
||||||
|
sc.MustGetToken(TK_IntConst);
|
||||||
|
value = sc.Number;
|
||||||
|
|
||||||
|
if (sc.CheckToken(','))
|
||||||
|
{
|
||||||
|
sc.MustGetToken(TK_Identifier);
|
||||||
|
|
||||||
|
if(sc.Compare("equal"))
|
||||||
|
{
|
||||||
|
equalcomp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc.ScriptError("Type mismatch: console variable '%s' is not of type 'bool' or 'int'.", cvarname.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc.ScriptError("Unknown console variable '%s'.", cvarname.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
|
||||||
|
{
|
||||||
|
SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
cvar = GetCVar(statusBar->CPlayer->mo, cvarname);
|
||||||
|
|
||||||
|
if (cvar != nullptr)
|
||||||
|
{
|
||||||
|
int cvarvalue = cvar->GetGenericRep(CVAR_Int).Int;
|
||||||
|
result = equalcomp ? cvarvalue == value : cvarvalue >= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTruth(result, block, statusBar);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
FString cvarname;
|
||||||
|
FBaseCVar *cvar;
|
||||||
|
int value;
|
||||||
|
bool equalcomp;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const char *SBarInfoCommandNames[] =
|
static const char *SBarInfoCommandNames[] =
|
||||||
{
|
{
|
||||||
"drawimage", "drawnumber", "drawswitchableimage",
|
"drawimage", "drawnumber", "drawswitchableimage",
|
||||||
|
@ -3474,7 +3546,7 @@ static const char *SBarInfoCommandNames[] =
|
||||||
"isselected", "usesammo", "usessecondaryammo",
|
"isselected", "usesammo", "usessecondaryammo",
|
||||||
"hasweaponpiece", "inventorybarnotvisible",
|
"hasweaponpiece", "inventorybarnotvisible",
|
||||||
"weaponammo", "ininventory", "alpha", "ifhealth",
|
"weaponammo", "ininventory", "alpha", "ifhealth",
|
||||||
"ifinvulnerable", "ifwaterlevel",
|
"ifinvulnerable", "ifwaterlevel", "ifcvarint",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3488,7 +3560,7 @@ enum SBarInfoCommands
|
||||||
SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO,
|
SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO,
|
||||||
SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE,
|
SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE,
|
||||||
SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH,
|
SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH,
|
||||||
SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL,
|
SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL, SBARINFO_IFCVARINT,
|
||||||
};
|
};
|
||||||
|
|
||||||
SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
|
SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
|
||||||
|
@ -3524,6 +3596,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
|
||||||
case SBARINFO_IFHEALTH: return new CommandIfHealth(script);
|
case SBARINFO_IFHEALTH: return new CommandIfHealth(script);
|
||||||
case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script);
|
case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script);
|
||||||
case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script);
|
case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script);
|
||||||
|
case SBARINFO_IFCVARINT: return new CommandIfCVarInt(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.ScriptError("Unknown command '%s'.\n", sc.String);
|
sc.ScriptError("Unknown command '%s'.\n", sc.String);
|
||||||
|
|
|
@ -66,7 +66,7 @@ EXTERN_CVAR (Int, screenblocks)
|
||||||
EXTERN_CVAR (Bool, am_showtime)
|
EXTERN_CVAR (Bool, am_showtime)
|
||||||
EXTERN_CVAR (Bool, am_showtotaltime)
|
EXTERN_CVAR (Bool, am_showtotaltime)
|
||||||
|
|
||||||
CVAR(Int,hud_althudscale, 2, CVAR_ARCHIVE) // Scale the hud to 640x400?
|
CVAR(Int,hud_althudscale, 4, CVAR_ARCHIVE) // Scale the hud to 640x400?
|
||||||
CVAR(Bool,hud_althud, false, CVAR_ARCHIVE) // Enable/Disable the alternate HUD
|
CVAR(Bool,hud_althud, false, CVAR_ARCHIVE) // Enable/Disable the alternate HUD
|
||||||
|
|
||||||
// These are intentionally not the same as in the automap!
|
// These are intentionally not the same as in the automap!
|
||||||
|
@ -118,7 +118,7 @@ static int hudwidth, hudheight; // current width/height for HUD display
|
||||||
static int statspace;
|
static int statspace;
|
||||||
|
|
||||||
DVector2 AM_GetPosition();
|
DVector2 AM_GetPosition();
|
||||||
|
int active_con_scaletext();
|
||||||
|
|
||||||
FTextureID GetHUDIcon(PClassInventory *cls)
|
FTextureID GetHUDIcon(PClassInventory *cls)
|
||||||
{
|
{
|
||||||
|
@ -886,22 +886,15 @@ static void DrawCoordinates(player_t * CPlayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
int vwidth, vheight;
|
int vwidth, vheight;
|
||||||
switch (con_scaletext)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
default:
|
vwidth = SCREENWIDTH / 2;
|
||||||
case 0:
|
vheight = SCREENHEIGHT / 2;
|
||||||
vwidth = SCREENWIDTH;
|
}
|
||||||
vheight = SCREENHEIGHT;
|
else
|
||||||
break;
|
{
|
||||||
case 1:
|
vwidth = SCREENWIDTH / active_con_scaletext();
|
||||||
case 2:
|
vheight = SCREENHEIGHT / active_con_scaletext();
|
||||||
vwidth = SCREENWIDTH/2;
|
|
||||||
vheight = SCREENHEIGHT/2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
vwidth = SCREENWIDTH/4;
|
|
||||||
vheight = SCREENHEIGHT/4;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||||
|
@ -1090,7 +1083,20 @@ void DrawHUD()
|
||||||
if (hud_althudscale && SCREENWIDTH>640)
|
if (hud_althudscale && SCREENWIDTH>640)
|
||||||
{
|
{
|
||||||
hudwidth=SCREENWIDTH/2;
|
hudwidth=SCREENWIDTH/2;
|
||||||
if (hud_althudscale == 3)
|
if (hud_althudscale == 4)
|
||||||
|
{
|
||||||
|
if (uiscale == 0)
|
||||||
|
{
|
||||||
|
hudwidth = CleanWidth;
|
||||||
|
hudheight = CleanHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hudwidth = SCREENWIDTH / uiscale;
|
||||||
|
hudheight = SCREENHEIGHT / uiscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hud_althudscale == 3)
|
||||||
{
|
{
|
||||||
hudwidth = SCREENWIDTH / 4;
|
hudwidth = SCREENWIDTH / 4;
|
||||||
hudheight = SCREENHEIGHT / 4;
|
hudheight = SCREENHEIGHT / 4;
|
||||||
|
|
|
@ -74,6 +74,8 @@ EXTERN_CVAR (Bool, am_showtotaltime)
|
||||||
EXTERN_CVAR (Bool, noisedebug)
|
EXTERN_CVAR (Bool, noisedebug)
|
||||||
EXTERN_CVAR (Int, con_scaletext)
|
EXTERN_CVAR (Int, con_scaletext)
|
||||||
|
|
||||||
|
int active_con_scaletext();
|
||||||
|
|
||||||
DBaseStatusBar *StatusBar;
|
DBaseStatusBar *StatusBar;
|
||||||
|
|
||||||
extern int setblocks;
|
extern int setblocks;
|
||||||
|
@ -1240,17 +1242,17 @@ void DBaseStatusBar::Draw (EHudState state)
|
||||||
int xpos;
|
int xpos;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (con_scaletext == 0)
|
if (active_con_scaletext() == 1)
|
||||||
{
|
{
|
||||||
vwidth = SCREENWIDTH;
|
vwidth = SCREENWIDTH;
|
||||||
vheight = SCREENHEIGHT;
|
vheight = SCREENHEIGHT;
|
||||||
xpos = vwidth - 80;
|
xpos = vwidth - 80;
|
||||||
y = ::ST_Y - height;
|
y = ::ST_Y - height;
|
||||||
}
|
}
|
||||||
else if (con_scaletext == 3)
|
else if (active_con_scaletext() > 1)
|
||||||
{
|
{
|
||||||
vwidth = SCREENWIDTH/4;
|
vwidth = SCREENWIDTH / active_con_scaletext();
|
||||||
vheight = SCREENHEIGHT/4;
|
vheight = SCREENHEIGHT / active_con_scaletext();
|
||||||
xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||||
y = ::ST_Y/4 - height;
|
y = ::ST_Y/4 - height;
|
||||||
}
|
}
|
||||||
|
@ -1264,9 +1266,9 @@ void DBaseStatusBar::Draw (EHudState state)
|
||||||
|
|
||||||
if (gameinfo.gametype == GAME_Strife)
|
if (gameinfo.gametype == GAME_Strife)
|
||||||
{
|
{
|
||||||
if (con_scaletext == 0)
|
if (active_con_scaletext() == 1)
|
||||||
y -= height * 4;
|
y -= height * 4;
|
||||||
else if (con_scaletext == 3)
|
else if (active_con_scaletext() > 3)
|
||||||
y -= height;
|
y -= height;
|
||||||
else
|
else
|
||||||
y -= height * 2;
|
y -= height * 2;
|
||||||
|
@ -1400,27 +1402,15 @@ void DBaseStatusBar::DrawLog ()
|
||||||
if (CPlayer->LogText.IsNotEmpty())
|
if (CPlayer->LogText.IsNotEmpty())
|
||||||
{
|
{
|
||||||
// This uses the same scaling as regular HUD messages
|
// This uses the same scaling as regular HUD messages
|
||||||
switch (con_scaletext)
|
if (active_con_scaletext() == 0)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
hudwidth = SCREENWIDTH;
|
|
||||||
hudheight = SCREENHEIGHT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
hudwidth = SCREENWIDTH / CleanXfac;
|
hudwidth = SCREENWIDTH / CleanXfac;
|
||||||
hudheight = SCREENHEIGHT / CleanYfac;
|
hudheight = SCREENHEIGHT / CleanYfac;
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
case 2:
|
{
|
||||||
hudwidth = SCREENWIDTH / 2;
|
hudwidth = SCREENWIDTH / active_con_scaletext();
|
||||||
hudheight = SCREENHEIGHT / 2;
|
hudheight = SCREENHEIGHT / active_con_scaletext();
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
hudwidth = SCREENWIDTH / 4;
|
|
||||||
hudheight = SCREENHEIGHT / 4;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int linelen = hudwidth<640? Scale(hudwidth,9,10)-40 : 560;
|
int linelen = hudwidth<640? Scale(hudwidth,9,10)-40 : 560;
|
||||||
|
|
|
@ -552,7 +552,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave)
|
||||||
|
|
||||||
// If the torpedo hit the ceiling, it should still spawn the wave
|
// If the torpedo hit the ceiling, it should still spawn the wave
|
||||||
savedz = self->Z();
|
savedz = self->Z();
|
||||||
if (wavedef && self->ceilingz < wavedef->Top())
|
if (wavedef && self->ceilingz < self->Z() + wavedef->Height)
|
||||||
{
|
{
|
||||||
self->SetZ(self->ceilingz - wavedef->Height);
|
self->SetZ(self->ceilingz - wavedef->Height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Do some tinkering with the menus so that certain options only appear
|
// Do some tinkering with the menus so that certain options only appear
|
||||||
|
@ -384,7 +386,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
||||||
DVector3 lpos = light->PosRelative(group);
|
DVector3 lpos = light->PosRelative(group);
|
||||||
|
|
||||||
float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y));
|
float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y));
|
||||||
float radius = (light->GetRadius() * gl_lights_size);
|
float radius = light->GetRadius();
|
||||||
|
|
||||||
if (radius <= 0.f) return false;
|
if (radius <= 0.f) return false;
|
||||||
if (dist > radius) return false;
|
if (dist > radius) return false;
|
||||||
|
@ -415,9 +417,9 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
||||||
|
|
||||||
float cs = 1.0f - (dist / radius);
|
float cs = 1.0f - (dist / radius);
|
||||||
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
|
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
|
||||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
float r = light->GetRed() / 255.0f * cs;
|
||||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
float g = light->GetGreen() / 255.0f * cs;
|
||||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
float b = light->GetBlue() / 255.0f * cs;
|
||||||
|
|
||||||
if (light->IsSubtractive())
|
if (light->IsSubtractive())
|
||||||
{
|
{
|
||||||
|
@ -478,7 +480,7 @@ bool GLWall::PutWallCompat(int passflag)
|
||||||
if (sub->lighthead == nullptr) return false;
|
if (sub->lighthead == nullptr) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool foggy = !gl_isBlack(Colormap.FadeColor) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
bool foggy = gl_CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||||
bool masked = passflag == 2 && gltexture->isMasked();
|
bool masked = passflag == 2 && gltexture->isMasked();
|
||||||
|
|
||||||
int list = list_indices[masked][foggy];
|
int list = list_indices[masked][foggy];
|
||||||
|
|
|
@ -10,6 +10,15 @@ struct secplane_t;
|
||||||
struct subsector_t;
|
struct subsector_t;
|
||||||
struct sector_t;
|
struct sector_t;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
VATTR_VERTEX_BIT,
|
||||||
|
VATTR_TEXCOORD_BIT,
|
||||||
|
VATTR_COLOR_BIT,
|
||||||
|
VATTR_VERTEX2_BIT,
|
||||||
|
VATTR_NORMAL_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class FVertexBuffer
|
class FVertexBuffer
|
||||||
{
|
{
|
||||||
|
@ -20,6 +29,7 @@ public:
|
||||||
FVertexBuffer(bool wantbuffer = true);
|
FVertexBuffer(bool wantbuffer = true);
|
||||||
virtual ~FVertexBuffer();
|
virtual ~FVertexBuffer();
|
||||||
virtual void BindVBO() = 0;
|
virtual void BindVBO() = 0;
|
||||||
|
void EnableBufferArrays(int enable, int disable);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FFlatVertex
|
struct FFlatVertex
|
||||||
|
|
|
@ -57,8 +57,6 @@
|
||||||
#include "gl/utility/gl_convert.h"
|
#include "gl/utility/gl_convert.h"
|
||||||
#include "gl/utility/gl_templates.h"
|
#include "gl/utility/gl_templates.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Float, gl_lights_size);
|
|
||||||
EXTERN_CVAR (Bool, gl_lights_additive);
|
|
||||||
EXTERN_CVAR(Int, vid_renderer)
|
EXTERN_CVAR(Int, vid_renderer)
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +377,7 @@ void ADynamicLight::UpdateLocation()
|
||||||
{
|
{
|
||||||
intensity = m_currentRadius;
|
intensity = m_currentRadius;
|
||||||
}
|
}
|
||||||
radius = intensity * 2.0f * gl_lights_size;
|
radius = intensity * 2.0f;
|
||||||
|
|
||||||
if (X() != oldx || Y() != oldy || radius != oldradius)
|
if (X() != oldx || Y() != oldy || radius != oldradius)
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,8 +61,6 @@
|
||||||
#include "gl/utility/gl_clock.h"
|
#include "gl/utility/gl_clock.h"
|
||||||
#include "gl/utility/gl_convert.h"
|
#include "gl/utility/gl_convert.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Float, gl_lights_intensity);
|
|
||||||
EXTERN_CVAR (Float, gl_lights_size);
|
|
||||||
int ScriptDepth;
|
int ScriptDepth;
|
||||||
void gl_InitGlow(FScanner &sc);
|
void gl_InitGlow(FScanner &sc);
|
||||||
void gl_ParseBrightmap(FScanner &sc, int);
|
void gl_ParseBrightmap(FScanner &sc, int);
|
||||||
|
@ -175,7 +173,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
|
||||||
light->Angles.Yaw.Degrees = m_Param;
|
light->Angles.Yaw.Degrees = m_Param;
|
||||||
light->SetOffset(m_Pos);
|
light->SetOffset(m_Pos);
|
||||||
light->halo = m_halo;
|
light->halo = m_halo;
|
||||||
for (int a = 0; a < 3; a++) light->args[a] = clamp<int>((int)(m_Args[a] * gl_lights_intensity), 0, 255);
|
for (int a = 0; a < 3; a++) light->args[a] = clamp<int>((int)(m_Args[a]), 0, 255);
|
||||||
light->m_Radius[0] = int(m_Args[LIGHT_INTENSITY]);
|
light->m_Radius[0] = int(m_Args[LIGHT_INTENSITY]);
|
||||||
light->m_Radius[1] = int(m_Args[LIGHT_SECONDARY_INTENSITY]);
|
light->m_Radius[1] = int(m_Args[LIGHT_SECONDARY_INTENSITY]);
|
||||||
light->flags4 &= ~(MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF);
|
light->flags4 &= ~(MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF);
|
||||||
|
|
|
@ -184,7 +184,7 @@ struct FDynLightData
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data);
|
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &data);
|
||||||
void gl_UploadLights(FDynLightData &data);
|
void gl_UploadLights(FDynLightData &data);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,15 +70,8 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
|
||||||
|
|
||||||
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
CVAR (Float, gl_lights_intensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
|
||||||
CVAR (Float, gl_lights_size, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
|
||||||
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
CUSTOM_CVAR (Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
|
||||||
{
|
|
||||||
gl_DeleteAllAttachedLights();
|
|
||||||
gl_RecreateAllAttachedLights();
|
|
||||||
}
|
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, gl_light_math, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR(Int, gl_light_math, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
|
@ -90,14 +83,14 @@ CUSTOM_CVAR(Int, gl_light_math, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
// Sets up the parameters to render one dynamic light onto one plane
|
// Sets up the parameters to render one dynamic light onto one plane
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &ldata)
|
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &ldata)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
DVector3 pos = light->PosRelative(group);
|
DVector3 pos = light->PosRelative(group);
|
||||||
|
|
||||||
float dist = fabsf(p.DistToPoint(pos.X, pos.Z, pos.Y));
|
float dist = fabsf(p.DistToPoint(pos.X, pos.Z, pos.Y));
|
||||||
float radius = (light->GetRadius() * gl_lights_size);
|
float radius = (light->GetRadius());
|
||||||
|
|
||||||
if (radius <= 0.f) return false;
|
if (radius <= 0.f) return false;
|
||||||
if (dist > radius) return false;
|
if (dist > radius) return false;
|
||||||
|
@ -108,7 +101,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
||||||
|
|
||||||
|
|
||||||
float cs;
|
float cs;
|
||||||
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive)
|
if (light->IsAdditive())
|
||||||
{
|
{
|
||||||
cs = 0.2f;
|
cs = 0.2f;
|
||||||
i = 2;
|
i = 2;
|
||||||
|
@ -118,9 +111,9 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
||||||
cs = 1.0f;
|
cs = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
float r = light->GetRed() / 255.0f * cs;
|
||||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
float g = light->GetGreen() / 255.0f * cs;
|
||||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
float b = light->GetBlue() / 255.0f * cs;
|
||||||
|
|
||||||
if (light->IsSubtractive())
|
if (light->IsSubtractive())
|
||||||
{
|
{
|
||||||
|
|
|
@ -378,7 +378,7 @@ void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32 color)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void F2DDrawer::Flush()
|
void F2DDrawer::Draw()
|
||||||
{
|
{
|
||||||
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
|
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
|
||||||
|
|
||||||
|
@ -490,10 +490,12 @@ void F2DDrawer::Flush()
|
||||||
}
|
}
|
||||||
i += dg->mLen;
|
i += dg->mLen;
|
||||||
}
|
}
|
||||||
mVertices.Clear();
|
|
||||||
mData.Clear();
|
|
||||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||||
glset.lightmode = savedlightmode;
|
glset.lightmode = savedlightmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void F2DDrawer::Clear()
|
||||||
|
{
|
||||||
|
mVertices.Clear();
|
||||||
|
mData.Clear();
|
||||||
|
}
|
||||||
|
|
|
@ -66,7 +66,8 @@ public:
|
||||||
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
||||||
void AddPixel(int x1, int y1, int palcolor, uint32 color);
|
void AddPixel(int x1, int y1, int palcolor, uint32 color);
|
||||||
|
|
||||||
void Flush();
|
void Draw();
|
||||||
|
void Clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
#include "gl/shaders/gl_lensshader.h"
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
#include "gl/renderer/gl_2ddrawer.h"
|
#include "gl/renderer/gl_2ddrawer.h"
|
||||||
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -395,7 +396,7 @@ void FGLRenderer::BindTonemapPalette(int texunit)
|
||||||
{
|
{
|
||||||
for (int b = 0; b < 64; b++)
|
for (int b = 0; b < 64; b++)
|
||||||
{
|
{
|
||||||
PalEntry color = GPalette.BaseColors[ColorMatcher.Pick((r << 2) | (r >> 1), (g << 2) | (g >> 1), (b << 2) | (b >> 1))];
|
PalEntry color = GPalette.BaseColors[(BYTE)PTM_BestColor((uint32 *)GPalette.BaseColors, (r << 2) | (r >> 4), (g << 2) | (g >> 4), (b << 2) | (b >> 4), 0, 256)];
|
||||||
int index = ((r * 64 + g) * 64 + b) * 4;
|
int index = ((r * 64 + g) * 64 + b) * 4;
|
||||||
lut[index] = color.r;
|
lut[index] = color.r;
|
||||||
lut[index + 1] = color.g;
|
lut[index + 1] = color.g;
|
||||||
|
@ -513,6 +514,41 @@ void FGLRenderer::LensDistortScene()
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copies the rendered screen to its final destination
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FGLRenderer::Flush()
|
||||||
|
{
|
||||||
|
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||||
|
|
||||||
|
if (stereo3dMode.IsMono() || !FGLRenderBuffers::IsEnabled())
|
||||||
|
{
|
||||||
|
CopyToBackbuffer(nullptr, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Render 2D to eye textures
|
||||||
|
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
|
||||||
|
{
|
||||||
|
FGLDebug::PushGroup("Eye2D");
|
||||||
|
mBuffers->BindEyeFB(eye_ix);
|
||||||
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
m2DDrawer->Draw();
|
||||||
|
FGLDebug::PopGroup();
|
||||||
|
}
|
||||||
|
m2DDrawer->Clear();
|
||||||
|
|
||||||
|
FGLPostProcessState savedState;
|
||||||
|
FGLDebug::PushGroup("PresentEyes");
|
||||||
|
stereo3dMode.Present();
|
||||||
|
FGLDebug::PopGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Gamma correct while copying to frame buffer
|
// Gamma correct while copying to frame buffer
|
||||||
|
@ -521,7 +557,9 @@ void FGLRenderer::LensDistortScene()
|
||||||
|
|
||||||
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
{
|
{
|
||||||
m2DDrawer->Flush(); // draw all pending 2D stuff before copying the buffer
|
m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer
|
||||||
|
m2DDrawer->Clear();
|
||||||
|
|
||||||
FGLDebug::PushGroup("CopyToBackbuffer");
|
FGLDebug::PushGroup("CopyToBackbuffer");
|
||||||
if (FGLRenderBuffers::IsEnabled())
|
if (FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
|
@ -539,28 +577,8 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
box = mOutputLetterbox;
|
box = mOutputLetterbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present what was rendered:
|
|
||||||
glViewport(box.left, box.top, box.width, box.height);
|
|
||||||
|
|
||||||
mPresentShader->Bind();
|
|
||||||
mPresentShader->InputTexture.Set(0);
|
|
||||||
if (!applyGamma || framebuffer->IsHWGammaActive())
|
|
||||||
{
|
|
||||||
mPresentShader->InvGamma.Set(1.0f);
|
|
||||||
mPresentShader->Contrast.Set(1.0f);
|
|
||||||
mPresentShader->Brightness.Set(0.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mPresentShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
|
||||||
mPresentShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
|
||||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
|
||||||
}
|
|
||||||
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
|
||||||
mBuffers->BindCurrentTexture(0);
|
mBuffers->BindCurrentTexture(0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
DrawPresentTexture(box, applyGamma);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
RenderScreenQuad();
|
|
||||||
}
|
}
|
||||||
else if (!bounds)
|
else if (!bounds)
|
||||||
{
|
{
|
||||||
|
@ -570,6 +588,32 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
|
||||||
|
{
|
||||||
|
glViewport(box.left, box.top, box.width, box.height);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
mPresentShader->Bind();
|
||||||
|
mPresentShader->InputTexture.Set(0);
|
||||||
|
if (!applyGamma || framebuffer->IsHWGammaActive())
|
||||||
|
{
|
||||||
|
mPresentShader->InvGamma.Set(1.0f);
|
||||||
|
mPresentShader->Contrast.Set(1.0f);
|
||||||
|
mPresentShader->Brightness.Set(0.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPresentShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||||
|
mPresentShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||||
|
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||||
|
}
|
||||||
|
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
||||||
|
RenderScreenQuad();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Fills the black bars around the screen letterbox
|
// Fills the black bars around the screen letterbox
|
||||||
|
@ -582,6 +626,8 @@ void FGLRenderer::ClearBorders()
|
||||||
|
|
||||||
int clientWidth = framebuffer->GetClientWidth();
|
int clientWidth = framebuffer->GetClientWidth();
|
||||||
int clientHeight = framebuffer->GetClientHeight();
|
int clientHeight = framebuffer->GetClientHeight();
|
||||||
|
if (clientWidth == 0 || clientHeight == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
glViewport(0, 0, clientWidth, clientHeight);
|
glViewport(0, 0, clientWidth, clientHeight);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
@ -608,3 +654,40 @@ void FGLRenderer::ClearBorders()
|
||||||
}
|
}
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// [SP] Re-implemented BestColor for more precision rather than speed. This function is only ever called once until the game palette is changed.
|
||||||
|
|
||||||
|
int FGLRenderer::PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int first, int num)
|
||||||
|
{
|
||||||
|
const PalEntry *pal = (const PalEntry *)pal_in;
|
||||||
|
static double powtable[256];
|
||||||
|
static bool firstTime = true;
|
||||||
|
|
||||||
|
double fbestdist, fdist;
|
||||||
|
int bestcolor;
|
||||||
|
|
||||||
|
if (firstTime)
|
||||||
|
{
|
||||||
|
firstTime = false;
|
||||||
|
for (int x = 0; x < 256; x++) powtable[x] = pow((double)x/255,1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int color = first; color < num; color++)
|
||||||
|
{
|
||||||
|
double x = powtable[abs(r-pal[color].r)];
|
||||||
|
double y = powtable[abs(g-pal[color].g)];
|
||||||
|
double z = powtable[abs(b-pal[color].b)];
|
||||||
|
fdist = x + y + z;
|
||||||
|
if (color == first || fdist < fbestdist)
|
||||||
|
{
|
||||||
|
if (fdist == 0)
|
||||||
|
return color;
|
||||||
|
|
||||||
|
fbestdist = fdist;
|
||||||
|
bestcolor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
|
||||||
{
|
{
|
||||||
ClearScene();
|
ClearScene();
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
ClearBloom();
|
ClearBloom();
|
||||||
ClearAmbientOcclusion();
|
ClearAmbientOcclusion();
|
||||||
}
|
}
|
||||||
|
@ -128,6 +129,18 @@ void FGLRenderBuffers::ClearAmbientOcclusion()
|
||||||
DeleteTexture(AmbientRandomTexture);
|
DeleteTexture(AmbientRandomTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::ClearEyeBuffers()
|
||||||
|
{
|
||||||
|
for (auto handle : mEyeFBs)
|
||||||
|
DeleteFrameBuffer(handle);
|
||||||
|
|
||||||
|
for (auto handle : mEyeTextures)
|
||||||
|
DeleteTexture(handle);
|
||||||
|
|
||||||
|
mEyeTextures.Clear();
|
||||||
|
mEyeFBs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void FGLRenderBuffers::DeleteTexture(GLuint &handle)
|
void FGLRenderBuffers::DeleteTexture(GLuint &handle)
|
||||||
{
|
{
|
||||||
if (handle != 0)
|
if (handle != 0)
|
||||||
|
@ -212,6 +225,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
|
||||||
{
|
{
|
||||||
ClearScene();
|
ClearScene();
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
ClearBloom();
|
ClearBloom();
|
||||||
mWidth = 0;
|
mWidth = 0;
|
||||||
mHeight = 0;
|
mHeight = 0;
|
||||||
|
@ -255,6 +269,7 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples)
|
||||||
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
||||||
{
|
{
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
|
|
||||||
for (int i = 0; i < NumPipelineTextures; i++)
|
for (int i = 0; i < NumPipelineTextures; i++)
|
||||||
{
|
{
|
||||||
|
@ -336,6 +351,35 @@ void FGLRenderBuffers::CreateAmbientOcclusion(int width, int height)
|
||||||
AmbientRandomTexture = Create2DTexture("AmbientRandomTexture", GL_RGBA16_SNORM, 4, 4, randomValues);
|
AmbientRandomTexture = Create2DTexture("AmbientRandomTexture", GL_RGBA16_SNORM, 4, 4, randomValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Creates eye buffers if needed
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderBuffers::CreateEyeBuffers(int eye)
|
||||||
|
{
|
||||||
|
if (mEyeFBs.Size() > eye)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLint activeTex, textureBinding, frameBufferBinding;
|
||||||
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
|
||||||
|
|
||||||
|
while (mEyeFBs.Size() <= eye)
|
||||||
|
{
|
||||||
|
GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight);
|
||||||
|
mEyeTextures.Push(texture);
|
||||||
|
mEyeFBs.Push(CreateFrameBuffer("EyeFB", texture));
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||||
|
glActiveTexture(activeTex);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Creates a 2D texture defaulting to linear filtering and clamp to edge
|
// Creates a 2D texture defaulting to linear filtering and clamp to edge
|
||||||
|
@ -544,6 +588,43 @@ void FGLRenderBuffers::BlitSceneToTexture()
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Eye textures and their frame buffers
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BlitToEyeTexture(int eye)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]);
|
||||||
|
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
|
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
|
||||||
|
{
|
||||||
|
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
|
||||||
|
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindEyeTexture(int eye, int texunit)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
||||||
|
|
|
@ -34,6 +34,10 @@ public:
|
||||||
|
|
||||||
void BindOutputFB();
|
void BindOutputFB();
|
||||||
|
|
||||||
|
void BlitToEyeTexture(int eye);
|
||||||
|
void BindEyeTexture(int eye, int texunit);
|
||||||
|
void BindEyeFB(int eye, bool readBuffer = false);
|
||||||
|
|
||||||
enum { NumBloomLevels = 4 };
|
enum { NumBloomLevels = 4 };
|
||||||
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
||||||
|
|
||||||
|
@ -57,12 +61,14 @@ public:
|
||||||
private:
|
private:
|
||||||
void ClearScene();
|
void ClearScene();
|
||||||
void ClearPipeline();
|
void ClearPipeline();
|
||||||
|
void ClearEyeBuffers();
|
||||||
void ClearBloom();
|
void ClearBloom();
|
||||||
void ClearAmbientOcclusion();
|
void ClearAmbientOcclusion();
|
||||||
void CreateScene(int width, int height, int samples);
|
void CreateScene(int width, int height, int samples);
|
||||||
void CreatePipeline(int width, int height);
|
void CreatePipeline(int width, int height);
|
||||||
void CreateBloom(int width, int height);
|
void CreateBloom(int width, int height);
|
||||||
void CreateAmbientOcclusion(int width, int height);
|
void CreateAmbientOcclusion(int width, int height);
|
||||||
|
void CreateEyeBuffers(int eye);
|
||||||
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
|
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
|
||||||
GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations);
|
GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations);
|
||||||
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
|
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
|
||||||
|
@ -97,6 +103,10 @@ private:
|
||||||
// Back buffer frame buffer
|
// Back buffer frame buffer
|
||||||
GLuint mOutputFB = 0;
|
GLuint mOutputFB = 0;
|
||||||
|
|
||||||
|
// Eye buffers
|
||||||
|
TArray<GLuint> mEyeTextures;
|
||||||
|
TArray<GLuint> mEyeFBs;
|
||||||
|
|
||||||
static bool FailedCreate;
|
static bool FailedCreate;
|
||||||
static bool BuffersActive;
|
static bool BuffersActive;
|
||||||
};
|
};
|
||||||
|
|
|
@ -244,6 +244,13 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
||||||
// Back buffer letterbox for the final output
|
// Back buffer letterbox for the final output
|
||||||
int clientWidth = framebuffer->GetClientWidth();
|
int clientWidth = framebuffer->GetClientWidth();
|
||||||
int clientHeight = framebuffer->GetClientHeight();
|
int clientHeight = framebuffer->GetClientHeight();
|
||||||
|
if (clientWidth == 0 || clientHeight == 0)
|
||||||
|
{
|
||||||
|
// When window is minimized there may not be any client area.
|
||||||
|
// Pretend to the rest of the render code that we just have a very small window.
|
||||||
|
clientWidth = 160;
|
||||||
|
clientHeight = 120;
|
||||||
|
}
|
||||||
int screenWidth = framebuffer->GetWidth();
|
int screenWidth = framebuffer->GetWidth();
|
||||||
int screenHeight = framebuffer->GetHeight();
|
int screenHeight = framebuffer->GetHeight();
|
||||||
float scale = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
|
float scale = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
|
||||||
|
|
|
@ -183,7 +183,8 @@ public:
|
||||||
void ClearTonemapPalette();
|
void ClearTonemapPalette();
|
||||||
void LensDistortScene();
|
void LensDistortScene();
|
||||||
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
||||||
void Flush() { CopyToBackbuffer(nullptr, true); }
|
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
|
||||||
|
void Flush();
|
||||||
|
|
||||||
void SetProjection(float fov, float ratio, float fovratio);
|
void SetProjection(float fov, float ratio, float fovratio);
|
||||||
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
||||||
|
@ -200,6 +201,8 @@ public:
|
||||||
double originx, double originy, double scalex, double scaley,
|
double originx, double originy, double scalex, double scaley,
|
||||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel);
|
DAngle rotation, FDynamicColormap *colormap, int lightlevel);
|
||||||
|
|
||||||
|
int PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int first, int num);
|
||||||
|
|
||||||
static float GetZNear() { return 5.f; }
|
static float GetZNear() { return 5.f; }
|
||||||
static float GetZFar() { return 65536.f; }
|
static float GetZFar() { return 65536.f; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -154,7 +154,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Set(plane.plane);
|
p.Set(plane.plane);
|
||||||
gl_GetLight(sub->sector->PortalGroup, p, light, false, false, lightdata);
|
gl_GetLight(sub->sector->PortalGroup, p, light, false, lightdata);
|
||||||
node = node->nextLight;
|
node = node->nextLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,15 +419,17 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
||||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
||||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
|
||||||
if (!gltexture)
|
if (!gltexture)
|
||||||
{
|
{
|
||||||
|
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.EnableTexture(false);
|
||||||
DrawSubsectors(pass, false, true);
|
DrawSubsectors(pass, false, true);
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||||
|
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||||
DrawSubsectors(pass, !gl.legacyMode, true);
|
DrawSubsectors(pass, !gl.legacyMode, true);
|
||||||
|
@ -477,6 +479,21 @@ inline void GLFlat::PutFlat(bool fog)
|
||||||
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
||||||
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||||
}
|
}
|
||||||
|
else if (gltexture->GetTransparent())
|
||||||
|
{
|
||||||
|
if (stack)
|
||||||
|
{
|
||||||
|
list = GLDL_TRANSLUCENTBORDER;
|
||||||
|
}
|
||||||
|
else if ((renderflags&SSRF_RENDER3DPLANES) && !plane.plane.isSlope())
|
||||||
|
{
|
||||||
|
list = GLDL_TRANSLUCENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = GLDL_PLAINFLATS;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "gl/renderer/gl_lightdata.h"
|
#include "gl/renderer/gl_lightdata.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/renderer/gl_renderstate.h"
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
|
#include "gl/renderer/gl_quaddrawer.h"
|
||||||
#include "gl/dynlights/gl_glow.h"
|
#include "gl/dynlights/gl_glow.h"
|
||||||
#include "gl/data/gl_data.h"
|
#include "gl/data/gl_data.h"
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
@ -128,8 +129,16 @@ void GLPortal::ClearScreen()
|
||||||
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
||||||
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
||||||
gl_MatrixStack.Push(gl_RenderState.mProjectionMatrix);
|
gl_MatrixStack.Push(gl_RenderState.mProjectionMatrix);
|
||||||
screen->Begin2D(false);
|
|
||||||
screen->Dim(0, 1.f, 0, 0, SCREENWIDTH, SCREENHEIGHT);
|
gl_RenderState.mViewMatrix.loadIdentity();
|
||||||
|
gl_RenderState.mProjectionMatrix.ortho(0, SCREENWIDTH, SCREENHEIGHT, 0, -1.0f, 1.0f);
|
||||||
|
gl_RenderState.ApplyMatrices();
|
||||||
|
|
||||||
|
glDisable(GL_MULTISAMPLE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
gl_MatrixStack.Pop(gl_RenderState.mProjectionMatrix);
|
gl_MatrixStack.Pop(gl_RenderState.mProjectionMatrix);
|
||||||
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
||||||
|
@ -137,7 +146,6 @@ void GLPortal::ClearScreen()
|
||||||
if (multi) glEnable(GL_MULTISAMPLE);
|
if (multi) glEnable(GL_MULTISAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// DrawPortalStencil
|
// DrawPortalStencil
|
||||||
|
|
|
@ -682,8 +682,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
|
||||||
}
|
}
|
||||||
if (gl.legacyMode)
|
if (gl.legacyMode)
|
||||||
{
|
{
|
||||||
int cm = gl_RenderState.GetFixedColormap();
|
|
||||||
gl_RenderState.SetFixedColormap(cm);
|
|
||||||
gl_RenderState.DrawColormapOverlay();
|
gl_RenderState.DrawColormapOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,7 +773,7 @@ void FGLRenderer::SetFixedColormap (player_t *player)
|
||||||
|
|
||||||
sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
|
sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
|
||||||
{
|
{
|
||||||
sector_t * retval;
|
sector_t * lviewsector;
|
||||||
mSceneClearColor[0] = 0.0f;
|
mSceneClearColor[0] = 0.0f;
|
||||||
mSceneClearColor[1] = 0.0f;
|
mSceneClearColor[1] = 0.0f;
|
||||||
mSceneClearColor[2] = 0.0f;
|
mSceneClearColor[2] = 0.0f;
|
||||||
|
@ -822,11 +820,11 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'viewsector' will not survive the rendering so it cannot be used anymore below.
|
// 'viewsector' will not survive the rendering so it cannot be used anymore below.
|
||||||
retval = viewsector;
|
lviewsector = viewsector;
|
||||||
|
|
||||||
// Render (potentially) multiple views for stereo 3d
|
// Render (potentially) multiple views for stereo 3d
|
||||||
float viewShift[3];
|
float viewShift[3];
|
||||||
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
const s3d::Stereo3DMode& stereo3dMode = mainview && toscreen? s3d::Stereo3DMode::getCurrentMode() : s3d::Stereo3DMode::getMonoMode();
|
||||||
stereo3dMode.SetUp();
|
stereo3dMode.SetUp();
|
||||||
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
|
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
|
||||||
{
|
{
|
||||||
|
@ -852,20 +850,26 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
|
clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
|
||||||
|
|
||||||
ProcessScene(toscreen);
|
ProcessScene(toscreen);
|
||||||
if (mainview && toscreen) EndDrawScene(retval); // do not call this for camera textures.
|
if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures.
|
||||||
if (mainview && FGLRenderBuffers::IsEnabled())
|
if (mainview && FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
PostProcessScene();
|
PostProcessScene();
|
||||||
DrawBlend(viewsector); // This should be done after postprocessing, not before.
|
|
||||||
|
// This should be done after postprocessing, not before.
|
||||||
|
mBuffers->BindCurrentFB();
|
||||||
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
DrawBlend(lviewsector);
|
||||||
}
|
}
|
||||||
mDrawingScene2D = false;
|
mDrawingScene2D = false;
|
||||||
|
if (!stereo3dMode.IsMono() && FGLRenderBuffers::IsEnabled())
|
||||||
|
mBuffers->BlitToEyeTexture(eye_ix);
|
||||||
eye->TearDown();
|
eye->TearDown();
|
||||||
}
|
}
|
||||||
stereo3dMode.TearDown();
|
stereo3dMode.TearDown();
|
||||||
|
|
||||||
gl_frameCount++; // This counter must be increased right before the interpolations are restored.
|
gl_frameCount++; // This counter must be increased right before the interpolations are restored.
|
||||||
interpolator.RestoreInterpolations ();
|
interpolator.RestoreInterpolations ();
|
||||||
return retval;
|
return lviewsector;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1313,29 +1317,16 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
|
||||||
gl_fixedcolormap=CM_DEFAULT;
|
gl_fixedcolormap=CM_DEFAULT;
|
||||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||||
|
|
||||||
bool usefb = gl_usefb || gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight();
|
if (gl.legacyMode)
|
||||||
if (!usefb)
|
|
||||||
{
|
{
|
||||||
|
// In legacy mode, fail if the requested texture is too large.
|
||||||
|
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))
|
GLRenderer->StartOffscreen();
|
||||||
__try
|
gltex->BindToFrameBuffer();
|
||||||
#endif
|
|
||||||
{
|
|
||||||
GLRenderer->StartOffscreen();
|
|
||||||
gltex->BindToFrameBuffer();
|
|
||||||
}
|
|
||||||
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))
|
|
||||||
__except(1)
|
|
||||||
{
|
|
||||||
usefb = false;
|
|
||||||
gl_usefb = false;
|
|
||||||
GLRenderer->EndOffscreen();
|
|
||||||
glFlush();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_IRECT bounds;
|
GL_IRECT bounds;
|
||||||
|
@ -1345,7 +1336,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
|
||||||
|
|
||||||
GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
|
GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
|
||||||
|
|
||||||
if (!usefb)
|
if (gl.legacyMode)
|
||||||
{
|
{
|
||||||
glFlush();
|
glFlush();
|
||||||
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
|
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
|
||||||
|
|
|
@ -110,17 +110,155 @@ CVAR(Bool, gl_nolayer, false, 0)
|
||||||
|
|
||||||
static const float LARGE_VALUE = 1e19f;
|
static const float LARGE_VALUE = 1e19f;
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLSprite::CalculateVertices(FVector3 *v)
|
||||||
|
{
|
||||||
|
// [BB] Billboard stuff
|
||||||
|
const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD)
|
||||||
|
//&& GLRenderer->mViewActor != NULL
|
||||||
|
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
|
||||||
|
|
||||||
|
const bool drawBillboardFacingCamera = gl_billboard_faces_camera;
|
||||||
|
// [Nash] has +ROLLSPRITE
|
||||||
|
const bool drawRollSpriteActor = (actor != nullptr && actor->renderflags & RF_ROLLSPRITE);
|
||||||
|
|
||||||
|
|
||||||
|
// [fgsfds] check sprite type mask
|
||||||
|
DWORD spritetype = (DWORD)-1;
|
||||||
|
if (actor != nullptr) spritetype = actor->renderflags & RF_SPRITETYPEMASK;
|
||||||
|
|
||||||
|
// [Nash] is a flat sprite
|
||||||
|
const bool isFlatSprite = (actor != nullptr) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE);
|
||||||
|
const bool dontFlip = (actor != nullptr) && (actor->renderflags & RF_DONTFLIP);
|
||||||
|
const bool useOffsets = (actor != nullptr) && !(actor->renderflags & RF_ROLLCENTER);
|
||||||
|
|
||||||
|
// [Nash] check for special sprite drawing modes
|
||||||
|
if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite)
|
||||||
|
{
|
||||||
|
// Compute center of sprite
|
||||||
|
float xcenter = (x1 + x2)*0.5;
|
||||||
|
float ycenter = (y1 + y2)*0.5;
|
||||||
|
float zcenter = (z1 + z2)*0.5;
|
||||||
|
float xx = -xcenter + x;
|
||||||
|
float zz = -zcenter + z;
|
||||||
|
float yy = -ycenter + y;
|
||||||
|
Matrix3x4 mat;
|
||||||
|
mat.MakeIdentity();
|
||||||
|
mat.Translate(xcenter, zcenter, ycenter); // move to sprite center
|
||||||
|
|
||||||
|
// Order of rotations matters. Perform yaw rotation (Y, face camera) before pitch (X, tilt up/down).
|
||||||
|
if (drawBillboardFacingCamera && !isFlatSprite)
|
||||||
|
{
|
||||||
|
// [CMB] Rotate relative to camera XY position, not just camera direction,
|
||||||
|
// which is nicer in VR
|
||||||
|
float xrel = xcenter - ViewPos.X;
|
||||||
|
float yrel = ycenter - ViewPos.Y;
|
||||||
|
float absAngleDeg = RAD2DEG(atan2(-yrel, xrel));
|
||||||
|
float counterRotationDeg = 270. - GLRenderer->mAngles.Yaw.Degrees; // counteracts existing sprite rotation
|
||||||
|
float relAngleDeg = counterRotationDeg + absAngleDeg;
|
||||||
|
|
||||||
|
mat.Rotate(0, 1, 0, relAngleDeg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [fgsfds] calculate yaw vectors
|
||||||
|
float yawvecX = 0, yawvecY = 0, rollDegrees = 0;
|
||||||
|
float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians();
|
||||||
|
if (actor) rollDegrees = actor->Angles.Roll.Degrees;
|
||||||
|
if (isFlatSprite)
|
||||||
|
{
|
||||||
|
yawvecX = actor->Angles.Yaw.Cos();
|
||||||
|
yawvecY = actor->Angles.Yaw.Sin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// [MC] This is the only thing that I changed in Nash's submission which
|
||||||
|
// was constantly applying roll to everything. That was wrong. Flat sprites
|
||||||
|
// with roll literally look like paper thing space ships trying to swerve.
|
||||||
|
// However, it does well with wall sprites.
|
||||||
|
// Also, renamed FLOORSPRITE to FLATSPRITE because that's technically incorrect.
|
||||||
|
// I plan on adding proper FLOORSPRITEs which can actually curve along sloped
|
||||||
|
// 3D floors later... if possible.
|
||||||
|
|
||||||
|
// Here we need some form of priority in order to work.
|
||||||
|
if (spritetype == RF_FLATSPRITE)
|
||||||
|
{
|
||||||
|
float pitchDegrees = -actor->Angles.Pitch.Degrees;
|
||||||
|
DVector3 apos = { x, y, z };
|
||||||
|
DVector3 diff = ViewPos - apos;
|
||||||
|
DAngle angto = diff.Angle();
|
||||||
|
|
||||||
|
angto = deltaangle(actor->Angles.Yaw, angto);
|
||||||
|
|
||||||
|
bool noFlipSprite = (!dontFlip || (fabs(angto) < 90.));
|
||||||
|
mat.Rotate(0, 1, 0, (noFlipSprite) ? 0 : 180);
|
||||||
|
|
||||||
|
mat.Rotate(-yawvecY, 0, yawvecX, (noFlipSprite) ? -pitchDegrees : pitchDegrees);
|
||||||
|
if (drawRollSpriteActor)
|
||||||
|
{
|
||||||
|
if (useOffsets) mat.Translate(xx, zz, yy);
|
||||||
|
mat.Rotate(yawvecX, 0, yawvecY, (noFlipSprite) ? -rollDegrees : rollDegrees);
|
||||||
|
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// [fgsfds] Rotate the sprite about the sight vector (roll)
|
||||||
|
else if (spritetype == RF_WALLSPRITE)
|
||||||
|
{
|
||||||
|
mat.Rotate(0, 1, 0, 0);
|
||||||
|
if (drawRollSpriteActor)
|
||||||
|
{
|
||||||
|
if (useOffsets) mat.Translate(xx, zz, yy);
|
||||||
|
mat.Rotate(yawvecX, 0, yawvecY, rollDegrees);
|
||||||
|
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (drawRollSpriteActor)
|
||||||
|
{
|
||||||
|
if (useOffsets) mat.Translate(xx, zz, yy);
|
||||||
|
if (drawWithXYBillboard)
|
||||||
|
{
|
||||||
|
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
||||||
|
}
|
||||||
|
mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees);
|
||||||
|
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
||||||
|
}
|
||||||
|
else if (drawWithXYBillboard)
|
||||||
|
{
|
||||||
|
// Rotate the sprite about the vector starting at the center of the sprite
|
||||||
|
// triangle strip and with direction orthogonal to where the player is looking
|
||||||
|
// in the x/y plane.
|
||||||
|
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center
|
||||||
|
v[0] = mat * FVector3(x1, z1, y1);
|
||||||
|
v[1] = mat * FVector3(x2, z1, y2);
|
||||||
|
v[2] = mat * FVector3(x1, z2, y1);
|
||||||
|
v[3] = mat * FVector3(x2, z2, y2);
|
||||||
|
}
|
||||||
|
else // traditional "Y" billboard mode
|
||||||
|
{
|
||||||
|
v[0] = FVector3(x1, z1, y1);
|
||||||
|
v[1] = FVector3(x2, z1, y2);
|
||||||
|
v[2] = FVector3(x1, z2, y1);
|
||||||
|
v[3] = FVector3(x2, z2, y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void GLSprite::Draw(int pass)
|
void GLSprite::Draw(int pass)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
|
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool additivefog = false;
|
bool additivefog = false;
|
||||||
bool foglayer = false;
|
bool foglayer = false;
|
||||||
int rel = fullbright? 0 : getExtraLight();
|
int rel = fullbright? 0 : getExtraLight();
|
||||||
|
@ -264,147 +402,17 @@ void GLSprite::Draw(int pass)
|
||||||
|
|
||||||
if (!modelframe)
|
if (!modelframe)
|
||||||
{
|
{
|
||||||
// [BB] Billboard stuff
|
|
||||||
const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD)
|
|
||||||
//&& GLRenderer->mViewActor != NULL
|
|
||||||
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
|
|
||||||
|
|
||||||
const bool drawBillboardFacingCamera = gl_billboard_faces_camera;
|
|
||||||
// [Nash] has +ROLLSPRITE
|
|
||||||
const bool drawRollSpriteActor = (actor != nullptr && actor->renderflags & RF_ROLLSPRITE);
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
|
|
||||||
FVector3 v1;
|
FVector3 v[4];
|
||||||
FVector3 v2;
|
CalculateVertices(v);
|
||||||
FVector3 v3;
|
|
||||||
FVector3 v4;
|
|
||||||
|
|
||||||
// [fgsfds] check sprite type mask
|
|
||||||
DWORD spritetype = (DWORD)-1;
|
|
||||||
if (actor != nullptr) spritetype = actor->renderflags & RF_SPRITETYPEMASK;
|
|
||||||
|
|
||||||
// [Nash] is a flat sprite
|
|
||||||
const bool isFlatSprite = (actor != nullptr) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE);
|
|
||||||
const bool dontFlip = (actor != nullptr) && (actor->renderflags & RF_DONTFLIP);
|
|
||||||
const bool useOffsets = (actor != nullptr) && !(actor->renderflags & RF_ROLLCENTER);
|
|
||||||
|
|
||||||
// [Nash] check for special sprite drawing modes
|
|
||||||
if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite)
|
|
||||||
{
|
|
||||||
// Compute center of sprite
|
|
||||||
float xcenter = (x1 + x2)*0.5;
|
|
||||||
float ycenter = (y1 + y2)*0.5;
|
|
||||||
float zcenter = (z1 + z2)*0.5;
|
|
||||||
float xx = -xcenter + x;
|
|
||||||
float zz = -zcenter + z;
|
|
||||||
float yy = -ycenter + y;
|
|
||||||
Matrix3x4 mat;
|
|
||||||
mat.MakeIdentity();
|
|
||||||
mat.Translate(xcenter, zcenter, ycenter); // move to sprite center
|
|
||||||
|
|
||||||
// Order of rotations matters. Perform yaw rotation (Y, face camera) before pitch (X, tilt up/down).
|
|
||||||
if (drawBillboardFacingCamera && !isFlatSprite)
|
|
||||||
{
|
|
||||||
// [CMB] Rotate relative to camera XY position, not just camera direction,
|
|
||||||
// which is nicer in VR
|
|
||||||
float xrel = xcenter - ViewPos.X;
|
|
||||||
float yrel = ycenter - ViewPos.Y;
|
|
||||||
float absAngleDeg = RAD2DEG(atan2(-yrel, xrel));
|
|
||||||
float counterRotationDeg = 270. - GLRenderer->mAngles.Yaw.Degrees; // counteracts existing sprite rotation
|
|
||||||
float relAngleDeg = counterRotationDeg + absAngleDeg;
|
|
||||||
|
|
||||||
mat.Rotate(0, 1, 0, relAngleDeg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [fgsfds] calculate yaw vectors
|
|
||||||
float yawvecX = 0, yawvecY = 0, rollDegrees = 0;
|
|
||||||
float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians();
|
|
||||||
if (actor) rollDegrees = actor->Angles.Roll.Degrees;
|
|
||||||
if (isFlatSprite)
|
|
||||||
{
|
|
||||||
yawvecX = actor->Angles.Yaw.Cos();
|
|
||||||
yawvecY = actor->Angles.Yaw.Sin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// [MC] This is the only thing that I changed in Nash's submission which
|
|
||||||
// was constantly applying roll to everything. That was wrong. Flat sprites
|
|
||||||
// with roll literally look like paper thing space ships trying to swerve.
|
|
||||||
// However, it does well with wall sprites.
|
|
||||||
// Also, renamed FLOORSPRITE to FLATSPRITE because that's technically incorrect.
|
|
||||||
// I plan on adding proper FLOORSPRITEs which can actually curve along sloped
|
|
||||||
// 3D floors later... if possible.
|
|
||||||
|
|
||||||
// Here we need some form of priority in order to work.
|
|
||||||
if (spritetype == RF_FLATSPRITE)
|
|
||||||
{
|
|
||||||
float pitchDegrees = -actor->Angles.Pitch.Degrees;
|
|
||||||
DVector3 apos = { x, y, z };
|
|
||||||
DVector3 diff = ViewPos - apos;
|
|
||||||
DAngle angto = diff.Angle();
|
|
||||||
|
|
||||||
angto = deltaangle(actor->Angles.Yaw, angto);
|
|
||||||
|
|
||||||
bool noFlipSprite = (!dontFlip || (fabs(angto) < 90.));
|
|
||||||
mat.Rotate(0, 1, 0, (noFlipSprite) ? 0 : 180);
|
|
||||||
|
|
||||||
mat.Rotate(-yawvecY, 0, yawvecX, (noFlipSprite) ? -pitchDegrees : pitchDegrees);
|
|
||||||
if (drawRollSpriteActor)
|
|
||||||
{
|
|
||||||
if (useOffsets) mat.Translate(xx, zz, yy);
|
|
||||||
mat.Rotate(yawvecX, 0, yawvecY, (noFlipSprite) ? -rollDegrees : rollDegrees);
|
|
||||||
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// [fgsfds] Rotate the sprite about the sight vector (roll)
|
|
||||||
else if (spritetype == RF_WALLSPRITE)
|
|
||||||
{
|
|
||||||
mat.Rotate(0, 1, 0, 0);
|
|
||||||
if (drawRollSpriteActor)
|
|
||||||
{
|
|
||||||
if (useOffsets) mat.Translate(xx, zz, yy);
|
|
||||||
mat.Rotate(yawvecX, 0, yawvecY, rollDegrees);
|
|
||||||
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (drawRollSpriteActor)
|
|
||||||
{
|
|
||||||
if (useOffsets) mat.Translate(xx, zz, yy);
|
|
||||||
if (drawWithXYBillboard)
|
|
||||||
{
|
|
||||||
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
|
||||||
}
|
|
||||||
mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees);
|
|
||||||
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply the transform
|
|
||||||
else if (drawWithXYBillboard)
|
|
||||||
{
|
|
||||||
// Rotate the sprite about the vector starting at the center of the sprite
|
|
||||||
// triangle strip and with direction orthogonal to where the player is looking
|
|
||||||
// in the x/y plane.
|
|
||||||
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center
|
|
||||||
v1 = mat * FVector3(x1, z1, y1);
|
|
||||||
v2 = mat * FVector3(x2, z1, y2);
|
|
||||||
v3 = mat * FVector3(x1, z2, y1);
|
|
||||||
v4 = mat * FVector3(x2, z2, y2);
|
|
||||||
}
|
|
||||||
else // traditional "Y" billboard mode
|
|
||||||
{
|
|
||||||
v1 = FVector3(x1, z1, y1);
|
|
||||||
v2 = FVector3(x2, z1, y2);
|
|
||||||
v3 = FVector3(x1, z2, y1);
|
|
||||||
v4 = FVector3(x2, z2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
FQuadDrawer qd;
|
FQuadDrawer qd;
|
||||||
qd.Set(0, v1[0], v1[1], v1[2], ul, vt);
|
qd.Set(0, v[0][0], v[0][1], v[0][2], ul, vt);
|
||||||
qd.Set(1, v2[0], v2[1], v2[2], ur, vt);
|
qd.Set(1, v[1][0], v[1][1], v[1][2], ur, vt);
|
||||||
qd.Set(2, v3[0], v3[1], v3[2], ul, vb);
|
qd.Set(2, v[2][0], v[2][1], v[2][2], ul, vb);
|
||||||
qd.Set(3, v4[0], v4[1], v4[2], ur, vb);
|
qd.Set(3, v[3][0], v[3][1], v[3][2], ur, vb);
|
||||||
qd.Render(GL_TRIANGLE_STRIP);
|
qd.Render(GL_TRIANGLE_STRIP);
|
||||||
|
|
||||||
if (foglayer)
|
if (foglayer)
|
||||||
|
@ -703,7 +711,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
||||||
x = thingpos.X;
|
x = thingpos.X;
|
||||||
z = thingpos.Z;
|
z = thingpos.Z;
|
||||||
y = thingpos.Y;
|
y = thingpos.Y;
|
||||||
if (spritetype == RF_FLATSPRITE) z -= thing->Floorclip;
|
if (spritetype != RF_FLATSPRITE) z -= thing->Floorclip;
|
||||||
|
|
||||||
// [RH] Make floatbobbing a renderer-only effect.
|
// [RH] Make floatbobbing a renderer-only effect.
|
||||||
if (thing->flags2 & MF2_FLOATBOB)
|
if (thing->flags2 & MF2_FLOATBOB)
|
||||||
|
|
|
@ -96,7 +96,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared();
|
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared();
|
||||||
}
|
}
|
||||||
|
|
||||||
radius = light->GetRadius() * gl_lights_size;
|
radius = light->GetRadius();
|
||||||
|
|
||||||
if (dist < radius * radius)
|
if (dist < radius * radius)
|
||||||
{
|
{
|
||||||
|
@ -106,9 +106,9 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
|
|
||||||
if (frac > 0)
|
if (frac > 0)
|
||||||
{
|
{
|
||||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
lr = light->GetRed() / 255.0f;
|
||||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
lg = light->GetGreen() / 255.0f;
|
||||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
lb = light->GetBlue() / 255.0f;
|
||||||
if (light->IsSubtractive())
|
if (light->IsSubtractive())
|
||||||
{
|
{
|
||||||
float bright = FVector3(lr, lg, lb).Length();
|
float bright = FVector3(lr, lg, lb).Length();
|
||||||
|
|
|
@ -371,6 +371,7 @@ public:
|
||||||
void SplitSprite(sector_t * frontsector, bool translucent);
|
void SplitSprite(sector_t * frontsector, bool translucent);
|
||||||
void SetLowerParam();
|
void SetLowerParam();
|
||||||
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
|
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
|
||||||
|
void CalculateVertices(FVector3 *v);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ void GLWall::SetupLights()
|
||||||
float y = node->lightsource->Y();
|
float y = node->lightsource->Y();
|
||||||
float z = node->lightsource->Z();
|
float z = node->lightsource->Z();
|
||||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||||
float radius = (node->lightsource->GetRadius() * gl_lights_size);
|
float radius = node->lightsource->GetRadius();
|
||||||
float scale = 1.0f / ((2.f * radius) - dist);
|
float scale = 1.0f / ((2.f * radius) - dist);
|
||||||
|
|
||||||
if (radius > 0.f && dist < radius)
|
if (radius > 0.f && dist < radius)
|
||||||
|
@ -158,7 +158,7 @@ void GLWall::SetupLights()
|
||||||
}
|
}
|
||||||
if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4)
|
if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4)
|
||||||
{
|
{
|
||||||
gl_GetLight(seg->frontsector->PortalGroup, p, node->lightsource, true, false, lightdata);
|
gl_GetLight(seg->frontsector->PortalGroup, p, node->lightsource, true, lightdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ enum
|
||||||
VATTR_VERTEX = 0,
|
VATTR_VERTEX = 0,
|
||||||
VATTR_TEXCOORD = 1,
|
VATTR_TEXCOORD = 1,
|
||||||
VATTR_COLOR = 2,
|
VATTR_COLOR = 2,
|
||||||
VATTR_VERTEX2 = 3
|
VATTR_VERTEX2 = 3,
|
||||||
|
VATTR_NORMAL = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gl_anaglyph.h"
|
#include "gl_anaglyph.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
@ -44,6 +46,25 @@ MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
||||||
eye_ptrs.Push(&rightEye);
|
eye_ptrs.Push(&rightEye);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaskAnaglyph::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
|
||||||
|
gl_RenderState.SetColorMask(leftEye.GetColorMask().r, leftEye.GetColorMask().g, leftEye.GetColorMask().b, true);
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
gl_RenderState.SetColorMask(rightEye.GetColorMask().r, rightEye.GetColorMask().g, rightEye.GetColorMask().b, true);
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
gl_RenderState.ResetColorMask();
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||||
|
|
|
@ -61,14 +61,8 @@ class AnaglyphLeftPose : public LeftEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
||||||
virtual void SetUp() const {
|
ColorMask GetColorMask() const { return colorMask; }
|
||||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
gl_RenderState.ResetColorMask();
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
ColorMask colorMask;
|
ColorMask colorMask;
|
||||||
};
|
};
|
||||||
|
@ -77,14 +71,8 @@ class AnaglyphRightPose : public RightEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
||||||
virtual void SetUp() const {
|
ColorMask GetColorMask() const { return colorMask; }
|
||||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
gl_RenderState.ResetColorMask();
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
ColorMask colorMask;
|
ColorMask colorMask;
|
||||||
};
|
};
|
||||||
|
@ -93,6 +81,7 @@ class MaskAnaglyph : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
||||||
|
void Present() const override;
|
||||||
private:
|
private:
|
||||||
AnaglyphLeftPose leftEye;
|
AnaglyphLeftPose leftEye;
|
||||||
AnaglyphRightPose rightEye;
|
AnaglyphRightPose rightEye;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gl_quadstereo.h"
|
#include "gl_quadstereo.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
@ -46,7 +48,7 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
GLboolean supportsStereo, supportsBuffered;
|
GLboolean supportsStereo, supportsBuffered;
|
||||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||||
bool bQuadStereoSupported = supportsStereo && supportsBuffered;
|
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||||
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
|
|
||||||
|
@ -57,6 +59,33 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuadStereo::Present() const
|
||||||
|
{
|
||||||
|
if (bQuadStereoSupported)
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_LEFT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_RIGHT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const QuadStereo& QuadStereo::getInstance(float ipd)
|
const QuadStereo& QuadStereo::getInstance(float ipd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,14 +47,6 @@ class QuadStereoLeftPose : public LeftEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_LEFT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,14 +54,6 @@ class QuadStereoRightPose : public RightEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_RIGHT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,10 +68,12 @@ class QuadStereo : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereo(double ipdMeters);
|
QuadStereo(double ipdMeters);
|
||||||
|
void Present() const override;
|
||||||
static const QuadStereo& getInstance(float ipd);
|
static const QuadStereo& getInstance(float ipd);
|
||||||
private:
|
private:
|
||||||
QuadStereoLeftPose leftEye;
|
QuadStereoLeftPose leftEye;
|
||||||
QuadStereoRightPose rightEye;
|
QuadStereoRightPose rightEye;
|
||||||
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class Stereo3DMode
|
||||||
public:
|
public:
|
||||||
/* static methods for managing the selected stereoscopic view state */
|
/* static methods for managing the selected stereoscopic view state */
|
||||||
static const Stereo3DMode& getCurrentMode();
|
static const Stereo3DMode& getCurrentMode();
|
||||||
|
static const Stereo3DMode& getMonoMode();
|
||||||
|
|
||||||
Stereo3DMode();
|
Stereo3DMode();
|
||||||
virtual ~Stereo3DMode();
|
virtual ~Stereo3DMode();
|
||||||
|
@ -84,6 +85,9 @@ public:
|
||||||
virtual void SetUp() const {};
|
virtual void SetUp() const {};
|
||||||
virtual void TearDown() const {};
|
virtual void TearDown() const {};
|
||||||
|
|
||||||
|
virtual bool IsMono() const { return false; }
|
||||||
|
virtual void Present() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TArray<const EyePose *> eye_ptrs;
|
TArray<const EyePose *> eye_ptrs;
|
||||||
|
|
||||||
|
@ -101,6 +105,9 @@ class MonoView : public Stereo3DMode
|
||||||
public:
|
public:
|
||||||
static const MonoView& getInstance();
|
static const MonoView& getInstance();
|
||||||
|
|
||||||
|
bool IsMono() const override { return true; }
|
||||||
|
void Present() const override { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MonoView() { eye_ptrs.Push(¢ralEye); }
|
MonoView() { eye_ptrs.Push(¢ralEye); }
|
||||||
EyePose centralEye;
|
EyePose centralEye;
|
||||||
|
|
|
@ -105,5 +105,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
||||||
return *currentStereo3DMode;
|
return *currentStereo3DMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Stereo3DMode& Stereo3DMode::getMonoMode()
|
||||||
|
{
|
||||||
|
setCurrentMode(MonoView::getInstance());
|
||||||
|
return *currentStereo3DMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,10 @@
|
||||||
#include "vectors.h" // RAD2DEG
|
#include "vectors.h" // RAD2DEG
|
||||||
#include "doomtype.h" // M_PI
|
#include "doomtype.h" // M_PI
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
EXTERN_CVAR(Float, vr_screendist)
|
EXTERN_CVAR(Float, vr_screendist)
|
||||||
|
@ -89,6 +92,13 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeftEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
|
@ -98,5 +108,13 @@ const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RightEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
|
@ -83,6 +83,7 @@ public:
|
||||||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
LeftEyePose eye;
|
LeftEyePose eye;
|
||||||
};
|
};
|
||||||
|
@ -96,6 +97,7 @@ public:
|
||||||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
RightEyePose eye;
|
RightEyePose eye;
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,9 +24,6 @@ EXTERN_CVAR(Int, gl_weaponlight)
|
||||||
EXTERN_CVAR (Bool, gl_lights);
|
EXTERN_CVAR (Bool, gl_lights);
|
||||||
EXTERN_CVAR (Bool, gl_attachedlights);
|
EXTERN_CVAR (Bool, gl_attachedlights);
|
||||||
EXTERN_CVAR (Bool, gl_lights_checkside);
|
EXTERN_CVAR (Bool, gl_lights_checkside);
|
||||||
EXTERN_CVAR (Float, gl_lights_intensity);
|
|
||||||
EXTERN_CVAR (Float, gl_lights_size);
|
|
||||||
EXTERN_CVAR (Bool, gl_lights_additive);
|
|
||||||
EXTERN_CVAR (Bool, gl_light_sprites);
|
EXTERN_CVAR (Bool, gl_light_sprites);
|
||||||
EXTERN_CVAR (Bool, gl_light_particles);
|
EXTERN_CVAR (Bool, gl_light_particles);
|
||||||
EXTERN_CVAR (Int, gl_light_math);
|
EXTERN_CVAR (Int, gl_light_math);
|
||||||
|
|
|
@ -189,7 +189,8 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
|
|
||||||
void OpenGLFrameBuffer::WipeEndScreen()
|
void OpenGLFrameBuffer::WipeEndScreen()
|
||||||
{
|
{
|
||||||
GLRenderer->m2DDrawer->Flush();
|
GLRenderer->m2DDrawer->Draw();
|
||||||
|
GLRenderer->m2DDrawer->Clear();
|
||||||
|
|
||||||
const auto &viewport = GLRenderer->mScreenViewport;
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
||||||
|
|
|
@ -43,15 +43,21 @@
|
||||||
#ifdef HAVE_MMX
|
#ifdef HAVE_MMX
|
||||||
#include "gl/hqnx_asm/hqnx_asm.h"
|
#include "gl/hqnx_asm/hqnx_asm.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "gl/xbr/xbrz.h"
|
||||||
|
#include "gl/xbr/xbrz_old.h"
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_MMX
|
if (self < 0 || self > 16)
|
||||||
if (self < 0 || self > 9)
|
{
|
||||||
#else
|
|
||||||
if (self < 0 || self > 6)
|
|
||||||
#endif
|
|
||||||
self = 0;
|
self = 0;
|
||||||
|
}
|
||||||
|
#ifndef HAVE_MMX
|
||||||
|
// This is to allow the menu option to work properly so that these filters can be skipped while cycling through them.
|
||||||
|
if (self == 7) self = 10;
|
||||||
|
if (self == 8) self = 10;
|
||||||
|
if (self == 9) self = 6;
|
||||||
|
#endif
|
||||||
GLRenderer->FlushTextures();
|
GLRenderer->FlushTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +248,42 @@ static unsigned char *hqNxHelper( void (*hqNxFunction) ( unsigned*, unsigned*, i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned char *xbrzHelper( void (*xbrzFunction) ( size_t, const uint32_t*, uint32_t*, int, int, xbrz::ColorFormat, const xbrz::ScalerCfg&, int, int ),
|
||||||
|
const int N,
|
||||||
|
unsigned char *inputBuffer,
|
||||||
|
const int inWidth,
|
||||||
|
const int inHeight,
|
||||||
|
int &outWidth,
|
||||||
|
int &outHeight )
|
||||||
|
{
|
||||||
|
outWidth = N * inWidth;
|
||||||
|
outHeight = N *inHeight;
|
||||||
|
|
||||||
|
unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
|
||||||
|
xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer), inWidth, inHeight, xbrz::ARGB, xbrz::ScalerCfg(), 0, std::numeric_limits<int>::max());
|
||||||
|
delete[] inputBuffer;
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char *xbrzoldHelper( void (*xbrzFunction) ( size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, const xbrz_old::ScalerCfg& cfg, int yFirst, int yLast ),
|
||||||
|
const int N,
|
||||||
|
unsigned char *inputBuffer,
|
||||||
|
const int inWidth,
|
||||||
|
const int inHeight,
|
||||||
|
int &outWidth,
|
||||||
|
int &outHeight )
|
||||||
|
{
|
||||||
|
outWidth = N * inWidth;
|
||||||
|
outHeight = N *inHeight;
|
||||||
|
|
||||||
|
unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
|
||||||
|
xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer), inWidth, inHeight, xbrz_old::ScalerCfg(), 0, std::numeric_limits<int>::max());
|
||||||
|
delete[] inputBuffer;
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns
|
// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns
|
||||||
|
@ -322,6 +364,16 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
|
||||||
case 9:
|
case 9:
|
||||||
return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||||
#endif
|
#endif
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
return xbrzHelper(xbrz::scale, type - 8, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
return xbrzoldHelper(xbrz_old::scale, type - 11, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inputBuffer;
|
return inputBuffer;
|
||||||
|
|
|
@ -64,18 +64,6 @@ extern int TexFormat[];
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
unsigned int FHardwareTexture::lastbound[FHardwareTexture::MAX_TEXTURES];
|
unsigned int FHardwareTexture::lastbound[FHardwareTexture::MAX_TEXTURES];
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// STATIC - Gets the maximum size of hardware textures
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
int FHardwareTexture::GetTexDimension(int value)
|
|
||||||
{
|
|
||||||
if (value > gl.max_texturesize) return gl.max_texturesize;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Quick'n dirty image rescaling.
|
// Quick'n dirty image rescaling.
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define DIRECT_PALETTE -2
|
#define DIRECT_PALETTE -2
|
||||||
|
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "gl/system/gl_interface.h"
|
||||||
|
|
||||||
class FCanvasTexture;
|
class FCanvasTexture;
|
||||||
class AActor;
|
class AActor;
|
||||||
|
@ -49,7 +50,11 @@ public:
|
||||||
|
|
||||||
static unsigned int lastbound[MAX_TEXTURES];
|
static unsigned int lastbound[MAX_TEXTURES];
|
||||||
|
|
||||||
static int GetTexDimension(int value);
|
static int GetTexDimension(int value)
|
||||||
|
{
|
||||||
|
if (value > gl.max_texturesize) return gl.max_texturesize;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static void InitGlobalState() { for (int i = 0; i < MAX_TEXTURES; i++) lastbound[i] = 0; }
|
static void InitGlobalState() { for (int i = 0; i < MAX_TEXTURES; i++) lastbound[i] = 0; }
|
||||||
|
|
||||||
|
|
|
@ -267,3 +267,5 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
1229
src/gl/xbr/xbrz.cpp
Normal file
1229
src/gl/xbr/xbrz.cpp
Normal file
File diff suppressed because it is too large
Load diff
102
src/gl/xbr/xbrz.h
Normal file
102
src/gl/xbr/xbrz.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// ****************************************************************************
|
||||||
|
// * This file is part of the HqMAME project. It is distributed under *
|
||||||
|
// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
|
||||||
|
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||||
|
// * *
|
||||||
|
// * Additionally and as a special exception, the author gives permission *
|
||||||
|
// * to link the code of this program with the MAME library (or with modified *
|
||||||
|
// * versions of MAME that use the same license as MAME), and distribute *
|
||||||
|
// * linked combinations including the two. You must obey the GNU General *
|
||||||
|
// * Public License in all respects for all of the code used other than MAME. *
|
||||||
|
// * If you modify this file, you may extend this exception to your version *
|
||||||
|
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||||
|
// * do so, delete this exception statement from your version. *
|
||||||
|
// * *
|
||||||
|
// * An explicit permission was granted to use xBRZ in combination with ZDoom *
|
||||||
|
// * and derived projects as long as it is used for non-commercial purposes. *
|
||||||
|
// * *
|
||||||
|
// * Backported to C++98 by Alexey Lysiuk *
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
#ifndef XBRZ_HEADER_3847894708239054
|
||||||
|
#define XBRZ_HEADER_3847894708239054
|
||||||
|
|
||||||
|
#include <cstddef> //size_t
|
||||||
|
#include <stdint.h> //uint32_t
|
||||||
|
#include <limits>
|
||||||
|
#include "xbrz_config.h"
|
||||||
|
|
||||||
|
namespace xbrz
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
| xBRZ: "Scale by rules" - high quality image upscaling filter by Zenju |
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
using a modified approach of xBR:
|
||||||
|
http://board.byuu.org/viewtopic.php?f=10&t=2248
|
||||||
|
- new rule set preserving small image features
|
||||||
|
- highly optimized for performance
|
||||||
|
- support alpha channel
|
||||||
|
- support multithreading
|
||||||
|
- support 64-bit architectures
|
||||||
|
- support processing image slices
|
||||||
|
- support scaling up to 6xBRZ
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ColorFormat //from high bits -> low bits, 8 bit per channel
|
||||||
|
{
|
||||||
|
RGB, //8 bit for each red, green, blue, upper 8 bits unused
|
||||||
|
ARGB, //including alpha channel, BGRA byte order on little-endian machines
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
-> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally processing a half-open slice of rows [yFirst, yLast) only
|
||||||
|
-> support for source/target pitch in bytes!
|
||||||
|
-> if your emulator changes only a few image slices during each cycle (e.g. DOSBox) then there's no need to run xBRZ on the complete image:
|
||||||
|
Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the additional range the xBRZ algorithm is using during analysis)
|
||||||
|
Caveat: If there are multiple changed slices, make sure they do not overlap after adding these additional rows in order to avoid a memory race condition
|
||||||
|
in the target image data if you are using multiple threads for processing each enlarged slice!
|
||||||
|
|
||||||
|
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap!
|
||||||
|
- there is a minor inefficiency for the first row of a slice, so avoid processing single rows only; suggestion: process 8-16 rows at least
|
||||||
|
*/
|
||||||
|
#ifdef max
|
||||||
|
#undef max
|
||||||
|
#endif
|
||||||
|
void scale(size_t factor, //valid range: 2 - 6
|
||||||
|
const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight,
|
||||||
|
ColorFormat colFmt,
|
||||||
|
const ScalerCfg& cfg = ScalerCfg(),
|
||||||
|
int yFirst = 0, int yLast = std::numeric_limits<int>::max()); //slice of source image
|
||||||
|
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight);
|
||||||
|
|
||||||
|
enum SliceType
|
||||||
|
{
|
||||||
|
NN_SCALE_SLICE_SOURCE,
|
||||||
|
NN_SCALE_SLICE_TARGET,
|
||||||
|
};
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes!
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight, int trgPitch,
|
||||||
|
SliceType st, int yFirst, int yLast);
|
||||||
|
|
||||||
|
//parameter tuning
|
||||||
|
bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//########################### implementation ###########################
|
||||||
|
inline
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight)
|
||||||
|
{
|
||||||
|
nearestNeighborScale(src, srcWidth, srcHeight, srcWidth * sizeof(uint32_t),
|
||||||
|
trg, trgWidth, trgHeight, trgWidth * sizeof(uint32_t),
|
||||||
|
NN_SCALE_SLICE_TARGET, 0, trgHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
45
src/gl/xbr/xbrz_config.h
Normal file
45
src/gl/xbr/xbrz_config.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// ****************************************************************************
|
||||||
|
// * This file is part of the HqMAME project. It is distributed under *
|
||||||
|
// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
|
||||||
|
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||||
|
// * *
|
||||||
|
// * Additionally and as a special exception, the author gives permission *
|
||||||
|
// * to link the code of this program with the MAME library (or with modified *
|
||||||
|
// * versions of MAME that use the same license as MAME), and distribute *
|
||||||
|
// * linked combinations including the two. You must obey the GNU General *
|
||||||
|
// * Public License in all respects for all of the code used other than MAME. *
|
||||||
|
// * If you modify this file, you may extend this exception to your version *
|
||||||
|
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||||
|
// * do so, delete this exception statement from your version. *
|
||||||
|
// * *
|
||||||
|
// * An explicit permission was granted to use xBRZ in combination with ZDoom *
|
||||||
|
// * and derived projects as long as it is used for non-commercial purposes. *
|
||||||
|
// * *
|
||||||
|
// * Backported to C++98 by Alexey Lysiuk *
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
#ifndef XBRZ_CONFIG_HEADER_284578425345
|
||||||
|
#define XBRZ_CONFIG_HEADER_284578425345
|
||||||
|
|
||||||
|
//do NOT include any headers here! used by xBRZ_dll!!!
|
||||||
|
|
||||||
|
namespace xbrz
|
||||||
|
{
|
||||||
|
struct ScalerCfg
|
||||||
|
{
|
||||||
|
ScalerCfg() :
|
||||||
|
luminanceWeight(1),
|
||||||
|
equalColorTolerance(30),
|
||||||
|
dominantDirectionThreshold(3.6),
|
||||||
|
steepDirectionThreshold(2.2),
|
||||||
|
newTestAttribute(0) {}
|
||||||
|
|
||||||
|
double luminanceWeight;
|
||||||
|
double equalColorTolerance;
|
||||||
|
double dominantDirectionThreshold;
|
||||||
|
double steepDirectionThreshold;
|
||||||
|
double newTestAttribute; //unused; test new parameters
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
45
src/gl/xbr/xbrz_config_old.h
Normal file
45
src/gl/xbr/xbrz_config_old.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// ****************************************************************************
|
||||||
|
// * This file is part of the HqMAME project. It is distributed under *
|
||||||
|
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
|
||||||
|
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||||
|
// * *
|
||||||
|
// * Additionally and as a special exception, the author gives permission *
|
||||||
|
// * to link the code of this program with the MAME library (or with modified *
|
||||||
|
// * versions of MAME that use the same license as MAME), and distribute *
|
||||||
|
// * linked combinations including the two. You must obey the GNU General *
|
||||||
|
// * Public License in all respects for all of the code used other than MAME. *
|
||||||
|
// * If you modify this file, you may extend this exception to your version *
|
||||||
|
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||||
|
// * do so, delete this exception statement from your version. *
|
||||||
|
// * *
|
||||||
|
// * An explicit permission was granted to use xBRZ in combination with ZDoom *
|
||||||
|
// * and derived projects as long as it is used for non-commercial purposes. *
|
||||||
|
// * *
|
||||||
|
// * Backported to C++98 by Alexey Lysiuk *
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
#ifndef __XBRZ_CONFIG_OLD_HEADER_INCLUDED__
|
||||||
|
#define __XBRZ_CONFIG_OLD_HEADER_INCLUDED__
|
||||||
|
|
||||||
|
//do NOT include any headers here! used by xBRZ_dll!!!
|
||||||
|
|
||||||
|
namespace xbrz_old
|
||||||
|
{
|
||||||
|
struct ScalerCfg
|
||||||
|
{
|
||||||
|
ScalerCfg() :
|
||||||
|
luminanceWeight_(1),
|
||||||
|
equalColorTolerance_(30),
|
||||||
|
dominantDirectionThreshold(3.6),
|
||||||
|
steepDirectionThreshold(2.2),
|
||||||
|
newTestAttribute_(0) {}
|
||||||
|
|
||||||
|
double luminanceWeight_;
|
||||||
|
double equalColorTolerance_;
|
||||||
|
double dominantDirectionThreshold;
|
||||||
|
double steepDirectionThreshold;
|
||||||
|
double newTestAttribute_; //unused; test new parameters
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1365
src/gl/xbr/xbrz_old.cpp
Normal file
1365
src/gl/xbr/xbrz_old.cpp
Normal file
File diff suppressed because it is too large
Load diff
92
src/gl/xbr/xbrz_old.h
Normal file
92
src/gl/xbr/xbrz_old.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// ****************************************************************************
|
||||||
|
// * This file is part of the HqMAME project. It is distributed under *
|
||||||
|
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
|
||||||
|
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||||
|
// * *
|
||||||
|
// * Additionally and as a special exception, the author gives permission *
|
||||||
|
// * to link the code of this program with the MAME library (or with modified *
|
||||||
|
// * versions of MAME that use the same license as MAME), and distribute *
|
||||||
|
// * linked combinations including the two. You must obey the GNU General *
|
||||||
|
// * Public License in all respects for all of the code used other than MAME. *
|
||||||
|
// * If you modify this file, you may extend this exception to your version *
|
||||||
|
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||||
|
// * do so, delete this exception statement from your version. *
|
||||||
|
// * *
|
||||||
|
// * An explicit permission was granted to use xBRZ in combination with ZDoom *
|
||||||
|
// * and derived projects as long as it is used for non-commercial purposes. *
|
||||||
|
// * *
|
||||||
|
// * Backported to C++98 by Alexey Lysiuk *
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
#ifndef __XBRZ_OLD_HEADER_INCLUDED__
|
||||||
|
#define __XBRZ_OLD_HEADER_INCLUDED__
|
||||||
|
|
||||||
|
#include <cstddef> //size_t
|
||||||
|
#include <stdint.h> //uint32_t
|
||||||
|
#include <limits>
|
||||||
|
#include "xbrz_config_old.h"
|
||||||
|
|
||||||
|
namespace xbrz_old
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
| xBRZ: "Scale by rules" - high quality image upscaling filter by Zenju |
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
using a modified approach of xBR:
|
||||||
|
http://board.byuu.org/viewtopic.php?f=10&t=2248
|
||||||
|
- new rule set preserving small image features
|
||||||
|
- support multithreading
|
||||||
|
- support 64 bit architectures
|
||||||
|
- support processing image slices
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
-> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally processing a half-open slice of rows [yFirst, yLast) only
|
||||||
|
-> color format: ARGB (BGRA byte order), alpha channel unused
|
||||||
|
-> support for source/target pitch in bytes!
|
||||||
|
-> if your emulator changes only a few image slices during each cycle (e.g. Dosbox) then there's no need to run xBRZ on the complete image:
|
||||||
|
Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the additional range the xBRZ algorithm is using during analysis)
|
||||||
|
Caveat: If there are multiple changed slices, make sure they do not overlap after adding these additional rows in order to avoid a memory race condition
|
||||||
|
if you are using multiple threads for processing each enlarged slice!
|
||||||
|
|
||||||
|
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap!
|
||||||
|
- there is a minor inefficiency for the first row of a slice, so avoid processing single rows only
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
void scale(size_t factor, //valid range: 2 - 5
|
||||||
|
const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight,
|
||||||
|
const ScalerCfg& cfg = ScalerCfg(),
|
||||||
|
int yFirst = 0, int yLast = std::numeric_limits<int>::max()); //slice of source image
|
||||||
|
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight);
|
||||||
|
|
||||||
|
enum SliceType
|
||||||
|
{
|
||||||
|
NN_SCALE_SLICE_SOURCE,
|
||||||
|
NN_SCALE_SLICE_TARGET,
|
||||||
|
};
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes!
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight, int trgPitch,
|
||||||
|
SliceType st, int yFirst, int yLast);
|
||||||
|
|
||||||
|
//parameter tuning
|
||||||
|
bool equalColor(uint32_t col1, uint32_t col2, double luminanceWeight, double equalColorTolerance);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//########################### implementation ###########################
|
||||||
|
inline
|
||||||
|
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||||
|
uint32_t* trg, int trgWidth, int trgHeight)
|
||||||
|
{
|
||||||
|
nearestNeighborScale(src, srcWidth, srcHeight, srcWidth * sizeof(uint32_t),
|
||||||
|
trg, trgWidth, trgHeight, trgWidth * sizeof(uint32_t),
|
||||||
|
NN_SCALE_SLICE_TARGET, 0, trgHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -4450,6 +4450,8 @@ enum EACSFunctions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ACSF_CheckClass = 200,
|
ACSF_CheckClass = 200,
|
||||||
|
ACSF_DamageActor, // [arookas]
|
||||||
|
ACSF_SetActorFlag,
|
||||||
|
|
||||||
// ZDaemon
|
// ZDaemon
|
||||||
ACSF_GetTeamScore = 19620, // (int team)
|
ACSF_GetTeamScore = 19620, // (int team)
|
||||||
|
@ -6035,6 +6037,43 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
const char *clsname = FBehavior::StaticLookupString(args[0]);
|
const char *clsname = FBehavior::StaticLookupString(args[0]);
|
||||||
return !!PClass::FindActor(clsname);
|
return !!PClass::FindActor(clsname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACSF_DamageActor: // [arookas] wrapper around P_DamageMobj
|
||||||
|
{
|
||||||
|
// (target, ptr_select1, inflictor, ptr_select2, amount, damagetype)
|
||||||
|
AActor* target = COPY_AAPTR(SingleActorFromTID(args[0], activator), args[1]);
|
||||||
|
AActor* inflictor = COPY_AAPTR(SingleActorFromTID(args[2], activator), args[3]);
|
||||||
|
FName damagetype(FBehavior::StaticLookupString(args[5]));
|
||||||
|
return P_DamageMobj(target, inflictor, inflictor, args[4], damagetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ACSF_SetActorFlag:
|
||||||
|
{
|
||||||
|
int tid = args[0];
|
||||||
|
FString flagname = FBehavior::StaticLookupString(args[1]);
|
||||||
|
bool flagvalue = !!args[2];
|
||||||
|
int count = 0; // Return value; number of actors affected
|
||||||
|
if (tid == 0)
|
||||||
|
{
|
||||||
|
if (ModActorFlag(activator, flagname, flagvalue))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FActorIterator it(tid);
|
||||||
|
while ((actor = it.Next()) != nullptr)
|
||||||
|
{
|
||||||
|
// Don't log errors when affecting many actors because things might share a TID but not share the flag
|
||||||
|
if (ModActorFlag(actor, flagname, flagvalue, false))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -459,23 +459,14 @@ CocoaWindow* CreateCocoaWindow(const NSUInteger styleMask)
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
enum OpenGLProfile
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
CocoaVideo::CocoaVideo()
|
|
||||||
: m_window(CreateCocoaWindow(STYLE_MASK_WINDOWED))
|
|
||||||
, m_width(-1)
|
|
||||||
, m_height(-1)
|
|
||||||
, m_fullscreen(false)
|
|
||||||
, m_hiDPI(false)
|
|
||||||
{
|
{
|
||||||
memset(&m_modeIterator, 0, sizeof m_modeIterator);
|
Core,
|
||||||
|
Legacy
|
||||||
// Set attributes for OpenGL context
|
};
|
||||||
|
|
||||||
|
NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile)
|
||||||
|
{
|
||||||
NSOpenGLPixelFormatAttribute attributes[16];
|
NSOpenGLPixelFormatAttribute attributes[16];
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
|
@ -492,17 +483,59 @@ CocoaVideo::CocoaVideo()
|
||||||
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NSAppKitVersionNumber >= AppKit10_7)
|
if (NSAppKitVersionNumber >= AppKit10_7 && OpenGLProfile::Core == profile)
|
||||||
{
|
{
|
||||||
|
NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersion3_2Core;
|
||||||
|
const char* const glversion = Args->CheckValue("-glversion");
|
||||||
|
|
||||||
|
if (nullptr != glversion)
|
||||||
|
{
|
||||||
|
const double version = strtod(glversion, nullptr) + 0.01;
|
||||||
|
if (version < 3.2)
|
||||||
|
{
|
||||||
|
profile = NSOpenGLProfileVersionLegacy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
attributes[i++] = NSOpenGLPFAOpenGLProfile;
|
attributes[i++] = NSOpenGLPFAOpenGLProfile;
|
||||||
attributes[i++] = NSOpenGLProfileVersion3_2Core;
|
attributes[i++] = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes[i] = NSOpenGLPixelFormatAttribute(0);
|
attributes[i] = NSOpenGLPixelFormatAttribute(0);
|
||||||
|
|
||||||
// Create OpenGL context and view
|
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||||
|
}
|
||||||
|
|
||||||
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
CocoaVideo::CocoaVideo()
|
||||||
|
: m_window(CreateCocoaWindow(STYLE_MASK_WINDOWED))
|
||||||
|
, m_width(-1)
|
||||||
|
, m_height(-1)
|
||||||
|
, m_fullscreen(false)
|
||||||
|
, m_hiDPI(false)
|
||||||
|
{
|
||||||
|
memset(&m_modeIterator, 0, sizeof m_modeIterator);
|
||||||
|
|
||||||
|
// Create OpenGL pixel format
|
||||||
|
|
||||||
|
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat(OpenGLProfile::Core);
|
||||||
|
|
||||||
|
if (nil == pixelFormat)
|
||||||
|
{
|
||||||
|
pixelFormat = CreatePixelFormat(OpenGLProfile::Legacy);
|
||||||
|
|
||||||
|
if (nil == pixelFormat)
|
||||||
|
{
|
||||||
|
I_FatalError("Cannot OpenGL create pixel format, graphics hardware is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create OpenGL context and view
|
||||||
|
|
||||||
const NSRect contentRect = [m_window contentRectForFrameRect:[m_window frame]];
|
const NSRect contentRect = [m_window contentRectForFrameRect:[m_window frame]];
|
||||||
NSOpenGLView* glView = [[CocoaView alloc] initWithFrame:contentRect
|
NSOpenGLView* glView = [[CocoaView alloc] initWithFrame:contentRect
|
||||||
|
|
187
src/posix/osx/i_specialpaths.mm
Normal file
187
src/posix/osx/i_specialpaths.mm
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
** i_specialpaths.mm
|
||||||
|
** Gets special system folders where data should be stored. (macOS version)
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2013-2016 Randy Heit
|
||||||
|
** Copyright 2016 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 <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
#include "version.h" // for GAMENAME
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetCachePath macOS
|
||||||
|
//
|
||||||
|
// Returns the path for cache GL nodes.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetCachePath(bool create)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
char pathstr[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX))
|
||||||
|
{
|
||||||
|
path = pathstr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = progdir;
|
||||||
|
}
|
||||||
|
path += "/zdoom/cache";
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetAutoexecPath macOS
|
||||||
|
//
|
||||||
|
// Returns the expected location of autoexec.cfg.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetAutoexecPath()
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
||||||
|
{
|
||||||
|
path << cpath << "/" GAME_DIR "/autoexec.cfg";
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetCajunPath macOS
|
||||||
|
//
|
||||||
|
// Returns the location of the Cajun Bot definitions.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetCajunPath(const char *botfilename)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
// Just copies the Windows code. Should this be more Mac-specific?
|
||||||
|
path << progdir << "zcajun/" << botfilename;
|
||||||
|
if (!FileExists(path))
|
||||||
|
{
|
||||||
|
path = "";
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetConfigPath macOS
|
||||||
|
//
|
||||||
|
// Returns the path to the config file. On Windows, this can vary for reading
|
||||||
|
// vs writing. i.e. If $PROGDIR/zdoom-<user>.ini does not exist, it will try
|
||||||
|
// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetConfigPath(bool for_reading)
|
||||||
|
{
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kPreferencesFolderType, kCreateFolder, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
path << cpath << "/" GAMENAMELOWERCASE ".ini";
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
// Ungh.
|
||||||
|
return GAMENAMELOWERCASE ".ini";
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetScreenshotsPath macOS
|
||||||
|
//
|
||||||
|
// Returns the path to the default screenshots directory.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetScreenshotsPath()
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
||||||
|
{
|
||||||
|
path << cpath << "/" GAME_DIR "/Screenshots/";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = "~/";
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetSavegamesPath macOS
|
||||||
|
//
|
||||||
|
// Returns the path to the default save games directory.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetSavegamesPath()
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
||||||
|
{
|
||||||
|
path << cpath << "/" GAME_DIR "/Savegames/";
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
200
src/posix/unix/i_specialpaths.cpp
Normal file
200
src/posix/unix/i_specialpaths.cpp
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
** i_specialpaths.cpp
|
||||||
|
** Gets special system folders where data should be stored. (Unix version)
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2013-2016 Randy Heit
|
||||||
|
** Copyright 2016 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 <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
|
#include "version.h" // for GAMENAME
|
||||||
|
|
||||||
|
|
||||||
|
FString GetUserFile (const char *file)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
path = NicePath("~/" GAME_DIR "/");
|
||||||
|
|
||||||
|
if (stat (path, &info) == -1)
|
||||||
|
{
|
||||||
|
struct stat extrainfo;
|
||||||
|
|
||||||
|
// Sanity check for ~/.config
|
||||||
|
FString configPath = NicePath("~/.config/");
|
||||||
|
if (stat (configPath, &extrainfo) == -1)
|
||||||
|
{
|
||||||
|
if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
||||||
|
{
|
||||||
|
I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!S_ISDIR(extrainfo.st_mode))
|
||||||
|
{
|
||||||
|
I_FatalError ("~/.config must be a directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be removed after a release or two
|
||||||
|
// Transfer the old zdoom directory to the new location
|
||||||
|
bool moved = false;
|
||||||
|
FString oldpath = NicePath("~/." GAMENAMELOWERCASE "/");
|
||||||
|
if (stat (oldpath, &extrainfo) != -1)
|
||||||
|
{
|
||||||
|
if (rename(oldpath, path) == -1)
|
||||||
|
{
|
||||||
|
I_Error ("Failed to move old " GAMENAMELOWERCASE " directory (%s) to new location (%s).",
|
||||||
|
oldpath.GetChars(), path.GetChars());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
||||||
|
{
|
||||||
|
I_FatalError ("Failed to create %s directory:\n%s",
|
||||||
|
path.GetChars(), strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(info.st_mode))
|
||||||
|
{
|
||||||
|
I_FatalError ("%s must be a directory", path.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path += file;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetCachePath Unix
|
||||||
|
//
|
||||||
|
// Returns the path for cache GL nodes.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetCachePath(bool create)
|
||||||
|
{
|
||||||
|
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||||
|
// share the node cache.
|
||||||
|
FString path = NicePath("~/.config/zdoom/cache");
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
CreatePath(path);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetAutoexecPath Unix
|
||||||
|
//
|
||||||
|
// Returns the expected location of autoexec.cfg.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetAutoexecPath()
|
||||||
|
{
|
||||||
|
return GetUserFile("autoexec.cfg");
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetCajunPath Unix
|
||||||
|
//
|
||||||
|
// Returns the location of the Cajun Bot definitions.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetCajunPath(const char *botfilename)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
// Check first in ~/.config/zdoom/botfilename.
|
||||||
|
path = GetUserFile(botfilename);
|
||||||
|
if (!FileExists(path))
|
||||||
|
{
|
||||||
|
// Then check in SHARE_DIR/botfilename.
|
||||||
|
path = SHARE_DIR;
|
||||||
|
path << botfilename;
|
||||||
|
if (!FileExists(path))
|
||||||
|
{
|
||||||
|
path = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetConfigPath Unix
|
||||||
|
//
|
||||||
|
// Returns the path to the config file. On Windows, this can vary for reading
|
||||||
|
// vs writing. i.e. If $PROGDIR/zdoom-<user>.ini does not exist, it will try
|
||||||
|
// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetConfigPath(bool for_reading)
|
||||||
|
{
|
||||||
|
return GetUserFile(GAMENAMELOWERCASE ".ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetScreenshotsPath Unix
|
||||||
|
//
|
||||||
|
// Returns the path to the default screenshots directory.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetScreenshotsPath()
|
||||||
|
{
|
||||||
|
return NicePath("~/" GAME_DIR "/screenshots/");
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetSavegamesPath Unix
|
||||||
|
//
|
||||||
|
// Returns the path to the default save games directory.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetSavegamesPath()
|
||||||
|
{
|
||||||
|
return NicePath("~/" GAME_DIR);
|
||||||
|
}
|
|
@ -656,7 +656,7 @@ void R_AddInterpolationPoint(const DVector3a &vec)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static double QuakePower(double factor, double intensity, double offset, double falloff, double wfalloff)
|
static double QuakePower(double factor, double intensity, double offset)
|
||||||
{
|
{
|
||||||
double randumb;
|
double randumb;
|
||||||
if (intensity == 0)
|
if (intensity == 0)
|
||||||
|
@ -667,7 +667,7 @@ static double QuakePower(double factor, double intensity, double offset, double
|
||||||
{
|
{
|
||||||
randumb = pr_torchflicker.GenRand_Real2() * (intensity * 2) - intensity;
|
randumb = pr_torchflicker.GenRand_Real2() * (intensity * 2) - intensity;
|
||||||
}
|
}
|
||||||
return factor * (wfalloff * offset + falloff * randumb);
|
return factor * (offset + randumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -797,36 +797,36 @@ void R_SetupFrame (AActor *actor)
|
||||||
|
|
||||||
if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0)
|
if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0)
|
||||||
{
|
{
|
||||||
ViewRoll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave, jiggers.RFalloff, jiggers.RWFalloff);
|
ViewRoll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave);
|
||||||
}
|
}
|
||||||
if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0)
|
if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0)
|
||||||
{
|
{
|
||||||
an = camera->Angles.Yaw;
|
an = camera->Angles.Yaw;
|
||||||
double power = QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X, jiggers.Falloff, jiggers.WFalloff);
|
double power = QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X);
|
||||||
ViewPos += an.ToVector(power);
|
ViewPos += an.ToVector(power);
|
||||||
}
|
}
|
||||||
if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0)
|
if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0)
|
||||||
{
|
{
|
||||||
an = camera->Angles.Yaw + 90;
|
an = camera->Angles.Yaw + 90;
|
||||||
double power = QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y, jiggers.Falloff, jiggers.WFalloff);
|
double power = QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y);
|
||||||
ViewPos += an.ToVector(power);
|
ViewPos += an.ToVector(power);
|
||||||
}
|
}
|
||||||
// FIXME: Relative Z is not relative
|
// FIXME: Relative Z is not relative
|
||||||
if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0)
|
if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0)
|
||||||
{
|
{
|
||||||
ViewPos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z, jiggers.Falloff, jiggers.WFalloff);
|
ViewPos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z);
|
||||||
}
|
}
|
||||||
if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0)
|
if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0)
|
||||||
{
|
{
|
||||||
ViewPos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X, jiggers.Falloff, jiggers.WFalloff);
|
ViewPos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X);
|
||||||
}
|
}
|
||||||
if (jiggers.Intensity.Y != 0 || jiggers.Offset.Y != 0)
|
if (jiggers.Intensity.Y != 0 || jiggers.Offset.Y != 0)
|
||||||
{
|
{
|
||||||
ViewPos.Y += QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y, jiggers.Falloff, jiggers.WFalloff);
|
ViewPos.Y += QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y);
|
||||||
}
|
}
|
||||||
if (jiggers.Intensity.Z != 0 || jiggers.Offset.Z != 0)
|
if (jiggers.Intensity.Z != 0 || jiggers.Offset.Z != 0)
|
||||||
{
|
{
|
||||||
ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z, jiggers.Falloff, jiggers.WFalloff);
|
ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,7 +380,7 @@ struct bCopyAlpha
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bOverlay
|
struct bOverlay
|
||||||
{
|
{
|
||||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; }
|
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; }
|
||||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = MAX(s,d); }
|
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = MAX(s,d); }
|
||||||
static __forceinline bool ProcessAlpha0() { return false; }
|
static __forceinline bool ProcessAlpha0() { return false; }
|
||||||
|
|
|
@ -628,8 +628,9 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
||||||
{
|
{
|
||||||
ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info);
|
ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info);
|
||||||
}
|
}
|
||||||
|
// treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done.
|
||||||
if (ret > retv) retv = ret;
|
if (ret == -1) retv = ret;
|
||||||
|
else if (retv != -1 && ret > retv) retv = ret;
|
||||||
}
|
}
|
||||||
// Restore previous clipping rectangle.
|
// Restore previous clipping rectangle.
|
||||||
bmp->SetClipRect(saved_cr);
|
bmp->SetClipRect(saved_cr);
|
||||||
|
|
|
@ -30,6 +30,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
|
||||||
bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index);
|
bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index);
|
||||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||||
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
||||||
|
bool ModActorFlag(AActor *actor, FString &flagname, bool set, bool printerror = true);
|
||||||
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
||||||
INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror = true);
|
INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror = true);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "p_maputl.h"
|
#include "p_maputl.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
|
#include "templates.h"
|
||||||
#include "math/cmath.h"
|
#include "math/cmath.h"
|
||||||
|
|
||||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||||
|
@ -1421,7 +1422,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
||||||
damagetype = self->DamageType;
|
damagetype = self->DamageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = P_RadiusAttack (self, self->target, damage, distance, damagetype, flags, fulldmgdistance);
|
int pflags = 0;
|
||||||
|
if (flags & XF_HURTSOURCE) pflags |= RADF_HURTSOURCE;
|
||||||
|
if (flags & XF_NOTMISSILE) pflags |= RADF_SOURCEISSPOT;
|
||||||
|
|
||||||
|
int count = P_RadiusAttack (self, self->target, damage, distance, damagetype, pflags, fulldmgdistance);
|
||||||
P_CheckSplash(self, distance);
|
P_CheckSplash(self, distance);
|
||||||
if (alert && self->target != NULL && self->target->player != NULL)
|
if (alert && self->target != NULL && self->target->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -4501,7 +4506,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
|
||||||
else { target = viewport; viewport = self; }
|
else { target = viewport; viewport = self; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fov > 0 && (fov < 360.))
|
fov = MIN<DAngle>(fov, 360.);
|
||||||
|
|
||||||
|
if (fov > 0)
|
||||||
{
|
{
|
||||||
DAngle an = absangle(viewport->AngleTo(target), viewport->Angles.Yaw);
|
DAngle an = absangle(viewport->AngleTo(target), viewport->Angles.Yaw);
|
||||||
|
|
||||||
|
@ -4678,90 +4685,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
||||||
PARAM_STRING (flagname);
|
PARAM_STRING (flagname);
|
||||||
PARAM_BOOL (value);
|
PARAM_BOOL (value);
|
||||||
|
|
||||||
const char *dot = strchr(flagname, '.');
|
ModActorFlag(self, flagname, value);
|
||||||
FFlagDef *fd;
|
|
||||||
PClassActor *cls = self->GetClass();
|
|
||||||
|
|
||||||
if (dot != NULL)
|
|
||||||
{
|
|
||||||
FString part1(flagname.GetChars(), dot - flagname);
|
|
||||||
fd = FindFlag(cls, part1, dot + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fd = FindFlag(cls, flagname, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd != NULL)
|
|
||||||
{
|
|
||||||
bool kill_before, kill_after;
|
|
||||||
INTBOOL item_before, item_after;
|
|
||||||
INTBOOL secret_before, secret_after;
|
|
||||||
|
|
||||||
kill_before = self->CountsAsKill();
|
|
||||||
item_before = self->flags & MF_COUNTITEM;
|
|
||||||
secret_before = self->flags5 & MF5_COUNTSECRET;
|
|
||||||
|
|
||||||
if (fd->structoffset == -1)
|
|
||||||
{
|
|
||||||
HandleDeprecatedFlags(self, cls, value, fd->flagbit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ActorFlags *flagp = (ActorFlags*) (((char*)self) + fd->structoffset);
|
|
||||||
|
|
||||||
// If these 2 flags get changed we need to update the blockmap and sector links.
|
|
||||||
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
|
||||||
|
|
||||||
if (linkchange) self->UnlinkFromWorld();
|
|
||||||
ModActorFlag(self, fd, value);
|
|
||||||
if (linkchange) self->LinkToWorld();
|
|
||||||
}
|
|
||||||
kill_after = self->CountsAsKill();
|
|
||||||
item_after = self->flags & MF_COUNTITEM;
|
|
||||||
secret_after = self->flags5 & MF5_COUNTSECRET;
|
|
||||||
// Was this monster previously worth a kill but no longer is?
|
|
||||||
// Or vice versa?
|
|
||||||
if (kill_before != kill_after)
|
|
||||||
{
|
|
||||||
if (kill_after)
|
|
||||||
{ // It counts as a kill now.
|
|
||||||
level.total_monsters++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as a kill.
|
|
||||||
level.total_monsters--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// same for items
|
|
||||||
if (item_before != item_after)
|
|
||||||
{
|
|
||||||
if (item_after)
|
|
||||||
{ // It counts as an item now.
|
|
||||||
level.total_items++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as an item
|
|
||||||
level.total_items--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// and secretd
|
|
||||||
if (secret_before != secret_after)
|
|
||||||
{
|
|
||||||
if (secret_after)
|
|
||||||
{ // It counts as an secret now.
|
|
||||||
level.total_secrets++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as an secret
|
|
||||||
level.total_secrets--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Printf("Unknown flag '%s' in '%s'\n", flagname.GetChars(), cls->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,7 @@ static FFlagDef ActorFlagDefs[]=
|
||||||
DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4),
|
DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4),
|
||||||
|
|
||||||
DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5),
|
DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5),
|
||||||
|
DEFINE_FLAG(MF5, GETOWNER, AActor, flags5),
|
||||||
DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5),
|
DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5),
|
||||||
DEFINE_FLAG(MF5, NOFORWARDFALL, AActor, flags5),
|
DEFINE_FLAG(MF5, NOFORWARDFALL, AActor, flags5),
|
||||||
DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5),
|
DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5),
|
||||||
|
|
|
@ -309,7 +309,8 @@ static FxExpression *ParseExpressionC (FScanner &sc, PClassActor *cls)
|
||||||
static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls)
|
static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls)
|
||||||
{
|
{
|
||||||
sc.GetToken();
|
sc.GetToken();
|
||||||
switch(sc.TokenType)
|
int token = sc.TokenType;
|
||||||
|
switch(token)
|
||||||
{
|
{
|
||||||
case '~':
|
case '~':
|
||||||
return new FxUnaryNotBitwise(ParseExpressionA (sc, cls));
|
return new FxUnaryNotBitwise(ParseExpressionA (sc, cls));
|
||||||
|
@ -325,7 +326,7 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls)
|
||||||
|
|
||||||
case TK_Incr:
|
case TK_Incr:
|
||||||
case TK_Decr:
|
case TK_Decr:
|
||||||
return new FxPreIncrDecr(ParseExpressionA(sc, cls), sc.TokenType);
|
return new FxPreIncrDecr(ParseExpressionA(sc, cls), token);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sc.UnGet();
|
sc.UnGet();
|
||||||
|
|
|
@ -162,6 +162,71 @@ void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Finds a flag by name and sets or clears it
|
||||||
|
//
|
||||||
|
// Returns true if the flag was found for the actor; else returns false
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool ModActorFlag(AActor *actor, FString &flagname, bool set, bool printerror)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (actor != NULL)
|
||||||
|
{
|
||||||
|
const char *dot = strchr(flagname, '.');
|
||||||
|
FFlagDef *fd;
|
||||||
|
PClassActor *cls = actor->GetClass();
|
||||||
|
|
||||||
|
if (dot != NULL)
|
||||||
|
{
|
||||||
|
FString part1(flagname.GetChars(), dot - flagname);
|
||||||
|
fd = FindFlag(cls, part1, dot + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd = FindFlag(cls, flagname, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd != NULL)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (actor->CountsAsKill() && actor->health > 0) --level.total_monsters;
|
||||||
|
if (actor->flags & MF_COUNTITEM) --level.total_items;
|
||||||
|
if (actor->flags5 & MF5_COUNTSECRET) --level.total_secrets;
|
||||||
|
|
||||||
|
if (fd->structoffset == -1)
|
||||||
|
{
|
||||||
|
HandleDeprecatedFlags(actor, cls, set, fd->flagbit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActorFlags *flagp = (ActorFlags*)(((char*)actor) + fd->structoffset);
|
||||||
|
|
||||||
|
// If these 2 flags get changed we need to update the blockmap and sector links.
|
||||||
|
bool linkchange = flagp == &actor->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
||||||
|
|
||||||
|
if (linkchange) actor->UnlinkFromWorld();
|
||||||
|
ModActorFlag(actor, fd, set);
|
||||||
|
if (linkchange) actor->LinkToWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters;
|
||||||
|
if (actor->flags & MF_COUNTITEM) ++level.total_items;
|
||||||
|
if (actor->flags5 & MF5_COUNTSECRET) ++level.total_secrets;
|
||||||
|
}
|
||||||
|
else if (printerror)
|
||||||
|
{
|
||||||
|
DPrintf(DMSG_ERROR, "ACS/DECORATE: '%s' is not a flag in '%s'\n", flagname.GetChars(), cls->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Returns whether an actor flag is true or not.
|
// Returns whether an actor flag is true or not.
|
||||||
|
|
|
@ -62,6 +62,14 @@
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Int, uiscale, 2, CVAR_ARCHIVE | CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
if (StatusBar != NULL)
|
||||||
|
{
|
||||||
|
StatusBar->ScreenSizeChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [RH] Stretch values to make a 320x200 image best fit the screen
|
// [RH] Stretch values to make a 320x200 image best fit the screen
|
||||||
// without using fractional steppings
|
// without using fractional steppings
|
||||||
int CleanXfac, CleanYfac;
|
int CleanXfac, CleanYfac;
|
||||||
|
@ -75,7 +83,7 @@ int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
||||||
// FillSimplePoly uses this
|
// FillSimplePoly uses this
|
||||||
extern "C" short spanend[MAXHEIGHT];
|
extern "C" short spanend[MAXHEIGHT];
|
||||||
|
|
||||||
CVAR (Bool, hud_scale, false, CVAR_ARCHIVE);
|
CVAR (Bool, hud_scale, true, CVAR_ARCHIVE);
|
||||||
|
|
||||||
// For routines that take RGB colors, cache the previous lookup in case there
|
// For routines that take RGB colors, cache the previous lookup in case there
|
||||||
// are several repetitions with the same color.
|
// are several repetitions with the same color.
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "r_data/voxels.h"
|
#include "r_data/voxels.h"
|
||||||
|
|
||||||
|
int active_con_scale();
|
||||||
|
|
||||||
FRenderer *Renderer;
|
FRenderer *Renderer;
|
||||||
|
|
||||||
|
@ -857,10 +858,20 @@ void DFrameBuffer::DrawRateStuff ()
|
||||||
int chars;
|
int chars;
|
||||||
int rate_x;
|
int rate_x;
|
||||||
|
|
||||||
|
int textScale = active_con_scale();
|
||||||
|
if (textScale == 0)
|
||||||
|
textScale = CleanXfac;
|
||||||
|
|
||||||
chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount);
|
chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount);
|
||||||
rate_x = Width - ConFont->StringWidth(&fpsbuff[0]);
|
rate_x = Width / textScale - ConFont->StringWidth(&fpsbuff[0]);
|
||||||
Clear (rate_x, 0, Width, ConFont->GetHeight(), GPalette.BlackIndex, 0);
|
Clear (rate_x * textScale, 0, Width, ConFont->GetHeight() * textScale, GPalette.BlackIndex, 0);
|
||||||
DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0], TAG_DONE);
|
if (textScale == 1)
|
||||||
|
DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0], TAG_DONE);
|
||||||
|
else
|
||||||
|
DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0],
|
||||||
|
DTA_VirtualWidth, screen->GetWidth() / textScale,
|
||||||
|
DTA_VirtualHeight, screen->GetHeight() / textScale,
|
||||||
|
DTA_KeepRatio, true, TAG_DONE);
|
||||||
|
|
||||||
DWORD thisSec = ms/1000;
|
DWORD thisSec = ms/1000;
|
||||||
if (LastSec < thisSec)
|
if (LastSec < thisSec)
|
||||||
|
|
|
@ -522,4 +522,6 @@ inline bool Is54Aspect(int ratio) {
|
||||||
return ratio == 4;
|
return ratio == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXTERN_CVAR(Int, uiscale);
|
||||||
|
|
||||||
#endif // __V_VIDEO_H__
|
#endif // __V_VIDEO_H__
|
||||||
|
|
|
@ -1,27 +1,46 @@
|
||||||
#ifdef __APPLE__
|
/*
|
||||||
#include <CoreServices/CoreServices.h>
|
** i_specialpaths.cpp
|
||||||
#endif
|
** Gets special system folders where data should be stored. (Windows version)
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2013-2016 Randy Heit
|
||||||
|
** Copyright 2016 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.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <lmcons.h>
|
#include <lmcons.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#define USE_WINDOWS_DWORD
|
#define USE_WINDOWS_DWORD
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "i_system.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "version.h" // for GAMENAME
|
#include "version.h" // for GAMENAME
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
||||||
typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
|
typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
|
||||||
|
@ -323,314 +342,3 @@ FString M_GetSavegamesPath()
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetCachePath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the path for cache GL nodes.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetCachePath(bool create)
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
|
|
||||||
char pathstr[PATH_MAX];
|
|
||||||
FSRef folder;
|
|
||||||
|
|
||||||
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) &&
|
|
||||||
noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX))
|
|
||||||
{
|
|
||||||
path = pathstr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = progdir;
|
|
||||||
}
|
|
||||||
path += "/zdoom/cache";
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetAutoexecPath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the expected location of autoexec.cfg.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetAutoexecPath()
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
|
|
||||||
char cpath[PATH_MAX];
|
|
||||||
FSRef folder;
|
|
||||||
|
|
||||||
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
|
||||||
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
|
||||||
{
|
|
||||||
path << cpath << "/" GAME_DIR "/autoexec.cfg";
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetCajunPath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the location of the Cajun Bot definitions.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetCajunPath(const char *botfilename)
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
|
|
||||||
// Just copies the Windows code. Should this be more Mac-specific?
|
|
||||||
path << progdir << "zcajun/" << botfilename;
|
|
||||||
if (!FileExists(path))
|
|
||||||
{
|
|
||||||
path = "";
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetConfigPath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the path to the config file. On Windows, this can vary for reading
|
|
||||||
// vs writing. i.e. If $PROGDIR/zdoom-<user>.ini does not exist, it will try
|
|
||||||
// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetConfigPath(bool for_reading)
|
|
||||||
{
|
|
||||||
char cpath[PATH_MAX];
|
|
||||||
FSRef folder;
|
|
||||||
|
|
||||||
if (noErr == FSFindFolder(kUserDomain, kPreferencesFolderType, kCreateFolder, &folder) &&
|
|
||||||
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
path << cpath << "/" GAMENAMELOWERCASE ".ini";
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
// Ungh.
|
|
||||||
return GAMENAMELOWERCASE ".ini";
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetScreenshotsPath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the path to the default screenshots directory.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetScreenshotsPath()
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
char cpath[PATH_MAX];
|
|
||||||
FSRef folder;
|
|
||||||
|
|
||||||
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
|
||||||
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
|
||||||
{
|
|
||||||
path << cpath << "/" GAME_DIR "/Screenshots/";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = "~/";
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetSavegamesPath Mac OS X
|
|
||||||
//
|
|
||||||
// Returns the path to the default save games directory.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetSavegamesPath()
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
char cpath[PATH_MAX];
|
|
||||||
FSRef folder;
|
|
||||||
|
|
||||||
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
|
|
||||||
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
|
||||||
{
|
|
||||||
path << cpath << "/" GAME_DIR "/Savegames/";
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // Linux, et al.
|
|
||||||
|
|
||||||
|
|
||||||
FString GetUserFile (const char *file)
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
struct stat info;
|
|
||||||
|
|
||||||
path = NicePath("~/" GAME_DIR "/");
|
|
||||||
|
|
||||||
if (stat (path, &info) == -1)
|
|
||||||
{
|
|
||||||
struct stat extrainfo;
|
|
||||||
|
|
||||||
// Sanity check for ~/.config
|
|
||||||
FString configPath = NicePath("~/.config/");
|
|
||||||
if (stat (configPath, &extrainfo) == -1)
|
|
||||||
{
|
|
||||||
if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
|
||||||
{
|
|
||||||
I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!S_ISDIR(extrainfo.st_mode))
|
|
||||||
{
|
|
||||||
I_FatalError ("~/.config must be a directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can be removed after a release or two
|
|
||||||
// Transfer the old zdoom directory to the new location
|
|
||||||
bool moved = false;
|
|
||||||
FString oldpath = NicePath("~/." GAMENAMELOWERCASE "/");
|
|
||||||
if (stat (oldpath, &extrainfo) != -1)
|
|
||||||
{
|
|
||||||
if (rename(oldpath, path) == -1)
|
|
||||||
{
|
|
||||||
I_Error ("Failed to move old " GAMENAMELOWERCASE " directory (%s) to new location (%s).",
|
|
||||||
oldpath.GetChars(), path.GetChars());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
moved = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
|
||||||
{
|
|
||||||
I_FatalError ("Failed to create %s directory:\n%s",
|
|
||||||
path.GetChars(), strerror (errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!S_ISDIR(info.st_mode))
|
|
||||||
{
|
|
||||||
I_FatalError ("%s must be a directory", path.GetChars());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path += file;
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetCachePath Unix
|
|
||||||
//
|
|
||||||
// Returns the path for cache GL nodes.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetCachePath(bool create)
|
|
||||||
{
|
|
||||||
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
|
||||||
// share the node cache.
|
|
||||||
FString path = NicePath("~/.config/zdoom/cache");
|
|
||||||
if (create)
|
|
||||||
{
|
|
||||||
CreatePath(path);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetAutoexecPath Unix
|
|
||||||
//
|
|
||||||
// Returns the expected location of autoexec.cfg.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetAutoexecPath()
|
|
||||||
{
|
|
||||||
return GetUserFile("autoexec.cfg");
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetCajunPath Unix
|
|
||||||
//
|
|
||||||
// Returns the location of the Cajun Bot definitions.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetCajunPath(const char *botfilename)
|
|
||||||
{
|
|
||||||
FString path;
|
|
||||||
|
|
||||||
// Check first in ~/.config/zdoom/botfilename.
|
|
||||||
path = GetUserFile(botfilename);
|
|
||||||
if (!FileExists(path))
|
|
||||||
{
|
|
||||||
// Then check in SHARE_DIR/botfilename.
|
|
||||||
path = SHARE_DIR;
|
|
||||||
path << botfilename;
|
|
||||||
if (!FileExists(path))
|
|
||||||
{
|
|
||||||
path = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetConfigPath Unix
|
|
||||||
//
|
|
||||||
// Returns the path to the config file. On Windows, this can vary for reading
|
|
||||||
// vs writing. i.e. If $PROGDIR/zdoom-<user>.ini does not exist, it will try
|
|
||||||
// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetConfigPath(bool for_reading)
|
|
||||||
{
|
|
||||||
return GetUserFile(GAMENAMELOWERCASE ".ini");
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetScreenshotsPath Unix
|
|
||||||
//
|
|
||||||
// Returns the path to the default screenshots directory.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetScreenshotsPath()
|
|
||||||
{
|
|
||||||
return NicePath("~/" GAME_DIR "/screenshots/");
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// M_GetSavegamesPath Unix
|
|
||||||
//
|
|
||||||
// Returns the path to the default save games directory.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FString M_GetSavegamesPath()
|
|
||||||
{
|
|
||||||
return NicePath("~/" GAME_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1807,6 +1807,7 @@ DSPLYMNU_STILLBOB = "View bob amount while not moving";
|
||||||
HUDMNU_TITLE = "HUD Options";
|
HUDMNU_TITLE = "HUD Options";
|
||||||
HUDMNU_ALTHUD = "Alternative HUD";
|
HUDMNU_ALTHUD = "Alternative HUD";
|
||||||
HUDMNU_MESSAGE = "Message Options";
|
HUDMNU_MESSAGE = "Message Options";
|
||||||
|
HUDMNU_UISCALE = "User interface scale";
|
||||||
HUDMNU_CROSSHAIR = "Default Crosshair";
|
HUDMNU_CROSSHAIR = "Default Crosshair";
|
||||||
HUDMNU_FORCECROSSHAIR = "Force default crosshair";
|
HUDMNU_FORCECROSSHAIR = "Force default crosshair";
|
||||||
HUDMNU_GROWCROSSHAIR = "Grow crosshair when picking up items";
|
HUDMNU_GROWCROSSHAIR = "Grow crosshair when picking up items";
|
||||||
|
@ -1946,6 +1947,7 @@ MSGMNU_SHOWMESSAGES = "Show messages";
|
||||||
MSGMNU_SHOWOBITUARIES = "Show obituaries";
|
MSGMNU_SHOWOBITUARIES = "Show obituaries";
|
||||||
MSGMNU_SHOWSECRETS = "Show secret notifications";
|
MSGMNU_SHOWSECRETS = "Show secret notifications";
|
||||||
MSGMNU_SCALETEXT = "Scale text in high res";
|
MSGMNU_SCALETEXT = "Scale text in high res";
|
||||||
|
MSGMNU_SCALECONSOLE = "Scale console";
|
||||||
MSGMNU_MESSAGELEVEL = "Minimum message level";
|
MSGMNU_MESSAGELEVEL = "Minimum message level";
|
||||||
MSGMNU_CENTERMESSAGES = "Center messages";
|
MSGMNU_CENTERMESSAGES = "Center messages";
|
||||||
MSGMNU_MESSAGECOLORS = "Message Colors";
|
MSGMNU_MESSAGECOLORS = "Message Colors";
|
||||||
|
@ -2237,6 +2239,7 @@ OPTVAL_ANIMATED = "Animated";
|
||||||
OPTVAL_ROTATED = "Rotated";
|
OPTVAL_ROTATED = "Rotated";
|
||||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colors only";
|
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colors only";
|
||||||
OPTVAL_DOUBLE = "Double";
|
OPTVAL_DOUBLE = "Double";
|
||||||
|
OPTVAL_TRIPLE = "Triple";
|
||||||
OPTVAL_QUADRUPLE = "Quadruple";
|
OPTVAL_QUADRUPLE = "Quadruple";
|
||||||
OPTVAL_ITEMPICKUP = "Item Pickup";
|
OPTVAL_ITEMPICKUP = "Item Pickup";
|
||||||
OPTVAL_OBITUARIES = "Obituaries";
|
OPTVAL_OBITUARIES = "Obituaries";
|
||||||
|
@ -2594,7 +2597,6 @@ GLTEXMNU_RESIZETEX = "Resize textures";
|
||||||
GLTEXMNU_RESIZESPR = "Resize sprites";
|
GLTEXMNU_RESIZESPR = "Resize sprites";
|
||||||
GLTEXMNU_RESIZEFNT = "Resize fonts";
|
GLTEXMNU_RESIZEFNT = "Resize fonts";
|
||||||
GLTEXMNU_PRECACHETEX = "Precache GL textures";
|
GLTEXMNU_PRECACHETEX = "Precache GL textures";
|
||||||
GLTEXMNU_CAMTEXOFFSCR = "Camera textures offscreen";
|
|
||||||
GLTEXMNU_TRIMSPREDGE = "Trim sprite edges";
|
GLTEXMNU_TRIMSPREDGE = "Trim sprite edges";
|
||||||
GLTEXMNU_SORTDRAWLIST = "Sort draw lists by texture";
|
GLTEXMNU_SORTDRAWLIST = "Sort draw lists by texture";
|
||||||
|
|
||||||
|
@ -2605,9 +2607,6 @@ GLLIGHTMNU_LIGHTDEFS = "Enable light definitions";
|
||||||
GLLIGHTMNU_CLIPLIGHTS = "Clip lights";
|
GLLIGHTMNU_CLIPLIGHTS = "Clip lights";
|
||||||
GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites";
|
GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites";
|
||||||
GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
|
GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
|
||||||
GLLIGHTMNU_FORCEADDITIVE = "Force additive lighting";
|
|
||||||
GLLIGHTMNU_LIGHTINTENSITY = "Light intensity";
|
|
||||||
GLLIGHTMNU_LIGHTSIZE = "Light size";
|
|
||||||
GLLIGHTMNU_LIGHTMATH = "Light quality";
|
GLLIGHTMNU_LIGHTMATH = "Light quality";
|
||||||
|
|
||||||
// OpenGL Preferences
|
// OpenGL Preferences
|
||||||
|
|
|
@ -768,6 +768,8 @@ OptionMenu "HUDOptions"
|
||||||
Submenu "$HUDMNU_ALTHUD", "AltHudOptions"
|
Submenu "$HUDMNU_ALTHUD", "AltHudOptions"
|
||||||
Submenu "$HUDMNU_MESSAGE", "MessageOptions"
|
Submenu "$HUDMNU_MESSAGE", "MessageOptions"
|
||||||
StaticText " "
|
StaticText " "
|
||||||
|
Slider "$HUDMNU_UISCALE", "uiscale", 0.0, 8.0, 1.0, 0
|
||||||
|
StaticText " "
|
||||||
Option "$HUDMNU_CROSSHAIR", "crosshair", "Crosshairs"
|
Option "$HUDMNU_CROSSHAIR", "crosshair", "Crosshairs"
|
||||||
Option "$HUDMNU_FORCECROSSHAIR", "crosshairforce", "OnOff"
|
Option "$HUDMNU_FORCECROSSHAIR", "crosshairforce", "OnOff"
|
||||||
Option "$HUDMNU_GROWCROSSHAIR", "crosshairgrow", "OnOff"
|
Option "$HUDMNU_GROWCROSSHAIR", "crosshairgrow", "OnOff"
|
||||||
|
@ -802,6 +804,7 @@ OptionValue "AMCoordinates"
|
||||||
OptionValue "AltHUDScale"
|
OptionValue "AltHUDScale"
|
||||||
{
|
{
|
||||||
0, "$OPTVAL_OFF"
|
0, "$OPTVAL_OFF"
|
||||||
|
4, "$OPTVAL_ON"
|
||||||
1, "$OPTVAL_SCALETO640X400"
|
1, "$OPTVAL_SCALETO640X400"
|
||||||
2, "$OPTVAL_PIXELDOUBLE"
|
2, "$OPTVAL_PIXELDOUBLE"
|
||||||
3, "$OPTVAL_PIXELQUADRUPLE"
|
3, "$OPTVAL_PIXELQUADRUPLE"
|
||||||
|
@ -1124,6 +1127,15 @@ OptionValue ScaleValues
|
||||||
3, "$OPTVAL_QUADRUPLE"
|
3, "$OPTVAL_QUADRUPLE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionValue ConsoleScaleValues
|
||||||
|
{
|
||||||
|
1, "$OPTVAL_OFF"
|
||||||
|
0, "$OPTVAL_ON"
|
||||||
|
2, "$OPTVAL_DOUBLE"
|
||||||
|
3, "$OPTVAL_TRIPLE"
|
||||||
|
4, "$OPTVAL_QUADRUPLE"
|
||||||
|
}
|
||||||
|
|
||||||
OptionValue MessageLevels
|
OptionValue MessageLevels
|
||||||
{
|
{
|
||||||
0.0, "$OPTVAL_ITEMPICKUP"
|
0.0, "$OPTVAL_ITEMPICKUP"
|
||||||
|
@ -1147,6 +1159,7 @@ OptionMenu MessageOptions
|
||||||
Option "$MSGMNU_SHOWOBITUARIES", "show_obituaries", "OnOff"
|
Option "$MSGMNU_SHOWOBITUARIES", "show_obituaries", "OnOff"
|
||||||
Option "$MSGMNU_SHOWSECRETS", "cl_showsecretmessage", "OnOff"
|
Option "$MSGMNU_SHOWSECRETS", "cl_showsecretmessage", "OnOff"
|
||||||
Option "$MSGMNU_SCALETEXT", "con_scaletext", "ScaleValues"
|
Option "$MSGMNU_SCALETEXT", "con_scaletext", "ScaleValues"
|
||||||
|
Option "$MSGMNU_SCALECONSOLE", "con_scale", "ConsoleScaleValues"
|
||||||
Option "$MSGMNU_MESSAGELEVEL", "msg", "MessageLevels"
|
Option "$MSGMNU_MESSAGELEVEL", "msg", "MessageLevels"
|
||||||
Option "$MSGMNU_DEVELOPER", "developer", "DevMessageLevels"
|
Option "$MSGMNU_DEVELOPER", "developer", "DevMessageLevels"
|
||||||
Option "$MSGMNU_CENTERMESSAGES", "con_centernotify", "OnOff"
|
Option "$MSGMNU_CENTERMESSAGES", "con_centernotify", "OnOff"
|
||||||
|
|
|
@ -141,6 +141,12 @@ OptionValue "HqResizeModes"
|
||||||
7, "$OPTVAL_HQ2XMMX"
|
7, "$OPTVAL_HQ2XMMX"
|
||||||
8, "$OPTVAL_HQ3XMMX"
|
8, "$OPTVAL_HQ3XMMX"
|
||||||
9, "$OPTVAL_HQ4XMMX"
|
9, "$OPTVAL_HQ4XMMX"
|
||||||
|
10, "xBRZ 2x"
|
||||||
|
11, "xBRZ 3x"
|
||||||
|
12, "xBRZ 4x"
|
||||||
|
13, "xBRZ_old 2x"
|
||||||
|
14, "xBRZ_old 3x"
|
||||||
|
15, "xBRZ_old 4x"
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionValue "FogMode"
|
OptionValue "FogMode"
|
||||||
|
@ -186,7 +192,6 @@ OptionMenu "GLTextureGLOptions"
|
||||||
Option "$GLTEXMNU_RESIZESPR", gl_texture_hqresize_sprites, "OnOff"
|
Option "$GLTEXMNU_RESIZESPR", gl_texture_hqresize_sprites, "OnOff"
|
||||||
Option "$GLTEXMNU_RESIZEFNT", gl_texture_hqresize_fonts, "OnOff"
|
Option "$GLTEXMNU_RESIZEFNT", gl_texture_hqresize_fonts, "OnOff"
|
||||||
Option "$GLTEXMNU_PRECACHETEX", gl_precache, "YesNo"
|
Option "$GLTEXMNU_PRECACHETEX", gl_precache, "YesNo"
|
||||||
Option "$GLTEXMNU_CAMTEXOFFSCR", gl_usefb, "OnOff"
|
|
||||||
Option "$GLTEXMNU_TRIMSPREDGE", gl_trimsprites, "OnOff"
|
Option "$GLTEXMNU_TRIMSPREDGE", gl_trimsprites, "OnOff"
|
||||||
Option "$GLTEXMNU_SORTDRAWLIST", gl_sort_textures, "YesNo"
|
Option "$GLTEXMNU_SORTDRAWLIST", gl_sort_textures, "YesNo"
|
||||||
}
|
}
|
||||||
|
@ -199,10 +204,7 @@ OptionMenu "GLLightOptions"
|
||||||
Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo"
|
Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo"
|
||||||
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
||||||
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
|
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
|
||||||
Option "$GLLIGHTMNU_FORCEADDITIVE", gl_lights_additive, "YesNo"
|
|
||||||
Option "$GLLIGHTMNU_LIGHTMATH", gl_light_math, "LightMathModes"
|
Option "$GLLIGHTMNU_LIGHTMATH", gl_light_math, "LightMathModes"
|
||||||
Slider "$GLLIGHTMNU_LIGHTINTENSITY", gl_lights_intensity, 0.0, 1.0, 0.1
|
|
||||||
Slider "$GLLIGHTMNU_LIGHTSIZE", gl_lights_size, 0.0, 2.0, 0.1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMenu "GLPrefOptions"
|
OptionMenu "GLPrefOptions"
|
||||||
|
|
|
@ -69,15 +69,15 @@ uniform sampler2D PaletteLUT;
|
||||||
|
|
||||||
vec3 Tonemap(vec3 color)
|
vec3 Tonemap(vec3 color)
|
||||||
{
|
{
|
||||||
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 255.0 + 0.5);
|
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 63.0 + 0.5);
|
||||||
int index = ((c.r >> 2) * 64 + (c.g >> 2)) * 64 + (c.b >> 2);
|
int index = (c.r * 64 + c.g) * 64 + c.b;
|
||||||
int tx = index % 512;
|
int tx = index % 512;
|
||||||
int ty = index / 512;
|
int ty = index / 512;
|
||||||
return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;
|
return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Tonemap mode define is missing"
|
#error Tonemap mode define is missing
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
Loading…
Reference in a new issue