Merge branch 'master' into garages_dev

This commit is contained in:
Nikolay Korolev 2020-04-08 14:26:07 +03:00
commit b075b0fccf
16 changed files with 1334 additions and 158 deletions

View File

@ -40,14 +40,9 @@ to reverse at the time, calling the original functions is acceptable.
```
cAudioManager - WIP
CBoat
CBrightLights
CBulletInfo
CCullZone - only mobile stuff
CCullZones - only mobile stuff
CExplosion
CFileLoader - almost done
CMenuManager - WIP
CMotionBlurStreaks
CObject
CPacManPickups
CPad - only cheats
@ -56,10 +51,7 @@ CPools - save/loading
CRecordDataForChase
CRecordDataForGame
CRoadBlocks
CRubbish
CSceneEdit
CSkidmarks
CSpecialFX
CStats
CTrafficLights
CWeapon
@ -68,6 +60,14 @@ CWorld
GenericLoad
```
The following classes have only unused or practically unused code left:
```
CCullZone - only mobile stuff
CCullZones - only mobile stuff
CFileLoader - almost done
CSceneEdit
```
### Coding style
I started writing in [Plan 9 style](http://man.cat-v.org/plan_9/6/style),

View File

@ -1679,7 +1679,7 @@ float CGarage::CalcDistToGarageRectangleSquared(float X, float Y)
else
distX = 0.0f;
if (Y < m_fY1)
distY = m_fY1 - X;
distY = m_fY1 - Y;
else if (Y > m_fY2)
distY = Y - m_fY2;
else
@ -2358,4 +2358,4 @@ STARTPATCHES
InjectHook(0x427AB0, CGarages::IsPointInAGarageCameraZone, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x427BC0, CGarages::CameraShouldBeOutside, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x428940, CGarages::Load, PATCH_JUMP); // GenericLoad
ENDPATCHES
ENDPATCHES

View File

@ -1107,7 +1107,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
CStreaming::LoadScene(ff_coord);
}
if (cam_mode == REPLAYCAMMODE_ASSTORED)
TheCamera.CarZoomIndicator = 5.0f;
TheCamera.CarZoomIndicator = CAM_ZOOM_CINEMATIC;
}
void CReplay::StoreStuffInMem(void)

View File

@ -7117,7 +7117,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_CLOSE_GARAGE:
{
CollectParameters(&m_nIp, 1);
CGarages::CloseGarage(ScriptParams[1]);
CGarages::CloseGarage(ScriptParams[0]);
return 0;
}
case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:

View File

@ -4672,15 +4672,15 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
else {
switch ((int)TheCamera.CarZoomIndicator) {
// near
case 1:
case CAM_ZOOM_1:
zoomModeAlphaOffset = ZmOneAlphaOffsetLCS[alphaArrPos];
break;
// mid
case 2:
case CAM_ZOOM_2:
zoomModeAlphaOffset = ZmTwoAlphaOffsetLCS[alphaArrPos];
break;
// far
case 3:
case CAM_ZOOM_3:
zoomModeAlphaOffset = ZmThreeAlphaOffsetLCS[alphaArrPos];
break;
default:
@ -4705,14 +4705,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
}
} else {
// 0.6f = fTestShiftHeliCamTarget
TargetCoors.x += 0.6f * car->GetUp().x * colMaxZ;
TargetCoors.y += 0.6f * car->GetUp().y * colMaxZ;
TargetCoors.z += 0.6f * car->GetUp().z * colMaxZ;
TargetCoors += 0.6f * car->GetUp() * colMaxZ;
}
float minDistForVehType = CARCAM_SET[camSetArrPos][4];
if ((int)TheCamera.CarZoomIndicator == 1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
if (TheCamera.CarZoomIndicator == CAM_ZOOM_1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
minDistForVehType = minDistForVehType * 0.65f;
}
@ -4904,8 +4902,8 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// yMovement = 0.0;
if (!nextDirectionIsForward) {
yMovement = 0.0;
xMovement = 0.0;
yMovement = 0.0f;
xMovement = 0.0f;
}
if (camSetArrPos == 0 || camSetArrPos == 7) {

View File

@ -124,8 +124,8 @@ CCamera::Init(void)
m_WideScreenOn = false;
m_fFOV_Wide_Screen = 0.0f;
m_bRestoreByJumpCut = false;
CarZoomIndicator = 2.0f;
PedZoomIndicator = 2.0f;
CarZoomIndicator = CAM_ZOOM_2;
PedZoomIndicator = CAM_ZOOM_2;
CarZoomValueSmooth = 0.0f;
m_fPedZoomValueSmooth = 0.0f;
pTargetEntity = nil;
@ -623,11 +623,11 @@ CCamera::CamControl(void)
if(CPad::GetPad(0)->CycleCameraModeUpJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
!m_WideScreenOn)
CarZoomIndicator -= 1.0f;
CarZoomIndicator--;
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
!m_WideScreenOn)
CarZoomIndicator += 1.0f;
CarZoomIndicator++;
if(!m_bFailedCullZoneTestPreviously){
if(CarZoomIndicator < CAM_ZOOM_1STPRS) CarZoomIndicator = CAM_ZOOM_CINEMATIC;
else if(CarZoomIndicator > CAM_ZOOM_CINEMATIC) CarZoomIndicator = CAM_ZOOM_1STPRS;
@ -812,7 +812,7 @@ CCamera::CamControl(void)
else
PedZoomIndicator = CAM_ZOOM_TOPDOWN;
}else
PedZoomIndicator -= 1.0f;
PedZoomIndicator--;
}
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
@ -823,7 +823,7 @@ CCamera::CamControl(void)
else
PedZoomIndicator = CAM_ZOOM_TOPDOWN;
}else
PedZoomIndicator += 1.0f;
PedZoomIndicator++;
}
// disabled obbe's cam here
if(PedZoomIndicator < CAM_ZOOM_1) PedZoomIndicator = CAM_ZOOM_TOPDOWN;
@ -1223,7 +1223,7 @@ CCamera::CamControl(void)
ReqMode == CCam::MODE_1STPERSON_RUNABOUT || ReqMode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
ReqMode == CCam::MODE_FIGHT_CAM_RUNABOUT || ReqMode == CCam::MODE_HELICANNON_1STPERSON ||
WhoIsInControlOfTheCamera == CAMCONTROL_SCRIPT ||
m_bJustCameOutOfGarage || m_bPlayerIsInGarage)
m_bJustCameOutOfGarage || m_bPlayerIsInGarage)
canUseObbeCam = false;
if(m_bObbeCinematicPedCamOn && canUseObbeCam)
@ -1524,7 +1524,7 @@ CCamera::UpdateTargetEntity(void)
cantOpen = false;
if(PLAYER->GetPedState() == PED_ENTER_CAR && !cantOpen){
if(!enteringCar && CarZoomIndicator != 0.0f){
if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS){
pTargetEntity = PLAYER->m_pMyVehicle;
if(PLAYER->m_pMyVehicle == nil)
pTargetEntity = PLAYER;
@ -1532,7 +1532,7 @@ CCamera::UpdateTargetEntity(void)
}
if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){
if(!enteringCar && CarZoomIndicator != 0.0f)
if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS)
#ifdef GTA_PS2_STUFF
// dunno if this has any amazing effects
{
@ -1549,7 +1549,7 @@ CCamera::UpdateTargetEntity(void)
pTargetEntity = FindPlayerPed();
if(PLAYER->GetPedState() == PED_DRAG_FROM_CAR)
pTargetEntity = FindPlayerPed();
if(pTargetEntity->IsVehicle() && CarZoomIndicator != 0.0f && FindPlayerPed()->GetPedState() == PED_ARRESTED)
if(pTargetEntity->IsVehicle() && CarZoomIndicator != CAM_ZOOM_1STPRS && FindPlayerPed()->GetPedState() == PED_ARRESTED)
pTargetEntity = FindPlayerPed();
}
}

View File

@ -16,12 +16,15 @@ enum
};
#define DEFAULT_NEAR (0.9f)
#define CAM_ZOOM_1STPRS (0.0f)
#define CAM_ZOOM_1 (1.0f)
#define CAM_ZOOM_2 (2.0f)
#define CAM_ZOOM_3 (3.0f)
#define CAM_ZOOM_TOPDOWN (4.0f)
#define CAM_ZOOM_CINEMATIC (5.0f)
enum
{
CAM_ZOOM_1STPRS,
CAM_ZOOM_1,
CAM_ZOOM_2,
CAM_ZOOM_3,
CAM_ZOOM_TOPDOWN,
CAM_ZOOM_CINEMATIC,
};
#ifdef FREE_CAM // LCS values
#define FREE_CAR_ZOOM_VALUE_1 (-1.0f)
@ -412,7 +415,11 @@ uint32 unknown; // some counter having to do with music
float CamFrontXNorm;
float CamFrontYNorm;
#if 0 // TODO: FIX_BUGS once GenericLoad is done
int32 CarZoomIndicator;
#else
float CarZoomIndicator;
#endif
float CarZoomValue;
float CarZoomValueSmooth;
@ -448,7 +455,11 @@ uint32 unknown; // some counter having to do with music
float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson;
float Orientation;
#if 0 // TODO: FIX_BUGS once GenericLoad is done
int32 PedZoomIndicator;
#else
float PedZoomIndicator;
#endif
float PlayerExhaustion;
float SoundDistUp, SoundDistLeft, SoundDistRight;
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;

View File

@ -73,9 +73,12 @@ enum Config {
NUMCORONAS = 56,
NUMPOINTLIGHTS = 32,
NUM3DMARKERS = 32,
NUMBRIGHTLIGHTS = 32,
NUMSHINYTEXTS = 32,
NUMMONEYMESSAGES = 16,
NUMPICKUPMESSAGES = 16,
NUMBULLETTRACES = 16,
NUMMBLURSTREAKS = 4,
NUMONSCREENTIMERENTRIES = 1,
NUMRADARBLIPS = 32,

View File

@ -162,17 +162,17 @@ Idle(void *arg)
} else {
CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
tbEndTimer("DMAudio.Service");
#endif
}
@ -181,18 +181,18 @@ Idle(void *arg)
#else
CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
tbEndTimer("DMAudio.Service");
#endif
#endif
@ -222,16 +222,16 @@ Idle(void *arg)
}
#endif
#ifdef TIMEBARS
tbStartTimer(0, "CnstrRenderList");
tbStartTimer(0, "CnstrRenderList");
#endif
CRenderer::ConstructRenderList();
#ifdef TIMEBARS
tbEndTimer("CnstrRenderList");
tbStartTimer(0, "PreRender");
tbStartTimer(0, "PreRender");
#endif
CRenderer::PreRender();
#ifdef TIMEBARS
tbEndTimer("PreRender");
tbEndTimer("PreRender");
#endif
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
@ -251,17 +251,17 @@ Idle(void *arg)
RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
#ifdef TIMEBARS
tbStartTimer(0, "RenderScene");
tbStartTimer(0, "RenderScene");
#endif
RenderScene();
#ifdef TIMEBARS
tbEndTimer("RenderScene");
tbEndTimer("RenderScene");
#endif
RenderDebugShit();
RenderEffects();
#ifdef TIMEBARS
tbStartTimer(0, "RenderMotionBlur");
#ifdef TIMEBARS
tbStartTimer(0, "RenderMotionBlur");
#endif
if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
TheCamera.m_ScreenReductionPercentage > 0.0f)
@ -269,11 +269,11 @@ Idle(void *arg)
TheCamera.RenderMotionBlur();
#ifdef TIMEBARS
tbEndTimer("RenderMotionBlur");
tbStartTimer(0, "Render2dStuff");
tbStartTimer(0, "Render2dStuff");
#endif
Render2dStuff();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff");
tbEndTimer("Render2dStuff");
#endif
}else{
float viewWindow = DEFAULT_VIEWWINDOW;
@ -293,21 +293,21 @@ Idle(void *arg)
DefinedState();
#endif
#ifdef TIMEBARS
tbStartTimer(0, "RenderMenus");
tbStartTimer(0, "RenderMenus");
#endif
RenderMenus();
#ifdef TIMEBARS
tbEndTimer("RenderMenus");
tbStartTimer(0, "DoFade");
tbStartTimer(0, "DoFade");
#endif
DoFade();
#ifdef TIMEBARS
tbEndTimer("DoFade");
tbStartTimer(0, "Render2dStuff-Fade");
tbStartTimer(0, "Render2dStuff-Fade");
#endif
Render2dStuffAfterFade();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff-Fade");
tbEndTimer("Render2dStuff-Fade");
#endif
CCredits::Render();

View File

@ -394,13 +394,13 @@ CEntity::PreRender(void)
}else if(GetModelIndex() == MI_GRENADE){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
100, 100, 100,
TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(),
TheCamera.GetPosition() + 0.07f*TheCamera.GetRight());
GetPosition() - 0.07f*TheCamera.GetRight(),
GetPosition() + 0.07f*TheCamera.GetRight());
}else if(GetModelIndex() == MI_MOLOTOV){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
0, 100, 0,
TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(),
TheCamera.GetPosition() + 0.07f*TheCamera.GetRight());
GetPosition() - 0.07f*TheCamera.GetRight(),
GetPosition() + 0.07f*TheCamera.GetRight());
}
}else if(GetModelIndex() == MI_MISSILE){
CVector pos = GetPosition();

View File

@ -1,10 +1,420 @@
#include "common.h"
#include "main.h"
#include "patcher.h"
#include "General.h"
#include "Timer.h"
#include "Weather.h"
#include "Camera.h"
#include "World.h"
#include "Vehicle.h"
#include "ZoneCull.h"
#include "TxdStore.h"
#include "RenderBuffer.h"
#include "Rubbish.h"
WRAPPER void CRubbish::Render(void) { EAXJMP(0x512190); }
WRAPPER void CRubbish::StirUp(CVehicle *veh) { EAXJMP(0x512690); }
WRAPPER void CRubbish::Update(void) { EAXJMP(0x511B90); }
WRAPPER void CRubbish::SetVisibility(bool) { EAXJMP(0x512AA0); }
WRAPPER void CRubbish::Init(void) { EAXJMP(0x511940); }
WRAPPER void CRubbish::Shutdown(void) { EAXJMP(0x511B50); }
#define RUBBISH_MAX_DIST (18.0f)
#define RUBBISH_FADE_DIST (16.5f)
RwTexture *gpRubbishTexture[4];
RwImVertexIndex RubbishIndexList[6];
RwImVertexIndex RubbishIndexList2[6]; // unused
RwIm3DVertex RubbishVertices[4];
bool CRubbish::bRubbishInvisible;
int CRubbish::RubbishVisibility;
COneSheet CRubbish::aSheets[NUM_RUBBISH_SHEETS];
COneSheet CRubbish::StartEmptyList;
COneSheet CRubbish::EndEmptyList;
COneSheet CRubbish::StartStaticsList;
COneSheet CRubbish::EndStaticsList;
COneSheet CRubbish::StartMoversList;
COneSheet CRubbish::EndMoversList;
void
COneSheet::AddToList(COneSheet *list)
{
this->m_next = list->m_next;
this->m_prev = list;
list->m_next = this;
this->m_next->m_prev = this;
}
void
COneSheet::RemoveFromList(void)
{
m_next->m_prev = m_prev;
m_prev->m_next = m_next;
}
void
CRubbish::Render(void)
{
int type;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
for(type = 0; type < 4; type++){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
COneSheet *sheet;
for(sheet = &aSheets[type*NUM_RUBBISH_SHEETS / 4];
sheet < &aSheets[(type+1)*NUM_RUBBISH_SHEETS / 4];
sheet++){
if(sheet->m_state == 0)
continue;
uint32 alpha = 128;
CVector pos;
if(sheet->m_state == 1){
pos = sheet->m_basePos;
if(!sheet->m_isVisible)
alpha = 0;
}else{
pos = sheet->m_animatedPos;
// Not fully visible during animation, calculate current alpha
if(!sheet->m_isVisible || !sheet->m_targetIsVisible){
float t = (float)(CTimer::GetTimeInMilliseconds() - sheet->m_moveStart)/sheet->m_moveDuration;
float f1 = sheet->m_isVisible ? 1.0f-t : 0.0f;
float f2 = sheet->m_targetIsVisible ? t : 0.0f;
alpha = 128 * (f1+f2);
}
}
float camDist = (pos - TheCamera.GetPosition()).Magnitude2D();
if(camDist < RUBBISH_MAX_DIST){
if(camDist >= RUBBISH_FADE_DIST)
alpha -= alpha*(camDist-RUBBISH_FADE_DIST)/(RUBBISH_MAX_DIST-RUBBISH_FADE_DIST);
alpha = (RubbishVisibility*alpha)/256;
float vx = Sin(sheet->m_angle) * 0.4f;
float vy = Cos(sheet->m_angle) * 0.4f;
int v = TempBufferVerticesStored;
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx, pos.y + vy, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x - vy, pos.y + vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x + vy, pos.y - vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx, pos.y - vy, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], 255, 255, 255, alpha);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], 0.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+1], 1.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+1], 0.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+2], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+2], 1.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+3], 1.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+3], 1.0f);
int i = TempBufferIndicesStored;
TempBufferRenderIndexList[i+0] = RubbishIndexList[0] + TempBufferVerticesStored;
TempBufferRenderIndexList[i+1] = RubbishIndexList[1] + TempBufferVerticesStored;
TempBufferRenderIndexList[i+2] = RubbishIndexList[2] + TempBufferVerticesStored;
TempBufferRenderIndexList[i+3] = RubbishIndexList[3] + TempBufferVerticesStored;
TempBufferRenderIndexList[i+4] = RubbishIndexList[4] + TempBufferVerticesStored;
TempBufferRenderIndexList[i+5] = RubbishIndexList[5] + TempBufferVerticesStored;
TempBufferVerticesStored += 4;
TempBufferIndicesStored += 6;
}
}
if(TempBufferIndicesStored != 0){
LittleTest();
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
}
}
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
}
void
CRubbish::StirUp(CVehicle *veh)
{
if((CTimer::GetFrameCounter() ^ (veh->m_randomSeed&3)) == 0)
return;
if(Abs(veh->GetPosition().x - TheCamera.GetPosition().x) < 20.0f &&
Abs(veh->GetPosition().y - TheCamera.GetPosition().y) < 20.0f)
if(Abs(veh->GetMoveSpeed().x) > 0.05f || Abs(veh->GetMoveSpeed().y) > 0.05f){
float speed = veh->GetMoveSpeed().Magnitude2D();
if(speed > 0.05f){
bool movingForward = DotProduct2D(veh->GetMoveSpeed(), veh->GetForward()) > 0.0f;
COneSheet *sheet = StartStaticsList.m_next;
CVector2D size = veh->GetColModel()->boundingBox.max;
// Check all static sheets
while(sheet != &EndStaticsList){
COneSheet *next = sheet->m_next;
CVector2D carToSheet = sheet->m_basePos - veh->GetPosition();
float distFwd = DotProduct2D(carToSheet, veh->GetForward());
// sheet has to be a bit behind car
if(movingForward && distFwd < -0.5f*size.y && distFwd > -1.5f*size.y ||
!movingForward && distFwd > 0.5f*size.y && distFwd < 1.5f*size.y){
float distSide = Abs(DotProduct2D(carToSheet, veh->GetRight()));
if(distSide < 1.5*size.x){
// Check with higher speed for sheet directly behind car
float speedToCheck = distSide < size.x ? speed : speed*0.5f;
if(speedToCheck > 0.05f){
sheet->m_state = 2;
if(speedToCheck > 0.15f)
sheet->m_animationType = 2;
else
sheet->m_animationType = 1;
sheet->m_moveDuration = 2000;
sheet->m_xDist = veh->GetMoveSpeed().x;
sheet->m_yDist = veh->GetMoveSpeed().y;
float dist = Sqrt(SQR(sheet->m_xDist)+SQR(sheet->m_yDist));
sheet->m_xDist *= 25.0f*speed/dist;
sheet->m_yDist *= 25.0f*speed/dist;
sheet->m_animHeight = 3.0f*speed;
sheet->m_moveStart = CTimer::GetTimeInMilliseconds();
float tx = sheet->m_basePos.x + sheet->m_xDist;
float ty = sheet->m_basePos.y + sheet->m_yDist;
float tz = sheet->m_basePos.z + 3.0f;
sheet->m_targetZ = CWorld::FindGroundZFor3DCoord(tx, ty, tz, nil) + 0.1f;
sheet->RemoveFromList();
sheet->AddToList(&StartMoversList);
}
}
}
sheet = next;
}
}
}
}
static float aAnimations[3][34] = {
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
// Normal move
{ 0.0f, 0.05f, 0.12f, 0.25f, 0.42f, 0.57f, 0.68f, 0.8f, 0.86f, 0.9f, 0.93f, 0.95f, 0.96f, 0.97f, 0.98f, 0.99f, 1.0f, // XY movemnt
0.15f, 0.35f, 0.6f, 0.9f, 1.2f, 1.25f, 1.3f, 1.2f, 1.1f, 0.95f, 0.8f, 0.6f, 0.45f, 0.3f, 0.2f, 0.1f, 0 }, // Z movement
// Stirred up by fast vehicle
{ 0.0f, 0.05f, 0.12f, 0.25f, 0.42f, 0.57f, 0.68f, 0.8f, 0.95f, 1.1f, 1.15f, 1.18f, 1.15f, 1.1f, 1.05f, 1.03f, 1.0f,
0.15f, 0.35f, 0.6f, 0.9f, 1.2f, 1.25f, 1.3f, 1.2f, 1.1f, 0.95f, 0.8f, 0.6f, 0.45f, 0.3f, 0.2f, 0.1f, 0 }
};
void
CRubbish::Update(void)
{
bool foundGround;
// FRAMETIME
if(bRubbishInvisible)
RubbishVisibility = max(RubbishVisibility-5, 0);
else
RubbishVisibility = min(RubbishVisibility+5, 255);
// Spawn a new sheet
COneSheet *sheet = StartEmptyList.m_next;
if(sheet != &EndEmptyList){
float spawnDist;
float spawnAngle;
spawnDist = (CGeneral::GetRandomNumber()&0xFF)/256.0f + RUBBISH_MAX_DIST;
uint8 r = CGeneral::GetRandomNumber();
if(r&1)
spawnAngle = (CGeneral::GetRandomNumber()&0xFF)/256.0f * 6.28f;
else
spawnAngle = (r-128)/160.0f + TheCamera.Orientation;
sheet->m_basePos.x = TheCamera.GetPosition().x + spawnDist*Sin(spawnAngle);
sheet->m_basePos.y = TheCamera.GetPosition().y + spawnDist*Cos(spawnAngle);
sheet->m_basePos.z = CWorld::FindGroundZFor3DCoord(sheet->m_basePos.x, sheet->m_basePos.y, TheCamera.GetPosition().z, &foundGround) + 0.1f;
if(foundGround){
// Found ground, so add to statics list
sheet->m_angle = (CGeneral::GetRandomNumber()&0xFF)/256.0f * 6.28f;
sheet->m_state = 1;
if(CCullZones::FindAttributesForCoors(sheet->m_basePos, nil) & ATTRZONE_NORAIN)
sheet->m_isVisible = false;
else
sheet->m_isVisible = true;
sheet->RemoveFromList();
sheet->AddToList(&StartStaticsList);
}
}
// Process animation
sheet = StartMoversList.m_next;
while(sheet != &EndMoversList){
uint32 currentTime = CTimer::GetTimeInMilliseconds() - sheet->m_moveStart;
if(currentTime < sheet->m_moveDuration){
// Animation
int step = 16 * currentTime / sheet->m_moveDuration; // 16 steps in animation
int stepTime = sheet->m_moveDuration/16; // time in each step
float s = (float)(currentTime - stepTime*step) / stepTime; // position on step
float t = (float)currentTime / sheet->m_moveDuration; // position on total animation
// factors for xy and z-movment
float fxy = aAnimations[sheet->m_animationType][step]*(1.0f-s) + aAnimations[sheet->m_animationType][step+1]*s;
float fz = aAnimations[sheet->m_animationType][step+17]*(1.0f-s) + aAnimations[sheet->m_animationType][step+1+17]*s;
sheet->m_animatedPos.x = sheet->m_basePos.x + fxy*sheet->m_xDist;
sheet->m_animatedPos.y = sheet->m_basePos.y + fxy*sheet->m_yDist;
sheet->m_animatedPos.z = (1.0f-t)*sheet->m_basePos.z + t*sheet->m_targetZ + fz*sheet->m_animHeight;
sheet->m_angle += CTimer::GetTimeStep()*0.04f;
if(sheet->m_angle > 6.28f)
sheet->m_angle -= 6.28f;
sheet = sheet->m_next;
}else{
// End of animation, back into statics list
sheet->m_basePos.x += sheet->m_xDist;
sheet->m_basePos.y += sheet->m_yDist;
sheet->m_basePos.z = sheet->m_targetZ;
sheet->m_state = 1;
sheet->m_isVisible = sheet->m_targetIsVisible;
COneSheet *next = sheet->m_next;
sheet->RemoveFromList();
sheet->AddToList(&StartStaticsList);
sheet = next;
}
}
// Stir up a sheet by wind
// FRAMETIME
int freq;
if(CWeather::Wind < 0.1f)
freq = 31;
else if(CWeather::Wind < 0.4f)
freq = 7;
else if(CWeather::Wind < 0.7f)
freq = 1;
else
freq = 0;
if((CTimer::GetFrameCounter() & freq) == 0){
// Pick a random sheet and set animation state if static
int i = CGeneral::GetRandomNumber() % NUM_RUBBISH_SHEETS;
if(aSheets[i].m_state == 1){
aSheets[i].m_moveStart = CTimer::GetTimeInMilliseconds();
aSheets[i].m_moveDuration = CWeather::Wind*1500.0f + 1000.0f;
aSheets[i].m_animHeight = 0.2f;
aSheets[i].m_xDist = 3.0f*CWeather::Wind;
aSheets[i].m_yDist = 3.0f*CWeather::Wind;
// Check if target position is ok
float tx = aSheets[i].m_basePos.x + aSheets[i].m_xDist;
float ty = aSheets[i].m_basePos.y + aSheets[i].m_yDist;
float tz = aSheets[i].m_basePos.z + 3.0f;
aSheets[i].m_targetZ = CWorld::FindGroundZFor3DCoord(tx, ty, tz, &foundGround) + 0.1f;
if(CCullZones::FindAttributesForCoors(CVector(tx, ty, aSheets[i].m_targetZ), nil) & ATTRZONE_NORAIN)
aSheets[i].m_targetIsVisible = false;
else
aSheets[i].m_targetIsVisible = true;
if(foundGround){
// start animation
aSheets[i].m_state = 2;
aSheets[i].m_animationType = 1;
aSheets[i].RemoveFromList();
aSheets[i].AddToList(&StartMoversList);
}
}
}
// Remove sheets that are too far away
int i = (CTimer::GetFrameCounter()%(NUM_RUBBISH_SHEETS/4))*4;
int last = ((CTimer::GetFrameCounter()%(NUM_RUBBISH_SHEETS/4)) + 1)*4;
for(; i < last; i++){
if(aSheets[i].m_state == 1 &&
(aSheets[i].m_basePos - TheCamera.GetPosition()).MagnitudeSqr2D() > SQR(RUBBISH_MAX_DIST+1.0f)){
aSheets[i].m_state = 0;
aSheets[i].RemoveFromList();
aSheets[i].AddToList(&StartEmptyList);
}
}
}
void
CRubbish::SetVisibility(bool visible)
{
bRubbishInvisible = !visible;
}
void
CRubbish::Init(void)
{
int i;
for(i = 0; i < NUM_RUBBISH_SHEETS; i++){
aSheets[i].m_state = 0;
if(i < NUM_RUBBISH_SHEETS-1)
aSheets[i].m_next = &aSheets[i+1];
else
aSheets[i].m_next = &EndEmptyList;
if(i > 0)
aSheets[i].m_prev = &aSheets[i-1];
else
aSheets[i].m_prev = &StartEmptyList;
}
StartEmptyList.m_next = &aSheets[0];
StartEmptyList.m_prev = nil;
EndEmptyList.m_next = nil;
EndEmptyList.m_prev = &aSheets[NUM_RUBBISH_SHEETS-1];
StartStaticsList.m_next = &EndStaticsList;
StartStaticsList.m_prev = nil;
EndStaticsList.m_next = nil;
EndStaticsList.m_prev = &StartStaticsList;
StartMoversList.m_next = &EndMoversList;
StartMoversList.m_prev = nil;
EndMoversList.m_next = nil;
EndMoversList.m_prev = &StartMoversList;
// unused
RwIm3DVertexSetU(&RubbishVertices[0], 0.0f);
RwIm3DVertexSetV(&RubbishVertices[0], 0.0f);
RwIm3DVertexSetU(&RubbishVertices[1], 1.0f);
RwIm3DVertexSetV(&RubbishVertices[1], 0.0f);
RwIm3DVertexSetU(&RubbishVertices[2], 0.0f);
RwIm3DVertexSetV(&RubbishVertices[2], 1.0f);
RwIm3DVertexSetU(&RubbishVertices[3], 1.0f);
RwIm3DVertexSetV(&RubbishVertices[3], 1.0f);
// unused
RubbishIndexList2[0] = 0;
RubbishIndexList2[1] = 2;
RubbishIndexList2[2] = 1;
RubbishIndexList2[3] = 1;
RubbishIndexList2[4] = 2;
RubbishIndexList2[5] = 3;
RubbishIndexList[0] = 0;
RubbishIndexList[1] = 1;
RubbishIndexList[2] = 2;
RubbishIndexList[3] = 1;
RubbishIndexList[4] = 3;
RubbishIndexList[5] = 2;
CTxdStore::PushCurrentTxd();
int slot = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slot);
gpRubbishTexture[0] = RwTextureRead("gameleaf01_64", nil);
gpRubbishTexture[1] = RwTextureRead("gameleaf02_64", nil);
gpRubbishTexture[2] = RwTextureRead("newspaper01_64", nil);
gpRubbishTexture[3] = RwTextureRead("newspaper02_64", nil);
CTxdStore::PopCurrentTxd();
RubbishVisibility = 255;
bRubbishInvisible = false;
}
void
CRubbish::Shutdown(void)
{
RwTextureDestroy(gpRubbishTexture[0]);
RwTextureDestroy(gpRubbishTexture[1]);
RwTextureDestroy(gpRubbishTexture[2]);
RwTextureDestroy(gpRubbishTexture[3]);
}

View File

@ -2,13 +2,50 @@
class CVehicle;
enum {
// NB: not all values are allowed, check the code
NUM_RUBBISH_SHEETS = 64
};
class COneSheet
{
public:
CVector m_basePos;
CVector m_animatedPos;
float m_targetZ;
int8 m_state;
int8 m_animationType;
uint32 m_moveStart;
uint32 m_moveDuration;
float m_animHeight;
float m_xDist;
float m_yDist;
float m_angle;
bool m_isVisible;
bool m_targetIsVisible;
COneSheet *m_next;
COneSheet *m_prev;
void AddToList(COneSheet *list);
void RemoveFromList(void);
};
class CRubbish
{
static bool bRubbishInvisible;
static int RubbishVisibility;
static COneSheet aSheets[NUM_RUBBISH_SHEETS];
static COneSheet StartEmptyList;
static COneSheet EndEmptyList;
static COneSheet StartStaticsList;
static COneSheet EndStaticsList;
static COneSheet StartMoversList;
static COneSheet EndMoversList;
public:
static void Render(void);
static void StirUp(CVehicle *veh); // CAutomobile on PS2
static void Update(void);
static void SetVisibility(bool);
static void SetVisibility(bool visible);
static void Init(void);
static void Shutdown(void);
};

View File

@ -175,11 +175,18 @@ public:
static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
};
extern RwTexture *&gpBloodPoolTex;
extern RwTexture *&gpShadowCarTex;
extern RwTexture *&gpShadowPedTex;
extern RwTexture *&gpShadowHeliTex;
extern RwTexture *&gpShadowExplosionTex;
extern RwTexture *&gpShadowHeadLightsTex;
extern RwTexture *&gpGoalTex;
extern RwTexture *&gpOutline1Tex;
extern RwTexture *&gpOutline2Tex;
extern RwTexture *&gpOutline3Tex;
extern RwTexture *&gpBloodPoolTex;
extern RwTexture *&gpReflectionTex;
extern RwTexture *&gpGoalMarkerTex;
extern RwTexture *&gpWalkDontTex;
extern RwTexture *&gpCrackedGlassTex;
extern RwTexture *&gpPostShadowTex;
extern RwTexture *&gpGoalTex;

View File

@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "SpecialFX.h"
#include "RenderBuffer.h"
#include "Timer.h"
#include "Sprite.h"
#include "Font.h"
@ -8,26 +9,260 @@
#include "TxdStore.h"
#include "FileMgr.h"
#include "FileLoader.h"
#include "Timecycle.h"
#include "Lights.h"
#include "ModelIndices.h"
#include "VisibilityPlugins.h"
#include "World.h"
#include "PlayerPed.h"
#include "Particle.h"
#include "Shadows.h"
#include "General.h"
#include "Camera.h"
#include "Shadows.h"
#include "main.h"
WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); }
WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); }
WRAPPER void CSpecialFX::Init(void) { EAXJMP(0x5189E0); }
WRAPPER void CSpecialFX::Shutdown(void) { EAXJMP(0x518BE0); }
RxObjSpace3DVertex StreakVertices[4];
RwImVertexIndex StreakIndexList[12];
WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); }
RxObjSpace3DVertex TraceVertices[6];
RwImVertexIndex TraceIndexList[12];
CBulletTrace (&CBulletTraces::aTraces)[NUMBULLETTRACES] = *(CBulletTrace(*)[NUMBULLETTRACES])*(uintptr*)0x72B1B8;
RxObjSpace3DVertex (&TraceVertices)[6] = *(RxObjSpace3DVertex(*)[6])*(uintptr*)0x649884;
RwImVertexIndex (&TraceIndexList)[12] = *(RwImVertexIndex(*)[12])*(uintptr*)0x64986C;
void
CSpecialFX::Init(void)
{
CBulletTraces::Init();
RwIm3DVertexSetU(&StreakVertices[0], 0.0f);
RwIm3DVertexSetV(&StreakVertices[0], 0.0f);
RwIm3DVertexSetU(&StreakVertices[1], 1.0f);
RwIm3DVertexSetV(&StreakVertices[1], 0.0f);
RwIm3DVertexSetU(&StreakVertices[2], 0.0f);
RwIm3DVertexSetV(&StreakVertices[2], 0.0f);
RwIm3DVertexSetU(&StreakVertices[3], 1.0f);
RwIm3DVertexSetV(&StreakVertices[3], 0.0f);
StreakIndexList[0] = 0;
StreakIndexList[1] = 1;
StreakIndexList[2] = 2;
StreakIndexList[3] = 1;
StreakIndexList[4] = 3;
StreakIndexList[5] = 2;
StreakIndexList[6] = 0;
StreakIndexList[7] = 2;
StreakIndexList[8] = 1;
StreakIndexList[9] = 1;
StreakIndexList[10] = 2;
StreakIndexList[11] = 3;
RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255);
RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255);
RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255);
RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255);
RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255);
RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255);
RwIm3DVertexSetU(&TraceVertices[0], 0.0);
RwIm3DVertexSetV(&TraceVertices[0], 0.0);
RwIm3DVertexSetU(&TraceVertices[1], 1.0);
RwIm3DVertexSetV(&TraceVertices[1], 0.0);
RwIm3DVertexSetU(&TraceVertices[2], 0.0);
RwIm3DVertexSetV(&TraceVertices[2], 0.5);
RwIm3DVertexSetU(&TraceVertices[3], 1.0);
RwIm3DVertexSetV(&TraceVertices[3], 0.5);
RwIm3DVertexSetU(&TraceVertices[4], 0.0);
RwIm3DVertexSetV(&TraceVertices[4], 1.0);
RwIm3DVertexSetU(&TraceVertices[5], 1.0);
RwIm3DVertexSetV(&TraceVertices[5], 1.0);
TraceIndexList[0] = 0;
TraceIndexList[1] = 2;
TraceIndexList[2] = 1;
TraceIndexList[3] = 1;
TraceIndexList[4] = 2;
TraceIndexList[5] = 3;
TraceIndexList[6] = 2;
TraceIndexList[7] = 4;
TraceIndexList[8] = 3;
TraceIndexList[9] = 3;
TraceIndexList[10] = 4;
TraceIndexList[11] = 5;
CMotionBlurStreaks::Init();
CBrightLights::Init();
CShinyTexts::Init();
CMoneyMessages::Init();
C3dMarkers::Init();
}
RwObject*
LookForBatCB(RwObject *object, void *data)
{
static CMatrix MatLTM;
if(CVisibilityPlugins::GetAtomicModelInfo((RpAtomic*)object) == (CSimpleModelInfo*)data){
MatLTM = CMatrix(RwFrameGetLTM(RpAtomicGetFrame((RpAtomic*)object)));
CVector p1 = MatLTM * CVector(0.02f, 0.05f, 0.07f);
CVector p2 = MatLTM * CVector(0.246f, 0.0325f, 0.796f);
CMotionBlurStreaks::RegisterStreak((uintptr)object, 100, 100, 100, p1, p2);
}
return nil;
}
void
CSpecialFX::Update(void)
{
CMotionBlurStreaks::Update();
CBulletTraces::Update();
if(FindPlayerPed() &&
FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING)
RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
}
void
CSpecialFX::Shutdown(void)
{
C3dMarkers::Shutdown();
}
void
CSpecialFX::Render(void)
{
CMotionBlurStreaks::Render();
CBulletTraces::Render();
CBrightLights::Render();
CShinyTexts::Render();
CMoneyMessages::Render();
C3dMarkers::Render();
}
CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS];
void
CRegisteredMotionBlurStreak::Update(void)
{
int i;
bool wasUpdated;
bool lastWasUpdated = false;
for(i = 2; i > 0; i--){
m_pos1[i] = m_pos1[i-1];
m_pos2[i] = m_pos2[i-1];
m_isValid[i] = m_isValid[i-1];
wasUpdated = true;
if(!lastWasUpdated && !m_isValid[i])
wasUpdated = false;
lastWasUpdated = wasUpdated;
}
m_isValid[0] = false;
if(!wasUpdated)
m_id = 0;
}
void
CRegisteredMotionBlurStreak::Render(void)
{
int i;
int a1, a2;
for(i = 0; i < 2; i++)
if(m_isValid[i] && m_isValid[i+1]){
a1 = (255/3)*(3-i)/3;
RwIm3DVertexSetRGBA(&StreakVertices[0], m_red, m_green, m_blue, a1);
RwIm3DVertexSetRGBA(&StreakVertices[1], m_red, m_green, m_blue, a1);
a2 = (255/3)*(3-(i+1))/3;
RwIm3DVertexSetRGBA(&StreakVertices[2], m_red, m_green, m_blue, a2);
RwIm3DVertexSetRGBA(&StreakVertices[3], m_red, m_green, m_blue, a2);
RwIm3DVertexSetPos(&StreakVertices[0], m_pos1[i].x, m_pos1[i].y, m_pos1[i].z);
RwIm3DVertexSetPos(&StreakVertices[1], m_pos2[i].x, m_pos2[i].y, m_pos2[i].z);
RwIm3DVertexSetPos(&StreakVertices[2], m_pos1[i+1].x, m_pos1[i+1].y, m_pos1[i+1].z);
RwIm3DVertexSetPos(&StreakVertices[3], m_pos2[i+1].x, m_pos2[i+1].y, m_pos2[i+1].z);
LittleTest();
if(RwIm3DTransform(StreakVertices, 4, nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, StreakIndexList, 12);
RwIm3DEnd();
}
}
}
void
CMotionBlurStreaks::Init(void)
{
int i;
for(i = 0; i < NUMMBLURSTREAKS; i++)
aStreaks[i].m_id = 0;
}
void
CMotionBlurStreaks::Update(void)
{
int i;
for(i = 0; i < NUMMBLURSTREAKS; i++)
if(aStreaks[i].m_id)
aStreaks[i].Update();
}
void
CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2)
{
int i;
for(i = 0; i < NUMMBLURSTREAKS; i++){
if(aStreaks[i].m_id == id){
// Found a streak from last frame, update
aStreaks[i].m_red = r;
aStreaks[i].m_green = g;
aStreaks[i].m_blue = b;
aStreaks[i].m_pos1[0] = p1;
aStreaks[i].m_pos2[0] = p2;
aStreaks[i].m_isValid[0] = true;
return;
}
}
// Find free slot
for(i = 0; aStreaks[i].m_id; i++)
if(i == NUMMBLURSTREAKS-1)
return;
// Create a new streak
aStreaks[i].m_id = id;
aStreaks[i].m_red = r;
aStreaks[i].m_green = g;
aStreaks[i].m_blue = b;
aStreaks[i].m_pos1[0] = p1;
aStreaks[i].m_pos2[0] = p2;
aStreaks[i].m_isValid[0] = true;
aStreaks[i].m_isValid[1] = false;
aStreaks[i].m_isValid[2] = false;
}
void
CMotionBlurStreaks::Render(void)
{
bool setRenderStates = false;
int i;
for(i = 0; i < NUMMBLURSTREAKS; i++)
if(aStreaks[i].m_id){
if(!setRenderStates){
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
(void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
setRenderStates = true;
}
aStreaks[i].Render();
}
if(setRenderStates){
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
}
}
CBulletTrace CBulletTraces::aTraces[NUMBULLETTRACES];
void CBulletTraces::Init(void)
{
@ -81,8 +316,8 @@ void CBulletTraces::Render(void)
RwIm3DEnd();
}
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6);
}
@ -115,8 +350,6 @@ void CBulletTrace::Update(void)
m_framesInUse++;
}
WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); }
RpAtomic *
MarkerAtomicCB(RpAtomic *atomic, void *data)
{
@ -201,9 +434,9 @@ C3dMarker::Render()
ReSetAmbientAndDirectionalColours();
}
C3dMarker(&C3dMarkers::m_aMarkerArray)[NUM3DMARKERS] = *(C3dMarker(*)[NUM3DMARKERS])*(uintptr*)0x72D408;
int32 &C3dMarkers::NumActiveMarkers = *(int32*)0x8F2A08;
RpClump* (&C3dMarkers::m_pRpClumpArray)[NUMMARKERTYPES] = *(RpClump*(*)[NUMMARKERTYPES])*(uintptr*)0x8E2888;
C3dMarker C3dMarkers::m_aMarkerArray[NUM3DMARKERS];
int32 C3dMarkers::NumActiveMarkers;
RpClump* C3dMarkers::m_pRpClumpArray[NUMMARKERTYPES];
void
C3dMarkers::Init()
@ -402,6 +635,377 @@ C3dMarkers::Update()
{
}
#define BRIGHTLIGHTS_MAX_DIST (60.0f) // invisible beyond this
#define BRIGHTLIGHTS_FADE_DIST (45.0f) // strongest between these two
#define CARLIGHTS_MAX_DIST (30.0f)
#define CARLIGHTS_FADE_DIST (15.0f) // 31 for close lights
int CBrightLights::NumBrightLights;
CBrightLight CBrightLights::aBrightLights[NUMBRIGHTLIGHTS];
void
CBrightLights::Init(void)
{
NumBrightLights = 0;
}
void
CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front,
uint8 type, uint8 red, uint8 green, uint8 blue)
{
if(NumBrightLights >= NUMBRIGHTLIGHTS)
return;
aBrightLights[NumBrightLights].m_camDist = (pos - TheCamera.GetPosition()).Magnitude();
if(aBrightLights[NumBrightLights].m_camDist > BRIGHTLIGHTS_MAX_DIST)
return;
aBrightLights[NumBrightLights].m_pos = pos;
aBrightLights[NumBrightLights].m_up = up;
aBrightLights[NumBrightLights].m_side = side;
aBrightLights[NumBrightLights].m_front = front;
aBrightLights[NumBrightLights].m_type = type;
aBrightLights[NumBrightLights].m_red = red;
aBrightLights[NumBrightLights].m_green = green;
aBrightLights[NumBrightLights].m_blue = blue;
NumBrightLights++;
}
static float TrafficLightsSide[6] = { -0.09f, 0.09f, 0.162f, 0.09f, -0.09f, -0.162f };
static float TrafficLightsUp[6] = { 0.162f, 0.162f, 0.0f, -0.162f, -0.162f, 0.0f };
static float LongCarHeadLightsSide[8] = { -0.2f, 0.2f, -0.2f, 0.2f, -0.2f, 0.2f, -0.2f, 0.2f };
static float LongCarHeadLightsFront[8] = { 0.1f, 0.1f, -0.1f, -0.1f, 0.1f, 0.1f, -0.1f, -0.1f };
static float LongCarHeadLightsUp[8] = { 0.1f, 0.1f, 0.1f, 0.1f, -0.1f, -0.1f, -0.1f, -0.1f };
static float SmallCarHeadLightsSide[8] = { -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f };
static float SmallCarHeadLightsFront[8] = { 0.08f, 0.08f, -0.08f, -0.08f, 0.08f, 0.08f, -0.08f, -0.08f };
static float SmallCarHeadLightsUp[8] = { 0.08f, 0.08f, 0.08f, 0.08f, -0.08f, -0.08f, -0.08f, -0.08f };
static float BigCarHeadLightsSide[8] = { -0.15f, 0.15f, -0.15f, 0.15f, -0.15f, 0.15f, -0.15f, 0.15f };
static float BigCarHeadLightsFront[8] = { 0.15f, 0.15f, -0.15f, -0.15f, 0.15f, 0.15f, -0.15f, -0.15f };
static float BigCarHeadLightsUp[8] = { 0.15f, 0.15f, 0.15f, 0.15f, -0.15f, -0.15f, -0.15f, -0.15f };
static float TallCarHeadLightsSide[8] = { -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f };
static float TallCarHeadLightsFront[8] = { 0.08f, 0.08f, -0.08f, -0.08f, 0.08f, 0.08f, -0.08f, -0.08f };
static float TallCarHeadLightsUp[8] = { 0.2f, 0.2f, 0.2f, 0.2f, -0.2f, -0.2f, -0.2f, -0.2f };
static float SirenLightsSide[6] = { -0.04f, 0.04f, 0.06f, 0.04f, -0.04f, -0.06f };
static float SirenLightsUp[6] = { 0.06f, 0.06f, 0.0f, -0.06f, -0.06f, 0.0f };
static RwImVertexIndex TrafficLightIndices[4*3] = { 0, 1, 5, 1, 2, 3, 1, 3, 4, 1, 4, 5 };
static RwImVertexIndex CubeIndices[12*3] = {
0, 2, 1, 1, 2, 3, 3, 5, 1, 3, 7, 5,
2, 7, 3, 2, 6, 7, 4, 0, 1, 4, 1, 5,
6, 0, 4, 6, 2, 0, 6, 5, 7, 6, 4, 5
};
void
CBrightLights::Render(void)
{
int i, j;
CVector pos;
if(NumBrightLights == 0)
return;
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
for(i = 0; i < NumBrightLights; i++){
if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40)
RenderOutGeometryBuffer();
int r, g, b, a;
float flicker = (CGeneral::GetRandomNumber()&0xFF) * 0.2f;
switch(aBrightLights[i].m_type){
case BRIGHTLIGHT_TRAFFIC_GREEN:
r = flicker; g = 255; b = flicker;
break;
case BRIGHTLIGHT_TRAFFIC_YELLOW:
r = 255; g = 128; b = flicker;
break;
case BRIGHTLIGHT_TRAFFIC_RED:
r = 255; g = flicker; b = flicker;
break;
case BRIGHTLIGHT_FRONT_LONG:
case BRIGHTLIGHT_FRONT_SMALL:
case BRIGHTLIGHT_FRONT_BIG:
case BRIGHTLIGHT_FRONT_TALL:
r = 255; g = 255; b = 255;
break;
case BRIGHTLIGHT_REAR_LONG:
case BRIGHTLIGHT_REAR_SMALL:
case BRIGHTLIGHT_REAR_BIG:
case BRIGHTLIGHT_REAR_TALL:
r = 255; g = flicker; b = flicker;
break;
case BRIGHTLIGHT_SIREN:
r = aBrightLights[i].m_red;
g = aBrightLights[i].m_green;
b = aBrightLights[i].m_blue;
break;
}
if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST)
a = 255;
else
a = 255*(1.0f - (aBrightLights[i].m_camDist-BRIGHTLIGHTS_FADE_DIST)/(BRIGHTLIGHTS_MAX_DIST-BRIGHTLIGHTS_FADE_DIST));
// fade car lights down to 31 as they come near
if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){
if(aBrightLights[i].m_camDist < CARLIGHTS_FADE_DIST)
a = 31;
else if(aBrightLights[i].m_camDist < CARLIGHTS_MAX_DIST)
a = 31 + (255-31)*((aBrightLights[i].m_camDist-CARLIGHTS_FADE_DIST)/(CARLIGHTS_MAX_DIST-CARLIGHTS_FADE_DIST));
}
switch(aBrightLights[i].m_type){
case BRIGHTLIGHT_TRAFFIC_GREEN:
case BRIGHTLIGHT_TRAFFIC_YELLOW:
case BRIGHTLIGHT_TRAFFIC_RED:
for(j = 0; j < 6; j++){
pos = TrafficLightsSide[j]*aBrightLights[i].m_side +
TrafficLightsUp[j]*aBrightLights[i].m_up +
aBrightLights[i].m_pos;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
}
for(j = 0; j < 4*3; j++)
TempBufferRenderIndexList[TempBufferIndicesStored+j] = TrafficLightIndices[j] + TempBufferVerticesStored;
TempBufferVerticesStored += 6;
TempBufferIndicesStored += 4*3;
break;
case BRIGHTLIGHT_FRONT_LONG:
case BRIGHTLIGHT_REAR_LONG:
for(j = 0; j < 8; j++){
pos = LongCarHeadLightsSide[j]*aBrightLights[i].m_side +
LongCarHeadLightsUp[j]*aBrightLights[i].m_up +
LongCarHeadLightsFront[j]*aBrightLights[i].m_front +
aBrightLights[i].m_pos;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
}
for(j = 0; j < 12*3; j++)
TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
TempBufferVerticesStored += 8;
TempBufferIndicesStored += 12*3;
break;
case BRIGHTLIGHT_FRONT_SMALL:
case BRIGHTLIGHT_REAR_SMALL:
for(j = 0; j < 8; j++){
pos = SmallCarHeadLightsSide[j]*aBrightLights[i].m_side +
SmallCarHeadLightsUp[j]*aBrightLights[i].m_up +
SmallCarHeadLightsFront[j]*aBrightLights[i].m_front +
aBrightLights[i].m_pos;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
}
for(j = 0; j < 12*3; j++)
TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
TempBufferVerticesStored += 8;
TempBufferIndicesStored += 12*3;
break;
case BRIGHTLIGHT_FRONT_TALL:
case BRIGHTLIGHT_REAR_TALL:
for(j = 0; j < 8; j++){
pos = TallCarHeadLightsSide[j]*aBrightLights[i].m_side +
TallCarHeadLightsUp[j]*aBrightLights[i].m_up +
TallCarHeadLightsFront[j]*aBrightLights[i].m_front +
aBrightLights[i].m_pos;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
}
for(j = 0; j < 12*3; j++)
TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
TempBufferVerticesStored += 8;
TempBufferIndicesStored += 12*3;
break;
case BRIGHTLIGHT_SIREN:
for(j = 0; j < 6; j++){
pos = SirenLightsSide[j]*aBrightLights[i].m_side +
SirenLightsUp[j]*aBrightLights[i].m_up +
aBrightLights[i].m_pos;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
}
for(j = 0; j < 4*3; j++)
TempBufferRenderIndexList[TempBufferIndicesStored+j] = TrafficLightIndices[j] + TempBufferVerticesStored;
TempBufferVerticesStored += 6;
TempBufferIndicesStored += 4*3;
break;
}
}
RenderOutGeometryBuffer();
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
NumBrightLights = 0;
}
void
CBrightLights::RenderOutGeometryBuffer(void)
{
if(TempBufferIndicesStored != 0){
LittleTest();
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
}
int CShinyTexts::NumShinyTexts;
CShinyText CShinyTexts::aShinyTexts[NUMSHINYTEXTS];
void
CShinyTexts::Init(void)
{
NumShinyTexts = 0;
}
void
CShinyTexts::RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist)
{
if(NumShinyTexts >= NUMSHINYTEXTS)
return;
aShinyTexts[NumShinyTexts].m_camDist = (p0 - TheCamera.GetPosition()).Magnitude();
if(aShinyTexts[NumShinyTexts].m_camDist > maxDist)
return;
aShinyTexts[NumShinyTexts].m_verts[0] = p0;
aShinyTexts[NumShinyTexts].m_verts[1] = p1;
aShinyTexts[NumShinyTexts].m_verts[2] = p2;
aShinyTexts[NumShinyTexts].m_verts[3] = p3;
aShinyTexts[NumShinyTexts].m_texCoords[0].x = u0;
aShinyTexts[NumShinyTexts].m_texCoords[0].y = v0;
aShinyTexts[NumShinyTexts].m_texCoords[1].x = u1;
aShinyTexts[NumShinyTexts].m_texCoords[1].y = v1;
aShinyTexts[NumShinyTexts].m_texCoords[2].x = u2;
aShinyTexts[NumShinyTexts].m_texCoords[2].y = v2;
aShinyTexts[NumShinyTexts].m_texCoords[3].x = u3;
aShinyTexts[NumShinyTexts].m_texCoords[3].y = v3;
aShinyTexts[NumShinyTexts].m_type = type;
aShinyTexts[NumShinyTexts].m_red = red;
aShinyTexts[NumShinyTexts].m_green = green;
aShinyTexts[NumShinyTexts].m_blue = blue;
// Fade out at half the max dist
float halfDist = maxDist*0.5f;
if(aShinyTexts[NumShinyTexts].m_camDist > halfDist){
float f = 1.0f - (aShinyTexts[NumShinyTexts].m_camDist - halfDist)/halfDist;
aShinyTexts[NumShinyTexts].m_red *= f;
aShinyTexts[NumShinyTexts].m_green *= f;
aShinyTexts[NumShinyTexts].m_blue *= f;
}
NumShinyTexts++;
}
void
CShinyTexts::Render(void)
{
int i, ix, v;
RwTexture *lastTex = nil;
if(NumShinyTexts == 0)
return;
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
for(i = 0; i < NumShinyTexts; i++){
if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-64 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-62)
RenderOutGeometryBuffer();
uint8 r = aShinyTexts[i].m_red;
uint8 g = aShinyTexts[i].m_green;
uint8 b = aShinyTexts[i].m_blue;
switch(aShinyTexts[i].m_type){
case SHINYTEXT_WALK:
if(lastTex != gpWalkDontTex){
RenderOutGeometryBuffer();
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpWalkDontTex));
lastTex = gpWalkDontTex;
}
quad:
v = TempBufferVerticesStored;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_verts[0].x, aShinyTexts[i].m_verts[0].y, aShinyTexts[i].m_verts[0].z);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_texCoords[0].x);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_texCoords[0].y);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_verts[1].x, aShinyTexts[i].m_verts[1].y, aShinyTexts[i].m_verts[1].z);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_texCoords[1].x);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_texCoords[1].y);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_verts[2].x, aShinyTexts[i].m_verts[2].y, aShinyTexts[i].m_verts[2].z);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_texCoords[2].x);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_texCoords[2].y);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_verts[3].x, aShinyTexts[i].m_verts[3].y, aShinyTexts[i].m_verts[3].z);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_texCoords[3].x);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_texCoords[3].y);
ix = TempBufferIndicesStored;
TempBufferRenderIndexList[ix+0] = 0 + TempBufferVerticesStored;
TempBufferRenderIndexList[ix+1] = 1 + TempBufferVerticesStored;
TempBufferRenderIndexList[ix+2] = 2 + TempBufferVerticesStored;
TempBufferRenderIndexList[ix+3] = 2 + TempBufferVerticesStored;
TempBufferRenderIndexList[ix+4] = 1 + TempBufferVerticesStored;
TempBufferRenderIndexList[ix+5] = 3 + TempBufferVerticesStored;
TempBufferVerticesStored += 4;
TempBufferIndicesStored += 6;
break;
case SHINYTEXT_FLAT:
if(lastTex != nil){
RenderOutGeometryBuffer();
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
lastTex = nil;
}
goto quad;
}
}
RenderOutGeometryBuffer();
NumShinyTexts = 0;
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
void
CShinyTexts::RenderOutGeometryBuffer(void)
{
if(TempBufferIndicesStored != 0){
LittleTest();
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
}
#define MONEY_MESSAGE_LIFETIME_MS 2000
CMoneyMessage CMoneyMessages::aMoneyMessages[NUMMONEYMESSAGES];
@ -564,6 +1168,16 @@ STARTPATCHES
InjectHook(0x51B400, C3dMarkers::Render, PATCH_JUMP);
InjectHook(0x51B3B0, C3dMarkers::Shutdown, PATCH_JUMP);
InjectHook(0x5197A0, CBrightLights::Init, PATCH_JUMP);
InjectHook(0x51A410, CBrightLights::RegisterOne, PATCH_JUMP);
InjectHook(0x5197B0, CBrightLights::Render, PATCH_JUMP);
InjectHook(0x51A3B0, CBrightLights::RenderOutGeometryBuffer, PATCH_JUMP);
InjectHook(0x51A5A0, CShinyTexts::Init, PATCH_JUMP);
InjectHook(0x51AAB0, CShinyTexts::RegisterOne, PATCH_JUMP);
InjectHook(0x51A5B0, CShinyTexts::Render, PATCH_JUMP);
InjectHook(0x51AA50, CShinyTexts::RenderOutGeometryBuffer, PATCH_JUMP);
InjectHook(0x51AF70, CMoneyMessages::Init, PATCH_JUMP);
InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP);
ENDPATCHES

View File

@ -9,10 +9,29 @@ public:
static void Shutdown(void);
};
class CMotionBlurStreaks
class CRegisteredMotionBlurStreak
{
public:
static void RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2);
uintptr m_id;
uint8 m_red;
uint8 m_green;
uint8 m_blue;
CVector m_pos1[3];
CVector m_pos2[3];
bool m_isValid[3];
void Update(void);
void Render(void);
};
class CMotionBlurStreaks
{
static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS];
public:
static void Init(void);
static void Update(void);
static void RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2);
static void Render(void);
};
struct CBulletTrace
@ -29,7 +48,7 @@ struct CBulletTrace
class CBulletTraces
{
public:
static CBulletTrace (&aTraces)[NUMBULLETTRACES];
static CBulletTrace aTraces[NUMBULLETTRACES];
static void Init(void);
static void AddTrace(CVector*, CVector*);
@ -37,12 +56,6 @@ public:
static void Update(void);
};
class CBrightLights
{
public:
static void RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1 = 0, uint8 unk2 = 0, uint8 unk3 = 0);
};
enum
{
MARKERTYPE_0 = 0,
@ -57,27 +70,27 @@ enum
class C3dMarker
{
public:
CMatrix m_Matrix;
RpAtomic *m_pAtomic;
RpMaterial *m_pMaterial;
uint16 m_nType;
bool m_bIsUsed;
uint32 m_nIdentifier;
RwRGBA m_Color;
uint16 m_nPulsePeriod;
int16 m_nRotateRate;
uint32 m_nStartTime;
float m_fPulseFraction;
float m_fStdSize;
float m_fSize;
float m_fBrightness;
float m_fCameraRange;
bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
void DeleteMarkerObject();
void Render();
{
public:
CMatrix m_Matrix;
RpAtomic *m_pAtomic;
RpMaterial *m_pMaterial;
uint16 m_nType;
bool m_bIsUsed;
uint32 m_nIdentifier;
RwRGBA m_Color;
uint16 m_nPulsePeriod;
int16 m_nRotateRate;
uint32 m_nStartTime;
float m_fPulseFraction;
float m_fStdSize;
float m_fSize;
float m_fBrightness;
float m_fCameraRange;
bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
void DeleteMarkerObject();
void Render();
};
class C3dMarkers
@ -87,42 +100,125 @@ public:
static void Shutdown();
static C3dMarker *PlaceMarker(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void Render();
static void Render();
static void Update();
static C3dMarker(&m_aMarkerArray)[NUM3DMARKERS];
static int32 &NumActiveMarkers;
static RpClump* (&m_pRpClumpArray)[NUMMARKERTYPES];
};
class CMoneyMessage
static C3dMarker m_aMarkerArray[NUM3DMARKERS];
static int32 NumActiveMarkers;
static RpClump* m_pRpClumpArray[NUMMARKERTYPES];
};
enum
{
BRIGHTLIGHT_INVALID,
BRIGHTLIGHT_TRAFFIC_GREEN,
BRIGHTLIGHT_TRAFFIC_YELLOW,
BRIGHTLIGHT_TRAFFIC_RED,
// white
BRIGHTLIGHT_FRONT_LONG,
BRIGHTLIGHT_FRONT_SMALL,
BRIGHTLIGHT_FRONT_BIG,
BRIGHTLIGHT_FRONT_TALL,
// red
BRIGHTLIGHT_REAR_LONG,
BRIGHTLIGHT_REAR_SMALL,
BRIGHTLIGHT_REAR_BIG,
BRIGHTLIGHT_REAR_TALL,
BRIGHTLIGHT_SIREN, // unused
BRIGHTLIGHT_FRONT = BRIGHTLIGHT_FRONT_LONG,
BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG,
};
class CBrightLight
{
friend class CMoneyMessages;
uint32 m_nTimeRegistered;
CVector m_vecPosition;
wchar m_aText[16];
CRGBA m_Colour;
float m_fSize;
float m_fOpacity;
public:
void Render();
};
class CMoneyMessages
{
static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES];
public:
static void Init();
static void Render();
static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
};
class CSpecialParticleStuff
{
static uint32 BoatFromStart;
public:
static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
static void StartBoatFoamAnimation();
static void UpdateBoatFoamAnimation(CMatrix*);
};
CVector m_pos;
CVector m_up;
CVector m_side;
CVector m_front;
float m_camDist;
uint8 m_type;
uint8 m_red;
uint8 m_green;
uint8 m_blue;
};
class CBrightLights
{
static int NumBrightLights;
static CBrightLight aBrightLights[NUMBRIGHTLIGHTS];
public:
static void Init(void);
static void RegisterOne(CVector pos, CVector up, CVector side, CVector front,
uint8 type, uint8 red = 0, uint8 green = 0, uint8 blue = 0);
static void Render(void);
static void RenderOutGeometryBuffer(void);
};
enum
{
SHINYTEXT_WALK = 1,
SHINYTEXT_FLAT
};
class CShinyText
{
public:
CVector m_verts[4];
CVector2D m_texCoords[4];
float m_camDist;
uint8 m_type;
uint8 m_red;
uint8 m_green;
uint8 m_blue;
};
class CShinyTexts
{
static int NumShinyTexts;
static CShinyText aShinyTexts[NUMSHINYTEXTS];
public:
static void Init(void);
static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist);
static void Render(void);
static void RenderOutGeometryBuffer(void);
};
class CMoneyMessage
{
friend class CMoneyMessages;
uint32 m_nTimeRegistered;
CVector m_vecPosition;
wchar m_aText[16];
CRGBA m_Colour;
float m_fSize;
float m_fOpacity;
public:
void Render();
};
class CMoneyMessages
{
static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES];
public:
static void Init();
static void Render();
static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
};
class CSpecialParticleStuff
{
static uint32 BoatFromStart;
public:
static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
static void StartBoatFoamAnimation();
static void UpdateBoatFoamAnimation(CMatrix*);
};

View File

@ -253,7 +253,7 @@ CAutomobile::ProcessControl(void)
ProcessCarAlarm();
// Scan if this car is committing a crime that the police can see
// Scan if this car sees the player committing any crimes
if(m_status != STATUS_ABANDONED && m_status != STATUS_WRECKED &&
m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
@ -1727,9 +1727,9 @@ CAutomobile::PreRender(void)
// bright lights
if(Damage.GetLightStatus(VEHLIGHT_FRONT_LEFT) == LIGHT_STATUS_OK && !bNoBrightHeadLights)
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + 4);
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
if(Damage.GetLightStatus(VEHLIGHT_FRONT_RIGHT) == LIGHT_STATUS_OK && !bNoBrightHeadLights)
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + 4);
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
// Taillights
@ -1798,9 +1798,9 @@ CAutomobile::PreRender(void)
// bright lights
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
// Light shadows
if(!alarmOff){
@ -1873,9 +1873,9 @@ CAutomobile::PreRender(void)
CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 4);
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_FRONT);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 4);
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_FRONT);
}else{
// braking
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
@ -1889,9 +1889,9 @@ CAutomobile::PreRender(void)
CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
}
}else{
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)