From fb5a26b46d2c2a9f52c3e52ef9f4ea8886cf2f19 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sun, 16 Dec 2012 13:38:27 +0800 Subject: [PATCH 01/20] Enable correct viewport switching for screen 1x-4x and add Ctrl1-4 as shortcut key --- GPU/GLES/DisplayListInterpreter.cpp | 4 ++-- Windows/ppsspp.rc | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 1f84c5ed1f..30a19d8cbc 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -78,7 +78,7 @@ void GLES_GPU::InitClear() // glClearColor(1,0,1,1); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); } - glViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + glViewport(0, 0, 480 * g_Config.iWindowZoom , 272 * g_Config.iWindowZoom ); } void GLES_GPU::BeginFrame() @@ -118,7 +118,7 @@ void GLES_GPU::CopyDisplayToOutput() VirtualFramebuffer *vfb = GetDisplayFBO(); fbo_unbind(); - glViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + glViewport(0, 0, 480 * g_Config.iWindowZoom , 272 * g_Config.iWindowZoom ); currentRenderVfb_ = 0; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index d3c0c6b5d7..eab8d124d4 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -196,14 +196,14 @@ BEGIN MENUITEM "R&eset", ID_EMULATION_RESET MENUITEM SEPARATOR MENUITEM "&Interpreter", ID_CPU_INTERPRETER - MENUITEM "&Slightly faster interpreter", ID_CPU_FASTINTERPRETER + MENUITEM "&Slightly Faster Interpreter", ID_CPU_FASTINTERPRETER MENUITEM "&Dynarec", ID_CPU_DYNAREC, CHECKED END POPUP "Debu&g" BEGIN MENUITEM "Load &Map File...", ID_DEBUG_LOADMAPFILE MENUITEM "&Save Map File...", ID_DEBUG_SAVEMAPFILE - MENUITEM "&Reset symbol table", ID_DEBUG_RESETSYMBOLTABLE + MENUITEM "&Reset Symbol Table", ID_DEBUG_RESETSYMBOLTABLE MENUITEM SEPARATOR MENUITEM "&Disassembly\tCtrl+D", ID_DEBUG_DISASSEMBLY MENUITEM "&Log Console\tCtrl+L", ID_DEBUG_LOG @@ -212,14 +212,14 @@ BEGIN POPUP "&Options" BEGIN MENUITEM "&Toggle Full Screen\tF12", ID_OPTIONS_FULLSCREEN - MENUITEM "&Display raw framebuffer", ID_OPTIONS_DISPLAYRAWFRAMEBUFFER - MENUITEM "&Buffered rendering", ID_OPTIONS_BUFFEREDRENDERING - MENUITEM "&Show debug statistics", ID_OPTIONS_SHOWDEBUGSTATISTICS + MENUITEM "&Display Raw Framebuffer", ID_OPTIONS_DISPLAYRAWFRAMEBUFFER + MENUITEM "&Buffered Rendering\tF5", ID_OPTIONS_BUFFEREDRENDERING + MENUITEM "&Show Debug Statistics", ID_OPTIONS_SHOWDEBUGSTATISTICS MENUITEM SEPARATOR - MENUITEM "Screen &1x", ID_OPTIONS_SCREEN1X - MENUITEM "Screen &2x", ID_OPTIONS_SCREEN2X - MENUITEM "Screen &3x", ID_OPTIONS_SCREEN3X - MENUITEM "Screen &4x", ID_OPTIONS_SCREEN4X + MENUITEM "Screen &1x\tCtrl+1", ID_OPTIONS_SCREEN1X + MENUITEM "Screen &2x\tCtrl+2", ID_OPTIONS_SCREEN2X + MENUITEM "Screen &3x\tCtrl+3", ID_OPTIONS_SCREEN3X + MENUITEM "Screen &4x\tCtrl+4", ID_OPTIONS_SCREEN4X MENUITEM SEPARATOR MENUITEM "&Ignore illegal reads/writes", ID_OPTIONS_IGNOREILLEGALREADS END @@ -313,9 +313,14 @@ BEGIN "R", ID_DEBUG_REGISTERS, VIRTKEY, CONTROL, NOINVERT VK_F8, ID_EMULATION_PAUSE, VIRTKEY, NOINVERT VK_F7, ID_EMULATION_RUN, VIRTKEY, NOINVERT - VK_F4, ID_FILE_LOADSTATE, VIRTKEY, NOINVERT - VK_F5, ID_FILE_REFRESHGAMELIST, VIRTKEY, NOINVERT - VK_F2, ID_FILE_SAVESTATE, VIRTKEY, NOINVERT + //VK_F4, ID_FILE_LOADSTATE, VIRTKEY, NOINVERT + //VK_F5, ID_FILE_REFRESHGAMELIST, VIRTKEY, NOINVERT + //VK_F2, ID_FILE_SAVESTATE, VIRTKEY, NOINVERT + "1", ID_OPTIONS_SCREEN1X, VIRTKEY, CONTROL, NOINVERT + "2", ID_OPTIONS_SCREEN2X, VIRTKEY, CONTROL, NOINVERT + "3", ID_OPTIONS_SCREEN3X, VIRTKEY, CONTROL, NOINVERT + "4", ID_OPTIONS_SCREEN4X, VIRTKEY, CONTROL, NOINVERT + VK_F5, ID_OPTIONS_BUFFEREDRENDERING, VIRTKEY, NOINVERT "W", ID_FILE_UNLOAD, VIRTKEY, CONTROL, NOINVERT VK_F12, ID_OPTIONS_FULLSCREEN, VIRTKEY, NOINVERT END From 8db1cef503d34d8c82fa07e1f8d7c83c9a8e5a13 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 19:04:19 +0100 Subject: [PATCH 02/20] Fix GPU block transfer --- GPU/GLES/DisplayListInterpreter.cpp | 4 ++-- GPU/GPUState.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 630e966797..3f4154ad11 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -1182,8 +1182,8 @@ void GLES_GPU::DoBlockTransfer() u32 srcBasePtr = (gstate.transfersrc & 0xFFFFFF) | ((gstate.transfersrcw & 0xFF0000) << 8); u32 srcStride = gstate.transfersrcw & 0x3FF; - u32 dstBasePtr = (gstate.transfersrc & 0xFFFFFF) | ((gstate.transfersrcw & 0xFF0000) << 8); - u32 dstStride = gstate.transfersrcw & 0x3FF; + u32 dstBasePtr = (gstate.transferdst & 0xFFFFFF) | ((gstate.transferdstw & 0xFF0000) << 8); + u32 dstStride = gstate.transferdstw & 0x3FF; int srcX = gstate.transfersrcpos & 0x3FF; int srcY = (gstate.transfersrcpos >> 10) & 0x3FF; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index f11eb33bff..a111b09418 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -226,9 +226,10 @@ struct GPUgstate transferstart, transfersrcpos, transferdstpos, - transfersize; + pad99, + transfersize; // 0xEE - u32 pad05[0x63-0x40]; + u32 pad05[0xFF- 0xEE]; }; }; From 1e086f500870d397dc25ca0e7b76e927c953917f Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 19:38:04 +0100 Subject: [PATCH 03/20] Let's not throw away our stereo... Also change mix freq back to 44100 for now. --- Core/HLE/__sceAudio.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index e880d228b2..b748339da2 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -38,15 +38,15 @@ std::recursive_mutex section; int eventAudioUpdate = -1; int eventHostAudioUpdate = -1; -int mixFrequency = 48000; -const int hwSampleRate = 48000; +int mixFrequency = 44100; +const int hwSampleRate = 44100; const int hwBlockSize = 480; const int hostAttemptBlockSize = 64; const int audioIntervalUs = (int)(1000000ULL * hwBlockSize / hwSampleRate); const int audioHostIntervalUs = (int)(1000000ULL * hostAttemptBlockSize / hwSampleRate); // High and low watermarks, basically. -const int chanQueueMaxSizeFactor = 12; +const int chanQueueMaxSizeFactor = 8; const int chanQueueMinSizeFactor = 1; FixedSizeQueue outAudioQueue; @@ -67,7 +67,7 @@ void hleHostAudioUpdate(u64 userdata, int cyclesLate) void __AudioInit() { - mixFrequency = 48000; + mixFrequency = 44100; eventAudioUpdate = CoreTiming::RegisterEvent("AudioUpdate", &hleAudioUpdate); eventHostAudioUpdate = CoreTiming::RegisterEvent("AudioUpdateHost", &hleHostAudioUpdate); @@ -151,8 +151,8 @@ void __AudioUpdate() if (chans[i].sampleQueue.size() >= 2) { s16 sampleL = chans[i].sampleQueue.front(); - s16 sampleR = chans[i].sampleQueue.front(); chans[i].sampleQueue.pop(); + s16 sampleR = chans[i].sampleQueue.front(); chans[i].sampleQueue.pop(); mixBuffer[s * 2] += sampleL; mixBuffer[s * 2 + 1] += sampleR; @@ -225,7 +225,7 @@ int __AudioMix(short *outstereo, int numFrames) } } if (anythingToPlay && underrun >= 0) { - DEBUG_LOG(HLE, "audio out buffer UNDERRUN at %i of %i", underrun, numFrames); + ERROR_LOG(HLE, "audio out buffer UNDERRUN at %i of %i", underrun, numFrames); } else { // DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames); } From cb29c1ce4b50879fb9879e13b94385cb757af4c6 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 20:14:06 +0100 Subject: [PATCH 04/20] Don't use __KernelTriggerWait in sceDisplay --- Core/HLE/sceDisplay.cpp | 15 ++++++++++++--- Core/HLE/sceKernelThread.h | 4 +++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index c1938e3f86..451e100a42 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -85,8 +85,9 @@ enum { struct WaitVBlankInfo { + WaitVBlankInfo(u32 tid) : threadID(tid), vcountUnblock(0) {} u32 threadID; - int vcountUnblock; + int vcountUnblock; // what was this for again? }; std::vector vblankWaitingThreads; @@ -144,7 +145,10 @@ void hleEnterVblank(u64 userdata, int cyclesLate) __DisplayFireVblank(); // Wake up threads waiting for VBlank - __KernelTriggerWait(WAITTYPE_VBLANK, 0, true); + for (int i = 0; i < vblankWaitingThreads.size(); i++) { + __KernelResumeThreadFromWait(vblankWaitingThreads[i].threadID, 0); + } + vblankWaitingThreads.clear(); // Trigger VBlank interrupt handlers. __TriggerInterrupt(PSP_VBLANK_INTR); @@ -201,7 +205,6 @@ void hleEnterVblank(u64 userdata, int cyclesLate) gpuStats.resetFrame(); } - host->EndFrame(); #ifdef _WIN32 @@ -318,36 +321,42 @@ u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, i void sceDisplayWaitVblankStart() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStart()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); } void sceDisplayWaitVblank() { DEBUG_LOG(HLE,"sceDisplayWaitVblank()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); } void sceDisplayWaitVblankStartMulti() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartMulti()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); } void sceDisplayWaitVblankCB() { DEBUG_LOG(HLE,"sceDisplayWaitVblankCB()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); } void sceDisplayWaitVblankStartCB() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartCB()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); } void sceDisplayWaitVblankStartMultiCB() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartMultiCB()"); + vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); } diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 30998ea4ad..bf9a3631a5 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -104,7 +104,9 @@ SceUID __KernelGetCurThread(); void __KernelSaveContext(ThreadContext *ctx); void __KernelLoadContext(ThreadContext *ctx); -// TODO: Replace this with __KernelResumeThread over time as it's misguided. +// TODO: Replace this with __KernelResumeThreadFromWait over time as it's misguided. +// It's better that each subsystem keeps track of the list of waiting threads +// and resumes them manually one by one using __KernelResumeThreadFromWait. bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch = false); bool __KernelTriggerWait(WaitType type, int id, int retVal, bool dontSwitch); u32 __KernelResumeThreadFromWait(SceUID threadID); // can return an error value From 9acfd5013989cd1cc782703863ce6e4c232c700c Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 20:15:23 +0100 Subject: [PATCH 05/20] Fix one cause of audio choppiness - we were dropping samples when audio functions blocked. Also some cleanup. --- Core/HLE/__sceAudio.cpp | 4 ++-- Core/HLE/sceAudio.cpp | 10 +++++++--- Core/HLE/sceAudio.h | 1 - Core/HLE/sceSas.cpp | 4 ++-- Core/HLE/sceUmd.cpp | 6 +++--- Core/HW/SasAudio.cpp | 16 +++++++++++----- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index b748339da2..12bbd21727 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -95,8 +95,8 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) chan.waitingThread = __KernelGetCurThread(); // WARNING: This changes currentThread so must grab waitingThread before (line above). __KernelWaitCurThread(WAITTYPE_AUDIOCHANNEL, (SceUID)chanNum, 0, 0, false); - section.unlock(); - return 0; + // Fall through to the sample queueing, don't want to lose the samples even though + // we're getting full. } else { diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index be2cc3652f..ea64d027fa 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -226,8 +226,7 @@ u32 sceAudioSetChannelDataLen(u32 chan, u32 len) } else { - DEBUG_LOG(HLE, "sceAudioSetChannelDataLen(%i, %i)", chan, len); - //chans[chan].dataLen = len; + INFO_LOG(HLE, "sceAudioSetChannelDataLen(%i, %i)", chan, len); chans[chan].sampleCount = len; return 0; } @@ -335,6 +334,11 @@ u32 sceAudioSetFrequency(u32 freq) { } } +u32 sceAudioSetVolumeOffset(u32 unknown) { + ERROR_LOG(HLE, "UNIMPL sceAudioSetVolumeOffset(%i)", unknown); + return 0; +} + const HLEFunction sceAudio[] = { // Newer simplified single channel audio output. Presumably for games that use Atrac3 @@ -349,7 +353,7 @@ const HLEFunction sceAudio[] = {0x210567F7, WrapU_V, "sceAudioEnd"}, {0xA2BEAA6C, WrapU_U, "sceAudioSetFrequency"}, - {0x927AC32B, 0, "sceAudioSetVolumeOffset"}, + {0x927AC32B, WrapU_U, "sceAudioSetVolumeOffset"}, // The oldest and standard audio interface. Supports 8 channels, most games use 1-2. {0x8c1009b2, WrapU_UUU, "sceAudioOutput"}, diff --git a/Core/HLE/sceAudio.h b/Core/HLE/sceAudio.h index 356a7efff1..6f1305b0d6 100644 --- a/Core/HLE/sceAudio.h +++ b/Core/HLE/sceAudio.h @@ -51,7 +51,6 @@ struct AudioChannel // last sample address u32 sampleAddress; u32 sampleCount; // Number of samples written in each OutputBlocking - int dataLen; // Probably internal queue size. Not currently used. int leftVolume; int rightVolume; diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index b8902626bc..bc482c572c 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -49,7 +49,7 @@ SasInstance sas; u32 sceSasInit(u32 core, u32 grainSize, u32 maxVoices, u32 outputMode, u32 sampleRate) { - DEBUG_LOG(HLE,"0=sceSasInit(%08x, %i, maxVoices=%i, %i, %i)", core, grainSize, maxVoices, outputMode, sampleRate); + INFO_LOG(HLE,"0=sceSasInit(%08x, grainSize=%i, maxVoices=%i, %i, %i)", core, grainSize, maxVoices, outputMode, sampleRate); memset(&sas, 0, sizeof(sas)); sas.SetGrainSize(grainSize); sas.maxVoices = maxVoices; @@ -339,7 +339,7 @@ u32 sceSasGetGrain(u32 core) u32 sceSasSetGrain(u32 core, int grain) { - DEBUG_LOG(HLE,"0=sceSasSetGrain(core=%08x, grain=%i)", core, grain); + INFO_LOG(HLE,"0=sceSasSetGrain(core=%08x, grain=%i)", core, grain); sas.SetGrainSize(grain); return 0; } diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 4fa68cf5e5..35f4534173 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -284,14 +284,14 @@ int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) return 0; } -void sceUmdCancelWaitDriveStat() +u32 sceUmdCancelWaitDriveStat() { DEBUG_LOG(HLE,"0=sceUmdCancelWaitDriveStat()"); - RETURN(0); __KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, true); // TODO: We should call UnscheduleEvent() event here? // But it's not often used anyway, and worst-case it will just do nothing unless it waits again. + return 0; } u32 sceUmdGetErrorStat() @@ -310,7 +310,7 @@ const HLEFunction sceUmdUser[] = {0x8EF08FCE,WrapI_U,"sceUmdWaitDriveStat"}, {0x56202973,WrapI_UU,"sceUmdWaitDriveStatWithTimer"}, {0x4A9E5E29,WrapI_UU,"sceUmdWaitDriveStatCB"}, - {0x6af9b50a,sceUmdCancelWaitDriveStat,"sceUmdCancelWaitDriveStat"}, + {0x6af9b50a,WrapU_V,"sceUmdCancelWaitDriveStat"}, {0x6B4A146C,&WrapU_V,"sceUmdGetDriveStat"}, {0x20628E6F,&WrapU_V,"sceUmdGetErrorStat"}, {0x340B7686,WrapU_U,"sceUmdGetDiscInfo"}, diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 6ee4dc95cc..a4d26fa3f0 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -182,15 +182,16 @@ SasInstance::~SasInstance() { } void SasInstance::SetGrainSize(int newGrainSize) { + grainSize = newGrainSize; + if (mixBuffer) delete [] mixBuffer; if (sendBuffer) delete [] sendBuffer; - mixBuffer = new s32[newGrainSize * 2]; - sendBuffer = new s32[newGrainSize * 2]; - memset(mixBuffer, 0, sizeof(int) * newGrainSize * 2); - memset(sendBuffer, 0, sizeof(int) * newGrainSize * 2); - grainSize = newGrainSize; + mixBuffer = new s32[grainSize * 2]; + sendBuffer = new s32[grainSize * 2]; + memset(mixBuffer, 0, sizeof(int) * grainSize * 2); + memset(sendBuffer, 0, sizeof(int) * grainSize * 2); if (resampleBuffer) delete [] resampleBuffer; @@ -218,6 +219,10 @@ void SasInstance::Mix(u32 outAddr) { int curSample = voice.samplePos / PSP_SAS_PITCH_BASE; int lastSample = (voice.samplePos + grainSize * voice.pitch) / PSP_SAS_PITCH_BASE; int numSamples = lastSample - curSample; + if (numSamples > grainSize * 4) { + ERROR_LOG(SAS, "numSamples too large, clamping: %i vs %i", numSamples, grainSize * 4); + numSamples = grainSize * 4; + } // Read N samples into the resample buffer. Could do either PCM or VAG here. voice.vag.GetSamples(resampleBuffer + 2, numSamples); @@ -254,6 +259,7 @@ void SasInstance::Mix(u32 outAddr) { sendBuffer[i * 2 + 1] += sample * voice.volumeRightSend >> 15; voice.envelope.Step(); } + voice.samplePos += voice.pitch * grainSize; if (voice.envelope.HasEnded()) { // NOTICE_LOG(SAS, "Hit end of envelope"); From b5808eaf4771abfad8fe522157b20d2777fc5822 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 20:43:43 +0100 Subject: [PATCH 06/20] optimizin', bugfixin' --- Core/HLE/__sceAudio.cpp | 2 +- Core/HW/SasAudio.cpp | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 12bbd21727..bf22116aeb 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -46,7 +46,7 @@ const int audioIntervalUs = (int)(1000000ULL * hwBlockSize / hwSampleRate); const int audioHostIntervalUs = (int)(1000000ULL * hostAttemptBlockSize / hwSampleRate); // High and low watermarks, basically. -const int chanQueueMaxSizeFactor = 8; +const int chanQueueMaxSizeFactor = 4; const int chanQueueMinSizeFactor = 1; FixedSizeQueue outAudioQueue; diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index a4d26fa3f0..e22d99323d 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -61,13 +61,9 @@ bool VagDecoder::DecodeBlock() for (int i = 0; i < 28; i += 2) { int d = GetByte(); - int s = (d & 0xf) << 12; - if (s & 0x8000) - s |= 0xffff0000; + int s = (short)((d & 0xf) << 12); samples[i] = (double)(s >> shift_factor); - s = (d & 0xf0) << 8; - if (s & 0x8000) - s |= 0xffff0000; + s = (short)((d & 0xf0) << 8); samples[i + 1] = (double)(s >> shift_factor); } for (int i = 0; i < 28; i++) @@ -83,7 +79,7 @@ bool VagDecoder::DecodeBlock() void VagDecoder::GetSamples(s16 *outSamples, int numSamples) { if (end_) { - memset(outSamples, 0, numSamples * sizeof(int)); + memset(outSamples, 0, numSamples * sizeof(s16)); return; } for (int i = 0; i < numSamples; i++) { @@ -218,7 +214,7 @@ void SasInstance::Mix(u32 outAddr) { // Figure out number of samples to read. int curSample = voice.samplePos / PSP_SAS_PITCH_BASE; int lastSample = (voice.samplePos + grainSize * voice.pitch) / PSP_SAS_PITCH_BASE; - int numSamples = lastSample - curSample; + u32 numSamples = lastSample - curSample; if (numSamples > grainSize * 4) { ERROR_LOG(SAS, "numSamples too large, clamping: %i vs %i", numSamples, grainSize * 4); numSamples = grainSize * 4; From 11279668ca9e9786cb50be7163327d2c6fbdc38b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 21:06:47 +0100 Subject: [PATCH 07/20] Allow changing of zoom factor at runtime --- Core/System.cpp | 2 +- Core/System.h | 2 +- GPU/GLES/DisplayListInterpreter.cpp | 4 ++-- Windows/WndMainWindow.cpp | 3 +++ Windows/ppsspp.rc | 7 ++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index da48ca9969..18c2b94687 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -112,7 +112,7 @@ void PSP_Shutdown() currentCPU = 0; } -const CoreParameter &PSP_CoreParameter() +CoreParameter &PSP_CoreParameter() { return coreParameter; } diff --git a/Core/System.h b/Core/System.h index 352897e640..a3340b2a21 100644 --- a/Core/System.h +++ b/Core/System.h @@ -29,4 +29,4 @@ bool PSP_IsInited(); void PSP_Shutdown(); void PSP_HWAdvance(int cycles); void PSP_SWI(); -const CoreParameter &PSP_CoreParameter(); \ No newline at end of file +CoreParameter &PSP_CoreParameter(); \ No newline at end of file diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 02caa9f5f6..3f4154ad11 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -78,7 +78,7 @@ void GLES_GPU::InitClear() // glClearColor(1,0,1,1); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); } - glViewport(0, 0, 480 * g_Config.iWindowZoom , 272 * g_Config.iWindowZoom ); + glViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); } void GLES_GPU::BeginFrame() @@ -118,7 +118,7 @@ void GLES_GPU::CopyDisplayToOutput() VirtualFramebuffer *vfb = GetDisplayFBO(); fbo_unbind(); - glViewport(0, 0, 480 * g_Config.iWindowZoom , 272 * g_Config.iWindowZoom ); + glViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); currentRenderVfb_ = 0; diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index a80e17345c..dfcbb99462 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -18,6 +18,7 @@ #include "main.h" #include "../Core/Core.h" +#include "../Core/System.h" #include "../Core/MemMap.h" #include "EmuThread.h" @@ -117,6 +118,8 @@ namespace MainWindow GetWindowRectAtZoom(zoom, rc, rcOuter); MoveWindow(hwndMain, rcOuter.left, rcOuter.top, rcOuter.right - rcOuter.left, rcOuter.bottom - rcOuter.top, TRUE); MoveWindow(hwndDisplay, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE); + PSP_CoreParameter().pixelWidth = 480 * zoom; + PSP_CoreParameter().pixelHeight = 272 * zoom; GL_Resized(); } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index eab8d124d4..8ddb89699d 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -190,8 +190,8 @@ BEGIN END POPUP "&Emulation" BEGIN - MENUITEM "&Run", ID_EMULATION_RUN - MENUITEM "&Pause", ID_EMULATION_PAUSE + MENUITEM "&Run\tF7", ID_EMULATION_RUN + MENUITEM "&Pause\tF8", ID_EMULATION_PAUSE MENUITEM SEPARATOR MENUITEM "R&eset", ID_EMULATION_RESET MENUITEM SEPARATOR @@ -313,9 +313,6 @@ BEGIN "R", ID_DEBUG_REGISTERS, VIRTKEY, CONTROL, NOINVERT VK_F8, ID_EMULATION_PAUSE, VIRTKEY, NOINVERT VK_F7, ID_EMULATION_RUN, VIRTKEY, NOINVERT - //VK_F4, ID_FILE_LOADSTATE, VIRTKEY, NOINVERT - //VK_F5, ID_FILE_REFRESHGAMELIST, VIRTKEY, NOINVERT - //VK_F2, ID_FILE_SAVESTATE, VIRTKEY, NOINVERT "1", ID_OPTIONS_SCREEN1X, VIRTKEY, CONTROL, NOINVERT "2", ID_OPTIONS_SCREEN2X, VIRTKEY, CONTROL, NOINVERT "3", ID_OPTIONS_SCREEN3X, VIRTKEY, CONTROL, NOINVERT From 458ed7f4217e35b12ea0ff2d6c3aee344ca2a07b Mon Sep 17 00:00:00 2001 From: TMaul Date: Mon, 17 Dec 2012 20:21:51 +0000 Subject: [PATCH 08/20] Make filename checks on iso case insentitive But still keep them logically in the same case they are on the discs --- Core/FileSystems/ISOFileSystem.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index b77c1d8223..761a7bbc45 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -21,6 +21,7 @@ #include #include + const int sectorSize = 2048; static bool parseLBN(std::string filename, u32 *sectorStart, u32 *readSize) @@ -209,7 +210,7 @@ nextblock: e->isBlockSectorMode = false; // Let's not excessively spam the log - I commented this line out. - // DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", name, dir.firstDataSectorLE, e->startingPosition, e->startingPosition); + DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", name, dir.firstDataSectorLE, e->startingPosition, e->startingPosition); if (e->isDirectory && !relative) { @@ -253,8 +254,15 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path) { for (size_t i=0; ichildren.size(); i++) { - std::string n = e->children[i]->name; + std::string n = (e->children[i]->name); + for (size_t i = 0; i < n.size(); i++) { + n[i] = tolower(n[i]); + } std::string curPath = path.substr(0, path.find_first_of('/')); + for (size_t i = 0; i < curPath.size(); i++) { + curPath[i] = tolower(curPath[i]); + } + if (curPath == n) { //yay we got it From 9c65a7b7f85425899cf365a7ab9694e9cedbe2a8 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 21:27:50 +0100 Subject: [PATCH 09/20] Fix issue with calling module imports --- Core/HLE/HLE.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 682c93005e..69af4be0c0 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -175,7 +175,8 @@ void ResolveSyscall(const char *moduleName, u32 nib, u32 address) { INFO_LOG(HLE,"Resolving %s/%08x",moduleName,nib); // Note: doing that, we can't trace external module calls, so maybe something else should be done to debug more efficiently - Memory::Write_U32(MIPS_MAKE_JAL(address), sysc->symAddr); + // Note that this should be J not JAL, as otherwise control will return to the stub.. + Memory::Write_U32(MIPS_MAKE_J(address), sysc->symAddr); Memory::Write_U32(MIPS_MAKE_NOP(), sysc->symAddr + 4); } } From 0ae55ae65cea9d9c16b3bf90c323add4776e58c5 Mon Sep 17 00:00:00 2001 From: TMaul Date: Mon, 17 Dec 2012 20:28:50 +0000 Subject: [PATCH 10/20] Ooops, didnt mean to leave that uncommented :) --- Core/FileSystems/ISOFileSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 761a7bbc45..f98cc88e9a 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -210,7 +210,7 @@ nextblock: e->isBlockSectorMode = false; // Let's not excessively spam the log - I commented this line out. - DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", name, dir.firstDataSectorLE, e->startingPosition, e->startingPosition); + //DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", name, dir.firstDataSectorLE, e->startingPosition, e->startingPosition); if (e->isDirectory && !relative) { From 913f392d6632a59d467a2f0bea0db602b02b4434 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 21:43:31 +0100 Subject: [PATCH 11/20] Move the SasInstance to the heap. Some cleanup. --- Core/HLE/sceSas.cpp | 115 +++++++++++++++++++++++-------------------- Core/HLE/sceSas.h | 3 ++ Core/HW/SasAudio.cpp | 7 ++- Core/HW/SasAudio.h | 34 ++++++++++--- 4 files changed, 96 insertions(+), 63 deletions(-) diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index bc482c572c..c19ae2c5bd 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -44,19 +44,27 @@ enum { // TODO - allow more than one, associating each with one Core pointer (passed in to all the functions) // No known games use more than one instance of Sas though. -SasInstance sas; +SasInstance *sas; + +void __SasInit() { + sas = new SasInstance(); +} + +void __SasShutdown() { + delete sas; + sas = 0; +} u32 sceSasInit(u32 core, u32 grainSize, u32 maxVoices, u32 outputMode, u32 sampleRate) { INFO_LOG(HLE,"0=sceSasInit(%08x, grainSize=%i, maxVoices=%i, %i, %i)", core, grainSize, maxVoices, outputMode, sampleRate); - memset(&sas, 0, sizeof(sas)); - sas.SetGrainSize(grainSize); - sas.maxVoices = maxVoices; - sas.sampleRate = sampleRate; - sas.outputMode = outputMode; + sas->SetGrainSize(grainSize); + sas->maxVoices = maxVoices; + sas->sampleRate = sampleRate; + sas->outputMode = outputMode; for (int i = 0; i < 32; i++) { - sas.voices[i].playing = false; + sas->voices[i].playing = false; } return 0; } @@ -64,8 +72,8 @@ u32 sceSasInit(u32 core, u32 grainSize, u32 maxVoices, u32 outputMode, u32 sampl u32 sceSasGetEndFlag(u32 core) { u32 endFlag = 0; - for (int i = 0; i < sas.maxVoices; i++) { - if (!sas.voices[i].playing) + for (int i = 0; i < sas->maxVoices; i++) { + if (!sas->voices[i].playing) endFlag |= 1 << i; } DEBUG_LOG(HLE,"%08x=sceSasGetEndFlag()", endFlag); @@ -75,23 +83,23 @@ u32 sceSasGetEndFlag(u32 core) // Runs the mixer u32 _sceSasCore(u32 core, u32 outAddr) { - DEBUG_LOG(HLE,"0=sceSasCore(, %08x) (grain: %i samples)", outAddr, sas.GetGrainSize()); + DEBUG_LOG(HLE,"0=sceSasCore(, %08x) (grain: %i samples)", outAddr, sas->GetGrainSize()); if (!Memory::IsValidAddress(outAddr)) { return ERROR_SAS_INVALID_PARAMETER; } - Memory::Memset(outAddr, 0, sas.GetGrainSize() * 2 * 2); - sas.Mix(outAddr); + Memory::Memset(outAddr, 0, sas->GetGrainSize() * 2 * 2); + sas->Mix(outAddr); return 0; } // Another way of running the mixer, what was the difference again? u32 _sceSasCoreWithMix(u32 core, u32 outAddr) { - DEBUG_LOG(HLE,"0=sceSasCoreWithMix(, %08x) (grain: %i samples)", outAddr, sas.GetGrainSize()); + DEBUG_LOG(HLE,"0=sceSasCoreWithMix(, %08x) (grain: %i samples)", outAddr, sas->GetGrainSize()); if (!Memory::IsValidAddress(outAddr)) { return ERROR_SAS_INVALID_PARAMETER; } - sas.Mix(outAddr); + sas->Mix(outAddr); return 0; } @@ -107,20 +115,32 @@ u32 sceSasSetVoice(u32 core, int voiceNum, u32 vagAddr, int size, int loop) } //Real VAG header is 0x30 bytes behind the vagAddr - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.type = VOICETYPE_VAG; v.vagAddr = vagAddr; v.vagSize = size; v.loop = loop ? true : false; - v.ChangedParams(); + v.ChangedParams(true); + return 0; +} + +u32 sceSasSetVoicePCM(u32 core, int voiceNum, u32 pcmAddr, int size, int loop) +{ + DEBUG_LOG(HLE,"0=sceSasSetVoicePCM(core=%08x, voicenum=%i, pcmAddr=%08x, size=%i, loop=%i)",core, voiceNum, pcmAddr, size, loop); + SasVoice &v = sas->voices[voiceNum]; + v.type = VOICETYPE_PCM; + v.pcmAddr = pcmAddr; + v.pcmSize = size; + v.loop = loop ? true : false; + v.playing = true; return 0; } u32 sceSasGetPauseFlag(u32 core) { u32 pauseFlag = 0; - for (int i = 0; i < sas.maxVoices; i++) { - if (sas.voices[i].paused) + for (int i = 0; i < sas->maxVoices; i++) { + if (sas->voices[i].paused) pauseFlag |= 1 << i; } DEBUG_LOG(HLE,"%08x=sceSasGetPauseFlag()", pauseFlag); @@ -135,7 +155,7 @@ u32 sceSasSetPause(u32 core, int voicebit, int pause) if (i < PSP_SAS_VOICES_MAX && i >= 0) { if ((voicebit & 1) != 0) - sas.voices[i].paused = pause ? true : false; + sas->voices[i].paused = pause ? true : false; } // TODO: Correct error code? Mimana crashes otherwise. else @@ -155,7 +175,7 @@ u32 sceSasSetVolume(u32 core, int voiceNum, int l, int r, int el, int er) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.volumeLeft = l; v.volumeRight = r; return 0; @@ -171,7 +191,7 @@ u32 sceSasSetPitch(u32 core, int voiceNum, int pitch) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.pitch = pitch; return 0; } @@ -186,7 +206,7 @@ u32 sceSasSetKeyOn(u32 core, int voiceNum) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.KeyOn(); return 0; } @@ -202,7 +222,7 @@ u32 sceSasSetKeyOff(u32 core, int voiceNum) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.KeyOff(); return 0; } @@ -217,7 +237,7 @@ u32 sceSasSetNoise(u32 core, int voiceNum, int freq) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.type = VOICETYPE_NOISE; v.noiseFreq = freq; return 0; @@ -233,7 +253,7 @@ u32 sceSasSetSL(u32 core, int voiceNum, int level) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.envelope.sustainLevel = level; return 0; } @@ -248,7 +268,7 @@ u32 sceSasSetADSR(u32 core, int voiceNum,int flag ,int a, int d, int s, int r) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; if ((flag & 0x1) != 0) v.envelope.attackRate = a; if ((flag & 0x2) != 0) v.envelope.decayRate = d; if ((flag & 0x4) != 0) v.envelope.sustainRate = s; @@ -266,7 +286,7 @@ u32 sceSasSetADSRMode(u32 core, int voiceNum,int flag ,int a, int d, int s, int return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; if ((flag & 0x1) != 0) v.envelope.attackType = a; if ((flag & 0x2) != 0) v.envelope.decayType = d; if ((flag & 0x4) != 0) v.envelope.sustainType = s; @@ -278,7 +298,7 @@ u32 sceSasSetADSRMode(u32 core, int voiceNum,int flag ,int a, int d, int s, int u32 sceSasSetSimpleADSR(u32 core, u32 voiceNum, u32 ADSREnv1, u32 ADSREnv2) { DEBUG_LOG(HLE,"0=sasSetSimpleADSR(%08x, %i, %08x, %08x)", core, voiceNum, ADSREnv1, ADSREnv2); - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; v.envelope.SetSimpleEnvelope(ADSREnv1 & 0xFFFF, ADSREnv2 & 0xFFFF); return 0; } @@ -296,85 +316,74 @@ u32 sceSasGetEnvelopeHeight(u32 core, u32 voiceNum) return ERROR_SAS_INVALID_VOICE; } - SasVoice &v = sas.voices[voiceNum]; + SasVoice &v = sas->voices[voiceNum]; return v.envelope.GetHeight(); } u32 sceSasRevType(u32 core, int type) { DEBUG_LOG(HLE,"0=sceSasRevType(core=%08x, type=%i)", core, type); - sas.waveformEffect.type = type; + sas->waveformEffect.type = type; return 0; } u32 sceSasRevParam(u32 core, int delay, int feedback) { DEBUG_LOG(HLE,"0=sceSasRevParam(core=%08x, delay=%i, feedback=%i)", core, delay, feedback); - sas.waveformEffect.delay = delay; - sas.waveformEffect.feedback = feedback; + sas->waveformEffect.delay = delay; + sas->waveformEffect.feedback = feedback; return 0; } u32 sceSasRevEVOL(u32 core, int lv, int rv) { DEBUG_LOG(HLE,"0=sceSasRevEVOL(core=%08x, leftVolume=%i, rightVolume=%i)", core, lv, rv); - sas.waveformEffect.leftVol = lv; - sas.waveformEffect.rightVol = rv; + sas->waveformEffect.leftVol = lv; + sas->waveformEffect.rightVol = rv; return 0; } u32 sceSasRevVON(u32 core, int dry, int wet) { DEBUG_LOG(HLE,"0=sceSasRevVON(core=%08x, dry=%i, wet=%i)", core, dry, wet); - sas.waveformEffect.isDryOn = (dry > 0); - sas.waveformEffect.isWetOn = (wet > 0); + sas->waveformEffect.isDryOn = (dry > 0); + sas->waveformEffect.isWetOn = (wet > 0); return 0; } u32 sceSasGetGrain(u32 core) { DEBUG_LOG(HLE,"0=sceSasGetGrain(core=%08x)", core); - return sas.GetGrainSize(); + return sas->GetGrainSize(); } u32 sceSasSetGrain(u32 core, int grain) { INFO_LOG(HLE,"0=sceSasSetGrain(core=%08x, grain=%i)", core, grain); - sas.SetGrainSize(grain); + sas->SetGrainSize(grain); return 0; } u32 sceSasGetOutputMode(u32 core) { DEBUG_LOG(HLE,"0=sceSasGetOutputMode(core=%08x)", core); - return sas.outputMode; + return sas->outputMode; } u32 sceSasSetOutputMode(u32 core, u32 outputMode) { DEBUG_LOG(HLE,"0=sceSasSetOutputMode(core=%08x, outputMode=%i)", core, outputMode); - sas.outputMode = outputMode; + sas->outputMode = outputMode; return 0; } -u32 sceSasSetVoicePCM(u32 core, int voiceNum, u32 pcmAddr, int size, int loop) -{ - DEBUG_LOG(HLE,"0=sceSasSetVoicePCM(core=%08x, voicenum=%i, pcmAddr=%08x, size=%i, loop=%i)",core, voiceNum, pcmAddr, size, loop); - SasVoice &v = sas.voices[voiceNum]; - v.type = VOICETYPE_PCM; - v.pcmAddr = pcmAddr; - v.pcmSize = size; - v.loop = loop ? true : false; - v.playing = true; - return 0; -} u32 sceSasGetAllEnvelopeHeights(u32 core, u32 heightsAddr) { DEBUG_LOG(HLE,"0=sceSasGetAllEnvelopeHeights(core=%08x, heightsAddr=%i)", core, heightsAddr); if (Memory::IsValidAddress(heightsAddr)) { - for (int i = 0; i < sas.length; i++) { - int voiceHeight = sas.voices[i].envelope.GetHeight(); + for (int i = 0; i < PSP_SAS_VOICES_MAX; i++) { + int voiceHeight = sas->voices[i].envelope.GetHeight(); Memory::Write_U32(voiceHeight, heightsAddr + i * 4); } } diff --git a/Core/HLE/sceSas.h b/Core/HLE/sceSas.h index bc3e331bbf..58efddd75b 100644 --- a/Core/HLE/sceSas.h +++ b/Core/HLE/sceSas.h @@ -17,4 +17,7 @@ #pragma once +void __SasInit(); +void __SasShutdown(); + void Register_sceSasCore(); diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index e22d99323d..5846acf483 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -168,7 +168,8 @@ void ADSREnvelope::SetSimpleEnvelope(u32 ADSREnv1, u32 ADSREnv2) { sustainLevel = getSustainLevel(ADSREnv1); } -SasInstance::SasInstance() : mixBuffer(0), sendBuffer(0), resampleBuffer(0), grainSize(0) { +SasInstance::SasInstance() + : mixBuffer(0), sendBuffer(0), resampleBuffer(0), grainSize(0) { } SasInstance::~SasInstance() { @@ -318,9 +319,11 @@ void SasVoice::KeyOff() { envelope.KeyOff(); } -void SasVoice::ChangedParams() { +void SasVoice::ChangedParams(bool changedVag) { if (!playing && on) { playing = true; + if (changedVag) + vag.Start(Memory::GetPointer(vagAddr), loop); } // TODO: restart VAG somehow } diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index 4478652cf8..3b776f5c6d 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -61,12 +61,13 @@ struct WaveformEffect }; enum VoiceType { - VOICETYPE_VAG = 0, // default - VOICETYPE_PCM = 1, - VOICETYPE_NOISE = 2, - VOICETYPE_ATRAC3 = 3, - VOICETYPE_TRIWAVE = 4, // are these used? there are functions for them (sceSetTriangularWave) - VOICETYPE_PULSEWAVE = 5, + VOICETYPE_OFF, + VOICETYPE_VAG, // default + VOICETYPE_PCM, + VOICETYPE_NOISE, + VOICETYPE_ATRAC3, + VOICETYPE_TRIWAVE, // are these used? there are functions for them (sceSetTriangularWave) + VOICETYPE_PULSEWAVE, }; // VAG is a Sony ADPCM audio compression format, which goes all the way back to the PSX. @@ -76,6 +77,7 @@ enum VoiceType { class VagDecoder { public: + VagDecoder() : data_(0), read_(0) {} void Start(u8 *data, bool loopEnabled); void GetSamples(s16 *outSamples, int numSamples); @@ -154,6 +156,23 @@ private: // It's not very likely that games encode VAG dynamically. struct SasVoice { + SasVoice() + : playing(false), paused(false), on(false), + type(VOICETYPE_OFF), + vagAddr(0), + vagSize(0), + pcmAddr(0), + pcmSize(0), + sampleRate(44100), + samplePos(0), + pitch(PSP_SAS_PITCH_BASE), + loop(false), + noiseFreq(0), + volumeLeft(0), + volumeRight(0), + volumeLeftSend(0), + volumeRightSend(0) {} + bool playing; bool paused; // a voice can be playing AND paused. In that case, it won't play. bool on; // key-on, key-off. @@ -182,7 +201,7 @@ struct SasVoice void KeyOn(); void KeyOff(); - void ChangedParams(); + void ChangedParams(bool changedVag); s16 resampleHist[2]; @@ -203,7 +222,6 @@ public: int maxVoices; int sampleRate; int outputMode; - int length; int *mixBuffer; int *sendBuffer; From a60d487d8db4ce6b9064acd561f02ea2a1876dcb Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 21:45:32 +0100 Subject: [PATCH 12/20] Create files for sceUsb --- CMakeLists.txt | 2 ++ Core/CMakeLists.txt | 1 + Core/Core.vcxproj | 2 ++ Core/Core.vcxproj.filters | 6 ++++ Core/HLE/HLETables.cpp | 33 ++---------------- Core/HLE/sceDisplay.cpp | 13 ++++--- Core/HLE/sceKernel.cpp | 3 ++ Core/HLE/sceUsb.cpp | 64 ++++++++++++++++++++++++++++++++++ Core/HLE/sceUsb.h | 20 +++++++++++ Windows/PPSSPP.vcxproj | 3 +- Windows/PPSSPP.vcxproj.filters | 1 + android/jni/Android.mk | 1 + 12 files changed, 110 insertions(+), 39 deletions(-) create mode 100644 Core/HLE/sceUsb.cpp create mode 100644 Core/HLE/sceUsb.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a48b2b886..858bc710c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,6 +721,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/HLE/scesupPreAcc.h Core/HLE/sceUmd.cpp Core/HLE/sceUmd.h + Core/HLE/sceUsb.cpp + Core/HLE/sceUsb.h Core/HLE/sceUtility.cpp Core/HLE/sceUtility.h Core/HLE/sceVaudio.cpp diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 4894a26d59..c96cec250a 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -55,6 +55,7 @@ set(SRCS HLE/sceRtc.cpp HLE/sceSas.cpp HLE/sceUmd.cpp + HLE/sceUsb.cpp HLE/sceUtility.cpp HLE/sceParseUri.cpp HLE/sceSsl.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 7447844c2a..e7c9e19328 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -170,6 +170,7 @@ + @@ -316,6 +317,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index a3a729f24a..0784ba189c 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -345,6 +345,9 @@ HW + + HLE\Libraries + @@ -635,6 +638,9 @@ HW + + HLE\Libraries + diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index 67d1ef8d9e..a2e2f5a634 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -53,6 +53,7 @@ #include "sceParseHttp.h" #include "scesupPreAcc.h" #include "sceVaudio.h" +#include "sceUsb.h" #define N(s) s @@ -185,43 +186,12 @@ const HLEFunction pspeDebug[] = }; -const HLEFunction sceUsb[] = -{ - {0xae5de6af, 0, "sceUsbStart"}, - {0xc2464fa0, 0, "sceUsbStop"}, - {0xc21645a4, 0, "sceUsbGetState"}, - {0x4e537366, 0, "sceUsbGetDrvList"}, - {0x112cc951, 0, "sceUsbGetDrvState"}, - {0x586db82c, 0, "sceUsbActivate"}, - {0xc572a9c8, 0, "sceUsbDeactivate"}, - {0x5be0e002, 0, "sceUsbWaitState"}, - {0x1c360735, 0, "sceUsbWaitCancel"}, -}; - -const HLEFunction sceUsbstor[] = -{ - {0x60066CFE, 0, "sceUsbstorGetStatus"}, -}; - -const HLEFunction sceUsbstorBoot[] = -{ - {0xE58818A8, 0, "sceUsbstorBootSetCapacity"}, - {0x594BBF95, 0, "sceUsbstorBootSetLoadAddr"}, - {0x6D865ECD, 0, "sceUsbstorBootGetDataSize"}, - {0xA1119F0D, 0, "sceUsbstorBootSetStatus"}, - {0x1F080078, 0, "sceUsbstorBootRegisterNotify"}, - {0xA55C9E16, 0, "sceUsbstorBootUnregisterNotify"}, -}; - const HLEModule moduleList[] = { {"FakeSysCalls", SZ(FakeSysCalls), FakeSysCalls}, {"UtilsForUser",SZ(UtilsForUser),UtilsForUser}, {"KDebugForKernel",SZ(KDebugForKernel),KDebugForKernel}, {"sceSAScore"}, - {"sceUsbstor",SZ(sceUsbstor),sceUsbstor}, - {"sceUsbstorBoot",SZ(sceUsbstorBoot),sceUsbstorBoot}, - {"sceUsb", SZ(sceUsb), sceUsb}, {"SceBase64_Library"}, {"sceCert_Loader"}, {"SceFont_Library"}, @@ -275,6 +245,7 @@ void RegisterAllModules() { Register_sceParseHttp(); Register_scesupPreAcc(); Register_sceVaudio(); + Register_sceUsb(); for (int i = 0; i < numModules; i++) { diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 451e100a42..591c1b382d 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -265,7 +265,7 @@ u32 sceDisplaySetMode(u32 unknown, u32 xres, u32 yres) return 0; } -void sceDisplaySetFramebuf() +u32 sceDisplaySetFramebuf() { //host->EndFrame(); u32 topaddr = PARAM(0); @@ -298,8 +298,7 @@ void sceDisplaySetFramebuf() latchedFramebuf = fbstate; framebufIsLatched = true; } - - RETURN(0); + return 0; } u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, int mode) @@ -392,16 +391,16 @@ float sceDisplayGetFramePerSec() const HLEFunction sceDisplay[] = { - {0x0E20F177,&WrapU_UUU, "sceDisplaySetMode"}, - {0x289D82FE,sceDisplaySetFramebuf, "sceDisplaySetFramebuf"}, - {0xEEDA2E54,&WrapU_UUUI,"sceDisplayGetFrameBuf"}, + {0x0E20F177,WrapU_UUU, "sceDisplaySetMode"}, + {0x289D82FE,WrapU_V, "sceDisplaySetFramebuf"}, + {0xEEDA2E54,WrapU_UUUI,"sceDisplayGetFrameBuf"}, {0x36CDFADE,sceDisplayWaitVblank, "sceDisplayWaitVblank"}, {0x984C27E7,sceDisplayWaitVblankStart, "sceDisplayWaitVblankStart"}, {0x40f1469c,sceDisplayWaitVblankStartMulti, "sceDisplayWaitVblankStartMulti"}, {0x8EB9EC49,sceDisplayWaitVblankCB, "sceDisplayWaitVblankCB"}, {0x46F186C3,sceDisplayWaitVblankStartCB, "sceDisplayWaitVblankStartCB"}, {0x77ed8b3a,sceDisplayWaitVblankStartMultiCB,"sceDisplayWaitVblankStartMultiCB"}, - {0xdba6c4c4,&WrapF_V,"sceDisplayGetFramePerSec"}, + {0xdba6c4c4,WrapF_V,"sceDisplayGetFramePerSec"}, {0x773dd3a3,sceDisplayGetCurrentHcount,"sceDisplayGetCurrentHcount"}, {0x210eab3a,sceDisplayGetAccumulatedHcount,"sceDisplayGetAccumulatedHcount"}, {0x9C6EAAD7,sceDisplayGetVcount,"sceDisplayGetVcount"}, diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 662cc30d68..3740e35070 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -50,6 +50,7 @@ #include "sceUtility.h" #include "sceUmd.h" #include "sceSsl.h" +#include "sceSas.h" #include "../Util/PPGeDraw.h" @@ -76,6 +77,7 @@ void __KernelInit() __KernelThreadingInit(); __IoInit(); __AudioInit(); + __SasInit(); __DisplayInit(); __InterruptsInit(); __GeInit(); @@ -106,6 +108,7 @@ void __KernelShutdown() __PPGeShutdown(); __GeShutdown(); + __SasShutdown(); __AudioShutdown(); __IoShutdown(); __InterruptsShutdown(); diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp new file mode 100644 index 0000000000..faec5397a9 --- /dev/null +++ b/Core/HLE/sceUsb.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "HLE.h" +#include "../MIPS/MIPS.h" +#include "../../Core/CoreTiming.h" +#include "sceUsb.h" + +bool usbActivated = false; + +u32 sceUsbActivate() { + ERROR_LOG(HLE, "UNIMPL sceUsbActivate"); + usbActivated = true; + return 0; +} + +const HLEFunction sceUsb[] = +{ + {0xae5de6af, 0, "sceUsbStart"}, + {0xc2464fa0, 0, "sceUsbStop"}, + {0xc21645a4, 0, "sceUsbGetState"}, + {0x4e537366, 0, "sceUsbGetDrvList"}, + {0x112cc951, 0, "sceUsbGetDrvState"}, + {0x586db82c, WrapU_V, "sceUsbActivate"}, + {0xc572a9c8, 0, "sceUsbDeactivate"}, + {0x5be0e002, 0, "sceUsbWaitState"}, + {0x1c360735, 0, "sceUsbWaitCancel"}, +}; + +const HLEFunction sceUsbstor[] = +{ + {0x60066CFE, 0, "sceUsbstorGetStatus"}, +}; + +const HLEFunction sceUsbstorBoot[] = +{ + {0xE58818A8, 0, "sceUsbstorBootSetCapacity"}, + {0x594BBF95, 0, "sceUsbstorBootSetLoadAddr"}, + {0x6D865ECD, 0, "sceUsbstorBootGetDataSize"}, + {0xA1119F0D, 0, "sceUsbstorBootSetStatus"}, + {0x1F080078, 0, "sceUsbstorBootRegisterNotify"}, + {0xA55C9E16, 0, "sceUsbstorBootUnregisterNotify"}, +}; + +void Register_sceUsb() +{ + RegisterModule("sceUsbstor", ARRAY_SIZE(sceUsbstor), sceUsbstor); + RegisterModule("sceUsbstorBoot", ARRAY_SIZE(sceUsbstorBoot), sceUsbstorBoot); + RegisterModule("sceUsb", ARRAY_SIZE(sceUsb), sceUsb); +} diff --git a/Core/HLE/sceUsb.h b/Core/HLE/sceUsb.h new file mode 100644 index 0000000000..009f44ec96 --- /dev/null +++ b/Core/HLE/sceUsb.h @@ -0,0 +1,20 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +void Register_sceUsb(); diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 8016e5e377..4d14a6d2e3 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -323,6 +323,7 @@ + @@ -360,4 +361,4 @@ - + \ No newline at end of file diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 5786358b73..c76c21f6ca 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -203,6 +203,7 @@ Android + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 245346dffe..13a44e02f1 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -141,6 +141,7 @@ LOCAL_SRC_FILES := \ $(SRC)/Core/HLE/sceSas.cpp \ $(SRC)/Core/HLE/sceSsl.cpp \ $(SRC)/Core/HLE/sceUmd.cpp \ + $(SRC)/Core/HLE/sceUsb.cpp \ $(SRC)/Core/HLE/sceUtility.cpp \ $(SRC)/Core/HLE/sceVaudio.cpp \ $(SRC)/Core/HLE/scesupPreAcc.cpp \ From c3819ec721220d37b90f6acaa2215492144bc6ac Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 21:59:43 +0100 Subject: [PATCH 13/20] Fix a possible crash in audio code --- Core/HW/SasAudio.cpp | 19 ++++++++++++------- GPU/GLES/DisplayListInterpreter.cpp | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 5846acf483..c9413b3308 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -207,7 +207,7 @@ void SasInstance::Mix(u32 outAddr) { // TODO: Special case no-resample case for speed - if (voice.vagAddr != 0) { + if (voice.type == VOICETYPE_VAG && voice.vagAddr != 0) { // Load resample history (so we can use a wide filter) resampleBuffer[0] = voice.resampleHist[0]; resampleBuffer[1] = voice.resampleHist[1]; @@ -263,10 +263,10 @@ void SasInstance::Mix(u32 outAddr) { voice.playing = false; } } - else if (voice.pcmAddr != 0) { + else if (voice.type == VOICETYPE_PCM && voice.pcmAddr != 0) { // PCM mixing should be easy, can share code with VAG } - else if (voice.noiseFreq != 0) { + else if (voice.type == VOICETYPE_NOISE && voice.noiseFreq != 0) { // Generate noise? } } @@ -301,17 +301,22 @@ void SasVoice::Reset() { } void SasVoice::KeyOn() { - on = true; - playing = true; - paused = false; envelope.KeyOn(); switch (type) { case VOICETYPE_VAG: - vag.Start(Memory::GetPointer(vagAddr), loop); + if (Memory::IsValidAddress(vagAddr)) { + vag.Start(Memory::GetPointer(vagAddr), loop); + } else { + ERROR_LOG(SAS, "Invalid VAG address %08x", vagAddr); + return; + } break; default: break; } + playing = true; + on = true; + paused = false; } void SasVoice::KeyOff() { diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 3f4154ad11..856710c134 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -106,7 +106,7 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) displayStride_ = stride; displayFormat_ = format; } else { - DEBUG_LOG(HLE, "Bogus framebuffer address: %08x", framebuf); + ERROR_LOG(HLE, "Bogus framebuffer address: %08x", framebuf); } } From 19af6531f70ba35b8e4fec0b0b6af7b5d618b81a Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 22:06:19 +0100 Subject: [PATCH 14/20] Warning fix (and I don't like shadowing) --- Core/FileSystems/ISOFileSystem.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index f98cc88e9a..11c8e88954 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -255,12 +255,12 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path) for (size_t i=0; ichildren.size(); i++) { std::string n = (e->children[i]->name); - for (size_t i = 0; i < n.size(); i++) { - n[i] = tolower(n[i]); + for (size_t j = 0; j < n.size(); j++) { + n[j] = tolower(n[j]); } std::string curPath = path.substr(0, path.find_first_of('/')); - for (size_t i = 0; i < curPath.size(); i++) { - curPath[i] = tolower(curPath[i]); + for (size_t j = 0; j < curPath.size(); j++) { + curPath[j] = tolower(curPath[j]); } if (curPath == n) From 5a11d4d9c5efb875a3f65a52d7a5d321d8b1a8cc Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 22:20:32 +0100 Subject: [PATCH 15/20] Implement sceKernelGetThreadmanIdList (partially) --- Core/HLE/sceAudio.cpp | 2 +- Core/HLE/sceKernel.cpp | 4 ++-- Core/HLE/sceKernelThread.cpp | 41 ++++++++++++++++++++++++------------ Core/HLE/sceKernelThread.h | 3 ++- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index ea64d027fa..bcfcb6300c 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -226,7 +226,7 @@ u32 sceAudioSetChannelDataLen(u32 chan, u32 len) } else { - INFO_LOG(HLE, "sceAudioSetChannelDataLen(%i, %i)", chan, len); + DEBUG_LOG(HLE, "sceAudioSetChannelDataLen(%i, %i)", chan, len); chans[chan].sampleCount = len; return 0; } diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 3740e35070..9e8fd755db 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -385,8 +385,8 @@ const HLEFunction ThreadManForUser[] = {0x840E8133,sceKernelWaitThreadEndCB,"sceKernelWaitThreadEndCB"}, {0xd13bde95,sceKernelCheckThreadStack,"sceKernelCheckThreadStack"}, - {0x94416130,0,"sceKernelGetThreadmanIdList"}, - {0x57CF62DD,sceKernelGetThreadmanIdType,"sceKernelGetThreadmanIdType"}, + {0x94416130,WrapU_UUUU,"sceKernelGetThreadmanIdList"}, + {0x57CF62DD,WrapU_U,"sceKernelGetThreadmanIdType"}, {0x20fff560,sceKernelCreateVTimer,"sceKernelCreateVTimer"}, {0x328F9E52,0,"sceKernelDeleteVTimer"}, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 8f0fbdf9eb..b6ad2c7a00 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -522,20 +522,35 @@ void sceKernelGetThreadExitStatus() } } -void sceKernelGetThreadmanIdType() +u32 sceKernelGetThreadmanIdType(u32 uid) { + int type; + if (kernelObjects.GetIDType(uid, &type)) { + DEBUG_LOG(HLE, "%i=sceKernelGetThreadmanIdType(%i)", type, uid); + return type; + } else { + ERROR_LOG(HLE, "sceKernelGetThreadmanIdType(%i) - FAILED", uid); + return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; + } +} + +u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr) { - SceUID uid = PARAM(0); - int type; - if (kernelObjects.GetIDType(uid, &type)) - { - RETURN(type); - DEBUG_LOG(HLE, "%i=sceKernelGetThreadmanIdType(%i)", type, uid); - } - else - { - ERROR_LOG(HLE, "sceKernelGetThreadmanIdType(%i) - FAILED", uid); - RETURN(SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT); - } + DEBUG_LOG(HLE, "sceKernelGetThreadmanIdList(%i, %08x, %i, %08x)", + type, readBufPtr, readBufSize, idCountPtr); + if (!Memory::IsValidAddress(readBufPtr)) + return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; + + if (type != SCE_KERNEL_TMID_Thread) { + ERROR_LOG(HLE, "sceKernelGetThreadmanIdList only implemented for threads"); + return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; + } + + for (size_t i = 0; i < std::min(readBufSize, threadqueue.size()); i++) + { + Memory::Write_U32(threadqueue[i]->GetUID(), readBufPtr + i * 4); + } + Memory::Write_U32(threadqueue.size(), idCountPtr); + return 0; } // Saves the current CPU context diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index bf9a3631a5..eb99e239e4 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -51,7 +51,8 @@ int sceKernelTerminateDeleteThread(int threadno); int sceKernelTerminateThread(u32 threadID); void sceKernelWaitThreadEndCB(); void sceKernelGetThreadExitStatus(); -void sceKernelGetThreadmanIdType(); +u32 sceKernelGetThreadmanIdType(u32); +u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr); enum WaitType //probably not the real values From 624927cd9a46d3960fe4584000b6666e9a90f2f6 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 22:24:07 +0100 Subject: [PATCH 16/20] Make the windows port find ppge_atlas in the assets subdirectory. --- Windows/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Windows/main.cpp b/Windows/main.cpp index 7170d7ba2a..1a859b1a89 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -56,6 +56,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin token = strtok(szCmdLine," "); g_Config.Load(); + VFSRegister("", new DirectoryAssetReader("assets/")); VFSRegister("", new DirectoryAssetReader("")); while (token) From 5ff2bf84efab4324147ef5a829ec439c3ae36b98 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 22:34:34 +0100 Subject: [PATCH 17/20] Path cleaning bugfix --- Core/FileSystems/MetaFileSystem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index b1b48ba11d..64278e4e46 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -20,6 +20,7 @@ bool applyPathStringToComponentsVector(std::vector &vector, const std::string &pathString) { + vector.clear(); size_t len = pathString.length(); size_t start = 0; From 3bd5cfed737294f2583e310bfb84082d58bf8ebe Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 17 Dec 2012 22:52:31 +0100 Subject: [PATCH 18/20] Work around for strange idling issue, various fixes --- Core/CoreTiming.cpp | 2 ++ Core/HLE/sceDisplay.cpp | 13 +++++++++---- Core/HLE/sceUmd.cpp | 16 +++++++++++++++- GPU/GLES/DisplayListInterpreter.cpp | 3 ++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index c9bc5a6db7..6cffd3d3eb 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -504,6 +504,8 @@ void Idle(int maxIdle) idledCycles += cyclesDown; downcount -= cyclesDown; + if (downcount == 0) + downcount = -1; } std::string GetScheduledEventsSummary() diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 591c1b382d..df34fda23c 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -359,13 +359,18 @@ void sceDisplayWaitVblankStartMultiCB() __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); } -void sceDisplayGetVcount() +u32 sceDisplayGetVcount() { // Too spammy // DEBUG_LOG(HLE,"%i=sceDisplayGetVcount()", vCount); - // Games like Puyo Puyo call this in a tight loop at end-of-frame. We could have it consume some time from CoreTiming? + + // Puyo Puyo Fever polls this as a substitute for waiting vblank. + // As a result, the game never gets to reschedule so it doesn't mix audio and things break. + // I added this as a workaround until we figure out what call actually does reschedule - it doesn't call much though... + CoreTiming::Idle(1000000); - RETURN(vCount); + __KernelReSchedule(); // Puyo puyo hack? + return vCount; } void sceDisplayGetCurrentHcount() @@ -403,7 +408,7 @@ const HLEFunction sceDisplay[] = {0xdba6c4c4,WrapF_V,"sceDisplayGetFramePerSec"}, {0x773dd3a3,sceDisplayGetCurrentHcount,"sceDisplayGetCurrentHcount"}, {0x210eab3a,sceDisplayGetAccumulatedHcount,"sceDisplayGetAccumulatedHcount"}, - {0x9C6EAAD7,sceDisplayGetVcount,"sceDisplayGetVcount"}, + {0x9C6EAAD7,WrapU_V,"sceDisplayGetVcount"}, {0xDEA197D4,0,"sceDisplayGetMode"}, {0x7ED59BC4,0,"sceDisplaySetHoldMode"}, {0xA544C486,0,"sceDisplaySetResumeMode"}, diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 35f4534173..fbe74b1ce8 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -300,6 +300,19 @@ u32 sceUmdGetErrorStat() return umdErrorStat; } +u32 sceUmdReplaceProhibit() +{ + DEBUG_LOG(HLE,"sceUmdReplaceProhibit()"); + return 0; +} + +u32 sceUmdReplacePermit() +{ + DEBUG_LOG(HLE,"sceUmdReplacePermit()"); + return 0; +} + + const HLEFunction sceUmdUser[] = { @@ -316,7 +329,8 @@ const HLEFunction sceUmdUser[] = {0x340B7686,WrapU_U,"sceUmdGetDiscInfo"}, {0xAEE7404D,&WrapU_U,"sceUmdRegisterUMDCallBack"}, {0xBD2BDE07,&WrapU_U,"sceUmdUnRegisterUMDCallBack"}, - {0x87533940,0,"sceUmdReplaceProhibit"}, // ??? sounds bogus + {0x87533940,WrapU_V,"sceUmdReplaceProhibit"}, + {0x87533940,WrapU_V,"sceUmdReplacePermit"}, }; void Register_sceUmdUser() diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 856710c134..90931d75bc 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -47,7 +47,8 @@ GLES_GPU::GLES_GPU(int renderWidth, int renderHeight) : interruptsEnabled_(true), renderWidth_(renderWidth), renderHeight_(renderHeight), - dlIdGenerator(1) + dlIdGenerator(1), + displayFramebufPtr_(0) { renderWidthFactor_ = (float)renderWidth / 480.0f; renderHeightFactor_ = (float)renderHeight / 272.0f; From 29379282379cf129f37b7546131166f89aeea3d9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 18 Dec 2012 00:01:40 +0100 Subject: [PATCH 19/20] Better hack for a path problem. Still don't get it. --- Core/FileSystems/DirectoryFileSystem.cpp | 2 +- Core/FileSystems/MetaFileSystem.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 64089cf6d3..6513fb7b9a 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -138,7 +138,7 @@ u32 DirectoryFileSystem::OpenFile(std::string filename, FileAccess access) if (!success) { #ifdef _WIN32 - ERROR_LOG(HLE, "DirectoryFileSystem::OpenFile: FAILED, %i", GetLastError()); + ERROR_LOG(HLE, "DirectoryFileSystem::OpenFile: FAILED, %i - access = %i", GetLastError(), (int)access); #endif //wwwwaaaaahh!! return 0; diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 64278e4e46..9d69f1d138 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -20,7 +20,6 @@ bool applyPathStringToComponentsVector(std::vector &vector, const std::string &pathString) { - vector.clear(); size_t len = pathString.length(); size_t start = 0; @@ -117,6 +116,12 @@ bool RealPath(const std::string ¤tDirectory, const std::string &inPath, st std::vector cmpnts; // path components size_t capacityGuess = inPath.length(); + // Special hack for strange root paths. + // Don't understand why this is needed. I don't think the current + // directory should be the root. + if (inAfter.substr(0, 11) == "./PSP_GAME/") + inAfter = inAfter.substr(1); + if ((inAfter[0] != '/')) { if (curDirLen == 0) From ba476264db2f5e52695538545d4c6b64267c3754 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 18 Dec 2012 00:02:04 +0100 Subject: [PATCH 20/20] Fix GL_ZERO transparencies --- GPU/GLES/TransformPipeline.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 31071a23b6..58ce633357 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -556,34 +556,34 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte // All is valid, no blendcolor needed glstate.blendFunc.set(aLookup[blendFuncA], bLookup[blendFuncB]); } else { - GLuint glBlendFuncA = blendFuncA == GE_SRCBLEND_FIXA ? 0 : aLookup[blendFuncA]; - GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? 0 : bLookup[blendFuncB]; + GLuint glBlendFuncA = blendFuncA == GE_SRCBLEND_FIXA ? GL_INVALID_ENUM : aLookup[blendFuncA]; + GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? GL_INVALID_ENUM : bLookup[blendFuncB]; u32 fixA = gstate.getFixA(); u32 fixB = gstate.getFixB(); // Shortcut by using GL_ONE where possible, no need to set blendcolor - if (!glBlendFuncA && blendFuncA == GE_SRCBLEND_FIXA) { + if (glBlendFuncA == GL_INVALID_ENUM && blendFuncA == GE_SRCBLEND_FIXA) { if (fixA == 0xFFFFFF) glBlendFuncA = GL_ONE; else if (fixA == 0) glBlendFuncA = GL_ZERO; } - if (!glBlendFuncB && blendFuncB == GE_DSTBLEND_FIXB) { + if (glBlendFuncB == GL_INVALID_ENUM && blendFuncB == GE_DSTBLEND_FIXB) { if (fixB == 0xFFFFFF) glBlendFuncB = GL_ONE; else if (fixB == 0) glBlendFuncB = GL_ZERO; } - if (!glBlendFuncA && glBlendFuncB) { + if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB != GL_INVALID_ENUM) { // Can use blendcolor trivially. const float blendColor[4] = {(fixA & 0xFF)/255.0f, ((fixA >> 8) & 0xFF)/255.0f, ((fixA >> 16) & 0xFF)/255.0f, 1.0f}; glstate.blendColor.set(blendColor); glBlendFuncA = GL_CONSTANT_COLOR; - } else if (glBlendFuncA && !glBlendFuncB) { + } else if (glBlendFuncA != GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) { // Can use blendcolor trivially. const float blendColor[4] = {(fixB & 0xFF)/255.0f, ((fixB >> 8) & 0xFF)/255.0f, ((fixB >> 16) & 0xFF)/255.0f, 1.0f}; glstate.blendColor.set(blendColor); glBlendFuncB = GL_CONSTANT_COLOR; - } else if (!glBlendFuncA && !glBlendFuncB) { // Should also check for approximate equality + } else if (glBlendFuncA == GL_INVALID_ENUM && glBlendFuncB == GL_INVALID_ENUM) { // Should also check for approximate equality if (fixA == (fixB ^ 0xFFFFFF)) { glBlendFuncA = GL_CONSTANT_COLOR; glBlendFuncB = GL_ONE_MINUS_CONSTANT_COLOR;