mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 16:59:35 -04:00
8c8a97af65
* feat: added ffmepg as dependency * feat: wip decoder video * feat: some perf and cleanup * feat: added generic MPEG stream notification * feat: CMakeLists.txt in ps2xStudio to configure SDL2 build options for static linking. fix: fix ffmpeg setup for linux fix: now MPEG decoder now identify that movie has ended and can play again anytime feat: better audio stub to not block games * feat: fix expansion test * feat: foo * a * feat: finally added a helper to to prevent thread starvation * feat: added basic vu0 code execution * feat: added yield Guest Execution After Wake to prevent deadlock * feat: added options on cmake for logs feat: better input for keyboard pad * feat: small corrections like top and itop vu branches etc * feat: changes * feat: working feature * feat: fatal frame iop * feat: test fix feat: z buffer fix * fix: gix GsPutIMR IMR * feat: added rl imgui * feat: added helper to get snapshot * feat: added debug panel consuming snapshots * feat: added pad snapshot feat: added RCP debug events * feat: final cleanup from old code * feat: added EE timer counter feat: applyed sound driver for Lotr feat: better check for sound driver compat layout feat: enquee and cosumed DMa cause feat: added Pad execCMd feat: update GS vsync signal flag feat: custom IOPs for LotR * feat: small cleanups * fix: fix wrong import
69 lines
2.0 KiB
C++
69 lines
2.0 KiB
C++
#include "runtime/ps2_gif_arbiter.h"
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
|
|
GifArbiter::GifArbiter(ProcessPacketFn processFn)
|
|
: m_processFn(std::move(processFn))
|
|
{
|
|
}
|
|
|
|
bool GifArbiter::isImagePacket(const uint8_t *data, uint32_t sizeBytes)
|
|
{
|
|
if (!data || sizeBytes < 16u)
|
|
return false;
|
|
|
|
uint64_t tagLo = 0;
|
|
std::memcpy(&tagLo, data, sizeof(tagLo));
|
|
const uint8_t flg = static_cast<uint8_t>((tagLo >> 58) & 0x3u);
|
|
return flg == 2u;
|
|
}
|
|
|
|
void GifArbiter::submit(GifPathId pathId, const uint8_t *data, uint32_t sizeBytes, bool path2DirectHl)
|
|
{
|
|
if (!data || sizeBytes < 16 || !m_processFn)
|
|
return;
|
|
|
|
GifArbiterPacket pkt;
|
|
pkt.pathId = pathId;
|
|
pkt.path2DirectHl = (pathId == GifPathId::Path2) && path2DirectHl;
|
|
pkt.path3Image = (pathId == GifPathId::Path3) && isImagePacket(data, sizeBytes);
|
|
pkt.data.resize(sizeBytes);
|
|
std::memcpy(pkt.data.data(), data, sizeBytes);
|
|
m_queue.push_back(std::move(pkt));
|
|
}
|
|
|
|
void GifArbiter::drain()
|
|
{
|
|
if (!m_processFn)
|
|
return;
|
|
|
|
std::stable_sort(m_queue.begin(), m_queue.end(),
|
|
[](const GifArbiterPacket &a, const GifArbiterPacket &b)
|
|
{
|
|
// DIRECTHL cannot preempt PATH3 IMAGE transfers.
|
|
if (a.path2DirectHl != b.path2DirectHl || a.path3Image != b.path3Image)
|
|
{
|
|
if (a.path3Image && b.path2DirectHl)
|
|
return true;
|
|
if (a.path2DirectHl && b.path3Image)
|
|
return false;
|
|
}
|
|
return pathPriority(a.pathId) < pathPriority(b.pathId);
|
|
});
|
|
|
|
for (size_t i = 0; i < m_queue.size(); ++i)
|
|
{
|
|
auto &pkt = m_queue[i];
|
|
if (!pkt.data.empty())
|
|
{
|
|
m_processFn(pkt.data.data(), static_cast<uint32_t>(pkt.data.size()));
|
|
}
|
|
}
|
|
m_queue.clear();
|
|
}
|
|
|
|
uint8_t GifArbiter::pathPriority(GifPathId id)
|
|
{
|
|
return static_cast<uint8_t>(id);
|
|
}
|