diff --git a/GBI.cpp b/GBI.cpp index 8ef79907..55470c5e 100644 --- a/GBI.cpp +++ b/GBI.cpp @@ -86,7 +86,6 @@ u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; -//GBIFunc GBICmd[256]; GBIInfo GBI; void GBI_Unknown( u32 w0, u32 w1 ) @@ -101,203 +100,33 @@ void GBI_Unknown( u32 w0, u32 w1 ) #endif } -MicrocodeInfo *GBI_AddMicrocode() +void GBIInfo::init() { - MicrocodeInfo *newtop = (MicrocodeInfo*)malloc( sizeof( MicrocodeInfo ) ); - - newtop->lower = GBI.top; - newtop->higher = NULL; - - if (GBI.top) - GBI.top->higher = newtop; - - if (!GBI.bottom) - GBI.bottom = newtop; - - GBI.top = newtop; - - GBI.numMicrocodes++; - - return newtop; + m_pCurrent = NULL; + for (u32 i = 0; i <= 0xFF; ++i) + cmd[i] = GBI_Unknown; } -void GBI_Init() +void GBIInfo::destroy() { - GBI.top = NULL; - GBI.bottom = NULL; - GBI.current = NULL; - GBI.numMicrocodes = 0; - - for (u32 i = 0; i <= 0xFF; i++) - GBI.cmd[i] = GBI_Unknown; + m_pCurrent = NULL; + m_list.clear(); } -void GBI_Destroy() +void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent) { - GBI.current = NULL; - while (GBI.bottom) - { - MicrocodeInfo *newBottom = GBI.bottom->higher; - - if (GBI.bottom == GBI.top) - GBI.top = NULL; - - free( GBI.bottom ); - - GBI.bottom = newBottom; - - if (GBI.bottom) - GBI.bottom->lower = NULL; - - GBI.numMicrocodes--; - } -} - -int MicrocodeDialog(u32 _crc, const char * _str); - -MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) -{ - MicrocodeInfo *current; - - for (u32 i = 0; i < GBI.numMicrocodes; i++) - { - current = GBI.top; - - while (current) - { - if ((current->address == uc_start) && (current->dataAddress == uc_dstart) && (current->dataSize == uc_dsize)) - return current; - - current = current->lower; - } + if (_pCurrent->type == NONE) { + LOG(LOG_ERROR, "[GLideN64]: error - unknown ucode!!!\n"); + return; } - current = GBI_AddMicrocode(); - - current->address = uc_start; - current->dataAddress = uc_dstart; - current->dataSize = uc_dsize; - current->NoN = FALSE; - current->type = NONE; - - // See if we can identify it by CRC - u32 uc_crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[uc_start & 0x1FFFFFFF], 4096 ); - for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++) - { - if (uc_crc == specialMicrocodes[i].crc) - { - current->type = specialMicrocodes[i].type; - return current; - } - } - - // See if we can identify it by text - char uc_data[2048]; - UnswapCopy( &RDRAM[uc_dstart & 0x1FFFFFFF], uc_data, 2048 ); - char uc_str[256]; - strcpy( uc_str, "Not Found" ); - - for (u32 i = 0; i < 2048; i++) - { - if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P')) - { - u32 j = 0; - while (uc_data[i+j] > 0x0A) - { - uc_str[j] = uc_data[i+j]; - j++; - } - - uc_str[j] = 0x00; - - int type = NONE; - - if (strncmp( &uc_str[4], "SW", 2 ) == 0) - { - type = F3D; - } - else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0) - { - current->NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0); - - if (strncmp( &uc_str[14], "F3D", 3 ) == 0) - { - if (uc_str[28] == '1' || strncmp(&uc_str[28], "0.95", 4) == 0) - type = F3DEX; - else if (uc_str[31] == '2') - type = F3DEX2; - } - else if (strncmp( &uc_str[14], "L3D", 3 ) == 0) - { - if (uc_str[28] == '1') - type = L3DEX; - else if (uc_str[31] == '2') - type = L3DEX2; - } - else if (strncmp( &uc_str[14], "S2D", 3 ) == 0) - { - if (uc_str[28] == '1') - type = S2DEX; - else if (uc_str[31] == '2') - type = S2DEX2; - } - } - - if (type != NONE) - { - current->type = type; - return current; - } - - break; - } - } - - for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++) - { - if (strcmp( uc_str, specialMicrocodes[i].text ) == 0) - { - current->type = specialMicrocodes[i].type; - return current; - } - } - - printf( "GLideN64: Warning - unknown ucode!!!\n" ); - LOG(LOG_ERROR, "[GLideN64]: Warning - unknown ucode!!!\n"); - current->type = MicrocodeDialog(uc_crc, uc_str); - return current; -} - -void GBI_MakeCurrent( MicrocodeInfo *current ) -{ - if (current != GBI.top) - { - if (current == GBI.bottom) - { - GBI.bottom = current->higher; - GBI.bottom->lower = NULL; - } - else - { - current->higher->lower = current->lower; - current->lower->higher = current->higher; - } - - current->higher = NULL; - current->lower = GBI.top; - GBI.top->higher = current; - GBI.top = current; - } - - if (!GBI.current || (GBI.current->type != current->type)) - { - for (int i = 0; i <= 0xFF; i++) - GBI.cmd[i] = GBI_Unknown; + if (m_pCurrent == NULL || (m_pCurrent->type != _pCurrent->type)) { + for (int i = 0; i <= 0xFF; ++i) + cmd[i] = GBI_Unknown; RDP_Init(); - switch (current->type) - { + switch (_pCurrent->type) { case F3D: F3D_Init(); break; case F3DEX: F3DEX_Init(); break; case F3DEX2: F3DEX2_Init(); break; @@ -312,5 +141,103 @@ void GBI_MakeCurrent( MicrocodeInfo *current ) } } - GBI.current = current; + m_pCurrent = _pCurrent; +} + +int MicrocodeDialog(u32 _crc, const char * _str); +void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize) +{ + for (Microcodes::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + if (iter->address == uc_start && iter->dataAddress == uc_dstart && iter->dataSize == uc_dsize) { + _makeCurrent(&(*iter)); + return; + } + } + + m_list.emplace_front(); + MicrocodeInfo & current = m_list.front(); + current.address = uc_start; + current.dataAddress = uc_dstart; + current.dataSize = uc_dsize; + current.NoN = false; + current.type = NONE; + + // See if we can identify it by CRC + const u32 uc_crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[uc_start & 0x1FFFFFFF], 4096 ); + const u32 numSpecialMicrocodes = sizeof(specialMicrocodes) / sizeof(SpecialMicrocodeInfo); + for (u32 i = 0; i < numSpecialMicrocodes; ++i) { + if (uc_crc == specialMicrocodes[i].crc) { + current.type = specialMicrocodes[i].type; + _makeCurrent(¤t); + return; + } + } + + // See if we can identify it by text + char uc_data[2048]; + UnswapCopy( &RDRAM[uc_dstart & 0x1FFFFFFF], uc_data, 2048 ); + char uc_str[256]; + strcpy(uc_str, "Not Found"); + + for (u32 i = 0; i < 2048; ++i) { + if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P')) { + u32 j = 0; + while (uc_data[i+j] > 0x0A) { + uc_str[j] = uc_data[i+j]; + j++; + } + + uc_str[j] = 0x00; + + int type = NONE; + + if (strncmp( &uc_str[4], "SW", 2 ) == 0) + type = F3D; + else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0) { + current.NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0); + + if (strncmp( &uc_str[14], "F3D", 3 ) == 0) { + if (uc_str[28] == '1' || strncmp(&uc_str[28], "0.95", 4) == 0) + type = F3DEX; + else if (uc_str[31] == '2') + type = F3DEX2; + } + else if (strncmp( &uc_str[14], "L3D", 3 ) == 0) { + if (uc_str[28] == '1') + type = L3DEX; + else if (uc_str[31] == '2') + type = L3DEX2; + } + else if (strncmp( &uc_str[14], "S2D", 3 ) == 0) { + if (uc_str[28] == '1') + type = S2DEX; + else if (uc_str[31] == '2') + type = S2DEX2; + } + } + + if (type != NONE) { + current.type = type; + _makeCurrent(¤t); + return; + } + + break; + } + } + + for (u32 i = 0; i < numSpecialMicrocodes; ++i) { + if (strcmp( uc_str, specialMicrocodes[i].text ) == 0) { + current.type = specialMicrocodes[i].type; + _makeCurrent(¤t); + return; + } + } + + printf( "GLideN64: Warning - unknown ucode!!!\n" ); + const int type = MicrocodeDialog(uc_crc, uc_str); + if (type >= F3D && type <= NONE) + current.type = type; + + _makeCurrent(¤t); } diff --git a/GBI.h b/GBI.h index 5b306a91..036eb9ad 100644 --- a/GBI.h +++ b/GBI.h @@ -1,5 +1,8 @@ #ifndef GBI_H #define GBI_H + +#include + #include "Types.h" // Microcode Types @@ -16,22 +19,6 @@ #define F3DWRUS 10 #define NONE 11 -static const char *MicrocodeTypes[] = -{ - "Fast3D", - "F3DEX", - "F3DEX2", - "Line3D", - "L3DEX", - "L3DEX2", - "S2DEX", - "S2DEX2", - "Perfect Dark", - "DKR/JFG", - "Waverace US", - "None" -}; - // Fixed point conversion factors #define FIXED2FLOATRECIP1 0.5f #define FIXED2FLOATRECIP2 0.25f @@ -681,28 +668,31 @@ struct MicrocodeInfo u32 address, dataAddress; u16 dataSize; u32 type; - u32 NoN; u32 crc; - - MicrocodeInfo *higher, *lower; + bool NoN; }; struct GBIInfo { GBIFunc cmd[256]; - u32 PCStackSize, numMicrocodes; - MicrocodeInfo *current, *top, *bottom; + u32 PCStackSize; + + void init(); + void destroy(); + void loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize); + +private: + void _makeCurrent(MicrocodeInfo * _pCurrent); + + MicrocodeInfo * m_pCurrent; + + typedef std::list Microcodes; + Microcodes m_list; }; extern GBIInfo GBI; -void GBI_MakeCurrent( MicrocodeInfo *current ); -MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize ); -extern u32 last_good_ucode; -void GBI_Init(); -void GBI_Destroy(); - // Allows easier setting of GBI commands #define GBI_SetGBI( command, value, function ) \ command = value; \ diff --git a/RSP.cpp b/RSP.cpp index 2d9785ea..5ad39f2e 100644 --- a/RSP.cpp +++ b/RSP.cpp @@ -253,6 +253,6 @@ void RSP_Init() gSP.textureTile[0] = &gDP.tiles[0]; gSP.textureTile[1] = &gDP.tiles[1]; // DepthBuffer_Init(); - GBI_Init(); + GBI.init(); video().start(); } diff --git a/common/CommonAPIImpl_common.cpp b/common/CommonAPIImpl_common.cpp index befa7600..f20bed12 100644 --- a/common/CommonAPIImpl_common.cpp +++ b/common/CommonAPIImpl_common.cpp @@ -37,7 +37,7 @@ void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx, break; case acRomClosed: video().stop(); - GBI_Destroy(); + GBI.destroy(); *_pCommand = acNone; _pRspThreadMtx->unlock(); _pPluginThreadMtx->lock(); @@ -81,6 +81,7 @@ void PluginAPI::RomClosed() m_pRspThread = NULL; #else video().stop(); + GBI.destroy(); #endif #ifdef DEBUG diff --git a/gSP.cpp b/gSP.cpp index 645aeb7d..445c5b4c 100644 --- a/gSP.cpp +++ b/gSP.cpp @@ -356,15 +356,7 @@ void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize)) return; - MicrocodeInfo *ucode = GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize ); - - if (ucode->type != 0xFFFFFFFF) - last_good_ucode = ucode->type; - - if (ucode->type != NONE) - GBI_MakeCurrent( ucode ); - else - LOG(LOG_WARNING, "Unknown Ucode\n"); + GBI.loadMicrocode(uc_start, uc_dstart, uc_dsize); } void gSPNoOp() diff --git a/mupenplus/MicrocodeDialog.cpp b/mupenplus/MicrocodeDialog.cpp index 0c2d69fe..23c60333 100644 --- a/mupenplus/MicrocodeDialog.cpp +++ b/mupenplus/MicrocodeDialog.cpp @@ -3,6 +3,5 @@ int MicrocodeDialog(unsigned int /*_crc*/, const char * /*_str*/) { - assert(last_good_ucode != (unsigned int)-1 && "Unknown microcode!"); - return last_good_ucode; + return NONE; } diff --git a/windows/MicrocodeDialog.cpp b/windows/MicrocodeDialog.cpp index 339b1604..a2b88f8f 100644 --- a/windows/MicrocodeDialog.cpp +++ b/windows/MicrocodeDialog.cpp @@ -5,6 +5,22 @@ #include "../GBI.h" #include "../Resource.h" +static const char *MicrocodeTypes[] = +{ + "Fast3D", + "F3DEX", + "F3DEX2", + "Line3D", + "L3DEX", + "L3DEX2", + "S2DEX", + "S2DEX2", + "Perfect Dark", + "DKR/JFG", + "Waverace US", + "None" +}; + static const int numMicrocodeTypes = 11; static unsigned int uc_crc; static const char * uc_str;