From daceee593be76fe7d681e3b8c9101b02c058d186 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Sat, 11 Apr 2020 18:37:20 +0300 Subject: Link with RW libs --- src/rw/ClumpRead.cpp | 230 +++++++++++ src/rw/Lights.cpp | 333 ++++++++++++++++ src/rw/Lights.h | 18 + src/rw/NodeName.cpp | 77 ++++ src/rw/NodeName.h | 4 + src/rw/RwHelper.cpp | 374 ++++++++++++++++++ src/rw/RwHelper.h | 40 ++ src/rw/RwMatFX.cpp | 213 +++++++++++ src/rw/TexRead.cpp | 349 +++++++++++++++++ src/rw/TxdStore.cpp | 209 ++++++++++ src/rw/TxdStore.h | 44 +++ src/rw/VisibilityPlugins.cpp | 889 +++++++++++++++++++++++++++++++++++++++++++ src/rw/VisibilityPlugins.h | 133 +++++++ src/rw/rw.cpp | 839 ++++++++++++++++++++++++++++++++++++++++ 14 files changed, 3752 insertions(+) create mode 100644 src/rw/ClumpRead.cpp create mode 100644 src/rw/Lights.cpp create mode 100644 src/rw/Lights.h create mode 100644 src/rw/NodeName.cpp create mode 100644 src/rw/NodeName.h create mode 100644 src/rw/RwHelper.cpp create mode 100644 src/rw/RwHelper.h create mode 100644 src/rw/RwMatFX.cpp create mode 100644 src/rw/TexRead.cpp create mode 100644 src/rw/TxdStore.cpp create mode 100644 src/rw/TxdStore.h create mode 100644 src/rw/VisibilityPlugins.cpp create mode 100644 src/rw/VisibilityPlugins.h create mode 100644 src/rw/rw.cpp (limited to 'src/rw') diff --git a/src/rw/ClumpRead.cpp b/src/rw/ClumpRead.cpp new file mode 100644 index 00000000..c9f027e7 --- /dev/null +++ b/src/rw/ClumpRead.cpp @@ -0,0 +1,230 @@ +#include "common.h" +#include "patcher.h" + +struct rpGeometryList +{ + RpGeometry **geometries; + int32 numGeoms; +}; + +struct rpAtomicBinary +{ + RwInt32 frameIndex; + RwInt32 geomIndex; + RwInt32 flags; + RwInt32 unused; +}; + +static int32 numberGeometrys; +static int32 streamPosition; +static rpGeometryList gGeomList; +static rwFrameList gFrameList; +static RpClumpChunkInfo gClumpInfo; + +rpGeometryList* +GeometryListStreamRead1(RwStream *stream, rpGeometryList *geomlist) +{ + int i; + RwUInt32 size, version; + RwInt32 numGeoms; + + numberGeometrys = 0; + if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + return nil; + assert(size == 4); + if(RwStreamRead(stream, &numGeoms, 4) != 4) + return nil; + + numberGeometrys = numGeoms/2; + geomlist->numGeoms = numGeoms; + if(geomlist->numGeoms > 0){ + geomlist->geometries = (RpGeometry**)RwMalloc(geomlist->numGeoms * sizeof(RpGeometry*)); + if(geomlist->geometries == nil) + return nil; + memset(geomlist->geometries, 0, geomlist->numGeoms * sizeof(RpGeometry*)); + }else + geomlist->geometries = nil; + + for(i = 0; i < numberGeometrys; i++){ + if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version)) + return nil; + geomlist->geometries[i] = RpGeometryStreamRead(stream); + if(geomlist->geometries[i] == nil) + return nil; + } + + return geomlist; +} + +rpGeometryList* +GeometryListStreamRead2(RwStream *stream, rpGeometryList *geomlist) +{ + int i; + RwUInt32 version; + + for(i = numberGeometrys; i < geomlist->numGeoms; i++){ + if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version)) + return nil; + geomlist->geometries[i] = RpGeometryStreamRead(stream); + if(geomlist->geometries[i] == nil) + return nil; + } + + return geomlist; +} + +void +GeometryListDeinitialize(rpGeometryList *geomlist) +{ + int i; + + for(i = 0; i < geomlist->numGeoms; i++) + if(geomlist->geometries[i]) + RpGeometryDestroy(geomlist->geometries[i]); + + if(geomlist->numGeoms){ + RwFree(geomlist->geometries); + geomlist->numGeoms = 0; + } +} + +RpAtomic* +ClumpAtomicStreamRead(RwStream *stream, rwFrameList *frmList, rpGeometryList *geomList) +{ + RwUInt32 size, version; + rpAtomicBinary a; + RpAtomic *atomic; + + numberGeometrys = 0; + if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + return nil; + assert(size <= sizeof(rpAtomicBinary)); + if(RwStreamRead(stream, &a, size) != size) + return nil; + + atomic = RpAtomicCreate(); + if(atomic == nil) + return nil; + + RpAtomicSetFlags(atomic, a.flags); + + if(frmList->numFrames){ + assert(a.frameIndex < frmList->numFrames); + RpAtomicSetFrame(atomic, frmList->frames[a.frameIndex]); + } + + if(geomList->numGeoms){ + assert(a.geomIndex < geomList->numGeoms); + RpAtomicSetGeometry(atomic, geomList->geometries[a.geomIndex], 0); + }else{ + RpGeometry *geom; + if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version)){ + RpAtomicDestroy(atomic); + return nil; + } + geom = RpGeometryStreamRead(stream); + if(geom == nil){ + RpAtomicDestroy(atomic); + return nil; + } + RpAtomicSetGeometry(atomic, geom, 0); + RpGeometryDestroy(geom); + } + + return atomic; +} + +bool +RpClumpGtaStreamRead1(RwStream *stream) +{ + RwUInt32 size, version; + + if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + return false; + if(version >= 0x33000){ + assert(size == 12); + if(RwStreamRead(stream, &gClumpInfo, 12) != 12) + return false; + }else{ + assert(size == 4); + if(RwStreamRead(stream, &gClumpInfo, 4) != 4) + return false; + } + + if(!RwStreamFindChunk(stream, rwID_FRAMELIST, nil, &version)) + return false; + if(_rwFrameListStreamRead(stream, &gFrameList) == nil) + return false; + + if(!RwStreamFindChunk(stream, rwID_GEOMETRYLIST, nil, &version)){ + rwFrameListDeinitialize(&gFrameList); + return false; + } + if(GeometryListStreamRead1(stream, &gGeomList) == nil){ + rwFrameListDeinitialize(&gFrameList); + return false; + } + streamPosition = stream->Type.memory.position; + return true; +} + +RpClump* +RpClumpGtaStreamRead2(RwStream *stream) +{ + int i; + RwUInt32 version; + RpAtomic *atomic; + RpClump *clump; + + clump = RpClumpCreate(); + if(clump == nil) + return nil; + + RwStreamSkip(stream, streamPosition - stream->Type.memory.position); + + if(GeometryListStreamRead2(stream, &gGeomList) == nil){ + GeometryListDeinitialize(&gGeomList); + rwFrameListDeinitialize(&gFrameList); + RpClumpDestroy(clump); + return nil; + } + + RpClumpSetFrame(clump, gFrameList.frames[0]); + + for(i = 0; i < gClumpInfo.numAtomics; i++){ + if(!RwStreamFindChunk(stream, rwID_ATOMIC, nil, &version)){ + GeometryListDeinitialize(&gGeomList); + rwFrameListDeinitialize(&gFrameList); + RpClumpDestroy(clump); + return nil; + } + + atomic = ClumpAtomicStreamRead(stream, &gFrameList, &gGeomList); + if(atomic == nil){ + GeometryListDeinitialize(&gGeomList); + rwFrameListDeinitialize(&gFrameList); + RpClumpDestroy(clump); + return nil; + } + + RpClumpAddAtomic(clump, atomic); + } + + GeometryListDeinitialize(&gGeomList); + rwFrameListDeinitialize(&gFrameList); + return clump; +} + +void +RpClumpGtaCancelStream(void) +{ + GeometryListDeinitialize(&gGeomList); + rwFrameListDeinitialize(&gFrameList); + gFrameList.numFrames = 0; +} + +STARTPATCHES + InjectHook(0x526060, RpClumpGtaStreamRead1, PATCH_JUMP); + InjectHook(0x526180, RpClumpGtaStreamRead2, PATCH_JUMP); + InjectHook(0x5262D0, RpClumpGtaCancelStream, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp new file mode 100644 index 00000000..cd83a898 --- /dev/null +++ b/src/rw/Lights.cpp @@ -0,0 +1,333 @@ +#include "common.h" +#include +#include +#include "patcher.h" +#include "Lights.h" +#include "Timecycle.h" +#include "Coronas.h" +#include "Weather.h" +#include "ZoneCull.h" +#include "Frontend.h" + +RpLight *&pAmbient = *(RpLight**)0x885B6C; +RpLight *&pDirect = *(RpLight**)0x880F7C; +RpLight **pExtraDirectionals = (RpLight**)0x60009C; +int *LightStrengths = (int*)0x87BEF0; +int &NumExtraDirLightsInWorld = *(int*)0x64C608; + +RwRGBAReal &AmbientLightColourForFrame = *(RwRGBAReal*)0x6F46F8; +RwRGBAReal &AmbientLightColourForFrame_PedsCarsAndObjects = *(RwRGBAReal*)0x6F1D10; +RwRGBAReal &DirectionalLightColourForFrame = *(RwRGBAReal*)0x87C6B8; + +RwRGBAReal &AmbientLightColour = *(RwRGBAReal*)0x86B0F8; +RwRGBAReal &DirectionalLightColour = *(RwRGBAReal*)0x72E308; + +void +SetLightsWithTimeOfDayColour(RpWorld *) +{ + CVector vec1, vec2, vecsun; + RwMatrix mat; + + if(pAmbient){ + AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed() * CCoronas::LightsMult; + AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen() * CCoronas::LightsMult; + AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult; + if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ + AmbientLightColourForFrame.red = 1.0f; + AmbientLightColourForFrame.green = 1.0f; + AmbientLightColourForFrame.blue = 1.0f; + } + AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame.red*1.3f); + AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame.green*1.3f); + AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame.blue*1.3f); + RpLightSetColor(pAmbient, &AmbientLightColourForFrame); + } + + if(pDirect){ + DirectionalLightColourForFrame.red = CTimeCycle::GetDirectionalRed() * CCoronas::LightsMult; + DirectionalLightColourForFrame.green = CTimeCycle::GetDirectionalGreen() * CCoronas::LightsMult; + DirectionalLightColourForFrame.blue = CTimeCycle::GetDirectionalBlue() * CCoronas::LightsMult; + RpLightSetColor(pDirect, &DirectionalLightColourForFrame); + + vecsun = CTimeCycle::m_VectorToSun[CTimeCycle::m_CurrentStoredValue]; + vec1 = CVector(0.0f, 0.0f, 1.0f); + vec2 = CrossProduct(vec1, vecsun); + vec2.Normalise(); + vec1 = CrossProduct(vec2, vecsun); + mat.at.x = -vecsun.x; + mat.at.y = -vecsun.y; + mat.at.z = -vecsun.z; + mat.right.x = vec1.x; + mat.right.y = vec1.y; + mat.right.z = vec1.z; + mat.up.x = vec2.x; + mat.up.y = vec2.y; + mat.up.z = vec2.z; + RwFrameTransform(RpLightGetFrame(pDirect), &mat, rwCOMBINEREPLACE); + } + + if(CMenuManager::m_PrefsBrightness > 256){ + float f1 = 2.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; + float f2 = 3.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; + + AmbientLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f2); + AmbientLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f2); + AmbientLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f2); + AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.red * f1); + AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.green * f1); + AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.blue * f1); +#ifdef FIX_BUGS + DirectionalLightColourForFrame.red = min(1.0f, DirectionalLightColourForFrame.red * f1); + DirectionalLightColourForFrame.green = min(1.0f, DirectionalLightColourForFrame.green * f1); + DirectionalLightColourForFrame.blue = min(1.0f, DirectionalLightColourForFrame.blue * f1); +#else + DirectionalLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f1); + DirectionalLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f1); + DirectionalLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f1); +#endif + } +} + +RpWorld* +LightsCreate(RpWorld *world) +{ + int i; + RwRGBAReal color; + RwFrame *frame; + + if(world == nil) + return nil; + + pAmbient = RpLightCreate(rpLIGHTAMBIENT); + RpLightSetFlags(pAmbient, rpLIGHTLIGHTATOMICS); + color.red = 0.25f; + color.green = 0.25f; + color.blue = 0.2f; + RpLightSetColor(pAmbient, &color); + + pDirect = RpLightCreate(rpLIGHTDIRECTIONAL); + RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS); + color.red = 1.0f; + color.green = 0.84f; + color.blue = 0.45f; + RpLightSetColor(pDirect, &color); + RpLightSetRadius(pDirect, 2.0f); + frame = RwFrameCreate(); + RpLightSetFrame(pDirect, frame); + RwV3d axis = { 1.0f, 1.0f, 0.0f }; + RwFrameRotate(frame, &axis, 160.0f, rwCOMBINEPRECONCAT); + + RpWorldAddLight(world, pAmbient); + RpWorldAddLight(world, pDirect); + + for(i = 0; i < NUMEXTRADIRECTIONALS; i++){ + pExtraDirectionals[i] = RpLightCreate(rpLIGHTDIRECTIONAL); + RpLightSetFlags(pExtraDirectionals[i], 0); + color.red = 1.0f; + color.green = 0.5f; + color.blue = 0.0f; + RpLightSetColor(pExtraDirectionals[i], &color); + RpLightSetRadius(pExtraDirectionals[i], 2.0f); + frame = RwFrameCreate(); + RpLightSetFrame(pExtraDirectionals[i], frame); + RpWorldAddLight(world, pExtraDirectionals[i]); + } + + return world; +} + +void +LightsDestroy(RpWorld *world) +{ + int i; + + if(world == nil) + return; + + if(pAmbient){ + RpWorldRemoveLight(world, pAmbient); + RpLightDestroy(pAmbient); + pAmbient = nil; + } + + if(pDirect){ + RpWorldRemoveLight(world, pDirect); + RwFrameDestroy(RpLightGetFrame(pDirect)); + RpLightDestroy(pDirect); + pDirect = nil; + } + + for(i = 0; i < NUMEXTRADIRECTIONALS; i++) + if(pExtraDirectionals[i]){ + RpWorldRemoveLight(world, pExtraDirectionals[i]); + RwFrameDestroy(RpLightGetFrame(pExtraDirectionals[i])); + RpLightDestroy(pExtraDirectionals[i]); + pExtraDirectionals[i] = nil; + } +} + +void +WorldReplaceNormalLightsWithScorched(RpWorld *world, float l) +{ + RwRGBAReal color; + color.red = l; + color.green = l; + color.blue = l; + RpLightSetColor(pAmbient, &color); + RpLightSetFlags(pDirect, 0); +} + +void +WorldReplaceScorchedLightsWithNormal(RpWorld *world) +{ + RpLightSetColor(pAmbient, &AmbientLightColourForFrame); + RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS); +} + +void +AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, float red, float green, float blue) +{ + float strength; + int weakest; + int i, n; + RwRGBAReal color; + RwV3d *dir; + + strength = max(max(red, green), blue); + n = -1; + if(NumExtraDirLightsInWorld < NUMEXTRADIRECTIONALS) + n = NumExtraDirLightsInWorld; + else{ + weakest = strength; + for(i = 0; i < NUMEXTRADIRECTIONALS; i++) + if(LightStrengths[i] < weakest){ + weakest = LightStrengths[i]; + n = i; + } + } + + if(n < 0) + return; + + color.red = red; + color.green = green; + color.blue = blue; + RpLightSetColor(pExtraDirectionals[n], &color); + dir = RwMatrixGetAt(RwFrameGetMatrix(RpLightGetFrame(pExtraDirectionals[n]))); + dir->x = -dirx; + dir->y = -diry; + dir->z = -dirz; + RwMatrixUpdate(RwFrameGetMatrix(RpLightGetFrame(pExtraDirectionals[n]))); + RwFrameUpdateObjects(RpLightGetFrame(pExtraDirectionals[n])); + RpLightSetFlags(pExtraDirectionals[n], rpLIGHTLIGHTATOMICS); + LightStrengths[n] = strength; + NumExtraDirLightsInWorld = min(NumExtraDirLightsInWorld+1, NUMEXTRADIRECTIONALS); +} + +void +RemoveExtraDirectionalLights(RpWorld *world) +{ + int i; + for(i = 0; i < NumExtraDirLightsInWorld; i++) + RpLightSetFlags(pExtraDirectionals[i], 0); + NumExtraDirLightsInWorld = 0; +} + +void +SetAmbientAndDirectionalColours(float f) +{ + AmbientLightColour.red = AmbientLightColourForFrame.red * f; + AmbientLightColour.green = AmbientLightColourForFrame.green * f; + AmbientLightColour.blue = AmbientLightColourForFrame.blue * f; + + DirectionalLightColour.red = DirectionalLightColourForFrame.red * f; + DirectionalLightColour.green = DirectionalLightColourForFrame.green * f; + DirectionalLightColour.blue = DirectionalLightColourForFrame.blue * f; + + RpLightSetColor(pAmbient, &AmbientLightColour); + RpLightSetColor(pDirect, &DirectionalLightColour); +} + +void +SetBrightMarkerColours(float f) +{ + AmbientLightColour.red = 0.6f; + AmbientLightColour.green = 0.6f; + AmbientLightColour.blue = 0.6f; + + DirectionalLightColour.red = (1.0f - DirectionalLightColourForFrame.red) * 0.4f + DirectionalLightColourForFrame.red; + DirectionalLightColour.green = (1.0f - DirectionalLightColourForFrame.green) * 0.4f + DirectionalLightColourForFrame.green; + DirectionalLightColour.blue = (1.0f - DirectionalLightColourForFrame.blue) * 0.4f + DirectionalLightColourForFrame.blue; + + RpLightSetColor(pAmbient, &AmbientLightColour); + RpLightSetColor(pDirect, &DirectionalLightColour); +} + +void +ReSetAmbientAndDirectionalColours(void) +{ + RpLightSetColor(pAmbient, &AmbientLightColourForFrame); + RpLightSetColor(pDirect, &DirectionalLightColourForFrame); +} + +void +DeActivateDirectional(void) +{ + RpLightSetFlags(pDirect, 0); +} + +void +ActivateDirectional(void) +{ + RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS); +} + +void +SetAmbientColours(void) +{ + RpLightSetColor(pAmbient, &AmbientLightColourForFrame); +} + +void +SetAmbientColoursForPedsCarsAndObjects(void) +{ + RpLightSetColor(pAmbient, &AmbientLightColourForFrame_PedsCarsAndObjects); +} + +uint8 IndicateR[] = { 0, 255, 0, 0, 255, 255, 0 }; +uint8 IndicateG[] = { 0, 0, 255, 0, 255, 0, 255 }; +uint8 IndicateB[] = { 0, 0, 0, 255, 0, 255, 255 }; + +void +SetAmbientColoursToIndicateRoadGroup(int i) +{ + AmbientLightColour.red = IndicateR[i%7]/255.0f; + AmbientLightColour.green = IndicateG[i%7]/255.0f; + AmbientLightColour.blue = IndicateB[i%7]/255.0f; + RpLightSetColor(pAmbient, &AmbientLightColour); +} + +void +SetAmbientColours(RwRGBAReal *color) +{ + RpLightSetColor(pAmbient, color); +} + + +STARTPATCHES + InjectHook(0x526510, SetLightsWithTimeOfDayColour, PATCH_JUMP); + InjectHook(0x5269A0, LightsCreate, PATCH_JUMP); + InjectHook(0x526B40, LightsDestroy, PATCH_JUMP); + InjectHook(0x526C10, WorldReplaceNormalLightsWithScorched, PATCH_JUMP); + InjectHook(0x526C50, WorldReplaceScorchedLightsWithNormal, PATCH_JUMP); + InjectHook(0x526C70, AddAnExtraDirectionalLight, PATCH_JUMP); + InjectHook(0x526DB0, RemoveExtraDirectionalLights, PATCH_JUMP); + InjectHook(0x526DE0, SetAmbientAndDirectionalColours, PATCH_JUMP); + InjectHook(0x526E60, SetBrightMarkerColours, PATCH_JUMP); + InjectHook(0x526F10, ReSetAmbientAndDirectionalColours, PATCH_JUMP); + InjectHook(0x526F40, DeActivateDirectional, PATCH_JUMP); + InjectHook(0x526F50, ActivateDirectional, PATCH_JUMP); + InjectHook(0x526F60, (void (*)(void))SetAmbientColours, PATCH_JUMP); + InjectHook(0x526F80, SetAmbientColoursForPedsCarsAndObjects, PATCH_JUMP); + InjectHook(0x526FA0, (void (*)(RwRGBAReal*))SetAmbientColours, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/Lights.h b/src/rw/Lights.h new file mode 100644 index 00000000..6fdd51de --- /dev/null +++ b/src/rw/Lights.h @@ -0,0 +1,18 @@ +#pragma once + +void SetLightsWithTimeOfDayColour(RpWorld *); +RpWorld *LightsCreate(RpWorld *world); +void LightsDestroy(RpWorld *world); +void WorldReplaceNormalLightsWithScorched(RpWorld *world, float l); +void WorldReplaceScorchedLightsWithNormal(RpWorld *world); +void AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, float red, float green, float blue); +void RemoveExtraDirectionalLights(RpWorld *world); +void SetAmbientAndDirectionalColours(float f); +void SetBrightMarkerColours(float f); +void ReSetAmbientAndDirectionalColours(void); +void DeActivateDirectional(void); +void ActivateDirectional(void); +void SetAmbientColours(void); +void SetAmbientColoursForPedsCarsAndObjects(void); +void SetAmbientColoursToIndicateRoadGroup(int i); +void SetAmbientColours(RwRGBAReal *color); diff --git a/src/rw/NodeName.cpp b/src/rw/NodeName.cpp new file mode 100644 index 00000000..2aea3c83 --- /dev/null +++ b/src/rw/NodeName.cpp @@ -0,0 +1,77 @@ +#include "common.h" +#include "patcher.h" +#include "NodeName.h" + +static int32 &gPluginOffset = *(int32*)0x64C610; + +enum +{ + ID_NODENAME = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0xFE), +}; + +#define NODENAMEEXT(o) (RWPLUGINOFFSET(char, o, gPluginOffset)) + +void* +NodeNameConstructor(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + if(gPluginOffset > 0) + NODENAMEEXT(object)[0] = '\0'; + return object; +} + +void* +NodeNameDestructor(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + return object; +} + +void* +NodeNameCopy(void *dstObject, const void *srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + strncpy(NODENAMEEXT(dstObject), NODENAMEEXT(srcObject), 23); + return nil; +} + +RwStream* +NodeNameStreamRead(RwStream *stream, RwInt32 binaryLength, void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwStreamRead(stream, NODENAMEEXT(object), binaryLength); + NODENAMEEXT(object)[binaryLength] = '\0'; + return stream; +} + +RwStream* +NodeNameStreamWrite(RwStream *stream, RwInt32 binaryLength, const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwStreamWrite(stream, NODENAMEEXT(object), binaryLength); + return stream; +} + +RwInt32 +NodeNameStreamGetSize(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + // game checks for null pointer on node name extension but that really happen + return rwstrlen(NODENAMEEXT(object)); +} + +bool +NodeNamePluginAttach(void) +{ + gPluginOffset = RwFrameRegisterPlugin(24, ID_NODENAME, + NodeNameConstructor, + NodeNameDestructor, + NodeNameCopy); + RwFrameRegisterPluginStream(ID_NODENAME, + NodeNameStreamRead, + NodeNameStreamWrite, + NodeNameStreamGetSize); + return gPluginOffset != -1; +} + +char* +GetFrameNodeName(RwFrame *frame) +{ + if(gPluginOffset < 0) + return nil; + return NODENAMEEXT(frame); +} diff --git a/src/rw/NodeName.h b/src/rw/NodeName.h new file mode 100644 index 00000000..1a3e057b --- /dev/null +++ b/src/rw/NodeName.h @@ -0,0 +1,4 @@ +#pragma once + +bool NodeNamePluginAttach(void); +char *GetFrameNodeName(RwFrame *frame); diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp new file mode 100644 index 00000000..44866f4f --- /dev/null +++ b/src/rw/RwHelper.cpp @@ -0,0 +1,374 @@ +#define WITHD3D +#include "common.h" +#include "patcher.h" +#include "Timecycle.h" +#include "skeleton.h" + +void * +RwMallocAlign(RwUInt32 size, RwUInt32 align) +{ + void *mem = (void *)malloc(size + align); + + ASSERT(mem != nil); + + void *addr = (void *)((((RwUInt32)mem) + align) & ~(align - 1)); + + ASSERT(addr != nil); + + *(((void **)addr) - 1) = mem; + + return addr; +} + +void +RwFreeAlign(void *mem) +{ + ASSERT(mem != nil); + + void *addr = *(((void **)mem) - 1); + + ASSERT(addr != nil); + + free(addr); +} + +void +DefinedState(void) +{ + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSWRAP); + RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEBORDERCOLOR, (void*)RWRGBALONG(0, 0, 0, 255)); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEFOGCOLOR, + (void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255)); + RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); + + // D3D stuff + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + RwD3D8SetRenderState(D3DRS_ALPHAREF, 2); +} + +RwFrame* +GetFirstFrameCallback(RwFrame *child, void *data) +{ + *(RwFrame**)data = child; + return nil; +} + +RwFrame* +GetFirstChild(RwFrame *frame) +{ + RwFrame *child; + + child = nil; + RwFrameForAllChildren(frame, GetFirstFrameCallback, &child); + return child; +} + +RwObject* +GetFirstObjectCallback(RwObject *object, void *data) +{ + *(RwObject**)data = object; + return nil; +} + +RwObject* +GetFirstObject(RwFrame *frame) +{ + RwObject *obj; + + obj = nil; + RwFrameForAllObjects(frame, GetFirstObjectCallback, &obj); + return obj; +} + +RpAtomic* +GetFirstAtomicCallback(RpAtomic *atm, void *data) +{ + *(RpAtomic**)data = atm; + return nil; +} + +RpAtomic* +GetFirstAtomic(RpClump *clump) +{ + RpAtomic *atm; + + atm = nil; + RpClumpForAllAtomics(clump, GetFirstAtomicCallback, &atm); + return atm; +} + +RwTexture* +GetFirstTextureCallback(RwTexture *tex, void *data) +{ + *(RwTexture**)data = tex; + return nil; +} + +RwTexture* +GetFirstTexture(RwTexDictionary *txd) +{ + RwTexture *tex; + + tex = nil; + RwTexDictionaryForAllTextures(txd, GetFirstTextureCallback, &tex); + return tex; +} + +void +CameraSize(RwCamera * camera, RwRect * rect, + RwReal viewWindow, RwReal aspectRatio) +{ + if (camera) + { + RwVideoMode videoMode; + RwRect r; + RwRect origSize = { 0, 0, 0, 0 }; // FIX just to make the compier happy + RwV2d vw; + + RwEngineGetVideoModeInfo(&videoMode, + RwEngineGetCurrentVideoMode()); + + origSize.w = RwRasterGetWidth(RwCameraGetRaster(camera)); + origSize.h = RwRasterGetHeight(RwCameraGetRaster(camera)); + + if (!rect) + { + if (videoMode.flags & rwVIDEOMODEEXCLUSIVE) + { + /* For full screen applications, resizing the camera just doesn't + * make sense, use the video mode size. + */ + + r.x = r.y = 0; + r.w = videoMode.width; + r.h = videoMode.height; + rect = &r; + } + else + { + /* + rect not specified - reuse current values + */ + r.w = RwRasterGetWidth(RwCameraGetRaster(camera)); + r.h = RwRasterGetHeight(RwCameraGetRaster(camera)); + r.x = r.y = 0; + rect = &r; + } + } + + if (( origSize.w != rect->w ) && ( origSize.h != rect->h )) + { + RwRaster *raster; + RwRaster *zRaster; + + /* + * Destroy rasters... + */ + + raster = RwCameraGetRaster(camera); + if( raster ) + { + RwRasterDestroy(raster); + } + + zRaster = RwCameraGetZRaster(camera); + if( zRaster ) + { + RwRasterDestroy(zRaster); + } + + /* + * Create new rasters... + */ + + raster = RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPECAMERA); + zRaster = RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPEZBUFFER); + + if( raster && zRaster ) + { + RwCameraSetRaster(camera, raster); + RwCameraSetZRaster(camera, zRaster); + } + else + { + if( raster ) + { + RwRasterDestroy(raster); + } + + if( zRaster ) + { + RwRasterDestroy(zRaster); + } + + rect->x = origSize.x; + rect->y = origSize.y; + rect->w = origSize.w; + rect->h = origSize.h; + + /* + * Use default values... + */ + raster = + RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPECAMERA); + + zRaster = + RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPEZBUFFER); + + RwCameraSetRaster(camera, raster); + RwCameraSetZRaster(camera, zRaster); + } + } + + /* Figure out the view window */ + if (videoMode.flags & rwVIDEOMODEEXCLUSIVE) + { + /* derive ratio from aspect ratio */ + vw.x = viewWindow; + vw.y = viewWindow / aspectRatio; + } + else + { + /* derive from pixel ratios */ + if (rect->w > rect->h) + { + vw.x = viewWindow; + vw.y = (rect->h * viewWindow) / rect->w; + } + else + { + vw.x = (rect->w * viewWindow) / rect->h; + vw.y = viewWindow; + } + } + + RwCameraSetViewWindow(camera, &vw); + + RsGlobal.width = rect->w; + RsGlobal.height = rect->h; + } + + return; +} + +void +CameraDestroy(RwCamera *camera) +{ + RwRaster *raster, *tmpRaster; + RwFrame *frame; + + if (camera) + { + frame = RwCameraGetFrame(camera); + if (frame) + { + RwFrameDestroy(frame); + } + + raster = RwCameraGetRaster(camera); + if (raster) + { + tmpRaster = RwRasterGetParent(raster); + + RwRasterDestroy(raster); + + if ((tmpRaster != nil) && (tmpRaster != raster)) + { + RwRasterDestroy(tmpRaster); + } + } + + raster = RwCameraGetZRaster(camera); + if (raster) + { + tmpRaster = RwRasterGetParent(raster); + + RwRasterDestroy(raster); + + if ((tmpRaster != nil) && (tmpRaster != raster)) + { + RwRasterDestroy(tmpRaster); + } + } + + RwCameraDestroy(camera); + } + + return; +} + +RwCamera * +CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) +{ + RwCamera *camera; + + camera = RwCameraCreate(); + + if (camera) + { + RwCameraSetFrame(camera, RwFrameCreate()); + RwCameraSetRaster(camera, + RwRasterCreate(0, 0, 0, rwRASTERTYPECAMERA)); + + if (zBuffer) + { + RwCameraSetZRaster(camera, + RwRasterCreate(0, 0, 0, + rwRASTERTYPEZBUFFER)); + } + + /* now check that everything is valid */ + if (RwCameraGetFrame(camera) && + RwCameraGetRaster(camera) && + RwRasterGetParent(RwCameraGetRaster(camera)) && + (!zBuffer || (RwCameraGetZRaster(camera) && + RwRasterGetParent(RwCameraGetZRaster + (camera))))) + { + /* everything OK */ + return (camera); + } + } + + /* if we're here then an error must have occurred so clean up */ + + CameraDestroy(camera); + return (nil); +} + +void CreateDebugFont() +{ + ; +} + +void DestroyDebugFont() +{ + ; +} + +void FlushObrsPrintfs() +{ + ; +} + +WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); } +WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); } + +STARTPATCHES + //InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP); + InjectHook(0x526460, GetFirstObject, PATCH_JUMP); + InjectHook(0x527170, CameraSize, PATCH_JUMP); + InjectHook(0x527340, CameraDestroy, PATCH_JUMP); + InjectHook(0x5273B0, CameraCreate, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h new file mode 100644 index 00000000..a9f0bdf4 --- /dev/null +++ b/src/rw/RwHelper.h @@ -0,0 +1,40 @@ +#pragma once + +void *RwMallocAlign(RwUInt32 size, RwUInt32 align); +void RwFreeAlign(void *mem); + +void CreateDebugFont(); +void DestroyDebugFont(); +void FlushObrsPrintfs(); +void DefinedState(void); +RwFrame *GetFirstChild(RwFrame *frame); +RwObject *GetFirstObject(RwFrame *frame); +RpAtomic *GetFirstAtomic(RpClump *clump); +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 CreateTxdImageForVideoCard(); + +bool RpClumpGtaStreamRead1(RwStream *stream); +RpClump *RpClumpGtaStreamRead2(RwStream *stream); +void RpClumpGtaCancelStream(void); + +void CameraSize(RwCamera *camera, + RwRect *rect, + RwReal viewWindow, + RwReal aspectRatio); +void CameraDestroy(RwCamera *camera); +RwCamera *CameraCreate(RwInt32 width, + RwInt32 height, + RwBool zBuffer); + + +void _TexturePoolsInitialise(); +void _TexturePoolsShutdown(); \ No newline at end of file diff --git a/src/rw/RwMatFX.cpp b/src/rw/RwMatFX.cpp new file mode 100644 index 00000000..ca9a633b --- /dev/null +++ b/src/rw/RwMatFX.cpp @@ -0,0 +1,213 @@ +#define WITHD3D +#include "common.h" +#include "patcher.h" + +struct MatFXNothing { int pad[5]; int effect; }; + +struct MatFXBump +{ + RwFrame *bumpFrame; + RwTexture *bumpedTex; + RwTexture *bumpTex; + float negBumpCoefficient; + int pad; + int effect; +}; + +struct MatFXEnv +{ + RwFrame *envFrame; + RwTexture *envTex; + float envCoeff; + int envFBalpha; + int pad; + int effect; +}; + +struct MatFXDual +{ + RwTexture *dualTex; + RwInt32 srcBlend; + RwInt32 dstBlend; +}; + + +struct MatFX +{ + union { + MatFXNothing n; + MatFXBump b; + MatFXEnv e; + MatFXDual d; + } fx[2]; + int effects; +}; + +int &MatFXMaterialDataOffset = *(int*)0x66188C; +int &MatFXAtomicDataOffset = *(int*)0x66189C; + +#ifdef PS2_MATFX + +void +_rpMatFXD3D8AtomicMatFXDefaultRender(RxD3D8InstanceData *inst, int flags, RwTexture *texture) +{ + if(flags & (rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2) && texture) + RwD3D8SetTexture(texture, 0); + else + RwD3D8SetTexture(nil, 0); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(inst->vertexAlpha || inst->material->color.alpha != 0xFF)); + RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, inst->vertexAlpha != 0); + RwD3D8SetPixelShader(0); + RwD3D8SetVertexShader(inst->vertexShader); + RwD3D8SetStreamSource(0, inst->vertexBuffer, inst->stride); + + if(inst->indexBuffer){ + RwD3D8SetIndices(inst->indexBuffer, inst->baseIndex); + RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices); + }else + RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices); +} + +// map [-1; -1] -> [0; 1], flip V +static RwMatrix scalenormal = { + { 0.5f, 0.0f, 0.0f }, 0, + { 0.0f, -0.5f, 0.0f }, 0, + { 0.0f, 0.0f, 1.0f }, 0, + { 0.5f, 0.5f, 0.0f }, 0, + +}; + +// flipped U for PS2 +static RwMatrix scalenormal_flipU = { + { -0.5f, 0.0f, 0.0f }, 0, + { 0.0f, -0.5f, 0.0f }, 0, + { 0.0f, 0.0f, 1.0f }, 0, + { 0.5f, 0.5f, 0.0f }, 0, + +}; + +void +ApplyEnvMapTextureMatrix(RwTexture *tex, int n, RwFrame *frame) +{ + RwD3D8SetTexture(tex, n); + RwD3D8SetTextureStageState(n, D3DRS_ALPHAREF, 2); + RwD3D8SetTextureStageState(n, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL); + if(frame){ + RwMatrix *envframemat = RwMatrixCreate(); + RwMatrix *tmpmat = RwMatrixCreate(); + RwMatrix *envmat = RwMatrixCreate(); + + RwMatrixInvert(envframemat, RwFrameGetLTM(frame)); + // PS2 + // can this be simplified? + *tmpmat = *RwFrameGetLTM(RwCameraGetFrame((RwCamera*)RWSRCGLOBAL(curCamera))); + RwV3dNegate(&tmpmat->right, &tmpmat->right); + tmpmat->flags = 0; + tmpmat->pos.x = 0.0f; + tmpmat->pos.y = 0.0f; + tmpmat->pos.z = 0.0f; + RwMatrixMultiply(envmat, tmpmat, envframemat); + *tmpmat = *envmat; + // important because envframemat can have a translation that we don't like + tmpmat->pos.x = 0.0f; + tmpmat->pos.y = 0.0f; + tmpmat->pos.z = 0.0f; + // for some reason we flip in U as well + RwMatrixMultiply(envmat, tmpmat, &scalenormal_flipU); + + RwD3D8SetTransform(D3DTS_TEXTURE0+n, envmat); + + RwMatrixDestroy(envmat); + RwMatrixDestroy(tmpmat); + RwMatrixDestroy(envframemat); + }else + RwD3D8SetTransform(D3DTS_TEXTURE0+n, &scalenormal); +} + +void +_rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int sel, RwTexture *texture, RwTexture *envMap) +{ + MatFX *matfx = *RWPLUGINOFFSET(MatFX*, inst->material, MatFXMaterialDataOffset); + MatFXEnv *env = &matfx->fx[sel].e; + + uint8 intens = (uint8)(env->envCoeff*255.0f); + + if(intens == 0 || envMap == nil){ + if(sel == 0) + _rpMatFXD3D8AtomicMatFXDefaultRender(inst, flags, texture); + return; + } + + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(inst->vertexAlpha || inst->material->color.alpha != 0xFF)); + if(flags & (rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2) && texture) + RwD3D8SetTexture(texture, 0); + else + RwD3D8SetTexture(nil, 0); + RwD3D8SetPixelShader(0); + RwD3D8SetVertexShader(inst->vertexShader); + RwD3D8SetStreamSource(0, inst->vertexBuffer, inst->stride); + RwD3D8SetIndices(inst->indexBuffer, inst->baseIndex); + if(inst->indexBuffer) + RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices); + else + RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices); + + // Effect pass + + ApplyEnvMapTextureMatrix(envMap, 0, env->envFrame); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwUInt32 src, dst, lighting, zwrite, fog, fogcol; + RwRenderStateGet(rwRENDERSTATESRCBLEND, &src); + RwRenderStateGet(rwRENDERSTATEDESTBLEND, &dst); + + // This is of course not using framebuffer alpha, + // but if the diffuse texture had no alpha, the result should actually be rather the same + if(env->envFBalpha) + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + else + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting); + RwD3D8GetRenderState(D3DRS_ZWRITEENABLE, &zwrite); + RwD3D8GetRenderState(D3DRS_FOGENABLE, &fog); + RwD3D8SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + if(fog){ + RwD3D8GetRenderState(D3DRS_FOGCOLOR, &fogcol); + RwD3D8SetRenderState(D3DRS_FOGCOLOR, 0); + } + + D3DCOLOR texfactor = D3DCOLOR_RGBA(intens, intens, intens, intens); + RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, texfactor); + RwD3D8SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + RwD3D8SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + RwD3D8SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR); + // alpha unused + //RwD3D8SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + //RwD3D8SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + //RwD3D8SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + + if(inst->indexBuffer) + RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices); + else + RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices); + + // Reset states + + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)src); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)dst); + RwD3D8SetRenderState(D3DRS_LIGHTING, lighting); + RwD3D8SetRenderState(D3DRS_ZWRITEENABLE, zwrite); + if(fog) + RwD3D8SetRenderState(D3DRS_FOGCOLOR, fogcol); + RwD3D8SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + RwD3D8SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + RwD3D8SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); +} + +STARTPATCHES + InjectHook(0x5CF6C0, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP); +ENDPATCHES + +#endif diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp new file mode 100644 index 00000000..50b99d47 --- /dev/null +++ b/src/rw/TexRead.cpp @@ -0,0 +1,349 @@ +#pragma warning( push ) +#pragma warning( disable : 4005) +#define DIRECTINPUT_VERSION 0x0800 +#include +#pragma warning( pop ) +#define WITHWINDOWS +#include "common.h" +#include "win.h" +#include "patcher.h" +#include "Timer.h" +#ifdef GTA_PC +#include "FileMgr.h" +#include "Pad.h" +#include "main.h" +#include "Directory.h" +#include "Streaming.h" +#include "TxdStore.h" +#include "CdStream.h" +#include "Font.h" +#include "Sprite2d.h" +#include "Text.h" +#include "RwHelper.h" +#endif //GTA_PC + +float &texLoadTime = *(float*)0x8F1B50; +int32 &texNumLoaded = *(int32*)0x8F252C; + +RwTexture* +RwTextureGtaStreamRead(RwStream *stream) +{ + RwUInt32 size, version; + RwTexture *tex; + + if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version)) + return nil; + + float preloadTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); + + if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size))) + return nil; + + if (gGameState == GS_INIT_PLAYING_GAME) { + texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1); + texNumLoaded++; + } + return tex; +} + +RwTexture* +destroyTexture(RwTexture *texture, void *data) +{ + RwTextureDestroy(texture); + return texture; +} + +RwTexDictionary* +RwTexDictionaryGtaStreamRead(RwStream *stream) +{ + RwUInt32 size, version; + RwInt32 numTextures; + RwTexDictionary *texDict; + RwTexture *tex; + + if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + return nil; + assert(size == 4); + if(RwStreamRead(stream, &numTextures, size) != size) + return nil; + + texDict = RwTexDictionaryCreate(); + if(texDict == nil) + return nil; + + while(numTextures--){ + tex = RwTextureGtaStreamRead(stream); + if(tex == nil){ + RwTexDictionaryForAllTextures(texDict, destroyTexture, nil); + RwTexDictionaryDestroy(texDict); + return nil; + } + RwTexDictionaryAddTexture(texDict, tex); + } + + return texDict; +} + +static int32 numberTextures = -1; +static int32 streamPosition; + +RwTexDictionary* +RwTexDictionaryGtaStreamRead1(RwStream *stream) +{ + RwUInt32 size, version; + RwInt32 numTextures; + RwTexDictionary *texDict; + RwTexture *tex; + + numberTextures = 0; + if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + return nil; + assert(size == 4); + if(RwStreamRead(stream, &numTextures, size) != size) + return nil; + + texDict = RwTexDictionaryCreate(); + if(texDict == nil) + return nil; + + numberTextures = numTextures/2; + + while(numTextures > numberTextures){ + numTextures--; + + tex = RwTextureGtaStreamRead(stream); + if(tex == nil){ + RwTexDictionaryForAllTextures(texDict, destroyTexture, nil); + RwTexDictionaryDestroy(texDict); + return nil; + } + RwTexDictionaryAddTexture(texDict, tex); + } + + numberTextures = numTextures; + streamPosition = stream->Type.memory.position; + + return texDict; +} + +RwTexDictionary* +RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict) +{ + RwTexture *tex; + + RwStreamSkip(stream, streamPosition - stream->Type.memory.position); + + while(numberTextures--){ + tex = RwTextureGtaStreamRead(stream); + if(tex == nil){ + RwTexDictionaryForAllTextures(texDict, destroyTexture, nil); + RwTexDictionaryDestroy(texDict); + return nil; + } + RwTexDictionaryAddTexture(texDict, tex); + } + + return texDict; +} + +#ifdef GTA_PC +#ifdef RWLIBS +extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags); +#else +WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); } +#endif + +void +ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8) +{ + cap32 = UINT32_MAX; + cap24 = UINT32_MAX; + cap16 = UINT32_MAX; + cap8 = UINT32_MAX; + + int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb"); + if (file != 0) { + CFileMgr::Read(file, (char*)&cap32, 4); + CFileMgr::Read(file, (char*)&cap24, 4); + CFileMgr::Read(file, (char*)&cap16, 4); + CFileMgr::Read(file, (char*)&cap8, 4); + CFileMgr::CloseFile(file); + } +} + +bool +CheckVideoCardCaps(void) +{ + uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888); + uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888); + uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555); + uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888); + uint32 fcap32, fcap24, fcap16, fcap8; + ReadVideoCardCapsFile(fcap32, fcap24, fcap16, fcap8); + return cap32 != fcap32 || cap24 != fcap24 || cap16 != fcap16 || cap8 != fcap8; +} + +void +WriteVideoCardCapsFile(void) +{ + uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888); + uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888); + uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555); + uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888); + int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb"); + if (file != 0) { + CFileMgr::Write(file, (char*)&cap32, 4); + CFileMgr::Write(file, (char*)&cap24, 4); + CFileMgr::Write(file, (char*)&cap16, 4); + CFileMgr::Write(file, (char*)&cap8, 4); + CFileMgr::CloseFile(file); + } +} + +bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); +void DoRWStuffEndOfFrame(void); + +void +ConvertingTexturesScreen(uint32 num, uint32 count, const char *text) +{ + HandleExit(); + + CSprite2d *splash = LoadSplash(nil); + if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)) + return; + + CSprite2d::SetRecipNearClip(); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + DefinedState(); + + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); + splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + + CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255)); + CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255)); + CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210)); + + CFont::SetBackgroundOff(); + CFont::SetPropOn(); + CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f)); + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f)); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(255, 217, 106, 255)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_BANK); + CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text)); + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); +} + +void +DealWithTxdWriteError(uint32 num, uint32 count, const char *text) +{ + while (!RsGlobal.quit) { + ConvertingTexturesScreen(num, count, text); + CPad::UpdatePads(); + if (CPad::GetPad(0)->GetEscapeJustDown()) + break; + } + RsGlobal.quit = false; + LoadingScreen(nil, nil, nil); + RsGlobal.quit = true; +} + +bool +CreateTxdImageForVideoCard() +{ + uint8 *buf = new uint8[CDSTREAM_SECTOR_SIZE]; + CDirectory *pDir = new CDirectory(TXDSTORESIZE); + CDirectory::DirectoryInfo dirInfo; + + CStreaming::FlushRequestList(); + + RwFileFunctions *filesys = RwOsGetFileInterface(); + + RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img"); + if (img == nil) { + // original code does otherwise and it leaks + delete []buf; + delete pDir; + + if (_dwOperatingSystemVersion == OS_WINNT || _dwOperatingSystemVersion == OS_WIN2000 || _dwOperatingSystemVersion == OS_WINXP) + DealWithTxdWriteError(0, TXDSTORESIZE, "CVT_CRT"); + + return false; + } + + int32 i; + for (i = 0; i < TXDSTORESIZE; i++) { + ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG"); + + if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) { + CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY); + CStreaming::RequestModelStream(0); + CStreaming::FlushChannels(); + + char filename[64]; + sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i)); + + if (CTxdStore::GetSlot(i)->texDict) { + int32 pos = filesys->rwftell(img->Type.file.fpFile); + + if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) { + DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR"); + RwStreamClose(img, nil); + delete []buf; + delete pDir; + CStreaming::RemoveTxd(i); + return false; + } + + int32 size = filesys->rwftell(img->Type.file.fpFile) - pos; + int32 num = size % CDSTREAM_SECTOR_SIZE; + + size /= CDSTREAM_SECTOR_SIZE; + if (num != 0) { + size++; + num = CDSTREAM_SECTOR_SIZE - num; + RwStreamWrite(img, buf, num); + } + + dirInfo.offset = pos / CDSTREAM_SECTOR_SIZE; + dirInfo.size = size; + strncpy(dirInfo.name, filename, sizeof(dirInfo.name)); + pDir->AddItem(dirInfo); + CStreaming::RemoveTxd(i); + } + CStreaming::FlushRequestList(); + } + } + + RwStreamClose(img, nil); + delete []buf; + + if (!pDir->WriteDirFile("models\\txd.dir")) { + DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR"); + delete pDir; + return false; + } + + delete pDir; + + WriteVideoCardCapsFile(); + return true; +} +#endif // GTA_PC + +STARTPATCHES + InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP); + InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP); + InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP); + InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP); + + InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP); + InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP); + InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP); + InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP); + InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP); + InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/TxdStore.cpp b/src/rw/TxdStore.cpp new file mode 100644 index 00000000..c751147d --- /dev/null +++ b/src/rw/TxdStore.cpp @@ -0,0 +1,209 @@ +#include "common.h" +#include "patcher.h" +#include "templates.h" +#include "General.h" +#include "Streaming.h" +#include "RwHelper.h" +#include "TxdStore.h" + +CPool *&CTxdStore::ms_pTxdPool = *(CPool**)0x8F5FB8; +RwTexDictionary *&CTxdStore::ms_pStoredTxd = *(RwTexDictionary**)0x9405BC; + +void +CTxdStore::Initialise(void) +{ + if(ms_pTxdPool == nil) + ms_pTxdPool = new CPool(TXDSTORESIZE); +} + +void +CTxdStore::Shutdown(void) +{ + if(ms_pTxdPool) + delete ms_pTxdPool; +} + +void +CTxdStore::GameShutdown(void) +{ + int i; + + for(i = 0; i < TXDSTORESIZE; i++){ + TxdDef *def = GetSlot(i); + if(def && GetNumRefs(i) == 0) + RemoveTxdSlot(i); + } +} + +int +CTxdStore::AddTxdSlot(const char *name) +{ + TxdDef *def = ms_pTxdPool->New(); + assert(def); + def->texDict = nil; + def->refCount = 0; + strcpy(def->name, name); + return ms_pTxdPool->GetJustIndex(def); +} + +void +CTxdStore::RemoveTxdSlot(int slot) +{ + TxdDef *def = GetSlot(slot); + if(def->texDict) + RwTexDictionaryDestroy(def->texDict); + ms_pTxdPool->Delete(def); +} + +int +CTxdStore::FindTxdSlot(const char *name) +{ + char *defname; + int size = ms_pTxdPool->GetSize(); + for(int i = 0; i < size; i++){ + defname = GetTxdName(i); + if(defname && !CGeneral::faststricmp(defname, name)) + return i; + } + return -1; +} + +char* +CTxdStore::GetTxdName(int slot) +{ + TxdDef *def = GetSlot(slot); + return def ? def->name : nil; +} + +void +CTxdStore::PushCurrentTxd(void) +{ + ms_pStoredTxd = RwTexDictionaryGetCurrent(); +} + +void +CTxdStore::PopCurrentTxd(void) +{ + RwTexDictionarySetCurrent(ms_pStoredTxd); + ms_pStoredTxd = nil; +} + +void +CTxdStore::SetCurrentTxd(int slot) +{ + TxdDef *def = GetSlot(slot); + if(def) + RwTexDictionarySetCurrent(def->texDict); +} + +void +CTxdStore::Create(int slot) +{ + GetSlot(slot)->texDict = RwTexDictionaryCreate(); +} + +int +CTxdStore::GetNumRefs(int slot) +{ + return GetSlot(slot)->refCount; +} + +void +CTxdStore::AddRef(int slot) +{ + GetSlot(slot)->refCount++; +} + +void +CTxdStore::RemoveRef(int slot) +{ + if(--GetSlot(slot)->refCount <= 0) + CStreaming::RemoveModel(slot + STREAM_OFFSET_TXD); +} + +void +CTxdStore::RemoveRefWithoutDelete(int slot) +{ + GetSlot(slot)->refCount--; +} + +bool +CTxdStore::LoadTxd(int slot, RwStream *stream) +{ + TxdDef *def = GetSlot(slot); + + if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil)){ + def->texDict = RwTexDictionaryGtaStreamRead(stream); + return def->texDict != nil; + } + printf("Failed to load TXD\n"); + return false; +} + +bool +CTxdStore::LoadTxd(int slot, const char *filename) +{ + RwStream *stream; + bool ret; + + ret = false; + _rwD3D8TexDictionaryEnableRasterFormatConversion(true); + do + stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename); + while(stream == nil); + ret = LoadTxd(slot, stream); + RwStreamClose(stream, nil); + return ret; +} + +bool +CTxdStore::StartLoadTxd(int slot, RwStream *stream) +{ + TxdDef *def = GetSlot(slot); + if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil)){ + def->texDict = RwTexDictionaryGtaStreamRead1(stream); + return def->texDict != nil; + }else{ + printf("Failed to load TXD\n"); + return false; + } +} + +bool +CTxdStore::FinishLoadTxd(int slot, RwStream *stream) +{ + TxdDef *def = GetSlot(slot); + def->texDict = RwTexDictionaryGtaStreamRead2(stream, def->texDict); + return def->texDict != nil; +} + +void +CTxdStore::RemoveTxd(int slot) +{ + TxdDef *def = GetSlot(slot); + if(def->texDict) + RwTexDictionaryDestroy(def->texDict); + def->texDict = nil; +} + +STARTPATCHES + InjectHook(0x527440, CTxdStore::Initialise, PATCH_JUMP); + InjectHook(0x527470, CTxdStore::Shutdown, PATCH_JUMP); + InjectHook(0x527490, CTxdStore::GameShutdown, PATCH_JUMP); + InjectHook(0x5274E0, CTxdStore::AddTxdSlot, PATCH_JUMP); + InjectHook(0x5275D0, CTxdStore::FindTxdSlot, PATCH_JUMP); + InjectHook(0x527590, CTxdStore::GetTxdName, PATCH_JUMP); + InjectHook(0x527900, CTxdStore::PushCurrentTxd, PATCH_JUMP); + InjectHook(0x527910, CTxdStore::PopCurrentTxd, PATCH_JUMP); + InjectHook(0x5278C0, CTxdStore::SetCurrentTxd, PATCH_JUMP); + InjectHook(0x527830, CTxdStore::Create, PATCH_JUMP); + InjectHook(0x527A00, CTxdStore::GetNumRefs, PATCH_JUMP); + InjectHook(0x527930, CTxdStore::AddRef, PATCH_JUMP); + InjectHook(0x527970, CTxdStore::RemoveRef, PATCH_JUMP); + InjectHook(0x5279C0, CTxdStore::RemoveRefWithoutDelete, PATCH_JUMP); + InjectHook(0x527700, (bool (*)(int, RwStream*))CTxdStore::LoadTxd, PATCH_JUMP); + InjectHook(0x5276B0, (bool (*)(int, const char*))CTxdStore::LoadTxd, PATCH_JUMP); + InjectHook(0x527770, CTxdStore::StartLoadTxd, PATCH_JUMP); + InjectHook(0x5277E0, CTxdStore::FinishLoadTxd, PATCH_JUMP); + InjectHook(0x527870, CTxdStore::RemoveTxd, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/TxdStore.h b/src/rw/TxdStore.h new file mode 100644 index 00000000..12ac708f --- /dev/null +++ b/src/rw/TxdStore.h @@ -0,0 +1,44 @@ +#pragma once + +#include "templates.h" + +struct TxdDef { + RwTexDictionary *texDict; + int refCount; + char name[20]; +}; + +class CTxdStore +{ + static CPool *&ms_pTxdPool; + static RwTexDictionary *&ms_pStoredTxd; +public: + static void Initialise(void); + static void Shutdown(void); + static void GameShutdown(void); + static int AddTxdSlot(const char *name); + static void RemoveTxdSlot(int slot); + static int FindTxdSlot(const char *name); + static char *GetTxdName(int slot); + static void PushCurrentTxd(void); + static void PopCurrentTxd(void); + static void SetCurrentTxd(int slot); + static void Create(int slot); + static int GetNumRefs(int slot); + static void AddRef(int slot); + static void RemoveRef(int slot); + static void RemoveRefWithoutDelete(int slot); + static bool LoadTxd(int slot, RwStream *stream); + static bool LoadTxd(int slot, const char *filename); + static bool StartLoadTxd(int slot, RwStream *stream); + static bool FinishLoadTxd(int slot, RwStream *stream); + static void RemoveTxd(int slot); + + static TxdDef *GetSlot(int slot) { + assert(slot >= 0); + assert(ms_pTxdPool); + assert(slot < ms_pTxdPool->GetSize()); + return ms_pTxdPool->GetSlot(slot); + } + static bool isTxdLoaded(int slot); +}; diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp new file mode 100644 index 00000000..f8b1f6b2 --- /dev/null +++ b/src/rw/VisibilityPlugins.cpp @@ -0,0 +1,889 @@ +#include "common.h" +#include "patcher.h" +#include "templates.h" +#include "Entity.h" +#include "ModelInfo.h" +#include "Lights.h" +#include "Renderer.h" +#include "Camera.h" +#include "VisibilityPlugins.h" +#include "World.h" + +#define FADE_DISTANCE 20.0f + +/* +CLinkList CVisibilityPlugins::m_alphaList; +CLinkList CVisibilityPlugins::m_alphaEntityList; + +int32 CVisibilityPlugins::ms_atomicPluginOffset = -1; +int32 CVisibilityPlugins::ms_framePluginOffset = -1; +int32 CVisibilityPlugins::ms_clumpPluginOffset = -1; +*/ +CLinkList &CVisibilityPlugins::m_alphaList = *(CLinkList*)0x8F42E4; +CLinkList &CVisibilityPlugins::m_alphaEntityList = *(CLinkList*)0x943084; + +int32 &CVisibilityPlugins::ms_atomicPluginOffset = *(int32*)0x600124; +int32 &CVisibilityPlugins::ms_framePluginOffset = *(int32*)0x600128; +int32 &CVisibilityPlugins::ms_clumpPluginOffset = *(int32*)0x60012C; + +RwCamera *&CVisibilityPlugins::ms_pCamera = *(RwCamera**)0x8F2514; +RwV3d *&CVisibilityPlugins::ms_pCameraPosn = *(RwV3d**)0x8F6270; +float &CVisibilityPlugins::ms_cullCompsDist = *(float*)0x8F2BC4; +float &CVisibilityPlugins::ms_vehicleLod0Dist = *(float*)0x885B28; +float &CVisibilityPlugins::ms_vehicleLod1Dist = *(float*)0x885B30; +float &CVisibilityPlugins::ms_vehicleFadeDist = *(float*)0x8E28B4; +float &CVisibilityPlugins::ms_bigVehicleLod0Dist = *(float*)0x8E2A84; +float &CVisibilityPlugins::ms_bigVehicleLod1Dist = *(float*)0x8E2A8C; +float &CVisibilityPlugins::ms_pedLod0Dist = *(float*)0x8F2BD4; +float &CVisibilityPlugins::ms_pedLod1Dist = *(float*)0x8F2BD8; +float &CVisibilityPlugins::ms_pedFadeDist = *(float*)0x8E2C34; + +void +CVisibilityPlugins::Initialise(void) +{ + m_alphaList.Init(20); + m_alphaList.head.item.sort = 0.0f; + m_alphaList.tail.item.sort = 100000000.0f; + m_alphaEntityList.Init(150); + m_alphaEntityList.head.item.sort = 0.0f; + m_alphaEntityList.tail.item.sort = 100000000.0f; +} + +void +CVisibilityPlugins::Shutdown(void) +{ + m_alphaList.Shutdown(); + m_alphaEntityList.Shutdown(); +} + +void +CVisibilityPlugins::InitAlphaEntityList(void) +{ + m_alphaEntityList.Clear(); +} + +bool +CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist) +{ + AlphaObjectInfo item; + item.entity = e; + item.sort = dist; + bool ret = !!m_alphaEntityList.InsertSorted(item); +// if(!ret) +// printf("list full %d\n", m_alphaEntityList.Count()); + return ret; +} + +void +CVisibilityPlugins::InitAlphaAtomicList(void) +{ + m_alphaList.Clear(); +} + +bool +CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist) +{ + AlphaObjectInfo item; + item.atomic = a; + item.sort = dist; + bool ret = !!m_alphaList.InsertSorted(item); +// if(!ret) +// printf("list full %d\n", m_alphaList.Count()); + return ret; +} + +void +CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) +{ + ms_pCamera = camera; + ms_pCameraPosn = RwMatrixGetPos(RwFrameGetMatrix(RwCameraGetFrame(camera))); + + if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) + ms_cullCompsDist = 1000000.0f; + else + ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f); + + ms_vehicleLod0Dist = sq(70.0f * TheCamera.GenerationDistMultiplier); + ms_vehicleLod1Dist = sq(90.0f * TheCamera.GenerationDistMultiplier); + ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier); + ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier); + ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier); + ms_pedLod0Dist = sq(25.0f * TheCamera.LODDistMultiplier); + ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier); + ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); +} + +RpMaterial* +SetAlphaCB(RpMaterial *material, void *data) +{ + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data; + return material; +} + +RpMaterial* +SetTextureCB(RpMaterial *material, void *data) +{ + RpMaterialSetTexture(material, (RwTexture*)data); + return material; +} + +void +CVisibilityPlugins::RenderAlphaAtomics(void) +{ + CLink *node; + for(node = m_alphaList.tail.prev; + node != &m_alphaList.head; + node = node->prev) + AtomicDefaultRenderCallBack(node->item.atomic); +} + +void +CVisibilityPlugins::RenderFadingEntities(void) +{ + CLink *node; + CSimpleModelInfo *mi; + for(node = m_alphaEntityList.tail.prev; + node != &m_alphaEntityList.head; + node = node->prev){ + CEntity *e = node->item.entity; + if(e->m_rwObject == nil) + continue; + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(e->m_modelIndex); + if(mi->m_noZwrite) + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); + + if(e->bDistanceFade){ + DeActivateDirectional(); + SetAmbientColours(); + e->bImBeingRendered = true; + RenderFadingAtomic((RpAtomic*)e->m_rwObject, node->item.sort); + e->bImBeingRendered = false; + }else + CRenderer::RenderOneNonRoad(e); + + if(mi->m_noZwrite) + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + } +} + +RpAtomic* +CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic) +{ + RpAtomic *lodatm; + RwMatrix *m; + RwV3d view; + float len; + CSimpleModelInfo *mi; + + mi = GetAtomicModelInfo(atomic); + m = RwFrameGetLTM(RpAtomicGetFrame(atomic)); + RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn); + len = RwV3dLength(&view); + lodatm = mi->GetAtomicFromDistance(len); + if(lodatm){ + if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic)) + RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE); + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderObjNormalAtomic(RpAtomic *atomic) +{ + RwMatrix *m; + RwV3d view; + float len; + + m = RwFrameGetLTM(RpAtomicGetFrame(atomic)); + RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn); + len = RwV3dLength(&view); + if(RwV3dDotProduct(&view, RwMatrixGetUp(m)) < -0.3f*len && len > 8.0f) + return atomic; + AtomicDefaultRenderCallBack(atomic); + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha) +{ + RpGeometry *geo; + uint32 flags; + + geo = RpAtomicGetGeometry(atomic); + flags = RpGeometryGetFlags(geo); + RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); + AtomicDefaultRenderCallBack(atomic); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); + RpGeometrySetFlags(geo, flags); + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) +{ + RpAtomic *lodatm; + float fadefactor; + uint8 alpha; + CSimpleModelInfo *mi; + + mi = GetAtomicModelInfo(atomic); + lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE); + if(mi->m_additive){ + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + AtomicDefaultRenderCallBack(atomic); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + }else{ + fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE; + if(fadefactor > 1.0f) + fadefactor = 1.0f; + alpha = mi->m_alpha * fadefactor; + if(alpha == 255) + AtomicDefaultRenderCallBack(atomic); + else{ + RpGeometry *geo = RpAtomicGetGeometry(lodatm); + uint32 flags = RpGeometryGetFlags(geo); + RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); + if(geo != RpAtomicGetGeometry(atomic)) + RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + AtomicDefaultRenderCallBack(atomic); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); + RpGeometrySetFlags(geo, flags); + } + } + return atomic; +} + + + +RpAtomic* +CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_vehicleLod0Dist){ + flags = GetAtomicId(atomic); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) + return atomic; + } + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_vehicleLod0Dist){ + flags = GetAtomicId(atomic); + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) + if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) + return atomic; + + if(flags & ATOMIC_FLAG_DRAWLAST){ + // sort before clump + if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f)) + AtomicDefaultRenderCallBack(atomic); + }else{ + if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) + AtomicDefaultRenderCallBack(atomic); + } + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_bigVehicleLod0Dist){ + flags = GetAtomicId(atomic); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f) + return atomic; + } + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_bigVehicleLod0Dist){ + flags = GetAtomicId(atomic); + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f) + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) + return atomic; + + if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_bigVehicleLod1Dist) + AtomicDefaultRenderCallBack(atomic); + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq >= ms_bigVehicleLod0Dist && + distsq < ms_bigVehicleLod1Dist){ + flags = GetAtomicId(atomic); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f) + return atomic; + } + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq >= ms_bigVehicleLod0Dist && + distsq < ms_bigVehicleLod1Dist){ + flags = GetAtomicId(atomic); + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f) + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) + return atomic; + + if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic) +{ + RpClump *clump; + float dist; + int32 alpha; + + clump = RpAtomicGetClump(atomic); + dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)); + if(dist >= ms_vehicleLod0Dist){ + alpha = GetClumpAlpha(clump); + if(alpha == 255) + AtomicDefaultRenderCallBack(atomic); + else + RenderAlphaAtomic(atomic, alpha); + } + return atomic; + +} + +RpAtomic* +CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq >= ms_bigVehicleLod1Dist) + AtomicDefaultRenderCallBack(atomic); + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_bigVehicleLod1Dist){ + flags = GetAtomicId(atomic); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){ + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) + return atomic; + } + AtomicDefaultRenderCallBack(atomic); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic) +{ + RwFrame *clumpframe; + float distsq, dot; + uint32 flags; + + clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic)); + distsq = GetDistanceSquaredFromCamera(clumpframe); + if(distsq < ms_bigVehicleLod1Dist){ + flags = GetAtomicId(atomic); + dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)), + RwFrameGetLTM(clumpframe), flags); + if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0) + if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot)) + return atomic; + + if(flags & ATOMIC_FLAG_DRAWLAST){ + // sort before clump + if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f)) + AtomicDefaultRenderCallBack(atomic); + }else{ + if(!InsertAtomicIntoSortedList(atomic, distsq + dot)) + AtomicDefaultRenderCallBack(atomic); + } + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic) +{ + if(CWorld::Players[0].m_pSkinTexture) + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture); + AtomicDefaultRenderCallBack(atomic); + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderPedLowDetailCB(RpAtomic *atomic) +{ + RpClump *clump; + float dist; + int32 alpha; + + clump = RpAtomicGetClump(atomic); + dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)); + if(dist >= ms_pedLod0Dist){ + alpha = GetClumpAlpha(clump); + if(alpha == 255) + AtomicDefaultRenderCallBack(atomic); + else + RenderAlphaAtomic(atomic, alpha); + } + return atomic; +} + +RpAtomic* +CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic) +{ + RpClump *clump; + float dist; + int32 alpha; + + clump = RpAtomicGetClump(atomic); + dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)); + if(dist < ms_pedLod0Dist){ + alpha = GetClumpAlpha(clump); + if(alpha == 255) + AtomicDefaultRenderCallBack(atomic); + else + RenderAlphaAtomic(atomic, alpha); + } + return atomic; +} + +float +CVisibilityPlugins::GetDistanceSquaredFromCamera(RwFrame *frame) +{ + RwMatrix *m; + RwV3d dist; + m = RwFrameGetLTM(frame); + RwV3dSub(&dist, RwMatrixGetPos(m), ms_pCameraPosn); + return RwV3dDotProduct(&dist, &dist); +} + +float +CVisibilityPlugins::GetDotProductWithCameraVector(RwMatrix *atomicMat, RwMatrix *clumpMat, uint32 flags) +{ + RwV3d dist; + float dot, dotdoor; + + // Vehicle forward is the y axis (RwMatrix.up) + // Vehicle right is the x axis (RwMatrix.right) + + RwV3dSub(&dist, RwMatrixGetPos(atomicMat), ms_pCameraPosn); + // forward/backward facing + if(flags & (ATOMIC_FLAG_FRONT | ATOMIC_FLAG_REAR)) + dot = RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat)); + // left/right facing + else if(flags & (ATOMIC_FLAG_LEFT | ATOMIC_FLAG_RIGHT)) + dot = RwV3dDotProduct(&dist, RwMatrixGetRight(clumpMat)); + else + dot = 0.0f; + if(flags & (ATOMIC_FLAG_LEFT | ATOMIC_FLAG_REAR)) + dot = -dot; + + if(flags & (ATOMIC_FLAG_REARDOOR | ATOMIC_FLAG_FRONTDOOR)){ + if(flags & ATOMIC_FLAG_REARDOOR) + dotdoor = -RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat)); + else if(flags & ATOMIC_FLAG_FRONTDOOR) + dotdoor = RwV3dDotProduct(&dist, RwMatrixGetUp(clumpMat)); + else + dotdoor = 0.0f; + + if(dot < 0.0f && dotdoor < 0.0f) + dot += dotdoor; + if(dot > 0.0f && dotdoor > 0.0f) + dot += dotdoor; + } + + return dot; +} + +/* These are all unused */ + +bool +CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump) +{ + return true; +} + +bool +CVisibilityPlugins::FrustumSphereCB(RpClump *clump) +{ + RwSphere sphere; + RwFrame *frame = RpClumpGetFrame(clump); + + CClumpModelInfo *modelInfo = (CClumpModelInfo*)GetFrameHierarchyId(frame); + sphere.radius = modelInfo->GetColModel()->boundingSphere.radius; + sphere.center.x = modelInfo->GetColModel()->boundingSphere.center.x; + sphere.center.y = modelInfo->GetColModel()->boundingSphere.center.y; + sphere.center.z = modelInfo->GetColModel()->boundingSphere.center.z; + RwV3dTransformPoints(&sphere.center, &sphere.center, 1, RwFrameGetLTM(frame)); + return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE; +} + +bool +CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump) +{ + if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist) + return FrustumSphereCB(clump); + return false; +} + +bool +CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump) +{ + return FrustumSphereCB(clump); +} + + + + +// +// RW Plugins +// + +enum +{ + ID_VISIBILITYATOMIC = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x00), + ID_VISIBILITYCLUMP = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x01), + ID_VISIBILITYFRAME = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x02), +}; + +bool +CVisibilityPlugins::PluginAttach(void) +{ + ms_atomicPluginOffset = RpAtomicRegisterPlugin(sizeof(AtomicExt), + ID_VISIBILITYATOMIC, + AtomicConstructor, AtomicDestructor, AtomicCopyConstructor); + + ms_framePluginOffset = RwFrameRegisterPlugin(sizeof(FrameExt), + ID_VISIBILITYFRAME, + FrameConstructor, FrameDestructor, FrameCopyConstructor); + + ms_clumpPluginOffset = RpClumpRegisterPlugin(sizeof(ClumpExt), + ID_VISIBILITYCLUMP, + ClumpConstructor, ClumpDestructor, ClumpCopyConstructor); + return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1; +} + +#define ATOMICEXT(o) (RWPLUGINOFFSET(AtomicExt, o, ms_atomicPluginOffset)) +#define FRAMEEXT(o) (RWPLUGINOFFSET(FrameExt, o, ms_framePluginOffset)) +#define CLUMPEXT(o) (RWPLUGINOFFSET(ClumpExt, o, ms_clumpPluginOffset)) + +// +// Atomic +// + +void* +CVisibilityPlugins::AtomicConstructor(void *object, int32, int32) +{ + ATOMICEXT(object)->modelInfo = nil; + return object; +} + +void* +CVisibilityPlugins::AtomicDestructor(void *object, int32, int32) +{ + return object; +} + +void* +CVisibilityPlugins::AtomicCopyConstructor(void *dst, const void *src, int32, int32) +{ + *ATOMICEXT(dst) = *ATOMICEXT(src); + return dst; +} + +void +CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic, + CSimpleModelInfo *modelInfo) +{ + AtomicExt *ext = ATOMICEXT(atomic); + ext->modelInfo = modelInfo; + switch(modelInfo->m_type) + case MITYPE_SIMPLE: + case MITYPE_TIME: + if(modelInfo->m_normalCull) + SetAtomicRenderCallback(atomic, RenderObjNormalAtomic); +} + +CSimpleModelInfo* +CVisibilityPlugins::GetAtomicModelInfo(RpAtomic *atomic) +{ + return ATOMICEXT(atomic)->modelInfo; +} + +void +CVisibilityPlugins::SetAtomicFlag(RpAtomic *atomic, int f) +{ + ATOMICEXT(atomic)->flags |= f; +} + +void +CVisibilityPlugins::ClearAtomicFlag(RpAtomic *atomic, int f) +{ + ATOMICEXT(atomic)->flags &= ~f; +} + +int +CVisibilityPlugins::GetAtomicId(RpAtomic *atomic) +{ + return ATOMICEXT(atomic)->flags; +} + +// This is rather useless, but whatever +void +CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb) +{ + if(cb == nil) + cb = AtomicDefaultRenderCallBack; // not necessary + RpAtomicSetRenderCallBack(atomic, cb); +} + +// +// Frame +// + +void* +CVisibilityPlugins::FrameConstructor(void *object, int32, int32) +{ + FRAMEEXT(object)->id = 0; + return object; +} + +void* +CVisibilityPlugins::FrameDestructor(void *object, int32, int32) +{ + return object; +} + +void* +CVisibilityPlugins::FrameCopyConstructor(void *dst, const void *src, int32, int32) +{ + *FRAMEEXT(dst) = *FRAMEEXT(src); + return dst; +} + +void +CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, int32 id) +{ + FRAMEEXT(frame)->id = id; +} + +int32 +CVisibilityPlugins::GetFrameHierarchyId(RwFrame *frame) +{ + return FRAMEEXT(frame)->id; +} + + +// +// Clump +// + +void* +CVisibilityPlugins::ClumpConstructor(void *object, int32, int32) +{ + ClumpExt *ext = CLUMPEXT(object); + ext->visibilityCB = DefaultVisibilityCB; + ext->alpha = 0xFF; + return object; +} + +void* +CVisibilityPlugins::ClumpDestructor(void *object, int32, int32) +{ + return object; +} + +void* +CVisibilityPlugins::ClumpCopyConstructor(void *dst, const void *src, int32, int32) +{ + CLUMPEXT(dst)->visibilityCB = CLUMPEXT(src)->visibilityCB; + return dst; +} + +void +CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo) +{ + CVehicleModelInfo *vmi; + SetFrameHierarchyId(RpClumpGetFrame(clump), (int32)modelInfo); + + // Unused + switch(modelInfo->m_type){ + // ignore MLO + case MITYPE_VEHICLE: + vmi = (CVehicleModelInfo*)modelInfo; + if(vmi->m_vehicleType == VEHICLE_TYPE_TRAIN || + vmi->m_vehicleType == VEHICLE_TYPE_HELI || + vmi->m_vehicleType == VEHICLE_TYPE_PLANE) + CLUMPEXT(clump)->visibilityCB = VehicleVisibilityCB_BigVehicle; + else + CLUMPEXT(clump)->visibilityCB = VehicleVisibilityCB; + break; + } +} + +void +CVisibilityPlugins::SetClumpAlpha(RpClump *clump, int alpha) +{ + CLUMPEXT(clump)->alpha = alpha; +} + +int +CVisibilityPlugins::GetClumpAlpha(RpClump *clump) +{ + return CLUMPEXT(clump)->alpha; +} + + +STARTPATCHES + InjectHook(0x527E50, CVisibilityPlugins::Initialise, PATCH_JUMP); + InjectHook(0x527EA0, CVisibilityPlugins::Shutdown, PATCH_JUMP); + InjectHook(0x528F90, CVisibilityPlugins::InitAlphaEntityList, PATCH_JUMP); + InjectHook(0x528FF0, CVisibilityPlugins::InsertEntityIntoSortedList, PATCH_JUMP); + InjectHook(0x528F80, CVisibilityPlugins::InitAlphaAtomicList, PATCH_JUMP); + InjectHook(0x528FA0, CVisibilityPlugins::InsertAtomicIntoSortedList, PATCH_JUMP); + InjectHook(0x528C50, CVisibilityPlugins::SetRenderWareCamera, PATCH_JUMP); + + InjectHook(0x527F60, SetAlphaCB, PATCH_JUMP); + InjectHook(0x529040, CVisibilityPlugins::RenderAlphaAtomics, PATCH_JUMP); + InjectHook(0x529070, CVisibilityPlugins::RenderFadingEntities, PATCH_JUMP); + + InjectHook(0x527F70, CVisibilityPlugins::RenderWheelAtomicCB, PATCH_JUMP); + InjectHook(0x528000, CVisibilityPlugins::RenderObjNormalAtomic, PATCH_JUMP); + InjectHook(0x5280B0, CVisibilityPlugins::RenderAlphaAtomic, PATCH_JUMP); + InjectHook(0x528100, CVisibilityPlugins::RenderFadingAtomic, PATCH_JUMP); + + InjectHook(0x5283E0, CVisibilityPlugins::RenderVehicleHiDetailCB, PATCH_JUMP); + InjectHook(0x5284B0, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB, PATCH_JUMP); + InjectHook(0x5288A0, CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle, PATCH_JUMP); + InjectHook(0x528A10, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle, PATCH_JUMP); + InjectHook(0x528AD0, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat, PATCH_JUMP); + InjectHook(0x5287F0, CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle, PATCH_JUMP); + InjectHook(0x528940, CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle, PATCH_JUMP); + InjectHook(0x528240, CVisibilityPlugins::RenderVehicleReallyLowDetailCB, PATCH_JUMP); + InjectHook(0x5287B0, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle, PATCH_JUMP); + InjectHook(0x5285D0, CVisibilityPlugins::RenderTrainHiDetailCB, PATCH_JUMP); + InjectHook(0x5286A0, CVisibilityPlugins::RenderTrainHiDetailAlphaCB, PATCH_JUMP); + + InjectHook(0x528BC0, CVisibilityPlugins::RenderPedHiDetailCB, PATCH_JUMP); + InjectHook(0x528B60, CVisibilityPlugins::RenderPedLowDetailCB, PATCH_JUMP); + + + InjectHook(0x527DC0, CVisibilityPlugins::PluginAttach, PATCH_JUMP); + + InjectHook(0x527EC0, CVisibilityPlugins::SetAtomicModelInfo, PATCH_JUMP); + InjectHook(0x527F00, CVisibilityPlugins::GetAtomicModelInfo, PATCH_JUMP); + InjectHook(0x527F10, CVisibilityPlugins::SetAtomicFlag, PATCH_JUMP); + InjectHook(0x527F30, CVisibilityPlugins::ClearAtomicFlag, PATCH_JUMP); + InjectHook(0x527F50, CVisibilityPlugins::GetAtomicId, PATCH_JUMP); + InjectHook(0x528C20, CVisibilityPlugins::SetAtomicRenderCallback, PATCH_JUMP); + + InjectHook(0x528D60, CVisibilityPlugins::SetFrameHierarchyId, PATCH_JUMP); + InjectHook(0x528D80, CVisibilityPlugins::GetFrameHierarchyId, PATCH_JUMP); + + InjectHook(0x528ED0, CVisibilityPlugins::SetClumpModelInfo, PATCH_JUMP); + InjectHook(0x528F50, CVisibilityPlugins::SetClumpAlpha, PATCH_JUMP); + InjectHook(0x528F70, CVisibilityPlugins::GetClumpAlpha, PATCH_JUMP); + + + InjectHook(0x529120, CVisibilityPlugins::GetDistanceSquaredFromCamera, PATCH_JUMP); + InjectHook(0x5282A0, CVisibilityPlugins::GetDotProductWithCameraVector, PATCH_JUMP); +ENDPATCHES diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h new file mode 100644 index 00000000..65d2675a --- /dev/null +++ b/src/rw/VisibilityPlugins.h @@ -0,0 +1,133 @@ +#pragma once + +#include "templates.h" + +class CEntity; +class CSimpleModelInfo; +class CClumpModelInfo; + +typedef bool (*ClumpVisibilityCB)(RpClump*); + +class CVisibilityPlugins +{ +public: + struct AlphaObjectInfo + { + union { + CEntity *entity; + RpAtomic *atomic; + }; + float sort; + }; + + static CLinkList &m_alphaList; + static CLinkList &m_alphaEntityList; + static RwCamera *&ms_pCamera; + static RwV3d *&ms_pCameraPosn; + static float &ms_cullCompsDist; + static float &ms_vehicleLod0Dist; + static float &ms_vehicleLod1Dist; + static float &ms_vehicleFadeDist; + static float &ms_bigVehicleLod0Dist; + static float &ms_bigVehicleLod1Dist; + static float &ms_pedLod0Dist; + static float &ms_pedLod1Dist; + static float &ms_pedFadeDist; + + static void Initialise(void); + static void Shutdown(void); + static void InitAlphaEntityList(void); + static bool InsertEntityIntoSortedList(CEntity *e, float dist); + static void InitAlphaAtomicList(void); + static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist); + + static void SetRenderWareCamera(RwCamera *camera); + + static RpAtomic *RenderWheelAtomicCB(RpAtomic *atomic); + static RpAtomic *RenderObjNormalAtomic(RpAtomic *atomic); + static RpAtomic *RenderAlphaAtomic(RpAtomic *atomic, int alpha); + static RpAtomic *RenderFadingAtomic(RpAtomic *atm, float dist); + + static RpAtomic *RenderVehicleHiDetailCB(RpAtomic *atomic); + static RpAtomic *RenderVehicleHiDetailAlphaCB(RpAtomic *atomic); + static RpAtomic *RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic); + static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic); + static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic); + static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic); + static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic); + static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic); + static RpAtomic *RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic); + static RpAtomic *RenderTrainHiDetailCB(RpAtomic *atomic); + static RpAtomic *RenderTrainHiDetailAlphaCB(RpAtomic *atomic); + + static RpAtomic *RenderPlayerCB(RpAtomic *atomic); + static RpAtomic *RenderPedLowDetailCB(RpAtomic *atomic); + static RpAtomic *RenderPedHiDetailCB(RpAtomic *atomic); + + static void RenderAlphaAtomics(void); + static void RenderFadingEntities(void); + + // All actually unused + static bool DefaultVisibilityCB(RpClump *clump); + static bool FrustumSphereCB(RpClump *clump); +// static bool MloVisibilityCB(RpClump *clump); + static bool VehicleVisibilityCB(RpClump *clump); + static bool VehicleVisibilityCB_BigVehicle(RpClump *clump); + + static float GetDistanceSquaredFromCamera(RwFrame *frame); + static float GetDotProductWithCameraVector(RwMatrix *atomicMat, RwMatrix *clumpMat, uint32 flags); + + // + // RW Plugins + // + + union AtomicExt + { + CSimpleModelInfo *modelInfo; // used by SimpleModelInfo + int flags; // used by ClumpModelInfo + }; + static void SetAtomicModelInfo(RpAtomic*, CSimpleModelInfo*); + static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic); + static void SetAtomicFlag(RpAtomic*, int); + static void ClearAtomicFlag(RpAtomic*, int); + static int GetAtomicId(RpAtomic *atomic); + static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender); + + static void *AtomicConstructor(void *object, int32 offset, int32 len); + static void *AtomicDestructor(void *object, int32 offset, int32 len); + static void *AtomicCopyConstructor(void *dst, const void *src, + int32 offset, int32 len); + static int32 &ms_atomicPluginOffset; + + struct FrameExt + { + // BUG: this is abused to hold a pointer by SetClumpModelInfo + int32 id; + }; + static void SetFrameHierarchyId(RwFrame *frame, int32 id); + static int32 GetFrameHierarchyId(RwFrame *frame); + + static void *FrameConstructor(void *object, int32 offset, int32 len); + static void *FrameDestructor(void *object, int32 offset, int32 len); + static void *FrameCopyConstructor(void *dst, const void *src, + int32 offset, int32 len); + static int32 &ms_framePluginOffset; + + // Not actually used + struct ClumpExt + { + ClumpVisibilityCB visibilityCB; + int alpha; + }; + static void SetClumpModelInfo(RpClump*, CClumpModelInfo*); + static void SetClumpAlpha(RpClump*, int); + static int GetClumpAlpha(RpClump*); + + static void *ClumpConstructor(void *object, int32 offset, int32 len); + static void *ClumpDestructor(void *object, int32 offset, int32 len); + static void *ClumpCopyConstructor(void *dst, const void *src, + int32 offset, int32 len); + static int32 &ms_clumpPluginOffset; + + static bool PluginAttach(void); +}; diff --git a/src/rw/rw.cpp b/src/rw/rw.cpp new file mode 100644 index 00000000..3875f2a1 --- /dev/null +++ b/src/rw/rw.cpp @@ -0,0 +1,839 @@ +#include "common.h" +#include "patcher.h" +#include "rwcore.h" +#include "rpworld.h" +#include "rpmatfx.h" +#include "rpskin.h" +#include "rphanim.h" +#include "rtbmp.h" + +typedef RwV3d *(*rwVectorsMultFn) (RwV3d * pointsOut, + const RwV3d * pointsIn, + RwInt32 numPoints, + const RwMatrix * matrix); + +#ifndef RWLIBS + +WRAPPER void _rwObjectHasFrameSetFrame(void* object, RwFrame* frame) { EAXJMP(0x5BC950); } +WRAPPER RpAtomic* AtomicDefaultRenderCallBack(RpAtomic* atomic) { EAXJMP(0x59E690); } +WRAPPER void _rpAtomicResyncInterpolatedSphere(RpAtomic* atomic) { EAXJMP(0x59E6C0); } +WRAPPER RwSphere const* RpAtomicGetWorldBoundingSphere(RpAtomic* atomic) { EAXJMP(0x59E800); } +WRAPPER RwInt32 RpClumpGetNumAtomics(RpClump* clump) { EAXJMP(0x59ED50); } +WRAPPER RpClump* RpClumpRender(RpClump* clump) { EAXJMP(0x59ED80); } +WRAPPER RpClump* RpClumpForAllAtomics(RpClump* clump, RpAtomicCallBack callback, void* pData) { EAXJMP(0x59EDD0); } +WRAPPER RpClump* RpClumpForAllCameras(RpClump* clump, RwCameraCallBack callback, void* pData) { EAXJMP(0x59EE10); } +WRAPPER RpClump* RpClumpForAllLights(RpClump* clump, RpLightCallBack callback, void* pData) { EAXJMP(0x59EE60); } +WRAPPER RpAtomic* RpAtomicCreate() { EAXJMP(0x59EEB0); } +WRAPPER RpAtomic* RpAtomicSetGeometry(RpAtomic* atomic, RpGeometry* geometry, RwUInt32 flags) { EAXJMP(0x59EFA0); } +WRAPPER RwBool RpAtomicDestroy(RpAtomic* atomic) { EAXJMP(0x59F020); } +WRAPPER RpAtomic* RpAtomicClone(RpAtomic* atomic) { EAXJMP(0x59F0A0); } +WRAPPER RpClump* RpClumpClone(RpClump* clump) { EAXJMP(0x59F1B0); } +WRAPPER RpClump* RpClumpCreate() { EAXJMP(0x59F490); } +WRAPPER RwBool RpClumpDestroy(RpClump* clump) { EAXJMP(0x59F500); } +WRAPPER RpClump* RpClumpAddAtomic(RpClump* clump, RpAtomic* atomic) { EAXJMP(0x59F680); } +WRAPPER RpClump* RpClumpRemoveAtomic(RpClump* clump, RpAtomic* atomic) { EAXJMP(0x59F6B0); } +WRAPPER RpClump* RpClumpRemoveLight(RpClump* clump, RpLight* light) { EAXJMP(0x59F6E0); } +WRAPPER RpClump* RpClumpStreamRead(RwStream* stream) { EAXJMP(0x59FC50); } +WRAPPER RwInt32 RpAtomicRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A0510); } +WRAPPER RwInt32 RpClumpRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A0540); } +WRAPPER RwInt32 RpAtomicRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5A0570); } +WRAPPER RwInt32 RpAtomicSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB) { EAXJMP(0x5A05A0); } +WRAPPER RwInt32 RpAtomicSetStreamRightsCallBack(RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB) { EAXJMP(0x5A05C0); } +WRAPPER RwInt32 RpAtomicGetPluginOffset(RwUInt32 pluginID) { EAXJMP(0x5A05E0); } +WRAPPER RpAtomic* RpAtomicSetFrame(RpAtomic* atomic, RwFrame* frame) { EAXJMP(0x5A0600); } +WRAPPER RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, RwPluginObjectDestructor termCB) { EAXJMP(0x5A0DC0); } +WRAPPER RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID) { EAXJMP(0x5A0DF0); } +WRAPPER RwInt32 RwEngineGetNumSubSystems() { EAXJMP(0x5A0E10); } +WRAPPER RwSubSystemInfo* RwEngineGetSubSystemInfo(RwSubSystemInfo* subSystemInfo, RwInt32 subSystemIndex) { EAXJMP(0x5A0E40); } +WRAPPER RwInt32 RwEngineGetCurrentSubSystem() { EAXJMP(0x5A0E70); } +WRAPPER RwBool RwEngineSetSubSystem(RwInt32 subSystemIndex) { EAXJMP(0x5A0EA0); } +WRAPPER RwInt32 RwEngineGetNumVideoModes() { EAXJMP(0x5A0ED0); } +WRAPPER RwVideoMode* RwEngineGetVideoModeInfo(RwVideoMode* modeinfo, RwInt32 modeIndex) { EAXJMP(0x5A0F00); } +WRAPPER RwInt32 RwEngineGetCurrentVideoMode() { EAXJMP(0x5A0F30); } +WRAPPER RwBool RwEngineSetVideoMode(RwInt32 modeIndex) { EAXJMP(0x5A0F60); } +WRAPPER RwBool RwEngineStop() { EAXJMP(0x5A0F90); } +WRAPPER RwBool RwEngineStart() { EAXJMP(0x5A0FE0); } +WRAPPER RwBool RwEngineClose() { EAXJMP(0x5A1070); } +WRAPPER RwBool RwEngineOpen(RwEngineOpenParams* initParams) { EAXJMP(0x5A10E0); } +WRAPPER RwBool RwEngineTerm() { EAXJMP(0x5A1290); } +WRAPPER RwBool RwEngineInit(RwMemoryFunctions* memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { EAXJMP(0x5A12D0); } +WRAPPER void* _rwFrameOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A15E0); } +WRAPPER void* _rwFrameClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A1650); } +WRAPPER RwFrame* _rwFrameCloneAndLinkClones(RwFrame* root) { EAXJMP(0x5A1690); } +WRAPPER RwFrame* _rwFramePurgeClone(RwFrame* root) { EAXJMP(0x5A1880); } +WRAPPER RwBool RwFrameDirty(RwFrame const* frame) { EAXJMP(0x5A1930); } +WRAPPER void _rwFrameInit(RwFrame* frame) { EAXJMP(0x5A1950); } +WRAPPER RwFrame* RwFrameCreate() { EAXJMP(0x5A1A00); } +WRAPPER RwBool RwFrameDestroy(RwFrame* frame) { EAXJMP(0x5A1A30); } +WRAPPER RwBool RwFrameDestroyHierarchy(RwFrame* frame) { EAXJMP(0x5A1BF0); } +WRAPPER RwFrame* RwFrameUpdateObjects(RwFrame* frame) { EAXJMP(0x5A1C60); } +WRAPPER RwMatrix* RwFrameGetLTM(RwFrame* frame) { EAXJMP(0x5A1CE0); } +WRAPPER RwFrame* RwFrameAddChild(RwFrame* parent, RwFrame* child) { EAXJMP(0x5A1D00); } +WRAPPER RwFrame* RwFrameRemoveChild(RwFrame* child) { EAXJMP(0x5A1ED0); } +WRAPPER RwFrame* RwFrameForAllChildren(RwFrame* frame, RwFrameCallBack callBack, void* data) { EAXJMP(0x5A1FC0); } +WRAPPER RwFrame* RwFrameTranslate(RwFrame* frame, RwV3d const* v, RwOpCombineType combine) { EAXJMP(0x5A2000); } +WRAPPER RwFrame* RwFrameScale(RwFrame* frame, RwV3d const* v, RwOpCombineType combine) { EAXJMP(0x5A20A0); } +WRAPPER RwFrame* RwFrameTransform(RwFrame* frame, RwMatrix const* m, RwOpCombineType combine) { EAXJMP(0x5A2140); } +WRAPPER RwFrame* RwFrameRotate(RwFrame* frame, RwV3d const* axis, RwReal angle, RwOpCombineType combine) { EAXJMP(0x5A21E0); } +WRAPPER RwFrame* RwFrameSetIdentity(RwFrame* frame) { EAXJMP(0x5A2280); } +WRAPPER RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, void* data) { EAXJMP(0x5A2340); } +WRAPPER RwInt32 RwFrameRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A2380); } +WRAPPER RwBool _rwMatrixSetMultFn(rwMatrixMultFn multMat) { EAXJMP(0x5A23B0); } +WRAPPER RwReal _rwMatrixDeterminant(RwMatrix const* matrix) { EAXJMP(0x5A2520); } +WRAPPER RwReal _rwMatrixOrthogonalError(RwMatrix const* matrix) { EAXJMP(0x5A2570); } +WRAPPER RwReal _rwMatrixNormalError(RwMatrix const* matrix) { EAXJMP(0x5A25D0); } +WRAPPER RwReal _rwMatrixIdentityError(RwMatrix const* matrix) { EAXJMP(0x5A2660); } +WRAPPER void* _rwMatrixClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A2730); } +WRAPPER void* _rwMatrixOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A2770); } +WRAPPER RwMatrix* RwMatrixOptimize(RwMatrix* matrix, RwMatrixTolerance const* tolerance) { EAXJMP(0x5A2820); } +WRAPPER RwMatrix* RwMatrixUpdate(RwMatrix* matrix) { EAXJMP(0x5A28E0); } +WRAPPER RwMatrix* RwMatrixMultiply(RwMatrix* matrixOut, RwMatrix const* MatrixIn1, RwMatrix const* matrixIn2) { EAXJMP(0x5A28F0); } +WRAPPER RwMatrix* RwMatrixRotateOneMinusCosineSine(RwMatrix* matrix, RwV3d const* unitAxis, RwReal oneMinusCosine, RwReal sine, RwOpCombineType combineOp) { EAXJMP(0x5A2960); } +WRAPPER RwMatrix* RwMatrixRotate(RwMatrix* matrix, RwV3d const* axis, RwReal angle, RwOpCombineType combineOp) { EAXJMP(0x5A2BF0); } +WRAPPER RwMatrix* RwMatrixInvert(RwMatrix* matrixOut, RwMatrix const* matrixIn) { EAXJMP(0x5A2C90); } +WRAPPER RwMatrix* RwMatrixScale(RwMatrix* matrix, RwV3d const* scale, RwOpCombineType combineOp) { EAXJMP(0x5A2EE0); } +WRAPPER RwMatrix* RwMatrixTranslate(RwMatrix* matrix, RwV3d const* translation, RwOpCombineType combineOp) { EAXJMP(0x5A3070); } +WRAPPER RwMatrix* RwMatrixTransform(RwMatrix* matrix, RwMatrix const* transform, RwOpCombineType combineOp) { EAXJMP(0x5A31C0); } +WRAPPER RwBool RwMatrixDestroy(RwMatrix* mpMat) { EAXJMP(0x5A3300); } +WRAPPER RwMatrix* RwMatrixCreate() { EAXJMP(0x5A3330); } +WRAPPER RwBool _rwVectorSetMultFn(rwVectorMultFn multPoint, rwVectorsMultFn multPoints, rwVectorMultFn multVector, rwVectorsMultFn multVectors) { EAXJMP(0x5A3450); } +WRAPPER RwReal _rwV3dNormalize(RwV3d* out, RwV3d const* in) { EAXJMP(0x5A3600); } +WRAPPER RwReal RwV3dLength(RwV3d const* in) { EAXJMP(0x5A36A0); } +WRAPPER RwReal _rwSqrt(RwReal const num) { EAXJMP(0x5A3710); } +WRAPPER RwReal _rwInvSqrt(RwReal const num) { EAXJMP(0x5A3770); } +WRAPPER RwV3d* RwV3dTransformPoints(RwV3d* pointsOut, RwV3d const* pointsIn, RwInt32 numPoints, RwMatrix const* matrix) { EAXJMP(0x5A37D0); } +WRAPPER RwV3d* RwV3dTransformVectors(RwV3d* vectorsOut, RwV3d const* vectorsIn, RwInt32 numPoints, RwMatrix const* matrix) { EAXJMP(0x5A37E0); } +WRAPPER void* _rwVectorClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A37F0); } +WRAPPER void* _rwVectorOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A3860); } +WRAPPER RwUInt32 RwStreamRead(RwStream* stream, void* buffer, RwUInt32 length) { EAXJMP(0x5A3AD0); } +WRAPPER RwStream* RwStreamWrite(RwStream* stream, void const* buffer, RwUInt32 length) { EAXJMP(0x5A3C30); } +WRAPPER RwStream* RwStreamSkip(RwStream* stream, RwUInt32 offset) { EAXJMP(0x5A3DF0); } +WRAPPER RwBool RwStreamClose(RwStream* stream, void* pData) { EAXJMP(0x5A3F10); } +WRAPPER RwStream* RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, void const* pData) { EAXJMP(0x5A3FE0); } +WRAPPER RwReal RwIm2DGetNearScreenZ() { EAXJMP(0x5A43A0); } +WRAPPER RwReal RwIm2DGetFarScreenZ() { EAXJMP(0x5A43B0); } +WRAPPER RwBool RwRenderStateSet(RwRenderState state, void* value) { EAXJMP(0x5A43C0); } +WRAPPER RwBool RwRenderStateGet(RwRenderState state, void* value) { EAXJMP(0x5A4410); } +WRAPPER RwBool RwIm2DRenderLine(RwIm2DVertex* vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2) { EAXJMP(0x5A4420); } +WRAPPER RwBool RwIm2DRenderPrimitive(RwPrimitiveType primType, RwIm2DVertex* vertices, RwInt32 numVertices) { EAXJMP(0x5A4430); } +WRAPPER RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType primType, RwIm2DVertex* vertices, RwInt32 numVertices, RwImVertexIndex* indices, RwInt32 numIndices) { EAXJMP(0x5A4440); } +WRAPPER RwCamera* RwCameraEndUpdate(RwCamera* camera) { EAXJMP(0x5A5020); } +WRAPPER RwCamera* RwCameraBeginUpdate(RwCamera* camera) { EAXJMP(0x5A5030); } +WRAPPER RwCamera* RwCameraSetViewOffset(RwCamera* camera, RwV2d const* offset) { EAXJMP(0x5A5040); } +WRAPPER RwCamera* RwCameraSetNearClipPlane(RwCamera* camera, RwReal nearClip) { EAXJMP(0x5A5070); } +WRAPPER RwCamera* RwCameraSetFarClipPlane(RwCamera* camera, RwReal farClip) { EAXJMP(0x5A5140); } +WRAPPER RwFrustumTestResult RwCameraFrustumTestSphere(RwCamera const* camera, RwSphere const* sphere) { EAXJMP(0x5A5170); } +WRAPPER RwCamera* RwCameraClear(RwCamera* camera, RwRGBA* colour, RwInt32 clearMode) { EAXJMP(0x5A51E0); } +WRAPPER RwCamera* RwCameraShowRaster(RwCamera* camera, void* pDev, RwUInt32 flags) { EAXJMP(0x5A5210); } +WRAPPER RwCamera* RwCameraSetProjection(RwCamera* camera, RwCameraProjection projection) { EAXJMP(0x5A5240); } +WRAPPER RwCamera* RwCameraSetViewWindow(RwCamera* camera, RwV2d const* viewWindow) { EAXJMP(0x5A52B0); } +WRAPPER RwInt32 RwCameraRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A52F0); } +WRAPPER RwBool RwCameraDestroy(RwCamera* camera) { EAXJMP(0x5A5320); } +WRAPPER RwCamera* RwCameraCreate() { EAXJMP(0x5A5360); } +WRAPPER RwBool RwTextureSetMipmapping(RwBool enable) { EAXJMP(0x5A7100); } +WRAPPER RwBool RwTextureGetMipmapping() { EAXJMP(0x5A7120); } +WRAPPER RwBool RwTextureSetAutoMipmapping(RwBool enable) { EAXJMP(0x5A7130); } +WRAPPER RwBool RwTextureGetAutoMipmapping() { EAXJMP(0x5A7150); } +WRAPPER RwTexDictionary* RwTexDictionaryCreate() { EAXJMP(0x5A7160); } +WRAPPER RwBool RwTexDictionaryDestroy(RwTexDictionary* dict) { EAXJMP(0x5A7200); } +WRAPPER RwTexDictionary const* RwTexDictionaryForAllTextures(RwTexDictionary const* dict, RwTextureCallBack fpCallBack, void* pData) { EAXJMP(0x5A7290); } +WRAPPER RwTexture* RwTextureCreate(RwRaster* raster) { EAXJMP(0x5A72D0); } +WRAPPER RwBool RwTextureDestroy(RwTexture* texture) { EAXJMP(0x5A7330); } +WRAPPER RwTexture* RwTextureSetName(RwTexture* texture, RwChar const* name) { EAXJMP(0x5A73B0); } +WRAPPER RwTexture* RwTextureSetMaskName(RwTexture* texture, RwChar const* maskName) { EAXJMP(0x5A7420); } +WRAPPER RwTexture* RwTexDictionaryAddTexture(RwTexDictionary* dict, RwTexture* texture) { EAXJMP(0x5A7490); } +WRAPPER RwTexture* RwTexDictionaryFindNamedTexture(RwTexDictionary* dict, RwChar const* name) { EAXJMP(0x5A74D0); } +WRAPPER RwTexDictionary* RwTexDictionarySetCurrent(RwTexDictionary* dict) { EAXJMP(0x5A7550); } +WRAPPER RwTexDictionary* RwTexDictionaryGetCurrent() { EAXJMP(0x5A7570); } +WRAPPER RwTexture* RwTextureRead(RwChar const* name, RwChar const* maskName) { EAXJMP(0x5A7580); } +WRAPPER RwBool RwTextureRasterGenerateMipmaps(RwRaster* raster, RwImage* image) { EAXJMP(0x5A7780); } +WRAPPER RwImage* RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth) { EAXJMP(0x5A9120); } +WRAPPER RwBool RwImageDestroy(RwImage* image) { EAXJMP(0x5A9180); } +WRAPPER RwImage* RwImageAllocatePixels(RwImage* image) { EAXJMP(0x5A91E0); } +WRAPPER RwImage* RwImageFreePixels(RwImage* image) { EAXJMP(0x5A92A0); } +WRAPPER RwImage* RwImageMakeMask(RwImage* image) { EAXJMP(0x5A92D0); } +WRAPPER RwImage* RwImageApplyMask(RwImage* image, RwImage const* mask) { EAXJMP(0x5A93A0); } +WRAPPER RwChar const* RwImageSetPath(RwChar const* path) { EAXJMP(0x5A9750); } +WRAPPER RwImage* RwImageRead(RwChar const* imageName) { EAXJMP(0x5A9810); } +WRAPPER RwChar const* RwImageFindFileType(RwChar const* imageName) { EAXJMP(0x5A9B40); } +WRAPPER RwImage* RwImageReadMaskedImage(RwChar const* imageName, RwChar const* maskname) { EAXJMP(0x5A9C10); } +WRAPPER RwImage* RwImageCopy(RwImage* destImage, RwImage const* sourceImage) { EAXJMP(0x5A9F50); } +WRAPPER RwImage* RwImageGammaCorrect(RwImage* image) { EAXJMP(0x5AA130); } +WRAPPER RwBool RwImageSetGamma(RwReal gammaValue) { EAXJMP(0x5AA2C0); } +WRAPPER RwStream* _rwStreamWriteVersionedChunkHeader(RwStream* stream, RwInt32 type, RwInt32 size, RwUInt32 version, RwUInt32 buildNum) { EAXJMP(0x5AA4E0); } +WRAPPER RwBool RwStreamFindChunk(RwStream* stream, RwUInt32 type, RwUInt32* lengthOut, RwUInt32* versionOut) { EAXJMP(0x5AA540); } +WRAPPER void* RwMemLittleEndian32(void* mem, RwUInt32 size) { EAXJMP(0x5AA640); } +WRAPPER void* RwMemNative32(void* mem, RwUInt32 size) { EAXJMP(0x5AA650); } +WRAPPER void* RwMemFloat32ToReal(void* mem, RwUInt32 size) { EAXJMP(0x5AA660); } +WRAPPER RwStream* RwStreamWriteReal(RwStream* stream, RwReal const* reals, RwUInt32 numBytes) { EAXJMP(0x5AA680); } +WRAPPER RwStream* RwStreamWriteInt32(RwStream* stream, RwInt32 const* ints, RwUInt32 numBytes) { EAXJMP(0x5AA720); } +WRAPPER RwStream* RwStreamReadReal(RwStream* stream, RwReal* reals, RwUInt32 numBytes) { EAXJMP(0x5AA740); } +WRAPPER RwStream* RwStreamReadInt32(RwStream* stream, RwInt32* ints, RwUInt32 numBytes) { EAXJMP(0x5AA7B0); } +WRAPPER RwUInt32 RwTextureStreamGetSize(RwTexture const* texture) { EAXJMP(0x5AA800); } +WRAPPER RwTexture const* RwTextureStreamWrite(RwTexture const* texture, RwStream* stream) { EAXJMP(0x5AA870); } +WRAPPER RwTexture* RwTextureStreamRead(RwStream* stream) { EAXJMP(0x5AAA40); } +WRAPPER RwTexDictionary const* RwTexDictionaryStreamWrite(RwTexDictionary const* texDict, RwStream* stream) { EAXJMP(0x5AB020); } +WRAPPER RpMorphTarget const* RpMorphTargetCalcBoundingSphere(RpMorphTarget const* morphTarget, RwSphere* boundingSphere) { EAXJMP(0x5AC890); } +WRAPPER RwInt32 RpGeometryAddMorphTargets(RpGeometry* geometry, RwInt32 mtcount) { EAXJMP(0x5AC9A0); } +WRAPPER RpGeometry const* RpGeometryTriangleSetVertexIndices(RpGeometry const* geometry, RpTriangle* triangle, RwUInt16 vert1, RwUInt16 vert2, RwUInt16 vert3) { EAXJMP(0x5ACB60); } +WRAPPER RpGeometry* RpGeometryTriangleSetMaterial(RpGeometry* geometry, RpTriangle* triangle, RpMaterial* material) { EAXJMP(0x5ACB90); } +WRAPPER RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, RpMaterialCallBack fpCallBack, void* pData) { EAXJMP(0x5ACBF0); } +WRAPPER RpGeometry* RpGeometryLock(RpGeometry* geometry, RwInt32 lockMode) { EAXJMP(0x5ACC30); } +WRAPPER RpGeometry* RpGeometryUnlock(RpGeometry* geometry) { EAXJMP(0x5ACC60); } +WRAPPER RpGeometry* RpGeometryCreate(RwInt32 numVert, RwInt32 numTriangles, RwUInt32 format) { EAXJMP(0x5ACD10); } +WRAPPER RpGeometry* _rpGeometryAddRef(RpGeometry* geometry) { EAXJMP(0x5ACF40); } +WRAPPER RwBool RpGeometryDestroy(RpGeometry* geometry) { EAXJMP(0x5ACF50); } +WRAPPER RwInt32 RpGeometryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5ACFF0); } +WRAPPER RwInt32 RpGeometryRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5AD020); } +WRAPPER RpGeometry* RpGeometryStreamRead(RwStream* stream) { EAXJMP(0x5AD050); } +WRAPPER RwRaster* RwRasterGetCurrentContext() { EAXJMP(0x5AD6D0); } +WRAPPER RwRaster* RwRasterUnlock(RwRaster* raster) { EAXJMP(0x5AD6F0); } +WRAPPER RwRaster* RwRasterRenderFast(RwRaster* raster, RwInt32 x, RwInt32 y) { EAXJMP(0x5AD710); } +WRAPPER RwRaster* RwRasterUnlockPalette(RwRaster* raster) { EAXJMP(0x5AD750); } +WRAPPER RwBool RwRasterDestroy(RwRaster* raster) { EAXJMP(0x5AD780); } +WRAPPER RwRaster* RwRasterPushContext(RwRaster* raster) { EAXJMP(0x5AD7C0); } +WRAPPER RwInt32 RwRasterRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5AD810); } +WRAPPER RwUInt8* RwRasterLockPalette(RwRaster* raster, RwInt32 lockMode) { EAXJMP(0x5AD840); } +WRAPPER RwRaster* RwRasterPopContext() { EAXJMP(0x5AD870); } +WRAPPER RwInt32 RwRasterGetNumLevels(RwRaster* raster) { EAXJMP(0x5AD8C0); } +WRAPPER RwRaster* RwRasterShowRaster(RwRaster* raster, void* dev, RwUInt32 flags) { EAXJMP(0x5AD900); } +WRAPPER RwRaster* RwRasterCreate(RwInt32 width, RwInt32 height, RwInt32 depth, RwInt32 flags) { EAXJMP(0x5AD930); } +WRAPPER RwUInt8* RwRasterLock(RwRaster* raster, RwUInt8 level, RwInt32 lockMode) { EAXJMP(0x5AD9D0); } +WRAPPER RpMaterial* RpMaterialCreate() { EAXJMP(0x5ADC30); } +WRAPPER RwBool RpMaterialDestroy(RpMaterial* material) { EAXJMP(0x5ADCB0); } +WRAPPER RpMaterial* RpMaterialSetTexture(RpMaterial* material, RwTexture* texture) { EAXJMP(0x5ADD10); } +WRAPPER RwInt32 RpMaterialRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5ADD40); } +WRAPPER RwInt32 RpMaterialRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5ADD70); } +WRAPPER RpMaterial* RpMaterialStreamRead(RwStream* stream) { EAXJMP(0x5ADDA0); } +WRAPPER RpWorldSector* _rpSectorDefaultRenderCallBack(RpWorldSector* sector) { EAXJMP(0x5AE0B0); } +WRAPPER RwBool _rpWorldForAllGlobalLights(RpLightCallBack callBack, void* pData) { EAXJMP(0x5AE100); } +WRAPPER RpWorldSector* _rpWorldSectorForAllLocalLights(RpWorldSector* sector, RpLightCallBack callBack, void* pData) { EAXJMP(0x5AE150); } +WRAPPER RpWorld* RpWorldUnlock(RpWorld* world) { EAXJMP(0x5AE190); } +WRAPPER RpWorld* RpWorldSectorGetWorld(RpWorldSector const* sector) { EAXJMP(0x5AE2B0); } +WRAPPER RwBool RpWorldDestroy(RpWorld* world) { EAXJMP(0x5AE340); } +WRAPPER RpWorld* RpWorldCreate(RwBBox* boundingBox) { EAXJMP(0x5AE6A0); } +WRAPPER RwInt32 RpWorldRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5AEA40); } +WRAPPER RwInt32 RpWorldRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5AEA70); } +WRAPPER RwBool RpWorldPluginAttach() { EAXJMP(0x5AEAA0); } +WRAPPER RpWorld* RpWorldAddCamera(RpWorld* world, RwCamera* camera) { EAXJMP(0x5AFB80); } +WRAPPER RpWorld* RpWorldRemoveCamera(RpWorld* world, RwCamera* camera) { EAXJMP(0x5AFBB0); } +WRAPPER RpWorld* RpAtomicGetWorld(RpAtomic const* atomic) { EAXJMP(0x5AFC10); } +WRAPPER RpWorld* RpWorldAddClump(RpWorld* world, RpClump* clump) { EAXJMP(0x5AFC20); } +WRAPPER RpWorld* RpWorldAddLight(RpWorld* world, RpLight* light) { EAXJMP(0x5AFDA0); } +WRAPPER RpWorld* RpWorldRemoveLight(RpWorld* world, RpLight* light) { EAXJMP(0x5AFDF0); } +WRAPPER RwImage* RtBMPImageRead(RwChar const* imageName) { EAXJMP(0x5AFE70); } +WRAPPER RwBool RpSkinPluginAttach() { EAXJMP(0x5B07D0); } +WRAPPER RpAtomic* RpSkinAtomicSetHAnimHierarchy(RpAtomic* atomic, RpHAnimHierarchy* hierarchy) { EAXJMP(0x5B1050); } +WRAPPER RpHAnimHierarchy* RpSkinAtomicGetHAnimHierarchy(RpAtomic const* atomic) { EAXJMP(0x5B1070); } +WRAPPER RpSkin* RpSkinGeometryGetSkin(RpGeometry* geometry) { EAXJMP(0x5B1080); } +WRAPPER RpGeometry* RpSkinGeometrySetSkin(RpGeometry* geometry, RpSkin* skin) { EAXJMP(0x5B1090); } +WRAPPER RwMatrix const* RpSkinGetSkinToBoneMatrices(RpSkin* skin) { EAXJMP(0x5B10D0); } +WRAPPER RpHAnimHierarchy* RpHAnimHierarchyCreate(RwInt32 numNodes, RwUInt32* nodeFlags, RwInt32* nodeIDs, RpHAnimHierarchyFlag flags, RwInt32 maxKeyFrameSize) { EAXJMP(0x5B10E0); } +WRAPPER RpHAnimHierarchy* RpHAnimFrameGetHierarchy(RwFrame* frame) { EAXJMP(0x5B11F0); } +WRAPPER RwBool RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy* hierarchy, RpHAnimAnimation* anim) { EAXJMP(0x5B1200); } +WRAPPER RwBool RpHAnimHierarchySubAnimTime(RpHAnimHierarchy* hierarchy, RwReal time) { EAXJMP(0x5B12B0); } +WRAPPER RwBool RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy* hierarchy, RwReal time) { EAXJMP(0x5B1480); } +WRAPPER RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy* hierarchy) { EAXJMP(0x5B1780); } +WRAPPER RpHAnimAnimation* RpHAnimAnimationStreamRead(RwStream* stream) { EAXJMP(0x5B1C10); } +WRAPPER RwBool RpHAnimPluginAttach() { EAXJMP(0x5B1D50); } +WRAPPER RwBool RpMatFXPluginAttach() { EAXJMP(0x5B2640); } +WRAPPER RpAtomic* RpMatFXAtomicEnableEffects(RpAtomic* atomic) { EAXJMP(0x5B3750); } +WRAPPER RpMaterial* RpMatFXMaterialSetEffects(RpMaterial* material, RpMatFXMaterialFlags flags) { EAXJMP(0x5B3780); } +WRAPPER RpMaterial* RpMatFXMaterialSetupEnvMap(RpMaterial* material, RwTexture* texture, RwFrame* frame, RwBool useFrameBufferAlpha, RwReal coef) { EAXJMP(0x5B38D0); } +WRAPPER RpMaterial* RpMatFXMaterialSetBumpMapTexture(RpMaterial* material, RwTexture* texture) { EAXJMP(0x5B3A40); } +WRAPPER RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) { EAXJMP(0x5B3CF0); } +WRAPPER void RwD3D8GetRenderState(RwUInt32 state, void* value) { EAXJMP(0x5B3D40); } +WRAPPER RwBool RwD3D8SetTextureStageState(RwUInt32 stage, RwUInt32 type, RwUInt32 value) { EAXJMP(0x5B3D60); } +WRAPPER RwBool RwD3D8SetTexture(RwTexture* texture, RwUInt32 stage) { EAXJMP(0x5B53A0); } +WRAPPER void* RwIm3DTransform(RwIm3DVertex* pVerts, RwUInt32 numVerts, RwMatrix* ltm, RwUInt32 flags) { EAXJMP(0x5B6720); } +WRAPPER RwBool RwIm3DEnd() { EAXJMP(0x5B67F0); } +WRAPPER RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType, RwImVertexIndex* indices, RwInt32 numIndices) { EAXJMP(0x5B6820); } +WRAPPER RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2) { EAXJMP(0x5B6980); } +WRAPPER RxPipeline* RwIm3DSetTransformPipeline(RxPipeline* pipeline) { EAXJMP(0x5B6A50); } +WRAPPER RxPipeline* RwIm3DSetRenderPipeline(RxPipeline* pipeline, RwPrimitiveType primType) { EAXJMP(0x5B6AC0); } +WRAPPER void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) { EAXJMP(0x5B95D0); } +WRAPPER RwBool RwD3D8CameraAttachWindow(void* camera, void* hwnd) { EAXJMP(0x5B9640); } +WRAPPER RwBool RwD3D8DeviceSupportsDXTTexture() { EAXJMP(0x5BAEB0); } +WRAPPER RwBool RwD3D8SetVertexShader(RwUInt32 handle) { EAXJMP(0x5BAF90); } +WRAPPER RwBool RwD3D8SetPixelShader(RwUInt32 handle) { EAXJMP(0x5BAFD0); } +WRAPPER RwBool RwD3D8SetStreamSource(RwUInt32 streamNumber, void* streamData, RwUInt32 stride) { EAXJMP(0x5BB010); } +WRAPPER RwBool RwD3D8SetIndices(void* indexData, RwUInt32 baseVertexIndex) { EAXJMP(0x5BB060); } +WRAPPER RwBool RwD3D8DrawIndexedPrimitive(RwUInt32 primitiveType, RwUInt32 minIndex, RwUInt32 numVertices, RwUInt32 startIndex, RwUInt32 numIndices) { EAXJMP(0x5BB0B0); } +WRAPPER RwBool RwD3D8DrawPrimitive(RwUInt32 primitiveType, RwUInt32 startVertex, RwUInt32 numVertices) { EAXJMP(0x5BB140); } +WRAPPER RwBool RwD3D8SetTransform(RwUInt32 state, void const* matrix) { EAXJMP(0x5BB1D0); } +WRAPPER void RwD3D8GetTransform(RwUInt32 state, void* matrix) { EAXJMP(0x5BB310); } +WRAPPER RwBool RwD3D8SetTransformWorld(RwMatrix const* matrix) { EAXJMP(0x5BB340); } +WRAPPER RwBool RwD3D8SetSurfaceProperties(RwRGBA const* color, RwSurfaceProperties const* surfaceProps, RwBool modulate) { EAXJMP(0x5BB490); } +WRAPPER RwBool RwD3D8SetLight(RwInt32 index, void const* light) { EAXJMP(0x5BB7A0); } +WRAPPER RwBool RwD3D8EnableLight(RwInt32 index, RwBool enable) { EAXJMP(0x5BB890); } +WRAPPER RwBool RwD3D8DynamicVertexBufferCreate(RwUInt32 fvf, RwUInt32 size, void** vertexBuffer) { EAXJMP(0x5BB9F0); } +WRAPPER void RwD3D8DynamicVertexBufferDestroy(void* vertexBuffer) { EAXJMP(0x5BBAE0); } +WRAPPER RwBool RwD3D8IndexBufferCreate(RwUInt32 numIndices, void** indexBuffer) { EAXJMP(0x5BBB10); } +WRAPPER RwBool RwD3D8CreatePixelShader(RwUInt32 const* function, RwUInt32* handle) { EAXJMP(0x5BBB40); } +WRAPPER void RwD3D8DeletePixelShader(RwUInt32 handle) { EAXJMP(0x5BBB90); } +WRAPPER RwBool RwD3D8SetPixelShaderConstant(RwUInt32 registerAddress, void const* antData, RwUInt32 antCount) { EAXJMP(0x5BBC00); } +WRAPPER void const* RwD3D8GetCaps() { EAXJMP(0x5BBC30); } +WRAPPER RwBool RwD3D8CameraIsSphereFullyInsideFrustum(void const* camera, void const* sphere) { EAXJMP(0x5BBC40); } +WRAPPER RwBool RwD3D8CameraIsBBoxFullyInsideFrustum(void const* camera, void const* boundingBox) { EAXJMP(0x5BBCA0); } +WRAPPER RwBool RwD3D8DynamicVertexBufferLock(RwUInt32 vertexSize, RwUInt32 numVertex, void** vertexBufferOut, void** vertexDataOut, RwUInt32* baseIndexOut) { EAXJMP(0x5BBD30); } +WRAPPER RwBool RwD3D8DynamicVertexBufferUnlock(void* vertexBuffer) { EAXJMP(0x5BBEB0); } +WRAPPER RwBool _rwIntelSSEsupported() { EAXJMP(0x5BBED0); } +WRAPPER RwImage* RwImageSetFromRaster(RwImage* image, RwRaster* raster) { EAXJMP(0x5BBF10); } +WRAPPER RwRaster* RwRasterSetFromImage(RwRaster* raster, RwImage* image) { EAXJMP(0x5BBF50); } +WRAPPER RwImage* RwImageFindRasterFormat(RwImage* ipImage, RwInt32 nRasterType, RwInt32* npWidth, RwInt32* npHeight, RwInt32* npDepth, RwInt32* npFormat) { EAXJMP(0x5BBF80); } +WRAPPER RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5BBFF0); } +WRAPPER rwFrameList* _rwFrameListDeinitialize(rwFrameList* frameList) { EAXJMP(0x5BC020); } +WRAPPER rwFrameList* _rwFrameListStreamRead(RwStream* stream, rwFrameList* fl) { EAXJMP(0x5BC050); } +WRAPPER RpLight* RpLightSetRadius(RpLight* light, RwReal radius) { EAXJMP(0x5BC300); } +WRAPPER RpLight* RpLightSetColor(RpLight* light, RwRGBAReal const* color) { EAXJMP(0x5BC320); } +WRAPPER RwReal RpLightGetConeAngle(RpLight const* light) { EAXJMP(0x5BC370); } +WRAPPER RwInt32 RpLightRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5BC5B0); } +WRAPPER RpLight* RpLightStreamRead(RwStream* stream) { EAXJMP(0x5BC5E0); } +WRAPPER RwBool RpLightDestroy(RpLight* light) { EAXJMP(0x5BC780); } +WRAPPER RpLight* RpLightCreate(RwInt32 type) { EAXJMP(0x5BC7C0); } +WRAPPER void _rwD3D8TexDictionaryEnableRasterFormatConversion(RwBool enable) { EAXJMP(0x5BE280); } +WRAPPER RwFileFunctions* RwOsGetFileInterface() { EAXJMP(0x5BF110); } +WRAPPER RwBool RwFreeListDestroy(RwFreeList* freelist) { EAXJMP(0x5C1720); } +WRAPPER RwFreeList* RwFreeListCreate(RwInt32 entrySize, RwInt32 entriesPerBlock, RwInt32 alignment) { EAXJMP(0x5C1790); } +WRAPPER RwInt32 RwFreeListPurge(RwFreeList* freelist) { EAXJMP(0x5C19F0); } +WRAPPER RwInt32 RwFreeListPurgeAllFreeLists() { EAXJMP(0x5C1B90); } +WRAPPER RwFreeList* RwFreeListForAllUsed(RwFreeList* freelist, RwFreeListCallBack fpCallBack, void* pData) { EAXJMP(0x5C1D40); } +WRAPPER RwBool _rxPipelineClose() { EAXJMP(0x5C2780); } +WRAPPER RwBool _rxPipelineOpen() { EAXJMP(0x5C27E0); } +WRAPPER RxHeap* RxHeapGetGlobalHeap() { EAXJMP(0x5C2AD0); } +WRAPPER RxPacket* RxPacketCreate(RxPipelineNode* node) { EAXJMP(0x5C2AE0); } +WRAPPER RxCluster* RxClusterSetExternalData(RxCluster* cluster, void* data, RwInt32 stride, RwInt32 numElements) { EAXJMP(0x5C2B10); } +WRAPPER RxCluster* RxClusterSetData(RxCluster* cluster, void* data, RwInt32 stride, RwInt32 numElements) { EAXJMP(0x5C2B70); } +WRAPPER RxCluster* RxClusterInitializeData(RxCluster* cluster, RwUInt32 numElements, RwUInt16 stride) { EAXJMP(0x5C2BD0); } +WRAPPER RxCluster* RxClusterResizeData(RxCluster* CurrentCluster, RwUInt32 NumElements) { EAXJMP(0x5C2C40); } +WRAPPER RxCluster* RxClusterLockWrite(RxPacket* packet, RwUInt32 clusterIndex, RxPipelineNode* node) { EAXJMP(0x5C2C90); } +WRAPPER RxPipeline* RxPipelineExecute(RxPipeline* pipeline, void* data, RwBool heapReset) { EAXJMP(0x5C2D60); } +WRAPPER RxPipeline* RxPipelineCreate() { EAXJMP(0x5C2E00); } +WRAPPER void _rxPipelineDestroy(RxPipeline* Pipeline) { EAXJMP(0x5C2E70); } +WRAPPER RwBool RwResourcesFreeResEntry(RwResEntry* entry) { EAXJMP(0x5C3080); } +WRAPPER void _rwResourcesPurge() { EAXJMP(0x5C30F0); } +WRAPPER RwResEntry* RwResourcesAllocateResEntry(void* owner, RwResEntry** ownerRef, RwInt32 size, RwResEntryDestroyNotify destroyNotify) { EAXJMP(0x5C3170); } +WRAPPER RwBool RwResourcesEmptyArena() { EAXJMP(0x5C3360); } +WRAPPER RwBool _rwPluginRegistryOpen() { EAXJMP(0x5C3450); } +WRAPPER RwBool _rwPluginRegistryClose() { EAXJMP(0x5C3480); } +WRAPPER RwInt32 _rwPluginRegistryGetPluginOffset(RwPluginRegistry const* reg, RwUInt32 pluginID) { EAXJMP(0x5C3590); } +WRAPPER RwInt32 _rwPluginRegistryAddPlugin(RwPluginRegistry* reg, RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5C35C0); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryInitObject(RwPluginRegistry const* reg, void* object) { EAXJMP(0x5C37F0); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryDeInitObject(RwPluginRegistry const* reg, void* object) { EAXJMP(0x5C3850); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryCopyObject(RwPluginRegistry const* reg, void* dstObject, void const* srcObject) { EAXJMP(0x5C3880); } +WRAPPER RwError* RwErrorSet(RwError* code) { EAXJMP(0x5C3910); } +WRAPPER RwInt32 _rwerror(RwInt32 code, ...) { EAXJMP(0x5C3970); } +WRAPPER RwInt32 _rwPluginRegistryAddPluginStream(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5C3980); } +WRAPPER RwInt32 _rwPluginRegistryAddPlgnStrmlwysCB(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB) { EAXJMP(0x5C39C0); } +WRAPPER RwInt32 _rwPluginRegistryAddPlgnStrmRightsCB(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB) { EAXJMP(0x5C39F0); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryReadDataChunks(RwPluginRegistry const* reg, RwStream* stream, void* object) { EAXJMP(0x5C3A20); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryInvokeRights(RwPluginRegistry const* reg, RwUInt32 id, void* obj, RwUInt32 extraData) { EAXJMP(0x5C3B50); } +WRAPPER RwInt32 _rwPluginRegistryGetSize(RwPluginRegistry const* reg, void const* object) { EAXJMP(0x5C3BA0); } +WRAPPER RwPluginRegistry const* _rwPluginRegistryWriteDataChunks(RwPluginRegistry const* reg, RwStream* stream, void const* object) { EAXJMP(0x5C3BE0); } +WRAPPER RwPluginRegistry const* _rwPluginRegistrySkipDataChunks(RwPluginRegistry const* reg, RwStream* stream) { EAXJMP(0x5C3CB0); } +WRAPPER RwCamera* RwCameraStreamRead(RwStream* stream) { EAXJMP(0x5C3D30); } +WRAPPER RwBBox* RwBBoxCalculate(RwBBox* boundBox, RwV3d const* verts, RwInt32 numVerts) { EAXJMP(0x5C5570); } +WRAPPER RwImage* RwImageResample(RwImage* dstImage, RwImage const* srcImage) { EAXJMP(0x5C72B0); } +WRAPPER RwImage* RwImageCreateResample(RwImage const* srcImage, RwInt32 width, RwInt32 height) { EAXJMP(0x5C7B30); } +WRAPPER RxRenderStateVector* RxRenderStateVectorSetDefaultRenderStateVector(RxRenderStateVector* rsvp) { EAXJMP(0x5D9240); } +WRAPPER RxRenderStateVector* RxRenderStateVectorCreate(RwBool current) { EAXJMP(0x5D9340); } +WRAPPER void RxRenderStateVectorDestroy(RxRenderStateVector* rsvp) { EAXJMP(0x5D9410); } +WRAPPER RxRenderStateVector* RxRenderStateVectorLoadDriverState(RxRenderStateVector* rsvp) { EAXJMP(0x5D9460); } +WRAPPER void _rxEmbeddedPacketBetweenPipelines(RxPipeline* fromPipeline, RxPipeline* toPipeline) { EAXJMP(0x5D95D0); } +WRAPPER RxPipelineNode* _rxEmbeddedPacketBetweenNodes(RxPipeline* pipeline, RxPipelineNode* nodeFrom, RwUInt32 whichOutput) { EAXJMP(0x5D9740); } +WRAPPER void _rxPacketDestroy(RxPacket* Packet) { EAXJMP(0x5D9810); } +WRAPPER RpMaterialList* _rpMaterialListDeinitialize(RpMaterialList* matList) { EAXJMP(0x5C8B10); } +WRAPPER RpMaterialList* _rpMaterialListInitialize(RpMaterialList* matList) { EAXJMP(0x5C8B70); } +WRAPPER RpMaterial* _rpMaterialListGetMaterial(RpMaterialList const* matList, RwInt32 matIndex) { EAXJMP(0x5C8B80); } +WRAPPER RwInt32 _rpMaterialListAppendMaterial(RpMaterialList* matList, RpMaterial* material) { EAXJMP(0x5C8B90); } +WRAPPER RwInt32 _rpMaterialListFindMaterialIndex(RpMaterialList const* matList, RpMaterial const* material) { EAXJMP(0x5C8C50); } +WRAPPER RpMaterialList* _rpMaterialListStreamRead(RwStream* stream, RpMaterialList* matList) { EAXJMP(0x5C8C80); } +WRAPPER RpMeshHeader* _rpMeshHeaderCreate(RwUInt32 size) { EAXJMP(0x5C8FE0); } +WRAPPER void* _rpMeshClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5C8FF0); } +WRAPPER void* _rpMeshOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5C9020); } +WRAPPER RpBuildMesh* _rpBuildMeshCreate(RwUInt32 bufferSize) { EAXJMP(0x5C9140); } +WRAPPER RwBool _rpBuildMeshDestroy(RpBuildMesh* mesh) { EAXJMP(0x5C9220); } +WRAPPER RwBool _rpMeshDestroy(RpMeshHeader* mesh) { EAXJMP(0x5C9260); } +WRAPPER RpBuildMesh* _rpBuildMeshAddTriangle(RpBuildMesh* mesh, RpMaterial* material, RwInt32 vert1, RwInt32 vert2, RwInt32 vert3) { EAXJMP(0x5C92A0); } +WRAPPER RpMeshHeader* _rpMeshHeaderForAllMeshes(RpMeshHeader* meshHeader, RpMeshCallBack fpCallBack, void* pData) { EAXJMP(0x5C9380); } +WRAPPER RwStream* _rpMeshWrite(RpMeshHeader const* meshHeader, void const* object, RwStream* stream, RpMaterialList const* matList) { EAXJMP(0x5C93C0); } +WRAPPER RpMeshHeader* _rpMeshRead(RwStream* stream, void const* object, RpMaterialList const* matList) { EAXJMP(0x5C9510); } +WRAPPER RwInt32 _rpMeshSize(RpMeshHeader const* meshHeader, void const* object) { EAXJMP(0x5C96E0); } +WRAPPER RpMeshHeader* RpBuildMeshGenerateDefaultTriStrip(RpBuildMesh* buildmesh, void* data) { EAXJMP(0x5C9730); } +WRAPPER RpMeshHeader* _rpTriListMeshGenerate(RpBuildMesh* buildMesh, void* data) { EAXJMP(0x5CAE10); } +WRAPPER RpMeshHeader* _rpMeshOptimise(RpBuildMesh* buildmesh, RwUInt32 flags) { EAXJMP(0x5CB230); } +WRAPPER RwInt32 RpWorldSectorRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5CB2B0); } +WRAPPER RwInt32 RpWorldSectorRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5CB2E0); } +WRAPPER RxPipeline* RpWorldSetDefaultSectorPipeline(RxPipeline* pipeline) { EAXJMP(0x5CB630); } +WRAPPER RxPipeline* RpAtomicSetDefaultPipeline(RxPipeline* pipeline) { EAXJMP(0x5CB670); } +WRAPPER void RpHAnimStdKeyFrameToMatrix(RwMatrix* matrix, void* voidIFrame) { EAXJMP(0x5CDEE0); } +WRAPPER void RpHAnimStdKeyFrameInterpolate(void* voidOut, void* voidIn1, void* voidIn2, RwReal time) { EAXJMP(0x5CE000); } +WRAPPER void RpHAnimStdKeyFrameBlend(void* voidOut, void* voidIn1, void* voidIn2, RwReal alpha) { EAXJMP(0x5CE420); } +WRAPPER RpHAnimAnimation* RpHAnimStdKeyFrameStreamRead(RwStream* stream, RpHAnimAnimation* animation) { EAXJMP(0x5CE820); } +WRAPPER RwBool RpHAnimStdKeyFrameStreamWrite(RpHAnimAnimation* animation, RwStream* stream) { EAXJMP(0x5CE8C0); } +WRAPPER RwInt32 RpHAnimStdKeyFrameStreamGetSize(RpHAnimAnimation* animation) { EAXJMP(0x5CE930); } +WRAPPER void RpHAnimStdKeyFrameMulRecip(void* voidFrame, void* voidStart) { EAXJMP(0x5CE950); } +WRAPPER void RpHAnimStdKeyFrameAdd(void* voidOut, void* voidIn1, void* voidIn2) { EAXJMP(0x5CEAB0); } +WRAPPER void RxHeapFree(RxHeap* heap, void* block) { EAXJMP(0x5D1070); } +WRAPPER void* RxHeapAlloc(RxHeap* heap, RwUInt32 size) { EAXJMP(0x5D1260); } +WRAPPER void* RxHeapRealloc(RxHeap* heap, void* block, RwUInt32 newSize, RwBool allowCopy) { EAXJMP(0x5D14D0); } +WRAPPER RwBool _rxHeapReset(RxHeap* heap) { EAXJMP(0x5D1680); } +WRAPPER void RxHeapDestroy(RxHeap* heap) { EAXJMP(0x5D16F0); } +WRAPPER RxHeap* RxHeapCreate(RwUInt32 size) { EAXJMP(0x5D1750); } +WRAPPER RxNodeOutput RxPipelineNodeFindOutputByName(RxPipelineNode* node, RwChar const* outputname) { EAXJMP(0x5D1EC0); } +WRAPPER RxNodeInput RxPipelineNodeFindInput(RxPipelineNode* node) { EAXJMP(0x5D1F20); } +WRAPPER RxPipeline* RxPipelineNodeRequestCluster(RxPipeline* pipeline, RxPipelineNode* node, RxClusterDefinition* clusterDef) { EAXJMP(0x5D1F30); } +WRAPPER RxPipeline* RxLockedPipeUnlock(RxLockedPipe* pipeline) { EAXJMP(0x5D1FA0); } +WRAPPER RxLockedPipe* RxPipelineLock(RxPipeline* pipeline) { EAXJMP(0x5D29F0); } +WRAPPER RxPipelineNode* RxPipelineFindNodeByName(RxPipeline* pipeline, RwChar const* name, RxPipelineNode* start, RwInt32* nodeIndex) { EAXJMP(0x5D2B10); } +WRAPPER RxLockedPipe* RxLockedPipeAddFragment(RxLockedPipe *pipeline, RwUInt32 *firstIndex, RxNodeDefinition *nodeDef0, ...) { EAXJMP(0x5D2BA0); } +WRAPPER RxPipeline* RxLockedPipeAddPath(RxLockedPipe* pipeline, RxNodeOutput out, RxNodeInput in) { EAXJMP(0x5D2EE0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmRenderSetup() { EAXJMP(0x5D31C0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmMangleTriangleIndices() { EAXJMP(0x5D35C0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetCullTriangle() { EAXJMP(0x5D3C60); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetClipTriangle() { EAXJMP(0x5D4F80); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetSubmitTriangle() { EAXJMP(0x5D51C0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmInstance() { EAXJMP(0x5D5400); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetTransform() { EAXJMP(0x5D6000); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmStash() { EAXJMP(0x5D61C0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmMangleLineIndices() { EAXJMP(0x5D6470); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetClipLine() { EAXJMP(0x5D7230); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetSubmitLine() { EAXJMP(0x5D74C0); } +WRAPPER RwBool _rwD3D8LightsOpen() { EAXJMP(0x5D9C90); } +WRAPPER void _rwD3D8LightsClose() { EAXJMP(0x5D9EF0); } +WRAPPER RwBool _rwD3D8LightsGlobalEnable(RpLightFlag flags) { EAXJMP(0x5D9F80); } +WRAPPER RwBool _rwD3D8LightLocalEnable(RpLight* light) { EAXJMP(0x5DA210); } +WRAPPER void _rwD3D8LightsEnable(RwBool enable, RwUInt32 type) { EAXJMP(0x5DA450); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetD3D8WorldSectorAllInOne() { EAXJMP(0x5DAAC0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetD3D8AtomicAllInOne() { EAXJMP(0x5DC500); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetWorldSectorInstance() { EAXJMP(0x5DCC50); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetWorldSectorEnumerateLights() { EAXJMP(0x5DCD80); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetAtomicInstance() { EAXJMP(0x5DD800); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetAtomicEnumerateLights() { EAXJMP(0x5DD9B0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetMaterialScatter() { EAXJMP(0x5DDAA0); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetLight() { EAXJMP(0x5DF040); } +WRAPPER RxNodeDefinition* RxNodeDefinitionGetPostLight() { EAXJMP(0x5DF560); } +WRAPPER void RxD3D8AllInOneSetRenderCallBack(RxPipelineNode* node, RxD3D8AllInOneRenderCallBack callback) { EAXJMP(0x5DFC60); } +#else + +extern "C" +{ + void* _rwFrameOpen(void* instance, RwInt32 offset, RwInt32 size); + void* _rwFrameClose(void* instance, RwInt32 offset, RwInt32 size); + RwFrame* _rwFrameCloneAndLinkClones(RwFrame* root); + RwFrame* _rwFramePurgeClone(RwFrame* root); + RwBool RwFrameDirty(RwFrame const* frame); + void _rwFrameInit(RwFrame* frame); + RwBool _rwMatrixSetMultFn(rwMatrixMultFn multMat); + void* _rwMatrixClose(void* instance, RwInt32 offset, RwInt32 size); + void* _rwMatrixOpen(void* instance, RwInt32 offset, RwInt32 size); + RwBool _rwVectorSetMultFn(rwVectorMultFn multPoint, rwVectorsMultFn multPoints, rwVectorMultFn multVector, rwVectorsMultFn multVectors); + void* _rwVectorClose(void* instance, RwInt32 offset, RwInt32 size); + void* _rwVectorOpen(void* instance, RwInt32 offset, RwInt32 size); + RwBool _rwPluginRegistryOpen(); + RwBool _rwPluginRegistryClose(); +} + +STARTPATCHES +InjectHook(0x5BC950, &_rwObjectHasFrameSetFrame, PATCH_JUMP); +InjectHook(0x59E690, &AtomicDefaultRenderCallBack, PATCH_JUMP); +InjectHook(0x59E6C0, &_rpAtomicResyncInterpolatedSphere, PATCH_JUMP); +InjectHook(0x59E800, &RpAtomicGetWorldBoundingSphere, PATCH_JUMP); +InjectHook(0x59ED50, &RpClumpGetNumAtomics, PATCH_JUMP); +InjectHook(0x59ED80, &RpClumpRender, PATCH_JUMP); +InjectHook(0x59EDD0, &RpClumpForAllAtomics, PATCH_JUMP); +InjectHook(0x59EE10, &RpClumpForAllCameras, PATCH_JUMP); +InjectHook(0x59EE60, &RpClumpForAllLights, PATCH_JUMP); +InjectHook(0x59EEB0, &RpAtomicCreate, PATCH_JUMP); +InjectHook(0x59EFA0, &RpAtomicSetGeometry, PATCH_JUMP); +InjectHook(0x59F020, &RpAtomicDestroy, PATCH_JUMP); +InjectHook(0x59F0A0, &RpAtomicClone, PATCH_JUMP); +InjectHook(0x59F1B0, &RpClumpClone, PATCH_JUMP); +InjectHook(0x59F490, &RpClumpCreate, PATCH_JUMP); +InjectHook(0x59F500, &RpClumpDestroy, PATCH_JUMP); +InjectHook(0x59F680, &RpClumpAddAtomic, PATCH_JUMP); +InjectHook(0x59F6B0, &RpClumpRemoveAtomic, PATCH_JUMP); +InjectHook(0x59F6E0, &RpClumpRemoveLight, PATCH_JUMP); +InjectHook(0x59FC50, &RpClumpStreamRead, PATCH_JUMP); +InjectHook(0x5A0510, &RpAtomicRegisterPlugin, PATCH_JUMP); +InjectHook(0x5A0540, &RpClumpRegisterPlugin, PATCH_JUMP); +InjectHook(0x5A0570, &RpAtomicRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5A05A0, &RpAtomicSetStreamAlwaysCallBack, PATCH_JUMP); +InjectHook(0x5A05C0, &RpAtomicSetStreamRightsCallBack, PATCH_JUMP); +InjectHook(0x5A05E0, &RpAtomicGetPluginOffset, PATCH_JUMP); +InjectHook(0x5A0600, &RpAtomicSetFrame, PATCH_JUMP); +InjectHook(0x5A0DC0, &RwEngineRegisterPlugin, PATCH_JUMP); +InjectHook(0x5A0DF0, &RwEngineGetPluginOffset, PATCH_JUMP); +InjectHook(0x5A0E10, &RwEngineGetNumSubSystems, PATCH_JUMP); +InjectHook(0x5A0E40, &RwEngineGetSubSystemInfo, PATCH_JUMP); +InjectHook(0x5A0E70, &RwEngineGetCurrentSubSystem, PATCH_JUMP); +InjectHook(0x5A0EA0, &RwEngineSetSubSystem, PATCH_JUMP); +InjectHook(0x5A0ED0, &RwEngineGetNumVideoModes, PATCH_JUMP); +InjectHook(0x5A0F00, &RwEngineGetVideoModeInfo, PATCH_JUMP); +InjectHook(0x5A0F30, &RwEngineGetCurrentVideoMode, PATCH_JUMP); +InjectHook(0x5A0F60, &RwEngineSetVideoMode, PATCH_JUMP); +InjectHook(0x5A0F90, &RwEngineStop, PATCH_JUMP); +InjectHook(0x5A0FE0, &RwEngineStart, PATCH_JUMP); +InjectHook(0x5A1070, &RwEngineClose, PATCH_JUMP); +InjectHook(0x5A10E0, &RwEngineOpen, PATCH_JUMP); +InjectHook(0x5A1290, &RwEngineTerm, PATCH_JUMP); +InjectHook(0x5A12D0, &RwEngineInit, PATCH_JUMP); +InjectHook(0x5A15E0, &_rwFrameOpen, PATCH_JUMP); +InjectHook(0x5A1650, &_rwFrameClose, PATCH_JUMP); +InjectHook(0x5A1690, &_rwFrameCloneAndLinkClones, PATCH_JUMP); +InjectHook(0x5A1880, &_rwFramePurgeClone, PATCH_JUMP); +InjectHook(0x5A1930, &RwFrameDirty, PATCH_JUMP); +InjectHook(0x5A1950, &_rwFrameInit, PATCH_JUMP); +InjectHook(0x5A1A00, &RwFrameCreate, PATCH_JUMP); +InjectHook(0x5A1A30, &RwFrameDestroy, PATCH_JUMP); +InjectHook(0x5A1BF0, &RwFrameDestroyHierarchy, PATCH_JUMP); +InjectHook(0x5A1C60, &RwFrameUpdateObjects, PATCH_JUMP); +InjectHook(0x5A1CE0, &RwFrameGetLTM, PATCH_JUMP); +InjectHook(0x5A1D00, &RwFrameAddChild, PATCH_JUMP); +InjectHook(0x5A1ED0, &RwFrameRemoveChild, PATCH_JUMP); +InjectHook(0x5A1FC0, &RwFrameForAllChildren, PATCH_JUMP); +InjectHook(0x5A2000, &RwFrameTranslate, PATCH_JUMP); +InjectHook(0x5A20A0, &RwFrameScale, PATCH_JUMP); +InjectHook(0x5A2140, &RwFrameTransform, PATCH_JUMP); +InjectHook(0x5A21E0, &RwFrameRotate, PATCH_JUMP); +InjectHook(0x5A2280, &RwFrameSetIdentity, PATCH_JUMP); +InjectHook(0x5A2340, &RwFrameForAllObjects, PATCH_JUMP); +InjectHook(0x5A2380, &RwFrameRegisterPlugin, PATCH_JUMP); +InjectHook(0x5A23B0, &_rwMatrixSetMultFn, PATCH_JUMP); +InjectHook(0x5A2520, &_rwMatrixDeterminant, PATCH_JUMP); +InjectHook(0x5A2570, &_rwMatrixOrthogonalError, PATCH_JUMP); +InjectHook(0x5A25D0, &_rwMatrixNormalError, PATCH_JUMP); +InjectHook(0x5A2660, &_rwMatrixIdentityError, PATCH_JUMP); +InjectHook(0x5A2730, &_rwMatrixClose, PATCH_JUMP); +InjectHook(0x5A2770, &_rwMatrixOpen, PATCH_JUMP); +InjectHook(0x5A2820, &RwMatrixOptimize, PATCH_JUMP); +InjectHook(0x5A28E0, &RwMatrixUpdate, PATCH_JUMP); +InjectHook(0x5A28F0, &RwMatrixMultiply, PATCH_JUMP); +InjectHook(0x5A2960, &RwMatrixRotateOneMinusCosineSine, PATCH_JUMP); +InjectHook(0x5A2BF0, &RwMatrixRotate, PATCH_JUMP); +InjectHook(0x5A2C90, &RwMatrixInvert, PATCH_JUMP); +InjectHook(0x5A2EE0, &RwMatrixScale, PATCH_JUMP); +InjectHook(0x5A3070, &RwMatrixTranslate, PATCH_JUMP); +InjectHook(0x5A31C0, &RwMatrixTransform, PATCH_JUMP); +InjectHook(0x5A3300, &RwMatrixDestroy, PATCH_JUMP); +InjectHook(0x5A3330, &RwMatrixCreate, PATCH_JUMP); +InjectHook(0x5A3450, &_rwVectorSetMultFn, PATCH_JUMP); +InjectHook(0x5A3600, &_rwV3dNormalize, PATCH_JUMP); +InjectHook(0x5A36A0, &RwV3dLength, PATCH_JUMP); +InjectHook(0x5A3710, &_rwSqrt, PATCH_JUMP); +InjectHook(0x5A3770, &_rwInvSqrt, PATCH_JUMP); +InjectHook(0x5A37D0, &RwV3dTransformPoints, PATCH_JUMP); +InjectHook(0x5A37E0, &RwV3dTransformVectors, PATCH_JUMP); +InjectHook(0x5A37F0, &_rwVectorClose, PATCH_JUMP); +InjectHook(0x5A3860, &_rwVectorOpen, PATCH_JUMP); +InjectHook(0x5A3AD0, &RwStreamRead, PATCH_JUMP); +InjectHook(0x5A3C30, &RwStreamWrite, PATCH_JUMP); +InjectHook(0x5A3DF0, &RwStreamSkip, PATCH_JUMP); +InjectHook(0x5A3F10, &RwStreamClose, PATCH_JUMP); +InjectHook(0x5A3FE0, &RwStreamOpen, PATCH_JUMP); +InjectHook(0x5A43A0, &RwIm2DGetNearScreenZ, PATCH_JUMP); +InjectHook(0x5A43B0, &RwIm2DGetFarScreenZ, PATCH_JUMP); +InjectHook(0x5A43C0, &RwRenderStateSet, PATCH_JUMP); +InjectHook(0x5A4410, &RwRenderStateGet, PATCH_JUMP); +InjectHook(0x5A4420, &RwIm2DRenderLine, PATCH_JUMP); +InjectHook(0x5A4430, &RwIm2DRenderPrimitive, PATCH_JUMP); +InjectHook(0x5A4440, &RwIm2DRenderIndexedPrimitive, PATCH_JUMP); +InjectHook(0x5A5020, &RwCameraEndUpdate, PATCH_JUMP); +InjectHook(0x5A5030, &RwCameraBeginUpdate, PATCH_JUMP); +InjectHook(0x5A5040, &RwCameraSetViewOffset, PATCH_JUMP); +InjectHook(0x5A5070, &RwCameraSetNearClipPlane, PATCH_JUMP); +InjectHook(0x5A5140, &RwCameraSetFarClipPlane, PATCH_JUMP); +InjectHook(0x5A5170, &RwCameraFrustumTestSphere, PATCH_JUMP); +InjectHook(0x5A51E0, &RwCameraClear, PATCH_JUMP); +InjectHook(0x5A5210, &RwCameraShowRaster, PATCH_JUMP); +InjectHook(0x5A5240, &RwCameraSetProjection, PATCH_JUMP); +InjectHook(0x5A52B0, &RwCameraSetViewWindow, PATCH_JUMP); +InjectHook(0x5A52F0, &RwCameraRegisterPlugin, PATCH_JUMP); +InjectHook(0x5A5320, &RwCameraDestroy, PATCH_JUMP); +InjectHook(0x5A5360, &RwCameraCreate, PATCH_JUMP); +InjectHook(0x5A7100, &RwTextureSetMipmapping, PATCH_JUMP); +InjectHook(0x5A7120, &RwTextureGetMipmapping, PATCH_JUMP); +InjectHook(0x5A7130, &RwTextureSetAutoMipmapping, PATCH_JUMP); +InjectHook(0x5A7150, &RwTextureGetAutoMipmapping, PATCH_JUMP); +InjectHook(0x5A7160, &RwTexDictionaryCreate, PATCH_JUMP); +InjectHook(0x5A7200, &RwTexDictionaryDestroy, PATCH_JUMP); +InjectHook(0x5A7290, &RwTexDictionaryForAllTextures, PATCH_JUMP); +InjectHook(0x5A72D0, &RwTextureCreate, PATCH_JUMP); +InjectHook(0x5A7330, &RwTextureDestroy, PATCH_JUMP); +InjectHook(0x5A73B0, &RwTextureSetName, PATCH_JUMP); +InjectHook(0x5A7420, &RwTextureSetMaskName, PATCH_JUMP); +InjectHook(0x5A7490, &RwTexDictionaryAddTexture, PATCH_JUMP); +InjectHook(0x5A74D0, &RwTexDictionaryFindNamedTexture, PATCH_JUMP); +InjectHook(0x5A7550, &RwTexDictionarySetCurrent, PATCH_JUMP); +InjectHook(0x5A7570, &RwTexDictionaryGetCurrent, PATCH_JUMP); +InjectHook(0x5A7580, &RwTextureRead, PATCH_JUMP); +InjectHook(0x5A7780, &RwTextureRasterGenerateMipmaps, PATCH_JUMP); +InjectHook(0x5A9120, &RwImageCreate, PATCH_JUMP); +InjectHook(0x5A9180, &RwImageDestroy, PATCH_JUMP); +InjectHook(0x5A91E0, &RwImageAllocatePixels, PATCH_JUMP); +InjectHook(0x5A92A0, &RwImageFreePixels, PATCH_JUMP); +InjectHook(0x5A92D0, &RwImageMakeMask, PATCH_JUMP); +InjectHook(0x5A93A0, &RwImageApplyMask, PATCH_JUMP); +InjectHook(0x5A9750, &RwImageSetPath, PATCH_JUMP); +InjectHook(0x5A9810, &RwImageRead, PATCH_JUMP); +InjectHook(0x5A9B40, &RwImageFindFileType, PATCH_JUMP); +InjectHook(0x5A9C10, &RwImageReadMaskedImage, PATCH_JUMP); +InjectHook(0x5A9F50, &RwImageCopy, PATCH_JUMP); +InjectHook(0x5AA130, &RwImageGammaCorrect, PATCH_JUMP); +InjectHook(0x5AA2C0, &RwImageSetGamma, PATCH_JUMP); +InjectHook(0x5AA4E0, &_rwStreamWriteVersionedChunkHeader, PATCH_JUMP); +InjectHook(0x5AA540, &RwStreamFindChunk, PATCH_JUMP); +InjectHook(0x5AA640, &RwMemLittleEndian32, PATCH_JUMP); +InjectHook(0x5AA650, &RwMemNative32, PATCH_JUMP); +InjectHook(0x5AA660, &RwMemFloat32ToReal, PATCH_JUMP); +InjectHook(0x5AA680, &RwStreamWriteReal, PATCH_JUMP); +InjectHook(0x5AA720, &RwStreamWriteInt32, PATCH_JUMP); +InjectHook(0x5AA740, &RwStreamReadReal, PATCH_JUMP); +InjectHook(0x5AA7B0, &RwStreamReadInt32, PATCH_JUMP); +InjectHook(0x5AA800, &RwTextureStreamGetSize, PATCH_JUMP); +InjectHook(0x5AA870, &RwTextureStreamWrite, PATCH_JUMP); +InjectHook(0x5AAA40, &RwTextureStreamRead, PATCH_JUMP); +InjectHook(0x5AB020, &RwTexDictionaryStreamWrite, PATCH_JUMP); +InjectHook(0x5AC890, &RpMorphTargetCalcBoundingSphere, PATCH_JUMP); +InjectHook(0x5AC9A0, &RpGeometryAddMorphTargets, PATCH_JUMP); +InjectHook(0x5ACB60, &RpGeometryTriangleSetVertexIndices, PATCH_JUMP); +InjectHook(0x5ACB90, &RpGeometryTriangleSetMaterial, PATCH_JUMP); +InjectHook(0x5ACBF0, &RpGeometryForAllMaterials, PATCH_JUMP); +InjectHook(0x5ACC30, &RpGeometryLock, PATCH_JUMP); +InjectHook(0x5ACC60, &RpGeometryUnlock, PATCH_JUMP); +InjectHook(0x5ACD10, &RpGeometryCreate, PATCH_JUMP); +InjectHook(0x5ACF40, &_rpGeometryAddRef, PATCH_JUMP); +InjectHook(0x5ACF50, &RpGeometryDestroy, PATCH_JUMP); +InjectHook(0x5ACFF0, &RpGeometryRegisterPlugin, PATCH_JUMP); +InjectHook(0x5AD020, &RpGeometryRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5AD050, &RpGeometryStreamRead, PATCH_JUMP); +InjectHook(0x5AD6D0, &RwRasterGetCurrentContext, PATCH_JUMP); +InjectHook(0x5AD6F0, &RwRasterUnlock, PATCH_JUMP); +InjectHook(0x5AD710, &RwRasterRenderFast, PATCH_JUMP); +InjectHook(0x5AD750, &RwRasterUnlockPalette, PATCH_JUMP); +InjectHook(0x5AD780, &RwRasterDestroy, PATCH_JUMP); +InjectHook(0x5AD7C0, &RwRasterPushContext, PATCH_JUMP); +InjectHook(0x5AD810, &RwRasterRegisterPlugin, PATCH_JUMP); +InjectHook(0x5AD840, &RwRasterLockPalette, PATCH_JUMP); +InjectHook(0x5AD870, &RwRasterPopContext, PATCH_JUMP); +InjectHook(0x5AD8C0, &RwRasterGetNumLevels, PATCH_JUMP); +InjectHook(0x5AD900, &RwRasterShowRaster, PATCH_JUMP); +InjectHook(0x5AD930, &RwRasterCreate, PATCH_JUMP); +InjectHook(0x5AD9D0, &RwRasterLock, PATCH_JUMP); +InjectHook(0x5ADC30, &RpMaterialCreate, PATCH_JUMP); +InjectHook(0x5ADCB0, &RpMaterialDestroy, PATCH_JUMP); +InjectHook(0x5ADD10, &RpMaterialSetTexture, PATCH_JUMP); +InjectHook(0x5ADD40, &RpMaterialRegisterPlugin, PATCH_JUMP); +InjectHook(0x5ADD70, &RpMaterialRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5ADDA0, &RpMaterialStreamRead, PATCH_JUMP); +InjectHook(0x5AE0B0, &_rpSectorDefaultRenderCallBack, PATCH_JUMP); +InjectHook(0x5AE100, &_rpWorldForAllGlobalLights, PATCH_JUMP); +InjectHook(0x5AE150, &_rpWorldSectorForAllLocalLights, PATCH_JUMP); +InjectHook(0x5AE190, &RpWorldUnlock, PATCH_JUMP); +InjectHook(0x5AE2B0, &RpWorldSectorGetWorld, PATCH_JUMP); +InjectHook(0x5AE340, &RpWorldDestroy, PATCH_JUMP); +InjectHook(0x5AE6A0, &RpWorldCreate, PATCH_JUMP); +InjectHook(0x5AEA40, &RpWorldRegisterPlugin, PATCH_JUMP); +InjectHook(0x5AEA70, &RpWorldRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5AEAA0, &RpWorldPluginAttach, PATCH_JUMP); +InjectHook(0x5AFB80, &RpWorldAddCamera, PATCH_JUMP); +InjectHook(0x5AFBB0, &RpWorldRemoveCamera, PATCH_JUMP); +InjectHook(0x5AFC10, &RpAtomicGetWorld, PATCH_JUMP); +InjectHook(0x5AFC20, &RpWorldAddClump, PATCH_JUMP); +InjectHook(0x5AFDA0, &RpWorldAddLight, PATCH_JUMP); +InjectHook(0x5AFDF0, &RpWorldRemoveLight, PATCH_JUMP); +InjectHook(0x5AFE70, &RtBMPImageRead, PATCH_JUMP); +InjectHook(0x5B07D0, &RpSkinPluginAttach, PATCH_JUMP); +InjectHook(0x5B1050, &RpSkinAtomicSetHAnimHierarchy, PATCH_JUMP); +InjectHook(0x5B1070, &RpSkinAtomicGetHAnimHierarchy, PATCH_JUMP); +InjectHook(0x5B1080, &RpSkinGeometryGetSkin, PATCH_JUMP); +InjectHook(0x5B1090, &RpSkinGeometrySetSkin, PATCH_JUMP); +InjectHook(0x5B10D0, &RpSkinGetSkinToBoneMatrices, PATCH_JUMP); +InjectHook(0x5B10E0, &RpHAnimHierarchyCreate, PATCH_JUMP); +InjectHook(0x5B11F0, &RpHAnimFrameGetHierarchy, PATCH_JUMP); +InjectHook(0x5B1200, &RpHAnimHierarchySetCurrentAnim, PATCH_JUMP); +InjectHook(0x5B12B0, &RpHAnimHierarchySubAnimTime, PATCH_JUMP); +InjectHook(0x5B1480, &RpHAnimHierarchyAddAnimTime, PATCH_JUMP); +InjectHook(0x5B1780, &RpHAnimHierarchyUpdateMatrices, PATCH_JUMP); +InjectHook(0x5B1C10, &RpHAnimAnimationStreamRead, PATCH_JUMP); +InjectHook(0x5B1D50, &RpHAnimPluginAttach, PATCH_JUMP); +InjectHook(0x5B2640, &RpMatFXPluginAttach, PATCH_JUMP); +InjectHook(0x5B3750, &RpMatFXAtomicEnableEffects, PATCH_JUMP); +InjectHook(0x5B3780, &RpMatFXMaterialSetEffects, PATCH_JUMP); +InjectHook(0x5B38D0, &RpMatFXMaterialSetupEnvMap, PATCH_JUMP); +InjectHook(0x5B3A40, &RpMatFXMaterialSetBumpMapTexture, PATCH_JUMP); +InjectHook(0x5B3CF0, &RwD3D8SetRenderState, PATCH_JUMP); +InjectHook(0x5B3D40, &RwD3D8GetRenderState, PATCH_JUMP); +InjectHook(0x5B3D60, &RwD3D8SetTextureStageState, PATCH_JUMP); +InjectHook(0x5B53A0, &RwD3D8SetTexture, PATCH_JUMP); +InjectHook(0x5B6720, &RwIm3DTransform, PATCH_JUMP); +InjectHook(0x5B67F0, &RwIm3DEnd, PATCH_JUMP); +InjectHook(0x5B6820, &RwIm3DRenderIndexedPrimitive, PATCH_JUMP); +InjectHook(0x5B6980, &RwIm3DRenderLine, PATCH_JUMP); +InjectHook(0x5B6A50, &RwIm3DSetTransformPipeline, PATCH_JUMP); +InjectHook(0x5B6AC0, &RwIm3DSetRenderPipeline, PATCH_JUMP); +InjectHook(0x5B95D0, &RwD3D8EngineSetRefreshRate, PATCH_JUMP); +InjectHook(0x5B9640, &RwD3D8CameraAttachWindow, PATCH_JUMP); +InjectHook(0x5BAEB0, &RwD3D8DeviceSupportsDXTTexture, PATCH_JUMP); +InjectHook(0x5BAF90, &RwD3D8SetVertexShader, PATCH_JUMP); +InjectHook(0x5BAFD0, &RwD3D8SetPixelShader, PATCH_JUMP); +InjectHook(0x5BB010, &RwD3D8SetStreamSource, PATCH_JUMP); +InjectHook(0x5BB060, &RwD3D8SetIndices, PATCH_JUMP); +InjectHook(0x5BB0B0, &RwD3D8DrawIndexedPrimitive, PATCH_JUMP); +InjectHook(0x5BB140, &RwD3D8DrawPrimitive, PATCH_JUMP); +InjectHook(0x5BB1D0, &RwD3D8SetTransform, PATCH_JUMP); +InjectHook(0x5BB310, &RwD3D8GetTransform, PATCH_JUMP); +InjectHook(0x5BB340, &RwD3D8SetTransformWorld, PATCH_JUMP); +InjectHook(0x5BB490, &RwD3D8SetSurfaceProperties, PATCH_JUMP); +InjectHook(0x5BB7A0, &RwD3D8SetLight, PATCH_JUMP); +InjectHook(0x5BB890, &RwD3D8EnableLight, PATCH_JUMP); +InjectHook(0x5BB9F0, &RwD3D8DynamicVertexBufferCreate, PATCH_JUMP); +InjectHook(0x5BBAE0, &RwD3D8DynamicVertexBufferDestroy, PATCH_JUMP); +InjectHook(0x5BBB10, &RwD3D8IndexBufferCreate, PATCH_JUMP); +InjectHook(0x5BBB40, &RwD3D8CreatePixelShader, PATCH_JUMP); +InjectHook(0x5BBB90, &RwD3D8DeletePixelShader, PATCH_JUMP); +InjectHook(0x5BBC00, &RwD3D8SetPixelShaderConstant, PATCH_JUMP); +InjectHook(0x5BBC30, &RwD3D8GetCaps, PATCH_JUMP); +InjectHook(0x5BBC40, &RwD3D8CameraIsSphereFullyInsideFrustum, PATCH_JUMP); +InjectHook(0x5BBCA0, &RwD3D8CameraIsBBoxFullyInsideFrustum, PATCH_JUMP); +InjectHook(0x5BBD30, &RwD3D8DynamicVertexBufferLock, PATCH_JUMP); +InjectHook(0x5BBEB0, &RwD3D8DynamicVertexBufferUnlock, PATCH_JUMP); +InjectHook(0x5BBED0, &_rwIntelSSEsupported, PATCH_JUMP); +InjectHook(0x5BBF10, &RwImageSetFromRaster, PATCH_JUMP); +InjectHook(0x5BBF50, &RwRasterSetFromImage, PATCH_JUMP); +InjectHook(0x5BBF80, &RwImageFindRasterFormat, PATCH_JUMP); +InjectHook(0x5BBFF0, &RwFrameRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5BC020, &_rwFrameListDeinitialize, PATCH_JUMP); +InjectHook(0x5BC050, &_rwFrameListStreamRead, PATCH_JUMP); +InjectHook(0x5BC300, &RpLightSetRadius, PATCH_JUMP); +InjectHook(0x5BC320, &RpLightSetColor, PATCH_JUMP); +InjectHook(0x5BC370, &RpLightGetConeAngle, PATCH_JUMP); +InjectHook(0x5BC5B0, &RpLightRegisterPlugin, PATCH_JUMP); +InjectHook(0x5BC5E0, &RpLightStreamRead, PATCH_JUMP); +InjectHook(0x5BC780, &RpLightDestroy, PATCH_JUMP); +InjectHook(0x5BC7C0, &RpLightCreate, PATCH_JUMP); +InjectHook(0x5BE280, &_rwD3D8TexDictionaryEnableRasterFormatConversion, PATCH_JUMP); +InjectHook(0x5BF110, &RwOsGetFileInterface, PATCH_JUMP); +InjectHook(0x5C1720, &RwFreeListDestroy, PATCH_JUMP); +InjectHook(0x5C1790, &RwFreeListCreate, PATCH_JUMP); +InjectHook(0x5C19F0, &RwFreeListPurge, PATCH_JUMP); +InjectHook(0x5C1B90, &RwFreeListPurgeAllFreeLists, PATCH_JUMP); +InjectHook(0x5C1D40, &RwFreeListForAllUsed, PATCH_JUMP); +InjectHook(0x5C2780, &_rxPipelineClose, PATCH_JUMP); +InjectHook(0x5C27E0, &_rxPipelineOpen, PATCH_JUMP); +InjectHook(0x5C2AD0, &RxHeapGetGlobalHeap, PATCH_JUMP); +InjectHook(0x5C2AE0, &RxPacketCreate, PATCH_JUMP); +InjectHook(0x5C2B10, &RxClusterSetExternalData, PATCH_JUMP); +InjectHook(0x5C2B70, &RxClusterSetData, PATCH_JUMP); +InjectHook(0x5C2BD0, &RxClusterInitializeData, PATCH_JUMP); +InjectHook(0x5C2C40, &RxClusterResizeData, PATCH_JUMP); +InjectHook(0x5C2C90, &RxClusterLockWrite, PATCH_JUMP); +InjectHook(0x5C2D60, &RxPipelineExecute, PATCH_JUMP); +InjectHook(0x5C2E00, &RxPipelineCreate, PATCH_JUMP); +InjectHook(0x5C2E70, &_rxPipelineDestroy, PATCH_JUMP); +InjectHook(0x5C3080, &RwResourcesFreeResEntry, PATCH_JUMP); +InjectHook(0x5C30F0, &_rwResourcesPurge, PATCH_JUMP); +InjectHook(0x5C3170, &RwResourcesAllocateResEntry, PATCH_JUMP); +InjectHook(0x5C3360, &RwResourcesEmptyArena, PATCH_JUMP); +InjectHook(0x5C3450, &_rwPluginRegistryOpen, PATCH_JUMP); +InjectHook(0x5C3480, &_rwPluginRegistryClose, PATCH_JUMP); +InjectHook(0x5C3590, &_rwPluginRegistryGetPluginOffset, PATCH_JUMP); +InjectHook(0x5C35C0, &_rwPluginRegistryAddPlugin, PATCH_JUMP); +InjectHook(0x5C37F0, &_rwPluginRegistryInitObject, PATCH_JUMP); +InjectHook(0x5C3850, &_rwPluginRegistryDeInitObject, PATCH_JUMP); +InjectHook(0x5C3880, &_rwPluginRegistryCopyObject, PATCH_JUMP); +InjectHook(0x5C3910, &RwErrorSet, PATCH_JUMP); +InjectHook(0x5C3970, &_rwerror, PATCH_JUMP); +InjectHook(0x5C3980, &_rwPluginRegistryAddPluginStream, PATCH_JUMP); +InjectHook(0x5C39C0, &_rwPluginRegistryAddPlgnStrmlwysCB, PATCH_JUMP); +InjectHook(0x5C39F0, &_rwPluginRegistryAddPlgnStrmRightsCB, PATCH_JUMP); +InjectHook(0x5C3A20, & _rwPluginRegistryReadDataChunks, PATCH_JUMP); +InjectHook(0x5C3B50, & _rwPluginRegistryInvokeRights, PATCH_JUMP); +InjectHook(0x5C3BA0, &_rwPluginRegistryGetSize, PATCH_JUMP); +InjectHook(0x5C3BE0, &_rwPluginRegistryWriteDataChunks, PATCH_JUMP); +InjectHook(0x5C3CB0, &_rwPluginRegistrySkipDataChunks, PATCH_JUMP); +InjectHook(0x5C3D30, &RwCameraStreamRead, PATCH_JUMP); +InjectHook(0x5C5570, &RwBBoxCalculate, PATCH_JUMP); +InjectHook(0x5C72B0, &RwImageResample, PATCH_JUMP); +InjectHook(0x5C7B30, &RwImageCreateResample, PATCH_JUMP); +InjectHook(0x5D9240, &RxRenderStateVectorSetDefaultRenderStateVector, PATCH_JUMP); +InjectHook(0x5D9340, &RxRenderStateVectorCreate, PATCH_JUMP); +InjectHook(0x5D9410, &RxRenderStateVectorDestroy, PATCH_JUMP); +InjectHook(0x5D9460, &RxRenderStateVectorLoadDriverState, PATCH_JUMP); +InjectHook(0x5D95D0, &_rxEmbeddedPacketBetweenPipelines, PATCH_JUMP); +InjectHook(0x5D9740, &_rxEmbeddedPacketBetweenNodes, PATCH_JUMP); +InjectHook(0x5D9810, &_rxPacketDestroy, PATCH_JUMP); +InjectHook(0x5C8B10, &_rpMaterialListDeinitialize, PATCH_JUMP); +InjectHook(0x5C8B70, &_rpMaterialListInitialize, PATCH_JUMP); +InjectHook(0x5C8B80, &_rpMaterialListGetMaterial, PATCH_JUMP); +InjectHook(0x5C8B90, &_rpMaterialListAppendMaterial, PATCH_JUMP); +InjectHook(0x5C8C50, &_rpMaterialListFindMaterialIndex, PATCH_JUMP); +InjectHook(0x5C8C80, &_rpMaterialListStreamRead, PATCH_JUMP); +InjectHook(0x5C8FE0, &_rpMeshHeaderCreate, PATCH_JUMP); +InjectHook(0x5C8FF0, &_rpMeshClose, PATCH_JUMP); +InjectHook(0x5C9020, &_rpMeshOpen, PATCH_JUMP); +InjectHook(0x5C9140, &_rpBuildMeshCreate, PATCH_JUMP); +InjectHook(0x5C9220, &_rpBuildMeshDestroy, PATCH_JUMP); +InjectHook(0x5C9260, &_rpMeshDestroy, PATCH_JUMP); +InjectHook(0x5C92A0, &_rpBuildMeshAddTriangle, PATCH_JUMP); +InjectHook(0x5C9380, &_rpMeshHeaderForAllMeshes, PATCH_JUMP); +InjectHook(0x5C93C0, &_rpMeshWrite, PATCH_JUMP); +InjectHook(0x5C9510, &_rpMeshRead, PATCH_JUMP); +InjectHook(0x5C96E0, &_rpMeshSize, PATCH_JUMP); +InjectHook(0x5C9730, &RpBuildMeshGenerateDefaultTriStrip, PATCH_JUMP); +InjectHook(0x5CAE10, &_rpTriListMeshGenerate, PATCH_JUMP); +InjectHook(0x5CB230, &_rpMeshOptimise, PATCH_JUMP); +InjectHook(0x5CB2B0, &RpWorldSectorRegisterPlugin, PATCH_JUMP); +InjectHook(0x5CB2E0, &RpWorldSectorRegisterPluginStream, PATCH_JUMP); +InjectHook(0x5CB630, &RpWorldSetDefaultSectorPipeline, PATCH_JUMP); +InjectHook(0x5CB670, &RpAtomicSetDefaultPipeline, PATCH_JUMP); +InjectHook(0x5CDEE0, &RpHAnimStdKeyFrameToMatrix, PATCH_JUMP); +InjectHook(0x5CE000, &RpHAnimStdKeyFrameInterpolate, PATCH_JUMP); +InjectHook(0x5CE420, &RpHAnimStdKeyFrameBlend, PATCH_JUMP); +InjectHook(0x5CE820, &RpHAnimStdKeyFrameStreamRead, PATCH_JUMP); +InjectHook(0x5CE8C0, &RpHAnimStdKeyFrameStreamWrite, PATCH_JUMP); +InjectHook(0x5CE930, &RpHAnimStdKeyFrameStreamGetSize, PATCH_JUMP); +InjectHook(0x5CE950, &RpHAnimStdKeyFrameMulRecip, PATCH_JUMP); +InjectHook(0x5CEAB0, &RpHAnimStdKeyFrameAdd, PATCH_JUMP); +InjectHook(0x5D1070, &RxHeapFree, PATCH_JUMP); +InjectHook(0x5D1260, &RxHeapAlloc, PATCH_JUMP); +InjectHook(0x5D14D0, &RxHeapRealloc, PATCH_JUMP); +InjectHook(0x5D1680, &_rxHeapReset, PATCH_JUMP); +InjectHook(0x5D16F0, &RxHeapDestroy, PATCH_JUMP); +InjectHook(0x5D1750, &RxHeapCreate, PATCH_JUMP); +InjectHook(0x5D1EC0, &RxPipelineNodeFindOutputByName, PATCH_JUMP); +InjectHook(0x5D1F20, &RxPipelineNodeFindInput, PATCH_JUMP); +InjectHook(0x5D1F30, &RxPipelineNodeRequestCluster, PATCH_JUMP); +InjectHook(0x5D1FA0, &RxLockedPipeUnlock, PATCH_JUMP); +InjectHook(0x5D29F0, &RxPipelineLock, PATCH_JUMP); +InjectHook(0x5D2B10, &RxPipelineFindNodeByName, PATCH_JUMP); +InjectHook(0x5D2BA0, &RxLockedPipeAddFragment, PATCH_JUMP); +InjectHook(0x5D2EE0, &RxLockedPipeAddPath, PATCH_JUMP); +InjectHook(0x5D31C0, &RxNodeDefinitionGetImmRenderSetup, PATCH_JUMP); +InjectHook(0x5D35C0, &RxNodeDefinitionGetImmMangleTriangleIndices, PATCH_JUMP); +InjectHook(0x5D3C60, &RxNodeDefinitionGetCullTriangle, PATCH_JUMP); +InjectHook(0x5D4F80, &RxNodeDefinitionGetClipTriangle, PATCH_JUMP); +InjectHook(0x5D51C0, &RxNodeDefinitionGetSubmitTriangle, PATCH_JUMP); +InjectHook(0x5D5400, &RxNodeDefinitionGetImmInstance, PATCH_JUMP); +InjectHook(0x5D6000, &RxNodeDefinitionGetTransform, PATCH_JUMP); +InjectHook(0x5D61C0, &RxNodeDefinitionGetImmStash, PATCH_JUMP); +InjectHook(0x5D6470, &RxNodeDefinitionGetImmMangleLineIndices, PATCH_JUMP); +InjectHook(0x5D7230, &RxNodeDefinitionGetClipLine, PATCH_JUMP); +InjectHook(0x5D74C0, &RxNodeDefinitionGetSubmitLine, PATCH_JUMP); +InjectHook(0x5D9C90, &_rwD3D8LightsOpen, PATCH_JUMP); +InjectHook(0x5D9EF0, &_rwD3D8LightsClose, PATCH_JUMP); +InjectHook(0x5D9F80, &_rwD3D8LightsGlobalEnable, PATCH_JUMP); +InjectHook(0x5DA210, &_rwD3D8LightLocalEnable, PATCH_JUMP); +InjectHook(0x5DA450, &_rwD3D8LightsEnable, PATCH_JUMP); +InjectHook(0x5DAAC0, &RxNodeDefinitionGetD3D8WorldSectorAllInOne, PATCH_JUMP); +InjectHook(0x5DC500, &RxNodeDefinitionGetD3D8AtomicAllInOne, PATCH_JUMP); +InjectHook(0x5DCC50, &RxNodeDefinitionGetWorldSectorInstance, PATCH_JUMP); +InjectHook(0x5DCD80, &RxNodeDefinitionGetWorldSectorEnumerateLights, PATCH_JUMP); +InjectHook(0x5DD800, &RxNodeDefinitionGetAtomicInstance, PATCH_JUMP); +InjectHook(0x5DD9B0, &RxNodeDefinitionGetAtomicEnumerateLights, PATCH_JUMP); +InjectHook(0x5DDAA0, &RxNodeDefinitionGetMaterialScatter, PATCH_JUMP); +InjectHook(0x5DF040, &RxNodeDefinitionGetLight, PATCH_JUMP); +InjectHook(0x5DF560, &RxNodeDefinitionGetPostLight, PATCH_JUMP); +InjectHook(0x5DFC60, &RxD3D8AllInOneSetRenderCallBack, PATCH_JUMP); +ENDPATCHES +#endif \ No newline at end of file -- cgit v1.2.3 From 7f8a4b4867cff2a2aaf32eddaca65ba9f4e92806 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 14 Apr 2020 10:31:00 +0300 Subject: Debug font and CProfiles --- src/rw/RwHelper.cpp | 53 ++++++++++++++++++++++++++++++++++++++--------------- src/rw/RwHelper.h | 1 + 2 files changed, 39 insertions(+), 15 deletions(-) (limited to 'src/rw') diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 44866f4f..44ca3a0a 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -3,6 +3,44 @@ #include "patcher.h" #include "Timecycle.h" #include "skeleton.h" +#if defined(RWLIBS) && !defined(FINAL) +#include "rtcharse.h" +#pragma comment( lib, "rtcharse.lib" ) + +RtCharset *debugCharset; +#endif + +void CreateDebugFont() +{ +#if defined(RWLIBS) && !defined(FINAL) + RwRGBA color = { 255, 255, 128, 255 }; + RwRGBA colorbg = { 0, 0, 0, 0 }; + RtCharsetOpen(); + debugCharset = RtCharsetCreate(&color, &colorbg); +#endif +} + +void DestroyDebugFont() +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetDestroy(debugCharset); + RtCharsetClose(); +#endif +} + +void ObrsPrintfString(const char *str, short x, short y) +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetPrintBuffered(debugCharset, str, x, y, true); +#endif +} + +void FlushObrsPrintfs() +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetBufferFlush(); +#endif +} void * RwMallocAlign(RwUInt32 size, RwUInt32 align) @@ -347,21 +385,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) return (nil); } -void CreateDebugFont() -{ - ; -} - -void DestroyDebugFont() -{ - ; -} - -void FlushObrsPrintfs() -{ - ; -} - WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); } WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); } diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index a9f0bdf4..5b47cb6f 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -5,6 +5,7 @@ void RwFreeAlign(void *mem); void CreateDebugFont(); void DestroyDebugFont(); +void ObrsPrintfString(const char *str, short x, short y); void FlushObrsPrintfs(); void DefinedState(void); RwFrame *GetFirstChild(RwFrame *frame); -- cgit v1.2.3 From 6d934892ecd3c4b6f025fbe2c4e6504fd979d391 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 14 Apr 2020 18:35:07 +0300 Subject: RwMatFX support with linked RW libs --- src/rw/RwMatFX.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/rw') diff --git a/src/rw/RwMatFX.cpp b/src/rw/RwMatFX.cpp index ca9a633b..3af6fabe 100644 --- a/src/rw/RwMatFX.cpp +++ b/src/rw/RwMatFX.cpp @@ -43,8 +43,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); +} +#else int &MatFXMaterialDataOffset = *(int*)0x66188C; int &MatFXAtomicDataOffset = *(int*)0x66189C; +#endif #ifdef PS2_MATFX @@ -206,8 +214,13 @@ _rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int se RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); } + STARTPATCHES +#ifdef RWLIBS + InjectHook((uintptr)&_rpMatFXD3D8AtomicMatFXEnvRender, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP); +#else InjectHook(0x5CF6C0, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP); +#endif ENDPATCHES #endif -- cgit v1.2.3