Compare commits

..
Author SHA1 Message Date
alufolie91 794fda5ac5 fix issues with interpolation when spawning mobjs
fixes them seemingly coming really fast out of nowhere
needs testing as this may break some things from addons
2026-07-21 15:58:34 +02:00
39 changed files with 282 additions and 758 deletions

No files matched your search

-62
View File
@@ -1,62 +0,0 @@
name: macOS
on:
push:
branches: [ "mac-ci-test"]
pull_request:
branches: [ "mac-ci-test"]
jobs:
build:
continue-on-error: true
strategy:
matrix:
arch:
- runner: macos-latest
name: aarch64
- runner: macos-15-intel
name: x86_64
name: ${{ matrix.arch.name }}
runs-on: ${{ matrix.arch.runner }}
steps:
- uses: actions/checkout@v6.0.1
- name: Install dependencies
run: brew install --formula sdl2 sdl2_mixer game-music-emu libopenmpt
- name: Download Kart assets
run: |
curl -L \
-o AssetsLinuxOnly.zip \
"https://github.com/STJr/Kart-Public/releases/download/v1.6/AssetsLinuxOnly.zip"
- name: Extract Kart assets
run: |
mkdir -p assets/installer
unzip -q AssetsLinuxOnly.zip -d assets/installer
- name: Configure CMake
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
- name: Build SRB2Kart-Saturn
run: ninja -C build
#idk what im doing here tbh i pray this works
- name: Package DMG
run: |
cd build
cpack -G DragNDrop
#- name: Upload build artifact
# uses: actions/upload-artifact@v6.0.0
# with:
# name: srb2kartsaturn-macOS-${{ matrix.arch.name }}-${{ github.sha }}
# path: build/bin
- name: Upload DMG
uses: actions/upload-artifact@v6.0.0
with:
name: srb2kartsaturn-macOS-${{ matrix.arch.name }}-${{ github.sha }}
path: build/*.dmg
+1 -1
View File
@@ -29,7 +29,7 @@ if("${SRB2_CPACK_GENERATOR}" STREQUAL "")
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
set(SRB2_CPACK_GENERATOR "TGZ")
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
set(SRB2_CPACK_GENERATOR "DragNDrop")
set(SRB2_CPACK_GENERATOR "TGZ")
endif()
endif()
-5
View File
@@ -247,9 +247,6 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
"Compile with UndefinedBehaviorSanitizer (libubsan).")
set(SRB2_CONFIG_MUMBLE ON CACHE BOOL
"Enable Mumble support")
set(SRB2_CONFIG_SATURNPAK ON CACHE BOOL
"Enable Saturn specific special packet. Required for using the newer resynch system")
set(SRB2_CONFIG_SATURNJOIN ON CACHE BOOL
@@ -278,7 +275,6 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_hooklib.c
lua_hudlib.c
lua_hudlib_drawlist.c
lua_profile.cpp
lua_infolib.c
lua_maplib.c
lua_mathlib.c
@@ -294,7 +290,6 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_hook.h
lua_hud.h
lua_hudlib_drawlist.h
lua_profile.h
lua_libs.h
lua_script.h
lua_udatalib.h
+4
View File
@@ -246,6 +246,10 @@ ifdef STATIC
libs+=-static
endif
ifneq (,$(filter $(CC) $(CXX),gcc g++))
opts+=-mno-ms-bitfields
endif
# build with profiling information
ifdef PROFILEMODE
opts+=-pg
+1 -1
View File
@@ -86,7 +86,7 @@ ifdef VALGRIND
VALGRIND_PKGCONFIG?=valgrind
VALGRIND_LDFLAGS=
$(eval $(call Use_pkg_config,VALGRIND))
#ZDEBUG=1 we enable this by default
ZDEBUG=1
opts+=-DHAVE_VALGRIND
endif
-1
View File
@@ -99,4 +99,3 @@ lua_skinlib.c
lua_thinkerlib.c
lua_udatalib.c
lua_glib.c
lua_profile.cpp
+3 -3
View File
@@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+38 -44
View File
@@ -1629,8 +1629,8 @@ static boolean CL_SendJoin(void)
netbuffer->u.clientcfg.packetversion = PACKETVERSION;
netbuffer->u.clientcfg.version = VERSION;
netbuffer->u.clientcfg.subversion = SUBVERSION;
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, sizeof(netbuffer->u.clientcfg.application)-1);
netbuffer->u.clientcfg.application[sizeof(netbuffer->u.clientcfg.application)-1] = '\0';
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
sizeof(netbuffer->u.clientcfg.application));
#ifdef SATURNJOIN
netbuffer->u.clientcfg.issaturn = ISSATURN;
#endif
@@ -1655,91 +1655,88 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
serverinfo_pak *serverinfo = &netbuffer->u.serverinfo;
netbuffer->packettype = PT_SERVERINFO;
serverinfo->_255 = 255;
serverinfo->packetversion = PACKETVERSION;
serverinfo->version = VERSION;
serverinfo->subversion = SUBVERSION;
strncpy(serverinfo->application, SRB2APPLICATION, sizeof(serverinfo->application)-1);
serverinfo->application[sizeof(serverinfo->application)-1] = '\0';
netbuffer->u.serverinfo._255 = 255;
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
netbuffer->u.serverinfo.version = VERSION;
netbuffer->u.serverinfo.subversion = SUBVERSION;
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
sizeof netbuffer->u.serverinfo.application);
// return back the time value so client can compute their ping
serverinfo->time = (tic_t)LONG(servertime);
serverinfo->leveltime = (tic_t)LONG(leveltime);
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
// force 1 player
if (UseFakeSeed())
serverinfo->numberofplayer = (UINT8)1;
netbuffer->u.serverinfo.numberofplayer = (UINT8)1;
else
serverinfo->numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
serverinfo->maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
// SRB2Kart: Vanilla's gametype constants for MS support
serverinfo->gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
netbuffer->u.serverinfo.gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
serverinfo->modifiedgame = (UINT8)modifiedgame;
serverinfo->cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
serverinfo->kartvars = (UINT8) (
netbuffer->u.serverinfo.kartvars = (UINT8) (
(cv_kartspeed.value & SV_SPEEDMASK) |
(dedicated ? SV_DEDICATED : 0)
);
CopyCaretColors(serverinfo->servername, cv_servername.string, MAXSERVERNAME);
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof(netbuffer->u.serverinfo.mapname)-1);
strncpy(serverinfo->mapname, G_BuildMapName(gamemap), sizeof(serverinfo->mapname)-1);
serverinfo->mapname[sizeof(serverinfo->mapname)-1] = '\0';
memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, sizeof(netbuffer->u.serverinfo.mapmd5));
memcpy(serverinfo->mapmd5, mapmd5, sizeof(serverinfo->mapmd5));
netbuffer->u.serverinfo.iszone = 0;
serverinfo->iszone = 0;
memset(serverinfo->maptitle, 0, sizeof(serverinfo->maptitle));
memset(serverinfo->httpsource, 0, MAX_MIRROR_LENGTH);
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof(netbuffer->u.serverinfo.maptitle));
memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH);
if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0])
{
strncpy(serverinfo->maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(serverinfo->maptitle)-1);
strncpy(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(netbuffer->u.serverinfo.maptitle)-1);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
{
if (mapheaderinfo[gamemap-1]->zonttl[0])
{
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->zonttl, sizeof(serverinfo->maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->zonttl,
sizeof(netbuffer->u.serverinfo.maptitle)-1);
}
else
{
serverinfo->iszone = 1; // ms and clients will append this themselves
netbuffer->u.serverinfo.iszone = 1; // ms and clients will append this themselves
}
}
if (mapheaderinfo[gamemap-1]->actnum[0])
{
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->actnum, sizeof(serverinfo->maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->actnum,
sizeof(netbuffer->u.serverinfo.maptitle)-1);
}
}
else
{
strncpy(serverinfo->maptitle, "Unknown", sizeof(serverinfo->maptitle)-1);
}
strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33);
serverinfo->maptitle[sizeof(serverinfo->maptitle)-1] = '\0';
netbuffer->u.serverinfo.maptitle[32] = '\0';
serverinfo->actnum = 0; //mapheaderinfo[gamemap-1]->actnum
netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum
mirror_length = strlen(httpurl);
if (mirror_length > MAX_MIRROR_LENGTH)
mirror_length = MAX_MIRROR_LENGTH;
if (snprintf(serverinfo->httpsource, mirror_length+1, "%s", httpurl) < 0)
if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0)
// If there's an encoding error, send nothing, we accept that the above may be truncated
strncpy(serverinfo->httpsource, "", mirror_length);
strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length);
serverinfo->httpsource[MAX_MIRROR_LENGTH-1] = '\0';
netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0';
p = PutFileNeeded(0);
@@ -6876,10 +6873,7 @@ boolean TryRunTics(tic_t realtics)
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, leveltime));
if (update_stats)
{
ps_prevtictime = ps_tictime;
PS_START_TIMING(ps_tictime);
}
G_Ticker((gametic % NEWTICRATERATIO) == 0);
ExtraDataTicker();
-6
View File
@@ -79,7 +79,6 @@
#include "core/memory.h"
#include "lua_script.h"
#include "lua_profile.h"
/* Manually defined asset hashes for non-CMake builds
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
@@ -645,11 +644,6 @@ static boolean D_Display(void)
CON_Drawer(); // Ha, i LIED!
if (cv_lua_profile.value > 0)
{
LUA_RenderTimers();
}
PS_START_TIMING(ps_swaptime);
I_FinishUpdate(); // page flip or blit buffer
PS_STOP_TIMING(ps_swaptime);
-12
View File
@@ -47,7 +47,6 @@
#include "z_zone.h"
#include "lua_script.h"
#include "lua_hook.h"
#include "lua_profile.h"
#include "m_cond.h"
#include "m_anigif.h"
#include "k_kart.h" // SRB2kart
@@ -507,9 +506,6 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_lua_profile = {"lua_profile", "0").values(CV_Unsigned).onchange(lua_profile_OnChange).description("Show hook timings over an average of N tics");
consvar_t cv_lua_profile = {"lua_profile", "0", CV_CALL, CV_Unsigned, lua_profile_OnChange, 0, NULL, NULL, 0, 0, NULL};
// only there to better keep track of it globally
consvar_t cv_director = {"director", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -604,12 +600,6 @@ void D_RegisterServerCommands(void)
Forceskin_cons_t[i].value = 0;
Forceskin_cons_t[i].strvalue = NULL;
}
// Set default player names
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
for (i = 0; i < MAXPLAYERS; i++)
sprintf(player_names[i], "Player %d", 1 + i);
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
@@ -944,8 +934,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_palette);
CV_RegisterVar(&cv_palettenum);
CV_RegisterVar(&cv_lua_profile);
// m_menu.c
CV_RegisterVar(&cv_chatheight);
CV_RegisterVar(&cv_chatwidth);
-2
View File
@@ -189,8 +189,6 @@ extern consvar_t cv_ps_thinkframe_page;
extern consvar_t cv_ps_samplesize;
extern consvar_t cv_ps_descriptor;
extern consvar_t cv_lua_profile;
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
extern consvar_t cv_showtrackaddon;
+3 -2
View File
@@ -1616,7 +1616,8 @@ static void CURLGetFile(void)
#endif
}
HTTP_login *CURLGetLogin(const char *url, HTTP_login ***return_prev_next)
HTTP_login *
CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
{
HTTP_login * login;
HTTP_login ** prev_next;
@@ -1626,7 +1627,7 @@ HTTP_login *CURLGetLogin(const char *url, HTTP_login ***return_prev_next)
( login = (*prev_next));
prev_next = &login->next
){
if (fastcmp(login->url, url))
if (fastcmp(login->url, url) != 0)
{
if (return_prev_next)
(*return_prev_next) = prev_next;
+2 -2
View File
@@ -211,12 +211,12 @@ void D_SetupProtocol(void)
if (result)
{
if (fastcmp(buffer, "no"))
if (!fastcmp(buffer, "no"))
{
fclose(fp);
return;
}
else if (!fastcmp(buffer, exe_path))
else if (fastcmp(buffer, exe_path))
{
// overwrite
fclose(fp);
+24 -3
View File
@@ -453,13 +453,34 @@ consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, dr
static CV_PossibleValue_t cechotoggle_t[] = {{0, "Off"}, {1, "On"}, {2, "Console"}, {0, NULL}};
consvar_t cv_cechotoggle = {"show_cecho", "On", CV_SAVE, cechotoggle_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 16
#error "please update player_name table using the new value for MAXPLAYERS"
#endif
#ifdef SEENAMES
player_t *seenplayer = NULL; // player we're aiming at right now
#endif
// now automatically allocated in D_RegisterServerCommands
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
char player_names[MAXPLAYERS][MAXPLAYERNAME+1] =
{
"Player 1",
"Player 2",
"Player 3",
"Player 4",
"Player 5",
"Player 6",
"Player 7",
"Player 8",
"Player 9",
"Player 10",
"Player 11",
"Player 12",
"Player 13",
"Player 14",
"Player 15",
"Player 16"
}; // SRB2kart - removed Players 17 through 32
INT32 player_name_changes[MAXPLAYERS] = {};
INT16 rw_maximums[NUM_WEAPONS] =
+1 -1
View File
@@ -998,7 +998,7 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
const char *flatname = W_CheckNameForNum(flatlumpnum);
// hack for gba rainbow roads cyan floors
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
{
glMipmap->flags &= ~TF_CHROMAKEYED;
}
+10 -16
View File
@@ -1101,8 +1101,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
// Found a break
// The heights are clamped to ensure the polygon doesn't cross itself.
bot = std::min(std::max(bheight, realbot), top);
endbot = std::min(std::max(endbheight, endrealbot), endtop);
bot = std::clamp(bheight, realbot, top);
endbot = std::clamp(endbheight, endrealbot, endtop);
Surf->PolyColor.s.alpha = alpha;
@@ -3235,18 +3235,6 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
if (!spr->mobj)
return;
// Ceiling scenery have no shadow.
if ((spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) == (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY))
return;
// Debris have no corona or shadow.
if (spr->mobj->flags2 & MF2_DEBRIS)
return;
// Without this, your shadow shows on the floor, even after you die and fall through the ground.
if (spr->mobj->z < spr->mobj->floorz)
return;
R_GetShadowZ(spr->mobj, &floorslope);
mobjfloor = HWR_OpaqueFloorAtPos(
@@ -3507,7 +3495,10 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
hwrpatch = static_cast<GLPatch_t *>(gpatch->hardware);
// Draw shadow BEFORE sprite
if (UNLIKELY(cv_shadow.value))
if (UNLIKELY(cv_shadow.value // Shadows enabled
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
@@ -3833,7 +3824,10 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
}
// Draw shadow BEFORE sprite
if (UNLIKELY(cv_shadow.value))
if (UNLIKELY(cv_shadow.value // Shadows enabled
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
-7
View File
@@ -3581,10 +3581,6 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
#endif
skin = K_GetMobjSkin(mo);
if (!skin)
return;
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
if (minimaphead == NULL)
@@ -3788,9 +3784,6 @@ static void K_drawKartMinimap(void)
mobj_t *mobj = players[localplayers[i]].mo;
if (!mobj)
continue;
// dont draw for no contestants
boolean playertimedout = (mobj->health <= 0 && players[localplayers[i]].pflags & PF_TIMEOVER);
-2
View File
@@ -3087,8 +3087,6 @@ static int lib_gPlayerDeviceRumble(lua_State *L)
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (demo.playback) return 0;
pnum = P_GetLocalPlayerNumForPlayer(player);
// Not a local player
+3 -49
View File
@@ -25,7 +25,6 @@
#include "lua_libs.h"
#include "lua_hook.h"
#include "lua_hud.h" // hud_running errors
#include "lua_profile.h"
/* =========================================================================
ABSTRACTION
@@ -446,54 +445,11 @@ FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n)
lua_getref(gL, hookRefs[hook->id]);
}
static int pcall(Hook_State *hook)
{
return lua_pcall(gL, hook->values, hook->results, EINDEX);
}
static const char *hook_name(Hook_State *hook)
{
if (hud_running)
{
return hudHookNames[hook->hook_type];
}
else if (hook->string)
{
return stringHookNames[hook->hook_type];
}
//else if (hook->mobj_type > 0)
else if (hook->mobj_type != NONMOHOOK)
{
return mobjHookNames[hook->hook_type];
}
else
{
return hookNames[hook->hook_type];
}
}
static int pcall_timed_or_untimed(Hook_State *hook)
{
if (!hud_running && cv_lua_profile.value > 0)
{
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -1 - hook->values, hook_name(hook));
int k = pcall(hook);
LUA_EndFunctionTimer(timer);
return k;
}
else
{
return pcall(hook);
}
}
static int call_single_hook_no_copy(Hook_State *hook)
{
hook_important = hook->important;
//if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
if (pcall_timed_or_untimed(hook) == 0)
if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
{
if (hook->results > 0)
{
@@ -584,6 +540,7 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|| hook->hook_type == MOBJ_HOOK(MobjThinker )
|| hook->hook_type == MOBJ_HOOK(BossThinker )
))
{
@@ -803,7 +760,7 @@ static void hook_think_frame(int type)
const hook_t * map = &hookIds[type];
int k;
const boolean perfstats = (cv_perfstats.value >= PS_THINKFRAME);
const boolean perfstats = (cv_perfstats.value >= 3);
if (prepare_hook(&hook, 0, type))
{
@@ -1061,9 +1018,6 @@ void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save)
lua_pushcclosure(gL, archFunc, 2);
// stack: tables, savebuffer_t, archFunc
// Manually set the hook's variables here since we don't call prepare_hook
hook.hook_type = HOOK(NetVars);
hook.mobj_type = NONMOHOOK; // Force mobj_type to be NONMOHOOK so the mobj_type check get skipped
init_hook_call(&hook, 0, res_none);
call_mapped(&hook, map);
+1 -5
View File
@@ -22,8 +22,7 @@
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // hook_cmd_running errors
#include "lua_profile.h"
#include "lua_hook.h" // cmd errors
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
state_t *astate = NULL;
@@ -111,10 +110,7 @@ static void A_Lua(mobj_t *actor)
LUA_PushUserdata(gL, actor, META_MOBJ);
lua_pushinteger(gL, var1);
lua_pushinteger(gL, var2);
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -4, "A_Lua");
LUA_Call(gL, 3, 0, 1);
LUA_EndFunctionTimer(timer);
lua_pop(gL, 1); // pop error handler
-264
View File
@@ -1,264 +0,0 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by James Robert Roman
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "screen.h"
#include <algorithm>
#include <cstddef>
#include <unordered_map>
#include <string>
#include <string_view>
#include <vector>
extern "C" {
#include "blua/lua.h"
};
#include "v_video.h"
#include "command.h"
#include "doomtype.h"
#include "i_system.h"
#include "lua_profile.h"
#include "m_perfstats.h"
extern "C" consvar_t cv_lua_profile;
namespace
{
precise_t g_time_reference;
int g_tics_counted;
double g_running_tic_time;
double g_avg_tic_time;
bool g_invalid;
}; // namespace
struct lua_timer_t
{
struct Stat
{
double calls = 0;
double time = 0.0;
};
Stat running, avg;
};
namespace
{
std::unordered_map<std::string, lua_timer_t> g_tic_timers;
}; // namespace
lua_timer_t* LUA_BeginFunctionTimer(lua_State* L, int fn_idx, const char* name)
{
lua_Debug ar;
lua_pushvalue(L, fn_idx);
lua_getinfo(L, ">S", &ar);
auto label = [&]
{
using sv = std::string_view;
sv view{ar.source};
switch (view.front())
{
case '@': // file
if (std::size_t p = view.rfind('/'); p != sv::npos) // lump or base
{
return view.substr(p + 1);
}
break;
case '=': // ??
view.remove_prefix(1);
break;
}
return view;
};
// i sure hope this std::string mess is fine...
auto [it, ins] = g_tic_timers.try_emplace(std::string(va("%s:%d (%s)", std::string(label()).c_str(), ar.linedefined, name)));
auto& [key, timer] = *it;
g_time_reference = I_GetPreciseTime();
return &timer;
}
void LUA_EndFunctionTimer(lua_timer_t* timer)
{
precise_t t = I_GetPreciseTime() - g_time_reference;
double precision = I_GetPrecisePrecision();
timer->running.time += t / precision;
timer->running.calls += 1.0;
}
void LUA_ResetTicTimers(void)
{
if (cv_lua_profile.value <= 0)
{
return;
}
if (g_tics_counted < cv_lua_profile.value)
{
g_tics_counted++;
double precision = I_GetPrecisePrecision();
g_running_tic_time += ps_prevtictime.value.p / precision;
}
else
{
double counted = g_tics_counted;
for (auto& [key, timer] : g_tic_timers)
{
timer.avg = {timer.running.calls / counted, timer.running.time / counted};
timer.running = {};
}
g_avg_tic_time = g_running_tic_time / counted;
g_running_tic_time = 0.0;
g_tics_counted = 1;
g_invalid = false;
}
}
void LUA_RenderTimers(void)
{
constexpr int kRowHeight = 4;
float row_y = kRowHeight;
// pretty much what the whole srb2::Draw does lol
auto draw_row = [](float x, float y, INT32 flags, const char *str)
{
V_DrawSmallStringAtFixed(
FloatToFixed(x),
FloatToFixed(y),
V_MONOSPACE|V_ALLOWLOWERCASE|flags,
str
);
};
draw_row(0.f, 0.f, 0, va("-- AVERAGES PER TIC (over %d tics) --", cv_lua_profile.value));
if (g_invalid)
{
draw_row(0.f, row_y, V_GRAYMAP, " <Data pending>");
return;
}
std::vector<decltype(g_tic_timers)::iterator> view;
view.reserve(g_tic_timers.size());
auto color_flag = [](double t)
{
if (t < 10.0)
{
return V_GRAYMAP;
}
else if (t >= 100.0)
{
return V_YELLOWMAP;
}
else
{
return 0;
}
};
{
double cum = 0.0;
for (auto it = g_tic_timers.begin(); it != g_tic_timers.end(); ++it)
{
auto& [key, timer] = *it;
cum += timer.avg.time;
if (timer.avg.time > 0.0)
{
view.push_back(it);
}
}
{
const INT32 tally_flags = color_flag(cum * 1'000'000.0);
draw_row(0.f, row_y, tally_flags, va("%8.2f us - TOTAL", cum * 1'000'000.0));
draw_row(0.f, row_y + kRowHeight, tally_flags, va("%8.2f ms", cum * 1000.0));
// dont need to show this if we didnt capture over time
// this would just show nan or inf anyways
if (std::fpclassify(g_avg_tic_time) != FP_ZERO)
{
draw_row(0.f, row_y + kRowHeight * 2, tally_flags, va(
"%8.2f%% overhead (%.2f / %.2f) <-- not counting rendering time",
(cum / g_avg_tic_time) * 100.0,
(cum * (double)TICRATE),
(g_avg_tic_time * (double)TICRATE)
));
}
}
row_y += kRowHeight * 4;
}
std::sort(
view.rbegin(),
view.rend(),
[](auto a, auto b)
{
auto& [k1, t1] = *a;
auto& [k2, t2] = *b;
return t1.avg.time < t2.avg.time;
}
);
for (auto it : view)
{
auto& [key, timer] = *it;
double t = timer.avg.time * 1'000'000.0;
draw_row(0.f, row_y, color_flag(t), va(
"%8.2f us %8.2f calls - %s",
t,
timer.avg.calls,
key.c_str()
));
row_y += kRowHeight;
// FIXME this is all ugly and sucks
if (row_y >= BASEVIDHEIGHT)
break;
}
}
extern "C" void lua_profile_OnChange(void)
{
g_invalid = true;
if (cv_lua_profile.value == 0)
{
g_tic_timers = {};
}
}
-38
View File
@@ -1,38 +0,0 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by James Robert Roman
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef lua_profile_h
#define lua_profile_h
#include "blua/lua.h"
#include "doomtype.h"
//#include "typedef.h"
#ifdef __cplusplus
extern "C" {
#endif
struct lua_timer_t;
typedef struct lua_timer_t lua_timer_t;
void LUA_ResetTicTimers(void);
lua_timer_t *LUA_BeginFunctionTimer(lua_State *L, int fn_idx, const char *name);
void LUA_EndFunctionTimer(lua_timer_t *timer);
void LUA_RenderTimers(void);
void lua_profile_OnChange(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif/*lua_profile_h*/
+1 -1
View File
@@ -11,7 +11,7 @@
#include "m_curl.h"
#include "doomtype.h"
#include "doomdef.h" // I_OutputMsg
#include "i_system.h" // I_OutputMsg
#include "m_argv.h" // M_CheckParm, M_GetNextParm
static boolean curl_args_init = false;
+2 -6
View File
@@ -5766,8 +5766,7 @@ static void M_DrawMusicTest(void)
x = 24;
y = 64;
if (renderisnewtic)
st_musictime++;
if (renderisnewtic) st_musictime++;
while (t <= b)
{
@@ -5776,11 +5775,11 @@ static void M_DrawMusicTest(void)
{
const musicdef_t *def = S_GetMusicCredit(t);
const size_t MAXLENGTH = 34;
const char *songname = def->title[0] ? def->title : def->source;
size_t namelength = strlen(songname);
#define MAXLENGTH 34
char buf[MAXLENGTH+1];
if (t == st_sel && namelength > MAXLENGTH)
@@ -5789,14 +5788,11 @@ static void M_DrawMusicTest(void)
strlcpy(buf, songname, MAXLENGTH);
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf);
if (curplaying == def)
{
V_DrawFill(20+280-9, y-4, 8, 16, 230);
}
#undef MAXLENGTH
}
t++;
y += 16;
}
+2 -2
View File
@@ -1261,7 +1261,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
const size_t amount = len - maxlen + 1;
// Note: anything above 17 will cause zero division
static const size_t MAXSPEED = 6;
const size_t MAXSPEED = 6;
const tic_t t = timer / (35/min(amount, MAXSPEED));
const size_t state = (t / amount) % 4;
@@ -1296,7 +1296,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
}
// Technically not necessary, since it gets set again after function call, but just in case
result[maxlen-1] = '\0';
result[maxlen] = 0;
}
void M_MinimapGenerate(void)
+56 -42
View File
@@ -47,7 +47,6 @@ struct perfstatrow {
static ps_metric_t ps_frametime = {0};
ps_metric_t ps_tictime = {0};
ps_metric_t ps_prevtictime = {0};
ps_metric_t ps_playerthink_time = {0};
ps_metric_t ps_thinkertime = {0};
@@ -169,14 +168,14 @@ perfstatrow_t gamelogic_rows[] = {
};
perfstatrow_t thinkercount_rows[] = {
{"thnkers" , "Thinkers: ", &ps_thinkercount, PS_LEVEL},
{" mobjs " , " Mobjs: ", &ps_mobjcount, PS_LEVEL},
{"thnkers", "Thinkers: ", &ps_thinkercount, PS_LEVEL},
{" mobjs ", " Mobjs: ", &ps_mobjcount, PS_LEVEL},
{" regular", " Regular: ", &ps_regularcount, PS_LEVEL},
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
{" precip " , " Precipitation: ", &ps_precipcount, PS_LEVEL},
{" other " , " Other: ", &ps_otherthcount, PS_LEVEL},
{" remove " , " Pending removal:", &ps_removecount, PS_LEVEL},
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
{}
};
@@ -606,9 +605,7 @@ static void PS_CountThinkers(void)
else if (thinker->function == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
ps_mobjcount.value.i++;
if (mobj->flags & MF_NOTHINK)
ps_nothinkcount.value.i++;
else if (mobj->flags & MF_SCENERY)
@@ -627,17 +624,49 @@ static void PS_CountThinkers(void)
ps_precipcount.value.i++;
}
/*for (i = 0; i < NUM_THINKERLISTS; i++)
{
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
{
ps_thinkercount.value.i++;
if (thinker->function == (actionf_p1)P_RemoveThinkerDelayed)
ps_removecount.value.i++;
else if (i == THINK_POLYOBJ)
ps_polythcount.value.i++;
else if (i == THINK_MAIN)
ps_mainthcount.value.i++;
else if (i == THINK_MOBJ)
{
if (thinker->function == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
ps_mobjcount.value.i++;
if (mobj->flags & MF_NOTHINK)
ps_nothinkcount.value.i++;
else if (mobj->flags & MF_SCENERY)
ps_scenerycount.value.i++;
else
ps_regularcount.value.i++;
}
}
else if (i == THINK_DYNSLOPE)
ps_dynslopethcount.value.i++;
else if (i == THINK_PRECIP)
ps_precipcount.value.i++;
}
}*/
}
// Update all metrics that are calculated on every tick.
void PS_UpdateTickStats(void)
{
if (cv_perfstats.value == PS_RENDER && cv_ps_samplesize.value > 1)
if (cv_perfstats.value == 1 && cv_ps_samplesize.value > 1)
{
PS_UpdateRowHistories(gamelogicbrief_row, false);
}
if (cv_perfstats.value == PS_LOGIC)
if (cv_perfstats.value == 2)
{
if (PS_IsLevelActive())
{
@@ -662,25 +691,25 @@ void PS_UpdateTickStats(void)
if (cv_ps_samplesize.value > 1)
{
if (cv_perfstats.value >= PS_THINKFRAME && PS_IsLevelActive())
if (cv_perfstats.value >= 3 && PS_IsLevelActive())
{
int i;
switch (cv_perfstats.value)
{
case PS_THINKFRAME:
case 3:
for (i = 0; i < thinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false);
}
break;
case PS_PRETHINKFRAME:
case 4:
for (i = 0; i < prethinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false);
}
break;
case PS_POSTTHINKFRAME:
case 5:
for (i = 0; i < postthinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false);
@@ -690,7 +719,6 @@ void PS_UpdateTickStats(void)
break;
}
}
if (cv_perfstats.value)
{
ps_tick_index++;
@@ -721,7 +749,7 @@ static void PS_DrawDescriptorHeader(void)
int samples_left = max(ps_frame_samples_left, ps_tick_samples_left);
int x, y;
if (cv_perfstats.value >= PS_THINKFRAME)
if (cv_perfstats.value >= 3)
{
x = 2;
y = 0;
@@ -837,19 +865,20 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
last_mod_name[0] = '\0';
INT32 total = 0;
// Decide page length based and drawn text on choosen thinker type
//Decide page length based and drawn text on choosen thinker type
switch (cv_perfstats.value)
{
case PS_THINKFRAME:
case 3:
{
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
pagestart = min((page - 1)*PAGE_ENTRIES, thinkframe_hooks_length);
pageend = min(pagestart + PAGE_ENTRIES, thinkframe_hooks_length);
V_DrawSmallString(MAX_X-50, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "ThinkFrame");
}
break;
case PS_PRETHINKFRAME:
case 4:
{
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
@@ -858,7 +887,7 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
V_DrawSmallString(MAX_X-60, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "PreThinkFrame");
}
break;
case PS_POSTTHINKFRAME:
case 5:
{
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
@@ -946,22 +975,7 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
void PS_ThinkFrame_Page_OnChange(void)
{
int maxpage = 0;
switch (cv_perfstats.value)
{
case PS_THINKFRAME:
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
case PS_PRETHINKFRAME:
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
case PS_POSTTHINKFRAME:
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
default:
break;
}
int maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
if (cv_ps_thinkframe_page.value > maxpage)
CV_StealthSetValue(&cv_ps_thinkframe_page, maxpage);
@@ -994,18 +1008,18 @@ static void PS_DrawPostThinkFrameStats(void)
void M_DrawPerfStats(void)
{
if (cv_perfstats.value == PS_RENDER) // rendering
if (cv_perfstats.value == 1) // rendering
{
PS_UpdateFrameStats();
PS_DrawRenderStats();
}
else if (cv_perfstats.value == PS_LOGIC) // logic
else if (cv_perfstats.value == 2) // logic
{
// PS_UpdateTickStats is called in TryRunTics, since otherwise it would miss
// tics when frame skips happen
PS_DrawGameLogicStats();
}
else if (cv_perfstats.value >= PS_THINKFRAME) // lua thinkframe
else if (cv_perfstats.value >= 3) // lua thinkframe
{
if (!PS_IsLevelActive())
return;
@@ -1022,13 +1036,13 @@ void M_DrawPerfStats(void)
switch (cv_perfstats.value)
{
case PS_THINKFRAME:
case 3:
PS_DrawThinkFrameStats();
break;
case PS_PRETHINKFRAME:
case 4:
PS_DrawPreThinkFrameStats();
break;
case PS_POSTTHINKFRAME:
case 5:
PS_DrawPostThinkFrameStats();
break;
default:
-11
View File
@@ -26,16 +26,6 @@ typedef struct
void *history;
} ps_metric_t;
typedef enum
{
PS_OFF = 0,
PS_RENDER,
PS_LOGIC,
PS_THINKFRAME,
PS_PRETHINKFRAME,
PS_POSTTHINKFRAME
} ps_types_t;
typedef struct
{
ps_metric_t time_taken;
@@ -46,7 +36,6 @@ typedef struct
#define PS_STOP_TIMING(metric) metric.value.p = I_GetPreciseTime() - metric.value.p
extern ps_metric_t ps_tictime;
extern ps_metric_t ps_prevtictime;
extern ps_metric_t ps_playerthink_time;
extern ps_metric_t ps_thinkertime;
+35 -46
View File
@@ -2573,7 +2573,7 @@ static void P_PlayerZMovement(mobj_t *mo)
P_SetPlayerMobjState(mo, S_KART_STND1);
}
#if 1 // praying that removing this dupe wont cause any issues...
#if 0 // praying that removing this dupe wont cause any issues...
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope))
{
// Handle landing on slope during Z movement
@@ -9150,17 +9150,15 @@ void P_MobjThinker(mobj_t *mobj)
tmfloorthing = tmhitthing = NULL;
// do NOT trigger linedef executors for "local" mobjs
if (!mobj->islocal)
const sector_t *sec1 = mobj->subsector ? mobj->subsector->sector : NULL;
// 970 allows ANY mobj to trigger a linedef exec
if (!mobj->islocal && sec1 && GETSECSPECIAL(sec1->special, 2) == 8) // BEWARE: islocal does not exist in vanilla
{
// 970 allows ANY mobj to trigger a linedef exec
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)
{
sector_t *sec2;
sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
}
sector_t *sec2;
sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
}
if (mobj->scale != mobj->destscale)
@@ -9172,7 +9170,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
// Special thinker for scenery objects
if (mobj->flags & MF_SCENERY && !mobj->player)
if (mobj->flags & MF_SCENERY)
{
P_MobjSceneryThink(mobj);
return;
@@ -9264,8 +9262,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
// Sliding physics for slidey mobjs!
if ( mobj->type == MT_FALLINGROCK
if (mobj->type == MT_FALLINGROCK
|| mobj->type == MT_LITTLETUMBLEWEED
|| mobj->type == MT_BIGTUMBLEWEED
|| mobj->type == MT_FLINGRING
@@ -9310,24 +9307,21 @@ void P_MobjThinker(mobj_t *mobj)
if (P_MobjWasRemoved(mobj))
return;
if ((mobj->health == 0) && // Fading tile
(mobj->type == MT_BOUNCEPICKUP
|| mobj->type == MT_RAILPICKUP
|| mobj->type == MT_AUTOPICKUP
|| mobj->type == MT_EXPLODEPICKUP
|| mobj->type == MT_SCATTERPICKUP
|| mobj->type == MT_GRENADEPICKUP))
if (P_WeaponOrPanel(mobj->type))
{
INT32 value = mobj->info->damage/10;
value = mobj->fuse/value;
value = 10-value;
value--;
if (mobj->health == 0) // Fading tile
{
INT32 value = mobj->info->damage/10;
value = mobj->fuse/value;
value = 10-value;
value--;
if (value <= 0)
value = 1;
if (value <= 0)
value = 1;
mobj->frame &= ~FF_TRANSMASK;
mobj->frame |= value << FF_TRANSSHIFT;
mobj->frame &= ~FF_TRANSMASK;
mobj->frame |= value << FF_TRANSSHIFT;
}
}
}
@@ -9364,29 +9358,25 @@ void P_PushableThinker(mobj_t *mobj)
I_Assert(!P_MobjWasRemoved(mobj));
// do NOT trigger linedef executors for "local" mobjs
if (!mobj->islocal)
if (P_MobjWasRemovedCompat(mobj))
return;
sec = mobj->subsector->sector;
if (mobj->z == sec->floorheight && GETSECSPECIAL(sec->special, 2) == 1)
P_LinedefExecute(sec->tag, mobj, sec);
{
sec = mobj->subsector->sector;
sector_t *sec2;
if (mobj->z == sec->floorheight && GETSECSPECIAL(sec->special, 2) == 1)
P_LinedefExecute(sec->tag, mobj, sec);
{
sector_t *sec2;
sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
}
sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
}
// it has to be pushable RIGHT NOW for this part to happen
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
P_TryMove(mobj, mobj->x, mobj->y, true);
if (P_MobjWasRemovedCompat(mobj))
return;
if (mobj->fuse == 1) // it would explode in the MobjThinker code
{
mobj_t *spawnmo;
@@ -9412,8 +9402,7 @@ void P_PushableThinker(mobj_t *mobj)
}
spawnmo = P_SpawnMobj(x, y, z, mobj->type);
if (!P_MobjWasRemovedCompat(spawnmo))
if (spawnmo)
{
spawnmo->spawnpoint = mobj->spawnpoint;
P_UnsetThingPosition(spawnmo);
+67 -79
View File
@@ -318,15 +318,15 @@ void P_AllocMapHeader(INT16 i)
// Loads the vertexes for a level.
FUNCINLINE static ATTRINLINE void P_LoadVertices(UINT8 *data)
{
mapvertex_t *mv = (mapvertex_t *)data;
vertex_t *v = vertexes;
mapvertex_t *ml = (mapvertex_t *)data;
vertex_t *li = vertexes;
size_t i;
// Copy and convert vertex coordinates, internal representation as fixed.
for (i = 0; i < numvertexes; i++, v++, mv++)
for (i = 0; i < numvertexes; i++, li++, ml++)
{
v->x = SHORT(mv->x)<<FRACBITS;
v->y = SHORT(mv->y)<<FRACBITS;
li->x = SHORT(ml->x)<<FRACBITS;
li->y = SHORT(ml->y)<<FRACBITS;
}
}
@@ -479,30 +479,65 @@ static void P_SetupDirectionalLight(void)
static void P_LoadSegs(UINT8 *data)
{
INT32 rawlinedef, rawside;
mapseg_t *ms = (mapseg_t*)data;
seg_t *seg = segs;
mapseg_t *ml = (mapseg_t*)data;
seg_t *li = segs;
line_t *ldef;
size_t i;
// Set map lighting settings.
P_SetupDirectionalLight();
for (i = 0; i < numsegs; i++, seg++, ms++)
for (i = 0; i < numsegs; i++, li++, ml++)
{
INT16 v1, v2;
v1 = SHORT(ms->v1);
v2 = SHORT(ms->v2);
v1 = SHORT(ml->v1);
v2 = SHORT(ml->v2);
// e6y
// moved down for additional checks to avoid overflow
// if wrong vertexe's indexes are in SEGS lump
// see below for more detailed information
// check and fix wrong references to non-existent vertexes
// see e1m9 @ NIVELES.WAD
// http://www.doomworld.com/idgames/index.php?id=12647
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
seg->angle = (SHORT(ms->angle)) << FRACBITS;
seg->offset = (SHORT(ms->offset)) << FRACBITS;
if (li->sidedef == &sides[li->linedef->sidenum[0]])
{
li->v1 = lines[ml->linedef].v1;
li->v2 = lines[ml->linedef].v2;
}
else
{
li->v1 = lines[ml->linedef].v2;
li->v2 = lines[ml->linedef].v1;
}
}
else
{
li->v1 = &vertexes[v1];
li->v2 = &vertexes[v2];
}
rawlinedef = SHORT(ms->linedef);
#ifdef HWRENDER
if (rendermode == render_opengl)
{
li->fv1.x = FixedToFloat(li->v1->x);
li->fv1.y = FixedToFloat(li->v1->y);
//li->fv1.z = FixedToFloat(li->v1->z); // z is unused in gl
li->fv2.x = FixedToFloat(li->v2->x);
li->fv2.y = FixedToFloat(li->v2->y);
//li->fv2.z = FixedToFloat(li->v2->z);
}
#endif
li->length = P_SegLength(li);
li->angle = (SHORT(ml->angle))<<FRACBITS;
li->offset = (SHORT(ml->offset))<<FRACBITS;
rawlinedef = SHORT(ml->linedef);
//e6y: check for wrong indexes
if ((unsigned)rawlinedef >= numlines)
@@ -511,8 +546,8 @@ static void P_LoadSegs(UINT8 *data)
}
ldef = &lines[rawlinedef];
seg->linedef = ldef;
rawside = SHORT(ms->side);
li->linedef = ldef;
rawside = SHORT(ml->side);
//e6y: fix wrong side index
if (rawside != 0 && rawside != 1)
@@ -527,9 +562,9 @@ static void P_LoadSegs(UINT8 *data)
I_Error("P_LoadSegs: linedef %d for seg %s references a non-existent sidedef %d", rawlinedef, sizeu1(i), ldef->sidenum[rawside]);
}
seg->side = rawside;
li->side = rawside;
seg->sidedef = &sides[ldef->sidenum[rawside]];
li->sidedef = &sides[ldef->sidenum[rawside]];
/* cph 2006/09/30 - our frontsector can be the second side of the
* linedef, so must check for NO_INDEX in case we are incorrectly
@@ -537,11 +572,11 @@ static void P_LoadSegs(UINT8 *data)
if (ldef->sidenum[rawside] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
seg->frontsector = NULL;
li->frontsector = NULL;
}
else
{
seg->frontsector = sides[ldef->sidenum[rawside]].sector;
li->frontsector = sides[ldef->sidenum[rawside]].sector;
}
if (ldef->flags & ML_TWOSIDED)
@@ -549,58 +584,15 @@ static void P_LoadSegs(UINT8 *data)
if (ldef->sidenum[rawside^1] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
seg->backsector = NULL;
li->backsector = NULL;
}
else
{
seg->backsector = sides[ldef->sidenum[rawside^1]].sector;
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
}
}
// e6y
// check and fix wrong references to non-existent vertexes
// see e1m9 @ NIVELES.WAD
// http://www.doomworld.com/idgames/index.php?id=12647
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
if (seg->sidedef == &sides[seg->linedef->sidenum[0]])
{
seg->v1 = lines[ms->linedef].v1;
seg->v2 = lines[ms->linedef].v2;
}
else
{
seg->v1 = lines[ms->linedef].v2;
seg->v2 = lines[ms->linedef].v1;
}
}
else
{
seg->v1 = &vertexes[v1];
seg->v2 = &vertexes[v2];
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
seg->fv1.x = FixedToFloat(seg->v1->x);
seg->fv1.y = FixedToFloat(seg->v1->y);
//seg->fv1.z = FixedToFloat(seg->v1->z); // z is unused in gl
seg->fv2.x = FixedToFloat(seg->v2->x);
seg->fv2.y = FixedToFloat(seg->v2->y);
//seg->fv2.z = FixedToFloat(seg->v2->z);
}
#endif
seg->length = P_SegLength(seg);
P_UpdateSegLightOffset(seg);
P_UpdateSegLightOffset(li);
}
}
@@ -618,6 +610,10 @@ FUNCINLINE static ATTRINLINE void P_LoadSubsectors(void *data)
}
}
//
// P_LoadSectors
//
//
// levelflats
//
@@ -669,17 +665,13 @@ static void P_CheckCyanFlat(levelflat_t *levelflat)
const char *flatname = W_CheckNameForNum(levelflat->lumpnum);
// hack for gba rainbow roads cyan floors
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
{
levelflat->cyan = false;
return;
}
const UINT8 *flat = R_GetFlat(levelflat->lumpnum);
if (!flat)
return;
const size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
@@ -799,10 +791,6 @@ INT32 P_CheckLevelFlat(const char *flatname)
return (INT32)i;
}
//
// P_LoadSectors
//
static const sector_t sector_default = {
.nexttag = -1,
.firsttag = -1,
@@ -1906,7 +1894,7 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
// because making both the WAD and PK3 loading code use
// the same functions is trickier than it looks for blockmap
// -- Monster Iestyn 09/01/18
static boolean P_LoadBlockMap(UINT8 *data, size_t count)
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
{
if (!count || count >= 0x20000)
return false;
@@ -2132,7 +2120,7 @@ static void P_LoadMapLUT(const virtres_t* virt)
rejectmatrix = NULL;
}
if (!(virtblockmap && P_LoadBlockMap(virtblockmap->data, virtblockmap->size)))
if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size)))
P_CreateBlockMap();
}
+1 -7
View File
@@ -38,8 +38,6 @@
#include "i_video.h" // rendermode
#include "m_perfstats.h"
#include "lua_profile.h"
// Object place
#include "m_cheat.h"
@@ -624,8 +622,6 @@ void P_Ticker(boolean run)
}
}
LUA_ResetTicTimers();
ps_lua_mobjhooks.value.i = 0;
ps_checkposition_calls.value.i = 0;
@@ -633,7 +629,6 @@ void P_Ticker(boolean run)
LUA_HookPreThinkFrame();
PS_STOP_TIMING(ps_lua_prethinkframe_time);
// OK! Now that we got all of that sorted, players can think!
PS_START_TIMING(ps_playerthink_time);
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -680,7 +675,6 @@ void P_Ticker(boolean run)
PS_STOP_TIMING(ps_lua_thinkframe_time);
}
// Run shield positioning
P_RunOverlays();
P_RunShadows();
@@ -802,7 +796,7 @@ void P_Ticker(boolean run)
if (!player->mo)
continue;
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
if (skyVisiblePerPlayer[i] && skybox)
{
+8 -4
View File
@@ -340,14 +340,18 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
return;
}
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
const boolean doreset = mobj->resetinterp && (mobj->type != MT_GHOST) && (mobj->type != MT_PLAYERRETICULE) && (mobj->type != MT_SHADOW);
out->x = doreset ? mobj->x : R_LerpFixed(mobj->old_x, mobj->x, frac);
out->y = doreset ? mobj->y : R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = doreset ? mobj->z : R_LerpFixed(mobj->old_z, mobj->z, frac);
out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac);
out->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac);
out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac);
out->spritexoffset = mobj->resetinterp ? mobj->spritexoffset : R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac);
out->spriteyoffset = mobj->resetinterp ? mobj->spriteyoffset : R_LerpFixed(mobj->old_spriteyoffset, mobj->spriteyoffset, frac);
out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac);
//out->subsector = R_PointInSubsector(out->x, out->y); // this is unused
if (mobj->player)
+1 -1
View File
@@ -1882,7 +1882,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// big room fix
if (longboi)
rw_distance = (fixed_t)R_CalcSegDist(curline, viewx, viewy);
rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy);
ds_p->x1 = rw_x = start;
ds_p->x2 = stop;
-4
View File
@@ -243,10 +243,6 @@ if(${SDL2_FOUND})
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(NOT SRB2_CONFIG_MUMBLE)
target_compile_options(SRB2SDL2 PRIVATE -DNOMUMBLE)
endif()
## strip debug symbols into separate file when using gcc
# if(CMAKE_COMPILER_IS_GNUCC)
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
-4
View File
@@ -1405,11 +1405,7 @@ void I_SleepDuration(precise_t duration)
duration -= slack;
struct timespec ts = {
.tv_sec = static_cast<__time_t>(duration / precision),
#ifdef __BIONIC__
.tv_nsec = static_cast<long>(duration * 1000000000 / precision % 1000000000),
#else
.tv_nsec = static_cast<__syscall_slong_t>(duration * 1000000000 / precision % 1000000000),
#endif
};
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
+6 -13
View File
@@ -581,19 +581,13 @@ const char *GetPalette(void)
if (user && user[0])
{
const lumpnum_t palnum = W_CheckNumForName(user);
if (palnum == LUMPERROR)
if (W_CheckNumForName(user) == LUMPERROR)
{
CONS_Alert(CONS_WARNING, "cv_palette %s lump does not exist\n", user);
}
else if (W_LumpLength(palnum) % (256 * 3) != 0) // not divisable by 768, so most def not a valid palette, idk if theres a better way to check this
{
CONS_Alert(CONS_WARNING, "cv_palette %s is not a valid palette lump\n", user);
}
else
{
return user;
return cv_palette.string;
}
}
@@ -615,16 +609,15 @@ void V_ReloadPalette(void)
void V_SetPalette(INT32 palettenum)
{
RGBA_t *pal = NULL;
if (!pLocalPalette)
V_ReloadPalette();
if (palettenum == 0)
{
#ifdef HWRENDER
if (rendermode == render_soft ||
(rendermode == render_opengl && HWR_ShouldUsePaletteRendering())) // opengl without paletterendering hates subpalettes
if (rendermode == render_soft ||
(rendermode == render_opengl && HWR_ShouldUsePaletteRendering())) // opengl without paletterendering hates subpalettes
#endif
{
if (palettenum == 0)
{
palettenum = cv_palettenum.value;
}