diff --git a/src/control/Record.cpp b/src/control/Record.cpp index ab0b478c..7c330311 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -7,6 +7,7 @@ uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24; uint8 &CRecordDataForChase::Status = *(uint8*)0x95CDCE; WRAPPER void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4341F0); } +WRAPPER void CRecordDataForGame::Init(void) { EAXJMP(0x4340F0); } WRAPPER void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4347F0); } WRAPPER void CRecordDataForChase::ProcessControlCars(void) { EAXJMP(0x435540); } @@ -15,3 +16,4 @@ WRAPPER void CRecordDataForChase::StartChaseScene(float) { EAXJMP(0x435690); } WRAPPER void CRecordDataForChase::CleanUpChaseScene() { EAXJMP(0x4357C0); } WRAPPER void CRecordDataForChase::RemoveCarFromChase(int32) { EAXJMP(0x435BC0); } WRAPPER CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32) { EAXJMP(0x435C00); } +WRAPPER void CRecordDataForChase::Init(void) { EAXJMP(0x434780); } diff --git a/src/control/Record.h b/src/control/Record.h index f36c2718..e52a623e 100644 --- a/src/control/Record.h +++ b/src/control/Record.h @@ -20,6 +20,7 @@ public: static void CleanUpChaseScene(); static void RemoveCarFromChase(int32); static CVehicle* TurnChaseCarIntoScriptCar(int32); + static void Init(void); }; @@ -29,4 +30,5 @@ public: static uint16 &RecordingState; static void SaveOrRetrieveDataForThisFrame(void); + static void Init(void); }; diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp index 287b3c98..28b4ea6c 100644 --- a/src/control/SceneEdit.cpp +++ b/src/control/SceneEdit.cpp @@ -3,3 +3,4 @@ #include "SceneEdit.h" WRAPPER void CSceneEdit::Update(void) { EAXJMP(0x585570); } +WRAPPER void CSceneEdit::Init(void) { EAXJMP(0x585170); } diff --git a/src/control/SceneEdit.h b/src/control/SceneEdit.h index f44b0011..e9209b90 100644 --- a/src/control/SceneEdit.h +++ b/src/control/SceneEdit.h @@ -4,4 +4,5 @@ class CSceneEdit { public: static void Update(void); + static void Init(void); }; diff --git a/src/core/Debug.cpp b/src/core/Debug.cpp new file mode 100644 index 00000000..b80e9959 --- /dev/null +++ b/src/core/Debug.cpp @@ -0,0 +1,12 @@ +#include "Debug.h" + +int CDebug::ms_nCurrentTextLine; + +void CDebug::DebugInitTextBuffer() +{ + ms_nCurrentTextLine = 0; +} + +void CDebug::DebugDisplayTextBuffer() +{ +} diff --git a/src/core/Debug.h b/src/core/Debug.h new file mode 100644 index 00000000..395f66af --- /dev/null +++ b/src/core/Debug.h @@ -0,0 +1,11 @@ +#pragma once + +class CDebug +{ + static int ms_nCurrentTextLine; + +public: + static void DebugInitTextBuffer(); + static void DebugDisplayTextBuffer(); + +}; diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 08751cf9..e89d62a0 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -12,10 +12,13 @@ #include "Clock.h" #include "Clouds.h" #include "Collision.h" +#include "Console.h" #include "Coronas.h" #include "Cranes.h" +#include "Credits.h" #include "CutsceneMgr.h" #include "Darkel.h" +#include "Debug.h" #include "EventList.h" #include "FileLoader.h" #include "FileMgr.h" @@ -27,6 +30,8 @@ #include "Garages.h" #include "Glass.h" #include "Heli.h" +#include "IniFile.h" +#include "Messages.h" #include "Pad.h" #include "Particle.h" #include "Phones.h" @@ -36,14 +41,18 @@ #include "Record.h" #include "Renderer.h" #include "Replay.h" +#include "Restart.h" #include "RoadBlocks.h" +#include "PedRoutes.h" #include "Rubbish.h" +#include "RwHelper.h" #include "SceneEdit.h" #include "Script.h" #include "Shadows.h" #include "Skidmarks.h" #include "SpecialFX.h" #include "Sprite2d.h" +#include "Stats.h" #include "Streaming.h" #include "TimeCycle.h" #include "TrafficLights.h" @@ -51,7 +60,9 @@ #include "TxdStore.h" #include "User.h" #include "WaterCannon.h" +#include "WaterLevel.h" #include "Weapon.h" +#include "WeaponEffects.h" #include "Weather.h" #include "World.h" #include "ZoneCull.h" @@ -76,7 +87,151 @@ CGame::InitialiseOnceBeforeRW(void) return true; } -WRAPPER void CGame::Initialise(const char *datFile) { EAXJMP(0x48BED0); } +int &gameTxdSlot = *(int*)0x628D88; + +bool CGame::Initialise(const char* datFile) +{ + ResetLoadingScreenBar(); + strcpy(aDatFile, datFile); + CPools::Initialise(); + CIniFile::LoadIniFile(); + currLevel = LEVEL_INDUSTRIAL; + LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); + gameTxdSlot = CTxdStore::AddTxdSlot("generic"); + CTxdStore::Create(gameTxdSlot); + CTxdStore::AddRef(gameTxdSlot); + LoadingScreen("Loading the Game", "Loading particles", nil); + int particleTxdSlot = CTxdStore::AddTxdSlot("particle"); + CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD"); + CTxdStore::AddRef(particleTxdSlot); + CTxdStore::SetCurrentTxd(gameTxdSlot); + LoadingScreen("Loading the Game", "Setup game variables", nil); + CGameLogic::InitAtStartOfGame(); + CReferences::Init(); + TheCamera.Init(); + TheCamera.SetRwCamera(Scene.camera); + CDebug::DebugInitTextBuffer(); + ThePaths.Init(); + ThePaths.AllocatePathFindInfoMem(4500); + CWeather::Init(); + CCullZones::Init(); + CCollision::Init(); + CTheZones::Init(); + CUserDisplay::Init(); + CMessages::Init(); + CMessages::ClearAllMessagesDisplayedByGame(); + CRecordDataForGame::Init(); + CRestart::Initialise(); + CWorld::Initialise(); + CParticle::Initialise(); + CAnimManager::Initialise(); + CCutsceneMgr::Initialise(); + CCarCtrl::Init(); + InitModelIndices(); + CModelInfo::Initialise(); + CPickups::Init(); + CTheCarGenerators::Init(); + CdStreamAddImage("MODELS\\GTA3.IMG"); + CFileLoader::LoadLevel("DATA\\DEFAULT.DAT"); + CFileLoader::LoadLevel(datFile); + CWorld::AddParticles(); + CVehicleModelInfo::LoadVehicleColours(); + CVehicleModelInfo::LoadEnvironmentMaps(); + CTheZones::PostZoneCreation(); + LoadingScreen("Loading the Game", "Setup paths", GetRandomSplashScreen()); + ThePaths.PreparePathData(); + for (int i = 0; i < NUMPLAYERS; i++) + CWorld::Players[i].Clear(); + CWorld::Players[0].LoadPlayerSkin(); + TestModelIndices(); + LoadingScreen("Loading the Game", "Setup water", nil); + CWaterLevel::Initialise("DATA\\WATER.DAT"); + TheConsole.Init(); + CDraw::SetFOV(120.0f); + CDraw::ms_fLODDistance = 500.0f; + LoadingScreen("Loading the Game", "Setup streaming", nil); + int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r"); + if (txdHandle) + CFileMgr::CloseFile(txdHandle); + if (!CheckVideoCardCaps() && txdHandle) { + CdStreamAddImage("MODELS\\TXD.IMG"); + CStreaming::Init(); + } else { + CStreaming::Init(); + if (ConvertTextures()) { + CStreaming::Shutdown(); + CdStreamAddImage("MODELS\\TXD.IMG"); + CStreaming::Init(); + } + } + CStreaming::LoadInitialVehicles(); + CStreaming::LoadInitialPeds(); + CStreaming::RequestBigBuildings(LEVEL_NONE); + CStreaming::LoadAllRequestedModels(false); + printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024); + LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); + CAnimManager::LoadAnimFiles(); + CPed::Initialise(); + CRouteNode::Initialise(); + CEventList::Initialise(); + LoadingScreen("Loading the Game", "Find big buildings", nil); + CRenderer::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); + CRadar::Initialise(); + CRadar::LoadTextures(); + CWeapon::InitialiseWeapons(); + LoadingScreen("Loading the Game", "Setup traffic lights", nil); + CTrafficLights::ScanForLightsOnMap(); + CRoadBlocks::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); + CPopulation::Initialise(); + CWorld::PlayerInFocus = 0; + CCoronas::Init(); + CShadows::Init(); + CWeaponEffects::Init(); + CSkidmarks::Init(); + CAntennas::Init(); + CGlass::Init(); + gPhoneInfo.Initialise(); + CSceneEdit::Init(); + LoadingScreen("Loading the Game", "Load scripts", nil); + CTheScripts::Init(); + CGangs::Initialize(); + LoadingScreen("Loading the Game", "Setup game variables", nil); + CClock::Initialise(1000); + CHeli::InitHelis(); + CCranes::InitCranes(); + CMovingThings::Init(); + CDarkel::Init(); + CStats::Init(); + CPacManPickups::Init(); + CRubbish::Init(); + CClouds::Init(); + CSpecialFX::Init(); + CWaterCannons::Init(); + CBridge::Init(); + CGarages::Init(); + LoadingScreen("Loading the Game", "Position dynamic objects", nil); + CWorld::RepositionCertainDynamicObjects(); + LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); + CCullZones::ResolveVisibilities(); + CTrain::InitTrains(); + CPlane::InitPlanes(); + CCredits::Init(); + CRecordDataForChase::Init(); + CReplay::Init(); + LoadingScreen("Loading the Game", "Start script", nil); + CTheScripts::StartTestScript(); + CTheScripts::Process(); + TheCamera.Process(); + LoadingScreen("Loading the Game", "Load scene", nil); + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CCollision::ms_collisionInMemory = CGame::currLevel; + for (int i = 0; i < MAX_PADS; i++) + CPad::GetPad(i)->Clear(true); + return true; +} + #if 0 WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); } #else diff --git a/src/core/Game.h b/src/core/Game.h index dca38bdb..7b20099c 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -20,7 +20,7 @@ public: static bool &playingIntro; static char *aDatFile; //[32]; - static void Initialise(const char *datFile); + static bool Initialise(const char *datFile); static bool InitialiseOnceBeforeRW(void); static bool InitialiseRenderWare(void); static bool InitialiseOnceAfterRW(void); diff --git a/src/core/RwHelper.cpp b/src/core/RwHelper.cpp index 8dade266..1030d69e 100644 --- a/src/core/RwHelper.cpp +++ b/src/core/RwHelper.cpp @@ -347,6 +347,13 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) return (nil); } +WRAPPER void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&) { EAXJMP(0x5926C0); } +WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); } +WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); } +WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); } +WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); } +WRAPPER bool ConvertTextures() { EAXJMP(0x592C70); } + STARTPATCHES //InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP); InjectHook(0x526460, GetFirstObject, PATCH_JUMP); diff --git a/src/core/RwHelper.h b/src/core/RwHelper.h index ef20467d..1f0290cc 100644 --- a/src/core/RwHelper.h +++ b/src/core/RwHelper.h @@ -12,6 +12,12 @@ RwTexture *GetFirstTexture(RwTexDictionary *txd); RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream); RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream); RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict); +void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&); +bool CheckVideoCardCaps(void); +void WriteVideoCardCapsFile(void); +void ConvertingTexturesScreen(uint32, uint32, const char*); +void DealWithTxdWriteError(uint32, uint32, const char*); +bool ConvertTextures(); // not a real name bool RpClumpGtaStreamRead1(RwStream *stream); RpClump *RpClumpGtaStreamRead2(RwStream *stream); diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 1d088e04..93eeb759 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -135,3 +135,5 @@ void CStats::SetTotalNumberMissions(int32 total) { TotalNumberMissions = total; } + +WRAPPER void CStats::Init() { EAXJMP(0x4AAC60); } \ No newline at end of file diff --git a/src/core/Stats.h b/src/core/Stats.h index 4bf99c45..0a750d5e 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -74,4 +74,6 @@ public: static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; }; static void RegisterElBurroTime(int32); static void SaveStats(uint8 *buf, uint32 *size); + + static void Init(void); }; diff --git a/src/core/World.cpp b/src/core/World.cpp index f6106bb5..cbceb292 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -27,7 +27,7 @@ uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64; CColPoint &CWorld::ms_testSpherePoint = *(CColPoint*)0x6E64C0; uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61; -CPlayerInfo *CWorld::Players = (CPlayerInfo *)0x9412F0; +CPlayerInfo (&CWorld::Players)[NUMPLAYERS] = *(CPlayerInfo (*)[NUMPLAYERS])*(uintptr*)0x9412F0; bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC; CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494; bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F; @@ -38,6 +38,7 @@ bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B; bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C; bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA; +WRAPPER void CWorld::AddParticles(void) { EAXJMP(0x4B4010); } WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); } WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); } WRAPPER void CWorld::RemoveStaticObjects() { EAXJMP(0x4B4D50); } diff --git a/src/core/World.h b/src/core/World.h index 12582d49..1ad65ac4 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -63,7 +63,7 @@ public: static CColPoint& ms_testSpherePoint; static uint8 &PlayerInFocus; - static CPlayerInfo *Players; + static CPlayerInfo (&Players)[NUMPLAYERS]; static CEntity *&pIgnoreEntity; static bool &bIncludeDeadPeds; static bool &bNoMoreCollisionTorque; @@ -134,6 +134,7 @@ public: static void ExtinguishAllCarFiresInArea(CVector, float); static void Initialise(); + static void AddParticles(); static void ShutDown(); static void RepositionCertainDynamicObjects(); static void RemoveStaticObjects(); diff --git a/src/core/config.h b/src/core/config.h index 468e8468..9235e744 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -1,6 +1,8 @@ #pragma once enum Config { + NUMPLAYERS = 1, + NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC) MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, diff --git a/src/core/main.cpp b/src/core/main.cpp index 6043074f..2a15e20e 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -49,6 +49,7 @@ #include "Frontend.h" #include "AnimViewer.h" #include "Script.h" +#include "Debug.h" #include "Console.h" #define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f))) @@ -324,7 +325,7 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 void DoRWStuffEndOfFrame(void) { - // CDebug::DebugDisplayTextBuffer(); + CDebug::DebugDisplayTextBuffer(); // FlushObrsPrintfs(); RwCameraEndUpdate(Scene.camera); RsCameraShowRaster(Scene.camera); @@ -725,6 +726,12 @@ DestroySplashScreen(void) float NumberOfChunksLoaded; #define TOTALNUMCHUNKS 73.0f +void +ResetLoadingScreenBar() +{ + NumberOfChunksLoaded = 0.0f; +} + // TODO: compare with PS2 void LoadingScreen(const char *str1, const char *str2, const char *splashscreen) @@ -792,12 +799,6 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) } } -void -ResetLoadingScreenBar(void) -{ - NumberOfChunksLoaded = 0.0f; -} - void LoadingIslandScreen(const char *levelName) { diff --git a/src/core/main.h b/src/core/main.h index d6724d2b..570189b3 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -32,6 +32,7 @@ char *GetLevelSplashScreen(int level); char *GetRandomSplashScreen(void); void LittleTest(void); void ValidateVersion(); +void ResetLoadingScreenBar(void); #ifndef MASTER void TheModelViewer(void); #endif diff --git a/src/peds/PedRoutes.cpp b/src/peds/PedRoutes.cpp index 9b7dafd4..3bc17002 100644 --- a/src/peds/PedRoutes.cpp +++ b/src/peds/PedRoutes.cpp @@ -5,6 +5,15 @@ CRouteNode (&gaRoutes)[NUMPEDROUTES] = *(CRouteNode(*)[NUMPEDROUTES]) * (uintptr*)0x62E090; +void +CRouteNode::Initialise() +{ + for (int i = 0; i < NUMPEDROUTES; i++) { + gaRoutes[i].m_route = -1; + gaRoutes[i].m_pos = CVector(0.0f, 0.0f, 0.0f); + } +} + int16 CRouteNode::GetRouteThisPointIsOn(int16 point) { diff --git a/src/peds/PedRoutes.h b/src/peds/PedRoutes.h index d313938a..c478e38d 100644 --- a/src/peds/PedRoutes.h +++ b/src/peds/PedRoutes.h @@ -11,4 +11,5 @@ public: static int16 GetRouteStart(int16); static void AddRoutePoint(int16, CVector); static void RemoveRoute(int16); -}; \ No newline at end of file + static void Initialise(void); +}; diff --git a/src/render/Console.cpp b/src/render/Console.cpp index 898f4d44..d4940955 100644 --- a/src/render/Console.cpp +++ b/src/render/Console.cpp @@ -1,95 +1,95 @@ -#include "common.h" -#include "patcher.h" -#include "Console.h" -#include "Font.h" -#include "Timer.h" - -#define CONSOLE_X_POS (30.0f) -#define CONSOLE_Y_POS (10.0f) -#define CONSOLE_LINE_HEIGHT (12.0f) - -CConsole &TheConsole = *(CConsole*)0x8F6498; - -void -CConsole::AddLine(char *s, uint8 r, uint8 g, uint8 b) -{ - char tempstr[MAX_STR_LEN+1]; - - while (strlen(s) > MAX_STR_LEN) { - strncpy_s(tempstr, s, MAX_STR_LEN); - tempstr[MAX_STR_LEN-1] = '\0'; - s += MAX_STR_LEN - 1; - AddOneLine(tempstr, r, g, b); - } - AddOneLine(s, r, g, b); -} - -void -CConsole::AddOneLine(char *s, uint8 r, uint8 g, uint8 b) -{ - int32 StrIndex = (m_nLineCount + m_nCurrentLine) % MAX_LINES; - - for (int32 i = 0; i < MAX_STR_LEN; i++) { - Buffers[StrIndex][i] = s[i]; - if (s[i] == '\0') break; - } - - uint8 _strNum1 = m_nLineCount; - if (_strNum1 < MAX_LINES) - _strNum1++; - - m_aTimer[StrIndex] = CTimer::GetTimeInMilliseconds(); - Buffers[StrIndex][MAX_STR_LEN-1] = '\0'; - m_aRed[StrIndex] = r; - m_aGreen[StrIndex] = g; - m_aBlue[StrIndex] = b; - - if (_strNum1 >= MAX_LINES) - m_nCurrentLine = (m_nCurrentLine + 1) % MAX_LINES; - else - m_nLineCount = _strNum1; - -} - -void -CConsole::Display() -{ - CFont::SetPropOn(); - CFont::SetBackgroundOff(); - CFont::SetScale(0.6f, 0.6f); - CFont::SetCentreOff(); - CFont::SetRightJustifyOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyWrap(0.0f); - CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_BANK); -#ifndef FIX_BUGS - CFont::SetPropOff(); // not sure why this is here anyway -#endif - CFont::SetWrapx(RsGlobal.width); - - while (m_nLineCount != 0 && CTimer::GetTimeInMilliseconds() - m_aTimer[m_nCurrentLine] > 20000) { - m_nLineCount--; - m_nCurrentLine = (m_nCurrentLine + 1) % MAX_LINES; - } - - for (int16 i = 0; i < m_nLineCount; i++) { - int16 line = (i + m_nCurrentLine) % MAX_LINES; - CFont::SetColor(CRGBA(0, 0, 0, 200)); - CFont::PrintString(CONSOLE_X_POS + 1.0f, CONSOLE_Y_POS + 1.0f + i * CONSOLE_LINE_HEIGHT, Buffers[line]); - CFont::SetColor(CRGBA(m_aRed[line], m_aGreen[line], m_aBlue[line], 200)); - CFont::PrintString(CONSOLE_X_POS, CONSOLE_Y_POS + i * CONSOLE_LINE_HEIGHT, Buffers[line]); - } -} - -void -cprintf(char* format, ...) -{ - char s[256]; - va_list vl1, vl2; - - va_start(vl1, format); - va_copy(vl2, vl1); - vsprintf(s, format, vl1); - TheConsole.AddLine(s, 255, 255, 128); -} \ No newline at end of file +#include "common.h" +#include "patcher.h" +#include "Console.h" +#include "Font.h" +#include "Timer.h" + +#define CONSOLE_X_POS (30.0f) +#define CONSOLE_Y_POS (10.0f) +#define CONSOLE_LINE_HEIGHT (12.0f) + +CConsole &TheConsole = *(CConsole*)0x8F6498; + +void +CConsole::AddLine(char *s, uint8 r, uint8 g, uint8 b) +{ + char tempstr[MAX_STR_LEN+1]; + + while (strlen(s) > MAX_STR_LEN) { + strncpy_s(tempstr, s, MAX_STR_LEN); + tempstr[MAX_STR_LEN-1] = '\0'; + s += MAX_STR_LEN - 1; + AddOneLine(tempstr, r, g, b); + } + AddOneLine(s, r, g, b); +} + +void +CConsole::AddOneLine(char *s, uint8 r, uint8 g, uint8 b) +{ + int32 StrIndex = (m_nLineCount + m_nCurrentLine) % MAX_LINES; + + for (int32 i = 0; i < MAX_STR_LEN; i++) { + Buffers[StrIndex][i] = s[i]; + if (s[i] == '\0') break; + } + + uint8 _strNum1 = m_nLineCount; + if (_strNum1 < MAX_LINES) + _strNum1++; + + m_aTimer[StrIndex] = CTimer::GetTimeInMilliseconds(); + Buffers[StrIndex][MAX_STR_LEN-1] = '\0'; + m_aRed[StrIndex] = r; + m_aGreen[StrIndex] = g; + m_aBlue[StrIndex] = b; + + if (_strNum1 >= MAX_LINES) + m_nCurrentLine = (m_nCurrentLine + 1) % MAX_LINES; + else + m_nLineCount = _strNum1; + +} + +void +CConsole::Display() +{ + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + CFont::SetScale(0.6f, 0.6f); + CFont::SetCentreOff(); + CFont::SetRightJustifyOff(); + CFont::SetJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_BANK); +#ifndef FIX_BUGS + CFont::SetPropOff(); // not sure why this is here anyway +#endif + CFont::SetWrapx(RsGlobal.width); + + while (m_nLineCount != 0 && CTimer::GetTimeInMilliseconds() - m_aTimer[m_nCurrentLine] > 20000) { + m_nLineCount--; + m_nCurrentLine = (m_nCurrentLine + 1) % MAX_LINES; + } + + for (int16 i = 0; i < m_nLineCount; i++) { + int16 line = (i + m_nCurrentLine) % MAX_LINES; + CFont::SetColor(CRGBA(0, 0, 0, 200)); + CFont::PrintString(CONSOLE_X_POS + 1.0f, CONSOLE_Y_POS + 1.0f + i * CONSOLE_LINE_HEIGHT, Buffers[line]); + CFont::SetColor(CRGBA(m_aRed[line], m_aGreen[line], m_aBlue[line], 200)); + CFont::PrintString(CONSOLE_X_POS, CONSOLE_Y_POS + i * CONSOLE_LINE_HEIGHT, Buffers[line]); + } +} + +void +cprintf(char* format, ...) +{ + char s[256]; + va_list vl1, vl2; + + va_start(vl1, format); + va_copy(vl2, vl1); + vsprintf(s, format, vl1); + TheConsole.AddLine(s, 255, 255, 128); +} diff --git a/src/render/Console.h b/src/render/Console.h index eb84c1a5..c454d75e 100644 --- a/src/render/Console.h +++ b/src/render/Console.h @@ -1,24 +1,25 @@ -#pragma once - -class CConsole -{ - enum - { - MAX_LINES = 8, // BUG? only shows 7 - MAX_STR_LEN = 40, - }; - - uint8 m_nLineCount; - uint8 m_nCurrentLine; - wchar Buffers[MAX_LINES][MAX_STR_LEN]; - uint32 m_aTimer[MAX_LINES]; - uint8 m_aRed[MAX_LINES]; - uint8 m_aGreen[MAX_LINES]; - uint8 m_aBlue[MAX_LINES]; -public: - void AddLine(char *s, uint8 r, uint8 g, uint8 b); - void AddOneLine(char *s, uint8 r, uint8 g, uint8 b); - void Display(); -}; - -extern CConsole &TheConsole; \ No newline at end of file +#pragma once + +class CConsole +{ + enum + { + MAX_LINES = 8, // BUG? only shows 7 + MAX_STR_LEN = 40, + }; + + uint8 m_nLineCount; + uint8 m_nCurrentLine; + wchar Buffers[MAX_LINES][MAX_STR_LEN]; + uint32 m_aTimer[MAX_LINES]; + uint8 m_aRed[MAX_LINES]; + uint8 m_aGreen[MAX_LINES]; + uint8 m_aBlue[MAX_LINES]; +public: + void AddLine(char *s, uint8 r, uint8 g, uint8 b); + void AddOneLine(char *s, uint8 r, uint8 g, uint8 b); + void Display(); + void Init() { m_nCurrentLine = 0; m_nLineCount = 0; } +}; + +extern CConsole &TheConsole; diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp index 5d7dcc86..ac04032b 100644 --- a/src/render/Glass.cpp +++ b/src/render/Glass.cpp @@ -18,3 +18,4 @@ CGlass::WindowRespondsToSoftCollision(CEntity *ent, float amount) WRAPPER void CGlass::Render(void) { EAXJMP(0x502350); } WRAPPER void CGlass::Update(void) { EAXJMP(0x502050); } +WRAPPER void CGlass::Init(void) { EAXJMP(0x501F20); } diff --git a/src/render/Glass.h b/src/render/Glass.h index b29cf173..ad4d50f2 100644 --- a/src/render/Glass.h +++ b/src/render/Glass.h @@ -10,4 +10,5 @@ public: static void WindowRespondsToSoftCollision(CEntity *ent, float amount); static void Render(void); static void Update(void); + static void Init(void); }; diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp index 5fa695ea..c336eb47 100644 --- a/src/render/Rubbish.cpp +++ b/src/render/Rubbish.cpp @@ -6,3 +6,4 @@ 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); } diff --git a/src/render/Rubbish.h b/src/render/Rubbish.h index 7ed0978b..c94ff303 100644 --- a/src/render/Rubbish.h +++ b/src/render/Rubbish.h @@ -9,4 +9,5 @@ public: static void StirUp(CVehicle *veh); // CAutomobile on PS2 static void Update(void); static void SetVisibility(bool); + static void Init(void); }; diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp index 7489f7cd..deb5a648 100644 --- a/src/render/Skidmarks.cpp +++ b/src/render/Skidmarks.cpp @@ -7,3 +7,5 @@ WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); } 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); } + +WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); } diff --git a/src/render/Skidmarks.h b/src/render/Skidmarks.h index e5372136..2f669575 100644 --- a/src/render/Skidmarks.h +++ b/src/render/Skidmarks.h @@ -7,4 +7,5 @@ public: 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); }; diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 18ef0017..8ec2d9a1 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -19,6 +19,7 @@ WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); } WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } +WRAPPER void CSpecialFX::Init(void) { EAXJMP(0x5189E0); } WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); } diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index ecd3ad87..701b89a0 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -5,6 +5,7 @@ class CSpecialFX public: static void Render(void); static void Update(void); + static void Init(void); }; class CMotionBlurStreaks diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index 81d91480..7a9aa4d9 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -7,3 +7,4 @@ CWaterCannon (&aCannons)[NUM_WATERCANNONS] = *(CWaterCannon(*)[NUM_WATERCANNONS] WRAPPER void CWaterCannons::Update(void) { EAXJMP(0x522510); } WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); } WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); } +WRAPPER void CWaterCannons::Init(void) { EAXJMP(0x522440); } diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h index 1d072f0c..c2b288f2 100644 --- a/src/render/WaterCannon.h +++ b/src/render/WaterCannon.h @@ -20,6 +20,7 @@ public: static void Update(); static void UpdateOne(uint32 id, CVector *pos, CVector *dir); static void Render(void); + static void Init(void); }; extern CWaterCannon (&aCannons)[NUM_WATERCANNONS]; diff --git a/src/render/WeaponEffects.cpp b/src/render/WeaponEffects.cpp index 11fb3d2e..932c661e 100644 --- a/src/render/WeaponEffects.cpp +++ b/src/render/WeaponEffects.cpp @@ -2,6 +2,8 @@ #include "patcher.h" #include "WeaponEffects.h" +#include "TxdStore.h" + WRAPPER void CWeaponEffects::Render(void) { EAXJMP(0x564D70); } CWeaponEffects &gCrossHair = *(CWeaponEffects*)0x6503BC; @@ -23,3 +25,21 @@ CWeaponEffects::MarkTarget(CVector pos, uint8 red, uint8 green, uint8 blue, uint gCrossHair.m_alpha = alpha; gCrossHair.m_size = size; } + +void +CWeaponEffects::Init() +{ + gCrossHair.m_bCrosshair = false; + gCrossHair.m_vecPos = CVector(0.0f, 0.0f, 0.0f); + gCrossHair.m_red = 0; + gCrossHair.m_green = 0; + gCrossHair.m_blue = 0; + gCrossHair.m_alpha = 255; + gCrossHair.m_size = 1.0f; + gCrossHair.field_24 = 0; + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); + gCrossHair.m_pTexture = RwTextureRead("crosshair", nil); + gCrossHair.m_pRaster = gCrossHair.m_pTexture->raster; + CTxdStore::PopCurrentTxd(); +} diff --git a/src/render/WeaponEffects.h b/src/render/WeaponEffects.h index 6edcd60b..e4d0461a 100644 --- a/src/render/WeaponEffects.h +++ b/src/render/WeaponEffects.h @@ -19,4 +19,5 @@ public: static void Render(void); static void ClearCrossHair(); static void MarkTarget(CVector, uint8, uint8, uint8, uint8, float); + static void Init(void); }; diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 479f3404..c1988ab4 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -34,6 +34,7 @@ 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); } void CWeather::ReleaseWeather() { diff --git a/src/render/Weather.h b/src/render/Weather.h index b5704b01..63def9b9 100644 --- a/src/render/Weather.h +++ b/src/render/Weather.h @@ -39,6 +39,7 @@ public: static void RenderRainStreaks(void); static void Update(void); + static void Init(void); static void ReleaseWeather(); static void ForceWeather(int16);