Compare commits

..
27 Commits
Author SHA1 Message Date
alufolie91 2bc9f32074 simpler fix for localskin minimap angle display crash 2026-10-12 15:15:26 +02:00
alufolie91 f0703dc5e1 fix crash when applying localskin midgame 2026-10-08 09:27:47 +02:00
alufolie91 7ca73cdfdb fix another "0 as null pointer" case 2026-10-08 09:27:44 +02:00
alufolie91 c01d6eccf6 fix arithmetic on NULL pointer when drawing 3d models
caused by localskin code.... sigh......
noticed this while messing with dynamic allocated (local)skins
2026-10-08 09:27:42 +02:00
alufolie91 4ba3eec1e3 cleanup squishdance stuff a bit
we dont need all those things saved per player really lol
2026-10-08 09:27:37 +02:00
alufolie91 601f384314 cleanup saltyhop a little, move it to player struct 2026-10-08 09:27:32 +02:00
alufolie91 19fc0da296 fix localskin menu not showing localskin 3d models
this should use the skins localnumber not the "actual" skinnumber
yeah localskin code still sucks....
fixes https://github.com/Indev450/SRB2Kart-Saturn/issues/230
2026-10-04 01:01:11 +02:00
indev 75d24743c1 Actually change command name to useprefcolor, so its a bit more intuitive 2026-09-27 17:47:01 +02:00
indev 9573d6c4cf Add command to change skin color to prefcolor 2026-09-27 17:46:32 +02:00
alufolie91 4fbcb14699 fix CMake again............ 2026-09-27 17:34:55 +02:00
alufolie91 325b4d5137 v10.1 2026-09-27 17:28:37 +02:00
alufolie91 f2e7b1d0bf fix "Modulative" blendmode in software
forgot to account it when the gamma correction stuff was ported
2026-09-27 17:27:03 +02:00
alufolie91 02834da690 fix desynchs with vanilla on Sewer System
read the sectornode list stuff
this means we reuse old stale data in some cases, which also causes strange bugs with orbiting items in some cases, but thats what vanilla does and we HAVE to keep vanilla compat after all
i really hope this does not cause any fun impossible to debug crashes, but what can you do
2026-09-27 17:26:21 +02:00
alufolie91 0c2bd7fd47 add orbit mobj check into K_MoveHeldObjects 2026-09-27 17:26:08 +02:00
alufolie91 0ce3bea34b disable phobos in cmake
stupid copy paste error
2026-09-26 12:04:05 +02:00
alufolie91 6a2ee9fa6a change version number for phobos
phobos is NOT vanilla compatible and is not meant to be
this should prevent the game be able to connect to vanilla servers hopefully
2026-09-26 12:03:59 +02:00
alufolie91 9525018c02 cleanup controller menu stuff a little more 2026-09-23 19:08:40 +02:00
alufolie91 7ea7020095 dont reset JoyInfo in I_InitJoystick
seems to fix wonky behavior when changing controllers per player
2026-09-23 19:08:37 +02:00
indev e0b9d131ca 20 2026-09-23 19:08:34 +02:00
alufolie91 34ab9d714c fun times with M_DoAssignJoystick
my tired ass forgor cv_usejoystick gets reassinged within this, so the cvar string also changes
2026-09-23 19:08:31 +02:00
orbitalviolet c68aacc922 Fix regression #1507 2026-09-23 19:08:25 +02:00
alufolie91 aeca22c7a3 few more smoler style cleanups 2026-09-23 19:08:17 +02:00
alufolie91 b93d8d1efb smol fix for pm´s in DoSayCommand
sending a pm might change the length of the string which we need to reconsider when sending the cmd
2026-09-23 19:08:12 +02:00
alufolie91 e16546db12 Merge branch 'Saturn-Next' into Saturn 2026-09-16 20:35:11 +02:00
Alug 8cf2395d42 Merge branch 'Saturn-Next' into Saturn 2025-12-06 15:45:51 +01:00
Alug 3abe74de86 release 9.2 2025-12-06 15:33:41 +01:00
Alug 5a61ebf325 Merge branch 'Saturn-Next' into Saturn 2025-12-06 15:33:08 +01:00
83 changed files with 4005 additions and 5473 deletions

No files matched your search

+2 -2
View File
@@ -246,8 +246,6 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
"Compile with AddressSanitizer (libasan).")
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
"Compile with UndefinedBehaviorSanitizer (libubsan).")
set(SRB2_CONFIG_TSAN OFF CACHE BOOL
"Compile with ThreadSanitizer (libtsan).")
set(SRB2_CONFIG_MUMBLE ON CACHE BOOL
"Enable Mumble support")
@@ -292,6 +290,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_script.c
lua_skinlib.c
lua_thinkerlib.c
lua_udatalib.c
lua_glib.c
)
set(SRB2_LUA_HEADERS
@@ -301,6 +300,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_profile.h
lua_libs.h
lua_script.h
lua_udatalib.h
lua_glib.h
)
+5 -18
View File
@@ -75,7 +75,6 @@
# PROFILEMODE=1 - Enable performance profiling (gprof).
# USEASAN=1 - Enable building with Address Sanitizer.
# USEUBSAN=1 - Enable building with Undefined Behavior Sanitizer.
# USETSAN=1 - Enable building with Thread Sanitizer.
# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces.
#
# General flags for building:
@@ -262,35 +261,23 @@ debug_opts=-D_DEBUG
else # build a normal optimized version
debug_opts=-DNDEBUG
opts+=-O3
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEASAN
# compile with asan
opts+=-O1 -fsanitize=address -fno-omit-frame-pointer -fno-common
libs+=-fsanitize=address
NOLTO=1
endif
ifdef USEUBSAN
# compile with ubsan
opts+=-O1 -fsanitize=undefined -fno-omit-frame-pointer
libs+=-fsanitize=undefined
NOLTO=1
endif
ifdef USETSAN
# compile with tsan
opts+=-O1 -fsanitize=thread -fno-omit-frame-pointer
libs+=-fsanitize=thread
NOLTO=1
endif
ifndef DEBUGMODE
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEJEMALLOC
+1
View File
@@ -97,5 +97,6 @@ lua_playerlib.c
lua_script.c
lua_skinlib.c
lua_thinkerlib.c
lua_udatalib.c
lua_glib.c
lua_profile.cpp
+2 -2
View File
@@ -55,8 +55,8 @@ struct lua_longjmp {
void luaD_seterrorobj (lua_State *L, int lerrcode, StkId oldtop) {
switch (lerrcode) {
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
break;
}
case LUA_ERRERR: {
+2
View File
@@ -13,6 +13,8 @@
#include "llimits.h"
#include "lua.h"
#define MEMERRMSG "not enough memory"
#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
+1 -6
View File
@@ -64,9 +64,6 @@ static void freestack (lua_State *L, lua_State *L1) {
}
#define MEMERRMSG "not enough memory"
/*
** open parts that may cause memory-allocation errors
*/
@@ -79,9 +76,7 @@ static void f_luaopen (lua_State *L, void *ud) {
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaS_fix(g->memerrmsg); /* it should never be collected */
luaS_fix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes;
}
-1
View File
@@ -88,7 +88,6 @@ typedef struct global_State {
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
TString *memerrmsg; /* memory-error message */
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
-1
View File
@@ -1739,7 +1739,6 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
// send the value of the variable
UINT8 buf[128];
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
+24 -44
View File
@@ -811,7 +811,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].mo->scalespeed = (fixed_t)LONG(rsp->scalespeed);
// And finally, SET THE MOBJ SKIN damn it.
players[i].mo->skin = skins[players[i].skin];
players[i].mo->skin = &skins[players[i].skin];
players[i].mo->color = players[i].skincolor;
P_SetThingPosition(players[i].mo);
@@ -3347,7 +3347,6 @@ static void Command_connect(void)
return;
}
// StarManiaKG: allow us to join servers from anywhere at any time //
if (Playing() || demo.title || demo.playback)
{
if (demo.title || demo.playback)
@@ -3366,9 +3365,7 @@ static void Command_connect(void)
D_StartTitle();
}
else
{
M_ClearMenus(true); // close the menus
}
// modified game check: no longer handled
// we don't request a restart unless the filelist differs
@@ -3384,52 +3381,37 @@ static void Command_connect(void)
}
else
{
// Get the server node.
if (netgame)
// used in menu to connect to a server in the list
if (netgame && fasticmp(COM_Argv(1), "node"))
{
// used in menu to connect to a server in the list
if (fasticmp(COM_Argv(1), "node"))
{
servernode = (SINT8)atoi(COM_Argv(2));
}
else
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
}
servernode = (SINT8)atoi(COM_Argv(2));
}
else
else if (netgame)
{
// Standard behaviour
if (I_NetOpenSocket)
{
I_NetOpenSocket();
netgame = true;
multiplayer = true;
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
}
else if (I_NetOpenSocket)
{
I_NetOpenSocket();
netgame = true;
multiplayer = true;
if (fasticmp(COM_Argv(1), "any"))
servernode = BROADCASTADDR;
else if (I_NetMakeNodewPort)
{
if (COM_Argc() >= 3) // address AND port
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
else // address only, or address:port
servernode = I_NetMakeNode(COM_Argv(1));
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
D_CloseConnection();
return;
}
}
if (fasticmp(COM_Argv(1), "any"))
servernode = BROADCASTADDR;
else if (I_NetMakeNodewPort && COM_Argc() >= 3)
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
else if (I_NetMakeNodewPort)
servernode = I_NetMakeNode(COM_Argv(1));
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
D_CloseConnection();
return;
}
}
else
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
// invalid address
if (servernode == -1)
@@ -3476,7 +3458,6 @@ static void ResetNode(INT32 node);
//
void CL_ClearPlayer(INT32 playernum)
{
// Handle mobj_t pointers.
if (players[playernum].mo)
{
// Don't leave a NiGHTS ghost!
@@ -3485,7 +3466,6 @@ void CL_ClearPlayer(INT32 playernum)
P_RemoveMobj(players[playernum].mo);
}
// Wipe the struct.
memset(&players[playernum], 0, sizeof(player_t));
}
@@ -4128,7 +4108,7 @@ static void Got_KickCmd(const UINT8 **p, INT32 playernum)
if (!players[i].mo->skin)
CONS_Printf("Mobj skin: NULL!\n");
else
CONS_Printf("Mobj skin: %s\n", players[i].mo->skin->name);
CONS_Printf("Mobj skin: %s\n", ((skin_t *)players[i].mo->skin)->name);
CONS_Printf("Position: %d, %d, %d\n", players[i].mo->x, players[i].mo->y, players[i].mo->z);
if (!players[i].mo->state)
CONS_Printf("State: S_NULL\n");
+2 -8
View File
@@ -1149,19 +1149,13 @@ static void D_FindAddonsToAutoload(void)
// ok so theres still issues with players adding stuff to autoload by accident
// sometimes this stuff contains maps
// you can probably imagine how that goes in a netgame....
int retmap = W_CheckAutoLoadContainsMap(wadsToAutoload);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "Autoload: file %s was not found or not valid.\n", wadsToAutoload);
continue;
}
if (retmap > 0)
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
{
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
continue;
}
if (!postload && W_CheckPostLoadList(wadsToAutoload) > 0)
if (!postload && W_CheckPostLoadList(wadsToAutoload))
{
CONS_Printf("Autoload: forcing postload for file %s\n", wadsToAutoload);
postload = true;
+33 -35
View File
@@ -1043,8 +1043,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_rumble[i]);
CV_RegisterVar(&cv_rumble_strength[i]);
CV_RegisterVar(&cv_rumble_wallbonk[i]);
CV_RegisterVar(&cv_rumble_spinout[i]);
CV_RegisterVar(&cv_rumble_sneakerboost[i]);
CV_RegisterVar(&cv_rumble_offroad[i]);
@@ -1176,14 +1174,14 @@ static void Skin_FindRealNameSkin(consvar_t *cvar)
for (i = 0; i < numskins; i++)
{
// Perfect match with some skin name, no need to find matching realname
if (strncasecmp(value, skins[i]->name, sizeof skins[i]->name) == 0)
if (strncasecmp(value, skins[i].name, sizeof skins[i].name) == 0)
return;
const char *match = strcasestr(skins[i]->realname, value);
const char *match = strcasestr(skins[i].realname, value);
if (match != NULL)
{
matches[nummatches] = i;
matches_pos[nummatches] = match - skins[i]->realname;
matches_pos[nummatches] = match - skins[i].realname;
++nummatches;
}
}
@@ -1191,7 +1189,7 @@ static void Skin_FindRealNameSkin(consvar_t *cvar)
if (nummatches == 1)
{
// Change the cvar to be the value of the name.
CV_StealthSet(cvar, skins[matches[0]]->name);
CV_StealthSet(cvar, skins[matches[0]].name);
}
else if (nummatches > 1)
{
@@ -1205,7 +1203,7 @@ static void Skin_FindRealNameSkin(consvar_t *cvar)
for (i = 0; i < nummatches; ++i)
{
const char *realname = skins[matches[i]]->realname;
const char *realname = skins[matches[i]].realname;
if (matches_pos[i] == 0)
start[0] = 0;
@@ -1220,7 +1218,7 @@ static void Skin_FindRealNameSkin(consvar_t *cvar)
end = realname + matches_pos[i] + query_length;
CONS_Printf("%s\x85%s\x80%s (%s)\n", start, match, end, skins[matches[i]]->name);
CONS_Printf("%s\x85%s\x80%s (%s)\n", start, match, end, skins[matches[i]].name);
}
CONS_Printf("\x86Try be more specific\n");
@@ -1555,13 +1553,13 @@ static void ForceAllSkins(INT32 forcedskin)
if (!dedicated) // But don't do this for dedicated servers, of course.
{
if (i == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin]->name);
CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (i == displayplayers[1])
CV_StealthSet(&cv_skin2, skins[forcedskin]->name);
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
else if (i == displayplayers[2])
CV_StealthSet(&cv_skin3, skins[forcedskin]->name);
CV_StealthSet(&cv_skin3, skins[forcedskin].name);
else if (i == displayplayers[3])
CV_StealthSet(&cv_skin4, skins[forcedskin]->name);
CV_StealthSet(&cv_skin4, skins[forcedskin].name);
}
}
}
@@ -1615,8 +1613,8 @@ static void SendNameAndColor(UINT8 splitplayer)
{
if (player->skincolor)
CV_StealthSetValue(playercolor, player->skincolor);
else if (skins[player->skin]->prefcolor)
CV_StealthSetValue(playercolor, skins[player->skin]->prefcolor);
else if (skins[player->skin].prefcolor)
CV_StealthSetValue(playercolor, skins[player->skin].prefcolor);
else
CV_StealthSet(playercolor, playercolor->defaultvalue);
}
@@ -1627,7 +1625,7 @@ static void SendNameAndColor(UINT8 splitplayer)
if (fastcmp(playername->string, player_names[pnum])
&& playercolor->value == player->skincolor
&& fastcmp(playerskin->string, skins[player->skin]->name))
&& fastcmp(playerskin->string, skins[player->skin].name))
return;
if (playerisbot)
@@ -1656,12 +1654,12 @@ static void SendNameAndColor(UINT8 splitplayer)
{
playerskin->value = foundskin;
SetPlayerSkin(pnum, playerskin->string);
CV_StealthSet(playerskin, skins[playerskin->value]->name);
CV_StealthSet(playerskin, skins[playerskin->value].name);
}
else
{
playerskin->value = player->skin;
CV_StealthSet(playerskin, skins[player->skin]->name);
CV_StealthSet(playerskin, skins[player->skin].name);
// will always be same as current
SetPlayerSkin(pnum, playerskin->string);
}
@@ -1686,7 +1684,7 @@ static void SendNameAndColor(UINT8 splitplayer)
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(pnum))
CV_StealthSet(playerskin, skins[player->skin]->name);
CV_StealthSet(playerskin, skins[player->skin].name);
// check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game)
@@ -1694,7 +1692,7 @@ static void SendNameAndColor(UINT8 splitplayer)
if (playerskin->value < 0)
{
INT32 skinnum = player->skin;
CV_StealthSet(playerskin, skins[skinnum]->name);
CV_StealthSet(playerskin, skins[skinnum].name);
playerskin->value = skinnum;
}
@@ -1782,13 +1780,13 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
// TODO: make cv_skin an array
if (playernum == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin]->name);
CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (playernum == displayplayers[1])
CV_StealthSet(&cv_skin2, skins[forcedskin]->name);
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
else if (playernum == displayplayers[2])
CV_StealthSet(&cv_skin3, skins[forcedskin]->name);
CV_StealthSet(&cv_skin3, skins[forcedskin].name);
else if (playernum == displayplayers[3])
CV_StealthSet(&cv_skin4, skins[forcedskin]->name);
CV_StealthSet(&cv_skin4, skins[forcedskin].name);
}
else
SetPlayerSkinByNum(playernum, skin);
@@ -4358,10 +4356,10 @@ static void SetPrefcolor(int splitplayer)
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
consvar_t *playercolor = colorvars[splitplayer];
if (skins[player->skin]->prefcolor)
if (skins[player->skin].prefcolor)
{
CV_SetValue(playercolor, skins[player->skin]->prefcolor);
CONS_Printf("Set color to %s%s\n", HU_SkinColorToConsoleColor(skins[player->skin]->prefcolor), KartColor_Names[skins[player->skin]->prefcolor]);
CV_SetValue(playercolor, skins[player->skin].prefcolor);
CONS_Printf("Set color to %s%s\n", HU_SkinColorToConsoleColor(skins[player->skin].prefcolor), KartColor_Names[skins[player->skin].prefcolor]);
}
else
{
@@ -5634,7 +5632,7 @@ static void Skin_OnChange(void)
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin]->name);
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
@@ -5643,7 +5641,7 @@ static void Skin_OnChange(void)
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin]->name);
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
}
}
@@ -5664,7 +5662,7 @@ static void Skin2_OnChange(void)
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin]->name);
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin].name);
}
}
@@ -5680,7 +5678,7 @@ static void Skin3_OnChange(void)
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin]->name);
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin].name);
}
}
@@ -5696,7 +5694,7 @@ static void Skin4_OnChange(void)
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin]->name);
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin].name);
}
}
@@ -5739,7 +5737,7 @@ static void Command_ListSkins(void)
for (i = page * 10; i < numskins && i < (page + 1) * 10; i++)
{
int length;
skin_t *skin = skins[i];
skin_t *skin = &skins[i];
if ((length = strlen(skin->name)) > longest_name)
longest_name = length;
@@ -5747,7 +5745,7 @@ static void Command_ListSkins(void)
for (i = page * 10; i < numskins && i < (page + 1) * 10; i++)
{
skin_t *skin = skins[i];
skin_t *skin = &skins[i];
CONS_Printf(
"%s[%-*s]\x80 %s\n",
@@ -5777,7 +5775,7 @@ static void Command_SkinSearch(void)
{
for (s = 0; s < numskins; s++)
{
skin_t *skininput = skins[s];
skin_t *skininput = &skins[s];
if (strcasestr(skininput->realname, COM_Argv(i)))
{
@@ -5801,7 +5799,7 @@ static void Color_OnChange(void)
if (!(cv_debug || devparm) && !(multiplayer || netgame || modeattacking)) // In single player.
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin]->name);
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
+3 -8
View File
@@ -119,25 +119,20 @@ target_compile_definitions(SRB2SDL2 PRIVATE
-DHAVE_THREADS
)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
endif()
## strip debug symbols into separate file when using gcc
# if(CMAKE_COMPILER_IS_GNUCC)
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
+3 -6
View File
@@ -474,7 +474,6 @@ void DRPC_UpdatePresence(void)
char charname[11+SKINNAMESIZE+1];
boolean joinSecretSet = false;
char *clientJoinSecret = NULL;
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
@@ -531,8 +530,7 @@ void DRPC_UpdatePresence(void)
// Grab the host's IP for joining.
if ((join = DRPC_GetServerIP()) != NULL)
{
clientJoinSecret = DRPC_XORIPString(join);
discordPresence.joinSecret = clientJoinSecret;
discordPresence.joinSecret = DRPC_XORIPString(join);
joinSecretSet = true;
}
}
@@ -686,7 +684,7 @@ void DRPC_UpdatePresence(void)
// Character image
while (supportedSkins[checkSkin] != NULL)
{
if (fastcmp(skins[players[consoleplayer].skin]->name, supportedSkins[checkSkin]))
if (fastcmp(skins[players[consoleplayer].skin].name, supportedSkins[checkSkin]))
{
snprintf(charimg, 21, "char%s", supportedSkins[checkSkin]);
discordPresence.smallImageKey = charimg;
@@ -703,7 +701,7 @@ void DRPC_UpdatePresence(void)
discordPresence.smallImageKey = "charcustom";
}
snprintf(charname, 28, "Character: %s", skins[players[consoleplayer].skin]->realname);
snprintf(charname, 28, "Character: %s", skins[players[consoleplayer].skin].realname);
discordPresence.smallImageText = charname; // Character name
}
@@ -714,7 +712,6 @@ void DRPC_UpdatePresence(void)
}
Discord_UpdatePresence(&discordPresence);
free(clientJoinSecret);
}
#endif // HAVE_DISCORDRPC
+1 -1
View File
@@ -147,7 +147,7 @@ extern char logfilename[1024];
#define VERSIONSTRING CLIENTNAME " v10.1"
#define VERSIONSTRINGW CLIENTNAMEW L" v10.1"
#define SATURN_TESTING // comment out for saturn release builds!
//#define SATURN_TESTING // comment out for saturn release builds!
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
// And change CMakeLists.txt (not src/, but in root), for CMake users!
+5 -5
View File
@@ -324,7 +324,7 @@ void F_IntroTicker(void)
// Need to use M_Random otherwise it always uses the same sound
INT32 rskin = M_RandomKey(numskins);
UINT8 rtaunt = M_RandomKey(2);
sfxenum_t rsound = skins[rskin]->soundsid[SKSKBST1+rtaunt];
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
S_StartSound(NULL, rsound);
}
}
@@ -1162,17 +1162,17 @@ void F_StartWaitingPlayers(void)
finalecount = 0;
randskin = M_RandomKey(numskins);
boolean waithires = skins[randskin]->flags && SF_HIRES;
boolean waithires = skins[randskin].flags && SF_HIRES;
Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin]->prefcolor, 0);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
if (waithires)
waitscale = waitscale * FIXED_TO_FLOAT(skins[randskin]->highresscale); // need to set scale here cause im lazy
waitscale = waitscale * FIXED_TO_FLOAT(skins[randskin].highresscale); // need to set scale here cause im lazy
for (i = 0; i < 2; i++)
{
sprframe = &skins[randskin]->spritedef.spriteframes[(6+(i*3)) & FF_FRAMEMASK];
sprframe = &skins[randskin].spritedef.spriteframes[(6+(i*3)) & FF_FRAMEMASK];
driver[i] = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
}
}
+73 -42
View File
@@ -63,6 +63,7 @@
// for replay dates
#include <time.h>
#include <locale.h>
// menu demo things
UINT32 demoDelayTime = 15*TICRATE;
@@ -202,7 +203,7 @@ static INT32 GetSkinNumClosestToStats(UINT8 kartspeed, UINT8 kartweight)
for (i = 0; i < numskins; i++)
{
stat_diff = abs(skins[i]->kartspeed - kartspeed) + abs(skins[i]->kartweight - kartweight);
stat_diff = abs(skins[i].kartspeed - kartspeed) + abs(skins[i].kartweight - kartweight);
if (stat_diff < closest_stats)
{
@@ -265,7 +266,7 @@ void G_ReadDemoExtraData(void)
kartspeed = READUINT8(demobuf.p);
kartweight = READUINT8(demobuf.p);
if (!fasticmp(skins[player->skin]->name, name))
if (!fasticmp(skins[player->skin].name, name))
FindClosestSkinForStats(p, kartspeed, kartweight);
player->kartspeed = kartspeed;
@@ -395,12 +396,12 @@ void G_WriteDemoExtraData(void)
{
// Skin
memset(name, 0, 16);
strncpy(name, skins[players[i].skin]->name, 16);
strncpy(name, skins[players[i].skin].name, 16);
memcpy(demobuf.p, name, 16);
demobuf.p += 16;
WRITEUINT8(demobuf.p, skins[players[i].skin]->kartspeed);
WRITEUINT8(demobuf.p, skins[players[i].skin]->kartweight);
WRITEUINT8(demobuf.p, skins[players[i].skin].kartspeed);
WRITEUINT8(demobuf.p, skins[players[i].skin].kartweight);
}
if (demo_extradata[i] & DXD_COLOR)
@@ -1806,7 +1807,7 @@ void G_BeginRecording(void)
// Skin
memset(name, 0, 16);
strncpy(name, skins[player->skin]->name, 16);
strncpy(name, skins[player->skin].name, 16);
memcpy(demobuf.p, name, 16);
demobuf.p += 16;
@@ -1820,8 +1821,8 @@ void G_BeginRecording(void)
WRITEUINT32(demobuf.p, player->score);
// Kart speed and weight
WRITEUINT8(demobuf.p, skins[player->skin]->kartspeed);
WRITEUINT8(demobuf.p, skins[player->skin]->kartweight);
WRITEUINT8(demobuf.p, skins[player->skin].kartspeed);
WRITEUINT8(demobuf.p, skins[player->skin].kartweight);
}
WRITEUINT8(demobuf.p, 0xFF); // Denote the end of the player listing
@@ -1877,7 +1878,7 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT
// Skin
memset(temp, 0, 16);
strncpy(temp, skins[skinnum]->name, 16);
strncpy(temp, skins[skinnum].name, 16);
memcpy(demobuf.p, temp, 16);
demobuf.p += 16;
@@ -2350,7 +2351,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
for (i = 0; i < numskins; i++)
{
if (fasticmp(skins[i]->name, temp))
if (fasticmp(skins[i].name, temp))
{
pdemo->standings[count].skin = i;
break;
@@ -2386,9 +2387,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
#if defined (_WIN32)
// return the file creation time
// useful for demos that were renamed
// windows only, as file creation times are
// very unreliable (or non existant depending on fs) on linux
static time_t G_GetCreationTime(char *filepath)
static long G_GetCreationTime(char *filepath)
{
struct stat fileinfo;
@@ -2399,24 +2398,35 @@ static time_t G_GetCreationTime(char *filepath)
}
#endif
static char *G_GetDemoDate(menudemo_t *pdemo, const char *dateformat)
static char *G_GetDemoDate(menudemo_t *pdemo)
{
char *endPos = NULL;
char *datetime;
static char datetime[11];
time_t file_time = 0;
struct tm tm_buf;
const char *format = NULL;
struct tm *tm_buf = NULL;
CLEANUP(pfree) char *filename = NULL;
// get le filepath
filename = strdup(pdemo->filepath);
if (!filename)
{
#if defined (_WIN32)
// if we cant get a filename try just getting the file creation time
file_time = G_GetCreationTime(pdemo->filepath);
goto skipfilenametime;
#else
return NULL;
#endif
}
// get the actual filename Zzz...
nameonly(filename);
// the first 10 characters of a replay name is a unix timestamp
// the first 10 characters of a replay name usually is a unix timestamp
// not long enough to contain a valid timestamp
if (strlen(filename) < 10)
{
#if defined (_WIN32)
@@ -2448,49 +2458,67 @@ static char *G_GetDemoDate(menudemo_t *pdemo, const char *dateformat)
#endif
}
// then throw it into localtime to get an actual human readable format lmao
#if defined(_WIN32)
#if defined (_WIN32)
skipfilenametime:
if ((localtime_s(&tm_buf, &file_time) != 0) ||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
#endif
// then throw it into localtime to get an actual human readable format lmao
tm_buf = localtime(&file_time);
// cant believe we ended up in 1970
if (tm_buf == NULL || tm_buf->tm_year <= 110)
{
#if defined (_WIN32)
// uh ohh, we got an invalid time
// try one more time getting the creation time
file_time = G_GetCreationTime(pdemo->filepath);
tm_buf = localtime(&file_time);
if ((localtime_s(&tm_buf, &file_time) != 0) ||
(tm_buf.tm_year <= 110))
if (tm_buf == NULL || tm_buf->tm_year <= 110)
return NULL;
}
goto gotcreationtime;
#else
if ((localtime_r(&file_time, &tm_buf) == NULL) ||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
return NULL;
#endif
}
datetime = malloc(sizeof(pdemo->date)); // mallocma balls
#if defined (_WIN32)
gotcreationtime:
#endif
// no mallocma balls... :c
if (!datetime)
return NULL;
// US ppl are special (:
if (cv_demodateformat.value == 2)
format = "%m.%d.%Y";
else if (cv_demodateformat.value == 1)
format = "%d.%m.%Y";
else
{
const char *locale = setlocale(LC_TIME, NULL);
if (strftime(datetime, sizeof(pdemo->date), dateformat, &tm_buf) == 0)
if (locale == NULL)
format = "%d.%m.%Y"; // fallback to non US format
else if (strstr(locale, "en_US"))
format = "%m.%d.%Y";
else
format = "%d.%m.%Y";
}
if (strftime(datetime, sizeof(datetime), format, tm_buf) == 0)
{
free(datetime);
return NULL;
}
return datetime;
}
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat)
void G_LoadDemoTitle(menudemo_t *pdemo)
{
UINT8 infobuffer[96], *info_p;
UINT16 pdemoversion;
char *demodate = NULL;
size_t count;
memset(pdemo->date, 0, sizeof(pdemo->date));
FILE *handle = fopen(pdemo->filepath, "rb");
if (!handle)
@@ -2518,6 +2546,8 @@ void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat)
pdemoversion = READUINT16(info_p);
memset(pdemo->date, 0, sizeof(pdemo->date));
switch (pdemoversion)
{
case DEMOVERSION: // latest always supported
@@ -2525,12 +2555,13 @@ void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat)
memcpy(pdemo->title, info_p, 64);
// demo date
char *demodate = G_GetDemoDate(pdemo, dateformat);
demodate = G_GetDemoDate(pdemo);
if (demodate)
{
strlcpy(pdemo->date, demodate, sizeof(pdemo->date));
free(demodate);
}
break;
#ifdef DEMO_COMPAT_100
case 0x0001:
@@ -2998,7 +3029,7 @@ void G_DoPlayDemo(char *defdemoname)
kartspeed[p] = READUINT8(demobuf.p);
kartweight[p] = READUINT8(demobuf.p);
if (!fasticmp(skins[players[p].skin]->name, skin))
if (!fasticmp(skins[players[p].skin].name, skin))
FindClosestSkinForStats(p, kartspeed[p], kartweight[p]);
// Look for the next player
@@ -3075,7 +3106,7 @@ void G_AddGhost(char *defdemoname)
CLEANUP(Z_Pfree) UINT8 *buffer = NULL;
mapthing_t *mthing;
UINT16 count, ghostversion;
skin_t *ghskin = skins[0];
skin_t *ghskin = &skins[0];
UINT8 kartspeed = UINT8_MAX, kartweight = UINT8_MAX;
name[16] = '\0';
@@ -3282,9 +3313,9 @@ void G_AddGhost(char *defdemoname)
for (i = 0; i < numskins; i++)
{
if (fasticmp(skins[i]->name, skin))
if (fasticmp(skins[i].name, skin))
{
ghskin = skins[i];
ghskin = &skins[i];
break;
}
}
@@ -3292,7 +3323,7 @@ void G_AddGhost(char *defdemoname)
if (i == numskins)
{
if (kartspeed != UINT8_MAX && kartweight != UINT8_MAX)
ghskin = skins[GetSkinNumClosestToStats(kartspeed, kartweight)];
ghskin = &skins[GetSkinNumClosestToStats(kartspeed, kartweight)];
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Invalid character. Falling back to %s.\n"), pdemoname, ghskin->name);
}
+1 -1
View File
@@ -98,7 +98,7 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
void G_LoadDemoInfo(menudemo_t *pdemo);
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat); // For use in replay search feature
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
void G_DeferedPlayDemo(const char *demo);
typedef enum
+2 -2
View File
@@ -3935,9 +3935,9 @@ void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar
}
if (!color && !modeattacking)
color = skins[pickedchar]->prefcolor;
color = skins[pickedchar].prefcolor;
SetPlayerSkinByNum(consoleplayer, pickedchar);
CV_StealthSet(&cv_skin, skins[pickedchar]->name);
CV_StealthSet(&cv_skin, skins[pickedchar].name);
if (color)
CV_StealthSetValue(&cv_playercolor, color);
+62 -39
View File
@@ -17,9 +17,14 @@
#include "g_game.h"
#include "keys.h"
#include "hu_stuff.h" // need HUFONT start & end
#include "d_net.h"
#include "console.h"
#include "m_menu.h"
#include "i_system.h"
#include "i_video.h"
#include "r_draw.h"
#include "v_video.h"
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
@@ -31,11 +36,10 @@ static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "
// mouse values are used once
consvar_t cv_mousexsens = {"mousexsens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens = {"mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS] = {
{"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing2", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing3", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing4", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
@@ -77,7 +81,6 @@ consvar_t cv_rumble_##type [MAXSPLITSCREENPLAYERS] = {\
{"rumble4_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}\
};
IMPL_RUMBLE_TYPE(wallbonk);
IMPL_RUMBLE_TYPE(spinout);
IMPL_RUMBLE_TYPE(sneakerboost);
IMPL_RUMBLE_TYPE(offroad);
@@ -86,6 +89,7 @@ IMPL_RUMBLE_TYPE(stairjank);
IMPL_RUMBLE_TYPE(brakedrift);
IMPL_RUMBLE_TYPE(driftcharge);
static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
{"gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
@@ -191,6 +195,7 @@ void G_MapEventsToControls(event_t *ev)
{
CONS_Debug(DBG_GAMELOGIC, "Bad downkey input %d\n",ev->data1);
}
#endif
break;
@@ -946,15 +951,16 @@ void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT8 color)
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
if (cv_gamepadled[playernum].value == 0 ||
(window_notinfocus && cv_gamepadledifunfocused.value == 0) ||
color >= MAXTRANSLATIONS)
if (cv_gamepadled[playernum].value == 0 || (window_notinfocus && cv_gamepadledifunfocused.value == 0)
|| color >= MAXTRANSLATIONS)
{
return;
}
if (!I_GamepadHasLED(playernum))
{
return;
}
// so we can override this
skincolor = color ? color : G_GetSkinColorForGamepad(playernum);
@@ -984,21 +990,29 @@ void G_DeviceLEDTick(void)
UINT8 i, newcolor;
if (numcontrollers == 0)
{
return;
}
for (i = 0; i <= splitscreen; i++)
{
if (!cv_usejoystick[i].value || !cv_gamepadled[i].value)
{
continue;
}
// does not have a configurable led! :c
if (!I_GamepadHasLED(i))
{
continue;
}
newcolor = G_GetSkinColorForGamepad(i);
if (curcolor[i] == newcolor) // dont update if same colour
{
continue;
}
G_SetPlayerGamepadIndicatorColor(i, newcolor);
curcolor[i] = newcolor;
@@ -1032,7 +1046,9 @@ void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_stre
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
if (cv_rumble[playernum].value == 0 || (window_notinfocus && cv_rumbleifunfocused.value == 0))
{
return;
}
// doesent need to be super precise
// but ensure this is within range (0-65535)
@@ -1061,34 +1077,46 @@ void G_DeviceRumbleTick(void)
UINT8 i;
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL || demo.playback)
{
return;
}
for (i = 0; i <= splitscreen; i++)
{
if (!cv_usejoystick[i].value || !cv_rumble[i].value)
{
continue;
}
// does not support rumble! :c
if (!I_GamepadHasRumble(i))
{
continue;
}
if (camera[i].freecam)
{
continue;
}
// SDL rumble strength goes from a range or 0-65535 respectively
// the higher, the stronger it is
UINT16 low = 0, high = 0;
// for how long the action should rumble, in ms
UINT16 length = 57; // 57ms is a short pulse, matches super well with this updating once per tic
UINT16 lenght = 57; // 57ms is a short pulse, matches super well with this updating once per tic
const player_t *player = P_GetLocalPlayerForNum(i);
if (!player)
{
continue;
}
// allow lua to do some crap for spectators
if (player->spectator || !player->mo)
{
continue;
}
// reset the rumble if you exit or are ded lel
if (player->exiting ||
@@ -1099,28 +1127,21 @@ void G_DeviceRumbleTick(void)
continue;
}
if (cv_rumble_wallbonk[i].value &&
(player->mo->eflags & MFE_JUSTBOUNCEDWALL))
{
high = RUMBLE_STRONG;
low = RUMBLE_MODERATE;
}
else if (cv_rumble_spinout[i].value &&
player->kartstuff[k_spinouttimer])
if (cv_rumble_spinout[i].value
&& player->kartstuff[k_spinouttimer])
{
//low = high = FRACUNIT / 6;
// try do some some kinda fadeout, 3*TICRATE / 2 is the "default" spinout time
low = high = FixedMul(RUMBLE_VERYSTRONG, FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)));
low = high = FixedMul((RUMBLE_VERYSTRONG), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)))); // try do some some kinda fadeout, 3*TICRATE / 2 is the "default" spinout time
}
else if (cv_rumble_sneakerboost[i].value &&
(player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2))))
else if (cv_rumble_sneakerboost[i].value
&& (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2))))
{
low = high = RUMBLE_STRONG;
}
else if (cv_rumble_offroad[i].value &&
(player->kartstuff[k_offroad]) &&
(player->speed != 0) &&
P_IsObjectOnGround(player->mo))
else if (cv_rumble_offroad[i].value
&& (player->kartstuff[k_offroad])
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
// weaken this depending on if you got hyu or invinc
if (player->kartstuff[k_hyudorotimer])
@@ -1136,48 +1157,50 @@ void G_DeviceRumbleTick(void)
low = high = RUMBLE_MODERATE;
}
}
else if (cv_rumble_bananadrag[i].value &&
(player->kartstuff[k_bananadrag] > TICRATE) &&
(player->speed != 0) &&
P_IsObjectOnGround(player->mo))
else if (cv_rumble_bananadrag[i].value
&& (player->kartstuff[k_bananadrag] > TICRATE)
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
if (leveltime & 1) // this is actually funny lel
high = RUMBLE_MODERATE;
}
else if (cv_rumble_stairjank[i].value &&
(player->stairjank > 8) &&
(player->speed != 0) &&
P_IsObjectOnGround(player->mo))
else if (cv_rumble_stairjank[i].value
&& (player->stairjank > 8)
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
low = high = RUMBLE_VERYWEAK;
}
if (cv_rumble_brakedrift[i].value &&
player->kartstuff[k_brakedrift])
if (cv_rumble_brakedrift[i].value
&& player->kartstuff[k_brakedrift])
{
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
}
// pulse when gettin new driftlevel
// let this come last
if (cv_rumble_driftcharge[i].value &&
player->kartstuff[k_driftcharge] &&
player->driftlevel)
if (cv_rumble_driftcharge[i].value
&& player->kartstuff[k_driftcharge]
&& player->driftlevel)
{
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
// make it rumble slightly longer the higher your driftlevel!
if (player->driftlevel == 2)
length = 114;
lenght = 114;
else if (player->driftlevel == 3)
length = 174;
lenght = 174;
}
// hack alert! i just dont want this thing constantly resetting the rumble lol
if (low == 0 && high == 0)
{
continue;
}
G_PlayerDeviceRumble(i, low, high, length);
G_PlayerDeviceRumble(i, low, high, lenght);
}
}
-2
View File
@@ -118,8 +118,6 @@ extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_strength[MAXSPLITSCREENPLAYERS];
// rumble types
extern consvar_t cv_rumble_wallbonk[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_spinout[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_sneakerboost[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_offroad[MAXSPLITSCREENPLAYERS];
+30 -111
View File
@@ -54,6 +54,10 @@ typedef struct {
// if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time.
boolean gl_maphasportals = false;
// Determine on mapload if current map has any Horizonlines present
// avoids doing a bunch of work during rendering
boolean gl_maphashorizonlines = false;
// ==========================================================================
// FLOOR & CEILING CONVEX POLYS GENERATION
// ==========================================================================
@@ -92,7 +96,7 @@ static void HWR_FreePoly(poly_t *poly)
// divfrac = how far along partline vector is crossing pt
static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t *v2)
{
double frac;
double frac1, frac2;
double num; // numerator
double den; // denominator
double v1x, v1y, v1dx, v1dy; // polygon side vector, v1->v2
@@ -118,23 +122,24 @@ static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t
// first check the frac along the polygon segment,
// (do not accept hit with the extensions)
num = (v3x - v1x)*v3dy + (v1y - v3y)*v3dx;
frac = num / den;
frac1 = num / den;
// 0= cross at v1, 1.0= cross at v2
if (frac < 0.0 || frac > 1.0) // double
if (frac1 < 0.0 || frac1 > 1.0) // double
return false; // not within the polygon side
// now get the frac along the BSP line
// which is useful to determine what is left, what is right
num = (v3x - v1x)*v1dy + (v1y - v3y)*v1dx;
frac2 = num / den;
partline->divfrac = num / den; // how far along partline vector
partline->divfrac = frac2; // how far along partline vector
// [WDJ] find the interception point along the segment.
// It should be slightly more accurate because it is always closer to the
// crossing point than arbitrary positions on the partition line.
partline->divpt.x = v1x + v1dx*frac;
partline->divpt.y = v1y + v1dy*frac;
partline->divpt.x = v1x + v1dx*frac1;
partline->divpt.y = v1y + v1dy*frac1;
return true;
}
@@ -156,71 +161,6 @@ static boolean SameVertex(polyvertex_t *p1, polyvertex_t *p2)
return true;
}
// Adapted from function in prboom.
// Point is to rightside of divline when result > 0,
// but result is multiplied by length of divline.
// Returns near 0, when point is on, or nearly on, the divline.
static inline double point_rightside(fdivline_t *dl, polyvertex_t *v4)
{
// Cross product of dl and vector dl->(x,y) to v4,
// is > 0 when v4 is to right side of divline.
// Viewed along divline from vertex, looking towards positive dx,dy.
// If divline is rotated until dy>0 and dx = 0, then true when rotated
// vertex position is to the right of the divline (v4->x > dl->x).
return ((((double)(v4->x) - (double)(dl->x)) * (double)(dl->dy))
- (((double)(v4->y) - (double)(dl->y)) * (double)(dl->dx)));
}
// [WDJ] The front and back MUST match the BSP determination, else it will assign
// this poly to the wrong sector.
// May have 1 point on the line, and other points might be very close to the line.
// Can only trust a test of a point that is NOT on the line.
// Using a tstdist = 0.5f worked, but it might break on very small poly.
// Avactor.wad had polys with d = 9.09, 5552, 1.64, 1011, 14252, 0.0136, 0.00634, 14655, 3,
// -0.3044, 7, 1.53, etc..,
// and one poly with d = -0.023 with the rest of the points d > 0.
// One 14 point poly with divline len=8, had to test 9 points to find d = 36.
// Typical: divline len=70 d=6828, divline len=1.0 d=35, divline len=1.414 d=5.
// The result of point_rightside is proportional to the length of divline.
// The divline length can be from 1.414 to 14000.
static void UnsplitPoly(fdivline_t *dlnp, poly_t *poly,
poly_t **frontpoly, poly_t **backpoly)
{
int32_t i;
double d;
const double tstd = hypot((double)dlnp->dx, (double)dlnp->dy) / 2.0;
double sumd = 0; // accumulated left or rightness.
for (i = 0; i < poly->numpts; i++)
{
// Look for a point that is obviously to the left or right.
d = point_rightside(dlnp, &poly->pts[i]); // d > 0 is right
sumd += d;
if (d > tstd)
goto poly_rightside;
if (d < -tstd)
goto poly_leftside;
}
// Did not find an obvious left or right point, then
if (sumd < 0)
goto poly_leftside;
poly_rightside:
// poly is to rightside of divline.
*frontpoly = poly;
*backpoly = NULL;
return;
poly_leftside:
// poly is to leftside of divline.
*frontpoly = NULL;
*backpoly = poly;
return;
}
// split a _CONVEX_ polygon in two convex polygons
// outputs:
// frontpoly : polygon on right side of bsp line
@@ -323,7 +263,10 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
// linedefs where each side point the same sector, that is:
// the deep water effect with the original Doom
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
//TODO: make sure front poly is to front of partition line?
*frontpoly = poly;
*backpoly = NULL;
return;
}
@@ -331,14 +274,16 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
if (pe < 0)
{
//I_Error("SplitPoly: only one point for split line (%d %d)", ps, pe);
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
*frontpoly = poly;
*backpoly = NULL;
return;
}
if (pe <= ps)
{
//I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
*frontpoly = poly;
*backpoly = NULL;
return;
}
@@ -401,7 +346,7 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
}
// checks if any line is a portal or horizonline, for optimization
static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_t *line, subsector_t *sub)
static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_t *line)
{
// portal check
if (!gl_maphasportals && firstside && line->special == PORTALSPECIAL)
@@ -417,8 +362,8 @@ static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_
}
// horizonline check
if (line->special == HORIZONSPECIAL)
sub->hashorizon = true;
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
gl_maphashorizonlines = true;
}
// Use each seg of the poly as a partition line, keep only the
@@ -431,7 +376,7 @@ static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_
// segcount : number of seg in the array
// Return frontpoly, which may be new or ptr to poly.
// Called from: HWR_SubsecPoly
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly, subsector_t *sub)
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
{
INT32 i, j;
poly_t* frontpoly = poly; // default, return same poly
@@ -452,7 +397,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly, subse
if (!line)
continue;
CheckForPortalsAndHorizonLines(lseg->side == 0, line, sub);
CheckForPortalsAndHorizonLines(lseg->side == 0, line);
if (line->sidenum[1] != NO_INDEX)
{
@@ -544,23 +489,6 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly, subse
// need 2 points
if (pe >= 0)
{
// Cuts that miss the polygon.
if (ps_frac < 0.0 && cutseg.divfrac < 0.0)
continue;
if (ps_frac > 1.0 && cutseg.divfrac > 1.0)
continue;
#define FRAC_EP 0.01f
// Reject cuts that could make the polygon non-convex.
// Cannot make normal cut, ps_frac end is loose.
if ((ps_frac < (0.0 - FRAC_EP)) || (ps_frac > (1.0f + FRAC_EP)))
continue;
// Cannot make normal cut, cutseg.divfrac end is loose.
if ((cutseg.divfrac < (0.0 - FRAC_EP)) || (cutseg.divfrac > (1.0f + FRAC_EP)))
continue;
#undef FRAC_EP
// generate FRONT poly
frontpoly = HWR_AllocPoly(poly_num_pts);
@@ -615,7 +543,7 @@ static inline void HWR_SubsecPoly(INT32 ssindex, poly_t *poly)
if (poly)
{
poly = CutOutSubsecPoly(lseg, segcount, poly, sub);
poly = CutOutSubsecPoly(lseg, segcount, poly);
#ifdef DEBUG_HWBSP
totalsubsecpolys++;
#endif
@@ -744,7 +672,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
#endif
// Recursively divide front space.
if (frontpoly)
if (LIKELY(frontpoly))
{
WalkBSPNode(bsp->children[0], frontpoly, &bsp->children[0],bsp->bbox[0]);
@@ -752,11 +680,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
memcpy(bbox, bsp->bbox[0], 4*sizeof (fixed_t));
}
else
{
// [WDJ] Having no front poly is as likely as no back poly, since
// logic in Split Poly was changed to check poly direction.
// I_Error("HWR_WalkBSPNode: no front poly, bspnum= %d\n", bspnum);
}
I_Error("WalkBSPNode: no front poly?");
// Recursively divide back space.
if (backpoly)
@@ -871,9 +795,7 @@ static boolean PointInSeg(polyvertex_t *va, polyvertex_t *v1, polyvertex_t *v2)
#endif
}
#ifdef DEBUG_HWBSP
static INT32 numsplitpoly;
#endif
static void SearchSegInBSP(INT32 bspnum, polyvertex_t *p, poly_t *poly)
{
@@ -912,9 +834,8 @@ static void SearchSegInBSP(INT32 bspnum, polyvertex_t *p, poly_t *poly)
for (n = k+1; n < newpoly->numpts; n++)
newpoly->pts[n] = q->pts[n-1];
#ifdef DEBUG_HWBSP
numsplitpoly++;
#endif
extrasubsectors[bspnum].planepoly = newpoly;
HWR_FreePoly(q);
return;
@@ -960,9 +881,7 @@ static void SolveTProblem(void)
I_FinishUpdate(); // page flip or blit buffer
#endif
#ifdef DEBUG_HWBSP
numsplitpoly = 0;
#endif
for (ssnum = 0; ssnum < num_extra_subsector; ssnum++)
{
@@ -999,8 +918,8 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
I_FinishUpdate(); // page flip or blit buffer
#endif
// reset the portal flag
gl_maphasportals = false;
// reset the portal and horizonline flag
gl_maphasportals = gl_maphashorizonlines = false;
// find min/max boundaries of map
#ifdef DEBUG_HWBSP
+40 -19
View File
@@ -614,12 +614,24 @@ void HWR_FreeMapTextures(void)
gl_numtextures = 0;
}
#define NAME flatcheck
#define KEY_TY UINT32
#define HASH_FN vt_hash_integer
#define CMPR_FN vt_cmpr_integer
#include "../verstable.h"
static void HWR_PrecacheLevelFlats(void)
{
// lookup for flats that may´ve been already loaded
flatcheck flatpresent;
size_t i;
#if 0
size_t j;
#endif
INT32 k;
// FIXME: this needs to account for FOFs to properly work
// this kinda messes up encore remapping behavior at times
// so just disable it for now ig
#ifdef GLENCORE
if (encoremap)
{
@@ -627,6 +639,9 @@ static void HWR_PrecacheLevelFlats(void)
}
#endif
flatcheck_init(&flatpresent);
flatcheck_reserve(&flatpresent, numlevelflats);
// special case for encore
#if 0
#ifdef GLENCORE
@@ -635,7 +650,6 @@ static void HWR_PrecacheLevelFlats(void)
// go through all sectors to determine if it should be remapped for encore
for (i = 0; i < numsectors; i++)
{
size_t j;
sector_t *sec = &sectors[i];
// gotta check sector floor and ceiling
@@ -678,7 +692,11 @@ static void HWR_PrecacheLevelFlats(void)
{
const levelflat_t *levelflat = &levelflats[i];
HWR_GetFlat(levelflat->lumpnum, false);
if (flatcheck_is_end(flatcheck_get(&flatpresent, levelflat->lumpnum)))
{
HWR_GetFlat(levelflat->lumpnum, false);
flatcheck_insert(&flatpresent, levelflat->lumpnum);
}
if (levelflat->speed) // is it an animated flat ?
{
@@ -686,11 +704,17 @@ static void HWR_PrecacheLevelFlats(void)
for (k = 0; k < levelflat->numpics; k++)
{
lumpnum_t lump = levelflat->baselumpnum + k;
HWR_GetFlat(lump, false);
if (flatcheck_is_end(flatcheck_get(&flatpresent, lump)))
{
HWR_GetFlat(lump, false);
flatcheck_insert(&flatpresent, lump);
}
}
}
}
}
flatcheck_cleanup(&flatpresent);
}
static void HWR_PrecacheLevelTextures(void)
@@ -714,7 +738,7 @@ static void HWR_PrecacheLevelTextures(void)
{
const line_t *line = &lines[i];
#ifdef GLENCORE
const boolean noencoremap = (encoremap && (line->flags & ML_TFERLINE));
const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1);
#endif
// two sides
for (j = 0; j < 2; j++)
@@ -731,27 +755,25 @@ static void HWR_PrecacheLevelTextures(void)
{
const INT32 texnum = sidetex[f];
if (texnum <= 0 || (unsigned)texnum >= gl_numtextures)
if (texnum < 0 || texnum >= (signed)gl_numtextures)
continue;
if (!(texturepresent[texnum] & 1))
{
texturepresent[texnum] |= 1;
HWR_GetTexture(texnum, false);
}
if (texturepresent[texnum])
continue;
#ifdef GLENCORE
if (noencoremap
&& !(texturepresent[texnum] & 2))
{
texturepresent[texnum] |= 2;
texturepresent[texnum] = 1|noencoremap;
#else
texturepresent[texnum] = 1;
#endif
HWR_GetTexture(texnum, false);
#ifdef GLENCORE
if (noencoremap & 2)
HWR_GetTexture(texnum, true);
}
#endif
}
}
}
// check for animated textures
for (anim = anims; anim < lastanim; anim++)
{
if (!anim->istexture)
@@ -770,7 +792,6 @@ static void HWR_PrecacheLevelTextures(void)
{
HWR_GetTexture(animtexnum, false);
}
#ifdef GLENCORE
if (texpresent & 2)
{
@@ -892,7 +913,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
GLMapTexture_t *gltex;
GLMipmap_t *glMipmap;
if (tex < 0 || (unsigned)tex >= gl_numtextures)
if (tex < 0 || tex >= (signed)gl_numtextures)
{
#ifdef PARANOIA
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
+81 -366
View File
@@ -16,7 +16,6 @@
#include <algorithm>
#include <vector>
#include "../d_main.h"
#include "../doomstat.h"
#include "../doomdef.h"
@@ -121,7 +120,7 @@ ps_metric_t ps_hw_batchdrawtime = {};
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, boolean noencore, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags);
static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap, subsector_t *subsector);
static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
static void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
@@ -205,8 +204,7 @@ static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 b
consvar_t cv_glscreentextures = {"gr_screentextures", "All", CV_CALL|CV_SAVE, glscreentextures_cons_t, CV_screentextures_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef USE_FBO_OGL
static CV_PossibleValue_t glframebuffer_cons_t[] = {{0, "Off"}, {1, "Downsample"}, {2, "Always"}, {0, NULL}};
consvar_t cv_glframebuffer = {"gr_framebuffer", "Off", CV_SAVE|CV_CALL, glframebuffer_cons_t, CV_glframebuffer_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_glframebuffer = {"gr_framebuffer", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, CV_glframebuffer_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_glmdls = {"gr_mdls", "Off", CV_SAVE|CV_CALL, CV_OnOff, M_UpdateOGLMenu, 0, NULL, NULL, 0, 0, NULL};
@@ -257,7 +255,6 @@ static void CV_screentextures_OnChange(void)
#endif
intermissionbginit = false;
}
GL_SetSpecialState(HWD_SET_SCREEN_TEXTURES, cv_glscreentextures.value);
M_UpdateOGLMenu();
}
@@ -266,11 +263,12 @@ static void CV_screentextures_OnChange(void)
static void CV_glframebuffer_OnChange(void)
{
ONLY_IF_GL_LOADED
// screen FBO needs screen textures currently
if (cv_glframebuffer.value != 0 && ((cv_glscreentextures.value != 2) || !supportFBO))
CV_StealthSetValue(&cv_glframebuffer, 0); // dont recursively call this lul
if (loaded_config) // dont do this crap on startup, this is handled elsewhere
I_CheckDownSampleState(true);
if ((cv_glframebuffer.value != 0 && cv_glscreentextures.value != 2)
|| (!supportFBO && cv_glframebuffer.value != 0)) // screen FBO needs screen textures
CV_SetValue(&cv_glframebuffer, 0);
I_DownSample();
RefreshOGLSDLSurface();
M_UpdateOGLMenu();
intermissionbginit = false;
}
@@ -612,7 +610,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
fflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144: // 512x512 lump
case 262144:// 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
break;
@@ -723,7 +721,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
if (subsector && subsector->hashorizon && cv_glhorizonlines.value)
if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
{
// Horizon lines
FOutVector horizonpts[6];
@@ -744,6 +742,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
line_t* ld = line->linedef;
// this check sucks and is a hotspot lel
if (LIKELY(ld->special != HORIZONSPECIAL))
continue;
@@ -808,268 +807,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
#undef SETUP3DVERT
}
static void HWR_RenderFOFHorizonPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap)
{
FSurfaceInfo Surf = {};
polyvertex_t *pv;
pslope_t *slope = NULL;
INT32 shader = SHADER_NONE;
size_t nrPlaneVerts;
INT32 i;
float height; // constant y for all points on the convex flat polygon
static float flatxref = 0.0f, flatyref = 0.0f;
static float fflatsize = 64.0f;
static INT32 flatflag = 63;
size_t len;
float tempxsow, tempytow;
float scrollx = 0.0f, scrolly = 0.0f;
float anglef = 0.0f, cosangf = 0.0f, sinangf = 0.0f;
angle_t angle = 0;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
poly_t *planepoly = xsub->planepoly;
if (!cv_glhorizonlines.value)
return;
if (!subsector || !subsector->hashorizon)
return;
// no convex poly were generated for this subsector
if (!planepoly)
return;
nrPlaneVerts = planepoly->numpts;
if (nrPlaneVerts < 3) // not even a triangle ?
return;
const sector_t *sec = FOFsector;
if (!(PolyFlags & PF_NoTexture))
{
HWR_GetFlat(lumpnum, R_NoEncore(FOFsector, !isceiling));
}
// Get the slope pointer to simplify future code
if (!isceiling && sec->f_slope)
slope = sec->f_slope;
else if (isceiling && sec->c_slope)
slope = sec->c_slope;
height = FixedToFloat(fixedheight);
// Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
{
numAllocedPlaneVerts = (UINT16)nrPlaneVerts;
Z_Free(planeVerts);
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
}
len = W_LumpLength(lumpnum);
switch (len)
{
case 4194304: // 2048x2048 lump
fflatsize = 2048.0f;
flatflag = 2047;
break;
case 1048576: // 1024x1024 lump
fflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144: // 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
break;
case 65536: // 256x256 lump
fflatsize = 256.0f;
flatflag = 255;
break;
case 16384: // 128x128 lump
fflatsize = 128.0f;
flatflag = 127;
break;
case 1024: // 32x32 lump
fflatsize = 32.0f;
flatflag = 31;
break;
default: // 64x64 lump
fflatsize = 64.0f;
flatflag = 63;
break;
}
pv = planepoly->pts;
// reference point for flat texture coord for each vertex around the polygon
flatxref = static_cast<float>(static_cast<fixed_t>(pv->x) & (~flatflag)) / fflatsize;
flatyref = static_cast<float>(static_cast<fixed_t>(pv->y) & (~flatflag)) / fflatsize;
if (!isceiling) // it's a floor
{
scrollx = FixedToFloat(sec->floor_xoffs)/fflatsize;
scrolly = FixedToFloat(sec->floor_yoffs)/fflatsize;
angle = sec->floorpic_angle;
}
else // it's a ceiling
{
scrollx = FixedToFloat(sec->ceiling_xoffs)/fflatsize;
scrolly = FixedToFloat(sec->ceiling_yoffs)/fflatsize;
angle = sec->ceilingpic_angle;
}
if (angle) // Only needs to be done if there's an altered angle
{
// This needs to be done so that it scrolls in a different direction after rotation like software
tempxsow = flatxref;
tempytow = flatyref;
anglef = ANG2RAD(InvAngle(angle));
// This needs to be done so everything aligns after rotation
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
cosangf = cosf(anglef);
sinangf = sinf(anglef);
flatxref = (tempxsow * cosangf) - (tempytow * sinangf);
flatyref = (tempxsow * sinangf) + (tempytow * cosangf);
}
#define SETUP3DVERT(vert, vx, vy) {\
/* Hurdler: add scrolling texture on floor/ceiling */\
vert->s = (float)(((vx) / fflatsize) - flatxref + scrollx);\
vert->t = (float)(flatyref - ((vy) / fflatsize) + scrolly);\
\
/* Need to rotate before translate */\
if (angle) /* Only needs to be done if there's an altered angle */\
{\
tempxsow = vert->s;\
tempytow = vert->t;\
vert->s = (tempxsow * cosangf) - (tempytow * sinangf);\
vert->t = (tempxsow * sinangf) + (tempytow * cosangf);\
}\
\
if (slope)\
{\
fixedheight = P_GetSlopeZAt(slope, FloatToFixed((vx)), FloatToFixed((vy)));\
height = FixedToFloat(fixedheight);\
}\
\
vert->x = (vx);\
vert->y = height;\
vert->z = (vy);\
\
}
HWR_Lighting(&Surf, lightlevel, planecolormap, false);
if (PolyFlags & (PF_Translucent|PF_Fog|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
{
Surf.PolyColor.s.alpha = (UINT8)alpha;
PolyFlags |= PF_Modulated;
}
else
PolyFlags |= PF_Masked|PF_Modulated;
if (HWR_UseShader())
{
if (PolyFlags & PF_Fog)
shader = SHADER_FOG;
else if (cv_ripplewater.value && (PolyFlags & PF_Ripple))
shader = SHADER_WATER;
else
shader = SHADER_FLOOR;
PolyFlags |= PF_ColorMapped;
}
// Horizon lines
FOutVector horizonpts[6];
float dist, vx, vy;
float x1, y1, xd, yd;
UINT8 numplanes, j;
vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion;
static constexpr float renderdist = 27000.0f; // How far out to properly render the plane
static constexpr float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion
const seg_t *line = &segs[subsector->firstline];
for (i = 0; i < subsector->numlines; i++, line++)
{
if (line->polyseg)
continue;
line_t* ld = line->linedef;
if (LIKELY(ld->special != HORIZONSPECIAL))
continue;
if (R_PointOnSegSide(viewx, viewy, line) != 0)
continue;
P_ClosestPointOnLine(viewx, viewy, ld, &v);
dist = FixedToFloat(R_PointToDist(v.x, v.y));
x1 = (line->fv1.x);
y1 = (line->fv1.y);
xd = (line->fv2.x) - x1;
yd = (line->fv2.y) - y1;
// Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion
dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f;
if (dist > 100.0f)
numplanes = 100;
else
numplanes = (UINT8)dist + 1;
for (j = 0; j < numplanes; j++)
{
// Left side
vx = x1 + xd * j / numplanes;
vy = y1 + yd * j / numplanes;
SETUP3DVERT((&horizonpts[1]), vx, vy);
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
SETUP3DVERT((&horizonpts[0]), vx, vy);
// Right side
vx = x1 + xd * (j+1) / numplanes;
vy = y1 + yd * (j+1) / numplanes;
SETUP3DVERT((&horizonpts[2]), vx, vy);
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
SETUP3DVERT((&horizonpts[3]), vx, vy);
// Horizon fills
vx = (horizonpts[0].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
vy = (horizonpts[0].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
SETUP3DVERT((&horizonpts[5]), vx, vy);
horizonpts[5].y = gl_viewz;
vx = (horizonpts[3].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
vy = (horizonpts[3].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
SETUP3DVERT((&horizonpts[4]), vx, vy);
horizonpts[4].y = gl_viewz;
// Draw
HWR_ProcessPolygon(&Surf, horizonpts, 6, PolyFlags, shader, true);
}
}
#undef SETUP3DVERT
}
#ifdef WALLSPLATS
static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
{
@@ -1503,44 +1240,46 @@ static inline boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
pSurf->PolyColor.s.alpha = 0xFF;
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// set alpha for transparent walls
switch (gl_linedef->special)
if (LIKELY(!gl_curline->polyseg))
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// set alpha for transparent walls
switch (gl_linedef->special)
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
}
}
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
else if (gl_curline->polyseg->translucency > 0)
{
// Polyobject translucency is shared between all of its lines
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
@@ -1647,8 +1386,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// two sided line
if (gl_backsector)
{
const INT32 gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
const INT32 gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
fixed_t texturevpeg;
@@ -1659,7 +1397,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (!gl_curline->polyseg) // Don't do it for polyobjects
{
// Sky Ceilings
wallVerts[2].y = wallVerts[3].y = FLOATMAX; // draw to top of map space
wallVerts[3].y = wallVerts[2].y = FLOATMAX;
auto draw_sky_walls = []
(int vert1, int vert2, fixed_t world, fixed_t worldslope, auto& wwallVerts, auto& sSurf) FUNCINLINE
@@ -1669,9 +1407,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_DrawSkyWall(wwallVerts, &sSurf);
};
// worldtop = front ceiling
// worldhigh = back ceiling
if (gl_frontsector->ceilingpic == skyflatnum)
{
if (gl_backsector->ceilingpic == skyflatnum)
@@ -1690,17 +1425,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
worldtop = worldhigh;
worldtopslope = worldhighslope;
}
else if (!gl_toptexture &&
(worldhigh <= worldtop && worldhighslope <= worldtopslope) && // Assuming ESLOPE is always on with my changes
(worldhigh != worldtop || worldhighslope != worldtopslope))
{
// Only the frontsector is sky.
// If there's no upper texture, extend the sky wall
// down to the lower of the two ceilings.
fixed_t top = std::min(worldtop, worldhigh);
fixed_t topslope = std::min(worldtopslope, worldhighslope);
draw_sky_walls(0, 1, top, topslope, wallVerts, Surf);
}
else
{
// Only the frontsector is sky, just draw a skywall from the front ceiling
@@ -1713,11 +1437,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(0, 1, worldtop, worldtopslope, wallVerts, Surf);
}
// worldbottom = front floor
// worldlow = back floor
// Sky Floors
wallVerts[0].y = wallVerts[1].y = FLOATMIN; // draw to bottom of map space
wallVerts[0].y = wallVerts[1].y = FLOATMIN;
if (gl_frontsector->floorpic == skyflatnum)
{
@@ -1729,7 +1450,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_bottomtexture))
&& !(gl_sidedef->bottomtexture))
{
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
@@ -1740,25 +1461,15 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(3, 2, worldbottom, worldbottomslope, wallVerts, Surf);
}
}
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_bottomtexture))
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_sidedef->bottomtexture))
{
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
else if (gl_frontsector->ceilingpic == skyflatnum &&
gl_backsector->ceilingpic == skyflatnum &&
(worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_bottomtexture))
{
// Both ceilings are sky, but neither floor is sky.
// If there's a lower wall gap without a bottom texture,
// draw a skywall from the backsector's higher floor.
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
}
gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
// check TOP TEXTURE
if (gl_toptexture && (worldhighslope < worldtopslope || worldhigh < worldtop))
{
@@ -1822,6 +1533,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
// check BOTTOM TEXTURE
if (gl_bottomtexture && (worldlowslope > worldbottomslope || worldlow > worldbottom))
{
@@ -3224,14 +2937,16 @@ static void HWR_Subsector(size_t num)
UINT8 alpha;
light = R_GetPlaneLight(gl_frontsector, centerHeight, underside);
alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap);
HWR_AddTransparentFloor(0,
&extrasubsectors[num],
!bottom,
roverheight,
*gl_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap, sub);
true, rover->master->frontsector->extra_colormap);
}
else if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend) // SoM: Flags are more efficient
{
@@ -3243,12 +2958,13 @@ static void HWR_Subsector(size_t num)
roverheight,
*gl_frontsector->lightlist[light].lightlevel,
CLAMP(rover->alpha, 0, 255), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : static_cast<FBITFIELD>(PF_Translucent)),
false, gl_frontsector->lightlist[light].extra_colormap, sub);
false, gl_frontsector->lightlist[light].extra_colormap);
}
else
{
HWR_GetFlat(flatlump, R_NoEncore(rover->master->frontsector, bottom));
HWR_GetFlat(flatlump, R_NoEncore(gl_frontsector, !bottom));
light = R_GetPlaneLight(gl_frontsector, centerHeight, underside);
HWR_RenderPlane(sub, &extrasubsectors[num], !bottom, roverheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, flatlump,
rover->master->frontsector, 255, gl_frontsector->lightlist[light].extra_colormap);
}
@@ -3580,7 +3296,7 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
// technically this_scale gets multiplied and added to sprite y/x scale, but this thing needs it for some crap so ill just throw it in here again
this_scale = FixedToFloat(spr->mobj->scale);
const skin_t *moskin = R_GetMobjSkin(spr->mobj);
const skin_t *moskin = K_GetMobjSkin(spr->mobj);
if (moskin && moskin->flags & SF_HIRES)
this_scale *= FixedToFloat(moskin->highresscale);
@@ -3744,12 +3460,8 @@ static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVert
{
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
const float f_xdiff = (spr->x1 - gl_viewx);
const float f_ydiff = (spr->z1 - gl_viewy);
const float f_zdiff = (spr->gzt - gl_viewz);
const float sprdist = sqrtf((f_xdiff*f_xdiff) + (f_ydiff*f_ydiff) + (f_zdiff*f_zdiff));
const float distfact = ((2.0f * spr->dispoffset) + 20.0f) / sprdist;
const float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
const float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
for (size_t i = 0; i < 4; i++)
{
@@ -4452,7 +4164,7 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I
wallinfo->wallcolormap = wallcolormap;
}
static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap, subsector_t *subsector)
static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap)
{
planeinfo_t *planeinfo = static_cast<planeinfo_t*>(HWR_CreateDrawNode(DRAWNODE_PLANE));
@@ -4466,9 +4178,6 @@ static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, b
planeinfo->blend = blend;
planeinfo->fogplane = fogplane;
planeinfo->planecolormap = planecolormap;
// horizonplanes need to be drawn BEFORE skywalls, so lets hope this works without too many issues....
HWR_RenderFOFHorizonPlane(subsector, planeinfo->xsub, planeinfo->isceiling, planeinfo->fixedheight, planeinfo->blend, planeinfo->lightlevel, planeinfo->lumpnum, planeinfo->FOFSector, (UINT8)planeinfo->alpha, planeinfo->planecolormap);
}
// Adding this for now until I can create extrasubsector info for polyobjects
@@ -4578,10 +4287,7 @@ static void HWR_RenderDrawNodes(void)
gl_frontsector = NULL;
if (!(plane->blend & PF_NoTexture))
{
const boolean ceiling = plane->FOFSector ? !plane->isceiling : plane->isceiling; // match software!
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, ceiling));
}
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling));
HWR_RenderPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->blend, plane->lightlevel,
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
@@ -4655,8 +4361,17 @@ static void HWR_DrawSprites(void)
{
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
/* fuck you */
md2_t *md2 = &R_GetMobjSkin(spr->mobj)->playermodel;
md2_t *md2;
if (spr->mobj->localskin)
{
if (spr->mobj->skinlocal)
md2 = &md2_localplayermodels[(skin_t *)spr->mobj->localskin - localskins];
else
md2 = &md2_playermodels [(skin_t *)spr->mobj->localskin - skins];
}
else
md2 = &md2_playermodels[(skin_t *)spr->mobj->skin - skins];
// 8/1/19: Only don't display player models if no default SPR_PLAY is found.
if (((md2->notfound || md2->scale < 0.0f) && ((!cv_glfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)) || spr->mobj->state == &states[S_PLAY_SIGN])
@@ -4878,7 +4593,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
rot = (thing->frame & FF_FRAMEMASK);
sprskin = R_GetMobjSkin(thing);
sprskin = K_GetMobjSkin(thing);
//Fab : 02-08-98: 'skin' override spritedef currently used for skin
if (sprskin && thing->sprite == SPR_PLAY)
@@ -6154,7 +5869,7 @@ void HWR_Startup(void)
HWR_TogglePaletteRendering();
if (msaa)
GL_SetSpecialState(HWD_SET_MSAA, 1);
GL_SetSpecialState(HWD_SET_MSAA, a2c ? 2 : 1);
HWR_RegisterCommands();
}
@@ -6242,7 +5957,7 @@ void HWR_Shutdown(void)
GL_FlushScreenTextures();
HWR_ClearAllTextures();
#ifdef USE_FBO_OGL
GL_FBO_Disable();
GL_Framebuffer_Disable();
#endif
}
+2
View File
@@ -43,6 +43,7 @@ void HWR_Startup(void);
void HWR_Shutdown(void);
extern unsigned msaa;
extern boolean a2c;
extern FTransform atransform;
extern float gl_viewsin, gl_viewcos;
@@ -171,6 +172,7 @@ void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
// hw_bsp.c
void HWR_CreatePlanePolygons(INT32 bspnum);
extern boolean gl_maphasportals;
extern boolean gl_maphashorizonlines;
// Console variables
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
+75 -77
View File
@@ -73,6 +73,8 @@
#endif
md2_t md2_models[NUMSPRITES] = {};
md2_t md2_playermodels[MAXSKINS] = {};
md2_t md2_localplayermodels[MAXLOCALSKINS] = {};
/*
* free model
@@ -419,7 +421,6 @@ static void md2_loadTexture(md2_t *model)
}
}
}
GL_SetTexture(glPatch->mipmap);
HWR_UnlockCachedPatch(glPatch);
}
@@ -477,7 +478,6 @@ static void md2_loadBlendTexture(md2_t *model)
glPatch->mipmap->width = (UINT16)w;
glPatch->mipmap->height = (UINT16)h;
}
GL_SetTexture(glPatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(glPatch);
@@ -487,19 +487,6 @@ static void md2_loadBlendTexture(md2_t *model)
// Don't spam the console, or the OS with fopen requests!
static boolean nomd2s = false;
// initializes an md2 model
static void HWR_InitModel(md2_t *md2)
{
md2->scale = -1.0f;
md2->model = NULL;
md2->glpatch = NULL;
md2->skinnum = -1;
md2->notexturefile = false;
md2->noblendfile = false;
md2->notfound = true;
md2->error = false;
}
void HWR_InitMD2(void)
{
size_t i;
@@ -509,22 +496,38 @@ void HWR_InitMD2(void)
float scale, offset;
CONS_Printf("InitMD2()...\n");
for (s = 0; s < numskins; s++)
for (s = 0; s < MAXSKINS; s++)
{
skin_t *skin = skins[s];
HWR_InitModel(&skin->playermodel);
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].glpatch = NULL;
md2_playermodels[s].skin = -1;
md2_playermodels[s].notexturefile = false;
md2_playermodels[s].noblendfile = false;
md2_playermodels[s].notfound = true;
md2_playermodels[s].error = false;
}
for (s = 0; s < numlocalskins; s++)
for (s = 0; s < MAXLOCALSKINS; s++)
{
skin_t *skin = localskins[s];
HWR_InitModel(&skin->playermodel);
md2_localplayermodels[s].scale = -1.0f;
md2_localplayermodels[s].model = NULL;
md2_localplayermodels[s].glpatch = NULL;
md2_localplayermodels[s].skin = -1;
md2_localplayermodels[s].notexturefile = false;
md2_localplayermodels[s].noblendfile = false;
md2_localplayermodels[s].notfound = true;
md2_localplayermodels[s].error = false;
}
for (i = 0; i < NUMSPRITES; i++)
{
HWR_InitModel(&md2_models[i]);
md2_models[i].scale = -1.0f;
md2_models[i].model = NULL;
md2_models[i].glpatch = NULL;
md2_models[i].skin = -1;
md2_models[s].notexturefile = false;
md2_models[s].noblendfile = false;
md2_models[i].notfound = true;
md2_models[i].error = false;
}
// read the mdls.dat file
@@ -541,7 +544,6 @@ void HWR_InitMD2(void)
return;
}
}
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
for (i = 0; i < NUMSPRITES; i++)
@@ -556,21 +558,18 @@ void HWR_InitMD2(void)
}
}
for (s = 0; s < numskins; s++)
for (s = 0; s < MAXSKINS; s++)
{
skin_t *skin = skins[s];
if (fasticmp(name, skin->name))
if (fasticmp(name, skins[s].name))
{
skin->playermodel.skinnum = s;
skin->playermodel.scale = scale;
skin->playermodel.offset = offset;
skin->playermodel.notfound = false;
strcpy(skin->playermodel.filename, filename);
md2_playermodels[s].skin = s;
md2_playermodels[s].scale = scale;
md2_playermodels[s].offset = offset;
md2_playermodels[s].notfound = false;
strcpy(md2_playermodels[s].filename, filename);
goto md2found;
}
}
// no sprite/player skin name found?!?D
CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name);
md2found:
@@ -580,16 +579,12 @@ md2found:
fclose(f);
}
void HWR_AddPlayerMD2(INT32 skinnum, boolean local) // For MD2's that were added after startup
void HWR_AddPlayerMD2(INT32 skin, boolean local) // For MD2's that were added after startup
{
FILE *f;
char name[20], filename[32];
float scale, offset;
skin_t *skin = R_GetSkinArray(local)[skinnum];
// ensure we ALWAYS initialize the model even if no mdls.dat was found!
HWR_InitModel(&skin->playermodel);
md2_t *md2s;
if (nomd2s)
return;
@@ -603,7 +598,6 @@ void HWR_AddPlayerMD2(INT32 skinnum, boolean local) // For MD2's that were added
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "mdls.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno));
@@ -612,25 +606,25 @@ void HWR_AddPlayerMD2(INT32 skinnum, boolean local) // For MD2's that were added
}
}
md2s = (local ? md2_localplayermodels : md2_playermodels);
// Check for any MD2s that match the names of player skins!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
if (fasticmp(name, skin->name))
if (fasticmp(name, K_GetSkinArray(local)[skin].name))
{
skin->playermodel.skinnum = skinnum;
skin->playermodel.scale = scale;
skin->playermodel.offset = offset;
skin->playermodel.notfound = false;
strcpy(skin->playermodel.filename, filename);
md2s[skin].skin = skin;
md2s[skin].scale = scale;
md2s[skin].offset = offset;
md2s[skin].notfound = false;
strcpy(md2s[skin].filename, filename);
goto playermd2found;
}
}
//CONS_Printf("MD2 for player skin %s not found\n", skins[skinnum].name);
skin->playermodel.notfound = true;
//CONS_Printf("MD2 for player skin %s not found\n", skins[skin].name);
md2s[skin].notfound = true;
playermd2found:
fclose(f);
}
@@ -680,7 +674,6 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
//CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]);
md2_models[spritenum].notfound = true;
spritemd2found:
fclose(f);
}
@@ -1153,6 +1146,8 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
md2_t *md2s = NULL;
int skinnum = 0;
patch_t *gpatch, *blendgpatch;
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
INT32 durs = spr->mobj->state->tics;
@@ -1212,29 +1207,36 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
// 1. load model+texture if not already loaded
// 2. draw model with correct position, rotation,...
// Use the player MD2 list if the mobj has a skin and is using the player sprites
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
/* fuck you */
if (spr->mobj->localskin)
{
/* fuck you */
md2_t *md2s = &R_GetMobjSkin(spr->mobj)->playermodel;
if (!md2s->notfound)
if (spr->mobj->skinlocal)
{
md2 = md2s;
md2->skinnum = R_GetMobjSkinNum(spr->mobj);
sprinfo = &spriteinfo[spr->mobj->sprite];
md2s = md2_localplayermodels;
skinnum = (skin_t *)spr->mobj->localskin - localskins;
}
else // if we can't find the player md2, use SPR_PLAY's MD2.
else
{
md2 = &md2_models[spr->mobj->sprite];
sprinfo = &spriteinfo[spr->mobj->sprite];
md2s = md2_playermodels;
skinnum = (skin_t *)spr->mobj->localskin - skins;
}
}
else
else if (spr->mobj->skin)
{
md2s = md2_playermodels;
skinnum = (skin_t *)spr->mobj->skin - skins;
}
// 1. load model+texture if not already loaded
// 2. draw model with correct position, rotation,...
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2s[skinnum].notfound) // Use the player MD2 list if the mobj has a skin and is using the player sprites
{
md2 = &md2s[skinnum];
md2->skin = skinnum;
sprinfo = &spriteinfo[spr->mobj->sprite];
}
else
{ // if we can't find the player md2, use SPR_PLAY's MD2.
md2 = &md2_models[spr->mobj->sprite];
sprinfo = &spriteinfo[spr->mobj->sprite];
}
@@ -1297,7 +1299,6 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
&& gpatch->width == blendgpatch->width && gpatch->height == blendgpatch->height)
{
INT32 tcskinnum = TC_DEFAULT;
if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
{
if (spr->mobj->type == MT_CYBRAKDEMON)
@@ -1312,16 +1313,13 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
if (spr->mobj->colorized)
{
tcskinnum = TC_RAINBOW;
}
else
{
tcskinnum = (INT32)R_GetMobjSkinNum(spr->mobj);
tcskinnum = (INT32)(K_GetMobjSkinNum(K_GetMobjSkin(spr->mobj), spr->mobj->skinlocal));
}
}
else
tcskinnum = TC_DEFAULT;
else tcskinnum = TC_DEFAULT;
}
HWR_GetBlendedTexture(gpatch, blendgpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
@@ -1385,7 +1383,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
p.z = FIXED_TO_FLOAT(interp.z);
if ((spr->mobj->skin || spr->mobj->localskin) && spr->mobj->sprite == SPR_PLAY)
sprdef = &R_GetMobjSkin(spr->mobj)->spritedef;
sprdef = &K_GetMobjSkin(spr->mobj)->spritedef;
else
sprdef = &sprites[spr->mobj->sprite];
+3 -1
View File
@@ -33,11 +33,13 @@ typedef struct
void *blendglpatch;
boolean noblendfile; // true if blend texture file was not found
boolean notfound;
INT32 skinnum;
INT32 skin;
boolean error;
} md2_t;
extern md2_t md2_models[NUMSPRITES];
extern md2_t md2_playermodels[MAXSKINS];
extern md2_t md2_localplayermodels[MAXLOCALSKINS];
void HWR_InitMD2(void);
void HWR_DrawMD2(gl_vissprite_t *spr);
+20
View File
@@ -193,6 +193,26 @@
"}\n" \
"#endif\0"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
"uniform vec4 tint_color;\n" \
"uniform vec4 fade_color;\n" \
"uniform float lighting;\n" \
"uniform float fade_start;\n" \
"uniform float fade_end;\n" \
GLSL_DOOM_COLORMAP \
GLSL_DOOM_LIGHT_EQUATION \
"void main(void) {\n" \
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
"vec4 base_color = texel * poly_color;\n" \
"vec4 final_color = base_color;\n" \
GLSL_SOFTWARE_TINT_EQUATION \
GLSL_SOFTWARE_FADE_EQUATION \
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\n" \
// hand tuned adjustments for light level calculation
#define GLSL_FLOOR_FUDGES \
"#define STARTMAP_FUDGE 1.06\n" \
+75 -282
View File
@@ -136,61 +136,32 @@ enum
{
FBO_NONE,
FBO_ARB,
FBO_EXT
FBO_EXT,
FBO_EXT_STENCIL // supports stencil attachment
};
typedef struct
{
GLuint fboobj; // normal single sample fbo
GLuint rboobj; // normal single sample rbo for depth and stencil stuff
GLuint tex; // fbo texture for color
GLuint msaa_fboobj; // msaa fbo
GLuint msaa_rboobj; // msaa rbo for color this time
GLuint msaa_depthrboobj; // msaa rbo for depth and stencil stuff
GLuint fboobj; // actual Framebuffer Object
GLuint rboobj; // Renderbuffer Object
GLuint tex; // Framebuffer texture
boolean init;
boolean msaa; // true if the msaa fbo is the render target ugh
boolean bound; // true if the fbo is currently bound as the framebuffer
} fboobj_t;
// this is a little messy but less messy than having two of those tbh
static fboobj_t framebufferobject = {};
int supportFBO = FBO_NONE;
// older gl versions might not have these, so prevent compile errors
#ifndef GL_DEPTH_COMPONENT
#define GL_DEPTH_COMPONENT 0x1902
#endif
#ifndef GL_DEPTH_ATTACHMENT_EXT
#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
#endif
// this should still give a simple depth only rbo
#ifndef GL_DEPTH24_STENCIL8
#define GL_DEPTH24_STENCIL8 0x88F0
GL_DEPTH24_STENCIL8 GL_DEPTH_COMPONENT_EXT
#endif
#ifndef GL_DEPTH_STENCIL_ATTACHMENT
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#endif
#ifndef GL_COLOR_ATTACHMENT0_EXT
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
#endif
#ifndef GL_READ_FRAMEBUFFER_EXT
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
#endif
#ifndef GL_DRAW_FRAMEBUFFER_EXT
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
#endif
#ifndef GL_FRAMEBUFFER_EXT
#define GL_FRAMEBUFFER_EXT 0x8D40
#endif
#ifndef GL_RENDERBUFFER_EXT
#define GL_RENDERBUFFER_EXT 0x8D41
#endif
#ifndef GL_FRAMEBUFFER_COMPLETE_EXT
#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
GL_DEPTH_STENCIL_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
#endif
static void GL_FBO_DeleteAttachments(void);
static void GL_FBO_Resolve(GLbitfield mask);
static void GL_Framebuffer_DeleteAttachments(void);
#endif
// needed for glportals
@@ -508,10 +479,6 @@ typedef void (APIENTRY * PFNglRenderbufferStorage) (GLenum target, GLenum intern
static PFNglRenderbufferStorage pglRenderbufferStorage;
typedef void (APIENTRY * PFNglFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLenum renderbuffer);
static PFNglFramebufferRenderbuffer pglFramebufferRenderbuffer;
typedef void (APIENTRY * PFNglRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
static PFNglRenderbufferStorageMultisample pglRenderbufferStorageMultisample;
typedef void (APIENTRY * PFNglBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
static PFNglBlitFramebuffer pglBlitFramebuffer;
/* 2.1 extension functions for framebuffers and renderbuffers */
typedef void (APIENTRY * PFNglGenFramebuffersEXT) (GLsizei n, GLuint *ids);
@@ -802,22 +769,28 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
#ifdef USE_FBO_OGL
static int GLFramebuffer_CheckExt(void)
{
// check for the standard arb extensions
// these should be there from version 3.0 onwards
// in opengl 3.0 and up fbos are standart and always supported
if (majorGL >= 3)
return FBO_ARB;
// gl versions from 2.1 may still support framebuffer objects
// maybe, just maybe, we support the standart extensions
if (GL_isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions) &&
GL_isExtAvailable("GL_ARB_framebuffer_object", gl_extensions) &&
GL_isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions))
{
return FBO_ARB;
}
// gl versions from 2.1 and older may still support framebuffer objects
// depending on vendor and driver support
// nope, try the older 2.1 extensions
if (GL_isExtAvailable("GL_EXT_framebuffer_no_attachments", gl_extensions) &&
GL_isExtAvailable("GL_EXT_framebuffer_object", gl_extensions) &&
GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions) &&
GL_isExtAvailable("GL_EXT_packed_depth_stencil", gl_extensions)) // we use the stencil buffer for stuff like portals, so its better to make stencil extension a requirement
GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions))
{
// perhaps we may even support a stencil attachment
if (GL_isExtAvailable("GL_EXT_packed_depth_stencil", gl_extensions))
return FBO_EXT_STENCIL;
// no stencil support, sad
return FBO_EXT;
}
@@ -933,69 +906,38 @@ void SetupGLFunc4(void)
GetGLfunc(glRenderbufferStorage);
GetGLfunc(glFramebufferRenderbuffer);
// multisample support, this should be in core per gl 3.0 and newer
pglRenderbufferStorageMultisample = GetGLFunc("glRenderbufferStorageMultisample");
pglBlitFramebuffer = GetGLFunc("glBlitFramebuffer");
if (!pglRenderbufferStorageMultisample || !pglBlitFramebuffer)
{
pglRenderbufferStorageMultisample = NULL;
pglBlitFramebuffer = NULL;
GL_DBG_Printf("\nFBO: No multisample support\n");
}
GL_DBG_Printf("\nFBO: ARB extensions found\n");
}
else if (fbocheck == FBO_EXT) // uh oh only support old fbo extensions...
else if (fbocheck == FBO_EXT || fbocheck == FBO_EXT_STENCIL) // uh oh only support for EXT prefix fbos...
{
GetGLfunc(glGenFramebuffersEXT);
GetGLfunc(glBindFramebufferEXT);
GetGLfunc(glDeleteFramebuffersEXT);
GetGLfunc(glFramebufferTexture2DEXT);
GetGLfunc(glCheckFramebufferStatusEXT);
GetGLfunc(glGenRenderbuffersEXT);
GetGLfunc(glBindRenderbufferEXT);
GetGLfunc(glDeleteRenderbuffersEXT);
GetGLfunc(glRenderbufferStorageEXT);
GetGLfunc(glFramebufferRenderbufferEXT);
// remapping galore huehue
// do this so we dont have to dupe half our code
GetGLfunc(glGenFramebuffersEXT);
pglGenFramebuffers = pglGenFramebuffersEXT;
GetGLfunc(glBindFramebufferEXT);
pglBindFramebuffer = pglBindFramebufferEXT;
GetGLfunc(glDeleteFramebuffersEXT);
pglDeleteFramebuffers = pglDeleteFramebuffersEXT;
GetGLfunc(glFramebufferTexture2DEXT);
pglFramebufferTexture2D = pglFramebufferTexture2DEXT;
GetGLfunc(glCheckFramebufferStatusEXT);
pglCheckFramebufferStatus = pglCheckFramebufferStatusEXT;
GetGLfunc(glGenRenderbuffersEXT);
pglGenRenderbuffers = pglGenRenderbuffersEXT;
GetGLfunc(glBindRenderbufferEXT);
pglBindRenderbuffer = pglBindRenderbufferEXT;
GetGLfunc(glDeleteRenderbuffersEXT);
pglDeleteRenderbuffers = pglDeleteRenderbuffersEXT;
GetGLfunc(glRenderbufferStorageEXT);
pglRenderbufferStorage = pglRenderbufferStorageEXT;
GetGLfunc(glFramebufferRenderbufferEXT);
pglFramebufferRenderbuffer = pglFramebufferRenderbufferEXT;
// multisample support needs the EXT multisample and blit extensions
if (GL_isExtAvailable("GL_EXT_framebuffer_multisample", gl_extensions) &&
GL_isExtAvailable("GL_EXT_framebuffer_blit", gl_extensions))
{
pglRenderbufferStorageMultisample = GetGLFunc("glRenderbufferStorageMultisampleEXT");
pglBlitFramebuffer = GetGLFunc("glBlitFramebufferEXT");
}
if (!pglRenderbufferStorageMultisample || !pglBlitFramebuffer)
{
pglRenderbufferStorageMultisample = NULL;
pglBlitFramebuffer = NULL;
GL_DBG_Printf("\nFBO: No multisample support\n");
}
GL_DBG_Printf("\nFBO: EXT extensions with packed depth-stencil\n");
if (fbocheck == FBO_EXT)
GL_DBG_Printf("\nFBO: EXT extensions found, no stencil\n");
else if (fbocheck == FBO_EXT_STENCIL)
GL_DBG_Printf("\nFBO: EXT extensions with packed depth-stencil\n");
}
supportFBO = fbocheck;
@@ -1209,7 +1151,7 @@ void GL_SetModelView(GLint w, GLint h)
GL_FlushScreenTextures();
#ifdef USE_FBO_OGL
GL_FBO_DeleteAttachments();
GL_Framebuffer_DeleteAttachments();
#endif
}
@@ -1515,15 +1457,6 @@ void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale)
const INT32 stride = (screen_width/scale)*3;
INT32 scanlines = screen_height;
GLubyte * restrict image;
#ifdef USE_FBO_OGL
const boolean msaa_fbo = (framebufferobject.bound && framebufferobject.msaa);
#endif
#ifdef USE_FBO_OGL
// cant read from the msaa fbo, so gotta blit it first into either the single sample fbo or the screen framebuffer....
if (msaa_fbo)
GL_FBO_Resolve(GL_COLOR_BUFFER_BIT);
#endif
// at the time this function is called, generic2 can be found drawn on the framebuffer
// if some other screen texture is needed, draw it to the framebuffer
@@ -1565,16 +1498,9 @@ void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale)
memcpy(dest + i, image + i*scale, 3);
dest += stride;
}
// this probably could be done with fbos, might mess around with that some time :3
// ...yet still, restrict doesn't make the inner loop any faster
free(image - ((screen_height % scale) * screen_width*3));
#ifdef USE_FBO_OGL
// this´ll reenable the msaa fbo....
if (msaa_fbo)
GL_FBO_Enable();
#endif
}
// -----------------+
@@ -2328,7 +2254,7 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
UNIFORM_2(shader->uniforms[gluniform_scr_resolution], (GLfloat)screen_width, (GLfloat)screen_height, pglUniform2f);
UNIFORM_2(shader->uniforms[gluniform_scr_resolution], (GLfloat)vid.width, (GLfloat)vid.height, pglUniform2f);
#undef UNIFORM_1
#undef UNIFORM_2
@@ -2715,7 +2641,11 @@ void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value)
case HWD_SET_MSAA:
if (Value)
{
pglEnable(GL_MULTISAMPLE);
if (Value == 2)
pglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
break;
case HWD_SET_TEXTUREANISOTROPICMODE:
@@ -3316,9 +3246,9 @@ void GL_SetTransform(FTransform *stransform)
}
#ifdef USE_FBO_OGL
static void GL_FBO_DeleteAttachments(void)
static void GL_Framebuffer_DeleteAttachments(void)
{
if (supportFBO == FBO_NONE)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
// Unbind the framebuffer
@@ -3331,45 +3261,14 @@ static void GL_FBO_DeleteAttachments(void)
if (framebufferobject.rboobj)
pglDeleteRenderbuffers(1, &framebufferobject.rboobj);
if (framebufferobject.msaa_rboobj)
pglDeleteRenderbuffers(1, &framebufferobject.msaa_rboobj);
if (framebufferobject.msaa_depthrboobj)
pglDeleteRenderbuffers(1, &framebufferobject.msaa_depthrboobj);
framebufferobject.tex = 0;
framebufferobject.rboobj = 0;
framebufferobject.msaa_rboobj = 0;
framebufferobject.msaa_depthrboobj = 0;
framebufferobject.init = false;
framebufferobject.bound = false;
}
// blit the msaa fbo into the normal single sample fbo
// so we can use it to copy from and stuff
static void GL_FBO_Resolve(GLbitfield mask)
static void GL_Framebuffer_Generate(void)
{
if (supportFBO == FBO_NONE || !framebufferobject.init || !framebufferobject.msaa)
return;
if (!pglBlitFramebuffer)
return;
pglBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, framebufferobject.msaa_fboobj);
pglBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, framebufferobject.fboobj);
pglBlitFramebuffer(0, 0, screen_width, screen_height,
0, 0, screen_width, screen_height,
mask, GL_NEAREST);
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.fboobj);
}
static void GL_FBO_Generate(void)
{
GLint msaasamples;
if (supportFBO == FBO_NONE || framebufferobject.init)
if (supportFBO == FBO_NONE || framebufferobject.init || !UseScreenFBO())
return;
// Generate the framebuffer
@@ -3384,7 +3283,7 @@ static void GL_FBO_Generate(void)
{
pglGenTextures(1, &framebufferobject.tex);
pglBindTexture(GL_TEXTURE_2D, framebufferobject.tex);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
@@ -3407,13 +3306,18 @@ static void GL_FBO_Generate(void)
pglRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, screen_width, screen_height);
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
}
else if (supportFBO == FBO_EXT)
else if (supportFBO == FBO_EXT || supportFBO == FBO_EXT_STENCIL)
{
pglRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, screen_width, screen_height);
// attach the renderbuffer to depth attachment point
pglRenderbufferStorage(GL_RENDERBUFFER_EXT, (supportFBO == FBO_EXT_STENCIL) ? GL_DEPTH_STENCIL_EXT : GL_DEPTH_COMPONENT, screen_width, screen_height);
// attach a renderbuffer to depth attachment point
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
// attach the renderbuffer to stencil attachment point
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
if (supportFBO == FBO_EXT_STENCIL)
{
// attach a renderbuffer to stencil attachment point
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
}
}
// Clear the renderbuffer
@@ -3425,124 +3329,48 @@ static void GL_FBO_Generate(void)
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
//pglGetError(); TODO:implement this or smth
GL_MSG_Error("GL_FBO_Generate: Failed to create Framebuffer Object");
GL_MSG_Error("GL_Framebuffer_Generate: Failed to create Framebuffer Object");
// if this fails, dont retry it a gazillion times
// this probably wouldnt recover and we dont want any more black screens...
// this wouldnt recover
supportFBO = FBO_NONE;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
return;
}
// Try to set up a multisampled render target for MSAA
framebufferobject.msaa = false;
msaasamples = (GLint)msaa;
// maybe should just make more "supportFBO" cases or smth but :chaosleep:
if (msaasamples > 1 && pglRenderbufferStorageMultisample && pglBlitFramebuffer)
{
if (!framebufferobject.msaa_fboobj)
pglGenFramebuffers(1, &framebufferobject.msaa_fboobj);
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.msaa_fboobj);
// Generate the multisampled color renderbuffer
if (!framebufferobject.msaa_rboobj)
{
pglGenRenderbuffers(1, &framebufferobject.msaa_rboobj);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, framebufferobject.msaa_rboobj);
pglRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT, msaasamples, GL_RGBA8, screen_width, screen_height);
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, framebufferobject.msaa_rboobj);
}
// Generate the multisampled depth/stencil renderbuffer
if (!framebufferobject.msaa_depthrboobj)
{
pglGenRenderbuffers(1, &framebufferobject.msaa_depthrboobj);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, framebufferobject.msaa_depthrboobj);
if (supportFBO == FBO_ARB)
{
pglRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT, msaasamples, GL_DEPTH24_STENCIL8, screen_width, screen_height);
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, framebufferobject.msaa_depthrboobj);
}
else if (supportFBO == FBO_EXT)
{
pglRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT, msaasamples, GL_DEPTH_STENCIL_EXT, screen_width, screen_height);
// attach a renderbuffer to depth attachment point
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, framebufferobject.msaa_depthrboobj);
// attach a renderbuffer to stencil attachment point
pglFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, framebufferobject.msaa_depthrboobj);
}
}
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT)
{
framebufferobject.msaa = true;
GL_ClearBuffer(true, true, true, NULL);
GL_DBG_Printf("\nGL_FBO_Generate: Multisampled framebuffer created with %d samples\n", msaasamples);
}
else
{
GL_MSG_Warning("GL_FBO_Generate: Failed to create multisampled Framebuffer Object, falling back to no MSAA");
if (framebufferobject.msaa_rboobj)
pglDeleteRenderbuffers(1, &framebufferobject.msaa_rboobj);
if (framebufferobject.msaa_depthrboobj)
pglDeleteRenderbuffers(1, &framebufferobject.msaa_depthrboobj);
framebufferobject.msaa_rboobj = 0;
framebufferobject.msaa_depthrboobj = 0;
}
}
// Unbind the framebuffer
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
framebufferobject.init = true;
}
void GL_FBO_BindMainFrameBuffer(void)
void GL_Framebuffer_Unbind(void)
{
if (supportFBO == FBO_NONE)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
framebufferobject.bound = false;
}
void GL_FBO_Enable(void)
void GL_Framebuffer_Enable(void)
{
if (supportFBO == FBO_NONE)
if (supportFBO == FBO_NONE || !UseScreenFBO())
return;
GL_FBO_Generate();
GL_Framebuffer_Generate();
// failed
if (!framebufferobject.init)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
if (framebufferobject.msaa)
{
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.msaa_fboobj);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, framebufferobject.msaa_rboobj);
}
else
{
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.fboobj);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
}
framebufferobject.bound = true;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.fboobj);
pglBindRenderbuffer(GL_RENDERBUFFER_EXT, framebufferobject.rboobj);
}
void GL_FBO_Disable(void)
void GL_Framebuffer_Disable(void)
{
if (supportFBO == FBO_NONE)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
@@ -3553,14 +3381,7 @@ void GL_FBO_Disable(void)
pglDeleteFramebuffers(1, &framebufferobject.fboobj);
framebufferobject.fboobj = 0;
if (framebufferobject.msaa_fboobj)
pglDeleteFramebuffers(1, &framebufferobject.msaa_fboobj);
framebufferobject.msaa_fboobj = 0;
GL_FBO_DeleteAttachments();
framebufferobject.msaa = false;
framebufferobject.bound = false;
GL_Framebuffer_DeleteAttachments();
}
#endif
@@ -3911,20 +3732,10 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8
void GL_MakeScreenTexture(int tex)
{
boolean firstTime;
static GLint lastfiltermode[NUMSCREENTEXTURES] = {-1, -1, -1, -1, -1};
#ifdef USE_FBO_OGL
const boolean msaa_fbo = (framebufferobject.bound && framebufferobject.msaa);
#endif
if (!gl_enable_screen_textures)
return;
#ifdef USE_FBO_OGL
// cant read from the msaa fbo, so gotta blit it first into either the single sample fbo or the screen framebuffer....
if (msaa_fbo)
GL_FBO_Resolve(GL_COLOR_BUFFER_BIT);
#endif
firstTime = (screenTextures[tex] == 0);
// Create screen texture
@@ -3933,36 +3744,18 @@ void GL_MakeScreenTexture(int tex)
pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
// if were downsampling, choose to do that with linear filter instead of nearest neighbor
// otherwise well get ugly mixels
GLint filtermode = I_IsDownsampling() ? GL_LINEAR : GL_NEAREST;
// avoid redundant calls to this, prob doesent really matter tbh
if (filtermode != lastfiltermode[tex] || firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtermode);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtermode);
lastfiltermode[tex] = filtermode;
}
if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, screen_texsizew, screen_texsizeh, 0);
}
else
{
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_texsizew, screen_texsizeh);
}
tex_downloaded = screenTextures[tex];
#ifdef USE_FBO_OGL
if (msaa_fbo)
GL_FBO_Enable();
#endif
}
void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height)
+3 -3
View File
@@ -98,9 +98,9 @@ extern PFNglGetString pglGetString;
#endif
#ifdef USE_FBO_OGL
void GL_FBO_BindMainFrameBuffer(void);
void GL_FBO_Enable(void);
void GL_FBO_Disable(void);
void GL_Framebuffer_Unbind(void);
void GL_Framebuffer_Enable(void);
void GL_Framebuffer_Disable(void);
extern int supportFBO;
#endif
+1 -4
View File
@@ -2654,12 +2654,9 @@ static inline void HU_DrawSpectatorTicker(void)
if (player->mo && player->mo->color)
{
const UINT8 *colormap = NULL;
const UINT8 *colormap = R_GetTranslationColormap(player->skin, player->mo->color, GTC_CACHE);
if (player->mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, player->mo->color, GTC_CACHE);
else
colormap = R_GetTranslationColormap(player->skin, player->mo->color, GTC_CACHE);
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceWant(player), colormap);
+7 -2
View File
@@ -118,14 +118,19 @@ void I_UpdateNoVsync(void);
*/
void I_ReadScreen(UINT8 * restrict scr, INT32 scale);
UINT32 I_GetRefreshRate(void);
boolean I_CheckNativeRes(void);
void I_SetBorderlessWindow(void);
#ifdef USE_FBO_OGL
void I_CheckDownSampleState(boolean forcerefresh);
boolean I_IsDownsampling(void);
void RefreshOGLSDLSurface(void);
void I_DownSample(void);
boolean UseScreenFBO(void);
extern boolean downsample;
#endif
// So we can call this from i_video event loop
+10 -8
View File
@@ -1221,8 +1221,10 @@ boolean K_UseHighResPortraits(void)
// accounts for localskins
patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum)
{
const skin_t *skin = R_GetSkinArray(player->skinlocal)[skinnum];
return (K_UseHighResPortraits() ? skin->facewantprefix : skin->facerankprefix);
if (!player->skinlocal)
return (K_UseHighResPortraits() ? facewantprefix[skinnum] : facerankprefix[skinnum]);
else
return (K_UseHighResPortraits() ? localfacewantprefix[skinnum] : localfacerankprefix[skinnum]);
}
INT32 K_calcSplitFlags(INT32 snapflags)
@@ -1424,7 +1426,7 @@ static void K_drawKartStats(void)
flags |= V_HUDTRANS;
flags2 = flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor);
fakeskin = R_GetPlayerSkin(stplyr);
fakeskin = K_GetPlayerSkin(stplyr);
// Skin name
if (cv_showstats_skinname.value)
@@ -3107,7 +3109,7 @@ static void K_drawNameTags(void)
cm = R_GetTranslationColormap(players[i].skin, players[i].mo->color, GTC_CACHE);
tagcolor = colortranslations[players[i].mo->color][7];
vflags = trans | V_NOSCALESTART;
usenametagrestat = ((cv_nametagrestat.value == 1 && (players[i].kartspeed != skins[players[i].skin]->kartspeed || players[i].kartweight != skins[players[i].skin]->kartweight)) || cv_nametagrestat.value == 2);
usenametagrestat = ((cv_nametagrestat.value == 1 && (players[i].kartspeed != skins[players[i].skin].kartspeed || players[i].kartweight != skins[players[i].skin].kartweight)) || cv_nametagrestat.value == 2);
tagwidthsmall = cv_smallnametags.value ? V_SmallStringWidth(player_names[i], V_ALLOWLOWERCASE) : V_ThinStringWidth(player_names[i], V_ALLOWLOWERCASE);
tagwidth = vid.dup*tagwidthsmall;
@@ -3592,12 +3594,12 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
INT32 rot = 0;
#endif
skin = R_GetMobjSkin(mo);
skin = K_GetMobjSkin(mo);
if (!skin)
return;
minimaphead = skin->facemmapprefix;
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
if (minimaphead == NULL)
return;
@@ -3828,7 +3830,7 @@ static void K_drawKartMinimap(void)
else
{
// special case if startcolor is not the default (160 / Green)
if (R_GetMobjSkin(mobj)->starttranscolor != skins[0]->starttranscolor)
if (K_GetMobjSkin(mobj)->starttranscolor != skins[0].starttranscolor)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
@@ -4903,7 +4905,7 @@ void K_drawKartHUD(void)
for (c = 1; c < MAXSKINCOLORS; c++)
{
UINT8 *cm = R_GetTranslationColormap(TC_RAINBOW, c, GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT>>1, 0, skins[stplyr->skin]->facewantprefix, cm);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT>>1, 0, facewantprefix[stplyr->skin], cm);
x += 16;
if (x > BASEVIDWIDTH-16)
-2
View File
@@ -78,8 +78,6 @@ INT32 K_getMinimapTrans(void);
void K_getLapsDrawinfo(drawinfo_t *out);
void K_getMinimapDrawinfo(drawinfo_t *out);
patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum);
#ifdef __cplusplus
} // extern "C"
#endif
+94 -136
View File
@@ -592,7 +592,7 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, bo
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
starttranscolor = (skinnum != TC_DEFAULT) ? R_GetSkinArray(local)[skinnum]->starttranscolor : DEFAULT_STARTTRANSCOLOR;
starttranscolor = (skinnum != TC_DEFAULT) ? K_GetSkinArray(local)[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d.", starttranscolor);
@@ -632,6 +632,60 @@ UINT8 K_GetKartColorByName(const char *name)
return 0;
}
//
// returns the players skinnumber
// accounts for localskins
//
INT32 K_GetSkinNum(player_t *player)
{
return player->localskin ? (player->localskin - 1) : player->skin;
}
//
// returns the mobj skinnumber
// accounts for localskins ?
//
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local)
{
return skin - K_GetSkinArray(local);
}
//
// returns the mobj skinnumber
// accounts for localskins
//
INT32 K_GetMobjLocalSkinNum(const skin_t *skin, const skin_t *localskin, boolean local)
{
return localskin ? (localskin - K_GetSkinArray(local)) : (skin - skins);
}
//
// returns the players skinnumber
// accounts for localskins
//
skin_t *K_GetMobjSkin(const mobj_t *mobj)
{
return mobj->localskin ? mobj->localskin : mobj->skin;
}
//
// returns the skin array to use
// accounts for localskins
//
skin_t *K_GetSkinArray(boolean local)
{
return local ? localskins : skins;
}
//
// returns the players skin
// accounts for localskins
//
skin_t *K_GetPlayerSkin(player_t *player)
{
return &K_GetSkinArray(player->skinlocal)[K_GetSkinNum(player)];
}
//}
//{ SRB2kart Net Variables
@@ -1755,56 +1809,25 @@ void K_RespawnChecker(player_t *player)
mobj_t *mo;
angle_t newangle;
fixed_t newx, newy, newz;
#ifdef PHOBOS_BUILD
const fixed_t fscale = player->mo->scale;
#else
static const fixed_t fscale = FRACUNIT; // does NOT use scale, since this effect doesn't scale properly
#endif
newangle = FixedAngle(((360/8)*i)*FRACUNIT);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * fscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * fscale);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31<<FRACBITS); // does NOT use scale, since this effect doesn't scale properly
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31<<FRACBITS);
if (player->mo->eflags & MFE_VERTICALFLIP)
newz = player->mo->z + player->mo->height;
else
newz = player->mo->z;
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (!P_MobjWasRemovedCompat(mo))
if (mo)
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8 * fscale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = fscale));
mo->momz = (8<<FRACBITS) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = FRACUNIT));
}
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal lazers!
mo->flags2 |= MF2_DONTDRAW;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
// now spawn our local lazers
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (!P_MobjWasRemovedCompat(mo))
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = player->mo->scale));
mo->islocal = true; // Keep this local!
}
}
#endif
}
}
}
@@ -1935,7 +1958,7 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf
// I HATE LOCALSKINS! I HATE LOCALSKINS! :AAAAAAAAAA:
if (source->player)
{
skin = R_GetPlayerSkin(source->player);
skin = K_GetPlayerSkin(source->player);
}
if (!skin)
@@ -3182,8 +3205,10 @@ static void K_SpawnDriftSparks(player_t *player)
for (i = 0; i < 2; i++)
{
const angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
const fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
fixed_t driftExtraScale = 0;
angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
newx = player->mo->x + P_ReturnThrustX(player->mo, thrustangle, smolscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, thrustangle, smolscale);
@@ -3195,9 +3220,9 @@ static void K_SpawnDriftSparks(player_t *player)
spark->angle = travelangle-(ANGLE_45/5)*player->kartstuff[k_drift];
// scale increase while driftspark level gained timer is running
const fixed_t driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
spark->destscale = FixedMul(player->mo->scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value));
P_SetScale(spark, spark->destscale);
P_SetScale(spark, spark->destscale); // why not use what we calculated above?
spark->momx = player->mo->momx/2;
spark->momy = player->mo->momy/2;
@@ -3289,10 +3314,10 @@ static void K_StretchPlayerGravity(player_t *player)
mobj_t *pmo = player->mo;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
stretchScaleFactor = FixedDiv(mapobjectscale*60, cv_gravstretch.value);
stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value);
stretchScaleFactor = min(stretchScaleFactor, MAXSTRETCHDIV);
if (pmo->slamsoundtimer)
@@ -3300,26 +3325,26 @@ static void K_StretchPlayerGravity(player_t *player)
if (!P_IsObjectOnGround(pmo))
{
const fixed_t pzmom = abs(pmo->momz);
fixed_t pzmom = abs(pmo->momz);
const fixed_t stretchDiv = FixedDiv(pzmom, stretchScaleFactor);
if (abs(pzmom/mapobjectscale) != 0)
if (abs(pzmom/FRACUNIT) != 0)
{
if ((tempxscale - stretchDiv) > (tempxscale / 5))
if (((tempxscale-(stretchDiv))) > (tempxscale/5))
{
pmo->spritexscale = (tempxscale - stretchDiv);
pmo->stretchslam = pzmom;
}
else
pmo->spritexscale = (tempxscale / 5);
pmo->spritexscale = (tempxscale/5);
pmo->spriteyscale = (tempyscale + ((stretchDiv * 2) / 3));
pmo->spriteyscale = (tempyscale + ((stretchDiv*2)/3));
}
}
else if (pmo->stretchslam > 0)
{
// Funni slam sound when landing
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*mapobjectscale))
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*FRACUNIT))
{
S_StartSound(pmo, sfx_s3k4c);
pmo->slamsoundtimer = TICRATE;
@@ -3327,9 +3352,9 @@ static void K_StretchPlayerGravity(player_t *player)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, stretchScaleFactor);
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3 ) * 2));
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*mapobjectscale);
pmo->stretchslam -= (4*FRACUNIT);
}
else
pmo->stretchslam = 0;
@@ -3344,16 +3369,16 @@ static void K_SaltySquish(player_t *player)
mobj_t *pmo = player->mo;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
if (pmo->stretchslam > 0)
{
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, mapobjectscale*60); // stretchScaleFactor = FixedDiv(mapobjectscale*60, FRACUNIT)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, FRACUNIT*60); // stretchScaleFactor = FixedDiv(FRACUNIT*60, FRACUNIT)
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3) * 2));
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*mapobjectscale);
pmo->stretchslam -= (4*FRACUNIT);
}
else
pmo->stretchslam = 0;
@@ -3422,7 +3447,7 @@ static void K_QuiteSaltyHop(player_t *player)
psalty->momz = 0;
// shlamma damma
if (cv_saltysquish.value)
pmo->stretchslam += 8*mapobjectscale;
pmo->stretchslam += 8*FRACUNIT;
}
else if (psalty->zoffset > 0)
{
@@ -3685,7 +3710,7 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
dust = P_SpawnMobj(rand_x, rand_y, mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo);
dust->angle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
@@ -3711,11 +3736,6 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
void K_DriftDustHandling(mobj_t *spawner)
{
angle_t anglediff;
#ifdef PHOBOS_BUILD
const fixed_t fscale = spawner->scale;
#else
static const fixed_t fscale = FRACUNIT; // should be spawner->scale but the below calls P_Random!
#endif
if (leveltime % 2 != 0 || !P_IsObjectOnGround(spawner))
return;
@@ -3732,7 +3752,7 @@ void K_DriftDustHandling(mobj_t *spawner)
{
angle_t playerangle = spawner->angle;
if (spawner->player->speed < (5 * fscale))
if (spawner->player->speed < 5<<FRACBITS)
return;
if (spawner->player->cmd.forwardmove < 0)
@@ -3743,7 +3763,7 @@ void K_DriftDustHandling(mobj_t *spawner)
}
else
{
if (P_AproxDistance(spawner->momx, spawner->momy) < (5 * fscale))
if (P_AproxDistance(spawner->momx, spawner->momy) < 5<<FRACBITS)
return;
anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
@@ -3756,29 +3776,13 @@ void K_DriftDustHandling(mobj_t *spawner)
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
{
mobj_t *dust = NULL;
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
INT32 speedrange = 2;
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
const INT32 momxrand = P_RandomRange(-speedrange, speedrange);
const INT32 momyrand = P_RandomRange(-speedrange, speedrange);
const INT32 momzrand = P_RandomRange(1, 4);
if (P_MobjWasRemovedCompat(dust))
return;
#ifdef PHOBOS_BUILD
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
#else
dust->momx = FixedMul(spawner->momx + (momxrand<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (momyrand<<FRACBITS), 3*(spawner->scale)/4);
#endif
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
@@ -3787,33 +3791,6 @@ void K_DriftDustHandling(mobj_t *spawner)
S_StartSound(spawner, sfx_screec);
K_MatchGenericExtraFlags(dust, spawner);
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal dust!
dust->flags2 |= MF2_DONTDRAW;
// now spawn our dust locally
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
if (P_MobjWasRemovedCompat(dust))
return;
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
dust->islocal = true; // Keep this local!
K_MatchGenericExtraFlags(dust, spawner);
}
#endif
}
}
@@ -4408,7 +4385,8 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
mobj_t *cachenext;
killnext:
if (P_MobjWasRemovedCompat(banana))
if (!banana)
return;
cachenext = banana->hnext;
@@ -4447,21 +4425,10 @@ void K_UpdateHnextList(player_t *player, boolean clean)
nextwork = work->hnext;
if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount]))
{
continue;
}
P_RemoveMobj(work);
}
#ifdef PHOBOS_BUILD
if (P_MobjWasRemoved(player->mo->hnext))
{
// Like below, try to clean up the pointer if it's NULL.
// Maybe this was a cause of the shrink/eggbox fails?
P_SetTarget(&player->mo->hnext, NULL);
}
#endif
}
// For getting hit!
@@ -4526,9 +4493,7 @@ void K_DropHnextList(player_t *player)
}
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
P_SetTarget(&dropwork->target, player->mo);
dropwork->angle = work->angle;
dropwork->flags2 = work->flags2;
dropwork->flags |= MF_NOCLIPTHING;
@@ -4596,13 +4561,10 @@ void K_DropHnextList(player_t *player)
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
P_SetTarget(&player->mo->hnext, NULL);
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld]
&& (dropall || (--player->kartstuff[k_itemamount] <= 0)))
{
@@ -4903,9 +4865,7 @@ static void K_MoveHeldObjects(player_t *player)
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld])
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
@@ -4922,9 +4882,7 @@ static void K_MoveHeldObjects(player_t *player)
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld])
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
+1 -3
View File
@@ -1766,8 +1766,6 @@ static int lib_rSetPlayerSkin(lua_State *L)
INT32 i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSKINS)
return luaL_error(L, "skin number (argument #2) %d out of range (0 - %d)", i, MAXSKINS-1);
if (i >= numskins)
return 0;
SetPlayerSkinByNum(player-players, i);
}
else // skin name
@@ -2633,7 +2631,7 @@ static int lib_kLossSound(lua_State *L)
if (!mobj->player)
return luaL_error(L, "K_PlayLossSound: mobj_t isn't a player object.");
sfx_id = R_GetMobjSkin(mobj)->soundsid[S_sfx[sfx_klose].skinsound];
sfx_id = ((skin_t *)mobj->skin)->soundsid[S_sfx[sfx_klose].skinsound];
S_StartSound(mobj, sfx_id);
return 0;
}
+1 -6
View File
@@ -182,19 +182,14 @@ void COM_Lua_f(void)
len = (argc+1)*256;
buf = malloc(len);
if (buf == NULL)
I_Error("Failed to allocate buffer for COM_Lua_f");
p = buf;
WRITEUINT8(p, argc);
for (i = 0; i < argc; i++)
WRITESTRINGN(p, COM_Argv(i), 255);
if (flags & COM_SPLITSCREEN)
if (flags & 2)
SendNetXCmdForPlayer(1, XD_LUACMD, buf, p-buf);
else
SendNetXCmd(XD_LUACMD, buf, p-buf);
free(buf);
return;
}
+1 -1
View File
@@ -962,7 +962,7 @@ static void res_botai(Hook_State *hook)
int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
{
const char *skin = tails->skin->name;
const char *skin = ((skin_t *)tails->skin)->name;
Hook_State hook = {};
BotAI_State botai = {};
-2
View File
@@ -53,6 +53,4 @@ boolean LUA_HudEnabled(enum hud option);
void LUA_SetHudHook(int hook, huddrawlist_h list);
#define LOCALSKINIMMERSION (hud_running && cv_luaimmersion.value)
#endif // __LUA_HUD_H__
+3 -5
View File
@@ -487,7 +487,7 @@ static int libd_getSpritePatch(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
for (skn = 0; skn < numskins; skn++)
if (fastcmp(skins[skn]->name, name))
if (fastcmp(skins[skn].name, name))
break;
if (skn >= numskins)
return 0;
@@ -527,9 +527,9 @@ static int libd_getSpritePatch(lua_State *L)
}
else // player skin
{
sprdef = &skins[skn]->spritedef;
sprdef = &skins[skn].spritedef;
#ifdef ROTSPRITE
sprinfo = &skins[skn]->sprinfo;
sprinfo = &skins[skn].sprinfo;
#endif
}
@@ -1056,8 +1056,6 @@ static int libd_getColormap(lua_State *L)
skinnum = (INT32)luaL_checkinteger(L, 1);
if (skinnum < TC_BLINK || skinnum >= MAXSKINS)
return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1);
if (skinnum >= numskins)
return 0;
}
else // skin name
{
+10
View File
@@ -18,6 +18,7 @@
#include "p_slopes.h"
#include "r_main.h"
#include "lua_udatalib.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
@@ -255,6 +256,15 @@ static const char *const vector_opt[] = {
static const char *const array_opt[] ={"iterate",NULL};
static const char *const valid_opt[] ={"valid",NULL};
#define pushsubsector(L, subsector) LUA_PushUserdata(L, subsector, META_SUBSECTOR)
int udatalib_getter_subsector(lua_State *L)
UDATALIB_SIMPLE_GETTER(subsector_t*, pushsubsector)
#undef pushsubsector
#define pushslope(L, slope) LUA_PushUserdata(L, slope, META_SLOPE)
int udatalib_getter_slope(lua_State *L)
UDATALIB_SIMPLE_GETTER(pslope_t*, pushslope)
#undef pushslope
// iterates through a sector's thinglist!
static int lib_iterateSectorThinglist(lua_State *L)
{
+743 -777
View File
File diff suppressed because it is too large. Load diff
+422 -847
View File
File diff suppressed because it is too large. Load diff
+10 -15
View File
@@ -62,6 +62,14 @@ static lua_CFunction liblist[] = {
NULL
};
// Lua asks for memory using this.
static void *LUA_Alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
(void)ud;
(void)osize;
return Z_Realloc(ptr, nsize, PU_LUA, NULL);
}
// Panic function Lua calls when there's an unprotected error.
// This function cannot return. Lua would kill the application anyway if it did.
FUNCNORETURN static int LUA_Panic(lua_State *L)
@@ -189,7 +197,7 @@ void LUA_ClearState(void)
CONS_Printf(M_GetText("Pardon me while I initialize the Lua scripting interface...\n"));
// allocate state
L = luaL_newstate();
L = lua_newstate(LUA_Alloc, NULL);
lua_atpanic(L, LUA_Panic);
// open base libraries
@@ -365,7 +373,7 @@ void LUA_DumpFile(const char *filename)
static void createMathLibState(void)
{
mL = luaL_newstate();
mL = lua_newstate(LUA_Alloc, NULL);
lua_atpanic(mL, LUA_Panic);
// open only enum lib
@@ -1457,16 +1465,3 @@ int Lua_CreateFieldTable(lua_State *L, const char *const lst[])
return luaL_ref(L, LUA_REGISTRYINDEX);
}
size_t LUA_MemoryUsage(void)
{
size_t usage = 0;
if (gL)
usage += lua_gc(gL, LUA_GCCOUNT, 0);
if (mL)
usage += lua_gc(mL, LUA_GCCOUNT, 0);
return usage;
}
-3
View File
@@ -82,9 +82,6 @@ int Lua_optoption(lua_State *L, int narg, int def, int list_ref);
int Lua_CreateFieldTable(lua_State *L, const char *const lst[]);
void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save);
// Returns lua memory usage in kbytes
size_t LUA_MemoryUsage(void);
// Console wrapper
void COM_Lua_f(void);
+13 -30
View File
@@ -18,10 +18,6 @@
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#define SKINARR (LOCALSKINIMMERSION ? allskins : skins)
#define NSKINS (LOCALSKINIMMERSION ? numallskins : numskins)
enum skin {
skin_valid = 0,
@@ -154,15 +150,13 @@ static int skin_num(lua_State *L)
// skins are always valid, only added, never removed
I_Assert(skin != NULL);
lua_pushinteger(L, LOCALSKINIMMERSION ? skin->allskinnum : skin->skinnum);
lua_pushinteger(L, skin-skins);
return 1;
}
static int lib_iterateSkins(lua_State *L)
{
INT32 i;
skin_t **skinar = SKINARR;
const INT32 nskins = NSKINS;
if (lua_gettop(L) < 2)
{
@@ -175,17 +169,14 @@ static int lib_iterateSkins(lua_State *L)
lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1))
{
skin_t *skin = (*((skin_t **)luaL_checkudata(L, 1, META_SKIN)));
i = (INT32)(LOCALSKINIMMERSION ? skin->allskinnum : skin->skinnum) + 1;
}
i = (INT32)(*((skin_t **)luaL_checkudata(L, 1, META_SKIN)) - allskins) + 1;
else
i = 0;
// skins are always valid, only added, never removed
if (i < nskins)
if (i < numallskins)
{
LUA_PushUserdata(L, skinar[i], META_SKIN);
LUA_PushUserdata(L, &allskins[i], META_SKIN);
return 1;
}
@@ -197,40 +188,32 @@ static int lib_getSkin(lua_State *L)
const char *field;
INT32 i;
skin_t **skinar = SKINARR;
const INT32 nskins = NSKINS;
// find skin by number
if (lua_type(L, 2) == LUA_TNUMBER)
{
const INT32 skinmax = LOCALSKINIMMERSION ? numallskins : MAXSKINS;
i = luaL_checkinteger(L, 2);
if (i < 0 || i >= skinmax)
return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, skinmax-1);
if (i >= nskins)
if (i < 0 || i >= MAXSKINS)
return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, MAXSKINS-1);
if (i >= numallskins)
return 0;
LUA_PushUserdata(L, skinar[i], META_SKIN);
LUA_PushUserdata(L, &allskins[i], META_SKIN);
return 1;
}
field = luaL_checkstring(L, 2);
// special function iterate
if (fastcmp(field, "iterate"))
if (fastcmp(field,"iterate"))
{
lua_pushcfunction(L, lib_iterateSkins);
return 1;
}
// find skin by name
for (i = 0; i < nskins; i++)
if (fastcmp(skinar[i]->name, field))
for (i = 0; i < numallskins; i++)
if (fastcmp(allskins[i].name, field))
{
LUA_PushUserdata(L, skinar[i], META_SKIN);
LUA_PushUserdata(L, &allskins[i], META_SKIN);
return 1;
}
@@ -239,7 +222,7 @@ static int lib_getSkin(lua_State *L)
static int lib_numSkins(lua_State *L)
{
lua_pushinteger(L, NSKINS);
lua_pushinteger(L, numallskins);
return 1;
}
+137
View File
@@ -0,0 +1,137 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.c
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#include "doomtype.h"
#include "m_fixed.h"
#include "lua_udatalib.h"
// Getters
int udatalib_getter_fixed(lua_State *L)
UDATALIB_SIMPLE_GETTER(fixed_t, lua_pushinteger)
int udatalib_getter_angle(lua_State *L)
UDATALIB_SIMPLE_GETTER(angle_t, lua_pushangle)
int udatalib_getter_uint8(lua_State *L)
UDATALIB_SIMPLE_GETTER(UINT8, lua_pushinteger)
int udatalib_getter_sint8(lua_State *L)
UDATALIB_SIMPLE_GETTER(SINT8, lua_pushinteger)
int udatalib_getter_uint16(lua_State *L)
UDATALIB_SIMPLE_GETTER(UINT16, lua_pushinteger)
int udatalib_getter_int16(lua_State *L)
UDATALIB_SIMPLE_GETTER(INT16, lua_pushinteger)
int udatalib_getter_uint32(lua_State *L)
UDATALIB_SIMPLE_GETTER(UINT32, lua_pushinteger)
int udatalib_getter_int32(lua_State *L)
UDATALIB_SIMPLE_GETTER(INT32, lua_pushinteger)
int udatalib_getter_uint64(lua_State *L)
UDATALIB_SIMPLE_GETTER(UINT64, lua_pushinteger)
int udatalib_getter_int64(lua_State *L)
UDATALIB_SIMPLE_GETTER(INT64, lua_pushinteger)
int udatalib_getter_string(lua_State *L)
UDATALIB_SIMPLE_GETTER(const char*, lua_pushstring)
int udatalib_getter_boolean(lua_State *L)
UDATALIB_SIMPLE_GETTER(boolean, lua_pushboolean)
int udatalib_getter_spritenum(lua_State *L)
UDATALIB_SIMPLE_GETTER(spritenum_t, lua_pushinteger)
int udatalib_getter_tic(lua_State *L)
UDATALIB_SIMPLE_GETTER(tic_t, lua_pushinteger)
// Setters
int udatalib_setter_fixed(lua_State *L)
UDATALIB_SIMPLE_SETTER(fixed_t, luaL_checkfixed)
int udatalib_setter_angle(lua_State *L)
UDATALIB_SIMPLE_SETTER(angle_t, luaL_checkangle)
int udatalib_setter_uint8(lua_State *L)
UDATALIB_SIMPLE_SETTER(UINT8, (UINT8)luaL_checkinteger)
int udatalib_setter_sint8(lua_State *L)
UDATALIB_SIMPLE_SETTER(SINT8, luaL_checkinteger)
int udatalib_setter_uint16(lua_State *L)
UDATALIB_SIMPLE_SETTER(UINT16, (UINT16)luaL_checkinteger)
int udatalib_setter_int16(lua_State *L)
UDATALIB_SIMPLE_SETTER(INT16, luaL_checkinteger)
int udatalib_setter_uint32(lua_State *L)
UDATALIB_SIMPLE_SETTER(UINT32, (UINT32)luaL_checkinteger)
int udatalib_setter_int32(lua_State *L)
UDATALIB_SIMPLE_SETTER(INT32, luaL_checkinteger)
int udatalib_setter_uint64(lua_State *L)
UDATALIB_SIMPLE_SETTER(UINT64, (UINT64)luaL_checkinteger)
int udatalib_setter_int64(lua_State *L)
UDATALIB_SIMPLE_SETTER(INT64, luaL_checkinteger)
int udatalib_setter_string(lua_State *L)
UDATALIB_SIMPLE_SETTER(const char*, luaL_checkstring)
int udatalib_setter_boolean(lua_State *L)
UDATALIB_SIMPLE_SETTER(boolean, luaL_checkboolean)
// ffs
int udatalib_setter_boolean_nocheck(lua_State *L)
UDATALIB_SIMPLE_SETTER(boolean, lua_toboolean)
int udatalib_setter_spritenum(lua_State *L)
UDATALIB_SIMPLE_SETTER(spritenum_t, luaL_checkinteger)
int udatalib_setter_tic(lua_State *L)
UDATALIB_SIMPLE_SETTER(tic_t, (tic_t)luaL_checkinteger)
void udatalib_addfield(lua_State *L, int mt, udata_field_t field)
{
int idx = abs_index(L, mt);
lua_createtable(L, 2, 0); // Push table
lua_pushinteger(L, field.offset); // Push offset
lua_pushcclosure(L, field.getter, 1); // Pop offset, push closure
lua_rawseti(L, -2, UDATALIB_GETTER); // Pop closure, add to table
lua_pushinteger(L, field.offset); // Push offset
lua_pushcclosure(L, field.setter, 1); // Pop offset, push closure
lua_rawseti(L, -2, UDATALIB_SETTER); // Pop closure, add to table
lua_pushstring(L, field.name); // Push field name
lua_pushvalue(L, -2); // Copy table
lua_rawset(L, idx); // Pop field name and table, add to metatable
lua_pop(L, 1); // Pop field table
}
void udatalib_addfields(lua_State *L, int mt, const udata_field_t fields[])
{
for (unsigned i = 0; fields[i].name != NULL; ++i)
{
udatalib_addfield(L, mt, fields[i]);
//CONS_Printf("Add field name=%s, offset=%d, getter=%p, setter=%p\n", fields[i].name, fields[i].offset, fields[i].getter, fields[i].setter);
}
}
+114
View File
@@ -0,0 +1,114 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.h
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#ifndef __LUA_UDATALIB_H__
#define __LUA_UDATALIB_H__
#include "doomdef.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "fastcmp.h"
// Indices in getter/setter tables for fields
#define UDATALIB_GETTER 1
#define UDATALIB_SETTER 2
typedef struct udata_field_s {
const char *name;
size_t offset;
lua_CFunction getter;
lua_CFunction setter;
} udata_field_t;
// Simple setters and getters, for situations where getter is simply
// "return obj.field" and setter is "obj.field = value"
int udatalib_getter_fixed(lua_State *L);
int udatalib_getter_angle(lua_State *L);
int udatalib_getter_uint8(lua_State *L);
int udatalib_getter_sint8(lua_State *L);
int udatalib_getter_uint16(lua_State *L);
int udatalib_getter_int16(lua_State *L);
int udatalib_getter_uint32(lua_State *L);
int udatalib_getter_int32(lua_State *L);
int udatalib_getter_uint64(lua_State *L);
int udatalib_getter_int64(lua_State *L);
int udatalib_getter_string(lua_State *L);
int udatalib_getter_boolean(lua_State *L);
int udatalib_getter_spritenum(lua_State *L);
int udatalib_getter_mobj(lua_State *L);
int udatalib_getter_subsector(lua_State *L);
int udatalib_getter_mobjtype(lua_State *L);
int udatalib_getter_player(lua_State *L);
int udatalib_getter_mapthing(lua_State *L);
int udatalib_getter_slope(lua_State *L);
int udatalib_getter_cmd(lua_State *L);
int udatalib_getter_playerstate(lua_State *L);
int udatalib_getter_powers(lua_State *L);
int udatalib_getter_kartstuff(lua_State *L);
int udatalib_getter_pflags(lua_State *L);
int udatalib_getter_panim(lua_State *L);
int udatalib_getter_tic(lua_State *L);
int udatalib_setter_fixed(lua_State *L);
int udatalib_setter_angle(lua_State *L);
int udatalib_setter_uint8(lua_State *L);
int udatalib_setter_sint8(lua_State *L);
int udatalib_setter_uint16(lua_State *L);
int udatalib_setter_int16(lua_State *L);
int udatalib_setter_uint32(lua_State *L);
int udatalib_setter_int32(lua_State *L);
int udatalib_setter_uint64(lua_State *L);
int udatalib_setter_int64(lua_State *L);
int udatalib_setter_string(lua_State *L);
int udatalib_setter_boolean(lua_State *L);
int udatalib_setter_boolean_nocheck(lua_State *L);
int udatalib_setter_spritenum(lua_State *L);
int udatalib_setter_mobj(lua_State *L);
int udatalib_setter_playerstate(lua_State *L);
int udatalib_setter_pflags(lua_State *L);
int udatalib_setter_panim(lua_State *L);
int udatalib_setter_tic(lua_State *L);
// Adds setter and getter for field and stores it as field.name..".get" and
// field.name..".set" in table at index mt. (metatable, usually)
void udatalib_addfield(lua_State *L, int mt, udata_field_t field);
// Convinience function to add array of fields at once.
void udatalib_addfields(lua_State *L, int mt, const udata_field_t fields[]);
// I miss C++ template functons :(
// Get pointer to field value within getter or setter
#define UDATALIB_GETFIELD(type, field) \
{ \
size_t offset = lua_tointeger(L, lua_upvalueindex(1)); \
field = (type*)((uint8_t*)lua_touserdata(L, 1) + offset); \
}
// Creates implementation for simple getter and setter. Super lazy, yes.
// Assumes userdata is a pointer to actual data. Maybe not really safe.
#define UDATALIB_SIMPLE_GETTER(type, pushf) \
{ \
type *field; \
UDATALIB_GETFIELD(type, field) \
pushf(L, *field); \
return 1; \
}
#define UDATALIB_SIMPLE_SETTER(type, checkf) \
{ \
type *field; \
UDATALIB_GETFIELD(type, field) \
*field = checkf(L, 2); \
return 0; \
}
#endif
+2 -11
View File
@@ -13,12 +13,6 @@
#include <string.h>
#ifdef HAVE_THREADS
#define local_for_thread _Thread_local
#else
#define local_for_thread
#endif
#include "doomdef.h"
#include "command.h"
#include "m_argv.h"
@@ -37,11 +31,8 @@ char **myargv = NULL;
boolean myargmalloc = false;
/** \brief founded the parm
*
* thread_local because it can potentially be used from multiple threads (global variables aaaaaa)
* (myargc and myargv don't have to be thread_local because they are never modified after being set up)
*/
static local_for_thread INT32 found;
static INT32 found;
/** \brief The M_CheckParm function
@@ -100,7 +91,7 @@ INT32 M_CheckProtoParam(const char *check)
const char *M_GetProtoParam(void)
{
INT32 i;
char *string;
static char *string;
for (i = 1; i < myargc; i++)
{
+1 -1
View File
@@ -100,7 +100,7 @@ static UINT8 cheatf_devmode(void)
if (menuactive && currentMenu != &MainDef)
return 0; // Only on the main menu!
S_StartSound(0, sfx_itemup);
S_StartSound(NULL, sfx_itemup);
// Just unlock all the things and turn on -debug and console devmode.
G_SetGameModified(false, false); // might need to revist the latter later
+82 -105
View File
@@ -809,7 +809,7 @@ static void M_ChangeCvar(INT32 choice)
{
INT32 skinno = R_SkinAvailable(cv_chooseskin.string);
if (skinno != -1)
CV_SetValue(cv,skins[skinno]->prefcolor);
CV_SetValue(cv,skins[skinno].prefcolor);
return;
}
@@ -2851,11 +2851,11 @@ static void M_PatchSkinNameTable(void)
memset(skins_cons_t, 0, sizeof (skins_cons_t));
for (j = 0; j < numskins; j++)
for (j = 0; j < MAXSKINS; j++)
{
if (skins[j]->name[0] != '\0')
if (skins[j].name[0] != '\0')
{
skins_cons_t[j].strvalue = skins[j]->name;
skins_cons_t[j].strvalue = skins[j].name;
skins_cons_t[j].value = j+1;
}
else
@@ -3984,14 +3984,6 @@ menudemo_t *demolist = NULL; // Replays that that have been checked to match wit
menudemo_t *demolist_all = NULL; // All replays
size_t demolist_all_size = 0;
boolean replaynamesloaded = false;
// Whenever we start a replay load thread, we increment this number and then thread will remember current value,
// and by the end it will compare it with current value, and if it is equal it means thread can store data it has loaded.
// If it's not equal, that means we started more than one thread (left and re-entered menu for example)
size_t replaythreadnum = 0;
// for replay dates
#include <locale.h>
const char *demodateformat = "%d.%m.%Y";
#ifdef HAVE_THREADS
I_mutex replayquerymutex;
@@ -4021,15 +4013,12 @@ static SINT8 replayScrollDelay = TICRATE, replayScrollDir = 1;
static void ReplayNamesLoadThread(void* userdata)
{
(void)userdata;
Lock_search_state();
size_t demolist_all_size_local = demolist_all_size;
menudemo_t *demolist_all_local = (menudemo_t*)malloc(sizeof(menudemo_t)*demolist_all_size_local);
memcpy(demolist_all_local, demolist_all, sizeof(menudemo_t)*demolist_all_size_local);
size_t localreplaythreadnum = replaythreadnum;
const char *localdemodateformat = demodateformat;
char *replaydirpath = (char*)userdata;
Unlock_search_state();
@@ -4037,13 +4026,19 @@ static void ReplayNamesLoadThread(void* userdata)
{
if (demolist_all_local[i].type != MD_SUBDIR)
{
G_LoadDemoTitle(&demolist_all_local[i], localdemodateformat);
G_LoadDemoTitle(&demolist_all_local[i]);
// this is fucking horrid, but i wanna be able to search for dates
/*if (demolist_all_local[i].date[0] != '\0')
{
snprintf(demolist_all_local[i].title, sizeof(demolist_all_local[i].title), "%s %s", demolist_all_local[i].title, demolist_all_local[i].date);
}*/
}
}
Lock_search_state();
if (replaythreadnum == localreplaythreadnum && demolist_all)
if (fastcmp(menupath, replaydirpath) && demolist_all)
{
memcpy(demolist_all, demolist_all_local, sizeof(menudemo_t)*demolist_all_size);
replaynamesloaded = true;
@@ -4052,32 +4047,22 @@ static void ReplayNamesLoadThread(void* userdata)
Unlock_search_state();
// Was allocated before thread start, we need to free it
free(replaydirpath);
free(demolist_all_local);
}
static void LoadReplayNames(void)
{
char *replaydirpath = strdup(menupath);
Lock_search_state();
replaythreadnum++;
replaynamesloaded = false;
if (cv_demodateformat.value == 2)
demodateformat = "%m.%d.%Y";
else if (cv_demodateformat.value == 1)
demodateformat = "%d.%m.%Y";
else
{
// get the date format here
// setlocale reads/writes global state
const char *locale = setlocale(LC_TIME, NULL);
// US ppl are special (:
demodateformat = (locale && strstr(locale, "en_US")) ? "%m.%d.%Y" : "%d.%m.%Y";
}
Unlock_search_state();
#ifdef HAVE_THREADS
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, NULL);
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, replaydirpath);
#else
ReplayNamesLoadThread(NULL);
ReplayNamesLoadThread(replaydirpath);
#endif
}
@@ -4116,12 +4101,8 @@ static void M_HutCheckReplays(size_t maxnum)
// Mark as done
replayqueryfound = replayquerycheck = sizedirmenu;
Lock_search_state();
memcpy(demolist, demolist_all, sizeof(menudemo_t) * sizedirmenu);
Unlock_search_state();
return;
}
@@ -4270,15 +4251,13 @@ static boolean M_HandleReplayHutQuery(INT32 choice)
char tmp[MAXREPLAYQUERY+1];
memcpy(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1);
// Honestly not sure if locks for replaynamesloaded are necessary...
// Thread sanitizer does report race condition whenever replaynamesloaded is accessed without lock
// but really it is only ever set to false in main thread and only set to true in replay load thread,
// and both are done via locks. If replaynamesloaded is true, it is never gonna suddenly switch from true to false
// while we're in main thread, and if it would switch from false to true it is not really a big deal, we will just skip
// 1 frame where replay names were loaded
Lock_search_state();
if (!replaynamesloaded)
{
Unlock_search_state();
return false;
}
Unlock_search_state();
if (M_TextInputHandle(&replayqueryinput, choice))
{
@@ -4564,9 +4543,9 @@ static void DrawReplayHutReplayInfo(void)
}
// Character face!
if (replaydemolist->standings[0].skin < numskins && W_CheckNumForName(skins[replaydemolist->standings[0].skin]->facewant) != LUMPERROR)
if (replaydemolist->standings[0].skin < numskins && W_CheckNumForName(skins[replaydemolist->standings[0].skin].facewant) != LUMPERROR)
{
patch = skins[replaydemolist->standings[0].skin]->facewantprefix;
patch = facewantprefix[replaydemolist->standings[0].skin];
colormap = R_GetTranslationColormap(
replaydemolist->standings[0].skin,
replaydemolist->standings[0].color,
@@ -4787,9 +4766,9 @@ static void M_DrawReplayStartMenu(void)
V_DrawString(BASEVIDWIDTH-92, STARTY + i*20 + 9, V_SNAPTOTOP, va("%d", timeorscore));
// Character face!
if (replaydemolist->standings[i].skin < numskins && W_CheckNumForName(skins[replaydemolist->standings[i].skin]->facerank) != LUMPERROR)
if (replaydemolist->standings[i].skin < numskins && W_CheckNumForName(skins[replaydemolist->standings[i].skin].facerank) != LUMPERROR)
{
patch = skins[replaydemolist->standings[i].skin]->facerankprefix;
patch = facerankprefix[replaydemolist->standings[i].skin];
colormap = R_GetTranslationColormap(
replaydemolist->standings[i].skin,
replaydemolist->standings[i].color,
@@ -4978,15 +4957,13 @@ static void M_DrawPlaybackMenu(void)
if (i >= playback_view1 && i <= playback_view4)
{
if (modeattacking)
continue;
if (modeattacking) continue;
if (splitscreen >= i - playback_view1)
{
INT32 ply = displayplayers[i - playback_view1];
icon = skins[players[ply].skin]->facerankprefix;
icon = facerankprefix[players[ply].skin];
if (i != itemOn)
inactivemap = R_GetTranslationColormap(players[ply].skin, players[ply].skincolor, GTC_MENUCACHE);
}
@@ -6272,17 +6249,17 @@ void M_DrawTimeAttackMenu(void)
SHOWMODDEDGAME
const INT32 skinnum = max(cv_chooseskin.value-1, 0); // dont think its needed but better safe than sorry!
const skin_t *skin = skins[skinnum];
const skin_t *skin = &skins[skinnum];
// Character face!
if (W_CheckNumForName(skin->facewant) != LUMPERROR)
{
const INT32 charx = (BASEVIDWIDTH-x - skins[skinnum]->facewantprefix->width);
const INT32 charx = (BASEVIDWIDTH-x - facewantprefix[skinnum]->width);
UINT8 *colormap = NULL;
colormap = R_GetTranslationColormap(skinnum, cv_playercolor.value, GTC_MENUCACHE);
V_DrawMappedPatch(charx, y, 0, skins[skinnum]->facewantprefix, colormap);
V_DrawMappedPatch(charx, y, 0, facewantprefix[skinnum], colormap);
// draw stats
// speed
@@ -7730,7 +7707,7 @@ static void M_DrawMPMainMenu(void)
break;
}
if (pskin >= numskins)
if (pskin >= MAXSKINS)
pskin = 0;
if (!trans && i > cv_splitplayers.value)
@@ -7738,7 +7715,7 @@ static void M_DrawMPMainMenu(void)
colmap = R_GetTranslationColormap(pskin, pcol, GTC_MENUCACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, trans, skins[pskin]->facewantprefix, colmap);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, trans, facewantprefix[pskin], colmap);
if (itemOn == 2 && i == setupm_pselect)
{
@@ -7999,12 +7976,12 @@ static void M_DrawSetupMultiPlayerMenu(void)
else
M_DrawTextInput(mx + 40, my + nameboxaddy, &setupm_input, 0);
#define GETSELECTEDSKINNAME (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]]->realname : skins[setupm_fakeskin]->realname)
#define GETSELECTEDSPEED (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]]->kartspeed : skins[setupm_fakeskin]->kartspeed)
#define GETSELECTEDWEIGHT (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]]->kartweight : skins[setupm_fakeskin]->kartweight)
#define GETSELECTEDSKINNAME (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]].realname : skins[setupm_fakeskin].realname)
#define GETSELECTEDSPEED (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]].kartspeed : skins[setupm_fakeskin].kartspeed)
#define GETSELECTEDWEIGHT (itemOn == 1 && setupm_skinselect < numskins ? skins[skinsorted[setupm_skinselect]].kartweight : skins[setupm_fakeskin].kartweight)
// draw skin string
st = V_StringWidth(skins[setupm_fakeskin]->realname, 0);
st = V_StringWidth(skins[setupm_fakeskin].realname, 0);
switch (cv_skinselectmenu.value)
{
case SKINMENUTYPE_EXTENDED:
@@ -8026,10 +8003,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
skintodisplay = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime()/TICRATE)%SELECTEDSTATSCOUNT];
tw = V_StringWidth("Character", 0);
st = V_StringWidth(skins[skintodisplay]->realname, 0);
st = V_StringWidth(skins[skintodisplay].realname, 0);
V_DrawString((mx+(tw/2)) - (st/2), my + 37,
((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0) | highlightflags | V_ALLOWLOWERCASE,
skins[skintodisplay]->realname);
skins[skintodisplay].realname);
// the menu is now 2d, no need for scroll arrows...
if (itemOn == 1 && setupm_skinlockedselect)
{
@@ -8043,7 +8020,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
default:
V_DrawString(BASEVIDWIDTH - mx - st, my + 16,
((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|highlightflags|V_ALLOWLOWERCASE,
skins[setupm_fakeskin]->realname);
skins[setupm_fakeskin].realname);
if (itemOn == 1)
{
V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 16,
@@ -8149,10 +8126,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
for (i = 0; i < numskins; i++) // draw the stat dots
{
if (i != setupm_fakeskin && R_SkinAvailable(skins[i]->name) != -1)
if (i != setupm_fakeskin && R_SkinAvailable(skins[i].name) != -1)
{
speed = skins[i]->kartspeed;
weight = skins[i]->kartweight;
speed = skins[i].kartspeed;
weight = skins[i].kartweight;
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, NULL);
}
}
@@ -8208,10 +8185,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
for (i = 0; i < numskins; i++) // draw the stat dots
{
if (i != setupm_fakeskin && R_SkinAvailable(skins[i]->name) != -1)
if (i != setupm_fakeskin && R_SkinAvailable(skins[i].name) != -1)
{
speed = skins[i]->kartspeed;
weight = skins[i]->kartweight;
speed = skins[i].kartspeed;
weight = skins[i].kartweight;
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
}
}
@@ -8245,8 +8222,8 @@ static void M_DrawSetupMultiPlayerMenu(void)
continue;
}
face = skins[skinn]->facerankprefix;
cmap = R_GetTranslationColormap(skinn, skins[skinn]->prefcolor, GTC_MENUCACHE);
face = facerankprefix[skinn];
cmap = R_GetTranslationColormap(skinn, skins[skinn].prefcolor, GTC_MENUCACHE);
V_DrawFixedPatch(x << FRACBITS, y << FRACBITS, FRACUNIT, 0, face, cmap);
}
@@ -8283,8 +8260,8 @@ static void M_DrawSetupMultiPlayerMenu(void)
continue;
}
face = skins[skinn]->facerankprefix;
cmap = R_GetTranslationColormap(skinn, skins[skinn]->prefcolor, GTC_MENUCACHE);
face = facerankprefix[skinn];
cmap = R_GetTranslationColormap(skinn, skins[skinn].prefcolor, GTC_MENUCACHE);
V_DrawFixedPatch(x << FRACBITS, y << FRACBITS, FRACUNIT, 0, face, cmap);
}
@@ -8298,7 +8275,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (setupm_skinselect < numskins)
{
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
cursor = skins[skinsorted[setupm_skinselect]]->facewantprefix;
cursor = facewantprefix[skinsorted[setupm_skinselect]];
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
}
else
@@ -8312,8 +8289,8 @@ static void M_DrawSetupMultiPlayerMenu(void)
{ // stat dot
const INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin);
speed = skins[selectedskin]->kartspeed;
weight = skins[selectedskin]->kartweight;
speed = skins[selectedskin].kartspeed;
weight = skins[selectedskin].kartweight;
const INT32 x = (((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1);
const INT32 y = (((staty+71) + (weight*4))<<FRACBITS);
@@ -8352,8 +8329,8 @@ static void M_DrawSetupMultiPlayerMenu(void)
}
skinn = skinstats[s][w][(I_GetTime() / TICRATE) % skinstatscount[s][w]];
face = skins[skinn]->facerankprefix;
cmap = R_GetTranslationColormap(skinn, skins[skinn]->prefcolor, GTC_MENUCACHE);
face = facerankprefix[skinn];
cmap = R_GetTranslationColormap(skinn, skins[skinn].prefcolor, GTC_MENUCACHE);
V_DrawFixedPatch(x << FRACBITS, y << FRACBITS, FRACUNIT, 0, face, cmap);
}
@@ -8370,7 +8347,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
const INT32 skinn = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime() / TICRATE) % skinstatscount[setupm_skinxpos][setupm_skinypos]];
cursor = skins[skinn]->facewantprefix;
cursor = facewantprefix[skinn];
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
}
else
@@ -8384,8 +8361,8 @@ static void M_DrawSetupMultiPlayerMenu(void)
#undef SKINXSHIFT
default:
{
speed = skins[setupm_fakeskin]->kartspeed;
weight = skins[setupm_fakeskin]->kartweight;
speed = skins[setupm_fakeskin].kartspeed;
weight = skins[setupm_fakeskin].kartweight;
const INT32 x = ((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS;
const INT32 y = ((my+76) + ((weight-1)*8))<<FRACBITS;
@@ -8469,14 +8446,14 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (!(k++))
{
scale = FRACUNIT;
face = skins[col]->facewantprefix;
face = facewantprefix[col];
offx = 12;
offy = 0;
}
else
{
scale = FRACUNIT/2;
face = skins[col]->facerankprefix;
face = facerankprefix[col];
offx = 8;
offy = 8;
}
@@ -8530,15 +8507,15 @@ static void M_DrawSetupMultiPlayerMenu(void)
break;
}
if (skintodisplay >= numskins)
if (skintodisplay >= MAXSKINS)
skintodisplay = 0;
skinnum = R_SkinAvailable(skins[skintodisplay]->name);
skinnum = R_SkinAvailable(skins[skintodisplay].name);
if (skinnum < 0 || skinnum >= numskins)
if (skinnum < 0 || skinnum >= MAXSKINS)
skinnum = 0;
sprdef = &skins[skinnum]->spritedef;
sprdef = &skins[skinnum].spritedef;
if (!sprdef->numframes) // No frames ??
return; // Can't render!
@@ -8556,7 +8533,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
{
UINT8 *colormap = R_GetTranslationColormap(skintodisplay, setupm_fakecolor, GTC_MENUCACHE);
#ifdef HWRENDER
md2_t *md2 = &skins[skinnum]->playermodel;
md2_t *md2 = &md2_playermodels[skinnum];
#endif
mx += 36;
my += 131;
@@ -8587,11 +8564,11 @@ static void M_DrawSetupMultiPlayerMenu(void)
patch = (patch_t *)W_CachePatchNum(sprframe->lumppat[speenframe], PU_PATCH);
if (skins[skintodisplay]->flags & SF_HIRES)
if (skins[skintodisplay].flags & SF_HIRES)
{
V_DrawFixedPatch(mx<<FRACBITS,
my<<FRACBITS,
skins[skintodisplay]->highresscale,
skins[skintodisplay].highresscale,
flags, patch, colormap);
}
else
@@ -8898,7 +8875,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else if (itemOn == 2)
{
UINT8 col = skins[setupm_fakeskin]->prefcolor;
UINT8 col = skins[setupm_fakeskin].prefcolor;
if (setupm_fakecolor != col)
{
S_StartSound(NULL, sfx_menu1); // Tails
@@ -9121,7 +9098,7 @@ static boolean M_QuitMultiPlayerMenu(void)
}
// you know what? always putting these in the buffer won't hurt anything.
COM_BufAddText(va("%s \"%s\"\n", setupm_cvskin->name, skins[setupm_fakeskin]->name));
COM_BufAddText(va("%s \"%s\"\n", setupm_cvskin->name, skins[setupm_fakeskin].name));
COM_BufAddText(va("%s %d\n", setupm_cvcolor->name, setupm_fakecolor));
return true;
@@ -9897,7 +9874,7 @@ static void M_DrawLocalSkinMenu(void)
UINT8 frame;
INT32 skintodisplay = 0;
UINT32 speenframe;
skin_t *displayskin;
skin_t displayskin;
mx = OP_ForkedBirdDef.x;
my = OP_ForkedBirdDef.y;
@@ -9939,7 +9916,7 @@ static void M_DrawLocalSkinMenu(void)
displayskin = allskins[skintodisplay];
sprdef = &displayskin->spritedef;
sprdef = &displayskin.spritedef;
if (!sprdef->numframes) // No frames ??
return; // Can't render!
@@ -9952,25 +9929,25 @@ static void M_DrawLocalSkinMenu(void)
V_DrawFill(mx + 220 - (charw/2), my+54, charw, 84, 239);
#undef charw
// FIXME: is using just "skins" array even correct?
UINT8 *colormap = R_GetLocalTranslationColormap(skins[displayskin->skinnum], (displayskin->localskin ? localskins[displayskin->skinnum] : NULL), cv_playercolor.value, GTC_MENUCACHE, displayskin->localskin);
// FIXME: is skins[displayskin.localnum] even correct?
UINT8 *colormap = R_GetLocalTranslationColormap(&skins[displayskin.localnum], (displayskin.localskin ? &localskins[displayskin.localnum] : NULL), cv_playercolor.value, GTC_MENUCACHE, displayskin.localskin);
V_DrawMappedPatch(mx, my+50, 0, (patch_t *)W_CachePatchName(displayskin->facewant, PU_PATCH), colormap);
V_DrawMappedPatch(mx+8, my+85, 0, (patch_t *)W_CachePatchName(displayskin->facerank, PU_PATCH), colormap);
V_DrawMappedPatch(mx, my+50, 0, (patch_t *)W_CachePatchName(displayskin.facewant, PU_PATCH), colormap);
V_DrawMappedPatch(mx+8, my+85, 0, (patch_t *)W_CachePatchName(displayskin.facerank, PU_PATCH), colormap);
V_DrawString(mx, my+108, V_ALLOWLOWERCASE, "Character");
if (strlen(displayskin->realname) > 10)
V_DrawThinString(mx+20, my+118, V_ALLOWLOWERCASE|highlightflags, displayskin->realname);
if (strlen(displayskin.realname) > 10)
V_DrawThinString(mx+20, my+118, V_ALLOWLOWERCASE|highlightflags, displayskin.realname);
else
V_DrawString(mx+20, my+118, V_ALLOWLOWERCASE|highlightflags, displayskin->realname);
V_DrawString(mx+20, my+118, V_ALLOWLOWERCASE|highlightflags, displayskin.realname);
// draw player sprite
mx += 220;
my += 120;
#ifdef HWRENDER
md2_t *md2 = &displayskin->playermodel;
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[displayskin.localnum] : &md2_playermodels[skintodisplay]);
// if we have 3d models enabled and a model exists
// try to show it instead of the sprite
@@ -9998,9 +9975,9 @@ static void M_DrawLocalSkinMenu(void)
patch = (patch_t *)W_CachePatchNum(sprframe->lumppat[speenframe], PU_PATCH);
if (displayskin->flags & SF_HIRES)
if (displayskin.flags & SF_HIRES)
{
V_DrawFixedPatch(mx<<FRACBITS, my<<FRACBITS, displayskin->highresscale, flags, patch, colormap);
V_DrawFixedPatch(mx<<FRACBITS, my<<FRACBITS, displayskin.highresscale, flags, patch, colormap);
}
else
{
+2 -2
View File
@@ -1004,7 +1004,7 @@ static menuitem_t OP_ExpOptionsMenu[] =
#ifdef HWRENDER
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 95},
#ifdef USE_FBO_OGL
{IT_STRING | IT_CVAR, NULL, "FBO support", &cv_glframebuffer, 100},
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 100},
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
#else
@@ -1030,7 +1030,7 @@ static const char* OP_ExpTooltips[] =
#ifdef HWRENDER
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!",
#ifdef USE_FBO_OGL
"Allows the game to downsample from a higher resolution\nthan your display in OpenGL renderer mode.\nThis can be set to automatically enable if the game resolution\nis higher than the current Display Resolution\nor enabled at all times.\nThis may improve performance in some cases.\nRequires a GPU with atleast OpenGL 2.1 support.",
"Allows the game to downsample from a higher resolution\nthan your display in OpenGL renderer mode.\nRequires a GPU with atleast OpenGL 2.1 support.",
#endif
"Change the bit depth of the Lookup Palette in Palette rendering mode\n 16 bits is like software looks ingame\nwhile 24 bits is how software looks in screenshots.",
#endif
+336 -713
View File
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -107,9 +107,6 @@ void P_DoNightsScore(player_t *player)
dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE);
if (P_MobjWasRemovedCompat(dummymo))
return;
if (player->bot)
player = &players[consoleplayer];
@@ -2016,7 +2013,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
}
}
static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
player_t *player = target->player;
(void)damage; //unused parm
+3 -3
View File
@@ -2026,7 +2026,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
mapcampointer = thiscam;
if (newsec->flags & SF_NOCLIPCAMERA)
if (UNLIKELY(GETSECSPECIAL(newsec->special, 4) == 12))
{ // Camera noclip on entire sector.
tmfloorz = tmdropoffz = thiscam->z;
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
@@ -2068,7 +2068,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL)
|| rover->master->frontsector->flags & SF_NOCLIPCAMERA)
|| UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
@@ -2144,7 +2144,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (polysec->flags & SF_NOCLIPCAMERA)
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
+2 -2
View File
@@ -328,7 +328,7 @@ void P_CameraLineOpening(line_t *linedef)
{
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
@@ -358,7 +358,7 @@ void P_CameraLineOpening(line_t *linedef)
{
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
+921 -1156
View File
File diff suppressed because it is too large. Load diff
+8 -8
View File
@@ -258,15 +258,15 @@ typedef enum
// PRECIPITATION flags ?! ?! ?!
//
typedef enum {
PCF_INVISIBLE = 1, // Don't draw.
PCF_INVISIBLE = 1, // Don't draw.
PCF_PIT = 1<<1, // Above pit.
PCF_SPLASH = 1<<2, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<3, // Ran the thinker this tic.
PCF_FOF = 1<<2, // Above FOF.
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<5, // Ran the thinker this tic.
} precipflag_t;
typedef struct skin_s skin_t;
// Map Object definition.
typedef struct mobj_s
{
@@ -342,9 +342,9 @@ typedef struct mobj_s
struct mobj_s *hnext;
struct mobj_s *hprev;
skin_t *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
skin_t *localskin;
boolean skinlocal; // if the skin is from a LOCALLY loaded skin
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
void *localskin;
boolean skinlocal;
// Player and mobj sprites in multiplayer modes are modified
// using an internal color lookup table for re-indexing.
+2 -38
View File
@@ -1109,10 +1109,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
return;
// do not send over locally spawned mobjs
if (mobj->islocal)
return;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
{
// spawnpoint is not modified but we must save it since it is an identifier
@@ -1138,17 +1134,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
#endif
diff |= MD_MOM;
#ifdef PHOBOS_BUILD
if (mobj->radius != FixedMul(mapobjectscale, mobj->info->radius))
#else
if (mobj->radius != mobj->info->radius)
#endif
diff |= MD_RADIUS;
#ifdef PHOBOS_BUILD
if (mobj->height != FixedMul(mapobjectscale, mobj->info->height))
#else
if (mobj->height != mobj->info->height)
#endif
diff |= MD_HEIGHT;
if (mobj->flags != mobj->info->flags)
diff |= MD_FLAGS;
@@ -1191,19 +1179,11 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff |= MD_MOVEFACTOR;
if (mobj->fuse)
diff |= MD_FUSE;
#ifdef PHOBOS_BUILD
if (mobj->watertop != INT32_MAX)
#else
if (mobj->watertop)
#endif
diff |= MD_WATERTOP;
if (mobj->waterbottom)
diff |= MD_WATERBOTTOM;
#ifdef PHOBOS_BUILD
if (mobj->scale != mapobjectscale)
#else
if (mobj->scale != FRACUNIT)
#endif
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
@@ -1344,7 +1324,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (diff2 & MD2_CVMEM)
WRITEINT32(save->p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITESKIN(save->p, (skinnum_t)mobj->skin->skinnum);
WRITESKIN(save->p, (skinnum_t)((skin_t *)mobj->skin - skins));
if (diff2 & MD2_COLOR)
WRITEUINT8(save->p, mobj->color);
if (diff2 & MD2_EXTVAL1)
@@ -2110,19 +2090,11 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->radius = FixedMul(mobj->info->radius, mapobjectscale);
#else
mobj->radius = mobj->info->radius;
#endif
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->height = FixedMul(mobj->info->height, mapobjectscale);
#else
mobj->height = mobj->info->height;
#endif
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save->p);
else
@@ -2194,20 +2166,12 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->fuse = READINT32(save->p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save->p);
#ifdef PHOBOS_BUILD
else
mobj->watertop = INT32_MAX;
#endif
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save->p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->scale = mapobjectscale;
#else
mobj->scale = FRACUNIT;
#endif
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save->p);
else
@@ -2221,7 +2185,7 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save->p);
if (diff2 & MD2_SKIN)
mobj->skin = skins[READSKIN(save->p)];
mobj->skin = &skins[READSKIN(save->p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT8(save->p);
if (diff2 & MD2_EXTVAL1)
+25 -37
View File
@@ -570,13 +570,13 @@ static void P_LoadSegs(UINT8 *data)
if (seg->sidedef == &sides[seg->linedef->sidenum[0]])
{
seg->v1 = lines[rawlinedef].v1;
seg->v2 = lines[rawlinedef].v2;
seg->v1 = lines[ms->linedef].v1;
seg->v2 = lines[ms->linedef].v2;
}
else
{
seg->v1 = lines[rawlinedef].v2;
seg->v2 = lines[rawlinedef].v1;
seg->v1 = lines[ms->linedef].v2;
seg->v2 = lines[ms->linedef].v1;
}
}
else
@@ -584,6 +584,7 @@ static void P_LoadSegs(UINT8 *data)
seg->v1 = &vertexes[v1];
seg->v2 = &vertexes[v2];
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
@@ -596,6 +597,7 @@ static void P_LoadSegs(UINT8 *data)
//seg->fv2.z = FixedToFloat(seg->v2->z);
}
#endif
seg->length = P_SegLength(seg);
P_UpdateSegLightOffset(seg);
@@ -2094,13 +2096,6 @@ static void P_LoadMapBSP(const virtres_t* virt)
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
virtlump_t* virtnodes = vres_Find(virt, "NODES");
if (!virtssectors)
I_Error("SSECTORS lump not found");
if (!virtsegs)
I_Error("SEGS lump not found");
if (!virtnodes)
I_Error("NODES lump not found");
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
numnodes = virtnodes->size / sizeof(mapnode_t);
numsegs = virtsegs->size / sizeof(mapseg_t);
@@ -2483,28 +2478,28 @@ static void P_ForceCharacter(const char *forcecharskin)
if (splitscreen)
{
SetPlayerSkin(displayplayers[1], forcecharskin);
if ((unsigned)cv_playercolor2.value != skins[players[displayplayers[1]].skin]->prefcolor && !modeattacking)
if ((unsigned)cv_playercolor2.value != skins[players[displayplayers[1]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor2, skins[players[displayplayers[1]].skin]->prefcolor);
players[displayplayers[1]].skincolor = skins[players[displayplayers[1]].skin]->prefcolor;
CV_StealthSetValue(&cv_playercolor2, skins[players[displayplayers[1]].skin].prefcolor);
players[displayplayers[1]].skincolor = skins[players[displayplayers[1]].skin].prefcolor;
}
if (splitscreen > 1)
{
SetPlayerSkin(displayplayers[2], forcecharskin);
if ((unsigned)cv_playercolor3.value != skins[players[displayplayers[2]].skin]->prefcolor && !modeattacking)
if ((unsigned)cv_playercolor3.value != skins[players[displayplayers[2]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor3, skins[players[displayplayers[2]].skin]->prefcolor);
players[displayplayers[2]].skincolor = skins[players[displayplayers[2]].skin]->prefcolor;
CV_StealthSetValue(&cv_playercolor3, skins[players[displayplayers[2]].skin].prefcolor);
players[displayplayers[2]].skincolor = skins[players[displayplayers[2]].skin].prefcolor;
}
if (splitscreen > 2)
{
SetPlayerSkin(displayplayers[3], forcecharskin);
if ((unsigned)cv_playercolor4.value != skins[players[displayplayers[3]].skin]->prefcolor && !modeattacking)
if ((unsigned)cv_playercolor4.value != skins[players[displayplayers[3]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor4, skins[players[displayplayers[3]].skin]->prefcolor);
players[displayplayers[3]].skincolor = skins[players[displayplayers[3]].skin]->prefcolor;
CV_StealthSetValue(&cv_playercolor4, skins[players[displayplayers[3]].skin].prefcolor);
players[displayplayers[3]].skincolor = skins[players[displayplayers[3]].skin].prefcolor;
}
}
}
@@ -2512,10 +2507,10 @@ static void P_ForceCharacter(const char *forcecharskin)
SetPlayerSkin(consoleplayer, forcecharskin);
// normal player colors in single player
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin]->prefcolor && !modeattacking)
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin]->prefcolor);
players[consoleplayer].skincolor = skins[players[consoleplayer].skin]->prefcolor;
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
players[consoleplayer].skincolor = skins[players[consoleplayer].skin].prefcolor;
}
}
}
@@ -2542,8 +2537,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i]->name));
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
}
}
@@ -2555,8 +2550,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_bestlap.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-lap-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-lap-best.lmp", gpath, skins[i]->name));
if (FIL_FileExists(va("%s-%s-lap-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-lap-best.lmp", gpath, skins[i].name));
}
}
@@ -2568,8 +2563,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i]->name));
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
}
}
@@ -3336,7 +3331,6 @@ static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
return false;
}
//
// P_CheckReplacMapReplacements
//
@@ -3429,13 +3423,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
{
// check if someone tries to load maps locally lol
// do this here so we can skip loading the file anyways
int retmap = W_CheckAutoLoadContainsMap(wadfilename);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "addilelocal: file %s was not found or not valid.\n", wadfilename);
return UINT16_MAX;
}
if (retmap > 0)
if (W_CheckAutoLoadContainsMap(wadfilename))
{
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
return UINT16_MAX;
+7 -27
View File
@@ -1962,19 +1962,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (!dest)
return;
const angle_t ang = (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle;
const boolean dontstopmove = (line->flags & ML_EFFECT4) == ML_EFFECT4;
if (bot)
P_Teleport(bot, dest->x, dest->y, dest->z, ang, (line->flags & ML_BLOCKMONSTERS) == 0, dontstopmove);
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
if (line->flags & ML_BLOCKMONSTERS)
{
P_Teleport(mo, dest->x, dest->y, dest->z, ang, false, dontstopmove);
}
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
else
{
P_Teleport(mo, dest->x, dest->y, dest->z, ang, true, dontstopmove);
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
// Play the 'bowrwoosh!' sound
S_StartSound(dest, sfx_mixup);
}
@@ -3400,7 +3394,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
break;
case 12: // SRB2kart: Invert Encore Remap
break;
case 15: // also Invert Encore Remap....
case 15: // no idea but keep it dont want anything to break
break;
}
DoneSection2:
@@ -5374,11 +5368,6 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
case 11: // Custom global gravity!
gravity = sector->floorheight/1000;
break;
case 12: // SRB2kart: Invert Encore Remap
case 15: // NOTE: vanilla kart checks only for this for some reason!
sector->flags |= SF_INVERTENCORE;
break;
}
// Process Section 4
@@ -5388,10 +5377,6 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
if (G_RaceGametype())
circuitmap = true;
break;
case 12: // Camera noclip
sector->flags |= SF_NOCLIPCAMERA;
break;
}
}
@@ -5476,11 +5461,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
sectors[s].gravity = &sectors[sec].floorheight; // This allows it to change in realtime!
if (lines[i].flags & ML_NOCLIMB)
sectors[s].flags |= SF_GRAVITYFLIP;
sectors[s].verticalflip = true;
else
sectors[s].flags &= ~SF_GRAVITYFLIP;
sectors[s].verticalflip = false;
CheckForReverseGravity = (boolean)(sectors[s].flags & SF_GRAVITYFLIP);
CheckForReverseGravity = sectors[s].verticalflip;
}
break;
@@ -5573,11 +5558,6 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
sectors[s].cullheight = &lines[i]; // This allows it to change in realtime!
break;
case 13: // Heat wave effect
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
sectors[s].flags |= SF_HEATWAVE;
break;
case 50: // Insta-Lower Sector
EV_DoFloor(&lines[i], instantLower);
break;
+8 -9
View File
@@ -91,7 +91,7 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx = FixedMul(move, FINECOSINE(angle));
if (!twodmo(mo))
mo->momy = FixedMul(move, FINESINE(angle));
mo->momy = FixedMul(move,FINESINE(angle));
}
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
@@ -498,7 +498,7 @@ void P_PlayRinglossSound(mobj_t *source, mobj_t *damager)
// I HATE LOCALSKINS! I HATE LOCALSKINS! :AAAAAAAAAA:
if (source->player)
sfx = R_GetPlayerSkin(source->player)->soundsid[SKSKPAN1 + key];
sfx = K_GetPlayerSkin(source->player)->soundsid[SKSKPAN1 + key];
S_StartSound(NULL, sfx);
}
@@ -1271,7 +1271,7 @@ void P_DoPlayerExit(player_t *player)
if (islocalplayer)
{
sfxenum_t sfx_id = R_GetMobjSkin(player->mo)->soundsid[S_sfx[soundid].skinsound];
sfxenum_t sfx_id = K_GetMobjSkin(player->mo)->soundsid[S_sfx[soundid].skinsound];
S_StartSound(NULL, sfx_id);
}
else
@@ -3561,7 +3561,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -3626,7 +3626,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (polysec->flags & SF_NOCLIPCAMERA)
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -3682,8 +3682,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
if (UNLIKELY((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
{
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -4263,7 +4262,7 @@ boolean P_SpectatorJoinGame(player_t *player)
static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector, fixed_t pviewheight)
{
if (sector->flags & SF_HEATWAVE)
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
return true;
if (sector->ffloors)
@@ -4281,7 +4280,7 @@ static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector,
if (pviewheight <= P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y))
continue;
if (rover->master->frontsector->flags & SF_HEATWAVE)
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
return true;
}
}
+4 -3
View File
@@ -48,7 +48,8 @@ boolean g_walloffscreen = false;
boolean R_NoEncore(sector_t *sector, boolean ceiling)
{
const boolean invertEncore = (sector->flags & SF_INVERTENCORE);
const INT32 invspecial = GETSECSPECIAL(sector->special, 2);
boolean invertencore = (invspecial == 12 || invspecial == 15); // keeping this incase its used
#if 0 // perfect implementation
const INT32 sprnspecial = GETSECSPECIAL(sector->special, 3);
@@ -58,10 +59,10 @@ boolean R_NoEncore(sector_t *sector, boolean ceiling)
#endif
&& GETSECSPECIAL(sector->special, 4) != 6) // sneaker panel
{
return invertEncore;
return invertencore;
}
if (invertEncore)
if (invertencore)
{
return false;
}
+5 -16
View File
@@ -307,19 +307,10 @@ typedef struct pslope_s
typedef enum
{
// flipspecial - planes with effect
SF_FLIPSPECIAL_FLOOR = 1,
SF_FLIPSPECIAL_CEILING = 1<<1,
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
// triggerspecial - conditions under which plane touch causes effect
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
SF_GRAVITYFLIP = 1<<3,
SF_HEATWAVE = 1<<4,
SF_NOCLIPCAMERA = 1<<5,
// invert encore color remap status
SF_INVERTENCORE = 1<<6,
SF_FLIPSPECIAL_FLOOR = 1,
SF_FLIPSPECIAL_CEILING = 2,
SF_FLIPSPECIAL_BOTH = 3,
SF_TRIGGERSPECIAL_TOUCH = 4,
} sectorflags_t;
//
@@ -400,6 +391,7 @@ typedef struct sector_s
// This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics
sectorflags_t flags;
// Sprite culling feature
@@ -504,9 +496,6 @@ typedef struct subsector_s
void *splats; // floorsplat_t list
#endif
size_t validcount;
#ifdef HWRENDER
boolean hashorizon; // not really needed for software, this stuff works differently there
#endif
} subsector_t;
// Sector list node showing all sectors an object appears in.
+64 -72
View File
@@ -94,18 +94,19 @@ spandrawfunc_t *spanfuncs[SPANDRAWFUNC_MAX] = {};
// TRANSLATION COLORMAP CODE
// =========================================================================
#define DEFAULT_TT_CACHE_INDEX 0
#define BOSS_TT_CACHE_INDEX 1
#define METALSONIC_TT_CACHE_INDEX 2
#define ALLWHITE_TT_CACHE_INDEX 3
#define RAINBOW_TT_CACHE_INDEX 4
#define BLINK_TT_CACHE_INDEX 5
#define TT_CACHE_SIZE 6
#define DEFAULT_TT_CACHE_INDEX MAXSKINS
#define BOSS_TT_CACHE_INDEX (MAXSKINS + 1)
#define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2)
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define TT_CACHE_SIZE (MAXSKINS + 6)
#define SKIN_RAMP_LENGTH 16
#define DEFAULT_STARTTRANSCOLOR 160
#define NUM_PALETTE_ENTRIES 256
static UINT8 **specialtranslationtablecache[TT_CACHE_SIZE] = {};
static UINT8 **translationtablecache[TT_CACHE_SIZE] = {};
static UINT8 **localtranslationtablecache[MAXLOCALSKINS] = {};
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1] = {};
@@ -377,60 +378,38 @@ static UINT8* RGetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 f
{
UINT8 ***tt;
UINT8* ret;
INT32 skintableindex;
if (local)
{
I_Assert(skinnum >= 0 && skinnum < numlocalskins);
tt = &localskins[skinnum]->translationtablecache;
tt = localtranslationtablecache;
skintableindex = skinnum;
}
else
{
tt = translationtablecache;
// Adjust if we want the default colormap
if (skinnum < 0)
switch (skinnum)
{
INT32 skintableindex;
switch (skinnum)
{
case TC_DEFAULT:
skintableindex = DEFAULT_TT_CACHE_INDEX;
break;
case TC_BOSS:
skintableindex = BOSS_TT_CACHE_INDEX;
break;
case TC_METALSONIC:
skintableindex = METALSONIC_TT_CACHE_INDEX;
break;
case TC_ALLWHITE:
skintableindex = ALLWHITE_TT_CACHE_INDEX;
break;
case TC_RAINBOW:
skintableindex = RAINBOW_TT_CACHE_INDEX;
break;
case TC_BLINK:
skintableindex = BLINK_TT_CACHE_INDEX;
break;
default:
return NULL;
}
tt = &specialtranslationtablecache[skintableindex];
}
else
{
I_Assert(skinnum >= 0 && skinnum < numskins);
tt = &skins[skinnum]->translationtablecache;
case TC_DEFAULT: skintableindex = DEFAULT_TT_CACHE_INDEX; break;
case TC_BOSS: skintableindex = BOSS_TT_CACHE_INDEX; break;
case TC_METALSONIC: skintableindex = METALSONIC_TT_CACHE_INDEX; break;
case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break;
case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break;
case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break;
default: skintableindex = skinnum; break;
}
}
if (flags & GTC_CACHE)
{
// Allocate table for skin if necessary
if (!*tt)
*tt = static_cast<UINT8**>(Z_Calloc(MAXTRANSLATIONS * sizeof(UINT8**), PU_STATIC, NULL));
if (!tt[skintableindex])
tt[skintableindex] = static_cast<UINT8**>(Z_Calloc(MAXTRANSLATIONS * sizeof(UINT8**), PU_STATIC, NULL));
// Get colormap
ret = (*tt)[color];
ret = tt[skintableindex][color];
}
else
ret = NULL;
@@ -439,11 +418,11 @@ static UINT8* RGetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 f
if (!ret)
{
ret = static_cast<UINT8*>(Z_Malloc(NUM_PALETTE_ENTRIES, PU_STATIC, NULL));
K_GenerateKartColormap(ret, skinnum, color, local); // R_GenerateTranslationColormap(ret, skinnum, color); // SRB2kart
K_GenerateKartColormap(ret, skinnum, color, local); //R_GenerateTranslationColormap(ret, skinnum, color); // SRB2kart
// Cache the colormap if desired
if (flags & GTC_CACHE)
(*tt)[color] = ret;
tt[skintableindex][color] = ret;
}
return ret;
@@ -456,26 +435,46 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
UINT8* R_GetLocalTranslationColormap(skin_t *skin, skin_t *localskin, skincolors_t color, UINT8 flags, boolean local)
{
const INT32 skinnum = (INT32)((localskin && local) ? localskin->skinnum : (skin != NULL ? skin->skinnum : 0));
return RGetTranslationColormap(skinnum, color, flags, (localskin && local));
return RGetTranslationColormap(K_GetMobjLocalSkinNum(skin, localskin, local), color, flags, (localskin && local));
}
patch_t* R_GetSkinFaceRank(player_t* player)
patch_t* R_GetSkinFaceRank(player_t* ply)
{
const skin_t *skin = R_GetPlayerSkin(player);
return skin->facerankprefix;
if (ply->localskin)
{
if (ply->skinlocal)
return localfacerankprefix[ply->localskin - 1];
return facerankprefix[ply->localskin - 1];
}
return facerankprefix[ply->skin];
}
patch_t* R_GetSkinFaceWant(player_t* player)
patch_t* R_GetSkinFaceWant(player_t* ply)
{
const skin_t *skin = R_GetPlayerSkin(player);
return skin->facewantprefix;
if (ply->localskin)
{
if (ply->skinlocal)
return localfacewantprefix[ply->localskin - 1];
return facewantprefix[ply->localskin - 1];
}
return facewantprefix[ply->skin];
}
patch_t* R_GetSkinFaceMini(player_t* player)
patch_t* R_GetSkinFaceMini(player_t* ply)
{
const skin_t *skin = R_GetPlayerSkin(player);
return skin->facemmapprefix;
if (ply->localskin)
{
if (ply->skinlocal)
return localfacemmapprefix[ply->localskin - 1];
return facemmapprefix[ply->localskin - 1];
}
return facemmapprefix[ply->skin];
}
/** \brief Flushes cache of translation colormaps.
@@ -494,20 +493,13 @@ void R_FlushTranslationColormapCache(void)
{
INT32 i;
// skin cache
for (i = 0; i < (INT32)numskins; i++)
if (skins[i]->translationtablecache)
memset(skins[i]->translationtablecache, 0, MAXTRANSLATIONS * sizeof(UINT8**));
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
if (translationtablecache[i])
memset(translationtablecache[i], 0, MAXTRANSLATIONS * sizeof(UINT8**));
// localskin cache
for (i = 0; i < (INT32)numlocalskins; i++)
if (localskins[i]->translationtablecache)
memset(localskins[i]->translationtablecache, 0, MAXTRANSLATIONS * sizeof(UINT8**));
// special cache
for (i = 0; i < (INT32)(sizeof(specialtranslationtablecache) / sizeof(specialtranslationtablecache[0])); i++)
if (specialtranslationtablecache[i])
memset(specialtranslationtablecache[i], 0, MAXTRANSLATIONS * sizeof(UINT8**));
for (i = 0; i < (INT32)(sizeof(localtranslationtablecache) / sizeof(localtranslationtablecache[0])); i++)
if (localtranslationtablecache[i])
memset(localtranslationtablecache[i], 0, MAXTRANSLATIONS * sizeof(UINT8**));
}
*/
+1 -1
View File
@@ -6,7 +6,7 @@
// Copyright (C) 1996 by id Software, Inc.
// Copyright (C) 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
// Copyright (C) 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) Copyright 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) 2013 by James Haley, Stephen McGranahan, et al.
//
// This program is free software distributed under the
+1 -1
View File
@@ -389,7 +389,7 @@ angle_t R_PlayerSliptideAngle(player_t *player)
if (mo->skin && mo->sprite == SPR_PLAY)
{
sprdef = &mo->skin->spritedef;
sprdef = &((skin_t *)mo->skin)->spritedef;
if (rot >= sprdef->numframes)
sprdef = &sprites[mo->sprite];
+4 -4
View File
@@ -129,8 +129,8 @@ static void R_ParseSpriteInfo(boolean spr2)
spritenum_t sprnum = NUMSPRITES;
//playersprite_t spr2num = NUMPLAYERSPRITES;
INT32 i;
INT32 skinnumbers[MAXSKINS]; // >variable 'skinnumbers' set but not used >compile error when commented out
INT32 foundskins = 0;
CLEANUP(pfree) INT32 *skinnumbers = (INT32 *)calloc(1, numallskins); // could realloc this for foundskins but this is simpler
// Sprite name
sprinfoToken = M_GetToken(NULL);
@@ -236,10 +236,10 @@ static void R_ParseSpriteInfo(boolean spr2)
{
size_t skinnum = skinnumbers[i];
skin_t *skin;
if (allskins[skinnum]->localskin)
skin = localskins[allskins[skinnum]->skinnum];
if (allskins[skinnum].localskin)
skin = &localskins[allskins[skinnum].localnum];
else
skin = skins[allskins[skinnum]->skinnum];
skin = &skins[allskins[skinnum].localnum];
memcpy(&skin->sprinfo, info, sizeof(spriteinfo_t));
}
}
+38 -6
View File
@@ -61,6 +61,7 @@ fixed_t rw_distance = 0;
static INT32 rw_x, rw_stopx;
static angle_t rw_centerangle;
static fixed_t rw_offset;
static fixed_t rw_offset2; // for splats
static fixed_t rw_scale, rw_scalestep;
static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid;
static INT32 worldtop, worldbottom, worldhigh, worldlow;
@@ -263,7 +264,12 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
else if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS - 1];
else
walllights = scalelight[lightnum];
}
if (frontsector->heightsec != -1)
@@ -365,7 +371,12 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
lightnum = rlight->lightnum;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -813,7 +824,12 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
else if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS-1];
else
walllights = scalelight[lightnum];
}
maskedtexturecol = drawseg->thicksidecol;
@@ -955,7 +971,12 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
lightnum = rlight->lightnum;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -1446,7 +1467,12 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
else if (P_ApplyLightOffset(lightnum, curline->frontsector))
lightnum += curline->lightOffset;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -2525,6 +2551,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_offset = -rw_offset;
/// don't use texture offset for splats
rw_offset2 = rw_offset + curline->offset;
rw_offset += sidedef->textureoffset + curline->offset;
rw_centerangle = ANGLE_90 + viewangle - rw_normalangle;
@@ -2537,7 +2564,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS - 1];
else
walllights = scalelight[lightnum];
}
// if a floor / ceiling plane is on the wrong side
-5
View File
@@ -22,11 +22,6 @@ extern "C" {
#pragma interface
#endif
FUNCINLINE static ATTRINLINE lighttable_t** R_GetWallLight(INT32 llevel)
{
return scalelight[CLAMP(llevel, 0, LIGHTLEVELS-1)];
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop);
+63 -102
View File
@@ -40,9 +40,7 @@ CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2] = {}; // huehuehuehuehue
INT32 numskins = 0;
INT32 numallskins = 0;
INT32 numlocalskins = 0;
skin_t **skins = NULL;
skin_t **localskins = NULL;
skin_t **allskins = NULL;
skin_t skins[MAXSKINS];
skinnum_t skinstats[9][9][MAXSKINS];
skinnum_t skinstatscount[9][9] = {
@@ -58,8 +56,17 @@ skinnum_t skinstatscount[9][9] = {
};
skinnum_t skinsorted[MAXSKINS] = {};
skin_t localskins[MAXLOCALSKINS] = {};
skin_t allskins[MAXSKINS+MAXLOCALSKINS] = {};
static void Sk_SetDefaultValue(skin_t *skin)
// FIXTHIS: don't work because it must be inistilised before the config load
//#define SKINVALUES
#ifdef SKINVALUES
CV_PossibleValue_t skin_cons_t[MAXSKINS+1] = {};
CV_PossibleValue_t localskin_cons_t[MAXLOCALSKINS+1] = {};
#endif
static void Sk_SetDefaultValue(skin_t *skin, boolean local)
{
INT32 i;
//
@@ -67,7 +74,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
//
memset(skin, 0, sizeof(skin_t));
snprintf(skin->name, sizeof skin->name, "skin %u", skin->skinnum); // this will always be "skin 0" cause of the memset above lmao
snprintf(skin->name, sizeof skin->name, "skin %u", K_GetMobjSkinNum(skin, local));
skin->name[sizeof skin->name - 1] = '\0';
skin->wadnum = INT16_MAX;
@@ -105,22 +112,35 @@ static void Sk_SetDefaultValue(skin_t *skin)
void R_InitSkins(void)
{
skin_t *skin;
#ifdef SKINVALUES
INT32 i;
skins = Z_Calloc(sizeof(skin_t *), PU_STATIC, NULL);
//localskins = Z_Calloc(sizeof(skin_t *), PU_STATIC, NULL);
allskins = Z_Calloc(sizeof(skin_t *), PU_STATIC, NULL);
for (i = 0; i <= MAXSKINS; i++)
{
skin_cons_t[i].value = 0;
skin_cons_t[i].strvalue = NULL;
}
for (i = 0; i <= MAXLOCALSKINS; i++)
{
localskin_cons_t[i].value = 0;
localskin_cons_t[i].strvalue = NULL;
}
#endif
// skin[0] = Sonic skin
skin = skins[0] = Z_Calloc(sizeof(skin_t), PU_STATIC, NULL);
Sk_SetDefaultValue(skin);
skin->skinnum = 0;
skin = &skins[0];
numskins = 1;
Sk_SetDefaultValue(skin, false);
memset(skinstats, 0, sizeof(skinstats));
memset(skinsorted, 0, sizeof(skinsorted));
// Hardcoded S_SKIN customizations for Sonic.
strcpy(skin->name, DEFAULTSKIN);
#ifdef SKINVALUES
skin_cons_t[0].strvalue = skins[0].name;
#endif
strcpy(skin->realname, "Sonic");
strcpy(skin->hudname, "SONIC");
@@ -133,6 +153,7 @@ void R_InitSkins(void)
skin->wadnum = 0; // god what have you brought to this world
skin->prefcolor = SKINCOLOR_BLUE;
skin->localskin = false;
skin->localnum = 0;
// SRB2kart
skin->kartspeed = 8;
@@ -142,7 +163,7 @@ void R_InitSkins(void)
skin->spritedef.numframes = sprites[SPR_PLAY].numframes;
skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes;
skin->sprinfo = spriteinfo[SPR_PLAY];
ST_LoadFaceGraphics(skin);
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, 0);
// Set values for Sonic skin
Forceskin_cons_t[1].value = 0;
@@ -156,8 +177,6 @@ void R_InitSkins(void)
// lets set it
allskins[0] = skins[0];
numskins = 1;
numallskins = 1;
}
@@ -169,7 +188,7 @@ INT32 R_SkinAvailable(const char *name)
for (i = 0; i < numskins; i++)
{
if (fasticmp(skins[i]->name, name))
if (fasticmp(skins[i].name, name))
return i;
}
@@ -184,7 +203,7 @@ INT32 R_AnySkinAvailable(const char *name)
for (i = 0; i < numallskins; i++)
{
if (fasticmp(allskins[i]->name, name))
if (fasticmp(allskins[i].name, name))
return i;
}
@@ -199,7 +218,7 @@ INT32 R_LocalSkinAvailable(const char *name, boolean local)
{
for (i = 0; i < numlocalskins; i++)
{
if (fasticmp(localskins[i]->name, name))
if (fasticmp(localskins[i].name, name))
return i;
}
@@ -217,7 +236,7 @@ boolean SetPlayerSkin(INT32 playernum, const char *skinname)
for (i = 0; i < numskins; i++)
{
// search in the skin list
if (fasticmp(skins[i]->name, skinname))
if (fasticmp(skins[i].name, skinname))
{
SetPlayerSkinByNum(playernum, i);
return true;
@@ -243,14 +262,14 @@ void SetLocalPlayerSkin(INT32 playernum, const char *skinname, consvar_t *cvar)
for (i = 0; i < numlocalskins; i++)
{
// search in the localskin list
if (fasticmp(localskins[i]->name, skinname))
if (fasticmp(localskins[i].name, skinname))
{
player->localskin = 1 + i;
player->skinlocal = true;
if (player->mo)
{
player->mo->localskin = localskins[i];
player->mo->localskin = &localskins[i];
player->mo->skinlocal = true;
}
@@ -261,14 +280,14 @@ void SetLocalPlayerSkin(INT32 playernum, const char *skinname, consvar_t *cvar)
for (i = 0; i < numskins; i++)
{
// search in the skin list
if (fasticmp(skins[i]->name, skinname))
if (fasticmp(skins[i].name, skinname))
{
player->localskin = 1 + i;
player->skinlocal = false;
if (player->mo)
{
player->mo->localskin = skins[i];
player->mo->localskin = &skins[i];
player->mo->skinlocal = false;
}
@@ -293,9 +312,9 @@ setcvar:
{
if (player->localskin > 0)
{
skin_t *lskin = R_GetSkinArray(player->skinlocal)[player->localskin-1];
CV_StealthSet(&cv_fakelocalskin, lskin->name);
CV_StealthSet(cvar, lskin->name);
CV_StealthSet(&cv_fakelocalskin, K_GetSkinArray(player->skinlocal)[player->localskin-1].name);
CV_StealthSet(cvar, K_GetSkinArray(player->skinlocal)[player->localskin-1].name);
}
else
{
@@ -310,12 +329,10 @@ setcvar:
void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
{
player_t *player = &players[playernum];
skin_t *skin;
skin_t *skin = &skins[skinnum];
if (skinnum >= 0 && skinnum < numskins) // Make sure it exists!
{
skin = skins[skinnum];
player->skin = skinnum;
if (player->mo)
@@ -383,8 +400,8 @@ static int skinSortFunc(const void *a, const void *b) // tbh i have no clue what
int diff = 0;
const skinnum_t val_a = *(const skinnum_t *)a;
const skinnum_t val_b = *(const skinnum_t *)b;
const skin_t *in1 = skins[val_a];
const skin_t *in2 = skins[val_b];
const skin_t *in1 = &skins[val_a];
const skin_t *in2 = &skins[val_b];
// return (strcmp(in1->realname, in2->realname) < 0) || (strcmp(in1->realname, in2->realname) ==);
@@ -471,7 +488,7 @@ void R_AddSkins(UINT16 wadnum, boolean local)
char *stoken;
char *value;
size_t size;
skin_t *skin = NULL;
skin_t *skin;
boolean hudname, realname;
#define lnumskins (local ? numlocalskins : numskins)
@@ -485,18 +502,16 @@ void R_AddSkins(UINT16 wadnum, boolean local)
// advance by default
lastlump = lump + 1;
// gotta keep this for vanilla compat reasons
if (!local && numskins >= MAXSKINS)
{
CONS_Alert(CONS_WARNING, M_GetText("Unable to add skin, too many characters are loaded (%d maximum)\n"), MAXSKINS);
continue; // so we know how many skins couldn't be added
}
/* if (local && numlocalskins >= MAXLOCALSKINS)
if (local && numlocalskins >= MAXLOCALSKINS)
{
CONS_Alert(CONS_WARNING, M_GetText("Unable to add localskin, too many localskins are loaded (%d maximum)\n"), MAXLOCALSKINS);
continue; // so we know how many skins couldn't be added
} */
}
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lump);
@@ -509,19 +524,8 @@ void R_AddSkins(UINT16 wadnum, boolean local)
buf2[size] = '\0';
// set defaults
if (!local)
{
skins = Z_Realloc(skins, sizeof(skin_t *) * (numskins + 1), PU_STATIC, NULL);
}
else
{
localskins = Z_Realloc(localskins, sizeof(skin_t *) * (numlocalskins + 1), PU_STATIC, NULL);
}
skin = R_GetSkinArray(local)[lnumskins] = Z_Calloc(sizeof(skin_t), PU_STATIC, NULL);
Sk_SetDefaultValue(skin);
skin->skinnum = lnumskins;
skin->allskinnum = numallskins;
skin = &K_GetSkinArray(local)[lnumskins];
Sk_SetDefaultValue(skin, local);
skin->wadnum = wadnum;
hudname = realname = false;
@@ -773,19 +777,24 @@ void R_AddSkins(UINT16 wadnum, boolean local)
//R_FlushTranslationColormapCache();
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
#ifdef SKINVALUES
(local ? localskin_cons_t : skin_cons_t)[lnumskins].value = lnumskins;
(local ? localskin_cons_t : skin_cons_t)[lnumskins].strvalue = skin->name;
#endif
if (!local)
{
// Update the forceskin possiblevalues
Forceskin_cons_t[numskins+1].value = numskins;
Forceskin_cons_t[numskins+1].strvalue = skins[numskins]->name;
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name;
skin->localskin = false;
ST_LoadFaceGraphics(skin);
skin->localnum = numskins;
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, numskins);
}
else
{
skin->localskin = true;
ST_LoadFaceGraphics(skin);
skin->localnum = numlocalskins;
ST_LoadLocalFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, numlocalskins);
}
#ifdef HWRENDER
@@ -801,8 +810,7 @@ void R_AddSkins(UINT16 wadnum, boolean local)
skinsorted[numskins] = numskins;
}
allskins = Z_Realloc(allskins, sizeof(skin_t*) * (numallskins + 1), PU_STATIC, NULL);
allskins[numallskins] = R_GetSkinArray(local)[lnumskins];
allskins[numallskins] = K_GetSkinArray(local)[lnumskins];
local ? numlocalskins++ : numskins++;
numallskins++;
@@ -812,50 +820,3 @@ void R_AddSkins(UINT16 wadnum, boolean local)
return;
}
// Helper functions for skin stuff
//
// returns the skin array to use
// accounts for localskins
//
skin_t **R_GetSkinArray(boolean local)
{
return local ? localskins : skins;
}
//
// returns the players skinnumber
// accounts for localskins
//
INT32 R_GetPlayerSkinNum(player_t *player)
{
return player->localskin ? (player->localskin - 1) : player->skin;
}
//
// returns the players skin
// accounts for localskins
//
skin_t *R_GetPlayerSkin(player_t *player)
{
return R_GetSkinArray(player->skinlocal)[R_GetPlayerSkinNum(player)];
}
//
// returns the mobj skinnumber
// accounts for localskins
//
INT32 R_GetMobjSkinNum(const mobj_t *mobj)
{
return mobj->localskin ? mobj->localskin->skinnum : mobj->skin->skinnum;
}
//
// returns the mobjs skin
// accounts for localskins
//
skin_t *R_GetMobjSkin(const mobj_t *mobj)
{
return mobj->localskin ? mobj->localskin : mobj->skin;
}
+13 -26
View File
@@ -16,7 +16,6 @@
#ifndef __R_SKINS__
#define __R_SKINS__
#include "doomtype.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -25,10 +24,6 @@ extern "C" {
#include "sounds.h"
#include "r_patch.h"
#ifdef HWRENDER
#include "hardware/hw_md2.h"
#endif
// "Left" and "Right" character symbols for additional rotation functionality
#define ROT_L ('L' - '0')
#define ROT_R ('R' - '0')
@@ -40,7 +35,7 @@ extern "C" {
#define DEFAULTSKIN3 "knuckles" // third player
#define DEFAULTSKIN4 "eggman" // fourth player
typedef struct skin_s
typedef struct
{
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
spritedef_t spritedef;
@@ -53,17 +48,12 @@ typedef struct skin_s
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps
patch_t *facerankprefix; // ranking
patch_t *facewantprefix; // wanted
patch_t *facemmapprefix; // minimap
// SRB2kart
UINT8 kartspeed;
UINT8 kartweight;
//
// Definable color translation table
UINT8 **translationtablecache;
UINT8 starttranscolor;
UINT8 prefcolor;
fixed_t highresscale; // scale of highres, default is 0.5
@@ -71,13 +61,8 @@ typedef struct skin_s
// specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
#ifdef HWRENDER
md2_t playermodel;
#endif
boolean localskin;
skinnum_t skinnum;
UINT16 allskinnum;
INT32 localnum;
} skin_t;
extern CV_PossibleValue_t Forceskin_cons_t[];
@@ -85,14 +70,14 @@ extern CV_PossibleValue_t Forceskin_cons_t[];
extern INT32 numskins;
extern INT32 numlocalskins;
extern INT32 numallskins;
extern skin_t **skins;
extern skin_t **localskins;
extern skin_t **allskins;
extern skin_t skins[MAXSKINS];
extern skinnum_t skinstats[9][9][MAXSKINS];
extern skinnum_t skinstatscount[9][9];
extern skinnum_t skinsorted[MAXSKINS];
extern skin_t localskins[MAXLOCALSKINS];
extern skin_t allskins[MAXSKINS+MAXLOCALSKINS];
//faB: find sprites in wadfile, replace existing, add new ones
// (only sprites from namelist are added or replaced)
void R_AddSpriteDefs(UINT16 wadnum);
@@ -105,11 +90,13 @@ INT32 R_AnySkinAvailable(const char *name);
INT32 R_LocalSkinAvailable(const char *name, boolean local);
// had to move those here Zzz...
skin_t **R_GetSkinArray(boolean local);
skin_t *R_GetPlayerSkin(player_t *player);
INT32 R_GetPlayerSkinNum(player_t *player);
INT32 R_GetMobjSkinNum(const mobj_t *mobj);
skin_t *R_GetMobjSkin(const mobj_t *mobj);
INT32 K_GetSkinNum(player_t *player);
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local);
INT32 K_GetMobjLocalSkinNum(const skin_t *skin, const skin_t *localskin, boolean local);
skin_t *K_GetPlayerSkin(player_t *player);
skin_t *K_GetMobjSkin(const mobj_t *mobj);
patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum);
skin_t *K_GetSkinArray(boolean local);
void sortSkinGrid(void);
+21 -6
View File
@@ -1062,7 +1062,12 @@ static void R_SplitSprite(vissprite_t *sprite)
{
INT32 lightnum = R_GetSoftLightlevel(*sector->lightlist[i].lightlevel);
spritelights = R_GetWallLight(lightnum);
if (lightnum < 0)
spritelights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
spritelights = scalelight[LIGHTLEVELS-1];
else
spritelights = scalelight[lightnum];
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
@@ -1276,7 +1281,7 @@ static void R_ProjectSprite(mobj_t *thing)
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || thing->temprollangle || sliprollrotate);
#endif
sprskin = R_GetMobjSkin(thing);
sprskin = K_GetMobjSkin(thing);
//Fab : 02-08-98: 'skin' override spritedef currently used for skin
if (sprskin && thing->sprite == SPR_PLAY)
@@ -1740,7 +1745,12 @@ static void R_ProjectSprite(mobj_t *thing)
}
}
lights_array = R_GetWallLight(lightnum);
if (lightnum < 0)
lights_array = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
lights_array = scalelight[LIGHTLEVELS-1];
else
lights_array = scalelight[lightnum];
}
// store information in a vissprite
@@ -2077,11 +2087,16 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
if (!sec->numlights)
{
if (sec->heightsec == -1)
lightlevel = sec->lightlevel;
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
lightnum = R_GetSoftLightlevel(lightlevel);
spritelights = R_GetWallLight(lightnum);
if (lightnum < 0)
spritelights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
spritelights = scalelight[LIGHTLEVELS-1];
else
spritelights = scalelight[lightnum];
}
// Handle all things in sector.
+1 -1
View File
@@ -529,7 +529,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx->skinsound != -1 && origin && origin->skin)
{
// redirect player sound to the sound in the skin table
sfx_id = R_GetMobjSkin(origin)->soundsid[sfx->skinsound];
sfx_id = K_GetMobjSkin(origin)->soundsid[sfx->skinsound];
sfx = &S_sfx[sfx_id];
}
+3 -8
View File
@@ -233,25 +233,20 @@ if(${SDL2_FOUND})
-DHAVE_THREADS
)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
endif()
if(NOT SRB2_CONFIG_MUMBLE)
target_compile_options(SRB2SDL2 PRIVATE -DNOMUMBLE)
endif()
+108 -38
View File
@@ -97,9 +97,11 @@ static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_none;
#ifdef HWRENDER
unsigned msaa = 0;
// Eee probably the way i organize it isn't best ><
// Just don't know where do i put declaration and "implementation"
unsigned msaa = 0;
boolean a2c = false;
#endif
static void KeyboardLayout_OnChange(void)
@@ -113,6 +115,10 @@ consvar_t cv_keyboardlayout = {"keyboardlayout", "Default US", CV_SAVE|CV_CALL,
static void Impl_SetVsync(void);
static INT32 desktopwidth = 0, desktopheight = 0;
static void I_CheckDesktopRes(void);
// synchronize page flipping with screen refresh
consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Impl_SetVsync, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -191,6 +197,10 @@ static INT32 custom_height = 0;
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
static void Impl_SetWindowIcon(void);
#ifdef USE_FBO_OGL
boolean downsample = false;
#endif
static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
{
if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_Z)
@@ -508,11 +518,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
return;
}
if (windowmoved)
if (windowmoved && rendermode == render_opengl)
{
I_CheckDesktopRes();
#ifdef USE_FBO_OGL
if (rendermode == render_opengl)
I_CheckDownSampleState(false);
I_DownSample();
#endif
windowmoved = SDL_FALSE;
}
@@ -1219,7 +1229,9 @@ static void VID_Command_ModeList_f(void)
// List windowed modes
INT32 i = 0;
CONS_Printf("NOTE: Under SDL2, all modes are supported on all platforms.\n");
CONS_Printf("NOTE: Under SDL2, all modes are supported on all platforms.\n"
"Under opengl, fullscreen only supports native desktop resolution.\n"
"Under software, the mode is stretched up to desktop resolution.\n");
for (i = 0; i < MAXWINMODES; i++)
{
@@ -1245,41 +1257,78 @@ static void VID_Command_Mode_f (void)
setmodeneeded = modenum+1; // request vid mode change
}
#ifdef USE_FBO_OGL
static boolean vid_downsampling = false;
boolean I_IsDownsampling(void)
// Get the desktop resolution from the current display the gamewindow resides on
static void I_CheckDesktopRes(void)
{
return vid_downsampling;
}
int currentDisplayIndex = -1;
SDL_DisplayMode curmode;
void I_CheckDownSampleState(boolean forcerefresh)
{
// no fbo support so we dont care
if (!supportFBO)
desktopwidth = 0;
desktopheight = 0;
currentDisplayIndex = SDL_GetWindowDisplayIndex(window);
// No valid index
if (currentDisplayIndex < 0)
{
vid_downsampling = false;
return;
}
// no sense to do this crap if we cant benefit from it
boolean newdownsamplestate = false;
if (cv_glframebuffer.value && (cv_glscreentextures.value == 2))
if (SDL_GetDesktopDisplayMode(currentDisplayIndex, &curmode) != 0)
{
int sdlw, sdlh;
SDL_GetWindowSize(window, &sdlw, &sdlh);
if (vid.width > sdlw || vid.height > sdlh)
newdownsamplestate = true;
return;
}
// state changed or fbo was toggled
if (vid_downsampling != newdownsamplestate || forcerefresh)
{
//printf("downsample changed from %d to %d\n", vid_downsampling, newdownsamplestate);
// needs to be reset before refreshing the gl surface!
vid_downsampling = newdownsamplestate;
desktopwidth = curmode.w;
desktopheight = curmode.h;
}
// Check if the game resolution matches the desktop resolution
boolean I_CheckNativeRes(void)
{
return (vid.width == desktopwidth && vid.height == desktopheight);
}
#ifdef USE_FBO_OGL
void RefreshOGLSDLSurface(void)
{
if (rendermode == render_opengl)
OglSdlSurface(vid.width, vid.height);
}
void I_DownSample(void)
{
boolean needrefresh = false;
if (!cv_glframebuffer.value || !supportFBO || (cv_glscreentextures.value == 0)) // no sense to do this crap if we cant benefit from it
{
downsample = false;
return;
}
if (I_CheckNativeRes() && (downsample == true))
{
downsample = false;
RefreshOGLSDLSurface();
return;
}
if ((vid.width > desktopwidth) || (vid.height > desktopheight)) //check if current resolution is higher than current display resolution
{
downsample = true;
needrefresh = true;
}
else if (downsample == true)
{
downsample = false;
needrefresh = true;
}
if (needrefresh)
{
RefreshOGLSDLSurface();
needrefresh = false;
}
}
#endif
@@ -1311,10 +1360,9 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
// Reposition window only in windowed mode
SDL_SetWindowSize(window, width, height);
const int windowpos = SDL_GetWindowDisplayIndex(window);
SDL_SetWindowPosition(window,
SDL_WINDOWPOS_CENTERED_DISPLAY(windowpos),
SDL_WINDOWPOS_CENTERED_DISPLAY(windowpos)
SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window)),
SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window))
);
}
}
@@ -1334,8 +1382,9 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
#ifdef HWRENDER
if (rendermode == render_opengl)
{
I_CheckDesktopRes();
#ifdef USE_FBO_OGL
I_CheckDownSampleState(false);
I_DownSample();
#endif
OglSdlSurface(vid.width, vid.height);
}
@@ -1531,7 +1580,7 @@ void VID_PrepareModeList(void)
static UINT32 refresh_rate;
static UINT32 VID_GetRefreshRate(void)
{
int index;
int index = SDL_GetWindowDisplayIndex(window);
SDL_DisplayMode m;
if (SDL_WasInit(SDL_INIT_VIDEO) == 0)
@@ -1540,8 +1589,6 @@ static UINT32 VID_GetRefreshRate(void)
return 0;
}
index = SDL_GetWindowDisplayIndex(window);
if (SDL_GetDesktopDisplayMode(index, &m) != 0)
{
// Error has occurred.
@@ -1778,6 +1825,7 @@ void I_StartupGraphics(void)
rendermode = render_opengl;
msaa = 0; boolean msaa_set = false;
a2c = false; boolean a2c_set = false;
// MSAA antialiasing
if (M_CheckParm("-msaa") && M_IsNextParm())
@@ -1789,6 +1837,16 @@ void I_StartupGraphics(void)
}
}
if (M_CheckParm("-a2c"))
{
a2c = true;
a2c_set = true;
}
else if (M_CheckParm("-noa2c"))
{
a2c_set = true;
}
{
char line[16];
char * word;
@@ -1832,10 +1890,19 @@ void I_StartupGraphics(void)
}
else
{
CONS_Printf("Using last known MSAA value: %u\n", msaa);
CONS_Printf("Using last know MSAA value: %u\n", msaa);
}
}
}
if (!a2c_set)
{
if (fasticmp(word, "a2c"))
{
a2c = true;
CONS_Printf("Using a2c because it was specified to be used earlier\n");
}
}
}
fclose(file);
@@ -1870,6 +1937,9 @@ void I_StartupGraphics(void)
#ifdef HWRENDER
fprintf(file, "msaa %u\n", msaa);
if (a2c)
fputs("a2c\n", file);
#endif
fclose(file);
}
+13 -7
View File
@@ -65,7 +65,7 @@ PFNglGetString pglGetString;
#ifdef USE_FBO_OGL
boolean UseScreenFBO(void)
{
return (supportFBO && cv_glframebuffer.value && (cv_glscreentextures.value == 2) && (cv_glframebuffer.value == 2 || I_IsDownsampling()));
return (supportFBO && cv_glframebuffer.value && downsample);
}
#endif
@@ -203,9 +203,9 @@ boolean OglSdlSurface(INT32 w, INT32 h)
#ifdef USE_FBO_OGL
if (UseScreenFBO())
GL_FBO_Enable();
GL_Framebuffer_Enable();
else
GL_FBO_Disable();
GL_Framebuffer_Disable();
#endif
if (!first_init)
@@ -225,6 +225,7 @@ boolean OglSdlSurface(INT32 w, INT32 h)
void OglSdlFinishUpdate(SDL_Window *window)
{
int sdlw, sdlh;
#ifdef USE_FBO_OGL
const boolean usefbo = UseScreenFBO();
#endif
@@ -234,7 +235,9 @@ void OglSdlFinishUpdate(SDL_Window *window)
#ifdef USE_FBO_OGL
if (usefbo)
GL_FBO_BindMainFrameBuffer();
{
GL_Framebuffer_Unbind();
}
#endif
if (HWR_ShouldUsePaletteRendering())
@@ -252,7 +255,9 @@ void OglSdlFinishUpdate(SDL_Window *window)
#ifdef USE_FBO_OGL
if (usefbo)
GL_FBO_Enable();
{
GL_Framebuffer_Enable();
}
#endif
SDL_GL_SwapWindow(window);
@@ -261,10 +266,11 @@ void OglSdlFinishUpdate(SDL_Window *window)
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
// effects that want to take the old screen can do so after this
// well we dont need it on native res it seems
#ifdef USE_FBO_OGL
if (!usefbo && (realwidth != sdlw || realheight != sdlh)) // not needed if fbo is in use
if ((!I_CheckNativeRes() && !usefbo) || WipeInAction)
#else
if (realwidth != sdlw || realheight != sdlh) // this is not needed if the render size matches window size
if (!I_CheckNativeRes() || WipeInAction)
#endif
HWR_DrawScreenFinalTexture(realwidth, realheight);
}
+42 -7
View File
@@ -60,6 +60,22 @@ tic_t directortoggletimer = 0;
// STATUS BAR DATA
//
patch_t *facerankprefix[MAXSKINS] = {}; // ranking
patch_t *facewantprefix[MAXSKINS] = {}; // wanted
patch_t *facemmapprefix[MAXSKINS] = {}; // minimap
patch_t *localfacerankprefix[MAXLOCALSKINS] = {}; // ranking
patch_t *localfacewantprefix[MAXLOCALSKINS] = {}; // wanted
patch_t *localfacemmapprefix[MAXLOCALSKINS] = {}; // minimap
/*char *facerankprefix_name[MAXSKINS]; // ranking
char *facewantprefix_name[MAXSKINS]; // wanted
char *facemmapprefix_name[MAXSKINS]; // minimap
char *localfacerankprefix_name[MAXLOCALSKINS]; // ranking
char *localfacewantprefix_name[MAXLOCALSKINS]; // wanted
char *localfacemmapprefix_name[MAXLOCALSKINS]; // minimap*/
// ------------------------------------------
// status bar overlay
// ------------------------------------------
@@ -227,11 +243,30 @@ void ST_LoadGraphics(void)
}
// made separate so that skins code can reload custom face graphics
void ST_LoadFaceGraphics(skin_t *skin)
void ST_LoadFaceGraphics(char *rankstr, char *wantstr, char *mmapstr, INT32 skinnum)
{
skin->facerankprefix = W_CachePatchName(skin->facerank, PU_HUDGFX);
skin->facewantprefix = W_CachePatchName(skin->facewant, PU_HUDGFX);
skin->facemmapprefix = W_CachePatchName(skin->facemmap, PU_HUDGFX);
facerankprefix[skinnum] = W_CachePatchName(rankstr, PU_HUDGFX);
facewantprefix[skinnum] = W_CachePatchName(wantstr, PU_HUDGFX);
facemmapprefix[skinnum] = W_CachePatchName(mmapstr, PU_HUDGFX);
/*facerankprefix_name[skinnum] = rankstr;
facewantprefix_name[skinnum] = wantstr;
facemmapprefix_name[skinnum] = mmapstr;*/
}
void ST_LoadLocalFaceGraphics(char *rankstr, char *wantstr, char *mmapstr, INT32 skinnum)
{
localfacerankprefix[skinnum] = W_CachePatchName(rankstr, PU_HUDGFX);
localfacewantprefix[skinnum] = W_CachePatchName(wantstr, PU_HUDGFX);
localfacemmapprefix[skinnum] = W_CachePatchName(mmapstr, PU_HUDGFX);
/*localfacerankprefix_name[skinnum] = rankstr;
localfacewantprefix_name[skinnum] = wantstr;
localfacemmapprefix_name[skinnum] = mmapstr;*/
//CONS_Printf("Added rank prefix %s\n", rankstr);
//CONS_Printf("Added want prefix %s\n", wantstr);
//CONS_Printf("Added mmap prefix %s\n", mmapstr);
}
void ST_ReloadSkinFaceGraphics(void)
@@ -239,10 +274,10 @@ void ST_ReloadSkinFaceGraphics(void)
INT32 i;
for (i = 0; i < numskins; i++)
ST_LoadFaceGraphics(skins[i]);
ST_LoadFaceGraphics(skins[i].facerank, skins[i].facewant, skins[i].facemmap, i);
for (i = 0; i < numlocalskins; i++)
ST_LoadFaceGraphics(localskins[i]);
ST_LoadLocalFaceGraphics(localskins[i].facerank, localskins[i].facewant, localskins[i].facemmap, i);
}
static inline void ST_InitData(void)
@@ -375,7 +410,7 @@ static void ST_drawDebugInfo(void)
}
if (cv_debug & DBG_MEMORY)
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TotalUsage()>>10)));
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
}
static void ST_drawLevelTitle(void)
+10 -1
View File
@@ -58,7 +58,8 @@ void ST_UnloadGraphics(void);
void ST_LoadGraphics(void);
// face load graphics, called when skin changes
void ST_LoadFaceGraphics(skin_t *skin);
void ST_LoadFaceGraphics(char *rankstr, char *wantstr, char *mmapstr, INT32 playernum);
void ST_LoadLocalFaceGraphics(char *rankstr, char *wantstr, char *mmapstr, INT32 playernum);
void ST_ReloadSkinFaceGraphics(void);
// return if player a is in the same team as player b
@@ -75,6 +76,14 @@ extern UINT8 stplyrnum;
extern lumpnum_t st_borderpatchnum;
// patches, also used in intermission
extern patch_t *facerankprefix[MAXSKINS]; // ranking
extern patch_t *facewantprefix[MAXSKINS]; // wanted
extern patch_t *facemmapprefix[MAXSKINS]; // minimap
extern patch_t *localfacerankprefix[MAXLOCALSKINS]; // ranking
extern patch_t *localfacewantprefix[MAXLOCALSKINS]; // wanted
extern patch_t *localfacemmapprefix[MAXLOCALSKINS]; // minimap
/** HUD location information (don't move this comment)
*/
typedef struct
+2 -2
View File
@@ -1261,11 +1261,11 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
//
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
{
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum]->flags & SF_HIRES))
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_PATCH)); // Draw a star
else
{ // Find front angle of the first waiting frame of the character's actual sprites
spriteframe_t *sprframe = &skins[skinnum]->spritedef.spriteframes[2 & FF_FRAMEMASK];
spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
+7 -8
View File
@@ -396,11 +396,6 @@ FUNCINLINE static ATTRINLINE UINT32 W_HashLumpName(const char *name)
return FNV1a_HashLowercaseString(name);
}
FUNCINLINE static ATTRINLINE UINT32 W_HashLumpNameLen(const char *name, size_t len)
{
return FNV1a_QuickCaseHash(name, len);
}
/** Detect a file type.
* \todo Actually detect the wad/pkzip headers and whatnot, instead of just checking the extensions.
*/
@@ -1100,14 +1095,18 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum)
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[8 + 1];
UINT32 hash;
size_t namelen;
if (!TestValidLump(wad, 0))
return INT16_MAX;
namelen = strnlen(name, 8); // :chaosleep:
hash = W_HashLumpNameLen(name, namelen);
memset(uname, 0, sizeof(uname));
strncpy(uname, name, sizeof(uname)-1);
strupr(uname);
namelen = strlen(uname);
hash = W_HashLumpName(uname);
//
// scan forward
@@ -1122,7 +1121,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
if (lump_p->namelength == namelen
&& lump_p->hash.name == hash
&& !strncasecmp(lump_p->name, name, namelen))
&& !memcmp(lump_p->name, uname, sizeof(uname) - 1))
return i;
}
}
+2 -1
View File
@@ -1190,7 +1190,8 @@ void Y_VoteDrawer(void)
if (player->skincolor)
{
UINT8 *colormap = R_GetTranslationColormap(player->skin, player->skincolor, GTC_CACHE);
patch_t *faceprefix = K_GetFacePrefix(player, R_GetPlayerSkinNum(player));
patch_t *faceprefix = K_GetFacePrefix(player, K_GetSkinNum(player));
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix, colormap);
+60 -91
View File
@@ -75,7 +75,7 @@ typedef struct memblock_s
#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - ALIGNPAD - sizeof(memblock_t))
// both the head and tail of the zone memory block list
static memblock_t headlist[NUM_PURGETAGS];
static memblock_t head;
static constexpr size_t kLevelLargePoolBlockSize = sizeof(mobj_t);
static constexpr size_t kLevelMedPoolBlockSize = sizeof(precipmobj_t);
@@ -107,14 +107,10 @@ static void Command_Memdump_f(void);
void Z_Init(void)
{
size_t total, memfree;
size_t i;
memset(&headlist, 0x00, sizeof(headlist));
memset(&head, 0x00, sizeof(head));
for (i = 0; i < NUM_PURGETAGS; i++)
{
headlist[i].next = headlist[i].prev = &headlist[i];
}
head.next = head.prev = &head;
memfree = I_GetFreeMem(&total)>>20;
@@ -208,7 +204,7 @@ static void *xm(size_t size)
if (p == NULL)
{
// Oh crumbs: we're out of heap. Try purging the cache and reallocating.
Z_FreeTags(PU_PURGELEVEL, NUM_PURGETAGS-1);
Z_FreeTags(PU_PURGELEVEL, INT32_MAX);
p = malloc(padedsize);
if (p == NULL)
@@ -249,9 +245,9 @@ void *Z_Malloc(size_t size, INT32 tag, void *user)
ptr = MEMORY(block);
I_Assert((intptr_t)ptr % alignof (max_align_t) == 0);
block->next = headlist[tag].next;
block->prev = &headlist[tag];
headlist[tag].next = block;
block->next = head.next;
block->prev = &head;
head.next = block;
block->next->prev = block;
block->tag = tag;
@@ -415,7 +411,6 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
#endif
{
memblock_t *block, *next;
INT32 i;
#ifdef ZDEBUG
Z_CheckHeap2(file, line);
@@ -432,13 +427,11 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
g_level_tiny_pool.release();
}
for (i = lowtag; i <= hightag; i++)
for (block = head.next; block != &head; block = next)
{
for (block = headlist[i].next; block != &headlist[i]; block = next)
{
next = block->next; // get link before freeing
next = block->next; // get link before freeing
if (block->tag >= lowtag && block->tag <= hightag)
Z_Free(MEMORY(block));
}
}
}
@@ -451,20 +444,18 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
{
memblock_t *block, *next;
INT32 i;
if (!iterfunc)
I_Error("Z_IterateTags: no iterator function was given");
for (i = lowtag; i <= hightag; i++)
for (block = head.next; block != &head; block = next)
{
for (block = headlist[i].next; block != &headlist[i]; block = next)
{
next = block->next; // get link before possibly freeing
next = block->next; // get link before possibly freeing
if (block->tag >= lowtag && block->tag <= hightag)
{
void *mem = MEMORY(block);
boolean free = iterfunc(mem);
if (free)
Z_Free(mem);
}
@@ -495,7 +486,7 @@ void Z_CheckMemCleanup(void)
if (nextcleanup-- == 0)
{
nextcleanup = CLEANUPCOUNT;
Z_FreeTags(PU_PURGELEVEL, NUM_PURGETAGS-1);
Z_FreeTags(PU_PURGELEVEL, INT32_MAX);
}
}
@@ -513,7 +504,6 @@ void Z_CheckHeap(INT32 tag)
{
memblock_t *block;
UINT32 blocknumon = 0;
size_t j;
void *given;
#ifndef ZDEBUG
@@ -530,47 +520,40 @@ void Z_CheckHeap(INT32 tag)
blocknumon, block->ownerfile, block->ownerline, msg)
#endif
for (j = 0; j < NUM_PURGETAGS; j++)
for (block = head.next; block != &head; block = block->next)
{
for (block = headlist[j].next; block != &headlist[j]; block = block->next)
{
blocknumon++;
given = MEMORY(block);
blocknumon++;
given = MEMORY(block);
#ifdef ZDEBUG2
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
blocknumon, block->ownerfile, block->ownerline);
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
blocknumon, block->ownerfile, block->ownerline);
#endif
#ifdef HAVE_VALGRIND
if (RUNNING_ON_VALGRIND && !VALGRIND_MEMPOOL_EXISTS(block))
{
HeapError(" should not exist");
}
#endif
if (block->user != NULL && *(block->user) != given)
{
HeapError(" doesn't have a proper user");
}
if (block->next->prev != block)
{
HeapError(" lacks proper backlink");
}
if (block->prev->next != block)
{
HeapError(" lacks proper forward link");
}
#ifdef PARANOIA
if (block->id != ZONEID)
{
HeapError(" has the wrong ID");
}
#endif
if (block->tag != j)
{
HeapError(va(" block is contained in the wrong headlist (got: %d expected: %s)", block->tag, sizeu1(j)));
}
if (RUNNING_ON_VALGRIND && !VALGRIND_MEMPOOL_EXISTS(block))
{
HeapError(" should not exist");
}
#endif
if (block->user != NULL && *(block->user) != given)
{
HeapError(" doesn't have a proper user");
}
if (block->next->prev != block)
{
HeapError(" lacks proper backlink");
}
if (block->prev->next != block)
{
HeapError(" lacks proper forward link");
}
#ifdef PARANOIA
if (block->id != ZONEID)
{
HeapError(" has the wrong ID");
}
#endif
}
}
@@ -607,14 +590,6 @@ void Z_ChangeTag(void *ptr, INT32 tag)
I_Error("Internal memory management error: "
"tried to make block purgable but it has no owner");
block->prev->next = block->next;
block->next->prev = block->prev;
block->next = headlist[tag].next;
block->prev = &headlist[tag];
headlist[tag].next = block;
block->next->prev = block;
block->tag = tag;
}
@@ -665,21 +640,18 @@ void Z_SetUser(void *ptr, void **newuser)
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag)
{
size_t cnt = 0;
memblock_t *head; // why was this called rover before?????
INT32 i;
memblock_t *rover;
for (i = lowtag; i <= hightag; i++)
for (rover = head.next; rover != &head; rover = rover->next)
{
for (head = headlist[i].next; head != &headlist[i]; head = head->next)
{
cnt += head->size + sizeof *head;
}
if (rover->tag < lowtag || rover->tag > hightag)
continue;
cnt += rover->size + sizeof(memblock_t);
}
return cnt;
}
// -----------------------
// Miscellaneous functions
// -----------------------
@@ -693,8 +665,8 @@ static void Command_Memfree_f(void)
Z_CheckHeap(-1);
CONS_Printf("\x82%s", M_GetText("Memory Info\n"));
CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1((Z_TotalUsage()>>10) + LUA_MemoryUsage()));
CONS_Printf(M_GetText("Lua : %7s KB\n"), sizeu1(LUA_MemoryUsage())); // No longer uses z_zone memory but for consistency keep it here
CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10));
CONS_Printf(M_GetText("Lua : %7s KB\n"), sizeu1(Z_TagUsage(PU_LUA)>>10));
CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10));
CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10));
CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10));
@@ -708,7 +680,7 @@ static void Command_Memfree_f(void)
CONS_Printf(M_GetText("Level (pooled) : %7s KB\n"), sizeu1(Z_LevelPoolUsage()>>10));
CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10));
CONS_Printf(M_GetText("All purgable : %7s KB\n"),
sizeu1(Z_TagsUsage(PU_PURGELEVEL, NUM_PURGETAGS-1)>>10));
sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10));
#ifdef HWRENDER
if (rendermode == render_opengl)
@@ -737,24 +709,21 @@ static void Command_Memfree_f(void)
static void Command_Memdump_f(void)
{
memblock_t *block;
INT32 mintag = 0, maxtag = NUM_PURGETAGS-1;
INT32 check;
INT32 mintag = 0, maxtag = INT32_MAX;
INT32 i;
if ((check = COM_CheckParm("-min")))
mintag = atoi(COM_Argv(check + 1));
if ((i = COM_CheckParm("-min")))
mintag = atoi(COM_Argv(i + 1));
if ((check = COM_CheckParm("-max")))
maxtag = atoi(COM_Argv(check + 1));
if ((i = COM_CheckParm("-max")))
maxtag = atoi(COM_Argv(i + 1));
for (i = mintag; i <= maxtag; i++)
{
for (block = headlist[i].next; block != &headlist[i]; block = block->next)
for (block = head.next; block != &head; block = block->next)
if (block->tag >= mintag && block->tag <= maxtag)
{
const char *filename = strrchr(block->ownerfile, PATHSEP[0]);
CONS_Printf("[%3d] %s (%s) bytes @ %s:%d tag: %d (%d)\n", block->tag, sizeu1(block->size + sizeof(memblock_t)), sizeu2(block->size), filename ? filename + 1 : block->ownerfile, block->ownerline, block->tag, i);
CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size + sizeof(memblock_t)), sizeu2(block->size), filename ? filename + 1 : block->ownerfile, block->ownerline);
}
}
}
#endif
+25 -28
View File
@@ -42,42 +42,39 @@ extern "C" {
enum
{
// Tags < PU_LEVEL are not purged until freed explicitly.
PU_STATIC = 0, // static entire execution time
PU_LUA, // static entire execution time -- used by lua so it doesn't get caught in loops forever
PU_PERFSTATS, // static between changes to ps_samplesize cvar
PU_STATIC = 1, // static entire execution time
PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever
PU_PERFSTATS = 3, // static between changes to ps_samplesize cvar
PU_SOUND, // static while playing
PU_MUSIC, // static while playing
PU_SOUND = 11, // static while playing
PU_MUSIC = 12, // static while playing
PU_PATCH, // static entire execution time
PU_PATCH_LOWPRIORITY, // lower priority patch, static until level exited
PU_PATCH_ROTATED, // rotated patch, static until level exited or WAD added
PU_PATCH_DATA, // patch data, lifetime depends on the patch that owns it
PU_SPRITE, // sprite patch, static until WAD added
PU_HUDGFX, // HUD patch, static until WAD added
PU_PATCH = 14, // static entire execution time
PU_PATCH_LOWPRIORITY = 15, // lower priority patch, static until level exited
PU_PATCH_ROTATED = 16, // rotated patch, static entire execution time
PU_PATCH_DATA = 17, // patch data, lifetime depends on the patch that owns it
PU_SPRITE = 18, // sprite patch, static until WAD added
PU_HUDGFX = 19, // HUD patch, static until WAD added
PU_HWRPATCHINFO, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP, // Hardware GLMipmap_t struct colormap variation of patch
PU_HWRMODELTEXTURE, // Hardware model texture
PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
PU_HWRMODELTEXTURE = 23, // Hardware model texture
PU_HWRCACHE, // static until unlocked
PU_CACHE, // static until unlocked
PU_HWRCACHE = 48, // static until unlocked
PU_CACHE = 49, // static until unlocked
// Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start
PU_LEVEL, // static until level exited
PU_LEVSPEC, // a special thinker in a level
PU_HWRPLANE, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL
PU_LEVEL = 50, // static until level exited
PU_LEVSPEC = 51, // a special thinker in a level
PU_HWRPLANE = 52, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL
// Tags >= PU_PURGELEVEL are purgable whenever needed
PU_PURGELEVEL, // Note: this is never actually used as a tag
PU_CACHE_UNLOCKED, // Note: unused
PU_HWRCACHE_UNLOCKED, // 'unlocked' PU_HWRCACHE memory:
PU_PURGELEVEL = 100, // Note: this is never actually used as a tag
PU_CACHE_UNLOCKED = 101, // Note: unused
PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory:
// 'second-level' cache for graphics
// stored in hardware format and downloaded as needed
PU_HWRMODELTEXTURE_UNLOCKED, // 'unlocked' PU_HWRMODELTEXTURE memory
NUM_PURGETAGS
// stored in hardware format and downloaded as needed
PU_HWRMODELTEXTURE_UNLOCKED = 103, // 'unlocked' PU_HWRMODELTEXTURE memory
};
//
@@ -160,7 +157,7 @@ void Z_SetUser(void *ptr, void **newuser);
//
#define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum)
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag);
#define Z_TotalUsage() Z_TagsUsage(0, NUM_PURGETAGS-1)
#define Z_TotalUsage() Z_TagsUsage(0, INT32_MAX)
//
// Miscellaneous functions