diff --git a/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp index 8d8330ec32..2f68b17153 100644 --- a/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp @@ -4,10 +4,10 @@ #include "Core/FifoPlayer/FifoAnalyzer.h" -#include #include #include "Common/Assert.h" +#include "Common/MsgHandler.h" #include "Common/Swap.h" #include "Core/FifoPlayer/FifoRecordAnalyzer.h" @@ -20,30 +20,141 @@ namespace FifoAnalyzer { -bool s_DrawingObject; -FifoAnalyzer::CPMemory s_CpMem; - +namespace +{ u8 ReadFifo8(const u8*& data) { - u8 value = data[0]; + const u8 value = data[0]; data += 1; return value; } u16 ReadFifo16(const u8*& data) { - u16 value = Common::swap16(data); + const u16 value = Common::swap16(data); data += 2; return value; } u32 ReadFifo32(const u8*& data) { - u32 value = Common::swap32(data); + const u32 value = Common::swap32(data); data += 4; return value; } +std::array CalculateVertexElementSizes(int vatIndex, const CPMemory& cpMem) +{ + const TVtxDesc& vtxDesc = cpMem.vtxDesc; + const VAT& vtxAttr = cpMem.vtxAttr[vatIndex]; + + // Colors + const std::array colDesc{ + vtxDesc.Color0, + vtxDesc.Color1, + }; + const std::array colComp{ + vtxAttr.g0.Color0Comp, + vtxAttr.g0.Color1Comp, + }; + + const std::array tcElements{ + vtxAttr.g0.Tex0CoordElements, vtxAttr.g1.Tex1CoordElements, vtxAttr.g1.Tex2CoordElements, + vtxAttr.g1.Tex3CoordElements, vtxAttr.g1.Tex4CoordElements, vtxAttr.g2.Tex5CoordElements, + vtxAttr.g2.Tex6CoordElements, vtxAttr.g2.Tex7CoordElements, + }; + const std::array tcFormat{ + vtxAttr.g0.Tex0CoordFormat, vtxAttr.g1.Tex1CoordFormat, vtxAttr.g1.Tex2CoordFormat, + vtxAttr.g1.Tex3CoordFormat, vtxAttr.g1.Tex4CoordFormat, vtxAttr.g2.Tex5CoordFormat, + vtxAttr.g2.Tex6CoordFormat, vtxAttr.g2.Tex7CoordFormat, + }; + + std::array sizes{}; + + // Add position and texture matrix indices + u64 vtxDescHex = cpMem.vtxDesc.Hex; + for (int i = 0; i < 9; ++i) + { + sizes[i] = vtxDescHex & 1; + vtxDescHex >>= 1; + } + + // Position + sizes[9] = VertexLoader_Position::GetSize(vtxDesc.Position, vtxAttr.g0.PosFormat, + vtxAttr.g0.PosElements); + + // Normals + if (vtxDesc.Normal != NOT_PRESENT) + { + sizes[10] = VertexLoader_Normal::GetSize(vtxDesc.Normal, vtxAttr.g0.NormalFormat, + vtxAttr.g0.NormalElements, vtxAttr.g0.NormalIndex3); + } + else + { + sizes[10] = 0; + } + + // Colors + for (size_t i = 0; i < colDesc.size(); i++) + { + int size = 0; + + switch (colDesc[i]) + { + case NOT_PRESENT: + break; + case DIRECT: + switch (colComp[i]) + { + case FORMAT_16B_565: + size = 2; + break; + case FORMAT_24B_888: + size = 3; + break; + case FORMAT_32B_888x: + size = 4; + break; + case FORMAT_16B_4444: + size = 2; + break; + case FORMAT_24B_6666: + size = 3; + break; + case FORMAT_32B_8888: + size = 4; + break; + default: + ASSERT(0); + break; + } + break; + case INDEX8: + size = 1; + break; + case INDEX16: + size = 2; + break; + } + + sizes[11 + i] = size; + } + + // Texture coordinates + vtxDescHex = vtxDesc.Hex >> 17; + for (size_t i = 0; i < tcFormat.size(); i++) + { + sizes[13 + i] = VertexLoader_TextCoord::GetSize(vtxDescHex & 3, tcFormat[i], tcElements[i]); + vtxDescHex >>= 2; + } + + return sizes; +} +} // Anonymous namespace + +bool s_DrawingObject; +FifoAnalyzer::CPMemory s_CpMem; + u32 AnalyzeCommand(const u8* data, DecodeMode mode) { const u8* dataStart = data; @@ -88,7 +199,7 @@ u32 AnalyzeCommand(const u8* data, DecodeMode mode) int array = 0xc + (cmd - OpcodeDecoder::GX_LOAD_INDX_A) / 8; u32 value = ReadFifo32(data); - if (mode == DECODE_RECORD) + if (mode == DecodeMode::Record) FifoRecordAnalyzer::ProcessLoadIndexedXf(value, array); break; } @@ -113,27 +224,28 @@ u32 AnalyzeCommand(const u8* data, DecodeMode mode) { s_DrawingObject = true; - int sizes[21]; - CalculateVertexElementSizes(sizes, cmd & OpcodeDecoder::GX_VAT_MASK, s_CpMem); + const std::array sizes = + CalculateVertexElementSizes(cmd & OpcodeDecoder::GX_VAT_MASK, s_CpMem); // Determine offset of each element that might be a vertex array // The first 9 elements are never vertex arrays so we just accumulate their sizes. - int offsets[12]; - int offset = std::accumulate(&sizes[0], &sizes[9], 0u); - for (int i = 0; i < 12; ++i) + int offset = std::accumulate(sizes.begin(), sizes.begin() + 9, 0u); + std::array offsets; + for (size_t i = 0; i < offsets.size(); ++i) { offsets[i] = offset; offset += sizes[i + 9]; } - int vertexSize = offset; - int numVertices = ReadFifo16(data); + const int vertexSize = offset; + const int numVertices = ReadFifo16(data); - if (mode == DECODE_RECORD && numVertices > 0) + if (mode == DecodeMode::Record && numVertices > 0) { - for (int i = 0; i < 12; ++i) + for (size_t i = 0; i < offsets.size(); ++i) { - FifoRecordAnalyzer::WriteVertexArray(i, data + offsets[i], vertexSize, numVertices); + FifoRecordAnalyzer::WriteVertexArray(static_cast(i), data + offsets[i], vertexSize, + numVertices); } } @@ -188,101 +300,4 @@ void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem) break; } } - -void CalculateVertexElementSizes(int sizes[], int vatIndex, const CPMemory& cpMem) -{ - const TVtxDesc& vtxDesc = cpMem.vtxDesc; - const VAT& vtxAttr = cpMem.vtxAttr[vatIndex]; - - // Colors - const u64 colDesc[2] = {vtxDesc.Color0, vtxDesc.Color1}; - const u32 colComp[2] = {vtxAttr.g0.Color0Comp, vtxAttr.g0.Color1Comp}; - - const u32 tcElements[8] = {vtxAttr.g0.Tex0CoordElements, vtxAttr.g1.Tex1CoordElements, - vtxAttr.g1.Tex2CoordElements, vtxAttr.g1.Tex3CoordElements, - vtxAttr.g1.Tex4CoordElements, vtxAttr.g2.Tex5CoordElements, - vtxAttr.g2.Tex6CoordElements, vtxAttr.g2.Tex7CoordElements}; - - const u32 tcFormat[8] = {vtxAttr.g0.Tex0CoordFormat, vtxAttr.g1.Tex1CoordFormat, - vtxAttr.g1.Tex2CoordFormat, vtxAttr.g1.Tex3CoordFormat, - vtxAttr.g1.Tex4CoordFormat, vtxAttr.g2.Tex5CoordFormat, - vtxAttr.g2.Tex6CoordFormat, vtxAttr.g2.Tex7CoordFormat}; - - // Add position and texture matrix indices - u64 vtxDescHex = cpMem.vtxDesc.Hex; - for (int i = 0; i < 9; ++i) - { - sizes[i] = vtxDescHex & 1; - vtxDescHex >>= 1; - } - - // Position - sizes[9] = VertexLoader_Position::GetSize(vtxDesc.Position, vtxAttr.g0.PosFormat, - vtxAttr.g0.PosElements); - - // Normals - if (vtxDesc.Normal != NOT_PRESENT) - { - sizes[10] = VertexLoader_Normal::GetSize(vtxDesc.Normal, vtxAttr.g0.NormalFormat, - vtxAttr.g0.NormalElements, vtxAttr.g0.NormalIndex3); - } - else - { - sizes[10] = 0; - } - - // Colors - for (int i = 0; i < 2; i++) - { - int size = 0; - - switch (colDesc[i]) - { - case NOT_PRESENT: - break; - case DIRECT: - switch (colComp[i]) - { - case FORMAT_16B_565: - size = 2; - break; - case FORMAT_24B_888: - size = 3; - break; - case FORMAT_32B_888x: - size = 4; - break; - case FORMAT_16B_4444: - size = 2; - break; - case FORMAT_24B_6666: - size = 3; - break; - case FORMAT_32B_8888: - size = 4; - break; - default: - ASSERT(0); - break; - } - break; - case INDEX8: - size = 1; - break; - case INDEX16: - size = 2; - break; - } - - sizes[11 + i] = size; - } - - // Texture coordinates - vtxDescHex = vtxDesc.Hex >> 17; - for (int i = 0; i < 8; i++) - { - sizes[13 + i] = VertexLoader_TextCoord::GetSize(vtxDescHex & 3, tcFormat[i], tcElements[i]); - vtxDescHex >>= 2; - } -} } // namespace FifoAnalyzer diff --git a/Source/Core/Core/FifoPlayer/FifoAnalyzer.h b/Source/Core/Core/FifoPlayer/FifoAnalyzer.h index 41054b7738..5f1d883ba2 100644 --- a/Source/Core/Core/FifoPlayer/FifoAnalyzer.h +++ b/Source/Core/Core/FifoPlayer/FifoAnalyzer.h @@ -4,20 +4,17 @@ #pragma once -#include "Common/CommonTypes.h" +#include +#include "Common/CommonTypes.h" #include "VideoCommon/CPMemory.h" namespace FifoAnalyzer { -u8 ReadFifo8(const u8*& data); -u16 ReadFifo16(const u8*& data); -u32 ReadFifo32(const u8*& data); - -enum DecodeMode +enum class DecodeMode { - DECODE_RECORD, - DECODE_PLAYBACK, + Record, + Playback, }; u32 AnalyzeCommand(const u8* data, DecodeMode mode); @@ -25,15 +22,13 @@ u32 AnalyzeCommand(const u8* data, DecodeMode mode); struct CPMemory { TVtxDesc vtxDesc; - VAT vtxAttr[8]; - u32 arrayBases[16]; - u32 arrayStrides[16]; + std::array vtxAttr; + std::array arrayBases; + std::array arrayStrides; }; void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem); -void CalculateVertexElementSizes(int sizes[], int vatIndex, const CPMemory& cpMem); - extern bool s_DrawingObject; extern FifoAnalyzer::CPMemory s_CpMem; } // namespace FifoAnalyzer diff --git a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp index 0458fe2fde..4b8da762bc 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp @@ -63,9 +63,9 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile* file, ++nextMemUpdate; } - bool wasDrawing = s_DrawingObject; - - u32 cmdSize = FifoAnalyzer::AnalyzeCommand(&frame.fifoData[cmdStart], DECODE_PLAYBACK); + const bool wasDrawing = s_DrawingObject; + const u32 cmdSize = + FifoAnalyzer::AnalyzeCommand(&frame.fifoData[cmdStart], DecodeMode::Playback); #if LOG_FIFO_CMDS CmdData cmdData; diff --git a/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp index d57637076e..284ecba620 100644 --- a/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp @@ -5,7 +5,6 @@ #include "Core/FifoPlayer/FifoRecordAnalyzer.h" #include -#include #include "Core/FifoPlayer/FifoAnalyzer.h" #include "Core/FifoPlayer/FifoRecorder.h" @@ -22,8 +21,13 @@ void FifoRecordAnalyzer::Initialize(const u32* cpMem) for (int i = 0; i < 8; ++i) FifoAnalyzer::LoadCPReg(0x70 + i, *(cpMem + 0x70 + i), s_CpMem); - memcpy(s_CpMem.arrayBases, cpMem + 0xA0, 16 * 4); - memcpy(s_CpMem.arrayStrides, cpMem + 0xB0, 16 * 4); + const u32* const bases_start = cpMem + 0xA0; + const u32* const bases_end = bases_start + s_CpMem.arrayBases.size(); + std::copy(bases_start, bases_end, s_CpMem.arrayBases.begin()); + + const u32* const strides_start = cpMem + 0xB0; + const u32* const strides_end = strides_start + s_CpMem.arrayStrides.size(); + std::copy(strides_start, strides_end, s_CpMem.arrayStrides.begin()); } void FifoRecordAnalyzer::ProcessLoadIndexedXf(u32 val, int array) diff --git a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp index f85eeb9aef..96329d695b 100644 --- a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp +++ b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp @@ -77,12 +77,14 @@ void FifoRecorder::WriteGPCommand(const u8* data, u32 size) { // Assumes data contains all information for the command // Calls FifoRecorder::UseMemory - u32 analyzed_size = FifoAnalyzer::AnalyzeCommand(data, FifoAnalyzer::DECODE_RECORD); + const u32 analyzed_size = FifoAnalyzer::AnalyzeCommand(data, FifoAnalyzer::DecodeMode::Record); // Make sure FifoPlayer's command analyzer agrees about the size of the command. if (analyzed_size != size) + { PanicAlert("FifoRecorder: Expected command to be %i bytes long, we were given %i bytes", analyzed_size, size); + } // Copy data to buffer size_t currentSize = m_FifoData.size();