mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-07 03:13:49 +00:00
293 lines
6.9 KiB
C++
293 lines
6.9 KiB
C++
#include <algorithm>
|
|
#include "Debug.h"
|
|
#include "RSP.h"
|
|
#include "RDP.h"
|
|
#include "N64.h"
|
|
#include "F3D.h"
|
|
#include "VI.h"
|
|
#include "Combiner.h"
|
|
#include "FrameBuffer.h"
|
|
#include "DepthBuffer.h"
|
|
#include "GBI.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()
|
|
{
|
|
VI_UpdateSize();
|
|
video().updateScale();
|
|
|
|
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 );
|
|
gSP.matrix.modelViewi = 0;
|
|
gSP.changed &= ~CHANGED_CPU_FB_WRITE;
|
|
gSP.changed |= CHANGED_MATRIX;
|
|
|
|
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;
|
|
|
|
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 );
|
|
|
|
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 );
|
|
|
|
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;
|
|
}
|
|
|
|
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
|
|
for (int i = 0; i < 20; ++i)
|
|
RSP.romname[i] = HEADER[(32 + i) ^ 3];
|
|
RSP.romname[20] = 0;
|
|
|
|
// remove all trailing spaces
|
|
while (RSP.romname[strlen(RSP.romname) - 1] == ' ')
|
|
RSP.romname[strlen(RSP.romname) - 1] = 0;
|
|
|
|
memset(&gSP, 0, sizeof(gSPInfo));
|
|
|
|
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;
|
|
}
|