summaryrefslogtreecommitdiffstats
path: root/src/rw/RwHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rw/RwHelper.cpp')
-rw-r--r--src/rw/RwHelper.cpp204
1 files changed, 200 insertions, 4 deletions
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index f568532a..58791ce2 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -16,6 +16,7 @@ bool gPS2alphaTest = true;
#else
bool gPS2alphaTest = false;
#endif
+bool gBackfaceCulling;
#ifndef FINAL
static bool charsetOpen;
@@ -111,7 +112,7 @@ DefinedState(void)
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE);
+ //RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEBORDERCOLOR, (void*)RWRGBALONG(0, 0, 0, 255));
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
@@ -131,6 +132,15 @@ DefinedState(void)
#endif
}
+void
+SetCullMode(uint32 mode)
+{
+ if(gBackfaceCulling)
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)mode);
+ else
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+}
+
RwFrame*
GetFirstFrameCallback(RwFrame *child, void *data)
{
@@ -352,9 +362,9 @@ AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
hier->interpolator->currentAnim = nil;
}
#else
- if(hier && hier->pCurrentAnim){
- RpHAnimAnimationDestroy(hier->pCurrentAnim);
- hier->pCurrentAnim = nil;
+ if(hier && hier->currentAnim){
+ RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim);
+ hier->currentAnim = nil;
}
#endif
}
@@ -389,6 +399,125 @@ RenderSkeleton(RpHAnimHierarchy *hier)
}
#endif
+
+RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset)
+{
+ RwIm2DVertex vx[4];
+
+ /*
+ * Render an opaque white 2D quad at the given coordinates and
+ * spanning a whole texture.
+ */
+
+ RwIm2DVertexSetScreenX(&vx[0], x1);
+ RwIm2DVertexSetScreenY(&vx[0], y1);
+ RwIm2DVertexSetScreenZ(&vx[0], z);
+ RwIm2DVertexSetIntRGBA(&vx[0], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
+ RwIm2DVertexSetU(&vx[0], uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[0], uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[1], x1);
+ RwIm2DVertexSetScreenY(&vx[1], y2);
+ RwIm2DVertexSetScreenZ(&vx[1], z);
+ RwIm2DVertexSetIntRGBA(&vx[1], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
+ RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[2], x2);
+ RwIm2DVertexSetScreenY(&vx[2], y1);
+ RwIm2DVertexSetScreenZ(&vx[2], z);
+ RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
+ RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[3], x2);
+ RwIm2DVertexSetScreenY(&vx[3], y2);
+ RwIm2DVertexSetScreenZ(&vx[3], z);
+ RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
+ RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
+
+ RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
+
+ return TRUE;
+}
+
+bool b_cbsUseLTM = true;
+
+RpAtomic *cbsCalcMeanBSphereRadiusCB(RpAtomic *atomic, void *data)
+{
+ RwV3d atomicPos;
+
+ if ( b_cbsUseLTM )
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
+ else
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
+
+ RwV3d temp;
+ RwV3dSub(&temp, &atomicPos, &((RwSphere *)data)->center);
+ RwReal radius = RwV3dLength(&temp) + RpAtomicGetBoundingSphere(atomic)->radius;
+
+ if ( ((RwSphere *)data)->radius < radius )
+ ((RwSphere *)data)->radius = radius;
+
+ return atomic;
+}
+
+RpAtomic *cbsCalcMeanBSphereCenterCB(RpAtomic *atomic, void *data)
+{
+ RwV3d atomicPos;
+
+ if ( b_cbsUseLTM )
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
+ else
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
+
+ RwV3dAdd(&((RwSphere *)data)->center, &((RwSphere *)data)->center, &atomicPos);
+
+ return atomic;
+}
+
+RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM)
+{
+ RwMatrix matrix;
+ RwSphere result = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+ b_cbsUseLTM = useLTM;
+
+ if ( clump == nil || sphere == nil )
+ return nil;
+
+ sphere->radius = 0.0f;
+ sphere->center.x = 0.0f;
+ sphere->center.y = 0.0f;
+ sphere->center.z = 0.0f;
+
+ RwInt32 numAtomics = RpClumpGetNumAtomics(clump);
+ if ( numAtomics < 1.0f )
+ return nil;
+
+ RpClumpForAllAtomics(clump, cbsCalcMeanBSphereCenterCB, &result);
+
+ RwV3dScale(&result.center, &result.center, 1.0f/numAtomics);
+
+ RpClumpForAllAtomics(clump, cbsCalcMeanBSphereRadiusCB, &result);
+
+ if ( b_cbsUseLTM )
+ RwMatrixInvert(&matrix, RwFrameGetLTM(RpClumpGetFrame(clump)));
+ else
+ RwMatrixInvert(&matrix, RwFrameGetMatrix(RpClumpGetFrame(clump)));
+
+ RwV3dTransformPoints(&result.center, &result.center, 1, &matrix);
+
+ *sphere = result;
+
+ return clump;
+}
+
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)
@@ -616,6 +745,73 @@ WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
#endif
+#ifdef LIBRW
+#include <rpmatfx.h>
+#include "VehicleModelInfo.h"
+
+int32
+findPlatform(rw::Atomic *a)
+{
+ rw::Geometry *g = a->geometry;
+ if(g->instData)
+ return g->instData->platform;
+ return 0;
+}
+
+// Game doesn't read atomic extensions so we never get any other than the default pipe,
+// but we need it for uninstancing
+void
+attachPipe(rw::Atomic *atomic)
+{
+ if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)))
+ atomic->pipeline = rw::skinGlobals.pipelines[rw::platform];
+ else{
+ int fx = rpMATFXEFFECTNULL;
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), CVehicleModelInfo::GetMatFXEffectMaterialCB, &fx);
+ if(fx != rpMATFXEFFECTNULL)
+ RpMatFXAtomicEnableEffects(atomic);
+ }
+}
+
+// Attach pipes for the platform we have native data for so we can uninstance
+void
+switchPipes(rw::Atomic *a, int32 platform)
+{
+ if(a->pipeline && a->pipeline->platform != platform){
+ uint32 plgid = a->pipeline->pluginID;
+ switch(plgid){
+ // assume default pipe won't be attached explicitly
+ case rw::ID_SKIN:
+ a->pipeline = rw::skinGlobals.pipelines[platform];
+ break;
+ case rw::ID_MATFX:
+ a->pipeline = rw::matFXGlobals.pipelines[platform];
+ break;
+ }
+ }
+}
+
+RpAtomic*
+ConvertPlatformAtomic(RpAtomic *atomic, void *data)
+{
+ int32 driver = rw::platform;
+ int32 platform = findPlatform(atomic);
+ if(platform != 0 && platform != driver){
+ attachPipe(atomic); // kludge
+ rw::ObjPipeline *origPipe = atomic->pipeline;
+ rw::platform = platform;
+ switchPipes(atomic, rw::platform);
+ if(atomic->geometry->flags & rw::Geometry::NATIVE)
+ atomic->uninstance();
+ // no ADC in this game
+ //rw::ps2::unconvertADC(atomic->geometry);
+ rw::platform = driver;
+ atomic->pipeline = origPipe;
+ }
+ return atomic;
+}
+#endif
+
#if defined(FIX_BUGS) && defined(GTA_PC)
RwUInt32 saved_alphafunc, saved_alpharef;