#include "stdafx_gui.h" #include "Utilities/rMsgBox.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 _WIN32 ::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; iGetValue().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 _WIN32 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() == rID_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(); }