mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Prepare for Atrac context data to work the new way. Not actually active yet. Also restrict old versions to 4 contexts.
This commit is contained in:
parent
4fbdb58beb
commit
b7782d98f3
7 changed files with 84 additions and 49 deletions
|
@ -39,6 +39,10 @@ const int DATA_CHUNK_MAGIC = 0x61746164;
|
|||
const int SMPL_CHUNK_MAGIC = 0x6C706D73;
|
||||
const int FACT_CHUNK_MAGIC = 0x74636166;
|
||||
|
||||
Atrac::~Atrac() {
|
||||
ResetData();
|
||||
}
|
||||
|
||||
void Atrac::DoState(PointerWrap &p) {
|
||||
auto s = p.Section("Atrac", 1, 9);
|
||||
if (!s)
|
||||
|
@ -171,15 +175,13 @@ u8 *Atrac::BufferStart() {
|
|||
return ignoreDataBuf_ ? Memory::GetPointerWrite(first_.addr) : dataBuf_;
|
||||
}
|
||||
|
||||
void AtracBase::UpdateContextFromPSPMem() {
|
||||
void Atrac::UpdateContextFromPSPMem() {
|
||||
if (!context_.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read in any changes from the game to the context.
|
||||
// TODO: Might be better to just always track in RAM.
|
||||
// TODO: It's possible that there are more changes we should read. Who knows,
|
||||
// problem games like FlatOut might poke stuff into the context?
|
||||
// TODO: Might be better to just always track in RAM. Actually, Atrac2 will do that.
|
||||
bufferState_ = context_->info.state;
|
||||
// This value is actually abused by games to store the SAS voice number.
|
||||
loopNum_ = context_->info.loopNum;
|
||||
|
@ -1216,3 +1218,18 @@ int Atrac::DecodeLowLevel(const u8 *srcData, int *bytesConsumed, s16 *dstData, i
|
|||
// TODO: Possibly return a decode error on bad data.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Atrac::NotifyGetContextAddress() {
|
||||
if (!context_.IsValid()) {
|
||||
// allocate a new context_
|
||||
u32 contextSize = sizeof(SceAtracContext);
|
||||
// Note that Alloc can increase contextSize to the "grain" size.
|
||||
context_ = kernelMemory.Alloc(contextSize, false, StringFromFormat("AtracCtx/%d", atracID_).c_str());
|
||||
if (context_.IsValid())
|
||||
Memory::Memset(context_.ptr, 0, contextSize, "AtracContextClear");
|
||||
WARN_LOG(Log::ME, "%08x=_sceAtracGetContextAddress(%i): allocated new context", context_.ptr, atracID_);
|
||||
} else {
|
||||
WARN_LOG(Log::ME, "%08x=_sceAtracGetContextAddress(%i)", context_.ptr, atracID_);
|
||||
}
|
||||
WriteContextToPSPMem();
|
||||
}
|
||||
|
|
|
@ -175,6 +175,9 @@ public:
|
|||
|
||||
virtual void DoState(PointerWrap &p) = 0;
|
||||
|
||||
// TODO: Find a way to get rid of this from the base class.
|
||||
virtual void UpdateContextFromPSPMem() = 0;
|
||||
|
||||
virtual int Channels() const = 0;
|
||||
|
||||
int GetOutputChannels() const {
|
||||
|
@ -185,7 +188,7 @@ public:
|
|||
outputChannels_ = channels;
|
||||
}
|
||||
|
||||
virtual void SetID(int id) = 0;
|
||||
virtual void SetIDAndAddr(int atracID, u32 contextAddr) = 0;
|
||||
virtual int GetID() const = 0;
|
||||
|
||||
PSPPointer<SceAtracContext> context_{};
|
||||
|
@ -207,6 +210,8 @@ public:
|
|||
|
||||
void CreateDecoder();
|
||||
|
||||
virtual void NotifyGetContextAddress() = 0;
|
||||
|
||||
virtual int GetNextDecodePosition(int *pos) const = 0;
|
||||
virtual int RemainingFrames() const = 0;
|
||||
virtual u32 SecondBufferSize() const = 0;
|
||||
|
@ -214,9 +219,6 @@ public:
|
|||
virtual int BytesPerFrame() const = 0;
|
||||
virtual int SamplesPerFrame() const = 0;
|
||||
|
||||
void UpdateContextFromPSPMem();
|
||||
virtual void WriteContextToPSPMem() = 0;
|
||||
|
||||
virtual void GetStreamDataInfo(u32 *writePtr, u32 *writableBytes, u32 *readOffset) = 0;
|
||||
virtual int AddStreamData(u32 bytesToAdd) = 0;
|
||||
virtual u32 AddStreamDataSas(u32 bufPtr, u32 bytesToAdd) = 0;
|
||||
|
@ -245,9 +247,12 @@ protected:
|
|||
|
||||
class Atrac : public AtracBase {
|
||||
public:
|
||||
~Atrac() {
|
||||
ResetData();
|
||||
Atrac(int codecType = 0) {
|
||||
if (codecType) {
|
||||
track_.codecType = codecType;
|
||||
}
|
||||
}
|
||||
~Atrac();
|
||||
|
||||
uint32_t CurBufferAddress(int adjust = 0) const {
|
||||
u32 off = track_.FileOffsetBySample(currentSample_ + adjust);
|
||||
|
@ -261,13 +266,12 @@ public:
|
|||
u8 *BufferStart();
|
||||
|
||||
void DoState(PointerWrap &p) override;
|
||||
void WriteContextToPSPMem() override;
|
||||
|
||||
int GetNextDecodePosition(int *pos) const override;
|
||||
int RemainingFrames() const override;
|
||||
|
||||
void SetID(int id) override {
|
||||
atracID_ = id;
|
||||
void SetIDAndAddr(int atracID, u32 contextAddr) override {
|
||||
atracID_ = atracID;
|
||||
}
|
||||
int GetID() const override {
|
||||
return atracID_;
|
||||
|
@ -322,6 +326,10 @@ public:
|
|||
|
||||
int GetSoundSample(int *endSample, int *loopStartSample, int *loopEndSample) const override;
|
||||
|
||||
void NotifyGetContextAddress() override;
|
||||
void UpdateContextFromPSPMem() override;
|
||||
void WriteContextToPSPMem();
|
||||
|
||||
private:
|
||||
void UpdateBufferState();
|
||||
void ResetData();
|
||||
|
|
|
@ -39,11 +39,13 @@ Atrac2::Atrac2(int codecType) {
|
|||
track_.codecType = codecType;
|
||||
}
|
||||
|
||||
void Atrac2::DoState(PointerWrap &p) {
|
||||
_assert_msg_(false, "Savestates not yet support with new Atrac implementation.\n\nTurn it off in Developer settings.\n\n");
|
||||
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).
|
||||
context_ = PSPPointer<SceAtracContext>::Create(contextAddr);
|
||||
}
|
||||
|
||||
void Atrac2::WriteContextToPSPMem() {
|
||||
void Atrac2::DoState(PointerWrap &p) {
|
||||
_assert_msg_(false, "Savestates not yet support with new Atrac implementation.\n\nTurn it off in Developer settings.\n\n");
|
||||
}
|
||||
|
||||
int Atrac2::RemainingFrames() const {
|
||||
|
|
|
@ -9,9 +9,8 @@ class Atrac2 : public AtracBase {
|
|||
public:
|
||||
Atrac2(int codecType);
|
||||
void DoState(PointerWrap &p) override;
|
||||
void WriteContextToPSPMem() override;
|
||||
|
||||
void SetID(int id) override {}
|
||||
void SetIDAndAddr(int atracID, u32 contextAddr) override;
|
||||
int GetID() const override { return 0; }
|
||||
|
||||
int GetNextDecodePosition(int *pos) const { return 0; }
|
||||
|
@ -40,6 +39,10 @@ public:
|
|||
|
||||
int GetSoundSample(int *endSample, int *loopStartSample, int *loopEndSample) const override;
|
||||
|
||||
// These will not be used by the new implementation.
|
||||
void UpdateContextFromPSPMem() override {}
|
||||
void NotifyGetContextAddress() override {}
|
||||
|
||||
private:
|
||||
int currentSample_ = 0;
|
||||
};
|
||||
|
|
|
@ -79,10 +79,12 @@
|
|||
static const int atracDecodeDelay = 2300;
|
||||
|
||||
static bool atracInited = true;
|
||||
static AtracBase *atracContexts[PSP_NUM_ATRAC_IDS];
|
||||
static u32 atracContextTypes[PSP_NUM_ATRAC_IDS];
|
||||
static AtracBase *atracContexts[PSP_MAX_ATRAC_IDS];
|
||||
static u32 atracContextTypes[PSP_MAX_ATRAC_IDS];
|
||||
static int atracLibVersion = 0;
|
||||
static u32 atracLibCrc = 0;
|
||||
static int g_atracMaxContexts = 6;
|
||||
static int g_atracBSS = 0;
|
||||
|
||||
// For debugger only.
|
||||
const AtracBase *__AtracGetCtx(int i, u32 *type) {
|
||||
|
@ -97,6 +99,8 @@ void __AtracInit() {
|
|||
|
||||
atracLibVersion = 0;
|
||||
atracLibCrc = 0;
|
||||
g_atracMaxContexts = 6;
|
||||
g_atracBSS = 0;
|
||||
|
||||
atracInited = true; // TODO: This should probably only happen in __AtracNotifyLoadModule.
|
||||
|
||||
|
@ -122,12 +126,21 @@ void __AtracNotifyLoadModule(int version, u32 crc, u32 bssAddr, int bssSize) {
|
|||
atracLibVersion = version;
|
||||
atracLibCrc = crc;
|
||||
INFO_LOG(Log::ME, "Atrac module loaded: atracLibVersion 0x%0x, atracLibcrc %x, bss: %x (%x bytes)", atracLibVersion, atracLibCrc, bssAddr, bssSize);
|
||||
// Later, save bssAddr/bssSize and use them to return context addresses.
|
||||
g_atracBSS = bssAddr;
|
||||
g_atracMaxContexts = atracLibVersion <= 0x101 ? 4 : 6; // Need to figure out where the cutoff is.
|
||||
_dbg_assert_(bssSize >= g_atracMaxContexts * sizeof(SceAtracContext));
|
||||
}
|
||||
|
||||
void __AtracNotifyUnloadModule() {
|
||||
atracLibVersion = 0;
|
||||
atracLibCrc = 0;
|
||||
INFO_LOG(Log::ME, "Atrac module unloaded.");
|
||||
g_atracBSS = 0;
|
||||
g_atracMaxContexts = 6; // TODO: We should make this zero here.
|
||||
}
|
||||
|
||||
static u32 GetAtracContextAddress(int atracID) {
|
||||
return g_atracBSS + atracID * sizeof(SceAtracContext);
|
||||
}
|
||||
|
||||
void __AtracDoState(PointerWrap &p) {
|
||||
|
@ -136,7 +149,7 @@ void __AtracDoState(PointerWrap &p) {
|
|||
return;
|
||||
|
||||
Do(p, atracInited);
|
||||
for (int i = 0; i < PSP_NUM_ATRAC_IDS; ++i) {
|
||||
for (int i = 0; i < PSP_MAX_ATRAC_IDS; ++i) {
|
||||
bool valid = atracContexts[i] != nullptr;
|
||||
Do(p, valid);
|
||||
if (valid) {
|
||||
|
@ -146,7 +159,7 @@ void __AtracDoState(PointerWrap &p) {
|
|||
atracContexts[i] = nullptr;
|
||||
}
|
||||
}
|
||||
DoArray(p, atracContextTypes, PSP_NUM_ATRAC_IDS);
|
||||
DoArray(p, atracContextTypes, PSP_MAX_ATRAC_IDS);
|
||||
if (s < 2) {
|
||||
atracLibVersion = 0;
|
||||
atracLibCrc = 0;
|
||||
|
@ -159,18 +172,17 @@ 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();
|
||||
if (codecType) {
|
||||
atrac->GetTrackMut().codecType = codecType;
|
||||
}
|
||||
Atrac *atrac = new Atrac(codecType);
|
||||
return atrac;
|
||||
}
|
||||
}
|
||||
|
||||
static AtracBase *getAtrac(int atracID) {
|
||||
if (atracID < 0 || atracID >= PSP_NUM_ATRAC_IDS) {
|
||||
if (atracID < 0 || atracID >= PSP_MAX_ATRAC_IDS) {
|
||||
return nullptr;
|
||||
}
|
||||
AtracBase *atrac = atracContexts[atracID];
|
||||
|
@ -181,10 +193,14 @@ static AtracBase *getAtrac(int atracID) {
|
|||
}
|
||||
|
||||
static int RegisterAtrac(AtracBase *atrac) {
|
||||
for (int i = 0; i < (int)ARRAY_SIZE(atracContexts); ++i) {
|
||||
for (int i = 0; i < g_atracMaxContexts; ++i) {
|
||||
if (atracContextTypes[i] == atrac->CodecType() && atracContexts[i] == 0) {
|
||||
atracContexts[i] = atrac;
|
||||
atrac->SetID(i);
|
||||
if (g_Config.bUseExperimentalAtrac) {
|
||||
// Note: This assert isn't really valid until we savestate the new contexts.
|
||||
_dbg_assert_(g_atracBSS != 0);
|
||||
}
|
||||
atrac->SetIDAndAddr(i, GetAtracContextAddress(i));
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +208,7 @@ static int RegisterAtrac(AtracBase *atrac) {
|
|||
}
|
||||
|
||||
static int deleteAtrac(int atracID) {
|
||||
if (atracID >= 0 && atracID < PSP_NUM_ATRAC_IDS) {
|
||||
if (atracID >= 0 && atracID < PSP_MAX_ATRAC_IDS) {
|
||||
if (atracContexts[atracID] != nullptr) {
|
||||
delete atracContexts[atracID];
|
||||
atracContexts[atracID] = nullptr;
|
||||
|
@ -702,7 +718,7 @@ static u32 sceAtracSetLoopNum(int atracID, int loopNum) {
|
|||
}
|
||||
|
||||
static int sceAtracReinit(int at3Count, int at3plusCount) {
|
||||
for (int i = 0; i < PSP_NUM_ATRAC_IDS; ++i) {
|
||||
for (int i = 0; i < PSP_MAX_ATRAC_IDS; ++i) {
|
||||
if (atracContexts[i] != nullptr) {
|
||||
return hleReportError(Log::ME, SCE_KERNEL_ERROR_BUSY, "cannot reinit while IDs in use");
|
||||
}
|
||||
|
@ -710,7 +726,7 @@ static int sceAtracReinit(int at3Count, int at3plusCount) {
|
|||
|
||||
memset(atracContextTypes, 0, sizeof(atracContextTypes));
|
||||
int next = 0;
|
||||
int space = PSP_NUM_ATRAC_IDS;
|
||||
int space = g_atracMaxContexts;
|
||||
|
||||
// This seems to deinit things. Mostly, it cause a reschedule on next deinit (but -1, -1 does not.)
|
||||
if (at3Count == 0 && at3plusCount == 0) {
|
||||
|
@ -900,19 +916,8 @@ static u32 _sceAtracGetContextAddress(int atracID) {
|
|||
return hleLogError(Log::ME, 0, "bad atrac id");
|
||||
}
|
||||
|
||||
if (!atrac->context_.IsValid()) {
|
||||
// allocate a new context_
|
||||
u32 contextSize = sizeof(SceAtracContext);
|
||||
// Note that Alloc can increase contextSize to the "grain" size.
|
||||
atrac->context_ = kernelMemory.Alloc(contextSize, false, StringFromFormat("AtracCtx/%d", atracID).c_str());
|
||||
if (atrac->context_.IsValid())
|
||||
Memory::Memset(atrac->context_.ptr, 0, contextSize, "AtracContextClear");
|
||||
WARN_LOG(Log::ME, "%08x=_sceAtracGetContextAddress(%i): allocated new context", atrac->context_.ptr, atracID);
|
||||
} else {
|
||||
WARN_LOG(Log::ME, "%08x=_sceAtracGetContextAddress(%i)", atrac->context_.ptr, atracID);
|
||||
}
|
||||
|
||||
atrac->WriteContextToPSPMem();
|
||||
// Only the old context needs this. The new one will always have a context pointer.
|
||||
atrac->NotifyGetContextAddress();
|
||||
return hleLogDebug(Log::ME, atrac->context_.ptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ struct SceAtracContext {
|
|||
SceAtracIdInfo info;
|
||||
};
|
||||
|
||||
const int PSP_NUM_ATRAC_IDS = 6;
|
||||
const int PSP_MAX_ATRAC_IDS = 6;
|
||||
|
||||
class AtracBase;
|
||||
|
||||
|
|
|
@ -968,7 +968,7 @@ void DrawAudioDecodersView(ImConfig &cfg, ImControl &control) {
|
|||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int i = 0; i < PSP_NUM_ATRAC_IDS; i++) {
|
||||
for (int i = 0; i < PSP_MAX_ATRAC_IDS; i++) {
|
||||
u32 type = 0;
|
||||
const AtracBase *ctx = __AtracGetCtx(i, &type);
|
||||
if (!ctx) {
|
||||
|
@ -1009,7 +1009,7 @@ void DrawAudioDecodersView(ImConfig &cfg, ImControl &control) {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (cfg.selectedAtracCtx >= 0 && cfg.selectedAtracCtx < PSP_NUM_ATRAC_IDS) {
|
||||
if (cfg.selectedAtracCtx >= 0 && cfg.selectedAtracCtx < PSP_MAX_ATRAC_IDS) {
|
||||
u32 type = 0;
|
||||
const AtracBase *ctx = __AtracGetCtx(cfg.selectedAtracCtx, &type);
|
||||
// Show details about the selected atrac context here.
|
||||
|
|
Loading…
Add table
Reference in a new issue