1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-07 03:13:49 +00:00
GLideN64/RSP.cpp
Sergey Lipskiy 34d638a0a3 Don't copy depth buffer if it was not cleared.
Uncleared depth buffer most likely is used as auxilary color buffer.

Fix pause screen in Mickey USA when copy depth to RDRAM is enabled, issue #85.
2015-05-13 10:18:14 +06:00

320 lines
7.6 KiB
C++

#include <algorithm>
#include "Debug.h"
#include "RSP.h"
#include "RDP.h"
#include "N64.h"
#include "F3D.h"
#include "Turbo3D.h"
#include "VI.h"
#include "Combiner.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "GBI.h"
#include "PluginAPI.h"
#include "Config.h"
using namespace std;
RSPInfo RSP;
void RSP_LoadMatrix( f32 mtx[4][4], u32 address )
{
f32 recip = 1.5258789e-05f;
#ifdef WIN32_ASM
__asm {
mov esi, dword ptr [RDRAM];
add esi, dword ptr [address];
mov edi, dword ptr [mtx];
mov ecx, 4
LoadLoop:
fild word ptr [esi+02h]
movzx eax, word ptr [esi+22h]
mov dword ptr [edi], eax
fild dword ptr [edi]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi]
fild word ptr [esi+00h]
movzx eax, word ptr [esi+20h]
mov dword ptr [edi+04h], eax
fild dword ptr [edi+04h]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+04h]
fild word ptr [esi+06h]
movzx eax, word ptr [esi+26h]
mov dword ptr [edi+08h], eax
fild dword ptr [edi+08h]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+08h]
fild word ptr [esi+04h]
movzx eax, word ptr [esi+24h]
mov dword ptr [edi+0Ch], eax
fild dword ptr [edi+0Ch]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+0Ch]
add esi, 08h
add edi, 10h
loop LoadLoop
}
#else // WIN32_ASM
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
"LoadLoop:" "\n\t"
" fild word ptr [esi+0x02]" "\n\t"
" movzx eax, word ptr [esi+0x22]" "\n\t"
" mov dword ptr [edi], eax" "\n\t"
" fild dword ptr [edi]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi]" "\n\t"
" fild word ptr [esi+0x00]" "\n\t"
" movzx eax, word ptr [esi+0x20]" "\n\t"
" mov dword ptr [edi+0x04], eax" "\n\t"
" fild dword ptr [edi+0x04]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x04]" "\n\t"
" fild word ptr [esi+0x06]" "\n\t"
" movzx eax, word ptr [esi+0x26]" "\n\t"
" mov dword ptr [edi+0x08], eax" "\n\t"
" fild dword ptr [edi+0x08]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x08]" "\n\t"
" fild word ptr [esi+0x04]" "\n\t"
" movzx eax, word ptr [esi+0x24]" "\n\t"
" mov dword ptr [edi+0x0C], eax" "\n\t"
" fild dword ptr [edi+0x0C]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x0C]" "\n\t"
" add esi, 0x08" "\n\t"
" add edi, 0x10" "\n\t"
" loop LoadLoop" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "f"(recip), "S"((int)RDRAM+address), "D"(mtx), "c"(4)
: "memory" );
# else // X86_ASM
struct _N64Matrix
{
SHORT integer[4][4];
WORD fraction[4][4];
} *n64Mat = (struct _N64Matrix *)&RDRAM[address];
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
mtx[i][j] = (GLfloat)(n64Mat->integer[i][j^1]) + (GLfloat)(n64Mat->fraction[i][j^1]) * recip;
# endif // !X86_ASM
#endif // WIN32_ASM
}
void RSP_CheckDLCounter()
{
if (RSP.count != -1) {
--RSP.count;
if (RSP.count == 0) {
RSP.count = -1;
--RSP.PCi;
DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "End of DL\n" );
}
}
}
void RSP_ProcessDList()
{
RSP.PC[0] = *(u32*)&DMEM[0x0FF0];
RSP.PCi = 0;
RSP.count = -1;
RSP.halt = FALSE;
RSP.busy = TRUE;
gSP.matrix.stackSize = min( 32U, *(u32*)&DMEM[0x0FE4] >> 6 );
if (gSP.matrix.stackSize == 0)
gSP.matrix.stackSize = 32;
gSP.matrix.modelViewi = 0;
gSP.changed &= ~CHANGED_CPU_FB_WRITE;
gSP.changed |= CHANGED_MATRIX;
gDPSetDepthSource(G_ZS_PIXEL);
gDPSetTexturePersp(G_TP_PERSP);
u32 uc_start = *(u32*)&DMEM[0x0FD0];
u32 uc_dstart = *(u32*)&DMEM[0x0FD8];
u32 uc_dsize = *(u32*)&DMEM[0x0FDC];
if ((uc_start != RSP.uc_start) || (uc_dstart != RSP.uc_dstart)) {
gSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize);
RSP.uc_start = uc_start;
RSP.uc_dstart = uc_dstart;
}
depthBufferList().setNotCleared();
if (GBI.getMicrocodeType() == Turbo3D)
RunTurbo3D();
else {
while (!RSP.halt) {
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize) {
#ifdef DEBUG
switch (Debug.level)
{
case DEBUG_LOW:
DebugMsg( DEBUG_LOW | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n" );
break;
case DEBUG_MEDIUM:
DebugMsg( DEBUG_MEDIUM | DEBUG_ERROR, "Attempting to execute RSP command at invalid RDRAM location\n" );
break;
case DEBUG_HIGH:
DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to execute RSP command at invalid RDRAM location\n" );
break;
}
#endif
break;
}
// printf( "!!!!!! RDRAM = 0x%8.8x\n", RDRAM );//RSP.PC[RSP.PCi] );
/* {
static u8 *lastRDRAM = 0;
if (lastRDRAM == 0)
lastRDRAM = RDRAM;
if (RDRAM != lastRDRAM)
{
__asm__( "int $3" );
}
}*/
u32 w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
u32 w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR(w0, 24, 8);
#ifdef DEBUG
DebugRSPState( RSP.PCi, RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 );
DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 );
#endif
RSP.PC[RSP.PCi] += 8;
RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi]], 24, 8);
GBI.cmd[RSP.cmd](w0, w1);
RSP_CheckDLCounter();
}
}
if (config.frameBufferEmulation.copyToRDRAM)
FrameBuffer_CopyToRDRAM( gDP.colorImage.address, false );
if (config.frameBufferEmulation.copyDepthToRDRAM)
FrameBuffer_CopyDepthBuffer( gDP.colorImage.address );
RSP.busy = FALSE;
RSP.DList++;
gSP.changed |= CHANGED_COLORBUFFER;
}
static
void RSP_SetDefaultState()
{
memset(&gSP, 0, sizeof(gSPInfo));
gSPTexture(1.0f, 1.0f, 0, 0, TRUE);
gDP.loadTile = &gDP.tiles[7];
gSP.textureTile[0] = &gDP.tiles[0];
gSP.textureTile[1] = &gDP.tiles[1];
gSP.lookat[0].x = gSP.lookat[1].x = 1.0f;
gSP.lookatEnable = false;
gSP.objMatrix.A = 1.0f;
gSP.objMatrix.B = 0.0f;
gSP.objMatrix.C = 0.0f;
gSP.objMatrix.D = 1.0f;
gSP.objMatrix.X = 0.0f;
gSP.objMatrix.Y = 0.0f;
gSP.objMatrix.baseScaleX = 1.0f;
gSP.objMatrix.baseScaleY = 1.0f;
gSP.objRendermode = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
gSP.matrix.modelView[0][i][j] = 0.0f;
gSP.matrix.modelView[0][0][0] = 1.0f;
gSP.matrix.modelView[0][1][1] = 1.0f;
gSP.matrix.modelView[0][2][2] = 1.0f;
gSP.matrix.modelView[0][3][3] = 1.0f;
gDPSetAlphaCompare(G_AC_NONE);
gDPSetDepthSource(G_ZS_PIXEL);
gDPSetRenderMode(0, 0);
gDPSetAlphaDither(G_AD_DISABLE);
gDPSetColorDither(G_CD_DISABLE);
gDPSetCombineKey(G_CK_NONE);
gDPSetTextureConvert(G_TC_FILT);
gDPSetTextureFilter(G_TF_POINT);
gDPSetTextureLUT(G_TT_NONE);
gDPSetTextureLOD(G_TL_TILE);
gDPSetTextureDetail(G_TD_CLAMP);
gDPSetTexturePersp(G_TP_PERSP);
gDPSetCycleType(G_CYC_1CYCLE);
gDPPipelineMode(G_PM_NPRIMITIVE);
}
void RSP_Init()
{
#ifdef OS_WINDOWS
// Calculate RDRAM size by intentionally causing an access violation
u32 test;
try
{
test = RDRAM[0x007FFFFF] + 1;
}
catch (...)
{
test = 0;
}
if (test > 0)
RDRAMSize = 0x7FFFFF;
else
RDRAMSize = 0x3FFFFF;
#else // OS_WINDOWS
RDRAMSize = 1024 * 1024 * 8;
#endif // OS_WINDOWS
RSP.DList = 0;
RSP.uc_start = RSP.uc_dstart = 0;
RSP.bLLE = false;
// get the name of the ROM
char romname[21];
for (int i = 0; i < 20; ++i)
romname[i] = HEADER[(32 + i) ^ 3];
romname[20] = 0;
// remove all trailing spaces
while (romname[strlen(romname) - 1] == ' ')
romname[strlen(romname) - 1] = 0;
if (strcmp(RSP.romname, romname) != 0)
TFH.shutdown();
strncpy(RSP.romname, romname, 21);
if (strstr(RSP.romname, (const char *)"OgreBattle64"))
config.generalEmulation.hacks |= hack_Ogre64;
api().FindPluginPath(RSP.pluginpath);
RSP_SetDefaultState();
}