diff --git a/extern/ZAPDUtils/Utils/BitConverter.h b/extern/ZAPDUtils/Utils/BitConverter.h index 46845fe36..c90b3dfbd 100644 --- a/extern/ZAPDUtils/Utils/BitConverter.h +++ b/extern/ZAPDUtils/Utils/BitConverter.h @@ -193,12 +193,12 @@ class BitConverter switch (firstByte) { case 0x37: // v64 - for (int32_t pos = 0; pos < (romSize / 2); pos++) { + for (size_t pos = 0; pos < (romSize / 2); pos++) { ((uint16_t*)rom)[pos] = ToUInt16BE(rom, pos * 2); } break; case 0x40: // n64 - for (int32_t pos = 0; pos < (romSize / 4); pos++) { + for (size_t pos = 0; pos < (romSize / 4); pos++) { ((uint32_t*)rom)[pos] = ToUInt32BE(rom, pos * 4); } break; diff --git a/extern/ZAPDUtils/Utils/DiskFile.h b/extern/ZAPDUtils/Utils/DiskFile.h index 74962a02a..221107f14 100644 --- a/extern/ZAPDUtils/Utils/DiskFile.h +++ b/extern/ZAPDUtils/Utils/DiskFile.h @@ -81,7 +81,10 @@ class DiskFile static void WriteAllText(const fs::path& filePath, const std::string& text) { - std::ofstream file(filePath, std::ios::out); + if (!std::filesystem::exists(filePath.parent_path())) { + std::filesystem::create_directories(filePath.parent_path()); + } + std::ofstream file(filePath, std::ios::out); file.write(text.c_str(), text.size()); } }; diff --git a/include/libultraship/bridge.h b/include/libultraship/bridge.h index 9d4f6dca7..668e6b63e 100644 --- a/include/libultraship/bridge.h +++ b/include/libultraship/bridge.h @@ -7,5 +7,6 @@ #include "public/bridge/windowbridge.h" #include "public/bridge/consolevariablebridge.h" #include "public/bridge/crashhandlerbridge.h" +#include "public/bridge/gfxdebuggerbridge.h" #endif diff --git a/include/libultraship/libultra/abi.h b/include/libultraship/libultra/abi.h index 99d8ddf35..a4e500695 100644 --- a/include/libultraship/libultra/abi.h +++ b/include/libultraship/libultra/abi.h @@ -7,7 +7,7 @@ typedef unsigned int u32; #define A_SPNOOP 0 #define A_ADPCM 1 #define A_CLEARBUFF 2 -#define A_UNK3 3 +#define A_UNK3 3f #define A_ADDMIXER 4 #define A_RESAMPLE 5 #define A_RESAMPLE_ZOH 6 @@ -37,6 +37,7 @@ typedef unsigned int u32; #define A_INIT 0x01 #define A_CONTINUE 0x00 #define A_LOOP 0x02 +#define A_ADPCM_SHORT 0x04 #define A_OUT 0x02 #define A_LEFT 0x02 #define A_RIGHT 0x00 @@ -446,12 +447,12 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = (u32)(addr); \ } -#define aDuplicate(pkt, count, dmemi, dmemo, a4) \ - { \ - Acmd* _a = (Acmd*)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_DUPLICATE, 24, 8) | _SHIFTL(count, 16, 8) | _SHIFTL(dmemi, 0, 16)); \ - _a->words.w1 = _SHIFTL(dmemo, 16, 16) | _SHIFTL(a4, 0, 16); \ +#define aDuplicate(pkt, numCopies, dmemSrc, dmemDest) \ + { \ + Acmd* _a = (Acmd*)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_DUPLICATE, 24, 8) | _SHIFTL(numCopies, 16, 8) | _SHIFTL(dmemSrc, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemDest, 16, 16) | _SHIFTL(0x80, 0, 16); \ } #define aAddMixer(pkt, count, dmemi, dmemo, a4) \ diff --git a/include/libultraship/libultra/gbi.h b/include/libultraship/libultra/gbi.h index f72898d72..a0a5567d2 100644 --- a/include/libultraship/libultra/gbi.h +++ b/include/libultraship/libultra/gbi.h @@ -184,6 +184,9 @@ // RDP Cmd #define G_SETGRAYSCALE 0x39 #define G_EXTRAGEOMETRYMODE 0x3a +#define G_COPYFB 0x3b +#define G_IMAGERECT 0x3c +#define G_DL_INDEX 0x3d #define G_SETINTENSITY 0x40 /* @@ -343,6 +346,7 @@ #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 #define G_LOD 0x00100000 /* NOT IMPLEMENTED */ +#define G_LIGHTING_POSITIONAL 0x00400000 #if (defined(F3DEX_GBI) || defined(F3DLP_GBI)) #define G_CLIPPING 0x00800000 #else @@ -1270,6 +1274,15 @@ typedef struct { char pad3; } Light_t; +typedef struct { + unsigned char col[3]; + unsigned char unk3; + unsigned char colc[3]; + unsigned char unk7; + short pos[3]; + unsigned char unkE; +} PointLight_t; + typedef struct { unsigned char col[3]; /* ambient light value (rgba) */ char pad1; @@ -1283,6 +1296,7 @@ typedef struct { typedef union { Light_t l; + PointLight_t p; long long int force_structure_alignment[2]; } Light; @@ -1769,11 +1783,13 @@ typedef union { #define gsSPDisplayList(dl) gsDma1p(G_DL, dl, 0, G_DL_PUSH) #define gsSPDisplayListOTRHash(dl) gsDma1p(G_DL_OTR_HASH, dl, 0, G_DL_PUSH) #define gsSPDisplayListOTRFilePath(dl) gsDma1p(G_DL_OTR_FILEPATH, dl, 0, G_DL_PUSH) +#define gsSPDisplayListIndex(dl) gsDma1p(G_DL_INDEX, dl, 0, G_DL_PUSH) #define gSPBranchList(pkt, dl) gDma1p(pkt, G_DL, dl, 0, G_DL_NOPUSH) #define gsSPBranchList(dl) gsDma1p(G_DL, dl, 0, G_DL_NOPUSH) #define gsSPBranchListOTRHash(dl) gsDma1p(G_DL_OTR_HASH, dl, 0, G_DL_NOPUSH) #define gsSPBranchListOTRFilePath(dl) gsDma1p(G_DL_OTR_FILEPATH, dl, 0, G_DL_NOPUSH) +#define gsSPBranchListIndex(dl) gsDma1p(G_DL_INDEX, dl, 0, G_DL_NOPUSH) #define gSPSprite2DBase(pkt, s) gDma1p(pkt, G_SPRITE2D_BASE, s, sizeof(uSprite), 0) #define gsSPSprite2DBase(s) gsDma1p(G_SPRITE2D_BASE, s, sizeof(uSprite), 0) @@ -2271,9 +2287,9 @@ typedef union { #define gsSPLoadUcode(uc_start, uc_dstart) gsSPLoadUcodeEx((uc_start), (uc_dstart), SP_UCODE_DATA_SIZE) #define gSPLoadUcodeL(pkt, ucode) \ - gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(&##ucode##TextStart), OS_K0_TO_PHYSICAL(&##ucode##DataStart)) + gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(&(ucode##TextStart)), OS_K0_TO_PHYSICAL(&(ucode##DataStart))) #define gsSPLoadUcodeL(ucode) \ - gsSPLoadUcode(OS_K0_TO_PHYSICAL(&##ucode##TextStart), OS_K0_TO_PHYSICAL(&##ucode##DataStart)) + gsSPLoadUcode(OS_K0_TO_PHYSICAL(&(ucode##TextStart)), OS_K0_TO_PHYSICAL(&(ucode##DataStart))) #endif #ifdef F3DEX_GBI_2 @@ -2648,6 +2664,26 @@ typedef union { _g->words.w1 = 0; \ } +#define gDPCopyFB(pkt, dst, src, once, copiedPtr) \ + { \ + Gfx* _g = (Gfx*)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_COPYFB, 24, 8) | _SHIFTL(dst, 11, 11) | _SHIFTL(src, 0, 11) | _SHIFTL(once, 22, 1); \ + _g->words.w1 = (uintptr_t)copiedPtr; \ + } + +#define gDPImageRectangle(pkt, x0, y0, s0, t0, x1, y1, s1, t1, tile, iw, ih) \ + { \ + Gfx *_g0 = (Gfx*)(pkt), *_g1 = (Gfx*)(pkt), *_g2 = (Gfx*)(pkt); \ + \ + _g0->words.w0 = _SHIFTL(G_IMAGERECT, 24, 8) | _SHIFTL((tile), 0, 3); \ + _g0->words.w1 = _SHIFTL((iw), 16, 16) | _SHIFTL((ih), 0, 16); \ + _g1->words.w0 = _SHIFTL((x0), 16, 16) | _SHIFTL((y0), 0, 16); \ + _g1->words.w1 = _SHIFTL((s0), 16, 16) | _SHIFTL((t0), 0, 16); \ + _g2->words.w0 = _SHIFTL((x1), 16, 16) | _SHIFTL((y1), 0, 16); \ + _g2->words.w1 = _SHIFTL((s1), 16, 16) | _SHIFTL((t1), 0, 16); \ + } + #define gSPGrayscale(pkt, state) \ { \ Gfx* _g = (Gfx*)(pkt); \ @@ -2785,6 +2821,8 @@ typedef union { #define gsDPSetAlphaDither(mode) gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode) #endif +#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 @@ -4061,4 +4099,4 @@ typedef union { #endif -#endif \ No newline at end of file +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c9c5753da..ce5a712a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,12 @@ add_library(libultraship STATIC) set_target_properties(libultraship PROPERTIES PREFIX "") set_property(TARGET libultraship PROPERTY CXX_STANDARD 20) +# Need to set C11 for libgfxd (_Alignas) +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}") @@ -173,7 +177,7 @@ set(Source_Files__Public__Libultra ${CMAKE_CURRENT_SOURCE_DIR}/public/libultra/os.h ${CMAKE_CURRENT_SOURCE_DIR}/public/libultra/os.cpp ) - + source_group("public/libultra" FILES ${Source_Files__Public__Libultra}) set(Source_Files__Public__Bridge @@ -183,6 +187,8 @@ set(Source_Files__Public__Bridge ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/windowbridge.cpp ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/audiobridge.h ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/audiobridge.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/gfxdebuggerbridge.h + ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/gfxdebuggerbridge.cpp ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/controllerbridge.h ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/controllerbridge.cpp ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/consolevariablebridge.h @@ -190,7 +196,7 @@ set(Source_Files__Public__Bridge ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/crashhandlerbridge.h ${CMAKE_CURRENT_SOURCE_DIR}/public/bridge/crashhandlerbridge.cpp ) - + source_group("public/bridge" FILES ${Source_Files__Public__Bridge}) target_sources(libultraship PRIVATE ${Source_Files__Public__Libultra} ${Source_Files__Public__Bridge}) @@ -201,6 +207,8 @@ set(Source_Files__Debug ${CMAKE_CURRENT_SOURCE_DIR}/debug/CrashHandler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/debug/Console.h ${CMAKE_CURRENT_SOURCE_DIR}/debug/Console.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/debug/GfxDebugger.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/debug/GfxDebugger.h ) source_group("debug" FILES ${Source_Files__Debug}) @@ -247,6 +255,8 @@ set(Source_Files__Window__Gui ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiElement.cpp ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiMenuBar.h ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiMenuBar.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GfxDebuggerWindow.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GfxDebuggerWindow.h ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/Font.h ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/Font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/FontFactory.h @@ -260,6 +270,28 @@ 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}) + + target_sources(libultraship PRIVATE ${Header_Files__Libraries__libgfxd} ${Source_Files__Libraries__libgfxd}) +endif() + #=================== Utils =================== set(Source_Files__Utils @@ -456,7 +488,7 @@ endif() #=================== Packages & Includes =================== target_include_directories(libultraship - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../extern ${CMAKE_CURRENT_BINARY_DIR} + 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 ) @@ -518,7 +550,7 @@ endif() if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set_target_properties(${PROJECT_NAME} PROPERTIES - XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES + XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES ) endif() @@ -530,6 +562,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/Context.cpp b/src/Context.cpp index 960a92bbf..8ba78df0b 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -5,6 +5,7 @@ #include #include #include "install_config.h" +#include "debug/GfxDebugger.h" #ifdef _WIN32 #include @@ -86,6 +87,7 @@ void Context::Init(const std::vector& otrFiles, const std::unordere InitConsole(); InitWindow(); InitAudio(); + InitGfxDebugger(); } void Context::InitLogging() { @@ -247,6 +249,14 @@ void Context::InitAudio() { GetAudio()->Init(); } +void Context::InitGfxDebugger() { + if (GetGfxDebugger() != nullptr) { + return; + } + + mGfxDebugger = std::make_shared(); +} + void Context::InitConsole() { if (GetConsole() != nullptr) { return; @@ -301,6 +311,10 @@ std::shared_ptr