1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Implement LLE triangles.

This commit is contained in:
Sergey Lipskiy 2014-10-07 17:59:54 +07:00
parent 2058770099
commit a8021084f2
11 changed files with 701 additions and 32 deletions

16
F3D.cpp
View File

@ -310,22 +310,8 @@ void F3D_Quad( u32 w0, u32 w1 )
void F3D_RDPHalf_1( u32 w0, u32 w1 )
{
/* if (_SHIFTR( w1, 24, 8 ) == 0xCE)
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
gDPTextureRectangle( gDP.scissor.ulx, // ulx
_FIXED2FLOAT( _SHIFTR( w2, 0, 16 ), 2 ), // uly
gDP.scissor.lrx, // lrx
_FIXED2FLOAT( _SHIFTR( w2, 16, 16 ), 2 ), // lry
0, // tile
0, // s
0, // t
1, // dsdx
1 ); // dsdy
}*/
gDP.half_1 = w1;
RDP_Half_1(w1);
}
void F3D_RDPHalf_2( u32 w0, u32 w1 )

View File

@ -605,10 +605,8 @@ void OGLRender::_setTexCoordArrays() const
glDisableVertexAttribArray(SC_STSCALED);
}
void OGLRender::drawTriangles()
void OGLRender::_prepareDrawTriangle()
{
if (triangles.num == 0) return;
#ifndef GLES2
if (m_bImageTexture)
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
@ -641,8 +639,53 @@ void OGLRender::drawTriangles()
currentCombiner()->updateRenderState();
}
currentCombiner()->updateColors(true);
currentCombiner()->updateLight(true);
currentCombiner()->updateColors();
currentCombiner()->updateLight();
}
void OGLRender::drawLLETriangle(u32 _numVtx)
{
if (_numVtx == 0)
return;
_prepareDrawTriangle();
glDisable(GL_CULL_FACE);
FrameBufferList & fbList = frameBufferList();
FrameBuffer* pBuffer = fbList.getCurrent();
OGLVideo & ogl = video();
if (!fbList.isFboMode())
glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight());
else
glViewport(0, 0, pBuffer->m_width*pBuffer->m_scaleX, pBuffer->m_height*pBuffer->m_scaleY);
const float scaleX = fbList.isFboMode() ? 1.0f / pBuffer->m_width : VI.rwidth;
const float scaleY = fbList.isFboMode() ? 1.0f / pBuffer->m_height : VI.rheight;
for (u32 i = 0; i < _numVtx; ++i) {
triangles.vertices[i].HWLight = 0;
triangles.vertices[i].st_scaled = 0;
triangles.vertices[i].x = triangles.vertices[i].x * (2.0f * scaleX) - 1.0f;
triangles.vertices[i].x *= triangles.vertices[i].w;
triangles.vertices[i].y = triangles.vertices[i].y * (-2.0f * scaleY) + 1.0f;
triangles.vertices[i].y *= triangles.vertices[i].w;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVtx);
triangles.num = 0;
gSP.changed != CHANGED_VIEWPORT | CHANGED_GEOMETRYMODE;
#ifdef __TRIBUFFER_OPT
_indexmap_clear();
#endif
}
void OGLRender::drawTriangles()
{
if (triangles.num == 0) return;
_prepareDrawTriangle();
glDrawElements(GL_TRIANGLES, triangles.num, GL_UNSIGNED_BYTE, triangles.elements);
triangles.num = 0;

View File

@ -34,6 +34,7 @@ class OGLRender
public:
void addTriangle(int _v0, int _v1, int _v2);
void drawTriangles();
void drawLLETriangle(u32 _numVtx);
void drawLine(int _v0, int _v1, float _width);
void drawRect(int _ulx, int _uly, int _lrx, int _lry, float * _pColor);
void drawTexturedRect(
@ -84,6 +85,7 @@ private:
void _updateViewport() const;
void _updateDepthUpdate() const;
void _updateStates() const;
void _prepareDrawTriangle();
#ifdef __TRIBUFFER_OPT
void _indexmap_init();

View File

@ -14,6 +14,7 @@
enum API_COMMAND {
acNone = 0,
acProcessDList,
acProcessRDPList,
acUpdateScreen,
acRomClosed
};
@ -31,11 +32,11 @@ public:
// Common
void MoveScreen(int /*_xpos*/, int /*_ypos*/) {}
void ProcessRDPList() {}
void ViStatusChanged() {}
void ViWidthChanged() {}
void ProcessDList();
void ProcessRDPList();
void RomClosed();
void RomOpen();
void ShowCFB();

267
RDP.cpp
View File

@ -1,5 +1,6 @@
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "GBI.h"
#include "gDP.h"
#include "Debug.h"
@ -214,12 +215,17 @@ void RDP_LoadSync( u32 w0, u32 w1 )
void RDP_TexRectFlip( u32 w0, u32 w1 )
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w2, w3;
if (RSP.bLLE) {
w2 = RDP.w2;
w3 = RDP.w3;
} else {
w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
}
gDPTextureRectangleFlip( _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // ulx
_FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ), // uly
_FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // lrx
@ -233,12 +239,17 @@ void RDP_TexRectFlip( u32 w0, u32 w1 )
void RDP_TexRect( u32 w0, u32 w1 )
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w2, w3;
if (RSP.bLLE) {
w2 = RDP.w2;
w3 = RDP.w3;
} else {
w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
}
gDPTextureRectangle( _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // ulx
_FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ), // uly
_FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // lrx
@ -250,6 +261,48 @@ void RDP_TexRect( u32 w0, u32 w1 )
_FIXED2FLOAT( (s16)_SHIFTR( w3, 0, 16 ), 10 ) ); // dsdy
}
void RDP_TriFill( u32 _w0, u32 _w1 )
{
gDPTriFill(_w0, _w1);
}
void RDP_TriShade( u32 _w0, u32 _w1 )
{
gDPTriShade(_w0, _w1);
}
void RDP_TriTxtr( u32 _w0, u32 _w1 )
{
gDPTriTxtr(_w0, _w1);
}
void RDP_TriShadeTxtr( u32 _w0, u32 _w1 )
{
gDPTriShadeTxtr(_w0, _w1);
}
void RDP_TriFillZ( u32 _w0, u32 _w1 )
{
gDPTriFillZ(_w0, _w1);
}
void RDP_TriShadeZ( u32 _w0, u32 _w1 )
{
gDPTriShadeZ(_w0, _w1);
}
void RDP_TriTxtrZ( u32 _w0, u32 _w1 )
{
gDPTriTxtrZ(_w0, _w1);
}
void RDP_TriShadeTxtrZ( u32 _w0, u32 _w1 )
{
gDPTriShadeTxtrZ(_w0, _w1);
}
RDPInfo RDP;
void RDP_Init()
{
// Initialize RDP commands to RDP_UNKNOWN
@ -289,5 +342,199 @@ void RDP_Init()
GBI.cmd[G_RDPLOADSYNC] = RDP_LoadSync;
GBI.cmd[G_TEXRECTFLIP] = RDP_TexRectFlip;
GBI.cmd[G_TEXRECT] = RDP_TexRect;
RDP.w2 = RDP.w3 = 0;
RDP.cmd_ptr = RDP.cmd_cur = 0;
}
static
GBIFunc LLEcmd[64] = {
/* 0x00 */
RDP_NoOp, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ,
RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ,
/* 0x10 */
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
/* 0x20 */
RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown,
RDP_TexRect, RDP_TexRectFlip, RDP_LoadSync, RDP_PipeSync,
RDP_TileSync, RDP_FullSync, RDP_SetKeyGB, RDP_SetKeyR,
RDP_SetConvert, RDP_SetScissor, RDP_SetPrimDepth, RDP_SetOtherMode,
/* 0x30 */
RDP_LoadTLUT, RDP_Unknown, RDP_SetTileSize, RDP_LoadBlock,
RDP_LoadTile, RDP_SetTile, RDP_FillRect, RDP_SetFillColor,
RDP_SetFogColor, RDP_SetBlendColor, RDP_SetPrimColor, RDP_SetEnvColor,
RDP_SetCombine, RDP_SetTImg, RDP_SetZImg, RDP_SetCImg
};
static
const u32 CmdLength[64] =
{
8, // 0x00, No Op
8, // 0x01, ???
8, // 0x02, ???
8, // 0x03, ???
8, // 0x04, ???
8, // 0x05, ???
8, // 0x06, ???
8, // 0x07, ???
32, // 0x08, Non-Shaded Triangle
32+16, // 0x09, Non-Shaded, Z-Buffered Triangle
32+64, // 0x0a, Textured Triangle
32+64+16, // 0x0b, Textured, Z-Buffered Triangle
32+64, // 0x0c, Shaded Triangle
32+64+16, // 0x0d, Shaded, Z-Buffered Triangle
32+64+64, // 0x0e, Shaded+Textured Triangle
32+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle
8, // 0x10, ???
8, // 0x11, ???
8, // 0x12, ???
8, // 0x13, ???
8, // 0x14, ???
8, // 0x15, ???
8, // 0x16, ???
8, // 0x17, ???
8, // 0x18, ???
8, // 0x19, ???
8, // 0x1a, ???
8, // 0x1b, ???
8, // 0x1c, ???
8, // 0x1d, ???
8, // 0x1e, ???
8, // 0x1f, ???
8, // 0x20, ???
8, // 0x21, ???
8, // 0x22, ???
8, // 0x23, ???
16, // 0x24, Texture_Rectangle
16, // 0x25, Texture_Rectangle_Flip
8, // 0x26, Sync_Load
8, // 0x27, Sync_Pipe
8, // 0x28, Sync_Tile
8, // 0x29, Sync_Full
8, // 0x2a, Set_Key_GB
8, // 0x2b, Set_Key_R
8, // 0x2c, Set_Convert
8, // 0x2d, Set_Scissor
8, // 0x2e, Set_Prim_Depth
8, // 0x2f, Set_Other_Modes
8, // 0x30, Load_TLUT
8, // 0x31, ???
8, // 0x32, Set_Tile_Size
8, // 0x33, Load_Block
8, // 0x34, Load_Tile
8, // 0x35, Set_Tile
8, // 0x36, Fill_Rectangle
8, // 0x37, Set_Fill_Color
8, // 0x38, Set_Fog_Color
8, // 0x39, Set_Blend_Color
8, // 0x3a, Set_Prim_Color
8, // 0x3b, Set_Env_Color
8, // 0x3c, Set_Combine
8, // 0x3d, Set_Texture_Image
8, // 0x3e, Set_Mask_Image
8 // 0x3f, Set_Color_Image
};
void RDP_Half_1( u32 _c )
{
u32 w0 = 0, w1 = _c;
u32 cmd = _SHIFTR( _c, 24, 8 );
if (cmd >= 0xc8 && cmd <=0xcf) {//triangle command
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPHalf_1 LLE Triangle\n");
RDP.cmd_ptr = 0;
RDP.cmd_cur = 0;
do {
RDP.cmd_data[RDP.cmd_ptr++] = w1;
RSP_CheckDLCounter();
w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR( w0, 24, 8 );
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 );
RSP.PC[RSP.PCi] += 8;
// RSP.nextCmd = _SHIFTR( *(u32*)&RDRAM[RSP.PC[RSP.PCi]], 24, 8 );
} while (RSP.cmd != 0xb3);
RDP.cmd_data[RDP.cmd_ptr++] = w1;
RSP.cmd = (RDP.cmd_data[RDP.cmd_cur] >> 24) & 0x3f;
w0 = RDP.cmd_data[RDP.cmd_cur+0];
w1 = RDP.cmd_data[RDP.cmd_cur+1];
LLEcmd[RSP.cmd](w0, w1);
} else {
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPHalf_1()\n" );
}
}
#define rdram ((u32*)RDRAM)
#define rsp_dmem ((u32*)DMEM)
#define dp_start (*(u32*)REG.DPC_START)
#define dp_end (*(u32*)REG.DPC_END)
#define dp_current (*(u32*)REG.DPC_CURRENT)
#define dp_status (*(u32*)REG.DPC_STATUS)
inline u32 READ_RDP_DATA(u32 address)
{
if (dp_status & 0x1) // XBUS_DMEM_DMA enabled
return rsp_dmem[(address & 0xfff)>>2];
else
return rdram[address>>2];
}
void RDP_ProcessRDPList()
{
DebugMsg(DEBUG_HIGH | DEBUG_HANDLED, "ProcessRDPList()\n");
u32 i;
u32 cmd, length, cmd_length;
RDP.cmd_ptr = 0;
RDP.cmd_cur = 0;
if (dp_end <= dp_current) return;
length = dp_end - dp_current;
// load command data
for (i = 0; i < length; i += 4) {
RDP.cmd_data[RDP.cmd_ptr++] = READ_RDP_DATA(dp_current + i);
if (RDP.cmd_ptr >= 0x1000) {
DebugMsg(DEBUG_HIGH | DEBUG_ERROR, "rdp_process_list: RDP.cmd_ptr overflow %x %x --> %x\n", length, dp_current, dp_end);
}
}
dp_current = dp_end;
cmd = (RDP.cmd_data[0] >> 24) & 0x3f;
cmd_length = (RDP.cmd_ptr + 1) * 4;
// check if more data is needed
if (cmd_length < CmdLength[cmd])
return;
RSP.bLLE = true;
while (RDP.cmd_cur < RDP.cmd_ptr) {
cmd = (RDP.cmd_data[RDP.cmd_cur] >> 24) & 0x3f;
if (((RDP.cmd_ptr-RDP.cmd_cur) * 4) < CmdLength[cmd])
return;
// execute the command
u32 w0 = RDP.cmd_data[RDP.cmd_cur+0];
u32 w1 = RDP.cmd_data[RDP.cmd_cur+1];
RDP.w2 = RDP.cmd_data[RDP.cmd_cur+2];
RDP.w3 = RDP.cmd_data[RDP.cmd_cur+3];
LLEcmd[cmd](w0, w1);
RDP.cmd_cur += CmdLength[cmd] / 4;
};
RSP.bLLE = false;
dp_start = dp_end;
dp_status &= ~0x0002;
}

12
RDP.h
View File

@ -1,7 +1,19 @@
#ifndef RDP_H
#define RDP_H
typedef struct
{
u32 w2, w3;
u32 cmd_ptr;
u32 cmd_cur;
u32 cmd_data[0x1000];
} RDPInfo;
extern RDPInfo RDP;
void RDP_Init();
void RDP_Half_1(u32 _c);
void RDP_ProcessRDPList();
#endif

View File

@ -261,6 +261,7 @@ void RSP_Init()
RSP.DList = 0;
RSP.uc_start = RSP.uc_dstart = 0;
RSP.bLLE = false;
gDP.loadTile = &gDP.tiles[7];
gSP.textureTile[0] = &gDP.tiles[0];

1
RSP.h
View File

@ -7,6 +7,7 @@ typedef struct
{
u32 PC[18], PCi, busy, halt, close, DList, uc_start, uc_dstart, cmd, nextCmd;
s32 count;
bool bLLE;
} RSPInfo;
extern RSPInfo RSP;

View File

@ -11,6 +11,7 @@
#include "../GLideN64.h"
#include "../OpenGL.h"
#include "../RSP.h"
#include "../RDP.h"
#include "../VI.h"
#include "../Debug.h"
#include "../Log.h"
@ -33,6 +34,9 @@ void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx,
case acProcessDList:
RSP_ProcessDList();
break;
case acProcessRDPList:
RDP_ProcessRDPList();
break;
case acUpdateScreen:
VI_UpdateScreen();
break;
@ -73,6 +77,16 @@ void PluginAPI::ProcessDList()
#endif
}
void PluginAPI::ProcessRDPList()
{
LOG(LOG_APIFUNC, "ProcessRDPList\n");
#ifdef RSPTHREAD
_callAPICommand(acProcessRDPList);
#else
RDP_ProcessRDPList();
#endif
}
void PluginAPI::RomClosed()
{
LOG(LOG_APIFUNC, "RomClosed\n");

353
gDP.cpp
View File

@ -4,6 +4,7 @@
#include "N64.h"
#include "GBI.h"
#include "RSP.h"
#include "RDP.h"
#include "gDP.h"
#include "gSP.h"
#include "Types.h"
@ -952,3 +953,355 @@ void gDPNoOp()
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPNoOp();\n" );
#endif
}
/*******************************************
* Low level triangle *
*******************************************
* based on sources of ziggy's z64 *
*******************************************/
void gDPLLETriangle(u32 _w1, u32 _w2, int _shade, int _texture, int _zbuffer, u32 * _pRdpCmd)
{
const u32 tile = _SHIFTR(_w1, 16, 3);
gDPTile *textureTileOrg[2];
textureTileOrg[0] = gSP.textureTile[0];
textureTileOrg[1] = gSP.textureTile[1];
gSP.textureTile[0] = &gDP.tiles[tile];
gSP.textureTile[1] = &gDP.tiles[tile < 7 ? tile + 1 : tile];
int j;
int xleft, xright, xleft_inc, xright_inc;
int r, g, b, a, z, s, t, w;
int drdx = 0, dgdx = 0, dbdx = 0, dadx = 0, dzdx = 0, dsdx = 0, dtdx = 0, dwdx = 0;
int drde = 0, dgde = 0, dbde = 0, dade = 0, dzde = 0, dsde = 0, dtde = 0, dwde = 0;
int flip = (_w1 & 0x800000) ? 1 : 0;
s32 yl, ym, yh;
s32 xl, xm, xh;
s32 dxldy, dxhdy, dxmdy;
u32 w3, w4, w5, w6, w7, w8;
u32 * shade_base = _pRdpCmd + 8;
u32 * texture_base = _pRdpCmd + 8;
u32 * zbuffer_base = _pRdpCmd + 8;
if (_shade != 0) {
texture_base += 16;
zbuffer_base += 16;
}
if (_texture != 0) {
zbuffer_base += 16;
}
w3 = _pRdpCmd[2];
w4 = _pRdpCmd[3];
w5 = _pRdpCmd[4];
w6 = _pRdpCmd[5];
w7 = _pRdpCmd[6];
w8 = _pRdpCmd[7];
yl = (_w1 & 0x3fff);
ym = ((_w2 >> 16) & 0x3fff);
yh = ((_w2 >> 0) & 0x3fff);
xl = (s32)(w3);
xh = (s32)(w5);
xm = (s32)(w7);
dxldy = (s32)(w4);
dxhdy = (s32)(w6);
dxmdy = (s32)(w8);
if (yl & (0x800<<2)) yl |= 0xfffff000<<2;
if (ym & (0x800<<2)) ym |= 0xfffff000<<2;
if (yh & (0x800<<2)) yh |= 0xfffff000<<2;
yh &= ~3;
r = 0xff; g = 0xff; b = 0xff; a = 0xff; z = 0xffff0000; s = 0; t = 0; w = 0x30000;
if (_shade != 0) {
r = (shade_base[0] & 0xffff0000) | ((shade_base[+4 ] >> 16) & 0x0000ffff);
g = ((shade_base[0 ] << 16) & 0xffff0000) | (shade_base[4 ] & 0x0000ffff);
b = (shade_base[1 ] & 0xffff0000) | ((shade_base[5 ] >> 16) & 0x0000ffff);
a = ((shade_base[1 ] << 16) & 0xffff0000) | (shade_base[5 ] & 0x0000ffff);
drdx = (shade_base[2 ] & 0xffff0000) | ((shade_base[6 ] >> 16) & 0x0000ffff);
dgdx = ((shade_base[2 ] << 16) & 0xffff0000) | (shade_base[6 ] & 0x0000ffff);
dbdx = (shade_base[3 ] & 0xffff0000) | ((shade_base[7 ] >> 16) & 0x0000ffff);
dadx = ((shade_base[3 ] << 16) & 0xffff0000) | (shade_base[7 ] & 0x0000ffff);
drde = (shade_base[8 ] & 0xffff0000) | ((shade_base[12] >> 16) & 0x0000ffff);
dgde = ((shade_base[8 ] << 16) & 0xffff0000) | (shade_base[12] & 0x0000ffff);
dbde = (shade_base[9 ] & 0xffff0000) | ((shade_base[13] >> 16) & 0x0000ffff);
dade = ((shade_base[9 ] << 16) & 0xffff0000) | (shade_base[13] & 0x0000ffff);
}
if (_texture != 0) {
s = (texture_base[0 ] & 0xffff0000) | ((texture_base[4 ] >> 16) & 0x0000ffff);
t = ((texture_base[0 ] << 16) & 0xffff0000) | (texture_base[4 ] & 0x0000ffff);
w = (texture_base[1 ] & 0xffff0000) | ((texture_base[5 ] >> 16) & 0x0000ffff);
// w = abs(w);
dsdx = (texture_base[2 ] & 0xffff0000) | ((texture_base[6 ] >> 16) & 0x0000ffff);
dtdx = ((texture_base[2 ] << 16) & 0xffff0000) | (texture_base[6 ] & 0x0000ffff);
dwdx = (texture_base[3 ] & 0xffff0000) | ((texture_base[7 ] >> 16) & 0x0000ffff);
dsde = (texture_base[8 ] & 0xffff0000) | ((texture_base[12] >> 16) & 0x0000ffff);
dtde = ((texture_base[8 ] << 16) & 0xffff0000) | (texture_base[12] & 0x0000ffff);
dwde = (texture_base[9 ] & 0xffff0000) | ((texture_base[13] >> 16) & 0x0000ffff);
}
if (_zbuffer != 0) {
z = zbuffer_base[0];
dzdx = zbuffer_base[1];
dzde = zbuffer_base[2];
}
xh <<= 2; xm <<= 2; xl <<= 2;
r <<= 2; g <<= 2; b <<= 2; a <<= 2;
dsde >>= 2; dtde >>= 2; dsdx >>= 2; dtdx >>= 2;
dzdx >>= 2; dzde >>= 2;
dwdx >>= 2; dwde >>= 2;
#define XSCALE(x) (float(x)/(1<<18))
#define YSCALE(y) (float(y)/(1<<2))
#define ZSCALE(z) ((gDP.otherMode.depthSource == G_ZS_PRIM)? gDP.primDepth.z : float(u32(z))/0xffff0000)
//#define WSCALE(w) (bPerspEnabled? (float(u32(w) + 0x10000)/0xffff0000) : 1.0f)
//#define WSCALE(w) (bPerspEnabled? 4294901760.0/(w + 65536) : 1.0f)
#define PERSP_EN (gDP.otherMode.texturePersp != 0)
#define WSCALE(w) (PERSP_EN? 65536.0f/float((w+ 0xffff)>>16) : 1.0f)
#define CSCALE(c) ((((c)>0x3ff0000? 0x3ff0000:((c)<0? 0 : (c)))>>18)*0.0039215689f)
#define _PERSP(w) ( w )
#define PERSP(s, w) ( ((s64)(s) << 20) / (_PERSP(w)? _PERSP(w):1) )
#define SSCALE(s, _w) (PERSP_EN? float(PERSP(s, _w))/(1 << 10) : float(s)/(1<<21))
#define TSCALE(s, w) (PERSP_EN? float(PERSP(s, w))/(1 << 10) : float(s)/(1<<21))
u32 nbVtxs = 0;
OGLRender & render = video().getRender();
SPVertex * vtx = &render.getVertex(nbVtxs++);
xleft = xm;
xright = xh;
xleft_inc = dxmdy;
xright_inc = dxhdy;
while (yh<ym &&
!((!flip && xleft < xright+0x10000) ||
(flip && xleft > xright-0x10000))) {
xleft += xleft_inc;
xright += xright_inc;
s += dsde; t += dtde; w += dwde;
r += drde; g += dgde; b += dbde; a += dade;
z += dzde;
yh++;
}
j = ym-yh;
if (j > 0) {
int dx = (xleft-xright)>>16;
if ((!flip && xleft < xright) ||
(flip/* && xleft > xright*/))
{
if (_shade != 0) {
vtx->r = CSCALE(r+drdx*dx);
vtx->g = CSCALE(g+dgdx*dx);
vtx->b = CSCALE(b+dbdx*dx);
vtx->a = CSCALE(a+dadx*dx);
}
if (_texture != 0) {
vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx);
vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx);
}
vtx->x = XSCALE(xleft);
vtx->y = YSCALE(yh);
vtx->z = ZSCALE(z+dzdx*dx);
vtx->w = WSCALE(w+dwdx*dx);
vtx = &render.getVertex(nbVtxs++);
}
if ((!flip/* && xleft < xright*/) ||
(flip && xleft > xright))
{
if (_shade != 0) {
vtx->r = CSCALE(r);
vtx->g = CSCALE(g);
vtx->b = CSCALE(b);
vtx->a = CSCALE(a);
}
if (_texture != 0) {
vtx->s = SSCALE(s, w);
vtx->t = TSCALE(t, w);
}
vtx->x = XSCALE(xright);
vtx->y = YSCALE(yh);
vtx->z = ZSCALE(z);
vtx->w = WSCALE(w);
vtx = &render.getVertex(nbVtxs++);
}
xleft += xleft_inc*j; xright += xright_inc*j;
s += dsde*j; t += dtde*j;
if (w + dwde*j) w += dwde*j;
else w += dwde*(j-1);
r += drde*j; g += dgde*j; b += dbde*j; a += dade*j;
z += dzde*j;
// render ...
}
if (xl != xh)
xleft = xl;
//if (yl-ym > 0)
{
int dx = (xleft-xright)>>16;
if ((!flip && xleft <= xright) ||
(flip/* && xleft >= xright*/))
{
if (_shade != 0) {
vtx->r = CSCALE(r+drdx*dx);
vtx->g = CSCALE(g+dgdx*dx);
vtx->b = CSCALE(b+dbdx*dx);
vtx->a = CSCALE(a+dadx*dx);
}
if (_texture != 0) {
vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx);
vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx);
}
vtx->x = XSCALE(xleft);
vtx->y = YSCALE(ym);
vtx->z = ZSCALE(z+dzdx*dx);
vtx->w = WSCALE(w+dwdx*dx);
vtx = &render.getVertex(nbVtxs++);
}
if ((!flip/* && xleft <= xright*/) ||
(flip && xleft >= xright))
{
if (_shade != 0) {
vtx->r = CSCALE(r);
vtx->g = CSCALE(g);
vtx->b = CSCALE(b);
vtx->a = CSCALE(a);
}
if (_texture != 0) {
vtx->s = SSCALE(s, w);
vtx->t = TSCALE(t, w);
}
vtx->x = XSCALE(xright);
vtx->y = YSCALE(ym);
vtx->z = ZSCALE(z);
vtx->w = WSCALE(w);
vtx = &render.getVertex(nbVtxs++);
}
}
xleft_inc = dxldy;
xright_inc = dxhdy;
j = yl-ym;
//j--; // ?
xleft += xleft_inc*j; xright += xright_inc*j;
s += dsde*j; t += dtde*j; w += dwde*j;
r += drde*j; g += dgde*j; b += dbde*j; a += dade*j;
z += dzde*j;
while (yl>ym &&
!((!flip && xleft < xright+0x10000) ||
(flip && xleft > xright-0x10000))) {
xleft -= xleft_inc; xright -= xright_inc;
s -= dsde; t -= dtde; w -= dwde;
r -= drde; g -= dgde; b -= dbde; a -= dade;
z -= dzde;
--j;
--yl;
}
// render ...
if (j >= 0) {
int dx = (xleft-xright)>>16;
if ((!flip && xleft <= xright) ||
(flip/* && xleft >= xright*/))
{
if (_shade != 0) {
vtx->r = CSCALE(r+drdx*dx);
vtx->g = CSCALE(g+dgdx*dx);
vtx->b = CSCALE(b+dbdx*dx);
vtx->a = CSCALE(a+dadx*dx);
}
if (_texture != 0) {
vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx);
vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx);
}
vtx->x = XSCALE(xleft);
vtx->y = YSCALE(yl);
vtx->z = ZSCALE(z+dzdx*dx);
vtx->w = WSCALE(w+dwdx*dx);
vtx = &render.getVertex(nbVtxs++);
}
if ((!flip/* && xleft <= xright*/) ||
(flip && xleft >= xright))
{
if (_shade != 0) {
vtx->r = CSCALE(r);
vtx->g = CSCALE(g);
vtx->b = CSCALE(b);
vtx->a = CSCALE(a);
}
if (_texture != 0) {
vtx->s = SSCALE(s, w);
vtx->t = TSCALE(t, w);
}
vtx->x = XSCALE(xright);
vtx->y = YSCALE(yl);
vtx->z = ZSCALE(z);
vtx->w = WSCALE(w);
vtx = &render.getVertex(nbVtxs++);
}
}
render.drawLLETriangle(nbVtxs - 1);
gSP.textureTile[0] = textureTileOrg[0];
gSP.textureTile[1] = textureTileOrg[1];
}
static void gDPTriangle(u32 _w1, u32 _w2, int shade, int texture, int zbuffer)
{
gDPLLETriangle(_w1, _w2, shade, texture, zbuffer, RDP.cmd_data + RDP.cmd_cur);
}
void gDPTriFill(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 0, 0, 0);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifill\n");
}
void gDPTriShade(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 1, 0, 0);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishade\n");
}
void gDPTriTxtr(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 0, 1, 0);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtr\n");
}
void gDPTriShadeTxtr(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 1, 1, 0);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtr\n");
}
void gDPTriFillZ(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 0, 0, 1);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifillz\n");
}
void gDPTriShadeZ(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 1, 0, 1);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadez\n");
}
void gDPTriTxtrZ(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 0, 1, 1);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtrz\n");
}
void gDPTriShadeTxtrZ(u32 w0, u32 w1)
{
gDPTriangle(w0, w1, 1, 1, 1);
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtrz\n");
}

11
gDP.h
View File

@ -138,7 +138,7 @@ struct gDPInfo
unsigned int blendMask : 4;
unsigned int alphaDither : 2;
unsigned int colorDither : 2;
unsigned int combineKey : 1;
unsigned int textureConvert : 3;
unsigned int textureFilter : 2;
@ -282,6 +282,15 @@ void gDPPipeSync();
void gDPLoadSync();
void gDPNoOp();
void gDPTriFill( u32 w0, u32 w1 );
void gDPTriShade( u32 w0, u32 w1 );
void gDPTriTxtr( u32 w0, u32 w1 );
void gDPTriShadeTxtr( u32 w0, u32 w1 );
void gDPTriFillZ( u32 w0, u32 w1 );
void gDPTriShadeZ( u32 w0, u32 w1 );
void gDPTriTxtrZ( u32 w0, u32 w1 );
void gDPTriShadeTxtrZ( u32 w0, u32 w1 );
void gDPFillRDRAM( u32 address, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 width, u32 size, u32 color );
#endif