Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart into rideroid-hardcode

# Conflicts:
#	src/sounds.c
This commit is contained in:
toaster 2023-09-26 21:39:19 +01:00
commit bee1cb9a04
50 changed files with 959 additions and 1139 deletions

View file

@ -78,7 +78,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
r_sky.c
r_splats.c
r_spritefx.cpp
r_things.c
r_things.cpp
r_bbox.c
r_textures.c
r_textures_dups.cpp

View file

@ -926,6 +926,20 @@ bool CallFunc_Timer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word
return false;
}
/*--------------------------------------------------
bool CallFunc_IsNetworkGame(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Pushes netgame status to ACS.
--------------------------------------------------*/
bool CallFunc_IsNetworkGame(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
(void)argV;
(void)argC;
thread->dataStk.push(netgame);
return false;
}
/*--------------------------------------------------
bool CallFunc_SectorSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -1277,7 +1291,7 @@ bool CallFunc_PlayerRings(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:
/*--------------------------------------------------
bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Returns the activating player's ring count.
Returns the activating player's roundscore.
--------------------------------------------------*/
bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
@ -1584,6 +1598,31 @@ bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
return false;
}
/*--------------------------------------------------
bool CallFunc_PlayerBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Returns the activating player's bot status.
--------------------------------------------------*/
bool CallFunc_PlayerBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
auto info = &static_cast<Thread *>(thread)->info;
(void)argV;
(void)argC;
if ((info != NULL)
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
&& (info->mo->player != NULL))
{
thread->dataStk.push(info->mo->player->bot);
return false;
}
thread->dataStk.push(false);
return false;
}
/*--------------------------------------------------
bool CallFunc_GetObjectDye(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -1685,11 +1724,11 @@ bool CallFunc_EncoreMode(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
}
/*--------------------------------------------------
bool CallFunc_BreakTheCapsules(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
bool CallFunc_PrisonBreak(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Returns if the map is in Break the Capsules.
Returns if the map is in Prison Break mode.
--------------------------------------------------*/
bool CallFunc_BreakTheCapsules(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
bool CallFunc_PrisonBreak(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
(void)argV;
(void)argC;

View file

@ -53,6 +53,7 @@ bool CallFunc_PlayerCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:
bool CallFunc_GameType(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GameSpeed(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_Timer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_IsNetworkGame(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SectorSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_AmbientSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SetLineTexture(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
@ -74,12 +75,13 @@ bool CallFunc_CountPushables(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS
bool CallFunc_HaveUnlockableTrigger(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_HaveUnlockable(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PlayerBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GetObjectDye(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PlayerEmeralds(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PlayerLap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_LowestLap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_EncoreMode(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_BreakTheCapsules(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_PrisonBreak(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_TimeAttack(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GrandPrix(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_GetGrabbedSprayCan(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);

View file

@ -90,6 +90,7 @@ Environment::Environment()
addCodeDataACS0(100, {"", 3, addCallFunc(CallFunc_ThingSound)});
addCodeDataACS0(101, {"", 0, addCallFunc(CallFunc_EndPrintBold)});
addCodeDataACS0(118, {"", 0, addCallFunc(CallFunc_IsNetworkGame)});
addCodeDataACS0(119, {"", 0, addCallFunc(CallFunc_PlayerTeam)});
addCodeDataACS0(120, {"", 0, addCallFunc(CallFunc_PlayerRings)});
@ -162,11 +163,12 @@ Environment::Environment()
addFuncDataACS0( 307, addCallFunc(CallFunc_PlayerLap));
addFuncDataACS0( 308, addCallFunc(CallFunc_LowestLap));
addFuncDataACS0( 309, addCallFunc(CallFunc_EncoreMode));
addFuncDataACS0( 310, addCallFunc(CallFunc_BreakTheCapsules));
addFuncDataACS0( 310, addCallFunc(CallFunc_PrisonBreak));
addFuncDataACS0( 311, addCallFunc(CallFunc_TimeAttack));
addFuncDataACS0( 312, addCallFunc(CallFunc_ThingCount));
addFuncDataACS0( 313, addCallFunc(CallFunc_GrandPrix));
addFuncDataACS0( 314, addCallFunc(CallFunc_GetGrabbedSprayCan));
addFuncDataACS0( 315, addCallFunc(CallFunc_PlayerBot));
addFuncDataACS0( 500, addCallFunc(CallFunc_CameraWait));
addFuncDataACS0( 501, addCallFunc(CallFunc_PodiumPosition));

View file

@ -233,11 +233,6 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
return -1;
}
const CPUInfoFlags *I_CPUInfo(void)
{
return NULL;
}
const char *I_LocateWad(void)
{
return "/sdcard/srb2";

View file

@ -92,10 +92,6 @@
#include "hardware/hw_main.h" // 3D View Rendering
#endif
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
#include "lua_script.h"
/* Manually defined asset hashes
@ -514,6 +510,29 @@ static void D_Display(void)
ps_rendercalltime = I_GetPreciseTime();
if (rendermode == render_soft)
{
if (cv_homremoval.value)
{
if (cv_homremoval.value == 1)
{
// Clear the software screen buffer to remove HOM
memset(screens[0], 31, vid.width * vid.height * vid.bpp);
}
else
{
//'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
memset(screens[0], 32+(timeinmap&15), vid.width * vid.height * vid.bpp);
}
}
if (r_splitscreen == 2)
{
// Draw over the fourth screen so you don't have to stare at a HOM :V
V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART);
}
}
for (i = 0; i <= r_splitscreen; i++)
{
if (players[displayplayers[i]].mo || players[displayplayers[i]].playerstate == PST_DEAD)
@ -838,10 +857,6 @@ void D_SRB2Loop(void)
interp = R_UsingFrameInterpolation() && !dedicated;
doDisplay = false;
#ifdef HW3SOUND
HW3S_BeginFrameUpdate();
#endif
if (realtics > 0 || singletics)
{
// don't skip more than 10 frames at a time
@ -932,10 +947,6 @@ void D_SRB2Loop(void)
S_TickSoundTest();
}
#ifdef HW3SOUND
HW3S_EndFrameUpdate();
#endif
LUA_Step();
#ifdef HAVE_DISCORDRPC
@ -1671,8 +1682,8 @@ void D_SRB2Main(void)
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
I_StartupSound();
I_InitMusic();
S_InitSfxChannels(cv_soundvolume.value);
S_InitMusicVolume();
S_InitSfxChannels();
S_SetMusicVolume();
}
Music_Init();

View file

@ -342,6 +342,8 @@ struct respawnvars_t
boolean manual; // Respawn coords were manually set, please respawn exactly there
boolean fromRingShooter; // Respawn was from Ring Shooter, don't allow E-Brake drop
boolean init;
boolean fast; // Deaths after long airtime can leave you far away from your first waypoint, speed over there!
fixed_t returnspeed; // Used for consistent timing for deathpoint-to-first-waypoint travel.
};
typedef enum
@ -666,6 +668,7 @@ struct player_t
UINT16 superring; // You were awarded rings, and have this many of them left to spawn on yourself.
UINT8 nextringaward; // When should we spawn our next superring ring?
UINT16 ringvolume; // When consuming lots of rings, lower the sound a little.
UINT16 ringburst; // Queued number of rings to lose after hitlag ends
UINT8 curshield; // see kartshields_t
UINT8 bubblecool; // Bubble Shield use cooldown

View file

@ -15,46 +15,6 @@
#ifndef __DOOMDEF__
#define __DOOMDEF__
// Sound system select
// This should actually be in the makefile,
// but I can't stand that gibberish. D:
#define SOUND_DUMMY 0
#define SOUND_SDL 1
#define SOUND_MIXER 2
#define SOUND_FMOD 3
#ifndef SOUND
#ifdef HAVE_SDL
// Use Mixer interface?
#ifdef HAVE_MIXER
#define SOUND SOUND_MIXER
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#endif
// Use generic SDL interface.
#ifndef SOUND
#define SOUND SOUND_SDL
#endif
#else // No SDL.
// Use FMOD?
#ifdef HAVE_FMOD
#define SOUND SOUND_FMOD
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#else
// No more interfaces. :(
#define SOUND SOUND_DUMMY
#endif
#endif
#endif
#ifdef _WIN32
#define ASMCALL __cdecl
#else
@ -533,7 +493,7 @@ extern char gpbackup[256];
#define M_GetText(x) (x)
#endif
void M_StartupLocale(void);
extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL;
void *M_Memcpy(void* dest, const void* src, size_t n);
char *va(const char *format, ...) FUNCPRINTF;
char *M_GetToken(const char *inputString);

View file

@ -138,11 +138,6 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
return -1;
}
const CPUInfoFlags *I_CPUInfo(void)
{
return NULL;
}
const char *I_LocateWad(void)
{
return NULL;

View file

@ -280,40 +280,6 @@ char *I_GetUserName(void);
*/
INT32 I_mkdir(const char *dirname, INT32 unixright);
struct CPUInfoFlags {
int FPU : 1; ///< FPU availabile
int CPUID : 1; ///< CPUID instruction
int RDTSC : 1; ///< RDTSC instruction
int MMX : 1; ///< MMX features
int MMXExt : 1; ///< MMX Ext. features
int CMOV : 1; ///< Pentium Pro's "cmov"
int AMD3DNow : 1; ///< 3DNow features
int AMD3DNowExt: 1; ///< 3DNow! Ext. features
int SSE : 1; ///< SSE features
int SSE2 : 1; ///< SSE2 features
int SSE3 : 1; ///< SSE3 features
int IA64 : 1; ///< Running on IA64
int AMD64 : 1; ///< Running on AMD64
int AltiVec : 1; ///< AltiVec features
int FPPE : 1; ///< floating-point precision error
int PFC : 1; ///< TBD?
int cmpxchg : 1; ///< ?
int cmpxchg16b : 1; ///< ?
int cmp8xchg16 : 1; ///< ?
int FPE : 1; ///< FPU Emu
int DEP : 1; ///< Data excution prevent
int PPCMM64 : 1; ///< PowerPC Movemem 64bit ok?
int ALPHAbyte : 1; ///< ?
int PAE : 1; ///< Physical Address Extension
int CPUs : 8;
};
/** \brief Info about CPU
\return CPUInfo in bits
*/
const CPUInfoFlags *I_CPUInfo(void);
/** \brief Find main WAD
\return path to main WAD
*/

View file

@ -449,6 +449,25 @@ static line_t *K_FindBotController(mobj_t *mo)
}
}
/*--------------------------------------------------
fixed_t K_BotMapModifier(void)
See header file for description.
--------------------------------------------------*/
fixed_t K_BotMapModifier(void)
{
constexpr INT32 complexity_scale = 10000;
constexpr INT32 modifier_max = FRACUNIT * 2;
const fixed_t complexity_value = std::clamp<fixed_t>(
FixedDiv(K_GetTrackComplexity(), complexity_scale),
-modifier_max,
modifier_max * 2
);
return FRACUNIT + complexity_value;
}
/*--------------------------------------------------
static UINT32 K_BotRubberbandDistance(player_t *player)
@ -465,7 +484,7 @@ static UINT32 K_BotRubberbandDistance(player_t *player)
{
const UINT32 spacing = FixedDiv(640 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
const UINT8 portpriority = player - players;
UINT8 pos = 0;
UINT8 pos = 1;
UINT8 i;
if (player->botvars.rival)
@ -509,15 +528,22 @@ static UINT32 K_BotRubberbandDistance(player_t *player)
--------------------------------------------------*/
fixed_t K_BotRubberband(player_t *player)
{
constexpr fixed_t rubberdeltabase = FRACUNIT / 4; // +/- x0.25
// Lv. 1: x0.50 avg
// Lv. 9: x1.50 avg
const fixed_t difficultyEase = ((player->botvars.difficulty - 1) * FRACUNIT) / (DIFFICULTBOT - 1);
const fixed_t rubberavg = Easing_Linear(difficultyEase, FRACUNIT / 2, FRACUNIT * 3 / 2);
// Lv. 1: x0.35 min
// Lv. 9: x1.35 min
const fixed_t rubbermin = Easing_Linear(difficultyEase, FRACUNIT * 35 / 100, FRACUNIT * 135 / 100);
const fixed_t rubberdeltamin = FixedMul(rubberdeltabase, K_BotMapModifier());
const fixed_t rubbermin = std::max<fixed_t>(rubberavg - rubberdeltamin, FRACUNIT/3);
// Lv. 1: x1.0 max
// Lv. 1: x0.65 max
// Lv. 9: x1.65 max
const fixed_t rubbermax = Easing_Linear(difficultyEase, FRACUNIT, FRACUNIT * 165 / 100);
const fixed_t rubberdeltamax = FixedMul(rubberdeltabase, K_BotMapModifier());
const fixed_t rubbermax = std::min<fixed_t>(rubberavg - rubberdeltamax, FRACUNIT*3);
fixed_t rubberband = FRACUNIT >> 1;
player_t *firstplace = nullptr;
@ -550,6 +576,12 @@ fixed_t K_BotRubberband(player_t *player)
continue;
}
// Don't rubberband to ourselves...
if (player == &players[i])
{
continue;
}
#if 0
// Only rubberband up to players.
if (players[i].bot)
@ -566,15 +598,7 @@ fixed_t K_BotRubberband(player_t *player)
if (firstplace != nullptr)
{
// Lv. 1: 5120 units
// Lv. 9: 320 units
const fixed_t spacing = FixedDiv(
std::max<fixed_t>(
80 * mapobjectscale,
Easing_Linear(difficultyEase, 5120 * mapobjectscale, 320 * mapobjectscale)
),
K_GetKartGameSpeedScalar(gamespeed)
) / FRACUNIT;
const fixed_t spacing = FixedDiv(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
const UINT32 wanteddist = firstplace->distancetofinish + K_BotRubberbandDistance(player);
const INT32 distdiff = player->distancetofinish - wanteddist;
@ -745,7 +769,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
const precise_t time = I_GetPreciseTime();
// Stair janking makes it harder to steer, so attempt to steer harder.
const UINT8 jankDiv = (player->stairjank > 0) ? 2 : 1;
const UINT8 jankDiv = (player->stairjank > 0) ? 4 : 1;
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN) / jankDiv; // Reduce prediction based on how fast you can turn

View file

@ -26,10 +26,10 @@ extern "C" {
#endif
// Maximum value of botvars.difficulty
#define MAXBOTDIFFICULTY 13
#define MAXBOTDIFFICULTY (13)
// Level of a "difficult" bot. The max bot level was increased, but this keeps all of the same calculations.
#define DIFFICULTBOT 9
#define DIFFICULTBOT (9)
// How many tics in a row do you need to turn in this direction before we'll let you turn.
// Made it as small as possible without making it look like the bots are twitching constantly.
@ -51,7 +51,6 @@ struct botprediction_t
fixed_t radius, baseRadius;
};
// AVAILABLE FOR LUA
@ -86,6 +85,26 @@ boolean K_PlayerUsesBotMovement(player_t *player);
boolean K_BotCanTakeCut(player_t *player);
/*--------------------------------------------------
fixed_t K_BotMapModifier(void);
Gives a multiplier, based on the track complexity.
Track complexity is a measure of how easy it is for
the bots to continuously rubberband. This is used
to make the rubberbanding and other difficulty
adjustments feel roughly the same between wildly
different layouts.
Input Arguments:-
N/A
Return:-
A multiplier in fixed point scale, between 0.0 and 2.0.
--------------------------------------------------*/
fixed_t K_BotMapModifier(void);
/*--------------------------------------------------
fixed_t K_BotRubberband(player_t *player);

View file

@ -1449,11 +1449,16 @@ static void K_BotItemInstashield(player_t *player, ticcmd_t *cmd)
if (dist <= radius)
{
// Use it!!
cmd->buttons |= BT_ATTACK;
break;
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2);
}
}
if (player->botvars.itemconfirm > 10*TICRATE)
{
// Use it!!
cmd->buttons |= BT_ATTACK;
player->botvars.itemconfirm = 0;
}
}
/*--------------------------------------------------
@ -1494,7 +1499,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd)
player->itemRoulette.itemList[ player->itemRoulette.index ]
);
if (player->botvars.roulettePriority == currentPriority)
if (player->botvars.roulettePriority == currentPriority)
{
// This is the item we want! Start timing!
player->botvars.itemconfirm++;

View file

@ -28,6 +28,7 @@
#include "r_things.h" // numskins
#include "p_slopes.h" // P_GetZAt
#include "m_perfstats.h"
#include "k_objects.h"
/*--------------------------------------------------
static BlockItReturn_t K_FindEggboxes(mobj_t *thing)
@ -477,7 +478,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 1))
{
K_AddAttackObject(thing, side, 10);
K_AddAttackObject(thing, side, ((thing->extravalue1 < RINGBOX_TIME) ? 10 : 20));
}
break;
case MT_EGGMANITEM:
@ -493,11 +494,11 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
if (stealth >= requiredstealth)
{
K_AddAttackObject(thing, side, 10);
K_AddAttackObject(thing, side, 20);
}
else
{
K_AddDodgeObject(thing, side, 10);
K_AddDodgeObject(thing, side, 20);
}
}
break;

View file

@ -305,7 +305,7 @@ static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing)
lagadded = (thing->hitlag - oldhitlag);
if (lagadded > 0)
if (lagadded > minehitlag)
{
minehitlag = lagadded;
}
@ -337,19 +337,17 @@ tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
// Set this flag to ensure that the inital action won't be triggered twice.
actor->flags2 |= MF2_DEBRIS;
if (minehitlag == 0)
{
minehitlag = actor->hitlag;
}
// Set this flag to ensure the hitbox timer doesn't get extended with every player hit
actor->flags |= MF_NOHITLAGFORME;
actor->hitlag = 0; // same deal
if (!spin)
{
if (minehitlag == 0)
{
minehitlag = actor->hitlag;
}
Obj_SpawnBrolyKi(actor, minehitlag);
return minehitlag;
}

View file

@ -773,7 +773,8 @@ void K_FollowerHornTaunt(player_t *taunter, player_t *victim)
honk->fuse = TICRATE/2;
honk->renderflags |= RF_DONTDRAW;
S_StartSound(taunter->follower, fl->hornsound);
if (P_IsDisplayPlayer(victim) || P_IsDisplayPlayer(taunter))
S_StartSound(NULL, fl->hornsound);
honk->flags2 |= MF2_AMBUSH;
}

View file

@ -667,18 +667,25 @@ void K_RetireBots(void)
grabskins[usableskins] = MAXSKINS;
}
if (!grandprixinfo.gp) // Sure, let's let this happen all the time :)
if (grandprixinfo.gp) // Sure, let's let this happen all the time :)
{
newDifficulty = cv_kartbot.value;
if (grandprixinfo.masterbots == true)
{
newDifficulty = MAXBOTDIFFICULTY;
}
else
{
const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed);
newDifficulty = startingdifficulty - 4;
if (roundqueue.size > 0)
{
newDifficulty += roundqueue.roundnum;
}
}
}
else
{
const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed);
newDifficulty = startingdifficulty - 4;
if (roundqueue.size > 0)
{
newDifficulty += roundqueue.roundnum;
}
newDifficulty = cv_kartbot.value;
}
if (newDifficulty > MAXBOTDIFFICULTY)

View file

@ -18,6 +18,7 @@
#include "m_random.h"
#include "p_local.h"
#include "r_main.h"
#include "s_sound.h"
/*--------------------------------------------------
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
@ -129,13 +130,38 @@ static void K_SpawnSingleHitLagSpark(
}
}
/*--------------------------------------------------
static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics)
Plays a damage sound for a player.
Input Arguments:-
victim - Object getting damaged.
tics - How long the hitlag was.
Return:-
N/A
--------------------------------------------------*/
static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics)
{
sfxenum_t soundID = sfx_dmga1;
if (P_Random(PR_DECORATION) & 1) // might want to use this set for some other scenario, instead of randomized?
{
soundID = sfx_dmgb1;
}
soundID += ((tics * (NUM_HITLAG_SOUNDS - 1)) + (MAXHITLAGTICS >> 1)) / MAXHITLAGTICS;
S_StartSound(victim, soundID);
}
/*--------------------------------------------------
static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, UINT8 tics)
Spawns several hitlag sparks for damage.
Input Arguments:-
victim - Object getting touched.
victim - Object getting damaged.
inflictor - Object touching the victim. May be NULL.
source - Object that inflictor came from. May be NULL or same as inflictor.
tics - How long the hitlag was.
@ -152,6 +178,7 @@ static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source,
I_Assert(P_MobjWasRemoved(victim) == false);
K_PlayHitLagSFX(victim, tics);
P_StartQuakeFromMobj(tics, tics * 2 * mapobjectscale, 512 * mapobjectscale, victim);
if (P_MobjWasRemoved(inflictor) == false)

View file

@ -23,6 +23,7 @@ extern "C" {
#define MAXHITLAGTICS (30)
#define HITLAGJITTERS (FRACUNIT / 20)
#define NUM_HITLAG_STATES (9)
#define NUM_HITLAG_SOUNDS (4)
/*--------------------------------------------------
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage);

View file

@ -3358,8 +3358,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb
if (K_PlayerUsesBotMovement(player))
{
// Increase bot speed by 1-10% depending on difficulty
fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / DIFFICULTBOT;
// Increase bot speed by 0-10% depending on difficulty
const fixed_t modifier = K_BotMapModifier();
fixed_t add = ((player->botvars.difficulty-1) * FixedMul(FRACUNIT / 10, modifier)) / (DIFFICULTBOT-1);
finalspeed = FixedMul(finalspeed, FRACUNIT + add);
if (player->bot && player->botvars.rival)
@ -4511,6 +4512,11 @@ void K_MineFlashScreen(mobj_t *source)
INT32 pnum;
player_t *p;
if (P_MobjWasRemoved(source))
{
return;
}
S_StartSound(source, sfx_s3k4e);
P_StartQuakeFromMobj(12, 55 * source->scale, MINEQUAKEDIST * source->scale, source);
@ -4620,6 +4626,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay)
truc->hitlag += delay;
truc->renderflags |= RF_DONTDRAW;
}
Obj_SpawnBrolyKi(source, delay);
}
#undef MINEQUAKEDIST
@ -9111,15 +9119,23 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
INT32 K_GetKartRingPower(player_t *player, boolean boosted)
{
INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2;
fixed_t ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) * (FRACUNIT/2);
if (boosted == true && K_PlayerUsesBotMovement(player))
{
// Double for Lv. 9
ringPower += (player->botvars.difficulty * ringPower) / DIFFICULTBOT;
// x2.0 for Lv. 9
const fixed_t modifier = K_BotMapModifier();
fixed_t add = ((player->botvars.difficulty-1) * modifier) / (DIFFICULTBOT-1);
ringPower = FixedMul(ringPower, FRACUNIT + add);
if (player->botvars.rival == true)
{
// x2.0 for Rival
ringPower = FixedMul(ringPower, 2*FRACUNIT);
}
}
return ringPower;
return ringPower / FRACUNIT;
}
// Returns false if this player being placed here causes them to collide with any other player
@ -10657,10 +10673,11 @@ fixed_t K_PlayerBaseFriction(player_t *player, fixed_t original)
frict -= FixedMul(FRACUNIT >> 5, factor);
// Bots gain more traction as they rubberband.
if (player->botvars.rubberband > FRACUNIT)
fixed_t traction_value = FixedMul(player->botvars.rubberband, max(FRACUNIT, K_BotMapModifier()));
if (traction_value > FRACUNIT)
{
const fixed_t extraFriction = FixedMul(FRACUNIT >> 5, factor);
const fixed_t mul = player->botvars.rubberband - FRACUNIT;
const fixed_t mul = traction_value - FRACUNIT;
frict -= FixedMul(extraFriction, mul);
}
}
@ -10716,9 +10733,10 @@ void K_AdjustPlayerFriction(player_t *player)
{
player->mo->friction += 614;
}
else if (player->mo->eflags & MFE_UNDERWATER)
else if ((player->mo->eflags & MFE_UNDERWATER))
{
player->mo->friction += 312;
if (!K_Sliptiding(player))
player->mo->friction += 312;
}
// Wipeout slowdown

View file

@ -287,6 +287,8 @@ void K_DoIngameRespawn(player_t *player)
player->respawn.timer = RESPAWN_TIME;
player->respawn.state = RESPAWNST_MOVE;
player->respawn.init = true;
player->respawn.fast = true;
player->respawn.returnspeed = 0;
player->respawn.airtimer = player->airtime;
player->respawn.truedeath = !!(player->pflags & PF_FAULT);
@ -338,6 +340,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
{
const int airCompensation = 128;
fixed_t realstepamt = (64 * mapobjectscale);
UINT32 returntime = TICRATE;
fixed_t stepamt;
vector3_t dest, step, laser;
@ -379,6 +382,14 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
player->mo->z - dest.z
);
// Traveling from death location to first waypoint? Set speed to get there in a fixed time.
if (player->respawn.fast)
{
if (player->respawn.returnspeed == 0)
player->respawn.returnspeed = dist / returntime;
stepamt = max(stepamt, player->respawn.returnspeed);
}
if (dist <= stepamt)
{
// Reduce by the amount we needed to get to this waypoint
@ -391,6 +402,9 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
player->mo->z = dest.z;
P_SetThingPosition(player->mo);
// We are no longer traveling from death location to 1st waypoint, so use standard timings
player->respawn.fast = false;
// At the first valid waypoint, permit extra player control options.
player->respawn.init = false;

View file

@ -21,6 +21,13 @@
#include "g_game.h"
#include "p_slopes.h"
#include "cxxutil.hpp"
#include <algorithm>
#include <vector>
#include <fmt/format.h>
// The number of sparkles per waypoint connection in the waypoint visualisation
static const UINT32 SPARKLES_PER_CONNECTION = 16U;
@ -30,12 +37,16 @@ static const UINT32 SPARKLES_PER_CONNECTION = 16U;
#define CLOSEDSET_BASE_SIZE (256U)
#define NODESARRAY_BASE_SIZE (256U)
static waypoint_t *waypointheap = NULL;
static waypoint_t *waypointheap = NULL;
static waypoint_t *firstwaypoint = NULL;
static waypoint_t *finishline = NULL;
static waypoint_t *startingwaypoint = NULL;
static UINT32 circuitlength = 0U;
#define BASE_TRACK_COMPLEXITY (-5000) // Arbritrary, vibes-based value
static INT32 trackcomplexity = 0;
static size_t numwaypoints = 0U;
static size_t numwaypointmobjs = 0U;
static size_t baseopensetsize = OPENSET_BASE_SIZE;
@ -53,6 +64,16 @@ waypoint_t *K_GetFinishLineWaypoint(void)
return finishline;
}
/*--------------------------------------------------
waypoint_t *K_GetStartingWaypoint(void)
See header file for description.
--------------------------------------------------*/
waypoint_t *K_GetStartingWaypoint(void)
{
return startingwaypoint;
}
/*--------------------------------------------------
boolean K_GetWaypointIsFinishline(waypoint_t *waypoint)
@ -268,6 +289,16 @@ UINT32 K_GetCircuitLength(void)
return circuitlength;
}
/*--------------------------------------------------
INT32 K_GetTrackComplexity(void)
See header file for description.
--------------------------------------------------*/
INT32 K_GetTrackComplexity(void)
{
return trackcomplexity;
}
/*--------------------------------------------------
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
@ -1909,13 +1940,34 @@ static UINT32 K_SetupCircuitLength(void)
// line places people correctly relative to each other
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == LF_SECTIONRACE)
{
circuitlength = 0U;
path_t bestsprintpath = {0};
auto sprint_finally = srb2::finally([&bestsprintpath]() { Z_Free(bestsprintpath.array); });
const boolean useshortcuts = false;
const boolean huntbackwards = true;
const UINT32 traveldist = UINT32_MAX - UINT16_MAX; // Go as far back as possible. Not exactly UINT32_MAX to avoid possible overflow.
boolean pathfindsuccess = K_PathfindThruCircuit(
finishline, traveldist,
&bestsprintpath,
useshortcuts, huntbackwards
);
circuitlength = bestsprintpath.totaldist;
if (pathfindsuccess == true)
{
startingwaypoint = (waypoint_t *)bestsprintpath.array[ bestsprintpath.numnodes - 1 ].nodedata;
}
}
else
{
// Create a fake finishline waypoint, then try and pathfind to the finishline from it
waypoint_t fakefinishline = *finishline;
path_t bestcircuitpath = {0};
auto circuit_finally = srb2::finally([&bestcircuitpath]() { Z_Free(bestcircuitpath.array); });
const boolean useshortcuts = false;
const boolean huntbackwards = false;
@ -1923,7 +1975,12 @@ static UINT32 K_SetupCircuitLength(void)
circuitlength = bestcircuitpath.totaldist;
Z_Free(bestcircuitpath.array);
if (finishline->numnextwaypoints > 0)
{
// TODO: Implementing a version of the fakefinishline hack for
// this instead would be the most ideal
startingwaypoint = finishline->nextwaypoints[0];
}
}
return circuitlength;
@ -2127,8 +2184,7 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj)
}
else
{
CONS_Alert(
CONS_WARNING, "Waypoint with ID %d has no next waypoint.\n", K_GetWaypointID(thiswaypoint));
CONS_Debug(DBG_SETUP, "Waypoint with ID %d has no next waypoint.\n", K_GetWaypointID(thiswaypoint));
}
}
else
@ -2214,6 +2270,413 @@ static void K_FreeWaypoints(void)
K_ClearWaypoints();
}
namespace
{
/*--------------------------------------------------
BlockItReturn_t K_TrackWaypointNearOffroad(line_t *line)
Blockmap iteration function to check in an extra radius
around a waypoint to find any solid walls around it.
--------------------------------------------------*/
static fixed_t g_track_wp_x = INT32_MAX;
static fixed_t g_track_wp_y = INT32_MAX;
static fixed_t g_track_wp_radius = INT32_MAX;
static BlockItReturn_t K_TrackWaypointNearOffroad(line_t *line)
{
fixed_t dist = INT32_MAX;
vertex_t v = {0};
P_ClosestPointOnLine(
g_track_wp_x, g_track_wp_y,
line,
&v
);
dist = R_PointToDist2(
g_track_wp_x, g_track_wp_y,
v.x, v.y
);
const fixed_t buffer = FixedMul(mobjinfo[MT_PLAYER].radius * 2, mapobjectscale) * 3;
dist -= buffer;
if (dist <= 0) // line gets crossed
{
if ((line->flags & (ML_TWOSIDED|ML_IMPASSABLE|ML_BLOCKPLAYERS|ML_MIDSOLID)) == ML_TWOSIDED)
{
// double-sided, and no blocking flags -- it's not a wall
const INT32 side = P_PointOnLineSide(g_track_wp_x, g_track_wp_y, line);
const sector_t *sec = side ? line->frontsector : line->backsector;
if (sec != nullptr && (sec->damagetype == SD_DEATHPIT || sec->damagetype == SD_INSTAKILL))
{
// force kill sectors to be more complex
return BMIT_STOP;
}
}
else
{
// actually is a wall
return BMIT_ABORT;
}
}
// not crossed, or not a wall
return BMIT_CONTINUE;
}
/*--------------------------------------------------
boolean K_SneakerPanelOverlap(struct sneakerpanel &panelA, struct sneakerpanel &panelB)
Returns whenever or not a sneaker panel sector / thing overlap
--------------------------------------------------*/
struct complexity_sneaker_s
{
fixed_t bbox[4];
//std::vector<sector_t *> sectors;
//std::vector<mapthing_t *> things;
complexity_sneaker_s(sector_t *sec)
{
M_ClearBox(bbox);
for (size_t i = 0; i < sec->linecount; i++)
{
line_t *const ld = sec->lines[i];
M_AddToBox(bbox, ld->bbox[BOXRIGHT], ld->bbox[BOXTOP]);
M_AddToBox(bbox, ld->bbox[BOXLEFT], ld->bbox[BOXBOTTOM]);
}
}
complexity_sneaker_s(mapthing_t *mt)
{
M_ClearBox(bbox);
fixed_t x = mt->x << FRACBITS;
fixed_t y = mt->y << FRACBITS;
fixed_t radius = FixedMul(FixedMul(mobjinfo[MT_SNEAKERPANEL].radius, mt->scale), mapobjectscale);
M_AddToBox(bbox, x - radius, y - radius);
M_AddToBox(bbox, x + radius, y + radius);
}
};
static boolean K_SneakerPanelOverlap(complexity_sneaker_s &panelA, complexity_sneaker_s &panelB)
{
const fixed_t overlap_extra = 528 * mapobjectscale; // merge ones this close together
const fixed_t a_width_half = (panelA.bbox[BOXRIGHT] - panelA.bbox[BOXLEFT]) / 2;
const fixed_t a_height_half = (panelA.bbox[BOXTOP] - panelA.bbox[BOXBOTTOM]) / 2;
const fixed_t a_x = panelA.bbox[BOXLEFT] + a_width_half;
const fixed_t a_y = panelA.bbox[BOXBOTTOM] + a_height_half;
const fixed_t b_width_half = (panelB.bbox[BOXRIGHT] - panelB.bbox[BOXLEFT]) / 2;
const fixed_t b_height_half = (panelB.bbox[BOXTOP] - panelB.bbox[BOXBOTTOM]) / 2;
const fixed_t b_x = panelB.bbox[BOXLEFT] + b_width_half;
const fixed_t b_y = panelB.bbox[BOXBOTTOM] + b_height_half;
const fixed_t dx = b_x - a_x;
const fixed_t px = (b_width_half - a_width_half) - abs(dx);
if (px <= -overlap_extra)
{
return false;
}
const fixed_t dy = b_y - a_y;
const fixed_t py = (b_height_half - a_height_half) - abs(dy);
if (py <= -overlap_extra)
{
return false;
}
return true;
}
/*--------------------------------------------------
INT32 K_CalculateTrackComplexity(void)
Sets the value of trackcomplexity. This value accumulates all of the
turn angle deltas to get an idea of how complicated the map is.
--------------------------------------------------*/
static INT32 K_CalculateTrackComplexity(void)
{
const boolean huntbackwards = false;
const boolean useshortcuts = false;
boolean pathfindsuccess = false;
path_t path = {0};
trackcomplexity = BASE_TRACK_COMPLEXITY;
if (startingwaypoint == NULL || finishline == NULL)
{
return trackcomplexity;
}
pathfindsuccess = K_PathfindToWaypoint(
startingwaypoint, finishline,
&path,
useshortcuts, huntbackwards
);
if (pathfindsuccess == true)
{
auto path_finally = srb2::finally([&path]() { Z_Free(path.array); });
for (size_t i = 1; i < path.numnodes-1; i++)
{
waypoint_t *const start = (waypoint_t *)path.array[ i - 1 ].nodedata;
waypoint_t *const mid = (waypoint_t *)path.array[ i ].nodedata;
waypoint_t *const end = (waypoint_t *)path.array[ i + 1 ].nodedata;
const fixed_t start_mid_dist = R_PointToDist2(
start->mobj->x, start->mobj->y,
mid->mobj->x, mid->mobj->y
);
const fixed_t mid_end_dist = R_PointToDist2(
mid->mobj->x, mid->mobj->y,
end->mobj->x, end->mobj->y
);
const angle_t start_mid_angle = R_PointToAngle2(
start->mobj->x, start->mobj->y,
mid->mobj->x, mid->mobj->y
);
const angle_t mid_end_angle = R_PointToAngle2(
mid->mobj->x, mid->mobj->y,
end->mobj->x, end->mobj->y
);
const angle_t start_mid_pitch = R_PointToAngle2(
0, start->mobj->z,
start_mid_dist, mid->mobj->z
);
const angle_t mid_end_pitch = R_PointToAngle2(
0, mid->mobj->z,
mid_end_dist, end->mobj->z
);
const fixed_t avg_radius = (start->mobj->radius + mid->mobj->radius + end->mobj->radius) / 3;
const fixed_t base_scale = DEFAULT_WAYPOINT_RADIUS * mapobjectscale;
// Reduce complexity with wider turns.
fixed_t radius_factor = FixedDiv(
base_scale,
std::max<fixed_t>(
1,
avg_radius
)
);
radius_factor = FRACUNIT + ((radius_factor - FRACUNIT) / 2); // reduce how much it's worth
// Reduce complexity with wider spaced waypoints.
fixed_t dist_factor = FixedDiv(
base_scale,
std::max<fixed_t>(
1,
start_mid_dist + mid_end_dist
)
);
fixed_t wall_factor = FRACUNIT;
constexpr fixed_t minimum_turn = 10 * FRACUNIT; // If the delta is lower than this, it's practically a straight-away.
fixed_t delta = AngleFixed(
AngleDelta(
start_mid_angle,
mid_end_angle
)
) - minimum_turn;
if (delta < 0)
{
dist_factor = FixedDiv(FRACUNIT, std::max(1, dist_factor));
radius_factor = FixedDiv(FRACUNIT, std::max(1, radius_factor));
}
else
{
// Weight turns hard enough
delta = FixedMul(delta, delta);
// Reduce turn complexity in walled maps.
wall_factor = FRACUNIT;
g_track_wp_x = mid->mobj->x;
g_track_wp_y = mid->mobj->y;
g_track_wp_radius = mid->mobj->radius;
const fixed_t searchRadius = /*g_track_wp_radius +*/ MAXRADIUS;
INT32 xl, xh, yl, yh;
INT32 bx, by;
const fixed_t c = FixedMul(g_track_wp_radius, FINECOSINE((start_mid_angle + ANGLE_90) >> ANGLETOFINESHIFT));
const fixed_t s = FixedMul(g_track_wp_radius, FINESINE((start_mid_angle + ANGLE_90) >> ANGLETOFINESHIFT));
validcount++; // used to make sure we only process a line once
xl = (unsigned)((g_track_wp_x + c - searchRadius) - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)((g_track_wp_x + c + searchRadius) - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)((g_track_wp_y + s - searchRadius) - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)((g_track_wp_y + s + searchRadius) - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (bx = xl; bx <= xh; bx++)
{
for (by = yl; by <= yh; by++)
{
if (P_BlockLinesIterator(bx, by, K_TrackWaypointNearOffroad) == false)
{
wall_factor /= 4;
bx = xh + 1;
by = yh + 1;
}
}
}
validcount++; // used to make sure we only process a line once
xl = (unsigned)((g_track_wp_x - c - searchRadius) - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)((g_track_wp_x - c + searchRadius) - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)((g_track_wp_y - s - searchRadius) - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)((g_track_wp_y - s + searchRadius) - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (bx = xl; bx <= xh; bx++)
{
for (by = yl; by <= yh; by++)
{
if (P_BlockLinesIterator(bx, by, K_TrackWaypointNearOffroad) == false)
{
wall_factor /= 4;
bx = xh + 1;
by = yh + 1;
}
}
}
}
fixed_t pitch_delta = AngleFixed(
AngleDelta(
start_mid_pitch,
mid_end_pitch
)
);
constexpr fixed_t minimum_drop = 45 * FRACUNIT; // If the delta is lower than this, it's probably just a slope.
if (pitch_delta > minimum_drop)
{
// bonus complexity for drop-off / ramp
delta += FixedMul(pitch_delta, FRACUNIT + (pitch_delta - minimum_drop));
}
delta = FixedMul(delta, FixedMul(FixedMul(dist_factor, radius_factor), wall_factor));
std::string msg = fmt::format(
"TURN [{}]: r: {:.2f}, d: {:.2f}, w: {:.2f}, r*d*w: {:.2f}, DELTA: {}\n",
i,
FixedToFloat(radius_factor),
FixedToFloat(dist_factor),
FixedToFloat(wall_factor),
FixedToFloat(FixedMul(FixedMul(dist_factor, radius_factor), wall_factor)),
(delta / FRACUNIT)
);
CONS_Printf("%s", msg.c_str());
trackcomplexity += (delta / FRACUNIT);
}
std::vector<complexity_sneaker_s> sneaker_panels;
for (size_t i = 0; i < numsectors; i++)
{
sector_t *const sec = &sectors[i];
if (sec->linecount == 0)
{
continue;
}
terrain_t *terrain_f = K_GetTerrainForFlatNum(sec->floorpic);
terrain_t *terrain_c = K_GetTerrainForFlatNum(sec->ceilingpic);
if ((terrain_f != nullptr && (terrain_f->flags & TRF_SNEAKERPANEL))
|| (terrain_c != nullptr && (terrain_c->flags & TRF_SNEAKERPANEL)))
{
complexity_sneaker_s new_panel(sec);
boolean create_new = true;
for (size_t j = 0; j < sec->linecount; j++)
{
line_t *const ld = sec->lines[j];
M_AddToBox(new_panel.bbox, ld->bbox[BOXRIGHT], ld->bbox[BOXTOP]);
M_AddToBox(new_panel.bbox, ld->bbox[BOXLEFT], ld->bbox[BOXBOTTOM]);
}
for (auto &panel : sneaker_panels)
{
if (K_SneakerPanelOverlap(new_panel, panel) == true)
{
// merge together
M_AddToBox(panel.bbox, new_panel.bbox[BOXRIGHT], new_panel.bbox[BOXTOP]);
M_AddToBox(panel.bbox, new_panel.bbox[BOXLEFT], new_panel.bbox[BOXBOTTOM]);
//panel.sectors.push_back(sec);
create_new = false;
break;
}
}
if (create_new == true)
{
//new_panel.sectors.push_back(sec);
sneaker_panels.push_back(new_panel);
}
}
}
for (size_t i = 0; i < nummapthings; i++)
{
mapthing_t *const mt = &mapthings[i];
if (mt->type != mobjinfo[MT_SNEAKERPANEL].doomednum)
{
continue;
}
complexity_sneaker_s new_panel(mt);
boolean create_new = true;
for (auto &panel : sneaker_panels)
{
if (K_SneakerPanelOverlap(new_panel, panel) == true)
{
// merge together
M_AddToBox(panel.bbox, new_panel.bbox[BOXRIGHT], new_panel.bbox[BOXTOP]);
M_AddToBox(panel.bbox, new_panel.bbox[BOXLEFT], new_panel.bbox[BOXBOTTOM]);
create_new = false;
break;
}
}
if (create_new == true)
{
sneaker_panels.push_back(new_panel);
}
}
CONS_Printf("%s", fmt::format("Num sneaker panel sets: {}\n", sneaker_panels.size()).c_str());
trackcomplexity -= sneaker_panels.size() * 1250;
CONS_Printf(" ** COMPLEXITY: %d\n", trackcomplexity);
}
return trackcomplexity;
}
}; // namespace
/*--------------------------------------------------
boolean K_SetupWaypointList(void)
@ -2263,6 +2726,11 @@ boolean K_SetupWaypointList(void)
CONS_Alert(CONS_ERROR, "Circuit track waypoints do not form a circuit.\n");
}
if (startingwaypoint != NULL)
{
K_CalculateTrackComplexity();
}
setupsuccessful = true;
}
}
@ -2281,9 +2749,11 @@ void K_ClearWaypoints(void)
waypointheap = NULL;
firstwaypoint = NULL;
finishline = NULL;
startingwaypoint = NULL;
numwaypoints = 0U;
numwaypointmobjs = 0U;
circuitlength = 0U;
trackcomplexity = 0U;
}
/*--------------------------------------------------

View file

@ -55,6 +55,21 @@ struct waypoint_t
waypoint_t *K_GetFinishLineWaypoint(void);
/*--------------------------------------------------
waypoint_t *K_GetStartingWaypoint(void);
Return the waypoint farthest from the finish line.
Input Arguments:-
None
Return:-
The waypoint that is being used as the startingwaypoint.
--------------------------------------------------*/
waypoint_t *K_GetStartingWaypoint(void);
/*--------------------------------------------------
boolean K_GetWaypointIsFinishline(waypoint_t *waypoint)
@ -170,9 +185,26 @@ waypoint_t *K_GetWaypointFromID(INT32 waypointID);
Return:-
The circuit length.
--------------------------------------------------*/
UINT32 K_GetCircuitLength(void);
/*--------------------------------------------------
INT32 K_GetTrackComplexity(void)
Returns the track complexity values. This depends
on how many turns the map has, and is used for
bot code to determine their rubberbanding.
Input Arguments:-
Return:-
The track complexity value.
--------------------------------------------------*/
INT32 K_GetTrackComplexity(void);
/*--------------------------------------------------
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)

View file

@ -91,7 +91,7 @@ huddrawlist_h LUA_HUD_CreateDrawList(void)
{
huddrawlist_h drawlist;
drawlist = (huddrawlist_h) Z_CallocAlign(sizeof(struct huddrawlist_s), PU_STATIC, NULL, 64);
drawlist = (huddrawlist_h) Z_Calloc(sizeof(struct huddrawlist_s), PU_STATIC, NULL);
drawlist->items = NULL;
drawlist->items_capacity = 0;
drawlist->items_len = 0;
@ -152,7 +152,7 @@ static size_t AllocateDrawItem(huddrawlist_h list)
{
if (list->items_capacity == 0) list->items_capacity = 128;
else list->items_capacity *= 2;
list->items = (drawitem_t *) Z_ReallocAlign(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL, 64);
list->items = (drawitem_t *) Z_Realloc(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL);
}
return list->items_len++;
@ -171,7 +171,7 @@ static size_t CopyString(huddrawlist_h list, const char* str)
{
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
else list->strbuf_capacity *= 2;
list->strbuf = (char*) Z_ReallocAlign(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL, 8);
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
}
{

View file

@ -361,6 +361,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->nextringaward);
else if (fastcmp(field,"ringvolume"))
lua_pushinteger(L, plr->ringvolume);
else if (fastcmp(field,"ringburst"))
lua_pushinteger(L, plr->ringburst);
else if (fastcmp(field,"curshield"))
lua_pushinteger(L, plr->curshield);
else if (fastcmp(field,"bubblecool"))
@ -838,6 +840,8 @@ static int player_set(lua_State *L)
plr->nextringaward = luaL_checkinteger(L, 3);
else if (fastcmp(field,"ringvolume"))
plr->ringvolume = luaL_checkinteger(L, 3);
else if (fastcmp(field,"ringburst"))
plr->ringburst = luaL_checkinteger(L, 3);
else if (fastcmp(field,"curshield"))
plr->curshield = luaL_checkinteger(L, 3);
else if (fastcmp(field,"bubblecool"))

View file

@ -9,432 +9,13 @@
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_memcpy.c
/// \brief X86 optimized implementations of M_Memcpy
/// \brief (formerly) X86 optimized implementations of M_Memcpy
#include "doomdef.h"
#include "m_misc.h"
#if defined (__GNUC__) && defined (__i386__) // from libkwave, under GPL
// Alam: note libkwave memcpy code comes from mplayer's libvo/aclib_template.c, r699
/* for small memory blocks (<256 bytes) this version is faster */
#define small_memcpy(dest,src,n)\
{\
register unsigned long int dummy;\
__asm__ __volatile__(\
"cld\n\t"\
"rep; movsb"\
:"=&D"(dest), "=&S"(src), "=&c"(dummy)\
:"0" (dest), "1" (src),"2" (n)\
: "memory", "cc");\
}
/* linux kernel __memcpy (from: /include/asm/string.h) */
ATTRINLINE static FUNCINLINE void *__memcpy (void *dest, const void * src, size_t n)
void *M_Memcpy(void* dest, const void* src, size_t n)
{
int d0, d1, d2;
if ( n < 4 )
{
small_memcpy(dest, src, n);
}
else
{
__asm__ __volatile__ (
"rep ; movsl;"
"testb $2,%b4;"
"je 1f;"
"movsw;"
"1:\ttestb $1,%b4;"
"je 2f;"
"movsb;"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) dest),"2" ((long) src)
: "memory");
}
memcpy(dest, src, n);
return dest;
}
#define SSE_MMREG_SIZE 16
#define MMX_MMREG_SIZE 8
#define MMX1_MIN_LEN 0x800 /* 2K blocks */
#define MIN_LEN 0x40 /* 64-byte blocks */
/* SSE note: i tried to move 128 bytes a time instead of 64 but it
didn't make any measureable difference. i'm using 64 for the sake of
simplicity. [MF] */
static /*FUNCTARGET("sse2")*/ void *sse_cpy(void * dest, const void * src, size_t n)
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetchnta (%0);"
"prefetchnta 32(%0);"
"prefetchnta 64(%0);"
"prefetchnta 96(%0);"
"prefetchnta 128(%0);"
"prefetchnta 160(%0);"
"prefetchnta 192(%0);"
"prefetchnta 224(%0);"
"prefetchnta 256(%0);"
"prefetchnta 288(%0);"
: : "r" (src) );
if (n >= MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(SSE_MMREG_SIZE-1);
if (delta)
{
delta=SSE_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
if (((unsigned long)src) & 15)
/* if SRC is misaligned */
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movups (%0), %%xmm0;"
"movups 16(%0), %%xmm1;"
"movups 32(%0), %%xmm2;"
"movups 48(%0), %%xmm3;"
"movntps %%xmm0, (%1);"
"movntps %%xmm1, 16(%1);"
"movntps %%xmm2, 32(%1);"
"movntps %%xmm3, 48(%1);"
:: "r" (src), "r" (dest) : "memory");
src = (const unsigned char *)src + 64;
dest = (unsigned char *)dest + 64;
}
else
/*
Only if SRC is aligned on 16-byte boundary.
It allows to use movaps instead of movups, which required data
to be aligned or a general-protection exception (#GP) is generated.
*/
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movaps (%0), %%xmm0;"
"movaps 16(%0), %%xmm1;"
"movaps 32(%0), %%xmm2;"
"movaps 48(%0), %%xmm3;"
"movntps %%xmm0, (%1);"
"movntps %%xmm1, 16(%1);"
"movntps %%xmm2, 32(%1);"
"movntps %%xmm3, 48(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
/* since movntq is weakly-ordered, a "sfence"
* is needed to become ordered again. */
__asm__ __volatile__ ("sfence":::"memory");
/* enables to use FPU */
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
static FUNCTARGET("mmx") void *mmx2_cpy(void *dest, const void *src, size_t n)
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetchnta (%0);"
"prefetchnta 32(%0);"
"prefetchnta 64(%0);"
"prefetchnta 96(%0);"
"prefetchnta 128(%0);"
"prefetchnta 160(%0);"
"prefetchnta 192(%0);"
"prefetchnta 224(%0);"
"prefetchnta 256(%0);"
"prefetchnta 288(%0);"
: : "r" (src));
if (n >= MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movntq %%mm0, (%1);"
"movntq %%mm1, 8(%1);"
"movntq %%mm2, 16(%1);"
"movntq %%mm3, 24(%1);"
"movntq %%mm4, 32(%1);"
"movntq %%mm5, 40(%1);"
"movntq %%mm6, 48(%1);"
"movntq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
/* since movntq is weakly-ordered, a "sfence"
* is needed to become ordered again. */
__asm__ __volatile__ ("sfence":::"memory");
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
static FUNCTARGET("mmx") void *mmx1_cpy(void *dest, const void *src, size_t n) //3DNOW
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetch (%0);"
"prefetch 32(%0);"
"prefetch 64(%0);"
"prefetch 96(%0);"
"prefetch 128(%0);"
"prefetch 160(%0);"
"prefetch 192(%0);"
"prefetch 224(%0);"
"prefetch 256(%0);"
"prefetch 288(%0);"
: : "r" (src));
if (n >= MMX1_MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetch 320(%0);"
"prefetch 352(%0);"
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movq %%mm0, (%1);"
"movq %%mm1, 8(%1);"
"movq %%mm2, 16(%1);"
"movq %%mm3, 24(%1);"
"movq %%mm4, 32(%1);"
"movq %%mm5, 40(%1);"
"movq %%mm6, 48(%1);"
"movq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
__asm__ __volatile__ ("femms":::"memory"); // same as mmx_cpy() but with a femms
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
#endif
// Alam: why? memcpy may be __cdecl/_System and our code may be not the same type
static void *cpu_cpy(void *dest, const void *src, size_t n)
{
if (src == NULL)
{
CONS_Debug(DBG_MEMORY, "Memcpy from 0x0?!: %p %p %s\n", dest, src, sizeu1(n));
return dest;
}
if(dest == NULL)
{
CONS_Debug(DBG_MEMORY, "Memcpy to 0x0?!: %p %p %s\n", dest, src, sizeu1(n));
return dest;
}
return memcpy(dest, src, n);
}
static /*FUNCTARGET("mmx")*/ void *mmx_cpy(void *dest, const void *src, size_t n)
{
#if defined (_MSC_VER) && defined (_X86_)
_asm
{
mov ecx, [n]
mov esi, [src]
mov edi, [dest]
shr ecx, 6 // mit mmx: 64bytes per iteration
jz lower_64 // if lower than 64 bytes
loop_64: // MMX transfers multiples of 64bytes
movq mm0, 0[ESI] // read sources
movq mm1, 8[ESI]
movq mm2, 16[ESI]
movq mm3, 24[ESI]
movq mm4, 32[ESI]
movq mm5, 40[ESI]
movq mm6, 48[ESI]
movq mm7, 56[ESI]
movq 0[EDI], mm0 // write destination
movq 8[EDI], mm1
movq 16[EDI], mm2
movq 24[EDI], mm3
movq 32[EDI], mm4
movq 40[EDI], mm5
movq 48[EDI], mm6
movq 56[EDI], mm7
add esi, 64
add edi, 64
dec ecx
jnz loop_64
emms // close mmx operation
lower_64:// transfer rest of buffer
mov ebx,esi
sub ebx,src
mov ecx,[n]
sub ecx,ebx
shr ecx, 3 // multiples of 8 bytes
jz lower_8
loop_8:
movq mm0, [esi] // read source
movq [edi], mm0 // write destination
add esi, 8
add edi, 8
dec ecx
jnz loop_8
emms // close mmx operation
lower_8:
mov ebx,esi
sub ebx,src
mov ecx,[n]
sub ecx,ebx
rep movsb
mov eax, [dest] // return dest
}
#elif defined (__GNUC__) && defined (__i386__)
void *retval = dest;
size_t i;
if (n >= MMX1_MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movq %%mm0, (%1);"
"movq %%mm1, 8(%1);"
"movq %%mm2, 16(%1);"
"movq %%mm3, 24(%1);"
"movq %%mm4, 32(%1);"
"movq %%mm5, 40(%1);"
"movq %%mm6, 48(%1);"
"movq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
#else
return cpu_cpy(dest, src, n);
#endif
}
void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
/** Memcpy that uses MMX, 3DNow, MMXExt or even SSE
* Do not use on overlapped memory, use memmove for that
*/
void M_SetupMemcpy(void)
{
#if defined (__GNUC__) && defined (__i386__)
if (R_SSE2)
M_Memcpy = sse_cpy;
else if (R_MMXExt)
M_Memcpy = mmx2_cpy;
else if (R_3DNow)
M_Memcpy = mmx1_cpy;
else
#endif
if (R_MMX)
M_Memcpy = mmx_cpy;
#if 0
M_Memcpy = cpu_cpy;
#endif
}

View file

@ -128,8 +128,6 @@ TMatrix *RotateZMatrix(angle_t rad);
// s1 = s2+s3+s1 (1024 lenghtmax)
void strcatbf(char *s1, const char *s2, const char *s3);
void M_SetupMemcpy(void);
const char *M_FileError(FILE *handle);
int M_PathParts (const char *path);

View file

@ -37,6 +37,8 @@ Obj_SpawnBrolyKi
x = P_SpawnMobjFromMobj(
source, 0, 0, 0, MT_BROLY);
P_SetTarget(&x->target, source);
// Shrink into center of source object.
x->z = (source->z + source->height / 2);

View file

@ -1249,31 +1249,7 @@ static mobj_t *InitSpecialUFO(waypoint_t *start)
mobj_t *Obj_CreateSpecialUFO(void)
{
waypoint_t *finishWaypoint = K_GetFinishLineWaypoint();
waypoint_t *startWaypoint = NULL;
if (finishWaypoint != NULL)
{
const boolean huntbackwards = true;
const boolean useshortcuts = false;
const UINT32 traveldist = INT32_MAX; // Go as far back as possible. Not UINT32_MAX to avoid possible overflow.
boolean pathfindsuccess = false;
path_t pathtofinish = {0};
pathfindsuccess = K_PathfindThruCircuit(
finishWaypoint, traveldist,
&pathtofinish,
useshortcuts, huntbackwards
);
if (pathfindsuccess == true)
{
startWaypoint = (waypoint_t *)pathtofinish.array[ pathtofinish.numnodes - 1 ].nodedata;
Z_Free(pathtofinish.array);
}
}
return InitSpecialUFO(startWaypoint);
return InitSpecialUFO(K_GetStartingWaypoint());
}
UINT32 K_GetSpecialUFODistance(void)

View file

@ -36,10 +36,6 @@
#include "k_objects.h"
#include "k_roulette.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
player_t *stplyr;
@ -13063,12 +13059,11 @@ void A_SSMineExplode(mobj_t *actor)
void A_SSMineFlash(mobj_t *actor)
{
K_MineFlashScreen(actor);
K_MineFlashScreen(actor->target);
}
void A_LandMineExplode(mobj_t *actor)
{
mobj_t *expl;
INT32 colour = SKINCOLOR_KETCHUP; // we spell words properly here
INT32 i;

View file

@ -1440,7 +1440,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
ACS_RunPlayerDeathScript(target->player);
}
if (source && target && target->player && source->player)
if (source && target && target->player && source->player && (target->player != source->player))
P_PlayVictorySound(source); // Killer laughs at you. LAUGHS! BWAHAHAHA!
// Other death animation effects
@ -2760,8 +2760,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (type != DMG_STING)
player->flashing = K_GetKartFlashing(player);
P_PlayRinglossSound(target);
P_PlayerRingBurst(player, ringburst);
player->ringburst += ringburst;
K_PopPlayerShield(player);
player->instashield = 15;
@ -2837,6 +2836,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
#define RING_LAYER_SIDE_SIZE (3)
#define RING_LAYER_SIZE (RING_LAYER_SIDE_SIZE * 2)
static void P_FlingBurst
( player_t *player,
angle_t fa,
@ -2845,16 +2847,11 @@ static void P_FlingBurst
fixed_t objScale,
INT32 i)
{
mobj_t *mo;
fixed_t ns;
fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts
INT32 mx = (i + 1) >> 1;
mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType);
mobj_t *mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType);
P_SetTarget(&mo->target, player->mo);
mo->threshold = 10; // not useful for spikes
mo->fuse = objFuse;
P_SetTarget(&mo->target, player->mo);
// We want everything from P_SpawnMobjFromMobj except scale.
objScale = FixedMul(objScale, FixedDiv(mapobjectscale, player->mo->scale));
@ -2865,27 +2862,20 @@ static void P_FlingBurst
mo->destscale = mo->scale;
}
/*
0: 0
1: 1 = (1+1)/2 = 1
2: 1 = (2+1)/2 = 1
3: 2 = (3+1)/2 = 2
4: 2 = (4+1)/2 = 2
5: 3 = (4+1)/2 = 2
*/
// Angle / height offset changes every other ring
momxy -= mx * FRACUNIT;
momz += mx * (2<<FRACBITS);
if (i & 1)
{
fa += ANGLE_180;
}
ns = FixedMul(momxy, player->mo->scale);
mo->momx = (mo->target->momx/2) + FixedMul(FINECOSINE(fa>>ANGLETOFINESHIFT), ns);
mo->momy = (mo->target->momy/2) + FixedMul(FINESINE(fa>>ANGLETOFINESHIFT), ns);
// Pitch offset changes every other ring
angle_t offset = ANGLE_90 / (RING_LAYER_SIDE_SIZE + 2);
angle_t fp = offset + (((i / 2) % RING_LAYER_SIDE_SIZE) * (offset * 3 >> 1));
ns = FixedMul(momz, player->mo->scale);
mo->momz = (mo->target->momz/2) + ((ns) * P_MobjFlip(mo));
const UINT8 layer = i / RING_LAYER_SIZE;
const fixed_t thrust = (13 * mo->scale) + (7 * mo->scale * layer);
mo->momx = (player->mo->momx / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINECOSINE(fa >> ANGLETOFINESHIFT));
mo->momy = (player->mo->momy / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINESINE(fa >> ANGLETOFINESHIFT));
mo->momz = (player->mo->momz / 2) + (FixedMul(thrust, FINESINE(fp >> ANGLETOFINESHIFT)) * P_MobjFlip(mo));
}
/** Spills an injured player's rings.
@ -2897,7 +2887,7 @@ static void P_FlingBurst
*/
void P_PlayerRingBurst(player_t *player, INT32 num_rings)
{
INT32 num_fling_rings;
INT32 spill_total, num_fling_rings;
INT32 i;
angle_t fa;
@ -2919,8 +2909,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
else if (num_rings <= 0)
return;
num_rings = -P_GivePlayerRings(player, -num_rings);
num_fling_rings = num_rings+min(0, player->rings);
spill_total = -P_GivePlayerRings(player, -num_rings);
num_fling_rings = spill_total + min(0, player->rings);
// determine first angle
fa = player->mo->angle + ((P_RandomByte(PR_ITEM_RINGS) & 1) ? -ANGLE_90 : ANGLE_90);
@ -2930,7 +2920,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
P_FlingBurst(player, fa, MT_FLINGRING, 60*TICRATE, FRACUNIT, i);
}
while (i < num_rings)
while (i < spill_total)
{
P_FlingBurst(player, fa, MT_DEBTSPIKE, 0, 3 * FRACUNIT / 2, i++);
}

View file

@ -10085,6 +10085,14 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->player != NULL && mobj->hitlag == 0 && (mobj->eflags & MFE_DAMAGEHITLAG))
{
if (mobj->player->ringburst > 0)
{
// Delayed ring loss
P_PlayRinglossSound(mobj);
P_PlayerRingBurst(mobj->player, mobj->player->ringburst);
mobj->player->ringburst = 0;
}
K_HandleDirectionalInfluence(mobj->player);
}

View file

@ -468,6 +468,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT16(save->p, players[i].superring);
WRITEUINT8(save->p, players[i].nextringaward);
WRITEUINT8(save->p, players[i].ringvolume);
WRITEUINT16(save->p, players[i].ringburst);
WRITEUINT8(save->p, players[i].curshield);
WRITEUINT8(save->p, players[i].bubblecool);
@ -598,6 +599,8 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT32(save->p, players[i].respawn.dropdash);
WRITEUINT8(save->p, players[i].respawn.truedeath);
WRITEUINT8(save->p, players[i].respawn.manual);
WRITEUINT8(save->p, players[i].respawn.fast);
WRITEUINT32(save->p, players[i].respawn.returnspeed);
// botvars_t
WRITEUINT8(save->p, players[i].bot);
@ -975,6 +978,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].superring = READUINT16(save->p);
players[i].nextringaward = READUINT8(save->p);
players[i].ringvolume = READUINT8(save->p);
players[i].ringburst = READUINT16(save->p);
players[i].curshield = READUINT8(save->p);
players[i].bubblecool = READUINT8(save->p);
@ -1105,6 +1109,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].respawn.dropdash = READUINT32(save->p);
players[i].respawn.truedeath = READUINT8(save->p);
players[i].respawn.manual = READUINT8(save->p);
players[i].respawn.fast = READUINT8(save->p);
players[i].respawn.returnspeed = READUINT32(save->p);
// botvars_t
players[i].bot = READUINT8(save->p);

View file

@ -47,10 +47,7 @@
#include "k_respawn.h"
#include "k_terrain.h"
#include "acs/interface.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
#include "m_easing.h"
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h>
@ -9389,7 +9386,7 @@ void P_StartQuakeFromMobj(tic_t time, fixed_t intensity, fixed_t radius, mobj_t
quake->epicenter = (mappoint_t *)Z_Malloc(sizeof(mappoint_t), PU_LEVEL, NULL);
quake->epicenter->x = mobj->x;
quake->epicenter->y = mobj->y;
quake->epicenter->z = mobj->z;
quake->epicenter->z = mobj->z + (mobj->height / 2);
}
void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset)
@ -9411,17 +9408,25 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset)
ir = quake->intensity;
// Modulate with time remaining.
ir = FixedMul(ir, 2 * FRACUNIT * (quake->time + 1) / quake->startTime);
const fixed_t timeEase = (FRACUNIT * ((quake->startTime - quake->time) - 1)) / quake->startTime;
ir = Easing_InCubic(timeEase, ir, 0);
// Modulate with distance from epicenter, if it exists.
if (quake->radius > 0 && quake->epicenter != NULL)
{
fixed_t epidist = P_AproxDistance(
viewPos->x - quake->epicenter->x,
viewPos->y - quake->epicenter->y
);
const fixed_t distBuffer = 256 * mapobjectscale; // add a small buffer zone before it starts to drop off
const fixed_t epidist = P_AproxDistance(
P_AproxDistance(
viewPos->x - quake->epicenter->x,
viewPos->y - quake->epicenter->y
),
viewPos->z - quake->epicenter->z
) - distBuffer;
ir = FixedMul(ir, FixedDiv(max(0, quake->radius - epidist), quake->radius));
fixed_t distEase = FixedDiv(max(epidist, 0), quake->radius);
distEase = min(distEase, FRACUNIT);
ir = Easing_InCubic(distEase, ir, 0);
}
addZ += ir;

View file

@ -1026,7 +1026,7 @@ void P_Ticker(boolean run)
{
quake->epicenter->x = quake->mobj->x;
quake->epicenter->y = quake->mobj->y;
quake->epicenter->z = quake->mobj->z;
quake->epicenter->z = quake->mobj->z + (quake->mobj->height / 2);
}
quake = quake->next;

View file

@ -67,10 +67,6 @@
#include "music.h"
#include "k_tally.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
#ifdef HWRENDER
#include "hardware/hw_light.h"
#include "hardware/hw_main.h"

View file

@ -327,13 +327,12 @@ static void AddInterpolator(levelinterpolator_t* interpolator)
{
levelinterpolators_size *= 2;
}
levelinterpolators = Z_ReallocAlign(
levelinterpolators = Z_Realloc(
(void*) levelinterpolators,
sizeof(levelinterpolator_t*) * levelinterpolators_size,
PU_LEVEL,
NULL,
sizeof(levelinterpolator_t*) * 8
NULL
);
}
@ -343,11 +342,8 @@ static void AddInterpolator(levelinterpolator_t* interpolator)
static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker)
{
levelinterpolator_t *ret = (levelinterpolator_t*) Z_CallocAlign(
sizeof(levelinterpolator_t),
PU_LEVEL,
NULL,
sizeof(levelinterpolator_t) * 8
levelinterpolator_t *ret = (levelinterpolator_t*) Z_Calloc(
sizeof(levelinterpolator_t), PU_LEVEL, NULL
);
ret->type = type;
@ -662,12 +658,11 @@ void R_AddMobjInterpolator(mobj_t *mobj)
interpolated_mobjs_capacity *= 2;
}
interpolated_mobjs = Z_ReallocAlign(
interpolated_mobjs = Z_Realloc(
interpolated_mobjs,
sizeof(mobj_t *) * interpolated_mobjs_capacity,
PU_LEVEL,
NULL,
64
NULL
);
}

View file

@ -1475,26 +1475,6 @@ void R_RenderPlayerView(void)
INT32 nummasks = 1;
maskcount_t* masks = malloc(sizeof(maskcount_t));
// if this is display player 1
if (cv_homremoval.value && player == &players[displayplayers[0]])
{
if (cv_homremoval.value == 1)
{
// Clear the software screen buffer to remove HOM
memset(screens[0], 31, vid.width * vid.height * vid.bpp);
}
else
{
//'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
memset(screens[0], 32+(timeinmap&15), vid.width * vid.height * vid.bpp);
}
}
else if (r_splitscreen == 2 && player == &players[displayplayers[2]])
{
// Draw over the fourth screen so you don't have to stare at a HOM :V
V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART);
}
R_SetupFrame(viewssnum);
framecount++;
validcount++;

View file

@ -8,9 +8,11 @@
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_things.c
/// \file r_things.cpp
/// \brief Refresh of things, i.e. objects represented by sprites
#include <algorithm>
#include "doomdef.h"
#include "console.h"
#include "g_game.h"
@ -325,7 +327,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
if (Picture_IsLumpPNG((UINT8*)&patch, len))
{
UINT8 *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
UINT8 *png = static_cast<UINT8*>(W_CacheLumpNumPwad(wadnum, l, PU_STATIC));
Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len);
isPNG = true;
Z_Free(png);
@ -451,7 +453,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// allocate this sprite's frames
if (!spritedef->spriteframes)
spritedef->spriteframes =
Z_Malloc(maxframe * sizeof (*spritedef->spriteframes), PU_STATIC, NULL);
static_cast<spriteframe_t*>(Z_Malloc(maxframe * sizeof (*spritedef->spriteframes), PU_STATIC, NULL));
spritedef->numframes = maxframe;
M_Memcpy(spritedef->spriteframes, sprtemp, maxframe*sizeof (spriteframe_t));
@ -574,7 +576,7 @@ void R_InitSprites(void)
if (!numsprites)
I_Error("R_AddSpriteDefs: no sprites in namelist\n");
sprites = Z_Calloc(numsprites * sizeof (*sprites), PU_STATIC, NULL);
sprites = static_cast<spritedef_t*>(Z_Calloc(numsprites * sizeof (*sprites), PU_STATIC, NULL));
// find sprites in each -file added pwad
for (i = 0; i < numwadfiles; i++)
@ -765,13 +767,13 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 base
if (dc_yl <= dc_yh && dc_yh > 0)
{
dc_source = ZZ_Alloc(column->length);
dc_source = static_cast<UINT8*>(ZZ_Alloc(column->length));
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
*d++ = *s;
if (brightmap != NULL)
{
dc_brightmap = ZZ_Alloc(brightmap->length);
dc_brightmap = static_cast<UINT8*>(ZZ_Alloc(brightmap->length));
for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s)
*d++ = *s;
}
@ -825,7 +827,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
if (!(vis->cut & SC_PRECIP) &&
R_ThingIsFlashing(vis->mobj))
{
return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE);
return R_GetTranslationColormap(TC_HITLAG, static_cast<skincolornum_t>(0), GTC_CACHE);
}
/*
else if (R_SpriteIsFlashing(vis)) // Bosses "flash"
@ -842,14 +844,14 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
{
// New colormap stuff for skins Tails 06-07-2002
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
return R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
{
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
return R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap((INT32)skinnum, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
}
else // Use the defaults
return R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
}
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE);
@ -987,7 +989,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
vis->scale = FixedMul(vis->scale, this_scale);
vis->scalestep = FixedMul(vis->scalestep, this_scale);
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
vis->cut |= SC_ISSCALED;
vis->cut = static_cast<spritecut_e>(vis->cut | SC_ISSCALED);
}
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
}
@ -1066,12 +1068,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
// Vertically sheared sprite
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, dc_texturemid -= vis->shear.tan)
{
texturecolumn = frac>>FRACBITS;
texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1);
#ifdef RANGECHECK
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end, dc_x=%d, x2=%d, texturecolumn=%d (%d), pwidth=%d, xiscale=%d, startfrac=%d", vis->x2 - dc_x, dc_x, vis->x2, texturecolumn, frac, pwidth, vis->xiscale, vis->startfrac);
#endif
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
if (bmpatch)
bmcol = (column_t *)((UINT8 *)bmpatch->columns + (bmpatch->columnofs[texturecolumn]));
@ -1082,10 +1080,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else
{
#ifdef RANGECHECK
pwidth = patch->width;
#endif
#ifdef RANGECHECK
if (vis->x1test && vis->x2test)
{
INT32 x1test = vis->x1test;
@ -1099,21 +1095,18 @@ static void R_DrawVisSprite(vissprite_t *vis)
const INT32 t = (vis->startfrac + (vis->xiscale * (x2test - x1test))) >> FRACBITS;
if (x1test <= x2test && (t < 0 || t >= pwidth))
if (x1test <= x2test && (t < 0 || t >= patch->width))
{
CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1));
}
}
#endif // RANGECHECK
// Non-paper drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
{
texturecolumn = frac>>FRACBITS;
texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1);
#ifdef RANGECHECK
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end, dc_x=%d, x2=%d, texturecolumn=%d (%d), pwidth=%d, xiscale=%d, startfrac=%d", vis->x2 - dc_x, dc_x, vis->x2, texturecolumn, frac, pwidth, vis->xiscale, vis->startfrac);
#endif
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
if (bmpatch)
@ -1232,11 +1225,11 @@ static void R_SplitSprite(vissprite_t *sprite)
// Found a split! Make a new sprite, copy the old sprite to it, and
// adjust the heights.
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
newsprite = static_cast<vissprite_t*>(M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)));
newsprite->cut |= (sprite->cut & SC_FLAGMASK);
newsprite->cut = static_cast<spritecut_e>(newsprite->cut | (sprite->cut & SC_FLAGMASK));
sprite->cut |= SC_BOTTOM;
sprite->cut = static_cast<spritecut_e>(sprite->cut | SC_BOTTOM);
sprite->gz = testheight;
newsprite->gzt = sprite->gz;
@ -1246,7 +1239,7 @@ static void R_SplitSprite(vissprite_t *sprite)
newsprite->szt -= 8;
newsprite->cut |= SC_TOP;
newsprite->cut = static_cast<spritecut_e>(newsprite->cut | SC_TOP);
if (!(sector->lightlist[i].caster->fofflags & FOF_NOSHADE))
{
lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
@ -1294,7 +1287,7 @@ static patch_t *R_CacheSpriteBrightMap(const spriteinfo_t *sprinfo, UINT8 frame)
return NULL;
}
return W_CachePatchNum(num, PU_SPRITE);
return static_cast<patch_t*>(W_CachePatchNum(num, PU_SPRITE));
}
//
@ -1451,12 +1444,12 @@ static void R_ProjectDropShadow(
R_InterpolateMobjState(thing, FRACUNIT, &interp);
}
patch = W_CachePatchName("DSHADOW", PU_SPRITE);
patch = static_cast<patch_t*>(W_CachePatchName("DSHADOW", PU_SPRITE));
xscale = FixedDiv(projection[viewssnum], tz);
yscale = FixedDiv(projectiony[viewssnum], tz);
shadowxscale = FixedMul(thing->radius*2, scale);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scale), FixedDiv(abs(groundz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / patch->height;
shadowyscale = std::min(shadowyscale, shadowxscale) / patch->height;
shadowxscale /= patch->width;
shadowskew = 0;
@ -1511,7 +1504,7 @@ static void R_ProjectDropShadow(
shadow->sector = vis->sector;
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
shadow->cut = SC_ISSCALED|SC_SHADOW; //check this
shadow->cut = static_cast<spritecut_e>(SC_ISSCALED|SC_SHADOW); //check this
shadow->startfrac = 0;
//shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2);
@ -1636,7 +1629,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
box->sortscale = vis->sortscale; // link sorting to sprite
box->dispoffset = vis->dispoffset + 5;
box->cut |= SC_LINKDRAW;
box->cut = static_cast<spritecut_e>(box->cut | SC_LINKDRAW);
}
else
{
@ -1661,7 +1654,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
static fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
{
// Copied from P_UpdateSegLightOffset
const UINT8 contrast = min(max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX);
const UINT8 contrast = std::min(std::max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX);
const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
fixed_t light = FRACUNIT;
@ -1919,7 +1912,7 @@ static void R_ProjectSprite(mobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
patch = static_cast<patch_t*>(W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE));
#ifdef ROTSPRITE
spriterotangle = R_SpriteRotationAngle(thing, NULL);
@ -1940,7 +1933,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (rotsprite != NULL)
{
patch = rotsprite;
cut |= SC_ISROTATED;
cut = static_cast<spritecut_e>(cut | SC_ISROTATED);
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
@ -2022,7 +2015,7 @@ static void R_ProjectSprite(mobj_t *thing)
tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
if (std::max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return;
// Needs partially clipped
@ -2172,7 +2165,7 @@ static void R_ProjectSprite(mobj_t *thing)
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
sortscale = linkscale; // now make sure it's linked
cut |= SC_LINKDRAW;
cut = static_cast<spritecut_e>(cut | SC_LINKDRAW);
}
else if (splat)
{
@ -2245,7 +2238,7 @@ static void R_ProjectSprite(mobj_t *thing)
spritexscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spritexscale));
spriteyscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spriteyscale));
spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz));
spriteyscale = min(spriteyscale, spritexscale) / patch->height;
spriteyscale = std::min(spriteyscale, spritexscale) / patch->height;
spritexscale /= patch->width;
}
else
@ -2261,7 +2254,7 @@ static void R_ProjectSprite(mobj_t *thing)
gzt = (isflipped ? (interp.z + thing->height) : interp.z) + patch->height * spriteyscale / 2;
gz = gzt - patch->height * spriteyscale;
cut |= SC_SHEAR;
cut = static_cast<spritecut_e>(cut | SC_SHEAR);
}
}
@ -2330,7 +2323,7 @@ static void R_ProjectSprite(mobj_t *thing)
: R_PointToAngle(interp.x, interp.y));
// Less change in contrast in dark sectors
extralight = FixedMul(extralight, min(max(0, lightnum), LIGHTLEVELS - 1) * FRACUNIT / (LIGHTLEVELS - 1));
extralight = FixedMul(extralight, std::min(std::max(0, lightnum), LIGHTLEVELS - 1) * FRACUNIT / (LIGHTLEVELS - 1));
if (papersprite)
{
@ -2342,7 +2335,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT));
// Less change in contrast at further distances, to counteract DOOM diminished light
extralight = FixedMul(extralight, min(n, FRACUNIT));
extralight = FixedMul(extralight, std::min(n, FRACUNIT));
// Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance
lightnum += FixedFloor((extralight / 4) + (FRACUNIT / 2)) / FRACUNIT;
@ -2484,11 +2477,11 @@ static void R_ProjectSprite(mobj_t *thing)
vis->transmap = R_GetBlendTable(blendmode, trans);
if (R_ThingIsSemiBright(oldthing))
vis->cut |= SC_SEMIBRIGHT;
vis->cut = static_cast<spritecut_e>(vis->cut | SC_SEMIBRIGHT);
else if (R_ThingIsFullBright(oldthing))
vis->cut |= SC_FULLBRIGHT;
vis->cut = static_cast<spritecut_e>(vis->cut | SC_FULLBRIGHT);
else if (R_ThingIsFullDark(oldthing))
vis->cut |= SC_FULLDARK;
vis->cut = static_cast<spritecut_e>(vis->cut | SC_FULLDARK);
//
// determine the colormap (lightlevel & special effects)
@ -2517,9 +2510,9 @@ static void R_ProjectSprite(mobj_t *thing)
}
if (vflip)
vis->cut |= SC_VFLIP;
vis->cut = static_cast<spritecut_e>(vis->cut | SC_VFLIP);
if (splat)
vis->cut |= SC_SPLAT; // I like ya cut g
vis->cut = static_cast<spritecut_e>(vis->cut | SC_SPLAT); // I like ya cut g
vis->patch = patch;
vis->bright = R_CacheSpriteBrightMap(sprinfo, frame);
@ -2714,7 +2707,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE);
vis->patch = static_cast<patch_t*>(W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE));
vis->bright = R_CacheSpriteBrightMap(&spriteinfo[thing->sprite],
thing->frame & FF_FRAMEMASK);
@ -3300,7 +3293,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link)
if (node == &nodebankhead)
{
node = malloc(sizeof (*node));
node = static_cast<drawnode_t*>(malloc(sizeof (*node)));
if (!node)
I_Error("No more free memory to CreateDrawNode");
}
@ -3591,12 +3584,12 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal)
if (xclip == x)
{
spr->cut |= SC_CULL; // completely skip this sprite going forward
spr->cut = static_cast<spritecut_e>(spr->cut | SC_CULL); // completely skip this sprite going forward
}
else if (portal)
{
INT32 start_index = max(portal->start, x1);
INT32 end_index = min(portal->start + portal->end - portal->start, x2);
INT32 start_index = std::max(portal->start, x1);
INT32 end_index = std::min(portal->start + portal->end - portal->start, x2);
for (x = x1; x < start_index; x++)
{
spr->clipbot[x] = -1;
@ -3644,11 +3637,11 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
for (i = 0; i < DS_RANGES_COUNT; i++)
{
drawsegs_xranges[i].items = Z_Realloc(
drawsegs_xranges[i].items = static_cast<drawseg_xrange_item_t*>(Z_Realloc(
drawsegs_xranges[i].items,
drawsegs_xrange_size * sizeof(drawsegs_xranges[i].items[0]),
PU_STATIC, NULL
);
));
}
}
@ -3884,7 +3877,7 @@ void R_DrawMasked(maskcount_t* masks, INT32 nummasks)
drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */
INT32 i;
heads = calloc(nummasks, sizeof(drawnode_t));
heads = static_cast<drawnode_t*>(calloc(nummasks, sizeof(drawnode_t)));
for (i = 0; i < nummasks; i++)
{

View file

@ -37,12 +37,7 @@
#include "v_video.h" // V_ThinStringWidth
#include "music.h"
#ifdef HW3SOUND
// 3D Sound Interface
#include "hardware/hw3sound.h"
#else
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
#endif
static void Command_Tunes_f(void);
static void Command_RestartAudio_f(void);
@ -213,13 +208,6 @@ void SetChannelsNum(void)
if (cv_numChannels.value == 999999999) //Alam_GBC: OH MY ROD!(ROD rimmiced with GOD!)
CV_StealthSet(&cv_numChannels,cv_numChannels.defaultvalue);
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_SetSourcesNum();
return;
}
#endif
if (cv_numChannels.value)
channels = (channel_t *)Z_Calloc(cv_numChannels.value * sizeof (channel_t), PU_STATIC, NULL);
numofchannels = (channels ? cv_numChannels.value : 0);
@ -267,14 +255,6 @@ void S_StopSounds(void)
{
INT32 cnum;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_StopSounds();
return;
}
#endif
// kill all playing sounds at start of level
for (cnum = 0; cnum < numofchannels; cnum++)
if (channels[cnum].sfxinfo)
@ -294,13 +274,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
#if 0
if (!origin)
return;
#endif
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_StopSoundByID(origin, sfx_id);
return;
}
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
{
@ -315,13 +288,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
{
INT32 cnum;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_StopSoundByNum(sfxnum);
return;
}
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
{
if (channels[cnum].sfxinfo == &S_sfx[sfxnum])
@ -484,14 +450,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
}
}
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_StartSound(origin, sfx_id);
return;
};
#endif
for (i = 0; i <= r_splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
@ -649,12 +607,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
return;
// the volume is handled 8 bits
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
HW3S_StartSound(origin, sfx_id);
else
#endif
S_StartSoundAtVolume(origin, sfx_id, 255);
S_StartSoundAtVolume(origin, sfx_id, 255);
}
void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner)
@ -687,13 +640,6 @@ void S_StopSound(void *origin)
if (!origin)
return;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_StopSound(origin);
return;
}
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
{
if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
@ -721,9 +667,9 @@ void S_UpdateSounds(void)
// Update sound/music volumes, if changed manually at console
if (actualsfxvolume != cv_soundvolume.value)
S_SetSfxVolume (cv_soundvolume.value);
S_SetSfxVolume();
if (actualdigmusicvolume != cv_digmusicvolume.value)
S_SetDigMusicVolume (cv_digmusicvolume.value);
S_SetMusicVolume();
// We're done now, if we're not in a level.
if (gamestate != GS_LEVEL)
@ -765,14 +711,6 @@ void S_UpdateSounds(void)
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
#endif
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_UpdateSources();
goto notinlevel;
}
#endif
for (i = 0; i <= r_splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
@ -914,17 +852,12 @@ void S_UpdateClosedCaptions(void)
}
}
void S_SetSfxVolume(INT32 volume)
void S_SetSfxVolume(void)
{
//CV_SetValue(&cv_soundvolume, volume);
actualsfxvolume = volume;
actualsfxvolume = cv_soundvolume.value;
#ifdef HW3SOUND
hws_mode == HWS_DEFAULT_MODE ? I_SetSfxVolume(volume&0x1F) : HW3S_SetSfxVolume(volume&0x1F);
#else
// now hardware volume
I_SetSfxVolume(volume);
#endif
I_SetSfxVolume(actualsfxvolume);
}
void S_ClearSfx(void)
@ -1128,11 +1061,6 @@ INT32 S_OriginPlaying(void *origin)
if (!origin)
return false;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
return HW3S_OriginPlaying(origin);
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
if (channels[cnum].origin == origin)
return 1;
@ -1145,11 +1073,6 @@ INT32 S_IdPlaying(sfxenum_t id)
{
INT32 cnum;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
return HW3S_IdPlaying(id);
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
return 1;
@ -1164,11 +1087,6 @@ INT32 S_SoundPlaying(void *origin, sfxenum_t id)
if (!origin)
return 0;
#ifdef HW3SOUND
if (hws_mode != HWS_DEFAULT_MODE)
return HW3S_SoundPlaying(origin, id);
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
{
if (channels[cnum].origin == origin
@ -1230,7 +1148,7 @@ void S_StartSoundName(void *mo, const char *soundname)
// Sets channels, SFX volume,
// allocates channel buffer, sets S_sfx lookup.
//
void S_InitSfxChannels(INT32 sfxVolume)
void S_InitSfxChannels(void)
{
extern consvar_t precachesound;
@ -1239,7 +1157,7 @@ void S_InitSfxChannels(INT32 sfxVolume)
if (dedicated)
return;
S_SetSfxVolume(sfxVolume);
S_SetSfxVolume();
SetChannelsNum();
@ -2091,14 +2009,10 @@ void S_ResumeAudio(void)
Music_UnPauseAll();
}
void S_SetMusicVolume(INT32 digvolume)
void S_SetMusicVolume(void)
{
if (digvolume < 0)
digvolume = cv_digmusicvolume.value;
//CV_SetValue(&cv_digmusicvolume, digvolume);
actualdigmusicvolume = digvolume;
I_SetMusicVolume(digvolume);
actualdigmusicvolume = cv_digmusicvolume.value;
I_SetMusicVolume(actualdigmusicvolume);
}
/// ------------------------
@ -2219,8 +2133,8 @@ static void Command_RestartAudio_f(void)
// These must be called or no sound and music until manually set.
I_SetSfxVolume(cv_soundvolume.value);
S_SetMusicVolume(cv_digmusicvolume.value);
S_SetSfxVolume();
S_SetMusicVolume();
S_StartSound(NULL, sfx_strpst);
@ -2392,7 +2306,7 @@ void GameSounds_OnChange(void)
{
sound_disabled = false;
I_StartupSound(); // will return early if initialised
S_InitSfxChannels(cv_soundvolume.value);
S_InitSfxChannels();
S_StartSound(NULL, sfx_strpst);
}
else
@ -2431,7 +2345,7 @@ void PlayMusicIfUnfocused_OnChange(void)
if (cv_playmusicifunfocused.value)
I_SetMusicVolume(0);
else
S_InitMusicVolume();
S_SetMusicVolume();
}
}

View file

@ -98,7 +98,7 @@ void S_RegisterSoundStuff(void);
// Initializes sound stuff, including volume
// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup.
//
void S_InitSfxChannels(INT32 sfxVolume);
void S_InitSfxChannels(void);
//
// Per level startup code.
@ -237,10 +237,8 @@ FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1,
INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume);
void S_SetSfxVolume(INT32 volume);
void S_SetMusicVolume(INT32 digvolume);
#define S_SetDigMusicVolume S_SetMusicVolume
#define S_InitMusicVolume() S_SetMusicVolume(-1)
void S_SetSfxVolume(void);
void S_SetMusicVolume(void);
INT32 S_OriginPlaying(void *origin);
INT32 S_IdPlaying(sfxenum_t id);
@ -251,10 +249,8 @@ void S_StartSoundName(void *mo, const char *soundname);
void S_StopSoundByID(void *origin, sfxenum_t sfx_id);
void S_StopSoundByNum(sfxenum_t sfxnum);
#ifndef HW3SOUND
#define S_StartAttackSound S_StartSound
#define S_StartScreamSound S_StartSound
#endif
#ifdef __cplusplus
} // extern "C"

View file

@ -319,50 +319,6 @@ void SCR_SetMode(void)
//
void SCR_Startup(void)
{
const CPUInfoFlags *RCpuInfo = I_CPUInfo();
if (!M_CheckParm("-NOCPUID") && RCpuInfo)
{
#if defined (__i386__) || defined (_M_IX86) || defined (__WATCOMC__)
R_486 = true;
#endif
if (RCpuInfo->RDTSC)
R_586 = true;
if (RCpuInfo->MMX)
R_MMX = true;
if (RCpuInfo->AMD3DNow)
R_3DNow = true;
if (RCpuInfo->MMXExt)
R_MMXExt = true;
if (RCpuInfo->SSE)
R_SSE = true;
if (RCpuInfo->SSE2)
R_SSE2 = true;
CONS_Printf("CPU Info: 486: %i, 586: %i, MMX: %i, 3DNow: %i, MMXExt: %i, SSE2: %i\n", R_486, R_586, R_MMX, R_3DNow, R_MMXExt, R_SSE2);
}
if (M_CheckParm("-noASM"))
R_ASM = false;
if (M_CheckParm("-486"))
R_486 = true;
if (M_CheckParm("-586"))
R_586 = true;
if (M_CheckParm("-MMX"))
R_MMX = true;
if (M_CheckParm("-3DNow"))
R_3DNow = true;
if (M_CheckParm("-MMXExt"))
R_MMXExt = true;
if (M_CheckParm("-SSE"))
R_SSE = true;
if (M_CheckParm("-noSSE"))
R_SSE = false;
if (M_CheckParm("-SSE2"))
R_SSE2 = true;
M_SetupMemcpy();
if (dedicated)
{
V_Init();

View file

@ -2423,70 +2423,6 @@ UINT32 I_GetFreeMem(UINT32 *total)
#endif
}
const CPUInfoFlags *I_CPUInfo(void)
{
#if defined (_WIN32)
static CPUInfoFlags WIN_CPUInfo;
SYSTEM_INFO SI;
p_IsProcessorFeaturePresent pfnCPUID;
*(void**)&pfnCPUID = FUNCPTRCAST(GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"));
ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo));
if (pfnCPUID)
{
WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA
WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED
WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE
WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE
WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK
WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS
WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE
WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE
WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE
WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED
WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE
//WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE
WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED
WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE
WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128
WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128
WIN_CPUInfo.PFC = pfnCPUID(16); //PF_CHANNELS_ENABLED
}
#ifdef HAVE_SDLCPUINFO
else
{
WIN_CPUInfo.RDTSC = SDL_HasRDTSC();
WIN_CPUInfo.MMX = SDL_HasMMX();
WIN_CPUInfo.AMD3DNow = SDL_Has3DNow();
WIN_CPUInfo.SSE = SDL_HasSSE();
WIN_CPUInfo.SSE2 = SDL_HasSSE2();
WIN_CPUInfo.AltiVec = SDL_HasAltiVec();
}
WIN_CPUInfo.MMXExt = SDL_FALSE; //SDL_HasMMXExt(); No longer in SDL2
WIN_CPUInfo.AMD3DNowExt = SDL_FALSE; //SDL_Has3DNowExt(); No longer in SDL2
#endif
GetSystemInfo(&SI);
WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors;
WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64
WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664
return &WIN_CPUInfo;
#elif defined (HAVE_SDLCPUINFO)
static CPUInfoFlags SDL_CPUInfo;
memset(&SDL_CPUInfo,0,sizeof (CPUInfoFlags));
SDL_CPUInfo.RDTSC = SDL_HasRDTSC();
SDL_CPUInfo.MMX = SDL_HasMMX();
SDL_CPUInfo.MMXExt = SDL_FALSE; //SDL_HasMMXExt(); No longer in SDL2
SDL_CPUInfo.AMD3DNow = SDL_Has3DNow();
SDL_CPUInfo.AMD3DNowExt = SDL_FALSE; //SDL_Has3DNowExt(); No longer in SDL2
SDL_CPUInfo.SSE = SDL_HasSSE();
SDL_CPUInfo.SSE2 = SDL_HasSSE2();
SDL_CPUInfo.AltiVec = SDL_HasAltiVec();
return &SDL_CPUInfo;
#else
return NULL; /// \todo CPUID asm
#endif
}
// note CPUAFFINITY code used to reside here
void I_RegisterSysCommands(void) {}

View file

@ -513,7 +513,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
// Tell game we got focus back, resume music if necessary
window_notinfocus = false;
S_InitMusicVolume();
S_SetMusicVolume();
if (!firsttimeonmouse)
{

View file

@ -1215,6 +1215,16 @@ sfxinfo_t S_sfx[NUMSFX] =
{"ridr3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Loop
{"ridr4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Leaving Rideroid
// Damage sounds
{"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmga3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmga4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmgb1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmgb2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmgb3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmgb4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
// SRB2Kart - Engine sounds
// Engine class A
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},

View file

@ -1285,6 +1285,16 @@ typedef enum
sfx_ridr3,
sfx_ridr4,
// Damage sounds
sfx_dmga1,
sfx_dmga2,
sfx_dmga3,
sfx_dmga4,
sfx_dmgb1,
sfx_dmgb2,
sfx_dmgb3,
sfx_dmgb4,
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
// Engine class A - Low Speed, Low Weight
sfx_krta00,

View file

@ -159,7 +159,6 @@ TYPEDEF (bannednode_t);
// i_system.h
TYPEDEF (JoyFF_t);
TYPEDEF (CPUInfoFlags);
// i_time.h
TYPEDEF (timestate_t);

View file

@ -1613,7 +1613,8 @@ finalcounter:
if (Y_CanSkipIntermission())
{
Y_DrawIntermissionButton(INTERBUTTONSLIDEIN - intertic, 3*TICRATE - timer);
const tic_t end = roundqueue.size != 0 ? 3*TICRATE : TICRATE;
Y_DrawIntermissionButton(INTERBUTTONSLIDEIN - intertic, end - timer);
}
else
{

View file

@ -25,6 +25,9 @@
/// allocator was fragmenting badly. Finally, this version is a bit
/// simpler (about half the lines of code).
#include <stddef.h>
#include <stdalign.h>
#include <tracy/tracy/TracyC.h>
#include "doomdef.h"
@ -49,27 +52,12 @@ static boolean Z_calloc = false;
#define ZONEID 0xa441d13d
struct memblock_s;
typedef struct
{
struct memblock_s *block; // Describing this memory
UINT32 id; // Should be ZONEID
} ATTRPACK memhdr_t;
// Some code might want aligned memory. Assume it wants memory n bytes
// aligned -- then we allocate n-1 extra bytes and return a pointer to
// the first byte aligned as requested.
// Thus, "real" is the pointer we get from malloc() and will free()
// later, but "hdr" is where the memhdr_t starts.
// For non-aligned allocations they will be the same.
typedef struct memblock_s
{
void *real;
memhdr_t *hdr;
void **user;
INT32 tag; // purgelevel
UINT32 id; // Should be ZONEID
size_t size; // including the header and blocks
size_t realsize; // size of real data only
@ -78,7 +66,11 @@ typedef struct memblock_s
INT32 ownerline;
struct memblock_s *next, *prev;
} ATTRPACK memblock_t;
} memblock_t;
#define ALIGNPAD (((sizeof (memblock_t) + (alignof (max_align_t) - 1)) & ~(alignof (max_align_t) - 1)) - sizeof (memblock_t))
#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t) + ALIGNPAD)
#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 head;
@ -119,52 +111,6 @@ void Z_Init(void)
// Zone memory allocation
// ----------------------
/** Returns the corresponding memblock_t for a given memory block.
*
* \param ptr A pointer to allocated memory,
* assumed to have been allocated with Z_Malloc/Z_Calloc.
* \param func A string containing the name of the function that called this,
* to be printed if the function I_Errors
* \return A pointer to the memblock_t for the given memory.
* \sa Z_Free, Z_ReallocAlign
*/
#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__)
static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line)
{
memhdr_t *hdr;
memblock_t *block;
if (ptr == NULL)
return NULL;
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "%s %s:%d\n", func, file, line);
#endif
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
#ifdef VALGRIND_MEMPOOL_EXISTS
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
{
I_Error("%s: bad memblock from %s:%d", func, file, line);
}
#endif
if (hdr->id != ZONEID)
{
I_Error("%s: wrong id from %s:%d", func, file, line);
}
block = hdr->block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
#endif
return block;
}
/** Frees allocated memory.
*
* \param ptr A pointer to allocated memory,
@ -185,7 +131,11 @@ void Z_Free2(void *ptr, const char *file, INT32 line)
#endif
*/
block = Ptr2Memblock2(ptr, "Z_Free", file, line);
block = MEMBLOCK(ptr);
#ifdef PARANOIA
if (block->id != ZONEID)
I_Error("Z_Free at %s:%d: wrong id", file, line);
#endif
// Write every Z_Free call to a debug file.
CONS_Debug(DBG_MEMORY, "Z_Free at %s:%d\n", file, line);
@ -201,9 +151,6 @@ void Z_Free2(void *ptr, const char *file, INT32 line)
if (block->user != NULL)
*block->user = NULL;
// Free the memory and get rid of the block.
TracyCFree(block->real);
free(block->real);
#ifdef VALGRIND_DESTROY_MEMPOOL
VALGRIND_DESTROY_MEMPOOL(block);
#endif
@ -256,35 +203,19 @@ static void *xm(size_t size)
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
const char *file, INT32 line)
{
size_t extrabytes = (1<<alignbits) - 1;
size_t padsize = 0;
memblock_t *block;
void *ptr;
memhdr_t *hdr;
void *given;
size_t blocksize = extrabytes + sizeof *hdr + size;
(void)(alignbits); // no longer used, so silence warnings. TODO we should figure out a solution for this
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
#endif
if (blocksize < size)/* overflow check */
I_Error("You are allocating memory too large!");
block = xm(sizeof *block);
#ifdef HAVE_VALGRIND
padsize += (1<<sizeof(size_t))*2;
#endif
ptr = xm(blocksize + padsize*2);
TracyCAlloc(ptr, blocksize);
// This horrible calculation makes sure that "given" is aligned
// properly.
given = (void *)((size_t)((UINT8 *)ptr + extrabytes + sizeof *hdr + padsize/2)
& ~extrabytes);
// The mem header lives 'sizeof (memhdr_t)' bytes before given.
hdr = (memhdr_t *)((UINT8 *)given - sizeof *hdr);
block = xm(sizeof (memblock_t) + ALIGNPAD + size);
TracyCAlloc(block, sizeof (memblock_t) + ALIGNPAD + size);
ptr = MEMORY(block);
I_Assert((intptr_t)ptr % alignof (max_align_t) == 0);
#ifdef HAVE_VALGRIND
Z_calloc = false;
@ -295,39 +226,29 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
head.next = block;
block->next->prev = block;
block->real = ptr;
block->hdr = hdr;
block->tag = tag;
block->user = NULL;
block->ownerline = line;
block->ownerfile = file;
block->size = blocksize;
block->size = sizeof (memblock_t) + size;
block->realsize = size;
#ifdef VALGRIND_CREATE_MEMPOOL
VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc);
VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc);
#endif
//#ifdef VALGRIND_MEMPOOL_ALLOC
// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr);
//#endif
hdr->id = ZONEID;
hdr->block = block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
#endif
block->id = ZONEID;
if (user != NULL)
{
block->user = user;
*(void **)user = given;
*(void **)user = ptr;
}
else if (tag >= PU_PURGELEVEL)
I_Error("Z_Malloc: attempted to allocate purgable block "
"(size %s) with no user", sizeu1(size));
return given;
return ptr;
}
/** The Z_CallocAlign function.
@ -388,7 +309,11 @@ void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits,
return Z_Calloc2(size, tag, user, alignbits, file , line);
}
block = Ptr2Memblock2(ptr, "Z_Realloc", file, line);
block = MEMBLOCK(ptr);
#ifdef PARANOIA
if (block->id != ZONEID)
I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line);
#endif
if (block == NULL)
return NULL;
@ -430,9 +355,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
for (block = head.next; block != &head; block = next)
{
next = block->next; // get link before freeing
if (block->tag >= lowtag && block->tag <= hightag)
Z_Free((UINT8 *)block->hdr + sizeof *block->hdr);
Z_Free(MEMORY(block));
}
}
@ -455,7 +379,7 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
if (block->tag >= lowtag && block->tag <= hightag)
{
void *mem = (UINT8 *)block->hdr + sizeof *block->hdr;
void *mem = MEMORY(block);
boolean free = iterfunc(mem);
if (free)
Z_Free(mem);
@ -500,15 +424,13 @@ void Z_CheckMemCleanup(void)
void Z_CheckHeap(INT32 i)
{
memblock_t *block;
memhdr_t *hdr;
UINT32 blocknumon = 0;
void *given;
for (block = head.next; block != &head; block = block->next)
{
blocknumon++;
hdr = block->hdr;
given = (UINT8 *)hdr + sizeof *hdr;
given = MEMORY(block);
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
blocknumon, block->ownerfile, block->ownerline);
@ -519,6 +441,7 @@ void Z_CheckHeap(INT32 i)
I_Error("Z_CheckHeap %d: block %u"
"(owned by %s:%d)"
" should not exist", i, blocknumon,
" should not exist", i, blocknumon,
block->ownerfile, block->ownerline
);
}
@ -550,16 +473,7 @@ void Z_CheckHeap(INT32 i)
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
if (hdr->block != block)
{
I_Error("Z_CheckHeap %d: block %u"
"(owned by %s:%d)"
" doesn't have linkback from allocated memory",
i, blocknumon,
block->ownerfile, block->ownerline
);
}
if (hdr->id != ZONEID)
if (block->id != ZONEID)
{
I_Error("Z_CheckHeap %d: block %u"
"(owned by %s:%d)"
@ -567,9 +481,6 @@ void Z_CheckHeap(INT32 i)
block->ownerfile, block->ownerline
);
}
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
#endif
}
}
@ -591,35 +502,14 @@ void Z_ChangeTag(void *ptr, INT32 tag)
#endif
{
memblock_t *block;
memhdr_t *hdr;
if (ptr == NULL)
return;
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
block = MEMBLOCK(ptr);
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
#ifdef VALGRIND_MEMPOOL_EXISTS
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
{
#ifdef PARANOIA
I_Error("Z_CT at %s:%d: bad memblock", file, line);
#else
I_Error("Z_CT: bad memblock");
#endif
}
#endif
#ifdef PARANOIA
if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line);
#endif
block = hdr->block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line);
#endif
if (tag >= PU_PURGELEVEL && block->user == NULL)
@ -643,25 +533,14 @@ void Z_SetUser(void *ptr, void **newuser)
#endif
{
memblock_t *block;
memhdr_t *hdr;
if (ptr == NULL)
return;
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
block = MEMBLOCK(ptr);
#ifdef PARANOIA
if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line);
#endif
block = hdr->block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line);
#endif
if (block->tag >= PU_PURGELEVEL && newuser == NULL)

View file

@ -95,10 +95,10 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2);
// Alloc with no alignment
#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0)
#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0)
#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0)
// Alloc with standard alignment
#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, sizeof(void *))
#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, sizeof(void *))
#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, sizeof(void *))
// Free all memory by tag
// these don't give line numbers currently though