mirror of
https://github.com/halpz/re3.git
synced 2025-06-26 20:46:21 +00:00
Merge branch 'master' into MoreLanguages
# Conflicts: # src/core/Frontend.cpp # src/render/Font.cpp # src/render/Hud.cpp # src/render/Hud.h # src/text/Messages.cpp # src/text/Text.cpp
This commit is contained in:
@ -87,7 +87,7 @@ CClouds::Render(void)
|
||||
RwV3d pos = { 0.0f, -100.0f, 15.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
|
||||
if(CCoronas::bSmallMoon){
|
||||
szx *= 4.0f;
|
||||
szy *= 4.0f;
|
||||
@ -116,7 +116,7 @@ CClouds::Render(void)
|
||||
static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
|
||||
static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
|
||||
int brightness = (1.0f - coverage) * starintens;
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
for(i = 0; i < 11; i++){
|
||||
RwV3d pos = { 100.0f, 0.0f, 10.0f };
|
||||
if(i >= 9) pos.x = -pos.x;
|
||||
@ -132,7 +132,7 @@ CClouds::Render(void)
|
||||
CSprite::FlushSpriteBuffer();
|
||||
|
||||
// *
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
RwV3d pos = { 100.0f, 0.0f, 10.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
worldpos.y -= 90.0f;
|
||||
@ -156,7 +156,7 @@ CClouds::Render(void)
|
||||
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
|
||||
for(int cloudtype = 0; cloudtype < 3; cloudtype++){
|
||||
for(i = cloudtype; i < 12; i += 3){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype]));
|
||||
RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] };
|
||||
worldpos.x = campos.x + pos.x;
|
||||
worldpos.y = campos.y + pos.y;
|
||||
@ -202,7 +202,7 @@ CClouds::Render(void)
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4]));
|
||||
for(i = 0; i < 37; i++){
|
||||
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
|
||||
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
|
||||
@ -244,7 +244,7 @@ CClouds::Render(void)
|
||||
// Highlights
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3]));
|
||||
|
||||
for(i = 0; i < 37; i++){
|
||||
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
|
||||
@ -269,7 +269,7 @@ CClouds::Render(void)
|
||||
static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
|
||||
static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
|
||||
static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
for(i = 0; i < 6; i++){
|
||||
RwV3d pos = { i*1.5f, 100.0f, 5.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
|
@ -320,7 +320,7 @@ CCoronas::Render(void)
|
||||
|
||||
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
|
||||
spritew * aCoronas[i].size * wscale,
|
||||
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale * hscale),
|
||||
spriteh * aCoronas[i].size * fogscale * hscale,
|
||||
CCoronas::aCoronas[i].red / fogscale,
|
||||
CCoronas::aCoronas[i].green / fogscale,
|
||||
CCoronas::aCoronas[i].blue / fogscale,
|
||||
@ -331,7 +331,7 @@ CCoronas::Render(void)
|
||||
CSprite::RenderOneXLUSprite_Rotate_Aspect(
|
||||
spriteCoors.x, spriteCoors.y, spriteCoors.z,
|
||||
spritew * aCoronas[i].size * fogscale,
|
||||
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale),
|
||||
spriteh * aCoronas[i].size * fogscale,
|
||||
CCoronas::aCoronas[i].red / fogscale,
|
||||
CCoronas::aCoronas[i].green / fogscale,
|
||||
CCoronas::aCoronas[i].blue / fogscale,
|
||||
|
@ -755,14 +755,14 @@ void CTowerClock::Render()
|
||||
&TempV[1],
|
||||
m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
|
||||
m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
|
||||
m_Position.z + Cos(angleMinute) * m_fScale;
|
||||
m_Position.z + Cos(angleMinute) * m_fScale
|
||||
);
|
||||
RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
|
||||
RwIm3DVertexSetPos(
|
||||
&TempV[3],
|
||||
m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
|
||||
m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
|
||||
m_Position.z + Cos(angleHour) * 0.75f * m_fScale;
|
||||
m_Position.z + Cos(angleHour) * 0.75f * m_fScale
|
||||
);
|
||||
|
||||
LittleTest();
|
||||
|
@ -23,55 +23,47 @@
|
||||
|
||||
//wchar *CHud::m_HelpMessage = (wchar*)0x86B888;
|
||||
//wchar *CHud::m_LastHelpMessage = (wchar*)0x6E8F28;
|
||||
wchar CHud::m_HelpMessage[256];
|
||||
wchar CHud::m_LastHelpMessage[256];
|
||||
|
||||
int32 &CHud::m_HelpMessageState = *(int32*)0x880E1C;
|
||||
int32 &CHud::m_HelpMessageTimer = *(int32*)0x880FA4;
|
||||
int32 &CHud::m_HelpMessageFadeTimer = *(int32*)0x8F6258;
|
||||
wchar *CHud::m_HelpMessageToPrint = (wchar*)0x664480;
|
||||
float &CHud::m_HelpMessageDisplayTime = *(float*)0x8E2C28;
|
||||
float &CHud::m_fTextBoxNumLines = *(float*)0x8E2C28;
|
||||
float &CHud::m_fHelpMessageTime = *(float *)0x8E2C28;
|
||||
bool &CHud::m_HelpMessageQuick = *(bool *)0x95CCF7;
|
||||
int32 CHud::m_ZoneState = *(int32*)0x8F29AC;
|
||||
wchar CHud::m_HelpMessageToPrint[256]; // = (wchar*)0x664480;
|
||||
float CHud::m_fHelpMessageTime; // *(float *)0x8E2C28;
|
||||
bool CHud::m_HelpMessageQuick; // = *(bool*)0x95CCF7;
|
||||
uint32 CHud::m_ZoneState; // = *(int32*)0x8F29AC;
|
||||
int32 CHud::m_ZoneFadeTimer;
|
||||
int32 CHud::m_ZoneNameTimer = *(int32*)0x8F1A50;
|
||||
wchar *&CHud::m_pZoneName = *(wchar **)0x8E2C2C;
|
||||
wchar *CHud::m_pLastZoneName = (wchar*)0x8F432C;
|
||||
uint32 CHud::m_ZoneNameTimer; // = *(int32*)0x8F1A50;
|
||||
wchar *CHud::m_pZoneName; // = *(wchar**)0x8E2C2C;
|
||||
wchar *CHud::m_pLastZoneName; // = (wchar*)0x8F432C;
|
||||
wchar *CHud::m_ZoneToPrint;
|
||||
int32 CHud::m_VehicleState = *(int32*)0x940560;
|
||||
uint32 CHud::m_VehicleState; // = *(int32*)0x940560;
|
||||
int32 CHud::m_VehicleFadeTimer;
|
||||
int32 CHud::m_VehicleNameTimer = *(int32*)0x8F2A14;
|
||||
wchar *&CHud::m_VehicleName = *(wchar **)0x942FB4;
|
||||
wchar *CHud::m_pLastVehicleName = *(wchar **)0x8E2DD8;
|
||||
uint32 CHud::m_VehicleNameTimer; // = *(int32*)0x8F2A14;
|
||||
wchar *CHud::m_VehicleName; // = *(wchar**)0x942FB4;
|
||||
wchar *CHud::m_pLastVehicleName; // = *(wchar**)0x8E2DD8;
|
||||
wchar *CHud::m_pVehicleNameToPrint;
|
||||
wchar *CHud::m_Message = (wchar*)0x72E318;
|
||||
wchar *CHud::m_PagerMessage = (wchar*)0x878840;
|
||||
bool &CHud::m_Wants_To_Draw_Hud = *(bool*)0x95CD89;
|
||||
bool &CHud::m_Wants_To_Draw_3dMarkers = *(bool*)0x95CD62;
|
||||
wchar(&CHud::m_BigMessage)[6][128] = *(wchar(*)[6][128])*(uintptr*)0x664CE0;
|
||||
int16 &CHud::m_ItemToFlash = *(int16*)0x95CC82;
|
||||
wchar CHud::m_Message[256];// = (wchar*)0x72E318;
|
||||
wchar CHud::m_PagerMessage[256]; // = (wchar*)0x878840;
|
||||
bool CHud::m_Wants_To_Draw_Hud; // (bool*)0x95CD89;
|
||||
bool CHud::m_Wants_To_Draw_3dMarkers; // = *(bool*)0x95CD62;
|
||||
wchar CHud::m_BigMessage[6][128]; // = *(wchar(*)[6][128]) * (uintptr*)0x664CE0;
|
||||
int16 CHud::m_ItemToFlash; // = *(int16*)0x95CC82;
|
||||
|
||||
// These aren't really in CHud
|
||||
float CHud::BigMessageInUse[6];
|
||||
float CHud::BigMessageAlpha[6];
|
||||
float CHud::BigMessageX[6];
|
||||
float &CHud::OddJob2OffTimer = *(float*)0x942FA0;
|
||||
int8 &CHud::CounterOnLastFrame = *(int8*)0x95CD67;
|
||||
float &CHud::OddJob2XOffset = *(float*)0x8F1B5C;
|
||||
int16 &CHud::CounterFlashTimer = *(int16*)0x95CC20;
|
||||
int16 &CHud::OddJob2Timer = *(int16*)0x95CC52;
|
||||
int8 &CHud::TimerOnLastFrame = *(int8*)0x95CDA7;
|
||||
int16 &CHud::OddJob2On = *(int16*)0x95CC78;
|
||||
int16 &CHud::TimerFlashTimer = *(int16*)0x95CC6C;
|
||||
int16 &CHud::PagerSoundPlayed = *(int16*)0x95CC4A;
|
||||
int32 &CHud::SpriteBrightness = *(int32*)0x95CC54;
|
||||
float &CHud::PagerXOffset = *(float*)0x941590;
|
||||
int16 &CHud::PagerTimer = *(int16*)0x95CC3A;
|
||||
int16 &CHud::PagerOn = *(int16*)0x95CCA0;
|
||||
float CHud::OddJob2OffTimer; // = *(float*)0x942FA0;
|
||||
bool CHud::CounterOnLastFrame; // = *(int8*)0x95CD67;
|
||||
float CHud::OddJob2XOffset; // = *(float*)0x8F1B5C;
|
||||
uint16 CHud::CounterFlashTimer; // = *(int16*)0x95CC20;
|
||||
uint16 CHud::OddJob2Timer; // = *(int16*)0x95CC52;
|
||||
bool CHud::TimerOnLastFrame; //= *(int8*)0x95CDA7;
|
||||
int16 CHud::OddJob2On; //= *(int16*)0x95CC78;
|
||||
uint16 CHud::TimerFlashTimer; //= *(int16*)0x95CC6C;
|
||||
int16 CHud::PagerSoundPlayed; //= *(int16*)0x95CC4A;
|
||||
int32 CHud::SpriteBrightness; //= *(int32*)0x95CC54;
|
||||
float CHud::PagerXOffset; //= *(float*)0x941590;
|
||||
int16 CHud::PagerTimer; //= *(int16*)0x95CC3A;
|
||||
int16 CHud::PagerOn; //= *(int16*)0x95CCA0;
|
||||
|
||||
CSprite2d *CHud::Sprites = (CSprite2d*)0x95CB9C;
|
||||
CSprite2d CHud::Sprites[NUM_HUD_SPRITES]; // = (CSprite2d*)0x95CB9C;
|
||||
|
||||
struct
|
||||
{
|
||||
@ -93,14 +85,14 @@ struct
|
||||
{"detonator", "detonator_mask"},
|
||||
{"", ""},
|
||||
{"", ""},
|
||||
{"radardisc", "radardiscm"},
|
||||
{"radardisc", "radardisc"},
|
||||
{"pager", "pagerm"},
|
||||
{"", ""},
|
||||
{"", ""},
|
||||
{"bleeder", ""},
|
||||
{"sitesniper", "sitesniperm"},
|
||||
{"siteM16", "siteM16m"},
|
||||
{"siterocket", "siterocketm"}
|
||||
{"siterocket", "siterocket"}
|
||||
};
|
||||
|
||||
RwTexture *&gpSniperSightTex = *(RwTexture**)0x8F5834;
|
||||
@ -418,7 +410,7 @@ void CHud::Draw()
|
||||
DrawZoneName
|
||||
*/
|
||||
if (m_pZoneName) {
|
||||
float fZoneAlpha = 0.0f;
|
||||
float fZoneAlpha = 255.0f;
|
||||
|
||||
if (m_pZoneName != m_pLastZoneName) {
|
||||
switch (m_ZoneState) {
|
||||
@ -432,7 +424,7 @@ void CHud::Draw()
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
m_ZoneNameTimer = 0;
|
||||
m_ZoneNameTimer = 5;
|
||||
m_ZoneState = 4;
|
||||
break;
|
||||
default:
|
||||
@ -444,6 +436,7 @@ void CHud::Draw()
|
||||
if (m_ZoneState) {
|
||||
switch (m_ZoneState) {
|
||||
case 1:
|
||||
m_ZoneFadeTimer = 1000;
|
||||
if (m_ZoneNameTimer > 10000) {
|
||||
m_ZoneFadeTimer = 1000;
|
||||
m_ZoneState = 3;
|
||||
@ -471,7 +464,6 @@ void CHud::Draw()
|
||||
if (m_ZoneFadeTimer < 0) {
|
||||
m_ZoneFadeTimer = 0;
|
||||
m_ZoneToPrint = m_pLastZoneName;
|
||||
m_ZoneNameTimer = 0;
|
||||
m_ZoneState = 2;
|
||||
}
|
||||
fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f;
|
||||
@ -503,12 +495,6 @@ void CHud::Draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
/*else {
|
||||
m_pLastZoneName = nil;
|
||||
m_ZoneState = 0;
|
||||
m_ZoneFadeTimer = 0;
|
||||
m_ZoneNameTimer = 0;
|
||||
}*/
|
||||
|
||||
/*
|
||||
DrawVehicleName
|
||||
@ -636,9 +622,9 @@ void CHud::Draw()
|
||||
wchar sTimer[16];
|
||||
|
||||
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed)
|
||||
TimerOnLastFrame = 0;
|
||||
TimerOnLastFrame = false;
|
||||
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed)
|
||||
CounterOnLastFrame = 0;
|
||||
CounterOnLastFrame = false;
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
#define TIMER_RIGHT_OFFSET 34.0f // Taken from VC frenzy timer
|
||||
@ -650,7 +636,7 @@ void CHud::Draw()
|
||||
if (!TimerOnLastFrame)
|
||||
TimerFlashTimer = 1;
|
||||
|
||||
TimerOnLastFrame = 1;
|
||||
TimerOnLastFrame = true;
|
||||
|
||||
if (TimerFlashTimer) {
|
||||
if (++TimerFlashTimer > 50)
|
||||
@ -688,7 +674,7 @@ void CHud::Draw()
|
||||
if (!CounterOnLastFrame)
|
||||
CounterFlashTimer = 1;
|
||||
|
||||
CounterOnLastFrame = 1;
|
||||
CounterOnLastFrame = true;
|
||||
|
||||
if (CounterFlashTimer) {
|
||||
if (++CounterFlashTimer > 50)
|
||||
@ -742,11 +728,9 @@ void CHud::Draw()
|
||||
/*
|
||||
DrawPager
|
||||
*/
|
||||
if (!m_PagerMessage[0]) {
|
||||
if (PagerOn == 1) {
|
||||
PagerSoundPlayed = false;
|
||||
PagerOn = 2;
|
||||
}
|
||||
if (!m_PagerMessage[0] && PagerOn == 1) {
|
||||
PagerSoundPlayed = false;
|
||||
PagerOn = 2;
|
||||
}
|
||||
if (m_PagerMessage[0] || PagerOn == 2) {
|
||||
if (!PagerOn) {
|
||||
@ -755,7 +739,7 @@ void CHud::Draw()
|
||||
}
|
||||
if (PagerOn == 1) {
|
||||
if (PagerXOffset > 0.0f) {
|
||||
float fStep = PagerXOffset * 0.05f;
|
||||
float fStep = PagerXOffset * 0.1f;
|
||||
if (fStep > 10.0f)
|
||||
fStep = 10.0f;
|
||||
PagerXOffset -= fStep * CTimer::GetTimeStep();
|
||||
@ -766,10 +750,10 @@ void CHud::Draw()
|
||||
}
|
||||
}
|
||||
else if (PagerOn == 2) {
|
||||
float fStep = PagerXOffset * 0.05f;
|
||||
float fStep = PagerXOffset * 0.1f;
|
||||
if (fStep < 2.0f)
|
||||
fStep = 2.0f;
|
||||
PagerXOffset += fStep * CTimer::GetTimeStep();
|
||||
PagerXOffset += fStep;
|
||||
if (PagerXOffset > 150.0f) {
|
||||
PagerXOffset = 150.0f;
|
||||
PagerOn = 0;
|
||||
@ -818,9 +802,7 @@ void CHud::Draw()
|
||||
DrawScriptText
|
||||
*/
|
||||
if (!CTimer::GetIsUserPaused()) {
|
||||
CTextLine* IntroText = CTheScripts::IntroTextLines;
|
||||
|
||||
for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
|
||||
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
|
||||
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
|
||||
CFont::SetScale(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fScaleX), SCREEN_SCALE_Y(CTheScripts::IntroTextLines[i].m_fScaleY * 0.5f));
|
||||
CFont::SetColor(CTheScripts::IntroTextLines[i].m_sColor);
|
||||
@ -861,31 +843,31 @@ void CHud::Draw()
|
||||
CFont::SetPropOff();
|
||||
|
||||
CFont::SetFontStyle(FONTJAP(CTheScripts::IntroTextLines[i].m_nFont));
|
||||
CFont::PrintString(SCREEN_SCALE_X(640.0f - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(448.0f - CTheScripts::IntroTextLines[i].m_fAtY), IntroText->m_Text);
|
||||
CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
|
||||
intro_script_rectangle &IntroRect = CTheScripts::IntroRectangles[i];
|
||||
|
||||
CScriptRectangle* IntroRect = CTheScripts::IntroRectangles;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {
|
||||
if (CTheScripts::IntroRectangles[i].m_nTextureId >= 0) {
|
||||
// Yeah, top and bottom changed place. R* vision
|
||||
if (IntroRect.m_bIsUsed && IntroRect.m_bBeforeFade) {
|
||||
if (IntroRect.m_nTextureId >= 0) {
|
||||
CRect rect = {
|
||||
CTheScripts::IntroRectangles[i].m_sRect.left,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.bottom,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.right,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.bottom };
|
||||
IntroRect.m_sRect.left,
|
||||
IntroRect.m_sRect.top,
|
||||
IntroRect.m_sRect.right,
|
||||
IntroRect.m_sRect.bottom };
|
||||
|
||||
CTheScripts::ScriptSprites[CTheScripts::IntroRectangles[i].m_nTextureId].Draw(rect, IntroRect->m_sColor);
|
||||
CTheScripts::ScriptSprites[IntroRect.m_nTextureId].Draw(rect, IntroRect.m_sColor);
|
||||
}
|
||||
else {
|
||||
CRect rect = {
|
||||
CTheScripts::IntroRectangles[i].m_sRect.left,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.bottom,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.right,
|
||||
CTheScripts::IntroRectangles[i].m_sRect.bottom };
|
||||
IntroRect.m_sRect.left,
|
||||
IntroRect.m_sRect.top,
|
||||
IntroRect.m_sRect.right,
|
||||
IntroRect.m_sRect.bottom };
|
||||
|
||||
CSprite2d::DrawRect(rect, IntroRect->m_sColor);
|
||||
CSprite2d::DrawRect(rect, IntroRect.m_sColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -931,7 +913,7 @@ void CHud::Draw()
|
||||
CFont::SetCentreSize(SCREEN_SCALE_X(615.0f));
|
||||
CFont::SetFontStyle(FONT_HEADING);
|
||||
|
||||
if (BigMessageX[0] >= (SCREEN_WIDTH - 20)) {
|
||||
if (BigMessageX[0] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
|
||||
BigMessageInUse[0] += CTimer::GetTimeStep();
|
||||
|
||||
if (BigMessageInUse[0] >= 120.0f) {
|
||||
@ -948,7 +930,7 @@ void CHud::Draw()
|
||||
BigMessageX[0] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
|
||||
BigMessageAlpha[0] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
|
||||
|
||||
if (BigMessageAlpha[0] >= 255.0f)
|
||||
if (BigMessageAlpha[0] > 255.0f)
|
||||
BigMessageAlpha[0] = 255.0f;
|
||||
}
|
||||
|
||||
@ -992,7 +974,7 @@ void CHud::Draw()
|
||||
CFont::SetFontStyle(FONT_HEADING);
|
||||
|
||||
CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[2]));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f + 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]);
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f - 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]);
|
||||
|
||||
CFont::SetColor(CRGBA(170, 123, 87, BigMessageAlpha[2]));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(82.0f), m_BigMessage[2]);
|
||||
@ -1021,7 +1003,7 @@ void CHud::DrawAfterFade()
|
||||
m_HelpMessageState = 2;
|
||||
m_HelpMessageTimer = 0;
|
||||
CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, 256);
|
||||
m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
|
||||
m_fHelpMessageTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
|
||||
|
||||
if (TheCamera.m_ScreenReductionPercentage == 0.0f)
|
||||
DMAudio.PlayFrontEndSound(SOUND_A0, 0);
|
||||
@ -1039,14 +1021,14 @@ void CHud::DrawAfterFade()
|
||||
CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, 256);
|
||||
}
|
||||
|
||||
float fAlpha = 255.0f;
|
||||
float fAlpha = 225.0f;
|
||||
|
||||
if (m_HelpMessageState) {
|
||||
if (m_HelpMessageState != 0) {
|
||||
switch (m_HelpMessageState) {
|
||||
case 1:
|
||||
fAlpha = 255.0f;
|
||||
fAlpha = 225.0f;
|
||||
m_HelpMessageFadeTimer = 600;
|
||||
if (m_HelpMessageTimer > m_fHelpMessageTime * 1000 || m_HelpMessageQuick && m_HelpMessageTimer > 1500) {
|
||||
if (m_HelpMessageTimer > m_fHelpMessageTime * 1000.0f || m_HelpMessageQuick && m_HelpMessageTimer > 1500.0f) {
|
||||
m_HelpMessageFadeTimer = 600;
|
||||
m_HelpMessageState = 3;
|
||||
}
|
||||
@ -1057,24 +1039,24 @@ void CHud::DrawAfterFade()
|
||||
m_HelpMessageState = 1;
|
||||
m_HelpMessageFadeTimer = 0;
|
||||
}
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
|
||||
break;
|
||||
case 3:
|
||||
m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
|
||||
if (m_HelpMessageFadeTimer >= 0) {
|
||||
if (m_HelpMessageFadeTimer < 0) {
|
||||
m_HelpMessageState = 0;
|
||||
m_HelpMessageFadeTimer = 0;
|
||||
}
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
|
||||
break;
|
||||
case 4:
|
||||
m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
|
||||
if (m_HelpMessageFadeTimer >= 0) {
|
||||
if (m_HelpMessageFadeTimer < 0) {
|
||||
m_HelpMessageState = 2;
|
||||
m_HelpMessageFadeTimer = 0;
|
||||
CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, 400);
|
||||
CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, 256);
|
||||
}
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
|
||||
fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1093,6 +1075,7 @@ void CHud::DrawAfterFade()
|
||||
else
|
||||
CFont::SetScale(SCREEN_SCALE_X(0.52f), SCREEN_SCALE_Y(1.1f));
|
||||
|
||||
CFont::SetColor(CRGBA(175, 175, 175, 255));
|
||||
CFont::SetJustifyOff();
|
||||
if (CFont::LanguageSet == FONT_LANGSET_JAPANESE)
|
||||
CFont::SetWrapx(SCREEN_SCALE_X(229.0f + 26.0f - 4.0f));
|
||||
@ -1101,14 +1084,69 @@ void CHud::DrawAfterFade()
|
||||
CFont::SetFontStyle(FONTJAP(FONT_BANK));
|
||||
CFont::SetBackgroundOn();
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.8f));
|
||||
CFont::SetColor(CRGBA(175, 175, 175, 255));
|
||||
CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
|
||||
CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::m_HelpMessageToPrint);
|
||||
CFont::SetAlphaFade(255.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_HelpMessageState = 0;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
|
||||
intro_text_line &line = CTheScripts::IntroTextLines[i];
|
||||
if (line.m_Text[0] != '\0' && !line.m_bTextBeforeFade) {
|
||||
CFont::SetScale(SCREEN_SCALE_X(line.m_fScaleX), SCREEN_SCALE_Y(line.m_fScaleY) / 2);
|
||||
|
||||
CFont::SetColor(line.m_sColor);
|
||||
if (line.m_bJustify)
|
||||
CFont::SetJustifyOn();
|
||||
else
|
||||
CFont::SetJustifyOff();
|
||||
|
||||
if (line.m_bRightJustify)
|
||||
CFont::SetRightJustifyOn();
|
||||
else
|
||||
CFont::SetRightJustifyOff();
|
||||
|
||||
if (line.m_bCentered)
|
||||
CFont::SetCentreOn();
|
||||
else
|
||||
CFont::SetCentreOff();
|
||||
|
||||
CFont::SetWrapx(SCREEN_SCALE_X(line.m_fWrapX));
|
||||
CFont::SetCentreSize(SCREEN_SCALE_X(line.m_fCenterSize));
|
||||
if (line.m_bBackground)
|
||||
CFont::SetBackgroundOn();
|
||||
else
|
||||
CFont::SetBackgroundOff();
|
||||
|
||||
CFont::SetBackgroundColor(line.m_sBackgroundColor);
|
||||
if (line.m_bBackgroundOnly)
|
||||
CFont::SetBackGroundOnlyTextOn();
|
||||
else
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
|
||||
if (line.m_bTextProportional)
|
||||
CFont::SetPropOn();
|
||||
else
|
||||
CFont::SetPropOff();
|
||||
|
||||
CFont::SetFontStyle(line.m_nFont);
|
||||
CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
|
||||
intro_script_rectangle &rectangle = CTheScripts::IntroRectangles[i];
|
||||
if (rectangle.m_bIsUsed && !rectangle.m_bBeforeFade) {
|
||||
|
||||
// Yeah, top and bottom changed place. R* vision
|
||||
if (rectangle.m_nTextureId >= 0) {
|
||||
CTheScripts::ScriptSprites[rectangle.m_nTextureId].Draw(CRect(rectangle.m_sRect.left, rectangle.m_sRect.bottom,
|
||||
rectangle.m_sRect.right, rectangle.m_sRect.top), rectangle.m_sColor);
|
||||
} else {
|
||||
CSprite2d::DrawRect(CRect(rectangle.m_sRect.left, rectangle.m_sRect.bottom,
|
||||
rectangle.m_sRect.right, rectangle.m_sRect.top), rectangle.m_sColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
DrawBigMessage2
|
||||
@ -1150,10 +1188,9 @@ void CHud::DrawAfterFade()
|
||||
if (OddJob2OffTimer > 0)
|
||||
OddJob2OffTimer -= CTimer::GetTimeStepInMilliseconds();
|
||||
|
||||
static float fStep;
|
||||
float fStep;
|
||||
if (m_BigMessage[5][0] && OddJob2OffTimer <= 0.0f) {
|
||||
if (OddJob2On <= 3) {
|
||||
switch (OddJob2On) {
|
||||
switch (OddJob2On) {
|
||||
case 0:
|
||||
OddJob2On = 1;
|
||||
OddJob2XOffset = 380.0f;
|
||||
@ -1164,9 +1201,7 @@ void CHud::DrawAfterFade()
|
||||
OddJob2On = 2;
|
||||
}
|
||||
else {
|
||||
fStep = 40.0f;
|
||||
if ((OddJob2XOffset / 6.0f) <= 40.0f)
|
||||
fStep = OddJob2XOffset / 6.0f;
|
||||
fStep = min(40.0f, OddJob2XOffset / 6.0f);
|
||||
OddJob2XOffset = OddJob2XOffset - fStep;
|
||||
}
|
||||
break;
|
||||
@ -1177,9 +1212,7 @@ void CHud::DrawAfterFade()
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
fStep = 30.0f;
|
||||
if ((OddJob2XOffset / 5.0f) >= 30.0f)
|
||||
fStep = OddJob2XOffset / 5.0f;
|
||||
fStep = max(30.0f, OddJob2XOffset / 5.0f);
|
||||
|
||||
OddJob2XOffset = OddJob2XOffset - fStep;
|
||||
|
||||
@ -1190,7 +1223,6 @@ void CHud::DrawAfterFade()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_BigMessage[1][0]) {
|
||||
@ -1224,10 +1256,10 @@ void CHud::DrawAfterFade()
|
||||
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
|
||||
|
||||
CFont::SetPropOn();
|
||||
CFont::SetRightJustifyWrap(-500.0f);
|
||||
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(-500.0f));
|
||||
CFont::SetRightJustifyOn();
|
||||
CFont::SetFontStyle(FONT_HEADING);
|
||||
if (BigMessageX[1] >= (SCREEN_WIDTH - 20)) {
|
||||
if (BigMessageX[1] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
|
||||
BigMessageInUse[1] += CTimer::GetTimeStep();
|
||||
|
||||
if (BigMessageInUse[1] >= 120.0f) {
|
||||
@ -1238,12 +1270,11 @@ void CHud::DrawAfterFade()
|
||||
m_BigMessage[1][0] = 0;
|
||||
BigMessageAlpha[1] = 0.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
BigMessageX[1] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
|
||||
BigMessageAlpha[1] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
|
||||
|
||||
if (BigMessageAlpha[1] >= 255.0f)
|
||||
if (BigMessageAlpha[1] > 255.0f)
|
||||
BigMessageAlpha[1] = 255.0f;
|
||||
}
|
||||
|
||||
@ -1281,7 +1312,7 @@ void CHud::GetRidOfAllHudMessages()
|
||||
m_HelpMessageFadeTimer = 0;
|
||||
m_HelpMessageState = 0;
|
||||
m_HelpMessageQuick = 0;
|
||||
m_HelpMessageDisplayTime = 1.0f;
|
||||
m_fHelpMessageTime = 1.0f;
|
||||
m_VehicleName = nil;
|
||||
m_pLastVehicleName = nil;
|
||||
m_pVehicleNameToPrint = nil;
|
||||
@ -1311,7 +1342,7 @@ void CHud::Initialise()
|
||||
CTxdStore::PopCurrentTxd();
|
||||
CTxdStore::SetCurrentTxd(HudTXD);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(WeaponFilenames); i++) {
|
||||
for (int i = 0; i < NUM_HUD_SPRITES; i++) {
|
||||
Sprites[i].SetTexture(WeaponFilenames[i].name, WeaponFilenames[i].mask);
|
||||
}
|
||||
|
||||
@ -1322,14 +1353,14 @@ void CHud::Initialise()
|
||||
if (gpRocketSightTex == nil)
|
||||
gpRocketSightTex = RwTextureRead("siterocket", nil);
|
||||
|
||||
CounterOnLastFrame = 0;
|
||||
CounterOnLastFrame = false;
|
||||
m_ItemToFlash = ITEM_NONE;
|
||||
OddJob2Timer = 0;
|
||||
OddJob2OffTimer = 0.0f;
|
||||
OddJob2On = 0;
|
||||
OddJob2XOffset = 0.0f;
|
||||
CounterFlashTimer = 0;
|
||||
TimerOnLastFrame = 0;
|
||||
TimerOnLastFrame = false;
|
||||
TimerFlashTimer = 0;
|
||||
SpriteBrightness = 0;
|
||||
PagerOn = 0;
|
||||
@ -1346,14 +1377,14 @@ void CHud::ReInitialise() {
|
||||
|
||||
GetRidOfAllHudMessages();
|
||||
|
||||
CounterOnLastFrame = 0;
|
||||
CounterOnLastFrame = false;
|
||||
m_ItemToFlash = ITEM_NONE;
|
||||
OddJob2Timer = 0;
|
||||
OddJob2OffTimer = 0.0f;
|
||||
OddJob2On = 0;
|
||||
OddJob2XOffset = 0.0f;
|
||||
CounterFlashTimer = 0;
|
||||
TimerOnLastFrame = 0;
|
||||
TimerOnLastFrame = false;
|
||||
TimerFlashTimer = 0;
|
||||
SpriteBrightness = 0;
|
||||
PagerOn = 0;
|
||||
@ -1443,7 +1474,7 @@ void CHud::SetZoneName(wchar *name)
|
||||
|
||||
void CHud::Shutdown()
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(WeaponFilenames); ++i) {
|
||||
for (int i = 0; i < NUM_HUD_SPRITES; ++i) {
|
||||
Sprites[i].Delete();
|
||||
}
|
||||
|
||||
|
@ -27,59 +27,60 @@ enum eSprites
|
||||
HUD_RADARDISC = 15,
|
||||
HUD_PAGER = 16,
|
||||
HUD_SITESNIPER = 20,
|
||||
HUD_SITEM16 = 21
|
||||
HUD_SITEM16,
|
||||
HUD_SITEROCKET,
|
||||
NUM_HUD_SPRITES,
|
||||
};
|
||||
|
||||
class CHud
|
||||
{
|
||||
public:
|
||||
static CSprite2d *Sprites;
|
||||
static int32 &SpriteBrightness;
|
||||
static CSprite2d Sprites[NUM_HUD_SPRITES];
|
||||
static wchar m_HelpMessage[256];
|
||||
static wchar m_LastHelpMessage[256];
|
||||
static int32 &m_HelpMessageState;
|
||||
static int32 &m_HelpMessageTimer;
|
||||
static int32 &m_HelpMessageFadeTimer;
|
||||
static wchar *m_HelpMessageToPrint;
|
||||
static uint32 m_HelpMessageState;
|
||||
static uint32 m_HelpMessageTimer;
|
||||
static int32 m_HelpMessageFadeTimer;
|
||||
static wchar m_HelpMessageToPrint[256];
|
||||
static float &m_HelpMessageDisplayTime;
|
||||
static float &m_fTextBoxNumLines;
|
||||
static float &m_fHelpMessageTime;
|
||||
static bool &m_HelpMessageQuick;
|
||||
static int32 m_ZoneState;
|
||||
static float m_fHelpMessageTime;
|
||||
static bool m_HelpMessageQuick;
|
||||
static uint32 m_ZoneState;
|
||||
static int32 m_ZoneFadeTimer;
|
||||
static int32 m_ZoneNameTimer;
|
||||
static wchar *&m_pZoneName;
|
||||
static uint32 m_ZoneNameTimer;
|
||||
static wchar *m_pZoneName;
|
||||
static wchar *m_pLastZoneName;
|
||||
static wchar *m_ZoneToPrint;
|
||||
static wchar *&m_VehicleName;
|
||||
static wchar *m_VehicleName;
|
||||
static wchar *m_pLastVehicleName;
|
||||
static wchar *m_pVehicleNameToPrint;
|
||||
static int32 m_VehicleState;
|
||||
static uint32 m_VehicleState;
|
||||
static int32 m_VehicleFadeTimer;
|
||||
static int32 m_VehicleNameTimer;
|
||||
static wchar *m_Message;
|
||||
static wchar *m_PagerMessage;
|
||||
static bool &m_Wants_To_Draw_Hud;
|
||||
static bool &m_Wants_To_Draw_3dMarkers;
|
||||
static wchar(&m_BigMessage)[6][128];
|
||||
static int16 &m_ItemToFlash;
|
||||
static uint32 m_VehicleNameTimer;
|
||||
static wchar m_Message[256];
|
||||
static wchar m_PagerMessage[256];
|
||||
static bool m_Wants_To_Draw_Hud;
|
||||
static bool m_Wants_To_Draw_3dMarkers;
|
||||
static wchar m_BigMessage[6][128];
|
||||
static int16 m_ItemToFlash;
|
||||
|
||||
// These aren't really in CHud
|
||||
static float BigMessageInUse[6];
|
||||
static float BigMessageAlpha[6];
|
||||
static float BigMessageX[6];
|
||||
static float &OddJob2OffTimer;
|
||||
static int8 &CounterOnLastFrame;
|
||||
static float &OddJob2XOffset;
|
||||
static int16 &CounterFlashTimer;
|
||||
static int16 &OddJob2Timer;
|
||||
static int8 &TimerOnLastFrame;
|
||||
static int16 &OddJob2On;
|
||||
static int16 &TimerFlashTimer;
|
||||
static int16 &PagerSoundPlayed;
|
||||
static float &PagerXOffset;
|
||||
static int16 &PagerTimer;
|
||||
static int16 &PagerOn;
|
||||
static float OddJob2OffTimer;
|
||||
static bool CounterOnLastFrame;
|
||||
static float OddJob2XOffset;
|
||||
static uint16 CounterFlashTimer;
|
||||
static uint16 OddJob2Timer;
|
||||
static bool TimerOnLastFrame;
|
||||
static int16 OddJob2On;
|
||||
static uint16 TimerFlashTimer;
|
||||
static int16 PagerSoundPlayed;
|
||||
static int32 SpriteBrightness;
|
||||
static float PagerXOffset;
|
||||
static int16 PagerTimer;
|
||||
static int16 PagerOn;
|
||||
|
||||
public:
|
||||
static void Draw();
|
||||
|
@ -1,333 +0,0 @@
|
||||
#include "common.h"
|
||||
#include <rwcore.h>
|
||||
#include <rpworld.h>
|
||||
#include "patcher.h"
|
||||
#include "Lights.h"
|
||||
#include "Timecycle.h"
|
||||
#include "Coronas.h"
|
||||
#include "Weather.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "Frontend.h"
|
||||
|
||||
RpLight *&pAmbient = *(RpLight**)0x885B6C;
|
||||
RpLight *&pDirect = *(RpLight**)0x880F7C;
|
||||
RpLight **pExtraDirectionals = (RpLight**)0x60009C;
|
||||
int *LightStrengths = (int*)0x87BEF0;
|
||||
int &NumExtraDirLightsInWorld = *(int*)0x64C608;
|
||||
|
||||
RwRGBAReal &AmbientLightColourForFrame = *(RwRGBAReal*)0x6F46F8;
|
||||
RwRGBAReal &AmbientLightColourForFrame_PedsCarsAndObjects = *(RwRGBAReal*)0x6F1D10;
|
||||
RwRGBAReal &DirectionalLightColourForFrame = *(RwRGBAReal*)0x87C6B8;
|
||||
|
||||
RwRGBAReal &AmbientLightColour = *(RwRGBAReal*)0x86B0F8;
|
||||
RwRGBAReal &DirectionalLightColour = *(RwRGBAReal*)0x72E308;
|
||||
|
||||
void
|
||||
SetLightsWithTimeOfDayColour(RpWorld *)
|
||||
{
|
||||
CVector vec1, vec2, vecsun;
|
||||
RwMatrix mat;
|
||||
|
||||
if(pAmbient){
|
||||
AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed() * CCoronas::LightsMult;
|
||||
AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen() * CCoronas::LightsMult;
|
||||
AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult;
|
||||
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
|
||||
AmbientLightColourForFrame.red = 1.0f;
|
||||
AmbientLightColourForFrame.green = 1.0f;
|
||||
AmbientLightColourForFrame.blue = 1.0f;
|
||||
}
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame.red*1.3f);
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame.green*1.3f);
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame.blue*1.3f);
|
||||
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
|
||||
}
|
||||
|
||||
if(pDirect){
|
||||
DirectionalLightColourForFrame.red = CTimeCycle::GetDirectionalRed() * CCoronas::LightsMult;
|
||||
DirectionalLightColourForFrame.green = CTimeCycle::GetDirectionalGreen() * CCoronas::LightsMult;
|
||||
DirectionalLightColourForFrame.blue = CTimeCycle::GetDirectionalBlue() * CCoronas::LightsMult;
|
||||
RpLightSetColor(pDirect, &DirectionalLightColourForFrame);
|
||||
|
||||
vecsun = CTimeCycle::m_VectorToSun[CTimeCycle::m_CurrentStoredValue];
|
||||
vec1 = CVector(0.0f, 0.0f, 1.0f);
|
||||
vec2 = CrossProduct(vec1, vecsun);
|
||||
vec2.Normalise();
|
||||
vec1 = CrossProduct(vec2, vecsun);
|
||||
mat.at.x = -vecsun.x;
|
||||
mat.at.y = -vecsun.y;
|
||||
mat.at.z = -vecsun.z;
|
||||
mat.right.x = vec1.x;
|
||||
mat.right.y = vec1.y;
|
||||
mat.right.z = vec1.z;
|
||||
mat.up.x = vec2.x;
|
||||
mat.up.y = vec2.y;
|
||||
mat.up.z = vec2.z;
|
||||
RwFrameTransform(RpLightGetFrame(pDirect), &mat, rwCOMBINEREPLACE);
|
||||
}
|
||||
|
||||
if(CMenuManager::m_PrefsBrightness > 256){
|
||||
float f1 = 2.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f;
|
||||
float f2 = 3.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f;
|
||||
|
||||
AmbientLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f2);
|
||||
AmbientLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f2);
|
||||
AmbientLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f2);
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.red * f1);
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.green * f1);
|
||||
AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.blue * f1);
|
||||
#ifdef FIX_BUGS
|
||||
DirectionalLightColourForFrame.red = min(1.0f, DirectionalLightColourForFrame.red * f1);
|
||||
DirectionalLightColourForFrame.green = min(1.0f, DirectionalLightColourForFrame.green * f1);
|
||||
DirectionalLightColourForFrame.blue = min(1.0f, DirectionalLightColourForFrame.blue * f1);
|
||||
#else
|
||||
DirectionalLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f1);
|
||||
DirectionalLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f1);
|
||||
DirectionalLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
RpWorld*
|
||||
LightsCreate(RpWorld *world)
|
||||
{
|
||||
int i;
|
||||
RwRGBAReal color;
|
||||
RwFrame *frame;
|
||||
|
||||
if(world == nil)
|
||||
return nil;
|
||||
|
||||
pAmbient = RpLightCreate(rpLIGHTAMBIENT);
|
||||
RpLightSetFlags(pAmbient, rpLIGHTLIGHTATOMICS);
|
||||
color.red = 0.25f;
|
||||
color.green = 0.25f;
|
||||
color.blue = 0.2f;
|
||||
RpLightSetColor(pAmbient, &color);
|
||||
|
||||
pDirect = RpLightCreate(rpLIGHTDIRECTIONAL);
|
||||
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
|
||||
color.red = 1.0f;
|
||||
color.green = 0.84f;
|
||||
color.blue = 0.45f;
|
||||
RpLightSetColor(pDirect, &color);
|
||||
RpLightSetRadius(pDirect, 2.0f);
|
||||
frame = RwFrameCreate();
|
||||
RpLightSetFrame(pDirect, frame);
|
||||
RwV3d axis = { 1.0f, 1.0f, 0.0f };
|
||||
RwFrameRotate(frame, &axis, 160.0f, rwCOMBINEPRECONCAT);
|
||||
|
||||
RpWorldAddLight(world, pAmbient);
|
||||
RpWorldAddLight(world, pDirect);
|
||||
|
||||
for(i = 0; i < NUMEXTRADIRECTIONALS; i++){
|
||||
pExtraDirectionals[i] = RpLightCreate(rpLIGHTDIRECTIONAL);
|
||||
RpLightSetFlags(pExtraDirectionals[i], 0);
|
||||
color.red = 1.0f;
|
||||
color.green = 0.5f;
|
||||
color.blue = 0.0f;
|
||||
RpLightSetColor(pExtraDirectionals[i], &color);
|
||||
RpLightSetRadius(pExtraDirectionals[i], 2.0f);
|
||||
frame = RwFrameCreate();
|
||||
RpLightSetFrame(pExtraDirectionals[i], frame);
|
||||
RpWorldAddLight(world, pExtraDirectionals[i]);
|
||||
}
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
void
|
||||
LightsDestroy(RpWorld *world)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(world == nil)
|
||||
return;
|
||||
|
||||
if(pAmbient){
|
||||
RpWorldRemoveLight(world, pAmbient);
|
||||
RpLightDestroy(pAmbient);
|
||||
pAmbient = nil;
|
||||
}
|
||||
|
||||
if(pDirect){
|
||||
RpWorldRemoveLight(world, pDirect);
|
||||
RwFrameDestroy(RpLightGetFrame(pDirect));
|
||||
RpLightDestroy(pDirect);
|
||||
pDirect = nil;
|
||||
}
|
||||
|
||||
for(i = 0; i < NUMEXTRADIRECTIONALS; i++)
|
||||
if(pExtraDirectionals[i]){
|
||||
RpWorldRemoveLight(world, pExtraDirectionals[i]);
|
||||
RwFrameDestroy(RpLightGetFrame(pExtraDirectionals[i]));
|
||||
RpLightDestroy(pExtraDirectionals[i]);
|
||||
pExtraDirectionals[i] = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorldReplaceNormalLightsWithScorched(RpWorld *world, float l)
|
||||
{
|
||||
RwRGBAReal color;
|
||||
color.red = l;
|
||||
color.green = l;
|
||||
color.blue = l;
|
||||
RpLightSetColor(pAmbient, &color);
|
||||
RpLightSetFlags(pDirect, 0);
|
||||
}
|
||||
|
||||
void
|
||||
WorldReplaceScorchedLightsWithNormal(RpWorld *world)
|
||||
{
|
||||
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
|
||||
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
|
||||
}
|
||||
|
||||
void
|
||||
AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, float red, float green, float blue)
|
||||
{
|
||||
float strength;
|
||||
int weakest;
|
||||
int i, n;
|
||||
RwRGBAReal color;
|
||||
RwV3d *dir;
|
||||
|
||||
strength = max(max(red, green), blue);
|
||||
n = -1;
|
||||
if(NumExtraDirLightsInWorld < NUMEXTRADIRECTIONALS)
|
||||
n = NumExtraDirLightsInWorld;
|
||||
else{
|
||||
weakest = strength;
|
||||
for(i = 0; i < NUMEXTRADIRECTIONALS; i++)
|
||||
if(LightStrengths[i] < weakest){
|
||||
weakest = LightStrengths[i];
|
||||
n = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(n < 0)
|
||||
return;
|
||||
|
||||
color.red = red;
|
||||
color.green = green;
|
||||
color.blue = blue;
|
||||
RpLightSetColor(pExtraDirectionals[n], &color);
|
||||
dir = RwMatrixGetAt(RwFrameGetMatrix(RpLightGetFrame(pExtraDirectionals[n])));
|
||||
dir->x = -dirx;
|
||||
dir->y = -diry;
|
||||
dir->z = -dirz;
|
||||
RwMatrixUpdate(RwFrameGetMatrix(RpLightGetFrame(pExtraDirectionals[n])));
|
||||
RwFrameUpdateObjects(RpLightGetFrame(pExtraDirectionals[n]));
|
||||
RpLightSetFlags(pExtraDirectionals[n], rpLIGHTLIGHTATOMICS);
|
||||
LightStrengths[n] = strength;
|
||||
NumExtraDirLightsInWorld = min(NumExtraDirLightsInWorld+1, NUMEXTRADIRECTIONALS);
|
||||
}
|
||||
|
||||
void
|
||||
RemoveExtraDirectionalLights(RpWorld *world)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NumExtraDirLightsInWorld; i++)
|
||||
RpLightSetFlags(pExtraDirectionals[i], 0);
|
||||
NumExtraDirLightsInWorld = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SetAmbientAndDirectionalColours(float f)
|
||||
{
|
||||
AmbientLightColour.red = AmbientLightColourForFrame.red * f;
|
||||
AmbientLightColour.green = AmbientLightColourForFrame.green * f;
|
||||
AmbientLightColour.blue = AmbientLightColourForFrame.blue * f;
|
||||
|
||||
DirectionalLightColour.red = DirectionalLightColourForFrame.red * f;
|
||||
DirectionalLightColour.green = DirectionalLightColourForFrame.green * f;
|
||||
DirectionalLightColour.blue = DirectionalLightColourForFrame.blue * f;
|
||||
|
||||
RpLightSetColor(pAmbient, &AmbientLightColour);
|
||||
RpLightSetColor(pDirect, &DirectionalLightColour);
|
||||
}
|
||||
|
||||
void
|
||||
SetBrightMarkerColours(float f)
|
||||
{
|
||||
AmbientLightColour.red = 0.6f;
|
||||
AmbientLightColour.green = 0.6f;
|
||||
AmbientLightColour.blue = 0.6f;
|
||||
|
||||
DirectionalLightColour.red = (1.0f - DirectionalLightColourForFrame.red) * 0.4f + DirectionalLightColourForFrame.red;
|
||||
DirectionalLightColour.green = (1.0f - DirectionalLightColourForFrame.green) * 0.4f + DirectionalLightColourForFrame.green;
|
||||
DirectionalLightColour.blue = (1.0f - DirectionalLightColourForFrame.blue) * 0.4f + DirectionalLightColourForFrame.blue;
|
||||
|
||||
RpLightSetColor(pAmbient, &AmbientLightColour);
|
||||
RpLightSetColor(pDirect, &DirectionalLightColour);
|
||||
}
|
||||
|
||||
void
|
||||
ReSetAmbientAndDirectionalColours(void)
|
||||
{
|
||||
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
|
||||
RpLightSetColor(pDirect, &DirectionalLightColourForFrame);
|
||||
}
|
||||
|
||||
void
|
||||
DeActivateDirectional(void)
|
||||
{
|
||||
RpLightSetFlags(pDirect, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ActivateDirectional(void)
|
||||
{
|
||||
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
|
||||
}
|
||||
|
||||
void
|
||||
SetAmbientColours(void)
|
||||
{
|
||||
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
|
||||
}
|
||||
|
||||
void
|
||||
SetAmbientColoursForPedsCarsAndObjects(void)
|
||||
{
|
||||
RpLightSetColor(pAmbient, &AmbientLightColourForFrame_PedsCarsAndObjects);
|
||||
}
|
||||
|
||||
uint8 IndicateR[] = { 0, 255, 0, 0, 255, 255, 0 };
|
||||
uint8 IndicateG[] = { 0, 0, 255, 0, 255, 0, 255 };
|
||||
uint8 IndicateB[] = { 0, 0, 0, 255, 0, 255, 255 };
|
||||
|
||||
void
|
||||
SetAmbientColoursToIndicateRoadGroup(int i)
|
||||
{
|
||||
AmbientLightColour.red = IndicateR[i%7]/255.0f;
|
||||
AmbientLightColour.green = IndicateG[i%7]/255.0f;
|
||||
AmbientLightColour.blue = IndicateB[i%7]/255.0f;
|
||||
RpLightSetColor(pAmbient, &AmbientLightColour);
|
||||
}
|
||||
|
||||
void
|
||||
SetAmbientColours(RwRGBAReal *color)
|
||||
{
|
||||
RpLightSetColor(pAmbient, color);
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x526510, SetLightsWithTimeOfDayColour, PATCH_JUMP);
|
||||
InjectHook(0x5269A0, LightsCreate, PATCH_JUMP);
|
||||
InjectHook(0x526B40, LightsDestroy, PATCH_JUMP);
|
||||
InjectHook(0x526C10, WorldReplaceNormalLightsWithScorched, PATCH_JUMP);
|
||||
InjectHook(0x526C50, WorldReplaceScorchedLightsWithNormal, PATCH_JUMP);
|
||||
InjectHook(0x526C70, AddAnExtraDirectionalLight, PATCH_JUMP);
|
||||
InjectHook(0x526DB0, RemoveExtraDirectionalLights, PATCH_JUMP);
|
||||
InjectHook(0x526DE0, SetAmbientAndDirectionalColours, PATCH_JUMP);
|
||||
InjectHook(0x526E60, SetBrightMarkerColours, PATCH_JUMP);
|
||||
InjectHook(0x526F10, ReSetAmbientAndDirectionalColours, PATCH_JUMP);
|
||||
InjectHook(0x526F40, DeActivateDirectional, PATCH_JUMP);
|
||||
InjectHook(0x526F50, ActivateDirectional, PATCH_JUMP);
|
||||
InjectHook(0x526F60, (void (*)(void))SetAmbientColours, PATCH_JUMP);
|
||||
InjectHook(0x526F80, SetAmbientColoursForPedsCarsAndObjects, PATCH_JUMP);
|
||||
InjectHook(0x526FA0, (void (*)(RwRGBAReal*))SetAmbientColours, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
void SetLightsWithTimeOfDayColour(RpWorld *);
|
||||
RpWorld *LightsCreate(RpWorld *world);
|
||||
void LightsDestroy(RpWorld *world);
|
||||
void WorldReplaceNormalLightsWithScorched(RpWorld *world, float l);
|
||||
void WorldReplaceScorchedLightsWithNormal(RpWorld *world);
|
||||
void AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, float red, float green, float blue);
|
||||
void RemoveExtraDirectionalLights(RpWorld *world);
|
||||
void SetAmbientAndDirectionalColours(float f);
|
||||
void SetBrightMarkerColours(float f);
|
||||
void ReSetAmbientAndDirectionalColours(void);
|
||||
void DeActivateDirectional(void);
|
||||
void ActivateDirectional(void);
|
||||
void SetAmbientColours(void);
|
||||
void SetAmbientColoursForPedsCarsAndObjects(void);
|
||||
void SetAmbientColoursToIndicateRoadGroup(int i);
|
||||
void SetAmbientColours(RwRGBAReal *color);
|
@ -4,12 +4,13 @@
|
||||
#include "Camera.h"
|
||||
#include "MBlur.h"
|
||||
|
||||
// Originally taken from RW example 'mblur'
|
||||
|
||||
RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
|
||||
bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
|
||||
bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
|
||||
|
||||
static RwIm2DVertex Vertex[4];
|
||||
//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
|
||||
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
|
||||
|
||||
void
|
||||
|
174
src/render/PlayerSkin.cpp
Normal file
174
src/render/PlayerSkin.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "TxdStore.h"
|
||||
#include "rtbmp.h"
|
||||
#include "ClumpModelInfo.h"
|
||||
#include "VisibilityPlugins.h"
|
||||
#include "World.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "CdStream.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Directory.h"
|
||||
#include "RwHelper.h"
|
||||
#include "Timer.h"
|
||||
#include "Lights.h"
|
||||
|
||||
RpClump *gpPlayerClump;
|
||||
float gOldFov;
|
||||
|
||||
int CPlayerSkin::m_txdSlot;
|
||||
|
||||
void
|
||||
FindPlayerDff(uint32 &offset, uint32 &size)
|
||||
{
|
||||
int file;
|
||||
CDirectory::DirectoryInfo info;
|
||||
|
||||
file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
|
||||
|
||||
do {
|
||||
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
|
||||
return;
|
||||
} while (strcasecmp("player.dff", info.name) != 0);
|
||||
|
||||
offset = info.offset;
|
||||
size = info.size;
|
||||
}
|
||||
|
||||
void
|
||||
LoadPlayerDff(void)
|
||||
{
|
||||
RwStream *stream;
|
||||
RwMemory mem;
|
||||
uint32 offset, size;
|
||||
uint8 *buffer;
|
||||
bool streamWasAdded = false;
|
||||
|
||||
if (CdStreamGetNumImages() == 0) {
|
||||
CdStreamAddImage("models\\gta3.img");
|
||||
streamWasAdded = true;
|
||||
}
|
||||
|
||||
FindPlayerDff(offset, size);
|
||||
buffer = (uint8*)RwMallocAlign(size << 11, 2048);
|
||||
CdStreamRead(0, buffer, offset, size);
|
||||
CdStreamSync(0);
|
||||
|
||||
mem.start = buffer;
|
||||
mem.length = size << 11;
|
||||
stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
|
||||
|
||||
if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||
gpPlayerClump = RpClumpStreamRead(stream);
|
||||
|
||||
RwStreamClose(stream, &mem);
|
||||
RwFreeAlign(buffer);
|
||||
|
||||
if (streamWasAdded)
|
||||
CdStreamRemoveImages();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Initialise(void)
|
||||
{
|
||||
m_txdSlot = CTxdStore::AddTxdSlot("skin");
|
||||
CTxdStore::Create(m_txdSlot);
|
||||
CTxdStore::AddRef(m_txdSlot);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Shutdown(void)
|
||||
{
|
||||
CTxdStore::RemoveTxdSlot(m_txdSlot);
|
||||
}
|
||||
|
||||
RwTexture *
|
||||
CPlayerSkin::GetSkinTexture(const char *texName)
|
||||
{
|
||||
RwTexture *tex;
|
||||
RwRaster *raster;
|
||||
int32 width, height, depth, format;
|
||||
|
||||
CTxdStore::PushCurrentTxd();
|
||||
CTxdStore::SetCurrentTxd(m_txdSlot);
|
||||
tex = RwTextureRead(texName, NULL);
|
||||
CTxdStore::PopCurrentTxd();
|
||||
if (tex != nil) return tex;
|
||||
|
||||
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
|
||||
sprintf(gString, "models\\generic\\player.bmp");
|
||||
else
|
||||
sprintf(gString, "skins\\%s.bmp", texName);
|
||||
|
||||
if (RwImage *image = RtBMPImageRead(gString)) {
|
||||
RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
|
||||
raster = RwRasterCreate(width, height, depth, format);
|
||||
RwRasterSetFromImage(raster, image);
|
||||
|
||||
tex = RwTextureCreate(raster);
|
||||
RwTextureSetName(tex, texName);
|
||||
#ifdef FIX_BUGS
|
||||
RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
|
||||
#endif
|
||||
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
|
||||
|
||||
RwImageDestroy(image);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::BeginFrontendSkinEdit(void)
|
||||
{
|
||||
LoadPlayerDff();
|
||||
RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
|
||||
CWorld::Players[0].LoadPlayerSkin();
|
||||
gOldFov = CDraw::GetFOV();
|
||||
CDraw::SetFOV(30.0f);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::EndFrontendSkinEdit(void)
|
||||
{
|
||||
RpClumpDestroy(gpPlayerClump);
|
||||
gpPlayerClump = NULL;
|
||||
CDraw::SetFOV(gOldFov);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::RenderFrontendSkinEdit(void)
|
||||
{
|
||||
static float rotation = 0.0f;
|
||||
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
|
||||
const RwV3d pos = { 1.35f, 0.35f, 7.725f };
|
||||
const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
|
||||
const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
|
||||
static uint32 LastFlash = 0;
|
||||
|
||||
RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
|
||||
|
||||
if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
|
||||
rotation += 2.0f;
|
||||
if (rotation > 360.0f)
|
||||
rotation -= 360.0f;
|
||||
LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
|
||||
RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
|
||||
RwFrameUpdateObjects(frame);
|
||||
SetAmbientColours(&AmbientColor);
|
||||
RpClumpRender(gpPlayerClump);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
|
||||
InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
|
||||
ENDPATCHES
|
15
src/render/PlayerSkin.h
Normal file
15
src/render/PlayerSkin.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#define DEFAULT_SKIN_NAME "$$\"\""
|
||||
|
||||
class CPlayerSkin
|
||||
{
|
||||
static int m_txdSlot;
|
||||
public:
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static RwTexture *GetSkinTexture(const char *texName);
|
||||
static void BeginFrontendSkinEdit();
|
||||
static void EndFrontendSkinEdit();
|
||||
static void RenderFrontendSkinEdit();
|
||||
};
|
@ -29,7 +29,7 @@ class CRenderer
|
||||
static CVehicle *&m_pFirstPersonVehicle;
|
||||
|
||||
public:
|
||||
static float &ms_lodDistScale; // defined in Frontend.cpp
|
||||
static float ms_lodDistScale; // defined in Frontend.cpp
|
||||
static bool &m_loadingPriority;
|
||||
|
||||
static void Init(void);
|
||||
|
@ -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,12 +1,247 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "TxdStore.h"
|
||||
#include "Timer.h"
|
||||
#include "Replay.h"
|
||||
#include "Skidmarks.h"
|
||||
|
||||
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
|
||||
WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
|
||||
CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
|
||||
|
||||
WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); }
|
||||
WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); }
|
||||
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
|
||||
RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
|
||||
RwTexture *gpSkidTex;
|
||||
RwTexture *gpSkidBloodTex;
|
||||
RwTexture *gpSkidMudTex;
|
||||
|
||||
WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); }
|
||||
WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); }
|
||||
void
|
||||
CSkidmarks::Init(void)
|
||||
{
|
||||
int i, ix, slot;
|
||||
CTxdStore::PushCurrentTxd();
|
||||
slot = CTxdStore::FindTxdSlot("particle");
|
||||
CTxdStore::SetCurrentTxd(slot);
|
||||
gpSkidTex = RwTextureRead("particleskid", nil);
|
||||
gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
|
||||
gpSkidMudTex = RwTextureRead("particleskidmud", nil);
|
||||
CTxdStore::PopCurrentTxd();
|
||||
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
aSkidmarks[i].m_state = 0;
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
|
||||
ix = 0;
|
||||
for(i = 0; i < SKIDMARK_LENGTH; i++){
|
||||
SkidmarkIndexList[i*6+0] = ix+0;
|
||||
SkidmarkIndexList[i*6+1] = ix+2;
|
||||
SkidmarkIndexList[i*6+2] = ix+1;
|
||||
SkidmarkIndexList[i*6+3] = ix+1;
|
||||
SkidmarkIndexList[i*6+4] = ix+2;
|
||||
SkidmarkIndexList[i*6+5] = ix+3;
|
||||
ix += 2;
|
||||
}
|
||||
|
||||
for(i = 0; i < SKIDMARK_LENGTH; i++){
|
||||
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
|
||||
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
|
||||
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
|
||||
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Shutdown(void)
|
||||
{
|
||||
RwTextureDestroy(gpSkidTex);
|
||||
RwTextureDestroy(gpSkidBloodTex);
|
||||
RwTextureDestroy(gpSkidMudTex);
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Clear(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
aSkidmarks[i].m_state = 0;
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Update(void)
|
||||
{
|
||||
int i;
|
||||
uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500;
|
||||
uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000;
|
||||
uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
switch(aSkidmarks[i].m_state){
|
||||
case 1:
|
||||
if(!aSkidmarks[i].m_wasUpdated){
|
||||
// Didn't continue this one last time, so finish it and set fade times
|
||||
aSkidmarks[i].m_state = 2;
|
||||
if(aSkidmarks[i].m_last < 4){
|
||||
aSkidmarks[i].m_fadeStart = t1;
|
||||
aSkidmarks[i].m_fadeEnd = t2;
|
||||
}else if(aSkidmarks[i].m_last < 9){
|
||||
aSkidmarks[i].m_fadeStart = t2;
|
||||
aSkidmarks[i].m_fadeEnd = t3;
|
||||
}else{
|
||||
aSkidmarks[i].m_fadeStart = t3;
|
||||
aSkidmarks[i].m_fadeEnd = t4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd)
|
||||
aSkidmarks[i].m_state = 0;
|
||||
break;
|
||||
}
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Render(void)
|
||||
{
|
||||
int i, j;
|
||||
RwTexture *lastTex = nil;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
|
||||
continue;
|
||||
|
||||
if(aSkidmarks[i].m_isBloody){
|
||||
if(lastTex != gpSkidBloodTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
|
||||
lastTex = gpSkidBloodTex;
|
||||
}
|
||||
}else if(aSkidmarks[i].m_isMuddy){
|
||||
if(lastTex != gpSkidMudTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
|
||||
lastTex = gpSkidMudTex;
|
||||
}
|
||||
}else{
|
||||
if(lastTex != gpSkidTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
|
||||
lastTex = gpSkidTex;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 fade, alpha;
|
||||
if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
|
||||
fade = 255;
|
||||
else
|
||||
fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart);
|
||||
|
||||
for(j = 0; j <= aSkidmarks[i].m_last; j++){
|
||||
alpha = 128;
|
||||
if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2)
|
||||
alpha = 0;
|
||||
alpha = alpha*fade/256;
|
||||
|
||||
CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
|
||||
CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
|
||||
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
|
||||
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
|
||||
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
|
||||
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
|
||||
}
|
||||
|
||||
LittleTest();
|
||||
if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
}
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
|
||||
{
|
||||
int i;
|
||||
CVector2D fwd(fwdX, fwdY);
|
||||
|
||||
if(CReplay::IsPlayingBack())
|
||||
return;
|
||||
|
||||
// Find a skidmark to continue
|
||||
for(i = 0; i < NUMSKIDMARKS; i++)
|
||||
if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id)
|
||||
break;
|
||||
|
||||
if(i < NUMSKIDMARKS){
|
||||
// Continue this one
|
||||
|
||||
if(aSkidmarks[i].m_isBloody != *isBloody){
|
||||
// Blood-status changed, end this one
|
||||
aSkidmarks[i].m_state = 2;
|
||||
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
return;
|
||||
}
|
||||
|
||||
aSkidmarks[i].m_wasUpdated = true;
|
||||
|
||||
if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){
|
||||
// Last update was recently, just change last coords
|
||||
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
|
||||
return;
|
||||
}
|
||||
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){
|
||||
// No space to continue, end it
|
||||
aSkidmarks[i].m_state = 2;
|
||||
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
*isBloody = false; // stpo blood marks at end
|
||||
return;
|
||||
}
|
||||
aSkidmarks[i].m_last++;
|
||||
|
||||
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
|
||||
|
||||
CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
|
||||
dist.Normalise();
|
||||
CVector2D right(dist.y, -dist.x);
|
||||
float turn = DotProduct2D(fwd, right);
|
||||
turn = Abs(turn) + 1.0f;
|
||||
aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
|
||||
if(aSkidmarks[i].m_last == 1)
|
||||
aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
|
||||
|
||||
if(aSkidmarks[i].m_last > 8)
|
||||
*isBloody = false; // stop blood marks after 8
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a new one
|
||||
for(i = 0; i < NUMSKIDMARKS; i++)
|
||||
if(aSkidmarks[i].m_state == 0)
|
||||
break;
|
||||
if(i < NUMSKIDMARKS){
|
||||
// Found a free slot
|
||||
aSkidmarks[i].m_state = 1;
|
||||
aSkidmarks[i].m_id = id;
|
||||
aSkidmarks[i].m_pos[0] = pos;
|
||||
aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
|
||||
aSkidmarks[i].m_wasUpdated = true;
|
||||
aSkidmarks[i].m_last = 0;
|
||||
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
|
||||
aSkidmarks[i].m_isBloody = *isBloody;
|
||||
aSkidmarks[i].m_isMuddy = *isMuddy;
|
||||
}else
|
||||
*isBloody = false; // stop blood marks if no space
|
||||
}
|
||||
|
@ -1,12 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
enum { SKIDMARK_LENGTH = 16 };
|
||||
|
||||
class CSkidmark
|
||||
{
|
||||
public:
|
||||
uint8 m_state;
|
||||
bool m_wasUpdated;
|
||||
bool m_isBloody;
|
||||
bool m_isMuddy;
|
||||
uintptr m_id;
|
||||
int16 m_last;
|
||||
uint32 m_lastUpdate;;
|
||||
uint32 m_fadeStart;
|
||||
uint32 m_fadeEnd;
|
||||
CVector m_pos[SKIDMARK_LENGTH];
|
||||
CVector m_side[SKIDMARK_LENGTH];
|
||||
};
|
||||
|
||||
class CSkidmarks
|
||||
{
|
||||
static CSkidmark aSkidmarks[NUMSKIDMARKS];
|
||||
public:
|
||||
|
||||
static void Init(void);
|
||||
static void Shutdown(void);
|
||||
static void Clear(void);
|
||||
static void Update(void);
|
||||
static void Render(void);
|
||||
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
|
||||
static void Init(void);
|
||||
static void Shutdown(void);
|
||||
static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
|
||||
};
|
||||
|
@ -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); }
|
||||
RwIm3DVertex StreakVertices[4];
|
||||
RwImVertexIndex StreakIndexList[12];
|
||||
|
||||
WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); }
|
||||
RwIm3DVertex 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)
|
||||
{
|
||||
@ -56,10 +291,10 @@ void CBulletTraces::Render(void)
|
||||
for (int i = 0; i < NUMBULLETTRACES; i++) {
|
||||
if (!aTraces[i].m_bInUse)
|
||||
continue;
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
|
||||
CVector inf = aTraces[i].m_vecCurrentPos;
|
||||
CVector sup = aTraces[i].m_vecTargetPos;
|
||||
CVector center = (inf + sup) / 2;
|
||||
@ -81,9 +316,9 @@ void CBulletTraces::Render(void)
|
||||
RwIm3DEnd();
|
||||
}
|
||||
}
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
}
|
||||
|
||||
void CBulletTraces::Update(void)
|
||||
@ -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)
|
||||
{
|
||||
@ -181,8 +414,7 @@ C3dMarker::Render()
|
||||
{
|
||||
if (m_pAtomic == nil) return;
|
||||
|
||||
RwRGBA *color = RpMaterialGetColor(m_pMaterial);
|
||||
*color = m_Color;
|
||||
RpMaterialSetColor(m_pMaterial, &m_Color);
|
||||
|
||||
m_Matrix.UpdateRW();
|
||||
|
||||
@ -201,9 +433,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 +634,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 +1167,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
|
||||
{
|
||||
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*);
|
||||
};
|
||||
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
|
||||
{
|
||||
public:
|
||||
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*);
|
||||
};
|
||||
|
@ -30,10 +30,12 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
|
||||
out->x *= SCREEN_WIDTH * recip;
|
||||
out->y *= SCREEN_HEIGHT * recip;
|
||||
// What is this? size?
|
||||
*outw = 70.0f/CDraw::GetFOV();
|
||||
*outh = 70.0f/CDraw::GetFOV();
|
||||
*outw *= SCREEN_WIDTH * recip;
|
||||
*outh *= SCREEN_HEIGHT * recip;
|
||||
*outw = 70.0f/CDraw::GetFOV() * SCREEN_WIDTH * recip;
|
||||
#ifdef ASPECT_RATIO_SCALE
|
||||
*outh = 70.0f/CDraw::GetFOV() / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) * SCREEN_HEIGHT * recip;
|
||||
#else
|
||||
*outh = 70.0f/CDraw::GetFOV() * SCREEN_HEIGHT * recip;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -432,6 +434,7 @@ void
|
||||
CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = m_f2DNearScreenZ;
|
||||
recipz = m_fRecipNearClipPlane;
|
||||
@ -496,6 +499,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float
|
||||
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = m_f2DNearScreenZ;
|
||||
recipz = m_fRecipNearClipPlane;
|
||||
|
@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y
|
||||
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
@ -312,10 +313,11 @@ void
|
||||
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
|
||||
{
|
||||
int i;
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
|
||||
for(i = 0; i < n; i++){
|
||||
@ -334,10 +336,11 @@ void
|
||||
CSprite2d::SetMaskVertices(int n, float *positions)
|
||||
{
|
||||
int i;
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
for(i = 0; i < n; i++){
|
||||
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
|
||||
@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions)
|
||||
RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
|
||||
RwIm2DVertexSetCameraZ(&maVertices[i], z);
|
||||
RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
|
||||
RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0);
|
||||
RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,10 +356,11 @@ void
|
||||
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
|
||||
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
RwIm2DVertexSetScreenX(&verts[0], r.left);
|
||||
RwIm2DVertexSetScreenY(&verts[0], r.top);
|
||||
@ -459,15 +463,15 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
|
||||
|
||||
void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color)
|
||||
{
|
||||
SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
|
||||
}
|
||||
|
||||
|
41
src/render/TexList.cpp
Normal file
41
src/render/TexList.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "common.h"
|
||||
#include "TexList.h"
|
||||
#include "rtbmp.h"
|
||||
#include "FileMgr.h"
|
||||
|
||||
bool CTexList::ms_nTexUsed[MAX_TEXUSED];
|
||||
|
||||
void
|
||||
CTexList::Initialise()
|
||||
{}
|
||||
|
||||
void
|
||||
CTexList::Shutdown()
|
||||
{}
|
||||
|
||||
RwTexture *
|
||||
CTexList::SetTexture(int32 slot, char *name)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
int32
|
||||
CTexList::GetFirstFreeTexture()
|
||||
{
|
||||
for (int32 i = 0; i < MAX_TEXUSED; i++)
|
||||
if (!ms_nTexUsed[i])
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
RwTexture *
|
||||
CTexList::LoadFileNameTexture(char *name)
|
||||
{
|
||||
return SetTexture(GetFirstFreeTexture(), name);
|
||||
}
|
||||
|
||||
void
|
||||
CTexList::LoadGlobalTextureList()
|
||||
{
|
||||
CFileMgr::SetDir("TEXTURES");
|
||||
}
|
14
src/render/TexList.h
Normal file
14
src/render/TexList.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
class CTexList
|
||||
{
|
||||
enum { MAX_TEXUSED = 400, };
|
||||
static bool ms_nTexUsed[MAX_TEXUSED];
|
||||
public:
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static RwTexture *SetTexture(int32 slot, char *name);
|
||||
static int32 GetFirstFreeTexture();
|
||||
static RwTexture *LoadFileNameTexture(char *name);
|
||||
static void LoadGlobalTextureList();
|
||||
};
|
@ -119,8 +119,10 @@ public:
|
||||
static int GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
|
||||
static float GetSunSize(void) { return m_fCurrentSunSize; }
|
||||
static float GetSpriteBrightness(void) { return m_fCurrentSpriteBrightness; }
|
||||
static float GetSpriteSize(void) { return m_fCurrentSpriteSize; }
|
||||
static int GetShadowStrength(void) { return m_nCurrentShadowStrength; }
|
||||
static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
|
||||
static int GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; }
|
||||
static float GetFarClip(void) { return m_fCurrentFarClip; }
|
||||
static float GetFogStart(void) { return m_fCurrentFogStart; }
|
||||
|
||||
@ -136,6 +138,7 @@ public:
|
||||
static int GetFogRed(void) { return m_nCurrentFogColourRed; }
|
||||
static int GetFogGreen(void) { return m_nCurrentFogColourGreen; }
|
||||
static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
|
||||
static int GetFogReduction(void) { return m_FogReduction; }
|
||||
|
||||
static void Initialise(void);
|
||||
static void Update(void);
|
||||
|
@ -1,889 +0,0 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "templates.h"
|
||||
#include "Entity.h"
|
||||
#include "ModelInfo.h"
|
||||
#include "Lights.h"
|
||||
#include "Renderer.h"
|
||||
#include "Camera.h"
|
||||
#include "VisibilityPlugins.h"
|
||||
#include "World.h"
|
||||
|
||||
#define FADE_DISTANCE 20.0f
|
||||
|
||||
/*
|
||||
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
|
||||
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
|
||||
|
||||
int32 CVisibilityPlugins::ms_atomicPluginOffset = -1;
|
||||
int32 CVisibilityPlugins::ms_framePluginOffset = -1;
|
||||
int32 CVisibilityPlugins::ms_clumpPluginOffset = -1;
|
||||
*/
|
||||
CLinkList<CVisibilityPlugins::AlphaObjectInfo> &CVisibilityPlugins::m_alphaList = *(CLinkList<CVisibilityPlugins::AlphaObjectInfo>*)0x8F42E4;
|
||||
CLinkList<CVisibilityPlugins::AlphaObjectInfo> &CVisibilityPlugins::m_alphaEntityList = *(CLinkList<CVisibilityPlugins::AlphaObjectInfo>*)0x943084;
|
||||
|
||||
int32 &CVisibilityPlugins::ms_atomicPluginOffset = *(int32*)0x600124;
|
||||
int32 &CVisibilityPlugins::ms_framePluginOffset = *(int32*)0x600128;
|
||||
int32 &CVisibilityPlugins::ms_clumpPluginOffset = *(int32*)0x60012C;
|
||||
|
||||
RwCamera *&CVisibilityPlugins::ms_pCamera = *(RwCamera**)0x8F2514;
|
||||
RwV3d *&CVisibilityPlugins::ms_pCameraPosn = *(RwV3d**)0x8F6270;
|
||||
float &CVisibilityPlugins::ms_cullCompsDist = *(float*)0x8F2BC4;
|
||||
float &CVisibilityPlugins::ms_vehicleLod0Dist = *(float*)0x885B28;
|
||||
float &CVisibilityPlugins::ms_vehicleLod1Dist = *(float*)0x885B30;
|
||||
float &CVisibilityPlugins::ms_vehicleFadeDist = *(float*)0x8E28B4;
|
||||
float &CVisibilityPlugins::ms_bigVehicleLod0Dist = *(float*)0x8E2A84;
|
||||
float &CVisibilityPlugins::ms_bigVehicleLod1Dist = *(float*)0x8E2A8C;
|
||||
float &CVisibilityPlugins::ms_pedLod0Dist = *(float*)0x8F2BD4;
|
||||
float &CVisibilityPlugins::ms_pedLod1Dist = *(float*)0x8F2BD8;
|
||||
float &CVisibilityPlugins::ms_pedFadeDist = *(float*)0x8E2C34;
|
||||
|
||||
void
|
||||
CVisibilityPlugins::Initialise(void)
|
||||
{
|
||||
m_alphaList.Init(20);
|
||||
m_alphaList.head.item.sort = 0.0f;
|
||||
m_alphaList.tail.item.sort = 100000000.0f;
|
||||
m_alphaEntityList.Init(150);
|
||||
m_alphaEntityList.head.item.sort = 0.0f;
|
||||
m_alphaEntityList.tail.item.sort = 100000000.0f;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::Shutdown(void)
|
||||
{
|
||||
m_alphaList.Shutdown();
|
||||
m_alphaEntityList.Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::InitAlphaEntityList(void)
|
||||
{
|
||||
m_alphaEntityList.Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist)
|
||||
{
|
||||
AlphaObjectInfo item;
|
||||
item.entity = e;
|
||||
item.sort = dist;
|
||||
bool ret = !!m_alphaEntityList.InsertSorted(item);
|
||||
// if(!ret)
|
||||
// printf("list full %d\n", m_alphaEntityList.Count());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::InitAlphaAtomicList(void)
|
||||
{
|
||||
m_alphaList.Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist)
|
||||
{
|
||||
AlphaObjectInfo item;
|
||||
item.atomic = a;
|
||||
item.sort = dist;
|
||||
bool ret = !!m_alphaList.InsertSorted(item);
|
||||
// if(!ret)
|
||||
// printf("list full %d\n", m_alphaList.Count());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
|
||||
{
|
||||
ms_pCamera = camera;
|
||||
ms_pCameraPosn = RwMatrixGetPos(RwFrameGetMatrix(RwCameraGetFrame(camera)));
|
||||
|
||||
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
|
||||
TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED)
|
||||
ms_cullCompsDist = 1000000.0f;
|
||||
else
|
||||
ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f);
|
||||
|
||||
ms_vehicleLod0Dist = sq(70.0f * TheCamera.GenerationDistMultiplier);
|
||||
ms_vehicleLod1Dist = sq(90.0f * TheCamera.GenerationDistMultiplier);
|
||||
ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier);
|
||||
ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier);
|
||||
ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier);
|
||||
ms_pedLod0Dist = sq(25.0f * TheCamera.LODDistMultiplier);
|
||||
ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier);
|
||||
ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier);
|
||||
}
|
||||
|
||||
RpMaterial*
|
||||
SetAlphaCB(RpMaterial *material, void *data)
|
||||
{
|
||||
material->color.alpha = (uint8)(uint32)data;
|
||||
return material;
|
||||
}
|
||||
|
||||
RpMaterial*
|
||||
SetTextureCB(RpMaterial *material, void *data)
|
||||
{
|
||||
RpMaterialSetTexture(material, (RwTexture*)data);
|
||||
return material;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::RenderAlphaAtomics(void)
|
||||
{
|
||||
CLink<AlphaObjectInfo> *node;
|
||||
for(node = m_alphaList.tail.prev;
|
||||
node != &m_alphaList.head;
|
||||
node = node->prev)
|
||||
AtomicDefaultRenderCallBack(node->item.atomic);
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::RenderFadingEntities(void)
|
||||
{
|
||||
CLink<AlphaObjectInfo> *node;
|
||||
CSimpleModelInfo *mi;
|
||||
for(node = m_alphaEntityList.tail.prev;
|
||||
node != &m_alphaEntityList.head;
|
||||
node = node->prev){
|
||||
CEntity *e = node->item.entity;
|
||||
if(e->m_rwObject == nil)
|
||||
continue;
|
||||
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(e->m_modelIndex);
|
||||
if(mi->m_noZwrite)
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
|
||||
|
||||
if(e->bDistanceFade){
|
||||
DeActivateDirectional();
|
||||
SetAmbientColours();
|
||||
e->bImBeingRendered = true;
|
||||
RenderFadingAtomic((RpAtomic*)e->m_rwObject, node->item.sort);
|
||||
e->bImBeingRendered = false;
|
||||
}else
|
||||
CRenderer::RenderOneNonRoad(e);
|
||||
|
||||
if(mi->m_noZwrite)
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic)
|
||||
{
|
||||
RpAtomic *lodatm;
|
||||
RwMatrix *m;
|
||||
RwV3d view;
|
||||
float len;
|
||||
CSimpleModelInfo *mi;
|
||||
|
||||
mi = GetAtomicModelInfo(atomic);
|
||||
m = RwFrameGetLTM(RpAtomicGetFrame(atomic));
|
||||
RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn);
|
||||
len = RwV3dLength(&view);
|
||||
lodatm = mi->GetAtomicFromDistance(len);
|
||||
if(lodatm){
|
||||
if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic))
|
||||
RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE);
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderObjNormalAtomic(RpAtomic *atomic)
|
||||
{
|
||||
RwMatrix *m;
|
||||
RwV3d view;
|
||||
float len;
|
||||
|
||||
m = RwFrameGetLTM(RpAtomicGetFrame(atomic));
|
||||
RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn);
|
||||
len = RwV3dLength(&view);
|
||||
if(RwV3dDotProduct(&view, RwMatrixGetUp(m)) < -0.3f*len && len > 8.0f)
|
||||
return atomic;
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha)
|
||||
{
|
||||
RpGeometry *geo;
|
||||
uint32 flags;
|
||||
|
||||
geo = RpAtomicGetGeometry(atomic);
|
||||
flags = RpGeometryGetFlags(geo);
|
||||
RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
|
||||
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
|
||||
RpGeometrySetFlags(geo, flags);
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
|
||||
{
|
||||
RpAtomic *lodatm;
|
||||
float fadefactor;
|
||||
uint8 alpha;
|
||||
CSimpleModelInfo *mi;
|
||||
|
||||
mi = GetAtomicModelInfo(atomic);
|
||||
lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE);
|
||||
if(mi->m_additive){
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
}else{
|
||||
fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE;
|
||||
if(fadefactor > 1.0f)
|
||||
fadefactor = 1.0f;
|
||||
alpha = mi->m_alpha * fadefactor;
|
||||
if(alpha == 255)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
else{
|
||||
RpGeometry *geo = RpAtomicGetGeometry(lodatm);
|
||||
uint32 flags = RpGeometryGetFlags(geo);
|
||||
RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
|
||||
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
|
||||
if(geo != RpAtomicGetGeometry(atomic))
|
||||
RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
|
||||
RpGeometrySetFlags(geo, flags);
|
||||
}
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_vehicleLod0Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
|
||||
return atomic;
|
||||
}
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_vehicleLod0Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
|
||||
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
|
||||
return atomic;
|
||||
|
||||
if(flags & ATOMIC_FLAG_DRAWLAST){
|
||||
// sort before clump
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}else{
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_bigVehicleLod0Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f)
|
||||
return atomic;
|
||||
}
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_bigVehicleLod0Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f)
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
|
||||
return atomic;
|
||||
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_bigVehicleLod1Dist)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq >= ms_bigVehicleLod0Dist &&
|
||||
distsq < ms_bigVehicleLod1Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f)
|
||||
return atomic;
|
||||
}
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq >= ms_bigVehicleLod0Dist &&
|
||||
distsq < ms_bigVehicleLod1Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f)
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
|
||||
return atomic;
|
||||
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
|
||||
{
|
||||
RpClump *clump;
|
||||
float dist;
|
||||
int32 alpha;
|
||||
|
||||
clump = RpAtomicGetClump(atomic);
|
||||
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
|
||||
if(dist >= ms_vehicleLod0Dist){
|
||||
alpha = GetClumpAlpha(clump);
|
||||
if(alpha == 255)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
else
|
||||
RenderAlphaAtomic(atomic, alpha);
|
||||
}
|
||||
return atomic;
|
||||
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq >= ms_bigVehicleLod1Dist)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_bigVehicleLod1Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
|
||||
return atomic;
|
||||
}
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
|
||||
{
|
||||
RwFrame *clumpframe;
|
||||
float distsq, dot;
|
||||
uint32 flags;
|
||||
|
||||
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
|
||||
distsq = GetDistanceSquaredFromCamera(clumpframe);
|
||||
if(distsq < ms_bigVehicleLod1Dist){
|
||||
flags = GetAtomicId(atomic);
|
||||
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
|
||||
RwFrameGetLTM(clumpframe), flags);
|
||||
if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
|
||||
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
|
||||
return atomic;
|
||||
|
||||
if(flags & ATOMIC_FLAG_DRAWLAST){
|
||||
// sort before clump
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}else{
|
||||
if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
}
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
|
||||
{
|
||||
if(CWorld::Players[0].m_pSkinTexture)
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderPedLowDetailCB(RpAtomic *atomic)
|
||||
{
|
||||
RpClump *clump;
|
||||
float dist;
|
||||
int32 alpha;
|
||||
|
||||
clump = RpAtomicGetClump(atomic);
|
||||
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
|
||||
if(dist >= ms_pedLod0Dist){
|
||||
alpha = GetClumpAlpha(clump);
|
||||
if(alpha == 255)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
else
|
||||
RenderAlphaAtomic(atomic, alpha);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
|
||||
{
|
||||
RpClump *clump;
|
||||
float dist;
|
||||
int32 alpha;
|
||||
|
||||
clump = RpAtomicGetClump(atomic);
|
||||
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
|
||||
if(dist < ms_pedLod0Dist){
|
||||
alpha = GetClumpAlpha(clump);
|
||||
if(alpha == 255)
|
||||
AtomicDefaultRenderCallBack(atomic);
|
||||
else
|
||||
RenderAlphaAtomic(atomic, alpha);
|
||||
}
|
||||
return atomic;
|
||||
}
|
||||
|
||||
float
|
||||
CVisibilityPlugins::GetDistanceSquaredFromCamera(RwFrame *frame)
|
||||
{
|
||||
RwMatrix *m;
|
||||
RwV3d dist;
|
||||
m = RwFrameGetLTM(frame);
|
||||
RwV3dSub(&dist, RwMatrixGetPos(m), ms_pCameraPosn);
|
||||
return RwV3dDotProduct(&dist, &dist);
|
||||
}
|
||||
|
||||
float
|
||||
CVisibilityPlugins::GetDotProductWithCameraVector(RwMatrix *atomicMat, RwMatrix *clumpMat, uint32 flags)
|
||||
{
|
||||
RwV3d dist;
|
||||
float dot, dotdoor;
|
||||
|
||||
// Vehicle forward is the y axis (RwMatrix.up)
|
||||
// Vehicle right is the x axis (RwMatrix.right)
|
||||
|
||||
RwV3dSub(&dist, RwMatrixGetPos(atomicMat), ms_pCameraPosn);
|
||||
// forward/backward facing
|
||||
if(flags & (ATOMIC_FLAG_FRONT | ATOMIC_FLAG_REAR))
|
||||
dot = RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat));
|
||||
// left/right facing
|
||||
else if(flags & (ATOMIC_FLAG_LEFT | ATOMIC_FLAG_RIGHT))
|
||||
dot = RwV3dDotProduct(&dist, RwMatrixGetRight(clumpMat));
|
||||
else
|
||||
dot = 0.0f;
|
||||
if(flags & (ATOMIC_FLAG_LEFT | ATOMIC_FLAG_REAR))
|
||||
dot = -dot;
|
||||
|
||||
if(flags & (ATOMIC_FLAG_REARDOOR | ATOMIC_FLAG_FRONTDOOR)){
|
||||
if(flags & ATOMIC_FLAG_REARDOOR)
|
||||
dotdoor = -RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat));
|
||||
else if(flags & ATOMIC_FLAG_FRONTDOOR)
|
||||
dotdoor = RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat));
|
||||
else
|
||||
dotdoor = 0.0f;
|
||||
|
||||
if(dot < 0.0f && dotdoor < 0.0f)
|
||||
dot += dotdoor;
|
||||
if(dot > 0.0f && dotdoor > 0.0f)
|
||||
dot += dotdoor;
|
||||
}
|
||||
|
||||
return dot;
|
||||
}
|
||||
|
||||
/* These are all unused */
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
|
||||
{
|
||||
RwSphere sphere;
|
||||
RwFrame *frame = RpClumpGetFrame(clump);
|
||||
|
||||
CClumpModelInfo *modelInfo = (CClumpModelInfo*)GetFrameHierarchyId(frame);
|
||||
sphere.radius = modelInfo->GetColModel()->boundingSphere.radius;
|
||||
sphere.center.x = modelInfo->GetColModel()->boundingSphere.center.x;
|
||||
sphere.center.y = modelInfo->GetColModel()->boundingSphere.center.y;
|
||||
sphere.center.z = modelInfo->GetColModel()->boundingSphere.center.z;
|
||||
RwV3dTransformPoints(&sphere.center, &sphere.center, 1, RwFrameGetLTM(frame));
|
||||
return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE;
|
||||
}
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump)
|
||||
{
|
||||
if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist)
|
||||
return FrustumSphereCB(clump);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump)
|
||||
{
|
||||
return FrustumSphereCB(clump);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// RW Plugins
|
||||
//
|
||||
|
||||
enum
|
||||
{
|
||||
ID_VISIBILITYATOMIC = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x00),
|
||||
ID_VISIBILITYCLUMP = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x01),
|
||||
ID_VISIBILITYFRAME = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x02),
|
||||
};
|
||||
|
||||
bool
|
||||
CVisibilityPlugins::PluginAttach(void)
|
||||
{
|
||||
ms_atomicPluginOffset = RpAtomicRegisterPlugin(sizeof(AtomicExt),
|
||||
ID_VISIBILITYATOMIC,
|
||||
AtomicConstructor, AtomicDestructor, AtomicCopyConstructor);
|
||||
|
||||
ms_framePluginOffset = RwFrameRegisterPlugin(sizeof(FrameExt),
|
||||
ID_VISIBILITYFRAME,
|
||||
FrameConstructor, FrameDestructor, FrameCopyConstructor);
|
||||
|
||||
ms_clumpPluginOffset = RpClumpRegisterPlugin(sizeof(ClumpExt),
|
||||
ID_VISIBILITYCLUMP,
|
||||
ClumpConstructor, ClumpDestructor, ClumpCopyConstructor);
|
||||
return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1;
|
||||
}
|
||||
|
||||
#define ATOMICEXT(o) (RWPLUGINOFFSET(AtomicExt, o, ms_atomicPluginOffset))
|
||||
#define FRAMEEXT(o) (RWPLUGINOFFSET(FrameExt, o, ms_framePluginOffset))
|
||||
#define CLUMPEXT(o) (RWPLUGINOFFSET(ClumpExt, o, ms_clumpPluginOffset))
|
||||
|
||||
//
|
||||
// Atomic
|
||||
//
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::AtomicConstructor(void *object, int32, int32)
|
||||
{
|
||||
ATOMICEXT(object)->modelInfo = nil;
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::AtomicDestructor(void *object, int32, int32)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::AtomicCopyConstructor(void *dst, const void *src, int32, int32)
|
||||
{
|
||||
*ATOMICEXT(dst) = *ATOMICEXT(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic,
|
||||
CSimpleModelInfo *modelInfo)
|
||||
{
|
||||
AtomicExt *ext = ATOMICEXT(atomic);
|
||||
ext->modelInfo = modelInfo;
|
||||
switch(modelInfo->m_type)
|
||||
case MITYPE_SIMPLE:
|
||||
case MITYPE_TIME:
|
||||
if(modelInfo->m_normalCull)
|
||||
SetAtomicRenderCallback(atomic, RenderObjNormalAtomic);
|
||||
}
|
||||
|
||||
CSimpleModelInfo*
|
||||
CVisibilityPlugins::GetAtomicModelInfo(RpAtomic *atomic)
|
||||
{
|
||||
return ATOMICEXT(atomic)->modelInfo;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetAtomicFlag(RpAtomic *atomic, int f)
|
||||
{
|
||||
ATOMICEXT(atomic)->flags |= f;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::ClearAtomicFlag(RpAtomic *atomic, int f)
|
||||
{
|
||||
ATOMICEXT(atomic)->flags &= ~f;
|
||||
}
|
||||
|
||||
int
|
||||
CVisibilityPlugins::GetAtomicId(RpAtomic *atomic)
|
||||
{
|
||||
return ATOMICEXT(atomic)->flags;
|
||||
}
|
||||
|
||||
// This is rather useless, but whatever
|
||||
void
|
||||
CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb)
|
||||
{
|
||||
if(cb == nil)
|
||||
cb = AtomicDefaultRenderCallBack; // not necessary
|
||||
RpAtomicSetRenderCallBack(atomic, cb);
|
||||
}
|
||||
|
||||
//
|
||||
// Frame
|
||||
//
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::FrameConstructor(void *object, int32, int32)
|
||||
{
|
||||
FRAMEEXT(object)->id = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::FrameDestructor(void *object, int32, int32)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::FrameCopyConstructor(void *dst, const void *src, int32, int32)
|
||||
{
|
||||
*FRAMEEXT(dst) = *FRAMEEXT(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, int32 id)
|
||||
{
|
||||
FRAMEEXT(frame)->id = id;
|
||||
}
|
||||
|
||||
int32
|
||||
CVisibilityPlugins::GetFrameHierarchyId(RwFrame *frame)
|
||||
{
|
||||
return FRAMEEXT(frame)->id;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Clump
|
||||
//
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::ClumpConstructor(void *object, int32, int32)
|
||||
{
|
||||
ClumpExt *ext = CLUMPEXT(object);
|
||||
ext->visibilityCB = DefaultVisibilityCB;
|
||||
ext->alpha = 0xFF;
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::ClumpDestructor(void *object, int32, int32)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
void*
|
||||
CVisibilityPlugins::ClumpCopyConstructor(void *dst, const void *src, int32, int32)
|
||||
{
|
||||
CLUMPEXT(dst)->visibilityCB = CLUMPEXT(src)->visibilityCB;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo)
|
||||
{
|
||||
CVehicleModelInfo *vmi;
|
||||
SetFrameHierarchyId(RpClumpGetFrame(clump), (int32)modelInfo);
|
||||
|
||||
// Unused
|
||||
switch(modelInfo->m_type){
|
||||
// ignore MLO
|
||||
case MITYPE_VEHICLE:
|
||||
vmi = (CVehicleModelInfo*)modelInfo;
|
||||
if(vmi->m_vehicleType == VEHICLE_TYPE_TRAIN ||
|
||||
vmi->m_vehicleType == VEHICLE_TYPE_HELI ||
|
||||
vmi->m_vehicleType == VEHICLE_TYPE_PLANE)
|
||||
CLUMPEXT(clump)->visibilityCB = VehicleVisibilityCB_BigVehicle;
|
||||
else
|
||||
CLUMPEXT(clump)->visibilityCB = VehicleVisibilityCB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CVisibilityPlugins::SetClumpAlpha(RpClump *clump, int alpha)
|
||||
{
|
||||
CLUMPEXT(clump)->alpha = alpha;
|
||||
}
|
||||
|
||||
int
|
||||
CVisibilityPlugins::GetClumpAlpha(RpClump *clump)
|
||||
{
|
||||
return CLUMPEXT(clump)->alpha;
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x527E50, CVisibilityPlugins::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x527EA0, CVisibilityPlugins::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x528F90, CVisibilityPlugins::InitAlphaEntityList, PATCH_JUMP);
|
||||
InjectHook(0x528FF0, CVisibilityPlugins::InsertEntityIntoSortedList, PATCH_JUMP);
|
||||
InjectHook(0x528F80, CVisibilityPlugins::InitAlphaAtomicList, PATCH_JUMP);
|
||||
InjectHook(0x528FA0, CVisibilityPlugins::InsertAtomicIntoSortedList, PATCH_JUMP);
|
||||
InjectHook(0x528C50, CVisibilityPlugins::SetRenderWareCamera, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x527F60, SetAlphaCB, PATCH_JUMP);
|
||||
InjectHook(0x529040, CVisibilityPlugins::RenderAlphaAtomics, PATCH_JUMP);
|
||||
InjectHook(0x529070, CVisibilityPlugins::RenderFadingEntities, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x527F70, CVisibilityPlugins::RenderWheelAtomicCB, PATCH_JUMP);
|
||||
InjectHook(0x528000, CVisibilityPlugins::RenderObjNormalAtomic, PATCH_JUMP);
|
||||
InjectHook(0x5280B0, CVisibilityPlugins::RenderAlphaAtomic, PATCH_JUMP);
|
||||
InjectHook(0x528100, CVisibilityPlugins::RenderFadingAtomic, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x5283E0, CVisibilityPlugins::RenderVehicleHiDetailCB, PATCH_JUMP);
|
||||
InjectHook(0x5284B0, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB, PATCH_JUMP);
|
||||
InjectHook(0x5288A0, CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle, PATCH_JUMP);
|
||||
InjectHook(0x528A10, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle, PATCH_JUMP);
|
||||
InjectHook(0x528AD0, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat, PATCH_JUMP);
|
||||
InjectHook(0x5287F0, CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle, PATCH_JUMP);
|
||||
InjectHook(0x528940, CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle, PATCH_JUMP);
|
||||
InjectHook(0x528240, CVisibilityPlugins::RenderVehicleReallyLowDetailCB, PATCH_JUMP);
|
||||
InjectHook(0x5287B0, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle, PATCH_JUMP);
|
||||
InjectHook(0x5285D0, CVisibilityPlugins::RenderTrainHiDetailCB, PATCH_JUMP);
|
||||
InjectHook(0x5286A0, CVisibilityPlugins::RenderTrainHiDetailAlphaCB, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x528BC0, CVisibilityPlugins::RenderPedHiDetailCB, PATCH_JUMP);
|
||||
InjectHook(0x528B60, CVisibilityPlugins::RenderPedLowDetailCB, PATCH_JUMP);
|
||||
|
||||
|
||||
InjectHook(0x527DC0, CVisibilityPlugins::PluginAttach, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x527EC0, CVisibilityPlugins::SetAtomicModelInfo, PATCH_JUMP);
|
||||
InjectHook(0x527F00, CVisibilityPlugins::GetAtomicModelInfo, PATCH_JUMP);
|
||||
InjectHook(0x527F10, CVisibilityPlugins::SetAtomicFlag, PATCH_JUMP);
|
||||
InjectHook(0x527F30, CVisibilityPlugins::ClearAtomicFlag, PATCH_JUMP);
|
||||
InjectHook(0x527F50, CVisibilityPlugins::GetAtomicId, PATCH_JUMP);
|
||||
InjectHook(0x528C20, CVisibilityPlugins::SetAtomicRenderCallback, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x528D60, CVisibilityPlugins::SetFrameHierarchyId, PATCH_JUMP);
|
||||
InjectHook(0x528D80, CVisibilityPlugins::GetFrameHierarchyId, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x528ED0, CVisibilityPlugins::SetClumpModelInfo, PATCH_JUMP);
|
||||
InjectHook(0x528F50, CVisibilityPlugins::SetClumpAlpha, PATCH_JUMP);
|
||||
InjectHook(0x528F70, CVisibilityPlugins::GetClumpAlpha, PATCH_JUMP);
|
||||
|
||||
|
||||
InjectHook(0x529120, CVisibilityPlugins::GetDistanceSquaredFromCamera, PATCH_JUMP);
|
||||
InjectHook(0x5282A0, CVisibilityPlugins::GetDotProductWithCameraVector, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -1,133 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "templates.h"
|
||||
|
||||
class CEntity;
|
||||
class CSimpleModelInfo;
|
||||
class CClumpModelInfo;
|
||||
|
||||
typedef bool (*ClumpVisibilityCB)(RpClump*);
|
||||
|
||||
class CVisibilityPlugins
|
||||
{
|
||||
public:
|
||||
struct AlphaObjectInfo
|
||||
{
|
||||
union {
|
||||
CEntity *entity;
|
||||
RpAtomic *atomic;
|
||||
};
|
||||
float sort;
|
||||
};
|
||||
|
||||
static CLinkList<AlphaObjectInfo> &m_alphaList;
|
||||
static CLinkList<AlphaObjectInfo> &m_alphaEntityList;
|
||||
static RwCamera *&ms_pCamera;
|
||||
static RwV3d *&ms_pCameraPosn;
|
||||
static float &ms_cullCompsDist;
|
||||
static float &ms_vehicleLod0Dist;
|
||||
static float &ms_vehicleLod1Dist;
|
||||
static float &ms_vehicleFadeDist;
|
||||
static float &ms_bigVehicleLod0Dist;
|
||||
static float &ms_bigVehicleLod1Dist;
|
||||
static float &ms_pedLod0Dist;
|
||||
static float &ms_pedLod1Dist;
|
||||
static float &ms_pedFadeDist;
|
||||
|
||||
static void Initialise(void);
|
||||
static void Shutdown(void);
|
||||
static void InitAlphaEntityList(void);
|
||||
static bool InsertEntityIntoSortedList(CEntity *e, float dist);
|
||||
static void InitAlphaAtomicList(void);
|
||||
static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist);
|
||||
|
||||
static void SetRenderWareCamera(RwCamera *camera);
|
||||
|
||||
static RpAtomic *RenderWheelAtomicCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderObjNormalAtomic(RpAtomic *atomic);
|
||||
static RpAtomic *RenderAlphaAtomic(RpAtomic *atomic, int alpha);
|
||||
static RpAtomic *RenderFadingAtomic(RpAtomic *atm, float dist);
|
||||
|
||||
static RpAtomic *RenderVehicleHiDetailCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleHiDetailAlphaCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic);
|
||||
static RpAtomic *RenderTrainHiDetailCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderTrainHiDetailAlphaCB(RpAtomic *atomic);
|
||||
|
||||
static RpAtomic *RenderPlayerCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderPedLowDetailCB(RpAtomic *atomic);
|
||||
static RpAtomic *RenderPedHiDetailCB(RpAtomic *atomic);
|
||||
|
||||
static void RenderAlphaAtomics(void);
|
||||
static void RenderFadingEntities(void);
|
||||
|
||||
// All actually unused
|
||||
static bool DefaultVisibilityCB(RpClump *clump);
|
||||
static bool FrustumSphereCB(RpClump *clump);
|
||||
// static bool MloVisibilityCB(RpClump *clump);
|
||||
static bool VehicleVisibilityCB(RpClump *clump);
|
||||
static bool VehicleVisibilityCB_BigVehicle(RpClump *clump);
|
||||
|
||||
static float GetDistanceSquaredFromCamera(RwFrame *frame);
|
||||
static float GetDotProductWithCameraVector(RwMatrix *atomicMat, RwMatrix *clumpMat, uint32 flags);
|
||||
|
||||
//
|
||||
// RW Plugins
|
||||
//
|
||||
|
||||
union AtomicExt
|
||||
{
|
||||
CSimpleModelInfo *modelInfo; // used by SimpleModelInfo
|
||||
int flags; // used by ClumpModelInfo
|
||||
};
|
||||
static void SetAtomicModelInfo(RpAtomic*, CSimpleModelInfo*);
|
||||
static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic);
|
||||
static void SetAtomicFlag(RpAtomic*, int);
|
||||
static void ClearAtomicFlag(RpAtomic*, int);
|
||||
static int GetAtomicId(RpAtomic *atomic);
|
||||
static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender);
|
||||
|
||||
static void *AtomicConstructor(void *object, int32 offset, int32 len);
|
||||
static void *AtomicDestructor(void *object, int32 offset, int32 len);
|
||||
static void *AtomicCopyConstructor(void *dst, const void *src,
|
||||
int32 offset, int32 len);
|
||||
static int32 &ms_atomicPluginOffset;
|
||||
|
||||
struct FrameExt
|
||||
{
|
||||
// BUG: this is abused to hold a pointer by SetClumpModelInfo
|
||||
int32 id;
|
||||
};
|
||||
static void SetFrameHierarchyId(RwFrame *frame, int32 id);
|
||||
static int32 GetFrameHierarchyId(RwFrame *frame);
|
||||
|
||||
static void *FrameConstructor(void *object, int32 offset, int32 len);
|
||||
static void *FrameDestructor(void *object, int32 offset, int32 len);
|
||||
static void *FrameCopyConstructor(void *dst, const void *src,
|
||||
int32 offset, int32 len);
|
||||
static int32 &ms_framePluginOffset;
|
||||
|
||||
// Not actually used
|
||||
struct ClumpExt
|
||||
{
|
||||
ClumpVisibilityCB visibilityCB;
|
||||
int alpha;
|
||||
};
|
||||
static void SetClumpModelInfo(RpClump*, CClumpModelInfo*);
|
||||
static void SetClumpAlpha(RpClump*, int);
|
||||
static int GetClumpAlpha(RpClump*);
|
||||
|
||||
static void *ClumpConstructor(void *object, int32 offset, int32 len);
|
||||
static void *ClumpDestructor(void *object, int32 offset, int32 len);
|
||||
static void *ClumpCopyConstructor(void *dst, const void *src,
|
||||
int32 offset, int32 len);
|
||||
static int32 &ms_clumpPluginOffset;
|
||||
|
||||
static bool PluginAttach(void);
|
||||
};
|
@ -2,6 +2,22 @@
|
||||
#include "patcher.h"
|
||||
#include "Weather.h"
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Clock.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "DMAudio.h"
|
||||
#include "General.h"
|
||||
#include "Pad.h"
|
||||
#include "Particle.h"
|
||||
#include "RenderBuffer.h"
|
||||
#include "Stats.h"
|
||||
#include "Shadows.h"
|
||||
#include "Timecycle.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "ZoneCull.h"
|
||||
|
||||
int32 &CWeather::SoundHandle = *(int32*)0x5FFBC4;
|
||||
|
||||
int32 &CWeather::WeatherTypeInList = *(int32*)0x8F626C;
|
||||
@ -32,13 +48,203 @@ int16 &CWeather::Stored_OldWeatherType = *(int16*)0x95CC68;
|
||||
int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE;
|
||||
float &CWeather::Stored_Rain = *(float*)0x885B4C;
|
||||
|
||||
WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); }
|
||||
WRAPPER void CWeather::Update(void) { EAXJMP(0x522C10); }
|
||||
WRAPPER void CWeather::Init(void) { EAXJMP(0x522BA0); }
|
||||
tRainStreak Streaks[NUM_RAIN_STREAKS];
|
||||
|
||||
void CWeather::ReleaseWeather()
|
||||
const int16 WeatherTypesList[] = {
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
|
||||
WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
|
||||
WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_SUNNY,
|
||||
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_RAINY, WEATHER_CLOUDY,
|
||||
};
|
||||
|
||||
const float Windiness[] = {
|
||||
0.0f, // WEATHER_SUNNY
|
||||
0.7f, // WEATHER_CLOUDY
|
||||
1.0f, // WEATHER_RAINY
|
||||
0.5f // WEATHER_FOGGY
|
||||
};
|
||||
|
||||
#define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50)
|
||||
|
||||
#define RAIN_CHANGE_SPEED (0.003f)
|
||||
|
||||
#define DROPLETS_LEFT_OFFSET (10.0f)
|
||||
#define DROPLETS_RIGHT_OFFSET (10.0f)
|
||||
#define DROPLETS_TOP_OFFSET (10.0f)
|
||||
#define DROPLETS_BOTTOM_OFFSET (10.0f)
|
||||
|
||||
#define STREAK_U (10.0f)
|
||||
#define STREAK_V (18.0f)
|
||||
#define LARGE_STREAK_COEFFICIENT (1.23f)
|
||||
#define STREAK_MIN_DISTANCE (8.0f)
|
||||
#define STREAK_MAX_DISTANCE (16.0f)
|
||||
|
||||
#define SPLASH_CHECK_RADIUS (7.0f)
|
||||
#define SPLASH_OFFSET_RADIUS (2.0f)
|
||||
|
||||
#define STREAK_LIFETIME (4.0f)
|
||||
#define STREAK_INTEROLATION_TIME (0.3f)
|
||||
|
||||
#define RAIN_COLOUR_R (200)
|
||||
#define RAIN_COLOUR_G (200)
|
||||
#define RAIN_COLOUR_B (256)
|
||||
#define RAIN_ALPHA (255)
|
||||
|
||||
void CWeather::Init(void)
|
||||
{
|
||||
ForcedWeatherType = -1;
|
||||
NewWeatherType = WEATHER_SUNNY;
|
||||
bScriptsForceRain = false;
|
||||
OldWeatherType = WEATHER_CLOUDY;
|
||||
Stored_StateStored = false;
|
||||
InterpolationValue = 0.0f;
|
||||
WhenToPlayLightningSound = 0;
|
||||
WeatherTypeInList = 0;
|
||||
ForcedWeatherType = WEATHER_RANDOM;
|
||||
SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1);
|
||||
if (SoundHandle >= 0)
|
||||
DMAudio.SetEntityStatus(SoundHandle, 1);
|
||||
}
|
||||
|
||||
void CWeather::Update(void)
|
||||
{
|
||||
float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60;
|
||||
if (fNewInterpolation < InterpolationValue) {
|
||||
// new hour
|
||||
OldWeatherType = NewWeatherType;
|
||||
if (ForcedWeatherType >= 0)
|
||||
NewWeatherType = ForcedWeatherType;
|
||||
else {
|
||||
WeatherTypeInList = (WeatherTypeInList + 1) % ARRAYSIZE(WeatherTypesList);
|
||||
NewWeatherType = WeatherTypesList[WeatherTypeInList];
|
||||
#ifdef FIX_BUGS
|
||||
}
|
||||
if (NewWeatherType == WEATHER_RAINY)
|
||||
CStats::mmRain += CGeneral::GetRandomNumber() & 7;
|
||||
#else
|
||||
if (NewWeatherType == WEATHER_RAINY)
|
||||
CStats::mmRain += CGeneral::GetRandomNumber() & 7;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
InterpolationValue = fNewInterpolation;
|
||||
if (CPad::GetPad(1)->GetRightShockJustDown()) {
|
||||
NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL;
|
||||
OldWeatherType = NewWeatherType;
|
||||
}
|
||||
|
||||
// Lightning
|
||||
if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) {
|
||||
LightningFlash = false;
|
||||
LightningBurst = false;
|
||||
}
|
||||
else{
|
||||
if (LightningBurst) {
|
||||
if ((CGeneral::GetRandomNumber() & 255) >= 32) {
|
||||
// 0.875 probability
|
||||
if (CTimer::GetTimeInMilliseconds() - LightningFlashLastChange > MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES) {
|
||||
bool bOldLightningFlash = LightningFlash;
|
||||
LightningFlash = CGeneral::GetRandomTrueFalse();
|
||||
if (LightningFlash != bOldLightningFlash)
|
||||
LightningFlashLastChange = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 0.125 probability
|
||||
LightningBurst = false;
|
||||
LightningDuration = min(CTimer::GetFrameCounter() - LightningStart, 20);
|
||||
LightningFlash = false;
|
||||
WhenToPlayLightningSound = CTimer::GetTimeInMilliseconds() + 150 * (20 - LightningDuration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (CGeneral::GetRandomNumber() >= 200) {
|
||||
// lower probability on PC due to randomness bug
|
||||
LightningFlash = false;
|
||||
}
|
||||
else {
|
||||
LightningBurst = true;
|
||||
LightningStart = CTimer::GetFrameCounter();
|
||||
LightningFlashLastChange = CTimer::GetTimeInMilliseconds();
|
||||
LightningFlash = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WhenToPlayLightningSound && CTimer::GetTimeInMilliseconds() > WhenToPlayLightningSound) {
|
||||
DMAudio.PlayOneShot(SoundHandle, SOUND_LIGHTNING, LightningDuration);
|
||||
CPad::GetPad(0)->StartShake(40 * LightningDuration + 100, 2 * LightningDuration + 80);
|
||||
WhenToPlayLightningSound = 0;
|
||||
}
|
||||
|
||||
// Wet roads
|
||||
if (OldWeatherType == WEATHER_RAINY) {
|
||||
if (NewWeatherType == WEATHER_RAINY)
|
||||
WetRoads = 1.0f;
|
||||
else
|
||||
WetRoads = 1.0f - InterpolationValue;
|
||||
}
|
||||
else {
|
||||
if (NewWeatherType == WEATHER_RAINY)
|
||||
WetRoads = InterpolationValue;
|
||||
else
|
||||
WetRoads = 0.0f;
|
||||
}
|
||||
|
||||
// Rain
|
||||
float fNewRain;
|
||||
if (NewWeatherType == WEATHER_RAINY) {
|
||||
// if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s
|
||||
fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f;
|
||||
if (OldWeatherType != WEATHER_RAINY) {
|
||||
if (InterpolationValue < 0.4f)
|
||||
// if rain has just started (<24 minutes), always 0.5
|
||||
fNewRain = 0.5f;
|
||||
else
|
||||
// if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s
|
||||
fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f;
|
||||
}
|
||||
}
|
||||
else
|
||||
fNewRain = 0.0f;
|
||||
if (Rain != fNewRain) { // ok to use comparasion
|
||||
if (Rain < fNewRain)
|
||||
Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
|
||||
else
|
||||
Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
|
||||
}
|
||||
|
||||
// Clouds
|
||||
if (OldWeatherType != WEATHER_SUNNY)
|
||||
CloudCoverage = 1.0f - InterpolationValue;
|
||||
else
|
||||
CloudCoverage = 0.0f;
|
||||
if (NewWeatherType != WEATHER_SUNNY)
|
||||
CloudCoverage += InterpolationValue;
|
||||
|
||||
// Fog
|
||||
if (OldWeatherType == WEATHER_FOGGY)
|
||||
Foggyness = 1.0f - InterpolationValue;
|
||||
else
|
||||
Foggyness = 0.0f;
|
||||
if (NewWeatherType == WEATHER_FOGGY)
|
||||
Foggyness += InterpolationValue;
|
||||
if (OldWeatherType == WEATHER_RAINY && NewWeatherType == WEATHER_SUNNY && InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21)
|
||||
Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f;
|
||||
else
|
||||
Rainbow = 0.0f;
|
||||
Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType];
|
||||
AddRain();
|
||||
}
|
||||
|
||||
void CWeather::ForceWeather(int16 weather)
|
||||
@ -53,6 +259,258 @@ void CWeather::ForceWeatherNow(int16 weather)
|
||||
ForcedWeatherType = weather;
|
||||
}
|
||||
|
||||
void CWeather::ReleaseWeather()
|
||||
{
|
||||
ForcedWeatherType = -1;
|
||||
}
|
||||
|
||||
void CWeather::AddRain()
|
||||
{
|
||||
if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
|
||||
return;
|
||||
if (TheCamera.GetLookingLRBFirstPerson()) {
|
||||
CVehicle* pVehicle = FindPlayerVehicle();
|
||||
if (pVehicle && pVehicle->CarHasRoof()) {
|
||||
CParticle::RemovePSystem(PARTICLE_RAINDROP_2D);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Rain <= 0.1f)
|
||||
return;
|
||||
static RwRGBA colour;
|
||||
float screen_width = RsGlobal.width;
|
||||
float screen_height = RsGlobal.height;
|
||||
int cur_frame = (int)(3 * Rain) & 3;
|
||||
int num_drops = (int)(2 * Rain) + 2;
|
||||
static int STATIC_RAIN_ANGLE = -45;
|
||||
static int count = 1500;
|
||||
static int add_angle = 1;
|
||||
if (--count == 0) {
|
||||
count = 1;
|
||||
if (add_angle) {
|
||||
STATIC_RAIN_ANGLE += 12;
|
||||
if (STATIC_RAIN_ANGLE > 45) {
|
||||
count = 1500;
|
||||
add_angle = !add_angle;
|
||||
}
|
||||
}
|
||||
else {
|
||||
STATIC_RAIN_ANGLE -= 12;
|
||||
if (STATIC_RAIN_ANGLE < -45) {
|
||||
count = 1500;
|
||||
add_angle = !add_angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0));
|
||||
float sin_angle = Sin(rain_angle);
|
||||
float cos_angle = Cos(rain_angle);
|
||||
float base_x = 0.0f * cos_angle - 1.0f * sin_angle;
|
||||
float base_y = 1.0f * cos_angle + 0.0f * sin_angle;
|
||||
CVector xpos(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < 2 * num_drops; i++) {
|
||||
CVector dir;
|
||||
dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.z = 0;
|
||||
CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
|
||||
colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
|
||||
xpos.x += screen_width / (2 * num_drops);
|
||||
xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
|
||||
}
|
||||
CVector ypos(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < num_drops; i++) {
|
||||
CVector dir;
|
||||
dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.z = 0;
|
||||
CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
|
||||
colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
|
||||
ypos.y += screen_width / num_drops;
|
||||
ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
|
||||
}
|
||||
CVector ypos2(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < num_drops; i++) {
|
||||
CVector dir;
|
||||
dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
|
||||
dir.z = 0;
|
||||
CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
|
||||
colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
|
||||
ypos2.y += screen_width / num_drops;
|
||||
ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
|
||||
}
|
||||
for (int i = 0; i < num_drops; i++) {
|
||||
CVector pos;
|
||||
pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET);
|
||||
pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET);
|
||||
pos.z = 0.0f;
|
||||
CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
|
||||
colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 0);
|
||||
}
|
||||
int num_splash_attempts = (int)(3 * Rain) + 1;
|
||||
int num_splashes = (int)(3 * Rain) + 4;
|
||||
CVector splash_points[4];
|
||||
splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
|
||||
RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
|
||||
splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
|
||||
RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
|
||||
splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
|
||||
RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
|
||||
splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
|
||||
RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
|
||||
RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
|
||||
CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4;
|
||||
for (int i = 0; i < num_splash_attempts; i++) {
|
||||
CColPoint point;
|
||||
CEntity* entity;
|
||||
CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f);
|
||||
if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) {
|
||||
for (int j = 0; j < num_splashes; j++)
|
||||
CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP),
|
||||
CVector(
|
||||
np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
|
||||
np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
|
||||
point.point.z + 0.1f),
|
||||
CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance)
|
||||
{
|
||||
static float RandomTex;
|
||||
static float RandomTexX;
|
||||
static float RandomTexY;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored + 1;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored + 3;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 6] = TempBufferVerticesStored + 1;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 7] = TempBufferVerticesStored + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 8] = TempBufferVerticesStored + 4;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 9] = TempBufferVerticesStored + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 10] = TempBufferVerticesStored + 3;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStored + 11] = TempBufferVerticesStored + 4;
|
||||
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0);
|
||||
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z);
|
||||
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0);
|
||||
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z);
|
||||
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RAIN_COLOUR_R * intensity / 256, RAIN_COLOUR_G * intensity / 256, RAIN_COLOUR_B * intensity / 256, RAIN_ALPHA);
|
||||
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z);
|
||||
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0);
|
||||
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z);
|
||||
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0);
|
||||
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetUp().x, pos.y - 11.0f * TheCamera.GetUp().y, pos.z - 11.0f * TheCamera.GetUp().z);
|
||||
float u = STREAK_U;
|
||||
float v = STREAK_V;
|
||||
if (scale) {
|
||||
u *= LARGE_STREAK_COEFFICIENT;
|
||||
v *= LARGE_STREAK_COEFFICIENT;
|
||||
}
|
||||
float distance_coefficient;
|
||||
if (distance < STREAK_MIN_DISTANCE)
|
||||
distance_coefficient = 1.0f;
|
||||
else if (distance > STREAK_MAX_DISTANCE)
|
||||
distance_coefficient = 0.5f;
|
||||
else
|
||||
distance_coefficient = 1.0f - 0.5f * (distance - STREAK_MIN_DISTANCE) / (STREAK_MAX_DISTANCE - STREAK_MIN_DISTANCE);
|
||||
u *= distance_coefficient;
|
||||
v *= distance_coefficient;
|
||||
if (!CTimer::GetIsPaused()) {
|
||||
RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f;
|
||||
RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f;
|
||||
RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f;
|
||||
}
|
||||
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX);
|
||||
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY);
|
||||
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexX);
|
||||
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexY);
|
||||
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 0.5f * u + RandomTexX);
|
||||
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RandomTexY);
|
||||
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 3], u + RandomTexX);
|
||||
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 3], RandomTexY);
|
||||
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0.5f * u + RandomTex + RandomTexX);
|
||||
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v + RandomTexY);
|
||||
TempBufferIndicesStored += 12;
|
||||
TempBufferVerticesStored += 5;
|
||||
}
|
||||
|
||||
void CWeather::RenderRainStreaks(void)
|
||||
{
|
||||
if (CTimer::GetIsCodePaused())
|
||||
return;
|
||||
int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain);
|
||||
if (base_intensity == 0)
|
||||
return;
|
||||
TempBufferIndicesStored = 0;
|
||||
TempBufferVerticesStored = 0;
|
||||
for (int i = 0; i < NUM_RAIN_STREAKS; i++) {
|
||||
if (Streaks[i].timer) {
|
||||
float secondsElapsed = (CTimer::GetTimeInMilliseconds() - Streaks[i].timer) / 1024.0f;
|
||||
if (secondsElapsed > STREAK_LIFETIME)
|
||||
Streaks[i].timer = 0;
|
||||
else{
|
||||
int intensity;
|
||||
if (secondsElapsed < STREAK_INTEROLATION_TIME)
|
||||
intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME;
|
||||
else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME))
|
||||
intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME;
|
||||
else
|
||||
intensity = base_intensity * 0.5f;
|
||||
CVector dir = Streaks[i].direction;
|
||||
dir.Normalise();
|
||||
CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction;
|
||||
RenderOneRainStreak(pos, dir, intensity, false, (pos - TheCamera.GetPosition()).Magnitude());
|
||||
#ifndef FIX_BUGS // remove useless code
|
||||
if (secondsElapsed > 1.0f && secondsElapsed < STREAK_LIFETIME - 1.0f) {
|
||||
CGeneral::GetRandomNumber(), CGeneral::GetRandomNumber();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){
|
||||
// 1/16 probability
|
||||
Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
|
||||
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
|
||||
if (!CCutsceneMgr::IsRunning()) {
|
||||
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
|
||||
Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f;
|
||||
}
|
||||
else
|
||||
Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f;
|
||||
Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
|
||||
Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
|
||||
Streaks[i].timer = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
}
|
||||
if (TempBufferIndicesStored){
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex[3]));
|
||||
if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1))
|
||||
{
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
}
|
||||
TempBufferVerticesStored = 0;
|
||||
TempBufferIndicesStored = 0;
|
||||
}
|
||||
|
||||
void CWeather::StoreWeatherState()
|
||||
{
|
||||
Stored_StateStored = true;
|
||||
@ -71,4 +529,4 @@ void CWeather::RestoreWeatherState()
|
||||
Rain = Stored_Rain;
|
||||
NewWeatherType = Stored_NewWeatherType;
|
||||
OldWeatherType = Stored_OldWeatherType;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,14 @@ enum {
|
||||
class CWeather
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
WEATHER_RANDOM = -1,
|
||||
WEATHER_SUNNY = 0,
|
||||
WEATHER_CLOUDY = 1,
|
||||
WEATHER_RAINY = 2,
|
||||
WEATHER_FOGGY = 3,
|
||||
WEATHER_TOTAL = 4
|
||||
};
|
||||
static int32 &SoundHandle;
|
||||
|
||||
static int32 &WeatherTypeInList;
|
||||
@ -46,4 +54,18 @@ public:
|
||||
static void ForceWeatherNow(int16);
|
||||
static void StoreWeatherState();
|
||||
static void RestoreWeatherState();
|
||||
static void AddRain();
|
||||
};
|
||||
|
||||
enum {
|
||||
NUM_RAIN_STREAKS = 35
|
||||
};
|
||||
|
||||
struct tRainStreak
|
||||
{
|
||||
CVector position;
|
||||
CVector direction;
|
||||
uint32 timer;
|
||||
};
|
||||
|
||||
extern RwTexture* (&gpRainDropTex)[4];
|
Reference in New Issue
Block a user