diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index c93332735a..8ffe3976e8 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -147,7 +147,6 @@ struct InputBuffer { struct Atrac; int __AtracSetContext(Atrac *atrac); -static void _AtracWriteContextToPSPMem(Atrac *atrac); struct AtracLoopInfo { int cuePointID; @@ -488,7 +487,7 @@ struct Atrac { } } - void UpdateFromPSPRam() { + void UpdateFromPSPMem() { if (context_.IsValid()) { // Read in any changes from the game to the context. // TODO: Might be better to just always track in RAM. @@ -498,6 +497,8 @@ struct Atrac { } } + void WriteContextToPSPMem(); + // To be moved into private. AtracStatus bufferState_ = ATRAC_STATUS_NO_DATA; @@ -585,7 +586,7 @@ static Atrac *getAtrac(int atracID) { } Atrac *atrac = atracContexts[atracID]; if (atrac) { - atrac->UpdateFromPSPRam(); + atrac->UpdateFromPSPMem(); } return atrac; } @@ -908,10 +909,7 @@ static u32 sceAtracGetAtracID(int codecType) { return hleLogSuccessInfoI(ME, atracID); } -u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) { - Atrac *atrac = getAtrac(atracID); - if (!atrac) - return 0; +static u32 _AtracAddStreamData(Atrac *atrac, u32 bufPtr, u32 bytesToAdd) { int addbytes = std::min(bytesToAdd, atrac->first_.filesize - atrac->first_.fileoffset - atrac->FirstOffsetExtra()); Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset + atrac->FirstOffsetExtra(), bufPtr, addbytes, "AtracAddStreamData"); atrac->first_.size += bytesToAdd; @@ -921,10 +919,8 @@ u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) { atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; } atrac->first_.fileoffset += addbytes; - if (atrac->context_.IsValid()) { - // refresh context_ - _AtracWriteContextToPSPMem(atrac); - } + // refresh context_ + atrac->WriteContextToPSPMem(); return 0; } @@ -1043,9 +1039,7 @@ static u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) { atrac->first_.size = atrac->first_.filesize; if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER) atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED; - if (atrac->context_.IsValid()) { - _AtracWriteContextToPSPMem(atrac); - } + atrac->WriteContextToPSPMem(); } atrac->first_.offset += bytesToAdd; @@ -1059,15 +1053,7 @@ static u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) { return hleLogSuccessI(ME, 0); } -u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) { - Atrac *atrac = getAtrac(atracID); - - if (atrac == NULL) { - return ATRAC_ERROR_BAD_ATRACID; - } else if (!atrac->dataBuf_) { - return ATRAC_ERROR_NO_DATA; - } - +static u32 _AtracDecodeData(Atrac *atrac, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) { int loopNum = atrac->loopNum_; if (atrac->bufferState_ == ATRAC_STATUS_FOR_SCESAS) { // TODO: Might need more testing. @@ -1078,10 +1064,8 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 if (atrac->currentSample_ >= atrac->endSample_ && loopNum == 0) { *SamplesNum = 0; *finish = 1; - if (atrac->context_.IsValid()) { - // refresh context_ - _AtracWriteContextToPSPMem(atrac); - } + // refresh context_ + atrac->WriteContextToPSPMem(); return ATRAC_ERROR_ALL_DATA_DECODED; } @@ -1198,20 +1182,24 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 *finish = finishFlag; *remains = atrac->RemainingFrames(); - if (atrac->context_.IsValid()) { - // refresh context_ - _AtracWriteContextToPSPMem(atrac); - } + // refresh context_ + atrac->WriteContextToPSPMem(); return 0; } +// Note that outAddr being null is completely valid here, used to skip data. static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishFlagAddr, u32 remainAddr) { - // Note that outAddr being null is completely valid here, used to skip data. + Atrac *atrac = getAtrac(atracID); + if (atrac == NULL) { + return ATRAC_ERROR_BAD_ATRACID; + } else if (!atrac->dataBuf_) { // TODO: Should check bufferState instead? + return ATRAC_ERROR_NO_DATA; + } u32 numSamples = 0; u32 finish = 0; int remains = 0; - int ret = _AtracDecodeData(atracID, Memory::GetPointerWrite(outAddr), outAddr, &numSamples, &finish, &remains); + int ret = _AtracDecodeData(atrac, Memory::GetPointerWrite(outAddr), outAddr, &numSamples, &finish, &remains); if (ret != (int)ATRAC_ERROR_BAD_ATRACID && ret != (int)ATRAC_ERROR_NO_DATA) { if (Memory::IsValidAddress(numSamplesAddr)) Memory::WriteUnchecked_U32(numSamples, numSamplesAddr); @@ -1637,9 +1625,7 @@ static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFi atrac->SeekToSample(sample); } - if (atrac->context_.IsValid()) { - _AtracWriteContextToPSPMem(atrac); - } + atrac->WriteContextToPSPMem(); return hleDelayResult(hleLogSuccessInfoI(ME, 0), "reset play pos", 3000); } @@ -1872,9 +1858,7 @@ static u32 sceAtracSetLoopNum(int atracID, int loopNum) { atrac->loopStartSample_ = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); atrac->loopEndSample_ = atrac->endSample_ + atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); } - if (atrac->context_.IsValid()) { - _AtracWriteContextToPSPMem(atrac); - } + atrac->WriteContextToPSPMem(); return hleLogSuccessI(ME, 0); } @@ -2067,46 +2051,43 @@ static int sceAtracSetAA3DataAndGetID(u32 buffer, u32 bufferSize, u32 fileSize, return _AtracSetData(atracID, buffer, bufferSize, bufferSize, true); } -// Used by SasAudio's AT3 integration. -int _AtracGetIDByContext(u32 contextAddr) { - int atracID = (int)Memory::Read_U32(contextAddr + 0xfc); - return atracID; -} - -void _AtracWriteContextToPSPMem(Atrac *atrac) { +void Atrac::WriteContextToPSPMem() { + if (!context_.IsValid()) { + return; + } // context points into PSP memory. - SceAtracContext *context = atrac->context_; - context->info.buffer = atrac->first_.addr; - context->info.bufferByte = atrac->bufferMaxSize_; - context->info.secondBuffer = atrac->second_.addr; - context->info.secondBufferByte = atrac->second_.size; - context->info.codec = atrac->codecType_; - context->info.loopNum = atrac->loopNum_; - context->info.loopStart = atrac->loopStartSample_ > 0 ? atrac->loopStartSample_ : 0; - context->info.loopEnd = atrac->loopEndSample_ > 0 ? atrac->loopEndSample_ : 0; + SceAtracContext *context = context_; + context->info.buffer = first_.addr; + context->info.bufferByte = bufferMaxSize_; + context->info.secondBuffer = second_.addr; + context->info.secondBufferByte = second_.size; + context->info.codec = codecType_; + context->info.loopNum = loopNum_; + context->info.loopStart = loopStartSample_ > 0 ? loopStartSample_ : 0; + context->info.loopEnd = loopEndSample_ > 0 ? loopEndSample_ : 0; // Note that we read in the state when loading the atrac object, so it's safe // to update it back here all the time. Some games, like Sol Trigger, change it. // TODO: Should we just keep this in PSP ram then, or something? - context->info.state = atrac->bufferState_; - if (atrac->firstSampleOffset_ != 0) { - context->info.samplesPerChan = atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); + context->info.state = bufferState_; + if (firstSampleOffset_ != 0) { + context->info.samplesPerChan = firstSampleOffset_ + FirstOffsetExtra(); } else { - context->info.samplesPerChan = (atrac->codecType_ == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES); + context->info.samplesPerChan = (codecType_ == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES); } - context->info.sampleSize = atrac->bytesPerFrame_; - context->info.numChan = atrac->channels_; - context->info.dataOff = atrac->dataOff_; - context->info.endSample = atrac->endSample_ + atrac->firstSampleOffset_ + atrac->FirstOffsetExtra(); - context->info.dataEnd = atrac->first_.filesize; - context->info.curOff = atrac->first_.fileoffset; - context->info.decodePos = atrac->DecodePosBySample(atrac->currentSample_); - context->info.streamDataByte = atrac->first_.size - atrac->dataOff_; + context->info.sampleSize = bytesPerFrame_; + context->info.numChan = channels_; + context->info.dataOff = dataOff_; + context->info.endSample = endSample_ + firstSampleOffset_ + FirstOffsetExtra(); + context->info.dataEnd = first_.filesize; + context->info.curOff = first_.fileoffset; + context->info.decodePos = DecodePosBySample(currentSample_); + context->info.streamDataByte = first_.size - dataOff_; u8 *buf = (u8 *)context; - *(u32_le *)(buf + 0xfc) = atrac->atracID_; + *(u32_le *)(buf + 0xfc) = atracID_; - NotifyMemInfo(MemBlockFlags::WRITE, atrac->context_.ptr, sizeof(SceAtracContext), "AtracContext"); + NotifyMemInfo(MemBlockFlags::WRITE, context_.ptr, sizeof(SceAtracContext), "AtracContext"); } static u32 _sceAtracGetContextAddress(int atracID) { @@ -2126,8 +2107,7 @@ static u32 _sceAtracGetContextAddress(int atracID) { } else WARN_LOG(ME, "%08x=_sceAtracGetContextAddress(%i)", atrac->context_.ptr, atracID); - if (atrac->context_.IsValid()) - _AtracWriteContextToPSPMem(atrac); + atrac->WriteContextToPSPMem(); return atrac->context_.ptr; } @@ -2207,9 +2187,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) { atrac->currentSample_ = 0; int ret = __AtracSetContext(atrac); - if (atrac->context_.IsValid()) { - _AtracWriteContextToPSPMem(atrac); - } + atrac->WriteContextToPSPMem(); if (ret < 0) { // Already logged. @@ -2268,6 +2246,27 @@ static int sceAtracSetAA3HalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 buf return _AtracSetData(atracID, buffer, readSize, bufferSize, true); } +// External interface used by sceSas' AT3 integration. + +u32 AtracSasAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) { + Atrac *atrac = getAtrac(atracID); + if (!atrac) + return 0; + return _AtracAddStreamData(atrac, bufPtr, bytesToAdd); +} + +u32 AtracSasDecodeData(int atracID, u8* outbuf, u32 outbufPtr, u32 *SamplesNum, u32* finish, int *remains) { + Atrac *atrac = getAtrac(atracID); + if (!atrac) + return 0; + return _AtracDecodeData(atrac, outbuf, outbufPtr, SamplesNum, finish, remains); +} + +int AtracSasGetIDByContext(u32 contextAddr) { + int atracID = (int)Memory::Read_U32(contextAddr + 0xfc); + return atracID; +} + const HLEFunction sceAtrac3plus[] = { {0X7DB31251, &WrapU_IU, "sceAtracAddStreamData", 'x', "ix" }, {0X6A8C3CD5, &WrapU_IUUUU, "sceAtracDecodeData", 'x', "ixppp"}, diff --git a/Core/HLE/sceAtrac.h b/Core/HLE/sceAtrac.h index 344f8c26f4..f29c59f798 100644 --- a/Core/HLE/sceAtrac.h +++ b/Core/HLE/sceAtrac.h @@ -25,6 +25,7 @@ void Register_sceAtrac3plus(); void __AtracInit(); void __AtracDoState(PointerWrap &p); void __AtracShutdown(); +void __AtracLoadModule(int version, u32 crc); enum AtracStatus : u8 { ATRAC_STATUS_NO_DATA = 1, @@ -84,9 +85,7 @@ struct SceAtracContext { SceAtracIdInfo info; }; -// provide some decoder interface - -u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd); -u32 _AtracDecodeData(int atracID, u8* outbuf, u32 outbufPtr, u32 *SamplesNum, u32* finish, int *remains); -int _AtracGetIDByContext(u32 contextAddr); -void __AtracLoadModule(int version, u32 crc); +// External interface used by sceSas. +u32 AtracSasAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd); +u32 AtracSasDecodeData(int atracID, u8* outbuf, u32 outbufPtr, u32 *SamplesNum, u32* finish, int *remains); +int AtracSasGetIDByContext(u32 contextAddr); diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 39ab2564c8..bfdb41834d 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -192,7 +192,7 @@ void VagDecoder::DoState(PointerWrap &p) { int SasAtrac3::setContext(u32 context) { contextAddr_ = context; - atracID_ = _AtracGetIDByContext(context); + atracID_ = AtracSasGetIDByContext(context); if (!sampleQueue_) sampleQueue_ = new BufferQueue(); sampleQueue_->clear(); @@ -211,7 +211,7 @@ void SasAtrac3::getNextSamples(s16 *outbuf, int wantedSamples) { u32 numSamples = 0; int remains = 0; static s16 buf[0x800]; - _AtracDecodeData(atracID_, (u8*)buf, 0, &numSamples, &finish, &remains); + AtracSasDecodeData(atracID_, (u8*)buf, 0, &numSamples, &finish, &remains); if (numSamples > 0) sampleQueue_->push((u8*)buf, numSamples * sizeof(s16)); else @@ -223,7 +223,7 @@ void SasAtrac3::getNextSamples(s16 *outbuf, int wantedSamples) { int SasAtrac3::addStreamData(u32 bufPtr, u32 addbytes) { if (atracID_ > 0) { - _AtracAddStreamData(atracID_, bufPtr, addbytes); + AtracSasAddStreamData(atracID_, bufPtr, addbytes); } return 0; }