mupen64plus-oldsvn/tr64_ogl/rdp.c
2009-05-28 12:47:17 +00:00

2035 lines
56 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright (C) 2009 icepir8 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <windows.h>
#include "type_sizes.h"
#include "wingl.h"
#include "debug.h"
#include "Combine.h"
#include "crc_ucode.h"
//** externals
extern int *pInterruptMask;
extern unsigned char *pRDRAM;
extern unsigned char *pIDMEM;
extern unsigned char *pVIREG;
extern _u32 *pVIORG;
char output[1024];
_u32 pltmode;
extern _u32 *Palette8;;
extern _u32 Palette8IA[256];
extern _u32 Palette8RGBA[256];
//extern unsigned long Palette4[256];
extern int Vtidx[256];
extern int Vtcnt;
extern void FlushVisualTriangle(int vn[]);
extern void loadtile(int tile);
#include "rdp.h"
#include "rdp_registers.h"
#include "Combine.h"
// FiRES
extern int ucode_version;
extern HWND hGraphics;
extern BOOLEAN Draw2d;
#include "rdp_gl.h"
#include "Render.h"
/* define macros - to speed up things and to make things looking nice */
#define MAXSMASK 7
#define MAXTMASK 7
#define SKIPMASK 1
BOOL CamSpyGo = TRUE;
BOOL CamSpyON = FALSE;
_u32 PaletteCRC[17];
_u8 m_tmem[0x1010];
_u32 InvPaletteCRC[17];
t_rdp_reg rdp_reg;
static _u32 segoffset2addr(_u32 so); /* calcs the real addr out of seg and offset */
int DList_C = 0;
//** rdp instructions (audio & graphics)
//** All ucodes
// Globals
//#define LstLdAddrSize (32 * 32)
#define LstLdAddrSize (64)
#define LstLdAddrMask (LstLdAddrSize - 1)
LoadCache tmpLdAddr;
LoadCache LstLdAddr[LstLdAddrSize];
_u32 LstLdAddNum = 0;
static char *format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" };
static char *size[] = { "4bit", "8bit", "16bit", "32bit" };
static char *cm[] = { "NOMIRROR/WARP(NOCLAMP)", "MIRROR", "CLAMP", "MIRROR&CLAMP" };
static void fixme();
static void spnoop();
static void rdp_noop();
static void rdp_texrect();
static void rdp_texrectflip();
static void rdp_loadsync();
static void rdp_pipesync();
static void rdp_tilesync();
static void rdp_fullsync();
static void rdp_setkeygb();
static void rdp_setkeyr();
static void rdp_setconvert();
static void rdp_setscissor();
static void rdp_setprimdepth();
static void rdp_setothermode();
static void rdp_loadtlut();
static void rdp_settilesize();
static void rdp_loadblock();
static void rdp_loadtile();
static void rdp_settile();
static void rdp_fillrect();
static void rdp_setfillcolor();
static void rdp_setfogcolor();
static void rdp_setblendcolor();
static void rdp_setprimcolor();
static void rdp_setenvcolor();
extern void rdp_setcombine();
static void rdp_settextureimage();
static void rdp_setdepthimage();
static void rdp_setcolorimage();
static void rdp_trifill();
static void rdp_trishade();
static void rdp_tritxtr();
static void rdp_trishadetxtr();
static void rdp_trifillz();
static void rdp_trishadez();
static void rdp_tritxtrz();
static void rdp_trishadetxtrz();
static void rsp_texture();
static void rsp_reserved0();
static void rsp_reserved1();
static void rsp_reserved2();
static void rsp_reserved3();
void DelTexture();
static void MathTextureScales();
void hleGetMatrix(float *dst,_u8 *src);
void exec_gfx();
int swapMode = 0;
int swapmodecnt = 5;
_u32 lastaddr;
BOOL SwapNow;
extern float imgHeight;
extern float imgWidth;
extern _u32 vi_height;
extern _u32 vi_width;
extern BOOL vi_Hires;
//////////////////////////////////////////////////////////////////////////////
// structure is tricky for changing the endians //
//////////////////////////////////////////////////////////////////////////////
float UC6_Matrices[8][4][4];
_u8 doReadMemByte(_u32 where)
{
where ^= 0x03;
return(*((_u8 *)&pRDRAM[where]));
} // _u8 doReadMemByte(_u32 where)
_u16 doReadMemHalfWord(_u32 where)
{
where ^= 0x02;
return(*((_u16 *)&pRDRAM[where]));
} // _u16 doReadMemHalfWord(_u32 where)
_u32 doReadMemWord(_u32 where)
{
return(*((_u32 *)&pRDRAM[where]));
} // _u32 doReadMemWord(_u32 where)
_u64 doReadMemDoubleWord(_u32 where)
{
_u64 value;
value = (*((_u64 *)&pRDRAM[where]));
return( (value >> 32) | (value << 32) );
} // _u64 doReadMemDoubleWord(_u32 where)
#include "hle_uc00.h"
#include "hle_uc01.h"
#include "hle_uc02.h"
#include "hle_uc03.h"
#include "hle_uc04.h"
#include "hle_uc05.h"
#include "hle_uc06.h"
#include "hle_uc07.h"
#include "hle_uc.h" // All Functions-Array
void exec_gfx()
{
gfx_instruction[ucode_version][rdp_reg.cmd0>>24]();
}
/******************************************************************************\
* *
* RDP (Reality Display Processor) - global routines *
* *
\******************************************************************************/
static void MathTextureScales()
{
int i = rdp_reg.tile;
float TScaleT, TScaleS;
_u32 twidth,theight;
twidth=rdp_reg.m_CurTile->Width;
theight=rdp_reg.m_CurTile->Height;
//twidth=rdp_reg.m_CurTile->lrs - rdp_reg.m_CurTile->uls + 1;
//theight=rdp_reg.m_CurTile->lrt - rdp_reg.m_CurTile->ult + 1;
if(twidth==0) twidth=1;
if(theight==0) theight=1;
if(rdp_reg.m_CurTile->shifts<MAXSHIFTS)
twidth<<=rdp_reg.m_CurTile->shifts;
else
twidth>>=(16-rdp_reg.m_CurTile->shifts);
if(rdp_reg.m_CurTile->shiftt<MAXSHIFTT)
theight<<=rdp_reg.m_CurTile->shiftt;
else
theight>>=(16-rdp_reg.m_CurTile->shiftt);
TScaleS = rdp_reg.m_CurTile->SScale;
TScaleT = rdp_reg.m_CurTile->TScale;
if (rdp_reg.m_CurTile->mirrors)
TScaleS /= 2;
if (rdp_reg.m_CurTile->mirrort)
TScaleT /= 2;
rdp_reg.texture[i].scale_t = TScaleT;
rdp_reg.texture[i].scale_s = TScaleS;
rdp_reg.texture[i].scale_w = 1.0f / twidth;
rdp_reg.texture[i].scale_h = 1.0f / theight;
}
void hleGetMatrix(float *dst,_u8 *src)
{
float Const=1.f/65536.f;
_asm
{
mov edi,dword ptr dst
mov esi,dword ptr src
mov ecx,8
mat_loop:
push ecx
mov eax,dword ptr [esi]
mov ebx,eax
and eax,0xffff0000
and ebx,0x0ffff
shl ebx,16
mov ecx,dword ptr [esi+32]
mov edx,ecx
shr ecx,16
mov ax,cx
mov bx,dx
add esi,4
mov dword ptr [edi+4],eax
mov dword ptr [edi],ebx
fild dword ptr [edi]
fmul DWORD PTR Const
fild dword ptr [edi+4]
fmul DWORD PTR Const
pop ecx
fstp DWORD PTR [edi]
fstp DWORD PTR [edi+4]
add edi,8
loop mat_loop
}
}
extern unsigned short m_idx;
extern int ArrayOk;
float tmpMat[4][4] = {{1.0f,0.0f,0.0f,0.0f}
,{0.0f,1.0f,0.0f,0.0f}
,{0.0f,0.0f,1.0f,0.0f}
,{0.0f,0.0f,0.0f,1.0f}};
void rdp_reset()
{
int idx;
load_matrix((float*)tmpMat);
ArrayOk = 0;
for (idx = 0; idx < 16; idx++) rdp_reg.segment[idx] = 0xffffffff;
rdp_reg.m_CurTile = &rdp_reg.td[0];
rdp_reg.tile = 0;
//rdp_reg.m_NexTile = &rdp_reg.td[1];
rdp_reg.pc_i = 0;
rdp_reg.halt = 1;
rdp_reg.lights = 1;
rdp_reg.ambient_light = rdp_reg.lights;
rdp_reg.tile = 0;
rdp_reg.loadtile = 7;
rdp_reg.td[0].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[1].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[2].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[3].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[4].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[5].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[6].set_by = RDPTD_LOAD_NOT_SET;
rdp_reg.td[7].set_by = RDPTD_LOAD_NOT_SET;
Vtcnt = 0;
m_idx=0;
rdp_reg.perspnorm = 1.0f;
ucode_version = -1;
glMatrixMode(GL_PROJECTION);
//glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
//glPushMatrix();
glLoadIdentity();
Render_ClearVisual();
ModesUsedCnt = 0;
} /* void rdp_reset() */
static _u32 nextcmd;
static int rdpbusy = 0;
static int skipfram = 0;
_u32 lastVIorg = 0;
BOOL res = FALSE;
// prefixed with "Real" because we have "ExecuteDList" exported from
// driver.h and it wraps this function.
void RealExecuteDList(unsigned __int32 dwAddr)
{
_u32 a,ta;
int cnt = 0x1000;
int tcmd;
////glDrawBuffer(GL_AUX0);
fast_gfx_instruction = gfx_instruction[ucode_version];
rdp_reg.task = GFX_TASK;
rdp_reg.pc_i = 0;
rdp_reg.pc[rdp_reg.pc_i] = dwAddr;
rdp_reg.halt = 0;
//rdp_reg.m_CurTile = &rdp_reg.td[0];
//rdp_reg.tile = 0;
//rdp_reg.m_NexTile = &rdp_reg.td[1];
m_idx=0;
//CamSpyGo = TRUE;
CamSpyON = FALSE;
rdp_reg.perspnorm = 1.0f;
Draw2d = FALSE;
if (!res)
res = wglMakeCurrent(WinData.hDC, WinData.hGLRC);
// if (!res) WGL_Init();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
SwapNow = TRUE;
rdp_reg.mode_l |= 0x30;
glEnable(GL_DEPTH_TEST);
skipfram++;
#ifdef LOG_ON
LOG_TO_FILE("\n****************************************");
LOG_TO_FILE( "* NEW DLIST *");
LOG_TO_FILE( "* address: %08X *", dwAddr);
LOG_TO_FILE( "* DList-no: % 6i *", DList_C);
LOG_TO_FILE( "****************************************\n");
#endif
//Render_ResetViewPort();
if (TRUE)
// if (skipfram > 83)
// if ((skipfram & SKIPMASK) == 0)
// if (0)
{
if (swapMode == 0)
{
Render_FlushVisualRenderBuffer();
Render_ClearVisual();
CamSpyGo = TRUE;
}
do
{
// a = rdp_reg.pc[rdp_reg.pc_i];
a = rdp_reg.pc[rdp_reg.pc_i] & 0x007fffff;
ta = a >> 2;
//** load next commando
rdp_reg.cmd0 = ((_u32 *)pRDRAM)[ta + 0];
rdp_reg.cmd1 = ((_u32 *)pRDRAM)[ta + 1];
nextcmd = ((_u32 *)pRDRAM)[ta + 2];
rdp_reg.cmd2 = ((_u32 *)pRDRAM)[ta + 3];
rdp_reg.cmd3 = ((_u32 *)pRDRAM)[ta + 5];
//** point to next instruction
rdp_reg.curr = rdp_reg.pc[rdp_reg.pc_i] = (a + 8) & 0x007fffff;
//** execute next gfx-instruction
tcmd = (_u8)(rdp_reg.cmd0>>24);
switch (ucode_version)
{
case 0:
case 1:
case 2:
case 3:
case 5:
if (((Vtcnt > 0) && (tcmd != 0xb1) && (tcmd != 0xb5) && (tcmd != 0xbf)))
{
FlushVisualTriangle(Vtidx);
Vtcnt = 0;
}
break;
case 4:
if (((Vtcnt > 0) && (tcmd != 0x05) && (tcmd != 0x06) && (tcmd != 0x07)))
{
FlushVisualTriangle(Vtidx);
Vtcnt = 0;
}
break;
case 6:
case 7:
if (((Vtcnt > 0) && (tcmd != 0x05) && (tcmd != 0x06) && (tcmd != 0x07) && !(tcmd > 0x0f && tcmd < 0x20)))
{
FlushVisualTriangle(Vtidx);
Vtcnt = 0;
}
break;
}
fast_gfx_instruction[rdp_reg.cmd0>>24]();
} while(!rdp_reg.halt);
}
else //if (((rdp_reg.cmd0>>24) & 0x0ff) == 0xb8)
{
//gfx_instruction[ucode_version][rdp_reg.cmd0>>24]();
rdp_fullsync();
rdp_reg.halt = 1;
}
DList_C++;
} /* rdp_execute_dlist() */
/******************************************************************************\
* *
* HLE (High Level Emulation) - helper routine. *
* *
\******************************************************************************/
static _u32 segoffset2addr(_u32 so)
{
// return( (rdp_reg.segment[(so>>24)&0x0f] + (so&0x00ffffff)) & 0x007fffff );
_u32 seg = (so>>24)&0x0f;
if (rdp_reg.segment[seg] != 0xffffffff)
return((rdp_reg.segment[seg] + (so&0x00ffffff)) & 0x007fffff );
else
return((rdp_reg.segment[0] + (so&0x00ffffff)) & 0x007fffff );
} /* static _u32 segoffset2addr(_u32 so) */
static void rsp_reserved0()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RSP_RESERVED0 ", ADDR, CMD0, CMD1);
#endif
} /* static void rsp_reserved0() */
static void rsp_reserved1()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RSP_RESERVED1 \n", ADDR, CMD0, CMD1);
#endif
} /* static void rsp_reserved1() */
static void rsp_reserved2()
{
rdp_reg.ColorInfoAdd = segoffset2addr(rdp_reg.cmd1);
rdp_reg.ColorMode = (rdp_reg.geometrymode & 0x00020000)? TRUE : FALSE;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD SETCOLORINFOADD ", ADDR, CMD0, CMD1);
LOG_TO_FILE("\tColorInfoAdd = %08X", rdp_reg.ColorInfoAdd);
LOG_TO_FILE("\tColorMode = %08X\n", rdp_reg.ColorMode);
#endif
} /* static void rsp_reserved2() */
static void rsp_reserved3()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RSP_RESERVED3 \n", ADDR, CMD0, CMD1);
#endif
} /* static void rsp_reserved3() */
/******************************************************************************\
* *
* RDP (Reality Display Processor) - static routines (graphics and audio) *
* *
\******************************************************************************/
static void fixme()
{
// _u32 add = segoffset2addr(rdp_reg.cmd1);
// MessageBox(hGraphics, "Problem with UCode ...\ntry another one", "fixme", MB_OK);
/* sprintf(output,"uCode = %i\ncmd0 = %8x\ncmd1 = %8x\ncmd2 = %8x\ncmd3 = %8x\nadd = %8x",ucode_version,rdp_reg.cmd0,rdp_reg.cmd1,rdp_reg.cmd2,rdp_reg.cmd3,add);
MessageBox(hGraphics, output, "fixme", MB_OK);
*/
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD FIXME %08X\n", ADDR, CMD0, CMD1,rdp_reg.cmd0>>24);
#endif
} // static void fixme()
static void spnoop()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X SPNOOP\n", ADDR, CMD0, CMD1);
#endif
} /* static void spnoop() */
/******************************************************************************\
* *
* RDP (Reality Display Processor) emulation. *
* *
\******************************************************************************/
static void rdp_noop()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_NOOP\n",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_noop() */
static void rdp_texrect()
{
_u32 a = rdp_reg.pc[rdp_reg.pc_i];
_u32 cmd2 = ((_u32 *)pRDRAM)[(a>>2)+1];
_u32 cmd3 = ((_u32 *)pRDRAM)[(a>>2)+3];
_s16 lrx = (_u16)((rdp_reg.cmd0 & 0x00fff000) >> 12);
_s16 lry = (_u16)((rdp_reg.cmd0 & 0x00000fff) >> 0);
_s16 ulx = (_u16)((rdp_reg.cmd1 & 0x00fff000) >> 12);
_s16 uly = (_u16)((rdp_reg.cmd1 & 0x00000fff) >> 0);
float lrxf = lrx / 4.0f;
float lryf = lry / 4.0f;
float ulxf = ulx / 4.0f;
float ulyf = uly / 4.0f;
int tile = (_u16)((rdp_reg.cmd1 & 0x07000000) >> 24);
float s = ((float)(_s16)((rdp_reg.cmd2 >> 16) & 0xffff)) / 32.0f; // s10.5
float t = ((float)(_s16)((rdp_reg.cmd2 ) & 0xffff)) / 32.0f; // s10.5
float dsdx = ((float)((_s16)((rdp_reg.cmd3 >> 16) & 0xffff))) / 1024.0f; // s5.10
float dtdy = ((float)((_s16)((rdp_reg.cmd3 ) & 0xffff))) / 1024.0f; // s5.10
// sprintf(output,"cmd0 = %8x\ncmd1 = %8x\ncmd2 = %8x\ncmd3 = %8x",rdp_reg.cmd0,rdp_reg.cmd1,rdp_reg.cmd2,rdp_reg.cmd3);
// MessageBox(hGraphics, output, "textrect", MB_OK);
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TEXRECT",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tulx=%+9.4f; uly=%+9.4f; lrx=%+9.4f; lry=%+9.4f;\n\ttile=%u; s=%+9.4f; t=%+9.4f; dsdx=%+7.4f; dtdy=%+7.4f\n",
ulxf, ulyf, lrxf, lryf, tile, s, t, dsdx, dtdy);
#endif
rdp_reg.curr = rdp_reg.pc[rdp_reg.pc_i] = (a + 16) & 0x007fffff;
// rdp_reg.loadtile = tile;
// rdp_reg.m_CurTile = &rdp_reg.td[tile];
//rdp_reg.m_NexTile = &rdp_reg.td[(tile+1)&7];
// return;
/* gil: in this case i am correct! */
/* 1cyc mode (0x00000000): w = lrx - ulx */
/* 2cyc mode (0x00100000): w = lrx - ulx */
/* copy mode (0x00200000): w = lrx - ulx + 1 */
/* fill mode (0x00300000): not allowed */
if(cycle_mode == CYCLE_COPY)
{
/* we are in copy mode */
/* 4 texels are drawn per cycle */
// lry--;
dsdx /= 4.0;
}
else
{
/* we are in 1 or 2 cycle mode (fill mode is not allowed)! */
/* we must not draw the bottom and right edges */
lrx--;
lry--;
lrxf-=1.0f;
lryf-=1.0f;
}
if (CamSpyON)
Render_TexRectangleFastFB(ulxf, ulyf, lrxf, lryf, tile, s,t,dsdx, dtdy);
else
Render_TexRectangle(ulxf, ulyf, lrxf, lryf, tile, s,t,dsdx, dtdy);
} /* static void rdp_texrect() */
static void rdp_texrectflip()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TEXRECTFLIP",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_texrectflip() */
static void rdp_loadsync()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_LOADSYNC",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_loadsync() */
static void rdp_pipesync()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_PIPESYNC",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_pipesync() */
static void rdp_tilesync()
{
int i = 01;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TILESYNC",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_tilesync() */
static void rdp_fullsync()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_FULLSYNC\n",
ADDR, CMD0, CMD1);
#endif
*pInterruptMask = 0x20; //0x20 Lionel
} /* static void rdp_fullsync() */
static void rdp_setkeygb()
{
//_g->words.w0 = (_SHIFTL(G_SETKEYGB, 24, 8) | \
// _SHIFTL(wG, 12, 12) | _SHIFTL(wB, 0, 12)); \
//_g->words.w1 = (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | \
// _SHIFTL(cB, 8, 8) | _SHIFTL(sB, 0, 8));
float Green = (float)((CMD1 >> 24) & 0xff) / 256.0f;
float Blue = (float)((CMD1>> 8) & 0xff) / 256.0f;
rdp_reg.key_b = Blue;
rdp_reg.key_1mb = 1.0f - Blue;
rdp_reg.key_g = Green;
rdp_reg.key_1mg = 1.0f - Green;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETKEYG",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_setkeygb() */
static void rdp_setkeyr()
{
//_SHIFTL(G_SETKEYR, 24, 8), \
//_SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | _SHIFTL(sR, 0, 8) \
float Red = (float)((CMD0 >> 8) & 0xff) / 256.0f;
rdp_reg.key_r = Red;
rdp_reg.key_1mr = 1.0f - Red;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETKEYR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_setkeyr() */
static void rdp_setconvert()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETCONVERT",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tIgnored!\n");
#endif
} /* static void rdp_setconvert() */
static void rdp_setscissor()
{
static char *interlace_modes[] = { "no", "?", "even", "odd" };
rdp_reg.scissor.ulx = (rdp_reg.cmd0 & 0x00fff000) >> 14;
rdp_reg.scissor.uly = (rdp_reg.cmd0 & 0x00000fff) >> 2;
rdp_reg.scissor.interlace_mode = (rdp_reg.cmd1 & 0x03000000) >> 24;
rdp_reg.scissor.lrx = (rdp_reg.cmd1 & 0x00fff000) >> 14;
rdp_reg.scissor.lry = (rdp_reg.cmd1 & 0x00000fff) >> 2;
/* It seems that most demo coders thought that SETSCISSOR uses:
x, y, width, height
arguments. That is NOT correct. SETSCISSOR uses:
ulx, uly, lrx, lry
args!!! */
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETSCISSOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tulx=%lu; uly=%lu; lrx=%lu; lry=%lu; interlace_mode=%s\n",
rdp_reg.scissor.ulx,
rdp_reg.scissor.uly,
rdp_reg.scissor.lrx,
rdp_reg.scissor.lry,
interlace_modes[rdp_reg.scissor.interlace_mode]
);
// LOG_TO_FILE("interlace_mode is ignored\n");
#endif
SetVisualClipRectangle(rdp_reg.scissor.ulx, rdp_reg.scissor.uly, rdp_reg.scissor.lrx, rdp_reg.scissor.lry);
} /* static void rdp_setscissor() */
static void rdp_setprimdepth()
{
rdp_reg.primdepth = (CMD1 >> 16) & 0x7FFF;
rdp_reg.fprimdepth = (float)((CMD1 >> 16) & 0x7FFF) / (float)0x8000;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETPRIMDEPTH",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tPrimdeth = %2.6f!\n",rdp_reg.fprimdepth);
#endif
} /* static void rdp_setprimdepth() */
static void rdp_setothermode()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETOTHERMODE\n",
ADDR, CMD0, CMD1);
#endif
rdp_reg.mode_h = rdp_reg.cmd0 & 0x00ffffff;
rdp_reg.mode_l = rdp_reg.cmd1 & 0xffffffff;
cycle_mode = (_u8)((rdp_reg.mode_h>>0x14) & 0x3);//^3;
if ((rdp_reg.mode_l & 0x0c00) != 0xc00) glDepthRange(-1,1.);
else glDepthRange(-1,0.9995);
if(rdp_reg.mode_l & 0x00000010)
Render_geometry_zbuffer(1);
else
Render_geometry_zbuffer(0);
if (rdp_reg.mode_l & 0x00000020)
Render_geometry_zwrite(1);
else
Render_geometry_zwrite(0);
/*
// if ((rdp_reg.mode_l & 0x0f0f0000) != 0x50000)
if ((rdp_reg.mode_l & 0x0f000000) != 0x0)
{
Src_Alpha = GL_SRC_ALPHA;
Dst_Alpha = GL_ONE_MINUS_SRC_ALPHA;
}
else
{
// Src_Alpha = GL_ONE;
// Dst_Alpha = GL_ZERO;
}
*/
} /* static void rdp_setothermode() */
_u32 lTmem;
_u16 lPallete[256];
_u16 *lPallete16[16] = {&lPallete[0x00],&lPallete[0x10],&lPallete[0x20],&lPallete[0x30],
&lPallete[0x40],&lPallete[0x50],&lPallete[0x60],&lPallete[0x70],
&lPallete[0x80],&lPallete[0x90],&lPallete[0xa0],&lPallete[0xb0],
&lPallete[0xc0],&lPallete[0xd0],&lPallete[0xe0],&lPallete[0xf0]};
BOOL loadPalAddr = TRUE;
void UpdatePalette()
{
int i,pal;
_u16 *spal = (_u16 *)((_u8 *)pRDRAM + (rdp_reg.tlut_8_addr));
_u32 color;
_u8 intensity;
_u8 *dia = (_u8 *)(&Palette8IA[0]);
_u8 *drgba = (_u8 *)(&Palette8RGBA[0]);
for (i=0; i<17; i++)
{
PaletteCRC[i] = 0;
}
for (i=0; i<256; i++)
{
pal = i >> 4;
PaletteCRC[16] = PaletteCRC[16] << 11 | PaletteCRC[16] >> 21;
PaletteCRC[16] += ((_u32)lPallete[i])<<pal;// * (i + 1));
PaletteCRC[16] = PaletteCRC[16] << (15 + (i & 15)) | PaletteCRC[16] >> (17 - (i & 15));
PaletteCRC[16] ^= ((_u32)lPallete[i])<<(16-pal);// * (i + 1));
PaletteCRC[pal] = (PaletteCRC[pal] << (5+(i & 15))) | (PaletteCRC[pal] >> (27-(i & 15)));
PaletteCRC[pal] += ((_u32)(lPallete[i]))<<pal;// * ((i & 0xf) + 1));
PaletteCRC[pal] = (PaletteCRC[pal] << (21-(i & 15))) | (PaletteCRC[pal] >> (11+(i & 15)));
PaletteCRC[pal] ^= ((_u32)lPallete[i])<<(16-pal);// * ((i & 0xf) + 1));
}
for (i=0; i<17; i++)
{
InvPaletteCRC[i] = ~PaletteCRC[i];
}
spal = lPallete;
for (i=0; i<256; i++)
{
color = lPallete[i];//*spal++;
intensity = (_u8)((color >> 8 ) & 0x00ff);
*drgba++ = (_u8)(((color >> 11 ) & 0x001f)<<3);
*drgba++ = (_u8)(((color >> 6 ) & 0x001f)<<3);
*drgba++ = (_u8)(((color >> 1 ) & 0x001f)<<3);
*drgba++ = (color & 0x01) ? 0xff : 0x00;
*dia++ = intensity;
*dia++ = intensity;
*dia++ = intensity;
*dia++ = (_u8)(color & 0xff);
}
}
static void rdp_loadtlut()
{
_u32 tile = (rdp_reg.cmd1 >> 24) & 0x07;
_u16 count = ((_u16)(rdp_reg.cmd1 >> 14) & 0x03ff)+1;
_u16 pltofst = ((_u16)(rdp_reg.cmd1 >> 14) & 0x03);
_u16 pltstart = ((_u16)(rdp_reg.cmd1 >> 2) & 0x03ff)+1;
t_tile *tmpTile = &rdp_reg.td[tile];
_u16 x0 = (_u16)(((rdp_reg.cmd0 >> 14)) & 0x03ff);
_u16 y0 = (_u16)(((rdp_reg.cmd0 >> 2 )) & 0x03ff);
_u16 x1 = (_u16)(((rdp_reg.cmd1 >> 14)) & 0x03ff);
_u16 y1 = (_u16)(((rdp_reg.cmd1 >> 2 )) & 0x03ff);
rdp_reg.tlut_8_fmt = rdp_reg.TextureImage.fmt;
rdp_reg.tlut_8_size = rdp_reg.TextureImage.size;
rdp_reg.tlut_8_addr = (_u32)((rdp_reg.TextureImage.addr));// + (tmpTile->ult * 2));
lTmem = tmpTile->tmem;
if (lTmem < 0x100)
lTmem = 0x100;
{
int i;
int idx;
int pal = (lTmem >> 4) & 0xf; //rdp_reg.td[tile].tmem >> 4 & 0xf;
_u16 *spal;
if (count > 256)
count /= 4;
if(pltstart!=0)
{
spal = (_u16 *)((_u8 *)pRDRAM + (rdp_reg.tlut_8_addr + (2*x0+2*y0)));
count=(x1-x0)+1;
if(count>256) count=256;
}
if (loadPalAddr)
{
for (i=0; i<16; i++) lPallete16[i] = &lPallete[i<<4];
loadPalAddr=FALSE;
}
if ((count + (pal << 4))>256) count = 256 - (pal << 4);
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_LOADTLUT",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\ttile=%ld (tmem=%lx),(pal=%i)\n\tLoad address = %08x, count=%hx\n",
tile,
rdp_reg.td[tile].tmem,
(rdp_reg.td[tile].tmem >> 4) & 0x0f,
rdp_reg.tlut_8_addr,
count
);
#endif
pal = rdp_reg.td[tile].tmem & 0xf0;
for (idx = 0; idx < count;idx++)
{
lPallete[(pal + idx) & 0x0ff] = *spal++;
}
UpdatePalette();
}
rdp_reg.tlut_4_fmt[rdp_reg.td[tile].palette] = rdp_reg.TextureImage.fmt;
rdp_reg.tlut_4_size[rdp_reg.td[tile].palette] = rdp_reg.TextureImage.size;
rdp_reg.tlut_4_addr[rdp_reg.td[tile].palette] = (_u32)rdp_reg.TextureImage.addr;
} /* static void rdp_loadtlut() */
static void rdp_settilesize()
{
_u32 tile = (rdp_reg.cmd1 >> 24) & 0x07;
_u32 oldtile = rdp_reg.tile;
t_tile *savCurTile = rdp_reg.m_CurTile;
int twidth, theight;
t_tile *tmpTile = &(rdp_reg.td[tile]);
if (tile == 7)
tile += 0;
rdp_reg.m_CurTile = tmpTile;
rdp_reg.tile = tile;
tmpTile->uls = ((_u16)(rdp_reg.cmd0 >> 12)) & 0x0fff;
tmpTile->ult = ((_u16)( rdp_reg.cmd0 )) & 0x0fff;
tmpTile->lrs = ((_u16)(rdp_reg.cmd1 >> 12)) & 0x0fff;
tmpTile->lrt = ((_u16)( rdp_reg.cmd1 )) & 0x0fff;
tmpTile->uls = (tmpTile->uls >> 2);
tmpTile->ult = (tmpTile->ult >> 2);
tmpTile->lrs = ((tmpTile->lrs) >> 2);
tmpTile->lrt = ((tmpTile->lrt) >> 2);
twidth = tmpTile->lrs - tmpTile->uls + 1;
tmpTile->Width = twidth;
if ((tmpTile->masks) && (tmpTile->masks < MAXSMASK))
{
tmpTile->Width = 1<<tmpTile->masks;
// if ((twidth > tmpTile->Width) || tmpTile->mirrors) tmpTile->clamps = 0;
if (twidth > (int)tmpTile->Width) tmpTile->clamps = 0;
}
theight = tmpTile->lrt - tmpTile->ult + 1;
tmpTile->Height = theight;
if ((tmpTile->maskt) && ((tmpTile->maskt < MAXTMASK)))
{
tmpTile->Height = 1<<tmpTile->maskt;
// if ((theight > tmpTile->Height) || tmpTile->mirrort) tmpTile->clampt = 0;
if (theight > (int)tmpTile->Height) tmpTile->clampt = 0;
}
if (tmpTile->maskt == 0) tmpTile->clampt = 1;
if (tmpTile->clampt) tmpTile->mirrort = 0;
// if (tmpTile->maskt == 0) tmpTile->mirrort = 0;
if (tmpTile->masks == 0) tmpTile->clamps = 1;
if (tmpTile->clamps) tmpTile->mirrors = 0;
// if (tmpTile->masks == 0) tmpTile->mirrors = 0;
//** Math the Texture-Coordinate Scalefactors ...
MathTextureScales();
rdp_reg.tile = oldtile;
rdp_reg.m_CurTile = savCurTile;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETTILESIZE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tuls=%hu; ult=%hu; lrs=%hu; lrt=%hu; tile=%lu\n",
rdp_reg.td[tile].uls, rdp_reg.td[tile].ult,
rdp_reg.td[tile].lrs, rdp_reg.td[tile].lrt,
tile);
#endif
} /* static void rdp_settilesize() */
static void rdp_loadblock()
{
_u32 offset = 0;
_u32 size = (1 << rdp_reg.TextureImage.size)/2;
_u32 width = rdp_reg.TextureImage.width;
_u32 Length = ((_u32)((rdp_reg.cmd1 >> 12) & 0xFFF) + 1);
_u16 LineWidth;
_u32 tile = (_u32)((rdp_reg.cmd1 >> 24) & 0x07);
_u16 dxt = (_u16)(rdp_reg.cmd1 & 0x0fff);
t_tile *tmpTile = &(rdp_reg.td[tile]);
// int i;
/*
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
(((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\
#define G_IM_SIZ_4b_SHIFT 2
#define G_IM_SIZ_8b_SHIFT 1
#define G_IM_SIZ_16b_SHIFT 0
#define G_IM_SIZ_32b_SHIFT 0
#define G_IM_SIZ_4b_INCR 3
#define G_IM_SIZ_8b_INCR 1
#define G_IM_SIZ_16b_INCR 0
#define G_IM_SIZ_32b_INCR 0
*/
switch(size)
{
case 0:
case 1:
case 2:
break;
case 4:
Length <<= 1; // ????? not sure about this
}
Length >>= 2; // convert to 64bit words
Length++;
if (size == 0)
size = 1;
tmpTile->reload = TRUE;
tmpTile->set_by = RDPTD_LOADBLOCK;
tmpTile->addr = (_u32)&pRDRAM[rdp_reg.TextureImage.addr];
if (dxt)
dxt = (_u16)((2048.0f / (float)(dxt))+0.5f);
else
dxt = 0;
tmpTile->dxt = dxt;
if (tmpTile->uls != 0)
size += 0;
tmpTile->offset = offset;
if (width<=1)
LineWidth=dxt * 8;
else
{
LineWidth = (_u16)width;
switch (rdp_reg.TextureImage.size)
{
case 0:
break;
case 1:
break;
case 2:
LineWidth <<= 1;
break;
case 3:
LineWidth <<= 2;
break;
}
}
offset = 0;
if(tmpTile->tmem == 0x160)
tmpTile->tmem = 0x160;
{
LstLdAddr[LstLdAddNum].Addr = rdp_reg.TextureImage.addr + offset;
LstLdAddr[LstLdAddNum].Offset = tmpTile->tmem;
LstLdAddr[LstLdAddNum].End = tmpTile->tmem + Length;
LstLdAddr[LstLdAddNum].LoadedBy = 0;
LstLdAddr[LstLdAddNum].Pitch = 0;
LstLdAddr[LstLdAddNum].LineWidth = LineWidth;
if ((_u16)(rdp_reg.cmd1 & 0x0fff) == 0)
LstLdAddr[LstLdAddNum].Swapped=1;// | ((tmpTile->ult & 1) << 1);
else
LstLdAddr[LstLdAddNum].Swapped=0;
LstLdAddr[LstLdAddNum].StepAdj=0;
LstLdAddNum++;
LstLdAddNum &= LstLdAddrMask;
}
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_LOADBLOCK",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tuls=%x; ult=%x; lrs=%x; dxt=%x;\n\ttile=%x (->tmem=0x%x); loadaddr = 0x%08x; length=0x%x\n",
rdp_reg.td[tile].uls, rdp_reg.td[tile].ult,
rdp_reg.td[tile].lrs, rdp_reg.td[tile].dxt,
tile,rdp_reg.td[tile].tmem,(rdp_reg.TextureImage.addr + offset),Length);
#endif
lTmem = tmpTile->tmem;
if (lTmem < 0x100) return;
{
_u16 count = ((_u16)(rdp_reg.cmd1 >> 14) & 0x03ff);
int i;
int idx;
int pal = (lTmem >> 4) & 0xf; //rdp_reg.td[tile].tmem >> 4 & 0xf;
_u16 *spal = (_u16 *)((_u8 *)pRDRAM + (rdp_reg.tlut_8_addr));
// _u32 color;
// _u8 intensity;
_u8 *dia = (_u8 *)(&Palette8IA[0]);
_u8 *drgba = (_u8 *)(&Palette8RGBA[0]);
_u16 pltstart = ((_u16)(rdp_reg.cmd1 >> 2) & 0x03ff)+1;
_u16 uls = (_u16)(((rdp_reg.cmd0 >> 14)) & 0x03ff);
_u16 ult = (_u16)(((rdp_reg.cmd0 >> 2 )) & 0x03ff);
_u16 lrs = (_u16)(((rdp_reg.cmd1 >> 14)) & 0x03ff);
_u16 lrt = (_u16)(((rdp_reg.cmd1 >> 2 )) & 0x03ff);
rdp_reg.tlut_8_addr = (_u32)(rdp_reg.TextureImage.addr);
if (loadPalAddr)
{
for (i=0; i<16; i++)
lPallete16[i] = &lPallete[i<<4];
loadPalAddr=FALSE;
}
if(pltstart!=0)
{
spal = (_u16 *)((_u8 *)pRDRAM + (rdp_reg.tlut_8_addr + (2*uls+2*ult)));
count=(lrs-uls)+1;
if(count>256) count=256;
}
pal <<= 4;
if ((count + pal) > 256) count = 256 - pal;
for (idx = 0; idx < count;idx++)
{
lPallete[(pal+idx) & 0x0ff] = *spal++;
}
UpdatePalette();
}
} /* static void rdp_loadblock() */
static void rdp_loadtile()
{
_u32 offset;
_u32 size = (1 << rdp_reg.TextureImage.size)/2;
_u32 width = rdp_reg.TextureImage.width;
_u16 LineWidth;
_u32 tile = (_u32)((rdp_reg.cmd1 >> 24) & 0x07);
t_tile *tmpTile = &(rdp_reg.td[tile]);
_u16 uls = (_u16)(((rdp_reg.cmd0 >> 12)) & 0x0fff);
_u16 ult = (_u16)(((rdp_reg.cmd0 )) & 0x0fff);
_u16 lrs = (_u16)(((rdp_reg.cmd1 >> 12)) & 0x0fff);
_u16 lrt = (_u16)(((rdp_reg.cmd1 )) & 0x0fff);
_u32 Width = lrs - uls + 4;
_u32 Height = lrt - ult + 4;
_u32 Length;
uls = (uls >> 2);
ult = (ult >> 2);
lrs = ((lrs) >> 2);
lrt = ((lrt) >> 2);
Width >>= 2;
Height >>= 2;
Length = Width * Height;
// if (width < 0) width = - width;
// if (size == 0)
// size = 1;
tmpTile->reload = TRUE;
tmpTile->set_by = RDPTD_LOADTILE;
tmpTile->addr = (_u32)&pRDRAM[rdp_reg.TextureImage.addr];//(_u32)rdp_reg.TextureImage.addr;
rdp_reg.loadtile = tile;
if (width<=1)
LineWidth=(_u16)Width;
else
LineWidth=(_u16)width;
switch (rdp_reg.TextureImage.size)
{
case 0:
Length >>= 4;
size = 1;
break;
case 1:
Length >>= 3;
size = 2;
break;
case 2:
Length >>= 2;
LineWidth <<= 1;
size = 4;
break;
case 3:
Length >>= 1;
LineWidth <<= 2;
size = 8;
break;
}
if (width <= 1)
{
if (size > 1)
width = Width;// >> 1;
else
width = Width;// >> 1;
}
offset = (uls + (ult * width)) * size;
offset >>= 1;
tmpTile->addr = rdp_reg.TextureImage.addr;
tmpTile->offset = offset;
offset += rdp_reg.TextureImage.addr;
Length++;
LstLdAddr[LstLdAddNum].Addr=offset;
LstLdAddr[LstLdAddNum].Offset=tmpTile->tmem;
LstLdAddr[LstLdAddNum].End = tmpTile->tmem + Length;
LstLdAddr[LstLdAddNum].Pitch=width;
LstLdAddr[LstLdAddNum].LineWidth=LineWidth;
LstLdAddr[LstLdAddNum].Swapped=0;
LstLdAddr[LstLdAddNum].StepAdj=(_u16)(tmpTile->uls * size) &0x03;
LstLdAddr[LstLdAddNum].LoadedBy = 1;
LstLdAddNum++;
LstLdAddNum&=LstLdAddrMask;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_LOADTILE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tuls=%lu, ult=%lu, lrs=%lu, lrt=%lu, tile=%lu\n\tlength = 0x%x",
tmpTile->uls, tmpTile->ult,
tmpTile->lrs, tmpTile->lrt,
tile, Length);
#endif
} /* static void rdp_loadtile() */
static void rdp_settile()
{
_u32 oldtile = rdp_reg.tile;
_u32 tile = (_u32)((rdp_reg.cmd1 >> 24) & 0x07);
t_tile *tmpTile = &(rdp_reg.td[tile]);
t_tile *savCurTile = rdp_reg.m_CurTile;
tmpTile->format = (_u8) ((rdp_reg.cmd0 >> 21) & 0x07);
tmpTile->size = (_u8) ((rdp_reg.cmd0 >> 19) & 0x03);
tmpTile->line = (_u16)((rdp_reg.cmd0 >> 9) & 0x01ff) * 8;
tmpTile->tmem = (_u16)( rdp_reg.cmd0 & 0x01ff);
tmpTile->palette = (_u8) ((rdp_reg.cmd1 >> 20) & 0x0f);
tmpTile->clampt = (_u8) ((rdp_reg.cmd1 >> 19) & 0x01);
tmpTile->mirrort = (_u8) ((rdp_reg.cmd1 >> 18) & 0x01);
tmpTile->maskt = (_u8) ((rdp_reg.cmd1 >> 14) & 0x0f);
tmpTile->shiftt = (_u8) ((rdp_reg.cmd1 >> 10) & 0x0f);
tmpTile->clamps = (_u8) ((rdp_reg.cmd1 >> 9) & 0x01);
tmpTile->mirrors = (_u8) ((rdp_reg.cmd1 >> 8) & 0x01);
tmpTile->masks = (_u8) ((rdp_reg.cmd1 >> 4) & 0x0f);
tmpTile->shifts = (_u8) ( rdp_reg.cmd1 & 0x0f);
tmpTile->addr = (_u32)&pRDRAM[rdp_reg.TextureImage.addr];
lTmem = tmpTile->tmem;
if(tmpTile->tmem == 0x160)
tmpTile->tmem = 0x160;
pltmode = (rdp_reg.mode_h & 0x0000c000);
//** setup line from "64bit pixel" to correct 32, 16, 8 or 4bit pixel
// switch(rdp_reg.td[tile].size)
// switch(rdp_reg.TextureImage.size)
switch(rdp_reg.td[tile].size)
{
case 0: //** 4bit
// rdp_reg.td[tile].line <<= 4;
break;
case 1: //** 8bit
// rdp_reg.td[tile].line <<= 3;
break;
case 2: //** 16bit
// rdp_reg.td[tile].line <<= 2;
break;
case 3: //** 32bit
// rdp_reg.td[tile].line <<= 2;//1;
rdp_reg.td[tile].line <<= 1;
break;
}
if (tile == 7)
tile += 0;
rdp_reg.tile = tile;
rdp_reg.m_CurTile = tmpTile;
/*
if(tile!=7)
{
DWORD last=LstLdAddNum;
if(last) last--;
else last=7;
if(LstLdAddr[last].Offset != tmpTile->tmem)
{
tmpTile->reload = TRUE;
LstLdAddr[LstLdAddNum].Pitch=0;
LstLdAddr[LstLdAddNum].LineWidth=LstLdAddr[last].LineWidth;
LstLdAddr[LstLdAddNum].Swapped=LstLdAddr[last].Swapped;
LstLdAddr[LstLdAddNum].Addr=LstLdAddr[last].Addr;
LstLdAddr[LstLdAddNum].Offset=tmpTile->tmem;
LstLdAddNum++;
LstLdAddNum&=7;
}
}
static char *format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" };
static char *size[] = { "4bit", "8bit", "16bit", "32bit" };
static char *cm[] = { "NOMIRROR/WARP(NOCLAMP)", "MIRROR", "CLAMP", "MIRROR&CLAMP" };
*/
MathTextureScales();
rdp_reg.m_CurTile = savCurTile;
rdp_reg.tile = oldtile;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETTILE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\ttile = %i, format = %s, size = %s, line = %i, tmem = 0x%x, palette = %i",
tile,format[tmpTile->format], size[tmpTile->size],
tmpTile->line, tmpTile->tmem, tmpTile->palette);
LOG_TO_FILE("\tclamps = %3i, mirrors = %3i, masks = %3i, shifs = %3i",
tmpTile->clamps, tmpTile->mirrors, tmpTile->masks, tmpTile->shifts);
LOG_TO_FILE("\tclampt = %3i, mirrort = %3i, maskt = %3i, shift = %3i\n",
tmpTile->clampt, tmpTile->mirrort, tmpTile->maskt, tmpTile->shiftt);
#endif
} /* static void rdp_settile() */
static void rdp_fillrect()
{
_u32 ulx, uly, lrx, lry;
_u32 color;
lrx = (rdp_reg.cmd0 & 0x00fff000) >> 12;
lry = (rdp_reg.cmd0 & 0x00000fff) >> 0;
ulx = (rdp_reg.cmd1 & 0x00fff000) >> 12;
uly = (rdp_reg.cmd1 & 0x00000fff) >> 0;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_FILLRECT",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tulx=%lu; uly=%lu; lrx=%lu; lry=%lu",
ulx/4,
uly/4,
lrx/4,
lry/4);
LOG_TO_FILE("\tmodes are ignored\n");
#endif
/* modes: copy mode is not used (not allowed?) */
if(!(rdp_reg.mode_h & 0x00200000))
{
/* if we are not in 1 or 2 cycle mode (not in copy or fill mode) */
/* we must not draw the bottom and right edges */
//lrx--;
//lry--;
color = rdp_reg.blendcolor;
}
else
{
color = rdp_reg.fillcolor;
}
SetVisualColor(rdp_reg.fillcolor);
Render_FillRectangle(ulx, uly, lrx, lry, color);
} /* static void rdp_fillrect() */
static void rdp_setfillcolor()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETFILLCOLOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tcolor=$%08lx\n", rdp_reg.cmd1);
#endif
rdp_reg.fillcolor = rdp_reg.cmd1;
rdp_reg.fill_r = ((float)((rdp_reg.fillcolor >> 11) & 0x1f) / 31.0f);
rdp_reg.fill_g = ((float)((rdp_reg.fillcolor >> 6) & 0x1f) / 31.0f);
rdp_reg.fill_b = ((float)((rdp_reg.fillcolor >> 1) & 0x1f) / 31.0f);
rdp_reg.fill_a = (float)(rdp_reg.fillcolor & 0x1);
rdp_reg.fill_1mr = 1.0f - rdp_reg.fill_r;
rdp_reg.fill_1mg = 1.0f - rdp_reg.fill_g;
rdp_reg.fill_1mb = 1.0f - rdp_reg.fill_b;
rdp_reg.fill_1ma = 1.0f - rdp_reg.fill_a;
} /* static void rdp_setfillcolor() */
static void rdp_setfogcolor()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETFOGCOLOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tcolor=$%08lx\n", rdp_reg.cmd1);
#endif
rdp_reg.fogcolor = rdp_reg.cmd1;
rdp_reg.fog_r = (((rdp_reg.fogcolor >> 24) & 0xff) / 255.0f);
rdp_reg.fog_g = (((rdp_reg.fogcolor >> 16) & 0xff) / 255.0f);
rdp_reg.fog_b = (((rdp_reg.fogcolor >> 8) & 0xff) / 255.0f);
rdp_reg.fog_a = (rdp_reg.fogcolor & 0xff) / 255.0f;
rdp_reg.fog_1mr = 1.0f - rdp_reg.fog_r;
rdp_reg.fog_1mg = 1.0f - rdp_reg.fog_g;
rdp_reg.fog_1mb = 1.0f - rdp_reg.fog_b;
rdp_reg.fog_1ma = 1.0f - rdp_reg.fog_a;
} /* static void rdp_setfogcolor() */
static void rdp_setblendcolor()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETBLENDCOLOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tcolor=$%08lx\n", rdp_reg.cmd1);
#endif
rdp_reg.blendcolor = rdp_reg.cmd1;
rdp_reg.blend_r = (((rdp_reg.blendcolor >> 24) & 0xff) / 255.0f);
rdp_reg.blend_g = (((rdp_reg.blendcolor >> 16) & 0xff) / 255.0f);
rdp_reg.blend_b = (((rdp_reg.blendcolor >> 8) & 0xff) / 255.0f);
rdp_reg.blend_a = (rdp_reg.blendcolor & 0xff) / 255.0f;
rdp_reg.blend_1mr = 1.0f - rdp_reg.blend_r;
rdp_reg.blend_1mg = 1.0f - rdp_reg.blend_g;
rdp_reg.blend_1mb = 1.0f - rdp_reg.blend_b;
rdp_reg.blend_1ma = 1.0f - rdp_reg.blend_a;
} /* static void rdp_setblendcolor() */
static void rdp_setprimcolor()
{
_u8 L = CMD0 & 0xff;
_u8 M = (CMD0 >> 8) & 0xff;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETPRIMCOLOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tcolor=$%08lx", CMD1);
LOG_TO_FILE("\tM = $%02x; L = $%02x\n", M,L);
#endif
rdp_reg.primcolor = rdp_reg.cmd1;
rdp_reg.prim_r = (((rdp_reg.primcolor >> 24) & 0xff) / 255.0f);
rdp_reg.prim_g = (((rdp_reg.primcolor >> 16) & 0xff) / 255.0f);
rdp_reg.prim_b = (((rdp_reg.primcolor >> 8) & 0xff) / 255.0f);
rdp_reg.prim_a = (rdp_reg.primcolor & 0xff) / 255.0f;
rdp_reg.prim_1mr = 1.0f - rdp_reg.prim_r;
rdp_reg.prim_1mg = 1.0f - rdp_reg.prim_g;
rdp_reg.prim_1mb = 1.0f - rdp_reg.prim_b;
rdp_reg.prim_1ma = 1.0f - rdp_reg.prim_a;
//UpdateTexRectClrs1 |= UsePrimAll;
//UpdateTexRectClrs2 |= UsePrimAll;
//UpdateTrisClrs1 |= UsePrimAll;
//UpdateTrisClrs2 |= UsePrimAll;
} /* static void rdp_setprimcolor() */
static void rdp_setenvcolor()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETENVCOLOR",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tcolor=$%08lx\n", rdp_reg.cmd1);
#endif
rdp_reg.envcolor = rdp_reg.cmd1;
rdp_reg.env_r = (((rdp_reg.envcolor >> 24) & 0xff) / 255.0f);
rdp_reg.env_g = (((rdp_reg.envcolor >> 16) & 0xff) / 255.0f);
rdp_reg.env_b = (((rdp_reg.envcolor >> 8) & 0xff) / 255.0f);
rdp_reg.env_a = (rdp_reg.envcolor & 0xff) / 255.0f;
rdp_reg.env_1mr = 1.0f - rdp_reg.env_r;
rdp_reg.env_1mg = 1.0f - rdp_reg.env_g;
rdp_reg.env_1mb = 1.0f - rdp_reg.env_b;
rdp_reg.env_1ma = 1.0f - rdp_reg.env_a;
//UpdateTexRectClrs1 |= UseEnvAll;
//UpdateTexRectClrs2 |= UseEnvAll;
//UpdateTrisClrs1 |= UseEnvAll;
//UpdateTrisClrs2 |= UseEnvAll;
} /* static void rdp_setenvcolor() */
static void rdp_settextureimage()
{
static char *format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" };
static char *size[] = { "4bit", "8bit", "16bit", "32bit" };
rdp_reg.TextureImage.fmt = (_u8)((rdp_reg.cmd0 >> 21) & 0x07);
rdp_reg.TextureImage.size = (_u8)((rdp_reg.cmd0 >> 19) & 0x03);
rdp_reg.TextureImage.width = (_u16)(1 + (rdp_reg.cmd0 & 0x00000fff));
rdp_reg.TextureImage.addr = segoffset2addr(rdp_reg.cmd1);
rdp_reg.TextureImage.vaddr = rdp_reg.cmd0;
// if (ADDR == 0x0041C810) rdp_reg.pc[rdp_reg.pc_i] = 0x0041F7F8;
CamSpyON = FALSE;
if (ucode_version == 5)
{
_s32 offset = rdp_reg.TextureImage.addr - rdp_reg.colorimg_addr;
// _u32 a,ta;
int cnt = 0;
// a = (rdp_reg.pc[rdp_reg.pc_i]+0x40) & 0x007fffff;
// ta = a >> 2;
CamSpyON = FALSE;
if ((offset > 0) && (offset <= 320*240*2))
{
if (CamSpyGo)
Render_FrameBuffer5(); // copy frame buffer we do this 1 time per dlist
CamSpyGo = FALSE;
CamSpyON = TRUE;
/* while((((_u32 *)pRDRAM)[ta + 0] != 0xFD10013F) && (cnt++ < 5))
{
a += 8;
a &= 0x007fffff;
ta = a >> 2;
}
while((((_u32 *)pRDRAM)[ta + 0] == 0xFD10013F))// || (((_u32 *)pRDRAM)[ta + 0] != 0x00000000))
{
a += 48;
a &= 0x007fffff;
ta = a >> 2;
}
rdp_reg.pc[rdp_reg.pc_i] = a - 8; // skip camspy lens code
// rdp_reg.pc[rdp_reg.pc_i] += 0x0041F7E0 - 0x0041C810; // skip camspy lens code
*/
}
}
// rdp_reg.TextureImage.LoadAddr = &pRDRAM[rdp_reg.TextureImage.addr];
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETTEXTUREIMAGE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tformat=%s; size=%s; width=%hu; addr=$%08lx\n",
format[rdp_reg.TextureImage.fmt],
size[rdp_reg.TextureImage.size],
rdp_reg.TextureImage.width,
rdp_reg.TextureImage.addr);
#endif
} /* static void rdp_settextureimage() */
static void rdp_setdepthimage()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETDEPTHIMAGE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\taddr=$%lx\n", rdp_reg.cmd1);
#endif
rdp_reg.depthimg_addr = segoffset2addr(rdp_reg.cmd1);
} /* static void rdp_setdepthimage() */
_u32 LastColorAdd = 0;
_u32 NewColorAdd = 0;
static void rdp_setcolorimage()
{
static char *format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" };
static char *size[] = { "4bit", "8bit", "16bit", "32bit" };
//rdp_reg.colorimg_addr = segoffset2addr(rdp_reg.cmd1);
NewColorAdd = segoffset2addr(rdp_reg.cmd1);
if ((swapMode == 0) && (NewColorAdd == rdp_reg.depthimg_addr))
{
swapmodecnt--;
if (swapmodecnt == 0) swapMode = 1;
// SwapNow = TRUE;
}
/**/
if ((swapMode == 1)
&& (NewColorAdd != rdp_reg.depthimg_addr)
&& (NewColorAdd != LastColorAdd)
// && (SwapNow)
)
{
rdp_reg.colorimg_addr = LastColorAdd;
// if (SwapNow)
Render_FrameBuffer();
if (SwapNow)
{
Render_FlushVisualRenderBuffer();
Render_ClearVisual();
SwapNow = FALSE;
CamSpyGo = TRUE;
}
LastColorAdd = NewColorAdd;
}
/*
if ((swapMode == 1)
&& (NewColorAdd != rdp_reg.depthimg_addr))
{
LastColorAdd = NewColorAdd;
}
/**/
rdp_reg.colorimg_fmt = (_u8)((rdp_reg.cmd0 & 0x00e00000) >> 21);
rdp_reg.colorimg_size = (_u8)((rdp_reg.cmd0 & 0x00180000) >> 19);
rdp_reg.colorimg_width = (_u16)((rdp_reg.cmd0 & 0x00000fff)+1);
rdp_reg.colorimg_addr = NewColorAdd;
rdp_reg.colorimg_addr2 = ~NewColorAdd;
imgWidth = rdp_reg.colorimg_width;
imgHeight = (imgWidth / 4.0f) * 3.0f;
//if(vi_Hires)
// imgHeight *= 2;
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_SETCOLORIMAGE",
ADDR, CMD0, CMD1);
LOG_TO_FILE("\tformat=%s; size=%s; width=%hu; addr=$%lx\n",
format[rdp_reg.colorimg_fmt],
size[rdp_reg.colorimg_size],
rdp_reg.colorimg_width,
rdp_reg.colorimg_addr);
#endif
} /* static void rdp_setcolorimage() */
static void rdp_trifill()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRIFILL",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trifill() */
static void rdp_trishade()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRISHADE",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trishade() */
static void rdp_tritxtr()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRITXTR",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_tritxtr() */
static void rdp_trishadetxtr()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRISHADETXTR",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trishadetxtr() */
static void rdp_trifillz()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRIFILLZ",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trifillz() */
static void rdp_trishadez()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRISHADEZ",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trishadez() */
static void rdp_tritxtrz()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRITXTRZ",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_tritxtrz() */
static void rdp_trishadetxtrz()
{
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD RDP_TRISHADETXTRZ",
ADDR, CMD0, CMD1);
#endif
} /* static void rdp_trishadetxtrz() */
static void rsp_texture()
{
int idx;
int tile = (rdp_reg.cmd0 >> 8) & 0x07; //** tile t0
int tile1 = (tile + 1) & 0x07; //** tile t1
_u32 mipmap_level = (rdp_reg.cmd0 >> 11) & 0x07; //** mipmap_level - not used yet
_u32 on = (rdp_reg.cmd0 & 0xff); //** 1: on - 0:off
float s = (float)((rdp_reg.cmd1 >> 16) & 0xffff);
float t = (float)((rdp_reg.cmd1 ) & 0xffff);
float SScale;
float TScale;
t_tile *tmp_tile = &rdp_reg.td[tile];
t_tile *tmp_tile1 = &rdp_reg.td[tile1];
tmp_tile->Texture_on = (_u8)on;
rdp_reg.tile = tile;
if (s<=1)
SScale=1.0f;
else
SScale=(float)s/65535.f;
if (t<=1)
TScale=1.0f;
else
TScale=(float)t/65535.f;
TScale/=32.f;
SScale/=32.f;
for (idx=0;idx<8;idx++)
{
rdp_reg.tile = idx;
tmp_tile1 = &rdp_reg.td[idx];
tmp_tile1->SScale=SScale;
tmp_tile1->TScale=TScale;
rdp_reg.m_CurTile = tmp_tile1;
MathTextureScales();
}
rdp_reg.tile = tile;
rdp_reg.m_CurTile = tmp_tile;
// MathTextureScales();
#ifdef LOG_ON
LOG_TO_FILE("%08X: %08X %08X CMD UC4_TEXTURE",ADDR, CMD0, CMD1);
LOG_TO_FILE("\tTile = %i, Mipmap = %i, enambled = %s\n",tile, mipmap_level, (on)?"on":"off");
#endif
}
void UpdateTile(t_tile *tmpTile)
{
BOOL found=FALSE;
_u16 tries=0;
_u16 closesttmem = 0;
_u16 closestidx = ((_u16)LstLdAddNum - 1) & LstLdAddrMask;
_u16 lp=(_u16)LstLdAddNum;
tmpTile->addr = (_u32)&pRDRAM[0];
if(lp)
lp--;
else
lp=LstLdAddrMask;
closestidx = lp;
tmpTile->Pitch = LstLdAddr[lp].Pitch;
tmpTile->offset =LstLdAddr[lp].Addr + (_u32)(tmpTile->tmem - LstLdAddr[lp].Offset) * 8;
tmpTile->LineWidth = (_u16)LstLdAddr[lp].LineWidth;
if (LstLdAddr[lp].Swapped>0)
tmpTile->WdSwpd = TRUE;
else
tmpTile->WdSwpd = FALSE;
tries=0;
while(!found)
{
if ((LstLdAddr[lp].Offset <= tmpTile->tmem)
&& (LstLdAddr[lp].End > tmpTile->tmem))
{
//if(tmpTile->tmem == 0x160)
// tmpTile->tmem = 0x2C;
tmpTile->Pitch = LstLdAddr[lp].Pitch;
tmpTile->offset =LstLdAddr[lp].Addr + (_u32)(tmpTile->tmem - LstLdAddr[lp].Offset) * 8;
tmpTile->LineWidth = (_u16)LstLdAddr[lp].LineWidth;
if (LstLdAddr[lp].Swapped>0)
tmpTile->WdSwpd = TRUE;
else
tmpTile->WdSwpd = FALSE;
found=TRUE;
}
else
{
if(lp)
lp--;
else
lp=LstLdAddrMask;
}
tries++;
if(tries == LstLdAddrSize)
{
tries++;
break;
}
}
if(!found)
{
lp = closestidx;
tmpTile->Pitch = LstLdAddr[lp].Pitch;
tmpTile->LineWidth = (_u16)LstLdAddr[lp].LineWidth;
tmpTile->offset = LstLdAddr[lp].Addr + (_u32)(tmpTile->tmem - LstLdAddr[lp].Offset) * 8;
if (LstLdAddr[lp].Swapped>0)
tmpTile->WdSwpd = TRUE;
else
tmpTile->WdSwpd = FALSE;
}
switch(tmpTile->size)
{
case 0:
tmpTile->Pitch<<=1;
break;
case 2:
break;
case 3:
break;
}
if(tmpTile->Pitch<=01)
{
tmpTile->Pitch=tmpTile->line;
}
}