diff --git a/Common/MemArena.cpp b/Common/MemArena.cpp index b8191b0808..c88f764989 100644 --- a/Common/MemArena.cpp +++ b/Common/MemArena.cpp @@ -351,7 +351,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); - exit(0); return 0; } #else @@ -377,7 +376,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena if (!Memory_TryBase(arena->memmap->Base(), views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); - exit(0); return 0; } u8* base = arena->memmap->Base(); @@ -387,7 +385,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); - exit(0); return 0; } #endif diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 589dde661f..b900b5dd3a 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -199,7 +199,7 @@ void ElfReader::LoadRelocations2(int rel_seg) buf += flag_table_size; type_table = buf; - type_table_size = flag_table[0]; + type_table_size = type_table[0]; buf += type_table_size; rel_base = 0; diff --git a/Core/HDRemaster.h b/Core/HDRemaster.h index af4d360b28..595b2b3724 100644 --- a/Core/HDRemaster.h +++ b/Core/HDRemaster.h @@ -24,6 +24,7 @@ // We keep it set to false by default in PSPLoaders.cpp // in order to keep the 99% of other PSP games working happily. extern bool g_RemasterMode; + extern bool g_DoubleTextureCoordinates; struct HDRemaster { @@ -32,26 +33,13 @@ struct HDRemaster { bool DoubleTextureCoordinates; }; -// TODO: Are those BLJM* IDs really valid? They seem to be the physical PS3 disk IDs, -// but they're included for safety. -// TODO: Do all of the remasters aside from Monster Hunter use double texture coordinates? -// TODO: Are all remasters happy with this end address? +// TODO: Use UMD_DATA.bin to differentiate the Eiyuu games from the regular PSP editions. +// TODO: Do all of the remasters aside from Monster Hunter/Shin Sangoku use double texture coordinates? const struct HDRemaster g_HDRemasters[] = { { "NPJB40001", 0x4000000, false }, // MONSTER HUNTER PORTABLE 3rd HD Ver. -{ "BLJM85002", 0x4000000, true }, // K-ON Houkago Live HD Ver { "NPJB40002", 0x4000000, true }, // K-ON Houkago Live HD Ver -{ "BLJM85003", 0x4000000, true }, // Shin Sangoku Musou Multi Raid 2 HD Ver -{ "NPJB40003", 0x4000000, true }, // Shin Sangoku Musou Multi Raid 2 HD Ver -{ "BLJM85004", 0x4000000, true }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition, this one is never used -// deactivated because it also affects the UMD version of the game -// TODO: Differentiate between UMD version and HD version (either through reading of UMD_DATA.BIN or ISO size) +{ "NPJB40003", 0x4000000, false }, // Shin Sangoku Musou Multi Raid 2 HD Ver // { "ULJM05170", 0x4000000, true }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition -{ "BLJM85005", 0x4C00000, true }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition, this one is never used -// deactivated because it also affects the UMD version of the game -// TODO: Differentiate between UMD version and HD version (either through reading of UMD_DATA.BIN or ISO size) // { "ULJM05277", 0x4C00000, true }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition, game needs 76 MB -{ "BLJM85006", 0x4C00000, true }, // Eiyuu Densetsu: Sora no Kiseki 3rd Kai HD Edition, this one is never used -// deactivated because it also affects the UMD version of the game -// TODO: Differentiate between UMD version and HD version (either through reading of UMD_DATA.BIN or ISO size) // { "ULJM05353", 0x4C00000, true }, // Eiyuu Densetsu: Sora no Kiseki 3rd Kai HD Edition, game needs 76 MB }; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 76ea3a3a35..3f34c8e61a 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -915,8 +915,6 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str u32 argpAddr = param.argp; param_argp = new u8[param.args]; Memory::Memcpy(param_argp, argpAddr, param.args); - } else { - param.argp = NULL; } if (param.keyp != 0) { u32 keyAddr = param.keyp; @@ -993,7 +991,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str option.stacksize = module->nm.module_start_thread_stacksize; if (paramPtr) - __KernelStartModule(module, param.args, (const char*)param.argp, &option); + __KernelStartModule(module, param.args, (const char*)param_argp, &option); else __KernelStartModule(module, (u32)strlen(filename) + 1, filename, &option); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index fe60942e50..00b27d77b7 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -21,6 +21,7 @@ #include "sceKernel.h" #include "sceKernelThread.h" +#include "sceKernelMutex.h" #include "sceUtility.h" #include "net/resolve.h" @@ -28,6 +29,8 @@ static bool netInited; static bool netInetInited; static bool netAdhocInited; +static bool netAdhocctlInited; +static bool netAdhocMatchingInited; static bool netApctlInited; // TODO: Determine how many handlers we can actually have @@ -37,6 +40,8 @@ const size_t MAX_APCTL_HANDLERS = 32; enum { ERROR_NET_BUFFER_TOO_SMALL = 0x80400706, + ERROR_NET_INET_ALREADY_INITIALIZED = 0x80410201, + ERROR_NET_RESOLVER_BAD_ID = 0x80410408, ERROR_NET_RESOLVER_ALREADY_STOPPED = 0x8041040a, ERROR_NET_RESOLVER_INVALID_HOST = 0x80410414, @@ -55,6 +60,8 @@ enum { ERROR_NET_ADHOC_MATCHING_ALREADY_INITIALIZED = 0x80410812, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED = 0x80410813, + ERROR_NET_APCTL_ALREADY_INITIALIZED = 0x80410a01, + ERROR_NET_ADHOCCTL_WLAN_SWITCH_OFF = 0x80410b03, ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED = 0x80410b07, ERROR_NET_ADHOCCTL_NOT_INITIALIZED = 0x80410b08, @@ -142,6 +149,8 @@ void __NetDoState(PointerWrap &p) { p.Do(netInetInited); p.Do(netAdhocInited); p.Do(netApctlInited); + p.Do(netAdhocctlInited); + p.Do(netAdhocMatchingInited); p.Do(adhocctlHandlers); p.Do(apctlHandlers); p.Do(netMallocStat); @@ -162,6 +171,7 @@ void sceNetInit() { u32 sceNetTerm() { ERROR_LOG(HLE,"UNIMPL sceNetTerm()"); netInited = false; + return 0; } @@ -176,6 +186,10 @@ u32 sceNetAdhocInit() { u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { ERROR_LOG(HLE,"UNIMPL sceNetAdhocctlInit(%i, %i, %08x)", stackSize, prio, productAddr); + if(netAdhocctlInited) + return ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED; + netAdhocctlInited = true; + return 0; } @@ -257,16 +271,25 @@ u32 sceNetAdhocctlDelHandler(u32 handlerID) { int sceNetAdhocMatchingTerm() { ERROR_LOG(HLE, "UNIMPL sceNetAdhocMatchingTerm()"); + netAdhocMatchingInited = false; + return 0; } int sceNetAdhocctlTerm() { ERROR_LOG(HLE, "UNIMPL sceNetAdhocctlTerm()"); + netAdhocctlInited = false; + return 0; } int sceNetAdhocTerm() { ERROR_LOG(HLE, "UNIMPL sceNetAdhocTerm()"); + // Seems to return this when called a second time after being terminated without another initialisation + if(!netAdhocInited) + return SCE_KERNEL_ERROR_LWMUTEX_NOT_FOUND; + netAdhocInited = false; + return 0; } @@ -372,13 +395,17 @@ int sceNetGetMallocStat(u32 statPtr) { int sceNetAdhocMatchingInit(u32 memsize) { ERROR_LOG(HLE, "UNIMPL sceNetAdhocMatchingInit(%08x)", memsize); + if(netAdhocMatchingInited) + return ERROR_NET_ADHOC_MATCHING_ALREADY_INITIALIZED; + netAdhocMatchingInited = true; + 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? + return ERROR_NET_INET_ALREADY_INITIALIZED; netInetInited = true; return 0; @@ -394,7 +421,7 @@ int sceNetInetTerm() { 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? + return ERROR_NET_APCTL_ALREADY_INITIALIZED; netApctlInited = true; return 0; @@ -402,8 +429,8 @@ int sceNetApctlInit() { int sceNetApctlTerm() { ERROR_LOG(HLE, "UNIMPL sceNeApctlTerm()"); - netInetInited = false; - + netApctlInited = false; + return 0; } diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 6cb25ff24a..ed5a4a945b 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -133,6 +133,16 @@ void CenterRect(float *x, float *y, float *w, float *h, } } +void FramebufferManager::CompileDraw2DProgram() { + if (!draw2dprogram) { + draw2dprogram = glsl_create_source(basic_vs, tex_fs); + + glsl_bind(draw2dprogram); + glUniform1i(draw2dprogram->sampler0, 0); + glsl_unbind(); + } +} + FramebufferManager::FramebufferManager() : ramDisplayFramebufPtr_(0), displayFramebufPtr_(0), @@ -145,18 +155,15 @@ FramebufferManager::FramebufferManager() : currentRenderVfb_(0), drawPixelsTex_(0), drawPixelsTexFormat_(-1), - convBuf(0) + convBuf(0), + draw2dprogram(0) #ifndef USING_GLES2 , pixelBufObj_(0), currentPBO_(0) #endif { - draw2dprogram = glsl_create_source(basic_vs, tex_fs); - - glsl_bind(draw2dprogram); - glUniform1i(draw2dprogram->sampler0, 0); - glsl_unbind(); + CompileDraw2DProgram(); // And an initial clear. We don't clear per frame as the games are supposed to handle that // by themselves. @@ -197,7 +204,9 @@ FramebufferManager::FramebufferManager() : FramebufferManager::~FramebufferManager() { if (drawPixelsTex_) glDeleteTextures(1, &drawPixelsTex_); - glsl_destroy(draw2dprogram); + if (draw2dprogram) { + glsl_destroy(draw2dprogram); + } #ifndef USING_GLES2 delete [] pixelBufObj_; @@ -316,8 +325,9 @@ void FramebufferManager::DrawActiveTexture(float x, float y, float w, float h, b const float pos[12] = {x,y,0, x+w,y,0, x+w,y+h,0, x,y+h,0}; const float texCoords[8] = {0,v1, u2,v1, u2,v2, 0,v2}; const GLubyte indices[4] = {0,1,3,2}; - + if(!program) { + CompileDraw2DProgram(); program = draw2dprogram; } @@ -824,6 +834,8 @@ void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *src, VirtualFrameb float x, y, w, h; CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight); + CompileDraw2DProgram(); + DrawActiveTexture(x, y, w, h, flip, upscale, vscale, draw2dprogram); glBindTexture(GL_TEXTURE_2D, 0); @@ -1081,6 +1093,8 @@ void FramebufferManager::EndFrame() { void FramebufferManager::DeviceLost() { DestroyAllFBOs(); + glsl_destroy(draw2dprogram); + draw2dprogram = 0; resized_ = false; } diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index e40dce4373..87203c761a 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -152,6 +152,8 @@ public: void DestroyFramebuf(VirtualFramebuffer *vfb); private: + void CompileDraw2DProgram(); + u32 ramDisplayFramebufPtr_; // workaround for MotoGP insanity u32 displayFramebufPtr_; u32 displayStride_; diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 32540a2d98..4c5c625947 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -460,6 +460,8 @@ void ShaderManager::Clear() { fsCache.clear(); vsCache.clear(); globalDirty = 0xFFFFFFFF; + lastFSID.clear(); + lastVSID.clear(); DirtyShader(); } @@ -473,6 +475,8 @@ void ShaderManager::DirtyShader() { lastFSID.clear(); lastVSID.clear(); lastShader = 0; + globalDirty = 0xFFFFFFFF; + shaderSwitchDirty = 0; } void ShaderManager::EndFrame() { // disables vertex arrays diff --git a/Qt/Core.pro b/Qt/Core.pro index c8c8d9cb63..58c0e25830 100755 --- a/Qt/Core.pro +++ b/Qt/Core.pro @@ -32,21 +32,7 @@ win32 { HEADERS += ../Windows/OpenGLBase.h } -SOURCES += ../Core/CPU.cpp \ # Core - ../Core/Config.cpp \ - ../Core/Core.cpp \ - ../Core/CoreTiming.cpp \ - ../Core/CwCheat.cpp \ - ../Core/HDRemaster.cpp \ - ../Core/Host.cpp \ - ../Core/Loaders.cpp \ - ../Core/MemMap.cpp \ - ../Core/MemMapFunctions.cpp \ - ../Core/PSPLoaders.cpp \ - ../Core/PSPMixer.cpp \ - ../Core/Reporting.cpp \ - ../Core/SaveState.cpp \ - ../Core/System.cpp \ +SOURCES += ../Core/*.cpp \ # Core ../Core/Debugger/*.cpp \ ../Core/Dialog/*.cpp \ ../Core/ELF/*.cpp \ @@ -66,21 +52,7 @@ SOURCES += ../Core/CPU.cpp \ # Core ../ext/libkirk/*.c \ # Kirk ../ext/xbrz/*.cpp # XBRZ -HEADERS += ../Core/CPU.h \ - ../Core/Config.h \ - ../Core/Core.h \ - ../Core/CoreParameter.h \ - ../Core/CoreTiming.h \ - ../Core/CwCheat.h \ - ../Core/HDRemaster.h \ - ../Core/Host.h \ - ../Core/Loaders.h \ - ../Core/MemMap.h \ - ../Core/PSPLoaders.h \ - ../Core/PSPMixer.h \ - ../Core/Reporting.h \ - ../Core/SaveState.h \ - ../Core/System.h \ +HEADERS += ../Core/*.h \ ../Core/Debugger/*.h \ ../Core/Dialog/*.h \ ../Core/ELF/*.h \ diff --git a/Qt/Native.pro b/Qt/Native.pro index 77952d7343..bc2670160b 100755 --- a/Qt/Native.pro +++ b/Qt/Native.pro @@ -87,8 +87,7 @@ SOURCES += ../native/audio/*.cpp \ ../native/gfx_es2/*.cpp \ ../native/i18n/*.cpp \ ../native/image/*.cpp \ - ../native/input/gesture_detector.cpp \ - ../native/input/input_state.cpp \ + ../native/input/*.cpp \ ../native/json/json_writer.cpp \ ../native/math/curves.cpp \ ../native/math/expression_parser.cpp \ @@ -121,27 +120,19 @@ HEADERS += ../native/audio/*.h \ ../native/base/timeutil.h \ ../native/data/compression.h \ ../native/file/*.h \ - ../native/gfx/gl_debug_log.h \ - ../native/gfx/gl_lost_manager.h \ - ../native/gfx/texture.h \ - ../native/gfx/texture_atlas.h \ - ../native/gfx/texture_gen.h \ + ../native/gfx/*.h \ ../native/gfx_es2/*.h \ ../native/i18n/*.h \ ../native/image/*.h \ - ../native/input/gesture_detector.h \ - ../native/input/input_state.h \ + ../native/input/*.h \ ../native/json/json_writer.h \ - ../native/math/curves.h \ - ../native/math/expression_parser.h \ + ../native/math/*.h \ ../native/math/lin/*.h \ ../native/midi/midi_input.h \ ../native/net/*.h \ ../native/profiler/profiler.h \ ../native/thread/*.h \ - ../native/ui/ui.h \ - ../native/ui/screen.h \ - ../native/ui/virtual_input.h \ + ../native/ui/*.h \ ../native/util/bits/*.h \ ../native/util/hash/hash.h \ ../native/util/random/*.h \ diff --git a/Qt/PPSSPP.pro b/Qt/PPSSPP.pro index a5afc32f45..580fe90a56 100755 --- a/Qt/PPSSPP.pro +++ b/Qt/PPSSPP.pro @@ -43,20 +43,17 @@ linux { SOURCES += ../native/base/QtMain.cpp HEADERS += ../native/base/QtMain.h -# Native -SOURCES += ../UI/EmuScreen.cpp \ - ../UI/MainScreen.cpp \ - ../UI/MenuScreens.cpp \ - ../UI/GameScreen.cpp \ - ../UI/GameSettingsScreen.cpp \ +# UI +SOURCES += ../UI/*Screen.cpp \ + ../UI/*Screens.cpp \ ../UI/GamepadEmu.cpp \ ../UI/GameInfoCache.cpp \ ../UI/OnScreenDisplay.cpp \ - ../UI/PluginScreen.cpp \ - ../android/jni/TestRunner.cpp \ ../UI/UIShader.cpp \ - ../UI/ui_atlas.cpp + ../UI/ui_atlas.cpp \ + ../android/jni/TestRunner.cpp +HEADERS += ../UI/*.h INCLUDEPATH += .. ../Common ../native # Temporarily only use new UI for Linux desktop @@ -70,6 +67,7 @@ linux:!mobile_platform { RESOURCES += resources.qrc INCLUDEPATH += ../Qt } else { + # Desktop handles the Init separately SOURCES += ../UI/NativeApp.cpp } RESOURCES += assets.qrc diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b22a831b3d..5b77669fdf 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -369,6 +369,12 @@ static const struct { int from, to; } legacy_touch_mapping[12] = { }; void EmuScreen::update(InputState &input) { + // Simply forcibily update to the current screen size every frame. Doesn't cost much. + PSP_CoreParameter().outputWidth = dp_xres; + PSP_CoreParameter().outputHeight = dp_yres; + PSP_CoreParameter().pixelWidth = pixel_xres; + PSP_CoreParameter().pixelHeight = pixel_yres; + globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new PromptScreen( diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 58a0c1809e..00928333b7 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -17,6 +17,7 @@ #include "base/colorutil.h" #include "base/timeutil.h" +#include "i18n/i18n.h" #include "math/curves.h" #include "ui/ui_context.h" #include "ui/view.h" @@ -32,6 +33,9 @@ void GameScreen::CreateViews() { GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true); + I18NCategory *g = GetI18NCategory("General"); + I18NCategory *ga = GetI18NCategory("Game"); + // Information in the top left. // Back button to the bottom left. // Scrolling action menu to the right. @@ -44,7 +48,7 @@ void GameScreen::CreateViews() { ViewGroup *leftColumn = new AnchorLayout(new LinearLayoutParams(1.0f)); root_->Add(leftColumn); - leftColumn->Add(new Choice("Back", "", new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack); + leftColumn->Add(new Choice(g->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack); if (info) { texvGameIcon_ = leftColumn->Add(new TextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE))); tvTitle_ = leftColumn->Add(new TextView(0, info->title, ALIGN_LEFT, 1.0f, new AnchorLayoutParams(10, 200, NONE, NONE))); @@ -57,10 +61,10 @@ void GameScreen::CreateViews() { ViewGroup *rightColumnItems = new LinearLayout(ORIENT_VERTICAL); rightColumn->Add(rightColumnItems); - rightColumnItems->Add(new Choice("Play"))->OnClick.Handle(this, &GameScreen::OnPlay); - rightColumnItems->Add(new Choice("Game Settings"))->OnClick.Handle(this, &GameScreen::OnGameSettings); - rightColumnItems->Add(new Choice("Delete Save Data"))->OnClick.Handle(this, &GameScreen::OnDeleteSaveData); - rightColumnItems->Add(new Choice("Delete Game"))->OnClick.Handle(this, &GameScreen::OnDeleteGame); + rightColumnItems->Add(new Choice(ga->T("Play")))->OnClick.Handle(this, &GameScreen::OnPlay); + rightColumnItems->Add(new Choice(ga->T("Game Settings")))->OnClick.Handle(this, &GameScreen::OnGameSettings); + rightColumnItems->Add(new Choice(ga->T("Delete Save Data")))->OnClick.Handle(this, &GameScreen::OnDeleteSaveData); + rightColumnItems->Add(new Choice(ga->T("Delete Game")))->OnClick.Handle(this, &GameScreen::OnDeleteGame); } void DrawBackground(float alpha); diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index a8037c8450..c898950efe 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -90,8 +90,7 @@ void LayoutGamepad(int w, int h) leftStick.setPos(stickX, stickY, controlScale); } -void UpdateGamepad(InputState &input_state) -{ +void UpdateGamepad(InputState &input_state) { LayoutGamepad(dp_xres, dp_yres); buttonO.update(input_state); @@ -119,8 +118,7 @@ void UpdateGamepad(InputState &input_state) leftStick.update(input_state); } -void DrawGamepad(DrawBuffer &db, float opacity) -{ +void DrawGamepad(DrawBuffer &db, float opacity) { uint32_t color = colorAlpha(0xc0b080, opacity); uint32_t colorOverlay = colorAlpha(0xFFFFFF, opacity); diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index b4efbb594d..197bf4b210 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -60,6 +60,7 @@ #include "UI/EmuScreen.h" #include "UI/PluginScreen.h" #include "UI/MainScreen.h" +#include "UI/MiscScreens.h" #include "GameInfoCache.h" #include "android/jni/TestRunner.h" @@ -1469,7 +1470,10 @@ void SystemScreen::render() { ui_draw2d.DrawTextShadow(UBUNTU24, lang, x, y += stride, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear2(x + 400, y, 20); if (UIButton(GEN_ID, hlinear2, 220, 0, s->T("Language"), ALIGN_TOPLEFT)) { - screenManager()->push(new LanguageScreen()); + if (g_Config.bNewUI) + screenManager()->push(new NewLanguageScreen()); + else + screenManager()->push(new LanguageScreen()); } y+=20; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 73696606a0..62c52d55e8 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -18,10 +18,14 @@ #include "base/colorutil.h" #include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" +#include "file/vfs.h" +#include "i18n/i18n.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "UI/MiscScreens.h" +#include "Core/Config.h" +#include "Core/HLE/sceUtility.h" void DrawBackground(float alpha); @@ -62,3 +66,93 @@ UI::EventReturn PromptScreen::OnNo(UI::EventParams &e) { screenManager()->finishDialog(this, DR_CANCEL); return UI::EVENT_DONE; } + +NewLanguageScreen::NewLanguageScreen() : ListPopupScreen("Language") { + langValuesMapping["ja_JP"] = std::make_pair("日本語", PSP_SYSTEMPARAM_LANGUAGE_JAPANESE); + langValuesMapping["en_US"] = std::make_pair("English",PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["fr_FR"] = std::make_pair("Français", PSP_SYSTEMPARAM_LANGUAGE_FRENCH); + langValuesMapping["es_ES"] = std::make_pair("Castellano", PSP_SYSTEMPARAM_LANGUAGE_SPANISH); + langValuesMapping["es_LA"] = std::make_pair("Latino", PSP_SYSTEMPARAM_LANGUAGE_SPANISH); + langValuesMapping["de_DE"] = std::make_pair("Deutsch", PSP_SYSTEMPARAM_LANGUAGE_GERMAN); + langValuesMapping["it_IT"] = std::make_pair("Italiano", PSP_SYSTEMPARAM_LANGUAGE_ITALIAN); + langValuesMapping["nl_NL"] = std::make_pair("Nederlands", PSP_SYSTEMPARAM_LANGUAGE_DUTCH); + langValuesMapping["pt_PT"] = std::make_pair("Português", PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE); + langValuesMapping["pt_BR"] = std::make_pair("Brasileiro", PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE); + langValuesMapping["ru_RU"] = std::make_pair("Русский", PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN); + langValuesMapping["ko_KR"] = std::make_pair("한국어", PSP_SYSTEMPARAM_LANGUAGE_KOREAN); + langValuesMapping["zh_TW"] = std::make_pair("繁體中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL); + 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); + langValuesMapping["hu_HU"] = std::make_pair("Magyar", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["id_ID"] = std::make_pair("Indonesia", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["pl_PL"] = std::make_pair("Polski", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["ro_RO"] = std::make_pair("Român", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["sv_SE"] = std::make_pair("Svenska", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["tr_TR"] = std::make_pair("Türk", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + langValuesMapping["uk_UA"] = std::make_pair("Українська", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); + +#ifdef ANDROID + VFSGetFileListing("assets/lang", &langs_, "ini"); +#else + VFSGetFileListing("lang", &langs_, "ini"); +#endif + std::vector listing; + 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) + code = langs_[i].name.substr(0, dot); + + std::string buttonTitle = langs_[i].name; + + if (!code.empty()) { + if (langValuesMapping.find(code) == langValuesMapping.end()) { + // No title found, show locale code + buttonTitle = code; + } else { + buttonTitle = langValuesMapping[code].first; + } + } + listing.push_back(buttonTitle); + } + + adaptor_ = UI::StringVectorListAdaptor(listing, 0); +} + +void NewLanguageScreen::OnCompleted() { + std::string oldLang = g_Config.languageIni; + + std::string iniFile = langs_[listView_->GetSelected()].name; + + size_t dot = iniFile.find('.'); + std::string code; + if (dot != std::string::npos) + code = iniFile.substr(0, dot); + + if (code.empty()) + return; + + g_Config.languageIni = code; + + if (i18nrepo.LoadIni(g_Config.languageIni)) { + // Dunno what else to do here. + if (langValuesMapping.find(code) == langValuesMapping.end()) { + // Fallback to English + g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + } else { + g_Config.ilanguage = langValuesMapping[code].second; + } + } else { + g_Config.languageIni = oldLang; + } +} \ No newline at end of file diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index 705534d90a..a1c6fe25ed 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -17,7 +17,12 @@ #pragma once +#include +#include +#include + #include "base/functional.h" +#include "file/file_util.h" #include "ui/ui_screen.h" inline void NoOpVoidBool(bool) {} @@ -44,3 +49,19 @@ private: std::string noButtonText_; std::function callback_; }; + +class NewLanguageScreen : public ListPopupScreen { +public: + NewLanguageScreen(); + +private: + virtual void OnCompleted(); + + std::map> langValuesMapping; + std::map titleCodeMapping; + std::vector langs_; +}; + + +// Utility functions that create various popup screens +ListPopupScreen *CreateLanguageScreen(); \ No newline at end of file diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index d6d1db815e..ff915e36e9 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -367,11 +367,7 @@ void NativeInit(int argc, const char *argv[], SaveState::Load(stateToLoad); g_gameInfoCache.Init(); -} -void NativeInitGraphics() { - gl_lost_manager_init(); - ui_draw2d.SetAtlas(&ui_atlas); screenManager = new ScreenManager(); @@ -388,6 +384,12 @@ void NativeInitGraphics() { // Go directly into the game. screenManager->switchScreen(new EmuScreen(boot_filename)); } +} + +void NativeInitGraphics() { + gl_lost_manager_init(); + ui_draw2d.SetAtlas(&ui_atlas); + UIShader_Init(); @@ -450,6 +452,25 @@ void NativeInitGraphics() { glstate.viewport.set(0, 0, pixel_xres, pixel_yres); } +void NativeShutdownGraphics() { + screenManager->deviceLost(); + + g_gameInfoCache.Clear(); + + delete uiTexture; + uiTexture = NULL; + + delete uiContext; + uiContext = NULL; + + ui_draw2d.Shutdown(); + ui_draw2d_front.Shutdown(); + + UIShader_Shutdown(); + + gl_lost_manager_shutdown(); +} + void TakeScreenshot() { #ifdef _WIN32 g_TakeScreenshot = false; @@ -573,25 +594,12 @@ void NativeMessageReceived(const char *message, const char *value) { } } -void NativeShutdownGraphics() { - g_gameInfoCache.Clear(); - - delete uiTexture; - uiTexture = NULL; +void NativeShutdown() { screenManager->shutdown(); delete screenManager; screenManager = 0; - ui_draw2d.Shutdown(); - ui_draw2d_front.Shutdown(); - - UIShader_Shutdown(); - - gl_lost_manager_shutdown(); -} - -void NativeShutdown() { g_gameInfoCache.Shutdown(); delete host; @@ -604,6 +612,7 @@ void NativeShutdown() { // boot up correctly with "dirty" global variables currently, so we hack around that // by simply exiting. #ifdef ANDROID + ELOG("NativeShutdown called"); exit(0); #endif } diff --git a/Windows/Log.bat b/Windows/Log.bat index ff714ca190..5f43e36576 100644 --- a/Windows/Log.bat +++ b/Windows/Log.bat @@ -1,5 +1,6 @@ @echo off IF Not exist .\User md .\User IF Not exist .\User\Logs md .\User\Logs -If exist .\User\Logs\ppsspp.log Del .\User\Logs\ppsspp.log -PPSSPPWindows.exe \ No newline at end of file +IF exist .\User\Logs\ppsspp.log Del .\User\Logs\ppsspp.log +IF exist .\PPSSPPWindows.exe PPSSPPWindows.exe +IF exist .\PPSSPPWindows64.exe PPSSPPWindows64.exe \ No newline at end of file diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index e7c0e67285..5bbd391093 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -29,8 +29,7 @@ android:name=".PpssppActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" - android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" - android:screenOrientation="landscape" > + android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode">