#include "gx.hpp" #include "__gx.h" #include "../../gx/command_processor.hpp" #include "../../gx/fifo.hpp" #include static __GXData_struct sSavedGXData; extern "C" { void GXBeginDisplayList(void* list, u32 size) { CHECK(!aurora::gx::fifo::in_display_list(), "Display list began twice!"); // Flush any pending dirty state before recording if (__gx->dirtyState != 0) { __GXSetDirtyState(); } // Save current shadow register state if requested if (__gx->dlSaveContext != 0) { std::memcpy(&sSavedGXData, __gx, sizeof(sSavedGXData)); } __gx->inDispList = 1; // Redirect FIFO writes to the user-provided buffer aurora::gx::fifo::begin_display_list(static_cast(list), size); } u32 GXEndDisplayList() { // Flush any pending dirty state into the display list if (__gx->dirtyState != 0) { __GXSetDirtyState(); } // End FIFO redirection and get the byte count (ROUNDUP32) u32 bytesWritten = aurora::gx::fifo::end_display_list(); // Restore saved shadow register state if (__gx->dlSaveContext != 0) { std::memcpy(__gx, &sSavedGXData, sizeof(*__gx)); } __gx->inDispList = 0; return bytesWritten; } void GXCallDisplayList(const void* data, u32 nbytes) { // Flush any pending dirty state before calling if (__gx->dirtyState != 0) { __GXSetDirtyState(); } // Flush pending primitives if (*reinterpret_cast(&__gx->vNum) != 0) { __GXSendFlushPrim(); } // Nested display-list calls add bytes instead of changing live renderer state. if (aurora::gx::fifo::in_display_list()) { aurora::gx::fifo::write_data(data, nbytes); return; } // Decode the display list immediately while its borrowed resources are valid. aurora::gx::fifo::drain(); aurora::gx::fifo::process(static_cast(data), nbytes, true); } void GXCallDisplayListLE(const void* data, u32 nbytes) { // Flush any pending dirty state before calling if (__gx->dirtyState != 0) { __GXSetDirtyState(); } // Flush pending primitives if (*reinterpret_cast(&__gx->vNum) != 0) { __GXSendFlushPrim(); } // Decode little-endian lists separately after finishing the normal FIFO work. aurora::gx::fifo::drain(); // Process the display list through the command processor (little-endian) aurora::gx::fifo::process(static_cast(data), nbytes, false); } }