mirror of
https://github.com/DrBeef/DVR.git
synced 2024-12-23 19:00:51 +00:00
420 lines
10 KiB
C
420 lines
10 KiB
C
/* Emacs style mode select -*- C++ -*-
|
|
*-----------------------------------------------------------------------------
|
|
*
|
|
*
|
|
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
|
|
* based on BOOM, a modified and improved DOOM engine
|
|
* Copyright (C) 1999 by
|
|
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
|
* Copyright (C) 1999-2000 by
|
|
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
|
* Copyright 2005, 2006 by
|
|
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*
|
|
* DESCRIPTION:
|
|
* Startup and quit functions. Handles signals, inits the
|
|
* memory management, then calls D_DoomMain. Also contains
|
|
* I_Init which does other system-related startup stuff.
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef USE_SDL
|
|
#include "SDL.h"
|
|
#endif
|
|
#include "doomdef.h"
|
|
#include "m_argv.h"
|
|
#include "d_main.h"
|
|
#include "m_fixed.h"
|
|
#include "i_system.h"
|
|
#include "i_video.h"
|
|
#include "z_zone.h"
|
|
#include "lprintf.h"
|
|
#include "m_random.h"
|
|
#include "doomstat.h"
|
|
#include "g_game.h"
|
|
#include "m_misc.h"
|
|
#include "i_sound.h"
|
|
#include "i_main.h"
|
|
#include "r_fps.h"
|
|
#include "lprintf.h"
|
|
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Most of the following has been rewritten by Lee Killough
|
|
*
|
|
* I_GetTime
|
|
* killough 4/13/98: Make clock rate adjustable by scale factor
|
|
* cphipps - much made static
|
|
*/
|
|
|
|
int realtic_clock_rate = 100;
|
|
static int_64_t I_GetTime_Scale = 1<<24;
|
|
|
|
static int I_GetTime_Scaled(void)
|
|
{
|
|
return (int)( (int_64_t) I_GetTime_RealTime() * I_GetTime_Scale >> 24);
|
|
}
|
|
|
|
|
|
|
|
static int I_GetTime_FastDemo(void)
|
|
{
|
|
static int fasttic;
|
|
return fasttic++;
|
|
}
|
|
|
|
|
|
|
|
static int I_GetTime_Error(void)
|
|
{
|
|
I_Error("I_GetTime_Error: GetTime() used before initialization");
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//int (*I_GetTime)(void) = I_GetTime_Error;
|
|
|
|
void I_Init(void)
|
|
{
|
|
|
|
/* killough 4/14/98: Adjustable speedup based on realtic_clock_rate */
|
|
/*
|
|
if (fastdemo) {
|
|
printf("I_Init: Using fast demo: I_GetTime_FastDemo\n");
|
|
I_GetTime = I_GetTime_FastDemo;
|
|
}
|
|
else {
|
|
if (realtic_clock_rate != 100)
|
|
{
|
|
printf("I_Init: Using fast demo: I_GetTime_Scaled\n");
|
|
I_GetTime_Scale = ((int_64_t) realtic_clock_rate << 24) / 100;
|
|
I_GetTime = I_GetTime_Scaled;
|
|
}
|
|
else {
|
|
printf("I_Init: Using fast demo: I_GetTime_RealTime\n");
|
|
I_GetTime = I_GetTime_RealTime;
|
|
}
|
|
}
|
|
*/
|
|
{
|
|
/* killough 2/21/98: avoid sound initialization if no sound & no music */
|
|
if (!(nomusicparm && nosfxparm))
|
|
I_InitSound();
|
|
}
|
|
|
|
R_InitInterpolation();
|
|
}
|
|
|
|
/* cleanup handling -- killough:
|
|
*/
|
|
static void I_SignalHandler(int s)
|
|
{
|
|
char buf[2048];
|
|
|
|
// signal(s,SIG_IGN); /* Ignore future instances of this signal.*/
|
|
|
|
strcpy(buf,"Exiting on signal: ");
|
|
I_SigString(buf+strlen(buf),2000-strlen(buf),s);
|
|
|
|
/* If corrupted memory could cause crash, dump memory
|
|
* allocation history, which points out probable causes
|
|
*/
|
|
if (s==SIGSEGV || s==SIGILL || s==SIGFPE)
|
|
Z_DumpHistory(buf);
|
|
|
|
I_Error("I_SignalHandler: %s", buf);
|
|
}
|
|
|
|
|
|
|
|
/* killough 2/22/98: Add support for ENDBOOM, which is PC-specific
|
|
*
|
|
* this converts BIOS color codes to ANSI codes.
|
|
* Its not pretty, but it does the job - rain
|
|
* CPhipps - made static
|
|
*/
|
|
|
|
inline static int convert(int color, int *bold)
|
|
{
|
|
if (color > 7) {
|
|
color -= 8;
|
|
*bold = 1;
|
|
}
|
|
switch (color) {
|
|
case 0:
|
|
return 0;
|
|
case 1:
|
|
return 4;
|
|
case 2:
|
|
return 2;
|
|
case 3:
|
|
return 6;
|
|
case 4:
|
|
return 1;
|
|
case 5:
|
|
return 5;
|
|
case 6:
|
|
return 3;
|
|
case 7:
|
|
return 7;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* CPhipps - flags controlling ENDOOM behaviour */
|
|
enum {
|
|
endoom_colours = 1,
|
|
endoom_nonasciichars = 2,
|
|
endoom_droplastline = 4
|
|
};
|
|
|
|
unsigned int endoom_mode;
|
|
|
|
static void PrintVer(void)
|
|
{
|
|
char vbuf[200];
|
|
lprintf(LO_INFO,"%s\n",I_GetVersionString(vbuf,200));
|
|
}
|
|
|
|
/* I_EndDoom
|
|
* Prints out ENDOOM or ENDBOOM, using some common sense to decide which.
|
|
* cphipps - moved to l_main.c, made static
|
|
*/
|
|
static void I_EndDoom(void)
|
|
{
|
|
int lump_eb, lump_ed, lump = -1;
|
|
|
|
/* CPhipps - ENDOOM/ENDBOOM selection */
|
|
lump_eb = W_CheckNumForName("ENDBOOM");/* jff 4/1/98 sign our work */
|
|
lump_ed = W_CheckNumForName("ENDOOM"); /* CPhipps - also maybe ENDOOM */
|
|
|
|
if (lump_eb == -1)
|
|
lump = lump_ed;
|
|
else if (lump_ed == -1)
|
|
lump = lump_eb;
|
|
else
|
|
{ /* Both ENDOOM and ENDBOOM are present */
|
|
#define LUMP_IS_NEW(num) (!((lumpinfo[num].source == source_iwad) || (lumpinfo[num].source == source_auto_load)))
|
|
switch ((LUMP_IS_NEW(lump_ed) ? 1 : 0 ) |
|
|
(LUMP_IS_NEW(lump_eb) ? 2 : 0)) {
|
|
case 1:
|
|
lump = lump_ed;
|
|
break;
|
|
case 2:
|
|
lump = lump_eb;
|
|
break;
|
|
default:
|
|
/* Both lumps have equal priority, both present */
|
|
lump = (P_Random(pr_misc) & 1) ? lump_ed : lump_eb;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (lump != -1)
|
|
{
|
|
const char (*endoom)[2] = (const void*)W_CacheLumpNum(lump);
|
|
int i, l = W_LumpLength(lump) / 2;
|
|
|
|
/* cph - colour ENDOOM by rain */
|
|
int oldbg = -1, oldcolor = -1, bold = 0, oldbold = -1, color = 0;
|
|
#ifndef _WIN32
|
|
if (endoom_mode & endoom_nonasciichars)
|
|
/* switch to secondary charset, and set to cp437 (IBM charset) */
|
|
printf("\e)K\016");
|
|
#endif /* _WIN32 */
|
|
|
|
/* cph - optionally drop the last line, so everything fits on one screen */
|
|
if (endoom_mode & endoom_droplastline)
|
|
l -= 80;
|
|
lprintf(LO_INFO,"\n");
|
|
for (i=0; i<l; i++)
|
|
{
|
|
#ifdef _WIN32
|
|
I_ConTextAttr(endoom[i][1]);
|
|
#elif defined (DJGPP)
|
|
textattr(endoom[i][1]);
|
|
#else
|
|
if (endoom_mode & endoom_colours)
|
|
{
|
|
if (!(i % 80))
|
|
{
|
|
/* reset color but not bold when we start a new line */
|
|
oldbg = -1;
|
|
oldcolor = -1;
|
|
printf("\e[39m\e[49m\n");
|
|
}
|
|
/* foreground color */
|
|
bold = 0;
|
|
color = endoom[i][1] % 16;
|
|
if (color != oldcolor)
|
|
{
|
|
oldcolor = color;
|
|
color = convert(color, &bold);
|
|
if (oldbold != bold)
|
|
{
|
|
oldbold = bold;
|
|
printf("\e[%cm", bold + '0');
|
|
if (!bold) oldbg = -1;
|
|
}
|
|
/* we buffer everything or output is horrendously slow */
|
|
printf("\e[%dm", color + 30);
|
|
bold = 0;
|
|
}
|
|
/* background color */
|
|
color = endoom[i][1] / 16;
|
|
if (color != oldbg)
|
|
{
|
|
oldbg = color;
|
|
color = convert(color, &bold);
|
|
printf("\e[%dm", color + 40);
|
|
}
|
|
}
|
|
#endif
|
|
/* cph - portable ascii printout if requested */
|
|
if (isascii(endoom[i][0]) || (endoom_mode & endoom_nonasciichars))
|
|
lprintf(LO_INFO,"%c",endoom[i][0]);
|
|
else /* Probably a box character, so do #'s */
|
|
lprintf(LO_INFO,"#");
|
|
}
|
|
#ifndef _WIN32
|
|
lprintf(LO_INFO,"\b"); /* hack workaround for extra newline at bottom of screen */
|
|
lprintf(LO_INFO,"\r");
|
|
if (endoom_mode & endoom_nonasciichars)
|
|
printf("%c",'\017'); /* restore primary charset */
|
|
#endif /* _WIN32 */
|
|
W_UnlockLumpNum(lump);
|
|
}
|
|
#ifndef _WIN32
|
|
if (endoom_mode & endoom_colours)
|
|
puts("\e[0m"); /* cph - reset colours */
|
|
PrintVer();
|
|
#endif /* _WIN32 */
|
|
}
|
|
|
|
static int has_exited;
|
|
|
|
/* I_SafeExit
|
|
* This function is called instead of exit() by functions that might be called
|
|
* during the exit process (i.e. after exit() has already been called)
|
|
* Prevent infinitely recursive exits -- killough
|
|
*/
|
|
|
|
void I_SafeExit(int rc)
|
|
{
|
|
if (!has_exited) /* If it hasn't exited yet, exit now -- killough */
|
|
{
|
|
has_exited=rc ? 2 : 1;
|
|
exit(rc);
|
|
}
|
|
}
|
|
|
|
static void I_Quit (void)
|
|
{
|
|
if (!has_exited)
|
|
has_exited=1; /* Prevent infinitely recursive exits -- killough */
|
|
|
|
if (has_exited == 1) {
|
|
I_EndDoom();
|
|
if (demorecording)
|
|
G_CheckDemoStatus();
|
|
M_SaveDefaults ();
|
|
}
|
|
}
|
|
|
|
#ifdef SECURE_UID
|
|
uid_t stored_euid = -1;
|
|
#endif
|
|
|
|
//int main(int argc, const char * const * argv)
|
|
int doom_main(int argc, char **argv, char *wadDir)
|
|
{
|
|
#ifdef SECURE_UID
|
|
/* First thing, revoke setuid status (if any) */
|
|
stored_euid = geteuid();
|
|
if (getuid() != stored_euid)
|
|
if (seteuid(getuid()) < 0)
|
|
fprintf(stderr, "Failed to revoke setuid\n");
|
|
else
|
|
fprintf(stderr, "Revoked uid %d\n",stored_euid);
|
|
#endif
|
|
|
|
myargc = argc;
|
|
myargv = argv;
|
|
|
|
#ifdef _WIN32
|
|
if (!M_CheckParm("-nodraw")) {
|
|
/* initialize the console window */
|
|
Init_ConsoleWin();
|
|
atexit(Done_ConsoleWin);
|
|
}
|
|
#endif
|
|
/* Version info */
|
|
lprintf(LO_INFO,"\n");
|
|
PrintVer();
|
|
|
|
/* cph - Z_Close must be done after I_Quit, so we register it first. */
|
|
atexit(Z_Close);
|
|
/*
|
|
killough 1/98:
|
|
|
|
This fixes some problems with exit handling
|
|
during abnormal situations.
|
|
|
|
The old code called I_Quit() to end program,
|
|
while now I_Quit() is installed as an exit
|
|
handler and exit() is called to exit, either
|
|
normally or abnormally. Seg faults are caught
|
|
and the error handler is used, to prevent
|
|
being left in graphics mode or having very
|
|
loud SFX noise because the sound card is
|
|
left in an unstable state.
|
|
*/
|
|
|
|
Z_Init(); /* 1/18/98 killough: start up memory stuff first */
|
|
|
|
atexit(I_Quit);
|
|
#ifndef _DEBUG
|
|
/*
|
|
signal(SIGSEGV, I_SignalHandler);
|
|
signal(SIGTERM, I_SignalHandler);
|
|
signal(SIGFPE, I_SignalHandler);
|
|
signal(SIGILL, I_SignalHandler);
|
|
signal(SIGINT, I_SignalHandler);
|
|
signal(SIGABRT, I_SignalHandler);
|
|
*/
|
|
#endif
|
|
|
|
I_SetAffinityMask();
|
|
|
|
/* cphipps - call to video specific startup code */
|
|
I_PreInitGraphics();
|
|
|
|
D_DoomMainSetup(wadDir);
|
|
|
|
return 0;
|
|
}
|