Merge branch 'master' of github.com:hrydgard/ppsspp

This commit is contained in:
Daniel Dressler 2013-06-15 18:37:08 -07:00
commit 0befec3358
34 changed files with 706 additions and 381 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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()
@ -132,8 +132,9 @@ int PSPMsgDialog::Init(unsigned int paramAddr)
void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo)
{
const float WRAP_WIDTH = 350.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;
@ -173,8 +174,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()

View File

@ -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

View File

@ -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<Thread>(threadHandle, error);
if (t)
u32 error;
Thread *t = kernelObjects.Get<Thread>(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;
}

View File

@ -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, 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++;
}
if (stream) {
currentStreamNum++;
@ -436,7 +434,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,18 +445,24 @@ 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);
return 1;
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 == type)
streamNum++;
}
return streamNum;
}
u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 channel)
{
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 +476,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,26 +495,26 @@ 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, "scePsmfGetNumberOfSpecificStreams - 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->videoWidth, videoInfoAddr + 4);
Memory::Write_U32(psmf->videoHeight, videoInfoAddr + 4);
}
return 0;
}
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(%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 +523,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 +543,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 +557,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 +566,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 +575,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 +589,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 +641,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 +655,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 +684,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 +704,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;
}
@ -715,7 +719,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 +740,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 +758,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 +776,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 +795,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 +841,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 +881,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 +914,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 +933,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 +942,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 +960,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 +985,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 +1002,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 +1019,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 +1045,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 +1059,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 +1098,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 +1115,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;

View File

@ -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;
@ -136,9 +135,20 @@ 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);
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;
@ -158,8 +168,15 @@ 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;
return mpeg->m_decodeNextPos;
}
#ifdef _DEBUG
@ -283,7 +300,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);
@ -414,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;
@ -423,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);
}
@ -439,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);
}
@ -448,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;
@ -483,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;
@ -496,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);
}
@ -506,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);
}
@ -516,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;
@ -528,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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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,12 +338,14 @@ 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) {
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;
@ -398,52 +354,175 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont,
for (UTF8 utf(text); !utf.end(); )
{
float lineWidth = 0;
bool skipRest = false;
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 utfWord(utf);
float nextWidth = 0;
float spaceWidth = 0;
int numChars = 0;
bool finished = false;
while (!utfWord.end() && !finished)
{
if (wrapType > 0)
{
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;
UTF8 utfPrev = utfWord;
u32 cval = utfWord.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:
{
// 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;
}
}
if (wrapType & PPGE_LINE_USE_ELLIPSIS) {
if (nextWidth >= wrapCutoff) {
// TODO: Truncate the word with an ellipsis.
// The word is not too short.
}
}
}
}
++numChars;
nextWidth += ch->wx * scale;
break;
}
}
bool useEllipsis = false;
if (wrapType > 0)
{
if (lineWidth + nextWidth > wrapWidth || skipRest)
{
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) {
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;
}
}
}
for (int i = 0; i < numChars; ++i)
{
u32 cval = utf.next();
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;
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 = utfWord;
}
y += lineHeight;
x = sx;

View File

@ -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,
@ -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"},
};

View File

@ -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 && 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 = true;
} 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;

View File

@ -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);

View File

@ -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

View File

@ -178,9 +178,17 @@ 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...
UpdateGamepad(input);
// Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux...
// TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms?
#ifdef _WIN32
if(g_Config.bShowTouchControls) {
#endif
UpdateGamepad(input);
UpdateInputState(&input);
UpdateInputState(&input);
#ifdef _WIN32
}
#endif
// Then translate pad input into PSP pad input. Also, add in tilt.
static const int mapping[12][2] = {

View File

@ -269,6 +269,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);
@ -462,38 +469,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);
}
@ -653,7 +656,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 : "";
}
@ -709,14 +712,14 @@ 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);
}
#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());
}
@ -814,8 +817,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) , 0xFFFFFFFF, ALIGN_LEFT);
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))
@ -826,35 +831,50 @@ 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);
char showType[256];
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 + 250, 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, 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;
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 + 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))
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();
}
@ -888,50 +908,51 @@ 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);
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;}
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 + 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))
if(g_Config.iFpsLimit > 30)
g_Config.iFpsLimit -= 1;
if (UIButton(GEN_ID, hlinear1, 40, 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;
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 {
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;
ui_draw2d.DrawText(UBUNTU24, showFrameSkip, x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT);
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))
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;
UIEnd();
}
@ -1077,7 +1098,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)) {
@ -1357,19 +1378,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",

View File

@ -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;
}

View File

@ -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);

View File

@ -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 <tchar.h>
#include <process.h>
#include <intrin.h>
#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;
}

View File

@ -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();
void EmuThread_Stop();
bool EmuThread_Ready();

View File

@ -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));
@ -214,18 +222,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 +252,23 @@ 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);
hideCursor = 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;
@ -304,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;
@ -324,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;
@ -341,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;
@ -423,12 +452,22 @@ 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:
{
if (!EmuThread_Ready())
return DefWindowProc(hWnd, message, wParam, lParam);
I18NCategory *g = GetI18NCategory("Graphics");
wmId = LOWORD(wParam);
@ -714,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);
@ -735,6 +779,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,24 +807,19 @@ 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:
KillTimer(hWnd, TIMER_CURSORUPDATE);
KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
PostQuitMessage(0);
break;

View File

@ -64,9 +64,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
hideLog = false;
#endif
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 +86,15 @@ 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(""));
//Windows, API init stuff
INITCOMMONCONTROLSEX comm;
comm.dwSize = sizeof(comm);
@ -97,15 +103,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 +118,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();

Binary file not shown.

Binary file not shown.

2
ffmpeg

@ -1 +1 @@
Subproject commit 697244c4b79b396de86e5d7fdbf9bc4771b815e9
Subproject commit 969f062d319ab9e3d341c6e661eedd51eefa50a2

2
lang

@ -1 +1 @@
Subproject commit 9a59b4db25598d735eb1ef365b6e69bff3f3e080
Subproject commit cf710f2017db93c4019ce53a03764edf3136fa84

2
native

@ -1 +1 @@
Subproject commit ce962bdf95717c52f29c211b6b242f899dcb9174
Subproject commit 5d098ca88bd11f0af09c95c9e91166fb82faa07b