mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 13:41:05 +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,6 +115,7 @@ if( WIN32 )
|
|||
set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib )
|
||||
set( NASM_NAMES nasmw nasm )
|
||||
|
||||
if( NOT MSVC )
|
||||
find_path( D3D_INCLUDE_DIR d3d9.h
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
|
@ -153,11 +154,20 @@ if( WIN32 )
|
|||
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
||||
endif()
|
||||
|
||||
set( ZDOOM_LIBS
|
||||
wsock32
|
||||
winmm
|
||||
set( DX_LIBS
|
||||
"${DX_dxguid_LIBRARY}"
|
||||
"${DX_dinput8_LIBRARY}"
|
||||
)
|
||||
else()
|
||||
set( DX_LIBS
|
||||
dxguid
|
||||
dinput8
|
||||
)
|
||||
endif()
|
||||
|
||||
set( ZDOOM_LIBS ${DX_LIBS}
|
||||
wsock32
|
||||
winmm
|
||||
ole32
|
||||
user32
|
||||
gdi32
|
||||
|
@ -660,6 +670,7 @@ set( PLAT_WIN32_SOURCES
|
|||
win32/i_main.cpp
|
||||
win32/i_movie.cpp
|
||||
win32/i_system.cpp
|
||||
win32/i_specialpaths.cpp
|
||||
win32/st_start.cpp
|
||||
win32/win32gliface.cpp
|
||||
win32/win32video.cpp )
|
||||
|
@ -679,8 +690,11 @@ set( PLAT_SDL_SOURCES
|
|||
posix/sdl/sdlvideo.cpp
|
||||
posix/sdl/sdlglvideo.cpp
|
||||
posix/sdl/st_start.cpp )
|
||||
set( PLAT_UNIX_SOURCES
|
||||
posix/unix/i_specialpaths.cpp )
|
||||
set( PLAT_OSX_SOURCES
|
||||
posix/osx/iwadpicker_cocoa.mm
|
||||
posix/osx/i_specialpaths.mm
|
||||
posix/osx/zdoom.icns )
|
||||
set( PLAT_COCOA_SOURCES
|
||||
posix/cocoa/critsec.cpp
|
||||
|
@ -697,7 +711,7 @@ set( PLAT_COCOA_SOURCES
|
|||
if( WIN32 )
|
||||
set( SYSTEM_SOURCES_DIR win32 )
|
||||
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 )
|
||||
# CMake is not set up to compile and link rc files with GCC. :(
|
||||
|
@ -712,12 +726,12 @@ elseif( APPLE )
|
|||
if( OSX_COCOA_BACKEND )
|
||||
set( SYSTEM_SOURCES_DIR posix posix/cocoa )
|
||||
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()
|
||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||
set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} )
|
||||
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()
|
||||
|
||||
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 )
|
||||
else()
|
||||
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} )
|
||||
endif()
|
||||
|
||||
|
@ -849,6 +863,7 @@ file( GLOB HEADER_FILES
|
|||
gl/dynlights/*.h
|
||||
gl/hqnx/*.h
|
||||
gl/hqnx_asm/*.h
|
||||
gl/xbr/*.h
|
||||
gl/models/*.h
|
||||
gl/renderer/*.h
|
||||
gl/scene/*.h
|
||||
|
@ -1072,6 +1087,8 @@ set( FASTMATH_SOURCES
|
|||
gl/hqnx/hq2x.cpp
|
||||
gl/hqnx/hq3x.cpp
|
||||
gl/hqnx/hq4x.cpp
|
||||
gl/xbr/xbrz.cpp
|
||||
gl/xbr/xbrz_old.cpp
|
||||
gl/textures/gl_hwtexture.cpp
|
||||
gl/textures/gl_texture.cpp
|
||||
gl/textures/gl_material.cpp
|
||||
|
@ -1385,7 +1402,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
${FASTMATH_SOURCES}
|
||||
${PCH_SOURCES}
|
||||
x86.cpp
|
||||
m_specialpaths.cpp
|
||||
strnatcmp.c
|
||||
zstring.cpp
|
||||
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\\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 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\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
|
||||
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("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("Unix Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/unix/.+")
|
||||
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
|
||||
source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
|
||||
source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+")
|
||||
|
|
|
@ -283,7 +283,7 @@ enum ActorFlag4
|
|||
enum ActorFlag5
|
||||
{
|
||||
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
|
||||
/* FREE SLOT 0x00000002*/
|
||||
MF5_GETOWNER = 0x00000002,
|
||||
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_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 (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 > 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)
|
||||
{
|
||||
if (self < 0.f) self = 0.f;
|
||||
|
@ -493,13 +518,13 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (con_scaletext)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
default:
|
||||
case 0: width = DisplayWidth; break;
|
||||
case 1: width = DisplayWidth / CleanXfac; break;
|
||||
case 2: width = DisplayWidth / 2; break;
|
||||
case 3: width = DisplayWidth / 4; break;
|
||||
width = DisplayWidth / CleanXfac;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = DisplayWidth / active_con_scaletext();
|
||||
}
|
||||
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel)
|
||||
|
@ -721,7 +746,7 @@ static void C_DrawNotifyText ()
|
|||
canskip = true;
|
||||
|
||||
lineadv = SmallFont->GetHeight ();
|
||||
if (con_scaletext == 1)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
lineadv *= CleanYfac;
|
||||
}
|
||||
|
@ -755,7 +780,7 @@ static void C_DrawNotifyText ()
|
|||
else
|
||||
color = PrintColors[NotifyStrings[i].PrintLevel];
|
||||
|
||||
if (con_scaletext == 1)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||
|
@ -766,7 +791,7 @@ static void C_DrawNotifyText ()
|
|||
line, NotifyStrings[i].Text, DTA_CleanNoMove, true,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 0)
|
||||
else if (active_con_scaletext() == 1)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||
|
@ -777,37 +802,20 @@ static void C_DrawNotifyText ()
|
|||
line, NotifyStrings[i].Text,
|
||||
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
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
||||
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
|
||||
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
|
||||
DTA_KeepRatio, true,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
else
|
||||
screen->DrawText (SmallFont, color, (screen->GetWidth() / 2 -
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
|
||||
screen->DrawText (SmallFont, color, (screen->GetWidth() / active_con_scaletext() -
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text))/ active_con_scaletext(),
|
||||
line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
||||
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
|
||||
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
|
||||
DTA_KeepRatio, true,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
}
|
||||
|
@ -851,9 +859,13 @@ void C_DrawConsole (bool hw2d)
|
|||
static int oldbottom = 0;
|
||||
int lines, left, offset;
|
||||
|
||||
int textScale = active_con_scale();
|
||||
if (textScale == 0)
|
||||
textScale = CleanXfac;
|
||||
|
||||
left = LEFTMARGIN;
|
||||
lines = (ConBottom-ConFont->GetHeight()*2)/ConFont->GetHeight();
|
||||
if (-ConFont->GetHeight() + lines*ConFont->GetHeight() > ConBottom - ConFont->GetHeight()*7/2)
|
||||
lines = (ConBottom/textScale-ConFont->GetHeight()*2)/ConFont->GetHeight();
|
||||
if (-ConFont->GetHeight() + lines*ConFont->GetHeight() > ConBottom/textScale - ConFont->GetHeight()*7/2)
|
||||
{
|
||||
offset = -ConFont->GetHeight()/2;
|
||||
lines--;
|
||||
|
@ -899,16 +911,26 @@ void C_DrawConsole (bool hw2d)
|
|||
|
||||
if (ConBottom >= 12)
|
||||
{
|
||||
if (textScale == 1)
|
||||
screen->DrawText (ConFont, CR_ORANGE, SCREENWIDTH - 8 -
|
||||
ConFont->StringWidth (GetVersionString()),
|
||||
ConBottom - ConFont->GetHeight() - 4,
|
||||
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)
|
||||
{
|
||||
char tickstr[256];
|
||||
const int tickerY = ConBottom - ConFont->GetHeight() - 4;
|
||||
const int tickerY = ConBottom / textScale - ConFont->GetHeight() - 4;
|
||||
size_t i;
|
||||
int tickend = ConCols - SCREENWIDTH / 90 - 6;
|
||||
int tickend = ConCols / textScale - SCREENWIDTH / textScale / 90 - 6;
|
||||
int tickbegin = 0;
|
||||
|
||||
if (TickerLabel)
|
||||
|
@ -931,11 +953,23 @@ void C_DrawConsole (bool hw2d)
|
|||
{
|
||||
tickstr[tickend+3] = 0;
|
||||
}
|
||||
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
|
||||
i = LEFTMARGIN+5+tickbegin*8 + Scale (TickerAt, (SDWORD)(tickend - tickbegin)*8, TickerMax);
|
||||
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;
|
||||
}
|
||||
|
@ -971,19 +1005,29 @@ void C_DrawConsole (bool hw2d)
|
|||
if (lines > 0)
|
||||
{
|
||||
// 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();
|
||||
FBrokenLines **blines = conbuffer->GetLines();
|
||||
FBrokenLines **printline = blines + consolelines - 1 - RowAdjust;
|
||||
|
||||
int bottomline = ConBottom - ConFont->GetHeight()*2 - 4;
|
||||
int bottomline = ConBottom / textScale - ConFont->GetHeight()*2 - 4;
|
||||
|
||||
ConsoleDrawing = true;
|
||||
|
||||
for(FBrokenLines **p = printline; p >= blines && lines > 0; p--, lines--)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -997,21 +1041,52 @@ void C_DrawConsole (bool hw2d)
|
|||
FString command((char *)&CmdLine[2+CmdLine[259]]);
|
||||
int cursorpos = CmdLine[1] - CmdLine[259];
|
||||
|
||||
screen->DrawChar (ConFont, CR_ORANGE, left, bottomline, '\x1c', TAG_DONE);
|
||||
screen->DrawText (ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline,
|
||||
if (textScale == 1)
|
||||
{
|
||||
screen->DrawChar(ConFont, CR_ORANGE, left, bottomline, '\x1c', 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),
|
||||
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)
|
||||
{
|
||||
// Indicate that the view has been scrolled up (10)
|
||||
// and if we can scroll no further (12)
|
||||
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_teamdeathmatch_enable)
|
||||
|
||||
int active_con_scaletext();
|
||||
|
||||
// Public data
|
||||
|
||||
void CT_Init ();
|
||||
|
@ -224,7 +226,7 @@ void CT_Drawer (void)
|
|||
int i, x, scalex, y, promptwidth;
|
||||
|
||||
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
||||
if (con_scaletext == 1)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
scalex = CleanXfac;
|
||||
y *= CleanYfac;
|
||||
|
@ -235,25 +237,17 @@ void CT_Drawer (void)
|
|||
}
|
||||
|
||||
int screen_width, screen_height, st_y;
|
||||
switch (con_scaletext)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
case 1:
|
||||
screen_width = SCREENWIDTH;
|
||||
screen_height = SCREENHEIGHT;
|
||||
st_y = ST_Y;
|
||||
break;
|
||||
case 2:
|
||||
screen_width = SCREENWIDTH / 2;
|
||||
screen_height = SCREENHEIGHT / 2;
|
||||
st_y = ST_Y / 2;
|
||||
break;
|
||||
case 3:
|
||||
screen_width = SCREENWIDTH / 4;
|
||||
screen_height = SCREENHEIGHT / 4;
|
||||
st_y = ST_Y / 4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen_width = SCREENWIDTH / active_con_scaletext();
|
||||
screen_height = SCREENHEIGHT / active_con_scaletext();
|
||||
st_y = ST_Y / active_con_scaletext();
|
||||
}
|
||||
|
||||
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
|
||||
ChatQueue[len] = SmallFont->GetCursor();
|
||||
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_GREY, promptwidth, y, (char *)(ChatQueue + i), 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, active_con_scaletext() == 0, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -166,8 +166,14 @@ void AFastProjectile::Effect()
|
|||
if (trail != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -195,7 +195,7 @@ double DEarthquake::GetModIntensity(double intensity) const
|
|||
}
|
||||
scalar = (scalar > divider) ? divider : scalar;
|
||||
|
||||
if (m_Flags & QF_FULLINTENSITY)
|
||||
if (!fake && (m_Flags & QF_FULLINTENSITY))
|
||||
{
|
||||
scalar *= 2;
|
||||
}
|
||||
|
@ -273,64 +273,69 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
|
|||
DEarthquake *quake;
|
||||
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)
|
||||
{
|
||||
const double falloff = quake->GetFalloff(dist);
|
||||
const double rfalloff = (quake->m_RollIntensity != 0) ? falloff : 0.;
|
||||
++count;
|
||||
double x = quake->GetModIntensity(quake->m_Intensity.X);
|
||||
double y = quake->GetModIntensity(quake->m_Intensity.Y);
|
||||
double z = quake->GetModIntensity(quake->m_Intensity.Z);
|
||||
double r = quake->GetModIntensity(quake->m_RollIntensity);
|
||||
const double falloff = quake->GetFalloff(dist);
|
||||
const double r = quake->GetModIntensity(quake->m_RollIntensity);
|
||||
const double strength = quake->GetModIntensity(1.0, true);
|
||||
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))
|
||||
{
|
||||
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||
jiggers.RFalloff = MAX(rfalloff, jiggers.RFalloff);
|
||||
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity);
|
||||
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity) * jiggers.Falloff;
|
||||
|
||||
intensity *= jiggers.Falloff;
|
||||
if (quake->m_Flags & QF_RELATIVE)
|
||||
{
|
||||
jiggers.RelIntensity.X = MAX(x, jiggers.RelIntensity.X);
|
||||
jiggers.RelIntensity.Y = MAX(y, jiggers.RelIntensity.Y);
|
||||
jiggers.RelIntensity.Z = MAX(z, jiggers.RelIntensity.Z);
|
||||
jiggers.RelIntensity.X = MAX(intensity.X, jiggers.RelIntensity.X);
|
||||
jiggers.RelIntensity.Y = MAX(intensity.Y, jiggers.RelIntensity.Y);
|
||||
jiggers.RelIntensity.Z = MAX(intensity.Z, jiggers.RelIntensity.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
jiggers.Intensity.X = MAX(x, jiggers.Intensity.X);
|
||||
jiggers.Intensity.Y = MAX(y, jiggers.Intensity.Y);
|
||||
jiggers.Intensity.Z = MAX(z, jiggers.Intensity.Z);
|
||||
jiggers.Intensity.X = MAX(intensity.X, jiggers.Intensity.X);
|
||||
jiggers.Intensity.Y = MAX(intensity.Y, jiggers.Intensity.Y);
|
||||
jiggers.Intensity.Z = MAX(intensity.Z, jiggers.Intensity.Z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jiggers.WFalloff = MAX(falloff, jiggers.WFalloff);
|
||||
jiggers.RWFalloff = MAX(rfalloff, jiggers.RWFalloff);
|
||||
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);
|
||||
double mz = z * quake->GetModWave(quake->m_WaveSpeed.Z);
|
||||
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||
jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave) * jiggers.Falloff * strength;
|
||||
|
||||
|
||||
intensity.X *= quake->GetModWave(quake->m_WaveSpeed.X);
|
||||
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
|
||||
// prefer if some way was found to make multiples coexist
|
||||
// peacefully, but just summing them together is undesirable
|
||||
// because they could cancel each other out depending on their
|
||||
// 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)
|
||||
{
|
||||
jiggers.RelOffset.X = mx;
|
||||
jiggers.RelOffset.Y = my;
|
||||
jiggers.RelOffset.Z = mz;
|
||||
jiggers.RelOffset += intensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
jiggers.Offset.X = mx;
|
||||
jiggers.Offset.Y = my;
|
||||
jiggers.Offset.Z = mz;
|
||||
jiggers.Offset += intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ struct FQuakeJiggers
|
|||
DVector3 RelIntensity;
|
||||
DVector3 Offset;
|
||||
DVector3 RelOffset;
|
||||
double Falloff, WFalloff, RFalloff, RWFalloff;
|
||||
double Falloff;
|
||||
double RollIntensity, RollWave;
|
||||
};
|
||||
|
||||
|
@ -180,8 +180,7 @@ public:
|
|||
int m_Highpoint, m_MiniCount;
|
||||
double m_RollIntensity, m_RollWave;
|
||||
|
||||
|
||||
double GetModIntensity(double intensity) const;
|
||||
double GetModIntensity(double intensity, bool fake = false) const;
|
||||
double GetModWave(double waveMultiplier) const;
|
||||
double GetFalloff(double dist) const;
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
EXTERN_CVAR(Int, con_scaletext)
|
||||
int active_con_scaletext();
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (DHUDMessage)
|
||||
DECLARE_POINTER(Next)
|
||||
|
@ -260,13 +261,10 @@ void DHUDMessage::ResetText (const char *text)
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (con_scaletext)
|
||||
switch (active_con_scaletext())
|
||||
{
|
||||
default:
|
||||
case 0: width = SCREENWIDTH; break;
|
||||
case 1: width = SCREENWIDTH / CleanXfac; break;
|
||||
case 2: width = SCREENWIDTH / 2; break;
|
||||
case 3: width = SCREENWIDTH / 4; break;
|
||||
case 0: width = SCREENWIDTH / CleanXfac; break;
|
||||
default: width = SCREENWIDTH / active_con_scaletext(); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,7 +330,7 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
|||
|
||||
int screen_width = SCREENWIDTH;
|
||||
int screen_height = SCREENHEIGHT;
|
||||
if (HUDWidth == 0 && con_scaletext==1)
|
||||
if (HUDWidth == 0 && active_con_scaletext() == 0)
|
||||
{
|
||||
clean = true;
|
||||
xscale = CleanXfac;
|
||||
|
@ -341,17 +339,11 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
|||
else
|
||||
{
|
||||
xscale = yscale = 1;
|
||||
if (HUDWidth==0 && con_scaletext==2)
|
||||
if (HUDWidth == 0)
|
||||
{
|
||||
screen_width/=2;
|
||||
screen_height/=2;
|
||||
bottom/=2;
|
||||
}
|
||||
else if (HUDWidth==0 && con_scaletext==3)
|
||||
{
|
||||
screen_width/=4;
|
||||
screen_height/=4;
|
||||
bottom/=4;
|
||||
screen_width /= active_con_scaletext();
|
||||
screen_height /= active_con_scaletext();
|
||||
bottom /= active_con_scaletext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +445,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
{
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
if (active_con_scaletext() <= 1)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
|
@ -461,21 +453,11 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
DTA_RenderStyle, Style,
|
||||
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
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||
DTA_AlphaF, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
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);
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
if (active_con_scaletext() <= 1)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
|
@ -574,21 +556,11 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
DTA_RenderStyle, Style,
|
||||
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
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||
DTA_AlphaF, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
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);
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
if (active_con_scaletext() <= 1)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
|
@ -684,21 +656,11 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
DTA_RenderStyle, Style,
|
||||
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
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||
DTA_AlphaF, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
|
@ -864,7 +826,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
{
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
if (active_con_scaletext() <= 1)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
|
@ -873,22 +835,11 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
DTA_RenderStyle, Style,
|
||||
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
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
|
||||
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
|
||||
DTA_KeepRatio, true,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_AlphaF, Alpha,
|
||||
|
|
|
@ -1013,8 +1013,16 @@ public:
|
|||
void ScreenSizeChanged()
|
||||
{
|
||||
Super::ScreenSizeChanged();
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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[] =
|
||||
{
|
||||
"drawimage", "drawnumber", "drawswitchableimage",
|
||||
|
@ -3474,7 +3546,7 @@ static const char *SBarInfoCommandNames[] =
|
|||
"isselected", "usesammo", "usessecondaryammo",
|
||||
"hasweaponpiece", "inventorybarnotvisible",
|
||||
"weaponammo", "ininventory", "alpha", "ifhealth",
|
||||
"ifinvulnerable", "ifwaterlevel",
|
||||
"ifinvulnerable", "ifwaterlevel", "ifcvarint",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -3488,7 +3560,7 @@ enum SBarInfoCommands
|
|||
SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO,
|
||||
SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE,
|
||||
SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH,
|
||||
SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL,
|
||||
SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL, SBARINFO_IFCVARINT,
|
||||
};
|
||||
|
||||
SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
|
||||
|
@ -3524,6 +3596,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
|
|||
case SBARINFO_IFHEALTH: return new CommandIfHealth(script);
|
||||
case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script);
|
||||
case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script);
|
||||
case SBARINFO_IFCVARINT: return new CommandIfCVarInt(script);
|
||||
}
|
||||
|
||||
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_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
|
||||
|
||||
// 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;
|
||||
|
||||
DVector2 AM_GetPosition();
|
||||
|
||||
int active_con_scaletext();
|
||||
|
||||
FTextureID GetHUDIcon(PClassInventory *cls)
|
||||
{
|
||||
|
@ -886,22 +886,15 @@ static void DrawCoordinates(player_t * CPlayer)
|
|||
}
|
||||
|
||||
int vwidth, vheight;
|
||||
switch (con_scaletext)
|
||||
if (active_con_scaletext() == 0)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
vwidth = SCREENWIDTH;
|
||||
vheight = SCREENHEIGHT;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
vwidth = SCREENWIDTH/2;
|
||||
vheight = SCREENHEIGHT/2;
|
||||
break;
|
||||
case 3:
|
||||
vwidth = SCREENWIDTH/4;
|
||||
vheight = SCREENHEIGHT/4;
|
||||
break;
|
||||
vwidth = SCREENWIDTH / 2;
|
||||
vheight = SCREENHEIGHT / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
vwidth = SCREENWIDTH / active_con_scaletext();
|
||||
vheight = SCREENHEIGHT / active_con_scaletext();
|
||||
}
|
||||
|
||||
int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||
|
@ -1090,7 +1083,20 @@ void DrawHUD()
|
|||
if (hud_althudscale && SCREENWIDTH>640)
|
||||
{
|
||||
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;
|
||||
hudheight = SCREENHEIGHT / 4;
|
||||
|
|
|
@ -74,6 +74,8 @@ EXTERN_CVAR (Bool, am_showtotaltime)
|
|||
EXTERN_CVAR (Bool, noisedebug)
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
|
||||
int active_con_scaletext();
|
||||
|
||||
DBaseStatusBar *StatusBar;
|
||||
|
||||
extern int setblocks;
|
||||
|
@ -1240,17 +1242,17 @@ void DBaseStatusBar::Draw (EHudState state)
|
|||
int xpos;
|
||||
int y;
|
||||
|
||||
if (con_scaletext == 0)
|
||||
if (active_con_scaletext() == 1)
|
||||
{
|
||||
vwidth = SCREENWIDTH;
|
||||
vheight = SCREENHEIGHT;
|
||||
xpos = vwidth - 80;
|
||||
y = ::ST_Y - height;
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
else if (active_con_scaletext() > 1)
|
||||
{
|
||||
vwidth = SCREENWIDTH/4;
|
||||
vheight = SCREENHEIGHT/4;
|
||||
vwidth = SCREENWIDTH / active_con_scaletext();
|
||||
vheight = SCREENHEIGHT / active_con_scaletext();
|
||||
xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||
y = ::ST_Y/4 - height;
|
||||
}
|
||||
|
@ -1264,9 +1266,9 @@ void DBaseStatusBar::Draw (EHudState state)
|
|||
|
||||
if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
if (con_scaletext == 0)
|
||||
if (active_con_scaletext() == 1)
|
||||
y -= height * 4;
|
||||
else if (con_scaletext == 3)
|
||||
else if (active_con_scaletext() > 3)
|
||||
y -= height;
|
||||
else
|
||||
y -= height * 2;
|
||||
|
@ -1400,27 +1402,15 @@ void DBaseStatusBar::DrawLog ()
|
|||
if (CPlayer->LogText.IsNotEmpty())
|
||||
{
|
||||
// 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;
|
||||
hudheight = SCREENHEIGHT / CleanYfac;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
hudwidth = SCREENWIDTH / 2;
|
||||
hudheight = SCREENHEIGHT / 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
hudwidth = SCREENWIDTH / 4;
|
||||
hudheight = SCREENHEIGHT / 4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
hudwidth = SCREENWIDTH / active_con_scaletext();
|
||||
hudheight = SCREENHEIGHT / active_con_scaletext();
|
||||
}
|
||||
|
||||
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
|
||||
savedz = self->Z();
|
||||
if (wavedef && self->ceilingz < wavedef->Top())
|
||||
if (wavedef && self->ceilingz < self->Z() + wavedef->Height)
|
||||
{
|
||||
self->SetZ(self->ceilingz - wavedef->Height);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#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
|
||||
|
@ -384,7 +386,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
DVector3 lpos = light->PosRelative(group);
|
||||
|
||||
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 (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);
|
||||
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
|
||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
||||
float r = light->GetRed() / 255.0f * cs;
|
||||
float g = light->GetGreen() / 255.0f * cs;
|
||||
float b = light->GetBlue() / 255.0f * cs;
|
||||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
|
@ -478,7 +480,7 @@ bool GLWall::PutWallCompat(int passflag)
|
|||
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();
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
|
|
|
@ -10,6 +10,15 @@ struct secplane_t;
|
|||
struct subsector_t;
|
||||
struct sector_t;
|
||||
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX_BIT,
|
||||
VATTR_TEXCOORD_BIT,
|
||||
VATTR_COLOR_BIT,
|
||||
VATTR_VERTEX2_BIT,
|
||||
VATTR_NORMAL_BIT
|
||||
};
|
||||
|
||||
|
||||
class FVertexBuffer
|
||||
{
|
||||
|
@ -20,6 +29,7 @@ public:
|
|||
FVertexBuffer(bool wantbuffer = true);
|
||||
virtual ~FVertexBuffer();
|
||||
virtual void BindVBO() = 0;
|
||||
void EnableBufferArrays(int enable, int disable);
|
||||
};
|
||||
|
||||
struct FFlatVertex
|
||||
|
|
|
@ -57,8 +57,6 @@
|
|||
#include "gl/utility/gl_convert.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
|
||||
EXTERN_CVAR (Float, gl_lights_size);
|
||||
EXTERN_CVAR (Bool, gl_lights_additive);
|
||||
EXTERN_CVAR(Int, vid_renderer)
|
||||
|
||||
|
||||
|
@ -379,7 +377,7 @@ void ADynamicLight::UpdateLocation()
|
|||
{
|
||||
intensity = m_currentRadius;
|
||||
}
|
||||
radius = intensity * 2.0f * gl_lights_size;
|
||||
radius = intensity * 2.0f;
|
||||
|
||||
if (X() != oldx || Y() != oldy || radius != oldradius)
|
||||
{
|
||||
|
|
|
@ -61,8 +61,6 @@
|
|||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_convert.h"
|
||||
|
||||
EXTERN_CVAR (Float, gl_lights_intensity);
|
||||
EXTERN_CVAR (Float, gl_lights_size);
|
||||
int ScriptDepth;
|
||||
void gl_InitGlow(FScanner &sc);
|
||||
void gl_ParseBrightmap(FScanner &sc, int);
|
||||
|
@ -175,7 +173,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
|
|||
light->Angles.Yaw.Degrees = m_Param;
|
||||
light->SetOffset(m_Pos);
|
||||
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[1] = int(m_Args[LIGHT_SECONDARY_INTENSITY]);
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -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_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_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)
|
||||
{
|
||||
|
@ -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
|
||||
//
|
||||
//==========================================================================
|
||||
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;
|
||||
|
||||
DVector3 pos = light->PosRelative(group);
|
||||
|
||||
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 (dist > radius) return false;
|
||||
|
@ -108,7 +101,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
|||
|
||||
|
||||
float cs;
|
||||
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive)
|
||||
if (light->IsAdditive())
|
||||
{
|
||||
cs = 0.2f;
|
||||
i = 2;
|
||||
|
@ -118,9 +111,9 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
|||
cs = 1.0f;
|
||||
}
|
||||
|
||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
||||
float r = light->GetRed() / 255.0f * cs;
|
||||
float g = light->GetGreen() / 255.0f * cs;
|
||||
float b = light->GetBlue() / 255.0f * cs;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -490,10 +490,12 @@ void F2DDrawer::Flush()
|
|||
}
|
||||
i += dg->mLen;
|
||||
}
|
||||
mVertices.Clear();
|
||||
mData.Clear();
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
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 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_presentshader.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++)
|
||||
{
|
||||
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;
|
||||
lut[index] = color.r;
|
||||
lut[index + 1] = color.g;
|
||||
|
@ -513,6 +514,41 @@ void FGLRenderer::LensDistortScene()
|
|||
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
|
||||
|
@ -521,7 +557,9 @@ void FGLRenderer::LensDistortScene()
|
|||
|
||||
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");
|
||||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
|
@ -539,9 +577,25 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
|||
box = mOutputLetterbox;
|
||||
}
|
||||
|
||||
// Present what was rendered:
|
||||
mBuffers->BindCurrentTexture(0);
|
||||
DrawPresentTexture(box, applyGamma);
|
||||
}
|
||||
else if (!bounds)
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
ClearBorders();
|
||||
}
|
||||
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())
|
||||
|
@ -557,17 +611,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
|||
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);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
RenderScreenQuad();
|
||||
}
|
||||
else if (!bounds)
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
ClearBorders();
|
||||
}
|
||||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -582,6 +626,8 @@ void FGLRenderer::ClearBorders()
|
|||
|
||||
int clientWidth = framebuffer->GetClientWidth();
|
||||
int clientHeight = framebuffer->GetClientHeight();
|
||||
if (clientWidth == 0 || clientHeight == 0)
|
||||
return;
|
||||
|
||||
glViewport(0, 0, clientWidth, clientHeight);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
@ -608,3 +654,40 @@ void FGLRenderer::ClearBorders()
|
|||
}
|
||||
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();
|
||||
ClearPipeline();
|
||||
ClearEyeBuffers();
|
||||
ClearBloom();
|
||||
ClearAmbientOcclusion();
|
||||
}
|
||||
|
@ -128,6 +129,18 @@ void FGLRenderBuffers::ClearAmbientOcclusion()
|
|||
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)
|
||||
{
|
||||
if (handle != 0)
|
||||
|
@ -212,6 +225,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
|
|||
{
|
||||
ClearScene();
|
||||
ClearPipeline();
|
||||
ClearEyeBuffers();
|
||||
ClearBloom();
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
|
@ -255,6 +269,7 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples)
|
|||
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
||||
{
|
||||
ClearPipeline();
|
||||
ClearEyeBuffers();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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
|
||||
|
@ -544,6 +588,43 @@ void FGLRenderBuffers::BlitSceneToTexture()
|
|||
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.)
|
||||
|
|
|
@ -34,6 +34,10 @@ public:
|
|||
|
||||
void BindOutputFB();
|
||||
|
||||
void BlitToEyeTexture(int eye);
|
||||
void BindEyeTexture(int eye, int texunit);
|
||||
void BindEyeFB(int eye, bool readBuffer = false);
|
||||
|
||||
enum { NumBloomLevels = 4 };
|
||||
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
||||
|
||||
|
@ -57,12 +61,14 @@ public:
|
|||
private:
|
||||
void ClearScene();
|
||||
void ClearPipeline();
|
||||
void ClearEyeBuffers();
|
||||
void ClearBloom();
|
||||
void ClearAmbientOcclusion();
|
||||
void CreateScene(int width, int height, int samples);
|
||||
void CreatePipeline(int width, int height);
|
||||
void CreateBloom(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 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);
|
||||
|
@ -97,6 +103,10 @@ private:
|
|||
// Back buffer frame buffer
|
||||
GLuint mOutputFB = 0;
|
||||
|
||||
// Eye buffers
|
||||
TArray<GLuint> mEyeTextures;
|
||||
TArray<GLuint> mEyeFBs;
|
||||
|
||||
static bool FailedCreate;
|
||||
static bool BuffersActive;
|
||||
};
|
||||
|
|
|
@ -244,6 +244,13 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
|||
// Back buffer letterbox for the final output
|
||||
int clientWidth = framebuffer->GetClientWidth();
|
||||
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 screenHeight = framebuffer->GetHeight();
|
||||
float scale = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
|
||||
|
|
|
@ -183,7 +183,8 @@ public:
|
|||
void ClearTonemapPalette();
|
||||
void LensDistortScene();
|
||||
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(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
||||
|
@ -200,6 +201,8 @@ public:
|
|||
double originx, double originy, double scalex, double scaley,
|
||||
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 GetZFar() { return 65536.f; }
|
||||
};
|
||||
|
|
|
@ -154,7 +154,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
if (!gltexture)
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
DrawSubsectors(pass, false, true);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
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_SetPlaneTextureRotation(&plane, gltexture);
|
||||
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.
|
||||
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
|
||||
{
|
||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_quaddrawer.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
@ -128,8 +129,16 @@ void GLPortal::ClearScreen()
|
|||
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
||||
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
||||
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);
|
||||
gl_MatrixStack.Pop(gl_RenderState.mProjectionMatrix);
|
||||
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
||||
|
@ -137,7 +146,6 @@ void GLPortal::ClearScreen()
|
|||
if (multi) glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// DrawPortalStencil
|
||||
|
|
|
@ -682,8 +682,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
|
|||
}
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
int cm = gl_RenderState.GetFixedColormap();
|
||||
gl_RenderState.SetFixedColormap(cm);
|
||||
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 * retval;
|
||||
sector_t * lviewsector;
|
||||
mSceneClearColor[0] = 0.0f;
|
||||
mSceneClearColor[1] = 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.
|
||||
retval = viewsector;
|
||||
lviewsector = viewsector;
|
||||
|
||||
// Render (potentially) multiple views for stereo 3d
|
||||
float viewShift[3];
|
||||
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||
const s3d::Stereo3DMode& stereo3dMode = mainview && toscreen? s3d::Stereo3DMode::getCurrentMode() : s3d::Stereo3DMode::getMonoMode();
|
||||
stereo3dMode.SetUp();
|
||||
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);
|
||||
|
||||
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())
|
||||
{
|
||||
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;
|
||||
if (!stereo3dMode.IsMono() && FGLRenderBuffers::IsEnabled())
|
||||
mBuffers->BlitToEyeTexture(eye_ix);
|
||||
eye->TearDown();
|
||||
}
|
||||
stereo3dMode.TearDown();
|
||||
|
||||
gl_frameCount++; // This counter must be increased right before the interpolations are restored.
|
||||
interpolator.RestoreInterpolations ();
|
||||
return retval;
|
||||
return lviewsector;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1313,30 +1317,17 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
|
|||
gl_fixedcolormap=CM_DEFAULT;
|
||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||
|
||||
bool usefb = gl_usefb || gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight();
|
||||
if (!usefb)
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
// In legacy mode, fail if the requested texture is too large.
|
||||
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
|
||||
glFlush();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))
|
||||
__try
|
||||
#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;
|
||||
bounds.left=bounds.top=0;
|
||||
|
@ -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);
|
||||
|
||||
if (!usefb)
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
glFlush();
|
||||
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
|
||||
|
|
|
@ -110,17 +110,155 @@ CVAR(Bool, gl_nolayer, false, 0)
|
|||
|
||||
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)
|
||||
{
|
||||
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
|
||||
|
||||
|
||||
|
||||
bool additivefog = false;
|
||||
bool foglayer = false;
|
||||
int rel = fullbright? 0 : getExtraLight();
|
||||
|
@ -264,147 +402,17 @@ void GLSprite::Draw(int pass)
|
|||
|
||||
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();
|
||||
|
||||
FVector3 v1;
|
||||
FVector3 v2;
|
||||
FVector3 v3;
|
||||
FVector3 v4;
|
||||
FVector3 v[4];
|
||||
CalculateVertices(v);
|
||||
|
||||
// [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;
|
||||
qd.Set(0, v1[0], v1[1], v1[2], ul, vt);
|
||||
qd.Set(1, v2[0], v2[1], v2[2], ur, vt);
|
||||
qd.Set(2, v3[0], v3[1], v3[2], ul, vb);
|
||||
qd.Set(3, v4[0], v4[1], v4[2], ur, vb);
|
||||
qd.Set(0, v[0][0], v[0][1], v[0][2], ul, vt);
|
||||
qd.Set(1, v[1][0], v[1][1], v[1][2], ur, vt);
|
||||
qd.Set(2, v[2][0], v[2][1], v[2][2], ul, vb);
|
||||
qd.Set(3, v[3][0], v[3][1], v[3][2], ur, vb);
|
||||
qd.Render(GL_TRIANGLE_STRIP);
|
||||
|
||||
if (foglayer)
|
||||
|
@ -703,7 +711,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
x = thingpos.X;
|
||||
z = thingpos.Z;
|
||||
y = thingpos.Y;
|
||||
if (spritetype == RF_FLATSPRITE) z -= thing->Floorclip;
|
||||
if (spritetype != RF_FLATSPRITE) z -= thing->Floorclip;
|
||||
|
||||
// [RH] Make floatbobbing a renderer-only effect.
|
||||
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();
|
||||
}
|
||||
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
radius = light->GetRadius();
|
||||
|
||||
if (dist < radius * radius)
|
||||
{
|
||||
|
@ -106,9 +106,9 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
|||
|
||||
if (frac > 0)
|
||||
{
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
|
|
|
@ -371,6 +371,7 @@ public:
|
|||
void SplitSprite(sector_t * frontsector, bool translucent);
|
||||
void SetLowerParam();
|
||||
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
|
||||
void CalculateVertices(FVector3 *v);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ void GLWall::SetupLights()
|
|||
float y = node->lightsource->Y();
|
||||
float z = node->lightsource->Z();
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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_TEXCOORD = 1,
|
||||
VATTR_COLOR = 2,
|
||||
VATTR_VERTEX2 = 3
|
||||
VATTR_VERTEX2 = 3,
|
||||
VATTR_NORMAL = 4
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "gl_anaglyph.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
|
||||
namespace s3d {
|
||||
|
||||
|
@ -44,6 +46,25 @@ MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
|||
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 */
|
||||
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||
|
|
|
@ -61,14 +61,8 @@ class AnaglyphLeftPose : public LeftEyePose
|
|||
{
|
||||
public:
|
||||
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
||||
virtual void SetUp() const {
|
||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
||||
gl_RenderState.ApplyColorMask();
|
||||
}
|
||||
virtual void TearDown() const {
|
||||
gl_RenderState.ResetColorMask();
|
||||
gl_RenderState.ApplyColorMask();
|
||||
}
|
||||
ColorMask GetColorMask() const { return colorMask; }
|
||||
|
||||
private:
|
||||
ColorMask colorMask;
|
||||
};
|
||||
|
@ -77,14 +71,8 @@ class AnaglyphRightPose : public RightEyePose
|
|||
{
|
||||
public:
|
||||
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
||||
virtual void SetUp() const {
|
||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
||||
gl_RenderState.ApplyColorMask();
|
||||
}
|
||||
virtual void TearDown() const {
|
||||
gl_RenderState.ResetColorMask();
|
||||
gl_RenderState.ApplyColorMask();
|
||||
}
|
||||
ColorMask GetColorMask() const { return colorMask; }
|
||||
|
||||
private:
|
||||
ColorMask colorMask;
|
||||
};
|
||||
|
@ -93,6 +81,7 @@ class MaskAnaglyph : public Stereo3DMode
|
|||
{
|
||||
public:
|
||||
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
||||
void Present() const override;
|
||||
private:
|
||||
AnaglyphLeftPose leftEye;
|
||||
AnaglyphRightPose rightEye;
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "gl_quadstereo.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
|
||||
namespace s3d {
|
||||
|
||||
|
@ -46,7 +48,7 @@ QuadStereo::QuadStereo(double ipdMeters)
|
|||
GLboolean supportsStereo, supportsBuffered;
|
||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||
bool bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||
leftEye.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 */
|
||||
const QuadStereo& QuadStereo::getInstance(float ipd)
|
||||
{
|
||||
|
|
|
@ -47,14 +47,6 @@ class QuadStereoLeftPose : public LeftEyePose
|
|||
{
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -62,14 +54,6 @@ class QuadStereoRightPose : public RightEyePose
|
|||
{
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -84,10 +68,12 @@ class QuadStereo : public Stereo3DMode
|
|||
{
|
||||
public:
|
||||
QuadStereo(double ipdMeters);
|
||||
void Present() const override;
|
||||
static const QuadStereo& getInstance(float ipd);
|
||||
private:
|
||||
QuadStereoLeftPose leftEye;
|
||||
QuadStereoRightPose rightEye;
|
||||
bool bQuadStereoSupported;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ class Stereo3DMode
|
|||
public:
|
||||
/* static methods for managing the selected stereoscopic view state */
|
||||
static const Stereo3DMode& getCurrentMode();
|
||||
static const Stereo3DMode& getMonoMode();
|
||||
|
||||
Stereo3DMode();
|
||||
virtual ~Stereo3DMode();
|
||||
|
@ -84,6 +85,9 @@ public:
|
|||
virtual void SetUp() const {};
|
||||
virtual void TearDown() const {};
|
||||
|
||||
virtual bool IsMono() const { return false; }
|
||||
virtual void Present() const = 0;
|
||||
|
||||
protected:
|
||||
TArray<const EyePose *> eye_ptrs;
|
||||
|
||||
|
@ -101,6 +105,9 @@ class MonoView : public Stereo3DMode
|
|||
public:
|
||||
static const MonoView& getInstance();
|
||||
|
||||
bool IsMono() const override { return true; }
|
||||
void Present() const override { }
|
||||
|
||||
protected:
|
||||
MonoView() { eye_ptrs.Push(¢ralEye); }
|
||||
EyePose centralEye;
|
||||
|
|
|
@ -105,5 +105,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
|||
return *currentStereo3DMode;
|
||||
}
|
||||
|
||||
const Stereo3DMode& Stereo3DMode::getMonoMode()
|
||||
{
|
||||
setCurrentMode(MonoView::getInstance());
|
||||
return *currentStereo3DMode;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace s3d */
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@
|
|||
#include "vectors.h" // RAD2DEG
|
||||
#include "doomtype.h" // M_PI
|
||||
#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_renderbuffers.h"
|
||||
#include <cmath>
|
||||
|
||||
EXTERN_CVAR(Float, vr_screendist)
|
||||
|
@ -89,6 +92,13 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
|||
return instance;
|
||||
}
|
||||
|
||||
void LeftEyeView::Present() const
|
||||
{
|
||||
GLRenderer->mBuffers->BindOutputFB();
|
||||
GLRenderer->ClearBorders();
|
||||
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||
}
|
||||
|
||||
/* static */
|
||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||
|
@ -98,5 +108,13 @@ const RightEyeView& RightEyeView::getInstance(float ipd)
|
|||
return instance;
|
||||
}
|
||||
|
||||
void RightEyeView::Present() const
|
||||
{
|
||||
GLRenderer->mBuffers->BindOutputFB();
|
||||
GLRenderer->ClearBorders();
|
||||
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace s3d */
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||
float getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||
void Present() const override;
|
||||
protected:
|
||||
LeftEyePose eye;
|
||||
};
|
||||
|
@ -96,6 +97,7 @@ public:
|
|||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||
float getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||
void Present() const override;
|
||||
protected:
|
||||
RightEyePose eye;
|
||||
};
|
||||
|
|
|
@ -24,9 +24,6 @@ EXTERN_CVAR(Int, gl_weaponlight)
|
|||
EXTERN_CVAR (Bool, gl_lights);
|
||||
EXTERN_CVAR (Bool, gl_attachedlights);
|
||||
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_particles);
|
||||
EXTERN_CVAR (Int, gl_light_math);
|
||||
|
|
|
@ -189,7 +189,8 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
|
||||
void OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->m2DDrawer->Flush();
|
||||
GLRenderer->m2DDrawer->Draw();
|
||||
GLRenderer->m2DDrawer->Clear();
|
||||
|
||||
const auto &viewport = GLRenderer->mScreenViewport;
|
||||
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
||||
|
|
|
@ -43,15 +43,21 @@
|
|||
#ifdef HAVE_MMX
|
||||
#include "gl/hqnx_asm/hqnx_asm.h"
|
||||
#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)
|
||||
{
|
||||
#ifdef HAVE_MMX
|
||||
if (self < 0 || self > 9)
|
||||
#else
|
||||
if (self < 0 || self > 6)
|
||||
#endif
|
||||
if (self < 0 || self > 16)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -322,6 +364,16 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
|
|||
case 9:
|
||||
return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
#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;
|
||||
|
|
|
@ -64,18 +64,6 @@ extern int TexFormat[];
|
|||
//===========================================================================
|
||||
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.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define DIRECT_PALETTE -2
|
||||
|
||||
#include "tarray.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
||||
class FCanvasTexture;
|
||||
class AActor;
|
||||
|
@ -49,7 +50,11 @@ public:
|
|||
|
||||
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; }
|
||||
|
||||
|
|
|
@ -267,3 +267,5 @@ public:
|
|||
};
|
||||
|
||||
#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_DamageActor, // [arookas]
|
||||
ACSF_SetActorFlag,
|
||||
|
||||
// ZDaemon
|
||||
ACSF_GetTeamScore = 19620, // (int team)
|
||||
|
@ -6036,6 +6038,43 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
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:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -459,23 +459,14 @@ CocoaWindow* CreateCocoaWindow(const NSUInteger styleMask)
|
|||
return window;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
CocoaVideo::CocoaVideo()
|
||||
: m_window(CreateCocoaWindow(STYLE_MASK_WINDOWED))
|
||||
, m_width(-1)
|
||||
, m_height(-1)
|
||||
, m_fullscreen(false)
|
||||
, m_hiDPI(false)
|
||||
enum OpenGLProfile
|
||||
{
|
||||
memset(&m_modeIterator, 0, sizeof m_modeIterator);
|
||||
|
||||
// Set attributes for OpenGL context
|
||||
Core,
|
||||
Legacy
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attributes[16];
|
||||
size_t i = 0;
|
||||
|
||||
|
@ -492,17 +483,59 @@ CocoaVideo::CocoaVideo()
|
|||
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++] = NSOpenGLProfileVersion3_2Core;
|
||||
attributes[i++] = profile;
|
||||
}
|
||||
|
||||
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]];
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
// FIXME: Relative Z is not relative
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z, jiggers.Falloff, jiggers.WFalloff);
|
||||
ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
if (ret > retv) retv = ret;
|
||||
// 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 == -1) retv = ret;
|
||||
else if (retv != -1 && ret > retv) retv = ret;
|
||||
}
|
||||
// Restore previous clipping rectangle.
|
||||
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);
|
||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||
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 *owner, const char *flagname, bool printerror = true);
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "d_player.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
#include "templates.h"
|
||||
#include "math/cmath.h"
|
||||
|
||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||
|
@ -1421,7 +1422,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
|||
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);
|
||||
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; }
|
||||
}
|
||||
|
||||
if (fov > 0 && (fov < 360.))
|
||||
fov = MIN<DAngle>(fov, 360.);
|
||||
|
||||
if (fov > 0)
|
||||
{
|
||||
DAngle an = absangle(viewport->AngleTo(target), viewport->Angles.Yaw);
|
||||
|
||||
|
@ -4678,90 +4685,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
|||
PARAM_STRING (flagname);
|
||||
PARAM_BOOL (value);
|
||||
|
||||
const char *dot = strchr(flagname, '.');
|
||||
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());
|
||||
}
|
||||
ModActorFlag(self, flagname, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4),
|
||||
|
||||
DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, GETOWNER, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, NOFORWARDFALL, 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)
|
||||
{
|
||||
sc.GetToken();
|
||||
switch(sc.TokenType)
|
||||
int token = sc.TokenType;
|
||||
switch(token)
|
||||
{
|
||||
case '~':
|
||||
return new FxUnaryNotBitwise(ParseExpressionA (sc, cls));
|
||||
|
@ -325,7 +326,7 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls)
|
|||
|
||||
case TK_Incr:
|
||||
case TK_Decr:
|
||||
return new FxPreIncrDecr(ParseExpressionA(sc, cls), sc.TokenType);
|
||||
return new FxPreIncrDecr(ParseExpressionA(sc, cls), token);
|
||||
|
||||
default:
|
||||
sc.UnGet();
|
||||
|
|
|
@ -162,6 +162,71 @@ void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
|
|||
#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.
|
||||
|
|
|
@ -62,6 +62,14 @@
|
|||
#include "colormatcher.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
|
||||
// without using fractional steppings
|
||||
int CleanXfac, CleanYfac;
|
||||
|
@ -75,7 +83,7 @@ int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
|||
// FillSimplePoly uses this
|
||||
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
|
||||
// are several repetitions with the same color.
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "menu/menu.h"
|
||||
#include "r_data/voxels.h"
|
||||
|
||||
int active_con_scale();
|
||||
|
||||
FRenderer *Renderer;
|
||||
|
||||
|
@ -857,10 +858,20 @@ void DFrameBuffer::DrawRateStuff ()
|
|||
int chars;
|
||||
int rate_x;
|
||||
|
||||
int textScale = active_con_scale();
|
||||
if (textScale == 0)
|
||||
textScale = CleanXfac;
|
||||
|
||||
chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount);
|
||||
rate_x = Width - ConFont->StringWidth(&fpsbuff[0]);
|
||||
Clear (rate_x, 0, Width, ConFont->GetHeight(), GPalette.BlackIndex, 0);
|
||||
rate_x = Width / textScale - ConFont->StringWidth(&fpsbuff[0]);
|
||||
Clear (rate_x * textScale, 0, Width, ConFont->GetHeight() * textScale, GPalette.BlackIndex, 0);
|
||||
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;
|
||||
if (LastSec < thisSec)
|
||||
|
|
|
@ -522,4 +522,6 @@ inline bool Is54Aspect(int ratio) {
|
|||
return ratio == 4;
|
||||
}
|
||||
|
||||
EXTERN_CVAR(Int, uiscale);
|
||||
|
||||
#endif // __V_VIDEO_H__
|
||||
|
|
|
@ -1,27 +1,46 @@
|
|||
#ifdef __APPLE__
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
/*
|
||||
** i_specialpaths.cpp
|
||||
** 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 <lmcons.h>
|
||||
#include <shlobj.h>
|
||||
#define USE_WINDOWS_DWORD
|
||||
#endif
|
||||
|
||||
#include "cmdlib.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
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "i_system.h"
|
||||
|
||||
typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
|
||||
|
@ -323,314 +342,3 @@ FString M_GetSavegamesPath()
|
|||
}
|
||||
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_ALTHUD = "Alternative HUD";
|
||||
HUDMNU_MESSAGE = "Message Options";
|
||||
HUDMNU_UISCALE = "User interface scale";
|
||||
HUDMNU_CROSSHAIR = "Default Crosshair";
|
||||
HUDMNU_FORCECROSSHAIR = "Force default crosshair";
|
||||
HUDMNU_GROWCROSSHAIR = "Grow crosshair when picking up items";
|
||||
|
@ -1946,6 +1947,7 @@ MSGMNU_SHOWMESSAGES = "Show messages";
|
|||
MSGMNU_SHOWOBITUARIES = "Show obituaries";
|
||||
MSGMNU_SHOWSECRETS = "Show secret notifications";
|
||||
MSGMNU_SCALETEXT = "Scale text in high res";
|
||||
MSGMNU_SCALECONSOLE = "Scale console";
|
||||
MSGMNU_MESSAGELEVEL = "Minimum message level";
|
||||
MSGMNU_CENTERMESSAGES = "Center messages";
|
||||
MSGMNU_MESSAGECOLORS = "Message Colors";
|
||||
|
@ -2237,6 +2239,7 @@ OPTVAL_ANIMATED = "Animated";
|
|||
OPTVAL_ROTATED = "Rotated";
|
||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colors only";
|
||||
OPTVAL_DOUBLE = "Double";
|
||||
OPTVAL_TRIPLE = "Triple";
|
||||
OPTVAL_QUADRUPLE = "Quadruple";
|
||||
OPTVAL_ITEMPICKUP = "Item Pickup";
|
||||
OPTVAL_OBITUARIES = "Obituaries";
|
||||
|
@ -2594,7 +2597,6 @@ GLTEXMNU_RESIZETEX = "Resize textures";
|
|||
GLTEXMNU_RESIZESPR = "Resize sprites";
|
||||
GLTEXMNU_RESIZEFNT = "Resize fonts";
|
||||
GLTEXMNU_PRECACHETEX = "Precache GL textures";
|
||||
GLTEXMNU_CAMTEXOFFSCR = "Camera textures offscreen";
|
||||
GLTEXMNU_TRIMSPREDGE = "Trim sprite edges";
|
||||
GLTEXMNU_SORTDRAWLIST = "Sort draw lists by texture";
|
||||
|
||||
|
@ -2605,9 +2607,6 @@ GLLIGHTMNU_LIGHTDEFS = "Enable light definitions";
|
|||
GLLIGHTMNU_CLIPLIGHTS = "Clip lights";
|
||||
GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites";
|
||||
GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
|
||||
GLLIGHTMNU_FORCEADDITIVE = "Force additive lighting";
|
||||
GLLIGHTMNU_LIGHTINTENSITY = "Light intensity";
|
||||
GLLIGHTMNU_LIGHTSIZE = "Light size";
|
||||
GLLIGHTMNU_LIGHTMATH = "Light quality";
|
||||
|
||||
// OpenGL Preferences
|
||||
|
|
|
@ -768,6 +768,8 @@ OptionMenu "HUDOptions"
|
|||
Submenu "$HUDMNU_ALTHUD", "AltHudOptions"
|
||||
Submenu "$HUDMNU_MESSAGE", "MessageOptions"
|
||||
StaticText " "
|
||||
Slider "$HUDMNU_UISCALE", "uiscale", 0.0, 8.0, 1.0, 0
|
||||
StaticText " "
|
||||
Option "$HUDMNU_CROSSHAIR", "crosshair", "Crosshairs"
|
||||
Option "$HUDMNU_FORCECROSSHAIR", "crosshairforce", "OnOff"
|
||||
Option "$HUDMNU_GROWCROSSHAIR", "crosshairgrow", "OnOff"
|
||||
|
@ -802,6 +804,7 @@ OptionValue "AMCoordinates"
|
|||
OptionValue "AltHUDScale"
|
||||
{
|
||||
0, "$OPTVAL_OFF"
|
||||
4, "$OPTVAL_ON"
|
||||
1, "$OPTVAL_SCALETO640X400"
|
||||
2, "$OPTVAL_PIXELDOUBLE"
|
||||
3, "$OPTVAL_PIXELQUADRUPLE"
|
||||
|
@ -1124,6 +1127,15 @@ OptionValue ScaleValues
|
|||
3, "$OPTVAL_QUADRUPLE"
|
||||
}
|
||||
|
||||
OptionValue ConsoleScaleValues
|
||||
{
|
||||
1, "$OPTVAL_OFF"
|
||||
0, "$OPTVAL_ON"
|
||||
2, "$OPTVAL_DOUBLE"
|
||||
3, "$OPTVAL_TRIPLE"
|
||||
4, "$OPTVAL_QUADRUPLE"
|
||||
}
|
||||
|
||||
OptionValue MessageLevels
|
||||
{
|
||||
0.0, "$OPTVAL_ITEMPICKUP"
|
||||
|
@ -1147,6 +1159,7 @@ OptionMenu MessageOptions
|
|||
Option "$MSGMNU_SHOWOBITUARIES", "show_obituaries", "OnOff"
|
||||
Option "$MSGMNU_SHOWSECRETS", "cl_showsecretmessage", "OnOff"
|
||||
Option "$MSGMNU_SCALETEXT", "con_scaletext", "ScaleValues"
|
||||
Option "$MSGMNU_SCALECONSOLE", "con_scale", "ConsoleScaleValues"
|
||||
Option "$MSGMNU_MESSAGELEVEL", "msg", "MessageLevels"
|
||||
Option "$MSGMNU_DEVELOPER", "developer", "DevMessageLevels"
|
||||
Option "$MSGMNU_CENTERMESSAGES", "con_centernotify", "OnOff"
|
||||
|
|
|
@ -141,6 +141,12 @@ OptionValue "HqResizeModes"
|
|||
7, "$OPTVAL_HQ2XMMX"
|
||||
8, "$OPTVAL_HQ3XMMX"
|
||||
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"
|
||||
|
@ -186,7 +192,6 @@ OptionMenu "GLTextureGLOptions"
|
|||
Option "$GLTEXMNU_RESIZESPR", gl_texture_hqresize_sprites, "OnOff"
|
||||
Option "$GLTEXMNU_RESIZEFNT", gl_texture_hqresize_fonts, "OnOff"
|
||||
Option "$GLTEXMNU_PRECACHETEX", gl_precache, "YesNo"
|
||||
Option "$GLTEXMNU_CAMTEXOFFSCR", gl_usefb, "OnOff"
|
||||
Option "$GLTEXMNU_TRIMSPREDGE", gl_trimsprites, "OnOff"
|
||||
Option "$GLTEXMNU_SORTDRAWLIST", gl_sort_textures, "YesNo"
|
||||
}
|
||||
|
@ -199,10 +204,7 @@ OptionMenu "GLLightOptions"
|
|||
Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo"
|
||||
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
||||
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
|
||||
Option "$GLLIGHTMNU_FORCEADDITIVE", gl_lights_additive, "YesNo"
|
||||
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"
|
||||
|
|
|
@ -69,15 +69,15 @@ uniform sampler2D PaletteLUT;
|
|||
|
||||
vec3 Tonemap(vec3 color)
|
||||
{
|
||||
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 255.0 + 0.5);
|
||||
int index = ((c.r >> 2) * 64 + (c.g >> 2)) * 64 + (c.b >> 2);
|
||||
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 63.0 + 0.5);
|
||||
int index = (c.r * 64 + c.g) * 64 + c.b;
|
||||
int tx = index % 512;
|
||||
int ty = index / 512;
|
||||
return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Tonemap mode define is missing"
|
||||
#error Tonemap mode define is missing
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
Loading…
Reference in a new issue