diff --git a/README.md b/README.md index 114c5e19..d9121eff 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,6 @@ such that we have a working game at all times. ## Preparing the environment for building -Currently only building on VS2015/2017/2019 (Windows) and GCC (Linux) is tested. - - Clone the repo. - Run `git submodule init` and `git submodule update`. - Point GTA_III_RE_DIR environment variable to GTA3 root folder. diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index c6d7b5a4..b814d58c 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -1623,7 +1623,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil { case WHEEL_STATE_SPINNING: if (gasPedalAudio > 0.4f) - relativeVelChange = (gasPedalAudio - 0.4f) * 1.6666666f * 0.75f; + relativeVelChange = (gasPedalAudio - 0.4f) * (5.0f / 3.0f) / (4.0f / 3.0f); break; case WHEEL_STATE_SKIDDING: relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); @@ -1631,7 +1631,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil case WHEEL_STATE_FIXED: relativeVel = gasPedalAudio; if (relativeVel > 0.4f) - relativeVel = (gasPedalAudio - 0.4f) * 1.6666666f; + relativeVel = (gasPedalAudio - 0.4f) * (5.0f / 3.0f); velChange = Abs(velocityChange); if (velChange > 0.04f) @@ -2662,7 +2662,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params) return true; velocityChange = Min(0.75f, velocityChange); - multiplier = (velocityChange - 0.0005f) * 1.3342f; + multiplier = (velocityChange - 0.0005f) / (1499.0f / 2000.0f); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); vol = (30.f * multiplier); m_sQueueSample.m_nVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance); @@ -2783,7 +2783,7 @@ cAudioManager::ProcessJumbo(cVehicleParams *params) DoJumboVolOffset(); position = PlanePathPosition[plane->m_nPlaneId]; if (position <= TakeOffPoint) { - if (plane->m_fSpeed <= 0.10334f) { + if (plane->m_fSpeed <= 0.103344f) { ProcessJumboTaxi(); return; } @@ -2795,7 +2795,7 @@ cAudioManager::ProcessJumbo(cVehicleParams *params) ProcessJumboFlying(); } else { if (position > LandingPoint) { - if (plane->m_fSpeed > 0.10334f) { + if (plane->m_fSpeed > 0.103344f) { ProcessJumboDecel(plane); return; } @@ -2825,7 +2825,7 @@ cAudioManager::ProcessJumboAccel(CPlane *plane) float modificator; if (SetupJumboFlySound(20)) { - modificator = (plane->m_fSpeed - 0.10334f) * 1.676f; + modificator = (plane->m_fSpeed - 0.103344f) * 1.6760077f; if (modificator > 1.0f) modificator = 1.0f; if (SetupJumboRumbleSound(MAX_VOLUME * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) { @@ -2878,7 +2878,7 @@ void cAudioManager::ProcessJumboDecel(CPlane *plane) { if (SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { - const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f); + const float modificator = Min(1.f, (plane->m_fSpeed - 0.103344f) * 1.6760077f); SetupJumboEngineSound(MAX_VOLUME * modificator, 6050.f * modificator + 16000); SetupJumboWhineSound(18, 29500); } diff --git a/src/core/Game.cpp b/src/core/Game.cpp index b5ba5b69..de5881b5 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -151,6 +151,10 @@ CGame::InitialiseOnceBeforeRW(void) return true; } +#if !defined(LIBRW) && defined(PS2_MATFX) +void ReplaceMatFxCallback(); +#endif + bool CGame::InitialiseRenderWare(void) { @@ -201,6 +205,8 @@ CGame::InitialiseRenderWare(void) #else rw::MatFX::modulateEnvMap = false; #endif +#elif defined(PS2_MATFX) + ReplaceMatFxCallback(); #endif CFont::Initialise(); diff --git a/src/core/patcher.cpp b/src/core/patcher.cpp deleted file mode 100644 index 83e06886..00000000 --- a/src/core/patcher.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#define WITHWINDOWS -#include "common.h" -#include "patcher.h" - -#include -#include - -StaticPatcher *StaticPatcher::ms_head; - -StaticPatcher::StaticPatcher(Patcher func) - : m_func(func) -{ - m_next = ms_head; - ms_head = this; -} - -void -StaticPatcher::Apply() -{ - StaticPatcher *current = ms_head; - while(current){ - current->Run(); - current = current->m_next; - } - ms_head = nil; -} -#ifdef _WIN32 -std::vector usedAddresses; - -static DWORD protect[2]; -static uint32 protect_address; -static uint32 protect_size; - -void -Protect_internal(uint32 address, uint32 size) -{ - protect_address = address; - protect_size = size; - VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &protect[0]); -} - -void -Unprotect_internal(void) -{ - VirtualProtect((void*)protect_address, protect_size, protect[0], &protect[1]); -} - -void -InjectHook_internal(uint32 address, uint32 hook, int type) -{ - if(std::any_of(usedAddresses.begin(), usedAddresses.end(), - [address](uint32 value) { return value == address; })) { - debug("Used address %#06x twice when injecting hook\n", address); - } - - usedAddresses.push_back(address); - - - switch(type){ - case PATCH_JUMP: - VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]); - *(uint8*)address = 0xE9; - break; - case PATCH_CALL: - VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]); - *(uint8*)address = 0xE8; - break; - default: - VirtualProtect((void*)(address + 1), 4, PAGE_EXECUTE_READWRITE, &protect[0]); - break; - } - - *(ptrdiff_t*)(address + 1) = hook - address - 5; - if(type == PATCH_NOTHING) - VirtualProtect((void*)(address + 1), 4, protect[0], &protect[1]); - else - VirtualProtect((void*)address, 5, protect[0], &protect[1]); -} -#else -void -Protect_internal(uint32 address, uint32 size) -{ -} - -void -Unprotect_internal(void) -{ -} - -void -InjectHook_internal(uint32 address, uint32 hook, int type) -{ -} -#endif diff --git a/src/core/patcher.h b/src/core/patcher.h deleted file mode 100644 index 2722b6fd..00000000 --- a/src/core/patcher.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#define WRAPPER __declspec(naked) -#define DEPRECATED __declspec(deprecated) -#define EAXJMP(a) { _asm mov eax, a _asm jmp eax } -#define VARJMP(a) { _asm jmp a } -#define WRAPARG(a) UNREFERENCED_PARAMETER(a) - -#include //memset - -enum -{ - PATCH_CALL, - PATCH_JUMP, - PATCH_NOTHING, -}; - -enum -{ - III_10 = 1, - III_11, - III_STEAM, - VC_10, - VC_11, - VC_STEAM -}; - -extern int gtaversion; - -class StaticPatcher -{ -private: - using Patcher = void(*)(); - - Patcher m_func; - StaticPatcher *m_next; - static StaticPatcher *ms_head; - - void Run() { m_func(); } -public: - StaticPatcher(Patcher func); - static void Apply(); -}; - -template -inline T AddressByVersion(uint32_t addressIII10, uint32_t addressIII11, uint32_t addressIIISteam, uint32_t addressvc10, uint32_t addressvc11, uint32_t addressvcSteam) -{ - if(gtaversion == -1){ - if(*(uint32_t*)0x5C1E75 == 0xB85548EC) gtaversion = III_10; - else if(*(uint32_t*)0x5C2135 == 0xB85548EC) gtaversion = III_11; - else if(*(uint32_t*)0x5C6FD5 == 0xB85548EC) gtaversion = III_STEAM; - else if(*(uint32_t*)0x667BF5 == 0xB85548EC) gtaversion = VC_10; - else if(*(uint32_t*)0x667C45 == 0xB85548EC) gtaversion = VC_11; - else if(*(uint32_t*)0x666BA5 == 0xB85548EC) gtaversion = VC_STEAM; - else gtaversion = 0; - } - switch(gtaversion){ - case III_10: - return (T)addressIII10; - case III_11: - return (T)addressIII11; - case III_STEAM: - return (T)addressIIISteam; - case VC_10: - return (T)addressvc10; - case VC_11: - return (T)addressvc11; - case VC_STEAM: - return (T)addressvcSteam; - default: - return (T)0; - } -} - -inline bool -is10(void) -{ - return gtaversion == III_10 || gtaversion == VC_10; -} - -inline bool -isIII(void) -{ - return gtaversion >= III_10 && gtaversion <= III_STEAM; -} - -inline bool -isVC(void) -{ - return gtaversion >= VC_10 && gtaversion <= VC_STEAM; -} - -#define PTRFROMCALL(addr) (uint32_t)(*(uint32_t*)((uint32_t)addr+1) + (uint32_t)addr + 5) -#define INTERCEPT(saved, func, a) \ -{ \ - saved = PTRFROMCALL(a); \ - InjectHook(a, func); \ -} - -void InjectHook_internal(uint32 address, uint32 hook, int type); -void Protect_internal(uint32 address, uint32 size); -void Unprotect_internal(void); - -template inline void -Patch(AT address, T value) -{ - Protect_internal((uint32)address, sizeof(T)); - *(T*)address = value; - Unprotect_internal(); -} - -template inline void -Nop(AT address, unsigned int nCount) -{ - Protect_internal((uint32)address, nCount); - memset((void*)address, 0x90, nCount); - Unprotect_internal(); -} - -template inline void -InjectHook(uintptr_t address, T hook, unsigned int nType = PATCH_NOTHING) -{ - InjectHook_internal(address, reinterpret_cast((void *&)hook), nType); -} - -inline void ExtractCall(void *dst, uint32_t a) -{ - *(uint32_t*)dst = (uint32_t)(*(uint32_t*)(a+1) + a + 5); -} -template -inline void InterceptCall(void *dst, T func, uint32_t a) -{ - ExtractCall(dst, a); - InjectHook(a, func); -} -template -inline void InterceptVmethod(void *dst, T func, uint32_t a) -{ - *(uint32_t*)dst = *(uint32_t*)a; - Patch(a, func); -} - -#define STARTPATCHES static StaticPatcher Patcher([](){ -#define ENDPATCHES }); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index f7a895c3..81b2bfc0 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -2,7 +2,6 @@ #define WITHWINDOWS #include "common.h" #include "crossplatform.h" -#include "patcher.h" #include "Renderer.h" #include "Occlusion.h" #include "Credits.h" diff --git a/src/rw/RwMatFX.cpp b/src/rw/RwMatFX.cpp index 1e64c560..3533eb24 100644 --- a/src/rw/RwMatFX.cpp +++ b/src/rw/RwMatFX.cpp @@ -2,9 +2,8 @@ #define WITHD3D #include "common.h" -#ifdef RWLIBS -#include "patcher.h" -#endif +#include "rwcore.h" +#include "rpmatfx.h" struct MatFXNothing { int pad[5]; int effect; }; @@ -47,16 +46,16 @@ struct MatFX int effects; }; -#ifdef RWLIBS extern "C" { extern int MatFXMaterialDataOffset; extern int MatFXAtomicDataOffset; + void _rpMatFXD3D8AtomicMatFXEnvRender(RxD3D8InstanceData* inst, int flags, int sel, RwTexture* texture, RwTexture* envMap); + void _rpMatFXD3D8AtomicMatFXRenderBlack(RxD3D8InstanceData *inst); + void _rpMatFXD3D8AtomicMatFXBumpMapRender(RxD3D8InstanceData *inst, int flags, RwTexture *texture, RwTexture *bumpMap, RwTexture *envMap); + void _rpMatFXD3D8AtomicMatFXDualPassRender(RxD3D8InstanceData *inst, int flags, RwTexture *texture, RwTexture *dualTexture); } -#else -int &MatFXMaterialDataOffset = *(int*)0x66188C; -int &MatFXAtomicDataOffset = *(int*)0x66189C; -#endif + #ifdef PS2_MATFX @@ -218,12 +217,96 @@ _rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int se RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); } -#ifdef RWLIBS -STARTPATCHES - InjectHook((uintptr)&_rpMatFXD3D8AtomicMatFXEnvRender, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP); -ENDPATCHES -#endif +void +_rwD3D8EnableClippingIfNeeded(void *object, RwUInt8 type) +{ + int clip; + if (type == rpATOMIC) + clip = !RwD3D8CameraIsSphereFullyInsideFrustum(RwCameraGetCurrentCameraMacro(), RpAtomicGetWorldBoundingSphere((RpAtomic *)object)); + else + clip = !RwD3D8CameraIsBBoxFullyInsideFrustum(RwCameraGetCurrentCameraMacro(), &((RpWorldSector *)object)->tightBoundingBox); + RwD3D8SetRenderState(D3DRS_CLIPPING, clip); +} -#endif +void +_rwD3D8AtomicMatFXRenderCallback(RwResEntry *repEntry, void *object, RwUInt8 type, RwUInt32 flags) +{ + RwBool lighting; + RwBool forceBlack; + RxD3D8ResEntryHeader *header; + RxD3D8InstanceData *inst; + RwInt32 i; -#endif + if (flags & rpGEOMETRYPRELIT) { + RwD3D8SetRenderState(D3DRS_COLORVERTEX, 1); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + } else { + RwD3D8SetRenderState(D3DRS_COLORVERTEX, 0); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + } + + _rwD3D8EnableClippingIfNeeded(object, type); + + RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting); + if (lighting || flags & rpGEOMETRYPRELIT) { + forceBlack = FALSE; + } else { + forceBlack = TRUE; + RwD3D8SetTexture(nil, 0); + RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(0, 0, 0, 255)); + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + } + + header = (RxD3D8ResEntryHeader *)(repEntry + 1); + inst = (RxD3D8InstanceData *)(header + 1); + for (i = 0; i < header->numMeshes; i++) { + if (forceBlack) + _rpMatFXD3D8AtomicMatFXRenderBlack(inst); + else { + if (lighting) + RwD3D8SetSurfaceProperties(&inst->material->color, &inst->material->surfaceProps, flags & rpGEOMETRYMODULATEMATERIALCOLOR); + MatFX *matfx = *RWPLUGINOFFSET(MatFX *, inst->material, MatFXMaterialDataOffset); + int effect = matfx ? matfx->effects : rpMATFXEFFECTNULL; + switch (effect) { + case rpMATFXEFFECTNULL: + default: + _rpMatFXD3D8AtomicMatFXDefaultRender(inst, flags, inst->material->texture); + break; + case rpMATFXEFFECTBUMPMAP: + _rpMatFXD3D8AtomicMatFXBumpMapRender(inst, flags, inst->material->texture, matfx->fx[0].b.bumpedTex, nil); + break; + case rpMATFXEFFECTENVMAP: + { + // TODO: matfx switch in the settings + //_rpMatFXD3D8AtomicMatFXEnvRender(inst, flags, 0, inst->material->texture, matfx->fx[0].e.envTex); + _rpMatFXD3D8AtomicMatFXEnvRender_ps2(inst, flags, 0, inst->material->texture, matfx->fx[0].e.envTex); + break; + } + case rpMATFXEFFECTBUMPENVMAP: + _rpMatFXD3D8AtomicMatFXBumpMapRender(inst, flags, inst->material->texture, matfx->fx[0].b.bumpedTex, matfx->fx[1].e.envTex); + break; + case rpMATFXEFFECTDUAL: + _rpMatFXD3D8AtomicMatFXDualPassRender(inst, flags, inst->material->texture, matfx->fx[0].d.dualTex); + break; + } + } + inst++; + } + + if (forceBlack) { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } +} + +void +ReplaceMatFxCallback() +{ + RxD3D8AllInOneSetRenderCallBack( + RxPipelineFindNodeByName(RpMatFXGetD3D8Pipeline(rpMATFXD3D8ATOMICPIPELINE), RxNodeDefinitionGetD3D8AtomicAllInOne()->name, nil, nil), + _rwD3D8AtomicMatFXRenderCallback); +} +#endif // PS2_MATFX + +#endif // !LIBRW diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index f49f0d42..8b479681 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -16,7 +16,6 @@ #include "platform.h" #include "crossplatform.h" -#include "patcher.h" #include "main.h" #include "FileMgr.h" #include "Text.h" @@ -1383,7 +1382,6 @@ main(int argc, char *argv[]) #endif RwV2d pos; RwInt32 i; -// StaticPatcher::Apply(); #ifndef _WIN32 struct sigaction act; diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index cd75236c..93f9b8f2 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -76,7 +76,6 @@ static psGlobalType PsGlobal; {debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;} #include "common.h" -#include "patcher.h" #include "main.h" #include "FileMgr.h" #include "Text.h" @@ -1939,7 +1938,6 @@ WinMain(HINSTANCE instance, RwV2d pos; RwInt32 argc, i; RwChar **argv; - StaticPatcher::Apply(); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); // TODO: make this an option somewhere