implemented splashes; fixed zones

This commit is contained in:
aap 2019-06-01 23:17:39 +02:00
parent c40c7acb96
commit b63c87e8a6
14 changed files with 241 additions and 91 deletions

View File

@ -5,6 +5,8 @@
int &CGame::currLevel = *(int*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
bool &CGame::frenchGame = *(bool*)0x95CDCB;
bool &CGame::germanGame = *(bool*)0x95CD1E;
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
WRAPPER Bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }

View File

@ -14,6 +14,8 @@ public:
static int &currLevel;
static bool &bDemoMode;
static bool &nastyGame;
static bool &frenchGame;
static bool &germanGame;
static void Process(void);
static Bool InitialiseOnceBeforeRW(void);

View File

@ -5,7 +5,7 @@
#include "Messages.h"
#include "Text.h"
static wchar_t WideErrorString[25];
static wchar WideErrorString[25];
CText &TheText = *(CText*)0x941520;
@ -90,7 +90,7 @@ CText::Unload(void)
keyArray.Unload();
}
wchar_t*
wchar*
CText::Get(const char *key)
{
return keyArray.Search(key);
@ -119,11 +119,11 @@ CKeyArray::Unload(void)
}
void
CKeyArray::Update(wchar_t *chars)
CKeyArray::Update(wchar *chars)
{
int i;
for(i = 0; i < numEntries; i++)
entries[i].value = (wchar_t*)((uint8*)chars + (uintptr)entries[i].value);
entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value);
}
CKeyEntry*
@ -146,7 +146,7 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi
return nil;
}
wchar_t*
wchar*
CKeyArray::Search(const char *key)
{
CKeyEntry *found;
@ -169,8 +169,8 @@ CData::Load(uint32 length, uint8 *data, int *offset)
uint32 i;
uint8 *rawbytes;
numChars = length / sizeof(wchar_t);
chars = new wchar_t[numChars];
numChars = length / sizeof(wchar);
chars = new wchar[numChars];
rawbytes = (uint8*)chars;
for(i = 0; i < length; i++)
@ -185,6 +185,12 @@ CData::Unload(void)
numChars = 0;
}
void
AsciiToUnicode(const char *cs, uint16 *ws)
{
while((*ws++ = *cs++) != '\0');
}
STARTPATCHES
InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);

View File

@ -1,8 +1,10 @@
#pragma once
void AsciiToUnicode(const char *cs, wchar *ws);
struct CKeyEntry
{
wchar_t *value;
wchar *value;
char key[8];
};
// If this fails, CKeyArray::Load will have to be fixed
@ -16,15 +18,15 @@ public:
void Load(uint32 length, uint8 *data, int *offset);
void Unload(void);
void Update(wchar_t *chars);
void Update(wchar *chars);
CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high);
wchar_t *Search(const char *key);
wchar *Search(const char *key);
};
class CData
{
public:
wchar_t *chars;
wchar *chars;
int numChars;
void Load(uint32 length, uint8 *data, int *offset);
@ -41,7 +43,7 @@ public:
~CText(void);
void Load(void);
void Unload(void);
wchar_t *Get(const char *key);
wchar *Get(const char *key);
};
extern CText &TheText;

View File

@ -19,6 +19,26 @@ CZoneInfo *CTheZones::ZoneInfoArray = (CZoneInfo*)0x714400;
#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
static void
CheckZoneInfo(CZoneInfo *info)
{
assert(info->carThreshold[0] >= 0);
assert(info->carThreshold[0] <= info->carThreshold[1]);
assert(info->carThreshold[1] <= info->carThreshold[2]);
assert(info->carThreshold[2] <= info->carThreshold[3]);
assert(info->carThreshold[3] <= info->carThreshold[4]);
assert(info->carThreshold[4] <= info->carThreshold[5]);
assert(info->carThreshold[5] <= info->copThreshold);
assert(info->copThreshold <= info->gangThreshold[0]);
assert(info->gangThreshold[0] <= info->gangThreshold[1]);
assert(info->gangThreshold[1] <= info->gangThreshold[2]);
assert(info->gangThreshold[2] <= info->gangThreshold[3]);
assert(info->gangThreshold[3] <= info->gangThreshold[4]);
assert(info->gangThreshold[4] <= info->gangThreshold[5]);
assert(info->gangThreshold[5] <= info->gangThreshold[6]);
assert(info->gangThreshold[6] <= info->gangThreshold[7]);
assert(info->gangThreshold[7] <= info->gangThreshold[8]);
}
void
CTheZones::Init(void)
@ -49,6 +69,7 @@ CTheZones::Init(void)
zonei->gangThreshold[6] = zonei->gangThreshold[5];
zonei->gangThreshold[7] = zonei->gangThreshold[6];
zonei->gangThreshold[8] = zonei->gangThreshold[7];
CheckZoneInfo(zonei);
}
TotalNumberOfZoneInfos = 1; // why 1?
@ -361,11 +382,11 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
if(CClock::GetIsTimeInRange(19, 22)){
n = (CClock::GetHours() - 19) / 3.0f;
assert(n >= 0.0f && n <= 1.0f);
d = n - 1.0f;
d = 1.0f - n;
}else{
d = (CClock::GetHours() - 5) / 3.0f;
assert(d >= 0.0f && d <= 1.0f);
n = d - 1.0f;
n = 1.0f - d;
}
info->carDensity = day->carDensity * d + night->carDensity * n;
info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n;
@ -402,28 +423,9 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
else
info->pedGroup = night->pedGroup;
assert(info->carDensity >= 0);
assert(info->carThreshold[0] >= 0);
assert(info->carThreshold[1] >= 0);
assert(info->carThreshold[2] >= 0);
assert(info->carThreshold[3] >= 0);
assert(info->carThreshold[4] >= 0);
assert(info->carThreshold[5] >= 0);
assert(info->copThreshold >= 0);
assert(info->gangThreshold[0] >= 0);
assert(info->gangThreshold[1] >= 0);
assert(info->gangThreshold[2] >= 0);
assert(info->gangThreshold[3] >= 0);
assert(info->gangThreshold[4] >= 0);
assert(info->gangThreshold[5] >= 0);
assert(info->gangThreshold[6] >= 0);
assert(info->gangThreshold[7] >= 0);
assert(info->gangThreshold[8] >= 0);
CheckZoneInfo(info);
}
// BUG: there might be a bug somewhere in there that causes
// thresholds to become negative so CCarCtrl::ChooseModel will hang
void
CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
int16 gang0Num, int16 gang1Num, int16 gang2Num,
@ -438,6 +440,8 @@ CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
zone = GetZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
CheckZoneInfo(info);
if(carDensity != -1) info->carDensity = carDensity;
int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0];
int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1];
@ -455,22 +459,6 @@ CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6];
int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7];
assert(oldCar1Num >= 0);
assert(oldCar2Num >= 0);
assert(oldCar3Num >= 0);
assert(oldCar4Num >= 0);
assert(oldCar5Num >= 0);
assert(oldCopNum >= 0);
assert(oldGang0Num >= 0);
assert(oldGang1Num >= 0);
assert(oldGang2Num >= 0);
assert(oldGang3Num >= 0);
assert(oldGang4Num >= 0);
assert(oldGang5Num >= 0);
assert(oldGang6Num >= 0);
assert(oldGang7Num >= 0);
assert(oldGang8Num >= 0);
if(car0Num != -1) info->carThreshold[0] = car0Num;
if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num;
else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num;
@ -503,23 +491,7 @@ CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num;
else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num;
assert(info->carDensity >= 0);
assert(info->carThreshold[0] >= 0);
assert(info->carThreshold[1] >= 0);
assert(info->carThreshold[2] >= 0);
assert(info->carThreshold[3] >= 0);
assert(info->carThreshold[4] >= 0);
assert(info->carThreshold[5] >= 0);
assert(info->copThreshold >= 0);
assert(info->gangThreshold[0] >= 0);
assert(info->gangThreshold[1] >= 0);
assert(info->gangThreshold[2] >= 0);
assert(info->gangThreshold[3] >= 0);
assert(info->gangThreshold[4] >= 0);
assert(info->gangThreshold[5] >= 0);
assert(info->gangThreshold[6] >= 0);
assert(info->gangThreshold[7] >= 0);
assert(info->gangThreshold[8] >= 0);
CheckZoneInfo(info);
}
void
@ -534,15 +506,15 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
if(pedDensity != -1) info->pedDensity = pedDensity;
if(copDensity != -1) info->copDensity = copDensity;
if(gang0Density != -1) info->gangThreshold[0] = gang0Density;
if(gang1Density != -1) info->gangThreshold[1] = gang1Density;
if(gang2Density != -1) info->gangThreshold[2] = gang2Density;
if(gang3Density != -1) info->gangThreshold[3] = gang3Density;
if(gang4Density != -1) info->gangThreshold[4] = gang4Density;
if(gang5Density != -1) info->gangThreshold[5] = gang5Density;
if(gang6Density != -1) info->gangThreshold[6] = gang6Density;
if(gang7Density != -1) info->gangThreshold[7] = gang7Density;
if(gang8Density != -1) info->gangThreshold[8] = gang8Density;
if(gang0Density != -1) info->gangDensity[0] = gang0Density;
if(gang1Density != -1) info->gangDensity[1] = gang1Density;
if(gang2Density != -1) info->gangDensity[2] = gang2Density;
if(gang3Density != -1) info->gangDensity[3] = gang3Density;
if(gang4Density != -1) info->gangDensity[4] = gang4Density;
if(gang5Density != -1) info->gangDensity[5] = gang5Density;
if(gang6Density != -1) info->gangDensity[6] = gang6Density;
if(gang7Density != -1) info->gangDensity[7] = gang7Density;
if(gang8Density != -1) info->gangDensity[8] = gang8Density;
}
void

View File

@ -33,10 +33,10 @@ class CZoneInfo
{
public:
// Car data
uint16 carDensity;
uint16 carThreshold[6];
uint16 copThreshold;
uint16 gangThreshold[9];
int16 carDensity;
int16 carThreshold[6];
int16 copThreshold;
int16 gangThreshold[9];
// Ped data
uint16 pedDensity;

View File

@ -40,12 +40,13 @@ typedef int32_t int32, Int32;
typedef uintptr_t uintptr;
typedef uint64_t uint64, UInt64;
typedef int64_t int64, Int64;
// hardcode ucs-2
typedef uint16_t wchar, WChar;
typedef float Float;
typedef double Double;
typedef bool Bool;
typedef char Char;
typedef wchar_t WChar;
#define nil NULL

View File

@ -59,3 +59,5 @@ enum Config {
#define GTA3_1_1_PATCH FALSE
#define USE_PS2_RAND FALSE
#define RANDOMSPLASH
#define CHATTYSPLASH

View File

@ -39,6 +39,9 @@
#include "Credits.h"
#include "CullZones.h"
#include "TimeCycle.h"
#include "TxdStore.h"
#include "FileMgr.h"
#include "Text.h"
#include "Frontend.h"
#define DEFAULT_VIEWWINDOW (tan(CDraw::GetFOV() * (360.0f / PI)))
@ -72,6 +75,10 @@ void RenderMenus(void);
void DoFade(void);
void Render2dStuffAfterFade(void);
CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
extern void (*DebugMenuProcess)(void);
extern void (*DebugMenuRender)(void);
@ -182,6 +189,30 @@ FrontendIdle(void)
DoRWStuffEndOfFrame();
}
bool
DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha)
{
CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha);
CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha);
float viewWindow = tan(DEGTORAD(CDraw::GetFOV() * 0.5f));
// ASPECT
float aspectRatio = CMenuManager::m_PrefsUseWideScreen ? 16.0f/9.0f : 4.0f/3.0f;
CameraSize(Scene.camera, nil, viewWindow, aspectRatio);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
CSprite2d::InitPerFrame();
if(Alpha != 0)
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREENW, SCREENH), BottomColor, BottomColor, TopColor, TopColor);
return true;
}
bool
DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha)
{
@ -361,7 +392,7 @@ DoFade(void)
}
if(CDraw::FadeValue != 0 || CMenuManager::m_PrefsBrightness < 256){
// LoadSplash
CSprite2d *splash = LoadSplash(nil);
CRGBA fadeColor;
CRect rect;
@ -411,7 +442,7 @@ DoFade(void)
fadeColor.g = 255;
fadeColor.b = 255;
fadeColor.a = CDraw::FadeValue;
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREENW, SCREENH), fadeColor, fadeColor, fadeColor, fadeColor);
splash->Draw(CRect(0.0f, 0.0f, SCREENW, SCREENH), fadeColor, fadeColor, fadeColor, fadeColor);
}
}
}
@ -423,6 +454,130 @@ Render2dStuffAfterFade(void)
CFont::DrawFonts();
}
CSprite2d splash;
int splashTxdId = -1;
CSprite2d*
LoadSplash(const char *name)
{
RwTexDictionary *txd;
char filename[140];
RwTexture *tex = nil;
if(name == nil)
return &splash;
if(splashTxdId == -1)
splashTxdId = CTxdStore::AddTxdSlot("splash");
txd = CTxdStore::GetSlot(splashTxdId)->texDict;
if(txd)
tex = RwTexDictionaryFindNamedTexture(txd, name);
// if texture is found, splash was already set up below
if(tex == nil){
CFileMgr::SetDir("TXD\\");
sprintf(filename, "%s.txd", name);
if(splash.m_pTexture)
splash.Delete();
if(txd)
CTxdStore::RemoveTxd(splashTxdId);
CTxdStore::LoadTxd(splashTxdId, filename);
CTxdStore::AddRef(splashTxdId);
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(splashTxdId);
splash.SetTexture(name);
CTxdStore::PopCurrentTxd();
CFileMgr::SetDir("");
}
return &splash;
}
void
DestroySplashScreen(void)
{
splash.Delete();
if(splashTxdId != -1)
CTxdStore::RemoveTxdSlot(splashTxdId);
splashTxdId = -1;
}
float NumberOfChunksLoaded;
#define TOTALNUMCHUNKS 73.0f
// TODO: compare with PS2
void
LoadingScreen(char *str1, char *str2, char *splashscreen)
{
CSprite2d *splash;
#ifndef RANDOMSPLASH
if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
splashscreen = "mainsc2";
else
splashscreen = "mainsc1";
#endif
splash = LoadSplash(splashscreen);
if(RsGlobal.quit)
return;
if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
splash->Draw(CRect(0.0f, 0.0f, SCREENW, SCREENH), CRGBA(255, 255, 255, 255));
if(str1){
NumberOfChunksLoaded += 1;
float hpos = SCREEN_STRETCH_X(40);
float length = SCREENW - SCREEN_STRETCH_X(100);
float vpos = SCREENH - SCREEN_STRETCH_Y(13);
float height = SCREEN_STRETCH_Y(7);
CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255));
length *= NumberOfChunksLoaded/TOTALNUMCHUNKS;
CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255));
// this is done by the game but is unused
CFont::SetScale(SCREEN_STRETCH_X(2), SCREEN_STRETCH_Y(2));
CFont::SetPropOn();
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
#ifdef CHATTYSPLASH
// my attempt
static wchar tmpstr[80];
float scale = SCREEN_STRETCH_Y(0.8f);
vpos -= 50*scale;
CFont::SetScale(scale, scale);
CFont::SetPropOn();
CFont::SetRightJustifyOff();
CFont::SetFontStyle(FONT_BANK);
CFont::SetColor(CRGBA(255, 255, 255, 255));
AsciiToUnicode(str1, tmpstr);
CFont::PrintString(hpos, vpos, tmpstr);
vpos += 25*scale;
AsciiToUnicode(str2, tmpstr);
CFont::PrintString(hpos, vpos, tmpstr);
#endif
}
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
}
void
ResetLoadingScreenBar(void)
{
NumberOfChunksLoaded = 0.0f;
}
#include "rwcore.h"
#include "rpworld.h"
#include "rpmatfx.h"
@ -590,6 +745,7 @@ STARTPATCHES
InjectHook(0x48E480, Idle, PATCH_JUMP);
InjectHook(0x48E700, FrontendIdle, PATCH_JUMP);
InjectHook(0x48CF10, DoRWStuffStartOfFrame, PATCH_JUMP);
InjectHook(0x48D040, DoRWStuffStartOfFrame_Horizon, PATCH_JUMP);
InjectHook(0x48E030, RenderScene, PATCH_JUMP);
InjectHook(0x48E080, RenderDebugShit, PATCH_JUMP);
@ -599,6 +755,11 @@ STARTPATCHES
InjectHook(0x48D120, DoFade, PATCH_JUMP);
InjectHook(0x48E470, Render2dStuffAfterFade, PATCH_JUMP);
InjectHook(0x48D550, LoadSplash, PATCH_JUMP);
InjectHook(0x48D670, DestroySplashScreen, PATCH_JUMP);
InjectHook(0x48D770, LoadingScreen, PATCH_JUMP);
InjectHook(0x48D760, ResetLoadingScreenBar, PATCH_JUMP);
InjectHook(0x48D470, PluginAttach, PATCH_JUMP);
InjectHook(0x48D520, Initialise3D, PATCH_JUMP);
InjectHook(0x48D540, Terminate3D, PATCH_JUMP);

View File

@ -61,6 +61,8 @@ int (*open_script_orig)(const char *path, const char *mode);
int
open_script(const char *path, const char *mode)
{
if(GetAsyncKeyState('G') & 0x8000)
return open_script_orig("main.scm", mode);
if(GetAsyncKeyState('D') & 0x8000)
return open_script_orig("main_d.scm", mode);
// if(GetAsyncKeyState('R') & 0x8000)

View File

@ -37,7 +37,7 @@ CCredits::PrintCreditSpace(float space, uint32 &line)
}
void
CCredits::PrintCreditText(float scaleX, float scaleY, wchar_t *text, uint32 &lineoffset, float scrolloffset)
CCredits::PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset)
{
float start = SCREENH + 50.0f;
float y = lineoffset + start - scrolloffset;

View File

@ -11,5 +11,5 @@ public:
static bool AreCreditsDone(void) { return bCreditsGoing; }
static void Render(void);
static void PrintCreditSpace(float space, uint32 &line);
static void PrintCreditText(float scaleX, float scaleY, wchar_t *text, uint32 &lineoffset, float scrolloffset);
static void PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset);
};

View File

@ -78,7 +78,7 @@ CSprite2d::Delete(void)
}
void
CSprite2d::SetTexture(char *name)
CSprite2d::SetTexture(const char *name)
{
Delete();
if(name)
@ -86,7 +86,7 @@ CSprite2d::SetTexture(char *name)
}
void
CSprite2d::SetTexture(char *name, char *mask)
CSprite2d::SetTexture(const char *name, const char *mask)
{
Delete();
if(name)
@ -468,8 +468,8 @@ STARTPATCHES
InjectHook(0x51EA00, &CSprite2d::Delete, PATCH_JUMP);
InjectHook(0x51F950, &CSprite2d::SetRenderState, PATCH_JUMP);
InjectHook(0x51EA40, (void (CSprite2d::*)(char*))&CSprite2d::SetTexture, PATCH_JUMP);
InjectHook(0x51EA70, (void (CSprite2d::*)(char*,char*))&CSprite2d::SetTexture, PATCH_JUMP);
InjectHook(0x51EA40, (void (CSprite2d::*)(const char*))&CSprite2d::SetTexture, PATCH_JUMP);
InjectHook(0x51EA70, (void (CSprite2d::*)(const char*,const char*))&CSprite2d::SetTexture, PATCH_JUMP);
InjectHook(0x51EAA0, &CSprite2d::SetAddressing, PATCH_JUMP);
InjectHook(0x51EE90, (void (*)(const CRect&, C4, uint32))CSprite2d::SetVertices, PATCH_JUMP);

View File

@ -23,8 +23,8 @@ public:
~CSprite2d(void) { Delete(); };
void Delete(void);
void SetRenderState(void);
void SetTexture(char *name);
void SetTexture(char *name, char *mask);
void SetTexture(const char *name);
void SetTexture(const char *name, const char *mask);
void SetAddressing(RwTextureAddressMode addr);
void Draw(float x, float y, float w, float h, const CRGBA &col);
void Draw(const CRect &rect, const CRGBA &col);