diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index b8e2318d..0da32dd2 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void)
 	pEmptyReferences = CReferences::pEmptyList;
 	pStoredCam = new uint8[sizeof(CCamera)];
 	memcpy(pStoredCam, &TheCamera, sizeof(CCamera));
-	pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS];
-	memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip));
+	pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS];
+	memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace));
 	PlayerWanted = *FindPlayerPed()->m_pWanted;
 	PlayerInfo = CWorld::Players[0];
 	Time1 = CTimer::GetTimeInMilliseconds();
@@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void)
 	memcpy(&TheCamera, pStoredCam, sizeof(CCamera));
 	delete[] pStoredCam;
 	pStoredCam = nil;
-	memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS);
+	memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
 	delete[] pRadarBlips;
 	pRadarBlips = nil;
 	FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index db2c93a3..ddea0e3c 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -91,10 +91,10 @@ uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SP
 CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
 int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
 int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
-CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
-CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
+intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
+intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
 CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
-CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
+script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
 tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
 tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
 int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
@@ -313,7 +313,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id)
 	return false;
 }
 
-void CStuckCarCheckEntry::Reset()
+void stuck_car_data::Reset()
 {
 	m_nVehicleIndex = -1;
 	m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f);
diff --git a/src/control/Script.h b/src/control/Script.h
index 8143bd43..4338bd18 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -15,22 +15,25 @@ class CRunningScript;
 
 #define KEY_LENGTH_IN_SCRIPT 8
 
-struct CScriptRectangle 
+struct intro_script_rectangle 
 {
 	bool m_bIsUsed;
 	bool m_bBeforeFade;
 	int16 m_nTextureId;
 	CRect m_sRect;
 	CRGBA m_sColor;
+	
+	intro_script_rectangle() { }
+	~intro_script_rectangle() { }
 };
 
-static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
+static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error");
 
 enum {
 	SCRIPT_TEXT_MAX_LENGTH = 500
 };
 
-struct CTextLine 
+struct intro_text_line 
 {
 	float m_fScaleX;
 	float m_fScaleY;
@@ -50,6 +53,9 @@ struct CTextLine
 	float m_fAtY;
 	wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
 
+	intro_text_line() { }
+	~intro_text_line() { }
+	
 	void Reset()
 	{
 		m_fScaleX = 0.48f;
@@ -72,15 +78,17 @@ struct CTextLine
 	}
 };
 
-static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
+static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error");
 
-struct CScriptSphere
+struct script_sphere_struct
 {
 	bool m_bInUse;
 	uint16 m_Index;
 	uint32 m_Id;
 	CVector m_vecCenter;
 	float m_fRadius;
+	
+	script_sphere_struct() { }
 };
 
 struct CStoredLine
@@ -145,7 +153,7 @@ public:
 	bool HasCarBeenUpsideDownForAWhile(int32);
 };
 
-struct CStuckCarCheckEntry
+struct stuck_car_data
 {
 	int32 m_nVehicleIndex;
 	CVector m_vecPos;
@@ -154,12 +162,13 @@ struct CStuckCarCheckEntry
 	uint32 m_nStuckTime;
 	bool m_bStuck;
 
+	stuck_car_data() { }
 	inline void Reset();
 };
 
 class CStuckCarCheck
 {
-	CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS];
+	stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
 
 public:
 	void Init();
@@ -235,10 +244,10 @@ class CTheScripts
 	static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
 	static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
 	static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
-	static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
-	static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
+	static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
+	static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
 	static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
-	static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
+	static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
 	static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
 	static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
 	static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index d79c9218..91dd6573 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -142,7 +142,7 @@ CCamera::Init(void)
 	PlayerExhaustion = 1.0f;
 	DebugCamMode = CCam::MODE_NONE;
 	m_PedOrientForBehindOrInFront = 0.0f;
-	if(!FrontEndMenuManager.m_bStartGameLoading){
+	if(!FrontEndMenuManager.m_bWantToRestart){
 		m_bFading = false;
 		CDraw::FadeValue = 0;
 		m_fFLOATingFade = 0.0f;
@@ -151,7 +151,7 @@ CCamera::Init(void)
 		m_fFLOATingFadeMusic = 0.0f;
 	}
 	m_bMoveCamToAvoidGeom = false;
-	if(FrontEndMenuManager.m_bStartGameLoading)
+	if(FrontEndMenuManager.m_bWantToRestart)
 		m_bMoveCamToAvoidGeom = true;
 	m_bStartingSpline = false;
 	m_iTypeOfSwitch = INTERPOLATION;
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 98d67fa2..beebacf9 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -555,7 +555,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
 		m_PrefsVsync = m_PrefsVsyncDisp;
 
 	DMAudio.Service();
-	m_bStartGameLoading = true;
+	m_bWantToRestart = true;
 
 	ShutdownJustMenu();
 	UnloadTextures();
@@ -2819,7 +2819,7 @@ void CMenuManager::Process(void)
 	if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
 		return;
 
-	m_bStartGameLoading = false;
+	m_bWantToRestart = false;
 	InitialiseChangedLanguageSettings();
 
 	if (CPad::GetPad(0)->GetEscapeJustDown())
@@ -2861,9 +2861,9 @@ void CMenuManager::Process(void)
 				if (m_PrefsVsyncDisp != m_PrefsVsync)
 					m_PrefsVsync = m_PrefsVsyncDisp;
 				DMAudio.Service();
-				m_bStartGameLoading = true;
+				m_bWantToRestart = true;
 				RequestFrontEndShutDown();
-				m_bLoadingSavedGame = true;
+				m_bWantToLoad = true;
 				b_FoundRecentSavedGameWantToLoad = true;
 				DMAudio.SetEffectsFadeVol(0);
 				DMAudio.SetMusicFadeVol(0);
@@ -2960,7 +2960,7 @@ void CMenuManager::Process(void)
 		m_bWaitingForNewKeyBind = false;
 	}
 
-	if (!m_bStartGameLoading) {
+	if (!m_bWantToRestart) {
 		if (m_bGameNotLoaded)
 			DMAudio.Service();
 	}
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index a97afb24..c08bc1d9 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -464,7 +464,7 @@ public:
 	bool m_bMenuActive;
 	bool m_bMenuStateChanged;
 	bool m_bWaitingForNewKeyBind;
-	bool m_bStartGameLoading;
+	bool m_bWantToRestart;
 	bool m_bFirstTime;
 	bool m_bGameNotLoaded;
 	int32 m_nMousePosX;
@@ -484,7 +484,7 @@ public:
 	bool m_bQuitGameNoCD;
  bool m_bRenderGameInMenu;
 	bool m_bSaveMenuActive;
-	bool m_bLoadingSavedGame;
+	bool m_bWantToLoad;
  char field_455;
 	bool m_bStartWaitingForKeyBind;
 	bool m_bSpritesLoaded;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 8571e93e..daac3ec5 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,8 +89,6 @@
 
 
 
-#define DEFAULT_VIEWWINDOW (0.7f)
-
 eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
 bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
 bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@@ -492,7 +490,7 @@ void CGame::ReInitGameObjectVariables(void)
 	CParticle::ReloadConfig();
 	CCullZones::ResolveVisibilities();
 
-	if ( !FrontEndMenuManager.m_bLoadingSavedGame )
+	if ( !FrontEndMenuManager.m_bWantToLoad )
 	{
 		CCranes::InitCranes();
 		CTheScripts::StartTestScript();
@@ -566,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void)
 	
 	TheCamera.Init();
 	
-	if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
+	if ( FrontEndMenuManager.m_bWantToLoad == true )
 	{
 		RestoreForStartLoad();
 		CStreaming::LoadScene(TheCamera.GetPosition());
@@ -574,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void)
 	
 	ReInitGameObjectVariables();
 	
-	if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
+	if ( FrontEndMenuManager.m_bWantToLoad == true )
 	{
 		if ( GenericLoad() == true )
 		{
@@ -593,7 +591,7 @@ void CGame::InitialiseWhenRestarting(void)
 			ShutDownForRestart();
 			CTimer::Stop();
 			CTimer::Initialise();
-			FrontEndMenuManager.m_bLoadingSavedGame = false;
+			FrontEndMenuManager.m_bWantToLoad = false;
 			ReInitGameObjectVariables();
 			currLevel = LEVEL_INDUSTRIAL;
 			CCollision::SortOutCollisionAfterLoad();
@@ -609,6 +607,9 @@ extern void (*DebugMenuProcess)(void);
 void CGame::Process(void) 
 {
 	CPad::UpdatePads();
+#ifdef GTA_PS2
+	ProcessTidyUpMemory();
+#endif
 	TheCamera.SetMotionBlurAlpha(0);
 	if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
 		TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
@@ -695,6 +696,13 @@ void CGame::TidyUpMemory(bool, bool)
 #endif
 }
 
+void CGame::ProcessTidyUpMemory(void)
+{
+#ifdef PS2
+	// meow
+#endif
+}
+
 STARTPATCHES
 	InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
 	InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);
diff --git a/src/core/Game.h b/src/core/Game.h
index 318ff54b..30581893 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -39,4 +39,5 @@ public:
 	// NB: these do something on PS2
 	static void TidyUpMemory(bool, bool);
 	static void DrasticTidyUpMemory(bool);
+	static void ProcessTidyUpMemory(void);
 };
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 079a3ea7..6efbeb8e 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -38,6 +38,7 @@ CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)
 
 bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
 bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
+bool CPad::bOldDisplayNoControllerMessage;
 bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
 
 CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
@@ -329,6 +330,21 @@ void CKeyboardState::Clear()
 	LWIN = RWIN = APPS = 0;
 }
 
+#ifdef GTA_PS2_STUFF
+void CPad::Initialise(void)
+{
+	for (int i = 0; i < MAX_PADS; i++)
+	{
+		CPad::GetPad(i)->Clear(true);
+		CPad::GetPad(i)->Mode = 0;
+	}
+	
+	bObsoleteControllerMessage     = false;
+	bOldDisplayNoControllerMessage = false;
+	bDisplayNoControllerMessage    = false;
+}
+#endif
+
 void CPad::Clear(bool bResetPlayerControls)
 {
 	NewState.Clear();
@@ -356,13 +372,13 @@ void CPad::Clear(bool bResetPlayerControls)
 	bApplyBrakes = false;
 	
 	
-	for ( int32 i = 0; i < _TODOCONST(5); i++ )
+	for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
 		bHornHistory[i] = false;
 	
 	iCurrHornHistory = 0;
 	
-	for ( int32 i = 0; i < _TODOCONST(12); i++ )
-		_unk[i] = ' ';
+	for ( int32 i = 0; i < ARRAY_SIZE(CheatString); i++ )
+		CheatString[i] = ' ';
 	
 	LastTimeTouched = CTimer::GetTimeInMilliseconds();
 	AverageWeapon = 0;
@@ -621,6 +637,108 @@ void CPad::StartShake_Train(float fX, float fY)
 	}
 }
 
+#ifdef GTA_PS2_STUFF
+void CPad::AddToCheatString(char c)
+{
+	for ( int32 i = ARRAY_SIZE(CheatString) - 2; i >= 0; i-- )
+		CheatString[i + 1] = CheatString[i];
+
+#define _CHEATCMP(str)  strncmp(str, CheatString, sizeof(str)-1)
+	// "4414LDRULDRU"	-	R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+	if ( !_CHEATCMP("URDLURDL4144") )
+		WeaponCheat();
+
+	// "4411LDRULDRU"	-	R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+	else if ( !_CHEATCMP("URDLURDL1144") )
+		MoneyCheat();
+	
+	// "4412LDRULDRU"	-	R2 R2 L1 L2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+	else if ( !_CHEATCMP("URDLURDL2144") )
+		ArmourCheat();
+	
+	// "4413LDRULDRU"	-	R2 R2 L1 R1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+	else if ( !_CHEATCMP("URDLURDL3144") )
+		HealthCheat();
+
+	// "4414LRLRLR"		-	R2 R2 L1 R2 LEFT RIGHT LEFT RIGHT LEFT RIGHT
+	else if ( !_CHEATCMP("RLRLRL4144") )
+		WantedLevelUpCheat();
+	
+	// "4414UDUDUD"		-	R2 R2 L1 R2 UP DOWN UP DOWN UP DOWN
+	else if ( !_CHEATCMP("DUDUDU4144") )
+		WantedLevelDownCheat();
+	
+	// "1234432T"		-	L1 L2 R1 R2 R2 R1 L2 TRIANGLE
+	else if ( !_CHEATCMP("T2344321") )
+		SunnyWeatherCheat();
+	
+	// "1234432S"		-	L1 L2 R1 R2 R2 R1 L2 SQUARE
+	else if ( !_CHEATCMP("S2344321") )
+		CloudyWeatherCheat();
+	
+	// "1234432C"		-	L1 L2 R1 R2 R2 R1 L2 CIRCLE
+	else if ( !_CHEATCMP("C2344321") )
+		RainyWeatherCheat();
+	
+	// "1234432X"		-	L1 L2 R1 R2 R2 R1 L2 CROSS
+	else if ( !_CHEATCMP("X2344321") )
+		FoggyWeatherCheat();
+	
+	// "CCCCCC321TCT"	-	CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE
+	else if ( !_CHEATCMP("TCT123CCCCCC") )
+		TankCheat();
+	
+	// "CCCSSSSS1TCT"	-	CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
+	else if ( !_CHEATCMP("TCT1SSSSSCCC") )
+		FastWeatherCheat();
+	
+	// "241324TSCT21"	-	L2 R2 L1 R1 L2 R2 TRIANGLE SQUARE CIRCLE TRIANGLE L2 L1
+	else if ( !_CHEATCMP("12TCST423142") )
+		BlowUpCarsCheat();
+	
+	// "RDLU12ULDR"		-	RIGHT DOWN LEFT UP L1 L2 UP LEFT DOWN RIGHT
+	else if ( !_CHEATCMP("RDLU21ULDR") )
+		ChangePlayerCheat();
+	
+	// "DULUX3421"		-	DOWN UP LEFT UP CROSS R1 R2 L2 L1
+	else if ( !_CHEATCMP("1243XULUD") )
+		MayhemCheat();
+	
+	// "DULUX3412"		-	DOWN UP LEFT UP CROSS R1 R2 L1 L2
+	else if ( !_CHEATCMP("2143XULUD") )
+		EverybodyAttacksPlayerCheat();
+	
+	// "43TX21UD"		-	R2 R1 TRIANGLE CROSS L2 L1 UP DOWN
+	else if ( !_CHEATCMP("DU12XT34") )
+		WeaponsForAllCheat();
+	
+	// "TURDS12"		-	TRIANGLE UP RIGHT DOWN SQUARE L1 L2
+	else if ( !_CHEATCMP("21SDRUT") )
+		FastTimeCheat();
+	
+	// "TURDS34"		-	TRIANGLE UP RIGHT DOWN SQUARE R1 R2
+	else if ( !_CHEATCMP("43SDRUT") )
+		SlowTimeCheat();
+
+	// "11S4T1T"		-	L1 L1 SQUARE R2 TRIANGLE L1 TRIANGLE
+	else if ( !_CHEATCMP("T1T4S11") )
+		OnlyRenderWheelsCheat();
+	
+	// "R4C32D13"		-	RIGHT R2 CIRCLE R1 L2 DOWN L1 R1
+	else if ( !_CHEATCMP("31D23C4R") )
+		ChittyChittyBangBangCheat();
+	
+	// "3141L33T"		-	R1 L1 R2 L1 LEFT R1 R1 TRIANGLE
+	else if ( !_CHEATCMP("T33L1413") )
+		StrongGripCheat();
+	
+	// "S1CD13TR1X"		-	SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS
+	else if ( !_CHEATCMP("X1RT31DC1S") )
+		NastyLimbsCheat();
+#undef _CHEATCMP
+}
+#endif
+
 void CPad::AddToPCCheatString(char c)
 {
 	for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
@@ -858,7 +976,7 @@ void CPad::Update(int16 unk)
 	
 	ProcessPCSpecificStuff();
 	
-	if ( ++iCurrHornHistory >= _TODOCONST(5) )
+	if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
 		iCurrHornHistory = 0;
 
 	bHornHistory[iCurrHornHistory] = GetHorn();
@@ -875,7 +993,7 @@ void CPad::DoCheats(void)
 
 void CPad::DoCheats(int16 unk)
 {
-#ifdef PS2
+#ifdef GTA_PS2_STUFF
 	if ( GetTriangleJustDown() )
 		AddToCheatString('T');
 	
diff --git a/src/core/Pad.h b/src/core/Pad.h
index ca44a9f7..78bfac1d 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -136,6 +136,10 @@ enum
 class CPad
 {
 public:
+	enum
+	{
+		HORNHISTORY_SIZE = 5,
+	};
 	CControllerState NewState;
 	CControllerState OldState;
 	CControllerState PCTempKeyState;
@@ -146,11 +150,11 @@ public:
 	int16 Mode;
 	int16 ShakeDur;
 	uint8 ShakeFreq;
-	bool bHornHistory[5];
+	bool bHornHistory[HORNHISTORY_SIZE];
 	uint8 iCurrHornHistory;
 	uint8 DisablePlayerControls;
 	int8 bApplyBrakes;
-	char _unk[12]; //int32 unk[3];
+	char CheatString[12];
 	char _pad0[3];
 	int32 LastTimeTouched;
 	int32 AverageWeapon;
@@ -161,6 +165,7 @@ public:
 
 	static bool &bDisplayNoControllerMessage;
 	static bool &bObsoleteControllerMessage;
+	static bool bOldDisplayNoControllerMessage;
 	static bool &m_bMapPadOneToPadTwo;
 	
 	static CKeyboardState &OldKeyState;
@@ -172,8 +177,9 @@ public:
 	static CMouseControllerState &PCTempMouseControllerState;
 	
 	
-	
-	
+#ifdef GTA_PS2_STUFF
+	static void Initialise(void);
+#endif
 	void Clear(bool bResetPlayerControls);
 	void ClearMouseHistory();
 	void UpdateMouse();
@@ -181,6 +187,9 @@ public:
 	void StartShake(int16 nDur, uint8 nFreq);
 	void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
 	void StartShake_Train(float fX, float fY);
+#ifdef GTA_PS2_STUFF
+	void AddToCheatString(char c);
+#endif
 	void AddToPCCheatString(char c);
 
 	static void UpdatePads(void);
diff --git a/src/core/PlayerSkin.cpp b/src/core/PlayerSkin.cpp
index bf780666..28879918 100644
--- a/src/core/PlayerSkin.cpp
+++ b/src/core/PlayerSkin.cpp
@@ -106,7 +106,9 @@ CPlayerSkin::GetSkinTexture(const char *texName)
 
 		tex = RwTextureCreate(raster);
 		RwTextureSetName(tex, texName);
+#ifdef FIX_BUGS
 		RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
+#endif
 		RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
 
 		RwImageDestroy(image);
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index afaceb6d..994c94ca 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -17,7 +17,7 @@
 #include "SpecialFX.h"
 
 float &CRadar::m_radarRange = *(float*)0x8E281C;
-CBlip (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(CBlip(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
+sRadarTrace (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(sRadarTrace(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
 CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
 int32 gRadarTxdIds[64];// = (int*)0x6299C0;
 
@@ -87,6 +87,134 @@ int CRadar::TargetMarkerId = -1;
 float CRadar::cachedCos;
 float CRadar::cachedSin;
 
+void ClipRadarTileCoords(int32 &x, int32 &y)
+{
+	if (x < 0)
+		x = 0;
+	if (x > RADAR_NUM_TILES-1)
+		x = RADAR_NUM_TILES-1;
+	if (y < 0)
+		y = 0;
+	if (y > RADAR_NUM_TILES-1)
+		y = RADAR_NUM_TILES-1;
+}
+
+void RequestMapSection(int32 x, int32 y)
+{
+	ClipRadarTileCoords(x, y);
+	CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
+}
+
+void RemoveMapSection(int32 x, int32 y)
+{
+	if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
+		CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
+}
+
+// Transform from section indices to world coordinates
+void GetTextureCorners(int32 x, int32 y, CVector2D *out)
+{
+	x =   x - RADAR_NUM_TILES/2;
+	y = -(y - RADAR_NUM_TILES/2);
+
+	// bottom left
+	out[0].x = RADAR_TILE_SIZE * (x);
+	out[0].y = RADAR_TILE_SIZE * (y - 1);
+
+	// bottom right
+	out[1].x = RADAR_TILE_SIZE * (x + 1);
+	out[1].y = RADAR_TILE_SIZE * (y - 1);
+
+	// top right
+	out[2].x = RADAR_TILE_SIZE * (x + 1);
+	out[2].y = RADAR_TILE_SIZE * (y);
+
+	// top left
+	out[3].x = RADAR_TILE_SIZE * (x);
+	out[3].y = RADAR_TILE_SIZE * (y);
+}
+
+
+bool IsPointInsideRadar(const CVector2D &point)
+{
+	if (point.x < -1.0f || point.x > 1.0f) return false;
+	if (point.y < -1.0f || point.y > 1.0f) return false;
+	return true;
+}
+
+// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
+int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
+{
+	float d1, d2;
+	float t;
+	float x, y;
+	float shortest = 1.0f;
+	int edge = -1;
+
+	// clip against left edge, x = -1.0
+	d1 = -1.0f - p1.x;
+	d2 = -1.0f - p2.x;
+	if (d1 * d2 < 0.0f) {
+		// they are on opposite sides, get point of intersection
+		t = d1 / (d1 - d2);
+		y = (p2.y - p1.y)*t + p1.y;
+		if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+			out.x = -1.0f;
+			out.y = y;
+			edge = 3;
+			shortest = t;
+		}
+	}
+
+	// clip against right edge, x = 1.0
+	d1 = p1.x - 1.0f;
+	d2 = p2.x - 1.0f;
+	if (d1 * d2 < 0.0f) {
+		// they are on opposite sides, get point of intersection
+		t = d1 / (d1 - d2);
+		y = (p2.y - p1.y)*t + p1.y;
+		if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+			out.x = 1.0f;
+			out.y = y;
+			edge = 1;
+			shortest = t;
+		}
+	}
+
+	// clip against top edge, y = -1.0
+	d1 = -1.0f - p1.y;
+	d2 = -1.0f - p2.y;
+	if (d1 * d2 < 0.0f) {
+		// they are on opposite sides, get point of intersection
+		t = d1 / (d1 - d2);
+		x = (p2.x - p1.x)*t + p1.x;
+		if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+			out.y = -1.0f;
+			out.x = x;
+			edge = 0;
+			shortest = t;
+		}
+	}
+
+	// clip against bottom edge, y = 1.0
+	d1 = p1.y - 1.0f;
+	d2 = p2.y - 1.0f;
+	if (d1 * d2 < 0.0f) {
+		// they are on opposite sides, get point of intersection
+		t = d1 / (d1 - d2);
+		x = (p2.x - p1.x)*t + p1.x;
+		if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+			out.y = 1.0f;
+			out.x = x;
+			edge = 2;
+			shortest = t;
+		}
+	}
+
+	return edge;
+}
+
+
 uint8 CRadar::CalculateBlipAlpha(float dist)
 {
 #ifdef MENU_MAP
@@ -889,7 +1017,7 @@ INITSAVEBUF
 	CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
 
 	for (int i = 0; i < NUMRADARBLIPS; i++)
-		ms_RadarTrace[i] = ReadSaveBuf<CBlip>(buf);
+		ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf);
 
 VALIDATESAVEBUF(size);
 }
@@ -922,12 +1050,6 @@ CRadar::LoadTextures()
 	CTxdStore::PopCurrentTxd();
 }
 
-void RemoveMapSection(int32 x, int32 y)
-{
-	if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
-		CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
-}
-
 void CRadar::RemoveRadarSections()
 {
 	for (int i = 0; i < 8; i++)
@@ -935,12 +1057,6 @@ void CRadar::RemoveRadarSections()
 			RemoveMapSection(i, j);
 }
 
-void CRadar::RequestMapSection(int32 x, int32 y)
-{
-	ClipRadarTileCoords(x, y);
-	CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
-}
-
 void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
 {
 	*size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
@@ -1239,121 +1355,6 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
 	out.y = c * y - s * x;
 }
 
-// Transform from section indices to world coordinates
-void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
-{
-	x =   x - RADAR_NUM_TILES/2;
-	y = -(y - RADAR_NUM_TILES/2);
-
-	// bottom left
-	out[0].x = RADAR_TILE_SIZE * (x);
-	out[0].y = RADAR_TILE_SIZE * (y - 1);
-
-	// bottom right
-	out[1].x = RADAR_TILE_SIZE * (x + 1);
-	out[1].y = RADAR_TILE_SIZE * (y - 1);
-
-	// top right
-	out[2].x = RADAR_TILE_SIZE * (x + 1);
-	out[2].y = RADAR_TILE_SIZE * (y);
-
-	// top left
-	out[3].x = RADAR_TILE_SIZE * (x);
-	out[3].y = RADAR_TILE_SIZE * (y);
-}
-
-void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
-{
-	if (x < 0)
-		x = 0;
-	if (x > RADAR_NUM_TILES-1)
-		x = RADAR_NUM_TILES-1;
-	if (y < 0)
-		y = 0;
-	if (y > RADAR_NUM_TILES-1)
-		y = RADAR_NUM_TILES-1;
-}
-
-
-bool CRadar::IsPointInsideRadar(const CVector2D &point)
-{
-	if (point.x < -1.0f || point.x > 1.0f) return false;
-	if (point.y < -1.0f || point.y > 1.0f) return false;
-	return true;
-}
-
-// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
-int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
-{
-	float d1, d2;
-	float t;
-	float x, y;
-	float shortest = 1.0f;
-	int edge = -1;
-
-	// clip against left edge, x = -1.0
-	d1 = -1.0f - p1.x;
-	d2 = -1.0f - p2.x;
-	if (d1 * d2 < 0.0f) {
-		// they are on opposite sides, get point of intersection
-		t = d1 / (d1 - d2);
-		y = (p2.y - p1.y)*t + p1.y;
-		if (y >= -1.0f && y <= 1.0f && t <= shortest) {
-			out.x = -1.0f;
-			out.y = y;
-			edge = 3;
-			shortest = t;
-		}
-	}
-
-	// clip against right edge, x = 1.0
-	d1 = p1.x - 1.0f;
-	d2 = p2.x - 1.0f;
-	if (d1 * d2 < 0.0f) {
-		// they are on opposite sides, get point of intersection
-		t = d1 / (d1 - d2);
-		y = (p2.y - p1.y)*t + p1.y;
-		if (y >= -1.0f && y <= 1.0f && t <= shortest) {
-			out.x = 1.0f;
-			out.y = y;
-			edge = 1;
-			shortest = t;
-		}
-	}
-
-	// clip against top edge, y = -1.0
-	d1 = -1.0f - p1.y;
-	d2 = -1.0f - p2.y;
-	if (d1 * d2 < 0.0f) {
-		// they are on opposite sides, get point of intersection
-		t = d1 / (d1 - d2);
-		x = (p2.x - p1.x)*t + p1.x;
-		if (x >= -1.0f && x <= 1.0f && t <= shortest) {
-			out.y = -1.0f;
-			out.x = x;
-			edge = 0;
-			shortest = t;
-		}
-	}
-
-	// clip against bottom edge, y = 1.0
-	d1 = p1.y - 1.0f;
-	d2 = p2.y - 1.0f;
-	if (d1 * d2 < 0.0f) {
-		// they are on opposite sides, get point of intersection
-		t = d1 / (d1 - d2);
-		x = (p2.x - p1.x)*t + p1.x;
-		if (x >= -1.0f && x <= 1.0f && t <= shortest) {
-			out.y = 1.0f;
-			out.x = x;
-			edge = 2;
-			shortest = t;
-		}
-	}
-
-	return edge;
-}
-
 void
 CRadar::CalculateCachedSinCos()
 {
@@ -1485,8 +1486,14 @@ STARTPATCHES
 	InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
 	InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
 	InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
+	InjectHook(0x4A6020, ClipRadarTileCoords, PATCH_JUMP);
+	InjectHook(0x4A6060, RequestMapSection, PATCH_JUMP);
+	InjectHook(0x4A60A0, RemoveMapSection, PATCH_JUMP);
 	InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
 	InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, PATCH_JUMP);
+	InjectHook(0x4A6160, IsPointInsideRadar, PATCH_JUMP);
+	InjectHook(0x4A61C0, GetTextureCorners, PATCH_JUMP);
+	InjectHook(0x4A6250, LineRadarBoxCollision, PATCH_JUMP);
 	InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
 	InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
 	InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
@@ -1494,8 +1501,6 @@ STARTPATCHES
 	InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
 	InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
 	InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
-
-	InjectHook(0x4A61C0, CRadar::GetTextureCorners, PATCH_JUMP);
-	InjectHook(0x4A6160, CRadar::IsPointInsideRadar, PATCH_JUMP);
-	InjectHook(0x4A6250, CRadar::LineRadarBoxCollision, PATCH_JUMP);
+	//InjectHook(0x4A7000, `global constructor keyed to'Radar.cpp, PATCH_JUMP);
+	//InjectHook(0x4A7260, sRadarTrace::sRadarTrace, PATCH_JUMP);
 ENDPATCHES
diff --git a/src/core/Radar.h b/src/core/Radar.h
index 6d5bb196..27f3a6f0 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -56,7 +56,7 @@ enum
 	BLIP_MODE_SQUARE,
 };
 
-struct CBlip
+struct sRadarTrace
 {
 	uint32 m_nColor;
 	uint32 m_eBlipType; // eBlipType
@@ -71,7 +71,7 @@ struct CBlip
 	uint16 m_eBlipDisplay; // eBlipDisplay
 	uint16 m_eRadarSprite; // eRadarSprite
 };
-static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
+static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
 
 // Values for screen space
 #define RADAR_LEFT (40.0f)
@@ -83,7 +83,7 @@ class CRadar
 {
 public:
 	static float &m_radarRange;
-	static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
+	static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
 	static CSprite2d AsukaSprite;
 	static CSprite2d BombSprite;
 	static CSprite2d CatSprite;
@@ -144,7 +144,6 @@ public:
 	static void LoadAllRadarBlips(uint8 *buf, uint32 size);
 	static void LoadTextures();
 	static void RemoveRadarSections();
-	static void RequestMapSection(int32 x, int32 y);
 	static void SaveAllRadarBlips(uint8*, uint32*);
 	static void SetBlipSprite(int32 i, int32 icon);
 	static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
@@ -161,10 +160,6 @@ public:
 	static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
 	static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
 
-	// no in CRadar in the game:
-	static void GetTextureCorners(int32 x, int32 y, CVector2D *out);
-	static void ClipRadarTileCoords(int32 &x, int32 &y);
-	static bool IsPointInsideRadar(const CVector2D &);
-	static int LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &);
+	// no in CRadar in the game:	
 	static void CalculateCachedSinCos();
 };
diff --git a/src/core/common.h b/src/core/common.h
index b58b93af..9b897cca 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -84,12 +84,14 @@ extern void **rwengine;
 #define DEFAULT_SCREEN_WIDTH (640)
 #define DEFAULT_SCREEN_HEIGHT (448)
 #define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
+#define DEFAULT_VIEWWINDOW (0.7f)
 
 // game uses maximumWidth/Height, but this probably won't work
 // with RW windowed mode
 #define SCREEN_WIDTH ((float)RsGlobal.width)
 #define SCREEN_HEIGHT ((float)RsGlobal.height)
 #define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio())
+#define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
 
 // This scales from PS2 pixel coordinates to the real resolution
 #define SCREEN_STRETCH_X(a)   ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
diff --git a/src/core/config.h b/src/core/config.h
index 198ee946..8dea3216 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -153,6 +153,7 @@ enum Config {
 //#define MASTER
 
 #if defined GTA_PS2
+#	define GTA_PS2_STUFF
 #	define RANDOMSPLASH
 #elif defined GTA_PC
 #	define GTA3_1_1_PATCH
diff --git a/src/core/main.cpp b/src/core/main.cpp
index fb5beee0..93e4c71c 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -1,6 +1,11 @@
 #include "common.h"
+#include "rpmatfx.h"
+#include "rpskin.h"
+#include "rphanim.h"
+#include "rtbmp.h"
 #include "patcher.h"
 #include "main.h"
+#include "CdStream.h"
 #include "General.h"
 #include "RwHelper.h"
 #include "Clouds.h"
@@ -52,9 +57,7 @@
 #include "Debug.h"
 #include "Console.h"
 #include "timebars.h"
-
-#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
-
+#include "GenericGameStorage.h"
 
 GlobalScene &Scene = *(GlobalScene*)0x726768;
 
@@ -68,293 +71,68 @@ char *gString2 = (char*)0x878A40;
 wchar *gUString = (wchar*)0x74B018;
 wchar *gUString2 = (wchar*)0x6EDD70;
 
-bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
-
-
-char version_name[64];
 
 float FramesPerSecond = 30.0f;
 
 bool gbPrintShite = false;
 bool &gbModelViewer = *(bool*)0x95CD93;
 
-bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
-bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
-void DoRWStuffEndOfFrame(void);
+int32 frameCount;
 
-void RenderScene(void);
-void RenderDebugShit(void);
-void RenderEffects(void);
-void Render2dStuff(void);
-void RenderMenus(void);
-void DoFade(void);
-void Render2dStuffAfterFade(void);
+RwRGBA gColourTop;
 
-CSprite2d *LoadSplash(const char *name);
+bool gameAlreadyInitialised;
 
+float NumberOfChunksLoaded;
+#define TOTALNUMCHUNKS 73.0f
+
+bool g_SlowMode = false;
+char version_name[64];
+
+
+void GameInit(void);
+void SystemInit(void);
+void TheGame(void);
 
 extern void (*DebugMenuProcess)(void);
 extern void (*DebugMenuRender)(void);
 void DebugMenuInit(void);
 void DebugMenuPopulate(void);
 
-void PrintGameVersion();
-
-RwRGBA gColourTop;
 
 void
-InitialiseGame(void)
+ValidateVersion()
 {
-	LoadingScreen(nil, nil, "loadsc0");
-	CGame::Initialise("DATA\\GTA3.DAT");
-}
+	int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
+	char buff[128];
 
-#ifndef MASTER
-void
-TheModelViewer(void)
-{
-#ifdef ASPECT_RATIO_SCALE
-	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-	CAnimViewer::Update();
-	CTimer::Update();
-	SetLightsWithTimeOfDayColour(Scene.world);
-	CRenderer::ConstructRenderList();
-	DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
-		CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
-		255);
-
-	CSprite2d::InitPerFrame();
-	CFont::InitPerFrame();
-	DefinedState();
-	CVisibilityPlugins::InitAlphaEntityList();
-	CAnimViewer::Render();
-	Render2dStuff();
-	DoRWStuffEndOfFrame();
-}
-#endif
-
-void
-Idle(void *arg)
-{
-#ifdef ASPECT_RATIO_SCALE
-	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
-	CTimer::Update();
-
-#ifdef TIMEBARS
-	tbInit();
-#endif
-
-	CSprite2d::InitPerFrame();
-	CFont::InitPerFrame();
-
-	// We're basically merging FrontendIdle and Idle (just like TheGame on PS2)
-#ifdef PS2_SAVE_DIALOG
-	// Only exists on PC FrontendIdle, probably some PS2 bug fix
-	if (FrontEndMenuManager.m_bMenuActive)
-		CSprite2d::SetRecipNearClip();
-	
-	if (FrontEndMenuManager.m_bGameNotLoaded) {
-		CPad::UpdatePads();
-		FrontEndMenuManager.Process();
-	} else {
-		CPointLights::InitPerFrame();
-#ifdef TIMEBARS
-		tbStartTimer(0, "CGame::Process");
-#endif
-		CGame::Process();
-#ifdef TIMEBARS
-		tbEndTimer("CGame::Process");
-		tbStartTimer(0, "DMAudio.Service");
-#endif
-		DMAudio.Service();
-
-#ifdef TIMEBARS
-		tbEndTimer("DMAudio.Service");
-#endif
-	}
-
-	if (RsGlobal.quit)
-		return;
-#else
-	CPointLights::InitPerFrame();
-#ifdef TIMEBARS
-	tbStartTimer(0, "CGame::Process");
-#endif
-	CGame::Process();
-#ifdef TIMEBARS
-	tbEndTimer("CGame::Process");
-	tbStartTimer(0, "DMAudio.Service");
-#endif
-
-	DMAudio.Service();
-
-#ifdef TIMEBARS
-	tbEndTimer("DMAudio.Service");
-#endif
-#endif
-
-	if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
-		FrontEndMenuManager.m_bStartGameLoading = true;
-		FrontEndMenuManager.m_bLoadingSavedGame = false;
-		return;
-	}
-
-	if(FrontEndMenuManager.m_bStartGameLoading || b_FoundRecentSavedGameWantToLoad)
-		return;
-
-	SetLightsWithTimeOfDayColour(Scene.world);
-
-	if(arg == nil)
-		return;
-
-	if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
-	   TheCamera.GetScreenFadeStatus() != FADE_2){
-#ifdef GTA_PC
-		if (!FrontEndMenuManager.m_bRenderGameInMenu) {
-			// This is from SA, but it's nice for windowed mode
-			RwV2d pos;
-			pos.x = SCREEN_WIDTH / 2.0f;
-			pos.y = SCREEN_HEIGHT / 2.0f;
-			RsMouseSetPos(&pos);
+	if ( file != -1 )
+	{
+		CFileMgr::Seek(file, 100, SEEK_SET);
+		
+		for ( int i = 0; i < 128; i++ )
+		{
+			CFileMgr::Read(file, &buff[i], sizeof(char));
+			buff[i] -= 23;
+			if ( buff[i] == '\0' )
+				break;
+			CFileMgr::Seek(file, 99, SEEK_CUR);
 		}
-#endif
-#ifdef TIMEBARS
-		tbStartTimer(0, "CnstrRenderList");
-#endif
-		CRenderer::ConstructRenderList();
-#ifdef TIMEBARS
-		tbEndTimer("CnstrRenderList");
-		tbStartTimer(0, "PreRender");
-#endif
-		CRenderer::PreRender();
-#ifdef TIMEBARS
-		tbEndTimer("PreRender");
-#endif
-
-		if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
-			if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
-				return;
-		}else{
-			if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
-						CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
-						255))
-				return;
-		}
-
-		DefinedState();
-
-		// BUG. This has to be done BEFORE RwCameraBeginUpdate
-		RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
-		RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
-
-#ifdef TIMEBARS
-		tbStartTimer(0, "RenderScene");
-#endif
-		RenderScene();
-#ifdef TIMEBARS
-		tbEndTimer("RenderScene");
-#endif
-		RenderDebugShit();
-		RenderEffects();
-
-#ifdef TIMEBARS
-		tbStartTimer(0, "RenderMotionBlur");
-#endif
-		if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
-		   TheCamera.m_ScreenReductionPercentage > 0.0f)
-		        TheCamera.SetMotionBlurAlpha(150);
-		TheCamera.RenderMotionBlur();
-#ifdef TIMEBARS
-		tbEndTimer("RenderMotionBlur");
-		tbStartTimer(0, "Render2dStuff");
-#endif
-		Render2dStuff();
-#ifdef TIMEBARS
-		tbEndTimer("Render2dStuff");
-#endif
-	}else{
-		float viewWindow = DEFAULT_VIEWWINDOW;
-#ifdef ASPECT_RATIO_SCALE
-		CameraSize(Scene.camera, nil, viewWindow, SCREEN_ASPECT_RATIO);
-#else
-		CameraSize(Scene.camera, nil, viewWindow, DEFAULT_ASPECT_RATIO);
-#endif
-		CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
-		RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
-		if(!RsCameraBeginUpdate(Scene.camera))
+		
+		if ( !strncmp(buff, "grandtheftauto3", 15) )
+		{
+			strncpy(version_name, &buff[15], 64);
+			CFileMgr::CloseFile(file);
 			return;
+		}
 	}
 
-#ifdef PS2_SAVE_DIALOG
-	if (FrontEndMenuManager.m_bMenuActive)
-		DefinedState();
-#endif
-#ifdef TIMEBARS
-	tbStartTimer(0, "RenderMenus");
-#endif
-	RenderMenus();
-#ifdef TIMEBARS
-	tbEndTimer("RenderMenus");
-	tbStartTimer(0, "DoFade");
-#endif
-	DoFade();
-#ifdef TIMEBARS
-	tbEndTimer("DoFade");
-	tbStartTimer(0, "Render2dStuff-Fade");
-#endif
-	Render2dStuffAfterFade();
-#ifdef TIMEBARS
-	tbEndTimer("Render2dStuff-Fade");
-#endif
-	CCredits::Render();
-
-#ifdef TIMEBARS
-	tbDisplay();
-#endif
-
-	DoRWStuffEndOfFrame();
-
-//	if(g_SlowMode) 
-//		ProcessSlowMode();
-}
-
-void
-FrontendIdle(void)
-{
-#ifdef ASPECT_RATIO_SCALE
-	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
-	CTimer::Update();
-	CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix
-	CSprite2d::InitPerFrame();
-	CFont::InitPerFrame();
-	CPad::UpdatePads();
-	FrontEndMenuManager.Process();
-
-	if(RsGlobal.quit)
-		return;
-
-	float viewWindow = DEFAULT_VIEWWINDOW;
-#ifdef ASPECT_RATIO_SCALE
-	CameraSize(Scene.camera, nil, viewWindow, SCREEN_ASPECT_RATIO);
-#else
-	CameraSize(Scene.camera, nil, viewWindow, DEFAULT_ASPECT_RATIO);
-#endif
-	CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
-	RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
-	if(!RsCameraBeginUpdate(Scene.camera))
-		return;
-
-	DefinedState(); // seems redundant, but breaks resolution change.
-	RenderMenus();
-	DoFade();
-	Render2dStuffAfterFade();
-//	CFont::DrawFonts(); // redundant
-	DoRWStuffEndOfFrame();
+	LoadingScreen("Invalid version", NULL, NULL);
+	
+	while(true)
+	{
+		;
+	}
 }
 
 bool
@@ -363,7 +141,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
 	CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha);
 	CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha);
 
-	CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+	CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
 	CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
 	RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
 
@@ -381,7 +159,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
 bool
 DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha)
 {
-	CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+	CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
 	CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
 	RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
 
@@ -394,17 +172,6 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16
 	return true;
 }
 
-void
-DoRWStuffEndOfFrame(void)
-{
-	CDebug::DisplayScreenStrings();	// custom
-	CDebug::DebugDisplayTextBuffer();
-	FlushObrsPrintfs();
-	RwCameraEndUpdate(Scene.camera);
-	RsCameraShowRaster(Scene.camera);
-}
-
-
 // This is certainly a very useful function
 void
 DoRWRenderHorizon(void)
@@ -412,127 +179,6 @@ DoRWRenderHorizon(void)
 	CClouds::RenderHorizon();
 }
 
-void
-RenderScene(void)
-{
-	CClouds::Render();
-	DoRWRenderHorizon();
-	CRenderer::RenderRoads();
-	CCoronas::RenderReflections();
-	RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
-	CRenderer::RenderEverythingBarRoads();
-	CRenderer::RenderBoats();
-	DefinedState();
-	CWaterLevel::RenderWater();
-	CRenderer::RenderFadingInEntities();
-	CRenderer::RenderVehiclesButNotBoats();
-	CWeather::RenderRainStreaks();
-}
-
-void
-RenderDebugShit(void)
-{
-	CTheScripts::RenderTheScriptDebugLines();
-	if(gbShowCollisionLines)
-		CRenderer::RenderCollisionLines();
-}
-
-void
-RenderEffects(void)
-{
-	CGlass::Render();
-	CWaterCannons::Render();
-	CSpecialFX::Render();
-	CShadows::RenderStaticShadows();
-	CShadows::RenderStoredShadows();
-	CSkidmarks::Render();
-	CAntennas::Render();
-	CRubbish::Render();
-	CCoronas::Render();
-	CParticle::Render();
-	CPacManPickups::Render();
-	CWeaponEffects::Render();
-	CPointLights::RenderFogEffect();
-	CMovingThings::Render();
-	CRenderer::RenderFirstPersonVehicle();
-}
-
-void
-Render2dStuff(void)
-{
-	RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
-	RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
-	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
-	RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
-	RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
-	RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
-
-	CReplay::Display();
-	CPickups::RenderPickUpText();
-
-	if(TheCamera.m_WideScreenOn)
-		TheCamera.DrawBordersForWideScreen();
-
-	CPed *player = FindPlayerPed();
-	int weaponType = 0;
-	if(player)
-		weaponType = player->GetWeapon()->m_eWeaponType;
-
-	bool firstPersonWeapon = false;
-	int cammode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
-	if(cammode == CCam::MODE_SNIPER ||
-	   cammode == CCam::MODE_SNIPER_RUNABOUT ||
-	   cammode == CCam::MODE_ROCKETLAUNCHER ||
-	   cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT)
-		firstPersonWeapon = true;
-
-	// Draw black border for sniper and rocket launcher
-	if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) && firstPersonWeapon){
-		CRGBA black(0, 0, 0, 255);
-
-		// top and bottom strips
-		if (weaponType == WEAPONTYPE_ROCKETLAUNCHER) {
-			CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(180)), black);
-			CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(170), SCREEN_WIDTH, SCREEN_HEIGHT), black);
-		}
-		else {
-			CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(210)), black);
-			CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(210), SCREEN_WIDTH, SCREEN_HEIGHT), black);
-		}
-		CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH / 2 - SCREEN_SCALE_X(210), SCREEN_HEIGHT), black);
-		CSprite2d::DrawRect(CRect(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(210), 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), black);
-	}
-
-	MusicManager.DisplayRadioStationName();
-	TheConsole.Display();
-/*
-	if(CSceneEdit::m_bEditOn)
-		CSceneEdit::Draw();
-	else
-*/
-		CHud::Draw();
-	CUserDisplay::OnscnTimer.ProcessForDisplay();
-	CMessages::Display();
-	CDarkel::DrawMessages();
-	CGarages::PrintMessages();
-	CPad::PrintErrorMessage();
-	CFont::DrawFonts();
-
-	DebugMenuRender();
-}
-
-void
-RenderMenus(void)
-{
-	if(FrontEndMenuManager.m_bMenuActive)
-		FrontEndMenuManager.DrawFrontEnd();
-}
-
-bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
-bool &StillToFadeOut = *(bool*)0x95CD99;
-uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
-uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
-
 void
 DoFade(void)
 {
@@ -613,6 +259,391 @@ DoFade(void)
 	}
 }
 
+void
+DoRWStuffEndOfFrame(void)
+{
+	CDebug::DisplayScreenStrings();	// custom
+	CDebug::DebugDisplayTextBuffer();
+	FlushObrsPrintfs();
+	RwCameraEndUpdate(Scene.camera);
+	RsCameraShowRaster(Scene.camera);
+}
+
+static RwBool 
+PluginAttach(void)
+{
+	if( !RpWorldPluginAttach() )
+	{
+		printf("Couldn't attach world plugin\n");
+		
+		return FALSE;
+	}
+	
+	if( !RpSkinPluginAttach() )
+	{
+		printf("Couldn't attach RpSkin plugin\n");
+		
+		return FALSE;
+	}
+	
+	if( !RpHAnimPluginAttach() )
+	{
+		printf("Couldn't attach RpHAnim plugin\n");
+		
+		return FALSE;
+	}
+	
+	if( !NodeNamePluginAttach() )
+	{
+		printf("Couldn't attach node name plugin\n");
+		
+		return FALSE;
+	}
+	
+	if( !CVisibilityPlugins::PluginAttach() )
+	{
+		printf("Couldn't attach visibility plugins\n");
+		
+		return FALSE;
+	}
+	
+	if( !RpAnimBlendPluginAttach() )
+	{
+		printf("Couldn't attach RpAnimBlend plugin\n");
+		
+		return FALSE;
+	}
+	
+	if( !RpMatFXPluginAttach() )
+	{
+		printf("Couldn't attach RpMatFX plugin\n");
+		
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static RwBool 
+Initialise3D(void *param)
+{
+	if (RsRwInitialise(param))
+	{
+		//
+		DebugMenuInit();
+		DebugMenuPopulate();
+		//
+
+		return CGame::InitialiseRenderWare();
+	}
+
+	return (FALSE);
+}
+
+static void 
+Terminate3D(void)
+{
+	CGame::ShutdownRenderWare();
+	
+	RsRwTerminate();
+
+	return;
+}
+
+CSprite2d splash;
+int splashTxdId = -1;
+
+CSprite2d*
+LoadSplash(const char *name)
+{
+	RwTexDictionary *txd;
+	char filename[140];
+	RwTexture *tex = nil;
+
+	if(name == nil)
+		return &splash;
+	if(splashTxdId == -1)
+		splashTxdId = CTxdStore::AddTxdSlot("splash");
+
+	txd = CTxdStore::GetSlot(splashTxdId)->texDict;
+	if(txd)
+		tex = RwTexDictionaryFindNamedTexture(txd, name);
+	// if texture is found, splash was already set up below
+
+	if(tex == nil){
+		CFileMgr::SetDir("TXD\\");
+		sprintf(filename, "%s.txd", name);
+		if(splash.m_pTexture)
+			splash.Delete();
+		if(txd)
+			CTxdStore::RemoveTxd(splashTxdId);
+		CTxdStore::LoadTxd(splashTxdId, filename);
+		CTxdStore::AddRef(splashTxdId);
+		CTxdStore::PushCurrentTxd();
+		CTxdStore::SetCurrentTxd(splashTxdId);
+		splash.SetTexture(name);
+		CTxdStore::PopCurrentTxd();
+		CFileMgr::SetDir("");
+	}
+
+	return &splash;
+}
+
+void
+DestroySplashScreen(void)
+{
+	splash.Delete();
+	if(splashTxdId != -1)
+		CTxdStore::RemoveTxdSlot(splashTxdId);
+	splashTxdId = -1;
+}
+
+char*
+GetRandomSplashScreen(void)
+{
+	int index;
+	static int index2 = 0;
+	static char splashName[128];
+	static int splashIndex[24] = {
+		25, 22, 4, 13,
+		1, 21, 14, 16,
+		10, 12, 5, 9,
+		11, 18, 3, 2,
+		19, 23, 7, 17,
+		15, 6, 8, 20
+	};
+
+	index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
+	index2++;
+	if(index2 == 6)
+		index2 = 0;
+	sprintf(splashName, "loadsc%d", index);
+	return splashName;
+}
+
+char*
+GetLevelSplashScreen(int level)
+{
+	static char *splashScreens[4] = {
+		nil,
+		"splash1",
+		"splash2",
+		"splash3",
+	};
+
+	return splashScreens[level];
+}
+
+void
+ResetLoadingScreenBar()
+{
+	NumberOfChunksLoaded = 0.0f;
+}
+
+// TODO: compare with PS2
+void
+LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
+{
+	CSprite2d *splash;
+
+#ifndef RANDOMSPLASH
+	if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
+		splashscreen = "mainsc2";
+	else
+		splashscreen = "mainsc1";
+#endif
+
+	splash = LoadSplash(splashscreen);
+
+#ifndef GTA_PS2
+	if(RsGlobal.quit)
+		return;
+#endif
+
+	if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){
+		CSprite2d::SetRecipNearClip();
+		CSprite2d::InitPerFrame();
+		CFont::InitPerFrame();
+		DefinedState();
+		RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+		splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
+
+		if(str1){
+			NumberOfChunksLoaded += 1;
+
+			float hpos = SCREEN_SCALE_X(40);
+			float length = SCREEN_WIDTH - SCREEN_SCALE_X(100);
+			float vpos = SCREEN_HEIGHT - SCREEN_SCALE_Y(13);
+			float height = SCREEN_SCALE_Y(7);
+			CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255));
+
+			length *= NumberOfChunksLoaded/TOTALNUMCHUNKS;
+			CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255));
+
+			// this is done by the game but is unused
+			CFont::SetScale(SCREEN_SCALE_X(2), SCREEN_SCALE_Y(2));
+			CFont::SetPropOn();
+			CFont::SetRightJustifyOn();
+			CFont::SetFontStyle(FONT_HEADING);
+
+#ifdef CHATTYSPLASH
+			// my attempt
+			static wchar tmpstr[80];
+			float yscale = SCREEN_SCALE_Y(0.9f);
+			vpos -= 45*yscale;
+			CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale);
+			CFont::SetPropOn();
+			CFont::SetRightJustifyOff();
+			CFont::SetFontStyle(FONT_BANK);
+			CFont::SetColor(CRGBA(255, 255, 255, 255));
+			AsciiToUnicode(str1, tmpstr);
+			CFont::PrintString(hpos, vpos, tmpstr);
+			vpos += 22*yscale;
+			AsciiToUnicode(str2, tmpstr);
+			CFont::PrintString(hpos, vpos, tmpstr);
+#endif
+		}
+
+		CFont::DrawFonts();
+ 		DoRWStuffEndOfFrame();
+	}
+}
+
+void
+LoadingIslandScreen(const char *levelName)
+{
+	CSprite2d *splash;
+	wchar *name;
+	char str[100];
+	wchar wstr[80];
+	CRGBA col;
+
+	splash = LoadSplash(nil);
+	name = TheText.Get(levelName);
+	if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
+		return;
+
+	CSprite2d::SetRecipNearClip();
+	CSprite2d::InitPerFrame();
+	CFont::InitPerFrame();
+	DefinedState();
+	col = CRGBA(255, 255, 255, 255);
+	splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col, col, col, col);
+	CFont::SetBackgroundOff();
+	CFont::SetScale(1.5f, 1.5f);
+	CFont::SetPropOn();
+	CFont::SetRightJustifyOn();
+	CFont::SetRightJustifyWrap(150.0f);
+	CFont::SetFontStyle(FONT_HEADING);
+	sprintf(str, "WELCOME TO");
+	AsciiToUnicode(str, wstr);
+	CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+	CFont::SetDropShadowPosition(3);
+	CFont::SetColor(CRGBA(243, 237, 71, 255));
+	CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
+	CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
+	TextCopy(wstr, name);
+	TheText.UpperCase(wstr);
+	CFont::SetColor(CRGBA(243, 237, 71, 255));
+	CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
+	CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
+	CFont::DrawFonts();
+	DoRWStuffEndOfFrame();
+}
+
+void
+ProcessSlowMode(void)
+{  
+	int16 lX = CPad::GetPad(0)->NewState.LeftStickX;
+	int16 lY = CPad::GetPad(0)->NewState.LeftStickY;
+	int16 rX = CPad::GetPad(0)->NewState.RightStickX;
+	int16 rY = CPad::GetPad(0)->NewState.RightStickY;
+	int16 L1 = CPad::GetPad(0)->NewState.LeftShoulder1;
+	int16 L2 = CPad::GetPad(0)->NewState.LeftShoulder2;
+	int16 R1 = CPad::GetPad(0)->NewState.RightShoulder1;
+	int16 R2 = CPad::GetPad(0)->NewState.RightShoulder2;
+	int16 up = CPad::GetPad(0)->NewState.DPadUp;
+	int16 down = CPad::GetPad(0)->NewState.DPadDown;
+	int16 left = CPad::GetPad(0)->NewState.DPadLeft;
+	int16 right = CPad::GetPad(0)->NewState.DPadRight;
+	int16 start = CPad::GetPad(0)->NewState.Start;
+	int16 select = CPad::GetPad(0)->NewState.Select;
+	int16 square = CPad::GetPad(0)->NewState.Square;
+	int16 triangle = CPad::GetPad(0)->NewState.Triangle;
+	int16 cross = CPad::GetPad(0)->NewState.Cross;
+	int16 circle = CPad::GetPad(0)->NewState.Circle;
+	int16 L3 = CPad::GetPad(0)->NewState.LeftShock;
+	int16 R3 = CPad::GetPad(0)->NewState.RightShock;
+	int16 networktalk = CPad::GetPad(0)->NewState.NetworkTalk;
+	int16 stop = true;
+	
+	do
+	{
+		if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
+			break;
+		
+		if ( stop )
+		{
+			CTimer::Stop();
+			stop = false;
+		}
+		
+		CPad::UpdatePads();
+		
+		RwCameraBeginUpdate(Scene.camera);
+		RwCameraEndUpdate(Scene.camera);
+		
+		if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
+			break;
+	
+	} while (!CPad::GetPad(1)->GetRightShoulder1());
+	
+	
+	CPad::GetPad(0)->OldState.LeftStickX = lX;
+	CPad::GetPad(0)->OldState.LeftStickY = lY;
+	CPad::GetPad(0)->OldState.RightStickX = rX;
+	CPad::GetPad(0)->OldState.RightStickY = rY;
+	CPad::GetPad(0)->OldState.LeftShoulder1 = L1;
+	CPad::GetPad(0)->OldState.LeftShoulder2 = L2;
+	CPad::GetPad(0)->OldState.RightShoulder1 = R1;
+	CPad::GetPad(0)->OldState.RightShoulder2 = R2;
+	CPad::GetPad(0)->OldState.DPadUp = up;
+	CPad::GetPad(0)->OldState.DPadDown = down;
+	CPad::GetPad(0)->OldState.DPadLeft = left;
+	CPad::GetPad(0)->OldState.DPadRight = right;
+	CPad::GetPad(0)->OldState.Start = start;
+	CPad::GetPad(0)->OldState.Select = select;
+	CPad::GetPad(0)->OldState.Square = square;
+	CPad::GetPad(0)->OldState.Triangle = triangle;
+	CPad::GetPad(0)->OldState.Cross = cross;
+	CPad::GetPad(0)->OldState.Circle = circle;
+	CPad::GetPad(0)->OldState.LeftShock = L3;
+	CPad::GetPad(0)->OldState.RightShock = R3;
+	CPad::GetPad(0)->OldState.NetworkTalk = networktalk;
+	CPad::GetPad(0)->NewState.LeftStickX = lX;
+	CPad::GetPad(0)->NewState.LeftStickY = lY;
+	CPad::GetPad(0)->NewState.RightStickX = rX;
+	CPad::GetPad(0)->NewState.RightStickY = rY;
+	CPad::GetPad(0)->NewState.LeftShoulder1 = L1;
+	CPad::GetPad(0)->NewState.LeftShoulder2 = L2;
+	CPad::GetPad(0)->NewState.RightShoulder1 = R1;
+	CPad::GetPad(0)->NewState.RightShoulder2 = R2;
+	CPad::GetPad(0)->NewState.DPadUp = up;
+	CPad::GetPad(0)->NewState.DPadDown = down;
+	CPad::GetPad(0)->NewState.DPadLeft = left;
+	CPad::GetPad(0)->NewState.DPadRight = right;
+	CPad::GetPad(0)->NewState.Start = start;
+	CPad::GetPad(0)->NewState.Select = select;
+	CPad::GetPad(0)->NewState.Square = square;
+	CPad::GetPad(0)->NewState.Triangle = triangle;
+	CPad::GetPad(0)->NewState.Cross = cross;
+	CPad::GetPad(0)->NewState.Circle = circle;
+	CPad::GetPad(0)->NewState.LeftShock = L3;
+	CPad::GetPad(0)->NewState.RightShock = R3;
+	CPad::GetPad(0)->NewState.NetworkTalk = networktalk;
+}
+
+
 float FramesPerSecondCounter;
 int32 FrameSamples;
 
@@ -736,309 +767,369 @@ DisplayGameDebugText()
 }
 #endif
 
+void
+RenderScene(void)
+{
+	CClouds::Render();
+	DoRWRenderHorizon();
+	CRenderer::RenderRoads();
+	CCoronas::RenderReflections();
+	RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+	CRenderer::RenderEverythingBarRoads();
+	CRenderer::RenderBoats();
+	DefinedState();
+	CWaterLevel::RenderWater();
+	CRenderer::RenderFadingInEntities();
+	CRenderer::RenderVehiclesButNotBoats();
+	CWeather::RenderRainStreaks();
+}
+
+void
+RenderDebugShit(void)
+{
+	CTheScripts::RenderTheScriptDebugLines();
+	if(gbShowCollisionLines)
+		CRenderer::RenderCollisionLines();
+}
+
+void
+RenderEffects(void)
+{
+	CGlass::Render();
+	CWaterCannons::Render();
+	CSpecialFX::Render();
+	CShadows::RenderStaticShadows();
+	CShadows::RenderStoredShadows();
+	CSkidmarks::Render();
+	CAntennas::Render();
+	CRubbish::Render();
+	CCoronas::Render();
+	CParticle::Render();
+	CPacManPickups::Render();
+	CWeaponEffects::Render();
+	CPointLights::RenderFogEffect();
+	CMovingThings::Render();
+	CRenderer::RenderFirstPersonVehicle();
+}
+
+void
+Render2dStuff(void)
+{
+	RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+	RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+	RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+	RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+	RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+
+	CReplay::Display();
+	CPickups::RenderPickUpText();
+
+	if(TheCamera.m_WideScreenOn)
+		TheCamera.DrawBordersForWideScreen();
+
+	CPed *player = FindPlayerPed();
+	int weaponType = 0;
+	if(player)
+		weaponType = player->GetWeapon()->m_eWeaponType;
+
+	bool firstPersonWeapon = false;
+	int cammode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+	if(cammode == CCam::MODE_SNIPER ||
+	   cammode == CCam::MODE_SNIPER_RUNABOUT ||
+	   cammode == CCam::MODE_ROCKETLAUNCHER ||
+	   cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT)
+		firstPersonWeapon = true;
+
+	// Draw black border for sniper and rocket launcher
+	if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) && firstPersonWeapon){
+		CRGBA black(0, 0, 0, 255);
+
+		// top and bottom strips
+		if (weaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+			CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(180)), black);
+			CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(170), SCREEN_WIDTH, SCREEN_HEIGHT), black);
+		}
+		else {
+			CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(210)), black);
+			CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(210), SCREEN_WIDTH, SCREEN_HEIGHT), black);
+		}
+		CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH / 2 - SCREEN_SCALE_X(210), SCREEN_HEIGHT), black);
+		CSprite2d::DrawRect(CRect(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(210), 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), black);
+	}
+
+	MusicManager.DisplayRadioStationName();
+	TheConsole.Display();
+/*
+	if(CSceneEdit::m_bEditOn)
+		CSceneEdit::Draw();
+	else
+*/
+		CHud::Draw();
+	CUserDisplay::OnscnTimer.ProcessForDisplay();
+	CMessages::Display();
+	CDarkel::DrawMessages();
+	CGarages::PrintMessages();
+	CPad::PrintErrorMessage();
+	CFont::DrawFonts();
+
+	DebugMenuRender();
+}
+
+void
+RenderMenus(void)
+{
+#ifdef PS2
+	if (FrontEndMenuManager.m_bWantToDraw)
+	{
+		gMainHeap.PushMemId(_TODOCONST(17));
+		FrontEndMenuManager.DrawFrontEnd();
+		gMainHeap.PopMemId();
+	}
+#else
+	if(FrontEndMenuManager.m_bMenuActive)
+		FrontEndMenuManager.DrawFrontEnd();
+#endif
+}
+
 void
 Render2dStuffAfterFade(void)
 {
 #ifndef MASTER
 	DisplayGameDebugText();
-	//PrintGameVersion();
 #endif
 
 	CHud::DrawAfterFade();
 	CFont::DrawFonts();
 }
 
-CSprite2d splash;
-int splashTxdId = -1;
-
-CSprite2d*
-LoadSplash(const char *name)
-{
-	RwTexDictionary *txd;
-	char filename[140];
-	RwTexture *tex = nil;
-
-	if(name == nil)
-		return &splash;
-	if(splashTxdId == -1)
-		splashTxdId = CTxdStore::AddTxdSlot("splash");
-
-	txd = CTxdStore::GetSlot(splashTxdId)->texDict;
-	if(txd)
-		tex = RwTexDictionaryFindNamedTexture(txd, name);
-	// if texture is found, splash was already set up below
-
-	if(tex == nil){
-		CFileMgr::SetDir("TXD\\");
-		sprintf(filename, "%s.txd", name);
-		if(splash.m_pTexture)
-			splash.Delete();
-		if(txd)
-			CTxdStore::RemoveTxd(splashTxdId);
-		CTxdStore::LoadTxd(splashTxdId, filename);
-		CTxdStore::AddRef(splashTxdId);
-		CTxdStore::PushCurrentTxd();
-		CTxdStore::SetCurrentTxd(splashTxdId);
-		splash.SetTexture(name);
-		CTxdStore::PopCurrentTxd();
-		CFileMgr::SetDir("");
-	}
-
-	return &splash;
-}
-
 void
-DestroySplashScreen(void)
+Idle(void *arg)
 {
-	splash.Delete();
-	if(splashTxdId != -1)
-		CTxdStore::RemoveTxdSlot(splashTxdId);
-	splashTxdId = -1;
-}
-
-float NumberOfChunksLoaded;
-#define TOTALNUMCHUNKS 73.0f
-
-void
-ResetLoadingScreenBar()
-{
-	NumberOfChunksLoaded = 0.0f;
-}
-
-// TODO: compare with PS2
-void
-LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
-{
-	CSprite2d *splash;
-
-#ifndef RANDOMSPLASH
-	if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
-		splashscreen = "mainsc2";
-	else
-		splashscreen = "mainsc1";
+#ifdef ASPECT_RATIO_SCALE
+	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
 #endif
 
-	splash = LoadSplash(splashscreen);
+	CTimer::Update();
+
+#ifdef TIMEBARS
+	tbInit();
+#endif
+
+	CSprite2d::InitPerFrame();
+	CFont::InitPerFrame();
+
+	// We're basically merging FrontendIdle and Idle (just like TheGame on PS2)
+#ifdef PS2_SAVE_DIALOG
+	// Only exists on PC FrontendIdle, probably some PS2 bug fix
+	if (FrontEndMenuManager.m_bMenuActive)
+		CSprite2d::SetRecipNearClip();
+	
+	if (FrontEndMenuManager.m_bGameNotLoaded) {
+		CPad::UpdatePads();
+		FrontEndMenuManager.Process();
+	} else {
+		CPointLights::InitPerFrame();
+#ifdef TIMEBARS
+		tbStartTimer(0, "CGame::Process");
+#endif
+		CGame::Process();
+#ifdef TIMEBARS
+		tbEndTimer("CGame::Process");
+		tbStartTimer(0, "DMAudio.Service");
+#endif
+		DMAudio.Service();
+
+#ifdef TIMEBARS
+		tbEndTimer("DMAudio.Service");
+#endif
+	}
+
+	if (RsGlobal.quit)
+		return;
+#else
+	CPointLights::InitPerFrame();
+#ifdef TIMEBARS
+	tbStartTimer(0, "CGame::Process");
+#endif
+	CGame::Process();
+#ifdef TIMEBARS
+	tbEndTimer("CGame::Process");
+	tbStartTimer(0, "DMAudio.Service");
+#endif
+
+	DMAudio.Service();
+
+#ifdef TIMEBARS
+	tbEndTimer("DMAudio.Service");
+#endif
+#endif
+
+	if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
+		FrontEndMenuManager.m_bWantToRestart = true;
+		FrontEndMenuManager.m_bWantToLoad = false;
+		return;
+	}
+
+	if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+		return;
+
+	SetLightsWithTimeOfDayColour(Scene.world);
+
+	if(arg == nil)
+		return;
+
+	if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
+	   TheCamera.GetScreenFadeStatus() != FADE_2)
+	{
+#ifdef GTA_PC
+		if (!FrontEndMenuManager.m_bRenderGameInMenu) {
+			// This is from SA, but it's nice for windowed mode
+			RwV2d pos;
+			pos.x = SCREEN_WIDTH / 2.0f;
+			pos.y = SCREEN_HEIGHT / 2.0f;
+			RsMouseSetPos(&pos);
+		}
+#endif
+#ifdef TIMEBARS
+		tbStartTimer(0, "CnstrRenderList");
+#endif
+		CRenderer::ConstructRenderList();
+#ifdef TIMEBARS
+		tbEndTimer("CnstrRenderList");
+		tbStartTimer(0, "PreRender");
+#endif
+		CRenderer::PreRender();
+#ifdef TIMEBARS
+		tbEndTimer("PreRender");
+#endif
+
+		if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
+			if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
+				return;
+		}else{
+			if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
+						CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
+						255))
+				return;
+		}
+
+		DefinedState();
+
+		// BUG. This has to be done BEFORE RwCameraBeginUpdate
+		RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+		RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+
+#ifdef TIMEBARS
+		tbStartTimer(0, "RenderScene");
+#endif
+		RenderScene();
+#ifdef TIMEBARS
+		tbEndTimer("RenderScene");
+#endif
+		RenderDebugShit();
+		RenderEffects();
+
+#ifdef TIMEBARS
+		tbStartTimer(0, "RenderMotionBlur");
+#endif
+		if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
+		   TheCamera.m_ScreenReductionPercentage > 0.0f)
+		        TheCamera.SetMotionBlurAlpha(150);
+		TheCamera.RenderMotionBlur();
+#ifdef TIMEBARS
+		tbEndTimer("RenderMotionBlur");
+		tbStartTimer(0, "Render2dStuff");
+#endif
+		Render2dStuff();
+#ifdef TIMEBARS
+		tbEndTimer("Render2dStuff");
+#endif
+	}else{
+#ifdef ASPECT_RATIO_SCALE
+		CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+#else
+		CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+#endif
+		CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+		RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+		if(!RsCameraBeginUpdate(Scene.camera))
+			return;
+	}
+
+#ifdef PS2_SAVE_DIALOG
+	if (FrontEndMenuManager.m_bMenuActive)
+		DefinedState();
+#endif
+#ifdef TIMEBARS
+	tbStartTimer(0, "RenderMenus");
+#endif
+	RenderMenus();
+#ifdef TIMEBARS
+	tbEndTimer("RenderMenus");
+	tbStartTimer(0, "DoFade");
+#endif
+	DoFade();
+#ifdef TIMEBARS
+	tbEndTimer("DoFade");
+	tbStartTimer(0, "Render2dStuff-Fade");
+#endif
+	Render2dStuffAfterFade();
+#ifdef TIMEBARS
+	tbEndTimer("Render2dStuff-Fade");
+#endif
+	CCredits::Render();
+
+#ifdef TIMEBARS
+	tbDisplay();
+#endif
+
+	DoRWStuffEndOfFrame();
+
+	if(g_SlowMode) 
+		ProcessSlowMode();
+}
+
+void
+FrontendIdle(void)
+{
+#ifdef ASPECT_RATIO_SCALE
+	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
+#endif
+
+	CTimer::Update();
+	CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix
+	CSprite2d::InitPerFrame();
+	CFont::InitPerFrame();
+	CPad::UpdatePads();
+	FrontEndMenuManager.Process();
 
 	if(RsGlobal.quit)
 		return;
 
-	if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){
-		CSprite2d::SetRecipNearClip();
-		CSprite2d::InitPerFrame();
-		CFont::InitPerFrame();
-		DefinedState();
-		RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
-		splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
-
-		if(str1){
-			NumberOfChunksLoaded += 1;
-
-			float hpos = SCREEN_SCALE_X(40);
-			float length = SCREEN_WIDTH - SCREEN_SCALE_X(100);
-			float vpos = SCREEN_HEIGHT - SCREEN_SCALE_Y(13);
-			float height = SCREEN_SCALE_Y(7);
-			CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255));
-
-			length *= NumberOfChunksLoaded/TOTALNUMCHUNKS;
-			CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255));
-
-			// this is done by the game but is unused
-			CFont::SetScale(SCREEN_SCALE_X(2), SCREEN_SCALE_Y(2));
-			CFont::SetPropOn();
-			CFont::SetRightJustifyOn();
-			CFont::SetFontStyle(FONT_HEADING);
-
-#ifdef CHATTYSPLASH
-			// my attempt
-			static wchar tmpstr[80];
-			float yscale = SCREEN_SCALE_Y(0.9f);
-			vpos -= 45*yscale;
-			CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale);
-			CFont::SetPropOn();
-			CFont::SetRightJustifyOff();
-			CFont::SetFontStyle(FONT_BANK);
-			CFont::SetColor(CRGBA(255, 255, 255, 255));
-			AsciiToUnicode(str1, tmpstr);
-			CFont::PrintString(hpos, vpos, tmpstr);
-			vpos += 22*yscale;
-			AsciiToUnicode(str2, tmpstr);
-			CFont::PrintString(hpos, vpos, tmpstr);
+#ifdef ASPECT_RATIO_SCALE
+	CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+#else
+	CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
 #endif
-		}
-
-		CFont::DrawFonts();
- 		DoRWStuffEndOfFrame();
-	}
-}
-
-void
-LoadingIslandScreen(const char *levelName)
-{
-	CSprite2d *splash;
-	wchar *name;
-	char str[100];
-	wchar wstr[80];
-	CRGBA col;
-
-	splash = LoadSplash(nil);
-	name = TheText.Get(levelName);
-	if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
+	CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+	RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+	if(!RsCameraBeginUpdate(Scene.camera))
 		return;
 
-	CSprite2d::SetRecipNearClip();
-	CSprite2d::InitPerFrame();
-	CFont::InitPerFrame();
-	DefinedState();
-	col = CRGBA(255, 255, 255, 255);
-	splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col, col, col, col);
-	CFont::SetBackgroundOff();
-	CFont::SetScale(1.5f, 1.5f);
-	CFont::SetPropOn();
-	CFont::SetRightJustifyOn();
-	CFont::SetRightJustifyWrap(150.0f);
-	CFont::SetFontStyle(FONT_HEADING);
-	sprintf(str, "WELCOME TO");
-	AsciiToUnicode(str, wstr);
-	CFont::SetDropColor(CRGBA(0, 0, 0, 255));
-	CFont::SetDropShadowPosition(3);
-	CFont::SetColor(CRGBA(243, 237, 71, 255));
-	CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
-	CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
-	TextCopy(wstr, name);
-	TheText.UpperCase(wstr);
-	CFont::SetColor(CRGBA(243, 237, 71, 255));
-	CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
-	CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
-	CFont::DrawFonts();
+	DefinedState(); // seems redundant, but breaks resolution change.
+	RenderMenus();
+	DoFade();
+	Render2dStuffAfterFade();
+//	CFont::DrawFonts(); // redundant
 	DoRWStuffEndOfFrame();
 }
 
-char*
-GetLevelSplashScreen(int level)
+void
+InitialiseGame(void)
 {
-	static char *splashScreens[4] = {
-		nil,
-		"splash1",
-		"splash2",
-		"splash3",
-	};
-
-	return splashScreens[level];
-}
-
-char*
-GetRandomSplashScreen(void)
-{
-	int index;
-	static int index2 = 0;
-	static char splashName[128];
-	static int splashIndex[24] = {
-		25, 22, 4, 13,
-		1, 21, 14, 16,
-		10, 12, 5, 9,
-		11, 18, 3, 2,
-		19, 23, 7, 17,
-		15, 6, 8, 20
-	};
-
-	index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
-	index2++;
-	if(index2 == 6)
-		index2 = 0;
-	sprintf(splashName, "loadsc%d", index);
-	return splashName;
-}
-
-#include "rwcore.h"
-#include "rpworld.h"
-#include "rpmatfx.h"
-#include "rpskin.h"
-#include "rphanim.h"
-#include "rtbmp.h"
-
-_TODO("temp, move this includes out of here")
-
-static RwBool 
-PluginAttach(void)
-{
-	if( !RpWorldPluginAttach() )
-	{
-		printf("Couldn't attach world plugin\n");
-		
-		return FALSE;
-	}
-	
-	if( !RpSkinPluginAttach() )
-	{
-		printf("Couldn't attach RpSkin plugin\n");
-		
-		return FALSE;
-	}
-	
-	if( !RpHAnimPluginAttach() )
-	{
-		printf("Couldn't attach RpHAnim plugin\n");
-		
-		return FALSE;
-	}
-	
-	if( !NodeNamePluginAttach() )
-	{
-		printf("Couldn't attach node name plugin\n");
-		
-		return FALSE;
-	}
-	
-	if( !CVisibilityPlugins::PluginAttach() )
-	{
-		printf("Couldn't attach visibility plugins\n");
-		
-		return FALSE;
-	}
-	
-	if( !RpAnimBlendPluginAttach() )
-	{
-		printf("Couldn't attach RpAnimBlend plugin\n");
-		
-		return FALSE;
-	}
-	
-	if( !RpMatFXPluginAttach() )
-	{
-		printf("Couldn't attach RpMatFX plugin\n");
-		
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static RwBool 
-Initialise3D(void *param)
-{
-	if (RsRwInitialise(param))
-	{
-		//
-		DebugMenuInit();
-		DebugMenuPopulate();
-		//
-
-		return CGame::InitialiseRenderWare();
-	}
-
-	return (FALSE);
-}
-
-
-static void 
-Terminate3D(void)
-{
-	CGame::ShutdownRenderWare();
-	
-	RsRwTerminate();
-
-	return;
+	LoadingScreen(nil, nil, "loadsc0");
+	CGame::Initialise("DATA\\GTA3.DAT");
 }
 
 RsEventStatus
@@ -1056,7 +1147,7 @@ AppEventHandler(RsEvent event, void *param)
 		{
 											
 			CameraSize(Scene.camera, (RwRect *)param,
-				DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+				SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
 			
 			return rsEVENTPROCESSED;
 		}
@@ -1133,58 +1224,615 @@ AppEventHandler(RsEvent event, void *param)
 	}
 }
 
-void PrintGameVersion()
+#ifndef MASTER
+void
+TheModelViewer(void)
 {
-	CFont::SetPropOn();
-	CFont::SetBackgroundOff();
-	CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.5f));
-	CFont::SetCentreOff();
-	CFont::SetRightJustifyOff();
-	CFont::SetBackGroundOnlyTextOff();
-	CFont::SetFontStyle(FONT_BANK);
-	CFont::SetWrapx(SCREEN_WIDTH);
-	CFont::SetDropShadowPosition(0);
-	CFont::SetDropColor(CRGBA(0, 0, 0, 255));
-	CFont::SetColor(CRGBA(235, 170, 50, 255));
+#if (defined(GTA_PS2) || defined(GTA_XBOX))
+	//TODO
+#else
+#ifdef ASPECT_RATIO_SCALE
+	CDraw::SetAspectRatio(CDraw::FindAspectRatio());
+#endif
+	CAnimViewer::Update();
+	CTimer::Update();
+	SetLightsWithTimeOfDayColour(Scene.world);
+	CRenderer::ConstructRenderList();
+	DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
+		CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
+		255);
 
-	strcpy(gString, "RE3");
-	AsciiToUnicode(gString, gUString);
-	CFont::PrintString(SCREEN_SCALE_X(10.5f), SCREEN_SCALE_Y(8.0f), gUString);
+	CSprite2d::InitPerFrame();
+	CFont::InitPerFrame();
+	DefinedState();
+	CVisibilityPlugins::InitAlphaEntityList();
+	CAnimViewer::Render();
+	Render2dStuff();
+	DoRWStuffEndOfFrame();
+#endif
+}
+#endif
+
+void TheGame(void)
+{
+	printf("Into TheGame!!!\n");
+
+#ifdef GTA_PS2
+	gMainHeap.PushMemId(_TODOCONST(1));
+#endif
+
+	CTimer::Initialise();
+
+#ifdef GTA_PS2
+	CGame::Initialise();
+#else
+	CGame::Initialise("DATA\\GTA3.DAT");
+#endif
+
+	char *splash = GetRandomSplashScreen(); // inlined here
+
+	LoadingScreen("Starting Game", NULL, splash);
+
+#ifdef GTA_PS2
+	if (   TheMemoryCard.CheckCardInserted(_TODOCONST(0)) == _TODOCONST(26)
+		&& TheMemoryCard.ChangeDirectory(_TODOCONST(0), TheMemoryCard.field154)
+		&& TheMemoryCard.FindMostRecentFileName(_TODOCONST(0), TheMemoryCard.field37) == 1
+		&& TheMemoryCard.CheckDataNotCorrupt(TheMemoryCard.field37))
+	{
+		strcpy(TheMemoryCard.LoadFileName, TheMemoryCard.field37);
+		TheMemoryCard.b_FoundRecentSavedGameWantToLoad = true;
+
+		if (CMenuManager::m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad())
+		{
+			CMenuManager::m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad();
+			TheText.Unload();
+			TheText.Load();
+		}
+
+		CGame::currLevel = TheMemoryCard.GetLevelToLoad();
+	}
+#else
+	//TODO
+#endif
+
+	while (true)
+	{
+#ifdef PS2
+		if (TheMemoryCard.m_bWantToLoad)
+#else
+		if (FrontEndMenuManager.m_bWantToLoad)
+#endif
+		{
+			char *splash1 = GetLevelSplashScreen(CGame::currLevel);
+			LoadSplash(splash1);
+		}
+
+#ifdef PS2
+		TheMemoryCard.m_bWantToLoad = false;
+#else
+		FrontEndMenuManager.m_bWantToLoad = false;
+#endif
+
+		CTimer::Update();
+
+#ifdef PS2
+		while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad))
+#else
+		while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad))
+#endif
+		{
+			CSprite2d::InitPerFrame();
+			CFont::InitPerFrame();
+
+#ifdef GTA_PS2
+			gMainHeap.PushMemId(_TODOCONST(12));
+#endif
+			CPointLights::NumLights = 0;
+			CGame::Process();
+#ifdef GTA_PS2
+			gMainHeap.PopMemId();
+#endif
+
+			DMAudio.Service();
+
+			if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing())
+			{
+#ifdef PS2
+				TheMemoryCard.m_bWantToLoad = false;
+#else
+				FrontEndMenuManager.m_bWantToLoad = false;
+#endif
+				FrontEndMenuManager.m_bWantToRestart = true;
+				break;
+			}
+
+#ifdef PS2
+			if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+			if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+#endif
+				break;
+
+			SetLightsWithTimeOfDayColour(Scene.world);
+#ifdef GTA_PS2
+			gMainHeap.PushMemId(_TODOCONST(15));
+#endif
+
+			if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 )
+			{
+#ifdef GTA_PS2
+				gMainHeap.PushMemId(_TODOCONST(11));
+#endif
+				CRenderer::ConstructRenderList();
+				CRenderer::PreRender();
+#ifdef GTA_PS2
+				gMainHeap.PopMemId();
+#endif
+
+				if (CWeather::LightningFlash && !CCullZones::CamNoRain())
+					DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255);
+				else
+					DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255);
+
+				DefinedState();
+				RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+				RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+
+				RenderScene();
+				RenderDebugShit();
+				RenderEffects();
+
+				if ((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) && TheCamera.m_ScreenReductionPercentage > 0.0f)
+					TheCamera.SetMotionBlurAlpha(150);
+				TheCamera.RenderMotionBlur();
+
+				Render2dStuff();
+			}
+			else
+			{
+				CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+				CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+				RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+				if (!RsCameraBeginUpdate(Scene.camera))
+					break;
+			}
+
+			RenderMenus();
+
+#ifdef PS2
+			if (TheMemoryCard.m_bWantToLoad)
+#else
+			if (FrontEndMenuManager.m_bWantToLoad)
+#endif
+			{
+#ifdef GTA_PS2
+				gMainHeap.PopMemId();
+#endif
+				break;
+			}
+
+			DoFade();
+			Render2dStuffAfterFade();
+			CCredits::Render();
+
+			DoRWStuffEndOfFrame();
+
+			while (frameCount < 2)
+				;
+
+			frameCount = 0;
+
+			CTimer::Update();
+
+#ifdef GTA_PS2
+			gMainHeap.PopMemId();
+#endif
+
+			if (g_SlowMode)
+				ProcessSlowMode();
+		}
+
+		CPad::ResetCheats();
+		CPad::StopPadsShaking();
+		DMAudio.ChangeMusicMode(MUSICMODE_DISABLE);
+		CGame::ShutDownForRestart();
+		CTimer::Stop();
+
+#ifdef PS2
+		if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+		if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+#endif
+		{
+#ifdef PS2
+			if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+			if (b_FoundRecentSavedGameWantToLoad)
+#endif
+			{
+				FrontEndMenuManager.m_bWantToRestart = true;
+#ifdef PS2
+				TheMemoryCard.m_bWantToLoad = true;
+#else
+				FrontEndMenuManager.m_bWantToLoad = true;
+#endif
+			}
+
+			CGame::InitialiseWhenRestarting();
+			DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+			FrontEndMenuManager.m_bWantToRestart = false;
+
+			continue;
+		}
+
+		break;
+	}
+
+	DMAudio.Terminate();
 }
 
-void
-ValidateVersion()
+
+void SystemInit()
 {
-	int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
-	char buff[128];
-
-	if ( file != -1 )
-	{
-		CFileMgr::Seek(file, 100, SEEK_SET);
-		
-		for ( int i = 0; i < 128; i++ )
-		{
-			CFileMgr::Read(file, &buff[i], sizeof(char));
-			buff[i] -= 23;
-			if ( buff[i] == '\0' )
-				break;
-			CFileMgr::Seek(file, 99, SEEK_CUR);
-		}
-		
-		if ( !strncmp(buff, "grandtheftauto3", 15) )
-		{
-			strncpy(version_name, &buff[15], 64);
-			CFileMgr::CloseFile(file);
-			return;
-		}
-	}
-
-	LoadingScreen("Invalid version", NULL, NULL);
+#ifdef __MWERKS__
+	mwInit();
+#endif
 	
-	while(true)
-	{
+#ifdef GTA_PS2
+	InitMemoryMgr();
+#endif
+	
+#ifdef GTA_PS2
+	CFileMgr::InitCdSystem();
+	
+	char path[256];
+	
+	sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG");
+	
+	sceSifInitRpc(0);
+	
+	while ( !sceSifRebootIop(path) )
 		;
+	while( !sceSifSyncIop() )
+		;
+	
+	sceSifInitRpc(0);
+	
+	CFileMgr::InitCdSystem();
+	
+	sceFsReset();
+#endif
+
+	CFileMgr::Initialise();
+	
+#ifdef GTA_PS2
+	CFileMgr::InitCd();
+	
+	Char modulepath[256];
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "SIO2MAN.IRX");
+	LoadModule(modulepath);
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "PADMAN.IRX");
+	LoadModule(modulepath);
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "LIBSD.IRX");
+	LoadModule(modulepath);
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "SDRDRV.IRX");
+	LoadModule(modulepath);
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "MCMAN.IRX");
+	LoadModule(modulepath);
+	
+	strcpy(modulepath, "cdrom0:\\");
+	strcat(modulepath, "SYSTEM\\");
+	strcat(modulepath, "MCSERV.IRX");
+	LoadModule(modulepath);
+#endif
+	
+
+#ifdef GTA_PS2
+	ThreadParam param;
+	
+	param.entry = &IdleThread;
+	param.stack = idleThreadStack;
+	param.stackSize = 2048;
+	param.initPriority = 127;
+	param.gpReg = &_gp;
+	
+	int thread = CreateThread(&param);
+	StartThread(thread, NULL);
+#else
+	//
+#endif
+	
+	
+	CPad::Initialise();
+	CPad::GetPad(0)->Mode = 0;
+	
+	CGame::frenchGame = false;
+	CGame::germanGame = false;
+	CGame::nastyGame = true;
+	CMenuManager::m_PrefsAllowNastyGame = true;
+	
+#ifdef GTA_PS2
+	int32 lang = sceScfGetLanguage();
+	if ( lang  == SCE_ITALIAN_LANGUAGE )
+		CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN;
+	else if ( lang  == SCE_SPANISH_LANGUAGE )
+		CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH;
+	else if ( lang  == SCE_GERMAN_LANGUAGE )
+	{
+		CGame::germanGame = true;
+		CGame::nastyGame = false;
+		CMenuManager::m_PrefsAllowNastyGame = false;
+		CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN;
 	}
+	else if ( lang  == SCE_FRENCH_LANGUAGE )
+	{
+		CGame::frenchGame = true;
+		CGame::nastyGame = false;
+		CMenuManager::m_PrefsAllowNastyGame = false;
+		CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH;
+	}
+	else
+		CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN;
+	
+	FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame();
+#else
+	//
+#endif
+	
+#ifdef PS2
+	TheMemoryCard.Init();
+#endif
+}
+
+void GameInit()
+{
+	if ( !gameAlreadyInitialised )
+	{
+#ifdef GTA_PS2
+		char path[256];
+		
+		strcpy(path, "cdrom0:\\");
+		strcat(path, "SYSTEM\\");
+		strcat(path, "CDSTREAM.IRX");
+		LoadModule(path);
+		
+		strcpy(path, "cdrom0:\\");
+		strcat(path, "SYSTEM\\");
+		strcat(path, "SAMPMAN.IRX");
+		LoadModule(path);
+		
+		strcpy(path, "cdrom0:\\");
+		strcat(path, "SYSTEM\\");
+		strcat(path, "MUSICSTR.IRX");
+		LoadModule(path);
+#endif
+		CdStreamInit(MAX_CDCHANNELS);
+		
+#ifdef PS2
+		Initialise3D(); //no params
+#else
+		//TODO
+#endif
+		
+#ifdef GTA_PS2
+		char *files[] =
+		{
+			"\\ANIM\\CUTS.IMG;1",
+			"\\ANIM\\CUTS.DIR;1",
+			"\\ANIM\\PED.IFP;1",
+			"\\MODELS\\FRONTEND.TXD;1",
+			"\\MODELS\\FONTS.TXD;1",
+			"\\MODELS\\HUD.TXD;1",
+			"\\MODELS\\PARTICLE.TXD;1",
+			"\\MODELS\\MISC.TXD;1",
+			"\\MODELS\\GENERIC.TXD;1",
+			"\\MODELS\\GTA3.DIR;1",
+			"\\TEXT\\ENGLISH.GXT;1",
+			"\\TEXT\\FRENCH.GXT;1",
+			"\\TEXT\\GERMAN.GXT;1",
+			"\\TEXT\\ITALIAN.GXT;1",
+			"\\TEXT\\SPANISH.GXT;1",
+			"\\TXD\\LOADSC0.TXD;1",
+			"\\TXD\\LOADSC1.TXD;1",
+			"\\TXD\\LOADSC2.TXD;1",
+			"\\TXD\\LOADSC3.TXD;1",
+			"\\TXD\\LOADSC4.TXD;1",
+			"\\TXD\\LOADSC5.TXD;1",
+			"\\TXD\\LOADSC6.TXD;1",
+			"\\TXD\\LOADSC7.TXD;1",
+			"\\TXD\\LOADSC8.TXD;1",
+			"\\TXD\\LOADSC9.TXD;1",
+			"\\TXD\\LOADSC10.TXD;1",
+			"\\TXD\\LOADSC11.TXD;1",
+			"\\TXD\\LOADSC12.TXD;1",
+			"\\TXD\\LOADSC13.TXD;1",
+			"\\TXD\\LOADSC14.TXD;1",
+			"\\TXD\\LOADSC15.TXD;1",
+			"\\TXD\\LOADSC16.TXD;1",
+			"\\TXD\\LOADSC17.TXD;1",
+			"\\TXD\\LOADSC18.TXD;1",
+			"\\TXD\\LOADSC19.TXD;1",
+			"\\TXD\\LOADSC20.TXD;1",
+			"\\TXD\\LOADSC21.TXD;1",
+			"\\TXD\\LOADSC22.TXD;1",
+			"\\TXD\\LOADSC23.TXD;1",
+			"\\TXD\\LOADSC24.TXD;1",
+			"\\TXD\\LOADSC25.TXD;1",
+			"\\TXD\\NEWS.TXD;1",
+			"\\MODELS\\COLL\\GENERIC.COL;1",
+			"\\MODELS\\COLL\\INDUST.COL;1",
+			"\\MODELS\\COLL\\COMMER.COL;1",
+			"\\MODELS\\COLL\\SUBURB.COL;1",
+			"\\MODELS\\COLL\\WEAPONS.COL;1",
+			"\\MODELS\\COLL\\VEHICLES.COL;1",
+			"\\MODELS\\COLL\\PEDS.COL;1",
+			"\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
+			"\\MODELS\\GENERIC\\WEAPONS.DFF;1",
+			"\\MODELS\\GENERIC\\WHEELS.DFF;1",
+			"\\MODELS\\GENERIC\\LOPLYGUY.DFF;1",
+			"\\MODELS\\GENERIC\\ARROW.DFF;1",
+			"\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
+			"\\DATA\\MAPS\\COMNTOP.IPL;1",
+			"\\DATA\\MAPS\\COMNBTM.IPL;1",
+			"\\DATA\\MAPS\\COMSE.IPL;1",
+			"\\DATA\\MAPS\\COMSW.IPL;1",
+			"\\DATA\\MAPS\\CULL.IPL;1",
+			"\\DATA\\MAPS\\INDUSTNE.IPL;1",
+			"\\DATA\\MAPS\\INDUSTNW.IPL;1",
+			"\\DATA\\MAPS\\INDUSTSE.IPL;1",
+			"\\DATA\\MAPS\\INDUSTSW.IPL;1",
+			"\\DATA\\MAPS\\SUBURBNE.IPL;1",
+			"\\DATA\\MAPS\\SUBURBSW.IPL;1",
+			"\\DATA\\MAPS\\OVERVIEW.IPL;1",
+			"\\DATA\\MAPS\\PROPS.IPL;1",
+			"\\DATA\\MAPS\\GTA3.IDE;1",
+			"\\DATA\\PATHS\\FLIGHT.DAT;1",
+			"\\DATA\\PATHS\\FLIGHT2.DAT;1",
+			"\\DATA\\PATHS\\FLIGHT3.DAT;1",
+			"\\DATA\\PATHS\\FLIGHT4.DAT;1",
+			"\\DATA\\PATHS\\TRACKS.DAT;1",
+			"\\DATA\\PATHS\\TRACKS2.DAT;1",
+			"\\DATA\\PATHS\\CHASE0.DAT;1",
+			"\\DATA\\PATHS\\CHASE1.DAT;1",
+			"\\DATA\\PATHS\\CHASE2.DAT;1",
+			"\\DATA\\PATHS\\CHASE3.DAT;1",
+			"\\DATA\\PATHS\\CHASE4.DAT;1",
+			"\\DATA\\PATHS\\CHASE5.DAT;1",
+			"\\DATA\\PATHS\\CHASE6.DAT;1",
+			"\\DATA\\PATHS\\CHASE7.DAT;1",
+			"\\DATA\\PATHS\\CHASE10.DAT;1",
+			"\\DATA\\PATHS\\CHASE11.DAT;1",
+			"\\DATA\\PATHS\\CHASE14.DAT;1",
+			"\\DATA\\PATHS\\CHASE16.DAT;1",
+			"\\DATA\\PATHS\\CHASE18.DAT;1",
+			"\\DATA\\PATHS\\CHASE19.DAT;1"
+		};
+		
+		for ( int32 i = 0; i < ARRAY_SIZE(files); i++ )
+			SkyRegisterFileOnCd([i]);
+#endif
+		
+		CreateDebugFont();
+		
+#ifdef GTA_PS2
+		AddIntcHandler(_TODOCONST(2), VBlankCounter, 0);
+#endif
+		
+		CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+		
+		CSprite2d::SetRecipNearClip();
+		CTxdStore::Initialise();
+#ifdef GTA_PS2
+		gMainHeap.PushMemId(_TODOCONST(9));
+#endif
+		CFont::Initialise();
+		CHud::Initialise();
+#ifdef GTA_PS2
+		gMainHeap.PopMemId();
+#endif
+
+		ValidateVersion();
+		
+#ifdef GTA_PS2
+		sceCdCLOCK rtc;
+		sceCdReadClock(&rtc);
+		uint32 seed = rtc.minute + rtc.day;
+		uint32 seed2 = (seed << 4)-seed;
+		uint32 seed3 = (seed2 << 4)-seed2;
+		srand ((seed3<<4)+rtc.second);
+#else
+		//TODO: mysrand();
+#endif
+		
+		gameAlreadyInitialised = true;
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+#ifdef __MWERKS__
+	mwInit(); // metrowerks initialisation
+#endif
+
+	SystemInit();
+	
+#ifdef PS2
+	int32 state = TheMemoryCard.CheckCardStateAtGameStartUp(_TODOCONST(0));
+		
+	if ( state == _TODOCONST(2) || state == _TODOCONST(1) && state != _TODOCONST(3) && state != _TODOCONST(0) )
+	{
+		GameInit();
+		
+		TheText.Unload();
+		TheText.Load();
+		
+		CFont::Initialise();
+		
+		FrontEndMenuManager.DrawMemoryCardStartUpMenus();
+	}
+#endif
+	
+#ifdef GTA_PS2
+	{
+		if (gameAlreadyInitialised)
+			RpSkySuspend();
+
+		InitMPEGPlayer();
+
+		PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false);
+
+		if (CGame::frenchGame || CGame::germanGame)
+			PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true);
+		else
+			PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true);
+
+		ShutdownMPEGPlayer();
+
+		if ( gameAlreadyInitialised )
+			RpSkyResume();
+	}
+#else
+	//TODO
+#endif
+
+	GameInit();
+
+	if ( CGame::frenchGame || CGame::germanGame )
+		LoadingScreen(NULL, version_name, "loadsc24");
+	else
+		LoadingScreen(NULL, version_name, "loadsc0");
+	
+	DMAudio.Initialise();
+	
+	TheGame();
+	
+	CGame::ShutDown();
+	
+	RwEngineStop();
+	RwEngineClose();
+	RwEngineTerm();
+	
+#ifdef __MWERKS__
+	mwExit(); // metrowerks shutdown
+#endif
+	
+	return 0;
 }
 
 STARTPATCHES
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index c4aca8e4..80d7fe47 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -815,7 +815,7 @@ void CHud::Draw()
 		DrawScriptText
 	*/
 	if (!CTimer::GetIsUserPaused()) {
-		CTextLine* IntroText = CTheScripts::IntroTextLines;
+		intro_text_line* IntroText = CTheScripts::IntroTextLines;
 
 		for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
 			if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
@@ -862,7 +862,7 @@ void CHud::Draw()
 			}
 		}
 
-		CScriptRectangle* IntroRect = CTheScripts::IntroRectangles;
+		intro_script_rectangle* IntroRect = CTheScripts::IntroRectangles;
 
 		for (int i = 0; i < 16; i++) {
 			if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index d71b0c22..2545b9ab 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -48,6 +48,13 @@ char SaveFileNameJustSaved[260];
 int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
 CDate &CompileDateAndTime = *(CDate*)0x72BCB8;
 
+
+bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
+bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
+bool &StillToFadeOut = *(bool*)0x95CD99;
+uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
+uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
+
 #define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
 #define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));
 
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index e22dfc7e..40d92f16 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -32,6 +32,12 @@ extern int &CheckSum;
 extern enum eLevelName &m_LevelToLoad;
 extern int (&Slots)[SLOT_COUNT+1];
 
+extern bool &b_FoundRecentSavedGameWantToLoad;
+extern bool &JustLoadedDontFadeInYet;
+extern bool &StillToFadeOut;
+extern uint32 &TimeStartedCountingForFade;
+extern uint32 &TimeToStayFadedBeforeFadeOut;
+
 extern char SaveFileNameJustSaved[260]; // 8F2570
 
 const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";
\ No newline at end of file
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 7993426a..ec84e968 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -1927,7 +1927,7 @@ _WinMain(HINSTANCE instance,
 		* Enter the message processing loop...
 		*/
 
-		while( !RsGlobal.quit && !FrontEndMenuManager.m_bStartGameLoading )
+		while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart )
 		{
 			if( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
 			{
@@ -2059,13 +2059,13 @@ _WinMain(HINSTANCE instance,
 						if (wp.showCmd != SW_SHOWMINIMIZED)
 							RsEventHandler(rsFRONTENDIDLE, nil);
 
-						if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
+						if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
 						{
 							gGameState = GS_INIT_PLAYING_GAME;
 							TRACE("gGameState = GS_INIT_PLAYING_GAME;");
 						}
 
-						if ( FrontEndMenuManager.m_bLoadingSavedGame )
+						if ( FrontEndMenuManager.m_bWantToLoad )
 						{
 							InitialiseGame();
 							FrontEndMenuManager.m_bGameNotLoaded = false;
@@ -2128,7 +2128,7 @@ _WinMain(HINSTANCE instance,
 		RwInitialised = FALSE;
 		
 		FrontEndMenuManager.UnloadTextures();
-		if ( !FrontEndMenuManager.m_bStartGameLoading )
+		if ( !FrontEndMenuManager.m_bWantToRestart )
 			break;
 		
 		CPad::ResetCheats();
@@ -2138,13 +2138,13 @@ _WinMain(HINSTANCE instance,
 		
 		CTimer::Stop();
 		
-		if ( FrontEndMenuManager.m_bLoadingSavedGame )
+		if ( FrontEndMenuManager.m_bWantToLoad )
 		{
 			CGame::ShutDownForRestart();
 			CGame::InitialiseWhenRestarting();
 			DMAudio.ChangeMusicMode(MUSICMODE_GAME);
 			LoadSplash(GetLevelSplashScreen(CGame::currLevel));
-			FrontEndMenuManager.m_bLoadingSavedGame = false;
+			FrontEndMenuManager.m_bWantToLoad = false;
 		}
 		else
 		{
@@ -2168,7 +2168,7 @@ _WinMain(HINSTANCE instance,
 		}
 		
 		FrontEndMenuManager.m_bFirstTime = false;
-		FrontEndMenuManager.m_bStartGameLoading = false;
+		FrontEndMenuManager.m_bWantToRestart = false;
 	}