- plugged all memory leaks that were reported with Shadow Warrior when starting the first level.

This commit is contained in:
Christoph Oelckers 2019-12-25 11:26:19 +01:00
parent 5e821de481
commit b0cefdedce
21 changed files with 102 additions and 430 deletions

View File

@ -237,7 +237,6 @@ void scrUnInit(void)
{
memset(palookup, 0, sizeof(palookup));
memset(blendtable, 0, sizeof(blendtable));
engineUnInit();
}

View File

@ -81,6 +81,7 @@ extern int32_t curbrightness;
extern int32_t paletteLoadLookupTable(FileReader &fp);
extern void paletteSetupDefaultFog(void);
void paletteFreeLookups();
extern void palettePostLoadLookups(void);
extern void paletteFixTranslucencyMask(void);

View File

@ -310,6 +310,11 @@ int GameMain()
I_ShowFatalError(err.what());
r = -1;
}
M_ClearMenus(true);
if (gi)
{
gi->FreeGameData(); // Must be done before taking down any subsystems.
}
S_StopMusic(true);
if (soundEngine) delete soundEngine;
soundEngine = nullptr;
@ -325,9 +330,9 @@ int GameMain()
I_ShutdownGraphics();
M_DeinitMenus();
paletteFreeColorTables();
engineUnInit();
if (gi)
{
gi->FreeGameData();
delete gi;
gi = nullptr;
}

View File

@ -908,7 +908,7 @@ void M_Drawer (void)
//
//=============================================================================
void M_ClearMenus ()
void M_ClearMenus (bool final)
{
M_DemoNoPlay = false;
transition.previous = transition.current = nullptr;
@ -923,8 +923,11 @@ void M_ClearMenus ()
}
DMenu::CurrentMenu = nullptr;
menuactive = MENU_Off;
mouseGrabInput(true);
gi->MenuClosed();
if (!final)
{
mouseGrabInput(true);
gi->MenuClosed();
}
}
void Menu_Close(int playerid)

View File

@ -769,7 +769,7 @@ void M_PreviousMenu();
void M_Init (void);
void M_CreateMenus();
void M_ActivateMenu(DMenu *menu);
void M_ClearMenus ();
void M_ClearMenus (bool final = false);
void M_ParseMenuDefs();
void M_StartupSkillMenu(FGameStartup *gs);
int M_GetDefaultSkill();

View File

@ -94,6 +94,7 @@ void M_DeinitMenus()
}
MenuDescriptors.Clear();
OptionValues.Clear();
DMenu::CurrentMenu = NULL;
DefaultListMenuSettings.mItems.Clear();
}

View File

@ -6435,7 +6435,6 @@ void nix()
void GameInterface::FreeGameData()
{
engineUnInit();
G_Cleanup();
}

View File

@ -1173,7 +1173,7 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int
// Use this to break at a specific allocation number.
_crtBreakAlloc = 250894;
//_crtBreakAlloc = 251490;
#endif
int ret = DoMain (hInstance);

View File

@ -7884,7 +7884,6 @@ void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt)
void GameInterface::FreeGameData()
{
G_SetFog(0);
engineUnInit();
G_Cleanup();
}

View File

@ -58,335 +58,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
BEGIN_SW_NS
// DEFINES ///////////////////////////////////////////////////////////////////////////////////
#define MAX_USER_ARGS 100
#define MAX_CONSOLE_COMMANDS 100
#define MAX_HISTORY 20
SWBOOL SpriteInfo = FALSE;
extern SWBOOL QuitFlag;
extern SWBOOL MultiPlayQuitFlag;
// FUNCTION PROTOTYPES ///////////////////////////////////////////////////////////////////////
void CON_ProcessOptions(void);
void CON_ClearConsole(void);
uint8_t CON_CommandCmp(const char *str1, const char *str2, int len);
void CheatInput(void);
// Modify actor routines
void CON_Sound(void);
void CON_Reverb(void);
void CON_Heap(void);
void CON_Cache(void);
void CON_SoundTest(void);
void CON_SpriteInfo(void);
void CON_KillSprite(void);
void CON_SpriteDetail(void);
void CON_UserDetail(void);
void CON_Quit(void);
void CON_LoadSetup(void);
void CON_DamageData(void);
void CON_WinPachinko(void);
void CON_Bunny(void);
void CON_CheckHeap(void);
void CON_DumpHeap(void);
void CON_ShowMirror(void);
void CON_MultiNameChange(void);
// STRUCTURES ////////////////////////////////////////////////////////////////////////////////
typedef struct
{
const char *command; // Text string representing the command that calls this function
void (*function)(void); // Function assigned to the command, take no parameters
} CON_COMMAND, *CON_COMMANDp;
// Contains any commands that don't get added by particular setup functions
CON_COMMAND pre_commands[] =
{
#if DEBUG
{"bobbing", CON_ProcessOptions},
{"swnext", CheatInput},
{"swprev", CheatInput},
{"swsecret", CheatInput},
{"swstart", CheatInput},
{"swres", CheatInput},
{"swloc", CheatInput},
{"swroom", CheatInput},
{"swmap", CheatInput},
{"swvox", CheatInput},
{"swsave", CheatInput},
#endif
#if DEBUG
{"george", CheatInput},
{"blackburn", CheatInput},
{"reverb", CON_Reverb},
{"showmirror", CON_ShowMirror},
{"clear", CON_ClearConsole},
#endif
{"swgod", CheatInput},
{"swchan", CheatInput},
{"swgimme", CheatInput},
{"swtrek##", CheatInput},
{"swgreed", CheatInput},
{"swghost", CheatInput},
{"swstart", CheatInput},
{"swres", CheatInput},
{"swloc", CheatInput},
{"swmap", CheatInput},
{"swsave", CheatInput},
{"swmedic", CheatInput},
{"swkeys", CheatInput},
{"swredcard", CheatInput},
{"swbluecard", CheatInput},
{"swgreencard", CheatInput},
{"swyellowcard", CheatInput},
{"swgoldkey", CheatInput},
{"swsilverkey", CheatInput},
{"swbronzekey", CheatInput},
{"swredkey", CheatInput},
{"swgun#", CheatInput},
{"swquit", CheatInput},
{"swexit", CheatInput},
{"swtrix", CON_Bunny},
{NULL, NULL}
};
// GLOBALS ///////////////////////////////////////////////////////////////////////////////////
CON_COMMAND commandlist[MAX_CONSOLE_COMMANDS]; // Console command array
CON_COMMANDp commandptr; // Pointer to a command
int16_t numcommands=0; // Total number of commands in the command list
char command_history[MAX_HISTORY][256]; // History of what has been typed in lately
int16_t curr_history=0; // Line currently being pointed to in the history array
int16_t numhistory=0;
// Array which stores all the user arguments passed into the game.
static char user_args[MAX_USER_ARGS][256];
static uint8_t con_argnum=0; // Total number of arguments that were passed into the game
char con_message[80]; // Holds the current console message to send to adduserquote
// FUNCTIONS /////////////////////////////////////////////////////////////////////////////////
//
// Frank's neato input string checker, useful for my stuff too.
//
uint8_t CON_CommandCmp(const char *str1, const char *str2, int len)
{
const char *cp1 = str1;
const char *cp2 = str2;
do
{
if (*cp1 != *cp2)
{
if (*cp1 != '#' && *cp2 != '#')
return FALSE;
else if ((*cp1 == '#' && !isdigit(*cp2)) || (*cp2 == '#' && !isdigit(*cp1)))
return FALSE;
}
cp1++;
cp2++;
}
while (--len);
return TRUE;
}
SWBOOL IsCommand(const char *str)
{
int i;
char first[512];
sscanf(str,"%s",first);
for (i = 0; i < numcommands; i++)
{
// Don't even try if they aren't the same length
if (strlen(first) != strlen(commandlist[i].command))
continue;
// See if it's in there
if (CON_CommandCmp(first, commandlist[i].command, strlen(first)))
{
return TRUE;
}
}
return FALSE;
}
//
// Stores user arguments passed in on the command line for later inspection
//
void CON_StoreArg(const char *userarg)
{
if (con_argnum < MAX_USER_ARGS)
{
strcpy(&user_args[con_argnum][0],userarg);
Bstrlwr(&user_args[con_argnum][0]);
con_argnum++;
}
}
//
// Checkes the user command array to see if user did in fact pass in a particular argument
//
SWBOOL CON_CheckParm(const char *userarg)
{
int16_t i;
for (i=0; i<con_argnum; i++)
{
if (!strcmp(&user_args[i][0],userarg))
return TRUE; // Yep, it's in there
}
return FALSE; // Not a parameter that was passed in
}
//
// Scrolls up and down through previous user commands like DosKey
// Copies the history text string into the MessageInputCommand
//
void CON_CommandHistory(signed char dir)
{
if (curr_history + dir < numhistory)
curr_history += dir;
if (curr_history < 0) curr_history = 0;
if (curr_history > MAX_HISTORY) curr_history = MAX_HISTORY;
strcpy(MessageInputString, command_history[curr_history]);
}
void CON_AddHistory(const char *commandstr)
{
int i;
for (i=MAX_HISTORY-1; i>=0; i--)
{
strcpy(command_history[i],command_history[i-1]);
}
strcpy(command_history[0],commandstr);
if ((++numhistory) > MAX_HISTORY) numhistory = MAX_HISTORY;
}
//
// Adds a command name to the command list and assigns the appropriate function pointer
//
SWBOOL CON_AddCommand(const char *command, void (*function)(void))
{
if (command != NULL && function != NULL && numcommands < MAX_CONSOLE_COMMANDS)
{
// strcpy(commandlist[numcommands].command, command);
commandlist[numcommands].command = command;
commandlist[numcommands].function = function;
// Increment counter to set up for next command insertion
numcommands++;
ASSERT(numcommands <= MAX_CONSOLE_COMMANDS);
return TRUE;
}
return FALSE;
}
//
// Process commands
// Returns TRUE upon success
//
void CON_ProcessUserCommand(void)
{
int16_t i=0;
char temp_message[256],command_str[256];
strcpy(temp_message,MessageInputString);
sscanf(Bstrlwr(temp_message),"%s", command_str); // Get the base command type
for (i = 0; i < numcommands; i++)
{
// Don't even try if they aren't the same length
if (strlen(command_str) != strlen(commandlist[i].command)) continue;
// See if it's in there
if (CON_CommandCmp(command_str, commandlist[i].command, strlen(command_str)))
{
if (commandlist[i].function)
{
(*commandlist[i].function)();
CON_AddHistory(MessageInputString); // Keep history only of valid input
return;
}
}
}
if (ConPanel)
OSD_Printf("Syntax Error or Command not enabled!");
}
//
// Initialize the console command list with the pre_command startup array
//
void CON_InitConsole(void)
{
CON_COMMANDp i;
for (i = &pre_commands[0]; i->command != NULL; i++)
{
if (!CON_AddCommand(i->command, i->function))
{
printf("CON_InitConsole: Failed to add command contained in pre_commands list.\n");
TerminateGame();
exit(0);
}
}
//printf("CON_InitConsole: Command list initialized.\n");
}
//
// Process as a command, anything that could be set in the options menu as well
//
void CON_ProcessOptions(void)
{
}
// Clear the console screen
void CON_ClearConsole(void)
{
short i;
for (i=0; i<MAXCONQUOTES; i++)
strcpy(con_quote[i],"\0");
}
void CON_Reverb(void)
{
char base[80];
int16_t op1=0;
PLAYERp pp = Player + screenpeek;
// Format: reverb [number]
if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
{
strcpy(MessageInputString,"help reverb");
return;
}
OSD_Printf("Reverb is now set to %d.",op1);
COVER_SetReverb(op1);
pp->Reverb = op1;
}
void CON_Bunny(void)
{
PLAYERp pp = Player + myconnectindex;

View File

@ -228,9 +228,7 @@ DemoReadHeader(void)
if (DF_ERR(DemoFileIn))
{
TerminateGame();
printf("File %s is not a valid demo file.",DemoFileName);
exit(0);
I_Error("File %s is not a valid demo file.",DemoFileName);
}
DREAD(&dh, sizeof(dh), 1, DemoFileIn);
@ -542,7 +540,6 @@ DemoPlayBack(void)
{
TerminateLevel();
TerminateGame();
exit(0);
}
}

View File

@ -1464,7 +1464,7 @@ void PrintSpriteInfo(PLAYERp pp)
Printf("COUNTER:%d, ", u->Counter);
Printf("COUNTER2:%d\n", u->Counter);
}
if (SpriteInfo > 1)
if (sp)
{
Printf("POSX:%d, ", TrackerCast(sp->x));
Printf("POSY:%d, ", TrackerCast(sp->y));

View File

@ -424,9 +424,7 @@ AllocMem(int size)
// Used for debugging, we can remove this at ship time
if (bp == NULL)
{
TerminateGame();
printf("Memory could NOT be allocated in AllocMem: size = %d\n",size);
exit(0);
I_FatalError("Memory could NOT be allocated in AllocMem: size = %d\n",size);
}
ASSERT(bp != NULL);
@ -489,9 +487,7 @@ CallocMem(int size, int num)
// Used for debugging, we can remove this at ship time
if (bp == NULL)
{
TerminateGame();
printf("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
exit(0);
I_FatalError("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
}
ASSERT(bp != NULL);
@ -532,6 +528,7 @@ ValidPtr(void *ptr)
return TRUE;
}
#if 0
void *
AllocMem(int size)
{
@ -555,6 +552,7 @@ FreeMem(void *ptr)
{
free(ptr);
}
#endif
#endif
@ -632,18 +630,13 @@ void TerminateGame(void)
SybexScreen();
//TenScreen();
}
engineUnInit();
timerUninit();
Bexit(0);
throw ExitEvent(3);
}
bool LoadLevel(const char *filename)
{
if (engineLoadBoard(filename, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &Player[0].pang, &Player[0].cursectnum) == -1)
{
TerminateGame();
Printf("Level not found: %s", filename);
return false;
}
@ -787,12 +780,6 @@ bool InitGame()
timerInit(120);
CON_InitConsole(); // Init console command list
////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__); MONO_PRINT(ds);
//InitFX();
memcpy(palette_data,palette,768);
InitPalette();
// sets numplayers, connecthead, connectpoint2, myconnectindex
@ -2483,7 +2470,7 @@ void Control()
}
CleanExit = TRUE;
TerminateGame();
throw ExitEvent(0);
}
@ -3986,6 +3973,13 @@ GameStats GameInterface::getStats()
return { pp->Kills, TotalKillable, pp->SecretsFound, LevelSecrets, PlayClock / 120, 0 };
}
void GameInterface::FreeGameData()
{
TerminateLevel();
}
#if 0 // the message input needs to be moved out of the game code!
void GetMessageInput(PLAYERp pp)
{
@ -4045,12 +4039,6 @@ void GetMessageInput(PLAYERp pp)
{
if (memcmp(MessageInputString, TEAM_MENU, sizeof(TEAM_MENU)) != 0)
{
// see if its a command
if (IsCommand(MessageInputString))
{
TeamSendAll = TRUE;
}
else
{
strcpy(HoldMessageInputString, MessageInputString);
strcpy(MessageInputString, TEAM_MENU);
@ -4072,7 +4060,6 @@ void GetMessageInput(PLAYERp pp)
inputState.ClearKeysDown();
inputState.keyFlushChars();
buttonMap.ClearButton(gamefunc_Inventory);
CON_ProcessUserCommand(); // Check to see if it's a cheat or command
for (i = 0; i < NUMGAMEFUNCTIONS; i++)
buttonMap.ClearButton(i);

View File

@ -858,7 +858,6 @@ SWBOOL CON_CheckParm(const char *userarg);
void CON_CommandHistory(signed char dir);
SWBOOL CON_AddCommand(const char *command, void (*function)(void));
void CON_ProcessUserCommand(void);
void CON_InitConsole(void);
///////////////////////////////////////////////////////////////////////////////////////////
//
@ -1756,10 +1755,18 @@ typedef struct
} MEM_HDR,*MEM_HDRp;
SWBOOL ValidPtr(void *ptr);
#if 0
void *AllocMem(int size);
void *CallocMem(int size, int num);
void *ReAllocMem(void *ptr, int size);
void FreeMem(void *ptr);
#else
// Make these #defines so that MSVC's allocation tracker gets correct line numbers
#define AllocMem malloc
#define CallocMem calloc
#define ReAllocMem realloc
#define FreeMem free
#endif
typedef struct
{
@ -2423,6 +2430,7 @@ void LoadSaveMsg(const char *msg);
struct GameInterface : ::GameInterface
{
int app_main() override;
void FreeGameData() override;
bool validate_hud(int) override;
void set_hud_layout(int size) override;
void set_hud_scale(int size) override;

View File

@ -387,9 +387,8 @@ void JS_InitMirrors(void)
if (!Found_Cam)
{
printf("Cound not find the camera view sprite for match %d\n",TrackerCast(wall[i].hitag));
printf("Map Coordinates: x = %d, y = %d\n",TrackerCast(wall[i].x),TrackerCast(wall[i].y));
exit(0);
Printf("Cound not find the camera view sprite for match %d\n",TrackerCast(wall[i].hitag));
Printf("Map Coordinates: x = %d, y = %d\n",TrackerCast(wall[i].x),TrackerCast(wall[i].y));
}
Found_Cam = FALSE;
@ -413,10 +412,9 @@ void JS_InitMirrors(void)
if (!Found_Cam)
{
printf("Did not find drawtotile for camera number %d\n",mirrorcnt);
printf("wall[%d].hitag == %d\n",i,TrackerCast(wall[i].hitag));
printf("Map Coordinates: x = %d, y = %d\n", TrackerCast(wall[i].x), TrackerCast(wall[i].y));
exit(0);
Printf("Did not find drawtotile for camera number %d\n",mirrorcnt);
Printf("wall[%d].hitag == %d\n",i,TrackerCast(wall[i].hitag));
Printf("Map Coordinates: x = %d, y = %d\n", TrackerCast(wall[i].x), TrackerCast(wall[i].y));
}
}
@ -692,10 +690,8 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
if (mirror[cnt].campic == -1)
{
TerminateGame();
printf("Missing campic for mirror %d\n",cnt);
printf("Map Coordinates: x = %d, y = %d\n",midx,midy);
exit(0);
Printf("Missing campic for mirror %d. Map Coordinates: x = %d, y = %d\n", cnt,midx,midy);
return;
}
// BOOL2 = Oscilate camera
@ -1086,22 +1082,33 @@ JS_UnInitLockouts(void)
{
OrgTileP tp=NULL, next_tp=NULL;
TRAVERSE(&orgwalllist, tp, next_tp)
if (orgwalllist.Next)
{
KillOrgTile(tp);
TRAVERSE(&orgwalllist, tp, next_tp)
{
KillOrgTile(tp);
}
}
TRAVERSE(&orgwalloverlist, tp, next_tp)
if (orgwalloverlist.Next)
{
KillOrgTile(tp);
TRAVERSE(&orgwalloverlist, tp, next_tp)
{
KillOrgTile(tp);
}
}
TRAVERSE(&orgsectorceilinglist, tp, next_tp)
if (orgsectorceilinglist.Next)
{
KillOrgTile(tp);
TRAVERSE(&orgsectorceilinglist, tp, next_tp)
{
KillOrgTile(tp);
}
}
TRAVERSE(&orgsectorfloorlist, tp, next_tp)
if (orgsectorfloorlist.Next)
{
KillOrgTile(tp);
TRAVERSE(&orgsectorfloorlist, tp, next_tp)
{
KillOrgTile(tp);
}
}
}
@ -1120,24 +1127,22 @@ JS_UnInitLockouts(void)
void
JS_PlockError(short wall_num, short t)
{
TerminateGame();
printf("ERROR: JS_InitLockouts(), out of range tile number\n");
Printf("ERROR: JS_InitLockouts(), out of range tile number\n");
switch (t)
{
case 1:
printf("wall %d, x %d, y %d, pic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].picnum));
Printf("wall %d, x %d, y %d, pic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].picnum));
break;
case 2:
printf("wall %d, x %d, y %d, OVERpic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].overpicnum));
Printf("wall %d, x %d, y %d, OVERpic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].overpicnum));
break;
case 3:
printf("sector %d, ceiling %d\n", wall_num, TrackerCast(sector[wall_num].ceilingpicnum));
Printf("sector %d, ceiling %d\n", wall_num, TrackerCast(sector[wall_num].ceilingpicnum));
break;
case 4:
printf("sector %d, floor %d\n", wall_num, TrackerCast(sector[wall_num].floorpicnum));
Printf("sector %d, floor %d\n", wall_num, TrackerCast(sector[wall_num].floorpicnum));
break;
}
exit(0);
}
void
@ -1163,7 +1168,10 @@ JS_InitLockouts(void)
picnum = wall[i].picnum;
if (aVoxelArray[picnum].Parental >= INVISTILE)
JS_PlockError(i,1);
{
JS_PlockError(i, 1);
continue;
}
if (aVoxelArray[picnum].Parental >= 0)
{
@ -1175,7 +1183,10 @@ JS_InitLockouts(void)
picnum = wall[i].overpicnum;
if (aVoxelArray[picnum].Parental >= INVISTILE)
JS_PlockError(i,2);
{
JS_PlockError(i, 2);
continue;
}
if (aVoxelArray[picnum].Parental >= 0)
{
@ -1192,7 +1203,10 @@ JS_InitLockouts(void)
picnum = sector[i].ceilingpicnum;
if (aVoxelArray[picnum].Parental >= INVISTILE)
JS_PlockError(i,3);
{
JS_PlockError(i, 3);
continue;
}
if (aVoxelArray[picnum].Parental >= 0)
{
@ -1204,7 +1218,10 @@ JS_InitLockouts(void)
picnum = sector[i].floorpicnum;
if (aVoxelArray[picnum].Parental >= INVISTILE)
JS_PlockError(i,2);
{
JS_PlockError(i, 2);
continue;
}
if (aVoxelArray[picnum].Parental >= 0)
{

View File

@ -648,7 +648,6 @@ waitforeverybody(void)
}
TerminateGame();
exit(0);
}
}

View File

@ -4578,9 +4578,7 @@ PlayerOnLadder(PLAYERp pp)
#if DEBUG
if (wall[wal].nextsector < 0)
{
TerminateGame();
printf("Take out white wall ladder x = %d, y = %d",wall[wal].x, wall[wal].y);
exit(0);
I_Error("Take out white wall ladder x = %d, y = %d",wall[wal].x, wall[wal].y);
}
#endif
@ -4733,9 +4731,7 @@ GetOverlapSector(int x, int y, short *over, short *under)
if (!found)
{
TerminateGame();
printf("GetOverlapSector x = %d, y = %d, over %d, under %d", x, y, *over, *under);
exit(0);
I_Error("GetOverlapSector x = %d, y = %d, over %d, under %d", x, y, *over, *under);
}
PRODUCTION_ASSERT(found != 0);
@ -4823,9 +4819,7 @@ GetOverlapSector2(int x, int y, short *over, short *under)
if (!found)
{
TerminateGame();
printf("GetOverlapSector x = %d, y = %d, over %d, under %d", x, y, *over, *under);
exit(0);
I_Error("GetOverlapSector x = %d, y = %d, over %d, under %d", x, y, *over, *under);
}
PRODUCTION_ASSERT(found != 0);
@ -8252,7 +8246,6 @@ PlayerSpawnPosition(PLAYERp pp)
spawn_sprite = headspritestat[STAT_MULTI_START + 0];
//TerminateGame();
//printf("Map does not contain a spawn position for Player %d.", pp - Player);
//exit(0);
}
ASSERT(spawn_sprite >= 0);

View File

@ -710,6 +710,7 @@ void COVER_SetReverb(int amt)
void DeleteNoSoundOwner(short spritenum)
{
if (!soundEngine) return;
SPRITEp sp = &sprite[spritenum];
soundEngine->EnumerateChannels([=](FSoundChan* chan)
@ -945,7 +946,8 @@ SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_tra
void StopSound(void)
{
soundEngine->StopAllChannels();
// This gets also called on shutdown.
if (soundEngine) soundEngine->StopAllChannels();
Mus_Stop();
}

View File

@ -2896,9 +2896,7 @@ SpriteSetup(void)
{
if (sprite[i].hitag == sp->hitag && sprite[i].lotag == sp->lotag)
{
TerminateGame();
printf("Two VIEW_THRU_ tags with same match found on level\n1: x %d, y %d \n2: x %d, y %d", TrackerCast(sp->x), TrackerCast(sp->y), TrackerCast(sprite[i].x), TrackerCast(sprite[i].y));
exit(0);
I_Error("Two VIEW_THRU_ tags with same match found on level\n1: x %d, y %d \n2: x %d, y %d", TrackerCast(sp->x), TrackerCast(sp->y), TrackerCast(sprite[i].x), TrackerCast(sprite[i].y));
}
}
change_sprite_stat(SpriteNum, STAT_FAF);
@ -4964,11 +4962,10 @@ ActorDrop(short SpriteNum, int x, int y, int z, short new_sector, short min_heig
#if 0
if (florhit < 0 || ceilhit < 0)
{
Printf("ERROR: FAFgetzrange() returned -1 for floor or ceiling check.\n");
Printf("Most likely a sprite has been placed too close to a white wall.\n");
Printf("spnum %d, sect %d, x %d, y %d, z %d, florhit %d, pic %d\n", SpriteNum, sp->sectnum, sp->x, sp->y, z - DIV2(SPRITEp_SIZE_Z(sp)), florhit, sp->picnum);
TerminateGame();
printf("ERROR: FAFgetzrange() returned -1 for floor or ceiling check.\n");
printf("Most likely a sprite has been placed too close to a white wall.\n");
printf("spnum %d, sect %d, x %d, y %d, z %d, florhit %d, pic %d\n", SpriteNum, sp->sectnum, sp->x, sp->y, z - DIV2(SPRITEp_SIZE_Z(sp)), florhit, sp->picnum);
exit(0);
}
#else
if (florhit < 0 || ceilhit < 0)

View File

@ -526,9 +526,7 @@ demosync_test(int cnt)
if (sync_val != (*SyncFunc[i])())
{
TerminateLevel();
TerminateGame();
printf("Demo out of sync - Sync Byte Number %d - Iteration %d.", i, cnt);
exit(0);
I_Error("Demo out of sync - Sync Byte Number %d - Iteration %d.", i, cnt);
}
}
}

View File

@ -880,9 +880,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop)
if (!FoundOutsideLoop)
{
TerminateGame();
printf("Forgot to tag outer loop for Sector Object #%d", (int)(sop - SectorObject));
exit(1);
I_Error("Forgot to tag outer loop for Sector Object #%d", (int)(sop - SectorObject));
}
for (i = 0; i < (int)SIZ(StatList); i++)
@ -3660,9 +3658,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum)
#if DEBUG
if (wall[hit_wall].nextsector < 0)
{
TerminateGame();
printf("Take out white wall ladder x = %d, y = %d",wall[hit_wall].x, wall[hit_wall].y);
exit(0);
I_Error("Take out white wall ladder x = %d, y = %d",wall[hit_wall].x, wall[hit_wall].y);
}
#endif