예제 #1
0
//
// D_DoomMain
//
void D_DoomMain (void)
{
	unsigned p;
	extern std::string defdemoname;

	gamestate = GS_STARTUP;
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command

	Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);

	M_LoadDefaults ();					// load before initing other systems
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	const char* iwad = Args.CheckValue("-iwad");
	if (!iwad)
		iwad = "";

	std::vector<std::string> newwadfiles, newpatchfiles;
	newwadfiles.push_back(iwad);
	D_AddWadCommandLineFiles(newwadfiles);
	D_AddDehCommandLineFiles(newpatchfiles);

	D_LoadResourceFiles(newwadfiles, newpatchfiles);

	I_Init();

	V_Init();
	atterm(V_Close);

	#ifdef _WIN32
	const char *sdlv = getenv("SDL_VIDEODRIVER");
	Printf (PRINT_HIGH, "Using %s video driver.\n",sdlv);
	#endif

	C_InitConsole(screen->width, screen->height, true);
	atterm(C_ShutdownConsole);

	// SDL needs video mode set up first before input code can be used
	I_InitInput();

	D_Init();
	atterm(D_Shutdown);

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (GStrings(STARTUP1)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP1));
	if (GStrings(STARTUP2)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP2));
	if (GStrings(STARTUP3)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP3));
	if (GStrings(STARTUP4)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP4));
	if (GStrings(STARTUP5)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP5));

	// Nomonsters
	sv_nomonsters = Args.CheckParm("-nomonsters");

	// Respawn
	sv_monstersrespawn = Args.CheckParm("-respawn");

	// Fast
	sv_fastmonsters = Args.CheckParm("-fast");

    // developer mode
	devparm = Args.CheckParm ("-devparm");

	// Record a vanilla demo
	p = Args.CheckParm ("-record");
	if (p)
	{
		autorecord = true;
		autostart = true;
		demorecordfile = Args.GetArg (p+1);
	}

	// get skill / episode / map from parms
	strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

	// Check for -playdemo, play a single demo then quit.
	p = Args.CheckParm ("-playdemo");
	// Hack to check for +playdemo command, since if you just add it normally
	// it won't run because it's attempting to run a demo and still set up the
	// first map as normal.
	if (!p)
		p = Args.CheckParm ("+playdemo");
	if (p && p < Args.NumArgs()-1)
	{
		Printf (PRINT_HIGH, "Playdemo parameter found on command line.\n");
		singledemo = true;
		defdemoname = Args.GetArg (p+1);
	}

	// [SL] check for -timedemo (was removed at some point)
	p = Args.CheckParm("-timedemo");
	if (p && p < Args.NumArgs() - 1)
	{
		singledemo = true;
		G_TimeDemo(Args.GetArg(p + 1));
	}

	const char *val = Args.CheckValue ("-skill");
	if (val)
	{
		sv_skill.Set (val[0]-'0');
	}

	p = Args.CheckParm ("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi (Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy (startmap, CalcMapName (ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm ("+map");
	if (p && p < Args.NumArgs()-1)
	{
		strncpy (startmap, Args.GetArg (p+1), 8);
		((char *)Args.GetArg (p))[0] = '-';
		autostart = true;
	}
	if (devparm)
		Printf (PRINT_HIGH, "%s", GStrings(D_DEVSTR));        // D_DEVSTR

	// [RH] Now that all text strings are set up,
	// insert them into the level and cluster data.
	G_SetLevelStrings();

	// [RH] Parse through all loaded mapinfo lumps
	G_ParseMapInfo();

	// [ML] Parse musinfo lump
	G_ParseMusInfo();

	// [RH] Parse any SNDINFO lumps
	S_ParseSndInfo();

	// NOTE(jsd): Set up local player color
	EXTERN_CVAR(cl_color);
	R_BuildPlayerTranslation (0, V_GetColorFromString (NULL, cl_color.cstring()));

	I_FinishClockCalibration ();

	Printf (PRINT_HIGH, "D_CheckNetGame: Checking network game status.\n");
	D_CheckNetGame ();

	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems ();

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet ();

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams (false, false);

	Printf_Bold("\n\35\36\36\36\36 Odamex Client Initialized \36\36\36\36\37\n");
	if(gamestate != GS_CONNECTING)
		Printf(PRINT_HIGH, "Type connect <address> or use the Odamex Launcher to connect to a game.\n");
    Printf(PRINT_HIGH, "\n");

	setmodeneeded = false; // [Fly] we don't need to set a video mode here!
    //gamestate = GS_FULLCONSOLE;

	// [SL] allow the user to pass the name of a netdemo as the first argument.
	// This allows easy launching of netdemos from Windows Explorer or other GUIs.

	// [Xyltol]
	if (Args.GetArg(1))
	{
		std::string demoarg = Args.GetArg(1);
		if (demoarg.find(".odd") != std::string::npos)
			CL_NetDemoPlay(demoarg);
	}

	p = Args.CheckParm("-netplay");
	if (p)
	{
		if (Args.GetArg(p + 1))
		{
			std::string filename = Args.GetArg(p + 1);
			CL_NetDemoPlay(filename);
		}
		else
		{
			Printf(PRINT_HIGH, "No netdemo filename specified.\n");
		}
	}

	// denis - bring back the demos
    if ( gameaction != ga_loadgame )
    {
		if (autostart || netgame || singledemo)
		{
			if (singledemo)
				G_DoPlayDemo();
			else
			{
				if(autostart)
				{
					// single player warp (like in g_level)
					serverside = true;
                    sv_allowexit = "1";
                    sv_freelook = "1";
                    sv_allowjump = "1";
                    sv_allowredscreen = "1";
                    sv_gametype = GM_COOP;

					players.clear();
					players.push_back(player_t());
					players.back().playerstate = PST_REBORN;
					consoleplayer_id = displayplayer_id = players.back().id = 1;
				}

				G_InitNew (startmap);
				if (autorecord)
					if (G_RecordDemo(demorecordfile.c_str()))
						G_BeginRecording();
			}
		}
        else
		{
            if (gamestate != GS_CONNECTING)
                gamestate = GS_HIDECONSOLE;

			C_HideConsole();

			if (gamemode == commercial_bfg) // DOOM 2 BFG Edtion
                AddCommandString("menu_main");

			D_StartTitle (); // start up intro loop
		}
    }

	// denis - this will run a demo and quit
	p = Args.CheckParm ("+demotest");
	if (p && p < Args.NumArgs()-1)
	{
		demotest = 1;
		defdemoname = Args.GetArg (p+1);
		G_DoPlayDemo();

		while(demoplayback)
		{
			DObject::BeginFrame ();
			G_Ticker();
			DObject::EndFrame ();
			gametic++;
		}
	}
	else
	{
		demotest = 0;
		D_DoomLoop ();		// never returns
	}
}
예제 #2
0
void DoMain (HINSTANCE hInstance)
{
	LONG WinWidth, WinHeight;
	int height, width, x, y;
	RECT cRect;
	TIMECAPS tc;
	DEVMODE displaysettings;

	try
	{
#ifdef _MSC_VER
		_set_new_handler (NewFailure);
#endif

		Args = new DArgs(__argc, __argv);

		// Load Win32 modules
		Kernel32Module.Load({"kernel32.dll"});
		Shell32Module.Load({"shell32.dll"});
		User32Module.Load({"user32.dll"});

		// Under XP, get our session ID so we can know when the user changes/locks sessions.
		// Since we need to remain binary compatible with older versions of Windows, we
		// need to extract the ProcessIdToSessionId function from kernel32.dll manually.
		HMODULE kernel = GetModuleHandle ("kernel32.dll");

		if (Args->CheckParm("-stdout"))
		{
			// As a GUI application, we don't normally get a console when we start.
			// If we were run from the shell and are on XP+, we can attach to its
			// console. Otherwise, we can create a new one. If we already have a
			// stdout handle, then we have been redirected and should just use that
			// handle instead of creating a console window.

			StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
			if (StdOut != NULL)
			{
				// It seems that running from a shell always creates a std output
				// for us, even if it doesn't go anywhere. (Running from Explorer
				// does not.) If we can get file information for this handle, it's
				// a file or pipe, so use it. Otherwise, pretend it wasn't there
				// and find a console to use instead.
				BY_HANDLE_FILE_INFORMATION info;
				if (!GetFileInformationByHandle(StdOut, &info))
				{
					StdOut = NULL;
				}
			}
			if (StdOut == NULL)
			{
				// AttachConsole was introduced with Windows XP. (OTOH, since we
				// have to share the console with the shell, I'm not sure if it's
				// a good idea to actually attach to it.)
				typedef BOOL (WINAPI *ac)(DWORD);
				ac attach_console = kernel != NULL ? (ac)GetProcAddress(kernel, "AttachConsole") : NULL;
				if (attach_console != NULL && attach_console(ATTACH_PARENT_PROCESS))
				{
					StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
					DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL);
					AttachedStdOut = true;
				}
				if (StdOut == NULL && AllocConsole())
				{
					StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
				}
				FancyStdOut = true;
			}
		}

		// Set the timer to be as accurate as possible
		if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR)
			TimerPeriod = 1;	// Assume minimum resolution of 1 ms
		else
			TimerPeriod = tc.wPeriodMin;

		timeBeginPeriod (TimerPeriod);

		/*
		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.
		*/

		atexit (call_terms);

		atterm (I_Quit);

		// Figure out what directory the program resides in.
		char *program;

#ifdef _MSC_VER
		if (_get_pgmptr(&program) != 0)
		{
			I_FatalError("Could not determine program location.");
		}
#else
		char progbuff[1024];
		GetModuleFileName(0, progbuff, sizeof(progbuff));
		progbuff[1023] = '\0';
		program = progbuff;
#endif

		progdir = program;
		program = progdir.LockBuffer();
		*(strrchr(program, '\\') + 1) = '\0';
		FixPathSeperator(program);
		progdir.Truncate((long)strlen(program));
		progdir.UnlockBuffer();

		HDC screenDC = GetDC(0);
		int dpi = GetDeviceCaps(screenDC, LOGPIXELSX);
		ReleaseDC(0, screenDC);
		width = (512 * dpi + 96 / 2) / 96;
		height = (384 * dpi + 96 / 2) / 96;

		// Many Windows structures that specify their size do so with the first
		// element. DEVMODE is not one of those structures.
		memset (&displaysettings, 0, sizeof(displaysettings));
		displaysettings.dmSize = sizeof(displaysettings);
		EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings);
		x = (displaysettings.dmPelsWidth - width) / 2;
		y = (displaysettings.dmPelsHeight - height) / 2;

		if (Args->CheckParm ("-0"))
		{
			x = y = 0;
		}

		WNDCLASS WndClass;
		WndClass.style			= 0;
		WndClass.lpfnWndProc	= LConProc;
		WndClass.cbClsExtra		= 0;
		WndClass.cbWndExtra		= 0;
		WndClass.hInstance		= hInstance;
		WndClass.hIcon			= LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1));
		WndClass.hCursor		= LoadCursor (NULL, IDC_ARROW);
		WndClass.hbrBackground	= NULL;
		WndClass.lpszMenuName	= NULL;
		WndClass.lpszClassName	= (LPCTSTR)WinClassName;
		
		/* register this new class with Windows */
		if (!RegisterClass((LPWNDCLASS)&WndClass))
			I_FatalError ("Could not register window class");
		
		/* create window */
		char caption[100];
		mysnprintf(caption, countof(caption), "" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime());
		Window = CreateWindowEx(
				WS_EX_APPWINDOW,
				(LPCTSTR)WinClassName,
				(LPCTSTR)caption,
				WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
				x, y, width, height,
				(HWND)   NULL,
				(HMENU)  NULL,
						hInstance,
				NULL);

		if (!Window)
			I_FatalError ("Could not open window");

		if (kernel != NULL)
		{
			typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
			pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId");
			if (pidsid != 0)
			{
				if (!pidsid (GetCurrentProcessId(), &SessionID))
				{
					SessionID = 0;
				}
				hwtsapi32 = LoadLibraryA ("wtsapi32.dll");
				if (hwtsapi32 != 0)
				{
					FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification");
					if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION))
					{
						FreeLibrary (hwtsapi32);
						hwtsapi32 = 0;
					}
					else
					{
						atterm (UnWTS);
					}
				}
			}
		}

		GetClientRect (Window, &cRect);

		WinWidth = cRect.right;
		WinHeight = cRect.bottom;

		CoInitialize (NULL);
		atterm (UnCOM);

		C_InitConsole (((WinWidth / 8) + 2) * 8, (WinHeight / 12) * 8, false);

		I_DetectOS ();
		D_DoomMain ();
	}
	catch (class CNoRunExit &)
	{
		I_ShutdownGraphics();
		if (!batchrun)
		{
			if (FancyStdOut && !AttachedStdOut)
			{ // Outputting to a new console window: Wait for a keypress before quitting.
				DWORD bytes;
				HANDLE stdinput = GetStdHandle(STD_INPUT_HANDLE);

				ShowWindow(Window, SW_HIDE);
				WriteFile(StdOut, "Press any key to exit...", 24, &bytes, NULL);
				FlushConsoleInputBuffer(stdinput);
				SetConsoleMode(stdinput, 0);
				ReadConsole(stdinput, &bytes, 1, &bytes, NULL);
			}
			else if (StdOut == NULL)
			{
				ShowErrorPane(NULL);
			}
		}
		exit(0);
	}
	catch (class CDoomError &error)
	{
		I_ShutdownGraphics ();
		RestoreConView ();
		I_FlushBufferedConsoleStuff();
		if (error.GetMessage ())
		{
			if (!batchrun)
			{
				ShowErrorPane(error.GetMessage());
			}
			else
			{
				Printf("%s\n", error.GetMessage());
			}
		}
		exit (-1);
	}
}
예제 #3
0
int main (int argc, char **argv)
{
#if !defined (__APPLE__)
	{
		int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS };
		cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo);
	}
#endif // !__APPLE__

	printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n",
		GetVersionString(), GetGitTime(), __DATE__);

	seteuid (getuid ());
    std::set_new_handler (NewFailure);

#if defined(__MACH__) && !defined(NOASM)
	unprotect_rtext();
#endif

	// Set LC_NUMERIC environment variable in case some library decides to
	// clear the setlocale call at least this will be correct.
	// Note that the LANG environment variable is overridden by LC_*
	setenv ("LC_NUMERIC", "C", 1);

#ifndef NO_GTK
	GtkAvailable = gtk_init_check (&argc, &argv);
#endif
	
	setlocale (LC_ALL, "C");

	if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE|SDL_INIT_JOYSTICK) == -1)
	{
		fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError());
		return -1;
	}
	atterm (SDL_Quit);

	{
		char viddriver[80];

		if (SDL_VideoDriverName(viddriver, sizeof(viddriver)) != NULL)
		{
			printf("Using video driver %s\n", viddriver);
#ifdef USE_XCURSOR
			UseXCursor = (strcmp(viddriver, "x11") == 0);
#endif
		}
		printf("\n");
	}

	char caption[100];
	mysnprintf(caption, countof(caption), GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
	SDL_WM_SetCaption(caption, caption);

#ifdef __APPLE__
	
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();
	if ( NULL != videoInfo )
	{
		EXTERN_CVAR(  Int, vid_defwidth  )
		EXTERN_CVAR(  Int, vid_defheight )
		EXTERN_CVAR(  Int, vid_defbits   )
		EXTERN_CVAR( Bool, vid_vsync     )
		EXTERN_CVAR( Bool, fullscreen    )
		
		vid_defwidth  = videoInfo->current_w;
		vid_defheight = videoInfo->current_h;
		vid_defbits   = videoInfo->vfmt->BitsPerPixel;
		vid_vsync     = true;
		fullscreen    = true;
	}
	
#endif // __APPLE__
	
    try
    {
		Args = new DArgs(argc, argv);

		/*
		  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.
		*/

		atexit (call_terms);
		atterm (I_Quit);

		// Should we even be doing anything with progdir on Unix systems?
		char program[PATH_MAX];
		if (realpath (argv[0], program) == NULL)
			strcpy (program, argv[0]);
		char *slash = strrchr (program, '/');
		if (slash != NULL)
		{
			*(slash + 1) = '\0';
			progdir = program;
		}
		else
		{
			progdir = "./";
		}

		I_StartupJoysticks();
		C_InitConsole (80*8, 25*8, false);
		D_DoomMain ();
    }
    catch (class CDoomError &error)
    {
		I_ShutdownJoysticks();
		if (error.GetMessage ())
			fprintf (stderr, "%s\n", error.GetMessage ());
		exit (-1);
    }
    catch (...)
    {
		call_terms ();
		throw;
    }
    return 0;
}
예제 #4
0
int main (int argc, char **argv)
{
	printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n\n",
		DOTVERSIONSTR_NOREV,SVN_REVISION_STRING,__DATE__);

	{
		int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS };
		cc_install_handlers(4, s, "zdoom-crash.log", DoomSpecificInfo);
	}

	seteuid (getuid ());
    std::set_new_handler (NewFailure);

#ifndef NO_GTK
	GtkAvailable = gtk_init_check (&argc, &argv);
#endif
	
	setlocale (LC_ALL, "C");

	if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) == -1)
	{
		fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError());
		return -1;
	}
	atterm (SDL_Quit);

	SDL_WM_SetCaption (GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")", NULL);
	
    try
    {
		Args = new DArgs(argc, argv);
		atterm(FinalGC);

		/*
		  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.
		*/

		atexit (call_terms);
		atterm (I_Quit);

		// Should we even be doing anything with progdir on Unix systems?
		char program[PATH_MAX];
		if (realpath (argv[0], program) == NULL)
			strcpy (program, argv[0]);
		char *slash = strrchr (program, '/');
		if (slash != NULL)
		{
			*(slash + 1) = '\0';
			progdir = program;
		}
		else
		{
			progdir = "./";
		}

		C_InitConsole (80*8, 25*8, false);
		D_DoomMain ();
    }
    catch (class CDoomError &error)
    {
		if (error.GetMessage ())
			fprintf (stderr, "%s\n", error.GetMessage ());
		exit (-1);
    }
    catch (...)
    {
		call_terms ();
		throw;
    }
    return 0;
}
예제 #5
0
int main(int argc, char *argv[])
#endif
{
	try
	{
#if defined(UNIX) && !defined(GEKKO)
		if(!getuid() || !geteuid())
			I_FatalError("root user detected, quitting odamex immediately");
#endif

		// [ML] 2007/9/3: From Eternity (originally chocolate Doom) Thanks SoM & fraggle!
		Args.SetArgs (argc, argv);

		const char *CON_FILE = Args.CheckValue("-confile");
		if(CON_FILE)CON.open(CON_FILE, std::ios::in);

		// denis - if argv[1] starts with "odamex://"
		if(argc == 2 && argv && argv[1])
		{
			const char *protocol = "odamex://";
			const char *uri = argv[1];

			if(strncmp(uri, protocol, strlen(protocol)) == 0)
			{
				std::string location = uri + strlen(protocol);
				size_t term = location.find_first_of('/');

				if(term == std::string::npos)
					term = location.length();

				Args.AppendArg("-connect");
				Args.AppendArg(location.substr(0, term).c_str());
			}
		}

        // [Russell] - No more double-tapping of capslock to enable autorun
        putenv("SDL_DISABLE_LOCK_KEYS=1");

#if defined WIN32 && !defined _XBOX
    	// From the SDL 1.2.10 release notes:
    	//
    	// > The "windib" video driver is the default now, to prevent
    	// > problems with certain laptops, 64-bit Windows, and Windows
    	// > Vista.
    	//
    	// The hell with that.

   		// SoM: the gdi interface is much faster for windowed modes which are more
   		// commonly used. Thus, GDI is default.
		//
		// GDI mouse issues fill many users with great sadness. We are going back
		// to directx as defulat for now and the people will rejoice. --Hyper_Eye
     	if (Args.CheckParm ("-gdi"))
        	putenv("SDL_VIDEODRIVER=windib");
    	else if (getenv("SDL_VIDEODRIVER") == NULL || Args.CheckParm ("-directx") > 0)
        	putenv("SDL_VIDEODRIVER=directx");

        // Set the process affinity mask to 1 on Windows, so that all threads
        // run on the same processor.  This is a workaround for a bug in
        // SDL_mixer that causes occasional crashes.  Thanks to entryway and fraggle for this.
        //
        // [ML] 8/6/10: Updated to match prboom+'s I_SetAffinityMask.  We don't do everything
        // you might find in there but we do enough for now.
        HMODULE kernel32_dll = LoadLibrary("kernel32.dll");
        
        if (kernel32_dll)
        {
            SetAffinityFunc SetAffinity = (SetAffinityFunc)GetProcAddress(kernel32_dll, "SetProcessAffinityMask");
            
            if (SetAffinity)
            {
                if (!SetAffinity(GetCurrentProcess(), 1))
                    LOG << "Failed to set process affinity mask: " << GetLastError() << std::endl;                
            }
        }
#endif

		if (SDL_Init (SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) == -1)
			I_FatalError("Could not initialize SDL:\n%s\n", SDL_GetError());

		atterm (SDL_Quit);

		/*
		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.
		*/

		atexit (call_terms);
		Z_Init ();					// 1/18/98 killough: start up memory stuff first

        atterm (R_Shutdown);
		atterm (I_Quit);
		atterm (DObject::StaticShutdown);

		// Figure out what directory the program resides in.
		progdir = I_GetBinaryDir();
		startdir = I_GetCWD();

		// init console
		C_InitConsole (80 * 8, 25 * 8, false);

		D_DoomMain ();
	}
	catch (CDoomError &error)
	{
		if (LOG.is_open())
        {
            LOG << error.GetMessage() << std::endl;
            LOG << std::endl;
        }
#ifndef WIN32
            fprintf(stderr, "%s\n", error.GetMessage().c_str());
#elif _XBOX
		// Use future Xbox error message handling.    -- Hyper_Eye
#else
		MessageBox(NULL, error.GetMessage().c_str(), "Odamex Error", MB_OK);
#endif
		exit (-1);
	}
#ifndef _DEBUG
	catch (...)
	{
		// If an exception is thrown, be sure to do a proper shutdown.
		// This is especially important if we are in fullscreen mode,
		// because the OS will only show the alert box if we are in
		// windowed mode. Graphics gets shut down first in case something
		// goes wrong calling the cleanup functions.
		call_terms ();
		// Now let somebody who understands the exception deal with it.
		throw;
	}
#endif
	return 0;
}
예제 #6
0
int main (int argc, char **argv)
{
	{
		int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS };
		cc_install_handlers(4, s, "zdoom-crash.log", DoomSpecificInfo);
	}

	seteuid (getuid ());
    std::set_new_handler (NewFailure);

	if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) == -1)
	{
		fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError());
		return -1;
	}
	atterm (SDL_Quit);

	SDL_WM_SetCaption (GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")", NULL);
	
    try
    {
		Args.SetArgs (argc, argv);

		/*
		  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.
		*/

		atexit (call_terms);
		atterm (I_Quit);

		if (realpath (argv[0], progdir) == NULL)
			strcpy (progdir, argv[0]);
		char *slash = strrchr (progdir, '/');
		if (slash)
			*(slash + 1) = '\0';
		else
			progdir[0] = '.', progdir[1] = '/', progdir[2] = '\0';

		C_InitConsole (80*8, 25*8, false);
		D_DoomMain ();
    }
    catch (class CDoomError &error)
    {
		if (error.GetMessage ())
			fprintf (stderr, "%s\n", error.GetMessage ());
		exit (-1);
    }
    catch (...)
    {
		call_terms ();
		throw;
    }
    return 0;
}
예제 #7
0
//
// D_DoomMain
//
// [NightFang] - Cause I cant call ArgsSet from g_level.cpp
// [ML] 23/1/07 - Add Response file support back in
//
void D_DoomMain()
{
	unsigned int p;

	gamestate = GS_STARTUP;

	// init console so it can capture all of the startup messages
	C_InitConsole();
	atterm(C_ShutdownConsole);

	W_SetupFileIdentifiers();

	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems();

	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError("Could not initialize LZO routines");

    C_ExecCmdLineParams(false, true);	// [Nes] test for +logfile command

	// Always log by default
    if (!LOG.is_open())
    	C_DoCommand("logfile");

	M_LoadDefaults();			// load before initing other systems
	C_ExecCmdLineParams(true, false);	// [RH] do all +set commands on the command line

	std::vector<std::string> newwadfiles, newpatchfiles;

	const char* iwad_filename_cstr = Args.CheckValue("-iwad");
	if (iwad_filename_cstr)
	{
		std::string iwad_filename(iwad_filename_cstr);
		M_AppendExtension(iwad_filename, ".WAD");
		newwadfiles.push_back(iwad_filename);
	}

	D_AddWadCommandLineFiles(newwadfiles);
	D_AddDehCommandLineFiles(newpatchfiles);

	D_LoadResourceFiles(newwadfiles, newpatchfiles);

	Printf(PRINT_HIGH, "I_Init: Init hardware.\n");
	I_Init();

	// [SL] Call init routines that need to be reinitialized every time WAD changes
	D_Init();
	atterm(D_Shutdown);

	Printf(PRINT_HIGH, "SV_InitNetwork: Checking network game status.\n");
	SV_InitNetwork();

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (GStrings(STARTUP1)[0])	Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP1));
	if (GStrings(STARTUP2)[0])	Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP2));
	if (GStrings(STARTUP3)[0])	Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP3));
	if (GStrings(STARTUP4)[0])	Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP4));
	if (GStrings(STARTUP5)[0])	Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP5));

	// developer mode
	devparm = Args.CheckParm("-devparm");

	if (devparm)
		Printf (PRINT_HIGH, "%s", GStrings(D_DEVSTR));        // D_DEVSTR

	// Nomonsters
	if (Args.CheckParm("-nomonsters"))
		sv_nomonsters = 1;

	// Respawn
	if (Args.CheckParm("-respawn"))
		sv_monstersrespawn = 1;

	// Fast
	if (Args.CheckParm("-fast"))
		sv_fastmonsters = 1;

    // get skill / episode / map from parms
	strcpy(startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

	const char* val = Args.CheckValue("-skill");
	if (val)
		sv_skill.Set(val[0] - '0');

	p = Args.CheckParm("-timer");
	if (p && p < Args.NumArgs() - 1)
	{
		float time = atof(Args.GetArg(p + 1));
		Printf(PRINT_HIGH, "Levels will end after %g minute%s.\n", time, time > 1 ? "s" : "");
		sv_timelimit.Set(time);
	}

	if (Args.CheckValue("-avg"))
	{
		Printf(PRINT_HIGH, "Austin Virtual Gaming: Levels will end after 20 minutes\n");
		sv_timelimit.Set(20);
	}

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet();

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams(false, false);

	// [AM] Initialize banlist
	SV_InitBanlist();

	Printf(PRINT_HIGH, "========== Odamex Server Initialized ==========\n");

	#ifdef UNIX
	if (Args.CheckParm("-fork"))
		daemon_init();
	#endif

	p = Args.CheckParm("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi(Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy(startmap, CalcMapName(ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm("+map");
	if (p && p < Args.NumArgs() - 1)
	{
		strncpy(startmap, Args.GetArg(p + 1), 8);
		((char*)Args.GetArg(p))[0] = '-';
		autostart = true;
	}

	strncpy(level.mapname, startmap, sizeof(level.mapname));

	G_ChangeMap();

	D_DoomLoop();	// never returns
}
예제 #8
0
void DoMain (HINSTANCE hInstance)
{
	LONG WinWidth, WinHeight;
	int height, width;
	RECT cRect;
	TIMECAPS tc;

	try
	{
#ifdef _MSC_VER
		_set_new_handler (NewFailure);
#endif

		Args.SetArgs (__argc, __argv);

		// Under XP, get our session ID so we can know when the user changes/locks sessions.
		// Since we need to remain binary compatible with older versions of Windows, we
		// need to extract the ProcessIdToSessionId function from kernel32.dll manually.
		HMODULE kernel = GetModuleHandle ("kernel32.dll");

		// NASM does not support creating writeable code sections (even though this
		// is a perfectly valid configuration for Microsoft's COFF format), so I
		// need to make the self-modifying code writeable after it's already loaded.
#ifdef USEASM
	{
		BYTE *module = (BYTE *)GetModuleHandle (NULL);
		IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)module;
		IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS *)(module + dosHeader->e_lfanew);
		IMAGE_SECTION_HEADER *sections = IMAGE_FIRST_SECTION (ntHeaders);
		int i;
		LPVOID *start = NULL;
		SIZE_T size = 0;
		DWORD oldprotect;

		for (i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
		{
			if (memcmp (sections[i].Name, ".rtext\0", 8) == 0)
			{
				start = (LPVOID *)(sections[i].VirtualAddress + module);
				size = sections[i].Misc.VirtualSize;
				break;
			}
		}

		// I think these pages need to be mapped PAGE_EXECUTE_WRITECOPY (based on the
		// description of PAGE_WRITECOPY), but PAGE_EXECUTE_READWRITE seems to work
		// just as well; two instances of the program can be running with different
		// resolutions at the same time either way. Perhaps the file mappings for
		// executables are created with PAGE_WRITECOPY, so any attempts to give them
		// write access are automatically transformed to copy-on-write?
		//
		// This used to be PAGE_EXECUTE_WRITECOPY until Timmie found out Win9x doesn't
		// support it, although the MSDN does not indicate it.
		if (!VirtualProtect (start, size, PAGE_EXECUTE_READWRITE, &oldprotect))
		{
			I_FatalError ("The self-modifying code section code not be made writeable.");
		}
	}
#endif

		// Set the timer to be as accurate as possible
		if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR)
			TimerPeriod = 1;	// Assume minimum resolution of 1 ms
		else
			TimerPeriod = tc.wPeriodMin;

		timeBeginPeriod (TimerPeriod);

		/*
		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.
		*/

		atexit (call_terms);

		atterm (I_Quit);

		// Figure out what directory the program resides in.
		GetModuleFileName (NULL, progdir, 1024);
		*(strrchr (progdir, '\\') + 1) = 0;
		FixPathSeperator (progdir);

		// [BC] When hosting, spawn a console dialog box instead of creating a window.
		if ( Args.CheckParm( "-host" ))
		{
			// This never returns.
			DialogBox( g_hInst, MAKEINTRESOURCE( IDD_SERVERDIALOG ), NULL/*(HWND)Window*/, SERVERCONSOLE_ServerDialogBoxCallback );
		}
		else
		{
			height = GetSystemMetrics (SM_CYFIXEDFRAME) * 2 +
					GetSystemMetrics (SM_CYCAPTION) + 12 * 32;
			width  = GetSystemMetrics (SM_CXFIXEDFRAME) * 2 + 8 * 78;

			TheInvisibleCursor = LoadCursor (hInstance, MAKEINTRESOURCE(IDC_INVISIBLECURSOR));
			TheArrowCursor = LoadCursor (NULL, IDC_ARROW);

			WndClass.style			= 0;
			WndClass.lpfnWndProc	= WndProc;
			WndClass.cbClsExtra		= 0;
			WndClass.cbWndExtra		= 0;
			WndClass.hInstance		= hInstance;
			WndClass.hIcon			= LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON5));
			WndClass.hCursor		= TheArrowCursor;
			WndClass.hbrBackground	= NULL;
			WndClass.lpszMenuName	= NULL;
			WndClass.lpszClassName	= (LPCTSTR)WinClassName;
			
			/* register this new class with Windows */
			if (!RegisterClass((LPWNDCLASS)&WndClass))
				I_FatalError ("Could not register window class");
			
			/* create window */
			Window = CreateWindow((LPCTSTR)WinClassName,
					(LPCTSTR) GAMESIG " v" DOTVERSIONSTR " (" __DATE__ ")",
					WS_OVERLAPPEDWINDOW,
					0/*CW_USEDEFAULT*/, 1/*CW_USEDEFAULT*/, width, height,
					(HWND)   NULL,
					(HMENU)  NULL,
							hInstance,
					NULL);

			if (!Window)
				I_FatalError ("Could not open window");

			WndClass.lpfnWndProc = LConProc;
			WndClass.lpszClassName = (LPCTSTR)ConClassName;
			if (RegisterClass ((LPWNDCLASS)&WndClass))
			{
				ConWindow = CreateWindowEx (
					WS_EX_PALETTEWINDOW & (~WS_EX_TOPMOST),
					(LPCTSTR)ConClassName,
					(LPCTSTR) "Skulltag Startup Viewer",
					WS_OVERLAPPEDWINDOW/* | WS_VISIBLE*/,
					CW_USEDEFAULT, CW_USEDEFAULT,
					512, 384,
					Window, NULL, hInstance, NULL);
			}

			if (kernel != 0)
			{
				typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
				pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId");
				if (pidsid != 0)
				{
					if (!pidsid (GetCurrentProcessId(), &SessionID))
					{
						SessionID = 0;
					}
					hwtsapi32 = LoadLibraryA ("wtsapi32.dll");
					if (hwtsapi32 != 0)
					{
						FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification");
						if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION))
						{
							FreeLibrary (hwtsapi32);
							hwtsapi32 = 0;
						}
						else
						{
							atterm (UnWTS);
						}
					}
				}
			}

			GetClientRect (Window, &cRect);

			WinWidth = cRect.right;
			WinHeight = cRect.bottom;
		}

		CoInitialize (NULL);
		atterm (UnCOM);

		C_InitConsole (((WinWidth / 8) + 2) * 8, (WinHeight / 12) * 8, false);

		I_DetectOS ();
		D_DoomMain ();
	}
	catch (class CDoomError &error)
	{
		I_ShutdownHardware ();
		SetWindowPos (Window, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW);
		if (ConWindow != NULL)
		{
			ShowWindow (ConWindow, SW_SHOW);
		}
		if (error.GetMessage ())
			MessageBox (Window, error.GetMessage(),
				"Skulltag Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
		exit (-1);
	}
}
예제 #9
0
int main(int argc, char *argv[])
{
	try
	{
#ifdef UNIX
		if(!getuid() || !geteuid())
			I_FatalError("root user detected, quitting odamex immediately");
#endif

		// [ML] 2007/9/3: From Eternity (originally chocolate Doom) Thanks SoM & fraggle!
		Args.SetArgs (argc, argv);

		LOG_FILE = Args.CheckValue("-logfile");
		if(!LOG_FILE)LOG_FILE = "odamex.log";
		LOG.open(LOG_FILE, std::ios::out);

        if (!LOG.is_open())
            std::cerr << "Unable to create logfile: %s\n" << std::endl;

		const char *CON_FILE = Args.CheckValue("-confile");
		if(CON_FILE)CON.open(CON_FILE, std::ios::in);

		// denis - if argv[1] starts with "odamex://"
		if(argc == 2 && argv && argv[1])
		{
			const char *protocol = "odamex://";
			const char *uri = argv[1];

			if(strncmp(uri, protocol, strlen(protocol)) == 0)
			{
				std::string location = uri + strlen(protocol);
				size_t term = location.find_first_of('/');

				if(term == std::string::npos)
					term = location.length();

				Args.AppendArg("-connect");
				Args.AppendArg(location.substr(0, term).c_str());
			}
		}

#ifdef WIN32
    	// From the SDL 1.2.10 release notes: 
    	//
    	// > The "windib" video driver is the default now, to prevent 
    	// > problems with certain laptops, 64-bit Windows, and Windows 
    	// > Vista. 
    	//
    	// The hell with that.
   
   		// SoM: the gdi interface is much faster for windowed modes which are more
   		// commonly used. Thus, GDI is default.
     	if (Args.CheckParm ("-directx"))
        	putenv("SDL_VIDEODRIVER=directx");     
    	else if (getenv("SDL_VIDEODRIVER") == NULL || Args.CheckParm ("-gdi") > 0)
        	putenv("SDL_VIDEODRIVER=windib");
        	

        // Set the process affinity mask to 1 on Windows, so that all threads
        // run on the same processor.  This is a workaround for a bug in 
        // SDL_mixer that causes occasional crashes.
        // Thanks to entryway and fraggle for this.
        
        if (!SetProcessAffinityMask(GetCurrentProcess(), 1))
            LOG << "Failed to set process affinity mask: " << GetLastError() << std::endl;

#endif
		
		if (SDL_Init (SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) == -1)
			I_FatalError("Could not initialize SDL:\n%s\n", SDL_GetError());

		atterm (SDL_Quit);
		
		/*
		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.
		*/
		
		atexit (call_terms);
		Z_Init ();					// 1/18/98 killough: start up memory stuff first

		atterm (I_Quit);
		atterm (DObject::StaticShutdown);
		
		// Figure out what directory the program resides in.
		progdir = I_GetBinaryDir();
		startdir = I_GetCWD();
		
		// init console
		C_InitConsole (80 * 8, 25 * 8, false);
		
		Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);
		
		D_DoomMain ();
	}
	catch (CDoomError &error)
	{
		if (LOG.is_open())
        {
            LOG << error.GetMessage() << std::endl;
        }
#ifndef WIN32
            fprintf(stderr, "%s\n", error.GetMessage().c_str());
#else
		MessageBox(NULL, error.GetMessage().c_str(), "Odamex Error", MB_OK);
#endif
		exit (-1);
	}
#ifndef _DEBUG
	catch (...)
	{
		// If an exception is thrown, be sure to do a proper shutdown.
		// This is especially important if we are in fullscreen mode,
		// because the OS will only show the alert box if we are in
		// windowed mode. Graphics gets shut down first in case something
		// goes wrong calling the cleanup functions.
		call_terms ();
		// Now let somebody who understands the exception deal with it.
		throw;
	}
#endif
	return 0;
}