From 350c7b01d5f52ad51b6fd7511d84118a30d73aea Mon Sep 17 00:00:00 2001 From: capitalistspz Date: Thu, 22 Jan 2026 13:22:35 +0000 Subject: [PATCH] Implement `WENCGetEncodeData` --- src/Cafe/OS/libs/padscore/padscore.cpp | 66 +++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/Cafe/OS/libs/padscore/padscore.cpp b/src/Cafe/OS/libs/padscore/padscore.cpp index 8612261a..69df0af6 100644 --- a/src/Cafe/OS/libs/padscore/padscore.cpp +++ b/src/Cafe/OS/libs/padscore/padscore.cpp @@ -38,6 +38,23 @@ enum class WPADLed : uint8 CHAN3 = (1 << 3), }; +struct WENCParams +{ + sint32be predSample; + sint32be step; + sint32be ukn0x8; + sint32be tempDiff; + sint32be step1; + sint32be step2; +}; +static_assert(offsetof(WENCParams, predSample) == 0x0); +static_assert(offsetof(WENCParams, step) == 0x04); +static_assert(offsetof(WENCParams, ukn0x8) == 0x08); +static_assert(offsetof(WENCParams, tempDiff) == 0xc); +static_assert(offsetof(WENCParams, step1) == 0x10); +static_assert(offsetof(WENCParams, step2) == 0x14); +static_assert(sizeof(WENCParams) == 24); + namespace padscore { enum WPADState_t @@ -686,8 +703,54 @@ namespace padscore acc->z = 99; } + uint32 WENCGetEncodeData(WENCParams* params, uint32 continuing, sint16be* lpcmSamples, uint32 lpcmSampleCount, uint8* adpcmSamples) + { + constexpr static std::array ADPCM_TABLE = {0.8984375, 0.8984375, 0.8984375, 0.8984375, 1.19921875, 1.59765625, 2.0, 2.3984375}; + const auto adpcmSampleCount = (lpcmSampleCount + 1) / 2; -#pragma endregion + WENCParams locParams = continuing ? *params : WENCParams{ .step = 0x7f}; + + std::memset(adpcmSamples, 0, adpcmSampleCount); + + for (auto lpcmSampleIndex = 0u; lpcmSampleIndex < lpcmSampleCount; ++lpcmSampleIndex) + { + const sint16 currentSample = lpcmSamples[lpcmSampleIndex]; + const sint32 sampleDiff = currentSample - locParams.predSample; + locParams.tempDiff = std::abs(sampleDiff); + const unsigned diffSign = currentSample < locParams.predSample; + const bool flag1 = locParams.step <= locParams.tempDiff; + if (flag1) + locParams.tempDiff -= locParams.step; + locParams.step1 = locParams.step / 2; + const bool flag2 = locParams.step1 <= locParams.tempDiff; + if (flag2) + { + locParams.tempDiff -= locParams.step1; + } + locParams.step2 = locParams.step1 / 2; + const bool flag3 = locParams.step2 <= locParams.tempDiff; + if (flag3) + { + locParams.tempDiff -= locParams.step2; + } + locParams.ukn0x8 = (diffSign * -2 + 1) * (locParams.step * flag1 + locParams.step1 * flag2 + locParams.step2 * flag3 + (locParams.step2 / 2)); + locParams.ukn0x8 = std::clamp(locParams.ukn0x8, -0x10000, 0x0ffff); + + locParams.predSample += locParams.ukn0x8; + locParams.predSample = std::clamp(locParams.predSample, -0x8000, 0x7fff); + + const auto shiftAmount = lpcmSampleIndex & 1 ? 0 : 4; + + const auto tableIndex = flag1 << 2 | flag2 << 1 | flag3; + + const auto adpcmSampleIndex = lpcmSampleIndex / 2; + locParams.step *= (locParams.step) * ADPCM_TABLE[tableIndex]; + adpcmSamples[adpcmSampleIndex] = adpcmSamples[adpcmSampleIndex] | uint8be((diffSign * 8 + tableIndex) << shiftAmount); + locParams.step = std::clamp(locParams.step, 0x7f, 0x6000); + } + *params = locParams; + return lpcmSampleCount; + } void TickFunction(PPCInterpreter_t* hCPU) { @@ -770,6 +833,7 @@ namespace padscore { cafeExportRegister("padscore", WPADIsMplsAttached, LogType::InputAPI); cafeExportRegister("padscore", WPADGetAccGravityUnit, LogType::InputAPI); + cafeExportRegister("padscore", WENCGetEncodeData, LogType::SoundAPI); // wpad //osLib_addFunction("padscore", "WPADInit", padscore::export_WPADInit);