diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 11116c94c3..85b308eb11 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -338,9 +338,9 @@ - + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 7ac7a64719..ebf5ad45bd 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -527,8 +527,8 @@ - + \ No newline at end of file diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 4be48dace0..5313b5a1f2 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -97,7 +97,7 @@ const char *GetFuncName(const char *moduleName, u32 nib) else { static char temp[256]; - sprintf(temp,"[UNK:%08x]",nib); + sprintf(temp,"[UNK: 0x%08x ]",nib); return temp; } } diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index e564a3fbc2..9305852bcd 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -23,6 +23,11 @@ #include "__sceAudio.h" #include "HLE.h" + +// There's a second Audio api called Audio2 that only has one channel, I guess the 8 channel api was overkill. +// We simply map it to the first of the 8 channels. + + AudioChannel chans[8]; // Enqueues the buffer pointer on the channel. If channel buffer queue is full (2 items?) will block until it isn't. @@ -90,17 +95,17 @@ u32 sceAudioOutputPanned(u32 chan, u32 leftVol, u32 rightVol, u32 samplePtr) } } -u32 sceAudioOutputBlocking(u32 chan, u32 vol, u32 samplePtr) +void sceAudioOutputBlocking(u32 chan, u32 vol, u32 samplePtr) { if (chan < 0 || chan >= MAX_CHANNEL) { ERROR_LOG(HLE,"sceAudioOutputBlocking() - BAD CHANNEL"); - return SCE_ERROR_AUDIO_INVALID_CHANNEL; + RETURN(SCE_ERROR_AUDIO_INVALID_CHANNEL); } else if (!chans[chan].reserved) { ERROR_LOG(HLE,"sceAudioOutputBlocking() - channel not reserved"); - return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED; + RETURN(SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED); } else { @@ -109,7 +114,7 @@ u32 sceAudioOutputBlocking(u32 chan, u32 vol, u32 samplePtr) chans[chan].leftVolume = vol; chans[chan].rightVolume = vol; chans[chan].sampleAddress = samplePtr; - return __AudioEnqueue(chans[chan], chan, true); + __AudioEnqueue(chans[chan], chan, true); } } @@ -236,13 +241,56 @@ void sceAudioInit() RETURN(0); } +void sceAudioOutput2Reserve() +{ + int sampleCount = PARAM(0); + ERROR_LOG(HLE,"sceAudioOutput2Reserve(%i)", sampleCount); + chans[0].sampleCount = sampleCount; + chans[0].reserved = true; + RETURN(0); +} + +void sceAudioOutput2OutputBlocking() +{ + int vol = PARAM(0); + u32 dataPtr = PARAM(1); + + ERROR_LOG(HLE,"UNIMPL sceAudioOutput2OutputBlocking(%i, %08x)", vol, dataPtr); + chans[0].running = true; + chans[0].leftVolume = vol; + chans[0].rightVolume = vol; + chans[0].sampleAddress = dataPtr; + __AudioEnqueue(chans[0], 0, true); + + RETURN(0); +} + +void sceAudioOutput2ChangeLength() +{ + ERROR_LOG(HLE,"UNIMPL sceAudioOutput2ChangeLength"); + RETURN(0); +} + +void sceAudioOutput2GetRestSample() +{ + ERROR_LOG(HLE,"UNIMPL sceAudioOutput2GetRestSample"); + RETURN(0); +} + +void sceAudioOutput2Release() +{ + ERROR_LOG(HLE,"sceAudioOutput2Release()"); + chans[0].reserved = false; + RETURN(0); +} + const HLEFunction sceAudio[] = { - {0x01562ba3, 0, "sceAudioOutput2Reserve"}, // Super Stardust Portable uses these - {0x2d53f36e, 0, "sceAudioOutput2OutputBlocking"}, - {0x63f2889c, 0, "sceAudioOutput2ChangeLength"}, - {0x647cef33, 0, "sceAudioOutput2GetRestSample"}, - {0x43196845, 0, "sceAudioOutput2Release"}, + {0x01562ba3, sceAudioOutput2Reserve, "sceAudioOutput2Reserve"}, // N+, Super Stardust Portable uses these + {0x2d53f36e, sceAudioOutput2OutputBlocking, "sceAudioOutput2OutputBlocking"}, + {0x63f2889c, sceAudioOutput2ChangeLength, "sceAudioOutput2ChangeLength"}, + {0x647cef33, sceAudioOutput2GetRestSample, "sceAudioOutput2GetRestSample"}, + {0x43196845, sceAudioOutput2Release, "sceAudioOutput2Release"}, {0x210567F7, 0, "sceAudioEnd"}, {0x38553111, 0, "sceAudioSRCChReserve"}, @@ -256,7 +304,7 @@ const HLEFunction sceAudio[] = {0xE0727056, 0, "sceAudioSRCOutputBlocking"}, {0xE926D3FB, 0, "sceAudioInputInitEx"}, {0x8c1009b2, 0, "sceAudioOutput"}, - {0x136CAF51, WrapU_UUU, "sceAudioOutputBlocking"}, + {0x136CAF51, WrapV_UUU, "sceAudioOutputBlocking"}, {0xE2D56B2D, WrapU_UUUU, "sceAudioOutputPanned"}, {0x13F592BC, WrapV_UUUU, "sceAudioOutputPannedBlocking"}, //(u32, u32, u32, void *)Output sound, blocking {0x5EC81C55, WrapU_UUU, "sceAudioChReserve"}, //(u32, u32 samplecount, u32) Initialize channel and allocate buffer long, long samplecount, long);//init buffer? returns handle, minus if error diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index a482759af6..0667bc3d1e 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -76,17 +76,22 @@ void sceCtrlInit() { ctrlInited = true; memset(&ctrl, 0, sizeof(ctrl)); - DEBUG_LOG(HLE,"sceCtrlInit"); + ctrl.analog[0] = 128; + ctrl.analog[1] = 128; + DEBUG_LOG(HLE,"sceCtrlInit"); } void sceCtrlSetSamplingMode() { - DEBUG_LOG(HLE,"sceCtrlSetSamplingMode"); + u32 mode = PARAM(0); + DEBUG_LOG(HLE,"sceCtrlSetSamplingMode(%i) ra=%08x", mode, currentMIPS->r[MIPS_REG_RA]); if (ctrlInited) { + RETURN((u32)analogEnabled); // Looks odd - analogEnabled = true; + analogEnabled = mode; } + RETURN(0); } void sceCtrlSetIdleCancelThreshold() @@ -146,8 +151,8 @@ void sceCtrlReadBufferPositive() analogX += 100; } - data.analog[0]=analogX; - data.analog[1]=analogY; + data.analog[0] = analogX; + data.analog[1] = analogY; #endif memcpy(Memory::GetPointer(ctrlData), &data, sizeof(_ctrl_data)); diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 269e2b84a1..c49d94be2d 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -146,7 +146,9 @@ u32 sceGeSetCallback(u32 structAddr) void sceGeUnsetCallback(u32 cbID) { - ERROR_LOG(HLE,"UNIMPL sceGeUnsetCallback(cbid=%08x)", cbID); + DEBUG_LOG(HLE,"sceGeUnsetCallback(cbid=%08x)", cbID); + sceKernelReleaseSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH); + sceKernelReleaseSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL); } void sceGeSaveContext() diff --git a/Core/HLE/sceKernelInterrupt.h b/Core/HLE/sceKernelInterrupt.h index baca7e4eb2..b93089676b 100644 --- a/Core/HLE/sceKernelInterrupt.h +++ b/Core/HLE/sceKernelInterrupt.h @@ -63,6 +63,7 @@ bool __RunOnePendingInterrupt(); void __KernelReturnFromInterrupt(); u32 sceKernelRegisterSubIntrHandler(u32 intrNumber, u32 subIntrNumber, u32 handler, u32 handlerArg); +u32 sceKernelReleaseSubIntrHandler(u32 intrNumber, u32 subIntrNumber); void Register_Kernel_Library(); void Register_InterruptManager(); diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index fd16ba283f..884a89911b 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -432,7 +432,10 @@ void sceKernelGetBlockHeadAddr() void sceKernelPrintf() { + const char *formatString = Memory::GetCharPointer(PARAM(0)); + ERROR_LOG(HLE,"UNIMPL sceKernelPrintf(%08x, %08x, %08x, %08x)", PARAM(0),PARAM(1),PARAM(2),PARAM(3)); + ERROR_LOG(HLE,"%s", formatString); RETURN(0); } @@ -588,8 +591,24 @@ void sceKernelTryAllocateVpl() void sceKernelFreeVpl() { - ERROR_LOG(HLE,"UNIMPL: sceKernelFreeVpl()"); - RETURN(0); + SceUID id = PARAM(0); + u32 blockPtr = PARAM(1); + DEBUG_LOG(HLE,"sceKernelFreeVpl(%i, %08x)", id, blockPtr); + u32 error; + VPL *vpl = kernelObjects.Get(id, error); + if (vpl) + { + if (vpl->alloc.Free(blockPtr)) { + RETURN(0); + // Should trigger waiting threads + } else { + ERROR_LOG(HLE, "sceKernelFreeVpl: Error freeing %08x", blockPtr); + RETURN(-1); + } + } + else { + RETURN(error); + } } void sceKernelCancelVpl() diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 2072ef423e..2f569e9e52 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -623,14 +623,22 @@ void sceKernelStopModule() { ERROR_LOG(HLE,"UNIMPL sceKernelStopModule"); RETURN(0); - } void sceKernelUnloadModule() { - ERROR_LOG(HLE,"UNIMPL sceKernelUnloadModule"); - RETURN(0); + u32 moduleId = PARAM(0); + ERROR_LOG(HLE,"UNIMPL sceKernelUnloadModule(%i)", moduleId); + u32 error; + Module *module = kernelObjects.Get(moduleId, error); + if (!module) + { + RETURN(error); + return; + } + kernelObjects.Destroy(moduleId); + RETURN(0); } void sceKernelGetModuleIdByAddress() diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 4f8b26f116..8900ebee58 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -93,6 +93,11 @@ const HLEFunction sceMpeg[] = {0xf2930c9c,0,"sceMpegAvcDecodeStopYCbCr"}, {0x31bd0272,0,"sceMpegAvcCsc"}, {0xa11c7026,0,"sceMpegAvcDecodeMode"}, + {0x0558B075,0,"sceMpegAvcCopyYCbCr"}, + {0x769BEBB6,0,"sceMpegRingbufferQueryPackNum"}, + {0x8C1E027D,0,"sceMpegGetPcmAu"}, + {0x9DCFB7EA,0,"sceMpegChangeGetAuMode"}, + {0xC02CF6B5,0,"sceMpegQueryPcmEsSize"}, }; const HLEFunction sceMp3[] = diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 84d594b9da..bbf41d23d7 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -81,11 +81,22 @@ const HLEFunction scePsmf[] = {0xA5EBFE81,0,"scePsmfGetStreamSizeFunction"}, }; +void scePsmfPlayerCreate() { + DEBUG_LOG(HLE, "scePsmfPlayerCreate"); + RETURN(0); +} + +void scePsmfPlayerReleasePsmf() { + DEBUG_LOG(HLE, "scePsmfPlayerReleasePsmf"); + RETURN(0); +} + + const HLEFunction scePsmfPlayer[] = { + {0x235d8787,scePsmfPlayerCreate,"scePsmfPlayerCreateFunction"}, {0x1078c008,0,"scePsmfPlayerStopFunction"}, {0x1e57a8e7,0,"scePsmfPlayerConfigPlayer"}, - {0x235d8787,0,"scePsmfPlayerCreateFunction"}, {0x2beb1569,0,"scePsmfPlayerBreak"}, {0x3d6d25a9,0,"scePsmfPlayerSetPsmfFunction"}, {0x3ea82a4b,0,"scePsmfPlayerGetAudioOutSize"}, @@ -103,11 +114,14 @@ const HLEFunction scePsmfPlayer[] = {0xb8d10c56,0,"scePsmfPlayerSelectAudio"}, {0xb9848a74,0,"scePsmfPlayerGetAudioData"}, {0xdf089680,0,"scePsmfPlayerGetPsmfInfo"}, - {0xe792cd94,0,"scePsmfPlayerReleasePsmfFunction"}, + {0xe792cd94,scePsmfPlayerReleasePsmf,"scePsmfPlayerReleasePsmfFunction"}, {0xf3efaa91,0,"scePsmfPlayerGetCurrentPlayMode"}, {0xf8ef08a6,0,"scePsmfPlayerGetCurrentStatus"}, {0x2D0E4E0A,0,"scePsmfPlayerSetTempBufFunction"}, {0x58B83577,0,"scePsmfPlayerSetPsmfCBFunction"}, + {0x2673646B,0,"scePsmfVerifyPsmf"}, + {0x4E624A34,0,"scePsmfGetEPWithId"}, + {0x5F457515,0,"scePsmfGetEPidWithTimestampFunction"}, }; void Register_scePsmf() { diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 7ea14a4930..d2423d6c18 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -646,9 +646,33 @@ namespace MIPSInt break; case 2: //vi2us - //break; + { + for (int i = 0; i < GetNumVectorElements(sz) / 2; i++) { + int low = s[i * 2]; + int high = s[i * 2 + 1]; + if (low < 0) low = 0; + if (high < 0) high = 0; + low >>= 15; + high >>= 15; + d[i] = low | (high << 16); + } + if (sz == V_Quad) oz = V_Pair; + if (sz == V_Pair) oz = V_Single; + } + break; case 3: //vi2s - //break; + { + for (int i = 0; i < GetNumVectorElements(sz) / 2; i++) { + u32 low = s[i * 2]; + u32 high = s[i * 2 + 1]; + low >>= 16; + high >>= 16; + d[i] = low | (high << 16); + } + if (sz == V_Quad) oz = V_Pair; + if (sz == V_Pair) oz = V_Single; + } + break; default: _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); break;