mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-17 03:29:00 +00:00
554 lines
19 KiB
C++
554 lines
19 KiB
C++
|
#include "common.h"
|
||
|
#include "patcher.h"
|
||
|
#include "Draw.h"
|
||
|
#include "Camera.h"
|
||
|
#include "Sprite.h"
|
||
|
|
||
|
// Get rid of bullshit windows definitions, we're not running on an 8086
|
||
|
#ifdef far
|
||
|
#undef far
|
||
|
#undef near
|
||
|
#endif
|
||
|
|
||
|
RwIm2DVertex *CSprite2d::maVertices = (RwIm2DVertex*)0x6E9168;
|
||
|
float &CSprite2d::RecipNearClip = *(float*)0x880DB4;
|
||
|
|
||
|
// Arguments:
|
||
|
// 2---3
|
||
|
// | |
|
||
|
// 0---1
|
||
|
void
|
||
|
CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, uint32 far)
|
||
|
{
|
||
|
float screenz, z, recipz;
|
||
|
|
||
|
if(far){
|
||
|
screenz = RwIm2DGetFarScreenZ();
|
||
|
z = RwCameraGetFarClipPlane(Scene.camera);
|
||
|
}else{
|
||
|
screenz = RwIm2DGetNearScreenZ();
|
||
|
z = 1.0f/RecipNearClip;
|
||
|
}
|
||
|
recipz = 1.0f/z;
|
||
|
|
||
|
// This is what we draw:
|
||
|
// 0---1
|
||
|
// | / |
|
||
|
// 3---2
|
||
|
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[0], r.bottom);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[0], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
|
||
|
RwIm2DVertexSetU(&maVertices[0], 0.0f, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[0], 0.0f, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[1], r.bottom);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[1], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
|
||
|
RwIm2DVertexSetU(&maVertices[1], 1.0f, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[1], 0.0f, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[2], r.top);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[2], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
|
||
|
RwIm2DVertexSetU(&maVertices[2], 1.0f, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[2], 1.0f, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[3], r.top);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[3], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
|
||
|
RwIm2DVertexSetU(&maVertices[3], 0.0f, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[3], 1.0f, recipz);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
|
||
|
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
|
||
|
{
|
||
|
float screenz, z, recipz;
|
||
|
|
||
|
screenz = RwIm2DGetNearScreenZ();
|
||
|
z = 1.0f/RecipNearClip;
|
||
|
recipz = 1.0f/z;
|
||
|
|
||
|
// This is what we draw:
|
||
|
// 0---1
|
||
|
// | / |
|
||
|
// 3---2
|
||
|
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[0], r.bottom);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[0], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
|
||
|
RwIm2DVertexSetU(&maVertices[0], u0, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[0], v0, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[1], r.bottom);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[1], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
|
||
|
RwIm2DVertexSetU(&maVertices[1], u1, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[1], v1, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[2], r.top);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[2], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
|
||
|
RwIm2DVertexSetU(&maVertices[2], u2, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[2], v2, recipz);
|
||
|
|
||
|
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
|
||
|
RwIm2DVertexSetScreenY(&maVertices[3], r.top);
|
||
|
RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&maVertices[3], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
|
||
|
RwIm2DVertexSetU(&maVertices[3], u3, recipz);
|
||
|
RwIm2DVertexSetV(&maVertices[3], v3, recipz);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite2d::SetRenderState(void)
|
||
|
{
|
||
|
if(m_pTexture)
|
||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(m_pTexture));
|
||
|
else
|
||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite2d::DrawRect(const CRect &r, const CRGBA &col)
|
||
|
{
|
||
|
SetVertices(r, col, col, col, col, false);
|
||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||
|
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(col.a != 255));
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, maVertices, 4);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||
|
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite2d::DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||
|
{
|
||
|
SetVertices(r, c0, c1, c2, c3, false);
|
||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, maVertices, 4);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||
|
{
|
||
|
SetVertices(r, c0, c1, c2, c3, false);
|
||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||
|
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||
|
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
float &CSprite::m_f2DNearScreenZ = *(float*)0x8F1ABC;
|
||
|
float &CSprite::m_f2DFarScreenZ = *(float*)0x8F2C94;
|
||
|
int32 &CSprite::m_bFlushSpriteBufferSwitchZTest = *(int32*)0x8F5FB0;
|
||
|
|
||
|
float
|
||
|
CSprite::CalcHorizonCoors(void)
|
||
|
{
|
||
|
CVector p = TheCamera.GetPosition() + CVector(TheCamera.CamFrontXNorm, TheCamera.CamFrontYNorm, 0.0f)*3000.0f;
|
||
|
p.z = 0.0f;
|
||
|
p = TheCamera.m_viewMatrix * p;
|
||
|
return p.y * RsGlobal.maximumHeight / p.z;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh, bool farclip)
|
||
|
{
|
||
|
CVector viewvec = TheCamera.m_viewMatrix * *(CVector*)∈
|
||
|
*out = *(RwV3d*)&viewvec;
|
||
|
if(out->z <= CDraw::GetNearClipZ() + 1.0f) return false;
|
||
|
if(out->z >= CDraw::GetFarClipZ() && farclip) return false;
|
||
|
float recip = 1.0f/out->z;
|
||
|
out->x *= RsGlobal.maximumWidth * recip;
|
||
|
out->y *= RsGlobal.maximumHeight * recip;
|
||
|
// What is this? size?
|
||
|
*outw = 70.0f/CDraw::GetFOV();
|
||
|
*outh = 70.0f/CDraw::GetFOV();
|
||
|
*outw *= RsGlobal.maximumWidth * recip;
|
||
|
*outh *= RsGlobal.maximumHeight * recip;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#define SPRITEBUFFERSIZE 64
|
||
|
static int32 &nSpriteBufferIndex = *(int32*)0x649A80;
|
||
|
static RwIm2DVertex *SpriteBufferVerts = (RwIm2DVertex*)0x649A84; //[SPRITEBUFFERSIZE*6];
|
||
|
static RwIm2DVertex *verts = (RwIm2DVertex*)0x64C484; //[4];
|
||
|
|
||
|
void
|
||
|
CSprite::InitSpriteBuffer(void)
|
||
|
{
|
||
|
m_f2DNearScreenZ = RwIm2DGetNearScreenZ();
|
||
|
m_f2DFarScreenZ = RwIm2DGetFarScreenZ();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::FlushSpriteBuffer(void)
|
||
|
{
|
||
|
if(nSpriteBufferIndex > 0){
|
||
|
if(m_bFlushSpriteBufferSwitchZTest){
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, SpriteBufferVerts, nSpriteBufferIndex*6);
|
||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||
|
}else
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, SpriteBufferVerts, nSpriteBufferIndex*6);
|
||
|
nSpriteBufferIndex = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::RenderOneXLUSprite(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, uint8 a)
|
||
|
{
|
||
|
static short indices[] = { 0, 1, 2, 3 };
|
||
|
// 0---3
|
||
|
// | |
|
||
|
// 1---2
|
||
|
float xs[4];
|
||
|
float ys[4];
|
||
|
float us[4];
|
||
|
float vs[4];
|
||
|
int i;
|
||
|
|
||
|
xs[0] = x-w; us[0] = 0.0f;
|
||
|
xs[1] = x-w; us[1] = 0.0f;
|
||
|
xs[2] = x+w; us[2] = 1.0f;
|
||
|
xs[3] = x+w; us[3] = 1.0f;
|
||
|
|
||
|
ys[0] = y-h; vs[0] = 0.0f;
|
||
|
ys[1] = y+h; vs[1] = 1.0f;
|
||
|
ys[2] = y+h; vs[2] = 1.0f;
|
||
|
ys[3] = y-h; vs[3] = 0.0f;
|
||
|
|
||
|
// clip
|
||
|
for(i = 0; i < 4; i++){
|
||
|
if(xs[i] < 0.0f){
|
||
|
us[i] = -xs[i] / (2.0f*w);
|
||
|
xs[i] = 0.0f;
|
||
|
}
|
||
|
if(xs[i] > RsGlobal.maximumWidth){
|
||
|
us[i] = 1.0f - (xs[i]-RsGlobal.maximumWidth) / (2.0f*w);
|
||
|
xs[i] = RsGlobal.maximumWidth;
|
||
|
}
|
||
|
if(ys[i] < 0.0f){
|
||
|
vs[i] = -ys[i] / (2.0f*h);
|
||
|
ys[i] = 0.0f;
|
||
|
}
|
||
|
if(ys[i] > RsGlobal.maximumHeight){
|
||
|
vs[i] = 1.0f - (ys[i]-RsGlobal.maximumHeight) / (2.0f*h);
|
||
|
ys[i] = RsGlobal.maximumHeight;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// (DrawZ - DrawNear)/(DrawFar - DrawNear) = (SpriteZ-SpriteNear)/(SpriteFar-SpriteNear)
|
||
|
// So to calculate SpriteZ:
|
||
|
float screenz = m_f2DNearScreenZ +
|
||
|
(z-CDraw::GetNearClipZ())*(m_f2DFarScreenZ-m_f2DNearScreenZ)*CDraw::GetFarClipZ() /
|
||
|
((CDraw::GetFarClipZ()-CDraw::GetNearClipZ())*z);
|
||
|
|
||
|
for(i = 0; i < 4; i++){
|
||
|
RwIm2DVertexSetScreenX(&verts[i], xs[i]);
|
||
|
RwIm2DVertexSetScreenY(&verts[i], ys[i]);
|
||
|
RwIm2DVertexSetScreenZ(&verts[i], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&verts[i], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&verts[i], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&verts[i], r*intens>>8, g*intens>>8, b*intens>>8, a);
|
||
|
RwIm2DVertexSetU(&verts[i], us[i], recipz);
|
||
|
RwIm2DVertexSetV(&verts[i], vs[i], recipz);
|
||
|
}
|
||
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, verts, 4);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::RenderBufferedOneXLUSprite(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, uint8 a)
|
||
|
{
|
||
|
m_bFlushSpriteBufferSwitchZTest = 0;
|
||
|
|
||
|
// 0---3
|
||
|
// | |
|
||
|
// 1---2
|
||
|
float xs[4];
|
||
|
float ys[4];
|
||
|
float us[4];
|
||
|
float vs[4];
|
||
|
int i;
|
||
|
|
||
|
xs[0] = x-w; us[0] = 0.0f;
|
||
|
xs[1] = x-w; us[1] = 0.0f;
|
||
|
xs[2] = x+w; us[2] = 1.0f;
|
||
|
xs[3] = x+w; us[3] = 1.0f;
|
||
|
|
||
|
ys[0] = y-h; vs[0] = 0.0f;
|
||
|
ys[1] = y+h; vs[1] = 1.0f;
|
||
|
ys[2] = y+h; vs[2] = 1.0f;
|
||
|
ys[3] = y-h; vs[3] = 0.0f;
|
||
|
|
||
|
// clip
|
||
|
for(i = 0; i < 4; i++){
|
||
|
if(xs[i] < 0.0f){
|
||
|
us[i] = -xs[i] / (2.0f*w);
|
||
|
xs[i] = 0.0f;
|
||
|
}
|
||
|
if(xs[i] > RsGlobal.maximumWidth){
|
||
|
us[i] = 1.0f - (xs[i]-RsGlobal.maximumWidth) / (2.0f*w);
|
||
|
xs[i] = RsGlobal.maximumWidth;
|
||
|
}
|
||
|
if(ys[i] < 0.0f){
|
||
|
vs[i] = -ys[i] / (2.0f*h);
|
||
|
ys[i] = 0.0f;
|
||
|
}
|
||
|
if(ys[i] > RsGlobal.maximumHeight){
|
||
|
vs[i] = 1.0f - (ys[i]-RsGlobal.maximumHeight) / (2.0f*h);
|
||
|
ys[i] = RsGlobal.maximumHeight;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float screenz = m_f2DNearScreenZ +
|
||
|
(z-CDraw::GetNearClipZ())*(m_f2DFarScreenZ-m_f2DNearScreenZ)*CDraw::GetFarClipZ() /
|
||
|
((CDraw::GetFarClipZ()-CDraw::GetNearClipZ())*z);
|
||
|
|
||
|
RwIm2DVertex *vert = &SpriteBufferVerts[nSpriteBufferIndex*6];
|
||
|
static int indices[6] = { 0, 1, 2, 3, 0, 2 };
|
||
|
for(i = 0; i < 6; i++){
|
||
|
RwIm2DVertexSetScreenX(&vert[i], xs[indices[i]]);
|
||
|
RwIm2DVertexSetScreenY(&vert[i], ys[indices[i]]);
|
||
|
RwIm2DVertexSetScreenZ(&vert[i], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&vert[i], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&vert[i], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&vert[i], r*intens>>8, g*intens>>8, b*intens>>8, a);
|
||
|
RwIm2DVertexSetU(&vert[i], us[indices[i]], recipz);
|
||
|
RwIm2DVertexSetV(&vert[i], vs[indices[i]], recipz);
|
||
|
}
|
||
|
nSpriteBufferIndex++;
|
||
|
if(nSpriteBufferIndex >= SPRITEBUFFERSIZE)
|
||
|
FlushSpriteBuffer();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a)
|
||
|
{
|
||
|
m_bFlushSpriteBufferSwitchZTest = 0;
|
||
|
// TODO: replace with lookup
|
||
|
float c = cos(DEGTORAD(rotation));
|
||
|
float s = sin(DEGTORAD(rotation));
|
||
|
|
||
|
float xs[4];
|
||
|
float ys[4];
|
||
|
float us[4];
|
||
|
float vs[4];
|
||
|
int i;
|
||
|
|
||
|
xs[0] = x - c*w - s*h; us[0] = 0.0f;
|
||
|
xs[1] = x - c*w + s*h; us[1] = 0.0f;
|
||
|
xs[2] = x + c*w + s*h; us[2] = 1.0f;
|
||
|
xs[3] = x + c*w - s*h; us[3] = 1.0f;
|
||
|
|
||
|
ys[0] = y - c*h + s*w; vs[0] = 0.0f;
|
||
|
ys[1] = y + c*h + s*w; vs[1] = 1.0f;
|
||
|
ys[2] = y + c*h - s*w; vs[2] = 1.0f;
|
||
|
ys[3] = y - c*h - s*w; vs[3] = 0.0f;
|
||
|
|
||
|
// No clipping, just culling
|
||
|
if(xs[0] < 0.0f && xs[1] < 0.0f && xs[2] < 0.0f && xs[3] < 0.0f) return;
|
||
|
if(ys[0] < 0.0f && ys[1] < 0.0f && ys[2] < 0.0f && ys[3] < 0.0f) return;
|
||
|
if(xs[0] > RsGlobal.maximumWidth && xs[1] > RsGlobal.maximumWidth &&
|
||
|
xs[2] > RsGlobal.maximumWidth && xs[3] > RsGlobal.maximumWidth) return;
|
||
|
if(ys[0] > RsGlobal.maximumHeight && ys[1] > RsGlobal.maximumHeight &&
|
||
|
ys[2] > RsGlobal.maximumHeight && ys[3] > RsGlobal.maximumHeight) return;
|
||
|
|
||
|
float screenz = m_f2DNearScreenZ +
|
||
|
(z-CDraw::GetNearClipZ())*(m_f2DFarScreenZ-m_f2DNearScreenZ)*CDraw::GetFarClipZ() /
|
||
|
((CDraw::GetFarClipZ()-CDraw::GetNearClipZ())*z);
|
||
|
|
||
|
RwIm2DVertex *vert = &SpriteBufferVerts[nSpriteBufferIndex*6];
|
||
|
static int indices[6] = { 0, 1, 2, 3, 0, 2 };
|
||
|
for(i = 0; i < 6; i++){
|
||
|
RwIm2DVertexSetScreenX(&vert[i], xs[indices[i]]);
|
||
|
RwIm2DVertexSetScreenY(&vert[i], ys[indices[i]]);
|
||
|
RwIm2DVertexSetScreenZ(&vert[i], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&vert[i], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&vert[i], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&vert[i], r*intens>>8, g*intens>>8, b*intens>>8, a);
|
||
|
RwIm2DVertexSetU(&vert[i], us[indices[i]], recipz);
|
||
|
RwIm2DVertexSetV(&vert[i], vs[indices[i]], recipz);
|
||
|
}
|
||
|
nSpriteBufferIndex++;
|
||
|
if(nSpriteBufferIndex >= SPRITEBUFFERSIZE)
|
||
|
FlushSpriteBuffer();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a)
|
||
|
{
|
||
|
m_bFlushSpriteBufferSwitchZTest = 0;
|
||
|
float c = cos(DEGTORAD(rotation));
|
||
|
float s = sin(DEGTORAD(rotation));
|
||
|
|
||
|
float xs[4];
|
||
|
float ys[4];
|
||
|
float us[4];
|
||
|
float vs[4];
|
||
|
int i;
|
||
|
|
||
|
xs[0] = x + w*(-c-s); us[0] = 0.0f;
|
||
|
xs[1] = x + w*(-c+s); us[1] = 0.0f;
|
||
|
xs[2] = x + w*(+c+s); us[2] = 1.0f;
|
||
|
xs[3] = x + w*(+c-s); us[3] = 1.0f;
|
||
|
|
||
|
ys[0] = y + h*(-c+s); vs[0] = 0.0f;
|
||
|
ys[1] = y + h*(+c+s); vs[1] = 1.0f;
|
||
|
ys[2] = y + h*(+c-s); vs[2] = 1.0f;
|
||
|
ys[3] = y + h*(-c-s); vs[3] = 0.0f;
|
||
|
|
||
|
// No clipping, just culling
|
||
|
if(xs[0] < 0.0f && xs[1] < 0.0f && xs[2] < 0.0f && xs[3] < 0.0f) return;
|
||
|
if(ys[0] < 0.0f && ys[1] < 0.0f && ys[2] < 0.0f && ys[3] < 0.0f) return;
|
||
|
if(xs[0] > RsGlobal.maximumWidth && xs[1] > RsGlobal.maximumWidth &&
|
||
|
xs[2] > RsGlobal.maximumWidth && xs[3] > RsGlobal.maximumWidth) return;
|
||
|
if(ys[0] > RsGlobal.maximumHeight && ys[1] > RsGlobal.maximumHeight &&
|
||
|
ys[2] > RsGlobal.maximumHeight && ys[3] > RsGlobal.maximumHeight) return;
|
||
|
|
||
|
float screenz = m_f2DNearScreenZ +
|
||
|
(z-CDraw::GetNearClipZ())*(m_f2DFarScreenZ-m_f2DNearScreenZ)*CDraw::GetFarClipZ() /
|
||
|
((CDraw::GetFarClipZ()-CDraw::GetNearClipZ())*z);
|
||
|
|
||
|
RwIm2DVertex *vert = &SpriteBufferVerts[nSpriteBufferIndex*6];
|
||
|
static int indices[6] = { 0, 1, 2, 3, 0, 2 };
|
||
|
for(i = 0; i < 6; i++){
|
||
|
RwIm2DVertexSetScreenX(&vert[i], xs[indices[i]]);
|
||
|
RwIm2DVertexSetScreenY(&vert[i], ys[indices[i]]);
|
||
|
RwIm2DVertexSetScreenZ(&vert[i], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&vert[i], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&vert[i], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&vert[i], r*intens>>8, g*intens>>8, b*intens>>8, a);
|
||
|
RwIm2DVertexSetU(&vert[i], us[indices[i]], recipz);
|
||
|
RwIm2DVertexSetV(&vert[i], vs[indices[i]], recipz);
|
||
|
}
|
||
|
nSpriteBufferIndex++;
|
||
|
if(nSpriteBufferIndex >= SPRITEBUFFERSIZE)
|
||
|
FlushSpriteBuffer();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours(float x, float y, float z, float w, float h, uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2, float cx, float cy, float recipz, float rotation, uint8 a)
|
||
|
{
|
||
|
m_bFlushSpriteBufferSwitchZTest = 0;
|
||
|
float c = cos(DEGTORAD(rotation));
|
||
|
float s = sin(DEGTORAD(rotation));
|
||
|
|
||
|
float xs[4];
|
||
|
float ys[4];
|
||
|
float us[4];
|
||
|
float vs[4];
|
||
|
float cf[4];
|
||
|
int i;
|
||
|
|
||
|
xs[0] = x + w*(-c-s); us[0] = 0.0f;
|
||
|
xs[1] = x + w*(-c+s); us[1] = 0.0f;
|
||
|
xs[2] = x + w*(+c+s); us[2] = 1.0f;
|
||
|
xs[3] = x + w*(+c-s); us[3] = 1.0f;
|
||
|
|
||
|
ys[0] = y + h*(-c+s); vs[0] = 0.0f;
|
||
|
ys[1] = y + h*(+c+s); vs[1] = 1.0f;
|
||
|
ys[2] = y + h*(+c-s); vs[2] = 1.0f;
|
||
|
ys[3] = y + h*(-c-s); vs[3] = 0.0f;
|
||
|
|
||
|
// No clipping, just culling
|
||
|
if(xs[0] < 0.0f && xs[1] < 0.0f && xs[2] < 0.0f && xs[3] < 0.0f) return;
|
||
|
if(ys[0] < 0.0f && ys[1] < 0.0f && ys[2] < 0.0f && ys[3] < 0.0f) return;
|
||
|
if(xs[0] > RsGlobal.maximumWidth && xs[1] > RsGlobal.maximumWidth &&
|
||
|
xs[2] > RsGlobal.maximumWidth && xs[3] > RsGlobal.maximumWidth) return;
|
||
|
if(ys[0] > RsGlobal.maximumHeight && ys[1] > RsGlobal.maximumHeight &&
|
||
|
ys[2] > RsGlobal.maximumHeight && ys[3] > RsGlobal.maximumHeight) return;
|
||
|
|
||
|
// Colour factors, cx/y is the direction in which colours change from rgb1 to rgb2
|
||
|
cf[0] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
|
||
|
cf[0] = clamp(cf[0], 0.0f, 1.0f);
|
||
|
cf[1] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
|
||
|
cf[1] = clamp(cf[1], 0.0f, 1.0f);
|
||
|
cf[2] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
|
||
|
cf[2] = clamp(cf[2], 0.0f, 1.0f);
|
||
|
cf[3] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
|
||
|
cf[3] = clamp(cf[3], 0.0f, 1.0f);
|
||
|
|
||
|
float screenz = m_f2DNearScreenZ +
|
||
|
(z-CDraw::GetNearClipZ())*(m_f2DFarScreenZ-m_f2DNearScreenZ)*CDraw::GetFarClipZ() /
|
||
|
((CDraw::GetFarClipZ()-CDraw::GetNearClipZ())*z);
|
||
|
|
||
|
RwIm2DVertex *vert = &SpriteBufferVerts[nSpriteBufferIndex*6];
|
||
|
static int indices[6] = { 0, 1, 2, 3, 0, 2 };
|
||
|
for(i = 0; i < 6; i++){
|
||
|
RwIm2DVertexSetScreenX(&vert[i], xs[indices[i]]);
|
||
|
RwIm2DVertexSetScreenY(&vert[i], ys[indices[i]]);
|
||
|
RwIm2DVertexSetScreenZ(&vert[i], screenz);
|
||
|
RwIm2DVertexSetCameraZ(&vert[i], z);
|
||
|
RwIm2DVertexSetRecipCameraZ(&vert[i], recipz);
|
||
|
RwIm2DVertexSetIntRGBA(&vert[i],
|
||
|
r1*cf[indices[i]] + r2*(1.0f - cf[indices[i]]),
|
||
|
g1*cf[indices[i]] + g2*(1.0f - cf[indices[i]]),
|
||
|
b1*cf[indices[i]] + b2*(1.0f - cf[indices[i]]),
|
||
|
a);
|
||
|
RwIm2DVertexSetU(&vert[i], us[indices[i]], recipz);
|
||
|
RwIm2DVertexSetV(&vert[i], vs[indices[i]], recipz);
|
||
|
}
|
||
|
nSpriteBufferIndex++;
|
||
|
if(nSpriteBufferIndex >= SPRITEBUFFERSIZE)
|
||
|
FlushSpriteBuffer();
|
||
|
}
|
||
|
|
||
|
STARTPATCHES
|
||
|
InjectHook(0x51EE90, (void (*)(const CRect&, const CRGBA&, const CRGBA&, const CRGBA&, const CRGBA&, uint32))CSprite2d::SetVertices, PATCH_JUMP);
|
||
|
InjectHook(0x51F220, (void (*)(const CRect&, const CRGBA&, const CRGBA&, const CRGBA&, const CRGBA&,
|
||
|
float, float, float, float, float, float, float, float))CSprite2d::SetVertices, PATCH_JUMP);
|
||
|
InjectHook(0x51F970, (void (*)(const CRect&, const CRGBA&))CSprite2d::DrawRect, PATCH_JUMP);
|
||
|
InjectHook(0x51FA00, (void (*)(const CRect&, const CRGBA&, const CRGBA&, const CRGBA&, const CRGBA&))CSprite2d::DrawRect, PATCH_JUMP);
|
||
|
InjectHook(0x51FA80, CSprite2d::DrawRectXLU, PATCH_JUMP);
|
||
|
|
||
|
InjectHook(0x51C4A0, CSprite::CalcHorizonCoors, PATCH_JUMP);
|
||
|
InjectHook(0x51C3A0, CSprite::CalcScreenCoors, PATCH_JUMP);
|
||
|
InjectHook(0x51C590, CSprite::InitSpriteBuffer, PATCH_JUMP);
|
||
|
InjectHook(0x51C520, CSprite::FlushSpriteBuffer, PATCH_JUMP);
|
||
|
InjectHook(0x51C960, CSprite::RenderOneXLUSprite, PATCH_JUMP);
|
||
|
InjectHook(0x51C5D0, CSprite::RenderBufferedOneXLUSprite, PATCH_JUMP);
|
||
|
InjectHook(0x51D5B0, CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension, PATCH_JUMP);
|
||
|
InjectHook(0x51CCD0, CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect, PATCH_JUMP);
|
||
|
InjectHook(0x51D9E0, CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours, PATCH_JUMP);
|
||
|
ENDPATCHES
|