mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
Extended -gfx-state to produce culling node analysis
This commit is contained in:
parent
9dd2b24729
commit
76817790d4
|
@ -162,11 +162,6 @@
|
|||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef DEBUG
|
||||
extern bool g_forceFlushModels;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Legacy3D {
|
||||
|
||||
// Microsoft doesn't provide isnan() and isinf()
|
||||
|
@ -668,9 +663,13 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
|
|||
m_colorTableAddr &= 0x000FFFFF; // clamp to 4MB (in words) range
|
||||
}
|
||||
|
||||
//printf("%08x NODE %d\n", addr, stackDepth);
|
||||
//for (int i = 0; i < 8; i++)
|
||||
// printf(" %08x\n", node[i]);
|
||||
#ifdef DEBUG
|
||||
bool oldDebugHighlightAll = m_debugHighlightAll;
|
||||
m_debugHighlightAll = (m_debugHighlightCullingNodeIdx >= 0) && (node[m_debugHighlightCullingNodeIdx] & m_debugHighlightCullingNodeMask) != 0;
|
||||
#endif
|
||||
//printf("%08x NODE %d\n", addr, stackDepth);
|
||||
//for (int i = 0; i < 8; i++)
|
||||
// printf(" %08x\n", node[i]);
|
||||
|
||||
// Debug: texture offset? (NOTE: offsets 1 and 2 don't exist on step 1.0)
|
||||
//if (node[0x02]&0xFFFF)
|
||||
|
@ -716,6 +715,9 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
|
|||
|
||||
// Proceed to second link
|
||||
glPopMatrix();
|
||||
#ifdef DEBUG
|
||||
m_debugHighlightAll = oldDebugHighlightAll;
|
||||
#endif
|
||||
if ((node[0x00] & 0x07) != 0x06) // seems to indicate second link is invalid (fixes circular references)
|
||||
DescendNodePtr(node2Ptr);
|
||||
--stackDepth;
|
||||
|
@ -1001,7 +1003,11 @@ void CLegacy3D::RenderFrame(void)
|
|||
|
||||
// Draw
|
||||
#ifdef DEBUG
|
||||
if (g_forceFlushModels)
|
||||
m_debugHighlightPolyHeaderIdx = m_config["Debug/HighlightPolyHeaderIdx"].ValueAsDefault<int>(-1);
|
||||
m_debugHighlightPolyHeaderMask = m_config["Debug/HighlightPolyHeaderMask"].ValueAsDefault<uint32_t>(0);
|
||||
m_debugHighlightCullingNodeIdx = m_config["Debug/HighlightCullingNodeIdx"].ValueAsDefault<int>(-1);
|
||||
m_debugHighlightCullingNodeMask = m_config["Debug/HighlightCullingNodeMask"].ValueAsDefault<uint32_t>(0);
|
||||
if (m_config["Debug/ForceFlushModels"].ValueAsDefault<bool>(false))
|
||||
ClearModelCache(&VROMCache);
|
||||
#endif
|
||||
ClearModelCache(&PolyCache);
|
||||
|
|
|
@ -390,6 +390,15 @@ private:
|
|||
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Debug
|
||||
int m_debugHighlightPolyHeaderIdx = -1;
|
||||
uint32_t m_debugHighlightPolyHeaderMask = 0;
|
||||
int m_debugHighlightCullingNodeIdx = -1;
|
||||
uint32_t m_debugHighlightCullingNodeMask = 0;
|
||||
bool m_debugHighlightAll = false;
|
||||
#endif
|
||||
|
||||
// Stepping
|
||||
int step;
|
||||
int offset; // offset to subtract for words 3 and higher of culling nodes
|
||||
|
|
|
@ -754,9 +754,9 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
|||
contourProcessing = 1.0f;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (g_testPolyHeaderIdx >= 0)
|
||||
if (m_debugHighlightPolyHeaderIdx >= 0 || m_debugHighlightAll)
|
||||
{
|
||||
if ((P->header[g_testPolyHeaderIdx] & g_testPolyHeaderMask))
|
||||
if ((P->header[m_debugHighlightPolyHeaderIdx] & m_debugHighlightPolyHeaderMask) || m_debugHighlightAll)
|
||||
{
|
||||
r = 0.;
|
||||
g = 1.;
|
||||
|
|
|
@ -410,9 +410,6 @@ static void SaveFrameBuffer(const std::string &file)
|
|||
Util::WriteSurfaceToBMP<Util::RGBA8>(file, pixels.get(), totalXRes, totalYRes, true);
|
||||
}
|
||||
|
||||
bool g_forceFlushModels = false;
|
||||
int g_testPolyHeaderIdx = -1;
|
||||
uint32_t g_testPolyHeaderMask = 0;
|
||||
static std::string s_gfxStatePath;
|
||||
|
||||
static std::string GetFileBaseName(const std::string &file)
|
||||
|
@ -439,24 +436,54 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
|||
0xffffff60,
|
||||
0xff0300ff // contour, luminous, etc.
|
||||
};
|
||||
|
||||
const std::vector<uint32_t> unknownCullingNodeBits
|
||||
{
|
||||
0xffffffff,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
GLint readBuffer;
|
||||
glGetIntegerv(GL_READ_BUFFER, &readBuffer);
|
||||
glReadBuffer(GL_FRONT);
|
||||
|
||||
// Render separate image for each unknown bit
|
||||
g_forceFlushModels = true;
|
||||
s_runtime_config.Set("Debug/ForceFlushModels", true);
|
||||
for (int idx = 0; idx < 7; idx++)
|
||||
{
|
||||
for (int bit = 0; bit < 32; bit++)
|
||||
{
|
||||
uint32_t mask = 1 << bit;
|
||||
g_testPolyHeaderIdx = idx;
|
||||
g_testPolyHeaderMask = mask;
|
||||
s_runtime_config.Set("Debug/HighlightPolyHeaderIdx", idx);
|
||||
s_runtime_config.Set("Debug/HighlightPolyHeaderMask", mask);
|
||||
if ((unknownPolyBits[idx] & mask))
|
||||
{
|
||||
Emu->RenderFrame();
|
||||
std::string file = Util::Format() << "Analysis/" << GetFileBaseName(s_gfxStatePath) << "." << idx << "_" << Util::Hex(mask) << ".bmp";
|
||||
std::string file = Util::Format() << "Analysis/" << GetFileBaseName(s_gfxStatePath) << "." << "poly" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
|
||||
SaveFrameBuffer(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < 10; idx++)
|
||||
{
|
||||
for (int bit = 0; bit < 32; bit++)
|
||||
{
|
||||
uint32_t mask = 1 << bit;
|
||||
s_runtime_config.Set("Debug/HighlightCullingNodeIdx", idx);
|
||||
s_runtime_config.Set("Debug/HighlightCullingNodeMask", mask);
|
||||
if ((unknownCullingNodeBits[idx] & mask))
|
||||
{
|
||||
Emu->RenderFrame();
|
||||
std::string file = Util::Format() << "Analysis/" << GetFileBaseName(s_gfxStatePath) << "." << "culling" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
|
||||
SaveFrameBuffer(file);
|
||||
}
|
||||
}
|
||||
|
@ -473,7 +500,8 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
|||
{
|
||||
std::string contents = s_polyAnalysisHTMLPrologue;
|
||||
contents += " var g_file_base_name = '" + GetFileBaseName(s_gfxStatePath) + "';\n";
|
||||
contents += " var g_unknown_bits = [" + std::string(Util::Format(",").Join(unknownPolyBits)) + "];\n";
|
||||
contents += " var g_unknown_poly_bits = [" + std::string(Util::Format(",").Join(unknownPolyBits)) + "];\n";
|
||||
contents += " var g_unknown_culling_bits = [" + std::string(Util::Format(",").Join(unknownCullingNodeBits)) + "];\n";
|
||||
contents += s_polyAnalysisHTMLEpilogue;
|
||||
fs << contents;
|
||||
printf("Produced: %s\n", file.c_str());
|
||||
|
|
|
@ -33,6 +33,7 @@ static const char s_polyAnalysisHTMLPrologue[] =
|
|||
"<html>\n"
|
||||
"<head>\n"
|
||||
" <style>\n"
|
||||
" left { float: left; }\n"
|
||||
" table { table-layout: fixed; }\n"
|
||||
" td { border: 1px solid black; width: 1em; }\n"
|
||||
" td.nonselectable { background-color: gray; }\n"
|
||||
|
@ -42,10 +43,13 @@ static const char s_polyAnalysisHTMLPrologue[] =
|
|||
" <script src='https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js'></script>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
" <div id='Header'></div>\n"
|
||||
" <div id='Header'>\n"
|
||||
" <div id='PolyBits' class='left'></div>\n"
|
||||
" <div id='CullingBits' class='left'></div>\n"
|
||||
" </div>\n"
|
||||
" <div><img id='Image' /></div>\n"
|
||||
" <script>\n"
|
||||
// Insert g_file_base_name and g_unknown bits here, then append epilogue
|
||||
// Insert g_file_base_name, g_unknown_poly_bits, and g_unknown_culling_bits here, then append epilogue
|
||||
};
|
||||
|
||||
static const char s_polyAnalysisHTMLEpilogue[] =
|
||||
|
@ -54,27 +58,28 @@ static const char s_polyAnalysisHTMLEpilogue[] =
|
|||
" {\n"
|
||||
" return '0x' + ('0000000'+Number(val).toString(16)).slice(-8);\n"
|
||||
" }\n"
|
||||
" function getOnClickHandler(table, td, word, mask)\n"
|
||||
|
||||
" function createOnClickHandler(type, table, td, word, mask)\n"
|
||||
" {\n"
|
||||
" return function()\n"
|
||||
" {\n"
|
||||
" var file = g_file_base_name + '.' + word + '_' + hex32(mask) + '.bmp';\n"
|
||||
" table.find('td').removeClass('selected'); // remove from all cells\n"
|
||||
" var file = g_file_base_name + '.' + type + '.' + word + '_' + hex32(mask) + '.bmp';\n"
|
||||
" $('td').removeClass('selected'); // remove from all cells\n"
|
||||
" td.addClass('selected');\n"
|
||||
" $('#Image').empty();\n"
|
||||
" $('#Image').attr('src', file);\n"
|
||||
" };\n"
|
||||
" }\n"
|
||||
" $(document).ready(function()\n"
|
||||
|
||||
" function buildTable(num_words, type, unknown_bits)\n"
|
||||
" {\n"
|
||||
" // Construct table\n"
|
||||
" var table = $('<table></table>');\n"
|
||||
" var bits_tr = $('<tr></tr>'); // first row will be bit legend\n"
|
||||
" bits_tr.append($('<td></td>')); // column for word numbers\n"
|
||||
" for (var bit = 31; bit >= 0; bit--)\n"
|
||||
" bits_tr.append($('<td>'+bit+'</td>'));\n"
|
||||
" table.append(bits_tr);\n"
|
||||
" for (var word = 0; word < 7; word++)\n"
|
||||
" for (var word = 0; word < num_words; word++)\n"
|
||||
" {\n"
|
||||
" var tr = $('<tr></tr>');\n"
|
||||
" tr.append($('<td>'+word+'</td>'));\n"
|
||||
|
@ -82,15 +87,28 @@ static const char s_polyAnalysisHTMLEpilogue[] =
|
|||
" {\n"
|
||||
" var mask = 1 << bit;\n"
|
||||
" var td = $('<td></td>');\n"
|
||||
" if (g_unknown_bits[word] & mask)\n"
|
||||
" td.addClass('selectable').click(getOnClickHandler(table, td, word, mask));\n"
|
||||
" if (unknown_bits[word] & mask)\n"
|
||||
" td.addClass('selectable').click(createOnClickHandler(type, table, td, word, mask));\n"
|
||||
" else\n"
|
||||
" td.addClass('nonselectable');\n"
|
||||
" tr.append(td);\n"
|
||||
" }\n"
|
||||
" table.append(tr);\n"
|
||||
" }\n"
|
||||
" $('#Header').append(table);\n"
|
||||
" return table;"
|
||||
" }\n"
|
||||
|
||||
" $(document).ready(function()\n"
|
||||
" {\n"
|
||||
" // Construct tables\n"
|
||||
" var poly_table = buildTable(7, 'poly', g_unknown_poly_bits);\n"
|
||||
" var poly_title = $('<p></p>').text('Polygon Header');\n"
|
||||
" $('#PolyBits').append(poly_title);\n"
|
||||
" $('#PolyBits').append(poly_table);\n"
|
||||
" var culling_table = buildTable(10, 'culling', g_unknown_culling_bits);\n"
|
||||
" var culling_title = $('<p></p>').text('Culling Node');\n"
|
||||
" $('#CullingBits').append(culling_title);\n"
|
||||
" $('#CullingBits').append(culling_table);\n"
|
||||
" });\n"
|
||||
" </script>\n"
|
||||
"</body>\n"
|
||||
|
|
Loading…
Reference in a new issue