Skip to content

Commit 8734df7

Browse files
authored
Merge pull request #20209 from hrydgard/more-hle-work
More HLE cleanup, fix MP3 in sceAudiocodec
2 parents fff8301 + efa022b commit 8734df7

17 files changed

+369
-401
lines changed

Common/Data/Random/Rng.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class GMRng {
3030
uint32_t m_z;
3131
};
3232

33-
3433
// Data must consist only of the index and the twister array. This matches the PSP
3534
// MT context exactly.
3635
class MersenneTwister {

Common/Log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ enum class Log {
6767
sceSas,
6868
sceUtility,
6969
sceMisc,
70+
sceReg,
7071

7172
NUMBER_OF_LOGS, // Must be last
7273
};

Common/Log/LogManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static const char * const g_logTypeNames[] = {
105105
"SCESAS",
106106
"SCEUTIL",
107107
"SCEMISC",
108+
"SCEREG",
108109
};
109110

110111
const char *LogManager::GetLogTypeName(Log type) {

Core/HLE/ErrorCodes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,4 +503,13 @@ enum PSPErrorCode : u32 {
503503
SCE_REG_ERROR_CATEGORY_NOT_FOUND = 0x80082718,
504504
SCE_REG_ERROR_INVALID_NAME = 0x80082738,
505505
SCE_REG_ERROR_PERMISSION_FAILURE = 0x8008273b,
506+
507+
SCE_MP3_ERROR_INVALID_HANDLE = 0x80671001,
508+
SCE_MP3_ERROR_UNRESERVED_HANDLE = 0x80671102,
509+
SCE_MP3_ERROR_NOT_YET_INIT_HANDLE = 0x80671103,
510+
SCE_MP3_ERROR_NO_RESOURCE_AVAIL = 0x80671201,
511+
SCE_MP3_ERROR_BAD_SAMPLE_RATE = 0x80671302,
512+
SCE_MP3_ERROR_BAD_RESET_FRAME = 0x80671501,
513+
SCE_MP3_ERROR_BAD_ADDR = 0x80671002,
514+
SCE_MP3_ERROR_BAD_SIZE = 0x80671003,
506515
};

Core/HLE/sceAudiocodec.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,10 @@ static int __AudioCodecInitCommon(u32 ctxPtr, int codec, bool mono) {
144144
}
145145

146146
// Create audio decoder for given audio codec and push it into AudioList
147-
if (inFrameBytes) {
148-
INFO_LOG(Log::ME, "sceAudioDecoder: Creating codec with %04x frame size and %d channels, codec %04x", inFrameBytes, channels, codec);
149-
AudioDecoder *decoder = CreateAudioDecoder(audioType, 44100, channels, inFrameBytes);
150-
decoder->SetCtxPtr(ctxPtr);
151-
g_audioDecoderContexts[ctxPtr] = decoder;
152-
} else {
153-
ERROR_LOG(Log::ME, "sceAudioDecoder: Unsupported codec %08x", codec);
154-
g_audioDecoderContexts[ctxPtr] = nullptr;
155-
}
147+
INFO_LOG(Log::ME, "sceAudioDecoder: Creating codec with %04x frame size and %d channels, codec %04x", inFrameBytes, channels, codec);
148+
AudioDecoder *decoder = CreateAudioDecoder(audioType, 44100, channels, inFrameBytes);
149+
decoder->SetCtxPtr(ctxPtr);
150+
g_audioDecoderContexts[ctxPtr] = decoder;
156151
return hleLogDebug(Log::ME, 0);
157152
}
158153

@@ -178,9 +173,18 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
178173
// TODO: Should check that codec corresponds to the currently used codec in the context, I guess..
179174

180175
auto ctx = PSPPointer<SceAudiocodecCodec>::Create(ctxPtr); // On game-owned heap, no need to allocate.
181-
int inFrameBytes;
182-
int channels;
183-
CalculateInputBytesAndChannelsAt3Plus(ctx, &inFrameBytes, &channels);
176+
177+
int inFrameBytes = 0;
178+
int channels = 2;
179+
180+
switch (codec) {
181+
case PSP_CODEC_AT3PLUS:
182+
CalculateInputBytesAndChannelsAt3Plus(ctx, &inFrameBytes, &channels);
183+
break;
184+
case PSP_CODEC_MP3:
185+
inFrameBytes = ctx->srcBytesRead;
186+
break;
187+
}
184188

185189
// find a decoder in audioList
186190
auto decoder = findDecoder(ctxPtr);

Core/HLE/sceGameUpdate.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,20 @@
1919
#include "Core/HLE/FunctionWrappers.h"
2020
#include "Core/HLE/sceGameUpdate.h"
2121

22-
static u32 sceGameUpdateInit()
23-
{
24-
ERROR_LOG(Log::sceUtility, "UNIMPL sceGameUpdateInit()");
25-
return 0;
22+
static u32 sceGameUpdateInit() {
23+
return hleLogError(Log::sceUtility, 0, "UNIMPL");
2624
}
2725

28-
static u32 sceGameUpdateTerm()
29-
{
30-
ERROR_LOG(Log::sceUtility, "UNIMPL sceGameUpdateTerm()");
31-
return 0;
26+
static u32 sceGameUpdateTerm() {
27+
return hleLogError(Log::sceUtility, 0, "UNIMPL");
3228
}
3329

34-
static u32 sceGameUpdateRun()
35-
{
36-
ERROR_LOG(Log::sceUtility, "UNIMPL sceGameUpdateRun()");
37-
return 0;
30+
static u32 sceGameUpdateRun() {
31+
return hleLogError(Log::sceUtility, 0, "UNIMPL");
3832
}
3933

40-
static u32 sceGameUpdateAbort()
41-
{
42-
ERROR_LOG(Log::sceUtility, "UNIMPL sceGameUpdateAbort()");
43-
return 0;
34+
static u32 sceGameUpdateAbort() {
35+
return hleLogError(Log::sceUtility, 0, "UNIMPL");
4436
}
4537

4638
const HLEFunction sceGameUpdate[] =

Core/HLE/sceHeap.cpp

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -83,119 +83,107 @@ void __HeapShutdown() {
8383

8484
static int sceHeapReallocHeapMemory(u32 heapAddr, u32 memPtr, int memSize) {
8585
ERROR_LOG_REPORT(Log::HLE,"UNIMPL sceHeapReallocHeapMemory(%08x, %08x, %08x)", heapAddr, memPtr, memSize);
86-
return 0;
86+
return hleNoLog(0);
8787
}
8888

8989
static int sceHeapReallocHeapMemoryWithOption(u32 heapPtr, u32 memPtr, int memSize, u32 paramsPtr) {
9090
ERROR_LOG_REPORT(Log::HLE,"UNIMPL sceHeapReallocHeapMemoryWithOption(%08x, %08x, %08x, %08x)", heapPtr, memPtr, memSize, paramsPtr);
91-
return 0;
91+
return hleNoLog(0);
9292
}
9393

9494
static int sceHeapFreeHeapMemory(u32 heapAddr, u32 memAddr) {
9595
Heap *heap = getHeap(heapAddr);
9696
if (!heap) {
97-
ERROR_LOG(Log::HLE, "sceHeapFreeHeapMemory(%08x, %08x): invalid heap", heapAddr, memAddr);
98-
return SCE_KERNEL_ERROR_INVALID_ID;
97+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_ID, "invalid heap");
9998
}
10099

101-
DEBUG_LOG(Log::HLE, "sceHeapFreeHeapMemory(%08x, %08x)", heapAddr, memAddr);
102100
// An invalid address will crash the PSP, but 0 is always returns success.
103101
if (memAddr == 0) {
104-
return 0;
102+
return hleLogDebug(Log::HLE, 0);
105103
}
106104

107105
if (!heap->alloc.FreeExact(memAddr)) {
108-
return SCE_KERNEL_ERROR_INVALID_POINTER;
106+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_POINTER);
109107
}
110-
return 0;
108+
return hleLogDebug(Log::HLE, 0);
111109
}
112110

113111
static int sceHeapGetMallinfo(u32 heapAddr, u32 infoPtr) {
114112
ERROR_LOG_REPORT(Log::HLE,"UNIMPL sceHeapGetMallinfo(%08x, %08x)", heapAddr, infoPtr);
115-
return 0;
113+
return hleNoLog(0);
116114
}
117115

118116
static u32 sceHeapAllocHeapMemoryWithOption(u32 heapAddr, u32 memSize, u32 paramsPtr) {
119117
Heap *heap = getHeap(heapAddr);
120-
u32 grain = 4;
121118
if (!heap) {
122-
ERROR_LOG(Log::HLE, "sceHeapAllocHeapMemoryWithOption(%08x, %08x, %08x): invalid heap", heapAddr, memSize, paramsPtr);
123-
return 0;
119+
return hleLogError(Log::HLE, 0, "invalid heap");
124120
}
125121

122+
u32 grain = 4;
126123
// 0 is ignored.
127124
if (paramsPtr != 0) {
128125
u32 size = Memory::Read_U32(paramsPtr);
129126
if (size < 8) {
130-
ERROR_LOG(Log::HLE, "sceHeapAllocHeapMemoryWithOption(%08x, %08x, %08x): invalid param size", heapAddr, memSize, paramsPtr);
131-
return 0;
127+
return hleLogError(Log::HLE, 0, "invalid param size");
132128
}
133129
if (size > 8) {
134130
WARN_LOG_REPORT(Log::HLE, "sceHeapAllocHeapMemoryWithOption(): unexpected param size %d", size);
135131
}
136132
grain = Memory::Read_U32(paramsPtr + 4);
137133
}
138134

139-
DEBUG_LOG(Log::HLE,"sceHeapAllocHeapMemoryWithOption(%08x, %08x, %08x)", heapAddr, memSize, paramsPtr);
140135
// There's 8 bytes at the end of every block, reserved.
141136
memSize += 8;
142137
u32 addr = heap->alloc.AllocAligned(memSize, grain, grain, true);
143-
return addr;
138+
return hleLogDebug(Log::HLE, addr);
144139
}
145140

146141
static int sceHeapGetTotalFreeSize(u32 heapAddr) {
147142
Heap *heap = getHeap(heapAddr);
148143
if (!heap) {
149-
ERROR_LOG(Log::HLE, "sceHeapGetTotalFreeSize(%08x): invalid heap", heapAddr);
150-
return SCE_KERNEL_ERROR_INVALID_ID;
144+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_ID, "invalid heap");
151145
}
152146

153-
DEBUG_LOG(Log::HLE, "sceHeapGetTotalFreeSize(%08x)", heapAddr);
154147
u32 free = heap->alloc.GetTotalFreeBytes();
155148
if (free >= 8) {
156149
// Every allocation requires an extra 8 bytes.
157150
free -= 8;
158151
}
159-
return free;
152+
return hleLogDebug(Log::HLE, free);
160153
}
161154

162155
static int sceHeapIsAllocatedHeapMemory(u32 heapPtr, u32 memPtr) {
163156
if (!Memory::IsValidAddress(memPtr)) {
164-
ERROR_LOG(Log::HLE, "sceHeapIsAllocatedHeapMemory(%08x, %08x): invalid address", heapPtr, memPtr);
165-
return SCE_KERNEL_ERROR_INVALID_POINTER;
157+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_POINTER, "invalid address");
166158
}
167-
168-
DEBUG_LOG(Log::HLE, "sceHeapIsAllocatedHeapMemory(%08x, %08x)", heapPtr, memPtr);
169159
Heap *heap = getHeap(heapPtr);
170160
// An invalid heap is fine, it's not a member of this heap one way or another.
171161
// Only an exact address matches. Off by one crashes, and off by 4 says no.
172162
if (heap && heap->alloc.GetBlockStartFromAddress(memPtr) == memPtr) {
173-
return 1;
163+
return hleLogDebug(Log::HLE, 1);
174164
}
175-
return 0;
165+
return hleLogDebug(Log::HLE, 0);
176166
}
177167

178168
static int sceHeapDeleteHeap(u32 heapAddr) {
179169
Heap *heap = getHeap(heapAddr);
180170
if (!heap) {
181-
ERROR_LOG(Log::HLE, "sceHeapDeleteHeap(%08x): invalid heap", heapAddr);
182-
return SCE_KERNEL_ERROR_INVALID_ID;
171+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_ID, "invalid heap");
183172
}
184173

185-
DEBUG_LOG(Log::HLE, "sceHeapDeleteHeap(%08x)", heapAddr);
186174
heapList.erase(heapAddr);
187175
delete heap;
188-
return 0;
176+
return hleLogDebug(Log::HLE, 0);
189177
}
190178

191179
static int sceHeapCreateHeap(const char* name, u32 heapSize, int attr, u32 paramsPtr) {
192180
if (paramsPtr != 0) {
193181
u32 size = Memory::Read_U32(paramsPtr);
194182
WARN_LOG_REPORT(Log::HLE, "sceHeapCreateHeap(): unsupported options parameter, size = %d", size);
195183
}
196-
if (name == NULL) {
184+
if (!name) {
197185
WARN_LOG_REPORT(Log::HLE, "sceHeapCreateHeap(): name is NULL");
198-
return 0;
186+
return hleNoLog(0);
199187
}
200188
int allocSize = (heapSize + 3) & ~3;
201189

@@ -204,33 +192,29 @@ static int sceHeapCreateHeap(const char* name, u32 heapSize, int attr, u32 param
204192
heap->fromtop = (attr & PSP_HEAP_ATTR_HIGHMEM) != 0;
205193
u32 addr = userMemory.Alloc(heap->size, heap->fromtop, StringFromFormat("Heap/%s", name).c_str());
206194
if (addr == (u32)-1) {
207-
ERROR_LOG(Log::HLE, "sceHeapCreateHeap(): Failed to allocate %i bytes memory", allocSize);
208195
delete heap;
209-
return 0;
196+
return hleLogError(Log::HLE, 0, "Failed to allocate %i bytes memory", allocSize);
210197
}
211198
heap->address = addr;
212199

213200
// Some of the heap is reserved by the implementation (the first 128 bytes, and 8 after each block.)
214201
heap->alloc.Init(heap->address + 128, heap->size - 128, true);
215202
heapList[heap->address] = heap;
216-
DEBUG_LOG(Log::HLE, "%08x=sceHeapCreateHeap(%s, %08x, %08x, %08x)", heap->address, name, heapSize, attr, paramsPtr);
217-
return heap->address;
203+
return hleLogDebug(Log::HLE, heap->address);
218204
}
219205

220206
static u32 sceHeapAllocHeapMemory(u32 heapAddr, u32 memSize) {
221207
Heap *heap = getHeap(heapAddr);
222208
if (!heap) {
223-
ERROR_LOG(Log::HLE, "sceHeapAllocHeapMemory(%08x, %08x): invalid heap", heapAddr, memSize);
224209
// Yes, not 0 (returns a pointer), but an error code. Strange.
225-
return SCE_KERNEL_ERROR_INVALID_ID;
210+
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_ID, "invalid heap");
226211
}
227212

228-
DEBUG_LOG(Log::HLE, "sceHeapAllocHeapMemory(%08x, %08x)", heapAddr, memSize);
229213
// There's 8 bytes at the end of every block, reserved.
230214
memSize += 8;
231215
// Always goes down, regardless of whether the heap is high or low.
232216
u32 addr = heap->alloc.Alloc(memSize, true);
233-
return addr;
217+
return hleLogDebug(Log::HLE, addr);
234218
}
235219

236220

Core/HLE/sceKernel.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,15 @@ const char *KernelErrorToString(u32 err) {
15031503
case SCE_REG_ERROR_INVALID_NAME: return "SCE_REG_ERROR_INVALID_NAME";
15041504
case SCE_REG_ERROR_PERMISSION_FAILURE: return "SCE_REG_ERROR_PERMISSION_FAILURE";
15051505

1506+
case SCE_MP3_ERROR_INVALID_HANDLE: return "SCE_MP3_ERROR_INVALID_HANDLE";
1507+
case SCE_MP3_ERROR_UNRESERVED_HANDLE: return "SCE_MP3_ERROR_UNRESERVED_HANDLE";
1508+
case SCE_MP3_ERROR_NOT_YET_INIT_HANDLE: return "SCE_MP3_ERROR_NOT_YET_INIT_HANDLE";
1509+
case SCE_MP3_ERROR_NO_RESOURCE_AVAIL: return "SCE_MP3_ERROR_NO_RESOURCE_AVAIL";
1510+
case SCE_MP3_ERROR_BAD_SAMPLE_RATE: return "SCE_MP3_ERROR_BAD_SAMPLE_RATE";
1511+
case SCE_MP3_ERROR_BAD_RESET_FRAME: return "SCE_MP3_ERROR_BAD_RESET_FRAME";
1512+
case SCE_MP3_ERROR_BAD_ADDR: return "SCE_MP3_ERROR_BAD_ADDR";
1513+
case SCE_MP3_ERROR_BAD_SIZE: return "SCE_MP3_ERROR_BAD_SIZE";
1514+
15061515
default:
15071516
return nullptr;
15081517
}

Core/HLE/sceKernel.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,6 @@ class KernelObjectPool {
184184
template <class T>
185185
T* Get(SceUID handle, u32 &outError) {
186186
if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset]) {
187-
// Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP
188-
if (handle != 0 && (u32)handle != 0x80020001) {
189-
WARN_LOG(Log::sceKernel, "Kernel: Bad %s handle %d (%08x)", T::GetStaticTypeName(), handle, handle);
190-
}
191187
outError = T::GetMissingErrorCode();
192188
return nullptr;
193189
} else {

Core/HLE/sceKernelMutex.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -523,25 +523,30 @@ int sceKernelCancelMutex(SceUID uid, int count, u32 numWaitThreadsPtr)
523523
// int sceKernelLockMutex(SceUID id, int count, int *timeout)
524524
int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
525525
{
526+
// Tekken 6 hack: Let's avoid the unnecessary logspam. It does this on hardware too.
527+
// This ID is always invalid.
528+
if (id == 0x80020001 && timeoutPtr == 0) {
529+
return hleNoLog(0);
530+
}
531+
526532
u32 error;
527533
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
528534

529535
if (__KernelLockMutex(mutex, count, error))
530536
return hleLogDebug(Log::sceKernel, 0);
531-
else if (error)
537+
else if (error) {
532538
return hleLogError(Log::sceKernel, error);
533-
else
534-
{
535-
SceUID threadID = __KernelGetCurThread();
536-
// May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates.
537-
if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end())
538-
mutex->waitingThreads.push_back(threadID);
539-
__KernelWaitMutex(mutex, timeoutPtr);
540-
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false, "mutex waited");
541-
542-
// Return value will be overwritten by wait.
543-
return hleLogDebug(Log::sceKernel, 0);
544539
}
540+
541+
SceUID threadID = __KernelGetCurThread();
542+
// May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates.
543+
if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end())
544+
mutex->waitingThreads.push_back(threadID);
545+
__KernelWaitMutex(mutex, timeoutPtr);
546+
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false, "mutex waited");
547+
548+
// Return value will be overwritten by wait.
549+
return hleLogDebug(Log::sceKernel, 0);
545550
}
546551

547552
// int sceKernelLockMutexCB(SceUID id, int count, int *timeout)
@@ -598,6 +603,12 @@ int sceKernelTryLockMutex(SceUID id, int count) {
598603
// int sceKernelUnlockMutex(SceUID id, int count)
599604
int sceKernelUnlockMutex(SceUID id, int count)
600605
{
606+
// Tekken 6 hack: Let's avoid the unnecessary logspam. It does this on hardware too.
607+
// This ID is always invalid.
608+
if (id == 0x80020001) {
609+
return hleNoLog(0);
610+
}
611+
601612
u32 error;
602613
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
603614

Core/HLE/sceKernelSemaphore.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,13 @@ int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
199199
}
200200

201201
int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr) {
202-
if (!name)
202+
if (!name) {
203+
// This is strangely quite common! Some shared library must be doing this.
203204
return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ERROR, "invalid name");
204-
if (attr >= 0x200)
205+
}
206+
if (attr >= 0x200) {
205207
return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "invalid attr parameter %08x", attr);
208+
}
206209

207210
PSPSemaphore *s = new PSPSemaphore();
208211
SceUID id = kernelObjects.Create(s);

0 commit comments

Comments
 (0)