From 48498656eaeff231f0d1c3fefa9b39c04e05c7b9 Mon Sep 17 00:00:00 2001 From: The Dax Date: Mon, 17 Jun 2013 19:55:43 -0400 Subject: [PATCH 01/46] Fix possible savestate/shutdown issue. --- Core/HLE/sceUtility.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index be75779fcc..8253876bff 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -72,6 +72,7 @@ void __UtilityDoState(PointerWrap &p) msgDialog.DoState(p); oskDialog.DoState(p); netDialog.DoState(p); + screenshotDialog.DoState(p); p.Do(currentlyLoadedModules); p.DoMarker("sceUtility"); } @@ -82,6 +83,7 @@ void __UtilityShutdown() msgDialog.Shutdown(true); oskDialog.Shutdown(true); netDialog.Shutdown(true); + screenshotDialog.Shutdown(true); } int __UtilityGetStatus() From e5202cebda7c2ff82ed6468a801be4dcf5fc70ea Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 18 Jun 2013 09:45:13 +0800 Subject: [PATCH 02/46] Toggle to adjust opacity in UI Controls --- UI/MenuScreens.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index ba70798f84..d0499a170a 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1134,6 +1134,21 @@ void ControlsScreen::render() { bool bTransparent = g_Config.iTouchButtonOpacity < 30; bool prev = bTransparent; UICheckBox(GEN_ID, x, y += stride, c->T("Transparent Buttons"), ALIGN_TOPLEFT, &bTransparent); + if (bTransparent) { + char opacity[256]; + sprintf(opacity, "%s %d", c->T("Opacity :"), g_Config.iTouchButtonOpacity); + ui_draw2d.DrawText(UBUNTU24, opacity, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 250, y, 20); + if (UIButton(GEN_ID, hlinear1, 80, 0, c->T("Auto"), ALIGN_LEFT)) + g_Config.iTouchButtonOpacity = 15; + if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("-1"), ALIGN_LEFT)) + if (g_Config.iTouchButtonOpacity > 15) + g_Config.iTouchButtonOpacity -= 1; + if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("+1"), ALIGN_LEFT)) + if (g_Config.iTouchButtonOpacity < 30) + g_Config.iTouchButtonOpacity += 1; + y += 20; + } if (bTransparent != prev) g_Config.iTouchButtonOpacity = bTransparent ? 15 : 65; } From cf790de2ce64ef2560aebddeb795d288a52469e6 Mon Sep 17 00:00:00 2001 From: The Dax Date: Mon, 17 Jun 2013 23:37:36 -0400 Subject: [PATCH 03/46] Switch handlers from std::vector to std::map, add a max handler count, and return an error if too many handlers exist. --- Core/HLE/sceNet.cpp | 51 ++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index bca7fac1df..2ecba10ec0 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -28,6 +28,9 @@ static bool netAdhocInited; static u32 adhocctlHandlerCount; +// TODO: Determine how many handlers we can actually have +const u32 MAX_ADHOCCTL_HANDLERS = 32; + enum { ERROR_NET_BUFFER_TOO_SMALL = 0x80400706, @@ -78,18 +81,17 @@ struct SceNetMallocStat { static struct SceNetMallocStat netMallocStat; -struct AdhocctlHandler -{ +struct AdhocctlHandler { u32 entryPoint; u32 argument; - u32 id; }; -static std::vector adhocctlHandlers; +static std::map adhocctlHandlers; void __NetInit() { netInited = false; netAdhocInited = false; + memset(&netMallocStat, 0, sizeof(netMallocStat)); } void __NetShutdown() { @@ -98,12 +100,13 @@ void __NetShutdown() { void __UpdateAdhocctlHandlers(int flag, int error) { u32 args[3] = { 0, 0, 0 }; - for(std::vector::iterator it = adhocctlHandlers.begin(); it < adhocctlHandlers.end(); it++) { + + for(std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { args[0] = flag; args[1] = error; - args[2] = it->argument; + args[2] = it->second.argument; - __KernelDirectMipsCall(it->entryPoint, NULL, args, 3, true); + __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true); } } @@ -121,12 +124,11 @@ void __NetDoState(PointerWrap &p) { void sceNetInit() { ERROR_LOG(HLE,"UNIMPL sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d)", PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); netInited = true; - memset(&netMallocStat, 0, sizeof(netMallocStat)); netMallocStat.maximum = PARAM(0); netMallocStat.free = PARAM(0); netMallocStat.pool = 0; - RETURN(0); //ERROR <- The Dax: Why is it an error when it returns 0 on success? + RETURN(0); } u32 sceNetTerm() { @@ -172,29 +174,35 @@ u32 sceWlanGetSwitchState() { // TODO: Should we allow the same handler to be added more than once? u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { bool foundHandler = false; + u32 retval = adhocctlHandlerCount; struct AdhocctlHandler handler; memset(&handler, 0, sizeof(handler)); + handler.entryPoint = handlerPtr; handler.argument = handlerArg; - handler.id = -1; - for(std::vector::iterator it = adhocctlHandlers.begin(); it < adhocctlHandlers.end(); it++) { - if(it->entryPoint == handlerPtr) { + for(std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); it++) { + if(it->second.entryPoint == handlerPtr) { foundHandler = true; break; } } if(!foundHandler && Memory::IsValidAddress(handlerPtr)) { - handler.id = adhocctlHandlerCount > 0? ++adhocctlHandlerCount : 0; - adhocctlHandlers.push_back(handler); - WARN_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, handler.id); + if(adhocctlHandlerCount >= MAX_ADHOCCTL_HANDLERS) { + ERROR_LOG(HLE, "UNTESTED UNTESTED sceNetAdhocctlAddHandler(%x, %x): Too many handlers", handlerPtr, handlerArg); + retval = ERROR_NET_ADHOCCTL_TOO_MANY_HANDLERS; + return retval; + } + adhocctlHandlers[adhocctlHandlerCount++] = handler; + WARN_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, adhocctlHandlerCount); } else ERROR_LOG(HLE, "UNTESTED sceNetAdhocctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg); - return handler.id; + // The id to return is the number of handlers currently registered + return retval; } u32 sceNetAdhocctlDisconnect() { @@ -205,9 +213,14 @@ u32 sceNetAdhocctlDisconnect() { } u32 sceNetAdhocctlDelHandler(u32 handlerID) { - WARN_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%x)", handlerID); - adhocctlHandlers.erase(adhocctlHandlers.begin() + handlerID); - adhocctlHandlerCount = adhocctlHandlerCount > 0? --adhocctlHandlerCount : adhocctlHandlerCount; + + if(adhocctlHandlers.find(handlerID) != adhocctlHandlers.end()) { + adhocctlHandlers.erase(handlerID); + adhocctlHandlerCount = adhocctlHandlerCount > 0? --adhocctlHandlerCount : 0; + WARN_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%d): deleted handler %d", handlerID, handlerID); + } + else + ERROR_LOG(HLE, "UNTESTED sceNetAdhocctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID); return 0; } From 97943bfbc357ba1c2020b3a6cb6efbfbb4109797 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 17 Jun 2013 22:37:35 -0700 Subject: [PATCH 04/46] Buildfix. Fixes #2337. --- Core/Config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/Config.h b/Core/Config.h index c0a991525e..03c91d4f06 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -125,6 +125,7 @@ public: bool bWlanPowerSave; std::string currentDirectory; + std::string externalDirectory; std::string memCardDirectory; std::string flashDirectory; std::string internalDataDirectory; From 7adb16e3ac097d3555845facd241c2fe893a1198 Mon Sep 17 00:00:00 2001 From: oioitff Date: Tue, 18 Jun 2013 13:55:15 +0800 Subject: [PATCH 05/46] Bug fix for sceAtrac. --- Core/HLE/sceAtrac.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index ba320148bc..3f3ea5175f 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -339,6 +339,7 @@ int createAtrac(Atrac *atrac, int codecType) { for (int i = 0; i < (int)ARRAY_SIZE(atracIDs); ++i) { if (atracIDTypes[i] == codecType && atracIDs[i] == 0) { atracIDs[i] = atrac; + atrac->atracID = i; return i; } } @@ -483,7 +484,7 @@ void Atrac::Analyze() } u32 sceAtracGetAtracID(int codecType) { - if (codecType != PSP_MODE_AT_3 && codecType > PSP_MODE_AT_3_PLUS) { + if (codecType != PSP_MODE_AT_3 && codecType != PSP_MODE_AT_3_PLUS) { ERROR_LOG_REPORT(HLE, "sceAtracGetAtracID(%i): invalid codecType", codecType); return ATRAC_ERROR_INVALID_CODECTYPE; } From f0c7c8538faaf164c05d1d5b7af516df52bc05ec Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 18 Jun 2013 14:03:49 +0800 Subject: [PATCH 06/46] Adjust by +5/-5 , relaod cheat show only when enabled cheat --- UI/MenuScreens.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index d0499a170a..ee694fe3fa 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1094,13 +1094,16 @@ void SystemScreen::render() { g_Config.itimeformat = tf ? 1 : 0; } 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 + 50, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT)) { - g_Config.bReloadCheats = true; + if (g_Config.bEnableCheats) { + HLinear hlinear1(x + 60, y += stride + 10, 20); + if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH + 50, 0, s->T("Reload Cheats"), ALIGN_TOPLEFT)) + g_Config.bReloadCheats = true; + y += 10; } + HLinear hlinear2(x, y += stride + 10, 20); if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, s->T("Language"), ALIGN_TOPLEFT)) { screenManager()->push(new LanguageScreen()); - } + } UIEnd(); } @@ -1131,7 +1134,7 @@ void ControlsScreen::render() { UICheckBox(GEN_ID, x, y += stride, c->T("Large Controls"), ALIGN_TOPLEFT, &g_Config.bLargeControls); UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); // This will be a slider in the new UI later - bool bTransparent = g_Config.iTouchButtonOpacity < 30; + bool bTransparent = g_Config.iTouchButtonOpacity < 65; bool prev = bTransparent; UICheckBox(GEN_ID, x, y += stride, c->T("Transparent Buttons"), ALIGN_TOPLEFT, &bTransparent); if (bTransparent) { @@ -1141,12 +1144,12 @@ void ControlsScreen::render() { HLinear hlinear1(x + 250, y, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, c->T("Auto"), ALIGN_LEFT)) g_Config.iTouchButtonOpacity = 15; - if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("-1"), ALIGN_LEFT)) + if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("-5"), ALIGN_LEFT)) if (g_Config.iTouchButtonOpacity > 15) - g_Config.iTouchButtonOpacity -= 1; - if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("+1"), ALIGN_LEFT)) - if (g_Config.iTouchButtonOpacity < 30) - g_Config.iTouchButtonOpacity += 1; + g_Config.iTouchButtonOpacity -= 5; + if (UIButton(GEN_ID, hlinear1, 40, 0, c->T("+5"), ALIGN_LEFT)) + if (g_Config.iTouchButtonOpacity < 65) + g_Config.iTouchButtonOpacity += 5; y += 20; } if (bTransparent != prev) From 926e1ebddc5b983cd178cbbb0ed85b51b0d931ae Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Jun 2013 00:31:15 -0700 Subject: [PATCH 07/46] Keep EmuThread running on game shutdown. Especially relevant for games that call sceKernelExitGame(), like most homebrew. Otherwise, EmuThread actually quits and we can't continue. --- Core/System.h | 1 + Windows/EmuThread.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Core/System.h b/Core/System.h index 9ed6e7bbd9..9ddcb2a8d5 100644 --- a/Core/System.h +++ b/Core/System.h @@ -32,6 +32,7 @@ enum GlobalUIState { UISTATE_MENU, UISTATE_PAUSEMENU, UISTATE_INGAME, + UISTATE_EXIT, }; diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 76ba989006..cb0be4f817 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -67,6 +67,7 @@ void EmuThread_Start() void EmuThread_Stop() { + globalUIState = UISTATE_EXIT; // DSound_UpdateSound(); Core_Stop(); Core_WaitInactive(800); @@ -137,7 +138,14 @@ unsigned int WINAPI TheThread(void *) Core_EnableStepping(FALSE); - Core_Run(); + while (globalUIState != UISTATE_EXIT) + { + Core_Run(); + + // We're here again, so the game quit. Restart Core_Run() which controls the UI. + // This way they can load a new game. + Core_UpdateState(CORE_RUNNING); + } shutdown: _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); From ab545a1cf0068b4c86d360cba7bb5c882696cd22 Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 18 Jun 2013 18:37:34 +0900 Subject: [PATCH 08/46] Toggle to adjust on-screen buttons scaling --- Core/Config.cpp | 3 ++- Core/Config.h | 1 + UI/GamepadEmu.cpp | 2 +- UI/MenuScreens.cpp | 17 ++++++++++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 8ecbb5ff8b..dc273895b3 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -138,6 +138,7 @@ void Config::Load(const char *iniFileName) control->Get("ForceInputDevice", &iForceInputDevice, -1); control->Get("RightStickBind", &iRightStickBind, 0); control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65); + control->Get("ButtonScale", &fButtonScale, 1.15); IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Get("NickName", &sNickName, "shadow"); @@ -232,7 +233,7 @@ void Config::Save() control->Set("ForceInputDevice", iForceInputDevice); control->Set("RightStickBind", iRightStickBind); control->Set("TouchButtonOpacity", iTouchButtonOpacity); - + control->Set("ButtonScale", fButtonScale); IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Set("NickName", sNickName.c_str()); diff --git a/Core/Config.h b/Core/Config.h index 03c91d4f06..7fbd525e65 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -110,6 +110,7 @@ public: std::map iMappingMap; // Can be used differently depending on systems int iForceInputDevice; int iTouchButtonOpacity; + float fButtonScale; // SystemParam std::string sNickName; diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index eab63aebd5..c8362b11b8 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -40,7 +40,7 @@ TouchStick leftStick(&ui_atlas, I_STICKBG, I_STICK, 0); void LayoutGamepad(int w, int h) { - float controlScale = g_Config.bLargeControls ? 1.6 : 1.15; + float controlScale = g_Config.bLargeControls ? g_Config.fButtonScale : 1.15; const int button_spacing = 50 * controlScale; const int arrow_spacing = 40 * controlScale; diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index ee694fe3fa..03c5a767d4 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1131,7 +1131,22 @@ void ControlsScreen::render() { UICheckBox(GEN_ID, x, y += stride, c->T("OnScreen", "On-Screen Touch Controls"), ALIGN_TOPLEFT, &g_Config.bShowTouchControls); if (g_Config.bShowTouchControls) { - UICheckBox(GEN_ID, x, y += stride, c->T("Large Controls"), ALIGN_TOPLEFT, &g_Config.bLargeControls); + UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Scaling"), ALIGN_TOPLEFT, &g_Config.bLargeControls); + if (g_Config.bLargeControls) { + char scale[256]; + sprintf(scale, "%s %0.2f", c->T("Scale :"), g_Config.fButtonScale); + ui_draw2d.DrawText(UBUNTU24, scale, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 250, y, 20); + if (UIButton(GEN_ID, hlinear1, 80, 0, c->T("Auto"), ALIGN_LEFT)) + g_Config.fButtonScale = 1.15; + if (UIButton(GEN_ID, hlinear1, 60, 0, c->T("-0.1"), ALIGN_LEFT)) + if (g_Config.fButtonScale > 1.15) + g_Config.fButtonScale -= 0.1; + if (UIButton(GEN_ID, hlinear1, 60, 0, c->T("+0.1"), ALIGN_LEFT)) + if (g_Config.fButtonScale < 2.05) + g_Config.fButtonScale += 0.1; + y += 20; + } UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); // This will be a slider in the new UI later bool bTransparent = g_Config.iTouchButtonOpacity < 65; From ec0f72541856c364aa13fd5f2e3ca72d429013f7 Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 18 Jun 2013 18:11:47 +0800 Subject: [PATCH 09/46] Add multple save/load slot in UI Pause Menu --- UI/MenuScreens.cpp | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 03c5a767d4..1f36a08dcf 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -489,16 +489,52 @@ void PauseScreen::render() { } 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, 0, i->T("Save State"), ALIGN_LEFT)) { + ui_draw2d.DrawText(UBUNTU24, gs->T("Save State :"), 30, 360, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear4(x + 180 , y += 50, 10); + if (UIButton(GEN_ID, hlinear4, 30, 0, "1", ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, i->T("Load State"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 30, 0, "2", ALIGN_LEFT)) { + SaveState::SaveSlot(1, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear4, 30, 0, "3", ALIGN_LEFT)) { + SaveState::SaveSlot(2, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear4, 30, 0, "4", ALIGN_LEFT)) { + SaveState::SaveSlot(3, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear4, 30, 0, "5", ALIGN_LEFT)) { + SaveState::SaveSlot(4, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + + + ui_draw2d.DrawText(UBUNTU24, gs->T("Load State :"), 30, 420, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear3(x + 180 , y += 60, 10); + if (UIButton(GEN_ID, hlinear3, 30, 0, "1", ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } + if (UIButton(GEN_ID, hlinear3, 30, 0, "2", ALIGN_LEFT)) { + SaveState::LoadSlot(1, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear3, 30, 0, "3", ALIGN_LEFT)) { + SaveState::LoadSlot(2, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear3, 30, 0, "4", ALIGN_LEFT)) { + SaveState::LoadSlot(3, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } + if (UIButton(GEN_ID, hlinear3, 30, 0, "5", ALIGN_LEFT)) { + SaveState::LoadSlot(4, 0, 0); + screenManager()->finishDialog(this, DR_CANCEL); + } DrawWatermark(); UIEnd(); From 4266db8a294f1a64ec0618c6e9f0ef49033386c5 Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 18 Jun 2013 21:17:53 +0800 Subject: [PATCH 10/46] Set width to 60 --- UI/MenuScreens.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 1f36a08dcf..dbcc1b3b84 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -491,23 +491,23 @@ void PauseScreen::render() { ui_draw2d.DrawText(UBUNTU24, gs->T("Save State :"), 30, 360, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear4(x + 180 , y += 50, 10); - if (UIButton(GEN_ID, hlinear4, 30, 0, "1", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 60, 0, "1", ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear4, 30, 0, "2", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 60, 0, "2", ALIGN_LEFT)) { SaveState::SaveSlot(1, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear4, 30, 0, "3", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 60, 0, "3", ALIGN_LEFT)) { SaveState::SaveSlot(2, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear4, 30, 0, "4", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 60, 0, "4", ALIGN_LEFT)) { SaveState::SaveSlot(3, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear4, 30, 0, "5", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear4, 60, 0, "5", ALIGN_LEFT)) { SaveState::SaveSlot(4, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } @@ -515,23 +515,23 @@ void PauseScreen::render() { ui_draw2d.DrawText(UBUNTU24, gs->T("Load State :"), 30, 420, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear3(x + 180 , y += 60, 10); - if (UIButton(GEN_ID, hlinear3, 30, 0, "1", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear3, 60, 0, "1", ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear3, 30, 0, "2", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear3, 60, 0, "2", ALIGN_LEFT)) { SaveState::LoadSlot(1, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear3, 30, 0, "3", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear3, 60, 0, "3", ALIGN_LEFT)) { SaveState::LoadSlot(2, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear3, 30, 0, "4", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear3, 60, 0, "4", ALIGN_LEFT)) { SaveState::LoadSlot(3, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } - if (UIButton(GEN_ID, hlinear3, 30, 0, "5", ALIGN_LEFT)) { + if (UIButton(GEN_ID, hlinear3, 60, 0, "5", ALIGN_LEFT)) { SaveState::LoadSlot(4, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } From 45775d4fc2d3e60805048eaaaf68e525a7866421 Mon Sep 17 00:00:00 2001 From: Sacha Date: Wed, 19 Jun 2013 01:14:14 +1000 Subject: [PATCH 11/46] Fix for non-ffmpeg platforms. Thanks unknownbrackets! Can now get past videos on platforms such as Meego and Symbian. Also fix some spacing and type issues. --- Common/ArmCPUDetect.cpp | 4 ++-- Core/HW/MediaEngine.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index 5d3a69669d..50ed3228bd 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -128,8 +128,8 @@ void CPUInfo::Detect() // Get the information about the CPU num_cores = GetCoreCount(); #if defined(__SYMBIAN32__) || defined(BLACKBERRY) || defined(IOS) -bool isVFP3 = false; -bool isVFP4 = false; + bool isVFP3 = false; + bool isVFP4 = false; #ifdef IOS isVFP3 = true; // TODO: Check for swift arch (VFP4) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 1b35a1f1dd..62eea7b2cc 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -369,13 +369,13 @@ void MediaEngine::updateSwsFormat(int videoPixelMode) { } bool MediaEngine::stepVideo(int videoPixelMode) { + // if video engine is broken, force to add timestamp + m_videopts += 3003; + if (!m_pFormatCtx) return false; if (!m_pCodecCtx) return false; - - // if video engine is broken, force to add timestamp - m_videopts += 3003; #ifdef USE_FFMPEG updateSwsFormat(videoPixelMode); // TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf. @@ -525,7 +525,7 @@ int MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode) } return videoImageSize; #endif // USE_FFMPEG - return true; + return 0; } int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode, @@ -590,7 +590,7 @@ int MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int videoP } return videoImageSize; #endif // USE_FFMPEG - return true; + return 0; } static bool isHeader(u8* audioStream, int offset) From 933c8abb55ab150ddd616dd9161d1fcd8d7540a9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Jun 2013 23:54:29 -0700 Subject: [PATCH 12/46] Check kernel object types when looking up ids. Some games misuse it, need to return an error. --- Core/HLE/sceIo.cpp | 2 ++ Core/HLE/sceKernel.h | 14 +++++++------- Core/HLE/sceKernelAlarm.cpp | 1 + Core/HLE/sceKernelEventFlag.cpp | 1 + Core/HLE/sceKernelMbx.cpp | 1 + Core/HLE/sceKernelMemory.cpp | 4 ++++ Core/HLE/sceKernelModule.cpp | 3 ++- Core/HLE/sceKernelMsgPipe.cpp | 1 + Core/HLE/sceKernelMutex.cpp | 2 ++ Core/HLE/sceKernelSemaphore.cpp | 1 + Core/HLE/sceKernelThread.cpp | 3 ++- Core/HLE/sceKernelVTimer.cpp | 1 + 12 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 3a4204acc5..d8ea2fb328 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -158,6 +158,7 @@ public: sprintf(ptr, "Seekpos: %08x", (u32)pspFileSystem.GetSeekPos(handle)); } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; } + static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_File; } int GetIDType() const { return PPSSPP_KERNEL_TMID_File; } virtual void DoState(PointerWrap &p) { @@ -1441,6 +1442,7 @@ public: const char *GetName() {return name.c_str();} const char *GetTypeName() {return "DirListing";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; } + static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_DirList; } int GetIDType() const { return PPSSPP_KERNEL_TMID_DirList; } virtual void DoState(PointerWrap &p) { diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 53a3b54114..7c0c1e270d 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -404,6 +404,7 @@ public: // Implement this in all subclasses: // static u32 GetMissingErrorCode() + // static int GetStaticIDType() virtual void DoState(PointerWrap &p) { @@ -443,7 +444,7 @@ public: if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset]) { ERROR_LOG(HLE, "Kernel: Bad object handle %i (%08x)", handle, handle); - outError = T::GetMissingErrorCode(); // ? + outError = T::GetMissingErrorCode(); return 0; } else @@ -452,10 +453,10 @@ public: // it just acted as a static case and everything worked. This means that we will never // see the Wrong type object error below, but we'll just have to live with that danger. T* t = static_cast(pool[handle - handleOffset]); - if (t == 0) + if (t == 0 || t->GetIDType() != T::GetStaticIDType()) { - ERROR_LOG(HLE, "Kernel: Wrong type object %i (%08x)", handle, handle); - outError = T::GetMissingErrorCode(); //FIX + ERROR_LOG(HLE, "Kernel: Wrong object type for %i (%08x)", handle, handle); + outError = T::GetMissingErrorCode(); return 0; } outError = SCE_KERNEL_ERROR_OK; @@ -477,8 +478,9 @@ public: } template - void Iterate(bool func(T *, ArgT), ArgT arg, int type) + void Iterate(bool func(T *, ArgT), ArgT arg) { + int type = T::GetStaticIDType(); for (int i = 0; i < maxCount; i++) { if (!occupied[i]) @@ -491,8 +493,6 @@ public: } } - static u32 GetMissingErrorCode() { return -1; } // TODO - bool GetIDType(SceUID handle, int *type) const { if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset]) diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index fdb19b991a..017155f9c5 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -40,6 +40,7 @@ struct Alarm : public KernelObject const char *GetName() {return "[Alarm]";} const char *GetTypeName() {return "Alarm";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_ALMID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Alarm; } int GetIDType() const { return SCE_KERNEL_TMID_Alarm; } virtual void DoState(PointerWrap &p) diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 61bc8add63..a5609a0078 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -64,6 +64,7 @@ public: static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_EVFID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_EventFlag; } int GetIDType() const { return SCE_KERNEL_TMID_EventFlag; } virtual void DoState(PointerWrap &p) diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index bd01e096eb..7548039ebc 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -53,6 +53,7 @@ struct Mbx : public KernelObject const char *GetName() {return nmb.name;} const char *GetTypeName() {return "Mbx";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MBXID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Mbox; } int GetIDType() const { return SCE_KERNEL_TMID_Mbox; } void AddWaitingThread(SceUID id, u32 addr) diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index a584cd697d..753fe8b393 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -72,6 +72,7 @@ struct FPL : public KernelObject const char *GetName() {return nf.name;} const char *GetTypeName() {return "FPL";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_FPLID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Fpl; } int GetIDType() const { return SCE_KERNEL_TMID_Fpl; } int findFreeBlock() { @@ -133,6 +134,7 @@ struct VPL : public KernelObject const char *GetName() {return nv.name;} const char *GetTypeName() {return "VPL";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VPLID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Vpl; } int GetIDType() const { return SCE_KERNEL_TMID_Vpl; } VPL() : alloc(8) {} @@ -424,6 +426,7 @@ public: sprintf(ptr, "MemPart: %08x - %08x size: %08x", address, address + sz, sz); } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_UID; } + static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_PMB; } int GetIDType() const { return PPSSPP_KERNEL_TMID_PMB; } PartitionMemoryBlock(BlockAllocator *_alloc, const char *_name, u32 size, MemblockType type, u32 alignment) @@ -1331,6 +1334,7 @@ struct TLS : public KernelObject const char *GetName() {return ntls.name;} const char *GetTypeName() {return "TLS";} static u32 GetMissingErrorCode() { return PSP_ERROR_UNKNOWN_TLS_ID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Tls; } int GetIDType() const { return SCE_KERNEL_TMID_Tls; } TLS() : next(0) {} diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index c4e14f637c..d18392ae43 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -179,6 +179,7 @@ public: nm.entry_addr); } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MODULE; } + static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_Module; } int GetIDType() const { return PPSSPP_KERNEL_TMID_Module; } virtual void DoState(PointerWrap &p) @@ -1349,7 +1350,7 @@ u32 sceKernelGetModuleIdByAddress(u32 moduleAddr) state.addr = moduleAddr; state.result = SCE_KERNEL_ERROR_UNKNOWN_MODULE; - kernelObjects.Iterate(&__GetModuleIdByAddressIterator, &state, PPSSPP_KERNEL_TMID_Module); + kernelObjects.Iterate(&__GetModuleIdByAddressIterator, &state); if (state.result == SCE_KERNEL_ERROR_UNKNOWN_MODULE) ERROR_LOG(HLE, "sceKernelGetModuleIdByAddress(%08x): module not found", moduleAddr) else diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 9e25cba658..8932ebda96 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -55,6 +55,7 @@ struct MsgPipe : public KernelObject const char *GetName() {return nmp.name;} const char *GetTypeName() {return "MsgPipe";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MPPID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Mpipe; } int GetIDType() const { return SCE_KERNEL_TMID_Mpipe; } MsgPipe() : buffer(NULL) {} diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 3c63eb960f..cfe1e2bca8 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -64,6 +64,7 @@ struct Mutex : public KernelObject const char *GetName() {return nm.name;} const char *GetTypeName() {return "Mutex";} static u32 GetMissingErrorCode() { return PSP_MUTEX_ERROR_NO_SUCH_MUTEX; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Mutex; } int GetIDType() const { return SCE_KERNEL_TMID_Mutex; } virtual void DoState(PointerWrap &p) @@ -125,6 +126,7 @@ struct LwMutex : public KernelObject const char *GetName() {return nm.name;} const char *GetTypeName() {return "LwMutex";} static u32 GetMissingErrorCode() { return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_LwMutex; } int GetIDType() const { return SCE_KERNEL_TMID_LwMutex; } virtual void DoState(PointerWrap &p) diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 1432711516..0e7caa2835 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -57,6 +57,7 @@ struct Semaphore : public KernelObject const char *GetTypeName() {return "Semaphore";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_SEMID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Semaphore; } int GetIDType() const { return SCE_KERNEL_TMID_Semaphore; } virtual void DoState(PointerWrap &p) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 942ce0bd6f..5b19d4ed72 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -82,6 +82,7 @@ public: } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_CBID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_Callback; } int GetIDType() const { return SCE_KERNEL_TMID_Callback; } virtual void DoState(PointerWrap &p) @@ -295,7 +296,7 @@ public: } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; } - + static int GetStaticIDType() { return SCE_KERNEL_TMID_Thread; } int GetIDType() const { return SCE_KERNEL_TMID_Thread; } bool AllocateStack(u32 &stackSize) diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index c8515723a9..ca25ba8af1 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -42,6 +42,7 @@ struct VTimer : public KernelObject { const char *GetName() {return nvt.name;} const char *GetTypeName() {return "VTimer";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VTID; } + static int GetStaticIDType() { return SCE_KERNEL_TMID_VTimer; } int GetIDType() const { return SCE_KERNEL_TMID_VTimer; } virtual void DoState(PointerWrap &p) { From ee2a99adee6034b3be79d0a081cdea7a671a8fdb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Jun 2013 23:58:52 -0700 Subject: [PATCH 13/46] Correctly read 48-bit pts in scePsmf as well. Attempt to fix #2347. --- 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 c7c1ab7448..651f2b4834 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -231,8 +231,8 @@ Psmf::Psmf(u32 data) { streamOffset = bswap32(Memory::Read_U32(data + 8)); streamSize = bswap32(Memory::Read_U32(data + 12)); streamDataTotalSize = bswap32(Memory::Read_U32(data + 0x50)); - presentationStartTime = bswap32(Memory::Read_U32(data + PSMF_FIRST_TIMESTAMP_OFFSET)); - presentationEndTime = bswap32(Memory::Read_U32(data + PSMF_LAST_TIMESTAMP_OFFSET)); + presentationStartTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_FIRST_TIMESTAMP_OFFSET)); + presentationEndTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_LAST_TIMESTAMP_OFFSET)); streamDataNextBlockSize = bswap32(Memory::Read_U32(data + 0x6A)); streamDataNextInnerBlockSize = bswap32(Memory::Read_U32(data + 0x7C)); numStreams = bswap16(Memory::Read_U16(data + 0x80)); From de4d970ab60d5ab062aad3cffabff8a46633d8cd Mon Sep 17 00:00:00 2001 From: raven02 Date: Wed, 19 Jun 2013 13:08:29 +0800 Subject: [PATCH 14/46] Toggle to adjust VPS/FPS/Both , new timeFormat/dateFormat/buttonPerference --- Core/Config.cpp | 12 ++-- Core/Config.h | 7 +- Core/Dialog/PSPSaveDialog.cpp | 55 +++++++++++----- Core/HLE/sceDisplay.cpp | 2 +- Core/HLE/sceUtility.cpp | 4 +- Core/Reporting.cpp | 2 +- UI/EmuScreen.cpp | 11 +++- UI/MenuScreens.cpp | 119 +++++++++++++++++++++++++++++----- Windows/WndMainWindow.cpp | 4 +- headless/Headless.cpp | 4 +- 10 files changed, 168 insertions(+), 52 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index dc273895b3..93461ec9a8 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -87,7 +87,7 @@ void Config::Load(const char *iniFileName) cpu->Get("FastMemory", &bFastMemory, false); IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics"); - graphics->Get("ShowFPSCounter", &bShowFPSCounter, false); + graphics->Get("ShowFPSCounter", &iShowFPSCounter, false); graphics->Get("DisplayFramebuffer", &bDisplayFramebuffer, false); #ifdef _WIN32 graphics->Get("ResolutionScale", &iWindowZoom, 2); @@ -143,11 +143,11 @@ void Config::Load(const char *iniFileName) IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Get("NickName", &sNickName, "shadow"); pspConfig->Get("Language", &ilanguage, PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); - pspConfig->Get("TimeFormat", &itimeformat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR); + pspConfig->Get("TimeFormat", &iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR); pspConfig->Get("DateFormat", &iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD); pspConfig->Get("TimeZone", &iTimeZone, 0); pspConfig->Get("DayLightSavings", &bDayLightSavings, PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD); - pspConfig->Get("ButtonPreference", &bButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS); + pspConfig->Get("ButtonPreference", &iButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS); pspConfig->Get("LockParentalLevel", &iLockParentalLevel, 0); pspConfig->Get("WlanAdhocChannel", &iWlanAdhocChannel, PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC); pspConfig->Get("WlanPowerSave", &bWlanPowerSave, PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF); @@ -196,7 +196,7 @@ void Config::Save() cpu->Set("FastMemory", bFastMemory); IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics"); - graphics->Set("ShowFPSCounter", bShowFPSCounter); + graphics->Set("ShowFPSCounter", iShowFPSCounter); graphics->Set("DisplayFramebuffer", bDisplayFramebuffer); graphics->Set("ResolutionScale", iWindowZoom); graphics->Set("BufferedRendering", bBufferedRendering); @@ -238,11 +238,11 @@ void Config::Save() IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Set("NickName", sNickName.c_str()); pspConfig->Set("Language", ilanguage); - pspConfig->Set("TimeFormat", itimeformat); + pspConfig->Set("TimeFormat", iTimeFormat); pspConfig->Set("DateFormat", iDateFormat); pspConfig->Set("TimeZone", iTimeZone); pspConfig->Set("DayLightSavings", bDayLightSavings); - pspConfig->Set("ButtonPreference", bButtonPreference); + pspConfig->Set("ButtonPreference", iButtonPreference); pspConfig->Set("LockParentalLevel", iLockParentalLevel); pspConfig->Set("WlanAdhocChannel", iWlanAdhocChannel); pspConfig->Set("WlanPowerSave", bWlanPowerSave); diff --git a/Core/Config.h b/Core/Config.h index 7fbd525e65..a63e571c46 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -95,7 +95,7 @@ public: bool bShowTouchControls; bool bShowDebuggerOnLoad; bool bShowAnalogStick; - bool bShowFPSCounter; + int iShowFPSCounter; bool bShowDebugStats; bool bLargeControls; bool bAccelerometerToAnalogHoriz; @@ -115,18 +115,19 @@ public: // SystemParam std::string sNickName; int ilanguage; - int itimeformat; + int iTimeFormat; int iDateFormat; int iTimeZone; bool bDayLightSavings; bool bButtonPreference; + int iButtonPreference; int iLockParentalLevel; bool bEncryptSave; int iWlanAdhocChannel; bool bWlanPowerSave; std::string currentDirectory; - std::string externalDirectory; + std::string externalDirectory; std::string memCardDirectory; std::string flashDirectory; std::string internalDataDirectory; diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 1c1a1b8023..23d32df181 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -356,14 +356,24 @@ void PSPSaveDialog::DisplaySaveDataInfo1() char hour_time[10] ; int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour; int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min; - if (g_Config.itimeformat == PSP_SYSTEMPARAM_TIME_FORMAT_12HR) { + switch (g_Config.iTimeFormat) { + case 1: if (hour > 12) { strcpy(am_pm, "PM"); hour -= 12; } snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); - } else - snprintf(hour_time,10,"%02d:%02d", hour, min); + break; + case 2: + snprintf(hour_time,10,"%02d:%02d", hour, min); + break; + default: + if (hour > 12) { + strcpy(am_pm, "PM"); + hour -= 12; + } + snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); + } snprintf(title, 512, "%s", param.GetFileInfo(currentSelectedSave).title); int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday; @@ -371,14 +381,15 @@ void PSPSaveDialog::DisplaySaveDataInfo1() int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900; s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024; switch (g_Config.iDateFormat) { - case PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY: - snprintf(time, 512, "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK); + case 1: + snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); break; - case PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY: + case 2: snprintf(time, 512, "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK); break; - case PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD: - // fall through + case 3: + snprintf(time, 512, "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK); + break; default: snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); } @@ -408,14 +419,24 @@ void PSPSaveDialog::DisplaySaveDataInfo2() char hour_time[10] ; int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour; int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min; - if (g_Config.itimeformat == PSP_SYSTEMPARAM_TIME_FORMAT_12HR) { + switch (g_Config.iTimeFormat) { + case 1: if (hour > 12) { strcpy(am_pm, "PM"); hour -= 12; } snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); - } else - snprintf(hour_time,10,"%02d:%02d", hour, min); + break; + case 2: + snprintf(hour_time,10,"%02d:%02d", hour, min); + break; + default: + if (hour > 12) { + strcpy(am_pm, "PM"); + hour -= 12; + } + snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); + } const char *saveTitle = param.GetFileInfo(currentSelectedSave).saveTitle; int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday; @@ -423,14 +444,14 @@ void PSPSaveDialog::DisplaySaveDataInfo2() int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900; s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024; switch (g_Config.iDateFormat) { - case PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY: - snprintf(date, 256, "%02d/%02d/%d", day, month, year); - break; - case PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY: + case 1: + snprintf(date, 256, "%d/%02d/%02d", year, month, day); + case 2: snprintf(date, 256, "%02d/%02d/%d", month, day, year); break; - case PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD: - // fall through + case 3: + snprintf(date, 256, "%02d/%02d/%d", day, month, year); + break; default: snprintf(date, 256, "%d/%02d/%02d", year, month, day); } diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7f7688deff..6a0fbe358e 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -426,7 +426,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) { gpuStats.numFrames++; - if (g_Config.bShowFPSCounter) { + if (g_Config.iShowFPSCounter) { CalculateFPS(); } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 8253876bff..e254cf973b 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -461,7 +461,7 @@ u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) param = g_Config.iDateFormat; break; case PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT: - param = g_Config.itimeformat?PSP_SYSTEMPARAM_TIME_FORMAT_12HR:PSP_SYSTEMPARAM_TIME_FORMAT_24HR; + param = g_Config.iTimeFormat?PSP_SYSTEMPARAM_TIME_FORMAT_12HR:PSP_SYSTEMPARAM_TIME_FORMAT_24HR; break; case PSP_SYSTEMPARAM_ID_INT_TIMEZONE: param = g_Config.iTimeZone; @@ -473,7 +473,7 @@ u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) param = g_Config.ilanguage; break; case PSP_SYSTEMPARAM_ID_INT_BUTTON_PREFERENCE: - param = g_Config.bButtonPreference?PSP_SYSTEMPARAM_BUTTON_CROSS:PSP_SYSTEMPARAM_BUTTON_CIRCLE; + param = g_Config.iButtonPreference?PSP_SYSTEMPARAM_BUTTON_CROSS:PSP_SYSTEMPARAM_BUTTON_CIRCLE; break; case PSP_SYSTEMPARAM_ID_INT_LOCK_PARENTAL_LEVEL: param = g_Config.iLockParentalLevel; diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 8cbabbed25..32f22b8d17 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -211,7 +211,7 @@ namespace Reporting postdata.Add("pixel_height", PSP_CoreParameter().pixelHeight); postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks()); - if (g_Config.bShowFPSCounter) + if (g_Config.iShowFPSCounter) { float vps, fps; __DisplayGetAveragedFPS(&vps, &fps); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 5ce338c37d..e461ab91ed 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -337,11 +337,18 @@ void EmuScreen::render() { ui_draw2d.SetFontScale(1.0f, 1.0f); } - if (g_Config.bShowFPSCounter) { + if (g_Config.iShowFPSCounter) { float vps, fps; __DisplayGetFPS(&vps, &fps); char fpsbuf[256]; - sprintf(fpsbuf, "VPS: %0.1f\nFPS: %0.1f", vps, fps); + switch (g_Config.iShowFPSCounter) { + case 2: + sprintf(fpsbuf, "VPS: %0.1f", vps); break; + case 3: + sprintf(fpsbuf, "FPS: %0.1f", fps); break; + case 4: + sprintf(fpsbuf, "VPS: %0.1f\nFPS: %0.1f", vps, fps); break; + } ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT); ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT); } diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index dbcc1b3b84..d4028b2757 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -465,8 +465,6 @@ void PauseScreen::render() { if (gpu) gpu->Resized(); } - 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 , gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); if (enableFrameSkip) { @@ -686,24 +684,24 @@ void DeveloperScreen::render() { screenManager()->finishDialog(this, DR_OK); } - if (UIButton(GEN_ID, vlinear, w, 0, d->T("Load language ini"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Load language ini"), ALIGN_LEFT)) { i18nrepo.LoadIni(g_Config.languageIni); // After this, g and s are no longer valid. Need to reload them. g = GetI18NCategory("General"); d = GetI18NCategory("Developer"); } - if (UIButton(GEN_ID, vlinear, w, 0, d->T("Save language ini"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Save language ini"), ALIGN_LEFT)) { i18nrepo.SaveIni(g_Config.languageIni); } - if (UIButton(GEN_ID, vlinear, w, 0, d->T("Run CPU tests"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Run CPU Tests"), ALIGN_LEFT)) { // TODO: Run tests RunTests(); // screenManager()->push(new EmuScreen()) } - if (UIButton(GEN_ID, vlinear, w, 0, d->T("Dump frame to log"), ALIGN_LEFT)) { + if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Dump next frame"), ALIGN_LEFT)) { gpu->DumpNextFrame(); } @@ -928,7 +926,35 @@ void GraphicsScreenP3::render() { int y = 35; int stride = 40; int columnw = 400; + + bool ShowCounter = g_Config.iShowFPSCounter > 0; + UICheckBox(GEN_ID, x, y += stride, gs->T("Show VPS/FPS"), ALIGN_TOPLEFT, &ShowCounter); + if (ShowCounter) { + if (g_Config.iShowFPSCounter <= 0) + g_Config.iShowFPSCounter = 1; + char counter[256]; + std::string type; + + switch (g_Config.iShowFPSCounter) { + case 1: type = "VPS";break; + case 2: type = "FPS";break; + case 3: type = "Both";break; + } + sprintf(counter, "%s %s", gs->T("Format :"), type.c_str()); + ui_draw2d.DrawText(UBUNTU24, counter, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 250, y, 20); + if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("VPS"), ALIGN_LEFT)) + g_Config.iShowFPSCounter = 1; + if (UIButton(GEN_ID, hlinear1, 80, 0, gs->T("FPS"), ALIGN_LEFT)) + g_Config.iShowFPSCounter = 2; + if (UIButton(GEN_ID, hlinear1, 90, 0, gs->T("Both"), ALIGN_LEFT)) + g_Config.iShowFPSCounter = 3; + + y += 20; + } else + g_Config.iShowFPSCounter = 0; + bool FpsLimit = g_Config.iFpsLimit != 0; UICheckBox(GEN_ID, x, y += stride, gs->T("FPS Limit"), ALIGN_TOPLEFT, &FpsLimit); if (FpsLimit) { @@ -1122,13 +1148,74 @@ void SystemScreen::render() { #endif if (g_Config.bJit) UICheckBox(GEN_ID, x, y += stride, s->T("Fast Memory", "Fast Memory (unstable)"), ALIGN_TOPLEFT, &g_Config.bFastMemory); - UICheckBox(GEN_ID, x, y += stride, s->T("Show FPS"), ALIGN_TOPLEFT, &g_Config.bShowFPSCounter); - UICheckBox(GEN_ID, x, y += stride, s->T("Encrypt Save"), ALIGN_TOPLEFT, &g_Config.bEncryptSave); - UICheckBox(GEN_ID, x, y += stride, s->T("Use Button X to Confirm"), ALIGN_TOPLEFT, &g_Config.bButtonPreference); - bool tf = g_Config.itimeformat == 1; - if (UICheckBox(GEN_ID, x, y += stride, s->T("12HR Time Format"), ALIGN_TOPLEFT, &tf)) { - g_Config.itimeformat = tf ? 1 : 0; + + UICheckBox(GEN_ID, x, y += stride, s->T("Daylight Savings"), ALIGN_TOPLEFT, &g_Config.bDayLightSavings); + UICheckBox(GEN_ID, x, y += stride, s->T("Button Perference"), ALIGN_TOPLEFT, &g_Config.bButtonPreference); + if (g_Config.bButtonPreference) { + char button[256]; + std::string type; + switch (g_Config.iButtonPreference) { + case 0: type = "O to Enter";break; + case 1: type = "X to Enter";break; + } + sprintf(button, "%s %s", s->T("Type :"), type.c_str()); + ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 280, y, 20); + if (UIButton(GEN_ID, hlinear1, 90, 0, s->T("Use O"), ALIGN_LEFT)) + g_Config.iButtonPreference = 0; + if (UIButton(GEN_ID, hlinear1, 90, 0, s->T("Use X"), ALIGN_LEFT)) + g_Config.iButtonPreference = 1; + y += 10; } + + bool time = g_Config.iTimeFormat > 0 ; + UICheckBox(GEN_ID, x, y += stride, s->T("Time Format"), ALIGN_TOPLEFT, &time); + if (time) { + if (g_Config.iTimeFormat <= 0) + g_Config.iTimeFormat = 1; + + char button[256]; + std::string type; + switch (g_Config.iTimeFormat) { + case 1: type = "12HR";break; + case 2: type = "24HR";break; + } + sprintf(button, "%s %s", s->T("Format :"), type.c_str()); + ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 280, y, 20); + if (UIButton(GEN_ID, hlinear1, 80, 0, s->T("12HR"), ALIGN_LEFT)) + g_Config.iTimeFormat = 1; + if (UIButton(GEN_ID, hlinear1, 80, 0, s->T("24HR"), ALIGN_LEFT)) + g_Config.iTimeFormat = 2; + y += 10; + } else + g_Config.iTimeFormat = 0 ; + + bool date = g_Config.iDateFormat > 0; + UICheckBox(GEN_ID, x, y += stride, s->T("Date Format"), ALIGN_TOPLEFT, &date); + if (date) { + if (g_Config.iDateFormat <= 0) + g_Config.iDateFormat = 1; + char button[256]; + std::string type; + switch (g_Config.iDateFormat) { + case 1: type = "YYYYMMDD";break; + case 2: type = "MMDDYYYY";break; + case 3: type = "DDMMYYYY";break; + } + sprintf(button, "%s %s", s->T("Format :"), type.c_str()); + ui_draw2d.DrawText(UBUNTU24, button, x + 60, y += stride , 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear1(x + 350, y, 10); + if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("YMD"), ALIGN_LEFT)) + g_Config.iDateFormat = 1; + if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("MDY"), ALIGN_LEFT)) + g_Config.iDateFormat = 2; + if (UIButton(GEN_ID, hlinear1, 70, 0, s->T("DMY"), ALIGN_LEFT)) + g_Config.iDateFormat = 3; + y += 10; + } else + g_Config.iDateFormat = 0; + UICheckBox(GEN_ID, x, y += stride, s->T("Enable Cheats"), ALIGN_TOPLEFT, &g_Config.bEnableCheats); if (g_Config.bEnableCheats) { HLinear hlinear1(x + 60, y += stride + 10, 20); @@ -1139,7 +1226,7 @@ void SystemScreen::render() { HLinear hlinear2(x, y += stride + 10, 20); if (UIButton(GEN_ID, hlinear2, LARGE_BUTTON_WIDTH, 0, s->T("Language"), ALIGN_TOPLEFT)) { screenManager()->push(new LanguageScreen()); - } + } UIEnd(); } @@ -1166,6 +1253,8 @@ void ControlsScreen::render() { int columnw = 440; UICheckBox(GEN_ID, x, y += stride, c->T("OnScreen", "On-Screen Touch Controls"), ALIGN_TOPLEFT, &g_Config.bShowTouchControls); + UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); + UICheckBox(GEN_ID, x, y += stride, c->T("Tilt", "Tilt to Analog (horizontal)"), ALIGN_TOPLEFT, &g_Config.bAccelerometerToAnalogHoriz); if (g_Config.bShowTouchControls) { UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Scaling"), ALIGN_TOPLEFT, &g_Config.bLargeControls); if (g_Config.bLargeControls) { @@ -1183,11 +1272,10 @@ void ControlsScreen::render() { g_Config.fButtonScale += 0.1; y += 20; } - UICheckBox(GEN_ID, x, y += stride, c->T("Show Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); // This will be a slider in the new UI later bool bTransparent = g_Config.iTouchButtonOpacity < 65; bool prev = bTransparent; - UICheckBox(GEN_ID, x, y += stride, c->T("Transparent Buttons"), ALIGN_TOPLEFT, &bTransparent); + UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Opacity"), ALIGN_TOPLEFT, &bTransparent); if (bTransparent) { char opacity[256]; sprintf(opacity, "%s %d", c->T("Opacity :"), g_Config.iTouchButtonOpacity); @@ -1206,7 +1294,6 @@ void ControlsScreen::render() { if (bTransparent != prev) g_Config.iTouchButtonOpacity = bTransparent ? 15 : 65; } - UICheckBox(GEN_ID, x, y += stride, c->T("Tilt", "Tilt to Analog (horizontal)"), ALIGN_TOPLEFT, &g_Config.bAccelerometerToAnalogHoriz); UIEnd(); } diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 34a0176c77..ee02b7bc89 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -726,7 +726,7 @@ namespace MainWindow g_Config.bVertexCache = !g_Config.bVertexCache; break; case ID_OPTIONS_SHOWFPS: - g_Config.bShowFPSCounter = !g_Config.bShowFPSCounter; + g_Config.iShowFPSCounter = !g_Config.iShowFPSCounter; break; case ID_OPTIONS_DISPLAYRAWFRAMEBUFFER: g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer; @@ -898,7 +898,7 @@ namespace MainWindow CHECKITEM(ID_EMULATION_RUNONLOAD, g_Config.bAutoRun); CHECKITEM(ID_OPTIONS_USEVBO, g_Config.bUseVBO); CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache); - CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.bShowFPSCounter); + CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.iShowFPSCounter); CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != 0); CHECKITEM(ID_OPTIONS_MIPMAP, g_Config.bMipMap); CHECKITEM(ID_OPTIONS_VSYNC, g_Config.iVSyncInterval != 0); diff --git a/headless/Headless.cpp b/headless/Headless.cpp index af2375fe67..5bba70a795 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -200,12 +200,12 @@ int main(int argc, const char* argv[]) g_Config.bVertexCache = true; g_Config.bTrueColor = true; g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; - g_Config.itimeformat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR; + g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR; g_Config.bEncryptSave = true; g_Config.sNickName = "shadow"; g_Config.iTimeZone = 60; g_Config.iDateFormat = PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY; - g_Config.bButtonPreference = true; + g_Config.iButtonPreference = PSP_SYSTEMPARAM_BUTTON_CROSS; g_Config.iLockParentalLevel = 9; #if defined(ANDROID) From d24ad28ceb00e468277aa145b5fd7743d4f54595 Mon Sep 17 00:00:00 2001 From: raven02 Date: Wed, 19 Jun 2013 15:24:35 +0800 Subject: [PATCH 15/46] Follow as 1/2/3 option --- UI/EmuScreen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index e461ab91ed..3636cc027f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -342,11 +342,11 @@ void EmuScreen::render() { __DisplayGetFPS(&vps, &fps); char fpsbuf[256]; switch (g_Config.iShowFPSCounter) { - case 2: + case 1: sprintf(fpsbuf, "VPS: %0.1f", vps); break; - case 3: + case 2: sprintf(fpsbuf, "FPS: %0.1f", fps); break; - case 4: + case 3: sprintf(fpsbuf, "VPS: %0.1f\nFPS: %0.1f", vps, fps); break; } ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT); From 7dac11922d81fee056cd8ad0b8e4a49681b4ec76 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 12:00:24 +0200 Subject: [PATCH 16/46] Some minor optimization of audio channel queues and mixing --- Common/FixedSizeQueue.h | 102 +++++++++++++++++++++++++++++++++++++++- Common/MemoryUtil.cpp | 2 + Core/HLE/__sceAudio.cpp | 91 ++++++++++++++++++++++++----------- 3 files changed, 166 insertions(+), 29 deletions(-) diff --git a/Common/FixedSizeQueue.h b/Common/FixedSizeQueue.h index 50b9548d56..8001f036e4 100644 --- a/Common/FixedSizeQueue.h +++ b/Common/FixedSizeQueue.h @@ -20,6 +20,7 @@ #include #include "ChunkFile.h" +#include "MemoryUtil.h" // STL-look-a-like interface, but name is mixed case to distinguish it clearly from the // real STL classes. @@ -30,12 +31,14 @@ template class FixedSizeQueue { public: FixedSizeQueue() { - storage_ = new T[N]; + // Allocate aligned memory, just because. + int sizeInBytes = N * sizeof(T); + storage_ = (T *)AllocateMemoryPages(sizeInBytes); clear(); } ~FixedSizeQueue() { - delete [] storage_; + FreeMemoryPages((void *)storage_, N * sizeof(T)); } void clear() { @@ -52,6 +55,45 @@ public: count_++; } + // Gets pointers to write to directly. + void pushPointers(size_t size, T **dest1, size_t *sz1, T **dest2, size_t *sz2) { + if (tail_ + size < N) { + *dest1 = &storage_[tail_]; + *sz1 = size; + tail_ += (int)size; + if (tail_ == N) tail_ = 0; + *dest2 = 0; + *sz2 = 0; + } else { + *dest1 = &storage_[tail_]; + *sz1 = N - tail_; + tail_ = (int)(size - *sz1); + *dest2 = &storage_[0]; + *sz2 = tail_; + } + count_ += (int)size; + } + + void popPointers(size_t size, const T **src1, size_t *sz1, const T **src2, size_t *sz2) { + if (size > count_) size = count_; + + if (head_ + size < N) { + *src1 = &storage_[head_]; + *sz1 = size; + head_ += (int)size; + if (head_ == N) head_ = 0; + *src2 = 0; + *sz2 = 0; + } else { + *src1 = &storage_[head_]; + *sz1 = N - head_; + head_ = (int)(size - *sz1); + *src2 = &storage_[0]; + *sz2 = head_; + } + count_ -= (int)size; + } + void pop() { head_++; if (head_ == N) @@ -125,5 +167,61 @@ private: FixedSizeQueue(FixedSizeQueue &other) { } }; + +// I'm not sure this is 100% safe but it might be "Good Enough" :) +// TODO: Use this, maybe make it safer first by using proper atomics +// instead of volatile +template +class LockFreeBlockQueue { +public: + LockFreeBlockQueue() { + curReadBlock = 0; + curWriteBlock = 0; + for (size_t i = 0; i < numBlocks; i++) { + blocks[i] = new T[blockSize]; + } + } + ~LockFreeBlockQueue() { + for (size_t i = 0; i < numBlocks; i++) { + delete [] blocks[i]; + } + } + + // Write to the returned pointer then call EndPush to finish the push. + T *BeginPush() { + return blocks[curWriteBlock]; + } + void EndPush() { + curWriteBlock++; + if (curWriteBlock == NUM_BLOCKS) + curWriteBlock = 0; + } + + bool CanPush() { + int nextBlock = curWriteBlock + 1; + if (nextBlock == NUM_BLOCKS) nextBlock == 0; + return nextBlock != curReadBlock; + } + + bool CanPop() { return curReadBlock != curWriteBlock; } + + // Read from the returned pointer then call EndPush to finish the pop. + T *BeginPop() { + return blocks[curReadBlock]; + } + T *EndPop() { + curReadBlock++; + if (curReadBlock == NUM_BLOCKS) + curReadBlock = 0; + } + +private: + enum { NUM_BLOCKS = 16 }; + T **blocks[NUM_BLOCKS]; + + volatile int curReadBlock; + volatile int curWriteBlock; +}; + #endif // _FIXED_SIZE_QUEUE_H_ diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index cebd40db07..88750232be 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -124,6 +124,7 @@ void* AllocateExecutableMemory(size_t size, bool low) void* AllocateMemoryPages(size_t size) { + size = (size + 4095) & (~4095); #ifdef _WIN32 void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); #elif defined(__SYMBIAN32__) @@ -169,6 +170,7 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) void FreeMemoryPages(void* ptr, size_t size) { + size = (size + 4095) & (~4095); if (ptr) { #ifdef _WIN32 diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 0325ac05e0..9bc7abca7a 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -47,6 +47,8 @@ const int audioHostIntervalUs = (int)(1000000ULL * hostAttemptBlockSize / hwSamp const int chanQueueMaxSizeFactor = 2; const int chanQueueMinSizeFactor = 1; +// TODO: Need to replace this with something lockless. Mutexes in the audio pipeline +// is bad mojo. FixedSizeQueue outAudioQueue; static inline s16 clamp_s16(int i) { @@ -70,6 +72,8 @@ void hleAudioUpdate(u64 userdata, int cyclesLate) void hleHostAudioUpdate(u64 userdata, int cyclesLate) { + // Not all hosts need this call to poke their audio system once in a while, but those that don't + // can just ignore it. host->UpdateSound(); CoreTiming::ScheduleEvent(usToCycles(audioHostIntervalUs) - cyclesLate, eventHostAudioUpdate, 0); } @@ -166,10 +170,33 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) // Walking a pointer for speed. But let's make sure we wouldn't trip on an invalid ptr. if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16))) { +#if 0 for (u32 i = 0; i < totalSamples; i += 2) { chan.sampleQueue.push(adjustvolume(*sampleData++, chan.leftVolume)); chan.sampleQueue.push(adjustvolume(*sampleData++, chan.rightVolume)); } +#else + s16 *buf1 = 0, *buf2 = 0; + size_t sz1, sz2; + chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2); + int leftVol = chan.leftVolume; + int rightVol = chan.rightVolume; + + // TODO: SSE/NEON implementations + for (u32 i = 0; i < sz1; i += 2) + { + buf1[i] = adjustvolume(sampleData[i], leftVol); + buf1[i + 1] = adjustvolume(sampleData[i + 1], rightVol); + } + if (buf2) { + sampleData += sz1; + for (u32 i = 0; i < sz2; i += 2) + { + buf2[i] = adjustvolume(sampleData[i], leftVol); + buf2[i + 1] = adjustvolume(sampleData[i + 1], rightVol); + } + } +#endif } } else @@ -227,46 +254,63 @@ void __AudioWakeThreads(AudioChannel &chan, int result) __AudioWakeThreads(chan, result, 0x7FFFFFFF); } +void __AudioSetOutputFrequency(int freq) +{ + WARN_LOG(HLE, "Switching audio frequency to %i", freq); + mixFrequency = freq; +} + // Mix samples from the various audio channels into a single sample queue. // This single sample queue is where __AudioMix should read from. If the sample queue is full, we should // just sleep the main emulator thread a little. -void __AudioUpdate() -{ +void __AudioUpdate() { // Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied // to the CPU. Much better to throttle the frame rate on frame display and just throw away audio // if the buffer somehow gets full. - s32 mixBuffer[hwBlockSize * 2]; - memset(mixBuffer, 0, sizeof(mixBuffer)); + bool firstChannel = true; - for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) - { + for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) { if (!chans[i].reserved) continue; + __AudioWakeThreads(chans[i], 0, hwBlockSize); if (!chans[i].sampleQueue.size()) { - // ERROR_LOG(HLE, "No queued samples, skipping channel %i", i); continue; } - for (int s = 0; s < hwBlockSize; s++) - { - if (chans[i].sampleQueue.size() >= 2) - { - s16 sampleL = chans[i].sampleQueue.pop_front(); - s16 sampleR = chans[i].sampleQueue.pop_front(); - mixBuffer[s * 2 + 0] += sampleL; - mixBuffer[s * 2 + 1] += sampleR; - } - else - { - ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize); - break; + if (hwBlockSize * 2 > chans[i].sampleQueue.size()) { + ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, chans[i].sampleQueue.size() / 2, hwBlockSize); + } + + const s16 *buf1 = 0, *buf2 = 0; + size_t sz1, sz2; + + chans[i].sampleQueue.popPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2); + + if (firstChannel) { + for (int s = 0; s < sz1; s++) + mixBuffer[s] = buf1[s]; + if (buf2) { + for (int s = 0; s < sz2; s++) + mixBuffer[s + sz1] = buf2[s]; + } + firstChannel = false; + } else { + for (int s = 0; s < sz1; s++) + mixBuffer[s] += buf1[s]; + if (buf2) { + for (int s = 0; s < sz2; s++) + mixBuffer[s + sz1] += buf2[s]; } } } + if (firstChannel) { + memset(mixBuffer, 0, sizeof(mixBuffer)); + } + if (g_Config.bEnableSound) { lock_guard guard(section); if (outAudioQueue.room() >= hwBlockSize * 2) { @@ -284,13 +328,6 @@ void __AudioUpdate() DEBUG_LOG(HLE, "Audio outbuffer overrun! room = %i / %i", outAudioQueue.room(), (u32)outAudioQueue.capacity()); } } - -} - -void __AudioSetOutputFrequency(int freq) -{ - WARN_LOG(HLE, "Switching audio frequency to %i", freq); - mixFrequency = freq; } // numFrames is number of stereo frames. From 8f9562cde444b01987dbb568ed99667d3790b204 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 12:42:04 +0200 Subject: [PATCH 17/46] Remove gl enum hacks in texturecache (doesn't seem to work, get bad log output on adreno) --- GPU/GLES/TextureCache.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 7fd6468fe1..39984d410c 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -484,16 +484,6 @@ static const GLuint MagFiltGL[2] = { GL_LINEAR }; -// OpenGL ES 2.0 workaround. This SHOULD be available but is NOT in the headers in Android. -// Let's see if this hackery works. -#ifndef GL_TEXTURE_LOD_BIAS -#define GL_TEXTURE_LOD_BIAS 0x8501 -#endif - -#ifndef GL_TEXTURE_MAX_LOD -#define GL_TEXTURE_MAX_LOD 0x813B -#endif - // This should not have to be done per texture! OpenGL is silly yo // TODO: Dirty-check this against the current texture. void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { @@ -509,7 +499,9 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { // TODO: Is this a signed value? Which direction? float lodBias = 0.0; // -(float)((gstate.texlevel >> 16) & 0xFF) / 16.0f; if (force || entry.lodBias != lodBias) { +#ifndef USING_GLES2 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias); +#endif entry.lodBias = lodBias; } } @@ -1117,8 +1109,8 @@ void TextureCache::SetTexture() { LoadTextureLevel(*entry, i, replaceImages); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel); -#endif glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel); +#endif } else { LoadTextureLevel(*entry, 0, replaceImages); #ifndef USING_GLES2 From c021c93883806f6278a5cf31764d3233816ed241 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 13:13:02 +0200 Subject: [PATCH 18/46] More minor audio optimizations --- Common/FixedSizeQueue.h | 8 ++++--- Core/HLE/__sceAudio.cpp | 47 +++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/Common/FixedSizeQueue.h b/Common/FixedSizeQueue.h index 8001f036e4..cb86a8c645 100644 --- a/Common/FixedSizeQueue.h +++ b/Common/FixedSizeQueue.h @@ -32,13 +32,15 @@ class FixedSizeQueue { public: FixedSizeQueue() { // Allocate aligned memory, just because. - int sizeInBytes = N * sizeof(T); - storage_ = (T *)AllocateMemoryPages(sizeInBytes); + //int sizeInBytes = N * sizeof(T); + //storage_ = (T *)AllocateMemoryPages(sizeInBytes); + storage_ = new T[N]; clear(); } ~FixedSizeQueue() { - FreeMemoryPages((void *)storage_, N * sizeof(T)); + // FreeMemoryPages((void *)storage_, N * sizeof(T)); + delete [] storage_; } void clear() { diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 9bc7abca7a..a8fa834f3a 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -314,13 +314,14 @@ void __AudioUpdate() { if (g_Config.bEnableSound) { lock_guard guard(section); if (outAudioQueue.room() >= hwBlockSize * 2) { - // Push the mixed samples onto the output audio queue. - for (int i = 0; i < hwBlockSize; i++) { - s16 sampleL = clamp_s16(mixBuffer[i * 2 + 0]); - s16 sampleR = clamp_s16(mixBuffer[i * 2 + 1]); - - outAudioQueue.push((s16)sampleL); - outAudioQueue.push((s16)sampleR); + s16 *buf1 = 0, *buf2 = 0; + size_t sz1, sz2; + outAudioQueue.pushPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2); + for (int s = 0; s < sz1; s++) + buf1[s] = clamp_s16(mixBuffer[s]); + if (buf2) { + for (int s = 0; s < sz2; s++) + buf2[s] = clamp_s16(mixBuffer[s + sz1]); } } else { // This happens quite a lot. There's still something slightly off @@ -335,28 +336,28 @@ void __AudioUpdate() { int __AudioMix(short *outstereo, int numFrames) { // TODO: if mixFrequency != the actual output frequency, resample! - lock_guard guard(section); int underrun = -1; s16 sampleL = 0; s16 sampleR = 0; - bool anythingToPlay = false; - for (int i = 0; i < numFrames; i++) { - if (outAudioQueue.size() >= 2) { - sampleL = outAudioQueue.pop_front(); - sampleR = outAudioQueue.pop_front(); - outstereo[i * 2 + 0] = sampleL; - outstereo[i * 2 + 1] = sampleR; - anythingToPlay = true; - } else { - if (underrun == -1) underrun = i; - outstereo[i * 2 + 0] = sampleL; // repeat last sample, can reduce clicking - outstereo[i * 2 + 1] = sampleR; // repeat last sample, can reduce clicking + + const s16 *buf1 = 0, *buf2 = 0; + size_t sz1, sz2; + { + lock_guard guard(section); + outAudioQueue.popPointers(numFrames * 2, &buf1, &sz1, &buf2, &sz2); + memcpy(outstereo, buf1, sz1 * sizeof(s16)); + if (buf2) { + memcpy(outstereo + sz1, buf2, sz2 * sizeof(s16)); } } - if (anythingToPlay && underrun >= 0) { + + int remains = (int)(numFrames * 2 - sz1 - sz2); + if (remains > 0) + memset(outstereo + numFrames * 2 - remains, 0, remains); + + if (sz1 + sz2 < numFrames) { + underrun = (int)(sz1 + sz2) / 2; DEBUG_LOG(HLE, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames); - } else { - // DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames); } return underrun >= 0 ? underrun : numFrames; } From 1b941b1a7b1f7884beece1bb1659f70a17ada223 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 13:13:23 +0200 Subject: [PATCH 19/46] UI tweaks --- UI/MenuScreens.cpp | 11 +++++++++-- UI/NativeApp.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index dbcc1b3b84..f76c87d95f 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -996,7 +996,7 @@ void LanguageScreen::render() { I18NCategory *g = GetI18NCategory("General"); I18NCategory *l = GetI18NCategory("Language"); - bool small = dp_xres < 720; + bool small = dp_xres < 790; if (!small) { ui_draw2d.SetFontScale(1.5f, 1.5f); @@ -1019,6 +1019,12 @@ void LanguageScreen::render() { for (size_t i = 0; i < langs_.size(); i++) { + // Skip README + if (langs_[i].name.find("README") != std::string::npos) { + continue; + } + + std::string code; size_t dot = langs_[i].name.find('.'); if (dot != std::string::npos) @@ -1042,6 +1048,7 @@ void LanguageScreen::render() { langValuesMapping["zh_CN"] = std::make_pair("简体中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED); //langValuesMapping["ar_AE"] = std::make_pair("العربية", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["az_AZ"] = std::make_pair("Azeri", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["ca_ES"] = std::make_pair("Català", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["gr_EL"] = std::make_pair("ελληνικά", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["he_IL"] = std::make_pair("עברית", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); @@ -1055,7 +1062,7 @@ void LanguageScreen::render() { if (!code.empty()) { if(langValuesMapping.find(code) == langValuesMapping.end()) { - //No title found, show locale code + // No title found, show locale code buttonTitle = code; } else { buttonTitle = langValuesMapping[code].first; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 37af83f56f..7b4adda767 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -237,6 +237,15 @@ void NativeInit(int argc, const char *argv[], g_Config.externalDirectory = external_directory; #endif +#ifdef ANDROID + // On Android, create a PSP directory tree in the external_directory, + // to hopefully reduce confusion a bit. + ILOG("Creating %s", (g_Config.externalDirectory + "/PSP").c_str()); + mkDir((g_Config.externalDirectory + "/PSP").c_str()); + mkDir((g_Config.externalDirectory + "/PSP/SAVEDATA").c_str()); + mkDir((g_Config.externalDirectory + "/PSP/GAME").c_str()); +#endif + const char *fileToLog = 0; const char *stateToLoad = 0; From d81533e8d888775cb569d284da1d1921632a446c Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 14:28:22 +0200 Subject: [PATCH 20/46] Fix lint warning. Update native with audio buffer size detection. --- android/AndroidManifest.xml | 3 ++- native | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 68875a411c..6637a86515 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -23,7 +23,8 @@ + android:label="@string/app_name" + android:allowBackup="true"> Date: Wed, 19 Jun 2013 15:05:19 +0200 Subject: [PATCH 21/46] Warning fix --- Common/FixedSizeQueue.h | 2 +- Core/HLE/__sceAudio.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/FixedSizeQueue.h b/Common/FixedSizeQueue.h index cb86a8c645..37066fe00a 100644 --- a/Common/FixedSizeQueue.h +++ b/Common/FixedSizeQueue.h @@ -201,7 +201,7 @@ public: bool CanPush() { int nextBlock = curWriteBlock + 1; - if (nextBlock == NUM_BLOCKS) nextBlock == 0; + if (nextBlock == NUM_BLOCKS) nextBlock = 0; return nextBlock != curReadBlock; } diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index a8fa834f3a..778e80df17 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -281,7 +281,7 @@ void __AudioUpdate() { } if (hwBlockSize * 2 > chans[i].sampleQueue.size()) { - ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, chans[i].sampleQueue.size() / 2, hwBlockSize); + ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, hwBlockSize); } const s16 *buf1 = 0, *buf2 = 0; From 2dad8cb90d82d893b605964261f5752a93c5ff56 Mon Sep 17 00:00:00 2001 From: raven02 Date: Wed, 19 Jun 2013 21:49:51 +0800 Subject: [PATCH 22/46] Quick fix spacing issue on Pause menu --- UI/MenuScreens.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index d4028b2757..7acfcb95fc 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -487,8 +487,9 @@ void PauseScreen::render() { } else g_Config.iFrameSkip = 0; - ui_draw2d.DrawText(UBUNTU24, gs->T("Save State :"), 30, 360, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear4(x + 180 , y += 50, 10); + UICheckBox(GEN_ID, x, y += stride, gs->T("Linear Filtering"), ALIGN_TOPLEFT, &g_Config.bLinearFiltering); + ui_draw2d.DrawText(UBUNTU24, gs->T("Save State :"), 30, y += 40, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear4(x + 180 , y , 10); if (UIButton(GEN_ID, hlinear4, 60, 0, "1", ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); @@ -510,9 +511,8 @@ void PauseScreen::render() { screenManager()->finishDialog(this, DR_CANCEL); } - - ui_draw2d.DrawText(UBUNTU24, gs->T("Load State :"), 30, 420, 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear3(x + 180 , y += 60, 10); + ui_draw2d.DrawText(UBUNTU24, gs->T("Load State :"), 30, y += 60, 0xFFFFFFFF, ALIGN_LEFT); + HLinear hlinear3(x + 180 , y + 10 , 10); if (UIButton(GEN_ID, hlinear3, 60, 0, "1", ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); From 0839a6ed0700647182bfaeb48579befb389fdc5b Mon Sep 17 00:00:00 2001 From: Sacha Date: Thu, 20 Jun 2013 01:34:25 +1000 Subject: [PATCH 23/46] Fix frozen black screens for non-FFMPEG platforms --- Core/HW/MediaEngine.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 62eea7b2cc..03f2b5273a 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -371,12 +371,11 @@ void MediaEngine::updateSwsFormat(int videoPixelMode) { bool MediaEngine::stepVideo(int videoPixelMode) { // if video engine is broken, force to add timestamp m_videopts += 3003; - +#ifdef USE_FFMPEG if (!m_pFormatCtx) return false; if (!m_pCodecCtx) return false; -#ifdef USE_FFMPEG updateSwsFormat(videoPixelMode); // TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf. // Update the linesize for the new format too. We started with the largest size, so it should fit. From 61b510b7530ca37640714d556efdbd24e97cdc04 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 14:41:42 +0200 Subject: [PATCH 24/46] Open ISOs very slightly faster by not reopening --- Core/FileSystems/BlockDevices.cpp | 25 +++++++++++-------------- Core/FileSystems/BlockDevices.h | 9 +++------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 79831fe3c4..6a883fb6b5 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -34,19 +34,18 @@ BlockDevice *constructBlockDevice(const char *filename) { return 0; char buffer[4]; auto size = fread(buffer, 1, 4, f); //size_t - fclose(f); + fseek(f, 0, SEEK_SET); if (!memcmp(buffer, "CISO", 4) && size == 4) - return new CISOFileBlockDevice(filename); + return new CISOFileBlockDevice(f); else if (!memcmp(buffer, "\x00PBP", 4) && size == 4) - return new NPDRMDemoBlockDevice(filename); + return new NPDRMDemoBlockDevice(f); else - return new FileBlockDevice(filename); + return new FileBlockDevice(f); } -FileBlockDevice::FileBlockDevice(std::string _filename) -: filename(_filename) +FileBlockDevice::FileBlockDevice(FILE *file) + : f(file) { - f = fopen(_filename.c_str(), "rb"); fseek(f,0,SEEK_END); filesize = ftell(f); fseek(f,0,SEEK_SET); @@ -94,12 +93,12 @@ typedef struct ciso_header // TODO: Need much better error handling. -CISOFileBlockDevice::CISOFileBlockDevice(std::string _filename) -: filename(_filename) +CISOFileBlockDevice::CISOFileBlockDevice(FILE *file) + : f(file) { // CISO format is EXTREMELY crappy and incomplete. All tools make broken CISO. - f = fopen(_filename.c_str(), "rb"); + f = file; CISO_H hdr; size_t readSize = fread(&hdr, sizeof(CISO_H), 1, f); if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0) @@ -206,8 +205,8 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) } -NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename) - : filename_(_filename) +NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(FILE *file) + : f(file) { MAC_KEY mkey; CIPHER_KEY ckey; @@ -215,8 +214,6 @@ NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename) u32 tableOffset, tableSize; u32 lbaStart, lbaEnd; - f = fopen(_filename.c_str(), "rb"); - fseek(f, 0x24, SEEK_SET); fread(&psarOffset, 1, 4, f); fseek(f, psarOffset, SEEK_SET); diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index baa34111d5..afe4491812 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -39,13 +39,12 @@ public: class CISOFileBlockDevice : public BlockDevice { public: - CISOFileBlockDevice(std::string _filename); + CISOFileBlockDevice(FILE *file); ~CISOFileBlockDevice(); bool ReadBlock(int blockNumber, u8 *outPtr); u32 GetNumBlocks() { return numBlocks;} private: - std::string filename; FILE *f; u32 *index; int indexShift; @@ -57,13 +56,12 @@ private: class FileBlockDevice : public BlockDevice { public: - FileBlockDevice(std::string _filename); + FileBlockDevice(FILE *file); ~FileBlockDevice(); bool ReadBlock(int blockNumber, u8 *outPtr); u32 GetNumBlocks() {return (u32)(filesize / GetBlockSize());} private: - std::string filename; FILE *f; size_t filesize; }; @@ -82,14 +80,13 @@ struct table_info { class NPDRMDemoBlockDevice : public BlockDevice { public: - NPDRMDemoBlockDevice(std::string _filename); + NPDRMDemoBlockDevice(FILE *file); ~NPDRMDemoBlockDevice(); bool ReadBlock(int blockNumber, u8 *outPtr); u32 GetNumBlocks() {return (u32)lbaSize;} private: - std::string filename_; FILE *f; u32 lbaSize; From fa335c83d3579c7fd23d6c88f1516eda9ee71ce2 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 20:46:36 +0200 Subject: [PATCH 25/46] Modify DInput and touch analog to not clamp to a circle. Tries to fix #2316 --- Windows/DinputDevice.cpp | 18 ++++++++++++++++-- native | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 14bed98fc4..f39e0d3bb1 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -16,6 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include + #include "Core/HLE/sceCtrl.h" #include "DinputDevice.h" #include "ControlMapping.h" @@ -25,6 +27,11 @@ #include "Xinput.h" #pragma comment(lib,"dinput8.lib") +#ifdef min +#undef min +#undef max +#endif + unsigned int dinput_ctrl_map[] = { 11, PAD_BUTTON_MENU, // Open PauseScreen 10, PAD_BUTTON_BACK, // Toggle PauseScreen & Back Setting Page @@ -183,8 +190,15 @@ int DinputDevice::UpdateState(InputState &input_state) if (analog) { - input_state.pad_lstick_x += (float)js.lX / 10000.f; - input_state.pad_lstick_y += -((float)js.lY / 10000.f); + float x = (float)js.lX / 10000.f; + float y = -((float)js.lY / 10000.f); + + // Expand and clamp. Hack to let us reach the corners on most pads. + x = std::min(1.0f, std::max(-1.0f, x * 1.2f)); + y = std::min(1.0f, std::max(-1.0f, y * 1.2f)); + + input_state.pad_lstick_x += x; + input_state.pad_lstick_y += y; } for (u8 i = 0; i < sizeof(dinput_ctrl_map)/sizeof(dinput_ctrl_map[0]); i += 2) diff --git a/native b/native index 0e5cab2b0c..d1df63036a 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 0e5cab2b0c2eb3fb1dac5bccc107e77697d65969 +Subproject commit d1df63036a93139ca66615f143bc390659c689da From 182644b57ceb7b36698bd343b9b25b8a96e31119 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 22:18:23 +0200 Subject: [PATCH 26/46] Update native with another touch control fix --- native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native b/native index d1df63036a..deb4ba8323 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit d1df63036a93139ca66615f143bc390659c689da +Subproject commit deb4ba83235a86491d073db73a1e5bab2a5ce523 From 56aeab6558341fcca0b5805e5f06b59e3fa33db3 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 23:27:45 +0200 Subject: [PATCH 27/46] Update ffmpeg --- ffmpeg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg b/ffmpeg index 969f062d31..e8ef410aac 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 969f062d319ab9e3d341c6e661eedd51eefa50a2 +Subproject commit e8ef410aac458a35064e67582fb80103c29e6474 From f2b7096bdf53e103b8b28909ec3a88f57a629183 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 19 Jun 2013 23:54:45 +0200 Subject: [PATCH 28/46] Attempted workaround for issue #2308. Needs plenty of testing! Fixes black screens in GTA when pausing for example. --- GPU/GLES/Framebuffer.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 2f83bb05fa..6f7f6703c7 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "gfx_es2/glsl_program.h" #include "gfx_es2/gl_state.h" #include "gfx_es2/fbo.h" @@ -354,12 +356,28 @@ void FramebufferManager::SetRenderFrameBuffer() { VirtualFramebuffer *vfb = 0; for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *v = *iter; - if (MaskedEqual(v->fb_address, fb_address) && v->width == drawing_width && v->height == drawing_height && v->format == fmt) { - // Let's not be so picky for now. Let's say this is the one. - vfb = v; - // Update fb stride in case it changed - vfb->fb_stride = fb_stride; - break; + if (MaskedEqual(v->fb_address, fb_address) && v->format == fmt) { + // Okay, let's check the sizes. If the new one is bigger than the old one, recreate. + // If the opposite, just use it and hope that the game sets scissors accordingly. + if (v->width >= drawing_width && v->height >= drawing_height) { + // Let's not be so picky for now. Let's say this is the one. + vfb = v; + // Update fb stride in case it changed + vfb->fb_stride = fb_stride; + // Just hack the width/height and we should be fine. also hack renderwidth/renderheight? + v->width = drawing_width; + v->height = drawing_height; + break; + } else { + INFO_LOG(HLE, "Embiggening framebuffer (%i, %i) -> (%i, %i)", (int)v->width, (int)v->height, drawing_width, drawing_height); + // drawing_width or drawing_height is bigger. Let's recreate with the max. + // To do this right we should copy the data over too, but meh. + drawing_width = std::max((int)v->width, drawing_width); + drawing_height = std::max((int)v->height, drawing_height); + delete v; + vfbs_.erase(iter); + break; + } } } From 283f382aff958b5da538884d6cc9d6017a6739ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 20 Jun 2013 01:26:18 +0200 Subject: [PATCH 29/46] Revert "Attempted workaround for issue #2308. Needs plenty of testing! Fixes black screens in GTA when pausing for example." This reverts commit f2b7096bdf53e103b8b28909ec3a88f57a629183. --- GPU/GLES/Framebuffer.cpp | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 6f7f6703c7..2f83bb05fa 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -15,8 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include - #include "gfx_es2/glsl_program.h" #include "gfx_es2/gl_state.h" #include "gfx_es2/fbo.h" @@ -356,28 +354,12 @@ void FramebufferManager::SetRenderFrameBuffer() { VirtualFramebuffer *vfb = 0; for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *v = *iter; - if (MaskedEqual(v->fb_address, fb_address) && v->format == fmt) { - // Okay, let's check the sizes. If the new one is bigger than the old one, recreate. - // If the opposite, just use it and hope that the game sets scissors accordingly. - if (v->width >= drawing_width && v->height >= drawing_height) { - // Let's not be so picky for now. Let's say this is the one. - vfb = v; - // Update fb stride in case it changed - vfb->fb_stride = fb_stride; - // Just hack the width/height and we should be fine. also hack renderwidth/renderheight? - v->width = drawing_width; - v->height = drawing_height; - break; - } else { - INFO_LOG(HLE, "Embiggening framebuffer (%i, %i) -> (%i, %i)", (int)v->width, (int)v->height, drawing_width, drawing_height); - // drawing_width or drawing_height is bigger. Let's recreate with the max. - // To do this right we should copy the data over too, but meh. - drawing_width = std::max((int)v->width, drawing_width); - drawing_height = std::max((int)v->height, drawing_height); - delete v; - vfbs_.erase(iter); - break; - } + if (MaskedEqual(v->fb_address, fb_address) && v->width == drawing_width && v->height == drawing_height && v->format == fmt) { + // Let's not be so picky for now. Let's say this is the one. + vfb = v; + // Update fb stride in case it changed + vfb->fb_stride = fb_stride; + break; } } From c5dfccd55dd6f84be4716bab3dd2b85a597f47a0 Mon Sep 17 00:00:00 2001 From: The Dax Date: Thu, 20 Jun 2013 03:15:07 -0400 Subject: [PATCH 30/46] Implement more sceNet and sceHttp stubs. List includes: sceNetApctlAddHandler sceNetApctlDelHandler sceNetApctlInit sceNetApctlTerm sceNetInetInit sceNetInetTerm sceHttpInit sceHttpEnd --- Core/HLE/sceHttp.cpp | 14 ++++- Core/HLE/sceNet.cpp | 136 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 137 insertions(+), 13 deletions(-) diff --git a/Core/HLE/sceHttp.cpp b/Core/HLE/sceHttp.cpp index 0ba77a7ec7..d755e2f5d2 100644 --- a/Core/HLE/sceHttp.cpp +++ b/Core/HLE/sceHttp.cpp @@ -25,14 +25,24 @@ int sceHttpSetResolveRetry(int connectionID, int retryCount) return 0; } +int sceHttpInit() { + ERROR_LOG(HLE, "UNIMPL sceHttpInit()"); + return 0; +} + +int sceHttpEnd() { + ERROR_LOG(HLE, "UNIMPL sceHttpInit()"); + return 0; +} + /* * 0x62411801 sceSircsInit 0x19155a2f sceSircsEnd 0x71eef62d sceSircsSend */ const HLEFunction sceHttp[] = { - {0xab1abe07,0,"sceHttpInit"}, - {0xd1c8945e,0,"sceHttpEnd"}, + {0xab1abe07,WrapI_V,"sceHttpInit"}, + {0xd1c8945e,WrapI_V,"sceHttpEnd"}, {0xa6800c34,0,"sceHttpInitCache"}, {0x78b54c09,0,"sceHttpEndCache"}, {0x59e6d16f,0,"sceHttpEnableCache"}, diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 2ecba10ec0..d0c7821c59 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -24,12 +24,16 @@ #include "sceUtility.h" static bool netInited; +static bool netInetInited; static bool netAdhocInited; +static bool netApctlInited; static u32 adhocctlHandlerCount; +static u32 apctlHandlerCount; // TODO: Determine how many handlers we can actually have const u32 MAX_ADHOCCTL_HANDLERS = 32; +const u32 MAX_APCTL_HANDLERS = 32; enum { ERROR_NET_BUFFER_TOO_SMALL = 0x80400706, @@ -88,9 +92,19 @@ struct AdhocctlHandler { static std::map adhocctlHandlers; +struct ApctlHandler { + u32 entryPoint; + u32 argument; +}; + +static std::map apctlHandlers; + + void __NetInit() { netInited = false; netAdhocInited = false; + netApctlInited = false; + netInetInited = false; memset(&netMallocStat, 0, sizeof(netMallocStat)); } @@ -100,22 +114,40 @@ void __NetShutdown() { void __UpdateAdhocctlHandlers(int flag, int error) { u32 args[3] = { 0, 0, 0 }; + args[0] = flag; + args[1] = error; for(std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { - args[0] = flag; - args[1] = error; args[2] = it->second.argument; - __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true); + __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 5, true); + } +} + +void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { + u32 args[5] = { 0, 0, 0, 0, 0 }; + args[0] = oldState; + args[1] = newState; + args[2] = flag; + args[3] = error; + + for(std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) { + args[4] = it->second.argument; + + __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 5, true); } } // This feels like a dubious proposition, mostly... void __NetDoState(PointerWrap &p) { p.Do(netInited); + p.Do(netInetInited); p.Do(netAdhocInited); + p.Do(netApctlInited); p.Do(adhocctlHandlers); p.Do(adhocctlHandlerCount); + p.Do(apctlHandlers); + p.Do(apctlHandlerCount); p.Do(netMallocStat); p.DoMarker("net"); } @@ -274,7 +306,7 @@ int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 unknown) // TODO: Should we really write the struct if we're disconnected? int sceNetAdhocctlGetParameter(u32 paramAddr) { - ERROR_LOG(HLE, "UNTESTED %x=sceNetAdhocctlGetParameter(%x)", 0, paramAddr); + WARN_LOG(HLE, "UNTESTED sceNetAdhocctlGetParameter(%x)", paramAddr); struct SceNetAdhocctlParams params; params.channel = 0; for(int i = 0; i < 6; i++) @@ -331,7 +363,7 @@ int sceNetAdhocctlConnect(u32 ptrToGroupName) { // Write static data since we don't actually manage any memory for sceNet* yet. int sceNetGetMallocStat(u32 statPtr) { - ERROR_LOG(HLE, "UNTESTED sceNetGetMallocStat(%x)", statPtr); + WARN_LOG(HLE, "UNTESTED sceNetGetMallocStat(%x)", statPtr); if(Memory::IsValidAddress(statPtr)) Memory::WriteStruct(statPtr, &netMallocStat); else @@ -345,6 +377,88 @@ int sceNetAdhocMatchingInit(u32 memsize) { return 0; } +int sceNetInetInit() { + ERROR_LOG(HLE, "UNIMPL sceNetInetInit()"); + if (netInetInited) + return ERROR_NET_ADHOC_ALREADY_INITIALIZED; // TODO: What's the proper error for netInet already being inited? + netInetInited = true; + + return 0; +} + +int sceNetInetTerm() { + ERROR_LOG(HLE, "UNIMPL sceNetInetTerm()"); + netInetInited = false; + + return 0; +} + +int sceNetApctlInit() { + ERROR_LOG(HLE, "UNIMPL sceNetApctlInit()"); + if (netAdhocInited) + return ERROR_NET_ADHOC_ALREADY_INITIALIZED; // TODO: What's the proper error for apctl already being inited? + netApctlInited = true; + + return 0; +} + +int sceNetApctlTerm() { + ERROR_LOG(HLE, "UNIMPL sceNeApctlTerm()"); + netInetInited = false; + + return 0; +} + +// TODO: How many handlers can the PSP actually have for Apctl? +// TODO: Should we allow the same handler to be added more than once? +u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) { + bool foundHandler = false; + u32 retval = apctlHandlerCount; + struct ApctlHandler handler; + memset(&handler, 0, sizeof(handler)); + + handler.entryPoint = handlerPtr; + handler.argument = handlerArg; + + for(std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); it++) { + if(it->second.entryPoint == handlerPtr) { + foundHandler = true; + break; + } + } + + if(!foundHandler && Memory::IsValidAddress(handlerPtr)) { + if(apctlHandlerCount >= MAX_APCTL_HANDLERS) { + ERROR_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): Too many handlers", handlerPtr, handlerArg); + retval = ERROR_NET_ADHOCCTL_TOO_MANY_HANDLERS; // TODO: What's the proper error code for Apctl's TOO_MANY_HANDLERS? + return retval; + } + apctlHandlers[apctlHandlerCount++] = handler; + WARN_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, apctlHandlerCount); + } + else + ERROR_LOG(HLE, "UNTESTED sceNetApctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg); + + + // The id to return is the number of handlers currently registered + return retval; +} + +int sceNetApctlDelHandler(u32 handlerID) { + + if(apctlHandlers.find(handlerID) != apctlHandlers.end()) { + apctlHandlers.erase(handlerID); + apctlHandlerCount = apctlHandlerCount > 0? --apctlHandlerCount : 0; + WARN_LOG(HLE, "UNTESTED sceNetapctlDelHandler(%d): deleted handler %d", handlerID, handlerID); + } + else + ERROR_LOG(HLE, "UNTESTED sceNetapctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID); + + return 0; +} + + + const HLEFunction sceNet[] = { {0x39AF39A6, sceNetInit, "sceNetInit"}, {0x281928A9, WrapU_V, "sceNetTerm"}, @@ -444,7 +558,7 @@ const HLEFunction sceNetResolver[] = { }; const HLEFunction sceNetInet[] = { - {0x17943399, 0, "sceNetInetInit"}, + {0x17943399, WrapI_V, "sceNetInetInit"}, {0x2fe71fe7, 0, "sceNetInetSetsockopt"}, {0x410b34aa, 0, "sceNetInetConnect"}, {0x5be8d595, 0, "sceNetInetSelect"}, @@ -463,7 +577,7 @@ const HLEFunction sceNetInet[] = { {0xd10a1a7a, 0, "sceNetInetListen"}, {0xdb094e1b, 0, "sceNetInetAccept"}, {0x8ca3a97e, 0, "sceNetInetGetPspError"}, - {0xa9ed66b9, 0, "sceNetInetTerm"}, + {0xa9ed66b9, WrapI_V, "sceNetInetTerm"}, {0xE30B8C19, 0, "sceNetInetInetPton"}, {0xE247B6D6, 0, "sceNetInetGetpeername"}, {0x162e6fd5, 0, "sceNetInetGetsockname"}, @@ -481,10 +595,10 @@ const HLEFunction sceNetApctl[] = { {0xCFB957C6, 0, "sceNetApctlConnect"}, {0x24fe91a1, 0, "sceNetApctlDisconnect"}, {0x5deac81b, 0, "sceNetApctlGetState"}, - {0x8abadd51, 0, "sceNetApctlAddHandler"}, - {0xe2f91f9b, 0, "sceNetApctlInit"}, - {0x5963991b, 0, "sceNetApctlDelHandler"}, - {0xb3edd0ec, 0, "sceNetApctlTerm"}, + {0x8abadd51, WrapU_UU, "sceNetApctlAddHandler"}, + {0xe2f91f9b, WrapI_V, "sceNetApctlInit"}, + {0x5963991b, WrapI_U, "sceNetApctlDelHandler"}, + {0xb3edd0ec, WrapI_V, "sceNetApctlTerm"}, {0x2BEFDF23, 0, "sceNetApctlGetInfo"}, {0xa3e77e13, 0, "sceNetApctlScanSSID2"}, {0xf25a5006, 0, "sceNetApctlGetBSSDescIDList2"}, From b989292c7cfa10d7cbb71b4e03f64dd406ff455a Mon Sep 17 00:00:00 2001 From: The Dax Date: Thu, 20 Jun 2013 03:20:10 -0400 Subject: [PATCH 31/46] Fix typo in __UpdateAdhocctlHandlers and remove stray carriage return. --- Core/HLE/sceNet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index d0c7821c59..2e31cd71fe 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -99,7 +99,6 @@ struct ApctlHandler { static std::map apctlHandlers; - void __NetInit() { netInited = false; netAdhocInited = false; @@ -120,7 +119,7 @@ void __UpdateAdhocctlHandlers(int flag, int error) { for(std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { args[2] = it->second.argument; - __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 5, true); + __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true); } } From 250260cccdee1f76bca462cb1e4dbde48ac7e07c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 20 Jun 2013 01:00:53 -0700 Subject: [PATCH 32/46] Fix sceCtrl analog range for all input devices. It should map (-1.0... 0.0... 1.0) to (0... 128... 255.) However, it was instead being mapped to (1... 128... 255.) This was causing games to not respect analog movement if they checked for 100%. Fixes #2363. --- Core/HLE/sceCtrl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index d38bd48151..7d032010f4 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -161,11 +161,11 @@ void __CtrlSetAnalog(float x, float y, int stick) { std::lock_guard guard(ctrlMutex); if (stick == 0) { - ctrlCurrent.analog[0] = (u8)(x * 127.f + 128.f); - ctrlCurrent.analog[1] = (u8)(-y * 127.f + 128.f); + ctrlCurrent.analog[0] = (u8)(x * 127.5f + 128.f); + ctrlCurrent.analog[1] = (u8)(-y * 127.5f + 128.f); } else { - ctrlCurrent.analogRight[0] = (u8)(x * 127.f + 128.f); - ctrlCurrent.analogRight[1] = (u8)(-y * 127.f + 128.f); + ctrlCurrent.analogRight[0] = (u8)(x * 127.5f + 128.f); + ctrlCurrent.analogRight[1] = (u8)(-y * 127.5f + 128.f); } } From 362c5be657c49f3f649ab0c0c9802da356197fb3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 20 Jun 2013 01:11:45 -0700 Subject: [PATCH 33/46] Tweak the ctrl analog rounding to be safer. --- Core/HLE/sceCtrl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 7d032010f4..7f828cb904 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -161,11 +161,11 @@ void __CtrlSetAnalog(float x, float y, int stick) { std::lock_guard guard(ctrlMutex); if (stick == 0) { - ctrlCurrent.analog[0] = (u8)(x * 127.5f + 128.f); - ctrlCurrent.analog[1] = (u8)(-y * 127.5f + 128.f); + ctrlCurrent.analog[0] = (u8)ceilf(x * 127.5f + 127.5f); + ctrlCurrent.analog[1] = (u8)ceilf(-y * 127.5f + 127.5f); } else { - ctrlCurrent.analogRight[0] = (u8)(x * 127.5f + 128.f); - ctrlCurrent.analogRight[1] = (u8)(-y * 127.5f + 128.f); + ctrlCurrent.analogRight[0] = (u8)ceilf(x * 127.5f + 127.5f); + ctrlCurrent.analogRight[1] = (u8)ceilf(-y * 127.5f + 127.5f); } } From 2863e74e521cfee3510c610001253d1bf449dc33 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 20 Jun 2013 01:53:07 -0700 Subject: [PATCH 34/46] For now, ignore duplicate sceMpegInit()/Finish()'s. Need to properly handle module unload for this to work right. Fixes #2364. --- Core/HLE/sceMpeg.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 1ccf65b1e9..305b535df2 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -327,10 +327,11 @@ void __MpegShutdown() { u32 sceMpegInit() { if (isMpegInit) { WARN_LOG(HLE, "sceMpegInit(): already initialized"); - return ERROR_MPEG_ALREADY_INIT; + // TODO: Need to properly hook module load/unload for this to work right. + //return ERROR_MPEG_ALREADY_INIT; + } else { + INFO_LOG(HLE, "sceMpegInit()"); } - - INFO_LOG(HLE, "sceMpegInit()"); isMpegInit = true; return hleDelayResult(0, "mpeg init", 750); } @@ -1009,10 +1010,11 @@ u32 sceMpegFinish() if (!isMpegInit) { WARN_LOG(HLE, "sceMpegFinish(...): not initialized"); - return ERROR_MPEG_NOT_YET_INIT; + // TODO: Need to properly hook module load/unload for this to work right. + //return ERROR_MPEG_NOT_YET_INIT; + } else { + INFO_LOG(HLE, "sceMpegFinish(...)"); } - - INFO_LOG(HLE, "sceMpegFinish(...)"); isMpegInit = false; //__MpegFinish(); return hleDelayResult(0, "mpeg finish", 250); From 32bedefe200cb5a7b7583c866ce707f3fbc2801a Mon Sep 17 00:00:00 2001 From: The Dax Date: Thu, 20 Jun 2013 12:50:10 -0400 Subject: [PATCH 35/46] Windows: Make DirectSound buffer global to allow sound to be played, even if other applications like Steam are brought to the foreground. --- Windows/DSoundStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/DSoundStream.cpp b/Windows/DSoundStream.cpp index 45047172bf..f2e83c8b76 100644 --- a/Windows/DSoundStream.cpp +++ b/Windows/DSoundStream.cpp @@ -49,7 +49,7 @@ namespace DSound pcmwf.wBitsPerSample = 16; dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; + dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //change to set buffer size dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf; From e224180ba62cf581df1133e038f798ee36dd3f92 Mon Sep 17 00:00:00 2001 From: raven02 Date: Fri, 21 Jun 2013 01:37:52 +0800 Subject: [PATCH 36/46] Add "Cleanup Recents" button --- UI/MenuScreens.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 7acfcb95fc..7d613267b8 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -705,6 +705,10 @@ void DeveloperScreen::render() { gpu->DumpNextFrame(); } + if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 80, 0, d->T("Cleanup Recents"), ALIGN_LEFT)) { + g_Config.recentIsos.clear(); + } + UIEnd(); } From a4bdd4bfc4a96e08ce3f987efa0efe84abac4a68 Mon Sep 17 00:00:00 2001 From: Sacha Date: Fri, 21 Jun 2013 04:23:34 +1000 Subject: [PATCH 37/46] Clean up RE code in sceChnnlsv.{cpp,h} --- Core/HLE/sceChnnlsv.cpp | 825 +++++++++++++--------------------------- Core/HLE/sceChnnlsv.h | 4 +- 2 files changed, 272 insertions(+), 557 deletions(-) diff --git a/Core/HLE/sceChnnlsv.cpp b/Core/HLE/sceChnnlsv.cpp index 27c583819e..25d96d613a 100644 --- a/Core/HLE/sceChnnlsv.cpp +++ b/Core/HLE/sceChnnlsv.cpp @@ -27,321 +27,217 @@ extern "C" u8 dataBuf[2048+20]; u8* dataBuf2 = dataBuf + 20; -static const u8 hash198C[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF }; -static const u8 hash19BC[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86 }; +static const u8 hash198C[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF}; +static const u8 hash19BC[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86}; -static const u8 key000019CC[16] = {0x70, 0x44, 0xA3, 0xAE, 0xEF, 0x5D, 0xA5, 0xF2, 0x85, 0x7F, 0xF2, 0xD6, 0x94, 0xF5, 0x36, 0x3B}; -static const u8 key000019DC[16] = {0xEC, 0x6D, 0x29, 0x59, 0x26, 0x35, 0xA5, 0x7F, 0x97, 0x2A, 0x0D, 0xBC, 0xA3, 0x26, 0x33, 0x00}; -static const u8 key0000199C[16] = {0x36, 0xA5, 0x3E, 0xAC, 0xC5, 0x26, 0x9E, 0xA3, 0x83, 0xD9, 0xEC, 0x25, 0x6C, 0x48, 0x48, 0x72}; -static const u8 key000019AC[16] = {0xD8, 0xC0, 0xB0, 0xF3, 0x3E, 0x6B, 0x76, 0x85, 0xFD, 0xFB, 0x4D, 0x7D, 0x45, 0x1E, 0x92, 0x03}; +static const u8 key19CC[16] = {0x70, 0x44, 0xA3, 0xAE, 0xEF, 0x5D, 0xA5, 0xF2, 0x85, 0x7F, 0xF2, 0xD6, 0x94, 0xF5, 0x36, 0x3B}; +static const u8 key19DC[16] = {0xEC, 0x6D, 0x29, 0x59, 0x26, 0x35, 0xA5, 0x7F, 0x97, 0x2A, 0x0D, 0xBC, 0xA3, 0x26, 0x33, 0x00}; +static const u8 key199C[16] = {0x36, 0xA5, 0x3E, 0xAC, 0xC5, 0x26, 0x9E, 0xA3, 0x83, 0xD9, 0xEC, 0x25, 0x6C, 0x48, 0x48, 0x72}; +static const u8 key19AC[16] = {0xD8, 0xC0, 0xB0, 0xF3, 0x3E, 0x6B, 0x76, 0x85, 0xFD, 0xFB, 0x4D, 0x7D, 0x45, 0x1E, 0x92, 0x03}; -int sub_000014BC(u8* data, int length) +void *memxor(void * dest, const void * src, size_t n) { - *(s32*)(data + 0) = 5; - *(s32*)(data + 12) = 256; - *(s32*)(data + 4) = 0; - *(s32*)(data + 8) = 0; - *(s32*)(data + 16) = length; - int res = sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, 8); - if (res == 0) - return 0; - return -258; + char const *s = (char const*)src; + char *d = (char*)dest; + + for (; n > 0; n--) + *d++ ^= *s++; + + return dest; } -int sub_00001418(u8* data, int length, int val2) +// The reason for the values from *FromMode calculations are not known. +int numFromMode(int mode) { - *(s32*)(data + 12) = val2; - *(s32*)(data + 0) = 5; - *(s32*)(data + 4) = 0; - *(s32*)(data + 8) = 0; - *(s32*)(data + 16) = length; - int res = sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, 7); - if (res == 0) - return 0; - return -257; -} - - -int sub_000015B0(u8* data, int alignedLen, u8* buf, int val) -{ - u8 sp0[16]; - - for(int i = 0; i < 16; i++) - { - sp0[i] = data[alignedLen+i+4]; - } - int res = sub_00001418(data, alignedLen, val); - if (res != 0) - { - return res; - } - - for(int i = 0; i < 16; i++) - { - data[i] = data[i] ^ buf[i]; - } - for(int i = 0; i < 16; i++) - { - buf[i] = sp0[i]; - } - return 0; -} - -int sub_00000000(u8* data_out, u8* data, int alignedLen, u8* data2, int& data3, int mode) -{ - for(int i = 0; i < 16; i++) - { - data_out[20+i] = data2[i]; - } - int valS4 = 100; - int res; - if (mode == 6) - { - valS4 = 100; - for(int i = 0; i < 16; i++) - { - data_out[20+i] = data_out[20+i] ^ key000019DC[i]; - } - res = sub_000014BC(data_out, 16); - for(int i = 0; i < 16; i++) - { - data_out[i] = data_out[i] ^ key000019CC[i]; - } - } - else if (mode == 4) - { - valS4 = 87; - for(int i = 0; i < 16; i++) - { - data_out[20+i] = data_out[20+i] ^ key000019AC[i]; - } - res = sub_000014BC(data_out, 16); - for(int i = 0; i < 16; i++) - { - data_out[i] = data_out[i] ^ key0000199C[i]; - } - } - else if (mode == 2) - { - res = sub_000014BC(data_out, 16); - valS4 = 83; - } - else if (mode == 1) - { - res = sub_00001418(data_out, 16, 4); - valS4 = 83; - } - else if (mode == 3) - { - valS4 = 87; - for(int i = 0; i < 16; i++) - { - data_out[i+20] = data_out[i+20] ^ key000019AC[i]; - } - res = sub_00001418(data_out, 16, 14); - for(int i = 0; i < 16; i++) - { - data_out[i] = data_out[i] ^ key0000199C[i]; - } - } - else - { - valS4 = 100; - for(int i = 0; i < 16; i++) - { - data_out[i + 20] = data_out[i + 20] ^ key000019DC[i]; - } - res = sub_00001418(data_out, 16, 18); - for(int i = 0; i < 16; i++) - { - data_out[i] = data_out[i] ^ key000019CC[i]; - } - } - - u8 sp16[16]; - if (res != 0) - { - return res; - } - for(int i = 0; i < 16; i++) - { - sp16[i] = data_out[i]; - } - u8 sp0[16]; - if (data3 == 1) - { - for(int i = 0; i < 16; i++) - { - sp0[i] = 0; - } - } - else - { - for(int i = 0; i < 12; i++) - { - sp0[i] = sp16[i]; - } - sp0[12] = (data3-1) & 0xFF ; - sp0[13] = ((data3-1) >> 8) & 0xFF; - sp0[14] = ((data3-1) >> 16) & 0xFF; - sp0[15] = ((data3-1) >> 24) & 0xFF; - } - - if ((u32)20 < (u32)alignedLen + 20) - { - for(int i = 20; i < alignedLen + 20; i += 16) - { - for(int j = 0; j < 12; j++) - { - data_out[i+j] = sp16[j]; - } - data_out[12+i] = data3; - data_out[13+i] = (data3 >> 8) & 0xFF; - data_out[14+i] = (data3 >> 16) & 0xFF; - data_out[15+i] = (data3 >> 24) & 0xFF; - data3++; - } - } - - res = sub_000015B0(data_out, alignedLen, sp0, valS4); - if (res != 0) - { - return res; - } - if (res >= alignedLen) - { - return 0; - } - for(int i = 0; i < alignedLen; i++) - { - data[i] = data[i] ^ data_out[i]; - } - - return 0; -} - -int sub_000013C8(u8* data, int size, int num) -{ - *(int*)(data+0) = 4; - *(int*)(data+4) = 0; - *(int*)(data+8) = 0; - *(int*)(data+12) = num; - *(int*)(data+16) = size; - size = size + 20; - - int res = sceUtilsBufferCopyWithRange(data,size,data,size,4); - if(res != 0) - { - return -257; - } - return 0; -} - -int sub_00001468(u8* data, int size) -{ - *(int*)(data+0) = 4; - *(int*)(data+12) = 256; - *(int*)(data+4) = 0; - *(int*)(data+8) = 0; - *(int*)(data+16) = size; - size = size + 20; - - int res = sceUtilsBufferCopyWithRange(data,size,data,size,5); - if(res != 0) - { - return -258; - } - return 0; -} - -int sub_00001510(u8* data, int size, u8* result , int num) -{ - for(int i = 0; i < 16; i++) - { - int v1 = data[i+20]; - v1 = v1 ^ result[i]; - data[i+20] = v1; - } - - int res = sub_000013C8(data, size, num); - if(res != 0) - { - return res; - } - - for(int i = 0; i < 16; i++) - { - result[i] = data[size + i + 4]; - } - return 0; -} - -int sub_000017A8(u8* data) - { - int res = sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14); - if (res == 0) - return 0; - return -261; -} - -int sceSdGetLastIndex(u32 addressCtx,u32 addressHash, u32 addressKey) -{ - pspChnnlsvContext1 ctx; - Memory::ReadStruct(addressCtx,&ctx); - u8* in_hash; - u8* in_key; - in_hash = Memory::GetPointer(addressHash); - in_key = Memory::GetPointer(addressKey); - - int res = sceSdGetLastIndex_(ctx, in_hash, in_key); - - Memory::WriteStruct(addressCtx,&ctx); - return res; -} -int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) -{ - if(ctx.keyLength >= 17) - { - return -1026; - } int num = 0; - switch(ctx.mode) + switch(mode) { - case 6: - num = 17; - break; - case 4: - num = 13; + case 1: + num = 3; break; case 2: num = 5; break; - case 1: - num = 3; - break; case 3: num = 12; break; + case 4: + num = 13; + break; + case 6: + num = 17; + break; default: num = 16; break; } + return num; +} +int numFromMode2(int mode) +{ + int num = 18; + if (mode == 1) + num = 4; + else if (mode == 3) + num = 14; + return num; +} - memset(dataBuf2,0,16); +int typeFromMode(int mode) +{ + return (mode == 1 || mode == 2) ? 83 : + ((mode == 3 || mode == 4) ? 87 : 100); +} - int res = sub_000013C8(dataBuf,16,num); - if(res != 0) - { +int kirkSendCmd(u8* data, int length, int num, bool encrypt) +{ + *(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC; + *(int*)(data+4) = 0; + *(int*)(data+8) = 0; + *(int*)(data+12) = num; + *(int*)(data+16) = length; + + if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0)) + return -257; + + return 0; +} + +int kirkSendFuseCmd(u8* data, int length, bool encrypt) +{ + *(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC; + *(int*)(data+4) = 0; + *(int*)(data+8) = 0; + *(int*)(data+12) = 256; + *(int*)(data+16) = length; + + // Note: CMD 5 and 8 are not available, will always return -1 + if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE)) + return -258; + + return 0; +} + +int sub_15B0(u8* data, int alignedLen, u8* buf, int val) +{ + u8 sp0[16]; + memcpy(sp0, data+alignedLen+4, 16); + + int res = kirkSendCmd(data, alignedLen, val, false); + if (res) return res; + + memxor(data, buf, 16); + memcpy(buf, sp0, 16); + return 0; +} + +int sub_0000(u8* data_out, u8* data, int alignedLen, u8* data2, int& data3, int mode) +{ + memcpy(data_out+20, data2, 16); + // Mode 1:2 is 83, 3:4 is 87, 5:6 is 100 + int type = typeFromMode(mode); + int res; + + if (type == 87) + memxor(data_out+20, key19AC, 16); + else if (type == 100) + memxor(data_out+20, key19DC, 16); + + // Odd is Cmd, Even is FuseCmd + switch(mode) + { + case 2: case 4: case 6: res = kirkSendFuseCmd(data_out, 16, false); + break; + case 1: case 3: default:res = kirkSendCmd(data_out, 16, numFromMode2(mode), false); + break; } - u8 data1[16]; - u8 data2[16]; + if (type == 87) + memxor(data_out, key199C, 16); + else if (type == 100) + memxor(data_out, key19CC, 16); - memcpy(data1,dataBuf2,16); - int tmp1 = 0; - if((s8)data1[0] < 0) - tmp1 = 135; + if (res) + return res; + + u8 sp0[16], sp16[16]; + memcpy(sp16, data_out, 16); + if (data3 == 1) + { + memset(sp0, 0, 16); + } + else + { + memcpy(sp0, sp16, 12); + *(u32*)(sp0+12) = data3-1; + } + + if (alignedLen > 0) + { + for(int i = 20; i < alignedLen + 20; i += 16) + { + memcpy(data_out+i, sp16, 12); + *(u32*)(data_out+12+i) = data3; + data3++; + } + } + + res = sub_15B0(data_out, alignedLen, sp0, type); + if (res) + return res; + + if (alignedLen > 0) + memxor(data, data_out, alignedLen); + + return 0; +} + +int sub_1510(u8* data, int size, u8* result , int num) +{ + memxor(data+20, result, 16); + + int res = kirkSendCmd(data, size, num, true); + if(res) + return res; + + memcpy(result, data+size+4, 16); + return 0; +} + +int sub_17A8(u8* data) +{ + if (sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0) + return 0; + return -261; +} + +int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) +{ + pspChnnlsvContext1 ctx; + Memory::ReadStruct(addressCtx, &ctx); + int res = sceSdGetLastIndex_(ctx, Memory::GetPointer(addressHash), Memory::GetPointer(addressKey)); + Memory::WriteStruct(addressCtx, &ctx); + return res; +} + +int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) +{ + if(ctx.keyLength >= 17) + return -1026; + + int num = numFromMode(ctx.mode); + + memset(dataBuf2, 0, 16); + + int res = kirkSendCmd(dataBuf, 16, num, true); + if(res) + return res; + + u8 data1[16], data2[16]; + + memcpy(data1, dataBuf2, 16); + int tmp1 = (data1[0] & 0x80) ? 135 : 0; for(int i = 0; i < 15; i++) { @@ -373,72 +269,37 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) int oldKeyLength = ctx.keyLength; *(s8*)(ctx.key + ctx.keyLength) = -128; - if(oldKeyLength + 1 < 16) - { - for(int i = oldKeyLength + 1; i < 16; i++) - { - *(s8*)(ctx.key + i) = 0; - } - } + int i = oldKeyLength + 1; + if(i < 16) + memset(ctx.key + i, 0, 16 - i); } - for(int i = 0; i < 16; i++) - { - ctx.key[i] = ctx.key[i] ^ data1[i]; - } + memxor(ctx.key, data1, 16); + memcpy(dataBuf2, ctx.key, 16); + memcpy(data2, ctx.result, 16); - for(int i = 0; i < 16; i++) - { - dataBuf2[i] = ctx.key[i]; - } - - for(int i = 0; i < 16; i++) - { - data2[i] = ctx.result[i]; - } - int ret = sub_00001510(dataBuf,16,data2,num); - if(ret != 0) - { + int ret = sub_1510(dataBuf, 16, data2, num); + if(ret) return ret; - } - if((u32)(ctx.mode-3) < 2) - { - for(int i = 0; i < 16; i++) - { - data2[i] = data2[i] ^ hash198C[i]; - } - } - else if((u32)(ctx.mode-5) < 2) - { - for(int i = 0; i < 16; i++) - { - data2[i] = data2[i] ^ hash19BC[i]; - } - } + if(ctx.mode == 3 || ctx.mode == 4) + memxor(data2, hash198C, 16); + else if(ctx.mode == 5 || ctx.mode == 6) + memxor(data2, hash19BC, 16); int cond = ((ctx.mode ^ 0x2) < 1 || (ctx.mode ^ 0x4) < 1 || ctx.mode == 6); if(cond != 0) { - for(int i = 0; i < 16; i++) - { - dataBuf2[i] = data2[i]; - } - int ret = sub_00001468(dataBuf,16); - if(ret != 0) - { + memcpy(dataBuf2, data2, 16); + int ret = kirkSendFuseCmd(dataBuf, 16, true); + if(ret) return ret; - } - int res = sub_000013C8(dataBuf,16,num); - if(res != 0) - { - return res; - } - for(int i = 0; i < 16; i++) - { - data2[i] = dataBuf2[i]; - } + int res = kirkSendCmd(dataBuf, 16, num, true); + if(res) + return res; + + memcpy(data2, dataBuf2, 16); } if(in_key != 0) @@ -448,37 +309,16 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) data2[i] = in_key[i] ^ data2[i]; } - for(int i = 0; i < 16; i++) - { - dataBuf2[i] = data2[i]; - } + memcpy(dataBuf2, data2, 16); - int res = sub_000013C8(dataBuf,16,num); - if(res != 0) - { + int res = kirkSendCmd(dataBuf, 16, num, true); + if(res) return res; - } - for(int i = 0; i < 16; i++) - { - data2[i] = dataBuf2[i]; - } - } - for(int i = 0; i < 16; i++) - { - in_hash[i] = data2[i]; - } - for(int i = 0; i < 16; i++) - { - ctx.result[i] = 0; + memcpy(data2, dataBuf2, 16); } - - for(int i = 0; i < 16; i++) - { - ctx.key[i] = 0; - } - ctx.keyLength = 0; - ctx.mode = 0; + memcpy(in_hash, data2, 16); + sceSdSetIndex_(ctx, 0); return 0; } @@ -495,8 +335,8 @@ int sceSdSetIndex(u32 addressCtx, int value) int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value) { ctx.mode = value; - memset(ctx.result,0,16); - memset(ctx.key,0,16); + memset(ctx.result, 0, 16); + memset(ctx.key, 0, 16); ctx.keyLength = 0; return 0; } @@ -505,104 +345,52 @@ int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value) int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length) { pspChnnlsvContext1 ctx; - Memory::ReadStruct(addressCtx,&ctx); - u8* data; - data = Memory::GetPointer(addressData); + Memory::ReadStruct(addressCtx, &ctx); + int res = sceSdRemoveValue_(ctx, Memory::GetPointer(addressData), length); + Memory::WriteStruct(addressCtx, &ctx); - int res = sceSdRemoveValue_(ctx, data, length); - - Memory::WriteStruct(addressCtx,&ctx); return res; } int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length) { if(ctx.keyLength >= 17) - { return -1026; - } + if(ctx.keyLength + length < 17) { - if(length == 0) - { - return 0; - } - for(int i = 0; i < length; i++) - { - ctx.key[ctx.keyLength+i] = data[i]; - } + memcpy(ctx.key+ctx.keyLength, data, length); ctx.keyLength = ctx.keyLength + length; return 0; } - int mode = ctx.mode; - int num = 0; - switch(mode) - { - case 6: - num = 17; - break; - case 4: - num = 13; - break; - case 2: - num = 5; - break; - case 1: - num = 3; - break; - case 3: - num = 12; - break; - default: - num = 16; - break; - } + int num = numFromMode(ctx.mode); - memset(dataBuf2,0,2048); + memset(dataBuf2, 0, 2048); + memcpy(dataBuf2, ctx.key, ctx.keyLength); - if(ctx.keyLength > 0) - { - memcpy(dataBuf2,ctx.key,ctx.keyLength); - } int len = (ctx.keyLength + length) & 0xF; if(len == 0) len = 16; - int oldLength = ctx.keyLength; + int newSize = ctx.keyLength; ctx.keyLength = len; int diff = length - len; - if(len != 0) + memcpy(ctx.key, data+diff, len); + for(int i = 0; i < diff; i++) { - memcpy(ctx.key,data+diff,len); - } - - int newSize = oldLength; - if(diff != 0) - { - for(int i = 0; i < diff; i++) + if(newSize == 2048) { - if(newSize == 2048) - { - int res = sub_00001510(dataBuf,2048,ctx.result,num); - if(res != 0) - { - return res; - } - newSize = 0; - } - dataBuf2[newSize] = data[i]; - newSize++; + int res = sub_1510(dataBuf, 2048, ctx.result, num); + if(res) + return res; + newSize = 0; } + dataBuf2[newSize] = data[i]; + newSize++; } - if(newSize == 0) - { - return 0; - } - int res = sub_00001510(dataBuf,newSize,ctx.result, num); - if(res == 0) - { - return res; - } + if(newSize) + sub_1510(dataBuf, newSize, ctx.result, num); + // The RE code showed this always returning 0. I suspect it would want to return res instead. return 0; } @@ -626,116 +414,49 @@ int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8* ctx2.unkn = 1; if (uknw == 2) { - for(int i = 0; i < 16; i++) - { - ctx2.unknown[i] = data[i]; - } - if (cryptkey == 0) - { - return 0; - } + memcpy(ctx2.cryptedData, data, 16); + if (cryptkey) + memxor(ctx2.cryptedData, cryptkey, 16); - for(int i = 0; i < 16; i++) - { - ctx2.unknown[i] = ctx2.unknown[i] ^ cryptkey[i]; - } return 0; } else if (uknw == 1) { u8 kirkHeader[37]; u8* kirkData = kirkHeader+20; - int res = sub_000017A8(kirkHeader); - if (res != 0) - { + int res = sub_17A8(kirkHeader); + if (res) return res; - } - for(int i = 15; i >= 0 ; i--) + + memcpy(kirkHeader+20, kirkHeader, 16); + memset(kirkHeader+32, 0, 4); + + int type = typeFromMode(mode); + if (type == 87) + memxor(kirkData, key199C, 16); + else if (type == 100) + memxor(kirkData, key19CC, 16); + + switch (mode) { - kirkHeader[i+20] = kirkHeader[i]; - } - for(int i = 0; i < 4; i++) - { - kirkHeader[i+32] = 0; + case 2: case 4: case 6: res = kirkSendFuseCmd(kirkHeader, 16, true); + break; + case 1: case 3: default:res = kirkSendCmd(kirkHeader, 16, numFromMode2(mode), true); + break; } - if (mode == 6) - { - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019CC[i]; - } - res = sub_00001468(kirkHeader, 16); - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019DC[i]; - } - } - else if (mode == 4) - { - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key0000199C[i]; - } - res = sub_00001468(kirkHeader, 16); - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019AC[i]; - } - } - else if (mode == 2) - { - res = sub_00001468(kirkHeader, 16); - } - else if (mode == 1) - { - res = sub_000013C8(kirkHeader, 16, 4); - } - else if (mode == 3) - { - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key0000199C[i]; - } - res = sub_000013C8(kirkHeader, 16, 14); - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019AC[i]; - } - } - else - { - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019CC[i]; - } - res = sub_000013C8(kirkHeader, 16, 18); - for(int i = 0; i < 16; i++) - { - kirkData[i] = kirkData[i] ^ key000019DC[i]; - } - } + if (type == 87) + memxor(kirkData, key19AC, 16); + else if (type == 100) + memxor(kirkData, key19DC, 16); - if (res != 0) - { + if (res) return res; - } - for(int i = 0; i < 16; i++) - { - ctx2.unknown[i] = kirkData[i]; - } - for(int i = 0; i < 16; i++) - { - data[i] = kirkData[i]; - } - if (cryptkey != 0) - { - for(int i = 0; i < 16; i++) - { - ctx2.unknown[i] = ctx2.unknown[i] ^ cryptkey[i]; - } - } + memcpy(ctx2.cryptedData, kirkData, 16); + memcpy(data, kirkData, 16); + if (cryptkey) + memxor(ctx2.cryptedData, cryptkey, 16); } return 0; @@ -770,12 +491,10 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen) { for(i = 0; alignedLen >= 2048; i += 2048) { - int res = sub_00000000(kirkData, data + i, 2048, ctx.unknown, ctx.unkn, ctx.mode); - alignedLen = alignedLen - 2048; - if (res != 0) - { + int res = sub_0000(kirkData, data + i, 2048, ctx.cryptedData, ctx.unkn, ctx.mode); + alignedLen -= 2048; + if (res) return res; - } } } if (alignedLen == 0) @@ -783,8 +502,7 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen) return 0; } - int res = sub_00000000(kirkData, data + i, alignedLen, ctx.unknown, ctx.unkn, ctx.mode); - return res; + return sub_0000(kirkData, data + i, alignedLen, ctx.cryptedData, ctx.unkn, ctx.mode); } int sceChnnlsv_21BE78B4(u32 ctxAddr) @@ -800,10 +518,7 @@ int sceChnnlsv_21BE78B4(u32 ctxAddr) int sceChnnlsv_21BE78B4_(pspChnnlsvContext2& ctx) { - for(int i = 0; i < 16; i++) - { - ctx.unknown[i] = 0; - } + memset(ctx.cryptedData, 0, 16); ctx.unkn = 0; ctx.mode = 0; @@ -822,6 +537,6 @@ const HLEFunction sceChnnlsv[] = void Register_sceChnnlsv() { - RegisterModule("sceChnnlsv",ARRAY_SIZE(sceChnnlsv),sceChnnlsv); + RegisterModule("sceChnnlsv", ARRAY_SIZE(sceChnnlsv), sceChnnlsv); kirk_init(); } diff --git a/Core/HLE/sceChnnlsv.h b/Core/HLE/sceChnnlsv.h index d6ec1480f3..df7604735f 100644 --- a/Core/HLE/sceChnnlsv.h +++ b/Core/HLE/sceChnnlsv.h @@ -23,7 +23,7 @@ typedef struct _pspChnnlsvContext1 { /** Context data */ u8 result[0x10]; - u8 key[0x10]; + u8 key[0x10]; int keyLength; } pspChnnlsvContext1; @@ -31,7 +31,7 @@ typedef struct _pspChnnlsvContext2 { /** Context data */ int mode; int unkn; - u8 unknown[0x92]; + u8 cryptedData[0x92]; } pspChnnlsvContext2; int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value); From a6c9c7e7c6a2ababc9108771e9e620be68bbafa3 Mon Sep 17 00:00:00 2001 From: raven02 Date: Fri, 21 Jun 2013 02:54:10 +0800 Subject: [PATCH 38/46] Comment out date/time format buttons --- UI/MenuScreens.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 7d613267b8..c4f7428b14 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1172,6 +1172,7 @@ void SystemScreen::render() { y += 10; } + /* bool time = g_Config.iTimeFormat > 0 ; UICheckBox(GEN_ID, x, y += stride, s->T("Time Format"), ALIGN_TOPLEFT, &time); if (time) { @@ -1219,7 +1220,8 @@ void SystemScreen::render() { y += 10; } else g_Config.iDateFormat = 0; - + */ + UICheckBox(GEN_ID, x, y += stride, s->T("Enable Cheats"), ALIGN_TOPLEFT, &g_Config.bEnableCheats); if (g_Config.bEnableCheats) { HLinear hlinear1(x + 60, y += stride + 10, 20); From eaede89761c97292b0c929abbcc0d2765235a46e Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 21:34:35 +0200 Subject: [PATCH 39/46] Support tex level factor 000001 (fixed at 0, that is, mipmapping off) --- GPU/GLES/DisplayListInterpreter.cpp | 5 ++--- GPU/GLES/TextureCache.cpp | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 118575425e..af91a48b3b 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -956,9 +956,8 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { break; case GE_CMD_TEXLEVEL: - if (data == 1) - WARN_LOG_REPORT_ONCE(texLevel1, G3D, "Unsupported texture level bias settings: %06x", data) - else if (data != 0) + // We support 000001, it means fixed at mip level 0. Don't report 0 as it's normal. + if (data != 1 && data != 0) WARN_LOG_REPORT_ONCE(texLevel2, G3D, "Unsupported texture level bias settings: %06x", data); break; #endif diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 39984d410c..82772eb823 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -492,6 +492,9 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { bool sClamp = gstate.texwrap & 1; bool tClamp = (gstate.texwrap>>8) & 1; + + bool noMip = gstate.texlevel == 0x000001; // Fix texlevel at 0 + if (entry.maxLevel == 0) { // Enforce no mip filtering, for safety. minFilt &= 1; // no mipmaps yet @@ -511,7 +514,7 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { minFilt |= 1; } - if (!g_Config.bMipMap) { + if (!g_Config.bMipMap || noMip) { magFilt &= 1; minFilt &= 1; } From 27f8f6a2f5c0b8c82593b6688330ca42de1b4fe9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 21:35:04 +0200 Subject: [PATCH 40/46] Logging reduction --- Core/HLE/sceAtrac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index 3f3ea5175f..d34d52b565 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -528,7 +528,7 @@ u32 _AtracAddStreamData(int atracID, u8 *buf, u32 bytesToAdd) { // because that function would tell games how to add the left stream data. u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) { - INFO_LOG(HLE, "sceAtracAddStreamData(%i, %08x)", atracID, bytesToAdd); + DEBUG_LOG(HLE, "sceAtracAddStreamData(%i, %08x)", atracID, bytesToAdd); Atrac *atrac = getAtrac(atracID); if (!atrac) { return 0; From 2953d01d15d97fd3922fc18f2633b9241d3e04c5 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 21:51:31 +0200 Subject: [PATCH 41/46] UI tweaks --- UI/MenuScreens.cpp | 2 +- UI/PluginScreen.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index e682b32bae..ced7085e53 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1511,7 +1511,7 @@ static const char * credits[] = { "PPSSPP is intended for educational purposes only.", "", "Please make sure that you own the rights to any games", - "you play by owning the UMD or buying the digital", + "you play by owning the UMD or by buying the digital", "download from the PSN store on your real PSP.", "", "", diff --git a/UI/PluginScreen.cpp b/UI/PluginScreen.cpp index bbc37c8b2c..8fb535b6ae 100644 --- a/UI/PluginScreen.cpp +++ b/UI/PluginScreen.cpp @@ -55,7 +55,7 @@ void PluginScreen::CreateViews() { Margins textMargins(20,17); Margins buttonMargins(10,10); - root_->Add(new TextView(UBUNTU24, "Atrac3+ Audio Decoding Support", ALIGN_HCENTER, 1.0f, new LinearLayoutParams(textMargins))); + root_->Add(new TextView(UBUNTU24, "Atrac3+ Audio Support", ALIGN_HCENTER, 1.5f, new LinearLayoutParams(textMargins))); ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); LinearLayout *scrollContents = new LinearLayout(ORIENT_VERTICAL); @@ -66,11 +66,11 @@ void PluginScreen::CreateViews() { const char *legalityNotice = p->T("Origins are dubious", "* Mai's Atrac3+ decoder is currently required\n" - "for audio in many games.\n" + "for background audio and voice in many games.\n" "Please note that the origins of this code are dubious.\n" "Choose More Information for more information."); - scrollContents->Add(new TextView(0, legalityNotice, ALIGN_LEFT, 1.0f, new LinearLayoutParams(textMargins) )); + scrollContents->Add(new TextView(0, legalityNotice, ALIGN_LEFT, 0.65f, new LinearLayoutParams(textMargins) )); progress_ = root_->Add(new ProgressBar()); progress_->SetVisibility(V_GONE); From 2694343243e68e6d3e940f14258234486bb31cfc Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 22:18:44 +0200 Subject: [PATCH 42/46] Another attempt at reusing bigger framebuffers. Doesn't solve everything but hopefully won't break much like the last attempt. --- GPU/GLES/Framebuffer.cpp | 35 ++++++++++++++++++++++++++++------- GPU/GLES/Framebuffer.h | 6 ++++++ GPU/GLES/StateMapping.cpp | 4 ++-- native | 2 +- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 2f83bb05fa..8ea2711612 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -350,16 +350,35 @@ void FramebufferManager::SetRenderFrameBuffer() { int drawing_width, drawing_height; GuessDrawingSize(drawing_width, drawing_height); - // Find a matching framebuffer + int buffer_width = drawing_width; + int buffer_height = drawing_height; + + // Find a matching framebuffer, same size or bigger VirtualFramebuffer *vfb = 0; for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *v = *iter; - if (MaskedEqual(v->fb_address, fb_address) && v->width == drawing_width && v->height == drawing_height && v->format == fmt) { - // Let's not be so picky for now. Let's say this is the one. - vfb = v; - // Update fb stride in case it changed - vfb->fb_stride = fb_stride; - break; + if (MaskedEqual(v->fb_address, fb_address) && v->format == fmt) { + // Okay, let's check the sizes. If the new one is bigger than the old one, recreate. + // If the opposite, just use it and hope that the game sets scissors accordingly. + if (v->bufferWidth >= drawing_width && v->bufferHeight >= drawing_height) { + // Let's not be so picky for now. Let's say this is the one. + vfb = v; + // Update fb stride in case it changed + vfb->fb_stride = fb_stride; + // Just hack the width/height and we should be fine. also hack renderwidth/renderheight? + v->width = drawing_width; + v->height = drawing_height; + break; + } else { + INFO_LOG(HLE, "Embiggening framebuffer (%i, %i) -> (%i, %i)", (int)v->width, (int)v->height, drawing_width, drawing_height); + // drawing_width or drawing_height is bigger. Let's recreate with the max. + // To do this right we should copy the data over too, but meh. + buffer_width = std::max((int)v->width, drawing_width); + buffer_height = std::max((int)v->height, drawing_height); + delete v; + vfbs_.erase(iter); + break; + } } } @@ -379,6 +398,8 @@ void FramebufferManager::SetRenderFrameBuffer() { vfb->height = drawing_height; vfb->renderWidth = (u16)(drawing_width * renderWidthFactor); vfb->renderHeight = (u16)(drawing_height * renderHeightFactor); + vfb->bufferWidth = buffer_width; + vfb->bufferHeight = buffer_height; vfb->format = fmt; vfb->usageFlags = FB_USAGE_RENDERTARGET; vfb->dirtyAfterDisplay = true; diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 9285cab997..78a6dfa3eb 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -54,10 +54,16 @@ struct VirtualFramebuffer { int z_stride; // There's also a top left of the drawing region, but meh... + + // width/height: The detected size of the current framebuffer. u16 width; u16 height; + // renderWidth/renderHeight: The actual size we render at. May be scaled to render at higher resolutions. u16 renderWidth; u16 renderHeight; + // bufferWidth/bufferHeight: The actual (but non scaled) size of the buffer we render to. May only be bigger than width/height. + u16 bufferWidth; + u16 bufferHeight; u16 usageFlags; diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 813be0caa8..4582fa18ca 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -265,8 +265,8 @@ void TransformDrawEngine::ApplyDrawState(int prim) { if (g_Config.bBufferedRendering) { renderX = 0; renderY = 0; - renderWidth = framebufferManager_->GetRenderWidth(); - renderHeight = framebufferManager_->GetRenderHeight(); + renderWidth = framebufferManager_->GetRenderWidth(); + renderHeight = framebufferManager_->GetRenderHeight(); renderWidthFactor = (float)renderWidth / framebufferManager_->GetTargetWidth(); renderHeightFactor = (float)renderHeight / framebufferManager_->GetTargetHeight(); } else { diff --git a/native b/native index deb4ba8323..0a26fae856 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit deb4ba83235a86491d073db73a1e5bab2a5ce523 +Subproject commit 0a26fae856aecdaa426d92fa5dde101b19487796 From 7ebc5b6daaaca67507a1c2775c9df21ddd6bc130 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 22:37:19 +0200 Subject: [PATCH 43/46] Fix typo, update lang (latest Swedish translation and more) --- UI/MenuScreens.cpp | 2 +- lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index ced7085e53..4a47e67991 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1161,7 +1161,7 @@ void SystemScreen::render() { UICheckBox(GEN_ID, x, y += stride, s->T("Fast Memory", "Fast Memory (unstable)"), ALIGN_TOPLEFT, &g_Config.bFastMemory); UICheckBox(GEN_ID, x, y += stride, s->T("Daylight Savings"), ALIGN_TOPLEFT, &g_Config.bDayLightSavings); - UICheckBox(GEN_ID, x, y += stride, s->T("Button Perference"), ALIGN_TOPLEFT, &g_Config.bButtonPreference); + UICheckBox(GEN_ID, x, y += stride, s->T("Button Preference"), ALIGN_TOPLEFT, &g_Config.bButtonPreference); if (g_Config.bButtonPreference) { char button[256]; std::string type; diff --git a/lang b/lang index cf710f2017..81dc0b9141 160000 --- a/lang +++ b/lang @@ -1 +1 @@ -Subproject commit cf710f2017db93c4019ce53a03764edf3136fa84 +Subproject commit 81dc0b9141e7d1445efc7b152b88ab16ff75c737 From 34e6b72599fd35d2954bfa47b60242651e05626e Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 23:06:05 +0200 Subject: [PATCH 44/46] Fix nomip check bug --- GPU/GLES/TextureCache.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 82772eb823..e6fee64e7a 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -492,8 +492,7 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { bool sClamp = gstate.texwrap & 1; bool tClamp = (gstate.texwrap>>8) & 1; - - bool noMip = gstate.texlevel == 0x000001; // Fix texlevel at 0 + bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001; // Fix texlevel at 0 if (entry.maxLevel == 0) { // Enforce no mip filtering, for safety. From 916184d2f4bcab877f7830f5b91432580fd070c5 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Jun 2013 23:30:21 +0200 Subject: [PATCH 45/46] Optimize the most common light type, directional, by doing the normalization beforehand. May shorten some shaders below Mali's limit with luck. --- GPU/GLES/ShaderManager.cpp | 17 ++++++++++++++++- GPU/GLES/VertexShaderGenerator.cpp | 7 ++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index c4ab5939c0..b727481bc9 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -390,7 +390,22 @@ void LinkedShader::updateUniforms() { for (int i = 0; i < 4; i++) { if (dirtyUniforms & (DIRTY_LIGHT0 << i)) { - if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, gstate_c.lightpos[i]); + GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); + if (type == GE_LIGHTTYPE_DIRECTIONAL) { + // Prenormalize + float x = gstate_c.lightpos[i][0]; + float y = gstate_c.lightpos[i][1]; + float z = gstate_c.lightpos[i][2]; + float len = sqrtf(x*x+y*y+z*z); + if (len == 0.0f) + len = 1.0f; + else + len = 1.0f / len; + float vec[3] = { x / len, y / len, z / len }; + if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, vec); + } else { + if (u_lightpos[i] != -1) glUniform3fv(u_lightpos[i], 1, gstate_c.lightpos[i]); + } if (u_lightdir[i] != -1) glUniform3fv(u_lightdir[i], 1, gstate_c.lightdir[i]); if (u_lightatt[i] != -1) glUniform3fv(u_lightatt[i], 1, gstate_c.lightatt[i]); if (u_lightangle[i] != -1) glUniform1f(u_lightangle[i], gstate_c.lightangle[i]); diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index 785e6db6b5..9ae40d540d 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -429,9 +429,10 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3); GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); - if (type == GE_LIGHTTYPE_DIRECTIONAL) - WRITE(p, " toLight = normalize(u_lightpos%i);\n", i); - else { + if (type == GE_LIGHTTYPE_DIRECTIONAL) { + // We prenormalize light positions for directional lights. + WRITE(p, " toLight = u_lightpos%i;\n", i); + } else { WRITE(p, " toLight = u_lightpos%i - worldpos;\n", i); WRITE(p, " distance = length(toLight);\n"); WRITE(p, " toLight /= distance;\n"); From 4bb9e32f03e4e6f9ee7916865880151577e89f08 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 21 Jun 2013 01:01:28 +0200 Subject: [PATCH 46/46] Atrac3: Bail on bad data --- Core/HLE/sceAtrac.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index d34d52b565..6dcd66e036 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -580,7 +580,11 @@ u32 _AtracDecodeData(int atracID, u8* outbuf, u32 *SamplesNum, u32* finish, int if (avret < 0) { ERROR_LOG(HLE, "avcodec_decode_audio4: Error decoding audio %d", avret); av_free_packet(&packet); - break; + // Avoid getting stuck in a loop (Virtua Tennis) + *SamplesNum = 0; + *finish = 1; + *remains = 0; + return ATRAC_ERROR_ALL_DATA_DECODED; } if (got_frame) {