Merge branch 'master' into garages_dev

This commit is contained in:
Nikolay Korolev 2020-04-10 21:17:00 +03:00
commit be260b49b1
94 changed files with 12517 additions and 10402 deletions

View File

@ -16,12 +16,6 @@ such that we have a working game at all times.
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader). - Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
- Build re3 or download it from one of the above links (Debug or Release). - Build re3 or download it from one of the above links (Debug or Release).
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`. - Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`.
- re3 starts the script `main_freeroam.scm` that comes along with it by default, so you should copy it to from `gamefiles/` to your game's `data/` directory.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice**
If you want to load original script/story, press and hold G while game is loading.
This includes both starting new game and loading save game.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it** ![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it**
@ -41,21 +35,16 @@ to reverse at the time, calling the original functions is acceptable.
cAudioManager - WIP cAudioManager - WIP
CBoat CBoat
CBulletInfo CBulletInfo
CExplosion
CMenuManager - WIP CMenuManager - WIP
CObject CObject
CPacManPickups CPacManPickups
CPad - only cheats
CPedPath CPedPath
CPools - save/loading CPools - save/loading
CRecordDataForChase CRecordDataForChase
CRecordDataForGame CRecordDataForGame
CRoadBlocks CRoadBlocks
CSkidmarks
CStats
CTrafficLights CTrafficLights
CWeapon CWeapon
CWeather
CWorld CWorld
GenericLoad GenericLoad
``` ```

View File

@ -134,8 +134,8 @@ uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
RpAtomic * RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data) CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
{ {
float radius = RpAtomicGetBoundingSphereMacro(atomic)->radius; float radius = RpAtomicGetBoundingSphere(atomic)->radius;
RwV3d center = RpAtomicGetBoundingSphereMacro(atomic)->center; RwV3d center = RpAtomicGetBoundingSphere(atomic)->center;
for (RwFrame *frame = RpAtomicGetFrame(atomic); RwFrameGetParent(frame); frame = RwFrameGetParent(frame)) for (RwFrame *frame = RpAtomicGetFrame(atomic); RwFrameGetParent(frame); frame = RwFrameGetParent(frame))
RwV3dTransformPoints(&center, &center, 1, RwFrameGetMatrix(frame)); RwV3dTransformPoints(&center, &center, 1, RwFrameGetMatrix(frame));
@ -326,7 +326,7 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pModelInfo->SetColModel(pColModel); pModelInfo->SetColModel(pColModel);
clump = (RpClump*)pModelInfo->GetRwObject(); clump = (RpClump*)pModelInfo->GetRwObject();
assert(RwObjectGetType(clump) == rpCLUMP); assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius); RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
pColModel->boundingSphere.radius = radius; pColModel->boundingSphere.radius = radius;
@ -352,6 +352,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]); CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject(); ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject();
delete ms_pCutsceneObjects[ms_numCutsceneObjs]; delete ms_pCutsceneObjects[ms_numCutsceneObjs];
ms_pCutsceneObjects[ms_numCutsceneObjs] = nil;
} }
ms_numCutsceneObjs = 0; ms_numCutsceneObjs = 0;

View File

@ -26,7 +26,7 @@ public:
static CDirectory *&ms_pCutsceneDir; static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus; static uint32 &ms_cutsceneLoadStatus;
static void SetRunning(bool running) { ms_running = running; } static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; } static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; } static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "DMAudio.h" #include "DMAudio.h"
#include "common.h" #include "common.h"

View File

@ -90,7 +90,7 @@ uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(ui
void void
CCarCtrl::GenerateRandomCars() CCarCtrl::GenerateRandomCars()
{ {
if (CCutsceneMgr::IsCutsceneProcessing()) if (CCutsceneMgr::IsRunning())
return; return;
if (NumRandomCars < 30){ if (NumRandomCars < 30){
if (CountDownToCarsAtStart == 0){ if (CountDownToCarsAtStart == 0){

View File

@ -242,7 +242,7 @@ void CCarGenerator::Load(uint8 *&buffer)
void CTheCarGenerators::Process() void CTheCarGenerators::Process()
{ {
if (FindPlayerTrain() || CCutsceneMgr::IsRunning()) if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing())
return; return;
if (++CTheCarGenerators::ProcessCounter == 4) if (++CTheCarGenerators::ProcessCounter == 4)
CTheCarGenerators::ProcessCounter = 0; CTheCarGenerators::ProcessCounter = 0;

View File

@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void)
pEmptyReferences = CReferences::pEmptyList; pEmptyReferences = CReferences::pEmptyList;
pStoredCam = new uint8[sizeof(CCamera)]; pStoredCam = new uint8[sizeof(CCamera)];
memcpy(pStoredCam, &TheCamera, sizeof(CCamera)); memcpy(pStoredCam, &TheCamera, sizeof(CCamera));
pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS]; pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS];
memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip)); memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace));
PlayerWanted = *FindPlayerPed()->m_pWanted; PlayerWanted = *FindPlayerPed()->m_pWanted;
PlayerInfo = CWorld::Players[0]; PlayerInfo = CWorld::Players[0];
Time1 = CTimer::GetTimeInMilliseconds(); Time1 = CTimer::GetTimeInMilliseconds();
@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(&TheCamera, pStoredCam, sizeof(CCamera)); memcpy(&TheCamera, pStoredCam, sizeof(CCamera));
delete[] pStoredCam; delete[] pStoredCam;
pStoredCam = nil; pStoredCam = nil;
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS); memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
delete[] pRadarBlips; delete[] pRadarBlips;
pRadarBlips = nil; pRadarBlips = nil;
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted); FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);

View File

@ -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; 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::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0; 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; intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108; 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; 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; 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; 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; 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; return false;
} }
void CStuckCarCheckEntry::Reset() void stuck_car_data::Reset()
{ {
m_nVehicleIndex = -1; m_nVehicleIndex = -1;
m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f); m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f);
@ -8442,7 +8442,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
pPlayerInfo->MakePlayerSafe(true); pPlayerInfo->MakePlayerSafe(true);
CCutsceneMgr::SetRunning(true); CCutsceneMgr::StartCutsceneProcessing();
return 0; return 0;
} }
case COMMAND_USE_TEXT_COMMANDS: case COMMAND_USE_TEXT_COMMANDS:
@ -11373,15 +11373,15 @@ void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntit
continue; continue;
CEntity* pFound = aEntities[i]; CEntity* pFound = aEntities[i];
int cols; int cols;
if (CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel()->numLines <= 0) if (pEntity->GetColModel()->numLines <= 0)
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(), cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, nil, nil); pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
else { else {
float lines[4]; float lines[4];
lines[0] = lines[1] = lines[2] = lines[3] = 1.0f; lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
CColPoint tmp; CColPoint tmp[4];
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(), cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, &tmp, lines); pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
} }
if (cols <= 0) if (cols <= 0)
continue; continue;

View File

@ -15,22 +15,25 @@ class CRunningScript;
#define KEY_LENGTH_IN_SCRIPT 8 #define KEY_LENGTH_IN_SCRIPT 8
struct CScriptRectangle struct intro_script_rectangle
{ {
bool m_bIsUsed; bool m_bIsUsed;
bool m_bBeforeFade; bool m_bBeforeFade;
int16 m_nTextureId; int16 m_nTextureId;
CRect m_sRect; CRect m_sRect;
CRGBA m_sColor; 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 { enum {
SCRIPT_TEXT_MAX_LENGTH = 500 SCRIPT_TEXT_MAX_LENGTH = 500
}; };
struct CTextLine struct intro_text_line
{ {
float m_fScaleX; float m_fScaleX;
float m_fScaleY; float m_fScaleY;
@ -50,6 +53,9 @@ struct CTextLine
float m_fAtY; float m_fAtY;
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH]; wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
intro_text_line() { }
~intro_text_line() { }
void Reset() void Reset()
{ {
m_fScaleX = 0.48f; 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; bool m_bInUse;
uint16 m_Index; uint16 m_Index;
uint32 m_Id; uint32 m_Id;
CVector m_vecCenter; CVector m_vecCenter;
float m_fRadius; float m_fRadius;
script_sphere_struct() { }
}; };
struct CStoredLine struct CStoredLine
@ -145,7 +153,7 @@ public:
bool HasCarBeenUpsideDownForAWhile(int32); bool HasCarBeenUpsideDownForAWhile(int32);
}; };
struct CStuckCarCheckEntry struct stuck_car_data
{ {
int32 m_nVehicleIndex; int32 m_nVehicleIndex;
CVector m_vecPos; CVector m_vecPos;
@ -154,12 +162,13 @@ struct CStuckCarCheckEntry
uint32 m_nStuckTime; uint32 m_nStuckTime;
bool m_bStuck; bool m_bStuck;
stuck_car_data() { }
inline void Reset(); inline void Reset();
}; };
class CStuckCarCheck class CStuckCarCheck
{ {
CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS]; stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
public: public:
void Init(); void Init();
@ -235,10 +244,10 @@ class CTheScripts
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS]; static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS]; static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS]; static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES]; static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES]; static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES]; 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 tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS]; static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS]; static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];

View File

@ -142,7 +142,7 @@ CCamera::Init(void)
PlayerExhaustion = 1.0f; PlayerExhaustion = 1.0f;
DebugCamMode = CCam::MODE_NONE; DebugCamMode = CCam::MODE_NONE;
m_PedOrientForBehindOrInFront = 0.0f; m_PedOrientForBehindOrInFront = 0.0f;
if(!FrontEndMenuManager.m_bStartGameLoading){ if(!FrontEndMenuManager.m_bWantToRestart){
m_bFading = false; m_bFading = false;
CDraw::FadeValue = 0; CDraw::FadeValue = 0;
m_fFLOATingFade = 0.0f; m_fFLOATingFade = 0.0f;
@ -151,7 +151,7 @@ CCamera::Init(void)
m_fFLOATingFadeMusic = 0.0f; m_fFLOATingFadeMusic = 0.0f;
} }
m_bMoveCamToAvoidGeom = false; m_bMoveCamToAvoidGeom = false;
if(FrontEndMenuManager.m_bStartGameLoading) if(FrontEndMenuManager.m_bWantToRestart)
m_bMoveCamToAvoidGeom = true; m_bMoveCamToAvoidGeom = true;
m_bStartingSpline = false; m_bStartingSpline = false;
m_iTypeOfSwitch = INTERPOLATION; m_iTypeOfSwitch = INTERPOLATION;
@ -3269,7 +3269,7 @@ void
CCamera::SetRwCamera(RwCamera *cam) CCamera::SetRwCamera(RwCamera *cam)
{ {
m_pRwCamera = cam; m_pRwCamera = cam;
m_viewMatrix.Attach(&m_pRwCamera->viewMatrix, false); m_viewMatrix.Attach(RwCameraGetViewMatrix(m_pRwCamera), false);
CMBlur::MotionBlurOpen(m_pRwCamera); CMBlur::MotionBlurOpen(m_pRwCamera);
} }

View File

@ -311,7 +311,7 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
int n; int n;
RpClump *clump = (RpClump*)data; RpClump *clump = (RpClump*)data;
nodename = GetFrameNodeName(RpClumpGetFrame(atomic)); nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n); GetNameAndLOD(nodename, name, &n);
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil); mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){ if(mi){

View File

@ -555,7 +555,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
m_PrefsVsync = m_PrefsVsyncDisp; m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service(); DMAudio.Service();
m_bStartGameLoading = true; m_bWantToRestart = true;
ShutdownJustMenu(); ShutdownJustMenu();
UnloadTextures(); UnloadTextures();
@ -2819,7 +2819,7 @@ void CMenuManager::Process(void)
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0) if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
return; return;
m_bStartGameLoading = false; m_bWantToRestart = false;
InitialiseChangedLanguageSettings(); InitialiseChangedLanguageSettings();
if (CPad::GetPad(0)->GetEscapeJustDown()) if (CPad::GetPad(0)->GetEscapeJustDown())
@ -2861,9 +2861,9 @@ void CMenuManager::Process(void)
if (m_PrefsVsyncDisp != m_PrefsVsync) if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp; m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service(); DMAudio.Service();
m_bStartGameLoading = true; m_bWantToRestart = true;
RequestFrontEndShutDown(); RequestFrontEndShutDown();
m_bLoadingSavedGame = true; m_bWantToLoad = true;
b_FoundRecentSavedGameWantToLoad = true; b_FoundRecentSavedGameWantToLoad = true;
DMAudio.SetEffectsFadeVol(0); DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0); DMAudio.SetMusicFadeVol(0);
@ -2960,7 +2960,7 @@ void CMenuManager::Process(void)
m_bWaitingForNewKeyBind = false; m_bWaitingForNewKeyBind = false;
} }
if (!m_bStartGameLoading) { if (!m_bWantToRestart) {
if (m_bGameNotLoaded) if (m_bGameNotLoaded)
DMAudio.Service(); DMAudio.Service();
} }

View File

@ -464,7 +464,7 @@ public:
bool m_bMenuActive; bool m_bMenuActive;
bool m_bMenuStateChanged; bool m_bMenuStateChanged;
bool m_bWaitingForNewKeyBind; bool m_bWaitingForNewKeyBind;
bool m_bStartGameLoading; bool m_bWantToRestart;
bool m_bFirstTime; bool m_bFirstTime;
bool m_bGameNotLoaded; bool m_bGameNotLoaded;
int32 m_nMousePosX; int32 m_nMousePosX;
@ -484,7 +484,7 @@ public:
bool m_bQuitGameNoCD; bool m_bQuitGameNoCD;
bool m_bRenderGameInMenu; bool m_bRenderGameInMenu;
bool m_bSaveMenuActive; bool m_bSaveMenuActive;
bool m_bLoadingSavedGame; bool m_bWantToLoad;
char field_455; char field_455;
bool m_bStartWaitingForKeyBind; bool m_bStartWaitingForKeyBind;
bool m_bSpritesLoaded; bool m_bSpritesLoaded;

View File

@ -89,8 +89,6 @@
#define DEFAULT_VIEWWINDOW (0.7f)
eLevelName &CGame::currLevel = *(eLevelName*)0x941514; eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0; bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4; bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@ -492,7 +490,7 @@ void CGame::ReInitGameObjectVariables(void)
CParticle::ReloadConfig(); CParticle::ReloadConfig();
CCullZones::ResolveVisibilities(); CCullZones::ResolveVisibilities();
if ( !FrontEndMenuManager.m_bLoadingSavedGame ) if ( !FrontEndMenuManager.m_bWantToLoad )
{ {
CCranes::InitCranes(); CCranes::InitCranes();
CTheScripts::StartTestScript(); CTheScripts::StartTestScript();
@ -566,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void)
TheCamera.Init(); TheCamera.Init();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true ) if ( FrontEndMenuManager.m_bWantToLoad == true )
{ {
RestoreForStartLoad(); RestoreForStartLoad();
CStreaming::LoadScene(TheCamera.GetPosition()); CStreaming::LoadScene(TheCamera.GetPosition());
@ -574,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void)
ReInitGameObjectVariables(); ReInitGameObjectVariables();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true ) if ( FrontEndMenuManager.m_bWantToLoad == true )
{ {
if ( GenericLoad() == true ) if ( GenericLoad() == true )
{ {
@ -593,7 +591,7 @@ void CGame::InitialiseWhenRestarting(void)
ShutDownForRestart(); ShutDownForRestart();
CTimer::Stop(); CTimer::Stop();
CTimer::Initialise(); CTimer::Initialise();
FrontEndMenuManager.m_bLoadingSavedGame = false; FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables(); ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL; currLevel = LEVEL_INDUSTRIAL;
CCollision::SortOutCollisionAfterLoad(); CCollision::SortOutCollisionAfterLoad();
@ -609,6 +607,9 @@ extern void (*DebugMenuProcess)(void);
void CGame::Process(void) void CGame::Process(void)
{ {
CPad::UpdatePads(); CPad::UpdatePads();
#ifdef GTA_PS2
ProcessTidyUpMemory();
#endif
TheCamera.SetMotionBlurAlpha(0); TheCamera.SetMotionBlurAlpha(0);
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL) if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
@ -695,6 +696,13 @@ void CGame::TidyUpMemory(bool, bool)
#endif #endif
} }
void CGame::ProcessTidyUpMemory(void)
{
#ifdef PS2
// meow
#endif
}
STARTPATCHES STARTPATCHES
InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP); InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP); InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);

View File

@ -39,4 +39,5 @@ public:
// NB: these do something on PS2 // NB: these do something on PS2
static void TidyUpMemory(bool, bool); static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool); static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void);
}; };

View File

@ -29,12 +29,17 @@
#include "Replay.h" #include "Replay.h"
#include "Weather.h" #include "Weather.h"
#include "win.h" #include "win.h"
#include "Streaming.h"
#include "PathFind.h"
#include "Wanted.h"
#include "General.h"
CPad *Pads = (CPad*)0x6F0360; // [2] CPad *Pads = (CPad*)0x6F0360; // [2]
CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C; CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C;
bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52; bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8; bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
bool CPad::bOldDisplayNoControllerMessage;
bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48; bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70; CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
@ -50,29 +55,217 @@ CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerStat
_TODO("gbFastTime"); _TODO("gbFastTime");
extern bool &gbFastTime; extern bool &gbFastTime;
WRAPPER void WeaponCheat() { EAXJMP(0x490D90); } void WeaponCheat()
WRAPPER void HealthCheat() { EAXJMP(0x490E70); } {
WRAPPER void TankCheat() { EAXJMP(0x490EE0); } CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
WRAPPER void BlowUpCarsCheat() { EAXJMP(0x491040); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
WRAPPER void ChangePlayerCheat() { EAXJMP(0x4910B0); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
WRAPPER void MayhemCheat() { EAXJMP(0x4911C0); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
WRAPPER void EverybodyAttacksPlayerCheat() { EAXJMP(0x491270); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
WRAPPER void WeaponsForAllCheat() { EAXJMP(0x491370); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
WRAPPER void FastTimeCheat() { EAXJMP(0x4913A0); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
WRAPPER void SlowTimeCheat() { EAXJMP(0x4913F0); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
WRAPPER void MoneyCheat() { EAXJMP(0x491430); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
WRAPPER void ArmourCheat() { EAXJMP(0x491460); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
WRAPPER void WantedLevelUpCheat() { EAXJMP(0x491490); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
WRAPPER void WantedLevelDownCheat() { EAXJMP(0x4914F0); } FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
WRAPPER void SunnyWeatherCheat() { EAXJMP(0x491520); } }
WRAPPER void CloudyWeatherCheat() { EAXJMP(0x491550); }
WRAPPER void RainyWeatherCheat() { EAXJMP(0x491580); } void HealthCheat()
WRAPPER void FoggyWeatherCheat() { EAXJMP(0x4915B0); } {
WRAPPER void FastWeatherCheat() { EAXJMP(0x4915E0); } CHud::SetHelpMessage(TheText.Get("CHEAT3"), true);
WRAPPER void OnlyRenderWheelsCheat() { EAXJMP(0x491610); } FindPlayerPed()->m_fHealth = 100.0f;
WRAPPER void ChittyChittyBangBangCheat() { EAXJMP(0x491640); } if (FindPlayerVehicle()) {
WRAPPER void StrongGripCheat() { EAXJMP(0x491670); } FindPlayerVehicle()->m_fHealth = 1000.0f;
WRAPPER void NastyLimbsCheat() { EAXJMP(0x4916A0); } if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR)
((CAutomobile*)FindPlayerVehicle())->Damage.SetEngineStatus(0);
}
}
void TankCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CStreaming::RequestModel(MI_RHINO, 0);
CStreaming::LoadAllRequestedModels(false);
if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
if (node < 0) return;
#ifdef FIX_BUGS
CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE);
#else
CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE);
#endif
if (tank != nil) {
CVector pos = ThePaths.m_pathNodes[node].pos;
pos.z += 4.0f;
tank->GetPosition() = pos;
tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f));
tank->m_status = STATUS_ABANDONED;
tank->m_nDoorLock = CARLOCK_UNLOCKED;
CWorld::Add(tank);
}
}
}
void BlowUpCarsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
int i = CPools::GetVehiclePool()->GetSize();
while (i-- > 0) {
if (CVehicle *veh = CPools::GetVehiclePool()->GetSlot(i))
veh->BlowUpCar(nil);
}
}
void ChangePlayerCheat()
{
int modelId;
if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPlayerPed *ped = FindPlayerPed();
AssocGroupId AnimGrp = ped->m_animGroup;
do
{
do
modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
while (!CModelInfo::GetModelInfo(modelId));
} while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
ped->DeleteRwObject();
CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
ped->m_modelIndex = -1;
ped->SetModelIndex(modelId);
ped->m_animGroup = AnimGrp;
if (modelId != MI_PLAYER) {
if (!(flags & STREAMFLAGS_DONT_REMOVE))
CStreaming::SetModelIsDeletable(modelId);
}
}
}
void MayhemCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::SetThreats(i, PED_FLAG_PLAYER1 | PED_FLAG_PLAYER2 | PED_FLAG_PLAYER3 | PED_FLAG_PLAYER4 |
PED_FLAG_CIVMALE | PED_FLAG_CIVFEMALE | PED_FLAG_COP | PED_FLAG_GANG1 |
PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
}
void EverybodyAttacksPlayerCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::AddThreat(i, PED_FLAG_PLAYER1);
}
void WeaponsForAllCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
}
void FastTimeCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
if (CTimer::GetTimeScale() < 4.0f)
CTimer::SetTimeScale(CTimer::GetTimeScale() * 2.0f);
}
void SlowTimeCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
if (CTimer::GetTimeScale() > 0.25f)
CTimer::SetTimeScale(CTimer::GetTimeScale() * 0.5f);
}
void MoneyCheat()
{
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250000;
CHud::SetHelpMessage(TheText.Get("CHEAT6"), true);
}
void ArmourCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT4"), true);
FindPlayerPed()->m_fArmour = 100.0f;
}
void WantedLevelUpCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
FindPlayerPed()->SetWantedLevel(min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
}
void WantedLevelDownCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
FindPlayerPed()->SetWantedLevel(0);
}
void SunnyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_SUNNY);
}
void CloudyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_CLOUDY);
}
void RainyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_RAINY);
}
void FoggyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_FOGGY);
}
void FastWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
gbFastTime = !gbFastTime;
}
void OnlyRenderWheelsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
}
void ChittyChittyBangBangCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
}
void StrongGripCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bCheat3 = !CVehicle::bCheat3;
}
void NastyLimbsCheat()
{
CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
#ifdef KANGAROO_CHEAT #ifdef KANGAROO_CHEAT
@ -89,7 +282,7 @@ void KangarooCheat()
string = TheText.Get("CHEAT1"); string = TheText.Get("CHEAT1");
m_fMass = 15.0f; m_fMass = 15.0f;
} }
CHud::SetHelpMessage(string, 1); CHud::SetHelpMessage(string, true);
playerPed->m_ped_flagI80 = !playerPed->m_ped_flagI80; playerPed->m_ped_flagI80 = !playerPed->m_ped_flagI80;
playerPed->m_fMass = m_fMass; playerPed->m_fMass = m_fMass;
@ -138,6 +331,21 @@ void CKeyboardState::Clear()
LWIN = RWIN = APPS = 0; 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) void CPad::Clear(bool bResetPlayerControls)
{ {
NewState.Clear(); NewState.Clear();
@ -165,13 +373,13 @@ void CPad::Clear(bool bResetPlayerControls)
bApplyBrakes = false; bApplyBrakes = false;
for ( int32 i = 0; i < _TODOCONST(5); i++ ) for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
bHornHistory[i] = false; bHornHistory[i] = false;
iCurrHornHistory = 0; iCurrHornHistory = 0;
for ( int32 i = 0; i < _TODOCONST(12); i++ ) for ( int32 i = 0; i < ARRAY_SIZE(CheatString); i++ )
_unk[i] = ' '; CheatString[i] = ' ';
LastTimeTouched = CTimer::GetTimeInMilliseconds(); LastTimeTouched = CTimer::GetTimeInMilliseconds();
AverageWeapon = 0; AverageWeapon = 0;
@ -430,6 +638,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) void CPad::AddToPCCheatString(char c)
{ {
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- ) for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
@ -672,7 +982,7 @@ void CPad::Update(int16 unk)
ProcessPCSpecificStuff(); ProcessPCSpecificStuff();
if ( ++iCurrHornHistory >= _TODOCONST(5) ) if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
iCurrHornHistory = 0; iCurrHornHistory = 0;
bHornHistory[iCurrHornHistory] = GetHorn(); bHornHistory[iCurrHornHistory] = GetHorn();
@ -689,7 +999,7 @@ void CPad::DoCheats(void)
void CPad::DoCheats(int16 unk) void CPad::DoCheats(int16 unk)
{ {
#ifdef PS2 #ifdef GTA_PS2_STUFF
if ( GetTriangleJustDown() ) if ( GetTriangleJustDown() )
AddToCheatString('T'); AddToCheatString('T');
@ -2093,6 +2403,30 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
} }
STARTPATCHES STARTPATCHES
InjectHook(0x490D90, &WeaponCheat, PATCH_JUMP);
InjectHook(0x490E70, &HealthCheat, PATCH_JUMP);
InjectHook(0x490EE0, &TankCheat, PATCH_JUMP);
InjectHook(0x491040, &BlowUpCarsCheat, PATCH_JUMP);
InjectHook(0x4910B0, &ChangePlayerCheat, PATCH_JUMP);
InjectHook(0x4911C0, &MayhemCheat, PATCH_JUMP);
InjectHook(0x491270, &EverybodyAttacksPlayerCheat, PATCH_JUMP);
InjectHook(0x491370, &WeaponsForAllCheat, PATCH_JUMP);
InjectHook(0x4913A0, &FastTimeCheat, PATCH_JUMP);
InjectHook(0x4913F0, &SlowTimeCheat, PATCH_JUMP);
InjectHook(0x491430, &MoneyCheat, PATCH_JUMP);
InjectHook(0x491460, &ArmourCheat, PATCH_JUMP);
InjectHook(0x491490, &WantedLevelUpCheat, PATCH_JUMP);
InjectHook(0x4914F0, &WantedLevelDownCheat, PATCH_JUMP);
InjectHook(0x491520, &SunnyWeatherCheat, PATCH_JUMP);
InjectHook(0x491550, &CloudyWeatherCheat, PATCH_JUMP);
InjectHook(0x491580, &RainyWeatherCheat, PATCH_JUMP);
InjectHook(0x4915B0, &FoggyWeatherCheat, PATCH_JUMP);
InjectHook(0x4915E0, &FastWeatherCheat, PATCH_JUMP);
InjectHook(0x491610, &OnlyRenderWheelsCheat, PATCH_JUMP);
InjectHook(0x491640, &ChittyChittyBangBangCheat, PATCH_JUMP);
InjectHook(0x491670, &StrongGripCheat, PATCH_JUMP);
InjectHook(0x4916A0, &NastyLimbsCheat, PATCH_JUMP);
InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP); InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP);
InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP); InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP);
InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP); InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP);

View File

@ -136,6 +136,10 @@ enum
class CPad class CPad
{ {
public: public:
enum
{
HORNHISTORY_SIZE = 5,
};
CControllerState NewState; CControllerState NewState;
CControllerState OldState; CControllerState OldState;
CControllerState PCTempKeyState; CControllerState PCTempKeyState;
@ -146,11 +150,11 @@ public:
int16 Mode; int16 Mode;
int16 ShakeDur; int16 ShakeDur;
uint8 ShakeFreq; uint8 ShakeFreq;
bool bHornHistory[5]; bool bHornHistory[HORNHISTORY_SIZE];
uint8 iCurrHornHistory; uint8 iCurrHornHistory;
uint8 DisablePlayerControls; uint8 DisablePlayerControls;
int8 bApplyBrakes; int8 bApplyBrakes;
char _unk[12]; //int32 unk[3]; char CheatString[12];
char _pad0[3]; char _pad0[3];
int32 LastTimeTouched; int32 LastTimeTouched;
int32 AverageWeapon; int32 AverageWeapon;
@ -161,6 +165,7 @@ public:
static bool &bDisplayNoControllerMessage; static bool &bDisplayNoControllerMessage;
static bool &bObsoleteControllerMessage; static bool &bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
static bool &m_bMapPadOneToPadTwo; static bool &m_bMapPadOneToPadTwo;
static CKeyboardState &OldKeyState; static CKeyboardState &OldKeyState;
@ -172,8 +177,9 @@ public:
static CMouseControllerState &PCTempMouseControllerState; static CMouseControllerState &PCTempMouseControllerState;
#ifdef GTA_PS2_STUFF
static void Initialise(void);
#endif
void Clear(bool bResetPlayerControls); void Clear(bool bResetPlayerControls);
void ClearMouseHistory(); void ClearMouseHistory();
void UpdateMouse(); void UpdateMouse();
@ -181,6 +187,9 @@ public:
void StartShake(int16 nDur, uint8 nFreq); void StartShake(int16 nDur, uint8 nFreq);
void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz); void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
void StartShake_Train(float fX, float fY); void StartShake_Train(float fX, float fY);
#ifdef GTA_PS2_STUFF
void AddToCheatString(char c);
#endif
void AddToPCCheatString(char c); void AddToPCCheatString(char c);
static void UpdatePads(void); static void UpdatePads(void);

View File

@ -17,7 +17,7 @@
#include "SpecialFX.h" #include "SpecialFX.h"
float &CRadar::m_radarRange = *(float*)0x8E281C; 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; CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
int32 gRadarTxdIds[64];// = (int*)0x6299C0; int32 gRadarTxdIds[64];// = (int*)0x6299C0;
@ -87,6 +87,134 @@ int CRadar::TargetMarkerId = -1;
float CRadar::cachedCos; float CRadar::cachedCos;
float CRadar::cachedSin; 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) uint8 CRadar::CalculateBlipAlpha(float dist)
{ {
#ifdef MENU_MAP #ifdef MENU_MAP
@ -645,15 +773,14 @@ void CRadar::DrawRadarMask()
}; };
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS);
CVector2D out[8]; CVector2D out[8];
CVector2D in; CVector2D in;
@ -675,8 +802,6 @@ void CRadar::DrawRadarMask()
CSprite2d::SetMaskVertices(8, (float *)out); CSprite2d::SetMaskVertices(8, (float *)out);
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8); RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
}; };
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
} }
void CRadar::DrawRadarSection(int32 x, int32 y) void CRadar::DrawRadarSection(int32 x, int32 y)
@ -892,7 +1017,7 @@ INITSAVEBUF
CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE); CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUMRADARBLIPS; i++) for (int i = 0; i < NUMRADARBLIPS; i++)
ms_RadarTrace[i] = ReadSaveBuf<CBlip>(buf); ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf);
VALIDATESAVEBUF(size); VALIDATESAVEBUF(size);
} }
@ -925,12 +1050,6 @@ CRadar::LoadTextures()
CTxdStore::PopCurrentTxd(); 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() void CRadar::RemoveRadarSections()
{ {
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -938,12 +1057,6 @@ void CRadar::RemoveRadarSections()
RemoveMapSection(i, j); 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) void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
{ {
*size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace); *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
@ -1242,121 +1355,6 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
out.y = c * y - s * x; 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 void
CRadar::CalculateCachedSinCos() CRadar::CalculateCachedSinCos()
{ {
@ -1488,8 +1486,14 @@ STARTPATCHES
InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP); InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP); InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, 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(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, 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(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP); InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP); InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
@ -1497,8 +1501,6 @@ STARTPATCHES
InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP); InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP); InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP); InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
//InjectHook(0x4A7000, `global constructor keyed to'Radar.cpp, PATCH_JUMP);
InjectHook(0x4A61C0, CRadar::GetTextureCorners, PATCH_JUMP); //InjectHook(0x4A7260, sRadarTrace::sRadarTrace, PATCH_JUMP);
InjectHook(0x4A6160, CRadar::IsPointInsideRadar, PATCH_JUMP);
InjectHook(0x4A6250, CRadar::LineRadarBoxCollision, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -56,7 +56,7 @@ enum
BLIP_MODE_SQUARE, BLIP_MODE_SQUARE,
}; };
struct CBlip struct sRadarTrace
{ {
uint32 m_nColor; uint32 m_nColor;
uint32 m_eBlipType; // eBlipType uint32 m_eBlipType; // eBlipType
@ -71,7 +71,7 @@ struct CBlip
uint16 m_eBlipDisplay; // eBlipDisplay uint16 m_eBlipDisplay; // eBlipDisplay
uint16 m_eRadarSprite; // eRadarSprite uint16 m_eRadarSprite; // eRadarSprite
}; };
static_assert(sizeof(CBlip) == 0x30, "CBlip: error"); static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
// Values for screen space // Values for screen space
#define RADAR_LEFT (40.0f) #define RADAR_LEFT (40.0f)
@ -83,7 +83,7 @@ class CRadar
{ {
public: public:
static float &m_radarRange; static float &m_radarRange;
static CBlip (&ms_RadarTrace)[NUMRADARBLIPS]; static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
static CSprite2d AsukaSprite; static CSprite2d AsukaSprite;
static CSprite2d BombSprite; static CSprite2d BombSprite;
static CSprite2d CatSprite; static CSprite2d CatSprite;
@ -144,7 +144,6 @@ public:
static void LoadAllRadarBlips(uint8 *buf, uint32 size); static void LoadAllRadarBlips(uint8 *buf, uint32 size);
static void LoadTextures(); static void LoadTextures();
static void RemoveRadarSections(); static void RemoveRadarSections();
static void RequestMapSection(int32 x, int32 y);
static void SaveAllRadarBlips(uint8*, uint32*); static void SaveAllRadarBlips(uint8*, uint32*);
static void SetBlipSprite(int32 i, int32 icon); static void SetBlipSprite(int32 i, int32 icon);
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
@ -162,9 +161,5 @@ public:
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in); static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
// no in CRadar in the game: // 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 &);
static void CalculateCachedSinCos(); static void CalculateCachedSinCos();
}; };

View File

@ -347,13 +347,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
return (nil); return (nil);
} }
WRAPPER void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&) { EAXJMP(0x5926C0); }
WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); }
WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); }
WRAPPER bool CreateTxdImageForVideoCard() { EAXJMP(0x592C70); }
void CreateDebugFont() void CreateDebugFont()
{ {
; ;

View File

@ -3,10 +3,24 @@
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
#pragma warning( pop ) #pragma warning( pop )
#define WITHWINDOWS
#include "common.h" #include "common.h"
#include "win.h" #include "win.h"
#include "patcher.h" #include "patcher.h"
#include "Timer.h" #include "Timer.h"
#ifdef GTA_PC
#include "FileMgr.h"
#include "Pad.h"
#include "main.h"
#include "Directory.h"
#include "Streaming.h"
#include "TxdStore.h"
#include "CdStream.h"
#include "Font.h"
#include "Sprite2d.h"
#include "Text.h"
#include "RwHelper.h"
#endif //GTA_PC
float &texLoadTime = *(float*)0x8F1B50; float &texLoadTime = *(float*)0x8F1B50;
int32 &texNumLoaded = *(int32*)0x8F252C; int32 &texNumLoaded = *(int32*)0x8F252C;
@ -132,9 +146,198 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
return texDict; return texDict;
} }
#ifdef GTA_PC
WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); }
void
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
{
cap32 = UINT32_MAX;
cap24 = UINT32_MAX;
cap16 = UINT32_MAX;
cap8 = UINT32_MAX;
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb");
if (file != 0) {
CFileMgr::Read(file, (char*)&cap32, 4);
CFileMgr::Read(file, (char*)&cap24, 4);
CFileMgr::Read(file, (char*)&cap16, 4);
CFileMgr::Read(file, (char*)&cap8, 4);
CFileMgr::CloseFile(file);
}
}
bool
CheckVideoCardCaps(void)
{
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
uint32 fcap32, fcap24, fcap16, fcap8;
ReadVideoCardCapsFile(fcap32, fcap24, fcap16, fcap8);
return cap32 != fcap32 || cap24 != fcap24 || cap16 != fcap16 || cap8 != fcap8;
}
void
WriteVideoCardCapsFile(void)
{
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb");
if (file != 0) {
CFileMgr::Write(file, (char*)&cap32, 4);
CFileMgr::Write(file, (char*)&cap24, 4);
CFileMgr::Write(file, (char*)&cap16, 4);
CFileMgr::Write(file, (char*)&cap8, 4);
CFileMgr::CloseFile(file);
}
}
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
void
ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
{
HandleExit();
CSprite2d *splash = LoadSplash(nil);
if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
return;
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));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 217, 106, 255));
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
void
DealWithTxdWriteError(uint32 num, uint32 count, const char *text)
{
while (!RsGlobal.quit) {
ConvertingTexturesScreen(num, count, text);
CPad::UpdatePads();
if (CPad::GetPad(0)->GetEscapeJustDown())
break;
}
RsGlobal.quit = false;
LoadingScreen(nil, nil, nil);
RsGlobal.quit = true;
}
bool
CreateTxdImageForVideoCard()
{
uint8 *buf = new uint8[CDSTREAM_SECTOR_SIZE];
CDirectory *pDir = new CDirectory(TXDSTORESIZE);
CDirectory::DirectoryInfo dirInfo;
CStreaming::FlushRequestList();
RwFileFunctions *filesys = RwOsGetFileInterface();
RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img");
if (img == nil) {
if (_dwOperatingSystemVersion == OS_WINNT || _dwOperatingSystemVersion == OS_WIN2000 || _dwOperatingSystemVersion == OS_WINXP) {
DealWithTxdWriteError(0, TXDSTORESIZE, "CVT_CRT");
delete []buf;
delete pDir;
}
return false;
}
int32 i;
for (i = 0; i < TXDSTORESIZE; i++) {
ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) {
CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY);
CStreaming::RequestModelStream(0);
CStreaming::FlushChannels();
char filename[64];
sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i));
if (CTxdStore::GetSlot(i)->texDict) {
int32 pos = filesys->rwftell(img->Type.file.fpFile);
if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
RwStreamClose(img, nil);
delete []buf;
delete pDir;
CStreaming::RemoveTxd(i);
return false;
}
int32 size = filesys->rwftell(img->Type.file.fpFile) - pos;
int32 num = size % CDSTREAM_SECTOR_SIZE;
size /= CDSTREAM_SECTOR_SIZE;
if (num != 0) {
size++;
num = CDSTREAM_SECTOR_SIZE - num;
RwStreamWrite(img, buf, num);
}
dirInfo.offset = pos / CDSTREAM_SECTOR_SIZE;
dirInfo.size = size;
strncpy(dirInfo.name, filename, sizeof(dirInfo.name));
pDir->AddItem(dirInfo);
CStreaming::RemoveTxd(i);
}
CStreaming::FlushRequestList();
}
}
RwStreamClose(img, nil);
delete []buf;
if (!pDir->WriteDirFile("models\\txd.dir")) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
delete pDir;
return false;
}
delete pDir;
WriteVideoCardCapsFile();
return true;
}
#endif // GTA_PC
STARTPATCHES STARTPATCHES
InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP); InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP); InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP); InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP); InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP);
InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP);
InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP);
InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP);
InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP);
InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -1,14 +1,14 @@
#include "common.h" #include "common.h"
#include "patcher.h" #include "patcher.h"
#include "Stats.h" #include "Stats.h"
#include "Text.h"
WRAPPER void CStats::SaveStats(uint8 *buf, uint32 *size) { EAXJMP(0x4ab3e0); } #include "World.h"
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8; int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
int32 &CStats::HeadsPopped = *(int32*)0x8F647C; int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
bool& CStats::CommercialPassed = *(bool*)0x8F4334; int32& CStats::CommercialPassed = *(int32*)0x8F4334;
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68; int32& CStats::IndustrialPassed = *(int32*)0x8E2A68;
bool& CStats::SuburbanPassed = *(bool*)0x8F2740; int32& CStats::SuburbanPassed = *(int32*)0x8F2740;
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C; int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50; int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64; int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
@ -48,7 +48,7 @@ int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24; int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884; int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
int32& CStats::TotalNumberMissions = *(int32*)0x8E2820; int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
int32& CStats::ShotsMade = *(int32*)0x8E2BE8; int32& CStats::RoundsFiredByPlayer = *(int32*)0x8E2BE8;
int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510; int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510;
int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070; int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070;
int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C; int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C;
@ -62,7 +62,7 @@ void CStats::Init()
{ {
PeopleKilledByOthers = 0; PeopleKilledByOthers = 0;
PeopleKilledByPlayer = 0; PeopleKilledByPlayer = 0;
ShotsMade = 0; RoundsFiredByPlayer = 0;
CarsExploded = 0; CarsExploded = 0;
HelisDestroyed = 0; HelisDestroyed = 0;
ProgressMade = 0; ProgressMade = 0;
@ -200,6 +200,229 @@ void CStats::SetTotalNumberMissions(int32 total)
TotalNumberMissions = total; TotalNumberMissions = total;
} }
wchar *CStats::FindCriminalRatingString()
{
int rating = FindCriminalRatingNumber();
if (rating < 10) return TheText.Get("RATNG1");
if (rating < 25) return TheText.Get("RATNG2");
if (rating < 70) return TheText.Get("RATNG3");
if (rating < 150) return TheText.Get("RATNG4");
if (rating < 250) return TheText.Get("RATNG5");
if (rating < 450) return TheText.Get("RATNG6");
if (rating < 700) return TheText.Get("RATNG7");
if (rating < 1000) return TheText.Get("RATNG8");
if (rating < 1400) return TheText.Get("RATNG9");
if (rating < 1900) return TheText.Get("RATNG10");
if (rating < 2500) return TheText.Get("RATNG11");
if (rating < 3200) return TheText.Get("RATNG12");
if (rating < 4000) return TheText.Get("RATNG13");
if (rating < 5000) return TheText.Get("RATNG14");
return TheText.Get("RATNG15");
}
int32 CStats::FindCriminalRatingNumber()
{
int32 rating;
rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
if (rating <= 0) rating = 0;
if (InstantHitsFiredByPlayer > 100)
rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
if (!IndustrialPassed && rating >= 3521)
rating = 3521;
if (!CommercialPassed && rating >= 4552)
rating = 4552;
return rating;
}
void CStats::SaveStats(uint8 *buf, uint32 *size)
{
CheckPointReachedSuccessfully();
uint8 *buf_start = buf;
*size = sizeof(PeopleKilledByPlayer) +
sizeof(PeopleKilledByOthers) +
sizeof(CarsExploded) +
sizeof(RoundsFiredByPlayer) +
sizeof(PedsKilledOfThisType) +
sizeof(HelisDestroyed) +
sizeof(ProgressMade) +
sizeof(TotalProgressInGame) +
sizeof(KgsOfExplosivesUsed) +
sizeof(InstantHitsFiredByPlayer) +
sizeof(InstantHitsHitByPlayer) +
sizeof(CarsCrushed) +
sizeof(HeadsPopped) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
sizeof(mmRain) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
sizeof(MaximumJumpSpins) +
sizeof(BestStuntJump) +
sizeof(NumberOfUniqueJumpsFound) +
sizeof(TotalNumberOfUniqueJumps) +
sizeof(MissionsGiven) +
sizeof(MissionsPassed) +
sizeof(PassengersDroppedOffWithTaxi) +
sizeof(MoneyMadeWithTaxi) +
sizeof(IndustrialPassed) +
sizeof(CommercialPassed) +
sizeof(SuburbanPassed) +
sizeof(ElBurroTime) +
sizeof(DistanceTravelledOnFoot) +
sizeof(DistanceTravelledInVehicle) +
sizeof(Record4x4One) +
sizeof(Record4x4Two) +
sizeof(Record4x4Three) +
sizeof(Record4x4Mayhem) +
sizeof(LivesSavedWithAmbulance) +
sizeof(CriminalsCaught) +
sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
sizeof(LongestFlightInDodo) +
sizeof(TimeTakenDefuseMission) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
sizeof(TotalNumberMissions) +
sizeof(FastestTimes) +
sizeof(HighestScores) +
sizeof(KillsSinceLastCheckpoint) +
sizeof(TotalLegitimateKills) +
sizeof(LastMissionPassedName);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, PeopleKilledByPlayer);
CopyToBuf(buf, PeopleKilledByOthers);
CopyToBuf(buf, CarsExploded);
CopyToBuf(buf, RoundsFiredByPlayer);
CopyToBuf(buf, PedsKilledOfThisType);
CopyToBuf(buf, HelisDestroyed);
CopyToBuf(buf, ProgressMade);
CopyToBuf(buf, TotalProgressInGame);
CopyToBuf(buf, KgsOfExplosivesUsed);
CopyToBuf(buf, InstantHitsFiredByPlayer);
CopyToBuf(buf, InstantHitsHitByPlayer);
CopyToBuf(buf, CarsCrushed);
CopyToBuf(buf, HeadsPopped);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
CopyToBuf(buf, mmRain);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
CopyToBuf(buf, MaximumJumpSpins);
CopyToBuf(buf, BestStuntJump);
CopyToBuf(buf, NumberOfUniqueJumpsFound);
CopyToBuf(buf, TotalNumberOfUniqueJumps);
CopyToBuf(buf, MissionsGiven);
CopyToBuf(buf, MissionsPassed);
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
CopyToBuf(buf, MoneyMadeWithTaxi);
CopyToBuf(buf, IndustrialPassed);
CopyToBuf(buf, CommercialPassed);
CopyToBuf(buf, SuburbanPassed);
CopyToBuf(buf, ElBurroTime);
CopyToBuf(buf, DistanceTravelledOnFoot);
CopyToBuf(buf, DistanceTravelledInVehicle);
CopyToBuf(buf, Record4x4One);
CopyToBuf(buf, Record4x4Two);
CopyToBuf(buf, Record4x4Three);
CopyToBuf(buf, Record4x4Mayhem);
CopyToBuf(buf, LivesSavedWithAmbulance);
CopyToBuf(buf, CriminalsCaught);
CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
CopyToBuf(buf, LongestFlightInDodo);
CopyToBuf(buf, TimeTakenDefuseMission);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
CopyToBuf(buf, TotalNumberMissions);
CopyToBuf(buf, FastestTimes);
CopyToBuf(buf, HighestScores);
CopyToBuf(buf, KillsSinceLastCheckpoint);
CopyToBuf(buf, TotalLegitimateKills);
CopyToBuf(buf, LastMissionPassedName);
assert(buf - buf_start == *size);
#undef CopyToBuf
}
void CStats::LoadStats(uint8 *buf, uint32 size)
{
uint8* buf_start = buf;
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
CopyFromBuf(buf, PeopleKilledByPlayer);
CopyFromBuf(buf, PeopleKilledByOthers);
CopyFromBuf(buf, CarsExploded);
CopyFromBuf(buf, RoundsFiredByPlayer);
CopyFromBuf(buf, PedsKilledOfThisType);
CopyFromBuf(buf, HelisDestroyed);
CopyFromBuf(buf, ProgressMade);
CopyFromBuf(buf, TotalProgressInGame);
CopyFromBuf(buf, KgsOfExplosivesUsed);
CopyFromBuf(buf, InstantHitsFiredByPlayer);
CopyFromBuf(buf, InstantHitsHitByPlayer);
CopyFromBuf(buf, CarsCrushed);
CopyFromBuf(buf, HeadsPopped);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
CopyFromBuf(buf, mmRain);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
CopyFromBuf(buf, MaximumJumpSpins);
CopyFromBuf(buf, BestStuntJump);
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
CopyFromBuf(buf, MissionsGiven);
CopyFromBuf(buf, MissionsPassed);
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
CopyFromBuf(buf, MoneyMadeWithTaxi);
CopyFromBuf(buf, IndustrialPassed);
CopyFromBuf(buf, CommercialPassed);
CopyFromBuf(buf, SuburbanPassed);
CopyFromBuf(buf, ElBurroTime);
CopyFromBuf(buf, DistanceTravelledOnFoot);
CopyFromBuf(buf, DistanceTravelledInVehicle);
CopyFromBuf(buf, Record4x4One);
CopyFromBuf(buf, Record4x4Two);
CopyFromBuf(buf, Record4x4Three);
CopyFromBuf(buf, Record4x4Mayhem);
CopyFromBuf(buf, LivesSavedWithAmbulance);
CopyFromBuf(buf, CriminalsCaught);
CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
CopyFromBuf(buf, LongestFlightInDodo);
CopyFromBuf(buf, TimeTakenDefuseMission);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);
CopyFromBuf(buf, TotalNumberMissions);
CopyFromBuf(buf, FastestTimes);
CopyFromBuf(buf, HighestScores);
CopyFromBuf(buf, KillsSinceLastCheckpoint);
CopyFromBuf(buf, TotalLegitimateKills);
CopyFromBuf(buf, LastMissionPassedName);
assert(buf - buf_start == size);
#undef CopyFromBuf
}
STARTPATCHES STARTPATCHES
InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables
InjectHook(0x4AB3E0, CStats::SaveStats, PATCH_JUMP);
InjectHook(0x4AB670, CStats::LoadStats, PATCH_JUMP);
InjectHook(0x4AB090, CStats::FindCriminalRatingString, PATCH_JUMP);
InjectHook(0x4AB2A0, CStats::FindCriminalRatingNumber, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -11,9 +11,9 @@ public:
}; };
static int32 &DaysPassed; static int32 &DaysPassed;
static int32 &HeadsPopped; static int32 &HeadsPopped;
static bool& CommercialPassed; static int32& CommercialPassed;
static bool& IndustrialPassed; static int32& IndustrialPassed;
static bool& SuburbanPassed; static int32& SuburbanPassed;
static int32 &NumberKillFrenziesPassed; static int32 &NumberKillFrenziesPassed;
static int32 &PeopleKilledByOthers; static int32 &PeopleKilledByOthers;
static int32 &HelisDestroyed; static int32 &HelisDestroyed;
@ -53,7 +53,7 @@ public:
static int32 &TimeTakenDefuseMission; static int32 &TimeTakenDefuseMission;
static int32 &TotalNumberKillFrenzies; static int32 &TotalNumberKillFrenzies;
static int32 &TotalNumberMissions; static int32 &TotalNumberMissions;
static int32 &ShotsMade; static int32 &RoundsFiredByPlayer;
static int32 &KgsOfExplosivesUsed; static int32 &KgsOfExplosivesUsed;
static int32 &InstantHitsFiredByPlayer; static int32 &InstantHitsFiredByPlayer;
static int32 &InstantHitsHitByPlayer; static int32 &InstantHitsHitByPlayer;
@ -64,24 +64,27 @@ public:
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES]; static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
public: public:
static void Init(void);
static void RegisterFastestTime(int32, int32); static void RegisterFastestTime(int32, int32);
static void RegisterHighestScore(int32, int32); static void RegisterHighestScore(int32, int32);
static void AnotherKillFrenzyPassed(); static void RegisterElBurroTime(int32);
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static void Register4x4OneTime(int32); static void Register4x4OneTime(int32);
static void Register4x4TwoTime(int32); static void Register4x4TwoTime(int32);
static void Register4x4ThreeTime(int32); static void Register4x4ThreeTime(int32);
static void Register4x4MayhemTime(int32); static void Register4x4MayhemTime(int32);
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
static void RegisterLongestFlightInDodo(int32); static void RegisterLongestFlightInDodo(int32);
static void RegisterTimeTakenDefuseMission(int32); static void RegisterTimeTakenDefuseMission(int32);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32); static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32); static void SetTotalNumberMissions(int32);
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; }; static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
static void RegisterElBurroTime(int32); static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static int32 FindCriminalRatingNumber();
static void SaveStats(uint8 *buf, uint32 *size); static void SaveStats(uint8 *buf, uint32 *size);
static void Init(void); static void LoadStats(uint8 *buf, uint32 size);
}; };

View File

@ -56,6 +56,8 @@ WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const C
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); } WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); } WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); } WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
void void
CWorld::Initialise() CWorld::Initialise()

View File

@ -132,6 +132,7 @@ public:
static void SetAllCarsCanBeDamaged(bool); static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float); static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float, float, float, float, CEntity*); static void SetCarsOnFire(float, float, float, float, CEntity*);
static void SetPedsOnFire(float, float, float, float, CEntity*);
static void Initialise(); static void Initialise();
static void AddParticles(); static void AddParticles();
@ -140,6 +141,7 @@ public:
static void RepositionCertainDynamicObjects(); static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects(); static void RemoveStaticObjects();
static void Process(); static void Process();
static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
}; };
extern CColPoint *gaTempSphereColPoints; extern CColPoint *gaTempSphereColPoints;

View File

@ -84,12 +84,14 @@ extern void **rwengine;
#define DEFAULT_SCREEN_WIDTH (640) #define DEFAULT_SCREEN_WIDTH (640)
#define DEFAULT_SCREEN_HEIGHT (448) #define DEFAULT_SCREEN_HEIGHT (448)
#define DEFAULT_ASPECT_RATIO (4.0f/3.0f) #define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
#define DEFAULT_VIEWWINDOW (0.7f)
// game uses maximumWidth/Height, but this probably won't work // game uses maximumWidth/Height, but this probably won't work
// with RW windowed mode // with RW windowed mode
#define SCREEN_WIDTH ((float)RsGlobal.width) #define SCREEN_WIDTH ((float)RsGlobal.width)
#define SCREEN_HEIGHT ((float)RsGlobal.height) #define SCREEN_HEIGHT ((float)RsGlobal.height)
#define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio()) #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 // This scales from PS2 pixel coordinates to the real resolution
#define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH) #define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
@ -105,10 +107,8 @@ extern void **rwengine;
#ifdef ASPECT_RATIO_SCALE #ifdef ASPECT_RATIO_SCALE
#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) #define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
#define SCREEN_SCALE_AR2(a) ((a) / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO))
#else #else
#define SCREEN_SCALE_AR(a) (a) #define SCREEN_SCALE_AR(a) (a)
#define SCREEN_SCALE_AR2(a) (a)
#endif #endif
#include "maths.h" #include "maths.h"

View File

@ -79,6 +79,7 @@ enum Config {
NUMPICKUPMESSAGES = 16, NUMPICKUPMESSAGES = 16,
NUMBULLETTRACES = 16, NUMBULLETTRACES = 16,
NUMMBLURSTREAKS = 4, NUMMBLURSTREAKS = 4,
NUMSKIDMARKS = 32,
NUMONSCREENTIMERENTRIES = 1, NUMONSCREENTIMERENTRIES = 1,
NUMRADARBLIPS = 32, NUMRADARBLIPS = 32,
@ -125,7 +126,9 @@ enum Config {
NUM_GARAGE_STORED_CARS = 6, NUM_GARAGE_STORED_CARS = 6,
NUM_CRANES = 8 NUM_CRANES = 8,
NUM_EXPLOSIONS = 48,
}; };
// We'll use this once we're ready to become independent of the game // We'll use this once we're ready to become independent of the game
@ -150,6 +153,7 @@ enum Config {
//#define MASTER //#define MASTER
#if defined GTA_PS2 #if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH # define RANDOMSPLASH
#elif defined GTA_PC #elif defined GTA_PC
# define GTA3_1_1_PATCH # define GTA3_1_1_PATCH

File diff suppressed because it is too large Load Diff

View File

@ -275,9 +275,9 @@ CEntity::CreateRwObject(void)
if(IsBuilding()) if(IsBuilding())
gBuildings++; gBuildings++;
if(RwObjectGetType(m_rwObject) == rpATOMIC) if(RwObjectGetType(m_rwObject) == rpATOMIC)
m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false); m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP) else if(RwObjectGetType(m_rwObject) == rpCLUMP)
m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false); m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
mi->AddRef(); mi->AddRef();
} }
} }
@ -290,7 +290,7 @@ CEntity::DeleteRwObject(void)
m_matrix.Detach(); m_matrix.Detach();
if(m_rwObject){ if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC){ if(RwObjectGetType(m_rwObject) == rpATOMIC){
f = RpAtomicGetFrame(m_rwObject); f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
RpAtomicDestroy((RpAtomic*)m_rwObject); RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f); RwFrameDestroy(f);
}else if(RwObjectGetType(m_rwObject) == rpCLUMP) }else if(RwObjectGetType(m_rwObject) == rpCLUMP)
@ -307,9 +307,9 @@ CEntity::UpdateRwFrame(void)
{ {
if(m_rwObject){ if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC) if(RwObjectGetType(m_rwObject) == rpATOMIC)
RwFrameUpdateObjects(RpAtomicGetFrame(m_rwObject)); RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
else if(RwObjectGetType(m_rwObject) == rpCLUMP) else if(RwObjectGetType(m_rwObject) == rpCLUMP)
RwFrameUpdateObjects(RpClumpGetFrame(m_rwObject)); RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
} }
} }
@ -482,9 +482,9 @@ CEntity::AttachToRwObject(RwObject *obj)
m_rwObject = obj; m_rwObject = obj;
if(m_rwObject){ if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC) if(RwObjectGetType(m_rwObject) == rpATOMIC)
m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false); m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP) else if(RwObjectGetType(m_rwObject) == rpCLUMP)
m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false); m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
} }
} }

View File

@ -216,7 +216,7 @@ CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
RwMatrixCopy(mat, RwFrameGetMatrix(f)); RwMatrixCopy(mat, RwFrameGetMatrix(f));
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) { for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
RwMatrixTransform(mat, &f->modelling, rwCOMBINEPOSTCONCAT); RwMatrixTransform(mat, RwFrameGetMatrix(f), rwCOMBINEPOSTCONCAT);
if (RwFrameGetParent(f) == frame) if (RwFrameGetParent(f) == frame)
break; break;
} }

View File

@ -707,7 +707,7 @@ RpMaterial*
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data) CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
{ {
static RwRGBA white = { 255, 255, 255, 255 }; static RwRGBA white = { 255, 255, 255, 255 };
RwRGBA *col; const RwRGBA *col;
editableMatCBData *cbdata; editableMatCBData *cbdata;
cbdata = (editableMatCBData*)data; cbdata = (editableMatCBData*)data;
@ -758,8 +758,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c1]; col = ms_vehicleColourTable[c1];
coltex = ms_colourTextureTable[c1]; coltex = ms_colourTextureTable[c1];
for(matp = m_materials1; *matp; matp++){ for(matp = m_materials1; *matp; matp++){
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){ if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
colp = RpMaterialGetColor(*matp); colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red; colp->red = col.red;
colp->green = col.green; colp->green = col.green;
colp->blue = col.blue; colp->blue = col.blue;
@ -773,8 +773,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c2]; col = ms_vehicleColourTable[c2];
coltex = ms_colourTextureTable[c2]; coltex = ms_colourTextureTable[c2];
for(matp = m_materials2; *matp; matp++){ for(matp = m_materials2; *matp; matp++){
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){ if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
colp = RpMaterialGetColor(*matp); colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red; colp->red = col.red;
colp->green = col.green; colp->green = col.green;
colp->blue = col.blue; colp->blue = col.blue;
@ -861,7 +861,7 @@ CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
RwImageDestroy(img); RwImageDestroy(img);
RwFree(pixels); RwFree(pixels);
tex = RwTextureCreate(ras); tex = RwTextureCreate(ras);
tex->name[0] = '@'; RwTextureGetName(tex)[0] = '@';
return tex; return tex;
} }
@ -1058,7 +1058,7 @@ CVehicleModelInfo::LoadEnvironmentMaps(void)
} }
if(gpWhiteTexture == nil){ if(gpWhiteTexture == nil){
gpWhiteTexture = RwTextureRead("white", nil); gpWhiteTexture = RwTextureRead("white", nil);
gpWhiteTexture->name[0] = '@'; RwTextureGetName(gpWhiteTexture)[0] = '@';
RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR); RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR);
} }
CTxdStore::PopCurrentTxd(); CTxdStore::PopCurrentTxd();

View File

@ -20,7 +20,7 @@ CCutsceneHead::CCutsceneHead(CObject *obj)
m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame; m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
atm = (RpAtomic*)GetFirstObject(m_pHeadNode); atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
if(atm){ if(atm){
assert(RwObjectGetType(atm) == rpATOMIC); assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER); RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
} }
} }

View File

@ -154,7 +154,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_nRemoveTimer = 0; pobj->m_nRemoveTimer = 0;
if ( color.alpha != 0 ) if ( color.alpha != 0 )
RwRGBAAssign(&pobj->m_Color, &color); pobj->m_Color, color;
else else
pobj->m_Color.alpha = 0; pobj->m_Color.alpha = 0;

View File

@ -676,7 +676,7 @@ RemoveAllModelCB(RwObject *object, void *data)
{ {
RpAtomic *atomic = (RpAtomic*)object; RpAtomic *atomic = (RpAtomic*)object;
if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) { if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
RpClumpRemoveAtomic(atomic->clump, atomic); RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
RpAtomicDestroy(atomic); RpAtomicDestroy(atomic);
} }
return object; return object;
@ -902,7 +902,7 @@ static RwObject*
SetPedAtomicVisibilityCB(RwObject* object, void* data) SetPedAtomicVisibilityCB(RwObject* object, void* data)
{ {
if (data == nil) if (data == nil)
RpAtomicSetFlags(object, 0); RpAtomicSetFlags((RpAtomic*)object, 0);
return object; return object;
} }

View File

@ -340,7 +340,7 @@ CPedIK::RestoreLookAt(void)
} }
void void
CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch) CPedIK::ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch)
{ {
float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f); float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f);
*yaw = Acos(f); *yaw = Acos(f);
@ -352,7 +352,7 @@ CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
} }
void void
CPedIK::ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch) CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
{ {
float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f); float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f);
*yaw = Acos(f); *yaw = Acos(f);

View File

@ -54,8 +54,8 @@ public:
void GetComponentPosition(RwV3d *pos, uint32 node); void GetComponentPosition(RwV3d *pos, uint32 node);
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination); static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch); void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo); LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void); bool RestoreGunPosn(void);
bool LookInDirection(float phi, float theta); bool LookInDirection(float phi, float theta);

View File

@ -85,6 +85,7 @@ public:
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; } static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; } static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; } static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
static void SetThreats(int type, uint32 threat) { ms_apPedType[type]->m_threats = threat; }
static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; } static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; } static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; } static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }

View File

@ -704,12 +704,15 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (i != 0) { if (i != 0) {
// Gang member // Gang member
newPed->SetLeader(gangLeader); newPed->SetLeader(gangLeader);
#ifndef FIX_BUGS
// seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
newPed->m_nPedState = PED_UNKNOWN; newPed->m_nPedState = PED_UNKNOWN;
gangLeader->m_nPedState = PED_UNKNOWN; gangLeader->m_nPedState = PED_UNKNOWN;
newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints( newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
gangLeader->GetPosition().x, gangLeader->GetPosition().y, gangLeader->GetPosition().x, gangLeader->GetPosition().y,
newPed->GetPosition().x, newPed->GetPosition().y); newPed->GetPosition().x, newPed->GetPosition().y);
newPed->m_fRotationDest = newPed->m_fRotationCur; newPed->m_fRotationDest = newPed->m_fRotationCur;
#endif
} else { } else {
gangLeader = newPed; gangLeader = newPed;
} }

View File

@ -87,7 +87,7 @@ CClouds::Render(void)
RwV3d pos = { 0.0f, -100.0f, 15.0f }; RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos); RwV3dAdd(&worldpos, &campos, &pos);
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){ if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
if(CCoronas::bSmallMoon){ if(CCoronas::bSmallMoon){
szx *= 4.0f; szx *= 4.0f;
szy *= 4.0f; szy *= 4.0f;
@ -116,7 +116,7 @@ CClouds::Render(void)
static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f }; static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f }; static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
int brightness = (1.0f - coverage) * starintens; int brightness = (1.0f - coverage) * starintens;
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 11; i++){ for(i = 0; i < 11; i++){
RwV3d pos = { 100.0f, 0.0f, 10.0f }; RwV3d pos = { 100.0f, 0.0f, 10.0f };
if(i >= 9) pos.x = -pos.x; if(i >= 9) pos.x = -pos.x;
@ -132,7 +132,7 @@ CClouds::Render(void)
CSprite::FlushSpriteBuffer(); CSprite::FlushSpriteBuffer();
// * // *
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
RwV3d pos = { 100.0f, 0.0f, 10.0f }; RwV3d pos = { 100.0f, 0.0f, 10.0f };
RwV3dAdd(&worldpos, &campos, &pos); RwV3dAdd(&worldpos, &campos, &pos);
worldpos.y -= 90.0f; worldpos.y -= 90.0f;
@ -156,7 +156,7 @@ CClouds::Render(void)
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity; int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
for(int cloudtype = 0; cloudtype < 3; cloudtype++){ for(int cloudtype = 0; cloudtype < 3; cloudtype++){
for(i = cloudtype; i < 12; i += 3){ for(i = cloudtype; i < 12; i += 3){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype]));
RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] }; RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] };
worldpos.x = campos.x + pos.x; worldpos.x = campos.x + pos.x;
worldpos.y = campos.y + pos.y; worldpos.y = campos.y + pos.y;
@ -202,7 +202,7 @@ CClouds::Render(void)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4]));
for(i = 0; i < 37; i++){ for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f }; RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x; worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
@ -244,7 +244,7 @@ CClouds::Render(void)
// Highlights // Highlights
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3]));
for(i = 0; i < 37; i++){ for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f }; RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
@ -269,7 +269,7 @@ CClouds::Render(void)
static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 }; static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 }; static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 }; static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 6; i++){ for(i = 0; i < 6; i++){
RwV3d pos = { i*1.5f, 100.0f, 5.0f }; RwV3d pos = { i*1.5f, 100.0f, 5.0f };
RwV3dAdd(&worldpos, &campos, &pos); RwV3dAdd(&worldpos, &campos, &pos);

View File

@ -320,7 +320,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z, CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * wscale, spritew * aCoronas[i].size * wscale,
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale * hscale), spriteh * aCoronas[i].size * fogscale * hscale,
CCoronas::aCoronas[i].red / fogscale, CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale, CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale, CCoronas::aCoronas[i].blue / fogscale,
@ -331,7 +331,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite_Rotate_Aspect( CSprite::RenderOneXLUSprite_Rotate_Aspect(
spriteCoors.x, spriteCoors.y, spriteCoors.z, spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * fogscale, spritew * aCoronas[i].size * fogscale,
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale), spriteh * aCoronas[i].size * fogscale,
CCoronas::aCoronas[i].red / fogscale, CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale, CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale, CCoronas::aCoronas[i].blue / fogscale,

View File

@ -755,14 +755,14 @@ void CTowerClock::Render()
&TempV[1], &TempV[1],
m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x, m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y, m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
m_Position.z + Cos(angleMinute) * m_fScale; m_Position.z + Cos(angleMinute) * m_fScale
); );
RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z); RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
RwIm3DVertexSetPos( RwIm3DVertexSetPos(
&TempV[3], &TempV[3],
m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x, m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y, m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
m_Position.z + Cos(angleHour) * 0.75f * m_fScale; m_Position.z + Cos(angleHour) * 0.75f * m_fScale
); );
LittleTest(); LittleTest();

View File

@ -815,7 +815,7 @@ void CHud::Draw()
DrawScriptText DrawScriptText
*/ */
if (!CTimer::GetIsUserPaused()) { if (!CTimer::GetIsUserPaused()) {
CTextLine* IntroText = CTheScripts::IntroTextLines; intro_text_line* IntroText = CTheScripts::IntroTextLines;
for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) { for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) { 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++) { for (int i = 0; i < 16; i++) {
if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) { if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {

View File

@ -4,12 +4,13 @@
#include "Camera.h" #include "Camera.h"
#include "MBlur.h" #include "MBlur.h"
// Originally taken from RW example 'mblur'
RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48; RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB; bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
bool &CMBlur::BlurOn = *(bool*)0x95CDAD; bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
static RwIm2DVertex Vertex[4]; static RwIm2DVertex Vertex[4];
//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 }; static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
void void

View File

@ -15,6 +15,9 @@
#include "Timer.h" #include "Timer.h"
#include "Lights.h" #include "Lights.h"
RpClump *gpPlayerClump;
float gOldFov;
int CPlayerSkin::m_txdSlot; int CPlayerSkin::m_txdSlot;
void void
@ -92,7 +95,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
CTxdStore::SetCurrentTxd(m_txdSlot); CTxdStore::SetCurrentTxd(m_txdSlot);
tex = RwTextureRead(texName, NULL); tex = RwTextureRead(texName, NULL);
CTxdStore::PopCurrentTxd(); CTxdStore::PopCurrentTxd();
if (tex) return tex; if (tex != nil) return tex;
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0) if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
sprintf(gString, "models\\generic\\player.bmp"); sprintf(gString, "models\\generic\\player.bmp");
@ -106,7 +109,9 @@ CPlayerSkin::GetSkinTexture(const char *texName)
tex = RwTextureCreate(raster); tex = RwTextureCreate(raster);
RwTextureSetName(tex, texName); RwTextureSetName(tex, texName);
#ifdef FIX_BUGS
RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
#endif
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex); RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
RwImageDestroy(image); RwImageDestroy(image);
@ -137,7 +142,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
{ {
static float rotation = 0.0f; static float rotation = 0.0f;
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f }; RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
RwV3d pos = { 1.35f, 0.35f, 7.725f }; const RwV3d pos = { 1.35f, 0.35f, 7.725f };
const RwV3d axis1 = { 1.0f, 0.0f, 0.0f }; const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
const RwV3d axis2 = { 0.0f, 0.0f, 1.0f }; const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
static uint32 LastFlash = 0; static uint32 LastFlash = 0;

View File

@ -2,12 +2,6 @@
#define DEFAULT_SKIN_NAME "$$\"\"" #define DEFAULT_SKIN_NAME "$$\"\""
static RpClump *gpPlayerClump;// = *(RpClump**)0x660FF8;
static float gOldFov;// = *(float*)0x660FFC;
void LoadPlayerDff(void);
void FindPlayerDff(uint32 &offset, uint32 &size);
class CPlayerSkin class CPlayerSkin
{ {
static int m_txdSlot; static int m_txdSlot;

View File

@ -1,12 +1,247 @@
#include "common.h" #include "common.h"
#include "patcher.h" #include "patcher.h"
#include "main.h"
#include "TxdStore.h"
#include "Timer.h"
#include "Replay.h"
#include "Skidmarks.h" #include "Skidmarks.h"
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); } CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); } RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); } RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
RwTexture *gpSkidTex;
RwTexture *gpSkidBloodTex;
RwTexture *gpSkidMudTex;
WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); } void
WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); } CSkidmarks::Init(void)
{
int i, ix, slot;
CTxdStore::PushCurrentTxd();
slot = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slot);
gpSkidTex = RwTextureRead("particleskid", nil);
gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
gpSkidMudTex = RwTextureRead("particleskidmud", nil);
CTxdStore::PopCurrentTxd();
for(i = 0; i < NUMSKIDMARKS; i++){
aSkidmarks[i].m_state = 0;
aSkidmarks[i].m_wasUpdated = false;
}
ix = 0;
for(i = 0; i < SKIDMARK_LENGTH; i++){
SkidmarkIndexList[i*6+0] = ix+0;
SkidmarkIndexList[i*6+1] = ix+2;
SkidmarkIndexList[i*6+2] = ix+1;
SkidmarkIndexList[i*6+3] = ix+1;
SkidmarkIndexList[i*6+4] = ix+2;
SkidmarkIndexList[i*6+5] = ix+3;
ix += 2;
}
for(i = 0; i < SKIDMARK_LENGTH; i++){
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
}
}
void
CSkidmarks::Shutdown(void)
{
RwTextureDestroy(gpSkidTex);
RwTextureDestroy(gpSkidBloodTex);
RwTextureDestroy(gpSkidMudTex);
}
void
CSkidmarks::Clear(void)
{
int i;
for(i = 0; i < NUMSKIDMARKS; i++){
aSkidmarks[i].m_state = 0;
aSkidmarks[i].m_wasUpdated = false;
}
}
void
CSkidmarks::Update(void)
{
int i;
uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500;
uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000;
uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000;
uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000;
for(i = 0; i < NUMSKIDMARKS; i++){
switch(aSkidmarks[i].m_state){
case 1:
if(!aSkidmarks[i].m_wasUpdated){
// Didn't continue this one last time, so finish it and set fade times
aSkidmarks[i].m_state = 2;
if(aSkidmarks[i].m_last < 4){
aSkidmarks[i].m_fadeStart = t1;
aSkidmarks[i].m_fadeEnd = t2;
}else if(aSkidmarks[i].m_last < 9){
aSkidmarks[i].m_fadeStart = t2;
aSkidmarks[i].m_fadeEnd = t3;
}else{
aSkidmarks[i].m_fadeStart = t3;
aSkidmarks[i].m_fadeEnd = t4;
}
}
break;
case 2:
if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd)
aSkidmarks[i].m_state = 0;
break;
}
aSkidmarks[i].m_wasUpdated = false;
}
}
void
CSkidmarks::Render(void)
{
int i, j;
RwTexture *lastTex = nil;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
for(i = 0; i < NUMSKIDMARKS; i++){
if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
continue;
if(aSkidmarks[i].m_isBloody){
if(lastTex != gpSkidBloodTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
lastTex = gpSkidBloodTex;
}
}else if(aSkidmarks[i].m_isMuddy){
if(lastTex != gpSkidMudTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
lastTex = gpSkidMudTex;
}
}else{
if(lastTex != gpSkidTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
lastTex = gpSkidTex;
}
}
uint32 fade, alpha;
if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
fade = 255;
else
fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart);
for(j = 0; j <= aSkidmarks[i].m_last; j++){
alpha = 128;
if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2)
alpha = 0;
alpha = alpha*fade/256;
CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
}
LittleTest();
if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last);
RwIm3DEnd();
}
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
void
CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
{
int i;
CVector2D fwd(fwdX, fwdY);
if(CReplay::IsPlayingBack())
return;
// Find a skidmark to continue
for(i = 0; i < NUMSKIDMARKS; i++)
if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id)
break;
if(i < NUMSKIDMARKS){
// Continue this one
if(aSkidmarks[i].m_isBloody != *isBloody){
// Blood-status changed, end this one
aSkidmarks[i].m_state = 2;
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
return;
}
aSkidmarks[i].m_wasUpdated = true;
if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){
// Last update was recently, just change last coords
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
return;
}
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds();
if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){
// No space to continue, end it
aSkidmarks[i].m_state = 2;
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
*isBloody = false; // stpo blood marks at end
return;
}
aSkidmarks[i].m_last++;
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
dist.Normalise();
CVector2D right(dist.y, -dist.x);
float turn = DotProduct2D(fwd, right);
turn = Abs(turn) + 1.0f;
aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
if(aSkidmarks[i].m_last == 1)
aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
if(aSkidmarks[i].m_last > 8)
*isBloody = false; // stop blood marks after 8
return;
}
// Start a new one
for(i = 0; i < NUMSKIDMARKS; i++)
if(aSkidmarks[i].m_state == 0)
break;
if(i < NUMSKIDMARKS){
// Found a free slot
aSkidmarks[i].m_state = 1;
aSkidmarks[i].m_id = id;
aSkidmarks[i].m_pos[0] = pos;
aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
aSkidmarks[i].m_wasUpdated = true;
aSkidmarks[i].m_last = 0;
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
aSkidmarks[i].m_isBloody = *isBloody;
aSkidmarks[i].m_isMuddy = *isMuddy;
}else
*isBloody = false; // stop blood marks if no space
}

View File

@ -1,12 +1,32 @@
#pragma once #pragma once
enum { SKIDMARK_LENGTH = 16 };
class CSkidmark
{
public:
uint8 m_state;
bool m_wasUpdated;
bool m_isBloody;
bool m_isMuddy;
uintptr m_id;
int16 m_last;
uint32 m_lastUpdate;;
uint32 m_fadeStart;
uint32 m_fadeEnd;
CVector m_pos[SKIDMARK_LENGTH];
CVector m_side[SKIDMARK_LENGTH];
};
class CSkidmarks class CSkidmarks
{ {
static CSkidmark aSkidmarks[NUMSKIDMARKS];
public: public:
static void Init(void);
static void Shutdown(void);
static void Clear(void); static void Clear(void);
static void Update(void); static void Update(void);
static void Render(void); static void Render(void);
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy); static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
static void Init(void);
static void Shutdown(void);
}; };

View File

@ -22,10 +22,10 @@
#include "Shadows.h" #include "Shadows.h"
#include "main.h" #include "main.h"
RxObjSpace3DVertex StreakVertices[4]; RwIm3DVertex StreakVertices[4];
RwImVertexIndex StreakIndexList[12]; RwImVertexIndex StreakIndexList[12];
RxObjSpace3DVertex TraceVertices[6]; RwIm3DVertex TraceVertices[6];
RwImVertexIndex TraceIndexList[12]; RwImVertexIndex TraceIndexList[12];
@ -291,10 +291,10 @@ void CBulletTraces::Render(void)
for (int i = 0; i < NUMBULLETTRACES; i++) { for (int i = 0; i < NUMBULLETTRACES; i++) {
if (!aTraces[i].m_bInUse) if (!aTraces[i].m_bInUse)
continue; continue;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
CVector inf = aTraces[i].m_vecCurrentPos; CVector inf = aTraces[i].m_vecCurrentPos;
CVector sup = aTraces[i].m_vecTargetPos; CVector sup = aTraces[i].m_vecTargetPos;
CVector center = (inf + sup) / 2; CVector center = (inf + sup) / 2;
@ -316,9 +316,9 @@ void CBulletTraces::Render(void)
RwIm3DEnd(); RwIm3DEnd();
} }
} }
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
} }
void CBulletTraces::Update(void) void CBulletTraces::Update(void)
@ -414,8 +414,7 @@ C3dMarker::Render()
{ {
if (m_pAtomic == nil) return; if (m_pAtomic == nil) return;
RwRGBA *color = RpMaterialGetColor(m_pMaterial); RpMaterialSetColor(m_pMaterial, &m_Color);
*color = m_Color;
m_Matrix.UpdateRW(); m_Matrix.UpdateRW();

View File

@ -30,10 +30,12 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
out->x *= SCREEN_WIDTH * recip; out->x *= SCREEN_WIDTH * recip;
out->y *= SCREEN_HEIGHT * recip; out->y *= SCREEN_HEIGHT * recip;
// What is this? size? // What is this? size?
*outw = 70.0f/CDraw::GetFOV(); *outw = 70.0f/CDraw::GetFOV() * SCREEN_WIDTH * recip;
*outh = 70.0f/CDraw::GetFOV(); #ifdef ASPECT_RATIO_SCALE
*outw *= SCREEN_WIDTH * recip; *outh = 70.0f/CDraw::GetFOV() / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) * SCREEN_HEIGHT * recip;
*outh *= SCREEN_HEIGHT * recip; #else
*outh = 70.0f/CDraw::GetFOV() * SCREEN_HEIGHT * recip;
#endif
return true; return true;
} }
@ -432,6 +434,7 @@ void
CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{ {
float screenz, recipz; float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ; screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane; recipz = m_fRecipNearClipPlane;
@ -496,6 +499,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{ {
float screenz, recipz; float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ; screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane; recipz = m_fRecipNearClipPlane;

View File

@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{ {
float screenz, recipz; float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = RwIm2DGetNearScreenZ(); screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip; recipz = RecipNearClip;
@ -312,10 +313,11 @@ void
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col) CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
{ {
int i; int i;
float screenz, recipz; float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ(); screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip; recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){ for(i = 0; i < n; i++){
@ -334,10 +336,11 @@ void
CSprite2d::SetMaskVertices(int n, float *positions) CSprite2d::SetMaskVertices(int n, float *positions)
{ {
int i; int i;
float screenz, recipz; float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ(); screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip; recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){ for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]); RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions)
RwIm2DVertexSetScreenZ(&maVertices[i], screenz); RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
RwIm2DVertexSetCameraZ(&maVertices[i], z); RwIm2DVertexSetCameraZ(&maVertices[i], z);
RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz); RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0); RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
} }
} }
@ -353,10 +356,11 @@ void
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2) float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{ {
float screenz, recipz; float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ(); screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip; recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
RwIm2DVertexSetScreenX(&verts[0], r.left); RwIm2DVertexSetScreenX(&verts[0], r.left);
RwIm2DVertexSetScreenY(&verts[0], r.top); RwIm2DVertexSetScreenY(&verts[0], r.top);

41
src/render/TexList.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "common.h"
#include "TexList.h"
#include "rtbmp.h"
#include "FileMgr.h"
bool CTexList::ms_nTexUsed[MAX_TEXUSED];
void
CTexList::Initialise()
{}
void
CTexList::Shutdown()
{}
RwTexture *
CTexList::SetTexture(int32 slot, char *name)
{
return nil;
}
int32
CTexList::GetFirstFreeTexture()
{
for (int32 i = 0; i < MAX_TEXUSED; i++)
if (!ms_nTexUsed[i])
return i;
return -1;
}
RwTexture *
CTexList::LoadFileNameTexture(char *name)
{
return SetTexture(GetFirstFreeTexture(), name);
}
void
CTexList::LoadGlobalTextureList()
{
CFileMgr::SetDir("TEXTURES");
}

14
src/render/TexList.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
class CTexList
{
enum { MAX_TEXUSED = 400, };
static bool ms_nTexUsed[MAX_TEXUSED];
public:
static void Initialise();
static void Shutdown();
static RwTexture *SetTexture(int32 slot, char *name);
static int32 GetFirstFreeTexture();
static RwTexture *LoadFileNameTexture(char *name);
static void LoadGlobalTextureList();
};

View File

@ -117,7 +117,7 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
RpMaterial* RpMaterial*
SetAlphaCB(RpMaterial *material, void *data) SetAlphaCB(RpMaterial *material, void *data)
{ {
material->color.alpha = (uint8)(uint32)data; ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data;
return material; return material;
} }

View File

@ -83,7 +83,7 @@ CWeaponEffects::Render(void)
{ {
float recipz = 1.0f / pos.z; float recipz = 1.0f / pos.z;
CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z, CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
gCrossHair.m_fSize * w, gCrossHair.m_fSize * SCREEN_SCALE_AR2(h), gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255, gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
recipz, 255); recipz, 255);
} }

View File

@ -71,8 +71,8 @@ const int16 WeatherTypesList[] = {
const float Windiness[] = { const float Windiness[] = {
0.0f, // WEATHER_SUNNY 0.0f, // WEATHER_SUNNY
0.7f, // WEATHER_RAINY 0.7f, // WEATHER_CLOUDY
1.0f, // WEATHER_CLOUDY 1.0f, // WEATHER_RAINY
0.5f // WEATHER_FOGGY 0.5f // WEATHER_FOGGY
}; };
@ -106,7 +106,7 @@ void CWeather::Init(void)
{ {
NewWeatherType = WEATHER_SUNNY; NewWeatherType = WEATHER_SUNNY;
bScriptsForceRain = false; bScriptsForceRain = false;
OldWeatherType = WEATHER_RAINY; OldWeatherType = WEATHER_CLOUDY;
Stored_StateStored = false; Stored_StateStored = false;
InterpolationValue = 0.0f; InterpolationValue = 0.0f;
WhenToPlayLightningSound = 0; WhenToPlayLightningSound = 0;
@ -475,7 +475,7 @@ void CWeather::RenderRainStreaks(void)
// 1/16 probability // 1/16 probability
Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f); Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f); Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
if (!CCutsceneMgr::IsCutsceneProcessing()) { if (!CCutsceneMgr::IsRunning()) {
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f; Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f; Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f;
} }

View File

@ -48,6 +48,13 @@ char SaveFileNameJustSaved[260];
int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C; int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
CDate &CompileDateAndTime = *(CDate*)0x72BCB8; 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 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)); #define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));

View File

@ -32,6 +32,12 @@ extern int &CheckSum;
extern enum eLevelName &m_LevelToLoad; extern enum eLevelName &m_LevelToLoad;
extern int (&Slots)[SLOT_COUNT+1]; 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 extern char SaveFileNameJustSaved[260]; // 8F2570
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";

View File

@ -1927,7 +1927,7 @@ _WinMain(HINSTANCE instance,
* Enter the message processing loop... * 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) ) if( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
{ {
@ -2059,13 +2059,13 @@ _WinMain(HINSTANCE instance,
if (wp.showCmd != SW_SHOWMINIMIZED) if (wp.showCmd != SW_SHOWMINIMIZED)
RsEventHandler(rsFRONTENDIDLE, nil); RsEventHandler(rsFRONTENDIDLE, nil);
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame ) if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
{ {
gGameState = GS_INIT_PLAYING_GAME; gGameState = GS_INIT_PLAYING_GAME;
TRACE("gGameState = GS_INIT_PLAYING_GAME;"); TRACE("gGameState = GS_INIT_PLAYING_GAME;");
} }
if ( FrontEndMenuManager.m_bLoadingSavedGame ) if ( FrontEndMenuManager.m_bWantToLoad )
{ {
InitialiseGame(); InitialiseGame();
FrontEndMenuManager.m_bGameNotLoaded = false; FrontEndMenuManager.m_bGameNotLoaded = false;
@ -2128,7 +2128,7 @@ _WinMain(HINSTANCE instance,
RwInitialised = FALSE; RwInitialised = FALSE;
FrontEndMenuManager.UnloadTextures(); FrontEndMenuManager.UnloadTextures();
if ( !FrontEndMenuManager.m_bStartGameLoading ) if ( !FrontEndMenuManager.m_bWantToRestart )
break; break;
CPad::ResetCheats(); CPad::ResetCheats();
@ -2138,13 +2138,13 @@ _WinMain(HINSTANCE instance,
CTimer::Stop(); CTimer::Stop();
if ( FrontEndMenuManager.m_bLoadingSavedGame ) if ( FrontEndMenuManager.m_bWantToLoad )
{ {
CGame::ShutDownForRestart(); CGame::ShutDownForRestart();
CGame::InitialiseWhenRestarting(); CGame::InitialiseWhenRestarting();
DMAudio.ChangeMusicMode(MUSICMODE_GAME); DMAudio.ChangeMusicMode(MUSICMODE_GAME);
LoadSplash(GetLevelSplashScreen(CGame::currLevel)); LoadSplash(GetLevelSplashScreen(CGame::currLevel));
FrontEndMenuManager.m_bLoadingSavedGame = false; FrontEndMenuManager.m_bWantToLoad = false;
} }
else else
{ {
@ -2168,7 +2168,7 @@ _WinMain(HINSTANCE instance,
} }
FrontEndMenuManager.m_bFirstTime = false; FrontEndMenuManager.m_bFirstTime = false;
FrontEndMenuManager.m_bStartGameLoading = false; FrontEndMenuManager.m_bWantToRestart = false;
} }

View File

@ -182,17 +182,17 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_weaponDoorTimerRight = m_weaponDoorTimerLeft; m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
if(GetModelIndex() == MI_DODO){ if(GetModelIndex() == MI_DODO){
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
CMatrix mat1; CMatrix mat1;
mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF])); mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF])); CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z); mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z);
mat1.UpdateRW(); mat1.UpdateRW();
}else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){ }else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
}else if(GetModelIndex() == MI_RHINO){ }else if(GetModelIndex() == MI_RHINO){
bExplosionProof = true; bExplosionProof = true;
bBulletProof = true; bBulletProof = true;

15
src/vehicles/Bike.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
// some miami bike leftovers
enum eBikeNodes {
BIKE_NODE_NONE,
BIKE_CHASSIS,
BIKE_FORKS_FRONT,
BIKE_FORKS_REAR,
BIKE_WHEEL_FRONT,
BIKE_WHEEL_REAR,
BIKE_MUDGUARD,
BIKE_HANDLEBARS,
BIKE_NUM_NODES
};

View File

@ -94,7 +94,7 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos)
pos = *RwMatrixGetPos(RwFrameGetLTM(m_aBoatNodes[component])); pos = *RwMatrixGetPos(RwFrameGetLTM(m_aBoatNodes[component]));
} }
RxObjSpace3DVertex KeepWaterOutVertices[4]; RwIm3DVertex KeepWaterOutVertices[4];
RwImVertexIndex KeepWaterOutIndices[6]; RwImVertexIndex KeepWaterOutIndices[6];
void void
@ -103,7 +103,7 @@ CBoat::Render()
CMatrix matrix; CMatrix matrix;
if (m_aBoatNodes[1] != nil) { if (m_aBoatNodes[1] != nil) {
matrix.Attach(&m_aBoatNodes[1]->modelling); matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[1]));
CVector pos = matrix.GetPosition(); CVector pos = matrix.GetPosition();
matrix.SetRotateZ(m_fMovingHiRotation); matrix.SetRotateZ(m_fMovingHiRotation);
@ -111,7 +111,7 @@ CBoat::Render()
matrix.UpdateRW(); matrix.UpdateRW();
if (CVehicle::bWheelsOnlyCheat) { if (CVehicle::bWheelsOnlyCheat) {
RpAtomicRenderMacro((RpAtomic*)GetFirstObject(m_aBoatNodes[1])); RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
} }
} }
m_fMovingHiRotation += 0.05f; m_fMovingHiRotation += 0.05f;
@ -130,47 +130,23 @@ CBoat::Render()
KeepWaterOutIndices[5] = 3; KeepWaterOutIndices[5] = 3;
switch (GetModelIndex()) { switch (GetModelIndex()) {
case MI_SPEEDER: case MI_SPEEDER:
KeepWaterOutVertices[0].objVertex.x = -1.15f; RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.15f, 3.61f, 1.03f);
KeepWaterOutVertices[0].objVertex.y = 3.61f; RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.15f, 3.61f, 1.03f);
KeepWaterOutVertices[0].objVertex.z = 1.03f; RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.15f, 0.06f, 1.03f);
KeepWaterOutVertices[1].objVertex.x = 1.15f; RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.15f, 0.06f, 1.03f);
KeepWaterOutVertices[1].objVertex.y = 3.61f;
KeepWaterOutVertices[1].objVertex.z = 1.03f;
KeepWaterOutVertices[2].objVertex.x = -1.15f;
KeepWaterOutVertices[2].objVertex.y = 0.06f;
KeepWaterOutVertices[2].objVertex.z = 1.03f;
KeepWaterOutVertices[3].objVertex.x = 1.15f;
KeepWaterOutVertices[3].objVertex.y = 0.06f;
KeepWaterOutVertices[3].objVertex.z = 1.03f;
break; break;
case MI_REEFER: case MI_REEFER:
KeepWaterOutVertices[2].objVertex.x = -1.9f; RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.9f, 2.83f, 1.0f);
KeepWaterOutVertices[2].objVertex.y = 2.83f; RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.9f, 2.83f, 1.0f);
KeepWaterOutVertices[2].objVertex.z = 1.0f; RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.66f, -4.48f, 0.83f);
KeepWaterOutVertices[3].objVertex.x = 1.9f; RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.66f, -4.48f, 0.83f);
KeepWaterOutVertices[3].objVertex.y = 2.83f;
KeepWaterOutVertices[3].objVertex.z = 1.0f;
KeepWaterOutVertices[0].objVertex.x = -1.66f;
KeepWaterOutVertices[0].objVertex.y = -4.48f;
KeepWaterOutVertices[0].objVertex.z = 0.83f;
KeepWaterOutVertices[1].objVertex.x = 1.66f;
KeepWaterOutVertices[1].objVertex.y = -4.48f;
KeepWaterOutVertices[1].objVertex.z = 0.83f;
break; break;
case MI_PREDATOR: case MI_PREDATOR:
default: default:
KeepWaterOutVertices[0].objVertex.x = -1.45f; RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.45f, 1.9f, 0.96f);
KeepWaterOutVertices[0].objVertex.y = 1.9f; RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.45f, 1.9f, 0.96f);
KeepWaterOutVertices[0].objVertex.z = 0.96f; RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.45f, -3.75f, 0.96f);
KeepWaterOutVertices[1].objVertex.x = 1.45f; RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.45f, -3.75f, 0.96f);
KeepWaterOutVertices[1].objVertex.y = 1.9f;
KeepWaterOutVertices[1].objVertex.z = 0.96f;
KeepWaterOutVertices[2].objVertex.x = -1.45f;
KeepWaterOutVertices[2].objVertex.y = -3.75f;
KeepWaterOutVertices[2].objVertex.z = 0.96f;
KeepWaterOutVertices[3].objVertex.x = 1.45f;
KeepWaterOutVertices[3].objVertex.y = -3.75f;
KeepWaterOutVertices[3].objVertex.z = 0.96f;
break; break;
} }
KeepWaterOutVertices[0].u = 0.0f; KeepWaterOutVertices[0].u = 0.0f;

View File

@ -238,6 +238,7 @@ public:
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; } bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; } bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; }
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; } bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
bool IsBike(void) { return m_vehType == VEHICLE_TYPE_BIKE; }
void FlyingControl(eFlightModel flightModel); void FlyingControl(eFlightModel flightModel);
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,

View File

@ -1,11 +1,29 @@
#include "common.h" #include "common.h"
#include "patcher.h" #include "patcher.h"
#include "Automobile.h"
#include "Bike.h"
#include "Camera.h"
#include "Coronas.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "Entity.h"
#include "EventList.h"
#include "Explosion.h" #include "Explosion.h"
#include "General.h"
#include "Fire.h"
#include "Pad.h"
#include "Particle.h"
#include "PointLights.h"
#include "Shadows.h"
#include "Timer.h"
#include "Vehicle.h"
#include "WaterLevel.h"
#include "World.h"
CExplosion(&gaExplosion)[48] = *(CExplosion(*)[48])*(uintptr*)0x64E208; CExplosion(&gaExplosion)[NUM_EXPLOSIONS] = *(CExplosion(*)[NUM_EXPLOSIONS])*(uintptr*)0x64E208;
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); } // these two were not initialised in original code, I'm really not sure what were they meant to be
RwRGBA colMedExpl = { 0, 0, 0, 0 };
RwRGBA colUpdate = { 0, 0, 0, 0 };
int AudioHandle = AEHANDLE_NONE; int AudioHandle = AEHANDLE_NONE;
@ -15,26 +33,25 @@ CExplosion::Initialise()
debug("Initialising CExplosion...\n"); debug("Initialising CExplosion...\n");
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) { for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE; gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE;
gaExplosion[i].m_vecPosition.x = 0.0f; gaExplosion[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
gaExplosion[i].m_vecPosition.y = 0.0f;
gaExplosion[i].m_vecPosition.z = 0.0f;
gaExplosion[i].m_fRadius = 1.0f; gaExplosion[i].m_fRadius = 1.0f;
gaExplosion[i].m_fPropagationRate = 0.0f; gaExplosion[i].m_fPropagationRate = 0.0f;
gaExplosion[i].field_38 = 0; gaExplosion[i].m_fZshift = 0.0f;
gaExplosion[i].m_pCreatorEntity = nil; gaExplosion[i].m_pCreatorEntity = nil;
gaExplosion[i].m_pVictimEntity = nil; gaExplosion[i].m_pVictimEntity = nil;
gaExplosion[i].m_fStopTime = 0.0f; gaExplosion[i].m_fStopTime = 0.0f;
gaExplosion[i].m_bActive = false; gaExplosion[i].m_nIteration = 0;
gaExplosion[i].m_nStartTime = 0; gaExplosion[i].m_fStartTime = 0.0f;
gaExplosion[i].field_34 = 0; gaExplosion[i].m_bIsBoat = false;
} }
AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1); AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
if (AudioHandle >= 0) if (AudioHandle >= 0)
DMAudio.SetEntityStatus(AudioHandle, 1); DMAudio.SetEntityStatus(AudioHandle, true);
debug("CExplosion ready\n"); debug("CExplosion ready\n");
} }
void CExplosion::Shutdown() void
CExplosion::Shutdown()
{ {
debug("Shutting down CExplosion...\n"); debug("Shutting down CExplosion...\n");
if (AudioHandle >= 0) { if (AudioHandle >= 0) {
@ -44,27 +61,16 @@ void CExplosion::Shutdown()
debug("CExplosion shut down\n"); debug("CExplosion shut down\n");
} }
void
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_bActive) {
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
gaExplosion[i].m_bActive = false;
}
}
}
int8 int8
CExplosion::GetExplosionActiveCounter(uint8 id) CExplosion::GetExplosionActiveCounter(uint8 id)
{ {
return gaExplosion[id].m_bActiveCounter; return gaExplosion[id].m_nActiveCounter;
} }
CVector * void
CExplosion::GetExplosionPosition(uint8 id) CExplosion::ResetExplosionActiveCounter(uint8 id)
{ {
return &gaExplosion[id].m_vecPosition; gaExplosion[id].m_nActiveCounter = 0;
} }
uint8 uint8
@ -73,18 +79,363 @@ CExplosion::GetExplosionType(uint8 id)
return gaExplosion[id].m_ExplosionType; return gaExplosion[id].m_ExplosionType;
} }
void CVector *
CExplosion::ResetExplosionActiveCounter(uint8 id) CExplosion::GetExplosionPosition(uint8 id)
{ {
gaExplosion[id].m_bActiveCounter = 0; return &gaExplosion[id].m_vecPosition;
} }
bool bool
CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float y1, float y2, float z1, float z2) CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
{
CVector pPosn;
CVector posGround;
RwRGBA colorMedium = colMedExpl;
bool bDontExplode = false;
const RwRGBA color = { 160, 160, 160, 255 };
pPosn = pos;
pPosn.z += 5.0f;
#ifdef FIX_BUGS
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 30000, 1.0f);
#else
// last two arguments are swapped resulting in no shadow
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 1, 30000.0f);
#endif
int n = 0;
while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion))
n++;
if (n == ARRAY_SIZE(gaExplosion))
return false;
CExplosion &explosion = gaExplosion[n];
explosion.m_ExplosionType = type;
explosion.m_vecPosition = pos;
explosion.m_fRadius = 1.0f;
explosion.m_fZshift = 0.0f;
explosion.m_pCreatorEntity = culprit;
if (culprit != nil)
culprit->RegisterReference(&explosion.m_pCreatorEntity);
explosion.m_pVictimEntity = explodingEntity;
if (explodingEntity != nil)
explodingEntity->RegisterReference(&explosion.m_pVictimEntity);
explosion.m_nIteration = 1;
explosion.m_nActiveCounter = 1;
explosion.m_bIsBoat = false;
explosion.m_nParticlesExpireTime = lifetime != 0 ? CTimer::GetTimeInMilliseconds() + lifetime : 0;
switch (type)
{
case EXPLOSION_GRENADE:
explosion.m_fRadius = 9.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, nil);
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
break;
case EXPLOSION_MOLOTOV:
{
explosion.m_fRadius = 6.0f;
explosion.m_fPower = 0.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 3000;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
bool found;
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
if (found) {
float waterLevel;
if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
&& posGround.z < waterLevel
&& waterLevel - 6.0f < posGround.z) // some subway/tunnels check?
bDontExplode = true;
else
gFireManager.StartFire(posGround, 1.8f, false);
}
else
bDontExplode = true;
break;
}
case EXPLOSION_ROCKET:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 250);
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
explosion.m_fRadius = 9.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 4250;
explosion.m_fPropagationRate = 0.5f;
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
if (explosion.m_pVictimEntity != nil) {
if (explosion.m_pVictimEntity->IsVehicle() && ((CVehicle*)explosion.m_pVictimEntity)->IsBoat())
explosion.m_bIsBoat = true;
CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, explosion.m_pVictimEntity, nil, 1000);
} else
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
int rn = (CGeneral::GetRandomNumber() & 1) + 2;
for (int i = 0; i < rn; i++) {
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, colMedExpl);
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
}
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
int32 component = CAR_WING_LR;
// miami leftover
if (veh->IsBike())
component = BIKE_FORKS_REAR;
if (veh->IsComponentPresent(component)) {
CVector componentPos;
veh->GetComponentWorldPosition(component, componentPos);
rn = (CGeneral::GetRandomNumber() & 1) + 1;
for (int i = 0; i < rn; i++)
CParticle::AddJetExplosion(componentPos, 1.4f, 0.0f);
}
}
break;
case EXPLOSION_HELI:
explosion.m_fRadius = 6.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
for (int i = 0; i < 10; i++) {
CVector randpos;
uint8 x, y, z;
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddParticle(PARTICLE_EXPLOSION_MFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 2.5f, color);
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 5.0f, color);
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddJetExplosion(randpos, 1.4f, 3.0f);
}
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
break;
case EXPLOSION_MINE:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_BARREL:
explosion.m_fRadius = 7.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
for (int i = 0; i < 6; i++) {
CVector randpos;
uint8 x, y, z;
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = CVector(x - 128, y - 128, z - 128);
randpos.x /= 50.0f;
randpos.y /= 50.0f;
randpos.z /= 25.0f;
randpos += pos;
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colorMedium);
}
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_TANK_GRENADE:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_HELI_BOMB:
explosion.m_fRadius = 8.0f;
explosion.m_fPower = 50.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
}
if (bDontExplode) {
explosion.m_nIteration = 0;
return false;
}
if (explosion.m_fPower != 0.0f && explosion.m_nParticlesExpireTime == 0)
CWorld::TriggerExplosion(pos, explosion.m_fRadius, explosion.m_fPower, culprit, (type == EXPLOSION_ROCKET || type == EXPLOSION_CAR_QUICK || type == EXPLOSION_MINE || type == EXPLOSION_BARREL || type == EXPLOSION_TANK_GRENADE || type == EXPLOSION_HELI_BOMB));
TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
return true;
}
void
CExplosion::Update()
{
RwRGBA color = colUpdate;
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
CExplosion &explosion = gaExplosion[i];
if (explosion.m_nIteration == 0) continue;
if (explosion.m_nParticlesExpireTime != 0) {
if (CTimer::GetTimeInMilliseconds() > explosion.m_nParticlesExpireTime) {
explosion.m_nParticlesExpireTime = 0;
if (explosion.m_fPower != 0.0f)
CWorld::TriggerExplosion(explosion.m_vecPosition, explosion.m_fRadius, explosion.m_fPower, explosion.m_pCreatorEntity, (explosion.m_ExplosionType == EXPLOSION_ROCKET || explosion.m_ExplosionType == EXPLOSION_CAR_QUICK || explosion.m_ExplosionType == EXPLOSION_MINE || explosion.m_ExplosionType == EXPLOSION_BARREL || explosion.m_ExplosionType == EXPLOSION_TANK_GRENADE || explosion.m_ExplosionType == EXPLOSION_HELI_BOMB));
}
} else {
explosion.m_fRadius += explosion.m_fPropagationRate * CTimer::GetTimeStep();
int32 someTime = explosion.m_fStopTime - CTimer::GetTimeInMilliseconds();
switch (explosion.m_ExplosionType)
{
case EXPLOSION_GRENADE:
case EXPLOSION_ROCKET:
case EXPLOSION_HELI:
case EXPLOSION_MINE:
case EXPLOSION_BARREL:
if (CTimer::GetFrameCounter() & 1) {
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 20.0f, 1.0f, 1.0f, 0.5f, CPointLights::FOG_NONE, true);
CCoronas::RegisterCorona((uintptr)&explosion, 255, 255, 200, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else
CCoronas::RegisterCorona((uintptr)&explosion, 128, 128, 100, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 30, 25, 255, explosion.m_vecPosition, explosion.m_fRadius, 120.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
break;
case EXPLOSION_MOLOTOV:
CWorld::SetPedsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
CWorld::SetCarsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
if (explosion.m_nIteration < 10) {
if (explosion.m_nIteration == 1) {
CVector point1 = explosion.m_vecPosition;
point1.z += 5.0f;
CColPoint colPoint;
CEntity *pEntity;
CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil);
explosion.m_fZshift = colPoint.point.z;
}
float ff = ((float)explosion.m_nIteration * 0.55f);
for (int i = 0; i < 5 * ff; i++) {
float angle = CGeneral::GetRandomNumber() / 256.0f * 6.28f;
CVector pos = explosion.m_vecPosition;
pos.x += ff * Sin(angle);
pos.y += ff * Cos(angle);
pos.z += 5.0f; // what is the point of this?
pos.z = explosion.m_fZshift + 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
}
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
if (someTime >= 3500) {
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
if ((CGeneral::GetRandomNumber() & 0xF) == 0) {
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
uint8 component = CAR_WING_LR;
// miami leftover
if (veh->IsBike())
component = BIKE_FORKS_REAR;
if (veh->IsComponentPresent(component)) {
CVector componentPos;
veh->GetComponentWorldPosition(component, componentPos);
CParticle::AddJetExplosion(componentPos, 1.5f, 0.0f);
}
}
if (CTimer::GetTimeInMilliseconds() > explosion.m_fStartTime) {
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds() + 125 + (CGeneral::GetRandomNumber() & 0x7F);
CVector pos = explosion.m_pVictimEntity->GetPosition();
for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++) {
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, color);
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
}
}
}
if (CTimer::GetFrameCounter() & 1) {
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 15.0f, 1.0f, 0.0f, 0.0f, CPointLights::FOG_NONE, true);
CCoronas::RegisterCorona((uintptr)&explosion, 200, 100, 0, 255, explosion.m_vecPosition, 6.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else
CCoronas::RegisterCorona((uintptr)&explosion, 128, 0, 0, 255, explosion.m_vecPosition, 8.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 15, 0, 255, explosion.m_vecPosition, explosion.m_fRadius, 80.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else if (explosion.m_nIteration & 1) {
if (explosion.m_pVictimEntity != nil)
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.8f), color);
CVector pos = explosion.m_vecPosition;
pos.z += 1.0f;
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, pos, CVector(0.0f, 0.0f, 0.11f), nil, CGeneral::GetRandomNumberInRange(0.5f, 2.0f), color);
}
break;
case EXPLOSION_TANK_GRENADE:
case EXPLOSION_HELI_BOMB:
if (explosion.m_nIteration < 5) {
float ff = ((float)explosion.m_nIteration * 0.65f);
for (int i = 0; i < 10 * ff; i++) {
uint8 x = CGeneral::GetRandomNumber(), y = CGeneral::GetRandomNumber(), z = CGeneral::GetRandomNumber();
CVector pos(x - 128, y - 128, (z % 128) + 1);
pos.Normalise();
pos *= ff / 5.0f;
pos += explosion.m_vecPosition;
pos.z += 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
}
break;
}
if (someTime > 0)
explosion.m_nIteration++;
else
explosion.m_nIteration = 0;
}
}
}
bool
CExplosion::TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2)
{ {
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) { for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_bActive) { if (gaExplosion[i].m_nIteration != 0) {
if (a1 == gaExplosion[i].m_ExplosionType) { if (type == gaExplosion[i].m_ExplosionType) {
if (gaExplosion[i].m_vecPosition.x >= x1 && gaExplosion[i].m_vecPosition.x <= x2) { if (gaExplosion[i].m_vecPosition.x >= x1 && gaExplosion[i].m_vecPosition.x <= x2) {
if (gaExplosion[i].m_vecPosition.y >= y1 && gaExplosion[i].m_vecPosition.y <= y2) { if (gaExplosion[i].m_vecPosition.y >= y1 && gaExplosion[i].m_vecPosition.y <= y2) {
if (gaExplosion[i].m_vecPosition.z >= z1 && gaExplosion[i].m_vecPosition.z <= z2) if (gaExplosion[i].m_vecPosition.z >= z1 && gaExplosion[i].m_vecPosition.z <= z2)
@ -97,13 +448,26 @@ CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float
return false; return false;
} }
void
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_nIteration != 0) {
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
gaExplosion[i].m_nIteration = 0;
}
}
}
STARTPATCHES STARTPATCHES
InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP); InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP);
InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP); InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP);
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP); InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP);
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP); InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP);
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
InjectHook(0x5591C0, &CExplosion::AddExplosion, PATCH_JUMP);
InjectHook(0x55A0C0, &CExplosion::Update, PATCH_JUMP);
InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP); InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP);
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -26,25 +26,24 @@ class CExplosion
CEntity *m_pCreatorEntity; CEntity *m_pCreatorEntity;
CEntity *m_pVictimEntity; CEntity *m_pVictimEntity;
float m_fStopTime; float m_fStopTime;
bool m_bActive; uint8 m_nIteration;
int8 m_bActiveCounter; uint8 m_nActiveCounter;
int32 m_nStartTime; float m_fStartTime;
uint32 m_nParticlesExpireTime; uint32 m_nParticlesExpireTime;
float m_fPower; float m_fPower;
int32 field_34; bool m_bIsBoat;
int32 field_38; float m_fZshift;
public: public:
static void Initialise(); static void Initialise();
static void Shutdown(); static void Shutdown();
static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type,
const CVector &pos, uint32);
static int8 GetExplosionActiveCounter(uint8 id); static int8 GetExplosionActiveCounter(uint8 id);
static CVector *GetExplosionPosition(uint8 id);
static uint8 GetExplosionType(uint8 id);
static void ResetExplosionActiveCounter(uint8 id); static void ResetExplosionActiveCounter(uint8 id);
static void RemoveAllExplosionsInArea(CVector, float); static uint8 GetExplosionType(uint8 id);
static bool TestForExplosionInArea(eExplosionType, float, float, float, float, float, float); static CVector *GetExplosionPosition(uint8 id);
static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime);
static void Update();
static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2);
static void RemoveAllExplosionsInArea(CVector pos, float radius);
}; };
extern CExplosion (&gaExplosion)[48]; extern CExplosion (&gaExplosion)[NUM_EXPLOSIONS];