mirror of https://git.rip/DMCA_FUCKER/re3.git
commit
600bf03514
@ -0,0 +1,101 @@
|
||||
# Intro
|
||||
|
||||
The aim of this project is to reverse GTA III for PC by replacing
|
||||
parts of the game [one by one](https://en.wikipedia.org/wiki/Ship_of_Theseus)
|
||||
such that we have a working game at all times.
|
||||
|
||||
# Strategy
|
||||
|
||||
A good approach is to start at the fringes of the code base,
|
||||
i.e. classes that don't depend on code that we don't have reversed yet.
|
||||
If a function uses only few unreversed functions that would be inconvenient
|
||||
to reverse at the time, calling the original functions is acceptable.
|
||||
|
||||
# Progress
|
||||
|
||||
This is a list of some things that have been reversed to some non-trivial extent.
|
||||
Not everything is listed, check the code.
|
||||
|
||||
```
|
||||
CPool
|
||||
CTxdStore
|
||||
CVector
|
||||
CVector2D
|
||||
CMatrix
|
||||
CModelInfo
|
||||
CBaseModelInfo
|
||||
CSimpleModelInfo
|
||||
CTimeModelInfo
|
||||
CClumpModelInfo
|
||||
CPedModelInfo
|
||||
CVehicleModelInfo
|
||||
CVisibilityPlugins
|
||||
CRenderer
|
||||
CEntity
|
||||
CPhysical
|
||||
CCollision
|
||||
CCullZones
|
||||
CTheZones
|
||||
CPathFind
|
||||
```
|
||||
|
||||
# Low hanging fruit
|
||||
|
||||
There are a couple of things that have been reversed for other projects
|
||||
already that could probably be put into this project without too much effort.
|
||||
Again, the list is not complete:
|
||||
|
||||
* Animation (https://github.com/aap/iii_anim)
|
||||
* File Loader (https://github.com/aap/librwgta/tree/master/tools/IIItest)
|
||||
* ...
|
||||
|
||||
# Coding style
|
||||
|
||||
I started writing in [Plan 9 style](http://man.cat-v.org/plan_9/6/style),
|
||||
but realize that this is not the most popular style, so I'm willing to compromise.
|
||||
Try not to deviate too much so the code will look similar across the whole project.
|
||||
|
||||
To give examples, these two styles (or anything in between) are fine:
|
||||
|
||||
```
|
||||
type
|
||||
functionname(args)
|
||||
{
|
||||
if(a == b){
|
||||
s1;
|
||||
s2;
|
||||
}
|
||||
if(x != y)
|
||||
s3;
|
||||
}
|
||||
|
||||
type functionname(args)
|
||||
{
|
||||
if (a == b) {
|
||||
s1;
|
||||
s2;
|
||||
}
|
||||
if (x != y)
|
||||
s3;
|
||||
}
|
||||
```
|
||||
|
||||
This one (or anything more extreme) is heavily discouraged:
|
||||
|
||||
```
|
||||
type functionname ( args )
|
||||
{
|
||||
if ( a == b )
|
||||
{
|
||||
s1;
|
||||
s2;
|
||||
}
|
||||
if ( x != y )
|
||||
{
|
||||
s3;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Indentation is done with TABS.
|
||||
|
@ -0,0 +1 @@
|
||||
premake5 vs2015
|
Binary file not shown.
@ -0,0 +1,38 @@
|
||||
workspace "re3"
|
||||
configurations { "Release","Debug" }
|
||||
location "build"
|
||||
|
||||
files { "src/*.*" }
|
||||
files { "src/math/*.*" }
|
||||
files { "src/modelinfo/*.*" }
|
||||
files { "src/entities/*.*" }
|
||||
files { "src/render/*.*" }
|
||||
|
||||
includedirs { "src", "src/modelinfo" }
|
||||
includedirs { "src", "src/entities" }
|
||||
includedirs { "src", "src/render" }
|
||||
includedirs { os.getenv("RWSDK33") }
|
||||
|
||||
project "re3"
|
||||
kind "SharedLib"
|
||||
language "C++"
|
||||
targetname "re3"
|
||||
targetdir "bin/%{cfg.buildcfg}"
|
||||
targetextension ".dll"
|
||||
characterset ("MBCS")
|
||||
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
flags { "StaticRuntime" }
|
||||
symbols "On"
|
||||
debugdir "C:/Users/aap/games/gta3_re"
|
||||
debugcommand "C:/Users/aap/games/gta3_re/gta3.exe"
|
||||
postbuildcommands "copy /y \"$(TargetPath)\" \"C:\\Users\\aap\\games\\gta3_re\\plugins\\re3.dll\""
|
||||
|
||||
filter "configurations:Release"
|
||||
defines { "NDEBUG" }
|
||||
optimize "On"
|
||||
flags { "StaticRuntime" }
|
||||
debugdir "C:/Users/aap/games/gta3_re"
|
||||
debugcommand "C:/Users/aap/games/gta3_re/gta3.exe"
|
||||
postbuildcommands "copy /y \"$(TargetPath)\" \"C:\\Users\\aap\\games\\gta3_re\\plugins\\re3.dll\""
|
@ -0,0 +1,63 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Draw.h"
|
||||
#include "Camera.h"
|
||||
|
||||
CCamera &TheCamera = *(CCamera*)0x6FACF8;
|
||||
|
||||
bool
|
||||
CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat)
|
||||
{
|
||||
RwV3d c;
|
||||
c = *(RwV3d*)¢er;
|
||||
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
|
||||
if(c.y + radius < CDraw::GetNearClipZ()) return false;
|
||||
if(c.y - radius > CDraw::GetFarClipZ()) return false;
|
||||
if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > radius) return false;
|
||||
if(c.x*m_vecFrustumNormals[1].x + c.y*m_vecFrustumNormals[1].y > radius) return false;
|
||||
if(c.y*m_vecFrustumNormals[2].y + c.z*m_vecFrustumNormals[2].z > radius) return false;
|
||||
if(c.y*m_vecFrustumNormals[3].y + c.z*m_vecFrustumNormals[3].z > radius) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat)
|
||||
{
|
||||
RwV3d c;
|
||||
c = *(RwV3d*)¢er;
|
||||
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
|
||||
if(c.y < CDraw::GetNearClipZ()) return false;
|
||||
if(c.y > CDraw::GetFarClipZ()) return false;
|
||||
if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > 0.0f) return false;
|
||||
if(c.x*m_vecFrustumNormals[1].x + c.y*m_vecFrustumNormals[1].y > 0.0f) return false;
|
||||
if(c.y*m_vecFrustumNormals[2].y + c.z*m_vecFrustumNormals[2].z > 0.0f) return false;
|
||||
if(c.y*m_vecFrustumNormals[3].y + c.z*m_vecFrustumNormals[3].z > 0.0f) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CCamera::IsBoxVisible(RwV3d *box, const CMatrix *mat)
|
||||
{
|
||||
int i;
|
||||
int frustumTests[6] = { 0 };
|
||||
RwV3dTransformPoints(box, box, 8, &mat->m_matrix);
|
||||
|
||||
for(i = 0; i < 8; i++){
|
||||
if(box[i].y < CDraw::GetNearClipZ()) frustumTests[0]++;
|
||||
if(box[i].y > CDraw::GetFarClipZ()) frustumTests[1]++;
|
||||
if(box[i].x*m_vecFrustumNormals[0].x + box[i].y*m_vecFrustumNormals[0].y > 0.0f) frustumTests[2]++;
|
||||
if(box[i].x*m_vecFrustumNormals[1].x + box[i].y*m_vecFrustumNormals[1].y > 0.0f) frustumTests[3]++;
|
||||
// Why not test z?
|
||||
// if(box[i].y*m_vecFrustumNormals[2].y + box[i].z*m_vecFrustumNormals[2].z > 0.0f) frustumTests[4]++;
|
||||
// if(box[i].y*m_vecFrustumNormals[3].y + box[i].z*m_vecFrustumNormals[3].z > 0.0f) frustumTests[5]++;
|
||||
}
|
||||
for(i = 0; i < 6; i++)
|
||||
if(frustumTests[i] == 8)
|
||||
return false; // Box is completely outside of one plane
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x42C760, &CCamera::IsSphereVisible, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -0,0 +1,420 @@
|
||||
#pragma once
|
||||
|
||||
#include "Placeable.h"
|
||||
|
||||
class CEntity;
|
||||
class CPed;
|
||||
class CAutomobile;
|
||||
|
||||
#define NUMBER_OF_VECTORS_FOR_AVERAGE 2
|
||||
|
||||
struct CCam
|
||||
{
|
||||
enum CamMode
|
||||
{
|
||||
MODE_TOPDOWN1 = 1,
|
||||
MODE_TOPDOWN2,
|
||||
MODE_BEHINDCAR,
|
||||
MODE_FOLLOWPED,
|
||||
MODE_AIMING,
|
||||
MODE_DEBUG,
|
||||
MODE_SNIPER,
|
||||
MODE_ROCKET,
|
||||
MODE_MODELVIEW,
|
||||
MODE_BILL,
|
||||
MODE_SYPHON,
|
||||
MODE_CIRCLE,
|
||||
MODE_CHEESYZOOM,
|
||||
MODE_WHEELCAM,
|
||||
MODE_FIXED,
|
||||
MODE_FIRSTPERSON,
|
||||
MODE_FLYBY,
|
||||
MODE_CAMONASTRING,
|
||||
MODE_REACTIONCAM,
|
||||
MODE_FOLLOWPEDWITHBINDING,
|
||||
MODE_CHRISWITHBINDINGPLUSROTATION,
|
||||
MODE_BEHINDBOAT,
|
||||
MODE_PLAYERFALLENWATER,
|
||||
MODE_CAMONTRAINROOF,
|
||||
MODE_CAMRUNNINGSIDETRAIN,
|
||||
MODE_BLOODONTHETRACKS,
|
||||
MODE_IMTHEPASSENGERWOOWOO,
|
||||
MODE_SYPHONCRIMINFRONT,
|
||||
MODE_PEDSDEADBABY,
|
||||
MODE_CUSHYPILLOWSARSE,
|
||||
MODE_LOOKATCARS,
|
||||
MODE_ARRESTCAMONE,
|
||||
MODE_ARRESTCAMTWO,
|
||||
MODE_M16FIRSTPERSON_34,
|
||||
MODE_SPECIALFIXEDFORSYPHON,
|
||||
MODE_FIGHT,
|
||||
MODE_TOPDOWNPED,
|
||||
MODE_FIRSTPERSONPEDONPC_38,
|
||||
MODE_FIRSTPERSONPEDONPC_39,
|
||||
MODE_FIRSTPERSONPEDONPC_40,
|
||||
MODE_FIRSTPERSONPEDONPC_41,
|
||||
MODE_FIRSTPERSONPEDONPC_42,
|
||||
MODE_EDITOR,
|
||||
MODE_M16FIRSTPERSON_44
|
||||
};
|
||||
|
||||
bool bBelowMinDist; //used for follow ped mode
|
||||
bool bBehindPlayerDesired; //used for follow ped mode
|
||||
bool m_bCamLookingAtVector;
|
||||
bool m_bCollisionChecksOn;
|
||||
bool m_bFixingBeta; //used for camera on a string
|
||||
bool m_bTheHeightFixerVehicleIsATrain;
|
||||
bool LookBehindCamWasInFront;
|
||||
bool LookingBehind;
|
||||
bool LookingLeft; // 32
|
||||
bool LookingRight;
|
||||
bool ResetStatics; //for interpolation type stuff to work
|
||||
bool Rotating;
|
||||
|
||||
int16 Mode; // CameraMode
|
||||
uint32 m_uiFinishTime; // 52
|
||||
|
||||
int m_iDoCollisionChecksOnFrameNum;
|
||||
int m_iDoCollisionCheckEveryNumOfFrames;
|
||||
int m_iFrameNumWereAt; // 64
|
||||
int m_iRunningVectorArrayPos;
|
||||
int m_iRunningVectorCounter;
|
||||
int DirectionWasLooking;
|
||||
|
||||
float f_max_role_angle; //=DEGTORAD(5.0f);
|
||||
float f_Roll; //used for adding a slight roll to the camera in the
|
||||
float f_rollSpeed;
|
||||
float m_fSyphonModeTargetZOffSet;
|
||||
float m_unknownZOffset;
|
||||
float m_fAmountFractionObscured;
|
||||
float m_fAlphaSpeedOverOneFrame; // 100
|
||||
float m_fBetaSpeedOverOneFrame;
|
||||
float m_fBufferedTargetBeta;
|
||||
float m_fBufferedTargetOrientation;
|
||||
float m_fBufferedTargetOrientationSpeed;
|
||||
float m_fCamBufferedHeight;
|
||||
float m_fCamBufferedHeightSpeed;
|
||||
float m_fCloseInPedHeightOffset;
|
||||
float m_fCloseInPedHeightOffsetSpeed; // 132
|
||||
float m_fCloseInCarHeightOffset;
|
||||
float m_fCloseInCarHeightOffsetSpeed;
|
||||
float m_fDimensionOfHighestNearCar;
|
||||
float m_fDistanceBeforeChanges;
|
||||
float m_fFovSpeedOverOneFrame;
|
||||
float m_fMinDistAwayFromCamWhenInterPolating;
|
||||
float m_fPedBetweenCameraHeightOffset;
|
||||
float m_fPlayerInFrontSyphonAngleOffSet; // 164
|
||||
float m_fRadiusForDead;
|
||||
float m_fRealGroundDist; //used for follow ped mode
|
||||
float m_fTargetBeta;
|
||||
float m_fTimeElapsedFloat;
|
||||
|
||||
float m_fTransitionBeta;
|
||||
float m_fTrueBeta;
|
||||
float m_fTrueAlpha; // 200
|
||||
float m_fInitialPlayerOrientation; //used for first person
|
||||
|
||||
float Alpha;
|
||||
float AlphaSpeed;
|
||||
float FOV;
|
||||
float FOVSpeed;
|
||||
float Beta;
|
||||
float BetaSpeed;
|
||||
float Distance; // 232
|
||||
float DistanceSpeed;
|
||||
float CA_MIN_DISTANCE;
|
||||
float CA_MAX_DISTANCE;
|
||||
float SpeedVar;
|
||||
|
||||
// ped onfoot zoom distance
|
||||
float m_fTargetZoomGroundOne;
|
||||
float m_fTargetZoomGroundTwo; // 256
|
||||
float m_fTargetZoomGroundThree;
|
||||
// ped onfoot alpha angle offset
|
||||
float m_fTargetZoomOneZExtra;
|
||||
float m_fTargetZoomTwoZExtra;
|
||||
float m_fTargetZoomThreeZExtra;
|
||||
|
||||
float m_fTargetZoomZCloseIn;
|
||||
float m_fMinRealGroundDist;
|
||||
float m_fTargetCloseInDist;
|
||||
|
||||
CVector m_cvecTargetCoorsForFudgeInter; // 360
|
||||
CVector m_cvecCamFixedModeVector; // 372
|
||||
CVector m_cvecCamFixedModeSource; // 384
|
||||
CVector m_cvecCamFixedModeUpOffSet; // 396
|
||||
CVector m_vecLastAboveWaterCamPosition; //408 //helper for when the player has gone under the water
|
||||
CVector m_vecBufferedPlayerBodyOffset; // 420
|
||||
|
||||
// The three vectors that determine this camera for this frame
|
||||
CVector Front; // 432 // Direction of looking in
|
||||
CVector Source; // Coors in world space
|
||||
CVector SourceBeforeLookBehind;
|
||||
CVector Up; // Just that
|
||||
CVector m_arrPreviousVectors[NUMBER_OF_VECTORS_FOR_AVERAGE]; // used to average stuff
|
||||
CEntity *CamTargetEntity;
|
||||
|
||||
float m_fCameraDistance;
|
||||
float m_fIdealAlpha;
|
||||
float m_fPlayerVelocity;
|
||||
CAutomobile *m_pLastCarEntered; // So interpolation works
|
||||
CPed *m_pLastPedLookedAt;// So interpolation works
|
||||
bool m_bFirstPersonRunAboutActive;
|
||||
|
||||
|
||||
void Process_Debug(float *vec, float a, float b, float c);
|
||||
void Process_Kalvin(float*, float, float, float);
|
||||
void GetVectorsReadyForRW(void);
|
||||
};
|
||||
static_assert(sizeof(CCam) == 0x1A4, "CCam: wrong size");
|
||||
static_assert(offsetof(CCam, Alpha) == 0xA8, "CCam: error");
|
||||
static_assert(offsetof(CCam, Front) == 0x140, "CCam: error");
|
||||
|
||||
struct CCamPathSplines
|
||||
{
|
||||
float m_arr_PathData[800];
|
||||
};
|
||||
|
||||
struct CTrainCamNode
|
||||
{
|
||||
CVector m_cvecCamPosition;
|
||||
CVector m_cvecPointToLookAt;
|
||||
CVector m_cvecMinPointInRange;
|
||||
CVector m_cvecMaxPointInRange;
|
||||
float m_fDesiredFOV;
|
||||
float m_fNearClip;
|
||||
};
|
||||
|
||||
struct CQueuedMode
|
||||
{
|
||||
int16 Mode;
|
||||
float Duration;
|
||||
int16 MinZoom;
|
||||
int16 MaxZoom;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOOKING_BEHIND,
|
||||
LOOKING_LEFT,
|
||||
LOOKING_RIGHT,
|
||||
LOOKING_FORWARD,
|
||||
};
|
||||
|
||||
struct CCamera : public CPlaceable
|
||||
{
|
||||
bool m_bAboveGroundTrainNodesLoaded;
|
||||
bool m_bBelowGroundTrainNodesLoaded;
|
||||
bool m_bCamDirectlyBehind;
|
||||
bool m_bCamDirectlyInFront;
|
||||
bool m_bCameraJustRestored;
|
||||
bool m_bcutsceneFinished;
|
||||
bool m_bCullZoneChecksOn;
|
||||
bool m_bFirstPersonBeingUsed;
|
||||
bool m_bJustJumpedOutOf1stPersonBecauseOfTarget;
|
||||
bool m_bIdleOn;
|
||||
bool m_bInATunnelAndABigVehicle;
|
||||
bool m_bInitialNodeFound;
|
||||
bool m_bInitialNoNodeStaticsSet;
|
||||
bool m_bIgnoreFadingStuffForMusic;
|
||||
bool m_bPlayerIsInGarage;
|
||||
bool m_bJustCameOutOfGarage;
|
||||
bool m_bJustInitalised;
|
||||
bool m_bJust_Switched;
|
||||
bool m_bLookingAtPlayer;
|
||||
bool m_bLookingAtVector;
|
||||
bool m_bMoveCamToAvoidGeom;
|
||||
bool m_bObbeCinematicPedCamOn;
|
||||
bool m_bObbeCinematicCarCamOn;
|
||||
bool m_bRestoreByJumpCut;
|
||||
bool m_bUseNearClipScript;
|
||||
bool m_bStartInterScript;
|
||||
bool m_bStartingSpline;
|
||||
bool m_bTargetJustBeenOnTrain;
|
||||
bool m_bTargetJustCameOffTrain;
|
||||
bool m_bUseSpecialFovTrain;
|
||||
bool m_bUseTransitionBeta;
|
||||
bool m_bUseScriptZoomValuePed;
|
||||
bool m_bUseScriptZoomValueCar;
|
||||
bool m_bWaitForInterpolToFinish;
|
||||
bool m_bItsOkToLookJustAtThePlayer;
|
||||
bool m_bWantsToSwitchWidescreenOff;
|
||||
bool m_WideScreenOn;
|
||||
bool m_1rstPersonRunCloseToAWall;
|
||||
bool m_bHeadBob;
|
||||
bool m_bFailedCullZoneTestPreviously;
|
||||
|
||||
bool m_FadeTargetIsSplashScreen;
|
||||
|
||||
bool WorldViewerBeingUsed;
|
||||
uint8 ActiveCam;
|
||||
uint32 m_uiCamShakeStart;
|
||||
uint32 m_uiFirstPersonCamLastInputTime;
|
||||
// where are those?
|
||||
//bool m_bVehicleSuspenHigh;
|
||||
//bool m_bEnable1rstPersonCamCntrlsScript;
|
||||
//bool m_bAllow1rstPersonWeaponsCamera;
|
||||
|
||||
uint32 m_uiLongestTimeInMill;
|
||||
uint32 m_uiNumberOfTrainCamNodes;
|
||||
uint8 m_uiTransitionJUSTStarted;
|
||||
uint8 m_uiTransitionState; // 0:one mode 1:transition
|
||||
|
||||
uint32 m_uiTimeLastChange;
|
||||
uint32 m_uiTimeWeEnteredIdle;
|
||||
uint32 m_uiTimeTransitionStart;
|
||||
uint32 m_uiTransitionDuration;
|
||||
int m_BlurBlue;
|
||||
int m_BlurGreen;
|
||||
int m_BlurRed;
|
||||
int m_BlurType;
|
||||
|
||||
uint32 unknown;
|
||||
int m_iWorkOutSpeedThisNumFrames;
|
||||
int m_iNumFramesSoFar;
|
||||
|
||||
|
||||
int m_iCurrentTrainCamNode;
|
||||
int m_motionBlur;
|
||||
int m_imotionBlurAddAlpha;
|
||||
int m_iCheckCullZoneThisNumFrames;
|
||||
int m_iZoneCullFrameNumWereAt;
|
||||
int WhoIsInControlOfTheCamera;
|
||||
|
||||
float CamFrontXNorm;
|
||||
float CamFrontYNorm;
|
||||
float CarZoomIndicator;
|
||||
float CarZoomValue;
|
||||
float CarZoomValueSmooth;
|
||||
|
||||
float DistanceToWater;
|
||||
float FOVDuringInter;
|
||||
float LODDistMultiplier;
|
||||
float GenerationDistMultiplier;
|
||||
float m_fAlphaSpeedAtStartInter;
|
||||
float m_fAlphaWhenInterPol;
|
||||
float m_fAlphaDuringInterPol;
|
||||
float m_fBetaDuringInterPol;
|
||||
float m_fBetaSpeedAtStartInter;
|
||||
float m_fBetaWhenInterPol;
|
||||
float m_fFOVWhenInterPol;
|
||||
float m_fFOVSpeedAtStartInter;
|
||||
float m_fStartingBetaForInterPol;
|
||||
float m_fStartingAlphaForInterPol;
|
||||
float m_PedOrientForBehindOrInFront;
|
||||
float m_CameraAverageSpeed;
|
||||
float m_CameraSpeedSoFar;
|
||||
float m_fCamShakeForce;
|
||||
float m_fCarZoomValueScript;
|
||||
float m_fFovForTrain;
|
||||
float m_fFOV_Wide_Screen;
|
||||
float m_fNearClipScript;
|
||||
float m_fOldBetaDiff;
|
||||
float m_fPedZoomValue;
|
||||
|
||||
float m_fPedZoomValueScript;
|
||||
float m_fPedZoomValueSmooth;
|
||||
float m_fPositionAlongSpline;
|
||||
float m_ScreenReductionPercentage;
|
||||
float m_ScreenReductionSpeed;
|
||||
float m_AlphaForPlayerAnim1rstPerson;
|
||||
float Orientation;
|
||||
float PedZoomIndicator;
|
||||
float PlayerExhaustion;
|
||||
float SoundDistUp, SoundDistLeft, SoundDistRight;
|
||||
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
|
||||
float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld;
|
||||
float m_fWideScreenReductionAmount;
|
||||
float m_fStartingFOVForInterPol;
|
||||
|
||||
// not static yet
|
||||
float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls
|
||||
float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls
|
||||
float m_f3rdPersonCHairMultX;
|
||||
float m_f3rdPersonCHairMultY;
|
||||
|
||||
|
||||
CCam Cams[3];
|
||||
void *pToGarageWeAreIn;
|
||||
void *pToGarageWeAreInForHackAvoidFirstPerson;
|
||||
CQueuedMode m_PlayerMode;
|
||||
CQueuedMode PlayerWeaponMode;
|
||||
CVector m_PreviousCameraPosition;
|
||||
CVector m_RealPreviousCameraPosition;
|
||||
CVector m_cvecAimingTargetCoors;
|
||||
CVector m_vecFixedModeVector;
|
||||
|
||||
// one of those has to go
|
||||
CVector m_vecFixedModeSource;
|
||||
CVector m_vecFixedModeUpOffSet;
|
||||
// CVector m_vecCutSceneOffset;
|
||||
CVector m_cvecStartingSourceForInterPol;
|
||||
CVector m_cvecStartingTargetForInterPol;
|
||||
CVector m_cvecStartingUpForInterPol;
|
||||
CVector m_cvecSourceSpeedAtStartInter;
|
||||
CVector m_cvecTargetSpeedAtStartInter;
|
||||
CVector m_cvecUpSpeedAtStartInter;
|
||||
CVector m_vecSourceWhenInterPol;
|
||||
CVector m_vecTargetWhenInterPol;
|
||||
CVector m_vecUpWhenInterPol;
|
||||
CVector m_vecClearGeometryVec;
|
||||
|
||||
CVector m_vecGameCamPos;
|
||||
CVector SourceDuringInter;
|
||||
CVector TargetDuringInter;
|
||||
CVector UpDuringInter;
|
||||
RwCamera *m_pRwCamera;
|
||||
CEntity *pTargetEntity;
|
||||
CCamPathSplines m_arrPathArray[4];
|
||||
CTrainCamNode m_arrTrainCamNode[800];
|
||||
CMatrix m_cameraMatrix;
|
||||
bool m_bGarageFixedCamPositionSet;
|
||||
bool m_vecDoingSpecialInterPolation;
|
||||
bool m_bScriptParametersSetForInterPol;
|
||||
bool m_bFading;
|
||||
bool m_bMusicFading;
|
||||
CMatrix m_viewMatrix;
|
||||
CVector m_vecFrustumNormals[4];
|
||||
CVector m_vecOldSourceForInter;
|
||||
CVector m_vecOldFrontForInter;
|
||||
CVector m_vecOldUpForInter;
|
||||
|
||||
float m_vecOldFOVForInter;
|
||||
float m_fFLOATingFade;
|
||||
float m_fFLOATingFadeMusic;
|
||||
float m_fTimeToFadeOut;
|
||||
float m_fTimeToFadeMusic;
|
||||
float m_fFractionInterToStopMovingTarget;
|
||||
float m_fFractionInterToStopCatchUpTarget;
|
||||
float m_fGaitSwayBuffer;
|
||||
float m_fScriptPercentageInterToStopMoving;
|
||||
float m_fScriptPercentageInterToCatchUp;
|
||||
|
||||
uint32 m_fScriptTimeForInterPolation;
|
||||
|
||||
|
||||
int16 m_iFadingDirection;
|
||||
int m_iModeObbeCamIsInForCar;
|
||||
int16 m_iModeToGoTo;
|
||||
int16 m_iMusicFadingDirection;
|
||||
int16 m_iTypeOfSwitch;
|
||||
|
||||
uint32 m_uiFadeTimeStarted;
|
||||
uint32 m_uiFadeTimeStartedMusic;
|
||||
|
||||
|
||||
CMatrix &GetCameraMatrix(void) { return m_cameraMatrix; }
|
||||
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
|
||||
bool IsPointVisible(const CVector ¢er, const CMatrix *mat);
|
||||
bool IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat);
|
||||
bool IsBoxVisible(RwV3d *box, const CMatrix *mat);
|
||||
};
|
||||
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, WorldViewerBeingUsed) == 0x75, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, m_uiNumberOfTrainCamNodes) == 0x84, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, m_uiTransitionState) == 0x89, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, m_uiTimeTransitionStart) == 0x94, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error");
|
||||
static_assert(offsetof(CCamera, Cams) == 0x1A4, "CCamera: error");
|
||||
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
|
||||
extern CCamera &TheCamera;
|
@ -0,0 +1,116 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Timer.h"
|
||||
#include "Pad.h"
|
||||
#include "Clock.h"
|
||||
|
||||
uint8 &CClock::ms_nGameClockHours = *(uint8*)0x95CDA6;
|
||||
uint8 &CClock::ms_nGameClockMinutes = *(uint8*)0x95CDC8;
|
||||
uint16 &CClock::ms_nGameClockSeconds = *(uint16*)0x95CC7C;
|
||||
uint8 &CClock::ms_Stored_nGameClockHours = *(uint8*)0x95CD7B;
|
||||
uint8 &CClock::ms_Stored_nGameClockMinutes = *(uint8*)0x95CD9B;
|
||||
uint16 &CClock::ms_Stored_nGameClockSeconds = *(uint16*)0x95CC9C;
|
||||
uint32 &CClock::ms_nMillisecondsPerGameMinute = *(uint32*)0x8F2C64;
|
||||
int32 &CClock::ms_nLastClockTick = *(int32*)0x9430E4;
|
||||
bool &CClock::ms_bClockHasBeenStored = *(bool*)0x95CD82;
|
||||
|
||||
void
|
||||
CClock::Initialise(uint32 scale)
|
||||
{
|
||||
debug("Initialising CClock...\n");
|
||||
ms_nGameClockHours = 12;
|
||||
ms_nGameClockMinutes = 0;
|
||||
ms_nGameClockSeconds = 0;
|
||||
ms_nMillisecondsPerGameMinute = scale;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
ms_bClockHasBeenStored = false;
|
||||
debug("CClock ready\n");
|
||||
}
|
||||
|
||||
void
|
||||
CClock::Update(void)
|
||||
{
|
||||
if(CPad::GetPad(1)->NewState.r1){
|
||||
ms_nGameClockMinutes += 8;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
if(ms_nGameClockMinutes >= 60){
|
||||
ms_nGameClockHours++;
|
||||
ms_nGameClockMinutes = 0;
|
||||
if(ms_nGameClockHours >= 24)
|
||||
ms_nGameClockHours = 0;
|
||||
}
|
||||
}else
|
||||
if(CTimer::GetTimeInMilliseconds() - ms_nLastClockTick >
|
||||
ms_nMillisecondsPerGameMinute){
|
||||
ms_nGameClockMinutes++;
|
||||
ms_nLastClockTick += ms_nMillisecondsPerGameMinute;
|
||||
if(ms_nGameClockMinutes >= 60){
|
||||
ms_nGameClockHours++;
|
||||
ms_nGameClockMinutes = 0;
|
||||
if(ms_nGameClockHours >= 24)
|
||||
ms_nGameClockHours = 0;
|
||||
// TODO: stats days passed
|
||||
}
|
||||
}
|
||||
ms_nGameClockSeconds +=
|
||||
60
|
||||
* (CTimer::GetTimeInMilliseconds() - ms_nLastClockTick)
|
||||
/ ms_nMillisecondsPerGameMinute;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::SetGameClock(uint8 h, uint8 m)
|
||||
{
|
||||
ms_nGameClockHours = h;
|
||||
ms_nGameClockMinutes = m;
|
||||
ms_nGameClockSeconds = 0;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
|
||||
int32
|
||||
CClock::GetGameClockMinutesUntil(uint8 h, uint8 m)
|
||||
{
|
||||
int32 now, then;
|
||||
now = ms_nGameClockHours*60 + ms_nGameClockMinutes;
|
||||
then = h*60 + m;
|
||||
if(then < now)
|
||||
then += 24*60;
|
||||
return then-now;
|
||||
}
|
||||
|
||||
bool
|
||||
CClock::GetIsTimeInRange(uint8 h1, uint8 h2)
|
||||
{
|
||||
if(h1 > h2)
|
||||
return ms_nGameClockHours >= h1 || ms_nGameClockHours < h2;
|
||||
else
|
||||
return ms_nGameClockHours >= h1 && ms_nGameClockHours < h2;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::StoreClock(void)
|
||||
{
|
||||
ms_Stored_nGameClockHours = ms_nGameClockHours;
|
||||
ms_Stored_nGameClockMinutes = ms_nGameClockMinutes;
|
||||
ms_Stored_nGameClockSeconds = ms_nGameClockSeconds;
|
||||
ms_bClockHasBeenStored = true;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::RestoreClock(void)
|
||||
{
|
||||
ms_nGameClockHours = ms_Stored_nGameClockHours;
|
||||
ms_nGameClockMinutes = ms_Stored_nGameClockMinutes;
|
||||
ms_nGameClockSeconds = ms_Stored_nGameClockSeconds;
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x473370, CClock::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x473460, CClock::Update, PATCH_JUMP);
|
||||
InjectHook(0x4733C0, CClock::SetGameClock, PATCH_JUMP);
|
||||
InjectHook(0x4733F0, CClock::GetGameClockMinutesUntil, PATCH_JUMP);
|
||||
InjectHook(0x473420, CClock::GetIsTimeInRange, PATCH_JUMP);
|
||||
InjectHook(0x473540, CClock::StoreClock, PATCH_JUMP);
|
||||
InjectHook(0x473570, CClock::RestoreClock, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
class CClock
|
||||
{
|
||||
static uint8 &ms_nGameClockHours;
|
||||
static uint8 &ms_nGameClockMinutes;
|
||||
static uint16 &ms_nGameClockSeconds;
|
||||
static uint8 &ms_Stored_nGameClockHours;
|
||||
static uint8 &ms_Stored_nGameClockMinutes;
|
||||
static uint16 &ms_Stored_nGameClockSeconds;
|
||||
static uint32 &ms_nMillisecondsPerGameMinute;
|
||||
static int32 &ms_nLastClockTick;
|
||||
static bool &ms_bClockHasBeenStored;
|
||||
public:
|
||||
|
||||
static void Initialise(uint32 scale);
|
||||
static void Update(void);
|
||||
static void SetGameClock(uint8 h, uint8 m);
|
||||
static int32 GetGameClockMinutesUntil(uint8 h, uint8 m);
|
||||
static bool GetIsTimeInRange(uint8 h1, uint8 h2);
|
||||
static void StoreClock(void);
|
||||
static void RestoreClock(void);
|
||||
|
||||
static int8 GetHours(void) { return ms_nGameClockHours; }
|
||||
static int8 GetMinutes(void) { return ms_nGameClockMinutes; }
|
||||
static int16 GetSeconds(void) { return ms_nGameClockSeconds; }
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#include "templates.h"
|
||||
#include "Game.h" // for eLevelName
|
||||
|
||||
struct CColSphere
|
||||
{
|
||||
CVector center;
|
||||
float radius;
|
||||
uint8 surface;
|
||||
uint8 piece;
|
||||
|
||||
void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece);
|
||||
void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; }
|
||||
};
|
||||
|
||||
struct CColBox
|
||||
{
|
||||
CVector min;
|
||||
CVector max;
|
||||
uint8 surface;
|
||||
uint8 piece;
|
||||
|
||||
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
|
||||
};
|
||||
|
||||
struct CColLine
|
||||
{
|
||||
CVector p0;
|
||||
int pad0;
|
||||
CVector p1;
|
||||
int pad1;
|
||||
|
||||
CColLine(void) { };
|
||||
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
|
||||
void Set(const CVector &p0, const CVector &p1);
|
||||
|
||||
CColLine *ctor(CVector *p0, CVector *p1) { return ::new (this) CColLine(*p0, *p1); }
|
||||
};
|
||||
|
||||
struct CColTriangle
|
||||
{
|
||||
uint16 a;
|
||||
uint16 b;
|
||||
uint16 c;
|
||||
uint8 surface;
|
||||
|
||||
void Set(const CVector *v, int a, int b, int c, uint8 surf, uint8 piece);
|
||||
};
|
||||
|
||||
struct CColTrianglePlane
|
||||
{
|
||||
CVector normal;
|
||||
float dist;
|
||||
uint8 dir;
|
||||
|
||||
void Set(const CVector *v, CColTriangle &tri);
|
||||
void GetNormal(CVector &n) const { n = normal; }
|
||||
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
|
||||
};
|
||||
|
||||
struct CColPoint
|
||||
{
|
||||
CVector point;
|
||||
int pad1;
|
||||
// the surface normal on the surface of point
|
||||
CVector normal;
|
||||
int pad2;
|
||||
uint8 surfaceA;
|
||||
uint8 pieceA;
|
||||
uint8 surfaceB;
|
||||
uint8 pieceB;
|
||||
float depth;
|
||||
};
|
||||
|
||||
struct CStoredCollPoly
|
||||
{
|
||||
CVector verts[3];
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct CColModel
|
||||
{
|
||||
CColSphere boundingSphere;
|
||||
CColBox boundingBox;
|
||||
short numSpheres;
|
||||
short numLines;
|
||||
short numBoxes;
|
||||
short numTriangles;
|
||||
int level;
|
||||
bool ownsCollisionVolumes;
|
||||
CColSphere *spheres;
|
||||
CColLine *lines;
|
||||
CColBox *boxes;
|
||||
CVector *vertices;
|
||||
CColTriangle *triangles;
|
||||
CColTrianglePlane *trianglePlanes;
|
||||
|
||||
CColModel(void);
|
||||
~CColModel(void);
|
||||
void RemoveCollisionVolumes(void);
|
||||
void CalculateTrianglePlanes(void);
|
||||
void RemoveTrianglePlanes(void);
|
||||
CLink<CColModel*> *GetLinkPtr(void);
|
||||
void SetLinkPtr(CLink<CColModel*>*);
|
||||
void GetTrianglePoint(CVector &v, int i) const;
|
||||
|
||||
CColModel *ctor(void) { return ::new (this) CColModel(); }
|
||||
void dtor(void) { this->CColModel::~CColModel(); }
|
||||
};
|
||||
|
||||
class CCollision
|
||||
{
|
||||
public:
|
||||
static eLevelName &ms_collisionInMemory;
|
||||
static CLinkList<CColModel*> &ms_colModelCache;
|
||||
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void LoadCollisionWhenINeedIt(bool changeLevel);
|
||||
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
|
||||
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
|
||||
|
||||
static void CalculateTrianglePlanes(CColModel *model);
|
||||
|
||||
// all these return true if there's a collision
|
||||
static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
|
||||
static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
|
||||
static bool TestLineBox(const CColLine &line, const CColBox &box);
|
||||
static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
|
||||
static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
||||
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
|
||||
static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
||||
static bool TestLineOfSight(CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSurf78);
|
||||
|
||||
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
|
||||
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
|
||||
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
|
||||
static bool ProcessVerticalLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
|
||||
static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
|
||||
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
|
||||
static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
|
||||
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSurf78);
|
||||
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSurf78, CStoredCollPoly *poly);
|
||||
static int32 ProcessColModels(const CMatrix &matrix1, CColModel &model1, const CMatrix &matrix2, CColModel &model2, CColPoint *point1, CColPoint *point2, float *linedists);
|
||||
|
||||
// TODO:
|
||||
// CCollision::IsStoredPolyStillValidVerticalLine
|
||||
|
||||
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
|
||||
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest);
|
||||
};
|
@ -0,0 +1,323 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Building.h"
|
||||
#include "Treadable.h"
|
||||
#include "Pools.h"
|
||||
#include "Timer.h"
|
||||
#include "Camera.h"
|
||||
#include "World.h"
|
||||
#include "CullZones.h"
|
||||
|
||||
int32 &CCullZones::NumCullZones = *(int*)0x8F2564;
|
||||
CCullZone *CCullZones::aZones = (CCullZone*)0x864750; // [NUMCULLZONES];
|
||||
int32 &CCullZones::NumAttributeZones = *(int*)0x8E29D0;
|
||||
CAttributeZone *CCullZones::aAttributeZones = (CAttributeZone*)0x709C60; // [NUMATTRIBZONES];
|
||||
uint16 *CCullZones::aIndices = (uint16*)0x847330; // [NUMZONEINDICES];
|
||||
int16 *CCullZones::aPointersToBigBuildingsForBuildings = (int16*)0x86C9D0; // [NUMBUILDINGS];
|
||||
int16 *CCullZones::aPointersToBigBuildingsForTreadables = (int16*)0x8F1B8C; // [NUMTREADABLES];
|
||||
|
||||
int32 &CCullZones::CurrentWantedLevelDrop_Player = *(int32*)0x880DA8;
|
||||
int32 &CCullZones::CurrentFlags_Camera = *(int32*)0x940718;
|
||||
int32 &CCullZones::CurrentFlags_Player = *(int32*)0x9415F0;
|
||||
int32 &CCullZones::OldCullZone = *(int32*)0x8E2C90;
|
||||
int32 &CCullZones::EntityIndicesUsed = *(int32*)0x8F2508;
|
||||
bool &CCullZones::bCurrentSubwayIsInvisible = *(bool*)0x95CDA5;
|
||||
bool &CCullZones::bCullZonesDisabled = *(bool*)0x95CD4A;
|
||||
|
||||
|
||||
void
|
||||
CCullZones::Init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
NumAttributeZones = 0;
|
||||
NumCullZones = 0;
|
||||
CurrentWantedLevelDrop_Player = 0;
|
||||
CurrentFlags_Camera = 0;
|
||||
CurrentFlags_Player = 0;
|
||||
OldCullZone = -1;
|
||||
EntityIndicesUsed = 0;
|
||||
bCurrentSubwayIsInvisible = false;
|
||||
|
||||
for(i = 0; i < NUMBUILDINGS; i++)
|
||||
aPointersToBigBuildingsForBuildings[i] = -1;
|
||||
for(i = 0; i < NUMTREADABLES; i++)
|
||||
aPointersToBigBuildingsForTreadables[i] = -1;
|
||||
}
|
||||
|
||||
void
|
||||
CCullZones::Update(void)
|
||||
{
|
||||
bool invisible;
|
||||
CVector v;
|
||||
|
||||
if(bCullZonesDisabled)
|
||||
return;
|
||||
|
||||
switch(CTimer::GetFrameCounter() & 7){
|
||||
case 0:
|
||||
case 4:
|
||||
/* Update Cull zone */
|
||||
ForceCullZoneCoors(TheCamera.GetGameCamPosition());
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Update camera attributes */
|
||||
CurrentFlags_Camera = FindAttributesForCoors(TheCamera.GetGameCamPosition(), nil);
|
||||
invisible = (CurrentFlags_Camera & ATTRZONE_SUBWAYVISIBLE) == 0;
|
||||
if(invisible != bCurrentSubwayIsInvisible){
|
||||
MarkSubwayAsInvisible(!invisible);
|
||||
bCurrentSubwayIsInvisible = invisible;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* Update player attributes */
|
||||
CurrentFlags_Player = FindAttributesForCoors(FindPlayerCoors(v),
|
||||
&CurrentWantedLevelDrop_Player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCullZones::ForceCullZoneCoors(CVector coors)
|
||||
{
|
||||
int32 z;
|
||||
z = FindCullZoneForCoors(coors);
|
||||
if(z != OldCullZone){
|
||||
if(OldCullZone >= 0)
|
||||
aZones[OldCullZone].DoStuffLeavingZone();
|
||||
if(z >= 0)
|
||||
aZones[z].DoStuffEnteringZone();
|
||||
OldCullZone = z;
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
CCullZones::FindCullZoneForCoors(CVector coors)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NumCullZones; i++)
|
||||
if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx &&
|
||||
coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy &&
|
||||
coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32
|
||||
CCullZones::FindAttributesForCoors(CVector coors, int32 *wantedLevel)
|
||||
{
|
||||
int i;
|
||||
int32 attribs;
|
||||
|
||||
attribs = 0;
|
||||
for(i = 0; i < NumAttributeZones; i++)
|
||||
if(coors.x >= aAttributeZones[i].minx && coors.x <= aAttributeZones[i].maxx &&
|
||||
coors.y >= aAttributeZones[i].miny && coors.y <= aAttributeZones[i].maxy &&
|
||||
coors.z >= aAttributeZones[i].minz && coors.z <= aAttributeZones[i].maxz){
|
||||
attribs |= aAttributeZones[i].attributes;
|
||||
if(wantedLevel && *wantedLevel <= aAttributeZones[i].wantedLevel)
|
||||
*wantedLevel = aAttributeZones[i].wantedLevel;
|
||||
}
|
||||
return attribs;
|
||||
}
|
||||
|
||||
CAttributeZone*
|
||||
CCullZones::FindZoneWithStairsAttributeForPlayer(void)
|
||||
{
|
||||
int i;
|
||||
CVector coors;
|
||||
|
||||
FindPlayerCoors(coors);
|
||||
for(i = 0; i < NumAttributeZones; i++)
|
||||
if(aAttributeZones[i].attributes & ATTRZONE_STAIRS &&
|
||||
coors.x >= aAttributeZones[i].minx && coors.x <= aAttributeZones[i].maxx &&
|
||||
coors.y >= aAttributeZones[i].miny && coors.y <= aAttributeZones[i].maxy &&
|
||||
coors.z >= aAttributeZones[i].minz && coors.z <= aAttributeZones[i].maxz)
|
||||
return &aAttributeZones[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
WRAPPER void
|
||||
CCullZones::MarkSubwayAsInvisible(bool visible)
|
||||
{ EAXJMP(0x525AF0);
|
||||
}
|
||||
|
||||
void
|
||||
CCullZones::AddCullZone(CVector const &position,
|
||||
float minx, float maxx,
|
||||
float miny, float maxy,
|
||||
float minz, float maxz,
|
||||
uint16 flag, int16 wantedLevel)
|
||||
{
|
||||
CCullZone *cull;
|
||||
CAttributeZone *attrib;
|
||||
|
||||
CVector v;
|
||||
if((flag & ATTRZONE_NOTCULLZONE) == 0){
|
||||
cull = &aZones[NumCullZones++];
|
||||
v = position;
|
||||
// WTF is this?
|
||||
if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f)
|
||||
v = CVector(1061.7f, -613.0f, 19.0f);
|
||||
if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f)
|
||||
v = CVector(1061.4f, -506.0f, 18.5f);
|
||||
cull->position.x = clamp(v.x, minx, maxx);
|
||||
cull->position.y = clamp(v.y, miny, maxy);
|
||||
cull->position.z = clamp(v.z, minz, maxz);
|
||||
cull->minx = minx;
|
||||
cull->maxx = maxx;
|
||||
cull->miny = miny;
|
||||
cull->maxy = maxy;
|
||||
cull->minz = minz;
|
||||
cull->maxz = maxz;
|
||||
cull->unk2 = 0;
|
||||
cull->unk3 = 0;
|
||||
cull->unk4 = 0;
|
||||
cull->m_indexStart = 0;
|
||||
}
|
||||
if(flag & ~ATTRZONE_NOTCULLZONE){
|
||||
attrib = &aAttributeZones[NumAttributeZones++];
|
||||
attrib->minx = minx;
|
||||
attrib->maxx = maxx;
|
||||
attrib->miny = miny;
|
||||
attrib->maxy = maxy;
|
||||
attrib->minz = minz;
|
||||
attrib->maxz = maxz;
|
||||
attrib->attributes = flag;
|
||||
attrib->wantedLevel = wantedLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
CCullZone::DoStuffLeavingZone(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < m_numBuildings; i++)
|
||||
DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
|
||||
for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++)
|
||||
DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]);
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i)
|
||||
{
|
||||
int16 bb;
|
||||
int j;
|
||||
|
||||
if(i < 6000){
|
||||
CPools::GetBuildingPool()->GetSlot(i)->m_bZoneCulled = false;
|
||||
bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
|
||||
if(bb != -1)
|
||||
CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = false;
|
||||
}else{
|
||||
i -= 6000;
|
||||
for(j = 0; j < 3; j++)
|
||||
DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i)
|
||||
{
|
||||
int16 bb;
|
||||
int j;
|
||||
|
||||
if(i < 6000){
|
||||
CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = false;
|
||||
CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled2 = false;
|
||||
bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
|
||||
if(bb != -1)
|
||||
CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = false;
|
||||
}else{
|
||||
i -= 6000;
|
||||
for(j = 0; j < 3; j++)
|
||||
DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffEnteringZone(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < m_numBuildings; i++)
|
||||
DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
|
||||
for(; i < m_numBuildings + m_numTreadablesPlus10m; i++)
|
||||
DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]);
|
||||
for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++)
|
||||
DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]);
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i)
|
||||
{
|
||||
int16 bb;
|
||||
int j;
|
||||
|
||||
if(i < 6000){
|
||||
CPools::GetBuildingPool()->GetSlot(i)->m_bZoneCulled = true;
|
||||
bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
|
||||
if(bb != -1)
|
||||
CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true;
|
||||
}else{
|
||||
i -= 6000;
|
||||
for(j = 0; j < 3; j++)
|
||||
DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i)
|
||||
{
|
||||
int16 bb;
|
||||
int j;
|
||||
|
||||
if(i < 6000){
|
||||
CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = true;;
|
||||
CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled2 = true;;
|
||||
bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
|
||||
if(bb != -1)
|
||||
CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true;
|
||||
}else{
|
||||
i -= 6000;
|
||||
for(j = 0; j < 3; j++)
|
||||
DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i)
|
||||
{
|
||||
int16 bb;
|
||||
int j;
|
||||
|
||||
if(i < 6000){
|
||||
CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = true;;
|
||||
bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
|
||||
if(bb != -1)
|
||||
CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true;
|
||||
}else{
|
||||
i -= 6000;
|
||||
for(j = 0; j < 3; j++)
|
||||
DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x524BC0, &CCullZones::Init, PATCH_JUMP);
|
||||
InjectHook(0x524F80, &CCullZones::Update, PATCH_JUMP);
|
||||
InjectHook(0x525370, &CCullZones::AddCullZone, PATCH_JUMP);
|
||||
InjectHook(0x5250D0, &CCullZones::ForceCullZoneCoors, PATCH_JUMP);
|
||||
InjectHook(0x525130, &CCullZones::FindCullZoneForCoors, PATCH_JUMP);
|
||||
InjectHook(0x5251C0, &CCullZones::FindAttributesForCoors, PATCH_JUMP);
|
||||
InjectHook(0x525290, &CCullZones::FindZoneWithStairsAttributeForPlayer, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x525610, &CCullZone::DoStuffLeavingZone, PATCH_JUMP);
|
||||
InjectHook(0x525810, &CCullZone::DoStuffEnteringZone, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -0,0 +1,93 @@
|
||||
class CCullZone
|
||||
{
|
||||
public:
|
||||
CVector position;
|
||||
float minx;
|
||||
float maxx;
|
||||
float miny;
|
||||
float maxy;
|
||||
float minz;
|
||||
float maxz;
|
||||
|
||||
// TODO: figure these out:
|
||||
int32 m_indexStart;
|
||||
int16 unk2;
|
||||
int16 unk3;
|
||||
int16 unk4;
|
||||
int16 m_numBuildings;
|
||||
int16 m_numTreadablesPlus10m;
|
||||
int16 m_numTreadables;
|
||||
|
||||
void DoStuffLeavingZone(void);
|
||||
static void DoStuffLeavingZone_OneBuilding(uint16 i);
|
||||
static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
|
||||
void DoStuffEnteringZone(void);
|
||||
static void DoStuffEnteringZone_OneBuilding(uint16 i);
|
||||
static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
|
||||
static void DoStuffEnteringZone_OneTreadable(uint16 i);
|
||||
};
|
||||
|
||||
enum eZoneAttribs
|
||||
{
|
||||
ATTRZONE_CAMCLOSEIN = 1,
|
||||
ATTRZONE_STAIRS = 2,
|
||||
ATTRZONE_1STPERSON = 4,
|
||||
ATTRZONE_NORAIN = 8,
|
||||
ATTRZONE_NOPOLICE = 0x10,
|
||||
ATTRZONE_NOTCULLZONE = 0x20,
|
||||
ATTRZONE_DOINEEDCOLLISION = 0x40,
|
||||
ATTRZONE_SUBWAYVISIBLE = 0x80,
|
||||
};
|
||||
|
||||
struct CAttributeZone
|
||||
{
|
||||
float minx;
|
||||
float maxx;
|
||||
float miny;
|
||||
float maxy;
|
||||
float minz;
|
||||
float maxz;
|
||||
int16 attributes;
|
||||
int16 wantedLevel;
|
||||
};
|
||||
|
||||
class CCullZones
|
||||
{
|
||||
public:
|
||||
static int32 &NumCullZones;
|
||||
static CCullZone *aZones; // [NUMCULLZONES];
|
||||
static int32 &NumAttributeZones;
|
||||
static CAttributeZone *aAttributeZones; // [NUMATTRIBZONES];
|
||||
static uint16 *aIndices; // [NUMZONEINDICES];
|
||||
static int16 *aPointersToBigBuildingsForBuildings; // [NUMBUILDINGS];
|
||||
static int16 *aPointersToBigBuildingsForTreadables; // [NUMTREADABLES];
|
||||
|
||||
static int32 &CurrentWantedLevelDrop_Player;
|
||||
static int32 &CurrentFlags_Camera;
|
||||
static int32 &CurrentFlags_Player;
|
||||
static int32 &OldCullZone;
|
||||
static int32 &EntityIndicesUsed;
|
||||
static bool &bCurrentSubwayIsInvisible;
|
||||
static bool &bCullZonesDisabled;
|
||||
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void ForceCullZoneCoors(CVector coors);
|
||||
static int32 FindCullZoneForCoors(CVector coors);
|
||||
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
|
||||
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
|
||||
static void MarkSubwayAsInvisible(bool visible);
|
||||
static void AddCullZone(CVector const &position,
|
||||
float minx, float maxx,
|
||||
float miny, float maxy,
|
||||
float minz, float maxz,
|
||||
uint16 flag, int16 wantedLevel);
|
||||
static bool CamCloseInForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_CAMCLOSEIN) != 0; }
|
||||
static bool CamStairsForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_STAIRS) != 0; }
|
||||
static bool Cam1stPersonForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_1STPERSON) != 0; }
|
||||
static bool NoPolice(void) { return (CurrentFlags_Player & ATTRZONE_NOPOLICE) != 0; }
|
||||
static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; }
|
||||
static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; }
|
||||
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
|
||||
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Game.h"
|
||||
|
||||
int &CGame::currLevel = *(int*)0x941514;
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
enum eLevelName
|
||||
{
|
||||
LEVEL_NONE = 0,
|
||||
LEVEL_INDUSTRIAL,
|
||||
LEVEL_COMMERCIAL,
|
||||
LEVEL_SUBURBAN
|
||||
};
|
||||
|
||||
class CGame
|
||||
{
|
||||
public:
|
||||
static int &currLevel;
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
class CGeneral
|
||||
{
|
||||
public:
|
||||
static float GetATanOfXY(float x, float y){
|
||||
if(y >= 0.0f) return atan2(x, y);
|
||||
return atan2(x, y) + 2*M_PI;
|
||||
}
|
||||
|
||||
// not too sure about all these...
|
||||
static uint16 GetRandomNumber(void)
|
||||
{ return myrand() & 0xFFFF; }
|
||||
// Probably don't want to ever reach high
|
||||
static float GetRandomNumberInRange(float low, float high)
|
||||
{ return low + (high - low)*(GetRandomNumber()/65536.0f); }
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Glass.h"
|
||||
|
||||
WRAPPER void
|
||||
CGlass::WindowRespondsToCollision(CEntity *ent, float amount, CVector speed, CVector point, bool foo)
|
||||
{
|
||||
EAXJMP(0x503F10);
|
||||
}
|
||||
|
||||
WRAPPER void
|
||||
CGlass::WindowRespondsToSoftCollision(CEntity *ent, float amount)
|
||||
{
|
||||
EAXJMP(0x504630);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
|
||||
class CGlass
|
||||
{
|
||||
public:
|
||||
static void WindowRespondsToCollision(CEntity *ent, float amount, CVector speed, CVector point, bool foo);
|
||||
static void WindowRespondsToSoftCollision(CEntity *ent, float amount);
|
||||
};
|
@ -0,0 +1,26 @@
|
||||
#include "common.h"
|
||||
#include "Pools.h"
|
||||
#include "Lists.h"
|
||||
|
||||
void*
|
||||
CPtrNode::operator new(size_t){
|
||||
CPtrNode *node = CPools::GetPtrNodePool()->New();
|
||||
assert(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
CPtrNode::operator delete(void *p, size_t){
|
||||
CPools::GetPtrNodePool()->Delete((CPtrNode*)p);
|
||||
}
|
||||
|
||||
void*
|
||||
CEntryInfoNode::operator new(size_t){
|
||||
CEntryInfoNode *node = CPools::GetEntryInfoNodePool()->New();
|
||||
assert(node);
|
||||
return node;
|
||||
}
|
||||
void
|
||||
CEntryInfoNode::operator delete(void *p, size_t){
|
||||
CPools::GetEntryInfoNodePool()->Delete((CEntryInfoNode*)p);
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
|
||||
class CPtrNode
|
||||
{
|
||||
public:
|
||||
void *item;
|
||||
CPtrNode *prev;
|
||||
CPtrNode *next;
|
||||
|
||||
void *operator new(size_t);
|
||||
void operator delete(void *p, size_t);
|
||||
};
|
||||
|
||||
class CPtrList
|
||||
{
|
||||
public:
|
||||
CPtrNode *first;
|
||||
|
||||
CPtrList(void) { first = nil; }
|
||||
~CPtrList(void) { Flush(); }
|
||||
CPtrNode *FindItem(void *item){
|
||||
CPtrNode *node;
|
||||
for(node = first; node; node = node->next)
|
||||
if(node->item == item)
|
||||
return node;
|
||||
return nil;
|
||||
}
|
||||
CPtrNode *InsertNode(CPtrNode *node){
|
||||
node->prev = nil;
|
||||
node->next = first;
|
||||
if(first)
|
||||
first->prev = node;
|
||||
first = node;
|
||||
return node;
|
||||
}
|
||||
CPtrNode *InsertItem(void *item){
|
||||
CPtrNode *node = new CPtrNode;
|
||||
node->item = item;
|
||||
InsertNode(node);
|
||||
|