1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

Partial commit: Gui

This commit is contained in:
Nekotekina 2016-02-02 00:46:27 +03:00
parent 643c15c4e9
commit c7738b8b37
45 changed files with 1631 additions and 3628 deletions

View File

@ -26,10 +26,10 @@ AutoPauseManagerDialog::AutoPauseManagerDialog(wxWindow* parent)
wxBoxSizer* s_action = new wxBoxSizer(wxHORIZONTAL);
s_action->Add(new wxButton(this, wxID_CLEAR, wxT("Cl&ear"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_REFRESH, wxT("&Reload"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_SAVE, wxT("&Save"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_CANCEL, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_CLEAR, "Cl&ear", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_REFRESH, "&Reload", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_SAVE, "&Save", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_CANCEL, "&Close", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_main->Add(s_action, 0, wxALL, 5);
@ -65,7 +65,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
u32 num;
size_t fmax = list.size();
size_t fcur = 0;
CHECK_ASSERTION(list.seek(0) != -1);
list.seek(0);
while (fcur <= fmax - sizeof(u32))
{
list.read(&num, sizeof(u32));
@ -82,10 +82,10 @@ void AutoPauseManagerDialog::LoadEntries(void)
//This would always use a 0xFFFFFFFF as end of the pause.bin
void AutoPauseManagerDialog::SaveEntries(void)
{
fs::file list(fs::get_config_dir() + "pause.bin", fom::rewrite);
fs::file list(fs::get_config_dir() + "pause.bin", fs::rewrite);
//System calls ID and Function calls ID are all u32 iirc.
u32 num = 0;
CHECK_ASSERTION(list.seek(0) != -1);
list.seek(0);
for (size_t i = 0; i < m_entries.size(); ++i)
{
if (num == 0xFFFFFFFF) continue;
@ -210,12 +210,12 @@ AutoPauseSettingsDialog::AutoPauseSettingsDialog(wxWindow* parent, u32 *entry)
m_id = new wxTextCtrl(this, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
s_config->Add(m_id, 1, wxALL | wxEXPAND, 5);
s_config->Add(new wxButton(this, wxID_OK, wxT("&OK"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_config->Add(new wxButton(this, wxID_CANCEL, wxT("&Cancel"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_config->Add(new wxButton(this, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_config->Add(new wxButton(this, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_main->Add(s_config, 0, wxEXPAND, 5);
m_current_converted = new wxStaticText(this, wxID_ANY, wxT("Currently it gets an id of \"Unset\"."), wxDefaultPosition, wxDefaultSize, 0);
m_current_converted = new wxStaticText(this, wxID_ANY, "Currently it gets an id of \"Unset\".", wxDefaultPosition, wxDefaultSize, 0);
s_main->Add(m_current_converted, 0, wxALL, 5);
m_id->SetValue(fmt::format("%08x", m_entry));

View File

@ -22,8 +22,8 @@ CgDisasm::CgDisasm(wxWindow* parent)
wxPanel* p_cg_disasm = new wxPanel(nb_cg, wxID_ANY);
wxPanel* p_glsl_shader = new wxPanel(nb_cg, wxID_ANY);
nb_cg->AddPage(p_cg_disasm, wxT("ASM"));
nb_cg->AddPage(p_glsl_shader, wxT("GLSL"));
nb_cg->AddPage(p_cg_disasm, "ASM");
nb_cg->AddPage(p_glsl_shader, "GLSL");
m_disasm_text = new wxTextCtrl(p_cg_disasm, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(620, 395), wxTE_MULTILINE | wxNO_BORDER | wxTE_READONLY | wxTE_RICH2);
m_glsl_text = new wxTextCtrl(p_glsl_shader, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(620, 395), wxTE_MULTILINE | wxNO_BORDER | wxTE_READONLY | wxTE_RICH2);

View File

@ -1,426 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
//#include "Emu/Cell/PPUProgramCompiler.h"
//using namespace PPU_opcodes;
#include "CompilerELF.h"
enum CompilerIDs
{
id_analyze_code = 0x555,
id_compile_code,
id_load_elf,
};
wxFont GetFont(int size)
{
return wxFont(size, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
}
CompilerELF::CompilerELF(wxWindow* parent)
: FrameBase(parent, wxID_ANY, "CompilerELF", "", wxSize(640, 680))
, m_status_bar(*CreateStatusBar())
{
m_disable_scroll = false;
m_aui_mgr.SetManagedWindow(this);
wxMenuBar* menubar = new wxMenuBar();
wxMenu* menu_code = new wxMenu();
menubar->Append(menu_code, "Code");
//menu_code.Append(id_analyze_code, "Analyze");
menu_code->Append(id_compile_code, "Compile");
menu_code->Append(id_load_elf, "Load ELF");
SetMenuBar(menubar);
asm_list = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(400, -1), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_RICH2);
hex_list = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(155, -1), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_READONLY | wxTE_RICH2);
err_list = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, 200), wxTE_MULTILINE | wxTE_READONLY);
const wxSize& client_size = GetClientSize();
m_aui_mgr.AddPane(asm_list, wxAuiPaneInfo().Name(L"asm_list").CenterPane().PaneBorder(false).CloseButton(false));
m_aui_mgr.AddPane(hex_list, wxAuiPaneInfo().Name(L"hex_list").Left().PaneBorder(false).CloseButton(false));
m_aui_mgr.AddPane(err_list, wxAuiPaneInfo().Name(L"err_list").Bottom().PaneBorder(false).CloseButton(false));
m_aui_mgr.GetPane(L"asm_list").CaptionVisible(false).Show();
m_aui_mgr.GetPane(L"hex_list").CaptionVisible(false).Show();
m_aui_mgr.GetPane(L"err_list").Caption("Errors").Show();
m_aui_mgr.Update();
FrameBase::LoadInfo();
Bind(wxEVT_MENU, &CompilerELF::AnalyzeCode, this, id_analyze_code);
Bind(wxEVT_MENU, &CompilerELF::CompileCode, this, id_compile_code);
Bind(wxEVT_MENU, (void (CompilerELF::*)(wxCommandEvent&)) &CompilerELF::LoadElf, this, id_load_elf);
asm_list->SetFont(wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
hex_list->SetFont(wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
asm_list->Bind(wxEVT_TEXT, &CompilerELF::OnUpdate, this);
Bind(wxEVT_SCROLLWIN_TOP, &CompilerELF::OnScroll, this);
Bind(wxEVT_SCROLLWIN_BOTTOM, &CompilerELF::OnScroll, this);
Bind(wxEVT_SCROLLWIN_LINEUP, &CompilerELF::OnScroll, this);
Bind(wxEVT_SCROLLWIN_LINEDOWN, &CompilerELF::OnScroll, this);
Bind(wxEVT_SCROLLWIN_THUMBTRACK, &CompilerELF::OnScroll, this);
Bind(wxEVT_SCROLLWIN_THUMBRELEASE, &CompilerELF::OnScroll, this);
asm_list->Bind(wxEVT_MOUSEWHEEL, &CompilerELF::MouseWheel, this);
hex_list->Bind(wxEVT_MOUSEWHEEL, &CompilerELF::MouseWheel, this);
asm_list->Bind(wxEVT_KEY_DOWN, &CompilerELF::OnKeyDown, this);
hex_list->Bind(wxEVT_KEY_DOWN, &CompilerELF::OnKeyDown, this);
asm_list->WriteText(
".int [sys_tty_write, 0x193]\n"
".int [sys_process_exit, 0x003]\n"
".string [str, \"Hello World!\\n\"]\n"
".strlen [str_len, str]\n"
".buf [ret, 8]\n"
"\n"
".srr [str_hi, str, 16]\n"
".and [str_lo, str, 0xffff]\n"
"\n"
".srr [ret_hi, str, 16]\n"
".and [ret_lo, str, 0xffff]\n"
"\n"
" addi r3, r0, 0\n"
" addi r4, r0, str_lo\n"
" oris r4, r4, str_hi\n"
" addi r5, r0, str_len\n"
" addi r6, r0, ret_lo\n"
" oris r6, r6, ret_hi\n"
" addi r11, r0, sys_tty_write\n"
" sc 2\n"
" cmpi cr7, 0, r3, 0\n"
" bc 0x04, 30, exit_err, 0, 0\n"
"\n"
"exit_ok:\n"
" addi r3, r0, 0\n"
" b exit, 0, 0\n"
"\n"
"exit_err:\n"
".string [str, \"error.\\n\"]\n"
".srr [str_hi, str, 16]\n"
".and [str_lo, str, 0xffff]\n"
".strlen [str_len, str]\n"
".int [written_len_lo, fd_lo]\n"
".int [written_len_hi, fd_hi]\n"
" addi r3, r0, 1\n"
" addi r4, r0, str_lo\n"
" oris r4, r4, str_hi\n"
" addi r5, r0, str_len\n"
" addi r6, r0, written_len_lo\n"
" oris r6, r6, written_len_hi\n"
" addi r11, r0, sys_tty_write\n"
" sc 2\n"
" addi r3, r0, 1\n"
"\n"
"exit:\n"
" addi r11, r0, sys_process_exit\n"
" sc 2\n"
" addi r3, r0, 1\n"
" b exit, 0, 0\n"
);
#ifdef _MSC_VER
::SendMessage((HWND)hex_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
::SendMessage((HWND)asm_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
#endif
}
CompilerELF::~CompilerELF()
{
m_aui_mgr.UnInit();
}
void CompilerELF::MouseWheel(wxMouseEvent& event)
{
int value = (event.m_wheelRotation / event.m_wheelDelta);
wxScrollWinEvent scrool_event;
scrool_event.SetEventType(value > 0 ? wxEVT_SCROLLWIN_LINEUP : wxEVT_SCROLLWIN_LINEDOWN);
scrool_event.SetOrientation(wxVERTICAL);
if(value < 0) value = -value;
value *= event.m_linesPerAction;
while(value--)
{
scrool_event.SetEventObject(asm_list);
OnScroll(scrool_event);
scrool_event.SetEventObject(hex_list);
OnScroll(scrool_event);
}
}
void CompilerELF::UpdateStatus(int offset)
{
long line;
if(asm_list->PositionToXY(asm_list->GetInsertionPoint() - 2, nullptr, &line))
{
m_status_bar.SetStatusText(wxString::Format("line %d", line), 0);
return;
}
m_status_bar.SetStatusText(wxEmptyString, 0);
}
void CompilerELF::OnKeyDown(wxKeyEvent& event)
{
wxScrollWinEvent scrool_event;
scrool_event.SetOrientation(wxVERTICAL);
switch(event.GetKeyCode())
{
case WXK_RETURN: UpdateStatus( 1); break;
case WXK_UP: UpdateStatus(-1); break;
case WXK_DOWN: UpdateStatus( 1); break;
case WXK_LEFT:
case WXK_RIGHT: UpdateStatus(); break;
case WXK_PAGEUP:
scrool_event.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
scrool_event.SetEventObject(asm_list);
OnScroll(scrool_event);
scrool_event.SetEventObject(hex_list);
OnScroll(scrool_event);
return;
case WXK_PAGEDOWN:
scrool_event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
scrool_event.SetEventObject(asm_list);
OnScroll(scrool_event);
scrool_event.SetEventObject(hex_list);
OnScroll(scrool_event);
return;
}
event.Skip();
}
void CompilerELF::OnUpdate(wxCommandEvent& event)
{
UpdateStatus();
DoAnalyzeCode(false);
return;
//asm_list->Freeze();
//asm_list->SetStyle(0, asm_list->GetValue().Len(), wxTextAttr("Black"));
///*
//for(u32 i=0; i<instr_count; ++i)
//{
// SetOpStyle(m_instructions[i].name, "Blue");
//}
//*/
//
//SetOpStyle(".int", "Blue");
//SetOpStyle(".string", "Blue");
//SetOpStyle(".strlen", "Blue");
//SetOpStyle(".buf", "Blue");
//SetOpStyle(".srl", "Blue");
//SetOpStyle(".srr", "Blue");
//SetOpStyle(".mul", "Blue");
//SetOpStyle(".div", "Blue");
//SetOpStyle(".add", "Blue");
//SetOpStyle(".sub", "Blue");
//SetOpStyle(".and", "Blue");
//SetOpStyle(".or", "Blue");
//SetOpStyle(".xor", "Blue");
//SetOpStyle(".not", "Blue");
//SetOpStyle(".nor", "Blue");
//SetTextStyle("[", "Red");
//SetTextStyle("]", "Red");
//SetTextStyle(":", "Red");
//SetTextStyle(",", "Red");
//for(int p=0; (p = asm_list->GetValue().find('#', p)) >= 0;)
//{
// const int from = p++;
// p = asm_list->GetValue().find('\n', p);
// if(p < 0) p = asm_list->GetValue().Len();
// asm_list->SetStyle(from, p, wxTextAttr(0x009900));
//}
//
//for(int p=0; (p = asm_list->GetValue().find('"', p)) >= 0;)
//{
// const int from = p++;
// const int p1 = asm_list->GetValue().find('\n', p);
// int p2 = p;
// for(;;)
// {
// p2 = asm_list->GetValue().find('"', p2);
// if(p2 == -1) break;
// if(asm_list->GetValue()[p2 - 1] == '\\')
// {
// if(p2 > 2 && asm_list->GetValue()[p2 - 2] == '\\') break;
// p2++;
// continue;
// }
// break;
// }
// if(p1 < 0 && p2 < 0)
// {
// p = asm_list->GetValue().Len();
// }
// else if(p1 >= 0 && p2 < 0)
// {
// p = p1;
// }
// else if(p2 >= 0 && p1 < 0)
// {
// p = p2 + 1;
// }
// else
// {
// p = p1 > p2 ? p2 + 1 : p1;
// }
// asm_list->SetStyle(from, p, wxTextAttr(0x000099));
//}
//asm_list->Thaw();
//UpdateScroll(true, wxVERTICAL);
}
void CompilerELF::OnScroll(wxScrollWinEvent& event)
{
if(!m_aui_mgr.GetManagedWindow()) return;
const int id = event.GetEventObject() ? ((wxScrollBar*)event.GetEventObject())->GetId() : -1;
wxTextCtrl* src = nullptr;
wxTextCtrl* dst = nullptr;
if(id == hex_list->GetId())
{
src = hex_list;
dst = asm_list;
}
else if(id == asm_list->GetId())
{
src = asm_list;
dst = hex_list;
}
#ifdef _MSC_VER
if(!m_disable_scroll && src && dst && event.GetOrientation() == wxVERTICAL)
{
s64 kind = -1;
if(event.GetEventType() == wxEVT_SCROLLWIN_TOP)
{
kind = SB_TOP;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM)
{
kind = SB_BOTTOM;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_LINEUP)
{
kind = SB_LINEUP;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN)
{
kind = SB_LINEDOWN;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_PAGEUP)
{
kind = SB_PAGEUP;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_PAGEDOWN)
{
kind = SB_PAGEDOWN;
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_THUMBTRACK)
{
kind = MAKEWPARAM(SB_THUMBTRACK, event.GetPosition());
//dst->SetScrollPos(event.GetOrientation(), event.GetPosition());
}
else if(event.GetEventType() == wxEVT_SCROLLWIN_THUMBRELEASE)
{
kind = MAKEWPARAM(SB_THUMBPOSITION, event.GetPosition());
//dst->SetScrollPos(event.GetOrientation(), event.GetPosition());
}
if(kind >= 0)
{
m_disable_scroll = true;
::SendMessage((HWND)dst->GetHWND(), (event.GetOrientation() == wxVERTICAL ? WM_VSCROLL : WM_HSCROLL), kind, 0);
m_disable_scroll = false;
}
}
#endif
event.Skip();
}
void CompilerELF::UpdateScroll(bool is_hex, int orient)
{
wxScrollWinEvent event;
event.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
event.SetEventObject(is_hex ? asm_list : hex_list);
event.SetPosition(is_hex ? asm_list->GetScrollPos(orient) : hex_list->GetScrollPos(orient));
event.SetOrientation(orient);
OnScroll(event);
}
void CompilerELF::LoadElf(wxCommandEvent& event)
{
wxFileDialog ctrl(this, L"Select ELF", wxEmptyString, wxEmptyString,
"Elf Files (*.elf, *.bin)|*.elf;*.bin|"
"All Files (*.*)|*.*",
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if(ctrl.ShowModal() == wxID_CANCEL) return;
LoadElf(fmt::ToUTF8(ctrl.GetPath()));
}
//#include "Emu/Cell/PPUDisAsm.h"
//#include "Emu/Cell/PPUDecoder.h"
void CompilerELF::LoadElf(const std::string& path)
{
}
void CompilerELF::SetTextStyle(const std::string& text, const wxColour& color, bool bold)
{
for(int p=0; (p = fmt::ToUTF8(asm_list->GetValue()).find(text, p)) !=std::string::npos; p += text.length())
{
asm_list->SetStyle(p, p + text.length(), wxTextAttr(color, wxNullColour,
wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL)));
}
}
void CompilerELF::SetOpStyle(const std::string& text, const wxColour& color, bool bold)
{
/*
for(int p=0; (p = FindOp(asm_list->GetValue(), text, p)) >= 0; p += text.Len())
{
asm_list->SetStyle(p, p + text.Len(), wxTextAttr(color, wxNullColour,
wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL)));
}
*/
}
void CompilerELF::DoAnalyzeCode(bool compile)
{
// CompilePPUProgram(fmt::ToUTF8(asm_list->GetValue()), "compiled.elf", asm_list, hex_list, err_list, !compile).Compile();
}

View File

@ -1,44 +0,0 @@
#pragma once
#include "Gui/MainFrame.h"
class CompilerELF : public FrameBase
{
wxAuiManager m_aui_mgr;
wxStatusBar& m_status_bar;
bool m_disable_scroll;
public:
CompilerELF(wxWindow* parent);
~CompilerELF();
wxTextCtrl* asm_list;
wxTextCtrl* hex_list;
wxTextCtrl* err_list;
void MouseWheel(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnUpdate(wxCommandEvent& event);
void OnScroll(wxScrollWinEvent& event);
void UpdateScroll(bool is_hex, int orient);
void AnalyzeCode(wxCommandEvent& WXUNUSED(event))
{
DoAnalyzeCode(false);
}
void CompileCode(wxCommandEvent& WXUNUSED(event))
{
DoAnalyzeCode(true);
}
void LoadElf(wxCommandEvent& event);
void LoadElf(const std::string& path);
void SetTextStyle(const std::string& text, const wxColour& color, bool bold=false);
void SetOpStyle(const std::string& text, const wxColour& color, bool bold = true);
void DoAnalyzeCode(bool compile);
void UpdateStatus(int offset=0);
};

View File

@ -1,13 +1,14 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/state.h"
#include "Gui/ConLogFrame.h"
enum
{
id_log_copy, // Copy log to ClipBoard
id_log_clear, // Clear log
id_log_level,
id_log_level7 = id_log_level + 7,
id_log_tty,
id_timer,
};
@ -22,10 +23,12 @@ LogFrame::LogFrame(wxWindow* parent)
, m_log(new wxTextCtrl(&m_tabs, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2))
, m_tty(new wxTextCtrl(&m_tabs, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2))
, m_timer(this, id_timer)
, m_cfg_level(g_gui_cfg["Log Level"])
, m_cfg_tty(g_gui_cfg["Log TTY"])
{
// Open or create RPCS3.log; TTY.log
m_log_file.open(fs::get_config_dir() + "RPCS3.log", fom::read | fom::create);
m_tty_file.open(fs::get_config_dir() + "TTY.log", fom::read | fom::create);
m_log_file.open(fs::get_config_dir() + "RPCS3.log", fs::read + fs::create);
m_tty_file.open(fs::get_config_dir() + "TTY.log", fs::read + fs::create);
m_tty->SetBackgroundColour(wxColour("Black"));
m_log->SetBackgroundColour(wxColour("Black"));
@ -42,6 +45,8 @@ LogFrame::LogFrame(wxWindow* parent)
m_log->Bind(wxEVT_RIGHT_DOWN, &LogFrame::OnRightClick, this);
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_clear);
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_copy);
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_level, id_log_level + 7);
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_tty);
Show();
@ -69,8 +74,21 @@ void LogFrame::OnRightClick(wxMouseEvent& event)
wxMenu* menu = new wxMenu();
menu->Append(id_log_copy, "&Copy");
menu->AppendSeparator();
menu->Append(id_log_clear, "C&lear");
menu->AppendSeparator();
menu->AppendRadioItem(id_log_level + 0, "Nothing");
menu->AppendRadioItem(id_log_level + 1, "Fatal");
menu->AppendRadioItem(id_log_level + 2, "Error");
menu->AppendRadioItem(id_log_level + 3, "Todo");
menu->AppendRadioItem(id_log_level + 4, "Success");
menu->AppendRadioItem(id_log_level + 5, "Warning");
menu->AppendRadioItem(id_log_level + 6, "Notice");
menu->AppendRadioItem(id_log_level + 7, "Trace");
menu->AppendSeparator();
menu->AppendCheckItem(id_log_tty, "TTY");
menu->Check(id_log_level + static_cast<uint>(get_cfg_level()), true);
menu->Check(id_log_tty, get_cfg_tty());
PopupMenu(menu);
}
@ -78,13 +96,17 @@ void LogFrame::OnRightClick(wxMouseEvent& event)
// Well you can bind more than one control to a single handler.
void LogFrame::OnContextMenu(wxCommandEvent& event)
{
int id = event.GetId();
switch (id)
switch (auto id = event.GetId())
{
case id_log_clear:
{
m_log->Clear();
m_log_file.seek(0, fs::seek_end);
break;
}
case id_log_copy:
{
if (wxTheClipboard->Open())
{
m_tdo = new wxTextDataObject(m_log->GetStringSelection());
@ -95,19 +117,36 @@ void LogFrame::OnContextMenu(wxCommandEvent& event)
wxTheClipboard->Close();
}
break;
default:
event.Skip();
}
case id_log_tty:
{
m_cfg_tty = !get_cfg_tty();
break;
}
default:
{
if (id >= id_log_level && id < id_log_level + 8)
{
m_cfg_level = id - id_log_level;
break;
}
}
}
save_gui_cfg();
event.Skip();
}
void LogFrame::OnTimer(wxTimerEvent& event)
{
char buf[4096];
std::vector<char> buf(4096);
// Get UTF-8 string from file
auto get_utf8 = [&](const fs::file& file, u64 size) -> wxString
{
size = file.read(buf, size);
size = file.read(buf.data(), size);
for (u64 i = 0; i < size; i++)
{
@ -120,37 +159,35 @@ void LogFrame::OnTimer(wxTimerEvent& event)
if (i + tail >= size)
{
file.seek(i - size, fs::seek_cur);
return wxString::FromUTF8(buf, i);
return wxString::FromUTF8(buf.data(), i);
}
}
return wxString::FromUTF8(buf, size);
return wxString::FromUTF8(buf.data(), size);
};
const auto stamp0 = std::chrono::high_resolution_clock::now();
const auto start = std::chrono::high_resolution_clock::now();
// Check TTY logs
while (const u64 size = std::min<u64>(sizeof(buf), _log::g_tty_file.size() - m_tty_file.seek(0, fs::seek_cur)))
while (const u64 size = std::min<u64>(sizeof(buf), _log::g_tty_file.size() - m_tty_file.pos()))
{
const wxString& text = get_utf8(m_tty_file, size);
m_tty->AppendText(text);
if (get_cfg_tty()) m_tty->AppendText(text);
// Limit processing time
if (std::chrono::high_resolution_clock::now() >= stamp0 + 4ms || text.empty()) break;
if (std::chrono::high_resolution_clock::now() >= start + 4ms || text.empty()) break;
}
const auto stamp1 = std::chrono::high_resolution_clock::now();
// Check main logs
while (const u64 size = std::min<u64>(sizeof(buf), _log::g_log_file.size() - m_log_file.seek(0, fs::seek_cur)))
while (const u64 size = std::min<u64>(sizeof(buf), m_log_file.size() - m_log_file.pos()))
{
const wxString& text = get_utf8(m_log_file, size);
// Append text if necessary
auto flush_logs = [&](u64 start, u64 pos)
{
if (pos != start && m_level <= rpcs3::config.misc.log.level.value())
if (pos != start && m_level <= get_cfg_level()) // TODO
{
m_log->SetDefaultStyle(m_color);
m_log->AppendText(text.substr(start, pos - start));
@ -205,6 +242,6 @@ void LogFrame::OnTimer(wxTimerEvent& event)
}
// Limit processing time
if (std::chrono::high_resolution_clock::now() >= stamp1 + 3ms || text.empty()) break;
if (std::chrono::high_resolution_clock::now() >= start + 7ms || text.empty()) break;
}
}

View File

@ -17,6 +17,12 @@ class LogFrame : public wxPanel
wxTimer m_timer;
YAML::Node m_cfg_level;
YAML::Node m_cfg_tty;
_log::level get_cfg_level() const { return static_cast<_log::level>(m_cfg_level.as<uint>(4)); }
bool get_cfg_tty() const { return m_cfg_tty.as<bool>(true); }
public:
LogFrame(wxWindow* parent);
LogFrame(LogFrame &other) = delete;

View File

@ -6,7 +6,6 @@
#include "rpcs3.h"
#include "Debugger.h"
#include "InterpreterDisAsm.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/CPU/CPUThread.h"
extern bool user_asked_for_frame_capture;

View File

@ -1,517 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#if 0
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "DisAsmFrame.h"
#include "Emu/FS/vfsLocalFile.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPCThread.h"
#include "Gui/DisAsmFrame.h"
#include "Emu/Cell/PPUDecoder.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/SPUDecoder.h"
#include "Emu/Cell/SPUDisAsm.h"
DisAsmFrame::DisAsmFrame(PPCThread& cpu)
: wxFrame(nullptr, wxID_ANY, "DisAsm")
, CPU(cpu)
{
exit = false;
count = 0;
wxBoxSizer* s_panel = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_b_panel = new wxBoxSizer(wxHORIZONTAL);
m_disasm_list = new wxListView(this);
m_disasm_list->Bind(wxEVT_MOUSEWHEEL, &DisAsmFrame::MouseWheel, this);
wxButton* b_fprev = new wxButton(this, wxID_ANY, L"<<");
wxButton* b_prev = new wxButton(this, wxID_ANY, L"<");
wxButton* b_next = new wxButton(this, wxID_ANY, L">");
wxButton* b_fnext = new wxButton(this, wxID_ANY, L">>");
b_fprev->Bind(wxEVT_BUTTON, &DisAsmFrame::fPrev, this);
b_prev->Bind(wxEVT_BUTTON, &DisAsmFrame::Prev, this);
b_next->Bind(wxEVT_BUTTON, &DisAsmFrame::Next, this);
b_fnext->Bind(wxEVT_BUTTON, &DisAsmFrame::fNext, this);
wxButton* b_dump = new wxButton(this, wxID_ANY, L"Dump code");
b_dump->Bind(wxEVT_BUTTON, &DisAsmFrame::Dump, this);
wxButton* b_setpc = new wxButton(this, wxID_ANY, L"Set PC");
b_setpc->Bind(wxEVT_BUTTON, &DisAsmFrame::SetPc, this);
s_b_panel->Add(b_fprev);
s_b_panel->Add(b_prev);
s_b_panel->AddSpacer(5);
s_b_panel->Add(b_next);
s_b_panel->Add(b_fnext);
s_b_panel->AddSpacer(8);
s_b_panel->Add(b_dump);
s_panel->Add(s_b_panel);
s_panel->Add(b_setpc);
s_panel->Add(m_disasm_list);
m_disasm_list->InsertColumn(0, "PC");
m_disasm_list->InsertColumn(1, "ASM");
m_disasm_list->SetColumnWidth(0, 50);
for(uint i=0; i<LINES_OPCODES; ++i)
m_disasm_list->InsertItem(i, -1);
SetSizerAndFit(s_panel);
SetSize(50, 660);
Bind(wxEVT_SIZE, &DisAsmFrame::OnResize, this);
}
void DisAsmFrame::OnResize(wxSizeEvent& event)
{
const wxSize size(GetClientSize());
m_disasm_list->SetSize( size.GetWidth(), size.GetHeight() - 25 );
m_disasm_list->SetColumnWidth( 1, size.GetWidth() - (m_disasm_list->GetColumnWidth(0) + 8) );
event.Skip();
}
void DisAsmFrame::AddLine(const wxString line)
{
static bool finished = false;
if(finished && Emu.IsRunning())
{
count = 0;
finished = false;
}
else if(count >= LINES_OPCODES || !Emu.IsRunning())
{
if(Emu.IsRunning()) Emu.Pause();
finished = true;
CPU.PC -= 4;
return;
}
m_disasm_list->SetItem(count, 0, wxString::Format("%x", CPU.PC));
m_disasm_list->SetItem(count, 1, line);
++count;
}
void DisAsmFrame::Resume()
{
Emu.Resume();
}
#include <Utilities/MTProgressDialog.h>
#include "Loader/ELF.h"
#include "Loader/ELF32.h"
#include "Loader/ELF64.h"
std::vector<Elf64_Shdr>* shdr_arr_64 = NULL;
std::vector<Elf32_Shdr>* shdr_arr_32 = NULL;
ELF64Loader* l_elf64 = NULL;
ELF32Loader* l_elf32 = NULL;
bool ElfType64 = false;
class DumperThread : public ThreadBase
{
volatile uint id;
PPCDisAsm* disasm;
PPCDecoder* decoder;
volatile bool* done;
volatile u8 cores;
MTProgressDialog* prog_dial;
wxArrayString** arr;
public:
DumperThread() : ThreadBase("DumperThread")
{
}
void Set(uint _id, u8 _cores, bool* _done, MTProgressDialog& _prog_dial, wxArrayString** _arr)
{
id = _id;
cores = _cores;
done = _done;
prog_dial = &_prog_dial;
arr = _arr;
*done = false;
if(Emu.GetCPU().GetThreads()[0]->GetType() != CPU_THREAD_PPU)
{
SPUDisAsm& dis_asm = *new SPUDisAsm(CPUDisAsm_DumpMode);
decoder = new SPUDecoder(dis_asm);
disasm = &dis_asm;
}
else
{
PPUDisAsm* dis_asm = new PPUDisAsm(CPUDisAsm_DumpMode);
decoder = new PPUDecoder(dis_asm);
disasm = dis_asm;
}
}
virtual void Task()
{
LOG_NOTICE(HLE, "Start dump in thread %d!", (int)id);
const u32 max_value = prog_dial->GetMaxValue(id);
const u32 shdr_count = ElfType64 ? shdr_arr_64->size() : shdr_arr_32->size();
for(u32 sh=0, vsize=0; sh<shdr_count; ++sh)
{
const u64 sh_size = (ElfType64 ? (*shdr_arr_64)[sh].sh_size : (*shdr_arr_32)[sh].sh_size) / 4;
const u64 sh_addr = (ElfType64 ? (*shdr_arr_64)[sh].sh_addr : (*shdr_arr_32)[sh].sh_addr);
u64 d_size = sh_size / cores;
const u64 s_fix = sh_size % cores;
if(id <= s_fix) d_size++;
for(u64 off = id * 4, size=0; size<d_size; vsize++, size++)
{
prog_dial->Update(id, vsize,
wxString::Format("%d thread: %d of %d", (int)id + 1, vsize, max_value));
disasm->dump_pc = sh_addr + off;
decoder->Decode(vm::read32(disasm->dump_pc));
arr[id][sh].Add(fmt::FromUTF8(disasm->last_opcode));
off += (cores - id) * 4;
off += id * 4;
}
}
LOG_NOTICE(HLE, "Finish dump in thread %d!", (int)id);
*done = true;
}
void OnExit()
{
LOG_NOTICE(HLE, "CleanUp dump thread (%d)!", (int)id);
safe_delete(decoder);
}
};
struct WaitDumperThread : public ThreadBase
{
volatile bool* done;
volatile u8 cores;
wxString patch;
MTProgressDialog& prog_dial;
wxArrayString** arr;
WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr)
: ThreadBase("WaitDumperThread")
, done(_done)
, cores(_cores)
, patch(_patch)
, prog_dial(_prog_dial)
, arr(_arr)
{
}
~WaitDumperThread()
{
delete (bool*)done;
done = NULL;
}
virtual void Task()
{
for(uint i=0; i<cores; i++)
{
while(done[i] == false)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
LOG_NOTICE(HLE, "Saving dump is started!");
const uint length_for_core = prog_dial.GetMaxValue(0);
const uint length = length_for_core * cores;
prog_dial.Close();
wxArrayLong max;
max.Add(length);
MTProgressDialog& prog_dial2 =
*new MTProgressDialog(NULL, wxDefaultSize, "Saving", "Loading...", max, 1);
wxFile fd;
fd.Open(patch, wxFile::write);
const u32 shdr_count = ElfType64 ? shdr_arr_64->size() : shdr_arr_32->size();
for(uint sh=0, counter=0; sh<shdr_count; ++sh)
{
const u64 sh_size = ElfType64 ? (*shdr_arr_64)[sh].sh_size : (*shdr_arr_32)[sh].sh_size;
if(!sh_size) continue;
const uint c_sh_size = sh_size / 4;
fd.Write(wxString::Format("Start of section header %d (instructions count: %d)\n", sh, c_sh_size));
for(uint i=0, c=0, v=0; i<c_sh_size; i++, c++, counter++)
{
if(c >= cores)
{
c = 0;
v++;
}
prog_dial2.Update(0, counter, wxString::Format("Saving data to file: %d of %d", counter, length));
if(v >= arr[c][sh].GetCount()) continue;
fd.Write("\t");
fd.Write(arr[c][sh][v]);
}
fd.Write(wxString::Format("End of section header %d\n\n", sh));
}
LOG_NOTICE(HLE, "CleanUp dump saving!");
for(uint c=0; c<cores; ++c)
{
for(uint sh=0; sh<shdr_count; ++sh) arr[c][sh].Empty();
}
delete[] arr;
//safe_delete(shdr_arr);
delete l_elf32;
delete l_elf64;
prog_dial2.Close();
fd.Close();
wxMessageBox("Dumping done.", "rpcs3 message");
Emu.Stop();
}
};
void DisAsmFrame::Dump(wxCommandEvent& WXUNUSED(event))
{
wxFileDialog ctrl( this, L"Select output file...",
wxEmptyString, "DisAsm.txt", "*.txt", wxFD_SAVE);
if(ctrl.ShowModal() == wxID_CANCEL) return;
vfsLocalFile& f_elf = *new vfsLocalFile(nullptr);
f_elf.Open(Emu.m_path);
LOG_NOTICE(HLE, "path: %s", Emu.m_path.c_str());
Elf_Ehdr ehdr;
ehdr.Load(f_elf);
if(!ehdr.CheckMagic())
{
LOG_ERROR(HLE, "Corrupted ELF!");
return;
}
std::vector<std::string> name_arr;
switch(ehdr.GetClass())
{
case CLASS_ELF64:
ElfType64 = true;
l_elf64 = new ELF64Loader(f_elf);
if(!l_elf64->LoadInfo())
{
delete l_elf64;
return;
}
name_arr = l_elf64->shdr_name_arr;
shdr_arr_64 = &l_elf64->shdr_arr;
if(l_elf64->shdr_arr.size() <= 0) return;
break;
case CLASS_ELF32:
ElfType64 = false;
l_elf32 = new ELF32Loader(f_elf);
if(!l_elf32->LoadInfo())
{
delete l_elf32;
return;
}
name_arr = l_elf32->shdr_name_arr;
shdr_arr_32 = &l_elf32->shdr_arr;
if(l_elf32->shdr_arr.size() <= 0) return;
break;
default: LOG_ERROR(HLE, "Corrupted ELF!"); return;
}
PPCDisAsm* disasm;
PPCDecoder* decoder;
switch(Emu.GetCPU().GetThreads()[0]->GetType())
{
case CPU_THREAD_PPU:
{
PPUDisAsm* dis_asm = new PPUDisAsm(CPUDisAsm_DumpMode);
decoder = new PPUDecoder(dis_asm);
disasm = dis_asm;
}
break;
case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU:
{
SPUDisAsm& dis_asm = *new SPUDisAsm(CPUDisAsm_DumpMode);
decoder = new SPUDecoder(dis_asm);
disasm = &dis_asm;
}
break;
}
const u32 shdr_count = ElfType64 ? shdr_arr_64->size() : shdr_arr_32->size();
u64 max_count = 0;
for(u32 sh=0; sh<shdr_count; ++sh)
{
const u64 sh_size = (ElfType64 ? (*shdr_arr_64)[sh].sh_size : (*shdr_arr_32)[sh].sh_size) / 4;
max_count += sh_size;
}
wxArrayLong max;
max.Add(max_count);
MTProgressDialog& prog_dial = *new MTProgressDialog(NULL, wxDefaultSize, "Saving", "Loading...", max, 1);
max.Clear();
wxFile fd(ctrl.GetPath(), wxFile::write);
for(u32 sh=0, vsize=0; sh<shdr_count; ++sh)
{
const u64 sh_size = (ElfType64 ? (*shdr_arr_64)[sh].sh_size : (*shdr_arr_32)[sh].sh_size) / 4;
const u64 sh_addr = (ElfType64 ? (*shdr_arr_64)[sh].sh_addr : (*shdr_arr_32)[sh].sh_addr);
const std::string name = sh < name_arr.size() ? name_arr[sh] : "Unknown";
fd.Write(wxString::Format("Start of section header %s[%d] (instructions count: %d)\n", name.c_str(), sh, sh_size));
prog_dial.Update(0, vsize, wxString::Format("Disasm %s section", name.c_str()));
if(Memory.IsGoodAddr(sh_addr))
{
for(u64 addr=sh_addr; addr<sh_addr+sh_size; addr++, vsize++)
{
disasm->dump_pc = addr;
decoder->Decode(vm::read32(disasm->dump_pc));
fd.Write("\t");
fd.Write(fmt::FromUTF8(disasm->last_opcode));
}
}
fd.Write(wxString::Format("End of section header %s[%d]\n\n", name.c_str(), sh));
}
prog_dial.Close();
Emu.Stop();
/*
SYSTEM_INFO si;
GetSystemInfo(&si);
const uint cores_count =
(si.dwNumberOfProcessors < 1 || si.dwNumberOfProcessors > 8 ? 2 : si.dwNumberOfProcessors);
wxArrayLong max;
max.Clear();
u64 max_count = 0;
if(ElfType64)
{
for(uint sh=0; sh<l_elf64->shdr_arr.GetCount(); ++sh)
{
max_count += l_elf64->shdr_arr[sh].sh_size / 4;
}
}
else
{
for(uint sh=0; sh<l_elf32->shdr_arr.GetCount(); ++sh)
{
max_count += l_elf32->shdr_arr[sh].sh_size / 4;
}
}
for(uint c=0; c<cores_count; ++c) max.Add(max_count / cores_count);
for(uint c=0; c<max_count % cores_count; ++c) max[c]++;
MTProgressDialog& prog_dial = *new MTProgressDialog(this, wxDefaultSize, "Dumping...", "Loading", max, cores_count);
DumperThread* dump = new DumperThread[cores_count];
wxArrayString** arr = new wxArrayString*[cores_count];
bool* threads_done = new bool[cores_count];
for(uint i=0; i<cores_count; ++i)
{
arr[i] = new wxArrayString[ElfType64 ? l_elf64->shdr_arr.GetCount() : l_elf32->shdr_arr.GetCount()];
dump[i].Set(i, cores_count, &threads_done[i], prog_dial, arr);
dump[i].Start();
}
WaitDumperThread& wait_dump =
*new WaitDumperThread(threads_done, cores_count, ctrl.GetPath(), prog_dial, arr);
wait_dump.Start();
*/
}
void DisAsmFrame::Prev (wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - 4*(LINES_OPCODES+1)); Resume(); } }
void DisAsmFrame::Next (wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - 4*(LINES_OPCODES-1)); Resume(); } }
void DisAsmFrame::fPrev(wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - (4*LINES_OPCODES)*2); Resume(); } }
void DisAsmFrame::fNext(wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { Resume(); } }
void DisAsmFrame::SetPc(wxCommandEvent& WXUNUSED(event))
{
if(!Emu.IsPaused()) return;
wxDialog diag(this, wxID_ANY, "Set PC", wxDefaultPosition);
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
wxTextCtrl* p_pc(new wxTextCtrl(&diag, wxID_ANY));
s_panel->Add(p_pc);
s_panel->AddSpacer(8);
s_panel->Add(s_b_panel);
s_b_panel->Add(new wxButton(&diag, wxID_OK), wxLEFT, 0, 5);
s_b_panel->AddSpacer(5);
s_b_panel->Add(new wxButton(&diag, wxID_CANCEL), wxRIGHT, 0, 5);
diag.SetSizerAndFit( s_panel );
p_pc->SetLabel(wxString::Format("%x", CPU.PC));
if(diag.ShowModal() == wxID_OK)
{
sscanf(fmt::ToUTF8(p_pc->GetLabel()).c_str(), "%x", &CPU.PC);
Resume();
}
}
void DisAsmFrame::MouseWheel(wxMouseEvent& event)
{
if(!Emu.IsPaused())
{
event.Skip();
return;
}
const int value = (event.m_wheelRotation / event.m_wheelDelta);
if(event.ControlDown())
{
CPU.SetPc( CPU.PC - (((4*LINES_OPCODES)*2)*value) );
}
else
{
CPU.SetPc( CPU.PC - 4*(LINES_OPCODES + (value /** event.m_linesPerAction*/)) );
}
Emu.Resume();
event.Skip();
}
#endif

View File

@ -1,36 +0,0 @@
#pragma once
#if 0
class PPCThread;
class DisAsmFrame : public wxFrame
{
static const uint LINES_OPCODES = 40;
u32 count;
wxListView* m_disasm_list;
PPCThread& CPU;
virtual void OnResize(wxSizeEvent& event);
virtual void Prev (wxCommandEvent& event);
virtual void Next (wxCommandEvent& event);
virtual void fPrev(wxCommandEvent& event);
virtual void fNext(wxCommandEvent& event);
virtual void SetPc(wxCommandEvent& event);
void Dump(wxCommandEvent& event);
void Resume();
void MouseWheel(wxMouseEvent& event);
public:
bool exit;
DisAsmFrame(PPCThread& cpu);
~DisAsmFrame()
{
exit = true;
}
virtual void AddLine(const wxString line);
};
#endif

60
rpcs3/Gui/FrameBase.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "FrameBase.h"
FrameBase::FrameBase(wxWindow* parent, wxWindowID id, const wxString& frame_name, const std::string& ini_name, wxSize defsize, wxPoint defposition, long style)
: wxFrame(parent, id, frame_name, defposition, defsize, style)
, ini_name(ini_name.empty() ? fmt::ToUTF8(frame_name) : ini_name)
{
LoadInfo();
Bind(wxEVT_CLOSE_WINDOW, &FrameBase::OnClose, this);
Bind(wxEVT_MOVE, &FrameBase::OnMove, this);
Bind(wxEVT_SIZE, &FrameBase::OnResize, this);
}
void FrameBase::SetSizerAndFit(wxSizer* sizer, bool deleteOld, bool loadinfo)
{
wxFrame::SetSizerAndFit(sizer, deleteOld);
if (loadinfo) LoadInfo();
}
void FrameBase::LoadInfo()
{
auto&& cfg = g_gui_cfg[ini_name];
auto&& size = GetSize();
std::tie(size.x, size.y) = cfg["size"].as<std::pair<int, int>>(std::make_pair(size.x, size.y));
SetSize(size);
auto&& pos = GetPosition();
std::tie(pos.x, pos.y) = cfg["pos"].as<std::pair<int, int>>(std::make_pair(pos.x, pos.y));
SetPosition(pos);
}
void FrameBase::OnMove(wxMoveEvent& event)
{
auto&& cfg = g_gui_cfg[ini_name];
const auto& pos = GetPosition();
cfg["pos"] = std::make_pair(pos.x, pos.y);
event.Skip();
}
void FrameBase::OnResize(wxSizeEvent& event)
{
auto&& cfg = g_gui_cfg[ini_name];
const auto& size = GetSize();
cfg["size"] = std::make_pair(size.x, size.y);
const auto& pos = GetPosition();
cfg["pos"] = std::make_pair(pos.x, pos.y);
}
void FrameBase::OnClose(wxCloseEvent& event)
{
save_gui_cfg();
event.Skip();
}

View File

@ -1,68 +1,26 @@
#pragma once
#include "Emu/state.h"
class FrameBase : public wxFrame
struct FrameBase : public wxFrame
{
protected:
bool m_is_skip_resize;
std::string m_ini_name;
const std::string ini_name;
protected:
FrameBase(
wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& framename = "UnknownFrame",
const std::string& ininame = "",
const wxString& frame_name = "UnknownFrame",
const std::string& ini_name = {},
wxSize defsize = wxDefaultSize,
wxPoint defposition = wxDefaultPosition,
long style = wxDEFAULT_FRAME_STYLE,
bool is_skip_resize = false)
: wxFrame(parent, id, framename, defposition, defsize, style)
, m_is_skip_resize(is_skip_resize)
{
//TODO
m_ini_name = ininame.empty() ? fmt::ToUTF8(framename) : ininame;
LoadInfo();
Bind(wxEVT_CLOSE_WINDOW, &FrameBase::OnClose, this);
Bind(wxEVT_MOVE, &FrameBase::OnMove, this);
Bind(wxEVT_SIZE, &FrameBase::OnResize, this);
}
long style = wxDEFAULT_FRAME_STYLE);
~FrameBase()
{
}
void SetSizerAndFit(wxSizer *sizer, bool deleteOld = true, bool loadinfo = true)
{
wxFrame::SetSizerAndFit(sizer, deleteOld);
if(loadinfo) LoadInfo();
}
void LoadInfo()
{
size2i size = rpcs3::config.gui.size.value();
position2i position = rpcs3::config.gui.position.value();
SetSize(wxSize(size.width, size.height));
SetPosition(wxPoint(position.x, position.y));
}
void OnMove(wxMoveEvent& event)
{
rpcs3::config.gui.position = position2i{ GetPosition().x, GetPosition().y };
event.Skip();
}
void OnResize(wxSizeEvent& event)
{
rpcs3::config.gui.size = size2i{ GetSize().GetWidth(), GetSize().GetHeight() };
rpcs3::config.gui.position = position2i{ GetPosition().x, GetPosition().y };
if(m_is_skip_resize) event.Skip();
}
void OnClose(wxCloseEvent& event)
{
rpcs3::config.save();
event.Skip();
}
void SetSizerAndFit(wxSizer* sizer, bool deleteOld = true, bool loadinfo = true);
void LoadInfo();
void OnMove(wxMoveEvent& event);
void OnResize(wxSizeEvent& event);
void OnClose(wxCloseEvent& event);
};

View File

@ -1,10 +1,14 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Utilities/Config.h"
#include "GLGSFrame.h"
#include "config.h"
#include <wx/version.h>
GLGSFrame::GLGSFrame() : GSFrame("OpenGL")
extern cfg::bool_entry g_cfg_rsx_debug_output;
GLGSFrame::GLGSFrame(size2i size)
: GSFrame("OpenGL", size)
{
const int context_attrs[] =
{
@ -16,15 +20,13 @@ GLGSFrame::GLGSFrame() : GSFrame("OpenGL")
WX_GL_MINOR_VERSION, 3,
WX_GL_CORE_PROFILE,
#if !defined(CMAKE_BUILD)
rpcs3::config.rsx.d3d12.debug_output.value() ? WX_GL_DEBUG : 0,
g_cfg_rsx_debug_output ? WX_GL_DEBUG : 0,
#endif
#endif
0
};
m_canvas = new wxGLCanvas(this, wxID_ANY, context_attrs);
m_canvas->SetSize(GetClientSize());
m_canvas = new wxGLCanvas(this, wxID_ANY, context_attrs, wxDefaultPosition, { size.width, size.height });
m_canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this);
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "Gui/GSFrame.h"
#include "wx/glcanvas.h"
@ -7,7 +8,7 @@ class GLGSFrame : public GSFrame
wxGLCanvas* m_canvas;
public:
GLGSFrame();
GLGSFrame(size2i);
void* make_context() override;
void set_current(draw_context_t context) override;

View File

@ -1,23 +1,23 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "GSFrame.h"
#include "Emu/System.h"
#include "Emu/state.h"
#include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "rpcs3.h"
#include "Utilities/Timer.h"
#include "Emu/System.h"
#include "rpcs3.h"
#include "GSFrame.h"
BEGIN_EVENT_TABLE(GSFrame, wxFrame)
EVT_PAINT(GSFrame::OnPaint)
EVT_SIZE(GSFrame::OnSize)
END_EVENT_TABLE()
GSFrame::GSFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, "GSFrame[" + title + "]")
GSFrame::GSFrame(const wxString& title, size2i size)
: wxFrame(nullptr, wxID_ANY, "GSFrame[" + title + "]")
{
SetIcon(wxGetApp().m_MainFrame->GetIcon());
CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum((u32)rpcs3::state.config.rsx.resolution.value())];
SetClientSize(res.width, res.height);
SetClientSize(size.width, size.height);
wxGetApp().Bind(wxEVT_KEY_DOWN, &GSFrame::OnKeyDown, this);
Bind(wxEVT_CLOSE_WINDOW, &GSFrame::OnClose, this);
Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this);
@ -102,16 +102,13 @@ void GSFrame::flip(draw_context_t)
{
std::string title = fmt::format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec());
if (!m_title_message.empty())
title += " | " + m_title_message;
if (!Emu.GetTitle().empty())
title += " | " + Emu.GetTitle();
if (!Emu.GetTitleID().empty())
title += " | [" + Emu.GetTitleID() + "]";
title += " | [" + Emu.GetTitleID() + ']';
// can freeze on exit
// can freeze
SetTitle(wxString(title.c_str(), wxConvUTF8));
m_frames = 0;
fps_t.Start();

View File

@ -1,4 +1,5 @@
#pragma once
#include "Emu/RSX/GSRender.h"
class GSFrame : public wxFrame, public GSFrameBase
@ -6,7 +7,7 @@ class GSFrame : public wxFrame, public GSFrameBase
u64 m_frames = 0;
public:
GSFrame(const wxString& title);
GSFrame(const wxString& title, size2i);
protected:
virtual void OnPaint(wxPaintEvent& event);

View File

@ -1,11 +1,7 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Utilities/AutoPause.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/FS/VFS.h"
#include "Emu/FS/vfsDir.h"
#include "Emu/FS/vfsFile.h"
#include "GameViewer.h"
#include "Loader/PSF.h"
#include "SettingsDialog.h"
@ -82,11 +78,11 @@ void GameViewer::LoadGames()
{
m_games.clear();
for (const auto info : vfsDir(m_path))
for (const auto& entry : fs::dir(vfs::get(m_path)))
{
if(info->flags & DirEntry_TypeDir)
if (entry.is_directory)
{
m_games.push_back(info->name);
m_games.push_back(entry.name);
}
}
}
@ -94,27 +90,19 @@ void GameViewer::LoadGames()
void GameViewer::LoadPSF()
{
m_game_data.clear();
for (u32 i = 0; i < m_games.size(); ++i)
{
const std::string sfb = m_path + m_games[i] + "/PS3_DISC.SFB";
const std::string sfo = m_path + m_games[i] + (Emu.GetVFS().ExistsFile(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
const std::string sfb = vfs::get(m_path) + m_games[i] + "/PS3_DISC.SFB";
const std::string sfo = vfs::get(m_path) + m_games[i] + (fs::is_file(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
if (!Emu.GetVFS().ExistsFile(sfo))
const fs::file sfo_file(sfo);
if (!sfo_file)
{
continue;
}
vfsFile f;
if (!f.Open(sfo))
{
continue;
}
const auto& psf = psf::load(f.VRead<char>());
// get local path from VFS...
std::string local_path;
Emu.GetVFS().GetDevice(m_path, local_path);
const auto& psf = psf::load_object(sfo_file);
GameInfo game;
game.root = m_games[i];
@ -129,33 +117,33 @@ void GameViewer::LoadPSF()
if (game.serial.length() == 9)
{
game.serial = game.serial.substr(0, 4) + "-" + game.serial.substr(4, 5);
game.serial.insert(4, 1, '-');
}
if (game.category.substr(0, 2) == "HG")
if (game.category == "HG")
{
game.category = "HDD Game";
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
game.icon_path = vfs::get(m_path) + m_games[i] + "/ICON0.PNG";
}
else if (game.category.substr(0, 2) == "DG")
else if (game.category == "DG")
{
game.category = "Disc Game";
game.icon_path = local_path + "/" + m_games[i] + "/PS3_GAME/ICON0.PNG";
game.icon_path = vfs::get(m_path) + m_games[i] + "/PS3_GAME/ICON0.PNG";
}
else if (game.category.substr(0, 2) == "HM")
else if (game.category == "HM")
{
game.category = "Home";
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
game.icon_path = vfs::get(m_path) + m_games[i] + "/ICON0.PNG";
}
else if (game.category.substr(0, 2) == "AV")
else if (game.category == "AV")
{
game.category = "Audio/Video";
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
game.icon_path = vfs::get(m_path) + m_games[i] + "/ICON0.PNG";
}
else if (game.category.substr(0, 2) == "GD")
else if (game.category == "GD")
{
game.category = "Game Data";
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
game.icon_path = vfs::get(m_path) + m_games[i] + "/ICON0.PNG";
}
m_game_data.push_back(game);
@ -173,11 +161,9 @@ void GameViewer::ShowData()
void GameViewer::Refresh()
{
Emu.GetVFS().Init("/");
LoadGames();
LoadPSF();
ShowData();
Emu.GetVFS().UnMountAll();
}
void GameViewer::SaveSettings()
@ -199,19 +185,9 @@ void GameViewer::DClick(wxListEvent& event)
Emu.Stop();
Debug::AutoPause::getInstance().Reload();
Emu.GetVFS().Init("/");
std::string local_path;
if (Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path))
if (!Emu.BootGame(vfs::get(path)))
{
LOG_ERROR(HLE, "Boot error: elf not found! [%s]", path.c_str());
return;
}
if (rpcs3::config.misc.always_start.value() && Emu.IsReady())
{
Emu.Run();
LOG_ERROR(LOADER, "Failed to boot %s", path);
}
}
@ -250,11 +226,7 @@ void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event))
long i = GetFirstSelected();
if (i < 0) return;
Emu.CreateConfig(m_game_data[i].serial);
rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + m_game_data[i].serial + "/settings.ini" };
custom_config.load();
LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str());
SettingsDialog(this, &custom_config);
LOG_TODO(LOADER, "Configure: %s", m_game_data[i].root);
}
void GameViewer::RemoveGame(wxCommandEvent& event)
@ -262,9 +234,218 @@ void GameViewer::RemoveGame(wxCommandEvent& event)
long i = GetFirstSelected();
if (i < 0) return;
Emu.GetVFS().Init("/");
Emu.GetVFS().DeleteAll(m_path + "/" + this->GetItemText(i, 6).ToStdString());
Emu.GetVFS().UnMountAll();
fs::remove_all(vfs::get(m_path) + this->GetItemText(i, 6).ToStdString());
Refresh();
}
ColumnsArr::ColumnsArr()
{
Init();
}
std::vector<Column*> ColumnsArr::GetSortedColumnsByPos()
{
std::vector<Column*> arr;
for (u32 pos = 0; pos<m_columns.size(); pos++)
{
for (u32 c = 0; c<m_columns.size(); ++c)
{
if (m_columns[c].pos != pos) continue;
arr.push_back(&m_columns[c]);
}
}
return arr;
}
Column* ColumnsArr::GetColumnByPos(u32 pos)
{
std::vector<Column *> columns = GetSortedColumnsByPos();
for (u32 c = 0; c<columns.size(); ++c)
{
if (!columns[c]->shown)
{
pos++;
continue;
}
if (columns[c]->pos != pos) continue;
return columns[c];
}
return NULL;
}
void ColumnsArr::Init()
{
m_img_list = new wxImageList(80, 44);
m_columns.clear();
m_columns.emplace_back(0, 90, "Icon");
m_columns.emplace_back(1, 160, "Name");
m_columns.emplace_back(2, 85, "Serial");
m_columns.emplace_back(3, 55, "FW");
m_columns.emplace_back(4, 55, "App version");
m_columns.emplace_back(5, 75, "Category");
m_columns.emplace_back(6, 160, "Path");
m_col_icon = &m_columns[0];
m_col_name = &m_columns[1];
m_col_serial = &m_columns[2];
m_col_fw = &m_columns[3];
m_col_app_ver = &m_columns[4];
m_col_category = &m_columns[5];
m_col_path = &m_columns[6];
}
void ColumnsArr::Update(const std::vector<GameInfo>& game_data)
{
m_col_icon->data.clear();
m_col_name->data.clear();
m_col_serial->data.clear();
m_col_fw->data.clear();
m_col_app_ver->data.clear();
m_col_category->data.clear();
m_col_path->data.clear();
m_icon_indexes.clear();
if (m_columns.size() == 0) return;
for (const auto& game : game_data)
{
m_col_icon->data.push_back(game.icon_path);
m_col_name->data.push_back(game.name);
m_col_serial->data.push_back(game.serial);
m_col_fw->data.push_back(game.fw);
m_col_app_ver->data.push_back(game.app_ver);
m_col_category->data.push_back(game.category);
m_col_path->data.push_back(game.root);
}
// load icons
for (const auto& path : m_col_icon->data)
{
wxImage game_icon(80, 44);
{
wxLogNull logNo; // temporary disable wx warnings ("iCCP: known incorrect sRGB profile" spamming)
if (game_icon.LoadFile(fmt::FromUTF8(path), wxBITMAP_TYPE_PNG))
game_icon.Rescale(80, 44, wxIMAGE_QUALITY_HIGH);
}
m_icon_indexes.push_back(m_img_list->Add(game_icon));
}
}
void ColumnsArr::Show(wxListView* list)
{
list->DeleteAllColumns();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
std::vector<Column *> c_col = GetSortedColumnsByPos();
for (u32 i = 0, c = 0; i<c_col.size(); ++i)
{
if (!c_col[i]->shown) continue;
list->InsertColumn(c++, fmt::FromUTF8(c_col[i]->name), 0, c_col[i]->width);
}
}
void ColumnsArr::ShowData(wxListView* list)
{
list->DeleteAllItems();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
for (int c = 1; c<list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (!col)
{
LOG_ERROR(HLE, "Columns loaded with error!");
return;
}
for (u32 i = 0; i<col->data.size(); ++i)
{
if (list->GetItemCount() <= (int)i)
{
list->InsertItem(i, wxEmptyString);
list->SetItemData(i, i);
}
list->SetItem(i, c, fmt::FromUTF8(col->data[i]));
list->SetItemColumnImage(i, 0, m_icon_indexes[i]);
}
}
}
void ColumnsArr::LoadSave(bool isLoad, const std::string& path, wxListView* list)
{
if (isLoad)
{
Init();
}
else if (list)
{
for (int c = 0; c < list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (col)
col->width = list->GetColumnWidth(c);
}
}
auto&& cfg = g_gui_cfg["GameViewer"];
for (auto& column : m_columns)
{
auto&& c_cfg = cfg[column.name];
if (isLoad)
{
std::tie(column.pos, column.width) = c_cfg.as<std::pair<u32, u32>>(std::make_pair(column.def_pos, column.def_width));
column.shown = true;
}
else //if (column.shown)
{
c_cfg = std::make_pair(column.pos, column.width);
}
}
if (isLoad)
{
//check for errors
for (u32 c1 = 0; c1 < m_columns.size(); ++c1)
{
for (u32 c2 = c1 + 1; c2 < m_columns.size(); ++c2)
{
if (m_columns[c1].pos == m_columns[c2].pos)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
for (u32 p = 0; p < m_columns.size(); ++p)
{
bool ishas = false;
for (u32 c = 0; c < m_columns.size(); ++c)
{
if (m_columns[c].pos != p)
continue;
ishas = true;
break;
}
if (!ishas)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
else
{
save_gui_cfg();
}
}

View File

@ -1,7 +1,6 @@
#pragma once
#include "Emu/GameInfo.h"
#include "Emu/state.h"
struct Column
{
@ -31,42 +30,11 @@ struct ColumnsArr
{
std::vector<Column> m_columns;
ColumnsArr()
{
Init();
}
ColumnsArr();
std::vector<Column*> GetSortedColumnsByPos()
{
std::vector<Column*> arr;
for(u32 pos=0; pos<m_columns.size(); pos++)
{
for(u32 c=0; c<m_columns.size(); ++c)
{
if(m_columns[c].pos != pos) continue;
arr.push_back(&m_columns[c]);
}
}
std::vector<Column*> GetSortedColumnsByPos();
return arr;
}
Column* GetColumnByPos(u32 pos)
{
std::vector<Column *> columns = GetSortedColumnsByPos();
for(u32 c=0; c<columns.size(); ++c)
{
if(!columns[c]->shown)
{
pos++;
continue;
}
if(columns[c]->pos != pos) continue;
return columns[c];
}
return NULL;
}
Column* GetColumnByPos(u32 pos);
public:
Column* m_col_icon;
@ -80,181 +48,15 @@ public:
wxImageList* m_img_list;
std::vector<int> m_icon_indexes;
void Init()
{
m_img_list = new wxImageList(80, 44);
void Init();
m_columns.clear();
m_columns.emplace_back(m_columns.size(), 90, "Icon");
m_columns.emplace_back(m_columns.size(), 160, "Name");
m_columns.emplace_back(m_columns.size(), 85, "Serial");
m_columns.emplace_back(m_columns.size(), 55, "FW");
m_columns.emplace_back(m_columns.size(), 55, "App version");
m_columns.emplace_back(m_columns.size(), 75, "Category");
m_columns.emplace_back(m_columns.size(), 160, "Path");
m_col_icon = &m_columns[0];
m_col_name = &m_columns[1];
m_col_serial = &m_columns[2];
m_col_fw = &m_columns[3];
m_col_app_ver = &m_columns[4];
m_col_category = &m_columns[5];
m_col_path = &m_columns[6];
}
void Update(const std::vector<GameInfo>& game_data);
void Update(const std::vector<GameInfo>& game_data)
{
m_col_icon->data.clear();
m_col_name->data.clear();
m_col_serial->data.clear();
m_col_fw->data.clear();
m_col_app_ver->data.clear();
m_col_category->data.clear();
m_col_path->data.clear();
m_icon_indexes.clear();
void Show(wxListView* list);
if(m_columns.size() == 0) return;
void ShowData(wxListView* list);
for(const auto& game : game_data)
{
m_col_icon->data.push_back(game.icon_path);
m_col_name->data.push_back(game.name);
m_col_serial->data.push_back(game.serial);
m_col_fw->data.push_back(game.fw);
m_col_app_ver->data.push_back(game.app_ver);
m_col_category->data.push_back(game.category);
m_col_path->data.push_back(game.root);
}
// load icons
for (const auto& path : m_col_icon->data)
{
wxImage game_icon(80, 44);
{
wxLogNull logNo; // temporary disable wx warnings ("iCCP: known incorrect sRGB profile" spamming)
if (game_icon.LoadFile(fmt::FromUTF8(path), wxBITMAP_TYPE_PNG))
game_icon.Rescale(80, 44, wxIMAGE_QUALITY_HIGH);
}
m_icon_indexes.push_back(m_img_list->Add(game_icon));
}
}
void Show(wxListView* list)
{
list->DeleteAllColumns();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
std::vector<Column *> c_col = GetSortedColumnsByPos();
for(u32 i=0, c=0; i<c_col.size(); ++i)
{
if(!c_col[i]->shown) continue;
list->InsertColumn(c++, fmt::FromUTF8(c_col[i]->name), 0, c_col[i]->width);
}
}
void ShowData(wxListView* list)
{
list->DeleteAllItems();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
for(int c=1; c<list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if(!col)
{
LOG_ERROR(HLE, "Columns loaded with error!");
return;
}
for(u32 i=0; i<col->data.size(); ++i)
{
if (list->GetItemCount() <= (int)i)
{
list->InsertItem(i, wxEmptyString);
list->SetItemData(i, i);
}
list->SetItem(i, c, fmt::FromUTF8(col->data[i]));
list->SetItemColumnImage(i, 0, m_icon_indexes[i]);
}
}
}
void LoadSave(bool isLoad, const std::string& path, wxListView* list = NULL)
{
if (isLoad)
Init();
else if (list)
{
for (int c = 0; c < list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (col)
col->width = list->GetColumnWidth(c);
}
}
auto add_column = [isLoad](Column& column, bool is_shown)
{
if (isLoad)
{
column.pos = rpcs3::config.game_viewer.get_entry_value<u32>(column.name + "_" + "position", column.def_pos);
column.width = rpcs3::config.game_viewer.get_entry_value<u32>(column.name + "_" + "width", column.def_width);
column.shown = rpcs3::config.game_viewer.get_entry_value<bool>(column.name + "_" + "shown", column.shown);
}
else if (is_shown ? column.shown : 1)
{
rpcs3::config.game_viewer.set_entry_value(column.name + "_" + "position", column.pos);
rpcs3::config.game_viewer.set_entry_value(column.name + "_" + "width", column.width);
rpcs3::config.game_viewer.set_entry_value(column.name + "_" + "shown", column.shown);
rpcs3::config.save();
}
};
for (auto& column : m_columns)
{
add_column(column, true);
}
if (isLoad)
{
//check for errors
for (u32 c1 = 0; c1 < m_columns.size(); ++c1)
{
for (u32 c2 = c1 + 1; c2 < m_columns.size(); ++c2)
{
if (m_columns[c1].pos == m_columns[c2].pos)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
for (u32 p = 0; p < m_columns.size(); ++p)
{
bool ishas = false;
for (u32 c = 0; c < m_columns.size(); ++c)
{
if (m_columns[c].pos != p)
continue;
ishas = true;
break;
}
if (!ishas)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
#undef ADD_COLUMN
}
void LoadSave(bool isLoad, const std::string& path, wxListView* list = NULL);
};
class GameViewer : public wxListView

View File

@ -0,0 +1,97 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/Memory/Memory.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Emu/Cell/SPUThread.h"
#include "InstructionEditor.h"
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
, pc(_pc)
, cpu(_cpu)
, disasm(_disasm)
{
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Address: ");
wxStaticText* t1_addr = new wxStaticText(this, wxID_ANY, wxString::Format("%08x", pc));
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Instruction:");
t2_instr = new wxTextCtrl(this, wxID_ANY);
wxStaticText* t3_text = new wxStaticText(this, wxID_ANY, "Preview: ");
t3_preview = new wxStaticText(this, wxID_ANY, "");
s_t1_panel->Add(t1_text);
s_t1_panel->AddSpacer(8);
s_t1_panel->Add(t1_addr);
s_t2_panel->Add(t2_text);
s_t2_panel->AddSpacer(8);
s_t2_panel->Add(t2_instr);
s_t3_panel->Add(t3_text);
s_t3_panel->AddSpacer(8);
s_t3_panel->Add(t3_preview);
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
s_b_panel->AddSpacer(5);
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxRIGHT, 0, 5);
s_panel->Add(s_t1_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t3_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t2_panel);
s_panel->AddSpacer(16);
s_panel->Add(s_b_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_y->Add(s_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_x->AddSpacer(12);
s_panel_margin_x->Add(s_panel_margin_y);
s_panel_margin_x->AddSpacer(12);
const u32 cpu_offset = cpu->type == cpu_type::spu ? static_cast<SPUThread&>(*cpu).offset : 0;
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
t2_instr->SetValue(wxString::Format("%08x", vm::ps3::read32(cpu_offset + pc).value()));
this->SetSizerAndFit(s_panel_margin_x);
if (this->ShowModal() == wxID_OK)
{
ulong opcode;
if (!t2_instr->GetValue().ToULong(&opcode, 16))
wxMessageBox("This instruction could not be parsed.\nNo changes were made.", "Error");
else
vm::ps3::write32(cpu_offset + pc, (u32)opcode);
}
}
void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
{
ulong opcode;
if (t2_instr->GetValue().ToULong(&opcode, 16))
{
if (cpu->type == cpu_type::arm)
{
t3_preview->SetLabel("Preview for ARMv7Thread not implemented yet.");
}
else
{
t3_preview->SetLabel("Preview disabled.");
}
}
else
{
t3_preview->SetLabel("Could not parse instruction.");
}
}

View File

@ -1,112 +1,17 @@
#pragma once
class InstructionEditorDialog
: public wxDialog
class InstructionEditorDialog : public wxDialog
{
u64 pc;
u32 pc;
CPUDisAsm* disasm;
CPUDecoder* decoder;
wxTextCtrl* t2_instr;
wxStaticText* t3_preview;
public:
CPUThread* CPU;
cpu_thread* cpu;
public:
InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm);
InstructionEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm);
void updatePreview(wxCommandEvent& event);
};
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
, pc(_pc)
, CPU(_CPU)
, decoder(_decoder)
, disasm(_disasm)
{
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Address: ");
wxStaticText* t1_addr = new wxStaticText(this, wxID_ANY, wxString::Format("%08x",pc));
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Instruction:");
t2_instr = new wxTextCtrl(this, wxID_ANY);
wxStaticText* t3_text = new wxStaticText(this, wxID_ANY, "Preview: ");
t3_preview = new wxStaticText(this, wxID_ANY, "");
s_t1_panel->Add(t1_text);
s_t1_panel->AddSpacer(8);
s_t1_panel->Add(t1_addr);
s_t2_panel->Add(t2_text);
s_t2_panel->AddSpacer(8);
s_t2_panel->Add(t2_instr);
s_t3_panel->Add(t3_text);
s_t3_panel->AddSpacer(8);
s_t3_panel->Add(t3_preview);
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
s_b_panel->AddSpacer(5);
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxRIGHT, 0, 5);
s_panel->Add(s_t1_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t3_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t2_panel);
s_panel->AddSpacer(16);
s_panel->Add(s_b_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_y->Add(s_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_x->AddSpacer(12);
s_panel_margin_x->Add(s_panel_margin_y);
s_panel_margin_x->AddSpacer(12);
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
t2_instr->SetValue(wxString::Format("%08x", vm::ps3::read32(CPU->get_offset() + pc).value()));
this->SetSizerAndFit(s_panel_margin_x);
if(this->ShowModal() == wxID_OK)
{
unsigned long opcode;
if (!t2_instr->GetValue().ToULong(&opcode, 16))
wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error");
else
vm::ps3::write32(CPU->get_offset() + pc, (u32)opcode);
}
}
void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
{
unsigned long opcode;
if (t2_instr->GetValue().ToULong(&opcode, 16))
{
if(CPU->get_type() == CPU_THREAD_ARMv7)
{
t3_preview->SetLabel("Preview for ARMv7Thread not implemented yet.");
}
else
{
disasm->dump_pc = pc;
((PPCDecoder*)decoder)->Decode((u32)opcode);
wxString preview = fmt::FromUTF8(disasm->last_opcode);
preview.Remove(0, preview.Find(':') + 1);
t3_preview->SetLabel(preview);
}
}
else
{
t3_preview->SetLabel("Could not parse instruction.");
}
}

View File

@ -4,29 +4,43 @@
#include "Emu/System.h"
#include "rpcs3.h"
#include "InterpreterDisAsm.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUDecoder.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/SPUDisAsm.h"
#include "Emu/ARMv7/ARMv7DisAsm.h"
#include "Emu/ARMv7/ARMv7Decoder.h"
#include "InstructionEditor.h"
#include "RegisterEditor.h"
//static const int show_lines = 30;
#include <map>
std::map<u32, bool> g_breakpoints;
u64 InterpreterDisAsmFrame::CentrePc(const u64 pc) const
u32 InterpreterDisAsmFrame::GetPc() const
{
switch (cpu->type)
{
case cpu_type::ppu: return static_cast<PPUThread*>(cpu)->PC;
case cpu_type::spu: return static_cast<SPUThread*>(cpu)->pc;
case cpu_type::arm: return static_cast<ARMv7Thread*>(cpu)->PC;
}
return 0xabadcafe;
}
u32 InterpreterDisAsmFrame::CentrePc(u32 pc) const
{
return pc/* - ((m_item_count / 2) * 4)*/;
}
InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(500, 700), wxTAB_TRAVERSAL)
, PC(0)
, CPU(nullptr)
, m_pc(0)
, cpu(nullptr)
, m_item_count(30)
, disasm(nullptr)
{
wxBoxSizer* s_p_main = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_b_main = new wxBoxSizer(wxHORIZONTAL);
@ -94,7 +108,7 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
Bind(wxEVT_KEY_DOWN, &InterpreterDisAsmFrame::OnKeyDown, this);
wxGetApp().Bind(wxEVT_DBG_COMMAND, &InterpreterDisAsmFrame::HandleCommand, this);
ShowAddr(CentrePc(PC));
ShowAddr(CentrePc(m_pc));
UpdateUnitList();
}
@ -107,9 +121,9 @@ void InterpreterDisAsmFrame::UpdateUnitList()
m_choice_units->Freeze();
m_choice_units->Clear();
for (auto& t : Emu.GetCPU().GetAllThreads())
for (auto& t : get_all_cpu_threads())
{
m_choice_units->Append(t->GetFName(), t.get());
m_choice_units->Append(t->get_name(), t.get());
}
m_choice_units->Thaw();
@ -117,58 +131,30 @@ void InterpreterDisAsmFrame::UpdateUnitList()
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
{
CPU = (CPUThread*)event.GetClientData();
m_disasm.reset();
decoder.reset();
disasm = nullptr;
class SPUDecoder : public CPUDecoder
if (cpu = (cpu_thread*)event.GetClientData())
{
std::unique_ptr<SPUDisAsm> disasm;
public:
SPUDecoder(SPUDisAsm* disasm)
: disasm(disasm)
switch (cpu->type)
{
}
virtual u32 DecodeMemory(const u32 address) override
case cpu_type::ppu:
{
disasm->do_disasm(vm::ps3::read32(address));
return 4;
}
};
if(CPU)
{
switch(CPU->get_type())
{
case CPU_THREAD_PPU:
{
PPUDisAsm* dis_asm = new PPUDisAsm(CPUDisAsm_InterpreterMode);
decoder = std::make_unique<PPUDecoder>(dis_asm);
disasm = dis_asm;
}
m_disasm = std::make_unique<PPUDisAsm>(CPUDisAsm_InterpreterMode);
break;
case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU:
{
SPUDisAsm* dis_asm = new SPUDisAsm(CPUDisAsm_InterpreterMode);
decoder = std::make_unique<SPUDecoder>(dis_asm);
disasm = dis_asm;
}
break;
case CPU_THREAD_ARMv7:
case cpu_type::spu:
{
//ARMv7DisAsm& dis_asm = *new ARMv7DisAsm(CPUDisAsm_InterpreterMode);
//decoder = new ARMv7Decoder(dis_asm);
//disasm = &dis_asm;
}
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
break;
}
case cpu_type::arm:
{
m_disasm = std::make_unique<ARMv7DisAsm>(CPUDisAsm_InterpreterMode);
break;
}
}
}
DoUpdate();
@ -195,10 +181,10 @@ void InterpreterDisAsmFrame::OnKeyDown(wxKeyEvent& event)
{
switch (event.GetKeyCode())
{
case WXK_PAGEUP: ShowAddr( PC - (m_item_count * 2) * 4 ); return;
case WXK_PAGEDOWN: ShowAddr( PC ); return;
case WXK_UP: ShowAddr( PC - (m_item_count + 1) * 4 ); return;
case WXK_DOWN: ShowAddr( PC - (m_item_count - 1) * 4 ); return;
case WXK_PAGEUP: ShowAddr(m_pc - (m_item_count * 2) * 4); return;
case WXK_PAGEDOWN: ShowAddr(m_pc); return;
case WXK_UP: ShowAddr(m_pc - (m_item_count + 1) * 4); return;
case WXK_DOWN: ShowAddr(m_pc - (m_item_count - 1) * 4); return;
}
}
@ -235,7 +221,7 @@ void InterpreterDisAsmFrame::OnResize(wxSizeEvent& event)
}
m_item_count = item;
ShowAddr(PC);
ShowAddr(m_pc);
}
}
@ -247,107 +233,71 @@ void InterpreterDisAsmFrame::DoUpdate()
WriteCallStack();
}
void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
void InterpreterDisAsmFrame::ShowAddr(u32 addr)
{
PC = addr;
m_pc = addr;
m_list->Freeze();
if(!CPU)
if (!cpu)
{
for(uint i=0; i<m_item_count; ++i, PC += 4)
for (uint i = 0; i<m_item_count; ++i, m_pc += 4)
{
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
m_list->SetItem(i, 0, wxString::Format("[%08x] illegal address", m_pc));
}
}
else
{
disasm->offset = (u8*)vm::base(CPU->get_offset());
for(uint i=0, count = 4; i<m_item_count; ++i, PC += count)
const u32 cpu_offset = cpu->type == cpu_type::spu ? static_cast<SPUThread&>(*cpu).offset : 0;
m_disasm->offset = (u8*)vm::base(cpu_offset);
for (uint i = 0, count = 4; i<m_item_count; ++i, m_pc += count)
{
if(!vm::check_addr(CPU->get_offset() + PC, 4))
if (!vm::check_addr(cpu_offset + m_pc, 4))
{
m_list->SetItem(i, 0, wxString(IsBreakPoint(PC) ? ">>> " : " ") + wxString::Format("[%08llx] illegal address", PC));
m_list->SetItem(i, 0, wxString(IsBreakPoint(m_pc) ? ">>> " : " ") + wxString::Format("[%08x] illegal address", m_pc));
count = 4;
continue;
}
disasm->dump_pc = PC;
count = decoder->DecodeMemory(CPU->get_offset() + PC);
count = m_disasm->disasm(m_disasm->dump_pc = m_pc);
if(IsBreakPoint(PC))
{
m_list->SetItem(i, 0, fmt::FromUTF8(">>> " + disasm->last_opcode));
}
else
{
m_list->SetItem(i, 0, fmt::FromUTF8(" " + disasm->last_opcode));
}
m_list->SetItem(i, 0, wxString(IsBreakPoint(m_pc) ? ">>> " : " ") + fmt::FromUTF8(m_disasm->last_opcode));
wxColour colour;
if(CPU->is_paused() && PC == CPU->get_pc())
if (cpu->state.test(cpu_state_pause) && m_pc == GetPc())
{
colour = wxColour("Green");
}
else
{
colour = wxColour("White");
for(u32 i=0; i<Emu.GetMarkedPoints().size(); ++i)
{
if(Emu.GetMarkedPoints()[i] == PC)
{
colour = wxColour("Wheat");
break;
}
}
colour = wxColour(IsBreakPoint(m_pc) ? "Wheat" : "White");
}
m_list->SetItemBackgroundColour(i, colour);
}
}
while(remove_markedPC.size())
{
u32 mpc = remove_markedPC[0];
for(u32 i=0; i<remove_markedPC.size(); ++i)
{
if(remove_markedPC[i] == mpc)
{
remove_markedPC.erase( remove_markedPC.begin() + i--);
continue;
}
if(remove_markedPC[i] > mpc) remove_markedPC[i]--;
}
Emu.GetMarkedPoints().erase(Emu.GetMarkedPoints().begin() + mpc);
}
m_list->SetColumnWidth(0, -1);
m_list->Thaw();
}
void InterpreterDisAsmFrame::WriteRegs()
{
if(!CPU)
if (!cpu)
{
m_regs->Clear();
return;
}
const std::string data = CPU->RegsToString();
m_regs->Freeze();
m_regs->Clear();
m_regs->WriteText(fmt::FromUTF8(data));
m_regs->WriteText(fmt::FromUTF8(cpu->dump()));
m_regs->Thaw();
}
void InterpreterDisAsmFrame::WriteCallStack()
{
if(!CPU)
if (!cpu)
{
m_calls->Clear();
return;
@ -361,7 +311,7 @@ void InterpreterDisAsmFrame::WriteCallStack()
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
{
CPUThread* thr = (CPUThread*)event.GetClientData();
cpu_thread* thr = (cpu_thread*)event.GetClientData();
event.Skip();
if (!thr)
@ -377,7 +327,7 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
break;
}
}
else if(CPU && thr->get_id() == CPU->get_id())
else if (cpu && thr == cpu)
{
switch (event.GetId())
{
@ -467,73 +417,80 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
diag->SetSizerAndFit(s_panel);
if(CPU) p_pc->SetValue(wxString::Format("%x", CPU->get_pc()));
if (cpu) p_pc->SetValue(wxString::Format("%x", GetPc()));
if (diag->ShowModal() == wxID_OK)
{
unsigned long pc = CPU ? CPU->get_pc() : 0x0;
unsigned long pc = cpu ? GetPc() : 0x0;
p_pc->GetValue().ToULong(&pc, 16);
Emu.GetMarkedPoints().push_back(pc);
remove_markedPC.push_back(Emu.GetMarkedPoints().size()-1);
ShowAddr(CentrePc(pc));
}
}
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event))
{
if(CPU) ShowAddr(CentrePc(CPU->get_pc()));
if (cpu) ShowAddr(CentrePc(GetPc()));
}
void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
{
if(!CPU) return;
if(CPU->is_paused()) CPU->resume();
if(!Emu.IsPaused())
if (cpu && cpu->state.test(cpu_state_pause))
{
CPU->exec();
cpu->state -= cpu_state::dbg_pause;
cpu->safe_notify();
}
//ThreadBase::Start();
}
void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
{
//DoUpdate();
if(CPU) CPU->pause();
if (cpu)
{
cpu->state += cpu_state::dbg_pause;
}
}
void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
{
if(CPU) CPU->step();
if (cpu)
{
if (cpu->state.atomic_op([](mset<cpu_state>& state) -> bool
{
state += cpu_state::dbg_step;
return state.test_and_reset(cpu_state::dbg_pause);
}))
{
cpu->safe_notify();
}
}
}
void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
{
long i = m_list->GetFirstSelected();
if(i < 0 || !CPU)
if (i < 0 || !cpu)
{
event.Skip();
return;
}
const u64 start_pc = PC - m_item_count*4;
const u64 pc = start_pc + i*4;
const u32 start_pc = m_pc - m_item_count * 4;
const u32 pc = start_pc + i * 4;
switch (event.GetKeyCode())
{
case 'E':
// TODO:: Syphurith: It is said the InstructionEditorDialog would be immediately destroyed.
InstructionEditorDialog(this, pc, CPU, decoder.get(), disasm);
{
InstructionEditorDialog dlg(this, pc, cpu, m_disasm.get());
DoUpdate();
return;
}
case 'R':
// TODO:: Syphurith: Eh Similiar for this one.
RegisterEditorDialog(this, pc, CPU, decoder.get(), disasm);
{
RegisterEditorDialog dlg(this, pc, cpu, m_disasm.get());
DoUpdate();
return;
}
}
event.Skip();
}
@ -543,8 +500,8 @@ void InterpreterDisAsmFrame::DClick(wxListEvent& event)
long i = m_list->GetFirstSelected();
if (i < 0) return;
const u64 start_pc = PC - m_item_count*4;
const u64 pc = start_pc + i*4;
const u32 start_pc = m_pc - m_item_count * 4;
const u32 pc = start_pc + i * 4;
//ConLog.Write("pc=0x%llx", pc);
if (IsBreakPoint(pc))
@ -563,39 +520,22 @@ void InterpreterDisAsmFrame::MouseWheel(wxMouseEvent& event)
{
const int value = (event.m_wheelRotation / event.m_wheelDelta);
ShowAddr( PC - (event.ControlDown() ? m_item_count * (value + 1) : m_item_count + value) * 4);
ShowAddr(m_pc - (event.ControlDown() ? m_item_count * (value + 1) : m_item_count + value) * 4);
event.Skip();
}
bool InterpreterDisAsmFrame::IsBreakPoint(u64 pc)
bool InterpreterDisAsmFrame::IsBreakPoint(u32 pc)
{
for(u32 i=0; i<Emu.GetBreakPoints().size(); ++i)
{
if(Emu.GetBreakPoints()[i] == pc) return true;
return g_breakpoints.count(pc) != 0;
}
return false;
void InterpreterDisAsmFrame::AddBreakPoint(u32 pc)
{
g_breakpoints.emplace(pc, false);
}
void InterpreterDisAsmFrame::AddBreakPoint(u64 pc)
bool InterpreterDisAsmFrame::RemoveBreakPoint(u32 pc)
{
for(u32 i=0; i<Emu.GetBreakPoints().size(); ++i)
{
if(Emu.GetBreakPoints()[i] == pc) return;
}
Emu.GetBreakPoints().push_back(pc);
}
bool InterpreterDisAsmFrame::RemoveBreakPoint(u64 pc)
{
for(u32 i=0; i<Emu.GetBreakPoints().size(); ++i)
{
if(Emu.GetBreakPoints()[i] != pc) continue;
Emu.GetBreakPoints().erase(Emu.GetBreakPoints().begin() + i);
return true;
}
return false;
return g_breakpoints.erase(pc) != 0;
}

View File

@ -1,15 +1,13 @@
#pragma once
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDecoder.h"
#include "Emu/CPU/CPUDisAsm.h"
class InterpreterDisAsmFrame : public wxPanel
{
wxListView* m_list;
CPUDisAsm* disasm;
std::unique_ptr<CPUDecoder> decoder;
u64 PC;
std::vector<u32> remove_markedPC;
std::unique_ptr<CPUDisAsm> m_disasm;
u32 m_pc;
wxTextCtrl* m_regs;
wxTextCtrl* m_calls;
wxButton* m_btn_step;
@ -19,7 +17,7 @@ class InterpreterDisAsmFrame : public wxPanel
wxChoice* m_choice_units;
public:
CPUThread* CPU;
cpu_thread* cpu;
public:
InterpreterDisAsmFrame(wxWindow* parent);
@ -27,12 +25,13 @@ public:
void UpdateUnitList();
u64 CentrePc(const u64 pc) const;
u32 GetPc() const;
u32 CentrePc(u32 pc) const;
void OnSelectUnit(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnResize(wxSizeEvent& event);
void DoUpdate();
void ShowAddr(const u64 addr);
void ShowAddr(u32 addr);
void WriteRegs();
void WriteCallStack();
@ -47,7 +46,7 @@ public:
void DClick(wxListEvent& event);
void MouseWheel(wxMouseEvent& event);
bool IsBreakPoint(u64 pc);
void AddBreakPoint(u64 pc);
bool RemoveBreakPoint(u64 pc);
bool IsBreakPoint(u32 pc);
void AddBreakPoint(u32 pc);
bool RemoveBreakPoint(u32 pc);
};

View File

@ -7,18 +7,18 @@
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
#include "Emu/SysCalls/lv2/sys_lwcond.h"
#include "Emu/SysCalls/lv2/sys_mutex.h"
#include "Emu/SysCalls/lv2/sys_cond.h"
#include "Emu/SysCalls/lv2/sys_semaphore.h"
#include "Emu/SysCalls/lv2/sys_event.h"
#include "Emu/SysCalls/lv2/sys_event_flag.h"
#include "Emu/SysCalls/lv2/sys_rwlock.h"
#include "Emu/SysCalls/lv2/sys_prx.h"
#include "Emu/SysCalls/lv2/sys_memory.h"
#include "Emu/SysCalls/lv2/sys_mmapper.h"
#include "Emu/SysCalls/lv2/sys_spu.h"
#include "Emu/Cell/lv2/sys_lwmutex.h"
#include "Emu/Cell/lv2/sys_lwcond.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_cond.h"
#include "Emu/Cell/lv2/sys_semaphore.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_event_flag.h"
#include "Emu/Cell/lv2/sys_rwlock.h"
#include "Emu/Cell/lv2/sys_prx.h"
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_spu.h"
#include "KernelExplorer.h"
@ -171,7 +171,7 @@ void KernelExplorer::Update()
const auto& eq = *data.second;
m_tree->AppendItem(node, fmt::format("Event Queue: ID = 0x%08x '%s', %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", data.first,
&name64(eq.name), eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.key, eq.events.size(), eq.size, eq.sq.size()));
&name64(eq.name), eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.ipc_key, eq.events(), eq.size, eq.waiters()));
}
}
@ -202,7 +202,7 @@ void KernelExplorer::Update()
{
const auto& ef = *data.second;
m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x", data.first));
m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x '%s', Type = 0x%x, Pattern = 0x%llx", data.first, &name64(ef.name), ef.type, ef.pattern.load()));
}
}
@ -277,8 +277,7 @@ void KernelExplorer::Update()
{
const auto& ppu = *data.second;
m_tree->AppendItem(node, fmt::format("PPU Thread: ID = 0x%08x '%s', - %s", data.first,
ppu.get_name().c_str(), ppu.ThreadStatusToString()));
m_tree->AppendItem(node, fmt::format("PPU Thread: ID = 0x%08x '%s'", data.first, ppu.get_name()));
}
}

View File

@ -1,112 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Loader/ELF64.h"
#include "Emu/FS/vfsDir.h"
#include "Emu/FS/vfsFile.h"
#include "LLEModulesManager.h"
#include "Emu/System.h"
#include "Emu/state.h"
#include "Emu/FS/VFS.h"
LLEModulesManagerFrame::LLEModulesManagerFrame(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "LLEModulesManagerFrame", wxDefaultPosition, wxSize(480, 640))
{
wxBoxSizer *s_panel = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *s_p_panel = new wxBoxSizer(wxVERTICAL);
wxPanel *p_main = new wxPanel(this);
m_check_list = new wxCheckListBox(p_main, wxID_ANY);
// select / unselect
wxStaticBoxSizer* s_selection = new wxStaticBoxSizer(wxHORIZONTAL, p_main);
wxButton* b_select = new wxButton(p_main, wxID_ANY, "Select All", wxDefaultPosition, wxSize(80, -1));
wxButton* b_unselect = new wxButton(p_main, wxID_ANY, "Unselect All", wxDefaultPosition, wxSize(80, -1));
s_selection->Add(b_select);
s_selection->Add(b_unselect);
s_p_panel->Add(s_selection);
s_p_panel->Add(m_check_list, 1, wxEXPAND | wxALL, 5);
p_main->SetSizerAndFit(s_p_panel);
s_panel->Add(p_main, 1, wxEXPAND | wxALL, 5);
SetSizerAndFit(s_panel);
Refresh();
SetSize(350, 500);
b_select->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { OnSelectAll(event, true); event.Skip(); });
b_unselect->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { OnSelectAll(event, false); event.Skip(); });
Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent& event) { UpdateSelection(event.GetInt()); event.Skip(); });
Bind(wxEVT_SIZE, [p_main, this](wxSizeEvent& event) { p_main->SetSize(GetClientSize()); m_check_list->SetSize(p_main->GetClientSize() - wxSize(10, 50)); event.Skip(); });
}
void LLEModulesManagerFrame::Refresh()
{
m_check_list->Clear();
m_funcs.clear();
std::string path = "/dev_flash/sys/external/";
Emu.GetVFS().Init(path);
loader::handlers::elf64 sprx_loader;
for (const auto info : vfsDir(path))
{
if (info->flags & DirEntry_TypeFile)
{
vfsFile f(path + info->name);
if (sprx_loader.init(f) != loader::handler::ok)
{
continue;
}
if (!sprx_loader.is_sprx())
{
continue;
}
//loader::handlers::elf64::sprx_info info;
//sprx_loader.load_sprx(info);
std::string name = sprx_loader.sprx_get_module_name();
bool is_skip = false;
for (auto &i : m_funcs)
{
if (i == name)
{
is_skip = true;
break;
}
}
if (is_skip)
continue;
m_funcs.push_back(name);
m_check_list->Check(m_check_list->Append(name +
" v" + std::to_string((int)sprx_loader.m_sprx_module_info.version[0]) +
"." + std::to_string((int)sprx_loader.m_sprx_module_info.version[1])),
rpcs3::config.lle.get_entry_value<bool>(name, false));
}
}
Emu.GetVFS().UnMountAll();
}
void LLEModulesManagerFrame::UpdateSelection(int index)
{
if (index < 0)
return;
rpcs3::config.lle.set_entry_value(m_funcs[index], m_check_list->IsChecked(index));
}
void LLEModulesManagerFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event), bool is_checked)
{
for (uint i = 0; i < m_check_list->GetCount(); i++)
{
m_check_list->Check(i, is_checked);
UpdateSelection(i);
}
}

View File

@ -1,15 +0,0 @@
#pragma once
#include "Gui/FrameBase.h"
class LLEModulesManagerFrame : public wxDialog
{
wxCheckListBox *m_check_list;
std::vector<std::string> m_funcs;
public:
LLEModulesManagerFrame(wxWindow *parent);
void Refresh();
void UpdateSelection(int index);
void OnSelectAll(wxCommandEvent& WXUNUSED(event), bool is_checked);
};

View File

@ -1,19 +1,14 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "rpcs3.h"
#include "config.h"
#include "MainFrame.h"
#include "git-version.h"
#include "Emu/Memory/Memory.h"
#include "Emu/SysCalls/Modules/cellSysutil.h"
#include "Emu/System.h"
#include "Gui/PADManager.h"
#include "Gui/VHDDManager.h"
#include "Gui/VFSManager.h"
#include "Gui/AboutDialog.h"
#include "Gui/GameViewer.h"
#include "Gui/CompilerELF.h"
#include "Gui/AutoPauseManager.h"
#include "Gui/SaveDataUtility.h"
#include "Gui/KernelExplorer.h"
@ -21,10 +16,11 @@
#include "Gui/RSXDebugger.h"
#include "Gui/SettingsDialog.h"
#include "Gui/MemoryStringSearcher.h"
#include "Gui/LLEModulesManager.h"
#include "Gui/CgDisasm.h"
#include "Crypto/unpkg.h"
#include <future>
#ifndef _WIN32
#include "frame_icon.xpm"
#endif
@ -49,7 +45,6 @@ enum IDs
id_config_vhdd_manager,
id_config_autopause_manager,
id_config_savedata_manager,
id_config_lle_modules_manager,
id_tools_compiler,
id_tools_kernel_explorer,
id_tools_memory_viewer,
@ -72,7 +67,7 @@ MainFrame::MainFrame()
, m_sys_menu_opened(false)
{
SetLabel(wxString::Format(_PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION));
SetLabel(_PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION);
wxMenuBar* menubar = new wxMenuBar();
@ -99,21 +94,19 @@ MainFrame::MainFrame()
menu_conf->Append(id_config_pad, "&PAD Settings");
menu_conf->AppendSeparator();
menu_conf->Append(id_config_autopause_manager, "&Auto Pause Settings");
menu_conf->AppendSeparator();
menu_conf->Append(id_config_vfs_manager, "Virtual &File System Manager");
menu_conf->Append(id_config_vhdd_manager, "Virtual &HDD Manager");
menu_conf->Append(id_config_savedata_manager, "Save &Data Utility");
menu_conf->Append(id_config_lle_modules_manager, "&LLE Modules Manager");
//menu_conf->AppendSeparator();
//menu_conf->Append(id_config_vfs_manager, "Virtual &File System Manager");
//menu_conf->Append(id_config_vhdd_manager, "Virtual &HDD Manager");
//menu_conf->Append(id_config_savedata_manager, "Save &Data Utility");
wxMenu* menu_tools = new wxMenu();
menubar->Append(menu_tools, "&Tools");
menu_tools->Append(id_tools_compiler, "&ELF Compiler");
//menu_tools->Append(id_tools_compiler, "&ELF Compiler");
menu_tools->Append(id_tools_cg_disasm, "&Cg Disasm")->Enable();
menu_tools->Append(id_tools_kernel_explorer, "&Kernel Explorer")->Enable(false);
menu_tools->Append(id_tools_memory_viewer, "&Memory Viewer")->Enable(false);
menu_tools->Append(id_tools_rsx_debugger, "&RSX Debugger")->Enable(false);
menu_tools->Append(id_tools_string_search, "&String Search")->Enable(false);
menu_tools->Append(id_tools_cg_disasm, "&Cg Disasm")->Enable();
wxMenu* menu_help = new wxMenu();
menubar->Append(menu_help, "&Help");
@ -144,11 +137,10 @@ MainFrame::MainFrame()
Bind(wxEVT_MENU, &MainFrame::Config, this, id_config_emu);
Bind(wxEVT_MENU, &MainFrame::ConfigPad, this, id_config_pad);
Bind(wxEVT_MENU, &MainFrame::ConfigAutoPause, this, id_config_autopause_manager);
Bind(wxEVT_MENU, &MainFrame::ConfigVFS, this, id_config_vfs_manager);
Bind(wxEVT_MENU, &MainFrame::ConfigVHDD, this, id_config_vhdd_manager);
Bind(wxEVT_MENU, &MainFrame::ConfigAutoPause, this, id_config_autopause_manager);
Bind(wxEVT_MENU, &MainFrame::ConfigSaveData, this, id_config_savedata_manager);
Bind(wxEVT_MENU, &MainFrame::ConfigLLEModules, this, id_config_lle_modules_manager);
Bind(wxEVT_MENU, &MainFrame::OpenELFCompiler, this, id_tools_compiler);
Bind(wxEVT_MENU, &MainFrame::OpenKernelExplorer, this, id_tools_kernel_explorer);
@ -164,7 +156,7 @@ MainFrame::MainFrame()
wxGetApp().Bind(wxEVT_KEY_DOWN, &MainFrame::OnKeyDown, this);
wxGetApp().Bind(wxEVT_DBG_COMMAND, &MainFrame::UpdateUI, this);
LOG_NOTICE(GENERAL, _PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION);
LOG_NOTICE(GENERAL, "%s", _PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION);
LOG_NOTICE(GENERAL, "");
}
@ -181,18 +173,18 @@ void MainFrame::AddPane(wxWindow* wind, const wxString& caption, int flags)
void MainFrame::DoSettings(bool load)
{
auto&& cfg = g_gui_cfg[ini_name]["aui"];
if (load)
{
// replace all '=' with '~' for ini-manager
if(!rpcs3::config.gui.aui_mgr_perspective.value().size())
rpcs3::config.gui.aui_mgr_perspective = fmt::replace_all(fmt::ToUTF8(m_aui_mgr.SavePerspective()), "=", "~");
const auto& perspective = fmt::FromUTF8(cfg.Scalar());
m_aui_mgr.LoadPerspective(fmt::FromUTF8(fmt::replace_all(rpcs3::config.gui.aui_mgr_perspective.value(), "~", "=")));
m_aui_mgr.LoadPerspective(perspective.empty() ? m_aui_mgr.SavePerspective() : perspective);
}
else
{
rpcs3::config.gui.aui_mgr_perspective = fmt::replace_all(fmt::ToUTF8(m_aui_mgr.SavePerspective()), "=", "~");
rpcs3::config.save();
cfg = fmt::ToUTF8(m_aui_mgr.SavePerspective());
save_gui_cfg();
}
}
@ -216,16 +208,7 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
Emu.Stop();
if(Emu.BootGame(ctrl.GetPath().ToStdString()))
{
LOG_SUCCESS(GENERAL, "Game: boot done.");
if (rpcs3::config.misc.always_start.value())
{
Emu.Run();
}
}
else
if(!Emu.BootGame(ctrl.GetPath().ToStdString()))
{
LOG_ERROR(GENERAL, "PS3 executable not found in selected folder (%s)", fmt::ToUTF8(ctrl.GetPath())); // passing std::string (test)
}
@ -233,37 +216,35 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
{
const bool was_running = Emu.Pause();
const bool paused = Emu.Pause();
wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (ctrl.ShowModal() == wxID_CANCEL)
{
if (was_running) Emu.Resume();
if (paused) Emu.Resume();
return;
}
Emu.Stop();
Emu.GetVFS().Init("/");
std::string local_path;
Emu.GetVFS().GetDevice("/dev_hdd0/game/", local_path);
// Open PKG file
fs::file pkg_f(ctrl.GetPath().ToStdString());
// Open file mapping (test)
fs::file_read_map pkg_ptr(pkg_f);
if (!pkg_f || !pkg_ptr)
if (!pkg_f || pkg_f.size() < 64)
{
LOG_ERROR(LOADER, "PKG: Failed to open %s", ctrl.GetPath().ToStdString());
return;
}
// Append title ID to the path
local_path += '/';
local_path.append(pkg_ptr + 55, 9);
// Get title ID
std::vector<char> title_id(9);
pkg_f.seek(55);
pkg_f.read(title_id);
pkg_f.seek(0);
// Get full path
const auto& local_path = vfs::get("/dev_hdd0/game/") + std::string(std::begin(title_id), std::end(title_id));
if (!fs::create_dir(local_path))
{
@ -343,11 +324,6 @@ void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
Emu.Load();
LOG_SUCCESS(LOADER, "(S)ELF: boot done.");
if (rpcs3::config.misc.always_start.value() && Emu.IsReady())
{
Emu.Run();
}
}
void MainFrame::Pause(wxCommandEvent& WXUNUSED(event))
@ -371,14 +347,17 @@ void MainFrame::Stop(wxCommandEvent& WXUNUSED(event))
Emu.Stop();
}
// This is ugly, but PS3 headers shall not be included there.
extern void sysutilSendSystemCommand(u64 status, u64 param);
void MainFrame::SendExit(wxCommandEvent& event)
{
sysutilSendSystemCommand(CELL_SYSUTIL_REQUEST_EXITGAME, 0);
sysutilSendSystemCommand(0x0101 /* CELL_SYSUTIL_REQUEST_EXITGAME */, 0);
}
void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event)
{
sysutilSendSystemCommand(m_sys_menu_opened ? CELL_SYSUTIL_SYSTEM_MENU_CLOSE : CELL_SYSUTIL_SYSTEM_MENU_OPEN, 0);
sysutilSendSystemCommand(m_sys_menu_opened ? 0x0132 /* CELL_SYSUTIL_SYSTEM_MENU_CLOSE */ : 0x0131 /* CELL_SYSUTIL_SYSTEM_MENU_OPEN */, 0);
m_sys_menu_opened = !m_sys_menu_opened;
wxCommandEvent ce;
UpdateUI(ce);
@ -396,12 +375,12 @@ void MainFrame::ConfigPad(wxCommandEvent& WXUNUSED(event))
void MainFrame::ConfigVFS(wxCommandEvent& WXUNUSED(event))
{
VFSManagerDialog(this).ShowModal();
//VFSManagerDialog(this).ShowModal();
}
void MainFrame::ConfigVHDD(wxCommandEvent& WXUNUSED(event))
{
VHDDManagerDialog(this).ShowModal();
//VHDDManagerDialog(this).ShowModal();
}
void MainFrame::ConfigAutoPause(wxCommandEvent& WXUNUSED(event))
@ -414,14 +393,9 @@ void MainFrame::ConfigSaveData(wxCommandEvent& event)
SaveDataListDialog(this, true).ShowModal();
}
void MainFrame::ConfigLLEModules(wxCommandEvent& event)
{
(new LLEModulesManagerFrame(this))->Show();
}
void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event))
{
(new CompilerELF(this))->Show();
//(new CompilerELF(this))->Show();
}
void MainFrame::OpenKernelExplorer(wxCommandEvent& WXUNUSED(event))
@ -508,14 +482,6 @@ void MainFrame::UpdateUI(wxCommandEvent& event)
default:
return;
}
if (event.GetId() == DID_STOPPED_EMU)
{
if (rpcs3::config.misc.exit_on_stop.value())
{
wxGetApp().Exit();
}
}
}
else
{

View File

@ -38,7 +38,6 @@ private:
void ConfigVHDD(wxCommandEvent& event);
void ConfigAutoPause(wxCommandEvent& event);
void ConfigSaveData(wxCommandEvent& event);
void ConfigLLEModules(wxCommandEvent& event);
void OpenELFCompiler(wxCommandEvent& evt);
void OpenKernelExplorer(wxCommandEvent& evt);
void OpenMemoryViewer(wxCommandEvent& evt);

View File

@ -1,6 +1,5 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Utilities/rPlatform.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"

View File

@ -107,7 +107,7 @@ MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
//Memory Panel: Set size of the wxTextCtrl's
int x, y;
t_mem_hex->GetTextExtent(wxT("T"), &x, &y);
t_mem_hex->GetTextExtent("T", &x, &y);
t_mem_hex->SetMinSize(wxSize(x * 3 * m_colcount + 6, 228));
t_mem_hex->SetMaxSize(wxSize(x * 3 * m_colcount + 6, 228));
t_mem_ascii->SetMinSize(wxSize(x * m_colcount + 6, 228));
@ -155,7 +155,7 @@ void MemoryViewerPanel::OnChangeToolsBytes(wxCommandEvent& event)
m_colcount = sc_bytes->GetValue();
int x, y;
t_mem_hex->GetTextExtent(wxT("T"), &x, &y);
t_mem_hex->GetTextExtent("T", &x, &y);
t_mem_hex->SetMinSize(wxSize(x * 3 * m_colcount + 6, 228));
t_mem_hex->SetMaxSize(wxSize(x * 3 * m_colcount + 6, 228));
t_mem_ascii->SetMinSize(wxSize(x * m_colcount + 6, 228));

View File

@ -4,7 +4,7 @@
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/SysCalls/lv2/sys_time.h"
#include "Emu/Cell/lv2/sys_time.h"
#include "MsgDialog.h"
MsgDialogFrame::~MsgDialogFrame()
@ -72,9 +72,9 @@ void MsgDialogFrame::Create(const std::string& msg)
if (type.button_type.unshifted() == CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO)
{
m_button_yes = new wxButton(m_dialog, wxID_YES);
m_buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8);
m_buttons->Add(m_button_yes, 0, wxRIGHT, 8);
m_button_no = new wxButton(m_dialog, wxID_NO);
m_buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16);
m_buttons->Add(m_button_no, 0, 0, 16);
if (type.default_cursor == 1)
{
@ -91,7 +91,7 @@ void MsgDialogFrame::Create(const std::string& msg)
if (type.button_type.unshifted() == CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK)
{
m_button_ok = new wxButton(m_dialog, wxID_OK);
m_buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16);
m_buttons->Add(m_button_ok, 0, 0, 16);
if (type.default_cursor == 0)
{

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/SysCalls/Modules/cellMsgDialog.h"
#include "Emu/Cell/Modules/cellMsgDialog.h"
class MsgDialogFrame : public MsgDialogBase
{

View File

@ -1,68 +1,64 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/state.h"
#include "rpcs3.h"
#include "KeyboardPadHandler.h"
#include "PADManager.h"
extern KeyboardPadConfig g_kbpad_config;
PADManager::PADManager(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "PAD Settings")
, m_button_id(0)
, m_key_pressed(false)
, m_emu_paused(false)
{
if(Emu.IsRunning())
{
Emu.Pause();
m_emu_paused = true;
}
g_kbpad_config.load();
wxBoxSizer* s_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel2 = new wxBoxSizer(wxVERTICAL);
// Left Analog Stick
wxStaticBoxSizer* s_round_stick_l = new wxStaticBoxSizer(wxVERTICAL, this, _("Left Analog Stick"));
wxStaticBoxSizer* s_round_stick_l = new wxStaticBoxSizer(wxVERTICAL, this, "Left Analog Stick");
wxBoxSizer* s_subpanel_lstick_1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_lstick_2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel_lstick_3 = new wxBoxSizer(wxVERTICAL);
// D-Pad
wxStaticBoxSizer* s_round_pad_controls = new wxStaticBoxSizer(wxVERTICAL, this, _("D-Pad"));
wxStaticBoxSizer* s_round_pad_controls = new wxStaticBoxSizer(wxVERTICAL, this, "D-Pad");
wxBoxSizer* s_subpanel_pad_1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_pad_2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel_pad_3 = new wxBoxSizer(wxVERTICAL);
// Left shifts
wxStaticBoxSizer* s_round_pad_shifts_l = new wxStaticBoxSizer(wxVERTICAL, this, _("Left Shifts"));
wxStaticBoxSizer* s_round_pad_l1 = new wxStaticBoxSizer(wxVERTICAL, this, _("L1"));
wxStaticBoxSizer* s_round_pad_l2 = new wxStaticBoxSizer(wxVERTICAL, this, _("L2"));
wxStaticBoxSizer* s_round_pad_l3 = new wxStaticBoxSizer(wxVERTICAL, this, _("L3"));
wxStaticBoxSizer* s_round_pad_shifts_l = new wxStaticBoxSizer(wxVERTICAL, this, "Left Shifts");
wxStaticBoxSizer* s_round_pad_l1 = new wxStaticBoxSizer(wxVERTICAL, this, "L1");
wxStaticBoxSizer* s_round_pad_l2 = new wxStaticBoxSizer(wxVERTICAL, this, "L2");
wxStaticBoxSizer* s_round_pad_l3 = new wxStaticBoxSizer(wxVERTICAL, this, "L3");
// Start / Select
wxStaticBoxSizer* s_round_pad_system = new wxStaticBoxSizer(wxVERTICAL, this, _("System"));
wxStaticBoxSizer* s_round_pad_select = new wxStaticBoxSizer(wxVERTICAL, this, _("Select"));
wxStaticBoxSizer* s_round_pad_start = new wxStaticBoxSizer(wxVERTICAL, this, _("Start"));
wxStaticBoxSizer* s_round_pad_system = new wxStaticBoxSizer(wxVERTICAL, this, "System");
wxStaticBoxSizer* s_round_pad_select = new wxStaticBoxSizer(wxVERTICAL, this, "Select");
wxStaticBoxSizer* s_round_pad_start = new wxStaticBoxSizer(wxVERTICAL, this, "Start");
// Right shifts
wxStaticBoxSizer* s_round_pad_shifts_r = new wxStaticBoxSizer(wxVERTICAL, this, _("Right Shifts"));
wxStaticBoxSizer* s_round_pad_r1 = new wxStaticBoxSizer(wxVERTICAL, this, _("R1"));
wxStaticBoxSizer* s_round_pad_r2 = new wxStaticBoxSizer(wxVERTICAL, this, _("R2"));
wxStaticBoxSizer* s_round_pad_r3 = new wxStaticBoxSizer(wxVERTICAL, this, _("R3"));
wxStaticBoxSizer* s_round_pad_shifts_r = new wxStaticBoxSizer(wxVERTICAL, this, "Right Shifts");
wxStaticBoxSizer* s_round_pad_r1 = new wxStaticBoxSizer(wxVERTICAL, this, "R1");
wxStaticBoxSizer* s_round_pad_r2 = new wxStaticBoxSizer(wxVERTICAL, this, "R2");
wxStaticBoxSizer* s_round_pad_r3 = new wxStaticBoxSizer(wxVERTICAL, this, "R3");
// Action buttons
wxStaticBoxSizer* s_round_pad_buttons = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
wxStaticBoxSizer* s_round_pad_square = new wxStaticBoxSizer(wxVERTICAL, this, _("Square"));
wxStaticBoxSizer* s_round_pad_cross = new wxStaticBoxSizer(wxVERTICAL, this, _("Cross"));
wxStaticBoxSizer* s_round_pad_circle = new wxStaticBoxSizer(wxVERTICAL, this, _("Circle"));
wxStaticBoxSizer* s_round_pad_triangle = new wxStaticBoxSizer(wxVERTICAL, this, _("Triangle"));
wxStaticBoxSizer* s_round_pad_buttons = new wxStaticBoxSizer(wxVERTICAL, this, "Buttons");
wxStaticBoxSizer* s_round_pad_square = new wxStaticBoxSizer(wxVERTICAL, this, "Square");
wxStaticBoxSizer* s_round_pad_cross = new wxStaticBoxSizer(wxVERTICAL, this, "Cross");
wxStaticBoxSizer* s_round_pad_circle = new wxStaticBoxSizer(wxVERTICAL, this, "Circle");
wxStaticBoxSizer* s_round_pad_triangle = new wxStaticBoxSizer(wxVERTICAL, this, "Triangle");
wxBoxSizer* s_subpanel_buttons_1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_buttons_2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel_buttons_3 = new wxBoxSizer(wxVERTICAL);
// Right Analog Stick
wxStaticBoxSizer* s_round_stick_r = new wxStaticBoxSizer(wxVERTICAL, this, _("Right Analog Stick"));
wxStaticBoxSizer* s_round_stick_r = new wxStaticBoxSizer(wxVERTICAL, this, "Right Analog Stick");
wxBoxSizer* s_subpanel_rstick_1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_rstick_2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel_rstick_3 = new wxBoxSizer(wxVERTICAL);
@ -258,36 +254,36 @@ void PADManager::OnKeyDown(wxKeyEvent &keyEvent)
switch (m_button_id)
{
case id_pad_lstick_left: rpcs3::config.io.pad.left_stick_left = keyEvent.GetKeyCode(); break;
case id_pad_lstick_down: rpcs3::config.io.pad.left_stick_down = keyEvent.GetKeyCode(); break;
case id_pad_lstick_right: rpcs3::config.io.pad.left_stick_right = keyEvent.GetKeyCode(); break;
case id_pad_lstick_up: rpcs3::config.io.pad.left_stick_up = keyEvent.GetKeyCode(); break;
case id_pad_lstick_left: g_kbpad_config.left_stick_left = keyEvent.GetKeyCode(); break;
case id_pad_lstick_down: g_kbpad_config.left_stick_down = keyEvent.GetKeyCode(); break;
case id_pad_lstick_right: g_kbpad_config.left_stick_right = keyEvent.GetKeyCode(); break;
case id_pad_lstick_up: g_kbpad_config.left_stick_up = keyEvent.GetKeyCode(); break;
case id_pad_left: rpcs3::config.io.pad.left = keyEvent.GetKeyCode(); break;
case id_pad_down: rpcs3::config.io.pad.down = keyEvent.GetKeyCode(); break;
case id_pad_right: rpcs3::config.io.pad.right = keyEvent.GetKeyCode(); break;
case id_pad_up: rpcs3::config.io.pad.up = keyEvent.GetKeyCode(); break;
case id_pad_left: g_kbpad_config.left = keyEvent.GetKeyCode(); break;
case id_pad_down: g_kbpad_config.down = keyEvent.GetKeyCode(); break;
case id_pad_right: g_kbpad_config.right = keyEvent.GetKeyCode(); break;
case id_pad_up: g_kbpad_config.up = keyEvent.GetKeyCode(); break;
case id_pad_l1: rpcs3::config.io.pad.l1 = keyEvent.GetKeyCode(); break;
case id_pad_l2: rpcs3::config.io.pad.l2 = keyEvent.GetKeyCode(); break;
case id_pad_l3: rpcs3::config.io.pad.l3 = keyEvent.GetKeyCode(); break;
case id_pad_l1: g_kbpad_config.l1 = keyEvent.GetKeyCode(); break;
case id_pad_l2: g_kbpad_config.l2 = keyEvent.GetKeyCode(); break;
case id_pad_l3: g_kbpad_config.l3 = keyEvent.GetKeyCode(); break;
case id_pad_start: rpcs3::config.io.pad.start = keyEvent.GetKeyCode(); break;
case id_pad_select: rpcs3::config.io.pad.select = keyEvent.GetKeyCode(); break;
case id_pad_start: g_kbpad_config.start = keyEvent.GetKeyCode(); break;
case id_pad_select: g_kbpad_config.select = keyEvent.GetKeyCode(); break;
case id_pad_r1: rpcs3::config.io.pad.r1 = keyEvent.GetKeyCode(); break;
case id_pad_r2: rpcs3::config.io.pad.r2 = keyEvent.GetKeyCode(); break;
case id_pad_r3: rpcs3::config.io.pad.r3 = keyEvent.GetKeyCode(); break;
case id_pad_r1: g_kbpad_config.r1 = keyEvent.GetKeyCode(); break;
case id_pad_r2: g_kbpad_config.r2 = keyEvent.GetKeyCode(); break;
case id_pad_r3: g_kbpad_config.r3 = keyEvent.GetKeyCode(); break;
case id_pad_square: rpcs3::config.io.pad.square = keyEvent.GetKeyCode(); break;
case id_pad_cross: rpcs3::config.io.pad.cross = keyEvent.GetKeyCode(); break;
case id_pad_circle: rpcs3::config.io.pad.circle = keyEvent.GetKeyCode(); break;
case id_pad_triangle: rpcs3::config.io.pad.triangle = keyEvent.GetKeyCode(); break;
case id_pad_square: g_kbpad_config.square = keyEvent.GetKeyCode(); break;
case id_pad_cross: g_kbpad_config.cross = keyEvent.GetKeyCode(); break;
case id_pad_circle: g_kbpad_config.circle = keyEvent.GetKeyCode(); break;
case id_pad_triangle: g_kbpad_config.triangle = keyEvent.GetKeyCode(); break;
case id_pad_rstick_left: rpcs3::config.io.pad.right_stick_left = keyEvent.GetKeyCode(); break;
case id_pad_rstick_down: rpcs3::config.io.pad.right_stick_down = keyEvent.GetKeyCode(); break;
case id_pad_rstick_right: rpcs3::config.io.pad.right_stick_right = keyEvent.GetKeyCode(); break;
case id_pad_rstick_up: rpcs3::config.io.pad.right_stick_up = keyEvent.GetKeyCode(); break;
case id_pad_rstick_left: g_kbpad_config.right_stick_left = keyEvent.GetKeyCode(); break;
case id_pad_rstick_down: g_kbpad_config.right_stick_down = keyEvent.GetKeyCode(); break;
case id_pad_rstick_right: g_kbpad_config.right_stick_right = keyEvent.GetKeyCode(); break;
case id_pad_rstick_up: g_kbpad_config.right_stick_up = keyEvent.GetKeyCode(); break;
case 0: break;
default: LOG_ERROR(HLE, "Unknown button ID: %d", m_button_id); break;
@ -321,7 +317,7 @@ void PADManager::OnButtonClicked(wxCommandEvent &event)
switch (event.GetId())
{
case id_reset_parameters: ResetParameters(); UpdateLabel(); break;
case wxID_OK: rpcs3::config.save(); break;
case wxID_OK: g_kbpad_config.save(); break;
case wxID_CANCEL: break;
default: LOG_ERROR(HLE, "Unknown button ID: %d", event.GetId()); break;
@ -409,70 +405,70 @@ const wxString PADManager::GetKeyName(const u32 keyCode)
void PADManager::UpdateLabel()
{
// Get button labels from .ini
b_up_lstick->SetLabel(GetKeyName(rpcs3::config.io.pad.left_stick_up.value()));
b_down_lstick->SetLabel(GetKeyName(rpcs3::config.io.pad.left_stick_down.value()));
b_left_lstick->SetLabel(GetKeyName(rpcs3::config.io.pad.left_stick_left.value()));
b_right_lstick->SetLabel(GetKeyName(rpcs3::config.io.pad.left_stick_right.value()));
b_up_lstick->SetLabel(GetKeyName(g_kbpad_config.left_stick_up));
b_down_lstick->SetLabel(GetKeyName(g_kbpad_config.left_stick_down));
b_left_lstick->SetLabel(GetKeyName(g_kbpad_config.left_stick_left));
b_right_lstick->SetLabel(GetKeyName(g_kbpad_config.left_stick_right));
b_up->SetLabel(GetKeyName(rpcs3::config.io.pad.up.value()));
b_down->SetLabel(GetKeyName(rpcs3::config.io.pad.down.value()));
b_left->SetLabel(GetKeyName(rpcs3::config.io.pad.left.value()));
b_right->SetLabel(GetKeyName(rpcs3::config.io.pad.right.value()));
b_up->SetLabel(GetKeyName(g_kbpad_config.up));
b_down->SetLabel(GetKeyName(g_kbpad_config.down));
b_left->SetLabel(GetKeyName(g_kbpad_config.left));
b_right->SetLabel(GetKeyName(g_kbpad_config.right));
b_shift_l1->SetLabel(GetKeyName(rpcs3::config.io.pad.l1.value()));
b_shift_l2->SetLabel(GetKeyName(rpcs3::config.io.pad.l2.value()));
b_shift_l3->SetLabel(GetKeyName(rpcs3::config.io.pad.l3.value()));
b_shift_l1->SetLabel(GetKeyName(g_kbpad_config.l1));
b_shift_l2->SetLabel(GetKeyName(g_kbpad_config.l2));
b_shift_l3->SetLabel(GetKeyName(g_kbpad_config.l3));
b_start->SetLabel(GetKeyName(rpcs3::config.io.pad.start.value()));
b_select->SetLabel(GetKeyName(rpcs3::config.io.pad.select.value()));
b_start->SetLabel(GetKeyName(g_kbpad_config.start));
b_select->SetLabel(GetKeyName(g_kbpad_config.select));
b_shift_r1->SetLabel(GetKeyName(rpcs3::config.io.pad.r1.value()));
b_shift_r2->SetLabel(GetKeyName(rpcs3::config.io.pad.r2.value()));
b_shift_r3->SetLabel(GetKeyName(rpcs3::config.io.pad.r3.value()));
b_shift_r1->SetLabel(GetKeyName(g_kbpad_config.r1));
b_shift_r2->SetLabel(GetKeyName(g_kbpad_config.r2));
b_shift_r3->SetLabel(GetKeyName(g_kbpad_config.r3));
b_square->SetLabel(GetKeyName(rpcs3::config.io.pad.square.value()));
b_cross->SetLabel(GetKeyName(rpcs3::config.io.pad.cross.value()));
b_circle->SetLabel(GetKeyName(rpcs3::config.io.pad.circle.value()));
b_triangle->SetLabel(GetKeyName(rpcs3::config.io.pad.triangle.value()));
b_square->SetLabel(GetKeyName(g_kbpad_config.square));
b_cross->SetLabel(GetKeyName(g_kbpad_config.cross));
b_circle->SetLabel(GetKeyName(g_kbpad_config.circle));
b_triangle->SetLabel(GetKeyName(g_kbpad_config.triangle));
b_up_rstick->SetLabel(GetKeyName(rpcs3::config.io.pad.right_stick_up.value()));
b_down_rstick->SetLabel(GetKeyName(rpcs3::config.io.pad.right_stick_down.value()));
b_left_rstick->SetLabel(GetKeyName(rpcs3::config.io.pad.right_stick_left.value()));
b_right_rstick->SetLabel(GetKeyName(rpcs3::config.io.pad.right_stick_right.value()));
b_up_rstick->SetLabel(GetKeyName(g_kbpad_config.right_stick_up));
b_down_rstick->SetLabel(GetKeyName(g_kbpad_config.right_stick_down));
b_left_rstick->SetLabel(GetKeyName(g_kbpad_config.right_stick_left));
b_right_rstick->SetLabel(GetKeyName(g_kbpad_config.right_stick_right));
}
void PADManager::ResetParameters()
{
rpcs3::config.io.pad.left_stick_up = 315;
rpcs3::config.io.pad.left_stick_down = 317;
rpcs3::config.io.pad.left_stick_left = 314;
rpcs3::config.io.pad.left_stick_right = 316;
g_kbpad_config.left_stick_up = g_kbpad_config.left_stick_up.def;
g_kbpad_config.left_stick_down = g_kbpad_config.left_stick_down.def;
g_kbpad_config.left_stick_left = g_kbpad_config.left_stick_left.def;
g_kbpad_config.left_stick_right = g_kbpad_config.left_stick_right.def;
rpcs3::config.io.pad.up = static_cast<int>('W');
rpcs3::config.io.pad.down = static_cast<int>('S');
rpcs3::config.io.pad.left = static_cast<int>('A');
rpcs3::config.io.pad.right = static_cast<int>('D');
g_kbpad_config.up = g_kbpad_config.up.def;
g_kbpad_config.down = g_kbpad_config.down.def;
g_kbpad_config.left = g_kbpad_config.left.def;
g_kbpad_config.right = g_kbpad_config.right.def;
rpcs3::config.io.pad.l1 = static_cast<int>('1');
rpcs3::config.io.pad.l2 = static_cast<int>('Q');
rpcs3::config.io.pad.l3 = static_cast<int>('Z');
g_kbpad_config.l1 = g_kbpad_config.l1.def;
g_kbpad_config.l2 = g_kbpad_config.l2.def;
g_kbpad_config.l3 = g_kbpad_config.l3.def;
rpcs3::config.io.pad.start = 13;
rpcs3::config.io.pad.select = 32;
g_kbpad_config.start = g_kbpad_config.start.def;
g_kbpad_config.select = g_kbpad_config.select.def;
rpcs3::config.io.pad.r1 = static_cast<int>('3');
rpcs3::config.io.pad.r2 = static_cast<int>('E');
rpcs3::config.io.pad.r3 = static_cast<int>('C');
g_kbpad_config.r1 = g_kbpad_config.r1.def;
g_kbpad_config.r2 = g_kbpad_config.r2.def;
g_kbpad_config.r3 = g_kbpad_config.r3.def;
rpcs3::config.io.pad.square = static_cast<int>('J');
rpcs3::config.io.pad.cross = static_cast<int>('K');
rpcs3::config.io.pad.circle = static_cast<int>('L');
rpcs3::config.io.pad.triangle = static_cast<int>('I');
g_kbpad_config.square = g_kbpad_config.square.def;
g_kbpad_config.cross = g_kbpad_config.cross.def;
g_kbpad_config.circle = g_kbpad_config.circle.def;
g_kbpad_config.triangle = g_kbpad_config.triangle.def;
rpcs3::config.io.pad.right_stick_up = 366;
rpcs3::config.io.pad.right_stick_down = 367;
rpcs3::config.io.pad.right_stick_left = 313;
rpcs3::config.io.pad.right_stick_right = 312;
g_kbpad_config.right_stick_up = g_kbpad_config.right_stick_up.def;
g_kbpad_config.right_stick_down = g_kbpad_config.right_stick_down.def;
g_kbpad_config.right_stick_left = g_kbpad_config.right_stick_left.def;
g_kbpad_config.right_stick_right = g_kbpad_config.right_stick_right.def;
}
void PADManager::UpdateTimerLabel(const u32 id)
@ -552,6 +548,9 @@ void PADManager::SwitchButtons(const bool IsEnabled)
b_reset->Enable(IsEnabled);
}
// TODO: rewrite with std::chrono or wxTimer
#include <time.h>
void PADManager::RunTimer(const u32 seconds, const u32 id)
{
m_seconds = seconds;

View File

@ -1,4 +1,4 @@
#include <time.h>
#pragma once
enum ButtonIDs
{
@ -80,11 +80,10 @@ class PADManager : public wxDialog, PadButtons
private:
u32 m_seconds;
u32 m_button_id;
bool m_key_pressed, m_emu_paused;
bool m_key_pressed;
public:
PADManager(wxWindow* parent);
~PADManager() { if(m_emu_paused) Emu.Resume(); }
void OnKeyDown(wxKeyEvent &keyEvent);
void OnKeyUp(wxKeyEvent &keyEvent);

View File

@ -1,22 +1,15 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "RSXDebugger.h"
#include "Utilities/rPlatform.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/state.h"
#include "Emu/IdManager.h"
#include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "Emu/RSX/GSManager.h"
#include "Emu/RSX/GSRender.h"
#include "Emu/RSX/GCM.h"
#include "MemoryViewer.h"
// TODO: Clear the object when restarting the emulator
std::vector<RSXDebuggerProgram> m_debug_programs;
#include "RSXDebugger.h"
enum GCMEnumTypes
{
@ -89,14 +82,14 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
wxPanel* p_texture = new wxPanel(nb_rsx, wxID_ANY);
wxPanel* p_settings = new wxPanel(nb_rsx, wxID_ANY);
nb_rsx->AddPage(p_commands, wxT("RSX Commands"));
nb_rsx->AddPage(p_captured_frame, wxT("Captured Frame"));
nb_rsx->AddPage(p_captured_draw_calls, wxT("Captured Draw Calls"));
nb_rsx->AddPage(p_flags, wxT("Flags"));
nb_rsx->AddPage(p_commands, "RSX Commands");
nb_rsx->AddPage(p_captured_frame, "Captured Frame");
nb_rsx->AddPage(p_captured_draw_calls, "Captured Draw Calls");
nb_rsx->AddPage(p_flags, "Flags");
nb_rsx->AddPage(p_lightning, wxT("Lightning"));
nb_rsx->AddPage(p_texture, wxT("Texture"));
nb_rsx->AddPage(p_settings, wxT("Settings"));
nb_rsx->AddPage(p_lightning, "Lightning");
nb_rsx->AddPage(p_texture, "Texture");
nb_rsx->AddPage(p_settings, "Settings");
//Tabs: Lists
m_list_commands = new wxListView(p_commands, wxID_ANY, wxPoint(1,3), wxSize(720, 720));
@ -165,10 +158,10 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
wxPanel* p_shader_program = new wxPanel(state_rsx, wxID_ANY);
wxPanel* p_index_buffer = new wxPanel(state_rsx, wxID_ANY);
state_rsx->AddPage(p_buffers, wxT("RTTs and DS"));
state_rsx->AddPage(p_transform_program, wxT("Transform program"));
state_rsx->AddPage(p_shader_program, wxT("Shader program"));
state_rsx->AddPage(p_index_buffer, (wxT("Index buffer")));
state_rsx->AddPage(p_buffers, "RTTs and DS");
state_rsx->AddPage(p_transform_program, "Transform program");
state_rsx->AddPage(p_shader_program, "Shader program");
state_rsx->AddPage(p_index_buffer, "Index buffer");
m_text_transform_program = new wxTextCtrl(p_transform_program, wxID_ANY, "", wxPoint(1, 3), wxSize(720, 720), wxTE_MULTILINE | wxTE_READONLY);
m_text_transform_program->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
@ -191,8 +184,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
wxStaticBoxSizer* s_buffers_text = new wxStaticBoxSizer(wxHORIZONTAL, p_buffers, "Texture");
//Buffers and textures
CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum((u32)rpcs3::state.config.rsx.resolution.value())];
m_panel_width = (res.width*108)/res.height;
m_panel_width = 108;
m_panel_height = 108;
m_text_width = 108;
m_text_height = 108;
@ -344,17 +336,20 @@ namespace
void RSXDebugger::OnClickBuffer(wxMouseEvent& event)
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto buffers = render.gcm_buffers;
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
const auto buffers = render->gcm_buffers;
if(!buffers)
return;
// TODO: Is there any better way to choose the color buffers
#define SHOW_BUFFER(id) \
{ \
u32 addr = render.local_mem_addr + buffers[id].offset; \
u32 addr = render->local_mem_addr + buffers[id].offset; \
if (vm::check_addr(addr) && buffers[id].width && buffers[id].height) \
MemoryViewerPanel::ShowImage(this, addr, 3, buffers[id].width, buffers[id].height, true); \
return; \
@ -373,13 +368,13 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event)
if (event.GetId() == p_buffer_stencil->GetId()) display_buffer(this, stencil_img);
if (event.GetId() == p_buffer_tex->GetId())
{
u8 location = render.textures[m_cur_texture].location();
if(location <= 1 && vm::check_addr(rsx::get_address(render.textures[m_cur_texture].offset(), location))
&& render.textures[m_cur_texture].width() && render.textures[m_cur_texture].height())
u8 location = render->textures[m_cur_texture].location();
if(location <= 1 && vm::check_addr(rsx::get_address(render->textures[m_cur_texture].offset(), location))
&& render->textures[m_cur_texture].width() && render->textures[m_cur_texture].height())
MemoryViewerPanel::ShowImage(this,
rsx::get_address(render.textures[m_cur_texture].offset(), location), 1,
render.textures[m_cur_texture].width(),
render.textures[m_cur_texture].height(), false);
rsx::get_address(render->textures[m_cur_texture].offset(), location), 1,
render->textures[m_cur_texture].width(),
render->textures[m_cur_texture].height(), false);
}
#undef SHOW_BUFFER
@ -587,30 +582,32 @@ void RSXDebugger::OnClickDrawCalls(wxMouseEvent& event)
void RSXDebugger::GoToGet(wxCommandEvent& event)
{
if (!RSXReady()) return;
auto ctrl = Emu.GetGSManager().GetRender().ctrl;
if (const auto render = fxm::get<GSRender>())
{
u32 realAddr;
if (RSXIOMem.getRealAddr(ctrl->get.load(), realAddr)) {
if (RSXIOMem.getRealAddr(render->ctrl->get.load(), realAddr))
{
m_addr = realAddr;
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
// TODO: We should probably throw something?
}
}
void RSXDebugger::GoToPut(wxCommandEvent& event)
{
if (!RSXReady()) return;
auto ctrl = Emu.GetGSManager().GetRender().ctrl;
if (const auto render = fxm::get<GSRender>())
{
u32 realAddr;
if (RSXIOMem.getRealAddr(ctrl->put.load(), realAddr)) {
if (RSXIOMem.getRealAddr(render->ctrl->put.load(), realAddr))
{
m_addr = realAddr;
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
// TODO: We should probably throw something?
}
}
void RSXDebugger::UpdateInformation()
@ -630,14 +627,12 @@ void RSXDebugger::GetMemory()
for(u32 i=0; i<m_item_count; i++)
m_list_commands->SetItem(i, 2, wxEmptyString);
bool isReady = RSXReady();
// Write information
for(u32 i=0, addr = m_addr; i<m_item_count; i++, addr += 4)
{
m_list_commands->SetItem(i, 0, wxString::Format("%08x", addr));
if (isReady && vm::check_addr(addr))
if (vm::check_addr(addr))
{
u32 cmd = vm::ps3::read32(addr);
u32 count = (cmd >> 18) & 0x7ff;
@ -667,7 +662,7 @@ void RSXDebugger::GetMemory()
dump += '\n';
}
fs::file(fs::get_config_dir() + "command_dump.log", fom::rewrite).write(dump);
fs::file(fs::get_config_dir() + "command_dump.log", fs::rewrite).write(dump);
for (u32 i = 0;i < frame_debug.draw_calls.size(); i++)
m_list_captured_draw_calls->InsertItem(i, frame_debug.draw_calls[i].name);
@ -675,18 +670,21 @@ void RSXDebugger::GetMemory()
void RSXDebugger::GetBuffers()
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
// Draw Buffers
// TODO: Currently it only supports color buffers
for (u32 bufferId=0; bufferId < render.gcm_buffers_count; bufferId++)
for (u32 bufferId=0; bufferId < render->gcm_buffers_count; bufferId++)
{
if(!vm::check_addr(render.gcm_buffers.addr()))
if(!vm::check_addr(render->gcm_buffers.addr()))
continue;
auto buffers = render.gcm_buffers;
u32 RSXbuffer_addr = render.local_mem_addr + buffers[bufferId].offset;
auto buffers = render->gcm_buffers;
u32 RSXbuffer_addr = render->local_mem_addr + buffers[bufferId].offset;
if(!vm::check_addr(RSXbuffer_addr))
continue;
@ -725,15 +723,15 @@ void RSXDebugger::GetBuffers()
}
// Draw Texture
if(!render.textures[m_cur_texture].enabled())
if(!render->textures[m_cur_texture].enabled())
return;
u32 offset = render.textures[m_cur_texture].offset();
u32 offset = render->textures[m_cur_texture].offset();
if(!offset)
return;
u8 location = render.textures[m_cur_texture].location();
u8 location = render->textures[m_cur_texture].location();
if(location > 1)
return;
@ -745,8 +743,8 @@ void RSXDebugger::GetBuffers()
unsigned char* TexBuffer = vm::ps3::_ptr<u8>(TexBuffer_addr);
u32 width = render.textures[m_cur_texture].width();
u32 height = render.textures[m_cur_texture].height();
u32 width = render->textures[m_cur_texture].width();
u32 height = render->textures[m_cur_texture].height();
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
std::memcpy(buffer, vm::base(TexBuffer_addr), width * height * 3);
@ -757,32 +755,36 @@ void RSXDebugger::GetBuffers()
void RSXDebugger::GetFlags()
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
m_list_flags->DeleteAllItems();
int i=0;
#define LIST_FLAGS_ADD(name, value) \
m_list_flags->InsertItem(i, name); m_list_flags->SetItem(i, 1, value ? "Enabled" : "Disabled"); i++;
/*
LIST_FLAGS_ADD("Alpha test", render.m_set_alpha_test);
LIST_FLAGS_ADD("Blend", render.m_set_blend);
LIST_FLAGS_ADD("Scissor", render.m_set_scissor_horizontal && render.m_set_scissor_vertical);
LIST_FLAGS_ADD("Cull face", render.m_set_cull_face);
LIST_FLAGS_ADD("Depth bounds test", render.m_set_depth_bounds_test);
LIST_FLAGS_ADD("Depth test", render.m_set_depth_test);
LIST_FLAGS_ADD("Dither", render.m_set_dither);
LIST_FLAGS_ADD("Line smooth", render.m_set_line_smooth);
LIST_FLAGS_ADD("Logic op", render.m_set_logic_op);
LIST_FLAGS_ADD("Poly smooth", render.m_set_poly_smooth);
LIST_FLAGS_ADD("Poly offset fill", render.m_set_poly_offset_fill);
LIST_FLAGS_ADD("Poly offset line", render.m_set_poly_offset_line);
LIST_FLAGS_ADD("Poly offset point", render.m_set_poly_offset_point);
LIST_FLAGS_ADD("Stencil test", render.m_set_stencil_test);
LIST_FLAGS_ADD("Primitive restart", render.m_set_restart_index);
LIST_FLAGS_ADD("Two sided lighting", render.m_set_two_side_light_enable);
LIST_FLAGS_ADD("Point Sprite", render.m_set_point_sprite_control);
LIST_FLAGS_ADD("Lighting ", render.m_set_specular);
LIST_FLAGS_ADD("Alpha test", render->m_set_alpha_test);
LIST_FLAGS_ADD("Blend", render->m_set_blend);
LIST_FLAGS_ADD("Scissor", render->m_set_scissor_horizontal && render->m_set_scissor_vertical);
LIST_FLAGS_ADD("Cull face", render->m_set_cull_face);
LIST_FLAGS_ADD("Depth bounds test", render->m_set_depth_bounds_test);
LIST_FLAGS_ADD("Depth test", render->m_set_depth_test);
LIST_FLAGS_ADD("Dither", render->m_set_dither);
LIST_FLAGS_ADD("Line smooth", render->m_set_line_smooth);
LIST_FLAGS_ADD("Logic op", render->m_set_logic_op);
LIST_FLAGS_ADD("Poly smooth", render->m_set_poly_smooth);
LIST_FLAGS_ADD("Poly offset fill", render->m_set_poly_offset_fill);
LIST_FLAGS_ADD("Poly offset line", render->m_set_poly_offset_line);
LIST_FLAGS_ADD("Poly offset point", render->m_set_poly_offset_point);
LIST_FLAGS_ADD("Stencil test", render->m_set_stencil_test);
LIST_FLAGS_ADD("Primitive restart", render->m_set_restart_index);
LIST_FLAGS_ADD("Two sided lighting", render->m_set_two_side_light_enable);
LIST_FLAGS_ADD("Point Sprite", render->m_set_point_sprite_control);
LIST_FLAGS_ADD("Lighting ", render->m_set_specular);
*/
#undef LIST_FLAGS_ADD
@ -790,50 +792,58 @@ void RSXDebugger::GetFlags()
void RSXDebugger::GetLightning()
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
m_list_lightning->DeleteAllItems();
int i=0;
#define LIST_LIGHTNING_ADD(name, value) \
m_list_lightning->InsertItem(i, name); m_list_lightning->SetItem(i, 1, value); i++;
//LIST_LIGHTNING_ADD("Shade model", (render.m_shade_mode == 0x1D00) ? "Flat" : "Smooth");
//LIST_LIGHTNING_ADD("Shade model", (render->m_shade_mode == 0x1D00) ? "Flat" : "Smooth");
#undef LIST_LIGHTNING_ADD
}
void RSXDebugger::GetTexture()
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
m_list_texture->DeleteAllItems();
for(uint i=0; i<rsx::limits::textures_count; ++i)
{
if(render.textures[i].enabled())
if(render->textures[i].enabled())
{
m_list_texture->InsertItem(i, wxString::Format("%d", i));
u8 location = render.textures[i].location();
u8 location = render->textures[i].location();
if(location > 1)
{
m_list_texture->SetItem(i, 1,
wxString::Format("Bad address (offset=0x%x, location=%d)", render.textures[i].offset(), location));
wxString::Format("Bad address (offset=0x%x, location=%d)", render->textures[i].offset(), location));
}
else
{
m_list_texture->SetItem(i, 1, wxString::Format("0x%x", rsx::get_address(render.textures[i].offset(), location)));
m_list_texture->SetItem(i, 1, wxString::Format("0x%x", rsx::get_address(render->textures[i].offset(), location)));
}
m_list_texture->SetItem(i, 2, render.textures[i].cubemap() ? "True" : "False");
m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.textures[i].dimension()));
m_list_texture->SetItem(i, 4, render.textures[i].enabled() ? "True" : "False");
m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.textures[i].format()));
m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.textures[i].mipmap()));
m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.textures[i].pitch()));
m_list_texture->SetItem(i, 2, render->textures[i].cubemap() ? "True" : "False");
m_list_texture->SetItem(i, 3, wxString::Format("%dD", render->textures[i].dimension()));
m_list_texture->SetItem(i, 4, render->textures[i].enabled() ? "True" : "False");
m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render->textures[i].format()));
m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render->textures[i].mipmap()));
m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render->textures[i].pitch()));
m_list_texture->SetItem(i, 8, wxString::Format("%dx%d",
render.textures[i].width(),
render.textures[i].height()));
render->textures[i].width(),
render->textures[i].height()));
m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White"));
}
@ -842,63 +852,67 @@ void RSXDebugger::GetTexture()
void RSXDebugger::GetSettings()
{
if (!RSXReady()) return;
const GSRender& render = Emu.GetGSManager().GetRender();
const auto render = fxm::get<GSRender>();
if (!render)
{
return;
}
m_list_settings->DeleteAllItems();
int i=0;
#define LIST_SETTINGS_ADD(name, value) \
m_list_settings->InsertItem(i, name); m_list_settings->SetItem(i, 1, value); i++;
/*
LIST_SETTINGS_ADD("Alpha func", !(render.m_set_alpha_func) ? "(none)" : wxString::Format("0x%x (%s)",
render.m_alpha_func,
ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Blend color", !(render.m_set_blend_color) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d",
render.m_blend_color_r,
render.m_blend_color_g,
render.m_blend_color_b,
render.m_blend_color_a));
LIST_SETTINGS_ADD("Clipping", wxString::Format("Min:%f, Max:%f", render.m_clip_min, render.m_clip_max));
LIST_SETTINGS_ADD("Color mask", !(render.m_set_color_mask) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d",
render.m_color_mask_r,
render.m_color_mask_g,
render.m_color_mask_b,
render.m_color_mask_a));
LIST_SETTINGS_ADD("Context DMA Color A", wxString::Format("0x%x", render.m_context_dma_color_a));
LIST_SETTINGS_ADD("Context DMA Color B", wxString::Format("0x%x", render.m_context_dma_color_b));
LIST_SETTINGS_ADD("Context DMA Color C", wxString::Format("0x%x", render.m_context_dma_color_c));
LIST_SETTINGS_ADD("Context DMA Color D", wxString::Format("0x%x", render.m_context_dma_color_d));
LIST_SETTINGS_ADD("Context DMA Zeta", wxString::Format("0x%x", render.m_context_dma_z));
LIST_SETTINGS_ADD("Depth bounds", wxString::Format("Min:%f, Max:%f", render.m_depth_bounds_min, render.m_depth_bounds_max));
LIST_SETTINGS_ADD("Depth func", !(render.m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)",
render.m_depth_func,
ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Alpha func", !(render->m_set_alpha_func) ? "(none)" : wxString::Format("0x%x (%s)",
render->m_alpha_func,
ParseGCMEnum(render->m_alpha_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Blend color", !(render->m_set_blend_color) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d",
render->m_blend_color_r,
render->m_blend_color_g,
render->m_blend_color_b,
render->m_blend_color_a));
LIST_SETTINGS_ADD("Clipping", wxString::Format("Min:%f, Max:%f", render->m_clip_min, render->m_clip_max));
LIST_SETTINGS_ADD("Color mask", !(render->m_set_color_mask) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d",
render->m_color_mask_r,
render->m_color_mask_g,
render->m_color_mask_b,
render->m_color_mask_a));
LIST_SETTINGS_ADD("Context DMA Color A", wxString::Format("0x%x", render->m_context_dma_color_a));
LIST_SETTINGS_ADD("Context DMA Color B", wxString::Format("0x%x", render->m_context_dma_color_b));
LIST_SETTINGS_ADD("Context DMA Color C", wxString::Format("0x%x", render->m_context_dma_color_c));
LIST_SETTINGS_ADD("Context DMA Color D", wxString::Format("0x%x", render->m_context_dma_color_d));
LIST_SETTINGS_ADD("Context DMA Zeta", wxString::Format("0x%x", render->m_context_dma_z));
LIST_SETTINGS_ADD("Depth bounds", wxString::Format("Min:%f, Max:%f", render->m_depth_bounds_min, render->m_depth_bounds_max));
LIST_SETTINGS_ADD("Depth func", !(render->m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)",
render->m_depth_func,
ParseGCMEnum(render->m_depth_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Draw mode", wxString::Format("%d (%s)",
render.m_draw_mode,
ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM)));
render->m_draw_mode,
ParseGCMEnum(render->m_draw_mode, CELL_GCM_PRIMITIVE_ENUM)));
LIST_SETTINGS_ADD("Scissor", wxString::Format("X:%d, Y:%d, W:%d, H:%d",
render.m_scissor_x,
render.m_scissor_y,
render.m_scissor_w,
render.m_scissor_h));
LIST_SETTINGS_ADD("Stencil func", !(render.m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)",
render.m_stencil_func,
ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", render.m_surface_pitch_a));
LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", render.m_surface_pitch_b));
LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", render.m_surface_pitch_c));
LIST_SETTINGS_ADD("Surface Pitch D", wxString::Format("0x%x", render.m_surface_pitch_d));
LIST_SETTINGS_ADD("Surface Pitch Z", wxString::Format("0x%x", render.m_surface_pitch_z));
LIST_SETTINGS_ADD("Surface Offset A", wxString::Format("0x%x", render.m_surface_offset_a));
LIST_SETTINGS_ADD("Surface Offset B", wxString::Format("0x%x", render.m_surface_offset_b));
LIST_SETTINGS_ADD("Surface Offset C", wxString::Format("0x%x", render.m_surface_offset_c));
LIST_SETTINGS_ADD("Surface Offset D", wxString::Format("0x%x", render.m_surface_offset_d));
LIST_SETTINGS_ADD("Surface Offset Z", wxString::Format("0x%x", render.m_surface_offset_z));
render->m_scissor_x,
render->m_scissor_y,
render->m_scissor_w,
render->m_scissor_h));
LIST_SETTINGS_ADD("Stencil func", !(render->m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)",
render->m_stencil_func,
ParseGCMEnum(render->m_stencil_func, CELL_GCM_ENUM)));
LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", render->m_surface_pitch_a));
LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", render->m_surface_pitch_b));
LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", render->m_surface_pitch_c));
LIST_SETTINGS_ADD("Surface Pitch D", wxString::Format("0x%x", render->m_surface_pitch_d));
LIST_SETTINGS_ADD("Surface Pitch Z", wxString::Format("0x%x", render->m_surface_pitch_z));
LIST_SETTINGS_ADD("Surface Offset A", wxString::Format("0x%x", render->m_surface_offset_a));
LIST_SETTINGS_ADD("Surface Offset B", wxString::Format("0x%x", render->m_surface_offset_b));
LIST_SETTINGS_ADD("Surface Offset C", wxString::Format("0x%x", render->m_surface_offset_c));
LIST_SETTINGS_ADD("Surface Offset D", wxString::Format("0x%x", render->m_surface_offset_d));
LIST_SETTINGS_ADD("Surface Offset Z", wxString::Format("0x%x", render->m_surface_offset_z));
LIST_SETTINGS_ADD("Viewport", wxString::Format("X:%d, Y:%d, W:%d, H:%d",
render.m_viewport_x,
render.m_viewport_y,
render.m_viewport_w,
render.m_viewport_h));
render->m_viewport_x,
render->m_viewport_y,
render->m_viewport_w,
render->m_viewport_h));
*/
#undef LIST_SETTINGS_ADD
}
@ -910,24 +924,24 @@ void RSXDebugger::SetFlags(wxListEvent& event)
GSRender& render = Emu.GetGSManager().GetRender();
switch(event.m_itemIndex)
{
case 0: render.m_set_alpha_test ^= true; break;
case 1: render.m_set_blend ^= true; break;
case 2: render.m_set_cull_face ^= true; break;
case 3: render.m_set_depth_bounds_test ^= true; break;
case 4: render.m_set_depth_test ^= true; break;
case 5: render.m_set_dither ^= true; break;
case 6: render.m_set_line_smooth ^= true; break;
case 7: render.m_set_logic_op ^= true; break;
case 8: render.m_set_poly_smooth ^= true; break;
case 9: render.m_set_poly_offset_fill ^= true; break;
case 10: render.m_set_poly_offset_line ^= true; break;
case 11: render.m_set_poly_offset_point ^= true; break;
case 12: render.m_set_stencil_test ^= true; break;
case 13: render.m_set_point_sprite_control ^= true; break;
case 14: render.m_set_restart_index ^= true; break;
case 15: render.m_set_specular ^= true; break;
case 16: render.m_set_scissor_horizontal ^= true; break;
case 17: render.m_set_scissor_vertical ^= true; break;
case 0: render->m_set_alpha_test ^= true; break;
case 1: render->m_set_blend ^= true; break;
case 2: render->m_set_cull_face ^= true; break;
case 3: render->m_set_depth_bounds_test ^= true; break;
case 4: render->m_set_depth_test ^= true; break;
case 5: render->m_set_dither ^= true; break;
case 6: render->m_set_line_smooth ^= true; break;
case 7: render->m_set_logic_op ^= true; break;
case 8: render->m_set_poly_smooth ^= true; break;
case 9: render->m_set_poly_offset_fill ^= true; break;
case 10: render->m_set_poly_offset_line ^= true; break;
case 11: render->m_set_poly_offset_point ^= true; break;
case 12: render->m_set_stencil_test ^= true; break;
case 13: render->m_set_point_sprite_control ^= true; break;
case 14: render->m_set_restart_index ^= true; break;
case 15: render->m_set_specular ^= true; break;
case 16: render->m_set_scissor_horizontal ^= true; break;
case 17: render->m_set_scissor_vertical ^= true; break;
}
*/
@ -936,40 +950,45 @@ void RSXDebugger::SetFlags(wxListEvent& event)
void RSXDebugger::SetPrograms(wxListEvent& event)
{
if (!RSXReady()) return;
GSRender& render = Emu.GetGSManager().GetRender();
RSXDebuggerProgram& program = m_debug_programs[event.m_itemIndex];
// Program Editor
wxString title = wxString::Format("Program ID: %d (VP:%d, FP:%d)", program.id, program.vp_id, program.fp_id);
wxDialog d_editor(this, wxID_ANY, title, wxDefaultPosition, wxSize(800,500),
wxDEFAULT_DIALOG_STYLE | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER);
wxBoxSizer& s_panel = *new wxBoxSizer(wxHORIZONTAL);
wxStaticBoxSizer& s_vp_box = *new wxStaticBoxSizer(wxHORIZONTAL, &d_editor, "Vertex Program");
wxStaticBoxSizer& s_fp_box = *new wxStaticBoxSizer(wxHORIZONTAL, &d_editor, "Fragment Program");
wxTextCtrl* t_vp_edit = new wxTextCtrl(&d_editor, wxID_ANY, program.vp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
wxTextCtrl* t_fp_edit = new wxTextCtrl(&d_editor, wxID_ANY, program.fp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
t_vp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
t_fp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
s_vp_box.Add(t_vp_edit, 1, wxEXPAND);
s_fp_box.Add(t_fp_edit, 1, wxEXPAND);
s_panel.Add(&s_vp_box, 1, wxEXPAND);
s_panel.Add(&s_fp_box, 1, wxEXPAND);
d_editor.SetSizer(&s_panel);
// Show editor and open Save Dialog when closing
if (d_editor.ShowModal())
const auto render = fxm::get<GSRender>();
if (!render)
{
wxMessageDialog d_save(&d_editor, "Save changes and compile shaders?", title, wxYES_NO|wxCENTRE);
if(d_save.ShowModal() == wxID_YES)
{
program.modified = true;
program.vp_shader = t_vp_edit->GetValue();
program.fp_shader = t_fp_edit->GetValue();
return;
}
}
UpdateInformation();
return;
//RSXDebuggerProgram& program = m_debug_programs[event.m_itemIndex];
//// Program Editor
//wxString title = wxString::Format("Program ID: %d (VP:%d, FP:%d)", program.id, program.vp_id, program.fp_id);
//wxDialog d_editor(this, wxID_ANY, title, wxDefaultPosition, wxSize(800,500),
// wxDEFAULT_DIALOG_STYLE | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER);
//wxBoxSizer& s_panel = *new wxBoxSizer(wxHORIZONTAL);
//wxStaticBoxSizer& s_vp_box = *new wxStaticBoxSizer(wxHORIZONTAL, &d_editor, "Vertex Program");
//wxStaticBoxSizer& s_fp_box = *new wxStaticBoxSizer(wxHORIZONTAL, &d_editor, "Fragment Program");
//wxTextCtrl* t_vp_edit = new wxTextCtrl(&d_editor, wxID_ANY, program.vp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
//wxTextCtrl* t_fp_edit = new wxTextCtrl(&d_editor, wxID_ANY, program.fp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
//t_vp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
//t_fp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
//s_vp_box.Add(t_vp_edit, 1, wxEXPAND);
//s_fp_box.Add(t_fp_edit, 1, wxEXPAND);
//s_panel.Add(&s_vp_box, 1, wxEXPAND);
//s_panel.Add(&s_fp_box, 1, wxEXPAND);
//d_editor.SetSizer(&s_panel);
//// Show editor and open Save Dialog when closing
//if (d_editor.ShowModal())
//{
// wxMessageDialog d_save(&d_editor, "Save changes and compile shaders?", title, wxYES_NO|wxCENTRE);
// if(d_save.ShowModal() == wxID_YES)
// {
// program.modified = true;
// program.vp_shader = t_vp_edit->GetValue();
// program.fp_shader = t_fp_edit->GetValue();
// }
//}
//UpdateInformation();
}
void RSXDebugger::OnSelectTexture(wxListEvent& event)
@ -1145,8 +1164,3 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA
return disasm;
}
bool RSXDebugger::RSXReady()
{
return Emu.GetGSManager().IsInited();
}

View File

@ -70,7 +70,5 @@ public:
const char* ParseGCMEnum(u32 value, u32 type);
wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr);
bool RSXReady();
void SetPC(const uint pc) { m_addr = pc; }
};

View File

@ -0,0 +1,217 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "RegisterEditor.h"
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit registers")
, pc(_pc)
, cpu(_cpu)
, disasm(_disasm)
{
wxBoxSizer* s_panel_margin_x = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_panel_margin_y = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_panel = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_t1_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_t2_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_t3_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_b_panel = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Register: ");
t1_register = new wxComboBox(this, wxID_ANY);
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Value (Hex):");
t2_value = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, -1));
s_t1_panel->Add(t1_text);
s_t1_panel->AddSpacer(8);
s_t1_panel->Add(t1_register);
s_t2_panel->Add(t2_text);
s_t2_panel->AddSpacer(8);
s_t2_panel->Add(t2_value);
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
s_b_panel->AddSpacer(5);
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxLEFT, 0, 5);
s_panel->Add(s_t1_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t2_panel);
s_panel->AddSpacer(16);
s_panel->Add(s_b_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_y->Add(s_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_x->AddSpacer(12);
s_panel_margin_x->Add(s_panel_margin_y);
s_panel_margin_x->AddSpacer(12);
Bind(wxEVT_COMBOBOX, &RegisterEditorDialog::updateRegister, this);
switch (cpu->type)
{
case cpu_type::ppu:
for (int i = 0; i<32; i++) t1_register->Append(wxString::Format("GPR[%d]", i));
for (int i = 0; i<32; i++) t1_register->Append(wxString::Format("FPR[%d]", i));
for (int i = 0; i<32; i++) t1_register->Append(wxString::Format("VR[%d]", i));
t1_register->Append("CR");
t1_register->Append("LR");
t1_register->Append("CTR");
//t1_register->Append("XER");
//t1_register->Append("FPSCR");
break;
case cpu_type::spu:
for (int i = 0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]", i));
break;
default:
wxMessageBox("Not supported thread.", "Error");
return;
}
SetSizerAndFit(s_panel_margin_x);
if (ShowModal() == wxID_OK)
{
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
std::string value = fmt::ToUTF8(t2_value->GetValue());
switch (cpu->type)
{
case cpu_type::ppu:
{
auto& ppu = *static_cast<PPUThread*>(cpu);
while (value.length() < 32) value = "0" + value;
std::string::size_type first_brk = reg.find('[');
try
{
if (first_brk != std::string::npos)
{
long reg_index = atol(reg.substr(first_brk + 1, reg.length() - first_brk - 2).c_str());
if (reg.find("GPR") == 0 || reg.find("FPR") == 0)
{
unsigned long long reg_value;
reg_value = std::stoull(value.substr(16, 31), 0, 16);
if (reg.find("GPR") == 0) ppu.GPR[reg_index] = (u64)reg_value;
if (reg.find("FPR") == 0) (u64&)ppu.FPR[reg_index] = (u64)reg_value;
return;
}
if (reg.find("VR") == 0)
{
unsigned long long reg_value0;
unsigned long long reg_value1;
reg_value0 = std::stoull(value.substr(16, 31), 0, 16);
reg_value1 = std::stoull(value.substr(0, 15), 0, 16);
ppu.VR[reg_index]._u64[0] = (u64)reg_value0;
ppu.VR[reg_index]._u64[1] = (u64)reg_value1;
return;
}
}
if (reg == "LR" || reg == "CTR")
{
unsigned long long reg_value;
reg_value = std::stoull(value.substr(16, 31), 0, 16);
if (reg == "LR") ppu.LR = (u64)reg_value;
if (reg == "CTR") ppu.CTR = (u64)reg_value;
return;
}
if (reg == "CR")
{
unsigned long long reg_value;
reg_value = std::stoull(value.substr(24, 31), 0, 16);
if (reg == "CR") ppu.SetCR((u32)reg_value);
return;
}
}
catch (std::invalid_argument&)//if any of the stoull conversion fail
{
break;
}
break;
}
case cpu_type::spu:
{
auto& spu = *static_cast<SPUThread*>(cpu);
while (value.length() < 32) value = "0" + value;
std::string::size_type first_brk = reg.find('[');
if (first_brk != std::string::npos)
{
long reg_index;
reg_index = atol(reg.substr(first_brk + 1, reg.length() - 2).c_str());
if (reg.find("GPR") == 0)
{
ullong reg_value0;
ullong reg_value1;
try
{
reg_value0 = std::stoull(value.substr(16, 31), 0, 16);
reg_value1 = std::stoull(value.substr(0, 15), 0, 16);
}
catch (std::invalid_argument& /*e*/)
{
break;
}
spu.gpr[reg_index]._u64[0] = (u64)reg_value0;
spu.gpr[reg_index]._u64[1] = (u64)reg_value1;
return;
}
}
break;
}
}
wxMessageBox("This value could not be converted.\nNo changes were made.", "Error");
}
}
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
{
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
std::string str;
switch (cpu->type)
{
case cpu_type::ppu:
{
auto& ppu = *static_cast<PPUThread*>(cpu);
std::size_t first_brk = reg.find('[');
if (first_brk != -1)
{
long reg_index = std::atol(reg.substr(first_brk + 1, reg.length() - first_brk - 2).c_str());
if (reg.find("GPR") == 0) str = fmt::format("%016llx", ppu.GPR[reg_index]);
if (reg.find("FPR") == 0) str = fmt::format("%016llx", ppu.FPR[reg_index]);
if (reg.find("VR") == 0) str = fmt::format("%016llx%016llx", ppu.VR[reg_index]._u64[1], ppu.VR[reg_index]._u64[0]);
}
if (reg == "CR") str = fmt::format("%08x", ppu.GetCR());
if (reg == "LR") str = fmt::format("%016llx", ppu.LR);
if (reg == "CTR") str = fmt::format("%016llx", ppu.CTR);
break;
}
case cpu_type::spu:
{
auto& spu = *static_cast<SPUThread*>(cpu);
std::string::size_type first_brk = reg.find('[');
if (first_brk != std::string::npos)
{
long reg_index;
reg_index = atol(reg.substr(first_brk + 1, reg.length() - 2).c_str());
if (reg.find("GPR") == 0) str = fmt::format("%016llx%016llx", spu.gpr[reg_index]._u64[1], spu.gpr[reg_index]._u64[0]);
}
break;
}
}
t2_value->SetValue(fmt::FromUTF8(str));
}

View File

@ -2,107 +2,17 @@
class RegisterEditorDialog : public wxDialog
{
u64 pc;
u32 pc;
CPUDisAsm* disasm;
CPUDecoder* decoder;
wxComboBox* t1_register;
wxTextCtrl* t2_value;
wxStaticText* t3_preview;
public:
CPUThread* CPU;
cpu_thread* cpu;
public:
RegisterEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm);
RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm);
void updateRegister(wxCommandEvent& event);
void updatePreview(wxCommandEvent& event);
};
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit registers")
, pc(_pc)
, CPU(_CPU)
, decoder(_decoder)
, disasm(_disasm)
{
wxBoxSizer* s_panel_margin_x = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_panel_margin_y = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_panel = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_t1_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_t2_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_t3_panel = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_b_panel = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Register: ");
t1_register = new wxComboBox(this, wxID_ANY);
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Value (Hex):");
t2_value = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1));
s_t1_panel->Add(t1_text);
s_t1_panel->AddSpacer(8);
s_t1_panel->Add(t1_register);
s_t2_panel->Add(t2_text);
s_t2_panel->AddSpacer(8);
s_t2_panel->Add(t2_value);
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
s_b_panel->AddSpacer(5);
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxLEFT, 0, 5);
s_panel->Add(s_t1_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t2_panel);
s_panel->AddSpacer(16);
s_panel->Add(s_b_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_y->Add(s_panel);
s_panel_margin_y->AddSpacer(12);
s_panel_margin_x->AddSpacer(12);
s_panel_margin_x->Add(s_panel_margin_y);
s_panel_margin_x->AddSpacer(12);
Bind(wxEVT_COMBOBOX, &RegisterEditorDialog::updateRegister, this);
switch(CPU->get_type())
{
case CPU_THREAD_PPU:
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("FPR[%d]",i));
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("VPR[%d]",i));
t1_register->Append("CR");
t1_register->Append("LR");
t1_register->Append("CTR");
t1_register->Append("XER");
t1_register->Append("FPSCR");
break;
case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU:
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
break;
default:
wxMessageBox("Not supported thread.", "Error");
return;
}
SetSizerAndFit(s_panel_margin_x);
if(ShowModal() == wxID_OK)
{
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
std::string value = fmt::ToUTF8(t2_value->GetValue());
if (!CPU->WriteRegString(reg,value))
wxMessageBox("This value could not be converted.\nNo changes were made.","Error");
}
}
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
{
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
t2_value->SetValue(fmt::FromUTF8(CPU->ReadRegString(reg)));
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "Emu/SysCalls/Modules/cellSaveData.h"
#include "Emu/Cell/Modules/cellSaveData.h"
class SaveDialogFrame : public SaveDialogBase
{

View File

@ -18,7 +18,7 @@ SaveDataInfoDialog::SaveDataInfoDialog(wxWindow* parent, const SaveDataInformati
wxBoxSizer* s_actions = new wxBoxSizer(wxHORIZONTAL);
s_actions->Add(0, 0, 1, wxEXPAND, 5); //Add a spacer to make Close on the Right-Down corner of this dialog.
s_actions->Add(new wxButton(this, wxID_CANCEL, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_actions->Add(new wxButton(this, wxID_CANCEL, "&Close", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_main->Add(s_actions, 0, wxEXPAND, 5);
SetSizerAndFit(s_main);
@ -78,20 +78,20 @@ SaveDataManageDialog::SaveDataManageDialog(wxWindow* parent, unsigned int* sort_
wxBoxSizer* s_manage = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_sort = new wxBoxSizer(wxHORIZONTAL);
s_sort->Add(new wxStaticText(this, wxID_ANY, wxT("Sort By"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL | wxEXPAND, 5);
s_sort->Add(new wxStaticText(this, wxID_ANY, "Sort By", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL | wxEXPAND, 5);
m_sort_options = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN | wxCB_READONLY);
//You might change this - of corse we should know what to been set - maybe after functions related been implemented.
m_sort_options->Append(wxT("User Id"));
m_sort_options->Append(wxT("Game Title"));
m_sort_options->Append(wxT("Game Subtitle"));
m_sort_options->Append(wxT("Play Time"));
m_sort_options->Append(wxT("Data Size"));
m_sort_options->Append(wxT("Last Modified"));
m_sort_options->Append(wxT("Created Time"));
m_sort_options->Append(wxT("Accessed Time"));
m_sort_options->Append(wxT("Modified Time"));
m_sort_options->Append(wxT("Modify Time"));
m_sort_options->Append("User Id");
m_sort_options->Append("Game Title");
m_sort_options->Append("Game Subtitle");
m_sort_options->Append("Play Time");
m_sort_options->Append("Data Size");
m_sort_options->Append("Last Modified");
m_sort_options->Append("Created Time");
m_sort_options->Append("Accessed Time");
m_sort_options->Append("Modified Time");
m_sort_options->Append("Modify Time");
m_sort_type = sort_type;
if (m_sort_type != nullptr)
@ -106,7 +106,7 @@ SaveDataManageDialog::SaveDataManageDialog(wxWindow* parent, unsigned int* sort_
m_sort_options->SetSelection(*m_sort_type);
s_sort->Add(m_sort_options, 1, wxALL | wxEXPAND, 5);
wxButton* s_sort_action = new wxButton(this, wxID_ANY, wxT("&Apply"), wxDefaultPosition, wxDefaultSize, 0);
wxButton* s_sort_action = new wxButton(this, wxID_ANY, "&Apply", wxDefaultPosition, wxDefaultSize, 0);
s_sort_action->Bind(wxEVT_BUTTON, &SaveDataManageDialog::OnApplySort, this);
s_sort->Add(s_sort_action, 0, wxALL, 5);
@ -114,19 +114,19 @@ SaveDataManageDialog::SaveDataManageDialog(wxWindow* parent, unsigned int* sort_
wxBoxSizer* s_actions = new wxBoxSizer(wxHORIZONTAL);
wxButton* s_copy = new wxButton(this, wxID_ANY, wxT("&Copy"), wxDefaultPosition, wxDefaultSize, 0);
wxButton* s_copy = new wxButton(this, wxID_ANY, "&Copy", wxDefaultPosition, wxDefaultSize, 0);
s_copy->Bind(wxEVT_BUTTON, &SaveDataManageDialog::OnCopy, this);
s_actions->Add(s_copy, 0, wxALL, 5);
wxButton* s_delete = new wxButton(this, wxID_ANY, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0);
wxButton* s_delete = new wxButton(this, wxID_ANY, "&Delete", wxDefaultPosition, wxDefaultSize, 0);
s_delete->Bind(wxEVT_BUTTON, &SaveDataManageDialog::OnDelete, this);
s_actions->Add(s_delete, 0, wxALL, 5);
wxButton* s_info = new wxButton(this, wxID_ANY, wxT("&Info"), wxDefaultPosition, wxDefaultSize, 0);
wxButton* s_info = new wxButton(this, wxID_ANY, "&Info", wxDefaultPosition, wxDefaultSize, 0);
s_info->Bind(wxEVT_BUTTON, &SaveDataManageDialog::OnInfo, this);
s_actions->Add(s_info, 0, wxALL, 5);
s_actions->Add(new wxButton(this, wxID_CANCEL, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_actions->Add(new wxButton(this, wxID_CANCEL, "&Close", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_manage->Add(s_actions, 1, wxEXPAND, 5);
@ -191,20 +191,20 @@ SaveDataListDialog::SaveDataListDialog(wxWindow* parent, bool enable_manage)
//If do not need manage, hide it, like just a save data picker.
if (!enable_manage)
{
wxButton *m_select = new wxButton(this, wxID_OK, wxT("&Select"), wxDefaultPosition, wxDefaultSize, 0);
wxButton *m_select = new wxButton(this, wxID_OK, "&Select", wxDefaultPosition, wxDefaultSize, 0);
m_select->Bind(wxEVT_BUTTON, &SaveDataListDialog::OnSelect, this);
s_action->Add(m_select, 0, wxALL, 5);
SetTitle("Save Data Chooser");
}
else {
wxButton *m_manage = new wxButton(this, wxID_ANY, wxT("&Manage"), wxDefaultPosition, wxDefaultSize, 0);
wxButton *m_manage = new wxButton(this, wxID_ANY, "&Manage", wxDefaultPosition, wxDefaultSize, 0);
m_manage->Bind(wxEVT_BUTTON, &SaveDataListDialog::OnManage, this);
s_action->Add(m_manage, 0, wxALL, 5);
}
s_action->Add(0, 0, 1, wxEXPAND, 5);
s_action->Add(new wxButton(this, wxID_CANCEL, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_action->Add(new wxButton(this, wxID_CANCEL, "&Close", wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5);
s_main->Add(s_action, 0, wxEXPAND, 5);

View File

@ -1,96 +1,215 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Utilities/Config.h"
#include "Loader/ELF.h"
#include "Emu/System.h"
#include "Emu/state.h"
#include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "SettingsDialog.h"
#ifdef _WIN32
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#undef GetHwnd
#ifdef _MSC_VER
#include <Windows.h>
#undef GetHwnd
#include <d3d12.h>
#include <wrl/client.h>
#include <dxgi1_4.h>
#endif
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif
std::vector<std::string> GetAdapters()
{
std::vector<std::string> adapters;
#ifdef _WIN32
PIP_ADAPTER_INFO pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);
#include "SettingsDialog.h"
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
#include <set>
// Node location
using cfg_location = std::vector<const char*>;
extern std::string g_cfg_defaults;
static YAML::Node loaded;
static YAML::Node saved;
// Emit sorted YAML
static never_inline void emit(YAML::Emitter& out, const YAML::Node& node)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(buflen);
// TODO
out << node;
}
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
// Incrementally load YAML
static never_inline void operator +=(YAML::Node& left, const YAML::Node& node)
{
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter)
if (node && !node.IsNull())
{
adapters.emplace_back(pAdapter->Description);
pAdapter = pAdapter->Next;
}
if (node.IsMap())
{
for (const auto& pair : node)
{
if (pair.first.IsScalar())
{
auto&& lhs = left[pair.first.Scalar()];
lhs += pair.second;
}
else
{
LOG_ERROR(HLE, "Call to GetAdaptersInfo failed.");
// Exotic case (TODO: probably doesn't work)
auto&& lhs = left[YAML::Clone(pair.first)];
lhs += pair.second;
}
#else
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
}
}
else if (node.IsScalar() || node.IsSequence())
{
LOG_ERROR(HLE, "Call to getifaddrs returned negative.");
// Scalars and sequences are replaced completely, but this may change in future.
// This logic may be overwritten by custom demands of every specific cfg:: node.
left = node;
}
}
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
// Connects wx gui element to the config node; abstract base class
struct cfg_adapter
{
if (ifa->ifa_addr == NULL)
cfg_location location;
cfg_adapter(cfg_location&& _loc)
: location(std::move(_loc))
{
continue;
}
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6)
static cfg::entry_base& get_cfg(cfg::entry_base& root, cfg_location::const_iterator begin, cfg_location::const_iterator end)
{
adapters.emplace_back(ifa->ifa_name);
return begin == end ? root : get_cfg(root[*begin], begin + 1, end);
}
static YAML::Node get_node(YAML::Node node, cfg_location::const_iterator begin, cfg_location::const_iterator end)
{
return begin == end ? node : get_node(node[*begin], begin + 1, end); // TODO
}
cfg::entry_base& get_cfg() const
{
return get_cfg(cfg::root, location.cbegin(), location.cend());
}
YAML::Node get_node(YAML::Node root) const
{
return get_node(root, location.cbegin(), location.cend());
}
virtual void save() = 0;
};
struct radiobox_pad_helper
{
cfg_location location;
wxArrayString values;
radiobox_pad_helper(cfg_location&& _loc)
: location(std::move(_loc))
{
for (const auto& v : cfg_adapter::get_cfg(cfg::root, location.cbegin(), location.cend()).to_list())
{
values.Add(fmt::FromUTF8(v));
}
}
freeifaddrs(ifaddr);
#endif
operator const wxArrayString&() const
{
return values;
}
};
return adapters;
struct radiobox_pad : cfg_adapter
{
wxRadioBox*& ptr;
radiobox_pad(radiobox_pad_helper&& helper, wxRadioBox*& ptr)
: cfg_adapter(std::move(helper.location))
, ptr(ptr)
{
const auto& value = get_node(loaded).Scalar();
const auto& values = get_cfg().to_list();
for (int i = 0; i < values.size(); i++)
{
if (value == values[i])
{
ptr->SetSelection(i);
return;
}
}
}
void save() override
{
get_node(saved) = get_cfg().to_list()[ptr->GetSelection()];
}
};
SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
struct combobox_pad : cfg_adapter
{
wxComboBox*& ptr;
combobox_pad(cfg_location&& _loc, wxComboBox*& ptr)
: cfg_adapter(std::move(_loc))
, ptr(ptr)
{
for (const auto& v : get_cfg().to_list())
{
ptr->Append(fmt::FromUTF8(v));
}
ptr->SetValue(fmt::FromUTF8(get_node(loaded).Scalar()));
}
void save() override
{
get_node(saved) = fmt::ToUTF8(ptr->GetValue());
}
};
struct checkbox_pad : cfg_adapter
{
wxCheckBox*& ptr;
checkbox_pad(cfg_location&& _loc, wxCheckBox*& ptr)
: cfg_adapter(std::move(_loc))
, ptr(ptr)
{
ptr->SetValue(get_node(loaded).as<bool>(false));
}
void save() override
{
get_node(saved) = ptr->GetValue() ? "true" : "false";
}
};
struct textctrl_pad : cfg_adapter
{
wxTextCtrl*& ptr;
textctrl_pad(cfg_location&& _loc, wxTextCtrl*& ptr)
: cfg_adapter(std::move(_loc))
, ptr(ptr)
{
ptr->SetValue(fmt::FromUTF8(get_node(loaded).Scalar()));
}
void save() override
{
get_node(saved) = fmt::ToUTF8(ptr->GetValue());
}
};
SettingsDialog::SettingsDialog(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "Settings", wxDefaultPosition)
{
const bool was_running = Emu.Pause();
if (was_running || Emu.IsReady()) cfg = &rpcs3::state.config;
// Load default config
loaded = YAML::Load(g_cfg_defaults);
// Incrementally load config.yml
const fs::file config(fs::get_config_dir() + "/config.yml", fs::read + fs::write + fs::create);
loaded += YAML::Load(config.to_string());
std::vector<std::unique_ptr<cfg_adapter>> pads;
static const u32 width = 458;
static const u32 height = 400;
@ -105,13 +224,13 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
wxPanel* p_misc = new wxPanel(nb_config, wxID_ANY);
wxPanel* p_networking = new wxPanel(nb_config, wxID_ANY);
nb_config->AddPage(p_core, wxT("Core"));
nb_config->AddPage(p_graphics, wxT("Graphics"));
nb_config->AddPage(p_audio, wxT("Audio"));
nb_config->AddPage(p_io, wxT("Input / Output"));
nb_config->AddPage(p_misc, wxT("Miscellaneous"));
nb_config->AddPage(p_networking, wxT("Networking"));
nb_config->AddPage(p_system, wxT("System"));
nb_config->AddPage(p_core, "Core");
nb_config->AddPage(p_graphics, "Graphics");
nb_config->AddPage(p_audio, "Audio");
nb_config->AddPage(p_io, "Input / Output");
nb_config->AddPage(p_misc, "Misc");
nb_config->AddPage(p_networking, "Networking");
nb_config->AddPage(p_system, "System");
wxBoxSizer* s_subpanel_core = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* s_subpanel_core1 = new wxBoxSizer(wxVERTICAL);
@ -128,43 +247,38 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
wxBoxSizer* s_subpanel_misc = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_networking = new wxBoxSizer(wxVERTICAL);
// Core settings
wxStaticBoxSizer* s_round_llvm = new wxStaticBoxSizer(wxVERTICAL, p_core, _("LLVM config"));
wxStaticBoxSizer* s_round_llvm_range = new wxStaticBoxSizer(wxHORIZONTAL, p_core, _("Excluded block range"));
wxStaticBoxSizer* s_round_llvm_threshold = new wxStaticBoxSizer(wxHORIZONTAL, p_core, _("Compilation threshold"));
// Core
wxStaticBoxSizer* s_round_core_lle = new wxStaticBoxSizer(wxVERTICAL, p_core, "Load libraries");
wxCheckListBox* chbox_list_core_lle = new wxCheckListBox(p_core, wxID_ANY, wxDefaultPosition, wxDefaultSize, {}, wxLB_EXTENDED);
// Graphics
wxStaticBoxSizer* s_round_gs_render = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Render"));
wxStaticBoxSizer* s_round_gs_d3d_adaptater = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("D3D Adaptater"));
wxStaticBoxSizer* s_round_gs_res = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Resolution"));
wxStaticBoxSizer* s_round_gs_aspect = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Aspect ratio"));
wxStaticBoxSizer* s_round_gs_frame_limit = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Frame limit"));
wxStaticBoxSizer* s_round_gs_render = new wxStaticBoxSizer(wxVERTICAL, p_graphics, "Render");
wxStaticBoxSizer* s_round_gs_d3d_adapter = new wxStaticBoxSizer(wxVERTICAL, p_graphics, "D3D Adaptater");
wxStaticBoxSizer* s_round_gs_res = new wxStaticBoxSizer(wxVERTICAL, p_graphics, "Resolution");
wxStaticBoxSizer* s_round_gs_aspect = new wxStaticBoxSizer(wxVERTICAL, p_graphics, "Aspect ratio");
wxStaticBoxSizer* s_round_gs_frame_limit = new wxStaticBoxSizer(wxVERTICAL, p_graphics, "Frame limit");
// Input / Output
wxStaticBoxSizer* s_round_io_pad_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Pad Handler"));
wxStaticBoxSizer* s_round_io_keyboard_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Keyboard Handler"));
wxStaticBoxSizer* s_round_io_mouse_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Mouse Handler"));
wxStaticBoxSizer* s_round_io_camera = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Camera"));
wxStaticBoxSizer* s_round_io_camera_type = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Camera type"));
wxStaticBoxSizer* s_round_io_pad_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, "Pad Handler");
wxStaticBoxSizer* s_round_io_keyboard_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, "Keyboard Handler");
wxStaticBoxSizer* s_round_io_mouse_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, "Mouse Handler");
wxStaticBoxSizer* s_round_io_camera = new wxStaticBoxSizer(wxVERTICAL, p_io, "Camera");
wxStaticBoxSizer* s_round_io_camera_type = new wxStaticBoxSizer(wxVERTICAL, p_io, "Camera type");
// Audio
wxStaticBoxSizer* s_round_audio_out = new wxStaticBoxSizer(wxVERTICAL, p_audio, _("Audio Out"));
// Miscellaneous
wxStaticBoxSizer* s_round_hle_log_lvl = new wxStaticBoxSizer(wxVERTICAL, p_misc, _("Log Level"));
wxStaticBoxSizer* s_round_audio_out = new wxStaticBoxSizer(wxVERTICAL, p_audio, "Audio Out");
// Networking
wxStaticBoxSizer* s_round_net_status = new wxStaticBoxSizer(wxVERTICAL, p_networking, _("Connection status"));
wxStaticBoxSizer* s_round_net_interface = new wxStaticBoxSizer(wxVERTICAL, p_networking, _("Network adapter"));
wxStaticBoxSizer* s_round_net_status = new wxStaticBoxSizer(wxVERTICAL, p_networking, "Connection status");
// System
wxStaticBoxSizer* s_round_sys_lang = new wxStaticBoxSizer(wxVERTICAL, p_system, _("Language"));
wxStaticBoxSizer* s_round_sys_lang = new wxStaticBoxSizer(wxVERTICAL, p_system, "Language");
wxRadioBox* rbox_ppu_decoder;
wxRadioBox* rbox_spu_decoder;
wxComboBox* cbox_gs_render = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_gs_d3d_adaptater = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_gs_d3d_adapter = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_gs_resolution = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_gs_aspect = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_gs_frame_limit = new wxComboBox(p_graphics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
@ -174,14 +288,12 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
wxComboBox* cbox_camera = new wxComboBox(p_io, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_camera_type = new wxComboBox(p_io, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_audio_out = new wxComboBox(p_audio, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_hle_loglvl = new wxComboBox(p_misc, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0, NULL, wxCB_READONLY);
wxComboBox* cbox_net_status = new wxComboBox(p_networking, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
wxComboBox* cbox_net_interface = new wxComboBox(p_networking, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
wxComboBox* cbox_sys_lang = new wxComboBox(p_system, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
wxCheckBox* chbox_core_llvm_exclud = new wxCheckBox(p_core, wxID_ANY, "Compiled blocks exclusion");
wxCheckBox* chbox_core_hook_stfunc = new wxCheckBox(p_core, wxID_ANY, "Hook static functions");
wxCheckBox* chbox_core_load_liblv2 = new wxCheckBox(p_core, wxID_ANY, "Load liblv2.sprx");
wxCheckBox* chbox_vfs_enable_host_root = new wxCheckBox(p_system, wxID_ANY, "Enable /host_root/");
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log shader programs");
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer");
wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers");
@ -193,195 +305,113 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
wxCheckBox* chbox_gs_overlay = new wxCheckBox(p_graphics, wxID_ANY, "Debug overlay");
wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file");
wxCheckBox* chbox_audio_conv = new wxCheckBox(p_audio, wxID_ANY, "Convert to 16 bit");
wxCheckBox* chbox_rsx_logging = new wxCheckBox(p_misc, wxID_ANY, "RSX Logging");
wxCheckBox* chbox_hle_exitonstop = new wxCheckBox(p_misc, wxID_ANY, "Exit RPCS3 when process finishes");
wxCheckBox* chbox_hle_always_start = new wxCheckBox(p_misc, wxID_ANY, "Always start after boot");
wxCheckBox* chbox_hle_use_default_ini = new wxCheckBox(p_misc, wxID_ANY, "Use default configuration");
wxTextCtrl* txt_dbg_range_min = new wxTextCtrl(p_core, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(55, 20));
wxTextCtrl* txt_dbg_range_max = new wxTextCtrl(p_core, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(55, 20));
wxTextCtrl* txt_llvm_threshold = new wxTextCtrl(p_core, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(55, 20));
//Auto Pause
wxCheckBox* chbox_dbg_ap_systemcall = new wxCheckBox(p_misc, wxID_ANY, "Auto Pause at System Call");
wxCheckBox* chbox_dbg_ap_functioncall = new wxCheckBox(p_misc, wxID_ANY, "Auto Pause at Function Call");
//Custom EmulationDir
wxCheckBox* chbox_emulationdir_enable = new wxCheckBox(p_system, wxID_ANY, "Use path below as EmulationDir. (Restart required)");
wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, fs::get_executable_dir());
std::vector<std::string> lle_module_list;
{
auto&& data = loaded["Core"]["Load libraries"].as<std::vector<std::string>, std::initializer_list<std::string>>({});
// List selected modules first
for (const auto& unk : data)
{
chbox_list_core_lle->Check(chbox_list_core_lle->Append(unk));
lle_module_list.push_back(unk);
}
wxArrayString ppu_decoder_modes;
ppu_decoder_modes.Add("Interpreter");
ppu_decoder_modes.Add("Interpreter 2");
ppu_decoder_modes.Add("Recompiler (LLVM)");
rbox_ppu_decoder = new wxRadioBox(p_core, wxID_ANY, "PPU Decoder", wxDefaultPosition, wxSize(215, -1), ppu_decoder_modes, 1);
const std::string& lle_dir = vfs::get("/dev_flash/sys/external/"); // TODO
#if !defined(LLVM_AVAILABLE)
rbox_ppu_decoder->Enable(2, false);
#endif
std::unordered_set<std::string> set(data.begin(), data.end());
wxArrayString spu_decoder_modes;
spu_decoder_modes.Add("Interpreter (precise)");
spu_decoder_modes.Add("Interpreter (fast)");
spu_decoder_modes.Add("Recompiler (ASMJIT)");
rbox_spu_decoder = new wxRadioBox(p_core, wxID_ANY, "SPU Decoder", wxDefaultPosition, wxSize(215, -1), spu_decoder_modes, 1);
for (const auto& prxf : fs::dir(lle_dir))
{
// List found unselected modules
if (!prxf.is_directory && ppu_prx_loader(fs::file(lle_dir + prxf.name)) == elf_error::ok && !set.count(prxf.name))
{
chbox_list_core_lle->Check(chbox_list_core_lle->Append(prxf.name), false);
lle_module_list.push_back(prxf.name);
}
}
}
cbox_gs_render->Append("Null");
cbox_gs_render->Append("OpenGL");
cbox_gs_render->Append("Vulkan");
radiobox_pad_helper ppu_decoder_modes({ "Core", "PPU Decoder" });
rbox_ppu_decoder = new wxRadioBox(p_core, wxID_ANY, "PPU Decoder", wxDefaultPosition, wxSize(-1, -1), ppu_decoder_modes, 1);
pads.emplace_back(std::make_unique<radiobox_pad>(std::move(ppu_decoder_modes), rbox_ppu_decoder));
rbox_ppu_decoder->Enable(2, false); // TODO
radiobox_pad_helper spu_decoder_modes({ "Core", "SPU Decoder" });
rbox_spu_decoder = new wxRadioBox(p_core, wxID_ANY, "SPU Decoder", wxDefaultPosition, wxSize(-1, -1), spu_decoder_modes, 1);
pads.emplace_back(std::make_unique<radiobox_pad>(std::move(spu_decoder_modes), rbox_spu_decoder));
rbox_spu_decoder->Enable(3, false); // TODO
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Core", "Hook static functions" }, chbox_core_hook_stfunc));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Core", "Load liblv2.sprx only" }, chbox_core_load_liblv2));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "VFS", "Enable /host_root/" }, chbox_vfs_enable_host_root));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Renderer" }, cbox_gs_render));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Resolution" }, cbox_gs_resolution));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Aspect ratio" }, cbox_gs_aspect));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Frame limit" }, cbox_gs_frame_limit));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Log shader programs" }, chbox_gs_log_prog));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Write Depth Buffer" }, chbox_gs_dump_depth));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Write Color Buffers" }, chbox_gs_dump_color));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Read Color Buffers" }, chbox_gs_read_color));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Read Depth Buffer" }, chbox_gs_read_depth));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "VSync" }, chbox_gs_vsync));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Debug output" }, chbox_gs_debug_output));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "3D Monitor" }, chbox_gs_3dmonitor));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Video", "Debug overlay" }, chbox_gs_overlay));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Audio", "Renderer" }, cbox_audio_out));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Audio", "Dump to file" }, chbox_audio_dump));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Audio", "Convert to 16 bit" }, chbox_audio_conv));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Input/Output", "Pad" }, cbox_pad_handler));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Input/Output", "Keyboard" }, cbox_keyboard_handler));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Input/Output", "Mouse" }, cbox_mouse_handler));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Input/Output", "Camera" }, cbox_camera));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Input/Output", "Camera type" }, cbox_camera_type));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Net", "Connection status" }, cbox_net_status));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "System", "Language" }, cbox_sys_lang));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Miscellaneous", "Exit RPCS3 when process finishes" }, chbox_hle_exitonstop));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Miscellaneous", "Always start after boot" }, chbox_hle_always_start));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Miscellaneous", "Auto Pause at System Call" }, chbox_dbg_ap_systemcall));
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Miscellaneous", "Auto Pause at Function Call" }, chbox_dbg_ap_functioncall));
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "D3D12", "Adapter" }, cbox_gs_d3d_adapter));
#ifdef _MSC_VER
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgiFactory;
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
if (SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))))
{
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
if (SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgiFactory))))
for (UINT id = 0; dxgi_factory->EnumAdapters(id, adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++)
{
cbox_gs_render->Append("DirectX 12");
for (uint id = 0; dxgiFactory->EnumAdapters(id, adapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++)
{
DXGI_ADAPTER_DESC adapterDesc;
adapter->GetDesc(&adapterDesc);
cbox_gs_d3d_adaptater->Append(adapterDesc.Description);
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
cbox_gs_d3d_adapter->Append(desc.Description);
}
}
else
#endif
{
cbox_gs_d3d_adaptater->Enable(false);
chbox_gs_overlay->Enable(false);
cbox_gs_d3d_adapter->Enable(false);
}
#endif
for (int i = 1; i < WXSIZEOF(ResolutionTable); ++i)
{
cbox_gs_resolution->Append(wxString::Format("%dx%d", ResolutionTable[i].width.value(), ResolutionTable[i].height.value()));
}
cbox_gs_aspect->Append("4:3");
cbox_gs_aspect->Append("16:9");
for (auto item : { "Off", "50", "59.94", "30", "60", "Auto" })
cbox_gs_frame_limit->Append(item);
cbox_pad_handler->Append("Null");
cbox_pad_handler->Append("Windows");
#ifdef _MSC_VER
cbox_pad_handler->Append("XInput");
#endif
//cbox_pad_handler->Append("DirectInput");
cbox_keyboard_handler->Append("Null");
cbox_keyboard_handler->Append("Windows");
//cbox_keyboard_handler->Append("DirectInput");
cbox_mouse_handler->Append("Null");
cbox_mouse_handler->Append("Windows");
//cbox_mouse_handler->Append("DirectInput");
cbox_audio_out->Append("Null");
cbox_audio_out->Append("OpenAL");
#ifdef _MSC_VER
cbox_audio_out->Append("XAudio2");
#endif
cbox_camera->Append("Null");
cbox_camera->Append("Connected");
cbox_camera_type->Append("Unknown");
cbox_camera_type->Append("EyeToy");
cbox_camera_type->Append("PlayStation Eye");
cbox_camera_type->Append("USB Video Class 1.1");
cbox_hle_loglvl->Append("Nothing");
cbox_hle_loglvl->Append("Fatal");
cbox_hle_loglvl->Append("Error");
cbox_hle_loglvl->Append("TODO");
cbox_hle_loglvl->Append("Success");
cbox_hle_loglvl->Append("Warning");
cbox_hle_loglvl->Append("Notice");
cbox_hle_loglvl->Append("All");
cbox_net_status->Append("IP Obtained");
cbox_net_status->Append("Obtaining IP");
cbox_net_status->Append("Connecting");
cbox_net_status->Append("Disconnected");
for(const auto& adapterName : GetAdapters())
cbox_net_interface->Append(adapterName);
static wxString s_langs[] =
{
"Japanese", "English (US)", "French", "Spanish", "German",
"Italian", "Dutch", "Portuguese (PT)", "Russian",
"Korean", "Chinese (Trad.)", "Chinese (Simp.)", "Finnish",
"Swedish", "Danish", "Norwegian", "Polish", "English (UK)"
};
for (const auto& lang : s_langs)
cbox_sys_lang->Append(lang);
chbox_core_llvm_exclud->SetValue(cfg->core.llvm.exclusion_range.value());
chbox_gs_log_prog->SetValue(rpcs3::config.rsx.log_programs.value());
chbox_gs_dump_depth->SetValue(cfg->rsx.opengl.write_depth_buffer.value());
chbox_gs_dump_color->SetValue(cfg->rsx.opengl.write_color_buffers.value());
chbox_gs_read_color->SetValue(cfg->rsx.opengl.read_color_buffers.value());
chbox_gs_read_depth->SetValue(cfg->rsx.opengl.read_depth_buffer.value());
chbox_gs_vsync->SetValue(rpcs3::config.rsx.vsync.value());
chbox_gs_debug_output->SetValue(cfg->rsx.d3d12.debug_output.value());
chbox_gs_3dmonitor->SetValue(rpcs3::config.rsx._3dtv.value());
chbox_gs_overlay->SetValue(cfg->rsx.d3d12.overlay.value());
chbox_audio_dump->SetValue(rpcs3::config.audio.dump_to_file.value());
chbox_audio_conv->SetValue(rpcs3::config.audio.convert_to_u16.value());
chbox_rsx_logging->SetValue(rpcs3::config.misc.log.rsx_logging.value());
chbox_hle_exitonstop->SetValue(rpcs3::config.misc.exit_on_stop.value());
chbox_hle_always_start->SetValue(rpcs3::config.misc.always_start.value());
chbox_hle_use_default_ini->SetValue(rpcs3::config.misc.use_default_ini.value());
chbox_core_hook_stfunc->SetValue(cfg->core.hook_st_func.value());
chbox_core_load_liblv2->SetValue(cfg->core.load_liblv2.value());
//Auto Pause related
chbox_dbg_ap_systemcall->SetValue(rpcs3::config.misc.debug.auto_pause_syscall.value());
chbox_dbg_ap_functioncall->SetValue(rpcs3::config.misc.debug.auto_pause_func_call.value());
//Custom EmulationDir
chbox_emulationdir_enable->SetValue(rpcs3::config.system.emulation_dir_path_enable.value());
txt_emulationdir_path->SetValue(rpcs3::config.system.emulation_dir_path.value());
rbox_ppu_decoder->SetSelection((int)cfg->core.ppu_decoder.value());
txt_dbg_range_min->SetValue(cfg->core.llvm.min_id.string_value());
txt_dbg_range_max->SetValue(cfg->core.llvm.max_id.string_value());
txt_llvm_threshold->SetValue(cfg->core.llvm.threshold.string_value());
rbox_spu_decoder->SetSelection((int)cfg->core.spu_decoder.value());
cbox_gs_render->SetSelection((int)cfg->rsx.renderer.value());
cbox_gs_d3d_adaptater->SetSelection(cfg->rsx.d3d12.adaptater.value());
cbox_gs_resolution->SetSelection(ResolutionIdToNum((int)cfg->rsx.resolution.value()) - 1);
cbox_gs_aspect->SetSelection((int)cfg->rsx.aspect_ratio.value() - 1);
cbox_gs_frame_limit->SetSelection((int)cfg->rsx.frame_limit.value());
cbox_pad_handler->SetSelection((int)cfg->io.pad_handler_mode.value());
cbox_keyboard_handler->SetSelection((int)cfg->io.keyboard_handler_mode.value());
cbox_mouse_handler->SetSelection((int)cfg->io.mouse_handler_mode.value());
cbox_audio_out->SetSelection((int)cfg->audio.out.value());
cbox_camera->SetSelection((int)cfg->io.camera.value());
cbox_camera_type->SetSelection((int)cfg->io.camera_type.value());
cbox_hle_loglvl->SetSelection((int)rpcs3::config.misc.log.level.value());
cbox_net_status->SetSelection((int)rpcs3::config.misc.net.status.value());
cbox_net_interface->SetSelection((int)rpcs3::config.misc.net._interface.value());
cbox_sys_lang->SetSelection((int)rpcs3::config.system.language.value());
// Core
s_round_llvm->Add(chbox_core_llvm_exclud, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_llvm_range->Add(txt_dbg_range_min, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_llvm_range->Add(txt_dbg_range_max, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_llvm->Add(s_round_llvm_range, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_llvm_threshold->Add(txt_llvm_threshold, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_llvm->Add(s_round_llvm_threshold, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_core_lle->Add(chbox_list_core_lle, wxSizerFlags().Border(wxALL, 5).Expand());
// Rendering
s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_gs_d3d_adaptater->Add(cbox_gs_d3d_adaptater, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_gs_d3d_adapter->Add(cbox_gs_d3d_adapter, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_gs_aspect->Add(cbox_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_gs_frame_limit->Add(cbox_gs_frame_limit, wxSizerFlags().Border(wxALL, 5).Expand());
@ -395,28 +425,25 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
s_round_audio_out->Add(cbox_audio_out, wxSizerFlags().Border(wxALL, 5).Expand());
// Miscellaneous
s_round_hle_log_lvl->Add(cbox_hle_loglvl, wxSizerFlags().Border(wxALL, 5).Expand());
// Networking
s_round_net_status->Add(cbox_net_status, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_net_interface->Add(cbox_net_interface, wxSizerFlags().Border(wxALL, 5).Expand());
// System
s_round_sys_lang->Add(cbox_sys_lang, wxSizerFlags().Border(wxALL, 5).Expand());
// Core
s_subpanel_core1->Add(rbox_ppu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core2->Add(rbox_spu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core1->Add(s_round_llvm, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core1->Add(rbox_spu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core1->Add(chbox_core_hook_stfunc, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core1->Add(chbox_core_load_liblv2, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core2->Add(s_round_core_lle, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_core->Add(s_subpanel_core1);
s_subpanel_core->Add(s_subpanel_core2);
// Graphics
s_subpanel_graphics1->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(s_round_gs_d3d_adaptater, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(s_round_gs_d3d_adapter, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(chbox_gs_read_color, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_graphics1->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand());
@ -447,11 +474,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
s_subpanel_audio->Add(chbox_audio_conv, wxSizerFlags().Border(wxALL, 5).Expand());
// Miscellaneous
s_subpanel_misc->Add(s_round_hle_log_lvl, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_misc->Add(chbox_rsx_logging, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_misc->Add(chbox_hle_exitonstop, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_misc->Add(chbox_hle_always_start, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_misc->Add(chbox_hle_use_default_ini, wxSizerFlags().Border(wxALL, 5).Expand());
// Auto Pause
s_subpanel_misc->Add(chbox_dbg_ap_systemcall, wxSizerFlags().Border(wxALL, 5).Expand());
@ -459,15 +483,11 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
// Networking
s_subpanel_networking->Add(s_round_net_status, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_networking->Add(s_round_net_interface, wxSizerFlags().Border(wxALL, 5).Expand());
// System
s_subpanel_system->Add(chbox_vfs_enable_host_root, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_system->Add(s_round_sys_lang, wxSizerFlags().Border(wxALL, 5).Expand());
// Custom EmulationDir
s_subpanel_system->Add(chbox_emulationdir_enable, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel_system->Add(txt_emulationdir_path, wxSizerFlags().Border(wxALL, 5).Expand());
// Buttons
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
s_b_panel->Add(new wxButton(this, wxID_OK), wxSizerFlags().Border(wxALL, 5).Bottom());
@ -487,74 +507,31 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
if (ShowModal() == wxID_OK)
{
long llvmthreshold;
long minllvmid, maxllvmid;
txt_dbg_range_min->GetValue().ToLong(&minllvmid);
txt_dbg_range_max->GetValue().ToLong(&maxllvmid);
txt_llvm_threshold->GetValue().ToLong(&llvmthreshold);
std::set<std::string> lle_selected;
// individual settings
cfg->core.ppu_decoder = rbox_ppu_decoder->GetSelection();
cfg->core.llvm.exclusion_range = chbox_core_llvm_exclud->GetValue();
cfg->core.llvm.min_id = minllvmid;
cfg->core.llvm.max_id = maxllvmid;
cfg->core.llvm.threshold = llvmthreshold;
cfg->core.spu_decoder = rbox_spu_decoder->GetSelection();
cfg->core.hook_st_func = chbox_core_hook_stfunc->GetValue();
cfg->core.load_liblv2 = chbox_core_load_liblv2->GetValue();
// Translates renderer string to enum class for config.h
if (cbox_gs_render->GetString(cbox_gs_render->GetSelection()) == "Null")
cfg->rsx.renderer = rsx_renderer_type::Null;
if (cbox_gs_render->GetString(cbox_gs_render->GetSelection()) == "OpenGL")
cfg->rsx.renderer = rsx_renderer_type::OpenGL;
if (cbox_gs_render->GetString(cbox_gs_render->GetSelection()) == "Vulkan")
cfg->rsx.renderer = rsx_renderer_type::Vulkan;
if (cbox_gs_render->GetString(cbox_gs_render->GetSelection()) == "DirectX 12")
cfg->rsx.renderer = rsx_renderer_type::DX12;
cfg->rsx.d3d12.adaptater = cbox_gs_d3d_adaptater->GetSelection();
cfg->rsx.resolution = ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1);
cfg->rsx.aspect_ratio = cbox_gs_aspect->GetSelection() + 1;
cfg->rsx.frame_limit = cbox_gs_frame_limit->GetSelection();
cfg->rsx.opengl.write_depth_buffer = chbox_gs_dump_depth->GetValue();
cfg->rsx.opengl.write_color_buffers = chbox_gs_dump_color->GetValue();
cfg->rsx.opengl.read_color_buffers = chbox_gs_read_color->GetValue();
cfg->rsx.opengl.read_depth_buffer = chbox_gs_read_depth->GetValue();
cfg->audio.out = cbox_audio_out->GetSelection();
cfg->io.pad_handler_mode = cbox_pad_handler->GetSelection();
cfg->io.keyboard_handler_mode = cbox_keyboard_handler->GetSelection();
cfg->io.mouse_handler_mode = cbox_mouse_handler->GetSelection();
cfg->io.camera = cbox_camera->GetSelection();
cfg->io.camera_type = cbox_camera_type->GetSelection();
// global settings
rpcs3::config.rsx.log_programs = chbox_gs_log_prog->GetValue();
rpcs3::config.rsx.vsync = chbox_gs_vsync->GetValue();
rpcs3::config.rsx._3dtv = chbox_gs_3dmonitor->GetValue();
rpcs3::config.rsx.d3d12.debug_output = chbox_gs_debug_output->GetValue();
rpcs3::config.rsx.d3d12.overlay = chbox_gs_overlay->GetValue();
rpcs3::config.audio.dump_to_file = chbox_audio_dump->GetValue();
rpcs3::config.audio.convert_to_u16 = chbox_audio_conv->GetValue();
rpcs3::config.misc.log.level = cbox_hle_loglvl->GetSelection();
rpcs3::config.misc.log.rsx_logging = chbox_rsx_logging->GetValue();
rpcs3::config.misc.net.status = cbox_net_status->GetSelection();
rpcs3::config.misc.net._interface = cbox_net_interface->GetSelection();
rpcs3::config.misc.debug.auto_pause_syscall = chbox_dbg_ap_systemcall->GetValue();
rpcs3::config.misc.debug.auto_pause_func_call = chbox_dbg_ap_functioncall->GetValue();
rpcs3::config.misc.always_start = chbox_hle_always_start->GetValue();
rpcs3::config.misc.exit_on_stop = chbox_hle_exitonstop->GetValue();
rpcs3::config.misc.use_default_ini = chbox_hle_use_default_ini->GetValue();
rpcs3::config.system.language = cbox_sys_lang->GetSelection();
rpcs3::config.system.emulation_dir_path_enable = chbox_emulationdir_enable->GetValue();
rpcs3::config.system.emulation_dir_path = txt_emulationdir_path->GetValue().ToStdString();
rpcs3::config.save();
cfg->save();
for (auto i = 0; i < lle_module_list.size(); i++)
{
if (chbox_list_core_lle->IsChecked(i))
{
lle_selected.emplace(lle_module_list[i]);
}
}
if (was_running) Emu.Resume();
saved.reset();
saved["Core"]["Load libraries"] = std::vector<std::string>(lle_selected.begin(), lle_selected.end());
for (auto& pad : pads)
{
pad->save();
}
loaded += saved;
YAML::Emitter out;
emit(out, loaded);
// Save config
config.seek(0);
config.trunc(0);
config.write(out.c_str(), out.size());
}
}

View File

@ -1,11 +1,7 @@
#pragma once
#include "config.h"
std::vector<std::string> GetAdapters();
class SettingsDialog : public wxDialog
{
public:
SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg = &rpcs3::config);
SettingsDialog(wxWindow* parent);
};

View File

@ -19,8 +19,8 @@ void SignInDialogFrame::Create()
wxButton* b_signin = new wxButton(p_esn, wxID_OK, "Fake sign in");
wxButton* b_cancel = new wxButton(p_esn, wxID_CANCEL, "Cancel");
nb_config->AddPage(p_esn, wxT("ESN"));
nb_config->AddPage(p_psn, wxT("PSN"));
nb_config->AddPage(p_esn, "ESN");
nb_config->AddPage(p_psn, "PSN");
wxBoxSizer* s_subpanel_esn = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* s_subpanel_psn = new wxBoxSizer(wxVERTICAL);

View File

@ -1,233 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/FS/VFS.h"
#include "VFSManager.h"
VFSEntrySettingsDialog::VFSEntrySettingsDialog(wxWindow* parent, VFSManagerEntry& entry)
: wxDialog(parent, wxID_ANY, "Mount configuration")
, m_entry(entry)
{
m_tctrl_dev_path = new wxTextCtrl(this, wxID_ANY);
m_btn_select_dev_path = new wxButton(this, wxID_ANY, "...");
m_tctrl_path = new wxTextCtrl(this, wxID_ANY);
m_btn_select_path = new wxButton(this, wxID_ANY, "...");
m_tctrl_mount = new wxTextCtrl(this, wxID_ANY);
m_ch_type = new wxChoice(this, wxID_ANY);
wxBoxSizer* s_type = new wxBoxSizer(wxHORIZONTAL);
s_type->Add(m_ch_type, 1, wxEXPAND);
wxBoxSizer* s_dev_path = new wxBoxSizer(wxHORIZONTAL);
s_dev_path->Add(m_tctrl_dev_path, 1, wxEXPAND);
s_dev_path->Add(m_btn_select_dev_path, 0, wxLEFT, 5);
wxBoxSizer* s_path = new wxBoxSizer(wxHORIZONTAL);
s_path->Add(m_tctrl_path, 1, wxEXPAND);
s_path->Add(m_btn_select_path, 0, wxLEFT, 5);
wxBoxSizer* s_mount = new wxBoxSizer(wxHORIZONTAL);
s_mount->Add(m_tctrl_mount, 1, wxEXPAND);
wxBoxSizer* s_btns = new wxBoxSizer(wxHORIZONTAL);
s_btns->Add(new wxButton(this, wxID_OK));
s_btns->AddSpacer(30);
s_btns->Add(new wxButton(this, wxID_CANCEL));
wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL);
s_main->Add(s_type, 1, wxEXPAND | wxALL, 10);
s_main->Add(s_dev_path, 1, wxEXPAND | wxALL, 10);
s_main->Add(s_path, 1, wxEXPAND | wxALL, 10);
s_main->Add(s_mount, 1, wxEXPAND | wxALL, 10);
s_main->AddSpacer(10);
s_main->Add(s_btns, 0, wxALL | wxCENTER, 10);
SetSizerAndFit(s_main);
SetSize(350, -1);
for(const auto i : vfsDeviceTypeNames)
{
m_ch_type->Append(i);
}
m_ch_type->Bind(wxEVT_CHOICE, &VFSEntrySettingsDialog::OnSelectType, this);
m_btn_select_path->Bind(wxEVT_BUTTON, &VFSEntrySettingsDialog::OnSelectPath, this);
m_btn_select_dev_path->Bind(wxEVT_BUTTON, &VFSEntrySettingsDialog::OnSelectDevPath, this);
Bind(wxEVT_BUTTON, &VFSEntrySettingsDialog::OnOk, this, wxID_OK);
m_tctrl_dev_path->SetValue(m_entry.device_path);
m_tctrl_path->SetValue(m_entry.path);
m_tctrl_mount->SetValue(m_entry.mount);
m_ch_type->SetSelection(m_entry.device);
wxCommandEvent ce;
OnSelectType(ce);
}
void VFSEntrySettingsDialog::OnSelectType(wxCommandEvent& event)
{
m_btn_select_path->Enable(m_ch_type->GetSelection() == vfsDevice_LocalFile);
m_tctrl_dev_path->Enable(m_ch_type->GetSelection() != vfsDevice_LocalFile);
m_btn_select_dev_path->Enable(m_ch_type->GetSelection() != vfsDevice_LocalFile);
}
void VFSEntrySettingsDialog::OnSelectPath(wxCommandEvent& event)
{
wxDirDialog ctrl(this, "Select path", wxGetCwd());
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
m_tctrl_path->SetValue(ctrl.GetPath());
}
void VFSEntrySettingsDialog::OnSelectDevPath(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select device");
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
m_tctrl_dev_path->SetValue(ctrl.GetPath());
}
void VFSEntrySettingsDialog::OnOk(wxCommandEvent& event)
{
m_entry.device_path = m_tctrl_dev_path->GetValue().ToStdString();
m_entry.path = m_tctrl_path->GetValue().ToStdString();
m_entry.mount = m_tctrl_mount->GetValue().ToStdString();
m_entry.device = (vfsDeviceType)m_ch_type->GetSelection();
EndModal(wxID_OK);
}
enum
{
id_add,
id_remove,
id_config,
};
VFSManagerDialog::VFSManagerDialog(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "Virtual File System Manager")
{
m_list = new wxListView(this);
wxBoxSizer* s_btns = new wxBoxSizer(wxHORIZONTAL);
s_btns->Add(new wxButton(this, wxID_OK));
s_btns->AddSpacer(30);
s_btns->Add(new wxButton(this, wxID_CANCEL));
wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL);
s_main->Add(m_list, 1, wxEXPAND);
s_main->Add(s_btns, 0, wxALL | wxCENTER, 10);
SetSizerAndFit(s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Path");
m_list->InsertColumn(1, "Device path");
m_list->InsertColumn(2, "Path to Device");
m_list->InsertColumn(3, "Device");
m_list->Bind(wxEVT_LIST_ITEM_ACTIVATED, &VFSManagerDialog::OnEntryConfig, this);
m_list->Bind(wxEVT_RIGHT_DOWN, &VFSManagerDialog::OnRightClick, this);
Bind(wxEVT_MENU, &VFSManagerDialog::OnAdd, this, id_add);
Bind(wxEVT_MENU, &VFSManagerDialog::OnRemove, this, id_remove);
Bind(wxEVT_MENU, &VFSManagerDialog::OnEntryConfig, this, id_config);
Bind(wxEVT_BUTTON, &VFSManagerDialog::OnOK, this, wxID_OK);
LoadEntries();
UpdateList();
}
void VFSManagerDialog::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
for(size_t i=0; i<m_entries.size(); ++i)
{
m_list->InsertItem(i, m_entries[i].mount);
m_list->SetItem(i, 1, m_entries[i].path);
m_list->SetItem(i, 2, m_entries[i].device_path);
m_list->SetItem(i, 3, vfsDeviceTypeNames[m_entries[i].device]);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VFSManagerDialog::OnEntryConfig(wxCommandEvent& event)
{
int idx = m_list->GetFirstSelected();
if(idx != wxNOT_FOUND)
{
VFSEntrySettingsDialog(this, m_entries[idx]).ShowModal();
UpdateList();
}
}
void VFSManagerDialog::OnRightClick(wxMouseEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_add, "Add");
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND);
menu->AppendSeparator();
menu->Append(id_config, "Config")->Enable(idx != wxNOT_FOUND);
PopupMenu(menu);
}
void VFSManagerDialog::OnAdd(wxCommandEvent& event)
{
m_entries.emplace_back(VFSManagerEntry());
UpdateList();
u32 idx = m_entries.size() - 1;
for(int i=0; i<m_list->GetItemCount(); ++i)
{
m_list->SetItemState(i, i == idx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
wxCommandEvent ce;
OnEntryConfig(ce);
}
void VFSManagerDialog::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1), offs = 0; sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel), --offs)
{
m_entries.erase(m_entries.begin() + (sel + offs));
}
UpdateList();
}
void VFSManagerDialog::OnOK(wxCommandEvent& event)
{
SaveEntries();
event.Skip();
}
void VFSManagerDialog::LoadEntries()
{
m_entries.clear();
Emu.GetVFS().SaveLoadDevices(m_entries, true);
}
void VFSManagerDialog::SaveEntries()
{
Emu.GetVFS().SaveLoadDevices(m_entries, false);
}

View File

@ -1,40 +0,0 @@
#pragma once
#include "Emu/FS/VFS.h"
class VFSEntrySettingsDialog : public wxDialog
{
wxTextCtrl* m_tctrl_dev_path;
wxButton* m_btn_select_dev_path;
wxTextCtrl* m_tctrl_path;
wxButton* m_btn_select_path;
wxTextCtrl* m_tctrl_mount;
wxChoice* m_ch_type;
VFSManagerEntry& m_entry;
public:
VFSEntrySettingsDialog(wxWindow* parent, VFSManagerEntry& entry);
void OnSelectType(wxCommandEvent& event);
void OnSelectPath(wxCommandEvent& event);
void OnSelectDevPath(wxCommandEvent& event);
void OnOk(wxCommandEvent& event);
};
class VFSManagerDialog : public wxDialog
{
wxListView* m_list;
std::vector<VFSManagerEntry> m_entries;
public:
VFSManagerDialog(wxWindow* parent);
void UpdateList();
void OnEntryConfig(wxCommandEvent& event);
void OnRightClick(wxMouseEvent& event);
void OnAdd(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnOK(wxCommandEvent& event);
void LoadEntries();
void SaveEntries();
};

View File

@ -1,545 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "VHDDManager.h"
#include "TextInputDialog.h"
#include "Emu/state.h"
VHDDListDropTarget::VHDDListDropTarget(wxListView* parent) : m_parent(parent)
{
SetDataObject(new wxDataObjectSimple(wxDF_PRIVATE));
}
wxDragResult VHDDListDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
{
int flags = 0;
int indx = m_parent->HitTest(wxPoint(x, y), flags);
for(int i=0; i<m_parent->GetItemCount(); ++i)
{
m_parent->SetItemState(i, i == indx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
return def;
}
void VHDDListDropTarget::OnLeave()
{
for(int i=0; i<m_parent->GetItemCount(); ++i)
{
m_parent->SetItemState(i, ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
}
wxDragResult VHDDListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
{
int flags = 0;
int dst_indx = m_parent->HitTest(wxPoint(x, y), flags);
LOG_NOTICE(HLE, "OnData(%d -> %d)", m_src_indx, dst_indx);
return def;
}
enum
{
id_open = 0x777,
id_rename,
id_remove,
id_create_dir,
id_create_file,
id_import,
id_export,
id_create_hdd,
id_add_hdd
};
VHDDExplorer::VHDDExplorer(wxWindow* parent, const std::string& hdd_path) : wxDialog(parent, wxID_ANY, "Virtual HDD Explorer", wxDefaultPosition)
{
m_list = new wxListView(this);
m_drop_target = new VHDDListDropTarget(m_list);
m_list->SetDropTarget(m_drop_target);
m_list->DragAcceptFiles(true);
wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL);
s_main->Add(m_list, 1, wxEXPAND | wxALL, 5);
SetSizerAndFit(s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Name");
m_list->InsertColumn(1, "Type");
m_list->InsertColumn(2, "Size");
m_list->InsertColumn(3, "Creation time");
m_hdd = new vfsHDD(nullptr, hdd_path);
UpdateList();
m_list->Bind(wxEVT_LIST_BEGIN_DRAG, &VHDDExplorer::OnListDrag, this);
m_list->Bind(wxEVT_LIST_ITEM_ACTIVATED, &VHDDExplorer::DClick, this);
m_list->Bind(wxEVT_RIGHT_DOWN, &VHDDExplorer::OnContextMenu, this);
m_list->Bind(wxEVT_DROP_FILES, &VHDDExplorer::OnDropFiles, this);
Bind(wxEVT_MENU, &VHDDExplorer::OnOpen, this, id_open);
Bind(wxEVT_MENU, &VHDDExplorer::OnRename, this, id_rename);
Bind(wxEVT_MENU, &VHDDExplorer::OnRemove, this, id_remove);
Bind(wxEVT_MENU, &VHDDExplorer::OnCreateDir, this, id_create_dir);
Bind(wxEVT_MENU, &VHDDExplorer::OnCreateFile, this, id_create_file);
Bind(wxEVT_MENU, &VHDDExplorer::OnImport, this, id_import);
Bind(wxEVT_MENU, &VHDDExplorer::OnExport, this, id_export);
}
void VHDDExplorer::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
m_entries.clear();
m_names.clear();
u64 block;
vfsHDD_Entry entry;
std::string name;
for(bool is_ok = m_hdd->GetFirstEntry(block, entry, name); is_ok; is_ok = m_hdd->GetNextEntry(block, entry, name))
{
int item = m_list->GetItemCount();
m_list->InsertItem(item, fmt::FromUTF8(name));
m_list->SetItem(item, 1, entry.type == vfsHDD_Entry_Dir ? "Dir" : "File");
m_list->SetItem(item, 2, wxString::Format("%lld", entry.size));
m_list->SetItem(item, 3, wxDateTime().Set(time_t(entry.ctime)).Format());
m_entries.push_back(entry);
m_names.push_back(name);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VHDDExplorer::Import(const std::string& path, const std::string& to)
{
if(!m_hdd->Create(vfsHDD_Entry_File, to))
{
wxMessageBox("IMPORT ERROR: file creation error.");
return;
}
if(!m_hdd->Open(to, fom::write))
{
wxMessageBox("IMPORT ERROR: file open error.");
return;
}
wxFile f(fmt::FromUTF8(path));
char buf[256];
while(!f.Eof())
{
m_hdd->Write(buf, f.Read(buf, 256));
}
m_hdd->Close();
}
void VHDDExplorer::Export(const std::string& path, const std::string& to)
{
if(!m_hdd->Open(path))
{
wxMessageBox(wxString::Format("EXPORT ERROR: file open error. (%s)", path.c_str()));
return;
}
wxFile f(fmt::FromUTF8(to), wxFile::write);
char buf[256];
while(u64 size = m_hdd->Read(buf, 256))
{
f.Write(buf, size);
}
}
void VHDDExplorer::OpenDir(int sel)
{
if(sel == wxNOT_FOUND)
{
return;
}
if(m_entries[sel].type == vfsHDD_Entry_Dir)
{
m_hdd->OpenDir(m_names[sel]);
UpdateList();
}
}
void VHDDExplorer::OnListDrag(wxListEvent& event)
{
m_drop_target->SetSrcIndx(event.GetIndex());
wxDataObjectSimple obj(wxDF_PRIVATE);
wxDropSource drag(obj, m_list);
drag.DoDragDrop(wxDrag_AllowMove);
}
void VHDDExplorer::OnDropFiles(wxDropFilesEvent& event)
{
int count = event.GetNumberOfFiles();
wxString* dropped = event.GetFiles();
wxBusyCursor busyCursor;
wxWindowDisabler disabler;
wxBusyInfo busyInfo("Adding files, wait please...");
for(int i=0; i<count; ++i)
{
LOG_NOTICE(HLE, "Importing '%s'", fmt::ToUTF8(dropped[i]).c_str());
Import(fmt::ToUTF8(dropped[i]), fmt::ToUTF8(wxFileName(dropped[i]).GetFullName()));
}
UpdateList();
}
void VHDDExplorer::DClick(wxListEvent& event)
{
OpenDir(event.GetIndex());
}
void VHDDExplorer::OnContextMenu(wxMouseEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_open, "Open")->Enable(idx != wxNOT_FOUND && m_entries[idx].type == vfsHDD_Entry_Dir);
menu->Append(id_rename, "Rename")->Enable(idx != wxNOT_FOUND && m_names[idx] != "." && m_names[idx] != "..");
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND && m_names[idx] != "." && m_names[idx] != "..");
menu->AppendSeparator();
menu->Append(id_create_dir, "Create dir");
menu->Append(id_create_file, "Create file");
menu->AppendSeparator();
menu->Append(id_import, "Import");
menu->Append(id_export, "Export")->Enable(idx != wxNOT_FOUND);
PopupMenu(menu);
}
void VHDDExplorer::OnOpen(wxCommandEvent& event)
{
m_hdd->OpenDir(m_names[m_list->GetFirstSelected()]);
UpdateList();
}
void VHDDExplorer::OnRename(wxCommandEvent& event)
{
TextInputDialog dial(this, m_names[m_list->GetFirstSelected()]);
if(dial.ShowModal() == wxID_OK)
{
m_hdd->Rename(m_names[m_list->GetFirstSelected()], dial.GetResult());
UpdateList();
}
}
void VHDDExplorer::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1); sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel))
{
m_hdd->RemoveEntry(m_names[sel]);
}
UpdateList();
}
void VHDDExplorer::OnCreateDir(wxCommandEvent& event)
{
int i = 1;
while(m_hdd->HasEntry(fmt::format("New Dir (%d)", i))) i++;
m_hdd->Create(vfsHDD_Entry_Dir, fmt::format("New Dir (%d)", i));
UpdateList();
}
void VHDDExplorer::OnCreateFile(wxCommandEvent& event)
{
int i = 1;
while (m_hdd->HasEntry(fmt::format("New File (%d)", i))) i++;
m_hdd->Create(vfsHDD_Entry_File, fmt::format("New File (%d)", i));
UpdateList();
}
void VHDDExplorer::OnImport(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select import files", wxEmptyString, wxEmptyString, wxFileSelectorDefaultWildcardStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
wxArrayString paths;
ctrl.GetPaths(paths);
for(size_t i=0; i<paths.GetCount(); ++i)
{
if(wxFileExists(paths[i]))
{
Import(fmt::ToUTF8(paths[i]), fmt::ToUTF8(wxFileName(paths[i]).GetFullName()));
}
}
UpdateList();
}
void VHDDExplorer::OnExport(wxCommandEvent& event)
{
if(m_list->GetSelectedItemCount() > 1)
{
wxDirDialog ctrl(this, "Select export folder", wxGetCwd());
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
for(int sel = m_list->GetNextSelected(-1); sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel))
{
Export(m_names[sel], fmt::ToUTF8(ctrl.GetPath()) + '\\' + m_names[sel]);
}
}
else
{
int sel = m_list->GetFirstSelected();
wxFileDialog ctrl(this, "Select export file", wxEmptyString, fmt::FromUTF8(m_names[sel]), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
Export(m_names[sel], fmt::ToUTF8(ctrl.GetPath()));
}
UpdateList();
}
VHDDSetInfoDialog::VHDDSetInfoDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, "HDD Settings")
{
m_spin_size = new wxSpinCtrl(this);
m_ch_type = new wxChoice(this, wxID_ANY);
m_spin_block_size = new wxSpinCtrl(this);
wxBoxSizer* s_sinf = new wxBoxSizer(wxHORIZONTAL);
s_sinf->Add(m_spin_size, wxSizerFlags().Border(wxALL, 5).Expand());
s_sinf->Add(m_ch_type, wxSizerFlags().Border(wxALL, 5).Expand());
wxBoxSizer* s_binf = new wxBoxSizer(wxHORIZONTAL);
s_binf->Add(m_spin_block_size, wxSizerFlags().Border(wxALL, 5).Expand());
wxBoxSizer* s_btns = new wxBoxSizer(wxHORIZONTAL);
s_btns->Add(new wxButton(this, wxID_OK), wxSizerFlags().Align(wxALIGN_LEFT).Border(wxALL, 5));
s_btns->Add(new wxButton(this, wxID_CANCEL), wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL, 5));
wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL);
s_main->Add(s_sinf, wxSizerFlags().Align(wxALIGN_TOP).Expand());
s_main->Add(s_binf, wxSizerFlags().Align(wxALIGN_TOP).Expand());
s_main->Add(s_btns, wxSizerFlags().Align(wxALIGN_BOTTOM).Expand());
SetSizerAndFit(s_main);
m_ch_type->Append("B");
m_ch_type->Append("KB");
m_ch_type->Append("MB");
m_ch_type->Append("GB");
m_spin_size->SetRange(1, 0x7fffffff);
m_spin_size->SetValue(64);
m_ch_type->SetSelection(3);
m_spin_block_size->SetRange(64, 0x7fffffff);
m_spin_block_size->SetValue(2048);
Bind(wxEVT_BUTTON, &VHDDSetInfoDialog::OnOk, this, wxID_OK);
}
void VHDDSetInfoDialog::OnOk(wxCommandEvent& event)
{
m_res_size = m_spin_size->GetValue();
for(int i=0; i<m_ch_type->GetSelection(); ++i)
{
m_res_size *= 1024;
}
m_res_block_size = m_spin_block_size->GetValue();
EndModal(wxID_OK);
}
void VHDDSetInfoDialog::GetResult(u64& size, u64& block_size)
{
size = m_res_size;
block_size = m_res_block_size;
}
VHDDManagerDialog::VHDDManagerDialog(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "Virtual HDD Manager")
{
m_list = new wxListView(this);
wxBoxSizer* s_btns = new wxBoxSizer(wxHORIZONTAL);
s_btns->Add(new wxButton(this, wxID_OK));
s_btns->AddSpacer(30);
s_btns->Add(new wxButton(this, wxID_CANCEL));
wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL);
s_main->Add(m_list, 1, wxEXPAND | wxALL, 5);
s_main->Add(s_btns, 0, wxALL | wxCENTER, 10);
SetSizerAndFit(s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Path");
//m_list->InsertColumn(1, "Size");
//m_list->InsertColumn(2, "Block size");
m_list->Bind(wxEVT_LIST_ITEM_ACTIVATED, &VHDDManagerDialog::DClick, this);
m_list->Bind(wxEVT_RIGHT_DOWN, &VHDDManagerDialog::OnContextMenu, this);
Bind(wxEVT_MENU, &VHDDManagerDialog::AddHDD, this, id_add_hdd);
Bind(wxEVT_MENU, &VHDDManagerDialog::OnOpen, this, id_open);
Bind(wxEVT_MENU, &VHDDManagerDialog::OnRemove, this, id_remove);
Bind(wxEVT_MENU, &VHDDManagerDialog::OnCreateHDD, this, id_create_hdd);
Bind(wxEVT_BUTTON, &VHDDManagerDialog::OnOk, this, wxID_OK);
LoadPaths();
UpdateList();
}
void VHDDManagerDialog::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
for(size_t i=0; i<m_paths.size(); ++i)
{
m_list->InsertItem(i, m_paths[i]);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
//m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
//m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VHDDManagerDialog::Open(int sel)
{
VHDDExplorer dial(this, m_paths[sel]);
dial.ShowModal();
}
void VHDDManagerDialog::DClick(wxListEvent& event)
{
Open(event.GetIndex());
}
void VHDDManagerDialog::AddHDD(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select HDDs", wxEmptyString, wxEmptyString, "Virtual HDD (*.hdd) | *.hdd",
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
wxArrayString paths;
ctrl.GetPaths(paths);
for(size_t i=0; i<paths.GetCount(); ++i)
{
bool skip = false;
for(size_t j=0; j<m_paths.size(); ++j)
{
if(fmt::FromUTF8(m_paths[j]).CmpNoCase(paths[i]) == 0)
{
skip = true;
break;
}
}
if(!skip)
{
m_paths.emplace_back(fmt::ToUTF8(paths[i]));
}
}
UpdateList();
}
void VHDDManagerDialog::OnContextMenu(wxMouseEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_open, "Open")->Enable(idx != wxNOT_FOUND);
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND);
menu->AppendSeparator();
menu->Append(id_add_hdd, "Add");
menu->Append(id_create_hdd, "Create");
PopupMenu(menu);
}
void VHDDManagerDialog::OnOpen(wxCommandEvent& event)
{
int idx = m_list->GetFirstSelected();
if(idx >= 0) Open(idx);
}
void VHDDManagerDialog::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1), offs = 0; sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel), --offs)
{
m_paths.erase(m_paths.begin() + (sel + offs));
}
UpdateList();
}
void VHDDManagerDialog::OnCreateHDD(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select HDD path", wxEmptyString, "new_hdd.hdd", "Virtual HDD (*.hdd) | *.hdd",
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
VHDDSetInfoDialog dial(this);
if(dial.ShowModal() == wxID_OK)
{
u64 size, bsize;
dial.GetResult(size, bsize);
vfsHDDManager::CreateHDD(fmt::ToUTF8(ctrl.GetPath()), size, bsize);
m_paths.push_back(fmt::ToUTF8(ctrl.GetPath()));
UpdateList();
}
}
void VHDDManagerDialog::OnOk(wxCommandEvent& event)
{
SavePaths();
event.Skip();
}
void VHDDManagerDialog::LoadPaths()
{
size_t count = rpcs3::config.vfs.hdd_count.value();
for (size_t i = 0; i < count; ++i)
{
m_paths.emplace_back(rpcs3::config.vfs.get_entry_value<std::string>(fmt::format("hdd_path[%d]", i), std::string{}));
}
}
void VHDDManagerDialog::SavePaths()
{
rpcs3::config.vfs.hdd_count = (int)m_paths.size();
for (size_t i = 0; i < m_paths.size(); ++i)
{
rpcs3::config.vfs.set_entry_value(fmt::format("hdd_path[%d]", i), m_paths[i]);
}
}

View File

@ -1,87 +0,0 @@
#pragma once
#include "Emu/HDD/HDD.h"
class VHDDListDropTarget : public wxDropTarget
{
wxListView* m_parent;
int m_src_indx;
public:
VHDDListDropTarget(wxListView* parent);
virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def);
virtual void OnLeave();
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def);
void SetSrcIndx(int src_indx)
{
m_src_indx = src_indx;
}
};
class VHDDExplorer : public wxDialog
{
std::vector<vfsHDD_Entry> m_entries;
std::vector<std::string> m_names;
wxListView* m_list;
vfsHDD* m_hdd;
VHDDListDropTarget* m_drop_target;
public:
VHDDExplorer(wxWindow* parent, const std::string& hdd_path);
void UpdateList();
void Import(const std::string& path, const std::string& to);
void Export(const std::string& path, const std::string& to);
void OnListDrag(wxListEvent& event);
void OnDropFiles(wxDropFilesEvent& event);
void OpenDir(int sel);
void DClick(wxListEvent& event);
void OnContextMenu(wxMouseEvent& event);
void OnOpen(wxCommandEvent& event);
void OnRename(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnCreateDir(wxCommandEvent& event);
void OnCreateFile(wxCommandEvent& event);
void OnImport(wxCommandEvent& event);
void OnExport(wxCommandEvent& event);
};
class VHDDSetInfoDialog : public wxDialog
{
wxSpinCtrl* m_spin_size;
wxChoice* m_ch_type;
wxSpinCtrl* m_spin_block_size;
u64 m_res_size;
u64 m_res_block_size;
public:
VHDDSetInfoDialog(wxWindow* parent);
void OnOk(wxCommandEvent& event);
void GetResult(u64& size, u64& block_size);
};
class VHDDManagerDialog : public wxDialog
{
std::vector<std::string> m_paths;
wxListView* m_list;
public:
VHDDManagerDialog(wxWindow* parent);
void UpdateList();
void Open(int sel);
void DClick(wxListEvent& event);
void AddHDD(wxCommandEvent& event);
void OnContextMenu(wxMouseEvent& event);
void OnOpen(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnCreateHDD(wxCommandEvent& event);
void OnOk(wxCommandEvent& event);
void LoadPaths();
void SavePaths();
};