summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2019-05-30 13:35:13 +0200
committeraap <aap@papnet.eu>2019-05-30 13:35:13 +0200
commit852d8298b1f6c838d4d5c7fd8cfbdbf2615b62d1 (patch)
tree2efed135e4d792f86cbac02c9c9bb1eaa340d9ed
parentee5088b3e185cb2d455cb64d2098e2a807b0ac27 (diff)
added CMBlur
-rw-r--r--src/RwHelper.cpp26
-rw-r--r--src/RwHelper.h1
-rw-r--r--src/Timecycle.h3
-rw-r--r--src/common.h5
-rw-r--r--src/main.cpp7
-rw-r--r--src/render/Draw.cpp28
-rw-r--r--src/render/Draw.h2
-rw-r--r--src/render/MBlur.cpp221
-rw-r--r--src/render/MBlur.h15
9 files changed, 301 insertions, 7 deletions
diff --git a/src/RwHelper.cpp b/src/RwHelper.cpp
index c8782f9e..2634cfd6 100644
--- a/src/RwHelper.cpp
+++ b/src/RwHelper.cpp
@@ -1,5 +1,31 @@
+#define WITHD3D
#include "common.h"
+#include "TimeCycle.h"
+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);
+}
RwObject*
GetFirstObjectCallback(RwObject *object, void *data)
diff --git a/src/RwHelper.h b/src/RwHelper.h
index 90852b08..49292449 100644
--- a/src/RwHelper.h
+++ b/src/RwHelper.h
@@ -1,3 +1,4 @@
#pragma once
+void DefinedState(void);
RwObject *GetFirstObject(RwFrame *frame);
diff --git a/src/Timecycle.h b/src/Timecycle.h
index 6946cc7c..2f9e4f2f 100644
--- a/src/Timecycle.h
+++ b/src/Timecycle.h
@@ -107,5 +107,8 @@ public:
static int GetFluffyCloudsBottomRed(void) { return m_nCurrentFluffyCloudsBottomRed; }
static int GetFluffyCloudsBottomGreen(void) { return m_nCurrentFluffyCloudsBottomGreen; }
static int GetFluffyCloudsBottomBlue(void) { return m_nCurrentFluffyCloudsBottomBlue; }
+ static int GetFogRed(void) { return m_nCurrentFogColourRed; }
+ static int GetFogGreen(void) { return m_nCurrentFogColourGreen; }
+ static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
};
diff --git a/src/common.h b/src/common.h
index 34214d42..a82e4c7f 100644
--- a/src/common.h
+++ b/src/common.h
@@ -13,6 +13,11 @@
#include <assert.h>
#include <new>
+#ifdef WITHD3D
+#include <Windows.h>
+#include <d3d8types.h>
+#endif
+
#include <rwcore.h>
#include <rpworld.h>
diff --git a/src/main.cpp b/src/main.cpp
index 955b33ed..4f125098 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -25,17 +25,12 @@ void operator delete(void *ptr) noexcept { gtadelete(ptr); }
unsigned __int64 myrand_seed = 1;
int
-myps2rand(void)
+myrand(void)
{
myrand_seed = 0x5851F42D4C957F2D * myrand_seed + 1;
return ((myrand_seed >> 32) & 0x7FFFFFFF);
}
-int myrand(void)
-{
- return myps2rand();
-}
-
void
mysrand(unsigned int seed)
{
diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp
index f26f2ada..6244c3fa 100644
--- a/src/render/Draw.cpp
+++ b/src/render/Draw.cpp
@@ -1,6 +1,34 @@
#include "common.h"
+#include "patcher.h"
#include "Draw.h"
float &CDraw::ms_fNearClipZ = *(float*)0x8E2DC4;
float &CDraw::ms_fFarClipZ = *(float*)0x9434F0;
float &CDraw::ms_fFOV = *(float*)0x5FBC6C;
+
+static float hFov2vFov(float hfov)
+{
+ float w = SCREENW;
+ float h = SCREENH;
+
+ // => tan(hFOV/2) = tan(vFOV/2)*aspectRatio
+ // => tan(vFOV/2) = tan(hFOV/2)/aspectRatio
+ float ar1 = 4.0/3.0;
+ float ar2 = w/h;
+ hfov = DEGTORAD(hfov);
+ float vfov = atan(tan(hfov/2) / ar1) *2;
+ hfov = atan(tan(vfov/2) * ar2) *2;
+ return RADTODEG(hfov);
+}
+
+void
+CDraw::SetFOV(float fov)
+{
+// TODO: fix FOV here or somewhere else?
+// ms_fFOV = hFov2vFov(fov);
+ ms_fFOV = fov;
+}
+
+STARTPATCHES
+ InjectHook(0x4FE7B0, CDraw::SetFOV, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/render/Draw.h b/src/render/Draw.h
index 62fe5193..84ec7ed3 100644
--- a/src/render/Draw.h
+++ b/src/render/Draw.h
@@ -11,6 +11,6 @@ public:
static float GetNearClipZ(void) { return ms_fNearClipZ; }
static void SetFarClipZ(float farclip) { ms_fFarClipZ = farclip; }
static float GetFarClipZ(void) { return ms_fFarClipZ; }
- static void SetFOV(float fov) { ms_fFOV = fov; }
+ static void SetFOV(float fov);
static float GetFOV(void) { return ms_fFOV; }
};
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
new file mode 100644
index 00000000..b7a65adc
--- /dev/null
+++ b/src/render/MBlur.cpp
@@ -0,0 +1,221 @@
+#include "common.h"
+#include "patcher.h"
+#include "RwHelper.h"
+#include "MBlur.h"
+
+RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
+bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
+bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
+
+static RwIm2DVertex Vertex[4];
+//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
+static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
+
+void
+CMBlur::MotionBlurOpen(RwCamera *cam)
+{
+ // TODO. this is simplified
+
+ RwRect rect = { 0, 0, 0, 0 };
+
+ if(pFrontBuffer)
+ MotionBlurClose();
+
+ if(BlurOn){
+ for(rect.w = 1; rect.w < RwRasterGetWidth(RwCameraGetRaster(cam)); rect.w *= 2);
+ for(rect.h = 1; rect.h < RwRasterGetHeight(RwCameraGetRaster(cam)); rect.h *= 2);
+ pFrontBuffer = RwRasterCreate(rect.w, rect.h, RwRasterGetDepth(RwCameraGetRaster(cam)), rwRASTERTYPECAMERATEXTURE);
+ if(pFrontBuffer)
+ ms_bJustInitialised = true;
+ else{
+ debug("MBlurOpen can't create raster.");
+ BlurOn = false;
+ rect.w = RwRasterGetWidth(RwCameraGetRaster(cam));
+ rect.h = RwRasterGetHeight(RwCameraGetRaster(cam));
+ }
+ CreateImmediateModeData(cam, &rect);
+ }else{
+ rect.w = RwRasterGetWidth(RwCameraGetRaster(cam));
+ rect.h = RwRasterGetHeight(RwCameraGetRaster(cam));
+ CreateImmediateModeData(cam, &rect);
+ }
+}
+
+void
+CMBlur::MotionBlurClose(void)
+{
+ if(pFrontBuffer){
+ RwRasterDestroy(pFrontBuffer);
+ pFrontBuffer = nil;
+ }
+}
+
+void
+CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
+{
+ float zero, xmax, ymax;
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ zero = 0.5f;
+ xmax = rect->w + 0.5f;
+ ymax = rect->h + 0.5f;
+ }else{
+ zero = -0.5f;
+ xmax = rect->w - 0.5f;
+ ymax = rect->h - 0.5f;
+ }
+
+ RwIm2DVertexSetScreenX(&Vertex[0], zero);
+ RwIm2DVertexSetScreenY(&Vertex[0], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[1], zero);
+ RwIm2DVertexSetScreenY(&Vertex[1], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[2], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[2], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[3], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[3], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
+
+}
+
+void
+CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 alpha, int32 type, uint32 bluralpha)
+{
+ RwRGBA color = { red, green, blue, alpha };
+ if(BlurOn){
+ if(pFrontBuffer){
+ if(ms_bJustInitialised)
+ ms_bJustInitialised = false;
+ else
+ OverlayRender(cam, pFrontBuffer, color, type, bluralpha);
+ }
+ RwRasterPushContext(pFrontBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+ }else{
+ OverlayRender(cam, nil, color, type, bluralpha);
+ }
+}
+
+void
+CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 bluralpha)
+{
+ int r, g, b, a;
+
+ r = color.red;
+ g = color.green;
+ b = color.blue;
+ a = color.alpha;
+
+ DefinedState();
+
+ switch(type){
+ case 3:
+ r = 0;
+ g = 255;
+ b = 0;
+ a = 128;
+ break;
+ case 5:
+ r = 100;
+ g = 220;
+ b = 230;
+ a = 158;
+ break;
+ case 6:
+ r = 80;
+ g = 255;
+ b = 230;
+ a = 138;
+ break;
+ case 8:
+ r = 255;
+ g = 60;
+ b = 60;
+ a = 200;
+ break;
+ case 9:
+ r = 255;
+ g = 180;
+ b = 180;
+ a = 128;
+ break;
+ }
+
+ if(!BlurOn){
+ r *= 0.6f;
+ g *= 0.6f;
+ b *= 0.6f;
+ if(type != 1)
+ a *= 0.6f;
+ // game clamps to 255 here, but why?
+ }
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, BlurOn ? raster : nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+
+ a = bluralpha/2;
+ if(a < 30)
+ a = 30;
+
+ if(BlurOn && a != 0){ // the second condition should always be true
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, a);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ }
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+}
+
+STARTPATCHES
+ InjectHook(0x50AE40, CMBlur::MotionBlurOpen, PATCH_JUMP);
+ InjectHook(0x50B170, CMBlur::MotionBlurClose, PATCH_JUMP);
+ InjectHook(0x50A800, CMBlur::CreateImmediateModeData, PATCH_JUMP);
+ InjectHook(0x50AD70, CMBlur::MotionBlurRender, PATCH_JUMP);
+ InjectHook(0x50A9C0, CMBlur::OverlayRender, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/render/MBlur.h b/src/render/MBlur.h
new file mode 100644
index 00000000..67ed658f
--- /dev/null
+++ b/src/render/MBlur.h
@@ -0,0 +1,15 @@
+#pragma once
+
+class CMBlur
+{
+ static RwRaster *&pFrontBuffer;
+ static bool &ms_bJustInitialised;
+ static bool &BlurOn;
+
+public:
+ static void MotionBlurOpen(RwCamera *cam);
+ static void MotionBlurClose(void);
+ static void CreateImmediateModeData(RwCamera *cam, RwRect *rect);
+ static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 alpha, int32 type, uint32 bluralpha);
+ static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 bluralpha);
+};