mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 06:39:46 -06:00
Graphics: (faked) bounding box support. Helps some Paper Mario effects although they're still a bit glitchy. Might also help other games? Enable with the #define in VideoCommon.h. Since there might be a speed hit it's off by default.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3580 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -62,6 +62,7 @@
|
||||
#define BPMEM_COPYFILTER1 0x54
|
||||
#define BPMEM_CLEARBBOX1 0x55
|
||||
#define BPMEM_CLEARBBOX2 0x56
|
||||
// what about 0x57?
|
||||
#define BPMEM_UNKNOWN 0x58
|
||||
#define BPMEM_SCISSOROFFSET 0x59
|
||||
#define BPMEM_UNKNOWN1 0x60
|
||||
|
@ -211,7 +211,12 @@ void BPWritten(const Bypass& bp)
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should be able to get away with deactivating the current bbox tracking
|
||||
// here. Not sure if there's a better spot to put this.
|
||||
// the number of lines copied is determined by the y scale * source efb height
|
||||
#ifdef BBOX_SUPPORT
|
||||
*g_VideoInitialize.pBBoxActive = false;
|
||||
#endif
|
||||
const float yScale = bpmem.dispcopyyscale / 256.0f;
|
||||
const float xfbLines = ((bpmem.copyTexSrcWH.y + 1.0f) * yScale);
|
||||
RenderToXFB(bp, multirc, yScale, xfbLines,
|
||||
@ -324,13 +329,35 @@ void BPWritten(const Bypass& bp)
|
||||
case BPMEM_CLEAR_Z: // Z Components (24-bit Zbuffer)
|
||||
break;
|
||||
// -------------------------
|
||||
// Culling Occulsion, we don't support this
|
||||
// let's hope not many games use bboxes..
|
||||
// TODO(ector): add something that watches bboxes
|
||||
// Bounding Box support
|
||||
// -------------------------
|
||||
case BPMEM_CLEARBBOX1:
|
||||
case BPMEM_CLEARBBOX2:
|
||||
case BPMEM_CLEARBBOX2: {
|
||||
|
||||
#ifdef BBOX_SUPPORT
|
||||
// which is which? these are GUESSES!
|
||||
if (bp.address == BPMEM_CLEARBBOX1) {
|
||||
int right = bp.newvalue >> 10;
|
||||
int left = bp.newvalue & 0x3ff;
|
||||
|
||||
// We should only set these if bbox is calculated properly.
|
||||
g_VideoInitialize.pBBox[0] = left;
|
||||
g_VideoInitialize.pBBox[1] = right;
|
||||
*g_VideoInitialize.pBBoxActive = true;
|
||||
// WARN_LOG(VIDEO, "ClearBBox LR: %i, %08x - %i, %i", bp.address, bp.newvalue, left, right);
|
||||
} else {
|
||||
int bottom = bp.newvalue >> 10;
|
||||
int top = bp.newvalue & 0x3ff;
|
||||
|
||||
// We should only set these if bbox is calculated properly.
|
||||
g_VideoInitialize.pBBox[2] = top;
|
||||
g_VideoInitialize.pBBox[3] = bottom;
|
||||
*g_VideoInitialize.pBBoxActive = true;
|
||||
// WARN_LOG(VIDEO, "ClearBBox TB: %i, %08x - %i, %i", bp.address, bp.newvalue, top, bottom);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case BPMEM_ZCOMPARE: // Set the Z-Compare
|
||||
case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow
|
||||
case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
|
||||
@ -363,14 +390,14 @@ void BPWritten(const Bypass& bp)
|
||||
PanicAlert("Unknown is not 0xF! val = 0x%08x", bp.newvalue);
|
||||
break;
|
||||
|
||||
// Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90
|
||||
// Are these related to BBox?
|
||||
case BPMEM_UNKNOWN1:
|
||||
case BPMEM_UNKNOWN2:
|
||||
case BPMEM_UNKNOWN3:
|
||||
case BPMEM_UNKNOWN4:
|
||||
|
||||
// Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90
|
||||
// Are these related to BBox?
|
||||
break;
|
||||
|
||||
// ------------------------------------------------
|
||||
// On Default, we try to look for other things
|
||||
// before we give up and say its an unknown opcode
|
||||
|
@ -38,6 +38,10 @@
|
||||
#include "VertexLoader_Color.h"
|
||||
#include "VertexLoader_TextCoord.h"
|
||||
|
||||
//BBox
|
||||
#include "XFMemory.h"
|
||||
extern float GC_ALIGNED16(g_fProjectionMatrix[16]);
|
||||
|
||||
#define USE_JIT
|
||||
|
||||
#define COMPILED_CODE_SIZE 4096
|
||||
@ -82,6 +86,50 @@ void LOADERDECL PosMtx_Write()
|
||||
*VertexManager::s_pCurBufferPointer++ = 0;
|
||||
}
|
||||
|
||||
void LOADERDECL UpdateBoundingBox()
|
||||
{
|
||||
if (!*g_VideoInitialize.pBBoxActive)
|
||||
return;
|
||||
|
||||
// Truly evil hack, reading backwards from the write pointer. If we were writing to write-only
|
||||
// memory like we might have been with a D3D vertex buffer, this would have been a bad idea.
|
||||
float *data = (float *)(VertexManager::s_pCurBufferPointer - 12);
|
||||
// We must transform the just loaded point by the current world and projection matrix - in software.
|
||||
// Then convert to screen space and update the bounding box.
|
||||
float p[3] = {data[0], data[1], data[2]};
|
||||
|
||||
const float *world_matrix = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
|
||||
const float *proj_matrix = &g_fProjectionMatrix[0];
|
||||
|
||||
float t[3];
|
||||
t[0] = p[0] * world_matrix[0] + p[1] * world_matrix[1] + p[2] * world_matrix[2] + world_matrix[3];
|
||||
t[1] = p[0] * world_matrix[4] + p[1] * world_matrix[5] + p[2] * world_matrix[6] + world_matrix[7];
|
||||
t[2] = p[0] * world_matrix[8] + p[1] * world_matrix[9] + p[2] * world_matrix[10] + world_matrix[11];
|
||||
|
||||
float o[4];
|
||||
o[0] = t[0] * proj_matrix[0] + t[1] * proj_matrix[1] + t[2] * proj_matrix[2] + proj_matrix[3];
|
||||
o[1] = t[0] * proj_matrix[4] + t[1] * proj_matrix[5] + t[2] * proj_matrix[6] + proj_matrix[7];
|
||||
o[2] = t[0] * proj_matrix[8] + t[1] * proj_matrix[9] + t[2] * proj_matrix[10] + proj_matrix[11];
|
||||
o[3] = t[0] * proj_matrix[12] + t[1] * proj_matrix[13] + t[2] * proj_matrix[14] + proj_matrix[15];
|
||||
|
||||
o[0] /= o[3];
|
||||
o[1] /= o[3];
|
||||
|
||||
// should possibly adjust for viewport?
|
||||
o[0] = (o[0] + 1.0f) * 320.0f;
|
||||
o[1] = (o[1] + 1.0f) * 240.0f;
|
||||
|
||||
if (o[0] < g_VideoInitialize.pBBox[0]) g_VideoInitialize.pBBox[0] = std::max(0.0f, o[0]);
|
||||
if (o[0] > g_VideoInitialize.pBBox[1]) g_VideoInitialize.pBBox[1] = std::min(640.0f, o[0]);
|
||||
if (o[1] < g_VideoInitialize.pBBox[2]) g_VideoInitialize.pBBox[2] = std::max(0.0f, o[1]);
|
||||
if (o[1] > g_VideoInitialize.pBBox[3]) g_VideoInitialize.pBBox[3] = std::min(480.0f, o[1]);
|
||||
/*
|
||||
if (GetAsyncKeyState(VK_LSHIFT)) {
|
||||
ERROR_LOG(VIDEO, "XForm: %f %f %f to %f %f", p[0], p[1], p[2], o[0], o[1]);
|
||||
ERROR_LOG(VIDEO, "%i %i %i %i", g_VideoInitialize.pBBox[0], g_VideoInitialize.pBBox[1], g_VideoInitialize.pBBox[2], g_VideoInitialize.pBBox[3]);
|
||||
}*/
|
||||
}
|
||||
|
||||
void LOADERDECL TexMtx_ReadDirect_UByte()
|
||||
{
|
||||
s_curtexmtx[s_texmtxread] = DataReadU8() & 0x3f;
|
||||
@ -247,6 +295,12 @@ void VertexLoader::CompileVertexTranslator()
|
||||
break;
|
||||
}
|
||||
|
||||
// OK, so we just got a point. Let's go back and read it for the bounding box.
|
||||
|
||||
#ifdef BBOX_SUPPORT
|
||||
WriteCall(UpdateBoundingBox);
|
||||
#endif
|
||||
|
||||
// Normals
|
||||
vtx_decl.num_normals = 0;
|
||||
if (m_VtxDesc.Normal != NOT_PRESENT) {
|
||||
|
@ -36,7 +36,8 @@ namespace VertexManager
|
||||
void Flush();
|
||||
}
|
||||
|
||||
static float s_fMaterials[16];
|
||||
static float GC_ALIGNED16(s_fMaterials[16]);
|
||||
float GC_ALIGNED16(g_fProjectionMatrix[16]);
|
||||
|
||||
// track changes
|
||||
static bool bTexMatricesChanged[2], bPosNormalMatrixChanged, bProjectionChanged, bViewportChanged;
|
||||
@ -204,8 +205,6 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
|
||||
|
||||
if (bProjectionChanged) {
|
||||
bProjectionChanged = false;
|
||||
static float GC_ALIGNED16(g_fProjectionMatrix[16]);
|
||||
|
||||
|
||||
if (xfregs.rawProjection[6] == 0) { // Perspective
|
||||
g_fProjectionMatrix[0] = xfregs.rawProjection[0];
|
||||
|
@ -45,7 +45,15 @@ enum
|
||||
// TODO: figure out what to do with PAL
|
||||
};
|
||||
|
||||
// If this is enabled, bounding boxes will be computed for everything drawn.
|
||||
// This can theoretically have a big speed hit in some geom heavy games. Needs more work.
|
||||
// Helps some effects in Paper Mario (but they aren't quite right yet).
|
||||
// May help Super Mario Galaxy?
|
||||
// Do testing to figure out if the speed hit is bad?
|
||||
// #define BBOX_SUPPORT
|
||||
|
||||
extern SVideoInitialize g_VideoInitialize;
|
||||
|
||||
// (mb2) for XFB update hack. TODO: find a static better place
|
||||
extern volatile u32 g_XFBUpdateRequested;
|
||||
|
||||
|
Reference in New Issue
Block a user