From aad5082d555039747cef9956c08344e2733c2392 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 11 Jul 2022 20:44:13 -0700 Subject: [PATCH 01/57] Config: Move recent ISOs access to accessors. --- Core/Config.cpp | 2 +- Core/Config.h | 12 +++++++++++- Core/Util/GameManager.cpp | 2 +- Core/WebServer.cpp | 4 ++-- UI/GameScreen.cpp | 4 ++-- UI/MainScreen.cpp | 10 +++++----- UI/MiscScreens.cpp | 11 +++++++---- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index fe03875ba8..bbb534fbc6 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1701,7 +1701,7 @@ void Config::RestoreDefaults() { } else { if (File::Exists(iniFilename_)) File::Delete(iniFilename_); - recentIsos.clear(); + ClearRecentIsos(); currentDirectory = defaultCurrentDirectory; } Load(); diff --git a/Core/Config.h b/Core/Config.h index 88aefb94e6..599c7de818 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -140,7 +140,6 @@ public: int iInternalScreenRotation; // The internal screen rotation angle. Useful for vertical SHMUPs and similar. std::string sReportHost; - std::vector recentIsos; std::vector vPinnedPaths; std::string sLanguageIni; @@ -536,6 +535,16 @@ public: return bFullScreen; } + std::vector RecentIsos() const { + return recentIsos; + } + bool HasRecentIsos() const { + return !recentIsos.empty(); + } + void ClearRecentIsos() { + recentIsos.clear(); + } + protected: void LoadStandardControllerIni(); @@ -543,6 +552,7 @@ private: bool reload_ = false; std::string gameId_; std::string gameIdTitle_; + std::vector recentIsos; Path iniFilename_; Path controllerIniFilename_; Path searchPath_; diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index bda6741c57..b6f4ccbd65 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -375,7 +375,7 @@ bool GameManager::DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest) std::string gameID = games.begin()->first; if (games.size() > 1) { // Check for any supported game on their recent list and use that instead. - for (const std::string &path : g_Config.recentIsos) { + for (const std::string &path : g_Config.RecentIsos()) { std::string recentID = GetGameID(Path(path)); if (games.find(recentID) != games.end()) { gameID = recentID; diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index a55b298ed2..ff21b02a2a 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -150,7 +150,7 @@ static std::string RemotePathForRecent(const std::string &filename) { } static Path LocalFromRemotePath(const std::string &path) { - for (const std::string &filename : g_Config.recentIsos) { + for (const std::string &filename : g_Config.RecentIsos()) { std::string basename = RemotePathForRecent(filename); if (basename == path) { return Path(filename); @@ -216,7 +216,7 @@ static void HandleListing(const http::Request &request) { request.Out()->Printf("/\n"); if (serverFlags & (int)WebServerFlags::DISCS) { // List the current discs in their recent order. - for (const std::string &filename : g_Config.recentIsos) { + for (const std::string &filename : g_Config.RecentIsos()) { std::string basename = RemotePathForRecent(filename); if (!basename.empty()) { request.Out()->Printf("%s\n", basename.c_str()); diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index a11572941a..15d4073f98 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -426,8 +426,8 @@ bool GameScreen::isRecentGame(const Path &gamePath) { return false; const std::string resolved = File::ResolvePath(gamePath.ToString()); - for (auto it = g_Config.recentIsos.begin(); it != g_Config.recentIsos.end(); ++it) { - const std::string recent = File::ResolvePath(*it); + for (auto iso : g_Config.RecentIsos()) { + const std::string recent = File::ResolvePath(iso); if (resolved == recent) return true; } diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index b1d337908a..8b5fbb08f4 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -587,7 +587,7 @@ bool GameBrowser::DisplayTopBar() { bool GameBrowser::HasSpecialFiles(std::vector &filenames) { if (path_.GetPath().ToString() == "!RECENT") { filenames.clear(); - for (auto &str : g_Config.recentIsos) { + for (auto &str : g_Config.RecentIsos()) { filenames.push_back(Path(str)); } return true; @@ -986,7 +986,7 @@ void MainScreen::CreateViews() { System_GetPermissionStatus(SYSTEM_PERMISSION_STORAGE) == PERMISSION_STATUS_GRANTED; bool storageIsTemporary = IsTempPath(GetSysDirectory(DIRECTORY_SAVEDATA)) && !confirmedTemporary_; if (showRecent && !hasStorageAccess) { - showRecent = !g_Config.recentIsos.empty(); + showRecent = g_Config.HasRecentIsos(); } if (showRecent) { @@ -1036,7 +1036,7 @@ void MainScreen::CreateViews() { tabAllGames->OnHighlight.Handle(this, &MainScreen::OnGameHighlight); tabHomebrew->OnHighlight.Handle(this, &MainScreen::OnGameHighlight); - if (g_Config.recentIsos.size() > 0) { + if (g_Config.HasRecentIsos()) { tabHolder_->SetCurrentTab(0, true); } else if (g_Config.iMaxRecent > 0) { tabHolder_->SetCurrentTab(1, true); @@ -1490,7 +1490,7 @@ void UmdReplaceScreen::CreateViews() { rightColumnItems->Add(new Choice(di->T("Cancel")))->OnClick.Handle(this, &UmdReplaceScreen::OnCancel); rightColumnItems->Add(new Choice(mm->T("Game Settings")))->OnClick.Handle(this, &UmdReplaceScreen::OnGameSettings); - if (g_Config.recentIsos.size() > 0) { + if (g_Config.HasRecentIsos()) { leftColumn->SetCurrentTab(0, true); } else if (g_Config.iMaxRecent > 0) { leftColumn->SetCurrentTab(1, true); @@ -1569,7 +1569,7 @@ UI::EventReturn GridSettingsScreen::GridMinusClick(UI::EventParams &e) { } UI::EventReturn GridSettingsScreen::OnRecentClearClick(UI::EventParams &e) { - g_Config.recentIsos.clear(); + g_Config.ClearRecentIsos(); OnRecentChanged.Trigger(e); return UI::EVENT_DONE; } diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index ccd5b86919..f7e22a8f78 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -203,7 +203,7 @@ public: lastIndex_ = nextIndex_; } - if (!g_Config.recentIsos.empty()) { + if (g_Config.HasRecentIsos()) { std::shared_ptr lastInfo = GetInfo(dc, lastIndex_); std::shared_ptr nextInfo = GetInfo(dc, nextIndex_); dc.Flush(); @@ -220,12 +220,12 @@ public: private: void CheckNext(UIContext &dc, double t) { - if (g_Config.recentIsos.empty()) { + if (!g_Config.HasRecentIsos()) { return; } for (int index = lastIndex_ + 1; index != lastIndex_; ++index) { - if (index < 0 || index >= (int)g_Config.recentIsos.size()) { + if (index < 0 || index >= (int)g_Config.RecentIsos().size()) { if (lastIndex_ == -1) break; index = 0; @@ -250,7 +250,10 @@ private: if (index < 0) { return nullptr; } - return g_gameInfoCache->GetInfo(dc.GetDrawContext(), Path(g_Config.recentIsos[index]), GAMEINFO_WANTBG); + const auto recentIsos = g_Config.RecentIsos(); + if (index >= recentIsos.size()) + return nullptr; + return g_gameInfoCache->GetInfo(dc.GetDrawContext(), Path(recentIsos[index]), GAMEINFO_WANTBG); } void DrawTex(UIContext &dc, std::shared_ptr &ginfo, float amount) { From c04de9dd7976c855960affcdbd1b96726c94c1bf Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 11 Jul 2022 22:01:06 -0700 Subject: [PATCH 02/57] Config: Cleanup recent on a thread. --- Core/Config.cpp | 92 ++++++++++++++++++++++++++++++++++++------------- Core/Config.h | 12 ++----- 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index bbb534fbc6..ebb0521f6e 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -19,8 +19,10 @@ #include #include #include +#include #include #include +#include #include "ppsspp_config.h" @@ -56,6 +58,9 @@ http::Downloader g_DownloadManager; Config g_Config; bool jitForcedOff; +static std::mutex recentIsosLock; +static std::mutex recentIsosThreadLock; +static std::thread recentIsosThread; #ifdef _DEBUG static const char *logSectionName = "LogDebug"; @@ -1206,6 +1211,19 @@ static void IterateSettings(IniFile &iniFile, std::function guard(recentIsosThreadLock); + if (recentIsosThread.joinable()) + recentIsosThread.join(); +} + +static void SetRecentIsosThread(std::function f) { + std::lock_guard guard(recentIsosThreadLock); + if (recentIsosThread.joinable()) + recentIsosThread.join(); + recentIsosThread = std::thread(f); +} + Config::Config() { } @@ -1213,6 +1231,7 @@ Config::~Config() { if (bUpdatedInstanceCounter) { ShutdownInstanceCounter(); } + ResetRecentIsosThread(); } std::map> GetLangValuesMapping() { @@ -1315,6 +1334,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { iMaxRecent = 60; if (iMaxRecent > 0) { + ResetRecentIsosThread(); + std::lock_guard guard(recentIsosLock); recentIsos.clear(); for (int i = 0; i < iMaxRecent; i++) { char keyName[64]; @@ -1470,9 +1491,11 @@ bool Config::Save(const char *saveReason) { Section *recent = iniFile.GetOrCreateSection("Recent"); recent->Set("MaxRecent", iMaxRecent); + ResetRecentIsosThread(); for (int i = 0; i < iMaxRecent; i++) { char keyName[64]; snprintf(keyName, sizeof(keyName), "FileName%d", i); + std::lock_guard guard(recentIsosLock); if (i < (int)recentIsos.size()) { recent->Set(keyName, recentIsos[i]); } else { @@ -1610,6 +1633,8 @@ void Config::AddRecent(const std::string &file) { // We'll add it back below. This makes sure it's at the front, and only once. RemoveRecent(file); + ResetRecentIsosThread(); + std::lock_guard guard(recentIsosLock); const std::string filename = File::ResolvePath(file); recentIsos.insert(recentIsos.begin(), filename); if ((int)recentIsos.size() > iMaxRecent) @@ -1621,6 +1646,8 @@ void Config::RemoveRecent(const std::string &file) { if (iMaxRecent <= 0) return; + ResetRecentIsosThread(); + std::lock_guard guard(recentIsosLock); const std::string filename = File::ResolvePath(file); for (auto iter = recentIsos.begin(); iter != recentIsos.end();) { const std::string recent = File::ResolvePath(*iter); @@ -1634,35 +1661,52 @@ void Config::RemoveRecent(const std::string &file) { } void Config::CleanRecent() { - double startTime = time_now_d(); + SetRecentIsosThread([this] { + double startTime = time_now_d(); - std::vector cleanedRecent; - for (size_t i = 0; i < recentIsos.size(); i++) { - bool exists = false; - Path path = Path(recentIsos[i]); - switch (path.Type()) { - case PathType::CONTENT_URI: - case PathType::NATIVE: - exists = File::Exists(path); - break; - default: - FileLoader *loader = ConstructFileLoader(path); - exists = loader->ExistsFast(); - delete loader; - break; - } + std::lock_guard guard(recentIsosLock); + std::vector cleanedRecent; + for (size_t i = 0; i < recentIsos.size(); i++) { + bool exists = false; + Path path = Path(recentIsos[i]); + switch (path.Type()) { + case PathType::CONTENT_URI: + case PathType::NATIVE: + exists = File::Exists(path); + break; + default: + FileLoader *loader = ConstructFileLoader(path); + exists = loader->ExistsFast(); + delete loader; + break; + } - if (exists) { - // Make sure we don't have any redundant items. - auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), recentIsos[i]); - if (duplicate == cleanedRecent.end()) { - cleanedRecent.push_back(recentIsos[i]); + if (exists) { + // Make sure we don't have any redundant items. + auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), recentIsos[i]); + if (duplicate == cleanedRecent.end()) { + cleanedRecent.push_back(recentIsos[i]); + } } } - } - INFO_LOG(SYSTEM, "CleanRecent took %0.2f", time_now_d() - startTime); - recentIsos = cleanedRecent; + INFO_LOG(SYSTEM, "CleanRecent took %0.2f", time_now_d() - startTime); + recentIsos = cleanedRecent; + }); +} + +std::vector Config::RecentIsos() const { + std::lock_guard guard(recentIsosLock); + return recentIsos; +} +bool Config::HasRecentIsos() const { + std::lock_guard guard(recentIsosLock); + return !recentIsos.empty(); +} +void Config::ClearRecentIsos() { + ResetRecentIsosThread(); + std::lock_guard guard(recentIsosLock); + recentIsos.clear(); } void Config::SetSearchPath(const Path &searchPath) { diff --git a/Core/Config.h b/Core/Config.h index 599c7de818..1125f5437b 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -535,15 +535,9 @@ public: return bFullScreen; } - std::vector RecentIsos() const { - return recentIsos; - } - bool HasRecentIsos() const { - return !recentIsos.empty(); - } - void ClearRecentIsos() { - recentIsos.clear(); - } + std::vector RecentIsos() const; + bool HasRecentIsos() const; + void ClearRecentIsos(); protected: void LoadStandardControllerIni(); From d76e2d434192155dba3de75f829e833ab93d7fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Jul 2022 22:14:01 +0200 Subject: [PATCH 03/57] compat.ini for Mali stencil bug: Add the Suikoden game too --- assets/compat.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 134c04cbc9..a17091de43 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -629,6 +629,11 @@ ULJS00384 = true ULJS00385 = true ULJS19078 = true +# Suikoden Woven Web of The Centuries / Genso Suikoden: Tsumugareshi Hyakunen no Toki +ULJM05886 = true +ULJM08063 = true +NPJH50535 = true + [RequireDefaultCPUClock] # GOW : Ghost of Sparta UCUS98737 = true From b3ccff5e2265941eb86f082267891b929a7aba84 Mon Sep 17 00:00:00 2001 From: Felipe Date: Tue, 12 Jul 2022 19:04:02 -0300 Subject: [PATCH 04/57] Add files via upload --- assets/lang/pt_BR.ini | 107 +++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/assets/lang/pt_BR.ini b/assets/lang/pt_BR.ini index ad82fbbad5..ecf92255bb 100644 --- a/assets/lang/pt_BR.ini +++ b/assets/lang/pt_BR.ini @@ -106,7 +106,6 @@ Portrait = Retrato Portrait Reversed = Retrato invertido PSP Action Buttons = Botões de ação do PSP Raw input = Entrada natural dos dados -Repeat mode = Repeat mode Reset to defaults = Resetar para os padrões Screen aligned to ground = Tela alinhada ao solo Screen at right angle to ground = Tela no ângulo direito do solo @@ -126,6 +125,7 @@ Tilt Sensitivity along X axis = Sensibilidade da inclinação junto ao eixo X Tilt Sensitivity along Y axis = Sensibilidade da inclinação junto ao eixo Y To Calibrate = Pra calibrar mantenha o dispositivo numa superfície plana e pressione "Calibrar". Toggle mode = Alternar modo +Repeat mode = Modo de repetição Touch Control Visibility = Visibilidade do controle de toque Use custom right analog = Usar analógico direito personalizado Use Mouse Control = Usar o controle do mouse @@ -265,12 +265,12 @@ FPU = FPU Framedump tests = Testes dos dumps dos frames Frame Profiler = Analista dos frames GPU Driver Test = Teste do driver da GPU -GPU Log Profiler = GPU Log Profiler GPU Profile = Perfil da GPU +GPU Log Profiler = Criador do Perfil do Registro da GPU Jit Compare = Comparar JIT JIT debug tools = Ferramentas de debug do JIT Language = Idioma -Load language ini = Carregar ini do idioma +Load language ini = Carregar o ini do idioma Log Dropped Frame Statistics = Pôr no log as estátisticas da queda dos frames Log Level = Nível do log Log View = Visualização do log @@ -293,7 +293,7 @@ Show Developer Menu = Mostrar menu do desenvolvedor Show on-screen messages = Mostrar mensagens na tela Stats = Estatísticas System Information = Informação do sistema -Texture ini file created = Texture ini file created +Texture ini file created = Arquivo ini da textura criado Texture Replacement = Substituição das texturas Toggle Audio Debug = Alternar debug do áudio Toggle Freeze = Alternar congelamento @@ -525,7 +525,6 @@ Frame Rate Control = Controle da taxa dos frames Frame Skipping = Pulo dos frames Frame Skipping Type = Tipo de pulo dos frames FullScreen = Tela cheia -GPU log profiler = GPU log profiler Hack Settings = Configurações dos hacks (pode causar erros gráficos) Hardware Tessellation = Tesselação por hardware Hardware Transform = Transformação por hardware @@ -599,6 +598,7 @@ VSync = VSync Vulkan = Vulkan Window Size = Tamanho da janela xBRZ = xBRZ +GPU log profiler = Criador de perfil da GPU [InstallZip] Delete ZIP file = Apagar arquivo ZIP @@ -653,9 +653,9 @@ Audio = Áudio Controls = Controles Graphics = Gráficos Networking = Rede -Search = Search System = Sistema Tools = Ferramentas +Search = Busca [MappableControls] Alt speed 1 = Velocidade alternativa 1 @@ -665,7 +665,7 @@ An.Left = Analógico Esquerdo An.Right = Analógico Direito An.Up = Analógico pra Cima Analog limiter = Limitador do analógico -Analog Stick = Analógico +Analog Stick = Direcional Analógico Audio/Video Recording = Gravação de Áudio/Vídeo AxisSwap = Trocar eixos Circle = Círculo @@ -685,14 +685,10 @@ D-pad left = Direcional esquerdo D-pad right = Direcional direito D-pad up = Direcional pra cima DevMenu = Menu dos desenvolvedores -Display Landscape = Display Landscape -Display Landscape Reversed = Display Landscape Reversed -Display Portrait = Display Portrait -Display Portrait Reversed = Display Portrait Reversed Double tap button = Botão do toque duplo Down = Direcional pra Baixo Dpad = Direcional -Frame Advance = Avançar frames +Frame Advance = Avanço dos frames Hold = Segurar Home = Home L = L @@ -710,7 +706,7 @@ Record = Gravar Remote hold = Segurar remoto Rewind = Rebobinar Right = Direcional Direito -Right Analog Stick = Análogico Direito +Right Analog Stick = Direcional Análogico Direito RightAn.Down = Analógico Direito pra Baixo RightAn.Left = Analógico Direito a Esquerda RightAn.Right = Analógico Direito a Direita @@ -731,7 +727,7 @@ Swipe Up = Deslizar pra Cima tap to customize = Toque pra personalizar Texture Dumping = Dumpagem das texturas Texture Replacement = Substituição das texturas -Toggle Fullscreen = Alternar pra Tela cheia +Toggle Fullscreen = Alternar pra tela cheia Toggle mode = Alternar modo Triangle = Triângulo Fast-forward = Avanço rápido @@ -739,6 +735,10 @@ Up = Direcional pra Cima Vol + = Vol + Vol - = Vol - Wlan = WLAN +Display Landscape = Exibir Paisagem +Display Landscape Reversed = Exibir Paisagem Revertida +Display Portrait = Exibir Retrato +Display Portrait Reversed = Exibir Retrato Revertido [Networking] AdHoc Server = Servidor Ad-hoc @@ -784,7 +784,7 @@ Network Initialized = Rede inicializada None = Nenhum Please change your Port Offset = Por favor mude seu deslocamento da porta Port offset = Deslocamento da porta (0 = Compatibilidade com o PSP) -Open PPSSPP Multiplayer Wiki Page = Página do Ad-Hoc no Wiki do PPSSPP +Open PPSSPP Multiplayer Wiki Page = Abrir a Página do Multiplayer do Wiki do PPSSPP proAdhocServer Address: = Endereço do servidor ad-hoc: Quick Chat 1 = Bate-papo rápido 1 Quick Chat 2 = Bate-papo rápido 2 @@ -803,7 +803,7 @@ UPnP need to be reinitialized = O UPnP precisa ser reinicializado UPnP use original port = O UPnP usa a porta original (ativado = compatibilidade com o PSP) Validating address... = Validando endereço... WLAN Channel = Canal do WLAN -You're in Offline Mode, go to lobby or online hall = Você está no modo offline, vá pro lobby ou salão online +You're in Offline Mode, go to lobby or online hall = Você está no modo offline, vá pro lobby ou pro salão online [Pause] Cheats = Trapaças @@ -827,12 +827,10 @@ Undo last save = Desfazer o último salvamento 5xBR-lv2 = 5xBR-lv2 AAColor = Cores-do-AA Amount = Quantidade -Animation speed (0 -> disable) = Animation speed (0 -> disable) Black border = Borda preta Bloom = Bloom Brightness = Brilho Cartoon = Cartoon -CatmullRom = Bicubic (Catmull-Rom) Upscaler ColorCorrection = Correção das cores Contrast = Contraste CRT = Scanlines do CRT @@ -841,7 +839,6 @@ Gamma = Gama Grayscale = Tons de cinza Intensity = Intensidade InverseColors = Cores invertidas -MitchellNetravali = Bicubic (Mitchell-Netravali) Upscaler Natural = Cores naturais NaturalA = Cores naturais (sem borrão) Off = Desligado @@ -856,13 +853,16 @@ TexMMPX = MMPX UpscaleSpline36 = Ampliador Spline36 VideoSmoothingAA = Suavização de vídeo do AA Vignette = Vinheta +Animation speed (0 -> disable) = Velocidade da animação (0 -> desativar) +CatmullRom = Ampliador Bi-cúbico (Catmull-Rom) +MitchellNetravali = Ampliador Bi-cúbico (Mitchell-Netravali) [PSPCredits] all the forum mods = Todos os moderadores do fórum build server = Servidor dos builds Buy Gold = Comprar Gold check = Verifique também o Dolphin, o melhor emu de Wii/GC: -CheckOutPPSSPP = Veja o PPSSPP, o incrível emulador de PSP: https://www.ppsspp.org/ +CheckOutPPSSPP = Verifique o PPSSPP, o incrível emulador de PSP: https://www.ppsspp.org/ contributors = Contribuidores: created = Criado por Discord = Discord @@ -993,7 +993,7 @@ View Feedback = Visualizar todos os feedbacks Date = Data Filename = Nome do arquivo No screenshot = Sem screenshot -None yet. Things will appear here after you save. = Nada ainda. As coisas aparecerão aqui após você salvar. +None yet. Things will appear here after you save. = Nada ainda. As coisas aparecerão aqui após você salvar. Nothing matching '%1' was found. = Nada combinando com o '%1' foi achado. Save Data = Dados salvos Save States = States salvos @@ -1030,13 +1030,6 @@ standard = Velocidade: padrão State load undone = Carregamento do state desfeito Untitled PSP game = Jogo de PSP sem título -[Search] -Clear filter = Clear filter -Filter = Filter -Filtering settings by '%1' = Filtering settings by '%1' -Find settings = Find settings -No settings matched '%1' = No settings matched '%1' - [Store] Already Installed = Já instalado Connection Error = Erro de conexão @@ -1056,7 +1049,7 @@ ABI = ABI API Version = Versão da API Audio Information = Informação do áudio Board = Placa -Build Config = Config do build +Build Config = Configuração do build Build Configuration = Configuração do build Built by = Compilado por Core Context = Contexto do núcleo @@ -1069,9 +1062,8 @@ Debug = Debug Debugger Present = Debugger presente Device Info = Informação do dispositivo Directories = Diretórios -Display Color Formats = Display Color Formats Display Information = Informação da tela -Driver bugs = Driver bugs +Driver Version = Versão do driver Driver Version = Versão do driver EGL Extensions = Extensões do EGL Frames per buffer = Frames por buffer @@ -1081,7 +1073,7 @@ High precision int range = Alcance do inteiro de alta precisão Lang/Region = Idioma/Região Memory Page Size = Tamanho da página de memória Native Resolution = Resolução nativa -No GPU driver bugs detected = No GPU driver bugs detected +No GPU driver bugs detected = Não foram detectado bugs no driver da GPU OGL Extensions = Extensões do OGL OpenGL ES 2.0 Extensions = Extensões do OpenGL 2.0 ES OpenGL ES 3.0 Extensions = Extensões do OpenGL 3.0 ES @@ -1106,6 +1098,7 @@ Vendor (detected) = Vendedor (detectado) Version Information = Informação da versão Vulkan Extensions = Extensões do Vulkan Vulkan Features = Características do Vulkan +Display Color Formats = Exibir Formatos das Cores [System] (broken) = (quebrado) @@ -1117,8 +1110,6 @@ AVI Dump started. = Dump do AVI iniciado AVI Dump stopped. = Dump do AVI parado Cache ISO in RAM = Pôr a ISO inteira na RAM Change CPU Clock = Mudar o clock da CPU do PSP emulado (instável) -Color Saturation = Color Saturation -Color Tint = Color Tint Memory Stick folder = Pasta do cartão de memória Memory Stick size = Tamanho do cartão de memória Change Nickname = Mudar apelido @@ -1190,7 +1181,6 @@ Savestate slot backups = Backups dos slots dos states salvos Screenshots as PNG = Salvar as screenshots no formato PNG Set UI background... = Definir o cenário de fundo da interface do usuário... Show ID = Mostrar ID -Show Memory Stick folder = Show Memory Stick folder Show region flag = Mostrar a bandeira da região Simulate UMD delays = Simular atrasos do UMD Slot 1 = Slot 1 @@ -1200,7 +1190,6 @@ Slot 4 = Slot 4 Slot 5 = Slot 5 Storage full = Armazenamento cheio Sustained performance mode = Modo de performance sustentado -Theme = Theme Time Format = Formato da hora UI = Interface do usuário UI Sound = Som da interface do usuário @@ -1217,29 +1206,41 @@ WARNING: Android battery save mode is on = AVISO: O modo de economia da bateria WARNING: Battery save mode is on = AVISO: O modo de economia da bateria está ligado Waves = Ondas YYYYMMDD = AAAAMMDD - -[TextureShaders] -Off = Off -TexMMPX = TexMMPX -Tex2xBRZ = Tex2xBRZ -Tex4xBRZ = Tex4xBRZ +Theme = Tema +Color Tint = Tonalidade da Cor +Color Saturation = Saturação das Cores +Show Memory Stick folder = Mostrar a pasta do cartão de memória [Themes] Default = Padrão -[UI Elements] -%1 button = %1 button -%1 checkbox = %1 checkbox -%1 choice = %1 choice -%1 heading = %1 heading -%1 radio button = %1 radio button -%1 text field = %1 text field -Choices: = Choices: -List: = List: -Progress: %1% = Progress: %1% -Screen representation = Screen representation +[TextureShaders] +Off = Desligado +TexMMPX = TexMMPX +Tex2xBRZ = Tex2xBRZ +Tex4xBRZ = Tex4xBRZ + +[Search] +No settings matched '%1' = Nenhuma das configurações combinou com o '%1' +Filtering settings by '%1' = Configurações da filtragem do '%1' +Find settings = Achar configurações +Filter = Filtro +Clear filter = Limpar filtro + [Upgrade] Details = Detalhes Dismiss = Ignorar Download = Baixar New version of PPSSPP available = Uma nova versão do PPSSPP está disponível + +[UI Elements] +%1 button = %1 botão +%1 checkbox = %1 caixa de seleção +%1 choice = %1 escolha +%1 heading = %1 cabeçalho +%1 radio button = %1 botão do rádio +%1 text field = %1 campo do texto +Choices: = Escolhas: +List: = Lista: +Progress: %1% = Progresso: %1% +Screen representation = Representação da tela \ No newline at end of file From 4e249203758495300240e2fef216b82a6de3161f Mon Sep 17 00:00:00 2001 From: xujibbs <79200793+xujibbs@users.noreply.github.com> Date: Wed, 13 Jul 2022 06:59:42 +0800 Subject: [PATCH 05/57] Update zh_CN.ini --- assets/lang/zh_CN.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index b3a321a8d7..ff13bbfe5e 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -269,7 +269,7 @@ Show Developer Menu = 显示开发者菜单 Show on-screen messages = 显示屏幕消息 Stats = 统计数据 System Information = 系统信息 -Texture ini file created = Texture ini file created +Texture ini file created = 创建纹理 ini 文件 Texture Replacement = 纹理替换 Toggle Audio Debug = 切换音频调试 Toggle Freeze = 切换冻结 From 23aab78861ec7598b27d654c327013eb0b0ce4f6 Mon Sep 17 00:00:00 2001 From: xujibbs <79200793+xujibbs@users.noreply.github.com> Date: Wed, 13 Jul 2022 07:01:27 +0800 Subject: [PATCH 06/57] Update zh_TW.ini --- assets/lang/zh_TW.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang/zh_TW.ini b/assets/lang/zh_TW.ini index c6280c2c59..a7e85f45ee 100644 --- a/assets/lang/zh_TW.ini +++ b/assets/lang/zh_TW.ini @@ -269,7 +269,7 @@ Show Developer Menu = 顯示開發者選單 Show on-screen messages = 顯示屏幕消息 Stats = 統計 System Information = 系統資料 -Texture ini file created = Texture ini file created +Texture ini file created = 創建紋理 INI 文件 Texture Replacement = 纹理更换 Toggle Audio Debug = 切換音訊除錯 Toggle Freeze = 切換凍結 From a983828731d99e39f9b02ed5a4586dbc388b1d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Jul 2022 01:16:40 +0200 Subject: [PATCH 07/57] langtool: Add command move-key to move a line globally from one section to another. Update deps --- Tools/langtool/Cargo.lock | 60 ++++++++++++++++++----------------- Tools/langtool/src/main.rs | 27 ++++++++++++++++ Tools/langtool/src/section.rs | 22 +++++++++++++ 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/Tools/langtool/Cargo.lock b/Tools/langtool/Cargo.lock index 362b6ec359..e837567757 100644 --- a/Tools/langtool/Cargo.lock +++ b/Tools/langtool/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] @@ -28,9 +30,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -74,9 +76,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "proc-macro-error" @@ -104,18 +106,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] @@ -128,9 +130,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.23" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", @@ -139,9 +141,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", @@ -152,13 +154,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.76" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -171,10 +173,16 @@ dependencies = [ ] [[package]] -name = "unicode-segmentation" -version = "1.8.0" +name = "unicode-ident" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" @@ -182,12 +190,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "vec_map" version = "0.8.2" @@ -196,9 +198,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "winapi" diff --git a/Tools/langtool/src/main.rs b/Tools/langtool/src/main.rs index 0ab1bc29ee..d3ffa95193 100644 --- a/Tools/langtool/src/main.rs +++ b/Tools/langtool/src/main.rs @@ -18,6 +18,7 @@ enum Command { CopyMissingLines {}, CommentUnknownLines {}, RemoveUnknownLines {}, + MoveKey { old: String, new: String, key: String }, } fn copy_missing_lines(reference_ini: &IniFile, target_ini: &mut IniFile) -> io::Result<()> { @@ -55,6 +56,29 @@ fn deal_with_unknown_lines( Ok(()) } +fn move_key( + target_ini: &mut IniFile, + old: &str, + new: &str, + key: &str, +) -> io::Result<()> { + // Insert any missing full sections. + if let Some(old_section) = target_ini.get_section_mut(old) { + if let Some(line) = old_section.remove_line(key) { + if let Some(new_section) = target_ini.get_section_mut(new) { + new_section.insert_line_if_missing(&line); + } else { + println!("No new section {}", new); + } + } else { + println!("No key {} in section {}", key, old); + } + } else { + println!("No old section {}", old); + } + Ok(()) +} + fn main() { let opt = Opt::from_args(); @@ -103,6 +127,9 @@ fn main() { Command::RemoveUnknownLines {} => { deal_with_unknown_lines(&reference_ini, &mut target_ini, true).unwrap(); } + Command::MoveKey { ref old, ref new,ref key, } => { + move_key(&mut target_ini, &old, &new, &key).unwrap(); + } } target_ini.write().unwrap(); diff --git a/Tools/langtool/src/section.rs b/Tools/langtool/src/section.rs index 1812cd006e..dbb097832a 100644 --- a/Tools/langtool/src/section.rs +++ b/Tools/langtool/src/section.rs @@ -11,6 +11,28 @@ pub struct Section { } impl Section { + pub fn remove_line(&mut self, key: &str) -> Option { + let mut remove_index = None; + for (index, line) in self.lines.iter().enumerate() { + let prefix = if let Some(pos) = line.find(" =") { + &line[0..pos] + } else { + continue; + }; + + if prefix.eq_ignore_ascii_case(&key) { + remove_index = Some(index); + break; + } + } + + if let Some(remove_index) = remove_index { + Some(self.lines.remove(remove_index)) + } else { + None + } + } + pub fn insert_line_if_missing(&mut self, line: &str) -> bool { let prefix = if let Some(pos) = line.find(" =") { &line[0..pos + 2] From e9891e084364593a5c74e5f331087e412f4f3e06 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 11 Jul 2022 23:46:09 -0700 Subject: [PATCH 08/57] Config: Keep recentIsos lock owned by Config. --- Core/Config.cpp | 55 +++++++++++++++++++++++++++++-------------------- Core/Config.h | 2 ++ 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index ebb0521f6e..d4753cf3e1 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -58,9 +58,17 @@ http::Downloader g_DownloadManager; Config g_Config; bool jitForcedOff; -static std::mutex recentIsosLock; -static std::mutex recentIsosThreadLock; -static std::thread recentIsosThread; + +// Not in Config.h because it's #included a lot. +struct ConfigPrivate { + std::mutex recentIsosLock; + std::mutex recentIsosThreadLock; + std::thread recentIsosThread; + bool recentIsosThreadPending = false; + + void ResetRecentIsosThread(); + void SetRecentIsosThread(std::function f); +}; #ifdef _DEBUG static const char *logSectionName = "LogDebug"; @@ -1211,27 +1219,30 @@ static void IterateSettings(IniFile &iniFile, std::function guard(recentIsosThreadLock); - if (recentIsosThread.joinable()) + if (recentIsosThreadPending && recentIsosThread.joinable()) recentIsosThread.join(); } -static void SetRecentIsosThread(std::function f) { +void ConfigPrivate::SetRecentIsosThread(std::function f) { std::lock_guard guard(recentIsosThreadLock); - if (recentIsosThread.joinable()) + if (recentIsosThreadPending && recentIsosThread.joinable()) recentIsosThread.join(); recentIsosThread = std::thread(f); + recentIsosThreadPending = true; } Config::Config() { + private_ = new ConfigPrivate(); } Config::~Config() { if (bUpdatedInstanceCounter) { ShutdownInstanceCounter(); } - ResetRecentIsosThread(); + private_->ResetRecentIsosThread(); + delete private_; } std::map> GetLangValuesMapping() { @@ -1334,8 +1345,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { iMaxRecent = 60; if (iMaxRecent > 0) { - ResetRecentIsosThread(); - std::lock_guard guard(recentIsosLock); + private_->ResetRecentIsosThread(); + std::lock_guard guard(private_->recentIsosLock); recentIsos.clear(); for (int i = 0; i < iMaxRecent; i++) { char keyName[64]; @@ -1491,11 +1502,11 @@ bool Config::Save(const char *saveReason) { Section *recent = iniFile.GetOrCreateSection("Recent"); recent->Set("MaxRecent", iMaxRecent); - ResetRecentIsosThread(); + private_->ResetRecentIsosThread(); for (int i = 0; i < iMaxRecent; i++) { char keyName[64]; snprintf(keyName, sizeof(keyName), "FileName%d", i); - std::lock_guard guard(recentIsosLock); + std::lock_guard guard(private_->recentIsosLock); if (i < (int)recentIsos.size()) { recent->Set(keyName, recentIsos[i]); } else { @@ -1633,8 +1644,8 @@ void Config::AddRecent(const std::string &file) { // We'll add it back below. This makes sure it's at the front, and only once. RemoveRecent(file); - ResetRecentIsosThread(); - std::lock_guard guard(recentIsosLock); + private_->ResetRecentIsosThread(); + std::lock_guard guard(private_->recentIsosLock); const std::string filename = File::ResolvePath(file); recentIsos.insert(recentIsos.begin(), filename); if ((int)recentIsos.size() > iMaxRecent) @@ -1646,8 +1657,8 @@ void Config::RemoveRecent(const std::string &file) { if (iMaxRecent <= 0) return; - ResetRecentIsosThread(); - std::lock_guard guard(recentIsosLock); + private_->ResetRecentIsosThread(); + std::lock_guard guard(private_->recentIsosLock); const std::string filename = File::ResolvePath(file); for (auto iter = recentIsos.begin(); iter != recentIsos.end();) { const std::string recent = File::ResolvePath(*iter); @@ -1661,10 +1672,10 @@ void Config::RemoveRecent(const std::string &file) { } void Config::CleanRecent() { - SetRecentIsosThread([this] { + private_->SetRecentIsosThread([this] { double startTime = time_now_d(); - std::lock_guard guard(recentIsosLock); + std::lock_guard guard(private_->recentIsosLock); std::vector cleanedRecent; for (size_t i = 0; i < recentIsos.size(); i++) { bool exists = false; @@ -1696,16 +1707,16 @@ void Config::CleanRecent() { } std::vector Config::RecentIsos() const { - std::lock_guard guard(recentIsosLock); + std::lock_guard guard(private_->recentIsosLock); return recentIsos; } bool Config::HasRecentIsos() const { - std::lock_guard guard(recentIsosLock); + std::lock_guard guard(private_->recentIsosLock); return !recentIsos.empty(); } void Config::ClearRecentIsos() { - ResetRecentIsosThread(); - std::lock_guard guard(recentIsosLock); + private_->ResetRecentIsosThread(); + std::lock_guard guard(private_->recentIsosLock); recentIsos.clear(); } diff --git a/Core/Config.h b/Core/Config.h index 1125f5437b..e682234ba3 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -48,6 +48,7 @@ namespace http { } struct UrlEncoder; +struct ConfigPrivate; struct ConfigTouchPos { float x; @@ -550,6 +551,7 @@ private: Path iniFilename_; Path controllerIniFilename_; Path searchPath_; + ConfigPrivate *private_ = nullptr; }; std::map> GetLangValuesMapping(); From 656576c2838c33b3c138f496f6d936a3a82a085b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 13 Jul 2022 23:40:38 -0700 Subject: [PATCH 09/57] Io: Correct access field on dir listings. --- Common/File/AndroidStorage.cpp | 4 +++- Common/File/DirListing.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Common/File/AndroidStorage.cpp b/Common/File/AndroidStorage.cpp index 01b5824a8a..c1b4283651 100644 --- a/Common/File/AndroidStorage.cpp +++ b/Common/File/AndroidStorage.cpp @@ -160,7 +160,9 @@ static bool ParseFileInfo(const std::string &line, File::FileInfo *fileInfo) { fileInfo->exists = true; sscanf(parts[1].c_str(), "%" PRIu64, &fileInfo->size); fileInfo->isWritable = true; // TODO: Should be passed as part of the string. - fileInfo->access = fileInfo->isDirectory ? 0666 : 0777; // TODO: For read-only mappings, reflect that here, similarly as with isWritable. + // TODO: For read-only mappings, reflect that here, similarly as with isWritable. + // Directories are normally executable (0111) which means they're traversable. + fileInfo->access = fileInfo->isDirectory ? 0777 : 0666; uint64_t lastModifiedMs = 0; sscanf(parts[3].c_str(), "%" PRIu64, &lastModifiedMs); diff --git a/Common/File/DirListing.cpp b/Common/File/DirListing.cpp index 9b7b07cbf6..abe5ff3af8 100644 --- a/Common/File/DirListing.cpp +++ b/Common/File/DirListing.cpp @@ -242,6 +242,14 @@ bool GetFilesInDir(const Path &directory, std::vector *files, const ch info.atime = FiletimeToStatTime(ffd.ftLastAccessTime); info.mtime = FiletimeToStatTime(ffd.ftLastWriteTime); info.ctime = FiletimeToStatTime(ffd.ftCreationTime); + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + info.access = 0444; // Read + } else { + info.access = 0666; // Read/Write + } + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info.access |= 0111; // Execute + } if (!info.isDirectory) { std::string ext = info.fullName.GetFileExtension(); if (!ext.empty()) { From 1949de6c65310f37769d2d0587aade2c48fe6489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 14 Jul 2022 18:29:35 +0200 Subject: [PATCH 10/57] zh_CN translation: Apply spacing rules according to leoxx. See #15660 --- assets/lang/zh_CN.ini | 535 +++++++++++++++++++++--------------------- 1 file changed, 268 insertions(+), 267 deletions(-) diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index ff13bbfe5e..bc028b6b0d 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -1,12 +1,12 @@ [Audio] Alternate speed volume = 自定义速度下的音量 -Audio backend = 音频引擎 (需要重启) +Audio backend = 音频引擎(需要重启) Audio Error = 音频错误 -AudioBufferingForBluetooth = 蓝牙友好缓冲区 (更慢) +AudioBufferingForBluetooth = 蓝牙友好缓冲区(更慢) Auto = 自动 Device = 设备 Disabled = 禁用 -DSound (compatible) = DirectSound (兼容) +DSound (compatible) = DirectSound(兼容) Enable Sound = 开启声音 Global volume = 全局音量 Microphone = 麦克风 @@ -15,7 +15,7 @@ Mute = 静音 Reverb volume = 混响音量 Use new audio devices automatically = 自动使用新的音频设备 Use global volume = 使用全局音量 -WASAPI (fast) = WASAPI (快) +WASAPI (fast) = WASAPI(快) [Controls] Analog Binding = 摇杆绑定 @@ -48,15 +48,15 @@ Customize Touch Controls = 编辑触屏布局... Customize tilt = 自定义重力感应... D-PAD = 方向键 Deadzone radius = 死区半径 -Disable D-Pad diagonals (4-way touch) = 禁用方向键对角线 (四方向触控) +Disable D-Pad diagonals (4-way touch) = 禁用方向键对角线(四方向触控) Disable diagonal input = 禁用对角线方向输入 Double tap = 双击 Enable gesture control = 启用体感操作 Enable standard shortcut keys = 启用标准快捷键 Gesture = 体感 Gesture mapping = 体感映射 -Glowing borders = 细边框 (发光) -HapticFeedback = 按键反馈 (震动) +Glowing borders = 细边框(发光) +HapticFeedback = 按键反馈(震动) Hide touch analog stick background circle = 隐藏触屏摇杆的背景圈 Icon = 图标 Ignore gamepads when not focused = 后台运行时忽略游戏手柄 @@ -66,7 +66,7 @@ Invert Tilt along X axis = 沿 X 轴倾斜反转 Invert Tilt along Y axis = 沿 Y 轴倾斜反转 Keep this button pressed when right analog is pressed = 按下右摇杆时保持按下此按钮 Keyboard = 键盘控制设定 -L/R Trigger Buttons = L/R 触发按钮 +L/R Trigger Buttons = L/R扳机按钮 Landscape = 横向 Landscape Auto = 自动横向 Landscape Reversed = 横向反转 @@ -75,20 +75,20 @@ Mouse = 鼠标设置 Mouse sensitivity = 鼠标灵敏度 Mouse smoothing = 鼠标平滑度 MouseControl Tip = 您可以在按键映射界面按下 "M" 图标来映射鼠标按键。 -None (Disabled) = 无 (禁用) +None (Disabled) = 无(禁用) Off = 关闭 OnScreen = 屏幕虚拟按键 Portrait = 纵向 Portrait Reversed = 纵向反转 -PSP Action Buttons = PSP 功能键 +PSP Action Buttons = PSP功能键 Raw input = 原始输入 -Repeat mode = Repeat mode +Repeat mode = 重复模式 Reset to defaults = 重置为默认 Screen aligned to ground = 屏幕水平地面 Screen at right angle to ground = 屏幕垂直地面 Screen Rotation = 屏幕旋转 seconds, 0 : off = 秒, 0 = 不隐藏 -Sensitivity (scale) = 灵敏度 (倍率) +Sensitivity (scale) = 灵敏度(倍率) Sensitivity = 灵敏度 Shape = 形状 Show Touch Pause Menu Button = 显示暂停菜单按键 @@ -98,8 +98,8 @@ Swipe smoothing = 滑动平滑度 Thin borders = 细边框 Tilt Base Radius = 倾斜最小半径 Tilt Input Type = 重力感应替代按键类型 -Tilt Sensitivity along X axis = 沿 X 轴倾斜灵敏度 -Tilt Sensitivity along Y axis = 沿 Y 轴倾斜灵敏度 +Tilt Sensitivity along X axis = 沿X轴倾斜灵敏度 +Tilt Sensitivity along Y axis = 沿Y轴倾斜灵敏度 To Calibrate = 如需校准, 请保证设备在一个平面上,然后按"校准" Toggle mode = 切换模式 Touch Control Visibility = 触摸按键可见性 @@ -114,7 +114,7 @@ Y = Y Cheats = 金手指 Edit Cheat File = 编辑金手指文件 Enable/Disable All = 启用/禁用所有金手指 -Import Cheats = 从 cheat.db 导入 +Import Cheats = 从cheat.db导入 Options = 选项 Refresh Rate = 刷新率 @@ -123,9 +123,9 @@ Refresh Rate = 刷新率 # Just add it to your language's ini file and uncomment it (remove the # by Font). Auto Max Quality = 自动最佳质量 (&Q) Font = 微软雅黑 -About PPSSPP... = 关于 PPSSPP (&A)... +About PPSSPP... = 关于PPSSPP (&A)... Auto = 自动 (&A) -Backend = 渲染引擎 (需要 PPSSPP 重新启动) (&b) +Backend = 渲染引擎(需要 PPSSPP 重新启动) (&b) Bicubic = 双三次 (&B) Break = 停止 Break on Load = 载入后停止 @@ -156,16 +156,16 @@ GitHub = Git&Hub Hardware Transform = 硬件几何变换 (&H) Help = 帮助 (&H) Hybrid = 混合 (&H) -Hybrid + Bicubic = 混合 + 双三次 (&y) +Hybrid + Bicubic = 混合+双三次 (&y) Ignore Illegal Reads/Writes = 忽略读写错误 (&I) -Ignore Windows Key = 忽略 Windows 键 +Ignore Windows Key = 忽略Windows键 Keep PPSSPP On Top = 窗口总在最前 (&K) Landscape = 横向 Landscape reversed = 横向反转 Language... = 语言 (&n)... Linear = 线性过滤 (&L) Load = 载入 (&L)... -Load .sym File... = 载入 .sym 文件 (&a)... +Load .sym File... = 载入.sym文件 (&a)... Load Map File... = 载入内存镜像文件 (&M)... Load State = 快速读档 (&o) Load State File... = 载入即时存档 (&L)... @@ -177,7 +177,7 @@ Non-Buffered Rendering = 跳过缓冲效果 (非缓冲, 更快) (&S) Off = 关闭 (&O) Open Chat = 打开聊天 Open Directory... = 打开路径(&D)... -Open from MS:/PSP/GAME... = 打开 MS:/PSP/GAME (&p)... +Open from MS:/PSP/GAME... = 从MS:/PSP/GAME处打开 (&p)... Open Memory Stick = 打开记忆棒 (&M) Open New Instance = 打开新的模拟器进程 OpenGL = &OpenGL @@ -195,56 +195,56 @@ Rendering Resolution = 渲染分辨率 (&R) Reset = 重置 (&e) Reset Symbol Table = 重置符号表 (&R) Run = 运行 (&R) -Save .sym File... = 保存 .sym 文件 (&e)... +Save .sym File... = 保存.sym文件 (&e)... Save Map File... = 保存内存镜像文件 (&S)... Save State = 快速存档 (&a) Save State File... = 保存即时存档 (&S)... Savestate Slot = 即时存档插槽 (&t) Screen Scaling Filter = 屏幕缩放滤镜 (&e) Show Debug Statistics = 显示调试信息 (&g) -Show FPS Counter = 显示 &FPS 计数器 +Show FPS Counter = 显示FPS计数器 (&F) Skip Number of Frames = 跳过帧的数量 Skip Percent of FPS = 跳过帧率的百分比 Stop = 停止 (&S) -Switch UMD = 切换 UMD 光盘 +Switch UMD = 切换UMD光盘 Take Screenshot = 屏幕截图 (&T) Texture Filtering = 纹理过滤方式 (&x) Texture Scaling = 纹理缩放方式 (&T) -Use Lossless Video Codec (FFV1) = 使用无损视频编解码器 (FFV1) (&U) +Use Lossless Video Codec (FFV1) = 使用无损视频编解码器(FFV1) (&U) Use output buffer for video = 录制时使用输出缓冲 Vertex Cache = 顶点缓存 (&V) VSync = 垂直同步 (&y) Vulkan = Vulkan Window Size = 窗口大小 (&W) -www.ppsspp.org = 访问官网 www.&ppsspp.org -xBRZ = &xBRZ (&x) +www.ppsspp.org = 访问www.ppsspp.org (&p) +xBRZ = &xBRZ [Developer] -Allocator Viewer = Allocator 查看器 (Vulkan) +Allocator Viewer = Allocator查看器(Vulkan) Allow remote debugger = 允许远程调试器 Backspace = 退格键 Block address = 内存块地址 By Address = 通过地址定位 Copy savestates to memstick root = 拷贝即时存档至记忆棒根路径 -Create/Open textures.ini file for current game = 创建/打开当前游戏的 textures.ini 文件 +Create/Open textures.ini file for current game = 创建/打开当前游戏的textures.ini文件 Current = 当前 Dev Tools = 开发者工具 DevMenu = 开发者菜单 -Disabled JIT functionality = 已禁用的 JIT 功能 +Disabled JIT functionality = 已禁用的JIT功能 Draw Frametimes Graph = 显示帧时间统计图 -Dump Decrypted Eboot = 当载入游戏时转储已解密的 EBOOT.BIN -Dump Frame GPU Commands = 转储帧 GPU 命令 +Dump Decrypted Eboot = 当载入游戏时转储已解密的EBOOT.BIN +Dump Frame GPU Commands = 转储帧GPU命令 Enable driver bug workarounds = 启用驱动程序错误解决方法 Enable Logging = 启用调试日志 Enter address = 输入地址 FPU = FPU Framedump tests = 帧转储测试 Frame Profiler = 帧分析器 -GPU Driver Test = GPU 驱动程序测试 -GPU Log Profiler = GPU 日志分析器 -GPU Profile = GPU 分析器 -Jit Compare = Jit 比较 -JIT debug tools = JIT 调试工具 +GPU Driver Test = GPU驱动程序测试 +GPU Log Profiler = GPU日志分析器 +GPU Profile = GPU分析器 +Jit Compare = Jit比较 +JIT debug tools = JIT调试工具 Language = 语言设置 Load language ini = 载入语言配置 Log Dropped Frame Statistics = 记录丢弃帧统计信息 @@ -258,10 +258,10 @@ Random = 随机 Replace textures = 纹理替换 Reset = 重置 Reset limited logging = 重置受限日志 -RestoreDefaultSettings = 您确定要将所有设置恢复到默认? (按键映射除外)\n该操作无法撤销。\n\n操作将在 PPSSPP 重新启动后生效。 -RestoreGameDefaultSettings = 您确定要将此游戏设置\n恢复为 PPSSPP 默认吗? +RestoreDefaultSettings = 您确定要将所有设置恢复到默认? (按键映射除外)\n该操作无法撤销。\n\n操作将在PPSSPP重新启动后生效。 +RestoreGameDefaultSettings = 您确定要将此游戏设置\n恢复为PPSSPP默认吗? Resume = 恢复 -Run CPU Tests = 运行 CPU 测试 +Run CPU Tests = 运行CPU测试 Save language ini = 保存语言配置 Save new textures = 保存新纹理 Shader Viewer = 着色器查看器 @@ -269,7 +269,7 @@ Show Developer Menu = 显示开发者菜单 Show on-screen messages = 显示屏幕消息 Stats = 统计数据 System Information = 系统信息 -Texture ini file created = 创建纹理 ini 文件 +Texture ini file created = 创建纹理ini文件 Texture Replacement = 纹理替换 Toggle Audio Debug = 切换音频调试 Toggle Freeze = 切换冻结 @@ -277,15 +277,15 @@ Touchscreen Test = 触屏测试 VFPU = VFPU [Dialog] -* PSP res = * PSP 分辨率 +* PSP res = * PSP分辨率 Active = 激活 Back = 返回 Cancel = 取消 Center = 中心 -ChangingGPUBackends = 更改引擎模式后需要重启 PPSSPP。立刻重启? -ChangingInflightFrames = 更改缓冲图形命令后需要重启 PPSSPP。立刻重启? +ChangingGPUBackends = 更改引擎模式后需要重启PPSSPP。立刻重启? +ChangingInflightFrames = 更改缓冲图形命令后需要重启PPSSPP。立刻重启? Channel: = 频道: -Choose PPSSPP save folder = 选择 PPSSPP 存档的文件夹 +Choose PPSSPP save folder = 选择PPSSPP存档的文件夹 Confirm Overwrite = 您要覆盖这个存档吗? Confirm Save = 您要保存到这个存档吗? ConfirmLoad = 您要载入这个存档吗? @@ -309,7 +309,7 @@ Enable All = 全部启用 Enter = 确定 Filter = 筛选 Finish = 完成 -GE Frame Dumps = GE 帧转储 +GE Frame Dumps = GE帧转储 Grid = 网格尺寸 Inactive = 未激活 InternalError = 发生内部错误. @@ -321,7 +321,7 @@ Move = 移动 Network Connection = 网络连接 NEW DATA = 新建存档 No = 否 -ObtainingIP = 获取 IP 地址.\n请稍候... +ObtainingIP = 获取IP地址.\n请稍候... OK = 确定 Old savedata detected = 检测到旧版本的存档数据 Options = 选项 @@ -345,32 +345,32 @@ There is no data = 存档不存在。 Toggle All = 全选 (全不选) Toggle List = 切换列表 Unsupported = 不支持 -When you save, it will load on a PSP, but not an older PPSSPP = 当您保存后, 它只会在 PSP 实机上载入, 而不是旧版本的 PPSSPP -When you save, it will not work on outdated PSP Firmware anymore = 当您保存后, 它无法在过时的 PSP 固件上运行 +When you save, it will load on a PSP, but not an older PPSSPP = 当您保存后, 它只会在PSP实机上载入, 而不是旧版本的PPSSPP +When you save, it will not work on outdated PSP Firmware anymore = 当您保存后, 它无法在过时的PSP固件上运行 Yes = 是 Zoom = 放大 [Error] -7z file detected (Require 7-Zip) = 这是 7ZIP 压缩文件。\n请试着使用 7-zip 或 WinRAR 进行解压缩。 -A PSP game couldn't be found on the disc. = 光盘中找不到 PSP 游戏。 -Cannot boot ELF located outside mountRoot. = 无法启动位于 mountRoot 之外的 ELF 文件。 +7z file detected (Require 7-Zip) = 这是7ZIP压缩文件。\n请试着使用 7-zip或WinRAR进行解压缩。 +A PSP game couldn't be found on the disc. = 光盘中找不到PSP游戏。 +Cannot boot ELF located outside mountRoot. = 无法启动位于 mountRoot 之外的ELF文件。 Could not save screenshot file = 无法保存屏幕截图文件 -D3D9or11 = 使用 Direct3D 9? (或者 "否" 以使用 Direct3D 11) -D3D11CompilerMissing = 没有找到 D3DCompiler_47.dll, 请安装它或者按下 确认 键来尝试使用 Direct3D 9 代替它。 -D3D11InitializationError = Direct3D 11 初始化出错 -D3D11Missing = 您的操作系统没有包含 D3D11。请运行 Windows Update。\n\n按下 确认 键来尝试使用 Direct3D 9 代替它。 -D3D11NotSupported = 您的图形处理器似乎并不支持 Direct3D 11。\n\n您想尝试使用 Direct3D 9 来代替它吗? +D3D9or11 = 使用Direct3D 9? (或者 "否" 以使用Direct3D 11) +D3D11CompilerMissing = 没有找到D3DCompiler_47.dll, 请安装它或者按下"确认"键来尝试使用Direct3D 9代替它。 +D3D11InitializationError = Direct3D 11初始化出错 +D3D11Missing = 您的操作系统没有包含D3D11。请运行Windows Update。\n\n按下"确认"键来尝试使用Direct3D 9代替它。 +D3D11NotSupported = 您的图形处理器似乎并不支持Direct3D 11。\n\n您想尝试使用Direct3D 9来代替它吗? Disk full while writing data = 写入数据时磁盘已满 -ELF file truncated - can't load = ELF 文件被截断 - 无法加载 +ELF file truncated - can't load = ELF文件被截断 - 无法加载 Error loading file = 无法加载游戏: Error reading file = 读取文件时出错。 Failed initializing CPU/Memory = 初始化CPU或内存失败 Failed to load executable: = 无法加载可执行文件: File corrupt = 文件损坏 -Game disc read error - ISO corrupt = 游戏光盘读取错误:ISO 损坏。 +Game disc read error - ISO corrupt = 游戏光盘读取错误:ISO损坏。 GenericAllStartupError = PPSSPP无法使用任何图形后端启动。 尝试升级图形和其他驱动程序. GenericBackendSwitchCrash = 启动时PPSSPP崩溃了.\n\n这通常意味着图形驱动程序问题。 尝试升级图形驱动程序.\n\n图形后端已切换: -GenericDirect3D9Error = 初始化图像失败。尝试更新您的显卡驱动程序和DirectX 9 运行库。\n\n是否尝试切换到 OpenGL 模式?\n\n错误信息: +GenericDirect3D9Error = 初始化图像失败。尝试更新您的显卡驱动程序和DirectX 9 运行库。\n\n是否尝试切换到OpenGL模式?\n\n错误信息: GenericGraphicsError = 图像错误 GenericOpenGLError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到 DirectX 9 模式?\n\n错误信息: GenericVulkanError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到 OpenGL 模式?\n\n错误信息: @@ -382,21 +382,21 @@ MsgErrorSavedataDataBroken = 保存数据已损坏. MsgErrorSavedataMSFull = 记忆棒已满.检查您的存储空间. MsgErrorSavedataNoData = 警告:未找到保存数据. MsgErrorSavedataNoMS = 未插入记忆棒. -No EBOOT.PBP, misidentified game = 找不到 EBOOT.PBP, 无法正确识别游戏。 +No EBOOT.PBP, misidentified game = 找不到EBOOT.PBP, 无法正确识别游戏。 Not a valid disc image. = 光盘镜像无效。 OpenGLDriverError = OpenGL 驱动程序错误 -PPSSPP doesn't support UMD Music. = PPSSPP 不支持 UMD 音乐。 -PPSSPP doesn't support UMD Video. = PPSSPP 不支持 UMD 视频。 -PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP 运行 PSP 游戏, PS1 或者 2 的游戏不能运行。 -PPSSPPDoesNotSupportInternet = PPSSPP 目前不支持连接互联网以获取 DLC、PSN 或游戏的更新。 -PS1 EBOOTs are not supported by PPSSPP. = PPSSPP 不支持由 PS1 EBOOT 生成的游戏镜像。 -PSX game image detected. = 这是 MODE2 镜像。PPSSPP 不支持 PS1 游戏。 -RAR file detected (Require UnRAR) = 这是 RAR 压缩文件。\n请尝试使用 UnRAR 进行解压缩。 -RAR file detected (Require WINRAR) = 这是 RAR 压缩文件。\n请尝试使用 WinRAR 进行解压缩。 +PPSSPP doesn't support UMD Music. = PPSSPP不支持UMD音乐。 +PPSSPP doesn't support UMD Video. = PPSSPP不支持UMD视频。 +PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP运行 PSP游戏, PS1或者2的游戏不能运行。 +PPSSPPDoesNotSupportInternet = PPSSPP目前不支持连接互联网以获取 DLC、PSN或游戏的更新。 +PS1 EBOOTs are not supported by PPSSPP. = PPSSPP不支持由PS1 EBOOT 生成的游戏镜像。 +PSX game image detected. = 这是MODE2镜像。PPSSPP不支持PS1游戏。 +RAR file detected (Require UnRAR) = 这是RAR压缩文件。\n请尝试使用 UnRAR进行解压缩。 +RAR file detected (Require WINRAR) = 这是RAR压缩文件。\n请尝试使用 WinRAR进行解压缩。 Running slow: try frameskip, sound is choppy when slow = 运行速度慢:尝试跳帧, 运行速度慢时声音不连贯 Running slow: Try turning off Software Rendering = 运行速度慢:尝试关闭"软件渲染" -Save encryption failed. This save won't work on real PSP = 存档加密失败。此存档将无法在 PSP 实机使用 -textures.ini filenames may not be cross-platform = "textures.ini" 文件名可能不是多平台的。 +Save encryption failed. This save won't work on real PSP = 存档加密失败。此存档将无法在PSP实机使用 +textures.ini filenames may not be cross-platform = "textures.ini"文件名可能不是多平台的。 This is a saved state, not a game. = 这是一个即时存档, 不是游戏。 This is save data, not a game. = 这是一个存档, 不是游戏。 Unable to create cheat file, disk may be full = 无法创建金手指文件, 磁盘可能已满 @@ -404,12 +404,12 @@ Unable to initialize rendering engine. = 无法初始化渲染引擎。 Unable to write savedata, disk may be full = 无法写入存档数据, 磁盘可能已满 Warning: Video memory FULL, reducing upscaling and switching to slow caching mode = 警告:显存已满, 减少分辨率提升并切换到慢速缓存模式。 Warning: Video memory FULL, switching to slow caching mode = 警告:显存已满, 切换到慢速缓存模式。 -ZIP file detected (Require UnRAR) = 这是 ZIP 压缩文件。\n请尝试使用 UnRAR 进行解压缩。 -ZIP file detected (Require WINRAR) = 这是 ZIP 压缩文件。\n请尝试使用 WinRAR 进行解压缩。 +ZIP file detected (Require UnRAR) = 这是ZIP压缩文件。\n请尝试使用 UnRAR进行解压缩。 +ZIP file detected (Require WINRAR) = 这是 ZIP 压缩文件。\n请尝试使用WinRAR进行解压缩。 [Game] Asia = 亚洲 -Calculate CRC = 计算 CRC +Calculate CRC = 计算CRC ConfirmDelete = 确认删除 Create Game Config = 建立游戏配置 Create Shortcut = 创建快捷方式 @@ -440,29 +440,29 @@ Use UI background = 使用界面背景 %, 0:unlimited = %, 0 = 无限制 (supersampling) = (超级采样) (upscaling) = (放大) -1x PSP = 1倍 PSP +1x PSP = 1倍PSP 2x = 2倍 -2x PSP = 2倍 PSP +2x PSP = 2倍PSP 3x = 3倍 -3x PSP = 3倍 PSP +3x PSP = 3倍PSP 4x = 4倍 4x PSP = 4倍 PSP 5x = 5倍 -5x PSP = 5倍 PSP -6x PSP = 6倍 PSP -7x PSP = 7倍 PSP +5x PSP = 5倍PSP +6x PSP = 6倍PSP +7x PSP = 7倍PSP 8x = 8倍 -8x PSP = 8倍 PSP -9x PSP = 9倍 PSP -10x PSP = 10倍 PSP +8x PSP = 8倍PSP +9x PSP = 9倍PSP +10x PSP = 10倍PSP 16x = 16倍 Aggressive = 激进 Alternative Speed = 自定义速度 -Alternative Speed 2 = 自定义速度 2 +Alternative Speed 2 = 自定义速度2 Anisotropic Filtering = 各向异性过滤 Auto = 自动 -Auto (1:1) = 自动 (1:1) -Auto (same as Rendering) = 自动 (同渲染分辨率) +Auto (1:1) = 自动(1:1) +Auto (same as Rendering) = 自动(同渲染分辨率) Auto FrameSkip = 自动跳帧 Auto Max Quality = 自动最佳质量 Auto Scaling = 自动缩放 @@ -472,12 +472,12 @@ Bicubic = 双三次 BlockTransfer Tip = 有些游戏需要将此选项设置为开以显示正确的图形 BlockTransferRequired = 警告:此游戏需要将"模拟块传输模式"设置为开。 Both = 全部显示 -Buffer graphics commands (faster, input lag) = 缓冲图形命令 (更快, 有输入延迟) +Buffer graphics commands (faster, input lag) = 缓冲图形命令(更快, 有输入延迟) Buffered Rendering = 缓冲渲染 BufferedRenderingRequired = 警告:此游戏需要将"渲染模式"设置为"缓冲渲染"。 Camera = 摄像头 Camera Device = 摄像头设备 -Cardboard Screen Size = 屏幕大小 (视区%) +Cardboard Screen Size = 屏幕大小(视区%) Cardboard Screen X Shift = 水平 % Cardboard Screen Y Shift = 垂直 % Cardboard VR Settings = Google Cardboard VR 设置 @@ -490,43 +490,43 @@ Deposterize Tip = 修复纹理被放大时可见的带状错误 Device = 设备 Direct3D 9 = Direct3D 9 Direct3D 11 = Direct3D 11 -Disable slower effects (speedup) = 停用较慢的渲染效果 (提速) +Disable slower effects (speedup) = 停用较慢的渲染效果(提速) Disabled = 禁用 Display layout editor = 显示布局编辑器 -Display Resolution (HW scaler) = 显示分辨率 (硬件缩放) +Display Resolution (HW scaler) = 显示分辨率(硬件缩放) Dump next frame to log = 转储下一帧到日志 -Enable Cardboard VR = 启用 Cardboard VR +Enable Cardboard VR = 启用Cardboard VR FPS = 每秒帧数 (FPS) Frame Rate Control = 帧率控制 Frame Skipping = 跳帧 Frame Skipping Type = 跳帧方式 FullScreen = 全屏幕 -GPU log profiler = GPU 日志分析器 -Hack Settings = 渲染修正 (可能引发故障) +GPU log profiler = GPU日志分析器 +Hack Settings = 渲染修正(可能引发故障) Hardware Tessellation = 硬件曲面细分 Hardware Transform = 硬件几何变换 hardware transform error - falling back to software = 硬件几何变换错误, 改回软件模式 HardwareTessellation Tip = 使用硬件绘制曲线, 使用固定的质量 High = 高 Hybrid = 混合 -Hybrid + Bicubic = 混合 + 双三次 +Hybrid + Bicubic = 混合+双三次 Ignore camera notch when centering = 居中时忽略摄像头缺口 Internal Resolution = 内部分辨率 -Lazy texture caching = 减少缓存存取 (提速) +Lazy texture caching = 减少缓存存取(提速) Lazy texture caching Tip = 更快, 在一些游戏里引起文字渲染错误 Linear = 线性过滤 Low = 低 -LowCurves = 低品质样条函数/贝塞尔曲线 (提速) +LowCurves = 低品质样条函数/贝塞尔曲线(提速) LowCurves Tip = 仅对部分游戏有效, 控制曲线的平滑度 -Lower resolution for effects (reduces artifacts) = 降低特效分辨率 (减少伪像) +Lower resolution for effects (reduces artifacts) = 降低特效分辨率(减少伪像) Manual Scaling = 手动缩放 Medium = 中 Mode = 渲染模式 -Must Restart = 重启 PPSSPP 才能使这项设置生效。 +Must Restart = 重启PPSSPP才能使这项设置生效。 Native device resolution = 本机原生的分辨率 Nearest = 邻近取样 No buffer = 不缓冲 -Non-Buffered Rendering = 跳过缓冲 (更快) +Non-Buffered Rendering = 跳过缓冲(更快) None = 不显示 Number of Frames = 帧的数量 Off = 关闭 @@ -538,12 +538,12 @@ Performance = 性能 Postprocessing effect = 后处理效果 Postprocessing Shader = 后处理着色器 Recreate Activity = 重建进程 -Render duplicate frames to 60hz = 渲染重复帧至 60 Hz +Render duplicate frames to 60hz = 渲染重复帧至60Hz RenderDuplicateFrames Tip = 在较低帧率的游戏中可以使帧速率更平滑 Rendering Mode = 渲染模式 Rendering Resolution = 渲染分辨率 RenderingMode NonBuffered Tip = 更快, 但可能在某些游戏中丢失特效 -Retain changed textures = 保留已更改的纹理 (有时更慢) +Retain changed textures = 保留已更改的纹理(有时更慢) RetainChangedTextures Tip = 使较多游戏减速, 但有些游戏可能变快很多 Rotation = 旋转 Safe = 安全 @@ -552,9 +552,9 @@ Screen Scaling Filter = 屏幕缩放滤镜 Show Debug Statistics = 显示调试信息 Show FPS Counter = 显示 FPS 计数器 Simulate Block Transfer = 模拟数据块传输效果 -Software Rendering = 软件渲染 (慢) +Software Rendering = 软件渲染(慢) Software Skinning = 软件蒙皮 -SoftwareSkinning Tip = 合并 CPU 中已经蒙皮的模型绘制, 在部分游戏中更快 +SoftwareSkinning Tip = 合并CPU中已经蒙皮的模型绘制, 在部分游戏中更快 Speed = 运行速度 Stretching = 拉伸 Texture Filter = 纹理过滤方式 @@ -563,11 +563,11 @@ Texture Scaling = 纹理缩放 Texture Shader = 纹理着色器 Turn off Hardware Tessellation - unsupported = 关闭"硬件曲面细分":不支持 Unlimited = 无限制 -Up to 1 = 最高为 1 -Up to 2 = 最高为 2 +Up to 1 = 最高为1 +Up to 2 = 最高为2 Upscale Level = 纹理缩放级别 Upscale Type = 纹理缩放方式 -UpscaleLevel Tip = CPU 重负载 - 为避免卡顿, 某些缩放可能会延迟 +UpscaleLevel Tip = CPU重负载 - 为避免卡顿, 某些缩放可能会延迟 Use all displays = 使用全部显示器 Vertex Cache = 顶点缓存 VertexCache Tip = 更快, 但可能会造成暂时的闪烁 @@ -577,14 +577,14 @@ Window Size = 窗口大小 xBRZ = xBRZ [InstallZip] -Delete ZIP file = 删除 ZIP 文件 +Delete ZIP file = 删除ZIP文件 Install = 安装 -Install game from ZIP file? = 从 ZIP 文件安装游戏? -Install textures from ZIP file? = 从 ZIP 文件安装纹理包? +Install game from ZIP file? = 从ZIP文件安装游戏? +Install textures from ZIP file? = 从ZIP文件安装纹理包? Installed! = 安装完成! Texture pack doesn't support install = 此纹理包不支持安装 Zip archive corrupt = ZIP 文档损坏 -Zip file does not contain PSP software = ZIP 文件不包含 PSP 软件 +Zip file does not contain PSP software = ZIP文件不包含PSP软件 [KeyMapping] Autoconfigure = 自动配置 @@ -597,28 +597,28 @@ Map Key = 按键映射 Map Mouse = 鼠标映射 Replace = 替换现有 Show PSP = 显示 PSP -You can press ESC to cancel. = 您可以按下 ESC 键取消 +You can press ESC to cancel. = 您可以按下ESC键取消 [MainMenu] Browse = 浏览... Buy PPSSPP Gold = 购买黄金版 Choose folder = 选择文件夹 Credits = 开发团队 -PPSSPP Homebrew Store = 从 PPSSPP 自制软件商店下载 +PPSSPP Homebrew Store = 从PPSSPP自制软件商店下载 Exit = 退出程序 Game Settings = 游戏设置 Games = 载入新游戏 -Give PPSSPP permission to access storage = 给予 PPSSPP 访问存储空间的权限 +Give PPSSPP permission to access storage = 给予PPSSPP访问存储空间的权限 Homebrew & Demos = 自制游戏与试玩 How to get games = 如何获得游戏? How to get homebrew & demos = 如何获得自制游戏与试玩? Load = 载入游戏... Loading... = 载入中... PinPath = 固定 -PPSSPP can't load games or save right now = PPSSPP 现在不能载入游戏或存档 +PPSSPP can't load games or save right now = PPSSPP现在不能载入游戏或存档 Recent = 最近的游戏 SavesAreTemporary = PPSSPP 正在临时空间内存档 -SavesAreTemporaryGuidance = 请将 PPSSPP 解压出来以使存档永久保留 +SavesAreTemporaryGuidance = 请将PPSSPP解压出来以使存档永久保留 SavesAreTemporaryIgnore = 忽略警告 UnpinPath = 取消固定 UseBrowseOrLoad = 浏览以选择文件夹,或者加载以读取游戏文件 @@ -634,8 +634,8 @@ Tools = 工具 Search = 搜索 [MappableControls] -Alt speed 1 = 自定义速度 1 -Alt speed 2 = 自定义速度 2 +Alt speed 1 = 自定义速度1 +Alt speed 2 = 自定义速度2 An.Down = 左摇杆:下 An.Left = 左摇杆:左 An.Right = 左摇杆:右 @@ -646,16 +646,16 @@ Audio/Video Recording = 音频/视频录制 AxisSwap = 摇杆互换 Circle = 圆 Cross = 叉 -Custom 1 = 预设 1 -Custom 10 = 预设 10 -Custom 2 = 预设 2 -Custom 3 = 预设 3 -Custom 4 = 预设 4 -Custom 5 = 预设 5 -Custom 6 = 预设 6 -Custom 7 = 预设 7 -Custom 8 = 预设 8 -Custom 9 = 预设 9 +Custom 1 = 预设1 +Custom 10 = 预设10 +Custom 2 = 预设2 +Custom 3 = 预设3 +Custom 4 = 预设4 +Custom 5 = 预设5 +Custom 6 = 预设6 +Custom 7 = 预设7 +Custom 8 = 预设8 +Custom 9 = 预设9 D-pad down = 方向键:下 D-pad left = 方向键:左 D-pad right = 方向键:右 @@ -670,14 +670,14 @@ Down = 方向键:下 Dpad = 方向键 Frame Advance = 逐帧播放 Hold = 短按电源键 -Home = Home 键 +Home = Home键 L = L Left = 方向键:左 Load State = 载入即时存档 Mute toggle = 静音 Next Slot = 下个即时存档插槽 None = 无 -Note = ♪ 键 +Note = ♪键 OpenChat = 打开聊天 Pause = 暂停 R = R @@ -691,8 +691,8 @@ RightAn.Down = 右摇杆:下 RightAn.Left = 右摇杆:左 RightAn.Right = 右摇杆:右 RightAn.Up = 右摇杆:上 -Rotate Analog (CCW) = 旋转摇杆 (逆时针) -Rotate Analog (CW) = 旋转摇杆 (顺时针) +Rotate Analog (CCW) = 旋转摇杆(逆时针) +Rotate Analog (CW) = 旋转摇杆(顺时针) Save State = 保存即时存档 Screen = 屏幕亮度键 Screenshot = 截图 @@ -710,87 +710,88 @@ Texture Replacement = 纹理替换 Toggle Fullscreen = 切换全屏 Toggle mode = 切换模式 Triangle = 三角 -Fast-forward = 加速 (长按) +Fast-forward = 加速(长按) Up = 方向键:上 -Vol + = 音量 + -Vol - = 音量 - +Vol + = 音量+ +Vol - = 音量- Wlan = 无线网络 [MemStick] -Already contains PSP data = 已含有 PSP 数据 -Create or Choose a PSP folder = 创建或者选择 PSP 文件夹 +Already contains PSP data = 已含有PSP数据 +Create or Choose a PSP folder = 创建或者选择PSP文件夹 Current = 目前 DataCanBeShared = 数据可以在普通版/黄金版之间共用 DataCannotBeShared = 数据无法在普通版/黄金版之间共用! -DataWillBeLostOnUninstall = 警告!卸载 PPSSPP 将丢失全部数据! -DataWillStay = 卸载 PPSSPP 时会保留数据。 +DataWillBeLostOnUninstall = 警告!卸载PPSSPP将丢失全部数据! +DataWillStay = 卸载PPSSPP时会保留数据。 Done! = 完成! -EasyUSBAccess = 轻松 USB 访问 +EasyUSBAccess = 轻松USB访问 Failed to move some files! = 无法移动部分文件! Failed to save config = 无法保存配置! Free space = 可用空间 -Manually specify PSP folder = 手动指定 PSP 文件夹 -MemoryStickDescription = 选择 PSP 文件的存放位置 (记忆棒) +Manually specify PSP folder = 手动指定PSP文件夹 +MemoryStickDescription = 选择PSP文件的存放位置(记忆棒) Move Data = 移动PSP数据 -Selected PSP Data Folder = 选择 PSP 数据文件夹 +Selected PSP Data Folder = 选择PSP数据文件夹 No data will be changed = 数据不会更改 -PPSSPP will restart after the change = 完成设置后会重启 PPSSPP +PPSSPP will restart after the change = 完成设置后会重启PPSSPP Skip for now = 暂时跳过 Starting move... = 开始移动... That folder doesn't work as a memstick folder. = 您选择的文件夹无法作为记忆棒路径。 -USBAccessThrough = USB 连接时请打开 Android/data/org.ppsspp.ppsspp/files -USBAccessThroughGold = USB 连接时请打开 Android/data/org.ppsspp.ppssppgold/files -Use App Private Data = 在 APP 内置的路径中保存 -Use PSP folder at root of storage = 在手机路径中保存 PSP 文件 -Welcome to PPSSPP! = 欢迎使用 PPSSPP! +USBAccessThrough = USB连接时请打开 Android/data/org.ppsspp.ppsspp/files +USBAccessThroughGold = USB连接时请打开Android/data/org.ppsspp.ppssppgold/files +Use App Private Data = 在APP内置的路径中保存 +Use PSP folder at root of storage = 在手机路径中保存PSP文件 +Welcome to PPSSPP! = 欢迎使用PPSSPP! WhatsThis = 这个设置有什么用? [Networking] -AdHoc Server = Ad Hoc 服务器 -AdhocServer Failed to Bind Port = 无法绑定 Adhoc 服务器端口 -AM: Data from Unknown Port = AM: 来自未知端口的数据 +AdHoc Server = Ad Hoc服务器 +AdhocServer Failed to Bind Port = 无法绑定Adhoc服务器端口 +AM: Data from Unknown Port = AM:来自未知端口的数据 Auto = 自动 Bottom Center = 正下方 Bottom Left = 左下方 Bottom Right = 右下方 Center Left = 左中间 Center Right = 右中间 -Change Mac Address = 更改 MAC 地址 -Change proAdhocServer Address = 更改 PRO Ad Hoc 服务器 IP 地址 (localhost = 模拟器双开) +Change Mac Address = 更改MAC地址 +Change proAdhocServer Address = 更改PRO Ad Hoc服务器IP地址 (localhost = 模拟器双开) Chat = 聊天 Chat Button Position = 聊天按钮位置 Chat Here = 在这里聊天 Chat message = 聊天消息 Chat Screen Position = 聊天屏幕位置 -Disconnected from AdhocServer = 与 Adhoc 服务器断开连接 -DNS Error Resolving = DNS 错误解析 -Enable built-in PRO Adhoc Server = 启用内置 PRO Ad Hoc 服务器 +Disconnected from AdhocServer = 与Adhoc服务器断开连接 +DNS Error Resolving = DNS错误解析 +Enable built-in PRO Adhoc Server = 启用内置PRO Ad Hoc服务器 Enable network chat = 启用聊天 Enable networking = 启用联网/无线网络 (测试) Enable UPnP = 启用UPnP(需要几秒钟来检测) EnableQuickChat = 启用快速聊天 Enter a new PSP nickname = 输入新的PSP昵称 -Enter Quick Chat 1 = 输入快速聊天 1 -Enter Quick Chat 2 = 输入快速聊天 2 -Enter Quick Chat 3 = 输入快速聊天 3 -Enter Quick Chat 4 = 输入快速聊天 4 -Enter Quick Chat 5 = 输入快速聊天 5 +Enter Quick Chat 1 = 输入快速聊天1 +Enter Quick Chat 2 = 输入快速聊天2 +Enter Quick Chat 3 = 输入快速聊天3 +Enter Quick Chat 4 = 输入快速聊天4 +Enter Quick Chat 5 = 输入快速聊天5 Error = 错误 -Failed to Bind Localhost IP = 无法绑定本地主机 IP +Failed to Bind Localhost IP = 无法绑定本地主机IP Failed to Bind Port = 无法绑定端口 -Failed to connect to Adhoc Server = 无法连接 Adhoc 服务器 +Failed to connect to Adhoc Server = 无法连接Adhoc服务器 Forced First Connect = 强制首次连接(更快的连接) -GM: Data from Unknown Port = GM: 来自未知端口的数据 +GM: Data from Unknown Port = GM:来自未知端口的数据 Hostname = 主机名 -Invalid IP or hostname = IP 或主机名是无效的 +Invalid IP or hostname = IP或主机名是无效的 Minimum Timeout = 最小超时(以毫秒为单位,0 = 默认值) Misc = 其他(默认 = PSP兼容性) Network Initialized = 网络已初始化 None = 无 Please change your Port Offset = 请更改您的端口偏移 -Port offset = 端口偏移 (0 = 兼容PSP) -Open PPSSPP Multiplayer Wiki Page = PPSSPP 多人百科页面 -proAdhocServer Address: = Ad Hoc 服务器地址: +Port offset = 端口偏移(0 = 兼容PSP) +Open PPSSPP Multiplayer Wiki Page = PPSSPP多人联机百科页面 +MultiplayerHowToURL = https://github.com/hrydgard/ppsspp/wiki/如何使用PPSSPP多人联机游戏 +proAdhocServer Address: = Ad Hoc服务器地址: Quick Chat 1 = 快速聊天 1 Quick Chat 2 = 快速聊天 2 Quick Chat 3 = 快速聊天 3 @@ -798,11 +799,11 @@ Quick Chat 4 = 快速聊天 4 Quick Chat 5 = 快速聊天 5 QuickChat = 快速聊天 Send = 发送 -Send Discord Presence information = 发送 Discord "在线状态" 信息 +Send Discord Presence information = 发送Discord"在线状态"信息 Top Center = 正上方 Top Left = 左上方 Top Right = 右上方 -Unable to find UPnP device = 找不到 UPnP 设备 +Unable to find UPnP device = 找不到UPnP设备 UPnP (port-forwarding) = UPnP(端口转发) UPnP need to be reinitialized = UPnP 需要重新初始化 UPnP use original port = UPnP 使用原始端口(启用 = 兼容 PSP) @@ -821,7 +822,7 @@ Load State = 载入即时存档 Rewind = 倒带 Save State = 保存即时存档 Settings = 设置 -Switch UMD = 切换 UMD 光盘 +Switch UMD = 切换UMD光盘 Undo last load = 撤销加载 Undo last save = 撤销保存 @@ -832,62 +833,62 @@ Undo last save = 撤销保存 5xBR-lv2 = 5xBR-lv2 AAColor = AA-Color Amount = 数量 -Animation speed (0 -> disable) = 动画速度 (0 -> 禁用) +Animation speed (0 -> disable) = 动画速度(0 -> 禁用) Black border = 黑色描边 -Bloom = Bloom (泛光) +Bloom = 泛光 Brightness = 亮度 -Cartoon = Cartoon (卡通) -ColorCorrection = Color correction (颜色修正) +Cartoon = 卡通 +ColorCorrection = 颜色修正 Contrast = 对比度 CRT = CRT 扫描线 FXAA = FXAA (快速近似抗锯齿) Gamma = 伽马值 -Grayscale = Grayscale (灰度图) +Grayscale = 灰度图 Intensity = 强度 -InverseColors = InverseColors (反色) -Natural = Natural (自然色) -NaturalA = NaturalA (自然色-无模糊) +InverseColors = 反色 +Natural = 自然色 +NaturalA = 自然色(无模糊) Off = 关闭 Power = 效果强度 -PSPColor = PSP 色彩 +PSPColor = PSP色彩 Saturation = 色彩 -Scanlines = 扫描线 (CRT) -Sharpen = Sharpen (锐化) -SSAA(Gauss) = SuperSamplingAA (超级采样抗锯齿:高斯) +Scanlines = 扫描线(CRT) +Sharpen = 锐化 +SSAA(Gauss) = 超级采样抗锯齿(高斯) Tex4xBRZ = 4xBRZ TexMMPX = MMPX -UpscaleSpline36 = Spline36 缩放 -VideoSmoothingAA = VideoSmoothingAA (视频平滑抗锯齿) -Vignette = Vignette (暗角) -MitchellNetravali = Mitchell-Netravali 双三插值缩放 -CatmullRom = Catmull-Rom 双三插值缩放 +UpscaleSpline36 = Spline36缩放 +VideoSmoothingAA = 视频平滑抗锯齿 +Vignette = 光晕 +MitchellNetravali = Mitchell-Netravali双三插值缩放 +CatmullRom = Catmull-Rom双三插值缩放 [PSPCredits] -all the forum mods = 所有的论坛管理员 +all the forum mods = 论坛上所有的mod build server = 编译服务器 Buy Gold = 购买黄金版 -check = 同时请查阅海豚模拟器, 最好用的 Wii/GC 模拟器 -CheckOutPPSSPP = 查阅 PPSSPP, 一款超级棒的 PSP 模拟器:https://www.ppsspp.org/ +check = 同时请查阅海豚模拟器, 最好用的Wii/GC模拟器 +CheckOutPPSSPP = 查阅PPSSPP, 一款超级棒的PSP 模拟器:https://www.ppsspp.org/ contributors = 参与者: created = 作者: Discord = Discord -info1 = PPSSPP 只用于教学研究, 不应被用于商业用途。 +info1 = PPSSPP只用于教学研究, 不应被用于商业用途。 info2 = 请确认您持有游戏镜像的正版拷贝: -info3 = 这可以是您购买了游戏的 UMD 光盘, -info4 = 或者通过 PSP 在 PSN 商店购买的数字版游戏。 -info5 = PSP™ 是索尼公司的注册商标。 -iOS builds = 负责 iOS 编译 -license = 遵循 GPL 2.0+ 许可协议的自由软件 +info3 = 这可以是您购买了游戏的UMD光盘, +info4 = 或者通过PSP在PSN商店购买的数字版游戏。 +info5 = PSP™是索尼公司的注册商标。 +iOS builds = 负责iOS编译 +license = 遵循GPL 2.0+许可协议的自由软件 list = 以了解兼容性列表、官方论坛以及开发动态 -PPSSPP Forums = PPSSPP 官方论坛 +PPSSPP Forums = PPSSPP官方论坛 Privacy Policy = 隐私政策 -Share PPSSPP = 分享 PPSSPP +Share PPSSPP = 分享PPSSPP specialthanks = 鸣谢: specialthanksKeithGalocy = 的硬件工作和指导, 他来自 NVIDIA -specialthanksMaxim = 的出色的 Atrac3 + 解码器工作 +specialthanksMaxim = 的出色的Atrac3+解码器工作 testing = 负责测试 this translation by = 界面汉化: -title = 效率高、移植性好的 PSP 模拟器 +title = 效率高、移植性好的PSP模拟器 tools = 使用的第三方开源库: # 在这里添加PPSSPP界面汉化人员的名单 # translators1-6这6行用于添加汉化人员名单 for up to 6 lines of translator credits. @@ -900,7 +901,7 @@ translators5 = translators6 = Twitter @PPSSPP_emu = Twitter website = 请查阅官方网站 -written = 使用 C++ 编写以保证速度与移植性 +written = 使用C++编写以保证速度与移植性 [RemoteISO] Browse Games = 浏览游戏 @@ -914,31 +915,31 @@ RemoteISODesc = 您最近列表中的游戏将被共享 RemoteISOLoading = 已连接, 正在载入游戏列表... RemoteISOScanning = 扫描中...在您的服务器设备上点击"共享游戏" RemoteISOScanningTimeout = 扫描中...请检查您防火墙的设置 -RemoteISOWifi = 说明: 请将设备连接到同一 Wi-Fi 网络下 -RemoteISOWinFirewall = 警告: Windows 防火墙正在阻挡游戏共享 +RemoteISOWifi = 说明: 请将设备连接到同一Wi-Fi网络下 +RemoteISOWinFirewall = 警告: Windows防火墙正在阻挡游戏共享 Settings = 设置 -Share Games (Server) = 共享游戏 (服务器) -Share on PPSSPP startup = PPSSPP 启动时共享 +Share Games (Server) = 共享游戏(服务器) +Share on PPSSPP startup = PPSSPP启动时共享 Stop Sharing = 停止共享 Stopping.. = 正在停止... [Reporting] Bad = 很差 FeedbackCRCCalculating = 光盘 CRC: 计算中... -FeedbackCRCValue = 光盘 CRC: %1 +FeedbackCRCValue = 光盘CRC: %1 FeedbackDelayInfo = 您的数据正在后台提交。 FeedbackDesc = 模拟兼容性怎样?请告诉我们和社区! FeedbackDisabled = 必须启用"向服务器报告兼容性问题"选项 -FeedbackIncludeCRC = 注意:将使用部分电量发送 CRC 校验 +FeedbackIncludeCRC = 注意:将使用部分电量发送CRC校验 FeedbackIncludeScreen = 包含一张截图 FeedbackSubmitDone = 您的数据已提交。 -FeedbackSubmitFail = 无法向服务器提交数据。尝试更新 PPSSPP。 +FeedbackSubmitFail = 无法向服务器提交数据。尝试更新PPSSPP。 FeedbackThanks = 感谢您的反馈! Gameplay = 游戏过程 Graphics = 图像 Great = 很好 In-game = 在游戏中 -In-game Description = 可以进入游戏, 但是 bug 太多无法完成游戏 +In-game Description = 可以进入游戏, 但是bug太多无法完成游戏 Menu/Intro = 菜单/开头 Menu/Intro Description = 无法进入游戏 Nothing = 没画面 @@ -951,17 +952,17 @@ Perfect Description = 完美模拟整个游戏 - 太棒了! Plays = 可玩 Plays Description = 基本模拟整个游戏, 但有时会出现故障 ReportButton = 报告反馈 -Show disc CRC = 显示光盘 CRC +Show disc CRC = 显示光盘CRC Speed = 速度 Submit Feedback = 提交反馈 SuggestionConfig = 请参阅网站上的报告以了解最佳设置。 -SuggestionCPUSpeed0 = 请禁用锁定 CPU 速度设置。 -SuggestionDowngrade = 请降级到较旧的 PPSSPP 版本 (请报告这个错误)。 +SuggestionCPUSpeed0 = 请禁用锁定CPU速度设置。 +SuggestionDowngrade = 请降级到较旧的PPSSPP版本 (请报告这个错误)。 SuggestionsFound = 其他用户报告了更佳的结果。点击"查看所有反馈"了解更多详情。 SuggestionsNone = 其他用户也不能运行该游戏。 SuggestionsWaiting = 提交中, 并检查其他用户的反馈... -SuggestionUpgrade = 请更新到较新版本的 PPSSPP -SuggestionVerifyDisc = 请检查您的 ISO 是否为光盘的正确拷贝。 +SuggestionUpgrade = 请更新到较新版本的PPSSPP +SuggestionVerifyDisc = 请检查您的ISO是否为光盘的正确拷贝。 Unselected Overall Description = 这款游戏模拟的怎样? View Feedback = 查看所有反馈 @@ -978,12 +979,12 @@ Showing matches for '%1'. = 找到符合'%1'的搜索结果。 Size = 大小 [Screen] -Cardboard VR OFF = Cardboard VR 关闭 -Chainfire3DWarning = 警告:检测到 Chainfire3D (3D 神器), 可能会导致问题。 +Cardboard VR OFF = Cardboard VR关闭 +Chainfire3DWarning = 警告:检测到Chainfire3D(3D 神器), 可能会导致问题。 Failed to load state = 无法载入即时存档 Failed to save state = 无法保存即时存档 fixed = 速度:自定义 -GLToolsWarning = 警告:检测到 GLTools, 可能会导致问题。 +GLToolsWarning = 警告:检测到GLTools, 可能会导致问题。 In menu = 在菜单中 Load savestate failed = 无法载入即时存档 Loaded State = 已载入即时存档 @@ -991,17 +992,17 @@ Loaded. Game may refuse to save over different savedata. = 已载入。游戏可 Loaded. Game may refuse to save over newer savedata. = 已载入。游戏可能无法保存在进度提前的存档。 Loaded. Save in game, restart, and load for less bugs. = 已载入。请在游戏中存档, 重开, 再次读档以减少 bug。 LoadStateDoesntExist = 即时存档载入失败:存档不存在 -LoadStateWrongVersion = 即时存档载入失败:存档是旧版本 PPSSPP 的 +LoadStateWrongVersion = 即时存档载入失败:存档是旧版本PPSSPP的 norewind = 没有可用的倒带自动即时存档。 Playing = 游戏中 -PressESC = 按下 ESC 键打开暂停菜单。 +PressESC = 按下ESC键打开暂停菜单。 replaceTextures_false = 纹理替换已关闭。 replaceTextures_true = 纹理替换已启用。 Save State Failed = 无法保存即时存档 Saved State = 已保存即时存档 saveNewTextures_false = 纹理转储已停止。 saveNewTextures_true = 开始转储新纹理。 -SpeedCustom2 = 速度:自定义 2 +SpeedCustom2 = 速度:自定义2 standard = 速度:标准 State load undone = 撤销即时存档载入 Untitled PSP game = 无标题的 PSP 游戏 @@ -1022,7 +1023,7 @@ Uninstall = 卸载 (none detected) = (未检测到) 3D API = 3D API ABI = ABI -API Version = API 版本 +API Version = API版本 Audio Information = 音频信息 Board = 主板 Build Config = 编译配置 @@ -1030,10 +1031,10 @@ Build Configuration = 编译配置 Built by = 编译者 Core Context = 核心上下文 Cores = 核心数 -CPU Extensions = CPU 扩展 -CPU Information = CPU 信息 +CPU Extensions = CPU扩展 +CPU Information = CPU信息 CPU Name = CPU 名称 -D3DCompiler Version = D3DCompiler 版本 +D3DCompiler Version = D3DCompiler版本 Debug = 调试 Debugger Present = 调试器已连接 Device Info = 设备信息 @@ -1041,25 +1042,25 @@ Directories = 路径 Display Color Formats = 显示颜色格式 Display Information = 显示信息 Driver Version = 驱动程序版本 -EGL Extensions = EGL 扩展 +EGL Extensions = EGL扩展 Frames per buffer = 每缓冲区帧数 -GPU Information = GPU 信息 +GPU Information = GPU信息 High precision float range = 高精度浮点范围 High precision int range = 高精度整数范围 Lang/Region = 语言/区域 Memory Page Size = 内存页大小 Native Resolution = 原生分辨率 OGL Extensions = OGL 扩展 -OpenGL ES 2.0 Extensions = OpenGL ES 2.0 扩展 -OpenGL ES 3.0 Extensions = OpenGL ES 3.0 扩展 -OpenGL Extensions = OpenGL 扩展 +OpenGL ES 2.0 Extensions = OpenGL ES 2.0扩展 +OpenGL ES 3.0 Extensions = OpenGL ES 3.0扩展 +OpenGL Extensions = OpenGL扩展 Optimal frames per buffer = 最佳每缓冲区帧数 Optimal sample rate = 最佳采样率 -OS Information = OS 信息 -PPSSPP build = PPSSPP 编译版本 +OS Information = OS信息 +PPSSPP build = PPSSPP编译版本 Refresh rate = 刷新率 Release = 发布 -RW/RX exclusive = RW/RX 独占 +RW/RX exclusive = RW/RX独占 Sample rate = 采样率 Shading Language = 着色语言 Storage = 存储 @@ -1069,23 +1070,23 @@ System Name = 系统名称 System Version = 系统版本 Threads = 线程数 Vendor = 供应商 -Vendor (detected) = 供应商 (检测到的) +Vendor (detected) = 供应商(检测到的) Version Information = 版本信息 -Vulkan Extensions = Vulkan 扩展 -Vulkan Features = Vulkan 特性 +Vulkan Extensions = Vulkan扩展 +Vulkan Features = Vulkan特性 Driver bugs = 驱动错误 -No GPU driver bugs detected = 未检测到 GPU 驱动错误 +No GPU driver bugs detected = 未检测到GPU驱动错误 [System] (broken) = (损坏) -12HR = 12 小时制 -24HR = 24 小时制 +12HR = 12小时制 +24HR = 24小时制 Auto = 自动 Auto Load Savestate = 自动载入即时存档 -AVI Dump started. = AVI 转储开始 -AVI Dump stopped. = AVI 转储停止 -Cache ISO in RAM = 在内存中缓存完整 ISO -Change CPU Clock = 修改模拟的 PSP 的 CPU 频率 (不稳定) +AVI Dump started. = AVI转储开始 +AVI Dump stopped. = AVI转储停止 +Cache ISO in RAM = 在内存中缓存完整ISO +Change CPU Clock = 修改模拟的PSP的CPU频率(不稳定) Color Tint = 颜色色调 Color Saturation = 颜色饱和度 Error: load undo state is from a different game = 错误: 撤回的即时存档是来自不同游戏的 @@ -1110,62 +1111,62 @@ Display Extra Info = 显示附加信息 Display Games on a grid = 以方格显示"游戏" Display Homebrew on a grid = 以方格显示"自制与试玩" Display Recent on a grid = 以方格显示"最近的游戏" -Dynarec (JIT) = 动态重编译 (JIT) +Dynarec (JIT) = 动态重编译(JIT) Emulation = 模拟设置 Enable Cheats = 开启金手指 Enable Compatibility Server Reports = 向服务器报告兼容性问题 Failed to load state. Error in the file system. = 无法载入即时存档。文件系统出错。 Failed to save state. Error in the file system. = 无法保存即时存档。文件系统出错。 -Fast (lag on slow storage) = 快速 (在低速存储会有延迟) -Fast Memory = 快速内存 (不稳定) -Force real clock sync (slower, less lag) = 强制同步实际时钟频率 (慢,但是更少延迟) +Fast (lag on slow storage) = 快速(在低速存储会有延迟) +Fast Memory = 快速内存(不稳定) +Force real clock sync (slower, less lag) = 强制同步实际时钟频率(慢,但是更少延迟) frames, 0:off = 每几帧, 0 = 关 Games list settings = 游戏列表设置 General = 常规设置 Grid icon size = 按倍率的图标尺寸 Help the PPSSPP team = 帮助 PPSSPP 团队 -Host (bugs, less lag) = 主机 (较少延迟, 有错误) +Host (bugs, less lag) = 主机(较少延迟, 有错误) Ignore bad memory accesses = 忽略错误的内存访问 Increase size = 增大尺寸 Interpreter = 解释器 -IO timing method = I/O 计时方法 +IO timing method = I/O计时方法 IR Interpreter = IR 解释器 Memory Stick Folder = 记忆棒文件夹 Memory Stick inserted = 记忆棒已插入 -MHz, 0:default = MHz, 默认为 0 +MHz, 0:default = MHz, 默认为0 MMDDYYYY = 月/日/年 Moving background = 动态壁纸 Newest Save = 最新的即时存档 No animation = 静态壁纸 -Not a PSP game = 这不是一个 PSP 游戏 +Not a PSP game = 这不是一个PSP游戏 Off = 关闭 Oldest Save = 最旧的即时存档 Path does not exist! = 路径不存在! -PSP Memory Stick = PSP 记忆棒 -PSP Model = PSP 机型 -PSP Settings = PSP 设置 +PSP Memory Stick = PSP记忆棒 +PSP Model = PSP机型 +PSP Settings = PSP设置 PSP-1000 = PSP-1000 PSP-2000/3000 = PSP-2000/3000 Recent games = 最近的游戏 Record Audio = 录制音频 Record Display = 录制视频 Reset Recording on Save/Load State = 保存/载入存档时重置录制 -Restore Default Settings = 恢复默认 PPSSPP 设置 +Restore Default Settings = 恢复默认PPSSPP设置 Rewind Snapshot Frequency = 倒带自动即时存档频率 -Save path in installed.txt = 存档路径在 installed.txt +Save path in installed.txt = 存档路径在installed.txt Save path in My Documents = 存档路径在我的文档 Savestate Slot = 即时存档插槽 Savestate slot backups = 即时存档插槽备份 -Screenshots as PNG = 将截图保存为 PNG 格式 +Screenshots as PNG = 将截图保存为PNG格式 Set UI background... = 设置界面背景... Show ID = 显示游戏 ID Show region flag = 显示游戏区域标识 -Simulate UMD delays = 模拟 UMD 延迟 -Slot 1 = 插槽 1 -Slot 2 = 插槽 2 -Slot 3 = 插槽 3 -Slot 4 = 插槽 4 -Slot 5 = 插槽 5 +Simulate UMD delays = 模拟UMD延迟 +Slot 1 = 插槽1 +Slot 2 = 插槽2 +Slot 3 = 插槽3 +Slot 4 = 插槽4 +Slot 5 = 插槽5 Storage full = 存储空间已满 Sustained performance mode = 持久性能模式 (使长时间运行的应用运行更流畅) Time Format = 时间格式 @@ -1174,11 +1175,11 @@ UI background animation = 界面背景效果 UI Sound = 界面声音 undo %c = 备份 %c USB = USB -Use Lossless Video Codec (FFV1) = 使用无损视频编解码器 (FFV1) -Use O to confirm = 使用按钮 O 确认 +Use Lossless Video Codec (FFV1) = 使用无损视频编解码器(FFV1) +Use O to confirm = 使用按钮O确认 Use output buffer (with overlay) for recording = 录制时使用输出缓冲 (包括叠加信息) Use system native keyboard = 使用系统本机键盘 -Use X to confirm = 使用按钮 X 确认 +Use X to confirm = 使用按钮X确认 VersionCheck = 检查 PPSSPP 新版本 WARNING: Android battery save mode is on = 警告:安卓省电模式已开启 WARNING: Battery save mode is on = 警告:省电模式已开启 @@ -1212,7 +1213,7 @@ Screen representation = 屏幕表现 Details = 详细内容 Dismiss = 忽略 Download = 下载 -New version of PPSSPP available = 新版本 PPSSPP 可用 +New version of PPSSPP available = 新版本PPSSPP可用 [Search] Filtering settings by '%1' = 设置筛选'%1' From 4b959c6b54c796c2f273f6b1ece87584f2baf2b2 Mon Sep 17 00:00:00 2001 From: LunaMoo Date: Thu, 14 Jul 2022 23:17:32 +0200 Subject: [PATCH 11/57] Add Zettai Zetsumei Toshi 3 bypass for softlock on character select screen --- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + Core/HLE/ReplaceTables.cpp | 10 ++++++++++ Core/MIPS/MIPSAnalyst.cpp | 3 ++- assets/compat.ini | 11 +++++++++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 1835efb753..813e324970 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -94,6 +94,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "BlueToAlpha", &flags_.BlueToAlpha); CheckSetting(iniFile, gameID, "CenteredLines", &flags_.CenteredLines); CheckSetting(iniFile, gameID, "MaliDepthStencilBugWorkaround", &flags_.MaliDepthStencilBugWorkaround); + CheckSetting(iniFile, gameID, "ZZT3SelectHack", &flags_.ZZT3SelectHack); } void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 2cd9cf042b..da9a1f79c0 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -84,6 +84,7 @@ struct CompatFlags { bool BlueToAlpha; bool CenteredLines; bool MaliDepthStencilBugWorkaround; + bool ZZT3SelectHack; }; class IniFile; diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 915ab466f9..fda0c07b07 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1361,6 +1361,15 @@ static int Hook_gow_vortex_hack() { return 0; } +static int Hook_ZZT3_select_hack() { + if (PSP_CoreParameter().compat.flags().ZZT3SelectHack) { + if (currentMIPS->r[MIPS_REG_V0] == 0) { + currentMIPS->r[MIPS_REG_V0] = 1; + } + } + return 0; +} + #define JITFUNC(f) (&MIPSComp::MIPSFrontendInterface::f) // Can either replace with C functions or functions emitted in Asm/ArmAsm. @@ -1479,6 +1488,7 @@ static const ReplacementTableEntry entries[] = { { "soltrigger_render_ucschar", &Hook_soltrigger_render_ucschar, 0, REPFLAG_HOOKENTER, 0 }, { "gow_fps_hack", &Hook_gow_fps_hack, 0, REPFLAG_HOOKEXIT , 0 }, { "gow_vortex_hack", &Hook_gow_vortex_hack, 0, REPFLAG_HOOKENTER, 0x60 }, + { "ZZT3_select_hack", &Hook_ZZT3_select_hack, 0, REPFLAG_HOOKENTER, 0xC4 }, {} }; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 63599a758c..f88dde62bf 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -508,7 +508,8 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xffc8f5f8f946152c, 192, "dl_write_light_color", }, { 0x249a3c5981c73480, 1472, "openseason_data_decode", }, // Open Season { 0x795d940ad0a605f8, 40, "gow_fps_hack", }, // God of War (all) - { 0x4c75043b7b0c643b, 512, "gow_vortex_hack", } // God of War: Ghost of Sparta vortex timer hack, avoids softlock #8299 + { 0x4c75043b7b0c643b, 512, "gow_vortex_hack", }, // God of War: Ghost of Sparta vortex timer hack, avoids softlock #8299 + { 0x7624dde603717640, 288, "ZZT3_select_hack", }, // Zettai Zetsumei Toshi 3 - bypasses softlock on character select screen #4901 }; namespace MIPSAnalyst { diff --git a/assets/compat.ini b/assets/compat.ini index a17091de43..8485ca6391 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1228,3 +1228,14 @@ UCES01011 = true UCAS40197 = true NPEG00006 = true NPUG80135 = true + +[ZZT3SelectHack] +# Bypass softlock on Zettai Zetsumei Toshi 3 character select screen #4901 +# This problem affects the game also on PS3 +ULJS00191 = true +UCAS40252 = true +UCKS45119 = true +NPJH50907 = true +UCAS40328 = true +ULJS19050 = true +NPJH50907 = true From c5916ba2903d917c9757ec8ddaf9aaf72993ed3c Mon Sep 17 00:00:00 2001 From: leoxxx <5364709+leoxxx@users.noreply.github.com> Date: Fri, 15 Jul 2022 12:50:48 +0800 Subject: [PATCH 12/57] Update zh_CN.ini Delete some spaces and change some translations. --- assets/lang/zh_CN.ini | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index bc028b6b0d..4eb6ee83a7 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -387,12 +387,12 @@ Not a valid disc image. = 光盘镜像无效。 OpenGLDriverError = OpenGL 驱动程序错误 PPSSPP doesn't support UMD Music. = PPSSPP不支持UMD音乐。 PPSSPP doesn't support UMD Video. = PPSSPP不支持UMD视频。 -PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP运行 PSP游戏, PS1或者2的游戏不能运行。 +PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP只能运行PSP游戏, 不能运行PS1或2的游戏。 PPSSPPDoesNotSupportInternet = PPSSPP目前不支持连接互联网以获取 DLC、PSN或游戏的更新。 -PS1 EBOOTs are not supported by PPSSPP. = PPSSPP不支持由PS1 EBOOT 生成的游戏镜像。 +PS1 EBOOTs are not supported by PPSSPP. = PPSSPP不支持由PS1 EBOOT生成的游戏镜像。 PSX game image detected. = 这是MODE2镜像。PPSSPP不支持PS1游戏。 -RAR file detected (Require UnRAR) = 这是RAR压缩文件。\n请尝试使用 UnRAR进行解压缩。 -RAR file detected (Require WINRAR) = 这是RAR压缩文件。\n请尝试使用 WinRAR进行解压缩。 +RAR file detected (Require UnRAR) = 这是RAR压缩文件。\n请尝试使用UnRAR进行解压缩。 +RAR file detected (Require WINRAR) = 这是RAR压缩文件。\n请尝试使用WinRAR进行解压缩。 Running slow: try frameskip, sound is choppy when slow = 运行速度慢:尝试跳帧, 运行速度慢时声音不连贯 Running slow: Try turning off Software Rendering = 运行速度慢:尝试关闭"软件渲染" Save encryption failed. This save won't work on real PSP = 存档加密失败。此存档将无法在PSP实机使用 @@ -518,7 +518,7 @@ Linear = 线性过滤 Low = 低 LowCurves = 低品质样条函数/贝塞尔曲线(提速) LowCurves Tip = 仅对部分游戏有效, 控制曲线的平滑度 -Lower resolution for effects (reduces artifacts) = 降低特效分辨率(减少伪像) +Lower resolution for effects (reduces artifacts) = 降低特效分辨率(减少失真) Manual Scaling = 手动缩放 Medium = 中 Mode = 渲染模式 @@ -783,13 +783,13 @@ Forced First Connect = 强制首次连接(更快的连接) GM: Data from Unknown Port = GM:来自未知端口的数据 Hostname = 主机名 Invalid IP or hostname = IP或主机名是无效的 -Minimum Timeout = 最小超时(以毫秒为单位,0 = 默认值) +Minimum Timeout = 最小超时(以毫秒为单位,0=默认值) Misc = 其他(默认 = PSP兼容性) Network Initialized = 网络已初始化 None = 无 Please change your Port Offset = 请更改您的端口偏移 Port offset = 端口偏移(0 = 兼容PSP) -Open PPSSPP Multiplayer Wiki Page = PPSSPP多人联机百科页面 +Open PPSSPP Multiplayer Wiki Page = 打开PPSSPP多人联机百科页面 MultiplayerHowToURL = https://github.com/hrydgard/ppsspp/wiki/如何使用PPSSPP多人联机游戏 proAdhocServer Address: = Ad Hoc服务器地址: Quick Chat 1 = 快速聊天 1 @@ -806,7 +806,7 @@ Top Right = 右上方 Unable to find UPnP device = 找不到UPnP设备 UPnP (port-forwarding) = UPnP(端口转发) UPnP need to be reinitialized = UPnP 需要重新初始化 -UPnP use original port = UPnP 使用原始端口(启用 = 兼容 PSP) +UPnP use original port = UPnP 使用原始端口(启用=兼容PSP) Validating address... = 正在验证地址... WLAN Channel = WLAN 频道 You're in Offline Mode, go to lobby or online hall = 您现在是离线模式, 请进入房间或在线大厅 @@ -833,7 +833,7 @@ Undo last save = 撤销保存 5xBR-lv2 = 5xBR-lv2 AAColor = AA-Color Amount = 数量 -Animation speed (0 -> disable) = 动画速度(0 -> 禁用) +Animation speed (0 -> disable) = 动画速度(0->禁用) Black border = 黑色描边 Bloom = 泛光 Brightness = 亮度 @@ -884,7 +884,7 @@ PPSSPP Forums = PPSSPP官方论坛 Privacy Policy = 隐私政策 Share PPSSPP = 分享PPSSPP specialthanks = 鸣谢: -specialthanksKeithGalocy = 的硬件工作和指导, 他来自 NVIDIA +specialthanksKeithGalocy = 的硬件工作和指导, 他来自NVIDIA specialthanksMaxim = 的出色的Atrac3+解码器工作 testing = 负责测试 this translation by = 界面汉化: @@ -1159,7 +1159,7 @@ Savestate Slot = 即时存档插槽 Savestate slot backups = 即时存档插槽备份 Screenshots as PNG = 将截图保存为PNG格式 Set UI background... = 设置界面背景... -Show ID = 显示游戏 ID +Show ID = 显示游戏ID Show region flag = 显示游戏区域标识 Simulate UMD delays = 模拟UMD延迟 Slot 1 = 插槽1 From df08bc221fc08926b5f18513dcc6afe5cce53220 Mon Sep 17 00:00:00 2001 From: leoxxx <5364709+leoxxx@users.noreply.github.com> Date: Fri, 15 Jul 2022 17:21:03 +0800 Subject: [PATCH 13/57] Update zh_CN.ini --- assets/lang/zh_CN.ini | 74 +++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index 4eb6ee83a7..d2c0ca600e 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -62,8 +62,8 @@ Icon = 图标 Ignore gamepads when not focused = 后台运行时忽略游戏手柄 Ignore Windows Key = 忽略 Windows 键 Invert Axes = 轴反转 -Invert Tilt along X axis = 沿 X 轴倾斜反转 -Invert Tilt along Y axis = 沿 Y 轴倾斜反转 +Invert Tilt along X axis = 沿X轴倾斜反转 +Invert Tilt along Y axis = 沿Y轴倾斜反转 Keep this button pressed when right analog is pressed = 按下右摇杆时保持按下此按钮 Keyboard = 键盘控制设定 L/R Trigger Buttons = L/R扳机按钮 @@ -74,7 +74,7 @@ Low end radius = 末端半径 Mouse = 鼠标设置 Mouse sensitivity = 鼠标灵敏度 Mouse smoothing = 鼠标平滑度 -MouseControl Tip = 您可以在按键映射界面按下 "M" 图标来映射鼠标按键。 +MouseControl Tip = 您可以在按键映射界面按下"M"图标来映射鼠标按键。 None (Disabled) = 无(禁用) Off = 关闭 OnScreen = 屏幕虚拟按键 @@ -125,7 +125,7 @@ Auto Max Quality = 自动最佳质量 (&Q) Font = 微软雅黑 About PPSSPP... = 关于PPSSPP (&A)... Auto = 自动 (&A) -Backend = 渲染引擎(需要 PPSSPP 重新启动) (&b) +Backend = 渲染引擎(需要PPSSPP重新启动) (&b) Bicubic = 双三次 (&B) Break = 停止 Break on Load = 载入后停止 @@ -186,7 +186,7 @@ Pause When Not Focused = 后台运行时自动暂停 (&P) Portrait = 纵向 Portrait reversed = 纵向反转 Postprocessing Shader = 后处理着色器 (&g) -PPSSPP Forums = PPSSPP 官方论坛 (&F) +PPSSPP Forums = PPSSPP官方论坛 (&F) Record = 录制 (&R) Record Audio = 录制音频 (&A) Record Display = 录制视频 (&D) @@ -342,7 +342,7 @@ SSID = SSID Submit = 提交 Supported = 支持 There is no data = 存档不存在。 -Toggle All = 全选 (全不选) +Toggle All = 全选(全不选) Toggle List = 切换列表 Unsupported = 不支持 When you save, it will load on a PSP, but not an older PPSSPP = 当您保存后, 它只会在PSP实机上载入, 而不是旧版本的PPSSPP @@ -353,9 +353,9 @@ Zoom = 放大 [Error] 7z file detected (Require 7-Zip) = 这是7ZIP压缩文件。\n请试着使用 7-zip或WinRAR进行解压缩。 A PSP game couldn't be found on the disc. = 光盘中找不到PSP游戏。 -Cannot boot ELF located outside mountRoot. = 无法启动位于 mountRoot 之外的ELF文件。 +Cannot boot ELF located outside mountRoot. = 无法启动位于mountRoot之外的ELF文件。 Could not save screenshot file = 无法保存屏幕截图文件 -D3D9or11 = 使用Direct3D 9? (或者 "否" 以使用Direct3D 11) +D3D9or11 = 使用Direct3D 9? (或"否"以使用Direct3D 11) D3D11CompilerMissing = 没有找到D3DCompiler_47.dll, 请安装它或者按下"确认"键来尝试使用Direct3D 9代替它。 D3D11InitializationError = Direct3D 11初始化出错 D3D11Missing = 您的操作系统没有包含D3D11。请运行Windows Update。\n\n按下"确认"键来尝试使用Direct3D 9代替它。 @@ -370,11 +370,11 @@ File corrupt = 文件损坏 Game disc read error - ISO corrupt = 游戏光盘读取错误:ISO损坏。 GenericAllStartupError = PPSSPP无法使用任何图形后端启动。 尝试升级图形和其他驱动程序. GenericBackendSwitchCrash = 启动时PPSSPP崩溃了.\n\n这通常意味着图形驱动程序问题。 尝试升级图形驱动程序.\n\n图形后端已切换: -GenericDirect3D9Error = 初始化图像失败。尝试更新您的显卡驱动程序和DirectX 9 运行库。\n\n是否尝试切换到OpenGL模式?\n\n错误信息: +GenericDirect3D9Error = 初始化图像失败。尝试更新您的显卡驱动程序和DirectX 9运行库。\n\n是否尝试切换到OpenGL模式?\n\n错误信息: GenericGraphicsError = 图像错误 -GenericOpenGLError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到 DirectX 9 模式?\n\n错误信息: -GenericVulkanError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到 OpenGL 模式?\n\n错误信息: -InsufficientOpenGLDriver = 检测到显卡驱动不支持 OpenGL 2.0!\n\n您想尝试使用 DirectX 吗?\n\nDirectX 目前只兼容较少游戏, 但在您的 GPU 也可能是唯一的选择。\n\n有关更多信息,请访问https://forums.ppsspp.org上的论坛。\n\n +GenericOpenGLError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到DirectX 9模式?\n\n错误信息: +GenericVulkanError = 初始化图像失败。尝试更新您的显卡驱动程序。\n\n是否尝试切换到OpenGL模式?\n\n错误信息: +InsufficientOpenGLDriver = 检测到显卡驱动不支持OpenGL 2.0!\n\n您想尝试使用DirectX吗?\n\nDirectX目前只兼容较少游戏, 但在您的GPU也可能是唯一的选择。\n\n有关更多信息,请访问论坛https://forums.ppsspp.org。\n\n Just a directory. = 这只是个文件夹。 Missing key = 缺失密钥 MsgErrorCode = 错误代码: @@ -388,7 +388,7 @@ OpenGLDriverError = OpenGL 驱动程序错误 PPSSPP doesn't support UMD Music. = PPSSPP不支持UMD音乐。 PPSSPP doesn't support UMD Video. = PPSSPP不支持UMD视频。 PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP只能运行PSP游戏, 不能运行PS1或2的游戏。 -PPSSPPDoesNotSupportInternet = PPSSPP目前不支持连接互联网以获取 DLC、PSN或游戏的更新。 +PPSSPPDoesNotSupportInternet = PPSSPP目前不支持连接互联网以获取DLC、PSN或游戏的更新。 PS1 EBOOTs are not supported by PPSSPP. = PPSSPP不支持由PS1 EBOOT生成的游戏镜像。 PSX game image detected. = 这是MODE2镜像。PPSSPP不支持PS1游戏。 RAR file detected (Require UnRAR) = 这是RAR压缩文件。\n请尝试使用UnRAR进行解压缩。 @@ -397,15 +397,15 @@ Running slow: try frameskip, sound is choppy when slow = 运行速度慢:尝 Running slow: Try turning off Software Rendering = 运行速度慢:尝试关闭"软件渲染" Save encryption failed. This save won't work on real PSP = 存档加密失败。此存档将无法在PSP实机使用 textures.ini filenames may not be cross-platform = "textures.ini"文件名可能不是多平台的。 -This is a saved state, not a game. = 这是一个即时存档, 不是游戏。 -This is save data, not a game. = 这是一个存档, 不是游戏。 -Unable to create cheat file, disk may be full = 无法创建金手指文件, 磁盘可能已满 +This is a saved state, not a game. = 这是一个即时存档,不是游戏。 +This is save data, not a game. = 这是一个存档,不是游戏。 +Unable to create cheat file, disk may be full = 无法创建金手指文件,磁盘可能已满 Unable to initialize rendering engine. = 无法初始化渲染引擎。 Unable to write savedata, disk may be full = 无法写入存档数据, 磁盘可能已满 Warning: Video memory FULL, reducing upscaling and switching to slow caching mode = 警告:显存已满, 减少分辨率提升并切换到慢速缓存模式。 Warning: Video memory FULL, switching to slow caching mode = 警告:显存已满, 切换到慢速缓存模式。 -ZIP file detected (Require UnRAR) = 这是ZIP压缩文件。\n请尝试使用 UnRAR进行解压缩。 -ZIP file detected (Require WINRAR) = 这是 ZIP 压缩文件。\n请尝试使用WinRAR进行解压缩。 +ZIP file detected (Require UnRAR) = 这是ZIP压缩文件。\n请尝试使用UnRAR进行解压缩。 +ZIP file detected (Require WINRAR) = 这是ZIP压缩文件。\n请尝试使用WinRAR进行解压缩。 [Game] Asia = 亚洲 @@ -446,7 +446,7 @@ Use UI background = 使用界面背景 3x = 3倍 3x PSP = 3倍PSP 4x = 4倍 -4x PSP = 4倍 PSP +4x PSP = 4倍PSP 5x = 5倍 5x PSP = 5倍PSP 6x PSP = 6倍PSP @@ -484,7 +484,7 @@ Cardboard VR Settings = Google Cardboard VR 设置 Cheats = 金手指 CPU Core = CPU 核心模式 Debugging = 调试设置 -DefaultCPUClockRequired = 警告:此游戏需要将 CPU 频率设置为默认。 +DefaultCPUClockRequired = 警告:此游戏需要将CPU频率设置为默认。 Deposterize = 色调融合 Deposterize Tip = 修复纹理被放大时可见的带状错误 Device = 设备 @@ -550,7 +550,7 @@ Safe = 安全 Screen layout = 屏幕布局 Screen Scaling Filter = 屏幕缩放滤镜 Show Debug Statistics = 显示调试信息 -Show FPS Counter = 显示 FPS 计数器 +Show FPS Counter = 显示FPS计数器 Simulate Block Transfer = 模拟数据块传输效果 Software Rendering = 软件渲染(慢) Software Skinning = 软件蒙皮 @@ -567,7 +567,7 @@ Up to 1 = 最高为1 Up to 2 = 最高为2 Upscale Level = 纹理缩放级别 Upscale Type = 纹理缩放方式 -UpscaleLevel Tip = CPU重负载 - 为避免卡顿, 某些缩放可能会延迟 +UpscaleLevel Tip = CPU重负载-为避免卡顿, 某些缩放可能会延迟 Use all displays = 使用全部显示器 Vertex Cache = 顶点缓存 VertexCache Tip = 更快, 但可能会造成暂时的闪烁 @@ -617,7 +617,7 @@ Loading... = 载入中... PinPath = 固定 PPSSPP can't load games or save right now = PPSSPP现在不能载入游戏或存档 Recent = 最近的游戏 -SavesAreTemporary = PPSSPP 正在临时空间内存档 +SavesAreTemporary = PPSSPP正在临时空间内存档 SavesAreTemporaryGuidance = 请将PPSSPP解压出来以使存档永久保留 SavesAreTemporaryIgnore = 忽略警告 UnpinPath = 取消固定 @@ -756,7 +756,7 @@ Bottom Right = 右下方 Center Left = 左中间 Center Right = 右中间 Change Mac Address = 更改MAC地址 -Change proAdhocServer Address = 更改PRO Ad Hoc服务器IP地址 (localhost = 模拟器双开) +Change proAdhocServer Address = 更改PRO Ad Hoc服务器IP地址(localhost=模拟器双开) Chat = 聊天 Chat Button Position = 聊天按钮位置 Chat Here = 在这里聊天 @@ -784,7 +784,7 @@ GM: Data from Unknown Port = GM:来自未知端口的数据 Hostname = 主机名 Invalid IP or hostname = IP或主机名是无效的 Minimum Timeout = 最小超时(以毫秒为单位,0=默认值) -Misc = 其他(默认 = PSP兼容性) +Misc = 其他(默认=PSP兼容性) Network Initialized = 网络已初始化 None = 无 Please change your Port Offset = 请更改您的端口偏移 @@ -792,11 +792,11 @@ Port offset = 端口偏移(0 = 兼容PSP) Open PPSSPP Multiplayer Wiki Page = 打开PPSSPP多人联机百科页面 MultiplayerHowToURL = https://github.com/hrydgard/ppsspp/wiki/如何使用PPSSPP多人联机游戏 proAdhocServer Address: = Ad Hoc服务器地址: -Quick Chat 1 = 快速聊天 1 -Quick Chat 2 = 快速聊天 2 -Quick Chat 3 = 快速聊天 3 -Quick Chat 4 = 快速聊天 4 -Quick Chat 5 = 快速聊天 5 +Quick Chat 1 = 快速聊天1 +Quick Chat 2 = 快速聊天2 +Quick Chat 3 = 快速聊天3 +Quick Chat 4 = 快速聊天4 +Quick Chat 5 = 快速聊天5 QuickChat = 快速聊天 Send = 发送 Send Discord Presence information = 发送Discord"在线状态"信息 @@ -925,7 +925,7 @@ Stopping.. = 正在停止... [Reporting] Bad = 很差 -FeedbackCRCCalculating = 光盘 CRC: 计算中... +FeedbackCRCCalculating = 光盘CRC: 计算中... FeedbackCRCValue = 光盘CRC: %1 FeedbackDelayInfo = 您的数据正在后台提交。 FeedbackDesc = 模拟兼容性怎样?请告诉我们和社区! @@ -990,7 +990,7 @@ Load savestate failed = 无法载入即时存档 Loaded State = 已载入即时存档 Loaded. Game may refuse to save over different savedata. = 已载入。游戏可能无法保存在别的存档中。 Loaded. Game may refuse to save over newer savedata. = 已载入。游戏可能无法保存在进度提前的存档。 -Loaded. Save in game, restart, and load for less bugs. = 已载入。请在游戏中存档, 重开, 再次读档以减少 bug。 +Loaded. Save in game, restart, and load for less bugs. = 已载入。请在游戏中存档, 重开, 再次读档以减少bug。 LoadStateDoesntExist = 即时存档载入失败:存档不存在 LoadStateWrongVersion = 即时存档载入失败:存档是旧版本PPSSPP的 norewind = 没有可用的倒带自动即时存档。 @@ -1005,7 +1005,7 @@ saveNewTextures_true = 开始转储新纹理。 SpeedCustom2 = 速度:自定义2 standard = 速度:标准 State load undone = 撤销即时存档载入 -Untitled PSP game = 无标题的 PSP 游戏 +Untitled PSP game = 无标题的PSP游戏 [Store] Already Installed = 已安装 @@ -1130,7 +1130,7 @@ Ignore bad memory accesses = 忽略错误的内存访问 Increase size = 增大尺寸 Interpreter = 解释器 IO timing method = I/O计时方法 -IR Interpreter = IR 解释器 +IR Interpreter = IR解释器 Memory Stick Folder = 记忆棒文件夹 Memory Stick inserted = 记忆棒已插入 MHz, 0:default = MHz, 默认为0 @@ -1168,7 +1168,7 @@ Slot 3 = 插槽3 Slot 4 = 插槽4 Slot 5 = 插槽5 Storage full = 存储空间已满 -Sustained performance mode = 持久性能模式 (使长时间运行的应用运行更流畅) +Sustained performance mode = 持久性能模式(使长时间运行的应用运行更流畅) Time Format = 时间格式 UI = 用户界面 UI background animation = 界面背景效果 @@ -1177,10 +1177,10 @@ undo %c = 备份 %c USB = USB Use Lossless Video Codec (FFV1) = 使用无损视频编解码器(FFV1) Use O to confirm = 使用按钮O确认 -Use output buffer (with overlay) for recording = 录制时使用输出缓冲 (包括叠加信息) +Use output buffer (with overlay) for recording = 录制时使用输出缓冲(包括叠加信息) Use system native keyboard = 使用系统本机键盘 Use X to confirm = 使用按钮X确认 -VersionCheck = 检查 PPSSPP 新版本 +VersionCheck = 检查PPSSPP新版本 WARNING: Android battery save mode is on = 警告:安卓省电模式已开启 WARNING: Battery save mode is on = 警告:省电模式已开启 Waves = 波浪动画 From 1272b402c11d1bd3ce8b3726e4d849755b4e0b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 15 Jul 2022 11:25:56 +0200 Subject: [PATCH 14/57] Apply leoxxx's spacing changes in zh_TW.ini --- assets/lang/zh_TW.ini | 510 +++++++++++++++++++++--------------------- 1 file changed, 258 insertions(+), 252 deletions(-) diff --git a/assets/lang/zh_TW.ini b/assets/lang/zh_TW.ini index a7e85f45ee..63ce1e7421 100644 --- a/assets/lang/zh_TW.ini +++ b/assets/lang/zh_TW.ini @@ -1,12 +1,12 @@ [Audio] Alternate speed volume = 自定義速度下的音量 -Audio backend = 音訊引擎 (需要重新啟動) +Audio backend = 音訊引擎(需要重新啟動) Audio Error = 音訊錯誤 AudioBufferingForBluetooth = 藍牙友好緩衝區(較慢) Auto = 自動 Device = 設備 Disabled = Disabled -DSound (compatible) = DirectSound (兼容) +DSound (compatible) = DirectSound(兼容) Enable Sound = 啟用音效 Global volume = 全局音量 Microphone = Microphone @@ -15,7 +15,7 @@ Mute = 靜音 Reverb volume = 混響音量 Use new audio devices automatically = 自動開啟新的音頻設備 Use global volume = 使用全局量 -WASAPI (fast) = WASAPI (快) +WASAPI (fast) = WASAPI(快) [Controls] Analog Binding = 搖桿綁定 @@ -48,7 +48,7 @@ Customize Touch Controls = 自訂佈局 Customize tilt = 自訂傾斜 D-PAD = 方向鍵 Deadzone radius = 死區半徑 -Disable D-Pad diagonals (4-way touch) = 停用方向鍵對角線 (四方向觸控) +Disable D-Pad diagonals (4-way touch) = 停用方向鍵對角線(四方向觸控) Disable diagonal input = 停用對角線錄入 Double tap = 雙擊 Enable gesture control = 開啓體感控制 @@ -56,17 +56,18 @@ Enable standard shortcut keys = 開啓標準熱鍵 Gesture = 體感 Gesture mapping = 體感映射 Glowing borders = 細邊框 -HapticFeedback = 按鍵反饋 (震動) +HapticFeedback = 按鍵反饋(震動) Hide touch analog stick background circle = 隱藏觸屏搖桿背景圈 Icon = 圖標 Ignore gamepads when not focused = 非作用時忽略遊戲手把 -Ignore Windows Key = 忽略 Windows 鍵 +Ignore Windows Key = 忽略Windows鍵 Invert Axes = 軸反轉 -Invert Tilt along X axis = 沿 X 軸傾斜反轉 -Invert Tilt along Y axis = 沿 Y 軸傾斜反轉 +Invert Tilt along X axis = 沿X軸傾斜反轉 +Invert Tilt along Y axis = 沿Y軸傾斜反轉 Keep this button pressed when right analog is pressed = 點擊右模擬鍵時保持點擊此按鈕 Keyboard = 鍵盤控制設定 -L/R Trigger Buttons = L/R 觸發按鈕 +L/R Trigger Buttons = L/R觸發按鈕 +#L/R扳机按钮 Landscape = 橫向 Landscape Auto = 自動橫向 Landscape Reversed = 橫向反轉 @@ -75,20 +76,21 @@ Mouse = 鼠標配置 Mouse sensitivity = 鼠標靈敏度 Mouse smoothing = 鼠標平滑 MouseControl Tip = 您現在可以在按鍵映射界面上按“ M”圖標來映射鼠標按鍵。 -None (Disabled) = 無 (停用) +None (Disabled) = 無(停用) Off = 關閉 OnScreen = 顯示虛擬控制器 Portrait = 縱向 Portrait Reversed = 縱向反轉 -PSP Action Buttons = PSP 的功能鍵 +PSP Action Buttons = PSP功能鍵 Raw input = 原始錄入 Repeat mode = Repeat mode +#重复模式 Reset to defaults = 重置爲默認 Screen aligned to ground = 屏幕水平地面 Screen at right angle to ground = 屏幕垂直地面 Screen Rotation = 螢幕旋轉 seconds, 0 : off = 秒,0 = 關閉 -Sensitivity (scale) = 靈敏度 (倍數) +Sensitivity (scale) = 靈敏度(倍數) Sensitivity = 靈敏度 Shape = 形狀 Show Touch Pause Menu Button = 顯示觸控暫停選單鍵 @@ -98,8 +100,8 @@ Swipe smoothing = 滑動光滑度 Thin borders = 薄邊框 Tilt Base Radius = 傾斜基本半徑 Tilt Input Type = 傾斜輸入類型 -Tilt Sensitivity along X axis = 沿 X 軸傾斜靈敏度 -Tilt Sensitivity along Y axis = 沿 Y 軸傾斜靈敏度 +Tilt Sensitivity along X axis = 沿X軸傾斜靈敏度 +Tilt Sensitivity along Y axis = 沿Y軸傾斜靈敏度 To Calibrate = 請將裝置放在平面上,然後按「校正」。 Toggle mode = 切換模式 Touch Control Visibility = 觸控可視性 @@ -114,7 +116,7 @@ Y = Y Cheats = 金手指 Edit Cheat File = 編輯金手指文件 Enable/Disable All = 全部啟用/停用 -Import Cheats = 由 cheat.db 匯入 +Import Cheats = 由cheat.db匯入 Options = 選項 Refresh Rate = 刷新率 @@ -123,9 +125,9 @@ Refresh Rate = 刷新率 # Just add it to your language's ini file and uncomment it (remove the # by Font). Auto Max Quality = 自動最高質量 (&Q) Font = Microsoft JhengHei -About PPSSPP... = 關於 PPSSPP (&A)... +About PPSSPP... = 關於PPSSPP (&A)... Auto = 自動 (&A) -Backend = 繪圖引擎 (需要重新啟動) (&b) +Backend = 繪圖引擎(需要重新啟動) (&b) Bicubic = 雙立方 (&B) Break = 停止 Break on Load = 載入后停止 @@ -156,17 +158,17 @@ GitHub = Git&Hub Hardware Transform = 硬體幾何轉換 (&H) Help = 幫助 (&H) Hybrid = 混合 (&H) -Hybrid + Bicubic = 混合 + 雙立方 (&Y) +Hybrid + Bicubic = 混合+雙立方 (&Y) Ignore Illegal Reads/Writes = 忽略非法存取 (&I) -Ignore Windows Key = 忽略 Windows 鍵 -Keep PPSSPP On Top = 保持 PPSSPP 視窗在最上層 (&K) +Ignore Windows Key = 忽略Windows鍵 +Keep PPSSPP On Top = 保持PPSSPP視窗在最上層 (&K) Landscape = 横向 Landscape reversed = 橫向反轉 Language... = 語言設定 (&a) Linear = 線性 (&L) Load = 載入遊戲 (&L) -Load .sym File... = 載入 .sym 檔案 (&A)... -Load Map File... = 載入 Map 檔案(&M)... +Load .sym File... = 載入.sym檔案 (&A)... +Load Map File... = 載入Map檔案(&M)... Load State = 載入即時存檔 (&O) Load State File... = 載入即時存檔檔案 (&L)... Log Console = 控制台日誌 (&L) @@ -178,6 +180,7 @@ Off = 關閉 (&O) Open Chat = 打開聊天 Open Directory... = 打開目錄 (&D)... Open from MS:/PSP/GAME... = 打開 MS:/PSP/GAME (&P)... +#从MS:/PSP/GAME处打开 (&p)... Open Memory Stick = 打開記憶卡 (&M) Open New Instance = 打開新實例 OpenGL = OpenGL (&O) @@ -195,29 +198,29 @@ Rendering Resolution = 渲染解析度 (&R) Reset = 重置 (&E) Reset Symbol Table = 重置符號表 (&R) Run = 執行 (&R) -Save .sym File... = 保存 .sym 檔案 (&e)... -Save Map File... = 保存 Map 檔案 (&S)... +Save .sym File... = 保存.sym檔案 (&e)... +Save Map File... = 保存Map檔案 (&S)... Save State = 即時存檔 (&a) Save State File... = 保存即時存檔檔案 (&S)... Savestate Slot = 即時存檔插槽 (&t) Screen Scaling Filter = 螢幕縮放濾鏡 (&e) Show Debug Statistics = 顯示除錯數據 (&g) -Show FPS Counter = 顯示 FPS 計數器 (&F) +Show FPS Counter = 顯示FPS計數器 (&F) Skip Number of Frames = 跳過幀數 -Skip Percent of FPS = 跳過FPS的百分比 +Skip Percent of FPS = 跳過FPS的百分比 Stop = 停止 (&S) -Switch UMD = 切換光碟 +Switch UMD = 切換UMD光碟 Take Screenshot = 截圖 (&T) Texture Filtering = 紋理過濾 (&x) Texture Scaling = 紋理縮放 (&T) -Use Lossless Video Codec (FFV1) = 使用無損視訊轉碼器 (FFV1) (&U) +Use Lossless Video Codec (FFV1) = 使用無損視訊轉碼器(FFV1) (&U) Use output buffer for video = 將輸出緩衝區用於視頻 Vertex Cache = 頂點快取 (&V) VSync = 垂直同步 (&y) Vulkan = Vulkan Window Size = 視窗大小 (&W) -www.ppsspp.org = 拜訪 www.&ppsspp.org -xBRZ = &xBRZ +www.ppsspp.org = 拜訪www.&ppsspp.org +xBRZ = &xBRZ [Developer] Allocator Viewer = 分配器查看器(Vulkan) @@ -232,18 +235,18 @@ Dev Tools = 開發工具 DevMenu = 開發菜單 Disabled JIT functionality = 禁用JIT功能 Draw Frametimes Graph = 繪製幀時間圖 -Dump Decrypted Eboot = 載入遊戲時,轉儲已解密的 EBOOT.BIN -Dump Frame GPU Commands = 轉儲幀 GPU 指令 +Dump Decrypted Eboot = 載入遊戲時,轉儲已解密的EBOOT.BIN +Dump Frame GPU Commands = 轉儲幀GPU指令 Enable driver bug workarounds = 啟用驅動程序錯誤解決方法 Enable Logging = 啟用日誌 Enter address = 輸入位址 FPU = FPU Framedump tests = 幀轉儲測試 Frame Profiler = 幀分析器 -GPU Driver Test = GPU 驅動程序測試 -GPU Log Profiler = GPU 日志分析器 -GPU Profile = GPU 配置文件 -Jit Compare = Jit 比較 +GPU Driver Test = GPU驅動程序測試 +GPU Log Profiler = GPU日志分析器 +GPU Profile = GPU配置文件 +Jit Compare = Jit比較 JIT debug tools = JIT調試工具 Language = 語言設定 Load language ini = 載入語言設定 @@ -258,10 +261,10 @@ Random = 隨機 Replace textures = 紋理更換 Reset = 重置 Reset limited logging = 重置受限日誌 -RestoreDefaultSettings = 你確定要所有設定還原到預設值 (除了按鍵配置)?\n此動作無法恢復。\n需要重新啟動 PPSSPP,變更才會生效。 -RestoreGameDefaultSettings = 你確定要恢復特定遊戲的配置,\n回到 PPSSPP 的預設值? +RestoreDefaultSettings = 你確定要所有設定還原到預設值 (除了按鍵配置)?\n此動作無法恢復。\n需要重新啟動PPSSPP,變更才會生效。 +RestoreGameDefaultSettings = 你確定要恢復特定遊戲的配置,\n回到PPSSPP的預設值? Resume = 恢復 -Run CPU Tests = 執行 CPU 測試 +Run CPU Tests = 執行CPU測試 Save language ini = 儲存語言設定 Save new textures = 保存新纹理 Shader Viewer = 著色器查看器 @@ -269,7 +272,7 @@ Show Developer Menu = 顯示開發者選單 Show on-screen messages = 顯示屏幕消息 Stats = 統計 System Information = 系統資料 -Texture ini file created = 創建紋理 INI 文件 +Texture ini file created = 創建紋理INI文件 Texture Replacement = 纹理更换 Toggle Audio Debug = 切換音訊除錯 Toggle Freeze = 切換凍結 @@ -277,15 +280,15 @@ Touchscreen Test = 觸摸屏測試 VFPU = VFPU [Dialog] -* PSP res = * PSP 解析度 +* PSP res = * PSP解析度 Active = 激活 Back = 返回 Cancel = 取消 Center = 中間 -ChangingGPUBackends = 改變渲染引擎之後需要重新啟動 PPSSPP。現在重新啟動嗎? +ChangingGPUBackends = 改變渲染引擎之後需要重新啟動PPSSPP。現在重新啟動嗎? ChangingInflightFrames = 更改圖形命令緩衝要求PPSSPP重新啟動。 現在重啟? Channel: = 頻道: -Choose PPSSPP save folder = 選擇 PPSSPP 的存檔資料夾 +Choose PPSSPP save folder = 選擇PPSSPP的存檔資料夾 Confirm Overwrite = 你要覆蓋這份檔案嗎? Confirm Save = 你要儲存這份檔案嗎? ConfirmLoad = 你要載入這份檔案嗎? @@ -309,7 +312,7 @@ Enable All = 全部啟用 Enter = 決定 Filter = 篩選 Finish = 完成 -GE Frame Dumps = GE 幀轉儲 +GE Frame Dumps = GE幀轉儲 Grid = 格 Inactive = 不活躍 InternalError = 發生了一個內部錯誤. @@ -351,30 +354,30 @@ Yes = 是 Zoom = 放大 [Error] -7z file detected (Require 7-Zip) = 檔案是 7z 壓縮檔。\n請先解壓縮 (使用 7-zip 或 WinRAR)。 +7z file detected (Require 7-Zip) = 檔案是7z壓縮檔。\n請先解壓縮 (使用 7-zip 或 WinRAR)。 A PSP game couldn't be found on the disc. = 光盤上找不到PSP遊戲. Cannot boot ELF located outside mountRoot. = 無法引導位於裝載根外部的ELF. Could not save screenshot file = 無法保存截圖檔案 -D3D9or11 = 使用 Direct3D 9? (或者 "否" 以使用 Direct3D 11) -D3D11CompilerMissing = D3DCompiler_47.dll 未找到。 請安裝。 或者按“是”,再次嘗試使用 Direct3D 9。 -D3D11InitializationError = Direct3D 11 初始化錯誤 +D3D9or11 = 使用 Direct3D 9? (或者 "否" 以使用Direct3D 11) +D3D11CompilerMissing = D3DCompiler_47.dll未找到。 請安裝。 或者按“是”,再次嘗試使用Direct3D 9。 +D3D11InitializationError = Direct3D 11初始化錯誤 D3D11Missing = 您的操作系統版本不包括 D3D11。 請運行Windows Update.\n\n按是,嘗試使用 Direct3D 9. -D3D11NotSupported = 您的 GPU 似乎不支持 Direct3D 11.\n\n您是否想改用 Direct3D 9? +D3D11NotSupported = 您的GPU似乎不支持Direct3D 11.\n\n您是否想改用Direct3D 9? Disk full while writing data = 寫入數據時硬碟空間不足 -ELF file truncated - can't load = ELF 文件被截斷-無法加載 +ELF file truncated - can't load = ELF文件被截斷-無法加載 Error loading file = 檔案載入錯誤 Error reading file = 讀取檔案錯誤 -Failed initializing CPU/Memory = 初始化 CPU 或內存失敗 +Failed initializing CPU/Memory = 初始化CPU或內存失敗 Failed to load executable: = 無法加載可執行文件: File corrupt = 文件損壞 -Game disc read error - ISO corrupt = 遊戲光盤讀取錯誤:ISO 損壞. +Game disc read error - ISO corrupt = 遊戲光盤讀取錯誤:ISO損壞. GenericAllStartupError = PPSSPP無法使用任何圖形後端啟動。 嘗試升級圖形和其他驅動程序. -GenericBackendSwitchCrash = 啟動時 PPSSPP 崩潰了.\n\n這通常意味著圖形驅動程序問題。 嘗試升級圖形驅動程序.\n\n圖形後端已切換: -GenericDirect3D9Error = 圖形初始化失敗,請試著更新你的圖形驅動程式與 DirectX 9 runtime。\n\n你要切換到 OpenGL 試試看嗎?\n\n錯誤訊息: +GenericBackendSwitchCrash = 啟動時PPSSPP 崩潰了.\n\n這通常意味著圖形驅動程序問題。 嘗試升級圖形驅動程序.\n\n圖形後端已切換: +GenericDirect3D9Error = 圖形初始化失敗,請試著更新你的圖形驅動程式與DirectX 9 runtime。\n\n你要切換到 OpenGL 試試看嗎?\n\n錯誤訊息: GenericGraphicsError = 圖形錯誤 -GenericOpenGLError = 圖形初始化失敗,請試著更新你的圖形驅動程式。\n\n你要切換到 DirectX 9 試試看嗎?\n\n錯誤訊息: -GenericVulkanError = 初始化圖形失敗。 嘗試升級圖形驅動程序.\n\n您想嘗試切換到 OpenGL 嗎?\n\n錯誤信息: -InsufficientOpenGLDriver = 偵測到 OpenGL 驅動程式的支援不足\n\n你想嘗試 DirectX 嗎?\n\n目前兼容 DirectX 的遊戲較少,但對你的 GPU 而言可能是唯一的選擇。 +GenericOpenGLError = 圖形初始化失敗,請試著更新你的圖形驅動程式。\n\n你要切換到DirectX 9 試試看嗎?\n\n錯誤訊息: +GenericVulkanError = 初始化圖形失敗。 嘗試升級圖形驅動程序.\n\n您想嘗試切換到OpenGL嗎?\n\n錯誤信息: +InsufficientOpenGLDriver = 偵測到OpenGL 驅動程式的支援不足\n\n你想嘗試DirectX嗎?\n\n目前兼容DirectX 的遊戲較少,但對你的GPU而言可能是唯一的選擇。 Just a directory. = 只是一個目錄。 Missing key = 缺失密鑰 MsgErrorCode = 錯誤代碼: @@ -382,21 +385,22 @@ MsgErrorSavedataDataBroken = 保存數據已損壞. MsgErrorSavedataMSFull = 記憶棒已滿. 檢查您的存儲空間. MsgErrorSavedataNoData = 警告:未找到保存數據. MsgErrorSavedataNoMS = 未插入記憶棒. -No EBOOT.PBP, misidentified game = 沒有 EBOOT.PBP,錯誤識別遊戲。 +No EBOOT.PBP, misidentified game = 沒有EBOOT.PBP,錯誤識別遊戲。 Not a valid disc image. = 無效的光盤映像. OpenGLDriverError = OpenGL 驅動程式錯誤 -PPSSPP doesn't support UMD Music. = PPSSPP 不支持 UMD 音樂 -PPSSPP doesn't support UMD Video. = PPSSPP 不支持 UMD 視頻 -PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP 玩 PSP 遊戲,而不是 PlayStation 1或2遊戲. -PPSSPPDoesNotSupportInternet = PPSSPP 目前不支援透過網路進行 DLC、PSN 或更新遊戲 -PS1 EBOOTs are not supported by PPSSPP. = PPSSPP 不支援 PS1 EBOOTS -PSX game image detected. = 抱歉,不支援 PSX 遊戲 -RAR file detected (Require UnRAR) = 檔案是 RAR 壓縮檔。\ n請先解壓縮 (需使用 UnRAR)。 -RAR file detected (Require WINRAR) = 檔案是 RAR 壓縮檔。\ n請先解壓縮 (需使用 WinRAR)。 +PPSSPP doesn't support UMD Music. = PPSSPP不支持UMD音樂 +PPSSPP doesn't support UMD Video. = PPSSPP不支持UMD視頻 +PPSSPP plays PSP games, not PlayStation 1 or 2 games. = PPSSPP玩 PSP遊戲,而不是PlayStation1或2遊戲. +#PPSSPP只能运行PSP游戏, 不能运行PS1或2的游戏 +PPSSPPDoesNotSupportInternet = PPSSPP目前不支援透過網路進行DLC、PSN 或更新遊戲 +PS1 EBOOTs are not supported by PPSSPP. = PPSSPP不支援PS1 EBOOTS +PSX game image detected. = 抱歉,不支援PSX遊戲 +RAR file detected (Require UnRAR) = 檔案是RAR壓縮檔。\ n請先解壓縮(需使用UnRAR)。 +RAR file detected (Require WINRAR) = 檔案是RAR壓縮檔。\ n請先解壓縮(需使用WinRAR)。 Running slow: try frameskip, sound is choppy when slow = 運行速度慢:嘗試跳幀,聲音不連貫時慢 Running slow: Try turning off Software Rendering = 運行緩慢:嘗試關閉“軟件渲染” -Save encryption failed. This save won't work on real PSP = 存檔加密失敗。真正的 PSP 將無法讀取這份存檔 -textures.ini filenames may not be cross-platform = "textures.ini" 文件名可能不是跨平台的。 +Save encryption failed. This save won't work on real PSP = 存檔加密失敗。真正的PSP將無法讀取這份存檔 +textures.ini filenames may not be cross-platform = "textures.ini"文件名可能不是跨平台的。 This is a saved state, not a game. = 這是保存狀態,而不是遊戲。 This is save data, not a game. = 這是保存數據,而不是遊戲。 Unable to create cheat file, disk may be full = 無法建立金手指文件,硬碟可能已滿 @@ -404,12 +408,12 @@ Unable to initialize rendering engine. = 無法初始化渲染引擎。 Unable to write savedata, disk may be full = 無法記錄,硬碟可能已滿 Warning: Video memory FULL, reducing upscaling and switching to slow caching mode = 警告:視訊記憶體已滿,降低像素提升並切換到慢速快取模式。 Warning: Video memory FULL, switching to slow caching mode = 警告:視訊記憶體已滿,切換到慢速快取模式。 -ZIP file detected (Require UnRAR) = 檔案是 ZIP 壓縮檔。\ n請先解壓縮 (需使用 UnRAR)。 -ZIP file detected (Require WINRAR) = 檔案是 ZIP 壓縮檔。\ n請先解壓縮 (需使用 WinRAR)。 +ZIP file detected (Require UnRAR) = 檔案是ZIP壓縮檔。\ n請先解壓縮 (需使用UnRAR)。 +ZIP file detected (Require WINRAR) = 檔案是ZIP壓縮檔。\ n請先解壓縮 (需使用WinRAR)。 [Game] Asia = 亞洲 -Calculate CRC = 計算 CRC +Calculate CRC = 計算CRC ConfirmDelete = 確定 Create Game Config = 建立遊戲配置 Create Shortcut = 建立捷徑 @@ -432,7 +436,7 @@ SaveData = 存檔 Setting Background = 配置背景 Show In Folder = 顯示資料夾 USA = 美國 -Use UI background = 使用 UI 背景 +Use UI background = 使用UI背景 [Graphics] % of the void = % 的邊框 @@ -440,29 +444,29 @@ Use UI background = 使用 UI 背景 %, 0:unlimited = %,0 = 無限 (supersampling) = (超級采樣) (upscaling) = (倍增) -1x PSP = 1倍 PSP +1x PSP = 1倍PSP 2x = 2倍 -2x PSP = 2倍 PSP +2x PSP = 2倍PSP 3x = 3倍 -3x PSP = 3倍 PSP +3x PSP = 3倍PSP 4x = 4倍 -4x PSP = 4倍 PSP +4x PSP = 4倍PSP 5x = 5倍 -5x PSP = 5倍 PSP -6x PSP = 6倍 PSP -7x PSP = 7倍 PSP +5x PSP = 5倍PSP +6x PSP = 6倍PSP +7x PSP = 7倍PSP 8x = 8倍 -8x PSP = 8倍 PSP -9x PSP = 9倍 PSP -10x PSP = 10倍 PSP +8x PSP = 8倍PSP +9x PSP = 9倍PSP +10x PSP = 10倍PSP 16x = 16倍 Aggressive = 激進 -Alternative Speed = 速度控制 (%,0 = 無限) -Alternative Speed 2 = 替代速度 2 (in %, 0 = 無限) +Alternative Speed = 速度控制(%,0 = 無限) +Alternative Speed 2 = 替代速度2(in %, 0 = 無限) Anisotropic Filtering = 非等方性過濾 Auto = 自動 -Auto (1:1) = 自動 (1:1) -Auto (same as Rendering) = 自動 (同渲染) +Auto (1:1) = 自動(1:1) +Auto (same as Rendering) = 自動(同渲染) Auto FrameSkip = 自動跳幀 Auto Max Quality = 自動最高質量 Auto Scaling = 自動縮放 @@ -477,7 +481,7 @@ Buffered Rendering = 緩衝渲染 BufferedRenderingRequired = 警告:此遊戲需要將“渲染模式”配置為“緩衝”。 Camera = 相機 Camera Device = 攝像頭設備 -Cardboard Screen Size = 螢幕大小 (視區%) +Cardboard Screen Size = 螢幕大小(視區%) Cardboard Screen X Shift = 水平% Cardboard Screen Y Shift = 垂直% Cardboard VR Settings = Google Cardboard VR 設定 @@ -490,18 +494,18 @@ Deposterize Tip = 修復在紋理被放大時可能發生的小紋理內部毛 Device = 設備 Direct3D 9 = Direct3D 9 Direct3D 11 = Direct3D 11 -Disable slower effects (speedup) = 停用較慢的效果 (提升速度) +Disable slower effects (speedup) = 停用較慢的效果(提升速度) Disabled = 已禁用 Display layout editor = 自訂版面 -Display Resolution (HW scaler) = 顯示解析度 (硬體縮放) +Display Resolution (HW scaler) = 顯示解析度(硬體縮放) Dump next frame to log = 將下一幀儲存到日誌 -Enable Cardboard VR = 啟用 Cardboard VR +Enable Cardboard VR = 啟用Cardboard VR FPS = FPS Frame Rate Control = 幀速率控制 Frame Skipping = 跳幀 Frame Skipping Type = 跳幀類型 FullScreen = 全螢幕 -GPU log profiler = GPU 日志分析器 +GPU log profiler = GPU日志分析器 Hack Settings = 修正設定 Hardware Tessellation = 硬體曲面細分 Hardware Transform = 硬體幾何轉換 @@ -509,16 +513,16 @@ hardware transform error - falling back to software = 硬體轉換錯誤,改 HardwareTessellation Tip = 使用硬體繪製曲綫,使用固定的質量 High = 高 Hybrid = 混合 -Hybrid + Bicubic = 混合 + 雙立方 +Hybrid + Bicubic = 混合+雙立方 Ignore camera notch when centering = 居中時忽略攝像頭缺口 Internal Resolution = 內部分辨率 -Lazy texture caching = 緩慢紋理快取 (提升速度) +Lazy texture caching = 緩慢紋理快取(提升速度) Lazy texture caching Tip = 更快,在一些游戲裏會引起文字渲染錯誤更快, 在一些游戏里引起文字渲染错误 Linear = 線性 Low = 低 LowCurves = 樣條函數/貝茲曲線品質 LowCurves Tip = 此選項將顯著提高/降低渲染樣條和貝塞爾曲線的質量 -Lower resolution for effects (reduces artifacts) = 降低效果的解析度 (減少失真) +Lower resolution for effects (reduces artifacts) = 降低效果的解析度(減少失真) Manual Scaling = 手動縮放 Medium = 中 Mode = 模式 @@ -526,7 +530,7 @@ Must Restart = 你必須重新啟動 PPSSPP,此更改才會生效 Native device resolution = 原生裝置的解析度 Nearest = 鄰近取樣 No buffer = 不緩衝 -Non-Buffered Rendering = 非緩衝渲染 (跳過緩衝效果,較快速) +Non-Buffered Rendering = 非緩衝渲染(跳過緩衝效果,較快速) None = 關閉 Number of Frames = 幀數 Off = 關閉 @@ -538,12 +542,12 @@ Performance = 性能 Postprocessing effect = 後處理效果 Postprocessing Shader = 後期處理著色器 Recreate Activity = 重新創建活動 -Render duplicate frames to 60hz = 渲染重複幀至60 Hz +Render duplicate frames to 60hz = 渲染重複幀至60Hz RenderDuplicateFrames Tip = 在以較低幀速率運行的遊戲中可以使幀速率更平滑 Rendering Mode = 渲染模式 Rendering Resolution = 渲染解析度 RenderingMode NonBuffered Tip = 較快速,但在某些遊戲中可能什麼都不會顯示 -Retain changed textures = 保留更改紋理 (有時更慢) +Retain changed textures = 保留更改紋理(有時更慢) RetainChangedTextures Tip = 許多遊戲的速度變慢,但某些遊戲則變快許多 Rotation = 旋轉 Safe = 安全 @@ -553,7 +557,7 @@ Show Debug Statistics = 顯示除錯數據 Show FPS Counter = 顯示 FPS 計數器 Simulate Block Transfer = 模擬塊傳送的影響 Software Rendering = 軟體渲染 -Software Skinning = 減少繪圖調用 (提升速度) +Software Skinning = 減少繪圖調用(提升速度) SoftwareSkinning Tip = 在使用高級皮膚技術的遊戲中減少繪圖和更快,但有些遊戲更慢 Speed = 速度 Stretching = 拉伸 @@ -567,7 +571,7 @@ Up to 1 = 上到1 Up to 2 = 上到2 Upscale Level = 縮放倍率 Upscale Type = 縮放類型 -UpscaleLevel Tip = CPU 的負擔大,某些縮放可能會延遲,以免遊戲不流暢 +UpscaleLevel Tip = CPU的負擔大,某些縮放可能會延遲,以免遊戲不流暢 Use all displays = 使用所有顯示 Vertex Cache = 頂點快取 VertexCache Tip = 速度更快,但可能會造成螢幕暫時閃爍 @@ -577,14 +581,14 @@ Window Size = 視窗大小 xBRZ = xBRZ [InstallZip] -Delete ZIP file = 刪除 ZIP 檔案 +Delete ZIP file = 刪除ZIP檔案 Install = 安裝 -Install game from ZIP file? = 從 ZIP 檔案安裝遊戲? -Install textures from ZIP file? = 從 ZIP 文件安裝紋理? +Install game from ZIP file? = 從ZIP檔案安裝遊戲? +Install textures from ZIP file? = 從ZIP文件安裝紋理? Installed! = 安裝完成! Texture pack doesn't support install = 紋理包不支持安裝 Zip archive corrupt = ZIP檔案損壞 -Zip file does not contain PSP software = ZIP 文件不包含 PSP 軟件 +Zip file does not contain PSP software = ZIP文件不包含PSP軟件 [KeyMapping] Autoconfigure = 自動配置 @@ -597,28 +601,28 @@ Map Key = 按鍵映射 Map Mouse = 鼠標映射 Replace = 替換 Show PSP = 顯示 PSP -You can press ESC to cancel. = 您可以按 Esc 取消。 +You can press ESC to cancel. = 您可以按Esc取消。 [MainMenu] Browse = 瀏覽... Buy PPSSPP Gold = 購買PPSSPP黃金版 Choose folder = 選擇文件夾 Credits = 製作團隊 -PPSSPP Homebrew Store = 從 PPSSPP 自製游戲商店下載 +PPSSPP Homebrew Store = 從PPSSPP自製游戲商店下載 Exit = 離開 Game Settings = 遊戲設定 Games = 遊戲 -Give PPSSPP permission to access storage = 給予 PPSSPP 存取權限 +Give PPSSPP permission to access storage = 給予PPSSPP存取權限 Homebrew & Demos = 自製遊戲和試玩 How to get games = 如何獲得遊戲 How to get homebrew & demos = 如何獲得自製遊戲和試玩 Load = 載入遊戲... Loading... = 載入中... PinPath = 標記 -PPSSPP can't load games or save right now = PPSSPP 現在無法載入遊戲或存檔 +PPSSPP can't load games or save right now = PPSSPP現在無法載入遊戲或存檔 Recent = 最近執行的遊戲 -SavesAreTemporary = PPSSPP 正在保存在臨時存儲中 -SavesAreTemporaryGuidance = 將 PPSSPP 提取到某個地方以永久保存 +SavesAreTemporary = PPSSPP正在保存在臨時存儲中 +SavesAreTemporaryGuidance = 將PPSSPP提取到某個地方以永久保存 SavesAreTemporaryIgnore = 忽略警告 UnpinPath = 取消標記 UseBrowseOrLoad = 瀏覽以選擇文件夾,或者加載以載入遊戲文件 @@ -634,8 +638,8 @@ System = 系統設定 Tools = 工具 [MappableControls] -Alt speed 1 = 自定義速度 1 -Alt speed 2 = 自定義速度 2 +Alt speed 1 = 自定義速度1 +Alt speed 2 = 自定義速度2 An.Down = 左搖桿:下 An.Left = 左搖桿:左 An.Right = 左搖桿:右 @@ -646,16 +650,16 @@ Audio/Video Recording = 音頻/視頻錄製 AxisSwap = 軸交換 Circle = 圈 Cross = 叉 -Custom 1 = 預設 1 -Custom 10 = 預設 10 -Custom 2 = 預設 2 -Custom 3 = 預設 3 -Custom 4 = 預設 4 -Custom 5 = 預設 5 -Custom 6 = 預設 6 -Custom 7 = 預設 7 -Custom 8 = 預設 8 -Custom 9 = 預設 9 +Custom 1 = 預設1 +Custom 10 = 預設10 +Custom 2 = 預設2 +Custom 3 = 預設3 +Custom 4 = 預設4 +Custom 5 = 預設5 +Custom 6 = 預設6 +Custom 7 = 預設7 +Custom 8 = 預設8 +Custom 9 = 預設9 D-pad down = 方向鍵:下 D-pad left = 方向鍵:左 D-pad right = 方向鍵:右 @@ -712,43 +716,43 @@ Toggle mode = 切換模式 Triangle = 三角形 Fast-forward = 解除速限 Up = 方向鍵:上 -Vol + = 音量 + -Vol - = 音量 - +Vol + = 音量+ +Vol - = 音量- Wlan = 無綫網絡 [MemStick] -Already contains PSP data = 已包含 PSP 數據 -Create or Choose a PSP folder = 創建或選擇 PSP 文件夾 +Already contains PSP data = 已包含PSP數據 +Create or Choose a PSP folder = 創建或選擇PSP文件夾 Current = 目前 -DataCanBeShared = 數據可在 PPSSPP 普通版/黃金版共用 -DataCannotBeShared = 數據無法在 PPSSPP 普通版/黃金版共用! -DataWillBeLostOnUninstall = 警告! 卸載 PPSSPP 會丟失數據! -DataWillStay = 卸載 PPSSPP 會保留數據 +DataCanBeShared = 數據可在PPSSPP普通版/黃金版共用 +DataCannotBeShared = 數據無法在PPSSPP普通版/黃金版共用! +DataWillBeLostOnUninstall = 警告! 卸載PPSSPP會丟失數據! +DataWillStay = 卸載PPSSPP會保留數據 Done! = 完成! -EasyUSBAccess = 輕鬆 USB 訪問 +EasyUSBAccess = 輕鬆USB訪問 Failed to move some files! = 無法移動部分文件! Failed to save config = 無法保存配置 Free space = 可用空間 -Manually specify PSP folder = 手動指定 PSP 文件夾 -MemoryStickDescription = 選擇 PSP 文件存放位置(記憶棒) -Move Data = 移動 PSP 數據 -Selected PSP Data Folder = 選擇 PSP 數據文件夾 +Manually specify PSP folder = 手動指定PSP文件夾 +MemoryStickDescription = 選擇PSP文件存放位置(記憶棒) +Move Data = 移動PSP數據 +Selected PSP Data Folder = 選擇PSP數據文件夾 No data will be changed = 數據不會更改 -PPSSPP will restart after the change = 完成配置后會重啓 PPSSPP +PPSSPP will restart after the change = 完成配置后會重啓PPSSPP Skip for now = 暫時跳過 Starting move... = 開始移動... That folder doesn't work as a memstick folder. = 所選文件夾無法作爲記憶棒目錄您选择的文件夹无法作为记忆棒目录。 -USBAccessThrough = USB 連接時請打開 Android/data/org.ppsspp.ppsspp/files -USBAccessThroughGold = USB 連接時請打開 Android/data/org.ppsspp.ppssppgold/files -Use App Private Data = 在 AP 内置的目錄中保存 -Use PSP folder at root of storage = 在手機目錄中保存 PSP 文件 -Welcome to PPSSPP! = 歡迎使用 PPSSPP! +USBAccessThrough = USB連接時請打開 Android/data/org.ppsspp.ppsspp/files +USBAccessThroughGold = USB連接時請打開 Android/data/org.ppsspp.ppssppgold/files +Use App Private Data = 在APP内置的目錄中保存 +Use PSP folder at root of storage = 在手機目錄中保存PSP文件 +Welcome to PPSSPP! = 歡迎使用PPSSPP! WhatsThis = 這個配置有什麽用? [Networking] -AdHoc Server = Ad hoc 服務器 -AdhocServer Failed to Bind Port = 無法綁定 Adhoc 服務器端口 -AM: Data from Unknown Port = AM: 來自未知端口的數據 +AdHoc Server = Ad hoc服務器 +AdhocServer Failed to Bind Port = 無法綁定Adhoc服務器端口 +AM: Data from Unknown Port = AM:來自未知端口的數據 Auto = 自動 Bottom Center = 中間下面 Bottom Left = 下左面 @@ -756,20 +760,20 @@ Bottom Right = 右下面 Center Left = 中間左面 Center Right = 中間右面 Change Mac Address = 改變 Mac 網路位址 -Change proAdhocServer Address = 改變 PRO Adhoc 網路位址 (localhost = 多個實例) +Change proAdhocServer Address = 改變PRO Adhoc網路位址(localhost = 多個實例) Chat = 聊天 Chat Button Position = 聊天按鈕位置 Chat Here = 在這裡聊天 Chat message = 聊天消息 Chat Screen Position = 聊天畫面位置 -Disconnected from AdhocServer = 與 Adhoc 服務器斷開連接 -DNS Error Resolving = DNS 錯誤解決 -Enable built-in PRO Adhoc Server = 啟用內建 PRO Adhoc 伺服器 +Disconnected from AdhocServer = 與 dhoc服務器斷開連接 +DNS Error Resolving = DNS錯誤解決 +Enable built-in PRO Adhoc Server = 啟用內建PRO Adhoc伺服器 Enable network chat = 啟用網絡聊天 -Enable networking = 啟用網路連線/無線區域網路 (測試) -Enable UPnP = 啟用 UPnP(需要幾秒鐘來檢測) +Enable networking = 啟用網路連線/無線區域網路(測試) +Enable UPnP = 啟用UPnP(需要幾秒鐘來檢測) EnableQuickChat = 啟用快速聊天 -Enter a new PSP nickname = 輸入新的 PSP 暱稱 +Enter a new PSP nickname = 輸入新的PSP暱稱 Enter Quick Chat 1 = 輸入快速聊天1 Enter Quick Chat 2 = 輸入快速聊天2 Enter Quick Chat 3 = 輸入快速聊天3 @@ -778,19 +782,20 @@ Enter Quick Chat 5 = 輸入快速聊天5 Error = Error Failed to Bind Localhost IP = 無法綁定本地主機IP Failed to Bind Port = 無法綁定端口 -Failed to connect to Adhoc Server = 無法連接 Adhoc 服務器 +Failed to connect to Adhoc Server = 無法連接Adhoc服務器 Forced First Connect = 強制首次連接(更快的連接) -GM: Data from Unknown Port = GM: 數據來自未知端口 +GM: Data from Unknown Port = GM:數據來自未知端口 Hostname = 主機名 -Invalid IP or hostname = 無效的 IP 或主機名 -Minimum Timeout = 最小超時(以毫秒為單位,0 =默認) +Invalid IP or hostname = 無效的IP或主機名 +Minimum Timeout = 最小超時(以毫秒為單位,0=默認) Misc = 其他(默認= PSP兼容性) Network Initialized = 網路已初始化 None = 無 Please change your Port Offset = 請更改您的端口偏移 Port offset = 端口偏移 (0 = PSP 實機兼容) -Open PPSSPP Multiplayer Wiki Page = 打開 PPSSPP 多人百科頁面 -proAdhocServer Address: = Ad hoc 服務器地址: +Open PPSSPP Multiplayer Wiki Page = 打開PPSSPP多人百科頁面 +#打开PPSSPP多人联机百科页面 +proAdhocServer Address: = Ad hoc服務器地址: Quick Chat 1 = 快速聊天1 Quick Chat 2 = 快速聊天2 Quick Chat 3 = 快速聊天3 @@ -798,14 +803,15 @@ Quick Chat 4 = 快速聊天4 Quick Chat 5 = 快速聊天5 QuickChat = 快速聊天 Send = 發送 -Send Discord Presence information = 發送 Discord "Rich Presence" information +Send Discord Presence information = 發送Discord "Rich Presence" information +#发送Discord"在线状态"信息 Top Center = 中間上面 Top Left = 左上面 Top Right = 右上面 -Unable to find UPnP device = 找不到 UPnP 設備 +Unable to find UPnP device = 找不到UPnP設備 UPnP (port-forwarding) = UPnP(端口轉發) -UPnP need to be reinitialized = UPnP 需要重新初始化 -UPnP use original port = UPnP 使用原始端口(已啟用= PSP兼容性) +UPnP need to be reinitialized = UPnP需要重新初始化 +UPnP use original port = UPnP使用原始端口(已啟用=PSP兼容性) Validating address... = 驗證地址... WLAN Channel = WLAN 頻道 You're in Offline Mode, go to lobby or online hall = 您現在是離綫模式,請進入房間或在綫大廳 @@ -832,62 +838,62 @@ Undo last save = 撤銷保存 5xBR-lv2 = 5xBR-lv2 AAColor = AA-Color Amount = 數量 -Animation speed (0 -> disable) = 動畫速度 (0 -> 禁用) +Animation speed (0 -> disable) = 動畫速度(0->禁用) Black border = 黑色描邊 -Bloom = Bloom (汎光) +Bloom = 汎光 Brightness = 亮度 -Cartoon = Cartoon (卡通) +Cartoon = 卡通 CatmullRom = Bicubic 雙三插值縮放 -ColorCorrection = Color correction (顔色修正) +ColorCorrection = 顔色修正 Contrast = 對比度 CRT = CRT 掃描綫 FXAA = FXAA (快速近似抗鋸齒) Gamma = 伽馬 -Grayscale = Grayscale (灰度) +Grayscale = 灰度图 Intensity = 强度 -InverseColors = Inverse Colors (反色) +InverseColors = 反色 MitchellNetravali = Bicubic 雙三插值縮放 -Natural = Natural Colors (自然色) -NaturalA = NaturalA (自然色-無模糊) +Natural = 自然色 +NaturalA = 自然色-無模糊 Off = 關閉 Power = 效果强度 -PSPColor = PSP 顔色 +PSPColor = PSP顔色 Saturation = 色彩 -Scanlines = 掃描綫 (CRT) -Sharpen = Sharpen (銳化) -SSAA(Gauss) = Supersampling AA (超級采樣抗鋸齒:高斯) +Scanlines = 掃描綫(CRT) +Sharpen = 銳化 +SSAA(Gauss) = Supersampling AA(超級采樣抗鋸齒:高斯) Tex4xBRZ = 4xBRZ TexMMPX = MMPX -UpscaleSpline36 = Spline36 縮放 -VideoSmoothingAA = VideoSmoothingAA (視頻平滑抗鋸齒) -Vignette = Vignette (暗角) +UpscaleSpline36 = Spline36縮放 +VideoSmoothingAA = VideoSmoothingAA(視頻平滑抗鋸齒) +Vignette = 光暈 [PSPCredits] -all the forum mods = 所有論壇管理員 +all the forum mods = 論壇上所有的mod build server = 編譯服務器 Buy Gold = 購買黃金版 -check = 也歡迎你試用海豚模擬器,最好用的 Wii/GC 模擬器 -CheckOutPPSSPP = 查閲 PPSSPP, 一款超棒的 PSP 模擬器: https://www.ppsspp.org/ +check = 也歡迎你試用海豚模擬器,最好用的Wii/GC 模擬器 +CheckOutPPSSPP = 查閲 PPSSPP, 一款超棒的PSP模擬器:https://www.ppsspp.org/ contributors = 參與者: created = 作者: Discord = Discord -info1 = PPSSPP 僅限教學用途 +info1 = PPSSPP僅限教學用途 info2 = 請確認你有權使用該遊戲, info3 = 例如持有該遊戲的正版光碟, -info4 = 或是透過 PSP 於 PSN 商店購買數位版。 -info5 = PSP® 是索尼公司的註冊商標。 +info4 = 或是透過PSP於PSN商店購買數位版。 +info5 = PSP®是索尼公司的註冊商標。 iOS builds = iOS builds -license = PPSSPP 是遵循 GPL 2.0+ 授權條款的自由軟體 +license = PPSSPP是遵循GPL 2.0+授權條款的自由軟體 list = 網站上有相容性列表、官方論壇以及開發動態 -PPSSPP Forums = PPSSPP 官方論壇 +PPSSPP Forums = PPSSPP官方論壇 Privacy Policy = 隱私政策 -Share PPSSPP = 分享 PPSSPP +Share PPSSPP = 分享PPSSPP specialthanks = 特別感謝: -specialthanksKeithGalocy = 的硬件,建議,他來自 NVIDIA -specialthanksMaxim = 的出色 Atrac3 + 解碼 +specialthanksKeithGalocy = 的硬件,建議,他來自NVIDIA +specialthanksMaxim = 的出色Atrac3 +解碼 testing = 負責測試 this translation by = 譯者: -title = 快速、方便攜帶的 PSP 模擬器 +title = 快速、方便攜帶的PSP模擬器 tools = 使用自由工具: # Add translators or contributors who translated PPSSPP into your language here. # Add translators1-6 for up to 6 lines of translator credits. @@ -900,7 +906,7 @@ translators5 = translators6 = Twitter @PPSSPP_emu = Twitter @PPSSPP_emu website = 歡迎參觀我們的網站: -written = 使用 C++ 編寫以保證移植性和速度 +written = 使用C++編寫以保證移植性和速度 [RemoteISO] Browse Games = 瀏覽遊戲 @@ -915,24 +921,24 @@ RemoteISOLoading = 已連接,正在加載遊戲列表... RemoteISOScanning = 掃描...單擊服務器設備上的“共享遊戲” RemoteISOScanningTimeout = 正在掃描...檢查您桌面的防火牆配置 RemoteISOWifi = 注意:將兩個設備都連接到同一Wi-Fi網絡 -RemoteISOWinFirewall = 警告:Windows 防火牆阻止共享 +RemoteISOWinFirewall = 警告:Windows防火牆阻止共享 Settings = 設定值 Share Games (Server) = 分享遊戲(服務器) -Share on PPSSPP startup = 分享 PPSSPP 啟動 +Share on PPSSPP startup = 分享PPSSPP啟動 Stop Sharing = 停止分享 Stopping.. = 正在停止... [Reporting] Bad = 壞 -FeedbackCRCCalculating = 光碟 CRC: 計算中... -FeedbackCRCValue = 光碟 CRC: %1 +FeedbackCRCCalculating = 光碟CRC: 計算中... +FeedbackCRCValue = 光碟CRC: %1 FeedbackDelayInfo = 您的數據正在後台提交. FeedbackDesc = 模擬的效果怎麼樣?說給我們聽聽! FeedbackDisabled = 兼容性服務器報告必須啟用. -FeedbackIncludeCRC = 注意:電池將用於發送光盤 CRC +FeedbackIncludeCRC = 注意:電池將用於發送光盤CRC FeedbackIncludeScreen = 包括屏幕截圖 FeedbackSubmitDone = 您的數據已提交. -FeedbackSubmitFail = 無法將數據提交到服務器。 嘗試更新 PPSSPP。 +FeedbackSubmitFail = 無法將數據提交到服務器。 嘗試更新PPSSPP。 FeedbackThanks = 感謝您的反饋意見! Gameplay = 遊戲過程 Graphics = 圖形 @@ -951,17 +957,17 @@ Perfect Description = 完美模擬整個游戲 - 太棒了! Plays = 可玩 Plays Description = 基本模擬整個游戲,但有時會出現故障 ReportButton = 報告反饋 -Show disc CRC = 顯示光碟 CRC +Show disc CRC = 顯示光碟CRC Speed = 速度 Submit Feedback = 提交反饋 SuggestionConfig = 請參閱網站上的報告以了解正確的配置。 -SuggestionCPUSpeed0 = 禁用鎖定的 CPU 速度配置。 -SuggestionDowngrade = 降級到較舊的 PPSSPP 版本(請報告此錯誤)。 +SuggestionCPUSpeed0 = 禁用鎖定的CPU速度配置。 +SuggestionDowngrade = 降級到較舊的PPSSPP版本(請報告此錯誤)。 SuggestionsFound = 其他用戶報告了更好的結果。 點擊“查看反饋”以獲取更多詳細信息。 SuggestionsNone = 其他用戶也不能運行該游戲。 SuggestionsWaiting = 提交並檢查其他用戶的反饋... -SuggestionUpgrade = 升級到更新的 PPSSPP 版本。 -SuggestionVerifyDisc = 檢查您的 ISO 是否是光盤的良好副本。 +SuggestionUpgrade = 升級到更新的PPSSPP版本。 +SuggestionVerifyDisc = 檢查您的ISO是否是光盤的良好副本。 Unselected Overall Description = 這個遊戲的模擬效果如何? View Feedback = 查看所有反饋 @@ -978,12 +984,12 @@ Showing matches for '%1'. = 找到符合'%1'的搜尋結果。 Size = 大小 [Screen] -Cardboard VR OFF = Cardboard VR 關閉 -Chainfire3DWarning = 警告:偵測到 Chainfire3D,可能造成問題 +Cardboard VR OFF = Cardboard VR關閉 +Chainfire3DWarning = 警告:偵測到Chainfire3D,可能造成問題 Failed to load state = 無法載入快速存檔 Failed to save state = 無法儲存快速存檔 fixed = 速度:固定 -GLToolsWarning = 警告:偵測到 GLTools,可能造成問題 +GLToolsWarning = 警告:偵測到GLTools,可能造成問題 In menu = In menu Load savestate failed = 無法載入快速存檔 Loaded State = 已載入即時存檔 @@ -991,10 +997,10 @@ Loaded. Game may refuse to save over different savedata. = 已加載。游戲可 Loaded. Game may refuse to save over newer savedata. = 已加載。游戲可能無法保存在進度提前的存檔。 Loaded. Save in game, restart, and load for less bugs. = 已加載。 保存在遊戲中,重新啟動並加載,以減少錯誤。 LoadStateDoesntExist = 無法載入:存檔不存在! -LoadStateWrongVersion = 無法載入:存檔為舊版的 PPSSPP 的! +LoadStateWrongVersion = 無法載入:存檔為舊版的PPSSPP的! norewind = 倒带即時存檔不可用 Playing = 游戲中 -PressESC = 按下 ESC 鍵以暫停遊戲 +PressESC = 按下ESC鍵以暫停遊戲 replaceTextures_false = 不再替換紋理. replaceTextures_true = 啟用紋理替換. Save State Failed = 即時存檔失敗! @@ -1029,7 +1035,7 @@ Uninstall = 解除安裝 (none detected) = (未檢測到) 3D API = 3D API ABI = ABI -API Version = API 版本 +API Version = API版本 Audio Information = 音頻信息 Board = 主板 Build Config = 編譯配置 @@ -1037,10 +1043,10 @@ Build Configuration = 編譯配置 Built by = 編譯者 Core Context = 核心上下文 Cores = 核心數 -CPU Extensions = CPU 擴展 -CPU Information = CPU 信息 -CPU Name = CPU 名稱me -D3DCompiler Version = D3DCompiler 版本 +CPU Extensions = CPU擴展 +CPU Information = CPU信息 +CPU Name = CPU名稱 +D3DCompiler Version = D3DCompiler版本 Debug = 調試 Debugger Present = 調試器已連接 Device Info = 設備信息 @@ -1048,25 +1054,25 @@ Directories = 路徑 Display Color Formats = 顯示顔色格式 Display Information = 顯示信息 Driver Version = 驅動程序版本 -EGL Extensions = EGL 擴展 +EGL Extensions = EGL擴展 Frames per buffer = 每緩存區幀數 -GPU Information = GPU 信息 +GPU Information = GPU信息 High precision float range = 高精度浮點範圍 High precision int range = 高精度整數範圍 Lang/Region = 語言/區域 Memory Page Size = 内存頁大小 Native Resolution = 原生分辨率 OGL Extensions = OGL 擴展 -OpenGL ES 2.0 Extensions = OpenGL ES 2.0 擴展 -OpenGL ES 3.0 Extensions = OpenGL ES 3.0 擴展 -OpenGL Extensions = OpenGL 擴展 +OpenGL ES 2.0 Extensions = OpenGL ES 2.0擴展 +OpenGL ES 3.0 Extensions = OpenGL ES 3.0擴展 +OpenGL Extensions = OpenGL擴展 Optimal frames per buffer = 最佳每緩存區幀數 Optimal sample rate = 最佳采樣率 -OS Information = OS 信息 -PPSSPP build = PPSSPP 編譯版本 +OS Information = OS信息 +PPSSPP build = PPSSPP編譯版本 Refresh rate = 刷新率 Release = 發佈 -RW/RX exclusive = RW/RX 獨占 +RW/RX exclusive = RW/RX獨占 Sample rate = 采樣率 Shading Language = 著色語言 Storage = 存儲 @@ -1078,10 +1084,10 @@ Threads = 綫程數 Vendor = 供應商 Vendor (detected) = 供應商 (已檢測到的) Version Information = 版本信息 -Vulkan Extensions = Vulkan 擴展 -Vulkan Features = Vulkan 特性 +Vulkan Extensions = Vulkan擴展 +Vulkan Features = Vulkan特性 Driver bugs = 驅動錯誤 -No GPU driver bugs detected = 未檢測到 GPU 驅動錯誤 +No GPU driver bugs detected = 未檢測到GPU驅動錯誤 [System] (broken) = (壞了) @@ -1089,17 +1095,17 @@ No GPU driver bugs detected = 未檢測到 GPU 驅動錯誤 24HR = 24小時 Auto = 自動 Auto Load Savestate = 自動加載保存狀態 -AVI Dump started. = AVI 轉儲開始 -AVI Dump stopped. = AVI 轉儲停止 -Cache ISO in RAM = 將整個 ISO 檔暫存於記憶體中 -Change CPU Clock = 調整 CPU 時鐘 (不穩定) +AVI Dump started. = AVI轉儲開始 +AVI Dump stopped. = AVI轉儲停止 +Cache ISO in RAM = 將整個ISO檔暫存於記憶體中 +Change CPU Clock = 調整CPU時鐘(不穩定) Color Tint = 色調 Color Saturation = 顔色飽和度 Error: load undo state is from a different game = 錯誤: 撤回的即時存檔來自不同游戲 Failed to load state for load undo. Error in the file system. = 無法撤銷加載的即時存檔,文件系統有錯誤。 Floating symbols = 漂浮的符號 Memory Stick folder = 更改記憶棒文件夾 -Memory Stick size = 更改記憶棒大小 (GB) +Memory Stick size = 更改記憶棒大小(GB) Change Nickname = 更改別名 ChangingMemstickPath = 游戲存檔、即時存檔以及其他數據不會被複製到新路徑。\n\n確定要修改記憶棒文件嗎? ChangingMemstickPathInvalid = 目標路徑不能用於保存記憶棒數據。 @@ -1117,39 +1123,39 @@ Display Extra Info = 顯示額外信息 Display Games on a grid = 以方格顯示“游戲” Display Homebrew on a grid = 以方格顯示 "自製游戲" Display Recent on a grid = 以方格顯示最近的游戲 -Dynarec (JIT) = 動態重編譯 (JIT) +Dynarec (JIT) = 動態重編譯(JIT) Emulation = 模擬 Enable Cheats = 啓用金手指 Enable Compatibility Server Reports = 向伺服器回報相容性問題 Failed to load state. Error in the file system. = 無法讀取即時存檔。檔案系統錯誤。 Failed to save state. Error in the file system. = 無法儲存即時存檔。檔案系統錯誤。 Fast (lag on slow storage) = 快速 (存取較慢的系統仍會延遲) -Fast Memory = 快速記憶體存取 (不穩定) -Force real clock sync (slower, less lag) = 強制實際時鐘同步 (速度較慢,但較少延遲) +Fast Memory = 快速記憶體存取(不穩定) +Force real clock sync (slower, less lag) = 強制實際時鐘同步(速度較慢,但較少延遲) frames, 0:off = 幀,0 = 關閉 Games list settings = 游戲列表配置 General = 一般 Grid icon size = 倍率圖標尺寸 -Help the PPSSPP team = 幫助 PPSSPP 團隊 -Host (bugs, less lag) = 主機 (較少延遲,但可能造成問題;有助於魔法少女小圓) +Help the PPSSPP team = 幫助PPSSPP團隊 +Host (bugs, less lag) = 主機(較少延遲,但可能造成問題;有助於魔法少女小圓) Ignore bad memory accesses = 忽略錯誤的內存訪問 Increase size = 增加大小 Interpreter = 解釋器 -IO timing method = I/O 計時方法 -IR Interpreter = IR 解釋器 +IO timing method = I/O計時方法 +IR Interpreter = IR解釋器 Memory Stick Folder = 記憶棒文件夾 Memory Stick inserted = 插入記憶棒 -MHz, 0:default = MHz,預設為 0 +MHz, 0:default = MHz,預設為0 MMDDYYYY = MMDDYYYY Moving background = 動態壁紙 Newest Save = 最新存礑 No animation = 靜態壁紙 -Not a PSP game = 不是 PSP 遊戲 +Not a PSP game = 不是PSP遊戲 Off = 關閉 Oldest Save = 最早存礑 Path does not exist! = 路徑不存在! -PSP Memory Stick = PSP 記憶棒 -PSP Model = PSP 機型 +PSP Memory Stick = PSP記憶棒 +PSP Model = PSP機型 PSP Settings = PSP 設定 PSP-1000 = PSP-1000 PSP-2000/3000 = PSP-2000/3000 @@ -1159,35 +1165,35 @@ Record Display = 錄製畫面 Reset Recording on Save/Load State = 在保存/加載狀態下重置記錄 Restore Default Settings = 還原出廠設定 Rewind Snapshot Frequency = 快照倒回頻率 -Save path in installed.txt = 存檔路徑在 installed.txt +Save path in installed.txt = 存檔路徑在installed.txt Save path in My Documents = 存檔路徑在我的文件 Savestate Slot = 即時存檔插槽 Savestate slot backups = 即時存檔插槽備份 -Screenshots as PNG = PNG 格式截圖 +Screenshots as PNG = PNG格式截圖 Set UI background... = 配置UI背景... -Show ID = 顯示 ID +Show ID = 顯示ID Show Memory Stick folder = 顯示記憶棒文件夾 Show region flag = 顯示區域標誌 -Simulate UMD delays = 模擬 UMD 延遲 (修正紙箱戰機W) -Slot 1 = 插槽 1 -Slot 2 = 插槽 2 -Slot 3 = 插槽t 3 -Slot 4 = 插槽 4 -Slot 5 = 插槽 5 +Simulate UMD delays = 模擬UMD延遲(修正紙箱戰機W) +Slot 1 = 插槽1 +Slot 2 = 插槽2 +Slot 3 = 插槽3 +Slot 4 = 插槽4 +Slot 5 = 插槽5 Storage full = 存儲容量已滿 Sustained performance mode = 持續性能模式 Theme = 主題 Time Format = 時間格式 UI = 用戶界面 -UI background animation = UI 背景效果 +UI background animation = UI背景效果 UI Sound = 介面聲音 undo %c = 備用 %c USB = USB -Use Lossless Video Codec (FFV1) = 使用無損視訊轉碼器 (FFV1) -Use O to confirm = 使用 O 確認 +Use Lossless Video Codec (FFV1) = 使用無損視訊轉碼器(FFV1) +Use O to confirm = 使用O確認 Use output buffer (with overlay) for recording =使用輸出緩衝區(帶有覆蓋)進行記錄 Use system native keyboard = 使用系統本機鍵盤 -Use X to confirm = 使用 X 確認 +Use X to confirm = 使用X確認 VersionCheck = 檢查 PPSSPP 新版本 WARNING: Android battery save mode is on = 警告:Android省電模式已開啟 WARNING: Battery save mode is on = 警告:省電模式已開啟 @@ -1199,7 +1205,7 @@ Show Memory Stick folder = 顯示記憶棒文件夾 [TextureShaders] Off = 關閉 TexMMPX = TexMMPX -Tex2xBRZ = Tex2xBRZ +Tex2xBRZ = Tex2xBRZ Tex4xBRZ = Tex4xBRZ [Themes] @@ -1220,11 +1226,11 @@ Screen representation = 屏幕表現 Details = 詳情 Dismiss = 忽略 Download = 下載 -New version of PPSSPP available = 已有新版的 PPSSPP +New version of PPSSPP available = 已有新版的PPSSPP [Search] Filtering settings by '%1' = 配置篩選 '%1' Find settings = 搜索配置 Filter = 篩選 Clear filter = 清楚篩選 -No settings matched '%1' = 未找到配置 '%1' +No settings matched '%1' = 未找到配置 '%1' From 15f5ed81a72a987af8064f8798f5b09b4980369d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 15 Jul 2022 11:43:49 +0200 Subject: [PATCH 15/57] Add a simple compat flag to workaround the Clone Wars issue, #12949 Could probably also be fixed by changing the heuristic a bit, but since we're in heuristic land anyway and close to a release, I feel this is the safest option. Also sneaks in a logspam reduction --- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + Core/HLE/sceMpeg.cpp | 3 ++- GPU/Common/TextureCacheCommon.cpp | 2 +- assets/compat.ini | 6 ++++++ 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 813e324970..984af5632b 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -95,6 +95,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "CenteredLines", &flags_.CenteredLines); CheckSetting(iniFile, gameID, "MaliDepthStencilBugWorkaround", &flags_.MaliDepthStencilBugWorkaround); CheckSetting(iniFile, gameID, "ZZT3SelectHack", &flags_.ZZT3SelectHack); + CheckSetting(iniFile, gameID, "AllowLargeFBTextureOffsets", &flags_.AllowLargeFBTextureOffsets); } void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { diff --git a/Core/Compatibility.h b/Core/Compatibility.h index da9a1f79c0..43dc651a23 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -85,6 +85,7 @@ struct CompatFlags { bool CenteredLines; bool MaliDepthStencilBugWorkaround; bool ZZT3SelectHack; + bool AllowLargeFBTextureOffsets; }; class IniFile; diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 84be05710b..3efd2320ef 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1962,7 +1962,8 @@ static u32 sceMpegAvcCopyYCbCr(u32 mpeg, u32 sourceAddr, u32 YCbCrAddr) return -1; } - WARN_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x)", mpeg, sourceAddr, YCbCrAddr); + // This is very common. + DEBUG_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x)", mpeg, sourceAddr, YCbCrAddr); return 0; } diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index b41aa69264..b45ea56299 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -975,7 +975,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( // Trying to play it safe. Below 0x04110000 is almost always framebuffers. // TODO: Maybe we can reduce this check and find a better way above 0x04110000? - if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { + if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000 && !PSP_CoreParameter().compat.flags().AllowLargeFBTextureOffsets) { WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } diff --git a/assets/compat.ini b/assets/compat.ini index 8485ca6391..4d4b40b3af 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1239,3 +1239,9 @@ NPJH50907 = true UCAS40328 = true ULJS19050 = true NPJH50907 = true + +[AllowLargeFBTextureOffsets] +# Quickfix for Clone Wars, see #12949 +ULES01284 = true +ULES01285 = true +ULUS10477 = true From 560419671a8399e802a605314bc2620b55e741a8 Mon Sep 17 00:00:00 2001 From: leoxxx <5364709+leoxxx@users.noreply.github.com> Date: Fri, 15 Jul 2022 18:34:51 +0800 Subject: [PATCH 16/57] Update zh_CN.ini --- assets/lang/zh_CN.ini | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index d2c0ca600e..05bc0ee8cb 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -60,7 +60,7 @@ HapticFeedback = 按键反馈(震动) Hide touch analog stick background circle = 隐藏触屏摇杆的背景圈 Icon = 图标 Ignore gamepads when not focused = 后台运行时忽略游戏手柄 -Ignore Windows Key = 忽略 Windows 键 +Ignore Windows Key = 忽略Windows键 Invert Axes = 轴反转 Invert Tilt along X axis = 沿X轴倾斜反转 Invert Tilt along Y axis = 沿Y轴倾斜反转 @@ -74,7 +74,7 @@ Low end radius = 末端半径 Mouse = 鼠标设置 Mouse sensitivity = 鼠标灵敏度 Mouse smoothing = 鼠标平滑度 -MouseControl Tip = 您可以在按键映射界面按下"M"图标来映射鼠标按键。 +MouseControl Tip = 您可以在按键映射界面按下'M'图标来映射鼠标按键。 None (Disabled) = 无(禁用) Off = 关闭 OnScreen = 屏幕虚拟按键 @@ -173,7 +173,7 @@ Log Console = 控制台日志 (&L) Memory View... = 查看内存 (&V)... More Settings... = 更多设置 (&M)... Nearest = 邻近取样 (&N) -Non-Buffered Rendering = 跳过缓冲效果 (非缓冲, 更快) (&S) +Non-Buffered Rendering = 跳过缓冲效果(非缓冲, 更快) (&S) Off = 关闭 (&O) Open Chat = 打开聊天 Open Directory... = 打开路径(&D)... @@ -480,7 +480,7 @@ Camera Device = 摄像头设备 Cardboard Screen Size = 屏幕大小(视区%) Cardboard Screen X Shift = 水平 % Cardboard Screen Y Shift = 垂直 % -Cardboard VR Settings = Google Cardboard VR 设置 +Cardboard VR Settings = Google Cardboard VR设置 Cheats = 金手指 CPU Core = CPU 核心模式 Debugging = 调试设置 @@ -542,7 +542,7 @@ Render duplicate frames to 60hz = 渲染重复帧至60Hz RenderDuplicateFrames Tip = 在较低帧率的游戏中可以使帧速率更平滑 Rendering Mode = 渲染模式 Rendering Resolution = 渲染分辨率 -RenderingMode NonBuffered Tip = 更快, 但可能在某些游戏中丢失特效 +RenderingMode NonBuffered Tip = 更快,但可能在某些游戏中丢失特效 Retain changed textures = 保留已更改的纹理(有时更慢) RetainChangedTextures Tip = 使较多游戏减速, 但有些游戏可能变快很多 Rotation = 旋转 @@ -554,7 +554,7 @@ Show FPS Counter = 显示FPS计数器 Simulate Block Transfer = 模拟数据块传输效果 Software Rendering = 软件渲染(慢) Software Skinning = 软件蒙皮 -SoftwareSkinning Tip = 合并CPU中已经蒙皮的模型绘制, 在部分游戏中更快 +SoftwareSkinning Tip = 合并CPU中已经蒙皮的模型绘制,在部分游戏中更快 Speed = 运行速度 Stretching = 拉伸 Texture Filter = 纹理过滤方式 @@ -570,7 +570,7 @@ Upscale Type = 纹理缩放方式 UpscaleLevel Tip = CPU重负载-为避免卡顿, 某些缩放可能会延迟 Use all displays = 使用全部显示器 Vertex Cache = 顶点缓存 -VertexCache Tip = 更快, 但可能会造成暂时的闪烁 +VertexCache Tip = 更快,但可能会造成暂时的闪烁 VSync = 垂直同步 Vulkan = Vulkan Window Size = 窗口大小 @@ -948,7 +948,7 @@ OK = 好 Open Browser = 打开报告网站 Overall = 总体 Perfect = 完美 -Perfect Description = 完美模拟整个游戏 - 太棒了! +Perfect Description = 完美模拟整个游戏-太棒了! Plays = 可玩 Plays Description = 基本模拟整个游戏, 但有时会出现故障 ReportButton = 报告反馈 @@ -984,7 +984,7 @@ Chainfire3DWarning = 警告:检测到Chainfire3D(3D 神器), 可能会导致 Failed to load state = 无法载入即时存档 Failed to save state = 无法保存即时存档 fixed = 速度:自定义 -GLToolsWarning = 警告:检测到GLTools, 可能会导致问题。 +GLToolsWarning = 警告:检测到GLTools,可能会导致问题。 In menu = 在菜单中 Load savestate failed = 无法载入即时存档 Loaded State = 已载入即时存档 @@ -1089,7 +1089,7 @@ Cache ISO in RAM = 在内存中缓存完整ISO Change CPU Clock = 修改模拟的PSP的CPU频率(不稳定) Color Tint = 颜色色调 Color Saturation = 颜色饱和度 -Error: load undo state is from a different game = 错误: 撤回的即时存档是来自不同游戏的 +Error: load undo state is from a different game = 错误:撤回的即时存档是来自不同游戏的 Failed to load state for load undo. Error in the file system. = 无法撤回加载即时存档。文件系统有错误。 Floating symbols = 飘浮的按键 Memory Stick folder = 记忆棒文件夹 @@ -1120,12 +1120,12 @@ Failed to save state. Error in the file system. = 无法保存即时存档。文 Fast (lag on slow storage) = 快速(在低速存储会有延迟) Fast Memory = 快速内存(不稳定) Force real clock sync (slower, less lag) = 强制同步实际时钟频率(慢,但是更少延迟) -frames, 0:off = 每几帧, 0 = 关 +frames, 0:off = 每几帧, 0=关 Games list settings = 游戏列表设置 General = 常规设置 Grid icon size = 按倍率的图标尺寸 -Help the PPSSPP team = 帮助 PPSSPP 团队 -Host (bugs, less lag) = 主机(较少延迟, 有错误) +Help the PPSSPP team = 帮助PPSSPP团队 +Host (bugs, less lag) = 主机(较少延迟,有错误) Ignore bad memory accesses = 忽略错误的内存访问 Increase size = 增大尺寸 Interpreter = 解释器 From 19c8ae4cddf250a5d47fe20b961fbe0c71b2f81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 16 Jul 2022 10:58:37 +0200 Subject: [PATCH 17/57] Use the recent Clone Wars fix for Star Wars: Force Unleashed too We should probably reconsider the heuristic indeed. Fixes #9572 See #15691 --- assets/compat.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 4d4b40b3af..9d582ae1bd 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1245,3 +1245,10 @@ NPJH50907 = true ULES01284 = true ULES01285 = true ULUS10477 = true + +# Star Wars: The Force Unleashed +ULUS10345 = true +ULKS46143 = true +ULES00981 = true +ULES00982 = true +LBSW10345 = true # Some modded version found in our report logs From 96b86907c205b80ef5cfd5478ab4ded879e7c606 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Jul 2022 09:43:12 -0700 Subject: [PATCH 18/57] Debugger: Fix SVG content-type for proper display. --- Core/WebServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index a55b298ed2..1defdd1c6a 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -248,7 +248,7 @@ static bool ServeDebuggerFile(const http::Request &request) { } else if (ext == ".js") { mimeType = "application/javascript"; } else if (ext == ".svg") { - mimeType = "image/svg"; + mimeType = "image/svg+xml"; } else if (ext == ".png") { mimeType = "image/png"; } else if (ext == ".css") { From 879ea030806d0d7548fa33c289b50e6f8aa37343 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Jul 2022 12:58:09 -0700 Subject: [PATCH 19/57] Debugger: Update to latest web debugger. This includes dependency updates, minor UI fixes, and a breakpoint persistence option. --- assets/debugger | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/debugger b/assets/debugger index 36ad6b19b2..9776332f72 160000 --- a/assets/debugger +++ b/assets/debugger @@ -1 +1 @@ -Subproject commit 36ad6b19b22de2075a01a4f0c765e3ef514dc38f +Subproject commit 9776332f720c854ef26f325a0cf9e32c02115a9c From 3ccbb51e43b7cf967d70cc5676ad5fdf7a2d3cfc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Jul 2022 17:47:31 -0700 Subject: [PATCH 20/57] Osk: Allow upper/lower for all keyboards. In previous tests, this seemed to be limited, but now I can't reproduce. Instead, let's just use it as the hint for the default case. See #15010. --- Core/Dialog/PSPOskDialog.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index c243e78a6b..8eb37918ce 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -148,6 +148,17 @@ static const char16_t oskKeys[OSK_KEYBOARD_COUNT][6][14] = // This isn't a complete representation of these flags, it just helps ensure we show the right keyboards. int allowedInputFlagsMap[OSK_KEYBOARD_COUNT] = { + PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HIRAGANA, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_KATAKANA | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HALF_KATAKANA, + PSP_UTILITY_OSK_INPUTTYPE_KOREAN, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_UPPERCASE, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_UPPERCASE, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_DIGIT, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL, +}; +int defaultInputFlagsMap[OSK_KEYBOARD_COUNT] = { PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT, PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL, PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HIRAGANA, @@ -249,11 +260,17 @@ static void FindValidKeyboard(s32 inputType, int direction, OskKeyboardLanguage if (inputType == 0) { return; } + // We use direction = 0 for default, but we actually move "forward". + int *matchMap = allowedInputFlagsMap; + if (direction == 0) { + direction = 1; + matchMap = defaultInputFlagsMap; + } // TODO: Limit by allowed keyboards properly... this is just an approximation. int tries = OSK_LANGUAGE_COUNT * 2; - while (!(inputType & allowedInputFlagsMap[disp]) && tries > 0) { - if ((--tries % 1) == 0) { + while (!(inputType & matchMap[disp]) && tries > 0) { + if ((--tries % 2) == 0) { lang = (OskKeyboardLanguage)((OSK_LANGUAGE_COUNT + lang + direction) % OSK_LANGUAGE_COUNT); disp = OskKeyboardCases[lang][LOWERCASE]; } else { @@ -312,7 +329,7 @@ int PSPOskDialog::Init(u32 oskPtr) { selectedChar = 0; currentKeyboardLanguage = OSK_LANGUAGE_ENGLISH; currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE; - FindValidKeyboard(oskParams->fields[0].inputtype, 1, currentKeyboardLanguage, currentKeyboard); + FindValidKeyboard(oskParams->fields[0].inputtype, 0, currentKeyboardLanguage, currentKeyboard); ConvertUCS2ToUTF8(oskDesc, oskParams->fields[0].desc); ConvertUCS2ToUTF8(oskIntext, oskParams->fields[0].intext); From 1fd80646cb7a7108c36e4b960c6282990619b727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 17 Jul 2022 22:50:37 +0200 Subject: [PATCH 21/57] Mali driver bug workaround for driver 32+. See #15661 Hope this small bias won't break things. --- Common/GPU/Vulkan/thin3d_vulkan.cpp | 8 ++++++++ Common/GPU/thin3d.cpp | 1 + Common/GPU/thin3d.h | 1 + GPU/Common/VertexShaderGenerator.cpp | 3 +++ 4 files changed, 13 insertions(+) diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 88c4ee90d5..41edd287c4 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -825,6 +825,14 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) bugs_.Infest(Bugs::EQUAL_WZ_CORRUPTS_DEPTH); // At least one driver at the upper end of the range is known to be likely to suffer from the bug causing issue #13833 (Midnight Club map broken). bugs_.Infest(Bugs::MALI_STENCIL_DISCARD_BUG); + + // This started in driver 31 or 32. + if (VK_API_VERSION_MAJOR(deviceProps.driverVersion) >= 32) { + NOTICE_LOG(G3D, "Driver version %08x infested: major=%d", deviceProps.driverVersion, VK_API_VERSION_MAJOR(deviceProps.driverVersion)); + bugs_.Infest(Bugs::MALI_CONSTANT_LOAD_BUG); // See issue #15661 + } else { + NOTICE_LOG(G3D, "Driver version %08x not infested: major=%d", deviceProps.driverVersion, VK_API_VERSION_MAJOR(deviceProps.driverVersion)); + } } caps_.deviceID = deviceProps.deviceID; diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index 42349b4991..b5a2b89c2c 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -630,6 +630,7 @@ const char *Bugs::GetBugName(uint32_t bug) { case EQUAL_WZ_CORRUPTS_DEPTH: return "EQUAL_WZ_CORRUPTS_DEPTH"; case MALI_STENCIL_DISCARD_BUG: return "MALI_STENCIL_DISCARD_BUG"; case RASPBERRY_SHADER_COMP_HANG: return "RASPBERRY_SHADER_COMP_HANG"; + case MALI_CONSTANT_LOAD_BUG: return "MALI_CONSTANT_LOAD_BUG"; default: return "(N/A)"; } } diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 45de0cc10c..7cccf0fd55 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -324,6 +324,7 @@ public: EQUAL_WZ_CORRUPTS_DEPTH = 7, MALI_STENCIL_DISCARD_BUG = 8, RASPBERRY_SHADER_COMP_HANG = 9, + MALI_CONSTANT_LOAD_BUG = 10, MAX_BUG, }; diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index a8f56be181..52624b6dcc 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -1052,6 +1052,9 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, " %sv_color0 = color0;\n", compat.vsOutPrefix); } else { WRITE(p, " %sv_color0 = u_matambientalpha;\n", compat.vsOutPrefix); + if (bugs.Has(Draw::Bugs::MALI_CONSTANT_LOAD_BUG) && g_Config.bVendorBugChecksEnabled) { + WRITE(p, " %sv_color0.r += 0.000001;\n", compat.vsOutPrefix); + } } if (lmode) WRITE(p, " %sv_color1 = splat3(0.0);\n", compat.vsOutPrefix); From 2933ace02fe72665603ce51cb3498a0d783c92cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 17 Jul 2022 23:03:43 +0200 Subject: [PATCH 22/57] Remove log noise --- Common/GPU/Vulkan/thin3d_vulkan.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 41edd287c4..7f18daba4e 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -828,10 +828,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) // This started in driver 31 or 32. if (VK_API_VERSION_MAJOR(deviceProps.driverVersion) >= 32) { - NOTICE_LOG(G3D, "Driver version %08x infested: major=%d", deviceProps.driverVersion, VK_API_VERSION_MAJOR(deviceProps.driverVersion)); bugs_.Infest(Bugs::MALI_CONSTANT_LOAD_BUG); // See issue #15661 - } else { - NOTICE_LOG(G3D, "Driver version %08x not infested: major=%d", deviceProps.driverVersion, VK_API_VERSION_MAJOR(deviceProps.driverVersion)); } } From f12e194cb2fe8008d2ea9733277459d176fec26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 18 Jul 2022 11:03:02 +0200 Subject: [PATCH 23/57] Main screen: Display .ppdmp filenames on buttons in grid mode Makes it a bit easier to pick them out and doesn't make them look quite as broken. --- UI/MainScreen.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 8b5fbb08f4..900fd17ad2 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -322,7 +322,17 @@ void GameButton::Draw(UIContext &dc) { dc.Draw()->Flush(); dc.RebindTexture(); dc.SetFontStyle(dc.theme->uiFont); - if (!gridStyle_) { + if (gridStyle_ && ginfo->fileType == IdentifiedFileType::PPSSPP_GE_DUMP) { + // Super simple drawing for ge dumps. + dc.PushScissor(bounds_); + const std::string currentTitle = ginfo->GetTitle(); + dc.SetFontScale(0.6f, 0.6f); + dc.DrawText(title_.c_str(), bounds_.x + 4.0f, bounds_.centerY(), style.fgColor, ALIGN_VCENTER | ALIGN_LEFT); + dc.SetFontScale(1.0f, 1.0f); + title_ = currentTitle; + dc.Draw()->Flush(); + dc.PopScissor(); + } else if (!gridStyle_) { float tw, th; dc.Draw()->Flush(); dc.PushScissor(bounds_); From b57a79c9c96bfee9a4da83a9dad97b631da228cb Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Mon, 18 Jul 2022 22:14:17 -0400 Subject: [PATCH 24/57] Prevent dummy file from being in the package. --- UWP/CommonUWP/CommonUWP.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 90eb76d7a5..980aed9b8b 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -632,6 +632,7 @@ + false From 98727756b45fc6e95cd763a6e4bee35d62fb13f2 Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Mon, 18 Jul 2022 22:15:54 -0400 Subject: [PATCH 25/57] Remove redundant file from package. --- UWP/UWP.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 6ddbadb3b0..d955bbb1b9 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -495,7 +495,7 @@ - true + false true @@ -1772,4 +1772,4 @@ - \ No newline at end of file + From 26850d80f0185ad553545d8584cd5a3a36e2c679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 Jul 2022 16:58:57 +0200 Subject: [PATCH 26/57] Remove a redundant mutex lock in logging. Really can't see any purpose at all... Weird. --- Common/LogManager.cpp | 1 - Common/LogManager.h | 1 - 2 files changed, 2 deletions(-) diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 969de62629..cdcb224667 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -234,7 +234,6 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const file = fileshort + 1; } - std::lock_guard lk(log_lock_); GetTimeFormatted(message.timestamp); if (hleCurrentThreadName) { diff --git a/Common/LogManager.h b/Common/LogManager.h index 805c48c5f8..65423b6121 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -122,7 +122,6 @@ private: RingbufferLogListener *ringLog_ = nullptr; static LogManager *logManager_; // Singleton. Ugh. - std::mutex log_lock_; std::mutex listeners_lock_; std::vector listeners_; From 989d5b8079682789fe2aa7cd733004b5285b61df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 Jul 2022 17:57:13 +0200 Subject: [PATCH 27/57] Revert "(UWP) Small Building Tweaks." --- UWP/CommonUWP/CommonUWP.vcxproj | 1 - UWP/UWP.vcxproj | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 980aed9b8b..90eb76d7a5 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -632,7 +632,6 @@ - false diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index d955bbb1b9..6ddbadb3b0 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -495,7 +495,7 @@ - false + true true @@ -1772,4 +1772,4 @@ - + \ No newline at end of file From d017437fb7785ac2ef758aeab4eb101ec04171dd Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 13:23:09 -0400 Subject: [PATCH 28/57] Prevent Dummy file from appearing in packages. --- UWP/CommonUWP/CommonUWP.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 90eb76d7a5..fa40f7130c 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -631,7 +631,7 @@ - + From bd1eefdda2222038cdd6f04d4d8f215b48e52314 Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 13:24:08 -0400 Subject: [PATCH 29/57] Remove redundant file from packages. --- UWP/UWP.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 6ddbadb3b0..d955bbb1b9 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -495,7 +495,7 @@ - true + false true @@ -1772,4 +1772,4 @@ - \ No newline at end of file + From c432af3fcc202f7d2e509df81f8ed806640b41cc Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 20:33:58 -0400 Subject: [PATCH 30/57] (UWP) Building Improvements --- UWP/PPSSPP_UWP_TemporaryKey.pfx | Bin 2520 -> 2520 bytes UWP/Package.appxmanifest | 15 +++++++++++++++ UWP/PackageGold.appxmanifest | 2 +- UWP/PackageNormal.appxmanifest | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 UWP/Package.appxmanifest diff --git a/UWP/PPSSPP_UWP_TemporaryKey.pfx b/UWP/PPSSPP_UWP_TemporaryKey.pfx index a7ffbad86017a6dcc26a9e41a9d00fbb28488520..0d737acfe6d5fa2f9da43235e39ff9b2310ff61e 100644 GIT binary patch delta 2267 zcmV<12qgE|6W9}wXn%KkgX5rn(VYSU2haq91lW}gE9wXuU>LW7!&{GSU3?$`N^5GU zsn57nuN83N#A)-ei1N}lN_CUQgmCB~B1P+#(&NZ^} zZ}T+FB*1BlpHSDa)c_C;Eor-0R3JbC>txlw$RNB1G%5+VPO#gzYNbx3l zZ`JCobaz4F3ptlPk>@z7TeL36D2{LBhx>AfZ14bHtvU(ov;rTlY%7;#B|oc)|phwLEQlTZ48dFAyh)svi)@tyx`!iWJHmx#{P!70D;fFUq-R)~bRR^==1gjudIyLIcnVPh)MF0@03s4aq zy)uTm;d{wP1jwnyIwS_#)v6%pt2`zE)VIBPe{xS5STSu*dCf;ixtLKEfSGer4f1Wj z<-{3lnSY%9UH3xr@GIbbuHJV|3BL&@^on-u`cyAyjhVWr(@OVhq{W`i^qqk$A`nJN z)JV(7dNpcqwkC)b?mv+xBvQOKxFvbHVY+)yKTWB-0hfBgJ~W< z@ylZ)=ocRoiQ)aR4riO+=eUsa#mxJn*nhnQSy?eEvP5$Lv9t%ZI`{Nt^CDNDr-!hp z+JB0{ON$#f^G=(yhn3;1kPFnw1h1smF1h0A!`rB`xJHs9`7BUuuf5O;ACa?Zc5vnO zSj=dU@SVo<1{-pPp6tv28pcur*Dxq7WmmbAGKQ5wEF!$o7DJMj$AxSzTZ~m9n!ZwH z1B4EEw#;upUy8rxjLXmnofvUv%HuUUihtEG{;TfE%~=|VF7wO!iFH)$lgOW2Lr}5O ze$sAfl^WjU9;hh2H%H;Qb&V*l@~G(UJ|rlvQ2(qEdqG&LU?7jzQVdY3moIv9d<>bL zDwQi8cN{QUMJ4jR}8ZHdhF49*Ah*=f&M>cdqmp3H3gv=MBOyq=BltrK=%19-W7q8+uxr4CiH!&BqPAm z1_gi+xzNT5ZXleTwNHoM>M9stD?+~nV6{|e^}r8Cy8_LBB9ci0I%UsFH=dn`9tTYE z|575BBw~ZhrR3&`8E>f7njc>VI)Ct&*dg3Lv>I{eU0EGZ!wRp-W|3l3?9Tcj)%_#( z|Aex4n1PoSo*Ct>MtCq|(RA1({stj(iC-deV=&LNQUQF#u)&VgM}wWdJe&HUKaHEdVqCV*oM$HUKREVgO?RH~=>QEdXNxGXOFG zVE|+RV*oV(GXP@%H~?h;Hj}{xntuiz$V-7wdk6vo2hf0m12FF;Z2U>~C7f0#>Y97v za`*P|L1aL_$tHeGVDqSM>s)KbDvjhdj3d|+g*62S5)qF$GU$QDK?rZ?+Ux@XvO*L+ z`$3@pv2$Y#p>0Xgr6}UooG!y&^~nw*tYzi3n#x#Mcgxn_Ya<#^RvcUT+<#j9M#Xkw zHh+~jK*y-30gr3?Q&Ud3CgU8b?*_s5wbu6w5^f^I7a>xA|0NdV;{Kd3rf1#vec z{;{8@K56n5+4?Wb-y61$>8W#PtgXlUh+P~Wi>ov(8+45ju?k}-z}*xDU2@O_8vI&i zo^Qt#b%G~MP3ZT_z9~){#ea%^BR#|^);FZv2BHDJ+=b~=;6Xr6I|`?n9U=u}eJJNp zL!q{h1;Vza$Ps)Jl>Vaee%ruuzhE;T;KKeW0w(|s#S z{|ba~DiR`Rjw~B>t45XdhZIT4%n?Rqx~wo9q~{znO)K|5D}}cM@P7@xVtm(Rfl-Mu zqE21^o0P8Qv7v{!Pjc*EbAe=WO3cB#ke>~A8{j~?cPmB!!!owGRHkqL(S8X`KUm2! zbcIT~7?7Nm_ChnhySR7cx;~`Sh0TAB-op|C>Ig*h@^_W*Iu;qY1qKZaT}_$@0il`M zylS%W7EY2VMmS^-Tz^s4@IGYTX&3vNStPy=DzrS`p-5`FmA| zA0eY5&)C0j$A9XFGHgIonlumG5dI4gT3(4ae&sQUM80G1X;H7%7;mQRw2@N?Pf7}o zyaC8UI-QAnXW}Ej;pw1Xx)&cjz_H2eT?KV*!W zQ5>w+vJ~o16d+v}ey`#)$Ls9XQ_3X#x)<;CW z`pU4vzw3q>Fi(~NKdw=P((E~u1imn|70}38wFO^Hn6+^p>VLE!X#0_=`7G4p2yyVV zRO6)JHA#~}L->=axM}$bo{t^#EWEP4SR}36R-N0qLY(ieYGZOu^he{T3YgoF+LUIKv^$9bc&J8U6? zzb&u)sDZ>^B7f41|9zdKr4-3c0V8>wSL~d{ORnYfi{+oI2ct@-GUeOk=_UehEb(R$ zFsm*cUGAL*|0{q_yUwbuoRw*x&})pI^T;|NKHqpyn#0^639%E6YjyPDV zPpgBGiDuM=CNIaWS`VL1Ss@WFmvOzb*C;kj`%bpbZ6z42OTTR1>|=FPWq~+S<~hn8T<~J@>Q;0biP9 zyMGWdJpnPDyMSeF&Mc-=gGp}+%NHrxY-XYn_orH#Ke(9tjP0O>Y#tErfn1PeR^%vYOILuL7;sNi370s)q$3}(X;=n(clapt+rZoZI{H-zf;F#O;Euvx z#{3D4J^>_(`pd-Np%tc;)0=m0KbeYb7)3bIUc^(C&rAP?*yj9iy=w=&sN1=Fvwy6+ z>90>gvVs(Vw!6C2tjOirR8qtKbx0C|@|M)JAI{4&Nf5Apw|@ljZvq%c-`gI0R29*U zpg}!h_(>y0V;RhH*oso&{rw(LmBxr%8=>0jrUTz)8F;iT)-TIE?c~O`I05A$-Y{Aw zSDN;8UHv(Tv-ScPQGel&gB24J$$x2DyI9RgieBCGYAd2d0Wlkfg~=6w zLv8Rk6@$5znUEG>YJ+`#3m&P$mc}9u{v|Q0*zj8ywi2%M)*mv?3}r^B7tw4&LNQUu+&&|7GDINC>MMPObNH$Nt_uNY zmcbuw!X0uIwa={A-o%g1vY@(KIm4Ad<0Qm&50O|+;)nu6UQnRPV%(IER)2b=a#yJC zLtWvFx%iEd81Da7Q6cR9RI0rqsB!HAc08C;|H}`M2Q{PRMR9M)LM*3X$MkRNw3b(b z0sb`?(Iv=mZIy~fpBU?SmLOoVi;a^bbyt^&}aHCs}!*Co6!9y0q)^yw(%VALUe1Nd4Czv)%Ab|B8ZFk zY){o6V5UQx)kQFhOqRlPL!~TCu5d*utT%~$>1MR5n{VoVQ5)UCL%r1YySQ_fF)_lwFk^V>!6lzGPs4%j6{_)WG9xw$P8HgVg+yrfyn~| z(AH~~{M+T^H|%SRbX&#&@;)**f~>oz$&crIiJW@_moTuV+@=Rf&o1j@1P#)FQ$kSkI`+zUNkz6}?3j-d2@M8OPq<(@11W3SP70N6&!6r##1q;m?oW$gciH_BZm2H$I_k#K(%Y1Nuv356QOpPZmrKGQ}aoLfyG z)?=>n-P=yil=xsBZ^oU+F~Fgq|GFb4(&D-Ht!8Uz&arFM^Q-^zTa p65Kdz76NKeyGz#u6w~VdhqeO8SUpzSbw_lamrYgZrUU{42hb_QO2_~J diff --git a/UWP/Package.appxmanifest b/UWP/Package.appxmanifest new file mode 100644 index 0000000000..e5da418581 --- /dev/null +++ b/UWP/Package.appxmanifest @@ -0,0 +1,15 @@ + + + + + + DUMMY + DUMMY + + + + + + + + diff --git a/UWP/PackageGold.appxmanifest b/UWP/PackageGold.appxmanifest index 6f8935b780..c2b898a502 100644 --- a/UWP/PackageGold.appxmanifest +++ b/UWP/PackageGold.appxmanifest @@ -1,6 +1,6 @@ - + PPSSPP Gold - PSP emulator diff --git a/UWP/PackageNormal.appxmanifest b/UWP/PackageNormal.appxmanifest index e794d00572..3ab4dbe2f8 100644 --- a/UWP/PackageNormal.appxmanifest +++ b/UWP/PackageNormal.appxmanifest @@ -1,6 +1,6 @@  - + PPSSPP - PSP emulator From c3baa48ceae2881d1e39c508fafcd4ac78fa5f22 Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 20:34:18 -0400 Subject: [PATCH 31/57] (UWP) Delete Old Key --- UWP/UWP_TemporaryKey.pfx | Bin 2452 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 UWP/UWP_TemporaryKey.pfx diff --git a/UWP/UWP_TemporaryKey.pfx b/UWP/UWP_TemporaryKey.pfx deleted file mode 100644 index cdcf39f7d07597e66c4f5493025941e92bb635fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2452 zcmZuzc{tQv8$Q2TjSQoiEb|VLeammgI-$$FTp93R=t0)K!BLqVnK{0|A zu|kCKP!>Yaz#s%Vj1W{{1iSEmA?!E?!M=qN>=2A#U*Wd=t>WW_P+16O8AdP*Fb&81 zUm8Ng{1_f>PFxSEy=xYQ!gDbQhWkRHB;3xavSgAq-_$~Iq)5_LgD)~oFILzk?Tp8ZtXL3U^+}Teg$gkQZJHWhI0DvE`>|) zOTJ*zgMZ5J@uW!M?(eFWS0;3abLw8q8&!CHGxrtb8hsPNf4{*qC~lZC&;LEFCBvkb z8t+}N;KViX&xzR!Yqi!Ih?tmljb-N8ko;P&SX}pR*U5Y(j?NRGj5CZ@P&(;fr7jmg z;-`FAgn)ee7;^i~wV~GFu_Bga{zK|UP~*j#PhaWQOsQuA;P8 zXOMnk4%524zgft5acp7lnaQ_r8S}QOt`VJSAMYqKc?#%?7V~RQZN_ssKsTtxa-UP`&t!sm}UC4viagZvDha!Xo$d*Ap&wv`PNS7zyogru?Ab ztF{UQldz=#xDL=RAL&@+NVeDClBe3QYSONS`)jW0sqAZCKPPDAKP;)yuDN#p!I(mE zKEH(N?WM`#lEGUY^J4a?4-1q_-O9;bV5DBo>mc{5anvjI!2UzKPU{cs6u#jTc`C@B zw1#@yqW|%Ud`RheR(eaGMbvWod(tOrzv#r!v&rK0=7gJ~L33gPt4771=u@k(6Gd#K zYhX3s(h%gJj%F_Mo;Ma-JTz5DpcVvS&0BF9L` zuS#g|zGYS66Qks|mw_^W3@x?gIy`r~rz;|5>-nV6=TbGcZ{|W;=D?me8I3N;iE0-A zsnwd9z9Bae*gWM|6V!0(F8@rg2@g+Yq8_q-n>oM=k3Zna9x#zA7|S&JCTefwww3VkdHSj zdvu&TXKC7z@h<9}Qjy|sLC$fRH>`(tDnr|S@3wdrH z8~6clzybb10$2h6P3AOk1ropj_<}&-1N?zEa0R}=5%>VNO_c;-Z|*w>+`&oU0(@Zv zt@g9>9}far8iSxEU<6Hr5wys!u8+<_Q1dW?n)&JZ1R*F3K@DRNR6mTMUcv}epM^$2 zC=`igYYrzbL zI$cu@R@br>CepQkKn7zI{*wfOcKmuUgav2>5&$p)@uCn20yQ_=iM8!csI+fM28i>i z{$dI@Xzf^4>&u3xRkYNUwy~||f#J(}(ZxbD*J={e%Q|t@CIhTT%wjRyOJm&%J>=&N z?67m@Ei+i?Vbw+9NFE62I_C<+Cr;b*SnQN(+Th#WtwavNzE07})OInqQM=z_sTq2g zGCCnIWk`kt+laTuh$jp>ge5=mMcq%pES0V{3iioFOR~@S-OG;PPE=+KjaT-?)rtDx zcCg>Y)ZT~*{n+OfWp>wgFtC`;<^<2tc{=uq@1nLmw6+L(m2W z1p`><2a@@L_+VZfj}i{TV)1D7uf5!|*-Ho{*fMAw)`OAWdHm9u&bb}ghyK;DJ?MU# zx7{E;H%UGjJ!rP9``YSJnm=NDMa@71eKI>(w=~vjs`=#d1T|k$-tBV<5a#?Dc8j}J z$~`Z6c-w-8vgyk_!$}Y99=#9Qo~k`>(z-))Ti)ltC`6j&Obu`nv3;1BJGmc{oQf%D zUN9aUC8PwZ>n15jN(zfk@NlArKeknP%TA|H^=k1-8%-UTz4*Dh@4aV0rqeuWl{)vu z{7D{nwo*iy-%QxI1S@gB*U|c+T|&(DqS(RR$!hE*@tysCl+tRwvtHjkdc+<6jG>9m z`ZFZtu5HOz5SElkh`p{5;9A2>xY^;T$xq+*&)0nyydB2luuA-B6ct0+pgyDdW>ILS rRN};)(%}TW-*_a3a_y{ Date: Tue, 19 Jul 2022 20:48:42 -0400 Subject: [PATCH 32/57] (UWP) Remove Reference to Deleted File. --- UWP/UWP.vcxproj | 1 - 1 file changed, 1 deletion(-) diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index d955bbb1b9..2fa50dbb9e 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -1721,7 +1721,6 @@ true - From 33b62047d0aaefe17966afa5cce3a58cb5a33ab3 Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 20:55:24 -0400 Subject: [PATCH 33/57] (UWP) Update Dummy Manifest --- UWP/Package.appxmanifest | 1 - 1 file changed, 1 deletion(-) diff --git a/UWP/Package.appxmanifest b/UWP/Package.appxmanifest index e5da418581..dc955c64bb 100644 --- a/UWP/Package.appxmanifest +++ b/UWP/Package.appxmanifest @@ -1,7 +1,6 @@  - DUMMY DUMMY From fc3d9fed15b9d44d0058a3e7bc20ab7ea4c1b901 Mon Sep 17 00:00:00 2001 From: GABO1423 <35014183+GABO1423@users.noreply.github.com> Date: Tue, 19 Jul 2022 22:49:14 -0400 Subject: [PATCH 34/57] Add UWP Platform to Issue Templates --- .github/ISSUE_TEMPLATE/bug.yml | 1 + .github/ISSUE_TEMPLATE/build.yml | 1 + .github/ISSUE_TEMPLATE/feature.yml | 1 + .github/ISSUE_TEMPLATE/graphics.yml | 1 + .github/ISSUE_TEMPLATE/performance.yml | 1 + 5 files changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index a343b8cdb5..a347472344 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -79,6 +79,7 @@ body: - Raspberry Pi - Linux / BSD - macOS + - UWP / Xbox - Other - type: input diff --git a/.github/ISSUE_TEMPLATE/build.yml b/.github/ISSUE_TEMPLATE/build.yml index 599e030936..01830ac853 100644 --- a/.github/ISSUE_TEMPLATE/build.yml +++ b/.github/ISSUE_TEMPLATE/build.yml @@ -14,6 +14,7 @@ body: - Raspberry Pi - Linux / BSD - macOS + - UWP / Xbox - Other - type: input diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 62dd323e51..8af90a3f0c 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -44,6 +44,7 @@ body: - Raspberry Pi - Linux / BSD - macOS + - UWP / Xbox - Other - type: input diff --git a/.github/ISSUE_TEMPLATE/graphics.yml b/.github/ISSUE_TEMPLATE/graphics.yml index 4a111788d5..6e15728da6 100644 --- a/.github/ISSUE_TEMPLATE/graphics.yml +++ b/.github/ISSUE_TEMPLATE/graphics.yml @@ -93,6 +93,7 @@ body: - Raspberry Pi - Linux / BSD - macOS + - UWP / Xbox - Other - type: input diff --git a/.github/ISSUE_TEMPLATE/performance.yml b/.github/ISSUE_TEMPLATE/performance.yml index 2798cc13b5..8ee009dfea 100644 --- a/.github/ISSUE_TEMPLATE/performance.yml +++ b/.github/ISSUE_TEMPLATE/performance.yml @@ -72,6 +72,7 @@ body: - Raspberry Pi - Linux / BSD - macOS + - UWP / Xbox - Other - type: input From c2a1caa2a2ef2253268c4e951fbf8ec74b3c7142 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 Jul 2022 09:06:37 -0700 Subject: [PATCH 35/57] irjit: Prevent corruption on purge temps pass. If a switch occurs and then something clobbers the dest of that switch, we were wiping out the first of those three instructions incorrectly. --- Core/MIPS/IR/IRPassSimplify.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index baf43491b6..80972d3ff3 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -27,6 +27,7 @@ u32 Evaluate(u32 a, u32 b, IROp op) { case IROp::Slt: case IROp::SltConst: return ((s32)a < (s32)b); case IROp::SltU: case IROp::SltUConst: return (a < b); default: + _assert_msg_(false, "Unable to evaluate two op %d", (int)op); return -1; } } @@ -50,6 +51,7 @@ u32 Evaluate(u32 a, IROp op) { return count; } default: + _assert_msg_(false, "Unable to evaluate one op %d", (int)op); return -1; } } @@ -64,6 +66,7 @@ IROp ArithToArithConst(IROp op) { case IROp::Slt: return IROp::SltConst; case IROp::SltU: return IROp::SltUConst; default: + _assert_msg_(false, "Invalid ArithToArithConst for op %d", (int)op); return (IROp)-1; } } @@ -75,6 +78,7 @@ IROp ShiftToShiftImm(IROp op) { case IROp::Ror: return IROp::RorImm; case IROp::Sar: return IROp::SarImm; default: + _assert_msg_(false, "Invalid ShiftToShiftImm for op %d", (int)op); return (IROp)-1; } } @@ -834,7 +838,8 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts) { // This happens with lwl/lwr temps. Replace the original dest. insts[check.index] = IRReplaceDestGPR(insts[check.index], check.reg, inst.dest); lastWrittenTo[inst.dest] = check.index; - check.reg = inst.dest; + // If it's being read from (by inst), we can't optimize out. + check.reg = 0; // Update the read by exit flag to match the new reg. check.readByExit = inst.dest < IRTEMP_0 || inst.dest > IRTEMP_LR_SHIFT; // And swap the args for this mov, since we changed the other dest. We'll optimize this out later. From 04a85b1da0b2cfad26b17f2062d1ceb4b98c7ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 11:50:06 +0200 Subject: [PATCH 36/57] Allows "merging" render targets that overlap on the Y access. Fixes #7295 (Juiced 2) To be safe, gating this behind the related AllowLargeFBTextureOffsets, which is also required for the effect to work. Additionally, fixes the offset check for X offsets, which I guess is a very small risk. --- GPU/Common/FramebufferManagerCommon.cpp | 49 ++++++++++++++++++------- GPU/Common/GPUStateUtils.cpp | 1 + GPU/Common/TextureCacheCommon.cpp | 17 ++++++++- GPU/Common/TextureCacheCommon.h | 3 +- GPU/GPUState.h | 8 ++-- assets/compat.ini | 5 +++ 6 files changed, 63 insertions(+), 20 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f5ea895bd5..03f6f370b6 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -266,13 +266,16 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame int drawing_width, drawing_height; EstimateDrawingSize(params.fb_address, params.fmt, params.viewportWidth, params.viewportHeight, params.regionWidth, params.regionHeight, params.scissorWidth, params.scissorHeight, std::max(params.fb_stride, 4), drawing_width, drawing_height); - gstate_c.SetCurRTOffsetX(0); + gstate_c.SetCurRTOffset(0, 0); bool vfbFormatChanged = false; // Find a matching framebuffer VirtualFramebuffer *vfb = nullptr; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *v = vfbs_[i]; + + const u32 bpp = v->format == GE_FORMAT_8888 ? 4 : 2; + if (v->fb_address == params.fb_address) { vfb = v; // Update fb stride in case it changed @@ -302,18 +305,36 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->height = drawing_height; } break; - } else if (v->fb_address < params.fb_address && v->fb_address + v->fb_stride * 4 > params.fb_address) { - // Possibly a render-to-offset. - const u32 bpp = v->format == GE_FORMAT_8888 ? 4 : 2; - const int x_offset = (params.fb_address - v->fb_address) / bpp; - if (v->format == params.fmt && v->fb_stride == params.fb_stride && x_offset < params.fb_stride && v->height >= drawing_height) { - WARN_LOG_REPORT_ONCE(renderoffset, HLE, "Rendering to framebuffer offset: %08x +%dx%d", v->fb_address, x_offset, 0); - vfb = v; - gstate_c.SetCurRTOffsetX(x_offset); - vfb->width = std::max((int)vfb->width, x_offset + drawing_width); - // To prevent the newSize code from being confused. - drawing_width += x_offset; - break; + } else if (v->fb_stride == params.fb_stride && v->format == params.fmt) { + u32 v_fb_first_line_end_ptr = v->fb_address + v->fb_stride * bpp; + u32 v_fb_end_ptr = v->fb_address + v->fb_stride * v->height * bpp; + + if (params.fb_address > v->fb_address && params.fb_address < v_fb_first_line_end_ptr) { + const int x_offset = (params.fb_address - v->fb_address) / bpp; + if (x_offset < params.fb_stride && v->height >= drawing_height) { + // Pretty certainly a pure render-to-X-offset. + WARN_LOG_REPORT_ONCE(renderoffset, HLE, "Rendering to framebuffer offset: %08x +%dx%d", v->fb_address, x_offset, 0); + vfb = v; + gstate_c.SetCurRTOffset(x_offset, 0); + vfb->width = std::max((int)vfb->width, x_offset + drawing_width); + // To prevent the newSize code from being confused. + drawing_width += x_offset; + break; + } + } else if (params.fb_address > v->fb_address && params.fb_address < v_fb_end_ptr && PSP_CoreParameter().compat.flags().AllowLargeFBTextureOffsets) { + if (params.fb_address % params.fb_stride == v->fb_address % params.fb_stride) { + // Framebuffers are overlapping on the Y axis. + const int y_offset = (params.fb_address - v->fb_address) / (bpp * params.fb_stride); + + vfb = v; + gstate_c.SetCurRTOffset(0, y_offset); + // To prevent the newSize code from being confused. + drawing_height += y_offset; + break; + } + } else { + // We ignore this match. + // TODO: We can allow X/Y overlaps too, but haven't seen any so safer to not. } } } @@ -386,7 +407,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame SetColorUpdated(vfb, skipDrawReason); - INFO_LOG(FRAMEBUF, "Creating FBO for %08x (z: %08x) : %i x %i x %i", vfb->fb_address, vfb->z_address, vfb->width, vfb->height, vfb->format); + INFO_LOG(FRAMEBUF, "Creating FBO for %08x (z: %08x) : %d x %d x %s", vfb->fb_address, vfb->z_address, vfb->width, vfb->height, GeBufferFormatToString(vfb->format)); vfb->last_frame_render = gpuStats.numFlips; frameLastFramebufUsed_ = gpuStats.numFlips; diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 8b27be2d34..1f0841d84f 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -584,6 +584,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo } renderX = gstate_c.curRTOffsetX; + renderY = gstate_c.curRTOffsetY; // Scissor int scissorX1 = gstate.getScissorX1(); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index b45ea56299..c4a03dfc0c 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -633,8 +633,17 @@ std::vector TextureCacheCommon::GetFramebufferCandidates(const if (candidates.size() > 1) { bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; - WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "GetFramebufferCandidates(%s): Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s)", - depth ? "DEPTH" : "COLOR", (int)candidates.size(), entry.addr, texAddrOffset, dimWidth(entry.dim), dimHeight(entry.dim), entry.bufw, GeTextureFormatToString(entry.format)); + + std::string cands; + for (auto &candidate : candidates) { + cands += candidate.ToString() + " "; + } + + WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "GetFramebufferCandidates(%s): Multiple (%d) candidate framebuffers. First will be chosen. texaddr: %08x offset: %d (%dx%d stride %d, %s):\n%s", + depth ? "DEPTH" : "COLOR", (int)candidates.size(), + entry.addr, texAddrOffset, dimWidth(entry.dim), dimHeight(entry.dim), entry.bufw, GeTextureFormatToString(entry.format), + cands.c_str() + ); } return candidates; @@ -1996,3 +2005,7 @@ void TextureCacheCommon::InvalidateAll(GPUInvalidationType /*unused*/) { void TextureCacheCommon::ClearNextFrame() { clearCacheNextFrame_ = true; } + +std::string AttachCandidate::ToString() { + return StringFromFormat("[C:%08x/%d Z:%08x/%d X:%d Y:%d reint: %s]", this->fb->fb_address, this->fb->fb_stride, this->fb->z_address, this->fb->z_stride, this->match.xOffset, this->match.yOffset, this->match.reinterpret ? "true" : "false"); +} diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 7fb47e25ca..3464a67841 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -203,7 +203,6 @@ typedef std::map> TexCache; #undef IGNORE #endif -// TODO: Try to get rid of IGNORE, it doesn't match what we want to do enum class FramebufferMatch { // Valid, exact match. VALID = 0, @@ -224,6 +223,8 @@ struct AttachCandidate { TextureDefinition entry; VirtualFramebuffer *fb; FramebufferNotificationChannel channel; + + std::string ToString(); }; class FramebufferManagerCommon; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a4e157448d..9026cfc24f 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -606,13 +606,15 @@ struct GPUStateCache { u32 curRTRenderWidth; u32 curRTRenderHeight; - void SetCurRTOffsetX(int off) { - if (off != curRTOffsetX) { - curRTOffsetX = off; + void SetCurRTOffset(u32 xoff, u32 yoff) { + if (xoff != curRTOffsetX || yoff != curRTOffsetY) { + curRTOffsetX = xoff; + curRTOffsetY = yoff; Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } } u32 curRTOffsetX; + u32 curRTOffsetY; // Set if we are doing hardware bezier/spline. SubmitType submitType; diff --git a/assets/compat.ini b/assets/compat.ini index 9d582ae1bd..24f5ecbf0e 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1252,3 +1252,8 @@ ULKS46143 = true ULES00981 = true ULES00982 = true LBSW10345 = true # Some modded version found in our report logs + +# Juiced 2 bloom effect (see #7295) +ULES00928 = true +ULUS10312 = true +ULKS46154 = true From e6403d7157c25b0a3bbf8d36c18052d5c8a22484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 20 Jul 2022 12:40:22 +0200 Subject: [PATCH 37/57] Split GetPointer into two versions, to help with const correctness --- Core/ELF/ElfReader.cpp | 2 +- Core/FileSystems/ISOFileSystem.cpp | 4 +-- Core/HLE/FunctionWrappers.h | 14 +++++----- Core/HLE/ReplaceTables.cpp | 14 +++++----- Core/HLE/proAdhoc.cpp | 2 +- Core/HLE/sceAdler.cpp | 2 +- Core/HLE/sceAtrac.cpp | 4 +-- Core/HLE/sceAudiocodec.cpp | 2 +- Core/HLE/sceChnnlsv.cpp | 10 ++++---- Core/HLE/sceDeflt.cpp | 2 +- Core/HLE/sceJpeg.cpp | 6 ++--- Core/HLE/sceKernelInterrupt.cpp | 18 ++++++------- Core/HLE/sceKernelMemory.cpp | 2 +- Core/HLE/sceKernelMsgPipe.cpp | 4 +-- Core/HLE/sceKernelSemaphore.cpp | 8 +++--- Core/HLE/sceMd5.cpp | 22 ++++++++-------- Core/HLE/sceMp3.cpp | 8 +++--- Core/HLE/sceMpeg.cpp | 6 ++--- Core/HLE/sceMt19937.cpp | 2 +- Core/HLE/sceNet.cpp | 12 ++++----- Core/HLE/sceNetAdhoc.cpp | 8 +++--- Core/HLE/sceNp.cpp | 2 +- Core/HLE/scePauth.cpp | 4 +-- Core/HLE/sceSha256.cpp | 4 +-- Core/HW/MediaEngine.cpp | 6 ++--- Core/HW/SasAudio.cpp | 8 +++--- Core/HW/SasAudio.h | 2 +- Core/HW/SimpleAudioDec.cpp | 6 ++--- Core/HW/SimpleAudioDec.h | 2 +- Core/MIPS/MIPSIntVFPU.cpp | 4 +-- Core/MemMap.cpp | 4 +-- Core/MemMap.h | 17 ++++++++++--- Core/MemMapFunctions.cpp | 14 ++++++---- Core/MemMapHelpers.h | 4 +-- GPU/Common/DrawEngineCommon.cpp | 6 ++--- GPU/Common/DrawEngineCommon.h | 12 ++++----- GPU/Common/FramebufferManagerCommon.cpp | 10 ++++---- GPU/GPUCommon.cpp | 18 ++++++------- GPU/Software/Rasterizer.cpp | 2 +- GPU/Software/Rasterizer.h | 2 +- GPU/Software/SoftGpu.cpp | 34 ++++++++++++------------- GPU/Software/TransformUnit.cpp | 6 ++--- GPU/Software/TransformUnit.h | 6 ++--- 43 files changed, 169 insertions(+), 156 deletions(-) diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index a350066f38..abfd881e87 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -493,7 +493,7 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop) u32 writeAddr = segmentVAddr[i]; const u8 *src = GetSegmentPtr(i); - u8 *dst = Memory::GetPointer(writeAddr); + u8 *dst = Memory::GetPointerWrite(writeAddr); u32 srcSize = p->p_filesz; u32 dstSize = p->p_memsz; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 713d9aaa2e..a873f3f19b 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -407,7 +407,7 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd } INFO_LOG(SCEIO, "sceIoIoctl: reading ISO9660 volume descriptor read"); - blockDevice->ReadBlock(16, Memory::GetPointer(outdataPtr)); + blockDevice->ReadBlock(16, Memory::GetPointerWriteUnchecked(outdataPtr)); return 0; // Get ISO9660 path table (from open ISO9660 file.) @@ -424,7 +424,7 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd } else { int block = (u16)desc.firstLETableSector; u32 size = Memory::ValidSize(outdataPtr, (u32)desc.pathTableLength); - u8 *out = Memory::GetPointer(outdataPtr); + u8 *out = Memory::GetPointerWrite(outdataPtr); int blocks = size / blockDevice->GetBlockSize(); blockDevice->ReadBlocks(block, blocks, out); diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 73cc956d12..9feb73cd04 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -106,7 +106,7 @@ template void WrapU_V() { } template void WrapU_IVI() { - u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), PARAM(2)); + u32 retval = func(PARAM(0), Memory::GetPointerWrite(PARAM(1)), PARAM(2)); RETURN(retval); } @@ -116,7 +116,7 @@ template void WrapI_CIIU() { } template void WrapI_ICUVVUI() { - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)),Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) ); + u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWrite(PARAM(3)),Memory::GetPointerWrite(PARAM(4)), PARAM(5), PARAM(6) ); RETURN(retval); } @@ -147,13 +147,13 @@ template void WrapI_IIIIIIU() { // Hm, do so many params get passed in registers? template void WrapI_IIIIIIIIU() { - u32 param8 = *(const u32_le *)Memory::GetPointer(currentMIPS->r[29]); //Fixed 9th parameter, thanks to Kingcom + u32 param8 = *(const u32_le *)Memory::GetPointerWrite(currentMIPS->r[29]); //Fixed 9th parameter, thanks to Kingcom u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7), param8); RETURN(retval); } template void WrapU_IV() { - u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1))); + u32 retval = func(PARAM(0), Memory::GetPointerWrite(PARAM(1))); RETURN(retval); } @@ -796,16 +796,16 @@ template void WrapI_ICI() { } template void WrapI_IVVVVUI(){ - u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), Memory::GetPointer(PARAM(2)), Memory::GetPointer(PARAM(3)), Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) ); + u32 retval = func(PARAM(0), Memory::GetPointerWrite(PARAM(1)), Memory::GetPointerWrite(PARAM(2)), Memory::GetPointerWrite(PARAM(3)), Memory::GetPointerWrite(PARAM(4)), PARAM(5), PARAM(6) ); RETURN(retval); } template void WrapI_ICUVIII(){ - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); + u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWrite(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } template void WrapI_VUI(){ - u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2)); + u32 retval = func(Memory::GetPointerWrite(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index fda0c07b07..4a0e7c4cac 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -138,7 +138,7 @@ static int Replace_memcpy() { } } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); const u8 *src = Memory::GetPointer(srcPtr); if (!dst || !src) { @@ -190,7 +190,7 @@ static int Replace_memcpy_jak() { } } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); const u8 *src = Memory::GetPointer(srcPtr); if (!dst || !src) { @@ -240,7 +240,7 @@ static int Replace_memcpy16() { } } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); const u8 *src = Memory::GetPointer(srcPtr); if (dst && src) { memmove(dst, src, bytes); @@ -267,7 +267,7 @@ static int Replace_memcpy_swizzled() { gpu->PerformMemoryDownload(srcPtr, pitch * h); } } - u8 *dstp = Memory::GetPointer(destPtr); + u8 *dstp = Memory::GetPointerWrite(destPtr); const u8 *srcp = Memory::GetPointer(srcPtr); if (dstp && srcp) { @@ -312,7 +312,7 @@ static int Replace_memmove() { } } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); const u8 *src = Memory::GetPointer(srcPtr); if (dst && src) { memmove(dst, src, bytes); @@ -338,7 +338,7 @@ static int Replace_memset() { skip = gpu->PerformMemorySet(destPtr, value, bytes); } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); if (dst) { memset(dst, value, bytes); } @@ -365,7 +365,7 @@ static int Replace_memset_jak() { skip = gpu->PerformMemorySet(destPtr, value, bytes); } if (!skip && bytes != 0) { - u8 *dst = Memory::GetPointer(destPtr); + u8 *dst = Memory::GetPointerWrite(destPtr); if (dst) { memset(dst, value, bytes); } diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 73784a3846..dcacbcc5bd 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1263,7 +1263,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * MatchingArgs argsNew = { 0 }; u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8); u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall. FIXME: Are these buffers supposed to be taken/pre-allocated from the memory pool during sceNetAdhocMatchingInit? - uint8_t * dataPtr = Memory::GetPointer(dataBufAddr); + uint8_t * dataPtr = Memory::GetPointerWrite(dataBufAddr); if (dataPtr) { memcpy(dataPtr, &msg->mac, sizeof(msg->mac)); if (msg->optlen > 0) diff --git a/Core/HLE/sceAdler.cpp b/Core/HLE/sceAdler.cpp index 43e589a001..59e2570467 100644 --- a/Core/HLE/sceAdler.cpp +++ b/Core/HLE/sceAdler.cpp @@ -33,7 +33,7 @@ static u32 sceAdler32(u32 adler, u32 data, u32 datalen) { } INFO_LOG(SCEMISC, "sceAdler32(adler=%08x, data=%08x, datalen=%08x)", adler, data, datalen); - u8 *buf = Memory::GetPointerUnchecked(data); + u8 *buf = Memory::GetPointerWriteUnchecked(data); u32 ret = adler32(adler, buf, datalen); return ret; diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index c6807c4ad2..f44ba65fe1 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -480,7 +480,7 @@ struct Atrac { } u8 *BufferStart() { - return ignoreDataBuf_ ? Memory::GetPointer(first_.addr) : dataBuf_; + return ignoreDataBuf_ ? Memory::GetPointerWrite(first_.addr) : dataBuf_; } void SeekToSample(int sample) { @@ -1345,7 +1345,7 @@ static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 u32 numSamples = 0; u32 finish = 0; int remains = 0; - int ret = _AtracDecodeData(atracID, Memory::GetPointer(outAddr), outAddr, &numSamples, &finish, &remains); + int ret = _AtracDecodeData(atracID, Memory::GetPointerWrite(outAddr), outAddr, &numSamples, &finish, &remains); if (ret != (int)ATRAC_ERROR_BAD_ATRACID && ret != (int)ATRAC_ERROR_NO_DATA) { if (Memory::IsValidAddress(numSamplesAddr)) Memory::Write_U32(numSamples, numSamplesAddr); diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index ed4dc42aa3..6d40c6802e 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -116,7 +116,7 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) { if (decoder != NULL) { // Decode audio - decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, Memory::GetPointer(ctx->outDataPtr), &outbytes); + decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes); } DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec)); return 0; diff --git a/Core/HLE/sceChnnlsv.cpp b/Core/HLE/sceChnnlsv.cpp index 475e2ed8d2..82e063b344 100644 --- a/Core/HLE/sceChnnlsv.cpp +++ b/Core/HLE/sceChnnlsv.cpp @@ -218,7 +218,7 @@ static int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) { pspChnnlsvContext1 ctx; Memory::ReadStruct(addressCtx, &ctx); - int res = sceSdGetLastIndex_(ctx, Memory::GetPointer(addressHash), Memory::GetPointer(addressKey)); + int res = sceSdGetLastIndex_(ctx, Memory::GetPointerWrite(addressHash), Memory::GetPointerWrite(addressKey)); Memory::WriteStruct(addressCtx, &ctx); return res; } @@ -348,7 +348,7 @@ static int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length) { pspChnnlsvContext1 ctx; Memory::ReadStruct(addressCtx, &ctx); - int res = sceSdRemoveValue_(ctx, Memory::GetPointer(addressData), length); + int res = sceSdRemoveValue_(ctx, Memory::GetPointerWrite(addressData), length); Memory::WriteStruct(addressCtx, &ctx); return res; @@ -400,8 +400,8 @@ static int sceSdCreateList(u32 ctx2Addr, int mode, int unkwn, u32 dataAddr, u32 { pspChnnlsvContext2 ctx2; Memory::ReadStruct(ctx2Addr, &ctx2); - u8* data = Memory::GetPointer(dataAddr); - u8* cryptkey = Memory::GetPointer(cryptkeyAddr); + u8* data = Memory::GetPointerWrite(dataAddr); + u8* cryptkey = Memory::GetPointerWrite(cryptkeyAddr); int res = sceSdCreateList_(ctx2, mode, unkwn, data, cryptkey); @@ -468,7 +468,7 @@ static int sceSdSetMember(u32 ctxAddr, u32 dataAddr, int alignedLen) { pspChnnlsvContext2 ctx; Memory::ReadStruct(ctxAddr, &ctx); - u8* data = Memory::GetPointer(dataAddr); + u8* data = Memory::GetPointerWrite(dataAddr); int res = sceSdSetMember_(ctx, data, alignedLen); diff --git a/Core/HLE/sceDeflt.cpp b/Core/HLE/sceDeflt.cpp index 2e18c2086f..d5580dcc40 100644 --- a/Core/HLE/sceDeflt.cpp +++ b/Core/HLE/sceDeflt.cpp @@ -36,7 +36,7 @@ static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength, } z_stream stream{}; - u8 *outBufferPtr = Memory::GetPointer(OutBuffer); + u8 *outBufferPtr = Memory::GetPointerWrite(OutBuffer); stream.next_in = (Bytef*)Memory::GetPointer(InBuffer); // We don't know the available length, just let it use as much as it wants. stream.avail_in = (uInt)Memory::ValidSize(InBuffer, Memory::g_MemorySize); diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index 9ad09796c9..e7f3011bdc 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -133,7 +133,7 @@ static u32 convertARGBtoABGR(u32 argb) { } static int __DecodeJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr) { - u8 *buf = Memory::GetPointer(jpegAddr); + const u8 *buf = Memory::GetPointer(jpegAddr); int width, height, actual_components; unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &width, &height, &actual_components, 3); @@ -219,7 +219,7 @@ static int getYCbCrBufferSize(int w, int h) { } static int __JpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr) { - u8 *buf = Memory::GetPointer(jpegAddr); + const u8 *buf = Memory::GetPointer(jpegAddr); int width, height, actual_components; unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &width, &height, &actual_components, 3); @@ -325,7 +325,7 @@ static int __JpegConvertRGBToYCbCr (const void *data, u32 bufferOutputAddr, int } static int __JpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr) { - u8 *buf = Memory::GetPointer(jpegAddr); + const u8 *buf = Memory::GetPointer(jpegAddr); int width, height, actual_components; unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &width, &height, &actual_components, 3); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 05d3f24fe1..a86deee9fe 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -634,8 +634,8 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size) // Technically should crash if these are invalid and size > 0... if (!skip && Memory::IsValidAddress(dst) && Memory::IsValidAddress(src) && Memory::IsValidAddress(dst + size - 1) && Memory::IsValidAddress(src + size - 1)) { - u8 *dstp = Memory::GetPointerUnchecked(dst); - u8 *srcp = Memory::GetPointerUnchecked(src); + u8 *dstp = Memory::GetPointerWriteUnchecked(dst); + const u8 *srcp = Memory::GetPointerUnchecked(src); // If it's non-overlapping, just do it in one go. if (dst + size < src || src + size < dst) @@ -688,7 +688,7 @@ const HLEFunction Kernel_Library[] = static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { - memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size); + memcpy(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size); } if (MemBlockInfoDetailed(size)) { const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size); @@ -701,7 +701,7 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { static u32 sysclib_strcat(u32 dst, u32 src) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strcat(dest=%08x, src=%08x)", dst, src); if (Memory::IsValidAddress(dst) && Memory::IsValidAddress(src)) { - strcat((char *)Memory::GetPointer(dst), (char *)Memory::GetPointer(src)); + strcat((char *)Memory::GetPointerWriteUnchecked(dst), (const char *)Memory::GetPointerUnchecked(src)); } return dst; } @@ -709,7 +709,7 @@ static u32 sysclib_strcat(u32 dst, u32 src) { static int sysclib_strcmp(u32 dst, u32 src) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strcmp(dest=%08x, src=%08x)", dst, src); if (Memory::IsValidAddress(dst) && Memory::IsValidAddress(src)) { - return strcmp((char *)Memory::GetPointer(dst), (char *)Memory::GetPointer(src)); + return strcmp((const char *)Memory::GetPointerUnchecked(dst), (const char *)Memory::GetPointerUnchecked(src)); } else { // What to do? Crash, probably. return 0; @@ -719,7 +719,7 @@ static int sysclib_strcmp(u32 dst, u32 src) { static u32 sysclib_strcpy(u32 dst, u32 src) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strcpy(dest=%08x, src=%08x)", dst, src); if (Memory::IsValidAddress(dst) && Memory::IsValidAddress(src)) { - strcpy((char *)Memory::GetPointer(dst), (char *)Memory::GetPointer(src)); + strcpy((char *)Memory::GetPointerWriteUnchecked(dst), (const char *)Memory::GetPointerUnchecked(src)); } return dst; } @@ -758,7 +758,7 @@ static int sysclib_sprintf(u32 dst, u32 fmt) { static u32 sysclib_memset(u32 destAddr, int data, int size) { ERROR_LOG(SCEKERNEL, "Untested sysclib_memset(dest=%08x, data=%d ,size=%d)", destAddr, data, size); if (Memory::IsValidRange(destAddr, size)) { - memset(Memory::GetPointer(destAddr), data, size); + memset(Memory::GetPointerWriteUnchecked(destAddr), data, size); } NotifyMemInfo(MemBlockFlags::WRITE, destAddr, size, "KernelMemset"); return 0; @@ -791,7 +791,7 @@ static int sysclib_strncmp(u32 s1, u32 s2, u32 size) { static u32 sysclib_memmove(u32 dst, u32 src, u32 size) { ERROR_LOG(SCEKERNEL, "Untested sysclib_memmove(%08x, %08x, %08x)", dst, src, size); if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { - memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size); + memmove(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size); } if (MemBlockInfoDetailed(size)) { const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size); @@ -810,7 +810,7 @@ static u32 sysclib_strncpy(u32 dest, u32 src, u32 size) { u32 i = 0; u32 srcSize = Memory::ValidSize(src, size); const u8 *srcp = Memory::GetPointer(src); - u8 *destp = Memory::GetPointer(dest); + u8 *destp = Memory::GetPointerWrite(dest); for (i = 0; i < srcSize; ++i) { u8 c = *srcp++; if (c == 0) diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index f99dc55978..3c5cce3a9f 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -432,7 +432,7 @@ void __KernelMemoryInit() MemBlockInfoInit(); kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), false); userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase(), false); - ParallelMemset(&g_threadManager, Memory::GetPointer(PSP_GetKernelMemoryBase()), 0, PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase()); + ParallelMemset(&g_threadManager, Memory::GetPointerWrite(PSP_GetKernelMemoryBase()), 0, PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase()); NotifyMemInfo(MemBlockFlags::WRITE, PSP_GetKernelMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetKernelMemoryBase(), "MemInit"); INFO_LOG(SCEKERNEL, "Kernel and user memory pools initialized"); diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 24d538609e..253bf9ae65 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -218,7 +218,7 @@ struct MsgPipe : public KernelObject // Receive as much as possible, even if it's not enough to wake up. u32 bytesToSend = std::min(thread->freeSize, GetUsedSize()); - u8* ptr = Memory::GetPointer(buffer); + u8* ptr = Memory::GetPointerWrite(buffer); thread->WriteBuffer(buffer, bytesToSend); // Put the unused data at the start of the buffer. nmp.freeSize += bytesToSend; @@ -494,7 +494,7 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz { Memory::Memcpy(curReceiveAddr, m->buffer, bytesToReceive, "MsgPipeReceive"); m->nmp.freeSize += bytesToReceive; - memmove(Memory::GetPointer(m->buffer), Memory::GetPointer(m->buffer) + bytesToReceive, m->GetUsedSize()); + memmove(Memory::GetPointerWrite(m->buffer), Memory::GetPointer(m->buffer) + bytesToReceive, m->GetUsedSize()); curReceiveAddr += bytesToReceive; receiveSize -= bytesToReceive; diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 0b90a3067c..d6ebbaf2c1 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -466,8 +466,8 @@ int sceKernelPollSema(SceUID id, int wantedCount) static u32 sceUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) { - u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointer(outAddr) : nullptr; - const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointer(inAddr) : nullptr; + u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr; + const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerUnchecked(inAddr) : nullptr; int temp = kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd); if (temp != 0) { ERROR_LOG(SCEKERNEL, "hleUtilsBufferCopyWithRange: Failed with %d", temp); @@ -478,8 +478,8 @@ static u32 sceUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int // Note sure what difference there is between this and sceUtilsBufferCopyWithRange. static int sceUtilsBufferCopyByPollingWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) { - u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointer(outAddr) : nullptr; - const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointer(inAddr) : nullptr; + u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr; + const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerUnchecked(inAddr) : nullptr; return kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd); } diff --git a/Core/HLE/sceMd5.cpp b/Core/HLE/sceMd5.cpp index 70e118d8e5..cd71adcd84 100644 --- a/Core/HLE/sceMd5.cpp +++ b/Core/HLE/sceMd5.cpp @@ -32,7 +32,7 @@ u32 sceKernelUtilsMt19937Init(u32 ctx, u32 seed) { DEBUG_LOG(HLE, "sceKernelUtilsMt19937Init(%08x, %08x)", ctx, seed); if (!Memory::IsValidAddress(ctx)) return -1; - void *ptr = Memory::GetPointer(ctx); + void *ptr = Memory::GetPointerWrite(ctx); // This is made to match the memory layout of a PSP MT structure exactly. // Let's just construct it in place with placement new. Elite C++ hackery FTW. new (ptr) MersenneTwister(seed); @@ -43,7 +43,7 @@ u32 sceKernelUtilsMt19937UInt(u32 ctx) { VERBOSE_LOG(HLE, "sceKernelUtilsMt19937UInt(%08x)", ctx); if (!Memory::IsValidAddress(ctx)) return -1; - MersenneTwister *mt = (MersenneTwister *)Memory::GetPointer(ctx); + MersenneTwister *mt = (MersenneTwister *)Memory::GetPointerUnchecked(ctx); return mt->R32(); } @@ -57,7 +57,7 @@ static int sceMd5Digest(u32 dataAddr, u32 len, u32 digestAddr) { if (!Memory::IsValidAddress(dataAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - md5(Memory::GetPointer(dataAddr), (int)len, Memory::GetPointer(digestAddr)); + md5(Memory::GetPointerWriteUnchecked(dataAddr), (int)len, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } @@ -78,7 +78,7 @@ static int sceMd5BlockUpdate(u32 ctxAddr, u32 dataPtr, u32 len) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(dataPtr)) return -1; - md5_update(&md5_ctx, Memory::GetPointer(dataPtr), (int)len); + md5_update(&md5_ctx, Memory::GetPointerWriteUnchecked(dataPtr), (int)len); return 0; } @@ -87,7 +87,7 @@ static int sceMd5BlockResult(u32 ctxAddr, u32 digestAddr) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - md5_finish(&md5_ctx, Memory::GetPointer(digestAddr)); + md5_finish(&md5_ctx, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } @@ -97,7 +97,7 @@ int sceKernelUtilsMd5Digest(u32 dataAddr, int len, u32 digestAddr) { if (!Memory::IsValidAddress(dataAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - md5(Memory::GetPointer(dataAddr), (int)len, Memory::GetPointer(digestAddr)); + md5(Memory::GetPointerWriteUnchecked(dataAddr), (int)len, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } @@ -118,7 +118,7 @@ int sceKernelUtilsMd5BlockUpdate(u32 ctxAddr, u32 dataPtr, int len) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(dataPtr)) return -1; - md5_update(&md5_ctx, Memory::GetPointer(dataPtr), (int)len); + md5_update(&md5_ctx, Memory::GetPointerWriteUnchecked(dataPtr), (int)len); return 0; } @@ -127,7 +127,7 @@ int sceKernelUtilsMd5BlockResult(u32 ctxAddr, u32 digestAddr) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - md5_finish(&md5_ctx, Memory::GetPointer(digestAddr)); + md5_finish(&md5_ctx, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } @@ -140,7 +140,7 @@ int sceKernelUtilsSha1Digest(u32 dataAddr, int len, u32 digestAddr) { if (!Memory::IsValidAddress(dataAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - sha1(Memory::GetPointer(dataAddr), (int)len, Memory::GetPointer(digestAddr)); + sha1(Memory::GetPointerWriteUnchecked(dataAddr), (int)len, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } @@ -162,7 +162,7 @@ int sceKernelUtilsSha1BlockUpdate(u32 ctxAddr, u32 dataAddr, int len) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(dataAddr)) return -1; - sha1_update(&sha1_ctx, Memory::GetPointer(dataAddr), (int)len); + sha1_update(&sha1_ctx, Memory::GetPointerWriteUnchecked(dataAddr), (int)len); return 0; } @@ -171,7 +171,7 @@ int sceKernelUtilsSha1BlockResult(u32 ctxAddr, u32 digestAddr) { if (!Memory::IsValidAddress(ctxAddr) || !Memory::IsValidAddress(digestAddr)) return -1; - sha1_finish(&sha1_ctx, Memory::GetPointer(digestAddr)); + sha1_finish(&sha1_ctx, Memory::GetPointerWriteUnchecked(digestAddr)); return 0; } diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index 12d2fdab68..aa070b4ff8 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -364,7 +364,7 @@ static int CalculateMp3SamplesPerFrame(int versionBits, int layerBits) { static int FindMp3Header(AuCtx *ctx, int &header, int end) { u32 addr = ctx->AuBuf + ctx->AuStreamWorkareaSize(); if (Memory::IsValidRange(addr, end)) { - u8 *ptr = Memory::GetPointerUnchecked(addr); + const u8 *ptr = Memory::GetPointerUnchecked(addr); for (int offset = 0; offset < end; ++offset) { // If we hit valid sync bits, then we've found a header. if (ptr[offset] == 0xFF && (ptr[offset + 1] & 0xC0) == 0xC0) { @@ -689,11 +689,11 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed return -1; } - auto inbuff = Memory::GetPointer(sourceAddr); - auto outbuff = Memory::GetPointer(samplesAddr); + auto inbuff = Memory::GetPointerWriteUnchecked(sourceAddr); + auto outbuff = Memory::GetPointerWriteUnchecked(samplesAddr); int outpcmbytes = 0; - ctx->decoder->Decode((void*)inbuff, 4096, outbuff, &outpcmbytes); + ctx->decoder->Decode(inbuff, 4096, outbuff, &outpcmbytes); NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outpcmbytes, "Mp3LowLevelDecode"); Memory::Write_U32(ctx->decoder->GetSourcePos(), sourceBytesConsumedAddr); diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 3efd2320ef..5a3cd77d35 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -628,7 +628,7 @@ static int sceMpegQueryStreamOffset(u32 mpeg, u32 bufferAddr, u32 offsetAddr) DEBUG_LOG(ME, "sceMpegQueryStreamOffset(%08x, %08x, %08x)", mpeg, bufferAddr, offsetAddr); // Kinda destructive, no? - AnalyzeMpeg(Memory::GetPointer(bufferAddr), Memory::ValidSize(bufferAddr, 32768), ctx); + AnalyzeMpeg(Memory::GetPointerWriteUnchecked(bufferAddr), Memory::ValidSize(bufferAddr, 32768), ctx); if (ctx->mpegMagic != PSMF_MAGIC) { ERROR_LOG(ME, "sceMpegQueryStreamOffset: Bad PSMF magic"); @@ -660,7 +660,7 @@ static u32 sceMpegQueryStreamSize(u32 bufferAddr, u32 sizeAddr) MpegContext ctx; ctx.mediaengine = 0; - AnalyzeMpeg(Memory::GetPointer(bufferAddr), Memory::ValidSize(bufferAddr, 32768), &ctx); + AnalyzeMpeg(Memory::GetPointerWriteUnchecked(bufferAddr), Memory::ValidSize(bufferAddr, 32768), &ctx); if (ctx.mpegMagic != PSMF_MAGIC) { ERROR_LOG(ME, "sceMpegQueryStreamSize: Bad PSMF magic"); @@ -965,7 +965,7 @@ static bool decodePmpVideo(PSPPointer ringbuffer, u32 pmpctxA for (int i = 0; i < pmp_nBlocks; i++){ auto lli = PSPPointer::Create(pmp_videoSource); // add source block into pmpframes - pmpframes->add(Memory::GetPointer(lli->pSrc), lli->iSize); + pmpframes->add(Memory::GetPointerWrite(lli->pSrc), lli->iSize); // get next block pmp_videoSource += sizeof(SceMpegLLI); } diff --git a/Core/HLE/sceMt19937.cpp b/Core/HLE/sceMt19937.cpp index cc56df502b..f22fcfeb1d 100644 --- a/Core/HLE/sceMt19937.cpp +++ b/Core/HLE/sceMt19937.cpp @@ -30,7 +30,7 @@ static u32 sceMt19937Init(u32 mt19937Addr, u32 seed) { if (!Memory::IsValidAddress(mt19937Addr)) return hleLogError(HLE, -1); - void *ptr = Memory::GetPointer(mt19937Addr); + void *ptr = Memory::GetPointerWriteUnchecked(mt19937Addr); // This is made to match the memory layout of a PSP MT structure exactly. // Let's just construct it in place with placement new. Elite C++ hackery FTW. new (ptr) MersenneTwister(seed); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 6565a3191c..ff2cb8ed7e 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -684,7 +684,7 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) { return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address"); } - u8 *addr = Memory::GetPointer(addrAddr); + u8 *addr = Memory::GetPointerWriteUnchecked(addrAddr); if (PPSSPP_ID > 1) { Memory::Memset(addrAddr, PPSSPP_ID, 6); // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) @@ -722,8 +722,8 @@ static void sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { DEBUG_LOG(SCENET, "sceNetEtherNtostr(%08x, %08x) at %08x", macPtr, bufferPtr, currentMIPS->pc); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { - char *buffer = (char *)Memory::GetPointer(bufferPtr); - const u8 *mac = Memory::GetPointer(macPtr); + char *buffer = (char *)Memory::GetPointerWriteUnchecked(bufferPtr); + const u8 *mac = Memory::GetPointerUnchecked(macPtr); // MAC address is always 6 bytes / 48 bits. sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", @@ -748,8 +748,8 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { DEBUG_LOG(SCENET, "sceNetEtherStrton(%08x, %08x)", bufferPtr, macPtr); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { - const char *buffer = (char *)Memory::GetPointer(bufferPtr); - u8 *mac = Memory::GetPointer(macPtr); + const char *buffer = (const char *)Memory::GetPointerUnchecked(bufferPtr); + u8 *mac = Memory::GetPointerWrite(macPtr); // MAC address is always 6 pairs of hex digits. // TODO: Funny stuff happens if it's too short. @@ -896,7 +896,7 @@ static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { if (!Memory::IsValidAddress(pInfoAddr)) return hleLogError(SCENET, -1, "apctl invalid arg"); - u8* info = Memory::GetPointer(pInfoAddr); // FIXME: Points to a union instead of a struct thus each field have the same address + u8* info = Memory::GetPointerWrite(pInfoAddr); // FIXME: Points to a union instead of a struct thus each field have the same address switch (code) { case PSP_NET_APCTL_INFO_PROFILE_NAME: diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 400d4ac9c9..ec3cced95e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5120,7 +5120,7 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres if ((optLen == 0) || (optLen > 0 && optDataPtr != 0)) { void * opt = NULL; - if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointer(optDataPtr); + if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointerWriteUnchecked(optDataPtr); // Host Mode if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { @@ -5247,7 +5247,7 @@ int NetAdhocMatching_CancelTargetWithOpt(int matchingId, const char* macAddress, { SceNetEtherAddr* target = (SceNetEtherAddr*)macAddress; void* opt = NULL; - if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointer(optDataPtr); + if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointerWriteUnchecked(optDataPtr); // Valid Arguments if (target != NULL && ((optLen == 0) || (optLen > 0 && opt != NULL))) @@ -5351,7 +5351,7 @@ int sceNetAdhocMatchingGetHelloOpt(int matchingId, u32 optLenAddr, u32 optDataAd // Get OptData *optlen = item->hellolen; if ((*optlen > 0) && Memory::IsValidAddress(optDataAddr)) { - uint8_t * optdata = Memory::GetPointer(optDataAddr); + uint8_t * optdata = Memory::GetPointerWriteUnchecked(optDataAddr); memcpy(optdata, item->hello, *optlen); } //else return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; @@ -5666,7 +5666,7 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_DATALEN, "invalid datalen"); void* data = NULL; - if (Memory::IsValidAddress(dataAddr)) data = Memory::GetPointer(dataAddr); + if (Memory::IsValidAddress(dataAddr)) data = Memory::GetPointerWriteUnchecked(dataAddr); // Lock the peer std::lock_guard peer_guard(peerlock); diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index cd0fc9a26b..3bd9d228b0 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -267,7 +267,7 @@ static int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) // Dummy Login ticket returned as Login response. Dummy ticket contents were taken from https://www.psdevwiki.com/ps3/X-I-5-Ticket ticket.header.version = TICKET_VER_2_1; ticket.header.size = 0xF0; // size excluding the header - u8* buf = Memory::GetPointer(bufferAddr + sizeof(ticket)); + u8* buf = Memory::GetPointerWrite(bufferAddr + sizeof(ticket)); int ofs = 0; ofs += writeTicketParam(buf, PARAM_TYPE_STRING_ASCII, "\x4c\x47\x56\x3b\x81\x39\x4a\x22\xd8\x6b\xc1\x57\x71\x6e\xfd\xb8\xab\x63\xcc\x51", 20); // 20 random letters, token key? ofs += writeTicketU32Param(buf + ofs, PARAM_TYPE_INT, 0x0100); // a flags? diff --git a/Core/HLE/scePauth.cpp b/Core/HLE/scePauth.cpp index ceba0710fb..705f6aeeaf 100644 --- a/Core/HLE/scePauth.cpp +++ b/Core/HLE/scePauth.cpp @@ -29,7 +29,7 @@ static int scePauth_F7AA47F6(u32 srcPtr, int srcLength, u32 destLengthPtr, u32 workArea) { - auto src = Memory::GetPointer(srcPtr); + auto src = Memory::GetPointerWrite(srcPtr); auto key = Memory::GetPointer(workArea); const auto decryptResult = pspDecryptPRX(src, src, srcLength, key); @@ -46,7 +46,7 @@ static int scePauth_F7AA47F6(u32 srcPtr, int srcLength, u32 destLengthPtr, u32 w static int scePauth_98B83B5D(u32 srcPtr, int srcLength, u32 destLengthPtr, u32 workArea) { - auto src = Memory::GetPointer(srcPtr); + auto src = Memory::GetPointerWrite(srcPtr); auto key = Memory::GetPointer(workArea); const auto decryptResult = pspDecryptPRX(src, src, srcLength, key); diff --git a/Core/HLE/sceSha256.cpp b/Core/HLE/sceSha256.cpp index 9ef585bd3b..a2dcef54ee 100644 --- a/Core/HLE/sceSha256.cpp +++ b/Core/HLE/sceSha256.cpp @@ -29,10 +29,10 @@ static int sceSha256Digest(u32 data, int dataLen, u32 digestPtr) { INFO_LOG(HLE, "sceSha256Digest(data=%08x, len=%d, digest=%08x)", data, dataLen, digestPtr); // Already checked above... - u8 *digest = Memory::GetPointerUnchecked(digestPtr); + u8 *digest = Memory::GetPointerWriteUnchecked(digestPtr); sha256_context ctx; sha256_starts(&ctx); - sha256_update(&ctx, Memory::GetPointerUnchecked(data), dataLen); + sha256_update(&ctx, Memory::GetPointerWriteUnchecked(data), dataLen); sha256_finish(&ctx, digest); return 0; diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index e845f5cadc..9028c6dee6 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -805,7 +805,7 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo return 0; } - u8 *buffer = Memory::GetPointer(bufferPtr); + u8 *buffer = Memory::GetPointerWrite(bufferPtr); #ifdef USE_FFMPEG if (!m_pFrame || !m_pFrameRGB) @@ -895,7 +895,7 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid return 0; } - u8 *buffer = Memory::GetPointer(bufferPtr); + u8 *buffer = Memory::GetPointerWrite(bufferPtr); #ifdef USE_FFMPEG if (!m_pFrame || !m_pFrameRGB) @@ -1032,7 +1032,7 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr); } - u8 *buffer = Memory::GetPointer(bufferPtr); + u8 *buffer = Memory::GetPointerWrite(bufferPtr); if (!m_demux) { return 0; } diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 2df95195a6..4a76553d4a 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -64,13 +64,13 @@ void VagDecoder::Start(u32 data, u32 vagSize, bool loopEnabled) { s_2 = 0; } -void VagDecoder::DecodeBlock(u8 *&read_pointer) { +void VagDecoder::DecodeBlock(const u8 *&read_pointer) { if (curBlock_ == numBlocks_ - 1) { end_ = true; return; } - u8 *readp = read_pointer; + const u8 *readp = read_pointer; int predict_nr = *readp++; int shift_factor = predict_nr & 0xf; predict_nr >>= 4; @@ -124,8 +124,8 @@ void VagDecoder::GetSamples(s16 *outSamples, int numSamples) { WARN_LOG(SASMIX, "Bad VAG samples address?"); return; } - u8 *readp = Memory::GetPointerUnchecked(read_); - u8 *origp = readp; + const u8 *readp = Memory::GetPointerUnchecked(read_); + const u8 *origp = readp; for (int i = 0; i < numSamples; i++) { if (curSample == 28) { diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index 9a2deca577..4e9670c136 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -102,7 +102,7 @@ public: void GetSamples(s16 *outSamples, int numSamples); - void DecodeBlock(u8 *&readp); + void DecodeBlock(const u8 *&readp); bool End() const { return end_; } void DoState(PointerWrap &p); diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 317a046a42..8db47c77b5 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -177,7 +177,7 @@ bool SimpleAudio::IsOK() const { #endif } -bool SimpleAudio::Decode(void *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) { +bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) { #ifdef USE_FFMPEG if (!codecOpen_) { OpenCodec(inbytes); @@ -185,7 +185,7 @@ bool SimpleAudio::Decode(void *inbuf, int inbytes, uint8_t *outbuf, int *outbyte AVPacket packet; av_init_packet(&packet); - packet.data = static_cast(inbuf); + packet.data = (uint8_t *)(inbuf); packet.size = inbytes; int got_frame = 0; @@ -338,7 +338,7 @@ size_t AuCtx::FindNextMp3Sync() { // return output pcm size, <0 error u32 AuCtx::AuDecode(u32 pcmAddr) { u32 outptr = PCMBuf + nextOutputHalf * PCMBufSize / 2; - auto outbuf = Memory::GetPointer(outptr); + auto outbuf = Memory::GetPointerWrite(outptr); int outpcmbufsize = 0; if (pcmAddr) diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index 2bc2c566d8..533172aaa6 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -45,7 +45,7 @@ public: SimpleAudio(int audioType, int sample_rate = 44100, int channels = 2); ~SimpleAudio(); - bool Decode(void* inbuf, int inbytes, uint8_t *outbuf, int *outbytes); + bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes); bool IsOK() const; int GetOutSamples(); diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 781f2aa042..c8df6b21dc 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -245,7 +245,7 @@ namespace MIPSInt _dbg_assert_msg_( 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN - f = reinterpret_cast(Memory::GetPointer(addr)); + f = reinterpret_cast(Memory::GetPointerWrite(addr)); if (f) WriteVector(f, V_Quad, vt); #else @@ -294,7 +294,7 @@ namespace MIPSInt _dbg_assert_msg_( 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN - f = reinterpret_cast(Memory::GetPointer(addr)); + f = reinterpret_cast(Memory::GetPointerWrite(addr)); if (f) ReadVector(f, V_Quad, vt); #else diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index d7dce4d7b5..1a0fd654f6 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -312,7 +312,7 @@ void Reinit() { } static void DoMemoryVoid(PointerWrap &p, uint32_t start, uint32_t size) { - uint8_t *d = GetPointer(start); + uint8_t *d = GetPointerWrite(start); uint8_t *&storage = *p.ptr; // We only handle aligned data and sizes. @@ -479,7 +479,7 @@ void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value) void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength, const char *tag) { if (IsValidRange(_Address, _iLength)) { - uint8_t *ptr = GetPointerUnchecked(_Address); + uint8_t *ptr = GetPointerWriteUnchecked(_Address); memset(ptr, _iValue, _iLength); } else { for (size_t i = 0; i < _iLength; i++) diff --git a/Core/MemMap.h b/Core/MemMap.h index d21d97a43d..97b7fd76e7 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -140,7 +140,7 @@ u16 Read_U16(const u32 _Address); u32 Read_U32(const u32 _Address); u64 Read_U64(const u32 _Address); -inline u8* GetPointerUnchecked(const u32 address) { +inline u8* GetPointerWriteUnchecked(const u32 address) { #ifdef MASKED_PSP_MEMORY return (u8 *)(base + (address & MEMVIEW32_MASK)); #else @@ -148,6 +148,14 @@ inline u8* GetPointerUnchecked(const u32 address) { #endif } +inline const u8* GetPointerUnchecked(const u32 address) { +#ifdef MASKED_PSP_MEMORY + return (const u8 *)(base + (address & MEMVIEW32_MASK)); +#else + return (const u8 *)(base + address); +#endif +} + inline u32 ReadUnchecked_U32(const u32 address) { #ifdef MASKED_PSP_MEMORY return *(u32_le *)(base + (address & MEMVIEW32_MASK)); @@ -236,7 +244,8 @@ inline void Write_Float(float f, u32 address) Write_U32(u, address); } -u8* GetPointer(const u32 address); +u8* GetPointerWrite(const u32 address); +const u8* GetPointer(const u32 address); bool IsRAMAddress(const u32 address); inline bool IsVRAMAddress(const u32 address) { return ((address & 0x3F800000) == 0x04000000); @@ -272,11 +281,11 @@ inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len } inline void MemcpyUnchecked(const u32 to_address, const void *from_data, const u32 len) { - memcpy(GetPointerUnchecked(to_address), from_data, len); + memcpy(GetPointerWriteUnchecked(to_address), from_data, len); } inline void MemcpyUnchecked(const u32 to_address, const u32 from_address, const u32 len) { - MemcpyUnchecked(GetPointer(to_address), from_address, len); + MemcpyUnchecked(GetPointerWrite(to_address), from_address, len); } inline bool IsValidAddress(const u32 address) { diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index b6bbf86b20..4c3e3ab81c 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -28,19 +28,19 @@ namespace Memory { -u8 *GetPointer(const u32 address) { +u8 *GetPointerWrite(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { // RAM - return GetPointerUnchecked(address); + return GetPointerWriteUnchecked(address); } else if ((address & 0x3F800000) == 0x04000000) { // VRAM - return GetPointerUnchecked(address); + return GetPointerWriteUnchecked(address); } else if ((address & 0xBFFFC000) == 0x00010000) { // Scratchpad - return GetPointerUnchecked(address); + return GetPointerWriteUnchecked(address); } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { // More RAM (remasters, etc.) - return GetPointerUnchecked(address); + return GetPointerWriteUnchecked(address); } else { static bool reported = false; if (!reported) { @@ -52,6 +52,10 @@ u8 *GetPointer(const u32 address) { } } +const u8 *GetPointer(const u32 address) { + return (const u8 *)GetPointerWrite(address); +} + template inline void ReadFromHardware(T &var, const u32 address) { // TODO: Figure out the fastest order of tests for both read and write (they are probably different). diff --git a/Core/MemMapHelpers.h b/Core/MemMapHelpers.h index b37fda3872..848bfa73b6 100644 --- a/Core/MemMapHelpers.h +++ b/Core/MemMapHelpers.h @@ -31,7 +31,7 @@ namespace Memory { inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const char *tag, size_t tagLen) { - u8 *to = GetPointer(to_address); + u8 *to = GetPointerWrite(to_address); if (to) { memcpy(to, from_data, len); if (!tag) { @@ -57,7 +57,7 @@ inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const c } inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char *tag, size_t tagLen) { - u8 *to = GetPointer(to_address); + u8 *to = GetPointerWrite(to_address); // If not, GetPointer will log. if (!to) return; diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 6af2348ae4..0755988029 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -192,7 +192,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, // // It does the simplest and safest test possible: If all points of a bbox is outside a single of // our clipping planes, we reject the box. Tighter bounds would be desirable but would take more calculations. -bool DrawEngineCommon::TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead) { +bool DrawEngineCommon::TestBoundingBox(const void* control_points, int vertexCount, u32 vertType, int *bytesRead) { SimpleVertex *corners = (SimpleVertex *)(decoded + 65536 * 12); float *verts = (float *)(decoded + 65536 * 18); @@ -217,7 +217,7 @@ bool DrawEngineCommon::TestBoundingBox(void* control_points, int vertexCount, u3 // Simplify away bones and morph before proceeding u8 *temp_buffer = decoded + 65536 * 24; int vertexSize = 0; - NormalizeVertices((u8 *)corners, temp_buffer, (u8 *)control_points, 0, vertexCount, vertType, &vertexSize); + NormalizeVertices((u8 *)corners, temp_buffer, (const u8 *)control_points, 0, vertexCount, vertType, &vertexSize); for (int i = 0; i < vertexCount; i++) { verts[i * 3] = corners[i].pos.x; verts[i * 3 + 1] = corners[i].pos.y; @@ -663,7 +663,7 @@ uint64_t DrawEngineCommon::ComputeHash() { } // vertTypeID is the vertex type but with the UVGen mode smashed into the top bits. -void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { +void DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) { DispatchFlush(); } diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index b49a1df6fa..e5b7f952da 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -69,18 +69,18 @@ public: // This would seem to be unnecessary now, but is still required for splines/beziers to work in the software backend since SubmitPrim // is different. Should probably refactor that. // Note that vertTypeID should be computed using GetVertTypeID(). - virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { + virtual void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, cullMode, bytesRead); } - virtual void DispatchSubmitImm(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { + virtual void DispatchSubmitImm(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, cullMode, bytesRead); DispatchFlush(); } - bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead); + bool TestBoundingBox(const void* control_points, int vertexCount, u32 vertType, int *bytesRead); - void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead); + void SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead); template void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope); void ClearSplineBezierWeights(); @@ -150,8 +150,8 @@ protected: // Defer all vertex decoding to a "Flush" (except when software skinning) struct DeferredDrawCall { - void *verts; - void *inds; + const void *verts; + const void *inds; u32 vertexCount; u8 indexType; s8 prim; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f5ea895bd5..b8f264d03c 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1694,7 +1694,7 @@ void FramebufferManagerCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2 return; } - u8 *addr = Memory::GetPointerUnchecked(gstate.getFrameBufAddress()); + u8 *addr = Memory::GetPointerWriteUnchecked(gstate.getFrameBufAddress()); const int bpp = gstate_c.framebufFormat == GE_FORMAT_8888 ? 4 : 2; u32 clearBits = clearColor; @@ -2033,7 +2033,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB if (!Memory::IsValidAddress(fb_address)) return false; // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, format); + buffer = GPUDebugBuffer(Memory::GetPointerWriteUnchecked(fb_address), fb_stride, 512, format); return true; } @@ -2090,7 +2090,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 if (!Memory::IsValidAddress(z_address)) return false; // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointerWriteUnchecked(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } @@ -2128,7 +2128,7 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G return false; // If there's no vfb and we're drawing there, must be memory? // TODO: Actually get the stencil. - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, GPU_DBG_FORMAT_8888); + buffer = GPUDebugBuffer(Memory::GetPointerWrite(fb_address), fb_stride, 512, GPU_DBG_FORMAT_8888); return true; } @@ -2193,7 +2193,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int return; } - u8 *destPtr = Memory::GetPointer(fb_address + dstByteOffset); + u8 *destPtr = Memory::GetPointerWriteUnchecked(fb_address + dstByteOffset); // We always need to convert from the framebuffer native format. // Right now that's always 8888. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 0d24e004c4..b5b3530a03 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1677,8 +1677,8 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { return; } - void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *inds = nullptr; + const void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + const void *inds = nullptr; u32 vertexType = gstate.vertType; if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { u32 indexAddr = gstate_c.indexAddr; @@ -1886,8 +1886,8 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { return; } - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; + const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + const void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); @@ -1956,8 +1956,8 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { return; } - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; + const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + const void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); @@ -2018,7 +2018,7 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) { return; } if (((count & 7) == 0) && count <= 64) { // Sanity check - void *control_points = Memory::GetPointer(gstate_c.vertexAddr); + const void *control_points = Memory::GetPointer(gstate_c.vertexAddr); if (!control_points) { ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Invalid verts in bounding box check"); currentList->bboxResult = true; @@ -2795,7 +2795,7 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) { u32 srcLineStartAddr = srcBasePtr + (srcY * srcStride + srcX) * bpp; u32 dstLineStartAddr = dstBasePtr + (dstY * dstStride + dstX) * bpp; const u8 *src = Memory::GetPointerUnchecked(srcLineStartAddr); - u8 *dst = Memory::GetPointerUnchecked(dstLineStartAddr); + u8 *dst = Memory::GetPointerWriteUnchecked(dstLineStartAddr); memcpy(dst, src, width * height * bpp); GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * height * bpp); } else { @@ -2804,7 +2804,7 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) { u32 dstLineStartAddr = dstBasePtr + ((y + dstY) * dstStride + dstX) * bpp; const u8 *src = Memory::GetPointerUnchecked(srcLineStartAddr); - u8 *dst = Memory::GetPointerUnchecked(dstLineStartAddr); + u8 *dst = Memory::GetPointerWriteUnchecked(dstLineStartAddr); memcpy(dst, src, width * bpp); GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * bpp); } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 8fff0f3f4e..36cd871ecb 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -1412,7 +1412,7 @@ bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) Sampler::FetchFunc sampler = Sampler::GetFetchFunc(id); - u8 *texptr = Memory::GetPointer(texaddr); + u8 *texptr = Memory::GetPointerWrite(texaddr); u32 *row = (u32 *)buffer.GetData(); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { diff --git a/GPU/Software/Rasterizer.h b/GPU/Software/Rasterizer.h index 9a3911f242..2725bb922e 100644 --- a/GPU/Software/Rasterizer.h +++ b/GPU/Software/Rasterizer.h @@ -40,7 +40,7 @@ struct RasterizerState { Sampler::NearestFunc nearest; uint32_t texaddr[8]{}; int texbufw[8]{}; - u8 *texptr[8]{}; + const u8 *texptr[8]{}; float textureLodSlope; int screenOffsetX; int screenOffsetY; diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 16ebc29940..6a4ddf88b7 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -395,8 +395,8 @@ const SoftwareCommandTableEntry softgpuCommandTable[] = { SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw) { - fb.data = Memory::GetPointer(0x44000000); // TODO: correct default address? - depthbuf.data = Memory::GetPointer(0x44000000); // TODO: correct default address? + fb.data = Memory::GetPointerWrite(0x44000000); // TODO: correct default address? + depthbuf.data = Memory::GetPointerWrite(0x44000000); // TODO: correct default address? memset(softgpuCmdInfo, 0, sizeof(softgpuCmdInfo)); @@ -494,7 +494,7 @@ void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, in // TODO: This should probably be converted in a shader instead.. fbTexBuffer_.resize(srcwidth * srcheight); FormatBuffer displayBuffer; - displayBuffer.data = overrideData ? overrideData : Memory::GetPointer(displayFramebuf_); + displayBuffer.data = overrideData ? overrideData : Memory::GetPointerWrite(displayFramebuf_); for (int y = 0; y < srcheight; ++y) { u32 *buf_line = &fbTexBuffer_[y * srcwidth]; const u16 *fb_line = &displayBuffer.as16[y * displayStride_]; @@ -557,7 +557,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { bool hasPostShader = presentation_ && presentation_->HasPostShader(); if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch != DSStretch::Off) { - u8 *data = Memory::GetPointer(0x04088000); + u8 *data = Memory::GetPointerWrite(0x04088000); bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. @@ -586,13 +586,13 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { hasImage = false; u1 = 1.0f; } else if (displayFormat_ == GE_FORMAT_8888) { - u8 *data = Memory::GetPointer(displayFramebuf_); + u8 *data = Memory::GetPointerWrite(displayFramebuf_); desc.width = displayStride_ == 0 ? srcwidth : displayStride_; desc.height = srcheight; desc.initData.push_back(data); desc.format = Draw::DataFormat::R8G8B8A8_UNORM; } else if (displayFormat_ == GE_FORMAT_5551) { - u8 *data = Memory::GetPointer(displayFramebuf_); + const u8 *data = Memory::GetPointerWrite(displayFramebuf_); bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. @@ -797,7 +797,7 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) { u32 dstLineStartAddr = dstBasePtr + (dstY * dstStride + dstX) * bpp; const u8 *srcp = Memory::GetPointer(srcLineStartAddr); - u8 *dstp = Memory::GetPointer(dstLineStartAddr); + u8 *dstp = Memory::GetPointerWrite(dstLineStartAddr); memcpy(dstp, srcp, width * height * bpp); GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * height * bpp); } else { @@ -806,7 +806,7 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) { u32 dstLineStartAddr = dstBasePtr + ((y + dstY) * dstStride + dstX) * bpp; const u8 *srcp = Memory::GetPointer(srcLineStartAddr); - u8 *dstp = Memory::GetPointer(dstLineStartAddr); + u8 *dstp = Memory::GetPointerWrite(dstLineStartAddr); memcpy(dstp, srcp, width * bpp); GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * bpp); } @@ -837,14 +837,14 @@ void SoftGPU::Execute_Prim(u32 op, u32 diff) { return; } - void *verts = Memory::GetPointer(gstate_c.vertexAddr); - void *indices = NULL; + const void *verts = Memory::GetPointer(gstate_c.vertexAddr); + const void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { ERROR_LOG_REPORT(G3D, "Software: Bad index address %08x!", gstate_c.indexAddr); return; } - indices = Memory::GetPointer(gstate_c.indexAddr); + indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } cyclesExecuted += EstimatePerVertexCost() * count; @@ -875,8 +875,8 @@ void SoftGPU::Execute_Bezier(u32 op, u32 diff) { return; } - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; + const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + const void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); @@ -927,8 +927,8 @@ void SoftGPU::Execute_Spline(u32 op, u32 diff) { return; } - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; + const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + const void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); @@ -1002,7 +1002,7 @@ void SoftGPU::Execute_LoadClut(u32 op, u32 diff) { void SoftGPU::Execute_FramebufPtr(u32 op, u32 diff) { // We assume fb.data won't change while we're drawing. drawEngine_->transformUnit.Flush("framebuf"); - fb.data = Memory::GetPointer(gstate.getFrameBufAddress()); + fb.data = Memory::GetPointerWrite(gstate.getFrameBufAddress()); } void SoftGPU::Execute_FramebufFormat(u32 op, u32 diff) { @@ -1013,7 +1013,7 @@ void SoftGPU::Execute_FramebufFormat(u32 op, u32 diff) { void SoftGPU::Execute_ZbufPtr(u32 op, u32 diff) { // We assume depthbuf.data won't change while we're drawing. drawEngine_->transformUnit.Flush("depthbuf"); - depthbuf.data = Memory::GetPointer(gstate.getDepthBufAddress()); + depthbuf.data = Memory::GetPointerWrite(gstate.getDepthBufAddress()); } void SoftGPU::Execute_VertexType(u32 op, u32 diff) { diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 57a320b9ba..378b558bea 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -65,12 +65,12 @@ void SoftwareDrawEngine::DispatchFlush() { transformUnit.Flush("debug"); } -void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { +void SoftwareDrawEngine::DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { _assert_msg_(cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this); } -void SoftwareDrawEngine::DispatchSubmitImm(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { +void SoftwareDrawEngine::DispatchSubmitImm(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { _assert_msg_(cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); // TODO: For now, just setting all dirty. transformUnit.SetDirty(SoftDirty(-1)); @@ -449,7 +449,7 @@ enum class CullType { OFF, }; -void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine) +void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine) { VertexDecoder &vdecoder = *drawEngine->FindVertexDecoder(vertex_type); const DecVtxFormat &vtxfmt = vdecoder.GetDecVtxFmt(); diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index 8b7eedb4eb..9f17ed1197 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -118,7 +118,7 @@ public: } static ScreenCoords DrawingToScreen(const DrawingCoords &coords, u16 z); - void SubmitPrimitive(void* vertices, void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine); + void SubmitPrimitive(const void* vertices, const void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine); bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices); @@ -144,8 +144,8 @@ public: ~SoftwareDrawEngine(); void DispatchFlush() override; - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int cullMode, int *bytesRead) override; - void DispatchSubmitImm(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) override; + void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int cullMode, int *bytesRead) override; + void DispatchSubmitImm(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) override; VertexDecoder *FindVertexDecoder(u32 vtype); From 861d66a4d4df871054d33c9ae26f2ec268d648f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 13:33:03 +0200 Subject: [PATCH 38/57] Separate logging for GetPointer/GetPointerWrite --- Core/HLE/sceIo.cpp | 4 ++-- Core/MemMapFunctions.cpp | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 7ce98cc2ff..575f4be959 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1042,7 +1042,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { } else if (Memory::IsValidAddress(data_addr)) { const std::string tag = "IoRead/" + IODetermineFilename(f); NotifyMemInfo(MemBlockFlags::WRITE, data_addr, size, tag.c_str(), tag.size()); - u8 *data = (u8 *)Memory::GetPointer(data_addr); + u8 *data = (u8 *)Memory::GetPointerUnchecked(data_addr); u32 validSize = Memory::ValidSize(data_addr, size); if (f->npdrm) { result = npdrmRead(f, data, validSize); @@ -2482,7 +2482,7 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44}; if (Memory::IsValidAddress(indataPtr) && inlen == 16) { - memcpy(keybuf, Memory::GetPointer(indataPtr), 16); + memcpy(keybuf, Memory::GetPointerUnchecked(indataPtr), 16); key_ptr = keybuf; }else{ key_ptr = NULL; diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 4c3e3ab81c..da4fbcf382 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -29,22 +29,15 @@ namespace Memory { u8 *GetPointerWrite(const u32 address) { - if ((address & 0x3E000000) == 0x08000000) { - // RAM - return GetPointerWriteUnchecked(address); - } else if ((address & 0x3F800000) == 0x04000000) { - // VRAM - return GetPointerWriteUnchecked(address); - } else if ((address & 0xBFFFC000) == 0x00010000) { - // Scratchpad - return GetPointerWriteUnchecked(address); - } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { - // More RAM (remasters, etc.) + if ((address & 0x3E000000) == 0x08000000 || // RAM + (address & 0x3F800000) == 0x04000000 || // VRAM + (address & 0xBFFFC000) == 0x00010000 || // Scratchpad + ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.) return GetPointerWriteUnchecked(address); } else { static bool reported = false; if (!reported) { - Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); + Reporting::ReportMessage("Unknown GetPointerWrite %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK); @@ -53,7 +46,20 @@ u8 *GetPointerWrite(const u32 address) { } const u8 *GetPointer(const u32 address) { - return (const u8 *)GetPointerWrite(address); + if ((address & 0x3E000000) == 0x08000000 || // RAM + (address & 0x3F800000) == 0x04000000 || // VRAM + (address & 0xBFFFC000) == 0x00010000 || // Scratchpad + ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.) + return GetPointerUnchecked(address); + } else { + static bool reported = false; + if (!reported) { + Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); + reported = true; + } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::READ_BLOCK); + return nullptr; + } } template From 881cc239655fde1906fb2f43366151282974c41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 23 Mar 2020 00:13:31 +0100 Subject: [PATCH 39/57] Delete some unused code. --- Common/GPU/Vulkan/VulkanMemory.h | 1 - Core/Util/PPGeDraw.cpp | 10 +++------- GPU/Common/FramebufferManagerCommon.h | 1 - 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanMemory.h b/Common/GPU/Vulkan/VulkanMemory.h index c68e76c4dd..079996b8a6 100644 --- a/Common/GPU/Vulkan/VulkanMemory.h +++ b/Common/GPU/Vulkan/VulkanMemory.h @@ -3,7 +3,6 @@ #include #include #include -#include #include "Common/GPU/Vulkan/VulkanContext.h" diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index ccd5a79bd5..425552a453 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -29,6 +29,7 @@ #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/Config.h" +#include "Common/BitScan.h" #include "Core/HDRemaster.h" #include "Core/Host.h" #include "GPU/ge_constants.h" @@ -841,14 +842,9 @@ void PPGeDrawCurrentText(u32 color) } // Return a value such that (1 << value) >= x -int GetPow2(int x) { -#ifdef __GNUC__ - int ret = 31 - __builtin_clz(x | 1); +inline int GetPow2(int x) { + int ret = 31 - clz32_nonzero(x | 1); if ((1 << ret) < x) -#else - int ret = 0; - while ((1 << ret) < x) -#endif ret++; return ret; } diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 2c31d5e668..936b59baf3 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -25,7 +25,6 @@ #pragma once -#include #include #include From f523341351687a5b386a8864e6ae7f7aef82d7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 20 Jul 2022 10:27:08 +0200 Subject: [PATCH 40/57] Remove unnecessary parameters from MakePixelsTexture --- GPU/Common/FramebufferManagerCommon.cpp | 6 +++--- GPU/Common/FramebufferManagerCommon.h | 2 +- GPU/D3D11/StencilBufferD3D11.cpp | 10 ++++------ GPU/Directx9/StencilBufferDX9.cpp | 10 ++++------ GPU/GLES/StencilBufferGLES.cpp | 6 ++---- GPU/Vulkan/StencilBufferVulkan.cpp | 4 +--- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f5ea895bd5..b727cd61aa 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -852,7 +852,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); } - Draw::Texture *pixelsTex = MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height, u1, v1); + Draw::Texture *pixelsTex = MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); if (pixelsTex) { draw_->BindTextures(0, 1, &pixelsTex); Bind2DShader(); @@ -934,7 +934,7 @@ void FramebufferManagerCommon::CopyFramebufferForColorTexture(VirtualFramebuffer } } -Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) { +Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { // TODO: We can just change the texture format and flip some bits around instead of this. // Could share code with the texture cache perhaps. auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) { @@ -1009,7 +1009,7 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu float u0 = 0.0f, u1 = 480.0f / 512.0f; float v0 = 0.0f, v1 = 1.0f; - Draw::Texture *pixelsTex = MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272, u1, v1); + Draw::Texture *pixelsTex = MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); if (!pixelsTex) return; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 936b59baf3..862d3e28f7 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -335,7 +335,7 @@ public: protected: virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h); void SetViewport2D(int x, int y, int w, int h); - Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1); + Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); virtual void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) = 0; virtual void Bind2DShader() = 0; diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index 8a552ab2f2..eee531b55f 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -157,9 +157,7 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl u16 w = dstBuffer->renderWidth; u16 h = dstBuffer->renderHeight; - float u1 = 1.0f; - float v1 = 1.0f; - Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1); + Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight); if (!tex) return false; if (dstBuffer->fbo) { @@ -175,9 +173,9 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl float coord[20] = { -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, u1, 0.0f, - -1.0f, -1.0f, 0.0f, 0.0f, v1, - 1.0f, -1.0f, 0.0f, u1, v1, + 1.0f, 1.0f, 0.0f, 1.0, 0.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 1.0, + 1.0f, -1.0f, 0.0f, 1.0, 1.0, }; D3D11_MAPPED_SUBRESOURCE map; diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 1817e4e0fb..2e0c2c4468 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -196,9 +196,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f }; device_->SetViewport(&vp); - float u1 = 1.0f; - float v1 = 1.0f; - Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1); + Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight); if (!tex) return false; @@ -208,9 +206,9 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa float coord[20] = { -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, u1, 0.0f, - -1.0f, -1.0f, 0.0f, 0.0f, v1, - 1.0f, -1.0f, 0.0f, u1, v1, + 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, }; device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index b658db3c17..4c35fb4967 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -177,10 +177,8 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo } render_->SetViewport({ 0, 0, (float)w, (float)h, 0.0f, 1.0f }); - float u1 = 1.0f; - float v1 = 1.0f; textureCache_->ForgetLastTexture(); - Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height, u1, v1); + Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height); if (!tex) return false; @@ -210,7 +208,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo render_->SetStencilOp(i, GL_REPLACE, GL_REPLACE, GL_REPLACE); render_->SetUniformF1(&u_stencilValue, i * (1.0f / 255.0f)); } - DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST | DRAWTEX_KEEP_STENCIL_ALPHA); + DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST | DRAWTEX_KEEP_STENCIL_ALPHA); } if (useBlit) { diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 0bb76ee439..6998455aef 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -168,9 +168,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp u16 w = dstBuffer->renderWidth; u16 h = dstBuffer->renderHeight; - float u1 = 1.0f; - float v1 = 1.0f; - Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1); + Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight); if (!tex) return false; From d3d601dced0033a51a5574042227e637306bb2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 13:58:20 +0200 Subject: [PATCH 41/57] Windows fixes --- GPU/Directx9/FramebufferManagerDX9.cpp | 8 ++++---- Windows/Debugger/CtrlMemView.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 15cb846a1b..114feb54b8 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -369,7 +369,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { // TODO: Handle the other formats? We don't currently create them, I think. const int dstByteOffset = (y * vfb->fb_stride + x) * dstBpp; // Pixel size always 4 here because we always request BGRA8888. - ConvertFromBGRA8888(Memory::GetPointer(fb_address + dstByteOffset), (u8 *)locked.pBits, vfb->fb_stride, locked.Pitch / 4, w, h, vfb->format); + ConvertFromBGRA8888(Memory::GetPointerWrite(fb_address + dstByteOffset), (u8 *)locked.pBits, vfb->fb_stride, locked.Pitch / 4, w, h, vfb->format); offscreen->UnlockRect(); } else { ERROR_LOG_REPORT(G3D, "Unable to lock rect from %08x: %d,%d %dx%d of %dx%d", fb_address, (int)rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom, vfb->renderWidth, vfb->renderHeight); @@ -464,7 +464,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!Memory::IsValidAddress(fb_address)) return false; // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, fb_format); + buffer = GPUDebugBuffer(Memory::GetPointerWrite(fb_address), fb_stride, 512, fb_format); return true; } LPDIRECT3DSURFACE9 renderTarget = vfb->fbo ? (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0) : nullptr; @@ -541,7 +541,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointerWrite(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } @@ -579,7 +579,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(vfb->z_address), vfb->z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointerWrite(vfb->z_address), vfb->z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 281a700bd9..11271ba00e 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -779,7 +779,7 @@ std::vector CtrlMemView::searchString(const std::string &searchQuery) { return searchResAddrs; } - u8 *ptr = Memory::GetPointerUnchecked(pos); + const u8 *ptr = Memory::GetPointerUnchecked(pos); if (memcmp(ptr, searchData.data(), searchData.size()) == 0) { searchResAddrs.push_back(pos); } @@ -798,7 +798,7 @@ void CtrlMemView::search(bool continueSearch) u32 searchAddress = 0; u32 segmentStart = 0; u32 segmentEnd = 0; - u8* dataPointer = 0; + const u8* dataPointer = 0; if (continueSearch == false || searchQuery.empty()) { if (InputBox_GetString(GetModuleHandle(NULL), wnd, L"Search for", searchQuery, searchQuery) == false) From f9a25458d567022686f1890e06737c864b4c053d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 14:10:12 +0200 Subject: [PATCH 42/57] Libretro fix --- libretro/libretro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 330a70bde6..eacbca25e5 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1409,7 +1409,7 @@ bool retro_unserialize(const void *data, size_t size) void *retro_get_memory_data(unsigned id) { if ( id == RETRO_MEMORY_SYSTEM_RAM ) - return Memory::GetPointerUnchecked(PSP_GetKernelMemoryBase()) ; + return Memory::GetPointerWriteUnchecked(PSP_GetKernelMemoryBase()) ; return NULL; } From 89845eae7a2d7b9a3373c7ee86b94d776a8c792d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 17:12:43 +0200 Subject: [PATCH 43/57] Add GPU stat for number of depth copies per frame Will be useful for evaluating #15700 --- GPU/Common/FramebufferManagerCommon.cpp | 2 ++ GPU/GPU.h | 2 ++ GPU/GPUCommon.cpp | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f7f993e770..b6b7c28d96 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -494,6 +494,8 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir return; } + gpuStats.numDepthCopies++; + int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); diff --git a/GPU/GPU.h b/GPU/GPU.h index 0a4fb4f66d..83a21481c2 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -75,6 +75,7 @@ struct GPUStatistics { numReadbacks = 0; numUploads = 0; numClears = 0; + numDepthCopies = 0; msProcessingDisplayLists = 0; vertexGPUCycles = 0; otherGPUCycles = 0; @@ -100,6 +101,7 @@ struct GPUStatistics { int numReadbacks; int numUploads; int numClears; + int numDepthCopies; double msProcessingDisplayLists; int vertexGPUCycles; int otherGPUCycles; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b5b3530a03..d78140f9f2 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -3029,7 +3029,7 @@ size_t GPUCommon::FormatGPUStatsCommon(char *buffer, size_t size) { "Vertices: %d cached: %d uncached: %d\n" "FBOs active: %d (evaluations: %d)\n" "Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\n" - "Readbacks: %d, uploads: %d\n" + "Readbacks: %d, uploads: %d, depth copies: %d\n" "GPU cycles executed: %d (%f per vertex)\n", gpuStats.msProcessingDisplayLists * 1000.0f, gpuStats.numDrawCalls, @@ -3049,6 +3049,7 @@ size_t GPUCommon::FormatGPUStatsCommon(char *buffer, size_t size) { gpuStats.numTextureDataBytesHashed / 1024, gpuStats.numReadbacks, gpuStats.numUploads, + gpuStats.numDepthCopies, gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, vertexAverageCycles ); From 80f0f90af770fbc091502b0a2737053c8231d8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 17:41:27 +0200 Subject: [PATCH 44/57] Revert the x-offset bpp fix temporarily. --- GPU/Common/FramebufferManagerCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 03f6f370b6..97008df8c2 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -306,7 +306,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame } break; } else if (v->fb_stride == params.fb_stride && v->format == params.fmt) { - u32 v_fb_first_line_end_ptr = v->fb_address + v->fb_stride * bpp; + u32 v_fb_first_line_end_ptr = v->fb_address + v->fb_stride * 4; // This should be * bpp, but leaving like this until after 1.13 to be safe. The God of War games use this for shadows. u32 v_fb_end_ptr = v->fb_address + v->fb_stride * v->height * bpp; if (params.fb_address > v->fb_address && params.fb_address < v_fb_first_line_end_ptr) { From 8f230252099010dc96f4de755f2731d832c65d13 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 10:37:54 -0700 Subject: [PATCH 45/57] irjit: Add tests for IR passes. --- CMakeLists.txt | 1 + Core/MIPS/IR/IRPassSimplify.cpp | 1 + Core/MIPS/IR/IRRegCache.cpp | 3 +- Core/MIPS/MIPSAnalyst.cpp | 2 +- android/jni/Android.mk | 1 + unittest/TestIRPassSimplify.cpp | 149 +++++++++++++++++++++++++++++ unittest/UnitTest.cpp | 2 + unittest/UnitTests.vcxproj | 1 + unittest/UnitTests.vcxproj.filters | 1 + 9 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 unittest/TestIRPassSimplify.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 22b4b802c3..5be55987dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2321,6 +2321,7 @@ if(UNITTEST) unittest/TestShaderGenerators.cpp unittest/TestArmEmitter.cpp unittest/TestArm64Emitter.cpp + unittest/TestIRPassSimplify.cpp unittest/TestX64Emitter.cpp unittest/TestVertexJit.cpp unittest/TestSoftwareGPUJit.cpp diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index 80972d3ff3..0ba252a018 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -738,6 +738,7 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts } } } + gpr.FlushAll(); return logBlocks; } diff --git a/Core/MIPS/IR/IRRegCache.cpp b/Core/MIPS/IR/IRRegCache.cpp index 63ae135878..ca54392be1 100644 --- a/Core/MIPS/IR/IRRegCache.cpp +++ b/Core/MIPS/IR/IRRegCache.cpp @@ -27,8 +27,7 @@ IRRegCache::IRRegCache(IRWriter *ir) : ir_(ir) { void IRRegCache::FlushAll() { for (int i = 0; i < TOTAL_MAPPABLE_MIPSREGS; i++) { - //if (i < IRTEMP_0) - Flush(i); + Flush(i); } } diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index f88dde62bf..2c4e11bea4 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -1462,7 +1462,7 @@ skip: } break; case 0x08: // addi - case 0x09: // adiu + case 0x09: // addiu info.hasRelevantAddress = true; info.relevantAddress = cpu->GetRegValue(0,MIPS_GET_RS(op))+((s16)(op & 0xFFFF)); break; diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 89cfded9f6..d133898544 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -734,6 +734,7 @@ ifeq ($(UNITTEST),1) LOCAL_MODULE := ppsspp_unittest LOCAL_SRC_FILES := \ $(SRC)/unittest/JitHarness.cpp \ + $(SRC)/unittest/TestIRPassSimplify.cpp \ $(SRC)/unittest/TestShaderGenerators.cpp \ $(SRC)/unittest/TestSoftwareGPUJit.cpp \ $(SRC)/unittest/TestThreadManager.cpp \ diff --git a/unittest/TestIRPassSimplify.cpp b/unittest/TestIRPassSimplify.cpp new file mode 100644 index 0000000000..93b57d4115 --- /dev/null +++ b/unittest/TestIRPassSimplify.cpp @@ -0,0 +1,149 @@ +// Copyright (c) 2022- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include +#include "Core/MIPS/IR/IRInst.h" +#include "Core/MIPS/IR/IRPassSimplify.h" + +struct IRVerification { + const char *name; + const std::vector input; + const std::vector expected; + const std::vector passes; +}; + +static void LogInstructions(const std::vector &insts) { + for (size_t i = 0; i < insts.size(); ++i) { + char buf[256]; + DisassembleIR(buf, sizeof(buf), insts[i]); + printf(" %s\n", buf); + } +} + +static bool VerifyPass(const IRVerification &v) { + IRWriter in, out; + IROptions opts{}; + opts.unalignedLoadStore = true; + + for (const auto &inst : v.input) + in.Write(inst); + if (IRApplyPasses(v.passes.data(), v.passes.size(), in, out, opts)) { + printf("%s FAILED: Unable to apply passes (or wanted to log)\n", v.name); + return false; + } + + const std::vector actual = out.GetInstructions(); + if (actual.size() != v.expected.size()) { + printf("%s FAILED: produced %d instructions, expected %d\n", v.name, (int)actual.size(), (int)v.expected.size()); + printf("Actual:\n"); + LogInstructions(actual); + printf("Expected:\n"); + LogInstructions(v.expected); + return false; + } + + for (size_t i = 0; i < actual.size(); ++i) { + if (memcmp(&v.expected[i], &actual[i], sizeof(IRInst)) != 0) { + char actualBuf[256]; + DisassembleIR(actualBuf, sizeof(actualBuf), actual[i]); + char expectedBuf[256]; + DisassembleIR(expectedBuf, sizeof(expectedBuf), v.expected[i]); + + if (strcmp(expectedBuf, actualBuf) == 0) { + // This means a field (like src2) was left set but isn't relevant. Ignore. + continue; + } + + printf("%s FAILED: #%d expected '%s' but was '%s'", v.name, (int)i, expectedBuf, actualBuf); + return false; + } + } + + return true; +} + +static const IRVerification tests[] = { + { + "SimplePurgeTemps", + { + { IROp::Add, IRTEMP_0, MIPS_REG_A0, MIPS_REG_A1 }, + { IROp::Mov, MIPS_REG_V0, IRTEMP_0 }, + { IROp::Add, IRTEMP_0, MIPS_REG_A2, MIPS_REG_A3 }, + { IROp::Mov, MIPS_REG_V1, IRTEMP_0 }, + }, + { + { IROp::Add, MIPS_REG_V0, MIPS_REG_A0, MIPS_REG_A1 }, + { IROp::Add, MIPS_REG_V1, MIPS_REG_A2, MIPS_REG_A3 }, + }, + { &PurgeTemps }, + }, + { + "SwapClobberTemp", + { + { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, + { IROp::Slt, MIPS_REG_A0, MIPS_REG_V0, MIPS_REG_V1 }, + }, + { + { IROp::Sub, MIPS_REG_S0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Slt, MIPS_REG_A0, MIPS_REG_V0, MIPS_REG_V1 }, + }, + { &PurgeTemps }, + }, + { + "SimplePropagateConstants", + { + { IROp::SetConst, MIPS_REG_A0, 0, 0, 0x12340000 }, + { IROp::OrConst, MIPS_REG_A0, MIPS_REG_A0, 0, 0x00005678 }, + { IROp::AddConst, MIPS_REG_A1, MIPS_REG_A0, 0, 0 }, + { IROp::AddConst, MIPS_REG_A2, MIPS_REG_A0, 0, 0x00001111 }, + }, + { + { IROp::SetConst, MIPS_REG_A0, 0, 0, 0x12345678 }, + { IROp::SetConst, MIPS_REG_A1, 0, 0, 0x12345678 }, + { IROp::SetConst, MIPS_REG_A2, 0, 0, 0x12346789 }, + }, + { &PropagateConstants }, + }, + { + // Needed for PurgeTemps optimizations to work. + "OrToMov", + { + { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Or, MIPS_REG_S0, MIPS_REG_A0, MIPS_REG_ZERO }, + { IROp::Add, MIPS_REG_S1, MIPS_REG_A0, MIPS_REG_ZERO }, + }, + { + { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S1, MIPS_REG_A0 }, + }, + { &PropagateConstants }, + }, +}; + +bool TestIRPassSimplify() { + InitIR(); + + for (const auto &test : tests) { + if (!VerifyPass(test)) + return false; + } + + return true; +} diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 80c0cbcb1c..6bb000418e 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -756,6 +756,7 @@ bool TestArm64Emitter(); bool TestX64Emitter(); bool TestShaderGenerators(); bool TestSoftwareGPUJit(); +bool TestIRPassSimplify(); bool TestThreadManager(); TestItem availableTests[] = { @@ -774,6 +775,7 @@ TestItem availableTests[] = { TEST_ITEM(VFPUSinCos), TEST_ITEM(MathUtil), TEST_ITEM(Parsers), + TEST_ITEM(IRPassSimplify), TEST_ITEM(Jit), TEST_ITEM(MatrixTranspose), TEST_ITEM(ParseLBN), diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index ca158dd1e5..dc50dacf92 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -382,6 +382,7 @@ true true + diff --git a/unittest/UnitTests.vcxproj.filters b/unittest/UnitTests.vcxproj.filters index bfa4b8bef8..d0e70e6021 100644 --- a/unittest/UnitTests.vcxproj.filters +++ b/unittest/UnitTests.vcxproj.filters @@ -14,6 +14,7 @@ + From 2154f747fccdd4eeafb3976213c5737454578d76 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 10:44:59 -0700 Subject: [PATCH 46/57] irjit: Simplify more arithmetic to Movs. Later passes rely on things being Mov, so better to have them more often. --- Core/MIPS/IR/IRPassSimplify.cpp | 13 +++++++++---- unittest/TestIRPassSimplify.cpp | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index 0ba252a018..6c6de0c16c 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -416,8 +416,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts } else if (gpr.IsImm(inst.src2)) { const u32 imm2 = gpr.GetImm(inst.src2); gpr.MapDirtyIn(inst.dest, inst.src1); - if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) { - // Add / Or with zero is just a Mov. + if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Sub || inst.op == IROp::Or || inst.op == IROp::Xor)) { + // Add / Sub / Or / Xor with zero is just a Mov. Add / Or are most common. if (inst.dest != inst.src1) out.Write(IROp::Mov, inst.dest, inst.src1); } else { @@ -426,8 +426,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts } else if (symmetric && gpr.IsImm(inst.src1)) { const u32 imm1 = gpr.GetImm(inst.src1); gpr.MapDirtyIn(inst.dest, inst.src2); - if (imm1 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) { - // Add / Or with zero is just a Mov. + if (imm1 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or || inst.op == IROp::Xor)) { + // Add / Or / Xor with zero is just a Mov. if (inst.dest != inst.src2) out.Write(IROp::Mov, inst.dest, inst.src2); } else { @@ -467,6 +467,11 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts gpr.SetImm(inst.dest, 0); } else if (gpr.IsImm(inst.src1)) { gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), inst.constant, inst.op)); + } else if (inst.constant == 0 && (inst.op == IROp::AddConst || inst.op == IROp::SubConst || inst.op == IROp::OrConst || inst.op == IROp::XorConst)) { + // Convert an Add/Sub/Or/Xor with a constant zero to a Mov (just like with reg zero.) + gpr.MapDirtyIn(inst.dest, inst.src1); + if (inst.dest != inst.src1) + out.Write(IROp::Mov, inst.dest, inst.src1); } else { gpr.MapDirtyIn(inst.dest, inst.src1); goto doDefault; diff --git a/unittest/TestIRPassSimplify.cpp b/unittest/TestIRPassSimplify.cpp index 93b57d4115..e04dfecbe6 100644 --- a/unittest/TestIRPassSimplify.cpp +++ b/unittest/TestIRPassSimplify.cpp @@ -127,11 +127,15 @@ static const IRVerification tests[] = { { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, { IROp::Or, MIPS_REG_S0, MIPS_REG_A0, MIPS_REG_ZERO }, { IROp::Add, MIPS_REG_S1, MIPS_REG_A0, MIPS_REG_ZERO }, + { IROp::OrConst, MIPS_REG_S2, MIPS_REG_A0, 0, 0 }, + { IROp::AddConst, MIPS_REG_S3, MIPS_REG_A0, 0, 0 }, }, { { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, { IROp::Mov, MIPS_REG_S1, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S2, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S3, MIPS_REG_A0 }, }, { &PropagateConstants }, }, From 257923294956e716254d417818a5131efd71b2a8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 10:45:41 -0700 Subject: [PATCH 47/57] Headless: Ignore __testcompare.png in tree. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 52b13f29d4..b7653209ae 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ __testoutput.txt __testerror.txt __testfinish.txt __testfailure.bmp +__testcompare.png GameLogNotes.txt screenshots android/assets/lang From 16188fa4376cec288ba654085ff536ad43b1812a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 10:56:43 -0700 Subject: [PATCH 48/57] irjit: Add test for double clobber in #15713. --- unittest/TestIRPassSimplify.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/unittest/TestIRPassSimplify.cpp b/unittest/TestIRPassSimplify.cpp index e04dfecbe6..3e2507cf29 100644 --- a/unittest/TestIRPassSimplify.cpp +++ b/unittest/TestIRPassSimplify.cpp @@ -105,6 +105,20 @@ static const IRVerification tests[] = { }, { &PurgeTemps }, }, + { + "DoubleClobberTemp", + { + { IROp::Add, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S0, MIPS_REG_A1 }, + }, + { + { IROp::Add, MIPS_REG_S0, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, MIPS_REG_A0, MIPS_REG_S0 }, + { IROp::Mov, MIPS_REG_S0, MIPS_REG_A1 }, + }, + { &PurgeTemps }, + }, { "SimplePropagateConstants", { From b620c966e0f9548c984a8750cd8796dee64f6c26 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 11:52:19 -0700 Subject: [PATCH 49/57] irjit: Correct initialization warning. --- unittest/TestIRPassSimplify.cpp | 68 ++++++++++++++++----------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/unittest/TestIRPassSimplify.cpp b/unittest/TestIRPassSimplify.cpp index 3e2507cf29..2703a3edaf 100644 --- a/unittest/TestIRPassSimplify.cpp +++ b/unittest/TestIRPassSimplify.cpp @@ -81,56 +81,56 @@ static const IRVerification tests[] = { { "SimplePurgeTemps", { - { IROp::Add, IRTEMP_0, MIPS_REG_A0, MIPS_REG_A1 }, - { IROp::Mov, MIPS_REG_V0, IRTEMP_0 }, - { IROp::Add, IRTEMP_0, MIPS_REG_A2, MIPS_REG_A3 }, - { IROp::Mov, MIPS_REG_V1, IRTEMP_0 }, + { IROp::Add, { IRTEMP_0 }, MIPS_REG_A0, MIPS_REG_A1 }, + { IROp::Mov, { MIPS_REG_V0 }, IRTEMP_0 }, + { IROp::Add, { IRTEMP_0 }, MIPS_REG_A2, MIPS_REG_A3 }, + { IROp::Mov, { MIPS_REG_V1 }, IRTEMP_0 }, }, { - { IROp::Add, MIPS_REG_V0, MIPS_REG_A0, MIPS_REG_A1 }, - { IROp::Add, MIPS_REG_V1, MIPS_REG_A2, MIPS_REG_A3 }, + { IROp::Add, { MIPS_REG_V0 }, MIPS_REG_A0, MIPS_REG_A1 }, + { IROp::Add, { MIPS_REG_V1 }, MIPS_REG_A2, MIPS_REG_A3 }, }, { &PurgeTemps }, }, { "SwapClobberTemp", { - { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, - { IROp::Slt, MIPS_REG_A0, MIPS_REG_V0, MIPS_REG_V1 }, + { IROp::Sub, { MIPS_REG_A0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, { MIPS_REG_S0 }, MIPS_REG_A0 }, + { IROp::Slt, { MIPS_REG_A0 }, MIPS_REG_V0, MIPS_REG_V1 }, }, { - { IROp::Sub, MIPS_REG_S0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Slt, MIPS_REG_A0, MIPS_REG_V0, MIPS_REG_V1 }, + { IROp::Sub, { MIPS_REG_S0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Slt, { MIPS_REG_A0 }, MIPS_REG_V0, MIPS_REG_V1 }, }, { &PurgeTemps }, }, { "DoubleClobberTemp", { - { IROp::Add, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, - { IROp::Mov, MIPS_REG_S0, MIPS_REG_A1 }, + { IROp::Add, { MIPS_REG_A0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, { MIPS_REG_S0 }, MIPS_REG_A0 }, + { IROp::Mov, { MIPS_REG_S0 }, MIPS_REG_A1 }, }, { - { IROp::Add, MIPS_REG_S0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Mov, MIPS_REG_A0, MIPS_REG_S0 }, - { IROp::Mov, MIPS_REG_S0, MIPS_REG_A1 }, + { IROp::Add, { MIPS_REG_S0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, { MIPS_REG_A0 }, MIPS_REG_S0 }, + { IROp::Mov, { MIPS_REG_S0 }, MIPS_REG_A1 }, }, { &PurgeTemps }, }, { "SimplePropagateConstants", { - { IROp::SetConst, MIPS_REG_A0, 0, 0, 0x12340000 }, - { IROp::OrConst, MIPS_REG_A0, MIPS_REG_A0, 0, 0x00005678 }, - { IROp::AddConst, MIPS_REG_A1, MIPS_REG_A0, 0, 0 }, - { IROp::AddConst, MIPS_REG_A2, MIPS_REG_A0, 0, 0x00001111 }, + { IROp::SetConst, { MIPS_REG_A0 }, 0, 0, 0x12340000 }, + { IROp::OrConst, { MIPS_REG_A0 }, MIPS_REG_A0, 0, 0x00005678 }, + { IROp::AddConst, { MIPS_REG_A1 }, MIPS_REG_A0, 0, 0 }, + { IROp::AddConst, { MIPS_REG_A2 }, MIPS_REG_A0, 0, 0x00001111 }, }, { - { IROp::SetConst, MIPS_REG_A0, 0, 0, 0x12345678 }, - { IROp::SetConst, MIPS_REG_A1, 0, 0, 0x12345678 }, - { IROp::SetConst, MIPS_REG_A2, 0, 0, 0x12346789 }, + { IROp::SetConst, { MIPS_REG_A0 }, 0, 0, 0x12345678 }, + { IROp::SetConst, { MIPS_REG_A1 }, 0, 0, 0x12345678 }, + { IROp::SetConst, { MIPS_REG_A2 }, 0, 0, 0x12346789 }, }, { &PropagateConstants }, }, @@ -138,18 +138,18 @@ static const IRVerification tests[] = { // Needed for PurgeTemps optimizations to work. "OrToMov", { - { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Or, MIPS_REG_S0, MIPS_REG_A0, MIPS_REG_ZERO }, - { IROp::Add, MIPS_REG_S1, MIPS_REG_A0, MIPS_REG_ZERO }, - { IROp::OrConst, MIPS_REG_S2, MIPS_REG_A0, 0, 0 }, - { IROp::AddConst, MIPS_REG_S3, MIPS_REG_A0, 0, 0 }, + { IROp::Sub, { MIPS_REG_A0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Or, { MIPS_REG_S0 }, MIPS_REG_A0, MIPS_REG_ZERO }, + { IROp::Add, { MIPS_REG_S1 }, MIPS_REG_A0, MIPS_REG_ZERO }, + { IROp::OrConst, { MIPS_REG_S2 }, MIPS_REG_A0, 0, 0 }, + { IROp::AddConst, { MIPS_REG_S3 }, MIPS_REG_A0, 0, 0 }, }, { - { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, - { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, - { IROp::Mov, MIPS_REG_S1, MIPS_REG_A0 }, - { IROp::Mov, MIPS_REG_S2, MIPS_REG_A0 }, - { IROp::Mov, MIPS_REG_S3, MIPS_REG_A0 }, + { IROp::Sub, { MIPS_REG_A0 }, MIPS_REG_A1, MIPS_REG_A2 }, + { IROp::Mov, { MIPS_REG_S0 }, MIPS_REG_A0 }, + { IROp::Mov, { MIPS_REG_S1 }, MIPS_REG_A0 }, + { IROp::Mov, { MIPS_REG_S2 }, MIPS_REG_A0 }, + { IROp::Mov, { MIPS_REG_S3 }, MIPS_REG_A0 }, }, { &PropagateConstants }, }, From c9a37ec6b95cbc7dfa8d5515f60139408de46701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Jul 2022 21:04:54 +0200 Subject: [PATCH 50/57] Remove bool that was always true in state mapping. --- GPU/Common/GPUStateUtils.cpp | 1 - GPU/Common/GPUStateUtils.h | 1 - GPU/D3D11/StateMappingD3D11.cpp | 15 ++++----------- GPU/Directx9/StateMappingDX9.cpp | 8 ++------ GPU/Vulkan/StateMappingVulkan.cpp | 15 ++++----------- 5 files changed, 10 insertions(+), 30 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 1f0841d84f..db237940fb 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -592,7 +592,6 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; - out.scissorEnable = true; if (scissorX2 < scissorX1 || scissorY2 < scissorY1) { out.scissorX = 0; out.scissorY = 0; diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index 5f2f455e60..14edc21638 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -65,7 +65,6 @@ LogicOpReplaceType ReplaceLogicOpType(); // Common representation, should be able to set this directly with any modern API. struct ViewportAndScissor { - bool scissorEnable; int scissorX; int scissorY; int scissorW; diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index bf2370e89e..79f8db4ce6 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -393,17 +393,10 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { } D3D11_RECT &scissor = dynState_.scissor; - if (vpAndScissor.scissorEnable) { - scissor.left = vpAndScissor.scissorX; - scissor.top = vpAndScissor.scissorY; - scissor.right = vpAndScissor.scissorX + std::max(0, vpAndScissor.scissorW); - scissor.bottom = vpAndScissor.scissorY + std::max(0, vpAndScissor.scissorH); - } else { - scissor.left = 0; - scissor.top = 0; - scissor.right = framebufferManager_->GetRenderWidth(); - scissor.bottom = framebufferManager_->GetRenderHeight(); - } + scissor.left = vpAndScissor.scissorX; + scissor.top = vpAndScissor.scissorY; + scissor.right = vpAndScissor.scissorX + std::max(0, vpAndScissor.scissorW); + scissor.bottom = vpAndScissor.scissorY + std::max(0, vpAndScissor.scissorH); } if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index efbb0e0b46..bdc9456ad6 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -239,12 +239,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) { framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), vpAndScissor); - if (vpAndScissor.scissorEnable) { - dxstate.scissorTest.enable(); - dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH); - } else { - dxstate.scissorTest.disable(); - } + dxstate.scissorTest.enable(); + dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH); float depthMin = vpAndScissor.depthRangeMin; float depthMax = vpAndScissor.depthRangeMax; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index f7ad74affa..166f3dc153 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -347,17 +347,10 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag } ScissorRect &scissor = dynState.scissor; - if (vpAndScissor.scissorEnable) { - scissor.x = vpAndScissor.scissorX; - scissor.y = vpAndScissor.scissorY; - scissor.width = std::max(0, vpAndScissor.scissorW); - scissor.height = std::max(0, vpAndScissor.scissorH); - } else { - scissor.x = 0; - scissor.y = 0; - scissor.width = framebufferManager_->GetRenderWidth(); - scissor.height = framebufferManager_->GetRenderHeight(); - } + scissor.x = vpAndScissor.scissorX; + scissor.y = vpAndScissor.scissorY; + scissor.width = std::max(0, vpAndScissor.scissorW); + scissor.height = std::max(0, vpAndScissor.scissorH); } } From c71951ca4d06a1b9130628b1e1b8c33142d687c1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Jul 2022 17:45:01 -0700 Subject: [PATCH 51/57] Build: Update to NDK r21e. This fixes a NEON intrinsic segfault and is LTS. --- .github/workflows/build.yml | 2 +- .github/workflows/manual_generate_apk.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b8066088d..857909af3c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -220,7 +220,7 @@ jobs: if: matrix.extra == 'android' id: setup-ndk with: - ndk-version: r21d + ndk-version: r21e - name: Install Linux dependencies if: runner.os == 'Linux' && matrix.extra != 'android' diff --git a/.github/workflows/manual_generate_apk.yml b/.github/workflows/manual_generate_apk.yml index a2306f9cf0..3f38055ac5 100644 --- a/.github/workflows/manual_generate_apk.yml +++ b/.github/workflows/manual_generate_apk.yml @@ -35,7 +35,7 @@ jobs: #- name: Setup NDK # uses: nttld/setup-ndk@v1 # with: - # ndk-version: r21d + # ndk-version: r21e - name: Assemble APK run: bash ./gradlew assemble${{ github.event.inputs.buildVariant }} --stacktrace From 6f4ec0fc43bb889690a162a6a54dad28d56c1d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Jul 2022 14:11:37 +0200 Subject: [PATCH 52/57] Simple hack to hide the search button in settings on small screens. Needs a better solution. --- UI/DevScreens.cpp | 4 ++++ UI/GameSettingsScreen.cpp | 27 +++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 11bbb70c00..1c938596ac 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -574,6 +574,10 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem(si->T("Native Resolution"), StringFromFormat("%dx%d", System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)))); + deviceSpecs->Add(new InfoItem(si->T("UI Resolution"), StringFromFormat("%dx%d (dpi: %0.2f)", + dp_xres, + dp_yres, + g_dpi))); #endif #if !PPSSPP_PLATFORM(WINDOWS) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 39ab8718a5..672c6bd36e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1081,20 +1081,23 @@ void GameSettingsScreen::CreateViews() { systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, sy->T("Confirmation Button"), buttonPref, 0, 2, sy->GetName(), screenManager())); #if !defined(MOBILE_DEVICE) || PPSSPP_PLATFORM(ANDROID) - // Search - LinearLayout *searchSettings = AddTab("GameSettingsSearch", ms->T("Search"), true); + // Hide search if screen is too small. + if (dp_xres < dp_yres || dp_yres >= 500) { + // Search + LinearLayout *searchSettings = AddTab("GameSettingsSearch", ms->T("Search"), true); - searchSettings->Add(new ItemHeader(se->T("Find settings"))); - if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { - searchSettings->Add(new ChoiceWithValueDisplay(&searchFilter_, se->T("Filter"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); - } else { - searchSettings->Add(new PopupTextInputChoice(&searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); + searchSettings->Add(new ItemHeader(se->T("Find settings"))); + if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { + searchSettings->Add(new ChoiceWithValueDisplay(&searchFilter_, se->T("Filter"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); + } else { + searchSettings->Add(new PopupTextInputChoice(&searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); + } + clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter"))); + clearSearchChoice_->OnClick.Handle(this, &GameSettingsScreen::OnClearSearchFilter); + noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5)))); + + ApplySearchFilter(); } - clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter"))); - clearSearchChoice_->OnClick.Handle(this, &GameSettingsScreen::OnClearSearchFilter); - noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5)))); - - ApplySearchFilter(); #endif } From 70255eed41a3d6b9298ff150f08f6558b780bc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Jul 2022 14:51:54 +0200 Subject: [PATCH 53/57] README.md update for the 1.13 release README: Small tweaks to v1.13.x notes. Additional points README: Correct some typos/consistency, add links. Couple additional updates More updates Cleanup More linking --- README.md | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d15b38cf6e..74c0795b51 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,49 @@ If you want to download regularly updated builds for Android, Windows x86 and x6 For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). +What's new in 1.13 +================== + +General + +* Fix assorted Android "scoped storage"-related bugs and performance issues ([#15237], [#15487]), etc. +* Analog mapping for fast-forward ([#15645]) +* Major softgpu accuracy fixes and speedups, including a JIT ([#15163], [#15345], [#15389], [#15529], [#15440], [#15410], [#15405], [#15400]) and many, many more +* Fixed some NEON code paths ([#15481]) +* Fix performance of texture uploads with Vulkan ([#15474]) +* Don't include the large font atlas when we don't need it +* Improved upscaling shaders ([#15566]) +* Vulkan texture upscaling performance improvements ([#15238]), etc. +* Vulkan correctness fixes ([#15217], [#15211]), use the VMA allocator ([#15162]), etc. +* Fixes to depth culling ([#15106]), many more +* Background loading of texture replacement ([#15025]) +* Threading manager improvements and fixes ([#15470]), etc. +* Added search in settings ([#14414]) +* Added fast button repeats on custom touch buttons ([#15613]) +* Two new bicubic upscaling shader: Catmull-Rom and Mitchell-Netravali ([#15569]) +* Allow to change screen rotation per game and to bind a key to change it ([#15494], [#15510]) +* Re-enabled software rendering option on Android ([#12958]) + +Game fixes + +* Add more workarounds for Mali driver bugs ([#15016]) +* Vortex in God of War: Ghost of Sparta can now be passed ([#15640]) +* Various proAdhoc fixes ([#15213], [#15215]), and many more +* Correct flickering text in Sol Trigger and Last Ranker. ([#15549]) +* Fix and improve line drawing in Echochrome ([#15583]), after line refactoring ([#15073], [#15075]) +* Fix HUD graphics in Split/Second ([#15500], [#15501]) +* Fix bad screen overlay issues in Clone Wars and Force Unleashed ([#15691], [#15696], [#12949], [#9572]) +* Zettai Zetsumei Toshi 3 no longer hangs on character select screen ([#15687]) +* Juiced 2: Bloom effect no longer covering the screen ([#7295], [#15717]) +* Fix keyboard shift issue in a few games ([#15698]) + +UI + +* Windows/Xbox UWP directory navigation improvements ([#15652]) +* Color change and basic theme support ([#15396], [#15394]) +* Fix input focus bug ([#15560]) +* New GE debugger features and other UI fixes ([#15393], [#15324], [#15377], [#15424], [#15402], [#15378], [#15338]), etc. + What's new in 1.12.3 ==================== * Fix background music speed. A couple translation fixes. @@ -61,9 +104,9 @@ Game fixes: Graphics and Sound: * Add new texture filtering mode "Auto Max Quality" ([#14789]) * Fix Princess Maker 5 Portable half screen in Vulkan ([#13741]) -* Fix Pro Yakyu Spirits 2010 (NPJH50234): Rendering errors with hardware transform off ([#14167]) +* Fix Pro Yakyu Spirits 2010 (NPJH50234): Rendering errors with hardware transform off ([#14167]) * Support texture replacement filtering overrides ([#14230]) -* Fix Yarudora Portable: Double Cast's FMVs artifacting ([#13759]) +* Fix Yarudora Portable: Double Cast's FMVs artifacting ([#13759]) * Fix Sims 2 Castaway/Pets EA Logo glitched out ([#13146]) * Fix bad size & position on Japanese & Numbers & Alphabets ([#14209]) * Implement basic depth texturing for OpenGL ([#14042]) @@ -80,9 +123,9 @@ UI: * Track and show memory allocation / usage information in debugger ([#14056]) * Allow searching within the savedata manager ([#14237]) * Enable postshaders to access previous frame ([#14528]) -* Add missing japanese keyboard symbol ([#14548]) +* Add missing Japanese keyboard symbol ([#14548]) * Add Reset button on crash screen, allow load state and related ([#14708]) -* Implement savestate load and save undo ([#14676], [#14679], [#14697]) +* Implement save state load and save undo ([#14676], [#14679], [#14697]) * A lot of minor debugger improvements Controls: @@ -207,7 +250,7 @@ What's new in 1.10.0 * Frames in-flight now configurable to reduce input lag at the cost of speed ([#12660]) * Add toggle mode to combo button ([#12623]) * SDL mouse support, Qt menu upgrades ([#12612], [#12817]) -* Real support for chinese patched version of Hatsune Miku Project Diva Extend ([#13007]) +* Real support for Chinese patched version of Hatsune Miku Project Diva Extend ([#13007]) * Some minor kernel module support ([#13028], [#12225], [#13026], [#13004], [#13038], [#13023]) * Fixed fullscreen toggling with Vulkan in SDL builds ([#11974]) @@ -404,3 +447,59 @@ Credit goes to: [#14513]: https://github.com/hrydgard/ppsspp/issues/14513 "[Adhoc] Reducing HLE delays due to Mutiplayer performance regressions" [#14849]: https://github.com/hrydgard/ppsspp/issues/14849 "[Adhoc] Fix Socket error 10014 on Windows when hosting a game of Vulcanus Seek and Destroy" [#14711]: https://github.com/hrydgard/ppsspp/issues/14711 "Sas: Add option to control reverb volume" +[#15237]: https://github.com/hrydgard/ppsspp/issues/15237 "Path: Check for PSP case insensitively" +[#15487]: https://github.com/hrydgard/ppsspp/issues/15487 "Save textures on background tasks when texture dumping is enabled." +[#15645]: https://github.com/hrydgard/ppsspp/issues/15645 "UI: Add analog speed limit mapping" +[#15566]: https://github.com/hrydgard/ppsspp/issues/15566 "Screen upscaling shaders improvements" +[#15163]: https://github.com/hrydgard/ppsspp/issues/15163 "Implement a jit for drawing pixels in the software renderer" +[#15345]: https://github.com/hrydgard/ppsspp/issues/15345 "Fix some minor softgpu blending bugs" +[#15389]: https://github.com/hrydgard/ppsspp/issues/15389 "Draw rectangles always using a specialized path in softgpu" +[#15529]: https://github.com/hrydgard/ppsspp/issues/15529 "softgpu: Fix viewport flag clean/dirty" +[#15440]: https://github.com/hrydgard/ppsspp/issues/15440 "softgpu: Plug bad leak of bin queue data" +[#15410]: https://github.com/hrydgard/ppsspp/issues/15410 "softgpu: Remove offset from screenpos, adjust filtering coords" +[#15405]: https://github.com/hrydgard/ppsspp/issues/15405 "Fix some samplerjit issues without SSE4 or AVX" +[#15400]: https://github.com/hrydgard/ppsspp/issues/15400 "softgpu: Track dirty vs really dirty per buffer" +[#15481]: https://github.com/hrydgard/ppsspp/issues/15481 "Fix some NEON code that had bad compile-time checks" +[#15474]: https://github.com/hrydgard/ppsspp/issues/15474 "Merge CheckAlpha into texture decoding" +[#15238]: https://github.com/hrydgard/ppsspp/issues/15238 "Vulkan: Be more restrictive about hardware texture upscaling on \"slow\" GPUs" +[#15217]: https://github.com/hrydgard/ppsspp/issues/15217 "Vulkan is strict about scissor rect, so let's clamp centrally." +[#15211]: https://github.com/hrydgard/ppsspp/issues/15211 "Vulkan: Specify Vulkan version, fix mip level generation calculation" +[#15162]: https://github.com/hrydgard/ppsspp/issues/15162 "Integrate VMA (Vulkan Memory Allocator)" +[#15106]: https://github.com/hrydgard/ppsspp/issues/15106 "GLES: Explicitly enable ARB_cull_distance" +[#15075]: https://github.com/hrydgard/ppsspp/issues/15075 "Draw points using triangles" +[#15470]: https://github.com/hrydgard/ppsspp/issues/15470 "Threading manager stresstest and fixes" +[#14414]: https://github.com/hrydgard/ppsspp/issues/14414 "Add search for settings" +[#15613]: https://github.com/hrydgard/ppsspp/issues/15613 "Allow to repeat a \"single\" button" +[#15569]: https://github.com/hrydgard/ppsspp/issues/15569 "Upscaling shaders" +[#15494]: https://github.com/hrydgard/ppsspp/issues/15494 "Add key bind to hotswap internal screen rotation" +[#15510]: https://github.com/hrydgard/ppsspp/issues/15510 "Allow to set InternalScreenRotation per game" +[#12958]: https://github.com/hrydgard/ppsspp/issues/12958 "Feature Request: restore software rendering ui setting on android" +[#15016]: https://github.com/hrydgard/ppsspp/issues/15016 "[Android][Mali GPU] Vulkan backend workaround issue in some games with graphics glitch." +[#15640]: https://github.com/hrydgard/ppsspp/issues/15640 "Disable ForceMax60FPS for GOW games and replace it with fixed 60 fps" +[#15213]: https://github.com/hrydgard/ppsspp/issues/15213 "[Adhoc] Updated PdpCreate, PdpSend, PdpRecv, GetPdpStat, GetPtpStat" +[#15215]: https://github.com/hrydgard/ppsspp/issues/15215 "[Adhocctl] Fix Tekken 5 Dark Resurrection Multiplayer" +[#15549]: https://github.com/hrydgard/ppsspp/issues/15549 "GPU: Hook Sol Trigger func to flush texture" +[#15583]: https://github.com/hrydgard/ppsspp/issues/15583 "Fix and further improve line drawing in Echochrome" +[#15073]: https://github.com/hrydgard/ppsspp/issues/15073 "Cleanup line/point handling and refactor a bit" +[#15500]: https://github.com/hrydgard/ppsspp/issues/15500 "Add BlueToAlpha compat.ini workaround, fixes Split/Second graphics" +[#15501]: https://github.com/hrydgard/ppsspp/issues/15501 "Make the existing ReinterpretFramebuffers/ShaderColorBitmask path work for Split/Second" +[#15652]: https://github.com/hrydgard/ppsspp/issues/15652 "Replace Win32 file IO with UWP safe variants and add support for getting drives to UWP build" +[#15396]: https://github.com/hrydgard/ppsspp/issues/15396 "Add UI Tint/Saturation settings" +[#15394]: https://github.com/hrydgard/ppsspp/issues/15394 "Allow custom UI themes" +[#15560]: https://github.com/hrydgard/ppsspp/issues/15560 "UI: Abandon focus movement on returning from pause" +[#15393]: https://github.com/hrydgard/ppsspp/issues/15393 "GE Debugger: Avoid crash on Step Draw with flush" +[#15324]: https://github.com/hrydgard/ppsspp/issues/15324 "UI: Reset ZIP install errors for new ZIPs" +[#15377]: https://github.com/hrydgard/ppsspp/issues/15377 "Debugger: Avoid mem write tag lookup on small alloc" +[#15424]: https://github.com/hrydgard/ppsspp/issues/15424 "Windows: Create SYSTEM directory early" +[#15402]: https://github.com/hrydgard/ppsspp/issues/15402 "GE Debugger: Highlight changed state values" +[#15378]: https://github.com/hrydgard/ppsspp/issues/15378 "GE Debugger: Add filter to skip prim calls" +[#15338]: https://github.com/hrydgard/ppsspp/issues/15338 "Alow flushing at will via the GE debugger" +[#15025]: https://github.com/hrydgard/ppsspp/issues/15025 "Allow delayed loading of texture replacements" +[#15691]: https://github.com/hrydgard/ppsspp/issues/15691 "Add a simple compat flag to workaround the Clone Wars issue, #12949" +[#15696]: https://github.com/hrydgard/ppsspp/issues/15696 "Use the recent Clone Wars fix for Star Wars: Force Unleashed too" +[#12949]: https://github.com/hrydgard/ppsspp/issues/12949 "Star Wars: The Clone Wars - Graphic glitch [Android/Windows]" +[#9572]: https://github.com/hrydgard/ppsspp/issues/9572 "Star Wars force unleashed [Screen Overlay problem]" +[#15687]: https://github.com/hrydgard/ppsspp/issues/15687 "Add Zettai Zetsumei Toshi 3" +[#7295]: https://github.com/hrydgard/ppsspp/issues/7295 "Juiced 2: Hot Import Nights, screen artifacts and missing half of race tracks" +[#15717]: https://github.com/hrydgard/ppsspp/issues/15717 "Allows \"merging\" render targets that overlap on the Y axis. Fixes Juiced 2" +[#15698]: https://github.com/hrydgard/ppsspp/issues/15698 "Osk: Allow upper/lower for all keyboards" \ No newline at end of file From a92e764c65b3248d1ddd7107ffa4c598a2ef4ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Jul 2022 15:18:52 +0200 Subject: [PATCH 54/57] Update version for 1.13 release --- android/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 2ae4d17046..4e67aaae58 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="org.ppsspp.ppsspp" android:installLocation="auto" - android:versionCode="112030000" - android:versionName="1.12.3.0"> + android:versionCode="113000000" + android:versionName="1.13.0.0"> From 19ebbb6a30707da9b0e4d17f3eb03b6aa160b3db Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 26 Jul 2022 17:32:03 +0200 Subject: [PATCH 55/57] OpenXR - Integrate SYSPROP_HAS_FILE_BROWSER --- UI/MainScreen.cpp | 2 -- android/jni/app-android.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 0a1b2454eb..cb5fbf0116 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1131,11 +1131,9 @@ void MainScreen::CreateViews() { ver->SetSmall(true); ver->SetClip(false); -#ifndef OPENXR if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { rightColumnItems->Add(new Choice(mm->T("Load", "Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); } -#endif rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings); rightColumnItems->Add(new Choice(mm->T("Credits")))->OnClick.Handle(this, &MainScreen::OnCredits); rightColumnItems->Add(new Choice(mm->T("www.ppsspp.org")))->OnClick.Handle(this, &MainScreen::OnPPSSPPOrg); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index aaa9e1298e..eb83ef7b09 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -503,7 +503,7 @@ bool System_GetPropertyBool(SystemProperty prop) { case SYSPROP_HAS_FILE_BROWSER: // It's only really needed with scoped storage, but why not make it available // as far back as possible - works just fine. - return androidVersion >= 19; // when ACTION_OPEN_DOCUMENT was added + return (androidVersion >= 19) && (deviceType != DEVICE_TYPE_VR); // when ACTION_OPEN_DOCUMENT was added case SYSPROP_HAS_FOLDER_BROWSER: // Uses OPEN_DOCUMENT_TREE to let you select a folder. // Doesn't actually mean it's usable though, in many early versions of Android From b2509ad4ddfc0e93176c626eeb4ddd3ed6eb5d36 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 26 Jul 2022 17:40:10 +0200 Subject: [PATCH 56/57] OpenXR - Version info refactor --- VR/VRBase.cpp | 8 ++++---- VR/VRFramebuffer.h | 2 ++ android/jni/app-android.cpp | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/VR/VRBase.cpp b/VR/VRBase.cpp index f8712db834..56745116e7 100644 --- a/VR/VRBase.cpp +++ b/VR/VRBase.cpp @@ -36,10 +36,10 @@ void VR_Init( ovrJava java ) { // Create the OpenXR instance. XrApplicationInfo appInfo; memset(&appInfo, 0, sizeof(appInfo)); - strcpy(appInfo.applicationName, "PPSSPP"); - appInfo.applicationVersion = 0; - strcpy(appInfo.engineName, "PPSSPP"); - appInfo.engineVersion = 0; + strcpy(appInfo.applicationName, java.AppName); + strcpy(appInfo.engineName, java.AppName); + appInfo.applicationVersion = java.AppVersion; + appInfo.engineVersion = java.AppVersion; appInfo.apiVersion = XR_CURRENT_API_VERSION; XrInstanceCreateInfo instanceCreateInfo; diff --git a/VR/VRFramebuffer.h b/VR/VRFramebuffer.h index b347e68e65..066d500375 100644 --- a/VR/VRFramebuffer.h +++ b/VR/VRFramebuffer.h @@ -30,6 +30,8 @@ typedef struct { JavaVM* Vm; jobject ActivityObject; JNIEnv* Env; + char AppName[64]; + int AppVersion; } ovrJava; typedef struct { diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index eb83ef7b09..305d68f982 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -811,9 +811,12 @@ retry: } #ifdef OPENXR + Version gitVer(PPSSPP_GIT_VERSION); ovrJava java; java.Vm = gJvm; java.ActivityObject = nativeActivity; + java.AppVersion = gitVer.ToInteger(); + strcpy(java.AppName, "PPSSPP"); VR_Init(java); #endif } From ab9a48d7501a4a7305943a4fcadb2194a640550b Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 26 Jul 2022 17:44:38 +0200 Subject: [PATCH 57/57] OpenXR - Static added to global variables --- android/jni/app-android.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 305d68f982..53013337b7 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -112,7 +112,7 @@ struct ButtonMapping { } }; -std::vector leftControllerMapping = { +static std::vector leftControllerMapping = { ButtonMapping(NKCODE_BUTTON_X, ovrButton_X), ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y), ButtonMapping(NKCODE_ALT_LEFT, ovrButton_GripTrigger), @@ -125,7 +125,7 @@ std::vector leftControllerMapping = { ButtonMapping(NKCODE_BACK, ovrButton_Enter), }; -std::vector rightControllerMapping = { +static std::vector rightControllerMapping = { ButtonMapping(NKCODE_BUTTON_A, ovrButton_A), ButtonMapping(NKCODE_BUTTON_B, ovrButton_B), ButtonMapping(NKCODE_ALT_RIGHT, ovrButton_GripTrigger), @@ -137,8 +137,8 @@ std::vector rightControllerMapping = { ButtonMapping(NKCODE_ENTER, ovrButton_Trigger), }; -int controllerIds[] = {DEVICE_ID_XR_CONTROLLER_LEFT, DEVICE_ID_XR_CONTROLLER_RIGHT}; -std::vector controllerMapping[2] = { +static const int controllerIds[] = {DEVICE_ID_XR_CONTROLLER_LEFT, DEVICE_ID_XR_CONTROLLER_RIGHT}; +static std::vector controllerMapping[2] = { leftControllerMapping, rightControllerMapping };