mirror of https://github.com/AxioDL/metaforce.git
Integrate JBus
This commit is contained in:
parent
37a523db7e
commit
8af76017c2
|
@ -104,6 +104,9 @@ add_subdirectory(kabufuda)
|
||||||
include_directories(${KABUFUDA_INCLUDE_DIR})
|
include_directories(${KABUFUDA_INCLUDE_DIR})
|
||||||
add_subdirectory(Editor)
|
add_subdirectory(Editor)
|
||||||
|
|
||||||
|
add_subdirectory(jbus)
|
||||||
|
set(JBUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jbus/include)
|
||||||
|
|
||||||
set(CLIENT_SOURCES
|
set(CLIENT_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.hpp
|
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.hpp
|
||||||
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.cpp
|
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.cpp
|
||||||
|
@ -111,8 +114,6 @@ set(CLIENT_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryMP1.cpp)
|
${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryMP1.cpp)
|
||||||
add_subdirectory(Runtime)
|
add_subdirectory(Runtime)
|
||||||
add_subdirectory(mpcksum)
|
add_subdirectory(mpcksum)
|
||||||
add_subdirectory(jbus)
|
|
||||||
set(JBUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jbus/include)
|
|
||||||
add_subdirectory(gbalink)
|
add_subdirectory(gbalink)
|
||||||
|
|
||||||
unset(GIT_EXECUTABLE CACHE)
|
unset(GIT_EXECUTABLE CACHE)
|
||||||
|
|
|
@ -43,8 +43,9 @@ target_link_libraries(urde
|
||||||
RuntimeCommon
|
RuntimeCommon
|
||||||
specter specter-fonts freetype ${DATA_SPEC_LIBS}
|
specter specter-fonts freetype ${DATA_SPEC_LIBS}
|
||||||
hecl-common hecl-blender-addon
|
hecl-common hecl-blender-addon
|
||||||
athena-core nod logvisor athena-libyaml amuse boo ${PNG_LIB} libjpeg-turbo squish xxhash zeus
|
athena-core nod logvisor athena-libyaml amuse boo
|
||||||
kabufuda ${ZLIB_LIBRARIES} ${LZO_LIB}
|
${PNG_LIB} libjpeg-turbo squish xxhash zeus
|
||||||
|
kabufuda jbus ${ZLIB_LIBRARIES} ${LZO_LIB}
|
||||||
${BOO_SYS_LIBS})
|
${BOO_SYS_LIBS})
|
||||||
|
|
||||||
set_target_properties(urde PROPERTIES
|
set_target_properties(urde PROPERTIES
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR} ${LIBJPEG_INCLUDE_DIR}
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR} ${LIBJPEG_INCLUDE_DIR}
|
||||||
${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec)
|
${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec ${JBUS_INCLUDE_DIR})
|
||||||
|
|
||||||
macro(runtime_add_list rel_path a_list)
|
macro(runtime_add_list rel_path a_list)
|
||||||
unset(tmp_list)
|
unset(tmp_list)
|
||||||
|
|
|
@ -1,70 +1,49 @@
|
||||||
#include "CGBASupport.hpp"
|
#include "CGBASupport.hpp"
|
||||||
#include "CDvdRequest.hpp"
|
#include "CDvdRequest.hpp"
|
||||||
#include "CBasics.hpp"
|
#include "CBasics.hpp"
|
||||||
|
#include "jbus/Listener.hpp"
|
||||||
|
#include "jbus/Endpoint.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
namespace MP1
|
namespace MP1
|
||||||
{
|
{
|
||||||
|
|
||||||
#define GBA_JSTAT_MASK 0x3a
|
static jbus::Listener g_JbusListener;
|
||||||
#define GBA_JSTAT_FLAGS_SHIFT 4
|
static std::unique_ptr<jbus::Endpoint> g_JbusEndpoint;
|
||||||
#define GBA_JSTAT_FLAGS_MASK 0x30
|
|
||||||
#define GBA_JSTAT_PSF1 0x20
|
|
||||||
#define GBA_JSTAT_PSF0 0x10
|
|
||||||
#define GBA_JSTAT_SEND 0x08
|
|
||||||
#define GBA_JSTAT_RECV 0x02
|
|
||||||
|
|
||||||
#define GBA_READY 0
|
void CGBASupport::Initialize()
|
||||||
#define GBA_NOT_READY 1
|
|
||||||
#define GBA_BUSY 2
|
|
||||||
#define GBA_JOYBOOT_UNKNOWN_STATE 3
|
|
||||||
#define GBA_JOYBOOT_ERR_INVALID 4
|
|
||||||
|
|
||||||
static void GBAInit()
|
|
||||||
{
|
{
|
||||||
|
jbus::Initialize();
|
||||||
|
g_JbusListener.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 GBAJoyBootAsync(s32 chan, s32 paletteColor, s32 paletteSpeed,
|
void CGBASupport::GlobalPoll()
|
||||||
u8* programp, s32 length, u8* status)
|
|
||||||
{
|
{
|
||||||
return GBA_READY;
|
if (g_JbusEndpoint && !g_JbusEndpoint->connected())
|
||||||
}
|
g_JbusEndpoint.reset();
|
||||||
|
if (!g_JbusEndpoint)
|
||||||
static s32 GBAGetProcessStatus(s32 chan, u8* percentp)
|
|
||||||
{
|
|
||||||
return GBA_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 GBAGetStatus(s32 chan, u8* status)
|
|
||||||
{
|
|
||||||
return GBA_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 GBAReset(s32 chan, u8* status)
|
|
||||||
{
|
|
||||||
return GBA_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 GBARead(s32 chan, u8* dst, u8* status)
|
|
||||||
{
|
|
||||||
return GBA_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 GBAWrite(s32 chan, u8* src, u8* status)
|
|
||||||
{
|
|
||||||
return GBA_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 calculateJBusChecksum(const u8* data, size_t len)
|
|
||||||
{
|
|
||||||
const u8* ptr = data;
|
|
||||||
u32 sum = -1;
|
|
||||||
for (int i = len ; i > 0; --i)
|
|
||||||
{
|
{
|
||||||
u8 ch = *ptr;
|
g_JbusEndpoint = g_JbusListener.accept();
|
||||||
ptr++;
|
if (g_JbusEndpoint)
|
||||||
|
g_JbusEndpoint->setChan(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGBASupport::CGBASupport()
|
||||||
|
: CDvdFile("client_pad.bin")
|
||||||
|
{
|
||||||
|
x28_fileSize = ROUND_UP_32(Length());
|
||||||
|
x2c_buffer.reset(new u8[x28_fileSize]);
|
||||||
|
x30_dvdReq = AsyncRead(x2c_buffer.get(), x28_fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 CGBASupport::CalculateFusionJBusChecksum(const u8* data, size_t len)
|
||||||
|
{
|
||||||
|
u32 sum = -1;
|
||||||
|
for (int i = 0 ; i < len; ++i)
|
||||||
|
{
|
||||||
|
u8 ch = *data++;
|
||||||
sum ^= ch;
|
sum ^= ch;
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
{
|
{
|
||||||
|
@ -77,92 +56,78 @@ static u32 calculateJBusChecksum(const u8* data, size_t len)
|
||||||
sum >>= 1;
|
sum >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGBASupport* CGBASupport::SharedInstance = nullptr;
|
|
||||||
|
|
||||||
CGBASupport::CGBASupport()
|
|
||||||
: CDvdFile("client_pad.bin")
|
|
||||||
{
|
|
||||||
x28_fileSize = ROUND_UP_32(Length());
|
|
||||||
x2c_buffer.reset(new u8[x28_fileSize]);
|
|
||||||
x30_dvdReq = AsyncRead(x2c_buffer.get(), x28_fileSize);
|
|
||||||
GBAInit();
|
|
||||||
SharedInstance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGBASupport::~CGBASupport()
|
|
||||||
{
|
|
||||||
SharedInstance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CGBASupport::PollResponse()
|
bool CGBASupport::PollResponse()
|
||||||
{
|
{
|
||||||
|
if (!g_JbusEndpoint)
|
||||||
|
return false;
|
||||||
|
|
||||||
u8 status;
|
u8 status;
|
||||||
if (GBAReset(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAReset(&status) == jbus::GBA_NOT_READY)
|
||||||
if (GBAReset(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAReset(&status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GBAGetStatus(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
if (status != (GBA_JSTAT_PSF1 | GBA_JSTAT_SEND))
|
if (status != (jbus::GBA_JSTAT_PSF1 | jbus::GBA_JSTAT_SEND))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u8 bytes[4];
|
u8 bytes[4];
|
||||||
if (GBARead(x40_siChan, bytes, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBARead(bytes, &status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
if (reinterpret_cast<u32&>(bytes) != SBIG('AMTE'))
|
if (reinterpret_cast<u32&>(bytes) != SBIG('AMTE'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GBAGetStatus(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
if (status != GBA_JSTAT_PSF1)
|
if (status != jbus::GBA_JSTAT_PSF1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GBAWrite(x40_siChan, (unsigned char*)"AMTE", &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAWrite((unsigned char*)"AMTE", &status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GBAGetStatus(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
||||||
return false;
|
return false;
|
||||||
if ((status & GBA_JSTAT_FLAGS_MASK) != GBA_JSTAT_FLAGS_MASK)
|
if ((status & jbus::GBA_JSTAT_FLAGS_MASK) != jbus::GBA_JSTAT_FLAGS_MASK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u64 profStart = CBasics::GetGCTicks();
|
u64 profStart = jbus::GetGCTicks();
|
||||||
const u64 timeToSpin = 486000000 / 8000;
|
const u64 timeToSpin = jbus::GetGCTicksPerSec() / 8000;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
u64 curTime = CBasics::GetGCTicks();
|
u64 curTime = jbus::GetGCTicks();
|
||||||
if (curTime - profStart > timeToSpin)
|
if (curTime - profStart > timeToSpin)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (GBAGetStatus(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
||||||
continue;
|
continue;
|
||||||
if (!(status & GBA_JSTAT_SEND))
|
if (!(status & jbus::GBA_JSTAT_SEND))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (GBAGetStatus(x40_siChan, &status) == GBA_NOT_READY)
|
if (g_JbusEndpoint->GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
||||||
continue;
|
continue;
|
||||||
if (status != (GBA_JSTAT_FLAGS_MASK | GBA_JSTAT_SEND))
|
if (status != (jbus::GBA_JSTAT_FLAGS_MASK | jbus::GBA_JSTAT_SEND))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GBARead(x40_siChan, bytes, &status) != GBA_READY)
|
if (g_JbusEndpoint->GBARead(bytes, &status) != jbus::GBA_READY)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u32 swapped = hecl::SBig(reinterpret_cast<u32&>(bytes));
|
if (bytes[3] != CalculateFusionJBusChecksum(bytes, 3))
|
||||||
if (bytes[0] != calculateJBusChecksum(reinterpret_cast<u8*>(&swapped), 3))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
x44_fusionLinked = (bytes[2] & 0x2) != 0;
|
x44_fusionLinked = (bytes[2] & 0x2) == 0;
|
||||||
if (x44_fusionLinked && (bytes[2] & 0x1) != 0)
|
if (x44_fusionLinked && (bytes[2] & 0x1) != 0)
|
||||||
x45_fusionBeat = true;
|
x45_fusionBeat = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void JoyBootDone(jbus::ThreadLocalEndpoint& endpoint, jbus::EJoyReturn status) {}
|
||||||
|
|
||||||
void CGBASupport::Update(float dt)
|
void CGBASupport::Update(float dt)
|
||||||
{
|
{
|
||||||
switch (x34_phase)
|
switch (x34_phase)
|
||||||
|
@ -177,17 +142,29 @@ void CGBASupport::Update(float dt)
|
||||||
|
|
||||||
case EPhase::PollProbe:
|
case EPhase::PollProbe:
|
||||||
/* SIProbe poll normally occurs here with 4 second timeout */
|
/* SIProbe poll normally occurs here with 4 second timeout */
|
||||||
|
if (!g_JbusEndpoint)
|
||||||
|
{
|
||||||
|
x34_phase = EPhase::Failed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
x40_siChan = g_JbusEndpoint->getChan();
|
||||||
x34_phase = EPhase::StartJoyBusBoot;
|
x34_phase = EPhase::StartJoyBusBoot;
|
||||||
|
|
||||||
case EPhase::StartJoyBusBoot:
|
case EPhase::StartJoyBusBoot:
|
||||||
x34_phase = EPhase::PollJoyBusBoot;
|
x34_phase = EPhase::PollJoyBusBoot;
|
||||||
GBAJoyBootAsync(x40_siChan, x40_siChan * 2, 2, x2c_buffer.get(), x28_fileSize, &x3c_status);
|
if (!g_JbusEndpoint || g_JbusEndpoint->GBAJoyBootAsync(x40_siChan * 2, 2,
|
||||||
|
x2c_buffer.get(), x28_fileSize, &x3c_status,
|
||||||
|
std::bind(JoyBootDone,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2)) != jbus::GBA_READY)
|
||||||
|
x34_phase = EPhase::Failed;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPhase::PollJoyBusBoot:
|
case EPhase::PollJoyBusBoot:
|
||||||
if (GBAGetProcessStatus(x40_siChan, &x3c_status) == GBA_BUSY)
|
u8 percent;
|
||||||
|
if (g_JbusEndpoint && g_JbusEndpoint->GBAGetProcessStatus(percent) == jbus::GBA_BUSY)
|
||||||
break;
|
break;
|
||||||
if (GBAGetStatus(x40_siChan, &x3c_status) == GBA_NOT_READY)
|
if (!g_JbusEndpoint || g_JbusEndpoint->GBAGetStatus(&x3c_status) == jbus::GBA_NOT_READY)
|
||||||
{
|
{
|
||||||
x34_phase = EPhase::Failed;
|
x34_phase = EPhase::Failed;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,18 +27,21 @@ public:
|
||||||
private:
|
private:
|
||||||
u32 x28_fileSize;
|
u32 x28_fileSize;
|
||||||
std::unique_ptr<u8[]> x2c_buffer;
|
std::unique_ptr<u8[]> x2c_buffer;
|
||||||
std::shared_ptr<IDvdRequest> x30_dvdReq;
|
|
||||||
EPhase x34_phase = EPhase::LoadClientPad;
|
EPhase x34_phase = EPhase::LoadClientPad;
|
||||||
float x38_timeout = 0.f;
|
float x38_timeout = 0.f;
|
||||||
|
std::shared_ptr<IDvdRequest> x30_dvdReq;
|
||||||
u8 x3c_status = 0;
|
u8 x3c_status = 0;
|
||||||
u32 x40_siChan = -1;
|
u32 x40_siChan = -1;
|
||||||
bool x44_fusionLinked = false;
|
bool x44_fusionLinked = false;
|
||||||
bool x45_fusionBeat = false;
|
bool x45_fusionBeat = false;
|
||||||
static CGBASupport* SharedInstance;
|
|
||||||
|
static u8 CalculateFusionJBusChecksum(const u8* data, size_t len);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static void Initialize();
|
||||||
|
static void GlobalPoll();
|
||||||
|
|
||||||
CGBASupport();
|
CGBASupport();
|
||||||
~CGBASupport();
|
|
||||||
bool PollResponse();
|
bool PollResponse();
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
bool IsReady();
|
bool IsReady();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Graphics/Shaders/CCameraBlurFilter.hpp"
|
#include "Graphics/Shaders/CCameraBlurFilter.hpp"
|
||||||
#include "Graphics/Shaders/CXRayBlurFilter.hpp"
|
#include "Graphics/Shaders/CXRayBlurFilter.hpp"
|
||||||
#include "Character/CCharLayoutInfo.hpp"
|
#include "Character/CCharLayoutInfo.hpp"
|
||||||
|
#include "CGBASupport.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -119,6 +120,7 @@ void CMain::InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr
|
||||||
CElementGen::Initialize();
|
CElementGen::Initialize();
|
||||||
CAnimData::InitializeCache();
|
CAnimData::InitializeCache();
|
||||||
CDecalManager::Initialize();
|
CDecalManager::Initialize();
|
||||||
|
CGBASupport::Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMain::FillInAssetIDs()
|
void CMain::FillInAssetIDs()
|
||||||
|
@ -154,6 +156,7 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||||
|
|
||||||
bool CMain::Proc()
|
bool CMain::Proc()
|
||||||
{
|
{
|
||||||
|
CGBASupport::GlobalPoll();
|
||||||
xe8_b24_finished = m_archSupport->Update();
|
xe8_b24_finished = m_archSupport->Update();
|
||||||
return xe8_b24_finished;
|
return xe8_b24_finished;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ void CGBASupport::Update(float dt)
|
||||||
|
|
||||||
case EPhase::PollProbe:
|
case EPhase::PollProbe:
|
||||||
/* SIProbe poll normally occurs here with 4 second timeout */
|
/* SIProbe poll normally occurs here with 4 second timeout */
|
||||||
x40_siChan = m_endpoint->GetChan();
|
x40_siChan = m_endpoint->getChan();
|
||||||
x34_phase = EPhase::StartJoyBusBoot;
|
x34_phase = EPhase::StartJoyBusBoot;
|
||||||
|
|
||||||
case EPhase::StartJoyBusBoot:
|
case EPhase::StartJoyBusBoot:
|
||||||
|
|
2
jbus
2
jbus
|
@ -1 +1 @@
|
||||||
Subproject commit 4699542f937ff96a087915e6ff98bf6ceac877c7
|
Subproject commit 9db987d3ddbc178883a7b2168367fe8b4ec29c05
|
Loading…
Reference in New Issue