X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-video-arachnoid%2Fsrc%2Fucodes%2FUCode5.cpp;fp=source%2Fmupen64plus-video-arachnoid%2Fsrc%2Fucodes%2FUCode5.cpp;h=01c0b5d314423f9c8f6480989f86fb07566bed26;hb=22726e4d55be26faa48b57b22689cbedde27ae44;hp=0000000000000000000000000000000000000000;hpb=fc5d46b49a19d41f9f2da5a9336daec452900475;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp new file mode 100755 index 0000000..01c0b5d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp @@ -0,0 +1,515 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * 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 "UCode5.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" +#include "DisplayListParser.h" + + +#define F3DEX2_MTX_STACKSIZE 18 + +#define F3DEX2_MTX_MODELVIEW 0x00 +#define F3DEX2_MTX_PROJECTION 0x04 +#define F3DEX2_MTX_MUL 0x00 +#define F3DEX2_MTX_LOAD 0x02 +#define F3DEX2_MTX_NOPUSH 0x00 +#define F3DEX2_MTX_PUSH 0x01 + +#define F3DEX2_TEXTURE_ENABLE 0x00000000 +#define F3DEX2_SHADING_SMOOTH 0x00200000 +#define F3DEX2_CULL_FRONT 0x00000200 +#define F3DEX2_CULL_BACK 0x00000400 +#define F3DEX2_CULL_BOTH 0x00000600 +#define F3DEX2_CLIPPING 0x00800000 + +#define F3DEX2_MV_VIEWPORT 8 + +#define F3DEX2_MWO_aLIGHT_1 0x00 +#define F3DEX2_MWO_bLIGHT_1 0x04 +#define F3DEX2_MWO_aLIGHT_2 0x18 +#define F3DEX2_MWO_bLIGHT_2 0x1c +#define F3DEX2_MWO_aLIGHT_3 0x30 +#define F3DEX2_MWO_bLIGHT_3 0x34 +#define F3DEX2_MWO_aLIGHT_4 0x48 +#define F3DEX2_MWO_bLIGHT_4 0x4c +#define F3DEX2_MWO_aLIGHT_5 0x60 +#define F3DEX2_MWO_bLIGHT_5 0x64 +#define F3DEX2_MWO_aLIGHT_6 0x78 +#define F3DEX2_MWO_bLIGHT_6 0x7c +#define F3DEX2_MWO_aLIGHT_7 0x90 +#define F3DEX2_MWO_bLIGHT_7 0x94 +#define F3DEX2_MWO_aLIGHT_8 0xa8 +#define F3DEX2_MWO_bLIGHT_8 0xac + + +#define F3DEX2_RDPHALF_2 0xF1 +#define F3DEX2_SETOTHERMODE_H 0xE3 +#define F3DEX2_SETOTHERMODE_L 0xE2 +#define F3DEX2_RDPHALF_1 0xE1 +#define F3DEX2_SPNOOP 0xE0 +#define F3DEX2_ENDDL 0xDF +#define F3DEX2_DL 0xDE +#define F3DEX2_LOAD_UCODE 0xDD +#define F3DEX2_MTX 0xDA +#define F3DEX2_GEOMETRYMODE 0xD9 +#define F3DEX2_POPMTX 0xD8 +#define F3DEX2_TEXTURE 0xD7 +#define F3DEX2_DMA_IO 0xD6 +#define F3DEX2_SPECIAL_1 0xD5 +#define F3DEX2_SPECIAL_2 0xD4 +#define F3DEX2_SPECIAL_3 0xD3 + +#define F3DEX2_VTX 0x01 +#define F3DEX2_MODIFYVTX 0x02 +#define F3DEX2_CULLDL 0x03 +#define F3DEX2_BRANCH_Z 0x04 +#define F3DEX2_TRI1 0x05 +#define F3DEX2_TRI2 0x06 +#define F3DEX2_QUAD 0x07 +#define F3DEX2_LINE3D 0x08 + + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode5::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode5::m_rdp = 0; //!< Pointer to Reality Drawing Processor +Memory* UCode5::m_memory = 0; +GBI* UCode5::m_gbi = 0; +DisplayListParser* UCode5::m_displayListParser = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode5::UCode5() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode5::~UCode5() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode5::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp) +{ + m_gbi = gbi; + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode5::initializeGBI() +{ + //Set flags + GBI_InitFlags( F3DEX2 ); + + + // GBI Command Command Value Command Function + GBI_SetGBI( GBI::G_RDPHALF_2, F3DEX2_RDPHALF_2, m_gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, m_gbi->m_cmds, F3DEX2_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, m_gbi->m_cmds, F3DEX2_SetOtherMode_L ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3DEX2_RDPHALF_1, m_gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_SPNOOP, F3DEX2_SPNOOP, m_gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_ENDDL, F3DEX2_ENDDL, m_gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_DL, F3DEX2_DL, m_gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_LOAD_UCODE, F3DEX2_LOAD_UCODE, m_gbi->m_cmds, UCode1::F3DEX_Load_uCode ); + GBI_SetGBI( GBI::G_MOVEMEM, F3DEX2_MOVEMEM, m_gbi->m_cmds, F3DEX2_MoveMem ); + GBI_SetGBI( GBI::G_MOVEWORD, F3DEX2_MOVEWORD, m_gbi->m_cmds, F3DEX2_MoveWord ); + GBI_SetGBI( GBI::G_MTX, F3DEX2_MTX, m_gbi->m_cmds, F3DEX2_Mtx ); + GBI_SetGBI( GBI::G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, m_gbi->m_cmds, F3DEX2_GeometryMode ); + GBI_SetGBI( GBI::G_POPMTX, F3DEX2_POPMTX, m_gbi->m_cmds, F3DEX2_PopMtx ); + GBI_SetGBI( GBI::G_TEXTURE, F3DEX2_TEXTURE, m_gbi->m_cmds, F3DEX2_Texture ); + GBI_SetGBI( GBI::G_DMA_IO, F3DEX2_DMA_IO, m_gbi->m_cmds, F3DEX2_DMAIO ); + GBI_SetGBI( GBI::G_SPECIAL_1, F3DEX2_SPECIAL_1, m_gbi->m_cmds, F3DEX2_Special_1 ); + GBI_SetGBI( GBI::G_SPECIAL_2, F3DEX2_SPECIAL_2, m_gbi->m_cmds, F3DEX2_Special_2 ); + GBI_SetGBI( GBI::G_SPECIAL_3, F3DEX2_SPECIAL_3, m_gbi->m_cmds, F3DEX2_Special_3 ); + GBI_SetGBI( GBI::G_VTX, F3DEX2_VTX, m_gbi->m_cmds, F3DEX2_Vtx ); + GBI_SetGBI( GBI::G_MODIFYVTX, F3DEX2_MODIFYVTX, m_gbi->m_cmds, UCode1::F3DEX_ModifyVtx ); + GBI_SetGBI( GBI::G_CULLDL, F3DEX2_CULLDL, m_gbi->m_cmds, UCode1::F3DEX_CullDL ); + GBI_SetGBI( GBI::G_BRANCH_Z, F3DEX2_BRANCH_Z, m_gbi->m_cmds, UCode1::F3DEX_Branch_Z ); + GBI_SetGBI( GBI::G_TRI1, F3DEX2_TRI1, m_gbi->m_cmds, F3DEX2_Tri1 ); + GBI_SetGBI( GBI::G_TRI2, F3DEX2_TRI2, m_gbi->m_cmds, UCode1::F3DEX_Tri2 ); + GBI_SetGBI( GBI::G_QUAD, F3DEX2_QUAD, m_gbi->m_cmds, F3DEX2_Quad ); + GBI_SetGBI( GBI::G_LINE3D, F3DEX2_LINE3D, m_gbi->m_cmds, F3DEX2_Line3D ); +} + +//***************************************************************************** +// Matrices +//***************************************************************************** + +//----------------------------------------------------------------------------- +//! Add Matrix +//! @todo Bomberman2 hack +//! @todo South park rally hack +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Mtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Mtx", M64MSG_VERBOSE); + RSPUCodeAddMatrixF3DEX2* temp = (RSPUCodeAddMatrixF3DEX2*)ucode; + + //TODO Bomberman2 hack + if( temp->param == 0 && temp->lenght == 0 ) + { + //Bomberman2TextRect(ucode); + Logger::getSingleton().printMsg("F3DEX2_Mtx - Bomberman2TextRect - Unimplemented", M64MSG_WARNING); + return; + } + + //Add Matrix + m_rsp->RSP_Matrix( temp->segmentAddress, temp->projection, !temp->nopush, temp->load ); + + //For Conker Bad Fur Day + m_rsp->getVertexMgr()->setConkerAddress(0); + + //TODO South park rally hack +} + +//----------------------------------------------------------------------------- +//! Pop Matrix +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_PopMtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_PopMtx", M64MSG_VERBOSE); + + m_rsp->RSP_PopMatrixN( ucode->w1 >> 6 ); +} + +//***************************************************************************** +//Textures +//***************************************************************************** + +//----------------------------------------------------------------------------- +//! Set Texture +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Texture( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Texture", M64MSG_VERBOSE); + + float scaleS = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 ); + float scaleT = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 ); + int level = _SHIFTR( ucode->w0, 11, 3 ); + int tile = _SHIFTR( ucode->w0, 8, 3 ); + int on = _SHIFTR( ucode->w0, 1, 7 ); + + m_rsp->RSP_Texture(scaleS, scaleT, level, tile, on); +} + +//***************************************************************************** +// Vertices and indices +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Vertices +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Vtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Vtx", M64MSG_VERBOSE); + RSPUCodeAddVerticesF3DEX2* temp = (RSPUCodeAddVerticesF3DEX2*)ucode; + + //Add Vertices + m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->vertexEnd - temp->numVertices); +} + +//----------------------------------------------------------------------------- +// Add 1 Triangle +//! @todo Add triangle flag +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Tri1( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Tri1", M64MSG_VERBOSE); + RSPUCodeAddOneTriangleF3DEX2* temp = (RSPUCodeAddOneTriangleF3DEX2*)ucode; + + //Add one triangle + m_rsp->RSP_1Triangle( temp->index0 / 2, temp->index1 / 2, temp->index2 / 2); //TODO flag +} + +//----------------------------------------------------------------------------- +// Add 1 Quad +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Quad( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Quad", M64MSG_VERBOSE); + RSPUCodeAddOneQuadF3DEX2* temp = (RSPUCodeAddOneQuadF3DEX2*)ucode; + + //Add two triangles + m_rsp->RSP_2Triangles( temp->v0 / 2, temp->v1 / 2, temp->v2 / 2, 0, + temp->v3 / 2, temp->v4 / 2, temp->v5 / 2, 0 ); +} + +//----------------------------------------------------------------------------- +// Render Line 3D +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Line3D( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Line3D - Unimplemented", M64MSG_WARNING); +} + + +//***************************************************************************** +// Misc +//***************************************************************************** + +//----------------------------------------------------------------------------- +// MoveMem +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_MoveMem( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_MoveMem", M64MSG_VERBOSE); + + switch (_SHIFTR( ucode->w0, 0, 8 )) + { + case F3DEX2_MV_VIEWPORT: + m_rsp->moveMemViewport( ucode->w1 ); + break; + case G_MV_MATRIX: + m_rsp->RSP_ForceMatrix( ucode->w1 ); + m_displayListParser->increasePC(8); // force matrix takes two commands + break; + case G_MV_LIGHT: + /* + unsigned int dwOffset2 = ((ucode->w0) >> 5) & 0x3FFF; + + switch (dwOffset2) + { + case 0x00: + { + s8 * pcBase = g_pRDRAMs8 + addr; + LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATX %f %f %f", + (float)pcBase[8 ^ 0x3], + (float)pcBase[9 ^ 0x3], + (float)pcBase[10 ^ 0x3]); + + } + break; + case 0x18: + { + s8 * pcBase = g_pRDRAMs8 + addr; + LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATY %f %f %f", + (float)pcBase[8 ^ 0x3], + (float)pcBase[9 ^ 0x3], + (float)pcBase[10 ^ 0x3]); + } + break; + default: //0x30/48/60 + { + uint32 dwLight = (dwOffset2 - 0x30)/0x18; + LOG_UCODE(" Light %d:", dwLight); + RSP_MoveMemLight(dwLight, addr); + } + break; + } + break; + */ + unsigned int offset = _SHIFTR( ucode->w0, 8, 8 ) << 3; + + if (offset >= 48) + { + m_rsp->RSP_Light( ((offset - 24) / 24) - 1, ucode->w1); + } + else + { + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("F3DEX2_MoveMem - Light - Unimplemented", M64MSG_WARNING); + warned = true; + } + } + + break; + } +} + +//----------------------------------------------------------------------------- +// Move Word +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_MoveWord(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX2_MoveWord", M64MSG_VERBOSE); + RSPUCodeMoveWordF3DEX2* temp = (RSPUCodeMoveWordF3DEX2*)ucode; + + switch ( temp->type ) + { + case G_MW_FORCEMTX: + Logger::getSingleton().printMsg("ForceMatrix - Unimplemented", M64MSG_WARNING); // Handled in movemem??? + break; + + case G_MW_MATRIX: + m_rsp->RSP_InsertMatrix( _SHIFTR( ucode->w0, 0, 16 ), ucode->w1 ); + break; + + case G_MW_NUMLIGHT: + m_rsp->RSP_NumLights(temp->value / 24); + break; + + case G_MW_SEGMENT: + m_rsp->moveSegment(temp->offset>>2, temp->value & 0x00FFFFFF); + break; + + case G_MW_CLIP: + //gSPClipRatio( ucode->w1 ); + break; + + case G_MW_FOG: + m_rsp->RSP_FogFactor( (short)temp->fm, (short)temp->fo); + break; + + case G_MW_PERSPNORM: + //gSPPerspNormalize( w1 ); + break; + + case G_MW_LIGHTCOL: + if ( (temp->offset & 0x7) == 0 ) + { + m_rsp->RSP_LightColor(temp->offset / 0x18, temp->value); + } + break; + } +} + +//----------------------------------------------------------------------------- +// Geometry Mode +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_GeometryMode( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_GeometryMode", M64MSG_VERBOSE); + //clear set + m_rsp->RSP_GeometryMode( ~_SHIFTR( ucode->w0, 0, 24 ), ucode->w1 ); +} + +//----------------------------------------------------------------------------- +//* Set Other Mode H +//! @todo more case in switch +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_SetOtherMode_H( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_H", M64MSG_VERBOSE); + + switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1)) + { + case G_MDSFT_CYCLETYPE: m_rdp->setCycleType( ucode->w1 >> G_MDSFT_CYCLETYPE ); break; + case G_MDSFT_TEXTLUT: m_rdp->setTextureLUT( ucode->w1 >> G_MDSFT_TEXTLUT ); break; + + //TODO + case G_MDSFT_PIPELINE: //m_rdp->setPiplineMode( w1 >> G_MDSFT_PIPELINE ); + break; + case G_MDSFT_TEXTPERSP: //m_rdp->setTexturePerspective( w1 >> G_MDSFT_TEXTPERSP ); + break; + case G_MDSFT_TEXTDETAIL: //m_rdp->setTextureDetail( w1 >> G_MDSFT_TEXTDETAIL ); + break; + case G_MDSFT_TEXTLOD: //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD ); + break; + case G_MDSFT_TEXTFILT: //gDPSetTextureFilter( w1 >> G_MDSFT_TEXTFILT ); + break; + case G_MDSFT_TEXTCONV: //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV ); + break; + case G_MDSFT_COMBKEY: //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY ); + break; + case G_MDSFT_RGBDITHER: //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER ); + break; + case G_MDSFT_ALPHADITHER: //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER ); + break; + default: + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L - Unknown type", M64MSG_WARNING); + + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1; + unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length; + unsigned int mask = ((1 << length) - 1) << shift; + + m_rdp->m_otherMode.h &= ~mask; + m_rdp->m_otherMode.h |= ucode->w1 & mask; + + m_rdp->setUpdateCombiner(true); + break; + } +} + +//----------------------------------------------------------------------------- +// Set Other Mode L +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_SetOtherMode_L( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L", M64MSG_VERBOSE); + + switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1)) + { + case G_MDSFT_ALPHACOMPARE: + m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE); + break; + case G_MDSFT_ZSRCSEL: + m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL ); + break; + case G_MDSFT_RENDERMODE: + m_rdp->setRenderMode( ucode->w1 ); + break; + default: + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1; + unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length; + unsigned int mask = ((1 << length) - 1) << shift; + m_rdp->m_otherMode.l &= ~mask; + m_rdp->m_otherMode.l |= ucode->w1 & mask; + break; + } +} + +//***************************************************************************** +// Other +//***************************************************************************** + +void UCode5::F3DEX2_DMAIO( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_DMAIO", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_1( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_1", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_2( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_2", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_3( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_3", M64MSG_VERBOSE); + //Ignore? +} + +//***************************************************************************** +// Unimportant Functions +//***************************************************************************** +void UCode5::F3DEX2_Reserved1(MicrocodeArgument* ucode) { + Logger::getSingleton().printMsg("F3DEX2_Reserved1", M64MSG_VERBOSE); + //Ignore +}