<NME> WINMAIN.CPP
<BEF> #define _X86_

#include "STANDARD.H"
#include "GLOBAL.H"
#include "TEMPLATE.H"
#include "DIRECTX.H"
#include "WINMAIN.H"
//#include "console.h"
#include "crtdbg.h"
//#include "texture.h"
#include "DRAWPRIMITIVE.H"
#include "HWRENDER.H"
#include "UTILS.H"
#include "CONTROL.H"
#include "DI.H"
#include "DS.H"
#include "time.h"
//#include "spanbuffer.h"
#include "HWINSERT.H"
#include "PICTURE.H"
#include "resource.h"
#include "FILE.H"
#include "GAMEFLOW.H"
#include "GAME.H"
#include "PCSETUP.H"
#include "DEBUG.H"
#include "INPUT.H"
#include "DISPLAY.H"
#include "TEXT.H"
#include <ctime>

WINAPP App;
bool thread_started;
HANDLE hThread;

void WinProcMsg()// (F)
{
	Log(LT_Enter, "WinProcMsg");

	MSG Msg;

	do
	{
		GetMessageA(&Msg, nullptr, 0, 0);

		if (!TranslateAcceleratorA(App.WindowHandle, App.hAccTable, &Msg))
		{
			TranslateMessage(&Msg);
			DispatchMessageA(&Msg);
		}
	} while (!thread_started && Msg.message != WM_QUIT);
}

void WinClose()// (F)
{
	Log(LT_Enter, "WinClose");

	SaveSettings();
	CloseHandle(App.hObject);
	DXFreeInfo(&App.DeviceInfo);
	DestroyAcceleratorTable(App.hAccTable);
	CloseDirectX();

	if (App.lpDIKeyboard)
	{
		DX_TRY(App.lpDIKeyboard->Unacquire());
		DXRelease(App.lpDIKeyboard, "Keyboard");
	}

	if (App.lpDIJoystick)
	{
		DX_TRY(App.lpDIJoystick->Unacquire());
		DXRelease(App.lpDIJoystick, "Joystick");
	}

	DXRelease(App.lpDI, "DirectInput");
}

bool WinRunCheck(LPCSTR lpName, LPCSTR lpClassName, HANDLE* mutex)// (F)
{
	Log(LT_Enter, "WinRunCheck");

	*mutex = CreateMutexA(nullptr, true, lpName);

	if (GetLastError() != ERROR_ALREADY_EXISTS)
		return false;

	HWND wnd = FindWindowA(lpClassName, lpName);

	if (wnd)
		SendMessageA(wnd, WM_ACTIVATE, 0, 0);

	return true;
}

void WinProcessCommandLine(LPSTR lpCmdLine)
{
	Log(LT_Enter, "WinProcessCommandLine");

	Unimpl();
}

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)// (F)
{
	int RetVal;
	int n;

	appsettings.OpenSetup = false;

	memset(&App, 0, sizeof(WINAPP));

	App.GameInitialized = false;

	DB_InitLog(1);

	HWND dblog = FindWindowA("DBLogWindowClass", "DBLog Server");
	if (dblog)
		PostMessageA(dblog, dbm_command, 2, 0);

	dblog = FindWindowA("DBLogWindowClass", "DBLog Server");
	if (dblog)
		PostMessageA(dblog, dbm_clearlog, 0, 0);

	DB_DefType("Error", 0xFF, 1);
	DB_DefType("Function", 0x8000, 0);
	DB_DefType("DirectX Information", 0x802040, 1);
	DB_DefType("Object Release", 0x80, 0);
	DB_DefType("General Information", 0x800000, 1);
	DB_DefType("Windows Message", 0x800080, 0);
	DB_DefType("Level Info", 0x8000FF, 0);
	DB_DefType("Sound", 0x8080, 0);

	Log(LT_Info, "Launching - %s", WINDOWNAME);
	Log(LT_Enter, "WinMain");

	if (WinRunCheck(WINDOWNAME, WINDOWCLASS, &App.hObject))
		return false;

	FindCdDrive();
	LoadGameflow();
	WinProcessCommandLine(lpCmdLine);

	App.hInstance = hInstance;
	App.WindowClass.hIcon = nullptr;
	App.WindowClass.lpszMenuName = nullptr;
	App.WindowClass.lpszClassName = WINDOWCLASS;
	App.WindowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
	App.WindowClass.hInstance = hInstance;
	App.WindowClass.style = CS_VREDRAW | CS_HREDRAW;
	App.WindowClass.lpfnWndProc = WinAppProc;
	App.WindowClass.cbClsExtra = 0;
	App.WindowClass.cbWndExtra = 0;
	App.WindowClass.hCursor = LoadCursor(App.hInstance, IDC_ARROW);

	if (!RegisterClass(&App.WindowClass))
	{
		Log(LT_Error, "Unable To Register Window Class");
		return false;
	}

	RECT Rect;

	Rect.left = 0;
	Rect.top = 0;
	Rect.right = 640;
	Rect.bottom = 480;

	AdjustWindowRect(&Rect, WS_CAPTION, false);

	App.WindowHandle = CreateWindowEx(
			WS_THICKFRAME,
			WINDOWCLASS,
			WINDOWNAME,
			WS_BORDER,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			Rect.right - Rect.left,
			Rect.bottom - Rect.top,
			nullptr,
			nullptr,
			App.hInstance,
			nullptr
	);

	if (!App.WindowHandle)
	{
		Log(LT_Error, "Unable To Create Window");
		return FALSE;
	}

	DXInitialise(&App.DeviceInfo, App.WindowHandle);

	if (appsettings.OpenSetup || !LoadSettings())
	{
		if (!InitSetupDialog())
		{
			free(gfScriptFile);
			free(gfStringOffset);
			WinClose();
			return 0;
		}

		LoadSettings();
	}

	uint32_t thread_id;
	hThread = (HANDLE)_beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);

	thread_started = true;

	WinProcMsg();

	while (game_running);

	WinClose();

	//App.DXConfig.nD3D = 0; // todo: temporary fix because of lack of software renderer

	if (!DXCreate(
			CUR_DM.w,
			CUR_DM.h,
			CUR_DM.bpp,
			App.orig_flags,
			&App,
			App.WindowHandle,
			WS_CAPTION))
	{
		MessageBoxA(nullptr, &gfStringWad[gfStringOffset[STR_FAILED_TO_SETUP_DIRECTX]], "Tomb Raider", 0);
		return false;
	}

	ShowBumpInfo();

	UpdateWindow(App.WindowHandle);
	ShowWindow(App.WindowHandle, nCmdShow);

	if (App.Flags & WA_FULLSCREEN)
	{
		SetCursor(nullptr);
		ShowCursor(false);
	}

	DXCreateDirectInput(App.WindowHandle, hInstance);

	App.hAccTable = LoadAcceleratorsA(hInstance, (LPCSTR) 0x65);

	if (!App.tDisableSound)
	{
		DXDSCreate();
		InitACM();
	}

	game_running = true;
	thread_started = false;

	uint32_t thread_id;
	hThread = (HANDLE) _beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);

	WinProcMsg();

	thread_started = true;

	while (game_running);

	WinClose();

	HWND desktop = GetDesktopWindow();
	ReleaseDC(desktop, GetDC(desktop));

	DEVMODEA dm;
	dm.dmSize = sizeof(dm);
	dm.dmBitsPerPel = App.OriginalBPP;
	dm.dmFields = DM_BITSPERPEL;
	ChangeDisplaySettingsA(&dm, 0);

	dblog = FindWindowA("DBLogWindowClass", "DBLog Server");
	if (dblog)
		PostMessageA(dblog, dbm_command, 4, 0);

	return 0;
}

void HandleCommand(WORD param)// (F)
{
	if (param == IDR_VKRETURN)
	{
		if (!App.PlayingFMV && CUR_DD.DDCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED && !levelLoading)
		{
			Log(LT_WindowMessage, "KA_ALTENTER");

			Log(LT_Info, "HangGameThread");

			while (App.isInScene);

			App.bNoFocus = true;

			while (!App.isInScene);

			SuspendThread(hThread);

			Log(LT_Info, "Game Thread Suspended");

			FreeD3DLights();
			DXToggleFullScreen();
			HWInitialise();
			//
			S_InitD3DMatrix();
			SetD3DViewMatrix();

			ResumeThread(hThread);

			App.bNoFocus = false;

			Log(LT_Info, "Game Thread Resumed");

			if (App.Flags & WA_FULLSCREEN)
			{
				SetCursor(nullptr);
				ShowCursor(false);
			}
			else
			{
				SetCursor(LoadCursor(App.hInstance, IDC_ARROW));
				ShowCursor(true);
			}
		}
	}
	else if ((param == IDR_VKADD || param == IDR_VKSUBTRACT) && !levelLoading && !App.PlayingFMV)
	{
		Log(LT_Info, "Change Video Mode");

		Log(LT_Info, "HangGameThread");

		if (App.isInScene)
			WaitUntilFalse(&App.isInScene);

		App.bNoFocus = true;

		if (!App.isInScene)
			WaitUntilTrue(&App.isInScene);

		SuspendThread(hThread);

		Log(LT_Info, "Game Thread Suspended");

		int old = App.DXConfig.nVMode;

		if (param == IDR_VKADD)
		{
			App.DXConfig.nVMode = MIN(App.DXConfig.nVMode + 1, CUR_D3D.nDisplayMode - 1);

			if (GET_DM(old).bpp != CUR_DM.bpp)
			{
				for (; App.DXConfig.nVMode < CUR_D3D.nDisplayMode; App.DXConfig.nVMode++)
				{
					if (GET_DM(old).bpp == CUR_DM.bpp)
					{
						break;
					}
				}

				if (App.DXConfig.nVMode == CUR_D3D.nDisplayMode)
				{
					App.DXConfig.nVMode = old;
				}
			}
		}
		else
		{
			App.DXConfig.nVMode = MAX(App.DXConfig.nVMode - 1, 0);

			if (GET_DM(old).bpp != CUR_DM.bpp)
			{
				for (; App.DXConfig.nVMode >= 0; App.DXConfig.nVMode--)
				{
					if (GET_DM(old).bpp == CUR_DM.bpp)
					{
						break;
					}
				}

				if (App.DXConfig.nVMode == -1)
				{
					App.DXConfig.nVMode = old;
				}
			}
		}

		if (App.DXConfig.nVMode != old)
		{
			FreeD3DLights();

			if (!DXChangeVideoMode())
			{
				App.DXConfig.nVMode = old;
				DXChangeVideoMode();
			}

			HWInitialise();
			//
			InitWindow(0, 0, App.width, App.height, 20, SECTOR(20), 80);
			InitFont();
			S_InitD3DMatrix();
			SetD3DViewMatrix();
		}

		ResumeThread(hThread);

		App.bNoFocus = false;

		Log(LT_Info, "Game Thread Resumed");

		//
	}
}

void HandleApp(LPARAM lParam, WPARAM wParam)
{
	byte_57A01C = true;

	if (!acm_file_stream)
	{
		byte_57A01C = false;
		byte_579FE4 = false;
		return;
	}

	if (wParam != (WPARAM) XATrack || wParam == 0xFFFFFFFF)
	{
		Log(LT_Default, "Not Current Track %d", wParam);
		byte_57A01C = false;
		byte_579FE4 = false;
		return;
	}

	memset((void*) lParam, 0, 22528);
	fread((void*) lParam, 1, 22528, acm_file_stream);

	if (acm_file_stream && feof(acm_file_stream))
	{
		byte_57A01C = false;

		if (acm_playing_mode == 1)
		{
			fseek(acm_file_stream, 90, 0);

			byte_579FE4 = true;
		}
		else
		{
			if (++dword_57A018 <= 8)
			{
				byte_579FE4 = true;
			}
			else
			{
				dword_57A018 = 0;

				if (acm_playing_mode == 2)
				{
					byte_579FE4 = false;
					S_CDStop();
				}
				else
				{
					if (CurrentAtmosphere == 0 || IsAtmospherePlaying)
					{
						byte_579FE4 = true;
					}
					else
					{
						byte_579FE4 = false;
						S_CDStop();
						S_CDPlay(CurrentAtmosphere, 1);
					}
				}
			}
		}
	}
	else
	{
		byte_57A01C = false;
		byte_579FE4 = true;
	}
}

HMODULE GetKernel32()// (F)
{
	return GetModuleHandleA("kernel32.dll");
}

void* FindSleepAddress(HMODULE kernel)// (F)
{
	return GetProcAddress(kernel, "Sleep");
}

void* GetSleepFunc()// (F)
{
	return FindSleepAddress(GetKernel32());
}

void Sleep1ms()// (F)
{
	((void (__stdcall*)(DWORD)) GetSleepFunc())(1);
}

void WaitUntilFalse(DWORD* ptr)// (F)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfor-loop-analysis"
	do
	{
		Sleep1ms();
	} while (*ptr);
#pragma clang diagnostic pop
}

void WaitUntilTrue(DWORD* ptr)// (F)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfor-loop-analysis"
	do
	{
		Sleep1ms();
	} while (!*ptr);
#pragma clang diagnostic pop
}

/*
Function : AppWinProc
Useage   : Application Window Procedure
*/

long FAR PASCAL WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
		case WM_CLOSE:
			Log(LT_WindowMessage, "WM_CLOSE");
			// TODO TODO TODO TODO TODO
			PostQuitMessage(EXIT_SUCCESS);

			game_running = false;
			break;

		case WM_CREATE:
			// todo todo todo
			Log(LT_WindowMessage, "WM_CREATE");
			break;

		case WM_MOVE:
			Log(LT_WindowMessage, "WM_MOVE");
			DXMove(LOWORD(lParam), HIWORD(lParam));
			break;

		case WM_COMMAND:
			Log(LT_WindowMessage, "WM_COMMAND");
			HandleCommand(LOWORD(wParam));
			break;

		case WM_MOUSEMOVE:
			mouse_x = GET_X_LPARAM(lParam);
			mouse_y = GET_Y_LPARAM(lParam);
			mouse_vkeys = (int) wParam;
			break;

		case WM_APP:
			HandleApp(lParam, wParam);
			return 0;

			/*case WM_CHAR:
				//		KeyToConsole(wParam);
				break;


			case WM_KEYDOWN:
				switch (wParam)
				{
				case VK_F1:
					//			ToggleConsole();
					break;
				}
				break;

			case WM_KEYUP:
				break;*/


		case WM_ACTIVATE:
			Log(LT_WindowMessage, "WM_ACTIVATE");

			if (!App.PlayingFMV)
			{
				switch (LOWORD(wParam))
				{
					case WA_ACTIVE:
					case WA_CLICKACTIVE:
						Log(LT_WindowMessage, "WM_ACTIVE");

						if (App.GameInitialized)
						{
							AcquireInput(true);
							ResumeThread(hThread);

							App.bNoFocus = false;

							Log(LT_Info, "Game Thread Resumed");
						}
						break;

					case WA_INACTIVE:
						Log(LT_WindowMessage, "WM_INACTIVE");

						if (App.GameInitialized)
						{
							AcquireInput(false);

							Log(LT_Info, "HangGameThread");

							if (App.isInScene)
								WaitUntilFalse(&App.isInScene);

							App.bNoFocus = true;

							if (!App.isInScene)
								WaitUntilTrue(&App.isInScene);

							SuspendThread(hThread);

							Log(LT_Info, "Game Thread Suspended");
						}
						break;
				}
			}
			return 0;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}


void ShowBumpInfo()
{
	if (CUR_D3D.DeviceDesc.dwTextureOpCaps & (D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
	{
		if (CUR_D3D.DeviceDesc.wMaxTextureBlendStages >= 3)
		{
			//App.lpD3DDevice->EnumTextureFormats(nullptr, nullptr);
/*
            if (false)
            {
                Log(LT_Info, "Bump bit count 0x%X", BumpBitCount);
                Log(LT_Info, "Bump DU %X", BumpDU);
                Log(LT_Info, "Bump DV %X", BumpDV);
            }
        */
		}
	}
}

float WinFrameRate()// (F)
{
	static int last_time = clock();

	if (++App.fps_counter == 10)
	{
		time_t this_time = clock();
		double t = (this_time - last_time) / (double) CLOCKS_PER_SEC;
		last_time = this_time;
		App.fps_static = App.fps_counter / t;
		App.fps_counter = 0;
	}

	App.fps = App.fps_static;

	return App.fps;
}

void WinDisplayString(int x, int y, const char* String, ...)// (F)
{
	va_list argptr;
	char msg[4096];
			va_start(argptr, String);
	vsprintf(msg, String, argptr);
			va_end(argptr);
	PrintString(x, y, 6, msg, 0);
}
<MSG> work ongoing, game loop works iojafoiqhsfpiheo

<DFF> @@ -206,10 +206,10 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
 	uint32_t thread_id;
 	hThread = (HANDLE)_beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);
 
-	thread_started = true;
-
 	WinProcMsg();
 
+	thread_started = true;
+
 	while (game_running);
 
 	WinClose();

{'commit': 'diff --git a/GAME/CAMERA.C b/GAME/CAMERA.C\nindex cbc6e6bb..621a1799 100644\n--- a/GAME/CAMERA.C\n+++ b/GAME/CAMERA.C\n@@ -40,7 +40,7 @@\n \n long BinocularRange;\n long BinocularOn;\n-long BinocularOldCamera;\n+enum camera_type BinocularOldCamera;\n long LaserSight;\n long InfraRed;\n char SniperCount;\ndiff --git a/GAME/CAMERA.H b/GAME/CAMERA.H\nindex 610a4280..03c91140 100644\n--- a/GAME/CAMERA.H\n+++ b/GAME/CAMERA.H\n@@ -12,7 +12,7 @@ enum camera_flags\n \n extern long BinocularRange;\n extern long BinocularOn;\n-extern long BinocularOldCamera;\n+extern enum camera_type BinocularOldCamera;\n extern long LaserSight;\n extern long InfraRed;\n extern char SniperCount;\ndiff --git a/GAME/CONTROL.C b/GAME/CONTROL.C\nindex 247da8d1..3fd8d9dd 100644\n--- a/GAME/CONTROL.C\n+++ b/GAME/CONTROL.C\n@@ -18,6 +18,7 @@\n \t#include "FILE.H"\n #include "GLOBAL.H"\n #include "SPECIFIC.H"\n+#include "INPUT.H"\n #endif\n #include "GAMEFLOW.H"\n #if PSX_VERSION || PSXPC_VERSION\n@@ -53,6 +54,7 @@\n \n #include <assert.h>\n #include <string.h>\n+#include "LARAMISC.H"\n \n #define MAX_FRAMES 10\n \n@@ -264,9 +266,94 @@ BYTE byte_86BBA3 = 0;\n \n char byte_A3660;\n \n+#if PC_VERSION\n+void UpdateSparks()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateFireSparks()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateSmokeSparks()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateBubbles()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateSplashes()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateDebris()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateBlood()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateDrips()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateGunShells()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateRats()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateBats()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateShockwaves()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateLightning()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdateTwogunLasers()\n+{\n+\tUnimpl();\n+}\n+\n+void UpdatePulseColour()\n+{\n+\tUnimpl();\n+}\n+\n+void KlaxonTremor()\n+{\n+\tUnimpl();\n+}\n+\n+#endif\n+\n long ControlPhase(long nframes, int demo_mode)//1D538(<), 1D6CC(<) //DO NOT TOUCH (PSX/PSXPC)\n {\n #if PC_VERSION\n+\tS_Warn("PC CONTROLPHASE %d %d", nframes, demo_mode);\n+\n \tRegeneratePickups();\n \n \tif (nframes > MAX_FRAMES)\n@@ -362,13 +449,14 @@ long ControlPhase(long nframes, int demo_mode)//1D538(<), 1D6CC(<) //DO NOT TOUC\n \t\t\t|| SniperCamActive\n \t\t\t|| bUseSpotCam\n \t\t\t|| bTrackCamInit\n-\t\t\t|| ((lara_item->current_anim_state != STATE_LARA_STOP || lara_item->anim_number != ANIMATION_LARA_STAY_IDLE)\n-\t\t\t&& (!lara.IsDucked\n-\t\t\t\t|| input & IN_CROUCH\n-\t\t\t\t|| lara_item->anim_number != ANIMATION_LARA_CROUCH_IDLE\n-\t\t\t\t|| lara_item->goal_anim_state != STATE_LARA_CROUCH_IDLE)))\n+\t\t\t|| \n+\t\t\t((lara_item->current_anim_state != STATE_LARA_STOP || lara_item->anim_number != ANIMATION_LARA_STAY_IDLE)\n+\t\t\t\t&& (!lara.IsDucked\n+\t\t\t\t\t|| input & IN_CROUCH\n+\t\t\t\t\t|| lara_item->anim_number != ANIMATION_LARA_CROUCH_IDLE\n+\t\t\t\t\t|| lara_item->goal_anim_state != STATE_LARA_CROUCH_IDLE)))\n \t\t{\n-\t\t\tif (!BinocularRange)\n+\t\t\tif (BinocularRange == 0)\n \t\t\t{\n \t\t\t\tif (SniperCamActive\n \t\t\t\t\t|| bUseSpotCam\n@@ -376,39 +464,300 @@ long ControlPhase(long nframes, int demo_mode)//1D538(<), 1D6CC(<) //DO NOT TOUC\n \t\t\t\t{\n \t\t\t\t\tinput &= ~IN_LOOK;\n \t\t\t\t}\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tif (LaserSight)\n+\t\t\t\t{\n+\t\t\t\t\tBinocularRange = 0;\n+\t\t\t\t\tLaserSight = 0;\n+\t\t\t\t\tAlterFOV(ANGLE(80));\n+\t\t\t\t\tlara_item->mesh_bits = 0xFFFFFFFF;\n+\t\t\t\t\tlara.IsDucked = FALSE;\n+\t\t\t\t\tcamera.type = BinocularOldCamera;\n+\n+\t\t\t\t\tlara.head_y_rot = 0;\n+\t\t\t\t\tlara.head_x_rot = 0;\n+\n+\t\t\t\t\tlara.torso_y_rot = 0;\n+\t\t\t\t\tlara.torso_x_rot = 0;\n \n-\t\t\t\t// GOTO\n+\t\t\t\t\tcamera.bounce = 0;\n+\t\t\t\t\tBinocularOn = -8;\n+\t\t\t\t\tinput &= ~IN_LOOK;\n+\t\t\t\t}\n+\t\t\t\telse\n+\t\t\t\t{\n+\t\t\t\t\tinput |= IN_LOOK;\n+\t\t\t\t}\n \t\t\t}\n \n+\t\t\tInfraRed = FALSE;\n+\t\t}\n+\t\telse if (BinocularRange == 0)\n+\t\t{\n+\t\t\tif (lara.gun_status == LG_READY\n+\t\t\t\t&& ((lara.gun_type == WEAPON_REVOLVER && lara.sixshooter_type_carried & WTYPE_LASERSIGHT)\n+\t\t\t\t\t|| (lara.gun_type == WEAPON_HK)\n+\t\t\t\t\t|| (lara.gun_type == WEAPON_CROSSBOW && lara.crossbow_type_carried & WTYPE_LASERSIGHT)))\n+\t\t\t{\n+\t\t\t\tBinocularRange = 128;\n+\t\t\t\tBinocularOldCamera = camera.old_type;\n+\n+\t\t\t\tlara.Busy = TRUE;\n+\t\t\t\tLaserSight = TRUE;\n+\n+\t\t\t\tif (!(gfLevelFlags & GF_LVOP_TRAIN))\n+\t\t\t\t\tInfraRed = TRUE;\n+\t\t\t\telse\n+\t\t\t\t\tInfraRed = FALSE;\n+\t\t\t}\n+\t\t\telse\n+\t\t\t\tInfraRed = FALSE;\n+\t\t}\n+\t\telse\n+\t\t{\n \t\t\tif (LaserSight)\n \t\t\t{\n-\t\t\t\tBinocularRange = 0;\n-\t\t\t\tLaserSight = 0;\n-\t\t\t\tAlterFOV(ANGLE(80));\n-\t\t\t\tlara_item->mesh_bits = -1;\n-\t\t\t\tlara.IsDucked = FALSE;\n-\t\t\t\tcamera.type = BinocularOldCamera;\n-\n-\t\t\t\tlara.head_y_rot = 0;\n-\t\t\t\tlara.head_x_rot = 0;\n-\n-\t\t\t\tlara.torso_y_rot = 0;\n-\t\t\t\tlara.torso_x_rot = 0;\n-\n-\t\t\t\tcamera.bounce = 0;\n-\t\t\t\tBinocularOn = -8;\n-\t\t\t\tinput &= ~IN_LOOK;\n+\t\t\t\tif (!(gfLevelFlags & GF_LVOP_TRAIN))\n+\t\t\t\t\tInfraRed = TRUE;\n+\t\t\t\telse\n+\t\t\t\t\tInfraRed = FALSE;\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tif ((gfLevelFlags & GF_LVOP_TRAIN) && (inputBusy & IN_ACTION))\n+\t\t\t\t\tInfraRed = TRUE;\n+\t\t\t\telse\n+\t\t\t\t\tInfraRed = FALSE;\n+\t\t\t}\n+\t\t}\n+\n+\t\tClearDynamics();\n+\t\tClearFires();\n+\n+\t\tGotLaraSpheres = FALSE;\n+\t\tInItemControlLoop = TRUE;\n+\n+\t\tshort item_num = next_item_active;\n+\t\twhile (item_num != -1)\n+\t\t{\n+\t\t\tstruct ITEM_INFO* item = &items[item_num];\n+\t\t\tshort nex = item->next_active;\n+\n+\t\t\tif (item->after_death < 128)\n+\t\t\t{\n+\t\t\t\tif (objects[item->object_number].control)\n+\t\t\t\t\tobjects[item->object_number].control(item_num);\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tKillItem(item_num);\n+\t\t\t}\n+\n+\t\t\titem_num = nex;\n+\t\t}\n+\n+\t\tInItemControlLoop = FALSE;\n+\n+\t\tKillMoveItems();\n+\n+\t\tInItemControlLoop = TRUE;\n+\n+\t\tshort fx_num = next_fx_active;\n+\t\twhile (fx_num != -1)\n+\t\t{\n+\t\t\tstruct FX_INFO* fx = &effects[fx_num];\n+\t\t\tshort nex = fx->next_active;\n+\n+\t\t\tif (objects[fx->object_number].control)\n+\t\t\t\tobjects[fx->object_number].control(fx_num);\n+\n+\t\t\tfx_num = nex;\n+\t\t}\n+\n+\t\tInItemControlLoop = FALSE;\n+\n+\t\tKillMoveEffects();\n+\n+\t\tif (KillEverythingFlag)\n+\t\t\tKillEverything();\n+\n+\t\tif (SmokeCountL != 0)\n+\t\t\tSmokeCountL--;\n+\n+\t\tif (SmokeCountR != 0)\n+\t\t\tSmokeCountR--;\n+\n+\t\tif (SplashCount != 0)\n+\t\t\tSplashCount--;\n+\n+\t\tif (WeaponDelay != 0)\n+\t\t\tWeaponDelay--;\n+\n+\t\tif (lara.has_fired && !(wibble & 0x7F))\n+\t\t{\n+\t\t\tAlertNearbyGuards(lara_item);\n+\t\t\tlara.has_fired = FALSE;\n+\t\t}\n+\n+\t\tXSoff1 += 150;\n+\t\tYSoff1 += 230;\n+\t\tZSoff1 += 660;\n+\n+\t\tXSoff2 += 270;\n+\t\tYSoff2 += 440;\n+\t\tZSoff2 += 160;\n+\n+\t\tif (lara.poisoned != 0 && !GLOBAL_playing_cutseq)\n+\t\t{\n+\t\t\tif (lara.poisoned <= 4096)\n+\t\t\t{\n+\t\t\t\tif (lara.dpoisoned)\n+\t\t\t\t\tlara.dpoisoned++;\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tlara.poisoned = 4096;\n+\t\t\t}\n+\n+\t\t\tif (gfLevelFlags & GF_LVOP_TRAIN && !lara.Gassed)\n+\t\t\t{\n+\t\t\t\tif (lara.dpoisoned != 0)\n+\t\t\t\t{\n+\t\t\t\t\tlara.dpoisoned -= 8;\n+\n+\t\t\t\t\tif (lara.dpoisoned < 0)\n+\t\t\t\t\t\tlara.dpoisoned = 0;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (lara.poisoned >= 256 && !(wibble & 0xFF))\n+\t\t\t{\n+\t\t\t\tlara_item->hit_points -= lara.poisoned >> (8 - lara.Gassed);\n+\t\t\t\tPoisonFlag = 16;\n+\t\t\t}\n+\t\t}\n+\n+\t\tlara.skelebob = 0;\n+\n+\t\tInItemControlLoop = TRUE;\n+\n+\t\tif (!GLOBAL_playing_cutseq && !gfGameMode)\n+\t\t{\n+\t\t\tlara.Fired = FALSE;\n+\n+\t\t\tLaraControl(0);\n+\n+\t\t\tif (LaraDrawType == LARA_DIVESUIT)\n+\t\t\t\tDoSubsuitStuff();\n+\t\t}\n+\n+\t\tInItemControlLoop = FALSE;\n+\n+\t\tKillMoveItems();\n+\n+\t\tif (gfLevelFlags & GF_LVOP_TRAIN && !bUseSpotCam)\n+\t\t{\n+\t\t\tif (room[lara_item->room_number].FlipNumber > 10)\n+\t\t\t{\n+\t\t\t\tInitialiseSpotCam(room[lara_item->room_number].FlipNumber);\n+\t\t\t\tbUseSpotCam = TRUE;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (GLOBAL_inventoryitemchosen != -1)\n+\t\t{\n+\t\t\tSayNo();\n+\n+\t\t\tGLOBAL_inventoryitemchosen = -1;\n+\t\t}\n+\n+\t\tif (GLOBAL_playing_cutseq)\n+\t\t{\n+\t\t\tcamera.type = CINEMATIC_CAMERA;\n+\t\t\tCalculateCamera();\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\tif (LaraDrawType != LARA_DIVESUIT)\n+\t\t\t{\n+\t\t\t\tHairControl(0, 0, 0);\n+\n+\t\t\t\tif (gfLevelFlags & GF_LVOP_YOUNG_LARA)\n+\t\t\t\t\tHairControl(0, 1, 0);\n+\t\t\t}\n+\n+\t\t\tif (!bUseSpotCam)\n+\t\t\t{\n+\t\t\t\tbTrackCamInit = FALSE;\n+\t\t\t\tCalculateCamera();\n \t\t\t}\n \t\t\telse\n \t\t\t{\n-\t\t\t\tinput |= IN_LOOK;\n+\t\t\t\tCalculateSpotCams();\n \t\t\t}\n+\t\t}\n+\n+\t\tCamRot.vy = (mGetAngle(camera.pos.z, camera.pos.x, camera.target.z, camera.target.x) >> 4) & 0xFFF;\n+\t\twibble = (wibble + 4) & 0xFC;\n+\t\tTriggerLaraDrips();\n+\n+\t\twhile (SmashedMeshCount != 0)\n+\t\t{\n+\t\t\tSmashedMeshCount--;\n \n-\t\t\t//if (input & I)\n+\t\t\tstruct MESH_INFO* mesh = SmashedMesh[SmashedMeshCount];\n+\t\t\tstruct FLOOR_INFO* floor = GetFloor(mesh->x, mesh->y, mesh->z, &SmashedMeshRoom[SmashedMeshCount]);\n+\n+\t\t\tGetHeight(floor, mesh->x, mesh->y, mesh->z);\n+\t\t\tTestTriggers(trigger_index, 1, 0);\n+\n+\t\t\tfloor->stopper = FALSE;\n+\n+\t\t\tSmashedMesh[SmashedMeshCount] = NULL;\n \t\t}\n+\n+\t\tUpdateSparks();\n+\t\tUpdateFireSparks();\n+\t\tUpdateSmokeSparks();\n+\t\tUpdateBubbles();\n+\t\tUpdateSplashes();\n+\t\tUpdateDebris();\n+\t\tUpdateBlood();\n+\t\tUpdateDrips();\n+\t\tUpdateGunShells();\n+\t\tUpdateRats();\n+\t\tUpdateBats();\n+\t\tUpdateSpiders();\n+\t\tUpdateShockwaves();\n+\t\tUpdateLightning();\n+\t\tUpdateTwogunLasers();\n+\t\tAnimateWaterfalls();\n+\t\tUpdatePulseColour();\n+\n+\t\tif (gfCurrentLevel == LVL5_SINKING_SUBMARINE)\n+\t\t\tKlaxonTremor();\n+\n+\t\tSoundEffects();\n+\n+\t\thealth_bar_timer--;\n+\n+\t\tif (gfGameMode == 0)\n+\t\t{\n+\t\t\tGameTimer++;\n+\n+\t\t\tif (savegame.Level.Timer != 0)\n+\t\t\t{\n+\t\t\t\tif (!GLOBAL_playing_cutseq)\n+\t\t\t\t\tsavegame.Level.Timer++;\n+\t\t\t}\n+\t\t}\n+\n+\t\tUpdateFadeClip();\n \t}\n \n-\tS_Warn("[ControlPhase] - Unimplemented!\\n");\n+\treturn 0;\n #else\n \tshort item_num;\n \tshort nex;\ndiff --git a/GAME/GAMEFLOW.C b/GAME/GAMEFLOW.C\nindex 542d3aff..ee831c8b 100644\n--- a/GAME/GAMEFLOW.C\n+++ b/GAME/GAMEFLOW.C\n@@ -522,19 +522,22 @@ void QuickControlPhase()//10274(<), 10264(<) (F)\n \n void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n {\n-#if PC_VERSION\n+/*#if PC_VERSION\n \tS_Warn("DoTitle PC");\n+\tgfCurrentLevel = LVL5_STREETS_OF_ROME;\n \tDoLevel(LVL5_STREETS_OF_ROME, Audio);\n \n \treturn;\n-#endif\n+#endif*/\n \n \tint i;\n \n \tCreditsDone = 0;\n \tCanLoad = 0;\n \n-#if !PC_VERSION\n+#if PC_VERSION\n+\tSetFade(255, 0);\n+#else\n \tif (Gameflow->LoadSaveEnabled)\n \t{\n \t\tmcOpen(1);\n@@ -565,6 +568,10 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n #if PC_VERSION\n \tInitialiseFXArray(1);\n \tInitialiseLOTarray(1);\n+\n+\t// TODO fog\n+\n+\tClearFXFogBulbs();\n #endif\n \n \tInitialisePickUpDisplay();\n@@ -573,6 +580,10 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \tphd_InitWindow(90);\n #endif\n \n+#if PC_VERSION\n+\tS_InitialiseScreen();\n+#endif\n+\n \tSOUND_Stop();\n \n \tIsAtmospherePlaying = 0;\n@@ -588,6 +599,10 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \t\tScreenFadedOut = 1;\n \t\tScreenFade = 255;\n \t\tdScreenFade = 255;\n+\n+#if PC_VERSION\n+\t\tS_CDPlay(CDA_XA14_ECREDITS, 1);\n+#endif\n \t}\n \telse\n \t{\n@@ -620,9 +635,21 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \n \tJustLoaded = 0;\n \t\n-#if !PC_VERSION\n-\tif (gfStatus == 0)\n+#if PC_VERSION\n+\twhile (gfStatus == 0)\n \t{\n+\t\tGPU_BeginScene();\n+\t\tSkyDrawPhase();\n+\t\tgfStatus = TitleOptions();\n+\t\tif (gfStatus != 0)\n+\t\t\tbreak;\n+\t\thandle_cutseq_triggering(Name);\n+\t\tnframes = DrawPhaseGame();\n+\t\tgfStatus = ControlPhase(nframes, 0);\n+\t\tDoSpecialFeaturesServer();\n+\t}\n+#else\n+\t\n \t\t//loc_107BC, 10778\n \t\twhile (gfStatus == 0)\n \t\t{\n@@ -728,7 +755,7 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \n \t\t\t}//loc_10A14\n \t\t}\n-\t}\n+\t\n \t\n \t//loc_10A24\n #if PSX_VERSION || PSXPC_VERSION\n@@ -746,6 +773,7 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \t{\n \t\tXAReqVolume = 0;\n \t}\n+#endif\n #endif\n \n \tNoInput = 0;\n@@ -753,8 +781,10 @@ void DoTitle(unsigned char Name, unsigned char Audio)//10604(<), 105C4(<)\n \tS_CDStop();\n \tbUseSpotCam = 0;\n \tbDisableLaraControl = 0;\n-\tinput = 0;\n-#endif\n+\n+\tif (gfStatus != 4)\n+\t\tinput = 0;\n+\n }\n \n void DoLevel(unsigned char Name, unsigned char Audio)//10ABC(<) 10A84(<) (F)\n@@ -903,32 +933,30 @@ void DoLevel(unsigned char Name, unsigned char Audio)//10ABC(<) 10A84(<) (F)\n \tdbinput = 0;\n \tJustLoaded = 0;\n \n-\tif (gfStatus == 0)\n+\t//loc_10D30\n+\twhile (gfStatus == 0)\n \t{\n-\t\t//loc_10D30\n-\t\twhile (gfStatus == 0)\n-\t\t{\n \n-\t\t\tGPU_BeginScene();\n+\t\tGPU_BeginScene();\n \n-\t\t\tif (gfLegendTime != 0 && DestFadeScreenHeight == 0 && FadeScreenHeight == 0 && cutseq_num == 0)\n-\t\t\t{\n-\t\t\t\tPrintString(0x100, 0xE8, 2, &gfStringWad[gfStringOffset[gfLegend]], 0x8000);\n-\t\t\t\tgfLegendTime--;\n-\t\t\t}\n+\t\tif (gfLegendTime != 0 && DestFadeScreenHeight == 0 && FadeScreenHeight == 0 && cutseq_num == 0)\n+\t\t{\n+\t\t\tPrintString(0x100, 0xE8, 2, &gfStringWad[gfStringOffset[gfLegend]], 0x8000);\n+\t\t\tgfLegendTime--;\n+\t\t}\n \n-\t\t\t//loc_10DC4\n-\t\t\tnframes = DrawPhaseGame();\n-\t\t\thandle_cutseq_triggering(Name);\n+\t\t//loc_10DC4\n+\t\tnframes = DrawPhaseGame();\n+\t\thandle_cutseq_triggering(Name);\n \n-\t\t\tif (DEL_playingamefmv != 0)\n-\t\t\t{\n-\t\t\t\tDEL_playingamefmv = 0;\n-\t\t\t}\n+\t\tif (DEL_playingamefmv != 0)\n+\t\t{\n+\t\t\tDEL_playingamefmv = 0;\n+\t\t}\n \n-\t\t\t//loc_10DEC\n-\t\t\tif (gfLevelComplete == 0)\n-\t\t\t{\n+\t\t//loc_10DEC\n+\t\tif (gfLevelComplete == 0)\n+\t\t{\n #if PSX_VERSION\n \t\t\t\tif (dbinput & 0x100 && GLOBAL_enterinventory != -1)\n \t\t\t\t{\n@@ -944,17 +972,16 @@ void DoLevel(unsigned char Name, unsigned char Audio)//10ABC(<) 10A84(<) (F)\n \t\t\t\t}\n #endif\n \n-\t\t\t\t//loc_10E7C\n-\t\t\t\tQuickControlPhase();\n-\t\t\t}\n-\t\t\telse\n-\t\t\t{\n+\t\t\t//loc_10E7C\n+\t\t\tQuickControlPhase();\n+\t\t}\n+\t\telse\n+\t\t{\n #if PSXENGINE\n \t\t\t\t//loc_10CAC\n \t\t\t\tgfStatus = 3;\n #endif\n-\t\t\t\tbreak;\n-\t\t\t}\n+\t\t\tbreak;\n \t\t}\n \t}\n \n@@ -1037,7 +1064,13 @@ void DoLevel(unsigned char Name, unsigned char Audio)//10ABC(<) 10A84(<) (F)\n \treset_flag = 0;\n }\n \n-void TitleOptions()\n+int TitleOptions()\n {\n+\tS_Warn("[TitleOptions] - Unimplemented!\\n");\n+\treturn 0;\n+}\n \n+void DoSpecialFeaturesServer()\n+{\n+\tS_Warn("[DoSpecialFeaturesServer] - Unimplemented!\\n");\n }\n\\ No newline at end of file\ndiff --git a/GAME/GAMEFLOW.H b/GAME/GAMEFLOW.H\nindex e5ea4bb3..5e30b637 100644\n--- a/GAME/GAMEFLOW.H\n+++ b/GAME/GAMEFLOW.H\n@@ -8,6 +8,8 @@ extern void LoadGameflow();\n extern void QuickControlPhase();\n extern void DoTitle(unsigned char Name, unsigned char Audio);\n extern void DoLevel(unsigned char Name, unsigned char Audio);\n+extern int TitleOptions();\n+extern void DoSpecialFeaturesServer();\n \n enum gf_languages\n {\ndiff --git a/GAME/SPOTCAM.C b/GAME/SPOTCAM.C\nindex c6735239..1ebee110 100644\n--- a/GAME/SPOTCAM.C\n+++ b/GAME/SPOTCAM.C\n@@ -426,7 +426,7 @@ void InitialiseSpotCam(short Sequence)//37648, 37B48 (F)\n \n void CalculateSpotCams()//37ED0(<), ? \n {\n-#if 1\n+#if !PC_VERSION\n \tlong cpx; // stack offset -96\n \tlong cpy; // stack offset -92\n \tlong cpz; // stack offset -88\ndiff --git a/SPEC_PC_N/DRAWPRIMITIVE.CPP b/SPEC_PC_N/DRAWPRIMITIVE.CPP\nindex 0d548ffc..9638c06f 100644\n--- a/SPEC_PC_N/DRAWPRIMITIVE.CPP\n+++ b/SPEC_PC_N/DRAWPRIMITIVE.CPP\n@@ -645,13 +645,10 @@ int32_t DrawPhaseGame()\n \tif (GLOBAL_playing_cutseq)\n \t\tfrigup_lara();\n \n-\t/*SetLaraUnderwaterNodes();\n+\tSetLaraUnderwaterNodes();\n \tDrawRooms(camera.pos.room_number);\n \tDrawGameInfo(TRUE);\n-\tS_OutputPolyList();*/\n-\tDDCopyBitmap(App.lpBackBuffer, "uk.bmp");\n-\tS_DumpScreen();\n-\tDDCopyBitmap(App.lpBackBuffer, "uk.bmp");\n+\tS_OutputPolyList();\n \tcamera.number_frames = S_DumpScreen();\n \tS_AnimateTextures(camera.number_frames);\n \treturn camera.number_frames;\ndiff --git a/SPEC_PC_N/DRAWPRIMITIVE.H b/SPEC_PC_N/DRAWPRIMITIVE.H\nindex 12340b15..e60bf84d 100644\n--- a/SPEC_PC_N/DRAWPRIMITIVE.H\n+++ b/SPEC_PC_N/DRAWPRIMITIVE.H\n@@ -18,6 +18,8 @@ void phd_PutPolygons(short* mesh);\n void DrawStaticObjects(short current_room);\n void DrawEffect(short fx);\n \n+void SkyDrawPhase();\n+\n extern int num_fog_bulbs;\n \n extern uint32_t GnFrameCounter;\ndiff --git a/SPEC_PC_N/GAME.CPP b/SPEC_PC_N/GAME.CPP\nindex 22a8ec43..8933c0f0 100644\n--- a/SPEC_PC_N/GAME.CPP\n+++ b/SPEC_PC_N/GAME.CPP\n@@ -55,6 +55,19 @@ void ClearSurfaces()\n \t{\n \t\t// todo\n \t}\n+\n+\tS_DumpScreen();\n+\n+\tif (App.Flags & WA_BACK_BUFFER)\n+\t{\n+\t\tDX_TRY(App.lpViewPort->Clear2(1, &rect, 3, 0, 1.0, 0));\n+\t}\n+\telse\n+\t{\n+\t\t// todo\n+\t}\n+\n+\tS_DumpScreen();\n }\n \n void GameClose()\ndiff --git a/SPEC_PC_N/GLOBAL.H b/SPEC_PC_N/GLOBAL.H\nindex 1c07b9ba..45bfeac4 100644\n--- a/SPEC_PC_N/GLOBAL.H\n+++ b/SPEC_PC_N/GLOBAL.H\n@@ -69,7 +69,7 @@ extern\tfloat\t\tf_a, f_b, f_boo;\t\t// a/b factors for z buffering (f_boo is f_b/one\n extern\tsint32\t\tw2v_matrix[];\t\t// World to View Matrix...\n extern\tsint32\t\tmatrix_stack[];\t\t// matrix stack for animations etc..\n \n-\n+extern struct SVECTOR CamRot;\n \n #define EndOfArray(a) ((a)+ArraySize(a))\n \ndiff --git a/SPEC_PC_N/INPUT.CPP b/SPEC_PC_N/INPUT.CPP\nindex 3ec6b839..ea0a77ef 100644\n--- a/SPEC_PC_N/INPUT.CPP\n+++ b/SPEC_PC_N/INPUT.CPP\n@@ -12,6 +12,7 @@\n \n sint32 input;\n sint32 dbinput;\n+sint32 inputBusy;\n \n short mouse_x;\n short mouse_y;\ndiff --git a/SPEC_PC_N/INPUT.H b/SPEC_PC_N/INPUT.H\nindex 8c371d6d..3e13d378 100644\n--- a/SPEC_PC_N/INPUT.H\n+++ b/SPEC_PC_N/INPUT.H\n@@ -14,6 +14,7 @@ extern "C" {\n \t// The global input variable\n \textern sint32 input;\n \textern sint32 dbinput;\n+\textern sint32 inputBusy;\n \n \n \textern int bLaraOn;\ndiff --git a/SPEC_PC_N/MATRIX_SHIT.CPP b/SPEC_PC_N/MATRIX_SHIT.CPP\nindex c39893a7..cc384672 100644\n--- a/SPEC_PC_N/MATRIX_SHIT.CPP\n+++ b/SPEC_PC_N/MATRIX_SHIT.CPP\n@@ -5,7 +5,7 @@\n #ifdef __cplusplus\n extern "C" {\n #endif\n-\n+\tstruct SVECTOR CamRot;\n \tsint32\t\tphd_left;  \t\t\t\t/* Left Clipping Value */\n \tsint32\t\tphd_right;              /* Right Clipping Value */\n \tsint32\t\tphd_top;                /* Top Clipping Value */\ndiff --git a/SPEC_PC_N/SPECIFIC.CPP b/SPEC_PC_N/SPECIFIC.CPP\nindex 012cd5b0..3370dd79 100644\n--- a/SPEC_PC_N/SPECIFIC.CPP\n+++ b/SPEC_PC_N/SPECIFIC.CPP\n@@ -138,17 +138,9 @@ long\t\tS_DumpScreen()\n \t}\n \tGnFrameCounter++;\n \n-\tDDPIXELFORMAT ddpf;\n-\tDXInit(ddpf);\n-\tApp.lpFrontBuffer->GetPixelFormat(&ddpf);\n-\tDDBLTFX fx;\n-\tDXInit(fx);\n-\tfx.dwFillColor = ddpf.dwBBitMask;\n-\tApp.lpFrontBuffer->Blt(&App.GnWindowRect, nullptr, nullptr, DDBLT_COLORFILL, &fx);\n-\tfx.dwFillColor = ddpf.dwRBitMask;\n-\tApp.lpBackBuffer->Blt(&App.GnWindowRect, nullptr, nullptr, DDBLT_COLORFILL, &fx);\n \tDDCopyBitmap(App.lpFrontBuffer, "uk.bmp");\n \tDDCopyBitmap(App.lpBackBuffer, "france.bmp");\n+\n \tEndScene();\n \tDXShowFrame();\n \tApp.sceneDone = true;\ndiff --git a/SPEC_PC_N/WINMAIN.CPP b/SPEC_PC_N/WINMAIN.CPP\nindex 77e842ea..c7d9bba6 100644\n--- a/SPEC_PC_N/WINMAIN.CPP\n+++ b/SPEC_PC_N/WINMAIN.CPP\n@@ -206,10 +206,10 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine\n \tuint32_t thread_id;\n \thThread = (HANDLE)_beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);\n \n-\tthread_started = true;\n-\n \tWinProcMsg();\n \n+\tthread_started = true;\n+\n \twhile (game_running);\n \n \tWinClose();\n', 'commit_subject': 'work ongoing, game loop works iojafoiqhsfpiheo', 'repo_name': 'TOMB5/TOMB5', 'committer': {'name': 'zdimension', 'email': '7f133c9dd458bcf09a5cce3b4ee818e8fbace9c6@free.fr', 'time_sec': '1534435812', 'tz_offset': '120', 'date': {'seconds': '1534435812'}}, 'commit_tree': '6429e72cb2f3655447b3d3a6968a72ff2d0b12da', 'commit_message': 'work ongoing, game loop works iojafoiqhsfpiheo\n', 'language_name': 'C++', 'license': 'mit', 'hunks': '@@ -206,10 +206,10 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine\n \tuint32_t thread_id;\n \thThread = (HANDLE)_beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);\n \n-\tthread_started = true;\n-\n \tWinProcMsg();\n \n+\tthread_started = true;\n+\n \twhile (game_running);\n \n \tWinClose();\n', 'addition_count': 2, 'deletion_count': 2, 'src_file': 'a/SPEC_PC_N/WINMAIN.CPP', 'tgt_file': 'b/SPEC_PC_N/WINMAIN.CPP', 'file_extension': '.CPP', 'before_file': '#define _X86_\n\n#include "STANDARD.H"\n#include "GLOBAL.H"\n#include "TEMPLATE.H"\n#include "DIRECTX.H"\n#include "WINMAIN.H"\n//#include "console.h"\n#include "crtdbg.h"\n//#include "texture.h"\n#include "DRAWPRIMITIVE.H"\n#include "HWRENDER.H"\n#include "UTILS.H"\n#include "CONTROL.H"\n#include "DI.H"\n#include "DS.H"\n#include "time.h"\n//#include "spanbuffer.h"\n#include "HWINSERT.H"\n#include "PICTURE.H"\n#include "resource.h"\n#include "FILE.H"\n#include "GAMEFLOW.H"\n#include "GAME.H"\n#include "PCSETUP.H"\n#include "DEBUG.H"\n#include "INPUT.H"\n#include "DISPLAY.H"\n#include "TEXT.H"\n#include <ctime>\n\nWINAPP App;\nbool thread_started;\nHANDLE hThread;\n\nvoid WinProcMsg()// (F)\n{\n\tLog(LT_Enter, "WinProcMsg");\n\n\tMSG Msg;\n\n\tdo\n\t{\n\t\tGetMessageA(&Msg, nullptr, 0, 0);\n\n\t\tif (!TranslateAcceleratorA(App.WindowHandle, App.hAccTable, &Msg))\n\t\t{\n\t\t\tTranslateMessage(&Msg);\n\t\t\tDispatchMessageA(&Msg);\n\t\t}\n\t} while (!thread_started && Msg.message != WM_QUIT);\n}\n\nvoid WinClose()// (F)\n{\n\tLog(LT_Enter, "WinClose");\n\n\tSaveSettings();\n\tCloseHandle(App.hObject);\n\tDXFreeInfo(&App.DeviceInfo);\n\tDestroyAcceleratorTable(App.hAccTable);\n\tCloseDirectX();\n\n\tif (App.lpDIKeyboard)\n\t{\n\t\tDX_TRY(App.lpDIKeyboard->Unacquire());\n\t\tDXRelease(App.lpDIKeyboard, "Keyboard");\n\t}\n\n\tif (App.lpDIJoystick)\n\t{\n\t\tDX_TRY(App.lpDIJoystick->Unacquire());\n\t\tDXRelease(App.lpDIJoystick, "Joystick");\n\t}\n\n\tDXRelease(App.lpDI, "DirectInput");\n}\n\nbool WinRunCheck(LPCSTR lpName, LPCSTR lpClassName, HANDLE* mutex)// (F)\n{\n\tLog(LT_Enter, "WinRunCheck");\n\n\t*mutex = CreateMutexA(nullptr, true, lpName);\n\n\tif (GetLastError() != ERROR_ALREADY_EXISTS)\n\t\treturn false;\n\n\tHWND wnd = FindWindowA(lpClassName, lpName);\n\n\tif (wnd)\n\t\tSendMessageA(wnd, WM_ACTIVATE, 0, 0);\n\n\treturn true;\n}\n\nvoid WinProcessCommandLine(LPSTR lpCmdLine)\n{\n\tLog(LT_Enter, "WinProcessCommandLine");\n\n\tUnimpl();\n}\n\nint PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)// (F)\n{\n\tint RetVal;\n\tint n;\n\n\tappsettings.OpenSetup = false;\n\n\tmemset(&App, 0, sizeof(WINAPP));\n\n\tApp.GameInitialized = false;\n\n\tDB_InitLog(1);\n\n\tHWND dblog = FindWindowA("DBLogWindowClass", "DBLog Server");\n\tif (dblog)\n\t\tPostMessageA(dblog, dbm_command, 2, 0);\n\n\tdblog = FindWindowA("DBLogWindowClass", "DBLog Server");\n\tif (dblog)\n\t\tPostMessageA(dblog, dbm_clearlog, 0, 0);\n\n\tDB_DefType("Error", 0xFF, 1);\n\tDB_DefType("Function", 0x8000, 0);\n\tDB_DefType("DirectX Information", 0x802040, 1);\n\tDB_DefType("Object Release", 0x80, 0);\n\tDB_DefType("General Information", 0x800000, 1);\n\tDB_DefType("Windows Message", 0x800080, 0);\n\tDB_DefType("Level Info", 0x8000FF, 0);\n\tDB_DefType("Sound", 0x8080, 0);\n\n\tLog(LT_Info, "Launching - %s", WINDOWNAME);\n\tLog(LT_Enter, "WinMain");\n\n\tif (WinRunCheck(WINDOWNAME, WINDOWCLASS, &App.hObject))\n\t\treturn false;\n\n\tFindCdDrive();\n\tLoadGameflow();\n\tWinProcessCommandLine(lpCmdLine);\n\n\tApp.hInstance = hInstance;\n\tApp.WindowClass.hIcon = nullptr;\n\tApp.WindowClass.lpszMenuName = nullptr;\n\tApp.WindowClass.lpszClassName = WINDOWCLASS;\n\tApp.WindowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);\n\tApp.WindowClass.hInstance = hInstance;\n\tApp.WindowClass.style = CS_VREDRAW | CS_HREDRAW;\n\tApp.WindowClass.lpfnWndProc = WinAppProc;\n\tApp.WindowClass.cbClsExtra = 0;\n\tApp.WindowClass.cbWndExtra = 0;\n\tApp.WindowClass.hCursor = LoadCursor(App.hInstance, IDC_ARROW);\n\n\tif (!RegisterClass(&App.WindowClass))\n\t{\n\t\tLog(LT_Error, "Unable To Register Window Class");\n\t\treturn false;\n\t}\n\n\tRECT Rect;\n\n\tRect.left = 0;\n\tRect.top = 0;\n\tRect.right = 640;\n\tRect.bottom = 480;\n\n\tAdjustWindowRect(&Rect, WS_CAPTION, false);\n\n\tApp.WindowHandle = CreateWindowEx(\n\t\t\tWS_THICKFRAME,\n\t\t\tWINDOWCLASS,\n\t\t\tWINDOWNAME,\n\t\t\tWS_BORDER,\n\t\t\tCW_USEDEFAULT,\n\t\t\tCW_USEDEFAULT,\n\t\t\tRect.right - Rect.left,\n\t\t\tRect.bottom - Rect.top,\n\t\t\tnullptr,\n\t\t\tnullptr,\n\t\t\tApp.hInstance,\n\t\t\tnullptr\n\t);\n\n\tif (!App.WindowHandle)\n\t{\n\t\tLog(LT_Error, "Unable To Create Window");\n\t\treturn FALSE;\n\t}\n\n\tDXInitialise(&App.DeviceInfo, App.WindowHandle);\n\n\tif (appsettings.OpenSetup || !LoadSettings())\n\t{\n\t\tif (!InitSetupDialog())\n\t\t{\n\t\t\tfree(gfScriptFile);\n\t\t\tfree(gfStringOffset);\n\t\t\tWinClose();\n\t\t\treturn 0;\n\t\t}\n\n\t\tLoadSettings();\n\t}\n\n\tuint32_t thread_id;\n\thThread = (HANDLE)_beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);\n\n\tthread_started = true;\n\n\tWinProcMsg();\n\n\twhile (game_running);\n\n\tWinClose();\n\n\t//App.DXConfig.nD3D = 0; // todo: temporary fix because of lack of software renderer\n\n\tif (!DXCreate(\n\t\t\tCUR_DM.w,\n\t\t\tCUR_DM.h,\n\t\t\tCUR_DM.bpp,\n\t\t\tApp.orig_flags,\n\t\t\t&App,\n\t\t\tApp.WindowHandle,\n\t\t\tWS_CAPTION))\n\t{\n\t\tMessageBoxA(nullptr, &gfStringWad[gfStringOffset[STR_FAILED_TO_SETUP_DIRECTX]], "Tomb Raider", 0);\n\t\treturn false;\n\t}\n\n\tShowBumpInfo();\n\n\tUpdateWindow(App.WindowHandle);\n\tShowWindow(App.WindowHandle, nCmdShow);\n\n\tif (App.Flags & WA_FULLSCREEN)\n\t{\n\t\tSetCursor(nullptr);\n\t\tShowCursor(false);\n\t}\n\n\tDXCreateDirectInput(App.WindowHandle, hInstance);\n\n\tApp.hAccTable = LoadAcceleratorsA(hInstance, (LPCSTR) 0x65);\n\n\tif (!App.tDisableSound)\n\t{\n\t\tDXDSCreate();\n\t\tInitACM();\n\t}\n\n\tgame_running = true;\n\tthread_started = false;\n\n\tuint32_t thread_id;\n\thThread = (HANDLE) _beginthreadex(nullptr, 0, GameMain, nullptr, 0, &thread_id);\n\n\tWinProcMsg();\n\n\tthread_started = true;\n\n\twhile (game_running);\n\n\tWinClose();\n\n\tHWND desktop = GetDesktopWindow();\n\tReleaseDC(desktop, GetDC(desktop));\n\n\tDEVMODEA dm;\n\tdm.dmSize = sizeof(dm);\n\tdm.dmBitsPerPel = App.OriginalBPP;\n\tdm.dmFields = DM_BITSPERPEL;\n\tChangeDisplaySettingsA(&dm, 0);\n\n\tdblog = FindWindowA("DBLogWindowClass", "DBLog Server");\n\tif (dblog)\n\t\tPostMessageA(dblog, dbm_command, 4, 0);\n\n\treturn 0;\n}\n\nvoid HandleCommand(WORD param)// (F)\n{\n\tif (param == IDR_VKRETURN)\n\t{\n\t\tif (!App.PlayingFMV && CUR_DD.DDCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED && !levelLoading)\n\t\t{\n\t\t\tLog(LT_WindowMessage, "KA_ALTENTER");\n\n\t\t\tLog(LT_Info, "HangGameThread");\n\n\t\t\twhile (App.isInScene);\n\n\t\t\tApp.bNoFocus = true;\n\n\t\t\twhile (!App.isInScene);\n\n\t\t\tSuspendThread(hThread);\n\n\t\t\tLog(LT_Info, "Game Thread Suspended");\n\n\t\t\tFreeD3DLights();\n\t\t\tDXToggleFullScreen();\n\t\t\tHWInitialise();\n\t\t\t//\n\t\t\tS_InitD3DMatrix();\n\t\t\tSetD3DViewMatrix();\n\n\t\t\tResumeThread(hThread);\n\n\t\t\tApp.bNoFocus = false;\n\n\t\t\tLog(LT_Info, "Game Thread Resumed");\n\n\t\t\tif (App.Flags & WA_FULLSCREEN)\n\t\t\t{\n\t\t\t\tSetCursor(nullptr);\n\t\t\t\tShowCursor(false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSetCursor(LoadCursor(App.hInstance, IDC_ARROW));\n\t\t\t\tShowCursor(true);\n\t\t\t}\n\t\t}\n\t}\n\telse if ((param == IDR_VKADD || param == IDR_VKSUBTRACT) && !levelLoading && !App.PlayingFMV)\n\t{\n\t\tLog(LT_Info, "Change Video Mode");\n\n\t\tLog(LT_Info, "HangGameThread");\n\n\t\tif (App.isInScene)\n\t\t\tWaitUntilFalse(&App.isInScene);\n\n\t\tApp.bNoFocus = true;\n\n\t\tif (!App.isInScene)\n\t\t\tWaitUntilTrue(&App.isInScene);\n\n\t\tSuspendThread(hThread);\n\n\t\tLog(LT_Info, "Game Thread Suspended");\n\n\t\tint old = App.DXConfig.nVMode;\n\n\t\tif (param == IDR_VKADD)\n\t\t{\n\t\t\tApp.DXConfig.nVMode = MIN(App.DXConfig.nVMode + 1, CUR_D3D.nDisplayMode - 1);\n\n\t\t\tif (GET_DM(old).bpp != CUR_DM.bpp)\n\t\t\t{\n\t\t\t\tfor (; App.DXConfig.nVMode < CUR_D3D.nDisplayMode; App.DXConfig.nVMode++)\n\t\t\t\t{\n\t\t\t\t\tif (GET_DM(old).bpp == CUR_DM.bpp)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (App.DXConfig.nVMode == CUR_D3D.nDisplayMode)\n\t\t\t\t{\n\t\t\t\t\tApp.DXConfig.nVMode = old;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tApp.DXConfig.nVMode = MAX(App.DXConfig.nVMode - 1, 0);\n\n\t\t\tif (GET_DM(old).bpp != CUR_DM.bpp)\n\t\t\t{\n\t\t\t\tfor (; App.DXConfig.nVMode >= 0; App.DXConfig.nVMode--)\n\t\t\t\t{\n\t\t\t\t\tif (GET_DM(old).bpp == CUR_DM.bpp)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (App.DXConfig.nVMode == -1)\n\t\t\t\t{\n\t\t\t\t\tApp.DXConfig.nVMode = old;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (App.DXConfig.nVMode != old)\n\t\t{\n\t\t\tFreeD3DLights();\n\n\t\t\tif (!DXChangeVideoMode())\n\t\t\t{\n\t\t\t\tApp.DXConfig.nVMode = old;\n\t\t\t\tDXChangeVideoMode();\n\t\t\t}\n\n\t\t\tHWInitialise();\n\t\t\t//\n\t\t\tInitWindow(0, 0, App.width, App.height, 20, SECTOR(20), 80);\n\t\t\tInitFont();\n\t\t\tS_InitD3DMatrix();\n\t\t\tSetD3DViewMatrix();\n\t\t}\n\n\t\tResumeThread(hThread);\n\n\t\tApp.bNoFocus = false;\n\n\t\tLog(LT_Info, "Game Thread Resumed");\n\n\t\t//\n\t}\n}\n\nvoid HandleApp(LPARAM lParam, WPARAM wParam)\n{\n\tbyte_57A01C = true;\n\n\tif (!acm_file_stream)\n\t{\n\t\tbyte_57A01C = false;\n\t\tbyte_579FE4 = false;\n\t\treturn;\n\t}\n\n\tif (wParam != (WPARAM) XATrack || wParam == 0xFFFFFFFF)\n\t{\n\t\tLog(LT_Default, "Not Current Track %d", wParam);\n\t\tbyte_57A01C = false;\n\t\tbyte_579FE4 = false;\n\t\treturn;\n\t}\n\n\tmemset((void*) lParam, 0, 22528);\n\tfread((void*) lParam, 1, 22528, acm_file_stream);\n\n\tif (acm_file_stream && feof(acm_file_stream))\n\t{\n\t\tbyte_57A01C = false;\n\n\t\tif (acm_playing_mode == 1)\n\t\t{\n\t\t\tfseek(acm_file_stream, 90, 0);\n\n\t\t\tbyte_579FE4 = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (++dword_57A018 <= 8)\n\t\t\t{\n\t\t\t\tbyte_579FE4 = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdword_57A018 = 0;\n\n\t\t\t\tif (acm_playing_mode == 2)\n\t\t\t\t{\n\t\t\t\t\tbyte_579FE4 = false;\n\t\t\t\t\tS_CDStop();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (CurrentAtmosphere == 0 || IsAtmospherePlaying)\n\t\t\t\t\t{\n\t\t\t\t\t\tbyte_579FE4 = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbyte_579FE4 = false;\n\t\t\t\t\t\tS_CDStop();\n\t\t\t\t\t\tS_CDPlay(CurrentAtmosphere, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tbyte_57A01C = false;\n\t\tbyte_579FE4 = true;\n\t}\n}\n\nHMODULE GetKernel32()// (F)\n{\n\treturn GetModuleHandleA("kernel32.dll");\n}\n\nvoid* FindSleepAddress(HMODULE kernel)// (F)\n{\n\treturn GetProcAddress(kernel, "Sleep");\n}\n\nvoid* GetSleepFunc()// (F)\n{\n\treturn FindSleepAddress(GetKernel32());\n}\n\nvoid Sleep1ms()// (F)\n{\n\t((void (__stdcall*)(DWORD)) GetSleepFunc())(1);\n}\n\nvoid WaitUntilFalse(DWORD* ptr)// (F)\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored "-Wfor-loop-analysis"\n\tdo\n\t{\n\t\tSleep1ms();\n\t} while (*ptr);\n#pragma clang diagnostic pop\n}\n\nvoid WaitUntilTrue(DWORD* ptr)// (F)\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored "-Wfor-loop-analysis"\n\tdo\n\t{\n\t\tSleep1ms();\n\t} while (!*ptr);\n#pragma clang diagnostic pop\n}\n\n/*\nFunction : AppWinProc\nUseage   : Application Window Procedure\n*/\n\nlong FAR PASCAL WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)\n{\n\tswitch (msg)\n\t{\n\t\tcase WM_CLOSE:\n\t\t\tLog(LT_WindowMessage, "WM_CLOSE");\n\t\t\t// TODO TODO TODO TODO TODO\n\t\t\tPostQuitMessage(EXIT_SUCCESS);\n\n\t\t\tgame_running = false;\n\t\t\tbreak;\n\n\t\tcase WM_CREATE:\n\t\t\t// todo todo todo\n\t\t\tLog(LT_WindowMessage, "WM_CREATE");\n\t\t\tbreak;\n\n\t\tcase WM_MOVE:\n\t\t\tLog(LT_WindowMessage, "WM_MOVE");\n\t\t\tDXMove(LOWORD(lParam), HIWORD(lParam));\n\t\t\tbreak;\n\n\t\tcase WM_COMMAND:\n\t\t\tLog(LT_WindowMessage, "WM_COMMAND");\n\t\t\tHandleCommand(LOWORD(wParam));\n\t\t\tbreak;\n\n\t\tcase WM_MOUSEMOVE:\n\t\t\tmouse_x = GET_X_LPARAM(lParam);\n\t\t\tmouse_y = GET_Y_LPARAM(lParam);\n\t\t\tmouse_vkeys = (int) wParam;\n\t\t\tbreak;\n\n\t\tcase WM_APP:\n\t\t\tHandleApp(lParam, wParam);\n\t\t\treturn 0;\n\n\t\t\t/*case WM_CHAR:\n\t\t\t\t//\t\tKeyToConsole(wParam);\n\t\t\t\tbreak;\n\n\n\t\t\tcase WM_KEYDOWN:\n\t\t\t\tswitch (wParam)\n\t\t\t\t{\n\t\t\t\tcase VK_F1:\n\t\t\t\t\t//\t\t\tToggleConsole();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase WM_KEYUP:\n\t\t\t\tbreak;*/\n\n\n\t\tcase WM_ACTIVATE:\n\t\t\tLog(LT_WindowMessage, "WM_ACTIVATE");\n\n\t\t\tif (!App.PlayingFMV)\n\t\t\t{\n\t\t\t\tswitch (LOWORD(wParam))\n\t\t\t\t{\n\t\t\t\t\tcase WA_ACTIVE:\n\t\t\t\t\tcase WA_CLICKACTIVE:\n\t\t\t\t\t\tLog(LT_WindowMessage, "WM_ACTIVE");\n\n\t\t\t\t\t\tif (App.GameInitialized)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAcquireInput(true);\n\t\t\t\t\t\t\tResumeThread(hThread);\n\n\t\t\t\t\t\t\tApp.bNoFocus = false;\n\n\t\t\t\t\t\t\tLog(LT_Info, "Game Thread Resumed");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WA_INACTIVE:\n\t\t\t\t\t\tLog(LT_WindowMessage, "WM_INACTIVE");\n\n\t\t\t\t\t\tif (App.GameInitialized)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAcquireInput(false);\n\n\t\t\t\t\t\t\tLog(LT_Info, "HangGameThread");\n\n\t\t\t\t\t\t\tif (App.isInScene)\n\t\t\t\t\t\t\t\tWaitUntilFalse(&App.isInScene);\n\n\t\t\t\t\t\t\tApp.bNoFocus = true;\n\n\t\t\t\t\t\t\tif (!App.isInScene)\n\t\t\t\t\t\t\t\tWaitUntilTrue(&App.isInScene);\n\n\t\t\t\t\t\t\tSuspendThread(hThread);\n\n\t\t\t\t\t\t\tLog(LT_Info, "Game Thread Suspended");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 0;\n\t}\n\n\treturn DefWindowProc(hWnd, msg, wParam, lParam);\n}\n\n\nvoid ShowBumpInfo()\n{\n\tif (CUR_D3D.DeviceDesc.dwTextureOpCaps & (D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))\n\t{\n\t\tif (CUR_D3D.DeviceDesc.wMaxTextureBlendStages >= 3)\n\t\t{\n\t\t\t//App.lpD3DDevice->EnumTextureFormats(nullptr, nullptr);\n/*\n            if (false)\n            {\n                Log(LT_Info, "Bump bit count 0x%X", BumpBitCount);\n                Log(LT_Info, "Bump DU %X", BumpDU);\n                Log(LT_Info, "Bump DV %X", BumpDV);\n            }\n        */\n\t\t}\n\t}\n}\n\nfloat WinFrameRate()// (F)\n{\n\tstatic int last_time = clock();\n\n\tif (++App.fps_counter == 10)\n\t{\n\t\ttime_t this_time = clock();\n\t\tdouble t = (this_time - last_time) / (double) CLOCKS_PER_SEC;\n\t\tlast_time = this_time;\n\t\tApp.fps_static = App.fps_counter / t;\n\t\tApp.fps_counter = 0;\n\t}\n\n\tApp.fps = App.fps_static;\n\n\treturn App.fps;\n}\n\nvoid WinDisplayString(int x, int y, const char* String, ...)// (F)\n{\n\tva_list argptr;\n\tchar msg[4096];\n\t\t\tva_start(argptr, String);\n\tvsprintf(msg, String, argptr);\n\t\t\tva_end(argptr);\n\tPrintString(x, y, 6, msg, 0);\n}', 'message': 'work ongoing, game loop works iojafoiqhsfpiheo\n', 'author_name': 'zdimension', 'lang': 'CPP'}