mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fix an ordering issue in Atrac context creation
This commit is contained in:
parent
8caec3c34d
commit
63c997b973
5 changed files with 64 additions and 91 deletions
|
@ -70,17 +70,16 @@ void DoClass(PointerWrap &p, T *&x) {
|
|||
x->DoState(p);
|
||||
}
|
||||
|
||||
template<class T, class S>
|
||||
void DoSubClass(PointerWrap &p, T *&x) {
|
||||
template<class T, class S, typename... Args>
|
||||
void DoSubClass(PointerWrap &p, T *&x, Args... args) {
|
||||
if (p.mode == PointerWrap::MODE_READ) {
|
||||
if (x != nullptr)
|
||||
delete x;
|
||||
x = new S();
|
||||
x = new S(args...);
|
||||
}
|
||||
x->DoState(p);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void DoArray(PointerWrap &p, T *x, int count) {
|
||||
DoHelper_<T>::DoArray(p, x, count);
|
||||
|
|
|
@ -188,7 +188,6 @@ public:
|
|||
outputChannels_ = channels;
|
||||
}
|
||||
|
||||
virtual void SetIDAndAddr(int atracID, u32 contextAddr) = 0;
|
||||
virtual int GetID() const = 0;
|
||||
|
||||
PSPPointer<SceAtracContext> context_{};
|
||||
|
@ -247,7 +246,7 @@ protected:
|
|||
|
||||
class Atrac : public AtracBase {
|
||||
public:
|
||||
Atrac(int codecType = 0) {
|
||||
Atrac(int atracID, int codecType = 0) : atracID_(atracID) {
|
||||
if (codecType) {
|
||||
track_.codecType = codecType;
|
||||
}
|
||||
|
@ -270,9 +269,6 @@ public:
|
|||
int GetNextDecodePosition(int *pos) const override;
|
||||
int RemainingFrames() const override;
|
||||
|
||||
void SetIDAndAddr(int atracID, u32 contextAddr) override {
|
||||
atracID_ = atracID;
|
||||
}
|
||||
int GetID() const override {
|
||||
return atracID_;
|
||||
}
|
||||
|
|
|
@ -35,13 +35,11 @@
|
|||
// * Half Minute Hero (bufsize 65536)
|
||||
// * Flatout (tricky! needs investigation)
|
||||
|
||||
Atrac2::Atrac2(int codecType) {
|
||||
track_.codecType = codecType;
|
||||
}
|
||||
|
||||
void Atrac2::SetIDAndAddr(int atracID, u32 contextAddr) {
|
||||
// Note: We don't allocate a context, we use memory directly from the loaded atrac binary (even if it's otherwise unused).
|
||||
Atrac2::Atrac2(int atracID, u32 contextAddr, int codecType) {
|
||||
context_ = PSPPointer<SceAtracContext>::Create(contextAddr);
|
||||
track_.codecType = codecType;
|
||||
context_->info.codec = codecType;
|
||||
}
|
||||
|
||||
void Atrac2::DoState(PointerWrap &p) {
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
|
||||
class Atrac2 : public AtracBase {
|
||||
public:
|
||||
Atrac2(int codecType);
|
||||
Atrac2(int atracID, u32 contextAddr, int codecType);
|
||||
void DoState(PointerWrap &p) override;
|
||||
|
||||
void SetIDAndAddr(int atracID, u32 contextAddr) override;
|
||||
int GetID() const override { return 0; }
|
||||
|
||||
int GetNextDecodePosition(int *pos) const { return 0; }
|
||||
|
|
|
@ -153,7 +153,7 @@ void __AtracDoState(PointerWrap &p) {
|
|||
bool valid = atracContexts[i] != nullptr;
|
||||
Do(p, valid);
|
||||
if (valid) {
|
||||
DoSubClass<AtracBase, Atrac>(p, atracContexts[i]);
|
||||
DoSubClass<AtracBase, Atrac>(p, atracContexts[i], i);
|
||||
} else {
|
||||
delete atracContexts[i];
|
||||
atracContexts[i] = nullptr;
|
||||
|
@ -170,17 +170,6 @@ void __AtracDoState(PointerWrap &p) {
|
|||
}
|
||||
}
|
||||
|
||||
static AtracBase *allocAtrac(int codecType = 0) {
|
||||
if (g_Config.bUseExperimentalAtrac) {
|
||||
// Note: This assert isn't really valid until we savestate the new contexts.
|
||||
_dbg_assert_(g_atracBSS != 0);
|
||||
return new Atrac2(codecType);
|
||||
} else {
|
||||
Atrac *atrac = new Atrac(codecType);
|
||||
return atrac;
|
||||
}
|
||||
}
|
||||
|
||||
static AtracBase *getAtrac(int atracID) {
|
||||
if (atracID < 0 || atracID >= PSP_MAX_ATRAC_IDS) {
|
||||
return nullptr;
|
||||
|
@ -192,22 +181,23 @@ static AtracBase *getAtrac(int atracID) {
|
|||
return atrac;
|
||||
}
|
||||
|
||||
static int RegisterAtrac(AtracBase *atrac) {
|
||||
static int AllocAndRegisterAtrac(int codecType) {
|
||||
for (int i = 0; i < g_atracMaxContexts; ++i) {
|
||||
if (atracContextTypes[i] == atrac->CodecType() && atracContexts[i] == 0) {
|
||||
atracContexts[i] = atrac;
|
||||
if (atracContextTypes[i] == codecType && atracContexts[i] == 0) {
|
||||
if (g_Config.bUseExperimentalAtrac) {
|
||||
// Note: This assert isn't really valid until we savestate the new contexts.
|
||||
_dbg_assert_(g_atracBSS != 0);
|
||||
atracContexts[i] = new Atrac2(i, GetAtracContextAddress(i), codecType);
|
||||
} else {
|
||||
atracContexts[i] = new Atrac(i, codecType);
|
||||
}
|
||||
atrac->SetIDAndAddr(i, GetAtracContextAddress(i));
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return SCE_ERROR_ATRAC_NO_ATRACID;
|
||||
}
|
||||
|
||||
static int deleteAtrac(int atracID) {
|
||||
static int UnregisterAndDeleteAtrac(int atracID) {
|
||||
if (atracID >= 0 && atracID < PSP_MAX_ATRAC_IDS) {
|
||||
if (atracContexts[atracID] != nullptr) {
|
||||
delete atracContexts[atracID];
|
||||
|
@ -225,10 +215,8 @@ static u32 sceAtracGetAtracID(int codecType) {
|
|||
return hleReportError(Log::ME, SCE_ERROR_ATRAC_INVALID_CODECTYPE, "invalid codecType");
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac(codecType);
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
int atracID = AllocAndRegisterAtrac(codecType);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
|
@ -543,7 +531,7 @@ static u32 sceAtracGetStreamDataInfo(int atracID, u32 writePtrAddr, u32 writable
|
|||
}
|
||||
|
||||
static u32 sceAtracReleaseAtracID(int atracID) {
|
||||
int result = deleteAtrac(atracID);
|
||||
int result = UnregisterAndDeleteAtrac(atracID);
|
||||
if (result < 0) {
|
||||
if (atracID >= 0) {
|
||||
return hleLogError(Log::ME, result, "did not exist");
|
||||
|
@ -655,17 +643,15 @@ static int sceAtracSetDataAndGetID(u32 buffer, int bufferSize) {
|
|||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, bufferSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, ret);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, bufferSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
return hleDelayResult(hleLogDebug(Log::ME, atracID), "atrac set data", 100);
|
||||
|
@ -682,17 +668,15 @@ static int sceAtracSetHalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 buffer
|
|||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, readSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, ret);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, readSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
return hleDelayResult(hleLogDebug(Log::ME, atracID), "atrac set data", 100);
|
||||
|
@ -803,6 +787,10 @@ static int sceAtracSetMOutHalfwayBuffer(int atracID, u32 buffer, u32 readSize, u
|
|||
}
|
||||
|
||||
ret = atrac->SetData(track, buffer, readSize, bufferSize, 1);
|
||||
if (ret < 0 && ret != SCE_ERROR_ATRAC_NOT_MONO) {
|
||||
// Must not delay.
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
return hleDelayResult(hleLogDebugOrError(Log::ME, ret), "atrac set data mono", 100);
|
||||
}
|
||||
|
||||
|
@ -823,10 +811,11 @@ static u32 sceAtracSetMOutData(int atracID, u32 buffer, u32 bufferSize) {
|
|||
}
|
||||
|
||||
ret = atrac->SetData(track, buffer, bufferSize, bufferSize, 1);
|
||||
if (ret < 0) {
|
||||
if (ret < 0 && ret != SCE_ERROR_ATRAC_NOT_MONO) {
|
||||
// Must not delay.
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
// It's OK if this fails, at least with NO_MONO...
|
||||
return hleDelayResult(hleLogDebugOrError(Log::ME, ret), "atrac set data mono", 100);
|
||||
}
|
||||
|
||||
|
@ -842,17 +831,15 @@ static int sceAtracSetMOutDataAndGetID(u32 buffer, u32 bufferSize) {
|
|||
return hleReportError(Log::ME, SCE_ERROR_ATRAC_NOT_MONO, "not mono data");
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, bufferSize, bufferSize, 1);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, ret);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, bufferSize, bufferSize, 1);
|
||||
if (ret < 0 && ret != SCE_ERROR_ATRAC_NOT_MONO) {
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
return hleDelayResult(hleLogDebugOrError(Log::ME, atracID), "atrac set data", 100);
|
||||
}
|
||||
|
@ -871,19 +858,16 @@ static int sceAtracSetMOutHalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 bu
|
|||
return hleReportError(Log::ME, SCE_ERROR_ATRAC_NOT_MONO, "not mono data");
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, readSize, bufferSize, 1);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, readSize, bufferSize, 1);
|
||||
if (ret < 0 && ret != SCE_ERROR_ATRAC_NOT_MONO) {
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
return hleDelayResult(hleLogDebug(Log::ME, atracID), "atrac set data", 100);
|
||||
}
|
||||
|
||||
|
@ -894,17 +878,15 @@ static int sceAtracSetAA3DataAndGetID(u32 buffer, u32 bufferSize, u32 fileSize,
|
|||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, bufferSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, ret);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, bufferSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
return hleDelayResult(hleLogDebug(Log::ME, atracID), "atrac set aa3 data", 100);
|
||||
|
@ -1013,18 +995,17 @@ static int sceAtracSetAA3HalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 buf
|
|||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
AtracBase *atrac = allocAtrac();
|
||||
ret = atrac->SetData(track, buffer, readSize, bufferSize, 2);
|
||||
int atracID = AllocAndRegisterAtrac(track.codecType);
|
||||
if (atracID < 0) {
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
|
||||
ret = atracContexts[atracID]->SetData(track, buffer, readSize, bufferSize, 2);
|
||||
if (ret < 0) {
|
||||
delete atrac;
|
||||
UnregisterAndDeleteAtrac(atracID);
|
||||
return hleLogError(Log::ME, ret);
|
||||
}
|
||||
|
||||
int atracID = RegisterAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
return hleLogError(Log::ME, atracID, "no free ID");
|
||||
}
|
||||
return hleDelayResult(hleLogDebug(Log::ME, atracID), "atrac set data", 100);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue