#include "pch.hpp"
//===========================================================================//
// File:	 ErrorHandler.cpp												 //
// Project:  GameOS					                                         //
// Contents: Error Handling routines										 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 11/04/97  SP     Created													 // 
// 11/10/97  JTR    Forced GOERR_TERMINATE to crash into debugger			 //
// 12/12/97  JTR    Fixed dialog focus										 //
// 12/13/97  JTR    Fixed Initialize Spew									 //
// 01/06/98  JTR    Straightened out bug in error message					 //
// 03/16/98  JTR    Added a nifty exception handler							 //
//																			 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include "ErrorHandler.hpp"
#include "Windows.hpp"
#include "Registry.hpp"
#include "DirectX.hpp"
#include "DXRasterizer.hpp"
#include "3DRasterizer.hpp"
#include "MemoryManager.hpp"
#include "Sound Renderer.hpp"
#include "ControlManager.hpp"
#include "LocalizationManager.hpp"
#include "Time.hpp"
#include "Texture Manager.hpp"
#include "Debugger.hpp"
#include "Profiler.hpp"
#include "Font3D.hpp"
#include "VideoPlayback.hpp"
#include "Perf.h"
#include "FileIO.hpp"
#include <crtdbg.h>


void DestroyNetworking();
void DestroyVextexBuffers( bool DontReportErrors );
extern bool gPauseSpew;
extern void StopGosViewServerThreads();
extern volatile char* ExceptionAttempt;


//
//
// Exit from a GAMEOS program, does minimal cleanup to leave windows in a valid state.
//
//
void __stdcall ExitGameOS()
{
	gos_MathExceptions( 0,0 );						// Stop any further math exceptions
	TerminateGame=1;								// Game can never start back up from now on
	gPauseSpew=0;									// Stop any pausing on spews
	if( Environment.fullScreen )
	{
		ExceptionAttempt="Exit:EnterWindowMode";
		EnterWindowMode();							// Make sure out of full screen mode
	}
	ExceptionAttempt="Exit:DestroyThreads";
	DestroyThreads();								// Destroy threads
	ExceptionAttempt="Exit:DestroyVextexBuffers";
	DestroyVextexBuffers( ProcessingError!=0 );		// Destroy all vertex buffers
	ExceptionAttempt="Exit:DeleteLogging";
	DeleteLogging();								// Stop logging
	ExceptionAttempt="Exit:DestroyNetworking";
	DestroyNetworking();							// Close any networking
	ExceptionAttempt="Exit:Destroy3DFont";
	Destroy3DFont();								// Remove any other fonts
	ExceptionAttempt="Exit:DestroyTextureManager";
	DestroyTextureManager();						// Remove textures
	ExceptionAttempt="Exit:SoundRendererUninstall";
	SoundRendererUninstall();						// Close sound renderer
	ExceptionAttempt="Exit:VideoManagerUninstall";
	VideoManagerUninstall();						// Stop any video playback
	ExceptionAttempt="Exit:CMUninstall";
	CMUninstall();									// Close Control manager
	ExceptionAttempt="Exit:TimeManagerUninstall";
	TimeManagerUninstall();							// Time manager
	ExceptionAttempt="Exit:Destroy3D";
	Destroy3D();									// Direct3D
	ExceptionAttempt="Exit:DirectDrawUninstall";
	if ( Platform != Platform_DLL )
		DirectDrawUninstall();						// Clean up any DirectX surfaces
	ExceptionAttempt="Exit:RegistryManagerUninstall";
	RegistryManagerUninstall();						// Registry updating
	ExceptionAttempt="Exit:DestroyStatistics";
	DestroyStatistics();							// Stop all statistics
	ExceptionAttempt="Exit:TermPerformanceMonitorLibrary";
	TermPerformanceMonitorLibrary();				// Stop processor performance registers
	ExceptionAttempt="Exit:StopGosViewServerThreads";
	StopGosViewServerThreads();						// Shut down GosView server
	ExceptionAttempt="Exit:CleanUpDebugger";
	CleanUpDebugger();								// Clean up debugger
	ExceptionAttempt="Exit:Destory_FileSystem";
	Destory_FileSystem( ProcessingError!=0 );		// Close down file system
	ExceptionAttempt="Exit:DestroyExceptions";
	DestroyExceptions();							// No more ignore list
	ExceptionAttempt="Exit:DestroyDebugger";
	DestroyDebugger();								// Release all debugger memory
	ExceptionAttempt="Exit:DestroyLocalization";
	DestroyLocalization();							// Unload localization DLL's
	ExceptionAttempt="Exit:MM_Shutdown";
	MM_Shutdown();									// Memory manager
	ExceptionAttempt="Exit:TerminateSpew";
	TerminateSpew();								// Close logging file
	if( DesktopDC )
		ReleaseDC(NULL, DesktopDC);
	ExceptionAttempt="Exit:DestroyLibraries";
	DestroyLibraries();								// Unload any libraries GOS loaded
	ExceptionAttempt="Exit:DestroyImageHlp";
	DestroyImageHlp();
	ExceptionAttempt="Exit:DestroyWindows";
	DestroyWindows();								// Clean up windows
	ExceptionAttempt="Exit:Finished";
	
	if( Platform==Platform_MFC || Platform==Platform_DLL )
	{
		if( ProcessingError )						// In MFC applications, do not debug memory errors when GameOS 'Exits'
		{
			#ifdef _DEBUG											// These disable MFC/CRT memory leak dumps when the app 'Exits' in debug builds
			_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
			_CrtSetReportFile( _CRT_WARN, NULL );
			_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
			_CrtSetReportFile( _CRT_ERROR, NULL );
			_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
			_CrtSetReportFile( _CRT_ASSERT, NULL );
			#endif
			status=AfterExit;
			TerminateProcess(GetCurrentProcess(), 1); 	// During an error, game is unstable, exit directly here (No static C++ class clean up)
		}
		else
		{
			return;
		}
	}
	else
	{
		status=AfterExit;
		if( ProcessingError>1 )
		{
			TerminateProcess(GetCurrentProcess(), 1); 	// During an error, game is unstable, exit directly here
		}
		else
		{
			exit(0);									// Otherwise clean up static C++ clases etc...	
		}
	}
}
