From 11ba688c988758c8654e5ea976aa141d44205b92 Mon Sep 17 00:00:00 2001 From: _AG Date: Thu, 20 Jun 2019 21:34:39 +0200 Subject: Update Radar.cpp --- src/Radar.cpp | 242 +++++++++++++++++++++++++++++++++----------------- src/Radar.h | 9 +- src/render/Hud.cpp | 22 ++--- src/render/Sprite2d.h | 2 + 4 files changed, 183 insertions(+), 92 deletions(-) diff --git a/src/Radar.cpp b/src/Radar.cpp index 5be0b572..eb2aad59 100644 --- a/src/Radar.cpp +++ b/src/Radar.cpp @@ -9,12 +9,15 @@ #include "Vehicle.h" #include "Pools.h" #include "Script.h" +#include "TxdStore.h" WRAPPER void CRadar::ClearBlipForEntity(eBlipType type, int32 id) { EAXJMP(0x4A56C0); } WRAPPER void CRadar::Draw3dMarkers() { EAXJMP(0x4A4C70); } -WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); } WRAPPER float CRadar::LimitRadarPoint(CVector2D *point) { EAXJMP(0x4A4F30); } WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha) { EAXJMP(0x4A5870); } +WRAPPER void CRadar::StreamRadarSections(int x, int y) { EAXJMP(0x4A6100); } +WRAPPER int CRadar::ClipRadarPoly(CVector2D *out, CVector2D *in) { EAXJMP(0x4A64A0); } +WRAPPER void CRadar::TransformRealWorldToTexCoordSpace(CVector2D *out, CVector2D *in, int x, int y) { EAXJMP(0x4A5530); } float &CRadar::m_RadarRange = *(float*)0x8E281C; CVector2D &CRadar::vec2DRadarOrigin = *(CVector2D*)0x6299B8; @@ -22,6 +25,8 @@ CBlip *CRadar::ms_RadarTrace = (CBlip*)0x6ED5E0; float CRadar::cachedSin; float CRadar::cachedCos; +int *gRadarTxdIds = (int*)0x6299C0; + CSprite2d *CRadar::AsukaSprite = (CSprite2d*)0x8F1A40; CSprite2d *CRadar::BombSprite = (CSprite2d*)0x8F5FB4; CSprite2d *CRadar::CatSprite = (CSprite2d*)0x885B24; @@ -93,6 +98,98 @@ void CRadar::DrawMap() } #endif +#if 0 +WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); } +#else +void CRadar::DrawRadarMask() +{ + CVector2D vec2d[4]{ + CVector2D(1.0f, -1.0f), + CVector2D(1.0f, 1.0f), + CVector2D(-1.0f, 1.0f), + CVector2D(-1.0, -1.0f) + }; + + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS); + + CVector2D out[8]; + CVector2D in; + + for (int i = 0; i < 4; i++) { + in.x = vec2d[i].x; + in.y = vec2d[i].y; + + CRadar::TransformRadarPointToScreenSpace(out, &in); + + for (int j = 0; j < 7; j++) { + CRadar::cachedCos = cos(j * M_PI_2 * (1.0f / 6.0f)); + CRadar::cachedSin = sin(j * M_PI_2 * (1.0f / 6.0f)); + + in.x = vec2d[i].x * cachedCos; + in.y = vec2d[i].y * cachedSin; + CRadar::TransformRadarPointToScreenSpace(&out[j + 1], &in); + }; + + CSprite2d::SetMaskVertices(8, (float *)out); + RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8); + }; + + RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER); +} +#endif + +#if 1 +WRAPPER void CRadar::DrawRadarSection(int x, int y) { EAXJMP(0x4A67E0); } +#else +void CRadar::DrawRadarSection(int x, int y) +{ + +} +#endif + +#if 0 +WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); } +#else +void CRadar::DrawRadarMap() +{ + CRadar::DrawRadarMask(); + + int x = floorf((2000.0f + vec2DRadarOrigin.x) * 0.002f); + int y = round(7.0f - (2000.0f + vec2DRadarOrigin.y) * 0.002f); + CRadar::StreamRadarSections(x, y); + + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); + RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)FALSE); + + CRadar::DrawRadarSection(x - 1, y - 1); + CRadar::DrawRadarSection(x, y - 1); + CRadar::DrawRadarSection(x + 1, y - 1); + CRadar::DrawRadarSection(x - 1, y); + CRadar::DrawRadarSection(x, y); + CRadar::DrawRadarSection(x + 1, y); + CRadar::DrawRadarSection(x - 1, y + 1); + CRadar::DrawRadarSection(x, y + 1); + CRadar::DrawRadarSection(x + 1, y + 1); +} +#endif + #if 0 WRAPPER void CRadar::DrawBlips() { EAXJMP(0x4A42F0); } #else @@ -120,7 +217,7 @@ void CRadar::DrawBlips() CVector2D vec2d; vec2d.x = vec2DRadarOrigin.x; - vec2d.y = M_SQRT2 * CRadar::m_RadarRange + vec2DRadarOrigin.y; + vec2d.y = M_SQRT2 * m_RadarRange + vec2DRadarOrigin.y; CRadar::TransformRealWorldPointToRadarSpace(&in, &vec2d); CRadar::LimitRadarPoint(&in); CRadar::TransformRadarPointToScreenSpace(&out, &in); @@ -146,62 +243,58 @@ void CRadar::DrawBlips() }; if (e) { - if (CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { if (CTheScripts::DbgFlag) { - CRadar::ShowRadarMarker(e->GetPosition(), CRadar::GetRadarTraceColour(CRadar::ms_RadarTrace[i].m_nColor, CRadar::ms_RadarTrace[i].m_bDim), CRadar::ms_RadarTrace->m_Radius); + CRadar::ShowRadarMarker(e->GetPosition(), GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius); - CRadar::ms_RadarTrace[i].m_Radius = CRadar::ms_RadarTrace[i].m_Radius - 0.1f; - if (CRadar::ms_RadarTrace[i].m_Radius >= 1.0f) - CRadar::ms_RadarTrace[i].m_Radius = 5.0; + ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f; + if (ms_RadarTrace[i].m_Radius >= 1.0f) + ms_RadarTrace[i].m_Radius = 5.0; } } - if (CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { vec2d = e->GetPosition(); CRadar::TransformRealWorldPointToRadarSpace(&in, &vec2d); float dist = CRadar::LimitRadarPoint(&in); int a = CRadar::CalculateBlipAlpha(dist); CRadar::TransformRadarPointToScreenSpace(&out, &in); - CRGBA col = CRadar::GetRadarTraceColour(CRadar::ms_RadarTrace[i].m_nColor, CRadar::ms_RadarTrace[i].m_bDim); + CRGBA col = CRadar::GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim); if (CRadar::ms_RadarTrace[i].m_IconID) - CRadar::DrawRadarSprite(CRadar::ms_RadarTrace[i].m_IconID, out.x, out.y, a); + CRadar::DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a); else - CRadar::ShowRadarTrace(out.x, out.y, CRadar::ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255); + CRadar::ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255); } } } - } - } - /* - DrawCoordBlip - */ - for (int i = 0; i < 32; i++) { - if (CRadar::ms_RadarTrace[i].m_bInUse) { + /* + DrawCoordBlip + */ if (ms_RadarTrace[i].m_eBlipType >= BLIP_COORD) { - if (CRadar::DisplayThisBlip(ms_RadarTrace[i].m_IconID) && CRadar::ms_RadarTrace[i].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission()) { - if (CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (ms_RadarTrace[i].m_eBlipType != BLIP_CONTACT_POINT || ms_RadarTrace[i].m_eBlipType == BLIP_CONTACT_POINT && DisplayThisBlip(i) || !CTheScripts::IsPlayerOnAMission()) { + if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { if (CTheScripts::DbgFlag) { - CRadar::ShowRadarMarker(CRadar::ms_RadarTrace[i].m_vecPos, CRadar::GetRadarTraceColour(CRadar::ms_RadarTrace[i].m_nColor, CRadar::ms_RadarTrace[i].m_bDim), CRadar::ms_RadarTrace->m_Radius); - CRadar::ms_RadarTrace[i].m_Radius = CRadar::ms_RadarTrace[i].m_Radius - 0.1f; - if (CRadar::ms_RadarTrace[i].m_Radius >= 1.0f) - CRadar::ms_RadarTrace[i].m_Radius = 5.0f; + CRadar::ShowRadarMarker(ms_RadarTrace[i].m_vecPos, GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius); + CRadar::ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f; + if (ms_RadarTrace[i].m_Radius >= 1.0f) + ms_RadarTrace[i].m_Radius = 5.0f; } } - if (CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || CRadar::ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { CRadar::TransformRealWorldPointToRadarSpace(&in, &ms_RadarTrace[i].m_vec2DPos); float dist = CRadar::LimitRadarPoint(&in); int a = CRadar::CalculateBlipAlpha(dist); CRadar::TransformRadarPointToScreenSpace(&out, &in); - CRGBA col = CRadar::GetRadarTraceColour(CRadar::ms_RadarTrace[i].m_nColor, CRadar::ms_RadarTrace[i].m_bDim); + CRGBA col = CRadar::GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim); if (CRadar::ms_RadarTrace[i].m_IconID) - CRadar::DrawRadarSprite(CRadar::ms_RadarTrace[i].m_IconID, out.x, out.y, a); + CRadar::DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a); else - CRadar::ShowRadarTrace(out.x, out.y, CRadar::ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255); + CRadar::ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255); } } } @@ -211,45 +304,6 @@ void CRadar::DrawBlips() } #endif -bool CRadar::DisplayThisBlip(int16 spriteid) -{ - switch (spriteid) { - case RADAR_SPRITE_NONE: - return true; - break; - case RADAR_SPRITE_ASUKA: - case RADAR_SPRITE_BOMB: - case RADAR_SPRITE_CAT: - return false; - break; - case RADAR_SPRITE_CENTRE: - return true; - break; - case RADAR_SPRITE_COPCAR: - case RADAR_SPRITE_DON: - case RADAR_SPRITE_EIGHT: - case RADAR_SPRITE_EL: - case RADAR_SPRITE_ICE: - case RADAR_SPRITE_JOEY: - case RADAR_SPRITE_KENJI: - case RADAR_SPRITE_LIZ: - case RADAR_SPRITE_LUIGI: - return false; - break; - case RADAR_SPRITE_NORTH: - return true; - break; - case RADAR_SPRITE_RAY: - case RADAR_SPRITE_SAL: - case RADAR_SPRITE_SAVE: - case RADAR_SPRITE_SPRAY: - case RADAR_SPRITE_TONY: - case RADAR_SPRITE_WEAPON: - return false; - break; - }; -} - int CRadar::CalculateBlipAlpha(float dist) { if (dist <= 1.0f) @@ -269,46 +323,38 @@ CRGBA CRadar::GetRadarTraceColour(uint32 color, bool bright) return CRGBA(113, 43, 73, 255); else return CRGBA(127, 0, 0, 255); - break; case 1: if (bright) return CRGBA(95, 160, 106, 255); else return CRGBA(127, 0, 255, 255); - break; case 2: if (bright) return CRGBA(128, 167, 243, 255); else return CRGBA(0, 127, 255, 255); - break; case 3: if (bright) return CRGBA(225, 225, 225, 255); else return CRGBA(127, 127, 127, 255); - break; case 4: if (bright) return CRGBA(255, 225, 0, 255); else return CRGBA(127, 127, 0, 255); - break; case 5: if (bright) return CRGBA(255, 0, 255, 255); else return CRGBA(127, 0, 127, 255); - break; case 6: if (bright) return CRGBA(255, 255, 255, 255); else return CRGBA(127, 127, 255, 255); - break; default: return CRGBA(0, 0, 0, 255); - break; } } @@ -323,20 +369,20 @@ WRAPPER void CRadar::TransformRealWorldPointToRadarSpace(CVector2D *out, CVector #else void CRadar::TransformRealWorldPointToRadarSpace(CVector2D *out, CVector2D *in) { - if (TheCamera.Cams->Mode != CCam::CamMode::MODE_TOPDOWN1 && TheCamera.Cams->Mode != CCam::CamMode::MODE_TOPDOWNPED) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::CamMode::MODE_TOPDOWN1 && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::CamMode::MODE_TOPDOWNPED) { if (TheCamera.GetLookDirection() != LOOKING_FORWARD) { - cachedSin = sin(atan2(-TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up.x, TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up.y)); - cachedCos = cos(atan2(-TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up.x, TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up.y)); + cachedSin = sin(atan2(-TheCamera.m_matrix.m_matrix.up.x, TheCamera.m_matrix.m_matrix.up.y)); + cachedCos = cos(atan2(-TheCamera.m_matrix.m_matrix.up.x, TheCamera.m_matrix.m_matrix.up.y)); } else { CVector vecCamera; - if (TheCamera.Cams->Mode == CCam::CamMode::MODE_FIRSTPERSON) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::CamMode::MODE_FIRSTPERSON) { vecCamera = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up; vecCamera.Normalise(); } else - vecCamera = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.pos - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; + vecCamera = TheCamera.m_matrix.m_matrix.up; cachedSin = sin(atan2(-vecCamera.x, vecCamera.y)); cachedCos = cos(atan2(-vecCamera.x, vecCamera.y)); @@ -436,6 +482,42 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float } #endif +bool CRadar::DisplayThisBlip(int counter) +{ + switch (ms_RadarTrace[counter].m_IconID) { + case RADAR_SPRITE_BOMB: + case RADAR_SPRITE_SPRAY: + case RADAR_SPRITE_WEAPON: + return true; + default: + return false; + } +} + +void CRadar::GetTextureCorners(int x, int y, CVector2D *out) +{ + out[0].x = 500.0f * (x - 4); + out[0].y = 500.0f * (3 - y); + out[1].x = 500.0f * (y - 4 + 1); + out[1].y = 500.0f * (3 - y); + out[2].x = 500.0f * (y - 4 + 1); + out[2].y = 500.0f * (3 - y + 1); + out[3].x = 500.0f * (x - 4); + out[3].y = 500.0f * (3 - y + 1); +} + +void CRadar::ClipRadarTileCoords(int x, int y) +{ + if (x < 0) + x = 0; + if (x > 7) + x = 7; + if (y < 0) + y = 0; + if (y > 7) + y = 7; +} + STARTPATCHES InjectHook(0x4A5040, CRadar::TransformRadarPointToScreenSpace, PATCH_JUMP); ENDPATCHES diff --git a/src/Radar.h b/src/Radar.h index b71618f1..9d219cc6 100644 --- a/src/Radar.h +++ b/src/Radar.h @@ -99,9 +99,12 @@ public: static void ClearBlipForEntity(eBlipType type, int32 id); static void Draw3dMarkers(); static void DrawMap(); + static void StreamRadarSections(int x, int y); + static int ClipRadarPoly(CVector2D *out, CVector2D *in); + static void TransformRealWorldToTexCoordSpace(CVector2D *out, CVector2D *in, int x, int y); + static void DrawRadarSection(int x, int y); static void TransformRadarPointToScreenSpace(CVector2D * out, CVector2D * in); static void DrawBlips(); - static bool DisplayThisBlip(int16 spriteid); static int CalculateBlipAlpha(float dist); static CRGBA GetRadarTraceColour(uint32 color, bool bright); static void DrawRadarMap(); @@ -111,4 +114,8 @@ public: static void DrawRadarSprite(int sprite, float x, float y, int alpha); static void ShowRadarMarker(CVector pos, CRGBA color, float radius); static void ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha); + static void DrawRadarMask(); + static bool DisplayThisBlip(int counter); + static void GetTextureCorners(int x, int y, CVector2D * out); + static void ClipRadarTileCoords(int x, int y); }; diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 540a1718..96e50f06 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -1011,13 +1011,13 @@ void CHud::Draw() CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(20.0f), m_BigMessage[0]); } else { - BigMessageAlpha[0] = 0.0; - BigMessageX[0] = -60.0; - BigMessageInUse[0] = 1.0; + BigMessageAlpha[0] = 0.0f; + BigMessageX[0] = -60.0f; + BigMessageInUse[0] = 1.0f; } } else { - BigMessageInUse[0] = 0.0; + BigMessageInUse[0] = 0.0f; } // WastedBustedText @@ -1149,7 +1149,7 @@ void CHud::DrawAfterFade() CFont::SetFontStyle(FONT_BANK); CFont::SetBackgroundOn(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha)); + CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.8f)); CFont::SetColor(CRGBA(175, 175, 175, 255)); CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::m_HelpMessageToPrint); CFont::SetAlphaFade(255.0f); @@ -1283,18 +1283,18 @@ void CHud::DrawAfterFade() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), m_BigMessage[1]); } else { - BigMessageAlpha[1] = 0.0; - BigMessageX[1] = -60.0; - BigMessageInUse[1] = 1.0; + BigMessageAlpha[1] = 0.0f; + BigMessageX[1] = -60.0f; + BigMessageInUse[1] = 1.0f; } } else { - BigMessageInUse[1] = 0.0; + BigMessageInUse[1] = 0.0f; } } #endif -#if 1 +#if 0 WRAPPER void CHud::ReInitialise(void) { EAXJMP(0x504CC0); } #else void CHud::ReInitialise() { @@ -1315,7 +1315,7 @@ void CHud::ReInitialise() { BigMessageInUse[i] = 0.0f; if (i <= 128) - *(wchar*)(m_BigMessage[i]) = 0; + m_BigMessage[i][0] = 0; } m_HelpMessageTimer = 0; diff --git a/src/render/Sprite2d.h b/src/render/Sprite2d.h index d5f0a5ae..e0f19ef1 100644 --- a/src/render/Sprite2d.h +++ b/src/render/Sprite2d.h @@ -46,4 +46,6 @@ public: static void DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3); static void DrawRect(const CRect &r, const CRGBA &col); static void DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3); + + static RwIm2DVertex* GetVertices() { return maVertices; }; }; -- cgit v1.2.3 From a9bcd1b7c5a91c0def1101223064651d538a00b2 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 21 Jun 2019 11:09:09 +0200 Subject: added some World defines --- src/World.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/World.h b/src/World.h index 9a8a0c46..b099583b 100644 --- a/src/World.h +++ b/src/World.h @@ -7,8 +7,20 @@ /* Sectors span from -2000 to 2000 in x and y. * With 100x100 sectors, each is 40x40 units. */ -#define NUMSECTORS_X 100 -#define NUMSECTORS_Y 100 +#define SECTOR_SIZE_X (40.0f) +#define SECTOR_SIZE_Y (40.0f) + +#define NUMSECTORS_X (100) +#define NUMSECTORS_Y (100) + +#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X) +#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y) + +#define WORLD_MIN_X (-2000.0f) +#define WORLD_MIN_Y (-2000.0f) + +#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X) +#define WORLD_MAX_Y (WORLD_MIN_Y + WORLD_SIZE_Y) enum { @@ -85,12 +97,12 @@ public: static float FindGroundZFor3DCoord(float x, float y, float z, bool *found); static float FindRoofZFor3DCoord(float x, float y, float z, bool *found); - static float GetSectorX(float f) { return ((f + 2000.0f)/40.0f); } - static float GetSectorY(float f) { return ((f + 2000.0f)/40.0f); } + static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); } + static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static int GetSectorIndexX(float f) { return (int)GetSectorX(f); } static int GetSectorIndexY(float f) { return (int)GetSectorY(f); } - static float GetWorldX(int x) { return x*40.0f - 2000.0f; } - static float GetWorldY(int y) { return y*40.0f - 2000.0f; } + static float GetWorldX(int x) { return x*SECTOR_SIZE_X + WORLD_MIN_X; } + static float GetWorldY(int y) { return y*SECTOR_SIZE_Y + WORLD_MIN_Y; } }; class CPed; -- cgit v1.2.3 From 074dd9486c6d198f61b098230447903959eda94f Mon Sep 17 00:00:00 2001 From: _AG Date: Fri, 21 Jun 2019 11:27:53 +0200 Subject: Clean up --- src/Radar.cpp | 33 +++++++++++++++++++-------------- src/Radar.h | 1 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/Radar.cpp b/src/Radar.cpp index eb2aad59..41ca0780 100644 --- a/src/Radar.cpp +++ b/src/Radar.cpp @@ -18,6 +18,7 @@ WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, u WRAPPER void CRadar::StreamRadarSections(int x, int y) { EAXJMP(0x4A6100); } WRAPPER int CRadar::ClipRadarPoly(CVector2D *out, CVector2D *in) { EAXJMP(0x4A64A0); } WRAPPER void CRadar::TransformRealWorldToTexCoordSpace(CVector2D *out, CVector2D *in, int x, int y) { EAXJMP(0x4A5530); } +WRAPPER void CRadar::TransformRadarPointToRealWorldSpace(CVector2D *out, CVector2D *in) { EAXJMP(0x4A5300); } float &CRadar::m_RadarRange = *(float*)0x8E281C; CVector2D &CRadar::vec2DRadarOrigin = *(CVector2D*)0x6299B8; @@ -103,7 +104,7 @@ WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); } #else void CRadar::DrawRadarMask() { - CVector2D vec2d[4]{ + CVector2D vec2d[4] = { CVector2D(1.0f, -1.0f), CVector2D(1.0f, 1.0f), CVector2D(-1.0f, 1.0f), @@ -131,8 +132,8 @@ void CRadar::DrawRadarMask() CRadar::TransformRadarPointToScreenSpace(out, &in); for (int j = 0; j < 7; j++) { - CRadar::cachedCos = cos(j * M_PI_2 * (1.0f / 6.0f)); - CRadar::cachedSin = sin(j * M_PI_2 * (1.0f / 6.0f)); + CRadar::cachedCos = cos(j * (PI / 2.0f / 6.0f)); + CRadar::cachedSin = sin(j * (PI / 2.0f / 6.0f)); in.x = vec2d[i].x * cachedCos; in.y = vec2d[i].y * cachedSin; @@ -208,10 +209,10 @@ void CRadar::DrawBlips() CRadar::TransformRadarPointToScreenSpace(&out, &in); float angle; - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::CamMode::MODE_TOPDOWN1) + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1) angle = PI + FindPlayerHeading(); else - angle = FindPlayerHeading() - (PI + atan2(-TheCamera.m_matrix.m_matrix.up.x, TheCamera.m_matrix.m_matrix.up.y)); + angle = FindPlayerHeading() - (PI + atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y)); CRadar::DrawRotatingRadarSprite(CentreSprite, out.x, out.y, angle, 255); @@ -230,7 +231,7 @@ void CRadar::DrawBlips() if (ms_RadarTrace[i].m_bInUse) { if (ms_RadarTrace[i].m_eBlipType <= BLIP_OBJECT) { CEntity *e = nil; - switch (CRadar::ms_RadarTrace[i].m_eBlipType) { + switch (ms_RadarTrace[i].m_eBlipType) { case BLIP_CAR: e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[i].m_nEntityHandle); break; @@ -261,7 +262,7 @@ void CRadar::DrawBlips() CRGBA col = CRadar::GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim); - if (CRadar::ms_RadarTrace[i].m_IconID) + if (ms_RadarTrace[i].m_IconID) CRadar::DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a); else CRadar::ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255); @@ -276,8 +277,8 @@ void CRadar::DrawBlips() if (ms_RadarTrace[i].m_eBlipType != BLIP_CONTACT_POINT || ms_RadarTrace[i].m_eBlipType == BLIP_CONTACT_POINT && DisplayThisBlip(i) || !CTheScripts::IsPlayerOnAMission()) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { if (CTheScripts::DbgFlag) { - CRadar::ShowRadarMarker(ms_RadarTrace[i].m_vecPos, GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius); - CRadar::ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f; + CRadar::ShowRadarMarker(ms_RadarTrace[i].m_vecPos, CRadar::GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius); + ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f; if (ms_RadarTrace[i].m_Radius >= 1.0f) ms_RadarTrace[i].m_Radius = 5.0f; } @@ -369,20 +370,20 @@ WRAPPER void CRadar::TransformRealWorldPointToRadarSpace(CVector2D *out, CVector #else void CRadar::TransformRealWorldPointToRadarSpace(CVector2D *out, CVector2D *in) { - if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::CamMode::MODE_TOPDOWN1 && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::CamMode::MODE_TOPDOWNPED) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_TOPDOWN1 && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_TOPDOWNPED) { if (TheCamera.GetLookDirection() != LOOKING_FORWARD) { - cachedSin = sin(atan2(-TheCamera.m_matrix.m_matrix.up.x, TheCamera.m_matrix.m_matrix.up.y)); - cachedCos = cos(atan2(-TheCamera.m_matrix.m_matrix.up.x, TheCamera.m_matrix.m_matrix.up.y)); + cachedSin = sin(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y)); + cachedCos = cos(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y)); } else { CVector vecCamera; - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::CamMode::MODE_FIRSTPERSON) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON) { vecCamera = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->m_matrix.m_matrix.up; vecCamera.Normalise(); } else - vecCamera = TheCamera.m_matrix.m_matrix.up; + vecCamera = TheCamera.GetForward(); cachedSin = sin(atan2(-vecCamera.x, vecCamera.y)); cachedCos = cos(atan2(-vecCamera.x, vecCamera.y)); @@ -494,6 +495,9 @@ bool CRadar::DisplayThisBlip(int counter) } } +#if 0 +WRAPPER void CRadar::GetTextureCorners(int x, int y, CVector2D *out) { EAXJMP(0x4A61C0); }; +#else void CRadar::GetTextureCorners(int x, int y, CVector2D *out) { out[0].x = 500.0f * (x - 4); @@ -505,6 +509,7 @@ void CRadar::GetTextureCorners(int x, int y, CVector2D *out) out[3].x = 500.0f * (x - 4); out[3].y = 500.0f * (3 - y + 1); } +#endif void CRadar::ClipRadarTileCoords(int x, int y) { diff --git a/src/Radar.h b/src/Radar.h index 9d219cc6..5a63a83b 100644 --- a/src/Radar.h +++ b/src/Radar.h @@ -102,6 +102,7 @@ public: static void StreamRadarSections(int x, int y); static int ClipRadarPoly(CVector2D *out, CVector2D *in); static void TransformRealWorldToTexCoordSpace(CVector2D *out, CVector2D *in, int x, int y); + static void CRadar::TransformRadarPointToRealWorldSpace(CVector2D *out, CVector2D *in); static void DrawRadarSection(int x, int y); static void TransformRadarPointToScreenSpace(CVector2D * out, CVector2D * in); static void DrawBlips(); -- cgit v1.2.3 From 66462d348bec183e6b7cf848a463052759221928 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 21 Jun 2019 17:28:55 +0200 Subject: more CStreaming; fixed CFileLoader --- src/FileLoader.cpp | 2 +- src/Streaming.cpp | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/Streaming.h | 22 ++- src/patcher.h | 9 ++ 4 files changed, 465 insertions(+), 9 deletions(-) diff --git a/src/FileLoader.cpp b/src/FileLoader.cpp index 1295177d..f50638b4 100644 --- a/src/FileLoader.cpp +++ b/src/FileLoader.cpp @@ -1082,7 +1082,7 @@ CFileLoader::LoadCullZone(const char *line) &minx, &miny, &minz, &maxx, &maxy, &maxz, &flags, &wantedLevelDrop); - CCullZones::AddCullZone(pos, minx, maxx, miny, maxy, minz, maxy, flags, wantedLevelDrop); + CCullZones::AddCullZone(pos, minx, maxx, miny, maxy, minz, maxz, flags, wantedLevelDrop); } // unused diff --git a/src/Streaming.cpp b/src/Streaming.cpp index fa0710ea..1a5800e2 100644 --- a/src/Streaming.cpp +++ b/src/Streaming.cpp @@ -2,11 +2,14 @@ #include "patcher.h" #include "ModelInfo.h" #include "TxdStore.h" +#include "ModelIndices.h" #include "Pools.h" #include "Directory.h" #include "RwHelper.h" +#include "World.h" #include "Entity.h" #include "FileMgr.h" +#include "FileLoader.h" #include "CdStream.h" #include "Streaming.h" @@ -56,11 +59,10 @@ int32 &islandLODcomSub = *(int32*)0x6212D0; int32 &islandLODsubInd = *(int32*)0x6212D4; int32 &islandLODsubCom = *(int32*)0x6212D8; - -WRAPPER void CStreaming::RemoveModel(int32 id) { EAXJMP(0x408830); } -WRAPPER void CStreaming::RequestModel(int32 model, int32 flags) { EAXJMP(0x407EA0); } - WRAPPER void CStreaming::MakeSpaceFor(int32 size) { EAXJMP(0x409B70); } +WRAPPER bool CStreaming::IsTxdUsedByRequestedModels(int32 txdId) { EAXJMP(0x4094C0); } +WRAPPER bool CStreaming::AddToLoadedVehiclesList(int32 modelId) { EAXJMP(0x40B060); } + void CStreaming::Init(void) @@ -279,6 +281,428 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) CFileMgr::CloseFile(fd); } +bool +CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) +{ + RwMemory mem; + RwStream *stream; + int cdsize; + uint32 startTime, endTime, timeDiff; + CBaseModelInfo *mi; + bool success; + + startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); + + cdsize = ms_aInfoForModel[streamId].GetCdSize(); + mem.start = (uint8*)buf; + mem.length = cdsize * CDSTREAM_SECTOR_SIZE; + stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem); + + if(streamId < STREAM_OFFSET_TXD){ + // Model + mi = CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL); + + // Txd has to be loaded + if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){ + debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot())); + RemoveModel(streamId); + RemoveModel(mi->GetTxdSlot() + STREAM_OFFSET_TXD); + // re-request + RequestModel(streamId, ms_aInfoForModel[streamId].m_flags); + RwStreamClose(stream, &mem); + return false; + } + + // Set Txd to use + CTxdStore::AddRef(mi->GetTxdSlot()); + CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); + + if(mi->IsSimple()){ + success = CFileLoader::LoadAtomicFile(stream, streamId - STREAM_OFFSET_MODEL); + }else if(mi->m_type == MITYPE_VEHICLE){ + // load vehicles in two parts + CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL)->AddRef(); + success = CFileLoader::StartLoadClumpFile(stream, streamId - STREAM_OFFSET_MODEL); + if(success) + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; + }else{ + success = CFileLoader::LoadClumpFile(stream, streamId - STREAM_OFFSET_MODEL); + } + UpdateMemoryUsed(); + + // Txd no longer needed unless we only read part of the file + if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED) + CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); + + if(!success){ + debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL)->GetName()); + RemoveModel(streamId); + // re-request + RequestModel(streamId, ms_aInfoForModel[streamId].m_flags); + RwStreamClose(stream, &mem); + return false; + } + }else{ + // Txd + assert(streamId < NUMSTREAMINFO); + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && + !IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){ + RemoveModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + + if(ms_bLoadingBigModel || cdsize > 200){ + success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream); + if(success) + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; + }else + success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream); + UpdateMemoryUsed(); + + if(!success){ + debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); + RemoveModel(streamId); + // re-request + RequestModel(streamId, ms_aInfoForModel[streamId].m_flags); + RwStreamClose(stream, &mem); + return false; + } + } + + RwStreamClose(stream, &mem); + + // We shouldn't even end up here unless load was successful + if(!success){ + RequestModel(streamId, ms_aInfoForModel[streamId].m_flags); + if(streamId < STREAM_OFFSET_TXD) + debug("Failed to load %s.dff\n", mi->GetName()); + else + debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); + return false; + } + + if(streamId < STREAM_OFFSET_TXD){ + // Model + // Vehicles and Peds not in loaded list + if(mi->m_type != MITYPE_VEHICLE && mi->m_type != MITYPE_PED){ + CSimpleModelInfo *smi = (CSimpleModelInfo*)mi; + + // Set fading for some objects + if(mi->IsSimple() && !smi->m_isBigBuilding){ + if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_NOFADE) + smi->m_alpha = 255; + else + smi->m_alpha = 0; + } + + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); + } + }else{ + // Txd + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); + } + + // Mark objects as loaded + if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; + ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; + } + + endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); + timeDiff = endTime - startTime; + if(timeDiff > 5){ + if(streamId < STREAM_OFFSET_TXD) + debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL)->GetName(), timeDiff); + else + debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); + } + + return true; +} + + +bool +CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) +{ + RwMemory mem; + RwStream *stream; + uint32 startTime, endTime, timeDiff; + CBaseModelInfo *mi; + bool success; + + startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); + + if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ + if(streamId < STREAM_OFFSET_TXD) + CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL)->RemoveRef(); + return false; + } + + mem.start = (uint8*)buf; + mem.length = ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; + stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem); + + if(streamId < STREAM_OFFSET_TXD){ + // Model + mi = CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL); + CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); + success = CFileLoader::FinishLoadClumpFile(stream, streamId); + if(success) + success = AddToLoadedVehiclesList(streamId); + mi->RemoveRef(); + CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); + }else{ + // Txd + CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); + success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); + CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); + } + + RwStreamClose(stream, &mem); + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; + ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; + + if(!success){ + RemoveModel(streamId); + // re-request + RequestModel(streamId, ms_aInfoForModel[streamId].m_flags); + UpdateMemoryUsed(); + return false; + } + + UpdateMemoryUsed(); + + endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); + timeDiff = endTime - startTime; + if(timeDiff > 5){ + if(streamId < STREAM_OFFSET_TXD) + debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId - STREAM_OFFSET_MODEL)->GetName(), timeDiff); + else + debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); + } + + return true; +} + +void +CStreaming::RequestModel(int32 id, int32 flags) +{ + CSimpleModelInfo *mi; + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_INQUEUE){ + // updgrade to priority + if(flags & STREAMFLAGS_PRIORITY && (ms_aInfoForModel[id].m_flags & STREAMFLAGS_PRIORITY) == 0){ + ms_numPriorityRequests++; + ms_aInfoForModel[id].m_flags |= STREAMFLAGS_PRIORITY; + } + }else if(ms_aInfoForModel[id].m_loadState != STREAMSTATE_NOTLOADED){ + flags &= ~STREAMFLAGS_PRIORITY; + } + ms_aInfoForModel[id].m_flags |= flags; + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ + // Already loaded, only check changed flags + + if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOFADE && id < STREAM_OFFSET_TXD){ + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id - STREAM_OFFSET_MODEL); + if(mi->IsSimple()) + mi->m_alpha = 255; + } + + // reinsert into list + if(ms_aInfoForModel[id].m_next){ + ms_aInfoForModel[id].RemoveFromList(); + if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + ms_aInfoForModel[id].AddToList(&ms_startLoadedList); + } + }else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED || + ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again? + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){ + if(id < STREAM_OFFSET_TXD) + RequestTxd(CModelInfo::GetModelInfo(id - STREAM_OFFSET_MODEL)->GetTxdSlot(), flags); + ms_aInfoForModel[id].AddToList(&ms_startRequestedList); + ms_numModelsRequested++; + if(flags & STREAMFLAGS_PRIORITY) + ms_numPriorityRequests++; + } + + ms_aInfoForModel[id].m_loadState = STREAMSTATE_INQUEUE; + ms_aInfoForModel[id].m_flags = flags; + } +} + +void +CStreaming::RequestSubway(void) +{ + RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE); + + switch(CGame::currLevel){ + case LEVEL_INDUSTRIAL: + RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE); + break; + case LEVEL_COMMERCIAL: + if(FindPlayerTrain()->GetPosition().y < -700.0f){ + RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE); + }else{ + RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE); + } + break; + case LEVEL_SUBURBAN: + RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE); + RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE); + break; + } +} + +void +CStreaming::RequestBigBuildings(eLevelName level) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize(); + for(i = 0; i < n; i++){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level) + RequestModel(b->GetModelIndex(), STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + } + RequestIslands(level); + ms_hasLoadedLODs = false; +} + +void +CStreaming::RequestIslands(eLevelName level) +{ + switch(level){ + case LEVEL_INDUSTRIAL: + RequestModel(islandLODcomInd, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODsubInd, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + break; + case LEVEL_COMMERCIAL: + RequestModel(islandLODindust, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODsubCom, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + break; + case LEVEL_SUBURBAN: + RequestModel(islandLODindust, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODcomSub, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + break; + } +} + +void +CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags) +{ + CBaseModelInfo *mi; + int txdId; + char oldName[48]; + uint32 pos, size; + + mi = CModelInfo::GetModelInfo(modelId); + if(strcmp(mi->GetName(), modelName) == 0){ + // Already have the correct name, just request it + RequestModel(modelId, flags); + return; + } + + strcpy(oldName, mi->GetName()); + mi->SetName(modelName); + + // What exactly is going on here? + if(CModelInfo::GetModelInfo(oldName, nil)){ + txdId = CTxdStore::FindTxdSlot(oldName); + if(txdId != -1 && CTxdStore::GetSlot(txdId)->texDict){ + CTxdStore::AddRef(txdId); + RemoveModel(modelId); + CTxdStore::RemoveRefWithoutDelete(txdId); + }else + RemoveModel(modelId); + }else + RemoveModel(modelId); + + ms_pExtraObjectsDir->FindItem(modelName, pos, size); + mi->ClearTexDictionary(); + if(CTxdStore::FindTxdSlot(modelName) == -1) + mi->SetTexDictionary("generic"); + else + mi->SetTexDictionary(modelName); + ms_aInfoForModel[modelId].SetCdPosnAndSize(pos, size); + RequestModel(modelId, flags); +} + +void +CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags) +{ + RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags); +} + +void +CStreaming::RemoveModel(int32 id) +{ + int i; + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED) + return; + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ + if(id < STREAM_OFFSET_TXD) + CModelInfo::GetModelInfo(id - STREAM_OFFSET_MODEL)->DeleteRwObject(); + else + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; + } + + if(ms_aInfoForModel[id].m_next){ + // Remove from list, model is neither loaded nor requested + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_INQUEUE){ + ms_numModelsRequested--; + if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_PRIORITY){ + ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_PRIORITY; + ms_numPriorityRequests--; + } + } + ms_aInfoForModel[id].RemoveFromList(); + }else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_READING){ + for(i = 0; i < 4; i++){ + if(ms_channel[0].modelIds[i] == id - STREAM_OFFSET_MODEL) + ms_channel[0].modelIds[i] = -1; + if(ms_channel[1].modelIds[i] == id - STREAM_OFFSET_MODEL) + ms_channel[1].modelIds[i] = -1; + } + } + + if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){ + if(id < STREAM_OFFSET_TXD) + RpClumpGtaCancelStream(); + else + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + } + + ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; +} + + void CStreaming::ImGonnaUseStreamingMemory(void) { @@ -338,6 +762,15 @@ STARTPATCHES InjectHook(0x406C80, CStreaming::Shutdown, PATCH_JUMP); InjectHook(0x406CC0, (void (*)(void))CStreaming::LoadCdDirectory, PATCH_JUMP); InjectHook(0x406DA0, (void (*)(const char*, int))CStreaming::LoadCdDirectory, PATCH_JUMP); + InjectHook(0x409740, CStreaming::ConvertBufferToObject, PATCH_JUMP); + InjectHook(0x409580, CStreaming::FinishLoadingLargeFile, PATCH_JUMP); + InjectHook(0x407EA0, CStreaming::RequestModel, PATCH_JUMP); + InjectHook(0x407FD0, CStreaming::RequestSubway, PATCH_JUMP); + InjectHook(0x408190, CStreaming::RequestBigBuildings, PATCH_JUMP); + InjectHook(0x408210, CStreaming::RequestIslands, PATCH_JUMP); + InjectHook(0x40A890, CStreaming::RequestSpecialModel, PATCH_JUMP); + InjectHook(0x40ADA0, CStreaming::RequestSpecialChar, PATCH_JUMP); + InjectHook(0x408830, CStreaming::RemoveModel, PATCH_JUMP); InjectHook(0x4063E0, &CStreamingInfo::GetCdPosnAndSize, PATCH_JUMP); InjectHook(0x406410, &CStreamingInfo::SetCdPosnAndSize, PATCH_JUMP); diff --git a/src/Streaming.h b/src/Streaming.h index f31faf9c..ef51f54a 100644 --- a/src/Streaming.h +++ b/src/Streaming.h @@ -13,6 +13,9 @@ enum StreamFlags STREAMFLAGS_DEPENDENCY = 0x04, STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, + + STREAMFLAGS_NOT_IN_LIST = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, + STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY, }; enum StreamLoadState @@ -21,7 +24,7 @@ enum StreamLoadState STREAMSTATE_LOADED = 1, STREAMSTATE_INQUEUE = 2, STREAMSTATE_READING = 3, // what is this? - STREAMSTATE_BIGFILE = 4, + STREAMSTATE_STARTED = 4, // first part read }; enum ChannelState @@ -96,10 +99,21 @@ public: static void Init(void); static void Shutdown(void); static void LoadCdDirectory(void); - static void LoadCdDirectory(const char *dirname, int n); - - static void RemoveModel(int32 id); + static void LoadCdDirectory(const char *dirname, int32 n); + static bool ConvertBufferToObject(int8 *buf, int32 streamId); + static bool FinishLoadingLargeFile(int8 *buf, int32 streamId); static void RequestModel(int32 model, int32 flags); + static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); } + static void RequestSubway(void); + static void RequestBigBuildings(eLevelName level); + static void RequestIslands(eLevelName level); + static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); + static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); + static void RemoveModel(int32 id); + + static bool IsTxdUsedByRequestedModels(int32 txdId); + static bool AddToLoadedVehiclesList(int32 modelId); + static void MakeSpaceFor(int32 size); static void ImGonnaUseStreamingMemory(void); static void IHaveUsedStreamingMemory(void); diff --git a/src/patcher.h b/src/patcher.h index 4ac1111b..43618b47 100644 --- a/src/patcher.h +++ b/src/patcher.h @@ -101,6 +101,15 @@ Nop(AT address, unsigned int nCount) VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]); } +template inline void +ClearCC(AT address, unsigned int nCount) +{ + DWORD dwProtect[2]; + VirtualProtect((void*)address, nCount, PAGE_EXECUTE_READWRITE, &dwProtect[0]); + memset((void*)address, 0xCC, nCount); + VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]); +} + template inline void InjectHook(AT address, HT hook, unsigned int nType=PATCH_NOTHING) { -- cgit v1.2.3