diff options
| author | fig02 <fig02srl@gmail.com> | 2021-03-12 15:51:39 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-12 15:51:39 -0500 |
| commit | 55718b1090083e1f5e9b1b1cc09ebcb329baa74f (patch) | |
| tree | ae890ccd6bfeded507518d227a0002f8fc136bcf /ZAPD/ZDisplayList.cpp | |
| parent | 1e67767cf988af08e79d8cea4ee1e4d47658fe29 (diff) | |
Use libgfxd (gfxdis) for display lists (#84)
* start
* dlists work
* progress
* vtx works
* texture wip
* debugging
* palletes sorta working
* pal issue sort of fixed
* progress
* fiix
* switching to master
* progress
* OK
* fixes
* whitespace
* libgfxd update
* prep for merge
* use new seg2filespace function
* vtx
Diffstat (limited to 'ZAPD/ZDisplayList.cpp')
| -rw-r--r-- | ZAPD/ZDisplayList.cpp | 267 |
1 files changed, 233 insertions, 34 deletions
diff --git a/ZAPD/ZDisplayList.cpp b/ZAPD/ZDisplayList.cpp index c69e1a8..4754c03 100644 --- a/ZAPD/ZDisplayList.cpp +++ b/ZAPD/ZDisplayList.cpp @@ -1,8 +1,10 @@ #include "ZDisplayList.h" #include "BitConverter.h" #include "StringHelper.h" +#include "OutputFormatter.h" #include "HighLevel/HLModelIntermediette.h" #include "Globals.h" +#include "gfxd.h" #include <chrono> #include <algorithm> #include <File.h> @@ -68,7 +70,7 @@ ZDisplayList::ZDisplayList(vector<uint8_t> nRawData, int nRawDataIndex, int rawD { fileData = nRawData; rawDataIndex = nRawDataIndex; - name = StringHelper::Sprintf("Dlist0x%06X", rawDataIndex); + name = StringHelper::Sprintf("DL_%06X", rawDataIndex); rawData = vector<uint8_t>(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + rawDataSize); ParseRawData(); } @@ -1428,48 +1430,241 @@ string ZDisplayList::GetSourceOutputHeader(const std::string& prefix) return ""; } -string ZDisplayList::GetSourceOutputCode(const std::string& prefix) +static int GfxdCallback_FormatSingleEntry(void) { - char line[4096]; - string sourceOutput = ""; + gfxd_puts("\t"); + gfxd_macro_dflt(); + gfxd_puts(","); - for (int i = 0; i < instructions.size(); i++) - { - uint8_t opcode = (uint8_t)(instructions[i] >> 56); - uint64_t data = instructions[i]; - sourceOutput += " "; + // dont print a new line after the last command + if (gfxd_macro_id() != gfxd_SPEndDisplayList) { + gfxd_puts("\n"); + } - auto start = chrono::steady_clock::now(); + return 0; +} - int optimizationResult = OptimizationChecks(i, sourceOutput, prefix); +static int GfxdCallback_Vtx(uint32_t seg, int32_t count) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t vtxOffset = Seg2Filespace(seg, instance->parent->baseAddress); + string vtxName = ""; - if (optimizationResult != -1) + if (!Globals::Instance->HasSegment(GETSEGNUM(seg))) // Probably an external asset we are unable to track + { + vtxName = StringHelper::Sprintf("0x%08X", seg); + } + else + { + instance->references.push_back(vtxOffset); + + // Check for vertex intersections from other display lists + // TODO: These two could probably be condenced to one... + if (instance->parent->GetDeclarationRanged(vtxOffset + (count * 16)) != nullptr) { - i += optimizationResult - 1; - line[0] = '\0'; + Declaration* decl = instance->parent->GetDeclarationRanged(vtxOffset + (count * 16)); + uint32_t addr = instance->parent->GetDeclarationRangedAddress(vtxOffset + (count * 16)); + int diff = addr - vtxOffset; + + if (diff > 0) + count = diff / 16; + else + count = 0; } - else + + if (instance->parent->GetDeclarationRanged(vtxOffset) != nullptr) { - if (dListType == DListType::F3DZEX) - ParseF3DZEX((F3DZEXOpcode)opcode, data, i, prefix, line); + Declaration* decl = instance->parent->GetDeclarationRanged(vtxOffset); + uint32_t addr = instance->parent->GetDeclarationRangedAddress(vtxOffset); + int diff = addr - vtxOffset; + + if (diff > 0) + count = diff / 16; else - ParseF3DEX((F3DEXOpcode)opcode, data, i, prefix, line); + count = 0; } - auto end = chrono::steady_clock::now(); - auto diff = chrono::duration_cast<chrono::milliseconds>(end - start).count(); + if (count > 0) + { + vector<Vertex> vtxList = vector<Vertex>(); + vtxList.reserve(count); + + uint32_t currentPtr = vtxOffset; + for (int i = 0; i < count; i++) + { + Vertex vtx = Vertex(instance->fileData, currentPtr); + vtxList.push_back(vtx); + currentPtr += 16; + } + instance->vertices[vtxOffset] = vtxList; + } + + vtxName = "@r"; + } + + gfxd_puts(vtxName.c_str()); + + return 1; +} + +static int GfxdCallback_Texture(uint32_t seg, int32_t fmt, int32_t siz, int32_t width, int32_t height, int32_t pal) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t texOffset = Seg2Filespace(seg, instance->parent->baseAddress); + uint32_t texSegNum = GETSEGNUM(seg); + Declaration* texDecl = nullptr; + string texName = ""; + + if (instance->parent != nullptr && texSegNum != 2) // HACK: Until we have declarations use segment addresses, we'll exclude scene references... + { + texDecl = instance->parent->GetDeclaration(texOffset); + + if (texDecl == nullptr) + texDecl = instance->parent->GetDeclaration(seg); + } + + if (!Globals::Instance->HasSegment(texSegNum)) // Probably an external asset we are unable to track + texName = StringHelper::Sprintf("0x%08X", seg); + else if (texDecl != nullptr) + texName = StringHelper::Sprintf("%s", texDecl->varName.c_str()); + else if (texSegNum == 2) + texName = StringHelper::Sprintf("%sTex_%06X", instance->scene->GetName().c_str(), texOffset); + else + texName = StringHelper::Sprintf("%sTex_%06X", instance->curPrefix.c_str(), texOffset); + + instance->lastTexWidth = width; + instance->lastTexHeight = height; + instance->lastTexAddr = texOffset; + instance->lastTexSeg = seg; + instance->lastTexFmt = (F3DZEXTexFormats)fmt; + instance->lastTexSiz = (F3DZEXTexSizes)siz; + instance->lastTexLoaded = true; + instance->lastTexIsPalette = false; + + instance->TextureGenCheck(instance->curPrefix); + gfxd_puts(texName.c_str()); + + return 1; +} + +static int GfxdCallback_Palette(uint32_t seg, int32_t idx, int32_t count) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t palOffset = Seg2Filespace(seg, instance->parent->baseAddress); + uint32_t palSegNum = GETSEGNUM(seg); + Declaration* palDecl = nullptr; + string palName = ""; + + if (instance->parent != nullptr && palSegNum != 2) // HACK: Until we have declarations use segment addresses, we'll exclude scene references... + { + palDecl = instance->parent->GetDeclaration(palOffset); + + if (palDecl == nullptr) + palDecl = instance->parent->GetDeclaration(seg); + } + + if (!Globals::Instance->HasSegment(palSegNum)) // Probably an external asset we are unable to track + palName = StringHelper::Sprintf("0x%08X", seg); + else if (palDecl != nullptr) + palName = StringHelper::Sprintf("%s", palDecl->varName.c_str()); + else if (palSegNum == 2) + palName = StringHelper::Sprintf("%sTex_%06X", instance->scene->GetName().c_str(), palOffset); + else + palName = StringHelper::Sprintf("%sTex_%06X", instance->curPrefix.c_str(), palOffset); + + instance->lastTexWidth = sqrt(count); + instance->lastTexHeight = sqrt(count); + instance->lastTexAddr = palOffset; + instance->lastTexSeg = seg; + instance->lastTexSiz = F3DZEXTexSizes::G_IM_SIZ_16b; + instance->lastTexFmt = F3DZEXTexFormats::G_IM_FMT_RGBA; + instance->lastTexLoaded = true; + instance->lastTexIsPalette = true; + + instance->TextureGenCheck(instance->curPrefix); + gfxd_puts(palName.c_str()); + + return 1; +} + +static int GfxdCallback_DisplayList(uint32_t seg) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t dListOffset = GETSEGOFFSET(seg); + uint32_t dListSegNum = GETSEGNUM(seg); + Declaration* dListDecl = nullptr; + string dListName = ""; -#if _MSC_VER - //if (diff > 5) - //printf("F3DOP: 0x%02X, TIME: %ims\n", opcode, diff); -#endif + if (instance->parent != nullptr) + dListDecl = instance->parent->GetDeclaration(dListOffset); - sourceOutput += line; + if (!Globals::Instance->HasSegment(dListSegNum)) // Probably an external asset we are unable to track + dListName = StringHelper::Sprintf("0x%08X", seg); + else if (dListDecl != nullptr) + dListName = StringHelper::Sprintf("%s", dListDecl->varName.c_str()); + else + dListName = StringHelper::Sprintf("%sDL_%06X", instance->curPrefix.c_str(), dListOffset); - if (i < instructions.size() - 1) - sourceOutput += "\n"; + if (dListSegNum <= 6) + { + ZDisplayList* newDList = new ZDisplayList(instance->fileData, dListOffset, instance->GetDListLength(instance->fileData, dListOffset, instance->dListType)); + newDList->scene = instance->scene; + newDList->parent = instance->parent; + instance->otherDLists.push_back(newDList); } + gfxd_puts(dListName.c_str()); + + return 1; +} + +static int GfxdCallback_Matrix(uint32_t seg) +{ + string mtxName = ""; + + if (Globals::Instance->symbolMap.find(seg) != Globals::Instance->symbolMap.end()) + mtxName = StringHelper::Sprintf("&%s", Globals::Instance->symbolMap[seg].c_str()); + else + mtxName = StringHelper::Sprintf("0x%08X", seg); + + gfxd_puts(mtxName.c_str()); + + return 1; +} + +ZDisplayList* ZDisplayList::static_instance; + +string ZDisplayList::GetSourceOutputCode(const std::string& prefix) +{ + OutputFormatter outputformatter; + string sourceOutput = ""; + int dListSize = instructions.size() * sizeof(instructions[0]); + + gfxd_input_buffer(instructions.data(), dListSize); + gfxd_endian(gfxd_endian_little, sizeof(uint64_t)); // tell gfxdis what format the data is + + gfxd_macro_fn(GfxdCallback_FormatSingleEntry); // format for each command entry + gfxd_vtx_callback(GfxdCallback_Vtx); // handle vertices + gfxd_timg_callback(GfxdCallback_Texture); // handle textures + gfxd_tlut_callback(GfxdCallback_Palette); // handle palettes + gfxd_dl_callback(GfxdCallback_DisplayList); // handle child display lists + gfxd_mtx_callback(GfxdCallback_Matrix); // handle matrices + gfxd_output_callback(outputformatter.static_writer()); // convert tabs to 4 spaces and enforce 120 line limit + + gfxd_enable(gfxd_emit_dec_color); // use decimal for colors + + // set microcode. see gfxd.h for more options. + if (dListType == DListType::F3DZEX) { + gfxd_target(gfxd_f3dex2); + } else { + gfxd_target(gfxd_f3dex); + } + + this->curPrefix = prefix; + static_instance = this; + gfxd_execute(); // generate display list + sourceOutput += outputformatter.get_output(); // write formatted display list + // Iterate through our vertex lists, connect intersecting lists. if (vertices.size() > 0) { @@ -1704,17 +1899,21 @@ TextureType ZDisplayList::TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSize else if (siz == F3DZEXTexSizes::G_IM_SIZ_32b) return TextureType::RGBA32bpp; } - else if (fmt == F3DZEXTexFormats::G_IM_FMT_CI) - { - //if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) - return TextureType::Palette8bpp; - } + else if (fmt == F3DZEXTexFormats::G_IM_FMT_CI) + { + if (siz == F3DZEXTexSizes::G_IM_SIZ_4b) + return TextureType::Palette4bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) + return TextureType::Palette8bpp; + } else if (fmt == F3DZEXTexFormats::G_IM_FMT_IA) { - if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) - return TextureType::GrayscaleAlpha16bpp; + if (siz == F3DZEXTexSizes::G_IM_SIZ_4b) + return TextureType::Grayscale4bpp; else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) return TextureType::GrayscaleAlpha8bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) + return TextureType::GrayscaleAlpha16bpp; } else if (fmt == F3DZEXTexFormats::G_IM_FMT_I) { |
