From 9965f7c071c9fbfbd2b42997a61e43fc44d67118 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 13 Jun 2013 22:11:04 -0700 Subject: [PATCH 01/51] Update ffmpeg. --- ffmpeg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg b/ffmpeg index 697244c4b7..5f420cb666 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 697244c4b79b396de86e5d7fdbf9bc4771b815e9 +Subproject commit 5f420cb6667430edaaef2d97bb85b170db67c45d From 5b17005e31f74a6bd44189ab0ee274e028254f66 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 13 Jun 2013 22:12:16 -0700 Subject: [PATCH 02/51] Correct result of scePsmfGetVideoInfo(). --- Core/HLE/scePsmf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index df1a7ee6bf..a1b70c91f2 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -494,12 +494,12 @@ u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) { INFO_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetNumberOfSpecificStreams - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetVideoInfo - invalid psmf"); return ERROR_PSMF_NOT_FOUND; } if (Memory::IsValidAddress(videoInfoAddr)) { Memory::Write_U32(psmf->videoWidth, videoInfoAddr); - Memory::Write_U32(psmf->videoWidth, videoInfoAddr + 4); + Memory::Write_U32(psmf->videoHeight, videoInfoAddr + 4); } return 0; } @@ -508,7 +508,7 @@ u32 scePsmfGetAudioInfo(u32 psmfStruct, u32 audioInfoAddr) { INFO_LOG(HLE, "scePsmfGetAudioInfo(%08x, %08x)", psmfStruct, audioInfoAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetNumberOfSpecificStreams - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetAudioInfo - invalid psmf"); return ERROR_PSMF_NOT_FOUND; } if (Memory::IsValidAddress(audioInfoAddr)) { From 1af3ef08807cc7eedda517435f3634167342edf8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 13 Jun 2013 22:21:39 -0700 Subject: [PATCH 03/51] Clean up scePsmf logging. --- Core/HLE/scePsmf.cpp | 76 ++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index a1b70c91f2..0b4f2b6bd3 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -436,7 +436,7 @@ u32 scePsmfGetNumberOfStreams(u32 psmfStruct) { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetNumberOfStreams - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetNumberOfStreams(%08x): invalid psmf", psmfStruct); return ERROR_PSMF_NOT_FOUND; } DEBUG_LOG(HLE, "scePsmfGetNumberOfStreams(%08x)", psmfStruct); @@ -447,10 +447,10 @@ u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, u32 streamType) { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetNumberOfSpecificStreams - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetNumberOfSpecificStreams(%08x, %08x): invalid psmf", psmfStruct, streamType); return ERROR_PSMF_NOT_FOUND; } - INFO_LOG(HLE, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType); + WARN_LOG(HLE, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType); return 1; } @@ -458,7 +458,7 @@ u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 chann { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfSpecifyStreamWithStreamType - invalid psmf"); + ERROR_LOG(HLE, "scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i): invalid psmf", psmfStruct, streamType, channel); return ERROR_PSMF_NOT_FOUND; } ERROR_LOG(HLE, "UNIMPL scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i)", psmfStruct, streamType, channel); @@ -472,17 +472,17 @@ u32 scePsmfSpecifyStreamWithStreamTypeNumber(u32 psmfStruct, u32 streamType, u32 { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfSpecifyStream - invalid psmf"); + ERROR_LOG(HLE, "scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x): invalid psmf", psmfStruct, streamType, typeNum); return ERROR_PSMF_NOT_FOUND; } - ERROR_LOG(HLE, "UNIMPL scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x)", psmfStruct, streamType, typeNum); + ERROR_LOG_REPORT(HLE, "UNIMPL scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x)", psmfStruct, streamType, typeNum); return 0; } u32 scePsmfSpecifyStream(u32 psmfStruct, int streamNum) { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfSpecifyStream - invalid psmf"); + ERROR_LOG(HLE, "scePsmfSpecifyStream(%08x, %i): invalid psmf", psmfStruct, streamNum); return ERROR_PSMF_NOT_FOUND; } INFO_LOG(HLE, "scePsmfSpecifyStream(%08x, %i)", psmfStruct, streamNum); @@ -491,12 +491,12 @@ u32 scePsmfSpecifyStream(u32 psmfStruct, int streamNum) { } u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) { - INFO_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetVideoInfo - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x): invalid psmf", psmfStruct, videoInfoAddr); return ERROR_PSMF_NOT_FOUND; } + INFO_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr); if (Memory::IsValidAddress(videoInfoAddr)) { Memory::Write_U32(psmf->videoWidth, videoInfoAddr); Memory::Write_U32(psmf->videoHeight, videoInfoAddr + 4); @@ -505,12 +505,12 @@ u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) { } u32 scePsmfGetAudioInfo(u32 psmfStruct, u32 audioInfoAddr) { - INFO_LOG(HLE, "scePsmfGetAudioInfo(%08x, %08x)", psmfStruct, audioInfoAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetAudioInfo - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetAudioInfo(%08x, %08x): invalid psmf", psmfStruct, audioInfoAddr); return ERROR_PSMF_NOT_FOUND; } + INFO_LOG(HLE, "scePsmfGetAudioInfo(%08x, %08x)", psmfStruct, audioInfoAddr); if (Memory::IsValidAddress(audioInfoAddr)) { Memory::Write_U32(psmf->audioChannels, audioInfoAddr); Memory::Write_U32(psmf->audioFrequency, audioInfoAddr + 4); @@ -519,12 +519,12 @@ u32 scePsmfGetAudioInfo(u32 psmfStruct, u32 audioInfoAddr) { } u32 scePsmfGetCurrentStreamType(u32 psmfStruct, u32 typeAddr, u32 channelAddr) { - INFO_LOG(HLE, "scePsmfGetCurrentStreamType(%08x, %08x, %08x)", psmfStruct, typeAddr, channelAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetCurrentStreamType - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetCurrentStreamType(%08x, %08x, %08x): invalid psmf", psmfStruct, typeAddr, channelAddr); return ERROR_PSMF_NOT_FOUND; } + INFO_LOG(HLE, "scePsmfGetCurrentStreamType(%08x, %08x, %08x)", psmfStruct, typeAddr, channelAddr); if (Memory::IsValidAddress(typeAddr)) { u32 type = 0, channel = 0; if (psmf->streamMap.find(psmf->currentStreamNum) != psmf->streamMap.end()) @@ -539,12 +539,12 @@ u32 scePsmfGetCurrentStreamType(u32 psmfStruct, u32 typeAddr, u32 channelAddr) { u32 scePsmfGetStreamSize(u32 psmfStruct, u32 sizeAddr) { - DEBUG_LOG(HLE, "scePsmfGetStreamSize(%08x, %08x)", psmfStruct, sizeAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetStreamSize - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetStreamSize(%08x, %08x): invalid psmf", psmfStruct, sizeAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetStreamSize(%08x, %08x)", psmfStruct, sizeAddr); if (Memory::IsValidAddress(sizeAddr)) { Memory::Write_U32(psmf->streamSize, sizeAddr); } @@ -553,7 +553,7 @@ u32 scePsmfGetStreamSize(u32 psmfStruct, u32 sizeAddr) u32 scePsmfQueryStreamOffset(u32 bufferAddr, u32 offsetAddr) { - ERROR_LOG(HLE, "UNIMPL scePsmfQueryStreamOffset(%08x, %08x)", bufferAddr, offsetAddr); + WARN_LOG(HLE, "scePsmfQueryStreamOffset(%08x, %08x)", bufferAddr, offsetAddr); if (Memory::IsValidAddress(offsetAddr)) { Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr); } @@ -562,7 +562,7 @@ u32 scePsmfQueryStreamOffset(u32 bufferAddr, u32 offsetAddr) u32 scePsmfQueryStreamSize(u32 bufferAddr, u32 sizeAddr) { - ERROR_LOG(HLE, "UNIMPL scePsmfQueryStreamSize(%08x, %08x)", bufferAddr, sizeAddr); + WARN_LOG(HLE, "scePsmfQueryStreamSize(%08x, %08x)", bufferAddr, sizeAddr); if (Memory::IsValidAddress(sizeAddr)) { Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr); } @@ -571,12 +571,12 @@ u32 scePsmfQueryStreamSize(u32 bufferAddr, u32 sizeAddr) u32 scePsmfGetHeaderSize(u32 psmfStruct, u32 sizeAddr) { - DEBUG_LOG(HLE, "scePsmfGetHeaderSize(%08x, %08x)", psmfStruct, sizeAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetHeaderSize - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetHeaderSize(%08x, %08x): invalid psmf", psmfStruct, sizeAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetHeaderSize(%08x, %08x)", psmfStruct, sizeAddr); if (Memory::IsValidAddress(sizeAddr)) { Memory::Write_U32(psmf->headerSize, sizeAddr); } @@ -585,50 +585,50 @@ u32 scePsmfGetHeaderSize(u32 psmfStruct, u32 sizeAddr) u32 scePsmfGetPsmfVersion(u32 psmfStruct) { - DEBUG_LOG(HLE, "scePsmfGetPsmfVersion(%08x)", psmfStruct); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetHeaderSize - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetHeaderSize(%08x): invalid psmf", psmfStruct); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetPsmfVersion(%08x)", psmfStruct); return psmf->version; } u32 scePsmfVerifyPsmf(u32 psmfAddr) { - DEBUG_LOG(HLE, "scePsmfVerifyPsmf(%08x)", psmfAddr); int magic = Memory::Read_U32(psmfAddr); if (magic != PSMF_MAGIC) { - ERROR_LOG(HLE, "scePsmfVerifyPsmf - bad magic"); + ERROR_LOG(HLE, "scePsmfVerifyPsmf(%08x): bad magic %08x", psmfAddr, magic); return ERROR_PSMF_NOT_FOUND; } int version = Memory::Read_U32(psmfAddr + PSMF_STREAM_VERSION_OFFSET); if (version < 0) { - ERROR_LOG(HLE, "scePsmfVerifyPsmf - bad version"); + ERROR_LOG(HLE, "scePsmfVerifyPsmf(%08x): bad version %08x", psmfAddr, version); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfVerifyPsmf(%08x)", psmfAddr); return 0; } u32 scePsmfGetNumberOfEPentries(u32 psmfStruct) { - DEBUG_LOG(HLE, "scePsmfGetNumberOfEPentries(%08x)", psmfStruct); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetNumberOfEPentries - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetNumberOfEPentries(%08x): invalid psmf", psmfStruct); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetNumberOfEPentries(%08x)", psmfStruct); return psmf->EPMapEntriesNum; } u32 scePsmfGetPresentationStartTime(u32 psmfStruct, u32 startTimeAddr) { - DEBUG_LOG(HLE, "scePsmfGetPresentationStartTime(%08x, %08x)", psmfStruct, startTimeAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetPresentationStartTime - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetPresentationStartTime(%08x, %08x): invalid psmf", psmfStruct, startTimeAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetPresentationStartTime(%08x, %08x)", psmfStruct, startTimeAddr); if (Memory::IsValidAddress(startTimeAddr)) { Memory::Write_U32(psmf->presentationStartTime, startTimeAddr); } @@ -637,12 +637,12 @@ u32 scePsmfGetPresentationStartTime(u32 psmfStruct, u32 startTimeAddr) u32 scePsmfGetPresentationEndTime(u32 psmfStruct, u32 endTimeAddr) { - DEBUG_LOG(HLE, "scePsmfGetPresentationEndTime(%08x, %08x)", psmfStruct, endTimeAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetPresentationEndTime - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetPresentationEndTime(%08x, %08x): invalid psmf", psmfStruct, endTimeAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetPresentationEndTime(%08x, %08x)", psmfStruct, endTimeAddr); if (Memory::IsValidAddress(endTimeAddr)) { Memory::Write_U32(psmf->presentationEndTime, endTimeAddr); } @@ -651,24 +651,24 @@ u32 scePsmfGetPresentationEndTime(u32 psmfStruct, u32 endTimeAddr) u32 scePsmfGetCurrentStreamNumber(u32 psmfStruct) { - DEBUG_LOG(HLE, "scePsmfGetCurrentStreamNumber(%08x)", psmfStruct); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetCurrentStreamNumber - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetCurrentStreamNumber(%08x): invalid psmf", psmfStruct); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetCurrentStreamNumber(%08x)", psmfStruct); return psmf->currentStreamNum; } u32 scePsmfGetEPWithId(u32 psmfStruct, int id, u32 outAddr) { - DEBUG_LOG(HLE, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, id, outAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetEPWithId - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetEPWithId(%08x, %i, %08x): invalid psmf", psmfStruct, id, outAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, id, outAddr); if (Memory::IsValidAddress(outAddr)) { Memory::Write_U32(psmf->psmfEntry.EPPts, outAddr); Memory::Write_U32(psmf->psmfEntry.EPOffset, outAddr + 4); @@ -680,12 +680,12 @@ u32 scePsmfGetEPWithId(u32 psmfStruct, int id, u32 outAddr) u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr) { - DEBUG_LOG(HLE, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetEPWithTimestamp - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetEPWithTimestamp(%08x, %i, %08x): invalid psmf", psmfStruct, ts, entryAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr); if (ts < psmf->presentationStartTime) { return ERROR_PSMF_INVALID_TIMESTAMP; } @@ -700,12 +700,12 @@ u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr) u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts) { - DEBUG_LOG(HLE, "scePsmfGetEPidWithTimestamp(%08x, %i)", psmfStruct, ts); Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(HLE, "scePsmfGetEPidWithTimestamp - invalid psmf"); + ERROR_LOG(HLE, "scePsmfGetEPidWithTimestamp(%08x, %i): invalid psmf", psmfStruct, ts); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfGetEPidWithTimestamp(%08x, %i)", psmfStruct, ts); if (ts < psmf->presentationStartTime) { return ERROR_PSMF_INVALID_TIMESTAMP; } From e36da8b49f4092d83f9ef114cfe1d4e7e7f65375 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 13 Jun 2013 22:33:59 -0700 Subject: [PATCH 04/51] Clean up scePsmfPlayer logging. Move a bunch of things from errors. --- Core/HLE/scePsmf.cpp | 88 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 0b4f2b6bd3..4ace5056dd 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -715,7 +715,7 @@ u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts) int scePsmfPlayerCreate(u32 psmfPlayer, u32 psmfPlayerDataAddr) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, psmfPlayerDataAddr); + WARN_LOG(HLE, "scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, psmfPlayerDataAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { // TODO: This is the wrong data. PsmfPlayer needs a new interface. @@ -736,7 +736,7 @@ int scePsmfPlayerCreate(u32 psmfPlayer, u32 psmfPlayerDataAddr) int scePsmfPlayerStop(u32 psmfPlayer) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerStop(%08x)", psmfPlayer); + INFO_LOG(HLE, "scePsmfPlayerStop(%08x)", psmfPlayer); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY; @@ -754,18 +754,17 @@ int scePsmfPlayerBreak(u32 psmfPlayer) int scePsmfPlayerSetPsmf(u32 psmfPlayer, const char *filename) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerSetPsmf(%08x, %s)", psmfPlayer, filename); - PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) { + INFO_LOG(HLE, "scePsmfPlayerSetPsmf(%08x, %s)", psmfPlayer, filename); psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY; psmfplayer->mediaengine->loadFile(filename); psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); } else { - ERROR_LOG(HLE, "psmfplayer null in scePsmfPlayerSetPsmf"); + INFO_LOG(HLE, "scePsmfPlayerSetPsmf(%08x, %s): invalid psmf player", psmfPlayer, filename); } return 0; @@ -773,18 +772,18 @@ int scePsmfPlayerSetPsmf(u32 psmfPlayer, const char *filename) int scePsmfPlayerSetPsmfCB(u32 psmfPlayer, const char *filename) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerSetPsmfCB(%08x, %s)", psmfPlayer, filename); - + // TODO: hleCheckCurrentCallbacks? PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) { + INFO_LOG(HLE, "scePsmfPlayerSetPsmfCB(%08x, %s)", psmfPlayer, filename); psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY; psmfplayer->mediaengine->loadFile(filename); psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); } else { - ERROR_LOG(HLE, "psmfplayer null in scePsmfPlayerSetPsmfCB"); + INFO_LOG(HLE, "scePsmfPlayerSetPsmfCB(%08x, %s): invalid psmf player", psmfPlayer, filename); } return 0; @@ -792,13 +791,13 @@ int scePsmfPlayerSetPsmfCB(u32 psmfPlayer, const char *filename) int scePsmfPlayerGetAudioOutSize(u32 psmfPlayer) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerGetAudioOutSize(%08x)", psmfPlayer); + WARN_LOG(HLE, "scePsmfPlayerGetAudioOutSize(%08x)", psmfPlayer); return audioSamplesBytes; } int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerStart(%08x, %08x, %08x)", psmfPlayer, psmfPlayerData, initPts); + WARN_LOG(HLE, "UNIMPL scePsmfPlayerStart(%08x, %08x, %08x)", psmfPlayer, psmfPlayerData, initPts); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { @@ -838,28 +837,29 @@ int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts) int scePsmfPlayerDelete(u32 psmfPlayer) { - ERROR_LOG(HLE, "UNIMPL scePsmfPlayerDelete(%08x)", psmfPlayer); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) { - psmfplayer->status = PSMF_PLAYER_STATUS_NONE; + INFO_LOG(HLE, "scePsmfPlayerDelete(%08x)", psmfPlayer); delete psmfplayer; psmfPlayerMap.erase(psmfPlayer); + } else { + ERROR_LOG(HLE, "scePsmfPlayerDelete(%08x): invalid psmf player", psmfPlayer); } return 0; } int scePsmfPlayerUpdate(u32 psmfPlayer) { - DEBUG_LOG(HLE, "scePsmfPlayerUpdate(%08x)", psmfPlayer); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerUpdate - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerUpdate(%08x): invalid psmf player", psmfPlayer); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfPlayerUpdate(%08x)", psmfPlayer); if (psmfplayer->psmfPlayerAvcAu.pts > 0) { if (psmfplayer->psmfPlayerAvcAu.pts >= psmfplayer->psmfPlayerLastTimestamp) { - INFO_LOG(HLE,"video end reach"); + INFO_LOG(HLE, "video end reached"); psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING_FINISHED; } } @@ -877,13 +877,13 @@ int scePsmfPlayerReleasePsmf(u32 psmfPlayer) int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr) { - DEBUG_LOG(HLE, "scePsmfPlayerGetVideoData(%08x, %08x)", psmfPlayer, videoDataAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetVideoData - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetVideoData(%08x, %08x): invalid psmf player", psmfPlayer, videoDataAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfPlayerGetVideoData(%08x, %08x)", psmfPlayer, videoDataAddr); if (Memory::IsValidAddress(videoDataAddr)) { int frameWidth = Memory::Read_U32(videoDataAddr); u32 displaybuf = Memory::Read_U32(videoDataAddr + 4); @@ -910,13 +910,13 @@ int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr) int scePsmfPlayerGetAudioData(u32 psmfPlayer, u32 audioDataAddr) { - DEBUG_LOG(HLE, "scePsmfPlayerGetAudioData(%08x, %08x)", psmfPlayer, audioDataAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetAudioData - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetAudioData(%08x, %08x): invalid psmf player", psmfPlayer, audioDataAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfPlayerGetAudioData(%08x, %08x)", psmfPlayer, audioDataAddr); if (Memory::IsValidAddress(audioDataAddr)) { Memory::Memset(audioDataAddr, 0, audioSamplesBytes); psmfplayer->mediaengine->getAudioSamples(Memory::GetPointer(audioDataAddr)); @@ -929,7 +929,7 @@ int scePsmfPlayerGetCurrentStatus(u32 psmfPlayer) { PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentStatus(%08x) - invalid psmf", psmfPlayer); + ERROR_LOG(HLE, "scePsmfPlayerGetCurrentStatus(%08x): invalid psmf player", psmfPlayer); return ERROR_PSMF_NOT_FOUND; } DEBUG_LOG(HLE, "%d=scePsmfPlayerGetCurrentStatus(%08x)", psmfplayer->status, psmfPlayer); @@ -938,18 +938,17 @@ int scePsmfPlayerGetCurrentStatus(u32 psmfPlayer) u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr) { - DEBUG_LOG(HLE, "scePsmfPlayerGetCurrentPts(%08x, %08x)", psmfPlayer , currentPtsAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentPts - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetCurrentPts(%08x, %08x): invalid psmf player", psmfPlayer, currentPtsAddr); return ERROR_PSMF_NOT_FOUND; } + DEBUG_LOG(HLE, "scePsmfPlayerGetCurrentPts(%08x, %08x)", psmfPlayer, currentPtsAddr); if (psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) { return ERROR_PSMFPLAYER_NOT_INITIALIZED; } if (Memory::IsValidAddress(currentPtsAddr)) { - //Comment out until psmfPlayerAvcAu.pts start increasing correctly, Ultimate Ghosts N Goblins relies on it . Memory::Write_U32(psmfplayer->psmfPlayerAvcAu.pts, currentPtsAddr); } return 0; @@ -957,16 +956,17 @@ u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr) u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr) { - ERROR_LOG(HLE, "scePsmfPlayerGetPsmfInfo(%08x, %08x)", psmfPlayer , psmfInfoAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetPsmfInfo - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetPsmfInfo(%08x, %08x): invalid psmf player", psmfPlayer, psmfInfoAddr); return ERROR_PSMF_NOT_FOUND; } if (psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) { + ERROR_LOG(HLE, "scePsmfPlayerGetPsmfInfo(%08x, %08x): not initialized", psmfPlayer, psmfInfoAddr); return ERROR_PSMFPLAYER_NOT_INITIALIZED; } + WARN_LOG(HLE, "scePsmfPlayerGetPsmfInfo(%08x, %08x)", psmfPlayer, psmfInfoAddr); if (Memory::IsValidAddress(psmfInfoAddr)) { Memory::Write_U32(psmfplayer->psmfPlayerLastTimestamp, psmfInfoAddr); Memory::Write_U32(psmfplayer->videoStreamNum, psmfInfoAddr + 4); @@ -981,12 +981,12 @@ u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr) u32 scePsmfPlayerGetCurrentPlayMode(u32 psmfPlayer, u32 playModeAddr, u32 playSpeedAddr) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentPlayMode(%08x, %08x, %08x)", psmfPlayer , playModeAddr, playSpeedAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentPlayMode - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetCurrentPlayMode(%08x, %08x, %08x): invalid psmf player", psmfPlayer, playModeAddr, playSpeedAddr); return ERROR_PSMF_NOT_FOUND; } + WARN_LOG(HLE, "scePsmfPlayerGetCurrentPlayMode(%08x, %08x, %08x)", psmfPlayer, playModeAddr, playSpeedAddr); if (Memory::IsValidAddress(playModeAddr)) { Memory::Write_U64(psmfplayer->playMode, playModeAddr); } @@ -998,12 +998,12 @@ u32 scePsmfPlayerGetCurrentPlayMode(u32 psmfPlayer, u32 playModeAddr, u32 playSp u32 scePsmfPlayerGetCurrentVideoStream(u32 psmfPlayer, u32 videoCodecAddr, u32 videoStreamNumAddr) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentVideoStream(%08x, %08x, %08x)", psmfPlayer , videoCodecAddr, videoStreamNumAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentVideoStream - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetCurrentVideoStream(%08x, %08x, %08x): invalid psmf player", psmfPlayer, videoCodecAddr, videoStreamNumAddr); return ERROR_PSMF_NOT_FOUND; } + WARN_LOG(HLE, "scePsmfPlayerGetCurrentVideoStream(%08x, %08x, %08x)", psmfPlayer, videoCodecAddr, videoStreamNumAddr); if (Memory::IsValidAddress(videoCodecAddr)) { Memory::Write_U64(psmfplayer->videoCodec, videoCodecAddr); } @@ -1015,12 +1015,12 @@ u32 scePsmfPlayerGetCurrentVideoStream(u32 psmfPlayer, u32 videoCodecAddr, u32 v u32 scePsmfPlayerGetCurrentAudioStream(u32 psmfPlayer, u32 audioCodecAddr, u32 audioStreamNumAddr) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x)", psmfPlayer , audioCodecAddr, audioStreamNumAddr); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerGetCurrentAudioStream - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x): invalid psmf player", psmfPlayer, audioCodecAddr, audioStreamNumAddr); return ERROR_PSMF_NOT_FOUND; } + WARN_LOG(HLE, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x)", psmfPlayer, audioCodecAddr, audioStreamNumAddr); if (Memory::IsValidAddress(audioCodecAddr)) { Memory::Write_U64(psmfplayer->audioCodec, audioCodecAddr); } @@ -1041,13 +1041,13 @@ int scePsmfPlayerSetTempBuf(u32 psmfPlayer, u32 tempBufAddr, u32 tempBufSize) u32 scePsmfPlayerChangePlayMode(u32 psmfPlayer, int playMode, int playSpeed) { - ERROR_LOG(HLE, "scePsmfPlayerChangePlayMode(%08x, %i, %i)", psmfPlayer , playMode, playSpeed); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerChangePlayMode - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerChangePlayMode(%08x, %i, %i): invalid psmf player", psmfPlayer, playMode, playSpeed); return ERROR_PSMF_NOT_FOUND; } + WARN_LOG(HLE, "scePsmfPlayerChangePlayMode(%08x, %i, %i)", psmfPlayer, playMode, playSpeed); psmfplayer->playMode = playMode; psmfplayer->playSpeed = playSpeed; return 0; @@ -1055,37 +1055,37 @@ u32 scePsmfPlayerChangePlayMode(u32 psmfPlayer, int playMode, int playSpeed) u32 scePsmfPlayerSelectAudio(u32 psmfPlayer) { - ERROR_LOG(HLE, "scePsmfPlayerSelectAudio(%08x)", psmfPlayer); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerChangePlayMode - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerSelectAudio(%08x): invalid psmf player", psmfPlayer); return ERROR_PSMF_NOT_FOUND; } + ERROR_LOG(HLE, "scePsmfPlayerSelectAudio(%08x)", psmfPlayer); psmfplayer->audioStreamNum++; return 0; } u32 scePsmfPlayerSelectVideo(u32 psmfPlayer) { - ERROR_LOG(HLE, "scePsmfPlayerSelectVideo(%08x)", psmfPlayer); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerSelectVideo - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerSelectVideo(%08x): invalid psmf player", psmfPlayer); return ERROR_PSMF_NOT_FOUND; } + ERROR_LOG(HLE, "scePsmfPlayerSelectVideo(%08x)", psmfPlayer); psmfplayer->videoStreamNum++; return 0; } u32 scePsmfPlayerSelectSpecificVideo(u32 psmfPlayer, int videoCodec, int videoStreamNum) { - ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i)", psmfPlayer , videoCodec, videoStreamNum); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificVideo - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): invalid psmf player", psmfPlayer, videoCodec, videoStreamNum); return ERROR_PSMF_NOT_FOUND; } + ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i)", psmfPlayer, videoCodec, videoStreamNum); psmfplayer->videoCodec = videoCodec; psmfplayer->videoStreamNum = videoStreamNum; psmfplayer->mediaengine->setVideoStream(videoStreamNum); @@ -1094,13 +1094,13 @@ u32 scePsmfPlayerSelectSpecificVideo(u32 psmfPlayer, int videoCodec, int videoSt u32 scePsmfPlayerSelectSpecificAudio(u32 psmfPlayer, int audioCodec, int audioStreamNum) { - ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i)", psmfPlayer , audioCodec, audioStreamNum); PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificAudio - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): invalid psmf player", psmfPlayer, audioCodec, audioStreamNum); return ERROR_PSMF_NOT_FOUND; } + ERROR_LOG(HLE, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i)", psmfPlayer, audioCodec, audioStreamNum); psmfplayer->audioCodec = audioCodec; psmfplayer->audioStreamNum = audioStreamNum; psmfplayer->mediaengine->setAudioStream(audioStreamNum); @@ -1111,18 +1111,20 @@ u32 scePsmfPlayerConfigPlayer(u32 psmfPlayer, int configMode, int configAttr) { PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (!psmfplayer) { - ERROR_LOG(HLE, "scePsmfPlayerConfigPlayer - invalid psmf"); + ERROR_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, %i, %i): invalid psmf player", psmfPlayer, configMode, configAttr); return ERROR_PSMF_NOT_FOUND; } if (configMode == PSMF_PLAYER_CONFIG_MODE_LOOP) { + INFO_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, loop, %i)", psmfPlayer, configAttr); videoLoopStatus = configAttr; } else if (configMode == PSMF_PLAYER_CONFIG_MODE_PIXEL_TYPE) { + INFO_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, pixelType, %i)", psmfPlayer, configAttr); // Does -1 mean default or something? if (configAttr != -1) { videoPixelMode = configAttr; } } else { - ERROR_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, %i, %i): unknown parameter", psmfPlayer, configMode, configAttr); + ERROR_LOG_REPORT(HLE, "scePsmfPlayerConfigPlayer(%08x, %i, %i): unknown parameter", psmfPlayer, configMode, configAttr); } return 0; From ff00b65cf3a568af113c9fe17ce2a83001465255 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 13 Jun 2013 23:04:11 -0700 Subject: [PATCH 05/51] Re-enable subimage optimization with scaling fix. Thanks go to @Squall-Leonhart for finding the issue. --- GPU/GLES/TextureCache.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index e7fe804f83..992a0bb9dd 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -1030,20 +1030,17 @@ void TextureCache::SetTexture() { entry->numInvalidated++; gpuStats.numTextureInvalidations++; INFO_LOG(G3D, "Texture different or overwritten, reloading at %08x", texaddr); - if (entry->texture == lastBoundTexture) { - lastBoundTexture = -1; - } if (doDelete) { - // TODO: This stuff is missing some check, its causes corruption. See issue #2222 . - /* - if (entry->maxLevel == maxLevel && entry->dim == (gstate.texsize[0] & 0xF0F)) { + if (entry->maxLevel == maxLevel && entry->dim == (gstate.texsize[0] & 0xF0F) && entry->format == format) { // Actually, if size and number of levels match, let's try to avoid deleting and recreating. // Instead, let's use glTexSubImage to replace the images. - replaceImages = true; + replaceImages = g_Config.iTexScalingLevel <= 1; } else { + if (entry->texture == lastBoundTexture) { + lastBoundTexture = -1; + } glDeleteTextures(1, &entry->texture); - }*/ - glDeleteTextures(1, &entry->texture); + } } if (entry->status == TexCacheEntry::STATUS_RELIABLE) { entry->status = TexCacheEntry::STATUS_HASHING; From 9e0fe6f1e657f18ec56445a7dbacc65c133141b0 Mon Sep 17 00:00:00 2001 From: HuangKangJing Date: Fri, 14 Jun 2013 14:24:04 +0800 Subject: [PATCH 06/51] Fixed a build error on 64-bit linux. --- GPU/GLES/TransformPipeline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index cdec86b448..9c20120ef2 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -1047,9 +1047,9 @@ u32 TransformDrawEngine::ComputeHash() { u32 TransformDrawEngine::ComputeFastDCID() { u32 hash = 0; for (int i = 0; i < numDrawCalls; i++) { - hash ^= (u32)drawCalls[i].verts; + hash ^= (u32)(uintptr_t)drawCalls[i].verts; hash = __rotl(hash, 13); - hash ^= (u32)drawCalls[i].inds; + hash ^= (u32)(uintptr_t)drawCalls[i].inds; hash = __rotl(hash, 13); hash ^= (u32)drawCalls[i].vertType; hash = __rotl(hash, 13); From 9ac2b605d5237e5ccd63fb350319118b7e477498 Mon Sep 17 00:00:00 2001 From: HuangKangJing Date: Fri, 14 Jun 2013 15:04:37 +0800 Subject: [PATCH 07/51] Fixed a build error of qt interface on Linux --- Qt/PPSSPP.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Qt/PPSSPP.pro b/Qt/PPSSPP.pro index 7161d85b9c..384b1f5896 100755 --- a/Qt/PPSSPP.pro +++ b/Qt/PPSSPP.pro @@ -22,7 +22,7 @@ win32 { LIBS += -lCore -lCommon -lNative -lwinmm -lws2_32 } linux { - LIBS += -L. -lCore -lCommon -lNative + LIBS += -L. -lCore -lCommon -lNative -ldl PRE_TARGETDEPS += ./libCommon.a ./libCore.a ./libNative.a !mobile_platform { CONFIG += link_pkgconfig From 7f6b20021b1903f1a05c1259271e88988ec66cba Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 14 Jun 2013 09:09:08 +0200 Subject: [PATCH 08/51] Update ffmpeg, should fix #2253 (at least the reference is not a tree error) --- ffmpeg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg b/ffmpeg index 697244c4b7..5f420cb666 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 697244c4b79b396de86e5d7fdbf9bc4771b815e9 +Subproject commit 5f420cb6667430edaaef2d97bb85b170db67c45d From a2853d4986bafce61d919cc958833dcd3d533942 Mon Sep 17 00:00:00 2001 From: The Dax Date: Fri, 14 Jun 2013 03:45:03 -0400 Subject: [PATCH 09/51] Changed my previous implementation to an ifdef at Henrik's request. Disable touch controls for "desktop" platforms(Windows/Linux/mac). The intention was to disable the invisible controls, but this commit will break the touch controls completely, even if visible. Platforms such as Android/Meego shouldn't be affected. --- UI/EmuScreen.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7e087d630e..6eb0176896 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -178,10 +178,13 @@ void EmuScreen::update(InputState &input) { // First translate touches into native pad input. // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... + // Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux... + // NOTE: Breaks both hidden and visible touch controls on Win/Lin/Mac by doing this! +#if !defined( _WIN32) && !defined(__APPLE__) && !defined(__linux__) UpdateGamepad(input); UpdateInputState(&input); - +#endif // Then translate pad input into PSP pad input. Also, add in tilt. static const int mapping[12][2] = { {PAD_BUTTON_A, CTRL_CROSS}, From dc5e7d5e71fbbc67d0ace8a1d6740c731dba8507 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 00:46:49 -0700 Subject: [PATCH 10/51] Still need to delete textures when scaling on. Duh. Fixes #2255. --- GPU/GLES/TextureCache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 992a0bb9dd..180c2530bc 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -1031,10 +1031,10 @@ void TextureCache::SetTexture() { gpuStats.numTextureInvalidations++; INFO_LOG(G3D, "Texture different or overwritten, reloading at %08x", texaddr); if (doDelete) { - if (entry->maxLevel == maxLevel && entry->dim == (gstate.texsize[0] & 0xF0F) && entry->format == format) { + if (entry->maxLevel == maxLevel && entry->dim == (gstate.texsize[0] & 0xF0F) && entry->format == format && g_Config.iTexScalingLevel <= 1) { // Actually, if size and number of levels match, let's try to avoid deleting and recreating. // Instead, let's use glTexSubImage to replace the images. - replaceImages = g_Config.iTexScalingLevel <= 1; + replaceImages = true; } else { if (entry->texture == lastBoundTexture) { lastBoundTexture = -1; From 6192feb27ac6a63b981393ec67e611960ce96247 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 00:42:27 -0700 Subject: [PATCH 11/51] Don't return less than ffmpeg wants 'til the end. Fixes #2223 (at least for the games I have.) --- Core/HW/MediaEngine.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index ae0f2c021b..a296bb6202 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -138,7 +138,15 @@ int _MpegReadbuffer(void *opaque, uint8_t *buf, int buf_size) { MediaEngine *mpeg = (MediaEngine*)opaque; int size = std::min(mpeg->m_bufSize, buf_size); - size = std::max(std::min((mpeg->m_readSize - mpeg->m_decodeNextPos), size), 0); + int available = mpeg->m_readSize - mpeg->m_decodeNextPos; + int remaining = mpeg->m_streamSize - mpeg->m_decodeNextPos; + + // There's more in the file, and there's not as much as requested available. + // Return nothing. Partial packets will cause artifacts or green frames. + if (available < remaining && size > available) + return 0; + + size = std::min(size, remaining); if (size > 0) memcpy(buf, mpeg->m_pdata + mpeg->m_decodeNextPos, size); mpeg->m_decodeNextPos += size; From 23cefa03c6c21d20d8f54059fea4ea0334af93fa Mon Sep 17 00:00:00 2001 From: oioitff Date: Fri, 14 Jun 2013 01:16:59 -0700 Subject: [PATCH 12/51] Delay video decode until we have enough packets. --- Core/HW/MediaEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index a296bb6202..f0cc59bbcb 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -291,7 +291,7 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) { if (size > 0 && m_pdata) { memcpy(m_pdata + m_readSize, buffer, size); m_readSize += size; - if (!m_pFormatCtx && m_readSize > 0x2000) + if (!m_pFormatCtx && (m_readSize > 0x20000 || m_readSize >= m_streamSize)) openContext(); if (m_demux) { m_demux->setReadSize(m_readSize); From 4ba1373985db75b7de369e556ee02beb5b3caeea Mon Sep 17 00:00:00 2001 From: The Dax Date: Fri, 14 Jun 2013 13:07:13 -0400 Subject: [PATCH 13/51] Fix ifdefs not to break iOS. --- UI/EmuScreen.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 6eb0176896..57cbe66e3c 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -179,12 +179,16 @@ void EmuScreen::update(InputState &input) { // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... // Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux... - // NOTE: Breaks both hidden and visible touch controls on Win/Lin/Mac by doing this! -#if !defined( _WIN32) && !defined(__APPLE__) && !defined(__linux__) - UpdateGamepad(input); - - UpdateInputState(&input); + // TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms? +#ifdef _WIN32 + if(g_Config.bShowTouchControls) { +#else + if(true) { #endif + UpdateGamepad(input); + + UpdateInputState(&input); + } // Then translate pad input into PSP pad input. Also, add in tilt. static const int mapping[12][2] = { {PAD_BUTTON_A, CTRL_CROSS}, From c8917bfbaf1bef9e2a442e0c4b36e1a710343b75 Mon Sep 17 00:00:00 2001 From: The Dax Date: Fri, 14 Jun 2013 13:11:35 -0400 Subject: [PATCH 14/51] No need to have an if true there. --- UI/EmuScreen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 57cbe66e3c..95935d1242 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -182,13 +182,14 @@ void EmuScreen::update(InputState &input) { // TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms? #ifdef _WIN32 if(g_Config.bShowTouchControls) { -#else - if(true) { #endif UpdateGamepad(input); UpdateInputState(&input); +#ifdef _WIN32 } +#endif + // Then translate pad input into PSP pad input. Also, add in tilt. static const int mapping[12][2] = { {PAD_BUTTON_A, CTRL_CROSS}, From 94bc8d0cd6936885a067088021cd8a6177ce4be8 Mon Sep 17 00:00:00 2001 From: oioitff Date: Sat, 15 Jun 2013 01:39:56 +0800 Subject: [PATCH 15/51] Implement scePsmfGetNumberOfSpecificStreams. --- Core/HLE/scePsmf.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 4ace5056dd..b93285851b 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -451,7 +451,12 @@ u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, u32 streamType) return ERROR_PSMF_NOT_FOUND; } WARN_LOG(HLE, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType); - return 1; + int streamNum = 0; + for (int i = psmf->streamMap.size() - 1; i >= 0; i--) { + if (psmf->streamMap[i]->type == streamType) + streamNum++; + } + return streamNum; } u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 channel) From f2af925015328ecdd6b079134797ebd799645fea Mon Sep 17 00:00:00 2001 From: oioitff Date: Sat, 15 Jun 2013 01:42:19 +0800 Subject: [PATCH 16/51] fix wrong video/audio stream channel. --- Core/HLE/scePsmf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index b93285851b..21c85a2e74 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -246,11 +246,11 @@ Psmf::Psmf(u32 data) { u32 currentStreamAddr = data + 0x82 + i * 16; int streamId = Memory::Read_U8(currentStreamAddr); if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) { - stream = new PsmfStream(PSMF_AVC_STREAM, 0); + stream = new PsmfStream(PSMF_AVC_STREAM, currentVideoStreamNum); stream->readMPEGVideoStreamParams(currentStreamAddr, this); currentVideoStreamNum++; } else if ((streamId & PSMF_AUDIO_STREAM_ID) == PSMF_AUDIO_STREAM_ID) { - stream = new PsmfStream(PSMF_ATRAC_STREAM, 1); + stream = new PsmfStream(PSMF_ATRAC_STREAM, currentAudioStreamNum); stream->readPrivateAudioStreamParams(currentStreamAddr, this); currentAudioStreamNum++; } From ce2c18d2fed4f8072260c74bf84609dbf29d0aaf Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 15 Jun 2013 00:19:48 +0200 Subject: [PATCH 17/51] Remove redundant vmov instructions (seen in wipeout) --- Core/MIPS/ARM/ArmCompVFPU.cpp | 5 +++++ Core/MIPS/ARM/ArmJit.h | 4 ++++ Core/MIPS/x86/CompVFPU.cpp | 5 +++++ Core/MIPS/x86/Jit.h | 3 +++ native | 2 +- 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 74cccb80b9..d61cb61298 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -516,6 +516,11 @@ namespace MIPSComp if (js.HasUnknownPrefix()) DISABLE; + // Pre-processing: Eliminate silly no-op VMOVs, common in Wipeout Pure + if (((op >> 16) & 0x1f) == 0 && _VS == _VD && js.HasNoPrefix()) { + return; + } + VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 54c89a9488..ec8d46796d 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -96,6 +96,10 @@ struct ArmJitState } return false; } + bool HasNoPrefix() const { + return (prefixDFlag & PREFIX_KNOWN) && (prefixSFlag & PREFIX_KNOWN) && (prefixTFlag & PREFIX_KNOWN) && (prefixS == 0xE4 && prefixT == 0xE4 && prefixD == 0); + } + void EatPrefix() { if ((prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4) { prefixSFlag = PREFIX_KNOWN_DIRTY; diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 24aa220e57..4825bd980f 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -632,6 +632,11 @@ void Jit::Comp_VV2Op(u32 op) { if (js.HasUnknownPrefix()) DISABLE; + // Pre-processing: Eliminate silly no-op VMOVs, common in Wipeout Pure + if (((op >> 16) & 0x1f) == 0 && _VS == _VD && js.HasNoPrefix()) { + return; + } + VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 0182705ee1..42deb55b7b 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -111,6 +111,9 @@ struct JitState } return false; } + bool HasNoPrefix() const { + return (prefixDFlag & PREFIX_KNOWN) && (prefixSFlag & PREFIX_KNOWN) && (prefixTFlag & PREFIX_KNOWN) && (prefixS == 0xE4 && prefixT == 0xE4 && prefixD == 0); + } void EatPrefix() { if ((prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4) { prefixSFlag = PREFIX_KNOWN_DIRTY; diff --git a/native b/native index ce962bdf95..5e50ceca86 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit ce962bdf95717c52f29c211b6b242f899dcb9174 +Subproject commit 5e50ceca86e4f8b3580662a1a5619fb660c5e066 From 2ec8106809a59425df29ed85f825737e58a0a50d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 17:56:27 -0700 Subject: [PATCH 18/51] Ensure FFmpeg doesn't corrupt an early keyframe. When the analyze func runs, it seems to check between 2-4% (or so?) of the stream, which for longer videos especially we don't have yet. Returning a read failure here seems to truncate that keyframe sometimes. FFmpeg asks for the total size when this happens, which we were ignoring. Handling it fixes this, as FFmpeg apparently realizes we ran out of data. --- Core/HW/MediaEngine.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index f0cc59bbcb..18621c1963 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -166,6 +166,13 @@ int64_t _MpegSeekbuffer(void *opaque, int64_t offset, int whence) case SEEK_END: mpeg->m_decodeNextPos = mpeg->m_streamSize - (u32)offset; break; + +#ifdef USE_FFMPEG + // Don't seek, just return the full size. + // Returning this means FFmpeg won't think frames are truncated if we don't have them yet. + case AVSEEK_SIZE: + return mpeg->m_streamSize; +#endif } return offset; } From 2e2ec5bcea79b28a99b82b6182fa01a0386ed61a Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 11:30:01 +0800 Subject: [PATCH 19/51] Quick fix wrong sizing of CIRCEL --- Core/Util/ppge_atlas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Util/ppge_atlas.cpp b/Core/Util/ppge_atlas.cpp index 9909e919c9..3cb9ebb50d 100644 --- a/Core/Util/ppge_atlas.cpp +++ b/Core/Util/ppge_atlas.cpp @@ -34633,7 +34633,7 @@ const AtlasFont *ppge_fonts[1] = { }; const AtlasImage ppge_images[4] = { {0.033447f, 0.000244f, 0.048096f, 0.014893f, 31, 31, "I_CROSS"}, - {0.000244f, 0.000244f, 0.015381f, 0.015381f, 32, 32, "I_CIRCLE"}, + {0.000244f, 0.000244f, 0.015881f, 0.015881f, 32, 32, "I_CIRCLE"}, {0.066162f, 0.000244f, 0.079834f, 0.013916f, 29, 29, "I_SQUARE"}, {0.016357f, 0.000244f, 0.032471f, 0.013916f, 34, 29, "I_TRIANGLE"}, }; From c96bf8d375922baa96ce7accac447f842d0a1b0c Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 12:38:22 +0800 Subject: [PATCH 20/51] Swap the position of next and prev button for better navigation --- UI/MenuScreens.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 95247b7e5e..03914bc49a 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -726,12 +726,12 @@ void GraphicsScreenP1::render() { } HLinear hlinear(10, dp_yres - 10, 20.0f); - if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { - screenManager()->switchScreen(new GraphicsScreenP3()); - } if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { screenManager()->switchScreen(new GraphicsScreenP2()); } + if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { + screenManager()->switchScreen(new GraphicsScreenP3()); + } int x = 30; int y = 35; @@ -778,12 +778,12 @@ void GraphicsScreenP2::render() { } HLinear hlinear(10, dp_yres - 10, 20.0f); - if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { - screenManager()->switchScreen(new GraphicsScreenP1()); - } if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { screenManager()->switchScreen(new GraphicsScreenP3()); } + if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { + screenManager()->switchScreen(new GraphicsScreenP1()); + } int x = 30; int y = 35; From bb5fce600e1ac0afe41009ec37a3ec98e30835be Mon Sep 17 00:00:00 2001 From: aquanull Date: Sat, 8 Jun 2013 08:32:07 +0800 Subject: [PATCH 21/51] Fix/prevent crashes when MainWindow is closed before LoadFile() completes, or when it gets certain messages before TheThread completes initialization. Fix missing ppsspp.ini loading log (only 1 unimportant line though). Fix loading ui_atlas.zim failure when [General]Browse = True is set in ppsspp.ini. Some other minor fixes as well. --- Common/ConsoleListener.cpp | 6 +-- Common/ConsoleListener.h | 2 +- Core/Core.cpp | 7 ++- Core/Core.h | 1 + Core/System.cpp | 3 +- Windows/DSoundStream.cpp | 5 +- Windows/Debugger/Debugger_Disasm.cpp | 2 +- Windows/EmuThread.cpp | 79 +++++++++++++++++++++++++--- Windows/EmuThread.h | 20 ++++++- Windows/WndMainWindow.cpp | 49 +++++++++-------- Windows/main.cpp | 31 +++++------ 11 files changed, 144 insertions(+), 61 deletions(-) diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index 0dfcf3914f..e5d3ef9c4c 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -101,7 +101,7 @@ void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title if (hTriggerEvent != NULL && hThread == NULL) { logPending = new char[LOG_PENDING_MAX]; - hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &ConsoleListener::RunThread, this, 0, NULL); + hThread = (HANDLE)_beginthreadex(NULL, 0, &ConsoleListener::RunThread, this, 0, NULL); } #endif } @@ -246,9 +246,9 @@ COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) return Ret; } -DWORD WINAPI ConsoleListener::RunThread(LPVOID lpParam) +unsigned int WINAPI ConsoleListener::RunThread(void *lpParam) { - ConsoleListener *consoleLog = (ConsoleListener *) lpParam; + ConsoleListener *consoleLog = (ConsoleListener *)lpParam; consoleLog->LogWriterThread(); return 0; } diff --git a/Common/ConsoleListener.h b/Common/ConsoleListener.h index 42547c0a00..1eff61a358 100644 --- a/Common/ConsoleListener.h +++ b/Common/ConsoleListener.h @@ -50,7 +50,7 @@ private: HWND GetHwnd(void); HANDLE hConsole; - static DWORD WINAPI RunThread(LPVOID lpParam); + static unsigned int WINAPI RunThread(void *lpParam); void LogWriterThread(); void SendToThread(LogTypes::LOG_LEVELS Level, const char *Text); void WriteToConsole(LogTypes::LOG_LEVELS Level, const char *Text, size_t Len); diff --git a/Core/Core.cpp b/Core/Core.cpp index 951a0578fd..d1170cce73 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -70,6 +70,11 @@ bool Core_IsStepping() return coreState == CORE_STEPPING || coreState == CORE_POWERDOWN; } +bool Core_IsActive() +{ + return coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME || coreStatePending; +} + bool Core_IsInactive() { return coreState != CORE_RUNNING && coreState != CORE_NEXTFRAME && !coreStatePending; @@ -77,7 +82,7 @@ bool Core_IsInactive() void Core_WaitInactive() { - while (!Core_IsInactive()) + while (Core_IsActive()) m_hInactiveEvent.wait(m_hInactiveMutex); } diff --git a/Core/Core.h b/Core/Core.h index 2994ca55fe..b26103b740 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -33,6 +33,7 @@ void Core_Halt(const char *msg); bool Core_IsStepping(); +bool Core_IsActive(); bool Core_IsInactive(); void Core_WaitInactive(); void Core_WaitInactive(int milliseconds); diff --git a/Core/System.cpp b/Core/System.cpp index dbafe42f57..d4d4e22d87 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -97,7 +97,8 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) // TODO: Check Game INI here for settings, patches and cheats, and modify coreParameter accordingly std::string filename = coreParameter.fileToStart; - if (!LoadFile(filename, error_string)) { + if (!LoadFile(filename, error_string) || coreState == CORE_POWERDOWN) + { pspFileSystem.Shutdown(); CoreTiming::Shutdown(); __KernelShutdown(); diff --git a/Windows/DSoundStream.cpp b/Windows/DSoundStream.cpp index 88d2426c6f..45047172bf 100644 --- a/Windows/DSoundStream.cpp +++ b/Windows/DSoundStream.cpp @@ -110,7 +110,7 @@ namespace DSound int lastPos; short realtimeBuffer[BUFSIZE * 2]; - DWORD WINAPI soundThread(void *) + unsigned int WINAPI soundThread(void *) { currentPos = 0; lastPos = 0; @@ -175,8 +175,7 @@ namespace DSound memset(p1,0,num1); dsBuffer->Unlock(p1,num1,0,0); totalRenderedBytes = -bufferSize; - DWORD h; - hThread = CreateThread(0,0,soundThread,0,0,&h); + hThread = (HANDLE)_beginthreadex(0, 0, soundThread, 0, 0, 0); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); return true; } diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index e0d11a8939..135a6af73a 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -228,7 +228,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_MEMCHECK: { - bool isRunning = !Core_IsInactive(); + bool isRunning = Core_IsActive(); if (isRunning) { SetDebugMode(true); diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index cfea3c8269..76ba989006 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -7,6 +7,8 @@ #include "StringUtils.h" #include "../Globals.h" #include "EmuThread.h" +#include "WndMainWindow.h" +#include "resource.h" #include "../Core/Reporting.h" #include "../Core/MemMap.h" #include "../Core/Core.h" @@ -17,34 +19,79 @@ #include #include +#include +#pragma intrinsic(_InterlockedExchange) +class EmuThreadLockGuard +{ +public: + EmuThreadLockGuard() { emuThreadCS_.Enter(); } + ~EmuThreadLockGuard() { emuThreadCS_.Leave(); } +private: + static struct EmuThreadCS + { + EmuThreadCS() { InitializeCriticalSection(&TheCS_); } + ~EmuThreadCS() { DeleteCriticalSection(&TheCS_); } + void Enter() { EnterCriticalSection(&TheCS_); } + void Leave() { LeaveCriticalSection(&TheCS_); } + CRITICAL_SECTION TheCS_; + } emuThreadCS_; +}; + +EmuThreadLockGuard::EmuThreadCS EmuThreadLockGuard::emuThreadCS_; static HANDLE emuThread; +static long emuThreadReady; + +enum EmuTreadStatus : long +{ + THREAD_NONE = 0, + THREAD_INIT, + THREAD_CORE_LOOP, + THREAD_SHUTDOWN, + THREAD_END, +}; HANDLE EmuThread_GetThreadHandle() { + EmuThreadLockGuard lock; return emuThread; } -DWORD TheThread(LPVOID x); +unsigned int WINAPI TheThread(void *); void EmuThread_Start() { - unsigned int i; - emuThread = (HANDLE)_beginthreadex(0,0,(unsigned int (__stdcall *)(void *))TheThread,(LPVOID)0,0,&i); + EmuThreadLockGuard lock; + emuThread = (HANDLE)_beginthreadex(0, 0, &TheThread, 0, 0, 0); } void EmuThread_Stop() { // DSound_UpdateSound(); Core_Stop(); - if (WAIT_TIMEOUT == WaitForSingleObject(EmuThread_GetThreadHandle(),300)) + Core_WaitInactive(800); + if (WAIT_TIMEOUT == WaitForSingleObject(emuThread, 800)) { - //MessageBox(0,"Wait for emuthread timed out, please alert the developer to possible deadlock or infinite loop in emuthread :(.",0,0); + MessageBox(MainWindow::GetHWND(),"Wait for emuthread timed out! :(\n" + "please alert the developer to possible deadlock or infinite loop in emuthread!", 0, 0); + } + { + EmuThreadLockGuard lock; + CloseHandle(emuThread); + emuThread = 0; } host->UpdateUI(); } -DWORD TheThread(LPVOID x) { +bool EmuThread_Ready() +{ + return emuThreadReady == THREAD_CORE_LOOP; +} + +unsigned int WINAPI TheThread(void *) +{ + _InterlockedExchange(&emuThreadReady, THREAD_INIT); + setCurrentThreadName("EmuThread"); std::string memstick, flash0; @@ -75,20 +122,36 @@ DWORD TheThread(LPVOID x) { INFO_LOG(BOOT, "Done."); _dbg_update_(); + if (coreState == CORE_POWERDOWN) { + INFO_LOG(BOOT, "Exit before core loop."); + goto shutdown; + } + + _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP); + + if (g_Config.bBrowse) + { + PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); + //MainWindow::BrowseAndBoot(""); + } + Core_EnableStepping(FALSE); + Core_Run(); shutdown: + _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); + host = nativeHost; NativeShutdownGraphics(); NativeShutdown(); host = oldHost; - host->ShutdownGL(); + _InterlockedExchange(&emuThreadReady, THREAD_END); + //The CPU should return when a game is stopped and cleanup should be done here, //so we can restart the plugins (or load new ones) for the next game - _endthreadex(0); return 0; } diff --git a/Windows/EmuThread.h b/Windows/EmuThread.h index eedf558c40..ed1a9df08d 100644 --- a/Windows/EmuThread.h +++ b/Windows/EmuThread.h @@ -1,4 +1,22 @@ +// Copyright (c) 2013- 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 EmuThread_Start(); -void EmuThread_Stop(); \ No newline at end of file +void EmuThread_Stop(); +bool EmuThread_Ready(); diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index cedfca8d7d..7f9ec35605 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -214,18 +214,21 @@ namespace MainWindow if (zoom < 1) zoom = 1; if (zoom > 4) zoom = 4; - RECT rc,rcOrig; + RECT rc, rcOrig; GetWindowRectAtZoom(zoom, rcOrig, rc); u32 style = WS_OVERLAPPEDWINDOW; hwndMain = CreateWindowEx(0,szWindowClass, "", style, - rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInstance, NULL); - SetTimer(hwndMain, TIMER_CURSORUPDATE, CURSORUPDATE_INTERVAL_MS, 0); - SetPlaying(0); + rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); if (!hwndMain) return FALSE; + hwndDisplay = CreateWindowEx(0, szDisplayClass, TEXT(""), WS_CHILD | WS_VISIBLE, + rcOrig.left, rcOrig.top, rcOrig.right - rcOrig.left, rcOrig.bottom - rcOrig.top, hwndMain, 0, hInstance, 0); + if (!hwndDisplay) + return FALSE; + menu = GetMenu(hwndMain); #ifdef FINAL RemoveMenu(menu,2,MF_BYPOSITION); @@ -241,20 +244,22 @@ namespace MainWindow { SetMenuInfo(GetSubMenu(menu,i),&info); } + UpdateMenus(); - hwndDisplay = CreateWindowEx(0,szDisplayClass,TEXT(""), - WS_CHILD|WS_VISIBLE, - 0,0,/*rcOrig.left,rcOrig.top,*/rcOrig.right-rcOrig.left,rcOrig.bottom-rcOrig.top,hwndMain,0,hInstance,0); - - ShowWindow(hwndMain, nCmdShow); //accept dragged files DragAcceptFiles(hwndMain, TRUE); + SetTimer(hwndMain, TIMER_CURSORUPDATE, CURSORUPDATE_INTERVAL_MS, 0); + + Update(); + SetPlaying(0); + + ShowWindow(hwndMain, nCmdShow); + #if ENABLE_TOUCH RegisterTouchWindow(hwndDisplay, TWF_WANTPALM); #endif - SetFocus(hwndMain); SetFocus(hwndDisplay); return TRUE; @@ -429,6 +434,8 @@ namespace MainWindow case WM_COMMAND: { + if (!EmuThread_Ready()) + return DefWindowProc(hWnd, message, wParam, lParam); I18NCategory *g = GetI18NCategory("Graphics"); wmId = LOWORD(wParam); @@ -735,6 +742,9 @@ namespace MainWindow case WM_DROPFILES: { + if (!EmuThread_Ready()) + return DefWindowProc(hWnd, message, wParam, lParam); + HDROP hdrop = (HDROP)wParam; int count = DragQueryFile(hdrop,0xFFFFFFFF,0,0); if (count != 1) @@ -760,21 +770,14 @@ namespace MainWindow break; case WM_CLOSE: - Core_Stop(); - Core_WaitInactive(200); + /* + if (g_Config.bConfirmOnQuit && __KernelIsRunning()) + if (IDYES != MessageBox(hwndMain, "A game is in progress. Are you sure you want to exit?", + "Are you sure?", MB_YESNO | MB_ICONQUESTION)) + return 0; + //*/ EmuThread_Stop(); - /* - if (g_Config.bConfirmOnQuit && CCore::IsRunning()) - { - if (IDNO==MessageBox(hwndMain,"A game is in progress. Are you sure you want to exit?","Are you sure?",MB_YESNO|MB_ICONQUESTION)) - return 1;//or 1? - else - return DefWindowProc(hWnd,message,wParam,lParam); - break; - } - else - */ return DefWindowProc(hWnd,message,wParam,lParam); case WM_DESTROY: diff --git a/Windows/main.cpp b/Windows/main.cpp index 280520f9e4..719062c8f4 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -64,9 +64,11 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin hideLog = false; #endif + LogManager::Init(); + LogManager::GetInstance()->GetConsoleListener()->Open(hideLog, 150, 120, "PPSSPP Debug Console"); + LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); + g_Config.Load(); - VFSRegister("", new DirectoryAssetReader("assets/")); - VFSRegister("", new DirectoryAssetReader("")); // The rest is handled in NativeInit(). for (int i = 1; i < __argc; ++i) @@ -89,6 +91,9 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin } } + VFSRegister("", new DirectoryAssetReader("assets/")); + VFSRegister("", new DirectoryAssetReader("")); + //Windows, API init stuff INITCOMMONCONTROLSEX comm; comm.dwSize = sizeof(comm); @@ -97,15 +102,13 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin timeBeginPeriod(1); MainWindow::Init(_hInstance); - HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS); g_hPopupMenus = LoadMenu(_hInstance, (LPCSTR)IDR_POPUPMENUS); MainWindow::Show(_hInstance, iCmdShow); - host = new WindowsHost(MainWindow::GetHWND(), MainWindow::GetDisplayHWND()); HWND hwndMain = MainWindow::GetHWND(); - HMENU menu = GetMenu(hwndMain); - + HWND hwndDisplay = MainWindow::GetDisplayHWND(); + //initialize custom controls CtrlDisAsmView::init(); CtrlMemView::init(); @@ -114,25 +117,15 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin DialogManager::AddDlg(memoryWindow[0] = new CMemoryDlg(_hInstance, hwndMain, currentDebugMIPS)); DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS)); - MainWindow::Update(); - MainWindow::UpdateMenus(); - - LogManager::Init(); - LogManager::GetInstance()->GetConsoleListener()->Open(hideLog, 150, 120, "PPSSPP Debug Console"); - LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); + host = new WindowsHost(hwndMain, hwndDisplay); // Emu thread is always running! EmuThread_Start(); - if (g_Config.bBrowse) - MainWindow::BrowseAndBoot(""); - - if (!hideLog) - SetForegroundWindow(hwndMain); + HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS); //so.. we're at the message pump of the GUI thread - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) //while no quit + for (MSG msg; GetMessage(&msg, NULL, 0, 0); ) // for no quit { //DSound_UpdateSound(); From 5898b6872c8ecebac81e76fd987eeb34059d831a Mon Sep 17 00:00:00 2001 From: aquanull Date: Wed, 12 Jun 2013 02:14:53 +0800 Subject: [PATCH 22/51] Show the mouse cursor on full screen when it is moved or clicked. --- Windows/WndMainWindow.cpp | 42 +++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 7f9ec35605..e6a0055b7f 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -52,7 +52,9 @@ extern InputState input_state; extern const char * getVirtualKeyName(unsigned char key); extern const char * getXinputButtonName(unsigned int button); #define TIMER_CURSORUPDATE 1 +#define TIMER_CURSORMOVEUPDATE 2 #define CURSORUPDATE_INTERVAL_MS 50 +#define CURSORUPDATE_MOVE_TIMESPAN_MS 500 namespace MainWindow { @@ -63,6 +65,10 @@ namespace MainWindow static HINSTANCE hInst; static int cursorCounter = 0; + static int prevCursorX = -1; + static int prevCursorY = -1; + static bool mouseButtonDown = false; + static bool hideCursor = false; //W32Util::LayeredWindow *layer; #define MAX_LOADSTRING 100 @@ -179,11 +185,13 @@ namespace MainWindow } void CorrectCursor() { - if (g_bFullScreen && globalUIState == UISTATE_INGAME) { + bool autoHide = g_bFullScreen && !mouseButtonDown && globalUIState == UISTATE_INGAME; + if (autoHide && hideCursor) { while (cursorCounter >= 0) { cursorCounter = ShowCursor(FALSE); } } else { + hideCursor = !autoHide; if (cursorCounter < 0) { cursorCounter = ShowCursor(TRUE); SetCursor(LoadCursor(NULL, IDC_ARROW)); @@ -249,6 +257,7 @@ namespace MainWindow //accept dragged files DragAcceptFiles(hwndMain, TRUE); + hideCursor = true; SetTimer(hwndMain, TIMER_CURSORUPDATE, CURSORUPDATE_INTERVAL_MS, 0); Update(); @@ -309,6 +318,8 @@ namespace MainWindow // and as asynchronous touch events for minimal latency. case WM_LBUTTONDOWN: + // Hack: Take the opportunity to show the cursor. + mouseButtonDown = true; { lock_guard guard(input_state.lock); input_state.mouse_valid = true; @@ -329,6 +340,17 @@ namespace MainWindow case WM_MOUSEMOVE: { + // Hack: Take the opportunity to show the cursor. + mouseButtonDown = (wParam & MK_LBUTTON) != 0; + int cursorX = GET_X_LPARAM(lParam); + int cursorY = GET_Y_LPARAM(lParam); + if (abs(cursorX - prevCursorX) > 1 || abs(cursorY - prevCursorY) > 1) { + hideCursor = false; + SetTimer(hwndMain, TIMER_CURSORMOVEUPDATE, CURSORUPDATE_MOVE_TIMESPAN_MS, 0); + } + prevCursorX = cursorX; + prevCursorY = cursorY; + lock_guard guard(input_state.lock); int factor = g_Config.iWindowZoom == 1 ? 2 : 1; input_state.pointer_x[0] = GET_X_LPARAM(lParam) * factor; @@ -346,6 +368,8 @@ namespace MainWindow break; case WM_LBUTTONUP: + // Hack: Take the opportunity to hide the cursor. + mouseButtonDown = false; { lock_guard guard(input_state.lock); input_state.pointer_down[0] = false; @@ -428,9 +452,17 @@ namespace MainWindow case WM_TIMER: // Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode. - CorrectCursor(); - SetTimer(hWnd, TIMER_CURSORUPDATE, CURSORUPDATE_INTERVAL_MS, 0); - return 0; + switch (wParam) + { + case TIMER_CURSORUPDATE: + CorrectCursor(); + return 0; + case TIMER_CURSORMOVEUPDATE: + hideCursor = true; + KillTimer(hWnd, TIMER_CURSORMOVEUPDATE); + return 0; + } + break; case WM_COMMAND: { @@ -781,6 +813,8 @@ namespace MainWindow return DefWindowProc(hWnd,message,wParam,lParam); case WM_DESTROY: + KillTimer(hWnd, TIMER_CURSORUPDATE); + KillTimer(hWnd, TIMER_CURSORMOVEUPDATE); PostQuitMessage(0); break; From c0d51065d61122c2d45bd01abfc8b5461d6fbd5f Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 13:08:00 +0800 Subject: [PATCH 23/51] Display current AF --- UI/MenuScreens.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 03914bc49a..3d6bfdd3ce 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -798,8 +798,10 @@ void GraphicsScreenP2::render() { if (g_Config.iAnisotropyLevel == 0) g_Config.iAnisotropyLevel = 2; - ui_draw2d.DrawText(UBUNTU24, gs->T("Level :"), x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 180, y, 20); + char showAF[256]; + sprintf(showAF, "%s %dx", gs->T("Level :"), g_Config.iAnisotropyLevel); + ui_draw2d.DrawText(UBUNTU24, showAF, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 60, y += stride , 20); if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("2x"), ALIGN_LEFT)) g_Config.iAnisotropyLevel = 2; if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("4x"), ALIGN_LEFT)) From a9363292d6e8bc6e80cddc699686789850bcd624 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 13:09:41 +0800 Subject: [PATCH 24/51] Better align the message context in message dialog --- Core/Dialog/PSPMsgDialog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index ddb5687473..722243bbb5 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -132,7 +132,7 @@ int PSPMsgDialog::Init(unsigned int paramAddr) void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo) { - const float WRAP_WIDTH = 350.0f; + const float WRAP_WIDTH = 480.0f; float y = 136.0f, h; int n; PPGeMeasureText(0, &h, &n, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); @@ -173,8 +173,8 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo) } PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); float sy = 122.0f - h2, ey = 150.0f + h2; - PPGeDrawRect(60.0f, sy, 420.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawRect(60.0f, ey, 420.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawRect(30.0f, sy, 450.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawRect(30.0f, ey, 450.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); } int PSPMsgDialog::Update() From d821946da539a8b54389e32884bce6b09fbb97b4 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 13:26:38 +0800 Subject: [PATCH 25/51] Only show option to select when enabled frameskip and FPS limit --- UI/MenuScreens.cpp | 55 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 3d6bfdd3ce..58af1acef2 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -874,29 +874,30 @@ void GraphicsScreenP3::render() { int columnw = 400; bool FpsLimit = g_Config.iFpsLimit != 0; - UICheckBox(GEN_ID, x, y += stride, gs->T("Fps Limit"), ALIGN_TOPLEFT, &FpsLimit); + UICheckBox(GEN_ID, x, y += stride, gs->T("FPS Limit"), ALIGN_TOPLEFT, &FpsLimit); if (FpsLimit) { if (g_Config.iFpsLimit == 0) g_Config.iFpsLimit = 60; char showFps[256]; - sprintf(showFps, "%s %d", gs->T("Fps :"), g_Config.iFpsLimit); + sprintf(showFps, "%s %d", gs->T("FPS :"), g_Config.iFpsLimit); ui_draw2d.DrawText(UBUNTU24, showFps, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); - } else { - g_Config.iFpsLimit = 0; - } - HLinear hlinear1(x + 60, y += stride, 20); - if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("Auto"), ALIGN_LEFT)) - g_Config.iFpsLimit = 60; - if (UIButton(GEN_ID, hlinear1, 60, 0, gs->T("-30"), ALIGN_LEFT)) - if(g_Config.iFpsLimit > 30){ - g_Config.iFpsLimit -= 30;} - if (UIButton(GEN_ID, hlinear1, 60, 0, gs->T("+30"), ALIGN_LEFT)) - if(g_Config.iFrameSkip != 240){ - g_Config.iFpsLimit += 30;} + HLinear hlinear1(x + 60, y += stride, 20); + if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("Auto"), ALIGN_LEFT)) + g_Config.iFpsLimit = 60; + if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("-1"), ALIGN_LEFT)) + if(g_Config.iFpsLimit > 30) + g_Config.iFpsLimit -= 1; + if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("+1"), ALIGN_LEFT)) + if(g_Config.iFrameSkip != 120) + g_Config.iFpsLimit += 1; + + y += 20; + } else + g_Config.iFpsLimit = 0; bool enableFrameSkip = g_Config.iFrameSkip != 0; - UICheckBox(GEN_ID, x, y += stride + 25, gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); + UICheckBox(GEN_ID, x, y += stride , gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); if (enableFrameSkip) { if (g_Config.iFrameSkip == 0) g_Config.iFrameSkip = 3; @@ -904,19 +905,19 @@ void GraphicsScreenP3::render() { char showFrameSkip[256]; sprintf(showFrameSkip, "%s %d", gs->T("Frames :"), g_Config.iFrameSkip); ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); - } - else { + HLinear hlinear2(x + 60, y += stride, 20); + if (UIButton(GEN_ID, hlinear2, 80, 0, gs->T("Auto"), ALIGN_LEFT)) + g_Config.iFrameSkip = 3; + if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("-1"), ALIGN_LEFT)) + if (g_Config.iFrameSkip > 1) + g_Config.iFrameSkip -= 1; + if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("+1"), ALIGN_LEFT)) + if (g_Config.iFrameSkip < 9) + g_Config.iFrameSkip += 1; + + y += 20; + } else g_Config.iFrameSkip = 0; - } - HLinear hlinear2(x + 60, y += stride, 20); - if (UIButton(GEN_ID, hlinear2, 80, 0, gs->T("Auto"), ALIGN_LEFT)) - g_Config.iFrameSkip = 3; - if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("-1"), ALIGN_LEFT)) - if (g_Config.iFrameSkip > 1) - g_Config.iFrameSkip -= 1; - if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("+1"), ALIGN_LEFT)) - if (g_Config.iFrameSkip < 9) - g_Config.iFrameSkip += 1; UIEnd(); } From 8821528d01b0f2061ed38a7424d5bcc105d8b85a Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 14:43:49 +0900 Subject: [PATCH 26/51] Optimizing the space to put in single line for frame skipping and fps limit --- UI/MenuScreens.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 58af1acef2..bece78c639 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -881,8 +881,8 @@ void GraphicsScreenP3::render() { char showFps[256]; sprintf(showFps, "%s %d", gs->T("FPS :"), g_Config.iFpsLimit); - ui_draw2d.DrawText(UBUNTU24, showFps, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 60, y += stride, 20); + ui_draw2d.DrawText(UBUNTU24, showFps, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 220, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("Auto"), ALIGN_LEFT)) g_Config.iFpsLimit = 60; if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("-1"), ALIGN_LEFT)) @@ -904,8 +904,8 @@ void GraphicsScreenP3::render() { char showFrameSkip[256]; sprintf(showFrameSkip, "%s %d", gs->T("Frames :"), g_Config.iFrameSkip); - ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear2(x + 60, y += stride, 20); + ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear2(x + 220, y, 20); if (UIButton(GEN_ID, hlinear2, 80, 0, gs->T("Auto"), ALIGN_LEFT)) g_Config.iFrameSkip = 3; if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("-1"), ALIGN_LEFT)) @@ -918,7 +918,7 @@ void GraphicsScreenP3::render() { y += 20; } else g_Config.iFrameSkip = 0; - + UIEnd(); } From 2aec47e702009e82af709dfce333ad87ec4c972f Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 13:50:18 +0800 Subject: [PATCH 27/51] Optimizing the space to put in single line for texture scaling and AF as well --- UI/MenuScreens.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index bece78c639..988a79ae82 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -693,7 +693,7 @@ void AudioScreen::render() { int columnw = 400; UICheckBox(GEN_ID, x, y += stride, a->T("Enable Sound"), ALIGN_TOPLEFT, &g_Config.bEnableSound); if (Atrac3plus_Decoder::IsInstalled() && g_Config.bEnableSound) { - UICheckBox(GEN_ID, x, y += stride, a->T("Enable Atrac3+"), ALIGN_TOPLEFT, &g_Config.bEnableAtrac3plus); + UICheckBox(GEN_ID, x + 60, y += stride, a->T("Enable Atrac3+"), ALIGN_TOPLEFT, &g_Config.bEnableAtrac3plus); } @@ -800,8 +800,8 @@ void GraphicsScreenP2::render() { char showAF[256]; sprintf(showAF, "%s %dx", gs->T("Level :"), g_Config.iAnisotropyLevel); - ui_draw2d.DrawText(UBUNTU24, showAF, x + 60, (y += stride) - 5, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 60, y += stride , 20); + ui_draw2d.DrawText(UBUNTU24, showAF, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 220, y , 20); if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("2x"), ALIGN_LEFT)) g_Config.iAnisotropyLevel = 2; if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("4x"), ALIGN_LEFT)) @@ -812,35 +812,44 @@ void GraphicsScreenP2::render() { g_Config.iAnisotropyLevel = 16; y += 20; - } else { + } else g_Config.iAnisotropyLevel = 0; - } + + bool TexScaling = g_Config.iTexScalingLevel > 1; UICheckBox(GEN_ID, x, y += stride, gs->T("xBRZ Texture Scaling"), ALIGN_TOPLEFT, &TexScaling); if (TexScaling) { if (g_Config.iTexScalingLevel <= 1) g_Config.iTexScalingLevel = 2; - ui_draw2d.DrawText(UBUNTU24, gs->T("Type :"), x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 180, y, 20); + + //TODO : Show the exact mode description instead of number of TexScalingType. + char showType[256]; + sprintf(showType, "%s %d", gs->T("Type :"), g_Config.iTexScalingType); + ui_draw2d.DrawText(UBUNTU24, showType, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 220, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("xBRZ"), ALIGN_LEFT)) g_Config.iTexScalingType = 0; - if (UIButton(GEN_ID, hlinear1, 150, 0, gs->T("Hybrid", "Hybrid(H)"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 100, 0, gs->T("Hybrid", "Hybrid(H)"), ALIGN_LEFT)) g_Config.iTexScalingType = 1; if (UIButton(GEN_ID, hlinear1, 150, 0, gs->T("Bicubic", "Bicubic(B)"), ALIGN_LEFT)) g_Config.iTexScalingType = 2; if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("H+B", "H+B"), ALIGN_LEFT)) g_Config.iTexScalingType = 3; - ui_draw2d.DrawText(UBUNTU24, gs->T("Level :"), x + 60, y += stride + 20, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear2(x + 180, y, 20); + + y += 20; + char showLevel[256]; + sprintf(showLevel, "%s %dx", gs->T("Level :"), g_Config.iTexScalingLevel); + ui_draw2d.DrawText(UBUNTU24, showLevel, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear2(x + 220, y, 20); if (UIButton(GEN_ID, hlinear2, 45, 0, gs->T("2x"), ALIGN_LEFT)) g_Config.iTexScalingLevel = 2; if (UIButton(GEN_ID, hlinear2, 45, 0, gs->T("3x"), ALIGN_LEFT)) g_Config.iTexScalingLevel = 3; - UICheckBox(GEN_ID, x + 60, y += stride + 20, gs->T("Deposterize"), ALIGN_LEFT, &g_Config.bTexDeposterize); - } else { - g_Config.iTexScalingLevel = 1; - } + UICheckBox(GEN_ID, x + 60, y += stride + 20, gs->T("Deposterize"), ALIGN_LEFT, &g_Config.bTexDeposterize); + } else + g_Config.iTexScalingLevel = 1; + UIEnd(); } From 136c05c7223c12d2fa4e3cfcc2840def7f73cc98 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 13:51:54 +0800 Subject: [PATCH 28/51] Minor spacing fix --- UI/MenuScreens.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 988a79ae82..5d62ddb5e4 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -894,10 +894,10 @@ void GraphicsScreenP3::render() { HLinear hlinear1(x + 220, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("Auto"), ALIGN_LEFT)) g_Config.iFpsLimit = 60; - if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("-1"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 40, 0, gs->T("-1"), ALIGN_LEFT)) if(g_Config.iFpsLimit > 30) g_Config.iFpsLimit -= 1; - if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("+1"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 40, 0, gs->T("+1"), ALIGN_LEFT)) if(g_Config.iFrameSkip != 120) g_Config.iFpsLimit += 1; From 940656149220ca579af34abe4d52c404089c9af3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 23:12:56 -0700 Subject: [PATCH 29/51] The seek callback should return new offset. Like lseek(). Not the passed param. --- Core/HW/MediaEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 18621c1963..e60e7c8b18 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -174,7 +174,7 @@ int64_t _MpegSeekbuffer(void *opaque, int64_t offset, int whence) return mpeg->m_streamSize; #endif } - return offset; + return mpeg->m_decodeNextPos; } #ifdef _DEBUG From f6534c3809458bfc80ff706d04df9f103cc650c4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 23:18:13 -0700 Subject: [PATCH 30/51] Fix a possible buffer over/underflow issue in mpeg. Atrac seems to have a problem here, so let's be safe. --- Core/HW/MediaEngine.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index e60e7c8b18..9a348b0d1d 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -136,7 +136,10 @@ void MediaEngine::closeMedia() { int _MpegReadbuffer(void *opaque, uint8_t *buf, int buf_size) { - MediaEngine *mpeg = (MediaEngine*)opaque; + MediaEngine *mpeg = (MediaEngine *)opaque; + if ((u32)mpeg->m_decodeNextPos > (u32)mpeg->m_streamSize) + return -1; + int size = std::min(mpeg->m_bufSize, buf_size); int available = mpeg->m_readSize - mpeg->m_decodeNextPos; int remaining = mpeg->m_streamSize - mpeg->m_decodeNextPos; From de0b94542ffd755034f950c3f8cdd573781212b1 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 15:23:14 +0900 Subject: [PATCH 31/51] Display current selection for texture scaling --- UI/MenuScreens.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 5d62ddb5e4..5224a09386 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -801,7 +801,7 @@ void GraphicsScreenP2::render() { char showAF[256]; sprintf(showAF, "%s %dx", gs->T("Level :"), g_Config.iAnisotropyLevel); ui_draw2d.DrawText(UBUNTU24, showAF, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 220, y , 20); + HLinear hlinear1(x + 250, y , 20); if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("2x"), ALIGN_LEFT)) g_Config.iAnisotropyLevel = 2; if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("4x"), ALIGN_LEFT)) @@ -822,25 +822,31 @@ void GraphicsScreenP2::render() { if (g_Config.iTexScalingLevel <= 1) g_Config.iTexScalingLevel = 2; - //TODO : Show the exact mode description instead of number of TexScalingType. char showType[256]; - sprintf(showType, "%s %d", gs->T("Type :"), g_Config.iTexScalingType); + std::string type; + + switch (g_Config.iTexScalingType) { + case 0: type = "xBRZ";break; + case 1: type = "Hybrid";break; + case 2: type = "Bicubic";break; + case 3: type = "H+B";break; + } + sprintf(showType, "%s %s", gs->T("Type :"), type.c_str()); ui_draw2d.DrawText(UBUNTU24, showType, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 220, y, 20); + HLinear hlinear1(x + 250, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("xBRZ"), ALIGN_LEFT)) g_Config.iTexScalingType = 0; - if (UIButton(GEN_ID, hlinear1, 100, 0, gs->T("Hybrid", "Hybrid(H)"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 120, 0, gs->T("Hybrid", "(H)ybrid"), ALIGN_LEFT)) g_Config.iTexScalingType = 1; - if (UIButton(GEN_ID, hlinear1, 150, 0, gs->T("Bicubic", "Bicubic(B)"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 130, 0, gs->T("Bicubic", "(B)icubic"), ALIGN_LEFT)) g_Config.iTexScalingType = 2; if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("H+B", "H+B"), ALIGN_LEFT)) g_Config.iTexScalingType = 3; - y += 20; char showLevel[256]; sprintf(showLevel, "%s %dx", gs->T("Level :"), g_Config.iTexScalingLevel); ui_draw2d.DrawText(UBUNTU24, showLevel, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear2(x + 220, y, 20); + HLinear hlinear2(x + 250, y, 20); if (UIButton(GEN_ID, hlinear2, 45, 0, gs->T("2x"), ALIGN_LEFT)) g_Config.iTexScalingLevel = 2; if (UIButton(GEN_ID, hlinear2, 45, 0, gs->T("3x"), ALIGN_LEFT)) @@ -891,7 +897,7 @@ void GraphicsScreenP3::render() { char showFps[256]; sprintf(showFps, "%s %d", gs->T("FPS :"), g_Config.iFpsLimit); ui_draw2d.DrawText(UBUNTU24, showFps, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 220, y, 20); + HLinear hlinear1(x + 250, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("Auto"), ALIGN_LEFT)) g_Config.iFpsLimit = 60; if (UIButton(GEN_ID, hlinear1, 40, 0, gs->T("-1"), ALIGN_LEFT)) @@ -914,7 +920,7 @@ void GraphicsScreenP3::render() { char showFrameSkip[256]; sprintf(showFrameSkip, "%s %d", gs->T("Frames :"), g_Config.iFrameSkip); ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear2(x + 220, y, 20); + HLinear hlinear2(x + 250, y, 20); if (UIButton(GEN_ID, hlinear2, 80, 0, gs->T("Auto"), ALIGN_LEFT)) g_Config.iFrameSkip = 3; if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("-1"), ALIGN_LEFT)) From 7531e50d27789bb00be2bbcefa04373692c5b647 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 23:24:37 -0700 Subject: [PATCH 32/51] Ignore/fail on bad seeks for atrac3 audio. This was happening in Disgaea, and causing it to crash. --- Core/HLE/sceAtrac.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index b217e8394e..96c36aa9ad 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -913,7 +913,9 @@ u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFirstBuf, #ifdef USE_FFMPEG int _AtracReadbuffer(void *opaque, uint8_t *buf, int buf_size) { - Atrac *atrac = (Atrac*)opaque; + Atrac *atrac = (Atrac *)opaque; + if (atrac->decodePos > atrac->first.filesize) + return -1; int size = std::min((int)atrac->atracBufSize, buf_size); size = std::max(std::min(((int)atrac->first.size - (int)atrac->decodePos), size), 0); if (size > 0) @@ -925,6 +927,9 @@ int _AtracReadbuffer(void *opaque, uint8_t *buf, int buf_size) int64_t _AtracSeekbuffer(void *opaque, int64_t offset, int whence) { Atrac *atrac = (Atrac*)opaque; + if (offset > atrac->first.filesize) + return -1; + switch (whence) { case SEEK_SET: atrac->decodePos = (u32)offset; @@ -935,8 +940,12 @@ int64_t _AtracSeekbuffer(void *opaque, int64_t offset, int whence) case SEEK_END: atrac->decodePos = atrac->first.filesize - (u32)offset; break; +#ifdef USE_FFMPEG + case AVSEEK_SIZE: + return atrac->first.filesize; +#endif } - return offset; + return atrac->decodePos; } #endif // USE_FFMPEG From 6d82479fe5e3b1a95b0053314bb5c9120fe37862 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 14:30:34 +0800 Subject: [PATCH 33/51] Only display "download atrac3+ plugin" when it is not installed. --- UI/MenuScreens.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 5224a09386..8c888c2f1a 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -700,7 +700,7 @@ void AudioScreen::render() { #if (defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))) || defined(ARMEABI) || defined(ARMEABI_V7A) VLinear vlinear(30, 300, 20); - if (UIButton(GEN_ID, vlinear, 400, 0, a->T("Download Atrac3+ plugin"), ALIGN_LEFT)) { + if (!Atrac3plus_Decoder::IsInstalled() && UIButton(GEN_ID, vlinear, 400, 0, a->T("Download Atrac3+ plugin"), ALIGN_LEFT)) { screenManager()->push(new PluginScreen()); } From c7d3caf5f7df2e9108a15466d3b4ebf88a565eef Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 14:36:07 +0800 Subject: [PATCH 34/51] Make frameskipping UI consistents with others --- UI/MenuScreens.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 8c888c2f1a..973ec1d143 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -461,38 +461,34 @@ void PauseScreen::render() { UICheckBox(GEN_ID, x, y += stride, ss->T("Show FPS"), ALIGN_TOPLEFT, &g_Config.bShowFPSCounter); bool enableFrameSkip = g_Config.iFrameSkip != 0; - UICheckBox(GEN_ID, x, (y += stride) + 5, gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); - - HLinear hlinear1(x + 330, y, 20); - if (UIButton(GEN_ID, hlinear1, 90, 0, gs->T("Auto"), ALIGN_LEFT)) - g_Config.iFrameSkip = 3; - if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("-1"), ALIGN_LEFT)) - if (g_Config.iFrameSkip > 1) - g_Config.iFrameSkip -= 1; - if (UIButton(GEN_ID, hlinear1, 45, 0, gs->T("+1"), ALIGN_LEFT)) - if (g_Config.iFrameSkip < 9) - g_Config.iFrameSkip += 1; - + UICheckBox(GEN_ID, x, y += stride , gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); if (enableFrameSkip) { if (g_Config.iFrameSkip == 0) g_Config.iFrameSkip = 3; char showFrameSkip[256]; sprintf(showFrameSkip, "%s %d", gs->T("Frames :"), g_Config.iFrameSkip); - ui_draw2d.DrawText(UBUNTU24, showFrameSkip, dp_xres - 15, y - 2, 0xc0000000, ALIGN_TOPRIGHT); - ui_draw2d.DrawText(UBUNTU24, showFrameSkip, dp_xres - 15, y, 0xFF3fFF3f, ALIGN_TOPRIGHT); - } - else { + ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear2(x + 220, y, 20); + if (UIButton(GEN_ID, hlinear2, 80, 0, gs->T("Auto"), ALIGN_LEFT)) + g_Config.iFrameSkip = 3; + if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("-1"), ALIGN_LEFT)) + if (g_Config.iFrameSkip > 1) + g_Config.iFrameSkip -= 1; + if (UIButton(GEN_ID, hlinear2, 40, 0, gs->T("+1"), ALIGN_LEFT)) + if (g_Config.iFrameSkip < 9) + g_Config.iFrameSkip += 1; + + } else g_Config.iFrameSkip = 0; - } // TODO: Add UI for more than one slot. HLinear hlinear2(x, y += 70, 20); - if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH + 125, 0, i->T("Save State"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, i->T("Save State"), ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH + 125, 0, i->T("Load State"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, i->T("Load State"), ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } From cf37d569a55dcaf4348c2e41b3153975a10ba3a4 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 14:54:50 +0800 Subject: [PATCH 35/51] Shorter string for Enable compatibility report servers --- UI/MenuScreens.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 973ec1d143..47604b8de7 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -633,7 +633,7 @@ void DeveloperScreen::render() { bool reportingEnabled = Reporting::IsEnabled(); const static std::string reportHostOfficial = "report.ppsspp.org"; - if (UICheckBox(GEN_ID, x, y += stride, s->T("Enable Compatibility Server Reports"), ALIGN_TOPLEFT, &reportingEnabled)) { + if (UICheckBox(GEN_ID, x, y += stride, d->T("Report","Enable Compatibility Server Reports"), ALIGN_TOPLEFT, &reportingEnabled)) { g_Config.sReportHost = reportingEnabled ? reportHostOfficial : ""; } @@ -1075,7 +1075,7 @@ void SystemScreen::render() { } UICheckBox(GEN_ID, x, y += stride, s->T("Enable Cheats"), ALIGN_TOPLEFT, &g_Config.bEnableCheats); HLinear hlinear2(x, y += stride + 10, 20); - if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH + 150, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT)) { + if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH + 50, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT)) { g_Config.bReloadCheats = true; } if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, s->T("Language"), ALIGN_TOPLEFT)) { From 1e805e7fc8ce58680286cc165e1a4db95f05671f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jun 2013 23:55:19 -0700 Subject: [PATCH 36/51] Return correct errors in sceKernelDeleteThread(). And also, don't reschedule in sceKernelTerminateDeleteThread(), per tests. --- Core/HLE/sceKernelThread.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 2859a9baaf..942ce0bd6f 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2136,27 +2136,31 @@ int sceKernelRotateThreadReadyQueue(int priority) return 0; } -int sceKernelDeleteThread(int threadHandle) +int sceKernelDeleteThread(int threadID) { - if (threadHandle != currentThread) + if (threadID == 0 || threadID == currentThread) { - DEBUG_LOG(HLE,"sceKernelDeleteThread(%i)",threadHandle); + ERROR_LOG(HLE, "sceKernelDeleteThread(%i): cannot delete current thread", threadID); + return SCE_KERNEL_ERROR_NOT_DORMANT; + } - u32 error; - Thread *t = kernelObjects.Get(threadHandle, error); - if (t) + u32 error; + Thread *t = kernelObjects.Get(threadID, error); + if (t) + { + if (!t->isStopped()) { - // TODO: Should this reschedule ever? Probably no? - return __KernelDeleteThread(threadHandle, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread deleted", true); + ERROR_LOG(HLE, "sceKernelDeleteThread(%i): thread not dormant", threadID); + return SCE_KERNEL_ERROR_NOT_DORMANT; } - // TODO: Error when doesn't exist? - return 0; + DEBUG_LOG(HLE, "sceKernelDeleteThread(%i)", threadID); + return __KernelDeleteThread(threadID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread deleted", true); } else { - ERROR_LOG_REPORT(HLE, "Thread \"%s\" tries to delete itself! :(", __GetCurrentThread() ? __GetCurrentThread()->GetName() : "NULL"); - return -1; + ERROR_LOG(HLE, "sceKernelDeleteThread(%i): thread doesn't exist", threadID); + return error; } } @@ -2173,9 +2177,7 @@ int sceKernelTerminateDeleteThread(int threadID) if (t) { INFO_LOG(HLE, "sceKernelTerminateDeleteThread(%i)", threadID); - //TODO: should we really reschedule here? - error = __KernelDeleteThread(threadID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread terminated with delete", false); - hleReSchedule("thread terminated with delete"); + error = __KernelDeleteThread(threadID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread terminated with delete", true); return error; } From 26ec4c283ffd553524e1c339d5d377b40f527735 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sat, 15 Jun 2013 16:29:46 +0800 Subject: [PATCH 37/51] Minor fix to the correct font scale --- Core/Dialog/PSPMsgDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index ddb5687473..f756505913 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -23,7 +23,7 @@ #include "ChunkFile.h" #include "i18n/i18n.h" -const float FONT_SCALE = 0.55f; +const float FONT_SCALE = 0.50f; PSPMsgDialog::PSPMsgDialog() : PSPDialog() From 85d896b9539cb1a6717ac66a40ed7641ff6b5a02 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 15 Jun 2013 10:55:18 +0200 Subject: [PATCH 38/51] Fix showing log windows on load with -l (initialization order). --- Windows/main.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Windows/main.cpp b/Windows/main.cpp index 719062c8f4..5366a05b76 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -64,11 +64,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin hideLog = false; #endif - LogManager::Init(); - LogManager::GetInstance()->GetConsoleListener()->Open(hideLog, 150, 120, "PPSSPP Debug Console"); - LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); - - g_Config.Load(); // The rest is handled in NativeInit(). for (int i = 1; i < __argc; ++i) @@ -91,6 +86,12 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin } } + g_Config.Load(); + + LogManager::Init(); + LogManager::GetInstance()->GetConsoleListener()->Open(hideLog, 150, 120, "PPSSPP Debug Console"); + LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); + VFSRegister("", new DirectoryAssetReader("assets/")); VFSRegister("", new DirectoryAssetReader("")); From ffb1d653138f3a6fa78e8004bedb466e93e717b1 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 15 Jun 2013 11:40:31 +0200 Subject: [PATCH 39/51] Add forum link to help menu on Windows, and under the website link on the main menu screen. --- UI/MenuScreens.cpp | 7 +++++++ Windows/WndMainWindow.cpp | 13 +++++++++---- Windows/ppsspp.rc | Bin 39344 -> 39448 bytes Windows/resource.h | Bin 22694 -> 22786 bytes 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 47604b8de7..9fcb8c4d4f 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -268,6 +268,13 @@ void MenuScreen::render() { LaunchBrowser("http://www.ppsspp.org/"); } + // Skip the forum button if screen too small. Will be redesigned in new UI later. + if (dp_yres > 510) { + if (UIButton(GEN_ID, vlinear, w, 0, "forums.ppsspp.org", ALIGN_RIGHT)) { + LaunchBrowser("http://forums.ppsspp.org/"); + } + } + int recentW = 350; if (g_Config.recentIsos.size()) { ui_draw2d.DrawText(UBUNTU24, m->T("Recent"), -xoff, 80, 0xFFFFFFFF, ALIGN_BOTTOMLEFT); diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index e6a0055b7f..23cbe0b860 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -753,11 +753,16 @@ namespace MainWindow case ID_EMULATION_SOUND: g_Config.bEnableSound = !g_Config.bEnableSound; break; - case ID_HELP_OPENWEBSITE: - ShellExecute(NULL, "open", "http://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); - break; - case ID_HELP_ABOUT: + case ID_HELP_OPENWEBSITE: + ShellExecute(NULL, "open", "http://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + break; + + case ID_HELP_OPENFORUM: + ShellExecute(NULL, "open", "http://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + break; + + case ID_HELP_ABOUT: DialogManager::EnableAll(FALSE); DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); DialogManager::EnableAll(TRUE); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index c00e33f5d3890f2de0089f7b90aa390c02c5bbf4..e7bb609c133761baabf39f55a4cd29e7fb811450 100644 GIT binary patch delta 99 zcmdn6nQ6urrVZcPq{|sVP>-Pi2#bLbMC&o+GZZnTPgZOXo-B~YGWk^-k7NKt07Ebk of@lQ>H?WFQhFpeXpelKGHwJ%(AcoM%iWQoZ*X7$R-q0=t0E?d+xc~qF delta 65 zcmbQSg=xcPrVZcPv@;k=fUtnUia{R;%fV0&$S+_h20{?6$B@rZ#E{OQKUuInc=CoR JHj5=XgaB+D5+?uv diff --git a/Windows/resource.h b/Windows/resource.h index 3b7432a1a68998751b0b77a554fa4bf1d9ddf7e5..0195e2b168b452fc7fc8645dae5fe1f90498e7ec 100644 GIT binary patch delta 58 zcmV-A0LA~Nu>pdz0kHm6lkgG@5l;Y607U>!07d{$08#)|08Nt-QYDkfR~VDvR1~ug QR=xoNH Date: Sat, 15 Jun 2013 21:19:49 +0900 Subject: [PATCH 40/51] Mipmapping always set to true that real PSP does --- Core/Config.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index ab159f20ae..f9c793b871 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -119,11 +119,7 @@ void Config::Load(const char *iniFileName) #endif graphics->Get("StretchToDisplay", &bStretchToDisplay, false); graphics->Get("TrueColor", &bTrueColor, true); -#ifdef USING_GLES2 graphics->Get("MipMap", &bMipMap, true); -#else - graphics->Get("MipMap", &bMipMap, false); -#endif graphics->Get("TexScalingLevel", &iTexScalingLevel, 1); graphics->Get("TexScalingType", &iTexScalingType, 0); graphics->Get("TexDeposterize", &bTexDeposterize, false); From c128f164eddd499c2a075c2703269d3358f463db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Jun 2013 14:50:47 +0200 Subject: [PATCH 41/51] Fix PPSSPPSDL on MacOSX, link ffmpeg. --- CMakeLists.txt | 12 +++++++++++- ffmpeg | 2 +- lang | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c2800ec37..fa5e2b0fac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,11 @@ else() # Assume x86 set(X86 ON) endif() -if(ANDROID OR BLACKBERRY OR IOS OR PANDORA OR MAEMO) +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(MACOSX ON) +endif() + +if(ANDROID OR BLACKBERRY OR IOS OR PANDORA OR MAEMO OR MACOSX) set(HEADLESS OFF) elseif(NOT DEFINED HEADLESS) set(HEADLESS ON) @@ -472,6 +476,12 @@ elseif(BLACKBERRY) set(nativeExtraLibs ${nativeExtraLibs} iconv libavformat.a libavcodec.a libswresample.a libavutil.a libswscale.a) set(TargetBin PPSSPPBlackberry) elseif(SDL_FOUND) + if(MACOSX) + include_directories(ffmpeg/macosx/x86_64/include) + link_directories(ffmpeg/macosx/x86_64/lib) + set(nativeExtraLibs ${nativeExtraLibs} libavformat.a libavcodec.a libswresample.a libavutil.a libswscale.a) + endif() + set(TargetBin PPSSPPSDL) # Require SDL include_directories(${SDL_INCLUDE_DIR}) set(nativeExtra ${nativeExtra} native/base/PCMain.cpp) diff --git a/ffmpeg b/ffmpeg index 5f420cb666..969f062d31 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 5f420cb6667430edaaef2d97bb85b170db67c45d +Subproject commit 969f062d319ab9e3d341c6e661eedd51eefa50a2 diff --git a/lang b/lang index 9a59b4db25..cf710f2017 160000 --- a/lang +++ b/lang @@ -1 +1 @@ -Subproject commit 9a59b4db25598d735eb1ef365b6e69bff3f3e080 +Subproject commit cf710f2017db93c4019ce53a03764edf3136fa84 From 0b433d28bad52761cb067d6f2674ab3369623d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Jun 2013 15:04:06 +0200 Subject: [PATCH 42/51] Add some more people to contributors in the Credits scroller. --- UI/MenuScreens.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 9fcb8c4d4f..efc124feb9 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1263,19 +1263,28 @@ static const char * credits[] = { "", "Contributors:", "unknownbrackets", + "oioitff", "xsacha", "raven02", - "oioitff", "tpunix", "orphis", "sum2012", "mikusp", - "artart78", + "aquanull", + "The Dax", "tmaul", + "artart78", "ced2911", "soywiz", "kovensky", "xele", + "chaserhjk", + "evilcorn", + "daniel dressler", + "makotech222", + "CPkmn", + "mgaver", + "jeid3", "cinaera/BeaR", "", "Written in C++ for speed and portability", From c8bbad2731a9cc70185fb8424c548ca3d166a421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Jun 2013 15:13:30 +0200 Subject: [PATCH 43/51] Update native (mouse fix for sdl) --- native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native b/native index 5e50ceca86..5d098ca88b 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 5e50ceca86e4f8b3580662a1a5619fb660c5e066 +Subproject commit 5d098ca88bd11f0af09c95c9e91166fb82faa07b From 77a01c1526081a316cf115c5b9073b5f028bfad6 Mon Sep 17 00:00:00 2001 From: aquanull Date: Sat, 15 Jun 2013 19:32:32 +0800 Subject: [PATCH 44/51] Fix missing punctuation marks when the text is wrapped around them. Truncate trailing white spaces instead of putting them on the beginning of the next line. --- Core/Util/PPGeDraw.cpp | 177 +++++++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 76 deletions(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 31807904d6..40989d9186 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -326,52 +326,6 @@ static const AtlasChar *PPGeGetChar(const AtlasFont &atlasfont, unsigned int cva return c; } -static float NextWordWidth(UTF8 utf, const AtlasFont &atlasfont, float scale) { - float w = 0.0; - bool finished = false; - while (!utf.end() && !finished) { - u32 cval = utf.next(); - const AtlasChar *ch = PPGeGetChar(atlasfont, cval); - if (!ch) { - continue; - } - - switch (cval) { - // TODO: This list of punctuation is very incomplete. - case ',': - case '.': - case ':': - case '!': - case ')': - case '?': - case 0x3001: // IDEOGRAPHIC COMMA - case 0x3002: // IDEOGRAPHIC FULL STOP - case 0x06D4: // ARABIC FULL STOP - case 0xFF01: // FULLWIDTH EXCLAMATION MARK - case 0xFF09: // FULLWIDTH RIGHT PARENTHESIS - case 0xFF1F: // FULLWIDTH QUESTION MARK - // Count this character (punctuation is so clingy), but then we're done. - w += ch->wx * scale; - finished = true; - break; - - case ' ': - case '\t': - case '\r': - case '\n': - case 0x3000: // IDEOGRAPHIC SPACE - finished = true; - break; - - default: - w += ch->wx * scale; - break; - } - } - - return w; -} - // Break a single text string into mutiple lines. static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, float x, float y, int align, float scale, int wrapType, float wrapWidth, bool dryRun) @@ -384,7 +338,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, wrapWidth = 480.f; } - // used for replacing with ellipsis + // used for replacing with ellipses float wrapCutoff = 8.0f; const AtlasChar *dot = PPGeGetChar(atlasfont, '.'); if (dot) { @@ -400,50 +354,121 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, float lineWidth = 0; while (!utf.end()) { - uint32_t cval = utf.next(); - if (cval == '\n') { - ++numLines; - break; - } - if (cval == '\r') { - // We simply ignore this. - continue; - } - const AtlasChar *c = PPGeGetChar(atlasfont, cval); - if (c) + UTF8 utfNext(utf); + float nextWidth = 0; + float spaceWidth = 0; + int numChars = 0; + bool finished = false; + while (!utfNext.end() && !finished) { - if (wrapType > 0) + u32 cval = utfNext.next(); + const AtlasChar *ch = PPGeGetChar(atlasfont, cval); + if (!ch) { + continue; + } + + switch (cval) { + // TODO: This list of punctuation is very incomplete. + case ',': + case '.': + case ':': + case '!': + case ')': + case '?': + case 0x3001: // IDEOGRAPHIC COMMA + case 0x3002: // IDEOGRAPHIC FULL STOP + case 0x06D4: // ARABIC FULL STOP + case 0xFF01: // FULLWIDTH EXCLAMATION MARK + case 0xFF09: // FULLWIDTH RIGHT PARENTHESIS + case 0xFF1F: // FULLWIDTH QUESTION MARK + // Count this character (punctuation is so clingy), but then we're done. + ++numChars; + nextWidth += ch->wx * scale; + finished = true; + break; + + case ' ': + case 0x3000: // IDEOGRAPHIC SPACE + spaceWidth += ch->wx * scale; + finished = true; + break; + + case '\t': + case '\r': + case '\n': + // Ignore this character and we're done. + finished = true; + break; + + default: + ++numChars; + nextWidth += ch->wx * scale; + break; + } + } + + if (wrapType > 0) + { + if (lineWidth + nextWidth > wrapWidth) { - float nextWidth = NextWordWidth(utf, atlasfont, scale); - if (lineWidth + nextWidth > wrapWidth) { - if (wrapType & PPGE_LINE_WRAP_WORD) { - // TODO: Should check if we have had at least one other word instead. - if (lineWidth > 0) { - ++numLines; - break; - } + if (wrapType & PPGE_LINE_WRAP_WORD) { + // TODO: Should check if we have had at least one other word instead. + if (lineWidth > 0) { + ++numLines; + break; } - if (wrapType & PPGE_LINE_USE_ELLIPSIS) { - if (nextWidth >= wrapCutoff) { - // TODO: Truncate the word with an ellipsis. - // The word is not too short. - } + } + if (wrapType & PPGE_LINE_USE_ELLIPSIS) { + if (nextWidth >= wrapCutoff) { + // The word is not too short. + // TODO: Truncate the current line with an ellipsis. } } } + } + for (int i = 0; i < numChars; ++i) + { + u32 cval = utf.next(); + const AtlasChar *c = PPGeGetChar(atlasfont, cval); + if (c) + { + if (!dryRun) + { + AtlasCharVertex cv; + cv.x = x + c->ox * scale; + cv.y = y + c->oy * scale; + cv.c = c; + char_one_line.push_back(cv); + } + x += c->wx * scale; + } + } + lineWidth += nextWidth; + + u32 cval = utf.next(); + if (spaceWidth > 0) + { if (!dryRun) { + // No need to check c. + const AtlasChar *c = PPGeGetChar(atlasfont, cval); AtlasCharVertex cv; cv.x = x + c->ox * scale; cv.y = y + c->oy * scale; cv.c = c; char_one_line.push_back(cv); } - - float ww = c->wx * scale; - lineWidth += ww; - x += ww; + x += spaceWidth; + lineWidth += spaceWidth; + if (wrapType > 0 && lineWidth > wrapWidth) { + lineWidth = wrapWidth; + } } + else if (cval == '\n') { + ++numLines; + break; + } + utf = utfNext; } y += lineHeight; x = sx; From 336f388fa2449e8215fb807d93c5911713392d5e Mon Sep 17 00:00:00 2001 From: aquanull Date: Sat, 15 Jun 2013 16:45:52 +0800 Subject: [PATCH 45/51] Allow CJK characters to be wrapped individually. --- Core/Util/PPGeDraw.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 40989d9186..4a5205ac4f 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -354,14 +354,15 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, float lineWidth = 0; while (!utf.end()) { - UTF8 utfNext(utf); + UTF8 utfWord(utf); float nextWidth = 0; float spaceWidth = 0; int numChars = 0; bool finished = false; - while (!utfNext.end() && !finished) + while (!utfWord.end() && !finished) { - u32 cval = utfNext.next(); + UTF8 utfPrev = utfWord; + u32 cval = utfWord.next(); const AtlasChar *ch = PPGeGetChar(atlasfont, cval); if (!ch) { continue; @@ -401,6 +402,31 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, break; default: + { + // CJK characters can be wrapped more freely. + bool isCJK = (cval >= 0x1100 && cval <= 0x11FF); // Hangul Jamo. + isCJK = isCJK || (cval >= 0x2E80 && cval <= 0x2FFF); // Kangxi Radicals etc. +#if 0 + isCJK = isCJK || (cval >= 0x3040 && cval <= 0x31FF); // Hiragana, Katakana, Hangul Compatibility Jamo etc. + isCJK = isCJK || (cval >= 0x3200 && cval <= 0x32FF); // CJK Enclosed + isCJK = isCJK || (cval >= 0x3300 && cval <= 0x33FF); // CJK Compatibility + isCJK = isCJK || (cval >= 0x3400 && cval <= 0x4DB5); // CJK Unified Ideographs Extension A +#else + isCJK = isCJK || (cval >= 0x3040 && cval <= 0x4DB5); // Above collapsed +#endif + isCJK = isCJK || (cval >= 0x4E00 && cval <= 0x9FBB); // CJK Unified Ideographs + isCJK = isCJK || (cval >= 0xAC00 && cval <= 0xD7AF); // Hangul Syllables + isCJK = isCJK || (cval >= 0xF900 && cval <= 0xFAD9); // CJK Compatibility Ideographs + isCJK = isCJK || (cval >= 0x20000 && cval <= 0x2A6D6); // CJK Unified Ideographs Extension B + isCJK = isCJK || (cval >= 0x2F800 && cval <= 0x2FA1D); // CJK Compatibility Supplement + if (isCJK) { + if (numChars > 0) { + utfWord = utfPrev; + finished = true; + break; + } + } + } ++numChars; nextWidth += ch->wx * scale; break; @@ -468,7 +494,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, ++numLines; break; } - utf = utfNext; + utf = utfWord; } y += lineHeight; x = sx; From fb651156d871adf42543526f409ea4912567474b Mon Sep 17 00:00:00 2001 From: aquanull Date: Sat, 15 Jun 2013 19:28:05 +0800 Subject: [PATCH 46/51] Implement text truncation with ellipses. --- Core/Util/PPGeDraw.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 4a5205ac4f..dc3262788b 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -344,6 +344,8 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, if (dot) { wrapCutoff = dot->wx * scale * 3.0f; } + float threshold = sx + wrapWidth - wrapCutoff; + //const float wrapGreyZone = 2.0f; // Grey zone for punctuations at line ends int numLines = 1; @@ -352,6 +354,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, for (UTF8 utf(text); !utf.end(); ) { float lineWidth = 0; + bool skipRest = false; while (!utf.end()) { UTF8 utfWord(utf); @@ -433,9 +436,10 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, } } + bool useEllipsis = false; if (wrapType > 0) { - if (lineWidth + nextWidth > wrapWidth) + if (lineWidth + nextWidth > wrapWidth || skipRest) { if (wrapType & PPGE_LINE_WRAP_WORD) { // TODO: Should check if we have had at least one other word instead. @@ -445,10 +449,16 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, } } if (wrapType & PPGE_LINE_USE_ELLIPSIS) { - if (nextWidth >= wrapCutoff) { - // The word is not too short. - // TODO: Truncate the current line with an ellipsis. + useEllipsis = true; + if (skipRest) { + numChars = 0; + } else if (nextWidth < wrapCutoff) { + // The word is too short, so just backspace! + x = threshold; } + nextWidth = 0; + spaceWidth = 0; + lineWidth = wrapWidth; } } } @@ -458,6 +468,24 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, const AtlasChar *c = PPGeGetChar(atlasfont, cval); if (c) { + if (useEllipsis && x >= threshold && dot) + { + if (!dryRun) + { + AtlasCharVertex cv; + // Replace the following part with an ellipsis. + cv.x = x + dot->ox * scale; + cv.y = y + dot->oy * scale; + cv.c = dot; + char_one_line.push_back(cv); + cv.x += dot->wx * scale; + char_one_line.push_back(cv); + cv.x += dot->wx * scale; + char_one_line.push_back(cv); + } + skipRest = true; + break; + } if (!dryRun) { AtlasCharVertex cv; From 3867a774ba18020f57c586db98370878e91a7563 Mon Sep 17 00:00:00 2001 From: aquanull Date: Sat, 15 Jun 2013 21:10:49 +0800 Subject: [PATCH 47/51] Text spacing adjustments. --- Core/Util/ppge_atlas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Util/ppge_atlas.cpp b/Core/Util/ppge_atlas.cpp index 3cb9ebb50d..04bc2243f8 100644 --- a/Core/Util/ppge_atlas.cpp +++ b/Core/Util/ppge_atlas.cpp @@ -34620,7 +34620,7 @@ const AtlasCharRange font_UBUNTU24_ranges[] = { }; const AtlasFont font_UBUNTU24 = { 4.531250f, // padding - 35.562500f, // height + 31.562500f, // height 26.000000f, // ascend 0.750000f, // distslope font_UBUNTU24_chardata, From afdaa1e299ef3fd5157b46b57e840299cfde595e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Jun 2013 10:00:11 -0700 Subject: [PATCH 48/51] Write video images with zeroed alpha. Fixes #2277, Sword Art Online. --- Core/HW/MediaEngine.cpp | 87 +++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 9a348b0d1d..1b35a1f1dd 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -56,7 +56,6 @@ static AVPixelFormat getSwsFormat(int pspFormat) return AV_PIX_FMT_BGR444LE; case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: return AV_PIX_FMT_RGBA; - default: ERROR_LOG(ME, "Unknown pixel format"); return (AVPixelFormat)0; @@ -432,6 +431,46 @@ bool MediaEngine::stepVideo(int videoPixelMode) { #endif // USE_FFMPEG } +// Helpers that null out alpha (which seems to be the case on the PSP.) +// Some games depend on this, for example Sword Art Online (doesn't clear A's from buffer.) + +inline void writeVideoLineRGBA(void *destp, const void *srcp, int width) { + // TODO: Use SSE/NEON, investigate why AV_PIX_FMT_RGB0 does not work. + u32 *dest = (u32 *)destp; + const u32 *src = (u32 *)srcp; + + u32 mask = 0x00FFFFFF; + for (int i = 0; i < width; ++i) { + dest[i] = src[i] & mask; + } +} + +inline void writeVideoLineABGR5650(void *destp, const void *srcp, int width) { + memcpy(destp, srcp, width * sizeof(u16)); +} + +inline void writeVideoLineABGR5551(void *destp, const void *srcp, int width) { + // TODO: Use SSE/NEON. + u16 *dest = (u16 *)destp; + const u16 *src = (u16 *)srcp; + + u16 mask = 0x7FFF; + for (int i = 0; i < width; ++i) { + dest[i] = src[i] & mask; + } +} + +inline void writeVideoLineABGR4444(void *destp, const void *srcp, int width) { + // TODO: Use SSE/NEON. + u16 *dest = (u16 *)destp; + const u16 *src = (u16 *)srcp; + + u16 mask = 0x0FFF; + for (int i = 0; i < width; ++i) { + dest[i] = src[i] & mask; + } +} + int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode) { if ((!m_pFrame)||(!m_pFrameRGB)) return false; @@ -441,14 +480,12 @@ int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode) int height = m_desHeight; int width = m_desWidth; u8 *imgbuf = buffer; - u8 *data = m_pFrameRGB->data[0]; - u16 *imgbuf16 = (u16 *)buffer; - u16 *data16 = (u16 *)data; + const u8 *data = m_pFrameRGB->data[0]; switch (videoPixelMode) { case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: for (int y = 0; y < height; y++) { - memcpy(imgbuf, data, width * sizeof(u32)); + writeVideoLineRGBA(imgbuf, data, width); data += width * sizeof(u32); imgbuf += frameWidth * sizeof(u32); } @@ -457,7 +494,7 @@ int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode) case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: for (int y = 0; y < height; y++) { - memcpy(imgbuf, data, width * sizeof(u16)); + writeVideoLineABGR5650(imgbuf, data, width); data += width * sizeof(u16); imgbuf += frameWidth * sizeof(u16); } @@ -466,20 +503,18 @@ int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode) case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *imgbuf16++ = *data16++ | (1 << 15); - } - imgbuf16 += (frameWidth - width); + writeVideoLineABGR5551(imgbuf, data, width); + data += width * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); } videoImageSize = frameWidth * sizeof(u16) * height; break; case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *imgbuf16++ = *data16++ | (0xF << 12); - } - imgbuf16 += (frameWidth - width); + writeVideoLineABGR4444(imgbuf, data, width); + data += width * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); } videoImageSize = frameWidth * sizeof(u16) * height; break; @@ -501,9 +536,7 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP int videoImageSize = 0; // lock the image size u8 *imgbuf = buffer; - u8 *data = m_pFrameRGB->data[0]; - u16 *imgbuf16 = (u16 *)buffer; - u16 *data16 = (u16 *)data; + const u8 *data = m_pFrameRGB->data[0]; if (width > m_desWidth - xpos) width = m_desWidth - xpos; @@ -514,7 +547,7 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: data += (ypos * m_desWidth + xpos) * sizeof(u32); for (int y = 0; y < height; y++) { - memcpy(imgbuf, data, width * sizeof(u32)); + writeVideoLineRGBA(imgbuf, data, width); data += m_desWidth * sizeof(u32); imgbuf += frameWidth * sizeof(u32); } @@ -524,7 +557,7 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: data += (ypos * m_desWidth + xpos) * sizeof(u16); for (int y = 0; y < height; y++) { - memcpy(imgbuf, data, width * sizeof(u16)); + writeVideoLineABGR5650(imgbuf, data, width); data += m_desWidth * sizeof(u16); imgbuf += frameWidth * sizeof(u16); } @@ -534,11 +567,9 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: data += (ypos * m_desWidth + xpos) * sizeof(u16); for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *imgbuf16++ = *data16++ | (1 << 15); - } - imgbuf16 += (frameWidth - width); - data16 += (m_desWidth - width); + writeVideoLineABGR5551(imgbuf, data, width); + data += m_desWidth * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); } videoImageSize = frameWidth * sizeof(u16) * m_desHeight; break; @@ -546,11 +577,9 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: data += (ypos * m_desWidth + xpos) * sizeof(u16); for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *imgbuf16++ = *data16++ | (0xF << 12); - } - imgbuf16 += (frameWidth - width); - data16 += (m_desWidth - width); + writeVideoLineABGR4444(imgbuf, data, width); + data += m_desWidth * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); } videoImageSize = frameWidth * sizeof(u16) * m_desHeight; break; From 00e6873a301163dde968e2d39a992f2313b65d7b Mon Sep 17 00:00:00 2001 From: oioitff Date: Sun, 16 Jun 2013 01:35:47 +0800 Subject: [PATCH 49/51] Bug fix for scepsmf. --- Core/HLE/scePsmf.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 21c85a2e74..c7c1ab7448 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -246,13 +246,11 @@ Psmf::Psmf(u32 data) { u32 currentStreamAddr = data + 0x82 + i * 16; int streamId = Memory::Read_U8(currentStreamAddr); if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) { - stream = new PsmfStream(PSMF_AVC_STREAM, currentVideoStreamNum); + stream = new PsmfStream(PSMF_AVC_STREAM, ++currentVideoStreamNum); stream->readMPEGVideoStreamParams(currentStreamAddr, this); - currentVideoStreamNum++; } else if ((streamId & PSMF_AUDIO_STREAM_ID) == PSMF_AUDIO_STREAM_ID) { - stream = new PsmfStream(PSMF_ATRAC_STREAM, currentAudioStreamNum); + stream = new PsmfStream(PSMF_ATRAC_STREAM, ++currentAudioStreamNum); stream->readPrivateAudioStreamParams(currentStreamAddr, this); - currentAudioStreamNum++; } if (stream) { currentStreamNum++; @@ -452,8 +450,9 @@ u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, u32 streamType) } WARN_LOG(HLE, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType); int streamNum = 0; + int type = (streamType == PSMF_AUDIO_STREAM ? PSMF_ATRAC_STREAM : streamType); for (int i = psmf->streamMap.size() - 1; i >= 0; i--) { - if (psmf->streamMap[i]->type == streamType) + if (psmf->streamMap[i]->type == type) streamNum++; } return streamNum; From 9625f9047754914a8a32ae703f479756b04fb18a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Jun 2013 11:57:39 -0700 Subject: [PATCH 50/51] Previous on the left, next on the right. Stay consistent at least. Fixes #2282. --- UI/MenuScreens.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index efc124feb9..fa501091c9 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -729,12 +729,12 @@ void GraphicsScreenP1::render() { } HLinear hlinear(10, dp_yres - 10, 20.0f); - if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { - screenManager()->switchScreen(new GraphicsScreenP2()); - } if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { screenManager()->switchScreen(new GraphicsScreenP3()); } + if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { + screenManager()->switchScreen(new GraphicsScreenP2()); + } int x = 30; int y = 35; @@ -781,12 +781,12 @@ void GraphicsScreenP2::render() { } HLinear hlinear(10, dp_yres - 10, 20.0f); - if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { - screenManager()->switchScreen(new GraphicsScreenP3()); - } if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Prev Page"), ALIGN_BOTTOMLEFT)) { screenManager()->switchScreen(new GraphicsScreenP1()); } + if (UIButton(GEN_ID, hlinear, LARGE_BUTTON_WIDTH + 10, 0, g->T("Next Page"), ALIGN_BOTTOMLEFT)) { + screenManager()->switchScreen(new GraphicsScreenP3()); + } int x = 30; int y = 35; From f8365178531dddd1ea4536a24359b281980e1fe5 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 15 Jun 2013 23:54:47 +0200 Subject: [PATCH 51/51] MsgDialog: Have the text WRAP_WIDTH match the horizontal lines. Fixes #2288. --- Core/Dialog/PSPMsgDialog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index e1d4fb91ab..ce13c922d1 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -132,8 +132,9 @@ int PSPMsgDialog::Init(unsigned int paramAddr) void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo) { - const float WRAP_WIDTH = 480.0f; - float y = 136.0f, h; + const float WRAP_WIDTH = 450.0f; + float y = 136.0f; + float h; int n; PPGeMeasureText(0, &h, &n, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); float h2 = h * (float)n / 2.0f;