mirror of
https://gitlab.com/GaryOderNichts/re3-wiiu.git
synced 2024-12-27 18:21:49 +01:00
Merge pull request #385 from aap/master
implemented CRubbish, CShinyTexts, CBrightLights, CMotionBlurStreaks, CSpecialFX
This commit is contained in:
commit
f89df29001
16
README.md
16
README.md
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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*);
|
||||
};
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user