diff --git a/include/libultraship/libultra/gbi.h b/include/libultraship/libultra/gbi.h index d0d861298..4c4f53fdd 100644 --- a/include/libultraship/libultra/gbi.h +++ b/include/libultraship/libultra/gbi.h @@ -2814,7 +2814,6 @@ typedef union { #define gDPSetDither(pkt, mode) gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 4, mode) - /* 'blendmask' is not supported anymore. * The bits are reserved for future use. * Fri May 26 13:45:55 PDT 1995 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d98ca01f..b4a452721 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ set_property(TARGET libultraship PROPERTY C_STANDARD 11) set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include) option(USE_OPENGLES "Enable GLES3" OFF) +option(GFX_DEBUG_DISASSEMBLER "Enable libgfxd" OFF) if (CMAKE_SYSTEM_NAME STREQUAL "Windows") use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}") @@ -263,27 +264,27 @@ set(Source_Files__Window__Gui source_group("window/gui" FILES ${Source_Files__Window__Gui}) target_sources(libultraship PRIVATE ${Source_Files__Window__Gui}) +if (GFX_DEBUG_DISASSEMBLER) + set(Header_Files__Libraries__libgfxd + "../../ZAPDTR/lib/libgfxd/gbi.h" + "../../ZAPDTR/lib/libgfxd/gfxd.h" + "../../ZAPDTR/lib/libgfxd/priv.h" + ) + source_group("Header Files\\Libraries\\libgfxd" FILES ${Header_Files__Libraries__libgfxd}) + + set(Source_Files__Libraries__libgfxd + "../../ZAPDTR/lib/libgfxd/gfxd.c" + "../../ZAPDTR/lib/libgfxd/uc.c" + "../../ZAPDTR/lib/libgfxd/uc_f3d.c" + "../../ZAPDTR/lib/libgfxd/uc_f3db.c" + "../../ZAPDTR/lib/libgfxd/uc_f3dex.c" + "../../ZAPDTR/lib/libgfxd/uc_f3dex2.c" + "../../ZAPDTR/lib/libgfxd/uc_f3dexb.c" + ) + source_group("Source Files\\Libraries\\libgfxd" FILES ${Source_Files__Libraries__libgfxd}) -set(Header_Files__Libraries__libgfxd - "../../ZAPDTR/lib/libgfxd/gbi.h" - "../../ZAPDTR/lib/libgfxd/gfxd.h" - "../../ZAPDTR/lib/libgfxd/priv.h" -) -source_group("Header Files\\Libraries\\libgfxd" FILES ${Header_Files__Libraries__libgfxd}) - -set(Source_Files__Libraries__libgfxd - "../../ZAPDTR/lib/libgfxd/gfxd.c" - "../../ZAPDTR/lib/libgfxd/uc.c" - "../../ZAPDTR/lib/libgfxd/uc_f3d.c" - "../../ZAPDTR/lib/libgfxd/uc_f3db.c" - "../../ZAPDTR/lib/libgfxd/uc_f3dex.c" - "../../ZAPDTR/lib/libgfxd/uc_f3dex2.c" - "../../ZAPDTR/lib/libgfxd/uc_f3dexb.c" -) -source_group("Source Files\\Libraries\\libgfxd" FILES ${Source_Files__Libraries__libgfxd}) - - -target_sources(libultraship PRIVATE ${Header_Files__Libraries__libgfxd} ${Source_Files__Libraries__libgfxd}) + target_sources(libultraship PRIVATE ${Header_Files__Libraries__libgfxd} ${Source_Files__Libraries__libgfxd}) +endif() #=================== Utils =================== @@ -467,7 +468,7 @@ endif() #=================== Packages & Includes =================== target_include_directories(libultraship - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../extern ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/libgfxd + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../extern ${CMAKE_CURRENT_BINARY_DIR} $<$:${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/libgfxd> PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../extern/spdlog/include ${CMAKE_CURRENT_SOURCE_DIR}/../extern/stb ) @@ -533,6 +534,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "CafeOS") $<$:SPDLOG_ACTIVE_LEVEL=0> $<$>:SPDLOG_ACTIVE_LEVEL=1> $<$:USE_OPENGLES> + $<$:GFX_DEBUG_DISASSEMBLER> ) else () target_compile_definitions(libultraship PRIVATE diff --git a/src/graphic/Fast3D/gfx_pc.cpp b/src/graphic/Fast3D/gfx_pc.cpp index 659bf6981..1951faf5f 100644 --- a/src/graphic/Fast3D/gfx_pc.cpp +++ b/src/graphic/Fast3D/gfx_pc.cpp @@ -1136,7 +1136,7 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx* verti float world_pos[3]; if (g_rsp.geometry_mode & G_LIGHTING_POSITIONAL) { - float (*mtx)[4] = g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1]; + float(*mtx)[4] = g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1]; world_pos[0] = v->ob[0] * mtx[0][0] + v->ob[1] * mtx[1][0] + v->ob[2] * mtx[2][0] + mtx[3][0]; world_pos[1] = v->ob[0] * mtx[0][1] + v->ob[1] * mtx[1][1] + v->ob[2] * mtx[2][1] + mtx[3][1]; world_pos[2] = v->ob[0] * mtx[0][2] + v->ob[1] * mtx[1][2] + v->ob[2] * mtx[2][2] + mtx[3][2]; @@ -1167,13 +1167,18 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx* verti float intensity = 0; if ((g_rsp.geometry_mode & G_LIGHTING_POSITIONAL) && (g_rsp.current_lights[i].p.unk3 != 0)) { // Calculate distance from the light to the vertex - float dist_vec[3] = { g_rsp.current_lights[i].p.pos[0] - world_pos[0], g_rsp.current_lights[i].p.pos[1] - world_pos[1], g_rsp.current_lights[i].p.pos[2] - world_pos[2] }; - float dist_sq = dist_vec[0] * dist_vec[0] + dist_vec[1] * dist_vec[1] + dist_vec[2] * dist_vec[2] * 2; // The *2 comes from GLideN64, unsure of why it does it + float dist_vec[3] = { g_rsp.current_lights[i].p.pos[0] - world_pos[0], + g_rsp.current_lights[i].p.pos[1] - world_pos[1], + g_rsp.current_lights[i].p.pos[2] - world_pos[2] }; + float dist_sq = + dist_vec[0] * dist_vec[0] + dist_vec[1] * dist_vec[1] + + dist_vec[2] * dist_vec[2] * 2; // The *2 comes from GLideN64, unsure of why it does it float dist = sqrt(dist_sq); // Transform distance vector (which acts as a direction light vector) into model's space float light_model[3]; - gfx_transposed_matrix_mul(light_model, dist_vec, g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1]); + gfx_transposed_matrix_mul(light_model, dist_vec, + g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1]); // Calculate intensity for each axis using standard formula for intensity float light_intensity[3]; @@ -1183,14 +1188,19 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx* verti } // Adjust intensity based on surface normal and sum up total - float total_intensity = light_intensity[0] * vn->n[0] + light_intensity[1] * vn->n[1] + light_intensity[2] * vn->n[2]; + float total_intensity = + light_intensity[0] * vn->n[0] + light_intensity[1] * vn->n[1] + light_intensity[2] * vn->n[2]; total_intensity = clamp(total_intensity, -1.0f, 1.0f); // Attenuate intensity based on attenuation values. // Example formula found at https://ogldev.org/www/tutorial20/tutorial20.html - // Specific coefficients for MM's microcode sourced from GLideN64 https://github.com/gonetz/GLideN64/blob/3b43a13a80dfc2eb6357673440b335e54eaa3896/src/gSP.cpp#L636 + // Specific coefficients for MM's microcode sourced from GLideN64 + // https://github.com/gonetz/GLideN64/blob/3b43a13a80dfc2eb6357673440b335e54eaa3896/src/gSP.cpp#L636 float distf = floorf(dist); - float attenuation = (distf * g_rsp.current_lights[i].p.unk7 * 2.0f + distf * distf * g_rsp.current_lights[i].p.unkE / 8.0f) / (float)0xFFFF + 1.0f; + float attenuation = (distf * g_rsp.current_lights[i].p.unk7 * 2.0f + + distf * distf * g_rsp.current_lights[i].p.unkE / 8.0f) / + (float)0xFFFF + + 1.0f; intensity = total_intensity / attenuation; } else { intensity += vn->n[0] * g_rsp.current_lights_coeffs[i][0]; @@ -1948,7 +1958,8 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t word_size_shift = 2; break; } - uint32_t orig_size_bytes = word_size_shift > 0 ? (lrs + 1) << word_size_shift : (lrs + 1) >> (-(int64_t)word_size_shift); + uint32_t orig_size_bytes = + word_size_shift > 0 ? (lrs + 1) << word_size_shift : (lrs + 1) >> (-(int64_t)word_size_shift); uint32_t size_bytes = orig_size_bytes; if (g_rdp.texture_to_load.raw_tex_metadata.h_byte_scale != 1 || g_rdp.texture_to_load.raw_tex_metadata.v_pixel_scale != 1) { @@ -2569,7 +2580,7 @@ static void gfx_step(GfxExecStack& exec_stack) { uint32_t opcode = cmd->words.w0 >> 24; // if (markerOn) - //printf("OP: %016X\n", cmd0->force_structure_alignment); + // printf("OP: %016X\n", cmd0->force_structure_alignment); switch (opcode) { // RSP commands: @@ -2606,7 +2617,7 @@ static void gfx_step(GfxExecStack& exec_stack) { exec_stack.openDisp(filename, l); } else if (p == 8) { if (exec_stack.disp_stack.size() == 0) { - SPDLOG_WARN("CLOSE_DISPS without matching open {}:{}", p, l); + SPDLOG_WARN("CLOSE_DISPS without matching open {}:{}", p, l); } else { exec_stack.closeDisp(); } @@ -3356,19 +3367,19 @@ void gfx_run(Gfx* commands, const std::unordered_map& mtx_replacemen rendering_state.scissor = {}; auto dbg = LUS::Context::GetInstance()->GetGfxDebugger(); - g_exec_stack.start(commands); - while (!g_exec_stack.cmd_stack.empty()) { - auto cmd = g_exec_stack.cmd_stack.top(); + g_exec_stack.start(commands); + while (!g_exec_stack.cmd_stack.empty()) { + auto cmd = g_exec_stack.cmd_stack.top(); - if (GfxDebuggerIsDebugging()) { - g_exec_stack.gfx_path.push_back(cmd); - if (dbg->HasBreakPoint(g_exec_stack.gfx_path)) { - break; - } - g_exec_stack.gfx_path.pop_back(); + if (GfxDebuggerIsDebugging()) { + g_exec_stack.gfx_path.push_back(cmd); + if (dbg->HasBreakPoint(g_exec_stack.gfx_path)) { + break; } - gfx_step(g_exec_stack); + g_exec_stack.gfx_path.pop_back(); } + gfx_step(g_exec_stack); + } gfx_flush(); gfxFramebuffer = 0; currentDir = std::stack(); diff --git a/src/resource/ResourceManager.cpp b/src/resource/ResourceManager.cpp index 7d18dc999..35f224bb5 100644 --- a/src/resource/ResourceManager.cpp +++ b/src/resource/ResourceManager.cpp @@ -60,7 +60,7 @@ bool ResourceManager::DidLoadSuccessfully() { std::shared_ptr ResourceManager::LoadFileProcess(const std::string& filePath) { auto file = mArchive->LoadFile(filePath, true); - + if (file != nullptr) { SPDLOG_TRACE("Loaded File {} on ResourceManager", file->Path); } else { diff --git a/src/resource/ResourceType.h b/src/resource/ResourceType.h index d84079838..c8846cc0b 100644 --- a/src/resource/ResourceType.h +++ b/src/resource/ResourceType.h @@ -33,9 +33,9 @@ enum class ResourceType { SOH_Background = 0x4F424749, // OBGI SOH_SceneCommand = 0x4F52434D, // ORCM - //LUS of Two - TSH_TexAnim = 0x4F54414E, // OTAN - TSH_CKeyFrameAnim = 0x4F4B4641, // OKFA - TSH_CKeyFrameSkel = 0x4F4B4653 // OKFS + // LUS of Two + TSH_TexAnim = 0x4F54414E, // OTAN + TSH_CKeyFrameAnim = 0x4F4B4641, // OKFA + TSH_CKeyFrameSkel = 0x4F4B4653 // OKFS }; } // namespace LUS diff --git a/src/window/gui/GfxDebuggerWindow.cpp b/src/window/gui/GfxDebuggerWindow.cpp index b342a82b4..51d043925 100644 --- a/src/window/gui/GfxDebuggerWindow.cpp +++ b/src/window/gui/GfxDebuggerWindow.cpp @@ -6,8 +6,10 @@ #include #include #include "libultraship/bridge.h" -#include #include +#ifdef GFX_DEBUG_DISASSEMBLER +#include +#endif extern uintptr_t gSegmentPointers[16]; @@ -158,8 +160,17 @@ void GfxDebuggerWindow::DrawDisasNode(const Gfx* cmd, std::vector& g if (opcode == G_TEXRECT) size = 3; if (opname) { - gfxd_input_buffer(cmd, sizeof(uint64_t) * size); - gfxd_endian(gfxd_endian_little, sizeof(uint32_t)); +#ifdef GFX_DEBUG_DISASSEMBLER + // Our Gfx uses uinptr_t for words, but libgfxd uses uint32_t, + // Copy only the first 32bits of each word into a vector before passing the instructions + std::vector input; + for (size_t i = 0; i < size; i++) { + input.push_back(cmd[i].words.w0 & 0xFFFFFFFF); + input.push_back(cmd[i].words.w1 & 0xFFFFFFFF); + } + + gfxd_input_buffer(input.data(), sizeof(uint32_t) * size * 2); + gfxd_endian(gfxd_endian_host, sizeof(uint32_t)); char buff[256] = { 0 }; gfxd_output_buffer(buff, sizeof(buff)); gfxd_enable(gfxd_emit_dec_color); @@ -167,6 +178,9 @@ void GfxDebuggerWindow::DrawDisasNode(const Gfx* cmd, std::vector& g gfxd_execute(); node_with_text(cmd, fmt::format("{}", buff)); +#else + node_with_text(cmd, fmt::format("{}", opname)); +#endif } else { uint32_t opcode = cmd->words.w0 >> 24; node_with_text(cmd, fmt::format("UNK: 0x{:X}", opcode));