mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #21229 from hrydgard/more-ui-polish
More UI fixes, easy way to copy function hash
This commit is contained in:
16 files changed
+79
-30
No files matched your search
@@ -1848,6 +1848,8 @@ std::map<u32, u32> SaveAndClearReplacements() {
|
||||
Memory::Write_U32(instr, addr);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Should we not also call replacedInstructions.clear(); ?
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,19 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
|
||||
// Regular replacement funcs are just C functions. These take care of their
|
||||
// own parameter parsing using the old school PARAM macros.
|
||||
// The return value is the number of cycles to eat.
|
||||
|
||||
// Replacement functions are replaced by function hash, also checking the size to reduce
|
||||
// collisions. This is not really super safe, and we probably should restrict them by
|
||||
// game ID, really...
|
||||
|
||||
// JIT replacefuncs can be for inline or "outline" replacement.
|
||||
// With inline replacement, we recognize the call to the functions
|
||||
// at jal time already. With outline replacement, we just replace the
|
||||
// implementation.
|
||||
// implementation, which gets jumped to from other functions.
|
||||
|
||||
// In both cases the jit needs to know how much to subtract downcount.
|
||||
//
|
||||
|
||||
@@ -771,7 +771,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
|
||||
case IROp::Mult:
|
||||
{
|
||||
s64 result = (s64)(s32)mips->r[inst->src1] * (s64)(s32)mips->r[inst->src2];
|
||||
memcpy(&mips->lo, &result, 8);
|
||||
memcpy(&mips->lo, &result, 8); // note: lo is followed by hi, so this is ok (little-endian).
|
||||
break;
|
||||
}
|
||||
case IROp::MultU:
|
||||
|
||||
@@ -1261,6 +1261,17 @@ skip:
|
||||
}
|
||||
}
|
||||
|
||||
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out) {
|
||||
std::lock_guard<std::recursive_mutex> guard(functions_lock);
|
||||
for (auto iter = functions.begin(), end = functions.end(); iter != end; ++iter) {
|
||||
if (iter->start <= addr && iter->end >= addr) {
|
||||
*out = *iter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ReplaceFunctions() {
|
||||
std::lock_guard<std::recursive_mutex> guard(functions_lock);
|
||||
|
||||
@@ -1299,13 +1310,6 @@ skip:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetHashMapFilename(const std::string& filename) {
|
||||
if (filename.empty())
|
||||
hashmapFileName = GetSysDirectory(DIRECTORY_SYSTEM) / "knownfuncs.ini";
|
||||
else
|
||||
hashmapFileName = Path(filename);
|
||||
}
|
||||
|
||||
void StoreHashMap(Path filename) {
|
||||
if (filename.empty())
|
||||
filename = hashmapFileName;
|
||||
|
||||
@@ -108,7 +108,8 @@ namespace MIPSAnalyst {
|
||||
void FinalizeScan(bool insertSymbols);
|
||||
void ForgetFunctions(u32 startAddr, u32 endAddr);
|
||||
|
||||
void SetHashMapFilename(const std::string& filename = "");
|
||||
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out);
|
||||
|
||||
void LoadBuiltinHashMap();
|
||||
void LoadHashMap(const Path &filename);
|
||||
void StoreHashMap(Path filename = Path());
|
||||
|
||||
+6
-2
@@ -1596,11 +1596,12 @@ ScreenRenderFlags EmuScreen::PreRender(ScreenRenderMode mode) {
|
||||
|
||||
using namespace Draw;
|
||||
skipBufferEffects_ = g_Config.bSkipBufferEffects;
|
||||
if (!skipBufferEffects_) {
|
||||
if (!skipBufferEffects_ && PSP_IsInited()) {
|
||||
if (ShouldRunEmulation(mode)) {
|
||||
// We need to run emulation here, and perform all the normal render passes.
|
||||
return RunEmulation(false);
|
||||
} else {
|
||||
} else if (gpu) {
|
||||
// Need to check for gpu here, we might be in reset.
|
||||
const DeviceOrientation orientation = GetDeviceOrientation();
|
||||
const DisplayLayoutConfig &displayLayoutConfig = g_Config.GetDisplayLayoutConfig(orientation);
|
||||
// We run just the post shaders.
|
||||
@@ -1666,6 +1667,9 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
gpu->CopyDisplayToOutput(displayLayoutConfig);
|
||||
}
|
||||
|
||||
// Reset the viewport. Needed in case Cardboard or something similar was enabled.
|
||||
draw->SetViewport(viewport);
|
||||
|
||||
runImDebugger();
|
||||
|
||||
Draw::BackendState state = draw->GetCurrentBackendState();
|
||||
|
||||
+7
-7
@@ -206,14 +206,14 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
std::vector<GameDBInfo> dbInfos;
|
||||
const bool inGameDB = g_gameDB.GetGameInfos(info_->id_version, &dbInfos);
|
||||
|
||||
// Show the game ID title below the icon. The top title will be from the DB.
|
||||
std::string title = info_->GetTitle();
|
||||
|
||||
if (knownFlags_ & GameInfoFlags::PARAM_SFO) {
|
||||
std::string regionID = ReplaceAll(info_->id_version, "_", " v");
|
||||
if (!regionID.empty()) {
|
||||
regionID += ": ";
|
||||
|
||||
// Show the game ID title below the icon. The top title will be from the DB.
|
||||
std::string title = info_->GetTitle();
|
||||
|
||||
TextView *tvTitle = mainGameInfo->Add(new TextView(title, ALIGN_LEFT | FLAG_WRAP_TEXT, false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
tvTitle->SetShadow(true);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
Choice *btnResetTime = timeHoriz->Add(new Choice(di->T("Reset"), new LinearLayoutParams(0.0f, Gravity::G_VCENTER)));
|
||||
btnResetTime->OnClick.Add([this, ga, timeStr](UI::EventParams &) {
|
||||
btnResetTime->OnClick.Add([this, ga, timeStr, title](UI::EventParams &) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto gta = GetI18NCategory(I18NCat::GAME);
|
||||
std::string id = info_->id;
|
||||
@@ -286,12 +286,12 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
questionText += "\n";
|
||||
questionText += timeStr;
|
||||
screenManager()->push(
|
||||
new PromptScreen(gamePath_, questionText, di->T("Reset"), di->T("Cancel"), [id](bool yes) {
|
||||
if (yes) {
|
||||
new UI::MessagePopupScreen(title, questionText, di->T("Reset"), di->T("Cancel"), [this, id](bool reset) {
|
||||
if (reset) {
|
||||
g_Config.TimeTracker().Reset(id);
|
||||
RecreateViews();
|
||||
}
|
||||
}));
|
||||
RecreateViews();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Core/Debugger/Breakpoints.h"
|
||||
#include "Core/MIPS/MIPSDebugInterface.h"
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
#include "Core/MIPS/MIPSAnalyst.h"
|
||||
#include "Core/Debugger/SymbolMap.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Common/System/Request.h"
|
||||
@@ -751,6 +752,16 @@ void ImDisasmView::PopupMenu(ImControl &control) {
|
||||
if (ImGui::MenuItem("Copy instruction (hex)")) {
|
||||
CopyInstructions(selectRangeStart_, selectRangeEnd_, CopyInstructionsMode::OPCODES);
|
||||
}
|
||||
if (ImGui::MenuItem("Copy function hash")) {
|
||||
MIPSAnalyst::AnalyzedFunction func;
|
||||
if (MIPSAnalyst::GetAnalyzedFunctionAt(curAddress_, &func)) {
|
||||
if (func.hasHash) {
|
||||
char temp[256];
|
||||
snprintf(temp, sizeof(temp), "%016llx:%d = %s\n", func.hash, func.size, func.name);
|
||||
System_CopyStringToClipboard(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Set PC to here")) {
|
||||
|
||||
+1
-1
@@ -428,7 +428,7 @@ void ReportFinishScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
|
||||
parent->Add(new Spacer(20.0f));
|
||||
|
||||
parent->Add(new Choice(rp->T("View Feedback"), ImageID("I_LINK_OUT")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback);
|
||||
parent->Add(new Choice(rp->T("View Feedback"), ImageID("I_LINK_OUT"), new LayoutParams(WRAP_CONTENT, ITEM_HEIGHT)))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback);
|
||||
}
|
||||
|
||||
void ReportFinishScreen::update() {
|
||||
|
||||
@@ -891,10 +891,26 @@ void CtrlDisAsmView::CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructio
|
||||
delete [] temp;
|
||||
} else {
|
||||
std::string disassembly = DisassembleRange(startAddr,endAddr-startAddr, displaySymbols, debugger);
|
||||
W32Util::CopyTextToClipboard(wnd, disassembly.c_str());
|
||||
W32Util::CopyTextToClipboard(wnd, disassembly);
|
||||
}
|
||||
}
|
||||
|
||||
void CtrlDisAsmView::CopyFunctionHash(u32 addr) {
|
||||
MIPSAnalyst::AnalyzedFunction func;
|
||||
if (MIPSAnalyst::GetAnalyzedFunctionAt(addr, &func)) {
|
||||
if (func.hasHash) {
|
||||
char temp[256];
|
||||
snprintf(temp, sizeof(temp), "%016llx:%d = %s\n", func.hash, func.size, func.name);
|
||||
W32Util::CopyTextToClipboard(wnd, temp);
|
||||
} else {
|
||||
MessageBox(wnd, L"No hash", L"", 0);
|
||||
}
|
||||
} else {
|
||||
MessageBox(wnd, L"No function", L"", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CtrlDisAsmView::NopInstructions(u32 selectRangeStart, u32 selectRangeEnd) {
|
||||
for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) {
|
||||
Memory::Write_U32(0, addr);
|
||||
@@ -945,6 +961,9 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
|
||||
case ID_DISASM_COPYINSTRUCTIONHEX:
|
||||
CopyInstructions(selectRangeStart, selectRangeEnd, CopyInstructionsMode::OPCODES);
|
||||
break;
|
||||
case ID_DISASM_COPYFUNCTIONHASH:
|
||||
CopyFunctionHash(curAddress);
|
||||
break;
|
||||
case ID_DISASM_NOPINSTRUCTION:
|
||||
NopInstructions(selectRangeStart, selectRangeEnd);
|
||||
redraw();
|
||||
|
||||
@@ -75,6 +75,7 @@ class CtrlDisAsmView {
|
||||
void updateStatusBarText();
|
||||
void drawBranchLine(HDC hdc, std::map<u32, int> &addressPositions, const BranchLine &line);
|
||||
void CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode);
|
||||
void CopyFunctionHash(u32 addr);
|
||||
void NopInstructions(u32 startAddr, u32 endAddr);
|
||||
std::set<std::string> getSelectedLineArguments();
|
||||
void drawArguments(HDC hdc, const DisassemblyLineInfo &line, int x, int y, int textColor, const std::set<std::string> ¤tArguments);
|
||||
|
||||
@@ -596,7 +596,7 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) {
|
||||
std::ostringstream stream;
|
||||
stream << (Memory::IsValidAddress(curAddress_) ? Memory::Read_Float(curAddress_) : NAN);
|
||||
auto temp_string = stream.str();
|
||||
W32Util::CopyTextToClipboard(wnd, temp_string.c_str());
|
||||
W32Util::CopyTextToClipboard(wnd, temp_string);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -814,7 +814,7 @@ void CtrlMemView::ScrollCursor(int bytes, GotoMode mode) {
|
||||
redraw();
|
||||
}
|
||||
|
||||
bool CtrlMemView::ParseSearchString(const std::string &query, bool asHex, std::vector<uint8_t> &data) {
|
||||
bool CtrlMemView::ParseSearchString(std::string_view query, bool asHex, std::vector<uint8_t> &data) {
|
||||
data.clear();
|
||||
if (!asHex) {
|
||||
for (size_t i = 0; i < query.length(); i++) {
|
||||
@@ -847,7 +847,7 @@ bool CtrlMemView::ParseSearchString(const std::string &query, bool asHex, std::v
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<u32> CtrlMemView::searchString(const std::string &searchQuery) {
|
||||
std::vector<u32> CtrlMemView::searchString(std::string_view searchQuery) {
|
||||
std::vector<u32> searchResAddrs;
|
||||
|
||||
auto memLock = Memory::Lock();
|
||||
@@ -993,8 +993,8 @@ void CtrlMemView::setHighlightType(MemBlockFlags flags) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CtrlMemView::pickTagColor(const std::string &tag) {
|
||||
uint32_t CtrlMemView::pickTagColor(std::string_view tag) {
|
||||
int colors[6] = { 0xe0FFFF, 0xFFE0E0, 0xE8E8FF, 0xFFE0FF, 0xE0FFE0, 0xFFFFE0 };
|
||||
int which = XXH3_64bits(tag.c_str(), tag.length()) % ARRAY_SIZE(colors);
|
||||
int which = XXH3_64bits(tag.data(), tag.length()) % ARRAY_SIZE(colors);
|
||||
return colors[which];
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
MIPSDebugInterface *getDebugger() {
|
||||
return debugger_;
|
||||
}
|
||||
std::vector<u32> searchString(const std::string &searchQuery);
|
||||
std::vector<u32> searchString(std::string_view query);
|
||||
void onPaint(WPARAM wParam, LPARAM lParam);
|
||||
void onVScroll(WPARAM wParam, LPARAM lParam);
|
||||
void onKeyDown(WPARAM wParam, LPARAM lParam);
|
||||
@@ -57,10 +57,10 @@ public:
|
||||
void setHighlightType(MemBlockFlags flags);
|
||||
|
||||
private:
|
||||
bool ParseSearchString(const std::string &query, bool asHex, std::vector<uint8_t> &data);
|
||||
bool ParseSearchString(std::string_view query, bool asHex, std::vector<uint8_t> &data);
|
||||
void updateStatusBarText();
|
||||
void search(bool continueSearch);
|
||||
uint32_t pickTagColor(const std::string &tag);
|
||||
uint32_t pickTagColor(std::string_view tag);
|
||||
|
||||
enum class GotoMode {
|
||||
RESET,
|
||||
|
||||
@@ -745,6 +745,7 @@ BEGIN
|
||||
MENUITEM "Copy Address", ID_DISASM_COPYADDRESS
|
||||
MENUITEM "Copy Instruction (Hex)", ID_DISASM_COPYINSTRUCTIONHEX
|
||||
MENUITEM "Copy Instruction (Disasm)", ID_DISASM_COPYINSTRUCTIONDISASM
|
||||
MENUITEM "Copy Function Hash", ID_DISASM_COPYFUNCTIONHASH
|
||||
MENUITEM "Disassemble to File", ID_DISASM_DISASSEMBLETOFILE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Assemble Opcode", ID_DISASM_ASSEMBLE
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
#define ID_MEMVIEW_COPYVALUE_8 40005
|
||||
#define ID_DISASM_COPYINSTRUCTIONDISASM 40006
|
||||
#define ID_DISASM_COPYINSTRUCTIONHEX 40007
|
||||
#define ID_DISASM_COPYFUNCTIONHASH 40031
|
||||
#define ID_EMULATION_SPEEDLIMIT 40008
|
||||
#define ID_TOGGLE_BREAK 40009
|
||||
#define ID_EMULATION_STOP 40010
|
||||
|
||||
+1
-1
Submodule ext/aemu_postoffice updated: b0625ecb65...eec2e71424.
Reference in new issue
Block a user